[email protected] | 77b5550 | 2012-11-08 22:20:20 | [diff] [blame] | 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 | |
[email protected] | 77b5550 | 2012-11-08 22:20:20 | [diff] [blame] | 7 | #include "base/logging.h" |
| 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" |
[email protected] | 3e1cde6 | 2013-07-26 21:07:17 | [diff] [blame] | 10 | #include "content/renderer/pepper/pepper_media_device_manager.h" |
[email protected] | 3f90dbc4 | 2013-07-26 19:09:27 | [diff] [blame] | 11 | #include "content/renderer/pepper/pepper_platform_audio_input.h" |
[email protected] | adab233 | 2013-07-25 18:04:32 | [diff] [blame] | 12 | #include "content/renderer/pepper/pepper_plugin_instance_impl.h" |
[email protected] | ef695867 | 2013-07-24 19:19:24 | [diff] [blame] | 13 | #include "content/renderer/pepper/renderer_ppapi_host_impl.h" |
[email protected] | 977db4a4 | 2014-07-17 08:04:32 | [diff] [blame] | 14 | #include "content/renderer/render_frame_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 | |
| 24 | namespace { |
| 25 | |
| 26 | base::PlatformFile ConvertSyncSocketHandle(const base::SyncSocket& socket) { |
| 27 | return socket.handle(); |
| 28 | } |
| 29 | |
[email protected] | 77b5550 | 2012-11-08 22:20:20 | [diff] [blame] | 30 | } // namespace |
| 31 | |
[email protected] | ad63b5c | 2014-04-11 21:12:36 | [diff] [blame] | 32 | PepperAudioInputHost::PepperAudioInputHost(RendererPpapiHostImpl* host, |
| 33 | PP_Instance instance, |
| 34 | PP_Resource resource) |
[email protected] | 77b5550 | 2012-11-08 22:20:20 | [diff] [blame] | 35 | : ResourceHost(host->GetPpapiHost(), instance, resource), |
| 36 | renderer_ppapi_host_(host), |
[email protected] | 4f01c76 | 2012-12-05 02:44:18 | [diff] [blame] | 37 | audio_input_(NULL), |
[email protected] | ad63b5c | 2014-04-11 21:12:36 | [diff] [blame] | 38 | enumeration_helper_(this, |
[email protected] | 977db4a4 | 2014-07-17 08:04:32 | [diff] [blame] | 39 | PepperMediaDeviceManager::GetForRenderFrame( |
| 40 | host->GetRenderFrameForInstance(pp_instance())), |
[email protected] | ad63b5c | 2014-04-11 21:12:36 | [diff] [blame] | 41 | PP_DEVICETYPE_DEV_AUDIOCAPTURE, |
| 42 | host->GetDocumentURL(instance)) {} |
[email protected] | 77b5550 | 2012-11-08 22:20:20 | [diff] [blame] | 43 | |
[email protected] | ad63b5c | 2014-04-11 21:12:36 | [diff] [blame] | 44 | PepperAudioInputHost::~PepperAudioInputHost() { Close(); } |
[email protected] | 77b5550 | 2012-11-08 22:20:20 | [diff] [blame] | 45 | |
| 46 | int32_t PepperAudioInputHost::OnResourceMessageReceived( |
| 47 | const IPC::Message& msg, |
| 48 | ppapi::host::HostMessageContext* context) { |
[email protected] | 4f01c76 | 2012-12-05 02:44:18 | [diff] [blame] | 49 | int32_t result = PP_ERROR_FAILED; |
| 50 | if (enumeration_helper_.HandleResourceMessage(msg, context, &result)) |
| 51 | return result; |
| 52 | |
[email protected] | dade5f8 | 2014-05-13 21:59:21 | [diff] [blame] | 53 | 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] | 77b5550 | 2012-11-08 22:20:20 | [diff] [blame] | 59 | return PP_ERROR_FAILED; |
| 60 | } |
| 61 | |
| 62 | void 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 | |
| 69 | void PepperAudioInputHost::StreamCreationFailed() { |
[email protected] | ad63b5c | 2014-04-11 21:12:36 | [diff] [blame] | 70 | OnOpenComplete(PP_ERROR_FAILED, |
| 71 | base::SharedMemory::NULLHandle(), |
| 72 | 0, |
[email protected] | 77b5550 | 2012-11-08 22:20:20 | [diff] [blame] | 73 | base::SyncSocket::kInvalidHandle); |
| 74 | } |
| 75 | |
[email protected] | ad63b5c | 2014-04-11 21:12:36 | [diff] [blame] | 76 | int32_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] | a850702d | 2014-04-14 21:51:57 | [diff] [blame] | 80 | if (open_context_.is_valid()) |
[email protected] | 77b5550 | 2012-11-08 22:20:20 | [diff] [blame] | 81 | return PP_ERROR_INPROGRESS; |
| 82 | if (audio_input_) |
| 83 | return PP_ERROR_FAILED; |
| 84 | |
[email protected] | 83d3c0c1 | 2013-11-05 06:31:03 | [diff] [blame] | 85 | GURL document_url = renderer_ppapi_host_->GetDocumentURL(pp_instance()); |
| 86 | if (!document_url.is_valid()) |
[email protected] | ae6ef14f | 2013-06-13 22:50:52 | [diff] [blame] | 87 | return PP_ERROR_FAILED; |
| 88 | |
[email protected] | 77b5550 | 2012-11-08 22:20:20 | [diff] [blame] | 89 | // When it is done, we'll get called back on StreamCreated() or |
| 90 | // StreamCreationFailed(). |
[email protected] | 977db4a4 | 2014-07-17 08:04:32 | [diff] [blame] | 91 | 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] | 77b5550 | 2012-11-08 22:20:20 | [diff] [blame] | 99 | if (audio_input_) { |
[email protected] | a850702d | 2014-04-14 21:51:57 | [diff] [blame] | 100 | open_context_ = context->MakeReplyMessageContext(); |
[email protected] | 77b5550 | 2012-11-08 22:20:20 | [diff] [blame] | 101 | return PP_OK_COMPLETIONPENDING; |
| 102 | } else { |
| 103 | return PP_ERROR_FAILED; |
| 104 | } |
| 105 | } |
| 106 | |
[email protected] | 3d9ec505 | 2013-01-02 22:05:25 | [diff] [blame] | 107 | int32_t PepperAudioInputHost::OnStartOrStop( |
[email protected] | 77b5550 | 2012-11-08 22:20:20 | [diff] [blame] | 108 | 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] | 3d9ec505 | 2013-01-02 22:05:25 | [diff] [blame] | 119 | int32_t PepperAudioInputHost::OnClose( |
[email protected] | 77b5550 | 2012-11-08 22:20:20 | [diff] [blame] | 120 | ppapi::host::HostMessageContext* /* context */) { |
| 121 | Close(); |
| 122 | return PP_OK; |
| 123 | } |
| 124 | |
[email protected] | 77b5550 | 2012-11-08 22:20:20 | [diff] [blame] | 125 | void 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] | a850702d | 2014-04-14 21:51:57 | [diff] [blame] | 134 | if (!open_context_.is_valid()) { |
[email protected] | 77b5550 | 2012-11-08 22:20:20 | [diff] [blame] | 135 | 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] | 078c07bd | 2013-10-23 21:33:46 | [diff] [blame] | 152 | serialized_shared_memory_handle.set_shmem(temp_shmem, shared_memory_size); |
[email protected] | 77b5550 | 2012-11-08 22:20:20 | [diff] [blame] | 153 | } |
| 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] | a850702d | 2014-04-14 21:51:57 | [diff] [blame] | 160 | open_context_.params.AppendHandle(serialized_socket_handle); |
| 161 | open_context_.params.AppendHandle(serialized_shared_memory_handle); |
| 162 | SendOpenReply(result); |
[email protected] | 77b5550 | 2012-11-08 22:20:20 | [diff] [blame] | 163 | } |
| 164 | |
| 165 | int32_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 | |
erikchen | 4fc32d5 | 2015-06-02 02:16:38 | [diff] [blame] | 175 | *remote_shared_memory_handle = |
| 176 | renderer_ppapi_host_->ShareSharedMemoryHandleWithRemote( |
| 177 | shared_memory.handle()); |
| 178 | if (!base::SharedMemory::IsHandleValid(*remote_shared_memory_handle)) |
[email protected] | 77b5550 | 2012-11-08 22:20:20 | [diff] [blame] | 179 | return PP_ERROR_FAILED; |
| 180 | |
| 181 | return PP_OK; |
| 182 | } |
| 183 | |
| 184 | void PepperAudioInputHost::Close() { |
| 185 | if (!audio_input_) |
| 186 | return; |
| 187 | |
| 188 | audio_input_->ShutDown(); |
| 189 | audio_input_ = NULL; |
| 190 | |
[email protected] | a850702d | 2014-04-14 21:51:57 | [diff] [blame] | 191 | if (open_context_.is_valid()) |
| 192 | SendOpenReply(PP_ERROR_ABORTED); |
| 193 | } |
| 194 | |
| 195 | void 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] | 77b5550 | 2012-11-08 22:20:20 | [diff] [blame] | 199 | } |
| 200 | |
[email protected] | 77b5550 | 2012-11-08 22:20:20 | [diff] [blame] | 201 | } // namespace content |