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 // 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 17 matching lines...) Expand all Loading... | |
| 28 #include "media/base/media.h" | 28 #include "media/base/media.h" |
| 29 #include "net/base/network_change_notifier.h" | 29 #include "net/base/network_change_notifier.h" |
| 30 #include "net/socket/client_socket_factory.h" | 30 #include "net/socket/client_socket_factory.h" |
| 31 #include "net/socket/ssl_server_socket.h" | 31 #include "net/socket/ssl_server_socket.h" |
| 32 #include "net/url_request/url_fetcher.h" | 32 #include "net/url_request/url_fetcher.h" |
| 33 #include "policy/policy_constants.h" | 33 #include "policy/policy_constants.h" |
| 34 #include "remoting/base/auto_thread_task_runner.h" | 34 #include "remoting/base/auto_thread_task_runner.h" |
| 35 #include "remoting/base/breakpad.h" | 35 #include "remoting/base/breakpad.h" |
| 36 #include "remoting/base/constants.h" | 36 #include "remoting/base/constants.h" |
| 37 #include "remoting/base/logging.h" | 37 #include "remoting/base/logging.h" |
| 38 #include "remoting/base/port_range.h" | |
| 38 #include "remoting/base/rsa_key_pair.h" | 39 #include "remoting/base/rsa_key_pair.h" |
| 39 #include "remoting/base/service_urls.h" | 40 #include "remoting/base/service_urls.h" |
| 40 #include "remoting/base/util.h" | 41 #include "remoting/base/util.h" |
| 41 #include "remoting/host/branding.h" | 42 #include "remoting/host/branding.h" |
| 42 #include "remoting/host/chromoting_host.h" | 43 #include "remoting/host/chromoting_host.h" |
| 43 #include "remoting/host/chromoting_host_context.h" | 44 #include "remoting/host/chromoting_host_context.h" |
| 44 #include "remoting/host/chromoting_messages.h" | 45 #include "remoting/host/chromoting_messages.h" |
| 45 #include "remoting/host/config_file_watcher.h" | 46 #include "remoting/host/config_file_watcher.h" |
| 46 #include "remoting/host/config_watcher.h" | 47 #include "remoting/host/config_watcher.h" |
| 47 #include "remoting/host/desktop_environment.h" | 48 #include "remoting/host/desktop_environment.h" |
| 48 #include "remoting/host/desktop_session_connector.h" | 49 #include "remoting/host/desktop_session_connector.h" |
| 49 #include "remoting/host/host_change_notification_listener.h" | 50 #include "remoting/host/host_change_notification_listener.h" |
| 50 #include "remoting/host/host_config.h" | 51 #include "remoting/host/host_config.h" |
| 51 #include "remoting/host/host_event_logger.h" | 52 #include "remoting/host/host_event_logger.h" |
| 52 #include "remoting/host/host_exit_codes.h" | 53 #include "remoting/host/host_exit_codes.h" |
| 53 #include "remoting/host/host_main.h" | 54 #include "remoting/host/host_main.h" |
| 54 #include "remoting/host/host_signaling_manager.h" | 55 #include "remoting/host/host_signaling_manager.h" |
| 55 #include "remoting/host/host_status_logger.h" | 56 #include "remoting/host/host_status_logger.h" |
| 56 #include "remoting/host/ipc_constants.h" | 57 #include "remoting/host/ipc_constants.h" |
| 57 #include "remoting/host/ipc_desktop_environment.h" | 58 #include "remoting/host/ipc_desktop_environment.h" |
| 58 #include "remoting/host/ipc_host_event_logger.h" | 59 #include "remoting/host/ipc_host_event_logger.h" |
| 59 #include "remoting/host/logging.h" | 60 #include "remoting/host/logging.h" |
| 60 #include "remoting/host/me2me_desktop_environment.h" | 61 #include "remoting/host/me2me_desktop_environment.h" |
| 61 #include "remoting/host/pairing_registry_delegate.h" | 62 #include "remoting/host/pairing_registry_delegate.h" |
| 62 #include "remoting/host/policy_watcher.h" | 63 #include "remoting/host/policy_watcher.h" |
| 63 #include "remoting/host/session_manager_factory.h" | 64 #include "remoting/host/session_manager_factory.h" |
| 64 #include "remoting/host/shutdown_watchdog.h" | 65 #include "remoting/host/shutdown_watchdog.h" |
| 65 #include "remoting/host/signaling_connector.h" | 66 #include "remoting/host/signaling_connector.h" |
| 66 #include "remoting/host/single_window_desktop_environment.h" | 67 #include "remoting/host/single_window_desktop_environment.h" |
| 68 #include "remoting/host/third_party_auth_config.h" | |
| 67 #include "remoting/host/token_validator_factory_impl.h" | 69 #include "remoting/host/token_validator_factory_impl.h" |
| 68 #include "remoting/host/usage_stats_consent.h" | 70 #include "remoting/host/usage_stats_consent.h" |
| 69 #include "remoting/host/username.h" | 71 #include "remoting/host/username.h" |
| 70 #include "remoting/host/video_frame_recorder_host_extension.h" | 72 #include "remoting/host/video_frame_recorder_host_extension.h" |
| 71 #include "remoting/protocol/me2me_host_authenticator_factory.h" | 73 #include "remoting/protocol/me2me_host_authenticator_factory.h" |
| 72 #include "remoting/protocol/network_settings.h" | 74 #include "remoting/protocol/network_settings.h" |
| 73 #include "remoting/protocol/pairing_registry.h" | 75 #include "remoting/protocol/pairing_registry.h" |
| 74 #include "remoting/protocol/token_validator.h" | 76 #include "remoting/protocol/token_validator.h" |
| 75 #include "remoting/signaling/xmpp_signal_strategy.h" | 77 #include "remoting/signaling/xmpp_signal_strategy.h" |
| 76 | 78 |
| (...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 332 bool use_service_account_; | 334 bool use_service_account_; |
| 333 bool enable_vp9_; | 335 bool enable_vp9_; |
| 334 int64_t frame_recorder_buffer_size_; | 336 int64_t frame_recorder_buffer_size_; |
| 335 | 337 |
| 336 scoped_ptr<PolicyWatcher> policy_watcher_; | 338 scoped_ptr<PolicyWatcher> policy_watcher_; |
| 337 PolicyState policy_state_; | 339 PolicyState policy_state_; |
| 338 std::string host_domain_; | 340 std::string host_domain_; |
| 339 bool host_username_match_required_; | 341 bool host_username_match_required_; |
| 340 bool allow_nat_traversal_; | 342 bool allow_nat_traversal_; |
| 341 bool allow_relay_; | 343 bool allow_relay_; |
| 342 uint16 min_udp_port_; | 344 PortRange udp_port_range_; |
| 343 uint16 max_udp_port_; | |
| 344 std::string talkgadget_prefix_; | 345 std::string talkgadget_prefix_; |
| 345 bool allow_pairing_; | 346 bool allow_pairing_; |
| 346 | 347 |
| 347 bool curtain_required_; | 348 bool curtain_required_; |
| 348 ThirdPartyAuthConfig third_party_auth_config_; | 349 ThirdPartyAuthConfig third_party_auth_config_; |
| 349 bool enable_gnubby_auth_; | 350 bool enable_gnubby_auth_; |
| 350 | 351 |
| 351 // Boolean to change flow, where necessary, if we're | 352 // Boolean to change flow, where necessary, if we're |
| 352 // capturing a window instead of the entire desktop. | 353 // capturing a window instead of the entire desktop. |
| 353 bool enable_window_capture_; | 354 bool enable_window_capture_; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 387 ShutdownWatchdog* shutdown_watchdog) | 388 ShutdownWatchdog* shutdown_watchdog) |
| 388 : context_(context.Pass()), | 389 : context_(context.Pass()), |
| 389 state_(HOST_STARTING), | 390 state_(HOST_STARTING), |
| 390 use_service_account_(false), | 391 use_service_account_(false), |
| 391 enable_vp9_(false), | 392 enable_vp9_(false), |
| 392 frame_recorder_buffer_size_(0), | 393 frame_recorder_buffer_size_(0), |
| 393 policy_state_(POLICY_INITIALIZING), | 394 policy_state_(POLICY_INITIALIZING), |
| 394 host_username_match_required_(false), | 395 host_username_match_required_(false), |
| 395 allow_nat_traversal_(true), | 396 allow_nat_traversal_(true), |
| 396 allow_relay_(true), | 397 allow_relay_(true), |
| 397 min_udp_port_(0), | |
|
Sergey Ulanov
2015/02/27 03:05:19
Without PortRange constructor the values inside of
Łukasz Anforowicz
2015/02/27 18:36:12
Right. Hmmm... I realized this, but for some reas
| |
| 398 max_udp_port_(0), | |
| 399 allow_pairing_(true), | 398 allow_pairing_(true), |
| 400 curtain_required_(false), | 399 curtain_required_(false), |
| 401 enable_gnubby_auth_(false), | 400 enable_gnubby_auth_(false), |
| 402 enable_window_capture_(false), | 401 enable_window_capture_(false), |
| 403 window_id_(0), | 402 window_id_(0), |
| 404 #if defined(REMOTING_MULTI_PROCESS) | 403 #if defined(REMOTING_MULTI_PROCESS) |
| 405 desktop_session_connector_(nullptr), | 404 desktop_session_connector_(nullptr), |
| 406 #endif // defined(REMOTING_MULTI_PROCESS) | 405 #endif // defined(REMOTING_MULTI_PROCESS) |
| 407 self_(this), | 406 self_(this), |
| 408 exit_code_out_(exit_code_out), | 407 exit_code_out_(exit_code_out), |
| (...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 689 #endif // defined(OS_WIN) | 688 #endif // defined(OS_WIN) |
| 690 | 689 |
| 691 pairing_registry = pairing_registry_; | 690 pairing_registry = pairing_registry_; |
| 692 } | 691 } |
| 693 | 692 |
| 694 factory = protocol::Me2MeHostAuthenticatorFactory::CreateWithSharedSecret( | 693 factory = protocol::Me2MeHostAuthenticatorFactory::CreateWithSharedSecret( |
| 695 use_service_account_, host_owner_, local_certificate, key_pair_, | 694 use_service_account_, host_owner_, local_certificate, key_pair_, |
| 696 host_secret_hash_, pairing_registry); | 695 host_secret_hash_, pairing_registry); |
| 697 | 696 |
| 698 host_->set_pairing_registry(pairing_registry); | 697 host_->set_pairing_registry(pairing_registry); |
| 699 } else if (third_party_auth_config_.is_valid()) { | 698 } else { |
| 699 CHECK(third_party_auth_config_.token_url.is_valid()); | |
| 700 CHECK(third_party_auth_config_.token_validation_url.is_valid()); | |
| 701 | |
| 700 scoped_ptr<protocol::TokenValidatorFactory> token_validator_factory( | 702 scoped_ptr<protocol::TokenValidatorFactory> token_validator_factory( |
| 701 new TokenValidatorFactoryImpl( | 703 new TokenValidatorFactoryImpl( |
| 702 third_party_auth_config_, | 704 third_party_auth_config_, |
| 703 key_pair_, context_->url_request_context_getter())); | 705 key_pair_, context_->url_request_context_getter())); |
| 704 factory = protocol::Me2MeHostAuthenticatorFactory::CreateWithThirdPartyAuth( | 706 factory = protocol::Me2MeHostAuthenticatorFactory::CreateWithThirdPartyAuth( |
| 705 use_service_account_, host_owner_, local_certificate, key_pair_, | 707 use_service_account_, host_owner_, local_certificate, key_pair_, |
| 706 token_validator_factory.Pass()); | 708 token_validator_factory.Pass()); |
| 707 | |
| 708 } else { | |
| 709 // TODO(rmsousa): If the policy is bad the host should not go online. It | |
| 710 // should keep running, but not connected, until the policies are fixed. | |
| 711 // Having it show up as online and then reject all clients is misleading. | |
| 712 LOG(ERROR) << "One of the third-party token URLs is empty or invalid. " | |
| 713 << "Host will reject all clients until policies are corrected. " | |
| 714 << "TokenUrl: " << third_party_auth_config_.token_url << ", " | |
| 715 << "TokenValidationUrl: " | |
| 716 << third_party_auth_config_.token_validation_url; | |
| 717 factory = protocol::Me2MeHostAuthenticatorFactory::CreateRejecting(); | |
| 718 } | 709 } |
| 719 | 710 |
| 720 #if defined(OS_POSIX) | 711 #if defined(OS_POSIX) |
| 721 // On Linux and Mac, perform a PAM authorization step after authentication. | 712 // On Linux and Mac, perform a PAM authorization step after authentication. |
| 722 factory.reset(new PamAuthorizationFactory(factory.Pass())); | 713 factory.reset(new PamAuthorizationFactory(factory.Pass())); |
| 723 #endif | 714 #endif |
| 724 host_->SetAuthenticatorFactory(factory.Pass()); | 715 host_->SetAuthenticatorFactory(factory.Pass()); |
| 725 } | 716 } |
| 726 | 717 |
| 727 // IPC::Listener implementation. | 718 // IPC::Listener implementation. |
| (...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1198 } else { | 1189 } else { |
| 1199 HOST_LOG << "Policy disables use of relay server."; | 1190 HOST_LOG << "Policy disables use of relay server."; |
| 1200 } | 1191 } |
| 1201 return true; | 1192 return true; |
| 1202 } | 1193 } |
| 1203 | 1194 |
| 1204 bool HostProcess::OnUdpPortPolicyUpdate(base::DictionaryValue* policies) { | 1195 bool HostProcess::OnUdpPortPolicyUpdate(base::DictionaryValue* policies) { |
| 1205 // Returns true if the host has to be restarted after this policy update. | 1196 // Returns true if the host has to be restarted after this policy update. |
| 1206 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | 1197 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
| 1207 | 1198 |
| 1208 std::string udp_port_range; | 1199 std::string string_value; |
| 1209 if (!policies->GetString(policy::key::kRemoteAccessHostUdpPortRange, | 1200 if (!policies->GetString(policy::key::kRemoteAccessHostUdpPortRange, |
| 1210 &udp_port_range)) { | 1201 &string_value)) { |
| 1211 return false; | 1202 return false; |
| 1212 } | 1203 } |
| 1213 | 1204 |
| 1214 // Use default values if policy setting is empty or invalid. | 1205 CHECK(PortRange::Parse(string_value, &udp_port_range_)); |
| 1215 uint16 min_udp_port = 0; | 1206 HOST_LOG << "Policy restricts UDP port range to: " << udp_port_range_; |
| 1216 uint16 max_udp_port = 0; | 1207 return true; |
| 1217 if (!udp_port_range.empty() && | |
| 1218 !NetworkSettings::ParsePortRange(udp_port_range, &min_udp_port, | |
| 1219 &max_udp_port)) { | |
| 1220 LOG(WARNING) << "Invalid port range policy: \"" << udp_port_range | |
| 1221 << "\". Using default values."; | |
| 1222 } | |
| 1223 | |
| 1224 if (min_udp_port_ != min_udp_port || max_udp_port_ != max_udp_port) { | |
| 1225 if (min_udp_port != 0 && max_udp_port != 0) { | |
| 1226 HOST_LOG << "Policy restricts UDP port range to [" << min_udp_port | |
| 1227 << ", " << max_udp_port << "]"; | |
| 1228 } else { | |
| 1229 HOST_LOG << "Policy does not restrict UDP port range."; | |
| 1230 } | |
| 1231 min_udp_port_ = min_udp_port; | |
| 1232 max_udp_port_ = max_udp_port; | |
| 1233 return true; | |
| 1234 } | |
| 1235 return false; | |
| 1236 } | 1208 } |
| 1237 | 1209 |
| 1238 bool HostProcess::OnCurtainPolicyUpdate(base::DictionaryValue* policies) { | 1210 bool HostProcess::OnCurtainPolicyUpdate(base::DictionaryValue* policies) { |
| 1239 // Returns true if the host has to be restarted after this policy update. | 1211 // Returns true if the host has to be restarted after this policy update. |
| 1240 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | 1212 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
| 1241 | 1213 |
| 1242 if (!policies->GetBoolean(policy::key::kRemoteAccessHostRequireCurtain, | 1214 if (!policies->GetBoolean(policy::key::kRemoteAccessHostRequireCurtain, |
| 1243 &curtain_required_)) { | 1215 &curtain_required_)) { |
| 1244 return false; | 1216 return false; |
| 1245 } | 1217 } |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1283 if (!policies->GetString(policy::key::kRemoteAccessHostTalkGadgetPrefix, | 1255 if (!policies->GetString(policy::key::kRemoteAccessHostTalkGadgetPrefix, |
| 1284 &talkgadget_prefix_)) { | 1256 &talkgadget_prefix_)) { |
| 1285 return false; | 1257 return false; |
| 1286 } | 1258 } |
| 1287 | 1259 |
| 1288 HOST_LOG << "Policy sets talkgadget prefix: " << talkgadget_prefix_; | 1260 HOST_LOG << "Policy sets talkgadget prefix: " << talkgadget_prefix_; |
| 1289 return true; | 1261 return true; |
| 1290 } | 1262 } |
| 1291 | 1263 |
| 1292 bool HostProcess::OnHostTokenUrlPolicyUpdate(base::DictionaryValue* policies) { | 1264 bool HostProcess::OnHostTokenUrlPolicyUpdate(base::DictionaryValue* policies) { |
| 1293 // Returns true if the host has to be restarted after this policy update. | 1265 // Extract 3 individial policy values. |
| 1294 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | 1266 std::string token_url; |
| 1295 | 1267 std::string token_validation_url; |
| 1296 bool token_policy_changed = false; | 1268 std::string token_validation_cert_issuer; |
| 1297 std::string token_url_string; | 1269 bool changed_entries_present = ThirdPartyAuthConfig::ExtractPolicyValues( |
| 1298 if (policies->GetString(policy::key::kRemoteAccessHostTokenUrl, | 1270 *policies, &token_url, &token_validation_url, |
| 1299 &token_url_string)) { | 1271 &token_validation_cert_issuer); |
| 1300 token_policy_changed = true; | 1272 if (!changed_entries_present) { |
| 1301 third_party_auth_config_.token_url = GURL(token_url_string); | 1273 return false; |
| 1302 } | |
| 1303 std::string token_validation_url_string; | |
| 1304 if (policies->GetString(policy::key::kRemoteAccessHostTokenValidationUrl, | |
| 1305 &token_validation_url_string)) { | |
| 1306 token_policy_changed = true; | |
| 1307 third_party_auth_config_.token_validation_url = | |
| 1308 GURL(token_validation_url_string); | |
| 1309 } | |
| 1310 if (policies->GetString( | |
| 1311 policy::key::kRemoteAccessHostTokenValidationCertificateIssuer, | |
| 1312 &third_party_auth_config_.token_validation_cert_issuer)) { | |
| 1313 token_policy_changed = true; | |
| 1314 } | 1274 } |
| 1315 | 1275 |
| 1316 if (token_policy_changed) { | 1276 // Parse the policy value. |
| 1317 HOST_LOG << "Policy sets third-party token URLs: " | 1277 ThirdPartyAuthConfig third_party_auth_config; |
| 1318 << "TokenUrl: " | 1278 CHECK(ThirdPartyAuthConfig::Parse(token_url, token_validation_url, |
| 1319 << third_party_auth_config_.token_url << ", " | 1279 token_validation_cert_issuer, |
| 1320 << "TokenValidationUrl: " | 1280 &third_party_auth_config_)); |
| 1321 << third_party_auth_config_.token_validation_url << ", " | 1281 HOST_LOG << "Policy sets third-party token URLs: " |
| 1322 << "TokenValidationCertificateIssuer: " | 1282 << third_party_auth_config_; |
| 1323 << third_party_auth_config_.token_validation_cert_issuer; | 1283 return true; |
| 1324 } | |
| 1325 return token_policy_changed; | |
| 1326 } | 1284 } |
| 1327 | 1285 |
| 1328 bool HostProcess::OnPairingPolicyUpdate(base::DictionaryValue* policies) { | 1286 bool HostProcess::OnPairingPolicyUpdate(base::DictionaryValue* policies) { |
| 1329 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | 1287 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
| 1330 | 1288 |
| 1331 if (!policies->GetBoolean(policy::key::kRemoteAccessHostAllowClientPairing, | 1289 if (!policies->GetBoolean(policy::key::kRemoteAccessHostAllowClientPairing, |
| 1332 &allow_pairing_)) { | 1290 &allow_pairing_)) { |
| 1333 return false; | 1291 return false; |
| 1334 } | 1292 } |
| 1335 | 1293 |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1401 uint32 network_flags = 0; | 1359 uint32 network_flags = 0; |
| 1402 if (allow_nat_traversal_) { | 1360 if (allow_nat_traversal_) { |
| 1403 network_flags = NetworkSettings::NAT_TRAVERSAL_STUN | | 1361 network_flags = NetworkSettings::NAT_TRAVERSAL_STUN | |
| 1404 NetworkSettings::NAT_TRAVERSAL_OUTGOING; | 1362 NetworkSettings::NAT_TRAVERSAL_OUTGOING; |
| 1405 if (allow_relay_) | 1363 if (allow_relay_) |
| 1406 network_flags |= NetworkSettings::NAT_TRAVERSAL_RELAY; | 1364 network_flags |= NetworkSettings::NAT_TRAVERSAL_RELAY; |
| 1407 } | 1365 } |
| 1408 | 1366 |
| 1409 NetworkSettings network_settings(network_flags); | 1367 NetworkSettings network_settings(network_flags); |
| 1410 | 1368 |
| 1411 if (min_udp_port_ && max_udp_port_) { | 1369 if (!udp_port_range_.is_empty()) { |
| 1412 network_settings.min_port = min_udp_port_; | 1370 network_settings.min_port = udp_port_range_.min_port; |
| 1413 network_settings.max_port = max_udp_port_; | 1371 network_settings.max_port = udp_port_range_.max_port; |
| 1414 } else if (!allow_nat_traversal_) { | 1372 } else if (!allow_nat_traversal_) { |
| 1415 // For legacy reasons we have to restrict the port range to a set of default | 1373 // For legacy reasons we have to restrict the port range to a set of default |
| 1416 // values when nat traversal is disabled, even if the port range was not | 1374 // values when nat traversal is disabled, even if the port range was not |
| 1417 // set in policy. | 1375 // set in policy. |
| 1418 network_settings.min_port = NetworkSettings::kDefaultMinPort; | 1376 network_settings.min_port = NetworkSettings::kDefaultMinPort; |
| 1419 network_settings.max_port = NetworkSettings::kDefaultMaxPort; | 1377 network_settings.max_port = NetworkSettings::kDefaultMaxPort; |
| 1420 } | 1378 } |
| 1421 | 1379 |
| 1422 host_.reset(new ChromotingHost( | 1380 host_.reset(new ChromotingHost( |
| 1423 host_signaling_manager_->signal_strategy(), | 1381 host_signaling_manager_->signal_strategy(), |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1626 base::TimeDelta::FromSeconds(kShutdownTimeoutSeconds)); | 1584 base::TimeDelta::FromSeconds(kShutdownTimeoutSeconds)); |
| 1627 new HostProcess(context.Pass(), &exit_code, &shutdown_watchdog); | 1585 new HostProcess(context.Pass(), &exit_code, &shutdown_watchdog); |
| 1628 | 1586 |
| 1629 // Run the main (also UI) message loop until the host no longer needs it. | 1587 // Run the main (also UI) message loop until the host no longer needs it. |
| 1630 message_loop.Run(); | 1588 message_loop.Run(); |
| 1631 | 1589 |
| 1632 return exit_code; | 1590 return exit_code; |
| 1633 } | 1591 } |
| 1634 | 1592 |
| 1635 } // namespace remoting | 1593 } // namespace remoting |
| OLD | NEW |