Merge "Only log unique mime types." into sc-dev
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 336e8eb..d57a013 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -89,10 +89,6 @@
<data android:scheme="package" />
</intent-filter>
<intent-filter>
- <action android:name="android.intent.action.MEDIA_MOUNTED" />
- <data android:scheme="file" />
- </intent-filter>
- <intent-filter>
<action android:name="android.intent.action.MEDIA_SCANNER_SCAN_FILE" />
<data android:scheme="file" />
</intent-filter>
diff --git a/src/com/android/providers/media/MediaService.java b/src/com/android/providers/media/MediaService.java
index 5e3e10f..bc7330a 100644
--- a/src/com/android/providers/media/MediaService.java
+++ b/src/com/android/providers/media/MediaService.java
@@ -29,6 +29,7 @@
import android.net.Uri;
import android.os.Bundle;
import android.os.Trace;
+import android.os.UserHandle;
import android.os.storage.StorageVolume;
import android.provider.MediaStore;
import android.util.Log;
@@ -43,6 +44,21 @@
public class MediaService extends JobIntentService {
private static final int JOB_ID = -300;
+ private static final String ACTION_SCAN_VOLUME
+ = "com.android.providers.media.action.SCAN_VOLUME";
+
+ private static final String EXTRA_MEDIAVOLUME = "MediaVolume";
+
+ private static final String EXTRA_SCAN_REASON = "scan_reason";
+
+
+ public static void queueVolumeScan(Context context, MediaVolume volume, int reason) {
+ Intent intent = new Intent(ACTION_SCAN_VOLUME);
+ intent.putExtra(EXTRA_MEDIAVOLUME, volume) ;
+ intent.putExtra(EXTRA_SCAN_REASON, reason);
+ enqueueWork(context, intent);
+ }
+
public static void enqueueWork(Context context, Intent work) {
enqueueWork(context, MediaService.class, JOB_ID, work);
}
@@ -69,8 +85,10 @@
onScanFile(this, intent.getData());
break;
}
- case Intent.ACTION_MEDIA_MOUNTED: {
- onScanVolume(this, intent, REASON_MOUNTED);
+ case ACTION_SCAN_VOLUME: {
+ final MediaVolume volume = intent.getParcelableExtra(EXTRA_MEDIAVOLUME);
+ int reason = intent.getIntExtra(EXTRA_SCAN_REASON, REASON_DEMAND);
+ onScanVolume(this, volume, reason);
break;
}
default: {
@@ -116,6 +134,11 @@
public static void onScanVolume(Context context, MediaVolume volume, int reason)
throws IOException {
final String volumeName = volume.getName();
+ UserHandle owner = volume.getUser();
+ if (owner == null) {
+ // Can happen for the internal volume
+ owner = context.getUser();
+ }
// If we're about to scan any external storage, scan internal first
// to ensure that we have ringtones ready to roll before a possibly very
// long external storage scan
@@ -129,7 +152,7 @@
// in the situation where a volume is ejected mid-scan
final Uri broadcastUri;
if (!MediaStore.VOLUME_INTERNAL.equals(volumeName)) {
- broadcastUri = Uri.fromFile(FileUtils.getVolumePath(context, volumeName));
+ broadcastUri = Uri.fromFile(volume.getPath());
} else {
broadcastUri = null;
}
@@ -146,20 +169,24 @@
Uri scanUri = resolver.insert(MediaStore.getMediaScannerUri(), values);
if (broadcastUri != null) {
- context.sendBroadcast(
- new Intent(Intent.ACTION_MEDIA_SCANNER_STARTED, broadcastUri));
+ context.sendBroadcastAsUser(
+ new Intent(Intent.ACTION_MEDIA_SCANNER_STARTED, broadcastUri), owner);
}
- for (File dir : FileUtils.getVolumeScanPaths(context, volumeName)) {
- provider.scanDirectory(dir, reason);
+ if (MediaStore.VOLUME_INTERNAL.equals(volumeName)) {
+ for (File dir : FileUtils.getVolumeScanPaths(context, volumeName)) {
+ provider.scanDirectory(dir, reason);
+ }
+ } else {
+ provider.scanDirectory(volume.getPath(), reason);
}
resolver.delete(scanUri, null, null);
} finally {
if (broadcastUri != null) {
- context.sendBroadcast(
- new Intent(Intent.ACTION_MEDIA_SCANNER_FINISHED, broadcastUri));
+ context.sendBroadcastAsUser(
+ new Intent(Intent.ACTION_MEDIA_SCANNER_FINISHED, broadcastUri), owner);
}
}
}
diff --git a/src/com/android/providers/media/MediaVolume.java b/src/com/android/providers/media/MediaVolume.java
index 577a040..461f67d 100644
--- a/src/com/android/providers/media/MediaVolume.java
+++ b/src/com/android/providers/media/MediaVolume.java
@@ -16,6 +16,8 @@
package com.android.providers.media;
+import android.os.Parcel;
+import android.os.Parcelable;
import android.os.UserHandle;
import android.os.storage.StorageVolume;
import android.provider.MediaStore;
@@ -37,7 +39,7 @@
* In addition to that, we keep the path and ID of the volume cached in here as well
* for easy access.
*/
-public final class MediaVolume {
+public final class MediaVolume implements Parcelable {
/**
* Name of the volume.
*/
@@ -81,6 +83,13 @@
this.mId = id;
}
+ private MediaVolume (Parcel in) {
+ this.mName = in.readString();
+ this.mUser = in.readParcelable(null);
+ this.mPath = new File(in.readString());
+ this.mId = in.readString();
+ }
+
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
@@ -115,4 +124,30 @@
return new MediaVolume(name, null, null, null);
}
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeString(mName);
+ dest.writeParcelable(mUser, flags);
+ dest.writeString(mPath.toString());
+ dest.writeString(mId);
+ }
+
+ public static final @android.annotation.NonNull Creator<MediaVolume> CREATOR
+ = new Creator<MediaVolume>() {
+ @Override
+ public MediaVolume createFromParcel(Parcel in) {
+ return new MediaVolume(in);
+ }
+
+ @Override
+ public MediaVolume[] newArray(int size) {
+ return new MediaVolume[size];
+ }
+ };
}
diff --git a/src/com/android/providers/media/fuse/ExternalStorageServiceImpl.java b/src/com/android/providers/media/fuse/ExternalStorageServiceImpl.java
index 612889d..1f8f3cd 100644
--- a/src/com/android/providers/media/fuse/ExternalStorageServiceImpl.java
+++ b/src/com/android/providers/media/fuse/ExternalStorageServiceImpl.java
@@ -16,6 +16,8 @@
package com.android.providers.media.fuse;
+import static com.android.providers.media.scan.MediaScanner.REASON_MOUNTED;
+
import android.annotation.BytesLong;
import android.content.ContentProviderClient;
import android.os.Environment;
@@ -30,6 +32,7 @@
import androidx.annotation.Nullable;
import com.android.providers.media.MediaProvider;
+import com.android.providers.media.MediaService;
import com.android.providers.media.MediaVolume;
import java.io.File;
@@ -83,8 +86,9 @@
switch(vol.getState()) {
case Environment.MEDIA_MOUNTED:
- mediaProvider.attachVolume(MediaVolume.fromStorageVolume(vol),
- /* validate */ false);
+ MediaVolume volume = MediaVolume.fromStorageVolume(vol);
+ mediaProvider.attachVolume(volume, /* validate */ false);
+ MediaService.queueVolumeScan(mediaProvider.getContext(), volume, REASON_MOUNTED);
break;
case Environment.MEDIA_UNMOUNTED:
case Environment.MEDIA_EJECTING:
diff --git a/src/com/android/providers/media/util/FileUtils.java b/src/com/android/providers/media/util/FileUtils.java
index 47e1559..a6311bd 100644
--- a/src/com/android/providers/media/util/FileUtils.java
+++ b/src/com/android/providers/media/util/FileUtils.java
@@ -1022,7 +1022,7 @@
* Regex that matches user-ids under well-known storage paths.
*/
private static final Pattern PATTERN_USER_ID = Pattern.compile(
- "(?i)^/storage/emulated/([0-9]+)/");
+ "(?i)^/storage/emulated/([0-9]+)");
private static final String CAMERA_RELATIVE_PATH =
String.format("%s/%s/", Environment.DIRECTORY_DCIM, "Camera");