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.server.pm; 18 19 import android.content.Context; 20 import android.content.pm.UserInfo; 21 import android.os.FileUtils; 22 import android.os.storage.StorageManager; 23 import android.os.storage.VolumeInfo; 24 import android.platform.test.annotations.Presubmit; 25 import android.support.test.InstrumentationRegistry; 26 import android.support.test.filters.SmallTest; 27 import android.support.test.runner.AndroidJUnit4; 28 29 import org.junit.Before; 30 import org.junit.Test; 31 import org.junit.runner.RunWith; 32 import org.mockito.Mock; 33 import org.mockito.MockitoAnnotations; 34 35 import java.io.File; 36 import java.io.FileOutputStream; 37 import java.io.IOException; 38 import java.nio.charset.Charset; 39 import java.util.Arrays; 40 import java.util.Collections; 41 42 import static org.junit.Assert.assertEquals; 43 import static org.mockito.Matchers.eq; 44 import static org.mockito.Matchers.isNull; 45 import static org.mockito.Mockito.verify; 46 import 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 60 public 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 158 mUserDataPreparer.destroyUserData(TEST_USER_ID, StorageManager.FLAG_STORAGE_DE); 159 160 verify(mInstaller).destroyUserData(isNull(String.class), eq(TEST_USER_ID), 161 eq(StorageManager.FLAG_STORAGE_DE)); 162 verify(mStorageManagerMock).destroyUserStorage(isNull(String.class), eq(TEST_USER_ID), 163 eq(StorageManager.FLAG_STORAGE_DE)); 164 165 assertEquals(Collections.emptyList(), Arrays.asList(FileUtils.listFilesOrEmpty(systemDir))); 166 assertEquals(Collections.emptyList(), Arrays.asList(FileUtils.listFilesOrEmpty( 167 systemDeDir))); 168 } 169 170 @Test 171 public void testDestroyUserData_Ce() throws Exception { 172 File systemCeDir = mUserDataPreparer.getDataSystemCeDirectory(TEST_USER_ID); 173 systemCeDir.mkdirs(); 174 writeFile(new File(systemCeDir, "file"), "-----" ); 175 176 mUserDataPreparer.destroyUserData(TEST_USER_ID, StorageManager.FLAG_STORAGE_CE); 177 178 verify(mInstaller).destroyUserData(isNull(String.class), eq(TEST_USER_ID), 179 eq(StorageManager.FLAG_STORAGE_CE)); 180 verify(mStorageManagerMock).destroyUserStorage(isNull(String.class), eq(TEST_USER_ID), 181 eq(StorageManager.FLAG_STORAGE_CE)); 182 183 assertEquals(Collections.emptyList(), Arrays.asList(FileUtils.listFilesOrEmpty( 184 systemCeDir))); 185 } 186 187 @Test 188 public void testReconcileUsers() throws Exception { 189 UserInfo u1 = new UserInfo(1, "u1", 0); 190 UserInfo u2 = new UserInfo(2, "u2", 0); 191 File testDir = mUserDataPreparer.testDir; 192 File dir1 = new File(testDir, "1"); 193 dir1.mkdirs(); 194 File dir2 = new File(testDir, "2"); 195 dir2.mkdirs(); 196 File dir3 = new File(testDir, "3"); 197 dir3.mkdirs(); 198 199 mUserDataPreparer 200 .reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL, Arrays.asList(u1, u2), 201 Arrays.asList(dir1, dir2, dir3)); 202 // Verify that user 3 data is removed 203 verify(mInstaller).destroyUserData(isNull(String.class), eq(3), 204 eq(StorageManager.FLAG_STORAGE_DE|StorageManager.FLAG_STORAGE_CE)); 205 } 206 207 private static void writeFile(File file, String content) throws IOException { 208 try (FileOutputStream os = new FileOutputStream(file)) { 209 os.write(content.getBytes(Charset.defaultCharset())); 210 } 211 } 212 213 private static class TestUserDataPreparer extends UserDataPreparer { 214 File testDir; 215 216 TestUserDataPreparer(Installer installer, Object installLock, Context context, 217 boolean onlyCore, File testDir) { 218 super(installer, installLock, context, onlyCore); 219 this.testDir = testDir; 220 } 221 222 @Override 223 protected File getDataMiscCeDirectory(int userId) { 224 return new File(testDir, "misc_ce_" + userId); 225 } 226 227 @Override 228 protected File getDataSystemCeDirectory(int userId) { 229 return new File(testDir, "system_ce_" + userId); 230 } 231 232 @Override 233 protected File getDataMiscDeDirectory(int userId) { 234 return new File(testDir, "misc_de_" + userId); 235 } 236 237 @Override 238 protected File getUserSystemDirectory(int userId) { 239 return new File(testDir, "user_system_" + userId); 240 } 241 242 @Override 243 protected File getDataUserCeDirectory(String volumeUuid, int userId) { 244 return new File(testDir, "user_ce_" + userId); 245 } 246 247 @Override 248 protected File getDataSystemDeDirectory(int userId) { 249 return new File(testDir, "system_de_" + userId); 250 } 251 252 @Override 253 protected File getDataUserDeDirectory(String volumeUuid, int userId) { 254 return new File(testDir, "user_de_" + userId); 255 } 256 257 @Override 258 protected boolean isFileEncryptedEmulatedOnly() { 259 return false; 260 } 261 } 262 263 } 264