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

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

Issue 6334016: Refactor PPAPI proxy resource handling to maintain which host they came from,... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 10 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) 2010 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_audio_proxy.h" 5 #include "ppapi/proxy/ppb_audio_proxy.h"
6 6
7 #include "base/threading/simple_thread.h" 7 #include "base/threading/simple_thread.h"
8 #include "ppapi/c/pp_errors.h" 8 #include "ppapi/c/pp_errors.h"
9 #include "ppapi/c/ppb_audio.h" 9 #include "ppapi/c/ppb_audio.h"
10 #include "ppapi/c/trusted/ppb_audio_trusted.h" 10 #include "ppapi/c/trusted/ppb_audio_trusted.h"
11 #include "ppapi/proxy/interface_id.h" 11 #include "ppapi/proxy/interface_id.h"
12 #include "ppapi/proxy/plugin_dispatcher.h" 12 #include "ppapi/proxy/plugin_dispatcher.h"
13 #include "ppapi/proxy/plugin_resource.h" 13 #include "ppapi/proxy/plugin_resource.h"
14 #include "ppapi/proxy/ppapi_messages.h" 14 #include "ppapi/proxy/ppapi_messages.h"
15 #include "ppapi/shared_impl/audio_impl.h" 15 #include "ppapi/shared_impl/audio_impl.h"
16 16
17 namespace pp { 17 namespace pp {
18 namespace proxy { 18 namespace proxy {
19 19
20 class Audio : public PluginResource, public pp::shared_impl::AudioImpl { 20 class Audio : public PluginResource, public pp::shared_impl::AudioImpl {
21 public: 21 public:
22 Audio(PP_Instance instance, 22 Audio(PP_Instance instance,
23 SerializedResource audio_id,
23 PP_Resource config_id, 24 PP_Resource config_id,
24 PPB_Audio_Callback callback, 25 PPB_Audio_Callback callback,
25 void* user_data) 26 void* user_data)
26 : PluginResource(instance), 27 : PluginResource(instance, audio_id),
27 config_(config_id) { 28 config_(config_id) {
28 SetCallback(callback, user_data); 29 SetCallback(callback, user_data);
29 PluginResourceTracker::GetInstance()->AddRefResource(config_); 30 PluginResourceTracker::GetInstance()->AddRefResource(config_);
30 } 31 }
31 virtual ~Audio() { 32 virtual ~Audio() {
32 PluginResourceTracker::GetInstance()->ReleaseResource(config_); 33 PluginResourceTracker::GetInstance()->ReleaseResource(config_);
33 } 34 }
34 35
35 // Resource overrides. 36 // Resource overrides.
36 virtual Audio* AsAudio() { return this; } 37 virtual Audio* AsAudio() { return this; }
37 38
38 PP_Resource config() const { return config_; } 39 PP_Resource config() const { return config_; }
39 40
40 void StartPlayback(PP_Resource resource) { 41 void StartPlayback(PP_Resource resource) {
41 if (playing()) 42 if (playing())
42 return; 43 return;
43 SetStartPlaybackState(); 44 SetStartPlaybackState();
44 PluginDispatcher::GetForInstance(instance())->Send( 45 PluginDispatcher::GetForInstance(instance())->Send(
45 new PpapiHostMsg_PPBAudio_StartOrStop( 46 new PpapiHostMsg_PPBAudio_StartOrStop(
46 INTERFACE_ID_PPB_AUDIO, resource, true)); 47 INTERFACE_ID_PPB_AUDIO, host_resource(), true));
47 } 48 }
48 49
49 void StopPlayback(PP_Resource resource) { 50 void StopPlayback(PP_Resource resource) {
50 if (!playing()) 51 if (!playing())
51 return; 52 return;
52 PluginDispatcher::GetForInstance(instance())->Send( 53 PluginDispatcher::GetForInstance(instance())->Send(
53 new PpapiHostMsg_PPBAudio_StartOrStop( 54 new PpapiHostMsg_PPBAudio_StartOrStop(
54 INTERFACE_ID_PPB_AUDIO, resource, false)); 55 INTERFACE_ID_PPB_AUDIO, host_resource(), false));
55 SetStopPlaybackState(); 56 SetStopPlaybackState();
56 } 57 }
57 58
58 private: 59 private:
59 PP_Resource config_; 60 PP_Resource config_;
60 61
61 DISALLOW_COPY_AND_ASSIGN(Audio); 62 DISALLOW_COPY_AND_ASSIGN(Audio);
62 }; 63 };
63 64
65 // Closure data for the AudioChannelConnected callback.
66 struct AudioChannelConnectedTracking {
67 PP_Instance instance;
68 SerializedResource resource;
69 };
70
64 namespace { 71 namespace {
65 72
66 PP_Resource Create(PP_Instance instance_id, 73 PP_Resource Create(PP_Instance instance_id,
67 PP_Resource config_id, 74 PP_Resource config_id,
68 PPB_Audio_Callback callback, 75 PPB_Audio_Callback callback,
69 void* user_data) { 76 void* user_data) {
70 PP_Resource result; 77 PluginResource* config = PluginResourceTracker::GetInstance()->
71 PluginDispatcher::Get()->Send(new PpapiHostMsg_PPBAudio_Create( 78 GetResourceObject(config_id);
72 INTERFACE_ID_PPB_AUDIO, instance_id, config_id, &result)); 79 if (!config)
73 if (!result)
74 return 0; 80 return 0;
75 81
76 linked_ptr<Audio> object(new Audio(instance_id, config_id, 82 SerializedResource result;
83 PluginDispatcher::Get()->Send(new PpapiHostMsg_PPBAudio_Create(
84 INTERFACE_ID_PPB_AUDIO, instance_id, config->host_resource(), &result));
85 if (result.is_null())
86 return 0;
87
88 linked_ptr<Audio> object(new Audio(instance_id, result, config_id,
77 callback, user_data)); 89 callback, user_data));
78 PluginResourceTracker::GetInstance()->AddResource(result, object); 90 return PluginResourceTracker::GetInstance()->AddResource(object);
79 return result;
80 } 91 }
81 92
82 PP_Bool IsAudio(PP_Resource resource) { 93 PP_Bool IsAudio(PP_Resource resource) {
83 Audio* object = PluginResource::GetAs<Audio>(resource); 94 Audio* object = PluginResource::GetAs<Audio>(resource);
84 return BoolToPPBool(!!object); 95 return BoolToPPBool(!!object);
85 } 96 }
86 97
87 PP_Resource GetCurrentConfiguration(PP_Resource audio_id) { 98 PP_Resource GetCurrentConfiguration(PP_Resource audio_id) {
88 Audio* object = PluginResource::GetAs<Audio>(audio_id); 99 Audio* object = PluginResource::GetAs<Audio>(audio_id);
89 if (!object) 100 if (!object)
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBAudio_StartOrStop, 154 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBAudio_StartOrStop,
144 OnMsgStartOrStop) 155 OnMsgStartOrStop)
145 IPC_MESSAGE_HANDLER(PpapiMsg_PPBAudio_NotifyAudioStreamCreated, 156 IPC_MESSAGE_HANDLER(PpapiMsg_PPBAudio_NotifyAudioStreamCreated,
146 OnMsgNotifyAudioStreamCreated) 157 OnMsgNotifyAudioStreamCreated)
147 IPC_MESSAGE_UNHANDLED(handled = false) 158 IPC_MESSAGE_UNHANDLED(handled = false)
148 IPC_END_MESSAGE_MAP() 159 IPC_END_MESSAGE_MAP()
149 return handled; 160 return handled;
150 } 161 }
151 162
152 void PPB_Audio_Proxy::OnMsgCreate(PP_Instance instance_id, 163 void PPB_Audio_Proxy::OnMsgCreate(PP_Instance instance_id,
153 PP_Resource config_id, 164 SerializedResource config_id,
154 PP_Resource* result) { 165 SerializedResource* result) {
155 const PPB_AudioTrusted* audio_trusted = 166 const PPB_AudioTrusted* audio_trusted =
156 reinterpret_cast<const PPB_AudioTrusted*>( 167 reinterpret_cast<const PPB_AudioTrusted*>(
157 dispatcher()->GetLocalInterface(PPB_AUDIO_TRUSTED_INTERFACE)); 168 dispatcher()->GetLocalInterface(PPB_AUDIO_TRUSTED_INTERFACE));
158 if (!audio_trusted) { 169 if (!audio_trusted)
159 *result = 0;
160 return;
161 }
162
163 *result = audio_trusted->CreateTrusted(instance_id);
164 if (!result)
165 return; 170 return;
166 171
172 result->set_host_resource(audio_trusted->CreateTrusted(instance_id));
173 if (result->is_null())
174 return;
175
176 // The callback will be in charge of deleting this pointer.
177 AudioChannelConnectedTracking* tracking = new AudioChannelConnectedTracking;
178 tracking->instance = instance_id;
179 tracking->resource = *result;
167 CompletionCallback callback = callback_factory_.NewCallback( 180 CompletionCallback callback = callback_factory_.NewCallback(
168 &PPB_Audio_Proxy::AudioChannelConnected, *result); 181 &PPB_Audio_Proxy::AudioChannelConnected, tracking);
169 int32_t open_error = audio_trusted->Open(*result, config_id, 182 int32_t open_error = audio_trusted->Open(result->host_resource(),
183 config_id.host_resource(),
170 callback.pp_completion_callback()); 184 callback.pp_completion_callback());
171 if (open_error != PP_ERROR_WOULDBLOCK) 185 if (open_error != PP_ERROR_WOULDBLOCK)
172 callback.Run(open_error); 186 callback.Run(open_error);
173 } 187 }
174 188
175 void PPB_Audio_Proxy::OnMsgStartOrStop(PP_Resource audio_id, bool play) { 189 void PPB_Audio_Proxy::OnMsgStartOrStop(SerializedResource audio_id, bool play) {
176 if (play) 190 if (play)
177 ppb_audio_target()->StartPlayback(audio_id); 191 ppb_audio_target()->StartPlayback(audio_id.host_resource());
178 else 192 else
179 ppb_audio_target()->StopPlayback(audio_id); 193 ppb_audio_target()->StopPlayback(audio_id.host_resource());
180 } 194 }
181 195
196 // Processed in the plugin (message from host).
182 void PPB_Audio_Proxy::OnMsgNotifyAudioStreamCreated( 197 void PPB_Audio_Proxy::OnMsgNotifyAudioStreamCreated(
183 PP_Resource audio_id, 198 const PPBAudio_NotifyAudioStreamCreated_Params& params) {
184 int32_t result_code, 199 PP_Resource plugin_resource =
185 IPC::PlatformFileForTransit socket_handle, 200 PluginResourceTracker::GetInstance()->PluginResourceForHostResource(
186 base::SharedMemoryHandle handle, 201 params.instance, params.audio_id);
187 uint32_t length) { 202 Audio* object = plugin_resource ?
188 Audio* object = PluginResource::GetAs<Audio>(audio_id); 203 PluginResource::GetAs<Audio>(plugin_resource) : NULL;
189 if (!object || result_code != PP_OK) { 204 if (!object || params.result_code != PP_OK) {
190 // The caller may still have given us these handles in the failure case. 205 // The caller may still have given us these handles in the failure case.
191 // The easiest way to clean these up is to just put them in the objects 206 // The easiest way to clean these up is to just put them in the objects
192 // and then close them. This failure case is not performance critical. 207 // and then close them. This failure case is not performance critical.
193 base::SyncSocket temp_socket( 208 base::SyncSocket temp_socket(
194 IPC::PlatformFileForTransitToPlatformFile(socket_handle)); 209 IPC::PlatformFileForTransitToPlatformFile(params.socket_handle));
195 base::SharedMemory temp_mem(handle, false); 210 base::SharedMemory temp_mem(params.handle, false);
196 return; 211 return;
197 } 212 }
198 object->SetStreamInfo( 213 object->SetStreamInfo(
199 handle, length, IPC::PlatformFileForTransitToPlatformFile(socket_handle)); 214 params.handle, params.length,
215 IPC::PlatformFileForTransitToPlatformFile(params.socket_handle));
200 } 216 }
201 217
202 void PPB_Audio_Proxy::AudioChannelConnected(int32_t result, 218 void PPB_Audio_Proxy::AudioChannelConnected(
203 PP_Resource resource) { 219 int32_t result,
220 AudioChannelConnectedTracking* tracking) {
221 // Ownership of the pointer was transferred to us.
222 scoped_ptr<AudioChannelConnectedTracking> tracking_deleter(tracking);
223
204 IPC::PlatformFileForTransit socket_handle = 224 IPC::PlatformFileForTransit socket_handle =
205 IPC::InvalidPlatformFileForTransit(); 225 IPC::InvalidPlatformFileForTransit();
206 #if defined(OS_WIN) 226 #if defined(OS_WIN)
207 base::SharedMemoryHandle shared_memory = NULL; 227 base::SharedMemoryHandle shared_memory = NULL;
208 #elif defined(OS_POSIX) 228 #elif defined(OS_POSIX)
209 base::SharedMemoryHandle shared_memory(-1, false); 229 base::SharedMemoryHandle shared_memory(-1, false);
210 #else 230 #else
211 #error Not implemented. 231 #error Not implemented.
212 #endif 232 #endif
213 uint32_t shared_memory_length = 0; 233 uint32_t shared_memory_length = 0;
214 234
215 int32_t result_code = result; 235 int32_t result_code = result;
216 if (result_code == PP_OK) { 236 if (result_code == PP_OK) {
217 result_code = GetAudioConnectedHandles(resource, &socket_handle, 237 result_code = GetAudioConnectedHandles(tracking->resource, &socket_handle,
218 &shared_memory, 238 &shared_memory,
219 &shared_memory_length); 239 &shared_memory_length);
220 } 240 }
221 241
222 // Send all the values, even on error. This simplifies some of our cleanup 242 // Send all the values, even on error. This simplifies some of our cleanup
223 // code since the handles will be in the other process and could be 243 // code since the handles will be in the other process and could be
224 // inconvenient to clean up. Our IPC code will automatically handle this for 244 // inconvenient to clean up. Our IPC code will automatically handle this for
225 // us, as long as the remote side always closes the handles it receives 245 // us, as long as the remote side always closes the handles it receives
226 // (in OnMsgNotifyAudioStreamCreated), even in the failure case. 246 // (in OnMsgNotifyAudioStreamCreated), even in the failure case.
247 PPBAudio_NotifyAudioStreamCreated_Params params;
248 params.instance = tracking->instance;
249 params.audio_id = tracking->resource;
250 params.result_code = result;
251 params.socket_handle = socket_handle;
252 params.handle = shared_memory;
253 params.length = shared_memory_length;
227 dispatcher()->Send(new PpapiMsg_PPBAudio_NotifyAudioStreamCreated( 254 dispatcher()->Send(new PpapiMsg_PPBAudio_NotifyAudioStreamCreated(
228 INTERFACE_ID_PPB_AUDIO, resource, result_code, socket_handle, 255 INTERFACE_ID_PPB_AUDIO, params));
229 shared_memory, shared_memory_length));
230 } 256 }
231 257
232 int32_t PPB_Audio_Proxy::GetAudioConnectedHandles( 258 int32_t PPB_Audio_Proxy::GetAudioConnectedHandles(
233 PP_Resource resource, 259 SerializedResource resource,
234 IPC::PlatformFileForTransit* foreign_socket_handle, 260 IPC::PlatformFileForTransit* foreign_socket_handle,
235 base::SharedMemoryHandle* foreign_shared_memory_handle, 261 base::SharedMemoryHandle* foreign_shared_memory_handle,
236 uint32_t* shared_memory_length) { 262 uint32_t* shared_memory_length) {
237 // Get the trusted audio interface which will give us the handles. 263 // Get the trusted audio interface which will give us the handles.
238 const PPB_AudioTrusted* audio_trusted = 264 const PPB_AudioTrusted* audio_trusted =
239 reinterpret_cast<const PPB_AudioTrusted*>( 265 reinterpret_cast<const PPB_AudioTrusted*>(
240 dispatcher()->GetLocalInterface(PPB_AUDIO_TRUSTED_INTERFACE)); 266 dispatcher()->GetLocalInterface(PPB_AUDIO_TRUSTED_INTERFACE));
241 if (!audio_trusted) 267 if (!audio_trusted)
242 return PP_ERROR_NOINTERFACE; 268 return PP_ERROR_NOINTERFACE;
243 269
244 // Get the socket handle for signaling. 270 // Get the socket handle for signaling.
245 int32_t socket_handle; 271 int32_t socket_handle;
246 int32_t result = audio_trusted->GetSyncSocket(resource, &socket_handle); 272 int32_t result = audio_trusted->GetSyncSocket(resource.host_resource(),
273 &socket_handle);
247 if (result != PP_OK) 274 if (result != PP_OK)
248 return result; 275 return result;
249 276
250 #if defined(OS_WIN) 277 #if defined(OS_WIN)
251 // On Windows, duplicate the socket into the plugin process, this will 278 // On Windows, duplicate the socket into the plugin process, this will
252 // automatically close the source handle. 279 // automatically close the source handle.
253 ::DuplicateHandle( 280 ::DuplicateHandle(
254 GetCurrentProcess(), 281 GetCurrentProcess(),
255 reinterpret_cast<HANDLE>(static_cast<intptr_t>(socket_handle)), 282 reinterpret_cast<HANDLE>(static_cast<intptr_t>(socket_handle)),
256 dispatcher()->remote_process_handle(), foreign_socket_handle, 283 dispatcher()->remote_process_handle(), foreign_socket_handle,
257 STANDARD_RIGHTS_REQUIRED | FILE_MAP_READ | FILE_MAP_WRITE, 284 STANDARD_RIGHTS_REQUIRED | FILE_MAP_READ | FILE_MAP_WRITE,
258 FALSE, DUPLICATE_CLOSE_SOURCE); 285 FALSE, DUPLICATE_CLOSE_SOURCE);
259 #else 286 #else
260 // On Posix, the socket handle will be auto-duplicated when we send the 287 // On Posix, the socket handle will be auto-duplicated when we send the
261 // FileDescriptor. Set AutoClose since we don't need the handle any more. 288 // FileDescriptor. Set AutoClose since we don't need the handle any more.
262 *foreign_socket_handle = base::FileDescriptor(socket_handle, true); 289 *foreign_socket_handle = base::FileDescriptor(socket_handle, true);
263 #endif 290 #endif
264 291
265 // Get the shared memory for the buffer. 292 // Get the shared memory for the buffer.
266 // TODO(brettw) remove the reinterpret cast when the interface is updated. 293 // TODO(brettw) remove the reinterpret cast when the interface is updated.
267 int shared_memory_handle; 294 int shared_memory_handle;
268 result = audio_trusted->GetSharedMemory(resource, &shared_memory_handle, 295 result = audio_trusted->GetSharedMemory(resource.host_resource(),
269 shared_memory_length); 296 &shared_memory_handle,
297 shared_memory_length);
270 if (result != PP_OK) 298 if (result != PP_OK)
271 return result; 299 return result;
272 300
273 base::SharedMemory shared_memory( 301 base::SharedMemory shared_memory(
274 #if defined(OS_WIN) 302 #if defined(OS_WIN)
275 reinterpret_cast<HANDLE>(static_cast<intptr_t>(shared_memory_handle)), 303 reinterpret_cast<HANDLE>(static_cast<intptr_t>(shared_memory_handle)),
276 #else 304 #else
277 base::FileDescriptor(shared_memory_handle, false), 305 base::FileDescriptor(shared_memory_handle, false),
278 #endif 306 #endif
279 false); 307 false);
280 308
281 // Duplicate the shared memory to the plugin process. This will automatically 309 // Duplicate the shared memory to the plugin process. This will automatically
282 // close the source handle. 310 // close the source handle.
283 if (!shared_memory.GiveToProcess(dispatcher()->remote_process_handle(), 311 if (!shared_memory.GiveToProcess(dispatcher()->remote_process_handle(),
284 foreign_shared_memory_handle)) 312 foreign_shared_memory_handle))
285 return PP_ERROR_FAILED; 313 return PP_ERROR_FAILED;
286 314
287 return PP_OK; 315 return PP_OK;
288 } 316 }
289 317
290 } // namespace proxy 318 } // namespace proxy
291 } // namespace pp 319 } // namespace pp
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698