| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 "chrome/browser/chromeos/arc/arc_session_manager.h" | 5 #include "chrome/browser/chromeos/arc/arc_session_manager.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "ash/common/shelf/shelf_delegate.h" | 9 #include "ash/common/shelf/shelf_delegate.h" |
| 10 #include "ash/common/wm_shell.h" | 10 #include "ash/common/wm_shell.h" |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 59 // testing. | 59 // testing. |
| 60 bool g_enable_check_android_management_for_testing = false; | 60 bool g_enable_check_android_management_for_testing = false; |
| 61 | 61 |
| 62 // Maximum amount of time we'll wait for ARC to finish booting up. Once this | 62 // Maximum amount of time we'll wait for ARC to finish booting up. Once this |
| 63 // timeout expires, keep ARC running in case the user wants to file feedback, | 63 // timeout expires, keep ARC running in case the user wants to file feedback, |
| 64 // but present the UI to try again. | 64 // but present the UI to try again. |
| 65 constexpr base::TimeDelta kArcSignInTimeout = base::TimeDelta::FromMinutes(5); | 65 constexpr base::TimeDelta kArcSignInTimeout = base::TimeDelta::FromMinutes(5); |
| 66 | 66 |
| 67 } // namespace | 67 } // namespace |
| 68 | 68 |
| 69 // This class is used to track statuses on OptIn flow. It is created in case ARC |
| 70 // is activated, and it needs to OptIn. Once started OptInFlowResult::STARTED is |
| 71 // recorded via UMA. If it finishes successfully OptInFlowResult::SUCCEEDED is |
| 72 // recorded. Optional OptInFlowResult::SUCCEEDED_AFTER_RETRY is recorded in this |
| 73 // case if an error occurred during OptIn flow, and user pressed Retry. In case |
| 74 // the user cancels OptIn flow before it was completed then |
| 75 // OptInFlowResult::CANCELED is recorded and if an error occurred optional |
| 76 // OptInFlowResult::CANCELED_AFTER_ERROR. If a shutdown happens during the OptIn |
| 77 // nothing is recorded, except initial OptInFlowResult::STARTED. |
| 78 // OptInFlowResult::STARTED = OptInFlowResult::SUCCEEDED + |
| 79 // OptInFlowResult::CANCELED + cases happened during the shutdown. |
| 80 class ArcSessionManager::ScopedOptInFlowTracker { |
| 81 public: |
| 82 ScopedOptInFlowTracker() { |
| 83 UpdateOptInFlowResultUMA(OptInFlowResult::STARTED); |
| 84 } |
| 85 |
| 86 ~ScopedOptInFlowTracker() { |
| 87 if (shutdown_) |
| 88 return; |
| 89 |
| 90 UpdateOptInFlowResultUMA(success_ ? OptInFlowResult::SUCCEEDED |
| 91 : OptInFlowResult::CANCELED); |
| 92 if (error_) { |
| 93 UpdateOptInFlowResultUMA(success_ |
| 94 ? OptInFlowResult::SUCCEEDED_AFTER_RETRY |
| 95 : OptInFlowResult::CANCELED_AFTER_ERROR); |
| 96 } |
| 97 } |
| 98 |
| 99 // Tracks error occurred during the OptIn flow. |
| 100 void TrackError() { |
| 101 DCHECK(!success_ && !shutdown_); |
| 102 error_ = true; |
| 103 } |
| 104 |
| 105 // Tracks that OptIn finished successfully. |
| 106 void TrackSuccess() { |
| 107 DCHECK(!success_ && !shutdown_); |
| 108 success_ = true; |
| 109 } |
| 110 |
| 111 // Tracks that OptIn was not completed before shutdown. |
| 112 void TrackShutdown() { |
| 113 DCHECK(!success_ && !shutdown_); |
| 114 shutdown_ = true; |
| 115 } |
| 116 |
| 117 private: |
| 118 bool error_ = false; |
| 119 bool success_ = false; |
| 120 bool shutdown_ = false; |
| 121 |
| 122 DISALLOW_COPY_AND_ASSIGN(ScopedOptInFlowTracker); |
| 123 }; |
| 124 |
| 69 ArcSessionManager::ArcSessionManager( | 125 ArcSessionManager::ArcSessionManager( |
| 70 std::unique_ptr<ArcSessionRunner> arc_session_runner) | 126 std::unique_ptr<ArcSessionRunner> arc_session_runner) |
| 71 : arc_session_runner_(std::move(arc_session_runner)), | 127 : arc_session_runner_(std::move(arc_session_runner)), |
| 72 attempt_user_exit_callback_(base::Bind(chrome::AttemptUserExit)), | 128 attempt_user_exit_callback_(base::Bind(chrome::AttemptUserExit)), |
| 73 weak_ptr_factory_(this) { | 129 weak_ptr_factory_(this) { |
| 74 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 130 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 75 DCHECK(!g_arc_session_manager); | 131 DCHECK(!g_arc_session_manager); |
| 76 g_arc_session_manager = this; | 132 g_arc_session_manager = this; |
| 77 arc_session_runner_->AddObserver(this); | 133 arc_session_runner_->AddObserver(this); |
| 78 } | 134 } |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 250 // We don't expect ProvisioningResult::SUCCESS is reported twice or reported | 306 // We don't expect ProvisioningResult::SUCCESS is reported twice or reported |
| 251 // after an error. | 307 // after an error. |
| 252 DCHECK_NE(result, ProvisioningResult::SUCCESS); | 308 DCHECK_NE(result, ProvisioningResult::SUCCESS); |
| 253 // TODO(khmel): Consider changing LOG to NOTREACHED once we guaranty that | 309 // TODO(khmel): Consider changing LOG to NOTREACHED once we guaranty that |
| 254 // no double message can happen in production. | 310 // no double message can happen in production. |
| 255 LOG(WARNING) << "Provisioning result was already reported. Ignoring " | 311 LOG(WARNING) << "Provisioning result was already reported. Ignoring " |
| 256 << "additional result " << static_cast<int>(result) << "."; | 312 << "additional result " << static_cast<int>(result) << "."; |
| 257 return; | 313 return; |
| 258 } | 314 } |
| 259 provisioning_reported_ = true; | 315 provisioning_reported_ = true; |
| 316 if (scoped_opt_in_tracker_ && result != ProvisioningResult::SUCCESS) |
| 317 scoped_opt_in_tracker_->TrackError(); |
| 260 | 318 |
| 261 if (result == ProvisioningResult::CHROME_SERVER_COMMUNICATION_ERROR) { | 319 if (result == ProvisioningResult::CHROME_SERVER_COMMUNICATION_ERROR) { |
| 262 if (IsArcKioskMode()) { | 320 if (IsArcKioskMode()) { |
| 263 VLOG(1) << "Robot account auth code fetching error"; | 321 VLOG(1) << "Robot account auth code fetching error"; |
| 264 // Log out the user. All the cleanup will be done in Shutdown() method. | 322 // Log out the user. All the cleanup will be done in Shutdown() method. |
| 265 // The callback is not called because auth code is empty. | 323 // The callback is not called because auth code is empty. |
| 266 attempt_user_exit_callback_.Run(); | 324 attempt_user_exit_callback_.Run(); |
| 267 return; | 325 return; |
| 268 } | 326 } |
| 269 | 327 |
| 270 // For backwards compatibility, use NETWORK_ERROR for | 328 // For backwards compatibility, use NETWORK_ERROR for |
| 271 // CHROME_SERVER_COMMUNICATION_ERROR case. | 329 // CHROME_SERVER_COMMUNICATION_ERROR case. |
| 272 UpdateOptInCancelUMA(OptInCancelReason::NETWORK_ERROR); | 330 UpdateOptInCancelUMA(OptInCancelReason::NETWORK_ERROR); |
| 273 } else if (!sign_in_start_time_.is_null()) { | 331 } else if (!sign_in_start_time_.is_null()) { |
| 274 arc_sign_in_timer_.Stop(); | 332 arc_sign_in_timer_.Stop(); |
| 275 | 333 |
| 276 UpdateProvisioningTiming(base::Time::Now() - sign_in_start_time_, | 334 UpdateProvisioningTiming(base::Time::Now() - sign_in_start_time_, |
| 277 result == ProvisioningResult::SUCCESS, | 335 result == ProvisioningResult::SUCCESS, |
| 278 policy_util::IsAccountManaged(profile_)); | 336 policy_util::IsAccountManaged(profile_)); |
| 279 UpdateProvisioningResultUMA(result, | 337 UpdateProvisioningResultUMA(result, |
| 280 policy_util::IsAccountManaged(profile_)); | 338 policy_util::IsAccountManaged(profile_)); |
| 281 if (result != ProvisioningResult::SUCCESS) | 339 if (result != ProvisioningResult::SUCCESS) |
| 282 UpdateOptInCancelUMA(OptInCancelReason::CLOUD_PROVISION_FLOW_FAIL); | 340 UpdateOptInCancelUMA(OptInCancelReason::CLOUD_PROVISION_FLOW_FAIL); |
| 283 } | 341 } |
| 284 | 342 |
| 285 if (result == ProvisioningResult::SUCCESS) { | 343 if (result == ProvisioningResult::SUCCESS) { |
| 286 if (support_host_) | 344 if (support_host_) |
| 287 support_host_->Close(); | 345 support_host_->Close(); |
| 288 | 346 |
| 347 if (scoped_opt_in_tracker_) { |
| 348 scoped_opt_in_tracker_->TrackSuccess(); |
| 349 scoped_opt_in_tracker_.reset(); |
| 350 } |
| 351 |
| 289 if (profile_->GetPrefs()->GetBoolean(prefs::kArcSignedIn)) | 352 if (profile_->GetPrefs()->GetBoolean(prefs::kArcSignedIn)) |
| 290 return; | 353 return; |
| 291 | 354 |
| 292 profile_->GetPrefs()->SetBoolean(prefs::kArcSignedIn, true); | 355 profile_->GetPrefs()->SetBoolean(prefs::kArcSignedIn, true); |
| 293 | 356 |
| 294 // Launch Play Store app, except for the following cases: | 357 // Launch Play Store app, except for the following cases: |
| 295 // * When Opt-in verification is disabled (for tests); | 358 // * When Opt-in verification is disabled (for tests); |
| 296 // * In ARC Kiosk mode, because the only one UI in kiosk mode must be the | 359 // * In ARC Kiosk mode, because the only one UI in kiosk mode must be the |
| 297 // kiosk app and device is not needed for opt-in; | 360 // kiosk app and device is not needed for opt-in; |
| 298 // * When ARC is managed and all OptIn preferences are managed too, because | 361 // * When ARC is managed and all OptIn preferences are managed too, because |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 435 enable_requested_ = false; | 498 enable_requested_ = false; |
| 436 ShutdownSession(); | 499 ShutdownSession(); |
| 437 if (support_host_) { | 500 if (support_host_) { |
| 438 support_host_->Close(); | 501 support_host_->Close(); |
| 439 support_host_->RemoveObserver(this); | 502 support_host_->RemoveObserver(this); |
| 440 support_host_.reset(); | 503 support_host_.reset(); |
| 441 } | 504 } |
| 442 context_.reset(); | 505 context_.reset(); |
| 443 profile_ = nullptr; | 506 profile_ = nullptr; |
| 444 SetState(State::NOT_INITIALIZED); | 507 SetState(State::NOT_INITIALIZED); |
| 508 if (scoped_opt_in_tracker_) { |
| 509 scoped_opt_in_tracker_->TrackShutdown(); |
| 510 scoped_opt_in_tracker_.reset(); |
| 511 } |
| 445 } | 512 } |
| 446 | 513 |
| 447 | 514 |
| 448 void ArcSessionManager::ShutdownSession() { | 515 void ArcSessionManager::ShutdownSession() { |
| 449 arc_sign_in_timer_.Stop(); | 516 arc_sign_in_timer_.Stop(); |
| 450 playstore_launcher_.reset(); | 517 playstore_launcher_.reset(); |
| 451 terms_of_service_negotiator_.reset(); | 518 terms_of_service_negotiator_.reset(); |
| 452 android_management_checker_.reset(); | 519 android_management_checker_.reset(); |
| 453 arc_session_runner_->RequestStop(); | 520 arc_session_runner_->RequestStop(); |
| 454 // TODO(hidehiko): The ARC instance's stopping is asynchronous, so it might | 521 // TODO(hidehiko): The ARC instance's stopping is asynchronous, so it might |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 613 } | 680 } |
| 614 | 681 |
| 615 // If it is marked that the Terms of service is accepted already, | 682 // If it is marked that the Terms of service is accepted already, |
| 616 // just skip the negotiation with user, and start Android management | 683 // just skip the negotiation with user, and start Android management |
| 617 // check directly. | 684 // check directly. |
| 618 // This happens, e.g., when; | 685 // This happens, e.g., when; |
| 619 // 1) User accepted the Terms of service on OOBE flow. | 686 // 1) User accepted the Terms of service on OOBE flow. |
| 620 // 2) User accepted the Terms of service on Opt-in flow, but logged out | 687 // 2) User accepted the Terms of service on Opt-in flow, but logged out |
| 621 // before ARC sign in procedure was done. Then, logs in again. | 688 // before ARC sign in procedure was done. Then, logs in again. |
| 622 if (prefs->GetBoolean(prefs::kArcTermsAccepted)) { | 689 if (prefs->GetBoolean(prefs::kArcTermsAccepted)) { |
| 690 if (!scoped_opt_in_tracker_ && |
| 691 !profile_->GetPrefs()->GetBoolean(prefs::kArcSignedIn)) { |
| 692 scoped_opt_in_tracker_ = base::MakeUnique<ScopedOptInFlowTracker>(); |
| 693 } |
| 694 |
| 623 // Don't show UI for this progress if it was not shown. | 695 // Don't show UI for this progress if it was not shown. |
| 624 if (support_host_ && | 696 if (support_host_ && |
| 625 support_host_->ui_page() != ArcSupportHost::UIPage::NO_PAGE) { | 697 support_host_->ui_page() != ArcSupportHost::UIPage::NO_PAGE) { |
| 626 support_host_->ShowArcLoading(); | 698 support_host_->ShowArcLoading(); |
| 627 } | 699 } |
| 628 StartArcAndroidManagementCheck(); | 700 StartArcAndroidManagementCheck(); |
| 629 return; | 701 return; |
| 630 } | 702 } |
| 631 | 703 |
| 632 StartTermsOfServiceNegotiation(); | 704 StartTermsOfServiceNegotiation(); |
| 633 } | 705 } |
| 634 | 706 |
| 635 void ArcSessionManager::RequestDisable() { | 707 void ArcSessionManager::RequestDisable() { |
| 636 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 708 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 637 DCHECK(profile_); | 709 DCHECK(profile_); |
| 638 | 710 |
| 639 if (!enable_requested_) { | 711 if (!enable_requested_) { |
| 640 VLOG(1) << "ARC is already disabled. Do nothing."; | 712 VLOG(1) << "ARC is already disabled. Do nothing."; |
| 641 return; | 713 return; |
| 642 } | 714 } |
| 643 enable_requested_ = false; | 715 enable_requested_ = false; |
| 716 scoped_opt_in_tracker_.reset(); |
| 644 | 717 |
| 645 // Reset any pending request to re-enable ARC. | 718 // Reset any pending request to re-enable ARC. |
| 646 VLOG(1) << "ARC opt-out. Removing user data."; | 719 VLOG(1) << "ARC opt-out. Removing user data."; |
| 647 reenable_arc_ = false; | 720 reenable_arc_ = false; |
| 648 StopArc(); | 721 StopArc(); |
| 649 RemoveArcData(); | 722 RemoveArcData(); |
| 650 } | 723 } |
| 651 | 724 |
| 652 void ArcSessionManager::StartTermsOfServiceNegotiation() { | 725 void ArcSessionManager::StartTermsOfServiceNegotiation() { |
| 653 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 726 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 654 DCHECK(!terms_of_service_negotiator_); | 727 DCHECK(!terms_of_service_negotiator_); |
| 655 | 728 |
| 656 if (!arc_session_runner_->IsStopped()) { | 729 if (!arc_session_runner_->IsStopped()) { |
| 657 // If the user attempts to re-enable ARC while the ARC instance is still | 730 // If the user attempts to re-enable ARC while the ARC instance is still |
| 658 // running the user should not be able to continue until the ARC instance | 731 // running the user should not be able to continue until the ARC instance |
| 659 // has stopped. | 732 // has stopped. |
| 660 if (support_host_) { | 733 if (support_host_) { |
| 661 support_host_->ShowError( | 734 support_host_->ShowError( |
| 662 ArcSupportHost::Error::SIGN_IN_SERVICE_UNAVAILABLE_ERROR, false); | 735 ArcSupportHost::Error::SIGN_IN_SERVICE_UNAVAILABLE_ERROR, false); |
| 663 } | 736 } |
| 737 UpdateOptInCancelUMA(OptInCancelReason::SESSION_BUSY); |
| 664 return; | 738 return; |
| 665 } | 739 } |
| 666 | 740 |
| 667 SetState(State::SHOWING_TERMS_OF_SERVICE); | 741 SetState(State::SHOWING_TERMS_OF_SERVICE); |
| 742 |
| 743 if (!scoped_opt_in_tracker_ && |
| 744 !profile_->GetPrefs()->GetBoolean(prefs::kArcSignedIn)) { |
| 745 scoped_opt_in_tracker_ = base::MakeUnique<ScopedOptInFlowTracker>(); |
| 746 } |
| 747 |
| 668 if (IsOobeOptInActive()) { | 748 if (IsOobeOptInActive()) { |
| 669 VLOG(1) << "Use OOBE negotiator."; | 749 VLOG(1) << "Use OOBE negotiator."; |
| 670 terms_of_service_negotiator_ = | 750 terms_of_service_negotiator_ = |
| 671 base::MakeUnique<ArcTermsOfServiceOobeNegotiator>(); | 751 base::MakeUnique<ArcTermsOfServiceOobeNegotiator>(); |
| 672 } else if (support_host_) { | 752 } else if (support_host_) { |
| 673 VLOG(1) << "Use default negotiator."; | 753 VLOG(1) << "Use default negotiator."; |
| 674 terms_of_service_negotiator_ = | 754 terms_of_service_negotiator_ = |
| 675 base::MakeUnique<ArcTermsOfServiceDefaultNegotiator>( | 755 base::MakeUnique<ArcTermsOfServiceDefaultNegotiator>( |
| 676 profile_->GetPrefs(), support_host_.get()); | 756 profile_->GetPrefs(), support_host_.get()); |
| 677 } | 757 } |
| (...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 892 | 972 |
| 893 #undef MAP_STATE | 973 #undef MAP_STATE |
| 894 | 974 |
| 895 // Some compilers report an error even if all values of an enum-class are | 975 // Some compilers report an error even if all values of an enum-class are |
| 896 // covered exhaustively in a switch statement. | 976 // covered exhaustively in a switch statement. |
| 897 NOTREACHED() << "Invalid value " << static_cast<int>(state); | 977 NOTREACHED() << "Invalid value " << static_cast<int>(state); |
| 898 return os; | 978 return os; |
| 899 } | 979 } |
| 900 | 980 |
| 901 } // namespace arc | 981 } // namespace arc |
| OLD | NEW |