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

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: Rebased to ToT. 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 ArcFileSystemOperationRunner::ChangeType FromMojoChangeType(
26 mojom::ChangeType type) {
27 switch (type) {
28 case mojom::ChangeType::CHANGED:
29 return ArcFileSystemOperationRunner::ChangeType::CHANGED;
30 case mojom::ChangeType::DELETED:
31 return ArcFileSystemOperationRunner::ChangeType::DELETED;
dcheng 2017/02/28 06:56:32 Let's add a typemap for this.
Shuhei Takahashi 2017/03/01 09:10:08 Typemap sounds good and I tried adding one, but I
dcheng 2017/03/01 21:47:57 What's the error you're seeing?
Shuhei Takahashi 2017/03/02 02:05:01 Here's a WIP patch: https://codereview.chromium.or
32 }
33 NOTREACHED();
Luis Héctor Chávez 2017/03/06 17:10:48 nit: mention that the above switch is exhaustive,
34 return ArcFileSystemOperationRunner::ChangeType::CHANGED;
35 }
36
37 } // namespace
38
21 // static 39 // static
22 const char ArcFileSystemOperationRunner::kArcServiceName[] = 40 const char ArcFileSystemOperationRunner::kArcServiceName[] =
23 "arc::ArcFileSystemOperationRunner"; 41 "arc::ArcFileSystemOperationRunner";
24 42
25 // static 43 // static
26 std::unique_ptr<ArcFileSystemOperationRunner> 44 std::unique_ptr<ArcFileSystemOperationRunner>
27 ArcFileSystemOperationRunner::CreateForTesting( 45 ArcFileSystemOperationRunner::CreateForTesting(
28 ArcBridgeService* bridge_service) { 46 ArcBridgeService* bridge_service) {
29 // We can't use base::MakeUnique() here because we are calling a private 47 // We can't use base::MakeUnique() here because we are calling a private
30 // constructor. 48 // constructor.
31 return base::WrapUnique<ArcFileSystemOperationRunner>( 49 return base::WrapUnique<ArcFileSystemOperationRunner>(
32 new ArcFileSystemOperationRunner(bridge_service, nullptr, false)); 50 new ArcFileSystemOperationRunner(bridge_service, nullptr, false));
33 } 51 }
34 52
35 ArcFileSystemOperationRunner::ArcFileSystemOperationRunner( 53 ArcFileSystemOperationRunner::ArcFileSystemOperationRunner(
36 ArcBridgeService* bridge_service, 54 ArcBridgeService* bridge_service,
37 const Profile* profile) 55 const Profile* profile)
38 : ArcFileSystemOperationRunner(bridge_service, profile, true) { 56 : ArcFileSystemOperationRunner(bridge_service, profile, true) {
39 DCHECK(profile); 57 DCHECK(profile);
40 } 58 }
41 59
42 ArcFileSystemOperationRunner::ArcFileSystemOperationRunner( 60 ArcFileSystemOperationRunner::ArcFileSystemOperationRunner(
43 ArcBridgeService* bridge_service, 61 ArcBridgeService* bridge_service,
44 const Profile* profile, 62 const Profile* profile,
45 bool observe_events) 63 bool set_should_defer_by_events)
46 : ArcService(bridge_service), 64 : ArcService(bridge_service),
47 profile_(profile), 65 profile_(profile),
48 observe_events_(observe_events), 66 set_should_defer_by_events_(set_should_defer_by_events),
67 binding_(this),
49 weak_ptr_factory_(this) { 68 weak_ptr_factory_(this) {
50 DCHECK_CURRENTLY_ON(BrowserThread::UI); 69 DCHECK_CURRENTLY_ON(BrowserThread::UI);
51 70
52 if (observe_events_) { 71 // We need to observe FileSystemInstance even in unit tests to call Init().
53 ArcSessionManager::Get()->AddObserver(this); 72 arc_bridge_service()->file_system()->AddObserver(this);
54 arc_bridge_service()->file_system()->AddObserver(this); 73
55 OnStateChanged(); 74 // ArcSessionManager may not exist in unit tests.
dcheng 2017/02/28 06:56:32 Nit: in many other parts of Chrome, null for testi
Shuhei Takahashi 2017/03/01 09:10:08 I totally agree checking null is not good, but we
56 } 75 auto* arc_session_manager = ArcSessionManager::Get();
76 if (arc_session_manager)
77 arc_session_manager->AddObserver(this);
78
79 OnStateChanged();
57 } 80 }
58 81
59 ArcFileSystemOperationRunner::~ArcFileSystemOperationRunner() { 82 ArcFileSystemOperationRunner::~ArcFileSystemOperationRunner() {
60 DCHECK_CURRENTLY_ON(BrowserThread::UI); 83 DCHECK_CURRENTLY_ON(BrowserThread::UI);
61 84
62 if (observe_events_) { 85 auto* arc_session_manager = ArcSessionManager::Get();
63 ArcSessionManager::Get()->RemoveObserver(this); 86 if (arc_session_manager)
64 arc_bridge_service()->file_system()->RemoveObserver(this); 87 arc_session_manager->AddObserver(this);
dcheng 2017/02/28 06:56:32 RemoveObserver?
Shuhei Takahashi 2017/03/01 09:10:08 Oops! Thanks for catching.
65 } 88
89 arc_bridge_service()->file_system()->RemoveObserver(this);
66 // On destruction, deferred operations are discarded. 90 // On destruction, deferred operations are discarded.
67 } 91 }
68 92
69 void ArcFileSystemOperationRunner::GetFileSize( 93 void ArcFileSystemOperationRunner::GetFileSize(
70 const GURL& url, 94 const GURL& url,
71 const GetFileSizeCallback& callback) { 95 const GetFileSizeCallback& callback) {
72 DCHECK_CURRENTLY_ON(BrowserThread::UI); 96 DCHECK_CURRENTLY_ON(BrowserThread::UI);
73 if (should_defer_) { 97 if (should_defer_) {
74 deferred_operations_.emplace_back( 98 deferred_operations_.emplace_back(
75 base::Bind(&ArcFileSystemOperationRunner::GetFileSize, 99 base::Bind(&ArcFileSystemOperationRunner::GetFileSize,
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 arc_bridge_service()->file_system(), GetChildDocuments); 167 arc_bridge_service()->file_system(), GetChildDocuments);
144 if (!file_system_instance) { 168 if (!file_system_instance) {
145 base::ThreadTaskRunnerHandle::Get()->PostTask( 169 base::ThreadTaskRunnerHandle::Get()->PostTask(
146 FROM_HERE, base::Bind(callback, base::nullopt)); 170 FROM_HERE, base::Bind(callback, base::nullopt));
147 return; 171 return;
148 } 172 }
149 file_system_instance->GetChildDocuments(authority, parent_document_id, 173 file_system_instance->GetChildDocuments(authority, parent_document_id,
150 callback); 174 callback);
151 } 175 }
152 176
177 void ArcFileSystemOperationRunner::AddWatcher(
178 const std::string& authority,
179 const std::string& document_id,
180 const WatcherCallback& watcher_callback,
181 const AddWatcherCallback& callback) {
182 DCHECK_CURRENTLY_ON(BrowserThread::UI);
183 if (should_defer_) {
184 deferred_operations_.emplace_back(
185 base::Bind(&ArcFileSystemOperationRunner::AddWatcher,
186 weak_ptr_factory_.GetWeakPtr(), authority, document_id,
187 watcher_callback, callback));
188 return;
189 }
190 auto* file_system_instance = ARC_GET_INSTANCE_FOR_METHOD(
191 arc_bridge_service()->file_system(), AddWatcher);
192 if (!file_system_instance) {
193 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
194 base::Bind(callback, -1));
195 return;
196 }
197 file_system_instance->AddWatcher(
198 authority, document_id,
199 base::Bind(&ArcFileSystemOperationRunner::OnWatcherAdded,
200 weak_ptr_factory_.GetWeakPtr(), watcher_callback, callback));
201 }
202
203 void ArcFileSystemOperationRunner::RemoveWatcher(
204 int64_t watcher_id,
205 const RemoveWatcherCallback& callback) {
206 DCHECK_CURRENTLY_ON(BrowserThread::UI);
207 // RemoveWatcher() is never deferred since watchers do not persist across
208 // container reboots.
209 if (should_defer_) {
210 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
211 base::Bind(callback, false));
212 return;
213 }
214
215 // Unregister from |watcher_callbacks_| now because we will do it even if
216 // the remote method fails anyway. This is an implementation detail, so
217 // users must not assume registered callbacks are immediately invalidated.
218 auto iter = watcher_callbacks_.find(watcher_id);
219 if (iter == watcher_callbacks_.end()) {
220 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
221 base::Bind(callback, false));
222 return;
223 }
224 watcher_callbacks_.erase(iter);
225
226 auto* file_system_instance = ARC_GET_INSTANCE_FOR_METHOD(
227 arc_bridge_service()->file_system(), AddWatcher);
228 if (!file_system_instance) {
229 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
230 base::Bind(callback, false));
231 return;
232 }
233 file_system_instance->RemoveWatcher(watcher_id, callback);
234 }
235
236 void ArcFileSystemOperationRunner::OnDocumentChanged(int64_t watcher_id,
237 mojom::ChangeType type) {
238 DCHECK_CURRENTLY_ON(BrowserThread::UI);
239 auto iter = watcher_callbacks_.find(watcher_id);
240 if (iter == watcher_callbacks_.end()) {
241 // This may happen in a race condition with documents changes and
242 // RemoveWatcher().
243 return;
244 }
245 WatcherCallback watcher_callback = iter->second;
246 if (type == mojom::ChangeType::DELETED)
247 watcher_callbacks_.erase(watcher_id);
248 watcher_callback.Run(FromMojoChangeType(type));
249 }
250
153 void ArcFileSystemOperationRunner::OnArcPlayStoreEnabledChanged(bool enabled) { 251 void ArcFileSystemOperationRunner::OnArcPlayStoreEnabledChanged(bool enabled) {
154 DCHECK_CURRENTLY_ON(BrowserThread::UI); 252 DCHECK_CURRENTLY_ON(BrowserThread::UI);
155 OnStateChanged(); 253 OnStateChanged();
156 } 254 }
157 255
158 void ArcFileSystemOperationRunner::OnInstanceReady() { 256 void ArcFileSystemOperationRunner::OnInstanceReady() {
159 DCHECK_CURRENTLY_ON(BrowserThread::UI); 257 DCHECK_CURRENTLY_ON(BrowserThread::UI);
258 auto* file_system_instance =
259 ARC_GET_INSTANCE_FOR_METHOD(arc_bridge_service()->file_system(), Init);
260 if (file_system_instance)
261 file_system_instance->Init(binding_.CreateInterfacePtrAndBind());
160 OnStateChanged(); 262 OnStateChanged();
161 } 263 }
162 264
163 void ArcFileSystemOperationRunner::OnInstanceClosed() { 265 void ArcFileSystemOperationRunner::OnInstanceClosed() {
164 DCHECK_CURRENTLY_ON(BrowserThread::UI); 266 DCHECK_CURRENTLY_ON(BrowserThread::UI);
165 OnStateChanged(); 267 OnStateChanged();
166 } 268 }
167 269
270 void ArcFileSystemOperationRunner::OnWatcherAdded(
271 const WatcherCallback& watcher_callback,
272 const AddWatcherCallback& callback,
273 int64_t watcher_id) {
274 DCHECK_CURRENTLY_ON(BrowserThread::UI);
275 if (watcher_id < 0) {
276 callback.Run(-1);
277 return;
278 }
279 DCHECK_EQ(0u, watcher_callbacks_.count(watcher_id));
dcheng 2017/02/28 06:56:32 As this is coming from a less-trusted container, w
Shuhei Takahashi 2017/03/01 09:10:08 Makes sense, done.
280 watcher_callbacks_.insert(std::make_pair(watcher_id, watcher_callback));
281 callback.Run(watcher_id);
282 }
283
168 void ArcFileSystemOperationRunner::OnStateChanged() { 284 void ArcFileSystemOperationRunner::OnStateChanged() {
169 DCHECK_CURRENTLY_ON(BrowserThread::UI); 285 DCHECK_CURRENTLY_ON(BrowserThread::UI);
170 SetShouldDefer(IsArcPlayStoreEnabledForProfile(profile_) && 286 if (set_should_defer_by_events_) {
171 !arc_bridge_service()->file_system()->has_instance()); 287 SetShouldDefer(IsArcPlayStoreEnabledForProfile(profile_) &&
288 !arc_bridge_service()->file_system()->has_instance());
289 }
172 } 290 }
173 291
174 void ArcFileSystemOperationRunner::SetShouldDefer(bool should_defer) { 292 void ArcFileSystemOperationRunner::SetShouldDefer(bool should_defer) {
175 DCHECK_CURRENTLY_ON(BrowserThread::UI); 293 DCHECK_CURRENTLY_ON(BrowserThread::UI);
176 294
177 should_defer_ = should_defer; 295 should_defer_ = should_defer;
178 296
179 if (should_defer_) 297 if (should_defer_)
180 return; 298 return;
181 299
182 // Run deferred operations. 300 // Run deferred operations.
183 std::vector<base::Closure> deferred_operations; 301 std::vector<base::Closure> deferred_operations;
184 deferred_operations.swap(deferred_operations_); 302 deferred_operations.swap(deferred_operations_);
185 for (const base::Closure& operation : deferred_operations) { 303 for (const base::Closure& operation : deferred_operations) {
186 operation.Run(); 304 operation.Run();
187 } 305 }
188 306
189 // No deferred operations should be left at this point. 307 // No deferred operations should be left at this point.
190 DCHECK(deferred_operations_.empty()); 308 DCHECK(deferred_operations_.empty());
191 } 309 }
192 310
193 } // namespace arc 311 } // namespace arc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698