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 17package com.android.server.pm; 18 19import android.content.Context; 20import android.content.pm.UserInfo; 21import android.os.FileUtils; 22import android.os.storage.StorageManager; 23import android.os.storage.VolumeInfo; 24import android.platform.test.annotations.Presubmit; 25import android.support.test.InstrumentationRegistry; 26import android.support.test.filters.SmallTest; 27import android.support.test.runner.AndroidJUnit4; 28 29import org.junit.Before; 30import org.junit.Test; 31import org.junit.runner.RunWith; 32import org.mockito.Mock; 33import org.mockito.MockitoAnnotations; 34 35import java.io.File; 36import java.io.FileOutputStream; 37import java.io.IOException; 38import java.nio.charset.Charset; 39import java.util.Arrays; 40import java.util.Collections; 41 42import static org.junit.Assert.assertEquals; 43import static org.mockito.Matchers.eq; 44import static org.mockito.Matchers.isNull; 45import static org.mockito.Mockito.verify; 46import static org.mockito.Mockito.when; 47 48/** 49 * <p>Run with:<pre> 50 * m FrameworksServicesTests && 51 * adb install \ 52 * -r out/target/product/hammerhead/data/app/FrameworksServicesTests/FrameworksServicesTests.apk && 53 * adb shell am instrument -e class com.android.server.pm.UserDataPreparerTest \ 54 * -w com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner 55 * </pre> 56 */ 57@RunWith(AndroidJUnit4.class) 58@Presubmit 59@SmallTest 60public class UserDataPreparerTest { 61 62 private static final int TEST_USER_SERIAL = 1000; 63 private static final int TEST_USER_ID = 10; 64 65 private TestUserDataPreparer mUserDataPreparer; 66 67 @Mock 68 private StorageManager mStorageManagerMock; 69 70 @Mock 71 private Context mContextMock; 72 73 @Mock 74 private Installer mInstaller; 75 76 private Object mInstallLock; 77 78 @Before 79 public void setup() { 80 Context ctx = InstrumentationRegistry.getContext(); 81 FileUtils.deleteContents(ctx.getCacheDir()); 82 mInstallLock = new Object(); 83 MockitoAnnotations.initMocks(this); 84 mUserDataPreparer = new TestUserDataPreparer(mInstaller, mInstallLock, mContextMock, false, 85 ctx.getCacheDir()); 86 when(mContextMock.getSystemServiceName(StorageManager.class)) 87 .thenReturn(Context.STORAGE_SERVICE); 88 when(mContextMock.getSystemService(eq(Context.STORAGE_SERVICE))) 89 .thenReturn(mStorageManagerMock); 90 VolumeInfo testVolume = new VolumeInfo("testuuid", VolumeInfo.TYPE_PRIVATE, null, null); 91 when(mStorageManagerMock.getWritablePrivateVolumes()).thenReturn(Arrays.asList(testVolume)); 92 } 93 94 @Test 95 public void testPrepareUserData_De() throws Exception { 96 File userDeDir = mUserDataPreparer.getDataUserDeDirectory(null, TEST_USER_ID); 97 userDeDir.mkdirs(); 98 File systemDeDir = mUserDataPreparer.getDataSystemDeDirectory(TEST_USER_ID); 99 systemDeDir.mkdirs(); 100 mUserDataPreparer 101 .prepareUserData(TEST_USER_ID, TEST_USER_SERIAL, StorageManager.FLAG_STORAGE_DE); 102 verify(mStorageManagerMock).prepareUserStorage(isNull(String.class), eq(TEST_USER_ID), 103 eq(TEST_USER_SERIAL), eq(StorageManager.FLAG_STORAGE_DE)); 104 verify(mInstaller).createUserData(isNull(String.class), eq(TEST_USER_ID), 105 eq(TEST_USER_SERIAL), eq(StorageManager.FLAG_STORAGE_DE)); 106 int serialNumber = UserDataPreparer.getSerialNumber(userDeDir); 107 assertEquals(TEST_USER_SERIAL, serialNumber); 108 serialNumber = UserDataPreparer.getSerialNumber(systemDeDir); 109 assertEquals(TEST_USER_SERIAL, serialNumber); 110 } 111 112 @Test 113 public void testPrepareUserData_Ce() throws Exception { 114 File userCeDir = mUserDataPreparer.getDataUserCeDirectory(null, TEST_USER_ID); 115 userCeDir.mkdirs(); 116 File systemCeDir = mUserDataPreparer.getDataSystemCeDirectory(TEST_USER_ID); 117 systemCeDir.mkdirs(); 118 mUserDataPreparer 119 .prepareUserData(TEST_USER_ID, TEST_USER_SERIAL, StorageManager.FLAG_STORAGE_CE); 120 verify(mStorageManagerMock).prepareUserStorage(isNull(String.class), eq(TEST_USER_ID), 121 eq(TEST_USER_SERIAL), eq(StorageManager.FLAG_STORAGE_CE)); 122 verify(mInstaller).createUserData(isNull(String.class), eq(TEST_USER_ID), 123 eq(TEST_USER_SERIAL), eq(StorageManager.FLAG_STORAGE_CE)); 124 int serialNumber = UserDataPreparer.getSerialNumber(userCeDir); 125 assertEquals(TEST_USER_SERIAL, serialNumber); 126 serialNumber = UserDataPreparer.getSerialNumber(systemCeDir); 127 assertEquals(TEST_USER_SERIAL, serialNumber); 128 } 129 130 @Test 131 public void testDestroyUserData() throws Exception { 132 // Add file in CE 133 File systemCeDir = mUserDataPreparer.getDataSystemCeDirectory(TEST_USER_ID); 134 systemCeDir.mkdirs(); 135 File ceFile = new File(systemCeDir, "file"); 136 writeFile(ceFile, "-----" ); 137 testDestroyUserData_De(); 138 // CE directory should be preserved 139 assertEquals(Collections.singletonList(ceFile), Arrays.asList(FileUtils.listFilesOrEmpty( 140 systemCeDir))); 141 142 testDestroyUserData_Ce(); 143 144 // Verify that testDir is empty 145 assertEquals(Collections.emptyList(), Arrays.asList(FileUtils.listFilesOrEmpty( 146 mUserDataPreparer.testDir))); 147 } 148 149 @Test 150 public void testDestroyUserData_De() throws Exception { 151 File systemDir = mUserDataPreparer.getUserSystemDirectory(TEST_USER_ID); 152 systemDir.mkdirs(); 153 writeFile(new File(systemDir, "file"), "-----" ); 154 File systemDeDir = mUserDataPreparer.getDataSystemDeDirectory(TEST_USER_ID); 155 systemDeDir.mkdirs(); 156 writeFile(new File(systemDeDir, "file"), "-----" ); 157 File miscDeDir = mUserDataPreparer.getDataMiscDeDirectory(TEST_USER_ID); 158 miscDeDir.mkdirs(); 159 writeFile(new File(miscDeDir, "file"), "-----" ); 160 161 mUserDataPreparer.destroyUserData(TEST_USER_ID, StorageManager.FLAG_STORAGE_DE); 162 163 verify(mInstaller).destroyUserData(isNull(String.class), eq(TEST_USER_ID), 164 eq(StorageManager.FLAG_STORAGE_DE)); 165 verify(mStorageManagerMock).destroyUserStorage(isNull(String.class), eq(TEST_USER_ID), 166 eq(StorageManager.FLAG_STORAGE_DE)); 167 168 assertEquals(Collections.emptyList(), Arrays.asList(FileUtils.listFilesOrEmpty(systemDir))); 169 assertEquals(Collections.emptyList(), Arrays.asList(FileUtils.listFilesOrEmpty( 170 systemDeDir))); 171 assertEquals(Collections.emptyList(), Arrays.asList(FileUtils.listFilesOrEmpty( 172 miscDeDir))); 173 } 174 175 @Test 176 public void testDestroyUserData_Ce() throws Exception { 177 File systemCeDir = mUserDataPreparer.getDataSystemCeDirectory(TEST_USER_ID); 178 systemCeDir.mkdirs(); 179 writeFile(new File(systemCeDir, "file"), "-----" ); 180 File miscCeDir = mUserDataPreparer.getDataMiscCeDirectory(TEST_USER_ID); 181 miscCeDir.mkdirs(); 182 writeFile(new File(miscCeDir, "file"), "-----" ); 183 184 mUserDataPreparer.destroyUserData(TEST_USER_ID, StorageManager.FLAG_STORAGE_CE); 185 186 verify(mInstaller).destroyUserData(isNull(String.class), eq(TEST_USER_ID), 187 eq(StorageManager.FLAG_STORAGE_CE)); 188 verify(mStorageManagerMock).destroyUserStorage(isNull(String.class), eq(TEST_USER_ID), 189 eq(StorageManager.FLAG_STORAGE_CE)); 190 191 assertEquals(Collections.emptyList(), Arrays.asList(FileUtils.listFilesOrEmpty( 192 systemCeDir))); 193 assertEquals(Collections.emptyList(), Arrays.asList(FileUtils.listFilesOrEmpty( 194 miscCeDir))); 195 } 196 197 @Test 198 public void testReconcileUsers() throws Exception { 199 UserInfo u1 = new UserInfo(1, "u1", 0); 200 UserInfo u2 = new UserInfo(2, "u2", 0); 201 File testDir = mUserDataPreparer.testDir; 202 File dir1 = new File(testDir, "1"); 203 dir1.mkdirs(); 204 File dir2 = new File(testDir, "2"); 205 dir2.mkdirs(); 206 File dir3 = new File(testDir, "3"); 207 dir3.mkdirs(); 208 209 mUserDataPreparer 210 .reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL, Arrays.asList(u1, u2), 211 Arrays.asList(dir1, dir2, dir3)); 212 // Verify that user 3 data is removed 213 verify(mInstaller).destroyUserData(isNull(String.class), eq(3), 214 eq(StorageManager.FLAG_STORAGE_DE|StorageManager.FLAG_STORAGE_CE)); 215 } 216 217 private static void writeFile(File file, String content) throws IOException { 218 try (FileOutputStream os = new FileOutputStream(file)) { 219 os.write(content.getBytes(Charset.defaultCharset())); 220 } 221 } 222 223 private static class TestUserDataPreparer extends UserDataPreparer { 224 File testDir; 225 226 TestUserDataPreparer(Installer installer, Object installLock, Context context, 227 boolean onlyCore, File testDir) { 228 super(installer, installLock, context, onlyCore); 229 this.testDir = testDir; 230 } 231 232 @Override 233 protected File getDataMiscCeDirectory(int userId) { 234 return new File(testDir, "misc_ce_" + userId); 235 } 236 237 @Override 238 protected File getDataSystemCeDirectory(int userId) { 239 return new File(testDir, "system_ce_" + userId); 240 } 241 242 @Override 243 protected File getDataMiscDeDirectory(int userId) { 244 return new File(testDir, "misc_de_" + userId); 245 } 246 247 @Override 248 protected File getUserSystemDirectory(int userId) { 249 return new File(testDir, "user_system_" + userId); 250 } 251 252 @Override 253 protected File getDataUserCeDirectory(String volumeUuid, int userId) { 254 return new File(testDir, "user_ce_" + userId); 255 } 256 257 @Override 258 protected File getDataSystemDeDirectory(int userId) { 259 return new File(testDir, "system_de_" + userId); 260 } 261 262 @Override 263 protected File getDataUserDeDirectory(String volumeUuid, int userId) { 264 return new File(testDir, "user_de_" + userId); 265 } 266 267 @Override 268 protected boolean isFileEncryptedEmulatedOnly() { 269 return false; 270 } 271 } 272 273} 274