OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chromeos/display/output_configurator.h" | 5 #include "chromeos/display/output_configurator.h" |
6 | 6 |
7 #include <cstdarg> | 7 #include <cstdarg> |
8 #include <map> | 8 #include <map> |
9 #include <string> | 9 #include <string> |
10 #include <vector> | 10 #include <vector> |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
65 } | 65 } |
66 | 66 |
67 // Returns a string describing a TestDelegate::ConfigureCTM() call. | 67 // Returns a string describing a TestDelegate::ConfigureCTM() call. |
68 std::string GetCTMAction( | 68 std::string GetCTMAction( |
69 int device_id, | 69 int device_id, |
70 const OutputConfigurator::CoordinateTransformation& ctm) { | 70 const OutputConfigurator::CoordinateTransformation& ctm) { |
71 return base::StringPrintf("ctm(id=%d,transform=(%f,%f,%f,%f))", device_id, | 71 return base::StringPrintf("ctm(id=%d,transform=(%f,%f,%f,%f))", device_id, |
72 ctm.x_scale, ctm.x_offset, ctm.y_scale, ctm.y_offset); | 72 ctm.x_scale, ctm.x_offset, ctm.y_scale, ctm.y_offset); |
73 } | 73 } |
74 | 74 |
| 75 // Returns a string describing a TestDelegate::SetHDCPState() call. |
| 76 std::string GetSetHDCPStateAction(RROutput id, HDCPState state) { |
| 77 return base::StringPrintf("set_hdcp(id=%lu,state=%d)", id, state); |
| 78 } |
| 79 |
75 // Joins a sequence of strings describing actions (e.g. kScreenDim) such | 80 // Joins a sequence of strings describing actions (e.g. kScreenDim) such |
76 // that they can be compared against a string returned by | 81 // that they can be compared against a string returned by |
77 // TestDelegate::GetActionsAndClear(). The list of actions must be | 82 // TestDelegate::GetActionsAndClear(). The list of actions must be |
78 // terminated by a NULL pointer. | 83 // terminated by a NULL pointer. |
79 std::string JoinActions(const char* action, ...) { | 84 std::string JoinActions(const char* action, ...) { |
80 std::string actions; | 85 std::string actions; |
81 | 86 |
82 va_list arg_list; | 87 va_list arg_list; |
83 va_start(arg_list, action); | 88 va_start(arg_list, action); |
84 while (action) { | 89 while (action) { |
85 if (!actions.empty()) | 90 if (!actions.empty()) |
86 actions += ","; | 91 actions += ","; |
87 actions += action; | 92 actions += action; |
88 action = va_arg(arg_list, const char*); | 93 action = va_arg(arg_list, const char*); |
89 } | 94 } |
90 va_end(arg_list); | 95 va_end(arg_list); |
91 return actions; | 96 return actions; |
92 } | 97 } |
93 | 98 |
94 class TestDelegate : public OutputConfigurator::Delegate { | 99 class TestDelegate : public OutputConfigurator::Delegate { |
95 public: | 100 public: |
96 static const int kXRandREventBase = 10; | 101 static const int kXRandREventBase = 10; |
97 | 102 |
98 TestDelegate() : configure_crtc_result_(true) {} | 103 TestDelegate() |
| 104 : configure_crtc_result_(true), |
| 105 hdcp_state_(HDCP_STATE_UNDESIRED) {} |
99 virtual ~TestDelegate() {} | 106 virtual ~TestDelegate() {} |
100 | 107 |
101 const std::vector<OutputConfigurator::OutputSnapshot>& outputs() const { | 108 const std::vector<OutputConfigurator::OutputSnapshot>& outputs() const { |
102 return outputs_; | 109 return outputs_; |
103 } | 110 } |
104 void set_outputs( | 111 void set_outputs( |
105 const std::vector<OutputConfigurator::OutputSnapshot>& outputs) { | 112 const std::vector<OutputConfigurator::OutputSnapshot>& outputs) { |
106 outputs_ = outputs; | 113 outputs_ = outputs; |
107 } | 114 } |
108 | 115 |
109 void set_configure_crtc_result(bool result) { | 116 void set_configure_crtc_result(bool result) { |
110 configure_crtc_result_ = result; | 117 configure_crtc_result_ = result; |
111 } | 118 } |
112 | 119 |
| 120 void set_hdcp_state(HDCPState state) { hdcp_state_ = state; } |
| 121 |
113 // Returns a comma-separated string describing the actions that were | 122 // Returns a comma-separated string describing the actions that were |
114 // requested since the previous call to GetActionsAndClear() (i.e. | 123 // requested since the previous call to GetActionsAndClear() (i.e. |
115 // results are non-repeatable). | 124 // results are non-repeatable). |
116 std::string GetActionsAndClear() { | 125 std::string GetActionsAndClear() { |
117 std::string actions = actions_; | 126 std::string actions = actions_; |
118 actions_.clear(); | 127 actions_.clear(); |
119 return actions; | 128 return actions; |
120 } | 129 } |
121 | 130 |
122 // OutputConfigurator::Delegate overrides: | 131 // OutputConfigurator::Delegate overrides: |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
161 virtual void ConfigureCTM( | 170 virtual void ConfigureCTM( |
162 int touch_device_id, | 171 int touch_device_id, |
163 const OutputConfigurator::CoordinateTransformation& ctm) OVERRIDE { | 172 const OutputConfigurator::CoordinateTransformation& ctm) OVERRIDE { |
164 AppendAction(GetCTMAction(touch_device_id, ctm)); | 173 AppendAction(GetCTMAction(touch_device_id, ctm)); |
165 } | 174 } |
166 virtual void SendProjectingStateToPowerManager(bool projecting) OVERRIDE { | 175 virtual void SendProjectingStateToPowerManager(bool projecting) OVERRIDE { |
167 AppendAction(projecting ? kProjectingOn : kProjectingOff); | 176 AppendAction(projecting ? kProjectingOn : kProjectingOff); |
168 } | 177 } |
169 | 178 |
170 virtual bool GetHDCPState(RROutput id, HDCPState* state) OVERRIDE { | 179 virtual bool GetHDCPState(RROutput id, HDCPState* state) OVERRIDE { |
| 180 *state = hdcp_state_; |
171 return true; | 181 return true; |
172 } | 182 } |
173 | 183 |
174 virtual bool SetHDCPState(RROutput id, HDCPState state) OVERRIDE { | 184 virtual bool SetHDCPState(RROutput id, HDCPState state) OVERRIDE { |
| 185 AppendAction(GetSetHDCPStateAction(id, state)); |
175 return true; | 186 return true; |
176 } | 187 } |
177 | 188 |
178 private: | 189 private: |
179 struct ModeDetails { | 190 struct ModeDetails { |
180 ModeDetails() : width(0), height(0), interlaced(false) {} | 191 ModeDetails() : width(0), height(0), interlaced(false) {} |
181 ModeDetails(int width, int height, bool interlaced) | 192 ModeDetails(int width, int height, bool interlaced) |
182 : width(width), | 193 : width(width), |
183 height(height), | 194 height(height), |
184 interlaced(interlaced) {} | 195 interlaced(interlaced) {} |
(...skipping 12 matching lines...) Expand all Loading... |
197 std::map<RRMode, ModeDetails> modes_; | 208 std::map<RRMode, ModeDetails> modes_; |
198 | 209 |
199 // Outputs to be returned by GetOutputs(). | 210 // Outputs to be returned by GetOutputs(). |
200 std::vector<OutputConfigurator::OutputSnapshot> outputs_; | 211 std::vector<OutputConfigurator::OutputSnapshot> outputs_; |
201 | 212 |
202 std::string actions_; | 213 std::string actions_; |
203 | 214 |
204 // Return value returned by ConfigureCrtc(). | 215 // Return value returned by ConfigureCrtc(). |
205 bool configure_crtc_result_; | 216 bool configure_crtc_result_; |
206 | 217 |
| 218 // Result value of GetHDCPState(). |
| 219 HDCPState hdcp_state_; |
| 220 |
207 DISALLOW_COPY_AND_ASSIGN(TestDelegate); | 221 DISALLOW_COPY_AND_ASSIGN(TestDelegate); |
208 }; | 222 }; |
209 | 223 |
210 class TestObserver : public OutputConfigurator::Observer { | 224 class TestObserver : public OutputConfigurator::Observer { |
211 public: | 225 public: |
212 explicit TestObserver(OutputConfigurator* configurator) | 226 explicit TestObserver(OutputConfigurator* configurator) |
213 : configurator_(configurator) { | 227 : configurator_(configurator) { |
214 Reset(); | 228 Reset(); |
215 configurator_->AddObserver(this); | 229 configurator_->AddObserver(this); |
216 } | 230 } |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
333 OutputConfigurator::ModeInfo big_mode_info; | 347 OutputConfigurator::ModeInfo big_mode_info; |
334 big_mode_info.width = kBigModeWidth; | 348 big_mode_info.width = kBigModeWidth; |
335 big_mode_info.height = kBigModeHeight; | 349 big_mode_info.height = kBigModeHeight; |
336 | 350 |
337 OutputConfigurator::OutputSnapshot* o = &outputs_[0]; | 351 OutputConfigurator::OutputSnapshot* o = &outputs_[0]; |
338 o->output = 1; | 352 o->output = 1; |
339 o->crtc = 10; | 353 o->crtc = 10; |
340 o->current_mode = kSmallModeId; | 354 o->current_mode = kSmallModeId; |
341 o->native_mode = kSmallModeId; | 355 o->native_mode = kSmallModeId; |
342 o->is_internal = true; | 356 o->is_internal = true; |
| 357 o->type = OUTPUT_TYPE_INTERNAL; |
343 o->is_aspect_preserving_scaling = true; | 358 o->is_aspect_preserving_scaling = true; |
344 o->mode_infos[kSmallModeId] = small_mode_info; | 359 o->mode_infos[kSmallModeId] = small_mode_info; |
345 o->has_display_id = true; | 360 o->has_display_id = true; |
346 o->index = 0; | 361 o->index = 0; |
347 | 362 |
348 o = &outputs_[1]; | 363 o = &outputs_[1]; |
349 o->output = 2; | 364 o->output = 2; |
350 o->crtc = 11; | 365 o->crtc = 11; |
351 o->current_mode = kBigModeId; | 366 o->current_mode = kBigModeId; |
352 o->native_mode = kBigModeId; | 367 o->native_mode = kBigModeId; |
353 o->is_internal = false; | 368 o->is_internal = false; |
| 369 o->type = OUTPUT_TYPE_HDMI; |
354 o->is_aspect_preserving_scaling = true; | 370 o->is_aspect_preserving_scaling = true; |
355 o->mode_infos[kSmallModeId] = small_mode_info; | 371 o->mode_infos[kSmallModeId] = small_mode_info; |
356 o->mode_infos[kBigModeId] = big_mode_info; | 372 o->mode_infos[kBigModeId] = big_mode_info; |
357 o->has_display_id = true; | 373 o->has_display_id = true; |
358 o->index = 1; | 374 o->index = 1; |
359 | 375 |
360 UpdateOutputs(2, false); | 376 UpdateOutputs(2, false); |
361 } | 377 } |
362 | 378 |
363 protected: | 379 protected: |
(...skipping 719 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1083 | 1099 |
1084 // Also check that the newly-added small mode is present in the internal | 1100 // Also check that the newly-added small mode is present in the internal |
1085 // snapshot that was passed to the observer (http://crbug.com/289159). | 1101 // snapshot that was passed to the observer (http://crbug.com/289159). |
1086 const OutputConfigurator::ModeInfo* info = OutputConfigurator::GetModeInfo( | 1102 const OutputConfigurator::ModeInfo* info = OutputConfigurator::GetModeInfo( |
1087 observer_.latest_outputs()[0], kSmallModeId); | 1103 observer_.latest_outputs()[0], kSmallModeId); |
1088 ASSERT_TRUE(info); | 1104 ASSERT_TRUE(info); |
1089 EXPECT_EQ(kSmallModeWidth, info->width); | 1105 EXPECT_EQ(kSmallModeWidth, info->width); |
1090 EXPECT_EQ(kSmallModeHeight, info->height); | 1106 EXPECT_EQ(kSmallModeHeight, info->height); |
1091 } | 1107 } |
1092 | 1108 |
| 1109 TEST_F(OutputConfiguratorTest, OutputProtection) { |
| 1110 configurator_.Init(false); |
| 1111 configurator_.Start(0); |
| 1112 EXPECT_NE(kNoActions, delegate_->GetActionsAndClear()); |
| 1113 |
| 1114 OutputConfigurator::OutputProtectionClientId id = |
| 1115 configurator_.RegisterOutputProtectionClient(); |
| 1116 EXPECT_NE(0u, id); |
| 1117 |
| 1118 // One output. |
| 1119 UpdateOutputs(1, true); |
| 1120 EXPECT_NE(kNoActions, delegate_->GetActionsAndClear()); |
| 1121 uint32_t link_mask = 0; |
| 1122 uint32_t protection_mask = 0; |
| 1123 EXPECT_TRUE(configurator_.QueryOutputProtectionStatus(id, &link_mask, |
| 1124 &protection_mask)); |
| 1125 EXPECT_EQ(static_cast<uint32_t>(OUTPUT_TYPE_INTERNAL), link_mask); |
| 1126 EXPECT_EQ(static_cast<uint32_t>(OUTPUT_PROTECTION_METHOD_NONE), |
| 1127 protection_mask); |
| 1128 EXPECT_EQ(kNoActions, delegate_->GetActionsAndClear()); |
| 1129 |
| 1130 // Two outputs. |
| 1131 UpdateOutputs(2, true); |
| 1132 EXPECT_NE(kNoActions, delegate_->GetActionsAndClear()); |
| 1133 EXPECT_TRUE(configurator_.QueryOutputProtectionStatus(id, &link_mask, |
| 1134 &protection_mask)); |
| 1135 EXPECT_EQ(static_cast<uint32_t>(OUTPUT_TYPE_INTERNAL | OUTPUT_TYPE_HDMI), |
| 1136 link_mask); |
| 1137 EXPECT_EQ(static_cast<uint32_t>(OUTPUT_PROTECTION_METHOD_NONE), |
| 1138 protection_mask); |
| 1139 EXPECT_EQ(kNoActions, delegate_->GetActionsAndClear()); |
| 1140 |
| 1141 EXPECT_TRUE( |
| 1142 configurator_.EnableOutputProtection(id, OUTPUT_PROTECTION_METHOD_HDCP)); |
| 1143 EXPECT_EQ(GetSetHDCPStateAction(outputs_[1].output, HDCP_STATE_DESIRED), |
| 1144 delegate_->GetActionsAndClear()); |
| 1145 |
| 1146 // Enable protection. |
| 1147 delegate_->set_hdcp_state(HDCP_STATE_ENABLED); |
| 1148 EXPECT_TRUE(configurator_.QueryOutputProtectionStatus(id, &link_mask, |
| 1149 &protection_mask)); |
| 1150 EXPECT_EQ(static_cast<uint32_t>(OUTPUT_TYPE_INTERNAL | OUTPUT_TYPE_HDMI), |
| 1151 link_mask); |
| 1152 EXPECT_EQ(static_cast<uint32_t>(OUTPUT_PROTECTION_METHOD_HDCP), |
| 1153 protection_mask); |
| 1154 EXPECT_EQ(kNoActions, delegate_->GetActionsAndClear()); |
| 1155 } |
| 1156 |
| 1157 TEST_F(OutputConfiguratorTest, OutputProtectionTwoClients) { |
| 1158 OutputConfigurator::OutputProtectionClientId client1 = |
| 1159 configurator_.RegisterOutputProtectionClient(); |
| 1160 OutputConfigurator::OutputProtectionClientId client2 = |
| 1161 configurator_.RegisterOutputProtectionClient(); |
| 1162 EXPECT_NE(client1, client2); |
| 1163 |
| 1164 configurator_.Init(false); |
| 1165 configurator_.Start(0); |
| 1166 UpdateOutputs(2, true); |
| 1167 EXPECT_NE(kNoActions, delegate_->GetActionsAndClear()); |
| 1168 |
| 1169 // Clients never know state enableness for methods that they didn't request. |
| 1170 EXPECT_TRUE( |
| 1171 configurator_.EnableOutputProtection(client1, |
| 1172 OUTPUT_PROTECTION_METHOD_HDCP)); |
| 1173 EXPECT_EQ(GetSetHDCPStateAction(outputs_[1].output, |
| 1174 HDCP_STATE_DESIRED).c_str(), |
| 1175 delegate_->GetActionsAndClear()); |
| 1176 delegate_->set_hdcp_state(HDCP_STATE_ENABLED); |
| 1177 |
| 1178 uint32_t link_mask = 0; |
| 1179 uint32_t protection_mask = 0; |
| 1180 EXPECT_TRUE(configurator_.QueryOutputProtectionStatus(client1, &link_mask, |
| 1181 &protection_mask)); |
| 1182 EXPECT_EQ(static_cast<uint32_t>(OUTPUT_TYPE_INTERNAL | OUTPUT_TYPE_HDMI), |
| 1183 link_mask); |
| 1184 EXPECT_EQ(OUTPUT_PROTECTION_METHOD_HDCP, protection_mask); |
| 1185 |
| 1186 EXPECT_TRUE(configurator_.QueryOutputProtectionStatus(client2, &link_mask, |
| 1187 &protection_mask)); |
| 1188 EXPECT_EQ(static_cast<uint32_t>(OUTPUT_TYPE_INTERNAL | OUTPUT_TYPE_HDMI), |
| 1189 link_mask); |
| 1190 EXPECT_EQ(OUTPUT_PROTECTION_METHOD_NONE, protection_mask); |
| 1191 |
| 1192 // Protections will be disabled only if no more clients request them. |
| 1193 EXPECT_TRUE( |
| 1194 configurator_.EnableOutputProtection(client2, |
| 1195 OUTPUT_PROTECTION_METHOD_NONE)); |
| 1196 EXPECT_EQ(GetSetHDCPStateAction(outputs_[1].output, |
| 1197 HDCP_STATE_DESIRED).c_str(), |
| 1198 delegate_->GetActionsAndClear()); |
| 1199 EXPECT_TRUE( |
| 1200 configurator_.EnableOutputProtection(client1, |
| 1201 OUTPUT_PROTECTION_METHOD_NONE)); |
| 1202 EXPECT_EQ(GetSetHDCPStateAction(outputs_[1].output, |
| 1203 HDCP_STATE_UNDESIRED).c_str(), |
| 1204 delegate_->GetActionsAndClear()); |
| 1205 } |
| 1206 |
1093 } // namespace chromeos | 1207 } // namespace chromeos |
OLD | NEW |