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