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

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

Powered by Google App Engine
This is Rietveld 408576698