Avi Drissman | 4e1b7bc3 | 2022-09-15 14:03:50 | [diff] [blame] | 1 | // Copyright 2012 The Chromium Authors |
[email protected] | 77b5550 | 2012-11-08 22:20:20 | [diff] [blame] | 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 | |
Hans Wennborg | 0917de89 | 2020-04-28 20:21:15 | [diff] [blame] | 7 | #include "base/notreached.h" |
[email protected] | 77b5550 | 2012-11-08 22:20:20 | [diff] [blame] | 8 | #include "build/build_config.h" |
lionel.g.landwerlin | 58344bb | 2015-03-06 15:43:46 | [diff] [blame] | 9 | #include "content/common/pepper_file_util.h" |
David Sanders | bccb1d0b | 2022-02-25 18:02:46 | [diff] [blame] | 10 | #include "content/public/renderer/render_frame.h" |
[email protected] | 3e1cde6 | 2013-07-26 21:07:17 | [diff] [blame] | 11 | #include "content/renderer/pepper/pepper_media_device_manager.h" |
[email protected] | 3f90dbc4 | 2013-07-26 19:09:27 | [diff] [blame] | 12 | #include "content/renderer/pepper/pepper_platform_audio_input.h" |
[email protected] | adab233 | 2013-07-25 18:04:32 | [diff] [blame] | 13 | #include "content/renderer/pepper/pepper_plugin_instance_impl.h" |
[email protected] | ef695867 | 2013-07-24 19:19:24 | [diff] [blame] | 14 | #include "content/renderer/pepper/renderer_ppapi_host_impl.h" |
[email protected] | 77b5550 | 2012-11-08 22:20:20 | [diff] [blame] | 15 | #include "ipc/ipc_message.h" |
[email protected] | 77b5550 | 2012-11-08 22:20:20 | [diff] [blame] | 16 | #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] | 77b5550 | 2012-11-08 22:20:20 | [diff] [blame] | 21 | |
| 22 | namespace content { |
| 23 | |
[email protected] | ad63b5c | 2014-04-11 21:12:36 | [diff] [blame] | 24 | PepperAudioInputHost::PepperAudioInputHost(RendererPpapiHostImpl* host, |
| 25 | PP_Instance instance, |
| 26 | PP_Resource resource) |
[email protected] | 77b5550 | 2012-11-08 22:20:20 | [diff] [blame] | 27 | : ResourceHost(host->GetPpapiHost(), instance, resource), |
| 28 | renderer_ppapi_host_(host), |
Ivan Kotenkov | 2c0d2bb3 | 2017-11-01 15:41:28 | [diff] [blame] | 29 | audio_input_(nullptr), |
[email protected] | ad63b5c | 2014-04-11 21:12:36 | [diff] [blame] | 30 | enumeration_helper_(this, |
[email protected] | 977db4a4 | 2014-07-17 08:04:32 | [diff] [blame] | 31 | PepperMediaDeviceManager::GetForRenderFrame( |
| 32 | host->GetRenderFrameForInstance(pp_instance())), |
[email protected] | ad63b5c | 2014-04-11 21:12:36 | [diff] [blame] | 33 | PP_DEVICETYPE_DEV_AUDIOCAPTURE, |
| 34 | host->GetDocumentURL(instance)) {} |
[email protected] | 77b5550 | 2012-11-08 22:20:20 | [diff] [blame] | 35 | |
[email protected] | ad63b5c | 2014-04-11 21:12:36 | [diff] [blame] | 36 | PepperAudioInputHost::~PepperAudioInputHost() { Close(); } |
[email protected] | 77b5550 | 2012-11-08 22:20:20 | [diff] [blame] | 37 | |
| 38 | int32_t PepperAudioInputHost::OnResourceMessageReceived( |
| 39 | const IPC::Message& msg, |
| 40 | ppapi::host::HostMessageContext* context) { |
[email protected] | 4f01c76 | 2012-12-05 02:44:18 | [diff] [blame] | 41 | int32_t result = PP_ERROR_FAILED; |
| 42 | if (enumeration_helper_.HandleResourceMessage(msg, context, &result)) |
| 43 | return result; |
| 44 | |
[email protected] | dade5f8 | 2014-05-13 21:59:21 | [diff] [blame] | 45 | 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] | 77b5550 | 2012-11-08 22:20:20 | [diff] [blame] | 51 | return PP_ERROR_FAILED; |
| 52 | } |
| 53 | |
| 54 | void PepperAudioInputHost::StreamCreated( |
Fredrik Hernqvist | 97f10842 | 2024-12-04 08:38:32 | [diff] [blame] | 55 | base::UnsafeSharedMemoryRegion shared_memory_region, |
Robert Sesek | 8dd0645 | 2020-02-19 01:10:49 | [diff] [blame] | 56 | base::SyncSocket::ScopedHandle socket) { |
| 57 | OnOpenComplete(PP_OK, std::move(shared_memory_region), std::move(socket)); |
[email protected] | 77b5550 | 2012-11-08 22:20:20 | [diff] [blame] | 58 | } |
| 59 | |
| 60 | void PepperAudioInputHost::StreamCreationFailed() { |
Fredrik Hernqvist | 97f10842 | 2024-12-04 08:38:32 | [diff] [blame] | 61 | OnOpenComplete(PP_ERROR_FAILED, base::UnsafeSharedMemoryRegion(), |
Robert Sesek | 8dd0645 | 2020-02-19 01:10:49 | [diff] [blame] | 62 | base::SyncSocket::ScopedHandle()); |
[email protected] | 77b5550 | 2012-11-08 22:20:20 | [diff] [blame] | 63 | } |
| 64 | |
[email protected] | ad63b5c | 2014-04-11 21:12:36 | [diff] [blame] | 65 | int32_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] | a850702d | 2014-04-14 21:51:57 | [diff] [blame] | 69 | if (open_context_.is_valid()) |
[email protected] | 77b5550 | 2012-11-08 22:20:20 | [diff] [blame] | 70 | return PP_ERROR_INPROGRESS; |
| 71 | if (audio_input_) |
| 72 | return PP_ERROR_FAILED; |
| 73 | |
[email protected] | 83d3c0c1 | 2013-11-05 06:31:03 | [diff] [blame] | 74 | GURL document_url = renderer_ppapi_host_->GetDocumentURL(pp_instance()); |
| 75 | if (!document_url.is_valid()) |
[email protected] | ae6ef14 | 2013-06-13 22:50:52 | [diff] [blame] | 76 | return PP_ERROR_FAILED; |
| 77 | |
[email protected] | 77b5550 | 2012-11-08 22:20:20 | [diff] [blame] | 78 | // When it is done, we'll get called back on StreamCreated() or |
| 79 | // StreamCreationFailed(). |
[email protected] | 977db4a4 | 2014-07-17 08:04:32 | [diff] [blame] | 80 | audio_input_ = PepperPlatformAudioInput::Create( |
| 81 | renderer_ppapi_host_->GetRenderFrameForInstance(pp_instance())-> |
| 82 | GetRoutingID(), |
| 83 | device_id, |
[email protected] | 977db4a4 | 2014-07-17 08:04:32 | [diff] [blame] | 84 | static_cast<int>(sample_rate), |
| 85 | static_cast<int>(sample_frame_count), |
| 86 | this); |
[email protected] | 77b5550 | 2012-11-08 22:20:20 | [diff] [blame] | 87 | if (audio_input_) { |
[email protected] | a850702d | 2014-04-14 21:51:57 | [diff] [blame] | 88 | open_context_ = context->MakeReplyMessageContext(); |
[email protected] | 77b5550 | 2012-11-08 22:20:20 | [diff] [blame] | 89 | return PP_OK_COMPLETIONPENDING; |
| 90 | } else { |
| 91 | return PP_ERROR_FAILED; |
| 92 | } |
| 93 | } |
| 94 | |
[email protected] | 3d9ec505 | 2013-01-02 22:05:25 | [diff] [blame] | 95 | int32_t PepperAudioInputHost::OnStartOrStop( |
[email protected] | 77b5550 | 2012-11-08 22:20:20 | [diff] [blame] | 96 | 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] | 3d9ec505 | 2013-01-02 22:05:25 | [diff] [blame] | 107 | int32_t PepperAudioInputHost::OnClose( |
[email protected] | 77b5550 | 2012-11-08 22:20:20 | [diff] [blame] | 108 | ppapi::host::HostMessageContext* /* context */) { |
| 109 | Close(); |
| 110 | return PP_OK; |
| 111 | } |
| 112 | |
[email protected] | 77b5550 | 2012-11-08 22:20:20 | [diff] [blame] | 113 | void PepperAudioInputHost::OnOpenComplete( |
| 114 | int32_t result, |
Fredrik Hernqvist | 97f10842 | 2024-12-04 08:38:32 | [diff] [blame] | 115 | base::UnsafeSharedMemoryRegion shared_memory_region, |
Robert Sesek | 8dd0645 | 2020-02-19 01:10:49 | [diff] [blame] | 116 | base::SyncSocket::ScopedHandle socket_handle) { |
[email protected] | 77b5550 | 2012-11-08 22:20:20 | [diff] [blame] | 117 | // Make sure the handles are cleaned up. |
Robert Sesek | 8dd0645 | 2020-02-19 01:10:49 | [diff] [blame] | 118 | base::SyncSocket scoped_socket(std::move(socket_handle)); |
[email protected] | 77b5550 | 2012-11-08 22:20:20 | [diff] [blame] | 119 | |
[email protected] | a850702d | 2014-04-14 21:51:57 | [diff] [blame] | 120 | if (!open_context_.is_valid()) { |
Peter Boström | fc7ddc18 | 2024-10-31 19:37:21 | [diff] [blame] | 121 | NOTREACHED(); |
[email protected] | 77b5550 | 2012-11-08 22:20:20 | [diff] [blame] | 122 | } |
| 123 | |
| 124 | ppapi::proxy::SerializedHandle serialized_socket_handle( |
| 125 | ppapi::proxy::SerializedHandle::SOCKET); |
| 126 | ppapi::proxy::SerializedHandle serialized_shared_memory_handle( |
Alexandr Ilin | 002a9a2 | 2018-06-01 13:32:18 | [diff] [blame] | 127 | ppapi::proxy::SerializedHandle::SHARED_MEMORY_REGION); |
[email protected] | 77b5550 | 2012-11-08 22:20:20 | [diff] [blame] | 128 | |
| 129 | if (result == PP_OK) { |
| 130 | IPC::PlatformFileForTransit temp_socket = |
| 131 | IPC::InvalidPlatformFileForTransit(); |
Fredrik Hernqvist | 97f10842 | 2024-12-04 08:38:32 | [diff] [blame] | 132 | base::UnsafeSharedMemoryRegion temp_shmem; |
Alexandr Ilin | 002a9a2 | 2018-06-01 13:32:18 | [diff] [blame] | 133 | result = GetRemoteHandles(scoped_socket, shared_memory_region, &temp_socket, |
| 134 | &temp_shmem); |
[email protected] | 77b5550 | 2012-11-08 22:20:20 | [diff] [blame] | 135 | |
| 136 | serialized_socket_handle.set_socket(temp_socket); |
Alexandr Ilin | 002a9a2 | 2018-06-01 13:32:18 | [diff] [blame] | 137 | serialized_shared_memory_handle.set_shmem_region( |
Fredrik Hernqvist | 97f10842 | 2024-12-04 08:38:32 | [diff] [blame] | 138 | base::UnsafeSharedMemoryRegion::TakeHandleForSerialization( |
Alexandr Ilin | 002a9a2 | 2018-06-01 13:32:18 | [diff] [blame] | 139 | std::move(temp_shmem))); |
[email protected] | 77b5550 | 2012-11-08 22:20:20 | [diff] [blame] | 140 | } |
| 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 Ilin | 1d00410 | 2018-05-30 10:55:32 | [diff] [blame] | 147 | open_context_.params.AppendHandle(std::move(serialized_socket_handle)); |
| 148 | open_context_.params.AppendHandle(std::move(serialized_shared_memory_handle)); |
[email protected] | a850702d | 2014-04-14 21:51:57 | [diff] [blame] | 149 | SendOpenReply(result); |
[email protected] | 77b5550 | 2012-11-08 22:20:20 | [diff] [blame] | 150 | } |
| 151 | |
| 152 | int32_t PepperAudioInputHost::GetRemoteHandles( |
| 153 | const base::SyncSocket& socket, |
Fredrik Hernqvist | 97f10842 | 2024-12-04 08:38:32 | [diff] [blame] | 154 | const base::UnsafeSharedMemoryRegion& shared_memory_region, |
[email protected] | 77b5550 | 2012-11-08 22:20:20 | [diff] [blame] | 155 | IPC::PlatformFileForTransit* remote_socket_handle, |
Fredrik Hernqvist | 97f10842 | 2024-12-04 08:38:32 | [diff] [blame] | 156 | base::UnsafeSharedMemoryRegion* remote_shared_memory_region) { |
Daniel Bratell | 590d6dc0 | 2017-12-07 21:41:21 | [diff] [blame] | 157 | *remote_socket_handle = |
| 158 | renderer_ppapi_host_->ShareHandleWithRemote(socket.handle(), false); |
[email protected] | 77b5550 | 2012-11-08 22:20:20 | [diff] [blame] | 159 | if (*remote_socket_handle == IPC::InvalidPlatformFileForTransit()) |
| 160 | return PP_ERROR_FAILED; |
| 161 | |
Alexandr Ilin | 002a9a2 | 2018-06-01 13:32:18 | [diff] [blame] | 162 | *remote_shared_memory_region = |
Fredrik Hernqvist | 97f10842 | 2024-12-04 08:38:32 | [diff] [blame] | 163 | renderer_ppapi_host_->ShareUnsafeSharedMemoryRegionWithRemote( |
Alexandr Ilin | 002a9a2 | 2018-06-01 13:32:18 | [diff] [blame] | 164 | shared_memory_region); |
| 165 | if (!remote_shared_memory_region->IsValid()) |
[email protected] | 77b5550 | 2012-11-08 22:20:20 | [diff] [blame] | 166 | return PP_ERROR_FAILED; |
| 167 | |
| 168 | return PP_OK; |
| 169 | } |
| 170 | |
| 171 | void PepperAudioInputHost::Close() { |
| 172 | if (!audio_input_) |
| 173 | return; |
| 174 | |
| 175 | audio_input_->ShutDown(); |
Ivan Kotenkov | 2c0d2bb3 | 2017-11-01 15:41:28 | [diff] [blame] | 176 | audio_input_ = nullptr; |
[email protected] | 77b5550 | 2012-11-08 22:20:20 | [diff] [blame] | 177 | |
[email protected] | a850702d | 2014-04-14 21:51:57 | [diff] [blame] | 178 | if (open_context_.is_valid()) |
| 179 | SendOpenReply(PP_ERROR_ABORTED); |
| 180 | } |
| 181 | |
| 182 | void 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] | 77b5550 | 2012-11-08 22:20:20 | [diff] [blame] | 186 | } |
| 187 | |
[email protected] | 77b5550 | 2012-11-08 22:20:20 | [diff] [blame] | 188 | } // namespace content |