summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorqqzhou <qqzhou@codeaurora.org>2013-12-05 17:02:33 +0800
committerAdnan <adnan@cyngn.com>2014-08-26 17:06:43 -0700
commitf668ad5ed0b6885052118725f360de5c68c96f36 (patch)
tree2611155cff1388a55b9df34bb36c9bff50bf92c3
parent58b97fe09205eea731f5a51d7be0a83230550ab8 (diff)
downloadandroid_packages_providers_DownloadProvider-f668ad5ed0b6885052118725f360de5c68c96f36.tar.gz
android_packages_providers_DownloadProvider-f668ad5ed0b6885052118725f360de5c68c96f36.tar.bz2
android_packages_providers_DownloadProvider-f668ad5ed0b6885052118725f360de5c68c96f36.zip
DownloadProvider: add to support download into sdcard storage
When insert into downloads database to start a new download, will check file uri destination is valid or not, currently it only support phone storage downloading, what we do is to add supporting sdcard storage downloading, this will make download save path setting feature work well. Change-Id: I7995ae63ec5769103d7ad66bcd677e383ef7f440
-rw-r--r--src/com/android/providers/downloads/DownloadProvider.java19
-rwxr-xr-xsrc/com/android/providers/downloads/DownloadThread.java2
-rw-r--r--src/com/android/providers/downloads/Helpers.java12
-rw-r--r--src/com/android/providers/downloads/StorageManager.java49
4 files changed, 66 insertions, 16 deletions
diff --git a/src/com/android/providers/downloads/DownloadProvider.java b/src/com/android/providers/downloads/DownloadProvider.java
index 0928fdfc..132deb9a 100644
--- a/src/com/android/providers/downloads/DownloadProvider.java
+++ b/src/com/android/providers/downloads/DownloadProvider.java
@@ -710,14 +710,15 @@ public final class DownloadProvider extends ContentProvider {
if (path == null) {
throw new IllegalArgumentException("Invalid file URI: " + uri);
}
- try {
- final String canonicalPath = new File(path).getCanonicalPath();
- final String externalPath = Environment.getExternalStorageDirectory().getAbsolutePath();
- if (!canonicalPath.startsWith(externalPath)) {
- throw new SecurityException("Destination must be on external storage: " + uri);
- }
- } catch (IOException e) {
- throw new SecurityException("Problem resolving path: " + uri);
+
+ final String phoneStoragePath = Environment.getExternalStorageDirectory().getAbsolutePath();
+ String sdCardStoragePath = null;
+ if (StorageManager.isSecondStorageSupported()) {
+ sdCardStoragePath = StorageManager.getExternalStorageDirectory(getContext());
+ }
+ if (!path.startsWith(phoneStoragePath)
+ && !(sdCardStoragePath != null && path.startsWith(sdCardStoragePath))) {
+ throw new SecurityException("Destination must be on external storage: " + uri);
}
}
@@ -1209,7 +1210,7 @@ public final class DownloadProvider extends ContentProvider {
if (path == null) {
throw new FileNotFoundException("No filename found.");
}
- if (!Helpers.isFilenameValid(path, mDownloadsDataDir)) {
+ if (!Helpers.isFilenameValid(getContext(), path, mDownloadsDataDir)) {
throw new FileNotFoundException("Invalid filename: " + path);
}
diff --git a/src/com/android/providers/downloads/DownloadThread.java b/src/com/android/providers/downloads/DownloadThread.java
index 9d5274c4..88cd9162 100755
--- a/src/com/android/providers/downloads/DownloadThread.java
+++ b/src/com/android/providers/downloads/DownloadThread.java
@@ -769,7 +769,7 @@ public class DownloadThread implements Runnable {
Log.i(Constants.TAG, "have run thread before for id: " + mInfo.mId +
", and state.mFilename: " + state.mFilename);
}
- if (!Helpers.isFilenameValid(state.mFilename,
+ if (!Helpers.isFilenameValid(mContext, state.mFilename,
mStorageManager.getDownloadDataDirectory())) {
// this should never happen
throw new StopRequestException(Downloads.Impl.STATUS_FILE_ERROR,
diff --git a/src/com/android/providers/downloads/Helpers.java b/src/com/android/providers/downloads/Helpers.java
index 3562dac7..d9b38b50 100644
--- a/src/com/android/providers/downloads/Helpers.java
+++ b/src/com/android/providers/downloads/Helpers.java
@@ -375,6 +375,18 @@ public class Helpers {
}
/**
+ * Checks whether the filename looks legitimate
+ */
+ static boolean isFilenameValid(Context context, String filename, File downloadsDataDir) {
+ filename = filename.replaceFirst("/+", "/"); // normalize leading slashes
+ return filename.startsWith(Environment.getDownloadCacheDirectory().toString())
+ || filename.startsWith(downloadsDataDir.toString())
+ || filename.startsWith(Environment.getExternalStorageDirectory().toString())
+ || (StorageManager.isSecondStorageSupported() && filename.startsWith(StorageManager
+ .getExternalStorageDirectory(context)));
+ }
+
+ /**
* Checks whether this looks like a legitimate selection parameter
*/
public static void validateSelection(String selection, Set<String> allowedColumns) {
diff --git a/src/com/android/providers/downloads/StorageManager.java b/src/com/android/providers/downloads/StorageManager.java
index deb412e7..a0ceae6a 100644
--- a/src/com/android/providers/downloads/StorageManager.java
+++ b/src/com/android/providers/downloads/StorageManager.java
@@ -19,6 +19,7 @@ package com.android.providers.downloads;
import static com.android.providers.downloads.Constants.LOGV;
import static com.android.providers.downloads.Constants.TAG;
+import android.app.Activity;
import android.content.ContentUris;
import android.content.Context;
import android.content.res.Resources;
@@ -27,6 +28,7 @@ import android.database.sqlite.SQLiteException;
import android.net.Uri;
import android.os.Environment;
import android.os.StatFs;
+import android.os.storage.StorageVolume;
import android.provider.Downloads;
import android.text.TextUtils;
import android.util.Log;
@@ -77,6 +79,8 @@ class StorageManager {
/** misc members */
private final Context mContext;
+ private static String sdCardStorageDir;
+ private static final String LOGTAG = "StorageManager";
public StorageManager(Context context) {
mContext = context;
@@ -84,6 +88,11 @@ class StorageManager {
mExternalStorageDir = Environment.getExternalStorageDirectory();
mSystemCacheDir = Environment.getDownloadCacheDirectory();
startThreadToCleanupDatabaseAndPurgeFileSystem();
+ if (isSecondStorageSupported()) {
+ sdCardStorageDir = getExternalStorageDirectory(context);
+ } else {
+ sdCardStorageDir = null;
+ }
}
/** How often should database and filesystem be cleaned up to remove spurious files
@@ -149,7 +158,9 @@ class StorageManager {
dir = mSystemCacheDir;
break;
case Downloads.Impl.DESTINATION_FILE_URI:
- if (path.startsWith(mExternalStorageDir.getPath())) {
+ if (isSecondStorageSupported() && path.startsWith(sdCardStorageDir)) {
+ dir = new File(sdCardStorageDir);
+ } else if (path.startsWith(mExternalStorageDir.getPath())) {
dir = mExternalStorageDir;
} else if (path.startsWith(mDownloadDataDir.getPath())) {
dir = mDownloadDataDir;
@@ -175,11 +186,13 @@ class StorageManager {
if (targetBytes == 0) {
return;
}
- if (destination == Downloads.Impl.DESTINATION_FILE_URI ||
- destination == Downloads.Impl.DESTINATION_EXTERNAL) {
- if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
- throw new StopRequestException(Downloads.Impl.STATUS_DEVICE_NOT_FOUND_ERROR,
- "external media not mounted");
+ if (!(isSecondStorageSupported() && root.getPath().startsWith(sdCardStorageDir))) {
+ if (destination == Downloads.Impl.DESTINATION_FILE_URI ||
+ destination == Downloads.Impl.DESTINATION_EXTERNAL) {
+ if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
+ throw new StopRequestException(Downloads.Impl.STATUS_DEVICE_NOT_FOUND_ERROR,
+ "external media not mounted");
+ }
}
}
// is there enough space in the file system of the given param 'root'.
@@ -469,4 +482,28 @@ class StorageManager {
private synchronized void resetBytesDownloadedSinceLastCheckOnSpace() {
mBytesDownloadedSinceLastCheckOnSpace = 0;
}
+
+ /**
+ * Whether support Second Storage
+ *
+ * @return boolean true support Second Storage, false will be not
+ */
+ public static boolean isSecondStorageSupported() {
+ return true;
+ }
+
+ public static String getExternalStorageDirectory(Context context) {
+ String sdCardDir = null;
+ android.os.storage.StorageManager storageManager =
+ (android.os.storage.StorageManager) context
+ .getSystemService(Context.STORAGE_SERVICE);
+ StorageVolume[] volumes = storageManager.getVolumeList();
+ for (int i = 0; i < volumes.length; i++) {
+ if (volumes[i].isRemovable() && volumes[i].allowMassStorage()) {
+ sdCardDir = volumes[i].getPath();
+ break;
+ }
+ }
+ return sdCardDir;
+ }
}