Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(971)

Side by Side Diff: device/wake_lock/wake_lock_service_impl.cc

Issue 2843353003: Move ownership of PowerSaveBlocker from WakeLockServiceContext to WakeLockServiceImpl (Closed)
Patch Set: seperate this CL into 2CLs Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "device/wake_lock/wake_lock_service_impl.h" 5 #include "device/wake_lock/wake_lock_service_impl.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/atomic_sequence_num.h"
10 #include "base/memory/ptr_util.h"
11 #include "device/power_save_blocker/power_save_blocker.h"
9 #include "device/wake_lock/wake_lock_service_context.h" 12 #include "device/wake_lock/wake_lock_service_context.h"
10 13
11 namespace device { 14 namespace device {
12 15
13 WakeLockServiceImpl::WakeLockServiceImpl(WakeLockServiceContext* context) 16 namespace {
14 : context_(context), wake_lock_request_outstanding_(false) {}
15 17
16 WakeLockServiceImpl::~WakeLockServiceImpl() { 18 base::StaticAtomicSequenceNumber g_unique_client_id;
17 CancelWakeLock(); 19
20 } // namespace
21
22 WakeLockServiceImpl::WakeLockServiceImpl(
23 mojom::WakeLockServiceRequest request,
24 device::PowerSaveBlocker::PowerSaveBlockerType type,
25 device::PowerSaveBlocker::Reason reason,
26 const std::string& description,
27 int context_id,
28 WakeLockContextCallback native_view_getter,
29 scoped_refptr<base::SingleThreadTaskRunner> file_task_runner)
30 : type_(type),
31 reason_(reason),
32 description_(base::MakeUnique<std::string>(description)),
33 num_lock_requests_(0),
34 #if defined(OS_ANDROID)
35 context_id_(context_id),
36 native_view_getter_(native_view_getter),
37 #endif
38 main_task_runner_(base::ThreadTaskRunnerHandle::Get()),
39 file_task_runner_(std::move(file_task_runner)) {
40 AddClient(std::move(request));
41 binding_set_.set_connection_error_handler(base::Bind(
42 &WakeLockServiceImpl::OnConnectionError, base::Unretained(this)));
43 }
44
45 WakeLockServiceImpl::~WakeLockServiceImpl() {}
46
47 void WakeLockServiceImpl::AddClient(mojom::WakeLockServiceRequest request) {
48 // Multiple frames that associate to the same WebContents share the same one
49 // WakeLockServiceImpl instance. Two consecutive |RequestWakeLock| requests
50 // from the same frame should be coalesced as one request. Everytime a new
51 // client is being added into the bindingSet, we create an unique client_id
52 // as its context, this context is used as the key of the map |outstandings_|
53 // and |binding_ids| which record the clients' last requested status and
54 // BindingId.
55 int client_id = g_unique_client_id.GetNext();
56 mojo::BindingId binding_id =
57 binding_set_.AddBinding(this, std::move(request), client_id);
58 outstandings_[client_id] = false;
59 binding_ids_[client_id] = binding_id;
18 } 60 }
19 61
20 void WakeLockServiceImpl::RequestWakeLock() { 62 void WakeLockServiceImpl::RequestWakeLock() {
21 if (wake_lock_request_outstanding_) 63 DCHECK(main_task_runner_->RunsTasksOnCurrentThread());
64
65 // Uses the Context to get the outstanding status of current binding.
66 // Two consecutive requests from the same client should be coalesced
67 // as one request.
68 int client_id = binding_set_.dispatch_context();
blundell 2017/05/04 15:40:50 Ken and I discussed, and we think it should work f
ke.he 2017/05/05 08:58:01 Yes, |outstandings_| is not needed. Done.
69 DCHECK(outstandings_.find(client_id) != outstandings_.end());
70
71 if (outstandings_[client_id]) {
22 return; 72 return;
23 73 }
24 wake_lock_request_outstanding_ = true; 74 outstandings_[client_id] = true;
25 context_->RequestWakeLock(); 75 num_lock_requests_++;
76 UpdateWakeLock();
26 } 77 }
27 78
28 void WakeLockServiceImpl::CancelWakeLock() { 79 void WakeLockServiceImpl::CancelWakeLock() {
29 if (!wake_lock_request_outstanding_) 80 DCHECK(main_task_runner_->RunsTasksOnCurrentThread());
81
82 int client_id = binding_set_.dispatch_context();
83 DCHECK(outstandings_.find(client_id) != outstandings_.end());
84
85 if (!outstandings_[client_id]) {
30 return; 86 return;
87 }
88 outstandings_[client_id] = false;
89 if (num_lock_requests_ > 0) {
90 num_lock_requests_--;
91 UpdateWakeLock();
92 }
93 }
31 94
32 wake_lock_request_outstanding_ = false; 95 void WakeLockServiceImpl::HasWakeLockForTests(
33 context_->CancelWakeLock(); 96 const HasWakeLockForTestsCallback& callback) {
97 callback.Run(!!wake_lock_);
98 }
99 void WakeLockServiceImpl::UpdateWakeLock() {
100 DCHECK(num_lock_requests_ >= 0);
101
102 if (num_lock_requests_) {
103 if (!wake_lock_)
104 CreateWakeLock();
105 } else {
106 if (wake_lock_)
107 RemoveWakeLock();
108 }
109 }
110
111 void WakeLockServiceImpl::CreateWakeLock() {
112 DCHECK(!wake_lock_);
113 wake_lock_ = base::MakeUnique<device::PowerSaveBlocker>(
114 type_, reason_, *description_, main_task_runner_, file_task_runner_);
115
116 #if defined(OS_ANDROID)
117 gfx::NativeView native_view = native_view_getter_.Run(context_id_);
blundell 2017/05/04 15:40:50 You either need to do this conditionally based on
ke.he 2017/05/05 08:58:01 The type, reason and description has already been
118 if (native_view) {
119 wake_lock_.get()->InitDisplaySleepBlocker(native_view);
120 }
121 #endif
122 }
123
124 void WakeLockServiceImpl::RemoveWakeLock() {
125 DCHECK(wake_lock_);
126 wake_lock_.reset();
127 }
128
129 void WakeLockServiceImpl::OnConnectionError() {
130 int client_id = binding_set_.dispatch_context();
131
132 auto it = outstandings_.find(client_id);
133 if (it != outstandings_.end()) {
134 // If the error-happening client's wakelock is in outstanding status,
135 // decrease the num_lock_requests and call UpdateWakeLock().
136 if (it->second && num_lock_requests_ > 0) {
137 num_lock_requests_--;
138 UpdateWakeLock();
139 }
140 // Remove the entry of client_id from map.
141 outstandings_.erase(client_id);
142 }
143
144 // Remove error-happening client's binding from bindingSet.
145 auto it2 = binding_ids_.find(client_id);
146 if (it2 != binding_ids_.end()) {
147 binding_set_.RemoveBinding(it2->second);
blundell 2017/05/04 15:40:50 BindingSet has already done this at the time of ca
ke.he 2017/05/05 08:58:01 Yes. we don't need |binding_ids_|. Done.
148 binding_ids_.erase(client_id);
149 }
150
151 // If |binding_set_| is empty, WakeLockServiceImpl should delele itself.
152 if (binding_set_.empty()) {
153 base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this);
154 }
34 } 155 }
35 156
36 } // namespace device 157 } // namespace device
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698