// 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_proxy.h" #include "base/threading/simple_thread.h" #include "ppapi/c/pp_errors.h" #include "ppapi/c/ppb_audio.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/interface_id.h" #include "ppapi/proxy/plugin_dispatcher.h" #include "ppapi/proxy/plugin_resource.h" #include "ppapi/proxy/ppapi_messages.h" #include "ppapi/shared_impl/audio_impl.h" #include "ppapi/thunk/ppb_audio_config_api.h" #include "ppapi/thunk/ppb_audio_trusted_api.h" #include "ppapi/thunk/enter.h" #include "ppapi/thunk/resource_creation_api.h" #include "ppapi/thunk/thunk.h" using ::ppapi::thunk::PPB_Audio_API; namespace pp { namespace proxy { class Audio : public PluginResource, public ppapi::AudioImpl { public: Audio(const HostResource& audio_id, PP_Resource config_id, PPB_Audio_Callback callback, void* user_data); virtual ~Audio(); // ResourceObjectBase overrides. virtual PPB_Audio_API* AsPPB_Audio_API(); // PPB_Audio_API implementation. virtual PP_Resource GetCurrentConfig() OVERRIDE; virtual PP_Bool StartPlayback() OVERRIDE; virtual PP_Bool StopPlayback() 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(Audio); }; Audio::Audio(const HostResource& audio_id, PP_Resource config_id, PPB_Audio_Callback callback, void* user_data) : PluginResource(audio_id), config_(config_id) { SetCallback(callback, user_data); PluginResourceTracker::GetInstance()->AddRefResource(config_); } Audio::~Audio() { PluginResourceTracker::GetInstance()->ReleaseResource(config_); } PPB_Audio_API* Audio::AsPPB_Audio_API() { return this; } PP_Resource Audio::GetCurrentConfig() { // AddRef for the caller. PluginResourceTracker::GetInstance()->AddRefResource(config_); return config_; } PP_Bool Audio::StartPlayback() { if (playing()) return PP_TRUE; SetStartPlaybackState(); PluginDispatcher::GetForInstance(instance())->Send( new PpapiHostMsg_PPBAudio_StartOrStop( INTERFACE_ID_PPB_AUDIO, host_resource(), true)); return PP_TRUE; } PP_Bool Audio::StopPlayback() { if (!playing()) return PP_TRUE; PluginDispatcher::GetForInstance(instance())->Send( new PpapiHostMsg_PPBAudio_StartOrStop( INTERFACE_ID_PPB_AUDIO, host_resource(), false)); SetStopPlaybackState(); return PP_TRUE; } namespace { InterfaceProxy* CreateAudioProxy(Dispatcher* dispatcher, const void* target_interface) { return new PPB_Audio_Proxy(dispatcher, target_interface); } 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(static_cast(handle)); #elif defined(OS_POSIX) return handle; #else #error Not implemented. #endif } } // namespace PPB_Audio_Proxy::PPB_Audio_Proxy(Dispatcher* dispatcher, const void* target_interface) : InterfaceProxy(dispatcher, target_interface), callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { } PPB_Audio_Proxy::~PPB_Audio_Proxy() { } // static const InterfaceProxy::Info* PPB_Audio_Proxy::GetInfo() { static const Info info = { ppapi::thunk::GetPPB_Audio_Thunk(), PPB_AUDIO_INTERFACE, INTERFACE_ID_PPB_AUDIO, false, &CreateAudioProxy, }; return &info; } // static PP_Resource PPB_Audio_Proxy::CreateProxyResource( PP_Instance instance_id, PP_Resource config_id, PPB_Audio_Callback audio_callback, void* user_data) { PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance_id); if (!dispatcher) return 0; ::ppapi::thunk::EnterResourceNoLock< ::ppapi::thunk::PPB_AudioConfig_API> config(config_id, true); if (config.failed()) return 0; HostResource result; dispatcher->Send(new PpapiHostMsg_PPBAudio_Create( INTERFACE_ID_PPB_AUDIO, instance_id, config.object()->GetSampleRate(), config.object()->GetSampleFrameCount(), &result)); if (result.is_null()) return 0; linked_ptr