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 "xwalk/runtime/browser/android/xwalk_login_delegate.h"
7 #include "base/android/jni_android.h"
8 #include "base/logging.h"
9 #include "base/supports_user_data.h"
10 #include "content/public/browser/browser_thread.h"
11 #include "content/public/browser/render_view_host.h"
12 #include "content/public/browser/resource_dispatcher_host.h"
13 #include "content/public/browser/resource_request_info.h"
14 #include "content/public/browser/web_contents.h"
15 #include "net/base/auth.h"
16 #include "net/url_request/url_request.h"
18 using content::BrowserThread;
19 using content::RenderViewHost;
20 using content::ResourceDispatcherHost;
21 using content::ResourceRequestInfo;
22 using content::WebContents;
25 const char* kAuthAttemptsKey = "xwalk_auth_attempts";
27 class UrlRequestAuthAttemptsData : public base::SupportsUserData::Data {
29 UrlRequestAuthAttemptsData() : auth_attempts_(0) { }
37 XWalkLoginDelegate::XWalkLoginDelegate(net::AuthChallengeInfo* auth_info,
38 net::URLRequest* request)
39 : auth_info_(auth_info),
41 render_process_id_(0),
43 ResourceRequestInfo::GetRenderFrameForRequest(
44 request, &render_process_id_, &render_view_id_);
46 UrlRequestAuthAttemptsData* count =
47 static_cast<UrlRequestAuthAttemptsData*>(
48 request->GetUserData(kAuthAttemptsKey));
51 count = new UrlRequestAuthAttemptsData();
52 request->SetUserData(kAuthAttemptsKey, count);
55 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
56 base::Bind(&XWalkLoginDelegate::HandleHttpAuthRequestOnUIThread,
57 this, (count->auth_attempts_ == 0)));
58 count->auth_attempts_++;
61 XWalkLoginDelegate::~XWalkLoginDelegate() {
62 // The Auth handler holds a ref count back on |this| object, so it should be
63 // impossible to reach here while this object still owns an auth handler.
64 DCHECK(xwalk_http_auth_handler_ == NULL);
67 void XWalkLoginDelegate::Proceed(const base::string16& user,
68 const base::string16& password) {
69 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
70 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
71 base::Bind(&XWalkLoginDelegate::ProceedOnIOThread,
72 this, user, password));
75 void XWalkLoginDelegate::Cancel() {
76 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
77 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
78 base::Bind(&XWalkLoginDelegate::CancelOnIOThread, this));
81 void XWalkLoginDelegate::HandleHttpAuthRequestOnUIThread(
82 bool first_auth_attempt) {
83 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
85 xwalk_http_auth_handler_.reset(XWalkHttpAuthHandlerBase::Create(
86 this, auth_info_.get(), first_auth_attempt));
88 RenderViewHost* render_view_host = RenderViewHost::FromID(
89 render_process_id_, render_view_id_);
90 if (!render_view_host) {
95 WebContents* web_contents = WebContents::FromRenderViewHost(
97 if (!xwalk_http_auth_handler_->HandleOnUIThread(web_contents)) {
103 void XWalkLoginDelegate::CancelOnIOThread() {
104 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
106 request_->CancelAuth();
107 ResourceDispatcherHost::Get()->ClearLoginDelegateForRequest(request_);
110 DeleteAuthHandlerSoon();
113 void XWalkLoginDelegate::ProceedOnIOThread(const base::string16& user,
114 const base::string16& password) {
115 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
117 request_->SetAuth(net::AuthCredentials(user, password));
118 ResourceDispatcherHost::Get()->ClearLoginDelegateForRequest(request_);
121 DeleteAuthHandlerSoon();
124 void XWalkLoginDelegate::OnRequestCancelled() {
125 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
127 DeleteAuthHandlerSoon();
130 void XWalkLoginDelegate::DeleteAuthHandlerSoon() {
131 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
132 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
133 base::Bind(&XWalkLoginDelegate::DeleteAuthHandlerSoon, this));
136 xwalk_http_auth_handler_.reset();