Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 "chrome/browser/android/download/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 "chrome/browser/android/download/chrome_download_delegate.h" |
| 19 #include "content/browser/android/deferred_download_observer.h" | 19 #include "chrome/common/chrome_content_client.h" |
| 20 #include "content/browser/download/download_item_impl.h" | |
| 21 #include "content/browser/download/download_manager_impl.h" | |
| 22 #include "content/browser/loader/resource_dispatcher_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" | |
| 25 #include "content/browser/renderer_host/render_view_host_impl.h" | |
| 26 #include "content/browser/web_contents/web_contents_impl.h" | |
| 27 #include "content/public/browser/browser_context.h" | 20 #include "content/public/browser/browser_context.h" |
| 28 #include "content/public/browser/browser_thread.h" | 21 #include "content/public/browser/browser_thread.h" |
| 22 #include "content/public/browser/download_manager.h" | |
| 29 #include "content/public/browser/download_url_parameters.h" | 23 #include "content/public/browser/download_url_parameters.h" |
| 30 #include "content/public/browser/global_request_id.h" | 24 #include "content/public/browser/global_request_id.h" |
| 25 #include "content/public/browser/render_process_host.h" | |
| 26 #include "content/public/browser/render_view_host.h" | |
| 27 #include "content/public/browser/resource_dispatcher_host.h" | |
| 31 #include "content/public/browser/resource_request_info.h" | 28 #include "content/public/browser/resource_request_info.h" |
| 32 #include "content/public/common/content_client.h" | |
| 33 #include "content/public/common/referrer.h" | 29 #include "content/public/common/referrer.h" |
| 34 #include "jni/DownloadController_jni.h" | 30 #include "jni/DownloadController_jni.h" |
| 35 #include "net/base/filename_util.h" | 31 #include "net/base/filename_util.h" |
| 36 #include "net/cookies/cookie_options.h" | 32 #include "net/cookies/cookie_options.h" |
| 37 #include "net/cookies/cookie_store.h" | 33 #include "net/cookies/cookie_store.h" |
| 38 #include "net/http/http_content_disposition.h" | 34 #include "net/http/http_content_disposition.h" |
| 39 #include "net/http/http_request_headers.h" | 35 #include "net/http/http_request_headers.h" |
| 40 #include "net/http/http_response_headers.h" | 36 #include "net/http/http_response_headers.h" |
| 41 #include "net/url_request/url_request.h" | 37 #include "net/url_request/url_request.h" |
| 42 #include "net/url_request/url_request_context.h" | 38 #include "net/url_request/url_request_context.h" |
| 39 #include "ui/android/view_android.h" | |
| 40 #include "ui/android/window_android.h" | |
| 43 | 41 |
| 44 using base::android::ConvertUTF8ToJavaString; | 42 using base::android::ConvertUTF8ToJavaString; |
| 45 using base::android::ScopedJavaLocalRef; | 43 using base::android::ScopedJavaLocalRef; |
| 44 using content::BrowserContext; | |
| 45 using content::BrowserThread; | |
| 46 using content::ContextMenuParams; | |
| 47 using content::DownloadItem; | |
| 48 using content::DownloadManager; | |
| 49 using content::GlobalRequestID; | |
| 50 using content::ResourceDispatcherHost; | |
| 51 using content::ResourceRequestInfo; | |
| 52 using content::WebContents; | |
| 46 | 53 |
| 47 namespace { | 54 namespace { |
| 48 // Guards download_controller_ | 55 // Guards download_controller_ |
| 49 base::LazyInstance<base::Lock> g_download_controller_lock_; | 56 base::LazyInstance<base::Lock> g_download_controller_lock_; |
| 50 | 57 |
| 51 content::WebContents* GetWebContents(int render_process_id, | 58 WebContents* GetWebContents(int render_process_id, int render_view_id) { |
| 52 int render_view_id) { | |
| 53 content::RenderViewHost* render_view_host = | 59 content::RenderViewHost* render_view_host = |
| 54 content::RenderViewHost::FromID(render_process_id, render_view_id); | 60 content::RenderViewHost::FromID(render_process_id, render_view_id); |
| 55 | 61 |
| 56 if (!render_view_host) | 62 if (!render_view_host) |
| 57 return nullptr; | 63 return nullptr; |
| 58 | 64 |
| 59 return content::WebContents::FromRenderViewHost(render_view_host); | 65 return WebContents::FromRenderViewHost(render_view_host); |
| 60 } | 66 } |
| 61 | 67 |
| 62 void CreateContextMenuDownload(int render_process_id, | 68 void CreateContextMenuDownload(int render_process_id, |
| 63 int render_view_id, | 69 int render_view_id, |
| 64 const content::ContextMenuParams& params, | 70 const content::ContextMenuParams& params, |
| 65 bool is_link, | 71 bool is_link, |
| 66 const std::string& extra_headers, | 72 const std::string& extra_headers, |
| 67 bool granted) { | 73 bool granted) { |
| 68 if (!granted) | 74 if (!granted) |
| 69 return; | 75 return; |
| 70 | 76 |
| 71 content::WebContents* web_contents = | 77 content::WebContents* web_contents = |
| 72 GetWebContents(render_process_id, render_view_id); | 78 GetWebContents(render_process_id, render_view_id); |
| 73 if (!web_contents) | 79 if (!web_contents) |
| 74 return; | 80 return; |
| 75 | 81 |
| 76 const GURL& url = is_link ? params.link_url : params.src_url; | 82 const GURL& url = is_link ? params.link_url : params.src_url; |
| 77 const GURL& referring_url = | 83 const GURL& referring_url = |
| 78 params.frame_url.is_empty() ? params.page_url : params.frame_url; | 84 params.frame_url.is_empty() ? params.page_url : params.frame_url; |
| 79 content::DownloadManagerImpl* dlm = | 85 content::DownloadManager* dlm = |
| 80 static_cast<content::DownloadManagerImpl*>( | 86 content::BrowserContext::GetDownloadManager( |
| 81 content::BrowserContext::GetDownloadManager( | 87 web_contents->GetBrowserContext()); |
| 82 web_contents->GetBrowserContext())); | |
| 83 std::unique_ptr<content::DownloadUrlParameters> dl_params( | 88 std::unique_ptr<content::DownloadUrlParameters> dl_params( |
| 84 content::DownloadUrlParameters::CreateForWebContentsMainFrame( | 89 content::DownloadUrlParameters::CreateForWebContentsMainFrame( |
| 85 web_contents, url)); | 90 web_contents, url)); |
| 86 content::Referrer referrer = content::Referrer::SanitizeForRequest( | 91 content::Referrer referrer = content::Referrer::SanitizeForRequest( |
| 87 url, | 92 url, |
| 88 content::Referrer(referring_url.GetAsReferrer(), params.referrer_policy)); | 93 content::Referrer(referring_url.GetAsReferrer(), params.referrer_policy)); |
| 89 dl_params->set_referrer(referrer); | 94 dl_params->set_referrer(referrer); |
| 90 if (is_link) | 95 if (is_link) |
| 91 dl_params->set_referrer_encoding(params.frame_charset); | 96 dl_params->set_referrer_encoding(params.frame_charset); |
| 92 net::HttpRequestHeaders headers; | 97 net::HttpRequestHeaders headers; |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 105 DCHECK_NE(interrupt_reason, content::DOWNLOAD_INTERRUPT_REASON_NONE); | 110 DCHECK_NE(interrupt_reason, content::DOWNLOAD_INTERRUPT_REASON_NONE); |
| 106 return | 111 return |
| 107 interrupt_reason == content::DOWNLOAD_INTERRUPT_REASON_NETWORK_TIMEOUT || | 112 interrupt_reason == content::DOWNLOAD_INTERRUPT_REASON_NETWORK_TIMEOUT || |
| 108 interrupt_reason == content::DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED || | 113 interrupt_reason == content::DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED || |
| 109 interrupt_reason == | 114 interrupt_reason == |
| 110 content::DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED; | 115 content::DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED; |
| 111 } | 116 } |
| 112 | 117 |
| 113 } // namespace | 118 } // namespace |
| 114 | 119 |
| 115 namespace content { | |
| 116 | |
| 117 // JNI methods | 120 // JNI methods |
| 118 static void Init(JNIEnv* env, const JavaParamRef<jobject>& obj) { | 121 static void Init(JNIEnv* env, const JavaParamRef<jobject>& obj) { |
| 119 DownloadControllerAndroidImpl::GetInstance()->Init(env, obj); | 122 DownloadControllerAndroidImpl::GetInstance()->Init(env, obj); |
| 120 } | 123 } |
| 121 | 124 |
| 122 static void OnRequestFileAccessResult(JNIEnv* env, | 125 static void OnRequestFileAccessResult(JNIEnv* env, |
| 123 const JavaParamRef<jobject>& obj, | 126 const JavaParamRef<jobject>& obj, |
| 124 jlong callback_id, | 127 jlong callback_id, |
| 125 jboolean granted) { | 128 jboolean granted) { |
| 126 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 129 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 148 } | 151 } |
| 149 | 152 |
| 150 // static | 153 // static |
| 151 DownloadControllerAndroid* DownloadControllerAndroid::Get() { | 154 DownloadControllerAndroid* DownloadControllerAndroid::Get() { |
| 152 base::AutoLock lock(g_download_controller_lock_.Get()); | 155 base::AutoLock lock(g_download_controller_lock_.Get()); |
| 153 if (!DownloadControllerAndroid::download_controller_) | 156 if (!DownloadControllerAndroid::download_controller_) |
| 154 download_controller_ = DownloadControllerAndroidImpl::GetInstance(); | 157 download_controller_ = DownloadControllerAndroidImpl::GetInstance(); |
| 155 return DownloadControllerAndroid::download_controller_; | 158 return DownloadControllerAndroid::download_controller_; |
| 156 } | 159 } |
| 157 | 160 |
| 158 //static | 161 // static |
| 159 void DownloadControllerAndroid::SetDownloadControllerAndroid( | 162 void DownloadControllerAndroid::SetDownloadControllerAndroid( |
| 160 DownloadControllerAndroid* download_controller) { | 163 DownloadControllerAndroid* download_controller) { |
| 161 base::AutoLock lock(g_download_controller_lock_.Get()); | 164 base::AutoLock lock(g_download_controller_lock_.Get()); |
| 162 DownloadControllerAndroid::download_controller_ = download_controller; | 165 DownloadControllerAndroid::download_controller_ = download_controller; |
| 163 } | 166 } |
| 164 | 167 |
| 165 // static | 168 // static |
| 166 DownloadControllerAndroidImpl* DownloadControllerAndroidImpl::GetInstance() { | 169 DownloadControllerAndroidImpl* DownloadControllerAndroidImpl::GetInstance() { |
| 167 return base::Singleton<DownloadControllerAndroidImpl>::get(); | 170 return base::Singleton<DownloadControllerAndroidImpl>::get(); |
| 168 } | 171 } |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 179 base::android::CheckException(env); | 182 base::android::CheckException(env); |
| 180 } | 183 } |
| 181 } | 184 } |
| 182 | 185 |
| 183 // Initialize references to Java object. | 186 // Initialize references to Java object. |
| 184 void DownloadControllerAndroidImpl::Init(JNIEnv* env, jobject obj) { | 187 void DownloadControllerAndroidImpl::Init(JNIEnv* env, jobject obj) { |
| 185 java_object_ = new JavaObject; | 188 java_object_ = new JavaObject; |
| 186 java_object_->obj = env->NewWeakGlobalRef(obj); | 189 java_object_->obj = env->NewWeakGlobalRef(obj); |
| 187 } | 190 } |
| 188 | 191 |
| 189 void DownloadControllerAndroidImpl::CancelDeferredDownload( | |
| 190 DeferredDownloadObserver* observer) { | |
| 191 for (auto iter = deferred_downloads_.begin(); | |
| 192 iter != deferred_downloads_.end(); ++iter) { | |
| 193 if (*iter == observer) { | |
| 194 deferred_downloads_.erase(iter); | |
| 195 return; | |
| 196 } | |
| 197 } | |
| 198 } | |
| 199 | |
| 200 void DownloadControllerAndroidImpl::AcquireFileAccessPermission( | 192 void DownloadControllerAndroidImpl::AcquireFileAccessPermission( |
| 201 WebContents* web_contents, | 193 WebContents* web_contents, |
| 202 const DownloadControllerAndroid::AcquireFileAccessPermissionCallback& cb) { | 194 const DownloadControllerAndroid::AcquireFileAccessPermissionCallback& cb) { |
| 203 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 195 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 204 DCHECK(web_contents); | 196 DCHECK(web_contents); |
| 205 | 197 |
| 206 ScopedJavaLocalRef<jobject> view = | 198 ui::WindowAndroid* window_android = |
| 207 GetContentViewCoreFromWebContents(web_contents); | 199 ViewAndroidHelper::FromWebContents(web_contents)-> |
| 208 if (view.is_null()) { | 200 GetViewAndroid()->GetWindowAndroid(); |
| 209 BrowserThread::PostTask( | 201 if (HasFileAccessPermission(window_android)) { |
|
no sievers
2016/06/07 21:35:23
|window_android| can be null (with custom tabs), s
Jinsuk Kim
2016/06/08 06:29:08
Done.
| |
| 210 BrowserThread::UI, FROM_HERE, base::Bind(cb, false)); | |
| 211 return; | |
| 212 } | |
| 213 | |
| 214 if (HasFileAccessPermission(view)) { | |
| 215 BrowserThread::PostTask( | 202 BrowserThread::PostTask( |
| 216 BrowserThread::UI, FROM_HERE, base::Bind(cb, true)); | 203 BrowserThread::UI, FROM_HERE, base::Bind(cb, true)); |
| 217 return; | 204 return; |
| 218 } | 205 } |
| 219 | |
| 220 JNIEnv* env = base::android::AttachCurrentThread(); | |
| 221 // Make copy on the heap so we can pass the pointer through JNI. | 206 // Make copy on the heap so we can pass the pointer through JNI. |
| 222 intptr_t callback_id = reinterpret_cast<intptr_t>( | 207 intptr_t callback_id = reinterpret_cast<intptr_t>( |
| 223 new DownloadControllerAndroid::AcquireFileAccessPermissionCallback(cb)); | 208 new DownloadControllerAndroid::AcquireFileAccessPermissionCallback(cb)); |
| 224 Java_DownloadController_requestFileAccess( | 209 ChromeDownloadDelegate::FromWebContents(web_contents)-> |
| 225 env, GetJavaObject()->Controller(env).obj(), view.obj(), callback_id); | 210 RequestFileAccess(callback_id); |
| 226 } | 211 } |
| 227 | 212 |
| 228 void DownloadControllerAndroidImpl::SetDefaultDownloadFileName( | 213 void DownloadControllerAndroidImpl::SetDefaultDownloadFileName( |
| 229 const std::string& file_name) { | 214 const std::string& file_name) { |
| 230 default_file_name_ = file_name; | 215 default_file_name_ = file_name; |
| 231 } | 216 } |
| 232 | 217 |
| 233 bool DownloadControllerAndroidImpl::HasFileAccessPermission( | 218 bool DownloadControllerAndroidImpl::HasFileAccessPermission( |
| 234 ScopedJavaLocalRef<jobject> j_content_view_core) { | 219 ui::WindowAndroid* window_android) { |
| 220 ScopedJavaLocalRef<jobject> jwindow_android = window_android->GetJavaObject(); | |
| 221 | |
| 235 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 222 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 236 DCHECK(!j_content_view_core.is_null()); | 223 DCHECK(!jwindow_android.is_null()); |
| 237 | 224 |
| 238 JNIEnv* env = base::android::AttachCurrentThread(); | 225 JNIEnv* env = base::android::AttachCurrentThread(); |
| 239 return Java_DownloadController_hasFileAccess( | 226 return Java_DownloadController_hasFileAccess( |
| 240 env, GetJavaObject()->Controller(env).obj(), j_content_view_core.obj()); | 227 env, GetJavaObject()->Controller(env).obj(), jwindow_android.obj()); |
| 241 } | 228 } |
| 242 | 229 |
| 243 void DownloadControllerAndroidImpl::CreateGETDownload( | 230 void DownloadControllerAndroidImpl::CreateGETDownload( |
| 244 int render_process_id, int render_view_id, int request_id, | 231 int render_process_id, int render_view_id, int request_id, |
| 245 bool must_download) { | 232 bool must_download) { |
| 246 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 233 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 247 GlobalRequestID global_id(render_process_id, request_id); | 234 GlobalRequestID global_id(render_process_id, request_id); |
| 248 | 235 |
| 249 // We are yielding the UI thread and render_view_host may go away by | 236 // 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 | 237 // the time we come back. Pass along render_process_id and render_view_id |
| 251 // to retrieve it later (if it still exists). | 238 // to retrieve it later (if it still exists). |
| 252 GetDownloadInfoCB cb = base::Bind( | 239 GetDownloadInfoCB cb = base::Bind( |
| 253 &DownloadControllerAndroidImpl::StartAndroidDownload, | 240 &DownloadControllerAndroidImpl::StartAndroidDownload, |
| 254 base::Unretained(this), render_process_id, | 241 base::Unretained(this), render_process_id, |
| 255 render_view_id, must_download); | 242 render_view_id, must_download); |
| 256 | 243 |
| 257 PrepareDownloadInfo( | 244 PrepareDownloadInfo( |
| 258 global_id, | 245 global_id, |
| 259 base::Bind(&DownloadControllerAndroidImpl::StartDownloadOnUIThread, | 246 base::Bind(&DownloadControllerAndroidImpl::StartDownloadOnUIThread, |
| 260 base::Unretained(this), cb)); | 247 base::Unretained(this), cb)); |
| 261 } | 248 } |
| 262 | 249 |
| 263 void DownloadControllerAndroidImpl::PrepareDownloadInfo( | 250 void DownloadControllerAndroidImpl::PrepareDownloadInfo( |
| 264 const GlobalRequestID& global_id, | 251 const GlobalRequestID& global_id, |
| 265 const GetDownloadInfoCB& callback) { | 252 const GetDownloadInfoCB& callback) { |
| 266 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 253 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 267 | 254 |
| 268 net::URLRequest* request = | 255 net::URLRequest* request = |
| 269 ResourceDispatcherHostImpl::Get()->GetURLRequest(global_id); | 256 ResourceDispatcherHost::Get()->GetURLRequest(global_id); |
| 270 if (!request) { | 257 if (!request) { |
| 271 LOG(ERROR) << "Request to download not found."; | 258 LOG(ERROR) << "Request to download not found."; |
| 272 return; | 259 return; |
| 273 } | 260 } |
| 274 | 261 |
| 275 DownloadInfoAndroid info_android(request); | 262 DownloadInfoAndroid info_android(request); |
| 276 | 263 |
| 277 net::CookieStore* cookie_store = request->context()->cookie_store(); | 264 net::CookieStore* cookie_store = request->context()->cookie_store(); |
| 278 if (cookie_store) { | 265 if (cookie_store) { |
| 279 cookie_store->GetAllCookiesForURLAsync( | 266 cookie_store->GetAllCookiesForURLAsync( |
| 280 request->url(), | 267 request->url(), |
| 281 base::Bind(&DownloadControllerAndroidImpl::CheckPolicyAndLoadCookies, | 268 base::Bind(&DownloadControllerAndroidImpl::CheckPolicyAndLoadCookies, |
| 282 base::Unretained(this), info_android, callback, global_id)); | 269 base::Unretained(this), info_android, callback, global_id)); |
| 283 } else { | 270 } else { |
| 284 // Can't get any cookies, start android download. | 271 // Can't get any cookies, start android download. |
| 285 callback.Run(info_android); | 272 callback.Run(info_android); |
| 286 } | 273 } |
| 287 } | 274 } |
| 288 | 275 |
| 289 void DownloadControllerAndroidImpl::CheckPolicyAndLoadCookies( | 276 void DownloadControllerAndroidImpl::CheckPolicyAndLoadCookies( |
| 290 const DownloadInfoAndroid& info, const GetDownloadInfoCB& callback, | 277 const DownloadInfoAndroid& info, const GetDownloadInfoCB& callback, |
| 291 const GlobalRequestID& global_id, const net::CookieList& cookie_list) { | 278 const GlobalRequestID& global_id, const net::CookieList& cookie_list) { |
| 292 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 279 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 293 | 280 |
| 294 net::URLRequest* request = | 281 net::URLRequest* request = |
| 295 ResourceDispatcherHostImpl::Get()->GetURLRequest(global_id); | 282 ResourceDispatcherHost::Get()->GetURLRequest(global_id); |
| 296 if (!request) { | 283 if (!request) { |
| 297 LOG(ERROR) << "Request to download not found."; | 284 LOG(ERROR) << "Request to download not found."; |
| 298 return; | 285 return; |
| 299 } | 286 } |
| 300 | 287 |
| 301 if (request->context()->network_delegate()->CanGetCookies( | 288 if (request->context()->network_delegate()->CanGetCookies( |
| 302 *request, cookie_list)) { | 289 *request, cookie_list)) { |
| 303 DoLoadCookies(info, callback, global_id); | 290 DoLoadCookies(info, callback, global_id); |
| 304 } else { | 291 } else { |
| 305 callback.Run(info); | 292 callback.Run(info); |
| 306 } | 293 } |
| 307 } | 294 } |
| 308 | 295 |
| 309 void DownloadControllerAndroidImpl::DoLoadCookies( | 296 void DownloadControllerAndroidImpl::DoLoadCookies( |
| 310 const DownloadInfoAndroid& info, const GetDownloadInfoCB& callback, | 297 const DownloadInfoAndroid& info, const GetDownloadInfoCB& callback, |
| 311 const GlobalRequestID& global_id) { | 298 const GlobalRequestID& global_id) { |
| 312 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 299 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 313 | 300 |
| 314 net::CookieOptions options; | 301 net::CookieOptions options; |
| 315 options.set_include_httponly(); | 302 options.set_include_httponly(); |
| 316 | 303 |
| 317 net::URLRequest* request = | 304 net::URLRequest* request = |
| 318 ResourceDispatcherHostImpl::Get()->GetURLRequest(global_id); | 305 ResourceDispatcherHost::Get()->GetURLRequest(global_id); |
| 319 if (!request) { | 306 if (!request) { |
| 320 LOG(ERROR) << "Request to download not found."; | 307 LOG(ERROR) << "Request to download not found."; |
| 321 return; | 308 return; |
| 322 } | 309 } |
| 323 | 310 |
| 324 request->context()->cookie_store()->GetCookiesWithOptionsAsync( | 311 request->context()->cookie_store()->GetCookiesWithOptionsAsync( |
| 325 info.url, options, | 312 info.url, options, |
| 326 base::Bind(&DownloadControllerAndroidImpl::OnCookieResponse, | 313 base::Bind(&DownloadControllerAndroidImpl::OnCookieResponse, |
| 327 base::Unretained(this), info, callback)); | 314 base::Unretained(this), info, callback)); |
| 328 } | 315 } |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 349 int render_process_id, int render_view_id, bool must_download, | 336 int render_process_id, int render_view_id, bool must_download, |
| 350 const DownloadInfoAndroid& info) { | 337 const DownloadInfoAndroid& info) { |
| 351 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 338 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 352 | 339 |
| 353 WebContents* web_contents = GetWebContents(render_process_id, render_view_id); | 340 WebContents* web_contents = GetWebContents(render_process_id, render_view_id); |
| 354 if (!web_contents) { | 341 if (!web_contents) { |
| 355 // The view went away. Can't proceed. | 342 // The view went away. Can't proceed. |
| 356 LOG(ERROR) << "Download failed on URL:" << info.url.spec(); | 343 LOG(ERROR) << "Download failed on URL:" << info.url.spec(); |
| 357 return; | 344 return; |
| 358 } | 345 } |
| 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 | 346 |
| 373 AcquireFileAccessPermission( | 347 AcquireFileAccessPermission( |
| 374 web_contents, | 348 web_contents, |
| 375 base::Bind(&DownloadControllerAndroidImpl::StartAndroidDownloadInternal, | 349 base::Bind(&DownloadControllerAndroidImpl::StartAndroidDownloadInternal, |
| 376 base::Unretained(this), render_process_id, render_view_id, | 350 base::Unretained(this), render_process_id, render_view_id, |
| 377 must_download, info)); | 351 must_download, info)); |
| 378 } | 352 } |
| 379 | 353 |
| 380 void DownloadControllerAndroidImpl::StartAndroidDownloadInternal( | 354 void DownloadControllerAndroidImpl::StartAndroidDownloadInternal( |
| 381 int render_process_id, int render_view_id, bool must_download, | 355 int render_process_id, int render_view_id, bool must_download, |
| 382 const DownloadInfoAndroid& info, bool allowed) { | 356 const DownloadInfoAndroid& info, bool allowed) { |
| 383 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 357 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 384 if (!allowed) | 358 if (!allowed) |
| 385 return; | 359 return; |
| 386 | 360 |
| 387 // Call newHttpGetDownload | |
| 388 WebContents* web_contents = GetWebContents(render_process_id, render_view_id); | 361 WebContents* web_contents = GetWebContents(render_process_id, render_view_id); |
| 389 // The view went away. Can't proceed. | 362 // The view went away. Can't proceed. |
| 390 if (!web_contents) | 363 if (!web_contents) |
| 391 return; | 364 return; |
| 392 ScopedJavaLocalRef<jobject> view = | |
| 393 GetContentViewCoreFromWebContents(web_contents); | |
| 394 if (view.is_null()) | |
| 395 return; | |
| 396 | 365 |
| 397 JNIEnv* env = base::android::AttachCurrentThread(); | 366 base::string16 filename = net::GetSuggestedFilename( |
| 398 ScopedJavaLocalRef<jstring> jurl = | 367 info.url, info.content_disposition, |
| 399 ConvertUTF8ToJavaString(env, info.url.spec()); | 368 std::string(), // referrer_charset |
| 400 ScopedJavaLocalRef<jstring> juser_agent = | 369 std::string(), // suggested_name |
| 401 ConvertUTF8ToJavaString(env, info.user_agent); | 370 info.original_mime_type, |
| 402 ScopedJavaLocalRef<jstring> jcontent_disposition = | 371 default_file_name_); |
| 403 ConvertUTF8ToJavaString(env, info.content_disposition); | 372 ChromeDownloadDelegate::FromWebContents(web_contents)->RequestHTTPGetDownload( |
| 404 ScopedJavaLocalRef<jstring> jmime_type = | 373 info.url.spec(), info.user_agent, |
| 405 ConvertUTF8ToJavaString(env, info.original_mime_type); | 374 info.content_disposition, info.original_mime_type, |
| 406 ScopedJavaLocalRef<jstring> jcookie = | 375 info.cookie, info.referer, filename, |
| 407 ConvertUTF8ToJavaString(env, info.cookie); | 376 info.total_bytes, info.has_user_gesture, |
| 408 ScopedJavaLocalRef<jstring> jreferer = | 377 must_download); |
| 409 ConvertUTF8ToJavaString(env, info.referer); | |
| 410 | |
| 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 } | 378 } |
| 426 | 379 |
| 427 void DownloadControllerAndroidImpl::OnDownloadStarted( | 380 void DownloadControllerAndroidImpl::OnDownloadStarted( |
| 428 DownloadItem* download_item) { | 381 DownloadItem* download_item) { |
| 429 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 382 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 430 if (!download_item->GetWebContents()) | 383 WebContents* web_contents = download_item->GetWebContents(); |
| 384 if (!web_contents) | |
| 431 return; | 385 return; |
| 432 | 386 |
| 433 JNIEnv* env = base::android::AttachCurrentThread(); | |
| 434 | |
| 435 // Register for updates to the DownloadItem. | 387 // Register for updates to the DownloadItem. |
| 436 download_item->AddObserver(this); | 388 download_item->AddObserver(this); |
| 437 | 389 |
| 438 ScopedJavaLocalRef<jobject> view = | 390 ChromeDownloadDelegate::FromWebContents(web_contents)->OnDownloadStarted( |
| 439 GetContentViewCoreFromWebContents(download_item->GetWebContents()); | 391 download_item->GetTargetFilePath().BaseName().value(), |
| 440 // The view went away. Can't proceed. | 392 download_item->GetMimeType()); |
| 441 if (view.is_null()) | |
| 442 return; | |
| 443 | |
| 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 } | 393 } |
| 452 | 394 |
| 453 void DownloadControllerAndroidImpl::OnDownloadUpdated(DownloadItem* item) { | 395 void DownloadControllerAndroidImpl::OnDownloadUpdated(DownloadItem* item) { |
| 454 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 396 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 455 if (item->IsDangerous() && (item->GetState() != DownloadItem::CANCELLED)) | 397 if (item->IsDangerous() && (item->GetState() != DownloadItem::CANCELLED)) |
| 456 OnDangerousDownload(item); | 398 OnDangerousDownload(item); |
| 457 | 399 |
| 458 JNIEnv* env = base::android::AttachCurrentThread(); | 400 JNIEnv* env = base::android::AttachCurrentThread(); |
| 459 ScopedJavaLocalRef<jstring> jguid = | 401 ScopedJavaLocalRef<jstring> jguid = |
| 460 ConvertUTF8ToJavaString(env, item->GetGuid()); | 402 ConvertUTF8ToJavaString(env, item->GetGuid()); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 511 item->CanResume(), IsInterruptedDownloadAutoResumable(item), | 453 item->CanResume(), IsInterruptedDownloadAutoResumable(item), |
| 512 item->GetBrowserContext()->IsOffTheRecord()); | 454 item->GetBrowserContext()->IsOffTheRecord()); |
| 513 item->RemoveObserver(this); | 455 item->RemoveObserver(this); |
| 514 break; | 456 break; |
| 515 case DownloadItem::MAX_DOWNLOAD_STATE: | 457 case DownloadItem::MAX_DOWNLOAD_STATE: |
| 516 NOTREACHED(); | 458 NOTREACHED(); |
| 517 } | 459 } |
| 518 } | 460 } |
| 519 | 461 |
| 520 void DownloadControllerAndroidImpl::OnDangerousDownload(DownloadItem* item) { | 462 void DownloadControllerAndroidImpl::OnDangerousDownload(DownloadItem* item) { |
| 521 JNIEnv* env = base::android::AttachCurrentThread(); | 463 WebContents* web_contents = item->GetWebContents(); |
| 522 ScopedJavaLocalRef<jstring> jfilename = ConvertUTF8ToJavaString( | |
| 523 env, item->GetTargetFilePath().BaseName().value()); | |
| 524 ScopedJavaLocalRef<jstring> jguid = | |
| 525 ConvertUTF8ToJavaString(env, 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 } | |
| 534 | |
| 535 ScopedJavaLocalRef<jobject> | |
| 536 DownloadControllerAndroidImpl::GetContentViewCoreFromWebContents( | |
| 537 WebContents* web_contents) { | |
| 538 if (!web_contents) | 464 if (!web_contents) |
| 539 return ScopedJavaLocalRef<jobject>(); | 465 return; |
| 540 | 466 ChromeDownloadDelegate::FromWebContents(web_contents)->OnDownloadStarted( |
|
no sievers
2016/06/07 21:35:23
not OnDangerousDownload()?
Jinsuk Kim
2016/06/08 06:29:08
Thanks for catching. Done.
| |
| 541 ContentViewCore* view_core = ContentViewCore::FromWebContents(web_contents); | 467 item->GetTargetFilePath().BaseName().value(), item->GetGuid()); |
| 542 return view_core ? view_core->GetJavaObject() : | |
| 543 ScopedJavaLocalRef<jobject>(); | |
| 544 } | 468 } |
| 545 | 469 |
| 546 DownloadControllerAndroidImpl::JavaObject* | 470 DownloadControllerAndroidImpl::JavaObject* |
| 547 DownloadControllerAndroidImpl::GetJavaObject() { | 471 DownloadControllerAndroidImpl::GetJavaObject() { |
| 548 if (!java_object_) { | 472 if (!java_object_) { |
| 549 // Initialize Java DownloadController by calling | 473 // Initialize Java DownloadController by calling |
| 550 // DownloadController.getInstance(), which will call Init() | 474 // DownloadController.getInstance(), which will call Init() |
| 551 // if Java DownloadController is not instantiated already. | 475 // if Java DownloadController is not instantiated already. |
| 552 JNIEnv* env = base::android::AttachCurrentThread(); | 476 JNIEnv* env = base::android::AttachCurrentThread(); |
| 553 Java_DownloadController_getInstance(env); | 477 Java_DownloadController_getInstance(env); |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 566 web_contents, base::Bind(&CreateContextMenuDownload, process_id, | 490 web_contents, base::Bind(&CreateContextMenuDownload, process_id, |
| 567 routing_id, params, is_link, extra_headers)); | 491 routing_id, params, is_link, extra_headers)); |
| 568 } | 492 } |
| 569 | 493 |
| 570 void DownloadControllerAndroidImpl::DangerousDownloadValidated( | 494 void DownloadControllerAndroidImpl::DangerousDownloadValidated( |
| 571 WebContents* web_contents, | 495 WebContents* web_contents, |
| 572 const std::string& download_guid, | 496 const std::string& download_guid, |
| 573 bool accept) { | 497 bool accept) { |
| 574 if (!web_contents) | 498 if (!web_contents) |
| 575 return; | 499 return; |
| 576 DownloadManagerImpl* dlm = static_cast<DownloadManagerImpl*>( | 500 DownloadManager* dlm = |
| 577 BrowserContext::GetDownloadManager(web_contents->GetBrowserContext())); | 501 BrowserContext::GetDownloadManager(web_contents->GetBrowserContext()); |
| 578 DownloadItem* item = dlm->GetDownloadByGuid(download_guid); | 502 DownloadItem* item = dlm->GetDownloadByGuid(download_guid); |
| 579 if (!item) | 503 if (!item) |
| 580 return; | 504 return; |
| 581 if (accept) | 505 if (accept) |
| 582 item->ValidateDangerousDownload(); | 506 item->ValidateDangerousDownload(); |
| 583 else | 507 else |
| 584 item->Remove(); | 508 item->Remove(); |
| 585 } | 509 } |
| 586 | 510 |
| 587 DownloadControllerAndroidImpl::DownloadInfoAndroid::DownloadInfoAndroid( | 511 DownloadControllerAndroidImpl::DownloadInfoAndroid::DownloadInfoAndroid( |
| 588 net::URLRequest* request) | 512 net::URLRequest* request) |
| 589 : has_user_gesture(false) { | 513 : has_user_gesture(false) { |
| 590 request->GetResponseHeaderByName("content-disposition", &content_disposition); | 514 request->GetResponseHeaderByName("content-disposition", &content_disposition); |
| 591 | 515 |
| 592 if (request->response_headers()) | 516 if (request->response_headers()) |
| 593 request->response_headers()->GetMimeType(&original_mime_type); | 517 request->response_headers()->GetMimeType(&original_mime_type); |
| 594 | 518 |
| 595 request->extra_request_headers().GetHeader( | 519 request->extra_request_headers().GetHeader( |
| 596 net::HttpRequestHeaders::kUserAgent, &user_agent); | 520 net::HttpRequestHeaders::kUserAgent, &user_agent); |
| 597 if (user_agent.empty()) | 521 if (user_agent.empty()) |
| 598 user_agent = GetContentClient()->GetUserAgent(); | 522 user_agent = GetUserAgent(); |
| 599 GURL referer_url(request->referrer()); | 523 GURL referer_url(request->referrer()); |
| 600 if (referer_url.is_valid()) | 524 if (referer_url.is_valid()) |
| 601 referer = referer_url.spec(); | 525 referer = referer_url.spec(); |
| 602 if (!request->url_chain().empty()) { | 526 if (!request->url_chain().empty()) { |
| 603 original_url = request->url_chain().front(); | 527 original_url = request->url_chain().front(); |
| 604 url = request->url_chain().back(); | 528 url = request->url_chain().back(); |
| 605 } | 529 } |
| 606 | 530 |
| 607 const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request); | 531 const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request); |
| 608 if (info) | 532 if (info) |
| 609 has_user_gesture = info->HasUserGesture(); | 533 has_user_gesture = info->HasUserGesture(); |
| 610 } | 534 } |
| 611 | 535 |
| 612 DownloadControllerAndroidImpl::DownloadInfoAndroid::DownloadInfoAndroid( | 536 DownloadControllerAndroidImpl::DownloadInfoAndroid::DownloadInfoAndroid( |
| 613 const DownloadInfoAndroid& other) = default; | 537 const DownloadInfoAndroid& other) = default; |
| 614 | 538 |
| 615 DownloadControllerAndroidImpl::DownloadInfoAndroid::~DownloadInfoAndroid() {} | 539 DownloadControllerAndroidImpl::DownloadInfoAndroid::~DownloadInfoAndroid() {} |
| 616 | |
| 617 } // namespace content | |
| OLD | NEW |