15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/android/download_controller_android_impl.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/android/jni_android.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/android/jni_string.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
12f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/time/time.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/android/content_view_core_impl.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/download/download_item_impl.h"
15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/browser/download/download_manager_impl.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/browser/loader/resource_dispatcher_host_impl.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/renderer_host/render_process_host_impl.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/renderer_host/render_view_host_delegate.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/renderer_host/render_view_host_impl.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/web_contents/web_contents_impl.h"
21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/public/browser/browser_context.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/public/browser/download_url_parameters.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/global_request_id.h"
255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/browser/resource_request_info.h"
26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/public/common/referrer.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "jni/DownloadController_jni.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/cookies/cookie_options.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/cookies/cookie_store.h"
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/http/http_content_disposition.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_request_headers.h"
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/http/http_response_headers.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_context.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::android::ConvertUTF8ToJavaString;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::android::ScopedJavaLocalRef;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// JNI methods
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void Init(JNIEnv* env, jobject obj) {
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DownloadControllerAndroidImpl::GetInstance()->Init(env, obj);
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct DownloadControllerAndroidImpl::JavaObject {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScopedJavaLocalRef<jobject> Controller(JNIEnv* env) {
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return GetRealObject(env, obj);
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  jweak obj;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DownloadControllerAndroidImpl::RegisterDownloadController(JNIEnv* env) {
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return RegisterNativesImpl(env);
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DownloadControllerAndroid* DownloadControllerAndroid::Get() {
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return DownloadControllerAndroidImpl::GetInstance();
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DownloadControllerAndroidImpl* DownloadControllerAndroidImpl::GetInstance() {
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return Singleton<DownloadControllerAndroidImpl>::get();
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DownloadControllerAndroidImpl::DownloadControllerAndroidImpl()
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : java_object_(NULL) {
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DownloadControllerAndroidImpl::~DownloadControllerAndroidImpl() {
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (java_object_) {
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    JNIEnv* env = base::android::AttachCurrentThread();
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    env->DeleteWeakGlobalRef(java_object_->obj);
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delete java_object_;
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::android::CheckException(env);
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Initialize references to Java object.
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DownloadControllerAndroidImpl::Init(JNIEnv* env, jobject obj) {
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  java_object_ = new JavaObject;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  java_object_->obj = env->NewWeakGlobalRef(obj);
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DownloadControllerAndroidImpl::CreateGETDownload(
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int render_process_id, int render_view_id, int request_id) {
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GlobalRequestID global_id(render_process_id, request_id);
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We are yielding the UI thread and render_view_host may go away by
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the time we come back. Pass along render_process_id and render_view_id
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to retrieve it later (if it still exists).
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GetDownloadInfoCB cb = base::Bind(
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        &DownloadControllerAndroidImpl::StartAndroidDownload,
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Unretained(this), render_process_id,
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        render_view_id);
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  PrepareDownloadInfo(
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      global_id,
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      base::Bind(&DownloadControllerAndroidImpl::StartDownloadOnUIThread,
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this), cb));
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DownloadControllerAndroidImpl::PrepareDownloadInfo(
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GlobalRequestID& global_id,
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GetDownloadInfoCB& callback) {
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::URLRequest* request =
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ResourceDispatcherHostImpl::Get()->GetURLRequest(global_id);
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!request) {
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LOG(ERROR) << "Request to download not found.";
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DownloadInfoAndroid info_android(request);
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::CookieStore* cookie_store = request->context()->cookie_store();
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (cookie_store) {
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::CookieMonster* cookie_monster = cookie_store->GetCookieMonster();
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (cookie_monster) {
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cookie_monster->GetAllCookiesForURLAsync(
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          request->url(),
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base::Bind(&DownloadControllerAndroidImpl::CheckPolicyAndLoadCookies,
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     base::Unretained(this), info_android, callback,
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     global_id));
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DoLoadCookies(info_android, callback, global_id);
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Can't get any cookies, start android download.
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    callback.Run(info_android);
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DownloadControllerAndroidImpl::CheckPolicyAndLoadCookies(
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const DownloadInfoAndroid& info, const GetDownloadInfoCB& callback,
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GlobalRequestID& global_id, const net::CookieList& cookie_list) {
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::URLRequest* request =
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ResourceDispatcherHostImpl::Get()->GetURLRequest(global_id);
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!request) {
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LOG(ERROR) << "Request to download not found.";
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (request->context()->network_delegate()->CanGetCookies(
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *request, cookie_list)) {
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DoLoadCookies(info, callback, global_id);
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    callback.Run(info);
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DownloadControllerAndroidImpl::DoLoadCookies(
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const DownloadInfoAndroid& info, const GetDownloadInfoCB& callback,
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GlobalRequestID& global_id) {
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::CookieOptions options;
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  options.set_include_httponly();
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::URLRequest* request =
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ResourceDispatcherHostImpl::Get()->GetURLRequest(global_id);
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!request) {
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LOG(ERROR) << "Request to download not found.";
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request->context()->cookie_store()->GetCookiesWithOptionsAsync(
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      info.url, options,
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&DownloadControllerAndroidImpl::OnCookieResponse,
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 base::Unretained(this), info, callback));
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DownloadControllerAndroidImpl::OnCookieResponse(
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DownloadInfoAndroid download_info,
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GetDownloadInfoCB& callback,
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& cookie) {
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  download_info.cookie = cookie;
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We have everything we need, start Android download.
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  callback.Run(download_info);
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DownloadControllerAndroidImpl::StartDownloadOnUIThread(
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GetDownloadInfoCB& callback,
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const DownloadInfoAndroid& info) {
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  BrowserThread::PostTask(
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      BrowserThread::UI, FROM_HERE, base::Bind(callback, info));
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DownloadControllerAndroidImpl::StartAndroidDownload(
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int render_process_id, int render_view_id,
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const DownloadInfoAndroid& info) {
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  JNIEnv* env = base::android::AttachCurrentThread();
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Call newHttpGetDownload
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScopedJavaLocalRef<jobject> view = GetContentView(render_process_id,
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                    render_view_id);
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (view.is_null()) {
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The view went away. Can't proceed.
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Download failed on URL:" << info.url.spec();
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScopedJavaLocalRef<jstring> jurl =
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ConvertUTF8ToJavaString(env, info.url.spec());
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScopedJavaLocalRef<jstring> juser_agent =
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ConvertUTF8ToJavaString(env, info.user_agent);
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScopedJavaLocalRef<jstring> jcontent_disposition =
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ConvertUTF8ToJavaString(env, info.content_disposition);
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScopedJavaLocalRef<jstring> jmime_type =
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ConvertUTF8ToJavaString(env, info.original_mime_type);
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScopedJavaLocalRef<jstring> jcookie =
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ConvertUTF8ToJavaString(env, info.cookie);
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScopedJavaLocalRef<jstring> jreferer =
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ConvertUTF8ToJavaString(env, info.referer);
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Try parsing the content disposition header to get a
2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // explicitly specified filename if available.
2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  net::HttpContentDisposition header(info.content_disposition, "");
2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ScopedJavaLocalRef<jstring> jfilename =
2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ConvertUTF8ToJavaString(env, header.filename());
2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Java_DownloadController_newHttpGetDownload(
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      env, GetJavaObject()->Controller(env).obj(), view.obj(), jurl.obj(),
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      juser_agent.obj(), jcontent_disposition.obj(), jmime_type.obj(),
2345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      jcookie.obj(), jreferer.obj(), info.has_user_gesture, jfilename.obj(),
2355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      info.total_bytes);
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void DownloadControllerAndroidImpl::OnDownloadStarted(
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DownloadItem* download_item) {
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!download_item->GetWebContents())
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  JNIEnv* env = base::android::AttachCurrentThread();
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Register for updates to the DownloadItem.
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  download_item->AddObserver(this);
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScopedJavaLocalRef<jobject> view =
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetContentViewCoreFromWebContents(download_item->GetWebContents());
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The view went away. Can't proceed.
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (view.is_null())
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ScopedJavaLocalRef<jstring> jmime_type =
256868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      ConvertUTF8ToJavaString(env, download_item->GetMimeType());
257868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ScopedJavaLocalRef<jstring> jfilename = ConvertUTF8ToJavaString(
258868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      env, download_item->GetTargetFilePath().BaseName().value());
259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Java_DownloadController_onDownloadStarted(
260868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      env, GetJavaObject()->Controller(env).obj(), view.obj(), jfilename.obj(),
261868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      jmime_type.obj());
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DownloadControllerAndroidImpl::OnDownloadUpdated(DownloadItem* item) {
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
266f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (item->IsDangerous() && (item->GetState() != DownloadItem::CANCELLED))
267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    OnDangerousDownload(item);
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  JNIEnv* env = base::android::AttachCurrentThread();
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScopedJavaLocalRef<jstring> jurl =
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ConvertUTF8ToJavaString(env, item->GetURL().spec());
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScopedJavaLocalRef<jstring> jmime_type =
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ConvertUTF8ToJavaString(env, item->GetMimeType());
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScopedJavaLocalRef<jstring> jpath =
275b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      ConvertUTF8ToJavaString(env, item->GetTargetFilePath().value());
276868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ScopedJavaLocalRef<jstring> jfilename = ConvertUTF8ToJavaString(
277868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      env, item->GetTargetFilePath().BaseName().value());
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
279f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  switch (item->GetState()) {
280f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    case DownloadItem::IN_PROGRESS: {
281f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::TimeDelta time_delta;
282f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      item->TimeRemaining(&time_delta);
283f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      Java_DownloadController_onDownloadUpdated(
284f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          env, GetJavaObject()->Controller(env).obj(),
285f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          base::android::GetApplicationContext(), jurl.obj(), jmime_type.obj(),
286f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          jfilename.obj(), jpath.obj(), item->GetReceivedBytes(), true,
287f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          item->GetId(), item->PercentComplete(), time_delta.InMilliseconds());
288f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      break;
289f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
290f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    case DownloadItem::COMPLETE:
291f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      // Multiple OnDownloadUpdated() notifications may be issued while the
292f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      // download is in the COMPLETE state. Only handle one.
293f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      item->RemoveObserver(this);
294f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
295f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      // Call onDownloadCompleted
296f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      Java_DownloadController_onDownloadCompleted(
297f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          env, GetJavaObject()->Controller(env).obj(),
298f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          base::android::GetApplicationContext(), jurl.obj(), jmime_type.obj(),
299f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          jfilename.obj(), jpath.obj(), item->GetReceivedBytes(), true,
300f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          item->GetId());
301f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      break;
302f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    case DownloadItem::CANCELLED:
303f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // TODO(shashishekhar): An interrupted download can be resumed. Android
304f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // currently does not support resumable downloads. Add handling for
305f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // interrupted case based on item->CanResume().
306f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    case DownloadItem::INTERRUPTED:
307f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      // Call onDownloadCompleted with success = false.
308f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      Java_DownloadController_onDownloadCompleted(
309f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          env, GetJavaObject()->Controller(env).obj(),
310f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          base::android::GetApplicationContext(), jurl.obj(), jmime_type.obj(),
311f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          jfilename.obj(), jpath.obj(), item->GetReceivedBytes(), false,
312f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          item->GetId());
313f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      break;
314f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    case DownloadItem::MAX_DOWNLOAD_STATE:
315f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      NOTREACHED();
316f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void DownloadControllerAndroidImpl::OnDangerousDownload(DownloadItem* item) {
320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  JNIEnv* env = base::android::AttachCurrentThread();
321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ScopedJavaLocalRef<jstring> jfilename = ConvertUTF8ToJavaString(
322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      env, item->GetTargetFilePath().BaseName().value());
323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ScopedJavaLocalRef<jobject> view_core = GetContentViewCoreFromWebContents(
324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      item->GetWebContents());
325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!view_core.is_null()) {
326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    Java_DownloadController_onDangerousDownload(
327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        env, GetJavaObject()->Controller(env).obj(), view_core.obj(),
328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        jfilename.obj(), item->GetId());
329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ScopedJavaLocalRef<jobject> DownloadControllerAndroidImpl::GetContentView(
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int render_process_id, int render_view_id) {
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RenderViewHost* render_view_host =
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      RenderViewHost::FromID(render_process_id, render_view_id);
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!render_view_host)
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ScopedJavaLocalRef<jobject>();
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebContents* web_contents =
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      render_view_host->GetDelegate()->GetAsWebContents();
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GetContentViewCoreFromWebContents(web_contents);
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ScopedJavaLocalRef<jobject>
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DownloadControllerAndroidImpl::GetContentViewCoreFromWebContents(
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebContents* web_contents) {
349a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (!web_contents)
350a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    return ScopedJavaLocalRef<jobject>();
351a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ContentViewCore* view_core = ContentViewCore::FromWebContents(web_contents);
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return view_core ? view_core->GetJavaObject() :
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ScopedJavaLocalRef<jobject>();
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DownloadControllerAndroidImpl::JavaObject*
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DownloadControllerAndroidImpl::GetJavaObject() {
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!java_object_) {
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Initialize Java DownloadController by calling
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // DownloadController.getInstance(), which will call Init()
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // if Java DownloadController is not instantiated already.
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    JNIEnv* env = base::android::AttachCurrentThread();
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Java_DownloadController_getInstance(env);
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(java_object_);
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return java_object_;
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void DownloadControllerAndroidImpl::StartContextMenuDownload(
372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const ContextMenuParams& params, WebContents* web_contents, bool is_link) {
373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const GURL& url = is_link ? params.link_url : params.src_url;
374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const GURL& referrer = params.frame_url.is_empty() ?
375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      params.page_url : params.frame_url;
376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DownloadManagerImpl* dlm = static_cast<DownloadManagerImpl*>(
377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      BrowserContext::GetDownloadManager(web_contents->GetBrowserContext()));
378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<DownloadUrlParameters> dl_params(
379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      DownloadUrlParameters::FromWebContents(web_contents, url));
380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  dl_params->set_referrer(
381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      Referrer(referrer, params.referrer_policy));
382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (is_link)
383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    dl_params->set_referrer_encoding(params.frame_charset);
384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  else
385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    dl_params->set_prefer_cache(true);
386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  dl_params->set_prompt(false);
387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  dlm->DownloadUrl(dl_params.Pass());
388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void DownloadControllerAndroidImpl::DangerousDownloadValidated(
391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    WebContents* web_contents, int download_id, bool accept) {
392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!web_contents)
393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DownloadManagerImpl* dlm = static_cast<DownloadManagerImpl*>(
395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      BrowserContext::GetDownloadManager(web_contents->GetBrowserContext()));
396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DownloadItem* item = dlm->GetDownload(download_id);
397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!item)
398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (accept)
400868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    item->ValidateDangerousDownload();
401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  else
402868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    item->Remove();
403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DownloadControllerAndroidImpl::DownloadInfoAndroid::DownloadInfoAndroid(
4065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    net::URLRequest* request)
4075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    : has_user_gesture(false) {
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request->GetResponseHeaderByName("content-disposition", &content_disposition);
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (request->response_headers())
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    request->response_headers()->GetMimeType(&original_mime_type);
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request->extra_request_headers().GetHeader(
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      net::HttpRequestHeaders::kUserAgent, &user_agent);
415c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GURL referer_url(request->referrer());
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (referer_url.is_valid())
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    referer = referer_url.spec();
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!request->url_chain().empty()) {
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    original_url = request->url_chain().front();
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    url = request->url_chain().back();
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const content::ResourceRequestInfo* info =
4245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      content::ResourceRequestInfo::ForRequest(request);
4255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (info)
4265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    has_user_gesture = info->HasUserGesture();
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DownloadControllerAndroidImpl::DownloadInfoAndroid::~DownloadInfoAndroid() {}
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace content
432