| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "webkit/plugins/ppapi/ppb_audio_input_impl.h" | 5 #include "webkit/plugins/ppapi/ppb_audio_input_impl.h" |
| 6 | 6 |
| 7 #include "base/bind.h" |
| 7 #include "base/logging.h" | 8 #include "base/logging.h" |
| 8 #include "ppapi/c/dev/ppb_audio_input_dev.h" | 9 #include "base/memory/ref_counted.h" |
| 10 #include "base/shared_memory.h" |
| 11 #include "base/sync_socket.h" |
| 12 #include "build/build_config.h" |
| 9 #include "ppapi/c/pp_completion_callback.h" | 13 #include "ppapi/c/pp_completion_callback.h" |
| 10 #include "ppapi/c/ppb_audio_config.h" | 14 #include "ppapi/shared_impl/ppb_device_ref_shared.h" |
| 11 #include "ppapi/c/trusted/ppb_audio_input_trusted_dev.h" | 15 #include "ppapi/shared_impl/tracked_callback.h" |
| 12 #include "ppapi/shared_impl/resource_tracker.h" | |
| 13 #include "ppapi/thunk/enter.h" | |
| 14 #include "ppapi/thunk/ppb_audio_config_api.h" | |
| 15 #include "ppapi/thunk/thunk.h" | |
| 16 #include "webkit/plugins/ppapi/common.h" | 16 #include "webkit/plugins/ppapi/common.h" |
| 17 #include "webkit/plugins/ppapi/resource_helper.h" | 17 #include "webkit/plugins/ppapi/resource_helper.h" |
| 18 | 18 |
| 19 using ppapi::PpapiGlobals; | |
| 20 using ppapi::thunk::EnterResourceNoLock; | |
| 21 using ppapi::thunk::PPB_AudioInput_API; | |
| 22 using ppapi::thunk::PPB_AudioConfig_API; | |
| 23 using ppapi::TrackedCallback; | 19 using ppapi::TrackedCallback; |
| 24 | 20 |
| 25 namespace webkit { | 21 namespace webkit { |
| 26 namespace ppapi { | 22 namespace ppapi { |
| 27 | 23 |
| 28 // PPB_AudioInput_Impl --------------------------------------------------------- | 24 // PPB_AudioInput_Impl --------------------------------------------------------- |
| 29 | 25 |
| 30 PPB_AudioInput_Impl::PPB_AudioInput_Impl(PP_Instance instance) | 26 PPB_AudioInput_Impl::PPB_AudioInput_Impl(PP_Instance instance) |
| 31 : Resource(::ppapi::OBJECT_IS_IMPL, instance), | 27 : ::ppapi::PPB_AudioInput_Shared(instance), |
| 32 audio_input_(NULL) { | 28 audio_input_(NULL) { |
| 33 } | 29 } |
| 34 | 30 |
| 35 PPB_AudioInput_Impl::~PPB_AudioInput_Impl() { | 31 PPB_AudioInput_Impl::~PPB_AudioInput_Impl() { |
| 36 // Calling ShutDown() makes sure StreamCreated cannot be called anymore and | 32 Close(); |
| 33 } |
| 34 |
| 35 // static |
| 36 PP_Resource PPB_AudioInput_Impl::Create0_1( |
| 37 PP_Instance instance, |
| 38 PP_Resource config, |
| 39 PPB_AudioInput_Callback audio_input_callback, |
| 40 void* user_data) { |
| 41 scoped_refptr<PPB_AudioInput_Impl> |
| 42 audio_input(new PPB_AudioInput_Impl(instance)); |
| 43 int32_t result = audio_input->Open( |
| 44 "", config, audio_input_callback, user_data, |
| 45 MakeIgnoredCompletionCallback()); |
| 46 if (result != PP_OK && result != PP_OK_COMPLETIONPENDING) |
| 47 return 0; |
| 48 return audio_input->GetReference(); |
| 49 } |
| 50 |
| 51 int32_t PPB_AudioInput_Impl::OpenTrusted( |
| 52 const std::string& device_id, |
| 53 PP_Resource config, |
| 54 PP_CompletionCallback create_callback) { |
| 55 return CommonOpen(device_id, config, NULL, NULL, create_callback); |
| 56 } |
| 57 |
| 58 int32_t PPB_AudioInput_Impl::GetSyncSocket(int* sync_socket) { |
| 59 if (socket_.get()) { |
| 60 #if defined(OS_POSIX) |
| 61 *sync_socket = socket_->handle(); |
| 62 #elif defined(OS_WIN) |
| 63 *sync_socket = reinterpret_cast<int>(socket_->handle()); |
| 64 #else |
| 65 #error "Platform not supported." |
| 66 #endif |
| 67 return PP_OK; |
| 68 } |
| 69 return PP_ERROR_FAILED; |
| 70 } |
| 71 |
| 72 int32_t PPB_AudioInput_Impl::GetSharedMemory(int* shm_handle, |
| 73 uint32_t* shm_size) { |
| 74 if (shared_memory_.get()) { |
| 75 #if defined(OS_POSIX) |
| 76 *shm_handle = shared_memory_->handle().fd; |
| 77 #elif defined(OS_WIN) |
| 78 *shm_handle = reinterpret_cast<int>(shared_memory_->handle()); |
| 79 #else |
| 80 #error "Platform not supported." |
| 81 #endif |
| 82 *shm_size = shared_memory_size_; |
| 83 return PP_OK; |
| 84 } |
| 85 return PP_ERROR_FAILED; |
| 86 } |
| 87 |
| 88 const PPB_AudioInput_Impl::DeviceRefDataVector& |
| 89 PPB_AudioInput_Impl::GetDeviceRefData() const { |
| 90 return devices_data_; |
| 91 } |
| 92 |
| 93 void PPB_AudioInput_Impl::StreamCreated( |
| 94 base::SharedMemoryHandle shared_memory_handle, |
| 95 size_t shared_memory_size, |
| 96 base::SyncSocket::Handle socket) { |
| 97 // TODO(yzshen): Report open failure. |
| 98 OnOpenComplete(PP_OK, shared_memory_handle, shared_memory_size, socket); |
| 99 } |
| 100 |
| 101 int32_t PPB_AudioInput_Impl::InternalEnumerateDevices( |
| 102 PP_Resource* devices, |
| 103 PP_CompletionCallback callback) { |
| 104 PluginDelegate* plugin_delegate = ResourceHelper::GetPluginDelegate(this); |
| 105 if (!plugin_delegate) |
| 106 return PP_ERROR_FAILED; |
| 107 |
| 108 devices_ = devices; |
| 109 enumerate_devices_callback_ = new TrackedCallback(this, callback); |
| 110 plugin_delegate->EnumerateDevices( |
| 111 PP_DEVICETYPE_DEV_AUDIOCAPTURE, |
| 112 base::Bind(&PPB_AudioInput_Impl::EnumerateDevicesCallbackFunc, |
| 113 AsWeakPtr())); |
| 114 return PP_OK_COMPLETIONPENDING; |
| 115 } |
| 116 |
| 117 int32_t PPB_AudioInput_Impl::InternalOpen(const std::string& device_id, |
| 118 PP_AudioSampleRate sample_rate, |
| 119 uint32_t sample_frame_count, |
| 120 PP_CompletionCallback callback) { |
| 121 PluginDelegate* plugin_delegate = ResourceHelper::GetPluginDelegate(this); |
| 122 if (!plugin_delegate) |
| 123 return PP_ERROR_FAILED; |
| 124 |
| 125 // TODO(yzshen): Open the device specified by |device_id|. |
| 126 // When the stream is created, we'll get called back on StreamCreated(). |
| 127 DCHECK(!audio_input_); |
| 128 audio_input_ = plugin_delegate->CreateAudioInput( |
| 129 sample_rate, sample_frame_count, this); |
| 130 if (audio_input_) { |
| 131 open_callback_ = new TrackedCallback(this, callback); |
| 132 return PP_OK_COMPLETIONPENDING; |
| 133 } else { |
| 134 return PP_ERROR_FAILED; |
| 135 } |
| 136 } |
| 137 |
| 138 PP_Bool PPB_AudioInput_Impl::InternalStartCapture() { |
| 139 if (!audio_input_) |
| 140 return PP_FALSE; |
| 141 SetStartCaptureState(); |
| 142 return BoolToPPBool(audio_input_->StartCapture()); |
| 143 } |
| 144 |
| 145 PP_Bool PPB_AudioInput_Impl::InternalStopCapture() { |
| 146 if (!audio_input_) |
| 147 return PP_FALSE; |
| 148 if (!audio_input_->StopCapture()) |
| 149 return PP_FALSE; |
| 150 SetStopCaptureState(); |
| 151 return PP_TRUE; |
| 152 } |
| 153 |
| 154 void PPB_AudioInput_Impl::InternalClose() { |
| 155 // Calling ShutDown() makes sure StreamCreated() cannot be called anymore and |
| 37 // releases the audio data associated with the pointer. Note however, that | 156 // releases the audio data associated with the pointer. Note however, that |
| 38 // until ShutDown returns, StreamCreated may still be called. This will be | 157 // until ShutDown() returns, StreamCreated() may still be called. This will be |
| 39 // OK since we'll just immediately clean up the data it stored later in this | 158 // OK since OnOpenComplete() will clean up the handles and do nothing else in |
| 40 // destructor. | 159 // that case. |
| 41 if (audio_input_) { | 160 if (audio_input_) { |
| 42 audio_input_->ShutDown(); | 161 audio_input_->ShutDown(); |
| 43 audio_input_ = NULL; | 162 audio_input_ = NULL; |
| 44 } | 163 } |
| 45 } | 164 } |
| 46 | 165 |
| 47 // static | 166 void PPB_AudioInput_Impl::EnumerateDevicesCallbackFunc( |
| 48 PP_Resource PPB_AudioInput_Impl::Create( | 167 int request_id, |
| 49 PP_Instance instance, | 168 bool succeeded, |
| 50 PP_Resource config, | 169 const DeviceRefDataVector& devices) { |
| 51 PPB_AudioInput_Callback audio_input_callback, | 170 devices_data_.clear(); |
| 52 void* user_data) { | 171 if (succeeded) |
| 53 scoped_refptr<PPB_AudioInput_Impl> | 172 devices_data_ = devices; |
| 54 audio_input(new PPB_AudioInput_Impl(instance)); | |
| 55 if (!audio_input->Init(config, audio_input_callback, user_data)) | |
| 56 return 0; | |
| 57 return audio_input->GetReference(); | |
| 58 } | |
| 59 | 173 |
| 60 PPB_AudioInput_API* PPB_AudioInput_Impl::AsPPB_AudioInput_API() { | 174 OnEnumerateDevicesComplete(succeeded ? PP_OK : PP_ERROR_FAILED, devices); |
| 61 return this; | |
| 62 } | |
| 63 | |
| 64 bool PPB_AudioInput_Impl::Init(PP_Resource config, | |
| 65 PPB_AudioInput_Callback callback, | |
| 66 void* user_data) { | |
| 67 // Validate the config and keep a reference to it. | |
| 68 EnterResourceNoLock<PPB_AudioConfig_API> enter(config, true); | |
| 69 if (enter.failed()) | |
| 70 return false; | |
| 71 config_ = config; | |
| 72 | |
| 73 if (!callback) | |
| 74 return false; | |
| 75 SetCallback(callback, user_data); | |
| 76 | |
| 77 PluginDelegate* plugin_delegate = ResourceHelper::GetPluginDelegate(this); | |
| 78 if (!plugin_delegate) | |
| 79 return false; | |
| 80 | |
| 81 // When the stream is created, we'll get called back on StreamCreated(). | |
| 82 CHECK(!audio_input_); | |
| 83 audio_input_ = plugin_delegate->CreateAudioInput( | |
| 84 enter.object()->GetSampleRate(), | |
| 85 enter.object()->GetSampleFrameCount(), | |
| 86 this); | |
| 87 return audio_input_ != NULL; | |
| 88 } | |
| 89 | |
| 90 PP_Resource PPB_AudioInput_Impl::GetCurrentConfig() { | |
| 91 // AddRef on behalf of caller, while keeping a ref for ourselves. | |
| 92 PpapiGlobals::Get()->GetResourceTracker()->AddRefResource(config_); | |
| 93 return config_; | |
| 94 } | |
| 95 | |
| 96 PP_Bool PPB_AudioInput_Impl::StartCapture() { | |
| 97 if (!audio_input_) | |
| 98 return PP_FALSE; | |
| 99 if (capturing()) | |
| 100 return PP_TRUE; | |
| 101 SetStartCaptureState(); | |
| 102 return BoolToPPBool(audio_input_->StartCapture()); | |
| 103 } | |
| 104 | |
| 105 PP_Bool PPB_AudioInput_Impl::StopCapture() { | |
| 106 if (!audio_input_) | |
| 107 return PP_FALSE; | |
| 108 if (!capturing()) | |
| 109 return PP_TRUE; | |
| 110 if (!audio_input_->StopCapture()) | |
| 111 return PP_FALSE; | |
| 112 SetStopCaptureState(); | |
| 113 return PP_TRUE; | |
| 114 } | |
| 115 | |
| 116 int32_t PPB_AudioInput_Impl::OpenTrusted( | |
| 117 PP_Resource config, | |
| 118 PP_CompletionCallback create_callback) { | |
| 119 // Validate the config and keep a reference to it. | |
| 120 EnterResourceNoLock<PPB_AudioConfig_API> enter(config, true); | |
| 121 if (enter.failed()) | |
| 122 return PP_ERROR_FAILED; | |
| 123 config_ = config; | |
| 124 | |
| 125 PluginDelegate* plugin_delegate = ResourceHelper::GetPluginDelegate(this); | |
| 126 if (!plugin_delegate) | |
| 127 return PP_ERROR_FAILED; | |
| 128 | |
| 129 // When the stream is created, we'll get called back on StreamCreated(). | |
| 130 DCHECK(!audio_input_); | |
| 131 audio_input_ = plugin_delegate->CreateAudioInput( | |
| 132 enter.object()->GetSampleRate(), | |
| 133 enter.object()->GetSampleFrameCount(), | |
| 134 this); | |
| 135 | |
| 136 if (!audio_input_) | |
| 137 return PP_ERROR_FAILED; | |
| 138 | |
| 139 // At this point, we are guaranteeing ownership of the completion | |
| 140 // callback. Audio promises to fire the completion callback | |
| 141 // once and only once. | |
| 142 SetCreateCallback(new TrackedCallback(this, create_callback)); | |
| 143 return PP_OK_COMPLETIONPENDING; | |
| 144 } | |
| 145 | |
| 146 int32_t PPB_AudioInput_Impl::GetSyncSocket(int* sync_socket) { | |
| 147 return GetSyncSocketImpl(sync_socket); | |
| 148 } | |
| 149 | |
| 150 int32_t PPB_AudioInput_Impl::GetSharedMemory(int* shm_handle, | |
| 151 uint32_t* shm_size) { | |
| 152 return GetSharedMemoryImpl(shm_handle, shm_size); | |
| 153 } | |
| 154 | |
| 155 void PPB_AudioInput_Impl::OnSetStreamInfo( | |
| 156 base::SharedMemoryHandle shared_memory_handle, | |
| 157 size_t shared_memory_size, | |
| 158 base::SyncSocket::Handle socket_handle) { | |
| 159 SetStreamInfo(shared_memory_handle, shared_memory_size, socket_handle); | |
| 160 } | 175 } |
| 161 | 176 |
| 162 } // namespace ppapi | 177 } // namespace ppapi |
| 163 } // namespace webkit | 178 } // namespace webkit |
| OLD | NEW |