Repo created

This commit is contained in:
Fr4nz D13trich 2025-11-22 14:04:28 +01:00
parent 81b91f4139
commit f8c34fa5ee
22732 changed files with 4815320 additions and 2 deletions

View file

@ -0,0 +1,84 @@
// 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.h"
#include <utility>
#include "base/power_monitor/power_monitor_source.h"
#include "base/trace_event/trace_event.h"
namespace base {
void PowerMonitor::Initialize(std::unique_ptr<PowerMonitorSource> source) {
DCHECK(!IsInitialized());
GetInstance()->source_ = std::move(source);
}
bool PowerMonitor::IsInitialized() {
return GetInstance()->source_.get() != nullptr;
}
bool PowerMonitor::AddObserver(PowerObserver* obs) {
PowerMonitor* power_monitor = GetInstance();
if (!IsInitialized())
return false;
power_monitor->observers_->AddObserver(obs);
return true;
}
void PowerMonitor::RemoveObserver(PowerObserver* obs) {
GetInstance()->observers_->RemoveObserver(obs);
}
PowerMonitorSource* PowerMonitor::Source() {
return GetInstance()->source_.get();
}
bool PowerMonitor::IsOnBatteryPower() {
DCHECK(IsInitialized());
return GetInstance()->source_->IsOnBatteryPower();
}
void PowerMonitor::ShutdownForTesting() {
PowerMonitor::GetInstance()->observers_->AssertEmpty();
GetInstance()->source_ = nullptr;
}
void PowerMonitor::NotifyPowerStateChange(bool battery_in_use) {
DCHECK(IsInitialized());
DVLOG(1) << "PowerStateChange: " << (battery_in_use ? "On" : "Off")
<< " battery";
GetInstance()->observers_->Notify(
FROM_HERE, &PowerObserver::OnPowerStateChange, battery_in_use);
}
void PowerMonitor::NotifySuspend() {
DCHECK(IsInitialized());
TRACE_EVENT_INSTANT0("base", "PowerMonitor::NotifySuspend",
TRACE_EVENT_SCOPE_GLOBAL);
DVLOG(1) << "Power Suspending";
GetInstance()->observers_->Notify(FROM_HERE, &PowerObserver::OnSuspend);
}
void PowerMonitor::NotifyResume() {
DCHECK(IsInitialized());
TRACE_EVENT_INSTANT0("base", "PowerMonitor::NotifyResume",
TRACE_EVENT_SCOPE_GLOBAL);
DVLOG(1) << "Power Resuming";
GetInstance()->observers_->Notify(FROM_HERE, &PowerObserver::OnResume);
}
PowerMonitor* PowerMonitor::GetInstance() {
static base::NoDestructor<PowerMonitor> power_monitor;
return power_monitor.get();
}
PowerMonitor::PowerMonitor()
: observers_(
base::MakeRefCounted<ObserverListThreadSafe<PowerObserver>>()) {}
PowerMonitor::~PowerMonitor() = default;
} // namespace base

View file

@ -0,0 +1,84 @@
// 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_H_
#define BASE_POWER_MONITOR_POWER_MONITOR_H_
#include "base/base_export.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/no_destructor.h"
#include "base/observer_list_threadsafe.h"
#include "base/power_monitor/power_observer.h"
namespace base {
class PowerMonitorSource;
// A class used to monitor the power state change and notify the observers about
// the change event. The threading model of this class is as follows:
// Once initialized, it is threadsafe. However, the client must ensure that
// initialization happens before any other methods are invoked, including
// IsInitialized(). IsInitialized() exists only as a convenience for detection
// of test contexts where the PowerMonitor global is never created.
class BASE_EXPORT PowerMonitor {
public:
// Initializes global PowerMonitor state. Takes ownership of |source|, which
// will be leaked on process teardown. May only be called once. Not threadsafe
// - no other PowerMonitor methods may be called on any thread while calling
// Initialize(). |source| must not be nullptr.
static void Initialize(std::unique_ptr<PowerMonitorSource> source);
// Returns true if Initialize() has been called. Safe to call on any thread,
// but must not be called while Initialize() or ShutdownForTesting() is being
// invoked.
static bool IsInitialized();
// Add and remove an observer.
// Can be called from any thread. |observer| is notified on the sequence
// from which it was registered.
// Must not be called from within a notification callback.
//
// AddObserver() fails and returns false if PowerMonitor::Initialize() has not
// been invoked. Failure should only happen in unit tests, where the
// PowerMonitor is generally not initialized. It is safe to call
// RemoveObserver with a PowerObserver that was not successfully added as an
// observer.
static bool AddObserver(PowerObserver* observer);
static void RemoveObserver(PowerObserver* observer);
// Is the computer currently on battery power. May only be called if the
// PowerMonitor has been initialized.
static bool IsOnBatteryPower();
// Uninitializes the PowerMonitor. Should be called at the end of any unit
// test that mocks out the PowerMonitor, to avoid affecting subsequent tests.
// There must be no live PowerObservers when invoked. Safe to call even if the
// PowerMonitor hasn't been initialized.
static void ShutdownForTesting();
private:
friend class PowerMonitorSource;
friend class base::NoDestructor<PowerMonitor>;
PowerMonitor();
~PowerMonitor();
static PowerMonitorSource* Source();
static void NotifyPowerStateChange(bool battery_in_use);
static void NotifySuspend();
static void NotifyResume();
static PowerMonitor* GetInstance();
scoped_refptr<ObserverListThreadSafe<PowerObserver>> observers_;
std::unique_ptr<PowerMonitorSource> source_;
DISALLOW_COPY_AND_ASSIGN(PowerMonitor);
};
} // namespace base
#endif // BASE_POWER_MONITOR_POWER_MONITOR_H_

View file

@ -0,0 +1,28 @@
// 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"
namespace base {
PowerMonitorDeviceSource::PowerMonitorDeviceSource() {
#if defined(OS_MACOSX)
PlatformInit();
#endif
#if defined(OS_WIN) || defined(OS_MACOSX)
// Provide the correct battery status if possible. Others platforms, such as
// Android and ChromeOS, will update their status once their backends are
// actually initialized.
SetInitialOnBatteryPowerState(IsOnBatteryPowerImpl());
#endif
}
PowerMonitorDeviceSource::~PowerMonitorDeviceSource() {
#if defined(OS_MACOSX)
PlatformDestroy();
#endif
}
} // namespace base

View file

@ -0,0 +1,115 @@
// 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/macros.h"
#include "base/power_monitor/power_monitor_source.h"
#include "base/power_monitor/power_observer.h"
#include "build/build_config.h"
#if defined(OS_WIN)
#include <windows.h>
#endif // !OS_WIN
#if defined(OS_MACOSX) && !defined(OS_IOS)
#include <IOKit/IOTypes.h>
#include "base/mac/scoped_cftyperef.h"
#include "base/mac/scoped_ionotificationportref.h"
#endif
#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();
~PowerMonitorDeviceSource() override;
#if defined(OS_CHROMEOS)
// On Chrome OS, Chrome receives power-related events from powerd, the system
// power daemon, via D-Bus signals received on the UI thread. base can't
// directly depend on that code, so this class instead exposes static methods
// so that events can be passed in.
static void SetPowerSource(bool on_battery);
static void HandleSystemSuspending();
static void HandleSystemResumed();
#endif
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:
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();
#if !defined(OS_IOS)
// Callback from IORegisterForSystemPower(). |refcon| is the |this| pointer.
static void SystemPowerEventCallback(void* refcon,
io_service_t service,
natural_t message_type,
void* message_argument);
#endif // !OS_IOS
#endif // OS_MACOSX
// Platform-specific method to check whether the system is currently
// running on battery power. Returns true if running on batteries,
// false otherwise.
bool IsOnBatteryPowerImpl() override;
#if defined(OS_MACOSX) && !defined(OS_IOS)
// Reference to the system IOPMrootDomain port.
io_connect_t power_manager_port_ = IO_OBJECT_NULL;
// Notification port that delivers power (sleep/wake) notifications.
mac::ScopedIONotificationPortRef notification_port_;
// Notifier reference for the |notification_port_|.
io_object_t notifier_ = IO_OBJECT_NULL;
// Run loop source to observe power-source-change events.
ScopedCFTypeRef<CFRunLoopSourceRef> power_source_run_loop_source_;
#endif
#if defined(OS_IOS)
// Holds pointers to system event notification observers.
std::vector<id> notification_observers_;
#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_

View file

@ -0,0 +1,37 @@
// 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/base_jni_headers/PowerMonitor_jni.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"
namespace base {
// A helper function which is a friend of PowerMonitorSource.
void ProcessPowerEventHelper(PowerMonitorSource::PowerEvent event) {
PowerMonitorSource::ProcessPowerEvent(event);
}
namespace android {
// Native implementation of PowerMonitor.java. Note: This will be invoked by
// PowerMonitor.java shortly after startup to set the correct initial value for
// "is on battery power."
void JNI_PowerMonitor_OnBatteryChargingChanged(JNIEnv* env) {
ProcessPowerEventHelper(PowerMonitorSource::POWER_STATE_EVENT);
}
// Note: Android does not have the concept of suspend / resume as it's known by
// other platforms. Thus we do not send Suspend/Resume notifications. See
// http://crbug.com/644515
} // namespace android
bool PowerMonitorDeviceSource::IsOnBatteryPowerImpl() {
JNIEnv* env = base::android::AttachCurrentThread();
return base::android::Java_PowerMonitor_isBatteryPower(env);
}
} // namespace base

View file

@ -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 "base/power_monitor/power_monitor.h"
#include "base/power_monitor/power_monitor_device_source.h"
#include "base/power_monitor/power_monitor_source.h"
namespace base {
namespace {
// The most-recently-seen power source.
bool g_on_battery = false;
} // namespace
// static
void PowerMonitorDeviceSource::SetPowerSource(bool on_battery) {
if (on_battery != g_on_battery) {
g_on_battery = on_battery;
ProcessPowerEvent(POWER_STATE_EVENT);
}
}
// static
void PowerMonitorDeviceSource::HandleSystemSuspending() {
ProcessPowerEvent(SUSPEND_EVENT);
}
// static
void PowerMonitorDeviceSource::HandleSystemResumed() {
ProcessPowerEvent(RESUME_EVENT);
}
bool PowerMonitorDeviceSource::IsOnBatteryPowerImpl() {
return g_on_battery;
}
} // namespace base

View file

@ -0,0 +1,54 @@
// 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"
#import <UIKit/UIKit.h>
namespace base {
bool PowerMonitorDeviceSource::IsOnBatteryPowerImpl() {
#if TARGET_IPHONE_SIMULATOR
return false;
#else
UIDevice* currentDevice = [UIDevice currentDevice];
BOOL isCurrentAppMonitoringBattery = currentDevice.isBatteryMonitoringEnabled;
[UIDevice currentDevice].batteryMonitoringEnabled = YES;
UIDeviceBatteryState batteryState = [UIDevice currentDevice].batteryState;
currentDevice.batteryMonitoringEnabled = isCurrentAppMonitoringBattery;
DCHECK(batteryState != UIDeviceBatteryStateUnknown);
return batteryState == UIDeviceBatteryStateUnplugged;
#endif
}
void PowerMonitorDeviceSource::PlatformInit() {
NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
id foreground =
[nc addObserverForName:UIApplicationWillEnterForegroundNotification
object:nil
queue:nil
usingBlock:^(NSNotification* notification) {
ProcessPowerEvent(RESUME_EVENT);
}];
id background =
[nc addObserverForName:UIApplicationDidEnterBackgroundNotification
object:nil
queue:nil
usingBlock:^(NSNotification* notification) {
ProcessPowerEvent(SUSPEND_EVENT);
}];
notification_observers_.push_back(foreground);
notification_observers_.push_back(background);
}
void PowerMonitorDeviceSource::PlatformDestroy() {
NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
for (std::vector<id>::iterator it = notification_observers_.begin();
it != notification_observers_.end(); ++it) {
[nc removeObserver:*it];
}
notification_observers_.clear();
}
} // namespace base

View file

@ -0,0 +1,131 @@
// 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.
// 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/mac/foundation_util.h"
#include "base/mac/scoped_cftyperef.h"
#include "base/power_monitor/power_monitor.h"
#include "base/power_monitor/power_monitor_source.h"
#include <IOKit/IOMessage.h>
#include <IOKit/ps/IOPSKeys.h>
#include <IOKit/ps/IOPowerSources.h>
#include <IOKit/pwr_mgt/IOPMLib.h>
namespace base {
void ProcessPowerEventHelper(PowerMonitorSource::PowerEvent event) {
PowerMonitorSource::ProcessPowerEvent(event);
}
bool PowerMonitorDeviceSource::IsOnBatteryPowerImpl() {
base::ScopedCFTypeRef<CFTypeRef> info(IOPSCopyPowerSourcesInfo());
base::ScopedCFTypeRef<CFArrayRef> power_sources_list(
IOPSCopyPowerSourcesList(info));
const CFIndex count = CFArrayGetCount(power_sources_list);
for (CFIndex i = 0; i < count; ++i) {
const CFDictionaryRef description = IOPSGetPowerSourceDescription(
info, CFArrayGetValueAtIndex(power_sources_list, i));
if (!description)
continue;
CFStringRef current_state = base::mac::GetValueFromDictionary<CFStringRef>(
description, CFSTR(kIOPSPowerSourceStateKey));
if (!current_state)
continue;
// We only report "on battery power" if no source is on AC power.
if (CFStringCompare(current_state, CFSTR(kIOPSBatteryPowerValue), 0) !=
kCFCompareEqualTo) {
return false;
}
}
return true;
}
namespace {
void BatteryEventCallback(void*) {
ProcessPowerEventHelper(PowerMonitorSource::POWER_STATE_EVENT);
}
} // namespace
void PowerMonitorDeviceSource::PlatformInit() {
power_manager_port_ = IORegisterForSystemPower(
this,
mac::ScopedIONotificationPortRef::Receiver(notification_port_).get(),
&SystemPowerEventCallback, &notifier_);
DCHECK_NE(power_manager_port_, IO_OBJECT_NULL);
// Add the sleep/wake notification event source to the runloop.
CFRunLoopAddSource(
CFRunLoopGetCurrent(),
IONotificationPortGetRunLoopSource(notification_port_.get()),
kCFRunLoopCommonModes);
// Create and add the power-source-change event source to the runloop.
power_source_run_loop_source_.reset(
IOPSNotificationCreateRunLoopSource(&BatteryEventCallback, nullptr));
// Verify that the source was created. This may fail if the sandbox does not
// permit the process to access the underlying system service. See
// https://crbug.com/897557 for an example of such a configuration bug.
DCHECK(power_source_run_loop_source_);
CFRunLoopAddSource(CFRunLoopGetCurrent(), power_source_run_loop_source_,
kCFRunLoopDefaultMode);
}
void PowerMonitorDeviceSource::PlatformDestroy() {
CFRunLoopRemoveSource(
CFRunLoopGetCurrent(),
IONotificationPortGetRunLoopSource(notification_port_.get()),
kCFRunLoopCommonModes);
CFRunLoopRemoveSource(CFRunLoopGetCurrent(),
power_source_run_loop_source_.get(),
kCFRunLoopDefaultMode);
// Deregister for system power notifications.
IODeregisterForSystemPower(&notifier_);
// Close the connection to the IOPMrootDomain that was opened in
// PlatformInit().
IOServiceClose(power_manager_port_);
power_manager_port_ = IO_OBJECT_NULL;
}
void PowerMonitorDeviceSource::SystemPowerEventCallback(
void* refcon,
io_service_t service,
natural_t message_type,
void* message_argument) {
auto* thiz = static_cast<PowerMonitorDeviceSource*>(refcon);
switch (message_type) {
// If this message is not handled the system may delay sleep for 30 seconds.
case kIOMessageCanSystemSleep:
IOAllowPowerChange(thiz->power_manager_port_,
reinterpret_cast<intptr_t>(message_argument));
break;
case kIOMessageSystemWillSleep:
ProcessPowerEventHelper(PowerMonitorSource::SUSPEND_EVENT);
IOAllowPowerChange(thiz->power_manager_port_,
reinterpret_cast<intptr_t>(message_argument));
break;
case kIOMessageSystemWillPowerOn:
ProcessPowerEventHelper(PowerMonitorSource::RESUME_EVENT);
break;
}
}
} // namespace base

View file

@ -0,0 +1,14 @@
// 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"
namespace base {
bool PowerMonitorDeviceSource::IsOnBatteryPowerImpl() {
NOTIMPLEMENTED();
return false;
}
} // namespace base

View file

@ -0,0 +1,115 @@
// 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/message_loop/message_loop_current.h"
#include "base/power_monitor/power_monitor.h"
#include "base/power_monitor/power_monitor_source.h"
#include "base/strings/string16.h"
#include "base/strings/string_util.h"
#include "base/win/wrapped_window_proc.h"
namespace base {
void ProcessPowerEventHelper(PowerMonitorSource::PowerEvent event) {
PowerMonitorSource::ProcessPowerEvent(event);
}
namespace {
const char16 kWindowClassName[] = STRING16_LITERAL("Base_PowerMessageWindow");
void ProcessWmPowerBroadcastMessage(WPARAM event_id) {
PowerMonitorSource::PowerEvent power_event;
switch (event_id) {
case PBT_APMPOWERSTATUSCHANGE: // The power status changed.
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 = PowerMonitorSource::RESUME_EVENT;
break;
case PBT_APMSUSPEND: // System has been suspended.
power_event = PowerMonitorSource::SUSPEND_EVENT;
break;
default:
return;
// Other Power Events:
// PBT_APMBATTERYLOW - removed in Vista.
// PBT_APMOEMEVENT - removed in Vista.
// PBT_APMQUERYSUSPEND - removed in Vista.
// PBT_APMQUERYSUSPENDFAILED - removed in Vista.
// PBT_APMRESUMECRITICAL - removed in Vista.
// PBT_POWERSETTINGCHANGE - user changed the power settings.
}
ProcessPowerEventHelper(power_event);
}
} // namespace
// Function to query the system to see if it is currently running on
// battery power. Returns true if running on battery.
bool PowerMonitorDeviceSource::IsOnBatteryPowerImpl() {
SYSTEM_POWER_STATUS status;
if (!GetSystemPowerStatus(&status)) {
DPLOG(ERROR) << "GetSystemPowerStatus failed";
return false;
}
return (status.ACLineStatus == 0);
}
PowerMonitorDeviceSource::PowerMessageWindow::PowerMessageWindow()
: instance_(NULL), message_hwnd_(NULL) {
if (!MessageLoopCurrentForUI::IsSet()) {
// Creating this window in (e.g.) a renderer inhibits shutdown on Windows.
// See http://crbug.com/230122. TODO(vandebo): http://crbug.com/236031
DLOG(ERROR)
<< "Cannot create windows on non-UI thread, power monitor disabled!";
return;
}
WNDCLASSEX window_class;
base::win::InitializeWindowClass(
kWindowClassName,
&base::win::WrappedWindowProc<
PowerMonitorDeviceSource::PowerMessageWindow::WndProcThunk>,
0, 0, 0, NULL, NULL, NULL, NULL, NULL,
&window_class);
instance_ = window_class.hInstance;
ATOM clazz = RegisterClassEx(&window_class);
DCHECK(clazz);
message_hwnd_ =
CreateWindowEx(WS_EX_NOACTIVATE, as_wcstr(kWindowClassName), NULL,
WS_POPUP, 0, 0, 0, 0, NULL, NULL, instance_, NULL);
}
PowerMonitorDeviceSource::PowerMessageWindow::~PowerMessageWindow() {
if (message_hwnd_) {
DestroyWindow(message_hwnd_);
UnregisterClass(as_wcstr(kWindowClassName), instance_);
}
}
// static
LRESULT CALLBACK PowerMonitorDeviceSource::PowerMessageWindow::WndProcThunk(
HWND hwnd,
UINT message,
WPARAM wparam,
LPARAM lparam) {
switch (message) {
case WM_POWERBROADCAST:
ProcessWmPowerBroadcastMessage(wparam);
return TRUE;
default:
return ::DefWindowProc(hwnd, message, wparam, lparam);
}
}
} // namespace base

View file

@ -0,0 +1,69 @@
// 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"
#include "build/build_config.h"
namespace base {
PowerMonitorSource::PowerMonitorSource() = default;
PowerMonitorSource::~PowerMonitorSource() = default;
bool PowerMonitorSource::IsOnBatteryPower() {
AutoLock auto_lock(battery_lock_);
return on_battery_power_;
}
void PowerMonitorSource::ProcessPowerEvent(PowerEvent event_id) {
if (!PowerMonitor::IsInitialized())
return;
PowerMonitorSource* source = PowerMonitor::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)
PowerMonitor::NotifyPowerStateChange(new_on_battery_power);
}
break;
case RESUME_EVENT:
if (source->suspended_) {
source->suspended_ = false;
PowerMonitor::NotifyResume();
}
break;
case SUSPEND_EVENT:
if (!source->suspended_) {
source->suspended_ = true;
PowerMonitor::NotifySuspend();
}
break;
}
}
void PowerMonitorSource::SetInitialOnBatteryPowerState(bool on_battery_power) {
// Must only be called before an initialized PowerMonitor exists, otherwise
// the caller should have just used a normal
// ProcessPowerEvent(POWER_STATE_EVENT) call.
DCHECK(!PowerMonitor::Source());
on_battery_power_ = on_battery_power;
}
} // namespace base

View file

@ -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.
#ifndef BASE_POWER_MONITOR_POWER_MONITOR_SOURCE_H_
#define BASE_POWER_MONITOR_POWER_MONITOR_SOURCE_H_
#include "base/base_export.h"
#include "base/macros.h"
#include "base/memory/ref_counted.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);
// 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;
// Sets the initial state for |on_battery_power_|, which defaults to false
// since not all implementations can provide the value at construction. May
// only be called before a base::PowerMonitor has been created.
void SetInitialOnBatteryPowerState(bool on_battery_power);
private:
bool on_battery_power_ = false;
bool suspended_ = false;
// 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_

View file

@ -0,0 +1,31 @@
// 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_OBSERVER_H_
#define BASE_POWER_MONITOR_POWER_OBSERVER_H_
#include "base/base_export.h"
#include "base/compiler_specific.h"
namespace base {
class BASE_EXPORT PowerObserver {
public:
// Notification of a change in power status of the computer, such
// as from switching between battery and A/C power.
virtual void OnPowerStateChange(bool on_battery_power) {}
// Notification that the system is suspending.
virtual void OnSuspend() {}
// Notification that the system is resuming.
virtual void OnResume() {}
protected:
virtual ~PowerObserver() = default;
};
} // namespace base
#endif // BASE_POWER_MONITOR_POWER_OBSERVER_H_