| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "remoting/host/setup/me2me_native_messaging_host.h" | 5 #include "remoting/host/setup/me2me_native_messaging_host.h" |
| 6 | 6 |
| 7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
| 8 #include "base/compiler_specific.h" | 8 #include "base/compiler_specific.h" |
| 9 #include "base/json/json_reader.h" | 9 #include "base/json/json_reader.h" |
| 10 #include "base/json/json_writer.h" | 10 #include "base/json/json_writer.h" |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 155 public: | 155 public: |
| 156 MockDaemonControllerDelegate(); | 156 MockDaemonControllerDelegate(); |
| 157 ~MockDaemonControllerDelegate() override; | 157 ~MockDaemonControllerDelegate() override; |
| 158 | 158 |
| 159 // DaemonController::Delegate interface. | 159 // DaemonController::Delegate interface. |
| 160 DaemonController::State GetState() override; | 160 DaemonController::State GetState() override; |
| 161 scoped_ptr<base::DictionaryValue> GetConfig() override; | 161 scoped_ptr<base::DictionaryValue> GetConfig() override; |
| 162 void SetConfigAndStart( | 162 void SetConfigAndStart( |
| 163 scoped_ptr<base::DictionaryValue> config, | 163 scoped_ptr<base::DictionaryValue> config, |
| 164 bool consent, | 164 bool consent, |
| 165 const DaemonController::CompletionCallback& done) override; | 165 const base::Closure& on_done, |
| 166 const DaemonController::ErrorCallback& on_error) override; |
| 166 void UpdateConfig(scoped_ptr<base::DictionaryValue> config, | 167 void UpdateConfig(scoped_ptr<base::DictionaryValue> config, |
| 167 const DaemonController::CompletionCallback& done) override; | 168 const base::Closure& on_done, |
| 168 void Stop(const DaemonController::CompletionCallback& done) override; | 169 const DaemonController::ErrorCallback& on_error) override; |
| 170 void Stop(const base::Closure& on_done, |
| 171 const DaemonController::ErrorCallback& on_error) override; |
| 169 DaemonController::UsageStatsConsent GetUsageStatsConsent() override; | 172 DaemonController::UsageStatsConsent GetUsageStatsConsent() override; |
| 170 | 173 |
| 171 private: | 174 private: |
| 172 DISALLOW_COPY_AND_ASSIGN(MockDaemonControllerDelegate); | 175 DISALLOW_COPY_AND_ASSIGN(MockDaemonControllerDelegate); |
| 173 }; | 176 }; |
| 174 | 177 |
| 175 MockDaemonControllerDelegate::MockDaemonControllerDelegate() {} | 178 MockDaemonControllerDelegate::MockDaemonControllerDelegate() {} |
| 176 | 179 |
| 177 MockDaemonControllerDelegate::~MockDaemonControllerDelegate() {} | 180 MockDaemonControllerDelegate::~MockDaemonControllerDelegate() {} |
| 178 | 181 |
| 179 DaemonController::State MockDaemonControllerDelegate::GetState() { | 182 DaemonController::State MockDaemonControllerDelegate::GetState() { |
| 180 return DaemonController::STATE_STARTED; | 183 return DaemonController::STATE_STARTED; |
| 181 } | 184 } |
| 182 | 185 |
| 183 scoped_ptr<base::DictionaryValue> MockDaemonControllerDelegate::GetConfig() { | 186 scoped_ptr<base::DictionaryValue> MockDaemonControllerDelegate::GetConfig() { |
| 184 return make_scoped_ptr(new base::DictionaryValue()); | 187 return make_scoped_ptr(new base::DictionaryValue()); |
| 185 } | 188 } |
| 186 | 189 |
| 187 void MockDaemonControllerDelegate::SetConfigAndStart( | 190 void MockDaemonControllerDelegate::SetConfigAndStart( |
| 188 scoped_ptr<base::DictionaryValue> config, | 191 scoped_ptr<base::DictionaryValue> config, |
| 189 bool consent, | 192 bool consent, |
| 190 const DaemonController::CompletionCallback& done) { | 193 const base::Closure& on_done, |
| 194 const DaemonController::ErrorCallback& on_error) { |
| 191 | 195 |
| 192 // Verify parameters passed in. | 196 // Verify parameters passed in. |
| 193 if (consent && config && config->HasKey("start")) { | 197 if (consent && config && config->HasKey("start")) { |
| 194 done.Run(DaemonController::RESULT_OK); | 198 on_done.Run(); |
| 195 } else { | 199 } else { |
| 196 done.Run(DaemonController::RESULT_FAILED); | 200 on_error.Run("Missing 'start'", FROM_HERE); |
| 197 } | 201 } |
| 198 } | 202 } |
| 199 | 203 |
| 200 void MockDaemonControllerDelegate::UpdateConfig( | 204 void MockDaemonControllerDelegate::UpdateConfig( |
| 201 scoped_ptr<base::DictionaryValue> config, | 205 scoped_ptr<base::DictionaryValue> config, |
| 202 const DaemonController::CompletionCallback& done) { | 206 const base::Closure& on_done, |
| 207 const DaemonController::ErrorCallback& on_error) { |
| 203 if (config && config->HasKey("update")) { | 208 if (config && config->HasKey("update")) { |
| 204 done.Run(DaemonController::RESULT_OK); | 209 on_done.Run(); |
| 205 } else { | 210 } else { |
| 206 done.Run(DaemonController::RESULT_FAILED); | 211 on_error.Run("Missing 'update'", FROM_HERE); |
| 207 } | 212 } |
| 208 } | 213 } |
| 209 | 214 |
| 210 void MockDaemonControllerDelegate::Stop( | 215 void MockDaemonControllerDelegate::Stop( |
| 211 const DaemonController::CompletionCallback& done) { | 216 const base::Closure& on_done, |
| 212 done.Run(DaemonController::RESULT_OK); | 217 const DaemonController::ErrorCallback& on_error) { |
| 218 on_done.Run(); |
| 213 } | 219 } |
| 214 | 220 |
| 215 DaemonController::UsageStatsConsent | 221 DaemonController::UsageStatsConsent |
| 216 MockDaemonControllerDelegate::GetUsageStatsConsent() { | 222 MockDaemonControllerDelegate::GetUsageStatsConsent() { |
| 217 DaemonController::UsageStatsConsent consent; | 223 DaemonController::UsageStatsConsent consent; |
| 218 consent.supported = true; | 224 consent.supported = true; |
| 219 consent.allowed = true; | 225 consent.allowed = true; |
| 220 consent.set_by_policy = true; | 226 consent.set_by_policy = true; |
| 221 return consent; | 227 return consent; |
| 222 } | 228 } |
| 223 | 229 |
| 224 class Me2MeNativeMessagingHostTest : public testing::Test { | 230 class Me2MeNativeMessagingHostTest : public testing::Test { |
| 225 public: | 231 public: |
| 226 Me2MeNativeMessagingHostTest(); | 232 Me2MeNativeMessagingHostTest(); |
| 227 ~Me2MeNativeMessagingHostTest() override; | 233 ~Me2MeNativeMessagingHostTest() override; |
| 228 | 234 |
| 229 void SetUp() override; | 235 void SetUp() override; |
| 230 void TearDown() override; | 236 void TearDown() override; |
| 231 | 237 |
| 232 scoped_ptr<base::DictionaryValue> ReadMessageFromOutputPipe(); | 238 scoped_ptr<base::DictionaryValue> ReadMessageFromOutputPipe(); |
| 233 | 239 |
| 234 void WriteMessageToInputPipe(const base::Value& message); | 240 void WriteMessageToInputPipe(const base::Value& message); |
| 235 | 241 |
| 236 // The Host process should shut down when it receives a malformed request. | 242 void TestBadDictionary(const base::DictionaryValue& message); |
| 237 // This is tested by sending a known-good request, followed by |message|, | 243 void TestBadRequest(const base::Value& message, |
| 238 // followed by the known-good request again. The response file should only | 244 const std::string& expected_type); |
| 239 // contain a single response from the first good request. | |
| 240 void TestBadRequest(const base::Value& message); | |
| 241 | 245 |
| 242 protected: | 246 protected: |
| 243 // Reference to the MockDaemonControllerDelegate, which is owned by | 247 // Reference to the MockDaemonControllerDelegate, which is owned by |
| 244 // |channel_|. | 248 // |channel_|. |
| 245 MockDaemonControllerDelegate* daemon_controller_delegate_; | 249 MockDaemonControllerDelegate* daemon_controller_delegate_; |
| 246 | 250 |
| 247 private: | 251 private: |
| 248 void StartHost(); | 252 void StartHost(); |
| 249 void StopHost(); | 253 void StopHost(); |
| 250 void ExitTest(); | 254 void ExitTest(); |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 410 const base::Value& message) { | 414 const base::Value& message) { |
| 411 std::string message_json; | 415 std::string message_json; |
| 412 base::JSONWriter::Write(message, &message_json); | 416 base::JSONWriter::Write(message, &message_json); |
| 413 | 417 |
| 414 uint32 length = message_json.length(); | 418 uint32 length = message_json.length(); |
| 415 input_write_file_.WriteAtCurrentPos(reinterpret_cast<char*>(&length), | 419 input_write_file_.WriteAtCurrentPos(reinterpret_cast<char*>(&length), |
| 416 sizeof(length)); | 420 sizeof(length)); |
| 417 input_write_file_.WriteAtCurrentPos(message_json.data(), length); | 421 input_write_file_.WriteAtCurrentPos(message_json.data(), length); |
| 418 } | 422 } |
| 419 | 423 |
| 420 void Me2MeNativeMessagingHostTest::TestBadRequest(const base::Value& message) { | 424 void Me2MeNativeMessagingHostTest::TestBadDictionary( |
| 425 const base::DictionaryValue& message) { |
| 426 std::string type; |
| 427 EXPECT_TRUE(message.GetString("type", &type)); |
| 428 TestBadRequest(message, type + "Response"); |
| 429 } |
| 430 |
| 431 void Me2MeNativeMessagingHostTest::TestBadRequest( |
| 432 const base::Value& message, |
| 433 const std::string& expected_type) { |
| 421 base::DictionaryValue good_message; | 434 base::DictionaryValue good_message; |
| 422 good_message.SetString("type", "hello"); | 435 good_message.SetString("type", "hello"); |
| 423 | 436 |
| 424 // This test currently relies on synchronous processing of hello messages and | 437 // This test currently relies on synchronous processing of hello messages and |
| 425 // message parameters verification. | 438 // message parameters verification. |
| 426 WriteMessageToInputPipe(good_message); | 439 WriteMessageToInputPipe(good_message); |
| 427 WriteMessageToInputPipe(message); | 440 WriteMessageToInputPipe(message); |
| 428 WriteMessageToInputPipe(good_message); | |
| 429 | 441 |
| 430 // Read from output pipe, and verify responses. | 442 // Read from output pipe, and verify responses. |
| 431 scoped_ptr<base::DictionaryValue> response = ReadMessageFromOutputPipe(); | 443 scoped_ptr<base::DictionaryValue> response = ReadMessageFromOutputPipe(); |
| 432 VerifyHelloResponse(response.Pass()); | 444 VerifyHelloResponse(response.Pass()); |
| 433 | 445 |
| 434 response = ReadMessageFromOutputPipe(); | 446 response = ReadMessageFromOutputPipe(); |
| 435 EXPECT_FALSE(response); | 447 EXPECT_TRUE(response); |
| 448 |
| 449 // If a type is expected, assert that it matches (note that a type is expected |
| 450 // for all message that included one). |
| 451 std::string value; |
| 452 if (!expected_type.empty()) { |
| 453 EXPECT_TRUE(response->GetString("type", &value)); |
| 454 EXPECT_EQ(expected_type, value); |
| 455 } else { |
| 456 EXPECT_FALSE(response->GetString("type", &value)); |
| 457 } |
| 458 |
| 459 EXPECT_TRUE(response->GetString("error_message", &value)); |
| 460 EXPECT_TRUE(response->GetString("error_location", &value)); |
| 436 } | 461 } |
| 437 | 462 |
| 438 // TODO (weitaosu): crbug.com/323306. Re-enable these tests. | |
| 439 // Test all valid request-types. | 463 // Test all valid request-types. |
| 440 TEST_F(Me2MeNativeMessagingHostTest, All) { | 464 TEST_F(Me2MeNativeMessagingHostTest, All) { |
| 441 int next_id = 0; | 465 int next_id = 0; |
| 442 base::DictionaryValue message; | 466 base::DictionaryValue message; |
| 443 message.SetInteger("id", next_id++); | 467 message.SetInteger("id", next_id++); |
| 444 message.SetString("type", "hello"); | 468 message.SetString("type", "hello"); |
| 445 WriteMessageToInputPipe(message); | 469 WriteMessageToInputPipe(message); |
| 446 | 470 |
| 447 message.SetInteger("id", next_id++); | 471 message.SetInteger("id", next_id++); |
| 448 message.SetString("type", "getHostName"); | 472 message.SetString("type", "getHostName"); |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 544 | 568 |
| 545 response = ReadMessageFromOutputPipe(); | 569 response = ReadMessageFromOutputPipe(); |
| 546 EXPECT_TRUE(response); | 570 EXPECT_TRUE(response); |
| 547 EXPECT_TRUE(response->GetString("id", &value)); | 571 EXPECT_TRUE(response->GetString("id", &value)); |
| 548 EXPECT_EQ("42", value); | 572 EXPECT_EQ("42", value); |
| 549 } | 573 } |
| 550 | 574 |
| 551 // Verify non-Dictionary requests are rejected. | 575 // Verify non-Dictionary requests are rejected. |
| 552 TEST_F(Me2MeNativeMessagingHostTest, WrongFormat) { | 576 TEST_F(Me2MeNativeMessagingHostTest, WrongFormat) { |
| 553 base::ListValue message; | 577 base::ListValue message; |
| 554 TestBadRequest(message); | 578 TestBadRequest(message, ""); |
| 555 } | 579 } |
| 556 | 580 |
| 557 // Verify requests with no type are rejected. | 581 // Verify requests with no type are rejected. |
| 558 TEST_F(Me2MeNativeMessagingHostTest, MissingType) { | 582 TEST_F(Me2MeNativeMessagingHostTest, MissingType) { |
| 559 base::DictionaryValue message; | 583 base::DictionaryValue message; |
| 560 TestBadRequest(message); | 584 TestBadRequest(message, ""); |
| 561 } | 585 } |
| 562 | 586 |
| 563 // Verify rejection if type is unrecognized. | 587 // Verify rejection if type is unrecognized. |
| 564 TEST_F(Me2MeNativeMessagingHostTest, InvalidType) { | 588 TEST_F(Me2MeNativeMessagingHostTest, InvalidType) { |
| 565 base::DictionaryValue message; | 589 base::DictionaryValue message; |
| 566 message.SetString("type", "xxx"); | 590 message.SetString("type", "xxx"); |
| 567 TestBadRequest(message); | 591 TestBadDictionary(message); |
| 568 } | 592 } |
| 569 | 593 |
| 570 // Verify rejection if getPinHash request has no hostId. | 594 // Verify rejection if getPinHash request has no hostId. |
| 571 TEST_F(Me2MeNativeMessagingHostTest, GetPinHashNoHostId) { | 595 TEST_F(Me2MeNativeMessagingHostTest, GetPinHashNoHostId) { |
| 572 base::DictionaryValue message; | 596 base::DictionaryValue message; |
| 573 message.SetString("type", "getPinHash"); | 597 message.SetString("type", "getPinHash"); |
| 574 message.SetString("pin", "1234"); | 598 message.SetString("pin", "1234"); |
| 575 TestBadRequest(message); | 599 TestBadDictionary(message); |
| 576 } | 600 } |
| 577 | 601 |
| 578 // Verify rejection if getPinHash request has no pin. | 602 // Verify rejection if getPinHash request has no pin. |
| 579 TEST_F(Me2MeNativeMessagingHostTest, GetPinHashNoPin) { | 603 TEST_F(Me2MeNativeMessagingHostTest, GetPinHashNoPin) { |
| 580 base::DictionaryValue message; | 604 base::DictionaryValue message; |
| 581 message.SetString("type", "getPinHash"); | 605 message.SetString("type", "getPinHash"); |
| 582 message.SetString("hostId", "my_host"); | 606 message.SetString("hostId", "my_host"); |
| 583 TestBadRequest(message); | 607 TestBadDictionary(message); |
| 584 } | 608 } |
| 585 | 609 |
| 586 // Verify rejection if updateDaemonConfig request has invalid config. | 610 // Verify rejection if updateDaemonConfig request has invalid config. |
| 587 TEST_F(Me2MeNativeMessagingHostTest, UpdateDaemonConfigInvalidConfig) { | 611 TEST_F(Me2MeNativeMessagingHostTest, UpdateDaemonConfigInvalidConfig) { |
| 588 base::DictionaryValue message; | 612 base::DictionaryValue message; |
| 589 message.SetString("type", "updateDaemonConfig"); | 613 message.SetString("type", "updateDaemonConfig"); |
| 590 message.SetString("config", "xxx"); | 614 message.SetString("config", "xxx"); |
| 591 TestBadRequest(message); | 615 TestBadDictionary(message); |
| 592 } | 616 } |
| 593 | 617 |
| 594 // Verify rejection if startDaemon request has invalid config. | 618 // Verify rejection if startDaemon request has invalid config. |
| 595 TEST_F(Me2MeNativeMessagingHostTest, StartDaemonInvalidConfig) { | 619 TEST_F(Me2MeNativeMessagingHostTest, StartDaemonInvalidConfig) { |
| 596 base::DictionaryValue message; | 620 base::DictionaryValue message; |
| 597 message.SetString("type", "startDaemon"); | 621 message.SetString("type", "startDaemon"); |
| 598 message.SetString("config", "xxx"); | 622 message.SetString("config", "xxx"); |
| 599 message.SetBoolean("consent", true); | 623 message.SetBoolean("consent", true); |
| 600 TestBadRequest(message); | 624 TestBadDictionary(message); |
| 601 } | 625 } |
| 602 | 626 |
| 603 // Verify rejection if startDaemon request has no "consent" parameter. | 627 // Verify rejection if startDaemon request has no "consent" parameter. |
| 604 TEST_F(Me2MeNativeMessagingHostTest, StartDaemonNoConsent) { | 628 TEST_F(Me2MeNativeMessagingHostTest, StartDaemonNoConsent) { |
| 605 base::DictionaryValue message; | 629 base::DictionaryValue message; |
| 606 message.SetString("type", "startDaemon"); | 630 message.SetString("type", "startDaemon"); |
| 607 message.Set("config", base::DictionaryValue().DeepCopy()); | 631 message.Set("config", base::DictionaryValue().DeepCopy()); |
| 608 TestBadRequest(message); | 632 TestBadDictionary(message); |
| 609 } | 633 } |
| 610 | 634 |
| 611 // Verify rejection if getCredentialsFromAuthCode has no auth code. | 635 // Verify rejection if getCredentialsFromAuthCode has no auth code. |
| 612 TEST_F(Me2MeNativeMessagingHostTest, GetCredentialsFromAuthCodeNoAuthCode) { | 636 TEST_F(Me2MeNativeMessagingHostTest, GetCredentialsFromAuthCodeNoAuthCode) { |
| 613 base::DictionaryValue message; | 637 base::DictionaryValue message; |
| 614 message.SetString("type", "getCredentialsFromAuthCode"); | 638 message.SetString("type", "getCredentialsFromAuthCode"); |
| 615 TestBadRequest(message); | 639 TestBadDictionary(message); |
| 616 } | 640 } |
| 617 | 641 |
| 618 } // namespace remoting | 642 } // namespace remoting |
| OLD | NEW |