File: silent_sync_enabler.cc

package info (click to toggle)
chromium 120.0.6099.224-1~deb11u1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 6,112,112 kB
  • sloc: cpp: 32,907,025; ansic: 8,148,123; javascript: 3,679,536; python: 2,031,248; asm: 959,718; java: 804,675; xml: 617,256; sh: 111,417; objc: 100,835; perl: 88,443; cs: 53,032; makefile: 29,579; fortran: 24,137; php: 21,162; tcl: 21,147; sql: 20,809; ruby: 17,735; pascal: 12,864; yacc: 8,045; lisp: 3,388; lex: 1,323; ada: 727; awk: 329; jsp: 267; csh: 117; exp: 43; sed: 37
file content (115 lines) | stat: -rw-r--r-- 4,479 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ui/startup/silent_sync_enabler.h"

#include "base/functional/callback_forward.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/signin/identity_manager_factory.h"
#include "chrome/browser/ui/webui/signin/login_ui_service.h"
#include "chrome/browser/ui/webui/signin/signin_utils.h"
#include "chrome/browser/ui/webui/signin/turn_sync_on_helper.h"
#include "components/signin/public/base/signin_metrics.h"
#include "components/signin/public/identity_manager/identity_manager.h"
#include "google_apis/gaia/core_account_id.h"

namespace {

// Silently goes through the `TurnSyncOnHelper` flow, enabling Sync when given
// the opportunity.
class SilentTurnSyncOnHelperDelegate : public TurnSyncOnHelper::Delegate {
 public:
  ~SilentTurnSyncOnHelperDelegate() override = default;

  // TurnSyncOnHelper::Delegate:
  void ShowEnterpriseAccountConfirmation(
      const AccountInfo& account_info,
      signin::SigninChoiceCallback callback) override {
    // We proceed here, and we are waiting until `ShowSyncConfirmation()` for
    // the Sync engine to be started to know if we can proceed or not.
    // TODO(https://crbug.com/1324569): Introduce a `DEFER` status or a new
    // `ShouldShowEnterpriseAccountConfirmation()` delegate method to handle
    // management consent not being handled at this step.
    std::move(callback).Run(signin::SIGNIN_CHOICE_CONTINUE);
  }

  void ShowSyncConfirmation(
      base::OnceCallback<void(LoginUIService::SyncConfirmationUIClosedResult)>
          callback) override {
    // The purpose of this delegate is specifically to enable Sync silently. If
    // we get all the way here, we assume that we can proceed with it.
    std::move(callback).Run(LoginUIService::SyncConfirmationUIClosedResult::
                                SYNC_WITH_DEFAULT_SETTINGS);
  }

  bool ShouldAbortBeforeShowSyncDisabledConfirmation() override { return true; }

  void ShowSyncDisabledConfirmation(
      bool is_managed_account,
      base::OnceCallback<void(LoginUIService::SyncConfirmationUIClosedResult)>
          callback) override {
    // If Sync is disabled, the `TurnSyncOnHelper` should quit earlier due to
    // `ShouldAbortBeforeShowSyncDisabledConfirmation()`.
    NOTREACHED();
  }

  void ShowLoginError(const SigninUIError& error) override { NOTREACHED(); }

  void ShowMergeSyncDataConfirmation(const std::string&,
                                     const std::string&,
                                     signin::SigninChoiceCallback) override {
    NOTREACHED();
  }

  void ShowSyncSettings() override { NOTREACHED(); }

  void SwitchToProfile(Profile*) override { NOTREACHED(); }
};

}  // namespace

SilentSyncEnabler::SilentSyncEnabler(Profile& profile,
                                     signin::IdentityManager& identity_manager)
    : profile_(profile), identity_manager_(identity_manager) {}

SilentSyncEnabler::~SilentSyncEnabler() = default;

void SilentSyncEnabler::StartAttempt(base::OnceClosure callback) {
  DCHECK(!callback_);  // An attempt should not be ongoing
  DCHECK(callback);

  DCHECK(identity_manager_->HasPrimaryAccount(signin::ConsentLevel::kSignin));
  DCHECK(!identity_manager_->HasPrimaryAccount(signin::ConsentLevel::kSync));

  callback_ = std::move(callback);
  if (identity_manager_->AreRefreshTokensLoaded()) {
    TryEnableSyncSilentlyWithToken();
  } else {
    scoped_observation_.Observe(&identity_manager_.get());
  }
}

void SilentSyncEnabler::OnRefreshTokensLoaded() {
  scoped_observation_.Reset();
  TryEnableSyncSilentlyWithToken();
}

void SilentSyncEnabler::TryEnableSyncSilentlyWithToken() {
  CoreAccountId account_id =
      identity_manager_->GetPrimaryAccountId(signin::ConsentLevel::kSignin);
  if (!identity_manager_->HasAccountWithRefreshToken(account_id)) {
    // Still no token, just give up.
    if (callback_)
      std::move(callback_).Run();
    return;
  }

  // TurnSyncOnHelper deletes itself once done.
  new TurnSyncOnHelper(
      &profile_.get(), signin_metrics::AccessPoint::ACCESS_POINT_UNKNOWN,
      signin_metrics::PromoAction::PROMO_ACTION_NO_SIGNIN_PROMO,
      signin_metrics::Reason::kSigninPrimaryAccount, account_id,
      TurnSyncOnHelper::SigninAbortedMode::KEEP_ACCOUNT,
      std::make_unique<SilentTurnSyncOnHelperDelegate>(), std::move(callback_));
}