Send RELATIVE_PATH and DISPLAY_NAME values. am: 9334cbf399 am: 27008f5d84
Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/providers/DownloadProvider/+/11910753
Change-Id: I4e1dcb969446037a97185578600f3d91406ca5a3
diff --git a/src/com/android/providers/downloads/DownloadProvider.java b/src/com/android/providers/downloads/DownloadProvider.java
index 7620c6d..b629f14 100644
--- a/src/com/android/providers/downloads/DownloadProvider.java
+++ b/src/com/android/providers/downloads/DownloadProvider.java
@@ -32,9 +32,6 @@
import static com.android.providers.downloads.Helpers.convertToMediaStoreDownloadsUri;
import static com.android.providers.downloads.Helpers.triggerMediaScan;
-import static com.android.providers.downloads.Helpers.convertToMediaStoreDownloadsUri;
-import static com.android.providers.downloads.Helpers.triggerMediaScan;
-
import android.annotation.NonNull;
import android.app.AppOpsManager;
import android.app.DownloadManager;
@@ -77,7 +74,6 @@
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.IndentingPrintWriter;
-import com.android.internal.util.Preconditions;
import libcore.io.IoUtils;
@@ -977,14 +973,15 @@
}
final boolean downloadCompleted = Downloads.Impl.isStatusCompleted(info.mStatus);
final ContentValues mediaValues = new ContentValues();
- mediaValues.put(MediaStore.Downloads.DATA, filePath);
+ mediaValues.put(MediaStore.Downloads.DATA, filePath);
+ mediaValues.put(MediaStore.Downloads.VOLUME_NAME, Helpers.extractVolumeName(filePath));
+ mediaValues.put(MediaStore.Downloads.RELATIVE_PATH, Helpers.extractRelativePath(filePath));
+ mediaValues.put(MediaStore.Downloads.DISPLAY_NAME, Helpers.extractDisplayName(filePath));
mediaValues.put(MediaStore.Downloads.SIZE,
downloadCompleted ? info.mTotalBytes : info.mCurrentBytes);
mediaValues.put(MediaStore.Downloads.DOWNLOAD_URI, info.mUri);
mediaValues.put(MediaStore.Downloads.REFERER_URI, info.mReferer);
mediaValues.put(MediaStore.Downloads.MIME_TYPE, info.mMimeType);
- // Note: Since we use DATA column for insert, MediaProvider will not respect IS_PENDING,
- // IS_PENDING will be unset to zero, Hence IS_PENDING usage here is a no-op.
mediaValues.put(MediaStore.Downloads.IS_PENDING, downloadCompleted ? 0 : 1);
mediaValues.put(MediaStore.Downloads.OWNER_PACKAGE_NAME,
Helpers.getPackageForUid(getContext(), info.mUid));
diff --git a/src/com/android/providers/downloads/Helpers.java b/src/com/android/providers/downloads/Helpers.java
index eafe86d..772c0b9 100644
--- a/src/com/android/providers/downloads/Helpers.java
+++ b/src/com/android/providers/downloads/Helpers.java
@@ -22,7 +22,6 @@
import static android.os.Environment.buildExternalStorageAppObbDirs;
import static android.os.Environment.buildExternalStoragePublicDirs;
import static android.os.Process.INVALID_UID;
-import static android.provider.Downloads.Impl.AUTHORITY;
import static android.provider.Downloads.Impl.COLUMN_DESTINATION;
import static android.provider.Downloads.Impl.DESTINATION_EXTERNAL;
import static android.provider.Downloads.Impl.DESTINATION_FILE_URI;
@@ -39,20 +38,16 @@
import android.app.job.JobScheduler;
import android.content.ComponentName;
import android.content.ContentProvider;
-import android.content.ContentProviderClient;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
-import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
-import android.os.Bundle;
import android.os.Environment;
import android.os.FileUtils;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Process;
-import android.os.RemoteException;
import android.os.SystemClock;
import android.os.UserHandle;
import android.os.storage.StorageManager;
@@ -71,8 +66,8 @@
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Locale;
import java.util.Random;
-import java.util.function.BiConsumer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -620,6 +615,83 @@
return false;
}
+ /**
+ * Shamelessly borrowed from
+ * {@code packages/providers/MediaProvider/src/com/android/providers/media/util/FileUtils.java}.
+ */
+ private static final Pattern PATTERN_RELATIVE_PATH = Pattern.compile(
+ "(?i)^/storage/(?:emulated/[0-9]+/|[^/]+/)(Android/sandbox/([^/]+)/)?");
+
+ /**
+ * Shamelessly borrowed from
+ * {@code packages/providers/MediaProvider/src/com/android/providers/media/util/FileUtils.java}.
+ */
+ private static final Pattern PATTERN_VOLUME_NAME = Pattern.compile(
+ "(?i)^/storage/([^/]+)");
+
+ /**
+ * Shamelessly borrowed from
+ * {@code packages/providers/MediaProvider/src/com/android/providers/media/util/FileUtils.java}.
+ */
+ private static @Nullable String normalizeUuid(@Nullable String fsUuid) {
+ return fsUuid != null ? fsUuid.toLowerCase(Locale.ROOT) : null;
+ }
+
+ /**
+ * Shamelessly borrowed from
+ * {@code packages/providers/MediaProvider/src/com/android/providers/media/util/FileUtils.java}.
+ */
+ public static @Nullable String extractVolumeName(@Nullable String data) {
+ if (data == null) return null;
+ final Matcher matcher = PATTERN_VOLUME_NAME.matcher(data);
+ if (matcher.find()) {
+ final String volumeName = matcher.group(1);
+ if (volumeName.equals("emulated")) {
+ return MediaStore.VOLUME_EXTERNAL_PRIMARY;
+ } else {
+ return normalizeUuid(volumeName);
+ }
+ } else {
+ return MediaStore.VOLUME_INTERNAL;
+ }
+ }
+
+ /**
+ * Shamelessly borrowed from
+ * {@code packages/providers/MediaProvider/src/com/android/providers/media/util/FileUtils.java}.
+ */
+ public static @Nullable String extractRelativePath(@Nullable String data) {
+ if (data == null) return null;
+ final Matcher matcher = PATTERN_RELATIVE_PATH.matcher(data);
+ if (matcher.find()) {
+ final int lastSlash = data.lastIndexOf('/');
+ if (lastSlash == -1 || lastSlash < matcher.end()) {
+ // This is a file in the top-level directory, so relative path is "/"
+ // which is different than null, which means unknown path
+ return "/";
+ } else {
+ return data.substring(matcher.end(), lastSlash + 1);
+ }
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Shamelessly borrowed from
+ * {@code packages/providers/MediaProvider/src/com/android/providers/media/util/FileUtils.java}.
+ */
+ public static @Nullable String extractDisplayName(@Nullable String data) {
+ if (data == null) return null;
+ if (data.indexOf('/') == -1) {
+ return data;
+ }
+ if (data.endsWith("/")) {
+ data = data.substring(0, data.length() - 1);
+ }
+ return data.substring(data.lastIndexOf('/') + 1);
+ }
+
private static boolean containsCanonical(File dir, File file) throws IOException {
return FileUtils.contains(dir.getCanonicalFile(), file);
}