File: profile_picker_dice_sign_in_provider.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (167 lines) | stat: -rw-r--r-- 7,097 bytes parent folder | download | duplicates (3)
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_UI_VIEWS_PROFILES_PROFILE_PICKER_DICE_SIGN_IN_PROVIDER_H_
#define CHROME_BROWSER_UI_VIEWS_PROFILES_PROFILE_PICKER_DICE_SIGN_IN_PROVIDER_H_

#include <optional>

#include "base/files/file_path.h"
#include "base/functional/callback_forward.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "chrome/browser/profiles/keep_alive/scoped_profile_keep_alive.h"
#include "chrome/browser/ui/chrome_web_modal_dialog_manager_delegate.h"
#include "chrome/browser/ui/views/profiles/profile_management_types.h"
#include "chrome/browser/ui/views/profiles/profile_picker_web_contents_host.h"
#include "components/signin/public/base/signin_metrics.h"
#include "content/public/browser/web_contents_delegate.h"

struct CoreAccountInfo;
class DiceTabHelper;
class ProfilePickerWebContentsHost;

namespace content {
struct ContextMenuParams;
class RenderFrameHost;
class WebContents;
}  // namespace content

// Class responsible for the GAIA sign-in within profile management flows.
class ProfilePickerDiceSignInProvider
    : public content::WebContentsDelegate,
      public ChromeWebModalDialogManagerDelegate {
 public:
  // The callback returns the newly created profile and a valid WebContents
  // instance within this profile. If the account info is empty, sign-in is not
  // completed there yet. Otherwise, the newly created profile has the account
  // in its `IdentityManager`, but the account may not be set as primary yet.
  // If the flow gets canceled by closing the window, the callback never gets
  // called.
  // TODO(crbug.com/40785551): Properly support saml sign in so that the special
  // casing is not needed here.
  using SignedInCallback =
      base::OnceCallback<void(Profile*,
                              const CoreAccountInfo&,
                              std::unique_ptr<content::WebContents>)>;

  // Creates a new provider that will render the Gaia sign-in flow in `host` for
  // a profile at `profile_path`.
  // If no `profile_path` is provided, a new profile (and associated directory)
  // will be created.
  explicit ProfilePickerDiceSignInProvider(
      ProfilePickerWebContentsHost* host,
      signin_metrics::AccessPoint signin_access_point,
      base::FilePath profile_path = base::FilePath());
  ~ProfilePickerDiceSignInProvider() override;
  ProfilePickerDiceSignInProvider(const ProfilePickerDiceSignInProvider&) =
      delete;
  ProfilePickerDiceSignInProvider& operator=(
      const ProfilePickerDiceSignInProvider&) = delete;

  // Initiates switching the flow to sign-in (which is normally asynchronous).
  // If a sign-in was in progress before in the lifetime of this class, it only
  // (synchronously) switches the view to show the ongoing sign-in again. When
  // the sign-in screen is displayed, `switch_finished_callback` gets called.
  // When the sign-in finishes (if it ever happens), `signin_finished_callback`
  // gets called.
  void SwitchToSignIn(StepSwitchFinishedCallback switch_finished_callback,
                      SignedInCallback signin_finished_callback);

  // Reloads the sign-in page if applicable.
  void ReloadSignInPage();

  // Navigates back in the sign-in flow if applicable.
  void NavigateBack();

  // Returns whether the flow is initialized (i.e. whether `profile_` has been
  // loaded).
  bool IsInitialized() const;

  content::WebContents* contents() const { return contents_.get(); }

 private:
  // content::WebContentsDelegate:
  bool HandleContextMenu(content::RenderFrameHost& render_frame_host,
                         const content::ContextMenuParams& params) override;
  content::WebContents* AddNewContents(
      content::WebContents* source,
      std::unique_ptr<content::WebContents> new_contents,
      const GURL& target_url,
      WindowOpenDisposition disposition,
      const blink::mojom::WindowFeatures& window_features,
      bool user_gesture,
      bool* was_blocked) override;
  bool HandleKeyboardEvent(content::WebContents* source,
                           const input::NativeWebKeyboardEvent& event) override;
  void NavigationStateChanged(content::WebContents* source,
                              content::InvalidateTypes changed_flags) override;

  // ChromeWebModalDialogManagerDelegate:
  web_modal::WebContentsModalDialogHost* GetWebContentsModalDialogHost()
      override;

  // Initializes the flow with the newly created or loaded profile.
  void OnProfileInitialized(StepSwitchFinishedCallback switch_finished_callback,
                            Profile* new_profile);

  // `account_info` is empty if the signin could not complete and must continue
  // in a browser (e.g. for SAML).
  void FinishFlow(const CoreAccountInfo& account_info);

  // Callback for the `DiceTabHelper`. Calls `FinishFlow()`.
  void FinishFlowInPicker(Profile* profile,
                          signin_metrics::AccessPoint access_point,
                          signin_metrics::PromoAction promo_action,
                          content::WebContents* contents,
                          const CoreAccountInfo& account_info);

  void OnSignInContentsFreedUp();

  void ResetWebContentsDelegates();

  GURL BuildSigninURL() const;

  // The sync confirmation screen is triggered by the `DiceTabHelper`. This can
  // happen in two cases: in the picker for normal accounts, and  in the
  // browser for SAML account.
  enum class DiceTabHelperMode {
    kInPicker,   // The sync confirmation screen opens in the picker.
    kInBrowser,  // The sync confirmation screen opens in the browser.
  };

  // Initializes the `DiceTabHelper`. It is initialized once at the beginning,
  // with the `kInPicker` mode, and in case of SAML it is initialized again
  // with the `kInBrowser` mode as the web contents is extracted to a tab.
  void InitializeDiceTabHelper(DiceTabHelper& helper, DiceTabHelperMode mode);

  // The host must outlive this object.
  const raw_ptr<ProfilePickerWebContentsHost> host_;

  const signin_metrics::AccessPoint signin_access_point_;

  // The path to the profile in which to perform the sign-in. If empty, a new
  // profile will be created.
  const base::FilePath profile_path_;
  // Sign-in callback, valid until it's called.
  SignedInCallback callback_;

  raw_ptr<Profile> profile_ = nullptr;

  // Prevent |profile_| from being destroyed first.
  std::unique_ptr<ScopedProfileKeepAlive> profile_keep_alive_;

  // The web contents backed by `profile_`. This is used for displaying the
  // sign-in flow.
  std::unique_ptr<content::WebContents> contents_;

  // Because of ProfileOAuth2TokenService intricacies, the sign in should not
  // finish before both the notification gets called.
  // TODO(crbug.com/40791271): Remove this if the bug gets resolved.
  bool refresh_token_updated_ = false;

  base::WeakPtrFactory<ProfilePickerDiceSignInProvider> weak_ptr_factory_{this};
};

#endif  // CHROME_BROWSER_UI_VIEWS_PROFILES_PROFILE_PICKER_DICE_SIGN_IN_PROVIDER_H_