summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
author Darshil Shah <darshilshah@google.com> 2025-02-12 09:24:25 -0800
committer Android (Google) Code Review <android-gerrit@google.com> 2025-02-12 09:24:25 -0800
commit6813f3582452cc27c70b9783db57ac5f7d3ed612 (patch)
treec3208b701f2e555edec04818c75d31ae8a8785df /tests
parentda3fdd1076e51ab17afa4e19115e368174f4784a (diff)
parentab6f4a5085e4d1f15ac0c28e66cb0cfadeecff1c (diff)
Merge "Add configurations to support for backup and restore of MediaProvider" into main
Diffstat (limited to 'tests')
-rw-r--r--tests/src/com/android/providers/media/backupandrestore/BackupAndRestoreTestUtils.java175
-rw-r--r--tests/src/com/android/providers/media/backupandrestore/BackupExecutorTest.java74
-rw-r--r--tests/src/com/android/providers/media/backupandrestore/MediaBackupAgentTest.java189
-rw-r--r--tests/src/com/android/providers/media/backupandrestore/RestoreExecutorTest.java73
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");
- }
}