From 495edec1d9f7659923c71b009db66c1bd4782034 Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Tue, 5 Aug 2014 11:51:24 -0700 Subject: Scan after writing download files. Kicks off media scanner after files are written, usually through a DocumentsProvider. Bug: 13557203 Change-Id: I4e29b778b4e19a217f60c1e415c4d814724752d3 --- src/com/android/providers/downloads/Constants.java | 3 -- .../android/providers/downloads/DownloadInfo.java | 2 +- .../providers/downloads/DownloadProvider.java | 59 +++++++++++++++------- .../downloads/DownloadStorageProvider.java | 2 +- 4 files changed, 43 insertions(+), 23 deletions(-) diff --git a/src/com/android/providers/downloads/Constants.java b/src/com/android/providers/downloads/Constants.java index 2803d1c6..7b8fcd24 100644 --- a/src/com/android/providers/downloads/Constants.java +++ b/src/com/android/providers/downloads/Constants.java @@ -45,9 +45,6 @@ public class Constants { /** The column that is used for the initiating app's UID */ public static final String UID = "uid"; - /** The column that is used to remember whether the media scanner was invoked */ - public static final String MEDIA_SCANNED = "scanned"; - /** The intent that gets sent when the service must wake up for a retry */ public static final String ACTION_RETRY = "android.intent.action.DOWNLOAD_WAKEUP"; diff --git a/src/com/android/providers/downloads/DownloadInfo.java b/src/com/android/providers/downloads/DownloadInfo.java index 3571a781..2423c0d7 100644 --- a/src/com/android/providers/downloads/DownloadInfo.java +++ b/src/com/android/providers/downloads/DownloadInfo.java @@ -94,7 +94,7 @@ public class DownloadInfo { info.mCurrentBytes = getLong(Downloads.Impl.COLUMN_CURRENT_BYTES); info.mETag = getString(Constants.ETAG); info.mUid = getInt(Constants.UID); - info.mMediaScanned = getInt(Constants.MEDIA_SCANNED); + info.mMediaScanned = getInt(Downloads.Impl.COLUMN_MEDIA_SCANNED); info.mDeleted = getInt(Downloads.Impl.COLUMN_DELETED) == 1; info.mMediaProviderUri = getString(Downloads.Impl.COLUMN_MEDIAPROVIDER_URI); info.mIsPublicApi = getInt(Downloads.Impl.COLUMN_IS_PUBLIC_API) != 0; diff --git a/src/com/android/providers/downloads/DownloadProvider.java b/src/com/android/providers/downloads/DownloadProvider.java index 59e753e5..5b45c3fb 100644 --- a/src/com/android/providers/downloads/DownloadProvider.java +++ b/src/com/android/providers/downloads/DownloadProvider.java @@ -414,7 +414,7 @@ public final class DownloadProvider extends ContentProvider { Downloads.Impl.COLUMN_OTHER_UID + " INTEGER, " + Downloads.Impl.COLUMN_TITLE + " TEXT, " + Downloads.Impl.COLUMN_DESCRIPTION + " TEXT, " + - Constants.MEDIA_SCANNED + " BOOLEAN);"); + Downloads.Impl.COLUMN_MEDIA_SCANNED + " BOOLEAN);"); } catch (SQLException ex) { Log.e(Constants.TAG, "couldn't create table in downloads database"); throw ex; @@ -1182,8 +1182,12 @@ public final class DownloadProvider extends ContentProvider { logVerboseOpenFileInfo(uri, mode); } - final Cursor cursor = query(uri, new String[] { Downloads.Impl._DATA }, null, null, null); - String path; + final Cursor cursor = query(uri, new String[] { + Downloads.Impl._DATA, Downloads.Impl.COLUMN_STATUS, + Downloads.Impl.COLUMN_DESTINATION, Downloads.Impl.COLUMN_MEDIA_SCANNED }, null, + null, null); + final String path; + final boolean shouldScan; try { int count = (cursor != null) ? cursor.getCount() : 0; if (count != 1) { @@ -1194,8 +1198,20 @@ public final class DownloadProvider extends ContentProvider { throw new FileNotFoundException("Multiple items at " + uri); } - cursor.moveToFirst(); - path = cursor.getString(0); + if (cursor.moveToFirst()) { + final int status = cursor.getInt(1); + final int destination = cursor.getInt(2); + final int mediaScanned = cursor.getInt(3); + + path = cursor.getString(0); + shouldScan = Downloads.Impl.isStatusSuccess(status) && ( + destination == Downloads.Impl.DESTINATION_EXTERNAL + || destination == Downloads.Impl.DESTINATION_FILE_URI + || destination == Downloads.Impl.DESTINATION_NON_DOWNLOADMANAGER_DOWNLOAD) + && mediaScanned != 2; + } else { + throw new FileNotFoundException("Failed moveToFirst"); + } } finally { IoUtils.closeQuietly(cursor); } @@ -1209,22 +1225,29 @@ public final class DownloadProvider extends ContentProvider { throw new FileNotFoundException("Invalid file: " + file); } - if ("r".equals(mode)) { - return ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY); + final int pfdMode = ParcelFileDescriptor.parseMode(mode); + if (pfdMode == ParcelFileDescriptor.MODE_READ_ONLY) { + return ParcelFileDescriptor.open(file, pfdMode); } 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); - } - }); + return ParcelFileDescriptor.open(file, pfdMode, 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); + + if (shouldScan) { + final Intent intent = new Intent( + Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); + intent.setData(Uri.fromFile(file)); + getContext().sendBroadcast(intent); + } + } + }); } catch (IOException e) { throw new FileNotFoundException("Failed to open for writing: " + e); } diff --git a/src/com/android/providers/downloads/DownloadStorageProvider.java b/src/com/android/providers/downloads/DownloadStorageProvider.java index ecef54e0..78b3c430 100644 --- a/src/com/android/providers/downloads/DownloadStorageProvider.java +++ b/src/com/android/providers/downloads/DownloadStorageProvider.java @@ -133,7 +133,7 @@ public class DownloadStorageProvider extends DocumentsProvider { } return Long.toString(mDm.addCompletedDownload( - file.getName(), file.getName(), false, mimeType, file.getAbsolutePath(), 0L, + file.getName(), file.getName(), true, mimeType, file.getAbsolutePath(), 0L, false, true)); } finally { Binder.restoreCallingIdentity(token); -- cgit v1.2.3