Supervised user whitelists: Cleanup
[chromium-blink-merge.git] / ui / display / chromeos / apply_content_protection_task.cc
blobe25d4277d05e78b124558ebe9e31a2ceba14d3c1
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ui/display/chromeos/apply_content_protection_task.h"
7 #include "ui/display/chromeos/display_layout_manager.h"
8 #include "ui/display/types/display_snapshot.h"
9 #include "ui/display/types/native_display_delegate.h"
11 namespace ui {
13 namespace {
15 bool GetHDCPCapableDisplays(
16 const DisplayLayoutManager& layout_manager,
17 std::vector<DisplaySnapshot*>* hdcp_capable_displays) {
18 for (DisplaySnapshot* display : layout_manager.GetDisplayStates()) {
19 switch (display->type()) {
20 case DISPLAY_CONNECTION_TYPE_UNKNOWN:
21 return false;
22 // DisplayPort, DVI, and HDMI all support HDCP.
23 case DISPLAY_CONNECTION_TYPE_DISPLAYPORT:
24 case DISPLAY_CONNECTION_TYPE_DVI:
25 case DISPLAY_CONNECTION_TYPE_HDMI:
26 hdcp_capable_displays->push_back(display);
27 break;
28 case DISPLAY_CONNECTION_TYPE_INTERNAL:
29 case DISPLAY_CONNECTION_TYPE_VGA:
30 case DISPLAY_CONNECTION_TYPE_NETWORK:
31 // No protections for these types. Do nothing.
32 break;
33 case DISPLAY_CONNECTION_TYPE_NONE:
34 NOTREACHED();
35 break;
39 return true;
42 } // namespace
44 ApplyContentProtectionTask::ApplyContentProtectionTask(
45 DisplayLayoutManager* layout_manager,
46 NativeDisplayDelegate* native_display_delegate,
47 const DisplayConfigurator::ContentProtections& requests,
48 const ResponseCallback& callback)
49 : layout_manager_(layout_manager),
50 native_display_delegate_(native_display_delegate),
51 requests_(requests),
52 callback_(callback),
53 query_status_(true),
54 pending_requests_(0),
55 weak_ptr_factory_(this) {
58 ApplyContentProtectionTask::~ApplyContentProtectionTask() {
61 void ApplyContentProtectionTask::Run() {
62 std::vector<DisplaySnapshot*> hdcp_capable_displays;
63 if (!GetHDCPCapableDisplays(*layout_manager_, &hdcp_capable_displays)) {
64 callback_.Run(false);
65 return;
68 pending_requests_ = hdcp_capable_displays.size();
69 if (pending_requests_ == 0) {
70 callback_.Run(true);
71 return;
74 // Need to poll the driver for updates since other applications may have
75 // updated the state.
76 for (DisplaySnapshot* display : hdcp_capable_displays) {
77 native_display_delegate_->GetHDCPState(
78 *display,
79 base::Bind(&ApplyContentProtectionTask::OnHDCPStateUpdate,
80 weak_ptr_factory_.GetWeakPtr(), display->display_id()));
84 void ApplyContentProtectionTask::OnHDCPStateUpdate(int64_t display_id,
85 bool success,
86 HDCPState state) {
87 query_status_ &= success;
88 display_hdcp_state_map_[display_id] = state;
89 pending_requests_--;
91 // Wait for all the requests before continuing.
92 if (pending_requests_ != 0)
93 return;
95 if (!query_status_) {
96 callback_.Run(false);
97 return;
100 ApplyProtections();
103 void ApplyContentProtectionTask::ApplyProtections() {
104 std::vector<DisplaySnapshot*> hdcp_capable_displays;
105 if (!GetHDCPCapableDisplays(*layout_manager_, &hdcp_capable_displays)) {
106 callback_.Run(false);
107 return;
110 std::vector<std::pair<DisplaySnapshot*, HDCPState>> hdcp_requests;
111 // Figure out which displays need to have their HDCP state changed.
112 for (DisplaySnapshot* display : hdcp_capable_displays) {
113 uint32_t desired_mask = GetDesiredProtectionMask(display->display_id());
115 auto it = display_hdcp_state_map_.find(display->display_id());
116 // If the display can't be found, the display configuration changed.
117 if (it == display_hdcp_state_map_.end()) {
118 callback_.Run(false);
119 return;
122 bool hdcp_enabled = it->second != HDCP_STATE_UNDESIRED;
123 bool hdcp_requested = desired_mask & CONTENT_PROTECTION_METHOD_HDCP;
124 if (hdcp_enabled != hdcp_requested) {
125 hdcp_requests.push_back(std::make_pair(
126 display, hdcp_requested ? HDCP_STATE_DESIRED : HDCP_STATE_UNDESIRED));
130 pending_requests_ = hdcp_requests.size();
131 // All the requested changes are the same as the current HDCP state. Nothing
132 // to do anymore, just ack the content protection change.
133 if (pending_requests_ == 0) {
134 callback_.Run(true);
135 return;
138 for (const auto& pair : hdcp_requests) {
139 native_display_delegate_->SetHDCPState(
140 *pair.first, pair.second,
141 base::Bind(&ApplyContentProtectionTask::OnHDCPStateApplied,
142 weak_ptr_factory_.GetWeakPtr()));
146 void ApplyContentProtectionTask::OnHDCPStateApplied(bool success) {
147 query_status_ &= success;
148 pending_requests_--;
150 if (pending_requests_ == 0)
151 callback_.Run(query_status_);
154 uint32_t ApplyContentProtectionTask::GetDesiredProtectionMask(
155 int64_t display_id) const {
156 uint32_t desired_mask = 0;
157 // In mirror mode, protection request of all displays need to be fulfilled.
158 // In non-mirror mode, only request of client's display needs to be
159 // fulfilled.
160 if (layout_manager_->IsMirroring()) {
161 for (auto pair : requests_)
162 desired_mask |= pair.second;
163 } else {
164 auto it = requests_.find(display_id);
165 if (it != requests_.end())
166 desired_mask = it->second;
169 return desired_mask;
172 } // namespace ui