Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(477)

Side by Side Diff: content/browser/android/download_controller.cc

Issue 10449017: Add android download controller. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Calling CanGetCookies on the network delegate. Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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 "content/browser/android/download_controller.h"
6
7 #include "base/android/jni_android.h"
8 #include "base/android/jni_string.h"
9 #include "base/bind.h"
10 #include "base/logging.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "content/browser/renderer_host/render_view_host_delegate.h"
13 #include "content/browser/renderer_host/resource_dispatcher_host_impl.h"
14 #include "content/public/browser/browser_thread.h"
15 #include "content/public/browser/download_item.h"
16 #include "content/public/browser/global_request_id.h"
17 #include "content/public/browser/render_process_host.h"
18 #include "content/public/browser/render_view_host.h"
19 #include "content/public/browser/web_contents.h"
jam 2012/05/29 21:48:05 nit: for all these includes, our convention is to
nilesh 2012/05/30 00:29:57 Done.
20 #include "jni/download_controller_jni.h"
21 #include "net/cookies/cookie_options.h"
22 #include "net/cookies/cookie_store.h"
23 #include "net/http/http_request_headers.h"
24 #include "net/url_request/url_request.h"
25 #include "net/url_request/url_request_context.h"
26
27 using base::android::AttachCurrentThread;
28 using base::android::CheckException;
29 using base::android::ConvertUTF8ToJavaString;
30 using base::android::GetClass;
31 using base::android::ScopedJavaLocalRef;
32 using content::BrowserThread;
33 using content::DownloadItem;
34 using content::RenderViewHost;
35 using content::WebContents;
jam 2012/05/29 21:48:05 these include statements don't appear to be needed
nilesh 2012/05/30 00:29:57 Done.
36
37 // JNI methods
38 static void Init(JNIEnv* env, jobject obj) {
39 content::DownloadController::GetInstance()->Init(env, obj);
40 }
41
42 namespace {
43 const char* kDownloadControllerClassPathName =
44 "org/chromium/content/browser/DownloadController";
45 } // namespace
46
47 namespace content {
48
49 struct DownloadController::JavaObject {
50 ScopedJavaLocalRef<jobject> Controller(JNIEnv* env) {
51 return GetRealObject(env, obj);
52 }
53 jweak obj;
54 };
55
56 // static
57 bool DownloadController::RegisterDownloadController(JNIEnv* env) {
58 return RegisterNativesImpl(env);
59 }
60
61 DownloadController* DownloadController::GetInstance() {
62 return Singleton<DownloadController>::get();
63 }
64
65 DownloadController::DownloadController()
66 : java_object_(NULL) {
67 }
68
69 DownloadController::~DownloadController() {
70 if (java_object_) {
71 JNIEnv* env = AttachCurrentThread();
72 env->DeleteWeakGlobalRef(java_object_->obj);
73 delete java_object_;
74 CheckException(env);
75 }
76 }
77
78 // Initialize references to Java object.
79 void DownloadController::Init(JNIEnv* env, jobject obj) {
80 java_object_ = new JavaObject;
81 java_object_->obj = env->NewWeakGlobalRef(obj);
82 }
83
84 void DownloadController::NewGetDownload(
85 content::RenderViewHost* render_view_host,
jam 2012/05/29 21:48:05 nit: get rid of all the "content::" since you're i
nilesh 2012/05/30 00:29:57 Done. I forgot to remove all these after I moved t
86 int request_id) {
87 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
88 int render_process_id = render_view_host->GetProcess()->GetID();
89 content::GlobalRequestID global_id(render_process_id, request_id);
90
91 // We are yielding the UI thread and render_view_host may go away by
92 // the time we come back. Pass along render_process_id and render_view_id
93 // to retrieve it later (if it still exists).
94 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
95 base::Bind(&DownloadController::PrepareDownloadInfo,
96 base::Unretained(this), global_id,
97 render_process_id,
98 render_view_host->GetRoutingID()));
99 }
100
101 void DownloadController::PrepareDownloadInfo(
102 const content::GlobalRequestID& global_id,
103 int render_process_id, int render_view_id) {
104 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
105
106 net::URLRequest* request =
107 content::ResourceDispatcherHostImpl::Get()->GetURLRequest(global_id);
108 DCHECK(request) << "Request to download not found.";
109
110 DownloadInfoAndroid info_android(request);
111
112 net::CookieStore* cookie_store = request->context()->cookie_store();
113 if (cookie_store) {
114 net::CookieMonster* cookie_monster = cookie_store->GetCookieMonster();
115 if (cookie_monster) {
116 cookie_monster->GetAllCookiesForURLAsync(
117 request->url(),
118 base::Bind(&DownloadController::CheckPolicyAndLoadCookies,
119 base::Unretained(this), info_android, render_process_id,
120 render_view_id, global_id));
121 } else {
122 DoLoadCookies(
123 info_android, render_process_id, render_view_id, global_id);
124 }
125 } else {
126 // Can't get any cookies, start android download.
127 StartAndroidDownload(info_android, render_process_id, render_view_id);
128 }
129 }
130
131 void DownloadController::CheckPolicyAndLoadCookies(
132 const DownloadInfoAndroid& info, int render_process_id,
133 int render_view_id, const content::GlobalRequestID& global_id,
134 const net::CookieList& cookie_list) {
135 net::URLRequest* request =
136 content::ResourceDispatcherHostImpl::Get()->GetURLRequest(global_id);
137 DCHECK(request) << "Request to download not found.";
138
139 if (request->context()->network_delegate()->CanGetCookies(
140 *request, cookie_list)) {
141 DoLoadCookies(info, render_process_id, render_view_id, global_id);
142 } else {
143 StartAndroidDownload(info, render_process_id, render_view_id);
144 }
145 }
146
147 void DownloadController::DoLoadCookies(
148 const DownloadInfoAndroid& info, int render_process_id,
149 int render_view_id, const content::GlobalRequestID& global_id) {
150 net::CookieOptions options;
151 options.set_include_httponly();
152
153 net::URLRequest* request =
154 content::ResourceDispatcherHostImpl::Get()->GetURLRequest(global_id);
155 DCHECK(request) << "Request to download not found.";
156
157 request->context()->cookie_store()->GetCookiesWithOptionsAsync(
158 info.url, options,
159 base::Bind(&DownloadController::OnCookieResponse,
160 base::Unretained(this), info, render_process_id,
161 render_view_id));
162 }
163
164 void DownloadController::OnCookieResponse(DownloadInfoAndroid download_info,
165 int render_process_id,
166 int render_view_id,
167 const std::string& cookie) {
168 download_info.cookie = cookie;
169
170 // We have everything we need, start Android download.
171 StartAndroidDownload(download_info, render_process_id, render_view_id);
172 }
173
174 void DownloadController::StartAndroidDownload(
175 const DownloadInfoAndroid& info,
176 int render_process_id,
177 int render_view_id) {
178 // Call ourself on the UI thread if not already on it.
179 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
180 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
181 base::Bind(&DownloadController::StartAndroidDownload,
182 base::Unretained(this), info, render_process_id,
183 render_view_id));
184 return;
185 }
186
187 JNIEnv* env = AttachCurrentThread();
188
189 // Call newHttpGetDownload
190 jobject view = GetContentView(render_process_id, render_view_id);
191 if (!view) {
192 // The view went away. Can't proceed.
193 LOG(ERROR) << "Download failed on URL:" << info.url.spec();
194 return;
195 }
196
197 ScopedJavaLocalRef<jstring> jurl =
198 ConvertUTF8ToJavaString(env, info.url.spec());
199 ScopedJavaLocalRef<jstring> juser_agent =
200 ConvertUTF8ToJavaString(env, info.user_agent);
201 ScopedJavaLocalRef<jstring> jcontent_disposition =
202 ConvertUTF8ToJavaString(env, info.content_disposition);
203 ScopedJavaLocalRef<jstring> jmime_type =
204 ConvertUTF8ToJavaString(env, info.original_mime_type);
205 ScopedJavaLocalRef<jstring> jcookie =
206 ConvertUTF8ToJavaString(env, info.cookie);
207
208 Java_DownloadController_newHttpGetDownload(
209 env, java_object()->Controller(env).obj(), view, jurl.obj(),
210 juser_agent.obj(), jcontent_disposition.obj(), jmime_type.obj(),
211 jcookie.obj(), info.total_bytes);
212 }
213
214 void DownloadController::OnPostDownloadStarted(
215 WebContents* web_contents,
216 DownloadItem* download_item) {
217 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
218 JNIEnv* env = AttachCurrentThread();
219
220 // Register for updates to the DownloadItem.
221 download_item->AddObserver(this);
222
223 jobject view = GetContentViewFromWebContents(web_contents);
224 if(!view) {
225 // The view went away. Can't proceed.
226 return;
227 }
228
229 Java_DownloadController_onHttpPostDownloadStarted(
230 env, java_object()->Controller(env).obj(), view);
231 }
232
233 void DownloadController::OnDownloadUpdated(DownloadItem* item) {
234 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
235
236 if (item->GetState() != DownloadItem::COMPLETE)
237 return;
238
239 // Call onHttpPostDownloadCompleted
240 JNIEnv* env = AttachCurrentThread();
241 ScopedJavaLocalRef<jstring> jurl =
242 ConvertUTF8ToJavaString(env, item->GetURL().spec());
243 ScopedJavaLocalRef<jstring> jcontent_disposition =
244 ConvertUTF8ToJavaString(env, item->GetContentDisposition());
245 ScopedJavaLocalRef<jstring> jmime_type =
246 ConvertUTF8ToJavaString(env, item->GetMimeType());
247 ScopedJavaLocalRef<jstring> jpath =
248 ConvertUTF8ToJavaString(env, item->GetFullPath().value());
249
250 jobject view = GetContentViewFromWebContents(item->GetWebContents());
251 if(!view) {
252 // We can get NULL WebContents from the DownloadItem.
253 return;
254 }
255
256 Java_DownloadController_onHttpPostDownloadCompleted(env,
257 java_object()->Controller(env).obj(), view, jurl.obj(),
258 jcontent_disposition.obj(), jmime_type.obj(), jpath.obj(),
259 item->GetReceivedBytes(), true);
260 }
261
262 void DownloadController::OnDownloadOpened(DownloadItem* item) {
263 }
264
265 jobject DownloadController::GetContentView(int render_process_id,
266 int render_view_id) {
267 RenderViewHost* render_view_host =
268 RenderViewHost::FromID(render_process_id, render_view_id);
269
270 if (!render_view_host)
271 return NULL;
272
273 WebContents* web_contents =
274 render_view_host->GetDelegate()->GetAsWebContents();
275
276 if (!web_contents)
277 return NULL;
278
279 return GetContentViewFromWebContents(web_contents);
280 }
281
282 jobject DownloadController::GetContentViewFromWebContents(
283 WebContents* web_contents) {
284 NOTIMPLEMENTED();
285 return NULL;
286 }
287
288 DownloadController::JavaObject* DownloadController::java_object() {
289 if (!java_object_) {
290 // Initialize Java DownloadController by calling
291 // DownloadController.getInstance(), which will call Init()
292 // if Java DownloadController is not instantiated already.
293 JNIEnv* env = AttachCurrentThread();
294 ScopedJavaLocalRef<jclass> clazz =
295 GetClass(env, kDownloadControllerClassPathName);
296 jmethodID get_instance = GetStaticMethodID(env, clazz, "getInstance",
297 "()Lorg/chromium/content/browser/DownloadController;");
298 ScopedJavaLocalRef<jobject> jobj(env,
299 env->CallStaticObjectMethod(clazz.obj(), get_instance));
300 CheckException(env);
301 }
302
303 DCHECK(java_object_);
304 return java_object_;
305 }
306
307 DownloadController::DownloadInfoAndroid::DownloadInfoAndroid(
308 net::URLRequest* request) {
309 request->GetResponseHeaderByName("content-disposition", &content_disposition);
310 request->GetResponseHeaderByName("mime-type", &original_mime_type);
311 request->extra_request_headers().GetHeader(
312 net::HttpRequestHeaders::kUserAgent,
313 &user_agent);
314 if (!request->url_chain().empty()) {
315 original_url = request->url_chain().front();
316 url = request->url_chain().back();
317 }
318 }
319
320 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698