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.
5 #include "android_webview/browser/aw_login_delegate.h"
7 #include "android_webview/browser/aw_browser_context.h"
8 #include "base/android/jni_android.h"
9 #include "base/logging.h"
10 #include "base/supports_user_data.h"
11 #include "content/public/browser/browser_thread.h"
12 #include "content/public/browser/render_frame_host.h"
13 #include "content/public/browser/resource_dispatcher_host.h"
14 #include "content/public/browser/resource_request_info.h"
15 #include "content/public/browser/web_contents.h"
16 #include "net/base/auth.h"
17 #include "net/url_request/url_request.h"
19 using namespace base::android
;
21 using content::BrowserThread
;
22 using content::RenderFrameHost
;
23 using content::ResourceDispatcherHost
;
24 using content::ResourceRequestInfo
;
25 using content::WebContents
;
28 const char* kAuthAttemptsKey
= "android_webview_auth_attempts";
30 class UrlRequestAuthAttemptsData
: public base::SupportsUserData::Data
{
32 UrlRequestAuthAttemptsData() : auth_attempts_(0) { }
38 namespace android_webview
{
40 AwLoginDelegate::AwLoginDelegate(net::AuthChallengeInfo
* auth_info
,
41 net::URLRequest
* request
)
42 : auth_info_(auth_info
),
44 render_process_id_(0),
46 ResourceRequestInfo::GetRenderFrameForRequest(
47 request
, &render_process_id_
, &render_frame_id_
);
49 UrlRequestAuthAttemptsData
* count
=
50 static_cast<UrlRequestAuthAttemptsData
*>(
51 request
->GetUserData(kAuthAttemptsKey
));
54 count
= new UrlRequestAuthAttemptsData();
55 request
->SetUserData(kAuthAttemptsKey
, count
);
58 BrowserThread::PostTask(BrowserThread::UI
, FROM_HERE
,
59 base::Bind(&AwLoginDelegate::HandleHttpAuthRequestOnUIThread
,
60 this, (count
->auth_attempts_
== 0)));
61 count
->auth_attempts_
++;
64 AwLoginDelegate::~AwLoginDelegate() {
65 // The Auth handler holds a ref count back on |this| object, so it should be
66 // impossible to reach here while this object still owns an auth handler.
67 DCHECK(!aw_http_auth_handler_
);
70 void AwLoginDelegate::Proceed(const base::string16
& user
,
71 const base::string16
& password
) {
72 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
73 BrowserThread::PostTask(BrowserThread::IO
, FROM_HERE
,
74 base::Bind(&AwLoginDelegate::ProceedOnIOThread
,
75 this, user
, password
));
78 void AwLoginDelegate::Cancel() {
79 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
80 BrowserThread::PostTask(BrowserThread::IO
, FROM_HERE
,
81 base::Bind(&AwLoginDelegate::CancelOnIOThread
, this));
84 void AwLoginDelegate::HandleHttpAuthRequestOnUIThread(
85 bool first_auth_attempt
) {
86 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
88 aw_http_auth_handler_
.reset(AwHttpAuthHandlerBase::Create(
89 this, auth_info_
.get(), first_auth_attempt
));
91 RenderFrameHost
* render_frame_host
= RenderFrameHost::FromID(
92 render_process_id_
, render_frame_id_
);
93 WebContents
* web_contents
= WebContents::FromRenderFrameHost(
95 if (!aw_http_auth_handler_
->HandleOnUIThread(web_contents
)) {
101 void AwLoginDelegate::CancelOnIOThread() {
102 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
104 request_
->CancelAuth();
105 ResourceDispatcherHost::Get()->ClearLoginDelegateForRequest(request_
);
108 DeleteAuthHandlerSoon();
111 void AwLoginDelegate::ProceedOnIOThread(const base::string16
& user
,
112 const base::string16
& password
) {
113 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
115 request_
->SetAuth(net::AuthCredentials(user
, password
));
116 ResourceDispatcherHost::Get()->ClearLoginDelegateForRequest(request_
);
119 DeleteAuthHandlerSoon();
122 void AwLoginDelegate::OnRequestCancelled() {
123 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
125 DeleteAuthHandlerSoon();
128 void AwLoginDelegate::DeleteAuthHandlerSoon() {
129 if (!BrowserThread::CurrentlyOn(BrowserThread::UI
)) {
130 BrowserThread::PostTask(BrowserThread::UI
, FROM_HERE
,
131 base::Bind(&AwLoginDelegate::DeleteAuthHandlerSoon
, this));
134 aw_http_auth_handler_
.reset();
137 } // namespace android_webview