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..c75901cb1e31 --- /dev/null +++ b/atom/browser/api/atom_api_power_save_blocker.cc @@ -0,0 +1,128 @@ +// 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 + +#include "content/public/browser/power_save_blocker.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; + std::string type; + if (!ConvertFromV8(isolate, val, &type)) + return false; + if (type == "prevent-app-suspension") + *out = PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension; + else if (type == "prevent-display-sleep") + *out = PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep; + else + return false; + return true; + } +}; + +} // namespace mate + +namespace atom { + +namespace api { + +PowerSaveBlocker::PowerSaveBlocker() + : current_blocker_type_( + content::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension) { +} + +PowerSaveBlocker::~PowerSaveBlocker() { +} + +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, + ATOM_PRODUCT_NAME); + power_save_blocker_.swap(new_blocker); + current_blocker_type_ = new_blocker_type; + } +} + +int PowerSaveBlocker::Start( + content::PowerSaveBlocker::PowerSaveBlockerType type) { + static int count = 0; + power_save_blocker_types_[count] = type; + UpdatePowerSaveBlocker(); + return count++; +} + +bool PowerSaveBlocker::Stop(int id) { + bool success = power_save_blocker_types_.erase(id) > 0; + UpdatePowerSaveBlocker(); + return success; +} + +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); +} + +// 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..9861f2b0f7cd --- /dev/null +++ b/atom/browser/api/atom_api_power_save_blocker.h @@ -0,0 +1,59 @@ +// 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 + +#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 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. + using PowerSaveBlockerTypeMap = + std::map; + PowerSaveBlockerTypeMap power_save_blocker_types_; + + + 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..7f428bc40f19 --- /dev/null +++ b/atom/browser/api/lib/power-save-blocker.coffee @@ -0,0 +1,3 @@ +bindings = process.atomBinding 'power_save_blocker' + +module.exports = bindings.powerSaveBlocker diff --git a/atom/common/node_bindings.cc b/atom/common/node_bindings.cc index cc53fe7ab8c4..8f5dd07428ad 100644 --- a/atom/common/node_bindings.cc +++ b/atom/common/node_bindings.cc @@ -36,6 +36,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/docs/api/power-save-blocker.md b/docs/api/power-save-blocker.md new file mode 100644 index 000000000000..23b1252c6789 --- /dev/null +++ b/docs/api/power-save-blocker.md @@ -0,0 +1,48 @@ +# power-save-blocker + +The `power-save-blocker` module is used to block the system from entering +low-power(sleep) mode, allowing app to keep system and screen active. + +An example is: + +```javascript +var powerSaveBlocker = require('power-save-blocker'); + +var id = powerSaveBlocker.start('prevent-display-sleep'); +console.log(powerSaveBlocker.isStarted(id)); + +powerSaveBlocker.stop(id); +``` + +## powerSaveBlocker.start(type) + +* `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`. + +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`. + +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. diff --git a/filenames.gypi b/filenames.gypi index f0c940ab52d5..57b3e1011fde 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',