Add a minor text member to ui::MenuModel.
[chromium-blink-merge.git] / chrome / browser / ui / sync / one_click_signin_helper.h
blob337b282973e7219c6a061ad188ab4a20d29e463e
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef CHROME_BROWSER_UI_SYNC_ONE_CLICK_SIGNIN_HELPER_H_
6 #define CHROME_BROWSER_UI_SYNC_ONE_CLICK_SIGNIN_HELPER_H_
8 #include <string>
10 #include "base/gtest_prod_util.h"
11 #include "base/memory/weak_ptr.h"
12 #include "chrome/browser/signin/signin_promo.h"
13 #include "chrome/browser/sync/profile_sync_service_observer.h"
14 #include "chrome/browser/ui/sync/one_click_signin_sync_starter.h"
15 #include "content/public/browser/navigation_controller.h"
16 #include "content/public/browser/web_contents_observer.h"
17 #include "content/public/browser/web_contents_user_data.h"
18 #include "google_apis/gaia/google_service_auth_error.h"
20 class Browser;
21 class GURL;
22 class PasswordManager;
23 class ProfileIOData;
25 namespace content {
26 class WebContents;
27 struct FrameNavigateParams;
28 struct LoadCommittedDetails;
29 struct PasswordForm;
32 namespace net {
33 class URLRequest;
36 // Per-tab one-click signin helper. When a user signs in to a Google service
37 // and the profile is not yet connected to a Google account, will start the
38 // process of helping the user connect his profile with one click. The process
39 // begins with an infobar and is followed with a confirmation dialog explaining
40 // more about what this means.
41 class OneClickSigninHelper
42 : public content::WebContentsObserver,
43 public content::WebContentsUserData<OneClickSigninHelper>,
44 public ProfileSyncServiceObserver {
45 public:
46 // Represents user's decision about sign in process.
47 enum AutoAccept {
48 // User decision not yet known. Assume cancel.
49 AUTO_ACCEPT_NONE,
51 // User has explicitly accepted to sign in. A bubble is shown with the
52 // option to start sync, configure it first, or abort.
53 AUTO_ACCEPT_ACCEPTED,
55 // User has explicitly accepted to sign in, but wants to configure sync
56 // settings before turning it on.
57 AUTO_ACCEPT_CONFIGURE,
59 // User has explicitly rejected to sign in. Furthermore, the user does
60 // not want to be prompted to see the interstitial again in this profile.
61 AUTO_ACCEPT_REJECTED_FOR_PROFILE,
63 // This is an explicit sign in from either first run, NTP, wrench menu,
64 // or settings page. The user will be signed in automatically with sync
65 // enabled using default settings.
66 AUTO_ACCEPT_EXPLICIT
69 // Return value of CanOfferOnIOThread().
70 enum Offer {
71 CAN_OFFER,
72 DONT_OFFER,
73 IGNORE_REQUEST
76 // Argument to CanOffer().
77 enum CanOfferFor {
78 CAN_OFFER_FOR_ALL,
79 CAN_OFFER_FOR_INTERSTITAL_ONLY
82 static void CreateForWebContentsWithPasswordManager(
83 content::WebContents* contents,
84 PasswordManager* password_manager);
86 // Returns true if the one-click signin feature can be offered at this time.
87 // If |email| is not empty, then the profile is checked to see if it's
88 // already connected to a google account or if the user has already rejected
89 // one-click sign-in with this email, in which cases a one click signin
90 // should not be offered.
92 // If |can_offer_for| is |CAN_OFFER_FOR_INTERSTITAL_ONLY|, then only do the
93 // checks that would affect the interstitial page. Otherwise, do the checks
94 // that would affect the interstitial and the explicit sign ins.
96 // Returns in |error_message_id| an explanation as a string resource ID for
97 // why one-clicked cannot be offered. |error_message_id| is valid only if
98 // the return value is false. If no explanation is needed, |error_message_id|
99 // may be null.
100 static bool CanOffer(content::WebContents* web_contents,
101 CanOfferFor can_offer_for,
102 const std::string& email,
103 std::string* error_message);
105 // Returns true if the one-click signin feature can be offered at this time.
106 // It can be offered if the io_data is not in an incognito window and if the
107 // origin of |url| is a valid Gaia sign in origin. This function is meant
108 // to called only from the IO thread.
109 static Offer CanOfferOnIOThread(net::URLRequest* request,
110 ProfileIOData* io_data);
112 // Looks for the Google-Accounts-SignIn response header, and if found,
113 // tries to display an infobar in the tab contents identified by the
114 // child/route id.
115 static void ShowInfoBarIfPossible(net::URLRequest* request,
116 ProfileIOData* io_data,
117 int child_id,
118 int route_id);
120 // Remove the item currently at the top of the history list if it's
121 // the Gaia redirect URL. Due to limitations of the NavigationController
122 // this cannot be done until a new page becomes "current".
123 static void RemoveSigninRedirectURLHistoryItem(
124 content::WebContents* web_contents);
126 static void LogConfirmHistogramValue(int action);
128 private:
129 friend class content::WebContentsUserData<OneClickSigninHelper>;
130 friend class OneClickSigninHelperTest;
131 FRIEND_TEST_ALL_PREFIXES(OneClickSigninHelperIncognitoTest,
132 ShowInfoBarUIThreadIncognito);
133 FRIEND_TEST_ALL_PREFIXES(OneClickSigninHelperTest,
134 SigninFromWebstoreWithConfigSyncfirst);
135 FRIEND_TEST_ALL_PREFIXES(OneClickSigninHelperTest,
136 ShowSigninBubbleAfterSigninComplete);
137 FRIEND_TEST_ALL_PREFIXES(OneClickSigninHelperTest, SigninCancelled);
138 FRIEND_TEST_ALL_PREFIXES(OneClickSigninHelperTest, SigninFailed);
139 FRIEND_TEST_ALL_PREFIXES(OneClickSigninHelperTest,
140 CleanTransientStateOnNavigate);
141 FRIEND_TEST_ALL_PREFIXES(OneClickSigninHelperTest,
142 RemoveObserverFromProfileSyncService);
143 FRIEND_TEST_ALL_PREFIXES(OneClickSigninHelperIOTest, CanOfferOnIOThread);
144 FRIEND_TEST_ALL_PREFIXES(OneClickSigninHelperIOTest,
145 CanOfferOnIOThreadIncognito);
146 FRIEND_TEST_ALL_PREFIXES(OneClickSigninHelperIOTest,
147 CanOfferOnIOThreadNoIOData);
148 FRIEND_TEST_ALL_PREFIXES(OneClickSigninHelperIOTest,
149 CanOfferOnIOThreadBadURL);
150 FRIEND_TEST_ALL_PREFIXES(OneClickSigninHelperIOTest,
151 CanOfferOnIOThreadReferrer);
152 FRIEND_TEST_ALL_PREFIXES(OneClickSigninHelperIOTest,
153 CanOfferOnIOThreadDisabled);
154 FRIEND_TEST_ALL_PREFIXES(OneClickSigninHelperIOTest,
155 CanOfferOnIOThreadSignedIn);
156 FRIEND_TEST_ALL_PREFIXES(OneClickSigninHelperIOTest,
157 CanOfferOnIOThreadEmailNotAllowed);
158 FRIEND_TEST_ALL_PREFIXES(OneClickSigninHelperIOTest,
159 CanOfferOnIOThreadEmailAlreadyUsed);
160 FRIEND_TEST_ALL_PREFIXES(OneClickSigninHelperIOTest,
161 CreateTestProfileIOData);
162 FRIEND_TEST_ALL_PREFIXES(OneClickSigninHelperIOTest,
163 CanOfferOnIOThreadWithRejectedEmail);
164 FRIEND_TEST_ALL_PREFIXES(OneClickSigninHelperIOTest,
165 CanOfferOnIOThreadNoSigninCookies);
166 FRIEND_TEST_ALL_PREFIXES(OneClickSigninHelperIOTest,
167 CanOfferOnIOThreadDisabledByPolicy);
169 // Maximum number of navigations away from the set of valid Gaia URLs before
170 // clearing the internal state of the helper. This is necessary to support
171 // SAML-based accounts, but causes bug crbug.com/181163.
172 static const int kMaxNavigationsSince;
174 OneClickSigninHelper(content::WebContents* web_contents,
175 PasswordManager* password_manager);
177 virtual ~OneClickSigninHelper();
179 // Returns true if the one-click signin feature can be offered at this time.
180 // It can be offered if the io_data is not in an incognito window and if the
181 // origin of |url| is a valid Gaia sign in origin. This function is meant
182 // to called only from the IO thread.
183 static Offer CanOfferOnIOThreadImpl(const GURL& url,
184 const std::string& referrer,
185 base::SupportsUserData* request,
186 ProfileIOData* io_data);
188 // The portion of ShowInfoBarIfPossible() that needs to run on the UI thread.
189 // |session_index| and |email| are extracted from the Google-Accounts-SignIn
190 // header. |auto_accept| is extracted from the Google-Chrome-SignIn header.
191 // |source| is used to determine which of the explicit sign in mechanism is
192 // being used.
194 // |continue_url| is where Gaia will continue to when the sign in process is
195 // done. For explicit sign ins, this is a URL chrome controls. For one-click
196 // sign in, this could be any google property. This URL is used to know
197 // when the sign process is over and to collect infomation from the user
198 // entered on the Gaia sign in page (for explicit sign ins).
199 static void ShowInfoBarUIThread(const std::string& session_index,
200 const std::string& email,
201 AutoAccept auto_accept,
202 signin::Source source,
203 const GURL& continue_url,
204 int child_id,
205 int route_id);
207 void RedirectToSignin();
208 void ShowSigninErrorBubble(Browser* browser, const std::string& error);
210 // Clear all data member of the helper, except for the error.
211 void CleanTransientState();
213 // Unitests that use a TestingProfile should call this.
214 // Otherwise, clearing the pending e-mail crashes because the code expects
215 // a real ResourceContext rather than the MockResourceContext a
216 // TestingProfile provides.
217 void SetDoNotClearPendingEmailForTesting();
219 // Called when password has been submitted.
220 void PasswordSubmitted(const content::PasswordForm& form);
222 // content::WebContentsObserver overrides.
223 virtual void NavigateToPendingEntry(
224 const GURL& url,
225 content::NavigationController::ReloadType reload_type) OVERRIDE;
226 virtual void DidNavigateMainFrame(
227 const content::LoadCommittedDetails& details,
228 const content::FrameNavigateParams& params) OVERRIDE;
229 virtual void DidStopLoading(
230 content::RenderViewHost* render_view_host) OVERRIDE;
231 virtual void WebContentsDestroyed(content::WebContents* contents) OVERRIDE;
233 // ProfileSyncServiceObserver.
234 virtual void OnStateChanged() OVERRIDE;
236 OneClickSigninSyncStarter::Callback CreateSyncStarterCallback();
238 // Callback invoked when OneClickSigninSyncStarter completes sync setup.
239 void SyncSetupCompletedCallback(
240 OneClickSigninSyncStarter::SyncSetupResult result);
242 // Tracks if we are in the process of showing the signin or one click
243 // interstitial page. It's set to true the first time we load one of those
244 // pages and set to false when transient state is cleaned.
245 // Note: This should only be used for logging purposes.
246 bool showing_signin_;
248 // Information about the account that has just logged in.
249 std::string session_index_;
250 std::string email_;
251 std::string password_;
252 AutoAccept auto_accept_;
253 signin::Source source_;
254 bool switched_to_advanced_;
255 GURL continue_url_;
256 // The orignal continue URL after sync setup is complete.
257 GURL original_continue_url_;
258 std::string error_message_;
260 // Number of navigations since starting a sign in that is outside the
261 // the set of trusted Gaia URLs. Sign in attempts that include visits to
262 // one more untrusted will cause a modal dialog to appear asking the user
263 // to confirm, similar to the interstitial flow.
264 int untrusted_navigations_since_signin_visit_;
266 // Whether a Gaia URL during the sign in process was not handled by the
267 // dedicated sign in process (e.g. SAML login, which redirects to a
268 // non-google-controlled domain).
269 // This is set to true if at least one such URL is detected.
270 bool untrusted_confirmation_required_;
272 // Allows unittests to avoid accessing the ResourceContext for clearing a
273 // pending e-mail.
274 bool do_not_clear_pending_email_;
276 base::WeakPtrFactory<OneClickSigninHelper> weak_pointer_factory_;
278 DISALLOW_COPY_AND_ASSIGN(OneClickSigninHelper);
281 #endif // CHROME_BROWSER_UI_SYNC_ONE_CLICK_SIGNIN_HELPER_H_