Loading services/core/java/com/android/server/pm/AppIdSettingMap.java 0 → 100644 +62 −0 Original line number Diff line number Diff line /* * Copyright (C) 2022 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.pm; import android.os.Process; import com.android.server.utils.WatchedSparseArray; /** * A wrapper over {@link WatchedSparseArray} that tracks the current maximum App ID. */ public class AppIdSettingMap extends WatchedSparseArray<SettingBase> { private int mCurrentMaxAppId; @Override public void put(int key, SettingBase value) { if (key > mCurrentMaxAppId) { mCurrentMaxAppId = key; } super.put(key, value); } @Override public AppIdSettingMap snapshot() { AppIdSettingMap l = new AppIdSettingMap(); snapshot(l, this); return l; } /** * @return the maximum of all the App IDs that have been added to the map. 0 if map is empty. */ public int getCurrentMaxAppId() { return mCurrentMaxAppId; } /** * @return the next available App ID that has not been added to the map */ public int getNextAvailableAppId() { if (mCurrentMaxAppId == 0) { // No app id has been added yet return Process.FIRST_APPLICATION_UID; } else { return mCurrentMaxAppId + 1; } } } services/core/java/com/android/server/pm/Settings.java +29 −65 Original line number Diff line number Diff line Loading @@ -40,7 +40,6 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.ComponentInfo; import android.content.pm.IntentFilterVerificationInfo; import android.content.pm.PackageInstaller; import android.content.pm.PackageManager; Loading Loading @@ -113,11 +112,9 @@ import com.android.server.pm.permission.LegacyPermissionState.PermissionState; import com.android.server.pm.pkg.PackageStateInternal; import com.android.server.pm.pkg.PackageUserState; import com.android.server.pm.pkg.PackageUserStateInternal; import com.android.server.pm.pkg.PackageUserStateUtils; import com.android.server.pm.pkg.SuspendParams; import com.android.server.pm.pkg.component.ParsedComponent; import com.android.server.pm.pkg.component.ParsedIntentInfo; import com.android.server.pm.pkg.component.ParsedMainComponent; import com.android.server.pm.pkg.component.ParsedPermission; import com.android.server.pm.pkg.component.ParsedProcess; import com.android.server.pm.pkg.parsing.PackageInfoWithoutStateUtils; Loading Loading @@ -476,9 +473,9 @@ public final class Settings implements Watchable, Snappable { @Watched final WatchedArrayMap<String, SharedUserSetting> mSharedUsers = new WatchedArrayMap<>(); @Watched private final WatchedArrayList<SettingBase> mAppIds; private final AppIdSettingMap mAppIds; @Watched private final WatchedSparseArray<SettingBase> mOtherAppIds; private final AppIdSettingMap mOtherAppIds; // For reading/writing settings file. @Watched Loading Loading @@ -594,8 +591,8 @@ public final class Settings implements Watchable, Snappable { mLock = new PackageManagerTracedLock(); mPackages.putAll(pkgSettings); mAppIds = new WatchedArrayList<>(); mOtherAppIds = new WatchedSparseArray<>(); mAppIds = new AppIdSettingMap(); mOtherAppIds = new AppIdSettingMap(); mSystemDir = null; mPermissions = null; mRuntimePermissionsPersistence = null; Loading Loading @@ -631,8 +628,8 @@ public final class Settings implements Watchable, Snappable { mKeySetManagerService = new KeySetManagerService(mPackages); mLock = lock; mAppIds = new WatchedArrayList<>(); mOtherAppIds = new WatchedSparseArray<>(); mAppIds = new AppIdSettingMap(); mOtherAppIds = new AppIdSettingMap(); mPermissions = new LegacyPermissionSettings(lock); mRuntimePermissionsPersistence = new RuntimePermissionPersistence( runtimePermissionsPersistence, new Consumer<Integer>() { Loading Loading @@ -1278,7 +1275,8 @@ public final class Settings implements Watchable, Snappable { // Utility method that adds a PackageSetting to mPackages and // completes updating the shared user attributes and any restored // app link verification state private void addPackageSettingLPw(PackageSetting p, SharedUserSetting sharedUser) { @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) void addPackageSettingLPw(PackageSetting p, SharedUserSetting sharedUser) { mPackages.put(p.getPackageName(), p); if (sharedUser != null) { SharedUserSetting existingSharedUserSetting = getSharedUserSettingLPr(p); Loading @@ -1301,7 +1299,7 @@ public final class Settings implements Watchable, Snappable { p.setAppId(sharedUser.mAppId); } // If the we know about this user id, we have to update it as it // If we know about this user id, we have to update it as it // has to point to the same PackageSetting instance as the package. Object userIdPs = getSettingLPr(p.getAppId()); if (sharedUser == null) { Loading Loading @@ -1366,20 +1364,13 @@ public final class Settings implements Watchable, Snappable { } if (appId >= Process.FIRST_APPLICATION_UID) { int size = mAppIds.size(); final int index = appId - Process.FIRST_APPLICATION_UID; // fill the array until our index becomes valid while (index >= size) { mAppIds.add(null); size++; } if (mAppIds.get(index) != null) { if (mAppIds.get(appId) != null) { PackageManagerService.reportSettingsProblem(Log.WARN, "Adding duplicate app id: " + appId + " name=" + name); return false; } mAppIds.set(index, obj); mAppIds.put(appId, obj); } else { if (mOtherAppIds.get(appId) != null) { PackageManagerService.reportSettingsProblem(Log.WARN, Loading @@ -1395,9 +1386,7 @@ public final class Settings implements Watchable, Snappable { /** Gets the setting associated with the provided App ID */ public SettingBase getSettingLPr(int appId) { if (appId >= Process.FIRST_APPLICATION_UID) { final int size = mAppIds.size(); final int index = appId - Process.FIRST_APPLICATION_UID; return index < size ? mAppIds.get(index) : null; return mAppIds.get(appId); } else { return mOtherAppIds.get(appId); } Loading @@ -1406,9 +1395,7 @@ public final class Settings implements Watchable, Snappable { /** Unregisters the provided app ID. */ void removeAppIdLPw(int appId) { if (appId >= Process.FIRST_APPLICATION_UID) { final int size = mAppIds.size(); final int index = appId - Process.FIRST_APPLICATION_UID; if (index < size) mAppIds.set(index, null); mAppIds.remove(appId); } else { mOtherAppIds.remove(appId); } Loading @@ -1417,9 +1404,14 @@ public final class Settings implements Watchable, Snappable { private void replaceAppIdLPw(int appId, SettingBase obj) { if (appId >= Process.FIRST_APPLICATION_UID) { final int size = mAppIds.size(); final int index = appId - Process.FIRST_APPLICATION_UID; if (index < size) mAppIds.set(index, obj); if (appId <= mAppIds.getCurrentMaxAppId()) { mAppIds.put(appId, obj); } else { PackageManagerService.reportSettingsProblem(Log.WARN, "Error in package manager settings: calling replaceAppIdLpw to" + " replace SettingBase at appId=" + appId + " but nothing is replaced."); } } else { mOtherAppIds.put(appId, obj); } Loading Loading @@ -4304,22 +4296,21 @@ public final class Settings implements Watchable, Snappable { /** Returns a new AppID or -1 if we could not find an available AppID to assign */ private int acquireAndRegisterNewAppIdLPw(SettingBase obj) { // Let's be stupidly inefficient for now... final int size = mAppIds.size(); for (int i = mFirstAvailableUid - Process.FIRST_APPLICATION_UID; i < size; i++) { if (mAppIds.get(i) == null) { mAppIds.set(i, obj); return Process.FIRST_APPLICATION_UID + i; final int nextAvailableAppId = mAppIds.getNextAvailableAppId(); for (int uid = mFirstAvailableUid; uid < nextAvailableAppId; uid++) { if (mAppIds.get(uid) == null) { mAppIds.put(uid, obj); return uid; } } // None left? if (size > (Process.LAST_APPLICATION_UID - Process.FIRST_APPLICATION_UID)) { if (nextAvailableAppId > Process.LAST_APPLICATION_UID) { return -1; } mAppIds.add(obj); return Process.FIRST_APPLICATION_UID + size; mAppIds.put(nextAvailableAppId, obj); return nextAvailableAppId; } public VerifierDeviceIdentity getVerifierDeviceIdentityLPw(@NonNull Computer computer) { Loading Loading @@ -4354,33 +4345,6 @@ public final class Settings implements Watchable, Snappable { return getDisabledSystemPkgLPr(enabledPackageSetting.getPackageName()); } boolean isEnabledAndMatchLPr(ComponentInfo componentInfo, long flags, int userId) { final PackageSetting ps = mPackages.get(componentInfo.packageName); if (ps == null) return false; final PackageUserStateInternal userState = ps.readUserState(userId); return PackageUserStateUtils.isMatch(userState, componentInfo, flags); } @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public boolean isEnabledAndMatchLPr(AndroidPackage pkg, ParsedMainComponent component, long flags, int userId) { final PackageSetting ps = mPackages.get(component.getPackageName()); if (ps == null) return false; final PackageUserStateInternal userState = ps.readUserState(userId); return PackageUserStateUtils.isMatch(userState, pkg.isSystem(), pkg.isEnabled(), component, flags); } boolean isOrphaned(String packageName) { final PackageSetting pkg = mPackages.get(packageName); if (pkg == null) { throw new IllegalArgumentException("Unknown package: " + packageName); } return pkg.getInstallSource().isOrphaned; } int getApplicationEnabledSettingLPr(String packageName, int userId) throws PackageManager.NameNotFoundException { final PackageSetting pkg = mPackages.get(packageName); Loading services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java +54 −1 Original line number Diff line number Diff line Loading @@ -31,11 +31,11 @@ import static org.hamcrest.CoreMatchers.not; import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.CoreMatchers.nullValue; import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import android.annotation.NonNull; Loading Loading @@ -1103,6 +1103,59 @@ public class PackageManagerSettingsTests { assertThat(countDownLatch.getCount(), is(0L)); } @Test public void testRegisterAndRemoveAppId() throws PackageManagerException { // Test that the first new app UID should start from FIRST_APPLICATION_UID final Settings settings = makeSettings(); final PackageSetting ps = createPackageSetting("com.foo"); assertTrue(settings.registerAppIdLPw(ps, false)); assertEquals(10000, ps.getAppId()); // Set up existing app IDs: 10000, 10001, 10003 final PackageSetting ps1 = createPackageSetting("com.foo1"); ps1.setAppId(10001); final PackageSetting ps2 = createPackageSetting("com.foo2"); ps2.setAppId(10003); final PackageSetting ps3 = createPackageSetting("com.foo3"); assertEquals(0, ps3.getAppId()); assertTrue(settings.registerAppIdLPw(ps1, false)); assertTrue(settings.registerAppIdLPw(ps2, false)); assertTrue(settings.registerAppIdLPw(ps3, false)); assertEquals(10001, ps1.getAppId()); assertEquals(10003, ps2.getAppId()); // Expecting the new one to start with the next available uid assertEquals(10002, ps3.getAppId()); // Remove and insert a new one and the new one should not reuse the same uid settings.removeAppIdLPw(10002); final PackageSetting ps4 = createPackageSetting("com.foo4"); assertTrue(settings.registerAppIdLPw(ps4, false)); assertEquals(10004, ps4.getAppId()); // Keep adding more final PackageSetting ps5 = createPackageSetting("com.foo5"); assertTrue(settings.registerAppIdLPw(ps5, false)); assertEquals(10005, ps5.getAppId()); // Remove the last one and the new one should use incremented uid settings.removeAppIdLPw(10005); final PackageSetting ps6 = createPackageSetting("com.foo6"); assertTrue(settings.registerAppIdLPw(ps6, false)); assertEquals(10006, ps6.getAppId()); } /** * Test replacing a PackageSetting with a SharedUserSetting in mAppIds */ @Test public void testAddPackageSetting() throws PackageManagerException { final Settings settings = makeSettings(); final SharedUserSetting sus1 = new SharedUserSetting( "TestUser", 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/); sus1.mAppId = 10001; final PackageSetting ps1 = createPackageSetting("com.foo"); ps1.setAppId(10001); assertTrue(settings.registerAppIdLPw(ps1, false)); settings.addPackageSettingLPw(ps1, sus1); assertSame(sus1, settings.getSharedUserSettingLPr(ps1)); } private void verifyUserState(PackageUserState userState, boolean notLaunched, boolean stopped, boolean installed) { assertThat(userState.getEnabledState(), is(0)); Loading Loading
services/core/java/com/android/server/pm/AppIdSettingMap.java 0 → 100644 +62 −0 Original line number Diff line number Diff line /* * Copyright (C) 2022 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.pm; import android.os.Process; import com.android.server.utils.WatchedSparseArray; /** * A wrapper over {@link WatchedSparseArray} that tracks the current maximum App ID. */ public class AppIdSettingMap extends WatchedSparseArray<SettingBase> { private int mCurrentMaxAppId; @Override public void put(int key, SettingBase value) { if (key > mCurrentMaxAppId) { mCurrentMaxAppId = key; } super.put(key, value); } @Override public AppIdSettingMap snapshot() { AppIdSettingMap l = new AppIdSettingMap(); snapshot(l, this); return l; } /** * @return the maximum of all the App IDs that have been added to the map. 0 if map is empty. */ public int getCurrentMaxAppId() { return mCurrentMaxAppId; } /** * @return the next available App ID that has not been added to the map */ public int getNextAvailableAppId() { if (mCurrentMaxAppId == 0) { // No app id has been added yet return Process.FIRST_APPLICATION_UID; } else { return mCurrentMaxAppId + 1; } } }
services/core/java/com/android/server/pm/Settings.java +29 −65 Original line number Diff line number Diff line Loading @@ -40,7 +40,6 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.ComponentInfo; import android.content.pm.IntentFilterVerificationInfo; import android.content.pm.PackageInstaller; import android.content.pm.PackageManager; Loading Loading @@ -113,11 +112,9 @@ import com.android.server.pm.permission.LegacyPermissionState.PermissionState; import com.android.server.pm.pkg.PackageStateInternal; import com.android.server.pm.pkg.PackageUserState; import com.android.server.pm.pkg.PackageUserStateInternal; import com.android.server.pm.pkg.PackageUserStateUtils; import com.android.server.pm.pkg.SuspendParams; import com.android.server.pm.pkg.component.ParsedComponent; import com.android.server.pm.pkg.component.ParsedIntentInfo; import com.android.server.pm.pkg.component.ParsedMainComponent; import com.android.server.pm.pkg.component.ParsedPermission; import com.android.server.pm.pkg.component.ParsedProcess; import com.android.server.pm.pkg.parsing.PackageInfoWithoutStateUtils; Loading Loading @@ -476,9 +473,9 @@ public final class Settings implements Watchable, Snappable { @Watched final WatchedArrayMap<String, SharedUserSetting> mSharedUsers = new WatchedArrayMap<>(); @Watched private final WatchedArrayList<SettingBase> mAppIds; private final AppIdSettingMap mAppIds; @Watched private final WatchedSparseArray<SettingBase> mOtherAppIds; private final AppIdSettingMap mOtherAppIds; // For reading/writing settings file. @Watched Loading Loading @@ -594,8 +591,8 @@ public final class Settings implements Watchable, Snappable { mLock = new PackageManagerTracedLock(); mPackages.putAll(pkgSettings); mAppIds = new WatchedArrayList<>(); mOtherAppIds = new WatchedSparseArray<>(); mAppIds = new AppIdSettingMap(); mOtherAppIds = new AppIdSettingMap(); mSystemDir = null; mPermissions = null; mRuntimePermissionsPersistence = null; Loading Loading @@ -631,8 +628,8 @@ public final class Settings implements Watchable, Snappable { mKeySetManagerService = new KeySetManagerService(mPackages); mLock = lock; mAppIds = new WatchedArrayList<>(); mOtherAppIds = new WatchedSparseArray<>(); mAppIds = new AppIdSettingMap(); mOtherAppIds = new AppIdSettingMap(); mPermissions = new LegacyPermissionSettings(lock); mRuntimePermissionsPersistence = new RuntimePermissionPersistence( runtimePermissionsPersistence, new Consumer<Integer>() { Loading Loading @@ -1278,7 +1275,8 @@ public final class Settings implements Watchable, Snappable { // Utility method that adds a PackageSetting to mPackages and // completes updating the shared user attributes and any restored // app link verification state private void addPackageSettingLPw(PackageSetting p, SharedUserSetting sharedUser) { @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) void addPackageSettingLPw(PackageSetting p, SharedUserSetting sharedUser) { mPackages.put(p.getPackageName(), p); if (sharedUser != null) { SharedUserSetting existingSharedUserSetting = getSharedUserSettingLPr(p); Loading @@ -1301,7 +1299,7 @@ public final class Settings implements Watchable, Snappable { p.setAppId(sharedUser.mAppId); } // If the we know about this user id, we have to update it as it // If we know about this user id, we have to update it as it // has to point to the same PackageSetting instance as the package. Object userIdPs = getSettingLPr(p.getAppId()); if (sharedUser == null) { Loading Loading @@ -1366,20 +1364,13 @@ public final class Settings implements Watchable, Snappable { } if (appId >= Process.FIRST_APPLICATION_UID) { int size = mAppIds.size(); final int index = appId - Process.FIRST_APPLICATION_UID; // fill the array until our index becomes valid while (index >= size) { mAppIds.add(null); size++; } if (mAppIds.get(index) != null) { if (mAppIds.get(appId) != null) { PackageManagerService.reportSettingsProblem(Log.WARN, "Adding duplicate app id: " + appId + " name=" + name); return false; } mAppIds.set(index, obj); mAppIds.put(appId, obj); } else { if (mOtherAppIds.get(appId) != null) { PackageManagerService.reportSettingsProblem(Log.WARN, Loading @@ -1395,9 +1386,7 @@ public final class Settings implements Watchable, Snappable { /** Gets the setting associated with the provided App ID */ public SettingBase getSettingLPr(int appId) { if (appId >= Process.FIRST_APPLICATION_UID) { final int size = mAppIds.size(); final int index = appId - Process.FIRST_APPLICATION_UID; return index < size ? mAppIds.get(index) : null; return mAppIds.get(appId); } else { return mOtherAppIds.get(appId); } Loading @@ -1406,9 +1395,7 @@ public final class Settings implements Watchable, Snappable { /** Unregisters the provided app ID. */ void removeAppIdLPw(int appId) { if (appId >= Process.FIRST_APPLICATION_UID) { final int size = mAppIds.size(); final int index = appId - Process.FIRST_APPLICATION_UID; if (index < size) mAppIds.set(index, null); mAppIds.remove(appId); } else { mOtherAppIds.remove(appId); } Loading @@ -1417,9 +1404,14 @@ public final class Settings implements Watchable, Snappable { private void replaceAppIdLPw(int appId, SettingBase obj) { if (appId >= Process.FIRST_APPLICATION_UID) { final int size = mAppIds.size(); final int index = appId - Process.FIRST_APPLICATION_UID; if (index < size) mAppIds.set(index, obj); if (appId <= mAppIds.getCurrentMaxAppId()) { mAppIds.put(appId, obj); } else { PackageManagerService.reportSettingsProblem(Log.WARN, "Error in package manager settings: calling replaceAppIdLpw to" + " replace SettingBase at appId=" + appId + " but nothing is replaced."); } } else { mOtherAppIds.put(appId, obj); } Loading Loading @@ -4304,22 +4296,21 @@ public final class Settings implements Watchable, Snappable { /** Returns a new AppID or -1 if we could not find an available AppID to assign */ private int acquireAndRegisterNewAppIdLPw(SettingBase obj) { // Let's be stupidly inefficient for now... final int size = mAppIds.size(); for (int i = mFirstAvailableUid - Process.FIRST_APPLICATION_UID; i < size; i++) { if (mAppIds.get(i) == null) { mAppIds.set(i, obj); return Process.FIRST_APPLICATION_UID + i; final int nextAvailableAppId = mAppIds.getNextAvailableAppId(); for (int uid = mFirstAvailableUid; uid < nextAvailableAppId; uid++) { if (mAppIds.get(uid) == null) { mAppIds.put(uid, obj); return uid; } } // None left? if (size > (Process.LAST_APPLICATION_UID - Process.FIRST_APPLICATION_UID)) { if (nextAvailableAppId > Process.LAST_APPLICATION_UID) { return -1; } mAppIds.add(obj); return Process.FIRST_APPLICATION_UID + size; mAppIds.put(nextAvailableAppId, obj); return nextAvailableAppId; } public VerifierDeviceIdentity getVerifierDeviceIdentityLPw(@NonNull Computer computer) { Loading Loading @@ -4354,33 +4345,6 @@ public final class Settings implements Watchable, Snappable { return getDisabledSystemPkgLPr(enabledPackageSetting.getPackageName()); } boolean isEnabledAndMatchLPr(ComponentInfo componentInfo, long flags, int userId) { final PackageSetting ps = mPackages.get(componentInfo.packageName); if (ps == null) return false; final PackageUserStateInternal userState = ps.readUserState(userId); return PackageUserStateUtils.isMatch(userState, componentInfo, flags); } @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public boolean isEnabledAndMatchLPr(AndroidPackage pkg, ParsedMainComponent component, long flags, int userId) { final PackageSetting ps = mPackages.get(component.getPackageName()); if (ps == null) return false; final PackageUserStateInternal userState = ps.readUserState(userId); return PackageUserStateUtils.isMatch(userState, pkg.isSystem(), pkg.isEnabled(), component, flags); } boolean isOrphaned(String packageName) { final PackageSetting pkg = mPackages.get(packageName); if (pkg == null) { throw new IllegalArgumentException("Unknown package: " + packageName); } return pkg.getInstallSource().isOrphaned; } int getApplicationEnabledSettingLPr(String packageName, int userId) throws PackageManager.NameNotFoundException { final PackageSetting pkg = mPackages.get(packageName); Loading
services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java +54 −1 Original line number Diff line number Diff line Loading @@ -31,11 +31,11 @@ import static org.hamcrest.CoreMatchers.not; import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.CoreMatchers.nullValue; import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import android.annotation.NonNull; Loading Loading @@ -1103,6 +1103,59 @@ public class PackageManagerSettingsTests { assertThat(countDownLatch.getCount(), is(0L)); } @Test public void testRegisterAndRemoveAppId() throws PackageManagerException { // Test that the first new app UID should start from FIRST_APPLICATION_UID final Settings settings = makeSettings(); final PackageSetting ps = createPackageSetting("com.foo"); assertTrue(settings.registerAppIdLPw(ps, false)); assertEquals(10000, ps.getAppId()); // Set up existing app IDs: 10000, 10001, 10003 final PackageSetting ps1 = createPackageSetting("com.foo1"); ps1.setAppId(10001); final PackageSetting ps2 = createPackageSetting("com.foo2"); ps2.setAppId(10003); final PackageSetting ps3 = createPackageSetting("com.foo3"); assertEquals(0, ps3.getAppId()); assertTrue(settings.registerAppIdLPw(ps1, false)); assertTrue(settings.registerAppIdLPw(ps2, false)); assertTrue(settings.registerAppIdLPw(ps3, false)); assertEquals(10001, ps1.getAppId()); assertEquals(10003, ps2.getAppId()); // Expecting the new one to start with the next available uid assertEquals(10002, ps3.getAppId()); // Remove and insert a new one and the new one should not reuse the same uid settings.removeAppIdLPw(10002); final PackageSetting ps4 = createPackageSetting("com.foo4"); assertTrue(settings.registerAppIdLPw(ps4, false)); assertEquals(10004, ps4.getAppId()); // Keep adding more final PackageSetting ps5 = createPackageSetting("com.foo5"); assertTrue(settings.registerAppIdLPw(ps5, false)); assertEquals(10005, ps5.getAppId()); // Remove the last one and the new one should use incremented uid settings.removeAppIdLPw(10005); final PackageSetting ps6 = createPackageSetting("com.foo6"); assertTrue(settings.registerAppIdLPw(ps6, false)); assertEquals(10006, ps6.getAppId()); } /** * Test replacing a PackageSetting with a SharedUserSetting in mAppIds */ @Test public void testAddPackageSetting() throws PackageManagerException { final Settings settings = makeSettings(); final SharedUserSetting sus1 = new SharedUserSetting( "TestUser", 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/); sus1.mAppId = 10001; final PackageSetting ps1 = createPackageSetting("com.foo"); ps1.setAppId(10001); assertTrue(settings.registerAppIdLPw(ps1, false)); settings.addPackageSettingLPw(ps1, sus1); assertSame(sus1, settings.getSharedUserSettingLPr(ps1)); } private void verifyUserState(PackageUserState userState, boolean notLaunched, boolean stopped, boolean installed) { assertThat(userState.getEnabledState(), is(0)); Loading