Repo created
This commit is contained in:
parent
81b91f4139
commit
f8c34fa5ee
22732 changed files with 4815320 additions and 2 deletions
|
|
@ -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
|
||||
|
|
@ -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_
|
||||
|
|
@ -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
|
||||
|
|
@ -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_
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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, ¬ifier_);
|
||||
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(¬ifier_);
|
||||
|
||||
// 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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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_
|
||||
|
|
@ -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_
|
||||
Loading…
Add table
Add a link
Reference in a new issue