blob: 1c8006900c01f2a2f735992193bbcc1537d793af [file] [log] [blame]
[email protected]833a6bf22013-10-10 21:59:261// Copyright 2013 The Chromium Authors. All rights reserved.
[email protected]d43970a72011-07-10 06:24:522// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]833a6bf22013-10-10 21:59:265#include "chromeos/settings/timezone_settings.h"
[email protected]d43970a72011-07-10 06:24:526
[email protected]5f647a32012-07-18 15:36:067#include <string>
8
[email protected]3b7a16e72011-09-21 11:38:119#include "base/bind.h"
[email protected]d43970a72011-07-10 06:24:5210#include "base/file_util.h"
[email protected]57999812013-02-24 05:40:5211#include "base/files/file_path.h"
[email protected]833a6bf22013-10-10 21:59:2612#include "base/location.h"
[email protected]d43970a72011-07-10 06:24:5213#include "base/logging.h"
[email protected]d43970a72011-07-10 06:24:5214#include "base/memory/scoped_ptr.h"
15#include "base/memory/singleton.h"
[email protected]c38831a12011-10-28 12:44:4916#include "base/observer_list.h"
[email protected]5f647a32012-07-18 15:36:0617#include "base/stl_util.h"
[email protected]5c073322013-06-11 08:03:3018#include "base/strings/string_util.h"
[email protected]135cb802013-06-09 16:44:2019#include "base/strings/utf_string_conversions.h"
[email protected]49c4cf852013-09-27 19:28:2420#include "base/sys_info.h"
[email protected]833a6bf22013-10-10 21:59:2621#include "base/task_runner.h"
22#include "base/threading/worker_pool.h"
[email protected]8bbf6192013-07-18 11:14:0423#include "third_party/icu/source/i18n/unicode/timezone.h"
[email protected]d43970a72011-07-10 06:24:5224
[email protected]d43970a72011-07-10 06:24:5225namespace {
26
27// The filepath to the timezone file that symlinks to the actual timezone file.
28const char kTimezoneSymlink[] = "/var/lib/timezone/localtime";
29const char kTimezoneSymlink2[] = "/var/lib/timezone/localtime2";
30
31// The directory that contains all the timezone files. So for timezone
32// "US/Pacific", the actual timezone file is: "/usr/share/zoneinfo/US/Pacific"
33const char kTimezoneFilesDir[] = "/usr/share/zoneinfo/";
34
35// Fallback time zone ID used in case of an unexpected error.
36const char kFallbackTimeZoneId[] = "America/Los_Angeles";
37
[email protected]5f647a32012-07-18 15:36:0638// TODO(jungshik): Using Enumerate method in ICU gives 600+ timezones.
39// Even after filtering out duplicate entries with a strict identity check,
40// we still have 400+ zones. Relaxing the criteria for the timezone
41// identity is likely to cut down the number to < 100. Until we
[email protected]f07059d2013-05-23 16:20:3242// come up with a better list, we hard-code the following list. It came from
43// from Android initially, but more entries have been added.
[email protected]5f647a32012-07-18 15:36:0644static const char* kTimeZones[] = {
[email protected]5f647a32012-07-18 15:36:0645 "Pacific/Midway",
46 "Pacific/Honolulu",
47 "America/Anchorage",
48 "America/Los_Angeles",
[email protected]f07059d2013-05-23 16:20:3249 "America/Vancouver",
[email protected]5f647a32012-07-18 15:36:0650 "America/Tijuana",
[email protected]fd22e702013-06-06 05:09:1651 "America/Phoenix",
[email protected]0f43b2c2014-02-14 00:12:3652 "America/Chihuahua",
[email protected]5f647a32012-07-18 15:36:0653 "America/Denver",
[email protected]f07059d2013-05-23 16:20:3254 "America/Edmonton",
[email protected]0f43b2c2014-02-14 00:12:3655 "America/Mazatlan",
[email protected]fd22e702013-06-06 05:09:1656 "America/Regina",
57 "America/Costa_Rica",
[email protected]5f647a32012-07-18 15:36:0658 "America/Chicago",
59 "America/Mexico_City",
[email protected]f07059d2013-05-23 16:20:3260 "America/Winnipeg",
[email protected]bdf5b2282014-02-15 14:21:0961 "Pacific/Easter",
[email protected]fd22e702013-06-06 05:09:1662 "America/Bogota",
[email protected]0f43b2c2014-02-14 00:12:3663 "America/Lima",
[email protected]5f647a32012-07-18 15:36:0664 "America/New_York",
[email protected]f07059d2013-05-23 16:20:3265 "America/Toronto",
[email protected]5f647a32012-07-18 15:36:0666 "America/Caracas",
67 "America/Barbados",
[email protected]fd22e702013-06-06 05:09:1668 "America/Halifax",
[email protected]5f647a32012-07-18 15:36:0669 "America/Manaus",
70 "America/Santiago",
71 "America/St_Johns",
[email protected]5f647a32012-07-18 15:36:0672 "America/Araguaina",
73 "America/Argentina/Buenos_Aires",
[email protected]f07059d2013-05-23 16:20:3274 "America/Argentina/San_Luis",
[email protected]bdf5b2282014-02-15 14:21:0975 "America/Sao_Paulo",
[email protected]5f647a32012-07-18 15:36:0676 "America/Montevideo",
[email protected]fd22e702013-06-06 05:09:1677 "America/Godthab",
[email protected]5f647a32012-07-18 15:36:0678 "Atlantic/South_Georgia",
[email protected]5f647a32012-07-18 15:36:0679 "Atlantic/Cape_Verde",
[email protected]fd22e702013-06-06 05:09:1680 "Atlantic/Azores",
[email protected]0f43b2c2014-02-14 00:12:3681 "Atlantic/Reykjavik",
82 "Atlantic/St_Helena",
[email protected]5f647a32012-07-18 15:36:0683 "Africa/Casablanca",
[email protected]0f43b2c2014-02-14 00:12:3684 "Atlantic/Faroe",
[email protected]f07059d2013-05-23 16:20:3285 "Europe/Dublin",
[email protected]bdf5b2282014-02-15 14:21:0986 "Europe/Lisbon",
87 "Europe/London",
[email protected]5f647a32012-07-18 15:36:0688 "Europe/Amsterdam",
89 "Europe/Belgrade",
[email protected]f07059d2013-05-23 16:20:3290 "Europe/Berlin",
[email protected]5f647a32012-07-18 15:36:0691 "Europe/Brussels",
[email protected]0f43b2c2014-02-14 00:12:3692 "Europe/Budapest",
93 "Europe/Copenhagen",
[email protected]bdf5b2282014-02-15 14:21:0994 "Europe/Ljubljana",
[email protected]fd22e702013-06-06 05:09:1695 "Europe/Madrid",
[email protected]0f43b2c2014-02-14 00:12:3696 "Europe/Oslo",
[email protected]f07059d2013-05-23 16:20:3297 "Europe/Paris",
[email protected]bdf5b2282014-02-15 14:21:0998 "Europe/Prague",
[email protected]fd22e702013-06-06 05:09:1699 "Europe/Rome",
[email protected]f07059d2013-05-23 16:20:32100 "Europe/Stockholm",
[email protected]5f647a32012-07-18 15:36:06101 "Europe/Sarajevo",
[email protected]bdf5b2282014-02-15 14:21:09102 "Europe/Tirane",
[email protected]fd22e702013-06-06 05:09:16103 "Europe/Vienna",
104 "Europe/Warsaw",
105 "Europe/Zurich",
[email protected]5f647a32012-07-18 15:36:06106 "Africa/Windhoek",
[email protected]f07059d2013-05-23 16:20:32107 "Africa/Lagos",
[email protected]5f647a32012-07-18 15:36:06108 "Africa/Brazzaville",
[email protected]fd22e702013-06-06 05:09:16109 "Africa/Cairo",
110 "Africa/Harare",
111 "Africa/Maputo",
[email protected]f07059d2013-05-23 16:20:32112 "Africa/Johannesburg",
[email protected]5f647a32012-07-18 15:36:06113 "Europe/Athens",
[email protected]0f43b2c2014-02-14 00:12:36114 "Europe/Bucharest",
[email protected]bdf5b2282014-02-15 14:21:09115 "Europe/Chisinau",
[email protected]0f43b2c2014-02-14 00:12:36116 "Europe/Helsinki",
117 "Europe/Istanbul",
118 "Europe/Kiev",
119 "Europe/Riga",
[email protected]bdf5b2282014-02-15 14:21:09120 "Europe/Sofia",
[email protected]0f43b2c2014-02-14 00:12:36121 "Europe/Tallinn",
122 "Europe/Vilnius",
[email protected]f07059d2013-05-23 16:20:32123 "Asia/Amman",
[email protected]5f647a32012-07-18 15:36:06124 "Asia/Beirut",
[email protected]5f647a32012-07-18 15:36:06125 "Asia/Jerusalem",
[email protected]bdf5b2282014-02-15 14:21:09126 "Africa/Nairobi",
[email protected]5f647a32012-07-18 15:36:06127 "Asia/Baghdad",
[email protected]f07059d2013-05-23 16:20:32128 "Asia/Riyadh",
[email protected]5f647a32012-07-18 15:36:06129 "Asia/Kuwait",
[email protected]bdf5b2282014-02-15 14:21:09130 "Europe/Minsk",
[email protected]5f647a32012-07-18 15:36:06131 "Asia/Tehran",
[email protected]f07059d2013-05-23 16:20:32132 "Europe/Moscow",
[email protected]5f647a32012-07-18 15:36:06133 "Asia/Dubai",
[email protected]f07059d2013-05-23 16:20:32134 "Asia/Tbilisi",
135 "Indian/Mauritius",
136 "Asia/Baku",
137 "Asia/Yerevan",
[email protected]5f647a32012-07-18 15:36:06138 "Asia/Kabul",
139 "Asia/Karachi",
[email protected]f07059d2013-05-23 16:20:32140 "Asia/Ashgabat",
[email protected]fd22e702013-06-06 05:09:16141 "Asia/Oral",
[email protected]8e0a3182014-02-27 06:27:31142 "Asia/Calcutta",
[email protected]5f647a32012-07-18 15:36:06143 "Asia/Colombo",
144 "Asia/Katmandu",
[email protected]f07059d2013-05-23 16:20:32145 "Asia/Yekaterinburg",
[email protected]5f647a32012-07-18 15:36:06146 "Asia/Almaty",
[email protected]f07059d2013-05-23 16:20:32147 "Asia/Dhaka",
[email protected]5f647a32012-07-18 15:36:06148 "Asia/Rangoon",
[email protected]5f647a32012-07-18 15:36:06149 "Asia/Bangkok",
[email protected]f07059d2013-05-23 16:20:32150 "Asia/Jakarta",
151 "Asia/Omsk",
[email protected]fd22e702013-06-06 05:09:16152 "Asia/Novosibirsk",
[email protected]0f43b2c2014-02-14 00:12:36153 "Asia/Ho_Chi_Minh",
[email protected]bdf5b2282014-02-15 14:21:09154 "Asia/Phnom_Penh",
[email protected]0f43b2c2014-02-14 00:12:36155 "Asia/Vientiane",
[email protected]5f647a32012-07-18 15:36:06156 "Asia/Shanghai",
157 "Asia/Hong_Kong",
[email protected]5f647a32012-07-18 15:36:06158 "Asia/Kuala_Lumpur",
[email protected]f07059d2013-05-23 16:20:32159 "Asia/Singapore",
160 "Asia/Manila",
[email protected]5f647a32012-07-18 15:36:06161 "Asia/Taipei",
[email protected]f07059d2013-05-23 16:20:32162 "Asia/Makassar",
163 "Asia/Krasnoyarsk",
164 "Australia/Perth",
165 "Australia/Eucla",
166 "Asia/Irkutsk",
[email protected]5f647a32012-07-18 15:36:06167 "Asia/Seoul",
168 "Asia/Tokyo",
[email protected]f07059d2013-05-23 16:20:32169 "Asia/Jayapura",
[email protected]5f647a32012-07-18 15:36:06170 "Australia/Darwin",
[email protected]bdf5b2282014-02-15 14:21:09171 "Australia/Adelaide",
172 "Asia/Yakutsk",
173 "Pacific/Guam",
[email protected]5f647a32012-07-18 15:36:06174 "Australia/Brisbane",
175 "Australia/Hobart",
176 "Australia/Sydney",
[email protected]f07059d2013-05-23 16:20:32177 "Pacific/Port_Moresby",
178 "Asia/Vladivostok",
[email protected]fd22e702013-06-06 05:09:16179 "Asia/Sakhalin",
[email protected]5f647a32012-07-18 15:36:06180 "Asia/Magadan",
[email protected]5f647a32012-07-18 15:36:06181 "Pacific/Fiji",
[email protected]f07059d2013-05-23 16:20:32182 "Pacific/Majuro",
[email protected]bdf5b2282014-02-15 14:21:09183 "Pacific/Auckland",
[email protected]5f647a32012-07-18 15:36:06184 "Pacific/Tongatapu",
[email protected]f07059d2013-05-23 16:20:32185 "Pacific/Apia",
[email protected]fd22e702013-06-06 05:09:16186 "Pacific/Kiritimati",
[email protected]d43970a72011-07-10 06:24:52187};
188
189std::string GetTimezoneIDAsString() {
[email protected]5f647a32012-07-18 15:36:06190 // Compare with chromiumos/src/platform/init/ui.conf which fixes certain
191 // incorrect states of the timezone symlink on startup. Thus errors occuring
192 // here should be rather contrived.
193
[email protected]d43970a72011-07-10 06:24:52194 // Look at kTimezoneSymlink, see which timezone we are symlinked to.
195 char buf[256];
196 const ssize_t len = readlink(kTimezoneSymlink, buf,
197 sizeof(buf)-1);
198 if (len == -1) {
199 LOG(ERROR) << "GetTimezoneID: Cannot read timezone symlink "
200 << kTimezoneSymlink;
201 return std::string();
202 }
203
204 std::string timezone(buf, len);
205 // Remove kTimezoneFilesDir from the beginning.
206 if (timezone.find(kTimezoneFilesDir) != 0) {
207 LOG(ERROR) << "GetTimezoneID: Timezone symlink is wrong "
208 << timezone;
209 return std::string();
210 }
211
212 return timezone.substr(strlen(kTimezoneFilesDir));
213}
214
215void SetTimezoneIDFromString(const std::string& id) {
216 // Change the kTimezoneSymlink symlink to the path for this timezone.
217 // We want to do this in an atomic way. So we are going to create the symlink
218 // at kTimezoneSymlink2 and then move it to kTimezoneSymlink
219
[email protected]650b2d52013-02-10 03:41:45220 base::FilePath timezone_symlink(kTimezoneSymlink);
221 base::FilePath timezone_symlink2(kTimezoneSymlink2);
222 base::FilePath timezone_file(kTimezoneFilesDir + id);
[email protected]d43970a72011-07-10 06:24:52223
224 // Make sure timezone_file exists.
[email protected]7567484142013-07-11 17:36:07225 if (!base::PathExists(timezone_file)) {
[email protected]d43970a72011-07-10 06:24:52226 LOG(ERROR) << "SetTimezoneID: Cannot find timezone file "
227 << timezone_file.value();
228 return;
229 }
230
231 // Delete old symlink2 if it exists.
[email protected]dd3aa792013-07-16 19:10:23232 base::DeleteFile(timezone_symlink2, false);
[email protected]d43970a72011-07-10 06:24:52233
234 // Create new symlink2.
235 if (symlink(timezone_file.value().c_str(),
236 timezone_symlink2.value().c_str()) == -1) {
237 LOG(ERROR) << "SetTimezoneID: Unable to create symlink "
238 << timezone_symlink2.value() << " to " << timezone_file.value();
239 return;
240 }
241
242 // Move symlink2 to symlink.
[email protected]5553d5b2013-07-01 23:07:36243 if (!base::ReplaceFile(timezone_symlink2, timezone_symlink, NULL)) {
[email protected]d43970a72011-07-10 06:24:52244 LOG(ERROR) << "SetTimezoneID: Unable to move symlink "
245 << timezone_symlink2.value() << " to "
246 << timezone_symlink.value();
247 }
248}
249
[email protected]5f647a32012-07-18 15:36:06250// Common code of the TimezoneSettings implementations.
251class TimezoneSettingsBaseImpl : public chromeos::system::TimezoneSettings {
252 public:
253 virtual ~TimezoneSettingsBaseImpl();
254
255 // TimezoneSettings implementation:
256 virtual const icu::TimeZone& GetTimezone() OVERRIDE;
[email protected]33c4bc792013-12-19 20:52:30257 virtual base::string16 GetCurrentTimezoneID() OVERRIDE;
258 virtual void SetTimezoneFromID(const base::string16& timezone_id) OVERRIDE;
[email protected]5f647a32012-07-18 15:36:06259 virtual void AddObserver(Observer* observer) OVERRIDE;
260 virtual void RemoveObserver(Observer* observer) OVERRIDE;
261 virtual const std::vector<icu::TimeZone*>& GetTimezoneList() const OVERRIDE;
262
263 protected:
264 TimezoneSettingsBaseImpl();
265
266 // Returns |timezone| if it is an element of |timezones_|.
267 // Otherwise, returns a timezone from |timezones_|, if such exists, that has
268 // the same rule as the given |timezone|.
269 // Otherwise, returns NULL.
270 // Note multiple timezones with the same time zone offset may exist
271 // e.g.
272 // US/Pacific == America/Los_Angeles
273 const icu::TimeZone* GetKnownTimezoneOrNull(
274 const icu::TimeZone& timezone) const;
275
276 ObserverList<Observer> observers_;
277 std::vector<icu::TimeZone*> timezones_;
278 scoped_ptr<icu::TimeZone> timezone_;
279
280 private:
281 DISALLOW_COPY_AND_ASSIGN(TimezoneSettingsBaseImpl);
282};
283
284// The TimezoneSettings implementation used in production.
285class TimezoneSettingsImpl : public TimezoneSettingsBaseImpl {
286 public:
287 // TimezoneSettings implementation:
288 virtual void SetTimezone(const icu::TimeZone& timezone) OVERRIDE;
289
290 static TimezoneSettingsImpl* GetInstance();
291
292 private:
293 friend struct DefaultSingletonTraits<TimezoneSettingsImpl>;
294
295 TimezoneSettingsImpl();
296
297 DISALLOW_COPY_AND_ASSIGN(TimezoneSettingsImpl);
298};
299
300// The stub TimezoneSettings implementation used on Linux desktop.
301class TimezoneSettingsStubImpl : public TimezoneSettingsBaseImpl {
302 public:
303 // TimezoneSettings implementation:
304 virtual void SetTimezone(const icu::TimeZone& timezone) OVERRIDE;
305
306 static TimezoneSettingsStubImpl* GetInstance();
307
308 private:
309 friend struct DefaultSingletonTraits<TimezoneSettingsStubImpl>;
310
311 TimezoneSettingsStubImpl();
312
313 DISALLOW_COPY_AND_ASSIGN(TimezoneSettingsStubImpl);
314};
315
316TimezoneSettingsBaseImpl::~TimezoneSettingsBaseImpl() {
317 STLDeleteElements(&timezones_);
318}
319
320const icu::TimeZone& TimezoneSettingsBaseImpl::GetTimezone() {
[email protected]d43970a72011-07-10 06:24:52321 return *timezone_.get();
322}
323
[email protected]33c4bc792013-12-19 20:52:30324base::string16 TimezoneSettingsBaseImpl::GetCurrentTimezoneID() {
[email protected]5f647a32012-07-18 15:36:06325 return chromeos::system::TimezoneSettings::GetTimezoneID(GetTimezone());
[email protected]d43970a72011-07-10 06:24:52326}
327
[email protected]33c4bc792013-12-19 20:52:30328void TimezoneSettingsBaseImpl::SetTimezoneFromID(
329 const base::string16& timezone_id) {
[email protected]5f647a32012-07-18 15:36:06330 scoped_ptr<icu::TimeZone> timezone(icu::TimeZone::createTimeZone(
331 icu::UnicodeString(timezone_id.c_str(), timezone_id.size())));
332 SetTimezone(*timezone);
333}
334
335void TimezoneSettingsBaseImpl::AddObserver(Observer* observer) {
[email protected]d43970a72011-07-10 06:24:52336 observers_.AddObserver(observer);
337}
338
[email protected]5f647a32012-07-18 15:36:06339void TimezoneSettingsBaseImpl::RemoveObserver(Observer* observer) {
[email protected]d43970a72011-07-10 06:24:52340 observers_.RemoveObserver(observer);
341}
342
[email protected]5f647a32012-07-18 15:36:06343const std::vector<icu::TimeZone*>&
344TimezoneSettingsBaseImpl::GetTimezoneList() const {
345 return timezones_;
[email protected]d43970a72011-07-10 06:24:52346}
347
[email protected]5f647a32012-07-18 15:36:06348TimezoneSettingsBaseImpl::TimezoneSettingsBaseImpl() {
349 for (size_t i = 0; i < arraysize(kTimeZones); ++i) {
350 timezones_.push_back(icu::TimeZone::createTimeZone(
351 icu::UnicodeString(kTimeZones[i], -1, US_INV)));
352 }
353}
354
355const icu::TimeZone* TimezoneSettingsBaseImpl::GetKnownTimezoneOrNull(
356 const icu::TimeZone& timezone) const {
357 const icu::TimeZone* known_timezone = NULL;
358 for (std::vector<icu::TimeZone*>::const_iterator iter = timezones_.begin();
359 iter != timezones_.end(); ++iter) {
360 const icu::TimeZone* entry = *iter;
361 if (*entry == timezone)
362 return entry;
363 if (entry->hasSameRules(timezone))
364 known_timezone = entry;
365 }
366
367 // May return NULL if we did not find a matching timezone in our list.
368 return known_timezone;
369}
370
371void TimezoneSettingsImpl::SetTimezone(const icu::TimeZone& timezone) {
372 // Replace |timezone| by a known timezone with the same rules. If none exists
373 // go on with |timezone|.
374 const icu::TimeZone* known_timezone = GetKnownTimezoneOrNull(timezone);
375 if (!known_timezone)
376 known_timezone = &timezone;
377
378 timezone_.reset(known_timezone->clone());
[email protected]d519b812013-12-25 18:15:40379 std::string id = base::UTF16ToUTF8(GetTimezoneID(*known_timezone));
[email protected]5f647a32012-07-18 15:36:06380 VLOG(1) << "Setting timezone to " << id;
381 // It's safe to change the timezone config files in the background as the
382 // following operations don't depend on the completion of the config change.
[email protected]833a6bf22013-10-10 21:59:26383 base::WorkerPool::GetTaskRunner(true /* task is slow */)->
384 PostTask(FROM_HERE, base::Bind(&SetTimezoneIDFromString, id));
[email protected]5f647a32012-07-18 15:36:06385 icu::TimeZone::setDefault(*known_timezone);
386 FOR_EACH_OBSERVER(Observer, observers_, TimezoneChanged(*known_timezone));
387}
388
389// static
[email protected]d43970a72011-07-10 06:24:52390TimezoneSettingsImpl* TimezoneSettingsImpl::GetInstance() {
391 return Singleton<TimezoneSettingsImpl,
392 DefaultSingletonTraits<TimezoneSettingsImpl> >::get();
393}
394
[email protected]5f647a32012-07-18 15:36:06395TimezoneSettingsImpl::TimezoneSettingsImpl() {
396 std::string id = GetTimezoneIDAsString();
397 if (id.empty()) {
398 id = kFallbackTimeZoneId;
399 LOG(ERROR) << "Got an empty string for timezone, default to '" << id;
[email protected]65acb402011-09-30 06:09:06400 }
401
[email protected]5f647a32012-07-18 15:36:06402 timezone_.reset(icu::TimeZone::createTimeZone(
403 icu::UnicodeString::fromUTF8(id)));
[email protected]65acb402011-09-30 06:09:06404
[email protected]5f647a32012-07-18 15:36:06405 // Store a known timezone equivalent to id in |timezone_|.
406 const icu::TimeZone* known_timezone = GetKnownTimezoneOrNull(*timezone_);
407 if (known_timezone != NULL && *known_timezone != *timezone_)
408 // Not necessary to update the filesystem because |known_timezone| has the
409 // same rules.
410 timezone_.reset(known_timezone->clone());
[email protected]65acb402011-09-30 06:09:06411
[email protected]5f647a32012-07-18 15:36:06412 icu::TimeZone::setDefault(*timezone_);
413 VLOG(1) << "Timezone initially set to " << id;
414}
[email protected]65acb402011-09-30 06:09:06415
[email protected]5f647a32012-07-18 15:36:06416void TimezoneSettingsStubImpl::SetTimezone(const icu::TimeZone& timezone) {
417 // Replace |timezone| by a known timezone with the same rules. If none exists
418 // go on with |timezone|.
419 const icu::TimeZone* known_timezone = GetKnownTimezoneOrNull(timezone);
420 if (!known_timezone)
421 known_timezone = &timezone;
[email protected]65acb402011-09-30 06:09:06422
[email protected]5f647a32012-07-18 15:36:06423 timezone_.reset(known_timezone->clone());
424 icu::TimeZone::setDefault(*known_timezone);
425 FOR_EACH_OBSERVER(Observer, observers_, TimezoneChanged(*known_timezone));
426}
[email protected]65acb402011-09-30 06:09:06427
[email protected]5f647a32012-07-18 15:36:06428// static
429TimezoneSettingsStubImpl* TimezoneSettingsStubImpl::GetInstance() {
430 return Singleton<TimezoneSettingsStubImpl,
431 DefaultSingletonTraits<TimezoneSettingsStubImpl> >::get();
432}
[email protected]65acb402011-09-30 06:09:06433
[email protected]5f647a32012-07-18 15:36:06434TimezoneSettingsStubImpl::TimezoneSettingsStubImpl() {
435 timezone_.reset(icu::TimeZone::createDefault());
436 const icu::TimeZone* known_timezone = GetKnownTimezoneOrNull(*timezone_);
437 if (known_timezone != NULL && *known_timezone != *timezone_)
438 timezone_.reset(known_timezone->clone());
439}
[email protected]65acb402011-09-30 06:09:06440
[email protected]5f647a32012-07-18 15:36:06441} // namespace
[email protected]65acb402011-09-30 06:09:06442
[email protected]5f647a32012-07-18 15:36:06443namespace chromeos {
444namespace system {
445
446TimezoneSettings::Observer::~Observer() {}
447
448// static
[email protected]d43970a72011-07-10 06:24:52449TimezoneSettings* TimezoneSettings::GetInstance() {
[email protected]49c4cf852013-09-27 19:28:24450 if (base::SysInfo::IsRunningOnChromeOS()) {
[email protected]65acb402011-09-30 06:09:06451 return TimezoneSettingsImpl::GetInstance();
452 } else {
453 return TimezoneSettingsStubImpl::GetInstance();
454 }
[email protected]d43970a72011-07-10 06:24:52455}
456
[email protected]5f647a32012-07-18 15:36:06457// static
[email protected]33c4bc792013-12-19 20:52:30458base::string16 TimezoneSettings::GetTimezoneID(const icu::TimeZone& timezone) {
[email protected]5f647a32012-07-18 15:36:06459 icu::UnicodeString id;
460 timezone.getID(id);
[email protected]33c4bc792013-12-19 20:52:30461 return base::string16(id.getBuffer(), id.length());
[email protected]5f647a32012-07-18 15:36:06462}
463
[email protected]d43970a72011-07-10 06:24:52464} // namespace system
465} // namespace chromeos