blob: 0da9cd1d99c7dd59a13f72cee5f5cd6297143808 [file] [log] [blame]
[email protected]77b55502012-11-08 22:20:201// 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
[email protected]77b55502012-11-08 22:20:207#include "base/logging.h"
8#include "build/build_config.h"
[email protected]3e1cde62013-07-26 21:07:179#include "content/renderer/pepper/pepper_media_device_manager.h"
[email protected]3f90dbc42013-07-26 19:09:2710#include "content/renderer/pepper/pepper_platform_audio_input.h"
[email protected]adab2332013-07-25 18:04:3211#include "content/renderer/pepper/pepper_plugin_instance_impl.h"
[email protected]ef6958672013-07-24 19:19:2412#include "content/renderer/pepper/renderer_ppapi_host_impl.h"
[email protected]977db4a42014-07-17 08:04:3213#include "content/renderer/render_frame_impl.h"
[email protected]77b55502012-11-08 22:20:2014#include "ipc/ipc_message.h"
[email protected]77b55502012-11-08 22:20:2015#include "ppapi/c/pp_errors.h"
16#include "ppapi/host/dispatch_host_message.h"
17#include "ppapi/host/ppapi_host.h"
18#include "ppapi/proxy/ppapi_messages.h"
19#include "ppapi/proxy/serialized_structs.h"
[email protected]77b55502012-11-08 22:20:2020
21namespace content {
22
23namespace {
24
25base::PlatformFile ConvertSyncSocketHandle(const base::SyncSocket& socket) {
26 return socket.handle();
27}
28
29base::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
[email protected]ad63b5c2014-04-11 21:12:3642PepperAudioInputHost::PepperAudioInputHost(RendererPpapiHostImpl* host,
43 PP_Instance instance,
44 PP_Resource resource)
[email protected]77b55502012-11-08 22:20:2045 : ResourceHost(host->GetPpapiHost(), instance, resource),
46 renderer_ppapi_host_(host),
[email protected]4f01c762012-12-05 02:44:1847 audio_input_(NULL),
[email protected]ad63b5c2014-04-11 21:12:3648 enumeration_helper_(this,
[email protected]977db4a42014-07-17 08:04:3249 PepperMediaDeviceManager::GetForRenderFrame(
50 host->GetRenderFrameForInstance(pp_instance())),
[email protected]ad63b5c2014-04-11 21:12:3651 PP_DEVICETYPE_DEV_AUDIOCAPTURE,
52 host->GetDocumentURL(instance)) {}
[email protected]77b55502012-11-08 22:20:2053
[email protected]ad63b5c2014-04-11 21:12:3654PepperAudioInputHost::~PepperAudioInputHost() { Close(); }
[email protected]77b55502012-11-08 22:20:2055
56int32_t PepperAudioInputHost::OnResourceMessageReceived(
57 const IPC::Message& msg,
58 ppapi::host::HostMessageContext* context) {
[email protected]4f01c762012-12-05 02:44:1859 int32_t result = PP_ERROR_FAILED;
60 if (enumeration_helper_.HandleResourceMessage(msg, context, &result))
61 return result;
62
[email protected]dade5f82014-05-13 21:59:2163 PPAPI_BEGIN_MESSAGE_MAP(PepperAudioInputHost, msg)
64 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_AudioInput_Open, OnOpen)
65 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_AudioInput_StartOrStop,
66 OnStartOrStop)
67 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_AudioInput_Close, OnClose)
68 PPAPI_END_MESSAGE_MAP()
[email protected]77b55502012-11-08 22:20:2069 return PP_ERROR_FAILED;
70}
71
72void PepperAudioInputHost::StreamCreated(
73 base::SharedMemoryHandle shared_memory_handle,
74 size_t shared_memory_size,
75 base::SyncSocket::Handle socket) {
76 OnOpenComplete(PP_OK, shared_memory_handle, shared_memory_size, socket);
77}
78
79void PepperAudioInputHost::StreamCreationFailed() {
[email protected]ad63b5c2014-04-11 21:12:3680 OnOpenComplete(PP_ERROR_FAILED,
81 base::SharedMemory::NULLHandle(),
82 0,
[email protected]77b55502012-11-08 22:20:2083 base::SyncSocket::kInvalidHandle);
84}
85
[email protected]ad63b5c2014-04-11 21:12:3686int32_t PepperAudioInputHost::OnOpen(ppapi::host::HostMessageContext* context,
87 const std::string& device_id,
88 PP_AudioSampleRate sample_rate,
89 uint32_t sample_frame_count) {
[email protected]a850702d2014-04-14 21:51:5790 if (open_context_.is_valid())
[email protected]77b55502012-11-08 22:20:2091 return PP_ERROR_INPROGRESS;
92 if (audio_input_)
93 return PP_ERROR_FAILED;
94
[email protected]83d3c0c12013-11-05 06:31:0395 GURL document_url = renderer_ppapi_host_->GetDocumentURL(pp_instance());
96 if (!document_url.is_valid())
[email protected]ae6ef14f2013-06-13 22:50:5297 return PP_ERROR_FAILED;
98
[email protected]77b55502012-11-08 22:20:2099 // When it is done, we'll get called back on StreamCreated() or
100 // StreamCreationFailed().
[email protected]977db4a42014-07-17 08:04:32101 audio_input_ = PepperPlatformAudioInput::Create(
102 renderer_ppapi_host_->GetRenderFrameForInstance(pp_instance())->
103 GetRoutingID(),
104 device_id,
105 document_url,
106 static_cast<int>(sample_rate),
107 static_cast<int>(sample_frame_count),
108 this);
[email protected]77b55502012-11-08 22:20:20109 if (audio_input_) {
[email protected]a850702d2014-04-14 21:51:57110 open_context_ = context->MakeReplyMessageContext();
[email protected]77b55502012-11-08 22:20:20111 return PP_OK_COMPLETIONPENDING;
112 } else {
113 return PP_ERROR_FAILED;
114 }
115}
116
[email protected]3d9ec5052013-01-02 22:05:25117int32_t PepperAudioInputHost::OnStartOrStop(
[email protected]77b55502012-11-08 22:20:20118 ppapi::host::HostMessageContext* /* context */,
119 bool capture) {
120 if (!audio_input_)
121 return PP_ERROR_FAILED;
122 if (capture)
123 audio_input_->StartCapture();
124 else
125 audio_input_->StopCapture();
126 return PP_OK;
127}
128
[email protected]3d9ec5052013-01-02 22:05:25129int32_t PepperAudioInputHost::OnClose(
[email protected]77b55502012-11-08 22:20:20130 ppapi::host::HostMessageContext* /* context */) {
131 Close();
132 return PP_OK;
133}
134
[email protected]77b55502012-11-08 22:20:20135void PepperAudioInputHost::OnOpenComplete(
136 int32_t result,
137 base::SharedMemoryHandle shared_memory_handle,
138 size_t shared_memory_size,
139 base::SyncSocket::Handle socket_handle) {
140 // Make sure the handles are cleaned up.
141 base::SyncSocket scoped_socket(socket_handle);
142 base::SharedMemory scoped_shared_memory(shared_memory_handle, false);
143
[email protected]a850702d2014-04-14 21:51:57144 if (!open_context_.is_valid()) {
[email protected]77b55502012-11-08 22:20:20145 NOTREACHED();
146 return;
147 }
148
149 ppapi::proxy::SerializedHandle serialized_socket_handle(
150 ppapi::proxy::SerializedHandle::SOCKET);
151 ppapi::proxy::SerializedHandle serialized_shared_memory_handle(
152 ppapi::proxy::SerializedHandle::SHARED_MEMORY);
153
154 if (result == PP_OK) {
155 IPC::PlatformFileForTransit temp_socket =
156 IPC::InvalidPlatformFileForTransit();
157 base::SharedMemoryHandle temp_shmem = base::SharedMemory::NULLHandle();
158 result = GetRemoteHandles(
159 scoped_socket, scoped_shared_memory, &temp_socket, &temp_shmem);
160
161 serialized_socket_handle.set_socket(temp_socket);
[email protected]078c07bd2013-10-23 21:33:46162 serialized_shared_memory_handle.set_shmem(temp_shmem, shared_memory_size);
[email protected]77b55502012-11-08 22:20:20163 }
164
165 // Send all the values, even on error. This simplifies some of our cleanup
166 // code since the handles will be in the other process and could be
167 // inconvenient to clean up. Our IPC code will automatically handle this for
168 // us, as long as the remote side always closes the handles it receives, even
169 // in the failure case.
[email protected]a850702d2014-04-14 21:51:57170 open_context_.params.AppendHandle(serialized_socket_handle);
171 open_context_.params.AppendHandle(serialized_shared_memory_handle);
172 SendOpenReply(result);
[email protected]77b55502012-11-08 22:20:20173}
174
175int32_t PepperAudioInputHost::GetRemoteHandles(
176 const base::SyncSocket& socket,
177 const base::SharedMemory& shared_memory,
178 IPC::PlatformFileForTransit* remote_socket_handle,
179 base::SharedMemoryHandle* remote_shared_memory_handle) {
180 *remote_socket_handle = renderer_ppapi_host_->ShareHandleWithRemote(
181 ConvertSyncSocketHandle(socket), false);
182 if (*remote_socket_handle == IPC::InvalidPlatformFileForTransit())
183 return PP_ERROR_FAILED;
184
185 *remote_shared_memory_handle = renderer_ppapi_host_->ShareHandleWithRemote(
186 ConvertSharedMemoryHandle(shared_memory), false);
187 if (*remote_shared_memory_handle == IPC::InvalidPlatformFileForTransit())
188 return PP_ERROR_FAILED;
189
190 return PP_OK;
191}
192
193void PepperAudioInputHost::Close() {
194 if (!audio_input_)
195 return;
196
197 audio_input_->ShutDown();
198 audio_input_ = NULL;
199
[email protected]a850702d2014-04-14 21:51:57200 if (open_context_.is_valid())
201 SendOpenReply(PP_ERROR_ABORTED);
202}
203
204void PepperAudioInputHost::SendOpenReply(int32_t result) {
205 open_context_.params.set_result(result);
206 host()->SendReply(open_context_, PpapiPluginMsg_AudioInput_OpenReply());
207 open_context_ = ppapi::host::ReplyMessageContext();
[email protected]77b55502012-11-08 22:20:20208}
209
[email protected]77b55502012-11-08 22:20:20210} // namespace content