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

Side by Side Diff: chrome/browser/chromeos/arc/fileapi/arc_file_system_operation_runner.cc

Issue 2715493002: mediaview: Support watchers in ArcFileSystemOperationRunner. (Closed)
Patch Set: Avoid UI/IO thread confusion in util. Created 3 years, 9 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 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 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 "chrome/browser/chromeos/arc/fileapi/arc_file_system_operation_runner.h " 5 #include "chrome/browser/chromeos/arc/fileapi/arc_file_system_operation_runner.h "
6 6
7 #include <utility>
8
7 #include "base/bind.h" 9 #include "base/bind.h"
8 #include "base/location.h" 10 #include "base/location.h"
9 #include "base/memory/ptr_util.h" 11 #include "base/memory/ptr_util.h"
10 #include "base/optional.h" 12 #include "base/optional.h"
11 #include "base/threading/thread_task_runner_handle.h" 13 #include "base/threading/thread_task_runner_handle.h"
12 #include "chrome/browser/chromeos/arc/arc_util.h" 14 #include "chrome/browser/chromeos/arc/arc_util.h"
13 #include "components/arc/arc_bridge_service.h" 15 #include "components/arc/arc_bridge_service.h"
14 #include "content/public/browser/browser_thread.h" 16 #include "content/public/browser/browser_thread.h"
15 #include "url/gurl.h" 17 #include "url/gurl.h"
16 18
17 using content::BrowserThread; 19 using content::BrowserThread;
18 20
19 namespace arc { 21 namespace arc {
20 22
23 namespace {
24
25 // TODO(nya): Use typemaps.
26 ArcFileSystemOperationRunner::ChangeType FromMojoChangeType(
27 mojom::ChangeType type) {
28 switch (type) {
29 case mojom::ChangeType::CHANGED:
30 return ArcFileSystemOperationRunner::ChangeType::CHANGED;
31 case mojom::ChangeType::DELETED:
32 return ArcFileSystemOperationRunner::ChangeType::DELETED;
33 }
34 NOTREACHED();
35 return ArcFileSystemOperationRunner::ChangeType::CHANGED;
36 }
37
38 } // namespace
39
21 // static 40 // static
22 const char ArcFileSystemOperationRunner::kArcServiceName[] = 41 const char ArcFileSystemOperationRunner::kArcServiceName[] =
23 "arc::ArcFileSystemOperationRunner"; 42 "arc::ArcFileSystemOperationRunner";
24 43
25 // static 44 // static
26 std::unique_ptr<ArcFileSystemOperationRunner> 45 std::unique_ptr<ArcFileSystemOperationRunner>
27 ArcFileSystemOperationRunner::CreateForTesting( 46 ArcFileSystemOperationRunner::CreateForTesting(
28 ArcBridgeService* bridge_service) { 47 ArcBridgeService* bridge_service) {
29 // We can't use base::MakeUnique() here because we are calling a private 48 // We can't use base::MakeUnique() here because we are calling a private
30 // constructor. 49 // constructor.
31 return base::WrapUnique<ArcFileSystemOperationRunner>( 50 return base::WrapUnique<ArcFileSystemOperationRunner>(
32 new ArcFileSystemOperationRunner(bridge_service, nullptr, false)); 51 new ArcFileSystemOperationRunner(bridge_service, nullptr, false));
33 } 52 }
34 53
35 ArcFileSystemOperationRunner::ArcFileSystemOperationRunner( 54 ArcFileSystemOperationRunner::ArcFileSystemOperationRunner(
36 ArcBridgeService* bridge_service, 55 ArcBridgeService* bridge_service,
37 const Profile* profile) 56 const Profile* profile)
38 : ArcFileSystemOperationRunner(bridge_service, profile, true) { 57 : ArcFileSystemOperationRunner(bridge_service, profile, true) {
39 DCHECK(profile); 58 DCHECK(profile);
40 } 59 }
41 60
42 ArcFileSystemOperationRunner::ArcFileSystemOperationRunner( 61 ArcFileSystemOperationRunner::ArcFileSystemOperationRunner(
43 ArcBridgeService* bridge_service, 62 ArcBridgeService* bridge_service,
44 const Profile* profile, 63 const Profile* profile,
45 bool observe_events) 64 bool set_should_defer_by_events)
46 : ArcService(bridge_service), 65 : ArcService(bridge_service),
47 profile_(profile), 66 profile_(profile),
48 observe_events_(observe_events), 67 set_should_defer_by_events_(set_should_defer_by_events),
68 binding_(this),
49 weak_ptr_factory_(this) { 69 weak_ptr_factory_(this) {
50 DCHECK_CURRENTLY_ON(BrowserThread::UI); 70 DCHECK_CURRENTLY_ON(BrowserThread::UI);
51 71
52 if (observe_events_) { 72 // We need to observe FileSystemInstance even in unit tests to call Init().
53 ArcSessionManager::Get()->AddObserver(this); 73 arc_bridge_service()->file_system()->AddObserver(this);
54 arc_bridge_service()->file_system()->AddObserver(this); 74
55 OnStateChanged(); 75 // ArcSessionManager may not exist in unit tests.
56 } 76 auto* arc_session_manager = ArcSessionManager::Get();
77 if (arc_session_manager)
78 arc_session_manager->AddObserver(this);
79
80 OnStateChanged();
57 } 81 }
58 82
59 ArcFileSystemOperationRunner::~ArcFileSystemOperationRunner() { 83 ArcFileSystemOperationRunner::~ArcFileSystemOperationRunner() {
60 DCHECK_CURRENTLY_ON(BrowserThread::UI); 84 DCHECK_CURRENTLY_ON(BrowserThread::UI);
61 85
62 if (observe_events_) { 86 auto* arc_session_manager = ArcSessionManager::Get();
63 ArcSessionManager::Get()->RemoveObserver(this); 87 if (arc_session_manager)
64 arc_bridge_service()->file_system()->RemoveObserver(this); 88 arc_session_manager->RemoveObserver(this);
65 } 89
90 arc_bridge_service()->file_system()->RemoveObserver(this);
66 // On destruction, deferred operations are discarded. 91 // On destruction, deferred operations are discarded.
67 } 92 }
68 93
94 void ArcFileSystemOperationRunner::AddObserver(Observer* observer) {
95 DCHECK_CURRENTLY_ON(BrowserThread::UI);
96 observer_list_.AddObserver(observer);
97 }
98
99 void ArcFileSystemOperationRunner::RemoveObserver(Observer* observer) {
100 DCHECK_CURRENTLY_ON(BrowserThread::UI);
101 observer_list_.RemoveObserver(observer);
102 }
103
69 void ArcFileSystemOperationRunner::GetFileSize( 104 void ArcFileSystemOperationRunner::GetFileSize(
70 const GURL& url, 105 const GURL& url,
71 const GetFileSizeCallback& callback) { 106 const GetFileSizeCallback& callback) {
72 DCHECK_CURRENTLY_ON(BrowserThread::UI); 107 DCHECK_CURRENTLY_ON(BrowserThread::UI);
73 if (should_defer_) { 108 if (should_defer_) {
74 deferred_operations_.emplace_back( 109 deferred_operations_.emplace_back(
75 base::Bind(&ArcFileSystemOperationRunner::GetFileSize, 110 base::Bind(&ArcFileSystemOperationRunner::GetFileSize,
76 weak_ptr_factory_.GetWeakPtr(), url, callback)); 111 weak_ptr_factory_.GetWeakPtr(), url, callback));
77 return; 112 return;
78 } 113 }
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 arc_bridge_service()->file_system(), GetChildDocuments); 178 arc_bridge_service()->file_system(), GetChildDocuments);
144 if (!file_system_instance) { 179 if (!file_system_instance) {
145 base::ThreadTaskRunnerHandle::Get()->PostTask( 180 base::ThreadTaskRunnerHandle::Get()->PostTask(
146 FROM_HERE, base::Bind(callback, base::nullopt)); 181 FROM_HERE, base::Bind(callback, base::nullopt));
147 return; 182 return;
148 } 183 }
149 file_system_instance->GetChildDocuments(authority, parent_document_id, 184 file_system_instance->GetChildDocuments(authority, parent_document_id,
150 callback); 185 callback);
151 } 186 }
152 187
188 void ArcFileSystemOperationRunner::AddWatcher(
189 const std::string& authority,
190 const std::string& document_id,
191 const WatcherCallback& watcher_callback,
192 const AddWatcherCallback& callback) {
193 DCHECK_CURRENTLY_ON(BrowserThread::UI);
194 if (should_defer_) {
195 deferred_operations_.emplace_back(
196 base::Bind(&ArcFileSystemOperationRunner::AddWatcher,
197 weak_ptr_factory_.GetWeakPtr(), authority, document_id,
198 watcher_callback, callback));
199 return;
200 }
201 auto* file_system_instance = ARC_GET_INSTANCE_FOR_METHOD(
202 arc_bridge_service()->file_system(), AddWatcher);
203 if (!file_system_instance) {
204 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
205 base::Bind(callback, -1));
206 return;
207 }
208 file_system_instance->AddWatcher(
209 authority, document_id,
210 base::Bind(&ArcFileSystemOperationRunner::OnWatcherAdded,
211 weak_ptr_factory_.GetWeakPtr(), watcher_callback, callback));
212 }
213
214 void ArcFileSystemOperationRunner::RemoveWatcher(
215 int64_t watcher_id,
216 const RemoveWatcherCallback& callback) {
217 DCHECK_CURRENTLY_ON(BrowserThread::UI);
218 // RemoveWatcher() is never deferred since watchers do not persist across
219 // container reboots.
220 if (should_defer_) {
221 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
222 base::Bind(callback, false));
223 return;
224 }
225
226 // Unregister from |watcher_callbacks_| now because we will do it even if
227 // the remote method fails anyway. This is an implementation detail, so
228 // users must not assume registered callbacks are immediately invalidated.
229 auto iter = watcher_callbacks_.find(watcher_id);
230 if (iter == watcher_callbacks_.end()) {
231 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
232 base::Bind(callback, false));
233 return;
234 }
235 watcher_callbacks_.erase(iter);
236
237 auto* file_system_instance = ARC_GET_INSTANCE_FOR_METHOD(
238 arc_bridge_service()->file_system(), AddWatcher);
239 if (!file_system_instance) {
240 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
241 base::Bind(callback, false));
242 return;
243 }
244 file_system_instance->RemoveWatcher(watcher_id, callback);
245 }
246
247 void ArcFileSystemOperationRunner::OnDocumentChanged(int64_t watcher_id,
248 mojom::ChangeType type) {
249 DCHECK_CURRENTLY_ON(BrowserThread::UI);
250 auto iter = watcher_callbacks_.find(watcher_id);
251 if (iter == watcher_callbacks_.end()) {
252 // This may happen in a race condition with documents changes and
253 // RemoveWatcher().
254 return;
255 }
256 WatcherCallback watcher_callback = iter->second;
257 watcher_callback.Run(FromMojoChangeType(type));
258 }
259
153 void ArcFileSystemOperationRunner::OnArcPlayStoreEnabledChanged(bool enabled) { 260 void ArcFileSystemOperationRunner::OnArcPlayStoreEnabledChanged(bool enabled) {
154 DCHECK_CURRENTLY_ON(BrowserThread::UI); 261 DCHECK_CURRENTLY_ON(BrowserThread::UI);
155 OnStateChanged(); 262 OnStateChanged();
156 } 263 }
157 264
158 void ArcFileSystemOperationRunner::OnInstanceReady() { 265 void ArcFileSystemOperationRunner::OnInstanceReady() {
159 DCHECK_CURRENTLY_ON(BrowserThread::UI); 266 DCHECK_CURRENTLY_ON(BrowserThread::UI);
267 auto* file_system_instance =
268 ARC_GET_INSTANCE_FOR_METHOD(arc_bridge_service()->file_system(), Init);
269 if (file_system_instance)
270 file_system_instance->Init(binding_.CreateInterfacePtrAndBind());
160 OnStateChanged(); 271 OnStateChanged();
161 } 272 }
162 273
163 void ArcFileSystemOperationRunner::OnInstanceClosed() { 274 void ArcFileSystemOperationRunner::OnInstanceClosed() {
164 DCHECK_CURRENTLY_ON(BrowserThread::UI); 275 DCHECK_CURRENTLY_ON(BrowserThread::UI);
276 // ArcFileSystemService and watchers are gone.
277 watcher_callbacks_.clear();
278 for (auto& observer : observer_list_)
279 observer.OnWatchersCleared();
165 OnStateChanged(); 280 OnStateChanged();
166 } 281 }
167 282
283 void ArcFileSystemOperationRunner::OnWatcherAdded(
284 const WatcherCallback& watcher_callback,
285 const AddWatcherCallback& callback,
286 int64_t watcher_id) {
287 DCHECK_CURRENTLY_ON(BrowserThread::UI);
288 if (watcher_id < 0) {
289 callback.Run(-1);
290 return;
291 }
292 if (watcher_callbacks_.count(watcher_id)) {
293 LOG(ERROR) << "Conflicting watcher ID received. This must be a bug.";
dcheng 2017/03/02 07:21:45 Nit: DLOG please (same comment below)
Shuhei Takahashi 2017/03/02 07:30:50 Done.
294 callback.Run(-1);
295 return;
296 }
297 watcher_callbacks_.insert(std::make_pair(watcher_id, watcher_callback));
298 callback.Run(watcher_id);
299 }
300
168 void ArcFileSystemOperationRunner::OnStateChanged() { 301 void ArcFileSystemOperationRunner::OnStateChanged() {
169 DCHECK_CURRENTLY_ON(BrowserThread::UI); 302 DCHECK_CURRENTLY_ON(BrowserThread::UI);
170 SetShouldDefer(IsArcPlayStoreEnabledForProfile(profile_) && 303 if (set_should_defer_by_events_) {
171 !arc_bridge_service()->file_system()->has_instance()); 304 SetShouldDefer(IsArcPlayStoreEnabledForProfile(profile_) &&
305 !arc_bridge_service()->file_system()->has_instance());
306 }
172 } 307 }
173 308
174 void ArcFileSystemOperationRunner::SetShouldDefer(bool should_defer) { 309 void ArcFileSystemOperationRunner::SetShouldDefer(bool should_defer) {
175 DCHECK_CURRENTLY_ON(BrowserThread::UI); 310 DCHECK_CURRENTLY_ON(BrowserThread::UI);
176 311
177 should_defer_ = should_defer; 312 should_defer_ = should_defer;
178 313
179 if (should_defer_) 314 if (should_defer_)
180 return; 315 return;
181 316
182 // Run deferred operations. 317 // Run deferred operations.
183 std::vector<base::Closure> deferred_operations; 318 std::vector<base::Closure> deferred_operations;
184 deferred_operations.swap(deferred_operations_); 319 deferred_operations.swap(deferred_operations_);
185 for (const base::Closure& operation : deferred_operations) { 320 for (const base::Closure& operation : deferred_operations) {
186 operation.Run(); 321 operation.Run();
187 } 322 }
188 323
189 // No deferred operations should be left at this point. 324 // No deferred operations should be left at this point.
190 DCHECK(deferred_operations_.empty()); 325 DCHECK(deferred_operations_.empty());
191 } 326 }
192 327
193 } // namespace arc 328 } // namespace arc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698