diff options
author | Steve Howard <showard@google.com> | 2010-09-16 13:58:30 -0700 |
---|---|---|
committer | Steve Howard <showard@google.com> | 2010-09-16 13:58:30 -0700 |
commit | 176a74426f750dc56e7d200a4cdc3b6ed75fe6cd (patch) | |
tree | 5e83e23318b22ce2877186a5b0aa9ab93978d4b7 /src | |
parent | 57df1b6a7219e049371cae72b36a63d04e214f59 (diff) | |
parent | 3d55d829c03fe78ad8cdab119293efb6c6e49c64 (diff) | |
download | android_packages_providers_DownloadProvider-176a74426f750dc56e7d200a4cdc3b6ed75fe6cd.tar.gz android_packages_providers_DownloadProvider-176a74426f750dc56e7d200a4cdc3b6ed75fe6cd.tar.bz2 android_packages_providers_DownloadProvider-176a74426f750dc56e7d200a4cdc3b6ed75fe6cd.zip |
resolved conflicts for merge of 3d55d829 to gingerbread-plus-aosp
Change-Id: I18ede2f2d5ad8aa40cd61bdb7213659d356fdf57
Diffstat (limited to 'src')
6 files changed, 236 insertions, 230 deletions
diff --git a/src/com/android/providers/downloads/DownloadInfo.java b/src/com/android/providers/downloads/DownloadInfo.java index 4380059b..0cf025b8 100644 --- a/src/com/android/providers/downloads/DownloadInfo.java +++ b/src/com/android/providers/downloads/DownloadInfo.java @@ -131,9 +131,8 @@ public class DownloadInfo { } private void readRequestHeaders(long downloadId) { - Uri headerUri = Downloads.Impl.CONTENT_URI.buildUpon() - .appendPath(Long.toString(downloadId)) - .appendPath(Downloads.Impl.RequestHeaders.URI_SEGMENT).build(); + Uri headerUri = Uri.withAppendedPath( + getAllDownloadsUri(), Downloads.Impl.RequestHeaders.URI_SEGMENT); Cursor cursor = mContext.getContentResolver().query(headerUri, null, null, null, null); try { int headerIndex = @@ -159,7 +158,7 @@ public class DownloadInfo { return Collections.unmodifiableMap(mRequestHeaders); } - public void sendIntentIfRequested(Uri contentUri) { + public void sendIntentIfRequested() { if (mPackage == null) { return; } @@ -181,7 +180,7 @@ public class DownloadInfo { // We only send the content: URI, for security reasons. Otherwise, malicious // applications would have an easier time spoofing download results by // sending spoofed intents. - intent.setData(contentUri); + intent.setData(getMyDownloadsUri()); } mSystemFacade.sendBroadcast(intent); } @@ -374,9 +373,7 @@ public class DownloadInfo { mStatus = Impl.STATUS_RUNNING; ContentValues values = new ContentValues(); values.put(Impl.COLUMN_STATUS, mStatus); - mContext.getContentResolver().update( - ContentUris.withAppendedId(Impl.CONTENT_URI, mId), - values, null, null); + mContext.getContentResolver().update(getAllDownloadsUri(), values, null, null); } DownloadThread downloader = new DownloadThread(mContext, mSystemFacade, this); mHasActiveThread = true; @@ -388,4 +385,12 @@ public class DownloadInfo { || mDestination == Downloads.Impl.DESTINATION_CACHE_PARTITION_NOROAMING || mDestination == Downloads.Impl.DESTINATION_CACHE_PARTITION_PURGEABLE); } + + public Uri getMyDownloadsUri() { + return ContentUris.withAppendedId(Downloads.Impl.CONTENT_URI, mId); + } + + public Uri getAllDownloadsUri() { + return ContentUris.withAppendedId(Downloads.Impl.ALL_DOWNLOADS_CONTENT_URI, mId); + } } diff --git a/src/com/android/providers/downloads/DownloadNotification.java b/src/com/android/providers/downloads/DownloadNotification.java index 472a5f30..38def594 100644 --- a/src/com/android/providers/downloads/DownloadNotification.java +++ b/src/com/android/providers/downloads/DownloadNotification.java @@ -18,6 +18,7 @@ package com.android.providers.downloads; import android.app.Notification; import android.app.PendingIntent; +import android.content.ContentUris; import android.content.Context; import android.content.Intent; import android.net.Uri; @@ -194,7 +195,7 @@ class DownloadNotification { Intent intent = new Intent(Constants.ACTION_LIST); intent.setClassName("com.android.providers.downloads", DownloadReceiver.class.getName()); - intent.setData(Uri.parse(Downloads.Impl.CONTENT_URI + "/" + item.mId)); + intent.setData(ContentUris.withAppendedId(Downloads.Impl.CONTENT_URI, item.mId)); intent.putExtra("multiple", item.mTitleCount > 1); n.contentIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0); @@ -223,7 +224,7 @@ class DownloadNotification { title = mContext.getResources().getString( R.string.download_unknown_title); } - Uri contentUri = Uri.parse(Downloads.Impl.CONTENT_URI + "/" + id); + Uri contentUri = ContentUris.withAppendedId(Downloads.Impl.CONTENT_URI, id); String caption; Intent intent; if (Downloads.Impl.isStatusError(download.mStatus)) { diff --git a/src/com/android/providers/downloads/DownloadProvider.java b/src/com/android/providers/downloads/DownloadProvider.java index d957989a..17f3d81d 100644 --- a/src/com/android/providers/downloads/DownloadProvider.java +++ b/src/com/android/providers/downloads/DownloadProvider.java @@ -17,6 +17,7 @@ package com.android.providers.downloads; import android.content.ContentProvider; +import android.content.ContentUris; import android.content.ContentValues; import android.content.Context; import android.content.Intent; @@ -54,7 +55,6 @@ import java.util.Map; * Allows application to interact with the download manager. */ public final class DownloadProvider extends ContentProvider { - /** Database filename */ private static final String DB_NAME = "downloads.db"; /** Current database version */ @@ -69,19 +69,35 @@ public final class DownloadProvider extends ContentProvider { /** URI matcher used to recognize URIs sent by applications */ private static final UriMatcher sURIMatcher = new UriMatcher(UriMatcher.NO_MATCH); - /** URI matcher constant for the URI of the entire download list */ - private static final int DOWNLOADS = 1; + /** URI matcher constant for the URI of all downloads belonging to the calling UID */ + private static final int MY_DOWNLOADS = 1; + /** URI matcher constant for the URI of an individual download belonging to the calling UID */ + private static final int MY_DOWNLOADS_ID = 2; + /** URI matcher constant for the URI of all downloads in the system */ + private static final int ALL_DOWNLOADS = 3; /** URI matcher constant for the URI of an individual download */ - private static final int DOWNLOADS_ID = 2; + private static final int ALL_DOWNLOADS_ID = 4; /** URI matcher constant for the URI of a download's request headers */ - private static final int REQUEST_HEADERS_URI = 3; + private static final int REQUEST_HEADERS_URI = 5; static { - sURIMatcher.addURI("downloads", "download", DOWNLOADS); - sURIMatcher.addURI("downloads", "download/#", DOWNLOADS_ID); - sURIMatcher.addURI("downloads", "download/#/" + Downloads.Impl.RequestHeaders.URI_SEGMENT, - REQUEST_HEADERS_URI); + sURIMatcher.addURI("downloads", "my_downloads", MY_DOWNLOADS); + sURIMatcher.addURI("downloads", "my_downloads/#", MY_DOWNLOADS_ID); + sURIMatcher.addURI("downloads", "all_downloads", ALL_DOWNLOADS); + sURIMatcher.addURI("downloads", "all_downloads/#", ALL_DOWNLOADS_ID); + sURIMatcher.addURI("downloads", + "my_downloads/#/" + Downloads.Impl.RequestHeaders.URI_SEGMENT, + REQUEST_HEADERS_URI); + sURIMatcher.addURI("downloads", + "all_downloads/#/" + Downloads.Impl.RequestHeaders.URI_SEGMENT, + REQUEST_HEADERS_URI); } + /** Different base URIs that could be used to access an individual download */ + private static final Uri[] BASE_URIS = new Uri[] { + Downloads.Impl.CONTENT_URI, + Downloads.Impl.ALL_DOWNLOADS_CONTENT_URI, + }; + private static final String[] sAppReadableColumnsArray = new String[] { Downloads.Impl._ID, Downloads.Impl.COLUMN_APP_DATA, @@ -319,10 +335,10 @@ public final class DownloadProvider extends ContentProvider { public String getType(final Uri uri) { int match = sURIMatcher.match(uri); switch (match) { - case DOWNLOADS: { + case MY_DOWNLOADS: { return DOWNLOAD_LIST_TYPE; } - case DOWNLOADS_ID: { + case MY_DOWNLOADS_ID: { return DOWNLOAD_TYPE; } default: { @@ -342,10 +358,10 @@ public final class DownloadProvider extends ContentProvider { checkInsertPermissions(values); SQLiteDatabase db = mOpenHelper.getWritableDatabase(); - if (sURIMatcher.match(uri) != DOWNLOADS) { - if (Config.LOGD) { - Log.d(Constants.TAG, "calling insert on an unknown/invalid URI: " + uri); - } + // note we disallow inserting into ALL_DOWNLOADS + int match = sURIMatcher.match(uri); + if (match != MY_DOWNLOADS) { + Log.d(Constants.TAG, "calling insert on an unknown/invalid URI: " + uri); throw new IllegalArgumentException("Unknown/Invalid URI " + uri); } @@ -463,21 +479,15 @@ public final class DownloadProvider extends ContentProvider { context.startService(new Intent(context, DownloadService.class)); long rowID = db.insert(DB_TABLE, null, filteredValues); - insertRequestHeaders(db, rowID, values); - - Uri ret = null; - - if (rowID != -1) { - context.startService(new Intent(context, DownloadService.class)); - ret = Uri.parse(Downloads.Impl.CONTENT_URI + "/" + rowID); - context.getContentResolver().notifyChange(uri, null); - } else { - if (Config.LOGD) { - Log.d(Constants.TAG, "couldn't insert into downloads database"); - } + if (rowID == -1) { + Log.d(Constants.TAG, "couldn't insert into downloads database"); + return null; } - return ret; + insertRequestHeaders(db, rowID, values); + context.startService(new Intent(context, DownloadService.class)); + notifyContentChanged(uri, match); + return ContentUris.withAppendedId(Downloads.Impl.CONTENT_URI, rowID); } /** @@ -600,33 +610,27 @@ public final class DownloadProvider extends ContentProvider { SQLiteDatabase db = mOpenHelper.getReadableDatabase(); SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); + qb.setTables(DB_TABLE); int match = sURIMatcher.match(uri); - boolean emptyWhere = true; - switch (match) { - case DOWNLOADS: { - qb.setTables(DB_TABLE); - break; - } - case DOWNLOADS_ID: { - qb.setTables(DB_TABLE); - qb.appendWhere(Downloads.Impl._ID + "="); - qb.appendWhere(getDownloadIdFromUri(uri)); - emptyWhere = false; - break; + if (match == -1) { + if (Constants.LOGV) { + Log.v(Constants.TAG, "querying unknown URI: " + uri); } - case REQUEST_HEADERS_URI: - if (projection != null || selection != null || sort != null) { - throw new UnsupportedOperationException("Request header queries do not support " - + "projections, selections or sorting"); - } - return queryRequestHeaders(db, uri); - default: { - if (Constants.LOGV) { - Log.v(Constants.TAG, "querying unknown URI: " + uri); - } - throw new IllegalArgumentException("Unknown URI: " + uri); + throw new IllegalArgumentException("Unknown URI: " + uri); + } + + if (match == REQUEST_HEADERS_URI) { + if (projection != null || selection != null || sort != null) { + throw new UnsupportedOperationException("Request header queries do not support " + + "projections, selections or sorting"); } + return queryRequestHeaders(db, uri); + } + + String where = getWhereClause(uri, null, match); + if (!where.isEmpty()) { + qb.appendWhere(where); } if (shouldRestrictVisibility()) { @@ -640,53 +644,10 @@ public final class DownloadProvider extends ContentProvider { } } } - if (!emptyWhere) { - qb.appendWhere(" AND "); - emptyWhere = false; - } - qb.appendWhere(getRestrictedUidClause()); } if (Constants.LOGVV) { - java.lang.StringBuilder sb = new java.lang.StringBuilder(); - sb.append("starting query, database is "); - if (db != null) { - sb.append("not "); - } - sb.append("null; "); - if (projection == null) { - sb.append("projection is null; "); - } else if (projection.length == 0) { - sb.append("projection is empty; "); - } else { - for (int i = 0; i < projection.length; ++i) { - sb.append("projection["); - sb.append(i); - sb.append("] is "); - sb.append(projection[i]); - sb.append("; "); - } - } - sb.append("selection is "); - sb.append(selection); - sb.append("; "); - if (selectionArgs == null) { - sb.append("selectionArgs is null; "); - } else if (selectionArgs.length == 0) { - sb.append("selectionArgs is empty; "); - } else { - for (int i = 0; i < selectionArgs.length; ++i) { - sb.append("selectionArgs["); - sb.append(i); - sb.append("] is "); - sb.append(selectionArgs[i]); - sb.append("; "); - } - } - sb.append("sort is "); - sb.append(sort); - sb.append("."); - Log.v(Constants.TAG, sb.toString()); + logVerboseQueryInfo(projection, selection, selectionArgs, sort, db); } Cursor ret = qb.query(db, projection, selection, selectionArgs, @@ -711,6 +672,49 @@ public final class DownloadProvider extends ContentProvider { return ret; } + private void logVerboseQueryInfo(String[] projection, final String selection, + final String[] selectionArgs, final String sort, SQLiteDatabase db) { + java.lang.StringBuilder sb = new java.lang.StringBuilder(); + sb.append("starting query, database is "); + if (db != null) { + sb.append("not "); + } + sb.append("null; "); + if (projection == null) { + sb.append("projection is null; "); + } else if (projection.length == 0) { + sb.append("projection is empty; "); + } else { + for (int i = 0; i < projection.length; ++i) { + sb.append("projection["); + sb.append(i); + sb.append("] is "); + sb.append(projection[i]); + sb.append("; "); + } + } + sb.append("selection is "); + sb.append(selection); + sb.append("; "); + if (selectionArgs == null) { + sb.append("selectionArgs is null; "); + } else if (selectionArgs.length == 0) { + sb.append("selectionArgs is empty; "); + } else { + for (int i = 0; i < selectionArgs.length; ++i) { + sb.append("selectionArgs["); + sb.append(i); + sb.append("] is "); + sb.append(selectionArgs[i]); + sb.append("; "); + } + } + sb.append("sort is "); + sb.append(sort); + sb.append("."); + Log.v(Constants.TAG, sb.toString()); + } + private String getDownloadIdFromUri(final Uri uri) { return uri.getPathSegments().get(1); } @@ -767,7 +771,7 @@ public final class DownloadProvider extends ContentProvider { } /** - * @return true if we should restrict this caller to viewing only its own downloads + * @return true if we should restrict the columns readable by this caller */ private boolean shouldRestrictVisibility() { int callingUid = Binder.getCallingUid(); @@ -831,26 +835,27 @@ public final class DownloadProvider extends ContentProvider { startService = true; } } + int match = sURIMatcher.match(uri); switch (match) { - case DOWNLOADS: - case DOWNLOADS_ID: { - String fullWhere = getWhereClause(uri, where); + case MY_DOWNLOADS: + case MY_DOWNLOADS_ID: + case ALL_DOWNLOADS: + case ALL_DOWNLOADS_ID: + String fullWhere = getWhereClause(uri, where, match); if (filteredValues.size() > 0) { count = db.update(DB_TABLE, filteredValues, fullWhere, whereArgs); } else { count = 0; } break; - } - default: { - if (Config.LOGD) { - Log.d(Constants.TAG, "updating unknown/invalid URI: " + uri); - } + + default: + Log.d(Constants.TAG, "updating unknown/invalid URI: " + uri); throw new UnsupportedOperationException("Cannot update URI: " + uri); - } } - getContext().getContentResolver().notifyChange(uri, null); + + notifyContentChanged(uri, match); if (startService) { Context context = getContext(); context.startService(new Intent(context, DownloadService.class)); @@ -858,17 +863,34 @@ public final class DownloadProvider extends ContentProvider { return count; } - private String getWhereClause(final Uri uri, final String where) { + /** + * Notify of a change through both URIs (/my_downloads and /all_downloads) + * @param uri either URI for the changed download(s) + * @param uriMatch the match ID from {@link #sURIMatcher} + */ + private void notifyContentChanged(final Uri uri, int uriMatch) { + Long downloadId = null; + if (uriMatch == MY_DOWNLOADS_ID || uriMatch == ALL_DOWNLOADS_ID) { + downloadId = Long.parseLong(getDownloadIdFromUri(uri)); + } + for (Uri uriToNotify : BASE_URIS) { + if (downloadId != null) { + uriToNotify = ContentUris.withAppendedId(uriToNotify, downloadId); + } + getContext().getContentResolver().notifyChange(uriToNotify, null); + } + } + + private String getWhereClause(final Uri uri, final String where, int uriMatch) { StringBuilder myWhere = new StringBuilder(); if (where != null) { myWhere.append("( " + where + " )"); } - if (sURIMatcher.match(uri) == DOWNLOADS_ID) { - String segment = getDownloadIdFromUri(uri); - long rowId = Long.parseLong(segment); - appendClause(myWhere, " ( " + Downloads.Impl._ID + " = " + rowId + " ) "); + if (uriMatch == MY_DOWNLOADS_ID || uriMatch == ALL_DOWNLOADS_ID) { + appendClause(myWhere, + " ( " + Downloads.Impl._ID + " = " + getDownloadIdFromUri(uri) + " ) "); } - if (shouldRestrictVisibility()) { + if (uriMatch == MY_DOWNLOADS || uriMatch == MY_DOWNLOADS_ID) { appendClause(myWhere, getRestrictedUidClause()); } return myWhere.toString(); @@ -887,21 +909,20 @@ public final class DownloadProvider extends ContentProvider { int count; int match = sURIMatcher.match(uri); switch (match) { - case DOWNLOADS: - case DOWNLOADS_ID: { - String fullWhere = getWhereClause(uri, where); + case MY_DOWNLOADS: + case MY_DOWNLOADS_ID: + case ALL_DOWNLOADS: + case ALL_DOWNLOADS_ID: + String fullWhere = getWhereClause(uri, where, match); deleteRequestHeaders(db, fullWhere, whereArgs); count = db.delete(DB_TABLE, fullWhere, whereArgs); break; - } - default: { - if (Config.LOGD) { - Log.d(Constants.TAG, "deleting unknown/invalid URI: " + uri); - } + + default: + Log.d(Constants.TAG, "deleting unknown/invalid URI: " + uri); throw new UnsupportedOperationException("Cannot delete URI: " + uri); - } } - getContext().getContentResolver().notifyChange(uri, null); + notifyContentChanged(uri, match); return count; } @@ -916,71 +937,41 @@ public final class DownloadProvider extends ContentProvider { * Remotely opens a file */ @Override - public ParcelFileDescriptor openFile(Uri uri, String mode) - throws FileNotFoundException { + public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException { if (Constants.LOGVV) { - Log.v(Constants.TAG, "openFile uri: " + uri + ", mode: " + mode - + ", uid: " + Binder.getCallingUid()); - Cursor cursor = query(Downloads.Impl.CONTENT_URI, - new String[] { "_id" }, null, null, "_id"); - if (cursor == null) { - Log.v(Constants.TAG, "null cursor in openFile"); - } else { - if (!cursor.moveToFirst()) { - Log.v(Constants.TAG, "empty cursor in openFile"); - } else { - do { - Log.v(Constants.TAG, "row " + cursor.getInt(0) + " available"); - } while(cursor.moveToNext()); - } - cursor.close(); - } - cursor = query(uri, new String[] { "_data" }, null, null, null); - if (cursor == null) { - Log.v(Constants.TAG, "null cursor in openFile"); - } else { - if (!cursor.moveToFirst()) { - Log.v(Constants.TAG, "empty cursor in openFile"); - } else { - String filename = cursor.getString(0); - Log.v(Constants.TAG, "filename in openFile: " + filename); - if (new java.io.File(filename).isFile()) { - Log.v(Constants.TAG, "file exists in openFile"); - } - } - cursor.close(); - } + logVerboseOpenFileInfo(uri, mode); } - // This logic is mostly copied form openFileHelper. If openFileHelper eventually - // gets split into small bits (to extract the filename and the modebits), - // this code could use the separate bits and be deeply simplified. - Cursor c = query(uri, new String[]{"_data"}, null, null, null); - int count = (c != null) ? c.getCount() : 0; - if (count != 1) { - // If there is not exactly one result, throw an appropriate exception. - if (c != null) { - c.close(); + Cursor cursor = query(uri, new String[] {"_data"}, null, null, null); + String path; + try { + int count = (cursor != null) ? cursor.getCount() : 0; + if (count != 1) { + // If there is not exactly one result, throw an appropriate exception. + if (count == 0) { + throw new FileNotFoundException("No entry for " + uri); + } + throw new FileNotFoundException("Multiple items at " + uri); } - if (count == 0) { - throw new FileNotFoundException("No entry for " + uri); + + cursor.moveToFirst(); + path = cursor.getString(0); + } finally { + if (cursor != null) { + cursor.close(); } - throw new FileNotFoundException("Multiple items at " + uri); } - c.moveToFirst(); - String path = c.getString(0); - c.close(); if (path == null) { throw new FileNotFoundException("No filename found."); } if (!Helpers.isFilenameValid(path)) { throw new FileNotFoundException("Invalid filename."); } - if (!"r".equals(mode)) { throw new FileNotFoundException("Bad mode for " + uri + ": " + mode); } + ParcelFileDescriptor ret = ParcelFileDescriptor.open(new File(path), ParcelFileDescriptor.MODE_READ_ONLY); @@ -989,14 +980,44 @@ public final class DownloadProvider extends ContentProvider { Log.v(Constants.TAG, "couldn't open file"); } throw new FileNotFoundException("couldn't open file"); - } else { - ContentValues values = new ContentValues(); - values.put(Downloads.Impl.COLUMN_LAST_MODIFICATION, mSystemFacade.currentTimeMillis()); - update(uri, values, null, null); } return ret; } + private void logVerboseOpenFileInfo(Uri uri, String mode) { + Log.v(Constants.TAG, "openFile uri: " + uri + ", mode: " + mode + + ", uid: " + Binder.getCallingUid()); + Cursor cursor = query(Downloads.Impl.CONTENT_URI, + new String[] { "_id" }, null, null, "_id"); + if (cursor == null) { + Log.v(Constants.TAG, "null cursor in openFile"); + } else { + if (!cursor.moveToFirst()) { + Log.v(Constants.TAG, "empty cursor in openFile"); + } else { + do { + Log.v(Constants.TAG, "row " + cursor.getInt(0) + " available"); + } while(cursor.moveToNext()); + } + cursor.close(); + } + cursor = query(uri, new String[] { "_data" }, null, null, null); + if (cursor == null) { + Log.v(Constants.TAG, "null cursor in openFile"); + } else { + if (!cursor.moveToFirst()) { + Log.v(Constants.TAG, "empty cursor in openFile"); + } else { + String filename = cursor.getString(0); + Log.v(Constants.TAG, "filename in openFile: " + filename); + if (new java.io.File(filename).isFile()) { + Log.v(Constants.TAG, "file exists in openFile"); + } + } + cursor.close(); + } + } + private static final void copyInteger(String key, ContentValues from, ContentValues to) { Integer i = from.getAsInteger(key); if (i != null) { diff --git a/src/com/android/providers/downloads/DownloadService.java b/src/com/android/providers/downloads/DownloadService.java index 6d9ee220..b85fb902 100644 --- a/src/com/android/providers/downloads/DownloadService.java +++ b/src/com/android/providers/downloads/DownloadService.java @@ -211,7 +211,7 @@ public class DownloadService extends Service { mDownloads = Lists.newArrayList(); mObserver = new DownloadManagerContentObserver(); - getContentResolver().registerContentObserver(Downloads.Impl.CONTENT_URI, + getContentResolver().registerContentObserver(Downloads.Impl.ALL_DOWNLOADS_CONTENT_URI, true, mObserver); mMediaScannerService = null; @@ -313,7 +313,7 @@ public class DownloadService extends Service { } long now = mSystemFacade.currentTimeMillis(); - Cursor cursor = getContentResolver().query(Downloads.Impl.CONTENT_URI, + Cursor cursor = getContentResolver().query(Downloads.Impl.ALL_DOWNLOADS_CONTENT_URI, null, null, null, Downloads.Impl._ID); if (cursor == null) { @@ -482,7 +482,7 @@ public class DownloadService extends Service { // when running the simulator). return; } - HashSet<String> fileSet = new HashSet(); + HashSet<String> fileSet = new HashSet<String>(); for (int i = 0; i < files.length; i++) { if (files[i].getName().equals(Constants.KNOWN_SPURIOUS_FILENAME)) { continue; @@ -493,7 +493,7 @@ public class DownloadService extends Service { fileSet.add(files[i].getPath()); } - Cursor cursor = getContentResolver().query(Downloads.Impl.CONTENT_URI, + Cursor cursor = getContentResolver().query(Downloads.Impl.ALL_DOWNLOADS_CONTENT_URI, new String[] { Downloads.Impl._DATA }, null, null, null); if (cursor != null) { if (cursor.moveToFirst()) { @@ -517,7 +517,7 @@ public class DownloadService extends Service { * Drops old rows from the database to prevent it from growing too large */ private void trimDatabase() { - Cursor cursor = getContentResolver().query(Downloads.Impl.CONTENT_URI, + Cursor cursor = getContentResolver().query(Downloads.Impl.ALL_DOWNLOADS_CONTENT_URI, new String[] { Downloads.Impl._ID }, Downloads.Impl.COLUMN_STATUS + " >= '200'", null, Downloads.Impl.COLUMN_LAST_MODIFICATION); @@ -530,9 +530,9 @@ public class DownloadService extends Service { int numDelete = cursor.getCount() - Constants.MAX_DOWNLOADS; int columnId = cursor.getColumnIndexOrThrow(Downloads.Impl._ID); while (numDelete > 0) { - getContentResolver().delete( - ContentUris.withAppendedId(Downloads.Impl.CONTENT_URI, - cursor.getLong(columnId)), null, null); + Uri downloadUri = ContentUris.withAppendedId( + Downloads.Impl.ALL_DOWNLOADS_CONTENT_URI, cursor.getLong(columnId)); + getContentResolver().delete(downloadUri, null, null); if (!cursor.moveToNext()) { break; } @@ -601,16 +601,13 @@ public class DownloadService extends Service { //Log.i(Constants.TAG, "*** QUERY " + mimetypeIntent + ": " + list); if (ri == null) { - if (Config.LOGD) { - Log.d(Constants.TAG, "no application to handle MIME type " + info.mMimeType); - } + Log.d(Constants.TAG, "no application to handle MIME type " + info.mMimeType); info.mStatus = Downloads.Impl.STATUS_NOT_ACCEPTABLE; - Uri uri = ContentUris.withAppendedId(Downloads.Impl.CONTENT_URI, info.mId); ContentValues values = new ContentValues(); values.put(Downloads.Impl.COLUMN_STATUS, Downloads.Impl.STATUS_NOT_ACCEPTABLE); - getContentResolver().update(uri, values, null, null); - info.sendIntentIfRequested(uri); + getContentResolver().update(info.getAllDownloadsUri(), values, null, null); + info.sendIntentIfRequested(); return; } } @@ -624,7 +621,7 @@ public class DownloadService extends Service { * Updates the local copy of the info about a download. */ private void updateDownload(Cursor cursor, int arrayPos, long now) { - DownloadInfo info = (DownloadInfo) mDownloads.get(arrayPos); + DownloadInfo info = mDownloads.get(arrayPos); int statusColumn = cursor.getColumnIndexOrThrow(Downloads.Impl.COLUMN_STATUS); int failedColumn = cursor.getColumnIndexOrThrow(Constants.FAILED_CONNECTIONS); info.mId = cursor.getInt(cursor.getColumnIndexOrThrow(Downloads.Impl._ID)); @@ -785,7 +782,7 @@ public class DownloadService extends Service { * Returns true if the file has been properly scanned. */ private boolean scanFile(Cursor cursor, int arrayPos) { - DownloadInfo info = (DownloadInfo) mDownloads.get(arrayPos); + DownloadInfo info = mDownloads.get(arrayPos); synchronized (this) { if (mMediaScannerService != null) { try { @@ -796,16 +793,11 @@ public class DownloadService extends Service { if (cursor != null) { ContentValues values = new ContentValues(); values.put(Constants.MEDIA_SCANNED, 1); - getContentResolver().update(ContentUris.withAppendedId( - Downloads.Impl.CONTENT_URI, cursor.getLong( - cursor.getColumnIndexOrThrow(Downloads.Impl._ID))), - values, null, null); + getContentResolver().update(info.getAllDownloadsUri(), values, null, null); } return true; } catch (RemoteException e) { - if (Config.LOGD) { - Log.d(Constants.TAG, "Failed to scan file " + info.mFileName); - } + Log.d(Constants.TAG, "Failed to scan file " + info.mFileName); } } } diff --git a/src/com/android/providers/downloads/DownloadThread.java b/src/com/android/providers/downloads/DownloadThread.java index 0073c6af..d680e083 100644 --- a/src/com/android/providers/downloads/DownloadThread.java +++ b/src/com/android/providers/downloads/DownloadThread.java @@ -18,7 +18,6 @@ package com.android.providers.downloads; import org.apache.http.conn.params.ConnRouteParams; -import android.content.ContentUris; import android.content.ContentValues; import android.content.Context; import android.content.Intent; @@ -88,14 +87,12 @@ public class DownloadThread extends Thread { public int mRetryAfter = 0; public int mRedirectCount = 0; public String mNewUri; - public Uri mContentUri; public boolean mGotData = false; public String mRequestUri; public State(DownloadInfo info) { mMimeType = sanitizeMimeType(info.mMimeType); mRedirectCount = info.mRedirectCount; - mContentUri = Uri.parse(Downloads.Impl.CONTENT_URI + "/" + info.mId); mRequestUri = info.mUri; mFilename = info.mFileName; } @@ -412,8 +409,7 @@ public class DownloadThread extends Thread { > Constants.MIN_PROGRESS_TIME) { ContentValues values = new ContentValues(); values.put(Downloads.Impl.COLUMN_CURRENT_BYTES, innerState.mBytesSoFar); - mContext.getContentResolver().update( - state.mContentUri, values, null, null); + mContext.getContentResolver().update(mInfo.getAllDownloadsUri(), values, null, null); innerState.mBytesNotified = innerState.mBytesSoFar; innerState.mTimeLastNotification = now; } @@ -457,7 +453,7 @@ public class DownloadThread extends Thread { if (innerState.mHeaderContentLength == null) { values.put(Downloads.Impl.COLUMN_TOTAL_BYTES, innerState.mBytesSoFar); } - mContext.getContentResolver().update(state.mContentUri, values, null, null); + mContext.getContentResolver().update(mInfo.getAllDownloadsUri(), values, null, null); boolean lengthMismatched = (innerState.mHeaderContentLength != null) && (innerState.mBytesSoFar != Integer.parseInt(innerState.mHeaderContentLength)); @@ -495,7 +491,7 @@ public class DownloadThread extends Thread { logNetworkState(); ContentValues values = new ContentValues(); values.put(Downloads.Impl.COLUMN_CURRENT_BYTES, innerState.mBytesSoFar); - mContext.getContentResolver().update(state.mContentUri, values, null, null); + mContext.getContentResolver().update(mInfo.getAllDownloadsUri(), values, null, null); if (cannotResume(innerState)) { Log.d(Constants.TAG, "download IOException for download " + mInfo.mId, ex); Log.d(Constants.TAG, "can't resume interrupted download with no ETag"); @@ -579,7 +575,7 @@ public class DownloadThread extends Thread { values.put(Downloads.Impl.COLUMN_MIME_TYPE, state.mMimeType); } values.put(Downloads.Impl.COLUMN_TOTAL_BYTES, mInfo.mTotalBytes); - mContext.getContentResolver().update(state.mContentUri, values, null, null); + mContext.getContentResolver().update(mInfo.getAllDownloadsUri(), values, null, null); } /** @@ -875,7 +871,7 @@ public class DownloadThread extends Thread { notifyThroughDatabase( status, countRetry, retryAfter, redirectCount, gotData, filename, uri, mimeType); if (Downloads.Impl.isStatusCompleted(status)) { - notifyThroughIntent(); + mInfo.sendIntentIfRequested(); } } @@ -899,17 +895,7 @@ public class DownloadThread extends Thread { values.put(Constants.FAILED_CONNECTIONS, mInfo.mNumFailed + 1); } - mContext.getContentResolver().update(ContentUris.withAppendedId( - Downloads.Impl.CONTENT_URI, mInfo.mId), values, null, null); - } - - /** - * Notifies the initiating app if it requested it. That way, it can know that the - * download completed even if it's not actively watching the cursor. - */ - private void notifyThroughIntent() { - Uri uri = Uri.parse(Downloads.Impl.CONTENT_URI + "/" + mInfo.mId); - mInfo.sendIntentIfRequested(uri); + mContext.getContentResolver().update(mInfo.getAllDownloadsUri(), values, null, null); } /** diff --git a/src/com/android/providers/downloads/Helpers.java b/src/com/android/providers/downloads/Helpers.java index e2dc9e86..a74810fe 100644 --- a/src/com/android/providers/downloads/Helpers.java +++ b/src/com/android/providers/downloads/Helpers.java @@ -470,7 +470,7 @@ public class Helpers { */ public static final boolean discardPurgeableFiles(Context context, long targetBytes) { Cursor cursor = context.getContentResolver().query( - Downloads.Impl.CONTENT_URI, + Downloads.Impl.ALL_DOWNLOADS_CONTENT_URI, null, "( " + Downloads.Impl.COLUMN_STATUS + " = '" + Downloads.Impl.STATUS_SUCCESS + "' AND " + @@ -494,7 +494,8 @@ public class Helpers { file.delete(); long id = cursor.getLong(cursor.getColumnIndex(Downloads.Impl._ID)); context.getContentResolver().delete( - ContentUris.withAppendedId(Downloads.Impl.CONTENT_URI, id), null, null); + ContentUris.withAppendedId(Downloads.Impl.ALL_DOWNLOADS_CONTENT_URI, id), + null, null); cursor.moveToNext(); } } finally { |