Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / sync / one_click_signin_sync_observer.cc
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): Redirecting after Sync is set up still has some bugs:
85       // http://crbug.com/355885
86       //   Having multiple settings pages open can cause issues.
87       // http://crbug.com/357901
88       //   Selecting anything other than "Sync Everything" when configuring Sync
89       //   prevents the redirect.
90       LoadContinueUrl();
91     }
92   }
93
94   sync_service->RemoveObserver(this);
95   delete this;
96 }
97
98 void OneClickSigninSyncObserver::LoadContinueUrl() {
99   web_contents()->GetController().LoadURL(
100       continue_url_,
101       content::Referrer(),
102       content::PAGE_TRANSITION_AUTO_TOPLEVEL,
103       std::string());
104 }
105
106 ProfileSyncService* OneClickSigninSyncObserver::GetSyncService(
107     content::WebContents* web_contents) {
108   Profile* profile =
109       Profile::FromBrowserContext(web_contents->GetBrowserContext());
110   return ProfileSyncServiceFactory::GetForProfile(profile);
111 }
112
113 // static
114 void OneClickSigninSyncObserver::DeleteObserver(
115     base::WeakPtr<OneClickSigninSyncObserver> observer) {
116   if (observer)
117     delete observer.get();
118 }