Merge pull request #4070 from atom/flash-drm
Respond to GetDeviceID message from pepper plugin
This commit is contained in:
commit
630cd091a0
6 changed files with 394 additions and 0 deletions
|
@ -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<ResourceHost> ChromeBrowserPepperHostFactory::CreateResourceHost(
|
|||
return scoped_ptr<ResourceHost>(new MessageFilterHost(
|
||||
host_->GetPpapiHost(), instance, resource, clipboard_filter));
|
||||
}
|
||||
case PpapiHostMsg_FlashDRM_Create::ID:
|
||||
return scoped_ptr<ResourceHost>(
|
||||
new chrome::PepperFlashDRMHost(host_, instance, resource));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 <ApplicationServices/ApplicationServices.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#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<MonitorFinder> {
|
||||
public:
|
||||
MonitorFinder(int process_id, int render_frame_id);
|
||||
|
||||
// Gets the native display ID for the <process_id, render_frame_id> 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>;
|
||||
~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_
|
|
@ -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 <Cocoa/Cocoa.h>
|
||||
|
||||
#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
|
|
@ -0,0 +1,217 @@
|
|||
// 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"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
#include "base/bind.h"
|
||||
#include "base/compiler_specific.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/memory/ref_counted.h"
|
||||
#include "base/strings/string_number_conversions.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 "net/base/net_util.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)
|
||||
bool GetSystemVolumeSerialNumber(std::string* number) {
|
||||
// Find the system root path (e.g: C:\).
|
||||
wchar_t system_path[MAX_PATH + 1];
|
||||
if (!GetSystemDirectoryW(system_path, MAX_PATH))
|
||||
return false;
|
||||
|
||||
wchar_t* first_slash = wcspbrk(system_path, L"\\/");
|
||||
if (first_slash != NULL)
|
||||
*(first_slash + 1) = 0;
|
||||
|
||||
DWORD number_local = 0;
|
||||
if (!GetVolumeInformationW(system_path, NULL, 0, &number_local, NULL, NULL,
|
||||
NULL, 0))
|
||||
return false;
|
||||
|
||||
*number = base::IntToString(std::abs(static_cast<int>(number_local)));
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#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<MonitorFinder> {
|
||||
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<int64_t>(monitor_);
|
||||
}
|
||||
|
||||
private:
|
||||
friend class base::RefCountedThreadSafe<MonitorFinder>;
|
||||
~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<void* volatile*>(&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<MonitorFinder> {
|
||||
public:
|
||||
MonitorFinder(int, int) {}
|
||||
int64_t GetMonitor() { return 0; }
|
||||
|
||||
private:
|
||||
friend class base::RefCountedThreadSafe<MonitorFinder>;
|
||||
~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) {
|
||||
static std::string id;
|
||||
#if defined(OS_WIN)
|
||||
if (id.empty() && !GetSystemVolumeSerialNumber(&id))
|
||||
id = net::GetHostName();
|
||||
#else
|
||||
if (id.empty())
|
||||
id = net::GetHostName();
|
||||
#endif
|
||||
context->reply_msg = PpapiPluginMsg_FlashDRM_GetDeviceIDReply(id);
|
||||
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
|
|
@ -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 <stdint.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#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<MonitorFinder> monitor_finder_;
|
||||
|
||||
base::WeakPtrFactory<PepperFlashDRMHost> weak_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(PepperFlashDRMHost);
|
||||
};
|
||||
|
||||
} // namespace chrome
|
||||
|
||||
#endif // CHROME_BROWSER_RENDERER_HOST_PEPPER_PEPPER_FLASH_DRM_HOST_H_
|
|
@ -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',
|
||||
|
|
Loading…
Reference in a new issue