blob: 30d9266535ab3a6564fb1fda2bf0243465ffb0ab [file] [log] [blame]
Avi Drissman4e1b7bc32022-09-15 14:03:501// Copyright 2012 The Chromium Authors
[email protected]77b55502012-11-08 22:20:202// 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
Hans Wennborg0917de892020-04-28 20:21:157#include "base/notreached.h"
[email protected]77b55502012-11-08 22:20:208#include "build/build_config.h"
lionel.g.landwerlin58344bb2015-03-06 15:43:469#include "content/common/pepper_file_util.h"
David Sandersbccb1d0b2022-02-25 18:02:4610#include "content/public/renderer/render_frame.h"
[email protected]3e1cde62013-07-26 21:07:1711#include "content/renderer/pepper/pepper_media_device_manager.h"
[email protected]3f90dbc42013-07-26 19:09:2712#include "content/renderer/pepper/pepper_platform_audio_input.h"
[email protected]adab2332013-07-25 18:04:3213#include "content/renderer/pepper/pepper_plugin_instance_impl.h"
[email protected]ef6958672013-07-24 19:19:2414#include "content/renderer/pepper/renderer_ppapi_host_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
[email protected]ad63b5c2014-04-11 21:12:3624PepperAudioInputHost::PepperAudioInputHost(RendererPpapiHostImpl* host,
25 PP_Instance instance,
26 PP_Resource resource)
[email protected]77b55502012-11-08 22:20:2027 : ResourceHost(host->GetPpapiHost(), instance, resource),
28 renderer_ppapi_host_(host),
Ivan Kotenkov2c0d2bb32017-11-01 15:41:2829 audio_input_(nullptr),
[email protected]ad63b5c2014-04-11 21:12:3630 enumeration_helper_(this,
[email protected]977db4a42014-07-17 08:04:3231 PepperMediaDeviceManager::GetForRenderFrame(
32 host->GetRenderFrameForInstance(pp_instance())),
[email protected]ad63b5c2014-04-11 21:12:3633 PP_DEVICETYPE_DEV_AUDIOCAPTURE,
34 host->GetDocumentURL(instance)) {}
[email protected]77b55502012-11-08 22:20:2035
[email protected]ad63b5c2014-04-11 21:12:3636PepperAudioInputHost::~PepperAudioInputHost() { Close(); }
[email protected]77b55502012-11-08 22:20:2037
38int32_t PepperAudioInputHost::OnResourceMessageReceived(
39 const IPC::Message& msg,
40 ppapi::host::HostMessageContext* context) {
[email protected]4f01c762012-12-05 02:44:1841 int32_t result = PP_ERROR_FAILED;
42 if (enumeration_helper_.HandleResourceMessage(msg, context, &result))
43 return result;
44
[email protected]dade5f82014-05-13 21:59:2145 PPAPI_BEGIN_MESSAGE_MAP(PepperAudioInputHost, msg)
46 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_AudioInput_Open, OnOpen)
47 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_AudioInput_StartOrStop,
48 OnStartOrStop)
49 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_AudioInput_Close, OnClose)
50 PPAPI_END_MESSAGE_MAP()
[email protected]77b55502012-11-08 22:20:2051 return PP_ERROR_FAILED;
52}
53
54void PepperAudioInputHost::StreamCreated(
Fredrik Hernqvist97f108422024-12-04 08:38:3255 base::UnsafeSharedMemoryRegion shared_memory_region,
Robert Sesek8dd06452020-02-19 01:10:4956 base::SyncSocket::ScopedHandle socket) {
57 OnOpenComplete(PP_OK, std::move(shared_memory_region), std::move(socket));
[email protected]77b55502012-11-08 22:20:2058}
59
60void PepperAudioInputHost::StreamCreationFailed() {
Fredrik Hernqvist97f108422024-12-04 08:38:3261 OnOpenComplete(PP_ERROR_FAILED, base::UnsafeSharedMemoryRegion(),
Robert Sesek8dd06452020-02-19 01:10:4962 base::SyncSocket::ScopedHandle());
[email protected]77b55502012-11-08 22:20:2063}
64
[email protected]ad63b5c2014-04-11 21:12:3665int32_t PepperAudioInputHost::OnOpen(ppapi::host::HostMessageContext* context,
66 const std::string& device_id,
67 PP_AudioSampleRate sample_rate,
68 uint32_t sample_frame_count) {
[email protected]a850702d2014-04-14 21:51:5769 if (open_context_.is_valid())
[email protected]77b55502012-11-08 22:20:2070 return PP_ERROR_INPROGRESS;
71 if (audio_input_)
72 return PP_ERROR_FAILED;
73
[email protected]83d3c0c12013-11-05 06:31:0374 GURL document_url = renderer_ppapi_host_->GetDocumentURL(pp_instance());
75 if (!document_url.is_valid())
[email protected]ae6ef142013-06-13 22:50:5276 return PP_ERROR_FAILED;
77
[email protected]77b55502012-11-08 22:20:2078 // When it is done, we'll get called back on StreamCreated() or
79 // StreamCreationFailed().
[email protected]977db4a42014-07-17 08:04:3280 audio_input_ = PepperPlatformAudioInput::Create(
81 renderer_ppapi_host_->GetRenderFrameForInstance(pp_instance())->
82 GetRoutingID(),
83 device_id,
[email protected]977db4a42014-07-17 08:04:3284 static_cast<int>(sample_rate),
85 static_cast<int>(sample_frame_count),
86 this);
[email protected]77b55502012-11-08 22:20:2087 if (audio_input_) {
[email protected]a850702d2014-04-14 21:51:5788 open_context_ = context->MakeReplyMessageContext();
[email protected]77b55502012-11-08 22:20:2089 return PP_OK_COMPLETIONPENDING;
90 } else {
91 return PP_ERROR_FAILED;
92 }
93}
94
[email protected]3d9ec5052013-01-02 22:05:2595int32_t PepperAudioInputHost::OnStartOrStop(
[email protected]77b55502012-11-08 22:20:2096 ppapi::host::HostMessageContext* /* context */,
97 bool capture) {
98 if (!audio_input_)
99 return PP_ERROR_FAILED;
100 if (capture)
101 audio_input_->StartCapture();
102 else
103 audio_input_->StopCapture();
104 return PP_OK;
105}
106
[email protected]3d9ec5052013-01-02 22:05:25107int32_t PepperAudioInputHost::OnClose(
[email protected]77b55502012-11-08 22:20:20108 ppapi::host::HostMessageContext* /* context */) {
109 Close();
110 return PP_OK;
111}
112
[email protected]77b55502012-11-08 22:20:20113void PepperAudioInputHost::OnOpenComplete(
114 int32_t result,
Fredrik Hernqvist97f108422024-12-04 08:38:32115 base::UnsafeSharedMemoryRegion shared_memory_region,
Robert Sesek8dd06452020-02-19 01:10:49116 base::SyncSocket::ScopedHandle socket_handle) {
[email protected]77b55502012-11-08 22:20:20117 // Make sure the handles are cleaned up.
Robert Sesek8dd06452020-02-19 01:10:49118 base::SyncSocket scoped_socket(std::move(socket_handle));
[email protected]77b55502012-11-08 22:20:20119
[email protected]a850702d2014-04-14 21:51:57120 if (!open_context_.is_valid()) {
Peter Boströmfc7ddc182024-10-31 19:37:21121 NOTREACHED();
[email protected]77b55502012-11-08 22:20:20122 }
123
124 ppapi::proxy::SerializedHandle serialized_socket_handle(
125 ppapi::proxy::SerializedHandle::SOCKET);
126 ppapi::proxy::SerializedHandle serialized_shared_memory_handle(
Alexandr Ilin002a9a22018-06-01 13:32:18127 ppapi::proxy::SerializedHandle::SHARED_MEMORY_REGION);
[email protected]77b55502012-11-08 22:20:20128
129 if (result == PP_OK) {
130 IPC::PlatformFileForTransit temp_socket =
131 IPC::InvalidPlatformFileForTransit();
Fredrik Hernqvist97f108422024-12-04 08:38:32132 base::UnsafeSharedMemoryRegion temp_shmem;
Alexandr Ilin002a9a22018-06-01 13:32:18133 result = GetRemoteHandles(scoped_socket, shared_memory_region, &temp_socket,
134 &temp_shmem);
[email protected]77b55502012-11-08 22:20:20135
136 serialized_socket_handle.set_socket(temp_socket);
Alexandr Ilin002a9a22018-06-01 13:32:18137 serialized_shared_memory_handle.set_shmem_region(
Fredrik Hernqvist97f108422024-12-04 08:38:32138 base::UnsafeSharedMemoryRegion::TakeHandleForSerialization(
Alexandr Ilin002a9a22018-06-01 13:32:18139 std::move(temp_shmem)));
[email protected]77b55502012-11-08 22:20:20140 }
141
142 // Send all the values, even on error. This simplifies some of our cleanup
143 // code since the handles will be in the other process and could be
144 // inconvenient to clean up. Our IPC code will automatically handle this for
145 // us, as long as the remote side always closes the handles it receives, even
146 // in the failure case.
Alexandr Ilin1d004102018-05-30 10:55:32147 open_context_.params.AppendHandle(std::move(serialized_socket_handle));
148 open_context_.params.AppendHandle(std::move(serialized_shared_memory_handle));
[email protected]a850702d2014-04-14 21:51:57149 SendOpenReply(result);
[email protected]77b55502012-11-08 22:20:20150}
151
152int32_t PepperAudioInputHost::GetRemoteHandles(
153 const base::SyncSocket& socket,
Fredrik Hernqvist97f108422024-12-04 08:38:32154 const base::UnsafeSharedMemoryRegion& shared_memory_region,
[email protected]77b55502012-11-08 22:20:20155 IPC::PlatformFileForTransit* remote_socket_handle,
Fredrik Hernqvist97f108422024-12-04 08:38:32156 base::UnsafeSharedMemoryRegion* remote_shared_memory_region) {
Daniel Bratell590d6dc02017-12-07 21:41:21157 *remote_socket_handle =
158 renderer_ppapi_host_->ShareHandleWithRemote(socket.handle(), false);
[email protected]77b55502012-11-08 22:20:20159 if (*remote_socket_handle == IPC::InvalidPlatformFileForTransit())
160 return PP_ERROR_FAILED;
161
Alexandr Ilin002a9a22018-06-01 13:32:18162 *remote_shared_memory_region =
Fredrik Hernqvist97f108422024-12-04 08:38:32163 renderer_ppapi_host_->ShareUnsafeSharedMemoryRegionWithRemote(
Alexandr Ilin002a9a22018-06-01 13:32:18164 shared_memory_region);
165 if (!remote_shared_memory_region->IsValid())
[email protected]77b55502012-11-08 22:20:20166 return PP_ERROR_FAILED;
167
168 return PP_OK;
169}
170
171void PepperAudioInputHost::Close() {
172 if (!audio_input_)
173 return;
174
175 audio_input_->ShutDown();
Ivan Kotenkov2c0d2bb32017-11-01 15:41:28176 audio_input_ = nullptr;
[email protected]77b55502012-11-08 22:20:20177
[email protected]a850702d2014-04-14 21:51:57178 if (open_context_.is_valid())
179 SendOpenReply(PP_ERROR_ABORTED);
180}
181
182void PepperAudioInputHost::SendOpenReply(int32_t result) {
183 open_context_.params.set_result(result);
184 host()->SendReply(open_context_, PpapiPluginMsg_AudioInput_OpenReply());
185 open_context_ = ppapi::host::ReplyMessageContext();
[email protected]77b55502012-11-08 22:20:20186}
187
[email protected]77b55502012-11-08 22:20:20188} // namespace content