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