Merge "[pm] revert changes to mAppIds" into tm-dev

This commit is contained in:
TreeHugger Robot
2022-03-15 00:15:41 +00:00
committed by Android (Google) Code Review
2 changed files with 123 additions and 124 deletions

View File

@@ -17,46 +17,131 @@
package com.android.server.pm; package com.android.server.pm;
import android.os.Process; import android.os.Process;
import android.util.Log;
import com.android.server.utils.WatchedArrayList;
import com.android.server.utils.WatchedSparseArray; import com.android.server.utils.WatchedSparseArray;
import com.android.server.utils.Watcher;
/** /**
* A wrapper over {@link WatchedSparseArray} that tracks the current maximum App ID. * A wrapper over {@link WatchedArrayList} that tracks the current (app ID -> SettingBase) mapping
* for non-system apps. Also tracks system app settings in an {@link WatchedSparseArray}.
*/ */
public class AppIdSettingMap extends WatchedSparseArray<SettingBase> { final class AppIdSettingMap {
private int mCurrentMaxAppId; /**
* We use an ArrayList instead of an SparseArray for non system apps because the number of apps
* might be big, and only ArrayList gives us a constant lookup time. For a given app ID, the
* index to the corresponding SettingBase object is (appId - FIRST_APPLICATION_ID). If an app ID
* doesn't exist (i.e., app is not installed), we fill the corresponding entry with null.
*/
private WatchedArrayList<SettingBase> mNonSystemSettings = new WatchedArrayList<>();
private WatchedSparseArray<SettingBase> mSystemSettings = new WatchedSparseArray<>();
private int mFirstAvailableAppId = Process.FIRST_APPLICATION_UID;
@Override /** Returns true if the requested AppID was valid and not already registered. */
public void put(int key, SettingBase value) { public boolean registerExistingAppId(int appId, SettingBase setting, Object name) {
if (key > mCurrentMaxAppId) { if (appId >= Process.FIRST_APPLICATION_UID) {
mCurrentMaxAppId = key; int size = mNonSystemSettings.size();
final int index = appId - Process.FIRST_APPLICATION_UID;
// fill the array until our index becomes valid
while (index >= size) {
mNonSystemSettings.add(null);
size++;
} }
super.put(key, value); if (mNonSystemSettings.get(index) != null) {
PackageManagerService.reportSettingsProblem(Log.WARN,
"Adding duplicate app id: " + appId
+ " name=" + name);
return false;
}
mNonSystemSettings.set(index, setting);
} else {
if (mSystemSettings.get(appId) != null) {
PackageManagerService.reportSettingsProblem(Log.WARN,
"Adding duplicate shared id: " + appId
+ " name=" + name);
return false;
}
mSystemSettings.put(appId, setting);
}
return true;
}
public SettingBase getSetting(int appId) {
if (appId >= Process.FIRST_APPLICATION_UID) {
final int size = mNonSystemSettings.size();
final int index = appId - Process.FIRST_APPLICATION_UID;
return index < size ? mNonSystemSettings.get(index) : null;
} else {
return mSystemSettings.get(appId);
}
}
public void removeSetting(int appId) {
if (appId >= Process.FIRST_APPLICATION_UID) {
final int size = mNonSystemSettings.size();
final int index = appId - Process.FIRST_APPLICATION_UID;
if (index < size) {
mNonSystemSettings.set(index, null);
}
} else {
mSystemSettings.remove(appId);
}
setFirstAvailableAppId(appId + 1);
}
// This should be called (at least) whenever an application is removed
private void setFirstAvailableAppId(int uid) {
if (uid > mFirstAvailableAppId) {
mFirstAvailableAppId = uid;
}
}
public void replaceSetting(int appId, SettingBase setting) {
if (appId >= Process.FIRST_APPLICATION_UID) {
final int size = mNonSystemSettings.size();
final int index = appId - Process.FIRST_APPLICATION_UID;
if (index < size) {
mNonSystemSettings.set(index, setting);
} else {
PackageManagerService.reportSettingsProblem(Log.WARN,
"Error in package manager settings: calling replaceAppIdLpw to"
+ " replace SettingBase at appId=" + appId
+ " but nothing is replaced.");
}
} else {
mSystemSettings.put(appId, setting);
}
}
/** Returns a new AppID or -1 if we could not find an available AppID to assign */
public int acquireAndRegisterNewAppId(SettingBase obj) {
final int size = mNonSystemSettings.size();
for (int i = mFirstAvailableAppId - Process.FIRST_APPLICATION_UID; i < size; i++) {
if (mNonSystemSettings.get(i) == null) {
mNonSystemSettings.set(i, obj);
return Process.FIRST_APPLICATION_UID + i;
}
}
// None left?
if (size > (Process.LAST_APPLICATION_UID - Process.FIRST_APPLICATION_UID)) {
return -1;
}
mNonSystemSettings.add(obj);
return Process.FIRST_APPLICATION_UID + size;
} }
@Override
public AppIdSettingMap snapshot() { public AppIdSettingMap snapshot() {
AppIdSettingMap l = new AppIdSettingMap(); AppIdSettingMap l = new AppIdSettingMap();
snapshot(l, this); mNonSystemSettings.snapshot(l.mNonSystemSettings, mNonSystemSettings);
mSystemSettings.snapshot(l.mSystemSettings, mSystemSettings);
return l; return l;
} }
/** public void registerObserver(Watcher observer) {
* @return the maximum of all the App IDs that have been added to the map. 0 if map is empty. mNonSystemSettings.registerObserver(observer);
*/ mSystemSettings.registerObserver(observer);
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;
}
} }
} }

View File

@@ -62,7 +62,6 @@ import android.os.Handler;
import android.os.Message; import android.os.Message;
import android.os.PatternMatcher; import android.os.PatternMatcher;
import android.os.PersistableBundle; import android.os.PersistableBundle;
import android.os.Process;
import android.os.SELinux; import android.os.SELinux;
import android.os.SystemClock; import android.os.SystemClock;
import android.os.Trace; import android.os.Trace;
@@ -408,8 +407,6 @@ public final class Settings implements Watchable, Snappable {
int[] excludedUserIds; int[] excludedUserIds;
} }
private static int mFirstAvailableUid = Process.FIRST_APPLICATION_UID;
/** Map from volume UUID to {@link VersionInfo} */ /** Map from volume UUID to {@link VersionInfo} */
@Watched @Watched
private final WatchedArrayMap<String, VersionInfo> mVersion = new WatchedArrayMap<>(); private final WatchedArrayMap<String, VersionInfo> mVersion = new WatchedArrayMap<>();
@@ -472,10 +469,8 @@ public final class Settings implements Watchable, Snappable {
@Watched @Watched
final WatchedArrayMap<String, SharedUserSetting> mSharedUsers = new WatchedArrayMap<>(); final WatchedArrayMap<String, SharedUserSetting> mSharedUsers = new WatchedArrayMap<>();
@Watched @Watched(manual = true)
private final AppIdSettingMap mAppIds; private final AppIdSettingMap mAppIds;
@Watched
private final AppIdSettingMap mOtherAppIds;
// For reading/writing settings file. // For reading/writing settings file.
@Watched @Watched
@@ -565,7 +560,6 @@ public final class Settings implements Watchable, Snappable {
mCrossProfileIntentResolvers.registerObserver(mObserver); mCrossProfileIntentResolvers.registerObserver(mObserver);
mSharedUsers.registerObserver(mObserver); mSharedUsers.registerObserver(mObserver);
mAppIds.registerObserver(mObserver); mAppIds.registerObserver(mObserver);
mOtherAppIds.registerObserver(mObserver);
mRenamedPackages.registerObserver(mObserver); mRenamedPackages.registerObserver(mObserver);
mNextAppLinkGeneration.registerObserver(mObserver); mNextAppLinkGeneration.registerObserver(mObserver);
mDefaultBrowserApp.registerObserver(mObserver); mDefaultBrowserApp.registerObserver(mObserver);
@@ -592,7 +586,6 @@ public final class Settings implements Watchable, Snappable {
mLock = new PackageManagerTracedLock(); mLock = new PackageManagerTracedLock();
mPackages.putAll(pkgSettings); mPackages.putAll(pkgSettings);
mAppIds = new AppIdSettingMap(); mAppIds = new AppIdSettingMap();
mOtherAppIds = new AppIdSettingMap();
mSystemDir = null; mSystemDir = null;
mPermissions = null; mPermissions = null;
mRuntimePermissionsPersistence = null; mRuntimePermissionsPersistence = null;
@@ -629,7 +622,6 @@ public final class Settings implements Watchable, Snappable {
mLock = lock; mLock = lock;
mAppIds = new AppIdSettingMap(); mAppIds = new AppIdSettingMap();
mOtherAppIds = new AppIdSettingMap();
mPermissions = new LegacyPermissionSettings(lock); mPermissions = new LegacyPermissionSettings(lock);
mRuntimePermissionsPersistence = new RuntimePermissionPersistence( mRuntimePermissionsPersistence = new RuntimePermissionPersistence(
runtimePermissionsPersistence, new Consumer<Integer>() { runtimePermissionsPersistence, new Consumer<Integer>() {
@@ -710,7 +702,6 @@ public final class Settings implements Watchable, Snappable {
mCrossProfileIntentResolvers, r.mCrossProfileIntentResolvers); mCrossProfileIntentResolvers, r.mCrossProfileIntentResolvers);
mSharedUsers.snapshot(r.mSharedUsers); mSharedUsers.snapshot(r.mSharedUsers);
mAppIds = r.mAppIds.snapshot(); mAppIds = r.mAppIds.snapshot();
mOtherAppIds = r.mOtherAppIds.snapshot();
WatchedArrayList.snapshot( WatchedArrayList.snapshot(
mPastSignatures, r.mPastSignatures); mPastSignatures, r.mPastSignatures);
WatchedArrayMap.snapshot( WatchedArrayMap.snapshot(
@@ -782,7 +773,7 @@ public final class Settings implements Watchable, Snappable {
SharedUserSetting s = mSharedUsers.get(name); SharedUserSetting s = mSharedUsers.get(name);
if (s == null && create) { if (s == null && create) {
s = new SharedUserSetting(name, pkgFlags, pkgPrivateFlags); s = new SharedUserSetting(name, pkgFlags, pkgPrivateFlags);
s.mAppId = acquireAndRegisterNewAppIdLPw(s); s.mAppId = mAppIds.acquireAndRegisterNewAppId(s);
if (s.mAppId < 0) { if (s.mAppId < 0) {
// < 0 means we couldn't assign a userid; throw exception // < 0 means we couldn't assign a userid; throw exception
throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE, throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
@@ -890,7 +881,7 @@ public final class Settings implements Watchable, Snappable {
pkgPrivateFlags, 0 /*userId*/, usesSdkLibraries, usesSdkLibrariesVersions, pkgPrivateFlags, 0 /*userId*/, usesSdkLibraries, usesSdkLibrariesVersions,
usesStaticLibraries, usesStaticLibrariesVersions, mimeGroups, domainSetId); usesStaticLibraries, usesStaticLibrariesVersions, mimeGroups, domainSetId);
p.setAppId(uid); p.setAppId(uid);
if (registerExistingAppIdLPw(uid, p, name)) { if (mAppIds.registerExistingAppId(uid, p, name)) {
mPackages.put(name, p); mPackages.put(name, p);
return p; return p;
} }
@@ -909,7 +900,7 @@ public final class Settings implements Watchable, Snappable {
} }
s = new SharedUserSetting(name, pkgFlags, pkgPrivateFlags); s = new SharedUserSetting(name, pkgFlags, pkgPrivateFlags);
s.mAppId = uid; s.mAppId = uid;
if (registerExistingAppIdLPw(uid, s, name)) { if (mAppIds.registerExistingAppId(uid, s, name)) {
mSharedUsers.put(name, s); mSharedUsers.put(name, s);
return s; return s;
} }
@@ -1210,11 +1201,11 @@ public final class Settings implements Watchable, Snappable {
final boolean createdNew; final boolean createdNew;
if (p.getAppId() == 0 || forceNew) { if (p.getAppId() == 0 || forceNew) {
// Assign new user ID // Assign new user ID
p.setAppId(acquireAndRegisterNewAppIdLPw(p)); p.setAppId(mAppIds.acquireAndRegisterNewAppId(p));
createdNew = true; createdNew = true;
} else { } else {
// Add new setting to list of user IDs // Add new setting to list of user IDs
createdNew = registerExistingAppIdLPw(p.getAppId(), p, p.getPackageName()); createdNew = mAppIds.registerExistingAppId(p.getAppId(), p, p.getPackageName());
} }
if (p.getAppId() < 0) { if (p.getAppId() < 0) {
PackageManagerService.reportSettingsProblem(Log.WARN, PackageManagerService.reportSettingsProblem(Log.WARN,
@@ -1304,11 +1295,11 @@ public final class Settings implements Watchable, Snappable {
Object userIdPs = getSettingLPr(p.getAppId()); Object userIdPs = getSettingLPr(p.getAppId());
if (sharedUser == null) { if (sharedUser == null) {
if (userIdPs != null && userIdPs != p) { if (userIdPs != null && userIdPs != p) {
replaceAppIdLPw(p.getAppId(), p); mAppIds.replaceSetting(p.getAppId(), p);
} }
} else { } else {
if (userIdPs != null && userIdPs != sharedUser) { if (userIdPs != null && userIdPs != sharedUser) {
replaceAppIdLPw(p.getAppId(), sharedUser); mAppIds.replaceSetting(p.getAppId(), sharedUser);
} }
} }
} }
@@ -1357,73 +1348,22 @@ public final class Settings implements Watchable, Snappable {
mInstallerPackages.remove(packageName); mInstallerPackages.remove(packageName);
} }
/** Returns true if the requested AppID was valid and not already registered. */
private boolean registerExistingAppIdLPw(int appId, SettingBase obj, Object name) {
if (appId > Process.LAST_APPLICATION_UID) {
return false;
}
if (appId >= Process.FIRST_APPLICATION_UID) {
if (mAppIds.get(appId) != null) {
PackageManagerService.reportSettingsProblem(Log.WARN,
"Adding duplicate app id: " + appId
+ " name=" + name);
return false;
}
mAppIds.put(appId, obj);
} else {
if (mOtherAppIds.get(appId) != null) {
PackageManagerService.reportSettingsProblem(Log.WARN,
"Adding duplicate shared id: " + appId
+ " name=" + name);
return false;
}
mOtherAppIds.put(appId, obj);
}
return true;
}
/** Gets the setting associated with the provided App ID */ /** Gets the setting associated with the provided App ID */
public SettingBase getSettingLPr(int appId) { public SettingBase getSettingLPr(int appId) {
if (appId >= Process.FIRST_APPLICATION_UID) { return mAppIds.getSetting(appId);
return mAppIds.get(appId);
} else {
return mOtherAppIds.get(appId);
}
} }
/** Unregisters the provided app ID. */ /** Unregisters the provided app ID. */
void removeAppIdLPw(int appId) { void removeAppIdLPw(int appId) {
if (appId >= Process.FIRST_APPLICATION_UID) { mAppIds.removeSetting(appId);
mAppIds.remove(appId);
} else {
mOtherAppIds.remove(appId);
} }
setFirstAvailableUid(appId + 1);
}
private void replaceAppIdLPw(int appId, SettingBase obj) {
if (appId >= Process.FIRST_APPLICATION_UID) {
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);
}
}
/** /**
* Transparently convert a SharedUserSetting into PackageSettings without changing appId. * Transparently convert a SharedUserSetting into PackageSettings without changing appId.
* The sharedUser passed to this method has to be {@link SharedUserSetting#isSingleUser()}. * The sharedUser passed to this method has to be {@link SharedUserSetting#isSingleUser()}.
*/ */
void convertSharedUserSettingsLPw(SharedUserSetting sharedUser) { void convertSharedUserSettingsLPw(SharedUserSetting sharedUser) {
final PackageSetting ps = sharedUser.getPackageSettings().valueAt(0); final PackageSetting ps = sharedUser.getPackageSettings().valueAt(0);
replaceAppIdLPw(sharedUser.getAppId(), ps); mAppIds.replaceSetting(sharedUser.getAppId(), ps);
// Unlink the SharedUserSetting // Unlink the SharedUserSetting
ps.setSharedUserAppId(INVALID_UID); ps.setSharedUserAppId(INVALID_UID);
@@ -4287,32 +4227,6 @@ public final class Settings implements Watchable, Snappable {
} }
} }
// This should be called (at least) whenever an application is removed
private void setFirstAvailableUid(int uid) {
if (uid > mFirstAvailableUid) {
mFirstAvailableUid = uid;
}
}
/** Returns a new AppID or -1 if we could not find an available AppID to assign */
private int acquireAndRegisterNewAppIdLPw(SettingBase obj) {
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 (nextAvailableAppId > Process.LAST_APPLICATION_UID) {
return -1;
}
mAppIds.put(nextAvailableAppId, obj);
return nextAvailableAppId;
}
public VerifierDeviceIdentity getVerifierDeviceIdentityLPw(@NonNull Computer computer) { public VerifierDeviceIdentity getVerifierDeviceIdentityLPw(@NonNull Computer computer) {
if (mVerifierDeviceIdentity == null) { if (mVerifierDeviceIdentity == null) {
mVerifierDeviceIdentity = VerifierDeviceIdentity.generate(); mVerifierDeviceIdentity = VerifierDeviceIdentity.generate();