pepper_output_protection_message_filter.cc revision f8ee788a64d60abd8f2d742a5fdedde054ecd910
1868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
4868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
5868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/renderer_host/pepper/pepper_output_protection_message_filter.h"
6868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
7868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "build/build_config.h"
8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/media/media_capture_devices_dispatcher.h"
9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/public/browser/browser_ppapi_host.h"
10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/public/browser/render_frame_host.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/web_contents.h"
13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "ppapi/c/pp_errors.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/c/private/ppb_output_protection_private.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/host/dispatch_host_message.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/host/host_message_context.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/host/ppapi_host.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/proxy/ppapi_messages.h"
19d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#if defined(OS_CHROMEOS)
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/shell.h"
22868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "ash/shell_delegate.h"
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/window.h"
24eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "ui/display/chromeos/display_configurator.h"
25d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/gfx/screen.h"
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
27868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace chrome {
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace {
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_CHROMEOS)
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)COMPILE_ASSERT(static_cast<int>(PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_NONE) ==
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   static_cast<int>(ui::DISPLAY_CONNECTION_TYPE_NONE),
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_NONE);
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)COMPILE_ASSERT(
3790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    static_cast<int>(PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_UNKNOWN) ==
38ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        static_cast<int>(ui::DISPLAY_CONNECTION_TYPE_UNKNOWN),
3990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_UNKNOWN);
40868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)COMPILE_ASSERT(
41868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    static_cast<int>(PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_INTERNAL) ==
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        static_cast<int>(ui::DISPLAY_CONNECTION_TYPE_INTERNAL),
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_INTERNAL);
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)COMPILE_ASSERT(static_cast<int>(PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_VGA) ==
45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                   static_cast<int>(ui::DISPLAY_CONNECTION_TYPE_VGA),
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_VGA);
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)COMPILE_ASSERT(static_cast<int>(PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_HDMI) ==
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   static_cast<int>(ui::DISPLAY_CONNECTION_TYPE_HDMI),
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_HDMI);
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)COMPILE_ASSERT(static_cast<int>(PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_DVI) ==
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   static_cast<int>(ui::DISPLAY_CONNECTION_TYPE_DVI),
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_DVI);
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)COMPILE_ASSERT(
54d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    static_cast<int>(PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_DISPLAYPORT) ==
55d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        static_cast<int>(ui::DISPLAY_CONNECTION_TYPE_DISPLAYPORT),
56d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_DISPLAYPORT);
57d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)COMPILE_ASSERT(
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    static_cast<int>(PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_NETWORK) ==
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        static_cast<int>(ui::DISPLAY_CONNECTION_TYPE_NETWORK),
60868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_NETWORK);
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)COMPILE_ASSERT(static_cast<int>(PP_OUTPUT_PROTECTION_METHOD_PRIVATE_NONE) ==
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   static_cast<int>(ui::CONTENT_PROTECTION_METHOD_NONE),
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               PP_OUTPUT_PROTECTION_METHOD_PRIVATE_NONE);
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)COMPILE_ASSERT(static_cast<int>(PP_OUTPUT_PROTECTION_METHOD_PRIVATE_HDCP) ==
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   static_cast<int>(ui::CONTENT_PROTECTION_METHOD_HDCP),
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               PP_OUTPUT_PROTECTION_METHOD_PRIVATE_HDCP);
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GetCurrentDisplayId(content::RenderFrameHost* rfh, int64* display_id) {
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::NativeView native_view = rfh->GetNativeView();
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Screen* screen = gfx::Screen::GetScreenFor(native_view);
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!screen)
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Display display = screen->GetDisplayNearestWindow(native_view);
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *display_id = display.id();
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
77868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
82868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#if defined(OS_CHROMEOS)
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Output protection delegate. All methods except constructor should be
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// invoked in UI thread.
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class PepperOutputProtectionMessageFilter::Delegate
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : public aura::WindowObserver {
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Delegate(int render_process_id, int render_frame_id);
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~Delegate();
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // aura::WindowObserver overrides.
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnWindowHierarchyChanged(
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const aura::WindowObserver::HierarchyChangeParams& params) OVERRIDE;
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnWindowDestroying(aura::Window* window) OVERRIDE;
95ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
96868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int32_t OnQueryStatus(uint32_t* link_mask, uint32_t* protection_mask);
97ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  int32_t OnEnableProtection(uint32_t desired_method_mask);
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
99868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private:
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui::DisplayConfigurator::ContentProtectionClientId GetClientId();
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Used to lookup the WebContents associated with this PP_Instance.
103ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  int render_process_id_;
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int render_frame_id_;
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Native window being observed.
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  aura::Window* window_;
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui::DisplayConfigurator::ContentProtectionClientId client_id_;
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The display id which the renderer currently uses.
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int64 display_id_;
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The last desired method mask. Will enable this mask on new display if
115868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // renderer changes display.
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uint32_t desired_method_mask_;
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)PepperOutputProtectionMessageFilter::Delegate::Delegate(int render_process_id,
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                        int render_frame_id)
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : render_process_id_(render_process_id),
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      render_frame_id_(render_frame_id),
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      window_(NULL),
124868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      client_id_(ui::DisplayConfigurator::kInvalidClientId),
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      display_id_(0) {
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)PepperOutputProtectionMessageFilter::Delegate::~Delegate() {
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
132868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ui::DisplayConfigurator* configurator =
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ash::Shell::GetInstance()->display_configurator();
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  configurator->UnregisterContentProtectionClient(client_id_);
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (window_)
137868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    window_->RemoveObserver(this);
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ui::DisplayConfigurator::ContentProtectionClientId
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)PepperOutputProtectionMessageFilter::Delegate::GetClientId() {
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (client_id_ == ui::DisplayConfigurator::kInvalidClientId) {
144868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    content::RenderFrameHost* rfh =
145868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        content::RenderFrameHost::FromID(render_process_id_, render_frame_id_);
146868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (!GetCurrentDisplayId(rfh, &display_id_))
147868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      return ui::DisplayConfigurator::kInvalidClientId;
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    window_ = rfh->GetNativeView();
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!window_)
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return ui::DisplayConfigurator::kInvalidClientId;
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    window_->AddObserver(this);
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ui::DisplayConfigurator* configurator =
155868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        ash::Shell::GetInstance()->display_configurator();
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    client_id_ = configurator->RegisterContentProtectionClient();
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return client_id_;
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int32_t PepperOutputProtectionMessageFilter::Delegate::OnQueryStatus(
162868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    uint32_t* link_mask,
16390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    uint32_t* protection_mask) {
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
165d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
166d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  content::RenderFrameHost* rfh =
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      content::RenderFrameHost::FromID(render_process_id_, render_frame_id_);
168868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!rfh) {
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LOG(WARNING) << "RenderFrameHost is not alive.";
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return PP_ERROR_FAILED;
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui::DisplayConfigurator* configurator =
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ash::Shell::GetInstance()->display_configurator();
175868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  bool result = configurator->QueryContentProtectionStatus(
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetClientId(), display_id_, link_mask, protection_mask);
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If we successfully retrieved the device level status, check for capturers.
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (result) {
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const bool capture_detected =
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        // Check for tab capture on the current tab.
182d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        content::WebContents::FromRenderFrameHost(rfh)->GetCapturerCount() >
183d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)            0 ||
184d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        // Check for desktop capture.
185d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        MediaCaptureDevicesDispatcher::GetInstance()
186d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)            ->IsDesktopCaptureInProgress();
187d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    if (capture_detected)
188d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      *link_mask |= ui::DISPLAY_CONNECTION_TYPE_NETWORK;
189d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
190d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
191d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  return result ? PP_OK : PP_ERROR_FAILED;
192d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
193d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
194d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)int32_t PepperOutputProtectionMessageFilter::Delegate::OnEnableProtection(
195d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    uint32_t desired_method_mask) {
196d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
197d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
198d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  ui::DisplayConfigurator* configurator =
199d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      ash::Shell::GetInstance()->display_configurator();
200d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  bool result = configurator->EnableContentProtection(
201d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      GetClientId(), display_id_, desired_method_mask);
202d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  desired_method_mask_ = desired_method_mask;
203d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  return result ? PP_OK : PP_ERROR_FAILED;
204d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
205d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
206d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void PepperOutputProtectionMessageFilter::Delegate::OnWindowHierarchyChanged(
207d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    const aura::WindowObserver::HierarchyChangeParams& params) {
208d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  content::RenderFrameHost* rfh =
209d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      content::RenderFrameHost::FromID(render_process_id_, render_frame_id_);
210d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (!rfh) {
211d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    LOG(WARNING) << "RenderFrameHost is not alive.";
212d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return;
213d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
214d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
215d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  int64 new_display_id = 0;
216d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (!GetCurrentDisplayId(rfh, &new_display_id))
217d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return;
218d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (display_id_ == new_display_id)
219d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return;
220d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
221d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (desired_method_mask_ != ui::CONTENT_PROTECTION_METHOD_NONE) {
222d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // Display changed and should enable output protections on new display.
223d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    ui::DisplayConfigurator* configurator =
224d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        ash::Shell::GetInstance()->display_configurator();
225d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    configurator->EnableContentProtection(
226d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        GetClientId(), new_display_id, desired_method_mask_);
227d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    configurator->EnableContentProtection(
228d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        GetClientId(), display_id_, ui::CONTENT_PROTECTION_METHOD_NONE);
229d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
230d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  display_id_ = new_display_id;
231d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
232d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
233d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void PepperOutputProtectionMessageFilter::Delegate::OnWindowDestroying(
234d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    aura::Window* window) {
235d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  DCHECK_EQ(window, window_);
236d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  window_->RemoveObserver(this);
237d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  window_ = NULL;
238d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
239d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#endif  // defined(OS_CHROMEOS)
240d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
241d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)PepperOutputProtectionMessageFilter::PepperOutputProtectionMessageFilter(
242d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    content::BrowserPpapiHost* host,
243d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    PP_Instance instance) {
244d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#if defined(OS_CHROMEOS)
245d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
246d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  int render_process_id = 0;
247d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  int render_frame_id = 0;
248d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  host->GetRenderFrameIDsForInstance(
249d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      instance, &render_process_id, &render_frame_id);
250868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  delegate_ = new Delegate(render_process_id, render_frame_id);
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NOTIMPLEMENTED();
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
25590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)PepperOutputProtectionMessageFilter::~PepperOutputProtectionMessageFilter() {
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_CHROMEOS)
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content::BrowserThread::DeleteSoon(
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      content::BrowserThread::UI, FROM_HERE, delegate_);
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delegate_ = NULL;
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
264a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)scoped_refptr<base::TaskRunner>
265d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)PepperOutputProtectionMessageFilter::OverrideTaskRunnerForMessage(
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const IPC::Message& message) {
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return content::BrowserThread::GetMessageLoopProxyForThread(
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      content::BrowserThread::UI);
269868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int32_t PepperOutputProtectionMessageFilter::OnResourceMessageReceived(
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const IPC::Message& msg,
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ppapi::host::HostMessageContext* context) {
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PPAPI_BEGIN_MESSAGE_MAP(PepperOutputProtectionMessageFilter, msg)
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(
276ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        PpapiHostMsg_OutputProtection_QueryStatus, OnQueryStatus);
27790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    PPAPI_DISPATCH_HOST_RESOURCE_CALL(
27890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        PpapiHostMsg_OutputProtection_EnableProtection, OnEnableProtection);
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PPAPI_END_MESSAGE_MAP()
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return PP_ERROR_FAILED;
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int32_t PepperOutputProtectionMessageFilter::OnQueryStatus(
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ppapi::host::HostMessageContext* context) {
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_CHROMEOS)
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uint32_t link_mask = 0, protection_mask = 0;
287868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int32_t result = delegate_->OnQueryStatus(&link_mask, &protection_mask);
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ppapi::host::ReplyMessageContext reply_context =
290d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      context->MakeReplyMessageContext();
2917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  reply_context.params.set_result(result);
2927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  SendReply(reply_context,
2937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            PpapiPluginMsg_OutputProtection_QueryStatusReply(link_mask,
294868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                                             protection_mask));
295868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return PP_OK_COMPLETIONPENDING;
29690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#else
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NOTIMPLEMENTED();
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return PP_ERROR_NOTSUPPORTED;
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int32_t PepperOutputProtectionMessageFilter::OnEnableProtection(
303a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ppapi::host::HostMessageContext* context,
304a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    uint32_t desired_method_mask) {
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_CHROMEOS)
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ppapi::host::ReplyMessageContext reply_context =
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      context->MakeReplyMessageContext();
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int32_t result = delegate_->OnEnableProtection(desired_method_mask);
309ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  reply_context.params.set_result(result);
31090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  SendReply(reply_context,
31190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)            PpapiPluginMsg_OutputProtection_EnableProtectionReply());
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return PP_OK_COMPLETIONPENDING;
313d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#else
314d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  NOTIMPLEMENTED();
315d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  return PP_ERROR_NOTSUPPORTED;
316d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#endif
317d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
318d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
319d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}  // namespace chrome
320d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)