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

Side by Side Diff: content/renderer/pepper/pepper_audio_input_host.cc

Issue 11366038: Rewrite PPB_AudioInput_Dev to use the new-style host/resource. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 8 years, 1 month 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
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/renderer/pepper/pepper_audio_input_host.h"
6
7 #include "base/bind.h"
8 #include "base/logging.h"
9 #include "build/build_config.h"
10 #include "content/public/renderer/renderer_ppapi_host.h"
11 #include "ipc/ipc_message.h"
12 #include "media/audio/shared_memory_util.h"
13 #include "ppapi/c/pp_errors.h"
14 #include "ppapi/host/dispatch_host_message.h"
15 #include "ppapi/host/ppapi_host.h"
16 #include "ppapi/proxy/ppapi_messages.h"
17 #include "ppapi/proxy/serialized_structs.h"
18 #include "ppapi/shared_impl/ppb_device_ref_shared.h"
19 #include "webkit/plugins/ppapi/ppapi_plugin_instance.h"
20
21 namespace content {
22
23 namespace {
24
25 base::PlatformFile ConvertSyncSocketHandle(const base::SyncSocket& socket) {
26 return socket.handle();
27 }
28
29 base::PlatformFile ConvertSharedMemoryHandle(
30 const base::SharedMemory& shared_memory) {
31 #if defined(OS_POSIX)
32 return shared_memory.handle().fd;
33 #elif defined(OS_WIN)
34 return shared_memory.handle();
35 #else
36 #error "Platform not supported."
37 #endif
38 }
39
40 } // namespace
41
42 PepperAudioInputHost::PepperAudioInputHost(
43 RendererPpapiHost* host,
44 PP_Instance instance,
45 PP_Resource resource)
46 : ResourceHost(host->GetPpapiHost(), instance, resource),
47 renderer_ppapi_host_(host),
48 audio_input_(NULL) {
49 }
50
51 PepperAudioInputHost::~PepperAudioInputHost() {
52 Close();
53 }
54
55 int32_t PepperAudioInputHost::OnResourceMessageReceived(
56 const IPC::Message& msg,
57 ppapi::host::HostMessageContext* context) {
58 IPC_BEGIN_MESSAGE_MAP(PepperAudioInputHost, msg)
59 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(
60 PpapiHostMsg_AudioInput_EnumerateDevices, OnMsgEnumerateDevices)
61 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_AudioInput_Open, OnMsgOpen)
62 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_AudioInput_StartOrStop,
63 OnMsgStartOrStop);
64 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_AudioInput_Close,
65 OnMsgClose);
66 IPC_END_MESSAGE_MAP()
67 return PP_ERROR_FAILED;
68 }
69
70 void PepperAudioInputHost::StreamCreated(
71 base::SharedMemoryHandle shared_memory_handle,
72 size_t shared_memory_size,
73 base::SyncSocket::Handle socket) {
74 OnOpenComplete(PP_OK, shared_memory_handle, shared_memory_size, socket);
75 }
76
77 void PepperAudioInputHost::StreamCreationFailed() {
78 OnOpenComplete(PP_ERROR_FAILED, base::SharedMemory::NULLHandle(), 0,
79 base::SyncSocket::kInvalidHandle);
80 }
81
82 int32_t PepperAudioInputHost::OnMsgEnumerateDevices(
83 ppapi::host::HostMessageContext* context) {
84 if (enumerate_devices_context_.get())
85 return PP_ERROR_INPROGRESS;
86
87 webkit::ppapi::PluginDelegate* plugin_delegate = GetDelegate();
88 if (!plugin_delegate)
89 return PP_ERROR_FAILED;
90
91 enumerate_devices_context_.reset(
92 new ppapi::host::ReplyMessageContext(context->MakeReplyMessageContext()));
93 // Note that the callback may be called synchronously.
94 plugin_delegate->EnumerateDevices(
95 PP_DEVICETYPE_DEV_AUDIOCAPTURE,
96 base::Bind(&PepperAudioInputHost::EnumerateDevicesCallbackFunc,
97 AsWeakPtr()));
98 return PP_OK_COMPLETIONPENDING;
99 }
100
101 int32_t PepperAudioInputHost::OnMsgOpen(
102 ppapi::host::HostMessageContext* context,
103 const std::string& device_id,
104 PP_AudioSampleRate sample_rate,
105 uint32_t sample_frame_count) {
106 if (open_context_.get())
107 return PP_ERROR_INPROGRESS;
108 if (audio_input_)
109 return PP_ERROR_FAILED;
110
111 webkit::ppapi::PluginDelegate* plugin_delegate = GetDelegate();
112 if (!plugin_delegate)
113 return PP_ERROR_FAILED;
114
115 // When it is done, we'll get called back on StreamCreated() or
116 // StreamCreationFailed().
117 audio_input_ = plugin_delegate->CreateAudioInput(
118 device_id, sample_rate, sample_frame_count, this);
119 if (audio_input_) {
120 open_context_.reset(new ppapi::host::ReplyMessageContext(
121 context->MakeReplyMessageContext()));
122 return PP_OK_COMPLETIONPENDING;
123 } else {
124 return PP_ERROR_FAILED;
125 }
126 }
127
128 int32_t PepperAudioInputHost::OnMsgStartOrStop(
129 ppapi::host::HostMessageContext* /* context */,
130 bool capture) {
131 if (!audio_input_)
132 return PP_ERROR_FAILED;
133 if (capture)
134 audio_input_->StartCapture();
135 else
136 audio_input_->StopCapture();
137 return PP_OK;
138 }
139
140 int32_t PepperAudioInputHost::OnMsgClose(
141 ppapi::host::HostMessageContext* /* context */) {
142 Close();
143 return PP_OK;
144 }
145
146 void PepperAudioInputHost::EnumerateDevicesCallbackFunc(
147 int request_id,
148 bool succeeded,
149 const std::vector<ppapi::DeviceRefData>& devices) {
150 DCHECK(enumerate_devices_context_.get());
151
152 webkit::ppapi::PluginDelegate* plugin_delegate = GetDelegate();
153 if (plugin_delegate)
154 plugin_delegate->StopEnumerateDevices(request_id);
155
156 enumerate_devices_context_->params.set_result(
157 succeeded ? PP_OK : PP_ERROR_FAILED);
158 host()->SendReply(
159 *enumerate_devices_context_,
160 PpapiPluginMsg_AudioInput_EnumerateDevicesReply(
161 succeeded ? devices : std::vector<ppapi::DeviceRefData>()));
162 enumerate_devices_context_.reset();
163 }
164
165 void PepperAudioInputHost::OnOpenComplete(
166 int32_t result,
167 base::SharedMemoryHandle shared_memory_handle,
168 size_t shared_memory_size,
169 base::SyncSocket::Handle socket_handle) {
170 // Make sure the handles are cleaned up.
171 base::SyncSocket scoped_socket(socket_handle);
172 base::SharedMemory scoped_shared_memory(shared_memory_handle, false);
173
174 if (!open_context_.get()) {
175 NOTREACHED();
176 return;
177 }
178
179 ppapi::proxy::SerializedHandle serialized_socket_handle(
180 ppapi::proxy::SerializedHandle::SOCKET);
181 ppapi::proxy::SerializedHandle serialized_shared_memory_handle(
182 ppapi::proxy::SerializedHandle::SHARED_MEMORY);
183
184 if (result == PP_OK) {
185 IPC::PlatformFileForTransit temp_socket =
186 IPC::InvalidPlatformFileForTransit();
187 base::SharedMemoryHandle temp_shmem = base::SharedMemory::NULLHandle();
188 result = GetRemoteHandles(
189 scoped_socket, scoped_shared_memory, &temp_socket, &temp_shmem);
190
191 serialized_socket_handle.set_socket(temp_socket);
192 // Note that we must call TotalSharedMemorySizeInBytes() because extra space
193 // in shared memory is allocated for book-keeping, so the actual size of the
194 // shared memory buffer is larger than |shared_memory_size|. When sending to
195 // NaCl, NaClIPCAdapter expects this size to match the size of the full
196 // shared memory buffer.
197 serialized_shared_memory_handle.set_shmem(
198 temp_shmem, media::TotalSharedMemorySizeInBytes(shared_memory_size));
199 }
200
201 // Send all the values, even on error. This simplifies some of our cleanup
202 // code since the handles will be in the other process and could be
203 // inconvenient to clean up. Our IPC code will automatically handle this for
204 // us, as long as the remote side always closes the handles it receives, even
205 // in the failure case.
206 open_context_->params.set_result(result);
207 open_context_->params.AppendHandle(serialized_socket_handle);
208 open_context_->params.AppendHandle(serialized_shared_memory_handle);
209
210 host()->SendReply(*open_context_, PpapiPluginMsg_AudioInput_OpenReply());
211 open_context_.reset();
212 }
213
214 int32_t PepperAudioInputHost::GetRemoteHandles(
215 const base::SyncSocket& socket,
216 const base::SharedMemory& shared_memory,
217 IPC::PlatformFileForTransit* remote_socket_handle,
218 base::SharedMemoryHandle* remote_shared_memory_handle) {
219 *remote_socket_handle = renderer_ppapi_host_->ShareHandleWithRemote(
220 ConvertSyncSocketHandle(socket), false);
221 if (*remote_socket_handle == IPC::InvalidPlatformFileForTransit())
222 return PP_ERROR_FAILED;
223
224 *remote_shared_memory_handle = renderer_ppapi_host_->ShareHandleWithRemote(
225 ConvertSharedMemoryHandle(shared_memory), false);
226 if (*remote_shared_memory_handle == IPC::InvalidPlatformFileForTransit())
227 return PP_ERROR_FAILED;
228
229 return PP_OK;
230 }
231
232 void PepperAudioInputHost::Close() {
233 if (!audio_input_)
234 return;
235
236 audio_input_->ShutDown();
237 audio_input_ = NULL;
238
239 if (open_context_.get()) {
240 open_context_->params.set_result(PP_ERROR_ABORTED);
241 host()->SendReply(*open_context_, PpapiPluginMsg_AudioInput_OpenReply());
242 open_context_.reset();
243 }
244 }
245
246 webkit::ppapi::PluginDelegate* PepperAudioInputHost::GetDelegate() const {
247 webkit::ppapi::PluginInstance* instance =
248 renderer_ppapi_host_->GetPluginInstance(pp_instance());
249 if (instance)
250 return instance->delegate();
251 return NULL;
252 }
253
254 } // namespace content
255
OLDNEW
« no previous file with comments | « content/renderer/pepper/pepper_audio_input_host.h ('k') | content/renderer/pepper/renderer_ppapi_host_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698