diff options
Diffstat (limited to 'src/com/android/providers/downloads/DownloadProvider.java')
-rw-r--r-- | src/com/android/providers/downloads/DownloadProvider.java | 89 |
1 files changed, 56 insertions, 33 deletions
diff --git a/src/com/android/providers/downloads/DownloadProvider.java b/src/com/android/providers/downloads/DownloadProvider.java index e0b5842d..ad3cf7ac 100644 --- a/src/com/android/providers/downloads/DownloadProvider.java +++ b/src/com/android/providers/downloads/DownloadProvider.java @@ -35,7 +35,9 @@ import android.database.sqlite.SQLiteOpenHelper; import android.net.Uri; import android.os.Binder; import android.os.Environment; +import android.os.Handler; import android.os.ParcelFileDescriptor; +import android.os.ParcelFileDescriptor.OnCloseListener; import android.os.Process; import android.os.SELinux; import android.provider.BaseColumns; @@ -49,6 +51,8 @@ import com.android.internal.util.IndentingPrintWriter; import com.google.android.collect.Maps; import com.google.common.annotations.VisibleForTesting; +import libcore.io.IoUtils; + import java.io.File; import java.io.FileDescriptor; import java.io.FileNotFoundException; @@ -69,7 +73,7 @@ public final class DownloadProvider extends ContentProvider { /** Database filename */ private static final String DB_NAME = "downloads.db"; /** Current database version */ - private static final int DB_VERSION = 108; + private static final int DB_VERSION = 109; /** Name of table in the database */ private static final String DB_TABLE = "downloads"; @@ -166,6 +170,8 @@ public final class DownloadProvider extends ContentProvider { private static final List<String> downloadManagerColumnsList = Arrays.asList(DownloadManager.UNDERLYING_COLUMNS); + private Handler mHandler; + /** The database that lies underneath this content provider */ private SQLiteOpenHelper mOpenHelper = null; @@ -319,6 +325,11 @@ public final class DownloadProvider extends ContentProvider { "INTEGER NOT NULL DEFAULT 1"); break; + case 109: + addColumn(db, DB_TABLE, Downloads.Impl.COLUMN_ALLOW_WRITE, + "BOOLEAN NOT NULL DEFAULT 0"); + break; + default: throw new IllegalStateException("Don't know how to upgrade to " + version); } @@ -432,6 +443,8 @@ public final class DownloadProvider extends ContentProvider { mSystemFacade = new RealSystemFacade(getContext()); } + mHandler = new Handler(); + mOpenHelper = new DatabaseHelper(getContext()); // Initialize the system uid mSystemUid = Process.SYSTEM_UID; @@ -590,6 +603,7 @@ public final class DownloadProvider extends ContentProvider { filteredValues.put(Downloads.Impl.COLUMN_CURRENT_BYTES, 0); copyInteger(Downloads.Impl.COLUMN_MEDIA_SCANNED, values, filteredValues); copyString(Downloads.Impl._DATA, values, filteredValues); + copyBoolean(Downloads.Impl.COLUMN_ALLOW_WRITE, values, filteredValues); } else { filteredValues.put(Downloads.Impl.COLUMN_STATUS, Downloads.Impl.STATUS_PENDING); filteredValues.put(Downloads.Impl.COLUMN_TOTAL_BYTES, -1); @@ -669,23 +683,12 @@ public final class DownloadProvider extends ContentProvider { } insertRequestHeaders(db, rowID, values); - /* - * requests coming from - * DownloadManager.addCompletedDownload(String, String, String, - * boolean, String, String, long) need special treatment - */ - Context context = getContext(); - if (values.getAsInteger(Downloads.Impl.COLUMN_DESTINATION) == - Downloads.Impl.DESTINATION_NON_DOWNLOADMANAGER_DOWNLOAD) { - // When notification is requested, kick off service to process all - // relevant downloads. - if (Downloads.Impl.isNotificationToBeDisplayed(vis)) { - context.startService(new Intent(context, DownloadService.class)); - } - } else { - context.startService(new Intent(context, DownloadService.class)); - } notifyContentChanged(uri, match); + + // Always start service to handle notifications and/or scanning + final Context context = getContext(); + context.startService(new Intent(context, DownloadService.class)); + return ContentUris.withAppendedId(Downloads.Impl.CONTENT_URI, rowID); } @@ -784,6 +787,7 @@ public final class DownloadProvider extends ContentProvider { values.remove(Downloads.Impl.COLUMN_ALLOW_METERED); values.remove(Downloads.Impl.COLUMN_IS_VISIBLE_IN_DOWNLOADS_UI); values.remove(Downloads.Impl.COLUMN_MEDIA_SCANNED); + values.remove(Downloads.Impl.COLUMN_ALLOW_WRITE); Iterator<Map.Entry<String, Object>> iterator = values.valueSet().iterator(); while (iterator.hasNext()) { String key = iterator.next().getKey(); @@ -1147,6 +1151,19 @@ public final class DownloadProvider extends ContentProvider { case ALL_DOWNLOADS_ID: SqlSelection selection = getWhereClause(uri, where, whereArgs, match); deleteRequestHeaders(db, selection.getSelection(), selection.getParameters()); + + final Cursor cursor = db.query(DB_TABLE, new String[] { + Downloads.Impl._ID }, selection.getSelection(), selection.getParameters(), + null, null, null); + try { + while (cursor.moveToNext()) { + final long id = cursor.getLong(0); + DownloadStorageProvider.onDownloadProviderDelete(getContext(), id); + } + } finally { + IoUtils.closeQuietly(cursor); + } + count = db.delete(DB_TABLE, selection.getSelection(), selection.getParameters()); break; @@ -1162,12 +1179,12 @@ public final class DownloadProvider extends ContentProvider { * Remotely opens a file */ @Override - public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException { + public ParcelFileDescriptor openFile(final Uri uri, String mode) throws FileNotFoundException { if (Constants.LOGVV) { logVerboseOpenFileInfo(uri, mode); } - Cursor cursor = query(uri, new String[] {"_data"}, null, null, null); + final Cursor cursor = query(uri, new String[] { Downloads.Impl._DATA }, null, null, null); String path; try { int count = (cursor != null) ? cursor.getCount() : 0; @@ -1182,9 +1199,7 @@ public final class DownloadProvider extends ContentProvider { cursor.moveToFirst(); path = cursor.getString(0); } finally { - if (cursor != null) { - cursor.close(); - } + IoUtils.closeQuietly(cursor); } if (path == null) { @@ -1193,20 +1208,28 @@ public final class DownloadProvider extends ContentProvider { if (!Helpers.isFilenameValid(path, mDownloadsDataDir)) { throw new FileNotFoundException("Invalid filename: " + path); } - if (!"r".equals(mode)) { - throw new FileNotFoundException("Bad mode for " + uri + ": " + mode); - } - - ParcelFileDescriptor ret = ParcelFileDescriptor.open(new File(path), - ParcelFileDescriptor.MODE_READ_ONLY); - if (ret == null) { - if (Constants.LOGV) { - Log.v(Constants.TAG, "couldn't open file"); + final File file = new File(path); + if ("r".equals(mode)) { + return ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY); + } else { + try { + // When finished writing, update size and timestamp + return ParcelFileDescriptor.open(file, ParcelFileDescriptor.parseMode(mode), + mHandler, new OnCloseListener() { + @Override + public void onClose(IOException e) { + final ContentValues values = new ContentValues(); + values.put(Downloads.Impl.COLUMN_TOTAL_BYTES, file.length()); + values.put(Downloads.Impl.COLUMN_LAST_MODIFICATION, + System.currentTimeMillis()); + update(uri, values, null, null); + } + }); + } catch (IOException e) { + throw new FileNotFoundException("Failed to open for writing: " + e); } - throw new FileNotFoundException("couldn't open file"); } - return ret; } @Override |