Home | History | Annotate | Download | only in sync
      1 // Copyright 2014 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.
      4 
      5 #include "chrome/browser/ui/sync/one_click_signin_sync_observer.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/message_loop/message_loop.h"
      9 #include "chrome/browser/profiles/profile.h"
     10 #include "chrome/browser/signin/signin_promo.h"
     11 #include "chrome/browser/sync/profile_sync_service.h"
     12 #include "chrome/browser/sync/profile_sync_service_factory.h"
     13 #include "content/public/browser/web_contents.h"
     14 #include "content/public/browser/web_contents_delegate.h"
     15 
     16 namespace {
     17 
     18 void CloseTab(content::WebContents* tab) {
     19   content::WebContentsDelegate* tab_delegate = tab->GetDelegate();
     20   if (tab_delegate)
     21     tab_delegate->CloseContents(tab);
     22 }
     23 
     24 }  // namespace
     25 
     26 
     27 OneClickSigninSyncObserver::OneClickSigninSyncObserver(
     28     content::WebContents* web_contents,
     29     const GURL& continue_url)
     30     : content::WebContentsObserver(web_contents),
     31       continue_url_(continue_url),
     32       weak_ptr_factory_(this) {
     33   DCHECK(!continue_url_.is_empty());
     34 
     35   ProfileSyncService* sync_service = GetSyncService(web_contents);
     36   if (sync_service) {
     37     sync_service->AddObserver(this);
     38   } else {
     39     LoadContinueUrl();
     40     // Post a task rather than calling |delete this| here, so that the
     41     // destructor is not called directly from the constructor. Note that it's
     42     // important to pass a weak pointer rather than base::Unretained(this)
     43     // because it's possible for e.g. WebContentsDestroyed() to be called
     44     // before this task has a chance to run.
     45     base::MessageLoop::current()->PostTask(
     46         FROM_HERE,
     47         base::Bind(&OneClickSigninSyncObserver::DeleteObserver,
     48                    weak_ptr_factory_.GetWeakPtr()));
     49   }
     50 }
     51 
     52 OneClickSigninSyncObserver::~OneClickSigninSyncObserver() {}
     53 
     54 void OneClickSigninSyncObserver::WebContentsDestroyed() {
     55   ProfileSyncService* sync_service = GetSyncService(web_contents());
     56   if (sync_service)
     57     sync_service->RemoveObserver(this);
     58 
     59   delete this;
     60 }
     61 
     62 void OneClickSigninSyncObserver::OnStateChanged() {
     63   ProfileSyncService* sync_service = GetSyncService(web_contents());
     64 
     65   // At this point, the sign-in process is complete, and control has been handed
     66   // back to the sync engine. Close the gaia sign in tab if the |continue_url_|
     67   // contains the |auto_close| parameter. Otherwise, wait for sync setup to
     68   // complete and then navigate to the |continue_url_|.
     69   if (signin::IsAutoCloseEnabledInURL(continue_url_)) {
     70     // Close the Gaia sign-in tab via a task to make sure we aren't in the
     71     // middle of any WebUI handler code.
     72     base::MessageLoop::current()->PostTask(
     73         FROM_HERE,
     74         base::Bind(&CloseTab, base::Unretained(web_contents())));
     75   } else {
     76     if (sync_service->FirstSetupInProgress()) {
     77       // Sync setup has not completed yet. Wait for it to complete.
     78       return;
     79     }
     80 
     81     if (sync_service->sync_initialized() &&
     82         signin::GetSourceForPromoURL(continue_url_)
     83             != signin::SOURCE_SETTINGS) {
     84       // TODO(isherman): Having multiple settings pages open can cause issues
     85       // redirecting after Sync is set up: http://crbug.com/355885
     86       LoadContinueUrl();
     87     }
     88   }
     89 
     90   sync_service->RemoveObserver(this);
     91   delete this;
     92 }
     93 
     94 void OneClickSigninSyncObserver::LoadContinueUrl() {
     95   web_contents()->GetController().LoadURL(
     96       continue_url_,
     97       content::Referrer(),
     98       content::PAGE_TRANSITION_AUTO_TOPLEVEL,
     99       std::string());
    100 }
    101 
    102 ProfileSyncService* OneClickSigninSyncObserver::GetSyncService(
    103     content::WebContents* web_contents) {
    104   Profile* profile =
    105       Profile::FromBrowserContext(web_contents->GetBrowserContext());
    106   return ProfileSyncServiceFactory::GetForProfile(profile);
    107 }
    108 
    109 // static
    110 void OneClickSigninSyncObserver::DeleteObserver(
    111     base::WeakPtr<OneClickSigninSyncObserver> observer) {
    112   if (observer)
    113     delete observer.get();
    114 }
    115