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

Side by Side Diff: ppapi/proxy/ppb_file_ref_proxy.cc

Issue 12817009: Add Query() support to FileRef (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 7 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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "ppapi/proxy/ppb_file_ref_proxy.h" 5 #include "ppapi/proxy/ppb_file_ref_proxy.h"
6 6
7 #include <map> 7 #include <map>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/debug/stack_trace.h"
dmichael (off chromium) 2013/03/18 23:16:16 ^^ leftover from debugging
10 #include "ppapi/c/pp_errors.h" 11 #include "ppapi/c/pp_errors.h"
11 #include "ppapi/c/ppb_file_ref.h" 12 #include "ppapi/c/ppb_file_ref.h"
12 #include "ppapi/c/private/ppb_file_ref_private.h" 13 #include "ppapi/c/private/ppb_file_ref_private.h"
13 #include "ppapi/c/private/ppb_proxy_private.h" 14 #include "ppapi/c/private/ppb_proxy_private.h"
14 #include "ppapi/proxy/enter_proxy.h" 15 #include "ppapi/proxy/enter_proxy.h"
15 #include "ppapi/proxy/host_dispatcher.h" 16 #include "ppapi/proxy/host_dispatcher.h"
16 #include "ppapi/proxy/plugin_dispatcher.h" 17 #include "ppapi/proxy/plugin_dispatcher.h"
17 #include "ppapi/proxy/ppapi_messages.h" 18 #include "ppapi/proxy/ppapi_messages.h"
18 #include "ppapi/proxy/serialized_var.h" 19 #include "ppapi/proxy/serialized_var.h"
19 #include "ppapi/shared_impl/ppb_file_ref_shared.h" 20 #include "ppapi/shared_impl/ppb_file_ref_shared.h"
(...skipping 20 matching lines...) Expand all
40 virtual PP_Resource GetParent() OVERRIDE; 41 virtual PP_Resource GetParent() OVERRIDE;
41 virtual int32_t MakeDirectory( 42 virtual int32_t MakeDirectory(
42 PP_Bool make_ancestors, 43 PP_Bool make_ancestors,
43 scoped_refptr<TrackedCallback> callback) OVERRIDE; 44 scoped_refptr<TrackedCallback> callback) OVERRIDE;
44 virtual int32_t Touch(PP_Time last_access_time, 45 virtual int32_t Touch(PP_Time last_access_time,
45 PP_Time last_modified_time, 46 PP_Time last_modified_time,
46 scoped_refptr<TrackedCallback> callback) OVERRIDE; 47 scoped_refptr<TrackedCallback> callback) OVERRIDE;
47 virtual int32_t Delete(scoped_refptr<TrackedCallback> callback) OVERRIDE; 48 virtual int32_t Delete(scoped_refptr<TrackedCallback> callback) OVERRIDE;
48 virtual int32_t Rename(PP_Resource new_file_ref, 49 virtual int32_t Rename(PP_Resource new_file_ref,
49 scoped_refptr<TrackedCallback> callback) OVERRIDE; 50 scoped_refptr<TrackedCallback> callback) OVERRIDE;
51 virtual int32_t Query(PP_FileInfo *info,
52 scoped_refptr<TrackedCallback> callback) OVERRIDE;
50 virtual PP_Var GetAbsolutePath() OVERRIDE; 53 virtual PP_Var GetAbsolutePath() OVERRIDE;
51 54
52 // Executes the pending callback with the given ID. See pending_callbacks_. 55 // Executes the pending callback with the given ID. See pending_callbacks_.
53 void ExecuteCallback(int callback_id, int32_t result); 56 void ExecuteCallback(int callback_id, int32_t result);
57 void SetFileInfo(int callback_id, const PP_FileInfo &info);
54 58
55 private: 59 private:
56 PluginDispatcher* GetDispatcher() const { 60 PluginDispatcher* GetDispatcher() const {
57 return PluginDispatcher::GetForResource(this); 61 return PluginDispatcher::GetForResource(this);
58 } 62 }
59 63
60 // Adds a callback to the list and returns its ID. 64 // Adds a callback to the list and returns its ID.
61 int SendCallback(scoped_refptr<TrackedCallback> callback); 65 int SendCallback(scoped_refptr<TrackedCallback> callback);
62 66
63 // This class can have any number of out-standing requests with completion 67 // This class can have any number of out-standing requests with completion
64 // callbacks, in contrast to most resources which have one possible pending 68 // callbacks, in contrast to most resources which have one possible pending
65 // callback pending (like a Flush callback). 69 // callback pending (like a Flush callback).
66 // 70 //
67 // To keep track of them, assign integer IDs to the callbacks, which is how 71 // To keep track of them, assign integer IDs to the callbacks, which is how
68 // the callback will be identified when it's passed to the host and then 72 // the callback will be identified when it's passed to the host and then
69 // back here. Use unsigned so that overflow is well-defined. 73 // back here. Use unsigned so that overflow is well-defined.
70 unsigned int next_callback_id_; 74 unsigned int next_callback_id_;
71 typedef std::map<unsigned int, 75 typedef std::map<unsigned int,
72 scoped_refptr<TrackedCallback> > PendingCallbackMap; 76 scoped_refptr<TrackedCallback> > PendingCallbackMap;
73 PendingCallbackMap pending_callbacks_; 77 PendingCallbackMap pending_callbacks_;
74 78
79 // Used to keep pointers to PP_FileInfo instances that are written before
80 // callbacks are invoked. The id of a pending file info will match that of
81 // the corresponding callback.
82 typedef std::map<unsigned int, PP_FileInfo*> PendingFileInfoMap;
dmichael (off chromium) 2013/03/18 23:16:16 It looks like you're using |int| instead of |unsig
teravest 2013/03/21 16:45:04 This is a little gross. PpapiMsg_PPBFileRef_Callba
dmichael (off chromium) 2013/03/21 22:11:29 Hmm, I guess you aren't making it worse, so you co
83 PendingFileInfoMap pending_file_infos_;
84
75 DISALLOW_IMPLICIT_CONSTRUCTORS(FileRef); 85 DISALLOW_IMPLICIT_CONSTRUCTORS(FileRef);
76 }; 86 };
77 87
78 FileRef::FileRef(const PPB_FileRef_CreateInfo& info) 88 FileRef::FileRef(const PPB_FileRef_CreateInfo& info)
79 : PPB_FileRef_Shared(OBJECT_IS_PROXY, info), 89 : PPB_FileRef_Shared(OBJECT_IS_PROXY, info),
80 next_callback_id_(0u) { 90 next_callback_id_(0u) {
81 } 91 }
82 92
83 FileRef::~FileRef() { 93 FileRef::~FileRef() {
84 // The callbacks map should have been cleared by LastPluginRefWasDeleted. 94 // The callbacks map should have been cleared by LastPluginRefWasDeleted.
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
127 if (!new_file_ref_object || 137 if (!new_file_ref_object ||
128 new_file_ref_object->host_resource().instance() != pp_instance()) 138 new_file_ref_object->host_resource().instance() != pp_instance())
129 return PP_ERROR_BADRESOURCE; 139 return PP_ERROR_BADRESOURCE;
130 140
131 GetDispatcher()->Send(new PpapiHostMsg_PPBFileRef_Rename( 141 GetDispatcher()->Send(new PpapiHostMsg_PPBFileRef_Rename(
132 API_ID_PPB_FILE_REF, host_resource(), 142 API_ID_PPB_FILE_REF, host_resource(),
133 new_file_ref_object->host_resource(), SendCallback(callback))); 143 new_file_ref_object->host_resource(), SendCallback(callback)));
134 return PP_OK_COMPLETIONPENDING; 144 return PP_OK_COMPLETIONPENDING;
135 } 145 }
136 146
147 int32_t FileRef::Query(PP_FileInfo* info,
148 scoped_refptr<TrackedCallback> callback) {
149 // Store the pending file info id.
150 int id = SendCallback(callback);
151 pending_file_infos_[id] = info;
152 GetDispatcher()->Send(new PpapiHostMsg_PPBFileRef_Query(
153 API_ID_PPB_FILE_REF, host_resource(), id));
154 return PP_OK_COMPLETIONPENDING;
155 }
156
137 PP_Var FileRef::GetAbsolutePath() { 157 PP_Var FileRef::GetAbsolutePath() {
138 ReceiveSerializedVarReturnValue result; 158 ReceiveSerializedVarReturnValue result;
139 GetDispatcher()->Send(new PpapiHostMsg_PPBFileRef_GetAbsolutePath( 159 GetDispatcher()->Send(new PpapiHostMsg_PPBFileRef_GetAbsolutePath(
140 API_ID_PPB_FILE_REF, host_resource(), &result)); 160 API_ID_PPB_FILE_REF, host_resource(), &result));
141 return result.Return(GetDispatcher()); 161 return result.Return(GetDispatcher());
142 } 162 }
143 163
144 void FileRef::ExecuteCallback(int callback_id, int32_t result) { 164 void FileRef::ExecuteCallback(int callback_id, int32_t result) {
145 PendingCallbackMap::iterator found = pending_callbacks_.find(callback_id); 165 PendingCallbackMap::iterator found = pending_callbacks_.find(callback_id);
146 if (found == pending_callbacks_.end()) { 166 if (found == pending_callbacks_.end()) {
147 // This will happen when the plugin deletes its resource with a pending 167 // This will happen when the plugin deletes its resource with a pending
148 // callback. The callback will be locally issued with an ABORTED call while 168 // callback. The callback will be locally issued with an ABORTED call while
149 // the operation may still be pending in the renderer. 169 // the operation may still be pending in the renderer.
150 return; 170 return;
151 } 171 }
152 172
153 // Executing the callback may mutate the callback list. 173 // Executing the callback may mutate the callback list.
154 scoped_refptr<TrackedCallback> callback = found->second; 174 scoped_refptr<TrackedCallback> callback = found->second;
155 pending_callbacks_.erase(found); 175 pending_callbacks_.erase(found);
156 callback->Run(result); 176 callback->Run(result);
157 } 177 }
158 178
179 void FileRef::SetFileInfo(int callback_id, const PP_FileInfo &info) {
180 PendingFileInfoMap::iterator found = pending_file_infos_.find(callback_id);
181 if (found == pending_file_infos_.end())
182 return;
183 PP_FileInfo *target_info = found->second;
dmichael (off chromium) 2013/03/18 23:16:16 nit: '*' should be with PP_FileInfo
teravest 2013/03/21 16:45:04 Done.
184 *target_info = info;
185 pending_file_infos_.erase(found);
186 }
187
159 int FileRef::SendCallback(scoped_refptr<TrackedCallback> callback) { 188 int FileRef::SendCallback(scoped_refptr<TrackedCallback> callback) {
160 // In extreme cases the IDs may wrap around, so avoid duplicates. 189 // In extreme cases the IDs may wrap around, so avoid duplicates.
161 while (pending_callbacks_.count(next_callback_id_)) 190 while (pending_callbacks_.count(next_callback_id_))
162 ++next_callback_id_; 191 ++next_callback_id_;
163 192
164 pending_callbacks_[next_callback_id_] = callback; 193 pending_callbacks_[next_callback_id_] = callback;
165 return next_callback_id_++; 194 return next_callback_id_++;
166 } 195 }
167 196
168 PPB_FileRef_Proxy::PPB_FileRef_Proxy(Dispatcher* dispatcher) 197 PPB_FileRef_Proxy::PPB_FileRef_Proxy(Dispatcher* dispatcher)
(...skipping 24 matching lines...) Expand all
193 bool handled = true; 222 bool handled = true;
194 IPC_BEGIN_MESSAGE_MAP(PPB_FileRef_Proxy, msg) 223 IPC_BEGIN_MESSAGE_MAP(PPB_FileRef_Proxy, msg)
195 #if !defined(OS_NACL) 224 #if !defined(OS_NACL)
196 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFileRef_Create, OnMsgCreate) 225 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFileRef_Create, OnMsgCreate)
197 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFileRef_GetParent, OnMsgGetParent) 226 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFileRef_GetParent, OnMsgGetParent)
198 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFileRef_MakeDirectory, 227 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFileRef_MakeDirectory,
199 OnMsgMakeDirectory) 228 OnMsgMakeDirectory)
200 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFileRef_Touch, OnMsgTouch) 229 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFileRef_Touch, OnMsgTouch)
201 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFileRef_Delete, OnMsgDelete) 230 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFileRef_Delete, OnMsgDelete)
202 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFileRef_Rename, OnMsgRename) 231 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFileRef_Rename, OnMsgRename)
232 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFileRef_Query, OnMsgQuery)
203 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFileRef_GetAbsolutePath, 233 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFileRef_GetAbsolutePath,
204 OnMsgGetAbsolutePath) 234 OnMsgGetAbsolutePath)
205 #endif // !defined(OS_NACL) 235 #endif // !defined(OS_NACL)
206 236
207 IPC_MESSAGE_HANDLER(PpapiMsg_PPBFileRef_CallbackComplete, 237 IPC_MESSAGE_HANDLER(PpapiMsg_PPBFileRef_CallbackComplete,
208 OnMsgCallbackComplete) 238 OnMsgCallbackComplete)
239 IPC_MESSAGE_HANDLER(PpapiMsg_PPBFileRef_QueryCallbackComplete,
240 OnMsgQueryCallbackComplete)
209 IPC_MESSAGE_UNHANDLED(handled = false) 241 IPC_MESSAGE_UNHANDLED(handled = false)
210 IPC_END_MESSAGE_MAP() 242 IPC_END_MESSAGE_MAP()
211 return handled; 243 return handled;
212 } 244 }
213 245
214 // static 246 // static
215 void PPB_FileRef_Proxy::SerializeFileRef(PP_Resource file_ref, 247 void PPB_FileRef_Proxy::SerializeFileRef(PP_Resource file_ref,
216 PPB_FileRef_CreateInfo* result) { 248 PPB_FileRef_CreateInfo* result) {
217 EnterResourceNoLock<PPB_FileRef_API> enter(file_ref, false); 249 EnterResourceNoLock<PPB_FileRef_API> enter(file_ref, false);
218 if (enter.succeeded()) 250 if (enter.succeeded())
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
287 int callback_id) { 319 int callback_id) {
288 EnterHostFromHostResourceForceCallback<PPB_FileRef_API> enter( 320 EnterHostFromHostResourceForceCallback<PPB_FileRef_API> enter(
289 file_ref, callback_factory_, 321 file_ref, callback_factory_,
290 &PPB_FileRef_Proxy::OnCallbackCompleteInHost, file_ref, callback_id); 322 &PPB_FileRef_Proxy::OnCallbackCompleteInHost, file_ref, callback_id);
291 if (enter.succeeded()) { 323 if (enter.succeeded()) {
292 enter.SetResult(enter.object()->Rename(new_file_ref.host_resource(), 324 enter.SetResult(enter.object()->Rename(new_file_ref.host_resource(),
293 enter.callback())); 325 enter.callback()));
294 } 326 }
295 } 327 }
296 328
329 void PPB_FileRef_Proxy::OnMsgQuery(const HostResource& file_ref,
330 int callback_id) {
331 PP_FileInfo info;
332 EnterHostFromHostResourceForceCallback<PPB_FileRef_API> enter(
333 file_ref, callback_factory_,
334 &PPB_FileRef_Proxy::OnQueryCallbackCompleteInHost, file_ref, &info,
335 callback_id);
336 if (enter.succeeded())
337 enter.SetResult(enter.object()->Query(&info, enter.callback()));
338 }
339
297 void PPB_FileRef_Proxy::OnMsgGetAbsolutePath(const HostResource& host_resource, 340 void PPB_FileRef_Proxy::OnMsgGetAbsolutePath(const HostResource& host_resource,
298 SerializedVarReturnValue result) { 341 SerializedVarReturnValue result) {
299 EnterHostFromHostResource<PPB_FileRef_API> enter(host_resource); 342 EnterHostFromHostResource<PPB_FileRef_API> enter(host_resource);
300 if (enter.succeeded()) 343 if (enter.succeeded())
301 result.Return(dispatcher(), enter.object()->GetAbsolutePath()); 344 result.Return(dispatcher(), enter.object()->GetAbsolutePath());
302 } 345 }
303 #endif // !defined(OS_NACL) 346 #endif // !defined(OS_NACL)
304 347
305 void PPB_FileRef_Proxy::OnMsgCallbackComplete( 348 void PPB_FileRef_Proxy::OnMsgCallbackComplete(
306 const HostResource& host_resource, 349 const HostResource& host_resource,
307 int callback_id, 350 int callback_id,
308 int32_t result) { 351 int32_t result) {
309 // Forward the callback info to the plugin resource. 352 // Forward the callback info to the plugin resource.
310 EnterPluginFromHostResource<PPB_FileRef_API> enter(host_resource); 353 EnterPluginFromHostResource<PPB_FileRef_API> enter(host_resource);
311 if (enter.succeeded()) 354 if (enter.succeeded())
312 static_cast<FileRef*>(enter.object())->ExecuteCallback(callback_id, result); 355 static_cast<FileRef*>(enter.object())->ExecuteCallback(callback_id, result);
313 } 356 }
314 357
358 void PPB_FileRef_Proxy::OnMsgQueryCallbackComplete(
359 const HostResource& host_resource,
360 PP_FileInfo info,
361 int callback_id,
362 int32_t result) {
363 EnterPluginFromHostResource<PPB_FileRef_API> enter(host_resource);
364 if (enter.succeeded()) {
365 // Set the FileInfo output parameter.
366 static_cast<FileRef*>(enter.object())->SetFileInfo(callback_id, info);
367 static_cast<FileRef*>(enter.object())->ExecuteCallback(callback_id, result);
368 }
369 }
370
315 #if !defined(OS_NACL) 371 #if !defined(OS_NACL)
316 void PPB_FileRef_Proxy::OnCallbackCompleteInHost( 372 void PPB_FileRef_Proxy::OnCallbackCompleteInHost(
317 int32_t result, 373 int32_t result,
318 const HostResource& host_resource, 374 const HostResource& host_resource,
319 int callback_id) { 375 int callback_id) {
320 // Execute OnMsgCallbackComplete in the plugin process. 376 // Execute OnMsgCallbackComplete in the plugin process.
321 Send(new PpapiMsg_PPBFileRef_CallbackComplete( 377 Send(new PpapiMsg_PPBFileRef_CallbackComplete(
322 API_ID_PPB_FILE_REF, host_resource, callback_id, result)); 378 API_ID_PPB_FILE_REF, host_resource, callback_id, result));
323 } 379 }
380
381 void PPB_FileRef_Proxy::OnQueryCallbackCompleteInHost(
382 int32_t result,
383 const HostResource& host_resource,
384 PP_FileInfo* info,
385 int callback_id) {
386 if (result == PP_OK) {
387 Send(new PpapiMsg_PPBFileRef_QueryCallbackComplete(
388 API_ID_PPB_FILE_REF, host_resource, *info, callback_id, result));
389 } else {
390 PP_FileInfo tmp_info;
391 memset(&tmp_info, 0, sizeof(tmp_info));
dmichael (off chromium) 2013/03/18 23:16:16 Shouldn't this just be done in PPB_FileRef_Impl? I
teravest 2013/03/21 16:45:04 I'm special casing it in the proxy because we can'
dmichael (off chromium) 2013/03/21 22:11:29 What if you just implement the host side so that i
392 Send(new PpapiMsg_PPBFileRef_QueryCallbackComplete(
393 API_ID_PPB_FILE_REF, host_resource, tmp_info, callback_id, result));
394 }
395 }
324 #endif // !defined(OS_NACL) 396 #endif // !defined(OS_NACL)
325 397
326 } // namespace proxy 398 } // namespace proxy
327 } // namespace ppapi 399 } // namespace ppapi
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698