summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Ivan Chiang <chiangi@google.com> 2021-01-25 16:53:54 +0800
committer Ivan Chiang <chiangi@google.com> 2021-02-10 01:37:32 +0000
commit7fce4a5145d1dec27fea8c325dde4fe913f2fadd (patch)
tree72cb87456482ae3ceb6c3943decb1456b6cb3db5
parent7a88ff358161efafab3824c8f8f34b12dc06b045 (diff)
Add AudioColumn is_recording and support recording type
Bug: 161526501 Test: atest --test-mapping packages/providers/MediaProvider Change-Id: I844f463d7f98185a507d24c4d7970d7d1de2ec72
-rw-r--r--Android.bp1
-rw-r--r--apex/framework/api/current.txt1
-rw-r--r--apex/framework/java/android/provider/MediaStore.java6
-rw-r--r--legacy/Android.bp3
-rw-r--r--src/com/android/providers/media/DatabaseHelper.java16
-rw-r--r--src/com/android/providers/media/MediaProvider.java28
-rw-r--r--src/com/android/providers/media/scan/ModernMediaScanner.java4
-rw-r--r--src/com/android/providers/media/util/FileUtils.java48
-rw-r--r--tests/Android.bp1
-rw-r--r--tests/src/com/android/providers/media/scan/ModernMediaScannerTest.java19
10 files changed, 104 insertions, 23 deletions
diff --git a/Android.bp b/Android.bp
index fa33f8f84..405f33c03 100644
--- a/Android.bp
+++ b/Android.bp
@@ -7,6 +7,7 @@ android_app {
"androidx.appcompat_appcompat",
"androidx.core_core",
"guava",
+ "modules-utils-build",
],
libs: [
diff --git a/apex/framework/api/current.txt b/apex/framework/api/current.txt
index 51dd35624..57022d895 100644
--- a/apex/framework/api/current.txt
+++ b/apex/framework/api/current.txt
@@ -136,6 +136,7 @@ package android.provider {
field public static final String IS_MUSIC = "is_music";
field public static final String IS_NOTIFICATION = "is_notification";
field public static final String IS_PODCAST = "is_podcast";
+ field public static final String IS_RECORDING = "is_recording";
field public static final String IS_RINGTONE = "is_ringtone";
field @Deprecated public static final String TITLE_KEY = "title_key";
field public static final String TITLE_RESOURCE_URI = "title_resource_uri";
diff --git a/apex/framework/java/android/provider/MediaStore.java b/apex/framework/java/android/provider/MediaStore.java
index 89c2e8bd1..48ff05497 100644
--- a/apex/framework/java/android/provider/MediaStore.java
+++ b/apex/framework/java/android/provider/MediaStore.java
@@ -2742,6 +2742,12 @@ public final class MediaStore {
public static final String IS_AUDIOBOOK = "is_audiobook";
/**
+ * Non-zero if the audio file is a recording
+ */
+ @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
+ public static final String IS_RECORDING = "is_recording";
+
+ /**
* The id of the genre the audio file is from, if any
*/
@Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
diff --git a/legacy/Android.bp b/legacy/Android.bp
index 203ee5a26..89ef09c69 100644
--- a/legacy/Android.bp
+++ b/legacy/Android.bp
@@ -7,6 +7,7 @@ android_app {
"androidx.appcompat_appcompat",
"androidx.core_core",
"guava",
+ "modules-utils-build",
],
libs: ["app-compat-annotations"],
@@ -17,7 +18,7 @@ android_app {
":mediaprovider-database-sources",
],
+ platform_apis: true,
certificate: "media",
privileged: true,
- sdk_version: "system_current",
}
diff --git a/src/com/android/providers/media/DatabaseHelper.java b/src/com/android/providers/media/DatabaseHelper.java
index e446ecb1b..6064d18b1 100644
--- a/src/com/android/providers/media/DatabaseHelper.java
+++ b/src/com/android/providers/media/DatabaseHelper.java
@@ -60,6 +60,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
+import com.android.modules.utils.build.SdkLevel;
import com.android.providers.media.playlist.Playlist;
import com.android.providers.media.util.BackgroundThread;
import com.android.providers.media.util.DatabaseUtils;
@@ -813,7 +814,7 @@ public class DatabaseHelper extends SQLiteOpenHelper implements AutoCloseable {
+ "scene_capture_type INTEGER DEFAULT NULL, generation_added INTEGER DEFAULT 0,"
+ "generation_modified INTEGER DEFAULT 0, xmp BLOB DEFAULT NULL,"
+ "_transcode_status INTEGER DEFAULT 0, _video_codec_type TEXT DEFAULT NULL,"
- + "_modifier INTEGER DEFAULT 0)");
+ + "_modifier INTEGER DEFAULT 0, is_recording INTEGER DEFAULT 0)");
db.execSQL("CREATE TABLE log (time DATETIME, message TEXT)");
if (!mInternal) {
@@ -1370,6 +1371,14 @@ public class DatabaseHelper extends SQLiteOpenHelper implements AutoCloseable {
db.execSQL("ALTER TABLE files ADD COLUMN is_audiobook INTEGER DEFAULT 0;");
}
+ private static void updateAddRecording(SQLiteDatabase db, boolean internal) {
+ db.execSQL("ALTER TABLE files ADD COLUMN is_recording INTEGER DEFAULT 0;");
+ if (SdkLevel.isAtLeastS()) {
+ // We add the column is_recording, rescan all music files
+ db.execSQL("UPDATE files SET date_modified=0 WHERE is_music=1;");
+ }
+ }
+
private static void updateClearLocation(SQLiteDatabase db, boolean internal) {
db.execSQL("UPDATE files SET latitude=NULL, longitude=NULL;");
}
@@ -1575,7 +1584,7 @@ public class DatabaseHelper extends SQLiteOpenHelper implements AutoCloseable {
static final int VERSION_R = 1115;
// Leave some gaps in database version tagging to allow R schema changes
// to go independent of S schema changes.
- static final int VERSION_S = 1204;
+ static final int VERSION_S = 1205;
static final int VERSION_LATEST = VERSION_S;
/**
@@ -1736,6 +1745,9 @@ public class DatabaseHelper extends SQLiteOpenHelper implements AutoCloseable {
if (fromVersion < 1204) {
// Empty version bump to ensure views are recreated
}
+ if (fromVersion < 1205) {
+ updateAddRecording(db, internal);
+ }
// If this is the legacy database, it's not worth recomputing data
// values locally, since they'll be recomputed after the migration
diff --git a/src/com/android/providers/media/MediaProvider.java b/src/com/android/providers/media/MediaProvider.java
index 7ecd3f95a..09f9820d0 100644
--- a/src/com/android/providers/media/MediaProvider.java
+++ b/src/com/android/providers/media/MediaProvider.java
@@ -177,6 +177,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
+import com.android.modules.utils.build.SdkLevel;
import com.android.providers.media.DatabaseHelper.OnFilesChangeListener;
import com.android.providers.media.DatabaseHelper.OnLegacyMigrationListener;
import com.android.providers.media.fuse.ExternalStorageServiceImpl;
@@ -263,6 +264,7 @@ public class MediaProvider extends ContentProvider {
private static final String DIRECTORY_DCIM_LOWER_CASE = "dcim";
private static final String DIRECTORY_DOCUMENTS_LOWER_CASE = "documents";
private static final String DIRECTORY_AUDIOBOOKS_LOWER_CASE = "audiobooks";
+ private static final String DIRECTORY_RECORDINGS_LOWER_CASE = "recordings";
private static final String DIRECTORY_ANDROID_LOWER_CASE = "android";
private static final String DIRECTORY_MEDIA = "media";
@@ -2775,13 +2777,24 @@ public class MediaProvider extends ContentProvider {
defaultMimeType = "audio/mpeg";
defaultMediaType = FileColumns.MEDIA_TYPE_AUDIO;
defaultPrimary = Environment.DIRECTORY_MUSIC;
- allowedPrimary = Arrays.asList(
- Environment.DIRECTORY_ALARMS,
- Environment.DIRECTORY_AUDIOBOOKS,
- Environment.DIRECTORY_MUSIC,
- Environment.DIRECTORY_NOTIFICATIONS,
- Environment.DIRECTORY_PODCASTS,
- Environment.DIRECTORY_RINGTONES);
+ if (SdkLevel.isAtLeastS()) {
+ allowedPrimary = Arrays.asList(
+ Environment.DIRECTORY_ALARMS,
+ Environment.DIRECTORY_AUDIOBOOKS,
+ Environment.DIRECTORY_MUSIC,
+ Environment.DIRECTORY_NOTIFICATIONS,
+ Environment.DIRECTORY_PODCASTS,
+ Environment.DIRECTORY_RECORDINGS,
+ Environment.DIRECTORY_RINGTONES);
+ } else {
+ allowedPrimary = Arrays.asList(
+ Environment.DIRECTORY_ALARMS,
+ Environment.DIRECTORY_AUDIOBOOKS,
+ Environment.DIRECTORY_MUSIC,
+ Environment.DIRECTORY_NOTIFICATIONS,
+ Environment.DIRECTORY_PODCASTS,
+ Environment.DIRECTORY_RINGTONES);
+ }
break;
case VIDEO_MEDIA:
case VIDEO_MEDIA_ID:
@@ -7600,6 +7613,7 @@ public class MediaProvider extends ContentProvider {
case DIRECTORY_ALARMS_LOWER_CASE:
case DIRECTORY_NOTIFICATIONS_LOWER_CASE:
case DIRECTORY_AUDIOBOOKS_LOWER_CASE:
+ case DIRECTORY_RECORDINGS_LOWER_CASE:
uri = Audio.Media.getContentUri(volName);
break;
case DIRECTORY_MUSIC_LOWER_CASE:
diff --git a/src/com/android/providers/media/scan/ModernMediaScanner.java b/src/com/android/providers/media/scan/ModernMediaScanner.java
index 141cee008..c88fc2028 100644
--- a/src/com/android/providers/media/scan/ModernMediaScanner.java
+++ b/src/com/android/providers/media/scan/ModernMediaScanner.java
@@ -90,6 +90,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
+import com.android.modules.utils.build.SdkLevel;
import com.android.providers.media.util.DatabaseUtils;
import com.android.providers.media.util.ExifUtils;
import com.android.providers.media.util.FileUtils;
@@ -1192,6 +1193,9 @@ public class ModernMediaScanner implements MediaScanner {
sAudioTypes.put(Environment.DIRECTORY_PODCASTS, AudioColumns.IS_PODCAST);
sAudioTypes.put(Environment.DIRECTORY_AUDIOBOOKS, AudioColumns.IS_AUDIOBOOK);
sAudioTypes.put(Environment.DIRECTORY_MUSIC, AudioColumns.IS_MUSIC);
+ if (SdkLevel.isAtLeastS()) {
+ sAudioTypes.put(Environment.DIRECTORY_RECORDINGS, AudioColumns.IS_RECORDING);
+ }
}
private static @NonNull ContentProviderOperation.Builder scanItemAudio(long existingId,
diff --git a/src/com/android/providers/media/util/FileUtils.java b/src/com/android/providers/media/util/FileUtils.java
index 0d6494bb8..7e79091e2 100644
--- a/src/com/android/providers/media/util/FileUtils.java
+++ b/src/com/android/providers/media/util/FileUtils.java
@@ -64,6 +64,8 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
+import com.android.modules.utils.build.SdkLevel;
+
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileNotFoundException;
@@ -932,19 +934,39 @@ public class FileUtils {
"(?i)^/storage/[^/]+/(?:[0-9]+/)?Android/(?:obb)(/?.*)");
@VisibleForTesting
- public static final String[] DEFAULT_FOLDER_NAMES = {
- Environment.DIRECTORY_MUSIC,
- Environment.DIRECTORY_PODCASTS,
- Environment.DIRECTORY_RINGTONES,
- Environment.DIRECTORY_ALARMS,
- Environment.DIRECTORY_NOTIFICATIONS,
- Environment.DIRECTORY_PICTURES,
- Environment.DIRECTORY_MOVIES,
- Environment.DIRECTORY_DOWNLOADS,
- Environment.DIRECTORY_DCIM,
- Environment.DIRECTORY_DOCUMENTS,
- Environment.DIRECTORY_AUDIOBOOKS,
- };
+ public static final String[] DEFAULT_FOLDER_NAMES;
+ static {
+ if (SdkLevel.isAtLeastS()) {
+ DEFAULT_FOLDER_NAMES = new String[]{
+ Environment.DIRECTORY_MUSIC,
+ Environment.DIRECTORY_PODCASTS,
+ Environment.DIRECTORY_RINGTONES,
+ Environment.DIRECTORY_ALARMS,
+ Environment.DIRECTORY_NOTIFICATIONS,
+ Environment.DIRECTORY_PICTURES,
+ Environment.DIRECTORY_MOVIES,
+ Environment.DIRECTORY_DOWNLOADS,
+ Environment.DIRECTORY_DCIM,
+ Environment.DIRECTORY_DOCUMENTS,
+ Environment.DIRECTORY_AUDIOBOOKS,
+ Environment.DIRECTORY_RECORDINGS,
+ };
+ } else {
+ DEFAULT_FOLDER_NAMES = new String[]{
+ Environment.DIRECTORY_MUSIC,
+ Environment.DIRECTORY_PODCASTS,
+ Environment.DIRECTORY_RINGTONES,
+ Environment.DIRECTORY_ALARMS,
+ Environment.DIRECTORY_NOTIFICATIONS,
+ Environment.DIRECTORY_PICTURES,
+ Environment.DIRECTORY_MOVIES,
+ Environment.DIRECTORY_DOWNLOADS,
+ Environment.DIRECTORY_DCIM,
+ Environment.DIRECTORY_DOCUMENTS,
+ Environment.DIRECTORY_AUDIOBOOKS,
+ };
+ }
+ }
/**
* Regex that matches paths for {@link MediaColumns#RELATIVE_PATH}
diff --git a/tests/Android.bp b/tests/Android.bp
index 25dd84aec..ed92db271 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -38,6 +38,7 @@ android_test {
"androidx.test.rules",
"guava",
"mockito-target",
+ "modules-utils-build",
"truth-prebuilt",
],
diff --git a/tests/src/com/android/providers/media/scan/ModernMediaScannerTest.java b/tests/src/com/android/providers/media/scan/ModernMediaScannerTest.java
index e1312c218..d913307f5 100644
--- a/tests/src/com/android/providers/media/scan/ModernMediaScannerTest.java
+++ b/tests/src/com/android/providers/media/scan/ModernMediaScannerTest.java
@@ -777,6 +777,25 @@ public class ModernMediaScannerTest {
}
}
+ @Test
+ public void testScan_audio_recording() throws Exception {
+ final File music = new File(mDir, "Recordings");
+ final File audio = new File(music, "audio.mp3");
+
+ music.mkdirs();
+ stage(R.raw.test_audio, audio);
+
+ mModern.scanFile(audio, REASON_UNKNOWN);
+
+ try (Cursor cursor = mIsolatedResolver
+ .query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null, null)) {
+ assertEquals(1, cursor.getCount());
+ cursor.moveToFirst();
+ assertEquals(1, cursor.getInt(cursor.getColumnIndex(AudioColumns.IS_RECORDING)));
+ assertEquals(0, cursor.getInt(cursor.getColumnIndex(AudioColumns.IS_MUSIC)));
+ }
+ }
+
/**
* Verify a narrow exception where we allow an {@code mp4} video file on
* disk to be indexed as an {@code m4a} audio file.