1 /* 2 * Copyright (C) 2022 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.systemui.settings 18 19 import android.content.BroadcastReceiver 20 import android.content.Context 21 import android.content.IntentFilter 22 import android.os.Environment 23 import android.os.UserManager 24 import android.testing.AndroidTestingRunner 25 import androidx.test.filters.SmallTest 26 import com.android.systemui.SysuiTestCase 27 import com.android.systemui.broadcast.BroadcastDispatcher 28 import com.android.systemui.util.concurrency.FakeExecutor 29 import com.android.systemui.util.mockito.any 30 import com.android.systemui.util.mockito.eq 31 import com.android.systemui.util.time.FakeSystemClock 32 import com.google.common.truth.Truth.assertThat 33 import java.io.File 34 import java.nio.file.Files 35 import java.util.concurrent.Executor 36 import org.junit.Before 37 import org.junit.Test 38 import org.junit.runner.RunWith 39 import org.mockito.Mock 40 import org.mockito.Mockito.atLeastOnce 41 import org.mockito.Mockito.isNull 42 import org.mockito.Mockito.spy 43 import org.mockito.Mockito.verify 44 import org.mockito.MockitoAnnotations 45 46 @SmallTest 47 @RunWith(AndroidTestingRunner::class) 48 class UserFileManagerImplTest : SysuiTestCase() { 49 companion object { 50 const val TEST_FILE_NAME = "abc.txt" 51 } 52 53 lateinit var userFileManager: UserFileManagerImpl 54 lateinit var backgroundExecutor: FakeExecutor 55 @Mock lateinit var userManager: UserManager 56 @Mock lateinit var broadcastDispatcher: BroadcastDispatcher 57 58 @Before 59 fun setUp() { 60 MockitoAnnotations.initMocks(this) 61 backgroundExecutor = FakeExecutor(FakeSystemClock()) 62 userFileManager = 63 UserFileManagerImpl(context, userManager, broadcastDispatcher, backgroundExecutor) 64 } 65 66 @Test 67 fun testGetFile() { 68 assertThat(userFileManager.getFile(TEST_FILE_NAME, 0).path) 69 .isEqualTo("${context.filesDir}/$TEST_FILE_NAME") 70 assertThat(userFileManager.getFile(TEST_FILE_NAME, 11).path) 71 .isEqualTo("${context.filesDir}/__USER_11_$TEST_FILE_NAME") 72 } 73 74 @Test 75 fun testGetSharedPreferences() { 76 val primarySharedPref = userFileManager.getSharedPreferences(TEST_FILE_NAME, 0, 0) 77 val secondarySharedPref = userFileManager.getSharedPreferences(TEST_FILE_NAME, 0, 11) 78 79 assertThat(primarySharedPref).isNotEqualTo(secondarySharedPref) 80 81 // Make sure these are different files 82 primarySharedPref.edit().putString("TEST", "ABC").commit() 83 assertThat(secondarySharedPref.getString("TEST", null)).isNull() 84 85 context.deleteSharedPreferences("TEST") 86 context.deleteSharedPreferences("__USER_11_TEST") 87 } 88 89 @Test 90 fun testMigrateFile() { 91 val userId = 12 92 val fileName = "myFile.txt" 93 val fileContents = "TestingFile" 94 val legacyFile = 95 UserFileManagerImpl.createLegacyFile( 96 context, 97 UserFileManagerImpl.FILES, 98 fileName, 99 userId 100 )!! 101 102 // Write file to legacy area 103 Files.createDirectories(legacyFile.getParentFile().toPath()) 104 Files.write(legacyFile.toPath(), fileContents.toByteArray()) 105 assertThat(legacyFile.exists()).isTrue() 106 107 // getFile() should migrate the legacy file to the new location 108 val file = userFileManager.getFile(fileName, userId) 109 val newContents = String(Files.readAllBytes(file.toPath())) 110 111 assertThat(newContents).isEqualTo(fileContents) 112 assertThat(legacyFile.exists()).isFalse() 113 assertThat(File(context.filesDir, UserFileManagerImpl.ROOT_DIR).exists()).isFalse() 114 } 115 116 @Test 117 fun testMigrateSharedPrefs() { 118 val userId = 13 119 val fileName = "myFile" 120 val contents = "TestingSharedPrefs" 121 val legacyFile = 122 UserFileManagerImpl.createLegacyFile( 123 context, 124 UserFileManagerImpl.SHARED_PREFS, 125 "$fileName.xml", 126 userId 127 )!! 128 129 // Write a valid shared prefs xml file to legacy area 130 val tmpPrefs = context.getSharedPreferences("tmp", Context.MODE_PRIVATE) 131 tmpPrefs.edit().putString(contents, contents).commit() 132 Files.createDirectories(legacyFile.getParentFile().toPath()) 133 val tmpFile = 134 Environment.buildPath(context.dataDir, UserFileManagerImpl.SHARED_PREFS, "tmp.xml") 135 tmpFile.renameTo(legacyFile) 136 assertThat(legacyFile.exists()).isTrue() 137 138 // getSharedpreferences() should migrate the legacy file to the new location 139 val prefs = userFileManager.getSharedPreferences(fileName, Context.MODE_PRIVATE, userId) 140 assertThat(prefs.getString(contents, "")).isEqualTo(contents) 141 assertThat(legacyFile.exists()).isFalse() 142 assertThat(File(context.filesDir, UserFileManagerImpl.ROOT_DIR).exists()).isFalse() 143 } 144 145 @Test 146 fun testUserFileManagerStart() { 147 val userFileManager = spy(userFileManager) 148 userFileManager.start() 149 verify(userFileManager).clearDeletedUserData() 150 verify(broadcastDispatcher) 151 .registerReceiver( 152 any(BroadcastReceiver::class.java), 153 any(IntentFilter::class.java), 154 any(Executor::class.java), 155 isNull(), 156 eq(Context.RECEIVER_EXPORTED), 157 isNull() 158 ) 159 } 160 161 @Test 162 fun testClearDeletedUserData() { 163 val file = userFileManager.getFile(TEST_FILE_NAME, 11) 164 file.createNewFile() 165 166 assertThat(file.exists()).isTrue() 167 userFileManager.clearDeletedUserData() 168 assertThat(backgroundExecutor.runAllReady()).isGreaterThan(0) 169 verify(userManager, atLeastOnce()).aliveUsers 170 171 assertThat(file.exists()).isFalse() 172 } 173 } 174