summaryrefslogtreecommitdiffstats
path: root/chromeos/settings
diff options
context:
space:
mode:
authorstevenjb@chromium.org <stevenjb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-10 21:59:26 +0000
committerstevenjb@chromium.org <stevenjb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-10 21:59:26 +0000
commit833a6bf23035005db6526096fa1e1c3ffdcf49f6 (patch)
tree576a249d3a01f2f3fa291fdccfc2ef8627d6689e /chromeos/settings
parentf54e768523cab56eb160ee463241ef29f46e77cd (diff)
downloadchromium_src-833a6bf23035005db6526096fa1e1c3ffdcf49f6.zip
chromium_src-833a6bf23035005db6526096fa1e1c3ffdcf49f6.tar.gz
chromium_src-833a6bf23035005db6526096fa1e1c3ffdcf49f6.tar.bz2
Move some cros settings code to chromeos/settings
BUG=270135 For numerous #include changes: TBR=sky@chromium.org Review URL: https://codereview.chromium.org/26732002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@228017 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chromeos/settings')
-rw-r--r--chromeos/settings/cros_settings_names.cc140
-rw-r--r--chromeos/settings/cros_settings_names.h85
-rw-r--r--chromeos/settings/cros_settings_provider.cc46
-rw-r--r--chromeos/settings/cros_settings_provider.h79
-rw-r--r--chromeos/settings/timezone_settings.cc440
-rw-r--r--chromeos/settings/timezone_settings.h53
6 files changed, 843 insertions, 0 deletions
diff --git a/chromeos/settings/cros_settings_names.cc b/chromeos/settings/cros_settings_names.cc
new file mode 100644
index 0000000..a82a254
--- /dev/null
+++ b/chromeos/settings/cros_settings_names.cc
@@ -0,0 +1,140 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chromeos/settings/cros_settings_names.h"
+
+namespace chromeos {
+
+const char kCrosSettingsPrefix[] = "cros.";
+
+// All cros.accounts.* settings are stored in SignedSettings.
+const char kAccountsPrefAllowGuest[] = "cros.accounts.allowBWSI";
+const char kAccountsPrefAllowNewUser[] = "cros.accounts.allowGuest";
+const char kAccountsPrefShowUserNamesOnSignIn[]
+ = "cros.accounts.showUserNamesOnSignIn";
+const char kAccountsPrefUsers[] = "cros.accounts.users";
+const char kAccountsPrefEphemeralUsersEnabled[] =
+ "cros.accounts.ephemeralUsersEnabled";
+const char kAccountsPrefDeviceLocalAccounts[] =
+ "cros.accounts.deviceLocalAccounts";
+const char kAccountsPrefDeviceLocalAccountsKeyId[] =
+ "id";
+const char kAccountsPrefDeviceLocalAccountsKeyType[] =
+ "type";
+const char kAccountsPrefDeviceLocalAccountsKeyKioskAppId[] =
+ "kiosk_app_id";
+const char kAccountsPrefDeviceLocalAccountAutoLoginId[] =
+ "cros.accounts.deviceLocalAccountAutoLoginId";
+const char kAccountsPrefDeviceLocalAccountAutoLoginDelay[] =
+ "cros.accounts.deviceLocalAccountAutoLoginDelay";
+const char kAccountsPrefDeviceLocalAccountAutoLoginBailoutEnabled[] =
+ "cros.accounts.deviceLocalAccountAutoLoginBailoutEnabled";
+const char kAccountsPrefSupervisedUsersEnabled[] =
+ "cros.accounts.supervisedUsersEnabled";
+
+// All cros.signed.* settings are stored in SignedSettings.
+const char kSignedDataRoamingEnabled[] = "cros.signed.data_roaming_enabled";
+
+// True if auto-update was disabled by the system administrator.
+const char kUpdateDisabled[] = "cros.system.updateDisabled";
+
+// A list of strings which specifies allowed connection types for
+// update.
+const char kAllowedConnectionTypesForUpdate[] =
+ "cros.system.allowedConnectionTypesForUpdate";
+
+// The first constant refers to the user setting editable in the UI. The second
+// refers to the timezone policy. This seperation is necessary to allow the user
+// to temporarily change the timezone for the current session and reset it to
+// the policy's value on logout.
+const char kSystemTimezone[] = "cros.system.timezone";
+const char kSystemTimezonePolicy[] = "cros.system.timezone_policy";
+
+// Value of kUse24HourClock user preference of device' owner.
+// ChromeOS device uses this setting on login screen.
+const char kSystemUse24HourClock[] = "cros.system.use_24hour_clock";
+
+const char kDeviceOwner[] = "cros.device.owner";
+
+const char kStatsReportingPref[] = "cros.metrics.reportingEnabled";
+
+const char kReleaseChannel[] = "cros.system.releaseChannel";
+const char kReleaseChannelDelegated[] = "cros.system.releaseChannelDelegated";
+
+// A boolean pref that indicates whether OS & firmware version info should be
+// reported along with device policy requests.
+const char kReportDeviceVersionInfo[] =
+ "cros.device_status.report_version_info";
+
+// A boolean pref that indicates whether device activity times should be
+// recorded and reported along with device policy requests.
+const char kReportDeviceActivityTimes[] =
+ "cros.device_status.report_activity_times";
+
+// A boolean pref that indicates whether the state of the dev mode switch at
+// boot should be reported along with device policy requests.
+const char kReportDeviceBootMode[] = "cros.device_status.report_boot_mode";
+
+// A boolean pref that indicates whether the current location should be reported
+// along with device policy requests.
+const char kReportDeviceLocation[] = "cros.device_status.report_location";
+
+// Determines whether the device reports network interface types and addresses
+// in device status reports to the device management server.
+const char kReportDeviceNetworkInterfaces[] =
+ "cros.device_status.report_network_interfaces";
+
+// A list of dictionaries, each detailing one extension to install as part of
+// the AppPack and including the following fields:
+// "extension-id": ID of the extension to install
+// "update-url": URL to check the extension's version and download location
+// "key-checksum": checksum of the extension's CRX public key, encoded in hex.
+const char kAppPack[] = "cros.app_pack";
+const char kAppPackKeyExtensionId[] = "extension-id";
+const char kAppPackKeyUpdateUrl[] = "update-url";
+
+// Values from the ScreenSaver proto. Defines the extension ID of the screen
+// saver extension and the timeout before the screen saver should be started.
+const char kScreenSaverExtensionId[] = "cros.screen_saver.extension_id";
+const char kScreenSaverTimeout[] = "cros.screen_saver.timeout";
+
+// Values from the ForcedLogoutTimeouts proto. Defines the timeouts before a
+// user is logged out after some period of inactivity as well as the duration of
+// a warning message informing the user about the pending logout.
+const char kIdleLogoutTimeout[] = "cros.idle_logout.timeout";
+const char kIdleLogoutWarningDuration[] = "cros.idle_logout.warning_duration";
+
+// Defines the set of URLs to be opened on login to the anonymous account used
+// if the device is in KIOSK mode.
+const char kStartUpUrls[] = "cros.start_up_urls";
+
+// This policy should not appear in the protobuf ever but is used internally to
+// signal that we are running in a "safe-mode" for policy recovery.
+const char kPolicyMissingMitigationMode[] =
+ "cros.internal.policy_mitigation_mode";
+
+// A boolean pref that indicates whether users are allowed to redeem offers
+// through Chrome OS Registration.
+const char kAllowRedeemChromeOsRegistrationOffers[] =
+ "cros.echo.allow_redeem_chrome_os_registration_offers";
+
+// A list pref storing the flags that need to be applied to the browser upon
+// start-up.
+const char kStartUpFlags[] = "cros.startup_flags";
+
+// A string pref for the restrict parameter to be appended to the Variations URL
+// when pinging the Variations server.
+const char kVariationsRestrictParameter[] =
+ "cros.variations_restrict_parameter";
+
+// A boolean pref that indicates whether enterprise attestation is enabled for
+// the device.
+const char kDeviceAttestationEnabled[] = "cros.device.attestation_enabled";
+
+// A boolean pref that indicates whether attestation for content protection is
+// enabled for the device.
+const char kAttestationForContentProtectionEnabled[] =
+ "cros.device.attestation_for_content_protection_enabled";
+
+} // namespace chromeos
diff --git a/chromeos/settings/cros_settings_names.h b/chromeos/settings/cros_settings_names.h
new file mode 100644
index 0000000..b0971dd
--- /dev/null
+++ b/chromeos/settings/cros_settings_names.h
@@ -0,0 +1,85 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROMEOS_SETTINGS_CROS_SETTINGS_NAMES_H_
+#define CHROMEOS_SETTINGS_CROS_SETTINGS_NAMES_H_
+
+#include "chromeos/chromeos_export.h"
+
+namespace chromeos {
+
+CHROMEOS_EXPORT extern const char kCrosSettingsPrefix[];
+
+CHROMEOS_EXPORT extern const char kAccountsPrefAllowGuest[];
+CHROMEOS_EXPORT extern const char kAccountsPrefAllowNewUser[];
+CHROMEOS_EXPORT extern const char kAccountsPrefShowUserNamesOnSignIn[];
+CHROMEOS_EXPORT extern const char kAccountsPrefUsers[];
+CHROMEOS_EXPORT extern const char kAccountsPrefEphemeralUsersEnabled[];
+CHROMEOS_EXPORT extern const char kAccountsPrefDeviceLocalAccounts[];
+CHROMEOS_EXPORT extern const char kAccountsPrefDeviceLocalAccountsKeyId[];
+CHROMEOS_EXPORT extern const char kAccountsPrefDeviceLocalAccountsKeyType[];
+CHROMEOS_EXPORT extern const char
+ kAccountsPrefDeviceLocalAccountsKeyKioskAppId[];
+CHROMEOS_EXPORT extern const char
+ kAccountsPrefDeviceLocalAccountAutoLoginId[];
+CHROMEOS_EXPORT extern const char
+ kAccountsPrefDeviceLocalAccountAutoLoginDelay[];
+CHROMEOS_EXPORT extern const char
+ kAccountsPrefDeviceLocalAccountAutoLoginBailoutEnabled[];
+CHROMEOS_EXPORT extern const char kAccountsPrefSupervisedUsersEnabled[];
+
+CHROMEOS_EXPORT extern const char kSignedDataRoamingEnabled[];
+
+CHROMEOS_EXPORT extern const char kUpdateDisabled[];
+CHROMEOS_EXPORT extern const char kAllowedConnectionTypesForUpdate[];
+
+CHROMEOS_EXPORT extern const char kSystemTimezonePolicy[];
+CHROMEOS_EXPORT extern const char kSystemTimezone[];
+CHROMEOS_EXPORT extern const char kSystemUse24HourClock[];
+
+CHROMEOS_EXPORT extern const char kDeviceOwner[];
+
+CHROMEOS_EXPORT extern const char kStatsReportingPref[];
+
+CHROMEOS_EXPORT extern const char kReleaseChannel[];
+CHROMEOS_EXPORT extern const char kReleaseChannelDelegated[];
+
+CHROMEOS_EXPORT extern const char kReportDeviceVersionInfo[];
+CHROMEOS_EXPORT extern const char kReportDeviceActivityTimes[];
+CHROMEOS_EXPORT extern const char kReportDeviceBootMode[];
+CHROMEOS_EXPORT extern const char kReportDeviceLocation[];
+CHROMEOS_EXPORT extern const char kReportDeviceNetworkInterfaces[];
+
+CHROMEOS_EXPORT extern const char kAppPack[];
+CHROMEOS_EXPORT extern const char kAppPackKeyExtensionId[];
+CHROMEOS_EXPORT extern const char kAppPackKeyUpdateUrl[];
+
+CHROMEOS_EXPORT extern const char kScreenSaverExtensionId[];
+CHROMEOS_EXPORT extern const char kScreenSaverTimeout[];
+
+CHROMEOS_EXPORT extern const char kIdleLogoutTimeout[];
+CHROMEOS_EXPORT extern const char kIdleLogoutWarningDuration[];
+
+CHROMEOS_EXPORT extern const char kStartUpUrls[];
+
+CHROMEOS_EXPORT extern const char kPolicyMissingMitigationMode[];
+
+CHROMEOS_EXPORT extern const char kAllowRedeemChromeOsRegistrationOffers[];
+
+CHROMEOS_EXPORT extern const char kStartUpFlags[];
+
+CHROMEOS_EXPORT extern const char kKioskAppSettingsPrefix[];
+CHROMEOS_EXPORT extern const int kKioskAppSettingsPrefixLength;
+CHROMEOS_EXPORT extern const char kKioskApps[];
+CHROMEOS_EXPORT extern const char kKioskAutoLaunch[];
+CHROMEOS_EXPORT extern const char kKioskDisableBailoutShortcut[];
+
+CHROMEOS_EXPORT extern const char kVariationsRestrictParameter[];
+
+CHROMEOS_EXPORT extern const char kDeviceAttestationEnabled[];
+CHROMEOS_EXPORT extern const char kAttestationForContentProtectionEnabled[];
+
+} // namespace chromeos
+
+#endif // CHROMEOS_SETTINGS_CROS_SETTINGS_NAMES_H_
diff --git a/chromeos/settings/cros_settings_provider.cc b/chromeos/settings/cros_settings_provider.cc
new file mode 100644
index 0000000..66ca64c
--- /dev/null
+++ b/chromeos/settings/cros_settings_provider.cc
@@ -0,0 +1,46 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chromeos/settings/cros_settings_provider.h"
+
+#include "base/command_line.h"
+#include "base/logging.h"
+#include "base/strings/string_util.h"
+#include "base/values.h"
+#include "chromeos/chromeos_switches.h"
+
+namespace chromeos {
+
+CrosSettingsProvider::CrosSettingsProvider(
+ const NotifyObserversCallback& notify_cb)
+ : notify_cb_(notify_cb) {
+}
+
+CrosSettingsProvider::~CrosSettingsProvider() {
+}
+
+void CrosSettingsProvider::Set(const std::string& path,
+ const base::Value& value) {
+ // We don't allow changing any of the cros settings without prefix
+ // "cros.session." in the guest mode.
+ // It should not reach here from UI in the guest mode, but just in case.
+ if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kGuestSession) &&
+ !::StartsWithASCII(path, "cros.session.", true)) {
+ LOG(ERROR) << "Ignoring the guest request to change: " << path;
+ return;
+ }
+ DoSet(path, value);
+}
+
+void CrosSettingsProvider::NotifyObservers(const std::string& path) {
+ if (!notify_cb_.is_null())
+ notify_cb_.Run(path);
+}
+
+void CrosSettingsProvider::SetNotifyObserversCallback(
+ const NotifyObserversCallback& notify_cb) {
+ notify_cb_ = notify_cb;
+}
+
+}; // namespace chromeos
diff --git a/chromeos/settings/cros_settings_provider.h b/chromeos/settings/cros_settings_provider.h
new file mode 100644
index 0000000..491113b
--- /dev/null
+++ b/chromeos/settings/cros_settings_provider.h
@@ -0,0 +1,79 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROMEOS_SETTINGS_CROS_SETTINGS_PROVIDER_H_
+#define CHROMEOS_SETTINGS_CROS_SETTINGS_PROVIDER_H_
+
+#include <string>
+
+#include "base/callback.h"
+#include "chromeos/chromeos_export.h"
+
+namespace base {
+class Value;
+}
+
+namespace chromeos {
+
+class CHROMEOS_EXPORT CrosSettingsProvider {
+ public:
+ // The callback type that is called to notify the CrosSettings observers
+ // about a setting change.
+ typedef base::Callback<void(const std::string&)> NotifyObserversCallback;
+
+ // Possible results of a trusted check.
+ enum TrustedStatus {
+ // The trusted values were populated in the cache and can be accessed
+ // until the next iteration of the message loop.
+ TRUSTED,
+ // Either a store or a load operation is in progress. The provided
+ // callback will be invoked once the verification has finished.
+ TEMPORARILY_UNTRUSTED,
+ // The verification of the trusted store has failed permanently. The
+ // client should assume this state final and further checks for
+ // trustedness will fail at least until the browser restarts.
+ PERMANENTLY_UNTRUSTED,
+ };
+
+ // Creates a new provider instance. |notify_cb| will be used to notify
+ // about setting changes.
+ explicit CrosSettingsProvider(const NotifyObserversCallback& notify_cb);
+ virtual ~CrosSettingsProvider();
+
+ // Sets |in_value| to given |path| in cros settings.
+ void Set(const std::string& path, const base::Value& in_value);
+
+ // Gets settings value of given |path| to |out_value|.
+ virtual const base::Value* Get(const std::string& path) const = 0;
+
+ // Requests the provider to fetch its values from a trusted store, if it
+ // hasn't done so yet. Returns TRUSTED if the values returned by this provider
+ // are trusted during the current loop cycle. Otherwise returns
+ // TEMPORARILY_UNTRUSTED, and |callback| will be invoked later when trusted
+ // values become available, PrepareTrustedValues() should be tried again in
+ // that case. Returns PERMANENTLY_UNTRUSTED if a permanent error has occurred.
+ virtual TrustedStatus PrepareTrustedValues(
+ const base::Closure& callback) = 0;
+
+ // Gets the namespace prefix provided by this provider.
+ virtual bool HandlesSetting(const std::string& path) const = 0;
+
+ void SetNotifyObserversCallback(const NotifyObserversCallback& notify_cb);
+
+ protected:
+ // Notifies the observers about a setting change.
+ void NotifyObservers(const std::string& path);
+
+ private:
+ // Does the real job for Set().
+ virtual void DoSet(const std::string& path,
+ const base::Value& in_value) = 0;
+
+ // Callback used to notify about setting changes.
+ NotifyObserversCallback notify_cb_;
+};
+
+} // namespace chromeos
+
+#endif // CHROMEOS_SETTINGS_CROS_SETTINGS_PROVIDER_H_
diff --git a/chromeos/settings/timezone_settings.cc b/chromeos/settings/timezone_settings.cc
new file mode 100644
index 0000000..1adcf13
--- /dev/null
+++ b/chromeos/settings/timezone_settings.cc
@@ -0,0 +1,440 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chromeos/settings/timezone_settings.h"
+
+#include <string>
+
+#include "base/bind.h"
+#include "base/file_util.h"
+#include "base/files/file_path.h"
+#include "base/location.h"
+#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/singleton.h"
+#include "base/observer_list.h"
+#include "base/stl_util.h"
+#include "base/strings/string_util.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/sys_info.h"
+#include "base/task_runner.h"
+#include "base/threading/worker_pool.h"
+#include "third_party/icu/source/i18n/unicode/timezone.h"
+
+namespace {
+
+// The filepath to the timezone file that symlinks to the actual timezone file.
+const char kTimezoneSymlink[] = "/var/lib/timezone/localtime";
+const char kTimezoneSymlink2[] = "/var/lib/timezone/localtime2";
+
+// The directory that contains all the timezone files. So for timezone
+// "US/Pacific", the actual timezone file is: "/usr/share/zoneinfo/US/Pacific"
+const char kTimezoneFilesDir[] = "/usr/share/zoneinfo/";
+
+// Fallback time zone ID used in case of an unexpected error.
+const char kFallbackTimeZoneId[] = "America/Los_Angeles";
+
+// TODO(jungshik): Using Enumerate method in ICU gives 600+ timezones.
+// Even after filtering out duplicate entries with a strict identity check,
+// we still have 400+ zones. Relaxing the criteria for the timezone
+// identity is likely to cut down the number to < 100. Until we
+// come up with a better list, we hard-code the following list. It came from
+// from Android initially, but more entries have been added.
+static const char* kTimeZones[] = {
+ "Pacific/Midway",
+ "Pacific/Honolulu",
+ "America/Anchorage",
+ "America/Los_Angeles",
+ "America/Vancouver",
+ "America/Tijuana",
+ "America/Phoenix",
+ "America/Denver",
+ "America/Edmonton",
+ "America/Chihuahua",
+ "America/Regina",
+ "America/Costa_Rica",
+ "America/Chicago",
+ "America/Mexico_City",
+ "America/Winnipeg",
+ "America/Bogota",
+ "America/New_York",
+ "America/Toronto",
+ "America/Caracas",
+ "America/Barbados",
+ "America/Halifax",
+ "America/Manaus",
+ "America/Santiago",
+ "America/St_Johns",
+ "America/Sao_Paulo",
+ "America/Araguaina",
+ "America/Argentina/Buenos_Aires",
+ "America/Argentina/San_Luis",
+ "America/Montevideo",
+ "America/Godthab",
+ "Atlantic/South_Georgia",
+ "Atlantic/Cape_Verde",
+ "Atlantic/Azores",
+ "Africa/Casablanca",
+ "Europe/London",
+ "Europe/Dublin",
+ "Europe/Amsterdam",
+ "Europe/Belgrade",
+ "Europe/Berlin",
+ "Europe/Brussels",
+ "Europe/Madrid",
+ "Europe/Paris",
+ "Europe/Rome",
+ "Europe/Stockholm",
+ "Europe/Sarajevo",
+ "Europe/Vienna",
+ "Europe/Warsaw",
+ "Europe/Zurich",
+ "Africa/Windhoek",
+ "Africa/Lagos",
+ "Africa/Brazzaville",
+ "Africa/Cairo",
+ "Africa/Harare",
+ "Africa/Maputo",
+ "Africa/Johannesburg",
+ "Europe/Helsinki",
+ "Europe/Athens",
+ "Asia/Amman",
+ "Asia/Beirut",
+ "Asia/Jerusalem",
+ "Europe/Minsk",
+ "Asia/Baghdad",
+ "Asia/Riyadh",
+ "Asia/Kuwait",
+ "Africa/Nairobi",
+ "Asia/Tehran",
+ "Europe/Moscow",
+ "Asia/Dubai",
+ "Asia/Tbilisi",
+ "Indian/Mauritius",
+ "Asia/Baku",
+ "Asia/Yerevan",
+ "Asia/Kabul",
+ "Asia/Karachi",
+ "Asia/Ashgabat",
+ "Asia/Oral",
+ "Asia/Calcutta",
+ "Asia/Colombo",
+ "Asia/Katmandu",
+ "Asia/Yekaterinburg",
+ "Asia/Almaty",
+ "Asia/Dhaka",
+ "Asia/Rangoon",
+ "Asia/Bangkok",
+ "Asia/Jakarta",
+ "Asia/Omsk",
+ "Asia/Novosibirsk",
+ "Asia/Shanghai",
+ "Asia/Hong_Kong",
+ "Asia/Kuala_Lumpur",
+ "Asia/Singapore",
+ "Asia/Manila",
+ "Asia/Taipei",
+ "Asia/Makassar",
+ "Asia/Krasnoyarsk",
+ "Australia/Perth",
+ "Australia/Eucla",
+ "Asia/Irkutsk",
+ "Asia/Seoul",
+ "Asia/Tokyo",
+ "Asia/Jayapura",
+ "Australia/Adelaide",
+ "Australia/Darwin",
+ "Australia/Brisbane",
+ "Australia/Hobart",
+ "Australia/Sydney",
+ "Asia/Yakutsk",
+ "Pacific/Guam",
+ "Pacific/Port_Moresby",
+ "Asia/Vladivostok",
+ "Asia/Sakhalin",
+ "Asia/Magadan",
+ "Pacific/Auckland",
+ "Pacific/Fiji",
+ "Pacific/Majuro",
+ "Pacific/Tongatapu",
+ "Pacific/Apia",
+ "Pacific/Kiritimati",
+};
+
+std::string GetTimezoneIDAsString() {
+ // Compare with chromiumos/src/platform/init/ui.conf which fixes certain
+ // incorrect states of the timezone symlink on startup. Thus errors occuring
+ // here should be rather contrived.
+
+ // Look at kTimezoneSymlink, see which timezone we are symlinked to.
+ char buf[256];
+ const ssize_t len = readlink(kTimezoneSymlink, buf,
+ sizeof(buf)-1);
+ if (len == -1) {
+ LOG(ERROR) << "GetTimezoneID: Cannot read timezone symlink "
+ << kTimezoneSymlink;
+ return std::string();
+ }
+
+ std::string timezone(buf, len);
+ // Remove kTimezoneFilesDir from the beginning.
+ if (timezone.find(kTimezoneFilesDir) != 0) {
+ LOG(ERROR) << "GetTimezoneID: Timezone symlink is wrong "
+ << timezone;
+ return std::string();
+ }
+
+ return timezone.substr(strlen(kTimezoneFilesDir));
+}
+
+void SetTimezoneIDFromString(const std::string& id) {
+ // Change the kTimezoneSymlink symlink to the path for this timezone.
+ // We want to do this in an atomic way. So we are going to create the symlink
+ // at kTimezoneSymlink2 and then move it to kTimezoneSymlink
+
+ base::FilePath timezone_symlink(kTimezoneSymlink);
+ base::FilePath timezone_symlink2(kTimezoneSymlink2);
+ base::FilePath timezone_file(kTimezoneFilesDir + id);
+
+ // Make sure timezone_file exists.
+ if (!base::PathExists(timezone_file)) {
+ LOG(ERROR) << "SetTimezoneID: Cannot find timezone file "
+ << timezone_file.value();
+ return;
+ }
+
+ // Delete old symlink2 if it exists.
+ base::DeleteFile(timezone_symlink2, false);
+
+ // Create new symlink2.
+ if (symlink(timezone_file.value().c_str(),
+ timezone_symlink2.value().c_str()) == -1) {
+ LOG(ERROR) << "SetTimezoneID: Unable to create symlink "
+ << timezone_symlink2.value() << " to " << timezone_file.value();
+ return;
+ }
+
+ // Move symlink2 to symlink.
+ if (!base::ReplaceFile(timezone_symlink2, timezone_symlink, NULL)) {
+ LOG(ERROR) << "SetTimezoneID: Unable to move symlink "
+ << timezone_symlink2.value() << " to "
+ << timezone_symlink.value();
+ }
+}
+
+// Common code of the TimezoneSettings implementations.
+class TimezoneSettingsBaseImpl : public chromeos::system::TimezoneSettings {
+ public:
+ virtual ~TimezoneSettingsBaseImpl();
+
+ // TimezoneSettings implementation:
+ virtual const icu::TimeZone& GetTimezone() OVERRIDE;
+ virtual string16 GetCurrentTimezoneID() OVERRIDE;
+ virtual void SetTimezoneFromID(const string16& timezone_id) OVERRIDE;
+ virtual void AddObserver(Observer* observer) OVERRIDE;
+ virtual void RemoveObserver(Observer* observer) OVERRIDE;
+ virtual const std::vector<icu::TimeZone*>& GetTimezoneList() const OVERRIDE;
+
+ protected:
+ TimezoneSettingsBaseImpl();
+
+ // Returns |timezone| if it is an element of |timezones_|.
+ // Otherwise, returns a timezone from |timezones_|, if such exists, that has
+ // the same rule as the given |timezone|.
+ // Otherwise, returns NULL.
+ // Note multiple timezones with the same time zone offset may exist
+ // e.g.
+ // US/Pacific == America/Los_Angeles
+ const icu::TimeZone* GetKnownTimezoneOrNull(
+ const icu::TimeZone& timezone) const;
+
+ ObserverList<Observer> observers_;
+ std::vector<icu::TimeZone*> timezones_;
+ scoped_ptr<icu::TimeZone> timezone_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TimezoneSettingsBaseImpl);
+};
+
+// The TimezoneSettings implementation used in production.
+class TimezoneSettingsImpl : public TimezoneSettingsBaseImpl {
+ public:
+ // TimezoneSettings implementation:
+ virtual void SetTimezone(const icu::TimeZone& timezone) OVERRIDE;
+
+ static TimezoneSettingsImpl* GetInstance();
+
+ private:
+ friend struct DefaultSingletonTraits<TimezoneSettingsImpl>;
+
+ TimezoneSettingsImpl();
+
+ DISALLOW_COPY_AND_ASSIGN(TimezoneSettingsImpl);
+};
+
+// The stub TimezoneSettings implementation used on Linux desktop.
+class TimezoneSettingsStubImpl : public TimezoneSettingsBaseImpl {
+ public:
+ // TimezoneSettings implementation:
+ virtual void SetTimezone(const icu::TimeZone& timezone) OVERRIDE;
+
+ static TimezoneSettingsStubImpl* GetInstance();
+
+ private:
+ friend struct DefaultSingletonTraits<TimezoneSettingsStubImpl>;
+
+ TimezoneSettingsStubImpl();
+
+ DISALLOW_COPY_AND_ASSIGN(TimezoneSettingsStubImpl);
+};
+
+TimezoneSettingsBaseImpl::~TimezoneSettingsBaseImpl() {
+ STLDeleteElements(&timezones_);
+}
+
+const icu::TimeZone& TimezoneSettingsBaseImpl::GetTimezone() {
+ return *timezone_.get();
+}
+
+string16 TimezoneSettingsBaseImpl::GetCurrentTimezoneID() {
+ return chromeos::system::TimezoneSettings::GetTimezoneID(GetTimezone());
+}
+
+void TimezoneSettingsBaseImpl::SetTimezoneFromID(const string16& timezone_id) {
+ scoped_ptr<icu::TimeZone> timezone(icu::TimeZone::createTimeZone(
+ icu::UnicodeString(timezone_id.c_str(), timezone_id.size())));
+ SetTimezone(*timezone);
+}
+
+void TimezoneSettingsBaseImpl::AddObserver(Observer* observer) {
+ observers_.AddObserver(observer);
+}
+
+void TimezoneSettingsBaseImpl::RemoveObserver(Observer* observer) {
+ observers_.RemoveObserver(observer);
+}
+
+const std::vector<icu::TimeZone*>&
+TimezoneSettingsBaseImpl::GetTimezoneList() const {
+ return timezones_;
+}
+
+TimezoneSettingsBaseImpl::TimezoneSettingsBaseImpl() {
+ for (size_t i = 0; i < arraysize(kTimeZones); ++i) {
+ timezones_.push_back(icu::TimeZone::createTimeZone(
+ icu::UnicodeString(kTimeZones[i], -1, US_INV)));
+ }
+}
+
+const icu::TimeZone* TimezoneSettingsBaseImpl::GetKnownTimezoneOrNull(
+ const icu::TimeZone& timezone) const {
+ const icu::TimeZone* known_timezone = NULL;
+ for (std::vector<icu::TimeZone*>::const_iterator iter = timezones_.begin();
+ iter != timezones_.end(); ++iter) {
+ const icu::TimeZone* entry = *iter;
+ if (*entry == timezone)
+ return entry;
+ if (entry->hasSameRules(timezone))
+ known_timezone = entry;
+ }
+
+ // May return NULL if we did not find a matching timezone in our list.
+ return known_timezone;
+}
+
+void TimezoneSettingsImpl::SetTimezone(const icu::TimeZone& timezone) {
+ // Replace |timezone| by a known timezone with the same rules. If none exists
+ // go on with |timezone|.
+ const icu::TimeZone* known_timezone = GetKnownTimezoneOrNull(timezone);
+ if (!known_timezone)
+ known_timezone = &timezone;
+
+ timezone_.reset(known_timezone->clone());
+ std::string id = UTF16ToUTF8(GetTimezoneID(*known_timezone));
+ VLOG(1) << "Setting timezone to " << id;
+ // It's safe to change the timezone config files in the background as the
+ // following operations don't depend on the completion of the config change.
+ base::WorkerPool::GetTaskRunner(true /* task is slow */)->
+ PostTask(FROM_HERE, base::Bind(&SetTimezoneIDFromString, id));
+ icu::TimeZone::setDefault(*known_timezone);
+ FOR_EACH_OBSERVER(Observer, observers_, TimezoneChanged(*known_timezone));
+}
+
+// static
+TimezoneSettingsImpl* TimezoneSettingsImpl::GetInstance() {
+ return Singleton<TimezoneSettingsImpl,
+ DefaultSingletonTraits<TimezoneSettingsImpl> >::get();
+}
+
+TimezoneSettingsImpl::TimezoneSettingsImpl() {
+ std::string id = GetTimezoneIDAsString();
+ if (id.empty()) {
+ id = kFallbackTimeZoneId;
+ LOG(ERROR) << "Got an empty string for timezone, default to '" << id;
+ }
+
+ timezone_.reset(icu::TimeZone::createTimeZone(
+ icu::UnicodeString::fromUTF8(id)));
+
+ // Store a known timezone equivalent to id in |timezone_|.
+ const icu::TimeZone* known_timezone = GetKnownTimezoneOrNull(*timezone_);
+ if (known_timezone != NULL && *known_timezone != *timezone_)
+ // Not necessary to update the filesystem because |known_timezone| has the
+ // same rules.
+ timezone_.reset(known_timezone->clone());
+
+ icu::TimeZone::setDefault(*timezone_);
+ VLOG(1) << "Timezone initially set to " << id;
+}
+
+void TimezoneSettingsStubImpl::SetTimezone(const icu::TimeZone& timezone) {
+ // Replace |timezone| by a known timezone with the same rules. If none exists
+ // go on with |timezone|.
+ const icu::TimeZone* known_timezone = GetKnownTimezoneOrNull(timezone);
+ if (!known_timezone)
+ known_timezone = &timezone;
+
+ timezone_.reset(known_timezone->clone());
+ icu::TimeZone::setDefault(*known_timezone);
+ FOR_EACH_OBSERVER(Observer, observers_, TimezoneChanged(*known_timezone));
+}
+
+// static
+TimezoneSettingsStubImpl* TimezoneSettingsStubImpl::GetInstance() {
+ return Singleton<TimezoneSettingsStubImpl,
+ DefaultSingletonTraits<TimezoneSettingsStubImpl> >::get();
+}
+
+TimezoneSettingsStubImpl::TimezoneSettingsStubImpl() {
+ timezone_.reset(icu::TimeZone::createDefault());
+ const icu::TimeZone* known_timezone = GetKnownTimezoneOrNull(*timezone_);
+ if (known_timezone != NULL && *known_timezone != *timezone_)
+ timezone_.reset(known_timezone->clone());
+}
+
+} // namespace
+
+namespace chromeos {
+namespace system {
+
+TimezoneSettings::Observer::~Observer() {}
+
+// static
+TimezoneSettings* TimezoneSettings::GetInstance() {
+ if (base::SysInfo::IsRunningOnChromeOS()) {
+ return TimezoneSettingsImpl::GetInstance();
+ } else {
+ return TimezoneSettingsStubImpl::GetInstance();
+ }
+}
+
+// static
+string16 TimezoneSettings::GetTimezoneID(const icu::TimeZone& timezone) {
+ icu::UnicodeString id;
+ timezone.getID(id);
+ return string16(id.getBuffer(), id.length());
+}
+
+} // namespace system
+} // namespace chromeos
diff --git a/chromeos/settings/timezone_settings.h b/chromeos/settings/timezone_settings.h
new file mode 100644
index 0000000..c0d9555
--- /dev/null
+++ b/chromeos/settings/timezone_settings.h
@@ -0,0 +1,53 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROMEOS_SETTINGS_TIMEZONE_SETTINGS_H_
+#define CHROMEOS_SETTINGS_TIMEZONE_SETTINGS_H_
+
+#include <vector>
+
+#include "base/strings/string16.h"
+#include "chromeos/settings/cros_settings_provider.h"
+#include "third_party/icu/source/i18n/unicode/timezone.h"
+
+namespace chromeos {
+namespace system {
+
+// This interface provides access to Chrome OS timezone settings.
+class CHROMEOS_EXPORT TimezoneSettings {
+ public:
+ class Observer {
+ public:
+ // Called when the timezone has changed. |timezone| is non-null.
+ virtual void TimezoneChanged(const icu::TimeZone& timezone) = 0;
+ protected:
+ virtual ~Observer();
+ };
+
+ static TimezoneSettings* GetInstance();
+
+ // Returns the current timezone as an icu::Timezone object.
+ virtual const icu::TimeZone& GetTimezone() = 0;
+ virtual string16 GetCurrentTimezoneID() = 0;
+
+ // Sets the current timezone and notifies all Observers.
+ virtual void SetTimezone(const icu::TimeZone& timezone) = 0;
+ virtual void SetTimezoneFromID(const string16& timezone_id) = 0;
+
+ virtual void AddObserver(Observer* observer) = 0;
+ virtual void RemoveObserver(Observer* observer) = 0;
+
+ virtual const std::vector<icu::TimeZone*>& GetTimezoneList() const = 0;
+
+ // Gets timezone ID which is also used as timezone pref value.
+ static string16 GetTimezoneID(const icu::TimeZone& timezone);
+
+ protected:
+ virtual ~TimezoneSettings() {}
+};
+
+} // namespace system
+} // namespace chromeos
+
+#endif // CHROMEOS_SETTINGS_TIMEZONE_SETTINGS_H_