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 // This file implements a standalone host process for Me2Me. | 5 // This file implements a standalone host process for Me2Me. |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/at_exit.h" | 9 #include "base/at_exit.h" |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
140 const char kWindowIdSwitchName[] = "window-id"; | 140 const char kWindowIdSwitchName[] = "window-id"; |
141 | 141 |
142 // Maximum time to wait for clean shutdown to occur, before forcing termination | 142 // Maximum time to wait for clean shutdown to occur, before forcing termination |
143 // of the process. | 143 // of the process. |
144 const int kShutdownTimeoutSeconds = 15; | 144 const int kShutdownTimeoutSeconds = 15; |
145 | 145 |
146 // Maximum time to wait for reporting host-offline-reason to the service, | 146 // Maximum time to wait for reporting host-offline-reason to the service, |
147 // before continuing normal process shutdown. | 147 // before continuing normal process shutdown. |
148 const int kHostOfflineReasonTimeoutSeconds = 10; | 148 const int kHostOfflineReasonTimeoutSeconds = 10; |
149 | 149 |
150 // Host offline reasons not associated with shutting down the host process | |
151 // and therefore not expressible through HostExitCodes enum. | |
152 const char kHostOfflineBecauseOfRestarting[] = "RESTARTING"; | |
153 const char kHostOfflineBecauseOfPolicyReadError[] = "POLICY_READ_ERROR"; | |
154 | |
150 } // namespace | 155 } // namespace |
151 | 156 |
152 namespace remoting { | 157 namespace remoting { |
153 | 158 |
154 class HostProcess : public ConfigWatcher::Delegate, | 159 class HostProcess : public ConfigWatcher::Delegate, |
155 public HostSignalingManager::Listener, | 160 public HostSignalingManager::Listener, |
156 public HostChangeNotificationListener::Listener, | 161 public HostChangeNotificationListener::Listener, |
157 public IPC::Listener, | 162 public IPC::Listener, |
158 public base::RefCountedThreadSafe<HostProcess> { | 163 public base::RefCountedThreadSafe<HostProcess> { |
159 public: | 164 public: |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
206 // STARTED->STOPPING | 211 // STARTED->STOPPING |
207 // STOPPING_TO_RESTART->STARTED | 212 // STOPPING_TO_RESTART->STARTED |
208 // STOPPING_TO_RESTART->STOPPING | 213 // STOPPING_TO_RESTART->STOPPING |
209 // STOPPING->STOPPED | 214 // STOPPING->STOPPED |
210 // STOPPED->STARTED | 215 // STOPPED->STARTED |
211 // | 216 // |
212 // |host_| must be nullptr in INITIALIZING and STOPPED states and not | 217 // |host_| must be nullptr in INITIALIZING and STOPPED states and not |
213 // nullptr in all other states. | 218 // nullptr in all other states. |
214 }; | 219 }; |
215 | 220 |
221 enum PolicyState { | |
222 // Cannot start the host, because a valid policy has not been read yet. | |
223 POLICY_INITIALIZING, | |
224 | |
225 // Policy was loaded successfully. | |
226 POLICY_LOADED, | |
227 | |
228 // Policy error was detected, and we haven't yet sent out a | |
229 // host-offline-reason (i.e. because we haven't yet read the config). | |
230 POLICY_ERROR_REPORT_PENDING, | |
231 | |
232 // Policy error was detected, and we have sent out a host-offline-reason. | |
233 POLICY_ERROR_REPORTED, | |
234 }; | |
235 | |
216 friend class base::RefCountedThreadSafe<HostProcess>; | 236 friend class base::RefCountedThreadSafe<HostProcess>; |
217 ~HostProcess() override; | 237 ~HostProcess() override; |
218 | 238 |
219 void StartOnNetworkThread(); | 239 void StartOnNetworkThread(); |
220 | 240 |
221 #if defined(OS_POSIX) | 241 #if defined(OS_POSIX) |
222 // Callback passed to RegisterSignalHandler() to handle SIGTERM events. | 242 // Callback passed to RegisterSignalHandler() to handle SIGTERM events. |
223 void SigTermHandler(int signal_number); | 243 void SigTermHandler(int signal_number); |
224 #endif | 244 #endif |
225 | 245 |
(...skipping 12 matching lines...) Expand all Loading... | |
238 | 258 |
239 // Tear down resources that run on the UI thread. | 259 // Tear down resources that run on the UI thread. |
240 void ShutdownOnUiThread(); | 260 void ShutdownOnUiThread(); |
241 | 261 |
242 // Applies the host config, returning true if successful. | 262 // Applies the host config, returning true if successful. |
243 bool ApplyConfig(const base::DictionaryValue& config); | 263 bool ApplyConfig(const base::DictionaryValue& config); |
244 | 264 |
245 // Handles policy updates, by calling On*PolicyUpdate methods. | 265 // Handles policy updates, by calling On*PolicyUpdate methods. |
246 void OnPolicyUpdate(scoped_ptr<base::DictionaryValue> policies); | 266 void OnPolicyUpdate(scoped_ptr<base::DictionaryValue> policies); |
247 void OnPolicyError(); | 267 void OnPolicyError(); |
268 void ReportPolicyErrorAndRestartHost(); | |
248 void ApplyHostDomainPolicy(); | 269 void ApplyHostDomainPolicy(); |
249 void ApplyUsernamePolicy(); | 270 void ApplyUsernamePolicy(); |
250 bool OnHostDomainPolicyUpdate(base::DictionaryValue* policies); | 271 bool OnHostDomainPolicyUpdate(base::DictionaryValue* policies); |
251 bool OnUsernamePolicyUpdate(base::DictionaryValue* policies); | 272 bool OnUsernamePolicyUpdate(base::DictionaryValue* policies); |
252 bool OnNatPolicyUpdate(base::DictionaryValue* policies); | 273 bool OnNatPolicyUpdate(base::DictionaryValue* policies); |
253 bool OnRelayPolicyUpdate(base::DictionaryValue* policies); | 274 bool OnRelayPolicyUpdate(base::DictionaryValue* policies); |
254 bool OnUdpPortPolicyUpdate(base::DictionaryValue* policies); | 275 bool OnUdpPortPolicyUpdate(base::DictionaryValue* policies); |
255 bool OnCurtainPolicyUpdate(base::DictionaryValue* policies); | 276 bool OnCurtainPolicyUpdate(base::DictionaryValue* policies); |
256 bool OnHostTalkGadgetPrefixPolicyUpdate(base::DictionaryValue* policies); | 277 bool OnHostTalkGadgetPrefixPolicyUpdate(base::DictionaryValue* policies); |
257 bool OnHostTokenUrlPolicyUpdate(base::DictionaryValue* policies); | 278 bool OnHostTokenUrlPolicyUpdate(base::DictionaryValue* policies); |
258 bool OnPairingPolicyUpdate(base::DictionaryValue* policies); | 279 bool OnPairingPolicyUpdate(base::DictionaryValue* policies); |
259 bool OnGnubbyAuthPolicyUpdate(base::DictionaryValue* policies); | 280 bool OnGnubbyAuthPolicyUpdate(base::DictionaryValue* policies); |
260 | 281 |
261 scoped_ptr<HostSignalingManager> CreateHostSignalingManager(); | 282 scoped_ptr<HostSignalingManager> CreateHostSignalingManager(); |
262 | 283 |
263 void StartHostIfReady(); | 284 void StartHostIfReady(); |
264 void StartHost(); | 285 void StartHost(); |
265 | 286 |
266 // Overrides for HostSignalingManager::Listener interface. | 287 // Overrides for HostSignalingManager::Listener interface. |
267 void OnHeartbeatSuccessful() override; | 288 void OnHeartbeatSuccessful() override; |
268 void OnUnknownHostIdError() override; | 289 void OnUnknownHostIdError() override; |
269 void OnAuthFailed() override; | 290 void OnAuthFailed() override; |
270 | 291 |
271 void RestartHost(); | 292 void RestartHost(); |
272 | 293 |
273 // Stops the host and shuts down the process with the specified |exit_code|. | 294 // Stops the host and shuts down the process with the specified |exit_code|. |
274 void ShutdownHost(HostExitCodes exit_code); | 295 void ShutdownHost(HostExitCodes exit_code); |
275 | 296 |
276 // Private helper used by ShutdownHost method to initiate sending of | 297 // Starts host shut down with an optional |host_offline_reason|. |
277 // host-offline-reason before continuing shutdown. | 298 void ShutdownOnNetworkThread(const std::string& host_offline_reason); |
278 void SendOfflineReasonAndShutdownOnNetworkThread(HostExitCodes exit_code); | 299 void OnHostOfflineReasonAck(bool success); |
279 | |
280 void ShutdownOnNetworkThread(); | |
281 | 300 |
282 #if defined(OS_WIN) | 301 #if defined(OS_WIN) |
283 // Initializes the pairing registry on Windows. This should be invoked on the | 302 // Initializes the pairing registry on Windows. This should be invoked on the |
284 // network thread. | 303 // network thread. |
285 void InitializePairingRegistry( | 304 void InitializePairingRegistry( |
286 IPC::PlatformFileForTransit privileged_key, | 305 IPC::PlatformFileForTransit privileged_key, |
287 IPC::PlatformFileForTransit unprivileged_key); | 306 IPC::PlatformFileForTransit unprivileged_key); |
288 #endif // defined(OS_WIN) | 307 #endif // defined(OS_WIN) |
289 | 308 |
290 // Crashes the process in response to a daemon's request. The daemon passes | 309 // Crashes the process in response to a daemon's request. The daemon passes |
(...skipping 27 matching lines...) Expand all Loading... | |
318 scoped_refptr<RsaKeyPair> key_pair_; | 337 scoped_refptr<RsaKeyPair> key_pair_; |
319 std::string oauth_refresh_token_; | 338 std::string oauth_refresh_token_; |
320 std::string serialized_config_; | 339 std::string serialized_config_; |
321 std::string host_owner_; | 340 std::string host_owner_; |
322 std::string host_owner_email_; | 341 std::string host_owner_email_; |
323 bool use_service_account_; | 342 bool use_service_account_; |
324 bool enable_vp9_; | 343 bool enable_vp9_; |
325 int64_t frame_recorder_buffer_size_; | 344 int64_t frame_recorder_buffer_size_; |
326 | 345 |
327 scoped_ptr<PolicyWatcher> policy_watcher_; | 346 scoped_ptr<PolicyWatcher> policy_watcher_; |
328 bool policies_loaded_; | 347 PolicyState policy_state_; |
329 std::string host_domain_; | 348 std::string host_domain_; |
330 bool host_username_match_required_; | 349 bool host_username_match_required_; |
331 bool allow_nat_traversal_; | 350 bool allow_nat_traversal_; |
332 bool allow_relay_; | 351 bool allow_relay_; |
333 uint16 min_udp_port_; | 352 uint16 min_udp_port_; |
334 uint16 max_udp_port_; | 353 uint16 max_udp_port_; |
335 std::string talkgadget_prefix_; | 354 std::string talkgadget_prefix_; |
336 bool allow_pairing_; | 355 bool allow_pairing_; |
337 | 356 |
338 bool curtain_required_; | 357 bool curtain_required_; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
374 }; | 393 }; |
375 | 394 |
376 HostProcess::HostProcess(scoped_ptr<ChromotingHostContext> context, | 395 HostProcess::HostProcess(scoped_ptr<ChromotingHostContext> context, |
377 int* exit_code_out, | 396 int* exit_code_out, |
378 ShutdownWatchdog* shutdown_watchdog) | 397 ShutdownWatchdog* shutdown_watchdog) |
379 : context_(context.Pass()), | 398 : context_(context.Pass()), |
380 state_(HOST_INITIALIZING), | 399 state_(HOST_INITIALIZING), |
381 use_service_account_(false), | 400 use_service_account_(false), |
382 enable_vp9_(false), | 401 enable_vp9_(false), |
383 frame_recorder_buffer_size_(0), | 402 frame_recorder_buffer_size_(0), |
384 policies_loaded_(false), | 403 policy_state_(POLICY_INITIALIZING), |
385 host_username_match_required_(false), | 404 host_username_match_required_(false), |
386 allow_nat_traversal_(true), | 405 allow_nat_traversal_(true), |
387 allow_relay_(true), | 406 allow_relay_(true), |
388 min_udp_port_(0), | 407 min_udp_port_(0), |
389 max_udp_port_(0), | 408 max_udp_port_(0), |
390 allow_pairing_(true), | 409 allow_pairing_(true), |
391 curtain_required_(false), | 410 curtain_required_(false), |
392 enable_gnubby_auth_(false), | 411 enable_gnubby_auth_(false), |
393 enable_window_capture_(false), | 412 enable_window_capture_(false), |
394 window_id_(0), | 413 window_id_(0), |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
544 ShutdownHost(kInvalidHostConfigurationExitCode); | 563 ShutdownHost(kInvalidHostConfigurationExitCode); |
545 return; | 564 return; |
546 } | 565 } |
547 | 566 |
548 if (!ApplyConfig(*config)) { | 567 if (!ApplyConfig(*config)) { |
549 LOG(ERROR) << "Failed to apply the configuration."; | 568 LOG(ERROR) << "Failed to apply the configuration."; |
550 ShutdownHost(kInvalidHostConfigurationExitCode); | 569 ShutdownHost(kInvalidHostConfigurationExitCode); |
551 return; | 570 return; |
552 } | 571 } |
553 | 572 |
554 if (state_ == HOST_INITIALIZING) { | 573 if (state_ == HOST_INITIALIZING || state_ == HOST_STOPPING_TO_RESTART) { |
555 StartHostIfReady(); | 574 StartHostIfReady(); |
556 } else if (state_ == HOST_STARTED) { | 575 } else if (state_ == HOST_STARTED) { |
557 DCHECK(policies_loaded_); | |
558 | |
559 // Reapply policies that could be affected by a new config. | 576 // Reapply policies that could be affected by a new config. |
577 DCHECK(policy_state_ == POLICY_LOADED); | |
560 ApplyHostDomainPolicy(); | 578 ApplyHostDomainPolicy(); |
561 ApplyUsernamePolicy(); | 579 ApplyUsernamePolicy(); |
562 | 580 |
563 // TODO(sergeyu): Here we assume that PIN is the only part of the config | 581 // TODO(sergeyu): Here we assume that PIN is the only part of the config |
564 // that may change while the service is running. Change ApplyConfig() to | 582 // that may change while the service is running. Change ApplyConfig() to |
565 // detect other changes in the config and restart host if necessary here. | 583 // detect other changes in the config and restart host if necessary here. |
566 CreateAuthenticatorFactory(); | 584 CreateAuthenticatorFactory(); |
567 } | 585 } |
568 } | 586 } |
569 | 587 |
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
974 // Note: UsernamePolicyUpdate must run after OnCurtainPolicyUpdate. | 992 // Note: UsernamePolicyUpdate must run after OnCurtainPolicyUpdate. |
975 restart_required |= OnUsernamePolicyUpdate(policies.get()); | 993 restart_required |= OnUsernamePolicyUpdate(policies.get()); |
976 restart_required |= OnNatPolicyUpdate(policies.get()); | 994 restart_required |= OnNatPolicyUpdate(policies.get()); |
977 restart_required |= OnRelayPolicyUpdate(policies.get()); | 995 restart_required |= OnRelayPolicyUpdate(policies.get()); |
978 restart_required |= OnUdpPortPolicyUpdate(policies.get()); | 996 restart_required |= OnUdpPortPolicyUpdate(policies.get()); |
979 restart_required |= OnHostTalkGadgetPrefixPolicyUpdate(policies.get()); | 997 restart_required |= OnHostTalkGadgetPrefixPolicyUpdate(policies.get()); |
980 restart_required |= OnHostTokenUrlPolicyUpdate(policies.get()); | 998 restart_required |= OnHostTokenUrlPolicyUpdate(policies.get()); |
981 restart_required |= OnPairingPolicyUpdate(policies.get()); | 999 restart_required |= OnPairingPolicyUpdate(policies.get()); |
982 restart_required |= OnGnubbyAuthPolicyUpdate(policies.get()); | 1000 restart_required |= OnGnubbyAuthPolicyUpdate(policies.get()); |
983 | 1001 |
984 policies_loaded_ = true; | 1002 policy_state_ = POLICY_LOADED; |
985 | 1003 |
986 if (state_ == HOST_INITIALIZING) { | 1004 if (state_ == HOST_INITIALIZING || state_ == HOST_STOPPING_TO_RESTART) { |
987 StartHostIfReady(); | 1005 StartHostIfReady(); |
988 } else if (state_ == HOST_STARTED) { | 1006 } else if (state_ == HOST_STARTED) { |
989 if (restart_required) | 1007 if (restart_required) |
990 RestartHost(); | 1008 RestartHost(); |
991 } | 1009 } |
992 } | 1010 } |
993 | 1011 |
994 void HostProcess::OnPolicyError() { | 1012 void HostProcess::OnPolicyError() { |
995 if (!context_->network_task_runner()->BelongsToCurrentThread()) { | 1013 if (!context_->network_task_runner()->BelongsToCurrentThread()) { |
996 context_->network_task_runner()->PostTask( | 1014 context_->network_task_runner()->PostTask( |
997 FROM_HERE, base::Bind(&HostProcess::OnPolicyError, this)); | 1015 FROM_HERE, base::Bind(&HostProcess::OnPolicyError, this)); |
998 return; | 1016 return; |
999 } | 1017 } |
1000 | 1018 |
1001 ShutdownHost(kInvalidHostConfigurationExitCode); | 1019 if (policy_state_ != POLICY_ERROR_REPORTED) { |
1020 policy_state_ = POLICY_ERROR_REPORT_PENDING; | |
1021 if (state_ == HOST_INITIALIZING) { | |
1022 StartHostIfReady(); | |
1023 } else if (state_ == HOST_STARTED) { | |
1024 ReportPolicyErrorAndRestartHost(); | |
1025 } | |
1026 } | |
1027 } | |
1028 | |
1029 void HostProcess::ReportPolicyErrorAndRestartHost() { | |
1030 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | |
1031 DCHECK_EQ(policy_state_, POLICY_ERROR_REPORT_PENDING); | |
1032 | |
1033 LOG(INFO) << "Restarting the host due to policy errors."; | |
1034 | |
1035 policy_state_ = POLICY_ERROR_REPORTED; | |
1036 state_ = HOST_STOPPING_TO_RESTART; | |
1037 | |
1038 ShutdownOnNetworkThread(kHostOfflineBecauseOfPolicyReadError); | |
1002 } | 1039 } |
1003 | 1040 |
1004 void HostProcess::ApplyHostDomainPolicy() { | 1041 void HostProcess::ApplyHostDomainPolicy() { |
1005 if (state_ != HOST_STARTED) | 1042 if (state_ != HOST_STARTED) |
1006 return; | 1043 return; |
1007 | 1044 |
1008 HOST_LOG << "Policy sets host domain: " << host_domain_; | 1045 HOST_LOG << "Policy sets host domain: " << host_domain_; |
1009 | 1046 |
1010 if (!host_domain_.empty()) { | 1047 if (!host_domain_.empty()) { |
1011 // If the user does not have a Google email, their client JID will not be | 1048 // If the user does not have a Google email, their client JID will not be |
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1293 } | 1330 } |
1294 | 1331 |
1295 scoped_ptr<HostSignalingManager> HostProcess::CreateHostSignalingManager() { | 1332 scoped_ptr<HostSignalingManager> HostProcess::CreateHostSignalingManager() { |
1296 DCHECK(!host_id_.empty()); // |ApplyConfig| should already have been run. | 1333 DCHECK(!host_id_.empty()); // |ApplyConfig| should already have been run. |
1297 | 1334 |
1298 scoped_ptr<OAuthTokenGetter::OAuthCredentials> oauth_credentials( | 1335 scoped_ptr<OAuthTokenGetter::OAuthCredentials> oauth_credentials( |
1299 new OAuthTokenGetter::OAuthCredentials(xmpp_server_config_.username, | 1336 new OAuthTokenGetter::OAuthCredentials(xmpp_server_config_.username, |
1300 oauth_refresh_token_, | 1337 oauth_refresh_token_, |
1301 use_service_account_)); | 1338 use_service_account_)); |
1302 | 1339 |
1303 return HostSignalingManager::Create(this, context_->network_task_runner(), | 1340 return HostSignalingManager::Create( |
1304 context_->url_request_context_getter(), | 1341 this, context_->url_request_context_getter(), xmpp_server_config_, |
1305 xmpp_server_config_, talkgadget_prefix_, | 1342 talkgadget_prefix_, host_id_, key_pair_, directory_bot_jid_, |
1306 host_id_, key_pair_, directory_bot_jid_, | 1343 oauth_credentials.Pass()); |
1307 oauth_credentials.Pass()); | |
1308 } | 1344 } |
1309 | 1345 |
1310 void HostProcess::StartHostIfReady() { | 1346 void HostProcess::StartHostIfReady() { |
1311 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | 1347 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
1312 DCHECK_EQ(state_, HOST_INITIALIZING); | 1348 DCHECK((state_ == HOST_INITIALIZING) || (state_ == HOST_STOPPING_TO_RESTART)); |
1313 | 1349 |
1314 // Start the host if both the config and the policies are loaded. | 1350 // Start the host if both the config and the policies are loaded. |
1315 if (!serialized_config_.empty() && policies_loaded_) | 1351 if (!serialized_config_.empty()) { |
1316 StartHost(); | 1352 if (policy_state_ == POLICY_LOADED) { |
1353 StartHost(); | |
1354 } else if (policy_state_ == POLICY_ERROR_REPORT_PENDING) { | |
1355 ReportPolicyErrorAndRestartHost(); | |
1356 } | |
1357 } | |
1317 } | 1358 } |
1318 | 1359 |
1319 void HostProcess::StartHost() { | 1360 void HostProcess::StartHost() { |
1320 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | 1361 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
1321 DCHECK(!host_); | 1362 DCHECK(!host_); |
1322 DCHECK(!host_signaling_manager_); | 1363 DCHECK(!host_signaling_manager_); |
1323 | 1364 |
1324 DCHECK(state_ == HOST_INITIALIZING || state_ == HOST_STOPPING_TO_RESTART || | 1365 DCHECK(state_ == HOST_INITIALIZING || state_ == HOST_STOPPING_TO_RESTART || |
1325 state_ == HOST_STOPPED) | 1366 state_ == HOST_STOPPED) |
1326 << "state_ = " << state_; | 1367 << "state_ = " << state_; |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1407 | 1448 |
1408 void HostProcess::OnAuthFailed() { | 1449 void HostProcess::OnAuthFailed() { |
1409 ShutdownHost(kInvalidOauthCredentialsExitCode); | 1450 ShutdownHost(kInvalidOauthCredentialsExitCode); |
1410 } | 1451 } |
1411 | 1452 |
1412 void HostProcess::RestartHost() { | 1453 void HostProcess::RestartHost() { |
1413 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | 1454 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
1414 DCHECK_EQ(state_, HOST_STARTED); | 1455 DCHECK_EQ(state_, HOST_STARTED); |
1415 | 1456 |
1416 state_ = HOST_STOPPING_TO_RESTART; | 1457 state_ = HOST_STOPPING_TO_RESTART; |
1417 ShutdownOnNetworkThread(); | 1458 ShutdownOnNetworkThread(kHostOfflineBecauseOfRestarting); |
1418 } | |
1419 | |
1420 void HostProcess::SendOfflineReasonAndShutdownOnNetworkThread( | |
1421 HostExitCodes exit_code) { | |
1422 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | |
1423 DCHECK(host_signaling_manager_); | |
1424 host_signaling_manager_.release()->SendHostOfflineReasonAndDelete( | |
1425 ExitCodeToString(exit_code), | |
1426 base::TimeDelta::FromSeconds(kHostOfflineReasonTimeoutSeconds)); | |
1427 ShutdownOnNetworkThread(); | |
1428 } | 1459 } |
1429 | 1460 |
1430 void HostProcess::ShutdownHost(HostExitCodes exit_code) { | 1461 void HostProcess::ShutdownHost(HostExitCodes exit_code) { |
1431 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | 1462 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
1432 | 1463 |
1433 *exit_code_out_ = exit_code; | 1464 *exit_code_out_ = exit_code; |
1465 std::string host_offline_reason = ExitCodeToString(exit_code); | |
1434 | 1466 |
1435 switch (state_) { | 1467 switch (state_) { |
1436 case HOST_INITIALIZING: | 1468 case HOST_INITIALIZING: |
1437 state_ = HOST_STOPPING; | |
1438 DCHECK(!host_signaling_manager_); | |
1439 host_signaling_manager_ = CreateHostSignalingManager(); | |
1440 SendOfflineReasonAndShutdownOnNetworkThread(exit_code); | |
1441 break; | |
1442 | |
1443 case HOST_STARTED: | 1469 case HOST_STARTED: |
1444 state_ = HOST_STOPPING; | 1470 state_ = HOST_STOPPING; |
1445 SendOfflineReasonAndShutdownOnNetworkThread(exit_code); | 1471 ShutdownOnNetworkThread(host_offline_reason); |
1446 break; | 1472 break; |
1447 | 1473 |
1448 case HOST_STOPPING_TO_RESTART: | 1474 case HOST_STOPPING_TO_RESTART: |
1449 state_ = HOST_STOPPING; | 1475 state_ = HOST_STOPPING; |
1450 break; | 1476 break; |
1451 | 1477 |
1452 case HOST_STOPPING: | 1478 case HOST_STOPPING: |
1453 case HOST_STOPPED: | 1479 case HOST_STOPPED: |
1454 // Host is already stopped or being stopped. No action is required. | 1480 // Host is already stopped or being stopped. No action is required. |
1455 break; | 1481 break; |
1456 } | 1482 } |
1457 } | 1483 } |
1458 | 1484 |
1459 void HostProcess::ShutdownOnNetworkThread() { | 1485 void HostProcess::ShutdownOnNetworkThread( |
1486 const std::string& host_offline_reason) { | |
1460 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | 1487 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
1461 | 1488 |
1489 // Shut down most host subsystems ... | |
1462 host_.reset(); | 1490 host_.reset(); |
1463 host_event_logger_.reset(); | 1491 host_event_logger_.reset(); |
1464 host_status_logger_.reset(); | 1492 host_status_logger_.reset(); |
1465 host_signaling_manager_.reset(); | |
1466 host_change_notification_listener_.reset(); | 1493 host_change_notification_listener_.reset(); |
1467 | 1494 |
1495 // ... but before shutting down |host_signaling_manager_|, check if we still | |
1496 // need it for sending a |host_offline_reason| first. | |
1497 if (!host_offline_reason.empty() && serialized_config_.empty()) { | |
Wez
2015/02/12 21:07:07
This would read more clearly as:
if (!host_offlin
Łukasz Anforowicz
2015/02/12 22:51:13
Done.
| |
1498 HOST_LOG << "SendHostOfflineReason( " << host_offline_reason << ") " | |
1499 << "not possible without a config..."; | |
1500 } else if (!host_offline_reason.empty()) { | |
1501 if (!host_signaling_manager_) { | |
1502 host_signaling_manager_ = CreateHostSignalingManager(); | |
1503 } | |
1504 | |
1505 host_signaling_manager_->SendHostOfflineReason( | |
1506 host_offline_reason, | |
1507 base::TimeDelta::FromSeconds(kHostOfflineReasonTimeoutSeconds), | |
1508 base::Bind(&HostProcess::OnHostOfflineReasonAck, | |
1509 base::Unretained(this))); | |
1510 return; // Shutdown will resume after OnHostOfflineReasonAck. | |
1511 } | |
1512 host_signaling_manager_.reset(); | |
1513 | |
1468 if (state_ == HOST_STOPPING_TO_RESTART) { | 1514 if (state_ == HOST_STOPPING_TO_RESTART) { |
1469 StartHost(); | 1515 StartHostIfReady(); |
1470 } else if (state_ == HOST_STOPPING) { | 1516 } else if (state_ == HOST_STOPPING) { |
1471 state_ = HOST_STOPPED; | 1517 state_ = HOST_STOPPED; |
1472 | 1518 |
1473 shutdown_watchdog_->SetExitCode(*exit_code_out_); | 1519 shutdown_watchdog_->SetExitCode(*exit_code_out_); |
1474 shutdown_watchdog_->Arm(); | 1520 shutdown_watchdog_->Arm(); |
1475 | 1521 |
1476 config_watcher_.reset(); | 1522 config_watcher_.reset(); |
1477 | 1523 |
1478 // Complete the rest of shutdown on the main thread. | 1524 // Complete the rest of shutdown on the main thread. |
1479 context_->ui_task_runner()->PostTask( | 1525 context_->ui_task_runner()->PostTask( |
1480 FROM_HERE, base::Bind(&HostProcess::ShutdownOnUiThread, this)); | 1526 FROM_HERE, base::Bind(&HostProcess::ShutdownOnUiThread, this)); |
1481 } else { | 1527 } else { |
1482 // This method is only called in STOPPING_TO_RESTART and STOPPING states. | 1528 // This method is only called in STOPPING_TO_RESTART and STOPPING states. |
1483 NOTREACHED(); | 1529 NOTREACHED(); |
1484 } | 1530 } |
1485 } | 1531 } |
1486 | 1532 |
1533 void HostProcess::OnHostOfflineReasonAck(bool success) { | |
1534 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | |
1535 | |
1536 if (success) { | |
1537 HOST_LOG << "SendHostOfflineReason: succeeded"; | |
1538 } else { | |
1539 HOST_LOG << "SendHostOfflineReason: timed out"; | |
1540 } | |
1541 | |
1542 ShutdownOnNetworkThread(std::string()); | |
Wez
2015/02/12 21:07:07
Now that I see this written out, it seems less cle
Łukasz Anforowicz
2015/02/12 22:51:13
I think I like it better this way.
If we have a
Łukasz Anforowicz
2015/02/13 20:41:00
Actually, when addressing Sergey's feedback (and t
| |
1543 } | |
1544 | |
1487 void HostProcess::OnCrash(const std::string& function_name, | 1545 void HostProcess::OnCrash(const std::string& function_name, |
1488 const std::string& file_name, | 1546 const std::string& file_name, |
1489 const int& line_number) { | 1547 const int& line_number) { |
1490 char message[1024]; | 1548 char message[1024]; |
1491 base::snprintf(message, sizeof(message), | 1549 base::snprintf(message, sizeof(message), |
1492 "Requested by %s at %s, line %d.", | 1550 "Requested by %s at %s, line %d.", |
1493 function_name.c_str(), file_name.c_str(), line_number); | 1551 function_name.c_str(), file_name.c_str(), line_number); |
1494 base::debug::Alias(message); | 1552 base::debug::Alias(message); |
1495 | 1553 |
1496 // The daemon requested us to crash the process. | 1554 // The daemon requested us to crash the process. |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1542 base::TimeDelta::FromSeconds(kShutdownTimeoutSeconds)); | 1600 base::TimeDelta::FromSeconds(kShutdownTimeoutSeconds)); |
1543 new HostProcess(context.Pass(), &exit_code, &shutdown_watchdog); | 1601 new HostProcess(context.Pass(), &exit_code, &shutdown_watchdog); |
1544 | 1602 |
1545 // Run the main (also UI) message loop until the host no longer needs it. | 1603 // Run the main (also UI) message loop until the host no longer needs it. |
1546 message_loop.Run(); | 1604 message_loop.Run(); |
1547 | 1605 |
1548 return exit_code; | 1606 return exit_code; |
1549 } | 1607 } |
1550 | 1608 |
1551 } // namespace remoting | 1609 } // namespace remoting |
OLD | NEW |