| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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_url_loader_proxy.h" | 5 #include "ppapi/proxy/ppb_url_loader_proxy.h" |
| 6 | 6 |
| 7 #include <vector> | 7 #include <vector> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "build/build_config.h" | 10 #include "build/build_config.h" |
| 11 #include "ppapi/c/pp_completion_callback.h" | 11 #include "ppapi/c/pp_completion_callback.h" |
| 12 #include "ppapi/c/pp_errors.h" | 12 #include "ppapi/c/pp_errors.h" |
| 13 #include "ppapi/c/pp_resource.h" | 13 #include "ppapi/c/pp_resource.h" |
| 14 #include "ppapi/c/ppb_url_loader.h" | 14 #include "ppapi/c/ppb_url_loader.h" |
| 15 #include "ppapi/c/trusted/ppb_url_loader_trusted.h" | 15 #include "ppapi/c/trusted/ppb_url_loader_trusted.h" |
| 16 #include "ppapi/proxy/host_dispatcher.h" | 16 #include "ppapi/proxy/host_dispatcher.h" |
| 17 #include "ppapi/proxy/plugin_dispatcher.h" | 17 #include "ppapi/proxy/plugin_dispatcher.h" |
| 18 #include "ppapi/proxy/plugin_resource.h" | 18 #include "ppapi/proxy/plugin_resource.h" |
| 19 #include "ppapi/proxy/plugin_resource_tracker.h" |
| 19 #include "ppapi/proxy/ppapi_messages.h" | 20 #include "ppapi/proxy/ppapi_messages.h" |
| 20 #include "ppapi/proxy/ppb_url_response_info_proxy.h" | 21 #include "ppapi/proxy/ppb_url_response_info_proxy.h" |
| 21 | 22 |
| 22 #if defined(OS_LINUX) | 23 #if defined(OS_LINUX) |
| 23 #include <sys/shm.h> | 24 #include <sys/shm.h> |
| 24 #endif | 25 #endif |
| 25 | 26 |
| 26 namespace pp { | 27 namespace pp { |
| 27 namespace proxy { | 28 namespace proxy { |
| 28 | 29 |
| 29 class URLLoader : public PluginResource { | 30 class URLLoader : public PluginResource { |
| 30 public: | 31 public: |
| 31 URLLoader(PP_Instance instance); | 32 URLLoader(PP_Instance instance, SerializedResource resource); |
| 32 virtual ~URLLoader(); | 33 virtual ~URLLoader(); |
| 33 | 34 |
| 34 // Resource overrides. | 35 // Resource overrides. |
| 35 virtual URLLoader* AsURLLoader() { return this; } | 36 virtual URLLoader* AsURLLoader() { return this; } |
| 36 | 37 |
| 38 PP_Resource GetResponseInfo(); |
| 39 |
| 37 // Initialized to -1. Will be set to nonnegative values by the UpdateProgress | 40 // Initialized to -1. Will be set to nonnegative values by the UpdateProgress |
| 38 // message when the values are known. | 41 // message when the values are known. |
| 39 int64_t bytes_sent_; | 42 int64_t bytes_sent_; |
| 40 int64_t total_bytes_to_be_sent_; | 43 int64_t total_bytes_to_be_sent_; |
| 41 int64_t bytes_received_; | 44 int64_t bytes_received_; |
| 42 int64_t total_bytes_to_be_received_; | 45 int64_t total_bytes_to_be_received_; |
| 43 | 46 |
| 44 // When an asynchronous read is pending, this will contain the callback and | 47 // When an asynchronous read is pending, this will contain the callback and |
| 45 // the buffer to put the data. | 48 // the buffer to put the data. |
| 46 PP_CompletionCallback current_read_callback_; | 49 PP_CompletionCallback current_read_callback_; |
| 47 char* current_read_buffer_; | 50 char* current_read_buffer_; |
| 48 | 51 |
| 52 // Cached copy of the response info. When nonzero, we're holding a reference |
| 53 // to this resource. |
| 54 PP_Resource response_info_; |
| 55 |
| 49 private: | 56 private: |
| 50 DISALLOW_COPY_AND_ASSIGN(URLLoader); | 57 DISALLOW_COPY_AND_ASSIGN(URLLoader); |
| 51 }; | 58 }; |
| 52 | 59 |
| 53 URLLoader::URLLoader(PP_Instance instance) | 60 URLLoader::URLLoader(PP_Instance instance, SerializedResource resource) |
| 54 : PluginResource(instance), | 61 : PluginResource(instance, resource), |
| 55 bytes_sent_(-1), | 62 bytes_sent_(-1), |
| 56 total_bytes_to_be_sent_(-1), | 63 total_bytes_to_be_sent_(-1), |
| 57 bytes_received_(-1), | 64 bytes_received_(-1), |
| 58 total_bytes_to_be_received_(-1), | 65 total_bytes_to_be_received_(-1), |
| 59 current_read_callback_(PP_MakeCompletionCallback(NULL, NULL)), | 66 current_read_callback_(PP_MakeCompletionCallback(NULL, NULL)), |
| 60 current_read_buffer_(NULL) { | 67 current_read_buffer_(NULL), |
| 68 response_info_(0) { |
| 61 } | 69 } |
| 62 | 70 |
| 63 URLLoader::~URLLoader() { | 71 URLLoader::~URLLoader() { |
| 72 if (response_info_) |
| 73 PluginResourceTracker::GetInstance()->ReleaseResource(response_info_); |
| 74 } |
| 75 |
| 76 PP_Resource URLLoader::GetResponseInfo() { |
| 77 if (!response_info_) { |
| 78 PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance()); |
| 79 if (!dispatcher) |
| 80 return 0; |
| 81 |
| 82 SerializedResource response_id; |
| 83 dispatcher->Send(new PpapiHostMsg_PPBURLLoader_GetResponseInfo( |
| 84 INTERFACE_ID_PPB_URL_LOADER, host_resource(), &response_id)); |
| 85 if (response_id.is_null()) |
| 86 return 0; |
| 87 |
| 88 response_info_ = PPB_URLResponseInfo_Proxy::CreateResponseForResource( |
| 89 instance(), response_id); |
| 90 } |
| 91 |
| 92 // The caller expects to get a ref, and we want to keep holding ours. |
| 93 PluginResourceTracker::GetInstance()->AddRefResource(response_info_); |
| 94 return response_info_; |
| 64 } | 95 } |
| 65 | 96 |
| 66 namespace { | 97 namespace { |
| 67 | 98 |
| 68 // Converts the given loader ID to the dispatcher associated with it, or NULL | 99 // Converts the given loader ID to the dispatcher associated with it and the |
| 69 // if it couldn't be found. | 100 // loader object. Returns true if the object was found. |
| 70 PluginDispatcher* DispatcherFromURLLoader(PP_Resource loader_id) { | 101 bool RoutingDataFromURLLoader(PP_Resource loader_id, |
| 71 URLLoader* object = PluginResource::GetAs<URLLoader>(loader_id); | 102 URLLoader** loader_object, |
| 72 if (!object) | 103 PluginDispatcher** dispatcher) { |
| 73 return NULL; | 104 *loader_object = PluginResource::GetAs<URLLoader>(loader_id); |
| 74 return PluginDispatcher::GetForInstance(object->instance()); | 105 if (!*loader_object) |
| 106 return false; |
| 107 *dispatcher = PluginDispatcher::GetForInstance((*loader_object)->instance()); |
| 108 return !!*dispatcher; |
| 75 } | 109 } |
| 76 | 110 |
| 77 // Plugin PPB_URLLoader implmentation ------------------------------------------ | 111 // Plugin PPB_URLLoader implmentation ------------------------------------------ |
| 78 | 112 |
| 79 PP_Resource Create(PP_Instance instance_id) { | 113 PP_Resource Create(PP_Instance instance_id) { |
| 80 PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance_id); | 114 PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance_id); |
| 81 if (!dispatcher) | 115 if (!dispatcher) |
| 82 return 0; | 116 return 0; |
| 83 | 117 |
| 84 PP_Resource result = 0; | 118 SerializedResource result; |
| 85 dispatcher->Send(new PpapiHostMsg_PPBURLLoader_Create( | 119 dispatcher->Send(new PpapiHostMsg_PPBURLLoader_Create( |
| 86 INTERFACE_ID_PPB_URL_LOADER, instance_id, &result)); | 120 INTERFACE_ID_PPB_URL_LOADER, instance_id, &result)); |
| 87 if (result) | 121 if (result.is_null()) |
| 88 PPB_URLLoader_Proxy::TrackPluginResource(instance_id, result); | 122 return 0; |
| 89 return result; | 123 return PPB_URLLoader_Proxy::TrackPluginResource(instance_id, result); |
| 90 } | 124 } |
| 91 | 125 |
| 92 PP_Bool IsURLLoader(PP_Resource resource) { | 126 PP_Bool IsURLLoader(PP_Resource resource) { |
| 93 URLLoader* object = PluginResource::GetAs<URLLoader>(resource); | 127 URLLoader* object = PluginResource::GetAs<URLLoader>(resource); |
| 94 return BoolToPPBool(!!object); | 128 return BoolToPPBool(!!object); |
| 95 } | 129 } |
| 96 | 130 |
| 97 int32_t Open(PP_Resource loader_id, | 131 int32_t Open(PP_Resource loader_id, |
| 98 PP_Resource request_id, | 132 PP_Resource request_id, |
| 99 PP_CompletionCallback callback) { | 133 PP_CompletionCallback callback) { |
| 100 PluginDispatcher* dispatcher = DispatcherFromURLLoader(loader_id); | 134 URLLoader* loader_object; |
| 101 if (!dispatcher) | 135 PluginDispatcher* dispatcher; |
| 136 if (!RoutingDataFromURLLoader(loader_id, &loader_object, &dispatcher)) |
| 137 return PP_ERROR_BADRESOURCE; |
| 138 PluginResource* request_object = |
| 139 PluginResourceTracker::GetInstance()->GetResourceObject(request_id); |
| 140 if (!request_object) |
| 102 return PP_ERROR_BADRESOURCE; | 141 return PP_ERROR_BADRESOURCE; |
| 103 | 142 |
| 104 dispatcher->Send(new PpapiHostMsg_PPBURLLoader_Open( | 143 dispatcher->Send(new PpapiHostMsg_PPBURLLoader_Open( |
| 105 INTERFACE_ID_PPB_URL_LOADER, loader_id, request_id, | 144 INTERFACE_ID_PPB_URL_LOADER, loader_object->host_resource(), |
| 145 request_object->host_resource(), |
| 106 dispatcher->callback_tracker().SendCallback(callback))); | 146 dispatcher->callback_tracker().SendCallback(callback))); |
| 107 return PP_ERROR_WOULDBLOCK; | 147 return PP_ERROR_WOULDBLOCK; |
| 108 } | 148 } |
| 109 | 149 |
| 110 int32_t FollowRedirect(PP_Resource loader_id, | 150 int32_t FollowRedirect(PP_Resource loader_id, |
| 111 PP_CompletionCallback callback) { | 151 PP_CompletionCallback callback) { |
| 112 PluginDispatcher* dispatcher = DispatcherFromURLLoader(loader_id); | 152 URLLoader* loader_object; |
| 113 if (!dispatcher) | 153 PluginDispatcher* dispatcher; |
| 154 if (!RoutingDataFromURLLoader(loader_id, &loader_object, &dispatcher)) |
| 114 return PP_ERROR_BADRESOURCE; | 155 return PP_ERROR_BADRESOURCE; |
| 115 | 156 |
| 116 dispatcher->Send(new PpapiHostMsg_PPBURLLoader_FollowRedirect( | 157 dispatcher->Send(new PpapiHostMsg_PPBURLLoader_FollowRedirect( |
| 117 INTERFACE_ID_PPB_URL_LOADER, loader_id, | 158 INTERFACE_ID_PPB_URL_LOADER, loader_object->host_resource(), |
| 118 dispatcher->callback_tracker().SendCallback(callback))); | 159 dispatcher->callback_tracker().SendCallback(callback))); |
| 119 return PP_ERROR_WOULDBLOCK; | 160 return PP_ERROR_WOULDBLOCK; |
| 120 } | 161 } |
| 121 | 162 |
| 122 PP_Bool GetUploadProgress(PP_Resource loader_id, | 163 PP_Bool GetUploadProgress(PP_Resource loader_id, |
| 123 int64_t* bytes_sent, | 164 int64_t* bytes_sent, |
| 124 int64_t* total_bytes_to_be_sent) { | 165 int64_t* total_bytes_to_be_sent) { |
| 125 URLLoader* object = PluginResource::GetAs<URLLoader>(loader_id); | 166 URLLoader* object = PluginResource::GetAs<URLLoader>(loader_id); |
| 126 if (!object || object->bytes_sent_ == -1) { | 167 if (!object || object->bytes_sent_ == -1) { |
| 127 *bytes_sent = 0; | 168 *bytes_sent = 0; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 144 } | 185 } |
| 145 *bytes_received = object->bytes_received_; | 186 *bytes_received = object->bytes_received_; |
| 146 *total_bytes_to_be_received = object->total_bytes_to_be_received_; | 187 *total_bytes_to_be_received = object->total_bytes_to_be_received_; |
| 147 return PP_TRUE; | 188 return PP_TRUE; |
| 148 } | 189 } |
| 149 | 190 |
| 150 PP_Resource GetResponseInfo(PP_Resource loader_id) { | 191 PP_Resource GetResponseInfo(PP_Resource loader_id) { |
| 151 URLLoader* object = PluginResource::GetAs<URLLoader>(loader_id); | 192 URLLoader* object = PluginResource::GetAs<URLLoader>(loader_id); |
| 152 if (!object) | 193 if (!object) |
| 153 return 0; | 194 return 0; |
| 154 | 195 return object->GetResponseInfo(); |
| 155 // If we find that plugins are frequently requesting the response info, we | |
| 156 // can improve performance by caching the PP_Resource in the URLLoader | |
| 157 // object. This way we only have to do IPC for the first request. However, | |
| 158 // it seems that most plugins will only call this once so there's no use | |
| 159 // optimizing this case. | |
| 160 | |
| 161 PP_Resource result; | |
| 162 PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance( | |
| 163 object->instance()); | |
| 164 if (!dispatcher) | |
| 165 return PP_ERROR_BADRESOURCE; | |
| 166 | |
| 167 dispatcher->Send(new PpapiHostMsg_PPBURLLoader_GetResponseInfo( | |
| 168 INTERFACE_ID_PPB_URL_LOADER, loader_id, &result)); | |
| 169 if (PluginResourceTracker::GetInstance()-> | |
| 170 PreparePreviouslyTrackedResource(result)) | |
| 171 return result; | |
| 172 | |
| 173 // Tell the response info to create a tracking object and add it to the | |
| 174 // resource tracker. | |
| 175 PPB_URLResponseInfo_Proxy::TrackPluginResource(object->instance(), result); | |
| 176 return result; | |
| 177 } | 196 } |
| 178 | 197 |
| 179 int32_t ReadResponseBody(PP_Resource loader_id, | 198 int32_t ReadResponseBody(PP_Resource loader_id, |
| 180 char* buffer, | 199 char* buffer, |
| 181 int32_t bytes_to_read, | 200 int32_t bytes_to_read, |
| 182 PP_CompletionCallback callback) { | 201 PP_CompletionCallback callback) { |
| 183 URLLoader* object = PluginResource::GetAs<URLLoader>(loader_id); | 202 URLLoader* loader_object; |
| 184 if (!object) | 203 PluginDispatcher* dispatcher; |
| 185 return PP_ERROR_BADRESOURCE; | 204 if (!RoutingDataFromURLLoader(loader_id, &loader_object, &dispatcher)) |
| 186 PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance( | |
| 187 object->instance()); | |
| 188 if (!dispatcher) | |
| 189 return PP_ERROR_BADRESOURCE; | 205 return PP_ERROR_BADRESOURCE; |
| 190 | 206 |
| 191 if (!buffer) | 207 if (!buffer) |
| 192 return PP_ERROR_BADARGUMENT; // Must specify an output buffer. | 208 return PP_ERROR_BADARGUMENT; // Must specify an output buffer. |
| 193 if (object->current_read_callback_.func) | 209 if (loader_object->current_read_callback_.func) |
| 194 return PP_ERROR_INPROGRESS; // Can only have one request pending. | 210 return PP_ERROR_INPROGRESS; // Can only have one request pending. |
| 195 | 211 |
| 196 // Currently we don't support sync calls to read. We'll need to revisit | 212 // Currently we don't support sync calls to read. We'll need to revisit |
| 197 // how this works when we allow blocking calls (from background threads). | 213 // how this works when we allow blocking calls (from background threads). |
| 198 if (!callback.func) | 214 if (!callback.func) |
| 199 return PP_ERROR_BADARGUMENT; | 215 return PP_ERROR_BADARGUMENT; |
| 200 | 216 |
| 201 object->current_read_callback_ = callback; | 217 loader_object->current_read_callback_ = callback; |
| 202 object->current_read_buffer_ = buffer; | 218 loader_object->current_read_buffer_ = buffer; |
| 203 | 219 |
| 204 dispatcher->Send(new PpapiHostMsg_PPBURLLoader_ReadResponseBody( | 220 dispatcher->Send(new PpapiHostMsg_PPBURLLoader_ReadResponseBody( |
| 205 INTERFACE_ID_PPB_URL_LOADER, loader_id, bytes_to_read)); | 221 INTERFACE_ID_PPB_URL_LOADER, loader_object->instance(), |
| 222 loader_object->host_resource(), bytes_to_read)); |
| 206 return PP_ERROR_WOULDBLOCK; | 223 return PP_ERROR_WOULDBLOCK; |
| 207 } | 224 } |
| 208 | 225 |
| 209 int32_t FinishStreamingToFile(PP_Resource loader_id, | 226 int32_t FinishStreamingToFile(PP_Resource loader_id, |
| 210 PP_CompletionCallback callback) { | 227 PP_CompletionCallback callback) { |
| 211 PluginDispatcher* dispatcher = DispatcherFromURLLoader(loader_id); | 228 URLLoader* loader_object; |
| 212 if (!dispatcher) | 229 PluginDispatcher* dispatcher; |
| 230 if (!RoutingDataFromURLLoader(loader_id, &loader_object, &dispatcher)) |
| 213 return PP_ERROR_BADRESOURCE; | 231 return PP_ERROR_BADRESOURCE; |
| 214 | 232 |
| 215 dispatcher->Send(new PpapiHostMsg_PPBURLLoader_FinishStreamingToFile( | 233 dispatcher->Send(new PpapiHostMsg_PPBURLLoader_FinishStreamingToFile( |
| 216 INTERFACE_ID_PPB_URL_LOADER, loader_id, | 234 INTERFACE_ID_PPB_URL_LOADER, loader_object->host_resource(), |
| 217 dispatcher->callback_tracker().SendCallback(callback))); | 235 dispatcher->callback_tracker().SendCallback(callback))); |
| 218 return PP_ERROR_WOULDBLOCK; | 236 return PP_ERROR_WOULDBLOCK; |
| 219 } | 237 } |
| 220 | 238 |
| 221 void Close(PP_Resource loader_id) { | 239 void Close(PP_Resource loader_id) { |
| 222 PluginDispatcher* dispatcher = DispatcherFromURLLoader(loader_id); | 240 URLLoader* loader_object; |
| 223 if (!dispatcher) | 241 PluginDispatcher* dispatcher; |
| 242 if (!RoutingDataFromURLLoader(loader_id, &loader_object, &dispatcher)) |
| 224 return; | 243 return; |
| 225 | 244 |
| 226 dispatcher->Send(new PpapiHostMsg_PPBURLLoader_Close( | 245 dispatcher->Send(new PpapiHostMsg_PPBURLLoader_Close( |
| 227 INTERFACE_ID_PPB_URL_LOADER, loader_id)); | 246 INTERFACE_ID_PPB_URL_LOADER, loader_object->host_resource())); |
| 228 } | 247 } |
| 229 | 248 |
| 230 const PPB_URLLoader ppb_urlloader = { | 249 const PPB_URLLoader ppb_urlloader = { |
| 231 &Create, | 250 &Create, |
| 232 &IsURLLoader, | 251 &IsURLLoader, |
| 233 &Open, | 252 &Open, |
| 234 &FollowRedirect, | 253 &FollowRedirect, |
| 235 &GetUploadProgress, | 254 &GetUploadProgress, |
| 236 &GetDownloadProgress, | 255 &GetDownloadProgress, |
| 237 &GetResponseInfo, | 256 &GetResponseInfo, |
| 238 &ReadResponseBody, | 257 &ReadResponseBody, |
| 239 &FinishStreamingToFile, | 258 &FinishStreamingToFile, |
| 240 &Close | 259 &Close |
| 241 }; | 260 }; |
| 242 | 261 |
| 243 // Plugin URLLoaderTrusted implementation -------------------------------------- | 262 // Plugin URLLoaderTrusted implementation -------------------------------------- |
| 244 | 263 |
| 245 void GrantUniversalAccess(PP_Resource loader) { | 264 void GrantUniversalAccess(PP_Resource loader_id) { |
| 246 PluginDispatcher::Get()->Send( | 265 URLLoader* loader_object; |
| 266 PluginDispatcher* dispatcher; |
| 267 if (!RoutingDataFromURLLoader(loader_id, &loader_object, &dispatcher)) |
| 268 return; |
| 269 |
| 270 dispatcher->Send( |
| 247 new PpapiHostMsg_PPBURLLoaderTrusted_GrantUniversalAccess( | 271 new PpapiHostMsg_PPBURLLoaderTrusted_GrantUniversalAccess( |
| 248 INTERFACE_ID_PPB_URL_LOADER_TRUSTED, loader)); | 272 INTERFACE_ID_PPB_URL_LOADER_TRUSTED, loader_object->host_resource())); |
| 249 } | 273 } |
| 250 | 274 |
| 251 const PPB_URLLoaderTrusted ppb_urlloader_trusted = { | 275 const PPB_URLLoaderTrusted ppb_urlloader_trusted = { |
| 252 &GrantUniversalAccess, | 276 &GrantUniversalAccess, |
| 253 NULL, // RegisterStatusCallback is used internally by the proxy only. | 277 NULL, // RegisterStatusCallback is used internally by the proxy only. |
| 254 }; | 278 }; |
| 255 | 279 |
| 256 } // namespace | 280 } // namespace |
| 257 | 281 |
| 258 // PPB_URLLoader_Proxy --------------------------------------------------------- | 282 // PPB_URLLoader_Proxy --------------------------------------------------------- |
| 259 | 283 |
| 260 struct PPB_URLLoader_Proxy::ReadCallbackInfo { | 284 struct PPB_URLLoader_Proxy::ReadCallbackInfo { |
| 261 PP_Resource pp_resource; | 285 PP_Instance instance; |
| 286 SerializedResource resource; |
| 262 std::string read_buffer; | 287 std::string read_buffer; |
| 263 }; | 288 }; |
| 264 | 289 |
| 265 PPB_URLLoader_Proxy::PPB_URLLoader_Proxy(Dispatcher* dispatcher, | 290 PPB_URLLoader_Proxy::PPB_URLLoader_Proxy(Dispatcher* dispatcher, |
| 266 const void* target_interface) | 291 const void* target_interface) |
| 267 : InterfaceProxy(dispatcher, target_interface), | 292 : InterfaceProxy(dispatcher, target_interface), |
| 268 callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { | 293 callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { |
| 269 } | 294 } |
| 270 | 295 |
| 271 PPB_URLLoader_Proxy::~PPB_URLLoader_Proxy() { | 296 PPB_URLLoader_Proxy::~PPB_URLLoader_Proxy() { |
| 272 } | 297 } |
| 273 | 298 |
| 274 // static | 299 // static |
| 275 void PPB_URLLoader_Proxy::TrackPluginResource(PP_Instance instance, | 300 PP_Resource PPB_URLLoader_Proxy::TrackPluginResource( |
| 276 PP_Resource url_loader_resource) { | 301 PP_Instance instance, |
| 277 linked_ptr<URLLoader> object(new URLLoader(instance)); | 302 SerializedResource url_loader_resource) { |
| 278 PluginResourceTracker::GetInstance()->AddResource(url_loader_resource, | 303 linked_ptr<URLLoader> object(new URLLoader(instance, url_loader_resource)); |
| 279 object); | 304 return PluginResourceTracker::GetInstance()->AddResource(object); |
| 280 } | 305 } |
| 281 | 306 |
| 282 const void* PPB_URLLoader_Proxy::GetSourceInterface() const { | 307 const void* PPB_URLLoader_Proxy::GetSourceInterface() const { |
| 283 return &ppb_urlloader; | 308 return &ppb_urlloader; |
| 284 } | 309 } |
| 285 | 310 |
| 286 InterfaceID PPB_URLLoader_Proxy::GetInterfaceId() const { | 311 InterfaceID PPB_URLLoader_Proxy::GetInterfaceId() const { |
| 287 return INTERFACE_ID_PPB_URL_LOADER; | 312 return INTERFACE_ID_PPB_URL_LOADER; |
| 288 } | 313 } |
| 289 | 314 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 309 OnMsgUpdateProgress) | 334 OnMsgUpdateProgress) |
| 310 IPC_MESSAGE_HANDLER(PpapiMsg_PPBURLLoader_ReadResponseBody_Ack, | 335 IPC_MESSAGE_HANDLER(PpapiMsg_PPBURLLoader_ReadResponseBody_Ack, |
| 311 OnMsgReadResponseBodyAck) | 336 OnMsgReadResponseBodyAck) |
| 312 IPC_MESSAGE_UNHANDLED(handled = false) | 337 IPC_MESSAGE_UNHANDLED(handled = false) |
| 313 IPC_END_MESSAGE_MAP() | 338 IPC_END_MESSAGE_MAP() |
| 314 // TODO(brettw) handle bad messages! | 339 // TODO(brettw) handle bad messages! |
| 315 return handled; | 340 return handled; |
| 316 } | 341 } |
| 317 | 342 |
| 318 void PPB_URLLoader_Proxy::OnMsgCreate(PP_Instance instance, | 343 void PPB_URLLoader_Proxy::OnMsgCreate(PP_Instance instance, |
| 319 PP_Resource* result) { | 344 SerializedResource* result) { |
| 320 *result = ppb_url_loader_target()->Create(instance); | 345 result->set_host_resource(ppb_url_loader_target()->Create(instance)); |
| 321 } | 346 } |
| 322 | 347 |
| 323 void PPB_URLLoader_Proxy::OnMsgOpen(PP_Resource loader, | 348 void PPB_URLLoader_Proxy::OnMsgOpen(SerializedResource loader, |
| 324 PP_Resource request_info, | 349 SerializedResource request_info, |
| 325 uint32_t serialized_callback) { | 350 uint32_t serialized_callback) { |
| 326 PP_CompletionCallback callback = ReceiveCallback(serialized_callback); | 351 PP_CompletionCallback callback = ReceiveCallback(serialized_callback); |
| 327 int32_t result = ppb_url_loader_target()->Open( | 352 int32_t result = ppb_url_loader_target()->Open( |
| 328 loader, request_info, callback); | 353 loader.host_resource(), request_info.host_resource(), callback); |
| 329 if (result != PP_ERROR_WOULDBLOCK) | 354 if (result != PP_ERROR_WOULDBLOCK) |
| 330 PP_RunCompletionCallback(&callback, result); | 355 PP_RunCompletionCallback(&callback, result); |
| 331 } | 356 } |
| 332 | 357 |
| 333 void PPB_URLLoader_Proxy::OnMsgFollowRedirect( | 358 void PPB_URLLoader_Proxy::OnMsgFollowRedirect( |
| 334 PP_Resource loader, | 359 SerializedResource loader, |
| 335 uint32_t serialized_callback) { | 360 uint32_t serialized_callback) { |
| 336 PP_CompletionCallback callback = ReceiveCallback(serialized_callback); | 361 PP_CompletionCallback callback = ReceiveCallback(serialized_callback); |
| 337 int32_t result = ppb_url_loader_target()->FollowRedirect( | 362 int32_t result = ppb_url_loader_target()->FollowRedirect( |
| 338 loader, callback); | 363 loader.host_resource(), callback); |
| 339 if (result != PP_ERROR_WOULDBLOCK) | 364 if (result != PP_ERROR_WOULDBLOCK) |
| 340 PP_RunCompletionCallback(&callback, result); | 365 PP_RunCompletionCallback(&callback, result); |
| 341 } | 366 } |
| 342 | 367 |
| 343 void PPB_URLLoader_Proxy::OnMsgGetResponseInfo(PP_Resource loader, | 368 void PPB_URLLoader_Proxy::OnMsgGetResponseInfo(SerializedResource loader, |
| 344 PP_Resource* result) { | 369 SerializedResource* result) { |
| 345 *result = ppb_url_loader_target()->GetResponseInfo(loader); | 370 result->set_host_resource( |
| 371 ppb_url_loader_target()->GetResponseInfo(loader.host_resource())); |
| 346 } | 372 } |
| 347 | 373 |
| 348 void PPB_URLLoader_Proxy::OnMsgReadResponseBody( | 374 void PPB_URLLoader_Proxy::OnMsgReadResponseBody( |
| 349 PP_Resource loader, | 375 PP_Instance instance, |
| 376 SerializedResource loader, |
| 350 int32_t bytes_to_read) { | 377 int32_t bytes_to_read) { |
| 351 // The plugin could be sending us malicious messages, don't accept negative | 378 // The plugin could be sending us malicious messages, don't accept negative |
| 352 // sizes. | 379 // sizes. |
| 353 if (bytes_to_read < 0) { | 380 if (bytes_to_read < 0) { |
| 354 // TODO(brettw) kill plugin. | 381 // TODO(brettw) kill plugin. |
| 355 bytes_to_read = 0; | 382 bytes_to_read = 0; |
| 356 } | 383 } |
| 357 | 384 |
| 358 // This heap object will get deleted by the callback handler. | 385 // This heap object will get deleted by the callback handler. |
| 359 // TODO(brettw) this will be leaked if the plugin closes the resource! | 386 // TODO(brettw) this will be leaked if the plugin closes the resource! |
| 360 // (Also including the plugin unloading and having the resource implicitly | 387 // (Also including the plugin unloading and having the resource implicitly |
| 361 // destroyed. Depending on the cleanup ordering, we may not need the weak | 388 // destroyed. Depending on the cleanup ordering, we may not need the weak |
| 362 // pointer here.) | 389 // pointer here.) |
| 363 ReadCallbackInfo* info = new ReadCallbackInfo; | 390 ReadCallbackInfo* info = new ReadCallbackInfo; |
| 364 info->pp_resource = loader; | 391 info->instance = instance; |
| 392 info->resource = loader; |
| 393 // TODO(brettw) have a way to check for out-of-memory. |
| 365 info->read_buffer.resize(bytes_to_read); | 394 info->read_buffer.resize(bytes_to_read); |
| 366 | 395 |
| 367 CompletionCallback callback = callback_factory_.NewCallback( | 396 CompletionCallback callback = callback_factory_.NewCallback( |
| 368 &PPB_URLLoader_Proxy::OnReadCallback, info); | 397 &PPB_URLLoader_Proxy::OnReadCallback, info); |
| 369 | 398 |
| 370 int32_t result = ppb_url_loader_target()->ReadResponseBody( | 399 int32_t result = ppb_url_loader_target()->ReadResponseBody( |
| 371 loader, const_cast<char*>(info->read_buffer.c_str()), bytes_to_read, | 400 loader.host_resource(), const_cast<char*>(info->read_buffer.c_str()), |
| 372 callback.pp_completion_callback()); | 401 bytes_to_read, callback.pp_completion_callback()); |
| 373 if (result != PP_ERROR_WOULDBLOCK) { | 402 if (result != PP_ERROR_WOULDBLOCK) { |
| 374 // Send error (or perhaps success for synchronous reads) back to plugin. | 403 // Send error (or perhaps success for synchronous reads) back to plugin. |
| 375 // The callback function is already set up to do this and also delete the | 404 // The callback function is already set up to do this and also delete the |
| 376 // callback info. | 405 // callback info. |
| 377 callback.Run(result); | 406 callback.Run(result); |
| 378 } | 407 } |
| 379 } | 408 } |
| 380 | 409 |
| 381 void PPB_URLLoader_Proxy::OnMsgFinishStreamingToFile( | 410 void PPB_URLLoader_Proxy::OnMsgFinishStreamingToFile( |
| 382 PP_Resource loader, | 411 SerializedResource loader, |
| 383 uint32_t serialized_callback) { | 412 uint32_t serialized_callback) { |
| 384 PP_CompletionCallback callback = ReceiveCallback(serialized_callback); | 413 PP_CompletionCallback callback = ReceiveCallback(serialized_callback); |
| 385 int32_t result = ppb_url_loader_target()->FinishStreamingToFile( | 414 int32_t result = ppb_url_loader_target()->FinishStreamingToFile( |
| 386 loader, callback); | 415 loader.host_resource(), callback); |
| 387 if (result != PP_ERROR_WOULDBLOCK) | 416 if (result != PP_ERROR_WOULDBLOCK) |
| 388 PP_RunCompletionCallback(&callback, result); | 417 PP_RunCompletionCallback(&callback, result); |
| 389 } | 418 } |
| 390 | 419 |
| 391 void PPB_URLLoader_Proxy::OnMsgClose(PP_Resource loader) { | 420 void PPB_URLLoader_Proxy::OnMsgClose(SerializedResource loader) { |
| 392 ppb_url_loader_target()->Close(loader); | 421 ppb_url_loader_target()->Close(loader.host_resource()); |
| 393 } | 422 } |
| 394 | 423 |
| 424 // Called in the Plugin. |
| 395 void PPB_URLLoader_Proxy::OnMsgUpdateProgress( | 425 void PPB_URLLoader_Proxy::OnMsgUpdateProgress( |
| 396 PP_Resource resource, | 426 const PPBURLLoader_UpdateProgress_Params& params) { |
| 397 int64_t bytes_sent, | 427 PP_Resource plugin_resource = |
| 398 int64_t total_bytes_to_be_sent, | 428 PluginResourceTracker::GetInstance()->PluginResourceForHostResource( |
| 399 int64_t bytes_received, | 429 params.instance, params.resource); |
| 400 int64_t total_bytes_to_be_received) { | 430 if (!plugin_resource) |
| 401 URLLoader* object = PluginResource::GetAs<URLLoader>(resource); | |
| 402 if (!object) { | |
| 403 NOTREACHED(); | |
| 404 return; | 431 return; |
| 405 } | 432 URLLoader* object = PluginResource::GetAs<URLLoader>(plugin_resource); |
| 433 if (!object) |
| 434 return; |
| 406 | 435 |
| 407 object->bytes_sent_ = bytes_sent; | 436 object->bytes_sent_ = params.bytes_sent; |
| 408 object->total_bytes_to_be_sent_ = total_bytes_to_be_sent; | 437 object->total_bytes_to_be_sent_ = params.total_bytes_to_be_sent; |
| 409 object->bytes_received_ = bytes_received; | 438 object->bytes_received_ = params.bytes_received; |
| 410 object->total_bytes_to_be_received_ = total_bytes_to_be_received; | 439 object->total_bytes_to_be_received_ = params.total_bytes_to_be_received; |
| 411 } | 440 } |
| 412 | 441 |
| 413 void PPB_URLLoader_Proxy::OnMsgReadResponseBodyAck(PP_Resource pp_resource, | 442 // Called in the Plugin. |
| 414 int32 result, | 443 void PPB_URLLoader_Proxy::OnMsgReadResponseBodyAck( |
| 415 const std::string& data) { | 444 PP_Instance instance, |
| 416 URLLoader* object = PluginResource::GetAs<URLLoader>(pp_resource); | 445 SerializedResource host_resource, |
| 417 if (!object) { | 446 int32 result, |
| 418 NOTREACHED(); | 447 const std::string& data) { |
| 448 PP_Resource plugin_resource = |
| 449 PluginResourceTracker::GetInstance()->PluginResourceForHostResource( |
| 450 instance, host_resource); |
| 451 if (!plugin_resource) |
| 419 return; | 452 return; |
| 420 } | 453 URLLoader* object = PluginResource::GetAs<URLLoader>(plugin_resource); |
| 454 if (!object) |
| 455 return; |
| 421 | 456 |
| 422 if (!object->current_read_callback_.func || !object->current_read_buffer_) { | 457 if (!object->current_read_callback_.func || !object->current_read_buffer_) { |
| 423 NOTREACHED(); | 458 NOTREACHED(); |
| 424 return; | 459 return; |
| 425 } | 460 } |
| 426 | 461 |
| 427 // In the error case, the string will be empty, so we can always just copy | 462 // In the error case, the string will be empty, so we can always just copy |
| 428 // out of it before issuing the callback. | 463 // out of it before issuing the callback. |
| 429 memcpy(object->current_read_buffer_, data.c_str(), data.length()); | 464 memcpy(object->current_read_buffer_, data.c_str(), data.length()); |
| 430 | 465 |
| 431 // The plugin should be able to make a new request from their callback, so | 466 // The plugin should be able to make a new request from their callback, so |
| 432 // we have to clear our copy first. | 467 // we have to clear our copy first. |
| 433 PP_CompletionCallback temp_callback = object->current_read_callback_; | 468 PP_CompletionCallback temp_callback = object->current_read_callback_; |
| 434 object->current_read_callback_ = PP_BlockUntilComplete(); | 469 object->current_read_callback_ = PP_BlockUntilComplete(); |
| 435 object->current_read_buffer_ = NULL; | 470 object->current_read_buffer_ = NULL; |
| 436 PP_RunCompletionCallback(&temp_callback, result); | 471 PP_RunCompletionCallback(&temp_callback, result); |
| 437 } | 472 } |
| 438 | 473 |
| 439 void PPB_URLLoader_Proxy::OnReadCallback(int32_t result, | 474 void PPB_URLLoader_Proxy::OnReadCallback(int32_t result, |
| 440 ReadCallbackInfo* info) { | 475 ReadCallbackInfo* info) { |
| 441 int32_t bytes_read = 0; | 476 int32_t bytes_read = 0; |
| 442 if (result > 0) | 477 if (result > 0) |
| 443 bytes_read = result; // Positive results indicate bytes read. | 478 bytes_read = result; // Positive results indicate bytes read. |
| 444 info->read_buffer.resize(bytes_read); | 479 info->read_buffer.resize(bytes_read); |
| 445 | 480 |
| 446 dispatcher()->Send(new PpapiMsg_PPBURLLoader_ReadResponseBody_Ack( | 481 dispatcher()->Send(new PpapiMsg_PPBURLLoader_ReadResponseBody_Ack( |
| 447 INTERFACE_ID_PPB_URL_LOADER, info->pp_resource, | 482 INTERFACE_ID_PPB_URL_LOADER, info->instance, info->resource, |
| 448 result, info->read_buffer)); | 483 result, info->read_buffer)); |
| 449 | 484 |
| 450 delete info; | 485 delete info; |
| 451 } | 486 } |
| 452 | 487 |
| 453 // PPB_URLLoaderTrusted_Proxy -------------------------------------------------- | 488 // PPB_URLLoaderTrusted_Proxy -------------------------------------------------- |
| 454 | 489 |
| 455 PPB_URLLoaderTrusted_Proxy::PPB_URLLoaderTrusted_Proxy( | 490 PPB_URLLoaderTrusted_Proxy::PPB_URLLoaderTrusted_Proxy( |
| 456 Dispatcher* dispatcher, | 491 Dispatcher* dispatcher, |
| 457 const void* target_interface) | 492 const void* target_interface) |
| (...skipping 15 matching lines...) Expand all Loading... |
| 473 bool handled = true; | 508 bool handled = true; |
| 474 IPC_BEGIN_MESSAGE_MAP(PPB_URLLoaderTrusted_Proxy, msg) | 509 IPC_BEGIN_MESSAGE_MAP(PPB_URLLoaderTrusted_Proxy, msg) |
| 475 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBURLLoaderTrusted_GrantUniversalAccess, | 510 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBURLLoaderTrusted_GrantUniversalAccess, |
| 476 OnMsgGrantUniversalAccess) | 511 OnMsgGrantUniversalAccess) |
| 477 IPC_MESSAGE_UNHANDLED(handled = false) | 512 IPC_MESSAGE_UNHANDLED(handled = false) |
| 478 IPC_END_MESSAGE_MAP(); | 513 IPC_END_MESSAGE_MAP(); |
| 479 // TODO(brettw) handle bad messages! | 514 // TODO(brettw) handle bad messages! |
| 480 return handled; | 515 return handled; |
| 481 } | 516 } |
| 482 | 517 |
| 483 void PPB_URLLoaderTrusted_Proxy::OnMsgGrantUniversalAccess(PP_Resource loader) { | 518 void PPB_URLLoaderTrusted_Proxy::OnMsgGrantUniversalAccess( |
| 484 ppb_url_loader_trusted_target()->GrantUniversalAccess(loader); | 519 SerializedResource loader) { |
| 520 ppb_url_loader_trusted_target()->GrantUniversalAccess(loader.host_resource()); |
| 485 } | 521 } |
| 486 | 522 |
| 487 } // namespace proxy | 523 } // namespace proxy |
| 488 } // namespace pp | 524 } // namespace pp |
| OLD | NEW |