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 28 matching lines...) Expand all Loading... | |
| 39 #include "remoting/base/service_urls.h" | 39 #include "remoting/base/service_urls.h" |
| 40 #include "remoting/base/util.h" | 40 #include "remoting/base/util.h" |
| 41 #include "remoting/host/branding.h" | 41 #include "remoting/host/branding.h" |
| 42 #include "remoting/host/chromoting_host.h" | 42 #include "remoting/host/chromoting_host.h" |
| 43 #include "remoting/host/chromoting_host_context.h" | 43 #include "remoting/host/chromoting_host_context.h" |
| 44 #include "remoting/host/chromoting_messages.h" | 44 #include "remoting/host/chromoting_messages.h" |
| 45 #include "remoting/host/config_file_watcher.h" | 45 #include "remoting/host/config_file_watcher.h" |
| 46 #include "remoting/host/config_watcher.h" | 46 #include "remoting/host/config_watcher.h" |
| 47 #include "remoting/host/desktop_environment.h" | 47 #include "remoting/host/desktop_environment.h" |
| 48 #include "remoting/host/desktop_session_connector.h" | 48 #include "remoting/host/desktop_session_connector.h" |
| 49 #include "remoting/host/gcd_rest_client.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" |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 266 bool OnUsernamePolicyUpdate(base::DictionaryValue* policies); | 267 bool OnUsernamePolicyUpdate(base::DictionaryValue* policies); |
| 267 bool OnNatPolicyUpdate(base::DictionaryValue* policies); | 268 bool OnNatPolicyUpdate(base::DictionaryValue* policies); |
| 268 bool OnRelayPolicyUpdate(base::DictionaryValue* policies); | 269 bool OnRelayPolicyUpdate(base::DictionaryValue* policies); |
| 269 bool OnUdpPortPolicyUpdate(base::DictionaryValue* policies); | 270 bool OnUdpPortPolicyUpdate(base::DictionaryValue* policies); |
| 270 bool OnCurtainPolicyUpdate(base::DictionaryValue* policies); | 271 bool OnCurtainPolicyUpdate(base::DictionaryValue* policies); |
| 271 bool OnHostTalkGadgetPrefixPolicyUpdate(base::DictionaryValue* policies); | 272 bool OnHostTalkGadgetPrefixPolicyUpdate(base::DictionaryValue* policies); |
| 272 bool OnHostTokenUrlPolicyUpdate(base::DictionaryValue* policies); | 273 bool OnHostTokenUrlPolicyUpdate(base::DictionaryValue* policies); |
| 273 bool OnPairingPolicyUpdate(base::DictionaryValue* policies); | 274 bool OnPairingPolicyUpdate(base::DictionaryValue* policies); |
| 274 bool OnGnubbyAuthPolicyUpdate(base::DictionaryValue* policies); | 275 bool OnGnubbyAuthPolicyUpdate(base::DictionaryValue* policies); |
| 275 | 276 |
| 277 scoped_ptr<OAuthTokenGetter> CreateOAuthTokenGetter(); | |
| 278 scoped_ptr<GcdRestClient> CreateGcdRestClient(); | |
| 276 scoped_ptr<HostSignalingManager> CreateHostSignalingManager(); | 279 scoped_ptr<HostSignalingManager> CreateHostSignalingManager(); |
| 277 | 280 |
| 278 void StartHostIfReady(); | 281 void StartHostIfReady(); |
| 279 void StartHost(); | 282 void StartHost(); |
| 280 | 283 |
| 281 // Overrides for HostSignalingManager::Listener interface. | 284 // Overrides for HostSignalingManager::Listener interface. |
| 282 void OnHeartbeatSuccessful() override; | 285 void OnHeartbeatSuccessful() override; |
| 283 void OnUnknownHostIdError() override; | 286 void OnUnknownHostIdError() override; |
| 284 void OnAuthFailed() override; | 287 void OnAuthFailed() override; |
| 285 | 288 |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 298 IPC::PlatformFileForTransit unprivileged_key); | 301 IPC::PlatformFileForTransit unprivileged_key); |
| 299 #endif // defined(OS_WIN) | 302 #endif // defined(OS_WIN) |
| 300 | 303 |
| 301 // Crashes the process in response to a daemon's request. The daemon passes | 304 // Crashes the process in response to a daemon's request. The daemon passes |
| 302 // the location of the code that detected the fatal error resulted in this | 305 // the location of the code that detected the fatal error resulted in this |
| 303 // request. | 306 // request. |
| 304 void OnCrash(const std::string& function_name, | 307 void OnCrash(const std::string& function_name, |
| 305 const std::string& file_name, | 308 const std::string& file_name, |
| 306 const int& line_number); | 309 const int& line_number); |
| 307 | 310 |
| 311 bool using_gcd() { return !gcd_device_id_.empty(); } | |
| 312 | |
| 308 scoped_ptr<ChromotingHostContext> context_; | 313 scoped_ptr<ChromotingHostContext> context_; |
| 309 | 314 |
| 310 // Accessed on the UI thread. | 315 // Accessed on the UI thread. |
| 311 scoped_ptr<IPC::ChannelProxy> daemon_channel_; | 316 scoped_ptr<IPC::ChannelProxy> daemon_channel_; |
| 312 | 317 |
| 313 // XMPP server/remoting bot configuration (initialized from the command line). | 318 // XMPP server/remoting bot configuration (initialized from the command line). |
| 314 XmppSignalStrategy::XmppServerConfig xmpp_server_config_; | 319 XmppSignalStrategy::XmppServerConfig xmpp_server_config_; |
| 315 std::string directory_bot_jid_; | 320 std::string directory_bot_jid_; |
| 316 | 321 |
| 317 // Created on the UI thread but used from the network thread. | 322 // Created on the UI thread but used from the network thread. |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 350 ThirdPartyAuthConfig third_party_auth_config_; | 355 ThirdPartyAuthConfig third_party_auth_config_; |
| 351 bool enable_gnubby_auth_; | 356 bool enable_gnubby_auth_; |
| 352 | 357 |
| 353 // Boolean to change flow, where necessary, if we're | 358 // Boolean to change flow, where necessary, if we're |
| 354 // capturing a window instead of the entire desktop. | 359 // capturing a window instead of the entire desktop. |
| 355 bool enable_window_capture_; | 360 bool enable_window_capture_; |
| 356 | 361 |
| 357 // Used to specify which window to stream, if enabled. | 362 // Used to specify which window to stream, if enabled. |
| 358 webrtc::WindowId window_id_; | 363 webrtc::WindowId window_id_; |
| 359 | 364 |
| 365 scoped_ptr<OAuthTokenGetter> oauth_token_getter_; | |
|
Sergey Ulanov
2015/05/07 21:49:55
Comment that this object must outlive gcd_rest_cli
John Williams
2015/05/20 00:22:44
Done.
| |
| 366 | |
| 367 scoped_ptr<GcdRestClient> gcd_rest_client_; | |
| 368 | |
| 360 // Used to send heartbeats while running, and the reason for going offline | 369 // Used to send heartbeats while running, and the reason for going offline |
| 361 // when shutting down. | 370 // when shutting down. |
| 362 scoped_ptr<HostSignalingManager> host_signaling_manager_; | 371 scoped_ptr<HostSignalingManager> host_signaling_manager_; |
| 363 | 372 |
| 364 scoped_ptr<HostChangeNotificationListener> host_change_notification_listener_; | 373 scoped_ptr<HostChangeNotificationListener> host_change_notification_listener_; |
| 365 scoped_ptr<HostStatusLogger> host_status_logger_; | 374 scoped_ptr<HostStatusLogger> host_status_logger_; |
| 366 scoped_ptr<HostEventLogger> host_event_logger_; | 375 scoped_ptr<HostEventLogger> host_event_logger_; |
| 367 | 376 |
| 368 scoped_ptr<ChromotingHost> host_; | 377 scoped_ptr<ChromotingHost> host_; |
| 369 | 378 |
| (...skipping 924 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1294 } else { | 1303 } else { |
| 1295 HOST_LOG << "Policy disables gnubby auth."; | 1304 HOST_LOG << "Policy disables gnubby auth."; |
| 1296 } | 1305 } |
| 1297 | 1306 |
| 1298 if (desktop_environment_factory_) | 1307 if (desktop_environment_factory_) |
| 1299 desktop_environment_factory_->SetEnableGnubbyAuth(enable_gnubby_auth_); | 1308 desktop_environment_factory_->SetEnableGnubbyAuth(enable_gnubby_auth_); |
| 1300 | 1309 |
| 1301 return true; | 1310 return true; |
| 1302 } | 1311 } |
| 1303 | 1312 |
| 1304 scoped_ptr<HostSignalingManager> HostProcess::CreateHostSignalingManager() { | 1313 scoped_ptr<OAuthTokenGetter> HostProcess::CreateOAuthTokenGetter() { |
| 1305 DCHECK(!host_id_.empty()); // |ApplyConfig| should already have been run. | 1314 DCHECK(context_); |
| 1306 | 1315 |
| 1307 scoped_ptr<OAuthTokenGetter::OAuthCredentials> oauth_credentials( | 1316 scoped_ptr<OAuthTokenGetter::OAuthCredentials> oauth_credentials( |
| 1308 new OAuthTokenGetter::OAuthCredentials(xmpp_server_config_.username, | 1317 new OAuthTokenGetter::OAuthCredentials(xmpp_server_config_.username, |
| 1309 oauth_refresh_token_, | 1318 oauth_refresh_token_, |
| 1310 use_service_account_)); | 1319 use_service_account_)); |
| 1311 | 1320 |
| 1321 return make_scoped_ptr(new OAuthTokenGetter( | |
| 1322 oauth_credentials.Pass(), context_->url_request_context_getter(), false, | |
| 1323 !using_gcd())); | |
| 1324 } | |
| 1325 | |
| 1326 scoped_ptr<GcdRestClient> HostProcess::CreateGcdRestClient() { | |
| 1327 DCHECK(oauth_token_getter_); | |
| 1328 | |
| 1329 if (!using_gcd()) { | |
| 1330 return nullptr; | |
| 1331 } | |
| 1332 | |
| 1333 ServiceUrls* service_urls = ServiceUrls::GetInstance(); | |
| 1334 return make_scoped_ptr(new GcdRestClient( | |
| 1335 service_urls->gcd_base_url(), gcd_device_id_, | |
| 1336 context_->url_request_context_getter(), oauth_token_getter_.get())); | |
| 1337 } | |
| 1338 | |
| 1339 scoped_ptr<HostSignalingManager> HostProcess::CreateHostSignalingManager() { | |
| 1340 DCHECK(!host_id_.empty()); // |ApplyConfig| should already have been run. | |
|
Sergey Ulanov
2015/05/07 21:49:55
s/|ApplyConfig|/ApplyConfig()/
FunctionName() vs
John Williams
2015/05/20 00:22:44
Done.
| |
| 1341 DCHECK(context_); | |
| 1342 DCHECK(oauth_token_getter_); | |
| 1343 | |
| 1312 return HostSignalingManager::Create( | 1344 return HostSignalingManager::Create( |
| 1313 this, context_->url_request_context_getter(), xmpp_server_config_, | 1345 this, context_->url_request_context_getter(), xmpp_server_config_, |
| 1314 talkgadget_prefix_, host_id_, key_pair_, directory_bot_jid_, | 1346 talkgadget_prefix_, host_id_, key_pair_, directory_bot_jid_, |
| 1315 oauth_credentials.Pass(), gcd_device_id_.empty()); | 1347 oauth_token_getter_.get(), gcd_rest_client_.get()); |
| 1316 } | 1348 } |
| 1317 | 1349 |
| 1318 void HostProcess::StartHostIfReady() { | 1350 void HostProcess::StartHostIfReady() { |
| 1319 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | 1351 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
| 1320 DCHECK_EQ(state_, HOST_STARTING); | 1352 DCHECK_EQ(state_, HOST_STARTING); |
| 1321 | 1353 |
| 1322 // Start the host if both the config and the policies are loaded. | 1354 // Start the host if both the config and the policies are loaded. |
| 1323 if (!serialized_config_.empty()) { | 1355 if (!serialized_config_.empty()) { |
| 1324 if (policy_state_ == POLICY_LOADED) { | 1356 if (policy_state_ == POLICY_LOADED) { |
| 1325 StartHost(); | 1357 StartHost(); |
| 1326 } else if (policy_state_ == POLICY_ERROR_REPORT_PENDING) { | 1358 } else if (policy_state_ == POLICY_ERROR_REPORT_PENDING) { |
| 1327 ReportPolicyErrorAndRestartHost(); | 1359 ReportPolicyErrorAndRestartHost(); |
| 1328 } | 1360 } |
| 1329 } | 1361 } |
| 1330 } | 1362 } |
| 1331 | 1363 |
| 1332 void HostProcess::StartHost() { | 1364 void HostProcess::StartHost() { |
| 1333 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | 1365 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
| 1334 DCHECK(!host_); | 1366 DCHECK(!host_); |
| 1335 DCHECK(!host_signaling_manager_); | 1367 DCHECK(!host_signaling_manager_); |
| 1368 DCHECK(!gcd_rest_client_); | |
| 1336 | 1369 |
| 1337 SetState(HOST_STARTED); | 1370 SetState(HOST_STARTED); |
| 1338 | 1371 |
| 1372 oauth_token_getter_ = CreateOAuthTokenGetter(); | |
| 1373 gcd_rest_client_ = CreateGcdRestClient(); | |
| 1339 host_signaling_manager_ = CreateHostSignalingManager(); | 1374 host_signaling_manager_ = CreateHostSignalingManager(); |
| 1340 | 1375 |
| 1341 uint32 network_flags = 0; | 1376 uint32 network_flags = 0; |
| 1342 if (allow_nat_traversal_) { | 1377 if (allow_nat_traversal_) { |
| 1343 network_flags = NetworkSettings::NAT_TRAVERSAL_STUN | | 1378 network_flags = NetworkSettings::NAT_TRAVERSAL_STUN | |
| 1344 NetworkSettings::NAT_TRAVERSAL_OUTGOING; | 1379 NetworkSettings::NAT_TRAVERSAL_OUTGOING; |
| 1345 if (allow_relay_) | 1380 if (allow_relay_) |
| 1346 network_flags |= NetworkSettings::NAT_TRAVERSAL_RELAY; | 1381 network_flags |= NetworkSettings::NAT_TRAVERSAL_RELAY; |
| 1347 } | 1382 } |
| 1348 | 1383 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1385 | 1420 |
| 1386 // TODO(simonmorris): Get the maximum session duration from a policy. | 1421 // TODO(simonmorris): Get the maximum session duration from a policy. |
| 1387 #if defined(OS_LINUX) | 1422 #if defined(OS_LINUX) |
| 1388 host_->SetMaximumSessionDuration(base::TimeDelta::FromHours(20)); | 1423 host_->SetMaximumSessionDuration(base::TimeDelta::FromHours(20)); |
| 1389 #endif | 1424 #endif |
| 1390 | 1425 |
| 1391 host_change_notification_listener_.reset(new HostChangeNotificationListener( | 1426 host_change_notification_listener_.reset(new HostChangeNotificationListener( |
| 1392 this, host_id_, host_signaling_manager_->signal_strategy(), | 1427 this, host_id_, host_signaling_manager_->signal_strategy(), |
| 1393 directory_bot_jid_)); | 1428 directory_bot_jid_)); |
| 1394 | 1429 |
| 1395 host_status_logger_.reset(new HostStatusLogger( | 1430 if (using_gcd()) { |
| 1396 host_->AsWeakPtr(), ServerLogEntry::ME2ME, | 1431 // TODO(jrw): Implement logging for GCD hosts. |
| 1397 host_signaling_manager_->signal_strategy(), directory_bot_jid_)); | 1432 HOST_LOG << "Logging not implemented for GCD hosts."; |
| 1433 } else { | |
| 1434 host_status_logger_.reset(new HostStatusLogger( | |
| 1435 host_->AsWeakPtr(), ServerLogEntry::ME2ME, | |
| 1436 host_signaling_manager_->signal_strategy(), directory_bot_jid_)); | |
| 1437 } | |
| 1398 | 1438 |
| 1399 // Set up reporting the host status notifications. | 1439 // Set up reporting the host status notifications. |
| 1400 #if defined(REMOTING_MULTI_PROCESS) | 1440 #if defined(REMOTING_MULTI_PROCESS) |
| 1401 host_event_logger_.reset( | 1441 host_event_logger_.reset( |
| 1402 new IpcHostEventLogger(host_->AsWeakPtr(), daemon_channel_.get())); | 1442 new IpcHostEventLogger(host_->AsWeakPtr(), daemon_channel_.get())); |
| 1403 #else // !defined(REMOTING_MULTI_PROCESS) | 1443 #else // !defined(REMOTING_MULTI_PROCESS) |
| 1404 host_event_logger_ = | 1444 host_event_logger_ = |
| 1405 HostEventLogger::Create(host_->AsWeakPtr(), kApplicationName); | 1445 HostEventLogger::Create(host_->AsWeakPtr(), kApplicationName); |
| 1406 #endif // !defined(REMOTING_MULTI_PROCESS) | 1446 #endif // !defined(REMOTING_MULTI_PROCESS) |
| 1407 | 1447 |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1458 // Shut down everything except the HostSignalingManager. | 1498 // Shut down everything except the HostSignalingManager. |
| 1459 host_.reset(); | 1499 host_.reset(); |
| 1460 host_event_logger_.reset(); | 1500 host_event_logger_.reset(); |
| 1461 host_status_logger_.reset(); | 1501 host_status_logger_.reset(); |
| 1462 host_change_notification_listener_.reset(); | 1502 host_change_notification_listener_.reset(); |
| 1463 | 1503 |
| 1464 // Before shutting down HostSignalingManager, send the |host_offline_reason| | 1504 // Before shutting down HostSignalingManager, send the |host_offline_reason| |
| 1465 // if possible (i.e. if we have the config). | 1505 // if possible (i.e. if we have the config). |
| 1466 if (!serialized_config_.empty()) { | 1506 if (!serialized_config_.empty()) { |
| 1467 if (!host_signaling_manager_) { | 1507 if (!host_signaling_manager_) { |
| 1468 host_signaling_manager_ = CreateHostSignalingManager(); | 1508 host_signaling_manager_ = CreateHostSignalingManager(); |
|
Sergey Ulanov
2015/05/07 21:49:55
Do you need to call CreateOAuthTokenGetter() here?
John Williams
2015/05/20 00:22:45
Done.
| |
| 1469 } | 1509 } |
| 1470 | 1510 |
| 1471 host_signaling_manager_->SendHostOfflineReason( | 1511 host_signaling_manager_->SendHostOfflineReason( |
| 1472 host_offline_reason, | 1512 host_offline_reason, |
| 1473 base::TimeDelta::FromSeconds(kHostOfflineReasonTimeoutSeconds), | 1513 base::TimeDelta::FromSeconds(kHostOfflineReasonTimeoutSeconds), |
| 1474 base::Bind(&HostProcess::OnHostOfflineReasonAck, this)); | 1514 base::Bind(&HostProcess::OnHostOfflineReasonAck, this)); |
| 1475 return; // Shutdown will resume after OnHostOfflineReasonAck. | 1515 return; // Shutdown will resume after OnHostOfflineReasonAck. |
| 1476 } | 1516 } |
| 1477 | 1517 |
| 1478 // Continue the shutdown without sending the host offline reason. | 1518 // Continue the shutdown without sending the host offline reason. |
| 1479 HOST_LOG << "Can't send offline reason (" << host_offline_reason << ") " | 1519 HOST_LOG << "Can't send offline reason (" << host_offline_reason << ") " |
| 1480 << "without a valid host config."; | 1520 << "without a valid host config."; |
| 1481 OnHostOfflineReasonAck(false); | 1521 OnHostOfflineReasonAck(false); |
| 1482 } | 1522 } |
| 1483 | 1523 |
| 1484 void HostProcess::OnHostOfflineReasonAck(bool success) { | 1524 void HostProcess::OnHostOfflineReasonAck(bool success) { |
| 1485 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | 1525 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
| 1486 DCHECK(!host_); // Assert that the host is really offline at this point. | 1526 DCHECK(!host_); // Assert that the host is really offline at this point. |
| 1487 | 1527 |
| 1488 HOST_LOG << "SendHostOfflineReason " << (success ? "succeeded." : "failed."); | 1528 HOST_LOG << "SendHostOfflineReason " << (success ? "succeeded." : "failed."); |
| 1489 host_signaling_manager_.reset(); | 1529 host_signaling_manager_.reset(); |
| 1530 gcd_rest_client_.reset(); | |
| 1531 oauth_token_getter_.reset(); | |
| 1490 | 1532 |
| 1491 if (state_ == HOST_GOING_OFFLINE_TO_RESTART) { | 1533 if (state_ == HOST_GOING_OFFLINE_TO_RESTART) { |
| 1492 SetState(HOST_STARTING); | 1534 SetState(HOST_STARTING); |
| 1493 StartHostIfReady(); | 1535 StartHostIfReady(); |
| 1494 } else if (state_ == HOST_GOING_OFFLINE_TO_STOP) { | 1536 } else if (state_ == HOST_GOING_OFFLINE_TO_STOP) { |
| 1495 SetState(HOST_STOPPED); | 1537 SetState(HOST_STOPPED); |
| 1496 | 1538 |
| 1497 shutdown_watchdog_->SetExitCode(*exit_code_out_); | 1539 shutdown_watchdog_->SetExitCode(*exit_code_out_); |
| 1498 shutdown_watchdog_->Arm(); | 1540 shutdown_watchdog_->Arm(); |
| 1499 | 1541 |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1558 base::TimeDelta::FromSeconds(kShutdownTimeoutSeconds)); | 1600 base::TimeDelta::FromSeconds(kShutdownTimeoutSeconds)); |
| 1559 new HostProcess(context.Pass(), &exit_code, &shutdown_watchdog); | 1601 new HostProcess(context.Pass(), &exit_code, &shutdown_watchdog); |
| 1560 | 1602 |
| 1561 // 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. |
| 1562 message_loop.Run(); | 1604 message_loop.Run(); |
| 1563 | 1605 |
| 1564 return exit_code; | 1606 return exit_code; |
| 1565 } | 1607 } |
| 1566 | 1608 |
| 1567 } // namespace remoting | 1609 } // namespace remoting |
| OLD | NEW |