PackageManagerSettingsTests.java revision 6788212d17f54475ca9c3dd689a863e031db868f
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                null /*parentPkgName*/,
392                null /*childPkgNames*/,
393                UserManagerService.getInstance(),
394                null /*usesStaticLibraries*/,
395                null /*usesStaticLibrariesVersions*/);
396        assertThat(testPkgSetting01.codePath, is(UPDATED_CODE_PATH));
397        assertThat(testPkgSetting01.name, is(PACKAGE_NAME));
398        assertThat(testPkgSetting01.pkgFlags, is(ApplicationInfo.FLAG_SYSTEM));
399        assertThat(testPkgSetting01.pkgPrivateFlags, is(ApplicationInfo.PRIVATE_FLAG_PRIVILEGED));
400        assertThat(testPkgSetting01.primaryCpuAbiString, is("arm64-v8a"));
401        assertThat(testPkgSetting01.resourcePath, is(UPDATED_CODE_PATH));
402        assertThat(testPkgSetting01.secondaryCpuAbiString, is("armeabi"));
403        assertSame(testPkgSetting01.origPackage, originalPkgSetting01);
404        // signatures object must be different
405        assertNotSame(testPkgSetting01.signatures, originalSignatures);
406        assertThat(testPkgSetting01.versionCode, is(UPDATED_VERSION_CODE));
407        final PackageUserState userState = testPkgSetting01.readUserState(0);
408        verifyUserState(userState, null /*oldUserState*/, false /*userStateChanged*/,
409                false /*notLaunched*/, false /*stopped*/, true /*installed*/);
410    }
411
412    /** Create a new non-system PackageSetting */
413    @Test
414    public void testCreateNewSetting02() {
415        final PackageSetting testPkgSetting01 = Settings.createNewSetting(
416                PACKAGE_NAME,
417                null /*originalPkg*/,
418                null /*disabledPkg*/,
419                null /*realPkgName*/,
420                null /*sharedUser*/,
421                INITIAL_CODE_PATH /*codePath*/,
422                INITIAL_CODE_PATH /*resourcePath*/,
423                null /*legacyNativeLibraryPath*/,
424                "x86_64" /*primaryCpuAbiString*/,
425                "x86" /*secondaryCpuAbiString*/,
426                INITIAL_VERSION_CODE /*versionCode*/,
427                0 /*pkgFlags*/,
428                0 /*pkgPrivateFlags*/,
429                UserHandle.SYSTEM /*installUser*/,
430                true /*allowInstall*/,
431                null /*parentPkgName*/,
432                null /*childPkgNames*/,
433                UserManagerService.getInstance(),
434                null /*usesStaticLibraries*/,
435                null /*usesStaticLibrariesVersions*/);
436        assertThat(testPkgSetting01.appId, is(0));
437        assertThat(testPkgSetting01.codePath, is(INITIAL_CODE_PATH));
438        assertThat(testPkgSetting01.name, is(PACKAGE_NAME));
439        assertThat(testPkgSetting01.origPackage, is(nullValue()));
440        assertThat(testPkgSetting01.pkgFlags, is(0));
441        assertThat(testPkgSetting01.pkgPrivateFlags, is(0));
442        assertThat(testPkgSetting01.primaryCpuAbiString, is("x86_64"));
443        assertThat(testPkgSetting01.resourcePath, is(INITIAL_CODE_PATH));
444        assertThat(testPkgSetting01.secondaryCpuAbiString, is("x86"));
445        assertThat(testPkgSetting01.versionCode, is(INITIAL_VERSION_CODE));
446        // by default, the package is considered stopped
447        final PackageUserState userState = testPkgSetting01.readUserState(0);
448        verifyUserState(userState, null /*oldUserState*/, false /*userStateChanged*/,
449                true /*notLaunched*/, true /*stopped*/, true /*installed*/);
450    }
451
452    /** Create PackageSetting for a shared user */
453    @Test
454    public void testCreateNewSetting03() {
455        final Settings testSettings01 = new Settings(new Object() /*lock*/);
456        final SharedUserSetting testUserSetting01 = createSharedUserSetting(
457                testSettings01, "TestUser", 10064, 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/);
458        final PackageSetting testPkgSetting01 = Settings.createNewSetting(
459                PACKAGE_NAME,
460                null /*originalPkg*/,
461                null /*disabledPkg*/,
462                null /*realPkgName*/,
463                testUserSetting01 /*sharedUser*/,
464                INITIAL_CODE_PATH /*codePath*/,
465                INITIAL_CODE_PATH /*resourcePath*/,
466                null /*legacyNativeLibraryPath*/,
467                "x86_64" /*primaryCpuAbiString*/,
468                "x86" /*secondaryCpuAbiString*/,
469                INITIAL_VERSION_CODE /*versionCode*/,
470                0 /*pkgFlags*/,
471                0 /*pkgPrivateFlags*/,
472                null /*installUser*/,
473                false /*allowInstall*/,
474                null /*parentPkgName*/,
475                null /*childPkgNames*/,
476                UserManagerService.getInstance(),
477                null /*usesStaticLibraries*/,
478                null /*usesStaticLibrariesVersions*/);
479        assertThat(testPkgSetting01.appId, is(10064));
480        assertThat(testPkgSetting01.codePath, is(INITIAL_CODE_PATH));
481        assertThat(testPkgSetting01.name, is(PACKAGE_NAME));
482        assertThat(testPkgSetting01.origPackage, is(nullValue()));
483        assertThat(testPkgSetting01.pkgFlags, is(0));
484        assertThat(testPkgSetting01.pkgPrivateFlags, is(0));
485        assertThat(testPkgSetting01.primaryCpuAbiString, is("x86_64"));
486        assertThat(testPkgSetting01.resourcePath, is(INITIAL_CODE_PATH));
487        assertThat(testPkgSetting01.secondaryCpuAbiString, is("x86"));
488        assertThat(testPkgSetting01.versionCode, is(INITIAL_VERSION_CODE));
489        final PackageUserState userState = testPkgSetting01.readUserState(0);
490        verifyUserState(userState, null /*oldUserState*/, false /*userStateChanged*/,
491                false /*notLaunched*/, false /*stopped*/, true /*installed*/);
492    }
493
494    /** Create a new PackageSetting based on a disabled package setting */
495    @Test
496    public void testCreateNewSetting04() {
497        final PackageSetting disabledPkgSetting01 =
498                createPackageSetting(0 /*sharedUserId*/, 0 /*pkgFlags*/);
499        disabledPkgSetting01.appId = 10064;
500        final PackageSignatures disabledSignatures = disabledPkgSetting01.signatures;
501        final PackageSetting testPkgSetting01 = Settings.createNewSetting(
502                PACKAGE_NAME,
503                null /*originalPkg*/,
504                disabledPkgSetting01 /*disabledPkg*/,
505                null /*realPkgName*/,
506                null /*sharedUser*/,
507                UPDATED_CODE_PATH /*codePath*/,
508                UPDATED_CODE_PATH /*resourcePath*/,
509                null /*legacyNativeLibraryPath*/,
510                "arm64-v8a" /*primaryCpuAbi*/,
511                "armeabi" /*secondaryCpuAbi*/,
512                UPDATED_VERSION_CODE /*versionCode*/,
513                0 /*pkgFlags*/,
514                0 /*pkgPrivateFlags*/,
515                null /*installUser*/,
516                false /*allowInstall*/,
517                null /*parentPkgName*/,
518                null /*childPkgNames*/,
519                UserManagerService.getInstance(),
520                null /*usesStaticLibraries*/,
521                null /*usesStaticLibrariesVersions*/);
522        assertThat(testPkgSetting01.appId, is(10064));
523        assertThat(testPkgSetting01.codePath, is(UPDATED_CODE_PATH));
524        assertThat(testPkgSetting01.name, is(PACKAGE_NAME));
525        assertThat(testPkgSetting01.origPackage, is(nullValue()));
526        assertThat(testPkgSetting01.pkgFlags, is(0));
527        assertThat(testPkgSetting01.pkgPrivateFlags, is(0));
528        assertThat(testPkgSetting01.primaryCpuAbiString, is("arm64-v8a"));
529        assertThat(testPkgSetting01.resourcePath, is(UPDATED_CODE_PATH));
530        assertThat(testPkgSetting01.secondaryCpuAbiString, is("armeabi"));
531        assertNotSame(testPkgSetting01.signatures, disabledSignatures);
532        assertThat(testPkgSetting01.versionCode, is(UPDATED_VERSION_CODE));
533        final PackageUserState userState = testPkgSetting01.readUserState(0);
534        verifyUserState(userState, null /*oldUserState*/, false /*userStateChanged*/,
535                false /*notLaunched*/, false /*stopped*/, true /*installed*/);
536    }
537
538    private void verifyUserState(PackageUserState userState, PackageUserState oldUserState,
539            boolean userStateChanged) {
540        verifyUserState(userState, oldUserState, userStateChanged, false /*notLaunched*/,
541                false /*stopped*/, true /*installed*/);
542    }
543
544    private void verifyUserState(PackageUserState userState, PackageUserState oldUserState,
545            boolean userStateChanged, boolean notLaunched, boolean stopped, boolean installed) {
546        assertThat(userState.blockUninstall, is(false));
547        assertThat(userState.enabled, is(0));
548        assertThat(userState.hidden, is(false));
549        assertThat(userState.installed, is(installed));
550        assertThat(userState.notLaunched, is(notLaunched));
551        assertThat(userState.stopped, is(stopped));
552        assertThat(userState.suspended, is(false));
553        if (oldUserState != null) {
554            assertThat(userState.equals(oldUserState), is(not(userStateChanged)));
555        }
556    }
557
558    private void verifySettingCopy(PackageSetting origPkgSetting, PackageSetting testPkgSetting) {
559        assertThat(origPkgSetting, is(not(testPkgSetting)));
560        assertThat(origPkgSetting.appId, is(testPkgSetting.appId));
561        // different but equal objects
562        assertNotSame(origPkgSetting.childPackageNames, testPkgSetting.childPackageNames);
563        assertThat(origPkgSetting.childPackageNames, is(testPkgSetting.childPackageNames));
564        assertSame(origPkgSetting.codePath, testPkgSetting.codePath);
565        assertThat(origPkgSetting.codePath, is(testPkgSetting.codePath));
566        assertSame(origPkgSetting.codePathString, testPkgSetting.codePathString);
567        assertThat(origPkgSetting.codePathString, is(testPkgSetting.codePathString));
568        assertSame(origPkgSetting.cpuAbiOverrideString, testPkgSetting.cpuAbiOverrideString);
569        assertThat(origPkgSetting.cpuAbiOverrideString, is(testPkgSetting.cpuAbiOverrideString));
570        assertThat(origPkgSetting.firstInstallTime, is(testPkgSetting.firstInstallTime));
571        assertSame(origPkgSetting.installerPackageName, testPkgSetting.installerPackageName);
572        assertThat(origPkgSetting.installerPackageName, is(testPkgSetting.installerPackageName));
573        assertThat(origPkgSetting.installPermissionsFixed,
574                is(testPkgSetting.installPermissionsFixed));
575        assertThat(origPkgSetting.installStatus, is(testPkgSetting.installStatus));
576        assertThat(origPkgSetting.isOrphaned, is(testPkgSetting.isOrphaned));
577        assertSame(origPkgSetting.keySetData, testPkgSetting.keySetData);
578        assertThat(origPkgSetting.keySetData, is(testPkgSetting.keySetData));
579        assertThat(origPkgSetting.lastUpdateTime, is(testPkgSetting.lastUpdateTime));
580        assertSame(origPkgSetting.legacyNativeLibraryPathString,
581                testPkgSetting.legacyNativeLibraryPathString);
582        assertThat(origPkgSetting.legacyNativeLibraryPathString,
583                is(testPkgSetting.legacyNativeLibraryPathString));
584        assertNotSame(origPkgSetting.mPermissionsState, testPkgSetting.mPermissionsState);
585        assertThat(origPkgSetting.mPermissionsState, is(testPkgSetting.mPermissionsState));
586        assertThat(origPkgSetting.name, is(testPkgSetting.name));
587        // oldCodePaths is _not_ copied
588        // assertNotSame(origPkgSetting.oldCodePaths, testPkgSetting.oldCodePaths);
589        // assertThat(origPkgSetting.oldCodePaths, is(not(testPkgSetting.oldCodePaths)));
590        assertSame(origPkgSetting.origPackage, testPkgSetting.origPackage);
591        assertThat(origPkgSetting.origPackage, is(testPkgSetting.origPackage));
592        assertSame(origPkgSetting.parentPackageName, testPkgSetting.parentPackageName);
593        assertThat(origPkgSetting.parentPackageName, is(testPkgSetting.parentPackageName));
594        assertSame(origPkgSetting.pkg, testPkgSetting.pkg);
595        // No equals() method for this object
596        // assertThat(origPkgSetting.pkg, is(testPkgSetting.pkg));
597        assertThat(origPkgSetting.pkgFlags, is(testPkgSetting.pkgFlags));
598        assertThat(origPkgSetting.pkgPrivateFlags, is(testPkgSetting.pkgPrivateFlags));
599        assertSame(origPkgSetting.primaryCpuAbiString, testPkgSetting.primaryCpuAbiString);
600        assertThat(origPkgSetting.primaryCpuAbiString, is(testPkgSetting.primaryCpuAbiString));
601        assertThat(origPkgSetting.realName, is(testPkgSetting.realName));
602        assertSame(origPkgSetting.resourcePath, testPkgSetting.resourcePath);
603        assertThat(origPkgSetting.resourcePath, is(testPkgSetting.resourcePath));
604        assertSame(origPkgSetting.resourcePathString, testPkgSetting.resourcePathString);
605        assertThat(origPkgSetting.resourcePathString, is(testPkgSetting.resourcePathString));
606        assertSame(origPkgSetting.secondaryCpuAbiString, testPkgSetting.secondaryCpuAbiString);
607        assertThat(origPkgSetting.secondaryCpuAbiString, is(testPkgSetting.secondaryCpuAbiString));
608        assertSame(origPkgSetting.sharedUser, testPkgSetting.sharedUser);
609        assertThat(origPkgSetting.sharedUser, is(testPkgSetting.sharedUser));
610        assertSame(origPkgSetting.signatures, testPkgSetting.signatures);
611        assertThat(origPkgSetting.signatures, is(testPkgSetting.signatures));
612        assertThat(origPkgSetting.timeStamp, is(testPkgSetting.timeStamp));
613        assertThat(origPkgSetting.uidError, is(testPkgSetting.uidError));
614        assertNotSame(origPkgSetting.getUserState(), is(testPkgSetting.getUserState()));
615        // No equals() method for SparseArray object
616        // assertThat(origPkgSetting.getUserState(), is(testPkgSetting.getUserState()));
617        assertSame(origPkgSetting.verificationInfo, testPkgSetting.verificationInfo);
618        assertThat(origPkgSetting.verificationInfo, is(testPkgSetting.verificationInfo));
619        assertThat(origPkgSetting.versionCode, is(testPkgSetting.versionCode));
620        assertSame(origPkgSetting.volumeUuid, testPkgSetting.volumeUuid);
621        assertThat(origPkgSetting.volumeUuid, is(testPkgSetting.volumeUuid));
622    }
623
624    private SharedUserSetting createSharedUserSetting(Settings settings, String userName,
625            int sharedUserId, int pkgFlags, int pkgPrivateFlags) {
626        return settings.addSharedUserLPw(
627                userName,
628                sharedUserId,
629                pkgFlags,
630                pkgPrivateFlags);
631    }
632    private PackageSetting createPackageSetting(int sharedUserId, int pkgFlags) {
633        return new PackageSetting(
634                PACKAGE_NAME,
635                REAL_PACKAGE_NAME,
636                INITIAL_CODE_PATH /*codePath*/,
637                INITIAL_CODE_PATH /*resourcePath*/,
638                null /*legacyNativeLibraryPathString*/,
639                "x86_64" /*primaryCpuAbiString*/,
640                "x86" /*secondaryCpuAbiString*/,
641                null /*cpuAbiOverrideString*/,
642                INITIAL_VERSION_CODE,
643                pkgFlags,
644                0 /*privateFlags*/,
645                null /*parentPackageName*/,
646                null /*childPackageNames*/,
647                sharedUserId,
648                null /*usesStaticLibraries*/,
649                null /*usesStaticLibrariesVersions*/);
650    }
651
652    private @NonNull List<UserInfo> createFakeUsers() {
653        ArrayList<UserInfo> users = new ArrayList<>();
654        users.add(new UserInfo(UserHandle.USER_SYSTEM, "test user", UserInfo.FLAG_INITIALIZED));
655        return users;
656    }
657
658    private void writeFile(File file, byte[] data) {
659        file.mkdirs();
660        try {
661            AtomicFile aFile = new AtomicFile(file);
662            FileOutputStream fos = aFile.startWrite();
663            fos.write(data);
664            aFile.finishWrite(fos);
665        } catch (IOException ioe) {
666            Log.e(TAG, "Cannot write file " + file.getPath());
667        }
668    }
669
670    private void writePackagesXml() {
671        writeFile(new File(InstrumentationRegistry.getContext().getFilesDir(), "system/packages.xml"),
672                ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
673                + "<packages>"
674                + "<last-platform-version internal=\"15\" external=\"0\" fingerprint=\"foo\" />"
675                + "<permission-trees>"
676                + "<item name=\"com.google.android.permtree\" package=\"com.google.android.permpackage\" />"
677                + "</permission-trees>"
678                + "<permissions>"
679                + "<item name=\"android.permission.WRITE_CALL_LOG\" package=\"android\" protection=\"1\" />"
680                + "<item name=\"android.permission.ASEC_ACCESS\" package=\"android\" protection=\"2\" />"
681                + "<item name=\"android.permission.ACCESS_WIMAX_STATE\" package=\"android\" />"
682                + "<item name=\"android.permission.REBOOT\" package=\"android\" protection=\"18\" />"
683                + "</permissions>"
684                + "<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\">"
685                + "<sigs count=\"1\">"
686                + "<cert index=\"0\" key=\"" + KeySetStrings.ctsKeySetCertA + "\" />"
687                + "</sigs>"
688                + "<proper-signing-keyset identifier=\"1\" />"
689                + "</package>"
690                + "<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\">"
691                + "<sigs count=\"1\">"
692                + "<cert index=\"0\" />"
693                + "</sigs>"
694                + "<proper-signing-keyset identifier=\"1\" />"
695                + "<defined-keyset alias=\"AB\" identifier=\"4\" />"
696                + "</package>"
697                + "<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\">"
698                + "<sigs count=\"1\">"
699                + "<cert index=\"1\" key=\"" + KeySetStrings.ctsKeySetCertB + "\" />"
700                + "</sigs>"
701                + "<proper-signing-keyset identifier=\"2\" />"
702                + "<upgrade-keyset identifier=\"3\" />"
703                + "<defined-keyset alias=\"C\" identifier=\"3\" />"
704                + "</package>"
705                + "<shared-user name=\"com.android.shared1\" userId=\"11000\">"
706                + "<sigs count=\"1\">"
707                + "<cert index=\"1\" />"
708                + "</sigs>"
709                + "<perms>"
710                + "<item name=\"android.permission.REBOOT\" />"
711                + "</perms>"
712                + "</shared-user>"
713                + "<keyset-settings version=\"1\">"
714                + "<keys>"
715                + "<public-key identifier=\"1\" value=\"" + KeySetStrings.ctsKeySetPublicKeyA + "\" />"
716                + "<public-key identifier=\"2\" value=\"" + KeySetStrings.ctsKeySetPublicKeyB + "\" />"
717                + "<public-key identifier=\"3\" value=\"" + KeySetStrings.ctsKeySetPublicKeyC + "\" />"
718                + "</keys>"
719                + "<keysets>"
720                + "<keyset identifier=\"1\">"
721                + "<key-id identifier=\"1\" />"
722                + "</keyset>"
723                + "<keyset identifier=\"2\">"
724                + "<key-id identifier=\"2\" />"
725                + "</keyset>"
726                + "<keyset identifier=\"3\">"
727                + "<key-id identifier=\"3\" />"
728                + "</keyset>"
729                + "<keyset identifier=\"4\">"
730                + "<key-id identifier=\"1\" />"
731                + "<key-id identifier=\"2\" />"
732                + "</keyset>"
733                + "</keysets>"
734                + "<lastIssuedKeyId value=\"3\" />"
735                + "<lastIssuedKeySetId value=\"4\" />"
736                + "</keyset-settings>"
737                + "</packages>").getBytes());
738    }
739
740    private void writeStoppedPackagesXml() {
741        writeFile(new File(InstrumentationRegistry.getContext().getFilesDir(), "system/packages-stopped.xml"),
742                ( "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
743                + "<stopped-packages>"
744                + "<pkg name=\"com.google.app1\" nl=\"1\" />"
745                + "<pkg name=\"com.android.app3\" nl=\"1\" />"
746                + "</stopped-packages>")
747                .getBytes());
748    }
749
750    private void writePackagesList() {
751        writeFile(new File(InstrumentationRegistry.getContext().getFilesDir(), "system/packages.list"),
752                ( "com.google.app1 11000 0 /data/data/com.google.app1 seinfo1"
753                + "com.google.app2 11001 0 /data/data/com.google.app2 seinfo2"
754                + "com.android.app3 11030 0 /data/data/com.android.app3 seinfo3")
755                .getBytes());
756    }
757
758    private void deleteSystemFolder() {
759        File systemFolder = new File(InstrumentationRegistry.getContext().getFilesDir(), "system");
760        deleteFolder(systemFolder);
761    }
762
763    private static void deleteFolder(File folder) {
764        File[] files = folder.listFiles();
765        if (files != null) {
766            for (File file : files) {
767                deleteFolder(file);
768            }
769        }
770        folder.delete();
771    }
772
773    private void writeOldFiles() {
774        deleteSystemFolder();
775        writePackagesXml();
776        writeStoppedPackagesXml();
777        writePackagesList();
778    }
779
780    @Before
781    public void createUserManagerServiceRef() throws ReflectiveOperationException {
782        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
783            @Override
784            public void run() {
785                Constructor<UserManagerService> umsc;
786                try {
787                    // unregister the user manager from the local service
788                    Method removeServiceForTest = LocalServices.class.getDeclaredMethod(
789                            "removeServiceForTest", Class.class);
790                    removeServiceForTest.invoke(null, UserManagerInternal.class);
791
792                    // now create a new user manager [which registers again with the local service]
793                    umsc = UserManagerService.class.getDeclaredConstructor(
794                            Context.class,
795                            PackageManagerService.class,
796                            Object.class,
797                            File.class);
798                    umsc.setAccessible(true);
799                    UserManagerService ums = umsc.newInstance(InstrumentationRegistry.getContext(),
800                            null /*PackageManagerService*/, new Object() /*packagesLock*/,
801                            new File(InstrumentationRegistry.getContext().getFilesDir(), "user"));
802                } catch (SecurityException
803                        | ReflectiveOperationException
804                        | IllegalArgumentException e) {
805                    fail("Could not create user manager service; " + e);
806                }
807            }
808        });
809    }
810
811    private void verifyKeySetMetaData(Settings settings)
812            throws ReflectiveOperationException, IllegalAccessException {
813        ArrayMap<String, PackageSetting> packages = settings.mPackages;
814        KeySetManagerService ksms = settings.mKeySetManagerService;
815
816        /* verify keyset and public key ref counts */
817        assertThat(KeySetUtils.getKeySetRefCount(ksms, 1), is(2));
818        assertThat(KeySetUtils.getKeySetRefCount(ksms, 2), is(1));
819        assertThat(KeySetUtils.getKeySetRefCount(ksms, 3), is(1));
820        assertThat(KeySetUtils.getKeySetRefCount(ksms, 4), is(1));
821        assertThat(KeySetUtils.getPubKeyRefCount(ksms, 1), is(2));
822        assertThat(KeySetUtils.getPubKeyRefCount(ksms, 2), is(2));
823        assertThat(KeySetUtils.getPubKeyRefCount(ksms, 3), is(1));
824
825        /* verify public keys properly read */
826        PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
827        PublicKey keyB = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyB);
828        PublicKey keyC = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyC);
829        assertThat(KeySetUtils.getPubKey(ksms, 1), is(keyA));
830        assertThat(KeySetUtils.getPubKey(ksms, 2), is(keyB));
831        assertThat(KeySetUtils.getPubKey(ksms, 3), is(keyC));
832
833        /* verify mapping is correct (ks -> pub keys) */
834        LongSparseArray<ArraySet<Long>> ksMapping = KeySetUtils.getKeySetMapping(ksms);
835        ArraySet<Long> mapping = ksMapping.get(1);
836        assertThat(mapping.size(), is(1));
837        assertThat(mapping.contains(new Long(1)), is(true));
838        mapping = ksMapping.get(2);
839        assertThat(mapping.size(), is(1));
840        assertThat(mapping.contains(new Long(2)), is(true));
841        mapping = ksMapping.get(3);
842        assertThat(mapping.size(), is(1));
843        assertThat(mapping.contains(new Long(3)), is(true));
844        mapping = ksMapping.get(4);
845        assertThat(mapping.size(), is(2));
846        assertThat(mapping.contains(new Long(1)), is(true));
847        assertThat(mapping.contains(new Long(2)), is(true));
848
849        /* verify lastIssuedIds are consistent */
850        assertThat(KeySetUtils.getLastIssuedKeyId(ksms), is(3L));
851        assertThat(KeySetUtils.getLastIssuedKeySetId(ksms), is(4L));
852
853        /* verify packages have been given the appropriate information */
854        PackageSetting ps = packages.get("com.google.app1");
855        assertThat(ps.keySetData.getProperSigningKeySet(), is(1L));
856        ps = packages.get("com.google.app2");
857        assertThat(ps.keySetData.getProperSigningKeySet(), is(1L));
858        assertThat(ps.keySetData.getAliases().get("AB"), is(4L));
859        ps = packages.get("com.android.app3");
860        assertThat(ps.keySetData.getProperSigningKeySet(), is(2L));
861        assertThat(ps.keySetData.getAliases().get("C"), is(3L));
862        assertThat(ps.keySetData.getUpgradeKeySets().length, is(1));
863        assertThat(ps.keySetData.getUpgradeKeySets()[0], is(3L));
864    }
865}
866