From 532f75fcab841de6f2fbaddd3491fcffdf5fd204 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Mon, 22 Jun 2015 10:23:58 +0800 Subject: [PATCH] Update PowerSaveBlocker APIs design. --- atom/browser/api/atom_api_power_save_blocker.cc | 64 ++++++++++++++++++++----- atom/browser/api/atom_api_power_save_blocker.h | 19 ++++++-- docs/api/power-save-blocker.md | 40 ++++++++++------ 3 files changed, 95 insertions(+), 28 deletions(-) diff --git a/atom/browser/api/atom_api_power_save_blocker.cc b/atom/browser/api/atom_api_power_save_blocker.cc index 98a84d0..0e09d9b 100644 --- a/atom/browser/api/atom_api_power_save_blocker.cc +++ b/atom/browser/api/atom_api_power_save_blocker.cc @@ -10,6 +10,12 @@ #include "atom/common/node_includes.h" +namespace { + +const char kPowerSaveBlockerDescription[] = "Electron"; + +} // namespace + namespace mate { template<> @@ -47,28 +53,64 @@ PowerSaveBlocker::PowerSaveBlocker() { PowerSaveBlocker::~PowerSaveBlocker() { } -void PowerSaveBlocker::Start( +void PowerSaveBlocker::UpdatePowerSaveBlocker() { + if (power_save_blocker_types_.empty()) { + power_save_blocker_.reset(); + return; + } + + // |kPowerSaveBlockPreventAppSuspension| keeps system active, but allows + // screen to be turned off. + // |kPowerSaveBlockPreventDisplaySleep| keeps system and screen active, has a + // higher precedence level than |kPowerSaveBlockPreventAppSuspension|. + // + // Only the highest-precedence blocker type takes effect. + content::PowerSaveBlocker::PowerSaveBlockerType new_blocker_type = + content::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension; + for (const auto& element : power_save_blocker_types_) { + if (element.second == + content::PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep) { + new_blocker_type = + content::PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep; + break; + } + } + + if (!power_save_blocker_ || new_blocker_type != current_blocker_type_) { + scoped_ptr new_blocker = + content::PowerSaveBlocker::Create( + new_blocker_type, + content::PowerSaveBlocker::kReasonOther, + kPowerSaveBlockerDescription); + power_save_blocker_.swap(new_blocker); + current_blocker_type_ = new_blocker_type; + } +} + +int PowerSaveBlocker::Start( content::PowerSaveBlocker::PowerSaveBlockerType type) { - power_save_blocker_ = content::PowerSaveBlocker::Create( - type, - content::PowerSaveBlocker::kReasonOther, - "Users required"); + static int count = 0; + power_save_blocker_types_[count] = type; + UpdatePowerSaveBlocker(); + return count++; } -void PowerSaveBlocker::Stop() { - power_save_blocker_.reset(); +bool PowerSaveBlocker::Stop(int id) { + bool success = power_save_blocker_types_.erase(id) > 0; + UpdatePowerSaveBlocker(); + return success; } -bool PowerSaveBlocker::IsStarted() { - return power_save_blocker_.get() != NULL; +bool PowerSaveBlocker::IsStarted(int id) { + return power_save_blocker_types_.find(id) != power_save_blocker_types_.end(); } mate::ObjectTemplateBuilder PowerSaveBlocker::GetObjectTemplateBuilder( v8::Isolate* isolate) { return mate::ObjectTemplateBuilder(isolate) .SetMethod("start", &PowerSaveBlocker::Start) - .SetMethod("stop", &PowerSaveBlocker::Stop); - .SetMethod("isStarted", &PowerSaveBlocker::IsStarted) + .SetMethod("stop", &PowerSaveBlocker::Stop) + .SetMethod("isStarted", &PowerSaveBlocker::IsStarted); } // static diff --git a/atom/browser/api/atom_api_power_save_blocker.h b/atom/browser/api/atom_api_power_save_blocker.h index 0333842..fdfb2d9 100644 --- a/atom/browser/api/atom_api_power_save_blocker.h +++ b/atom/browser/api/atom_api_power_save_blocker.h @@ -5,6 +5,8 @@ #ifndef ATOM_BROWSER_API_ATOM_API_POWER_SAVE_BLOCKER_H_ #define ATOM_BROWSER_API_ATOM_API_POWER_SAVE_BLOCKER_H_ +#include + #include "base/memory/scoped_ptr.h" #include "content/public/browser/power_save_blocker.h" #include "native_mate/handle.h" @@ -31,11 +33,22 @@ class PowerSaveBlocker : public mate::Wrappable { v8::Isolate* isolate) override; private: - void Start(content::PowerSaveBlocker::PowerSaveBlockerType type); - void Stop(); - bool IsStarted(); + void UpdatePowerSaveBlocker(); + int Start(content::PowerSaveBlocker::PowerSaveBlockerType type); + bool Stop(int id); + bool IsStarted(int id); scoped_ptr power_save_blocker_; + + // Currnet blocker type used by |power_save_blocker_| + content::PowerSaveBlocker::PowerSaveBlockerType current_blocker_type_; + + // Map from id to the corresponding blocker type for each request. + typedef std::map + PowerSaveBlockerTypeMap; + PowerSaveBlockerTypeMap power_save_blocker_types_; + + DISALLOW_COPY_AND_ASSIGN(PowerSaveBlocker); }; diff --git a/docs/api/power-save-blocker.md b/docs/api/power-save-blocker.md index 3dfb024..e4de5a1 100644 --- a/docs/api/power-save-blocker.md +++ b/docs/api/power-save-blocker.md @@ -1,37 +1,49 @@ # power-save-blocker The `power-save-blocker` module is used to block the system from entering -low-power(sleep) mode. +low-power(sleep) mode, allowing app to keep system and screen active. An example is: ```javascript var powerSaveBlocker = require('power-save-blocker'); -powerSaveBlocker.start(powerSaveBlocker.PREVENT_DISPLAY_SLEEP); -console.log(powerSaveBlocker.IsStarted()); +var id = powerSaveBlocker.start(powerSaveBlocker.PREVENT_DISPLAY_SLEEP); +console.log(powerSaveBlocker.isStarted(id)); + +powerSaveBlocker.stop(id); ``` ## powerSaveBlocker.start(type) -* type - Power save blocker type +* `type` - Power save blocker type * powerSaveBlocker.PREVENT_APP_SUSPENSION - Prevent the application from being - suspended. On some platforms, apps may be suspended when they are not visible - to the user. This type of block requests that the app continue to run in that - case,and on all platforms prevents the system from sleeping. + suspended. Keeps system active, but allows screen to be turned off. Example use cases: downloading a file, playing audio. * powerSaveBlocker.PREVENT_DISPLAY_SLEEP - Prevent the display from going to sleep. - This also has the side effect of preventing the system from sleeping, but - does not necessarily prevent the app from being suspended on some platforms - if the user hides it. + Keeps system and screen active. Example use case: playing video. Starts the power save blocker preventing the system entering lower-power mode. +Returns an integer identified the power save blocker. + +**Note:** +`PREVENT_DISPLAY_SLEEP` has higher precedence level than `PREVENT_APP_SUSPENSION`. +Only the highest precedence type takes effect. In other words, `PREVENT_DISPLAY_SLEEP` +always take precedence over `PREVENT_APP_SUSPENSION`. + +For example, an API calling A requests for `PREVENT_APP_SUSPENSION`, and +another calling B requests for `PREVENT_DISPLAY_SLEEP`. `PREVENT_DISPLAY_SLEEP` +will be used until B stops its request. After that, `PREVENT_APP_SUSPENSION` is used. + +## powerSaveBlocker.stop(id) + +* `id` Integer - The power save blocker id returned by `powerSaveBlocker.start`. -## powerSaveBlocker.isStarted() +Stops the specified power save blocker. -Returns whether the `powerSaveBlocker` starts. +## powerSaveBlocker.isStarted(id) -## powerSaveBlocker.stop() +* `id` Integer - The power save blocker id returned by `powerSaveBlocker.start`. -Stops blocking the system from entering low-power mode. +Returns whether the corresponding `powerSaveBlocker` starts. -- 2.7.4