diff options
author | 2025-02-12 09:24:25 -0800 | |
---|---|---|
committer | 2025-02-12 09:24:25 -0800 | |
commit | 6813f3582452cc27c70b9783db57ac5f7d3ed612 (patch) | |
tree | c3208b701f2e555edec04818c75d31ae8a8785df /tests | |
parent | da3fdd1076e51ab17afa4e19115e368174f4784a (diff) | |
parent | ab6f4a5085e4d1f15ac0c28e66cb0cfadeecff1c (diff) |
Merge "Add configurations to support for backup and restore of MediaProvider" into main
Diffstat (limited to 'tests')
4 files changed, 366 insertions, 145 deletions
diff --git a/tests/src/com/android/providers/media/backupandrestore/BackupAndRestoreTestUtils.java b/tests/src/com/android/providers/media/backupandrestore/BackupAndRestoreTestUtils.java new file mode 100644 index 000000000..228be1b40 --- /dev/null +++ b/tests/src/com/android/providers/media/backupandrestore/BackupAndRestoreTestUtils.java @@ -0,0 +1,175 @@ +/* + * Copyright (C) 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.providers.media.backupandrestore; + +import static com.android.providers.media.backupandrestore.BackupAndRestoreUtils.FIELD_SEPARATOR; +import static com.android.providers.media.backupandrestore.BackupAndRestoreUtils.KEY_VALUE_SEPARATOR; +import static com.android.providers.media.backupandrestore.BackupAndRestoreUtils.RESTORE_COMPLETED; +import static com.android.providers.media.backupandrestore.BackupAndRestoreUtils.SHARED_PREFERENCE_NAME; + +import android.content.Context; +import android.provider.MediaStore; + +import java.util.HashMap; +import java.util.Map; + +public class BackupAndRestoreTestUtils { + + /** + * Map used to store column name for given key id. + */ + private static Map<String, String> sColumnIdToKeyMap; + + /** + * Map used to store key id for given column name. + */ + private static Map<String, String> sColumnNameToIdMap; + + static void createKeyToColumnNameMap() { + sColumnIdToKeyMap = new HashMap<>(); + sColumnIdToKeyMap.put("0", MediaStore.Files.FileColumns.IS_FAVORITE); + sColumnIdToKeyMap.put("1", MediaStore.Files.FileColumns.MEDIA_TYPE); + sColumnIdToKeyMap.put("2", MediaStore.Files.FileColumns.MIME_TYPE); + sColumnIdToKeyMap.put("3", MediaStore.Files.FileColumns._USER_ID); + sColumnIdToKeyMap.put("4", MediaStore.Files.FileColumns.SIZE); + sColumnIdToKeyMap.put("5", MediaStore.MediaColumns.DATE_TAKEN); + sColumnIdToKeyMap.put("6", MediaStore.MediaColumns.CD_TRACK_NUMBER); + sColumnIdToKeyMap.put("7", MediaStore.MediaColumns.ALBUM); + sColumnIdToKeyMap.put("8", MediaStore.MediaColumns.ARTIST); + sColumnIdToKeyMap.put("9", MediaStore.MediaColumns.AUTHOR); + sColumnIdToKeyMap.put("10", MediaStore.MediaColumns.COMPOSER); + sColumnIdToKeyMap.put("11", MediaStore.MediaColumns.GENRE); + sColumnIdToKeyMap.put("12", MediaStore.MediaColumns.TITLE); + sColumnIdToKeyMap.put("13", MediaStore.MediaColumns.YEAR); + sColumnIdToKeyMap.put("14", MediaStore.MediaColumns.DURATION); + sColumnIdToKeyMap.put("15", MediaStore.MediaColumns.NUM_TRACKS); + sColumnIdToKeyMap.put("16", MediaStore.MediaColumns.WRITER); + sColumnIdToKeyMap.put("17", MediaStore.MediaColumns.ALBUM_ARTIST); + sColumnIdToKeyMap.put("18", MediaStore.MediaColumns.DISC_NUMBER); + sColumnIdToKeyMap.put("19", MediaStore.MediaColumns.COMPILATION); + sColumnIdToKeyMap.put("20", MediaStore.MediaColumns.BITRATE); + sColumnIdToKeyMap.put("21", MediaStore.MediaColumns.CAPTURE_FRAMERATE); + sColumnIdToKeyMap.put("22", MediaStore.Audio.AudioColumns.TRACK); + sColumnIdToKeyMap.put("23", MediaStore.MediaColumns.DOCUMENT_ID); + sColumnIdToKeyMap.put("24", MediaStore.MediaColumns.INSTANCE_ID); + sColumnIdToKeyMap.put("25", MediaStore.MediaColumns.ORIGINAL_DOCUMENT_ID); + sColumnIdToKeyMap.put("26", MediaStore.MediaColumns.RESOLUTION); + sColumnIdToKeyMap.put("27", MediaStore.MediaColumns.ORIENTATION); + sColumnIdToKeyMap.put("28", MediaStore.Video.VideoColumns.COLOR_STANDARD); + sColumnIdToKeyMap.put("29", MediaStore.Video.VideoColumns.COLOR_TRANSFER); + sColumnIdToKeyMap.put("30", MediaStore.Video.VideoColumns.COLOR_RANGE); + sColumnIdToKeyMap.put("31", MediaStore.Files.FileColumns._VIDEO_CODEC_TYPE); + sColumnIdToKeyMap.put("32", MediaStore.MediaColumns.WIDTH); + sColumnIdToKeyMap.put("33", MediaStore.MediaColumns.HEIGHT); + sColumnIdToKeyMap.put("34", MediaStore.Images.ImageColumns.DESCRIPTION); + sColumnIdToKeyMap.put("35", MediaStore.Images.ImageColumns.EXPOSURE_TIME); + sColumnIdToKeyMap.put("36", MediaStore.Images.ImageColumns.F_NUMBER); + sColumnIdToKeyMap.put("37", MediaStore.Images.ImageColumns.ISO); + sColumnIdToKeyMap.put("38", MediaStore.Images.ImageColumns.SCENE_CAPTURE_TYPE); + sColumnIdToKeyMap.put("39", MediaStore.Files.FileColumns._SPECIAL_FORMAT); + sColumnIdToKeyMap.put("40", MediaStore.Files.FileColumns.OWNER_PACKAGE_NAME); + // Adding number gap to allow addition of new values + sColumnIdToKeyMap.put("80", MediaStore.MediaColumns.XMP); + } + + static void createColumnNameToKeyMap() { + sColumnNameToIdMap = new HashMap<>(); + sColumnNameToIdMap.put(MediaStore.Files.FileColumns.IS_FAVORITE, "0"); + sColumnNameToIdMap.put(MediaStore.Files.FileColumns.MEDIA_TYPE, "1"); + sColumnNameToIdMap.put(MediaStore.Files.FileColumns.MIME_TYPE, "2"); + sColumnNameToIdMap.put(MediaStore.Files.FileColumns._USER_ID, "3"); + sColumnNameToIdMap.put(MediaStore.Files.FileColumns.SIZE, "4"); + sColumnNameToIdMap.put(MediaStore.MediaColumns.DATE_TAKEN, "5"); + sColumnNameToIdMap.put(MediaStore.MediaColumns.CD_TRACK_NUMBER, "6"); + sColumnNameToIdMap.put(MediaStore.MediaColumns.ALBUM, "7"); + sColumnNameToIdMap.put(MediaStore.MediaColumns.ARTIST, "8"); + sColumnNameToIdMap.put(MediaStore.MediaColumns.AUTHOR, "9"); + sColumnNameToIdMap.put(MediaStore.MediaColumns.COMPOSER, "10"); + sColumnNameToIdMap.put(MediaStore.MediaColumns.GENRE, "11"); + sColumnNameToIdMap.put(MediaStore.MediaColumns.TITLE, "12"); + sColumnNameToIdMap.put(MediaStore.MediaColumns.YEAR, "13"); + sColumnNameToIdMap.put(MediaStore.MediaColumns.DURATION, "14"); + sColumnNameToIdMap.put(MediaStore.MediaColumns.NUM_TRACKS, "15"); + sColumnNameToIdMap.put(MediaStore.MediaColumns.WRITER, "16"); + sColumnNameToIdMap.put(MediaStore.MediaColumns.ALBUM_ARTIST, "17"); + sColumnNameToIdMap.put(MediaStore.MediaColumns.DISC_NUMBER, "18"); + sColumnNameToIdMap.put(MediaStore.MediaColumns.COMPILATION, "19"); + sColumnNameToIdMap.put(MediaStore.MediaColumns.BITRATE, "20"); + sColumnNameToIdMap.put(MediaStore.MediaColumns.CAPTURE_FRAMERATE, "21"); + sColumnNameToIdMap.put(MediaStore.Audio.AudioColumns.TRACK, "22"); + sColumnNameToIdMap.put(MediaStore.MediaColumns.DOCUMENT_ID, "23"); + sColumnNameToIdMap.put(MediaStore.MediaColumns.INSTANCE_ID, "24"); + sColumnNameToIdMap.put(MediaStore.MediaColumns.ORIGINAL_DOCUMENT_ID, "25"); + sColumnNameToIdMap.put(MediaStore.MediaColumns.RESOLUTION, "26"); + sColumnNameToIdMap.put(MediaStore.MediaColumns.ORIENTATION, "27"); + sColumnNameToIdMap.put(MediaStore.Video.VideoColumns.COLOR_STANDARD, "28"); + sColumnNameToIdMap.put(MediaStore.Video.VideoColumns.COLOR_TRANSFER, "29"); + sColumnNameToIdMap.put(MediaStore.Video.VideoColumns.COLOR_RANGE, "30"); + sColumnNameToIdMap.put(MediaStore.Files.FileColumns._VIDEO_CODEC_TYPE, "31"); + sColumnNameToIdMap.put(MediaStore.MediaColumns.WIDTH, "32"); + sColumnNameToIdMap.put(MediaStore.MediaColumns.HEIGHT, "33"); + sColumnNameToIdMap.put(MediaStore.Images.ImageColumns.DESCRIPTION, "34"); + sColumnNameToIdMap.put(MediaStore.Images.ImageColumns.EXPOSURE_TIME, "35"); + sColumnNameToIdMap.put(MediaStore.Images.ImageColumns.F_NUMBER, "36"); + sColumnNameToIdMap.put(MediaStore.Images.ImageColumns.ISO, "37"); + sColumnNameToIdMap.put(MediaStore.Images.ImageColumns.SCENE_CAPTURE_TYPE, "38"); + sColumnNameToIdMap.put(MediaStore.Files.FileColumns._SPECIAL_FORMAT, "39"); + sColumnNameToIdMap.put(MediaStore.Files.FileColumns.OWNER_PACKAGE_NAME, "40"); + // Adding number gap to allow addition of new values + sColumnNameToIdMap.put(MediaStore.MediaColumns.XMP, "80"); + } + + static Map<String, String> deSerialiseValueString(String valueString) { + if (sColumnIdToKeyMap == null) { + createKeyToColumnNameMap(); + } + + String[] values = valueString.split(":::"); + Map<String, String> map = new HashMap<>(); + for (String value : values) { + if (value == null || value.isEmpty()) { + continue; + } + + String[] keyValue = value.split("=", 2); + map.put(sColumnIdToKeyMap.get(keyValue[0]), keyValue[1]); + } + + return map; + } + + static String createSerialisedValue(Map<String, String> entries) { + if (sColumnNameToIdMap == null) { + createColumnNameToKeyMap(); + } + + StringBuilder sb = new StringBuilder(); + for (String backupColumn : sColumnNameToIdMap.keySet()) { + if (entries.containsKey(backupColumn)) { + sb.append(sColumnNameToIdMap.get(backupColumn)).append(KEY_VALUE_SEPARATOR).append( + entries.get(backupColumn)); + sb.append(FIELD_SEPARATOR); + } + } + return sb.toString(); + } + + static boolean getSharedPreferenceValue(Context context) { + return context.getSharedPreferences(SHARED_PREFERENCE_NAME, + Context.MODE_PRIVATE).getBoolean(RESTORE_COMPLETED, false); + } +} diff --git a/tests/src/com/android/providers/media/backupandrestore/BackupExecutorTest.java b/tests/src/com/android/providers/media/backupandrestore/BackupExecutorTest.java index d464dffc3..70c7eb373 100644 --- a/tests/src/com/android/providers/media/backupandrestore/BackupExecutorTest.java +++ b/tests/src/com/android/providers/media/backupandrestore/BackupExecutorTest.java @@ -16,6 +16,7 @@ package com.android.providers.media.backupandrestore; +import static com.android.providers.media.backupandrestore.BackupAndRestoreTestUtils.deSerialiseValueString; import static com.android.providers.media.backupandrestore.BackupAndRestoreUtils.BACKUP_COLUMNS; import static com.android.providers.media.scan.MediaScanner.REASON_UNKNOWN; import static com.android.providers.media.scan.MediaScannerTest.stage; @@ -51,7 +52,6 @@ import com.android.providers.media.util.FileUtils; import org.junit.After; import org.junit.Before; -import org.junit.BeforeClass; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -75,11 +75,6 @@ public final class BackupExecutorTest { @Rule public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule(); - /** - * Map used to store key id for given column and vice versa. - */ - private static Map<String, String> sColumnIdToKeyMap; - private Set<File> mStagedFiles = new HashSet<>(); private Context mIsolatedContext; @@ -90,11 +85,6 @@ public final class BackupExecutorTest { private File mDownloadsDir; - @BeforeClass - public static void setupBeforeClass() { - createColumnToKeyMap(); - } - private String mLevelDbPath; @Before @@ -216,71 +206,9 @@ public final class BackupExecutorTest { } } - static Map<String, String> deSerialiseValueString(String valueString) { - String[] values = valueString.split(":::"); - Map<String, String> map = new HashMap<>(); - for (String value : values) { - if (value == null || value.isEmpty()) { - continue; - } - - String[] keyValue = value.split("=", 2); - map.put(sColumnIdToKeyMap.get(keyValue[0]), keyValue[1]); - } - - return map; - } - private void stageNewFile(int resId, File file) throws IOException { file.createNewFile(); mStagedFiles.add(file); stage(resId, file); } - - static void createColumnToKeyMap() { - sColumnIdToKeyMap = new HashMap<>(); - sColumnIdToKeyMap.put("0", MediaStore.Files.FileColumns.IS_FAVORITE); - sColumnIdToKeyMap.put("1", MediaStore.Files.FileColumns.MEDIA_TYPE); - sColumnIdToKeyMap.put("2", MediaStore.Files.FileColumns.MIME_TYPE); - sColumnIdToKeyMap.put("3", MediaStore.Files.FileColumns._USER_ID); - sColumnIdToKeyMap.put("4", MediaStore.Files.FileColumns.SIZE); - sColumnIdToKeyMap.put("5", MediaStore.MediaColumns.DATE_TAKEN); - sColumnIdToKeyMap.put("6", MediaStore.MediaColumns.CD_TRACK_NUMBER); - sColumnIdToKeyMap.put("7", MediaStore.MediaColumns.ALBUM); - sColumnIdToKeyMap.put("8", MediaStore.MediaColumns.ARTIST); - sColumnIdToKeyMap.put("9", MediaStore.MediaColumns.AUTHOR); - sColumnIdToKeyMap.put("10", MediaStore.MediaColumns.COMPOSER); - sColumnIdToKeyMap.put("11", MediaStore.MediaColumns.GENRE); - sColumnIdToKeyMap.put("12", MediaStore.MediaColumns.TITLE); - sColumnIdToKeyMap.put("13", MediaStore.MediaColumns.YEAR); - sColumnIdToKeyMap.put("14", MediaStore.MediaColumns.DURATION); - sColumnIdToKeyMap.put("15", MediaStore.MediaColumns.NUM_TRACKS); - sColumnIdToKeyMap.put("16", MediaStore.MediaColumns.WRITER); - sColumnIdToKeyMap.put("17", MediaStore.MediaColumns.ALBUM_ARTIST); - sColumnIdToKeyMap.put("18", MediaStore.MediaColumns.DISC_NUMBER); - sColumnIdToKeyMap.put("19", MediaStore.MediaColumns.COMPILATION); - sColumnIdToKeyMap.put("20", MediaStore.MediaColumns.BITRATE); - sColumnIdToKeyMap.put("21", MediaStore.MediaColumns.CAPTURE_FRAMERATE); - sColumnIdToKeyMap.put("22", MediaStore.Audio.AudioColumns.TRACK); - sColumnIdToKeyMap.put("23", MediaStore.MediaColumns.DOCUMENT_ID); - sColumnIdToKeyMap.put("24", MediaStore.MediaColumns.INSTANCE_ID); - sColumnIdToKeyMap.put("25", MediaStore.MediaColumns.ORIGINAL_DOCUMENT_ID); - sColumnIdToKeyMap.put("26", MediaStore.MediaColumns.RESOLUTION); - sColumnIdToKeyMap.put("27", MediaStore.MediaColumns.ORIENTATION); - sColumnIdToKeyMap.put("28", MediaStore.Video.VideoColumns.COLOR_STANDARD); - sColumnIdToKeyMap.put("29", MediaStore.Video.VideoColumns.COLOR_TRANSFER); - sColumnIdToKeyMap.put("30", MediaStore.Video.VideoColumns.COLOR_RANGE); - sColumnIdToKeyMap.put("31", MediaStore.Files.FileColumns._VIDEO_CODEC_TYPE); - sColumnIdToKeyMap.put("32", MediaStore.MediaColumns.WIDTH); - sColumnIdToKeyMap.put("33", MediaStore.MediaColumns.HEIGHT); - sColumnIdToKeyMap.put("34", MediaStore.Images.ImageColumns.DESCRIPTION); - sColumnIdToKeyMap.put("35", MediaStore.Images.ImageColumns.EXPOSURE_TIME); - sColumnIdToKeyMap.put("36", MediaStore.Images.ImageColumns.F_NUMBER); - sColumnIdToKeyMap.put("37", MediaStore.Images.ImageColumns.ISO); - sColumnIdToKeyMap.put("38", MediaStore.Images.ImageColumns.SCENE_CAPTURE_TYPE); - sColumnIdToKeyMap.put("39", MediaStore.Files.FileColumns._SPECIAL_FORMAT); - sColumnIdToKeyMap.put("40", MediaStore.Files.FileColumns.OWNER_PACKAGE_NAME); - // Adding number gap to allow addition of new values - sColumnIdToKeyMap.put("80", MediaStore.MediaColumns.XMP); - } } diff --git a/tests/src/com/android/providers/media/backupandrestore/MediaBackupAgentTest.java b/tests/src/com/android/providers/media/backupandrestore/MediaBackupAgentTest.java new file mode 100644 index 000000000..5f892f126 --- /dev/null +++ b/tests/src/com/android/providers/media/backupandrestore/MediaBackupAgentTest.java @@ -0,0 +1,189 @@ +/* + * Copyright (C) 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.providers.media.backupandrestore; + +import static com.android.providers.media.backupandrestore.BackupAndRestoreTestUtils.deSerialiseValueString; +import static com.android.providers.media.backupandrestore.BackupAndRestoreTestUtils.getSharedPreferenceValue; +import static com.android.providers.media.scan.MediaScanner.REASON_UNKNOWN; +import static com.android.providers.media.scan.MediaScannerTest.stage; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import android.Manifest; +import android.content.ContentResolver; +import android.content.ContentValues; +import android.content.Context; +import android.database.Cursor; +import android.net.Uri; +import android.os.Build; +import android.os.Environment; +import android.os.SystemClock; +import android.platform.test.annotations.EnableFlags; +import android.platform.test.flag.junit.SetFlagsRule; +import android.provider.MediaStore; + +import androidx.test.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.filters.SdkSuppress; + +import com.android.providers.media.IsolatedContext; +import com.android.providers.media.R; +import com.android.providers.media.TestConfigStore; +import com.android.providers.media.flags.Flags; +import com.android.providers.media.leveldb.LevelDBInstance; +import com.android.providers.media.leveldb.LevelDBManager; +import com.android.providers.media.leveldb.LevelDBResult; +import com.android.providers.media.scan.ModernMediaScanner; +import com.android.providers.media.util.FileUtils; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.io.File; +import java.util.Map; + +@RunWith(AndroidJUnit4.class) +@EnableFlags(Flags.FLAG_ENABLE_BACKUP_AND_RESTORE) +@SdkSuppress(minSdkVersion = Build.VERSION_CODES.S) +public class MediaBackupAgentTest { + @Rule + public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); + + private Context mIsolatedContext; + + private ContentResolver mIsolatedResolver; + + private ModernMediaScanner mModern; + + private File mDownloadsDir; + + private File mRestoreDir; + private File mBackupDir; + + private String mLevelDbPath; + private MediaBackupAgent mMediaBackupAgent; + + @Before + public void setUp() { + final Context context = InstrumentationRegistry.getTargetContext(); + androidx.test.platform.app.InstrumentationRegistry.getInstrumentation().getUiAutomation() + .adoptShellPermissionIdentity(Manifest.permission.LOG_COMPAT_CHANGE, + Manifest.permission.READ_COMPAT_CHANGE_CONFIG, + Manifest.permission.DUMP, + Manifest.permission.READ_DEVICE_CONFIG); + + mIsolatedContext = new IsolatedContext(context, "modern", /*asFuseThread*/ false); + mIsolatedResolver = mIsolatedContext.getContentResolver(); + mModern = new ModernMediaScanner(mIsolatedContext, new TestConfigStore()); + mRestoreDir = new File(mIsolatedContext.getFilesDir(), "restore"); + mBackupDir = new File(mIsolatedContext.getFilesDir(), "backup"); + mDownloadsDir = new File(Environment.getExternalStorageDirectory(), + Environment.DIRECTORY_DOWNLOADS); + mLevelDbPath = + mIsolatedContext.getFilesDir().getAbsolutePath() + "/backup/external_primary/"; + FileUtils.deleteContents(mDownloadsDir); + + mMediaBackupAgent = new MediaBackupAgent(); + mMediaBackupAgent.attach(mIsolatedContext); + } + + @Test + public void testCompleteFlow() throws Exception { + //create new test file & stage it + File file = new File(mDownloadsDir, "testImage_" + + SystemClock.elapsedRealtimeNanos() + ".jpg"); + file.createNewFile(); + stage(R.raw.test_image, file); + + try { + String path = file.getAbsolutePath(); + // scan directory to have entry in files table + mModern.scanDirectory(mDownloadsDir, REASON_UNKNOWN); + + // set is_favorite value to 1. We will check this value later after restoration. + updateFavoritesValue(path, 1); + + // run idle maintenance, this will save file's metadata in leveldb with is_favorite = 1 + MediaStore.runIdleMaintenance(mIsolatedResolver); + assertTrue(mBackupDir.exists()); + + assertLevelDbExistsAndHasLatestValues(path); + + // run the backup agent. This will copy over backup directory to restore directory and + // set shared preference. + mMediaBackupAgent.onRestoreFinished(); + assertTrue(getSharedPreferenceValue(mIsolatedContext)); + assertTrue(mRestoreDir.exists()); + assertFalse(mBackupDir.exists()); + + //delete existing external db database having old values + mIsolatedContext.deleteDatabase("external.db"); + + // run media scan, this will populate db and read value from backup + mModern.scanDirectory(mDownloadsDir, REASON_UNKNOWN); + assertEquals(1, queryFavoritesValue(path)); + + // on idle maintenance, clean up is called. It should delete restore directory and set + // shared preference to false + MediaStore.runIdleMaintenance(mIsolatedResolver); + assertFalse(getSharedPreferenceValue(mIsolatedContext)); + assertFalse(mRestoreDir.exists()); + } finally { + file.delete(); + } + } + + private void assertLevelDbExistsAndHasLatestValues(String path) { + // check that entry is created in level db for the file + LevelDBInstance levelDBInstance = LevelDBManager.getInstance(mLevelDbPath); + assertNotNull(levelDBInstance); + + // check that entry created in level db has latest value(is_favorite = 1) + LevelDBResult levelDBResult = levelDBInstance.query(path); + assertNotNull(levelDBResult); + Map<String, String> actualResultMap = deSerialiseValueString(levelDBResult.getValue()); + assertEquals(1, + Integer.parseInt(actualResultMap.get(MediaStore.MediaColumns.IS_FAVORITE))); + } + + private void updateFavoritesValue(String path, int value) { + Uri uri = MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL); + String selection = MediaStore.Files.FileColumns.DATA + " LIKE ?"; + String[] selectionArgs = new String[]{path}; + + ContentValues values = new ContentValues(); + values.put(MediaStore.Files.FileColumns.IS_FAVORITE, value); + values.put(MediaStore.MediaColumns.DATE_MODIFIED, System.currentTimeMillis()); + + mIsolatedResolver.update(uri, values, selection, selectionArgs); + } + + private int queryFavoritesValue(String path) { + Uri uri = MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL); + String selection = MediaStore.Files.FileColumns.DATA + " LIKE ?"; + String[] selectionArgs = new String[]{path}; + + Cursor cursor = mIsolatedResolver.query(uri, null, selection, selectionArgs, null); + cursor.moveToFirst(); + return cursor.getInt(cursor.getColumnIndex(MediaStore.Files.FileColumns.IS_FAVORITE)); + } +} diff --git a/tests/src/com/android/providers/media/backupandrestore/RestoreExecutorTest.java b/tests/src/com/android/providers/media/backupandrestore/RestoreExecutorTest.java index ebffecc13..9f0b41a21 100644 --- a/tests/src/com/android/providers/media/backupandrestore/RestoreExecutorTest.java +++ b/tests/src/com/android/providers/media/backupandrestore/RestoreExecutorTest.java @@ -16,8 +16,7 @@ package com.android.providers.media.backupandrestore; -import static com.android.providers.media.backupandrestore.BackupAndRestoreUtils.FIELD_SEPARATOR; -import static com.android.providers.media.backupandrestore.BackupAndRestoreUtils.KEY_VALUE_SEPARATOR; +import static com.android.providers.media.backupandrestore.BackupAndRestoreTestUtils.createSerialisedValue; import static com.android.providers.media.backupandrestore.BackupAndRestoreUtils.RESTORE_COMPLETED; import static com.android.providers.media.scan.MediaScanner.REASON_UNKNOWN; import static com.android.providers.media.scan.MediaScannerTest.stage; @@ -53,7 +52,6 @@ import com.android.providers.media.util.FileUtils; import org.junit.After; import org.junit.Before; -import org.junit.BeforeClass; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -73,11 +71,6 @@ public final class RestoreExecutorTest { @Rule public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule(); - /** - * Map used to store key id for given column and vice versa. - */ - private static Map<String, String> sColumnNameToIdMap; - private Context mIsolatedContext; private ContentResolver mIsolatedResolver; @@ -86,11 +79,6 @@ public final class RestoreExecutorTest { private File mDownloadsDir; - @BeforeClass - public static void setupBeforeClass() { - createColumnToKeyMap(); - } - @Before public void setUp() { final Context context = InstrumentationRegistry.getTargetContext(); @@ -347,63 +335,4 @@ public final class RestoreExecutorTest { file.createNewFile(); stage(resId, file); } - - private String createSerialisedValue(Map<String, String> entries) { - StringBuilder sb = new StringBuilder(); - for (String backupColumn : sColumnNameToIdMap.keySet()) { - if (entries.containsKey(backupColumn)) { - sb.append(sColumnNameToIdMap.get(backupColumn)).append(KEY_VALUE_SEPARATOR).append( - entries.get(backupColumn)); - sb.append(FIELD_SEPARATOR); - } - } - return sb.toString(); - } - - private static void createColumnToKeyMap() { - sColumnNameToIdMap = new HashMap<>(); - sColumnNameToIdMap.put(MediaStore.Files.FileColumns.IS_FAVORITE, "0"); - sColumnNameToIdMap.put(MediaStore.Files.FileColumns.MEDIA_TYPE, "1"); - sColumnNameToIdMap.put(MediaStore.Files.FileColumns.MIME_TYPE, "2"); - sColumnNameToIdMap.put(MediaStore.Files.FileColumns._USER_ID, "3"); - sColumnNameToIdMap.put(MediaStore.Files.FileColumns.SIZE, "4"); - sColumnNameToIdMap.put(MediaStore.MediaColumns.DATE_TAKEN, "5"); - sColumnNameToIdMap.put(MediaStore.MediaColumns.CD_TRACK_NUMBER, "6"); - sColumnNameToIdMap.put(MediaStore.MediaColumns.ALBUM, "7"); - sColumnNameToIdMap.put(MediaStore.MediaColumns.ARTIST, "8"); - sColumnNameToIdMap.put(MediaStore.MediaColumns.AUTHOR, "9"); - sColumnNameToIdMap.put(MediaStore.MediaColumns.COMPOSER, "10"); - sColumnNameToIdMap.put(MediaStore.MediaColumns.GENRE, "11"); - sColumnNameToIdMap.put(MediaStore.MediaColumns.TITLE, "12"); - sColumnNameToIdMap.put(MediaStore.MediaColumns.YEAR, "13"); - sColumnNameToIdMap.put(MediaStore.MediaColumns.DURATION, "14"); - sColumnNameToIdMap.put(MediaStore.MediaColumns.NUM_TRACKS, "15"); - sColumnNameToIdMap.put(MediaStore.MediaColumns.WRITER, "16"); - sColumnNameToIdMap.put(MediaStore.MediaColumns.ALBUM_ARTIST, "17"); - sColumnNameToIdMap.put(MediaStore.MediaColumns.DISC_NUMBER, "18"); - sColumnNameToIdMap.put(MediaStore.MediaColumns.COMPILATION, "19"); - sColumnNameToIdMap.put(MediaStore.MediaColumns.BITRATE, "20"); - sColumnNameToIdMap.put(MediaStore.MediaColumns.CAPTURE_FRAMERATE, "21"); - sColumnNameToIdMap.put(MediaStore.Audio.AudioColumns.TRACK, "22"); - sColumnNameToIdMap.put(MediaStore.MediaColumns.DOCUMENT_ID, "23"); - sColumnNameToIdMap.put(MediaStore.MediaColumns.INSTANCE_ID, "24"); - sColumnNameToIdMap.put(MediaStore.MediaColumns.ORIGINAL_DOCUMENT_ID, "25"); - sColumnNameToIdMap.put(MediaStore.MediaColumns.RESOLUTION, "26"); - sColumnNameToIdMap.put(MediaStore.MediaColumns.ORIENTATION, "27"); - sColumnNameToIdMap.put(MediaStore.Video.VideoColumns.COLOR_STANDARD, "28"); - sColumnNameToIdMap.put(MediaStore.Video.VideoColumns.COLOR_TRANSFER, "29"); - sColumnNameToIdMap.put(MediaStore.Video.VideoColumns.COLOR_RANGE, "30"); - sColumnNameToIdMap.put(MediaStore.Files.FileColumns._VIDEO_CODEC_TYPE, "31"); - sColumnNameToIdMap.put(MediaStore.MediaColumns.WIDTH, "32"); - sColumnNameToIdMap.put(MediaStore.MediaColumns.HEIGHT, "33"); - sColumnNameToIdMap.put(MediaStore.Images.ImageColumns.DESCRIPTION, "34"); - sColumnNameToIdMap.put(MediaStore.Images.ImageColumns.EXPOSURE_TIME, "35"); - sColumnNameToIdMap.put(MediaStore.Images.ImageColumns.F_NUMBER, "36"); - sColumnNameToIdMap.put(MediaStore.Images.ImageColumns.ISO, "37"); - sColumnNameToIdMap.put(MediaStore.Images.ImageColumns.SCENE_CAPTURE_TYPE, "38"); - sColumnNameToIdMap.put(MediaStore.Files.FileColumns._SPECIAL_FORMAT, "39"); - sColumnNameToIdMap.put(MediaStore.Files.FileColumns.OWNER_PACKAGE_NAME, "40"); - // Adding number gap to allow addition of new values - sColumnNameToIdMap.put(MediaStore.MediaColumns.XMP, "80"); - } } |