atom_api_power_save_blocker.cc 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. // Copyright (c) 2015 GitHub, Inc.
  2. // Use of this source code is governed by the MIT license that can be
  3. // found in the LICENSE file.
  4. #include "atom/browser/api/atom_api_power_save_blocker.h"
  5. #include <string>
  6. #include "content/public/browser/browser_thread.h"
  7. #include "native_mate/dictionary.h"
  8. #include "atom/common/node_includes.h"
  9. using content::BrowserThread;
  10. namespace mate {
  11. template <>
  12. struct Converter<device::PowerSaveBlocker::PowerSaveBlockerType> {
  13. static bool FromV8(v8::Isolate* isolate,
  14. v8::Local<v8::Value> val,
  15. device::PowerSaveBlocker::PowerSaveBlockerType* out) {
  16. using device::PowerSaveBlocker;
  17. std::string type;
  18. if (!ConvertFromV8(isolate, val, &type))
  19. return false;
  20. if (type == "prevent-app-suspension")
  21. *out = PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension;
  22. else if (type == "prevent-display-sleep")
  23. *out = PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep;
  24. else
  25. return false;
  26. return true;
  27. }
  28. };
  29. } // namespace mate
  30. namespace atom {
  31. namespace api {
  32. PowerSaveBlocker::PowerSaveBlocker(v8::Isolate* isolate)
  33. : current_blocker_type_(
  34. device::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension) {
  35. Init(isolate);
  36. }
  37. PowerSaveBlocker::~PowerSaveBlocker() {}
  38. void PowerSaveBlocker::UpdatePowerSaveBlocker() {
  39. if (power_save_blocker_types_.empty()) {
  40. power_save_blocker_.reset();
  41. return;
  42. }
  43. // |kPowerSaveBlockPreventAppSuspension| keeps system active, but allows
  44. // screen to be turned off.
  45. // |kPowerSaveBlockPreventDisplaySleep| keeps system and screen active, has a
  46. // higher precedence level than |kPowerSaveBlockPreventAppSuspension|.
  47. //
  48. // Only the highest-precedence blocker type takes effect.
  49. device::PowerSaveBlocker::PowerSaveBlockerType new_blocker_type =
  50. device::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension;
  51. for (const auto& element : power_save_blocker_types_) {
  52. if (element.second ==
  53. device::PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep) {
  54. new_blocker_type =
  55. device::PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep;
  56. break;
  57. }
  58. }
  59. if (!power_save_blocker_ || new_blocker_type != current_blocker_type_) {
  60. std::unique_ptr<device::PowerSaveBlocker> new_blocker(
  61. new device::PowerSaveBlocker(
  62. new_blocker_type, device::PowerSaveBlocker::kReasonOther,
  63. ATOM_PRODUCT_NAME,
  64. BrowserThread::GetTaskRunnerForThread(BrowserThread::UI),
  65. BrowserThread::GetTaskRunnerForThread(BrowserThread::FILE)));
  66. power_save_blocker_.swap(new_blocker);
  67. current_blocker_type_ = new_blocker_type;
  68. }
  69. }
  70. int PowerSaveBlocker::Start(
  71. device::PowerSaveBlocker::PowerSaveBlockerType type) {
  72. static int count = 0;
  73. power_save_blocker_types_[count] = type;
  74. UpdatePowerSaveBlocker();
  75. return count++;
  76. }
  77. bool PowerSaveBlocker::Stop(int id) {
  78. bool success = power_save_blocker_types_.erase(id) > 0;
  79. UpdatePowerSaveBlocker();
  80. return success;
  81. }
  82. bool PowerSaveBlocker::IsStarted(int id) {
  83. return power_save_blocker_types_.find(id) != power_save_blocker_types_.end();
  84. }
  85. // static
  86. mate::Handle<PowerSaveBlocker> PowerSaveBlocker::Create(v8::Isolate* isolate) {
  87. return mate::CreateHandle(isolate, new PowerSaveBlocker(isolate));
  88. }
  89. // static
  90. void PowerSaveBlocker::BuildPrototype(
  91. v8::Isolate* isolate,
  92. v8::Local<v8::FunctionTemplate> prototype) {
  93. prototype->SetClassName(mate::StringToV8(isolate, "PowerSaveBlocker"));
  94. mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
  95. .SetMethod("start", &PowerSaveBlocker::Start)
  96. .SetMethod("stop", &PowerSaveBlocker::Stop)
  97. .SetMethod("isStarted", &PowerSaveBlocker::IsStarted);
  98. }
  99. } // namespace api
  100. } // namespace atom
  101. namespace {
  102. void Initialize(v8::Local<v8::Object> exports,
  103. v8::Local<v8::Value> unused,
  104. v8::Local<v8::Context> context,
  105. void* priv) {
  106. v8::Isolate* isolate = context->GetIsolate();
  107. mate::Dictionary dict(isolate, exports);
  108. dict.Set("powerSaveBlocker", atom::api::PowerSaveBlocker::Create(isolate));
  109. }
  110. } // namespace
  111. NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_power_save_blocker, Initialize);