Chromium Code Reviews| 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::GetHDCPState() call. | |
| 76 std::string GetGetHDCPStateAction(RROutput id) { | |
| 77 return base::StringPrintf("get_hdcp(id=%lu)", id); | |
|
Daniel Erat
2013/09/30 14:01:16
i wouldn't bother with an action for this Get*() m
kcwu
2013/10/01 07:15:51
Done.
| |
| 78 } | |
| 79 | |
| 80 // Returns a string describing a TestDelegate::SetHDCPState() call. | |
| 81 std::string GetSetHDCPStateAction(RROutput id, HDCPState state) { | |
| 82 return base::StringPrintf("set_hdcp(id=%lu, state=%d)", id, state); | |
|
Daniel Erat
2013/09/30 14:01:16
nit: remove space after the comma in the string to
kcwu
2013/10/01 07:15:51
Done.
| |
| 83 } | |
| 84 | |
| 75 // Joins a sequence of strings describing actions (e.g. kScreenDim) such | 85 // Joins a sequence of strings describing actions (e.g. kScreenDim) such |
| 76 // that they can be compared against a string returned by | 86 // that they can be compared against a string returned by |
| 77 // TestDelegate::GetActionsAndClear(). The list of actions must be | 87 // TestDelegate::GetActionsAndClear(). The list of actions must be |
| 78 // terminated by a NULL pointer. | 88 // terminated by a NULL pointer. |
| 79 std::string JoinActions(const char* action, ...) { | 89 std::string JoinActions(const char* action, ...) { |
| 80 std::string actions; | 90 std::string actions; |
| 81 | 91 |
| 82 va_list arg_list; | 92 va_list arg_list; |
| 83 va_start(arg_list, action); | 93 va_start(arg_list, action); |
| 84 while (action) { | 94 while (action) { |
| 85 if (!actions.empty()) | 95 if (!actions.empty()) |
| 86 actions += ","; | 96 actions += ","; |
| 87 actions += action; | 97 actions += action; |
| 88 action = va_arg(arg_list, const char*); | 98 action = va_arg(arg_list, const char*); |
| 89 } | 99 } |
| 90 va_end(arg_list); | 100 va_end(arg_list); |
| 91 return actions; | 101 return actions; |
| 92 } | 102 } |
| 93 | 103 |
| 94 class TestDelegate : public OutputConfigurator::Delegate { | 104 class TestDelegate : public OutputConfigurator::Delegate { |
| 95 public: | 105 public: |
| 96 static const int kXRandREventBase = 10; | 106 static const int kXRandREventBase = 10; |
| 97 | 107 |
| 98 TestDelegate() : configure_crtc_result_(true) {} | 108 TestDelegate() |
| 109 : configure_crtc_result_(true), | |
| 110 hdcp_state_(HDCP_STATE_UNDESIRED) {} | |
| 99 virtual ~TestDelegate() {} | 111 virtual ~TestDelegate() {} |
| 100 | 112 |
| 101 const std::vector<OutputConfigurator::OutputSnapshot>& outputs() const { | 113 const std::vector<OutputConfigurator::OutputSnapshot>& outputs() const { |
| 102 return outputs_; | 114 return outputs_; |
| 103 } | 115 } |
| 104 void set_outputs( | 116 void set_outputs( |
| 105 const std::vector<OutputConfigurator::OutputSnapshot>& outputs) { | 117 const std::vector<OutputConfigurator::OutputSnapshot>& outputs) { |
| 106 outputs_ = outputs; | 118 outputs_ = outputs; |
| 107 } | 119 } |
| 108 | 120 |
| 109 void set_configure_crtc_result(bool result) { | 121 void set_configure_crtc_result(bool result) { |
| 110 configure_crtc_result_ = result; | 122 configure_crtc_result_ = result; |
| 111 } | 123 } |
| 112 | 124 |
| 125 void set_hdcp_state(HDCPState state) { | |
|
Daniel Erat
2013/09/30 14:01:16
nit: move this all to one line since it'll fit:
kcwu
2013/10/01 07:15:51
Done.
| |
| 126 hdcp_state_ = state; | |
| 127 } | |
| 128 | |
| 113 // Returns a comma-separated string describing the actions that were | 129 // Returns a comma-separated string describing the actions that were |
| 114 // requested since the previous call to GetActionsAndClear() (i.e. | 130 // requested since the previous call to GetActionsAndClear() (i.e. |
| 115 // results are non-repeatable). | 131 // results are non-repeatable). |
| 116 std::string GetActionsAndClear() { | 132 std::string GetActionsAndClear() { |
| 117 std::string actions = actions_; | 133 std::string actions = actions_; |
| 118 actions_.clear(); | 134 actions_.clear(); |
| 119 return actions; | 135 return actions; |
| 120 } | 136 } |
| 121 | 137 |
| 122 // OutputConfigurator::Delegate overrides: | 138 // OutputConfigurator::Delegate overrides: |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 161 virtual void ConfigureCTM( | 177 virtual void ConfigureCTM( |
| 162 int touch_device_id, | 178 int touch_device_id, |
| 163 const OutputConfigurator::CoordinateTransformation& ctm) OVERRIDE { | 179 const OutputConfigurator::CoordinateTransformation& ctm) OVERRIDE { |
| 164 AppendAction(GetCTMAction(touch_device_id, ctm)); | 180 AppendAction(GetCTMAction(touch_device_id, ctm)); |
| 165 } | 181 } |
| 166 virtual void SendProjectingStateToPowerManager(bool projecting) OVERRIDE { | 182 virtual void SendProjectingStateToPowerManager(bool projecting) OVERRIDE { |
| 167 AppendAction(projecting ? kProjectingOn : kProjectingOff); | 183 AppendAction(projecting ? kProjectingOn : kProjectingOff); |
| 168 } | 184 } |
| 169 | 185 |
| 170 virtual bool GetHDCPState(RROutput id, HDCPState* state) OVERRIDE { | 186 virtual bool GetHDCPState(RROutput id, HDCPState* state) OVERRIDE { |
| 187 AppendAction(GetGetHDCPStateAction(id)); | |
| 188 *state = hdcp_state_; | |
| 171 return true; | 189 return true; |
| 172 } | 190 } |
| 173 | 191 |
| 174 virtual bool SetHDCPState(RROutput id, HDCPState state) OVERRIDE { | 192 virtual bool SetHDCPState(RROutput id, HDCPState state) OVERRIDE { |
| 193 AppendAction(GetSetHDCPStateAction(id, state)); | |
| 175 return true; | 194 return true; |
| 176 } | 195 } |
| 177 | 196 |
| 178 private: | 197 private: |
| 179 struct ModeDetails { | 198 struct ModeDetails { |
| 180 ModeDetails() : width(0), height(0), interlaced(false) {} | 199 ModeDetails() : width(0), height(0), interlaced(false) {} |
| 181 ModeDetails(int width, int height, bool interlaced) | 200 ModeDetails(int width, int height, bool interlaced) |
| 182 : width(width), | 201 : width(width), |
| 183 height(height), | 202 height(height), |
| 184 interlaced(interlaced) {} | 203 interlaced(interlaced) {} |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 197 std::map<RRMode, ModeDetails> modes_; | 216 std::map<RRMode, ModeDetails> modes_; |
| 198 | 217 |
| 199 // Outputs to be returned by GetOutputs(). | 218 // Outputs to be returned by GetOutputs(). |
| 200 std::vector<OutputConfigurator::OutputSnapshot> outputs_; | 219 std::vector<OutputConfigurator::OutputSnapshot> outputs_; |
| 201 | 220 |
| 202 std::string actions_; | 221 std::string actions_; |
| 203 | 222 |
| 204 // Return value returned by ConfigureCrtc(). | 223 // Return value returned by ConfigureCrtc(). |
| 205 bool configure_crtc_result_; | 224 bool configure_crtc_result_; |
| 206 | 225 |
| 226 // Result value of GetHDCPState(). | |
| 227 HDCPState hdcp_state_; | |
| 228 | |
| 207 DISALLOW_COPY_AND_ASSIGN(TestDelegate); | 229 DISALLOW_COPY_AND_ASSIGN(TestDelegate); |
| 208 }; | 230 }; |
| 209 | 231 |
| 210 class TestObserver : public OutputConfigurator::Observer { | 232 class TestObserver : public OutputConfigurator::Observer { |
| 211 public: | 233 public: |
| 212 explicit TestObserver(OutputConfigurator* configurator) | 234 explicit TestObserver(OutputConfigurator* configurator) |
| 213 : configurator_(configurator) { | 235 : configurator_(configurator) { |
| 214 Reset(); | 236 Reset(); |
| 215 configurator_->AddObserver(this); | 237 configurator_->AddObserver(this); |
| 216 } | 238 } |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 333 OutputConfigurator::ModeInfo big_mode_info; | 355 OutputConfigurator::ModeInfo big_mode_info; |
| 334 big_mode_info.width = kBigModeWidth; | 356 big_mode_info.width = kBigModeWidth; |
| 335 big_mode_info.height = kBigModeHeight; | 357 big_mode_info.height = kBigModeHeight; |
| 336 | 358 |
| 337 OutputConfigurator::OutputSnapshot* o = &outputs_[0]; | 359 OutputConfigurator::OutputSnapshot* o = &outputs_[0]; |
| 338 o->output = 1; | 360 o->output = 1; |
| 339 o->crtc = 10; | 361 o->crtc = 10; |
| 340 o->current_mode = kSmallModeId; | 362 o->current_mode = kSmallModeId; |
| 341 o->native_mode = kSmallModeId; | 363 o->native_mode = kSmallModeId; |
| 342 o->is_internal = true; | 364 o->is_internal = true; |
| 365 o->type = OUTPUT_TYPE_INTERNAL; | |
| 343 o->is_aspect_preserving_scaling = true; | 366 o->is_aspect_preserving_scaling = true; |
| 344 o->mode_infos[kSmallModeId] = small_mode_info; | 367 o->mode_infos[kSmallModeId] = small_mode_info; |
| 345 o->has_display_id = true; | 368 o->has_display_id = true; |
| 346 o->index = 0; | 369 o->index = 0; |
| 347 | 370 |
| 348 o = &outputs_[1]; | 371 o = &outputs_[1]; |
| 349 o->output = 2; | 372 o->output = 2; |
| 350 o->crtc = 11; | 373 o->crtc = 11; |
| 351 o->current_mode = kBigModeId; | 374 o->current_mode = kBigModeId; |
| 352 o->native_mode = kBigModeId; | 375 o->native_mode = kBigModeId; |
| 353 o->is_internal = false; | 376 o->is_internal = false; |
| 377 o->type = OUTPUT_TYPE_HDMI; | |
| 354 o->is_aspect_preserving_scaling = true; | 378 o->is_aspect_preserving_scaling = true; |
| 355 o->mode_infos[kSmallModeId] = small_mode_info; | 379 o->mode_infos[kSmallModeId] = small_mode_info; |
| 356 o->mode_infos[kBigModeId] = big_mode_info; | 380 o->mode_infos[kBigModeId] = big_mode_info; |
| 357 o->has_display_id = true; | 381 o->has_display_id = true; |
| 358 o->index = 1; | 382 o->index = 1; |
| 359 | 383 |
| 360 UpdateOutputs(2, false); | 384 UpdateOutputs(2, false); |
| 361 } | 385 } |
| 362 | 386 |
| 363 protected: | 387 protected: |
| (...skipping 719 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1083 | 1107 |
| 1084 // Also check that the newly-added small mode is present in the internal | 1108 // 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). | 1109 // snapshot that was passed to the observer (http://crbug.com/289159). |
| 1086 const OutputConfigurator::ModeInfo* info = OutputConfigurator::GetModeInfo( | 1110 const OutputConfigurator::ModeInfo* info = OutputConfigurator::GetModeInfo( |
| 1087 observer_.latest_outputs()[0], kSmallModeId); | 1111 observer_.latest_outputs()[0], kSmallModeId); |
| 1088 ASSERT_TRUE(info); | 1112 ASSERT_TRUE(info); |
| 1089 EXPECT_EQ(kSmallModeWidth, info->width); | 1113 EXPECT_EQ(kSmallModeWidth, info->width); |
| 1090 EXPECT_EQ(kSmallModeHeight, info->height); | 1114 EXPECT_EQ(kSmallModeHeight, info->height); |
| 1091 } | 1115 } |
| 1092 | 1116 |
| 1117 TEST_F(OutputConfiguratorTest, OutputProtection) { | |
| 1118 uint32_t link_mask; | |
| 1119 uint32_t protection_mask; | |
|
Daniel Erat
2013/09/30 14:01:16
nit: move these down to the point where they're fi
kcwu
2013/10/01 07:15:51
Done.
| |
| 1120 | |
| 1121 OutputConfigurator::OutputProtectionClientId id = | |
| 1122 configurator_.RegisterOutputProtectionClient(); | |
| 1123 EXPECT_NE(0u, id); | |
| 1124 | |
| 1125 // One output. | |
| 1126 UpdateOutputs(1, true); | |
| 1127 configurator_.Start(0); | |
| 1128 EXPECT_NE(kNoActions, delegate_->GetActionsAndClear()); | |
| 1129 EXPECT_TRUE(configurator_.QueryOutputProtectionStatus(id, &link_mask, | |
| 1130 &protection_mask)); | |
| 1131 EXPECT_EQ(static_cast<uint32_t>(OUTPUT_TYPE_INTERNAL), link_mask); | |
| 1132 EXPECT_EQ(static_cast<uint32_t>(OUTPUT_PROTECTION_METHOD_NONE), | |
| 1133 protection_mask); | |
| 1134 EXPECT_EQ(kNoActions, delegate_->GetActionsAndClear()); | |
| 1135 | |
| 1136 // Two outputs. | |
| 1137 UpdateOutputs(2, true); | |
| 1138 configurator_.Start(0); | |
|
Daniel Erat
2013/09/30 14:01:16
calling Start() multiple times isn't expected beha
kcwu
2013/10/01 07:15:51
Done.
| |
| 1139 EXPECT_NE(kNoActions, delegate_->GetActionsAndClear()); | |
| 1140 EXPECT_TRUE(configurator_.QueryOutputProtectionStatus(id, &link_mask, | |
| 1141 &protection_mask)); | |
| 1142 EXPECT_EQ(static_cast<uint32_t>(OUTPUT_TYPE_INTERNAL | OUTPUT_TYPE_HDMI), | |
| 1143 link_mask); | |
| 1144 EXPECT_EQ(static_cast<uint32_t>(OUTPUT_PROTECTION_METHOD_NONE), | |
| 1145 protection_mask); | |
| 1146 EXPECT_EQ(GetGetHDCPStateAction(outputs_[1].output), | |
| 1147 delegate_->GetActionsAndClear()); | |
| 1148 | |
| 1149 EXPECT_TRUE( | |
| 1150 configurator_.EnableOutputProtection(id, OUTPUT_PROTECTION_METHOD_HDCP)); | |
| 1151 EXPECT_EQ(GetSetHDCPStateAction(outputs_[1].output, HDCP_STATE_DESIRED), | |
| 1152 delegate_->GetActionsAndClear()); | |
| 1153 | |
| 1154 // Enable protection. | |
| 1155 delegate_->set_hdcp_state(HDCP_STATE_ENABLED); | |
| 1156 EXPECT_TRUE(configurator_.QueryOutputProtectionStatus(id, &link_mask, | |
| 1157 &protection_mask)); | |
| 1158 EXPECT_EQ(static_cast<uint32_t>(OUTPUT_TYPE_INTERNAL | OUTPUT_TYPE_HDMI), | |
| 1159 link_mask); | |
| 1160 EXPECT_EQ(static_cast<uint32_t>(OUTPUT_PROTECTION_METHOD_HDCP), | |
| 1161 protection_mask); | |
| 1162 EXPECT_EQ(GetGetHDCPStateAction(outputs_[1].output), | |
| 1163 delegate_->GetActionsAndClear()); | |
| 1164 } | |
| 1165 | |
| 1166 TEST_F(OutputConfiguratorTest, OutputProtectionTwoClients) { | |
| 1167 uint32_t link_mask; | |
| 1168 uint32_t protection_mask; | |
| 1169 | |
| 1170 OutputConfigurator::OutputProtectionClientId client1 = | |
| 1171 configurator_.RegisterOutputProtectionClient(); | |
| 1172 OutputConfigurator::OutputProtectionClientId client2 = | |
| 1173 configurator_.RegisterOutputProtectionClient(); | |
| 1174 EXPECT_NE(client1, client2); | |
| 1175 | |
| 1176 UpdateOutputs(2, true); | |
| 1177 configurator_.Start(0); | |
| 1178 EXPECT_NE(kNoActions, delegate_->GetActionsAndClear()); | |
| 1179 | |
| 1180 // Clients never know state enableness for methods that they didn't request. | |
| 1181 EXPECT_TRUE( | |
| 1182 configurator_.EnableOutputProtection(client1, | |
| 1183 OUTPUT_PROTECTION_METHOD_HDCP)); | |
| 1184 delegate_->set_hdcp_state(HDCP_STATE_ENABLED); | |
| 1185 | |
| 1186 EXPECT_TRUE(configurator_.QueryOutputProtectionStatus(client1, &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_HDCP, protection_mask); | |
| 1191 | |
| 1192 EXPECT_TRUE(configurator_.QueryOutputProtectionStatus(client2, &link_mask, | |
| 1193 &protection_mask)); | |
| 1194 EXPECT_EQ(static_cast<uint32_t>(OUTPUT_TYPE_INTERNAL | OUTPUT_TYPE_HDMI), | |
| 1195 link_mask); | |
| 1196 EXPECT_EQ(OUTPUT_PROTECTION_METHOD_NONE, protection_mask); | |
| 1197 EXPECT_EQ(JoinActions(GetSetHDCPStateAction(outputs_[1].output, | |
| 1198 HDCP_STATE_DESIRED).c_str(), | |
|
Daniel Erat
2013/09/30 14:01:16
please move the call to check the Set action up to
kcwu
2013/10/01 07:15:51
Done.
| |
| 1199 GetGetHDCPStateAction(outputs_[1].output).c_str(), | |
| 1200 GetGetHDCPStateAction(outputs_[1].output).c_str(), | |
| 1201 NULL), | |
| 1202 delegate_->GetActionsAndClear()); | |
| 1203 | |
| 1204 // Protections will be disabled only if no more clients request for. | |
|
Daniel Erat
2013/09/30 14:01:16
nit: s/request for/request them/
| |
| 1205 EXPECT_TRUE( | |
| 1206 configurator_.EnableOutputProtection(client2, | |
| 1207 OUTPUT_PROTECTION_METHOD_NONE)); | |
| 1208 EXPECT_EQ(GetSetHDCPStateAction(outputs_[1].output, | |
| 1209 HDCP_STATE_DESIRED).c_str(), | |
| 1210 delegate_->GetActionsAndClear()); | |
| 1211 EXPECT_TRUE( | |
| 1212 configurator_.EnableOutputProtection(client1, | |
| 1213 OUTPUT_PROTECTION_METHOD_NONE)); | |
| 1214 EXPECT_EQ(GetSetHDCPStateAction(outputs_[1].output, | |
| 1215 HDCP_STATE_UNDESIRED).c_str(), | |
| 1216 delegate_->GetActionsAndClear()); | |
| 1217 } | |
| 1218 | |
| 1093 } // namespace chromeos | 1219 } // namespace chromeos |
| OLD | NEW |