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