| 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/native_messaging_host.h" | 5 #include "remoting/host/setup/native_messaging_host.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 69 base::PlatformFile output, | 69 base::PlatformFile output, |
| 70 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, | 70 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, |
| 71 const base::Closure& quit_closure) | 71 const base::Closure& quit_closure) |
| 72 : caller_task_runner_(caller_task_runner), | 72 : caller_task_runner_(caller_task_runner), |
| 73 quit_closure_(quit_closure), | 73 quit_closure_(quit_closure), |
| 74 native_messaging_reader_(input), | 74 native_messaging_reader_(input), |
| 75 native_messaging_writer_(output), | 75 native_messaging_writer_(output), |
| 76 daemon_controller_(daemon_controller.Pass()), | 76 daemon_controller_(daemon_controller.Pass()), |
| 77 pairing_registry_(pairing_registry), | 77 pairing_registry_(pairing_registry), |
| 78 oauth_client_(oauth_client.Pass()), | 78 oauth_client_(oauth_client.Pass()), |
| 79 pending_requests_(0), |
| 80 shutdown_(false), |
| 79 weak_factory_(this) { | 81 weak_factory_(this) { |
| 80 weak_ptr_ = weak_factory_.GetWeakPtr(); | 82 weak_ptr_ = weak_factory_.GetWeakPtr(); |
| 81 } | 83 } |
| 82 | 84 |
| 83 NativeMessagingHost::~NativeMessagingHost() {} | 85 NativeMessagingHost::~NativeMessagingHost() {} |
| 84 | 86 |
| 85 void NativeMessagingHost::Start() { | 87 void NativeMessagingHost::Start() { |
| 86 DCHECK(caller_task_runner_->BelongsToCurrentThread()); | 88 DCHECK(caller_task_runner_->BelongsToCurrentThread()); |
| 87 | 89 |
| 88 native_messaging_reader_.Start( | 90 native_messaging_reader_.Start( |
| 89 base::Bind(&NativeMessagingHost::ProcessMessage, weak_ptr_), | 91 base::Bind(&NativeMessagingHost::ProcessMessage, weak_ptr_), |
| 90 base::Bind(&NativeMessagingHost::Shutdown, weak_ptr_)); | 92 base::Bind(&NativeMessagingHost::Shutdown, weak_ptr_)); |
| 91 } | 93 } |
| 92 | 94 |
| 93 void NativeMessagingHost::Shutdown() { | 95 void NativeMessagingHost::Shutdown() { |
| 94 DCHECK(caller_task_runner_->BelongsToCurrentThread()); | 96 DCHECK(caller_task_runner_->BelongsToCurrentThread()); |
| 95 if (!quit_closure_.is_null()) { | 97 |
| 98 if (shutdown_) |
| 99 return; |
| 100 |
| 101 shutdown_ = true; |
| 102 if (!pending_requests_) |
| 96 caller_task_runner_->PostTask(FROM_HERE, quit_closure_); | 103 caller_task_runner_->PostTask(FROM_HERE, quit_closure_); |
| 97 quit_closure_.Reset(); | |
| 98 } | |
| 99 } | 104 } |
| 100 | 105 |
| 101 void NativeMessagingHost::ProcessMessage(scoped_ptr<base::Value> message) { | 106 void NativeMessagingHost::ProcessMessage(scoped_ptr<base::Value> message) { |
| 102 DCHECK(caller_task_runner_->BelongsToCurrentThread()); | 107 DCHECK(caller_task_runner_->BelongsToCurrentThread()); |
| 103 | 108 |
| 104 // Don't process any more messages if Shutdown() has been called. | 109 // Don't process any more messages if Shutdown() has been called. |
| 105 if (quit_closure_.is_null()) | 110 if (shutdown_) |
| 106 return; | 111 return; |
| 107 | 112 |
| 108 const base::DictionaryValue* message_dict; | 113 const base::DictionaryValue* message_dict; |
| 109 if (!message->GetAsDictionary(&message_dict)) { | 114 if (!message->GetAsDictionary(&message_dict)) { |
| 110 LOG(ERROR) << "Expected DictionaryValue"; | 115 LOG(ERROR) << "Expected DictionaryValue"; |
| 111 Shutdown(); | 116 Shutdown(); |
| 112 return; | 117 return; |
| 113 } | 118 } |
| 114 | 119 |
| 115 scoped_ptr<base::DictionaryValue> response_dict(new base::DictionaryValue()); | 120 scoped_ptr<base::DictionaryValue> response_dict(new base::DictionaryValue()); |
| 116 | 121 |
| 117 // If the client supplies an ID, it will expect it in the response. This | 122 // If the client supplies an ID, it will expect it in the response. This |
| 118 // might be a string or a number, so cope with both. | 123 // might be a string or a number, so cope with both. |
| 119 const base::Value* id; | 124 const base::Value* id; |
| 120 if (message_dict->Get("id", &id)) | 125 if (message_dict->Get("id", &id)) |
| 121 response_dict->Set("id", id->DeepCopy()); | 126 response_dict->Set("id", id->DeepCopy()); |
| 122 | 127 |
| 123 std::string type; | 128 std::string type; |
| 124 if (!message_dict->GetString("type", &type)) { | 129 if (!message_dict->GetString("type", &type)) { |
| 125 LOG(ERROR) << "'type' not found"; | 130 LOG(ERROR) << "'type' not found"; |
| 126 Shutdown(); | 131 Shutdown(); |
| 127 return; | 132 return; |
| 128 } | 133 } |
| 129 | 134 |
| 130 response_dict->SetString("type", type + "Response"); | 135 response_dict->SetString("type", type + "Response"); |
| 131 | 136 |
| 137 DCHECK_GE(pending_requests_, 0); |
| 138 pending_requests_++; |
| 139 |
| 132 bool success = false; | 140 bool success = false; |
| 133 if (type == "hello") { | 141 if (type == "hello") { |
| 134 success = ProcessHello(*message_dict, response_dict.Pass()); | 142 success = ProcessHello(*message_dict, response_dict.Pass()); |
| 135 } else if (type == "clearPairedClients") { | 143 } else if (type == "clearPairedClients") { |
| 136 success = ProcessClearPairedClients(*message_dict, response_dict.Pass()); | 144 success = ProcessClearPairedClients(*message_dict, response_dict.Pass()); |
| 137 } else if (type == "deletePairedClient") { | 145 } else if (type == "deletePairedClient") { |
| 138 success = ProcessDeletePairedClient(*message_dict, response_dict.Pass()); | 146 success = ProcessDeletePairedClient(*message_dict, response_dict.Pass()); |
| 139 } else if (type == "getHostName") { | 147 } else if (type == "getHostName") { |
| 140 success = ProcessGetHostName(*message_dict, response_dict.Pass()); | 148 success = ProcessGetHostName(*message_dict, response_dict.Pass()); |
| 141 } else if (type == "getPinHash") { | 149 } else if (type == "getPinHash") { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 158 success = ProcessGetDaemonState(*message_dict, response_dict.Pass()); | 166 success = ProcessGetDaemonState(*message_dict, response_dict.Pass()); |
| 159 } else if (type == "getHostClientId") { | 167 } else if (type == "getHostClientId") { |
| 160 success = ProcessGetHostClientId(*message_dict, response_dict.Pass()); | 168 success = ProcessGetHostClientId(*message_dict, response_dict.Pass()); |
| 161 } else if (type == "getCredentialsFromAuthCode") { | 169 } else if (type == "getCredentialsFromAuthCode") { |
| 162 success = ProcessGetCredentialsFromAuthCode( | 170 success = ProcessGetCredentialsFromAuthCode( |
| 163 *message_dict, response_dict.Pass()); | 171 *message_dict, response_dict.Pass()); |
| 164 } else { | 172 } else { |
| 165 LOG(ERROR) << "Unsupported request type: " << type; | 173 LOG(ERROR) << "Unsupported request type: " << type; |
| 166 } | 174 } |
| 167 | 175 |
| 168 if (!success) | 176 if (!success) { |
| 177 pending_requests_--; |
| 178 DCHECK_GE(pending_requests_, 0); |
| 179 |
| 169 Shutdown(); | 180 Shutdown(); |
| 181 } |
| 170 } | 182 } |
| 171 | 183 |
| 172 bool NativeMessagingHost::ProcessHello( | 184 bool NativeMessagingHost::ProcessHello( |
| 173 const base::DictionaryValue& message, | 185 const base::DictionaryValue& message, |
| 174 scoped_ptr<base::DictionaryValue> response) { | 186 scoped_ptr<base::DictionaryValue> response) { |
| 175 response->SetString("version", STRINGIZE(VERSION)); | 187 response->SetString("version", STRINGIZE(VERSION)); |
| 176 scoped_ptr<base::ListValue> supported_features_list(new base::ListValue()); | 188 scoped_ptr<base::ListValue> supported_features_list(new base::ListValue()); |
| 177 supported_features_list->AppendStrings(std::vector<std::string>( | 189 supported_features_list->AppendStrings(std::vector<std::string>( |
| 178 kSupportedFeatures, kSupportedFeatures + arraysize(kSupportedFeatures))); | 190 kSupportedFeatures, kSupportedFeatures + arraysize(kSupportedFeatures))); |
| 179 response->Set("supportedFeatures", supported_features_list.release()); | 191 response->Set("supportedFeatures", supported_features_list.release()); |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 399 scoped_ptr<base::DictionaryValue> response) { | 411 scoped_ptr<base::DictionaryValue> response) { |
| 400 if (!caller_task_runner_->BelongsToCurrentThread()) { | 412 if (!caller_task_runner_->BelongsToCurrentThread()) { |
| 401 caller_task_runner_->PostTask( | 413 caller_task_runner_->PostTask( |
| 402 FROM_HERE, base::Bind(&NativeMessagingHost::SendResponse, weak_ptr_, | 414 FROM_HERE, base::Bind(&NativeMessagingHost::SendResponse, weak_ptr_, |
| 403 base::Passed(&response))); | 415 base::Passed(&response))); |
| 404 return; | 416 return; |
| 405 } | 417 } |
| 406 | 418 |
| 407 if (!native_messaging_writer_.WriteMessage(*response)) | 419 if (!native_messaging_writer_.WriteMessage(*response)) |
| 408 Shutdown(); | 420 Shutdown(); |
| 421 |
| 422 pending_requests_--; |
| 423 DCHECK_GE(pending_requests_, 0); |
| 424 |
| 425 if (shutdown_ && !pending_requests_) |
| 426 caller_task_runner_->PostTask(FROM_HERE, quit_closure_); |
| 409 } | 427 } |
| 410 | 428 |
| 411 void NativeMessagingHost::SendConfigResponse( | 429 void NativeMessagingHost::SendConfigResponse( |
| 412 scoped_ptr<base::DictionaryValue> response, | 430 scoped_ptr<base::DictionaryValue> response, |
| 413 scoped_ptr<base::DictionaryValue> config) { | 431 scoped_ptr<base::DictionaryValue> config) { |
| 414 if (config) { | 432 if (config) { |
| 415 response->Set("config", config.release()); | 433 response->Set("config", config.release()); |
| 416 } else { | 434 } else { |
| 417 response->Set("config", Value::CreateNullValue()); | 435 response->Set("config", Value::CreateNullValue()); |
| 418 } | 436 } |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 500 oauth_client.Pass(), | 518 oauth_client.Pass(), |
| 501 read_file, write_file, | 519 read_file, write_file, |
| 502 message_loop.message_loop_proxy(), | 520 message_loop.message_loop_proxy(), |
| 503 run_loop.QuitClosure()); | 521 run_loop.QuitClosure()); |
| 504 host.Start(); | 522 host.Start(); |
| 505 run_loop.Run(); | 523 run_loop.Run(); |
| 506 return kSuccessExitCode; | 524 return kSuccessExitCode; |
| 507 } | 525 } |
| 508 | 526 |
| 509 } // namespace remoting | 527 } // namespace remoting |
| OLD | NEW |