#include "chrome/browser/signin/signin_promo.h"
#include "chrome/browser/sync/profile_sync_service_observer.h"
#include "chrome/browser/ui/sync/one_click_signin_sync_starter.h"
+#include "components/signin/core/browser/signin_oauth_helper.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/browser/web_contents_user_data.h"
class Browser;
class GURL;
-class PasswordManager;
class ProfileIOData;
namespace autofill {
class URLRequest;
}
+namespace password_manager {
+class PasswordManager;
+}
+
// Per-tab one-click signin helper. When a user signs in to a Google service
// and the profile is not yet connected to a Google account, will start the
// process of helping the user connect his profile with one click. The process
// more about what this means.
class OneClickSigninHelper
: public content::WebContentsObserver,
- public content::WebContentsUserData<OneClickSigninHelper>,
- public ProfileSyncServiceObserver {
+ public content::WebContentsUserData<OneClickSigninHelper> {
public:
// Represents user's decision about sign in process.
enum AutoAccept {
// Argument to CanOffer().
enum CanOfferFor {
CAN_OFFER_FOR_ALL,
- CAN_OFFER_FOR_INTERSTITAL_ONLY
+ CAN_OFFER_FOR_INTERSTITAL_ONLY,
+ CAN_OFFER_FOR_SECONDARY_ACCOUNT
+ // TODO(guohui): needs to handle adding secondary account through
+ // interstitial.
};
+ // Arguments used with StartSync function. base::Bind() cannot support too
+ // many args for performance reasons, so they are packaged up into a struct.
+ struct StartSyncArgs {
+ // Default contructor for testing only.
+ StartSyncArgs();
+ StartSyncArgs(Profile* profile,
+ Browser* browser,
+ OneClickSigninHelper::AutoAccept auto_accept,
+ const std::string& session_index,
+ const std::string& email,
+ const std::string& password,
+ const std::string& refresh_token,
+ content::WebContents* web_contents,
+ bool untrusted_confirmation_required,
+ signin::Source source,
+ OneClickSigninSyncStarter::Callback callback);
+ ~StartSyncArgs();
+
+ Profile* profile;
+ Browser* browser;
+ OneClickSigninHelper::AutoAccept auto_accept;
+ std::string session_index;
+ std::string email;
+ std::string password;
+ std::string refresh_token;
+
+ // Web contents in which the sync setup page should be displayed,
+ // if necessary. Can be NULL.
+ content::WebContents* web_contents;
+
+ OneClickSigninSyncStarter::ConfirmationRequired confirmation_required;
+ signin::Source source;
+ OneClickSigninSyncStarter::Callback callback;
+ };
+
+ // Wrapper to call OneClickSigninSyncStarter after fetching the refresh token
+ // if needed. Also verifies that the cookies are correct if no password is
+ // specified, and checks that the email from the cookies match the expected
+ // email address.
+ class SyncStarterWrapper : public SigninOAuthHelper::Consumer,
+ public chrome::BrowserListObserver {
+ public:
+ SyncStarterWrapper(
+ const OneClickSigninHelper::StartSyncArgs& args,
+ OneClickSigninSyncStarter::StartSyncMode start_mode);
+ virtual ~SyncStarterWrapper();
+
+ void Start();
+
+ private:
+ void VerifyGaiaCookiesBeforeSignIn();
+ void OnGaiaCookiesFetched(const std::string session_index,
+ const net::CookieList& cookie_list);
+
+ // Virtual to be overridden in tests.
+ virtual void DisplayErrorBubble(const std::string& error_message);
+ virtual void StartSigninOAuthHelper();
+ virtual void StartOneClickSigninSyncStarter(
+ const std::string& email,
+ const std::string& refresh_token);
+
+ // Overriden from SigninOAuthHelper::Consumer.
+ virtual void OnSigninOAuthInformationAvailable(
+ const std::string& email,
+ const std::string& display_email,
+ const std::string& refresh_token) OVERRIDE;
+ virtual void OnSigninOAuthInformationFailure(
+ const GoogleServiceAuthError& error) OVERRIDE;
+
+ // Overriden from chrome::BrowserListObserver.
+ virtual void OnBrowserRemoved(Browser* browser) OVERRIDE;
+
+ OneClickSigninHelper::StartSyncArgs args_;
+ chrome::HostDesktopType desktop_type_;
+ OneClickSigninSyncStarter::StartSyncMode start_mode_;
+ scoped_ptr<SigninOAuthHelper> signin_oauth_helper_;
+ base::WeakPtrFactory<SyncStarterWrapper> weak_pointer_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(SyncStarterWrapper);
+ };
+
+ static void LogHistogramValue(signin::Source source, int action);
+
static void CreateForWebContentsWithPasswordManager(
content::WebContents* contents,
- PasswordManager* password_manager);
+ password_manager::PasswordManager* password_manager);
// Returns true if the one-click signin feature can be offered at this time.
// If |email| is not empty, then the profile is checked to see if it's
int child_id,
int route_id);
+ // Handles cross account sign in error. If the supplied |email| does not match
+ // the last signed in email of the current profile, then Chrome will show a
+ // confirmation dialog before starting sync. It returns true if there is a
+ // cross account error, and false otherwise.
+ static bool HandleCrossAccountError(
+ Profile* profile,
+ const std::string& session_index,
+ const std::string& email,
+ const std::string& password,
+ const std::string& refresh_token,
+ OneClickSigninHelper::AutoAccept auto_accept,
+ signin::Source source,
+ OneClickSigninSyncStarter::StartSyncMode start_mode,
+ OneClickSigninSyncStarter::Callback sync_callback);
+
+ static void RedirectToNtpOrAppsPage(
+ content::WebContents* contents, signin::Source source);
+
+ // If the |source| is not settings page/webstore, redirects to
+ // the NTP/Apps page.
+ static void RedirectToNtpOrAppsPageIfNecessary(
+ content::WebContents* contents, signin::Source source);
+
// Remove the item currently at the top of the history list if it's
// the Gaia redirect URL. Due to limitations of the NavigationController
// this cannot be done until a new page becomes "current".
FRIEND_TEST_ALL_PREFIXES(OneClickSigninHelperTest, SigninFailed);
FRIEND_TEST_ALL_PREFIXES(OneClickSigninHelperTest,
CleanTransientStateOnNavigate);
- FRIEND_TEST_ALL_PREFIXES(OneClickSigninHelperTest,
- RemoveObserverFromProfileSyncService);
FRIEND_TEST_ALL_PREFIXES(OneClickSigninHelperIOTest, CanOfferOnIOThread);
FRIEND_TEST_ALL_PREFIXES(OneClickSigninHelperIOTest,
CanOfferOnIOThreadIncognito);
FRIEND_TEST_ALL_PREFIXES(OneClickSigninHelperIOTest,
CanOfferOnIOThreadBadURL);
FRIEND_TEST_ALL_PREFIXES(OneClickSigninHelperIOTest,
- CanOfferOnIOThreadReferrer);
- FRIEND_TEST_ALL_PREFIXES(OneClickSigninHelperIOTest,
CanOfferOnIOThreadDisabled);
FRIEND_TEST_ALL_PREFIXES(OneClickSigninHelperIOTest,
CanOfferOnIOThreadSignedIn);
static const int kMaxNavigationsSince;
OneClickSigninHelper(content::WebContents* web_contents,
- PasswordManager* password_manager);
+ password_manager::PasswordManager* password_manager);
virtual ~OneClickSigninHelper();
// origin of |url| is a valid Gaia sign in origin. This function is meant
// to called only from the IO thread.
static Offer CanOfferOnIOThreadImpl(const GURL& url,
- const std::string& referrer,
base::SupportsUserData* request,
ProfileIOData* io_data);
int route_id);
void RedirectToSignin();
- void ShowSigninErrorBubble(Browser* browser, const std::string& error);
// Clear all data member of the helper, except for the error.
void CleanTransientState();
void PasswordSubmitted(const autofill::PasswordForm& form);
// content::WebContentsObserver overrides.
- virtual void NavigateToPendingEntry(
+ virtual void DidStartNavigationToPendingEntry(
const GURL& url,
content::NavigationController::ReloadType reload_type) OVERRIDE;
virtual void DidNavigateMainFrame(
const content::FrameNavigateParams& params) OVERRIDE;
virtual void DidStopLoading(
content::RenderViewHost* render_view_host) OVERRIDE;
- virtual void WebContentsDestroyed(content::WebContents* contents) OVERRIDE;
-
- // ProfileSyncServiceObserver.
- virtual void OnStateChanged() OVERRIDE;
OneClickSigninSyncStarter::Callback CreateSyncStarterCallback();