1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.documentsui.prefs; 18 19 import static org.junit.Assert.assertEquals; 20 import static org.junit.Assert.assertFalse; 21 import static org.junit.Assert.fail; 22 23 import android.content.SharedPreferences; 24 import android.content.SharedPreferences.Editor; 25 26 import androidx.test.InstrumentationRegistry; 27 import androidx.test.filters.SmallTest; 28 import androidx.test.runner.AndroidJUnit4; 29 30 import org.junit.After; 31 import org.junit.Before; 32 import org.junit.Test; 33 import org.junit.runner.RunWith; 34 35 import java.util.HashMap; 36 import java.util.HashSet; 37 import java.util.Map; 38 import java.util.Set; 39 40 @RunWith(AndroidJUnit4.class) 41 @SmallTest 42 public class PrefsBackupHelperTest { 43 44 private static final String LOCAL_PREFERENCE_1 = "rootViewMode-validPreference1"; 45 private static final String LOCAL_PREFERENCE_2 = "rootViewMode-validPreference2"; 46 private static final String SCOPED_PREFERENCE = "includeDeviceRoot"; 47 private static final String NON_BACKUP_PREFERENCE = "notBackup-invalidPreference"; 48 49 private SharedPreferences mDefaultPrefs; 50 private SharedPreferences mBackupPrefs; 51 private PrefsBackupHelper mPrefsBackupHelper; 52 53 @Before setUp()54 public void setUp() { 55 mDefaultPrefs = InstrumentationRegistry.getContext().getSharedPreferences("prefs1", 0); 56 mBackupPrefs = InstrumentationRegistry.getContext().getSharedPreferences("prefs2", 0); 57 clearSharedPrefs(); 58 mPrefsBackupHelper = new PrefsBackupHelper(mDefaultPrefs); 59 } 60 61 @After tearDown()62 public void tearDown() { 63 clearSharedPrefs(); 64 } 65 clearSharedPrefs()66 private void clearSharedPrefs() { 67 mDefaultPrefs.edit().clear().commit(); 68 mBackupPrefs.edit().clear().commit(); 69 } 70 71 @Test testPrepareBackupFile_BackupLocalPreferences()72 public void testPrepareBackupFile_BackupLocalPreferences() { 73 mDefaultPrefs.edit().putInt(LOCAL_PREFERENCE_1, 1).commit(); 74 75 mPrefsBackupHelper.getBackupPreferences(mBackupPrefs); 76 77 assertEquals(mBackupPrefs.getInt(LOCAL_PREFERENCE_1, 0), 1); 78 } 79 80 @Test testPrepareBackupFile_BackupScopedPreferences()81 public void testPrepareBackupFile_BackupScopedPreferences() { 82 mDefaultPrefs.edit().putBoolean(SCOPED_PREFERENCE, true).commit(); 83 84 mPrefsBackupHelper.getBackupPreferences(mBackupPrefs); 85 86 assertEquals(mBackupPrefs.getBoolean(SCOPED_PREFERENCE, false), true); 87 } 88 89 @Test testPrepareBackupFile_BackupNotInterestedPreferences()90 public void testPrepareBackupFile_BackupNotInterestedPreferences() { 91 mDefaultPrefs.edit().putBoolean(NON_BACKUP_PREFERENCE, true).commit(); 92 93 mPrefsBackupHelper.getBackupPreferences(mBackupPrefs); 94 95 assertFalse(mBackupPrefs.contains(NON_BACKUP_PREFERENCE)); 96 } 97 98 @Test testPrepareBackupFile_BackupUnexpectedType()99 public void testPrepareBackupFile_BackupUnexpectedType() throws Exception { 100 // Currently only Integer and Boolean type are supported. 101 mDefaultPrefs.edit().putString(LOCAL_PREFERENCE_1, "String is not accepted").commit(); 102 103 try { 104 mPrefsBackupHelper.getBackupPreferences(mBackupPrefs); 105 fail(); 106 } catch(IllegalArgumentException e) { 107 108 } finally { 109 assertFalse(mBackupPrefs.contains(LOCAL_PREFERENCE_1)); 110 } 111 } 112 113 @Test testRestorePreferences_RestoreLocalPreferences()114 public void testRestorePreferences_RestoreLocalPreferences() { 115 mBackupPrefs.edit().putInt(LOCAL_PREFERENCE_1, 1).commit(); 116 117 mPrefsBackupHelper.putBackupPreferences(mBackupPrefs); 118 119 assertEquals(mDefaultPrefs.getInt(LOCAL_PREFERENCE_1, 0), 1); 120 } 121 122 @Test testRestorePreferences_RestoreScopedPreferences()123 public void testRestorePreferences_RestoreScopedPreferences() { 124 mBackupPrefs.edit().putBoolean(SCOPED_PREFERENCE, true).commit(); 125 126 mPrefsBackupHelper.putBackupPreferences(mBackupPrefs); 127 128 assertEquals(mDefaultPrefs.getBoolean(SCOPED_PREFERENCE, false), true); 129 } 130 131 @Test testEndToEnd()132 public void testEndToEnd() { 133 // Simulating an end to end backup & restore process. At the begining, all preferences are 134 // stored in the default shared preferences file, includes preferences that we don't want 135 // to backup. 136 // 137 // On backup, we copy all preferences that we want to backup to the backup shared 138 // preferences file, and then backup that single file. 139 // 140 // On restore, we restore the backup file first, and then copy all preferences in the backup 141 // file to the app's default shared preferences file. 142 143 SharedPreferences.Editor editor = mDefaultPrefs.edit(); 144 145 // Set preferences to the default file, includes preferences that are not backed up. 146 editor.putInt(LOCAL_PREFERENCE_1, 1); 147 editor.putInt(LOCAL_PREFERENCE_2, 2); 148 editor.putBoolean(SCOPED_PREFERENCE, true); 149 editor.putBoolean(NON_BACKUP_PREFERENCE, true); 150 editor.commit(); 151 152 // Write all backed up preferences to backup shared preferences file. 153 mPrefsBackupHelper.getBackupPreferences(mBackupPrefs); 154 155 // Assume we are doing backup to the backup file. 156 157 // Clear all preferences in default shared preferences file. 158 editor.clear().commit(); 159 160 // Assume we are doing restore to the backup file. 161 162 // Copy all backuped preferences to default shared preferences file. 163 mPrefsBackupHelper.putBackupPreferences(mBackupPrefs); 164 165 // Check all preferences are correctly restored. 166 assertEquals(mDefaultPrefs.getInt(LOCAL_PREFERENCE_1, 0), 1); 167 assertEquals(mDefaultPrefs.getInt(LOCAL_PREFERENCE_2, 0), 2); 168 assertEquals(mDefaultPrefs.getBoolean(SCOPED_PREFERENCE, false), true); 169 assertFalse(mDefaultPrefs.contains(NON_BACKUP_PREFERENCE)); 170 } 171 172 @Test testPreferenceTypesSupport()173 public void testPreferenceTypesSupport() { 174 Map<String, Object> map = new HashMap<String, Object>(); 175 map.put("int", (Integer) 1); 176 map.put("float", (Float) 0.1f); 177 map.put("long", (Long) 10000000000l); 178 map.put("boolean", true); 179 map.put("String", "String"); 180 Set<String> stringSet = new HashSet<String>(); 181 stringSet.add("string1"); 182 stringSet.add("string2"); 183 map.put("StringSet", stringSet); 184 185 // SharedPreferences accept Integer, Float, Long, Boolean, String, Set<String> types. 186 // Currently in DocumentsUI, only Integer and Boolean preferences are backed up. 187 for (Map.Entry<String, ?> entry : map.entrySet()) { 188 String key = entry.getKey(); 189 Object value = entry.getValue(); 190 Editor editor = mDefaultPrefs.edit().clear(); 191 if (value instanceof Integer) { 192 mPrefsBackupHelper.setPreference(editor, entry); 193 editor.apply(); 194 assertEquals(mDefaultPrefs.getInt("int", 0), 1); 195 } else if(value instanceof Boolean) { 196 mPrefsBackupHelper.setPreference(editor, entry); 197 editor.apply(); 198 assertEquals(mDefaultPrefs.getBoolean("boolean", false), true); 199 } else { 200 try { 201 mPrefsBackupHelper.setPreference(editor, entry); 202 fail(); 203 } catch(IllegalArgumentException e) { 204 205 } finally { 206 editor.apply(); 207 assertFalse(mDefaultPrefs.contains(key)); 208 } 209 } 210 } 211 } 212 } 213