diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2019-08-30 10:22:43 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2019-08-30 12:36:28 +0000 |
commit | 271a6c3487a14599023a9106329505597638d793 (patch) | |
tree | e040d58ffc86c1480b79ca8528020ca9ec919bf8 /chromium/ui/display | |
parent | 7b2ffa587235a47d4094787d72f38102089f402a (diff) | |
download | qtwebengine-chromium-271a6c3487a14599023a9106329505597638d793.tar.gz |
BASELINE: Update Chromium to 77.0.3865.59
Change-Id: I1e89a5f3b009a9519a6705102ad65c92fe736f21
Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/ui/display')
61 files changed, 1871 insertions, 830 deletions
diff --git a/chromium/ui/display/BUILD.gn b/chromium/ui/display/BUILD.gn index 19320f0b5ba..ffb7da246ff 100644 --- a/chromium/ui/display/BUILD.gn +++ b/chromium/ui/display/BUILD.gn @@ -29,6 +29,8 @@ jumbo_component("display") { "display_switches.cc", "display_switches.h", "ios/screen_ios.mm", + "mac/display_link_mac.cc", + "mac/display_link_mac.h", "mac/screen_mac.mm", "screen.cc", "screen.h", @@ -54,8 +56,6 @@ jumbo_component("display") { "win/uwp_text_scale_factor.h", ] - configs += [ "//build/config/compiler:wexit_time_destructors" ] - defines = [ "DISPLAY_IMPLEMENTATION" ] public_deps = [ @@ -85,6 +85,7 @@ jumbo_component("display") { libs = [ "AppKit.framework", "CoreGraphics.framework", + "QuartzCore.framework", ] } } @@ -167,7 +168,7 @@ test("display_unittests") { "manager/display_manager_utilities_unittest.cc", "manager/json_converter_unittest.cc", "manager/managed_display_info_unittest.cc", - "mojo/display_struct_traits_unittest.cc", + "mojom/display_mojom_traits_unittest.cc", "screen_unittest.cc", "unified_desktop_utils_unittests.cc", "util/display_util_unittest.cc", @@ -180,6 +181,7 @@ test("display_unittests") { sources += [ "manager/apply_content_protection_task_unittest.cc", "manager/configure_displays_task_unittest.cc", + "manager/content_protection_manager_unittest.cc", "manager/display_change_observer_unittest.cc", "manager/display_configurator_unittest.cc", "manager/display_utils_unittest.cc", @@ -202,7 +204,7 @@ test("display_unittests") { "//testing/gtest", "//ui/display/fake", "//ui/display/manager", - "//ui/display/mojo:interfaces", + "//ui/display/mojom:mojom", "//ui/display/types", "//ui/display/util", "//ui/events:test_support", diff --git a/chromium/ui/display/OWNERS b/chromium/ui/display/OWNERS index 0101ef32916..6f1361981b8 100644 --- a/chromium/ui/display/OWNERS +++ b/chromium/ui/display/OWNERS @@ -1,5 +1,4 @@ afakhry@chromium.org -derat@chromium.org dnicoara@chromium.org marcheu@chromium.org oshima@chromium.org diff --git a/chromium/ui/display/display_change_notifier.cc b/chromium/ui/display/display_change_notifier.cc index 9c1e6eca641..ff453e0a31e 100644 --- a/chromium/ui/display/display_change_notifier.cc +++ b/chromium/ui/display/display_change_notifier.cc @@ -80,8 +80,10 @@ void DisplayChangeNotifier::NotifyDisplaysChanged( if (new_it->device_scale_factor() != old_it->device_scale_factor()) metrics |= DisplayObserver::DISPLAY_METRIC_DEVICE_SCALE_FACTOR; - if (new_it->color_space() != old_it->color_space()) + if (new_it->color_space() != old_it->color_space() || + new_it->sdr_white_level() != old_it->sdr_white_level()) { metrics |= DisplayObserver::DISPLAY_METRIC_COLOR_SPACE; + } if (metrics != DisplayObserver::DISPLAY_METRIC_NONE) { for (DisplayObserver& observer : observer_list_) diff --git a/chromium/ui/display/mac/display_link_mac.cc b/chromium/ui/display/mac/display_link_mac.cc new file mode 100644 index 00000000000..6e0f7cfbc0c --- /dev/null +++ b/chromium/ui/display/mac/display_link_mac.cc @@ -0,0 +1,266 @@ +// 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 "ui/display/mac/display_link_mac.h" + +#include <stdint.h> + +#include "base/bind.h" +#include "base/location.h" +#include "base/logging.h" +#include "base/no_destructor.h" +#include "base/numerics/safe_conversions.h" +#include "base/single_thread_task_runner.h" +#include "base/threading/thread_task_runner_handle.h" +#include "base/trace_event/trace_event.h" + +namespace base { + +template <> +struct ScopedTypeRefTraits<CVDisplayLinkRef> { + static CVDisplayLinkRef InvalidValue() { return nullptr; } + static CVDisplayLinkRef Retain(CVDisplayLinkRef object) { + return CVDisplayLinkRetain(object); + } + static void Release(CVDisplayLinkRef object) { CVDisplayLinkRelease(object); } +}; + +} // namespace base + +namespace ui { + +using DisplayLinkMap = std::map<CGDirectDisplayID, DisplayLinkMac*>; + +namespace { + +// The task runner to post tasks to from the display link thread. Note that this +// is initialized with the very first DisplayLinkMac instance, and is never +// changed (even, e.g, in tests that re-initialize the main thread task runner). +// https://885329 +// TODO(ccameron): crbug.com/969157 - Save this ask_runner to DisaplayLinkMac. +// configs += [ "//build/config/compiler:wexit_time_destructors" ] in +// ui/display/BUILD.gn has to be removed because GetMainThreadTaskRunner() +// causes a compiler error. +scoped_refptr<base::SingleThreadTaskRunner> GetMainThreadTaskRunner() { + static scoped_refptr<base::SingleThreadTaskRunner> task_runner = + base::ThreadTaskRunnerHandle::Get(); + return task_runner; +} + +// Each display link instance consumes a non-negligible number of cycles, so +// make all display links on the same screen share the same object. +// +// Note that this is a weak map, holding non-owning pointers to the +// DisplayLinkMac objects. DisplayLinkMac is a ref-counted class, and is +// jointly owned by the various callers that got a copy by calling +// GetForDisplay(). +// +// ** This map may only be accessed from the main thread. ** +DisplayLinkMap& GetAllDisplayLinks() { + static base::NoDestructor<DisplayLinkMap> all_display_links; + return *all_display_links; +} + +} // namespace + +// static +scoped_refptr<DisplayLinkMac> DisplayLinkMac::GetForDisplay( + CGDirectDisplayID display_id) { + if (!display_id) + return nullptr; + + // Return the existing display link for this display, if it exists. + DisplayLinkMap& all_display_links = GetAllDisplayLinks(); + auto found = all_display_links.find(display_id); + if (found != all_display_links.end()) + return found->second; + + CVReturn ret = kCVReturnSuccess; + + base::ScopedTypeRef<CVDisplayLinkRef> display_link; + ret = CVDisplayLinkCreateWithCGDisplay(display_id, + display_link.InitializeInto()); + if (ret != kCVReturnSuccess) { + LOG(ERROR) << "CVDisplayLinkCreateWithActiveCGDisplays failed: " << ret; + return nullptr; + } + + scoped_refptr<DisplayLinkMac> display_link_mac( + new DisplayLinkMac(display_id, display_link)); + ret = CVDisplayLinkSetOutputCallback(display_link_mac->display_link_, + &DisplayLinkCallback, + reinterpret_cast<void*>(display_id)); + if (ret != kCVReturnSuccess) { + LOG(ERROR) << "CVDisplayLinkSetOutputCallback failed: " << ret; + return nullptr; + } + + return display_link_mac; +} + +bool DisplayLinkMac::GetVSyncParameters(base::TimeTicks* timebase, + base::TimeDelta* interval) { + if (!timebase_and_interval_valid_) { + StartOrContinueDisplayLink(); + return false; + } + + // The vsync parameters skew over time (astonishingly quickly -- 0.1 msec per + // second). If too much time has elapsed since the last time the vsync + // parameters were calculated, re-calculate them (but still return the old + // parameters -- the update will be asynchronous). + if (base::TimeTicks::Now() >= recalculate_time_) + StartOrContinueDisplayLink(); + + *timebase = timebase_; + *interval = interval_; + return true; +} + +double DisplayLinkMac::GetRefreshRate() { + double refresh_rate = 0; + CVTime cv_time = + CVDisplayLinkGetNominalOutputVideoRefreshPeriod(display_link_); + if (!(cv_time.flags & kCVTimeIsIndefinite)) + refresh_rate = (static_cast<double>(cv_time.timeScale) / + static_cast<double>(cv_time.timeValue)); + + return refresh_rate; +} + +DisplayLinkMac::DisplayLinkMac( + CGDirectDisplayID display_id, + base::ScopedTypeRef<CVDisplayLinkRef> display_link) + : display_id_(display_id), display_link_(display_link) { + DisplayLinkMap& all_display_links = GetAllDisplayLinks(); + DCHECK(all_display_links.find(display_id) == all_display_links.end()); + if (all_display_links.empty()) { + CGError register_error = CGDisplayRegisterReconfigurationCallback( + DisplayReconfigurationCallBack, nullptr); + DPLOG_IF(ERROR, register_error != kCGErrorSuccess) + << "CGDisplayRegisterReconfigurationCallback: " << register_error; + } + all_display_links.insert(std::make_pair(display_id_, this)); +} + +DisplayLinkMac::~DisplayLinkMac() { + StopDisplayLink(); + + DisplayLinkMap& all_display_links = GetAllDisplayLinks(); + auto found = all_display_links.find(display_id_); + DCHECK(found != all_display_links.end()); + DCHECK(found->second == this); + all_display_links.erase(found); + if (all_display_links.empty()) { + CGError remove_error = CGDisplayRemoveReconfigurationCallback( + DisplayReconfigurationCallBack, nullptr); + DPLOG_IF(ERROR, remove_error != kCGErrorSuccess) + << "CGDisplayRemoveReconfigurationCallback: " << remove_error; + } +} + +// static +void DisplayLinkMac::DoUpdateVSyncParameters(CGDirectDisplayID display, + const CVTimeStamp& time) { + DisplayLinkMap& all_display_links = GetAllDisplayLinks(); + auto found = all_display_links.find(display); + if (found == all_display_links.end()) { + // This might reasonably happen (and does; see https://crbug.com/564780). It + // occasionally happens that the CVDisplayLink calls back on the video + // thread, but by the time the callback makes it to the main thread for + // processing, the DisplayLinkMac object has lost all its references and + // has been deleted. + return; + } + + DisplayLinkMac* display_link_mac = found->second; + display_link_mac->UpdateVSyncParameters(time); +} + +void DisplayLinkMac::UpdateVSyncParameters(const CVTimeStamp& cv_time) { + TRACE_EVENT0("ui", "DisplayLinkMac::UpdateVSyncParameters"); + + // Verify that videoRefreshPeriod fits in 32 bits. + DCHECK((cv_time.videoRefreshPeriod & ~0xFFFF'FFFFull) == 0ull); + + // Verify that the numerator and denominator make some sense. + uint32_t numerator = static_cast<uint32_t>(cv_time.videoRefreshPeriod); + uint32_t denominator = cv_time.videoTimeScale; + if (numerator == 0 || denominator == 0) { + LOG(WARNING) << "Unexpected numerator or denominator, bailing."; + return; + } + + base::CheckedNumeric<int64_t> interval_us(base::Time::kMicrosecondsPerSecond); + interval_us *= numerator; + interval_us /= denominator; + if (!interval_us.IsValid()) { + LOG(DFATAL) << "Bailing due to overflow: " + << base::Time::kMicrosecondsPerSecond << " * " << numerator + << " / " << denominator; + return; + } + + timebase_ = base::TimeTicks::FromMachAbsoluteTime(cv_time.hostTime); + interval_ = base::TimeDelta::FromMicroseconds(interval_us.ValueOrDie()); + timebase_and_interval_valid_ = true; + + // Don't restart the display link for 10 seconds. + recalculate_time_ = base::TimeTicks::Now() + base::TimeDelta::FromSeconds(10); + StopDisplayLink(); +} + +void DisplayLinkMac::StartOrContinueDisplayLink() { + if (CVDisplayLinkIsRunning(display_link_)) + return; + + // Ensure the main thread is captured. + if (!task_runner_) + task_runner_ = GetMainThreadTaskRunner(); + + CVReturn ret = CVDisplayLinkStart(display_link_); + if (ret != kCVReturnSuccess) + LOG(ERROR) << "CVDisplayLinkStart failed: " << ret; +} + +void DisplayLinkMac::StopDisplayLink() { + if (!CVDisplayLinkIsRunning(display_link_)) + return; + + CVReturn ret = CVDisplayLinkStop(display_link_); + if (ret != kCVReturnSuccess) + LOG(ERROR) << "CVDisplayLinkStop failed: " << ret; +} + +// static +CVReturn DisplayLinkMac::DisplayLinkCallback(CVDisplayLinkRef display_link, + const CVTimeStamp* now, + const CVTimeStamp* output_time, + CVOptionFlags flags_in, + CVOptionFlags* flags_out, + void* context) { + TRACE_EVENT0("ui", "DisplayLinkMac::DisplayLinkCallback"); + CGDirectDisplayID display = + static_cast<CGDirectDisplayID>(reinterpret_cast<uintptr_t>(context)); + GetMainThreadTaskRunner()->PostTask( + FROM_HERE, base::BindOnce(&DisplayLinkMac::DoUpdateVSyncParameters, + display, *output_time)); + return kCVReturnSuccess; +} + +// static +void DisplayLinkMac::DisplayReconfigurationCallBack( + CGDirectDisplayID display, + CGDisplayChangeSummaryFlags flags, + void* user_info) { + DisplayLinkMap& all_display_links = GetAllDisplayLinks(); + auto found = all_display_links.find(display); + if (found == all_display_links.end()) + return; + + DisplayLinkMac* display_link_mac = found->second; + display_link_mac->timebase_and_interval_valid_ = false; +} + +} // namespace ui diff --git a/chromium/ui/display/mac/display_link_mac.h b/chromium/ui/display/mac/display_link_mac.h new file mode 100644 index 00000000000..3db8d3cbfb6 --- /dev/null +++ b/chromium/ui/display/mac/display_link_mac.h @@ -0,0 +1,88 @@ +// 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 UI_DISPLAY_MAC_DISPLAY_LINK_MAC_H_ +#define UI_DISPLAY_MAC_DISPLAY_LINK_MAC_H_ + +#include <QuartzCore/CVDisplayLink.h> + +#include <map> + +#include "base/mac/scoped_typeref.h" +#include "base/memory/ref_counted.h" +#include "base/single_thread_task_runner.h" +#include "base/time/time.h" +#include "ui/display/display_export.h" + +namespace ui { + +class DISPLAY_EXPORT DisplayLinkMac + : public base::RefCountedThreadSafe<DisplayLinkMac> { + public: + // This must only be called from the main thread. + static scoped_refptr<DisplayLinkMac> GetForDisplay( + CGDirectDisplayID display_id); + + // Get vsync scheduling parameters. Returns false if the populated parameters + // are invalid. + bool GetVSyncParameters(base::TimeTicks* timebase, base::TimeDelta* interval); + + // Get the panel/monitor refresh rate + double GetRefreshRate(); + + private: + friend class base::RefCountedThreadSafe<DisplayLinkMac>; + + DisplayLinkMac(CGDirectDisplayID display_id, + base::ScopedTypeRef<CVDisplayLinkRef> display_link); + virtual ~DisplayLinkMac(); + + void StartOrContinueDisplayLink(); + void StopDisplayLink(); + + // Looks up the display and calls UpdateVSyncParameters() on the corresponding + // DisplayLinkMac. + static void DoUpdateVSyncParameters(CGDirectDisplayID display, + const CVTimeStamp& time); + + // Processes the display link callback. + void UpdateVSyncParameters(const CVTimeStamp& time); + + // Called by the system on the display link thread, and posts a call to + // DoUpdateVSyncParameters() to the UI thread. + static CVReturn DisplayLinkCallback(CVDisplayLinkRef display_link, + const CVTimeStamp* now, + const CVTimeStamp* output_time, + CVOptionFlags flags_in, + CVOptionFlags* flags_out, + void* context); + + // This is called whenever the display is reconfigured, and marks that the + // vsync parameters must be recalculated. + static void DisplayReconfigurationCallBack(CGDirectDisplayID display, + CGDisplayChangeSummaryFlags flags, + void* user_info); + + // The display that this display link is attached to. + CGDirectDisplayID display_id_; + + // CVDisplayLink for querying VSync timing info. + base::ScopedTypeRef<CVDisplayLinkRef> display_link_; + + // The task runner to post tasks to from the display link thread. + scoped_refptr<base::SingleThreadTaskRunner> task_runner_; + + // VSync parameters computed during UpdateVSyncParameters(). + bool timebase_and_interval_valid_ = false; + base::TimeTicks timebase_; + base::TimeDelta interval_; + + // The time after which we should re-start the display link to get fresh + // parameters. + base::TimeTicks recalculate_time_; +}; + +} // namespace ui + +#endif // UI_DISPLAY_MAC_DISPLAY_LINK_MAC_H_ diff --git a/chromium/ui/display/mac/screen_mac.mm b/chromium/ui/display/mac/screen_mac.mm index 4d5b83a1a4b..170963e3206 100644 --- a/chromium/ui/display/mac/screen_mac.mm +++ b/chromium/ui/display/mac/screen_mac.mm @@ -21,6 +21,7 @@ #include "base/timer/timer.h" #include "ui/display/display.h" #include "ui/display/display_change_notifier.h" +#include "ui/display/mac/display_link_mac.h" #include "ui/gfx/icc_profile.h" #include "ui/gfx/mac/coordinate_conversion.h" @@ -109,6 +110,9 @@ Display BuildDisplayForScreen(NSScreen* screen) { display.set_depth_per_component(NSBitsPerSampleFromDepth([screen depth])); display.set_is_monochrome(CGDisplayUsesForceToGray()); + if (auto display_link = ui::DisplayLinkMac::GetForDisplay(display_id)) + display.set_display_frequency(display_link->GetRefreshRate()); + // CGDisplayRotation returns a double. Display::SetRotationAsDegree will // handle the unexpected situations were the angle is not a multiple of 90. display.SetRotationAsDegree(static_cast<int>(CGDisplayRotation(display_id))); diff --git a/chromium/ui/display/manager/BUILD.gn b/chromium/ui/display/manager/BUILD.gn index 49c4c8e27cb..c158f6586c8 100644 --- a/chromium/ui/display/manager/BUILD.gn +++ b/chromium/ui/display/manager/BUILD.gn @@ -15,6 +15,8 @@ jumbo_component("manager") { "display_manager_export.h", "display_manager_utilities.cc", "display_manager_utilities.h", + "display_util.cc", + "display_util.h", "json_converter.cc", "json_converter.h", "managed_display_info.cc", @@ -27,6 +29,8 @@ jumbo_component("manager") { "apply_content_protection_task.h", "configure_displays_task.cc", "configure_displays_task.h", + "content_protection_manager.cc", + "content_protection_manager.h", "default_touch_transform_setter.cc", "default_touch_transform_setter.h", "display_change_observer.cc", @@ -34,8 +38,6 @@ jumbo_component("manager") { "display_configurator.cc", "display_configurator.h", "display_layout_manager.h", - "display_util.cc", - "display_util.h", "query_content_protection_task.cc", "query_content_protection_task.h", "touch_device_manager.cc", @@ -57,7 +59,7 @@ jumbo_component("manager") { deps = [ "//base", "//ui/base", - "//ui/display/mojo:interfaces", + "//ui/display/mojom:mojom", "//ui/display/util", "//ui/events:platform_event", "//ui/events/devices", diff --git a/chromium/ui/display/manager/DEPS b/chromium/ui/display/manager/DEPS index c75536d94a5..c4cefa3507c 100644 --- a/chromium/ui/display/manager/DEPS +++ b/chromium/ui/display/manager/DEPS @@ -5,18 +5,4 @@ include_rules = [ "+ui/events/devices", "+ui/events/platform_event.h", "+ui/strings", - # DeviceDataManager is not created in all environments (such as ash when - # running in mus/mash). - "-ui/events/devices/device_data_manager.h", ] - -specific_include_rules = { - "default_touch_transform_setter.cc": [ - # DefaultTouchTransformSetter only runs in environments where - # DeviceDataManager exists. - "+ui/events/devices/device_data_manager.h", - ], - "touch_transform_controller_unittest.cc": [ - "+ui/events/devices/device_data_manager.h", - ], -} diff --git a/chromium/ui/display/manager/apply_content_protection_task.cc b/chromium/ui/display/manager/apply_content_protection_task.cc index 43ad7ff8647..71eac64ebc9 100644 --- a/chromium/ui/display/manager/apply_content_protection_task.cc +++ b/chromium/ui/display/manager/apply_content_protection_task.cc @@ -18,7 +18,7 @@ namespace display { ApplyContentProtectionTask::ApplyContentProtectionTask( DisplayLayoutManager* layout_manager, NativeDisplayDelegate* native_display_delegate, - DisplayConfigurator::ContentProtections requests, + ContentProtectionManager::ContentProtections requests, ResponseCallback callback) : layout_manager_(layout_manager), native_display_delegate_(native_display_delegate), diff --git a/chromium/ui/display/manager/apply_content_protection_task.h b/chromium/ui/display/manager/apply_content_protection_task.h index 89bcabf0f1c..7be81c11f86 100644 --- a/chromium/ui/display/manager/apply_content_protection_task.h +++ b/chromium/ui/display/manager/apply_content_protection_task.h @@ -11,7 +11,8 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" -#include "ui/display/manager/display_configurator.h" +#include "ui/display/manager/content_protection_manager.h" +#include "ui/display/types/display_constants.h" namespace display { @@ -19,16 +20,17 @@ class DisplayLayoutManager; class NativeDisplayDelegate; class DISPLAY_MANAGER_EXPORT ApplyContentProtectionTask - : public DisplayConfigurator::ContentProtectionTask { + : public ContentProtectionManager::Task { public: using ResponseCallback = base::OnceCallback<void(Status)>; // The task disables protection on displays omitted from |requests|. Note that // pending tasks are killed on display reconfiguration. - ApplyContentProtectionTask(DisplayLayoutManager* layout_manager, - NativeDisplayDelegate* native_display_delegate, - DisplayConfigurator::ContentProtections requests, - ResponseCallback callback); + ApplyContentProtectionTask( + DisplayLayoutManager* layout_manager, + NativeDisplayDelegate* native_display_delegate, + ContentProtectionManager::ContentProtections requests, + ResponseCallback callback); ~ApplyContentProtectionTask() override; void Run() override; @@ -42,7 +44,7 @@ class DISPLAY_MANAGER_EXPORT ApplyContentProtectionTask DisplayLayoutManager* const layout_manager_; // Not owned. NativeDisplayDelegate* const native_display_delegate_; // Not owned. - const DisplayConfigurator::ContentProtections requests_; + const ContentProtectionManager::ContentProtections requests_; ResponseCallback callback_; std::vector<std::pair<DisplaySnapshot*, HDCPState>> hdcp_requests_; diff --git a/chromium/ui/display/manager/apply_content_protection_task_unittest.cc b/chromium/ui/display/manager/apply_content_protection_task_unittest.cc index a179ada443e..ec7494cd9fe 100644 --- a/chromium/ui/display/manager/apply_content_protection_task_unittest.cc +++ b/chromium/ui/display/manager/apply_content_protection_task_unittest.cc @@ -60,7 +60,7 @@ TEST_F(ApplyContentProtectionTaskTest, ApplyHdcpToInternalDisplay) { TestDisplayLayoutManager layout_manager(std::move(displays), MULTIPLE_DISPLAY_STATE_SINGLE); - DisplayConfigurator::ContentProtections request; + ContentProtectionManager::ContentProtections request; request[1] = CONTENT_PROTECTION_METHOD_HDCP; ApplyContentProtectionTask task( &layout_manager, &display_delegate_, request, @@ -78,7 +78,7 @@ TEST_F(ApplyContentProtectionTaskTest, ApplyHdcpToExternalDisplay) { TestDisplayLayoutManager layout_manager(std::move(displays), MULTIPLE_DISPLAY_STATE_SINGLE); - DisplayConfigurator::ContentProtections request; + ContentProtectionManager::ContentProtections request; request[1] = CONTENT_PROTECTION_METHOD_HDCP; ApplyContentProtectionTask task( &layout_manager, &display_delegate_, request, @@ -97,7 +97,7 @@ TEST_F(ApplyContentProtectionTaskTest, ApplyHdcpToUnknownDisplay) { TestDisplayLayoutManager layout_manager(std::move(displays), MULTIPLE_DISPLAY_STATE_SINGLE); - DisplayConfigurator::ContentProtections request; + ContentProtectionManager::ContentProtections request; request[1] = CONTENT_PROTECTION_METHOD_HDCP; ApplyContentProtectionTask task( &layout_manager, &display_delegate_, request, @@ -116,7 +116,7 @@ TEST_F(ApplyContentProtectionTaskTest, ApplyHdcpToDisplayThatCannotGetHdcp) { MULTIPLE_DISPLAY_STATE_SINGLE); display_delegate_.set_get_hdcp_state_expectation(false); - DisplayConfigurator::ContentProtections request; + ContentProtectionManager::ContentProtections request; request[1] = CONTENT_PROTECTION_METHOD_HDCP; ApplyContentProtectionTask task( &layout_manager, &display_delegate_, request, @@ -135,7 +135,7 @@ TEST_F(ApplyContentProtectionTaskTest, ApplyHdcpToDisplayThatCannotSetHdcp) { MULTIPLE_DISPLAY_STATE_SINGLE); display_delegate_.set_set_hdcp_state_expectation(false); - DisplayConfigurator::ContentProtections request; + ContentProtectionManager::ContentProtections request; request[1] = CONTENT_PROTECTION_METHOD_HDCP; ApplyContentProtectionTask task( &layout_manager, &display_delegate_, request, @@ -155,7 +155,7 @@ TEST_F(ApplyContentProtectionTaskTest, ApplyNoProtectionToExternalDisplay) { MULTIPLE_DISPLAY_STATE_SINGLE); display_delegate_.set_hdcp_state(HDCP_STATE_UNDESIRED); - DisplayConfigurator::ContentProtections request; + ContentProtectionManager::ContentProtections request; request[1] = CONTENT_PROTECTION_METHOD_NONE; ApplyContentProtectionTask task( &layout_manager, &display_delegate_, request, diff --git a/chromium/ui/display/manager/configure_displays_task.cc b/chromium/ui/display/manager/configure_displays_task.cc index 6ef399ae5a8..6db286838a5 100644 --- a/chromium/ui/display/manager/configure_displays_task.cc +++ b/chromium/ui/display/manager/configure_displays_task.cc @@ -77,15 +77,9 @@ void ConfigureDisplaysTask::Run() { size_t index = pending_request_indexes_.front(); DisplayConfigureRequest* request = &requests_[index]; pending_request_indexes_.pop(); - // Non-native displays do not require configuration through the - // NativeDisplayDelegate. - if (!IsPhysicalDisplayType(request->display->type())) { - OnConfigured(index, true); - } else { - delegate_->Configure(*request->display, request->mode, request->origin, - base::Bind(&ConfigureDisplaysTask::OnConfigured, - weak_ptr_factory_.GetWeakPtr(), index)); - } + delegate_->Configure(*request->display, request->mode, request->origin, + base::Bind(&ConfigureDisplaysTask::OnConfigured, + weak_ptr_factory_.GetWeakPtr(), index)); } } diff --git a/chromium/ui/display/manager/configure_displays_task_unittest.cc b/chromium/ui/display/manager/configure_displays_task_unittest.cc index daa7423d5c2..b89205ceea8 100644 --- a/chromium/ui/display/manager/configure_displays_task_unittest.cc +++ b/chromium/ui/display/manager/configure_displays_task_unittest.cc @@ -5,9 +5,9 @@ #include <stddef.h> #include "base/bind.h" -#include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "base/stl_util.h" +#include "base/test/scoped_task_environment.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/display/fake/fake_display_snapshot.h" #include "ui/display/manager/configure_displays_task.h" @@ -48,7 +48,7 @@ class ConfigureDisplaysTaskTest : public testing::Test { } protected: - base::MessageLoop message_loop_; + base::test::ScopedTaskEnvironment scoped_task_environment_; ActionLogger log_; TestNativeDisplayDelegate delegate_; diff --git a/chromium/ui/display/manager/content_protection_manager.cc b/chromium/ui/display/manager/content_protection_manager.cc new file mode 100644 index 00000000000..986d9617d1b --- /dev/null +++ b/chromium/ui/display/manager/content_protection_manager.cc @@ -0,0 +1,302 @@ +// Copyright 2019 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 "ui/display/manager/content_protection_manager.h" + +#include <algorithm> +#include <utility> + +#include "base/logging.h" +#include "base/observer_list.h" +#include "base/stl_util.h" +#include "ui/display/manager/apply_content_protection_task.h" +#include "ui/display/manager/display_layout_manager.h" +#include "ui/display/manager/query_content_protection_task.h" +#include "ui/display/types/display_constants.h" +#include "ui/display/types/display_snapshot.h" + +namespace display { + +namespace { + +// HDCP requires suppressing content within 2 seconds when authentication drops. +constexpr auto kDisplaySecurityPollingPeriod = base::TimeDelta::FromSeconds(2); + +} // namespace + +ContentProtectionManager::ContentProtectionManager( + DisplayLayoutManager* layout_manager, + ConfigurationDisabledCallback config_disabled_callback) + : layout_manager_(layout_manager), + config_disabled_callback_(std::move(config_disabled_callback)) {} + +ContentProtectionManager::~ContentProtectionManager() { + // Destroy to fire failure callbacks before weak pointers for |this| expire. + tasks_ = {}; +} + +ContentProtectionManager::ClientId ContentProtectionManager::RegisterClient() { + if (disabled()) + return base::nullopt; + + ClientId client_id = next_client_id_++; + bool success = requests_.emplace(*client_id, ContentProtections()).second; + DCHECK(success); + + return client_id; +} + +void ContentProtectionManager::UnregisterClient(ClientId client_id) { + if (disabled()) + return; + + DCHECK(GetContentProtections(client_id)); + requests_.erase(*client_id); + + QueueTask(std::make_unique<ApplyContentProtectionTask>( + layout_manager_, native_display_delegate_, AggregateContentProtections(), + base::BindOnce(&ContentProtectionManager::OnContentProtectionApplied, + weak_ptr_factory_.GetWeakPtr(), + ApplyContentProtectionCallback(), base::nullopt))); + + ToggleDisplaySecurityPolling(); +} + +void ContentProtectionManager::AddObserver(Observer* observer) { + observers_.AddObserver(observer); + QueueDisplaySecurityQueries(); +} + +void ContentProtectionManager::RemoveObserver(Observer* observer) { + observers_.RemoveObserver(observer); +} + +void ContentProtectionManager::QueryContentProtection( + ClientId client_id, + int64_t display_id, + QueryContentProtectionCallback callback) { + DCHECK(disabled() || GetContentProtections(client_id)); + + if (disabled() || !GetDisplay(display_id)) { + std::move(callback).Run(/*success=*/false, DISPLAY_CONNECTION_TYPE_NONE, + CONTENT_PROTECTION_METHOD_NONE); + return; + } + + QueueTask(std::make_unique<QueryContentProtectionTask>( + layout_manager_, native_display_delegate_, display_id, + base::BindOnce(&ContentProtectionManager::OnContentProtectionQueried, + weak_ptr_factory_.GetWeakPtr(), std::move(callback), + client_id, display_id))); +} + +void ContentProtectionManager::ApplyContentProtection( + ClientId client_id, + int64_t display_id, + uint32_t protection_mask, + ApplyContentProtectionCallback callback) { + ContentProtections* protections = GetContentProtections(client_id); + DCHECK(disabled() || protections); + + if (disabled() || !GetDisplay(display_id)) { + std::move(callback).Run(/*success=*/false); + return; + } + + protections->insert_or_assign(display_id, protection_mask); + + QueueTask(std::make_unique<ApplyContentProtectionTask>( + layout_manager_, native_display_delegate_, AggregateContentProtections(), + base::BindOnce(&ContentProtectionManager::OnContentProtectionApplied, + weak_ptr_factory_.GetWeakPtr(), std::move(callback), + client_id))); + + ToggleDisplaySecurityPolling(); +} + +const DisplaySnapshot* ContentProtectionManager::GetDisplay( + int64_t display_id) const { + for (const DisplaySnapshot* display : layout_manager_->GetDisplayStates()) + if (display->display_id() == display_id) + return display; + + return nullptr; +} + +ContentProtectionManager::ContentProtections +ContentProtectionManager::AggregateContentProtections() const { + ContentProtections protections; + + for (const auto& requests_pair : requests_) + for (const auto& protections_pair : requests_pair.second) + protections[protections_pair.first] |= protections_pair.second; + + return protections; +} + +ContentProtectionManager::ContentProtections* +ContentProtectionManager::GetContentProtections(ClientId client_id) { + if (!client_id) + return nullptr; + + auto it = requests_.find(*client_id); + return it == requests_.end() ? nullptr : &it->second; +} + +void ContentProtectionManager::QueueTask(std::unique_ptr<Task> task) { + tasks_.emplace(std::move(task)); + + if (tasks_.size() == 1) + tasks_.front()->Run(); +} + +void ContentProtectionManager::DequeueTask() { + DCHECK(!tasks_.empty()); + tasks_.pop(); + + if (!tasks_.empty()) + tasks_.front()->Run(); +} + +void ContentProtectionManager::KillTasks() { + // Filter out content protection requests for removed displays. + for (auto& requests : requests_) { + base::EraseIf(requests.second, + [this](const auto& pair) { return !GetDisplay(pair.first); }); + } + + // Fire failure callbacks. + tasks_ = {}; + + ToggleDisplaySecurityPolling(); +} + +void ContentProtectionManager::OnContentProtectionQueried( + QueryContentProtectionCallback callback, + ClientId client_id, + int64_t display_id, + Task::Status status, + uint32_t connection_mask, + uint32_t protection_mask) { + // Only run callback if client is still registered. + if (const auto* protections = GetContentProtections(client_id)) { + bool success = status == Task::Status::SUCCESS; + + // Conceal protections requested by other clients. + uint32_t client_mask = CONTENT_PROTECTION_METHOD_NONE; + + if (success) { + auto it = protections->find(display_id); + if (it != protections->end()) + client_mask = it->second; + } + + protection_mask &= client_mask; + + std::move(callback).Run(success, connection_mask, protection_mask); + } + + if (status != Task::Status::KILLED) + DequeueTask(); +} + +void ContentProtectionManager::OnContentProtectionApplied( + ApplyContentProtectionCallback callback, + ClientId client_id, + Task::Status status) { + // Only run callback if client is still registered. + if (GetContentProtections(client_id)) + std::move(callback).Run(status == Task::Status::SUCCESS); + + if (status != Task::Status::KILLED) + DequeueTask(); +} + +void ContentProtectionManager::OnDisplayModeChanged( + const DisplayConfigurator::DisplayStateList&) { + KillTasks(); +} + +void ContentProtectionManager::OnDisplayModeChangeFailed( + const DisplayConfigurator::DisplayStateList&, + MultipleDisplayState) { + KillTasks(); +} + +bool ContentProtectionManager::ShouldPollDisplaySecurity() const { + const auto displays = layout_manager_->GetDisplayStates(); + if (std::all_of(displays.begin(), displays.end(), + [](const DisplaySnapshot* display) { + return display->type() == DISPLAY_CONNECTION_TYPE_INTERNAL; + })) { + return false; + } + + const auto protections = AggregateContentProtections(); + return std::any_of(protections.begin(), protections.end(), + [](const auto& pair) { + return pair.second != CONTENT_PROTECTION_METHOD_NONE; + }); +} + +void ContentProtectionManager::ToggleDisplaySecurityPolling() { + if (ShouldPollDisplaySecurity()) { + if (!security_timer_.IsRunning()) { + security_timer_.Start( + FROM_HERE, kDisplaySecurityPollingPeriod, + base::BindRepeating( + &ContentProtectionManager::QueueDisplaySecurityQueries, + weak_ptr_factory_.GetWeakPtr())); + } + } else { + security_timer_.Stop(); + + // Query once if polling was stopped or not started. The latter case happens + // when all displays are internal. + QueueDisplaySecurityQueries(); + } +} + +bool ContentProtectionManager::TriggerDisplaySecurityTimeoutForTesting() { + if (!security_timer_.IsRunning()) + return false; + + security_timer_.user_task().Run(); + return true; +} + +void ContentProtectionManager::QueueDisplaySecurityQueries() { + if (disabled()) + return; + + for (DisplaySnapshot* display : layout_manager_->GetDisplayStates()) { + int64_t display_id = display->display_id(); + + QueueTask(std::make_unique<QueryContentProtectionTask>( + layout_manager_, native_display_delegate_, display_id, + base::BindOnce(&ContentProtectionManager::OnDisplaySecurityQueried, + weak_ptr_factory_.GetWeakPtr(), display_id))); + } +} + +void ContentProtectionManager::OnDisplaySecurityQueried( + int64_t display_id, + Task::Status status, + uint32_t connection_mask, + uint32_t protection_mask) { + if (GetDisplay(display_id)) { + // Internal display is secure if not mirrored on unsecure external display. + const bool secure = status == Task::Status::SUCCESS && + (protection_mask != CONTENT_PROTECTION_METHOD_NONE || + connection_mask == DISPLAY_CONNECTION_TYPE_INTERNAL); + + for (Observer& observer : observers_) + observer.OnDisplaySecurityChanged(display_id, secure); + } + + if (status != Task::Status::KILLED) + DequeueTask(); +} + +} // namespace display diff --git a/chromium/ui/display/manager/content_protection_manager.h b/chromium/ui/display/manager/content_protection_manager.h new file mode 100644 index 00000000000..0d4af4cb378 --- /dev/null +++ b/chromium/ui/display/manager/content_protection_manager.h @@ -0,0 +1,187 @@ +// Copyright 2019 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 UI_DISPLAY_MANAGER_CONTENT_PROTECTION_MANAGER_H_ +#define UI_DISPLAY_MANAGER_CONTENT_PROTECTION_MANAGER_H_ + +#include <cstdint> +#include <memory> + +#include "base/callback.h" +#include "base/containers/flat_map.h" +#include "base/containers/queue.h" +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "base/observer_list.h" +#include "base/optional.h" +#include "base/timer/timer.h" +#include "ui/display/manager/display_configurator.h" +#include "ui/display/manager/display_manager_export.h" + +namespace display { + +class DisplayLayoutManager; +class DisplaySnapshot; +class NativeDisplayDelegate; + +namespace test { +class ContentProtectionManagerTest; +} // namespace test + +// Fulfills client requests to query and apply per-display content protection, +// and notifies observers of display security changes. Changes are detected by +// polling as required by the kernel API, since authentication latency depends +// on hardware topology, and the hardware may temporarily drop authentication, +// in which case the kernel automatically tries to re-establish protection. +class DISPLAY_MANAGER_EXPORT ContentProtectionManager + : public DisplayConfigurator::Observer { + public: + // |connection_mask| is a DisplayConnectionType bitmask, and |protection_mask| + // is a ContentProtectionMethod bitmask. + using QueryContentProtectionCallback = base::OnceCallback< + void(bool success, uint32_t connection_mask, uint32_t protection_mask)>; + using ApplyContentProtectionCallback = base::OnceCallback<void(bool success)>; + + using ContentProtections = + base::flat_map<int64_t /* display_id */, uint32_t /* protection_mask */>; + + // Though only run once, a task must outlive its asynchronous operations, so + // cannot be a OnceCallback. + struct Task { + enum class Status { KILLED, FAILURE, SUCCESS }; + + virtual ~Task() = default; + virtual void Run() = 0; + }; + + class Observer : public base::CheckedObserver { + public: + ~Observer() override = default; + + // Called after the secure state of a display has been changed. + virtual void OnDisplaySecurityChanged(int64_t display_id, bool secure) = 0; + }; + + // Returns whether display configuration is disabled, in which case API calls + // are no-ops resulting in failure callbacks. + using ConfigurationDisabledCallback = base::RepeatingCallback<bool()>; + + ContentProtectionManager(DisplayLayoutManager*, + ConfigurationDisabledCallback); + ~ContentProtectionManager() override; + + void set_native_display_delegate(NativeDisplayDelegate* delegate) { + native_display_delegate_ = delegate; + } + + using ClientId = base::Optional<uint64_t>; + + // On display reconfiguration, pending requests are cancelled, i.e. clients + // receive failure callbacks, and are responsible for renewing requests. If a + // client unregisters with pending requests, the callbacks are not run. + ClientId RegisterClient(); + void UnregisterClient(ClientId client_id); + + void AddObserver(Observer* observer); + void RemoveObserver(Observer* observer); + + // Queries protection against the client's latest request on the same display, + // i.e. the result is CONTENT_PROTECTION_METHOD_NONE unless the client has + // previously applied protection on that display, such that requests from + // other clients are concealed. + void QueryContentProtection(ClientId client_id, + int64_t display_id, + QueryContentProtectionCallback callback); + + // |protection_mask| is a ContentProtectionMethod bitmask. Callback success + // does not mean that protection is active, but merely that the request went + // through. The client must periodically query protection status until it no + // longer requires protection and applies CONTENT_PROTECTION_METHOD_NONE. If + // protection becomes temporarily unavailable, the client is not required to + // renew the request, but should keep querying to detect if automatic retries + // to establish protection are successful. + void ApplyContentProtection(ClientId client_id, + int64_t display_id, + uint32_t protection_mask, + ApplyContentProtectionCallback callback); + + private: + friend class test::ContentProtectionManagerTest; + + bool disabled() const { + return !native_display_delegate_ || config_disabled_callback_.Run(); + } + + const DisplaySnapshot* GetDisplay(int64_t display_id) const; + + // Returns cumulative content protections given all client requests. + ContentProtections AggregateContentProtections() const; + + // Returns content protections for |client_id|, or nullptr if invalid. + ContentProtections* GetContentProtections(ClientId client_id); + + void QueueTask(std::unique_ptr<Task> task); + void DequeueTask(); + void KillTasks(); + + // Called on task completion. Responsible for running the client callback, and + // dequeuing the next pending task. + void OnContentProtectionQueried(QueryContentProtectionCallback callback, + ClientId client_id, + int64_t display_id, + Task::Status status, + uint32_t connection_mask, + uint32_t protection_mask); + void OnContentProtectionApplied(ApplyContentProtectionCallback callback, + ClientId client_id, + Task::Status status); + + // DisplayConfigurator::Observer overrides: + void OnDisplayModeChanged( + const DisplayConfigurator::DisplayStateList&) override; + void OnDisplayModeChangeFailed(const DisplayConfigurator::DisplayStateList&, + MultipleDisplayState) override; + + bool ShouldPollDisplaySecurity() const; + + // Toggles timer for periodic security queries given latest client requests. + void ToggleDisplaySecurityPolling(); + + // Forces timer to fire if running, and returns whether it was running. + bool TriggerDisplaySecurityTimeoutForTesting(); + + // Queries protection status for all displays, and notifies observers whether + // each display is secure. Called periodically while protection is requested. + void QueueDisplaySecurityQueries(); + void OnDisplaySecurityQueried(int64_t display_id, + Task::Status status, + uint32_t connection_mask, + uint32_t protection_mask); + + DisplayLayoutManager* const layout_manager_; // Not owned. + NativeDisplayDelegate* native_display_delegate_ = nullptr; // Not owned. + + const ConfigurationDisabledCallback config_disabled_callback_; + + uint64_t next_client_id_ = 0; + + // Content protections requested by each client. + base::flat_map<uint64_t, ContentProtections> requests_; + + // Pending tasks to query or apply content protection. + base::queue<std::unique_ptr<Task>> tasks_; + + base::ObserverList<Observer> observers_; + + // Used for periodic queries to notify observers of display security changes. + base::RepeatingTimer security_timer_; + + base::WeakPtrFactory<ContentProtectionManager> weak_ptr_factory_{this}; + + DISALLOW_COPY_AND_ASSIGN(ContentProtectionManager); +}; + +} // namespace display + +#endif // UI_DISPLAY_MANAGER_CONTENT_PROTECTION_MANAGER_H_ diff --git a/chromium/ui/display/manager/content_protection_manager_unittest.cc b/chromium/ui/display/manager/content_protection_manager_unittest.cc new file mode 100644 index 00000000000..ee4c0fcbda3 --- /dev/null +++ b/chromium/ui/display/manager/content_protection_manager_unittest.cc @@ -0,0 +1,760 @@ +// Copyright 2019 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 "ui/display/manager/content_protection_manager.h" + +#include "base/containers/flat_map.h" +#include "base/message_loop/message_loop.h" +#include "base/run_loop.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/display/fake/fake_display_snapshot.h" +#include "ui/display/manager/test/action_logger_util.h" +#include "ui/display/manager/test/test_display_layout_manager.h" +#include "ui/display/manager/test/test_native_display_delegate.h" + +namespace display { +namespace test { + +namespace { + +constexpr int64_t kDisplayIds[] = {123, 456, 789}; +const DisplayMode kDisplayMode{gfx::Size(1366, 768), false, 60.0f}; + +} // namespace + +using SecurityChanges = base::flat_map<int64_t, bool>; + +class TestObserver : public ContentProtectionManager::Observer { + public: + explicit TestObserver(ContentProtectionManager* manager) : manager_(manager) { + manager_->AddObserver(this); + } + ~TestObserver() override { manager_->RemoveObserver(this); } + + const SecurityChanges& security_changes() const { return security_changes_; } + + void Reset() { security_changes_.clear(); } + + private: + void OnDisplaySecurityChanged(int64_t display_id, bool secure) override { + security_changes_.emplace(display_id, secure); + } + + ContentProtectionManager* const manager_; + SecurityChanges security_changes_; + + DISALLOW_COPY_AND_ASSIGN(TestObserver); +}; + +class ContentProtectionManagerTest : public testing::Test { + public: + ContentProtectionManagerTest() = default; + ~ContentProtectionManagerTest() override = default; + + void SetUp() override { + manager_.set_native_display_delegate(&native_display_delegate_); + + displays_[0] = FakeDisplaySnapshot::Builder() + .SetId(kDisplayIds[0]) + .SetType(DISPLAY_CONNECTION_TYPE_INTERNAL) + .SetCurrentMode(kDisplayMode.Clone()) + .Build(); + + displays_[1] = FakeDisplaySnapshot::Builder() + .SetId(kDisplayIds[1]) + .SetType(DISPLAY_CONNECTION_TYPE_HDMI) + .SetCurrentMode(kDisplayMode.Clone()) + .Build(); + + displays_[2] = FakeDisplaySnapshot::Builder() + .SetId(kDisplayIds[2]) + .SetType(DISPLAY_CONNECTION_TYPE_VGA) + .SetCurrentMode(kDisplayMode.Clone()) + .Build(); + + UpdateDisplays(2); + } + + void ApplyContentProtectionCallback(bool success) { + apply_content_protection_success_ = success; + apply_content_protection_call_count_++; + } + + void QueryContentProtectionCallback(bool success, + uint32_t connection_mask, + uint32_t protection_mask) { + query_content_protection_success_ = success; + query_content_protection_call_count_++; + + connection_mask_ = connection_mask; + protection_mask_ = protection_mask; + } + + protected: + void UpdateDisplays(size_t count) { + ASSERT_LE(count, base::size(displays_)); + + std::vector<std::unique_ptr<DisplaySnapshot>> displays; + for (size_t i = 0; i < count; ++i) + displays.push_back(displays_[i]->Clone()); + + layout_manager_.set_displays(std::move(displays)); + native_display_delegate_.set_outputs(layout_manager_.GetDisplayStates()); + } + + void TriggerDisplayConfiguration() { + manager_.OnDisplayModeChanged(layout_manager_.GetDisplayStates()); + } + + bool TriggerDisplaySecurityTimeout() { + return manager_.TriggerDisplaySecurityTimeoutForTesting(); + } + + base::MessageLoop message_loop_; + TestDisplayLayoutManager layout_manager_{{}, MULTIPLE_DISPLAY_STATE_INVALID}; + + ActionLogger log_; + TestNativeDisplayDelegate native_display_delegate_{&log_}; + + ContentProtectionManager manager_{&layout_manager_, + base::BindRepeating([] { return false; })}; + + bool apply_content_protection_success_ = false; + int apply_content_protection_call_count_ = 0; + + bool query_content_protection_success_ = false; + int query_content_protection_call_count_ = 0; + uint32_t connection_mask_ = DISPLAY_CONNECTION_TYPE_NONE; + uint32_t protection_mask_ = CONTENT_PROTECTION_METHOD_NONE; + + std::unique_ptr<DisplaySnapshot> displays_[3]; + + DISALLOW_COPY_AND_ASSIGN(ContentProtectionManagerTest); +}; + +TEST_F(ContentProtectionManagerTest, Basic) { + UpdateDisplays(1); + + auto id = manager_.RegisterClient(); + EXPECT_TRUE(id); + + manager_.QueryContentProtection( + id, displays_[0]->display_id(), + base::BindOnce( + &ContentProtectionManagerTest::QueryContentProtectionCallback, + base::Unretained(this))); + + EXPECT_EQ(1, query_content_protection_call_count_); + EXPECT_TRUE(query_content_protection_success_); + EXPECT_EQ(DISPLAY_CONNECTION_TYPE_INTERNAL, connection_mask_); + EXPECT_EQ(CONTENT_PROTECTION_METHOD_NONE, protection_mask_); + EXPECT_EQ(kNoActions, log_.GetActionsAndClear()); + + UpdateDisplays(2); + + manager_.QueryContentProtection( + id, displays_[1]->display_id(), + base::BindOnce( + &ContentProtectionManagerTest::QueryContentProtectionCallback, + base::Unretained(this))); + + EXPECT_EQ(2, query_content_protection_call_count_); + EXPECT_TRUE(query_content_protection_success_); + EXPECT_EQ(DISPLAY_CONNECTION_TYPE_HDMI, connection_mask_); + EXPECT_EQ(CONTENT_PROTECTION_METHOD_NONE, protection_mask_); + EXPECT_EQ(kNoActions, log_.GetActionsAndClear()); + + manager_.ApplyContentProtection( + id, displays_[1]->display_id(), CONTENT_PROTECTION_METHOD_HDCP, + base::BindOnce( + &ContentProtectionManagerTest::ApplyContentProtectionCallback, + base::Unretained(this))); + + EXPECT_EQ(1, apply_content_protection_call_count_); + EXPECT_TRUE(apply_content_protection_success_); + EXPECT_EQ(GetSetHDCPStateAction(kDisplayIds[1], HDCP_STATE_DESIRED), + log_.GetActionsAndClear()); + + EXPECT_EQ(HDCP_STATE_ENABLED, native_display_delegate_.hdcp_state()); + + manager_.QueryContentProtection( + id, displays_[1]->display_id(), + base::BindOnce( + &ContentProtectionManagerTest::QueryContentProtectionCallback, + base::Unretained(this))); + + EXPECT_EQ(3, query_content_protection_call_count_); + EXPECT_TRUE(query_content_protection_success_); + EXPECT_EQ(DISPLAY_CONNECTION_TYPE_HDMI, connection_mask_); + EXPECT_EQ(CONTENT_PROTECTION_METHOD_HDCP, protection_mask_); + EXPECT_EQ(kNoActions, log_.GetActionsAndClear()); + + // Requests on invalid display should fail. + constexpr int64_t kInvalidDisplayId = -999; + manager_.QueryContentProtection( + id, kInvalidDisplayId, + base::BindOnce( + &ContentProtectionManagerTest::QueryContentProtectionCallback, + base::Unretained(this))); + + manager_.ApplyContentProtection( + id, kInvalidDisplayId, CONTENT_PROTECTION_METHOD_HDCP, + base::BindOnce( + &ContentProtectionManagerTest::ApplyContentProtectionCallback, + base::Unretained(this))); + + EXPECT_EQ(4, query_content_protection_call_count_); + EXPECT_FALSE(query_content_protection_success_); + EXPECT_EQ(DISPLAY_CONNECTION_TYPE_NONE, connection_mask_); + EXPECT_EQ(CONTENT_PROTECTION_METHOD_NONE, protection_mask_); + + EXPECT_EQ(2, apply_content_protection_call_count_); + EXPECT_FALSE(apply_content_protection_success_); + + EXPECT_EQ(HDCP_STATE_ENABLED, native_display_delegate_.hdcp_state()); + + // Protections should be disabled after unregister. + manager_.UnregisterClient(id); + + EXPECT_EQ(GetSetHDCPStateAction(kDisplayIds[1], HDCP_STATE_UNDESIRED), + log_.GetActionsAndClear()); + EXPECT_EQ(HDCP_STATE_UNDESIRED, native_display_delegate_.hdcp_state()); +} + +TEST_F(ContentProtectionManagerTest, BasicAsync) { + auto id = manager_.RegisterClient(); + EXPECT_TRUE(id); + + native_display_delegate_.set_run_async(true); + + // Asynchronous tasks should be pending. + constexpr int kTaskCount = 3; + for (int i = 0; i < kTaskCount; ++i) { + manager_.ApplyContentProtection( + id, displays_[1]->display_id(), CONTENT_PROTECTION_METHOD_HDCP, + base::BindOnce( + &ContentProtectionManagerTest::ApplyContentProtectionCallback, + base::Unretained(this))); + + manager_.QueryContentProtection( + id, displays_[1]->display_id(), + base::BindOnce( + &ContentProtectionManagerTest::QueryContentProtectionCallback, + base::Unretained(this))); + } + + EXPECT_EQ(0, apply_content_protection_call_count_); + EXPECT_EQ(0, query_content_protection_call_count_); + EXPECT_EQ(kNoActions, log_.GetActionsAndClear()); + EXPECT_EQ(HDCP_STATE_UNDESIRED, native_display_delegate_.hdcp_state()); + + base::RunLoop().RunUntilIdle(); + + EXPECT_EQ(kTaskCount, apply_content_protection_call_count_); + EXPECT_TRUE(apply_content_protection_success_); + + EXPECT_EQ(kTaskCount, query_content_protection_call_count_); + EXPECT_TRUE(query_content_protection_success_); + EXPECT_EQ(DISPLAY_CONNECTION_TYPE_HDMI, connection_mask_); + EXPECT_EQ(CONTENT_PROTECTION_METHOD_HDCP, protection_mask_); + + EXPECT_EQ(GetSetHDCPStateAction(kDisplayIds[1], HDCP_STATE_DESIRED), + log_.GetActionsAndClear()); + EXPECT_EQ(HDCP_STATE_ENABLED, native_display_delegate_.hdcp_state()); + + // Pending task should run even if previous task fails. + native_display_delegate_.set_set_hdcp_state_expectation(false); + + manager_.ApplyContentProtection( + id, displays_[1]->display_id(), CONTENT_PROTECTION_METHOD_NONE, + base::BindOnce( + &ContentProtectionManagerTest::ApplyContentProtectionCallback, + base::Unretained(this))); + + manager_.QueryContentProtection( + id, displays_[1]->display_id(), + base::BindOnce( + &ContentProtectionManagerTest::QueryContentProtectionCallback, + base::Unretained(this))); + + EXPECT_EQ(kTaskCount, apply_content_protection_call_count_); + EXPECT_EQ(kTaskCount, query_content_protection_call_count_); + + base::RunLoop().RunUntilIdle(); + + EXPECT_EQ(kTaskCount + 1, apply_content_protection_call_count_); + EXPECT_FALSE(apply_content_protection_success_); + + EXPECT_EQ(kTaskCount + 1, query_content_protection_call_count_); + EXPECT_TRUE(query_content_protection_success_); + EXPECT_EQ(DISPLAY_CONNECTION_TYPE_HDMI, connection_mask_); + EXPECT_EQ(CONTENT_PROTECTION_METHOD_NONE, protection_mask_); + + // Disabling protection should fail. + EXPECT_EQ(GetSetHDCPStateAction(kDisplayIds[1], HDCP_STATE_UNDESIRED), + log_.GetActionsAndClear()); + EXPECT_EQ(HDCP_STATE_ENABLED, native_display_delegate_.hdcp_state()); +} + +TEST_F(ContentProtectionManagerTest, TwoClients) { + auto client1 = manager_.RegisterClient(); + auto client2 = manager_.RegisterClient(); + EXPECT_NE(client1, client2); + + // Clients should not be aware of requests from other clients. + manager_.ApplyContentProtection( + client1, displays_[1]->display_id(), CONTENT_PROTECTION_METHOD_HDCP, + base::BindOnce( + &ContentProtectionManagerTest::ApplyContentProtectionCallback, + base::Unretained(this))); + + EXPECT_EQ(1, apply_content_protection_call_count_); + EXPECT_TRUE(apply_content_protection_success_); + + EXPECT_EQ(GetSetHDCPStateAction(kDisplayIds[1], HDCP_STATE_DESIRED), + log_.GetActionsAndClear()); + EXPECT_EQ(HDCP_STATE_ENABLED, native_display_delegate_.hdcp_state()); + + manager_.QueryContentProtection( + client1, displays_[1]->display_id(), + base::BindOnce( + &ContentProtectionManagerTest::QueryContentProtectionCallback, + base::Unretained(this))); + + EXPECT_EQ(1, query_content_protection_call_count_); + EXPECT_TRUE(query_content_protection_success_); + EXPECT_EQ(DISPLAY_CONNECTION_TYPE_HDMI, connection_mask_); + EXPECT_EQ(CONTENT_PROTECTION_METHOD_HDCP, protection_mask_); + + manager_.QueryContentProtection( + client2, displays_[1]->display_id(), + base::BindOnce( + &ContentProtectionManagerTest::QueryContentProtectionCallback, + base::Unretained(this))); + + EXPECT_EQ(2, query_content_protection_call_count_); + EXPECT_TRUE(query_content_protection_success_); + EXPECT_EQ(DISPLAY_CONNECTION_TYPE_HDMI, connection_mask_); + EXPECT_EQ(CONTENT_PROTECTION_METHOD_NONE, protection_mask_); + + // Protection should be disabled if there are no client requests. + manager_.ApplyContentProtection( + client2, displays_[1]->display_id(), CONTENT_PROTECTION_METHOD_NONE, + base::BindOnce( + &ContentProtectionManagerTest::ApplyContentProtectionCallback, + base::Unretained(this))); + + EXPECT_EQ(2, apply_content_protection_call_count_); + EXPECT_TRUE(apply_content_protection_success_); + + EXPECT_EQ(kNoActions, log_.GetActionsAndClear()); + EXPECT_EQ(HDCP_STATE_ENABLED, native_display_delegate_.hdcp_state()); + + manager_.ApplyContentProtection( + client1, displays_[1]->display_id(), CONTENT_PROTECTION_METHOD_NONE, + base::BindOnce( + &ContentProtectionManagerTest::ApplyContentProtectionCallback, + base::Unretained(this))); + + EXPECT_EQ(3, apply_content_protection_call_count_); + EXPECT_TRUE(apply_content_protection_success_); + + EXPECT_EQ(GetSetHDCPStateAction(kDisplayIds[1], HDCP_STATE_UNDESIRED), + log_.GetActionsAndClear()); + EXPECT_EQ(HDCP_STATE_UNDESIRED, native_display_delegate_.hdcp_state()); +} + +TEST_F(ContentProtectionManagerTest, TwoClientsEnable) { + auto client1 = manager_.RegisterClient(); + auto client2 = manager_.RegisterClient(); + EXPECT_NE(client1, client2); + + // Multiple requests should result in one update. + manager_.ApplyContentProtection( + client1, displays_[1]->display_id(), CONTENT_PROTECTION_METHOD_HDCP, + base::BindOnce( + &ContentProtectionManagerTest::ApplyContentProtectionCallback, + base::Unretained(this))); + + EXPECT_EQ(1, apply_content_protection_call_count_); + EXPECT_TRUE(apply_content_protection_success_); + + manager_.ApplyContentProtection( + client2, displays_[1]->display_id(), CONTENT_PROTECTION_METHOD_HDCP, + base::BindOnce( + &ContentProtectionManagerTest::ApplyContentProtectionCallback, + base::Unretained(this))); + + EXPECT_EQ(2, apply_content_protection_call_count_); + EXPECT_TRUE(apply_content_protection_success_); + + EXPECT_EQ(GetSetHDCPStateAction(kDisplayIds[1], HDCP_STATE_DESIRED), + log_.GetActionsAndClear()); + EXPECT_EQ(HDCP_STATE_ENABLED, native_display_delegate_.hdcp_state()); + + // Requests should not result in updates if protection is already active. + manager_.ApplyContentProtection( + client1, displays_[1]->display_id(), CONTENT_PROTECTION_METHOD_HDCP, + base::BindOnce( + &ContentProtectionManagerTest::ApplyContentProtectionCallback, + base::Unretained(this))); + + EXPECT_EQ(3, apply_content_protection_call_count_); + EXPECT_TRUE(apply_content_protection_success_); + + manager_.ApplyContentProtection( + client2, displays_[1]->display_id(), CONTENT_PROTECTION_METHOD_HDCP, + base::BindOnce( + &ContentProtectionManagerTest::ApplyContentProtectionCallback, + base::Unretained(this))); + + EXPECT_EQ(4, apply_content_protection_call_count_); + EXPECT_TRUE(apply_content_protection_success_); + + EXPECT_EQ(kNoActions, log_.GetActionsAndClear()); + EXPECT_EQ(HDCP_STATE_ENABLED, native_display_delegate_.hdcp_state()); +} + +TEST_F(ContentProtectionManagerTest, RequestRetention) { + auto id = manager_.RegisterClient(); + EXPECT_TRUE(id); + + native_display_delegate_.set_run_async(true); + + // Enable protection on external display. + manager_.ApplyContentProtection( + id, displays_[1]->display_id(), CONTENT_PROTECTION_METHOD_HDCP, + base::BindOnce( + &ContentProtectionManagerTest::ApplyContentProtectionCallback, + base::Unretained(this))); + + // Disable protection on internal display. + manager_.ApplyContentProtection( + id, displays_[0]->display_id(), CONTENT_PROTECTION_METHOD_NONE, + base::BindOnce( + &ContentProtectionManagerTest::ApplyContentProtectionCallback, + base::Unretained(this))); + + EXPECT_EQ(0, apply_content_protection_call_count_); + EXPECT_EQ(kNoActions, log_.GetActionsAndClear()); + EXPECT_EQ(HDCP_STATE_UNDESIRED, native_display_delegate_.hdcp_state()); + + base::RunLoop().RunUntilIdle(); + + EXPECT_EQ(2, apply_content_protection_call_count_); + EXPECT_TRUE(apply_content_protection_success_); + + // Protection on external display should be retained. + EXPECT_EQ(GetSetHDCPStateAction(kDisplayIds[1], HDCP_STATE_DESIRED).c_str(), + log_.GetActionsAndClear()); + EXPECT_EQ(HDCP_STATE_ENABLED, native_display_delegate_.hdcp_state()); +} + +TEST_F(ContentProtectionManagerTest, ClientRegistration) { + auto id = manager_.RegisterClient(); + EXPECT_TRUE(id); + + native_display_delegate_.set_run_async(true); + + manager_.ApplyContentProtection( + id, displays_[1]->display_id(), CONTENT_PROTECTION_METHOD_HDCP, + base::BindOnce( + &ContentProtectionManagerTest::ApplyContentProtectionCallback, + base::Unretained(this))); + + manager_.QueryContentProtection( + id, displays_[1]->display_id(), + base::BindOnce( + &ContentProtectionManagerTest::QueryContentProtectionCallback, + base::Unretained(this))); + + manager_.UnregisterClient(id); + + base::RunLoop().RunUntilIdle(); + + // Pending callbacks should not run if client was unregistered. + EXPECT_EQ(0, apply_content_protection_call_count_); + EXPECT_EQ(0, query_content_protection_call_count_); + + // Unregistration should disable protection. + EXPECT_EQ( + JoinActions( + GetSetHDCPStateAction(kDisplayIds[1], HDCP_STATE_DESIRED).c_str(), + GetSetHDCPStateAction(kDisplayIds[1], HDCP_STATE_UNDESIRED).c_str(), + nullptr), + log_.GetActionsAndClear()); + EXPECT_EQ(HDCP_STATE_UNDESIRED, native_display_delegate_.hdcp_state()); +} + +TEST_F(ContentProtectionManagerTest, TasksKilledOnConfigure) { + auto id = manager_.RegisterClient(); + EXPECT_TRUE(id); + + native_display_delegate_.set_run_async(true); + + manager_.ApplyContentProtection( + id, displays_[1]->display_id(), CONTENT_PROTECTION_METHOD_HDCP, + base::BindOnce( + &ContentProtectionManagerTest::ApplyContentProtectionCallback, + base::Unretained(this))); + + manager_.QueryContentProtection( + id, displays_[1]->display_id(), + base::BindOnce( + &ContentProtectionManagerTest::QueryContentProtectionCallback, + base::Unretained(this))); + + TriggerDisplayConfiguration(); + base::RunLoop().RunUntilIdle(); + + // Configuration change should kill tasks and trigger failure callbacks. + EXPECT_EQ(1, apply_content_protection_call_count_); + EXPECT_FALSE(apply_content_protection_success_); + + EXPECT_EQ(1, query_content_protection_call_count_); + EXPECT_FALSE(query_content_protection_success_); + EXPECT_EQ(DISPLAY_CONNECTION_TYPE_NONE, connection_mask_); + EXPECT_EQ(CONTENT_PROTECTION_METHOD_NONE, protection_mask_); + + // Pending task to enable protection should have been killed. + EXPECT_EQ(kNoActions, log_.GetActionsAndClear()); + EXPECT_EQ(HDCP_STATE_UNDESIRED, native_display_delegate_.hdcp_state()); +} + +TEST_F(ContentProtectionManagerTest, DisplaySecurityObserver) { + TestObserver observer(&manager_); + + // Internal display is secure if not mirroring. + EXPECT_EQ(SecurityChanges({{kDisplayIds[0], true}, {kDisplayIds[1], false}}), + observer.security_changes()); + observer.Reset(); + + auto id = manager_.RegisterClient(); + EXPECT_TRUE(id); + + native_display_delegate_.set_run_async(true); + + manager_.ApplyContentProtection( + id, kDisplayIds[1], CONTENT_PROTECTION_METHOD_HDCP, + base::BindOnce( + &ContentProtectionManagerTest::ApplyContentProtectionCallback, + base::Unretained(this))); + + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(observer.security_changes().empty()); + + EXPECT_TRUE(TriggerDisplaySecurityTimeout()); + base::RunLoop().RunUntilIdle(); + + // Observer should be notified when client applies protection. + EXPECT_EQ(SecurityChanges({{kDisplayIds[0], true}, {kDisplayIds[1], true}}), + observer.security_changes()); + observer.Reset(); + + layout_manager_.set_display_state(MULTIPLE_DISPLAY_STATE_MULTI_MIRROR); + TriggerDisplayConfiguration(); + base::RunLoop().RunUntilIdle(); + + EXPECT_TRUE(TriggerDisplaySecurityTimeout()); + base::RunLoop().RunUntilIdle(); + + // Observer should be notified on configuration change. + EXPECT_EQ(SecurityChanges({{kDisplayIds[0], true}, {kDisplayIds[1], true}}), + observer.security_changes()); + observer.Reset(); + + manager_.ApplyContentProtection( + id, kDisplayIds[1], CONTENT_PROTECTION_METHOD_NONE, + base::BindOnce( + &ContentProtectionManagerTest::ApplyContentProtectionCallback, + base::Unretained(this))); + + // Timer should be stopped when no client requests protection. + EXPECT_FALSE(TriggerDisplaySecurityTimeout()); + base::RunLoop().RunUntilIdle(); + + // Internal display is not secure if mirrored to an unprotected display. + EXPECT_EQ(SecurityChanges({{kDisplayIds[0], false}, {kDisplayIds[1], false}}), + observer.security_changes()); + observer.Reset(); + + native_display_delegate_.set_set_hdcp_state_expectation(false); + + manager_.ApplyContentProtection( + id, kDisplayIds[1], CONTENT_PROTECTION_METHOD_HDCP, + base::BindOnce( + &ContentProtectionManagerTest::ApplyContentProtectionCallback, + base::Unretained(this))); + + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(observer.security_changes().empty()); + + EXPECT_TRUE(TriggerDisplaySecurityTimeout()); + base::RunLoop().RunUntilIdle(); + + // Internal display is not secure if mirrored to an unprotected display. + EXPECT_EQ(SecurityChanges({{kDisplayIds[0], false}, {kDisplayIds[1], false}}), + observer.security_changes()); + observer.Reset(); + + native_display_delegate_.set_hdcp_state(HDCP_STATE_UNDESIRED); + native_display_delegate_.set_set_hdcp_state_expectation(true); + + manager_.ApplyContentProtection( + id, kDisplayIds[1], CONTENT_PROTECTION_METHOD_HDCP, + base::BindOnce( + &ContentProtectionManagerTest::ApplyContentProtectionCallback, + base::Unretained(this))); + + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(observer.security_changes().empty()); + + EXPECT_TRUE(TriggerDisplaySecurityTimeout()); + base::RunLoop().RunUntilIdle(); + + // Internal display is secure if mirrored to a protected display. + EXPECT_EQ(SecurityChanges({{kDisplayIds[0], true}, {kDisplayIds[1], true}}), + observer.security_changes()); + observer.Reset(); + + layout_manager_.set_display_state(MULTIPLE_DISPLAY_STATE_MULTI_EXTENDED); + TriggerDisplayConfiguration(); + base::RunLoop().RunUntilIdle(); + + EXPECT_TRUE(TriggerDisplaySecurityTimeout()); + base::RunLoop().RunUntilIdle(); + + // Observer should be notified on configuration change. + EXPECT_EQ(SecurityChanges({{kDisplayIds[0], true}, {kDisplayIds[1], true}}), + observer.security_changes()); + observer.Reset(); + + manager_.UnregisterClient(id); + + // Timer should be stopped when no client requests protection. + EXPECT_FALSE(TriggerDisplaySecurityTimeout()); + base::RunLoop().RunUntilIdle(); + + // Observer should be notified when client unregisters. + EXPECT_EQ(SecurityChanges({{kDisplayIds[0], true}, {kDisplayIds[1], false}}), + observer.security_changes()); +} + +TEST_F(ContentProtectionManagerTest, NoSecurityPollingIfInternalDisplayOnly) { + UpdateDisplays(1); + TestObserver observer(&manager_); + + EXPECT_EQ(SecurityChanges({{kDisplayIds[0], true}}), + observer.security_changes()); + observer.Reset(); + + auto id = manager_.RegisterClient(); + EXPECT_TRUE(id); + + native_display_delegate_.set_run_async(true); + + manager_.ApplyContentProtection( + id, kDisplayIds[0], CONTENT_PROTECTION_METHOD_HDCP, + base::BindOnce( + &ContentProtectionManagerTest::ApplyContentProtectionCallback, + base::Unretained(this))); + + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(SecurityChanges({{kDisplayIds[0], true}}), + observer.security_changes()); + observer.Reset(); + + // Timer should not be running unless there are external displays. + EXPECT_FALSE(TriggerDisplaySecurityTimeout()); + base::RunLoop().RunUntilIdle(); + + EXPECT_EQ(SecurityChanges(), observer.security_changes()); + + manager_.UnregisterClient(id); + + EXPECT_FALSE(TriggerDisplaySecurityTimeout()); + base::RunLoop().RunUntilIdle(); + + EXPECT_EQ(SecurityChanges({{kDisplayIds[0], true}}), + observer.security_changes()); +} + +TEST_F(ContentProtectionManagerTest, AnalogDisplaySecurity) { + UpdateDisplays(3); + TestObserver observer(&manager_); + + EXPECT_EQ(SecurityChanges({{kDisplayIds[0], true}, + {kDisplayIds[1], false}, + {kDisplayIds[2], false}}), + observer.security_changes()); + observer.Reset(); + + auto id = manager_.RegisterClient(); + EXPECT_TRUE(id); + + native_display_delegate_.set_run_async(true); + + for (int64_t display_id : kDisplayIds) { + manager_.ApplyContentProtection( + id, display_id, CONTENT_PROTECTION_METHOD_HDCP, + base::BindOnce( + &ContentProtectionManagerTest::ApplyContentProtectionCallback, + base::Unretained(this))); + } + + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(observer.security_changes().empty()); + + EXPECT_TRUE(TriggerDisplaySecurityTimeout()); + base::RunLoop().RunUntilIdle(); + + // Analog display is never secure. + EXPECT_EQ(SecurityChanges({{kDisplayIds[0], true}, + {kDisplayIds[1], true}, + {kDisplayIds[2], false}}), + observer.security_changes()); + observer.Reset(); + + layout_manager_.set_display_state(MULTIPLE_DISPLAY_STATE_MULTI_MIRROR); + TriggerDisplayConfiguration(); + base::RunLoop().RunUntilIdle(); + + EXPECT_TRUE(TriggerDisplaySecurityTimeout()); + base::RunLoop().RunUntilIdle(); + + // Internal display is not secure if mirrored to an analog display. + EXPECT_EQ(SecurityChanges({{kDisplayIds[0], false}, + {kDisplayIds[1], false}, + {kDisplayIds[2], false}}), + observer.security_changes()); + observer.Reset(); + + layout_manager_.set_display_state(MULTIPLE_DISPLAY_STATE_MULTI_EXTENDED); + TriggerDisplayConfiguration(); + base::RunLoop().RunUntilIdle(); + + EXPECT_TRUE(TriggerDisplaySecurityTimeout()); + base::RunLoop().RunUntilIdle(); + + EXPECT_EQ(SecurityChanges({{kDisplayIds[0], true}, + {kDisplayIds[1], true}, + {kDisplayIds[2], false}}), + observer.security_changes()); + observer.Reset(); + + manager_.UnregisterClient(id); + + // Timer should be stopped when no client requests protection. + EXPECT_FALSE(TriggerDisplaySecurityTimeout()); + base::RunLoop().RunUntilIdle(); + + // Observer should be notified when client unregisters. + EXPECT_EQ(SecurityChanges({{kDisplayIds[0], true}, + {kDisplayIds[1], false}, + {kDisplayIds[2], false}}), + observer.security_changes()); +} + +} // namespace test +} // namespace display diff --git a/chromium/ui/display/manager/display_change_observer.cc b/chromium/ui/display/manager/display_change_observer.cc index 11445d49d7e..dd961135871 100644 --- a/chromium/ui/display/manager/display_change_observer.cc +++ b/chromium/ui/display/manager/display_change_observer.cc @@ -28,7 +28,7 @@ #include "ui/display/types/display_snapshot.h" #include "ui/display/util/display_util.h" #include "ui/display/util/edid_parser.h" -#include "ui/events/devices/input_device_manager.h" +#include "ui/events/devices/device_data_manager.h" #include "ui/events/devices/touchscreen_device.h" #include "ui/strings/grit/ui_strings.h" @@ -161,11 +161,11 @@ DisplayChangeObserver::GetExternalManagedDisplayModeList( DisplayChangeObserver::DisplayChangeObserver(DisplayManager* display_manager) : display_manager_(display_manager) { - ui::InputDeviceManager::GetInstance()->AddObserver(this); + ui::DeviceDataManager::GetInstance()->AddObserver(this); } DisplayChangeObserver::~DisplayChangeObserver() { - ui::InputDeviceManager::GetInstance()->RemoveObserver(this); + ui::DeviceDataManager::GetInstance()->RemoveObserver(this); } MultipleDisplayState DisplayChangeObserver::GetStateForDisplayIds( @@ -203,8 +203,7 @@ void DisplayChangeObserver::OnDisplayModeChanged( } display_manager_->touch_device_manager()->AssociateTouchscreens( - &displays, - ui::InputDeviceManager::GetInstance()->GetTouchscreenDevices()); + &displays, ui::DeviceDataManager::GetInstance()->GetTouchscreenDevices()); display_manager_->OnNativeDisplaysChanged(displays); // For the purposes of user activity detection, ignore synthetic mouse events diff --git a/chromium/ui/display/manager/display_configurator.cc b/chromium/ui/display/manager/display_configurator.cc index 99e4310663a..8a72cfec562 100644 --- a/chromium/ui/display/manager/display_configurator.cc +++ b/chromium/ui/display/manager/display_configurator.cc @@ -4,7 +4,6 @@ #include "ui/display/manager/display_configurator.h" -#include <algorithm> #include <cstddef> #include <utility> @@ -13,17 +12,15 @@ #include "base/command_line.h" #include "base/logging.h" #include "base/macros.h" -#include "base/stl_util.h" #include "base/time/time.h" #include "chromeos/system/devicemode.h" #include "ui/display/display.h" #include "ui/display/display_features.h" #include "ui/display/display_switches.h" -#include "ui/display/manager/apply_content_protection_task.h" +#include "ui/display/manager/content_protection_manager.h" #include "ui/display/manager/display_layout_manager.h" #include "ui/display/manager/display_util.h" #include "ui/display/manager/managed_display_info.h" -#include "ui/display/manager/query_content_protection_task.h" #include "ui/display/manager/update_display_configuration_task.h" #include "ui/display/types/display_mode.h" #include "ui/display/types/display_snapshot.h" @@ -580,18 +577,23 @@ DisplayConfigurator::DisplayConfigurator() display_control_changing_(false), displays_suspended_(false), layout_manager_(new DisplayLayoutManagerImpl(this)), + content_protection_manager_(new ContentProtectionManager( + layout_manager_.get(), + base::BindRepeating(&DisplayConfigurator::configurator_disabled, + base::Unretained(this)))), has_unassociated_display_(false), - weak_ptr_factory_(this) {} + weak_ptr_factory_(this) { + AddObserver(content_protection_manager_.get()); +} DisplayConfigurator::~DisplayConfigurator() { + RemoveObserver(content_protection_manager_.get()); + if (native_display_delegate_) native_display_delegate_->RemoveObserver(this); CallAndClearInProgressCallbacks(false); CallAndClearQueuedCallbacks(false); - - // Destroy to fire failure callbacks before weak pointers for |this| expire. - content_protection_tasks_ = {}; } void DisplayConfigurator::SetDelegateForTesting( @@ -642,6 +644,9 @@ void DisplayConfigurator::Init( native_display_delegate_ = std::move(display_delegate); native_display_delegate_->AddObserver(this); + + content_protection_manager_->set_native_display_delegate( + native_display_delegate_.get()); } void DisplayConfigurator::TakeControl(DisplayControlCallback callback) { @@ -754,160 +759,6 @@ void DisplayConfigurator::ForceInitialConfigure() { configuration_task_->Run(); } -DisplayConfigurator::ContentProtectionClientId -DisplayConfigurator::RegisterContentProtectionClient() { - if (configurator_disabled()) - return base::nullopt; - - ContentProtectionClientId client_id = next_content_protection_client_id_++; - bool success = - content_protection_requests_.emplace(*client_id, ContentProtections()) - .second; - DCHECK(success); - - return client_id; -} - -void DisplayConfigurator::UnregisterContentProtectionClient( - ContentProtectionClientId client_id) { - if (configurator_disabled()) - return; - - DCHECK(GetContentProtections(client_id)); - content_protection_requests_.erase(*client_id); - - QueueContentProtectionTask(std::make_unique<ApplyContentProtectionTask>( - layout_manager_.get(), native_display_delegate_.get(), - AggregateContentProtections(), - base::BindOnce(&DisplayConfigurator::OnContentProtectionApplied, - weak_ptr_factory_.GetWeakPtr(), - ApplyContentProtectionCallback(), base::nullopt))); -} - -void DisplayConfigurator::QueryContentProtection( - ContentProtectionClientId client_id, - int64_t display_id, - QueryContentProtectionCallback callback) { - DCHECK(configurator_disabled() || GetContentProtections(client_id)); - - // Exclude virtual displays so that protected content will not be recaptured - // through the cast stream. - const DisplaySnapshot* display = GetDisplay(display_id); - if (configurator_disabled() || !display || - !IsPhysicalDisplayType(display->type())) { - std::move(callback).Run(/*success=*/false, DISPLAY_CONNECTION_TYPE_NONE, - CONTENT_PROTECTION_METHOD_NONE); - return; - } - - QueueContentProtectionTask(std::make_unique<QueryContentProtectionTask>( - layout_manager_.get(), native_display_delegate_.get(), display_id, - base::BindOnce(&DisplayConfigurator::OnContentProtectionQueried, - weak_ptr_factory_.GetWeakPtr(), std::move(callback), - client_id, display_id))); -} - -void DisplayConfigurator::OnContentProtectionQueried( - QueryContentProtectionCallback callback, - ContentProtectionClientId client_id, - int64_t display_id, - ContentProtectionTask::Status status, - uint32_t connection_mask, - uint32_t protection_mask) { - // Only run callback if client is still registered. - if (const auto* protections = GetContentProtections(client_id)) { - bool success = status == ContentProtectionTask::Status::SUCCESS; - - // Conceal protections requested by other clients. - uint32_t client_mask = CONTENT_PROTECTION_METHOD_NONE; - - if (success) { - auto it = protections->find(display_id); - if (it != protections->end()) - client_mask = it->second; - } - - protection_mask &= client_mask; - - std::move(callback).Run(success, connection_mask, protection_mask); - } - - if (status != ContentProtectionTask::Status::KILLED) - DequeueContentProtectionTask(); -} - -void DisplayConfigurator::ApplyContentProtection( - ContentProtectionClientId client_id, - int64_t display_id, - uint32_t protection_mask, - ApplyContentProtectionCallback callback) { - ContentProtections* protections = GetContentProtections(client_id); - DCHECK(configurator_disabled() || protections); - - if (configurator_disabled() || !GetDisplay(display_id)) { - std::move(callback).Run(/*success=*/false); - return; - } - - protections->insert_or_assign(display_id, protection_mask); - - QueueContentProtectionTask(std::make_unique<ApplyContentProtectionTask>( - layout_manager_.get(), native_display_delegate_.get(), - AggregateContentProtections(), - base::BindOnce(&DisplayConfigurator::OnContentProtectionApplied, - weak_ptr_factory_.GetWeakPtr(), std::move(callback), - client_id))); -} - -void DisplayConfigurator::QueueContentProtectionTask( - std::unique_ptr<ContentProtectionTask> task) { - content_protection_tasks_.emplace(std::move(task)); - - if (content_protection_tasks_.size() == 1) - content_protection_tasks_.front()->Run(); -} - -void DisplayConfigurator::DequeueContentProtectionTask() { - DCHECK(!content_protection_tasks_.empty()); - content_protection_tasks_.pop(); - - if (!content_protection_tasks_.empty()) - content_protection_tasks_.front()->Run(); -} - -void DisplayConfigurator::OnContentProtectionApplied( - ApplyContentProtectionCallback callback, - ContentProtectionClientId client_id, - ContentProtectionTask::Status status) { - // Only run callback if client is still registered. - if (GetContentProtections(client_id)) - std::move(callback).Run(status == ContentProtectionTask::Status::SUCCESS); - - if (status != ContentProtectionTask::Status::KILLED) - DequeueContentProtectionTask(); -} - -DisplayConfigurator::ContentProtections* -DisplayConfigurator::GetContentProtections( - ContentProtectionClientId client_id) { - if (!client_id) - return nullptr; - - auto it = content_protection_requests_.find(*client_id); - return it == content_protection_requests_.end() ? nullptr : &it->second; -} - -DisplayConfigurator::ContentProtections -DisplayConfigurator::AggregateContentProtections() const { - ContentProtections protections; - - for (const auto& requests_pair : content_protection_requests_) - for (const auto& protections_pair : requests_pair.second) - protections[protections_pair.first] |= protections_pair.second; - - return protections; -} - bool DisplayConfigurator::SetColorMatrix( int64_t display_id, const std::vector<float>& color_matrix) { @@ -941,15 +792,6 @@ void DisplayConfigurator::PrepareForExit() { configure_display_ = false; } -const DisplaySnapshot* DisplayConfigurator::GetDisplay( - int64_t display_id) const { - auto it = std::find_if(cached_displays_.begin(), cached_displays_.end(), - [display_id](const DisplaySnapshot* display) { - return display->display_id() == display_id; - }); - return it == cached_displays_.end() ? nullptr : *it; -} - void DisplayConfigurator::SetDisplayPowerInternal( chromeos::DisplayPowerState power_state, int flags, @@ -1176,15 +1018,6 @@ void DisplayConfigurator::OnConfigured( if (!configure_timer_.IsRunning()) CallAndClearQueuedCallbacks(success); } - - // Filter out content protection requests for removed displays. - for (auto& requests : content_protection_requests_) { - base::EraseIf(requests.second, - [this](const auto& pair) { return !GetDisplay(pair.first); }); - } - - // Kill tasks to fire failure callbacks. - content_protection_tasks_ = {}; } void DisplayConfigurator::UpdatePowerState( diff --git a/chromium/ui/display/manager/display_configurator.h b/chromium/ui/display/manager/display_configurator.h index df358b67988..4427cf7fce4 100644 --- a/chromium/ui/display/manager/display_configurator.h +++ b/chromium/ui/display/manager/display_configurator.h @@ -5,14 +5,11 @@ #ifndef UI_DISPLAY_MANAGER_DISPLAY_CONFIGURATOR_H_ #define UI_DISPLAY_MANAGER_DISPLAY_CONFIGURATOR_H_ -#include <stdint.h> - +#include <cstdint> #include <memory> #include <string> #include <vector> -#include "base/containers/flat_map.h" -#include "base/containers/queue.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/observer_list.h" @@ -31,7 +28,8 @@ class Size; } namespace display { -struct GammaRampRGBEntry; + +class ContentProtectionManager; class DisplayLayoutManager; class DisplayMode; class DisplaySnapshot; @@ -39,6 +37,8 @@ class ManagedDisplayMode; class NativeDisplayDelegate; class UpdateDisplayConfigurationTask; +struct GammaRampRGBEntry; + namespace test { class DisplayManagerTestApi; } @@ -48,29 +48,10 @@ class DISPLAY_MANAGER_EXPORT DisplayConfigurator : public NativeDisplayObserver { public: using ConfigurationCallback = base::Callback<void(bool /* success */)>; - - // |connection_mask| is a DisplayConnectionType bitmask, and |protection_mask| - // is a ContentProtectionMethod bitmask. - using QueryContentProtectionCallback = base::OnceCallback< - void(bool success, uint32_t connection_mask, uint32_t protection_mask)>; - using ApplyContentProtectionCallback = base::OnceCallback<void(bool success)>; - using DisplayControlCallback = base::OnceCallback<void(bool success)>; using DisplayStateList = std::vector<DisplaySnapshot*>; - using ContentProtections = - base::flat_map<int64_t /* display_id */, uint32_t /* protection_mask */>; - - // Though only run once, a task must outlive its asynchronous operations, so - // cannot be a OnceCallback. - struct ContentProtectionTask { - enum class Status { KILLED, FAILURE, SUCCESS }; - - virtual ~ContentProtectionTask() = default; - virtual void Run() = 0; - }; - class Observer { public: virtual ~Observer() {} @@ -200,6 +181,9 @@ class DISPLAY_MANAGER_EXPORT DisplayConfigurator chromeos::DisplayPowerState current_power_state() const { return current_power_state_; } + ContentProtectionManager* content_protection_manager() const { + return content_protection_manager_.get(); + } // Called when an external process no longer needs to control the display // and Chrome can take control. @@ -267,20 +251,6 @@ class DISPLAY_MANAGER_EXPORT DisplayConfigurator // suspended. void ResumeDisplays(); - using ContentProtectionClientId = base::Optional<uint64_t>; - - ContentProtectionClientId RegisterContentProtectionClient(); - void UnregisterContentProtectionClient(ContentProtectionClientId client_id); - - void QueryContentProtection(ContentProtectionClientId client_id, - int64_t display_id, - QueryContentProtectionCallback callback); - // |protection_mask| is a ContentProtectionMethod bitmask. - void ApplyContentProtection(ContentProtectionClientId client_id, - int64_t display_id, - uint32_t protection_mask, - ApplyContentProtectionCallback callback); - // Returns true if there is at least one display on. bool IsDisplayOn() const; @@ -317,8 +287,6 @@ class DISPLAY_MANAGER_EXPORT DisplayConfigurator return !configure_display_ || display_externally_controlled_; } - const DisplaySnapshot* GetDisplay(int64_t display_id) const; - // Updates |pending_*| members and applies the passed-in state. |callback| is // invoked (perhaps synchronously) on completion. void SetDisplayPowerInternal(chromeos::DisplayPowerState power_state, @@ -367,29 +335,6 @@ class DISPLAY_MANAGER_EXPORT DisplayConfigurator void CallAndClearInProgressCallbacks(bool success); void CallAndClearQueuedCallbacks(bool success); - // Content protection callbacks called by the tasks when they finish. These - // are responsible for destroying the task, replying to the caller that made - // the task and starting the a new content protection task if one is queued. - void OnContentProtectionQueried(QueryContentProtectionCallback callback, - ContentProtectionClientId client_id, - int64_t display_id, - ContentProtectionTask::Status status, - uint32_t connection_mask, - uint32_t protection_mask); - void OnContentProtectionApplied(ApplyContentProtectionCallback callback, - ContentProtectionClientId client_id, - ContentProtectionTask::Status status); - - // Returns content protections for |client_id|, or nullptr if invalid. - ContentProtections* GetContentProtections( - ContentProtectionClientId client_id); - - // Returns cumulative content protections given all client requests. - ContentProtections AggregateContentProtections() const; - - void QueueContentProtectionTask(std::unique_ptr<ContentProtectionTask> task); - void DequeueContentProtectionTask(); - // Callbacks used to signal when the native platform has released/taken // display control. void OnDisplayControlTaken(DisplayControlCallback callback, bool success); @@ -460,14 +405,6 @@ class DISPLAY_MANAGER_EXPORT DisplayConfigurator // display configuration events when they are reported in short time spans. base::OneShotTimer configure_timer_; - uint64_t next_content_protection_client_id_ = 0; - - // Content protections requested by each client. - base::flat_map<uint64_t, ContentProtections> content_protection_requests_; - - // Pending tasks to query or apply content protection. - base::queue<std::unique_ptr<ContentProtectionTask>> content_protection_tasks_; - // Display controlled by an external entity. bool display_externally_controlled_; @@ -479,6 +416,7 @@ class DISPLAY_MANAGER_EXPORT DisplayConfigurator bool displays_suspended_; std::unique_ptr<DisplayLayoutManager> layout_manager_; + std::unique_ptr<ContentProtectionManager> content_protection_manager_; std::unique_ptr<UpdateDisplayConfigurationTask> configuration_task_; diff --git a/chromium/ui/display/manager/display_configurator_unittest.cc b/chromium/ui/display/manager/display_configurator_unittest.cc index d4fb1b21017..474b267e172 100644 --- a/chromium/ui/display/manager/display_configurator_unittest.cc +++ b/chromium/ui/display/manager/display_configurator_unittest.cc @@ -9,9 +9,9 @@ #include "base/bind.h" #include "base/command_line.h" -#include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "base/stl_util.h" +#include "base/test/scoped_task_environment.h" #include "chromeos/constants/chromeos_switches.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/display/fake/fake_display_snapshot.h" @@ -252,21 +252,6 @@ class DisplayConfiguratorTest : public testing::Test { display_control_result_ = success ? CALLBACK_SUCCESS : CALLBACK_FAILURE; } - void ApplyContentProtectionCallback(bool success) { - apply_content_protection_success_ = success; - apply_content_protection_call_count_++; - } - - void QueryContentProtectionCallback(bool success, - uint32_t connection_mask, - uint32_t protection_mask) { - query_content_protection_success_ = success; - query_content_protection_call_count_++; - - connection_mask_ = connection_mask; - protection_mask_ = protection_mask; - } - // Predefined modes that can be used by outputs. const DisplayMode small_mode_{gfx::Size(1366, 768), false, 60.0f}; const DisplayMode big_mode_{gfx::Size(2560, 1600), false, 60.0f}; @@ -327,7 +312,7 @@ class DisplayConfiguratorTest : public testing::Test { return result; } - base::MessageLoop message_loop_; + base::test::ScopedTaskEnvironment scoped_task_environment_; TestStateController state_controller_; TestMirroringController mirroring_controller_; DisplayConfigurator configurator_; @@ -337,13 +322,6 @@ class DisplayConfiguratorTest : public testing::Test { DisplayConfigurator::TestApi test_api_{&configurator_}; ConfigurationWaiter config_waiter_{&test_api_}; - bool apply_content_protection_success_ = false; - int apply_content_protection_call_count_ = 0; - bool query_content_protection_success_ = false; - int query_content_protection_call_count_ = 0; - uint32_t connection_mask_ = DISPLAY_CONNECTION_TYPE_NONE; - uint32_t protection_mask_ = CONTENT_PROTECTION_METHOD_NONE; - static constexpr size_t kNumOutputs = 3; std::unique_ptr<DisplaySnapshot> outputs_[kNumOutputs]; @@ -860,268 +838,6 @@ TEST_F(DisplayConfiguratorTest, UpdateCachedOutputsEvenAfterFailure) { EXPECT_EQ(outputs_[1]->current_mode(), cached[1]->current_mode()); } -TEST_F(DisplayConfiguratorTest, ContentProtection) { - InitWithOutputs(&small_mode_); - - auto id = configurator_.RegisterContentProtectionClient(); - EXPECT_TRUE(id); - - configurator_.QueryContentProtection( - id, outputs_[0]->display_id(), - base::BindOnce(&DisplayConfiguratorTest::QueryContentProtectionCallback, - base::Unretained(this))); - EXPECT_EQ(1, query_content_protection_call_count_); - EXPECT_TRUE(query_content_protection_success_); - EXPECT_EQ(DISPLAY_CONNECTION_TYPE_INTERNAL, connection_mask_); - EXPECT_EQ(CONTENT_PROTECTION_METHOD_NONE, protection_mask_); - EXPECT_EQ(kNoActions, log_->GetActionsAndClear()); - - UpdateOutputs(2, true); - EXPECT_NE(kNoActions, log_->GetActionsAndClear()); - - configurator_.QueryContentProtection( - id, outputs_[1]->display_id(), - base::BindOnce(&DisplayConfiguratorTest::QueryContentProtectionCallback, - base::Unretained(this))); - EXPECT_EQ(2, query_content_protection_call_count_); - EXPECT_TRUE(query_content_protection_success_); - EXPECT_EQ(DISPLAY_CONNECTION_TYPE_HDMI, connection_mask_); - EXPECT_EQ(CONTENT_PROTECTION_METHOD_NONE, protection_mask_); - EXPECT_EQ(kNoActions, log_->GetActionsAndClear()); - - configurator_.ApplyContentProtection( - id, outputs_[1]->display_id(), CONTENT_PROTECTION_METHOD_HDCP, - base::BindOnce(&DisplayConfiguratorTest::ApplyContentProtectionCallback, - base::Unretained(this))); - EXPECT_EQ(1, apply_content_protection_call_count_); - EXPECT_TRUE(apply_content_protection_success_); - EXPECT_EQ(GetSetHDCPStateAction(kDisplayIds[1], HDCP_STATE_DESIRED), - log_->GetActionsAndClear()); - - EXPECT_EQ(HDCP_STATE_ENABLED, native_display_delegate_->hdcp_state()); - - configurator_.QueryContentProtection( - id, outputs_[1]->display_id(), - base::BindOnce(&DisplayConfiguratorTest::QueryContentProtectionCallback, - base::Unretained(this))); - EXPECT_EQ(3, query_content_protection_call_count_); - EXPECT_TRUE(query_content_protection_success_); - EXPECT_EQ(DISPLAY_CONNECTION_TYPE_HDMI, connection_mask_); - EXPECT_EQ(CONTENT_PROTECTION_METHOD_HDCP, protection_mask_); - EXPECT_EQ(kNoActions, log_->GetActionsAndClear()); - - // Requests on invalid display should fail. - constexpr int64_t kInvalidDisplayId = -999; - configurator_.QueryContentProtection( - id, kInvalidDisplayId, - base::BindOnce(&DisplayConfiguratorTest::QueryContentProtectionCallback, - base::Unretained(this))); - configurator_.ApplyContentProtection( - id, kInvalidDisplayId, CONTENT_PROTECTION_METHOD_HDCP, - base::BindOnce(&DisplayConfiguratorTest::ApplyContentProtectionCallback, - base::Unretained(this))); - - EXPECT_EQ(4, query_content_protection_call_count_); - EXPECT_FALSE(query_content_protection_success_); - EXPECT_EQ(DISPLAY_CONNECTION_TYPE_NONE, connection_mask_); - EXPECT_EQ(CONTENT_PROTECTION_METHOD_NONE, protection_mask_); - - EXPECT_EQ(2, apply_content_protection_call_count_); - EXPECT_FALSE(apply_content_protection_success_); - - EXPECT_EQ(HDCP_STATE_ENABLED, native_display_delegate_->hdcp_state()); - - // Protections should be disabled after unregister. - configurator_.UnregisterContentProtectionClient(id); - - EXPECT_EQ(GetSetHDCPStateAction(kDisplayIds[1], HDCP_STATE_UNDESIRED), - log_->GetActionsAndClear()); - EXPECT_EQ(HDCP_STATE_UNDESIRED, native_display_delegate_->hdcp_state()); -} - -TEST_F(DisplayConfiguratorTest, ContentProtectionAsync) { - InitWithOutputs(&small_mode_, &big_mode_); - - auto id = configurator_.RegisterContentProtectionClient(); - EXPECT_TRUE(id); - - native_display_delegate_->set_run_async(true); - - // Asynchronous tasks should be pending. - constexpr int kTaskCount = 3; - for (int i = 0; i < kTaskCount; ++i) { - configurator_.ApplyContentProtection( - id, outputs_[1]->display_id(), CONTENT_PROTECTION_METHOD_HDCP, - base::BindOnce(&DisplayConfiguratorTest::ApplyContentProtectionCallback, - base::Unretained(this))); - - configurator_.QueryContentProtection( - id, outputs_[1]->display_id(), - base::BindOnce(&DisplayConfiguratorTest::QueryContentProtectionCallback, - base::Unretained(this))); - } - - EXPECT_EQ(0, apply_content_protection_call_count_); - EXPECT_EQ(0, query_content_protection_call_count_); - EXPECT_EQ(kNoActions, log_->GetActionsAndClear()); - EXPECT_EQ(HDCP_STATE_UNDESIRED, native_display_delegate_->hdcp_state()); - - base::RunLoop().RunUntilIdle(); - - EXPECT_EQ(kTaskCount, apply_content_protection_call_count_); - EXPECT_TRUE(apply_content_protection_success_); - - EXPECT_EQ(kTaskCount, query_content_protection_call_count_); - EXPECT_TRUE(query_content_protection_success_); - EXPECT_EQ(DISPLAY_CONNECTION_TYPE_HDMI, connection_mask_); - EXPECT_EQ(CONTENT_PROTECTION_METHOD_HDCP, protection_mask_); - - EXPECT_EQ(GetSetHDCPStateAction(kDisplayIds[1], HDCP_STATE_DESIRED), - log_->GetActionsAndClear()); - EXPECT_EQ(HDCP_STATE_ENABLED, native_display_delegate_->hdcp_state()); - - // Pending task should run even if previous task fails. - native_display_delegate_->set_set_hdcp_state_expectation(false); - - configurator_.ApplyContentProtection( - id, outputs_[1]->display_id(), CONTENT_PROTECTION_METHOD_NONE, - base::BindOnce(&DisplayConfiguratorTest::ApplyContentProtectionCallback, - base::Unretained(this))); - - configurator_.QueryContentProtection( - id, outputs_[1]->display_id(), - base::BindOnce(&DisplayConfiguratorTest::QueryContentProtectionCallback, - base::Unretained(this))); - - EXPECT_EQ(kTaskCount, apply_content_protection_call_count_); - EXPECT_EQ(kTaskCount, query_content_protection_call_count_); - - base::RunLoop().RunUntilIdle(); - - EXPECT_EQ(kTaskCount + 1, apply_content_protection_call_count_); - EXPECT_FALSE(apply_content_protection_success_); - - EXPECT_EQ(kTaskCount + 1, query_content_protection_call_count_); - EXPECT_TRUE(query_content_protection_success_); - EXPECT_EQ(DISPLAY_CONNECTION_TYPE_HDMI, connection_mask_); - EXPECT_EQ(CONTENT_PROTECTION_METHOD_NONE, protection_mask_); - - // Disabling protection should fail. - EXPECT_EQ(GetSetHDCPStateAction(kDisplayIds[1], HDCP_STATE_UNDESIRED), - log_->GetActionsAndClear()); - EXPECT_EQ(HDCP_STATE_ENABLED, native_display_delegate_->hdcp_state()); -} - -TEST_F(DisplayConfiguratorTest, ContentProtectionRequestRetention) { - InitWithOutputs(&small_mode_, &big_mode_); - - auto id = configurator_.RegisterContentProtectionClient(); - EXPECT_TRUE(id); - - native_display_delegate_->set_run_async(true); - - // Enable protection on external display. - configurator_.ApplyContentProtection( - id, outputs_[1]->display_id(), CONTENT_PROTECTION_METHOD_HDCP, - base::BindOnce(&DisplayConfiguratorTest::ApplyContentProtectionCallback, - base::Unretained(this))); - - // Disable protection on internal display. - configurator_.ApplyContentProtection( - id, outputs_[0]->display_id(), CONTENT_PROTECTION_METHOD_NONE, - base::BindOnce(&DisplayConfiguratorTest::ApplyContentProtectionCallback, - base::Unretained(this))); - - EXPECT_EQ(0, apply_content_protection_call_count_); - EXPECT_EQ(kNoActions, log_->GetActionsAndClear()); - EXPECT_EQ(HDCP_STATE_UNDESIRED, native_display_delegate_->hdcp_state()); - - base::RunLoop().RunUntilIdle(); - - EXPECT_EQ(2, apply_content_protection_call_count_); - EXPECT_TRUE(apply_content_protection_success_); - - // Protection on external display should be retained. - EXPECT_EQ(GetSetHDCPStateAction(kDisplayIds[1], HDCP_STATE_DESIRED).c_str(), - log_->GetActionsAndClear()); - EXPECT_EQ(HDCP_STATE_ENABLED, native_display_delegate_->hdcp_state()); -} - -TEST_F(DisplayConfiguratorTest, ContentProtectionClientRegistration) { - InitWithOutputs(&small_mode_, &big_mode_); - - auto id = configurator_.RegisterContentProtectionClient(); - EXPECT_TRUE(id); - - native_display_delegate_->set_run_async(true); - - configurator_.ApplyContentProtection( - id, outputs_[1]->display_id(), CONTENT_PROTECTION_METHOD_HDCP, - base::BindOnce(&DisplayConfiguratorTest::ApplyContentProtectionCallback, - base::Unretained(this))); - - configurator_.QueryContentProtection( - id, outputs_[1]->display_id(), - base::BindOnce(&DisplayConfiguratorTest::QueryContentProtectionCallback, - base::Unretained(this))); - - configurator_.UnregisterContentProtectionClient(id); - - base::RunLoop().RunUntilIdle(); - - // Pending callbacks should not run if client was unregistered. - EXPECT_EQ(0, apply_content_protection_call_count_); - EXPECT_EQ(0, query_content_protection_call_count_); - - // Unregistration should disable protection. - EXPECT_EQ( - JoinActions( - GetSetHDCPStateAction(kDisplayIds[1], HDCP_STATE_DESIRED).c_str(), - GetSetHDCPStateAction(kDisplayIds[1], HDCP_STATE_UNDESIRED).c_str(), - nullptr), - log_->GetActionsAndClear()); - EXPECT_EQ(HDCP_STATE_UNDESIRED, native_display_delegate_->hdcp_state()); -} - -TEST_F(DisplayConfiguratorTest, ContentProtectionTasksKilledOnConfigure) { - InitWithOutputs(&small_mode_, &big_mode_); - - auto id = configurator_.RegisterContentProtectionClient(); - EXPECT_TRUE(id); - - native_display_delegate_->set_run_async(true); - - configurator_.ApplyContentProtection( - id, outputs_[1]->display_id(), CONTENT_PROTECTION_METHOD_HDCP, - base::BindOnce(&DisplayConfiguratorTest::ApplyContentProtectionCallback, - base::Unretained(this))); - - configurator_.QueryContentProtection( - id, outputs_[1]->display_id(), - base::BindOnce(&DisplayConfiguratorTest::QueryContentProtectionCallback, - base::Unretained(this))); - - native_display_delegate_->set_run_async(false); - configurator_.OnConfigurationChanged(); - EXPECT_TRUE(test_api_.TriggerConfigureTimeout()); - log_->GetActionsAndClear(); - - base::RunLoop().RunUntilIdle(); - - // Configuration change should kill tasks and trigger failure callbacks. - EXPECT_EQ(1, apply_content_protection_call_count_); - EXPECT_FALSE(apply_content_protection_success_); - - EXPECT_EQ(1, query_content_protection_call_count_); - EXPECT_FALSE(query_content_protection_success_); - EXPECT_EQ(DISPLAY_CONNECTION_TYPE_NONE, connection_mask_); - EXPECT_EQ(CONTENT_PROTECTION_METHOD_NONE, protection_mask_); - - // Pending task to enable protection should have been killed. - EXPECT_EQ(kNoActions, log_->GetActionsAndClear()); - EXPECT_EQ(HDCP_STATE_UNDESIRED, native_display_delegate_->hdcp_state()); -} - TEST_F(DisplayConfiguratorTest, DoNotConfigureWithSuspendedDisplays) { InitWithOutputs(&small_mode_); @@ -1189,110 +905,6 @@ TEST_F(DisplayConfiguratorTest, DoNotConfigureWithSuspendedDisplays) { EXPECT_EQ(GetCrtcActions(&small_mode_), log_->GetActionsAndClear()); } -TEST_F(DisplayConfiguratorTest, ContentProtectionTwoClients) { - InitWithOutputs(&small_mode_, &big_mode_); - - auto client1 = configurator_.RegisterContentProtectionClient(); - auto client2 = configurator_.RegisterContentProtectionClient(); - EXPECT_NE(client1, client2); - - // Clients never know state enableness for methods that they didn't request. - configurator_.ApplyContentProtection( - client1, outputs_[1]->display_id(), CONTENT_PROTECTION_METHOD_HDCP, - base::BindOnce(&DisplayConfiguratorTest::ApplyContentProtectionCallback, - base::Unretained(this))); - EXPECT_EQ(1, apply_content_protection_call_count_); - EXPECT_TRUE(apply_content_protection_success_); - - EXPECT_EQ(GetSetHDCPStateAction(kDisplayIds[1], HDCP_STATE_DESIRED), - log_->GetActionsAndClear()); - EXPECT_EQ(HDCP_STATE_ENABLED, native_display_delegate_->hdcp_state()); - - configurator_.QueryContentProtection( - client1, outputs_[1]->display_id(), - base::BindOnce(&DisplayConfiguratorTest::QueryContentProtectionCallback, - base::Unretained(this))); - EXPECT_EQ(1, query_content_protection_call_count_); - EXPECT_TRUE(query_content_protection_success_); - EXPECT_EQ(DISPLAY_CONNECTION_TYPE_HDMI, connection_mask_); - EXPECT_EQ(CONTENT_PROTECTION_METHOD_HDCP, protection_mask_); - - configurator_.QueryContentProtection( - client2, outputs_[1]->display_id(), - base::BindOnce(&DisplayConfiguratorTest::QueryContentProtectionCallback, - base::Unretained(this))); - EXPECT_EQ(2, query_content_protection_call_count_); - EXPECT_TRUE(query_content_protection_success_); - EXPECT_EQ(DISPLAY_CONNECTION_TYPE_HDMI, connection_mask_); - EXPECT_EQ(CONTENT_PROTECTION_METHOD_NONE, protection_mask_); - - // Protections will be disabled only if no more clients request them. - configurator_.ApplyContentProtection( - client2, outputs_[1]->display_id(), CONTENT_PROTECTION_METHOD_NONE, - base::BindOnce(&DisplayConfiguratorTest::ApplyContentProtectionCallback, - base::Unretained(this))); - EXPECT_EQ(2, apply_content_protection_call_count_); - EXPECT_TRUE(apply_content_protection_success_); - - EXPECT_EQ(kNoActions, log_->GetActionsAndClear()); - EXPECT_EQ(HDCP_STATE_ENABLED, native_display_delegate_->hdcp_state()); - - configurator_.ApplyContentProtection( - client1, outputs_[1]->display_id(), CONTENT_PROTECTION_METHOD_NONE, - base::BindOnce(&DisplayConfiguratorTest::ApplyContentProtectionCallback, - base::Unretained(this))); - EXPECT_EQ(3, apply_content_protection_call_count_); - EXPECT_TRUE(apply_content_protection_success_); - EXPECT_EQ(GetSetHDCPStateAction(kDisplayIds[1], HDCP_STATE_UNDESIRED), - log_->GetActionsAndClear()); - EXPECT_EQ(HDCP_STATE_UNDESIRED, native_display_delegate_->hdcp_state()); -} - -TEST_F(DisplayConfiguratorTest, ContentProtectionTwoClientsEnable) { - InitWithOutputs(&small_mode_, &big_mode_); - - auto client1 = configurator_.RegisterContentProtectionClient(); - auto client2 = configurator_.RegisterContentProtectionClient(); - EXPECT_NE(client1, client2); - - // Only enable once if HDCP is enabling. - configurator_.ApplyContentProtection( - client1, outputs_[1]->display_id(), CONTENT_PROTECTION_METHOD_HDCP, - base::BindOnce(&DisplayConfiguratorTest::ApplyContentProtectionCallback, - base::Unretained(this))); - EXPECT_EQ(1, apply_content_protection_call_count_); - EXPECT_TRUE(apply_content_protection_success_); - - configurator_.ApplyContentProtection( - client2, outputs_[1]->display_id(), CONTENT_PROTECTION_METHOD_HDCP, - base::BindOnce(&DisplayConfiguratorTest::ApplyContentProtectionCallback, - base::Unretained(this))); - EXPECT_EQ(2, apply_content_protection_call_count_); - EXPECT_TRUE(apply_content_protection_success_); - - EXPECT_EQ(GetSetHDCPStateAction(kDisplayIds[1], HDCP_STATE_DESIRED), - log_->GetActionsAndClear()); - EXPECT_EQ(HDCP_STATE_ENABLED, native_display_delegate_->hdcp_state()); - - // Don't enable again if HDCP is already active. - configurator_.ApplyContentProtection( - client1, outputs_[1]->display_id(), CONTENT_PROTECTION_METHOD_HDCP, - base::BindOnce(&DisplayConfiguratorTest::ApplyContentProtectionCallback, - base::Unretained(this))); - EXPECT_EQ(3, apply_content_protection_call_count_); - EXPECT_TRUE(apply_content_protection_success_); - - configurator_.ApplyContentProtection( - client2, outputs_[1]->display_id(), CONTENT_PROTECTION_METHOD_HDCP, - base::BindOnce(&DisplayConfiguratorTest::ApplyContentProtectionCallback, - base::Unretained(this))); - EXPECT_EQ(4, apply_content_protection_call_count_); - EXPECT_TRUE(apply_content_protection_success_); - - EXPECT_EQ(kNoActions, log_->GetActionsAndClear()); - EXPECT_EQ(HDCP_STATE_ENABLED, native_display_delegate_->hdcp_state()); -} - TEST_F(DisplayConfiguratorTest, HandleConfigureCrtcFailure) { InitWithOutputs(&small_mode_); diff --git a/chromium/ui/display/manager/display_manager.cc b/chromium/ui/display/manager/display_manager.cc index 4cf95123464..76db4bb7a11 100644 --- a/chromium/ui/display/manager/display_manager.cc +++ b/chromium/ui/display/manager/display_manager.cc @@ -322,9 +322,7 @@ DisplayManager::BeginEndNotifier::~BeginEndNotifier() { } DisplayManager::DisplayManager(std::unique_ptr<Screen> screen) - : screen_(std::move(screen)), - layout_store_(new DisplayLayoutStore), - weak_ptr_factory_(this) { + : screen_(std::move(screen)), layout_store_(new DisplayLayoutStore) { #if defined(OS_CHROMEOS) configure_displays_ = chromeos::IsRunningAsSystemCompositor(); change_display_upon_host_resize_ = !configure_displays_; @@ -1047,7 +1045,7 @@ void DisplayManager::UpdateDisplaysWith( std::vector<size_t> updated_indices; UpdateNonPrimaryDisplayBoundsForLayout(&new_displays, &updated_indices); for (size_t updated_index : updated_indices) { - if (!base::ContainsValue(added_display_indices, updated_index)) { + if (!base::Contains(added_display_indices, updated_index)) { uint32_t metrics = DisplayObserver::DISPLAY_METRIC_BOUNDS | DisplayObserver::DISPLAY_METRIC_WORK_AREA; if (display_changes.find(updated_index) != display_changes.end()) @@ -2098,6 +2096,7 @@ Display DisplayManager::CreateDisplayFromDisplayInfoById(int64_t id) { new_display.set_touch_support(display_info.touch_support()); new_display.set_maximum_cursor_size(display_info.maximum_cursor_size()); new_display.SetColorSpaceAndDepth(display_info.color_space()); + new_display.set_display_frequency(display_info.refresh_rate()); if (internal_display_has_accelerometer_ && Display::IsInternalDisplayId(id)) { new_display.set_accelerometer_support( diff --git a/chromium/ui/display/manager/display_manager.h b/chromium/ui/display/manager/display_manager.h index 9bceae9a8b1..a0b971f1ef3 100644 --- a/chromium/ui/display/manager/display_manager.h +++ b/chromium/ui/display/manager/display_manager.h @@ -700,7 +700,7 @@ class DISPLAY_MANAGER_EXPORT DisplayManager base::CancelableCallback<void()> on_display_zoom_modify_timeout_; #endif - base::WeakPtrFactory<DisplayManager> weak_ptr_factory_; + base::WeakPtrFactory<DisplayManager> weak_ptr_factory_{this}; DISALLOW_COPY_AND_ASSIGN(DisplayManager); }; diff --git a/chromium/ui/display/manager/display_util.cc b/chromium/ui/display/manager/display_util.cc index 592b1313cc2..c8c273c47d8 100644 --- a/chromium/ui/display/manager/display_util.cc +++ b/chromium/ui/display/manager/display_util.cc @@ -62,6 +62,7 @@ bool WithinEpsilon(float a, float b) { } // namespace +#if defined(OS_CHROMEOS) std::string DisplayPowerStateToString(chromeos::DisplayPowerState state) { switch (state) { case chromeos::DISPLAY_POWER_ALL_ON: @@ -77,23 +78,6 @@ std::string DisplayPowerStateToString(chromeos::DisplayPowerState state) { } } -std::string MultipleDisplayStateToString(MultipleDisplayState state) { - switch (state) { - case MULTIPLE_DISPLAY_STATE_INVALID: - return "INVALID"; - case MULTIPLE_DISPLAY_STATE_HEADLESS: - return "HEADLESS"; - case MULTIPLE_DISPLAY_STATE_SINGLE: - return "SINGLE"; - case MULTIPLE_DISPLAY_STATE_MULTI_MIRROR: - return "DUAL_MIRROR"; - case MULTIPLE_DISPLAY_STATE_MULTI_EXTENDED: - return "MULTI_EXTENDED"; - } - NOTREACHED() << "Unknown state " << state; - return "INVALID"; -} - int GetDisplayPower(const std::vector<DisplaySnapshot*>& displays, chromeos::DisplayPowerState state, std::vector<bool>* display_power) { @@ -116,8 +100,23 @@ int GetDisplayPower(const std::vector<DisplaySnapshot*>& displays, return num_on_displays; } -bool IsPhysicalDisplayType(DisplayConnectionType type) { - return !(type & DISPLAY_CONNECTION_TYPE_NETWORK); +#endif // defined(OS_CHROMEOS) + +std::string MultipleDisplayStateToString(MultipleDisplayState state) { + switch (state) { + case MULTIPLE_DISPLAY_STATE_INVALID: + return "INVALID"; + case MULTIPLE_DISPLAY_STATE_HEADLESS: + return "HEADLESS"; + case MULTIPLE_DISPLAY_STATE_SINGLE: + return "SINGLE"; + case MULTIPLE_DISPLAY_STATE_MULTI_MIRROR: + return "DUAL_MIRROR"; + case MULTIPLE_DISPLAY_STATE_MULTI_EXTENDED: + return "MULTI_EXTENDED"; + } + NOTREACHED() << "Unknown state " << state; + return "INVALID"; } bool GetContentProtectionMethods(DisplayConnectionType type, diff --git a/chromium/ui/display/manager/display_util.h b/chromium/ui/display/manager/display_util.h index 786a6db1cfd..e90f055eeaa 100644 --- a/chromium/ui/display/manager/display_util.h +++ b/chromium/ui/display/manager/display_util.h @@ -8,21 +8,22 @@ #include <string> #include <vector> -#include "third_party/cros_system_api/dbus/service_constants.h" #include "ui/display/manager/display_manager_export.h" #include "ui/display/types/display_constants.h" +#if defined(OS_CHROMEOS) +#include "third_party/cros_system_api/dbus/service_constants.h" +#endif // defined(OS_CHROMEOS) + namespace display { class DisplaySnapshot; class ManagedDisplayMode; +#if defined(OS_CHROMEOS) // Returns a string describing |state|. std::string DisplayPowerStateToString(chromeos::DisplayPowerState state); -// Returns a string describing |state|. -std::string MultipleDisplayStateToString(MultipleDisplayState state); - // Returns the number of displays in |displays| that should be turned on, per // |state|. If |display_power| is non-NULL, it is updated to contain the // on/off state of each corresponding entry in |displays|. @@ -31,10 +32,10 @@ GetDisplayPower(const std::vector<DisplaySnapshot*>& displays, chromeos::DisplayPowerState state, std::vector<bool>* display_power); -// Returns whether the DisplayConnectionType |type| is a physically connected -// display. Currently only DISPLAY_CONNECTION_TYPE_NETWORK return false. -// All other types return true. -bool IsPhysicalDisplayType(DisplayConnectionType type); +#endif // defined(OS_CHROMEOS) + +// Returns a string describing |state|. +std::string MultipleDisplayStateToString(MultipleDisplayState state); // Sets bits in |protection_mask| for each ContentProtectionMethod supported by // the display |type|. Returns false for unknown display types. diff --git a/chromium/ui/display/manager/query_content_protection_task.cc b/chromium/ui/display/manager/query_content_protection_task.cc index 8488b962c9b..a627324dc4b 100644 --- a/chromium/ui/display/manager/query_content_protection_task.cc +++ b/chromium/ui/display/manager/query_content_protection_task.cc @@ -48,8 +48,14 @@ void QueryContentProtectionTask::Run() { return; } + // Collect displays to be queried based on HDCP capability. For unprotected + // displays not inherently secure through an internal connection, record the + // existence of an unsecure display to report no protection for all displays + // in mirroring mode. if (protection_mask & CONTENT_PROTECTION_METHOD_HDCP) hdcp_capable_displays.push_back(display); + else if (display->type() != DISPLAY_CONNECTION_TYPE_INTERNAL) + no_protection_mask_ |= CONTENT_PROTECTION_METHOD_HDCP; } pending_requests_ = hdcp_capable_displays.size(); diff --git a/chromium/ui/display/manager/query_content_protection_task.h b/chromium/ui/display/manager/query_content_protection_task.h index 8521c8cd924..bf6a1e20696 100644 --- a/chromium/ui/display/manager/query_content_protection_task.h +++ b/chromium/ui/display/manager/query_content_protection_task.h @@ -11,7 +11,7 @@ #include "base/callback.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" -#include "ui/display/manager/display_configurator.h" +#include "ui/display/manager/content_protection_manager.h" #include "ui/display/manager/display_manager_export.h" #include "ui/display/types/display_constants.h" @@ -21,7 +21,7 @@ class DisplayLayoutManager; class NativeDisplayDelegate; class DISPLAY_MANAGER_EXPORT QueryContentProtectionTask - : public DisplayConfigurator::ContentProtectionTask { + : public ContentProtectionManager::Task { public: // |connection_mask| includes mirroring displays, and a protection method is // only included in |protection_mask| if also enabled on mirroring displays. diff --git a/chromium/ui/display/manager/query_content_protection_task_unittest.cc b/chromium/ui/display/manager/query_content_protection_task_unittest.cc index 69b2759c0ad..7404e3b8d76 100644 --- a/chromium/ui/display/manager/query_content_protection_task_unittest.cc +++ b/chromium/ui/display/manager/query_content_protection_task_unittest.cc @@ -81,7 +81,7 @@ TEST_F(QueryContentProtectionTaskTest, QueryInternalDisplay) { ASSERT_TRUE(response_); EXPECT_EQ(Status::SUCCESS, response_->status); EXPECT_EQ(DISPLAY_CONNECTION_TYPE_INTERNAL, response_->connection_mask); - EXPECT_EQ(0u, response_->protection_mask); + EXPECT_EQ(CONTENT_PROTECTION_METHOD_NONE, response_->protection_mask); } TEST_F(QueryContentProtectionTaskTest, QueryUnknownDisplay) { @@ -99,7 +99,7 @@ TEST_F(QueryContentProtectionTaskTest, QueryUnknownDisplay) { ASSERT_TRUE(response_); EXPECT_EQ(Status::FAILURE, response_->status); EXPECT_EQ(DISPLAY_CONNECTION_TYPE_UNKNOWN, response_->connection_mask); - EXPECT_EQ(0u, response_->protection_mask); + EXPECT_EQ(CONTENT_PROTECTION_METHOD_NONE, response_->protection_mask); } TEST_F(QueryContentProtectionTaskTest, QueryDisplayThatCannotGetHdcp) { @@ -135,7 +135,7 @@ TEST_F(QueryContentProtectionTaskTest, QueryDisplayWithHdcpDisabled) { ASSERT_TRUE(response_); EXPECT_EQ(Status::SUCCESS, response_->status); EXPECT_EQ(DISPLAY_CONNECTION_TYPE_HDMI, response_->connection_mask); - EXPECT_EQ(0u, response_->protection_mask); + EXPECT_EQ(CONTENT_PROTECTION_METHOD_NONE, response_->protection_mask); } TEST_F(QueryContentProtectionTaskTest, QueryDisplayWithHdcpEnabled) { @@ -173,7 +173,7 @@ TEST_F(QueryContentProtectionTaskTest, QueryInMultiDisplayMode) { ASSERT_TRUE(response_); EXPECT_EQ(Status::SUCCESS, response_->status); EXPECT_EQ(DISPLAY_CONNECTION_TYPE_HDMI, response_->connection_mask); - EXPECT_EQ(0u, response_->protection_mask); + EXPECT_EQ(CONTENT_PROTECTION_METHOD_NONE, response_->protection_mask); } TEST_F(QueryContentProtectionTaskTest, QueryInMirroringMode) { @@ -194,7 +194,63 @@ TEST_F(QueryContentProtectionTaskTest, QueryInMirroringMode) { EXPECT_EQ(static_cast<uint32_t>(DISPLAY_CONNECTION_TYPE_HDMI | DISPLAY_CONNECTION_TYPE_DVI), response_->connection_mask); - EXPECT_EQ(0u, response_->protection_mask); + EXPECT_EQ(CONTENT_PROTECTION_METHOD_NONE, response_->protection_mask); +} + +TEST_F(QueryContentProtectionTaskTest, QueryAnalogDisplay) { + std::vector<std::unique_ptr<DisplaySnapshot>> displays; + displays.push_back(CreateDisplaySnapshot(1, DISPLAY_CONNECTION_TYPE_VGA)); + TestDisplayLayoutManager layout_manager(std::move(displays), + MULTIPLE_DISPLAY_STATE_SINGLE); + + QueryContentProtectionTask task( + &layout_manager, &display_delegate_, 1, + base::Bind(&QueryContentProtectionTaskTest::ResponseCallback, + base::Unretained(this))); + task.Run(); + + ASSERT_TRUE(response_); + EXPECT_EQ(Status::SUCCESS, response_->status); + EXPECT_EQ(DISPLAY_CONNECTION_TYPE_VGA, response_->connection_mask); + EXPECT_EQ(CONTENT_PROTECTION_METHOD_NONE, response_->protection_mask); +} + +TEST_F(QueryContentProtectionTaskTest, QueryAnalogDisplayMirror) { + std::vector<std::unique_ptr<DisplaySnapshot>> displays; + displays.push_back(CreateDisplaySnapshot(1, DISPLAY_CONNECTION_TYPE_HDMI)); + displays.push_back(CreateDisplaySnapshot(2, DISPLAY_CONNECTION_TYPE_VGA)); + TestDisplayLayoutManager layout_manager(std::move(displays), + MULTIPLE_DISPLAY_STATE_MULTI_MIRROR); + + display_delegate_.set_hdcp_state(HDCP_STATE_ENABLED); + + QueryContentProtectionTask task1( + &layout_manager, &display_delegate_, 1, + base::Bind(&QueryContentProtectionTaskTest::ResponseCallback, + base::Unretained(this))); + task1.Run(); + + ASSERT_TRUE(response_); + EXPECT_EQ(Status::SUCCESS, response_->status); + EXPECT_EQ(static_cast<uint32_t>(DISPLAY_CONNECTION_TYPE_HDMI | + DISPLAY_CONNECTION_TYPE_VGA), + response_->connection_mask); + EXPECT_EQ(CONTENT_PROTECTION_METHOD_NONE, response_->protection_mask); + + response_.reset(); + + QueryContentProtectionTask task2( + &layout_manager, &display_delegate_, 2, + base::Bind(&QueryContentProtectionTaskTest::ResponseCallback, + base::Unretained(this))); + task2.Run(); + + ASSERT_TRUE(response_); + EXPECT_EQ(Status::SUCCESS, response_->status); + EXPECT_EQ(static_cast<uint32_t>(DISPLAY_CONNECTION_TYPE_HDMI | + DISPLAY_CONNECTION_TYPE_VGA), + response_->connection_mask); + EXPECT_EQ(CONTENT_PROTECTION_METHOD_NONE, response_->protection_mask); } } // namespace test diff --git a/chromium/ui/display/manager/touch_device_manager.cc b/chromium/ui/display/manager/touch_device_manager.cc index 713ecfff60f..1ffeb3f1524 100644 --- a/chromium/ui/display/manager/touch_device_manager.cc +++ b/chromium/ui/display/manager/touch_device_manager.cc @@ -15,8 +15,8 @@ #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" #include "ui/display/manager/managed_display_info.h" +#include "ui/events/devices/device_data_manager.h" #include "ui/events/devices/input_device.h" -#include "ui/events/devices/input_device_manager.h" #include "ui/events/devices/touchscreen_device.h" namespace display { @@ -132,7 +132,7 @@ ManagedDisplayInfo* GetBestMatchForDevice( // If we have no historical information for the touch device identified by // |identifier|, do an early return. - if (!base::ContainsKey(touch_associations, identifier)) + if (!base::Contains(touch_associations, identifier)) return display_info; const TouchDeviceManager::AssociationInfoMap& info_map = @@ -143,7 +143,7 @@ ManagedDisplayInfo* GetBestMatchForDevice( // We do not want to match anything to the internal display. if (Display::IsInternalDisplayId(display->id())) continue; - if (!base::ContainsKey(info_map, display->id())) + if (!base::Contains(info_map, display->id())) continue; const TouchDeviceManager::TouchAssociationInfo& info = info_map.at(display->id()); @@ -405,8 +405,8 @@ void TouchDeviceManager::AssociateDevicesWithCollision( // If this device is not the one that has a collision or if this device is // the one that has collision but we have no past port mapping information // associated with it, then we skip. - if (!base::ContainsKey(collision_set, identifier) || - !base::ContainsKey(port_associations_, identifier)) { + if (!base::Contains(collision_set, identifier) || + !base::Contains(port_associations_, identifier)) { device_it++; continue; } @@ -599,7 +599,7 @@ void TouchDeviceManager::AddTouchCalibrationData( const TouchDeviceIdentifier& identifier, int64_t display_id, const TouchCalibrationData& data) { - if (!base::ContainsKey(touch_associations_, identifier)) + if (!base::Contains(touch_associations_, identifier)) touch_associations_.emplace(identifier, AssociationInfoMap()); // Update the current touch association and associate the display identified @@ -631,7 +631,7 @@ void TouchDeviceManager::AddTouchCalibrationData( void TouchDeviceManager::ClearTouchCalibrationData( const TouchDeviceIdentifier& identifier, int64_t display_id) { - if (base::ContainsKey(touch_associations_, identifier)) { + if (base::Contains(touch_associations_, identifier)) { ClearCalibrationDataInMap(touch_associations_.at(identifier), display_id); } } @@ -652,7 +652,7 @@ TouchCalibrationData TouchDeviceManager::GetCalibrationData( if (display_id == kInvalidDisplayId) { // If the touch device is currently not associated with any display and the // |display_id| was not provided, then this is an invalid query. - if (!base::ContainsKey(active_touch_associations_, identifier)) + if (!base::Contains(active_touch_associations_, identifier)) return TouchCalibrationData(); // If the display id is not provided, we return the calibration information @@ -661,7 +661,7 @@ TouchCalibrationData TouchDeviceManager::GetCalibrationData( display_id = active_touch_associations_.at(identifier); } - if (base::ContainsKey(touch_associations_, identifier)) { + if (base::Contains(touch_associations_, identifier)) { const AssociationInfoMap& info_map = touch_associations_.at(identifier); if (info_map.find(display_id) != info_map.end()) return info_map.at(display_id).calibration_data; @@ -670,7 +670,7 @@ TouchCalibrationData TouchDeviceManager::GetCalibrationData( // Check for legacy calibration data. TouchDeviceIdentifier fallback_identifier( TouchDeviceIdentifier::GetFallbackTouchDeviceIdentifier()); - if (base::ContainsKey(touch_associations_, fallback_identifier)) { + if (base::Contains(touch_associations_, fallback_identifier)) { const AssociationInfoMap& info_map = touch_associations_.at(fallback_identifier); if (info_map.find(display_id) != info_map.end()) @@ -684,13 +684,13 @@ TouchCalibrationData TouchDeviceManager::GetCalibrationData( bool TouchDeviceManager::DisplayHasTouchDevice( int64_t display_id, const TouchDeviceIdentifier& identifier) const { - return base::ContainsKey(active_touch_associations_, identifier) && + return base::Contains(active_touch_associations_, identifier) && active_touch_associations_.at(identifier) == display_id; } int64_t TouchDeviceManager::GetAssociatedDisplay( const TouchDeviceIdentifier& identifier) const { - if (base::ContainsKey(active_touch_associations_, identifier)) + if (base::Contains(active_touch_associations_, identifier)) return active_touch_associations_.at(identifier); return kInvalidDisplayId; } @@ -721,7 +721,7 @@ std::ostream& operator<<(std::ostream& os, bool HasExternalTouchscreenDevice() { for (const auto& device : - ui::InputDeviceManager::GetInstance()->GetTouchscreenDevices()) { + ui::DeviceDataManager::GetInstance()->GetTouchscreenDevices()) { if (device.type == ui::InputDeviceType::INPUT_DEVICE_USB || device.type == ui::InputDeviceType::INPUT_DEVICE_BLUETOOTH) { return true; @@ -732,7 +732,7 @@ bool HasExternalTouchscreenDevice() { bool IsInternalTouchscreenDevice(const TouchDeviceIdentifier& identifier) { for (const auto& device : - ui::InputDeviceManager::GetInstance()->GetTouchscreenDevices()) { + ui::DeviceDataManager::GetInstance()->GetTouchscreenDevices()) { if (TouchDeviceIdentifier::FromDevice(device) == identifier) return device.type == ui::InputDeviceType::INPUT_DEVICE_INTERNAL; } diff --git a/chromium/ui/display/manager/touch_transform_controller.cc b/chromium/ui/display/manager/touch_transform_controller.cc index 50b55ffaa13..8f49a26803a 100644 --- a/chromium/ui/display/manager/touch_transform_controller.cc +++ b/chromium/ui/display/manager/touch_transform_controller.cc @@ -16,7 +16,7 @@ #include "ui/display/screen.h" #include "ui/display/types/display_constants.h" #include "ui/display/types/display_snapshot.h" -#include "ui/events/devices/input_device_manager.h" +#include "ui/events/devices/device_data_manager.h" #include "ui/events/devices/touch_device_transform.h" namespace display { @@ -26,7 +26,7 @@ namespace { ui::TouchscreenDevice FindTouchscreenByIdentifier( const TouchDeviceIdentifier& identifier) { const std::vector<ui::TouchscreenDevice>& touchscreens = - ui::InputDeviceManager::GetInstance()->GetTouchscreenDevices(); + ui::DeviceDataManager::GetInstance()->GetTouchscreenDevices(); for (const auto& touchscreen : touchscreens) { if (TouchDeviceIdentifier::FromDevice(touchscreen) == identifier) return touchscreen; diff --git a/chromium/ui/display/mojo/typemaps.gni b/chromium/ui/display/mojo/typemaps.gni deleted file mode 100644 index e352a04421f..00000000000 --- a/chromium/ui/display/mojo/typemaps.gni +++ /dev/null @@ -1,12 +0,0 @@ -# Copyright 2016 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. - -typemaps = [ - "//ui/display/mojo/display.typemap", - "//ui/display/mojo/display_constants.typemap", - "//ui/display/mojo/display_layout.typemap", - "//ui/display/mojo/display_mode.typemap", - "//ui/display/mojo/display_snapshot.typemap", - "//ui/display/mojo/gamma_ramp_rgb_entry.typemap", -] diff --git a/chromium/ui/display/mojo/BUILD.gn b/chromium/ui/display/mojom/BUILD.gn index c60046c3aea..fb7b96492c8 100644 --- a/chromium/ui/display/mojo/BUILD.gn +++ b/chromium/ui/display/mojom/BUILD.gn @@ -4,7 +4,7 @@ import("//mojo/public/tools/bindings/mojom.gni") -mojom("interfaces") { +mojom("mojom") { sources = [ "display.mojom", "display_constants.mojom", diff --git a/chromium/ui/display/mojo/OWNERS b/chromium/ui/display/mojom/OWNERS index e75daf744a0..7ed4e44a4d5 100644 --- a/chromium/ui/display/mojo/OWNERS +++ b/chromium/ui/display/mojom/OWNERS @@ -1,5 +1,5 @@ -per-file *_struct_traits*.*=set noparent -per-file *_struct_traits*.*=file://ipc/SECURITY_OWNERS +per-file *_mojom_traits*.*=set noparent +per-file *_mojom_traits*.*=file://ipc/SECURITY_OWNERS per-file *.mojom=set noparent per-file *.mojom=file://ipc/SECURITY_OWNERS diff --git a/chromium/ui/display/mojo/display.mojom b/chromium/ui/display/mojom/display.mojom index fbcfbad56be..fbcfbad56be 100644 --- a/chromium/ui/display/mojo/display.mojom +++ b/chromium/ui/display/mojom/display.mojom diff --git a/chromium/ui/display/mojo/display.typemap b/chromium/ui/display/mojom/display.typemap index 7bf184fbe3d..0625a2e0d1b 100644 --- a/chromium/ui/display/mojo/display.typemap +++ b/chromium/ui/display/mojom/display.typemap @@ -2,11 +2,11 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -mojom = "//ui/display/mojo/display.mojom" +mojom = "//ui/display/mojom/display.mojom" public_headers = [ "//ui/display/display.h" ] -traits_headers = [ "//ui/display/mojo/display_struct_traits.h" ] +traits_headers = [ "//ui/display/mojom/display_mojom_traits.h" ] sources = [ - "//ui/display/mojo/display_struct_traits.cc", + "//ui/display/mojom/display_mojom_traits.cc", ] public_deps = [ "//ui/display", diff --git a/chromium/ui/display/mojo/display_constants.mojom b/chromium/ui/display/mojom/display_constants.mojom index a10d8d39f40..a10d8d39f40 100644 --- a/chromium/ui/display/mojo/display_constants.mojom +++ b/chromium/ui/display/mojom/display_constants.mojom diff --git a/chromium/ui/display/mojo/display_constants.typemap b/chromium/ui/display/mojom/display_constants.typemap index 4c0b4ae1b59..fcefbacf208 100644 --- a/chromium/ui/display/mojo/display_constants.typemap +++ b/chromium/ui/display/mojom/display_constants.typemap @@ -2,11 +2,11 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -mojom = "//ui/display/mojo/display_constants.mojom" +mojom = "//ui/display/mojom/display_constants.mojom" public_headers = [ "//ui/display/types/display_constants.h" ] -traits_headers = [ "//ui/display/mojo/display_constants_struct_traits.h" ] +traits_headers = [ "//ui/display/mojom/display_constants_mojom_traits.h" ] sources = [ - "//ui/display/mojo/display_constants_struct_traits.cc", + "//ui/display/mojom/display_constants_mojom_traits.cc", ] public_deps = [ "//ui/display", diff --git a/chromium/ui/display/mojo/display_constants_struct_traits.cc b/chromium/ui/display/mojom/display_constants_mojom_traits.cc index c5cc01342d5..a34a657dcbe 100644 --- a/chromium/ui/display/mojo/display_constants_struct_traits.cc +++ b/chromium/ui/display/mojom/display_constants_mojom_traits.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ui/display/mojo/display_constants_struct_traits.h" +#include "ui/display/mojom/display_constants_mojom_traits.h" namespace mojo { diff --git a/chromium/ui/display/mojo/display_constants_struct_traits.h b/chromium/ui/display/mojom/display_constants_mojom_traits.h index 9ecf7ccebf5..24ab48db219 100644 --- a/chromium/ui/display/mojo/display_constants_struct_traits.h +++ b/chromium/ui/display/mojom/display_constants_mojom_traits.h @@ -2,10 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef UI_DISPLAY_MOJO_DISPLAY_CONSTANTS_STRUCT_TRAITS_H_ -#define UI_DISPLAY_MOJO_DISPLAY_CONSTANTS_STRUCT_TRAITS_H_ +#ifndef UI_DISPLAY_MOJOM_DISPLAY_CONSTANTS_MOJOM_TRAITS_H_ +#define UI_DISPLAY_MOJOM_DISPLAY_CONSTANTS_MOJOM_TRAITS_H_ -#include "ui/display/mojo/display_constants.mojom.h" +#include "ui/display/mojom/display_constants.mojom.h" #include "ui/display/types/display_constants.h" namespace mojo { @@ -28,4 +28,4 @@ struct EnumTraits<display::mojom::HDCPState, display::HDCPState> { } // namespace mojo -#endif // UI_DISPLAY_MOJO_DISPLAY_CONSTANTS_STRUCT_TRAITS_H_ +#endif // UI_DISPLAY_MOJOM_DISPLAY_CONSTANTS_MOJOM_TRAITS_H_ diff --git a/chromium/ui/display/mojo/display_layout.mojom b/chromium/ui/display/mojom/display_layout.mojom index 77d3c50b26f..77d3c50b26f 100644 --- a/chromium/ui/display/mojo/display_layout.mojom +++ b/chromium/ui/display/mojom/display_layout.mojom diff --git a/chromium/ui/display/mojo/display_layout.typemap b/chromium/ui/display/mojom/display_layout.typemap index d524e562019..652ffb2c315 100644 --- a/chromium/ui/display/mojo/display_layout.typemap +++ b/chromium/ui/display/mojom/display_layout.typemap @@ -2,11 +2,11 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -mojom = "//ui/display/mojo/display_layout.mojom" +mojom = "//ui/display/mojom/display_layout.mojom" public_headers = [ "//ui/display/display_layout.h" ] -traits_headers = [ "//ui/display/mojo/display_layout_struct_traits.h" ] +traits_headers = [ "//ui/display/mojom/display_layout_mojom_traits.h" ] sources = [ - "//ui/display/mojo/display_layout_struct_traits.cc", + "//ui/display/mojom/display_layout_mojom_traits.cc", ] public_deps = [ "//ui/display", diff --git a/chromium/ui/display/mojo/display_layout_struct_traits.cc b/chromium/ui/display/mojom/display_layout_mojom_traits.cc index 24a9d8774de..af247ab1111 100644 --- a/chromium/ui/display/mojo/display_layout_struct_traits.cc +++ b/chromium/ui/display/mojom/display_layout_mojom_traits.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ui/display/mojo/display_layout_struct_traits.h" +#include "ui/display/mojom/display_layout_mojom_traits.h" namespace mojo { diff --git a/chromium/ui/display/mojo/display_layout_struct_traits.h b/chromium/ui/display/mojom/display_layout_mojom_traits.h index 45b109ad589..cf161dc4684 100644 --- a/chromium/ui/display/mojo/display_layout_struct_traits.h +++ b/chromium/ui/display/mojom/display_layout_mojom_traits.h @@ -2,14 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef UI_DISPLAY_MOJO_DISPLAY_LAYOUT_STRUCT_TRAITS_H_ -#define UI_DISPLAY_MOJO_DISPLAY_LAYOUT_STRUCT_TRAITS_H_ +#ifndef UI_DISPLAY_MOJOM_DISPLAY_LAYOUT_MOJOM_TRAITS_H_ +#define UI_DISPLAY_MOJOM_DISPLAY_LAYOUT_MOJOM_TRAITS_H_ #include <memory> #include <vector> #include "ui/display/display_layout.h" -#include "ui/display/mojo/display_layout.mojom.h" +#include "ui/display/mojom/display_layout.mojom.h" namespace mojo { @@ -84,4 +84,4 @@ struct StructTraits<display::mojom::DisplayLayoutDataView, } // namespace mojo -#endif // UI_DISPLAY_MOJO_DISPLAY_LAYOUT_STRUCT_TRAITS_H_ +#endif // UI_DISPLAY_MOJOM_DISPLAY_MOJOM_TRAITS_H_ diff --git a/chromium/ui/display/mojo/display_mode.mojom b/chromium/ui/display/mojom/display_mode.mojom index 892521ca79b..892521ca79b 100644 --- a/chromium/ui/display/mojo/display_mode.mojom +++ b/chromium/ui/display/mojom/display_mode.mojom diff --git a/chromium/ui/display/mojo/display_mode.typemap b/chromium/ui/display/mojom/display_mode.typemap index fc1f37d4174..3cbe5f3a475 100644 --- a/chromium/ui/display/mojo/display_mode.typemap +++ b/chromium/ui/display/mojom/display_mode.typemap @@ -2,11 +2,11 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -mojom = "//ui/display/mojo/display_mode.mojom" +mojom = "//ui/display/mojom/display_mode.mojom" public_headers = [ "//ui/display/types/display_mode.h" ] -traits_headers = [ "//ui/display/mojo/display_mode_struct_traits.h" ] +traits_headers = [ "//ui/display/mojom/display_mode_mojom_traits.h" ] sources = [ - "//ui/display/mojo/display_mode_struct_traits.cc", + "//ui/display/mojom/display_mode_mojom_traits.cc", ] public_deps = [ "//ui/display", @@ -14,4 +14,6 @@ public_deps = [ deps = [ "//ui/gfx/geometry", ] -type_mappings = [ "display.mojom.DisplayMode=std::unique_ptr<display::DisplayMode>[move_only]" ] +type_mappings = [ + "display.mojom.DisplayMode=std::unique_ptr<display::DisplayMode>[move_only]", +] diff --git a/chromium/ui/display/mojo/display_mode_struct_traits.cc b/chromium/ui/display/mojom/display_mode_mojom_traits.cc index 7c65a2dce67..688d4350dfe 100644 --- a/chromium/ui/display/mojo/display_mode_struct_traits.cc +++ b/chromium/ui/display/mojom/display_mode_mojom_traits.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ui/display/mojo/display_mode_struct_traits.h" +#include "ui/display/mojom/display_mode_mojom_traits.h" #include "ui/gfx/geometry/mojo/geometry_struct_traits.h" diff --git a/chromium/ui/display/mojo/display_mode_struct_traits.h b/chromium/ui/display/mojom/display_mode_mojom_traits.h index 2990846de19..a47c72a7a0a 100644 --- a/chromium/ui/display/mojo/display_mode_struct_traits.h +++ b/chromium/ui/display/mojom/display_mode_mojom_traits.h @@ -2,11 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef UI_DISPLAY_MOJO_DISPLAY_MODE_STRUCT_TRAITS_H_ -#define UI_DISPLAY_MOJO_DISPLAY_MODE_STRUCT_TRAITS_H_ +#ifndef UI_DISPLAY_MOJOM_DISPLAY_MODE_MOJOM_TRAITS_H_ +#define UI_DISPLAY_MOJOM_DISPLAY_MODE_MOJOM_TRAITS_H_ +#include "ui/display/mojom/display_mode.mojom.h" #include "ui/display/types/display_mode.h" -#include "ui/display/mojo/display_mode.mojom.h" #include "ui/gfx/geometry/size.h" namespace mojo { @@ -35,4 +35,4 @@ struct StructTraits<display::mojom::DisplayModeDataView, } // namespace mojo -#endif // UI_DISPLAY_MOJO_DISPLAY_MODE_STRUCT_TRAITS_H_ +#endif // UI_DISPLAY_MOJOM_DISPLAY_MODE_MOJOM_TRAITS_H_ diff --git a/chromium/ui/display/mojo/display_struct_traits.cc b/chromium/ui/display/mojom/display_mojom_traits.cc index acbcaabacff..0df6fc4a387 100644 --- a/chromium/ui/display/mojo/display_struct_traits.cc +++ b/chromium/ui/display/mojom/display_mojom_traits.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ui/display/mojo/display_struct_traits.h" +#include "ui/display/mojom/display_mojom_traits.h" namespace mojo { diff --git a/chromium/ui/display/mojo/display_struct_traits.h b/chromium/ui/display/mojom/display_mojom_traits.h index 055cd8b8d4d..2937b93627e 100644 --- a/chromium/ui/display/mojo/display_struct_traits.h +++ b/chromium/ui/display/mojom/display_mojom_traits.h @@ -2,11 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef UI_DISPLAY_MOJO_DISPLAY_STRUCT_TRAITS_H_ -#define UI_DISPLAY_MOJO_DISPLAY_STRUCT_TRAITS_H_ +#ifndef UI_DISPLAY_MOJOM_DISPLAY_MOJOM_TRAITS_H_ +#define UI_DISPLAY_MOJOM_DISPLAY_MOJOM_TRAITS_H_ #include "ui/display/display.h" -#include "ui/display/mojo/display.mojom.h" +#include "ui/display/mojom/display.mojom.h" #include "ui/gfx/geometry/mojo/geometry_struct_traits.h" namespace mojo { @@ -95,4 +95,4 @@ struct StructTraits<display::mojom::DisplayDataView, display::Display> { } // namespace mojo -#endif // UI_DISPLAY_MOJO_DISPLAY_STRUCT_TRAITS_H_ +#endif // UI_DISPLAY_MOJOM_DISPLAY_MOJOM_TRAITS_H_ diff --git a/chromium/ui/display/mojo/display_struct_traits_unittest.cc b/chromium/ui/display/mojom/display_mojom_traits_unittest.cc index b4c0b3ba013..5038f2a2664 100644 --- a/chromium/ui/display/mojo/display_struct_traits_unittest.cc +++ b/chromium/ui/display/mojom/display_mojom_traits_unittest.cc @@ -12,11 +12,11 @@ #include "testing/gtest/include/gtest/gtest.h" #include "ui/display/display.h" #include "ui/display/display_layout.h" -#include "ui/display/mojo/display_layout_struct_traits.h" -#include "ui/display/mojo/display_mode_struct_traits.h" -#include "ui/display/mojo/display_snapshot_struct_traits.h" -#include "ui/display/mojo/display_struct_traits.h" -#include "ui/display/mojo/gamma_ramp_rgb_entry_struct_traits.h" +#include "ui/display/mojom/display_layout_mojom_traits.h" +#include "ui/display/mojom/display_mode_mojom_traits.h" +#include "ui/display/mojom/display_mojom_traits.h" +#include "ui/display/mojom/display_snapshot_mojom_traits.h" +#include "ui/display/mojom/gamma_ramp_rgb_entry_mojom_traits.h" #include "ui/display/types/display_constants.h" #include "ui/display/types/display_mode.h" #include "ui/display/types/display_snapshot.h" diff --git a/chromium/ui/display/mojo/display_rotation_for_blink.typemap b/chromium/ui/display/mojom/display_rotation_for_blink.typemap index 9e8394befaa..78d24b3653a 100644 --- a/chromium/ui/display/mojo/display_rotation_for_blink.typemap +++ b/chromium/ui/display/mojom/display_rotation_for_blink.typemap @@ -2,11 +2,11 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -mojom = "//ui/display/mojo/display.mojom" +mojom = "//ui/display/mojom/display.mojom" public_headers = [ "//ui/display/display.h" ] -traits_headers = [ "//ui/display/mojo/display_struct_traits.h" ] +traits_headers = [ "//ui/display/mojom/display_mojom_traits.h" ] public_deps = [ "//ui/display", - "//ui/display/mojo:interfaces", + "//ui/display/mojom:mojom", ] type_mappings = [ "display.mojom.Rotation=display::Display::Rotation" ] diff --git a/chromium/ui/display/mojo/display_snapshot.mojom b/chromium/ui/display/mojom/display_snapshot.mojom index 9c358b50662..95c32cb9711 100644 --- a/chromium/ui/display/mojo/display_snapshot.mojom +++ b/chromium/ui/display/mojom/display_snapshot.mojom @@ -5,8 +5,8 @@ module display.mojom; import "mojo/public/mojom/base/file_path.mojom"; -import "ui/display/mojo/display_constants.mojom"; -import "ui/display/mojo/display_mode.mojom"; +import "ui/display/mojom/display_constants.mojom"; +import "ui/display/mojom/display_mode.mojom"; import "ui/gfx/geometry/mojo/geometry.mojom"; import "ui/gfx/mojo/color_space.mojom"; diff --git a/chromium/ui/display/mojo/display_snapshot.typemap b/chromium/ui/display/mojom/display_snapshot.typemap index 4668070524a..f9d8d0767a1 100644 --- a/chromium/ui/display/mojo/display_snapshot.typemap +++ b/chromium/ui/display/mojom/display_snapshot.typemap @@ -2,11 +2,11 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -mojom = "//ui/display/mojo/display_snapshot.mojom" +mojom = "//ui/display/mojom/display_snapshot.mojom" public_headers = [ "//ui/display/types/display_snapshot.h" ] -traits_headers = [ "//ui/display/mojo/display_snapshot_struct_traits.h" ] +traits_headers = [ "//ui/display/mojom/display_snapshot_mojom_traits.h" ] sources = [ - "//ui/display/mojo/display_snapshot_struct_traits.cc", + "//ui/display/mojom/display_snapshot_mojom_traits.cc", ] public_deps = [ "//ui/display", diff --git a/chromium/ui/display/mojo/display_snapshot_struct_traits.cc b/chromium/ui/display/mojom/display_snapshot_mojom_traits.cc index 21eb7044ab0..0c5373e029f 100644 --- a/chromium/ui/display/mojo/display_snapshot_struct_traits.cc +++ b/chromium/ui/display/mojom/display_snapshot_mojom_traits.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ui/display/mojo/display_snapshot_struct_traits.h" +#include "ui/display/mojom/display_snapshot_mojom_traits.h" #include "mojo/public/cpp/base/file_path_mojom_traits.h" #include "ui/display/types/display_constants.h" diff --git a/chromium/ui/display/mojo/display_snapshot_struct_traits.h b/chromium/ui/display/mojom/display_snapshot_mojom_traits.h index 0267d56c15b..55c15799f9b 100644 --- a/chromium/ui/display/mojo/display_snapshot_struct_traits.h +++ b/chromium/ui/display/mojom/display_snapshot_mojom_traits.h @@ -2,13 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef UI_DISPLAY_MOJO_DISPLAY_SNAPSHOT_MOJO_STRUCT_TRAITS_H_ -#define UI_DISPLAY_MOJO_DISPLAY_SNAPSHOT_MOJO_STRUCT_TRAITS_H_ +#ifndef UI_DISPLAY_MOJOM_DISPLAY_SNAPSHOT_MOJOM_TRAITS_H_ +#define UI_DISPLAY_MOJOM_DISPLAY_SNAPSHOT_MOJOM_TRAITS_H_ #include "ipc/ipc_message_utils.h" -#include "ui/display/mojo/display_constants_struct_traits.h" -#include "ui/display/mojo/display_mode_struct_traits.h" -#include "ui/display/mojo/display_snapshot.mojom.h" +#include "ui/display/mojom/display_constants_mojom_traits.h" +#include "ui/display/mojom/display_mode_mojom_traits.h" +#include "ui/display/mojom/display_snapshot.mojom.h" #include "ui/display/types/display_mode.h" #include "ui/display/types/display_snapshot.h" #include "ui/gfx/geometry/mojo/geometry_struct_traits.h" @@ -119,4 +119,4 @@ struct StructTraits<display::mojom::DisplaySnapshotDataView, } // namespace mojo -#endif // UI_DISPLAY_MOJO_DISPLAY_SNAPSHOT_MOJO_STRUCT_TRAITS_H_ +#endif // UI_DISPLAY_MOJOM_DISPLAY_SNAPSHOT_MOJOM_TRAITS_H_ diff --git a/chromium/ui/display/mojo/gamma_ramp_rgb_entry.mojom b/chromium/ui/display/mojom/gamma_ramp_rgb_entry.mojom index db2d7ed3a7f..db2d7ed3a7f 100644 --- a/chromium/ui/display/mojo/gamma_ramp_rgb_entry.mojom +++ b/chromium/ui/display/mojom/gamma_ramp_rgb_entry.mojom diff --git a/chromium/ui/display/mojo/gamma_ramp_rgb_entry.typemap b/chromium/ui/display/mojom/gamma_ramp_rgb_entry.typemap index 2618fe9da0f..d93d295e322 100644 --- a/chromium/ui/display/mojo/gamma_ramp_rgb_entry.typemap +++ b/chromium/ui/display/mojom/gamma_ramp_rgb_entry.typemap @@ -2,11 +2,11 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -mojom = "//ui/display/mojo/gamma_ramp_rgb_entry.mojom" +mojom = "//ui/display/mojom/gamma_ramp_rgb_entry.mojom" public_headers = [ "//ui/display/types/gamma_ramp_rgb_entry.h" ] -traits_headers = [ "//ui/display/mojo/gamma_ramp_rgb_entry_struct_traits.h" ] +traits_headers = [ "//ui/display/mojom/gamma_ramp_rgb_entry_mojom_traits.h" ] sources = [ - "//ui/display/mojo/gamma_ramp_rgb_entry_struct_traits.cc", + "//ui/display/mojom/gamma_ramp_rgb_entry_mojom_traits.cc", ] public_deps = [ "//ui/display", diff --git a/chromium/ui/display/mojo/gamma_ramp_rgb_entry_struct_traits.cc b/chromium/ui/display/mojom/gamma_ramp_rgb_entry_mojom_traits.cc index 6ac8ecbcc63..19a34fc53be 100644 --- a/chromium/ui/display/mojo/gamma_ramp_rgb_entry_struct_traits.cc +++ b/chromium/ui/display/mojom/gamma_ramp_rgb_entry_mojom_traits.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ui/display/mojo/gamma_ramp_rgb_entry_struct_traits.h" +#include "ui/display/mojom/gamma_ramp_rgb_entry_mojom_traits.h" namespace mojo { diff --git a/chromium/ui/display/mojo/gamma_ramp_rgb_entry_struct_traits.h b/chromium/ui/display/mojom/gamma_ramp_rgb_entry_mojom_traits.h index 68c19f545e4..30c4c1a39fa 100644 --- a/chromium/ui/display/mojo/gamma_ramp_rgb_entry_struct_traits.h +++ b/chromium/ui/display/mojom/gamma_ramp_rgb_entry_mojom_traits.h @@ -2,10 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef UI_DISPLAY_MOJO_GAMMA_RAMP_RGB_ENTRY_STRUCT_TRAITS_H_ -#define UI_DISPLAY_MOJO_GAMMA_RAMP_RGB_ENTRY_STRUCT_TRAITS_H_ +#ifndef UI_DISPLAY_MOJOM_GAMMA_RAMP_RGB_ENTRY_MOJOM_TRAITS_H_ +#define UI_DISPLAY_MOJOM_GAMMA_RAMP_RGB_ENTRY_MOJOM_TRAITS_H_ -#include "ui/display/mojo/gamma_ramp_rgb_entry.mojom.h" +#include "ui/display/mojom/gamma_ramp_rgb_entry.mojom.h" #include "ui/display/types/gamma_ramp_rgb_entry.h" namespace mojo { @@ -31,4 +31,4 @@ struct StructTraits<display::mojom::GammaRampRGBEntryDataView, } // namespace mojo -#endif // UI_DISPLAY_MOJO_GAMMA_RAMP_RGB_ENTRY_STRUCT_TRAITS_H_ +#endif // UI_DISPLAY_MOJOM_GAMMA_RAMP_RGB_ENTRY_MOJOM_TRAITS_H_ diff --git a/chromium/ui/display/mojom/typemaps.gni b/chromium/ui/display/mojom/typemaps.gni new file mode 100644 index 00000000000..1cbc47b18ee --- /dev/null +++ b/chromium/ui/display/mojom/typemaps.gni @@ -0,0 +1,12 @@ +# Copyright 2016 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. + +typemaps = [ + "//ui/display/mojom/display.typemap", + "//ui/display/mojom/display_constants.typemap", + "//ui/display/mojom/display_layout.typemap", + "//ui/display/mojom/display_mode.typemap", + "//ui/display/mojom/display_snapshot.typemap", + "//ui/display/mojom/gamma_ramp_rgb_entry.typemap", +] diff --git a/chromium/ui/display/unified_desktop_utils.cc b/chromium/ui/display/unified_desktop_utils.cc index 6a0da75f127..5016514dc67 100644 --- a/chromium/ui/display/unified_desktop_utils.cc +++ b/chromium/ui/display/unified_desktop_utils.cc @@ -204,7 +204,7 @@ bool BuildUnifiedDesktopMatrix(const DisplayIdList& ids_list, const DisplayLayout& layout, UnifiedDesktopLayoutMatrix* out_matrix) { // The primary display should be in the IDs list. - if (!base::ContainsValue(ids_list, layout.primary_id)) { + if (!base::Contains(ids_list, layout.primary_id)) { LOG(ERROR) << "The primary ID: " << layout.primary_id << " is not in the IDs list."; return false; @@ -259,13 +259,13 @@ bool BuildUnifiedDesktopMatrix(const DisplayIdList& ids_list, LOG(ERROR) << "display_id must not be the same as parent_display_id"; return false; } - if (!base::ContainsValue(ids_list, placement.display_id)) { + if (!base::Contains(ids_list, placement.display_id)) { LOG(ERROR) << "display_id: " << placement.display_id << " is not in the id list: " << placement.ToString(); return false; } - if (!base::ContainsValue(ids_list, placement.parent_display_id)) { + if (!base::Contains(ids_list, placement.parent_display_id)) { LOG(ERROR) << "parent_display_id: " << placement.parent_display_id << " is not in the id list: " << placement.ToString(); return false; diff --git a/chromium/ui/display/win/screen_win.cc b/chromium/ui/display/win/screen_win.cc index 0998b147fa0..200c33684eb 100644 --- a/chromium/ui/display/win/screen_win.cc +++ b/chromium/ui/display/win/screen_win.cc @@ -724,8 +724,10 @@ void ScreenWin::OnWndProc(HWND hwnd, WPARAM wparam, LPARAM lparam) { if (message != WM_DISPLAYCHANGE && - !(message == WM_SETTINGCHANGE && wparam == SPI_SETWORKAREA)) + !(message == WM_ACTIVATEAPP && wparam == TRUE) && + !(message == WM_SETTINGCHANGE && wparam == SPI_SETWORKAREA)) { return; + } color_profile_reader_->UpdateIfNeeded(); if (request_hdr_status_callback_) @@ -850,7 +852,7 @@ void ScreenWin::RecordDisplayScaleFactors() const { // it so that if it's wildly out-of-band we won't send it to the backend. const int reported_scale = std::min( std::max(base::checked_cast<int>(scale_factor * 100), 0), 1000); - if (!base::ContainsValue(unique_scale_factors, reported_scale)) { + if (!base::Contains(unique_scale_factors, reported_scale)) { unique_scale_factors.push_back(reported_scale); base::UmaHistogramSparse("UI.DeviceScale", reported_scale); } |