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

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, 11 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_audio_proxy.h ('k') | ppapi/proxy/ppb_buffer_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) 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 namespace { 64 namespace {
65 65
66 PP_Resource Create(PP_Instance instance_id, 66 PP_Resource Create(PP_Instance instance_id,
67 PP_Resource config_id, 67 PP_Resource config_id,
68 PPB_Audio_Callback callback, 68 PPB_Audio_Callback callback,
69 void* user_data) { 69 void* user_data) {
70 PP_Resource result; 70 PluginResource* config = PluginResourceTracker::GetInstance()->
71 PluginDispatcher::Get()->Send(new PpapiHostMsg_PPBAudio_Create( 71 GetResourceObject(config_id);
72 INTERFACE_ID_PPB_AUDIO, instance_id, config_id, &result)); 72 if (!config)
73 if (!result)
74 return 0; 73 return 0;
75 74
76 linked_ptr<Audio> object(new Audio(instance_id, config_id, 75 HostResource result;
77 callback, user_data)); 76 PluginDispatcher::Get()->Send(new PpapiHostMsg_PPBAudio_Create(
78 PluginResourceTracker::GetInstance()->AddResource(result, object); 77 INTERFACE_ID_PPB_AUDIO, instance_id, config->host_resource(), &result));
79 return result; 78 if (result.is_null())
79 return 0;
80
81 linked_ptr<Audio> object(new Audio(result, config_id, callback, user_data));
82 return PluginResourceTracker::GetInstance()->AddResource(object);
80 } 83 }
81 84
82 PP_Bool IsAudio(PP_Resource resource) { 85 PP_Bool IsAudio(PP_Resource resource) {
83 Audio* object = PluginResource::GetAs<Audio>(resource); 86 Audio* object = PluginResource::GetAs<Audio>(resource);
84 return BoolToPPBool(!!object); 87 return BoolToPPBool(!!object);
85 } 88 }
86 89
87 PP_Resource GetCurrentConfiguration(PP_Resource audio_id) { 90 PP_Resource GetCurrentConfiguration(PP_Resource audio_id) {
88 Audio* object = PluginResource::GetAs<Audio>(audio_id); 91 Audio* object = PluginResource::GetAs<Audio>(audio_id);
89 if (!object) 92 if (!object)
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBAudio_StartOrStop, 146 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBAudio_StartOrStop,
144 OnMsgStartOrStop) 147 OnMsgStartOrStop)
145 IPC_MESSAGE_HANDLER(PpapiMsg_PPBAudio_NotifyAudioStreamCreated, 148 IPC_MESSAGE_HANDLER(PpapiMsg_PPBAudio_NotifyAudioStreamCreated,
146 OnMsgNotifyAudioStreamCreated) 149 OnMsgNotifyAudioStreamCreated)
147 IPC_MESSAGE_UNHANDLED(handled = false) 150 IPC_MESSAGE_UNHANDLED(handled = false)
148 IPC_END_MESSAGE_MAP() 151 IPC_END_MESSAGE_MAP()
149 return handled; 152 return handled;
150 } 153 }
151 154
152 void PPB_Audio_Proxy::OnMsgCreate(PP_Instance instance_id, 155 void PPB_Audio_Proxy::OnMsgCreate(PP_Instance instance_id,
153 PP_Resource config_id, 156 const HostResource& config_id,
154 PP_Resource* result) { 157 HostResource* result) {
155 const PPB_AudioTrusted* audio_trusted = 158 const PPB_AudioTrusted* audio_trusted =
156 reinterpret_cast<const PPB_AudioTrusted*>( 159 reinterpret_cast<const PPB_AudioTrusted*>(
157 dispatcher()->GetLocalInterface(PPB_AUDIO_TRUSTED_INTERFACE)); 160 dispatcher()->GetLocalInterface(PPB_AUDIO_TRUSTED_INTERFACE));
158 if (!audio_trusted) { 161 if (!audio_trusted)
159 *result = 0;
160 return; 162 return;
161 }
162 163
163 *result = audio_trusted->CreateTrusted(instance_id); 164 result->SetHostResource(instance_id,
164 if (!result) 165 audio_trusted->CreateTrusted(instance_id));
166 if (result->is_null())
165 return; 167 return;
166 168
167 CompletionCallback callback = callback_factory_.NewCallback( 169 CompletionCallback callback = callback_factory_.NewCallback(
168 &PPB_Audio_Proxy::AudioChannelConnected, *result); 170 &PPB_Audio_Proxy::AudioChannelConnected, *result);
169 int32_t open_error = audio_trusted->Open(*result, config_id, 171 int32_t open_error = audio_trusted->Open(result->host_resource(),
172 config_id.host_resource(),
170 callback.pp_completion_callback()); 173 callback.pp_completion_callback());
171 if (open_error != PP_ERROR_WOULDBLOCK) 174 if (open_error != PP_ERROR_WOULDBLOCK)
172 callback.Run(open_error); 175 callback.Run(open_error);
173 } 176 }
174 177
175 void PPB_Audio_Proxy::OnMsgStartOrStop(PP_Resource audio_id, bool play) { 178 void PPB_Audio_Proxy::OnMsgStartOrStop(const HostResource& audio_id,
179 bool play) {
176 if (play) 180 if (play)
177 ppb_audio_target()->StartPlayback(audio_id); 181 ppb_audio_target()->StartPlayback(audio_id.host_resource());
178 else 182 else
179 ppb_audio_target()->StopPlayback(audio_id); 183 ppb_audio_target()->StopPlayback(audio_id.host_resource());
180 } 184 }
181 185
186 // Processed in the plugin (message from host).
182 void PPB_Audio_Proxy::OnMsgNotifyAudioStreamCreated( 187 void PPB_Audio_Proxy::OnMsgNotifyAudioStreamCreated(
183 PP_Resource audio_id, 188 const PPBAudio_NotifyAudioStreamCreated_Params& params) {
184 int32_t result_code, 189 PP_Resource plugin_resource =
185 IPC::PlatformFileForTransit socket_handle, 190 PluginResourceTracker::GetInstance()->PluginResourceForHostResource(
186 base::SharedMemoryHandle handle, 191 params.audio_id);
187 uint32_t length) { 192 Audio* object = plugin_resource ?
188 Audio* object = PluginResource::GetAs<Audio>(audio_id); 193 PluginResource::GetAs<Audio>(plugin_resource) : NULL;
189 if (!object || result_code != PP_OK) { 194 if (!object || params.result_code != PP_OK) {
190 // The caller may still have given us these handles in the failure case. 195 // 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 196 // 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. 197 // and then close them. This failure case is not performance critical.
193 base::SyncSocket temp_socket( 198 base::SyncSocket temp_socket(
194 IPC::PlatformFileForTransitToPlatformFile(socket_handle)); 199 IPC::PlatformFileForTransitToPlatformFile(params.socket_handle));
195 base::SharedMemory temp_mem(handle, false); 200 base::SharedMemory temp_mem(params.handle, false);
196 return; 201 return;
197 } 202 }
198 object->SetStreamInfo( 203 object->SetStreamInfo(
199 handle, length, IPC::PlatformFileForTransitToPlatformFile(socket_handle)); 204 params.handle, params.length,
205 IPC::PlatformFileForTransitToPlatformFile(params.socket_handle));
200 } 206 }
201 207
202 void PPB_Audio_Proxy::AudioChannelConnected(int32_t result, 208 void PPB_Audio_Proxy::AudioChannelConnected(
203 PP_Resource resource) { 209 int32_t result,
210 const HostResource& resource) {
204 IPC::PlatformFileForTransit socket_handle = 211 IPC::PlatformFileForTransit socket_handle =
205 IPC::InvalidPlatformFileForTransit(); 212 IPC::InvalidPlatformFileForTransit();
206 #if defined(OS_WIN) 213 #if defined(OS_WIN)
207 base::SharedMemoryHandle shared_memory = NULL; 214 base::SharedMemoryHandle shared_memory = NULL;
208 #elif defined(OS_POSIX) 215 #elif defined(OS_POSIX)
209 base::SharedMemoryHandle shared_memory(-1, false); 216 base::SharedMemoryHandle shared_memory(-1, false);
210 #else 217 #else
211 #error Not implemented. 218 #error Not implemented.
212 #endif 219 #endif
213 uint32_t shared_memory_length = 0; 220 uint32_t shared_memory_length = 0;
214 221
215 int32_t result_code = result; 222 int32_t result_code = result;
216 if (result_code == PP_OK) { 223 if (result_code == PP_OK) {
217 result_code = GetAudioConnectedHandles(resource, &socket_handle, 224 result_code = GetAudioConnectedHandles(resource, &socket_handle,
218 &shared_memory, 225 &shared_memory,
219 &shared_memory_length); 226 &shared_memory_length);
220 } 227 }
221 228
222 // Send all the values, even on error. This simplifies some of our cleanup 229 // 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 230 // 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 231 // 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 232 // us, as long as the remote side always closes the handles it receives
226 // (in OnMsgNotifyAudioStreamCreated), even in the failure case. 233 // (in OnMsgNotifyAudioStreamCreated), even in the failure case.
234 PPBAudio_NotifyAudioStreamCreated_Params params;
235 params.audio_id = resource;
236 params.result_code = result;
237 params.socket_handle = socket_handle;
238 params.handle = shared_memory;
239 params.length = shared_memory_length;
227 dispatcher()->Send(new PpapiMsg_PPBAudio_NotifyAudioStreamCreated( 240 dispatcher()->Send(new PpapiMsg_PPBAudio_NotifyAudioStreamCreated(
228 INTERFACE_ID_PPB_AUDIO, resource, result_code, socket_handle, 241 INTERFACE_ID_PPB_AUDIO, params));
229 shared_memory, shared_memory_length));
230 } 242 }
231 243
232 int32_t PPB_Audio_Proxy::GetAudioConnectedHandles( 244 int32_t PPB_Audio_Proxy::GetAudioConnectedHandles(
233 PP_Resource resource, 245 const HostResource& resource,
234 IPC::PlatformFileForTransit* foreign_socket_handle, 246 IPC::PlatformFileForTransit* foreign_socket_handle,
235 base::SharedMemoryHandle* foreign_shared_memory_handle, 247 base::SharedMemoryHandle* foreign_shared_memory_handle,
236 uint32_t* shared_memory_length) { 248 uint32_t* shared_memory_length) {
237 // Get the trusted audio interface which will give us the handles. 249 // Get the trusted audio interface which will give us the handles.
238 const PPB_AudioTrusted* audio_trusted = 250 const PPB_AudioTrusted* audio_trusted =
239 reinterpret_cast<const PPB_AudioTrusted*>( 251 reinterpret_cast<const PPB_AudioTrusted*>(
240 dispatcher()->GetLocalInterface(PPB_AUDIO_TRUSTED_INTERFACE)); 252 dispatcher()->GetLocalInterface(PPB_AUDIO_TRUSTED_INTERFACE));
241 if (!audio_trusted) 253 if (!audio_trusted)
242 return PP_ERROR_NOINTERFACE; 254 return PP_ERROR_NOINTERFACE;
243 255
244 // Get the socket handle for signaling. 256 // Get the socket handle for signaling.
245 int32_t socket_handle; 257 int32_t socket_handle;
246 int32_t result = audio_trusted->GetSyncSocket(resource, &socket_handle); 258 int32_t result = audio_trusted->GetSyncSocket(resource.host_resource(),
259 &socket_handle);
247 if (result != PP_OK) 260 if (result != PP_OK)
248 return result; 261 return result;
249 262
250 #if defined(OS_WIN) 263 #if defined(OS_WIN)
251 // On Windows, duplicate the socket into the plugin process, this will 264 // On Windows, duplicate the socket into the plugin process, this will
252 // automatically close the source handle. 265 // automatically close the source handle.
253 ::DuplicateHandle( 266 ::DuplicateHandle(
254 GetCurrentProcess(), 267 GetCurrentProcess(),
255 reinterpret_cast<HANDLE>(static_cast<intptr_t>(socket_handle)), 268 reinterpret_cast<HANDLE>(static_cast<intptr_t>(socket_handle)),
256 dispatcher()->remote_process_handle(), foreign_socket_handle, 269 dispatcher()->remote_process_handle(), foreign_socket_handle,
257 STANDARD_RIGHTS_REQUIRED | FILE_MAP_READ | FILE_MAP_WRITE, 270 STANDARD_RIGHTS_REQUIRED | FILE_MAP_READ | FILE_MAP_WRITE,
258 FALSE, DUPLICATE_CLOSE_SOURCE); 271 FALSE, DUPLICATE_CLOSE_SOURCE);
259 #else 272 #else
260 // On Posix, the socket handle will be auto-duplicated when we send the 273 // 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. 274 // FileDescriptor. Set AutoClose since we don't need the handle any more.
262 *foreign_socket_handle = base::FileDescriptor(socket_handle, true); 275 *foreign_socket_handle = base::FileDescriptor(socket_handle, true);
263 #endif 276 #endif
264 277
265 // Get the shared memory for the buffer. 278 // Get the shared memory for the buffer.
266 // TODO(brettw) remove the reinterpret cast when the interface is updated. 279 // TODO(brettw) remove the reinterpret cast when the interface is updated.
267 int shared_memory_handle; 280 int shared_memory_handle;
268 result = audio_trusted->GetSharedMemory(resource, &shared_memory_handle, 281 result = audio_trusted->GetSharedMemory(resource.host_resource(),
269 shared_memory_length); 282 &shared_memory_handle,
283 shared_memory_length);
270 if (result != PP_OK) 284 if (result != PP_OK)
271 return result; 285 return result;
272 286
273 base::SharedMemory shared_memory( 287 base::SharedMemory shared_memory(
274 #if defined(OS_WIN) 288 #if defined(OS_WIN)
275 reinterpret_cast<HANDLE>(static_cast<intptr_t>(shared_memory_handle)), 289 reinterpret_cast<HANDLE>(static_cast<intptr_t>(shared_memory_handle)),
276 #else 290 #else
277 base::FileDescriptor(shared_memory_handle, false), 291 base::FileDescriptor(shared_memory_handle, false),
278 #endif 292 #endif
279 false); 293 false);
280 294
281 // Duplicate the shared memory to the plugin process. This will automatically 295 // Duplicate the shared memory to the plugin process. This will automatically
282 // close the source handle. 296 // close the source handle.
283 if (!shared_memory.GiveToProcess(dispatcher()->remote_process_handle(), 297 if (!shared_memory.GiveToProcess(dispatcher()->remote_process_handle(),
284 foreign_shared_memory_handle)) 298 foreign_shared_memory_handle))
285 return PP_ERROR_FAILED; 299 return PP_ERROR_FAILED;
286 300
287 return PP_OK; 301 return PP_OK;
288 } 302 }
289 303
290 } // namespace proxy 304 } // namespace proxy
291 } // namespace pp 305 } // namespace pp
OLDNEW
« no previous file with comments | « ppapi/proxy/ppb_audio_proxy.h ('k') | ppapi/proxy/ppb_buffer_proxy.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698