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

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

Issue 2014803002: Move DownloadControllerAndroid from content/ to chrome/ (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: moved download delegate interface to native Created 4 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/android/download_controller_android_impl.h" 5 #include "content/browser/android/download_controller_android_impl.h"
6 6
7 #include <memory> 7 #include <memory>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/android/context_utils.h" 10 #include "base/android/context_utils.h"
11 #include "base/android/jni_android.h" 11 #include "base/android/jni_android.h"
12 #include "base/android/jni_string.h" 12 #include "base/android/jni_string.h"
13 #include "base/bind.h" 13 #include "base/bind.h"
14 #include "base/lazy_instance.h" 14 #include "base/lazy_instance.h"
15 #include "base/logging.h" 15 #include "base/logging.h"
16 #include "base/synchronization/lock.h" 16 #include "base/synchronization/lock.h"
17 #include "base/time/time.h" 17 #include "base/time/time.h"
18 #include "content/browser/android/content_view_core_impl.h" 18 #include "content/browser/android/content_view_core_impl.h"
19 #include "content/browser/android/deferred_download_observer.h" 19 #include "content/browser/android/deferred_download_observer.h"
20 #include "content/browser/download/download_item_impl.h" 20 #include "content/browser/download/download_item_impl.h"
21 #include "content/browser/download/download_manager_impl.h" 21 #include "content/browser/download/download_manager_impl.h"
22 #include "content/browser/loader/resource_dispatcher_host_impl.h" 22 #include "content/browser/loader/resource_dispatcher_host_impl.h"
23 #include "content/browser/renderer_host/render_process_host_impl.h" 23 #include "content/browser/renderer_host/render_process_host_impl.h"
24 #include "content/browser/renderer_host/render_view_host_delegate.h" 24 #include "content/browser/renderer_host/render_view_host_delegate.h"
25 #include "content/browser/renderer_host/render_view_host_impl.h" 25 #include "content/browser/renderer_host/render_view_host_impl.h"
26 #include "content/browser/web_contents/web_contents_android.h"
26 #include "content/browser/web_contents/web_contents_impl.h" 27 #include "content/browser/web_contents/web_contents_impl.h"
28 #include "content/public/browser/android/download_delegate.h"
27 #include "content/public/browser/browser_context.h" 29 #include "content/public/browser/browser_context.h"
28 #include "content/public/browser/browser_thread.h" 30 #include "content/public/browser/browser_thread.h"
29 #include "content/public/browser/download_url_parameters.h" 31 #include "content/public/browser/download_url_parameters.h"
30 #include "content/public/browser/global_request_id.h" 32 #include "content/public/browser/global_request_id.h"
31 #include "content/public/browser/resource_request_info.h" 33 #include "content/public/browser/resource_request_info.h"
32 #include "content/public/common/content_client.h" 34 #include "content/public/common/content_client.h"
33 #include "content/public/common/referrer.h" 35 #include "content/public/common/referrer.h"
34 #include "jni/DownloadController_jni.h" 36 #include "jni/DownloadController_jni.h"
35 #include "net/base/filename_util.h" 37 #include "net/base/filename_util.h"
36 #include "net/cookies/cookie_options.h" 38 #include "net/cookies/cookie_options.h"
37 #include "net/cookies/cookie_store.h" 39 #include "net/cookies/cookie_store.h"
38 #include "net/http/http_content_disposition.h" 40 #include "net/http/http_content_disposition.h"
39 #include "net/http/http_request_headers.h" 41 #include "net/http/http_request_headers.h"
40 #include "net/http/http_response_headers.h" 42 #include "net/http/http_response_headers.h"
41 #include "net/url_request/url_request.h" 43 #include "net/url_request/url_request.h"
42 #include "net/url_request/url_request_context.h" 44 #include "net/url_request/url_request_context.h"
45 #include "ui/android/window_android.h"
43 46
44 using base::android::ConvertUTF8ToJavaString; 47 using base::android::ConvertUTF8ToJavaString;
45 using base::android::ScopedJavaLocalRef; 48 using base::android::ScopedJavaLocalRef;
46 49
47 namespace { 50 namespace {
48 // Guards download_controller_ 51 // Guards download_controller_
49 base::LazyInstance<base::Lock> g_download_controller_lock_; 52 base::LazyInstance<base::Lock> g_download_controller_lock_;
50 53
51 content::WebContents* GetWebContents(int render_process_id, 54 content::WebContents* GetWebContents(int render_process_id,
52 int render_view_id) { 55 int render_view_id) {
53 content::RenderViewHost* render_view_host = 56 content::RenderViewHost* render_view_host =
54 content::RenderViewHost::FromID(render_process_id, render_view_id); 57 content::RenderViewHost::FromID(render_process_id, render_view_id);
55 58
56 if (!render_view_host) 59 if (!render_view_host)
57 return nullptr; 60 return nullptr;
58 61
59 return content::WebContents::FromRenderViewHost(render_view_host); 62 return content::WebContents::FromRenderViewHost(render_view_host);
60 } 63 }
61 64
65 ScopedJavaLocalRef<jobject>
66 GetJavaWebContents(content::WebContents* web_contents) {
67 return (static_cast<content::WebContentsImpl*>(web_contents))
68 ->GetJavaWebContents();
69 }
70
62 void CreateContextMenuDownload(int render_process_id, 71 void CreateContextMenuDownload(int render_process_id,
63 int render_view_id, 72 int render_view_id,
64 const content::ContextMenuParams& params, 73 const content::ContextMenuParams& params,
65 bool is_link, 74 bool is_link,
66 const std::string& extra_headers, 75 const std::string& extra_headers,
67 bool granted) { 76 bool granted) {
68 if (!granted) 77 if (!granted)
69 return; 78 return;
70 79
71 content::WebContents* web_contents = 80 content::WebContents* web_contents =
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
196 } 205 }
197 } 206 }
198 } 207 }
199 208
200 void DownloadControllerAndroidImpl::AcquireFileAccessPermission( 209 void DownloadControllerAndroidImpl::AcquireFileAccessPermission(
201 WebContents* web_contents, 210 WebContents* web_contents,
202 const DownloadControllerAndroid::AcquireFileAccessPermissionCallback& cb) { 211 const DownloadControllerAndroid::AcquireFileAccessPermissionCallback& cb) {
203 DCHECK_CURRENTLY_ON(BrowserThread::UI); 212 DCHECK_CURRENTLY_ON(BrowserThread::UI);
204 DCHECK(web_contents); 213 DCHECK(web_contents);
205 214
206 ScopedJavaLocalRef<jobject> view = 215 ContentViewCore* view_core = ContentViewCore::FromWebContents(web_contents);
207 GetContentViewCoreFromWebContents(web_contents); 216 if (!view_core) {
208 if (view.is_null()) {
209 BrowserThread::PostTask( 217 BrowserThread::PostTask(
210 BrowserThread::UI, FROM_HERE, base::Bind(cb, false)); 218 BrowserThread::UI, FROM_HERE, base::Bind(cb, false));
211 return; 219 return;
212 } 220 }
213 221
214 if (HasFileAccessPermission(view)) { 222 ScopedJavaLocalRef<jobject> jweb_contents =
223 GetJavaWebContents(web_contents);
224 if (HasFileAccessPermission(view_core->GetWindowAndroid())) {
215 BrowserThread::PostTask( 225 BrowserThread::PostTask(
216 BrowserThread::UI, FROM_HERE, base::Bind(cb, true)); 226 BrowserThread::UI, FROM_HERE, base::Bind(cb, true));
217 return; 227 return;
218 } 228 }
219
220 JNIEnv* env = base::android::AttachCurrentThread();
221 // Make copy on the heap so we can pass the pointer through JNI. 229 // Make copy on the heap so we can pass the pointer through JNI.
222 intptr_t callback_id = reinterpret_cast<intptr_t>( 230 intptr_t callback_id = reinterpret_cast<intptr_t>(
223 new DownloadControllerAndroid::AcquireFileAccessPermissionCallback(cb)); 231 new DownloadControllerAndroid::AcquireFileAccessPermissionCallback(cb));
224 Java_DownloadController_requestFileAccess( 232 content::WebContentsImpl* web_contents_impl =
225 env, GetJavaObject()->Controller(env).obj(), view.obj(), callback_id); 233 static_cast<content::WebContentsImpl*>(web_contents);
234 web_contents_impl->GetWebContentsAndroid()->GetDownloadDelegate()->
235 RequestFileAccess(callback_id);
226 } 236 }
227 237
228 void DownloadControllerAndroidImpl::SetDefaultDownloadFileName( 238 void DownloadControllerAndroidImpl::SetDefaultDownloadFileName(
229 const std::string& file_name) { 239 const std::string& file_name) {
230 default_file_name_ = file_name; 240 default_file_name_ = file_name;
231 } 241 }
232 242
233 bool DownloadControllerAndroidImpl::HasFileAccessPermission( 243 bool DownloadControllerAndroidImpl::HasFileAccessPermission(
234 ScopedJavaLocalRef<jobject> j_content_view_core) { 244 ui::WindowAndroid* window_android) {
245 ScopedJavaLocalRef<jobject> jwindow_android = window_android->GetJavaObject();
246
235 DCHECK_CURRENTLY_ON(BrowserThread::UI); 247 DCHECK_CURRENTLY_ON(BrowserThread::UI);
236 DCHECK(!j_content_view_core.is_null()); 248 DCHECK(!jwindow_android.is_null());
237 249
238 JNIEnv* env = base::android::AttachCurrentThread(); 250 JNIEnv* env = base::android::AttachCurrentThread();
239 return Java_DownloadController_hasFileAccess( 251 return Java_DownloadController_hasFileAccess(
240 env, GetJavaObject()->Controller(env).obj(), j_content_view_core.obj()); 252 env, GetJavaObject()->Controller(env).obj(), jwindow_android.obj());
241 } 253 }
242 254
243 void DownloadControllerAndroidImpl::CreateGETDownload( 255 void DownloadControllerAndroidImpl::CreateGETDownload(
244 int render_process_id, int render_view_id, int request_id, 256 int render_process_id, int render_view_id, int request_id,
245 bool must_download) { 257 bool must_download) {
246 DCHECK_CURRENTLY_ON(BrowserThread::IO); 258 DCHECK_CURRENTLY_ON(BrowserThread::IO);
247 GlobalRequestID global_id(render_process_id, request_id); 259 GlobalRequestID global_id(render_process_id, request_id);
248 260
249 // We are yielding the UI thread and render_view_host may go away by 261 // We are yielding the UI thread and render_view_host may go away by
250 // the time we come back. Pass along render_process_id and render_view_id 262 // the time we come back. Pass along render_process_id and render_view_id
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
349 int render_process_id, int render_view_id, bool must_download, 361 int render_process_id, int render_view_id, bool must_download,
350 const DownloadInfoAndroid& info) { 362 const DownloadInfoAndroid& info) {
351 DCHECK_CURRENTLY_ON(BrowserThread::UI); 363 DCHECK_CURRENTLY_ON(BrowserThread::UI);
352 364
353 WebContents* web_contents = GetWebContents(render_process_id, render_view_id); 365 WebContents* web_contents = GetWebContents(render_process_id, render_view_id);
354 if (!web_contents) { 366 if (!web_contents) {
355 // The view went away. Can't proceed. 367 // The view went away. Can't proceed.
356 LOG(ERROR) << "Download failed on URL:" << info.url.spec(); 368 LOG(ERROR) << "Download failed on URL:" << info.url.spec();
357 return; 369 return;
358 } 370 }
359 ScopedJavaLocalRef<jobject> view =
360 GetContentViewCoreFromWebContents(web_contents);
361 if (view.is_null()) {
362 // ContentViewCore might not have been created yet, pass a callback to
363 // DeferredDownloadTaskManager so that the download can restart when
364 // ContentViewCore is created.
365 deferred_downloads_.push_back(new DeferredDownloadObserver(
366 web_contents,
367 base::Bind(&DownloadControllerAndroidImpl::StartAndroidDownload,
368 base::Unretained(this), render_process_id, render_view_id,
369 must_download, info)));
370 return;
371 }
372 371
373 AcquireFileAccessPermission( 372 AcquireFileAccessPermission(
374 web_contents, 373 web_contents,
375 base::Bind(&DownloadControllerAndroidImpl::StartAndroidDownloadInternal, 374 base::Bind(&DownloadControllerAndroidImpl::StartAndroidDownloadInternal,
376 base::Unretained(this), render_process_id, render_view_id, 375 base::Unretained(this), render_process_id, render_view_id,
377 must_download, info)); 376 must_download, info));
378 } 377 }
379 378
380 void DownloadControllerAndroidImpl::StartAndroidDownloadInternal( 379 void DownloadControllerAndroidImpl::StartAndroidDownloadInternal(
381 int render_process_id, int render_view_id, bool must_download, 380 int render_process_id, int render_view_id, bool must_download,
382 const DownloadInfoAndroid& info, bool allowed) { 381 const DownloadInfoAndroid& info, bool allowed) {
383 DCHECK_CURRENTLY_ON(BrowserThread::UI); 382 DCHECK_CURRENTLY_ON(BrowserThread::UI);
384 if (!allowed) 383 if (!allowed)
385 return; 384 return;
386 385
387 // Call newHttpGetDownload 386 // Call newHttpGetDownload
388 WebContents* web_contents = GetWebContents(render_process_id, render_view_id); 387 WebContents* web_contents = GetWebContents(render_process_id, render_view_id);
389 // The view went away. Can't proceed. 388 // The view went away. Can't proceed.
390 if (!web_contents) 389 if (!web_contents)
391 return; 390 return;
392 ScopedJavaLocalRef<jobject> view =
393 GetContentViewCoreFromWebContents(web_contents);
394 if (view.is_null())
395 return;
396 391
397 JNIEnv* env = base::android::AttachCurrentThread(); 392 content::WebContentsImpl* web_contents_impl =
398 ScopedJavaLocalRef<jstring> jurl = 393 (static_cast<content::WebContentsImpl*>(web_contents));
399 ConvertUTF8ToJavaString(env, info.url.spec()); 394 base::string16 filename = net::GetSuggestedFilename(
400 ScopedJavaLocalRef<jstring> juser_agent = 395 info.url, info.content_disposition,
401 ConvertUTF8ToJavaString(env, info.user_agent); 396 std::string(), // referrer_charset
402 ScopedJavaLocalRef<jstring> jcontent_disposition = 397 std::string(), // suggested_name
403 ConvertUTF8ToJavaString(env, info.content_disposition); 398 info.original_mime_type,
404 ScopedJavaLocalRef<jstring> jmime_type = 399 default_file_name_);
405 ConvertUTF8ToJavaString(env, info.original_mime_type); 400 web_contents_impl->GetWebContentsAndroid()->GetDownloadDelegate()->
406 ScopedJavaLocalRef<jstring> jcookie = 401 NewHTTPGetDownload(info.url.spec(), info.user_agent,
407 ConvertUTF8ToJavaString(env, info.cookie); 402 info.content_disposition, info.original_mime_type,
408 ScopedJavaLocalRef<jstring> jreferer = 403 info.cookie, info.referer, filename,
409 ConvertUTF8ToJavaString(env, info.referer); 404 info.total_bytes, info.has_user_gesture,
410 405 must_download);
411 // net::GetSuggestedFilename will fallback to "download" as filename.
412 ScopedJavaLocalRef<jstring> jfilename =
413 base::android::ConvertUTF16ToJavaString(
414 env, net::GetSuggestedFilename(info.url, info.content_disposition,
415 std::string(), // referrer_charset
416 std::string(), // suggested_name
417 info.original_mime_type,
418 default_file_name_));
419
420 Java_DownloadController_newHttpGetDownload(
421 env, GetJavaObject()->Controller(env).obj(), view.obj(), jurl.obj(),
422 juser_agent.obj(), jcontent_disposition.obj(), jmime_type.obj(),
423 jcookie.obj(), jreferer.obj(), info.has_user_gesture, jfilename.obj(),
424 info.total_bytes, must_download);
425 } 406 }
426 407
427 void DownloadControllerAndroidImpl::OnDownloadStarted( 408 void DownloadControllerAndroidImpl::OnDownloadStarted(
428 DownloadItem* download_item) { 409 DownloadItem* download_item) {
429 DCHECK_CURRENTLY_ON(BrowserThread::UI); 410 DCHECK_CURRENTLY_ON(BrowserThread::UI);
430 if (!download_item->GetWebContents()) 411 if (!download_item->GetWebContents())
431 return; 412 return;
432 413
433 JNIEnv* env = base::android::AttachCurrentThread();
434
435 // Register for updates to the DownloadItem. 414 // Register for updates to the DownloadItem.
436 download_item->AddObserver(this); 415 download_item->AddObserver(this);
437 416
438 ScopedJavaLocalRef<jobject> view = 417 content::WebContentsImpl* web_contents_impl =
439 GetContentViewCoreFromWebContents(download_item->GetWebContents()); 418 (static_cast<content::WebContentsImpl*>(download_item->GetWebContents()));
440 // The view went away. Can't proceed. 419 web_contents_impl->GetWebContentsAndroid()->GetDownloadDelegate()->
441 if (view.is_null()) 420 OnDownloadStarted(download_item->GetTargetFilePath().BaseName().value(),
442 return; 421 download_item->GetMimeType());
443 422
444 ScopedJavaLocalRef<jstring> jmime_type =
445 ConvertUTF8ToJavaString(env, download_item->GetMimeType());
446 ScopedJavaLocalRef<jstring> jfilename = ConvertUTF8ToJavaString(
447 env, download_item->GetTargetFilePath().BaseName().value());
448 Java_DownloadController_onDownloadStarted(
449 env, GetJavaObject()->Controller(env).obj(), view.obj(), jfilename.obj(),
450 jmime_type.obj());
451 } 423 }
452 424
453 void DownloadControllerAndroidImpl::OnDownloadUpdated(DownloadItem* item) { 425 void DownloadControllerAndroidImpl::OnDownloadUpdated(DownloadItem* item) {
454 DCHECK_CURRENTLY_ON(BrowserThread::UI); 426 DCHECK_CURRENTLY_ON(BrowserThread::UI);
455 if (item->IsDangerous() && (item->GetState() != DownloadItem::CANCELLED)) 427 if (item->IsDangerous() && (item->GetState() != DownloadItem::CANCELLED))
456 OnDangerousDownload(item); 428 OnDangerousDownload(item);
457 429
458 JNIEnv* env = base::android::AttachCurrentThread(); 430 JNIEnv* env = base::android::AttachCurrentThread();
459 ScopedJavaLocalRef<jstring> jguid = 431 ScopedJavaLocalRef<jstring> jguid =
460 ConvertUTF8ToJavaString(env, item->GetGuid()); 432 ConvertUTF8ToJavaString(env, item->GetGuid());
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
511 item->CanResume(), IsInterruptedDownloadAutoResumable(item), 483 item->CanResume(), IsInterruptedDownloadAutoResumable(item),
512 item->GetBrowserContext()->IsOffTheRecord()); 484 item->GetBrowserContext()->IsOffTheRecord());
513 item->RemoveObserver(this); 485 item->RemoveObserver(this);
514 break; 486 break;
515 case DownloadItem::MAX_DOWNLOAD_STATE: 487 case DownloadItem::MAX_DOWNLOAD_STATE:
516 NOTREACHED(); 488 NOTREACHED();
517 } 489 }
518 } 490 }
519 491
520 void DownloadControllerAndroidImpl::OnDangerousDownload(DownloadItem* item) { 492 void DownloadControllerAndroidImpl::OnDangerousDownload(DownloadItem* item) {
521 JNIEnv* env = base::android::AttachCurrentThread(); 493 content::WebContentsImpl* web_contents_impl =
522 ScopedJavaLocalRef<jstring> jfilename = ConvertUTF8ToJavaString( 494 (static_cast<content::WebContentsImpl*>(item->GetWebContents()));
523 env, item->GetTargetFilePath().BaseName().value()); 495 web_contents_impl->GetWebContentsAndroid()->GetDownloadDelegate()->
524 ScopedJavaLocalRef<jstring> jguid = 496 OnDownloadStarted(item->GetTargetFilePath().BaseName().value(),
525 ConvertUTF8ToJavaString(env, item->GetGuid()); 497 item->GetGuid());
526 ScopedJavaLocalRef<jobject> view_core = GetContentViewCoreFromWebContents(
527 item->GetWebContents());
528 if (!view_core.is_null()) {
529 Java_DownloadController_onDangerousDownload(
530 env, GetJavaObject()->Controller(env).obj(), view_core.obj(),
531 jfilename.obj(), jguid.obj());
532 }
533 } 498 }
534 499
535 ScopedJavaLocalRef<jobject> 500 ScopedJavaLocalRef<jobject>
536 DownloadControllerAndroidImpl::GetContentViewCoreFromWebContents( 501 DownloadControllerAndroidImpl::GetContentViewCoreFromWebContents(
537 WebContents* web_contents) { 502 WebContents* web_contents) {
538 if (!web_contents) 503 if (!web_contents)
539 return ScopedJavaLocalRef<jobject>(); 504 return ScopedJavaLocalRef<jobject>();
540 505
541 ContentViewCore* view_core = ContentViewCore::FromWebContents(web_contents); 506 ContentViewCore* view_core = ContentViewCore::FromWebContents(web_contents);
542 return view_core ? view_core->GetJavaObject() : 507 return view_core ? view_core->GetJavaObject() :
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
608 if (info) 573 if (info)
609 has_user_gesture = info->HasUserGesture(); 574 has_user_gesture = info->HasUserGesture();
610 } 575 }
611 576
612 DownloadControllerAndroidImpl::DownloadInfoAndroid::DownloadInfoAndroid( 577 DownloadControllerAndroidImpl::DownloadInfoAndroid::DownloadInfoAndroid(
613 const DownloadInfoAndroid& other) = default; 578 const DownloadInfoAndroid& other) = default;
614 579
615 DownloadControllerAndroidImpl::DownloadInfoAndroid::~DownloadInfoAndroid() {} 580 DownloadControllerAndroidImpl::DownloadInfoAndroid::~DownloadInfoAndroid() {}
616 581
617 } // namespace content 582 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698