diff --git a/chromium_src/chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.cc b/chromium_src/chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.cc index c2992abcc11d..98932a494bf8 100644 --- a/chromium_src/chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.cc +++ b/chromium_src/chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.cc @@ -8,6 +8,7 @@ #include "chrome/browser/renderer_host/pepper/pepper_broker_message_filter.h" #include "chrome/browser/renderer_host/pepper/pepper_flash_browser_host.h" #include "chrome/browser/renderer_host/pepper/pepper_flash_clipboard_message_filter.h" +#include "chrome/browser/renderer_host/pepper/pepper_flash_drm_host.h" #include "chrome/browser/renderer_host/pepper/pepper_isolated_file_system_message_filter.h" #include "content/public/browser/browser_ppapi_host.h" #include "ppapi/host/message_filter_host.h" @@ -65,6 +66,9 @@ scoped_ptr ChromeBrowserPepperHostFactory::CreateResourceHost( return scoped_ptr(new MessageFilterHost( host_->GetPpapiHost(), instance, resource, clipboard_filter)); } + case PpapiHostMsg_FlashDRM_Create::ID: + return scoped_ptr( + new chrome::PepperFlashDRMHost(host_, instance, resource)); } } diff --git a/chromium_src/chrome/browser/renderer_host/pepper/monitor_finder_mac.h b/chromium_src/chrome/browser/renderer_host/pepper/monitor_finder_mac.h new file mode 100644 index 000000000000..cc10ee85780c --- /dev/null +++ b/chromium_src/chrome/browser/renderer_host/pepper/monitor_finder_mac.h @@ -0,0 +1,52 @@ +// Copyright 2014 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 CHROME_BROWSER_RENDERER_HOST_PEPPER_MONITOR_FINDER_MAC_H_ +#define CHROME_BROWSER_RENDERER_HOST_PEPPER_MONITOR_FINDER_MAC_H_ + +#include +#include + +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "base/synchronization/lock.h" + +namespace chrome { + +// MonitorFinder maps a RenderFrameHost to the display ID on which the widget +// is painting. This class operates on the IO thread while the RenderFrameHost +// is on the UI thread, so the value returned by GetMonitor() may be 0 until +// the information can be retrieved asynchronously. +class MonitorFinder : public base::RefCountedThreadSafe { + public: + MonitorFinder(int process_id, int render_frame_id); + + // Gets the native display ID for the tuple. + int64_t GetMonitor(); + + // Checks if the given |monitor_id| represents a built-in display. + static bool IsMonitorBuiltIn(int64_t monitor_id); + + private: + friend class base::RefCountedThreadSafe; + ~MonitorFinder(); + + // Method run on the UI thread to get the display information. + void FetchMonitorFromWidget(); + + const int process_id_; + const int render_frame_id_; + + base::Lock mutex_; // Protects the two members below. + // Whether one request to FetchMonitorFromWidget() has been made already. + bool request_sent_; + // The native display ID for the RenderFrameHost. + CGDirectDisplayID display_id_; + + DISALLOW_COPY_AND_ASSIGN(MonitorFinder); +}; + +} // namespace chrome + +#endif // CHROME_BROWSER_RENDERER_HOST_PEPPER_MONITOR_FINDER_H_ diff --git a/chromium_src/chrome/browser/renderer_host/pepper/monitor_finder_mac.mm b/chromium_src/chrome/browser/renderer_host/pepper/monitor_finder_mac.mm new file mode 100644 index 000000000000..31f6cfd41060 --- /dev/null +++ b/chromium_src/chrome/browser/renderer_host/pepper/monitor_finder_mac.mm @@ -0,0 +1,62 @@ +// Copyright 2014 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 "chrome/browser/renderer_host/pepper/monitor_finder_mac.h" + +#import + +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/render_frame_host.h" + +namespace chrome { + +MonitorFinder::MonitorFinder(int process_id, int render_frame_id) + : process_id_(process_id), + render_frame_id_(render_frame_id), + request_sent_(false), + display_id_(kCGNullDirectDisplay) {} + +MonitorFinder::~MonitorFinder() {} + +int64_t MonitorFinder::GetMonitor() { + { + // The plugin may call this method several times, so avoid spamming the UI + // thread with requests by only allowing one outstanding request at a time. + base::AutoLock lock(mutex_); + if (request_sent_) + return display_id_; + request_sent_ = true; + } + + content::BrowserThread::PostTask( + content::BrowserThread::UI, + FROM_HERE, + base::Bind(&MonitorFinder::FetchMonitorFromWidget, this)); + return display_id_; +} + +// static +bool MonitorFinder::IsMonitorBuiltIn(int64_t display_id) { + return CGDisplayIsBuiltin(display_id); +} + +void MonitorFinder::FetchMonitorFromWidget() { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + content::RenderFrameHost* rfh = + content::RenderFrameHost::FromID(process_id_, render_frame_id_); + if (!rfh) + return; + + gfx::NativeView native_view = rfh->GetNativeView(); + NSWindow* window = [native_view window]; + NSScreen* screen = [window screen]; + CGDirectDisplayID display_id = + [[[screen deviceDescription] objectForKey:@"NSScreenNumber"] intValue]; + + base::AutoLock lock(mutex_); + request_sent_ = false; + display_id_ = display_id; +} + +} // namespace chrome diff --git a/chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_drm_host.cc b/chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_drm_host.cc new file mode 100644 index 000000000000..892c26141aa9 --- /dev/null +++ b/chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_drm_host.cc @@ -0,0 +1,182 @@ +// Copyright (c) 2012 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 "chrome/browser/renderer_host/pepper/pepper_flash_drm_host.h" + +#if defined(OS_WIN) +#include +#endif + +#include "base/bind.h" +#include "base/compiler_specific.h" +#include "base/logging.h" +#include "base/memory/ref_counted.h" +#include "build/build_config.h" +#include "content/public/browser/browser_ppapi_host.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/child_process_security_policy.h" +#include "content/public/browser/render_frame_host.h" +#include "content/public/common/pepper_plugin_info.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/host/dispatch_host_message.h" +#include "ppapi/host/host_message_context.h" +#include "ppapi/host/ppapi_host.h" +#include "ppapi/proxy/ppapi_messages.h" + +#if defined(USE_AURA) +#include "ui/aura/window.h" +#include "ui/aura/window_tree_host.h" +#endif + +#if defined(OS_MACOSX) +#include "chrome/browser/renderer_host/pepper/monitor_finder_mac.h" +#endif + +using content::BrowserPpapiHost; + +namespace chrome { + +namespace { +const char kVoucherFilename[] = "plugin.vch"; +} + +#if defined(OS_WIN) +// Helper class to get the UI thread which monitor is showing the +// window associated with the instance's render view. Since we get +// called by the IO thread and we cannot block, the first answer is +// of GetMonitor() may be NULL, but eventually it will contain the +// right monitor. +class MonitorFinder : public base::RefCountedThreadSafe { + public: + MonitorFinder(int process_id, int render_frame_id) + : process_id_(process_id), + render_frame_id_(render_frame_id), + monitor_(NULL), + request_sent_(0) {} + + int64_t GetMonitor() { + // We use |request_sent_| as an atomic boolean so that we + // never have more than one task posted at a given time. We + // do this because we don't know how often our client is going + // to call and we can't cache the |monitor_| value. + if (InterlockedCompareExchange(&request_sent_, 1, 0) == 0) { + content::BrowserThread::PostTask( + content::BrowserThread::UI, + FROM_HERE, + base::Bind(&MonitorFinder::FetchMonitorFromWidget, this)); + } + return reinterpret_cast(monitor_); + } + + private: + friend class base::RefCountedThreadSafe; + ~MonitorFinder() {} + + void FetchMonitorFromWidget() { + InterlockedExchange(&request_sent_, 0); + content::RenderFrameHost* rfh = + content::RenderFrameHost::FromID(process_id_, render_frame_id_); + if (!rfh) + return; + gfx::NativeView native_view = rfh->GetNativeView(); +#if defined(USE_AURA) + aura::WindowTreeHost* host = native_view->GetHost(); + if (!host) + return; + HWND window = host->GetAcceleratedWidget(); +#else + HWND window = native_view; +#endif + HMONITOR monitor = ::MonitorFromWindow(window, MONITOR_DEFAULTTONULL); + InterlockedExchangePointer(reinterpret_cast(&monitor_), + monitor); + } + + const int process_id_; + const int render_frame_id_; + volatile HMONITOR monitor_; + volatile long request_sent_; +}; +#elif !defined(OS_MACOSX) +// TODO(cpu): Support Linux someday. +class MonitorFinder : public base::RefCountedThreadSafe { + public: + MonitorFinder(int, int) {} + int64_t GetMonitor() { return 0; } + + private: + friend class base::RefCountedThreadSafe; + ~MonitorFinder() {} +}; +#endif + +PepperFlashDRMHost::PepperFlashDRMHost(BrowserPpapiHost* host, + PP_Instance instance, + PP_Resource resource) + : ppapi::host::ResourceHost(host->GetPpapiHost(), instance, resource), + weak_factory_(this) { + // Grant permissions to read the flash voucher file. + int render_process_id; + int render_frame_id; + bool success = host->GetRenderFrameIDsForInstance( + instance, &render_process_id, &render_frame_id); + base::FilePath plugin_dir = host->GetPluginPath().DirName(); + DCHECK(!plugin_dir.empty() && success); + base::FilePath voucher_file = plugin_dir.AppendASCII(kVoucherFilename); + content::ChildProcessSecurityPolicy::GetInstance()->GrantReadFile( + render_process_id, voucher_file); + + monitor_finder_ = new MonitorFinder(render_process_id, render_frame_id); + monitor_finder_->GetMonitor(); +} + +PepperFlashDRMHost::~PepperFlashDRMHost() {} + +int32_t PepperFlashDRMHost::OnResourceMessageReceived( + const IPC::Message& msg, + ppapi::host::HostMessageContext* context) { + PPAPI_BEGIN_MESSAGE_MAP(PepperFlashDRMHost, msg) + PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_FlashDRM_GetDeviceID, + OnHostMsgGetDeviceID) + PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_FlashDRM_GetHmonitor, + OnHostMsgGetHmonitor) + PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_FlashDRM_MonitorIsExternal, + OnHostMsgMonitorIsExternal) + PPAPI_END_MESSAGE_MAP() + return PP_ERROR_FAILED; +} + +int32_t PepperFlashDRMHost::OnHostMsgGetDeviceID( + ppapi::host::HostMessageContext* context) { + context->reply_msg = PpapiPluginMsg_FlashDRM_GetDeviceIDReply(""); + return PP_OK; +} + +int32_t PepperFlashDRMHost::OnHostMsgGetHmonitor( + ppapi::host::HostMessageContext* context) { + int64_t monitor_id = monitor_finder_->GetMonitor(); + if (monitor_id) { + context->reply_msg = PpapiPluginMsg_FlashDRM_GetHmonitorReply(monitor_id); + return PP_OK; + } + return PP_ERROR_FAILED; +} + +int32_t PepperFlashDRMHost::OnHostMsgMonitorIsExternal( + ppapi::host::HostMessageContext* context) { + int64_t monitor_id = monitor_finder_->GetMonitor(); + if (!monitor_id) + return PP_ERROR_FAILED; + + PP_Bool is_external = PP_FALSE; +#if defined(OS_MACOSX) + if (!MonitorFinder::IsMonitorBuiltIn(monitor_id)) + is_external = PP_TRUE; +#endif + context->reply_msg = + PpapiPluginMsg_FlashDRM_MonitorIsExternalReply(is_external); + return PP_OK; +} + +} // namespace chrome diff --git a/chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_drm_host.h b/chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_drm_host.h new file mode 100644 index 000000000000..91bba9631e68 --- /dev/null +++ b/chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_drm_host.h @@ -0,0 +1,55 @@ +// Copyright (c) 2013 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 CHROME_BROWSER_RENDERER_HOST_PEPPER_PEPPER_FLASH_DRM_HOST_H_ +#define CHROME_BROWSER_RENDERER_HOST_PEPPER_PEPPER_FLASH_DRM_HOST_H_ + +#include + +#include + +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "ppapi/host/host_message_context.h" +#include "ppapi/host/resource_host.h" + +namespace content { +class BrowserPpapiHost; +} + +namespace IPC { +class Message; +} + +namespace chrome { +class MonitorFinder; + +class PepperFlashDRMHost : public ppapi::host::ResourceHost { + public: + PepperFlashDRMHost(content::BrowserPpapiHost* host, + PP_Instance instance, + PP_Resource resource); + ~PepperFlashDRMHost() override; + + // ResourceHost override. + int32_t OnResourceMessageReceived( + const IPC::Message& msg, + ppapi::host::HostMessageContext* context) override; + + private: + // IPC message handler. + int32_t OnHostMsgGetDeviceID(ppapi::host::HostMessageContext* context); + int32_t OnHostMsgGetHmonitor(ppapi::host::HostMessageContext* context); + int32_t OnHostMsgMonitorIsExternal(ppapi::host::HostMessageContext* context); + + scoped_refptr monitor_finder_; + + base::WeakPtrFactory weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(PepperFlashDRMHost); +}; + +} // namespace chrome + +#endif // CHROME_BROWSER_RENDERER_HOST_PEPPER_PEPPER_FLASH_DRM_HOST_H_ diff --git a/filenames.gypi b/filenames.gypi index d7eb8409261b..61791604ecc5 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -410,12 +410,16 @@ 'chromium_src/chrome/browser/process_singleton.h', 'chromium_src/chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.cc', 'chromium_src/chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.h', + 'chromium_src/chrome/browser/renderer_host/pepper/monitor_finder_mac.h', + 'chromium_src/chrome/browser/renderer_host/pepper/monitor_finder_mac.mm', 'chromium_src/chrome/browser/renderer_host/pepper/pepper_broker_message_filter.cc', 'chromium_src/chrome/browser/renderer_host/pepper/pepper_broker_message_filter.h', 'chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_browser_host.cc', 'chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_browser_host.h', 'chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_clipboard_message_filter.cc', 'chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_clipboard_message_filter.h', + 'chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_drm_host.cc', + 'chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_drm_host.h', 'chromium_src/chrome/browser/renderer_host/pepper/pepper_isolated_file_system_message_filter.cc', 'chromium_src/chrome/browser/renderer_host/pepper/pepper_isolated_file_system_message_filter.h', 'chromium_src/chrome/browser/renderer_host/pepper/widevine_cdm_message_filter.cc',