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

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

Issue 10169040: Move the rest of the Flash functions to the thunk system. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 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 | Annotate | Revision Log
« no previous file with comments | « ppapi/proxy/ppb_flash_proxy.h ('k') | ppapi/shared_impl/api_id.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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_flash_proxy.h" 5 #include "ppapi/proxy/ppb_flash_proxy.h"
6 6
7 #include <map>
8 #include <set>
9
7 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/memory/ref_counted.h"
8 #include "base/message_loop.h" 12 #include "base/message_loop.h"
13 #include "base/synchronization/lock.h"
9 #include "base/time.h" 14 #include "base/time.h"
15 #include "ipc/ipc_channel_proxy.h"
10 #include "ppapi/c/dev/ppb_font_dev.h" 16 #include "ppapi/c/dev/ppb_font_dev.h"
11 #include "ppapi/c/dev/ppb_var_deprecated.h" 17 #include "ppapi/c/dev/ppb_var_deprecated.h"
12 #include "ppapi/c/pp_errors.h" 18 #include "ppapi/c/pp_errors.h"
13 #include "ppapi/c/pp_resource.h" 19 #include "ppapi/c/pp_resource.h"
14 #include "ppapi/c/private/ppb_flash.h" 20 #include "ppapi/c/private/ppb_flash.h"
15 #include "ppapi/proxy/host_dispatcher.h" 21 #include "ppapi/proxy/host_dispatcher.h"
16 #include "ppapi/proxy/plugin_dispatcher.h" 22 #include "ppapi/proxy/plugin_dispatcher.h"
17 #include "ppapi/proxy/plugin_globals.h" 23 #include "ppapi/proxy/plugin_globals.h"
18 #include "ppapi/proxy/plugin_proxy_delegate.h" 24 #include "ppapi/proxy/plugin_proxy_delegate.h"
19 #include "ppapi/proxy/ppapi_messages.h" 25 #include "ppapi/proxy/ppapi_messages.h"
20 #include "ppapi/proxy/proxy_module.h" 26 #include "ppapi/proxy/proxy_module.h"
21 #include "ppapi/proxy/serialized_var.h" 27 #include "ppapi/proxy/serialized_var.h"
22 #include "ppapi/shared_impl/ppapi_globals.h" 28 #include "ppapi/shared_impl/ppapi_globals.h"
23 #include "ppapi/shared_impl/proxy_lock.h" 29 #include "ppapi/shared_impl/proxy_lock.h"
24 #include "ppapi/shared_impl/resource.h" 30 #include "ppapi/shared_impl/resource.h"
25 #include "ppapi/shared_impl/resource_tracker.h" 31 #include "ppapi/shared_impl/resource_tracker.h"
26 #include "ppapi/shared_impl/scoped_pp_resource.h" 32 #include "ppapi/shared_impl/scoped_pp_resource.h"
27 #include "ppapi/shared_impl/var.h" 33 #include "ppapi/shared_impl/var.h"
28 #include "ppapi/thunk/enter.h" 34 #include "ppapi/thunk/enter.h"
29 #include "ppapi/thunk/ppb_instance_api.h" 35 #include "ppapi/thunk/ppb_instance_api.h"
30 #include "ppapi/thunk/ppb_url_request_info_api.h" 36 #include "ppapi/thunk/ppb_url_request_info_api.h"
31 #include "ppapi/thunk/resource_creation_api.h" 37 #include "ppapi/thunk/resource_creation_api.h"
32 38
33 using ppapi::thunk::EnterInstanceNoLock; 39 using ppapi::thunk::EnterInstanceNoLock;
40 using ppapi::thunk::EnterResourceNoLock;
34 41
35 namespace ppapi { 42 namespace ppapi {
36 namespace proxy { 43 namespace proxy {
37 44
45 namespace {
46
47 IPC::PlatformFileForTransit PlatformFileToPlatformFileForTransit(
48 Dispatcher* dispatcher,
49 int32_t* error,
50 base::PlatformFile file) {
51 if (*error != PP_OK)
52 return IPC::InvalidPlatformFileForTransit();
53 IPC::PlatformFileForTransit out_handle =
54 dispatcher->ShareHandleWithRemote(file, true);
55 if (out_handle == IPC::InvalidPlatformFileForTransit())
56 *error = PP_ERROR_NOACCESS;
57 return out_handle;
58 }
59
60 // ModuleLocalThreadAdapter ----------------------------------------------------
61 // TODO(yzshen): Refactor to use IPC::SyncMessageFilter.
62 class ModuleLocalThreadAdapter
63 : public base::RefCountedThreadSafe<ModuleLocalThreadAdapter> {
64 class Filter;
65 public:
66 ModuleLocalThreadAdapter();
67
68 void AddInstanceRouting(PP_Instance instance, Dispatcher* dispatcher);
69 void ClearInstanceRouting(PP_Instance instance);
70 void ClearFilter(Dispatcher* dispatcher, Filter* filter);
71
72 bool OnModuleLocalMessageReceived(const IPC::Message& msg);
73
74 // Called on the I/O thread when the channel is being destroyed and the
75 // given message will never be issued a reply.
76 void OnModuleLocalMessageFailed(int message_id);
77
78 bool Send(PP_Instance instance, IPC::Message* msg);
79
80 private:
81 class Filter : public IPC::ChannelProxy::MessageFilter {
82 public:
83 explicit Filter(Dispatcher* dispatcher);
84 ~Filter();
85
86 void Send(IPC::Message* msg);
87
88 virtual void OnFilterAdded(IPC::Channel* channel);
89 virtual void OnFilterRemoved();
90 virtual bool OnMessageReceived(const IPC::Message& message);
91
92 private:
93 // DO NOT DEREFERENCE! This is used only for tracking.
94 Dispatcher* dispatcher_;
95
96 IPC::Channel* channel_;
97
98 // Holds the IPC messages that were sent before the channel was connected.
99 // These will be sent ASAP.
100 std::vector<IPC::Message*> pre_connect_pending_messages_;
101
102 // Holds the IDs of the sync messages we're currently waiting on for this
103 // channel. This tracking allows us to cancel those requests if the
104 // remote process crashes and we're cleaning up this filter (without just
105 // deadlocking the waiting thread(s).
106 std::set<int> pending_requests_for_filter_;
107 };
108
109 void SendFromIOThread(Dispatcher* dispatcher, IPC::Message* msg);
110
111 // Internal version of OnModuleLocalMessageFailed which assumes the lock
112 // is already held.
113 void OnModuleLocalMessageFailedLocked(int message_id);
114
115 base::Lock lock_;
116
117 scoped_refptr<base::MessageLoopProxy> main_thread_;
118
119 // Will be NULL before an instance routing is added.
120 scoped_refptr<base::MessageLoopProxy> io_thread_;
121
122 typedef std::map<PP_Instance, Dispatcher*> InstanceToDispatcher;
123 InstanceToDispatcher instance_to_dispatcher_;
124
125 // The filters are owned by the channel.
126 typedef std::map<Dispatcher*, Filter*> DispatcherToFilter;
127 DispatcherToFilter dispatcher_to_filter_;
128
129 // Tracks all messages with currently waiting threads. This does not own
130 // the pointer, the pointer lifetime is managed by Send().
131 typedef std::map<int, IPC::PendingSyncMsg*> SyncRequestMap;
132 SyncRequestMap pending_sync_requests_;
133 };
134
135 ModuleLocalThreadAdapter* g_module_local_thread_adapter = NULL;
136
137 ModuleLocalThreadAdapter::Filter::Filter(Dispatcher* dispatcher)
138 : dispatcher_(dispatcher), channel_(NULL) {
139 }
140
141 ModuleLocalThreadAdapter::Filter::~Filter() {
142 }
143
144 void ModuleLocalThreadAdapter::Filter::Send(IPC::Message* msg) {
145 if (channel_) {
146 int message_id = IPC::SyncMessage::GetMessageId(*msg);
147 if (channel_->Send(msg))
148 pending_requests_for_filter_.insert(message_id);
149 else // Message lost, notify adapter so it can unblock.
150 g_module_local_thread_adapter->OnModuleLocalMessageFailed(message_id);
151 } else {
152 // No channel, save this message for when it's connected.
153 pre_connect_pending_messages_.push_back(msg);
154 }
155 }
156
157 void ModuleLocalThreadAdapter::Filter::OnFilterAdded(IPC::Channel* channel) {
158 DCHECK(!channel_);
159 channel_ = channel;
160
161 // Now that we have a channel, process all pending messages.
162 for (size_t i = 0; i < pre_connect_pending_messages_.size(); i++)
163 Send(pre_connect_pending_messages_[i]);
164 pre_connect_pending_messages_.clear();
165 }
166
167 void ModuleLocalThreadAdapter::Filter::OnFilterRemoved() {
168 DCHECK(channel_);
169 channel_ = NULL;
170 g_module_local_thread_adapter->ClearFilter(dispatcher_, this);
171
172 for (std::set<int>::iterator i = pending_requests_for_filter_.begin();
173 i != pending_requests_for_filter_.end(); ++i) {
174 g_module_local_thread_adapter->OnModuleLocalMessageFailed(*i);
175 }
176 }
177
178 bool ModuleLocalThreadAdapter::Filter::OnMessageReceived(
179 const IPC::Message& message) {
180 if (!message.is_reply() ||
181 message.routing_id() != API_ID_PPB_FLASH)
182 return false;
183
184 if (g_module_local_thread_adapter->OnModuleLocalMessageReceived(message)) {
185 // The message was consumed, this means we can remove the message ID from
186 // the list of messages this channel is waiting on.
187 pending_requests_for_filter_.erase(IPC::SyncMessage::GetMessageId(message));
188 return true;
189 }
190 return false;
191 }
192
193 ModuleLocalThreadAdapter::ModuleLocalThreadAdapter()
194 : main_thread_(base::MessageLoopProxy::current()) {
195 }
196
197 void ModuleLocalThreadAdapter::AddInstanceRouting(PP_Instance instance,
198 Dispatcher* dispatcher) {
199 base::AutoLock lock(lock_);
200
201 // Now that we've had contact with a dispatcher, we can set up the IO thread.
202 DCHECK(main_thread_->BelongsToCurrentThread());
203 if (!io_thread_.get())
204 io_thread_ = dispatcher->GetIPCMessageLoop();
205
206 // Set up the instance -> dispatcher routing.
207 DCHECK(instance_to_dispatcher_.find(instance) ==
208 instance_to_dispatcher_.end());
209 instance_to_dispatcher_[instance] = dispatcher;
210
211 DispatcherToFilter::iterator found_filter =
212 dispatcher_to_filter_.find(dispatcher);
213 if (found_filter == dispatcher_to_filter_.end()) {
214 // Need to set up a filter for this dispatcher to intercept the messages.
215 Filter* filter = new Filter(dispatcher);
216 dispatcher_to_filter_[dispatcher] = filter;
217 dispatcher->AddIOThreadMessageFilter(filter);
218 }
219 }
220
221 void ModuleLocalThreadAdapter::ClearInstanceRouting(PP_Instance instance) {
222 // The dispatcher->filter mapping is cleaned up by ClearFilter which is
223 // initiated by the channel.
224 instance_to_dispatcher_.erase(instance);
225 }
226
227 void ModuleLocalThreadAdapter::ClearFilter(Dispatcher* dispatcher,
228 Filter* filter) {
229 // DANGER! Don't dereference the dispatcher, it's just used to identify
230 // which filter to remove. The dispatcher may not even exist any more.
231 //
232 // Since the dispatcher may be gone, there's a potential for ambiguity if
233 // another one is created on the main thread before this code runs on the
234 // I/O thread. So we check that the filter matches to avoid this rare case.
235 base::AutoLock lock(lock_);
236 if (dispatcher_to_filter_[dispatcher] == filter)
237 dispatcher_to_filter_.erase(dispatcher);
238 }
239
240 bool ModuleLocalThreadAdapter::OnModuleLocalMessageReceived(
241 const IPC::Message& msg) {
242 base::AutoLock lock(lock_);
243
244 int message_id = IPC::SyncMessage::GetMessageId(msg);
245 SyncRequestMap::iterator found = pending_sync_requests_.find(message_id);
246 if (found == pending_sync_requests_.end()) {
247 // Not waiting for this event. This will happen for sync messages to the
248 // main thread which use the "regular" sync channel code path.
249 return false;
250 }
251
252 IPC::PendingSyncMsg& info = *found->second;
253
254 if (!msg.is_reply_error())
255 info.deserializer->SerializeOutputParameters(msg);
256 info.done_event->Signal();
257 return true;
258 }
259
260 void ModuleLocalThreadAdapter::OnModuleLocalMessageFailed(int message_id) {
261 base::AutoLock lock(lock_);
262 OnModuleLocalMessageFailedLocked(message_id);
263 }
264
265 bool ModuleLocalThreadAdapter::Send(PP_Instance instance, IPC::Message* msg) {
266 // Compute the dispatcher corresponding to this message.
267 Dispatcher* dispatcher = NULL;
268 {
269 base::AutoLock lock(lock_);
270 InstanceToDispatcher::iterator found =
271 instance_to_dispatcher_.find(instance);
272 if (found == instance_to_dispatcher_.end()) {
273 NOTREACHED();
274 delete msg;
275 return false;
276 }
277 dispatcher = found->second;
278 }
279
280 if (main_thread_->BelongsToCurrentThread()) {
281 // Easy case: We're on the same thread as the dispatcher, so we don't need
282 // a lock to access it, and we can just use the normal sync channel stuff
283 // to handle the message. Actually, we MUST use the normal sync channel
284 // stuff since there may be incoming sync messages that need processing.
285 // The code below doesn't handle any nested message loops.
286 return dispatcher->Send(msg);
287 }
288
289 // Background thread case
290 // ----------------------
291 // 1. Generate tracking info, stick in pending_sync_messages_map.
292 // 2. Kick off the request. This is done on the I/O thread.
293 // 3. Filter on the I/O thread notices reply, writes the reply data and
294 // signals the event. We block on the event while this is happening.
295 // 4. Remove tracking info.
296
297 // Generate the tracking info. and copied
298 IPC::SyncMessage* sync_msg = static_cast<IPC::SyncMessage*>(msg);
299 int message_id = IPC::SyncMessage::GetMessageId(*sync_msg);
300 base::WaitableEvent event(true, false);
301 scoped_ptr<IPC::MessageReplyDeserializer> deserializer(
302 sync_msg->GetReplyDeserializer()); // We own this pointer once retrieved.
303 IPC::PendingSyncMsg info(message_id, deserializer.get(), &event);
304
305 // Add the tracking information to our map.
306 {
307 base::AutoLock lock(lock_);
308 pending_sync_requests_[message_id] = &info;
309 }
310
311 // This is a bit dangerous. We use the dispatcher pointer as the routing
312 // ID for this message. While we don't dereference it, there is an
313 // exceedingly remote possibility that while this is going to the background
314 // thread the connection will be shut down and a new one will be created with
315 // a dispatcher at the same address. It could potentially get sent to a
316 // random place, but it should actually still work (since the Flash file
317 // operations are global).
318 io_thread_->PostTask(FROM_HERE,
319 base::Bind(&ModuleLocalThreadAdapter::SendFromIOThread, this,
320 dispatcher, msg));
321
322 // Now we block the current thread waiting for the reply.
323 event.Wait();
324
325 {
326 // Clear our tracking info for this message now that we're done.
327 base::AutoLock lock(lock_);
328 DCHECK(pending_sync_requests_.find(message_id) !=
329 pending_sync_requests_.end());
330 pending_sync_requests_.erase(message_id);
331 }
332
333 return true;
334 }
335
336 void ModuleLocalThreadAdapter::SendFromIOThread(Dispatcher* dispatcher,
337 IPC::Message* msg) {
338 // DO NOT DEREFERENCE DISPATCHER. Used as a lookup only.
339 base::AutoLock lock(lock_);
340 DispatcherToFilter::iterator found = dispatcher_to_filter_.find(dispatcher);
341
342 // The dispatcher could have been destroyed by the time we got here since
343 // we're on another thread. Need to unblock the caller.
344 if (found == dispatcher_to_filter_.end()) {
345 OnModuleLocalMessageFailedLocked(IPC::SyncMessage::GetMessageId(*msg));
346 delete msg;
347 return;
348 }
349
350 // Takes ownership of pointer.
351 found->second->Send(msg);
352 }
353
354 void ModuleLocalThreadAdapter::OnModuleLocalMessageFailedLocked(
355 int message_id) {
356 lock_.AssertAcquired();
357
358 // Unblock the thread waiting for the message that will never come.
359 SyncRequestMap::iterator found = pending_sync_requests_.find(message_id);
360 if (found == pending_sync_requests_.end()) {
361 NOTREACHED();
362 return;
363 }
364 found->second->done_event->Signal();
365 }
366
367 } // namespace
368
369 // -----------------------------------------------------------------------------
370
38 PPB_Flash_Proxy::PPB_Flash_Proxy(Dispatcher* dispatcher) 371 PPB_Flash_Proxy::PPB_Flash_Proxy(Dispatcher* dispatcher)
39 : InterfaceProxy(dispatcher) { 372 : InterfaceProxy(dispatcher) {
40 } 373 }
41 374
42 PPB_Flash_Proxy::~PPB_Flash_Proxy() { 375 PPB_Flash_Proxy::~PPB_Flash_Proxy() {
43 } 376 }
44 377
45 bool PPB_Flash_Proxy::OnMessageReceived(const IPC::Message& msg) { 378 bool PPB_Flash_Proxy::OnMessageReceived(const IPC::Message& msg) {
46 // Prevent the dispatcher from going away during a call to Navigate. 379 // Prevent the dispatcher from going away during a call to Navigate.
47 // This must happen OUTSIDE of OnMsgNavigate since the handling code use 380 // This must happen OUTSIDE of OnMsgNavigate since the handling code use
(...skipping 20 matching lines...) Expand all
68 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlash_FlashSetFullscreen, 401 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlash_FlashSetFullscreen,
69 OnHostMsgFlashSetFullscreen) 402 OnHostMsgFlashSetFullscreen)
70 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlash_FlashGetScreenSize, 403 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlash_FlashGetScreenSize,
71 OnHostMsgFlashGetScreenSize) 404 OnHostMsgFlashGetScreenSize)
72 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlash_IsClipboardFormatAvailable, 405 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlash_IsClipboardFormatAvailable,
73 OnHostMsgIsClipboardFormatAvailable) 406 OnHostMsgIsClipboardFormatAvailable)
74 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlash_ReadClipboardData, 407 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlash_ReadClipboardData,
75 OnHostMsgReadClipboardData) 408 OnHostMsgReadClipboardData)
76 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlash_WriteClipboardData, 409 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlash_WriteClipboardData,
77 OnHostMsgWriteClipboardData) 410 OnHostMsgWriteClipboardData)
411 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlash_OpenFile,
412 OnHostMsgOpenFile)
413 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlash_RenameFile,
414 OnHostMsgRenameFile)
415 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlash_DeleteFileOrDir,
416 OnHostMsgDeleteFileOrDir)
417 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlash_CreateDir,
418 OnHostMsgCreateDir)
419 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlash_QueryFile,
420 OnHostMsgQueryFile)
421 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlash_GetDirContents,
422 OnHostMsgGetDirContents)
423 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlash_OpenFileRef,
424 OnHostMsgOpenFileRef)
425 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlash_QueryFileRef,
426 OnHostMsgQueryFileRef)
78 IPC_MESSAGE_UNHANDLED(handled = false) 427 IPC_MESSAGE_UNHANDLED(handled = false)
79 IPC_END_MESSAGE_MAP() 428 IPC_END_MESSAGE_MAP()
80 // TODO(brettw) handle bad messages! 429 // TODO(brettw) handle bad messages!
81 return handled; 430 return handled;
82 } 431 }
83 432
84 void PPB_Flash_Proxy::SetInstanceAlwaysOnTop(PP_Instance instance, 433 void PPB_Flash_Proxy::SetInstanceAlwaysOnTop(PP_Instance instance,
85 PP_Bool on_top) { 434 PP_Bool on_top) {
86 dispatcher()->Send(new PpapiHostMsg_PPBFlash_SetInstanceAlwaysOnTop( 435 dispatcher()->Send(new PpapiHostMsg_PPBFlash_SetInstanceAlwaysOnTop(
87 API_ID_PPB_FLASH, instance, on_top)); 436 API_ID_PPB_FLASH, instance, on_top));
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
261 dispatcher()->Send(new PpapiHostMsg_PPBFlash_WriteClipboardData( 610 dispatcher()->Send(new PpapiHostMsg_PPBFlash_WriteClipboardData(
262 API_ID_PPB_FLASH, 611 API_ID_PPB_FLASH,
263 instance, 612 instance,
264 static_cast<int>(clipboard_type), 613 static_cast<int>(clipboard_type),
265 formats_vector, 614 formats_vector,
266 data_items_vector)); 615 data_items_vector));
267 // Assume success, since it allows us to avoid a sync IPC. 616 // Assume success, since it allows us to avoid a sync IPC.
268 return PP_OK; 617 return PP_OK;
269 } 618 }
270 619
620 bool PPB_Flash_Proxy::CreateThreadAdapterForInstance(PP_Instance instance) {
621 if (!g_module_local_thread_adapter) {
622 g_module_local_thread_adapter = new ModuleLocalThreadAdapter();
623 g_module_local_thread_adapter->AddRef(); // Leaked, this object is global.
624 }
625
626 PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance);
627 if (!dispatcher) {
628 NOTREACHED();
629 return false;
630 }
631 g_module_local_thread_adapter->AddInstanceRouting(instance, dispatcher);
632 return true;
633 }
634
635 void PPB_Flash_Proxy::ClearThreadAdapterForInstance(PP_Instance instance) {
636 if (g_module_local_thread_adapter)
637 g_module_local_thread_adapter->ClearInstanceRouting(instance);
638 }
639
640 int32_t PPB_Flash_Proxy::OpenFile(PP_Instance instance,
641 const char* path,
642 int32_t mode,
643 PP_FileHandle* file) {
644 if (!g_module_local_thread_adapter)
645 return PP_ERROR_FAILED;
646
647 int32_t result = PP_ERROR_FAILED;
648 IPC::PlatformFileForTransit transit;
649 g_module_local_thread_adapter->Send(instance,
650 new PpapiHostMsg_PPBFlash_OpenFile(
651 API_ID_PPB_FLASH, instance, path, mode, &transit, &result));
652 *file = IPC::PlatformFileForTransitToPlatformFile(transit);
653 return result;
654 }
655
656 int32_t PPB_Flash_Proxy::RenameFile(PP_Instance instance,
657 const char* path_from,
658 const char* path_to) {
659 if (!g_module_local_thread_adapter)
660 return PP_ERROR_FAILED;
661
662 int32_t result = PP_ERROR_FAILED;
663 g_module_local_thread_adapter->Send(instance,
664 new PpapiHostMsg_PPBFlash_RenameFile(
665 API_ID_PPB_FLASH, instance, path_from, path_to, &result));
666 return result;
667 }
668
669 int32_t PPB_Flash_Proxy::DeleteFileOrDir(PP_Instance instance,
670 const char* path,
671 PP_Bool recursive) {
672 if (!g_module_local_thread_adapter)
673 return PP_ERROR_FAILED;
674
675 int32_t result = PP_ERROR_FAILED;
676 g_module_local_thread_adapter->Send(instance,
677 new PpapiHostMsg_PPBFlash_DeleteFileOrDir(
678 API_ID_PPB_FLASH, instance, path, recursive, &result));
679 return result;
680 }
681
682 int32_t PPB_Flash_Proxy::CreateDir(PP_Instance instance, const char* path) {
683 if (!g_module_local_thread_adapter)
684 return PP_ERROR_FAILED;
685
686 int32_t result = PP_ERROR_FAILED;
687 g_module_local_thread_adapter->Send(instance,
688 new PpapiHostMsg_PPBFlash_CreateDir(
689 API_ID_PPB_FLASH, instance, path, &result));
690 return result;
691 }
692
693 int32_t PPB_Flash_Proxy::QueryFile(PP_Instance instance,
694 const char* path,
695 PP_FileInfo* info) {
696 if (!g_module_local_thread_adapter)
697 return PP_ERROR_FAILED;
698
699 int32_t result = PP_ERROR_FAILED;
700 g_module_local_thread_adapter->Send(instance,
701 new PpapiHostMsg_PPBFlash_QueryFile(
702 API_ID_PPB_FLASH, instance, path, info, &result));
703 return result;
704 }
705
706 int32_t PPB_Flash_Proxy::GetDirContents(PP_Instance instance,
707 const char* path,
708 PP_DirContents_Dev** contents) {
709 if (!g_module_local_thread_adapter)
710 return PP_ERROR_FAILED;
711
712 int32_t result = PP_ERROR_FAILED;
713 std::vector<SerializedDirEntry> entries;
714 g_module_local_thread_adapter->Send(instance,
715 new PpapiHostMsg_PPBFlash_GetDirContents(
716 API_ID_PPB_FLASH, instance, path, &entries, &result));
717
718 if (result != PP_OK)
719 return result;
720
721 // Copy the serialized dir entries to the output struct.
722 *contents = new PP_DirContents_Dev;
723 (*contents)->count = static_cast<int32_t>(entries.size());
724 (*contents)->entries = new PP_DirEntry_Dev[entries.size()];
725 for (size_t i = 0; i < entries.size(); i++) {
726 const SerializedDirEntry& source = entries[i];
727 PP_DirEntry_Dev* dest = &(*contents)->entries[i];
728
729 char* name_copy = new char[source.name.size() + 1];
730 memcpy(name_copy, source.name.c_str(), source.name.size() + 1);
731 dest->name = name_copy;
732 dest->is_dir = PP_FromBool(source.is_dir);
733 }
734
735 return result;
736 }
737
738 int32_t PPB_Flash_Proxy::OpenFileRef(PP_Instance instance,
739 PP_Resource file_ref_id,
740 int32_t mode,
741 PP_FileHandle* file) {
742 EnterResourceNoLock<PPB_FileRef> enter(file_ref_id, true);
743 if (enter.failed())
744 return PP_ERROR_BADRESOURCE;
745
746 int32_t result = PP_ERROR_FAILED;
747 IPC::PlatformFileForTransit transit;
748 dispatcher()->Send(new PpapiHostMsg_PPBFlash_OpenFileRef(
749 API_ID_PPB_FLASH, instance, enter.resource()->host_resource(), mode,
750 &transit, &result));
751 *file = IPC::PlatformFileForTransitToPlatformFile(transit);
752 return result;
753 }
754
755 int32_t PPB_Flash_Proxy::QueryFileRef(PP_Instance instance,
756 PP_Resource file_ref_id,
757 PP_FileInfo* info) {
758 EnterResourceNoLock<PPB_FileRef> enter(file_ref_id, true);
759 if (enter.failed())
760 return PP_ERROR_BADRESOURCE;
761
762 int32_t result = PP_ERROR_FAILED;
763 dispatcher()->Send(new PpapiHostMsg_PPBFlash_QueryFileRef(
764 API_ID_PPB_FLASH, instance, enter.resource()->host_resource(), info,
765 &result));
766 return result;
767 }
768
271 PP_Bool PPB_Flash_Proxy::FlashIsFullscreen(PP_Instance instance) { 769 PP_Bool PPB_Flash_Proxy::FlashIsFullscreen(PP_Instance instance) {
272 InstanceData* data = static_cast<PluginDispatcher*>(dispatcher())-> 770 InstanceData* data = static_cast<PluginDispatcher*>(dispatcher())->
273 GetInstanceData(instance); 771 GetInstanceData(instance);
274 if (!data) 772 if (!data)
275 return PP_FALSE; 773 return PP_FALSE;
276 return data->flash_fullscreen; 774 return data->flash_fullscreen;
277 } 775 }
278 776
279 PP_Bool PPB_Flash_Proxy::FlashSetFullscreen(PP_Instance instance, 777 PP_Bool PPB_Flash_Proxy::FlashSetFullscreen(PP_Instance instance,
280 PP_Bool fullscreen) { 778 PP_Bool fullscreen) {
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
493 static_cast<PP_Flash_Clipboard_Type>(clipboard_type), 991 static_cast<PP_Flash_Clipboard_Type>(clipboard_type),
494 data_item_count, 992 data_item_count,
495 formats_array.get(), 993 formats_array.get(),
496 data_items_array); 994 data_items_array);
497 DLOG_IF(WARNING, result != PP_OK) 995 DLOG_IF(WARNING, result != PP_OK)
498 << "Write to clipboard failed unexpectedly."; 996 << "Write to clipboard failed unexpectedly.";
499 (void)result; // Prevent warning in release mode. 997 (void)result; // Prevent warning in release mode.
500 } 998 }
501 } 999 }
502 1000
1001 void PPB_Flash_Proxy::OnHostMsgOpenFile(
1002 PP_Instance instance,
1003 const std::string& path,
1004 int32_t mode,
1005 IPC::PlatformFileForTransit* file_handle,
1006 int32_t* result) {
1007 EnterInstanceNoLock enter(instance);
1008 if (enter.succeeded()) {
1009 base::PlatformFile file;
1010 *result = enter.functions()->GetFlashAPI()->OpenFile(
1011 instance, path.c_str(), mode, &file);
1012 *file_handle = PlatformFileToPlatformFileForTransit(
1013 dispatcher(), result, file);
1014 } else {
1015 *result = PP_ERROR_BADARGUMENT;
1016 }
1017 }
1018
1019 void PPB_Flash_Proxy::OnHostMsgRenameFile(PP_Instance instance,
1020 const std::string& from_path,
1021 const std::string& to_path,
1022 int32_t* result) {
1023 EnterInstanceNoLock enter(instance);
1024 if (enter.succeeded()) {
1025 *result = enter.functions()->GetFlashAPI()->RenameFile(
1026 instance, from_path.c_str(), to_path.c_str());
1027 } else {
1028 *result = PP_ERROR_BADARGUMENT;
1029 }
1030 }
1031
1032 void PPB_Flash_Proxy::OnHostMsgDeleteFileOrDir(PP_Instance instance,
1033 const std::string& path,
1034 PP_Bool recursive,
1035 int32_t* result) {
1036 EnterInstanceNoLock enter(instance);
1037 if (enter.succeeded()) {
1038 *result = enter.functions()->GetFlashAPI()->DeleteFileOrDir(
1039 instance, path.c_str(), recursive);
1040 } else {
1041 *result = PP_ERROR_BADARGUMENT;
1042 }
1043 }
1044
1045 void PPB_Flash_Proxy::OnHostMsgCreateDir(PP_Instance instance,
1046 const std::string& path,
1047 int32_t* result) {
1048 EnterInstanceNoLock enter(instance);
1049 if (enter.succeeded()) {
1050 *result = enter.functions()->GetFlashAPI()->CreateDir(
1051 instance, path.c_str());
1052 } else {
1053 *result = PP_ERROR_BADARGUMENT;
1054 }
1055 }
1056
1057 void PPB_Flash_Proxy::OnHostMsgQueryFile(PP_Instance instance,
1058 const std::string& path,
1059 PP_FileInfo* info,
1060 int32_t* result) {
1061 EnterInstanceNoLock enter(instance);
1062 if (enter.succeeded()) {
1063 *result = enter.functions()->GetFlashAPI()->QueryFile(
1064 instance, path.c_str(), info);
1065 } else {
1066 *result = PP_ERROR_BADARGUMENT;
1067 }
1068 }
1069
1070 void PPB_Flash_Proxy::OnHostMsgGetDirContents(
1071 PP_Instance instance,
1072 const std::string& path,
1073 std::vector<SerializedDirEntry>* entries,
1074 int32_t* result) {
1075 EnterInstanceNoLock enter(instance);
1076 if (enter.failed()) {
1077 *result = PP_ERROR_BADARGUMENT;
1078 return;
1079 }
1080
1081 PP_DirContents_Dev* contents = NULL;
1082 *result = enter.functions()->GetFlashAPI()->GetDirContents(
1083 instance, path.c_str(), &contents);
1084 if (*result != PP_OK)
1085 return;
1086
1087 // Convert the list of entries to the serialized version.
1088 entries->resize(contents->count);
1089 for (int32_t i = 0; i < contents->count; i++) {
1090 (*entries)[i].name.assign(contents->entries[i].name);
1091 (*entries)[i].is_dir = PP_ToBool(contents->entries[i].is_dir);
1092 }
1093 enter.functions()->GetFlashAPI()->FreeDirContents(instance, contents);
1094 }
1095
1096 void PPB_Flash_Proxy::OnHostMsgOpenFileRef(
1097 PP_Instance instance,
1098 const HostResource& host_resource,
1099 int32_t mode,
1100 IPC::PlatformFileForTransit* file_handle,
1101 int32_t* result) {
1102 EnterInstanceNoLock enter(instance);
1103 if (enter.failed()) {
1104 *result = PP_ERROR_BADARGUMENT;
1105 return;
1106 }
1107
1108 base::PlatformFile file;
1109 *result = enter.functions()->GetFlashAPI()->OpenFileRef(
1110 instance, host_resource.host_resource(), mode, &file);
1111 *file_handle = PlatformFileToPlatformFileForTransit(dispatcher(),
1112 result, file);
1113 }
1114
1115 void PPB_Flash_Proxy::OnHostMsgQueryFileRef(
1116 PP_Instance instance,
1117 const HostResource& host_resource,
1118 PP_FileInfo* info,
1119 int32_t* result) {
1120 EnterInstanceNoLock enter(instance);
1121 if (enter.failed()) {
1122 *result = PP_ERROR_BADARGUMENT;
1123 return;
1124 }
1125 *result = enter.functions()->GetFlashAPI()->QueryFileRef(
1126 instance, host_resource.host_resource(), info);
1127 }
1128
503 } // namespace proxy 1129 } // namespace proxy
504 } // namespace ppapi 1130 } // namespace ppapi
OLDNEW
« no previous file with comments | « ppapi/proxy/ppb_flash_proxy.h ('k') | ppapi/shared_impl/api_id.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698