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; | 8 import android.app.Activity; |
9 import android.app.DownloadManager; | 9 import android.app.DownloadManager; |
10 import android.content.Context; | 10 import android.content.Context; |
11 import android.content.DialogInterface; | 11 import android.content.DialogInterface; |
12 import android.content.pm.PackageManager; | 12 import android.content.pm.PackageManager; |
13 import android.net.Uri; | 13 import android.net.Uri; |
14 import android.os.AsyncTask; | 14 import android.os.AsyncTask; |
15 import android.os.Environment; | 15 import android.os.Environment; |
16 import android.support.v7.app.AlertDialog; | 16 import android.support.v7.app.AlertDialog; |
17 import android.text.TextUtils; | 17 import android.text.TextUtils; |
18 import android.util.Pair; | |
19 import android.view.View; | 18 import android.view.View; |
20 import android.webkit.MimeTypeMap; | 19 import android.webkit.MimeTypeMap; |
21 import android.webkit.URLUtil; | 20 import android.webkit.URLUtil; |
22 import android.widget.TextView; | 21 import android.widget.TextView; |
23 | 22 |
24 import org.chromium.base.Log; | 23 import org.chromium.base.Log; |
25 import org.chromium.base.ThreadUtils; | 24 import org.chromium.base.ThreadUtils; |
26 import org.chromium.base.annotations.CalledByNative; | 25 import org.chromium.base.annotations.CalledByNative; |
27 import org.chromium.chrome.R; | 26 import org.chromium.chrome.R; |
28 import org.chromium.chrome.browser.ChromeActivity; | 27 import org.chromium.chrome.browser.ChromeActivity; |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
78 protected void onDownloadStartNoStream(final DownloadInfo downloadInfo) { | 77 protected void onDownloadStartNoStream(final DownloadInfo downloadInfo) { |
79 final String fileName = downloadInfo.getFileName(); | 78 final String fileName = downloadInfo.getFileName(); |
80 assert !TextUtils.isEmpty(fileName); | 79 assert !TextUtils.isEmpty(fileName); |
81 final String newMimeType = | 80 final String newMimeType = |
82 remapGenericMimeType(downloadInfo.getMimeType(), downloadInfo.ge
tUrl(), fileName); | 81 remapGenericMimeType(downloadInfo.getMimeType(), downloadInfo.ge
tUrl(), fileName); |
83 new AsyncTask<Void, Void, Object[]>() { | 82 new AsyncTask<Void, Void, Object[]>() { |
84 @Override | 83 @Override |
85 protected Object[] doInBackground(Void... params) { | 84 protected Object[] doInBackground(Void... params) { |
86 // Check to see if we have an SDCard. | 85 // Check to see if we have an SDCard. |
87 String status = Environment.getExternalStorageState(); | 86 String status = Environment.getExternalStorageState(); |
88 Pair<String, String> result = getDownloadDirectoryNameAndFullPat
h(); | 87 File fullDirPath = getDownloadDirectoryFullPath(); |
89 String dirName = result.first; | 88 boolean fileExists = checkFileExists(fullDirPath, fileName); |
90 String fullDirPath = result.second; | |
91 boolean fileExists = doesFileAlreadyExists(fullDirPath, fileName
); | |
92 | 89 |
93 return new Object[] {status, dirName, fullDirPath, fileExists}; | 90 return new Object[] {status, fullDirPath, fileExists}; |
94 } | 91 } |
95 | 92 |
96 @Override | 93 @Override |
97 protected void onPostExecute(Object[] result) { | 94 protected void onPostExecute(Object[] result) { |
98 String externalStorageState = (String) result[0]; | 95 String externalStorageState = (String) result[0]; |
99 String dirName = (String) result[1]; | 96 File fullDirPath = (File) result[1]; |
100 String fullDirPath = (String) result[2]; | 97 Boolean fileExists = (Boolean) result[2]; |
101 Boolean fileExists = (Boolean) result[3]; | |
102 if (!checkExternalStorageAndNotify( | 98 if (!checkExternalStorageAndNotify( |
103 fileName, fullDirPath, externalStorageState)) { | 99 fileName, fullDirPath, externalStorageState)) { |
104 return; | 100 return; |
105 } | 101 } |
106 String url = sanitizeDownloadUrl(downloadInfo); | 102 String url = sanitizeDownloadUrl(downloadInfo); |
107 if (url == null) return; | 103 if (url == null) return; |
108 DownloadInfo newInfo = DownloadInfo.Builder.fromDownloadInfo(dow
nloadInfo) | 104 DownloadInfo newInfo = DownloadInfo.Builder.fromDownloadInfo(dow
nloadInfo) |
109 .setUrl(url) | 105 .setUrl(url) |
110 .setMimeType(newMimeType) | 106 .setMimeType(newMimeType) |
111 .setDescription(url) | 107 .setDescription(url) |
112 .setFileName(fileName) | 108 .setFileName(fileName) |
113 .setIsGETRequest(true) | 109 .setIsGETRequest(true) |
114 .build(); | 110 .build(); |
115 | 111 |
116 // TODO(acleung): This is a temp fix to disable auto downloading
if flash files. | 112 // TODO(acleung): This is a temp fix to disable auto downloading
if flash files. |
117 // We want to avoid downloading flash files when it is linked as
an iframe. | 113 // We want to avoid downloading flash files when it is linked as
an iframe. |
118 // The proper fix would be to let chrome knows which frame origi
nated the request. | 114 // The proper fix would be to let chrome knows which frame origi
nated the request. |
119 if ("application/x-shockwave-flash".equals(newInfo.getMimeType()
)) return; | 115 if ("application/x-shockwave-flash".equals(newInfo.getMimeType()
)) return; |
120 | 116 |
121 // Not a dangerous file, proceed. | 117 // Not a dangerous file, proceed. |
122 if (fileExists) { | 118 if (fileExists) { |
123 launchDownloadInfoBar(newInfo, dirName, fullDirPath); | 119 launchDownloadInfoBar(newInfo, fullDirPath); |
124 } else { | 120 } else { |
125 enqueueDownloadManagerRequest(newInfo); | 121 enqueueDownloadManagerRequest(newInfo); |
126 } | 122 } |
127 } | 123 } |
128 }.execute(); | 124 }.execute(); |
129 } | 125 } |
130 | 126 |
131 /** | 127 /** |
132 * Sanitize the URL for the download item. | 128 * Sanitize the URL for the download item. |
133 * | 129 * |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
189 builder.create().show(); | 185 builder.create().show(); |
190 } else if (!mTab.getWindowAndroid().isPermissionRevokedByPolicy(storageP
ermission)) { | 186 } else if (!mTab.getWindowAndroid().isPermissionRevokedByPolicy(storageP
ermission)) { |
191 nativeLaunchPermissionUpdateInfoBar(mTab, storagePermission, callbac
kId); | 187 nativeLaunchPermissionUpdateInfoBar(mTab, storagePermission, callbac
kId); |
192 } else { | 188 } else { |
193 // TODO(tedchoc): Show toast. | 189 // TODO(tedchoc): Show toast. |
194 DownloadController.getInstance().onRequestFileAccessResult(callbackI
d, false); | 190 DownloadController.getInstance().onRequestFileAccessResult(callbackI
d, false); |
195 } | 191 } |
196 } | 192 } |
197 | 193 |
198 /** | 194 /** |
199 * Return a pair of directory name and its full path. Note that we create th
e directory if | 195 * Return the full path of the download directory. |
200 * it does not already exist. | |
201 * | 196 * |
202 * @return A pair of directory name and its full path. A pair of <null, null
> will be returned | 197 * @return File object containing the path to the download directory. |
203 * in case of an error. | |
204 */ | 198 */ |
205 private static Pair<String, String> getDownloadDirectoryNameAndFullPath() { | 199 private static File getDownloadDirectoryFullPath() { |
206 assert !ThreadUtils.runningOnUiThread(); | 200 assert !ThreadUtils.runningOnUiThread(); |
207 File dir = Environment.getExternalStoragePublicDirectory(Environment.DIR
ECTORY_DOWNLOADS); | 201 File dir = Environment.getExternalStoragePublicDirectory(Environment.DIR
ECTORY_DOWNLOADS); |
208 if (!dir.mkdir() && !dir.isDirectory()) return new Pair<>(null, null); | 202 if (!dir.mkdir() && !dir.isDirectory()) return null; |
209 String dirName = dir.getName(); | 203 return dir; |
210 String fullDirPath = dir.getPath(); | |
211 return new Pair<>(dirName, fullDirPath); | |
212 } | 204 } |
213 | 205 |
214 private static boolean doesFileAlreadyExists(String dirPath, final String fi
leName) { | 206 private static boolean checkFileExists(File dirPath, final String fileName)
{ |
215 assert !ThreadUtils.runningOnUiThread(); | 207 assert !ThreadUtils.runningOnUiThread(); |
216 final File file = new File(dirPath, fileName); | 208 final File file = new File(dirPath, fileName); |
217 return file != null && file.exists(); | 209 return file != null && file.exists(); |
218 } | 210 } |
219 | 211 |
220 private static void deleteFileForOverwrite(DownloadInfo info) { | 212 private static void deleteFileForOverwrite(DownloadInfo info) { |
221 assert !ThreadUtils.runningOnUiThread(); | 213 assert !ThreadUtils.runningOnUiThread(); |
222 File dir = Environment.getExternalStoragePublicDirectory(Environment.DIR
ECTORY_DOWNLOADS); | 214 File dir = Environment.getExternalStoragePublicDirectory(Environment.DIR
ECTORY_DOWNLOADS); |
223 if (!dir.isDirectory()) return; | 215 if (!dir.isDirectory()) return; |
224 final File file = new File(dir, info.getFileName()); | 216 final File file = new File(dir, info.getFileName()); |
(...skipping 27 matching lines...) Expand all Loading... |
252 public void onPostExecute(Void args) { | 244 public void onPostExecute(Void args) { |
253 enqueueDownloadManagerRequest(downloadInfo); | 245 enqueueDownloadManagerRequest(downloadInfo); |
254 } | 246 } |
255 }.execute(); | 247 }.execute(); |
256 } else { | 248 } else { |
257 enqueueDownloadManagerRequest(downloadInfo); | 249 enqueueDownloadManagerRequest(downloadInfo); |
258 } | 250 } |
259 return closeBlankTab(); | 251 return closeBlankTab(); |
260 } | 252 } |
261 | 253 |
262 private void launchDownloadInfoBar(DownloadInfo info, String dirName, String
fullDirPath) { | 254 private void launchDownloadInfoBar(DownloadInfo info, File fullDirPath) { |
263 if (mTab == null) return; | 255 if (mTab == null) return; |
264 nativeLaunchDownloadOverwriteInfoBar( | 256 nativeLaunchDuplicateDownloadInfoBar(ChromeDownloadDelegate.this, mTab,
info, |
265 ChromeDownloadDelegate.this, mTab, info, info.getFileName(), dir
Name, fullDirPath); | 257 new File(fullDirPath, info.getFileName()).toString(), mTab.isInc
ognito()); |
266 } | 258 } |
267 | 259 |
268 /** | 260 /** |
269 * Enqueue a request to download a file using Android DownloadManager. | 261 * Enqueue a request to download a file using Android DownloadManager. |
270 * | 262 * |
271 * @param info Download information about the download. | 263 * @param info Download information about the download. |
272 */ | 264 */ |
273 private void enqueueDownloadManagerRequest(final DownloadInfo info) { | 265 private void enqueueDownloadManagerRequest(final DownloadInfo info) { |
274 DownloadManagerService.getDownloadManagerService( | 266 DownloadManagerService.getDownloadManagerService( |
275 mContext.getApplicationContext()).enqueueDownloadManagerRequest( | 267 mContext.getApplicationContext()).enqueueDownloadManagerRequest( |
276 new DownloadItem(true, info), true); | 268 new DownloadItem(true, info), true); |
277 closeBlankTab(); | 269 closeBlankTab(); |
278 } | 270 } |
279 | 271 |
280 /** | 272 /** |
281 * Check the external storage and notify user on error. | 273 * Check the external storage and notify user on error. |
282 * | 274 * |
283 * @param fullDirPath The dir path to download a file. Normally this is exte
rnal storage. | 275 * @param fullDirPath The dir path to download a file. Normally this is exte
rnal storage. |
284 * @param externalStorageStatus The status of the external storage. | 276 * @param externalStorageStatus The status of the external storage. |
285 * @return Whether external storage is ok for downloading. | 277 * @return Whether external storage is ok for downloading. |
286 */ | 278 */ |
287 private boolean checkExternalStorageAndNotify( | 279 private boolean checkExternalStorageAndNotify( |
288 String filename, String fullDirPath, String externalStorageStatus) { | 280 String filename, File fullDirPath, String externalStorageStatus) { |
289 if (fullDirPath == null) { | 281 if (fullDirPath == null) { |
290 Log.e(TAG, "Download failed: no SD card"); | 282 Log.e(TAG, "Download failed: no SD card"); |
291 alertDownloadFailure( | 283 alertDownloadFailure( |
292 filename, DownloadManager.ERROR_DEVICE_NOT_FOUND); | 284 filename, DownloadManager.ERROR_DEVICE_NOT_FOUND); |
293 return false; | 285 return false; |
294 } | 286 } |
295 if (!externalStorageStatus.equals(Environment.MEDIA_MOUNTED)) { | 287 if (!externalStorageStatus.equals(Environment.MEDIA_MOUNTED)) { |
296 int reason = DownloadManager.ERROR_DEVICE_NOT_FOUND; | 288 int reason = DownloadManager.ERROR_DEVICE_NOT_FOUND; |
297 // Check to see if the SDCard is busy, same as the music app | 289 // Check to see if the SDCard is busy, same as the music app |
298 if (externalStorageStatus.equals(Environment.MEDIA_SHARED)) { | 290 if (externalStorageStatus.equals(Environment.MEDIA_SHARED)) { |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
477 return true; | 469 return true; |
478 } | 470 } |
479 | 471 |
480 protected Context getContext() { | 472 protected Context getContext() { |
481 return mContext; | 473 return mContext; |
482 } | 474 } |
483 | 475 |
484 private native void nativeInit(WebContents webContents); | 476 private native void nativeInit(WebContents webContents); |
485 private static native String nativeGetDownloadWarningText(String filename); | 477 private static native String nativeGetDownloadWarningText(String filename); |
486 private static native boolean nativeIsDownloadDangerous(String filename); | 478 private static native boolean nativeIsDownloadDangerous(String filename); |
487 private static native void nativeLaunchDownloadOverwriteInfoBar(ChromeDownlo
adDelegate delegate, | 479 private static native void nativeLaunchDuplicateDownloadInfoBar(ChromeDownlo
adDelegate delegate, |
488 Tab tab, DownloadInfo downloadInfo, String fileName, String dirName, | 480 Tab tab, DownloadInfo downloadInfo, String filePath, boolean isIncog
nito); |
489 String dirFullPath); | |
490 private static native void nativeLaunchPermissionUpdateInfoBar( | 481 private static native void nativeLaunchPermissionUpdateInfoBar( |
491 Tab tab, String permission, long callbackId); | 482 Tab tab, String permission, long callbackId); |
492 } | 483 } |
OLD | NEW |