blob: 59e334ddc0084f10096e67b4210082f4a0b9b0d6 [file] [log] [blame]
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_WEBUI_SIGNIN_DICE_TURN_SYNC_ON_HELPER_H_
#define CHROME_BROWSER_UI_WEBUI_SIGNIN_DICE_TURN_SYNC_ON_HELPER_H_
#include <memory>
#include <string>
#include "base/callback_forward.h"
#include "base/callback_helpers.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/sync/sync_startup_tracker.h"
#include "chrome/browser/ui/webui/signin/login_ui_service.h"
#include "components/keyed_service/core/keyed_service_shutdown_notifier.h"
#include "components/signin/public/base/signin_metrics.h"
#include "components/signin/public/identity_manager/account_info.h"
class Browser;
namespace signin {
class IdentityManager;
}
namespace syncer {
class SyncService;
class SyncSetupInProgressHandle;
}
// Handles details of setting the primary account with IdentityManager and
// turning on sync for an account for which there is already a refresh token.
class DiceTurnSyncOnHelper : public SyncStartupTracker::Observer {
public:
// Behavior when the signin is aborted (by an error or cancelled by the user).
enum class SigninAbortedMode {
// The token is revoked and the account is signed out of the web.
REMOVE_ACCOUNT,
// The account is kept.
KEEP_ACCOUNT
};
// User choice when signing in.
// Used for UMA histograms, Hence, constants should never be deleted or
// reordered, and new constants should only be appended at the end.
// Keep this in sync with SigninChoice in histograms.xml.
enum SigninChoice {
SIGNIN_CHOICE_CANCEL = 0, // Signin is cancelled.
SIGNIN_CHOICE_CONTINUE = 1, // Signin continues in the current profile.
SIGNIN_CHOICE_NEW_PROFILE = 2, // Signin continues in a new profile.
// SIGNIN_CHOICE_SIZE should always be last.
SIGNIN_CHOICE_SIZE,
};
using SigninChoiceCallback = base::OnceCallback<void(SigninChoice)>;
// Delegate implementing the UI prompts.
class Delegate {
public:
virtual ~Delegate() {}
// Shows a login error to the user.
virtual void ShowLoginError(const std::string& email,
const std::string& error_message) = 0;
// Shows a confirmation dialog when the user was previously signed in with a
// different account in the same profile. |callback| must be called.
virtual void ShowMergeSyncDataConfirmation(
const std::string& previous_email,
const std::string& new_email,
SigninChoiceCallback callback) = 0;
// Shows a confirmation dialog when the user is signing in a managed
// account. |callback| must be called.
virtual void ShowEnterpriseAccountConfirmation(
const std::string& email,
SigninChoiceCallback callback) = 0;
// Shows a sync confirmation screen offering to open the Sync settings.
// |callback| must be called.
virtual void ShowSyncConfirmation(
base::OnceCallback<void(LoginUIService::SyncConfirmationUIClosedResult)>
callback) = 0;
// Opens the Sync settings page.
virtual void ShowSyncSettings() = 0;
// Informs the delegate that the flow is switching to a new profile.
virtual void SwitchToProfile(Profile* new_profile) = 0;
};
// Create a helper that turns sync on for an account that is already present
// in the token service.
// |callback| is called at the end of the flow (i.e. after the user closes the
// sync confirmation dialog).
DiceTurnSyncOnHelper(Profile* profile,
signin_metrics::AccessPoint signin_access_point,
signin_metrics::PromoAction signin_promo_action,
signin_metrics::Reason signin_reason,
const std::string& account_id,
SigninAbortedMode signin_aborted_mode,
std::unique_ptr<Delegate> delegate,
base::OnceClosure callback);
// Convenience constructor using the default delegate and empty callback.
DiceTurnSyncOnHelper(Profile* profile,
Browser* browser,
signin_metrics::AccessPoint signin_access_point,
signin_metrics::PromoAction signin_promo_action,
signin_metrics::Reason signin_reason,
const std::string& account_id,
SigninAbortedMode signin_aborted_mode);
// SyncStartupTracker::Observer:
void SyncStartupCompleted() override;
void SyncStartupFailed() override;
private:
friend class base::DeleteHelper<DiceTurnSyncOnHelper>;
enum class ProfileMode {
// Attempts to sign the user in |profile_|. Note that if the account to be
// signed in is a managed account, then a profile confirmation dialog is
// shown and the user has the possibility to create a new profile before
// signing in.
CURRENT_PROFILE,
// Creates a new profile and signs the user in this new profile.
NEW_PROFILE
};
// DiceTurnSyncOnHelper deletes itself.
~DiceTurnSyncOnHelper() override;
// Handles can offer sign-in errors. It returns true if there is an error,
// and false otherwise.
bool HasCanOfferSigninError();
// Used as callback for ShowMergeSyncDataConfirmation().
void OnMergeAccountConfirmation(SigninChoice choice);
// Used as callback for ShowEnterpriseAccountConfirmation().
void OnEnterpriseAccountConfirmation(SigninChoice choice);
// Turns sync on with the current profile or a new profile.
void TurnSyncOnWithProfileMode(ProfileMode profile_mode);
// Callback invoked once policy registration is complete. If registration
// fails, |dm_token| and |client_id| will be empty.
void OnRegisteredForPolicy(const std::string& dm_token,
const std::string& client_id);
// Helper function that loads policy with the cached |dm_token_| and
// |client_id|, then completes the signin process.
void LoadPolicyWithCachedCredentials();
// Callback invoked when a policy fetch request has completed. |success| is
// true if policy was successfully fetched.
void OnPolicyFetchComplete(bool success);
// Called to create a new profile, which is then signed in with the
// in-progress auth credentials currently stored in this object.
void CreateNewSignedInProfile();
// Callback invoked once a profile is created, so we can transfer the
// credentials.
void OnNewProfileCreated(Profile* new_profile, Profile::CreateStatus status);
// Callback invoked once the token service is ready for the new profile.
void OnNewProfileTokensLoaded(Profile* new_profile);
// Returns the SyncService, or nullptr if sync is not allowed.
syncer::SyncService* GetSyncService();
// Completes the signin in IdentityManager and displays the Sync confirmation
// UI.
void SigninAndShowSyncConfirmationUI();
// Displays the Sync confirmation UI.
// Note: If sync fails to start (e.g. sync is disabled by admin), the sync
// confirmation dialog will be updated accordingly.
void ShowSyncConfirmationUI();
// Handles the user input from the sync confirmation UI and deletes this
// object.
void FinishSyncSetupAndDelete(
LoginUIService::SyncConfirmationUIClosedResult result);
// Switch to a new profile after exporting the token.
void SwitchToProfile(Profile* new_profile);
// Aborts the flow and deletes this object.
void AbortAndDelete();
std::unique_ptr<Delegate> delegate_;
Profile* profile_;
signin::IdentityManager* identity_manager_;
const signin_metrics::AccessPoint signin_access_point_;
const signin_metrics::PromoAction signin_promo_action_;
const signin_metrics::Reason signin_reason_;
// Whether the refresh token should be deleted if the Sync flow is aborted.
SigninAbortedMode signin_aborted_mode_;
// Account information.
const AccountInfo account_info_;
// Prevents Sync from running until configuration is complete.
std::unique_ptr<syncer::SyncSetupInProgressHandle> sync_blocker_;
// Policy credentials we keep while determining whether to create
// a new profile for an enterprise user or not.
std::string dm_token_;
std::string client_id_;
// Called when this object is deleted.
base::ScopedClosureRunner scoped_callback_runner_;
std::unique_ptr<SyncStartupTracker> sync_startup_tracker_;
std::unique_ptr<KeyedServiceShutdownNotifier::Subscription>
shutdown_subscription_;
base::WeakPtrFactory<DiceTurnSyncOnHelper> weak_pointer_factory_{this};
DISALLOW_COPY_AND_ASSIGN(DiceTurnSyncOnHelper);
};
#endif // CHROME_BROWSER_UI_WEBUI_SIGNIN_DICE_TURN_SYNC_ON_HELPER_H_