blob: 1805eb7d3f7aa06e2dc7bbd95dfb086aec575162 [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"
lionel.g.landwerlin58344bb2015-03-06 15:43:469#include "content/common/pepper_file_util.h"
[email protected]3e1cde62013-07-26 21:07:1710#include "content/renderer/pepper/pepper_media_device_manager.h"
[email protected]3f90dbc42013-07-26 19:09:2711#include "content/renderer/pepper/pepper_platform_audio_input.h"
[email protected]adab2332013-07-25 18:04:3212#include "content/renderer/pepper/pepper_plugin_instance_impl.h"
[email protected]ef6958672013-07-24 19:19:2413#include "content/renderer/pepper/renderer_ppapi_host_impl.h"
[email protected]977db4a42014-07-17 08:04:3214#include "content/renderer/render_frame_impl.h"
[email protected]77b55502012-11-08 22:20:2015#include "ipc/ipc_message.h"
[email protected]77b55502012-11-08 22:20:2016#include "ppapi/c/pp_errors.h"
17#include "ppapi/host/dispatch_host_message.h"
18#include "ppapi/host/ppapi_host.h"
19#include "ppapi/proxy/ppapi_messages.h"
20#include "ppapi/proxy/serialized_structs.h"
[email protected]77b55502012-11-08 22:20:2021
22namespace content {
23
24namespace {
25
26base::PlatformFile ConvertSyncSocketHandle(const base::SyncSocket& socket) {
27 return socket.handle();
28}
29
[email protected]77b55502012-11-08 22:20:2030} // namespace
31
[email protected]ad63b5c2014-04-11 21:12:3632PepperAudioInputHost::PepperAudioInputHost(RendererPpapiHostImpl* host,
33 PP_Instance instance,
34 PP_Resource resource)
[email protected]77b55502012-11-08 22:20:2035 : ResourceHost(host->GetPpapiHost(), instance, resource),
36 renderer_ppapi_host_(host),
[email protected]4f01c762012-12-05 02:44:1837 audio_input_(NULL),
[email protected]ad63b5c2014-04-11 21:12:3638 enumeration_helper_(this,
[email protected]977db4a42014-07-17 08:04:3239 PepperMediaDeviceManager::GetForRenderFrame(
40 host->GetRenderFrameForInstance(pp_instance())),
[email protected]ad63b5c2014-04-11 21:12:3641 PP_DEVICETYPE_DEV_AUDIOCAPTURE,
42 host->GetDocumentURL(instance)) {}
[email protected]77b55502012-11-08 22:20:2043
[email protected]ad63b5c2014-04-11 21:12:3644PepperAudioInputHost::~PepperAudioInputHost() { Close(); }
[email protected]77b55502012-11-08 22:20:2045
46int32_t PepperAudioInputHost::OnResourceMessageReceived(
47 const IPC::Message& msg,
48 ppapi::host::HostMessageContext* context) {
[email protected]4f01c762012-12-05 02:44:1849 int32_t result = PP_ERROR_FAILED;
50 if (enumeration_helper_.HandleResourceMessage(msg, context, &result))
51 return result;
52
[email protected]dade5f82014-05-13 21:59:2153 PPAPI_BEGIN_MESSAGE_MAP(PepperAudioInputHost, msg)
54 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_AudioInput_Open, OnOpen)
55 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_AudioInput_StartOrStop,
56 OnStartOrStop)
57 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_AudioInput_Close, OnClose)
58 PPAPI_END_MESSAGE_MAP()
[email protected]77b55502012-11-08 22:20:2059 return PP_ERROR_FAILED;
60}
61
62void PepperAudioInputHost::StreamCreated(
63 base::SharedMemoryHandle shared_memory_handle,
64 size_t shared_memory_size,
65 base::SyncSocket::Handle socket) {
66 OnOpenComplete(PP_OK, shared_memory_handle, shared_memory_size, socket);
67}
68
69void PepperAudioInputHost::StreamCreationFailed() {
[email protected]ad63b5c2014-04-11 21:12:3670 OnOpenComplete(PP_ERROR_FAILED,
71 base::SharedMemory::NULLHandle(),
72 0,
[email protected]77b55502012-11-08 22:20:2073 base::SyncSocket::kInvalidHandle);
74}
75
[email protected]ad63b5c2014-04-11 21:12:3676int32_t PepperAudioInputHost::OnOpen(ppapi::host::HostMessageContext* context,
77 const std::string& device_id,
78 PP_AudioSampleRate sample_rate,
79 uint32_t sample_frame_count) {
[email protected]a850702d2014-04-14 21:51:5780 if (open_context_.is_valid())
[email protected]77b55502012-11-08 22:20:2081 return PP_ERROR_INPROGRESS;
82 if (audio_input_)
83 return PP_ERROR_FAILED;
84
[email protected]83d3c0c12013-11-05 06:31:0385 GURL document_url = renderer_ppapi_host_->GetDocumentURL(pp_instance());
86 if (!document_url.is_valid())
[email protected]ae6ef14f2013-06-13 22:50:5287 return PP_ERROR_FAILED;
88
[email protected]77b55502012-11-08 22:20:2089 // When it is done, we'll get called back on StreamCreated() or
90 // StreamCreationFailed().
[email protected]977db4a42014-07-17 08:04:3291 audio_input_ = PepperPlatformAudioInput::Create(
92 renderer_ppapi_host_->GetRenderFrameForInstance(pp_instance())->
93 GetRoutingID(),
94 device_id,
95 document_url,
96 static_cast<int>(sample_rate),
97 static_cast<int>(sample_frame_count),
98 this);
[email protected]77b55502012-11-08 22:20:2099 if (audio_input_) {
[email protected]a850702d2014-04-14 21:51:57100 open_context_ = context->MakeReplyMessageContext();
[email protected]77b55502012-11-08 22:20:20101 return PP_OK_COMPLETIONPENDING;
102 } else {
103 return PP_ERROR_FAILED;
104 }
105}
106
[email protected]3d9ec5052013-01-02 22:05:25107int32_t PepperAudioInputHost::OnStartOrStop(
[email protected]77b55502012-11-08 22:20:20108 ppapi::host::HostMessageContext* /* context */,
109 bool capture) {
110 if (!audio_input_)
111 return PP_ERROR_FAILED;
112 if (capture)
113 audio_input_->StartCapture();
114 else
115 audio_input_->StopCapture();
116 return PP_OK;
117}
118
[email protected]3d9ec5052013-01-02 22:05:25119int32_t PepperAudioInputHost::OnClose(
[email protected]77b55502012-11-08 22:20:20120 ppapi::host::HostMessageContext* /* context */) {
121 Close();
122 return PP_OK;
123}
124
[email protected]77b55502012-11-08 22:20:20125void PepperAudioInputHost::OnOpenComplete(
126 int32_t result,
127 base::SharedMemoryHandle shared_memory_handle,
128 size_t shared_memory_size,
129 base::SyncSocket::Handle socket_handle) {
130 // Make sure the handles are cleaned up.
131 base::SyncSocket scoped_socket(socket_handle);
132 base::SharedMemory scoped_shared_memory(shared_memory_handle, false);
133
[email protected]a850702d2014-04-14 21:51:57134 if (!open_context_.is_valid()) {
[email protected]77b55502012-11-08 22:20:20135 NOTREACHED();
136 return;
137 }
138
139 ppapi::proxy::SerializedHandle serialized_socket_handle(
140 ppapi::proxy::SerializedHandle::SOCKET);
141 ppapi::proxy::SerializedHandle serialized_shared_memory_handle(
142 ppapi::proxy::SerializedHandle::SHARED_MEMORY);
143
144 if (result == PP_OK) {
145 IPC::PlatformFileForTransit temp_socket =
146 IPC::InvalidPlatformFileForTransit();
147 base::SharedMemoryHandle temp_shmem = base::SharedMemory::NULLHandle();
148 result = GetRemoteHandles(
149 scoped_socket, scoped_shared_memory, &temp_socket, &temp_shmem);
150
151 serialized_socket_handle.set_socket(temp_socket);
[email protected]078c07bd2013-10-23 21:33:46152 serialized_shared_memory_handle.set_shmem(temp_shmem, shared_memory_size);
[email protected]77b55502012-11-08 22:20:20153 }
154
155 // Send all the values, even on error. This simplifies some of our cleanup
156 // code since the handles will be in the other process and could be
157 // inconvenient to clean up. Our IPC code will automatically handle this for
158 // us, as long as the remote side always closes the handles it receives, even
159 // in the failure case.
[email protected]a850702d2014-04-14 21:51:57160 open_context_.params.AppendHandle(serialized_socket_handle);
161 open_context_.params.AppendHandle(serialized_shared_memory_handle);
162 SendOpenReply(result);
[email protected]77b55502012-11-08 22:20:20163}
164
165int32_t PepperAudioInputHost::GetRemoteHandles(
166 const base::SyncSocket& socket,
167 const base::SharedMemory& shared_memory,
168 IPC::PlatformFileForTransit* remote_socket_handle,
169 base::SharedMemoryHandle* remote_shared_memory_handle) {
170 *remote_socket_handle = renderer_ppapi_host_->ShareHandleWithRemote(
171 ConvertSyncSocketHandle(socket), false);
172 if (*remote_socket_handle == IPC::InvalidPlatformFileForTransit())
173 return PP_ERROR_FAILED;
174
erikchen4fc32d52015-06-02 02:16:38175 *remote_shared_memory_handle =
176 renderer_ppapi_host_->ShareSharedMemoryHandleWithRemote(
177 shared_memory.handle());
178 if (!base::SharedMemory::IsHandleValid(*remote_shared_memory_handle))
[email protected]77b55502012-11-08 22:20:20179 return PP_ERROR_FAILED;
180
181 return PP_OK;
182}
183
184void PepperAudioInputHost::Close() {
185 if (!audio_input_)
186 return;
187
188 audio_input_->ShutDown();
189 audio_input_ = NULL;
190
[email protected]a850702d2014-04-14 21:51:57191 if (open_context_.is_valid())
192 SendOpenReply(PP_ERROR_ABORTED);
193}
194
195void PepperAudioInputHost::SendOpenReply(int32_t result) {
196 open_context_.params.set_result(result);
197 host()->SendReply(open_context_, PpapiPluginMsg_AudioInput_OpenReply());
198 open_context_ = ppapi::host::ReplyMessageContext();
[email protected]77b55502012-11-08 22:20:20199}
200
[email protected]77b55502012-11-08 22:20:20201} // namespace content