| OLD | NEW |
| (Empty) |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "device/wake_lock/wake_lock_service_impl.h" | |
| 6 | |
| 7 #include <utility> | |
| 8 | |
| 9 #include "base/memory/ptr_util.h" | |
| 10 | |
| 11 namespace device { | |
| 12 | |
| 13 namespace { | |
| 14 | |
| 15 PowerSaveBlocker::PowerSaveBlockerType ToPowerSaveBlockerType( | |
| 16 mojom::WakeLockType type) { | |
| 17 switch (type) { | |
| 18 case mojom::WakeLockType::PreventAppSuspension: | |
| 19 return PowerSaveBlocker::PowerSaveBlockerType:: | |
| 20 kPowerSaveBlockPreventAppSuspension; | |
| 21 case mojom::WakeLockType::PreventDisplaySleep: | |
| 22 return PowerSaveBlocker::PowerSaveBlockerType:: | |
| 23 kPowerSaveBlockPreventDisplaySleep; | |
| 24 } | |
| 25 | |
| 26 NOTREACHED(); | |
| 27 return PowerSaveBlocker::PowerSaveBlockerType:: | |
| 28 kPowerSaveBlockPreventAppSuspension; | |
| 29 } | |
| 30 | |
| 31 PowerSaveBlocker::Reason ToPowerSaveBlockerReason( | |
| 32 mojom::WakeLockReason reason) { | |
| 33 switch (reason) { | |
| 34 case mojom::WakeLockReason::ReasonAudioPlayback: | |
| 35 return PowerSaveBlocker::Reason::kReasonAudioPlayback; | |
| 36 case mojom::WakeLockReason::ReasonVideoPlayback: | |
| 37 return PowerSaveBlocker::Reason::kReasonVideoPlayback; | |
| 38 case mojom::WakeLockReason::ReasonOther: | |
| 39 return PowerSaveBlocker::Reason::kReasonOther; | |
| 40 } | |
| 41 | |
| 42 NOTREACHED(); | |
| 43 return PowerSaveBlocker::Reason::kReasonOther; | |
| 44 } | |
| 45 | |
| 46 } // namespace | |
| 47 | |
| 48 WakeLockServiceImpl::WakeLockServiceImpl( | |
| 49 mojom::WakeLockServiceRequest request, | |
| 50 mojom::WakeLockType type, | |
| 51 mojom::WakeLockReason reason, | |
| 52 const std::string& description, | |
| 53 int context_id, | |
| 54 WakeLockContextCallback native_view_getter, | |
| 55 scoped_refptr<base::SingleThreadTaskRunner> file_task_runner) | |
| 56 : num_lock_requests_(0), | |
| 57 type_(type), | |
| 58 reason_(reason), | |
| 59 description_(base::MakeUnique<std::string>(description)), | |
| 60 #if defined(OS_ANDROID) | |
| 61 context_id_(context_id), | |
| 62 native_view_getter_(native_view_getter), | |
| 63 #endif | |
| 64 main_task_runner_(base::ThreadTaskRunnerHandle::Get()), | |
| 65 file_task_runner_(std::move(file_task_runner)) { | |
| 66 AddClient(std::move(request)); | |
| 67 binding_set_.set_connection_error_handler(base::Bind( | |
| 68 &WakeLockServiceImpl::OnConnectionError, base::Unretained(this))); | |
| 69 } | |
| 70 | |
| 71 WakeLockServiceImpl::~WakeLockServiceImpl() {} | |
| 72 | |
| 73 void WakeLockServiceImpl::AddClient(mojom::WakeLockServiceRequest request) { | |
| 74 binding_set_.AddBinding(this, std::move(request), | |
| 75 base::MakeUnique<bool>(false)); | |
| 76 } | |
| 77 | |
| 78 void WakeLockServiceImpl::RequestWakeLock() { | |
| 79 DCHECK(main_task_runner_->RunsTasksInCurrentSequence()); | |
| 80 DCHECK(binding_set_.dispatch_context()); | |
| 81 | |
| 82 // Uses the Context to get the outstanding status of current binding. | |
| 83 // Two consecutive requests from the same client should be coalesced | |
| 84 // as one request. | |
| 85 if (*binding_set_.dispatch_context()) | |
| 86 return; | |
| 87 | |
| 88 *binding_set_.dispatch_context() = true; | |
| 89 num_lock_requests_++; | |
| 90 UpdateWakeLock(); | |
| 91 } | |
| 92 | |
| 93 void WakeLockServiceImpl::CancelWakeLock() { | |
| 94 DCHECK(main_task_runner_->RunsTasksInCurrentSequence()); | |
| 95 DCHECK(binding_set_.dispatch_context()); | |
| 96 | |
| 97 if (!(*binding_set_.dispatch_context())) | |
| 98 return; | |
| 99 | |
| 100 DCHECK(num_lock_requests_ > 0); | |
| 101 *binding_set_.dispatch_context() = false; | |
| 102 num_lock_requests_--; | |
| 103 UpdateWakeLock(); | |
| 104 } | |
| 105 | |
| 106 void WakeLockServiceImpl::HasWakeLockForTests( | |
| 107 HasWakeLockForTestsCallback callback) { | |
| 108 std::move(callback).Run(!!wake_lock_); | |
| 109 } | |
| 110 void WakeLockServiceImpl::UpdateWakeLock() { | |
| 111 DCHECK(num_lock_requests_ >= 0); | |
| 112 | |
| 113 if (num_lock_requests_) { | |
| 114 if (!wake_lock_) | |
| 115 CreateWakeLock(); | |
| 116 } else { | |
| 117 if (wake_lock_) | |
| 118 RemoveWakeLock(); | |
| 119 } | |
| 120 } | |
| 121 | |
| 122 void WakeLockServiceImpl::CreateWakeLock() { | |
| 123 DCHECK(!wake_lock_); | |
| 124 | |
| 125 // TODO(heke): Switch PowerSaveBlocker to use mojom::WakeLockType and | |
| 126 // mojom::WakeLockReason once all its clients are converted to be the clients | |
| 127 // of WakeLock. | |
| 128 wake_lock_ = base::MakeUnique<PowerSaveBlocker>( | |
| 129 ToPowerSaveBlockerType(type_), ToPowerSaveBlockerReason(reason_), | |
| 130 *description_, main_task_runner_, file_task_runner_); | |
| 131 | |
| 132 if (type_ != mojom::WakeLockType::PreventDisplaySleep) | |
| 133 return; | |
| 134 | |
| 135 #if defined(OS_ANDROID) | |
| 136 if (context_id_ == WakeLockServiceContext::WakeLockInvalidContextId) { | |
| 137 LOG(ERROR) << "Client must pass a valid context_id when requests wake lock " | |
| 138 "on Android."; | |
| 139 return; | |
| 140 } | |
| 141 | |
| 142 gfx::NativeView native_view = native_view_getter_.Run(context_id_); | |
| 143 if (native_view) | |
| 144 wake_lock_.get()->InitDisplaySleepBlocker(native_view); | |
| 145 #endif | |
| 146 } | |
| 147 | |
| 148 void WakeLockServiceImpl::RemoveWakeLock() { | |
| 149 DCHECK(wake_lock_); | |
| 150 wake_lock_.reset(); | |
| 151 } | |
| 152 | |
| 153 void WakeLockServiceImpl::OnConnectionError() { | |
| 154 // If this client has an outstanding wake lock request, decrease the | |
| 155 // num_lock_requests and call UpdateWakeLock(). | |
| 156 if (*binding_set_.dispatch_context() && num_lock_requests_ > 0) { | |
| 157 num_lock_requests_--; | |
| 158 UpdateWakeLock(); | |
| 159 } | |
| 160 | |
| 161 if (binding_set_.empty()) | |
| 162 base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this); | |
| 163 } | |
| 164 | |
| 165 } // namespace device | |
| OLD | NEW |