Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / android_webview / browser / aw_login_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 "android_webview/browser/aw_login_delegate.h"
6
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"
18
19 using namespace base::android;
20
21 using content::BrowserThread;
22 using content::RenderFrameHost;
23 using content::ResourceDispatcherHost;
24 using content::ResourceRequestInfo;
25 using content::WebContents;
26
27 namespace {
28 const char* kAuthAttemptsKey = "android_webview_auth_attempts";
29
30 class UrlRequestAuthAttemptsData : public base::SupportsUserData::Data {
31  public:
32   UrlRequestAuthAttemptsData() : auth_attempts_(0) { }
33   int auth_attempts_;
34 };
35
36 }  // namespace
37
38 namespace android_webview {
39
40 AwLoginDelegate::AwLoginDelegate(net::AuthChallengeInfo* auth_info,
41                                  net::URLRequest* request)
42     : auth_info_(auth_info),
43       request_(request),
44       render_process_id_(0),
45       render_frame_id_(0) {
46     ResourceRequestInfo::GetRenderFrameForRequest(
47         request, &render_process_id_, &render_frame_id_);
48
49     UrlRequestAuthAttemptsData* count =
50         static_cast<UrlRequestAuthAttemptsData*>(
51             request->GetUserData(kAuthAttemptsKey));
52
53     if (count == NULL) {
54       count = new UrlRequestAuthAttemptsData();
55       request->SetUserData(kAuthAttemptsKey, count);
56     }
57
58     BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
59         base::Bind(&AwLoginDelegate::HandleHttpAuthRequestOnUIThread,
60                    this, (count->auth_attempts_ == 0)));
61     count->auth_attempts_++;
62 }
63
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_);
68 }
69
70 void AwLoginDelegate::Proceed(const base::string16& user,
71                               const base::string16& password) {
72   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
73   BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
74       base::Bind(&AwLoginDelegate::ProceedOnIOThread,
75                  this, user, password));
76 }
77
78 void AwLoginDelegate::Cancel() {
79   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
80   BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
81       base::Bind(&AwLoginDelegate::CancelOnIOThread, this));
82 }
83
84 void AwLoginDelegate::HandleHttpAuthRequestOnUIThread(
85     bool first_auth_attempt) {
86   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
87
88   aw_http_auth_handler_.reset(AwHttpAuthHandlerBase::Create(
89       this, auth_info_.get(), first_auth_attempt));
90
91   RenderFrameHost* render_frame_host = RenderFrameHost::FromID(
92       render_process_id_, render_frame_id_);
93   WebContents* web_contents = WebContents::FromRenderFrameHost(
94       render_frame_host);
95   if (!aw_http_auth_handler_->HandleOnUIThread(web_contents)) {
96     Cancel();
97     return;
98   }
99 }
100
101 void AwLoginDelegate::CancelOnIOThread() {
102   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
103   if (request_) {
104     request_->CancelAuth();
105     ResourceDispatcherHost::Get()->ClearLoginDelegateForRequest(request_);
106     request_ = NULL;
107   }
108   DeleteAuthHandlerSoon();
109 }
110
111 void AwLoginDelegate::ProceedOnIOThread(const base::string16& user,
112                                         const base::string16& password) {
113   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
114   if (request_) {
115     request_->SetAuth(net::AuthCredentials(user, password));
116     ResourceDispatcherHost::Get()->ClearLoginDelegateForRequest(request_);
117     request_ = NULL;
118   }
119   DeleteAuthHandlerSoon();
120 }
121
122 void AwLoginDelegate::OnRequestCancelled() {
123   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
124   request_ = NULL;
125   DeleteAuthHandlerSoon();
126 }
127
128 void AwLoginDelegate::DeleteAuthHandlerSoon() {
129   if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
130     BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
131         base::Bind(&AwLoginDelegate::DeleteAuthHandlerSoon, this));
132     return;
133   }
134   aw_http_auth_handler_.reset();
135 }
136
137 }  // namespace android_webview