OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/ui/auto_login_infobar_delegate.h" | 5 #include "chrome/browser/ui/android/infobars/auto_login_infobar_delegate.h" |
6 | 6 |
| 7 #include "base/android/jni_android.h" |
| 8 #include "base/android/jni_helper.h" |
| 9 #include "base/android/jni_string.h" |
7 #include "base/bind.h" | 10 #include "base/bind.h" |
8 #include "base/logging.h" | 11 #include "base/logging.h" |
9 #include "base/message_loop/message_loop.h" | 12 #include "base/message_loop/message_loop.h" |
10 #include "base/metrics/histogram.h" | 13 #include "base/metrics/histogram.h" |
11 #include "base/prefs/pref_service.h" | 14 #include "base/prefs/pref_service.h" |
12 #include "base/strings/utf_string_conversions.h" | 15 #include "base/strings/utf_string_conversions.h" |
13 #include "chrome/browser/browser_process.h" | 16 #include "chrome/browser/browser_process.h" |
14 #include "chrome/browser/google/google_util.h" | 17 #include "chrome/browser/google/google_util.h" |
15 #include "chrome/browser/infobars/infobar.h" | 18 #include "chrome/browser/infobars/infobar.h" |
16 #include "chrome/browser/infobars/infobar_service.h" | 19 #include "chrome/browser/infobars/infobar_service.h" |
| 20 #include "chrome/browser/infobars/simple_alert_infobar_delegate.h" |
17 #include "chrome/browser/profiles/profile.h" | 21 #include "chrome/browser/profiles/profile.h" |
18 #include "chrome/browser/signin/profile_oauth2_token_service.h" | 22 #include "chrome/browser/signin/profile_oauth2_token_service.h" |
19 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" | 23 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" |
20 #include "chrome/browser/signin/signin_manager_factory.h" | 24 #include "chrome/browser/signin/signin_manager_factory.h" |
21 #include "chrome/browser/ui/sync/sync_promo_ui.h" | 25 #include "chrome/browser/ui/sync/sync_promo_ui.h" |
22 #include "chrome/common/chrome_switches.h" | 26 #include "chrome/common/chrome_switches.h" |
23 #include "chrome/common/pref_names.h" | 27 #include "chrome/common/pref_names.h" |
24 #include "chrome/common/url_constants.h" | 28 #include "chrome/common/url_constants.h" |
25 #include "content/public/browser/navigation_controller.h" | 29 #include "content/public/browser/navigation_controller.h" |
26 #include "content/public/browser/page_navigator.h" | 30 #include "content/public/browser/page_navigator.h" |
27 #include "content/public/browser/web_contents.h" | 31 #include "content/public/browser/web_contents.h" |
28 #include "content/public/browser/web_contents_observer.h" | 32 #include "content/public/browser/web_contents_observer.h" |
29 #include "content/public/common/referrer.h" | 33 #include "content/public/common/referrer.h" |
30 #include "google_apis/gaia/gaia_constants.h" | 34 #include "google_apis/gaia/gaia_constants.h" |
31 #include "google_apis/gaia/gaia_urls.h" | 35 #include "google_apis/gaia/gaia_urls.h" |
32 #include "google_apis/gaia/ubertoken_fetcher.h" | 36 #include "google_apis/gaia/ubertoken_fetcher.h" |
33 #include "grit/chromium_strings.h" | 37 #include "grit/chromium_strings.h" |
34 #include "grit/generated_resources.h" | 38 #include "grit/generated_resources.h" |
35 #include "grit/theme_resources.h" | 39 #include "grit/theme_resources.h" |
| 40 #include "jni/AutoLoginDelegate_jni.h" |
36 #include "net/base/escape.h" | 41 #include "net/base/escape.h" |
37 #include "net/url_request/url_request.h" | 42 #include "net/url_request/url_request.h" |
38 #include "ui/base/l10n/l10n_util.h" | 43 #include "ui/base/l10n/l10n_util.h" |
39 | 44 |
40 #if defined(OS_ANDROID) | 45 using base::android::ConvertUTF8ToJavaString; |
41 #include "chrome/browser/ui/android/infobars/auto_login_infobar_delegate_android
.h" | 46 using base::android::ScopedJavaLocalRef; |
42 #endif | |
43 | 47 |
44 | 48 |
45 // AutoLoginRedirector -------------------------------------------------------- | 49 // AutoLoginRedirector -------------------------------------------------------- |
46 | 50 |
47 namespace { | 51 namespace { |
48 | 52 |
49 // This class is created by the AutoLoginInfoBarDelegate when the user wishes to | 53 // This class is created by the AutoLoginInfoBarDelegate when the user wishes to |
50 // auto-login. It holds context information needed while re-issuing service | 54 // auto-login. It holds context information needed while re-issuing service |
51 // tokens using the OAuth2TokenService, gets the browser cookies with the | 55 // tokens using the OAuth2TokenService, gets the browser cookies with the |
52 // TokenAuth API, and finally redirects the user to the correct page. | 56 // TokenAuth API, and finally redirects the user to the correct page. |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
135 const Params& params) { | 139 const Params& params) { |
136 // If |web_contents| is hosted in a WebDialog, there may be no infobar | 140 // If |web_contents| is hosted in a WebDialog, there may be no infobar |
137 // service. | 141 // service. |
138 InfoBarService* infobar_service = | 142 InfoBarService* infobar_service = |
139 InfoBarService::FromWebContents(web_contents); | 143 InfoBarService::FromWebContents(web_contents); |
140 if (!infobar_service) | 144 if (!infobar_service) |
141 return false; | 145 return false; |
142 | 146 |
143 Profile* profile = | 147 Profile* profile = |
144 Profile::FromBrowserContext(web_contents->GetBrowserContext()); | 148 Profile::FromBrowserContext(web_contents->GetBrowserContext()); |
145 #if defined(OS_ANDROID) | |
146 typedef AutoLoginInfoBarDelegateAndroid Delegate; | |
147 #else | |
148 typedef AutoLoginInfoBarDelegate Delegate; | |
149 #endif | |
150 return !!infobar_service->AddInfoBar(ConfirmInfoBarDelegate::CreateInfoBar( | 149 return !!infobar_service->AddInfoBar(ConfirmInfoBarDelegate::CreateInfoBar( |
151 scoped_ptr<ConfirmInfoBarDelegate>(new Delegate(params, profile)))); | 150 scoped_ptr<ConfirmInfoBarDelegate>( |
| 151 new AutoLoginInfoBarDelegate(params, profile)))); |
152 } | 152 } |
153 | 153 |
154 AutoLoginInfoBarDelegate::AutoLoginInfoBarDelegate(const Params& params, | 154 AutoLoginInfoBarDelegate::AutoLoginInfoBarDelegate(const Params& params, |
155 Profile* profile) | 155 Profile* profile) |
156 : ConfirmInfoBarDelegate(), | 156 : ConfirmInfoBarDelegate(), |
157 params_(params), | 157 params_(params), |
158 profile_(profile), | 158 profile_(profile), |
159 button_pressed_(false) { | 159 button_pressed_(false) { |
160 RecordHistogramAction(SHOWN); | 160 RecordHistogramAction(SHOWN); |
161 SigninManagerFactory::GetInstance()->GetForProfile(profile_)->AddObserver( | 161 SigninManagerFactory::GetInstance()->GetForProfile(profile_)->AddObserver( |
162 this); | 162 this); |
163 } | 163 } |
164 | 164 |
165 AutoLoginInfoBarDelegate::~AutoLoginInfoBarDelegate() { | 165 AutoLoginInfoBarDelegate::~AutoLoginInfoBarDelegate() { |
166 // The SigninManagerFactory is scoped to the lifetime of the app and the | 166 // The SigninManagerFactory is scoped to the lifetime of the app and the |
167 // SigninManager is scoped to the lifetime of the Profile, both of which are | 167 // SigninManager is scoped to the lifetime of the Profile, both of which are |
168 // longer than the lifetime of the WebContents that this object cannot | 168 // longer than the lifetime of the WebContents that this object cannot |
169 // outlive. Therefore, it's safe to call RemoveObserver() unconditionally. | 169 // outlive. Therefore, it's safe to call RemoveObserver() unconditionally. |
170 SigninManagerFactory::GetInstance()->GetForProfile(profile_)->RemoveObserver( | 170 SigninManagerFactory::GetInstance()->GetForProfile(profile_)->RemoveObserver( |
171 this); | 171 this); |
172 | 172 |
173 if (!button_pressed_) | 173 if (!button_pressed_) |
174 RecordHistogramAction(IGNORED); | 174 RecordHistogramAction(IGNORED); |
175 } | 175 } |
176 | 176 |
| 177 bool AutoLoginInfoBarDelegate::AttachAccount( |
| 178 JavaObjectWeakGlobalRef weak_java_auto_login_delegate) { |
| 179 weak_java_auto_login_delegate_ = weak_java_auto_login_delegate; |
| 180 JNIEnv* env = base::android::AttachCurrentThread(); |
| 181 ScopedJavaLocalRef<jstring> jrealm = ConvertUTF8ToJavaString(env, realm()); |
| 182 ScopedJavaLocalRef<jstring> jaccount = |
| 183 ConvertUTF8ToJavaString(env, account()); |
| 184 ScopedJavaLocalRef<jstring> jargs = ConvertUTF8ToJavaString(env, args()); |
| 185 DCHECK(!jrealm.is_null()); |
| 186 DCHECK(!jaccount.is_null()); |
| 187 DCHECK(!jargs.is_null()); |
| 188 |
| 189 ScopedJavaLocalRef<jobject> delegate = |
| 190 weak_java_auto_login_delegate_.get(env); |
| 191 DCHECK(delegate.obj()); |
| 192 user_ = base::android::ConvertJavaStringToUTF8( |
| 193 Java_AutoLoginDelegate_initializeAccount( |
| 194 env, delegate.obj(), reinterpret_cast<intptr_t>(this), jrealm.obj(), |
| 195 jaccount.obj(), jargs.obj())); |
| 196 return !user_.empty(); |
| 197 } |
| 198 |
| 199 void AutoLoginInfoBarDelegate::LoginSuccess(JNIEnv* env, |
| 200 jobject obj, |
| 201 jstring result) { |
| 202 if (!infobar()->owner()) |
| 203 return; // We're closing; don't call anything, it might access the owner. |
| 204 |
| 205 // TODO(miguelg): Test whether the Stop() and RemoveInfoBar() calls here are |
| 206 // necessary, or whether OpenURL() will do this for us. |
| 207 content::WebContents* contents = web_contents(); |
| 208 contents->Stop(); |
| 209 infobar()->RemoveSelf(); |
| 210 // WARNING: |this| may be deleted at this point! Do not access any members! |
| 211 contents->OpenURL(content::OpenURLParams( |
| 212 GURL(base::android::ConvertJavaStringToUTF8(env, result)), |
| 213 content::Referrer(), CURRENT_TAB, content::PAGE_TRANSITION_AUTO_BOOKMARK, |
| 214 false)); |
| 215 } |
| 216 |
| 217 void AutoLoginInfoBarDelegate::LoginFailed(JNIEnv* env, jobject obj) { |
| 218 if (!infobar()->owner()) |
| 219 return; // We're closing; don't call anything, it might access the owner. |
| 220 |
| 221 // TODO(miguelg): Using SimpleAlertInfoBarDelegate::Create() animates in a new |
| 222 // infobar while we animate the current one closed. It would be better to use |
| 223 // ReplaceInfoBar(). |
| 224 SimpleAlertInfoBarDelegate::Create( |
| 225 infobar()->owner(), IDR_INFOBAR_WARNING, |
| 226 l10n_util::GetStringUTF16(IDS_AUTO_LOGIN_FAILED), false); |
| 227 infobar()->RemoveSelf(); |
| 228 } |
| 229 |
| 230 void AutoLoginInfoBarDelegate::LoginDismiss(JNIEnv* env, jobject obj) { |
| 231 infobar()->RemoveSelf(); |
| 232 } |
| 233 |
| 234 bool AutoLoginInfoBarDelegate::Register(JNIEnv* env) { |
| 235 return RegisterNativesImpl(env); |
| 236 } |
| 237 |
177 void AutoLoginInfoBarDelegate::InfoBarDismissed() { | 238 void AutoLoginInfoBarDelegate::InfoBarDismissed() { |
178 RecordHistogramAction(DISMISSED); | 239 RecordHistogramAction(DISMISSED); |
179 button_pressed_ = true; | 240 button_pressed_ = true; |
180 } | 241 } |
181 | 242 |
182 int AutoLoginInfoBarDelegate::GetIconID() const { | 243 int AutoLoginInfoBarDelegate::GetIconID() const { |
183 return IDR_INFOBAR_AUTOLOGIN; | 244 return IDR_INFOBAR_AUTOLOGIN; |
184 } | 245 } |
185 | 246 |
186 InfoBarDelegate::Type AutoLoginInfoBarDelegate::GetInfoBarType() const { | 247 InfoBarDelegate::Type AutoLoginInfoBarDelegate::GetInfoBarType() const { |
187 return PAGE_ACTION_TYPE; | 248 return PAGE_ACTION_TYPE; |
188 } | 249 } |
189 | 250 |
190 AutoLoginInfoBarDelegate* | 251 AutoLoginInfoBarDelegate* |
191 AutoLoginInfoBarDelegate::AsAutoLoginInfoBarDelegate() { | 252 AutoLoginInfoBarDelegate::AsAutoLoginInfoBarDelegate() { |
192 return this; | 253 return this; |
193 } | 254 } |
194 | 255 |
195 base::string16 AutoLoginInfoBarDelegate::GetMessageText() const { | 256 base::string16 AutoLoginInfoBarDelegate::GetMessageText() const { |
196 return l10n_util::GetStringFUTF16(IDS_AUTOLOGIN_INFOBAR_MESSAGE, | 257 return l10n_util::GetStringFUTF16(IDS_AUTOLOGIN_INFOBAR_MESSAGE, |
197 base::UTF8ToUTF16(params_.username)); | 258 base::UTF8ToUTF16(user_)); |
198 } | 259 } |
199 | 260 |
200 base::string16 AutoLoginInfoBarDelegate::GetButtonLabel( | 261 base::string16 AutoLoginInfoBarDelegate::GetButtonLabel( |
201 InfoBarButton button) const { | 262 InfoBarButton button) const { |
202 return l10n_util::GetStringUTF16((button == BUTTON_OK) ? | 263 return l10n_util::GetStringUTF16((button == BUTTON_OK) ? |
203 IDS_AUTOLOGIN_INFOBAR_OK_BUTTON : IDS_AUTOLOGIN_INFOBAR_CANCEL_BUTTON); | 264 IDS_AUTOLOGIN_INFOBAR_OK_BUTTON : IDS_AUTOLOGIN_INFOBAR_CANCEL_BUTTON); |
204 } | 265 } |
205 | 266 |
206 bool AutoLoginInfoBarDelegate::Accept() { | 267 bool AutoLoginInfoBarDelegate::Accept() { |
207 // AutoLoginRedirector deletes itself. | 268 JNIEnv* env = base::android::AttachCurrentThread(); |
208 new AutoLoginRedirector(web_contents(), params_.header.args); | 269 ScopedJavaLocalRef<jobject> delegate = |
209 RecordHistogramAction(ACCEPTED); | 270 weak_java_auto_login_delegate_.get(env); |
210 button_pressed_ = true; | 271 DCHECK(delegate.obj()); |
| 272 Java_AutoLoginDelegate_logIn(env, delegate.obj(), |
| 273 reinterpret_cast<intptr_t>(this)); |
| 274 // Do not close the infobar on accept, it will be closed as part |
| 275 // of the log in callback. |
| 276 return false; |
| 277 } |
| 278 |
| 279 bool AutoLoginInfoBarDelegate::Cancel() { |
| 280 JNIEnv* env = base::android::AttachCurrentThread(); |
| 281 ScopedJavaLocalRef<jobject> delegate = |
| 282 weak_java_auto_login_delegate_.get(env); |
| 283 DCHECK(delegate.obj()); |
| 284 Java_AutoLoginDelegate_cancelLogIn(env, delegate.obj(), |
| 285 reinterpret_cast<intptr_t>(this)); |
211 return true; | 286 return true; |
212 } | 287 } |
213 | 288 |
214 bool AutoLoginInfoBarDelegate::Cancel() { | |
215 PrefService* pref_service = Profile::FromBrowserContext( | |
216 web_contents()->GetBrowserContext())->GetPrefs(); | |
217 pref_service->SetBoolean(prefs::kAutologinEnabled, false); | |
218 RecordHistogramAction(REJECTED); | |
219 button_pressed_ = true; | |
220 return true; | |
221 } | |
222 | |
223 void AutoLoginInfoBarDelegate::GoogleSignedOut(const std::string& username) { | 289 void AutoLoginInfoBarDelegate::GoogleSignedOut(const std::string& username) { |
224 infobar()->RemoveSelf(); | 290 infobar()->RemoveSelf(); |
225 } | 291 } |
226 | 292 |
227 void AutoLoginInfoBarDelegate::RecordHistogramAction(Actions action) { | 293 void AutoLoginInfoBarDelegate::RecordHistogramAction(Actions action) { |
228 UMA_HISTOGRAM_ENUMERATION("AutoLogin.Regular", action, | 294 UMA_HISTOGRAM_ENUMERATION("AutoLogin.Regular", action, |
229 HISTOGRAM_BOUNDING_VALUE); | 295 HISTOGRAM_BOUNDING_VALUE); |
230 } | 296 } |
OLD | NEW |