PackageManagerSettingsTests.java revision 788c8423d19972389b82a23dec297eb27d819c86
1/*
2 * Copyright (C) 2012 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 static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
20import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
21import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
22import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
23
24import static org.hamcrest.CoreMatchers.is;
25import static org.hamcrest.CoreMatchers.not;
26import static org.hamcrest.CoreMatchers.notNullValue;
27import static org.hamcrest.CoreMatchers.nullValue;
28import static org.junit.Assert.assertThat;
29import static org.junit.Assert.fail;
30
31import android.annotation.NonNull;
32import android.content.Context;
33import android.content.pm.ApplicationInfo;
34import android.content.pm.PackageParser;
35import android.content.pm.PackageUserState;
36import android.content.pm.UserInfo;
37import android.os.Process;
38import android.os.UserHandle;
39import android.os.UserManagerInternal;
40import android.support.test.InstrumentationRegistry;
41import android.support.test.runner.AndroidJUnit4;
42import android.test.suitebuilder.annotation.SmallTest;
43import android.util.ArrayMap;
44import android.util.ArraySet;
45import android.util.Log;
46import android.util.LongSparseArray;
47
48import com.android.internal.os.AtomicFile;
49import com.android.internal.util.FastPrintWriter;
50import com.android.server.LocalServices;
51
52import org.hamcrest.core.IsNot;
53import org.junit.Before;
54import org.junit.Test;
55import org.junit.runner.RunWith;
56
57import java.lang.reflect.Constructor;
58import java.lang.reflect.Method;
59import java.nio.charset.StandardCharsets;
60import java.io.ByteArrayOutputStream;
61import java.io.File;
62import java.io.FileOutputStream;
63import java.io.IOException;
64import java.io.PrintStream;
65import java.security.PublicKey;
66import java.util.ArrayList;
67import java.util.List;
68
69@RunWith(AndroidJUnit4.class)
70@SmallTest
71public class PackageManagerSettingsTests {
72    private static final String PACKAGE_NAME_2 = "com.google.app2";
73    private static final String PACKAGE_NAME_3 = "com.android.app3";
74    private static final String PACKAGE_NAME_1 = "com.google.app1";
75    public static final String TAG = "PackageManagerSettingsTests";
76    protected final String PREFIX = "android.content.pm";
77
78    /** make sure our initialized KeySetManagerService metadata matches packages.xml */
79    @Test
80    public void testReadKeySetSettings()
81            throws ReflectiveOperationException, IllegalAccessException {
82        /* write out files and read */
83        writeOldFiles();
84        Settings settings =
85                new Settings(InstrumentationRegistry.getContext().getFilesDir(), new Object());
86        assertThat(settings.readLPw(createFakeUsers()), is(true));
87        verifyKeySetMetaData(settings);
88    }
89
90    /** read in data, write it out, and read it back in.  Verify same. */
91    @Test
92    public void testWriteKeySetSettings()
93            throws ReflectiveOperationException, IllegalAccessException {
94        // write out files and read
95        writeOldFiles();
96        Settings settings =
97                new Settings(InstrumentationRegistry.getContext().getFilesDir(), new Object());
98        assertThat(settings.readLPw(createFakeUsers()), is(true));
99
100        // write out, read back in and verify the same
101        settings.writeLPr();
102        assertThat(settings.readLPw(createFakeUsers()), is(true));
103        verifyKeySetMetaData(settings);
104    }
105
106    @Test
107    public void testSettingsReadOld() {
108        // Write the package files and make sure they're parsed properly the first time
109        writeOldFiles();
110        Settings settings =
111                new Settings(InstrumentationRegistry.getContext().getFilesDir(), new Object());
112        assertThat(settings.readLPw(createFakeUsers()), is(true));
113        assertThat(settings.peekPackageLPr(PACKAGE_NAME_3), is(notNullValue()));
114        assertThat(settings.peekPackageLPr(PACKAGE_NAME_1), is(notNullValue()));
115
116        PackageSetting ps = settings.peekPackageLPr(PACKAGE_NAME_1);
117        assertThat(ps.getEnabled(0), is(COMPONENT_ENABLED_STATE_DEFAULT));
118        assertThat(ps.getNotLaunched(0), is(true));
119
120        ps = settings.peekPackageLPr(PACKAGE_NAME_2);
121        assertThat(ps.getStopped(0), is(false));
122        assertThat(ps.getEnabled(0), is(COMPONENT_ENABLED_STATE_DISABLED_USER));
123        assertThat(ps.getEnabled(1), is(COMPONENT_ENABLED_STATE_DEFAULT));
124    }
125
126    @Test
127    public void testNewPackageRestrictionsFile() throws ReflectiveOperationException {
128        // Write the package files and make sure they're parsed properly the first time
129        writeOldFiles();
130        Settings settings =
131                new Settings(InstrumentationRegistry.getContext().getFilesDir(), new Object());
132        assertThat(settings.readLPw(createFakeUsers()), is(true));
133        settings.writeLPr();
134
135        // Create Settings again to make it read from the new files
136        settings = new Settings(InstrumentationRegistry.getContext().getFilesDir(), new Object());
137        assertThat(settings.readLPw(createFakeUsers()), is(true));
138
139        PackageSetting ps = settings.peekPackageLPr(PACKAGE_NAME_2);
140        assertThat(ps.getEnabled(0), is(COMPONENT_ENABLED_STATE_DISABLED_USER));
141        assertThat(ps.getEnabled(1), is(COMPONENT_ENABLED_STATE_DEFAULT));
142    }
143
144    @Test
145    public void testEnableDisable() {
146        // Write the package files and make sure they're parsed properly the first time
147        writeOldFiles();
148        Settings settings =
149                new Settings(InstrumentationRegistry.getContext().getFilesDir(), new Object());
150        assertThat(settings.readLPw(createFakeUsers()), is(true));
151
152        // Enable/Disable a package
153        PackageSetting ps = settings.peekPackageLPr(PACKAGE_NAME_1);
154        ps.setEnabled(COMPONENT_ENABLED_STATE_DISABLED, 0, null);
155        ps.setEnabled(COMPONENT_ENABLED_STATE_ENABLED, 1, null);
156        assertThat(ps.getEnabled(0), is(COMPONENT_ENABLED_STATE_DISABLED));
157        assertThat(ps.getEnabled(1), is(COMPONENT_ENABLED_STATE_ENABLED));
158
159        // Enable/Disable a component
160        ArraySet<String> components = new ArraySet<String>();
161        String component1 = PACKAGE_NAME_1 + "/.Component1";
162        components.add(component1);
163        ps.setDisabledComponents(components, 0);
164        ArraySet<String> componentsDisabled = ps.getDisabledComponents(0);
165        assertThat(componentsDisabled.size(), is(1));
166        assertThat(componentsDisabled.toArray()[0], is(component1));
167        boolean hasEnabled =
168                ps.getEnabledComponents(0) != null && ps.getEnabledComponents(1).size() > 0;
169        assertThat(hasEnabled, is(false));
170
171        // User 1 should not have any disabled components
172        boolean hasDisabled =
173                ps.getDisabledComponents(1) != null && ps.getDisabledComponents(1).size() > 0;
174        assertThat(hasDisabled, is(false));
175        ps.setEnabledComponents(components, 1);
176        assertThat(ps.getEnabledComponents(1).size(), is(1));
177        hasEnabled = ps.getEnabledComponents(0) != null && ps.getEnabledComponents(0).size() > 0;
178        assertThat(hasEnabled, is(false));
179    }
180
181    private static final String PACKAGE_NAME = "com.android.bar";
182    private static final String REAL_PACKAGE_NAME = "com.android.foo";
183    private static final File INITIAL_CODE_PATH =
184            new File(InstrumentationRegistry.getContext().getFilesDir(), "com.android.bar-1");
185    private static final File UPDATED_CODE_PATH =
186            new File(InstrumentationRegistry.getContext().getFilesDir(), "com.android.bar-2");
187    private static final int INITIAL_VERSION_CODE = 10023;
188    private static final int UPDATED_VERSION_CODE = 10025;
189
190    /** Update existing package; don't install */
191    @Test
192    public void testUpdatePackageSetting01()
193            throws ReflectiveOperationException, PackageManagerException {
194        final PackageSetting pkgSetting01 = createPackageSetting(0 /*pkgFlags*/);
195        final PackageSetting oldPkgSetting01 = new PackageSetting(pkgSetting01);
196        final PackageSetting testPkgSetting01 = Settings.updatePackageSetting(
197                pkgSetting01,
198                PACKAGE_NAME,
199                null /*realPkgName*/,
200                null /*originalPkg*/,
201                null /*disabledPkg*/,
202                null /*sharedUser*/,
203                UPDATED_CODE_PATH /*codePath*/,
204                UPDATED_CODE_PATH /*resourcePath*/,
205                null /*legacyNativeLibraryPath*/,
206                "arm64-v8a" /*primaryCpuAbi*/,
207                "armeabi" /*secondaryCpuAbi*/,
208                UPDATED_VERSION_CODE /*versionCode*/,
209                ApplicationInfo.FLAG_SYSTEM /*pkgFlags*/,
210                ApplicationInfo.PRIVATE_FLAG_PRIVILEGED /*pkgPrivateFlags*/,
211                null /*installUser*/,
212                false /*allowInstall*/,
213                null /*parentPkgName*/,
214                null /*childPkgNames*/,
215                UserManagerService.getInstance());
216        assertThat(testPkgSetting01, is(pkgSetting01));
217        assertThat(testPkgSetting01.primaryCpuAbiString, is("arm64-v8a"));
218        assertThat(testPkgSetting01.secondaryCpuAbiString, is("armeabi"));
219        assertThat(testPkgSetting01.origPackage, is(nullValue()));
220        assertThat(testPkgSetting01.pkgFlags, is(ApplicationInfo.FLAG_SYSTEM));
221        assertThat(testPkgSetting01.pkgPrivateFlags, is(ApplicationInfo.PRIVATE_FLAG_PRIVILEGED));
222        final PackageUserState userState = testPkgSetting01.readUserState(UserHandle.USER_SYSTEM);
223        final PackageUserState oldUserState = oldPkgSetting01.readUserState(UserHandle.USER_SYSTEM);
224        verifyUserState(userState, oldUserState, false /*userStateChanged*/);
225    }
226
227    /** Update existing package; install for UserHandle.SYSTEM */
228    @Test
229    public void testUpdatePackageSetting02()
230            throws ReflectiveOperationException, PackageManagerException {
231        final PackageSetting pkgSetting01 = createPackageSetting(0 /*pkgFlags*/);
232        final PackageSetting oldPkgSetting01 = new PackageSetting(pkgSetting01);
233        final PackageSetting testPkgSetting01 = Settings.updatePackageSetting(
234                pkgSetting01,
235                PACKAGE_NAME,
236                null /*realPkgName*/,
237                null /*originalPkg*/,
238                null /*disabledPkg*/,
239                null /*sharedUser*/,
240                UPDATED_CODE_PATH /*codePath*/,
241                UPDATED_CODE_PATH /*resourcePath*/,
242                null /*legacyNativeLibraryPath*/,
243                "arm64-v8a" /*primaryCpuAbi*/,
244                "armeabi" /*secondaryCpuAbi*/,
245                UPDATED_VERSION_CODE /*versionCode*/,
246                0 /*pkgFlags*/,
247                0 /*pkgPrivateFlags*/,
248                UserHandle.SYSTEM /*installUser*/,
249                true /*allowInstall*/,
250                null /*parentPkgName*/,
251                null /*childPkgNames*/,
252                UserManagerService.getInstance());
253        assertThat(testPkgSetting01, is(pkgSetting01));
254        assertThat(testPkgSetting01.primaryCpuAbiString, is("arm64-v8a"));
255        assertThat(testPkgSetting01.secondaryCpuAbiString, is("armeabi"));
256        assertThat(testPkgSetting01.origPackage, is(nullValue()));
257        assertThat(testPkgSetting01.pkgFlags, is(0));
258        assertThat(testPkgSetting01.pkgPrivateFlags, is(0));
259        final PackageUserState userState = testPkgSetting01.readUserState(UserHandle.USER_SYSTEM);
260        final PackageUserState oldUserState = oldPkgSetting01.readUserState(UserHandle.USER_SYSTEM);
261        // The user state won't be changed in this scenario; the default user state is for
262        // the package to be installed.
263        verifyUserState(userState, oldUserState, false /*userStateChanged*/,
264                false /*notLaunched*/, false /*stopped*/);
265    }
266
267    /** Update existing package; install for {@code null} */
268    @Test
269    public void testUpdatePackageSetting03()
270            throws ReflectiveOperationException, PackageManagerException {
271        final PackageSetting pkgSetting01 = createPackageSetting(0 /*pkgFlags*/);
272        final PackageSetting oldPkgSetting01 = new PackageSetting(pkgSetting01);
273        final PackageSetting testPkgSetting01 = Settings.updatePackageSetting(
274                pkgSetting01,
275                PACKAGE_NAME,
276                null /*realPkgName*/,
277                null /*originalPkg*/,
278                null /*disabledPkg*/,
279                null /*sharedUser*/,
280                UPDATED_CODE_PATH /*codePath*/,
281                UPDATED_CODE_PATH /*resourcePath*/,
282                null /*legacyNativeLibraryPath*/,
283                "arm64-v8a" /*primaryCpuAbi*/,
284                "armeabi" /*secondaryCpuAbi*/,
285                UPDATED_VERSION_CODE /*versionCode*/,
286                0 /*pkgFlags*/,
287                0 /*pkgPrivateFlags*/,
288                null /*installUser*/,
289                true /*allowInstall*/,
290                null /*parentPkgName*/,
291                null /*childPkgNames*/,
292                UserManagerService.getInstance());
293        assertThat(testPkgSetting01, is(pkgSetting01));
294        assertThat(testPkgSetting01.primaryCpuAbiString, is("arm64-v8a"));
295        assertThat(testPkgSetting01.secondaryCpuAbiString, is("armeabi"));
296        assertThat(testPkgSetting01.origPackage, is(nullValue()));
297        assertThat(testPkgSetting01.pkgFlags, is(0));
298        assertThat(testPkgSetting01.pkgPrivateFlags, is(0));
299        final PackageUserState userState = testPkgSetting01.readUserState(UserHandle.USER_SYSTEM);
300        final PackageUserState oldUserState = oldPkgSetting01.readUserState(UserHandle.USER_SYSTEM);
301        verifyUserState(userState, oldUserState, false /*userStateChanged*/);
302    }
303
304    /** Update renamed package */
305    @Test
306    public void testUpdatePackageSetting04()
307            throws ReflectiveOperationException, PackageManagerException {
308        final PackageSetting originalPkgSetting = createPackageSetting(0 /*pkgFlags*/);
309        final PackageSetting testPkgSetting01 = Settings.updatePackageSetting(
310                null /*pkgSetting*/,
311                PACKAGE_NAME,
312                null /*realPkgName*/,
313                originalPkgSetting /*originalPkg*/,
314                null /*disabledPkg*/,
315                null /*sharedUser*/,
316                UPDATED_CODE_PATH /*codePath*/,
317                UPDATED_CODE_PATH /*resourcePath*/,
318                null /*legacyNativeLibraryPath*/,
319                "arm64-v8a" /*primaryCpuAbi*/,
320                "armeabi" /*secondaryCpuAbi*/,
321                UPDATED_VERSION_CODE /*versionCode*/,
322                0 /*pkgFlags*/,
323                0 /*pkgPrivateFlags*/,
324                UserHandle.SYSTEM /*installUser*/,
325                false /*allowInstall*/,
326                null /*parentPkgName*/,
327                null /*childPkgNames*/,
328                UserManagerService.getInstance());
329        assertThat(testPkgSetting01, is(not(originalPkgSetting)));
330        // ABI isn't pulled from the original package setting
331        assertThat(testPkgSetting01.primaryCpuAbiString, is("x86_64"));
332        assertThat(testPkgSetting01.secondaryCpuAbiString, is("x86"));
333        assertThat(testPkgSetting01.origPackage, is(originalPkgSetting));
334        assertThat(testPkgSetting01.pkgFlags, is(0));
335        assertThat(testPkgSetting01.pkgPrivateFlags, is(0));
336        final PackageUserState userState = testPkgSetting01.readUserState(UserHandle.USER_SYSTEM);
337        verifyUserState(userState, PackageSettingBase.DEFAULT_USER_STATE /*oldUserState*/,
338                false /*userStateChanged*/);
339    }
340
341    /** Update new package */
342    @Test
343    public void testUpdatePackageSetting05()
344            throws ReflectiveOperationException, PackageManagerException {
345        final PackageSetting testPkgSetting01 = Settings.updatePackageSetting(
346                null /*pkgSetting*/,
347                PACKAGE_NAME,
348                null /*realPkgName*/,
349                null /*originalPkg*/,
350                null /*disabledPkg*/,
351                null /*sharedUser*/,
352                UPDATED_CODE_PATH /*codePath*/,
353                UPDATED_CODE_PATH /*resourcePath*/,
354                null /*legacyNativeLibraryPath*/,
355                "arm64-v8a" /*primaryCpuAbi*/,
356                "armeabi" /*secondaryCpuAbi*/,
357                UPDATED_VERSION_CODE /*versionCode*/,
358                0 /*pkgFlags*/,
359                0 /*pkgPrivateFlags*/,
360                null /*installUser*/,
361                false /*allowInstall*/,
362                null /*parentPkgName*/,
363                null /*childPkgNames*/,
364                UserManagerService.getInstance());
365        assertThat(testPkgSetting01, is(notNullValue()));
366        assertThat(testPkgSetting01.primaryCpuAbiString, is("arm64-v8a"));
367        assertThat(testPkgSetting01.secondaryCpuAbiString, is("armeabi"));
368        assertThat(testPkgSetting01.origPackage, is(nullValue()));
369        assertThat(testPkgSetting01.pkgFlags, is(0));
370        assertThat(testPkgSetting01.pkgPrivateFlags, is(0));
371        final PackageUserState userState = testPkgSetting01.readUserState(UserHandle.USER_SYSTEM);
372        verifyUserState(userState, PackageSettingBase.DEFAULT_USER_STATE /*oldUserState*/,
373                false /*userStateChanged*/);
374    }
375
376    /** Update new package; install for {@code null} user */
377    @Test
378    public void testUpdatePackageSetting06()
379            throws ReflectiveOperationException, PackageManagerException {
380        final PackageSetting testPkgSetting01 = Settings.updatePackageSetting(
381                null /*pkgSetting*/,
382                PACKAGE_NAME,
383                null /*realPkgName*/,
384                null /*originalPkg*/,
385                null /*disabledPkg*/,
386                null /*sharedUser*/,
387                UPDATED_CODE_PATH /*codePath*/,
388                UPDATED_CODE_PATH /*resourcePath*/,
389                null /*legacyNativeLibraryPath*/,
390                "arm64-v8a" /*primaryCpuAbi*/,
391                "armeabi" /*secondaryCpuAbi*/,
392                UPDATED_VERSION_CODE /*versionCode*/,
393                0 /*pkgFlags*/,
394                0 /*pkgPrivateFlags*/,
395                null /*installUser*/,
396                true /*allowInstall*/,
397                null /*parentPkgName*/,
398                null /*childPkgNames*/,
399                UserManagerService.getInstance());
400        assertThat(testPkgSetting01, is(notNullValue()));
401        assertThat(testPkgSetting01.primaryCpuAbiString, is("arm64-v8a"));
402        assertThat(testPkgSetting01.secondaryCpuAbiString, is("armeabi"));
403        assertThat(testPkgSetting01.origPackage, is(nullValue()));
404        assertThat(testPkgSetting01.pkgFlags, is(0));
405        assertThat(testPkgSetting01.pkgPrivateFlags, is(0));
406        final PackageUserState userState = testPkgSetting01.readUserState(UserHandle.USER_SYSTEM);
407        verifyUserState(userState, PackageSettingBase.DEFAULT_USER_STATE /*oldUserState*/,
408                true /*userStateChanged*/, true /*notLaunched*/, true /*stopped*/);
409    }
410
411    /** Update new package; install for UserHandle.SYSTEM */
412    @Test
413    public void testUpdatePackageSetting07()
414            throws ReflectiveOperationException, PackageManagerException {
415        final PackageSetting testPkgSetting01 = Settings.updatePackageSetting(
416                null /*pkgSetting*/,
417                PACKAGE_NAME,
418                null /*realPkgName*/,
419                null /*originalPkg*/,
420                null /*disabledPkg*/,
421                null /*sharedUser*/,
422                UPDATED_CODE_PATH /*codePath*/,
423                UPDATED_CODE_PATH /*resourcePath*/,
424                null /*legacyNativeLibraryPath*/,
425                "arm64-v8a" /*primaryCpuAbi*/,
426                "armeabi" /*secondaryCpuAbi*/,
427                UPDATED_VERSION_CODE /*versionCode*/,
428                0 /*pkgFlags*/,
429                0 /*pkgPrivateFlags*/,
430                UserHandle.SYSTEM /*installUser*/,
431                true /*allowInstall*/,
432                null /*parentPkgName*/,
433                null /*childPkgNames*/,
434                UserManagerService.getInstance());
435        assertThat(testPkgSetting01, is(notNullValue()));
436        assertThat(testPkgSetting01.primaryCpuAbiString, is("arm64-v8a"));
437        assertThat(testPkgSetting01.secondaryCpuAbiString, is("armeabi"));
438        assertThat(testPkgSetting01.origPackage, is(nullValue()));
439        assertThat(testPkgSetting01.pkgFlags, is(0));
440        assertThat(testPkgSetting01.pkgPrivateFlags, is(0));
441        final PackageUserState userState = testPkgSetting01.readUserState(UserHandle.USER_SYSTEM);
442        verifyUserState(userState, PackageSettingBase.DEFAULT_USER_STATE /*oldUserState*/,
443                true /*userStateChanged*/, true /*notLaunched*/, true /*stopped*/);
444    }
445
446    /** Update package, but, shared user changed; ensure old setting not modified */
447    @Test
448    public void testUpdatePackageSetting08()
449            throws ReflectiveOperationException, PackageManagerException {
450        final SharedUserSetting testSharedUser =
451                new SharedUserSetting("testSharedUser", 0 /*pkgFlags*/, 0 /*_pkgPrivateFlags*/);
452        testSharedUser.userId = Process.FIRST_APPLICATION_UID + 9995;
453        final PackageSetting pkgSetting01 = createPackageSetting(0 /*pkgFlags*/);
454        final PackageSetting oldPkgSetting01 = new PackageSetting(pkgSetting01);
455        final PackageSetting testPkgSetting01 = Settings.updatePackageSetting(
456                pkgSetting01,
457                PACKAGE_NAME,
458                null /*realPkgName*/,
459                null /*originalPkg*/,
460                null /*disabledPkg*/,
461                testSharedUser /*sharedUser*/,
462                UPDATED_CODE_PATH /*codePath*/,
463                UPDATED_CODE_PATH /*resourcePath*/,
464                null /*legacyNativeLibraryPath*/,
465                "arm64-v8a" /*primaryCpuAbi*/,
466                "armeabi" /*secondaryCpuAbi*/,
467                UPDATED_VERSION_CODE /*versionCode*/,
468                0 /*pkgFlags*/,
469                0 /*pkgPrivateFlags*/,
470                UserHandle.SYSTEM /*installUser*/,
471                true /*allowInstall*/,
472                null /*parentPkgName*/,
473                null /*childPkgNames*/,
474                UserManagerService.getInstance());
475        assertThat(testPkgSetting01, is(not(pkgSetting01)));
476        assertThat(testPkgSetting01.primaryCpuAbiString, is("arm64-v8a"));
477        assertThat(testPkgSetting01.secondaryCpuAbiString, is("armeabi"));
478        assertThat(testPkgSetting01.origPackage, is(nullValue()));
479        assertThat(testPkgSetting01.appId, is(19995));
480        assertThat(testPkgSetting01.pkgFlags, is(0));
481        assertThat(testPkgSetting01.pkgPrivateFlags, is(0));
482        // package setting should not have been modified
483        assertThat(pkgSetting01.primaryCpuAbiString, is("x86_64"));
484        assertThat(pkgSetting01.secondaryCpuAbiString, is("x86"));
485        final PackageUserState userState = testPkgSetting01.readUserState(UserHandle.USER_SYSTEM);
486        final PackageUserState oldUserState = oldPkgSetting01.readUserState(UserHandle.USER_SYSTEM);
487        verifyUserState(userState, oldUserState, true /*userStateChanged*/,
488                true /*notLaunched*/, true /*stopped*/);
489    }
490
491    private void verifyUserState(PackageUserState userState, PackageUserState oldUserState,
492            boolean userStateChanged) {
493        verifyUserState(userState, oldUserState, userStateChanged, false /*notLaunched*/,
494                false /*stopped*/);
495    }
496
497    private void verifyUserState(PackageUserState userState, PackageUserState oldUserState,
498            boolean userStateChanged, boolean notLaunched, boolean stopped) {
499        assertThat(userState.blockUninstall, is(false));
500        assertThat(userState.enabled, is(0));
501        assertThat(userState.hidden, is(false));
502        assertThat(userState.installed, is(true));
503        assertThat(userState.notLaunched, is(notLaunched));
504        assertThat(userState.stopped, is(stopped));
505        assertThat(userState.suspended, is(false));
506        if (oldUserState != null) {
507            assertThat(userState.equals(oldUserState), is(not(userStateChanged)));
508        }
509    }
510
511    private PackageSetting createPackageSetting(int pkgFlags) {
512        return new PackageSetting(
513                PACKAGE_NAME,
514                REAL_PACKAGE_NAME,
515                INITIAL_CODE_PATH /*codePath*/,
516                INITIAL_CODE_PATH /*resourcePath*/,
517                null /*legacyNativeLibraryPathString*/,
518                "x86_64" /*primaryCpuAbiString*/,
519                "x86" /*secondaryCpuAbiString*/,
520                null /*cpuAbiOverrideString*/,
521                INITIAL_VERSION_CODE,
522                pkgFlags,
523                0 /*privateFlags*/,
524                null /*parentPackageName*/,
525                null /*childPackageNames*/,
526                0 /*sharedUserId*/);
527    }
528
529    private @NonNull List<UserInfo> createFakeUsers() {
530        ArrayList<UserInfo> users = new ArrayList<>();
531        users.add(new UserInfo(UserHandle.USER_SYSTEM, "test user", UserInfo.FLAG_INITIALIZED));
532        return users;
533    }
534
535    private void writeFile(File file, byte[] data) {
536        file.mkdirs();
537        try {
538            AtomicFile aFile = new AtomicFile(file);
539            FileOutputStream fos = aFile.startWrite();
540            fos.write(data);
541            aFile.finishWrite(fos);
542        } catch (IOException ioe) {
543            Log.e(TAG, "Cannot write file " + file.getPath());
544        }
545    }
546
547    private void writePackagesXml() {
548        writeFile(new File(InstrumentationRegistry.getContext().getFilesDir(), "system/packages.xml"),
549                ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
550                + "<packages>"
551                + "<last-platform-version internal=\"15\" external=\"0\" fingerprint=\"foo\" />"
552                + "<permission-trees>"
553                + "<item name=\"com.google.android.permtree\" package=\"com.google.android.permpackage\" />"
554                + "</permission-trees>"
555                + "<permissions>"
556                + "<item name=\"android.permission.WRITE_CALL_LOG\" package=\"android\" protection=\"1\" />"
557                + "<item name=\"android.permission.ASEC_ACCESS\" package=\"android\" protection=\"2\" />"
558                + "<item name=\"android.permission.ACCESS_WIMAX_STATE\" package=\"android\" />"
559                + "<item name=\"android.permission.REBOOT\" package=\"android\" protection=\"18\" />"
560                + "</permissions>"
561                + "<package name=\"com.google.app1\" codePath=\"/system/app/app1.apk\" nativeLibraryPath=\"/data/data/com.google.app1/lib\" flags=\"1\" ft=\"1360e2caa70\" it=\"135f2f80d08\" ut=\"1360e2caa70\" version=\"1109\" sharedUserId=\"11000\">"
562                + "<sigs count=\"1\">"
563                + "<cert index=\"0\" key=\"" + KeySetStrings.ctsKeySetCertA + "\" />"
564                + "</sigs>"
565                + "<proper-signing-keyset identifier=\"1\" />"
566                + "</package>"
567                + "<package name=\"com.google.app2\" codePath=\"/system/app/app2.apk\" nativeLibraryPath=\"/data/data/com.google.app2/lib\" flags=\"1\" ft=\"1360e578718\" it=\"135f2f80d08\" ut=\"1360e578718\" version=\"15\" enabled=\"3\" userId=\"11001\">"
568                + "<sigs count=\"1\">"
569                + "<cert index=\"0\" />"
570                + "</sigs>"
571                + "<proper-signing-keyset identifier=\"1\" />"
572                + "<defined-keyset alias=\"AB\" identifier=\"4\" />"
573                + "</package>"
574                + "<package name=\"com.android.app3\" codePath=\"/system/app/app3.apk\" nativeLibraryPath=\"/data/data/com.android.app3/lib\" flags=\"1\" ft=\"1360e577b60\" it=\"135f2f80d08\" ut=\"1360e577b60\" version=\"15\" userId=\"11030\">"
575                + "<sigs count=\"1\">"
576                + "<cert index=\"1\" key=\"" + KeySetStrings.ctsKeySetCertB + "\" />"
577                + "</sigs>"
578                + "<proper-signing-keyset identifier=\"2\" />"
579                + "<upgrade-keyset identifier=\"3\" />"
580                + "<defined-keyset alias=\"C\" identifier=\"3\" />"
581                + "</package>"
582                + "<shared-user name=\"com.android.shared1\" userId=\"11000\">"
583                + "<sigs count=\"1\">"
584                + "<cert index=\"1\" />"
585                + "</sigs>"
586                + "<perms>"
587                + "<item name=\"android.permission.REBOOT\" />"
588                + "</perms>"
589                + "</shared-user>"
590                + "<keyset-settings version=\"1\">"
591                + "<keys>"
592                + "<public-key identifier=\"1\" value=\"" + KeySetStrings.ctsKeySetPublicKeyA + "\" />"
593                + "<public-key identifier=\"2\" value=\"" + KeySetStrings.ctsKeySetPublicKeyB + "\" />"
594                + "<public-key identifier=\"3\" value=\"" + KeySetStrings.ctsKeySetPublicKeyC + "\" />"
595                + "</keys>"
596                + "<keysets>"
597                + "<keyset identifier=\"1\">"
598                + "<key-id identifier=\"1\" />"
599                + "</keyset>"
600                + "<keyset identifier=\"2\">"
601                + "<key-id identifier=\"2\" />"
602                + "</keyset>"
603                + "<keyset identifier=\"3\">"
604                + "<key-id identifier=\"3\" />"
605                + "</keyset>"
606                + "<keyset identifier=\"4\">"
607                + "<key-id identifier=\"1\" />"
608                + "<key-id identifier=\"2\" />"
609                + "</keyset>"
610                + "</keysets>"
611                + "<lastIssuedKeyId value=\"3\" />"
612                + "<lastIssuedKeySetId value=\"4\" />"
613                + "</keyset-settings>"
614                + "</packages>").getBytes());
615    }
616
617    private void writeStoppedPackagesXml() {
618        writeFile(new File(InstrumentationRegistry.getContext().getFilesDir(), "system/packages-stopped.xml"),
619                ( "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
620                + "<stopped-packages>"
621                + "<pkg name=\"com.google.app1\" nl=\"1\" />"
622                + "<pkg name=\"com.android.app3\" nl=\"1\" />"
623                + "</stopped-packages>")
624                .getBytes());
625    }
626
627    private void writePackagesList() {
628        writeFile(new File(InstrumentationRegistry.getContext().getFilesDir(), "system/packages.list"),
629                ( "com.google.app1 11000 0 /data/data/com.google.app1 seinfo1"
630                + "com.google.app2 11001 0 /data/data/com.google.app2 seinfo2"
631                + "com.android.app3 11030 0 /data/data/com.android.app3 seinfo3")
632                .getBytes());
633    }
634
635    private void deleteSystemFolder() {
636        File systemFolder = new File(InstrumentationRegistry.getContext().getFilesDir(), "system");
637        deleteFolder(systemFolder);
638    }
639
640    private static void deleteFolder(File folder) {
641        File[] files = folder.listFiles();
642        if (files != null) {
643            for (File file : files) {
644                deleteFolder(file);
645            }
646        }
647        folder.delete();
648    }
649
650    private void writeOldFiles() {
651        deleteSystemFolder();
652        writePackagesXml();
653        writeStoppedPackagesXml();
654        writePackagesList();
655    }
656
657    @Before
658    public void createUserManagerServiceRef() throws ReflectiveOperationException {
659        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
660            @Override
661            public void run() {
662                Constructor<UserManagerService> umsc;
663                try {
664                    // unregister the user manager from the local service
665                    Method removeServiceForTest = LocalServices.class.getDeclaredMethod(
666                            "removeServiceForTest", Class.class);
667                    removeServiceForTest.invoke(null, UserManagerInternal.class);
668
669                    // now create a new user manager [which registers again with the local service]
670                    umsc = UserManagerService.class.getDeclaredConstructor(
671                            Context.class,
672                            PackageManagerService.class,
673                            Object.class,
674                            File.class);
675                    umsc.setAccessible(true);
676                    UserManagerService ums = umsc.newInstance(InstrumentationRegistry.getContext(),
677                            null /*PackageManagerService*/, new Object() /*packagesLock*/,
678                            new File(InstrumentationRegistry.getContext().getFilesDir(), "user"));
679                } catch (SecurityException
680                        | ReflectiveOperationException
681                        | IllegalArgumentException e) {
682                    fail("Could not create user manager service; " + e);
683                }
684            }
685        });
686    }
687
688    private void verifyKeySetMetaData(Settings settings)
689            throws ReflectiveOperationException, IllegalAccessException {
690        ArrayMap<String, PackageSetting> packages = settings.mPackages;
691        KeySetManagerService ksms = settings.mKeySetManagerService;
692
693        /* verify keyset and public key ref counts */
694        assertThat(KeySetUtils.getKeySetRefCount(ksms, 1), is(2));
695        assertThat(KeySetUtils.getKeySetRefCount(ksms, 2), is(1));
696        assertThat(KeySetUtils.getKeySetRefCount(ksms, 3), is(1));
697        assertThat(KeySetUtils.getKeySetRefCount(ksms, 4), is(1));
698        assertThat(KeySetUtils.getPubKeyRefCount(ksms, 1), is(2));
699        assertThat(KeySetUtils.getPubKeyRefCount(ksms, 2), is(2));
700        assertThat(KeySetUtils.getPubKeyRefCount(ksms, 3), is(1));
701
702        /* verify public keys properly read */
703        PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
704        PublicKey keyB = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyB);
705        PublicKey keyC = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyC);
706        assertThat(KeySetUtils.getPubKey(ksms, 1), is(keyA));
707        assertThat(KeySetUtils.getPubKey(ksms, 2), is(keyB));
708        assertThat(KeySetUtils.getPubKey(ksms, 3), is(keyC));
709
710        /* verify mapping is correct (ks -> pub keys) */
711        LongSparseArray<ArraySet<Long>> ksMapping = KeySetUtils.getKeySetMapping(ksms);
712        ArraySet<Long> mapping = ksMapping.get(1);
713        assertThat(mapping.size(), is(1));
714        assertThat(mapping.contains(new Long(1)), is(true));
715        mapping = ksMapping.get(2);
716        assertThat(mapping.size(), is(1));
717        assertThat(mapping.contains(new Long(2)), is(true));
718        mapping = ksMapping.get(3);
719        assertThat(mapping.size(), is(1));
720        assertThat(mapping.contains(new Long(3)), is(true));
721        mapping = ksMapping.get(4);
722        assertThat(mapping.size(), is(2));
723        assertThat(mapping.contains(new Long(1)), is(true));
724        assertThat(mapping.contains(new Long(2)), is(true));
725
726        /* verify lastIssuedIds are consistent */
727        assertThat(KeySetUtils.getLastIssuedKeyId(ksms), is(3L));
728        assertThat(KeySetUtils.getLastIssuedKeySetId(ksms), is(4L));
729
730        /* verify packages have been given the appropriate information */
731        PackageSetting ps = packages.get("com.google.app1");
732        assertThat(ps.keySetData.getProperSigningKeySet(), is(1L));
733        ps = packages.get("com.google.app2");
734        assertThat(ps.keySetData.getProperSigningKeySet(), is(1L));
735        assertThat(ps.keySetData.getAliases().get("AB"), is(4L));
736        ps = packages.get("com.android.app3");
737        assertThat(ps.keySetData.getProperSigningKeySet(), is(2L));
738        assertThat(ps.keySetData.getAliases().get("C"), is(3L));
739        assertThat(ps.keySetData.getUpgradeKeySets().length, is(1));
740        assertThat(ps.keySetData.getUpgradeKeySets()[0], is(3L));
741    }
742}
743