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

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 // In case UI is disabled we assume that ARC is opted-in.
503 // a privacy issue on next run without this flag set. 498 if (!profile_->GetPrefs()->GetBoolean(prefs::kArcTermsAccepted) &&
504 if (IsArcKioskMode()) 499 !IsOptInVerificationDisabled()) {
505 profile_->GetPrefs()->SetBoolean(prefs::kArcTermsAccepted, true); 500 // Need user's explicit Terms Of Service agreement.
506 StartArc(); 501 StartTermsOfServiceNegotiation();
507 return; 502 return;
508 } 503 }
509 504
510 if (!profile_->GetPrefs()->GetBoolean(prefs::kArcSignedIn)) { 505 StartArc();
511 if (profile_->GetPrefs()->GetBoolean(prefs::kArcTermsAccepted)) { 506
512 StartArc(); 507 // Skip Android management check for testing.
513 } else { 508 if (IsOptInVerificationDisabled() ||
514 // Need pre-fetch auth code and show OptIn UI if needed. 509 (g_disable_ui_for_testing &&
515 StartUI(); 510 !g_enable_check_android_management_for_testing)) {
516 } 511 return;
517 } else {
518 // Ready to start Arc, but check Android management in parallel.
519 StartArc();
520 // 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().
522 // Otherwise, DisableArc() which may be called in
523 // OnBackgroundAndroidManagementChecked() could be ignored.
524 if (!g_disable_ui_for_testing ||
525 g_enable_check_android_management_for_testing) {
526 android_management_checker_.reset(new ArcAndroidManagementChecker(
527 profile_, context_->token_service(), context_->account_id(),
528 true /* retry_on_error */));
529 android_management_checker_->StartCheck(
530 base::Bind(&ArcSessionManager::OnBackgroundAndroidManagementChecked,
531 weak_ptr_factory_.GetWeakPtr()));
532 }
533 } 512 }
513
514 // We skip following if Android management check because there are no
515 // managed human users for Kiosk exist.
516 if (IsArcKioskMode())
517 return;
518
519 // If Sign-in is not yet completed, but terms-of-service is already agreed,
520 // then it should have been done in OOBE phase.
Luis Héctor Chávez 2016/11/29 18:18:12 ah! now I understand this part. "If Sign-in is no
hidehiko 2016/12/01 14:20:09 Chatted with khmel@ offline. It was not, but it wa
521 // The Android management check should be also done in the OOBE phase.
522 if (!profile_->GetPrefs()->GetBoolean(prefs::kArcSignedIn))
523 return;
524
525 // Check Android management in parallel.
526 // Note: Because the callback may be called in synchronous way (i.e. called
527 // on the same stack), StartCheck() needs to be called *after* StartArc().
528 // Otherwise, DisableArc() which may be called in
529 // OnBackgroundAndroidManagementChecked() could be ignored.
530 android_management_checker_ = base::MakeUnique<ArcAndroidManagementChecker>(
531 profile_, context_->token_service(), context_->account_id(),
532 true /* retry_on_error */);
533 android_management_checker_->StartCheck(
534 base::Bind(&ArcSessionManager::OnBackgroundAndroidManagementChecked,
535 weak_ptr_factory_.GetWeakPtr()));
534 } 536 }
535 537
536 void ArcSessionManager::ShutdownBridge() { 538 void ArcSessionManager::ShutdownBridge() {
537 arc_sign_in_timer_.Stop(); 539 arc_sign_in_timer_.Stop();
538 playstore_launcher_.reset(); 540 playstore_launcher_.reset();
541 terms_of_service_negotiator_.reset();
539 android_management_checker_.reset(); 542 android_management_checker_.reset();
540 arc_bridge_service()->RequestStop(); 543 arc_bridge_service()->RequestStop();
541 if (state_ != State::NOT_INITIALIZED) 544 if (state_ != State::NOT_INITIALIZED)
542 SetState(State::STOPPED); 545 SetState(State::STOPPED);
543 for (auto& observer : observer_list_) 546 for (auto& observer : observer_list_)
544 observer.OnShutdownBridge(); 547 observer.OnShutdownBridge();
545 } 548 }
546 549
547 void ArcSessionManager::AddObserver(Observer* observer) { 550 void ArcSessionManager::AddObserver(Observer* observer) {
548 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 551 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); 644 profile_->GetPrefs()->SetBoolean(prefs::kArcEnabled, false);
642 } 645 }
643 646
644 void ArcSessionManager::RecordArcState() { 647 void ArcSessionManager::RecordArcState() {
645 // Only record Enabled state if ARC is allowed in the first place, so we do 648 // 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. 649 // not split the ARC population by devices that cannot run ARC.
647 if (IsAllowed()) 650 if (IsAllowed())
648 UpdateEnabledStateUMA(IsArcEnabled()); 651 UpdateEnabledStateUMA(IsArcEnabled());
649 } 652 }
650 653
651 void ArcSessionManager::StartUI() { 654 void ArcSessionManager::StartTermsOfServiceNegotiation() {
652 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 655 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
656 DCHECK(!terms_of_service_negotiator_);
653 657
654 if (!arc_bridge_service()->stopped()) { 658 if (!arc_bridge_service()->stopped()) {
655 // If the user attempts to re-enable ARC while the bridge is still running 659 // 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. 660 // the user should not be able to continue until the bridge has stopped.
657 if (support_host_) { 661 if (support_host_) {
658 support_host_->ShowError( 662 support_host_->ShowError(
659 ArcSupportHost::Error::SIGN_IN_SERVICE_UNAVAILABLE_ERROR, false); 663 ArcSupportHost::Error::SIGN_IN_SERVICE_UNAVAILABLE_ERROR, false);
660 } 664 }
661 return; 665 return;
662 } 666 }
663 667
664 SetState(State::SHOWING_TERMS_OF_SERVICE); 668 SetState(State::SHOWING_TERMS_OF_SERVICE);
665 if (support_host_) 669 if (support_host_) {
666 support_host_->ShowTermsOfService(); 670 terms_of_service_negotiator_ =
671 base::MakeUnique<ArcTermsOfServiceNegotiator>(profile_->GetPrefs(),
672 support_host_.get());
673 terms_of_service_negotiator_->StartNegotiation(
674 base::Bind(&ArcSessionManager::OnTermsOfServiceNegotiated,
675 weak_ptr_factory_.GetWeakPtr()));
676 }
677 }
678
679 void ArcSessionManager::OnTermsOfServiceNegotiated(bool agreed) {
Luis Héctor Chávez 2016/11/29 18:18:12 nit: let's standardize on "accepted" since you're
hidehiko 2016/12/01 14:20:09 Done for ArcTermsOfServiceNegotiator and above lay
680 DCHECK(terms_of_service_negotiator_);
681 terms_of_service_negotiator_.reset();
682
683 if (!agreed) {
684 // To cancel, user needs to close the window. Note that clicking "Cancel"
685 // button effectively just closes the window.
686 CancelAuthCode();
687 return;
688 }
689
690 // Terms were accepted.
691 profile_->GetPrefs()->SetBoolean(prefs::kArcTermsAccepted, true);
692
693 support_host_->ShowArcLoading();
694 StartArcAndroidManagementCheck();
667 } 695 }
668 696
669 void ArcSessionManager::StartArcAndroidManagementCheck() { 697 void ArcSessionManager::StartArcAndroidManagementCheck() {
670 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 698 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
671 DCHECK(arc_bridge_service()->stopped()); 699 DCHECK(arc_bridge_service()->stopped());
672 DCHECK(state_ == State::SHOWING_TERMS_OF_SERVICE || 700 DCHECK(state_ == State::SHOWING_TERMS_OF_SERVICE ||
673 state_ == State::CHECKING_ANDROID_MANAGEMENT); 701 state_ == State::CHECKING_ANDROID_MANAGEMENT);
674 SetState(State::CHECKING_ANDROID_MANAGEMENT); 702 SetState(State::CHECKING_ANDROID_MANAGEMENT);
675 703
676 android_management_checker_.reset(new ArcAndroidManagementChecker( 704 android_management_checker_.reset(new ArcAndroidManagementChecker(
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
727 break; 755 break;
728 case policy::AndroidManagementClient::Result::ERROR: 756 case policy::AndroidManagementClient::Result::ERROR:
729 // This code should not be reached. For background check, 757 // This code should not be reached. For background check,
730 // retry_on_error should be set. 758 // retry_on_error should be set.
731 NOTREACHED(); 759 NOTREACHED();
732 } 760 }
733 } 761 }
734 762
735 void ArcSessionManager::OnWindowClosed() { 763 void ArcSessionManager::OnWindowClosed() {
736 DCHECK(support_host_); 764 DCHECK(support_host_);
765 if (terms_of_service_negotiator_) {
766 // In this case, ArcTermsOfServiceNegotiator should handle the case.
767 // Do nothing.
768 return;
769 }
737 CancelAuthCode(); 770 CancelAuthCode();
738 } 771 }
739 772
740 void ArcSessionManager::OnTermsAgreed(bool is_metrics_enabled, 773 void ArcSessionManager::OnTermsAgreed(bool is_metrics_enabled,
741 bool is_backup_and_restore_enabled, 774 bool is_backup_and_restore_enabled,
742 bool is_location_service_enabled) { 775 bool is_location_service_enabled) {
743 DCHECK(support_host_); 776 DCHECK(support_host_);
744 777 DCHECK(terms_of_service_negotiator_);
745 // Terms were accepted 778 // 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 } 779 }
758 780
759 void ArcSessionManager::OnRetryClicked() { 781 void ArcSessionManager::OnRetryClicked() {
760 DCHECK(support_host_); 782 DCHECK(support_host_);
761 783
762 UpdateOptInActionUMA(OptInActionType::RETRY); 784 UpdateOptInActionUMA(OptInActionType::RETRY);
763 785
764 // TODO(hidehiko): Simplify the retry logic. 786 // TODO(hidehiko): Simplify the retry logic.
765 if (!profile_->GetPrefs()->GetBoolean(prefs::kArcTermsAccepted)) { 787 if (terms_of_service_negotiator_) {
766 // If the user has not yet agreed on Terms of Service, then show it. 788 // Currently Terms of service is shown. ArcTermsOfServiceNegotiator should
767 support_host_->ShowTermsOfService(); 789 // handle this.
790 } else if (!profile_->GetPrefs()->GetBoolean(prefs::kArcTermsAccepted)) {
791 StartTermsOfServiceNegotiation();
768 } else if (support_host_->ui_page() == ArcSupportHost::UIPage::ERROR && 792 } else if (support_host_->ui_page() == ArcSupportHost::UIPage::ERROR &&
769 !arc_bridge_service()->stopped()) { 793 !arc_bridge_service()->stopped()) {
770 // ERROR_WITH_FEEDBACK is set in OnSignInFailed(). In the case, stopping 794 // ERROR_WITH_FEEDBACK is set in OnSignInFailed(). In the case, stopping
771 // ARC was postponed to contain its internal state into the report. 795 // ARC was postponed to contain its internal state into the report.
772 // Here, on retry, stop it, then restart. 796 // Here, on retry, stop it, then restart.
773 DCHECK_EQ(State::ACTIVE, state_); 797 DCHECK_EQ(State::ACTIVE, state_);
774 support_host_->ShowArcLoading(); 798 support_host_->ShowArcLoading();
775 ShutdownBridge(); 799 ShutdownBridge();
776 reenable_arc_ = true; 800 reenable_arc_ = true;
777 } else if (state_ == State::ACTIVE) { 801 } else if (state_ == State::ACTIVE) {
778 // This case is handled in ArcAuthService. 802 // This case is handled in ArcAuthService.
779 // Do nothing. 803 // Do nothing.
780 } else { 804 } else {
781 // Otherwise, we restart ARC. Note: this is the first boot case. 805 // Otherwise, we restart ARC. Note: this is the first boot case.
782 // For second or later boot, either ERROR_WITH_FEEDBACK case or ACTIVE 806 // For second or later boot, either ERROR_WITH_FEEDBACK case or ACTIVE
783 // case must hit. 807 // case must hit.
784 support_host_->ShowArcLoading(); 808 support_host_->ShowArcLoading();
785 StartArcAndroidManagementCheck(); 809 StartArcAndroidManagementCheck();
786 } 810 }
787 } 811 }
788 812
789 void ArcSessionManager::OnSendFeedbackClicked() { 813 void ArcSessionManager::OnSendFeedbackClicked() {
790 DCHECK(support_host_); 814 DCHECK(support_host_);
791 chrome::OpenFeedbackDialog(nullptr); 815 chrome::OpenFeedbackDialog(nullptr);
792 } 816 }
793 817
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, 818 std::ostream& operator<<(std::ostream& os,
815 const ArcSessionManager::State& state) { 819 const ArcSessionManager::State& state) {
816 switch (state) { 820 switch (state) {
817 case ArcSessionManager::State::NOT_INITIALIZED: 821 case ArcSessionManager::State::NOT_INITIALIZED:
818 return os << "NOT_INITIALIZED"; 822 return os << "NOT_INITIALIZED";
819 case ArcSessionManager::State::STOPPED: 823 case ArcSessionManager::State::STOPPED:
820 return os << "STOPPED"; 824 return os << "STOPPED";
821 case ArcSessionManager::State::SHOWING_TERMS_OF_SERVICE: 825 case ArcSessionManager::State::SHOWING_TERMS_OF_SERVICE:
822 return os << "SHOWING_TERMS_OF_SERVICE"; 826 return os << "SHOWING_TERMS_OF_SERVICE";
823 case ArcSessionManager::State::CHECKING_ANDROID_MANAGEMENT: 827 case ArcSessionManager::State::CHECKING_ANDROID_MANAGEMENT:
824 return os << "CHECKING_ANDROID_MANAGEMENT"; 828 return os << "CHECKING_ANDROID_MANAGEMENT";
825 case ArcSessionManager::State::ACTIVE: 829 case ArcSessionManager::State::ACTIVE:
826 return os << "ACTIVE"; 830 return os << "ACTIVE";
827 } 831 }
828 832
829 // Some compiler reports an error even if all values of an enum-class are 833 // Some compiler reports an error even if all values of an enum-class are
830 // covered indivisually in a switch statement. 834 // covered indivisually in a switch statement.
831 NOTREACHED(); 835 NOTREACHED();
832 return os; 836 return os;
833 } 837 }
834 838
835 } // namespace arc 839 } // namespace arc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698