diff options
author | 2021-01-25 16:53:54 +0800 | |
---|---|---|
committer | 2021-02-10 01:37:32 +0000 | |
commit | 7fce4a5145d1dec27fea8c325dde4fe913f2fadd (patch) | |
tree | 72cb87456482ae3ceb6c3943decb1456b6cb3db5 | |
parent | 7a88ff358161efafab3824c8f8f34b12dc06b045 (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.bp | 1 | ||||
-rw-r--r-- | apex/framework/api/current.txt | 1 | ||||
-rw-r--r-- | apex/framework/java/android/provider/MediaStore.java | 6 | ||||
-rw-r--r-- | legacy/Android.bp | 3 | ||||
-rw-r--r-- | src/com/android/providers/media/DatabaseHelper.java | 16 | ||||
-rw-r--r-- | src/com/android/providers/media/MediaProvider.java | 28 | ||||
-rw-r--r-- | src/com/android/providers/media/scan/ModernMediaScanner.java | 4 | ||||
-rw-r--r-- | src/com/android/providers/media/util/FileUtils.java | 48 | ||||
-rw-r--r-- | tests/Android.bp | 1 | ||||
-rw-r--r-- | tests/src/com/android/providers/media/scan/ModernMediaScannerTest.java | 19 |
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. |