Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1470)

Side by Side Diff: chrome/browser/chromeos/arc/arc_session_manager.cc

Issue 2534883002: Extract ArcTermsOfServiceNegotiator implementation. (Closed)
Patch Set: Address comments Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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"
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/callback_helpers.h" 12 #include "base/callback_helpers.h"
13 #include "base/command_line.h" 13 #include "base/command_line.h"
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "base/strings/string16.h" 15 #include "base/strings/string16.h"
16 #include "base/time/time.h" 16 #include "base/time/time.h"
17 #include "chrome/browser/chromeos/arc/arc_auth_code_fetcher.h" 17 #include "chrome/browser/chromeos/arc/arc_auth_code_fetcher.h"
18 #include "chrome/browser/chromeos/arc/arc_auth_context.h" 18 #include "chrome/browser/chromeos/arc/arc_auth_context.h"
19 #include "chrome/browser/chromeos/arc/arc_optin_uma.h" 19 #include "chrome/browser/chromeos/arc/arc_optin_uma.h"
20 #include "chrome/browser/chromeos/arc/arc_support_host.h" 20 #include "chrome/browser/chromeos/arc/arc_support_host.h"
21 #include "chrome/browser/chromeos/arc/auth/arc_robot_auth.h" 21 #include "chrome/browser/chromeos/arc/auth/arc_robot_auth.h"
22 #include "chrome/browser/chromeos/arc/optin/arc_optin_preference_handler.h" 22 #include "chrome/browser/chromeos/arc/optin/arc_terms_of_service_negotiator.h"
23 #include "chrome/browser/chromeos/arc/policy/arc_android_management_checker.h" 23 #include "chrome/browser/chromeos/arc/policy/arc_android_management_checker.h"
24 #include "chrome/browser/chromeos/arc/policy/arc_policy_util.h" 24 #include "chrome/browser/chromeos/arc/policy/arc_policy_util.h"
25 #include "chrome/browser/chromeos/profiles/profile_helper.h" 25 #include "chrome/browser/chromeos/profiles/profile_helper.h"
26 #include "chrome/browser/lifetime/application_lifetime.h" 26 #include "chrome/browser/lifetime/application_lifetime.h"
27 #include "chrome/browser/policy/profile_policy_connector.h" 27 #include "chrome/browser/policy/profile_policy_connector.h"
28 #include "chrome/browser/policy/profile_policy_connector_factory.h" 28 #include "chrome/browser/policy/profile_policy_connector_factory.h"
29 #include "chrome/browser/prefs/pref_service_syncable_util.h" 29 #include "chrome/browser/prefs/pref_service_syncable_util.h"
30 #include "chrome/browser/profiles/profile.h" 30 #include "chrome/browser/profiles/profile.h"
31 #include "chrome/browser/ui/app_list/arc/arc_app_launcher.h" 31 #include "chrome/browser/ui/app_list/arc/arc_app_launcher.h"
32 #include "chrome/browser/ui/app_list/arc/arc_app_utils.h" 32 #include "chrome/browser/ui/app_list/arc/arc_app_utils.h"
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after
370 // 370 //
371 // Don't show UI for ARC Kiosk because the only one UI in kiosk mode must 371 // Don't show UI for ARC Kiosk because the only one UI in kiosk mode must
372 // be the kiosk app. In case of error the UI will be useless as well, because 372 // be the kiosk app. In case of error the UI will be useless as well, because
373 // in typical use case there will be no one nearby the kiosk device, who can 373 // in typical use case there will be no one nearby the kiosk device, who can
374 // do some action to solve the problem be means of UI. 374 // do some action to solve the problem be means of UI.
375 if (!g_disable_ui_for_testing && !IsOptInVerificationDisabled() && 375 if (!g_disable_ui_for_testing && !IsOptInVerificationDisabled() &&
376 !IsArcKioskMode()) { 376 !IsArcKioskMode()) {
377 DCHECK(!support_host_); 377 DCHECK(!support_host_);
378 support_host_ = base::MakeUnique<ArcSupportHost>(profile_); 378 support_host_ = base::MakeUnique<ArcSupportHost>(profile_);
379 support_host_->AddObserver(this); 379 support_host_->AddObserver(this);
380
381 preference_handler_ = base::MakeUnique<arc::ArcOptInPreferenceHandler>(
382 this, profile_->GetPrefs());
383 // This automatically updates all preferences.
384 preference_handler_->Start();
385 } 380 }
386 381
387 DCHECK_EQ(State::NOT_INITIALIZED, state_); 382 DCHECK_EQ(State::NOT_INITIALIZED, state_);
388 SetState(State::STOPPED); 383 SetState(State::STOPPED);
389 384
390 PrefServiceSyncableFromProfile(profile_)->AddSyncedPrefObserver( 385 PrefServiceSyncableFromProfile(profile_)->AddSyncedPrefObserver(
391 prefs::kArcEnabled, this); 386 prefs::kArcEnabled, this);
392 387
393 context_.reset(new ArcAuthContext(profile_)); 388 context_.reset(new ArcAuthContext(profile_));
394 389
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
486 RemoveArcData(); 481 RemoveArcData();
487 return; 482 return;
488 } 483 }
489 484
490 if (state_ == State::ACTIVE) 485 if (state_ == State::ACTIVE)
491 return; 486 return;
492 487
493 if (support_host_) 488 if (support_host_)
494 support_host_->SetArcManaged(IsArcManaged()); 489 support_host_->SetArcManaged(IsArcManaged());
495 490
496 // In case UI is disabled we assume that ARC is opted-in. For ARC Kiosk we 491 // For ARC Kiosk we skip ToS because it is very likely that near the device
497 // skip ToS because it is very likely that near the device there will be 492 // there will be no one who is eligible to accept them.
498 // no one who is eligible to accept them. We skip if Android management check 493 // TODO(poromov): Move to more Kiosk dedicated set-up phase.
499 // because there are no managed human users for Kiosk exist. 494 if (IsArcKioskMode())
500 if (IsOptInVerificationDisabled() || IsArcKioskMode()) { 495 profile_->GetPrefs()->SetBoolean(prefs::kArcTermsAccepted, true);
501 // Automatically accept terms in kiosk mode. This is not required for 496
502 // IsOptInVerificationDisabled mode because in last case it may cause 497 // If it is marked that sign in has been successfully done, then directly
503 // a privacy issue on next run without this flag set. 498 // start ARC.
504 if (IsArcKioskMode()) 499 // For testing, and for Kisok mode, we also skip ToS negotiation procedure.
505 profile_->GetPrefs()->SetBoolean(prefs::kArcTermsAccepted, true); 500 // For backward compatibility, this check needs to be prior to the
501 // kArcTermsAccepted check below.
502 if (profile_->GetPrefs()->GetBoolean(prefs::kArcSignedIn) ||
503 IsOptInVerificationDisabled() || IsArcKioskMode()) {
506 StartArc(); 504 StartArc();
507 return;
508 }
509 505
510 if (!profile_->GetPrefs()->GetBoolean(prefs::kArcSignedIn)) { 506 // Skip Android management check for testing.
511 if (profile_->GetPrefs()->GetBoolean(prefs::kArcTermsAccepted)) { 507 // We also skip if Android management check for Kiosk mode,
512 StartArc(); 508 // because there are no managed human users for Kiosk exist.
513 } else { 509 if (IsOptInVerificationDisabled() || IsArcKioskMode() ||
514 // Need pre-fetch auth code and show OptIn UI if needed. 510 (g_disable_ui_for_testing &&
515 StartUI(); 511 !g_enable_check_android_management_for_testing)) {
512 return;
516 } 513 }
517 } else { 514
518 // Ready to start Arc, but check Android management in parallel. 515 // Check Android management in parallel.
519 StartArc();
520 // Note: Because the callback may be called in synchronous way (i.e. called 516 // Note: Because the callback may be called in synchronous way (i.e. called
521 // on the same stack), StartCheck() needs to be called *after* StartArc(). 517 // on the same stack), StartCheck() needs to be called *after* StartArc().
522 // Otherwise, DisableArc() which may be called in 518 // Otherwise, DisableArc() which may be called in
523 // OnBackgroundAndroidManagementChecked() could be ignored. 519 // OnBackgroundAndroidManagementChecked() could be ignored.
524 if (!g_disable_ui_for_testing || 520 android_management_checker_ = base::MakeUnique<ArcAndroidManagementChecker>(
525 g_enable_check_android_management_for_testing) { 521 profile_, context_->token_service(), context_->account_id(),
526 android_management_checker_.reset(new ArcAndroidManagementChecker( 522 true /* retry_on_error */);
527 profile_, context_->token_service(), context_->account_id(), 523 android_management_checker_->StartCheck(
528 true /* retry_on_error */)); 524 base::Bind(&ArcSessionManager::OnBackgroundAndroidManagementChecked,
529 android_management_checker_->StartCheck( 525 weak_ptr_factory_.GetWeakPtr()));
530 base::Bind(&ArcSessionManager::OnBackgroundAndroidManagementChecked, 526 return;
531 weak_ptr_factory_.GetWeakPtr()));
532 }
533 } 527 }
528
529 // If it is marked that the Terms of service is accepted already,
530 // just skip the negotiation with user, and start Android management
531 // check directly.
532 // This happens, e.g., when;
533 // 1) User accepted the Terms of service on OOBE flow.
534 // 2) User accepted the Terms of service on Opt-in flow, but logged out
535 // before ARC sign in procedure was done. Then, logs in again.
536 if (profile_->GetPrefs()->GetBoolean(prefs::kArcTermsAccepted)) {
537 support_host_->ShowArcLoading();
538 StartArcAndroidManagementCheck();
539 return;
540 }
541
542 // Need user's explicit Terms Of Service agreement.
543 StartTermsOfServiceNegotiation();
534 } 544 }
535 545
536 void ArcSessionManager::ShutdownBridge() { 546 void ArcSessionManager::ShutdownBridge() {
537 arc_sign_in_timer_.Stop(); 547 arc_sign_in_timer_.Stop();
538 playstore_launcher_.reset(); 548 playstore_launcher_.reset();
549 terms_of_service_negotiator_.reset();
539 android_management_checker_.reset(); 550 android_management_checker_.reset();
540 arc_bridge_service()->RequestStop(); 551 arc_bridge_service()->RequestStop();
541 if (state_ != State::NOT_INITIALIZED) 552 if (state_ != State::NOT_INITIALIZED)
542 SetState(State::STOPPED); 553 SetState(State::STOPPED);
543 for (auto& observer : observer_list_) 554 for (auto& observer : observer_list_)
544 observer.OnShutdownBridge(); 555 observer.OnShutdownBridge();
545 } 556 }
546 557
547 void ArcSessionManager::AddObserver(Observer* observer) { 558 void ArcSessionManager::AddObserver(Observer* observer) {
548 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 559 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
641 profile_->GetPrefs()->SetBoolean(prefs::kArcEnabled, false); 652 profile_->GetPrefs()->SetBoolean(prefs::kArcEnabled, false);
642 } 653 }
643 654
644 void ArcSessionManager::RecordArcState() { 655 void ArcSessionManager::RecordArcState() {
645 // Only record Enabled state if ARC is allowed in the first place, so we do 656 // Only record Enabled state if ARC is allowed in the first place, so we do
646 // not split the ARC population by devices that cannot run ARC. 657 // not split the ARC population by devices that cannot run ARC.
647 if (IsAllowed()) 658 if (IsAllowed())
648 UpdateEnabledStateUMA(IsArcEnabled()); 659 UpdateEnabledStateUMA(IsArcEnabled());
649 } 660 }
650 661
651 void ArcSessionManager::StartUI() { 662 void ArcSessionManager::StartTermsOfServiceNegotiation() {
652 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 663 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
664 DCHECK(!terms_of_service_negotiator_);
653 665
654 if (!arc_bridge_service()->stopped()) { 666 if (!arc_bridge_service()->stopped()) {
655 // If the user attempts to re-enable ARC while the bridge is still running 667 // If the user attempts to re-enable ARC while the bridge is still running
656 // the user should not be able to continue until the bridge has stopped. 668 // the user should not be able to continue until the bridge has stopped.
657 if (support_host_) { 669 if (support_host_) {
658 support_host_->ShowError( 670 support_host_->ShowError(
659 ArcSupportHost::Error::SIGN_IN_SERVICE_UNAVAILABLE_ERROR, false); 671 ArcSupportHost::Error::SIGN_IN_SERVICE_UNAVAILABLE_ERROR, false);
660 } 672 }
661 return; 673 return;
662 } 674 }
663 675
664 SetState(State::SHOWING_TERMS_OF_SERVICE); 676 SetState(State::SHOWING_TERMS_OF_SERVICE);
665 if (support_host_) 677 if (support_host_) {
666 support_host_->ShowTermsOfService(); 678 terms_of_service_negotiator_ =
679 base::MakeUnique<ArcTermsOfServiceNegotiator>(profile_->GetPrefs(),
680 support_host_.get());
681 terms_of_service_negotiator_->StartNegotiation(
682 base::Bind(&ArcSessionManager::OnTermsOfServiceNegotiated,
683 weak_ptr_factory_.GetWeakPtr()));
684 }
685 }
686
687 void ArcSessionManager::OnTermsOfServiceNegotiated(bool accepted) {
688 DCHECK(terms_of_service_negotiator_);
689 terms_of_service_negotiator_.reset();
690
691 if (!accepted) {
692 // To cancel, user needs to close the window. Note that clicking "Cancel"
693 // button effectively just closes the window.
694 CancelAuthCode();
695 return;
696 }
697
698 // Terms were accepted.
699 profile_->GetPrefs()->SetBoolean(prefs::kArcTermsAccepted, true);
700
701 support_host_->ShowArcLoading();
702 StartArcAndroidManagementCheck();
667 } 703 }
668 704
669 void ArcSessionManager::StartArcAndroidManagementCheck() { 705 void ArcSessionManager::StartArcAndroidManagementCheck() {
670 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 706 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
671 DCHECK(arc_bridge_service()->stopped()); 707 DCHECK(arc_bridge_service()->stopped());
672 DCHECK(state_ == State::SHOWING_TERMS_OF_SERVICE || 708 DCHECK(state_ == State::SHOWING_TERMS_OF_SERVICE ||
673 state_ == State::CHECKING_ANDROID_MANAGEMENT); 709 state_ == State::CHECKING_ANDROID_MANAGEMENT);
674 SetState(State::CHECKING_ANDROID_MANAGEMENT); 710 SetState(State::CHECKING_ANDROID_MANAGEMENT);
675 711
676 android_management_checker_.reset(new ArcAndroidManagementChecker( 712 android_management_checker_.reset(new ArcAndroidManagementChecker(
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
727 break; 763 break;
728 case policy::AndroidManagementClient::Result::ERROR: 764 case policy::AndroidManagementClient::Result::ERROR:
729 // This code should not be reached. For background check, 765 // This code should not be reached. For background check,
730 // retry_on_error should be set. 766 // retry_on_error should be set.
731 NOTREACHED(); 767 NOTREACHED();
732 } 768 }
733 } 769 }
734 770
735 void ArcSessionManager::OnWindowClosed() { 771 void ArcSessionManager::OnWindowClosed() {
736 DCHECK(support_host_); 772 DCHECK(support_host_);
773 if (terms_of_service_negotiator_) {
774 // In this case, ArcTermsOfServiceNegotiator should handle the case.
775 // Do nothing.
776 return;
777 }
737 CancelAuthCode(); 778 CancelAuthCode();
738 } 779 }
739 780
740 void ArcSessionManager::OnTermsAgreed(bool is_metrics_enabled, 781 void ArcSessionManager::OnTermsAgreed(bool is_metrics_enabled,
741 bool is_backup_and_restore_enabled, 782 bool is_backup_and_restore_enabled,
742 bool is_location_service_enabled) { 783 bool is_location_service_enabled) {
743 DCHECK(support_host_); 784 DCHECK(support_host_);
744 785 DCHECK(terms_of_service_negotiator_);
745 // Terms were accepted 786 // This should be handled in ArcTermsOfServiceNegotiator. Do nothing here.
746 profile_->GetPrefs()->SetBoolean(prefs::kArcTermsAccepted, true);
747
748 // Since this is ARC support's UI event callback, preference_handler_
749 // should be always created (see OnPrimaryUserProfilePrepared()).
750 // TODO(hidehiko): Simplify the logic with the code restructuring.
751 DCHECK(preference_handler_);
752 preference_handler_->EnableMetrics(is_metrics_enabled);
753 preference_handler_->EnableBackupRestore(is_backup_and_restore_enabled);
754 preference_handler_->EnableLocationService(is_location_service_enabled);
755 support_host_->ShowArcLoading();
756 StartArcAndroidManagementCheck();
757 } 787 }
758 788
759 void ArcSessionManager::OnRetryClicked() { 789 void ArcSessionManager::OnRetryClicked() {
760 DCHECK(support_host_); 790 DCHECK(support_host_);
761 791
762 UpdateOptInActionUMA(OptInActionType::RETRY); 792 UpdateOptInActionUMA(OptInActionType::RETRY);
763 793
764 // TODO(hidehiko): Simplify the retry logic. 794 // TODO(hidehiko): Simplify the retry logic.
765 if (!profile_->GetPrefs()->GetBoolean(prefs::kArcTermsAccepted)) { 795 if (terms_of_service_negotiator_) {
766 // If the user has not yet agreed on Terms of Service, then show it. 796 // Currently Terms of service is shown. ArcTermsOfServiceNegotiator should
767 support_host_->ShowTermsOfService(); 797 // handle this.
798 } else if (!profile_->GetPrefs()->GetBoolean(prefs::kArcTermsAccepted)) {
799 StartTermsOfServiceNegotiation();
768 } else if (support_host_->ui_page() == ArcSupportHost::UIPage::ERROR && 800 } else if (support_host_->ui_page() == ArcSupportHost::UIPage::ERROR &&
769 !arc_bridge_service()->stopped()) { 801 !arc_bridge_service()->stopped()) {
770 // ERROR_WITH_FEEDBACK is set in OnSignInFailed(). In the case, stopping 802 // ERROR_WITH_FEEDBACK is set in OnSignInFailed(). In the case, stopping
771 // ARC was postponed to contain its internal state into the report. 803 // ARC was postponed to contain its internal state into the report.
772 // Here, on retry, stop it, then restart. 804 // Here, on retry, stop it, then restart.
773 DCHECK_EQ(State::ACTIVE, state_); 805 DCHECK_EQ(State::ACTIVE, state_);
774 support_host_->ShowArcLoading(); 806 support_host_->ShowArcLoading();
775 ShutdownBridge(); 807 ShutdownBridge();
776 reenable_arc_ = true; 808 reenable_arc_ = true;
777 } else if (state_ == State::ACTIVE) { 809 } else if (state_ == State::ACTIVE) {
778 // This case is handled in ArcAuthService. 810 // This case is handled in ArcAuthService.
779 // Do nothing. 811 // Do nothing.
780 } else { 812 } else {
781 // Otherwise, we restart ARC. Note: this is the first boot case. 813 // Otherwise, we restart ARC. Note: this is the first boot case.
782 // For second or later boot, either ERROR_WITH_FEEDBACK case or ACTIVE 814 // For second or later boot, either ERROR_WITH_FEEDBACK case or ACTIVE
783 // case must hit. 815 // case must hit.
784 support_host_->ShowArcLoading(); 816 support_host_->ShowArcLoading();
785 StartArcAndroidManagementCheck(); 817 StartArcAndroidManagementCheck();
786 } 818 }
787 } 819 }
788 820
789 void ArcSessionManager::OnSendFeedbackClicked() { 821 void ArcSessionManager::OnSendFeedbackClicked() {
790 DCHECK(support_host_); 822 DCHECK(support_host_);
791 chrome::OpenFeedbackDialog(nullptr); 823 chrome::OpenFeedbackDialog(nullptr);
792 } 824 }
793 825
794 void ArcSessionManager::OnMetricsModeChanged(bool enabled, bool managed) {
795 if (!support_host_)
796 return;
797 support_host_->SetMetricsPreferenceCheckbox(enabled, managed);
798 }
799
800 void ArcSessionManager::OnBackupAndRestoreModeChanged(bool enabled,
801 bool managed) {
802 if (!support_host_)
803 return;
804 support_host_->SetBackupAndRestorePreferenceCheckbox(enabled, managed);
805 }
806
807 void ArcSessionManager::OnLocationServicesModeChanged(bool enabled,
808 bool managed) {
809 if (!support_host_)
810 return;
811 support_host_->SetLocationServicesPreferenceCheckbox(enabled, managed);
812 }
813
814 std::ostream& operator<<(std::ostream& os, 826 std::ostream& operator<<(std::ostream& os,
815 const ArcSessionManager::State& state) { 827 const ArcSessionManager::State& state) {
816 switch (state) { 828 switch (state) {
817 case ArcSessionManager::State::NOT_INITIALIZED: 829 case ArcSessionManager::State::NOT_INITIALIZED:
818 return os << "NOT_INITIALIZED"; 830 return os << "NOT_INITIALIZED";
819 case ArcSessionManager::State::STOPPED: 831 case ArcSessionManager::State::STOPPED:
820 return os << "STOPPED"; 832 return os << "STOPPED";
821 case ArcSessionManager::State::SHOWING_TERMS_OF_SERVICE: 833 case ArcSessionManager::State::SHOWING_TERMS_OF_SERVICE:
822 return os << "SHOWING_TERMS_OF_SERVICE"; 834 return os << "SHOWING_TERMS_OF_SERVICE";
823 case ArcSessionManager::State::CHECKING_ANDROID_MANAGEMENT: 835 case ArcSessionManager::State::CHECKING_ANDROID_MANAGEMENT:
824 return os << "CHECKING_ANDROID_MANAGEMENT"; 836 return os << "CHECKING_ANDROID_MANAGEMENT";
825 case ArcSessionManager::State::ACTIVE: 837 case ArcSessionManager::State::ACTIVE:
826 return os << "ACTIVE"; 838 return os << "ACTIVE";
827 } 839 }
828 840
829 // Some compiler reports an error even if all values of an enum-class are 841 // Some compiler reports an error even if all values of an enum-class are
830 // covered indivisually in a switch statement. 842 // covered indivisually in a switch statement.
831 NOTREACHED(); 843 NOTREACHED();
832 return os; 844 return os;
833 } 845 }
834 846
835 } // namespace arc 847 } // namespace arc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698