| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 package org.chromium.chrome.browser.download; | 5 package org.chromium.chrome.browser.download; |
| 6 | 6 |
| 7 import android.Manifest.permission; | 7 import android.Manifest.permission; |
| 8 import android.app.Activity; | |
| 9 import android.app.DownloadManager; | 8 import android.app.DownloadManager; |
| 10 import android.content.Context; | 9 import android.content.Context; |
| 11 import android.content.pm.PackageManager; | 10 import android.content.pm.PackageManager; |
| 12 import android.net.Uri; | 11 import android.net.Uri; |
| 13 import android.os.AsyncTask; | 12 import android.os.AsyncTask; |
| 14 import android.os.Environment; | 13 import android.os.Environment; |
| 15 import android.os.Handler; | |
| 16 import android.text.TextUtils; | 14 import android.text.TextUtils; |
| 17 import android.webkit.MimeTypeMap; | 15 import android.webkit.MimeTypeMap; |
| 18 import android.webkit.URLUtil; | 16 import android.webkit.URLUtil; |
| 19 | 17 |
| 20 import org.chromium.base.Log; | 18 import org.chromium.base.Log; |
| 21 import org.chromium.base.ThreadUtils; | 19 import org.chromium.base.ThreadUtils; |
| 22 import org.chromium.base.annotations.CalledByNative; | 20 import org.chromium.base.annotations.CalledByNative; |
| 23 import org.chromium.chrome.browser.ChromeActivity; | |
| 24 import org.chromium.chrome.browser.UrlConstants; | 21 import org.chromium.chrome.browser.UrlConstants; |
| 25 import org.chromium.chrome.browser.tab.EmptyTabObserver; | 22 import org.chromium.chrome.browser.tab.EmptyTabObserver; |
| 26 import org.chromium.chrome.browser.tab.Tab; | 23 import org.chromium.chrome.browser.tab.Tab; |
| 27 import org.chromium.chrome.browser.tabmodel.TabModelSelector; | |
| 28 import org.chromium.content_public.browser.WebContents; | 24 import org.chromium.content_public.browser.WebContents; |
| 29 import org.chromium.ui.base.WindowAndroid; | 25 import org.chromium.ui.base.WindowAndroid; |
| 30 import org.chromium.ui.base.WindowAndroid.PermissionCallback; | 26 import org.chromium.ui.base.WindowAndroid.PermissionCallback; |
| 31 | 27 |
| 32 import java.io.File; | 28 import java.io.File; |
| 33 | 29 |
| 34 /** | 30 /** |
| 35 * Chrome implementation of the ContentViewDownloadDelegate interface. | 31 * Chrome implementation of the ContentViewDownloadDelegate interface. |
| 36 * | 32 * |
| 37 * Listens to POST and GET download events. GET download requests are passed alo
ng to the | 33 * Listens to POST and GET download events. GET download requests are passed alo
ng to the |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 180 } | 176 } |
| 181 | 177 |
| 182 @Override | 178 @Override |
| 183 public void onPostExecute(Void args) { | 179 public void onPostExecute(Void args) { |
| 184 enqueueDownloadManagerRequest(downloadInfo); | 180 enqueueDownloadManagerRequest(downloadInfo); |
| 185 } | 181 } |
| 186 }.execute(); | 182 }.execute(); |
| 187 } else { | 183 } else { |
| 188 enqueueDownloadManagerRequest(downloadInfo); | 184 enqueueDownloadManagerRequest(downloadInfo); |
| 189 } | 185 } |
| 190 return closeBlankTab(); | 186 return DownloadController.closeTabIfBlank(mTab); |
| 191 } | 187 } |
| 192 | 188 |
| 193 private void launchDownloadInfoBar(DownloadInfo info, File fullDirPath) { | 189 private void launchDownloadInfoBar(DownloadInfo info, File fullDirPath) { |
| 194 if (mTab == null) return; | 190 if (mTab == null) return; |
| 195 nativeLaunchDuplicateDownloadInfoBar(ChromeDownloadDelegate.this, mTab,
info, | 191 nativeLaunchDuplicateDownloadInfoBar(ChromeDownloadDelegate.this, mTab,
info, |
| 196 new File(fullDirPath, info.getFileName()).toString(), mTab.isInc
ognito()); | 192 new File(fullDirPath, info.getFileName()).toString(), mTab.isInc
ognito()); |
| 197 } | 193 } |
| 198 | 194 |
| 199 /** | 195 /** |
| 200 * Enqueue a request to download a file using Android DownloadManager. | 196 * Enqueue a request to download a file using Android DownloadManager. |
| 201 * | 197 * |
| 202 * @param info Download information about the download. | 198 * @param info Download information about the download. |
| 203 */ | 199 */ |
| 204 private void enqueueDownloadManagerRequest(final DownloadInfo info) { | 200 private void enqueueDownloadManagerRequest(final DownloadInfo info) { |
| 205 DownloadManagerService.getDownloadManagerService().enqueueDownloadManage
rRequest( | 201 DownloadManagerService.getDownloadManagerService().enqueueDownloadManage
rRequest( |
| 206 new DownloadItem(true, info), true); | 202 new DownloadItem(true, info), true); |
| 207 closeBlankTab(); | 203 DownloadController.closeTabIfBlank(mTab); |
| 208 } | 204 } |
| 209 | 205 |
| 210 /** | 206 /** |
| 211 * Check the external storage and notify user on error. | 207 * Check the external storage and notify user on error. |
| 212 * | 208 * |
| 213 * @param fullDirPath The dir path to download a file. Normally this is exte
rnal storage. | 209 * @param fullDirPath The dir path to download a file. Normally this is exte
rnal storage. |
| 214 * @param externalStorageStatus The status of the external storage. | 210 * @param externalStorageStatus The status of the external storage. |
| 215 * @return Whether external storage is ok for downloading. | 211 * @return Whether external storage is ok for downloading. |
| 216 */ | 212 */ |
| 217 private boolean checkExternalStorageAndNotify( | 213 private boolean checkExternalStorageAndNotify( |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 265 .setFileName(fileName) | 261 .setFileName(fileName) |
| 266 .setMimeType(mimeType) | 262 .setMimeType(mimeType) |
| 267 .setCookie(cookie) | 263 .setCookie(cookie) |
| 268 .setReferrer(referrer) | 264 .setReferrer(referrer) |
| 269 .setIsGETRequest(true) | 265 .setIsGETRequest(true) |
| 270 .build(); | 266 .build(); |
| 271 enqueueDownloadManagerRequest(downloadInfo); | 267 enqueueDownloadManagerRequest(downloadInfo); |
| 272 } | 268 } |
| 273 | 269 |
| 274 /** | 270 /** |
| 275 * Called when download starts. | |
| 276 * | |
| 277 * @param filename Name of the file. | |
| 278 * @param mimeType MIME type of the content. | |
| 279 */ | |
| 280 @CalledByNative | |
| 281 private void onDownloadStarted(String filename) { | |
| 282 DownloadUtils.showDownloadStartToast(mContext); | |
| 283 new Handler().post(new Runnable() { | |
| 284 @Override | |
| 285 public void run() { | |
| 286 closeBlankTab(); | |
| 287 } | |
| 288 }); | |
| 289 } | |
| 290 | |
| 291 /** | |
| 292 * If the given MIME type is null, or one of the "generic" types (text/plain | 271 * If the given MIME type is null, or one of the "generic" types (text/plain |
| 293 * or application/octet-stream) map it to a type that Android can deal with. | 272 * or application/octet-stream) map it to a type that Android can deal with. |
| 294 * If the given type is not generic, return it unchanged. | 273 * If the given type is not generic, return it unchanged. |
| 295 * | 274 * |
| 296 * We have to implement this ourselves as | 275 * We have to implement this ourselves as |
| 297 * MimeTypeMap.remapGenericMimeType() is not public. | 276 * MimeTypeMap.remapGenericMimeType() is not public. |
| 298 * See http://crbug.com/407829. | 277 * See http://crbug.com/407829. |
| 299 * | 278 * |
| 300 * @param mimeType MIME type provided by the server. | 279 * @param mimeType MIME type provided by the server. |
| 301 * @param url URL of the data being loaded. | 280 * @param url URL of the data being loaded. |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 354 File file = new File(filepath); | 333 File file = new File(filepath); |
| 355 if (file.exists() && !file.delete()) { | 334 if (file.exists() && !file.delete()) { |
| 356 Log.e(TAG, "Error discarding file: " + filepath); | 335 Log.e(TAG, "Error discarding file: " + filepath); |
| 357 } | 336 } |
| 358 return null; | 337 return null; |
| 359 } | 338 } |
| 360 }.execute(); | 339 }.execute(); |
| 361 } | 340 } |
| 362 | 341 |
| 363 /** | 342 /** |
| 364 * Close a blank tab just opened for the download purpose. | |
| 365 * @return true iff the tab was (already) closed. | |
| 366 */ | |
| 367 private boolean closeBlankTab() { | |
| 368 if (mTab == null) { | |
| 369 // We do not want caller to dismiss infobar. | |
| 370 return true; | |
| 371 } | |
| 372 WebContents contents = mTab.getWebContents(); | |
| 373 boolean isInitialNavigation = contents == null | |
| 374 || contents.getNavigationController().isInitialNavigation(); | |
| 375 if (isInitialNavigation) { | |
| 376 // Tab is created just for download, close it. | |
| 377 Activity activity = mTab.getWindowAndroid().getActivity().get(); | |
| 378 if (!(activity instanceof ChromeActivity)) return true; | |
| 379 | |
| 380 TabModelSelector selector = ((ChromeActivity) activity).getTabModelS
elector(); | |
| 381 if (mTab.isIncognito() && selector.getModel(true).getCount() == 1) r
eturn false; | |
| 382 return selector == null ? true : selector.closeTab(mTab); | |
| 383 } | |
| 384 return false; | |
| 385 } | |
| 386 | |
| 387 /** | |
| 388 * For certain download types(OMA for example), android DownloadManager shou
ld | 343 * For certain download types(OMA for example), android DownloadManager shou
ld |
| 389 * handle them. Call this function to intercept those downloads. | 344 * handle them. Call this function to intercept those downloads. |
| 390 * | 345 * |
| 391 * @param url URL to be downloaded. | 346 * @param url URL to be downloaded. |
| 392 * @return whether the DownloadManager should intercept the download. | 347 * @return whether the DownloadManager should intercept the download. |
| 393 */ | 348 */ |
| 394 public boolean shouldInterceptContextMenuDownload(String url) { | 349 public boolean shouldInterceptContextMenuDownload(String url) { |
| 395 Uri uri = Uri.parse(url); | 350 Uri uri = Uri.parse(url); |
| 396 String scheme = uri.normalizeScheme().getScheme(); | 351 String scheme = uri.normalizeScheme().getScheme(); |
| 397 if (!UrlConstants.HTTP_SCHEME.equals(scheme) && !UrlConstants.HTTPS_SCHE
ME.equals(scheme)) { | 352 if (!UrlConstants.HTTP_SCHEME.equals(scheme) && !UrlConstants.HTTPS_SCHE
ME.equals(scheme)) { |
| (...skipping 30 matching lines...) Expand all Loading... |
| 428 | 383 |
| 429 protected Context getContext() { | 384 protected Context getContext() { |
| 430 return mContext; | 385 return mContext; |
| 431 } | 386 } |
| 432 | 387 |
| 433 private native void nativeInit(WebContents webContents); | 388 private native void nativeInit(WebContents webContents); |
| 434 private static native String nativeGetDownloadWarningText(String filename); | 389 private static native String nativeGetDownloadWarningText(String filename); |
| 435 private static native void nativeLaunchDuplicateDownloadInfoBar(ChromeDownlo
adDelegate delegate, | 390 private static native void nativeLaunchDuplicateDownloadInfoBar(ChromeDownlo
adDelegate delegate, |
| 436 Tab tab, DownloadInfo downloadInfo, String filePath, boolean isIncog
nito); | 391 Tab tab, DownloadInfo downloadInfo, String filePath, boolean isIncog
nito); |
| 437 } | 392 } |
| OLD | NEW |