- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / auto_login_infobar_delegate.cc
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.
4
5 #include "chrome/browser/ui/auto_login_infobar_delegate.h"
6
7 #include "base/bind.h"
8 #include "base/logging.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/metrics/histogram.h"
11 #include "base/prefs/pref_service.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "chrome/browser/browser_process.h"
14 #include "chrome/browser/chrome_notification_types.h"
15 #include "chrome/browser/google/google_util.h"
16 #include "chrome/browser/infobars/infobar_service.h"
17 #include "chrome/browser/profiles/profile.h"
18 #include "chrome/browser/signin/ubertoken_fetcher.h"
19 #include "chrome/browser/ui/sync/sync_promo_ui.h"
20 #include "chrome/common/chrome_switches.h"
21 #include "chrome/common/pref_names.h"
22 #include "chrome/common/url_constants.h"
23 #include "content/public/browser/navigation_controller.h"
24 #include "content/public/browser/notification_details.h"
25 #include "content/public/browser/notification_observer.h"
26 #include "content/public/browser/notification_registrar.h"
27 #include "content/public/browser/notification_source.h"
28 #include "content/public/browser/notification_types.h"
29 #include "content/public/browser/page_navigator.h"
30 #include "content/public/browser/web_contents.h"
31 #include "content/public/browser/web_contents_observer.h"
32 #include "content/public/common/referrer.h"
33 #include "google_apis/gaia/gaia_constants.h"
34 #include "google_apis/gaia/gaia_urls.h"
35 #include "grit/chromium_strings.h"
36 #include "grit/generated_resources.h"
37 #include "grit/theme_resources.h"
38 #include "net/base/escape.h"
39 #include "net/url_request/url_request.h"
40 #include "ui/base/l10n/l10n_util.h"
41
42 #if defined(OS_ANDROID)
43 #include "chrome/browser/ui/android/infobars/auto_login_infobar_delegate_android.h"
44 #endif
45
46
47 // AutoLoginRedirector --------------------------------------------------------
48
49 namespace {
50
51 // This class is created by the AutoLoginInfoBarDelegate when the user wishes to
52 // auto-login.  It holds context information needed while re-issuing service
53 // tokens using the TokenService, gets the browser cookies with the TokenAuth
54 // API, and finally redirects the user to the correct page.
55 class AutoLoginRedirector : public UbertokenConsumer,
56                             public content::WebContentsObserver {
57  public:
58   AutoLoginRedirector(content::WebContents* web_contents,
59                       const std::string& args);
60   virtual ~AutoLoginRedirector();
61
62  private:
63   // Overriden from UbertokenConsumer:
64   virtual void OnUbertokenSuccess(const std::string& token) OVERRIDE;
65   virtual void OnUbertokenFailure(const GoogleServiceAuthError& error) OVERRIDE;
66
67   // Implementation of content::WebContentsObserver
68   virtual void WebContentsDestroyed(
69       content::WebContents* web_contents) OVERRIDE;
70
71   // Redirect tab to MergeSession URL, logging the user in and navigating
72   // to the desired page.
73   void RedirectToMergeSession(const std::string& token);
74
75   const std::string args_;
76   scoped_ptr<UbertokenFetcher> ubertoken_fetcher_;
77
78   DISALLOW_COPY_AND_ASSIGN(AutoLoginRedirector);
79 };
80
81 AutoLoginRedirector::AutoLoginRedirector(
82     content::WebContents* web_contents,
83     const std::string& args)
84     : content::WebContentsObserver(web_contents),
85       args_(args) {
86   ubertoken_fetcher_.reset(new UbertokenFetcher(
87       Profile::FromBrowserContext(web_contents->GetBrowserContext()), this));
88   ubertoken_fetcher_->StartFetchingToken();
89 }
90
91 AutoLoginRedirector::~AutoLoginRedirector() {
92 }
93
94 void AutoLoginRedirector::WebContentsDestroyed(
95     content::WebContents* web_contents) {
96   // The WebContents that started this has been destroyed. The request must be
97   // cancelled and this object must be deleted.
98   ubertoken_fetcher_.reset();
99   base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
100 }
101
102 void AutoLoginRedirector::OnUbertokenSuccess(const std::string& token) {
103   RedirectToMergeSession(token);
104   base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
105 }
106
107 void AutoLoginRedirector::OnUbertokenFailure(
108     const GoogleServiceAuthError& error) {
109   LOG(WARNING) << "AutoLoginRedirector: token request failed";
110   base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
111 }
112
113 void AutoLoginRedirector::RedirectToMergeSession(const std::string& token) {
114   // TODO(rogerta): what is the correct page transition?
115   web_contents()->GetController().LoadURL(
116       GaiaUrls::GetInstance()->merge_session_url().Resolve(
117           "?source=chrome&uberauth=" + token + "&" + args_),
118       content::Referrer(), content::PAGE_TRANSITION_AUTO_BOOKMARK,
119       std::string());
120 }
121
122 }  // namespace
123
124
125 // AutoLoginInfoBarDelegate ---------------------------------------------------
126
127 // static
128 void AutoLoginInfoBarDelegate::Create(InfoBarService* infobar_service,
129                                       const Params& params) {
130   infobar_service->AddInfoBar(scoped_ptr<InfoBarDelegate>(
131 #if defined(OS_ANDROID)
132       new AutoLoginInfoBarDelegateAndroid(infobar_service, params)
133 #else
134       new AutoLoginInfoBarDelegate(infobar_service, params)
135 #endif
136       ));
137 }
138
139 AutoLoginInfoBarDelegate::AutoLoginInfoBarDelegate(
140     InfoBarService* owner,
141     const Params& params)
142     : ConfirmInfoBarDelegate(owner),
143       params_(params),
144       button_pressed_(false) {
145   RecordHistogramAction(SHOWN);
146   registrar_.Add(this, chrome::NOTIFICATION_GOOGLE_SIGNED_OUT,
147                  content::Source<Profile>(Profile::FromBrowserContext(
148                      web_contents()->GetBrowserContext())));
149 }
150
151 AutoLoginInfoBarDelegate::~AutoLoginInfoBarDelegate() {
152   if (!button_pressed_)
153     RecordHistogramAction(IGNORED);
154 }
155
156 void AutoLoginInfoBarDelegate::InfoBarDismissed() {
157   RecordHistogramAction(DISMISSED);
158   button_pressed_ = true;
159 }
160
161 int AutoLoginInfoBarDelegate::GetIconID() const {
162   return IDR_INFOBAR_AUTOLOGIN;
163 }
164
165 InfoBarDelegate::Type AutoLoginInfoBarDelegate::GetInfoBarType() const {
166   return PAGE_ACTION_TYPE;
167 }
168
169 AutoLoginInfoBarDelegate*
170     AutoLoginInfoBarDelegate::AsAutoLoginInfoBarDelegate() {
171   return this;
172 }
173
174 string16 AutoLoginInfoBarDelegate::GetMessageText() const {
175   return l10n_util::GetStringFUTF16(IDS_AUTOLOGIN_INFOBAR_MESSAGE,
176                                     UTF8ToUTF16(params_.username));
177 }
178
179 string16 AutoLoginInfoBarDelegate::GetButtonLabel(
180     InfoBarButton button) const {
181   return l10n_util::GetStringUTF16((button == BUTTON_OK) ?
182       IDS_AUTOLOGIN_INFOBAR_OK_BUTTON : IDS_AUTOLOGIN_INFOBAR_CANCEL_BUTTON);
183 }
184
185 bool AutoLoginInfoBarDelegate::Accept() {
186   // AutoLoginRedirector deletes itself.
187   new AutoLoginRedirector(web_contents(), params_.header.args);
188   RecordHistogramAction(ACCEPTED);
189   button_pressed_ = true;
190   return true;
191 }
192
193 bool AutoLoginInfoBarDelegate::Cancel() {
194   PrefService* pref_service = Profile::FromBrowserContext(
195       web_contents()->GetBrowserContext())->GetPrefs();
196   pref_service->SetBoolean(prefs::kAutologinEnabled, false);
197   RecordHistogramAction(REJECTED);
198   button_pressed_ = true;
199   return true;
200 }
201
202 void AutoLoginInfoBarDelegate::Observe(
203     int type,
204     const content::NotificationSource& source,
205     const content::NotificationDetails& details) {
206   DCHECK_EQ(chrome::NOTIFICATION_GOOGLE_SIGNED_OUT, type);
207   // owner() can be NULL when InfoBarService removes us. See
208   // |InfoBarDelegate::clear_owner|.
209   if (owner())
210     owner()->RemoveInfoBar(this);
211 }
212
213 void AutoLoginInfoBarDelegate::RecordHistogramAction(Actions action) {
214   UMA_HISTOGRAM_ENUMERATION("AutoLogin.Regular", action,
215                             HISTOGRAM_BOUNDING_VALUE);
216 }