diff options
author | viettrungluu@chromium.org <viettrungluu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-18 00:14:24 +0000 |
---|---|---|
committer | viettrungluu@chromium.org <viettrungluu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-18 00:14:24 +0000 |
commit | 1f8a089555312f281aa4074141e0945096d2a621 (patch) | |
tree | 32ace48d91e7eb290bd2b8df39e7fbc17282fcdf /ppapi | |
parent | fc2436bac6a8e5f6839f6e62e8680a15e7d592eb (diff) | |
download | chromium_src-1f8a089555312f281aa4074141e0945096d2a621.zip chromium_src-1f8a089555312f281aa4074141e0945096d2a621.tar.gz chromium_src-1f8a089555312f281aa4074141e0945096d2a621.tar.bz2 |
Revert 110602 - Revert 110587 - Microphone support for Pepper Flash.
[I think the Windows shared builders just need to be clobbered.]
[Committing for pbrophy@adobe.com. Original review:
http://codereview.chromium.org/8138008/ .]
This change supports audio capture from the microphone and supplies the data
through a Pepper interface. Its enumeration is limited to the default audio
device that uses mono 44.1kHz.
TBR=tony@chromium.org
Review URL: http://codereview.chromium.org/8574029
TBR=viettrungluu@chromium.org
Review URL: http://codereview.chromium.org/8569003
TBR=ajwong@chromium.org
Review URL: http://codereview.chromium.org/8561003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@110609 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi')
25 files changed, 1268 insertions, 2 deletions
diff --git a/ppapi/api/dev/ppb_audio_input_dev.idl b/ppapi/api/dev/ppb_audio_input_dev.idl new file mode 100644 index 0000000..ba6b578 --- /dev/null +++ b/ppapi/api/dev/ppb_audio_input_dev.idl @@ -0,0 +1,94 @@ +/* Copyright (c) 2011 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/** + * This file defines the <code>PPB_AudioInput_Dev</code> interface, which + * provides realtime audio input capture. + */ + +label Chrome { + M17 = 0.1 +}; + +/** + * <code>PPB_AudioInput_Callback</code> defines the type of an audio callback + * function used to provide the audio buffer with data. This callback will be + * called on a separate thread to the creation thread. + */ +typedef void PPB_AudioInput_Callback([out] mem_t sample_buffer, + [in] uint32_t buffer_size_in_bytes, + [inout] mem_t user_data); + +/** + * The <code>PPB_AudioInput_Dev</code> interface contains pointers to several + * functions for handling audio input resources. + */ +[version=0.1, macro="PPB_AUDIO_INPUT_DEV_INTERFACE"] +interface PPB_AudioInput_Dev { + /** + * Create is a pointer to a function that creates an audio input resource. + * No sound will be captured until StartCapture() is called. + */ + PP_Resource Create( + [in] PP_Instance instance, + [in] PP_Resource config, + [in] PPB_AudioInput_Callback audio_input_callback, + [inout] mem_t user_data); + + /** + * IsAudioInput is a pointer to a function that determines if the given + * resource is an audio input resource. + * + * @param[in] resource A PP_Resource containing a resource. + * + * @return A PP_BOOL containing containing PP_TRUE if the given resource is + * an audio input resource, otherwise PP_FALSE. + */ + PP_Bool IsAudioInput( + [in] PP_Resource audio_input); + + /** + * GetCurrrentConfig() returns an audio config resource for the given audio + * resource. + * + * @param[in] config A <code>PP_Resource</code> corresponding to an audio + * resource. + * + * @return A <code>PP_Resource</code> containing the audio config resource if + * successful. + */ + PP_Resource GetCurrentConfig( + [in] PP_Resource audio_input); + + /** + * StartCapture() starts the capture of the audio input resource and begins + * periodically calling the callback. + * + * @param[in] config A <code>PP_Resource</code> corresponding to an audio + * input resource. + * + * @return A <code>PP_Bool</code> containing <code>PP_TRUE</code> if + * successful, otherwise <code>PP_FALSE</code>. Also returns + * <code>PP_TRUE</code> (and be a no-op) if called while callback is already + * in progress. + */ + PP_Bool StartCapture( + [in] PP_Resource audio_input); + + /** + * StopCapture is a pointer to a function that stops the capture of + * the audio input resource. + * + * @param[in] config A PP_Resource containing the audio input resource. + * + * @return A PP_BOOL containing PP_TRUE if successful, otherwise PP_FALSE. + * Also returns PP_TRUE (and is a no-op) if called while capture is already + * stopped. If a buffer is being captured, StopCapture will block until the + * call completes. + */ + PP_Bool StopCapture( + [in] PP_Resource audio_input); +}; + diff --git a/ppapi/api/trusted/ppb_audio_input_trusted_dev.idl b/ppapi/api/trusted/ppb_audio_input_trusted_dev.idl new file mode 100644 index 0000000..860c2e3 --- /dev/null +++ b/ppapi/api/trusted/ppb_audio_input_trusted_dev.idl @@ -0,0 +1,53 @@ +/* Copyright (c) 2011 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +/** + * This file defines the trusted audio input interface. + */ + +label Chrome { + M17 = 0.1 +}; + +/** + * This interface is to be used by proxy implementations. All + * functions should be called from the main thread only. The + * resource returned is an Audio input esource; most of the PPB_Audio + * interface is also usable on this resource. + */ +[version=0.1, macro="PPB_AUDIO_INPUT_TRUSTED_DEV_INTERFACE"] +interface PPB_AudioInputTrusted_Dev { + /** Returns an audio input resource. */ + PP_Resource CreateTrusted( + [in] PP_Instance instance); + + /** + * Opens a paused audio interface, used by trusted side of proxy. + * Returns PP_ERROR_WOULD_BLOCK on success, and invokes + * the |create_callback| asynchronously to complete. + * As this function should always be invoked from the main thread, + * do not use the blocking variant of PP_CompletionCallback. + */ + int32_t Open( + [in] PP_Resource audio_input, + [in] PP_Resource config, + [in] PP_CompletionCallback create_callback); + + /** + * Get the sync socket. Use once Open has completed. + * Returns PP_OK on success. + */ + int32_t GetSyncSocket( + [in] PP_Resource audio_input, + [out] handle_t sync_socket); + + /** + * Get the shared memory interface. Use once Open has completed. + * Returns PP_OK on success. + */ + int32_t GetSharedMemory( + [in] PP_Resource audio_input, + [out] handle_t shm_handle, + [out] uint32_t shm_size); +}; diff --git a/ppapi/c/dev/ppb_audio_input_dev.h b/ppapi/c/dev/ppb_audio_input_dev.h new file mode 100644 index 0000000..ed9e098 --- /dev/null +++ b/ppapi/c/dev/ppb_audio_input_dev.h @@ -0,0 +1,112 @@ +/* Copyright (c) 2011 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* From dev/ppb_audio_input_dev.idl modified Mon Nov 14 17:58:16 2011. */ + +#ifndef PPAPI_C_DEV_PPB_AUDIO_INPUT_DEV_H_ +#define PPAPI_C_DEV_PPB_AUDIO_INPUT_DEV_H_ + +#include "ppapi/c/pp_bool.h" +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/pp_macros.h" +#include "ppapi/c/pp_resource.h" +#include "ppapi/c/pp_stdint.h" + +#define PPB_AUDIO_INPUT_DEV_INTERFACE_0_1 "PPB_AudioInput(Dev);0.1" +#define PPB_AUDIO_INPUT_DEV_INTERFACE PPB_AUDIO_INPUT_DEV_INTERFACE_0_1 + +/** + * @file + * This file defines the <code>PPB_AudioInput_Dev</code> interface, which + * provides realtime audio input capture. + */ + + +/** + * @addtogroup Typedefs + * @{ + */ +/** + * <code>PPB_AudioInput_Callback</code> defines the type of an audio callback + * function used to provide the audio buffer with data. This callback will be + * called on a separate thread to the creation thread. + */ +typedef void (*PPB_AudioInput_Callback)(void* sample_buffer, + uint32_t buffer_size_in_bytes, + void* user_data); +/** + * @} + */ + +/** + * @addtogroup Interfaces + * @{ + */ +/** + * The <code>PPB_AudioInput_Dev</code> interface contains pointers to several + * functions for handling audio input resources. + */ +struct PPB_AudioInput_Dev { + /** + * Create is a pointer to a function that creates an audio input resource. + * No sound will be captured until StartCapture() is called. + */ + PP_Resource (*Create)(PP_Instance instance, + PP_Resource config, + PPB_AudioInput_Callback audio_input_callback, + void* user_data); + /** + * IsAudioInput is a pointer to a function that determines if the given + * resource is an audio input resource. + * + * @param[in] resource A PP_Resource containing a resource. + * + * @return A PP_BOOL containing containing PP_TRUE if the given resource is + * an audio input resource, otherwise PP_FALSE. + */ + PP_Bool (*IsAudioInput)(PP_Resource audio_input); + /** + * GetCurrrentConfig() returns an audio config resource for the given audio + * resource. + * + * @param[in] config A <code>PP_Resource</code> corresponding to an audio + * resource. + * + * @return A <code>PP_Resource</code> containing the audio config resource if + * successful. + */ + PP_Resource (*GetCurrentConfig)(PP_Resource audio_input); + /** + * StartCapture() starts the capture of the audio input resource and begins + * periodically calling the callback. + * + * @param[in] config A <code>PP_Resource</code> corresponding to an audio + * input resource. + * + * @return A <code>PP_Bool</code> containing <code>PP_TRUE</code> if + * successful, otherwise <code>PP_FALSE</code>. Also returns + * <code>PP_TRUE</code> (and be a no-op) if called while callback is already + * in progress. + */ + PP_Bool (*StartCapture)(PP_Resource audio_input); + /** + * StopCapture is a pointer to a function that stops the capture of + * the audio input resource. + * + * @param[in] config A PP_Resource containing the audio input resource. + * + * @return A PP_BOOL containing PP_TRUE if successful, otherwise PP_FALSE. + * Also returns PP_TRUE (and is a no-op) if called while capture is already + * stopped. If a buffer is being captured, StopCapture will block until the + * call completes. + */ + PP_Bool (*StopCapture)(PP_Resource audio_input); +}; +/** + * @} + */ + +#endif /* PPAPI_C_DEV_PPB_AUDIO_INPUT_DEV_H_ */ + diff --git a/ppapi/c/trusted/ppb_audio_input_trusted_dev.h b/ppapi/c/trusted/ppb_audio_input_trusted_dev.h new file mode 100644 index 0000000..bbdb44f --- /dev/null +++ b/ppapi/c/trusted/ppb_audio_input_trusted_dev.h @@ -0,0 +1,69 @@ +/* Copyright (c) 2011 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* From trusted/ppb_audio_input_trusted_dev.idl modified Mon Nov 14 18:13:23 2011. */ + +#ifndef PPAPI_C_TRUSTED_PPB_AUDIO_INPUT_TRUSTED_DEV_H_ +#define PPAPI_C_TRUSTED_PPB_AUDIO_INPUT_TRUSTED_DEV_H_ + +#include "ppapi/c/pp_completion_callback.h" +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/pp_macros.h" +#include "ppapi/c/pp_resource.h" +#include "ppapi/c/pp_stdint.h" + +#define PPB_AUDIO_INPUT_TRUSTED_DEV_INTERFACE_0_1 \ + "PPB_AudioInputTrusted(Dev);0.1" +#define PPB_AUDIO_INPUT_TRUSTED_DEV_INTERFACE \ + PPB_AUDIO_INPUT_TRUSTED_DEV_INTERFACE_0_1 + +/** + * @file + * This file defines the trusted audio input interface. + */ + + +/** + * @addtogroup Interfaces + * @{ + */ +/** + * This interface is to be used by proxy implementations. All + * functions should be called from the main thread only. The + * resource returned is an Audio input esource; most of the PPB_Audio + * interface is also usable on this resource. + */ +struct PPB_AudioInputTrusted_Dev { + /** Returns an audio input resource. */ + PP_Resource (*CreateTrusted)(PP_Instance instance); + /** + * Opens a paused audio interface, used by trusted side of proxy. + * Returns PP_ERROR_WOULD_BLOCK on success, and invokes + * the |create_callback| asynchronously to complete. + * As this function should always be invoked from the main thread, + * do not use the blocking variant of PP_CompletionCallback. + */ + int32_t (*Open)(PP_Resource audio_input, + PP_Resource config, + struct PP_CompletionCallback create_callback); + /** + * Get the sync socket. Use once Open has completed. + * Returns PP_OK on success. + */ + int32_t (*GetSyncSocket)(PP_Resource audio_input, int* sync_socket); + /** + * Get the shared memory interface. Use once Open has completed. + * Returns PP_OK on success. + */ + int32_t (*GetSharedMemory)(PP_Resource audio_input, + int* shm_handle, + uint32_t* shm_size); +}; +/** + * @} + */ + +#endif /* PPAPI_C_TRUSTED_PPB_AUDIO_INPUT_TRUSTED_DEV_H_ */ + diff --git a/ppapi/cpp/dev/audio_input_dev.cc b/ppapi/cpp/dev/audio_input_dev.cc new file mode 100644 index 0000000..fd81945 --- /dev/null +++ b/ppapi/cpp/dev/audio_input_dev.cc @@ -0,0 +1,44 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ppapi/cpp/dev/audio_input_dev.h" + +#include "ppapi/c/dev/ppb_audio_input_dev.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/cpp/instance.h" +#include "ppapi/cpp/module.h" +#include "ppapi/cpp/module_impl.h" + +namespace pp { + +namespace { + +template <> const char* interface_name<PPB_AudioInput_Dev>() { + return PPB_AUDIO_INPUT_DEV_INTERFACE; +} + +} // namespace + +AudioInput_Dev::AudioInput_Dev(Instance* instance, + const AudioConfig& config, + PPB_AudioInput_Callback callback, + void* user_data) + : config_(config) { + if (has_interface<PPB_AudioInput_Dev>()) { + PassRefFromConstructor(get_interface<PPB_AudioInput_Dev>()->Create( + instance->pp_instance(), config.pp_resource(), callback, user_data)); + } +} + +bool AudioInput_Dev::StartCapture() { + return has_interface<PPB_AudioInput_Dev>() && + get_interface<PPB_AudioInput_Dev>()->StartCapture(pp_resource()); +} + +bool AudioInput_Dev::StopCapture() { + return has_interface<PPB_AudioInput_Dev>() && + get_interface<PPB_AudioInput_Dev>()->StopCapture(pp_resource()); +} + +} // namespace pp diff --git a/ppapi/cpp/dev/audio_input_dev.h b/ppapi/cpp/dev/audio_input_dev.h new file mode 100644 index 0000000..2a51eb7 --- /dev/null +++ b/ppapi/cpp/dev/audio_input_dev.h @@ -0,0 +1,48 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef PPAPI_CPP_DEV_AUDIO_INPUT_DEV_H_ +#define PPAPI_CPP_DEV_AUDIO_INPUT_DEV_H_ + +#include "ppapi/c/dev/ppb_audio_input_dev.h" +#include "ppapi/cpp/audio_config.h" +#include "ppapi/cpp/resource.h" + +namespace pp { + +class Instance; + +class AudioInput_Dev : public Resource { + public: + /// An empty constructor for an AudioInput resource. + AudioInput_Dev() {} + + AudioInput_Dev(Instance* instance, + const AudioConfig& config, + PPB_AudioInput_Callback callback, + void* user_data); + + /// Getter function for returning the internal <code>PPB_AudioConfig</code> + /// struct. + /// + /// @return A mutable reference to the PPB_AudioConfig struct. + AudioConfig& config() { return config_; } + + /// Getter function for returning the internal <code>PPB_AudioConfig</code> + /// struct. + /// + /// @return A const reference to the internal <code>PPB_AudioConfig</code> + /// struct. + const AudioConfig& config() const { return config_; } + + bool StartCapture(); + bool StopCapture(); + + private: + AudioConfig config_; +}; + +} // namespace pp + +#endif // PPAPI_CPP_DEV_AUDIO_INPUT_DEV_H_ diff --git a/ppapi/ppapi_cpp.gypi b/ppapi/ppapi_cpp.gypi index 8f8ba1d..7a34e52 100644 --- a/ppapi/ppapi_cpp.gypi +++ b/ppapi/ppapi_cpp.gypi @@ -198,6 +198,8 @@ 'cpp/var.h', # Dev interfaces. + 'cpp/dev/audio_input_dev.cc', + 'cpp/dev/audio_input_dev.h', 'cpp/dev/buffer_dev.cc', 'cpp/dev/buffer_dev.h', 'cpp/dev/context_3d_dev.cc', diff --git a/ppapi/ppapi_proxy.gypi b/ppapi/ppapi_proxy.gypi index 955a5f8..b1d3ee8 100644 --- a/ppapi/ppapi_proxy.gypi +++ b/ppapi/ppapi_proxy.gypi @@ -56,6 +56,8 @@ 'proxy/ppapi_messages.h', 'proxy/ppapi_param_traits.cc', 'proxy/ppapi_param_traits.h', + 'proxy/ppb_audio_input_proxy.cc', + 'proxy/ppb_audio_input_proxy.h', 'proxy/ppb_audio_proxy.cc', 'proxy/ppb_audio_proxy.h', 'proxy/ppb_broker_proxy.cc', diff --git a/ppapi/ppapi_shared.gypi b/ppapi/ppapi_shared.gypi index a3f4806..93d9f61 100644 --- a/ppapi/ppapi_shared.gypi +++ b/ppapi/ppapi_shared.gypi @@ -34,6 +34,8 @@ 'shared_impl/audio_config_impl.h', 'shared_impl/audio_impl.cc', 'shared_impl/audio_impl.h', + 'shared_impl/audio_input_impl.cc', + 'shared_impl/audio_input_impl.h', 'shared_impl/char_set_impl.cc', 'shared_impl/char_set_impl.h', 'shared_impl/crypto_impl.cc', @@ -97,6 +99,9 @@ 'thunk/ppb_audio_api.h', 'thunk/ppb_audio_config_api.h', 'thunk/ppb_audio_config_thunk.cc', + 'thunk/ppb_audio_input_api.h', + 'thunk/ppb_audio_input_thunk.cc', + 'thunk/ppb_audio_input_trusted_thunk.cc', 'thunk/ppb_audio_thunk.cc', 'thunk/ppb_audio_trusted_thunk.cc', 'thunk/ppb_broker_api.h', diff --git a/ppapi/proxy/interface_list.cc b/ppapi/proxy/interface_list.cc index 0d654a5..96ee6bc 100644 --- a/ppapi/proxy/interface_list.cc +++ b/ppapi/proxy/interface_list.cc @@ -5,6 +5,7 @@ #include "ppapi/proxy/interface_list.h" #include "base/memory/singleton.h" +#include "ppapi/c/dev/ppb_audio_input_dev.h" #include "ppapi/c/dev/ppb_buffer_dev.h" #include "ppapi/c/dev/ppb_char_set_dev.h" #include "ppapi/c/dev/ppb_console_dev.h" @@ -55,6 +56,7 @@ #include "ppapi/c/trusted/ppb_broker_trusted.h" #include "ppapi/c/trusted/ppb_url_loader_trusted.h" #include "ppapi/proxy/interface_proxy.h" +#include "ppapi/proxy/ppb_audio_input_proxy.h" #include "ppapi/proxy/ppb_audio_proxy.h" #include "ppapi/proxy/ppb_broker_proxy.h" #include "ppapi/proxy/ppb_buffer_proxy.h" diff --git a/ppapi/proxy/ppapi_messages.h b/ppapi/proxy/ppapi_messages.h index 6a41a38..d38a397 100644 --- a/ppapi/proxy/ppapi_messages.h +++ b/ppapi/proxy/ppapi_messages.h @@ -216,6 +216,14 @@ IPC_MESSAGE_ROUTED5(PpapiMsg_PPBAudio_NotifyAudioStreamCreated, base::SharedMemoryHandle /* handle */, int32_t /* length */) +// PPB_AudioInput_Dev. +IPC_MESSAGE_ROUTED5(PpapiMsg_PPBAudioInput_NotifyAudioStreamCreated, + ppapi::HostResource /* audio_id */, + int32_t /* result_code (will be != PP_OK on failure) */, + IPC::PlatformFileForTransit /* socket_handle */, + base::SharedMemoryHandle /* handle */, + int32_t /* length */) + // PPB_Broker. IPC_MESSAGE_ROUTED3( PpapiMsg_PPBBroker_ConnectComplete, @@ -490,6 +498,16 @@ IPC_MESSAGE_ROUTED2(PpapiHostMsg_PPBAudio_StartOrStop, ppapi::HostResource /* audio_id */, bool /* play */) +// PPB_AudioInput. +IPC_SYNC_MESSAGE_ROUTED3_1(PpapiHostMsg_PPBAudioInput_Create, + PP_Instance /* instance_id */, + int32_t /* sample_rate */, + uint32_t /* sample_frame_count */, + ppapi::HostResource /* result */) +IPC_MESSAGE_ROUTED2(PpapiHostMsg_PPBAudioInput_StartOrStop, + ppapi::HostResource /* audio_id */, + bool /* capture */) + // PPB_Broker. IPC_SYNC_MESSAGE_ROUTED1_1(PpapiHostMsg_PPBBroker_Create, PP_Instance /* instance */, diff --git a/ppapi/proxy/ppb_audio_input_proxy.cc b/ppapi/proxy/ppb_audio_input_proxy.cc new file mode 100644 index 0000000..e3b9b05 --- /dev/null +++ b/ppapi/proxy/ppb_audio_input_proxy.cc @@ -0,0 +1,334 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ppapi/proxy/ppb_audio_input_proxy.h" + +#include "base/compiler_specific.h" +#include "base/threading/simple_thread.h" +#include "ppapi/c/dev/ppb_audio_input_dev.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/ppb_audio_config.h" +#include "ppapi/c/ppb_var.h" +#include "ppapi/c/trusted/ppb_audio_trusted.h" +#include "ppapi/proxy/enter_proxy.h" +#include "ppapi/proxy/plugin_dispatcher.h" +#include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/shared_impl/api_id.h" +#include "ppapi/shared_impl/audio_input_impl.h" +#include "ppapi/shared_impl/ppapi_globals.h" +#include "ppapi/shared_impl/resource.h" +#include "ppapi/thunk/enter.h" +#include "ppapi/thunk/ppb_audio_config_api.h" +#include "ppapi/thunk/resource_creation_api.h" +#include "ppapi/thunk/thunk.h" + +using ppapi::thunk::EnterResourceNoLock; +using ppapi::thunk::PPB_AudioInput_API; +using ppapi::thunk::PPB_AudioConfig_API; + +namespace ppapi { +namespace proxy { + +class AudioInput : public Resource, public AudioInputImpl { + public: + AudioInput(const HostResource& audio_input_id, + PP_Resource config_id, + PPB_AudioInput_Callback callback, + void* user_data); + virtual ~AudioInput(); + + // Resource overrides. + virtual PPB_AudioInput_API* AsPPB_AudioInput_API() OVERRIDE; + + // PPB_AudioInput_API implementation. + virtual PP_Resource GetCurrentConfig() OVERRIDE; + virtual PP_Bool StartCapture() OVERRIDE; + virtual PP_Bool StopCapture() OVERRIDE; + + virtual int32_t OpenTrusted(PP_Resource config_id, + PP_CompletionCallback create_callback) OVERRIDE; + virtual int32_t GetSyncSocket(int* sync_socket) OVERRIDE; + virtual int32_t GetSharedMemory(int* shm_handle, uint32_t* shm_size) OVERRIDE; + + private: + // Owning reference to the current config object. This isn't actually used, + // we just dish it out as requested by the plugin. + PP_Resource config_; + + DISALLOW_COPY_AND_ASSIGN(AudioInput); +}; + +AudioInput::AudioInput(const HostResource& audio_input_id, + PP_Resource config_id, + PPB_AudioInput_Callback callback, + void* user_data) + : Resource(audio_input_id), + config_(config_id) { + SetCallback(callback, user_data); + PpapiGlobals::Get()->GetResourceTracker()->AddRefResource(config_); +} + +AudioInput::~AudioInput() { + PpapiGlobals::Get()->GetResourceTracker()->ReleaseResource(config_); +} + +PPB_AudioInput_API* AudioInput::AsPPB_AudioInput_API() { + return this; +} + +PP_Resource AudioInput::GetCurrentConfig() { + // AddRef for the caller. + PpapiGlobals::Get()->GetResourceTracker()->AddRefResource(config_); + return config_; +} + +PP_Bool AudioInput::StartCapture() { + if (capturing()) + return PP_TRUE; + SetStartCaptureState(); + PluginDispatcher::GetForResource(this)->Send( + new PpapiHostMsg_PPBAudioInput_StartOrStop( + API_ID_PPB_AUDIO_INPUT_DEV, host_resource(), true)); + return PP_TRUE; +} + +PP_Bool AudioInput::StopCapture() { + if (!capturing()) + return PP_TRUE; + PluginDispatcher::GetForResource(this)->Send( + new PpapiHostMsg_PPBAudioInput_StartOrStop( + API_ID_PPB_AUDIO_INPUT_DEV, host_resource(), false)); + SetStopCaptureState(); + return PP_TRUE; +} + +int32_t AudioInput::OpenTrusted(PP_Resource config_id, + PP_CompletionCallback create_callback) { + return PP_ERROR_NOTSUPPORTED; // Don't proxy the trusted interface. +} + +int32_t AudioInput::GetSyncSocket(int* sync_socket) { + return PP_ERROR_NOTSUPPORTED; // Don't proxy the trusted interface. +} + +int32_t AudioInput::GetSharedMemory(int* shm_handle, uint32_t* shm_size) { + return PP_ERROR_NOTSUPPORTED; // Don't proxy the trusted interface. +} + +namespace { + +base::PlatformFile IntToPlatformFile(int32_t handle) { + // TODO(piman/brettw): Change trusted interface to return a PP_FileHandle, + // those casts are ugly. +#if defined(OS_WIN) + return reinterpret_cast<HANDLE>(static_cast<intptr_t>(handle)); +#elif defined(OS_POSIX) + return handle; +#else + #error Not implemented. +#endif +} + +} // namespace + +PPB_AudioInput_Proxy::PPB_AudioInput_Proxy(Dispatcher* dispatcher) + : InterfaceProxy(dispatcher), + callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { +} + +PPB_AudioInput_Proxy::~PPB_AudioInput_Proxy() { +} + +// static +PP_Resource PPB_AudioInput_Proxy::CreateProxyResource( + PP_Instance instance_id, + PP_Resource config_id, + PPB_AudioInput_Callback audio_input_callback, + void* user_data) { + PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance_id); + if (!dispatcher) + return 0; + + EnterResourceNoLock<PPB_AudioConfig_API> config(config_id, true); + if (config.failed()) + return 0; + + HostResource result; + dispatcher->Send(new PpapiHostMsg_PPBAudioInput_Create( + API_ID_PPB_AUDIO_INPUT_DEV, instance_id, + config.object()->GetSampleRate(), config.object()->GetSampleFrameCount(), + &result)); + if (result.is_null()) + return 0; + + return (new AudioInput(result, config_id, audio_input_callback, + user_data))->GetReference(); +} + +bool PPB_AudioInput_Proxy::OnMessageReceived(const IPC::Message& msg) { + bool handled = true; + IPC_BEGIN_MESSAGE_MAP(PPB_AudioInput_Proxy, msg) + IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBAudioInput_Create, OnMsgCreate) + IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBAudioInput_StartOrStop, + OnMsgStartOrStop) + IPC_MESSAGE_HANDLER(PpapiMsg_PPBAudioInput_NotifyAudioStreamCreated, + OnMsgNotifyAudioStreamCreated) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + // TODO(brettw) handle bad messages! + + return handled; +} + +void PPB_AudioInput_Proxy::OnMsgCreate(PP_Instance instance_id, + int32_t sample_rate, + uint32_t sample_frame_count, + HostResource* result) { + thunk::EnterFunction<thunk::ResourceCreationAPI> resource_creation( + instance_id, true); + if (resource_creation.failed()) + return; + + // Make the resource and get the API pointer to its trusted interface. + result->SetHostResource( + instance_id, + resource_creation.functions()->CreateAudioInputTrusted(instance_id)); + if (result->is_null()) + return; + + // At this point, we've set the result resource, and this is a sync request. + // Anything below this point must issue the AudioInputChannelConnected + // callback to the browser. Since that's an async message, it will be issued + // back to the plugin after the Create function returns (which is good + // because it would be weird to get a connected message with a failure code + // for a resource you haven't finished creating yet). + // + // The ...ForceCallback class will help ensure the callback is always called. + // All error cases must call SetResult on this class. + + EnterHostFromHostResourceForceCallback<PPB_AudioInput_API> enter( + *result, callback_factory_, + &PPB_AudioInput_Proxy::AudioInputChannelConnected, *result); + if (enter.failed()) + return; // When enter fails, it will internally schedule the callback. + + // Make an audio config object. + PP_Resource audio_config_res = + resource_creation.functions()->CreateAudioConfig( + instance_id, static_cast<PP_AudioSampleRate>(sample_rate), + sample_frame_count); + if (!audio_config_res) { + enter.SetResult(PP_ERROR_FAILED); + return; + } + + // Initiate opening the audio object. + enter.SetResult(enter.object()->OpenTrusted(audio_config_res, + enter.callback())); + + // Clean up the temporary audio config resource we made. + const PPB_Core* core = static_cast<const PPB_Core*>( + dispatcher()->local_get_interface()(PPB_CORE_INTERFACE)); + core->ReleaseResource(audio_config_res); +} + +void PPB_AudioInput_Proxy::OnMsgStartOrStop( + const HostResource& resource, + bool capture) { + EnterHostFromHostResource<PPB_AudioInput_API> enter(resource); + if (enter.failed()) + return; + if (capture) + enter.object()->StartCapture(); + else + enter.object()->StopCapture(); +} + +// Processed in the plugin (message from host). +void PPB_AudioInput_Proxy::OnMsgNotifyAudioStreamCreated( + const HostResource& audio_id, + int32_t result_code, + IPC::PlatformFileForTransit socket_handle, + base::SharedMemoryHandle handle, + uint32_t length) { + EnterPluginFromHostResource<PPB_AudioInput_API> enter(audio_id); + if (enter.failed() || result_code != PP_OK) { + // The caller may still have given us these handles in the failure case. + // The easiest way to clean these up is to just put them in the objects + // and then close them. This failure case is not performance critical. + base::SyncSocket temp_socket( + IPC::PlatformFileForTransitToPlatformFile(socket_handle)); + base::SharedMemory temp_mem(handle, false); + } else { + static_cast<AudioInput*>(enter.object())->SetStreamInfo( + handle, length, + IPC::PlatformFileForTransitToPlatformFile(socket_handle)); + } +} + +void PPB_AudioInput_Proxy::AudioInputChannelConnected( + int32_t result, + const HostResource& resource) { + IPC::PlatformFileForTransit socket_handle = + IPC::InvalidPlatformFileForTransit(); + base::SharedMemoryHandle shared_memory = IPC::InvalidPlatformFileForTransit(); + uint32_t shared_memory_length = 0; + + int32_t result_code = result; + if (result_code == PP_OK) { + result_code = GetAudioInputConnectedHandles(resource, &socket_handle, + &shared_memory, + &shared_memory_length); + } + + // Send all the values, even on error. This simplifies some of our cleanup + // code since the handles will be in the other process and could be + // inconvenient to clean up. Our IPC code will automatically handle this for + // us, as long as the remote side always closes the handles it receives + // (in OnMsgNotifyAudioStreamCreated), even in the failure case. + dispatcher()->Send(new PpapiMsg_PPBAudioInput_NotifyAudioStreamCreated( + API_ID_PPB_AUDIO_INPUT_DEV, resource, result_code, socket_handle, + shared_memory, shared_memory_length)); +} + +int32_t PPB_AudioInput_Proxy::GetAudioInputConnectedHandles( + const HostResource& resource, + IPC::PlatformFileForTransit* foreign_socket_handle, + base::SharedMemoryHandle* foreign_shared_memory_handle, + uint32_t* shared_memory_length) { + // Get the audio interface which will give us the handles. + EnterHostFromHostResource<PPB_AudioInput_API> enter(resource); + if (enter.failed()) + return PP_ERROR_NOINTERFACE; + + // Get the socket handle for signaling. + int32_t socket_handle; + int32_t result = enter.object()->GetSyncSocket(&socket_handle); + if (result != PP_OK) + return result; + + // socket_handle doesn't belong to us: don't close it. + *foreign_socket_handle = dispatcher()->ShareHandleWithRemote( + IntToPlatformFile(socket_handle), false); + if (*foreign_socket_handle == IPC::InvalidPlatformFileForTransit()) + return PP_ERROR_FAILED; + + // Get the shared memory for the buffer. + int shared_memory_handle; + result = enter.object()->GetSharedMemory(&shared_memory_handle, + shared_memory_length); + if (result != PP_OK) + return result; + + // shared_memory_handle doesn't belong to us: don't close it. + *foreign_shared_memory_handle = dispatcher()->ShareHandleWithRemote( + IntToPlatformFile(shared_memory_handle), false); + if (*foreign_shared_memory_handle == IPC::InvalidPlatformFileForTransit()) + return PP_ERROR_FAILED; + + return PP_OK; +} + +} // namespace proxy +} // namespace ppapi diff --git a/ppapi/proxy/ppb_audio_input_proxy.h b/ppapi/proxy/ppb_audio_input_proxy.h new file mode 100644 index 0000000..6244e55 --- /dev/null +++ b/ppapi/proxy/ppb_audio_input_proxy.h @@ -0,0 +1,86 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef PPAPI_PPB_AUDIO_INPUT_PROXY_H_ +#define PPAPI_PPB_AUDIO_INPUT_PROXY_H_ + +#include <utility> + +#include "base/basictypes.h" +#include "base/shared_memory.h" +#include "base/sync_socket.h" +#include "ipc/ipc_platform_file.h" +#include "ppapi/c/dev/ppb_audio_input_dev.h" +#include "ppapi/c/ppb_audio_config.h" +#include "ppapi/cpp/completion_callback.h" +#include "ppapi/proxy/interface_proxy.h" +#include "ppapi/proxy/proxy_non_thread_safe_ref_count.h" + +struct PPB_AudioInput_Dev; + +namespace ppapi { + +class HostResource; + +namespace proxy { + +class PPB_AudioInput_Proxy : public InterfaceProxy { + public: + explicit PPB_AudioInput_Proxy(Dispatcher* dispatcher); + virtual ~PPB_AudioInput_Proxy(); + + static PP_Resource CreateProxyResource( + PP_Instance instance, + PP_Resource config_id, + PPB_AudioInput_Callback audio_input_callback, + void* user_data); + + // InterfaceProxy implementation. + virtual bool OnMessageReceived(const IPC::Message& msg); + + static const ApiID kApiID = API_ID_PPB_AUDIO_INPUT_DEV; + + private: + // Message handlers. + // Plugin->renderer message handlers. + void OnMsgCreate(PP_Instance instance_id, + int32_t sample_rate, + uint32_t sample_frame_count, + ppapi::HostResource* result); + void OnMsgStartOrStop(const ppapi::HostResource& audio_id, bool capture); + + // Renderer->plugin message handlers. + void OnMsgNotifyAudioStreamCreated(const ppapi::HostResource& audio_id, + int32_t result_code, + IPC::PlatformFileForTransit socket_handle, + base::SharedMemoryHandle handle, + uint32_t length); + + void AudioInputChannelConnected(int32_t result, + const ppapi::HostResource& resource); + + // In the renderer, this is called in response to a stream created message. + // It will retrieve the shared memory and socket handles and place them into + // the given out params. The return value is a PPAPI error code. + // + // The input arguments should be initialized to 0 or -1, depending on the + // platform's default invalid handle values. On error, some of these + // arguments may be written to, and others may be untouched, depending on + // where the error occurred. + int32_t GetAudioInputConnectedHandles( + const ppapi::HostResource& resource, + IPC::PlatformFileForTransit* foreign_socket_handle, + base::SharedMemoryHandle* foreign_shared_memory_handle, + uint32_t* shared_memory_length); + + pp::CompletionCallbackFactory<PPB_AudioInput_Proxy, + ProxyNonThreadSafeRefCount> callback_factory_; + + DISALLOW_COPY_AND_ASSIGN(PPB_AudioInput_Proxy); +}; + +} // namespace proxy +} // namespace ppapi + +#endif // PPAPI_PPB_AUDIO_INPUT_PROXY_H_ diff --git a/ppapi/proxy/resource_creation_proxy.cc b/ppapi/proxy/resource_creation_proxy.cc index afdf56d..3777a2d 100644 --- a/ppapi/proxy/resource_creation_proxy.cc +++ b/ppapi/proxy/resource_creation_proxy.cc @@ -10,6 +10,7 @@ #include "ppapi/proxy/plugin_dispatcher.h" #include "ppapi/proxy/plugin_resource_tracker.h" #include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/proxy/ppb_audio_input_proxy.h" #include "ppapi/proxy/ppb_audio_proxy.h" #include "ppapi/proxy/ppb_buffer_proxy.h" #include "ppapi/proxy/ppb_broker_proxy.h" @@ -83,6 +84,22 @@ PP_Resource ResourceCreationProxy::CreateAudioTrusted(PP_Instance instance) { return 0; } +PP_Resource ResourceCreationProxy::CreateAudioInput( + PP_Instance instance, + PP_Resource config_id, + PPB_Audio_Callback audio_input_callback, + void* user_data) { + return PPB_AudioInput_Proxy::CreateProxyResource(instance, config_id, + audio_input_callback, + user_data); +} + +PP_Resource ResourceCreationProxy::CreateAudioInputTrusted( + PP_Instance instance) { + // Proxied plugins can't created trusted audio input devices. + return 0; +} + PP_Resource ResourceCreationProxy::CreateBroker(PP_Instance instance) { return PPB_Broker_Proxy::CreateProxyResource(instance); } diff --git a/ppapi/proxy/resource_creation_proxy.h b/ppapi/proxy/resource_creation_proxy.h index 20924d1..e543722 100644 --- a/ppapi/proxy/resource_creation_proxy.h +++ b/ppapi/proxy/resource_creation_proxy.h @@ -46,6 +46,12 @@ class ResourceCreationProxy : public InterfaceProxy, PP_AudioSampleRate sample_rate, uint32_t sample_frame_count) OVERRIDE; virtual PP_Resource CreateAudioTrusted(PP_Instance instance) OVERRIDE; + virtual PP_Resource CreateAudioInput( + PP_Instance instance, + PP_Resource config_id, + PPB_AudioInput_Callback audio_input_callback, + void* user_data) OVERRIDE; + virtual PP_Resource CreateAudioInputTrusted(PP_Instance instance) OVERRIDE; virtual PP_Resource CreateBroker(PP_Instance instance) OVERRIDE; virtual PP_Resource CreateBuffer(PP_Instance instance, uint32_t size) OVERRIDE; @@ -140,6 +146,8 @@ class ResourceCreationProxy : public InterfaceProxy, int32_t sample_rate, uint32_t sample_frame_count, HostResource* result); + void OnMsgCreateAudioInput(PP_Instance instance, + HostResource* result); void OnMsgCreateGraphics2D(PP_Instance instance, const PP_Size& size, PP_Bool is_always_opaque, diff --git a/ppapi/shared_impl/api_id.h b/ppapi/shared_impl/api_id.h index d439d3d..5da4b04 100644 --- a/ppapi/shared_impl/api_id.h +++ b/ppapi/shared_impl/api_id.h @@ -14,6 +14,7 @@ enum ApiID { API_ID_NONE = 0, API_ID_PPB_AUDIO = 1, API_ID_PPB_AUDIO_CONFIG, + API_ID_PPB_AUDIO_INPUT_DEV, API_ID_PPB_BROKER, API_ID_PPB_BUFFER, API_ID_PPB_CONTEXT_3D, diff --git a/ppapi/shared_impl/audio_input_impl.cc b/ppapi/shared_impl/audio_input_impl.cc new file mode 100644 index 0000000..659cd47 --- /dev/null +++ b/ppapi/shared_impl/audio_input_impl.cc @@ -0,0 +1,94 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ppapi/shared_impl/audio_input_impl.h" + +#include "base/logging.h" + +namespace ppapi { + +AudioInputImpl::AudioInputImpl() + : capturing_(false), + shared_memory_size_(0), + callback_(NULL), + user_data_(NULL) { +} + +AudioInputImpl::~AudioInputImpl() { + // Closing the socket causes the thread to exit - wait for it. + if (socket_.get()) + socket_->Close(); + if (audio_input_thread_.get()) { + audio_input_thread_->Join(); + audio_input_thread_.reset(); + } +} + +void AudioInputImpl::SetCallback(PPB_AudioInput_Callback callback, + void* user_data) { + callback_ = callback; + user_data_ = user_data; +} + +void AudioInputImpl::SetStartCaptureState() { + DCHECK(!capturing_); + DCHECK(!audio_input_thread_.get()); + + // If the socket doesn't exist, that means that the plugin has started before + // the browser has had a chance to create all the shared memory info and + // notify us. This is a common case. In this case, we just set the playing_ + // flag and the capture will automatically start when that data is available + // in SetStreamInfo. + if (socket_.get()) + StartThread(); + capturing_ = true; +} + +void AudioInputImpl::SetStopCaptureState() { + DCHECK(capturing_); + + if (audio_input_thread_.get()) { + audio_input_thread_->Join(); + audio_input_thread_.reset(); + } + capturing_ = false; +} + +void AudioInputImpl::SetStreamInfo( + base::SharedMemoryHandle shared_memory_handle, + size_t shared_memory_size, + base::SyncSocket::Handle socket_handle) { + socket_.reset(new base::SyncSocket(socket_handle)); + shared_memory_.reset(new base::SharedMemory(shared_memory_handle, false)); + shared_memory_size_ = shared_memory_size; + + if (callback_) { + shared_memory_->Map(shared_memory_size_); + + // In common case StartCapture() was called before StreamCreated(). + if (capturing_) + StartThread(); + } +} + +void AudioInputImpl::StartThread() { + DCHECK(callback_); + DCHECK(!audio_input_thread_.get()); + audio_input_thread_.reset(new base::DelegateSimpleThread( + this, "plugin_audio_input_thread")); + audio_input_thread_->Start(); +} + +void AudioInputImpl::Run() { + int pending_data; + void* buffer = shared_memory_->memory(); + + while (sizeof(pending_data) == socket_->Receive(&pending_data, + sizeof(pending_data)) && + pending_data >= 0) { + callback_(buffer, shared_memory_size_, user_data_); + } +} + +} // namespace ppapi diff --git a/ppapi/shared_impl/audio_input_impl.h b/ppapi/shared_impl/audio_input_impl.h new file mode 100644 index 0000000..e7604c3 --- /dev/null +++ b/ppapi/shared_impl/audio_input_impl.h @@ -0,0 +1,88 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef PPAPI_SHARED_IMPL_AUDIO_INPUT_IMPL_H_ +#define PPAPI_SHARED_IMPL_AUDIO_INPUT_IMPL_H_ + +#include "base/memory/scoped_ptr.h" +#include "base/shared_memory.h" +#include "base/sync_socket.h" +#include "base/threading/simple_thread.h" +#include "ppapi/c/dev/ppb_audio_input_dev.h" +#include "ppapi/shared_impl/resource.h" +#include "ppapi/thunk/ppb_audio_input_api.h" + +namespace ppapi { + +// Implements the logic to map shared memory and run the audio thread signaled +// from the sync socket. Both the proxy and the renderer implementation use +// this code. +class PPAPI_SHARED_EXPORT AudioInputImpl + : public thunk::PPB_AudioInput_API, + public base::DelegateSimpleThread::Delegate { + public: + AudioInputImpl(); + virtual ~AudioInputImpl(); + + bool capturing() const { return capturing_; } + + // Sets the callback information that the background thread will use. This + // is optional. Without a callback, the thread will not be run. This + // non-callback mode is used in the renderer with the proxy, since the proxy + // handles the callback entirely within the plugin process. + void SetCallback(PPB_AudioInput_Callback callback, void* user_data); + + // Configures the current state to be playing or not. The caller is + // responsible for ensuring the new state is the opposite of the current one. + // + // This is the implementation for PPB_AudioInput.Start/StopCapture, except + // that it does not actually notify the audio system to stop capture, it just + // configures our object to stop generating callbacks. The actual stop + // playback request will be done in the derived classes and will be different + // from the proxy and the renderer. + void SetStartCaptureState(); + void SetStopCaptureState(); + + // Sets the shared memory and socket handles. This will automatically start + // playback if we're currently set to play. + void SetStreamInfo(base::SharedMemoryHandle shared_memory_handle, + size_t shared_memory_size, + base::SyncSocket::Handle socket_handle); + + private: + // Starts execution of the audio input thread. + void StartThread(); + + // DelegateSimpleThread::Delegate implementation. + // Run on the audio input thread. + virtual void Run(); + + // True if capturing the stream. + bool capturing_; + + // Socket used to notify us when audio is ready to accept new samples. This + // pointer is created in StreamCreated(). + scoped_ptr<base::SyncSocket> socket_; + + // Sample buffer in shared memory. This pointer is created in + // StreamCreated(). The memory is only mapped when the audio thread is + // created. + scoped_ptr<base::SharedMemory> shared_memory_; + + // The size of the sample buffer in bytes. + size_t shared_memory_size_; + + // When the callback is set, this thread is spawned for calling it. + scoped_ptr<base::DelegateSimpleThread> audio_input_thread_; + + // Callback to call when audio is ready to produce new samples. + PPB_AudioInput_Callback callback_; + + // User data pointer passed verbatim to the callback function. + void* user_data_; +}; + +} // namespace ppapi + +#endif // PPAPI_SHARED_IMPL_AUDIO_INPUT_IMPL_H_ diff --git a/ppapi/shared_impl/resource.h b/ppapi/shared_impl/resource.h index 247287f..19c909c 100644 --- a/ppapi/shared_impl/resource.h +++ b/ppapi/shared_impl/resource.h @@ -16,9 +16,11 @@ // All resource types should be added here. This implements our hand-rolled // RTTI system since we don't compile with "real" RTTI. #define FOR_ALL_PPAPI_RESOURCE_APIS(F) \ + F(PPB_Audio_API) \ F(PPB_AudioConfig_API) \ + F(PPB_AudioInput_API) \ + F(PPB_AudioInputTrusted_API) \ F(PPB_AudioTrusted_API) \ - F(PPB_Audio_API) \ F(PPB_Broker_API) \ F(PPB_Buffer_API) \ F(PPB_BufferTrusted_API) \ diff --git a/ppapi/thunk/interfaces_ppb_public_dev.h b/ppapi/thunk/interfaces_ppb_public_dev.h index 574c954..7ef9f30 100644 --- a/ppapi/thunk/interfaces_ppb_public_dev.h +++ b/ppapi/thunk/interfaces_ppb_public_dev.h @@ -7,6 +7,7 @@ #include "ppapi/thunk/interfaces_preamble.h" +PROXIED_API(PPB_AudioInput) PROXIED_API(PPB_Buffer) PROXIED_API(PPB_Context3D) PROXIED_API(PPB_CursorControl) @@ -23,6 +24,8 @@ PROXIED_API(PPB_VideoCapture) PROXIED_API(PPB_VideoDecoder) UNPROXIED_API(PPB_Widget) +PROXIED_IFACE(PPB_AudioInput, PPB_AUDIO_INPUT_DEV_INTERFACE_0_1, + PPB_AudioInput_Dev) PROXIED_IFACE(NoAPIName, PPB_IME_INPUT_EVENT_DEV_INTERFACE_0_1, PPB_IMEInputEvent_Dev) PROXIED_IFACE(PPB_Buffer, PPB_BUFFER_DEV_INTERFACE_0_4, PPB_Buffer_Dev) diff --git a/ppapi/thunk/ppb_audio_input_api.h b/ppapi/thunk/ppb_audio_input_api.h new file mode 100644 index 0000000..f42f0d5 --- /dev/null +++ b/ppapi/thunk/ppb_audio_input_api.h @@ -0,0 +1,33 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef PPAPI_THUNK_AUDIO_INPUT_API_H_ +#define PPAPI_THUNK_AUDIO_INPUT_API_H_ + +#include "ppapi/c/dev/ppb_audio_input_dev.h" +#include "ppapi/c/pp_completion_callback.h" +#include "ppapi/thunk/ppapi_thunk_export.h" + +namespace ppapi { +namespace thunk { + +class PPB_AudioInput_API { + public: + virtual ~PPB_AudioInput_API() {} + + virtual PP_Resource GetCurrentConfig() = 0; + virtual PP_Bool StartCapture() = 0; + virtual PP_Bool StopCapture() = 0; + + // Trusted API. + virtual int32_t OpenTrusted(PP_Resource config_id, + PP_CompletionCallback create_callback) = 0; + virtual int32_t GetSyncSocket(int* sync_socket) = 0; + virtual int32_t GetSharedMemory(int* shm_handle, uint32_t* shm_size) = 0; +}; + +} // namespace thunk +} // namespace ppapi + +#endif // PPAPI_THUNK_AUDIO_INPUT_API_H_ diff --git a/ppapi/thunk/ppb_audio_input_thunk.cc b/ppapi/thunk/ppb_audio_input_thunk.cc new file mode 100644 index 0000000..7b6f31c --- /dev/null +++ b/ppapi/thunk/ppb_audio_input_thunk.cc @@ -0,0 +1,74 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ppapi/c/pp_errors.h" +#include "ppapi/thunk/common.h" +#include "ppapi/thunk/enter.h" +#include "ppapi/thunk/ppb_audio_input_api.h" +#include "ppapi/thunk/resource_creation_api.h" +#include "ppapi/thunk/thunk.h" + +namespace ppapi { +namespace thunk { + +namespace { + +typedef EnterResource<PPB_AudioInput_API> EnterAudioInput; + +PP_Resource Create(PP_Instance instance, + PP_Resource config_id, + PPB_AudioInput_Callback callback, + void* user_data) { + EnterFunction<ResourceCreationAPI> enter(instance, true); + if (enter.failed()) + return 0; + + return enter.functions()->CreateAudioInput(instance, config_id, + callback, user_data); +} + +PP_Bool IsAudioInput(PP_Resource resource) { + EnterAudioInput enter(resource, false); + return PP_FromBool(enter.succeeded()); +} + +PP_Resource GetCurrentConfiguration(PP_Resource audio_id) { + EnterAudioInput enter(audio_id, true); + if (enter.failed()) + return 0; + return enter.object()->GetCurrentConfig(); +} + +PP_Bool StartCapture(PP_Resource audio_input) { + EnterAudioInput enter(audio_input, true); + if (enter.failed()) + return PP_FALSE; + + return enter.object()->StartCapture(); +} + +PP_Bool StopCapture(PP_Resource audio_input) { + EnterAudioInput enter(audio_input, true); + if (enter.failed()) + return PP_FALSE; + + return enter.object()->StopCapture(); +} + +const PPB_AudioInput_Dev g_ppb_audioinput_thunk = { + &Create, + &IsAudioInput, + &GetCurrentConfiguration, + &StartCapture, + &StopCapture +}; + +} // namespace + +const PPB_AudioInput_Dev* GetPPB_AudioInput_Dev_Thunk() { + return &g_ppb_audioinput_thunk; +} + +} // namespace thunk +} // namespace ppapi diff --git a/ppapi/thunk/ppb_audio_input_trusted_thunk.cc b/ppapi/thunk/ppb_audio_input_trusted_thunk.cc new file mode 100644 index 0000000..1de878c --- /dev/null +++ b/ppapi/thunk/ppb_audio_input_trusted_thunk.cc @@ -0,0 +1,67 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/trusted/ppb_audio_input_trusted_dev.h" +#include "ppapi/thunk/common.h" +#include "ppapi/thunk/enter.h" +#include "ppapi/thunk/ppb_audio_input_api.h" +#include "ppapi/thunk/resource_creation_api.h" +#include "ppapi/thunk/thunk.h" + +namespace ppapi { +namespace thunk { + +namespace { + +typedef EnterResource<PPB_AudioInput_API> EnterAudioInput; + +PP_Resource Create(PP_Instance instance_id) { + EnterFunction<ResourceCreationAPI> enter(instance_id, true); + if (enter.failed()) + return 0; + return enter.functions()->CreateAudioInputTrusted(instance_id); +} + +int32_t Open(PP_Resource audio_id, + PP_Resource config_id, + PP_CompletionCallback create_callback) { + EnterAudioInput enter(audio_id, true); + if (enter.failed()) + return MayForceCallback(create_callback, PP_ERROR_BADRESOURCE); + int32_t result = enter.object()->OpenTrusted(config_id, create_callback); + return MayForceCallback(create_callback, result); +} + +int32_t GetSyncSocket(PP_Resource audio_id, int* sync_socket) { + EnterAudioInput enter(audio_id, true); + if (enter.failed()) + return PP_ERROR_BADRESOURCE; + return enter.object()->GetSyncSocket(sync_socket); +} + +int32_t GetSharedMemory(PP_Resource audio_id, + int* shm_handle, + uint32_t* shm_size) { + EnterAudioInput enter(audio_id, true); + if (enter.failed()) + return PP_ERROR_BADRESOURCE; + return enter.object()->GetSharedMemory(shm_handle, shm_size); +} + +const PPB_AudioInputTrusted_Dev g_ppb_audioinput_trusted_thunk = { + &Create, + &Open, + &GetSyncSocket, + &GetSharedMemory, +}; + +} // namespace + +const PPB_AudioInputTrusted_Dev* GetPPB_AudioInputTrusted_Thunk() { + return &g_ppb_audioinput_trusted_thunk; +} + +} // namespace thunk +} // namespace ppapi diff --git a/ppapi/thunk/resource_creation_api.h b/ppapi/thunk/resource_creation_api.h index dd37bed..b9e26d5 100644 --- a/ppapi/thunk/resource_creation_api.h +++ b/ppapi/thunk/resource_creation_api.h @@ -5,6 +5,7 @@ #ifndef PPAPI_THUNK_RESOURCE_CREATION_API_H_ #define PPAPI_THUNK_RESOURCE_CREATION_API_H_ +#include "ppapi/c/dev/ppb_audio_input_dev.h" #include "ppapi/c/dev/ppb_file_chooser_dev.h" #include "ppapi/c/dev/ppb_video_layer_dev.h" #include "ppapi/c/pp_bool.h" @@ -43,10 +44,16 @@ class ResourceCreationAPI { PP_Resource config_id, PPB_Audio_Callback audio_callback, void* user_data) = 0; - virtual PP_Resource CreateAudioTrusted(PP_Instance instace) = 0; + virtual PP_Resource CreateAudioTrusted(PP_Instance instance) = 0; virtual PP_Resource CreateAudioConfig(PP_Instance instance, PP_AudioSampleRate sample_rate, uint32_t sample_frame_count) = 0; + virtual PP_Resource CreateAudioInput( + PP_Instance instance, + PP_Resource config_id, + PPB_AudioInput_Callback audio_input_callback, + void* user_data) = 0; + virtual PP_Resource CreateAudioInputTrusted(PP_Instance instance) = 0; virtual PP_Resource CreateBroker(PP_Instance instance) = 0; virtual PP_Resource CreateBuffer(PP_Instance instance, uint32_t size) = 0; virtual PP_Resource CreateContext3D(PP_Instance instance, diff --git a/ppapi/thunk/thunk.h b/ppapi/thunk/thunk.h index 8990b94..5f6a62c 100644 --- a/ppapi/thunk/thunk.h +++ b/ppapi/thunk/thunk.h @@ -27,6 +27,7 @@ #undef PROXIED_IFACE #undef IFACE +struct PPB_AudioInputTrusted_Dev; struct PPB_AudioTrusted; struct PPB_BrokerTrusted; struct PPB_BufferTrusted; @@ -52,6 +53,8 @@ namespace thunk { // Old-style thunk getters. Only put trusted/private stuff here (it hasn't // yet been converted to the new system). Otherwise, add the declaration to // the appropriate interfaces_*.h file. +PPAPI_THUNK_EXPORT const PPB_AudioInputTrusted_Dev* + GetPPB_AudioInputTrusted_Thunk(); PPAPI_THUNK_EXPORT const PPB_AudioTrusted* GetPPB_AudioTrusted_Thunk(); PPAPI_THUNK_EXPORT const PPB_BrokerTrusted* GetPPB_Broker_Thunk(); PPAPI_THUNK_EXPORT const PPB_BufferTrusted* GetPPB_BufferTrusted_Thunk(); |