PackageManagerSettingsTests.java revision 253984ed8c8f39fa0aa9c5f4addf2f44f334c749
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                null /*usesStaticLibraries*/,
221                null /*usesStaticLibrariesVersions*/);
222        final PackageSetting testPkgSetting01 = new PackageSetting(origPkgSetting01);
223        verifySettingCopy(origPkgSetting01, testPkgSetting01);
224    }
225
226    @Test
227    public void testPackageStateCopy02() {
228        final List<String> childPackageNames = new ArrayList<>();
229        childPackageNames.add(CHILD_PACKAGE_NAME_01);
230        childPackageNames.add(CHILD_PACKAGE_NAME_02);
231        childPackageNames.add(CHILD_PACKAGE_NAME_03);
232        final PackageSetting origPkgSetting01 = new PackageSetting(
233                PACKAGE_NAME /*pkgName*/,
234                REAL_PACKAGE_NAME /*realPkgName*/,
235                INITIAL_CODE_PATH /*codePath*/,
236                INITIAL_CODE_PATH /*resourcePath*/,
237                null /*legacyNativeLibraryPathString*/,
238                "x86_64" /*primaryCpuAbiString*/,
239                "x86" /*secondaryCpuAbiString*/,
240                null /*cpuAbiOverrideString*/,
241                INITIAL_VERSION_CODE,
242                ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_HAS_CODE,
243                ApplicationInfo.PRIVATE_FLAG_PRIVILEGED|ApplicationInfo.PRIVATE_FLAG_HIDDEN,
244                PARENT_PACKAGE_NAME,
245                childPackageNames,
246                0,
247                null /*usesStaticLibraries*/,
248                null /*usesStaticLibrariesVersions*/);
249        final PackageSetting testPkgSetting01 = new PackageSetting(
250                PACKAGE_NAME /*pkgName*/,
251                REAL_PACKAGE_NAME /*realPkgName*/,
252                UPDATED_CODE_PATH /*codePath*/,
253                UPDATED_CODE_PATH /*resourcePath*/,
254                null /*legacyNativeLibraryPathString*/,
255                null /*primaryCpuAbiString*/,
256                null /*secondaryCpuAbiString*/,
257                null /*cpuAbiOverrideString*/,
258                UPDATED_VERSION_CODE,
259                0 /*pkgFlags*/,
260                0 /*pkgPrivateFlags*/,
261                null /*parentPkgName*/,
262                null /*childPkgNames*/,
263                0,
264                null /*usesStaticLibraries*/,
265                null /*usesStaticLibrariesVersions*/);
266        testPkgSetting01.copyFrom(origPkgSetting01);
267        verifySettingCopy(origPkgSetting01, testPkgSetting01);
268    }
269
270    /** Update package */
271    @Test
272    public void testUpdatePackageSetting01() throws PackageManagerException {
273        final PackageSetting testPkgSetting01 =
274                createPackageSetting(0 /*sharedUserId*/, 0 /*pkgFlags*/);
275        testPkgSetting01.setInstalled(false /*installed*/, 0 /*userId*/);
276        assertThat(testPkgSetting01.pkgFlags, is(0));
277        assertThat(testPkgSetting01.pkgPrivateFlags, is(0));
278        final PackageSetting oldPkgSetting01 = new PackageSetting(testPkgSetting01);
279        Settings.updatePackageSetting(
280                testPkgSetting01,
281                null /*disabledPkg*/,
282                null /*sharedUser*/,
283                UPDATED_CODE_PATH /*codePath*/,
284                null /*legacyNativeLibraryPath*/,
285                "arm64-v8a" /*primaryCpuAbi*/,
286                "armeabi" /*secondaryCpuAbi*/,
287                0 /*pkgFlags*/,
288                0 /*pkgPrivateFlags*/,
289                null /*childPkgNames*/,
290                UserManagerService.getInstance(),
291                null /*usesStaticLibraries*/,
292                null /*usesStaticLibrariesVersions*/);
293        assertThat(testPkgSetting01.primaryCpuAbiString, is("arm64-v8a"));
294        assertThat(testPkgSetting01.secondaryCpuAbiString, is("armeabi"));
295        assertThat(testPkgSetting01.origPackage, is(nullValue()));
296        assertThat(testPkgSetting01.pkgFlags, is(0));
297        assertThat(testPkgSetting01.pkgPrivateFlags, is(0));
298        final PackageUserState userState = testPkgSetting01.readUserState(0);
299        final PackageUserState oldUserState = oldPkgSetting01.readUserState(0);
300        verifyUserState(userState, oldUserState, false /*userStateChanged*/, false /*notLaunched*/,
301                false /*stopped*/, false /*installed*/);
302    }
303
304    /** Update package; package now on /system, install for user '0' */
305    @Test
306    public void testUpdatePackageSetting02() throws PackageManagerException {
307        final PackageSetting testPkgSetting01 =
308                createPackageSetting(0 /*sharedUserId*/, 0 /*pkgFlags*/);
309        testPkgSetting01.setInstalled(false /*installed*/, 0 /*userId*/);
310        assertThat(testPkgSetting01.pkgFlags, is(0));
311        assertThat(testPkgSetting01.pkgPrivateFlags, is(0));
312        final PackageSetting oldPkgSetting01 = new PackageSetting(testPkgSetting01);
313        Settings.updatePackageSetting(
314                testPkgSetting01,
315                null /*disabledPkg*/,
316                null /*sharedUser*/,
317                UPDATED_CODE_PATH /*codePath*/,
318                null /*legacyNativeLibraryPath*/,
319                "arm64-v8a" /*primaryCpuAbi*/,
320                "armeabi" /*secondaryCpuAbi*/,
321                ApplicationInfo.FLAG_SYSTEM /*pkgFlags*/,
322                ApplicationInfo.PRIVATE_FLAG_PRIVILEGED /*pkgPrivateFlags*/,
323                null /*childPkgNames*/,
324                UserManagerService.getInstance(),
325                null /*usesStaticLibraries*/,
326                null /*usesStaticLibrariesVersions*/);
327        assertThat(testPkgSetting01.primaryCpuAbiString, is("arm64-v8a"));
328        assertThat(testPkgSetting01.secondaryCpuAbiString, is("armeabi"));
329        assertThat(testPkgSetting01.origPackage, is(nullValue()));
330        assertThat(testPkgSetting01.pkgFlags, is(ApplicationInfo.FLAG_SYSTEM));
331        assertThat(testPkgSetting01.pkgPrivateFlags, is(ApplicationInfo.PRIVATE_FLAG_PRIVILEGED));
332        final PackageUserState userState = testPkgSetting01.readUserState(0);
333        final PackageUserState oldUserState = oldPkgSetting01.readUserState(0);
334        // WARNING: When creating a shallow copy of the PackageSetting we do NOT create
335        // new contained objects. For example, this means that changes to the user state
336        // in testPkgSetting01 will also change the user state in its copy.
337        verifyUserState(userState, oldUserState, false /*userStateChanged*/, false /*notLaunched*/,
338                false /*stopped*/, true /*installed*/);
339    }
340
341    /** Update package; changing shared user throws exception */
342    @Test
343    public void testUpdatePackageSetting03() {
344        final Settings testSettings01 = new Settings(new Object() /*lock*/);
345        final SharedUserSetting testUserSetting01 = createSharedUserSetting(
346                testSettings01, "TestUser", 10064, 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/);
347        final PackageSetting testPkgSetting01 =
348                createPackageSetting(0 /*sharedUserId*/, 0 /*pkgFlags*/);
349        try {
350            Settings.updatePackageSetting(
351                    testPkgSetting01,
352                    null /*disabledPkg*/,
353                    testUserSetting01 /*sharedUser*/,
354                    UPDATED_CODE_PATH /*codePath*/,
355                    null /*legacyNativeLibraryPath*/,
356                    "arm64-v8a" /*primaryCpuAbi*/,
357                    "armeabi" /*secondaryCpuAbi*/,
358                    0 /*pkgFlags*/,
359                    0 /*pkgPrivateFlags*/,
360                    null /*childPkgNames*/,
361                    UserManagerService.getInstance(),
362                    null /*usesStaticLibraries*/,
363                    null /*usesStaticLibrariesVersions*/);
364            fail("Expected a PackageManagerException");
365        } catch (PackageManagerException expected) {
366        }
367    }
368
369    /** Create a new PackageSetting based on an original package setting */
370    @Test
371    public void testCreateNewSetting01() {
372        final PackageSetting originalPkgSetting01 =
373                createPackageSetting(0 /*sharedUserId*/, 0 /*pkgFlags*/);
374        final PackageSignatures originalSignatures = originalPkgSetting01.signatures;
375        final PackageSetting testPkgSetting01 = Settings.createNewSetting(
376                REAL_PACKAGE_NAME,
377                originalPkgSetting01 /*originalPkg*/,
378                null /*disabledPkg*/,
379                null /*realPkgName*/,
380                null /*sharedUser*/,
381                UPDATED_CODE_PATH /*codePath*/,
382                UPDATED_CODE_PATH /*resourcePath*/,
383                null /*legacyNativeLibraryPath*/,
384                "arm64-v8a" /*primaryCpuAbi*/,
385                "armeabi" /*secondaryCpuAbi*/,
386                UPDATED_VERSION_CODE /*versionCode*/,
387                ApplicationInfo.FLAG_SYSTEM /*pkgFlags*/,
388                ApplicationInfo.PRIVATE_FLAG_PRIVILEGED /*pkgPrivateFlags*/,
389                null /*installUser*/,
390                false /*allowInstall*/,
391                false /*instantApp*/,
392                null /*parentPkgName*/,
393                null /*childPkgNames*/,
394                UserManagerService.getInstance(),
395                null /*usesStaticLibraries*/,
396                null /*usesStaticLibrariesVersions*/);
397        assertThat(testPkgSetting01.codePath, is(UPDATED_CODE_PATH));
398        assertThat(testPkgSetting01.name, is(PACKAGE_NAME));
399        assertThat(testPkgSetting01.pkgFlags, is(ApplicationInfo.FLAG_SYSTEM));
400        assertThat(testPkgSetting01.pkgPrivateFlags, is(ApplicationInfo.PRIVATE_FLAG_PRIVILEGED));
401        assertThat(testPkgSetting01.primaryCpuAbiString, is("arm64-v8a"));
402        assertThat(testPkgSetting01.resourcePath, is(UPDATED_CODE_PATH));
403        assertThat(testPkgSetting01.secondaryCpuAbiString, is("armeabi"));
404        assertSame(testPkgSetting01.origPackage, originalPkgSetting01);
405        // signatures object must be different
406        assertNotSame(testPkgSetting01.signatures, originalSignatures);
407        assertThat(testPkgSetting01.versionCode, is(UPDATED_VERSION_CODE));
408        final PackageUserState userState = testPkgSetting01.readUserState(0);
409        verifyUserState(userState, null /*oldUserState*/, false /*userStateChanged*/,
410                false /*notLaunched*/, false /*stopped*/, true /*installed*/);
411    }
412
413    /** Create a new non-system PackageSetting */
414    @Test
415    public void testCreateNewSetting02() {
416        final PackageSetting testPkgSetting01 = Settings.createNewSetting(
417                PACKAGE_NAME,
418                null /*originalPkg*/,
419                null /*disabledPkg*/,
420                null /*realPkgName*/,
421                null /*sharedUser*/,
422                INITIAL_CODE_PATH /*codePath*/,
423                INITIAL_CODE_PATH /*resourcePath*/,
424                null /*legacyNativeLibraryPath*/,
425                "x86_64" /*primaryCpuAbiString*/,
426                "x86" /*secondaryCpuAbiString*/,
427                INITIAL_VERSION_CODE /*versionCode*/,
428                0 /*pkgFlags*/,
429                0 /*pkgPrivateFlags*/,
430                UserHandle.SYSTEM /*installUser*/,
431                true /*allowInstall*/,
432                false /*instantApp*/,
433                null /*parentPkgName*/,
434                null /*childPkgNames*/,
435                UserManagerService.getInstance(),
436                null /*usesStaticLibraries*/,
437                null /*usesStaticLibrariesVersions*/);
438        assertThat(testPkgSetting01.appId, is(0));
439        assertThat(testPkgSetting01.codePath, is(INITIAL_CODE_PATH));
440        assertThat(testPkgSetting01.name, is(PACKAGE_NAME));
441        assertThat(testPkgSetting01.origPackage, is(nullValue()));
442        assertThat(testPkgSetting01.pkgFlags, is(0));
443        assertThat(testPkgSetting01.pkgPrivateFlags, is(0));
444        assertThat(testPkgSetting01.primaryCpuAbiString, is("x86_64"));
445        assertThat(testPkgSetting01.resourcePath, is(INITIAL_CODE_PATH));
446        assertThat(testPkgSetting01.secondaryCpuAbiString, is("x86"));
447        assertThat(testPkgSetting01.versionCode, is(INITIAL_VERSION_CODE));
448        // by default, the package is considered stopped
449        final PackageUserState userState = testPkgSetting01.readUserState(0);
450        verifyUserState(userState, null /*oldUserState*/, false /*userStateChanged*/,
451                true /*notLaunched*/, true /*stopped*/, true /*installed*/);
452    }
453
454    /** Create PackageSetting for a shared user */
455    @Test
456    public void testCreateNewSetting03() {
457        final Settings testSettings01 = new Settings(new Object() /*lock*/);
458        final SharedUserSetting testUserSetting01 = createSharedUserSetting(
459                testSettings01, "TestUser", 10064, 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/);
460        final PackageSetting testPkgSetting01 = Settings.createNewSetting(
461                PACKAGE_NAME,
462                null /*originalPkg*/,
463                null /*disabledPkg*/,
464                null /*realPkgName*/,
465                testUserSetting01 /*sharedUser*/,
466                INITIAL_CODE_PATH /*codePath*/,
467                INITIAL_CODE_PATH /*resourcePath*/,
468                null /*legacyNativeLibraryPath*/,
469                "x86_64" /*primaryCpuAbiString*/,
470                "x86" /*secondaryCpuAbiString*/,
471                INITIAL_VERSION_CODE /*versionCode*/,
472                0 /*pkgFlags*/,
473                0 /*pkgPrivateFlags*/,
474                null /*installUser*/,
475                false /*allowInstall*/,
476                false /*instantApp*/,
477                null /*parentPkgName*/,
478                null /*childPkgNames*/,
479                UserManagerService.getInstance(),
480                null /*usesStaticLibraries*/,
481                null /*usesStaticLibrariesVersions*/);
482        assertThat(testPkgSetting01.appId, is(10064));
483        assertThat(testPkgSetting01.codePath, is(INITIAL_CODE_PATH));
484        assertThat(testPkgSetting01.name, is(PACKAGE_NAME));
485        assertThat(testPkgSetting01.origPackage, is(nullValue()));
486        assertThat(testPkgSetting01.pkgFlags, is(0));
487        assertThat(testPkgSetting01.pkgPrivateFlags, is(0));
488        assertThat(testPkgSetting01.primaryCpuAbiString, is("x86_64"));
489        assertThat(testPkgSetting01.resourcePath, is(INITIAL_CODE_PATH));
490        assertThat(testPkgSetting01.secondaryCpuAbiString, is("x86"));
491        assertThat(testPkgSetting01.versionCode, is(INITIAL_VERSION_CODE));
492        final PackageUserState userState = testPkgSetting01.readUserState(0);
493        verifyUserState(userState, null /*oldUserState*/, false /*userStateChanged*/,
494                false /*notLaunched*/, false /*stopped*/, true /*installed*/);
495    }
496
497    /** Create a new PackageSetting based on a disabled package setting */
498    @Test
499    public void testCreateNewSetting04() {
500        final PackageSetting disabledPkgSetting01 =
501                createPackageSetting(0 /*sharedUserId*/, 0 /*pkgFlags*/);
502        disabledPkgSetting01.appId = 10064;
503        final PackageSignatures disabledSignatures = disabledPkgSetting01.signatures;
504        final PackageSetting testPkgSetting01 = Settings.createNewSetting(
505                PACKAGE_NAME,
506                null /*originalPkg*/,
507                disabledPkgSetting01 /*disabledPkg*/,
508                null /*realPkgName*/,
509                null /*sharedUser*/,
510                UPDATED_CODE_PATH /*codePath*/,
511                UPDATED_CODE_PATH /*resourcePath*/,
512                null /*legacyNativeLibraryPath*/,
513                "arm64-v8a" /*primaryCpuAbi*/,
514                "armeabi" /*secondaryCpuAbi*/,
515                UPDATED_VERSION_CODE /*versionCode*/,
516                0 /*pkgFlags*/,
517                0 /*pkgPrivateFlags*/,
518                null /*installUser*/,
519                false /*allowInstall*/,
520                false /*instantApp*/,
521                null /*parentPkgName*/,
522                null /*childPkgNames*/,
523                UserManagerService.getInstance(),
524                null /*usesStaticLibraries*/,
525                null /*usesStaticLibrariesVersions*/);
526        assertThat(testPkgSetting01.appId, is(10064));
527        assertThat(testPkgSetting01.codePath, is(UPDATED_CODE_PATH));
528        assertThat(testPkgSetting01.name, is(PACKAGE_NAME));
529        assertThat(testPkgSetting01.origPackage, is(nullValue()));
530        assertThat(testPkgSetting01.pkgFlags, is(0));
531        assertThat(testPkgSetting01.pkgPrivateFlags, is(0));
532        assertThat(testPkgSetting01.primaryCpuAbiString, is("arm64-v8a"));
533        assertThat(testPkgSetting01.resourcePath, is(UPDATED_CODE_PATH));
534        assertThat(testPkgSetting01.secondaryCpuAbiString, is("armeabi"));
535        assertNotSame(testPkgSetting01.signatures, disabledSignatures);
536        assertThat(testPkgSetting01.versionCode, is(UPDATED_VERSION_CODE));
537        final PackageUserState userState = testPkgSetting01.readUserState(0);
538        verifyUserState(userState, null /*oldUserState*/, false /*userStateChanged*/,
539                false /*notLaunched*/, false /*stopped*/, true /*installed*/);
540    }
541
542    private void verifyUserState(PackageUserState userState, PackageUserState oldUserState,
543            boolean userStateChanged) {
544        verifyUserState(userState, oldUserState, userStateChanged, false /*notLaunched*/,
545                false /*stopped*/, true /*installed*/);
546    }
547
548    private void verifyUserState(PackageUserState userState, PackageUserState oldUserState,
549            boolean userStateChanged, boolean notLaunched, boolean stopped, boolean installed) {
550        assertThat(userState.enabled, is(0));
551        assertThat(userState.hidden, is(false));
552        assertThat(userState.installed, is(installed));
553        assertThat(userState.notLaunched, is(notLaunched));
554        assertThat(userState.stopped, is(stopped));
555        assertThat(userState.suspended, is(false));
556        if (oldUserState != null) {
557            assertThat(userState.equals(oldUserState), is(not(userStateChanged)));
558        }
559    }
560
561    private void verifySettingCopy(PackageSetting origPkgSetting, PackageSetting testPkgSetting) {
562        assertThat(origPkgSetting, is(not(testPkgSetting)));
563        assertThat(origPkgSetting.appId, is(testPkgSetting.appId));
564        // different but equal objects
565        assertNotSame(origPkgSetting.childPackageNames, testPkgSetting.childPackageNames);
566        assertThat(origPkgSetting.childPackageNames, is(testPkgSetting.childPackageNames));
567        assertSame(origPkgSetting.codePath, testPkgSetting.codePath);
568        assertThat(origPkgSetting.codePath, is(testPkgSetting.codePath));
569        assertSame(origPkgSetting.codePathString, testPkgSetting.codePathString);
570        assertThat(origPkgSetting.codePathString, is(testPkgSetting.codePathString));
571        assertSame(origPkgSetting.cpuAbiOverrideString, testPkgSetting.cpuAbiOverrideString);
572        assertThat(origPkgSetting.cpuAbiOverrideString, is(testPkgSetting.cpuAbiOverrideString));
573        assertThat(origPkgSetting.firstInstallTime, is(testPkgSetting.firstInstallTime));
574        assertSame(origPkgSetting.installerPackageName, testPkgSetting.installerPackageName);
575        assertThat(origPkgSetting.installerPackageName, is(testPkgSetting.installerPackageName));
576        assertThat(origPkgSetting.installPermissionsFixed,
577                is(testPkgSetting.installPermissionsFixed));
578        assertThat(origPkgSetting.installStatus, is(testPkgSetting.installStatus));
579        assertThat(origPkgSetting.isOrphaned, is(testPkgSetting.isOrphaned));
580        assertSame(origPkgSetting.keySetData, testPkgSetting.keySetData);
581        assertThat(origPkgSetting.keySetData, is(testPkgSetting.keySetData));
582        assertThat(origPkgSetting.lastUpdateTime, is(testPkgSetting.lastUpdateTime));
583        assertSame(origPkgSetting.legacyNativeLibraryPathString,
584                testPkgSetting.legacyNativeLibraryPathString);
585        assertThat(origPkgSetting.legacyNativeLibraryPathString,
586                is(testPkgSetting.legacyNativeLibraryPathString));
587        assertNotSame(origPkgSetting.mPermissionsState, testPkgSetting.mPermissionsState);
588        assertThat(origPkgSetting.mPermissionsState, is(testPkgSetting.mPermissionsState));
589        assertThat(origPkgSetting.name, is(testPkgSetting.name));
590        // oldCodePaths is _not_ copied
591        // assertNotSame(origPkgSetting.oldCodePaths, testPkgSetting.oldCodePaths);
592        // assertThat(origPkgSetting.oldCodePaths, is(not(testPkgSetting.oldCodePaths)));
593        assertSame(origPkgSetting.origPackage, testPkgSetting.origPackage);
594        assertThat(origPkgSetting.origPackage, is(testPkgSetting.origPackage));
595        assertSame(origPkgSetting.parentPackageName, testPkgSetting.parentPackageName);
596        assertThat(origPkgSetting.parentPackageName, is(testPkgSetting.parentPackageName));
597        assertSame(origPkgSetting.pkg, testPkgSetting.pkg);
598        // No equals() method for this object
599        // assertThat(origPkgSetting.pkg, is(testPkgSetting.pkg));
600        assertThat(origPkgSetting.pkgFlags, is(testPkgSetting.pkgFlags));
601        assertThat(origPkgSetting.pkgPrivateFlags, is(testPkgSetting.pkgPrivateFlags));
602        assertSame(origPkgSetting.primaryCpuAbiString, testPkgSetting.primaryCpuAbiString);
603        assertThat(origPkgSetting.primaryCpuAbiString, is(testPkgSetting.primaryCpuAbiString));
604        assertThat(origPkgSetting.realName, is(testPkgSetting.realName));
605        assertSame(origPkgSetting.resourcePath, testPkgSetting.resourcePath);
606        assertThat(origPkgSetting.resourcePath, is(testPkgSetting.resourcePath));
607        assertSame(origPkgSetting.resourcePathString, testPkgSetting.resourcePathString);
608        assertThat(origPkgSetting.resourcePathString, is(testPkgSetting.resourcePathString));
609        assertSame(origPkgSetting.secondaryCpuAbiString, testPkgSetting.secondaryCpuAbiString);
610        assertThat(origPkgSetting.secondaryCpuAbiString, is(testPkgSetting.secondaryCpuAbiString));
611        assertSame(origPkgSetting.sharedUser, testPkgSetting.sharedUser);
612        assertThat(origPkgSetting.sharedUser, is(testPkgSetting.sharedUser));
613        assertSame(origPkgSetting.signatures, testPkgSetting.signatures);
614        assertThat(origPkgSetting.signatures, is(testPkgSetting.signatures));
615        assertThat(origPkgSetting.timeStamp, is(testPkgSetting.timeStamp));
616        assertThat(origPkgSetting.uidError, is(testPkgSetting.uidError));
617        assertNotSame(origPkgSetting.getUserState(), is(testPkgSetting.getUserState()));
618        // No equals() method for SparseArray object
619        // assertThat(origPkgSetting.getUserState(), is(testPkgSetting.getUserState()));
620        assertSame(origPkgSetting.verificationInfo, testPkgSetting.verificationInfo);
621        assertThat(origPkgSetting.verificationInfo, is(testPkgSetting.verificationInfo));
622        assertThat(origPkgSetting.versionCode, is(testPkgSetting.versionCode));
623        assertSame(origPkgSetting.volumeUuid, testPkgSetting.volumeUuid);
624        assertThat(origPkgSetting.volumeUuid, is(testPkgSetting.volumeUuid));
625    }
626
627    private SharedUserSetting createSharedUserSetting(Settings settings, String userName,
628            int sharedUserId, int pkgFlags, int pkgPrivateFlags) {
629        return settings.addSharedUserLPw(
630                userName,
631                sharedUserId,
632                pkgFlags,
633                pkgPrivateFlags);
634    }
635    private PackageSetting createPackageSetting(int sharedUserId, int pkgFlags) {
636        return new PackageSetting(
637                PACKAGE_NAME,
638                REAL_PACKAGE_NAME,
639                INITIAL_CODE_PATH /*codePath*/,
640                INITIAL_CODE_PATH /*resourcePath*/,
641                null /*legacyNativeLibraryPathString*/,
642                "x86_64" /*primaryCpuAbiString*/,
643                "x86" /*secondaryCpuAbiString*/,
644                null /*cpuAbiOverrideString*/,
645                INITIAL_VERSION_CODE,
646                pkgFlags,
647                0 /*privateFlags*/,
648                null /*parentPackageName*/,
649                null /*childPackageNames*/,
650                sharedUserId,
651                null /*usesStaticLibraries*/,
652                null /*usesStaticLibrariesVersions*/);
653    }
654
655    private @NonNull List<UserInfo> createFakeUsers() {
656        ArrayList<UserInfo> users = new ArrayList<>();
657        users.add(new UserInfo(UserHandle.USER_SYSTEM, "test user", UserInfo.FLAG_INITIALIZED));
658        return users;
659    }
660
661    private void writeFile(File file, byte[] data) {
662        file.mkdirs();
663        try {
664            AtomicFile aFile = new AtomicFile(file);
665            FileOutputStream fos = aFile.startWrite();
666            fos.write(data);
667            aFile.finishWrite(fos);
668        } catch (IOException ioe) {
669            Log.e(TAG, "Cannot write file " + file.getPath());
670        }
671    }
672
673    private void writePackagesXml() {
674        writeFile(new File(InstrumentationRegistry.getContext().getFilesDir(), "system/packages.xml"),
675                ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
676                + "<packages>"
677                + "<last-platform-version internal=\"15\" external=\"0\" fingerprint=\"foo\" />"
678                + "<permission-trees>"
679                + "<item name=\"com.google.android.permtree\" package=\"com.google.android.permpackage\" />"
680                + "</permission-trees>"
681                + "<permissions>"
682                + "<item name=\"android.permission.WRITE_CALL_LOG\" package=\"android\" protection=\"1\" />"
683                + "<item name=\"android.permission.ASEC_ACCESS\" package=\"android\" protection=\"2\" />"
684                + "<item name=\"android.permission.ACCESS_WIMAX_STATE\" package=\"android\" />"
685                + "<item name=\"android.permission.REBOOT\" package=\"android\" protection=\"18\" />"
686                + "</permissions>"
687                + "<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\">"
688                + "<sigs count=\"1\">"
689                + "<cert index=\"0\" key=\"" + KeySetStrings.ctsKeySetCertA + "\" />"
690                + "</sigs>"
691                + "<proper-signing-keyset identifier=\"1\" />"
692                + "</package>"
693                + "<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\">"
694                + "<sigs count=\"1\">"
695                + "<cert index=\"0\" />"
696                + "</sigs>"
697                + "<proper-signing-keyset identifier=\"1\" />"
698                + "<defined-keyset alias=\"AB\" identifier=\"4\" />"
699                + "</package>"
700                + "<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\">"
701                + "<sigs count=\"1\">"
702                + "<cert index=\"1\" key=\"" + KeySetStrings.ctsKeySetCertB + "\" />"
703                + "</sigs>"
704                + "<proper-signing-keyset identifier=\"2\" />"
705                + "<upgrade-keyset identifier=\"3\" />"
706                + "<defined-keyset alias=\"C\" identifier=\"3\" />"
707                + "</package>"
708                + "<shared-user name=\"com.android.shared1\" userId=\"11000\">"
709                + "<sigs count=\"1\">"
710                + "<cert index=\"1\" />"
711                + "</sigs>"
712                + "<perms>"
713                + "<item name=\"android.permission.REBOOT\" />"
714                + "</perms>"
715                + "</shared-user>"
716                + "<keyset-settings version=\"1\">"
717                + "<keys>"
718                + "<public-key identifier=\"1\" value=\"" + KeySetStrings.ctsKeySetPublicKeyA + "\" />"
719                + "<public-key identifier=\"2\" value=\"" + KeySetStrings.ctsKeySetPublicKeyB + "\" />"
720                + "<public-key identifier=\"3\" value=\"" + KeySetStrings.ctsKeySetPublicKeyC + "\" />"
721                + "</keys>"
722                + "<keysets>"
723                + "<keyset identifier=\"1\">"
724                + "<key-id identifier=\"1\" />"
725                + "</keyset>"
726                + "<keyset identifier=\"2\">"
727                + "<key-id identifier=\"2\" />"
728                + "</keyset>"
729                + "<keyset identifier=\"3\">"
730                + "<key-id identifier=\"3\" />"
731                + "</keyset>"
732                + "<keyset identifier=\"4\">"
733                + "<key-id identifier=\"1\" />"
734                + "<key-id identifier=\"2\" />"
735                + "</keyset>"
736                + "</keysets>"
737                + "<lastIssuedKeyId value=\"3\" />"
738                + "<lastIssuedKeySetId value=\"4\" />"
739                + "</keyset-settings>"
740                + "</packages>").getBytes());
741    }
742
743    private void writeStoppedPackagesXml() {
744        writeFile(new File(InstrumentationRegistry.getContext().getFilesDir(), "system/packages-stopped.xml"),
745                ( "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
746                + "<stopped-packages>"
747                + "<pkg name=\"com.google.app1\" nl=\"1\" />"
748                + "<pkg name=\"com.android.app3\" nl=\"1\" />"
749                + "</stopped-packages>")
750                .getBytes());
751    }
752
753    private void writePackagesList() {
754        writeFile(new File(InstrumentationRegistry.getContext().getFilesDir(), "system/packages.list"),
755                ( "com.google.app1 11000 0 /data/data/com.google.app1 seinfo1"
756                + "com.google.app2 11001 0 /data/data/com.google.app2 seinfo2"
757                + "com.android.app3 11030 0 /data/data/com.android.app3 seinfo3")
758                .getBytes());
759    }
760
761    private void deleteSystemFolder() {
762        File systemFolder = new File(InstrumentationRegistry.getContext().getFilesDir(), "system");
763        deleteFolder(systemFolder);
764    }
765
766    private static void deleteFolder(File folder) {
767        File[] files = folder.listFiles();
768        if (files != null) {
769            for (File file : files) {
770                deleteFolder(file);
771            }
772        }
773        folder.delete();
774    }
775
776    private void writeOldFiles() {
777        deleteSystemFolder();
778        writePackagesXml();
779        writeStoppedPackagesXml();
780        writePackagesList();
781    }
782
783    @Before
784    public void createUserManagerServiceRef() throws ReflectiveOperationException {
785        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
786            @Override
787            public void run() {
788                Constructor<UserManagerService> umsc;
789                try {
790                    // unregister the user manager from the local service
791                    Method removeServiceForTest = LocalServices.class.getDeclaredMethod(
792                            "removeServiceForTest", Class.class);
793                    removeServiceForTest.invoke(null, UserManagerInternal.class);
794
795                    // now create a new user manager [which registers again with the local service]
796                    umsc = UserManagerService.class.getDeclaredConstructor(
797                            Context.class,
798                            PackageManagerService.class,
799                            Object.class,
800                            File.class);
801                    umsc.setAccessible(true);
802                    UserManagerService ums = umsc.newInstance(InstrumentationRegistry.getContext(),
803                            null /*PackageManagerService*/, new Object() /*packagesLock*/,
804                            new File(InstrumentationRegistry.getContext().getFilesDir(), "user"));
805                } catch (SecurityException
806                        | ReflectiveOperationException
807                        | IllegalArgumentException e) {
808                    fail("Could not create user manager service; " + e);
809                }
810            }
811        });
812    }
813
814    private void verifyKeySetMetaData(Settings settings)
815            throws ReflectiveOperationException, IllegalAccessException {
816        ArrayMap<String, PackageSetting> packages = settings.mPackages;
817        KeySetManagerService ksms = settings.mKeySetManagerService;
818
819        /* verify keyset and public key ref counts */
820        assertThat(KeySetUtils.getKeySetRefCount(ksms, 1), is(2));
821        assertThat(KeySetUtils.getKeySetRefCount(ksms, 2), is(1));
822        assertThat(KeySetUtils.getKeySetRefCount(ksms, 3), is(1));
823        assertThat(KeySetUtils.getKeySetRefCount(ksms, 4), is(1));
824        assertThat(KeySetUtils.getPubKeyRefCount(ksms, 1), is(2));
825        assertThat(KeySetUtils.getPubKeyRefCount(ksms, 2), is(2));
826        assertThat(KeySetUtils.getPubKeyRefCount(ksms, 3), is(1));
827
828        /* verify public keys properly read */
829        PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
830        PublicKey keyB = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyB);
831        PublicKey keyC = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyC);
832        assertThat(KeySetUtils.getPubKey(ksms, 1), is(keyA));
833        assertThat(KeySetUtils.getPubKey(ksms, 2), is(keyB));
834        assertThat(KeySetUtils.getPubKey(ksms, 3), is(keyC));
835
836        /* verify mapping is correct (ks -> pub keys) */
837        LongSparseArray<ArraySet<Long>> ksMapping = KeySetUtils.getKeySetMapping(ksms);
838        ArraySet<Long> mapping = ksMapping.get(1);
839        assertThat(mapping.size(), is(1));
840        assertThat(mapping.contains(new Long(1)), is(true));
841        mapping = ksMapping.get(2);
842        assertThat(mapping.size(), is(1));
843        assertThat(mapping.contains(new Long(2)), is(true));
844        mapping = ksMapping.get(3);
845        assertThat(mapping.size(), is(1));
846        assertThat(mapping.contains(new Long(3)), is(true));
847        mapping = ksMapping.get(4);
848        assertThat(mapping.size(), is(2));
849        assertThat(mapping.contains(new Long(1)), is(true));
850        assertThat(mapping.contains(new Long(2)), is(true));
851
852        /* verify lastIssuedIds are consistent */
853        assertThat(KeySetUtils.getLastIssuedKeyId(ksms), is(3L));
854        assertThat(KeySetUtils.getLastIssuedKeySetId(ksms), is(4L));
855
856        /* verify packages have been given the appropriate information */
857        PackageSetting ps = packages.get("com.google.app1");
858        assertThat(ps.keySetData.getProperSigningKeySet(), is(1L));
859        ps = packages.get("com.google.app2");
860        assertThat(ps.keySetData.getProperSigningKeySet(), is(1L));
861        assertThat(ps.keySetData.getAliases().get("AB"), is(4L));
862        ps = packages.get("com.android.app3");
863        assertThat(ps.keySetData.getProperSigningKeySet(), is(2L));
864        assertThat(ps.keySetData.getAliases().get("C"), is(3L));
865        assertThat(ps.keySetData.getUpgradeKeySets().length, is(1));
866        assertThat(ps.keySetData.getUpgradeKeySets()[0], is(3L));
867    }
868}
869