diff options
Diffstat (limited to 'src/com/android/providers/downloads/Helpers.java')
-rw-r--r-- | src/com/android/providers/downloads/Helpers.java | 107 |
1 files changed, 57 insertions, 50 deletions
diff --git a/src/com/android/providers/downloads/Helpers.java b/src/com/android/providers/downloads/Helpers.java index d8f262c7..1e07d421 100644 --- a/src/com/android/providers/downloads/Helpers.java +++ b/src/com/android/providers/downloads/Helpers.java @@ -91,26 +91,26 @@ public class Helpers { /* * Don't download files that we won't be able to handle */ - if (destination == Downloads.DESTINATION_EXTERNAL - || destination == Downloads.DESTINATION_CACHE_PARTITION_PURGEABLE) { + if (destination == Downloads.Impl.DESTINATION_EXTERNAL + || destination == Downloads.Impl.DESTINATION_CACHE_PARTITION_PURGEABLE) { if (mimeType == null) { if (Config.LOGD) { Log.d(Constants.TAG, "external download with no mime type not allowed"); } - return new DownloadFileInfo(null, null, Downloads.STATUS_NOT_ACCEPTABLE); + return new DownloadFileInfo(null, null, Downloads.Impl.STATUS_NOT_ACCEPTABLE); } if (!DrmRawContent.DRM_MIMETYPE_MESSAGE_STRING.equalsIgnoreCase(mimeType)) { // Check to see if we are allowed to download this file. Only files // that can be handled by the platform can be downloaded. // special case DRM files, which we should always allow downloading. Intent intent = new Intent(Intent.ACTION_VIEW); - + // We can provide data as either content: or file: URIs, // so allow both. (I think it would be nice if we just did // everything as content: URIs) // Actually, right now the download manager's UId restrictions // prevent use from using content: so it's got to be file: or - // nothing + // nothing PackageManager pm = context.getPackageManager(); intent.setDataAndType(Uri.fromParts("file", "", null), mimeType); @@ -121,7 +121,7 @@ public class Helpers { if (Config.LOGD) { Log.d(Constants.TAG, "no handler found for type " + mimeType); } - return new DownloadFileInfo(null, null, Downloads.STATUS_NOT_ACCEPTABLE); + return new DownloadFileInfo(null, null, Downloads.Impl.STATUS_NOT_ACCEPTABLE); } } } @@ -148,10 +148,11 @@ public class Helpers { StatFs stat = null; // DRM messages should be temporarily stored internally and then passed to // the DRM content provider - if (destination == Downloads.DESTINATION_CACHE_PARTITION - || destination == Downloads.DESTINATION_CACHE_PARTITION_PURGEABLE - || destination == Downloads.DESTINATION_CACHE_PARTITION_NOROAMING + if (destination == Downloads.Impl.DESTINATION_CACHE_PARTITION + || destination == Downloads.Impl.DESTINATION_CACHE_PARTITION_PURGEABLE + || destination == Downloads.Impl.DESTINATION_CACHE_PARTITION_NOROAMING || DrmRawContent.DRM_MIMETYPE_MESSAGE_STRING.equalsIgnoreCase(mimeType)) { + // Saving to internal storage. base = Environment.getDownloadCacheDirectory(); stat = new StatFs(base.getPath()); @@ -160,52 +161,58 @@ public class Helpers { * Put a bit of margin (in case creating the file grows the system by a few blocks). */ int blockSize = stat.getBlockSize(); - for (;;) { - int availableBlocks = stat.getAvailableBlocks(); - if (blockSize * ((long) availableBlocks - 4) >= contentLength) { - break; - } - if (!discardPurgeableFiles(context, - contentLength - blockSize * ((long) availableBlocks - 4))) { + long bytesAvailable = blockSize * ((long) stat.getAvailableBlocks() - 4); + while (bytesAvailable < contentLength) { + // Insufficient space; try discarding purgeable files. + if (!discardPurgeableFiles(context, contentLength - bytesAvailable)) { + // No files to purge, give up. if (Config.LOGD) { Log.d(Constants.TAG, "download aborted - not enough free space in internal storage"); } - return new DownloadFileInfo(null, null, Downloads.STATUS_FILE_ERROR); - } - stat.restat(base.getPath()); - } - - } else { - if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { - String root = Environment.getExternalStorageDirectory().getPath(); - base = new File(root + Constants.DEFAULT_DL_SUBDIR); - if (!base.isDirectory() && !base.mkdir()) { - if (Config.LOGD) { - Log.d(Constants.TAG, "download aborted - can't create base directory " - + base.getPath()); - } - return new DownloadFileInfo(null, null, Downloads.STATUS_FILE_ERROR); - } - stat = new StatFs(base.getPath()); - } else { - if (Config.LOGD) { - Log.d(Constants.TAG, "download aborted - no external storage"); + return new DownloadFileInfo(null, null, + Downloads.Impl.STATUS_INSUFFICIENT_SPACE_ERROR); + } else { + // Recalculate available space and try again. + stat.restat(base.getPath()); + bytesAvailable = blockSize * ((long) stat.getAvailableBlocks() - 4); } - return new DownloadFileInfo(null, null, Downloads.STATUS_FILE_ERROR); } + } else if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { + // Saving to external storage (SD card). + String root = Environment.getExternalStorageDirectory().getPath(); + stat = new StatFs(root); /* * Check whether there's enough space on the target filesystem to save the file. * Put a bit of margin (in case creating the file grows the system by a few blocks). */ if (stat.getBlockSize() * ((long) stat.getAvailableBlocks() - 4) < contentLength) { + // Insufficient space. if (Config.LOGD) { Log.d(Constants.TAG, "download aborted - not enough free space"); } - return new DownloadFileInfo(null, null, Downloads.STATUS_FILE_ERROR); + return new DownloadFileInfo(null, null, + Downloads.Impl.STATUS_INSUFFICIENT_SPACE_ERROR); } + base = new File(root + Constants.DEFAULT_DL_SUBDIR); + if (!base.isDirectory() && !base.mkdir()) { + // Can't create download directory, e.g. because a file called "download" + // already exists at the root level, or the SD card filesystem is read-only. + if (Config.LOGD) { + Log.d(Constants.TAG, "download aborted - can't create base directory " + + base.getPath()); + } + return new DownloadFileInfo(null, null, Downloads.Impl.STATUS_FILE_ERROR); + } + } else { + // No SD card found. + if (Config.LOGD) { + Log.d(Constants.TAG, "download aborted - no external storage"); + } + return new DownloadFileInfo(null, null, + Downloads.Impl.STATUS_DEVICE_NOT_FOUND_ERROR); } boolean recoveryDir = Constants.RECOVERY_DIRECTORY.equalsIgnoreCase(filename + extension); @@ -224,7 +231,7 @@ public class Helpers { if (fullFilename != null) { return new DownloadFileInfo(fullFilename, new FileOutputStream(fullFilename), 0); } else { - return new DownloadFileInfo(null, null, Downloads.STATUS_FILE_ERROR); + return new DownloadFileInfo(null, null, Downloads.Impl.STATUS_FILE_ERROR); } } @@ -380,9 +387,9 @@ public class Helpers { String fullFilename = filename + extension; if (!new File(fullFilename).exists() && (!recoveryDir || - (destination != Downloads.DESTINATION_CACHE_PARTITION && - destination != Downloads.DESTINATION_CACHE_PARTITION_PURGEABLE && - destination != Downloads.DESTINATION_CACHE_PARTITION_NOROAMING))) { + (destination != Downloads.Impl.DESTINATION_CACHE_PARTITION && + destination != Downloads.Impl.DESTINATION_CACHE_PARTITION_PURGEABLE && + destination != Downloads.Impl.DESTINATION_CACHE_PARTITION_NOROAMING))) { return fullFilename; } filename = filename + Constants.FILENAME_SEQUENCE_SEPARATOR; @@ -423,14 +430,14 @@ public class Helpers { */ public static final boolean discardPurgeableFiles(Context context, long targetBytes) { Cursor cursor = context.getContentResolver().query( - Downloads.CONTENT_URI, + Downloads.Impl.CONTENT_URI, null, "( " + - Downloads.COLUMN_STATUS + " = '" + Downloads.STATUS_SUCCESS + "' AND " + - Downloads.COLUMN_DESTINATION + - " = '" + Downloads.DESTINATION_CACHE_PARTITION_PURGEABLE + "' )", + Downloads.Impl.COLUMN_STATUS + " = '" + Downloads.Impl.STATUS_SUCCESS + "' AND " + + Downloads.Impl.COLUMN_DESTINATION + + " = '" + Downloads.Impl.DESTINATION_CACHE_PARTITION_PURGEABLE + "' )", null, - Downloads.COLUMN_LAST_MODIFICATION); + Downloads.Impl.COLUMN_LAST_MODIFICATION); if (cursor == null) { return false; } @@ -438,16 +445,16 @@ public class Helpers { try { cursor.moveToFirst(); while (!cursor.isAfterLast() && totalFreed < targetBytes) { - File file = new File(cursor.getString(cursor.getColumnIndex(Downloads._DATA))); + File file = new File(cursor.getString(cursor.getColumnIndex(Downloads.Impl._DATA))); if (Constants.LOGVV) { Log.v(Constants.TAG, "purging " + file.getAbsolutePath() + " for " + file.length() + " bytes"); } totalFreed += file.length(); file.delete(); - long id = cursor.getLong(cursor.getColumnIndex(Downloads._ID)); + long id = cursor.getLong(cursor.getColumnIndex(Downloads.Impl._ID)); context.getContentResolver().delete( - ContentUris.withAppendedId(Downloads.CONTENT_URI, id), null, null); + ContentUris.withAppendedId(Downloads.Impl.CONTENT_URI, id), null, null); cursor.moveToNext(); } } finally { |