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

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

Issue 7105013: Convert more interfaces to the new thunk system. This goes up to and including (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 6 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_file_chooser_proxy.h ('k') | ppapi/proxy/ppb_file_ref_proxy.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) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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_chooser_proxy.h" 5 #include "ppapi/proxy/ppb_file_chooser_proxy.h"
6 6
7 #include <queue> 7 #include <queue>
8 8
9 #include "ppapi/c/dev/ppb_file_chooser_dev.h" 9 #include "ppapi/c/dev/ppb_file_chooser_dev.h"
10 #include "ppapi/c/pp_errors.h" 10 #include "ppapi/c/pp_errors.h"
11 #include "ppapi/c/private/ppb_proxy_private.h" 11 #include "ppapi/c/private/ppb_proxy_private.h"
12 #include "ppapi/proxy/enter_proxy.h"
12 #include "ppapi/proxy/host_dispatcher.h" 13 #include "ppapi/proxy/host_dispatcher.h"
13 #include "ppapi/proxy/plugin_dispatcher.h" 14 #include "ppapi/proxy/plugin_dispatcher.h"
14 #include "ppapi/proxy/plugin_resource.h" 15 #include "ppapi/proxy/plugin_resource.h"
15 #include "ppapi/proxy/ppapi_messages.h" 16 #include "ppapi/proxy/ppapi_messages.h"
16 #include "ppapi/proxy/ppb_file_ref_proxy.h" 17 #include "ppapi/proxy/ppb_file_ref_proxy.h"
17 #include "ppapi/proxy/serialized_var.h" 18 #include "ppapi/proxy/serialized_var.h"
19 #include "ppapi/thunk/thunk.h"
20
21 using ::ppapi::thunk::PPB_FileChooser_API;
18 22
19 namespace pp { 23 namespace pp {
20 namespace proxy { 24 namespace proxy {
21 25
22 class FileChooser : public PluginResource { 26 class FileChooser : public PluginResource,
27 public PPB_FileChooser_API {
23 public: 28 public:
24 FileChooser(const HostResource& resource); 29 FileChooser(const HostResource& resource);
25 virtual ~FileChooser(); 30 virtual ~FileChooser();
26 31
27 virtual FileChooser* AsFileChooser(); 32 // ResourceObjectBase overrides.
33 virtual PPB_FileChooser_API* AsPPB_FileChooser_API() OVERRIDE;
28 34
35 // PPB_FileChooser_API implementation.
36 virtual int32_t Show(PP_CompletionCallback callback) OVERRIDE;
37 virtual PP_Resource GetNextChosenFile() OVERRIDE;
38
39 // Handles the choose complete notification from the host.
40 void ChooseComplete(
41 int32_t result_code,
42 const std::vector<PPBFileRef_CreateInfo>& chosen_files);
43
44 private:
29 PP_CompletionCallback current_show_callback_; 45 PP_CompletionCallback current_show_callback_;
30 46
31 // All files returned by the current show callback that haven't yet been 47 // All files returned by the current show callback that haven't yet been
32 // given to the plugin. The plugin will repeatedly call us to get the next 48 // given to the plugin. The plugin will repeatedly call us to get the next
33 // file, and we'll vend those out of this queue, removing them when ownership 49 // file, and we'll vend those out of this queue, removing them when ownership
34 // has transferred to the plugin. 50 // has transferred to the plugin.
35 std::queue<PP_Resource> file_queue_; 51 std::queue<PP_Resource> file_queue_;
36 52
37 private:
38 DISALLOW_COPY_AND_ASSIGN(FileChooser); 53 DISALLOW_COPY_AND_ASSIGN(FileChooser);
39 }; 54 };
40 55
41 FileChooser::FileChooser(const HostResource& resource) 56 FileChooser::FileChooser(const HostResource& resource)
42 : PluginResource(resource), 57 : PluginResource(resource),
43 current_show_callback_(PP_MakeCompletionCallback(NULL, NULL)) { 58 current_show_callback_(PP_MakeCompletionCallback(NULL, NULL)) {
44 } 59 }
45 60
46 FileChooser::~FileChooser() { 61 FileChooser::~FileChooser() {
47 // Always need to fire completion callbacks to prevent a leak in the plugin. 62 // Always need to fire completion callbacks to prevent a leak in the plugin.
48 if (current_show_callback_.func) { 63 if (current_show_callback_.func) {
49 // TODO(brettw) the callbacks at this level should be refactored with a 64 // TODO(brettw) the callbacks at this level should be refactored with a
50 // more automatic tracking system like we have in the renderer. 65 // more automatic tracking system like we have in the renderer.
51 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableFunction( 66 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableFunction(
52 current_show_callback_.func, current_show_callback_.user_data, 67 current_show_callback_.func, current_show_callback_.user_data,
53 static_cast<int32_t>(PP_ERROR_ABORTED))); 68 static_cast<int32_t>(PP_ERROR_ABORTED)));
54 } 69 }
55 70
56 // Any existing files we haven't transferred ownership to the plugin need 71 // Any existing files we haven't transferred ownership to the plugin need
57 // to be freed. 72 // to be freed.
58 PluginResourceTracker* tracker = PluginResourceTracker::GetInstance(); 73 PluginResourceTracker* tracker = PluginResourceTracker::GetInstance();
59 while (!file_queue_.empty()) { 74 while (!file_queue_.empty()) {
60 tracker->ReleaseResource(file_queue_.front()); 75 tracker->ReleaseResource(file_queue_.front());
61 file_queue_.pop(); 76 file_queue_.pop();
62 } 77 }
63 } 78 }
64 79
65 FileChooser* FileChooser::AsFileChooser() { 80 PPB_FileChooser_API* FileChooser::AsPPB_FileChooser_API() {
66 return this; 81 return this;
67 } 82 }
68 83
69 namespace { 84 int32_t FileChooser::Show(PP_CompletionCallback callback) {
70 85 if (current_show_callback_.func)
71 PP_Resource Create(PP_Instance instance,
72 const PP_FileChooserOptions_Dev* options) {
73 Dispatcher* dispatcher = PluginDispatcher::GetForInstance(instance);
74 if (!dispatcher)
75 return 0;
76
77 HostResource result;
78 dispatcher->Send(new PpapiHostMsg_PPBFileChooser_Create(
79 INTERFACE_ID_PPB_FILE_CHOOSER, instance,
80 options->mode,
81 options->accept_mime_types ? options->accept_mime_types : std::string(),
82 &result));
83
84 if (result.is_null())
85 return 0;
86 linked_ptr<FileChooser> object(new FileChooser(result));
87 return PluginResourceTracker::GetInstance()->AddResource(object);
88 }
89
90 PP_Bool IsFileChooser(PP_Resource resource) {
91 FileChooser* object = PluginResource::GetAs<FileChooser>(resource);
92 return BoolToPPBool(!!object);
93 }
94
95 int32_t Show(PP_Resource chooser, struct PP_CompletionCallback callback) {
96 FileChooser* object = PluginResource::GetAs<FileChooser>(chooser);
97 if (!object)
98 return PP_ERROR_BADRESOURCE;
99 Dispatcher* dispatcher = PluginDispatcher::GetForInstance(object->instance());
100 if (!dispatcher)
101 return PP_ERROR_BADARGUMENT;
102
103 if (object->current_show_callback_.func)
104 return PP_ERROR_INPROGRESS; // Can't show more than once. 86 return PP_ERROR_INPROGRESS; // Can't show more than once.
105 87
106 object->current_show_callback_ = callback; 88 current_show_callback_ = callback;
107 dispatcher->Send(new PpapiHostMsg_PPBFileChooser_Show( 89 GetDispatcher()->Send(new PpapiHostMsg_PPBFileChooser_Show(
108 INTERFACE_ID_PPB_FILE_CHOOSER, 90 INTERFACE_ID_PPB_FILE_CHOOSER, host_resource()));
109 object->host_resource()));
110 return PP_OK_COMPLETIONPENDING; 91 return PP_OK_COMPLETIONPENDING;
111 } 92 }
112 93
113 PP_Resource GetNextChosenFile(PP_Resource chooser) { 94 PP_Resource FileChooser::GetNextChosenFile() {
114 FileChooser* object = PluginResource::GetAs<FileChooser>(chooser); 95 if (file_queue_.empty())
115 if (!object || object->file_queue_.empty())
116 return 0; 96 return 0;
117 97
118 // Return the next resource in the queue. These resource have already been 98 // Return the next resource in the queue. These resource have already been
119 // addrefed (they're currently owned by the FileChooser) and returning them 99 // addrefed (they're currently owned by the FileChooser) and returning them
120 // transfers ownership of that reference to the plugin. 100 // transfers ownership of that reference to the plugin.
121 PP_Resource next = object->file_queue_.front(); 101 PP_Resource next = file_queue_.front();
122 object->file_queue_.pop(); 102 file_queue_.pop();
123 return next; 103 return next;
124 } 104 }
125 105
126 const PPB_FileChooser_Dev file_chooser_interface = { 106 void FileChooser::ChooseComplete(
127 &Create, 107 int32_t result_code,
128 &IsFileChooser, 108 const std::vector<PPBFileRef_CreateInfo>& chosen_files) {
129 &Show, 109 // Convert each of the passed in file infos to resources. These will be owned
130 &GetNextChosenFile 110 // by the FileChooser object until they're passed to the plugin.
131 }; 111 DCHECK(file_queue_.empty());
112 for (size_t i = 0; i < chosen_files.size(); i++)
113 file_queue_.push(PPB_FileRef_Proxy::DeserializeFileRef(chosen_files[i]));
114
115 // Notify the plugin of the new data.
116 PP_RunAndClearCompletionCallback(&current_show_callback_, result_code);
117 // DANGER: May delete |this|!
118 }
119
120 namespace {
132 121
133 InterfaceProxy* CreateFileChooserProxy(Dispatcher* dispatcher, 122 InterfaceProxy* CreateFileChooserProxy(Dispatcher* dispatcher,
134 const void* target_interface) { 123 const void* target_interface) {
135 return new PPB_FileChooser_Proxy(dispatcher, target_interface); 124 return new PPB_FileChooser_Proxy(dispatcher, target_interface);
136 } 125 }
137 126
138 } // namespace 127 } // namespace
139 128
140 PPB_FileChooser_Proxy::PPB_FileChooser_Proxy(Dispatcher* dispatcher, 129 PPB_FileChooser_Proxy::PPB_FileChooser_Proxy(Dispatcher* dispatcher,
141 const void* target_interface) 130 const void* target_interface)
142 : InterfaceProxy(dispatcher, target_interface), 131 : InterfaceProxy(dispatcher, target_interface),
143 callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { 132 callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
144 } 133 }
145 134
146 PPB_FileChooser_Proxy::~PPB_FileChooser_Proxy() { 135 PPB_FileChooser_Proxy::~PPB_FileChooser_Proxy() {
147 } 136 }
148 137
149 const InterfaceProxy::Info* PPB_FileChooser_Proxy::GetInfo() { 138 const InterfaceProxy::Info* PPB_FileChooser_Proxy::GetInfo() {
150 static const Info info = { 139 static const Info info = {
151 &file_chooser_interface, 140 ::ppapi::thunk::GetPPB_FileChooser_Thunk(),
152 PPB_FILECHOOSER_DEV_INTERFACE, 141 PPB_FILECHOOSER_DEV_INTERFACE,
153 INTERFACE_ID_PPB_FILE_CHOOSER, 142 INTERFACE_ID_PPB_FILE_CHOOSER,
154 false, 143 false,
155 &CreateFileChooserProxy, 144 &CreateFileChooserProxy,
156 }; 145 };
157 return &info; 146 return &info;
158 } 147 }
159 148
149 // static
150 PP_Resource PPB_FileChooser_Proxy::CreateProxyResource(
151 PP_Instance instance,
152 const PP_FileChooserOptions_Dev* options) {
153 Dispatcher* dispatcher = PluginDispatcher::GetForInstance(instance);
154 if (!dispatcher)
155 return 0;
156
157 HostResource result;
158 dispatcher->Send(new PpapiHostMsg_PPBFileChooser_Create(
159 INTERFACE_ID_PPB_FILE_CHOOSER, instance,
160 options->mode,
161 options->accept_mime_types ? options->accept_mime_types : std::string(),
162 &result));
163
164 if (result.is_null())
165 return 0;
166 linked_ptr<FileChooser> object(new FileChooser(result));
167 return PluginResourceTracker::GetInstance()->AddResource(object);
168 }
169
160 bool PPB_FileChooser_Proxy::OnMessageReceived(const IPC::Message& msg) { 170 bool PPB_FileChooser_Proxy::OnMessageReceived(const IPC::Message& msg) {
161 bool handled = true; 171 bool handled = true;
162 IPC_BEGIN_MESSAGE_MAP(PPB_FileChooser_Proxy, msg) 172 IPC_BEGIN_MESSAGE_MAP(PPB_FileChooser_Proxy, msg)
163 // Plugin -> host messages. 173 // Plugin -> host messages.
164 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFileChooser_Create, OnMsgCreate) 174 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFileChooser_Create, OnMsgCreate)
165 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFileChooser_Show, OnMsgShow) 175 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFileChooser_Show, OnMsgShow)
166 176
167 // Host -> plugin messages. 177 // Host -> plugin messages.
168 IPC_MESSAGE_HANDLER(PpapiMsg_PPBFileChooser_ChooseComplete, 178 IPC_MESSAGE_HANDLER(PpapiMsg_PPBFileChooser_ChooseComplete,
169 OnMsgChooseComplete) 179 OnMsgChooseComplete)
(...skipping 20 matching lines...) Expand all
190 int32_t result = ppb_file_chooser_target()->Show( 200 int32_t result = ppb_file_chooser_target()->Show(
191 chooser.host_resource(), callback.pp_completion_callback()); 201 chooser.host_resource(), callback.pp_completion_callback());
192 if (result != PP_OK_COMPLETIONPENDING) 202 if (result != PP_OK_COMPLETIONPENDING)
193 callback.Run(result); 203 callback.Run(result);
194 } 204 }
195 205
196 void PPB_FileChooser_Proxy::OnMsgChooseComplete( 206 void PPB_FileChooser_Proxy::OnMsgChooseComplete(
197 const HostResource& chooser, 207 const HostResource& chooser,
198 int32_t result_code, 208 int32_t result_code,
199 const std::vector<PPBFileRef_CreateInfo>& chosen_files) { 209 const std::vector<PPBFileRef_CreateInfo>& chosen_files) {
200 PP_Resource plugin_resource = 210 EnterPluginFromHostResource<PPB_FileChooser_API> enter(chooser);
201 PluginResourceTracker::GetInstance()->PluginResourceForHostResource( 211 if (enter.succeeded()) {
202 chooser); 212 static_cast<FileChooser*>(enter.object())->ChooseComplete(
203 if (!plugin_resource) 213 result_code, chosen_files);
204 return;
205 FileChooser* object = PluginResource::GetAs<FileChooser>(plugin_resource);
206 if (!object)
207 return;
208
209 // Convert each of the passed in file infos to resources. These will be owned
210 // by the FileChooser object until they're passed to the plugin.
211 DCHECK(object->file_queue_.empty());
212 for (size_t i = 0; i < chosen_files.size(); i++) {
213 object->file_queue_.push(
214 PPB_FileRef_Proxy::DeserializeFileRef(chosen_files[i]));
215 } 214 }
216
217 // Notify the plugin of the new data. We have to swap out the callback
218 // because the plugin may trigger deleting the object from the callback, and
219 // the FileChooser object will attempt to call the callback in its destructor
220 // with the ABORTED status.
221 PP_RunAndClearCompletionCallback(&object->current_show_callback_,
222 result_code);
223 // DANGER: May delete |object|!
224 } 215 }
225 216
226 void PPB_FileChooser_Proxy::OnShowCallback(int32_t result, 217 void PPB_FileChooser_Proxy::OnShowCallback(int32_t result,
227 const HostResource& chooser) { 218 const HostResource& chooser) {
228 std::vector<PPBFileRef_CreateInfo> files; 219 std::vector<PPBFileRef_CreateInfo> files;
229 if (result == PP_OK) { 220 if (result == PP_OK) {
230 // Jump through some hoops to get the FileRef proxy. Since we know we're 221 // Jump through some hoops to get the FileRef proxy. Since we know we're
231 // in the host at this point, we can ask the host dispatcher for it. 222 // in the host at this point, we can ask the host dispatcher for it.
232 DCHECK(!dispatcher()->IsPlugin()); 223 DCHECK(!dispatcher()->IsPlugin());
233 HostDispatcher* host_disp = static_cast<HostDispatcher*>(dispatcher()); 224 HostDispatcher* host_disp = static_cast<HostDispatcher*>(dispatcher());
234 PPB_FileRef_Proxy* file_ref_proxy = static_cast<PPB_FileRef_Proxy*>( 225 PPB_FileRef_Proxy* file_ref_proxy = static_cast<PPB_FileRef_Proxy*>(
235 host_disp->GetOrCreatePPBInterfaceProxy(INTERFACE_ID_PPB_FILE_REF)); 226 host_disp->GetOrCreatePPBInterfaceProxy(INTERFACE_ID_PPB_FILE_REF));
236 227
237 // Convert the returned files to the serialized info. 228 // Convert the returned files to the serialized info.
238 while (PP_Resource cur_file_resource = 229 while (PP_Resource cur_file_resource =
239 ppb_file_chooser_target()->GetNextChosenFile( 230 ppb_file_chooser_target()->GetNextChosenFile(
240 chooser.host_resource())) { 231 chooser.host_resource())) {
241 PPBFileRef_CreateInfo cur_create_info; 232 PPBFileRef_CreateInfo cur_create_info;
242 file_ref_proxy->SerializeFileRef(cur_file_resource, &cur_create_info); 233 file_ref_proxy->SerializeFileRef(cur_file_resource, &cur_create_info);
243 files.push_back(cur_create_info); 234 files.push_back(cur_create_info);
244 } 235 }
245 } 236 }
246 237
247 dispatcher()->Send(new PpapiMsg_PPBFileChooser_ChooseComplete( 238 dispatcher()->Send(new PpapiMsg_PPBFileChooser_ChooseComplete(
248 INTERFACE_ID_PPB_FILE_CHOOSER, chooser, result, files)); 239 INTERFACE_ID_PPB_FILE_CHOOSER, chooser, result, files));
249 } 240 }
250 241
251 } // namespace proxy 242 } // namespace proxy
252 } // namespace pp 243 } // namespace pp
OLDNEW
« no previous file with comments | « ppapi/proxy/ppb_file_chooser_proxy.h ('k') | ppapi/proxy/ppb_file_ref_proxy.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698