diff options
Diffstat (limited to 'content/browser')
-rw-r--r-- | content/browser/android/browser_jni_registrar.cc | 11 | ||||
-rw-r--r-- | content/browser/browser_main_loop.cc | 48 | ||||
-rw-r--r-- | content/browser/browser_main_loop.h | 5 | ||||
-rw-r--r-- | content/browser/time_zone_monitor.cc | 31 | ||||
-rw-r--r-- | content/browser/time_zone_monitor.h | 51 | ||||
-rw-r--r-- | content/browser/time_zone_monitor_android.cc | 38 | ||||
-rw-r--r-- | content/browser/time_zone_monitor_android.h | 37 | ||||
-rw-r--r-- | content/browser/time_zone_monitor_chromeos.cc | 37 | ||||
-rw-r--r-- | content/browser/time_zone_monitor_linux.cc | 166 | ||||
-rw-r--r-- | content/browser/time_zone_monitor_mac.mm | 40 | ||||
-rw-r--r-- | content/browser/time_zone_monitor_win.cc | 46 |
11 files changed, 485 insertions, 25 deletions
diff --git a/content/browser/android/browser_jni_registrar.cc b/content/browser/android/browser_jni_registrar.cc index fca55a9..60221e9 100644 --- a/content/browser/android/browser_jni_registrar.cc +++ b/content/browser/android/browser_jni_registrar.cc @@ -35,6 +35,7 @@ #include "content/browser/renderer_host/java/java_bound_object.h" #include "content/browser/screen_orientation/screen_orientation_provider_android.h" #include "content/browser/speech/speech_recognizer_impl_android.h" +#include "content/browser/time_zone_monitor_android.h" #include "content/browser/vibration/vibration_provider_android.h" #include "content/browser/web_contents/web_contents_android.h" @@ -44,15 +45,17 @@ namespace { base::android::RegistrationMethod kContentRegisteredMethods[] = { {"AndroidLocationApiAdapter", content::AndroidLocationApiAdapter::RegisterGeolocationService}, + {"BatteryStatusManagerAndroid", + content::BatteryStatusManagerAndroid::Register}, {"BrowserAccessibilityManager", content::RegisterBrowserAccessibilityManager}, {"BrowserStartupController", content::RegisterBrowserStartupController}, {"ChildProcessLauncher", content::RegisterChildProcessLauncher}, {"ContentSettings", content::ContentSettings::RegisterContentSettings}, - {"ContentViewRenderView", - content::ContentViewRenderView::RegisterContentViewRenderView}, {"ContentVideoView", content::ContentVideoView::RegisterContentVideoView}, {"ContentViewCore", content::RegisterContentViewCore}, + {"ContentViewRenderView", + content::ContentViewRenderView::RegisterContentViewRenderView}, {"DateTimePickerAndroid", content::RegisterDateTimeChooserAndroid}, {"DownloadControllerAndroidImpl", content::DownloadControllerAndroidImpl::RegisterDownloadController}, @@ -75,6 +78,7 @@ base::android::RegistrationMethod kContentRegisteredMethods[] = { {"SensorManagerAndroid", content::SensorManagerAndroid::Register}, {"SpeechRecognizerImplAndroid", content::SpeechRecognizerImplAndroid::RegisterSpeechRecognizer}, + {"TimeZoneMonitorAndroid", content::TimeZoneMonitorAndroid::Register}, {"TouchEventSynthesizer", content::SyntheticGestureTargetAndroid::RegisterTouchEventSynthesizer}, {"TracingControllerAndroid", content::RegisterTracingControllerAndroid}, @@ -82,8 +86,7 @@ base::android::RegistrationMethod kContentRegisteredMethods[] = { {"WebContentsAndroid", content::WebContentsAndroid::Register}, {"WebContentsObserverAndroid", content::RegisterWebContentsObserverAndroid}, {"WebViewStatics", content::RegisterWebViewStatics}, - {"BatterStatusManagerAndroid", - content::BatteryStatusManagerAndroid::Register}, }; +}; } // namespace diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc index 316d7c3..b5db4bc1 100644 --- a/content/browser/browser_main_loop.cc +++ b/content/browser/browser_main_loop.cc @@ -41,6 +41,7 @@ #include "content/browser/renderer_host/media/media_stream_manager.h" #include "content/browser/speech/speech_recognition_manager_impl.h" #include "content/browser/startup_task_runner.h" +#include "content/browser/time_zone_monitor.h" #include "content/browser/webui/content_web_ui_controller_factory.h" #include "content/browser/webui/url_data_manager.h" #include "content/public/browser/browser_main_parts.h" @@ -325,7 +326,7 @@ BrowserMainLoop::~BrowserMainLoop() { } void BrowserMainLoop::Init() { - TRACE_EVENT0("startup", "BrowserMainLoop::Init") + TRACE_EVENT0("startup", "BrowserMainLoop::Init"); parts_.reset( GetContentClient()->browser()->CreateBrowserMainParts(parameters_)); } @@ -397,7 +398,7 @@ void BrowserMainLoop::EarlyInitialization() { } void BrowserMainLoop::MainMessageLoopStart() { - TRACE_EVENT0("startup", "BrowserMainLoop::MainMessageLoopStart") + TRACE_EVENT0("startup", "BrowserMainLoop::MainMessageLoopStart"); if (parts_) { TRACE_EVENT0("startup", "BrowserMainLoop::MainMessageLoopStart:PreMainMessageLoopStart"); @@ -420,50 +421,51 @@ void BrowserMainLoop::MainMessageLoopStart() { InitializeMainThread(); { - TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:SystemMonitor") + TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:SystemMonitor"); system_monitor_.reset(new base::SystemMonitor); } { - TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:PowerMonitor") + TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:PowerMonitor"); scoped_ptr<base::PowerMonitorSource> power_monitor_source( new base::PowerMonitorDeviceSource()); power_monitor_.reset(new base::PowerMonitor(power_monitor_source.Pass())); } { - TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:HighResTimerManager") + TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:HighResTimerManager"); hi_res_timer_manager_.reset(new base::HighResolutionTimerManager); } { - TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:NetworkChangeNotifier") + TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:NetworkChangeNotifier"); network_change_notifier_.reset(net::NetworkChangeNotifier::Create()); } #if !defined(OS_IOS) { - TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:MediaFeatures") + TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:MediaFeatures"); media::InitializeCPUSpecificMediaFeatures(); } { - TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:AudioMan") + TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:AudioMan"); audio_manager_.reset(media::AudioManager::Create( MediaInternals::GetInstance())); } { - TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:MidiManager") + TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:MidiManager"); midi_manager_.reset(media::MidiManager::Create()); } { - TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:ContentWebUIController") + TRACE_EVENT0("startup", + "BrowserMainLoop::Subsystem:ContentWebUIController"); WebUIControllerFactory::RegisterFactory( ContentWebUIControllerFactory::GetInstance()); } { - TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:AudioMirroringManager") + TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:AudioMirroringManager"); audio_mirroring_manager_.reset(new AudioMirroringManager()); } { - TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:OnlineStateObserver") + TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:OnlineStateObserver"); online_state_observer_.reset(new BrowserOnlineStateObserver); } @@ -485,20 +487,20 @@ void BrowserMainLoop::MainMessageLoopStart() { // message loop to avoid calling MessagePumpForUI::ScheduleWork() before // MessagePumpForUI::Start() as it will crash the browser. if (is_tracing_startup_) { - TRACE_EVENT0("startup", "BrowserMainLoop::InitStartupTracing") + TRACE_EVENT0("startup", "BrowserMainLoop::InitStartupTracing"); InitStartupTracing(parsed_command_line_); } #endif // !defined(OS_IOS) #if defined(OS_ANDROID) { - TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:SurfaceTexturePeer") + TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:SurfaceTexturePeer"); SurfaceTexturePeer::InitInstance(new SurfaceTexturePeerBrowserImpl()); } #endif if (parsed_command_line_.HasSwitch(switches::kMemoryMetrics)) { - TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:MemoryObserver") + TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:MemoryObserver"); memory_observer_.reset(new MemoryObserver()); base::MessageLoop::current()->AddTaskObserver(memory_observer_.get()); } @@ -526,7 +528,7 @@ int BrowserMainLoop::PreCreateThreads() { // but must be created on the main thread. The service ctor is // inexpensive and does not invoke the io_thread() accessor. { - TRACE_EVENT0("startup", "BrowserMainLoop::CreateThreads:PluginService") + TRACE_EVENT0("startup", "BrowserMainLoop::CreateThreads:PluginService"); PluginService::GetInstance()->Init(); } #endif @@ -712,7 +714,7 @@ void BrowserMainLoop::ShutdownThreadsAndCleanUp() { // Called early, nothing to do return; } - TRACE_EVENT0("shutdown", "BrowserMainLoop::ShutdownThreadsAndCleanUp") + TRACE_EVENT0("shutdown", "BrowserMainLoop::ShutdownThreadsAndCleanUp"); // Teardown may start in PostMainMessageLoopRun, and during teardown we // need to be able to perform IO. @@ -893,7 +895,7 @@ void BrowserMainLoop::ShutdownThreadsAndCleanUp() { } void BrowserMainLoop::InitializeMainThread() { - TRACE_EVENT0("startup", "BrowserMainLoop::InitializeMainThread") + TRACE_EVENT0("startup", "BrowserMainLoop::InitializeMainThread"); const char* kThreadName = "CrBrowserMain"; base::PlatformThread::SetName(kThreadName); if (main_message_loop_) @@ -905,7 +907,7 @@ void BrowserMainLoop::InitializeMainThread() { } int BrowserMainLoop::BrowserThreadsStarted() { - TRACE_EVENT0("startup", "BrowserMainLoop::BrowserThreadsStarted") + TRACE_EVENT0("startup", "BrowserMainLoop::BrowserThreadsStarted"); #if !defined(OS_IOS) indexed_db_thread_.reset(new base::Thread("IndexedDB")); @@ -992,6 +994,12 @@ int BrowserMainLoop::BrowserThreadsStarted() { io_thread_->message_loop_proxy(), main_thread_->message_loop_proxy()); } + { + TRACE_EVENT0("startup", + "BrowserMainLoop::BrowserThreadsStarted::TimeZoneMonitor"); + time_zone_monitor_ = TimeZoneMonitor::Create(); + } + // Alert the clipboard class to which threads are allowed to access the // clipboard: std::vector<base::PlatformThreadId> allowed_clipboard_threads; @@ -1030,7 +1038,7 @@ int BrowserMainLoop::BrowserThreadsStarted() { } bool BrowserMainLoop::InitializeToolkit() { - TRACE_EVENT0("startup", "BrowserMainLoop::InitializeToolkit") + TRACE_EVENT0("startup", "BrowserMainLoop::InitializeToolkit"); // TODO(evan): this function is rather subtle, due to the variety // of intersecting ifdefs we have. To keep it easy to follow, there // are no #else branches on any #ifs. diff --git a/content/browser/browser_main_loop.h b/content/browser/browser_main_loop.h index e308117..f38ac42 100644 --- a/content/browser/browser_main_loop.h +++ b/content/browser/browser_main_loop.h @@ -44,13 +44,15 @@ class MediaStreamManager; class ResourceDispatcherHostImpl; class SpeechRecognitionManagerImpl; class StartupTaskRunner; -class SystemMessageWindowWin; +class TimeZoneMonitor; struct MainFunctionParams; #if defined(OS_LINUX) class DeviceMonitorLinux; #elif defined(OS_MACOSX) class DeviceMonitorMac; +#elif defined(OS_WIN) +class SystemMessageWindowWin; #endif // Implements the main browser loop stages called from BrowserMainRunner. @@ -173,6 +175,7 @@ class CONTENT_EXPORT BrowserMainLoop { // Members initialized in |BrowserThreadsStarted()| -------------------------- scoped_ptr<ResourceDispatcherHostImpl> resource_dispatcher_host_; scoped_ptr<SpeechRecognitionManagerImpl> speech_recognition_manager_; + scoped_ptr<TimeZoneMonitor> time_zone_monitor_; // Members initialized in |RunMainMessageLoopParts()| ------------------------ scoped_ptr<BrowserProcessSubThread> db_thread_; diff --git a/content/browser/time_zone_monitor.cc b/content/browser/time_zone_monitor.cc new file mode 100644 index 0000000..0c17f8e --- /dev/null +++ b/content/browser/time_zone_monitor.cc @@ -0,0 +1,31 @@ +// Copyright 2014 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 "content/browser/time_zone_monitor.h" + +#include "base/logging.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/render_process_host.h" + +namespace content { + +TimeZoneMonitor::TimeZoneMonitor() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); +} + +TimeZoneMonitor::~TimeZoneMonitor() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); +} + +void TimeZoneMonitor::NotifyRenderers() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + for (RenderProcessHost::iterator iterator = + RenderProcessHost::AllHostsIterator(); + !iterator.IsAtEnd(); + iterator.Advance()) { + iterator.GetCurrentValue()->NotifyTimezoneChange(); + } +} + +} // namespace content diff --git a/content/browser/time_zone_monitor.h b/content/browser/time_zone_monitor.h new file mode 100644 index 0000000..fed177f --- /dev/null +++ b/content/browser/time_zone_monitor.h @@ -0,0 +1,51 @@ +// Copyright 2014 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 CONTENT_BROWSER_TIME_ZONE_MONITOR_H_ +#define CONTENT_BROWSER_TIME_ZONE_MONITOR_H_ + +#include "base/basictypes.h" +#include "base/memory/scoped_ptr.h" + +namespace content { + +// TimeZoneMonitor watches the system time zone, and notifies renderers +// when it changes. Some renderer code caches the system time zone, so +// this notification is necessary to inform such code that cached +// timezone data may have become invalid. Due to sandboxing, it is not +// possible for renderer processes to monitor for system time zone +// changes themselves, so this must happen in the browser process. +// +// Sandboxing also may prevent renderer processes from reading the time +// zone when it does change, so platforms may have to deal with this in +// platform-specific ways: +// - Mac uses a sandbox hole defined in content/renderer/renderer.sb. +// - Linux-based platforms use ProxyLocaltimeCallToBrowser in +// content/zygote/zygote_main_linux.cc and HandleLocaltime in +// content/browser/renderer_host/sandbox_ipc_linux.cc to override +// localtime in renderer processes with custom code that calls +// localtime in the browser process via Chrome IPC. + +class TimeZoneMonitor { + public: + // Returns a new TimeZoneMonitor object (likely a subclass) specific to the + // platform. + static scoped_ptr<TimeZoneMonitor> Create(); + + virtual ~TimeZoneMonitor(); + + protected: + TimeZoneMonitor(); + + // Loop over all renderers and notify them that the system time zone may + // have changed. + void NotifyRenderers(); + + private: + DISALLOW_COPY_AND_ASSIGN(TimeZoneMonitor); +}; + +} // namespace content + +#endif // CONTENT_BROWSER_TIME_ZONE_MONITOR_H_ diff --git a/content/browser/time_zone_monitor_android.cc b/content/browser/time_zone_monitor_android.cc new file mode 100644 index 0000000..af57f80 --- /dev/null +++ b/content/browser/time_zone_monitor_android.cc @@ -0,0 +1,38 @@ +// Copyright 2014 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 "content/browser/time_zone_monitor_android.h" + +#include "base/android/jni_android.h" +#include "jni/TimeZoneMonitor_jni.h" + +namespace content { + +TimeZoneMonitorAndroid::TimeZoneMonitorAndroid() : TimeZoneMonitor() { + impl_.Reset(Java_TimeZoneMonitor_getInstance( + base::android::AttachCurrentThread(), + base::android::GetApplicationContext(), + reinterpret_cast<intptr_t>(this))); +} + +TimeZoneMonitorAndroid::~TimeZoneMonitorAndroid() { + Java_TimeZoneMonitor_stop(base::android::AttachCurrentThread(), impl_.obj()); +} + +// static +bool TimeZoneMonitorAndroid::Register(JNIEnv* env) { + return RegisterNativesImpl(env); +} + +void TimeZoneMonitorAndroid::TimeZoneChangedFromJava(JNIEnv* env, + jobject caller) { + NotifyRenderers(); +} + +// static +scoped_ptr<TimeZoneMonitor> TimeZoneMonitor::Create() { + return scoped_ptr<TimeZoneMonitor>(new TimeZoneMonitorAndroid()); +} + +} // namespace content diff --git a/content/browser/time_zone_monitor_android.h b/content/browser/time_zone_monitor_android.h new file mode 100644 index 0000000..a462eb5 --- /dev/null +++ b/content/browser/time_zone_monitor_android.h @@ -0,0 +1,37 @@ +// Copyright 2014 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 CONTENT_BROWSER_TIME_ZONE_MONITOR_ANDROID_H_ +#define CONTENT_BROWSER_TIME_ZONE_MONITOR_ANDROID_H_ + +#include "content/browser/time_zone_monitor.h" + +#include <jni.h> + +#include "base/android/scoped_java_ref.h" +#include "base/basictypes.h" + +namespace content { + +class TimeZoneMonitorAndroid : public TimeZoneMonitor { + public: + TimeZoneMonitorAndroid(); + virtual ~TimeZoneMonitorAndroid(); + + // Must be called at startup. + static bool Register(JNIEnv* env); + + // Called by the Java implementation when the system time zone changes. + void TimeZoneChangedFromJava(JNIEnv* env, jobject caller); + + private: + // Java provider of system time zone change notifications. + base::android::ScopedJavaGlobalRef<jobject> impl_; + + DISALLOW_COPY_AND_ASSIGN(TimeZoneMonitorAndroid); +}; + +} // namespace content + +#endif // CONTENT_BROWSER_TIME_ZONE_MONITOR_ANDROID_H_ diff --git a/content/browser/time_zone_monitor_chromeos.cc b/content/browser/time_zone_monitor_chromeos.cc new file mode 100644 index 0000000..6fc885e --- /dev/null +++ b/content/browser/time_zone_monitor_chromeos.cc @@ -0,0 +1,37 @@ +// Copyright 2014 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 "content/browser/time_zone_monitor.h" + +#include "chromeos/settings/timezone_settings.h" + +namespace content { + +class TimeZoneMonitorChromeOS + : public TimeZoneMonitor, + public chromeos::system::TimezoneSettings::Observer { + public: + TimeZoneMonitorChromeOS() : TimeZoneMonitor() { + chromeos::system::TimezoneSettings::GetInstance()->AddObserver(this); + } + + virtual ~TimeZoneMonitorChromeOS() { + chromeos::system::TimezoneSettings::GetInstance()->RemoveObserver(this); + } + + // chromeos::system::TimezoneSettings::Observer implementation. + virtual void TimezoneChanged(const icu::TimeZone& time_zone) OVERRIDE { + NotifyRenderers(); + } + + private: + DISALLOW_COPY_AND_ASSIGN(TimeZoneMonitorChromeOS); +}; + +// static +scoped_ptr<TimeZoneMonitor> TimeZoneMonitor::Create() { + return scoped_ptr<TimeZoneMonitor>(new TimeZoneMonitorChromeOS()); +} + +} // namespace content diff --git a/content/browser/time_zone_monitor_linux.cc b/content/browser/time_zone_monitor_linux.cc new file mode 100644 index 0000000..f8cae0e --- /dev/null +++ b/content/browser/time_zone_monitor_linux.cc @@ -0,0 +1,166 @@ +// Copyright 2014 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 "content/browser/time_zone_monitor.h" + +#include <stdlib.h> + +#include <vector> + +#include "base/basictypes.h" +#include "base/bind.h" +#include "base/files/file_path.h" +#include "base/files/file_path_watcher.h" +#include "base/memory/ref_counted.h" +#include "base/stl_util.h" +#include "content/public/browser/browser_thread.h" + +#if !defined(OS_CHROMEOS) + +namespace content { + +namespace { +class TimeZoneMonitorLinuxImpl; +} // namespace + +class TimeZoneMonitorLinux : public TimeZoneMonitor { + public: + TimeZoneMonitorLinux(); + virtual ~TimeZoneMonitorLinux(); + + void NotifyRenderersFromImpl() { + NotifyRenderers(); + } + + private: + scoped_refptr<TimeZoneMonitorLinuxImpl> impl_; + + DISALLOW_COPY_AND_ASSIGN(TimeZoneMonitorLinux); +}; + +namespace { + +// FilePathWatcher needs to run on the FILE thread, but TimeZoneMonitor runs +// on the UI thread. TimeZoneMonitorLinuxImpl is the bridge between these +// threads. +class TimeZoneMonitorLinuxImpl + : public base::RefCountedThreadSafe<TimeZoneMonitorLinuxImpl> { + public: + explicit TimeZoneMonitorLinuxImpl(TimeZoneMonitorLinux* owner) + : base::RefCountedThreadSafe<TimeZoneMonitorLinuxImpl>(), + file_path_watchers_(), + owner_(owner) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + BrowserThread::PostTask( + BrowserThread::FILE, + FROM_HERE, + base::Bind(&TimeZoneMonitorLinuxImpl::StartWatchingOnFileThread, this)); + } + + void StopWatching() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + owner_ = NULL; + BrowserThread::PostTask( + BrowserThread::FILE, + FROM_HERE, + base::Bind(&TimeZoneMonitorLinuxImpl::StopWatchingOnFileThread, this)); + } + + private: + friend class base::RefCountedThreadSafe<TimeZoneMonitorLinuxImpl>; + + ~TimeZoneMonitorLinuxImpl() { + DCHECK(!owner_); + STLDeleteElements(&file_path_watchers_); + } + + void StartWatchingOnFileThread() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); + + // There is no true standard for where time zone information is actually + // stored. glibc uses /etc/localtime, uClibc uses /etc/TZ, and some older + // systems store the name of the time zone file within /usr/share/zoneinfo + // in /etc/timezone. Different libraries and custom builds may mean that + // still more paths are used. Just watch all three of these paths, because + // false positives are harmless, assuming the false positive rate is + // reasonable. + const char* kFilesToWatch[] = { + "/etc/localtime", + "/etc/timezone", + "/etc/TZ", + }; + + for (size_t index = 0; index < arraysize(kFilesToWatch); ++index) { + file_path_watchers_.push_back(new base::FilePathWatcher()); + file_path_watchers_.back()->Watch( + base::FilePath(kFilesToWatch[index]), + false, + base::Bind(&TimeZoneMonitorLinuxImpl::OnTimeZoneFileChanged, this)); + } + } + + void StopWatchingOnFileThread() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); + STLDeleteElements(&file_path_watchers_); + } + + void OnTimeZoneFileChanged(const base::FilePath& path, bool error) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); + BrowserThread::PostTask( + BrowserThread::UI, + FROM_HERE, + base::Bind(&TimeZoneMonitorLinuxImpl::OnTimeZoneFileChangedOnUIThread, + this)); + } + + void OnTimeZoneFileChangedOnUIThread() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + if (owner_) { + owner_->NotifyRenderersFromImpl(); + } + } + + std::vector<base::FilePathWatcher*> file_path_watchers_; + TimeZoneMonitorLinux* owner_; + + DISALLOW_COPY_AND_ASSIGN(TimeZoneMonitorLinuxImpl); +}; + +} // namespace + +TimeZoneMonitorLinux::TimeZoneMonitorLinux() + : TimeZoneMonitor(), + impl_() { + // If the TZ environment variable is set, its value specifies the time zone + // specification, and it's pointless to monitor any files in /etc for + // changes because such changes would have no effect on the TZ environment + // variable and thus the interpretation of the local time zone in the + // or renderer processes. + // + // The system-specific format for the TZ environment variable beginning with + // a colon is implemented by glibc as the path to a time zone data file, and + // it would be possible to monitor this file for changes if a TZ variable of + // this format was encountered, but this is not necessary: when loading a + // time zone specification in this way, glibc does not reload the file when + // it changes, so it's pointless to respond to a notification that it has + // changed. + if (!getenv("TZ")) { + impl_ = new TimeZoneMonitorLinuxImpl(this); + } +} + +TimeZoneMonitorLinux::~TimeZoneMonitorLinux() { + if (impl_) { + impl_->StopWatching(); + } +} + +// static +scoped_ptr<TimeZoneMonitor> TimeZoneMonitor::Create() { + return scoped_ptr<TimeZoneMonitor>(new TimeZoneMonitorLinux()); +} + +} // namespace content + +#endif // !OS_CHROMEOS diff --git a/content/browser/time_zone_monitor_mac.mm b/content/browser/time_zone_monitor_mac.mm new file mode 100644 index 0000000..c435aae --- /dev/null +++ b/content/browser/time_zone_monitor_mac.mm @@ -0,0 +1,40 @@ +// Copyright 2014 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 "content/browser/time_zone_monitor.h" + +#import <Foundation/Foundation.h> + +namespace content { + +class TimeZoneMonitorMac : public TimeZoneMonitor { + public: + TimeZoneMonitorMac() : TimeZoneMonitor() { + NSNotificationCenter* nc = [NSNotificationCenter defaultCenter]; + notification_observer_ = + [nc addObserverForName:NSSystemTimeZoneDidChangeNotification + object:nil + queue:nil + usingBlock:^(NSNotification* notification) { + NotifyRenderers(); + }]; + } + + virtual ~TimeZoneMonitorMac() { + NSNotificationCenter* nc = [NSNotificationCenter defaultCenter]; + [nc removeObserver:notification_observer_]; + } + + private: + id notification_observer_; + + DISALLOW_COPY_AND_ASSIGN(TimeZoneMonitorMac); +}; + +// static +scoped_ptr<TimeZoneMonitor> TimeZoneMonitor::Create() { + return scoped_ptr<TimeZoneMonitor>(new TimeZoneMonitorMac()); +} + +} // namespace content diff --git a/content/browser/time_zone_monitor_win.cc b/content/browser/time_zone_monitor_win.cc new file mode 100644 index 0000000..6d99b94 --- /dev/null +++ b/content/browser/time_zone_monitor_win.cc @@ -0,0 +1,46 @@ +// Copyright 2014 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 "content/browser/time_zone_monitor.h" + +#include <windows.h> + +#include "base/basictypes.h" +#include "ui/gfx/win/singleton_hwnd.h" + +namespace content { + +class TimeZoneMonitorWin : public TimeZoneMonitor, + public gfx::SingletonHwnd::Observer { + public: + TimeZoneMonitorWin() : TimeZoneMonitor() { + gfx::SingletonHwnd::GetInstance()->AddObserver(this); + } + + virtual ~TimeZoneMonitorWin() { + gfx::SingletonHwnd::GetInstance()->RemoveObserver(this); + } + + // gfx::SingletonHwnd::Observer implementation. + virtual void OnWndProc(HWND hwnd, + UINT message, + WPARAM wparam, + LPARAM lparam) OVERRIDE { + if (message != WM_TIMECHANGE) { + return; + } + + NotifyRenderers(); + } + + private: + DISALLOW_COPY_AND_ASSIGN(TimeZoneMonitorWin); +}; + +// static +scoped_ptr<TimeZoneMonitor> TimeZoneMonitor::Create() { + return scoped_ptr<TimeZoneMonitor>(new TimeZoneMonitorWin()); +} + +} // namespace content |