123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- // Copyright 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.
- #include "ash/display/output_protection_delegate.h"
- #include "ash/capture_mode/capture_mode_controller.h"
- #include "ash/shell.h"
- #include "base/callback_helpers.h"
- #include "ui/display/display.h"
- #include "ui/display/manager/content_protection_manager.h"
- #include "ui/display/manager/display_configurator.h"
- #include "ui/display/screen.h"
- #include "ui/display/types/display_constants.h"
- namespace ash {
- namespace {
- display::ContentProtectionManager* manager() {
- return Shell::Get()->display_configurator()->content_protection_manager();
- }
- void MaybeSetCaptureModeWindowProtection(aura::Window* window,
- uint32_t protection_mask) {
- CaptureModeController::Get()->SetWindowProtectionMask(window,
- protection_mask);
- }
- } // namespace
- struct OutputProtectionDelegate::ClientIdHolder {
- ClientIdHolder() : id(manager()->RegisterClient()) {}
- ~ClientIdHolder() { manager()->UnregisterClient(id); }
- const display::ContentProtectionManager::ClientId id;
- };
- OutputProtectionDelegate::OutputProtectionDelegate(aura::Window* window)
- : window_(window),
- display_id_(
- display::Screen::GetScreen()->GetDisplayNearestWindow(window).id()) {
- // TODO(domlaskowski): OutputProtectionImpl passes null if the RenderFrameHost
- // no longer exists. Investigate removing this check in crbug.com/997270.
- if (!window_)
- return;
- window_->AddObserver(this);
- }
- OutputProtectionDelegate::~OutputProtectionDelegate() {
- if (!window_)
- return;
- window_->RemoveObserver(this);
- MaybeSetCaptureModeWindowProtection(window_,
- display::CONTENT_PROTECTION_METHOD_NONE);
- }
- void OutputProtectionDelegate::OnDisplayMetricsChanged(
- const display::Display& display,
- uint32_t changed_metrics) {
- // Switching the primary display (either by user or by going into docked
- // mode), as well as changing mirror mode may change the display on which
- // the window resides without actually changing the window hierarchy (i.e.
- // the root window is still the same). Hence we need to watch out for these
- // situations and update |display_id_| if needed.
- if (!(changed_metrics &
- (display::DisplayObserver::DISPLAY_METRIC_PRIMARY |
- display::DisplayObserver::DISPLAY_METRIC_MIRROR_STATE))) {
- return;
- }
- OnWindowMayHaveMovedToAnotherDisplay();
- }
- void OutputProtectionDelegate::OnWindowHierarchyChanged(
- const aura::WindowObserver::HierarchyChangeParams& params) {
- OnWindowMayHaveMovedToAnotherDisplay();
- }
- void OutputProtectionDelegate::OnWindowDestroying(aura::Window* window) {
- DCHECK_EQ(window, window_);
- display_observer_.reset();
- window_->RemoveObserver(this);
- MaybeSetCaptureModeWindowProtection(window_,
- display::CONTENT_PROTECTION_METHOD_NONE);
- window_ = nullptr;
- }
- void OutputProtectionDelegate::QueryStatus(QueryStatusCallback callback) {
- if (!RegisterClientIfNecessary()) {
- std::move(callback).Run(/*success=*/false,
- display::DISPLAY_CONNECTION_TYPE_NONE,
- display::CONTENT_PROTECTION_METHOD_NONE);
- return;
- }
- manager()->QueryContentProtection(client_->id, display_id_,
- std::move(callback));
- }
- void OutputProtectionDelegate::SetProtection(uint32_t protection_mask,
- SetProtectionCallback callback) {
- protection_mask_ = protection_mask;
- // Capture mode screen recording doesn't rely on display protection, and hence
- // must be informed with the new window's protection.
- if (window_)
- MaybeSetCaptureModeWindowProtection(window_, protection_mask);
- if (!RegisterClientIfNecessary()) {
- std::move(callback).Run(/*success=*/false);
- return;
- }
- manager()->ApplyContentProtection(client_->id, display_id_, protection_mask,
- std::move(callback));
- }
- void OutputProtectionDelegate::OnWindowMayHaveMovedToAnotherDisplay() {
- DCHECK(window_);
- int64_t new_display_id =
- display::Screen::GetScreen()->GetDisplayNearestWindow(window_).id();
- if (display_id_ == new_display_id)
- return;
- if (protection_mask_ != display::CONTENT_PROTECTION_METHOD_NONE) {
- DCHECK(client_);
- manager()->ApplyContentProtection(client_->id, new_display_id,
- protection_mask_, base::DoNothing());
- manager()->ApplyContentProtection(client_->id, display_id_,
- display::CONTENT_PROTECTION_METHOD_NONE,
- base::DoNothing());
- // The window may have moved to a display that is currently being recorded,
- // so we need to refresh Capture Mode's content protection.
- CaptureModeController::Get()->RefreshContentProtection();
- }
- display_id_ = new_display_id;
- }
- bool OutputProtectionDelegate::RegisterClientIfNecessary() {
- if (!window_)
- return false;
- if (!client_)
- client_ = std::make_unique<ClientIdHolder>();
- return true;
- }
- } // namespace ash
|