summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbajones@chromium.org <bajones@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-02 22:09:13 +0000
committerbajones@chromium.org <bajones@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-02 22:09:13 +0000
commit9dd901522edbaf51a00f03504cac30553b5dbfde (patch)
tree5e812fac198a30a83f80490814b691ba4b869573
parent1d1b537362626b73838ebbe55d4aed3f8116e7d9 (diff)
downloadchromium_src-9dd901522edbaf51a00f03504cac30553b5dbfde.zip
chromium_src-9dd901522edbaf51a00f03504cac30553b5dbfde.tar.gz
chromium_src-9dd901522edbaf51a00f03504cac30553b5dbfde.tar.bz2
Created multi-process-friendly PowerMonitor interface.
PowerMonitor status is now captured in the browser process, which has the appropriate UI thread, and then sent via IPC to other processes which are interested in the power state. BUG=236031 R=apatrick@chromium.org, jam@chromium.org, jar@chromium.org, jvoung@chromium.org, kbr@chromium.org, mpcomplete@chromium.org, palmer@chromium.org, piman@chromium.org, vandebo@chromium.org Review URL: https://codereview.chromium.org/17074009 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@215381 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--base/android/base_jni_registrar.cc2
-rw-r--r--base/base.gypi20
-rw-r--r--base/power_monitor/power_monitor.cc65
-rw-r--r--base/power_monitor/power_monitor.h113
-rw-r--r--base/power_monitor/power_monitor_device_source.cc39
-rw-r--r--base/power_monitor/power_monitor_device_source.h110
-rw-r--r--base/power_monitor/power_monitor_device_source_android.cc (renamed from base/power_monitor/power_monitor_android.cc)19
-rw-r--r--base/power_monitor/power_monitor_device_source_android.h (renamed from base/power_monitor/power_monitor_android.h)8
-rw-r--r--base/power_monitor/power_monitor_device_source_ios.mm (renamed from base/power_monitor/power_monitor_ios.mm)6
-rw-r--r--base/power_monitor/power_monitor_device_source_mac.mm (renamed from base/power_monitor/power_monitor_mac.mm)24
-rw-r--r--base/power_monitor/power_monitor_device_source_posix.cc (renamed from base/power_monitor/power_monitor_posix.cc)4
-rw-r--r--base/power_monitor/power_monitor_device_source_win.cc (renamed from base/power_monitor/power_monitor_win.cc)46
-rw-r--r--base/power_monitor/power_monitor_source.cc66
-rw-r--r--base/power_monitor/power_monitor_source.h65
-rw-r--r--base/power_monitor/power_monitor_test_base.cc64
-rw-r--r--base/power_monitor/power_monitor_test_base.h50
-rw-r--r--base/power_monitor/power_monitor_unittest.cc112
-rw-r--r--base/timer/hi_res_timer_manager_unittest.cc6
-rw-r--r--base/timer/hi_res_timer_manager_win.cc3
-rw-r--r--chrome/browser/extensions/event_router_forwarder_unittest.cc7
-rw-r--r--chrome/nacl/nacl_exe_win_64.cc5
-rw-r--r--components/nacl/loader/nacl_main.cc5
-rw-r--r--content/app/content_main_runner.cc4
-rw-r--r--content/browser/browser_child_process_host_impl.cc3
-rw-r--r--content/browser/browser_child_process_host_impl.h3
-rw-r--r--content/browser/browser_main_loop.cc5
-rw-r--r--content/browser/power_monitor_message_broadcaster.cc39
-rw-r--r--content/browser/power_monitor_message_broadcaster.h41
-rw-r--r--content/browser/power_monitor_message_broadcaster_unittest.cc109
-rw-r--r--content/browser/renderer_host/render_process_host_impl.cc3
-rw-r--r--content/browser/renderer_host/render_process_host_impl.h4
-rw-r--r--content/child/child_thread.cc11
-rw-r--r--content/child/child_thread.h3
-rw-r--r--content/child/power_monitor_broadcast_source.cc108
-rw-r--r--content/child/power_monitor_broadcast_source.h44
-rw-r--r--content/child/power_monitor_broadcast_source_unittest.cc95
-rw-r--r--content/common/content_message_generator.h1
-rw-r--r--content/common/power_monitor_messages.h26
-rw-r--r--content/content_browser.gypi2
-rw-r--r--content/content_child.gypi2
-rw-r--r--content/content_common.gypi1
-rw-r--r--content/content_tests.gypi2
-rw-r--r--content/plugin/plugin_main.cc5
-rw-r--r--content/public/test/browser_test_base.cc4
-rw-r--r--content/renderer/renderer_main.cc6
-rw-r--r--content/utility/utility_main.cc6
-rw-r--r--content/worker/worker_main.cc6
-rw-r--r--ipc/ipc_message_start.h1
48 files changed, 1067 insertions, 306 deletions
diff --git a/base/android/base_jni_registrar.cc b/base/android/base_jni_registrar.cc
index 706290b..ea4c37b 100644
--- a/base/android/base_jni_registrar.cc
+++ b/base/android/base_jni_registrar.cc
@@ -18,7 +18,7 @@
#include "base/basictypes.h"
#include "base/debug/trace_event.h"
#include "base/message_loop/message_pump_android.h"
-#include "base/power_monitor/power_monitor_android.h"
+#include "base/power_monitor/power_monitor_device_source_android.h"
#if defined(GOOGLE_TV)
#include "base/android/context_types.h"
diff --git a/base/base.gypi b/base/base.gypi
index bd89f3e..3a57e24 100644
--- a/base/base.gypi
+++ b/base/base.gypi
@@ -378,12 +378,18 @@
'posix/unix_domain_socket_linux.h',
'power_monitor/power_monitor.cc',
'power_monitor/power_monitor.h',
- 'power_monitor/power_monitor_android.cc',
- 'power_monitor/power_monitor_android.h',
- 'power_monitor/power_monitor_ios.mm',
- 'power_monitor/power_monitor_mac.mm',
- 'power_monitor/power_monitor_posix.cc',
- 'power_monitor/power_monitor_win.cc',
+ 'power_monitor/power_monitor_device_source_android.cc',
+ 'power_monitor/power_monitor_device_source_android.h',
+ 'power_monitor/power_monitor_device_source.cc',
+ 'power_monitor/power_monitor_device_source.h',
+ 'power_monitor/power_monitor_device_source_ios.mm',
+ 'power_monitor/power_monitor_device_source_mac.mm',
+ 'power_monitor/power_monitor_device_source_posix.cc',
+ 'power_monitor/power_monitor_device_source_win.cc',
+ 'power_monitor/power_monitor_source.cc',
+ 'power_monitor/power_monitor_source.h',
+ 'power_monitor/power_monitor_test_base.cc',
+ 'power_monitor/power_monitor_test_base.h',
'power_monitor/power_observer.h',
'process/internal_linux.cc',
'process/internal_linux.h',
@@ -726,7 +732,7 @@
'base_paths_posix.cc',
'files/file_path_watcher_kqueue.cc',
'files/file_path_watcher_stub.cc',
- 'power_monitor/power_monitor_posix.cc',
+ 'power_monitor/power_monitor_device_source_posix.cc',
],
'sources/': [
['include', '^debug/proc_maps_linux\\.cc$'],
diff --git a/base/power_monitor/power_monitor.cc b/base/power_monitor/power_monitor.cc
index 87188f1..14dc4b5 100644
--- a/base/power_monitor/power_monitor.cc
+++ b/base/power_monitor/power_monitor.cc
@@ -3,41 +3,20 @@
// found in the LICENSE file.
#include "base/power_monitor/power_monitor.h"
-
-#include "base/time/time.h"
+#include "base/power_monitor/power_monitor_source.h"
namespace base {
static PowerMonitor* g_power_monitor = NULL;
-#if defined(ENABLE_BATTERY_MONITORING)
-// The amount of time (in ms) to wait before running the initial
-// battery check.
-static int kDelayedBatteryCheckMs = 10 * 1000;
-#endif // defined(ENABLE_BATTERY_MONITORING)
-
-PowerMonitor::PowerMonitor()
+PowerMonitor::PowerMonitor(scoped_ptr<PowerMonitorSource> source)
: observers_(new ObserverListThreadSafe<PowerObserver>()),
- battery_in_use_(false),
- suspended_(false) {
+ source_(source.Pass()) {
DCHECK(!g_power_monitor);
g_power_monitor = this;
-
- DCHECK(MessageLoop::current());
-#if defined(ENABLE_BATTERY_MONITORING)
- delayed_battery_check_.Start(FROM_HERE,
- base::TimeDelta::FromMilliseconds(kDelayedBatteryCheckMs), this,
- &PowerMonitor::BatteryCheck);
-#endif // defined(ENABLE_BATTERY_MONITORING)
-#if defined(OS_MACOSX)
- PlatformInit();
-#endif
}
PowerMonitor::~PowerMonitor() {
-#if defined(OS_MACOSX)
- PlatformDestroy();
-#endif
DCHECK_EQ(this, g_power_monitor);
g_power_monitor = NULL;
}
@@ -55,42 +34,18 @@ void PowerMonitor::RemoveObserver(PowerObserver* obs) {
observers_->RemoveObserver(obs);
}
-void PowerMonitor::ProcessPowerEvent(PowerEvent event_id) {
- // Suppress duplicate notifications. Some platforms may
- // send multiple notifications of the same event.
- switch (event_id) {
- case POWER_STATE_EVENT:
- {
- bool on_battery = IsBatteryPower();
- if (on_battery != battery_in_use_) {
- battery_in_use_ = on_battery;
- NotifyPowerStateChange();
- }
- }
- break;
- case RESUME_EVENT:
- if (suspended_) {
- suspended_ = false;
- NotifyResume();
- }
- break;
- case SUSPEND_EVENT:
- if (!suspended_) {
- suspended_ = true;
- NotifySuspend();
- }
- break;
- }
+PowerMonitorSource* PowerMonitor::Source() {
+ return source_.get();
}
-void PowerMonitor::BatteryCheck() {
- ProcessPowerEvent(PowerMonitor::POWER_STATE_EVENT);
+bool PowerMonitor::IsOnBatteryPower() {
+ return source_->IsOnBatteryPower();
}
-void PowerMonitor::NotifyPowerStateChange() {
- DVLOG(1) << "PowerStateChange: " << (BatteryPower() ? "On" : "Off")
+void PowerMonitor::NotifyPowerStateChange(bool battery_in_use) {
+ DVLOG(1) << "PowerStateChange: " << (battery_in_use ? "On" : "Off")
<< " battery";
- observers_->Notify(&PowerObserver::OnPowerStateChange, BatteryPower());
+ observers_->Notify(&PowerObserver::OnPowerStateChange, battery_in_use);
}
void PowerMonitor::NotifySuspend() {
diff --git a/base/power_monitor/power_monitor.h b/base/power_monitor/power_monitor.h
index fc3df48..4acb3bf 100644
--- a/base/power_monitor/power_monitor.h
+++ b/base/power_monitor/power_monitor.h
@@ -11,132 +11,41 @@
#include "base/observer_list_threadsafe.h"
#include "base/power_monitor/power_observer.h"
-#if defined(OS_WIN)
-#include <windows.h>
-
-// Windows HiRes timers drain the battery faster so we need to know the battery
-// status. This isn't true for other platforms.
-#define ENABLE_BATTERY_MONITORING 1
-#else
-#undef ENABLE_BATTERY_MONITORING
-#endif // !OS_WIN
-
-#if defined(ENABLE_BATTERY_MONITORING)
-#include "base/timer/timer.h"
-#endif // defined(ENABLE_BATTERY_MONITORING)
-
-#if defined(OS_IOS)
-#include <objc/runtime.h>
-#endif // OS_IOS
-
namespace base {
+class PowerMonitorSource;
+
// A class used to monitor the power state change and notify the observers about
// the change event.
class BASE_EXPORT PowerMonitor {
public:
- // Normalized list of power events.
- enum PowerEvent {
- POWER_STATE_EVENT, // The Power status of the system has changed.
- SUSPEND_EVENT, // The system is being suspended.
- RESUME_EVENT // The system is being resumed.
- };
-
- PowerMonitor();
+ // Takes ownership of |source|.
+ explicit PowerMonitor(scoped_ptr<PowerMonitorSource> source);
~PowerMonitor();
- // Get the application-wide PowerMonitor (if not present, returns NULL).
+ // Get the process-wide PowerMonitor (if not present, returns NULL).
static PowerMonitor* Get();
-#if defined(OS_MACOSX)
- // Allocate system resources needed by the PowerMonitor class.
- //
- // This function must be called before instantiating an instance of the class
- // and before the Sandbox is initialized.
-#if !defined(OS_IOS)
- static void AllocateSystemIOPorts();
-#else
- static void AllocateSystemIOPorts() {}
-#endif // OS_IOS
-#endif // OS_MACOSX
-
// Add and remove an observer.
// Can be called from any thread.
// Must not be called from within a notification callback.
void AddObserver(PowerObserver* observer);
void RemoveObserver(PowerObserver* observer);
- // Is the computer currently on battery power. Can be called on any thread.
- bool BatteryPower() const {
- // Using a lock here is not necessary for just a bool.
- return battery_in_use_;
- }
+ // Is the computer currently on battery power.
+ bool IsOnBatteryPower();
private:
- friend class PowerMonitorTest;
- // A friend function that is allowed to access the private ProcessPowerEvent.
- friend void ProcessPowerEventHelper(PowerEvent);
-
-#if defined(OS_WIN)
- // Represents a message-only window for power message handling on Windows.
- // Only allow PowerMonitor to create it.
- class PowerMessageWindow {
- public:
- PowerMessageWindow();
- ~PowerMessageWindow();
+ friend class PowerMonitorSource;
- private:
- void ProcessWmPowerBroadcastMessage(int event_id);
- LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
- WPARAM wparam, LPARAM lparam);
- static LRESULT CALLBACK WndProcThunk(HWND hwnd,
- UINT message,
- WPARAM wparam,
- LPARAM lparam);
- // Instance of the module containing the window procedure.
- HMODULE instance_;
- // A hidden message-only window.
- HWND message_hwnd_;
- };
-#endif // OS_WIN
+ PowerMonitorSource* Source();
-#if defined(OS_MACOSX)
- void PlatformInit();
- void PlatformDestroy();
-#endif
-
- // Cross-platform handling of a power event.
- void ProcessPowerEvent(PowerEvent event_id);
-
- // Platform-specific method to check whether the system is currently
- // running on battery power. Returns true if running on batteries,
- // false otherwise.
- bool IsBatteryPower();
-
- // Checks the battery status and notifies observers if the battery
- // status has changed.
- void BatteryCheck();
-
- void NotifyPowerStateChange();
+ void NotifyPowerStateChange(bool battery_in_use);
void NotifySuspend();
void NotifyResume();
-#if defined(OS_IOS)
- // Holds pointers to system event notification observers.
- std::vector<id> notification_observers_;
-#endif
-
-#if defined(ENABLE_BATTERY_MONITORING)
- base::OneShotTimer<PowerMonitor> delayed_battery_check_;
-#endif
-
scoped_refptr<ObserverListThreadSafe<PowerObserver> > observers_;
- bool battery_in_use_;
- bool suspended_;
-
-#if defined(OS_WIN)
- PowerMessageWindow power_message_window_;
-#endif
+ scoped_ptr<PowerMonitorSource> source_;
DISALLOW_COPY_AND_ASSIGN(PowerMonitor);
};
diff --git a/base/power_monitor/power_monitor_device_source.cc b/base/power_monitor/power_monitor_device_source.cc
new file mode 100644
index 0000000..0a39975
--- /dev/null
+++ b/base/power_monitor/power_monitor_device_source.cc
@@ -0,0 +1,39 @@
+// 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 "base/power_monitor/power_monitor_device_source.h"
+
+#include "base/time/time.h"
+
+namespace base {
+
+#if defined(ENABLE_BATTERY_MONITORING)
+// The amount of time (in ms) to wait before running the initial
+// battery check.
+static int kDelayedBatteryCheckMs = 10 * 1000;
+#endif // defined(ENABLE_BATTERY_MONITORING)
+
+PowerMonitorDeviceSource::PowerMonitorDeviceSource() {
+ DCHECK(MessageLoop::current());
+#if defined(ENABLE_BATTERY_MONITORING)
+ delayed_battery_check_.Start(FROM_HERE,
+ base::TimeDelta::FromMilliseconds(kDelayedBatteryCheckMs), this,
+ &PowerMonitorDeviceSource::BatteryCheck);
+#endif // defined(ENABLE_BATTERY_MONITORING)
+#if defined(OS_MACOSX)
+ PlatformInit();
+#endif
+}
+
+PowerMonitorDeviceSource::~PowerMonitorDeviceSource() {
+#if defined(OS_MACOSX)
+ PlatformDestroy();
+#endif
+}
+
+void PowerMonitorDeviceSource::BatteryCheck() {
+ ProcessPowerEvent(PowerMonitorSource::POWER_STATE_EVENT);
+}
+
+} // namespace base
diff --git a/base/power_monitor/power_monitor_device_source.h b/base/power_monitor/power_monitor_device_source.h
new file mode 100644
index 0000000..9939560
--- /dev/null
+++ b/base/power_monitor/power_monitor_device_source.h
@@ -0,0 +1,110 @@
+// 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 BASE_POWER_MONITOR_POWER_MONITOR_DEVICE_SOURCE_H_
+#define BASE_POWER_MONITOR_POWER_MONITOR_DEVICE_SOURCE_H_
+
+#include "base/base_export.h"
+#include "base/basictypes.h"
+#include "base/memory/ref_counted.h"
+#include "base/observer_list_threadsafe.h"
+#include "base/power_monitor/power_monitor_source.h"
+#include "base/power_monitor/power_observer.h"
+
+#if defined(OS_WIN)
+#include <windows.h>
+
+// Windows HiRes timers drain the battery faster so we need to know the battery
+// status. This isn't true for other platforms.
+#define ENABLE_BATTERY_MONITORING 1
+#else
+#undef ENABLE_BATTERY_MONITORING
+#endif // !OS_WIN
+
+#if defined(ENABLE_BATTERY_MONITORING)
+#include "base/timer/timer.h"
+#endif // defined(ENABLE_BATTERY_MONITORING)
+
+#if defined(OS_IOS)
+#include <objc/runtime.h>
+#endif // OS_IOS
+
+namespace base {
+
+// A class used to monitor the power state change and notify the observers about
+// the change event.
+class BASE_EXPORT PowerMonitorDeviceSource : public PowerMonitorSource {
+ public:
+ PowerMonitorDeviceSource();
+ virtual ~PowerMonitorDeviceSource();
+
+#if defined(OS_MACOSX)
+ // Allocate system resources needed by the PowerMonitor class.
+ //
+ // This function must be called before instantiating an instance of the class
+ // and before the Sandbox is initialized.
+#if !defined(OS_IOS)
+ static void AllocateSystemIOPorts();
+#else
+ static void AllocateSystemIOPorts() {}
+#endif // OS_IOS
+#endif // OS_MACOSX
+
+ private:
+#if defined(OS_WIN)
+ // Represents a message-only window for power message handling on Windows.
+ // Only allow PowerMonitor to create it.
+ class PowerMessageWindow {
+ public:
+ PowerMessageWindow();
+ ~PowerMessageWindow();
+
+ private:
+ void ProcessWmPowerBroadcastMessage(int event_id);
+ LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
+ WPARAM wparam, LPARAM lparam);
+ static LRESULT CALLBACK WndProcThunk(HWND hwnd,
+ UINT message,
+ WPARAM wparam,
+ LPARAM lparam);
+ // Instance of the module containing the window procedure.
+ HMODULE instance_;
+ // A hidden message-only window.
+ HWND message_hwnd_;
+ };
+#endif // OS_WIN
+
+#if defined(OS_MACOSX)
+ void PlatformInit();
+ void PlatformDestroy();
+#endif
+
+ // Platform-specific method to check whether the system is currently
+ // running on battery power. Returns true if running on batteries,
+ // false otherwise.
+ virtual bool IsOnBatteryPowerImpl() OVERRIDE;
+
+ // Checks the battery status and notifies observers if the battery
+ // status has changed.
+ void BatteryCheck();
+
+#if defined(OS_IOS)
+ // Holds pointers to system event notification observers.
+ std::vector<id> notification_observers_;
+#endif
+
+#if defined(ENABLE_BATTERY_MONITORING)
+ base::OneShotTimer<PowerMonitorDeviceSource> delayed_battery_check_;
+#endif
+
+#if defined(OS_WIN)
+ PowerMessageWindow power_message_window_;
+#endif
+
+ DISALLOW_COPY_AND_ASSIGN(PowerMonitorDeviceSource);
+};
+
+} // namespace base
+
+#endif // BASE_POWER_MONITOR_POWER_MONITOR_DEVICE_SOURCE_H_
diff --git a/base/power_monitor/power_monitor_android.cc b/base/power_monitor/power_monitor_device_source_android.cc
index 4900f6c..4d9eb52 100644
--- a/base/power_monitor/power_monitor_android.cc
+++ b/base/power_monitor/power_monitor_device_source_android.cc
@@ -2,35 +2,38 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "base/power_monitor/power_monitor_device_source_android.h"
+
#include "base/power_monitor/power_monitor.h"
+#include "base/power_monitor/power_monitor_device_source.h"
+#include "base/power_monitor/power_monitor_source.h"
#include "jni/PowerMonitor_jni.h"
namespace base {
-// A helper function which is a friend of PowerMonitor.
-void ProcessPowerEventHelper(PowerMonitor::PowerEvent event) {
- if (base::PowerMonitor::Get())
- base::PowerMonitor::Get()->ProcessPowerEvent(event);
+// A helper function which is a friend of PowerMonitorSource.
+void ProcessPowerEventHelper(PowerMonitorSource::PowerEvent event) {
+ PowerMonitorSource::ProcessPowerEvent(event);
}
namespace android {
// Native implementation of PowerMonitor.java.
void OnBatteryChargingChanged(JNIEnv* env, jclass clazz) {
- ProcessPowerEventHelper(PowerMonitor::POWER_STATE_EVENT);
+ ProcessPowerEventHelper(PowerMonitorSource::POWER_STATE_EVENT);
}
void OnMainActivityResumed(JNIEnv* env, jclass clazz) {
- ProcessPowerEventHelper(PowerMonitor::RESUME_EVENT);
+ ProcessPowerEventHelper(PowerMonitorSource::RESUME_EVENT);
}
void OnMainActivitySuspended(JNIEnv* env, jclass clazz) {
- ProcessPowerEventHelper(PowerMonitor::SUSPEND_EVENT);
+ ProcessPowerEventHelper(PowerMonitorSource::SUSPEND_EVENT);
}
} // namespace android
-bool PowerMonitor::IsBatteryPower() {
+bool PowerMonitorDeviceSource::IsOnBatteryPowerImpl() {
JNIEnv* env = base::android::AttachCurrentThread();
return base::android::Java_PowerMonitor_isBatteryPower(env);
}
diff --git a/base/power_monitor/power_monitor_android.h b/base/power_monitor/power_monitor_device_source_android.h
index 7f43164..024f95a 100644
--- a/base/power_monitor/power_monitor_android.h
+++ b/base/power_monitor/power_monitor_device_source_android.h
@@ -2,16 +2,16 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef BASE_POWER_MONITOR_POWER_MONITOR_ANDROID_H_
-#define BASE_POWER_MONITOR_POWER_MONITOR_ANDROID_H_
+#ifndef BASE_POWER_MONITOR_POWER_MONITOR_DEVICE_SOURCE_ANDROID_H_
+#define BASE_POWER_MONITOR_POWER_MONITOR_DEVICE_SOURCE_ANDROID_H_
#include <jni.h>
namespace base {
-// Registers the JNI bindings for PowerMonitor.
+// Registers the JNI bindings for PowerMonitorDeviceSource.
bool RegisterPowerMonitor(JNIEnv* env);
} // namespace base
-#endif // BASE_POWER_MONITOR_POWER_MONITOR_ANDROID_H_
+#endif // BASE_POWER_MONITOR_POWER_MONITOR_DEVICE_SOURCE_ANDROID_H_
diff --git a/base/power_monitor/power_monitor_ios.mm b/base/power_monitor/power_monitor_device_source_ios.mm
index f7c0b92..dc12f1c 100644
--- a/base/power_monitor/power_monitor_ios.mm
+++ b/base/power_monitor/power_monitor_device_source_ios.mm
@@ -2,13 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/power_monitor/power_monitor.h"
+#include "base/power_monitor/power_monitor_device_source.h"
#import <UIKit/UIKit.h>
namespace base {
-void PowerMonitor::PlatformInit() {
+void PowerMonitorDeviceSource::PlatformInit() {
NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
id foreground =
[nc addObserverForName:UIApplicationWillEnterForegroundNotification
@@ -28,7 +28,7 @@ void PowerMonitor::PlatformInit() {
notification_observers_.push_back(background);
}
-void PowerMonitor::PlatformDestroy() {
+void PowerMonitorDeviceSource::PlatformDestroy() {
NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
for (std::vector<id>::iterator it = notification_observers_.begin();
it != notification_observers_.end(); ++it) {
diff --git a/base/power_monitor/power_monitor_mac.mm b/base/power_monitor/power_monitor_device_source_mac.mm
index ee906f6..61e4396 100644
--- a/base/power_monitor/power_monitor_mac.mm
+++ b/base/power_monitor/power_monitor_device_source_mac.mm
@@ -5,17 +5,18 @@
// Implementation based on sample code from
// http://developer.apple.com/library/mac/#qa/qa1340/_index.html.
+#include "base/power_monitor/power_monitor_device_source.h"
+
#include "base/power_monitor/power_monitor.h"
+#include "base/power_monitor/power_monitor_source.h"
#include <IOKit/pwr_mgt/IOPMLib.h>
#include <IOKit/IOMessage.h>
namespace base {
-void ProcessPowerEventHelper(PowerMonitor::PowerEvent event) {
- DCHECK(PowerMonitor::Get());
- if (PowerMonitor::Get())
- PowerMonitor::Get()->ProcessPowerEvent(event);
+void ProcessPowerEventHelper(PowerMonitorSource::PowerEvent event) {
+ PowerMonitorSource::ProcessPowerEvent(event);
}
namespace {
@@ -29,14 +30,19 @@ void SystemPowerEventCallback(void*,
natural_t message_type,
void* message_argument) {
switch (message_type) {
+ // If this message is not handled the system may delay sleep for 30 seconds.
+ case kIOMessageCanSystemSleep:
+ IOAllowPowerChange(g_system_power_io_port,
+ reinterpret_cast<intptr_t>(message_argument));
+ break;
case kIOMessageSystemWillSleep:
- ProcessPowerEventHelper(base::PowerMonitor::SUSPEND_EVENT);
+ ProcessPowerEventHelper(base::PowerMonitorSource::SUSPEND_EVENT);
IOAllowPowerChange(g_system_power_io_port,
reinterpret_cast<intptr_t>(message_argument));
break;
case kIOMessageSystemWillPowerOn:
- ProcessPowerEventHelper(PowerMonitor::RESUME_EVENT);
+ ProcessPowerEventHelper(PowerMonitorSource::RESUME_EVENT);
break;
}
}
@@ -49,7 +55,7 @@ void SystemPowerEventCallback(void*,
// See crbug.com/83783 .
// static
-void PowerMonitor::AllocateSystemIOPorts() {
+void PowerMonitorDeviceSource::AllocateSystemIOPorts() {
DCHECK_EQ(g_system_power_io_port, 0u);
// Notification port allocated by IORegisterForSystemPower.
@@ -60,7 +66,7 @@ void PowerMonitor::AllocateSystemIOPorts() {
DCHECK_NE(g_system_power_io_port, 0u);
}
-void PowerMonitor::PlatformInit() {
+void PowerMonitorDeviceSource::PlatformInit() {
// Need to call AllocateSystemIOPorts() before creating a PowerMonitor
// object.
DCHECK_NE(g_system_power_io_port, 0u);
@@ -74,7 +80,7 @@ void PowerMonitor::PlatformInit() {
kCFRunLoopCommonModes);
}
-void PowerMonitor::PlatformDestroy() {
+void PowerMonitorDeviceSource::PlatformDestroy() {
DCHECK_NE(g_system_power_io_port, 0u);
if (g_system_power_io_port == 0)
return;
diff --git a/base/power_monitor/power_monitor_posix.cc b/base/power_monitor/power_monitor_device_source_posix.cc
index affebea..f24e5b2 100644
--- a/base/power_monitor/power_monitor_posix.cc
+++ b/base/power_monitor/power_monitor_device_source_posix.cc
@@ -2,11 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/power_monitor/power_monitor.h"
+#include "base/power_monitor/power_monitor_device_source.h"
namespace base {
-bool PowerMonitor::IsBatteryPower() {
+bool PowerMonitorDeviceSource::IsOnBatteryPowerImpl() {
NOTIMPLEMENTED();
return false;
}
diff --git a/base/power_monitor/power_monitor_win.cc b/base/power_monitor/power_monitor_device_source_win.cc
index 156ee2b..6f4c131 100644
--- a/base/power_monitor/power_monitor_win.cc
+++ b/base/power_monitor/power_monitor_device_source_win.cc
@@ -3,11 +3,16 @@
// found in the LICENSE file.
#include "base/power_monitor/power_monitor.h"
-
+#include "base/power_monitor/power_monitor_device_source.h"
+#include "base/power_monitor/power_monitor_source.h"
#include "base/win/wrapped_window_proc.h"
namespace base {
+void ProcessPowerEventHelper(PowerMonitorSource::PowerEvent event) {
+ PowerMonitorSource::ProcessPowerEvent(event);
+}
+
namespace {
const wchar_t kWindowClassName[] = L"Base_PowerMessageWindow";
@@ -16,7 +21,7 @@ const wchar_t kWindowClassName[] = L"Base_PowerMessageWindow";
// Function to query the system to see if it is currently running on
// battery power. Returns true if running on battery.
-bool PowerMonitor::IsBatteryPower() {
+bool PowerMonitorDeviceSource::IsOnBatteryPowerImpl() {
SYSTEM_POWER_STATUS status;
if (!GetSystemPowerStatus(&status)) {
DLOG_GETLASTERROR(ERROR) << "GetSystemPowerStatus failed";
@@ -25,7 +30,7 @@ bool PowerMonitor::IsBatteryPower() {
return (status.ACLineStatus == 0);
}
-PowerMonitor::PowerMessageWindow::PowerMessageWindow()
+PowerMonitorDeviceSource::PowerMessageWindow::PowerMessageWindow()
: instance_(NULL), message_hwnd_(NULL) {
if (MessageLoop::current()->type() != MessageLoop::TYPE_UI) {
// Creating this window in (e.g.) a renderer inhibits shutdown on Windows.
@@ -38,7 +43,7 @@ PowerMonitor::PowerMessageWindow::PowerMessageWindow()
base::win::InitializeWindowClass(
kWindowClassName,
&base::win::WrappedWindowProc<
- PowerMonitor::PowerMessageWindow::WndProcThunk>,
+ PowerMonitorDeviceSource::PowerMessageWindow::WndProcThunk>,
0, 0, 0, NULL, NULL, NULL, NULL, NULL,
&window_class);
instance_ = window_class.hInstance;
@@ -51,29 +56,30 @@ PowerMonitor::PowerMessageWindow::PowerMessageWindow()
reinterpret_cast<LONG_PTR>(this));
}
-PowerMonitor::PowerMessageWindow::~PowerMessageWindow() {
+PowerMonitorDeviceSource::PowerMessageWindow::~PowerMessageWindow() {
if (message_hwnd_) {
DestroyWindow(message_hwnd_);
UnregisterClass(kWindowClassName, instance_);
}
}
-void PowerMonitor::PowerMessageWindow::ProcessWmPowerBroadcastMessage(
+void
+PowerMonitorDeviceSource::PowerMessageWindow::ProcessWmPowerBroadcastMessage(
int event_id) {
- PowerMonitor::PowerEvent power_event;
+ PowerMonitorSource::PowerEvent power_event;
switch (event_id) {
case PBT_APMPOWERSTATUSCHANGE: // The power status changed.
- power_event = PowerMonitor::POWER_STATE_EVENT;
+ power_event = PowerMonitorSource::POWER_STATE_EVENT;
break;
case PBT_APMRESUMEAUTOMATIC: // Resume from suspend.
//case PBT_APMRESUMESUSPEND: // User-initiated resume from suspend.
// We don't notify for this latter event
// because if it occurs it is always sent as a
// second event after PBT_APMRESUMEAUTOMATIC.
- power_event = PowerMonitor::RESUME_EVENT;
+ power_event = PowerMonitorSource::RESUME_EVENT;
break;
case PBT_APMSUSPEND: // System has been suspended.
- power_event = PowerMonitor::SUSPEND_EVENT;
+ power_event = PowerMonitorSource::SUSPEND_EVENT;
break;
default:
return;
@@ -87,11 +93,14 @@ void PowerMonitor::PowerMessageWindow::ProcessWmPowerBroadcastMessage(
// PBT_POWERSETTINGCHANGE - user changed the power settings.
}
- PowerMonitor::Get()->ProcessPowerEvent(power_event);
+ ProcessPowerEventHelper(power_event);
}
-LRESULT CALLBACK PowerMonitor::PowerMessageWindow::WndProc(
- HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) {
+LRESULT CALLBACK PowerMonitorDeviceSource::PowerMessageWindow::WndProc(
+ HWND hwnd,
+ UINT message,
+ WPARAM wparam,
+ LPARAM lparam) {
switch (message) {
case WM_POWERBROADCAST: {
DWORD power_event = static_cast<DWORD>(message);
@@ -105,10 +114,13 @@ LRESULT CALLBACK PowerMonitor::PowerMessageWindow::WndProc(
}
// static
-LRESULT CALLBACK PowerMonitor::PowerMessageWindow::WndProcThunk(
- HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) {
- PowerMonitor::PowerMessageWindow* message_hwnd =
- reinterpret_cast<PowerMonitor::PowerMessageWindow*>(
+LRESULT CALLBACK PowerMonitorDeviceSource::PowerMessageWindow::WndProcThunk(
+ HWND hwnd,
+ UINT message,
+ WPARAM wparam,
+ LPARAM lparam) {
+ PowerMonitorDeviceSource::PowerMessageWindow* message_hwnd =
+ reinterpret_cast<PowerMonitorDeviceSource::PowerMessageWindow*>(
GetWindowLongPtr(hwnd, GWLP_USERDATA));
if (message_hwnd)
return message_hwnd->WndProc(hwnd, message, wparam, lparam);
diff --git a/base/power_monitor/power_monitor_source.cc b/base/power_monitor/power_monitor_source.cc
new file mode 100644
index 0000000..6868cb1
--- /dev/null
+++ b/base/power_monitor/power_monitor_source.cc
@@ -0,0 +1,66 @@
+// 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 "base/power_monitor/power_monitor_source.h"
+
+#include "base/power_monitor/power_monitor.h"
+
+namespace base {
+
+PowerMonitorSource::PowerMonitorSource()
+ : on_battery_power_(false),
+ suspended_(false) {
+}
+
+PowerMonitorSource::~PowerMonitorSource() {
+}
+
+bool PowerMonitorSource::IsOnBatteryPower() {
+ AutoLock auto_lock(battery_lock_);
+ return on_battery_power_;
+}
+
+void PowerMonitorSource::ProcessPowerEvent(PowerEvent event_id) {
+ PowerMonitor* monitor = PowerMonitor::Get();
+ if (!monitor)
+ return;
+
+ PowerMonitorSource* source = monitor->Source();
+
+ // Suppress duplicate notifications. Some platforms may
+ // send multiple notifications of the same event.
+ switch (event_id) {
+ case POWER_STATE_EVENT:
+ {
+ bool new_on_battery_power = source->IsOnBatteryPowerImpl();
+ bool changed = false;
+
+ {
+ AutoLock auto_lock(source->battery_lock_);
+ if (source->on_battery_power_ != new_on_battery_power) {
+ changed = true;
+ source->on_battery_power_ = new_on_battery_power;
+ }
+ }
+
+ if (changed)
+ monitor->NotifyPowerStateChange(new_on_battery_power);
+ }
+ break;
+ case RESUME_EVENT:
+ if (source->suspended_) {
+ source->suspended_ = false;
+ monitor->NotifyResume();
+ }
+ break;
+ case SUSPEND_EVENT:
+ if (!source->suspended_) {
+ source->suspended_ = true;
+ monitor->NotifySuspend();
+ }
+ break;
+ }
+}
+
+} // namespace base
diff --git a/base/power_monitor/power_monitor_source.h b/base/power_monitor/power_monitor_source.h
new file mode 100644
index 0000000..b8f4185
--- /dev/null
+++ b/base/power_monitor/power_monitor_source.h
@@ -0,0 +1,65 @@
+// 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 BASE_POWER_MONITOR_POWER_MONITOR_SOURCE_H_
+#define BASE_POWER_MONITOR_POWER_MONITOR_SOURCE_H_
+
+#include "base/base_export.h"
+#include "base/basictypes.h"
+#include "base/memory/ref_counted.h"
+#include "base/observer_list_threadsafe.h"
+#include "base/synchronization/lock.h"
+
+namespace base {
+
+class PowerMonitor;
+
+// Communicates power state changes to the power monitor.
+class BASE_EXPORT PowerMonitorSource {
+ public:
+ PowerMonitorSource();
+ virtual ~PowerMonitorSource();
+
+ // Normalized list of power events.
+ enum PowerEvent {
+ POWER_STATE_EVENT, // The Power status of the system has changed.
+ SUSPEND_EVENT, // The system is being suspended.
+ RESUME_EVENT // The system is being resumed.
+ };
+
+ // Is the computer currently on battery power. Can be called on any thread.
+ bool IsOnBatteryPower();
+
+ protected:
+ friend class PowerMonitorTest;
+
+ // Friend function that is allowed to access the protected ProcessPowerEvent.
+ friend void ProcessPowerEventHelper(PowerEvent);
+
+ // Get the process-wide PowerMonitorSource (if not present, returns NULL).
+ static PowerMonitorSource* Get();
+
+ // ProcessPowerEvent should only be called from a single thread, most likely
+ // the UI thread or, in child processes, the IO thread.
+ static void ProcessPowerEvent(PowerEvent event_id);
+
+ // Platform-specific method to check whether the system is currently
+ // running on battery power. Returns true if running on batteries,
+ // false otherwise.
+ virtual bool IsOnBatteryPowerImpl() = 0;
+
+ private:
+ bool on_battery_power_;
+ bool suspended_;
+
+ // This lock guards access to on_battery_power_, to ensure that
+ // IsOnBatteryPower can be called from any thread.
+ Lock battery_lock_;
+
+ DISALLOW_COPY_AND_ASSIGN(PowerMonitorSource);
+};
+
+} // namespace base
+
+#endif // BASE_POWER_MONITOR_POWER_MONITOR_SOURCE_H_
diff --git a/base/power_monitor/power_monitor_test_base.cc b/base/power_monitor/power_monitor_test_base.cc
new file mode 100644
index 0000000..990b8d1
--- /dev/null
+++ b/base/power_monitor/power_monitor_test_base.cc
@@ -0,0 +1,64 @@
+// 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 "base/power_monitor/power_monitor_test_base.h"
+
+#include "base/message_loop/message_loop.h"
+#include "base/power_monitor/power_monitor.h"
+#include "base/power_monitor/power_monitor_source.h"
+
+namespace base {
+
+PowerMonitorTestSource::PowerMonitorTestSource()
+ : test_on_battery_power_(false) {
+}
+
+PowerMonitorTestSource::~PowerMonitorTestSource() {
+}
+
+void PowerMonitorTestSource::GeneratePowerStateEvent(bool on_battery_power) {
+ test_on_battery_power_ = on_battery_power;
+ ProcessPowerEvent(POWER_STATE_EVENT);
+ message_loop_.RunUntilIdle();
+}
+
+void PowerMonitorTestSource::GenerateSuspendEvent() {
+ ProcessPowerEvent(SUSPEND_EVENT);
+ message_loop_.RunUntilIdle();
+}
+
+void PowerMonitorTestSource::GenerateResumeEvent() {
+ ProcessPowerEvent(RESUME_EVENT);
+ message_loop_.RunUntilIdle();
+}
+
+bool PowerMonitorTestSource::IsOnBatteryPowerImpl() {
+ return test_on_battery_power_;
+};
+
+PowerMonitorTestObserver::PowerMonitorTestObserver()
+ : last_power_state_(false),
+ power_state_changes_(0),
+ suspends_(0),
+ resumes_(0) {
+}
+
+PowerMonitorTestObserver::~PowerMonitorTestObserver() {
+}
+
+// PowerObserver callbacks.
+void PowerMonitorTestObserver::OnPowerStateChange(bool on_battery_power) {
+ last_power_state_ = on_battery_power;
+ power_state_changes_++;
+}
+
+void PowerMonitorTestObserver::OnSuspend() {
+ suspends_++;
+}
+
+void PowerMonitorTestObserver::OnResume() {
+ resumes_++;
+}
+
+} // namespace base
diff --git a/base/power_monitor/power_monitor_test_base.h b/base/power_monitor/power_monitor_test_base.h
new file mode 100644
index 0000000..6f82fc0
--- /dev/null
+++ b/base/power_monitor/power_monitor_test_base.h
@@ -0,0 +1,50 @@
+// 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 "base/message_loop/message_loop.h"
+#include "base/power_monitor/power_monitor.h"
+#include "base/power_monitor/power_monitor_source.h"
+
+namespace base {
+
+class BASE_EXPORT PowerMonitorTestSource : public PowerMonitorSource {
+ public:
+ PowerMonitorTestSource();
+ virtual ~PowerMonitorTestSource();
+
+ void GeneratePowerStateEvent(bool on_battery_power);
+ void GenerateSuspendEvent();
+ void GenerateResumeEvent();
+
+ protected:
+ virtual bool IsOnBatteryPowerImpl() OVERRIDE;
+
+ bool test_on_battery_power_;
+ MessageLoop message_loop_;
+};
+
+class BASE_EXPORT PowerMonitorTestObserver : public PowerObserver {
+ public:
+ PowerMonitorTestObserver();
+ virtual ~PowerMonitorTestObserver();
+
+ // PowerObserver callbacks.
+ virtual void OnPowerStateChange(bool on_battery_power) OVERRIDE;
+ virtual void OnSuspend() OVERRIDE;
+ virtual void OnResume() OVERRIDE;
+
+ // Test status counts.
+ bool last_power_state() { return last_power_state_; }
+ int power_state_changes() { return power_state_changes_; }
+ int suspends() { return suspends_; }
+ int resumes() { return resumes_; }
+
+ private:
+ bool last_power_state_; // Last power state we were notified of.
+ int power_state_changes_; // Count of OnPowerStateChange notifications.
+ int suspends_; // Count of OnSuspend notifications.
+ int resumes_; // Count of OnResume notifications.
+};
+
+} // namespace base \ No newline at end of file
diff --git a/base/power_monitor/power_monitor_unittest.cc b/base/power_monitor/power_monitor_unittest.cc
index 90f36f0..61b720e 100644
--- a/base/power_monitor/power_monitor_unittest.cc
+++ b/base/power_monitor/power_monitor_unittest.cc
@@ -3,104 +3,78 @@
// found in the LICENSE file.
#include "base/power_monitor/power_monitor.h"
-
-#include "base/message_loop/message_loop.h"
+#include "base/power_monitor/power_monitor_test_base.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace base {
-class PowerTest : public PowerObserver {
- public:
- PowerTest()
- : power_state_changes_(0),
- suspends_(0),
- resumes_(0) {
- }
-
- // PowerObserver callbacks.
- virtual void OnPowerStateChange(bool on_battery_power) OVERRIDE {
- power_state_changes_++;
- }
-
- virtual void OnSuspend() OVERRIDE {
- suspends_++;
- }
-
- virtual void OnResume() OVERRIDE {
- resumes_++;
- }
-
- // Test status counts.
- int power_state_changes() { return power_state_changes_; }
- int suspends() { return suspends_; }
- int resumes() { return resumes_; }
-
- private:
- int power_state_changes_; // Count of OnPowerStateChange notifications.
- int suspends_; // Count of OnSuspend notifications.
- int resumes_; // Count of OnResume notifications.
-};
-
class PowerMonitorTest : public testing::Test {
protected:
PowerMonitorTest() {
-#if defined(OS_MACOSX)
- // This needs to happen before PowerMonitor's ctor.
- PowerMonitor::AllocateSystemIOPorts();
-#endif
- power_monitor_.reset(new PowerMonitor);
- }
-
- void ProcessPowerEvent(PowerMonitor::PowerEvent event_id) {
- power_monitor_->ProcessPowerEvent(event_id);
+ power_monitor_source_ = new PowerMonitorTestSource();
+ power_monitor_.reset(new PowerMonitor(
+ scoped_ptr<PowerMonitorSource>(power_monitor_source_)));
}
+ virtual ~PowerMonitorTest() {};
- virtual ~PowerMonitorTest() {}
+ PowerMonitorTestSource* source() { return power_monitor_source_; }
+ PowerMonitor* monitor() { return power_monitor_.get(); }
- MessageLoop message_loop_;
+ private:
+ PowerMonitorTestSource* power_monitor_source_;
scoped_ptr<PowerMonitor> power_monitor_;
DISALLOW_COPY_AND_ASSIGN(PowerMonitorTest);
};
+// PowerMonitorSource is tightly coupled with the PowerMonitor, so this test
+// Will cover both classes
TEST_F(PowerMonitorTest, PowerNotifications) {
const int kObservers = 5;
- PowerTest test[kObservers];
+ PowerMonitorTestObserver observers[kObservers];
for (int index = 0; index < kObservers; ++index)
- power_monitor_->AddObserver(&test[index]);
-
- // Send a bunch of power changes. Since the battery power hasn't
- // actually changed, we shouldn't get notifications.
- for (int index = 0; index < 5; index++) {
- ProcessPowerEvent(PowerMonitor::POWER_STATE_EVENT);
- EXPECT_EQ(test[0].power_state_changes(), 0);
- }
+ monitor()->AddObserver(&observers[index]);
// Sending resume when not suspended should have no effect.
- ProcessPowerEvent(PowerMonitor::RESUME_EVENT);
- message_loop_.RunUntilIdle();
- EXPECT_EQ(test[0].resumes(), 0);
+ source()->GenerateResumeEvent();
+ EXPECT_EQ(observers[0].resumes(), 0);
// Pretend we suspended.
- ProcessPowerEvent(PowerMonitor::SUSPEND_EVENT);
- message_loop_.RunUntilIdle();
- EXPECT_EQ(test[0].suspends(), 1);
+ source()->GenerateSuspendEvent();
+ // Ensure all observers were notified of the event
+ for (int index = 0; index < kObservers; ++index)
+ EXPECT_EQ(observers[index].suspends(), 1);
// Send a second suspend notification. This should be suppressed.
- ProcessPowerEvent(PowerMonitor::SUSPEND_EVENT);
- message_loop_.RunUntilIdle();
- EXPECT_EQ(test[0].suspends(), 1);
+ source()->GenerateSuspendEvent();
+ EXPECT_EQ(observers[0].suspends(), 1);
// Pretend we were awakened.
- ProcessPowerEvent(PowerMonitor::RESUME_EVENT);
- message_loop_.RunUntilIdle();
- EXPECT_EQ(test[0].resumes(), 1);
+ source()->GenerateResumeEvent();
+ EXPECT_EQ(observers[0].resumes(), 1);
// Send a duplicate resume notification. This should be suppressed.
- ProcessPowerEvent(PowerMonitor::RESUME_EVENT);
- message_loop_.RunUntilIdle();
- EXPECT_EQ(test[0].resumes(), 1);
+ source()->GenerateResumeEvent();
+ EXPECT_EQ(observers[0].resumes(), 1);
+
+ // Pretend the device has gone on battery power
+ source()->GeneratePowerStateEvent(true);
+ EXPECT_EQ(observers[0].power_state_changes(), 1);
+ EXPECT_EQ(observers[0].last_power_state(), true);
+
+ // Repeated indications the device is on battery power should be suppressed.
+ source()->GeneratePowerStateEvent(true);
+ EXPECT_EQ(observers[0].power_state_changes(), 1);
+
+ // Pretend the device has gone off battery power
+ source()->GeneratePowerStateEvent(false);
+ EXPECT_EQ(observers[0].power_state_changes(), 2);
+ EXPECT_EQ(observers[0].last_power_state(), false);
+
+ // Repeated indications the device is off battery power should be suppressed.
+ source()->GeneratePowerStateEvent(false);
+ EXPECT_EQ(observers[0].power_state_changes(), 2);
}
} // namespace base
diff --git a/base/timer/hi_res_timer_manager_unittest.cc b/base/timer/hi_res_timer_manager_unittest.cc
index 7ae6ab1..ce10e37 100644
--- a/base/timer/hi_res_timer_manager_unittest.cc
+++ b/base/timer/hi_res_timer_manager_unittest.cc
@@ -7,6 +7,7 @@
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/power_monitor/power_monitor.h"
+#include "base/power_monitor/power_monitor_device_source.h"
#include "base/time/time.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -16,7 +17,10 @@ namespace base {
// http://crbug.com/114048
TEST(HiResTimerManagerTest, DISABLED_ToggleOnOff) {
base::MessageLoop loop;
- scoped_ptr<base::PowerMonitor> power_monitor(new base::PowerMonitor());
+ scoped_ptr<base::PowerMonitorSource> power_monitor_source(
+ new base::PowerMonitorDeviceSource());
+ scoped_ptr<base::PowerMonitor> power_monitor(
+ new base::PowerMonitor(power_monitor_source.Pass()));
HighResolutionTimerManager manager;
// At this point, we don't know if the high resolution timers are on or off,
diff --git a/base/timer/hi_res_timer_manager_win.cc b/base/timer/hi_res_timer_manager_win.cc
index 3647714..692f72b 100644
--- a/base/timer/hi_res_timer_manager_win.cc
+++ b/base/timer/hi_res_timer_manager_win.cc
@@ -12,8 +12,9 @@ namespace base {
HighResolutionTimerManager::HighResolutionTimerManager()
: hi_res_clock_available_(false) {
base::PowerMonitor* power_monitor = base::PowerMonitor::Get();
+ DCHECK(power_monitor != NULL);
power_monitor->AddObserver(this);
- UseHiResClock(!power_monitor->BatteryPower());
+ UseHiResClock(!power_monitor->IsOnBatteryPower());
}
HighResolutionTimerManager::~HighResolutionTimerManager() {
diff --git a/chrome/browser/extensions/event_router_forwarder_unittest.cc b/chrome/browser/extensions/event_router_forwarder_unittest.cc
index c77ecbf..0e6619a 100644
--- a/chrome/browser/extensions/event_router_forwarder_unittest.cc
+++ b/chrome/browser/extensions/event_router_forwarder_unittest.cc
@@ -7,6 +7,7 @@
#include "base/bind.h"
#include "base/message_loop/message_loop.h"
#include "base/power_monitor/power_monitor.h"
+#include "base/power_monitor/power_monitor_device_source.h"
#include "base/test/thread_test_helper.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/test/base/testing_browser_process.h"
@@ -92,9 +93,11 @@ class EventRouterForwarderTest : public testing::Test {
profile_manager_(
TestingBrowserProcess::GetGlobal()) {
#if defined(OS_MACOSX)
- base::PowerMonitor::AllocateSystemIOPorts();
+ base::PowerMonitorDeviceSource::AllocateSystemIOPorts();
#endif
- dummy.reset(new base::PowerMonitor);
+ scoped_ptr<base::PowerMonitorSource> power_monitor_source(
+ new base::PowerMonitorDeviceSource());
+ dummy.reset(new base::PowerMonitor(power_monitor_source.Pass()));
}
virtual void SetUp() {
diff --git a/chrome/nacl/nacl_exe_win_64.cc b/chrome/nacl/nacl_exe_win_64.cc
index 76385df..4e480d5 100644
--- a/chrome/nacl/nacl_exe_win_64.cc
+++ b/chrome/nacl/nacl_exe_win_64.cc
@@ -8,6 +8,7 @@
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
#include "base/power_monitor/power_monitor.h"
+#include "base/power_monitor/power_monitor_device_source.h"
#include "base/process/launch.h"
#include "base/process/memory.h"
#include "base/strings/string_util.h"
@@ -44,7 +45,9 @@ int NaClBrokerMain(const content::MainFunctionParams& parameters) {
base::MessageLoopForIO main_message_loop;
base::PlatformThread::SetName("CrNaClBrokerMain");
- base::PowerMonitor power_monitor;
+ scoped_ptr<base::PowerMonitorSource> power_monitor_source(
+ new base::PowerMonitorDeviceSource());
+ base::PowerMonitor power_monitor(power_monitor_source.Pass());
base::HighResolutionTimerManager hi_res_timer_manager;
NaClBrokerListener listener;
diff --git a/components/nacl/loader/nacl_main.cc b/components/nacl/loader/nacl_main.cc
index 9a3586f..a9ec5c9 100644
--- a/components/nacl/loader/nacl_main.cc
+++ b/components/nacl/loader/nacl_main.cc
@@ -7,6 +7,7 @@
#include "base/command_line.h"
#include "base/message_loop/message_loop.h"
#include "base/power_monitor/power_monitor.h"
+#include "base/power_monitor/power_monitor_device_source.h"
#include "base/timer/hi_res_timer_manager.h"
#include "components/nacl/loader/nacl_listener.h"
#include "components/nacl/loader/nacl_main_platform_delegate.h"
@@ -21,7 +22,9 @@ int NaClMain(const content::MainFunctionParams& parameters) {
base::MessageLoopForIO main_message_loop;
base::PlatformThread::SetName("CrNaClMain");
- base::PowerMonitor power_monitor;
+ scoped_ptr<base::PowerMonitorSource> power_monitor_source(
+ new base::PowerMonitorDeviceSource());
+ base::PowerMonitor power_monitor(power_monitor_source.Pass());
base::HighResolutionTimerManager hi_res_timer_manager;
#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX)
diff --git a/content/app/content_main_runner.cc b/content/app/content_main_runner.cc
index a91d6d3..dfab14f 100644
--- a/content/app/content_main_runner.cc
+++ b/content/app/content_main_runner.cc
@@ -68,7 +68,7 @@
#elif defined(OS_MACOSX)
#include "base/mac/scoped_nsautorelease_pool.h"
#if !defined(OS_IOS)
-#include "base/power_monitor/power_monitor.h"
+#include "base/power_monitor/power_monitor_device_source.h"
#include "content/browser/mach_broker_mac.h"
#include "content/common/sandbox_init_mac.h"
#endif // !OS_IOS
@@ -665,7 +665,7 @@ class ContentMainRunnerImpl : public ContentMainRunner {
process_type == switches::kWorkerProcess ||
(delegate &&
delegate->ProcessRegistersWithSystemProcess(process_type))) {
- base::PowerMonitor::AllocateSystemIOPorts();
+ base::PowerMonitorDeviceSource::AllocateSystemIOPorts();
}
if (!process_type.empty() &&
diff --git a/content/browser/browser_child_process_host_impl.cc b/content/browser/browser_child_process_host_impl.cc
index 6155776..780dc6a 100644
--- a/content/browser/browser_child_process_host_impl.cc
+++ b/content/browser/browser_child_process_host_impl.cc
@@ -95,7 +95,8 @@ BrowserChildProcessHostImpl::BrowserChildProcessHostImpl(
int process_type,
BrowserChildProcessHostDelegate* delegate)
: data_(process_type),
- delegate_(delegate) {
+ delegate_(delegate),
+ power_monitor_message_broadcaster_(this) {
data_.id = ChildProcessHostImpl::GenerateChildProcessUniqueId();
child_process_host_.reset(ChildProcessHost::Create(this));
diff --git a/content/browser/browser_child_process_host_impl.h b/content/browser/browser_child_process_host_impl.h
index e25b514..61971d6 100644
--- a/content/browser/browser_child_process_host_impl.h
+++ b/content/browser/browser_child_process_host_impl.h
@@ -12,6 +12,7 @@
#include "base/process/process.h"
#include "base/synchronization/waitable_event_watcher.h"
#include "content/browser/child_process_launcher.h"
+#include "content/browser/power_monitor_message_broadcaster.h"
#include "content/public/browser/browser_child_process_host.h"
#include "content/public/browser/child_process_data.h"
#include "content/public/common/child_process_host_delegate.h"
@@ -104,6 +105,8 @@ class CONTENT_EXPORT BrowserChildProcessHostImpl
scoped_ptr<ChildProcessLauncher> child_process_;
+ PowerMonitorMessageBroadcaster power_monitor_message_broadcaster_;
+
#if defined(OS_WIN)
// Watches to see if the child process exits before the IPC channel has
// been connected. Thereafter, its exit is determined by an error on the
diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc
index 9e02cc4..1c6b1a0 100644
--- a/content/browser/browser_main_loop.cc
+++ b/content/browser/browser_main_loop.cc
@@ -13,6 +13,7 @@
#include "base/metrics/histogram.h"
#include "base/pending_task.h"
#include "base/power_monitor/power_monitor.h"
+#include "base/power_monitor/power_monitor_device_source.h"
#include "base/process/process_metrics.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
@@ -397,7 +398,9 @@ void BrowserMainLoop::MainMessageLoopStart() {
}
{
TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:PowerMonitor")
- power_monitor_.reset(new base::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")
diff --git a/content/browser/power_monitor_message_broadcaster.cc b/content/browser/power_monitor_message_broadcaster.cc
new file mode 100644
index 0000000..77abcb9
--- /dev/null
+++ b/content/browser/power_monitor_message_broadcaster.cc
@@ -0,0 +1,39 @@
+// 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 "content/browser/power_monitor_message_broadcaster.h"
+
+#include "base/power_monitor/power_monitor.h"
+#include "content/common/power_monitor_messages.h"
+#include "ipc/ipc_sender.h"
+
+namespace content {
+
+PowerMonitorMessageBroadcaster::PowerMonitorMessageBroadcaster(
+ IPC::Sender* sender)
+ : sender_(sender) {
+ base::PowerMonitor* power_monitor = base::PowerMonitor::Get();
+ if (power_monitor)
+ power_monitor->AddObserver(this);
+}
+
+PowerMonitorMessageBroadcaster::~PowerMonitorMessageBroadcaster() {
+ base::PowerMonitor* power_monitor = base::PowerMonitor::Get();
+ if (power_monitor)
+ power_monitor->RemoveObserver(this);
+}
+
+void PowerMonitorMessageBroadcaster::OnPowerStateChange(bool on_battery_power) {
+ sender_->Send(new PowerMonitorMsg_PowerStateChange(on_battery_power));
+}
+
+void PowerMonitorMessageBroadcaster::OnSuspend() {
+ sender_->Send(new PowerMonitorMsg_Suspend());
+}
+
+void PowerMonitorMessageBroadcaster::OnResume() {
+ sender_->Send(new PowerMonitorMsg_Resume());
+}
+
+} // namespace content \ No newline at end of file
diff --git a/content/browser/power_monitor_message_broadcaster.h b/content/browser/power_monitor_message_broadcaster.h
new file mode 100644
index 0000000..f0e3a20
--- /dev/null
+++ b/content/browser/power_monitor_message_broadcaster.h
@@ -0,0 +1,41 @@
+// 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 CONTENT_BROWSER_POWER_MONITOR_MESSAGE_BROADCASTER_H_
+#define CONTENT_BROWSER_POWER_MONITOR_MESSAGE_BROADCASTER_H_
+
+#include "base/basictypes.h"
+#include "base/memory/ref_counted.h"
+#include "base/power_monitor/power_observer.h"
+#include "content/common/content_export.h"
+#include "content/public/browser/browser_thread.h"
+
+namespace IPC {
+ class Sender;
+}
+
+namespace content {
+
+// A class used to monitor the power state change and communicate it to child
+// processes via IPC.
+class CONTENT_EXPORT PowerMonitorMessageBroadcaster
+ : public base::PowerObserver {
+ public:
+ explicit PowerMonitorMessageBroadcaster(IPC::Sender* sender);
+ virtual ~PowerMonitorMessageBroadcaster();
+
+ // Implement PowerObserver.
+ virtual void OnPowerStateChange(bool on_battery_power) OVERRIDE;
+ virtual void OnSuspend() OVERRIDE;
+ virtual void OnResume() OVERRIDE;
+
+ private:
+ IPC::Sender* sender_;
+
+ DISALLOW_COPY_AND_ASSIGN(PowerMonitorMessageBroadcaster);
+};
+
+} // namespace base
+
+#endif // CONTENT_BROWSER_POWER_MONITOR_MESSAGE_BROADCASTER_H_ \ No newline at end of file
diff --git a/content/browser/power_monitor_message_broadcaster_unittest.cc b/content/browser/power_monitor_message_broadcaster_unittest.cc
new file mode 100644
index 0000000..6eb0cb4
--- /dev/null
+++ b/content/browser/power_monitor_message_broadcaster_unittest.cc
@@ -0,0 +1,109 @@
+// 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 "base/power_monitor/power_monitor_test_base.h"
+#include "content/browser/power_monitor_message_broadcaster.h"
+#include "content/common/power_monitor_messages.h"
+#include "ipc/ipc_sender.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+
+class PowerMonitorMessageSender : public IPC::Sender {
+ public:
+ PowerMonitorMessageSender()
+ : power_state_changes_(0),
+ suspends_(0),
+ resumes_(0) {
+ }
+ virtual ~PowerMonitorMessageSender() {}
+
+ virtual bool Send(IPC::Message* msg) OVERRIDE {
+ switch (msg->type()) {
+ case PowerMonitorMsg_Suspend::ID:
+ suspends_++;
+ break;
+ case PowerMonitorMsg_Resume::ID:
+ resumes_++;
+ break;
+ case PowerMonitorMsg_PowerStateChange::ID:
+ power_state_changes_++;
+ break;
+ }
+ delete msg;
+ return true;
+ };
+
+ // Test status counts.
+ int power_state_changes() { return power_state_changes_; }
+ int suspends() { return suspends_; }
+ int resumes() { return resumes_; }
+
+ private:
+ int power_state_changes_; // Count of OnPowerStateChange notifications.
+ int suspends_; // Count of OnSuspend notifications.
+ int resumes_; // Count of OnResume notifications.
+};
+
+class PowerMonitorMessageBroadcasterTest : public testing::Test {
+ protected:
+ PowerMonitorMessageBroadcasterTest() {
+ power_monitor_source_ = new base::PowerMonitorTestSource();
+ power_monitor_.reset(new base::PowerMonitor(
+ scoped_ptr<base::PowerMonitorSource>(power_monitor_source_)));
+ }
+ virtual ~PowerMonitorMessageBroadcasterTest() {};
+
+ base::PowerMonitorTestSource* source() { return power_monitor_source_; }
+ base::PowerMonitor* monitor() { return power_monitor_.get(); }
+
+ private:
+ base::PowerMonitorTestSource* power_monitor_source_;
+ scoped_ptr<base::PowerMonitor> power_monitor_;
+
+ DISALLOW_COPY_AND_ASSIGN(PowerMonitorMessageBroadcasterTest);
+};
+
+TEST_F(PowerMonitorMessageBroadcasterTest, PowerMessageBroadcast) {
+ PowerMonitorMessageSender sender;
+ PowerMonitorMessageBroadcaster broadcaster(&sender);
+
+ // Sending resume when not suspended should have no effect.
+ source()->GenerateResumeEvent();
+ EXPECT_EQ(sender.resumes(), 0);
+
+ // Pretend we suspended.
+ source()->GenerateSuspendEvent();
+ EXPECT_EQ(sender.suspends(), 1);
+
+ // Send a second suspend notification. This should be suppressed.
+ source()->GenerateSuspendEvent();
+ EXPECT_EQ(sender.suspends(), 1);
+
+ // Pretend we were awakened.
+ source()->GenerateResumeEvent();
+ EXPECT_EQ(sender.resumes(), 1);
+
+ // Send a duplicate resume notification. This should be suppressed.
+ source()->GenerateResumeEvent();
+ EXPECT_EQ(sender.resumes(), 1);
+
+ // Pretend the device has gone on battery power
+ source()->GeneratePowerStateEvent(true);
+ EXPECT_EQ(sender.power_state_changes(), 1);
+
+ // Repeated indications the device is on battery power should be suppressed.
+ source()->GeneratePowerStateEvent(true);
+ EXPECT_EQ(sender.power_state_changes(), 1);
+
+ // Pretend the device has gone off battery power
+ source()->GeneratePowerStateEvent(false);
+ EXPECT_EQ(sender.power_state_changes(), 2);
+
+ // Repeated indications the device is off battery power should be suppressed.
+ source()->GeneratePowerStateEvent(false);
+ EXPECT_EQ(sender.power_state_changes(), 2);
+}
+
+} // namespace base
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc
index 53a6fde..9302752 100644
--- a/content/browser/renderer_host/render_process_host_impl.cc
+++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -410,7 +410,8 @@ RenderProcessHostImpl::RenderProcessHostImpl(
ignore_input_events_(false),
supports_browser_plugin_(supports_browser_plugin),
is_guest_(is_guest),
- gpu_observer_registered_(false) {
+ gpu_observer_registered_(false),
+ power_monitor_broadcaster_(this) {
widget_helper_ = new RenderWidgetHelper();
ChildProcessSecurityPolicyImpl::GetInstance()->Add(GetID());
diff --git a/content/browser/renderer_host/render_process_host_impl.h b/content/browser/renderer_host/render_process_host_impl.h
index 65d85a0..72ec846 100644
--- a/content/browser/renderer_host/render_process_host_impl.h
+++ b/content/browser/renderer_host/render_process_host_impl.h
@@ -13,6 +13,7 @@
#include "base/process/process.h"
#include "base/timer/timer.h"
#include "content/browser/child_process_launcher.h"
+#include "content/browser/power_monitor_message_broadcaster.h"
#include "content/common/content_export.h"
#include "content/public/browser/global_request_id.h"
#include "content/public/browser/gpu_data_manager_observer.h"
@@ -320,6 +321,9 @@ class CONTENT_EXPORT RenderProcessHostImpl
// than once.
bool gpu_observer_registered_;
+ // Forwards power state messages to the renderer process.
+ PowerMonitorMessageBroadcaster power_monitor_broadcaster_;
+
DISALLOW_COPY_AND_ASSIGN(RenderProcessHostImpl);
};
diff --git a/content/child/child_thread.cc b/content/child/child_thread.cc
index e022259..bc3dcaa 100644
--- a/content/child/child_thread.cc
+++ b/content/child/child_thread.cc
@@ -19,6 +19,7 @@
#include "content/child/child_process.h"
#include "content/child/child_resource_message_filter.h"
#include "content/child/fileapi/file_system_dispatcher.h"
+#include "content/child/power_monitor_broadcast_source.h"
#include "content/child/quota_dispatcher.h"
#include "content/child/quota_message_filter.h"
#include "content/child/resource_dispatcher.h"
@@ -157,6 +158,16 @@ void ChildThread::Init() {
channel_->AddFilter(resource_message_filter_.get());
channel_->AddFilter(quota_message_filter_.get());
+ // In single process mode we may already have a power monitor
+ if (!base::PowerMonitor::Get()) {
+ scoped_ptr<PowerMonitorBroadcastSource> power_monitor_source(
+ new PowerMonitorBroadcastSource());
+ channel_->AddFilter(power_monitor_source->GetMessageFilter());
+
+ power_monitor_.reset(new base::PowerMonitor(
+ power_monitor_source.PassAs<base::PowerMonitorSource>()));
+ }
+
#if defined(OS_POSIX)
// Check that --process-type is specified so we don't do this in unit tests
// and single-process mode.
diff --git a/content/child/child_thread.h b/content/child/child_thread.h
index 173fa2f..b2095ab 100644
--- a/content/child/child_thread.h
+++ b/content/child/child_thread.h
@@ -9,6 +9,7 @@
#include "base/memory/scoped_ptr.h"
#include "base/memory/shared_memory.h"
#include "base/memory/weak_ptr.h"
+#include "base/power_monitor/power_monitor.h"
#include "base/tracked_objects.h"
#include "content/common/content_export.h"
#include "content/common/message_router.h"
@@ -201,6 +202,8 @@ class CONTENT_EXPORT ChildThread : public IPC::Listener, public IPC::Sender {
// starts profiling the tcmalloc heap.
scoped_ptr<base::debug::TraceMemoryController> trace_memory_controller_;
+ scoped_ptr<base::PowerMonitor> power_monitor_;
+
DISALLOW_COPY_AND_ASSIGN(ChildThread);
};
diff --git a/content/child/power_monitor_broadcast_source.cc b/content/child/power_monitor_broadcast_source.cc
new file mode 100644
index 0000000..b3f72ed
--- /dev/null
+++ b/content/child/power_monitor_broadcast_source.cc
@@ -0,0 +1,108 @@
+// Copyright (c) 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 "content/child/power_monitor_broadcast_source.h"
+
+#include "base/message_loop/message_loop.h"
+#include "content/common/power_monitor_messages.h"
+
+namespace content {
+
+class PowerMessageFilter : public IPC::ChannelProxy::MessageFilter {
+ public:
+ PowerMessageFilter(
+ PowerMonitorBroadcastSource* source,
+ scoped_refptr<base::MessageLoopProxy> message_loop)
+ : source_(source),
+ message_loop_(message_loop) {
+ }
+
+ virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE {
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(PowerMessageFilter, message)
+ IPC_MESSAGE_HANDLER(PowerMonitorMsg_PowerStateChange, OnPowerStateChange)
+ IPC_MESSAGE_HANDLER(PowerMonitorMsg_Suspend, OnSuspend)
+ IPC_MESSAGE_HANDLER(PowerMonitorMsg_Resume, OnResume)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ return handled;
+ }
+
+ void RemoveSource() {
+ source_ = NULL;
+ }
+
+ private:
+ friend class base::RefCounted<PowerMessageFilter>;
+
+ virtual ~PowerMessageFilter() {};
+
+ void OnPowerStateChange(bool on_battery_power) {
+ message_loop_->PostTask(FROM_HERE,
+ base::Bind(&PowerMessageFilter::NotifySourcePowerStateChange, this,
+ on_battery_power));
+ }
+ void OnSuspend() {
+ message_loop_->PostTask(FROM_HERE,
+ base::Bind(&PowerMessageFilter::NotifySourceSuspend, this));
+ }
+ void OnResume() {
+ message_loop_->PostTask(FROM_HERE,
+ base::Bind(&PowerMessageFilter::NotifySourceResume, this));
+ }
+
+ void NotifySourcePowerStateChange(bool on_battery_power) {
+ if (source_)
+ source_->OnPowerStateChange(on_battery_power);
+ }
+ void NotifySourceSuspend() {
+ if (source_)
+ source_->OnSuspend();
+ }
+ void NotifySourceResume() {
+ if (source_)
+ source_->OnResume();
+ }
+
+ // source_ should only be accessed on the thread associated with
+ // message_loop_.
+ PowerMonitorBroadcastSource* source_;
+ scoped_refptr<base::MessageLoopProxy> message_loop_;
+
+ DISALLOW_COPY_AND_ASSIGN(PowerMessageFilter);
+};
+
+PowerMonitorBroadcastSource::PowerMonitorBroadcastSource()
+ : last_reported_battery_power_state_(false) {
+ message_filter_ = new PowerMessageFilter(this,
+ base::MessageLoopProxy::current());
+}
+
+PowerMonitorBroadcastSource::~PowerMonitorBroadcastSource() {
+ message_filter_->RemoveSource();
+}
+
+IPC::ChannelProxy::MessageFilter*
+PowerMonitorBroadcastSource::GetMessageFilter() {
+ return message_filter_.get();
+}
+
+bool PowerMonitorBroadcastSource::IsOnBatteryPowerImpl() {
+ return last_reported_battery_power_state_;
+}
+
+void PowerMonitorBroadcastSource::OnPowerStateChange(bool on_battery_power) {
+ last_reported_battery_power_state_ = on_battery_power;
+ ProcessPowerEvent(PowerMonitorSource::POWER_STATE_EVENT);
+}
+
+void PowerMonitorBroadcastSource::OnSuspend() {
+ ProcessPowerEvent(PowerMonitorSource::SUSPEND_EVENT);
+}
+
+void PowerMonitorBroadcastSource::OnResume() {
+ ProcessPowerEvent(PowerMonitorSource::RESUME_EVENT);
+}
+
+} // namespace content
diff --git a/content/child/power_monitor_broadcast_source.h b/content/child/power_monitor_broadcast_source.h
new file mode 100644
index 0000000..c2553f8
--- /dev/null
+++ b/content/child/power_monitor_broadcast_source.h
@@ -0,0 +1,44 @@
+// Copyright (c) 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 CONTENT_CHILD_POWER_MONITOR_BROADCAST_SOURCE_H_
+#define CONTENT_CHILD_POWER_MONITOR_BROADCAST_SOURCE_H_
+
+#include "base/power_monitor/power_monitor_source.h"
+#include "content/common/content_export.h"
+#include "ipc/ipc_channel.h"
+#include "ipc/ipc_channel_proxy.h"
+
+namespace content {
+
+class PowerMessageFilter;
+
+// Receives Power Monitor IPC messages sent from the browser process and relays
+// them to the PowerMonitor of the current process.
+class CONTENT_EXPORT PowerMonitorBroadcastSource :
+ public base::PowerMonitorSource {
+ public:
+ explicit PowerMonitorBroadcastSource();
+ virtual ~PowerMonitorBroadcastSource();
+
+ IPC::ChannelProxy::MessageFilter* GetMessageFilter();
+
+ private:
+ friend class PowerMessageFilter;
+
+ virtual bool IsOnBatteryPowerImpl() OVERRIDE;
+
+ void OnPowerStateChange(bool on_battery_power);
+ void OnSuspend();
+ void OnResume();
+
+ bool last_reported_battery_power_state_;
+ scoped_refptr<PowerMessageFilter> message_filter_;
+
+ DISALLOW_COPY_AND_ASSIGN(PowerMonitorBroadcastSource);
+};
+
+} // namespace content
+
+#endif // CONTENT_CHILD_POWER_MONITOR_MESSAGE_FILTER_H_
diff --git a/content/child/power_monitor_broadcast_source_unittest.cc b/content/child/power_monitor_broadcast_source_unittest.cc
new file mode 100644
index 0000000..0d09f60
--- /dev/null
+++ b/content/child/power_monitor_broadcast_source_unittest.cc
@@ -0,0 +1,95 @@
+// 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 "base/message_loop/message_loop.h"
+#include "base/power_monitor/power_monitor_test_base.h"
+#include "content/child/power_monitor_broadcast_source.h"
+#include "content/common/power_monitor_messages.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+
+class PowerMonitorBroadcastSourceTest : public testing::Test {
+ protected:
+ PowerMonitorBroadcastSourceTest() {
+ power_monitor_source_ = new PowerMonitorBroadcastSource();
+ power_monitor_.reset(new base::PowerMonitor(
+ scoped_ptr<base::PowerMonitorSource>(power_monitor_source_)));
+ }
+ virtual ~PowerMonitorBroadcastSourceTest() {}
+
+ PowerMonitorBroadcastSource* source() { return power_monitor_source_; }
+ base::PowerMonitor* monitor() { return power_monitor_.get(); }
+
+ base::MessageLoop message_loop_;
+
+ private:
+ PowerMonitorBroadcastSource* power_monitor_source_;
+ scoped_ptr<base::PowerMonitor> power_monitor_;
+
+ DISALLOW_COPY_AND_ASSIGN(PowerMonitorBroadcastSourceTest);
+};
+
+TEST_F(PowerMonitorBroadcastSourceTest, PowerMessageReceiveBroadcast) {
+ IPC::ChannelProxy::MessageFilter* message_filter =
+ source()->GetMessageFilter();
+
+ base::PowerMonitorTestObserver observer;
+ monitor()->AddObserver(&observer);
+
+ PowerMonitorMsg_Suspend suspend_msg;
+ PowerMonitorMsg_Resume resume_msg;
+
+ // Sending resume when not suspended should have no effect.
+ message_filter->OnMessageReceived(resume_msg);
+ message_loop_.RunUntilIdle();
+ EXPECT_EQ(observer.resumes(), 0);
+
+ // Pretend we suspended.
+ message_filter->OnMessageReceived(suspend_msg);
+ message_loop_.RunUntilIdle();
+ EXPECT_EQ(observer.suspends(), 1);
+
+ // Send a second suspend notification. This should be suppressed.
+ message_filter->OnMessageReceived(suspend_msg);
+ message_loop_.RunUntilIdle();
+ EXPECT_EQ(observer.suspends(), 1);
+
+ // Pretend we were awakened.
+ message_filter->OnMessageReceived(resume_msg);
+ message_loop_.RunUntilIdle();
+ EXPECT_EQ(observer.resumes(), 1);
+
+ // Send a duplicate resume notification. This should be suppressed.
+ message_filter->OnMessageReceived(resume_msg);
+ message_loop_.RunUntilIdle();
+ EXPECT_EQ(observer.resumes(), 1);
+
+ PowerMonitorMsg_PowerStateChange on_battery_msg(true);
+ PowerMonitorMsg_PowerStateChange off_battery_msg(false);
+
+ // Pretend the device has gone on battery power
+ message_filter->OnMessageReceived(on_battery_msg);
+ message_loop_.RunUntilIdle();
+ EXPECT_EQ(observer.power_state_changes(), 1);
+ EXPECT_EQ(observer.last_power_state(), true);
+
+ // Repeated indications the device is on battery power should be suppressed.
+ message_filter->OnMessageReceived(on_battery_msg);
+ message_loop_.RunUntilIdle();
+ EXPECT_EQ(observer.power_state_changes(), 1);
+
+ // Pretend the device has gone off battery power
+ message_filter->OnMessageReceived(off_battery_msg);
+ message_loop_.RunUntilIdle();
+ EXPECT_EQ(observer.power_state_changes(), 2);
+ EXPECT_EQ(observer.last_power_state(), false);
+
+ // Repeated indications the device is off battery power should be suppressed.
+ message_filter->OnMessageReceived(off_battery_msg);
+ message_loop_.RunUntilIdle();
+ EXPECT_EQ(observer.power_state_changes(), 2);
+}
+
+} // namespace base
diff --git a/content/common/content_message_generator.h b/content/common/content_message_generator.h
index f1c88e9..ba81705 100644
--- a/content/common/content_message_generator.h
+++ b/content/common/content_message_generator.h
@@ -44,6 +44,7 @@
#include "content/common/p2p_messages.h"
#include "content/common/pepper_messages.h"
#include "content/common/plugin_process_messages.h"
+#include "content/common/power_monitor_messages.h"
#include "content/common/quota_messages.h"
#include "content/common/resource_messages.h"
#include "content/common/socket_stream_messages.h"
diff --git a/content/common/power_monitor_messages.h b/content/common/power_monitor_messages.h
new file mode 100644
index 0000000..9b46245
--- /dev/null
+++ b/content/common/power_monitor_messages.h
@@ -0,0 +1,26 @@
+// Copyright (c) 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.
+
+// Multiply-included message file, no include guard.
+
+#include "ipc/ipc_message_macros.h"
+#include "ipc/ipc_param_traits.h"
+#include "ipc/ipc_platform_file.h"
+
+#undef IPC_MESSAGE_EXPORT
+#define IPC_MESSAGE_EXPORT CONTENT_EXPORT
+#define IPC_MESSAGE_START PowerMonitorMsgStart
+
+// Messages sent from the browser to the renderer/gpu.
+
+// Notification of a change in power status of the computer, such
+// as from switching between battery and A/C power.
+IPC_MESSAGE_CONTROL1(PowerMonitorMsg_PowerStateChange,
+ bool /* on_battery_power */)
+
+// Notification that the system is suspending.
+IPC_MESSAGE_CONTROL0(PowerMonitorMsg_Suspend)
+
+// Notification that the system is resuming.
+IPC_MESSAGE_CONTROL0(PowerMonitorMsg_Resume)
diff --git a/content/content_browser.gypi b/content/content_browser.gypi
index 66cfb54..cf84e74 100644
--- a/content/content_browser.gypi
+++ b/content/content_browser.gypi
@@ -711,6 +711,8 @@
'browser/plugin_process_host_mac.cc',
'browser/plugin_service_impl.cc',
'browser/plugin_service_impl.h',
+ 'browser/power_monitor_message_broadcaster.cc',
+ 'browser/power_monitor_message_broadcaster.h',
'browser/power_save_blocker_android.cc',
'browser/power_save_blocker_android.h',
'browser/power_save_blocker_chromeos.cc',
diff --git a/content/content_child.gypi b/content/content_child.gypi
index fce636b..109ae20 100644
--- a/content/content_child.gypi
+++ b/content/content_child.gypi
@@ -102,6 +102,8 @@
'child/plugin_messages.h',
'child/plugin_param_traits.cc',
'child/plugin_param_traits.h',
+ 'child/power_monitor_broadcast_source.cc',
+ 'child/power_monitor_broadcast_source.h',
'child/quota_dispatcher.cc',
'child/quota_dispatcher.h',
'child/quota_message_filter.cc',
diff --git a/content/content_common.gypi b/content/content_common.gypi
index b9eb787..cf12fda 100644
--- a/content/content_common.gypi
+++ b/content/content_common.gypi
@@ -298,6 +298,7 @@
'common/plugin_list_posix.cc',
'common/plugin_list_win.cc',
'common/plugin_process_messages.h',
+ 'common/power_monitor_messages.h',
'common/process_type.cc',
'common/quota_messages.h',
'common/resource_messages.cc',
diff --git a/content/content_tests.gypi b/content/content_tests.gypi
index 587234e..5affb8b 100644
--- a/content/content_tests.gypi
+++ b/content/content_tests.gypi
@@ -330,6 +330,7 @@
'browser/net/sqlite_persistent_cookie_store_unittest.cc',
'browser/notification_service_impl_unittest.cc',
'browser/plugin_loader_posix_unittest.cc',
+ 'browser/power_monitor_message_broadcaster_unittest.cc',
'browser/renderer_host/compositing_iosurface_transformer_mac_unittest.cc',
'browser/renderer_host/gtk_key_bindings_handler_unittest.cc',
'browser/renderer_host/input/immediate_input_router_unittest.cc',
@@ -390,6 +391,7 @@
'child/indexed_db/indexed_db_dispatcher_unittest.cc',
'child/indexed_db/proxy_webidbcursor_impl_unittest.cc',
'child/npapi/plugin_lib_unittest.cc',
+ 'child/power_monitor_broadcast_source_unittest.cc',
'child/resource_dispatcher_unittest.cc',
'common/android/address_parser_unittest.cc',
'common/cc_messages_unittest.cc',
diff --git a/content/plugin/plugin_main.cc b/content/plugin/plugin_main.cc
index 44a701b..e55d235 100644
--- a/content/plugin/plugin_main.cc
+++ b/content/plugin/plugin_main.cc
@@ -11,7 +11,6 @@
#include "base/bind.h"
#include "base/command_line.h"
#include "base/message_loop/message_loop.h"
-#include "base/power_monitor/power_monitor.h"
#include "base/strings/string_util.h"
#include "base/threading/platform_thread.h"
#include "base/timer/hi_res_timer_manager.h"
@@ -59,9 +58,6 @@ int PluginMain(const MainFunctionParams& parameters) {
base::debug::TraceLog::GetInstance()->SetProcessSortIndex(
kTraceEventPluginProcessSortIndex);
- base::PowerMonitor power_monitor;
- base::HighResolutionTimerManager high_resolution_timer_manager;
-
const CommandLine& parsed_command_line = parameters.command_line;
#if defined(OS_LINUX)
@@ -81,6 +77,7 @@ int PluginMain(const MainFunctionParams& parameters) {
{
ChildProcess plugin_process;
plugin_process.set_main_thread(new PluginThread());
+ base::HighResolutionTimerManager hi_res_timer_manager;
base::MessageLoop::current()->Run();
}
diff --git a/content/public/test/browser_test_base.cc b/content/public/test/browser_test_base.cc
index d15e54b..25d6330 100644
--- a/content/public/test/browser_test_base.cc
+++ b/content/public/test/browser_test_base.cc
@@ -20,7 +20,7 @@
#if defined(OS_MACOSX)
#include "base/mac/mac_util.h"
-#include "base/power_monitor/power_monitor.h"
+#include "base/power_monitor/power_monitor_device_source.h"
#endif
#if defined(OS_ANDROID)
@@ -67,7 +67,7 @@ BrowserTestBase::BrowserTestBase()
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO))) {
#if defined(OS_MACOSX)
base::mac::SetOverrideAmIBundled(true);
- base::PowerMonitor::AllocateSystemIOPorts();
+ base::PowerMonitorDeviceSource::AllocateSystemIOPorts();
#endif
#if defined(OS_POSIX)
diff --git a/content/renderer/renderer_main.cc b/content/renderer/renderer_main.cc
index d1b73403..0a8b0d8 100644
--- a/content/renderer/renderer_main.cc
+++ b/content/renderer/renderer_main.cc
@@ -16,7 +16,6 @@
#include "base/metrics/stats_counters.h"
#include "base/path_service.h"
#include "base/pending_task.h"
-#include "base/power_monitor/power_monitor.h"
#include "base/strings/string_util.h"
#include "base/threading/platform_thread.h"
#include "base/time/time.h"
@@ -168,9 +167,6 @@ int RendererMain(const MainFunctionParams& parameters) {
base::PlatformThread::SetName("CrRendererMain");
- base::PowerMonitor power_monitor;
- base::HighResolutionTimerManager hi_res_timer_manager;
-
platform.PlatformInitialize();
bool no_sandbox = parsed_command_line.HasSwitch(switches::kNoSandbox);
@@ -231,6 +227,8 @@ int RendererMain(const MainFunctionParams& parameters) {
new RenderThreadImpl();
#endif
+ base::HighResolutionTimerManager hi_res_timer_manager;
+
platform.RunSandboxTests(no_sandbox);
startup_timer.Stop(); // End of Startup Time Measurement.
diff --git a/content/utility/utility_main.cc b/content/utility/utility_main.cc
index 3d130f9..c93c1ec 100644
--- a/content/utility/utility_main.cc
+++ b/content/utility/utility_main.cc
@@ -4,7 +4,6 @@
#include "base/command_line.h"
#include "base/message_loop/message_loop.h"
-#include "base/power_monitor/power_monitor.h"
#include "base/threading/platform_thread.h"
#include "base/timer/hi_res_timer_manager.h"
#include "content/child/child_process.h"
@@ -26,9 +25,6 @@ int UtilityMain(const MainFunctionParams& parameters) {
base::MessageLoop main_message_loop;
base::PlatformThread::SetName("CrUtilityMain");
- base::PowerMonitor power_monitor;
- base::HighResolutionTimerManager hi_res_timer_manager;
-
#if defined(OS_LINUX)
// Initialize the sandbox before any thread is created.
LinuxSandbox::InitializeSandbox();
@@ -37,6 +33,8 @@ int UtilityMain(const MainFunctionParams& parameters) {
ChildProcess utility_process;
utility_process.set_main_thread(new UtilityThreadImpl());
+ base::HighResolutionTimerManager hi_res_timer_manager;
+
#if defined(OS_WIN)
bool no_sandbox = parameters.command_line.HasSwitch(switches::kNoSandbox);
if (!no_sandbox) {
diff --git a/content/worker/worker_main.cc b/content/worker/worker_main.cc
index 9e9f79f..b6a8fd1 100644
--- a/content/worker/worker_main.cc
+++ b/content/worker/worker_main.cc
@@ -5,7 +5,6 @@
#include "base/base_switches.h"
#include "base/command_line.h"
#include "base/message_loop/message_loop.h"
-#include "base/power_monitor/power_monitor.h"
#include "base/strings/string_util.h"
#include "base/threading/platform_thread.h"
#include "base/timer/hi_res_timer_manager.h"
@@ -31,9 +30,6 @@ int WorkerMain(const MainFunctionParams& parameters) {
base::MessageLoop main_message_loop;
base::PlatformThread::SetName("CrWorkerMain");
- base::PowerMonitor power_monitor;
- base::HighResolutionTimerManager hi_res_timer_manager;
-
#if defined(OS_WIN)
sandbox::TargetServices* target_services =
parameters.sandbox_info->target_services;
@@ -60,6 +56,8 @@ int WorkerMain(const MainFunctionParams& parameters) {
ChildProcess worker_process;
worker_process.set_main_thread(new WorkerThread());
+ base::HighResolutionTimerManager hi_res_timer_manager;
+
const CommandLine& parsed_command_line = parameters.command_line;
if (parsed_command_line.HasSwitch(switches::kWaitForDebugger)) {
ChildProcess::WaitForDebugger("Worker");
diff --git a/ipc/ipc_message_start.h b/ipc/ipc_message_start.h
index 79c823b..745acb0 100644
--- a/ipc/ipc_message_start.h
+++ b/ipc/ipc_message_start.h
@@ -88,6 +88,7 @@ enum IPCMessageStart {
WebRTCIdentityMsgStart,
EncodedVideoCaptureMsgStart,
LocalDiscoveryMsgStart,
+ PowerMonitorMsgStart,
LastIPCMsgStart // Must come last.
};