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

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

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

Powered by Google App Engine
This is Rietveld 408576698