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

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(const HostResource& audio_id,
23 PP_Resource config_id, 23 PP_Resource config_id,
24 PPB_Audio_Callback callback, 24 PPB_Audio_Callback callback,
25 void* user_data) 25 void* user_data)
26 : PluginResource(instance), 26 : PluginResource(audio_id),
27 config_(config_id) { 27 config_(config_id) {
28 SetCallback(callback, user_data); 28 SetCallback(callback, user_data);
29 PluginResourceTracker::GetInstance()->AddRefResource(config_); 29 PluginResourceTracker::GetInstance()->AddRefResource(config_);
30 } 30 }
31 virtual ~Audio() { 31 virtual ~Audio() {
32 PluginResourceTracker::GetInstance()->ReleaseResource(config_); 32 PluginResourceTracker::GetInstance()->ReleaseResource(config_);
33 } 33 }
34 34
35 // Resource overrides. 35 // Resource overrides.
36 virtual Audio* AsAudio() { return this; } 36 virtual Audio* AsAudio() { return this; }
37 37
38 PP_Resource config() const { return config_; } 38 PP_Resource config() const { return config_; }
39 39
40 void StartPlayback(PP_Resource resource) { 40 void StartPlayback(PP_Resource resource) {
41 if (playing()) 41 if (playing())
42 return; 42 return;
43 SetStartPlaybackState(); 43 SetStartPlaybackState();
44 PluginDispatcher::GetForInstance(instance())->Send( 44 PluginDispatcher::GetForInstance(instance())->Send(
45 new PpapiHostMsg_PPBAudio_StartOrStop( 45 new PpapiHostMsg_PPBAudio_StartOrStop(
46 INTERFACE_ID_PPB_AUDIO, resource, true)); 46 INTERFACE_ID_PPB_AUDIO, host_resource(), true));
47 } 47 }
48 48
49 void StopPlayback(PP_Resource resource) { 49 void StopPlayback(PP_Resource resource) {
50 if (!playing()) 50 if (!playing())
51 return; 51 return;
52 PluginDispatcher::GetForInstance(instance())->Send( 52 PluginDispatcher::GetForInstance(instance())->Send(
53 new PpapiHostMsg_PPBAudio_StartOrStop( 53 new PpapiHostMsg_PPBAudio_StartOrStop(
54 INTERFACE_ID_PPB_AUDIO, resource, false)); 54 INTERFACE_ID_PPB_AUDIO, host_resource(), false));
55 SetStopPlaybackState(); 55 SetStopPlaybackState();
56 } 56 }
57 57
58 private: 58 private:
59 PP_Resource config_; 59 PP_Resource config_;
60 60
61 DISALLOW_COPY_AND_ASSIGN(Audio); 61 DISALLOW_COPY_AND_ASSIGN(Audio);
62 }; 62 };
63 63
64 // Closure data for the AudioChannelConnected callback.
65 struct AudioChannelConnectedTracking {
66 PP_Instance instance;
67 HostResource resource;
68 };
69
64 namespace { 70 namespace {
65 71
66 PP_Resource Create(PP_Instance instance_id, 72 PP_Resource Create(PP_Instance instance_id,
67 PP_Resource config_id, 73 PP_Resource config_id,
68 PPB_Audio_Callback callback, 74 PPB_Audio_Callback callback,
69 void* user_data) { 75 void* user_data) {
70 PP_Resource result; 76 PluginResource* config = PluginResourceTracker::GetInstance()->
71 PluginDispatcher::Get()->Send(new PpapiHostMsg_PPBAudio_Create( 77 GetResourceObject(config_id);
72 INTERFACE_ID_PPB_AUDIO, instance_id, config_id, &result)); 78 if (!config)
73 if (!result)
74 return 0; 79 return 0;
75 80
76 linked_ptr<Audio> object(new Audio(instance_id, config_id, 81 HostResource result;
77 callback, user_data)); 82 PluginDispatcher::Get()->Send(new PpapiHostMsg_PPBAudio_Create(
78 PluginResourceTracker::GetInstance()->AddResource(result, object); 83 INTERFACE_ID_PPB_AUDIO, instance_id, config->host_resource(), &result));
79 return result; 84 if (result.is_null())
85 return 0;
86
87 linked_ptr<Audio> object(new Audio(result, config_id, callback, user_data));
88 return PluginResourceTracker::GetInstance()->AddResource(object);
80 } 89 }
81 90
82 PP_Bool IsAudio(PP_Resource resource) { 91 PP_Bool IsAudio(PP_Resource resource) {
83 Audio* object = PluginResource::GetAs<Audio>(resource); 92 Audio* object = PluginResource::GetAs<Audio>(resource);
84 return BoolToPPBool(!!object); 93 return BoolToPPBool(!!object);
85 } 94 }
86 95
87 PP_Resource GetCurrentConfiguration(PP_Resource audio_id) { 96 PP_Resource GetCurrentConfiguration(PP_Resource audio_id) {
88 Audio* object = PluginResource::GetAs<Audio>(audio_id); 97 Audio* object = PluginResource::GetAs<Audio>(audio_id);
89 if (!object) 98 if (!object)
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBAudio_StartOrStop, 152 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBAudio_StartOrStop,
144 OnMsgStartOrStop) 153 OnMsgStartOrStop)
145 IPC_MESSAGE_HANDLER(PpapiMsg_PPBAudio_NotifyAudioStreamCreated, 154 IPC_MESSAGE_HANDLER(PpapiMsg_PPBAudio_NotifyAudioStreamCreated,
146 OnMsgNotifyAudioStreamCreated) 155 OnMsgNotifyAudioStreamCreated)
147 IPC_MESSAGE_UNHANDLED(handled = false) 156 IPC_MESSAGE_UNHANDLED(handled = false)
148 IPC_END_MESSAGE_MAP() 157 IPC_END_MESSAGE_MAP()
149 return handled; 158 return handled;
150 } 159 }
151 160
152 void PPB_Audio_Proxy::OnMsgCreate(PP_Instance instance_id, 161 void PPB_Audio_Proxy::OnMsgCreate(PP_Instance instance_id,
153 PP_Resource config_id, 162 const HostResource& config_id,
154 PP_Resource* result) { 163 HostResource* result) {
155 const PPB_AudioTrusted* audio_trusted = 164 const PPB_AudioTrusted* audio_trusted =
156 reinterpret_cast<const PPB_AudioTrusted*>( 165 reinterpret_cast<const PPB_AudioTrusted*>(
157 dispatcher()->GetLocalInterface(PPB_AUDIO_TRUSTED_INTERFACE)); 166 dispatcher()->GetLocalInterface(PPB_AUDIO_TRUSTED_INTERFACE));
158 if (!audio_trusted) { 167 if (!audio_trusted)
159 *result = 0;
160 return;
161 }
162
163 *result = audio_trusted->CreateTrusted(instance_id);
164 if (!result)
165 return; 168 return;
166 169
170 result->SetHostResource(instance_id,
171 audio_trusted->CreateTrusted(instance_id));
172 if (result->is_null())
173 return;
174
175 // The callback will be in charge of deleting this pointer.
176 AudioChannelConnectedTracking* tracking = new AudioChannelConnectedTracking;
177 tracking->instance = instance_id;
178 tracking->resource = *result;
167 CompletionCallback callback = callback_factory_.NewCallback( 179 CompletionCallback callback = callback_factory_.NewCallback(
168 &PPB_Audio_Proxy::AudioChannelConnected, *result); 180 &PPB_Audio_Proxy::AudioChannelConnected, tracking);
169 int32_t open_error = audio_trusted->Open(*result, config_id, 181 int32_t open_error = audio_trusted->Open(result->host_resource(),
182 config_id.host_resource(),
170 callback.pp_completion_callback()); 183 callback.pp_completion_callback());
171 if (open_error != PP_ERROR_WOULDBLOCK) 184 if (open_error != PP_ERROR_WOULDBLOCK)
172 callback.Run(open_error); 185 callback.Run(open_error);
173 } 186 }
174 187
175 void PPB_Audio_Proxy::OnMsgStartOrStop(PP_Resource audio_id, bool play) { 188 void PPB_Audio_Proxy::OnMsgStartOrStop(const HostResource& audio_id,
189 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.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 const HostResource& 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