From 7c5afdd3881130a68f4f0e33156d007a1e38bffb Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Sun, 21 Jun 2015 20:57:42 +0800 Subject: [PATCH 1/4] Add PowerSaveBlocker APIs. --- .../api/atom_api_power_save_blocker.cc | 94 +++++++++++++++++++ .../browser/api/atom_api_power_save_blocker.h | 46 +++++++++ .../browser/api/lib/power-save-blocker.coffee | 8 ++ atom/common/node_bindings.cc | 1 + filenames.gypi | 3 + 5 files changed, 152 insertions(+) create mode 100644 atom/browser/api/atom_api_power_save_blocker.cc create mode 100644 atom/browser/api/atom_api_power_save_blocker.h create mode 100644 atom/browser/api/lib/power-save-blocker.coffee diff --git a/atom/browser/api/atom_api_power_save_blocker.cc b/atom/browser/api/atom_api_power_save_blocker.cc new file mode 100644 index 000000000000..98a84d0001a5 --- /dev/null +++ b/atom/browser/api/atom_api_power_save_blocker.cc @@ -0,0 +1,94 @@ +// Copyright (c) 2015 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "atom/browser/api/atom_api_power_save_blocker.h" + +#include "content/public/browser/power_save_blocker.h" +#include "native_mate/constructor.h" +#include "native_mate/dictionary.h" + +#include "atom/common/node_includes.h" + +namespace mate { + +template<> +struct Converter { + static bool FromV8(v8::Isolate* isolate, + v8::Local val, + content::PowerSaveBlocker::PowerSaveBlockerType* out) { + using content::PowerSaveBlocker; + int type; + if (!ConvertFromV8(isolate, val, &type)) + return false; + switch (static_cast(type)) { + case PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension: + *out = PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension; + break; + case PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep: + *out = PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep; + break; + default: + return false; + } + return true; + } +}; + +} // namespace mate + +namespace atom { + +namespace api { + +PowerSaveBlocker::PowerSaveBlocker() { +} + +PowerSaveBlocker::~PowerSaveBlocker() { +} + +void PowerSaveBlocker::Start( + content::PowerSaveBlocker::PowerSaveBlockerType type) { + power_save_blocker_ = content::PowerSaveBlocker::Create( + type, + content::PowerSaveBlocker::kReasonOther, + "Users required"); +} + +void PowerSaveBlocker::Stop() { + power_save_blocker_.reset(); +} + +bool PowerSaveBlocker::IsStarted() { + return power_save_blocker_.get() != NULL; +} + +mate::ObjectTemplateBuilder PowerSaveBlocker::GetObjectTemplateBuilder( + v8::Isolate* isolate) { + return mate::ObjectTemplateBuilder(isolate) + .SetMethod("start", &PowerSaveBlocker::Start) + .SetMethod("stop", &PowerSaveBlocker::Stop); + .SetMethod("isStarted", &PowerSaveBlocker::IsStarted) +} + +// static +mate::Handle PowerSaveBlocker::Create(v8::Isolate* isolate) { + return CreateHandle(isolate, new PowerSaveBlocker); +} + +} // namespace api + +} // namespace atom + +namespace { + +void Initialize(v8::Local exports, v8::Local unused, + v8::Local context, void* priv) { + v8::Isolate* isolate = context->GetIsolate(); + mate::Dictionary dict(isolate, exports); + dict.Set("powerSaveBlocker", atom::api::PowerSaveBlocker::Create(isolate)); +} + +} // namespace + +NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_power_save_blocker, Initialize); diff --git a/atom/browser/api/atom_api_power_save_blocker.h b/atom/browser/api/atom_api_power_save_blocker.h new file mode 100644 index 000000000000..03338422de1e --- /dev/null +++ b/atom/browser/api/atom_api_power_save_blocker.h @@ -0,0 +1,46 @@ +// Copyright (c) 2015 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#ifndef ATOM_BROWSER_API_ATOM_API_POWER_SAVE_BLOCKER_H_ +#define ATOM_BROWSER_API_ATOM_API_POWER_SAVE_BLOCKER_H_ + +#include "base/memory/scoped_ptr.h" +#include "content/public/browser/power_save_blocker.h" +#include "native_mate/handle.h" +#include "native_mate/wrappable.h" + +namespace mate { +class Dictionary; +} + +namespace atom { + +namespace api { + +class PowerSaveBlocker : public mate::Wrappable { + public: + static mate::Handle Create(v8::Isolate* isolate); + + protected: + PowerSaveBlocker(); + virtual ~PowerSaveBlocker(); + + // mate::Wrappable implementations: + mate::ObjectTemplateBuilder GetObjectTemplateBuilder( + v8::Isolate* isolate) override; + + private: + void Start(content::PowerSaveBlocker::PowerSaveBlockerType type); + void Stop(); + bool IsStarted(); + + scoped_ptr power_save_blocker_; + DISALLOW_COPY_AND_ASSIGN(PowerSaveBlocker); +}; + +} // namespace api + +} // namespace atom + +#endif // ATOM_BROWSER_API_ATOM_API_POWER_SAVE_BLOCKER_H_ diff --git a/atom/browser/api/lib/power-save-blocker.coffee b/atom/browser/api/lib/power-save-blocker.coffee new file mode 100644 index 000000000000..6ac8b9b01905 --- /dev/null +++ b/atom/browser/api/lib/power-save-blocker.coffee @@ -0,0 +1,8 @@ +bindings = process.atomBinding 'power_save_blocker' + +powerSaveBlocker = bindings.powerSaveBlocker + +powerSaveBlocker.PREVENT_APP_SUSPENSION = 0 +powerSaveBlocker.PREVENT_DISPLAY_SLEEP = 1 + +module.exports = powerSaveBlocker diff --git a/atom/common/node_bindings.cc b/atom/common/node_bindings.cc index eb627d06b757..8e3db80125d6 100644 --- a/atom/common/node_bindings.cc +++ b/atom/common/node_bindings.cc @@ -35,6 +35,7 @@ REFERENCE_MODULE(atom_browser_content_tracing); REFERENCE_MODULE(atom_browser_dialog); REFERENCE_MODULE(atom_browser_menu); REFERENCE_MODULE(atom_browser_power_monitor); +REFERENCE_MODULE(atom_browser_power_save_blocker); REFERENCE_MODULE(atom_browser_protocol); REFERENCE_MODULE(atom_browser_global_shortcut); REFERENCE_MODULE(atom_browser_tray); diff --git a/filenames.gypi b/filenames.gypi index 99d37b5d3093..0c16a62ce107 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -20,6 +20,7 @@ 'atom/browser/api/lib/menu-item.coffee', 'atom/browser/api/lib/navigation-controller.coffee', 'atom/browser/api/lib/power-monitor.coffee', + 'atom/browser/api/lib/power-save-blocker.coffee', 'atom/browser/api/lib/protocol.coffee', 'atom/browser/api/lib/screen.coffee', 'atom/browser/api/lib/tray.coffee', @@ -80,6 +81,8 @@ 'atom/browser/api/atom_api_menu_mac.mm', 'atom/browser/api/atom_api_power_monitor.cc', 'atom/browser/api/atom_api_power_monitor.h', + 'atom/browser/api/atom_api_power_save_blocker.cc', + 'atom/browser/api/atom_api_power_save_blocker.h', 'atom/browser/api/atom_api_protocol.cc', 'atom/browser/api/atom_api_protocol.h', 'atom/browser/api/atom_api_screen.cc', From 7ee2a703d98ed1a38d3f4f3f1928968c8be1bfd8 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Sun, 21 Jun 2015 21:14:49 +0800 Subject: [PATCH 2/4] :memo: Add powerSaveBlocker APIs doc. --- docs/api/power-save-blocker.md | 37 ++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 docs/api/power-save-blocker.md diff --git a/docs/api/power-save-blocker.md b/docs/api/power-save-blocker.md new file mode 100644 index 000000000000..3dfb024aa23c --- /dev/null +++ b/docs/api/power-save-blocker.md @@ -0,0 +1,37 @@ +# power-save-blocker + +The `power-save-blocker` module is used to block the system from entering +low-power(sleep) mode. + +An example is: + +```javascript +var powerSaveBlocker = require('power-save-blocker'); + +powerSaveBlocker.start(powerSaveBlocker.PREVENT_DISPLAY_SLEEP); +console.log(powerSaveBlocker.IsStarted()); +``` + +## powerSaveBlocker.start(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. + 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. + Example use case: playing video. + +Starts the power save blocker preventing the system entering lower-power mode. + +## powerSaveBlocker.isStarted() + +Returns whether the `powerSaveBlocker` starts. + +## powerSaveBlocker.stop() + +Stops blocking the system from entering low-power mode. From 532f75fcab841de6f2fbaddd3491fcffdf5fd204 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Mon, 22 Jun 2015 10:23:58 +0800 Subject: [PATCH 3/4] Update PowerSaveBlocker APIs design. --- .../api/atom_api_power_save_blocker.cc | 64 +++++++++++++++---- .../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 98a84d0001a5..0e09d9b8c2bd 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 03338422de1e..fdfb2d9cdec8 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 3dfb024aa23c..e4de5a17d310 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. -## powerSaveBlocker.isStarted() +**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`. -Returns whether the `powerSaveBlocker` starts. +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() +## powerSaveBlocker.stop(id) -Stops blocking the system from entering low-power mode. +* `id` Integer - The power save blocker id returned by `powerSaveBlocker.start`. + +Stops the specified power save blocker. + +## powerSaveBlocker.isStarted(id) + +* `id` Integer - The power save blocker id returned by `powerSaveBlocker.start`. + +Returns whether the corresponding `powerSaveBlocker` starts. From 13784e6551040c4cc03769711b441f490c25cd64 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Wed, 24 Jun 2015 12:49:43 +0800 Subject: [PATCH 4/4] More updates: use string instead of integer to identify blocker type. --- .../api/atom_api_power_save_blocker.cc | 34 +++++++------------ .../browser/api/atom_api_power_save_blocker.h | 4 +-- .../browser/api/lib/power-save-blocker.coffee | 7 +--- docs/api/power-save-blocker.md | 27 +++++++-------- 4 files changed, 29 insertions(+), 43 deletions(-) diff --git a/atom/browser/api/atom_api_power_save_blocker.cc b/atom/browser/api/atom_api_power_save_blocker.cc index 0e09d9b8c2bd..c75901cb1e31 100644 --- a/atom/browser/api/atom_api_power_save_blocker.cc +++ b/atom/browser/api/atom_api_power_save_blocker.cc @@ -4,18 +4,12 @@ #include "atom/browser/api/atom_api_power_save_blocker.h" +#include + #include "content/public/browser/power_save_blocker.h" -#include "native_mate/constructor.h" #include "native_mate/dictionary.h" - #include "atom/common/node_includes.h" -namespace { - -const char kPowerSaveBlockerDescription[] = "Electron"; - -} // namespace - namespace mate { template<> @@ -24,19 +18,15 @@ struct Converter { v8::Local val, content::PowerSaveBlocker::PowerSaveBlockerType* out) { using content::PowerSaveBlocker; - int type; + std::string type; if (!ConvertFromV8(isolate, val, &type)) return false; - switch (static_cast(type)) { - case PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension: - *out = PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension; - break; - case PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep: - *out = PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep; - break; - default: - return false; - } + if (type == "prevent-app-suspension") + *out = PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension; + else if (type == "prevent-display-sleep") + *out = PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep; + else + return false; return true; } }; @@ -47,7 +37,9 @@ namespace atom { namespace api { -PowerSaveBlocker::PowerSaveBlocker() { +PowerSaveBlocker::PowerSaveBlocker() + : current_blocker_type_( + content::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension) { } PowerSaveBlocker::~PowerSaveBlocker() { @@ -81,7 +73,7 @@ void PowerSaveBlocker::UpdatePowerSaveBlocker() { content::PowerSaveBlocker::Create( new_blocker_type, content::PowerSaveBlocker::kReasonOther, - kPowerSaveBlockerDescription); + ATOM_PRODUCT_NAME); power_save_blocker_.swap(new_blocker); current_blocker_type_ = new_blocker_type; } diff --git a/atom/browser/api/atom_api_power_save_blocker.h b/atom/browser/api/atom_api_power_save_blocker.h index fdfb2d9cdec8..9861f2b0f7cd 100644 --- a/atom/browser/api/atom_api_power_save_blocker.h +++ b/atom/browser/api/atom_api_power_save_blocker.h @@ -44,8 +44,8 @@ class PowerSaveBlocker : public mate::Wrappable { content::PowerSaveBlocker::PowerSaveBlockerType current_blocker_type_; // Map from id to the corresponding blocker type for each request. - typedef std::map - PowerSaveBlockerTypeMap; + using PowerSaveBlockerTypeMap = + std::map; PowerSaveBlockerTypeMap power_save_blocker_types_; diff --git a/atom/browser/api/lib/power-save-blocker.coffee b/atom/browser/api/lib/power-save-blocker.coffee index 6ac8b9b01905..7f428bc40f19 100644 --- a/atom/browser/api/lib/power-save-blocker.coffee +++ b/atom/browser/api/lib/power-save-blocker.coffee @@ -1,8 +1,3 @@ bindings = process.atomBinding 'power_save_blocker' -powerSaveBlocker = bindings.powerSaveBlocker - -powerSaveBlocker.PREVENT_APP_SUSPENSION = 0 -powerSaveBlocker.PREVENT_DISPLAY_SLEEP = 1 - -module.exports = powerSaveBlocker +module.exports = bindings.powerSaveBlocker diff --git a/docs/api/power-save-blocker.md b/docs/api/power-save-blocker.md index e4de5a17d310..23b1252c6789 100644 --- a/docs/api/power-save-blocker.md +++ b/docs/api/power-save-blocker.md @@ -8,7 +8,7 @@ An example is: ```javascript var powerSaveBlocker = require('power-save-blocker'); -var id = powerSaveBlocker.start(powerSaveBlocker.PREVENT_DISPLAY_SLEEP); +var id = powerSaveBlocker.start('prevent-display-sleep'); console.log(powerSaveBlocker.isStarted(id)); powerSaveBlocker.stop(id); @@ -16,25 +16,24 @@ powerSaveBlocker.stop(id); ## powerSaveBlocker.start(type) -* `type` - Power save blocker type - * powerSaveBlocker.PREVENT_APP_SUSPENSION - Prevent the application from being - 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. - Keeps system and screen active. - Example use case: playing video. +* `type` String - Power save blocker type + * `prevent-app-suspension` - Prevent the application from being suspended. + Keeps system active, but allows screen to be turned off. Example use cases: + downloading a file, playing audio. + * `prevent-display-sleep`- Prevent the display from going to sleep. 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`. +`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. +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)