Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(160)

Unified Diff: ppapi/proxy/ppb_audio_proxy.cc

Issue 4985001: Initial audio implementation. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 10 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ppapi/proxy/ppb_audio_proxy.h ('k') | ppapi/shared_impl/DEPS » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ppapi/proxy/ppb_audio_proxy.cc
===================================================================
--- ppapi/proxy/ppb_audio_proxy.cc (revision 0)
+++ ppapi/proxy/ppb_audio_proxy.cc (revision 0)
@@ -0,0 +1,285 @@
+// Copyright (c) 2010 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/simple_thread.h"
+#include "ppapi/c/dev/ppb_audio_dev.h"
+#include "ppapi/c/dev/ppb_audio_trusted_dev.h"
+#include "ppapi/c/pp_errors.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"
+
+namespace pp {
+namespace proxy {
+
+class Audio : public PluginResource, public pp::shared_impl::AudioImpl {
+ public:
+ Audio(PP_Resource config_id, PPB_Audio_Callback callback, void* user_data)
+ : config_(config_id) {
+ SetCallback(callback, user_data);
+ PluginDispatcher::Get()->plugin_resource_tracker()->AddRefResource(
+ config_);
+ }
+ virtual ~Audio() {
+ PluginDispatcher::Get()->plugin_resource_tracker()->ReleaseResource(
+ config_);
+ }
+
+ // Resource overrides.
+ virtual Audio* AsAudio() { return this; }
+
+ PP_Resource config() const { return config_; }
+
+ void StartPlayback(PP_Resource resource) {
+ if (playing())
+ return;
+ SetStartPlaybackState();
+ PluginDispatcher::Get()->Send(new PpapiHostMsg_PPBAudio_StartOrStop(
+ INTERFACE_ID_PPB_AUDIO, resource, true));
+ }
+
+ void StopPlayback(PP_Resource resource) {
+ if (!playing())
+ return;
+ PluginDispatcher::Get()->Send(new PpapiHostMsg_PPBAudio_StartOrStop(
+ INTERFACE_ID_PPB_AUDIO, resource, false));
+ SetStopPlaybackState();
+ }
+
+ private:
+ PP_Resource config_;
+
+ DISALLOW_COPY_AND_ASSIGN(Audio);
+};
+
+namespace {
+
+PP_Resource Create(PP_Instance instance_id,
+ PP_Resource config_id,
+ PPB_Audio_Callback callback,
+ void* user_data) {
+ PP_Resource result;
+ PluginDispatcher::Get()->Send(new PpapiHostMsg_PPBAudio_Create(
+ INTERFACE_ID_PPB_AUDIO, instance_id, config_id, &result));
+ if (!result)
+ return 0;
+
+ linked_ptr<Audio> object(new Audio(config_id, callback, user_data));
+ PluginDispatcher::Get()->plugin_resource_tracker()->AddResource(
+ result, object);
+ return result;
+}
+
+PP_Bool IsAudio(PP_Resource resource) {
+ Audio* object = PluginResource::GetAs<Audio>(resource);
+ return BoolToPPBool(!!object);
+}
+
+PP_Resource GetCurrentConfiguration(PP_Resource audio_id) {
+ Audio* object = PluginResource::GetAs<Audio>(audio_id);
+ if (!object)
+ return 0;
+ PP_Resource result = object->config();
+ PluginDispatcher::Get()->plugin_resource_tracker()->AddRefResource(result);
+ return result;
+}
+
+PP_Bool StartPlayback(PP_Resource audio_id) {
+ Audio* object = PluginResource::GetAs<Audio>(audio_id);
+ if (!object)
+ return PP_FALSE;
+ object->StartPlayback(audio_id);
+ return PP_TRUE;
+}
+
+PP_Bool StopPlayback(PP_Resource audio_id) {
+ Audio* object = PluginResource::GetAs<Audio>(audio_id);
+ if (!object)
+ return PP_FALSE;
+ object->StopPlayback(audio_id);
+ return PP_TRUE;
+}
+
+const PPB_Audio_Dev audio_interface = {
+ &Create,
+ &IsAudio,
+ &GetCurrentConfiguration,
+ &StartPlayback,
+ &StopPlayback
+};
+
+} // 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() {
+}
+
+const void* PPB_Audio_Proxy::GetSourceInterface() const {
+ return &audio_interface;
+}
+
+InterfaceID PPB_Audio_Proxy::GetInterfaceId() const {
+ return INTERFACE_ID_PPB_AUDIO;
+}
+
+void PPB_Audio_Proxy::OnMessageReceived(const IPC::Message& msg) {
+ IPC_BEGIN_MESSAGE_MAP(PPB_Audio_Proxy, msg)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBAudio_Create, OnMsgCreate)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBAudio_StartOrStop,
+ OnMsgStartOrStop)
+
+ IPC_MESSAGE_HANDLER(PpapiMsg_PPBAudio_NotifyAudioStreamCreated,
+ OnMsgNotifyAudioStreamCreated)
+ IPC_END_MESSAGE_MAP()
+}
+
+void PPB_Audio_Proxy::OnMsgCreate(PP_Instance instance_id,
+ PP_Resource config_id,
+ PP_Resource* result) {
+ const PPB_AudioTrusted_Dev* audio_trusted =
+ reinterpret_cast<const PPB_AudioTrusted_Dev*>(
+ dispatcher()->GetLocalInterface(PPB_AUDIO_TRUSTED_DEV_INTERFACE));
+ if (!audio_trusted) {
+ *result = 0;
+ return;
+ }
+
+ *result = audio_trusted->CreateTrusted(instance_id);
+ if (!result)
+ return;
+
+ CompletionCallback callback = callback_factory_.NewCallback(
+ &PPB_Audio_Proxy::AudioChannelConnected, *result);
+ int32_t open_error = audio_trusted->Open(*result, config_id,
+ callback.pp_completion_callback());
+ if (open_error != PP_ERROR_WOULDBLOCK)
+ callback.Run(open_error);
+}
+
+void PPB_Audio_Proxy::OnMsgStartOrStop(PP_Resource audio_id, bool play) {
+ if (play)
+ ppb_audio_target()->StartPlayback(audio_id);
+ else
+ ppb_audio_target()->StopPlayback(audio_id);
+}
+
+void PPB_Audio_Proxy::OnMsgNotifyAudioStreamCreated(
+ PP_Resource audio_id,
+ int32_t result_code,
+ IPC::PlatformFileForTransit socket_handle,
+ base::SharedMemoryHandle handle,
+ uint32_t length) {
+ Audio* object = PluginResource::GetAs<Audio>(audio_id);
+ if (!object || 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);
+ return;
+ }
+ object->SetStreamInfo(
+ handle, IPC::PlatformFileForTransitToPlatformFile(socket_handle), length);
+}
+
+void PPB_Audio_Proxy::AudioChannelConnected(int32_t result,
+ PP_Resource resource) {
+ IPC::PlatformFileForTransit socket_handle =
+ IPC::InvalidPlatformFileForTransit();
+#if defined(OS_WIN)
+ base::SharedMemoryHandle shared_memory = NULL;
+#elif defined(OS_POSIX)
+ base::SharedMemoryHandle shared_memory(-1, false);
+#else
+ #error Not implemented.
+#endif
+ uint32_t shared_memory_length = 0;
+
+ int32_t result_code = result;
+ if (result_code == PP_OK) {
+ result_code = GetAudioConnectedHandles(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_PPBAudio_NotifyAudioStreamCreated(
+ INTERFACE_ID_PPB_AUDIO, resource, result_code, shared_memory,
+ socket_handle, shared_memory_length));
+}
+
+int32_t PPB_Audio_Proxy::GetAudioConnectedHandles(
+ PP_Resource resource,
+ IPC::PlatformFileForTransit* foreign_socket_handle,
+ base::SharedMemoryHandle* foreign_shared_memory_handle,
+ uint32_t* shared_memory_length) {
+ // Get the trusted audio interface which will give us the handles.
+ const PPB_AudioTrusted_Dev* audio_trusted =
+ reinterpret_cast<const PPB_AudioTrusted_Dev*>(
+ dispatcher()->GetLocalInterface(PPB_AUDIO_TRUSTED_DEV_INTERFACE));
+ if (!audio_trusted)
+ return PP_ERROR_NOINTERFACE;
+
+ // Get the socket handle for signaling.
+ int32_t socket_handle;
+ int32_t result = audio_trusted->GetSyncSocket(resource, &socket_handle);
+ if (result != PP_OK)
+ return result;
+
+#if defined(OS_WIN)
+ // On Windows, duplicate the socket into the plugin process, this will
+ // automatically close the source handle.
+ ::DuplicateHandle(
+ GetCurrentProcess(),
+ reinterpret_cast<HANDLE>(static_cast<intptr_t>(socket_handle)),
+ dispatcher()->remote_process_handle(), foreign_socket_handle,
+ STANDARD_RIGHTS_REQUIRED | FILE_MAP_READ | FILE_MAP_WRITE,
+ FALSE, DUPLICATE_CLOSE_SOURCE);
+#else
+ // On Posix, the socket handle will be auto-duplicated when we send the
+ // FileDescriptor. Set AutoClose since we don't need the handle any more.
+ *foreign_socket_handle = base::FileDescriptor(socket_handle, true);
+#endif
+
+ // Get the shared memory for the buffer.
+ // TODO(brettw) remove the reinterpret cast when the interface is updated.
+ int shared_memory_handle;
+ result = audio_trusted->GetSharedMemory(resource, &shared_memory_handle,
+ shared_memory_length);
+ if (result != PP_OK)
+ return result;
+
+ base::SharedMemory shared_memory(
+#if defined(OS_WIN)
+ reinterpret_cast<HANDLE>(static_cast<intptr_t>(shared_memory_handle)),
+#else
+ base::FileDescriptor(shared_memory_handle, false),
+#endif
+ false);
+
+ // Duplicate the shared memory to the plugin process. This will automatically
+ // close the source handle.
+ if (!shared_memory.GiveToProcess(dispatcher()->remote_process_handle(),
+ foreign_shared_memory_handle))
+ return PP_ERROR_FAILED;
+
+ return PP_OK;
+}
+
+} // namespace proxy
+} // namespace pp
Property changes on: ppapi/proxy/ppb_audio_proxy.cc
___________________________________________________________________
Added: svn:eol-style
+ LF
« no previous file with comments | « ppapi/proxy/ppb_audio_proxy.h ('k') | ppapi/shared_impl/DEPS » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698