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

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: error fix, non-frame client. 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) {} 17
18 base::StaticAtomicSequenceNumber g_unique_client_id;
19
20 } // namespace
21
22 WakeLockServiceImpl::WakeLockServiceImpl(
23 WakeLockServiceContext* context,
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 : context_(context),
31 type_(type),
32 reason_(reason),
33 description_(base::MakeUnique<std::string>(description)),
34 num_lock_requests_(0),
35 #if defined(OS_ANDROID)
36 context_id_(context_id),
37 native_view_getter_(native_view_getter),
38 #endif
39 main_task_runner_(base::ThreadTaskRunnerHandle::Get()),
40 file_task_runner_(std::move(file_task_runner)),
41 outstanding_(false) {
42 frames_binding_set_.set_connection_error_handler(base::Bind(
43 &WakeLockServiceImpl::OnConnectionError, base::Unretained(this)));
44 }
15 45
16 WakeLockServiceImpl::~WakeLockServiceImpl() { 46 WakeLockServiceImpl::~WakeLockServiceImpl() {
17 CancelWakeLock(); 47 if (wake_lock_) {
48 wake_lock_.reset();
49 DCHECK(context_);
50 context_->DecreaseWakeLockCount();
51 }
52 }
53
54 void WakeLockServiceImpl::AddClient(mojom::WakeLockServiceRequest request) {
55 // Multiple frames that associate to the same WebContents share the same one
56 // WakeLockServiceImpl instance. Two consecutive |RequestWakeLock| requests
57 // from the same frame should be coalesced as one request. Everytime a new
58 // client is being added into the bindingSet, we create an unique client_id
59 // as its context, this context is used as the key of the map |outstandings_|
60 // which records the clients' last requested status.
61 int client_id = g_unique_client_id.GetNext();
62 frames_binding_set_.AddBinding(this, std::move(request), client_id);
63 outstandings_[client_id] = false;
18 } 64 }
19 65
20 void WakeLockServiceImpl::RequestWakeLock() { 66 void WakeLockServiceImpl::RequestWakeLock() {
21 if (wake_lock_request_outstanding_) 67 DCHECK(main_task_runner_->RunsTasksOnCurrentThread());
22 return;
23 68
24 wake_lock_request_outstanding_ = true; 69 // |frames_binding_set_| empty means the requests are not from frames.
25 context_->RequestWakeLock(); 70 if (frames_binding_set_.empty()) {
71 if (outstanding_) {
72 return;
73 }
74 outstanding_ = true;
75 } else {
76 // If the requests are from frames, we need the Context of bindingSet to
77 // differenciate which binding is from which frame.
78 int client_id = frames_binding_set_.dispatch_context();
79 if (outstandings_[client_id]) {
80 return;
81 }
82 outstandings_[client_id] = true;
83 }
84
85 num_lock_requests_++;
86 UpdateWakeLock();
26 } 87 }
27 88
28 void WakeLockServiceImpl::CancelWakeLock() { 89 void WakeLockServiceImpl::CancelWakeLock() {
29 if (!wake_lock_request_outstanding_) 90 DCHECK(main_task_runner_->RunsTasksOnCurrentThread());
30 return;
31 91
32 wake_lock_request_outstanding_ = false; 92 if (frames_binding_set_.empty()) {
33 context_->CancelWakeLock(); 93 if (!outstanding_) {
94 return;
95 }
96 outstanding_ = false;
97 } else {
98 int client_id = frames_binding_set_.dispatch_context();
99 if (!outstandings_[client_id]) {
100 return;
101 }
102 outstandings_[client_id] = false;
103 if (num_lock_requests_ == 0) {
104 return;
105 }
106 }
107
108 num_lock_requests_--;
109 UpdateWakeLock();
110 }
111
112 void WakeLockServiceImpl::UpdateWakeLock() {
113 DCHECK(num_lock_requests_ >= 0);
114 if (num_lock_requests_) {
115 if (!wake_lock_)
116 CreateWakeLock();
117 } else {
118 if (wake_lock_)
119 RemoveWakeLock();
120 }
121 }
122
123 void WakeLockServiceImpl::CreateWakeLock() {
124 DCHECK(!wake_lock_);
125 wake_lock_ = base::MakeUnique<device::PowerSaveBlocker>(
126 type_, reason_, *description_, main_task_runner_, file_task_runner_);
127 DCHECK(context_);
128 context_->IncreaseWakeLockCount();
129
130 #if defined(OS_ANDROID)
131 gfx::NativeView native_view = native_view_getter_.Run(context_id_);
132 if (native_view) {
133 wake_lock_.get()->InitDisplaySleepBlocker(native_view);
134 }
135 #endif
136 }
137
138 void WakeLockServiceImpl::RemoveWakeLock() {
139 DCHECK(wake_lock_);
140 wake_lock_.reset();
141 DCHECK(context_);
142 context_->DecreaseWakeLockCount();
143 }
144
145 void WakeLockServiceImpl::OnConnectionError() {
146 int client_id = frames_binding_set_.dispatch_context();
147 // If the client's wakelock outstanding status is True before it crashes, we
148 // should decrease the num_lock_requests and call UpdateWakeLock().
149 if (outstandings_[client_id]) {
150 if (num_lock_requests_ == 0) {
151 return;
152 }
153 num_lock_requests_--;
154 UpdateWakeLock();
155 }
156
157 // Remove the entry of client_id from map.
158 outstandings_.erase(client_id);
34 } 159 }
35 160
36 } // namespace device 161 } // namespace device
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698