Home | History | Annotate | Download | only in pm
      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