Merge "Break install up into phases"

This commit is contained in:
TreeHugger Robot
2018-09-17 15:14:10 +00:00
committed by Android (Google) Code Review
7 changed files with 1131 additions and 817 deletions

View File

@@ -1048,11 +1048,14 @@ public class ComponentResolver {
final String otherPackageName =
(other != null && other.getComponentName() != null)
? other.getComponentName().getPackageName() : "?";
throw new PackageManagerException(
INSTALL_FAILED_CONFLICTING_PROVIDER,
"Can't install because provider name " + names[j]
+ " (in package " + pkg.applicationInfo.packageName
+ ") is already used by " + otherPackageName);
// if we're installing over the same already-installed package, this is ok
if (otherPackageName != pkg.packageName) {
throw new PackageManagerException(
INSTALL_FAILED_CONFLICTING_PROVIDER,
"Can't install because provider name " + names[j]
+ " (in package " + pkg.applicationInfo.packageName
+ ") is already used by " + otherPackageName);
}
}
}
}

View File

@@ -207,4 +207,13 @@ public final class PackageSetting extends PackageSettingBase {
writeUsersInfoToProto(proto, PackageProto.USERS);
proto.end(packageToken);
}
/** Updates all fields in the current setting from another. */
public void updateFrom(PackageSetting other) {
super.updateFrom(other);
appId = other.appId;
pkg = other.pkg;
sharedUserId = other.sharedUserId;
sharedUser = other.sharedUser;
}
}

View File

@@ -26,7 +26,6 @@ import android.content.pm.PackageManager;
import android.content.pm.PackageParser;
import android.content.pm.PackageUserState;
import android.content.pm.Signature;
import android.os.BaseBundle;
import android.os.PersistableBundle;
import android.service.pm.PackageProto;
import android.util.ArraySet;
@@ -109,7 +108,7 @@ public abstract class PackageSettingBase extends SettingBase {
// Whether this package is currently stopped, thus can not be
// started until explicitly launched by the user.
private final SparseArray<PackageUserState> userState = new SparseArray<PackageUserState>();
private final SparseArray<PackageUserState> mUserState = new SparseArray<>();
/**
* Non-persisted value. During an "upgrade without restart", we need the set
@@ -118,7 +117,7 @@ public abstract class PackageSettingBase extends SettingBase {
* restart, this field will be cleared since the classloader would be created
* using the full set of code paths when the package's process is started.
*/
Set<String> oldCodePaths;
Set<String> mOldCodePaths;
/** Package name of the app that installed this package */
String installerPackageName;
@@ -223,7 +222,7 @@ public abstract class PackageSettingBase extends SettingBase {
/**
* Makes a shallow copy of the given package settings.
*
* NOTE: For some fields [such as keySetData, signatures, userState, verificationInfo, etc...],
* NOTE: For some fields [such as keySetData, signatures, mUserState, verificationInfo, etc...],
* the original object is copied and a new one is not created.
*/
public void copyFrom(PackageSettingBase orig) {
@@ -244,7 +243,7 @@ public abstract class PackageSettingBase extends SettingBase {
keySetData = orig.keySetData;
lastUpdateTime = orig.lastUpdateTime;
legacyNativeLibraryPathString = orig.legacyNativeLibraryPathString;
// Intentionally skip oldCodePaths; it's not relevant for copies
// Intentionally skip mOldCodePaths; it's not relevant for copies
parentPackageName = orig.parentPackageName;
primaryCpuAbiString = orig.primaryCpuAbiString;
resourcePath = orig.resourcePath;
@@ -253,9 +252,9 @@ public abstract class PackageSettingBase extends SettingBase {
signatures = orig.signatures;
timeStamp = orig.timeStamp;
uidError = orig.uidError;
userState.clear();
for (int i=0; i<orig.userState.size(); i++) {
userState.put(orig.userState.keyAt(i), orig.userState.valueAt(i));
mUserState.clear();
for (int i = 0; i < orig.mUserState.size(); i++) {
mUserState.put(orig.mUserState.keyAt(i), orig.mUserState.valueAt(i));
}
verificationInfo = orig.verificationInfo;
versionCode = orig.versionCode;
@@ -271,16 +270,16 @@ public abstract class PackageSettingBase extends SettingBase {
}
private PackageUserState modifyUserState(int userId) {
PackageUserState state = userState.get(userId);
PackageUserState state = mUserState.get(userId);
if (state == null) {
state = new PackageUserState();
userState.put(userId, state);
mUserState.put(userId, state);
}
return state;
}
public PackageUserState readUserState(int userId) {
PackageUserState state = userState.get(userId);
PackageUserState state = mUserState.get(userId);
if (state == null) {
return DEFAULT_USER_STATE;
}
@@ -330,7 +329,7 @@ public abstract class PackageSettingBase extends SettingBase {
/** Only use for testing. Do NOT use in production code. */
@VisibleForTesting
SparseArray<PackageUserState> getUserState() {
return userState;
return mUserState;
}
boolean isAnyInstalled(int[] users) {
@@ -536,14 +535,14 @@ public abstract class PackageSettingBase extends SettingBase {
}
void removeUser(int userId) {
userState.delete(userId);
mUserState.delete(userId);
}
public int[] getNotInstalledUserIds() {
int count = 0;
int userStateCount = userState.size();
int userStateCount = mUserState.size();
for (int i = 0; i < userStateCount; i++) {
if (userState.valueAt(i).installed == false) {
if (!mUserState.valueAt(i).installed) {
count++;
}
}
@@ -551,8 +550,8 @@ public abstract class PackageSettingBase extends SettingBase {
int[] excludedUserIds = new int[count];
int idx = 0;
for (int i = 0; i < userStateCount; i++) {
if (userState.valueAt(i).installed == false) {
excludedUserIds[idx++] = userState.keyAt(i);
if (!mUserState.valueAt(i).installed) {
excludedUserIds[idx++] = mUserState.keyAt(i);
}
}
return excludedUserIds;
@@ -591,11 +590,11 @@ public abstract class PackageSettingBase extends SettingBase {
}
protected void writeUsersInfoToProto(ProtoOutputStream proto, long fieldId) {
int count = userState.size();
int count = mUserState.size();
for (int i = 0; i < count; i++) {
final long userToken = proto.start(fieldId);
final int userId = userState.keyAt(i);
final PackageUserState state = userState.valueAt(i);
final int userId = mUserState.keyAt(i);
final PackageUserState state = mUserState.valueAt(i);
proto.write(PackageProto.UserInfoProto.ID, userId);
final int installType;
if (state.instantApp) {
@@ -630,4 +629,48 @@ public abstract class PackageSettingBase extends SettingBase {
PackageUserState userState = readUserState(userId);
return userState.harmfulAppWarning;
}
protected PackageSettingBase updateFrom(PackageSettingBase other) {
super.copyFrom(other);
this.parentPackageName = other.parentPackageName;
this.childPackageNames = other.childPackageNames;
this.codePath = other.codePath;
this.codePathString = other.codePathString;
this.resourcePath = other.resourcePath;
this.resourcePathString = other.resourcePathString;
this.usesStaticLibraries = other.usesStaticLibraries;
this.usesStaticLibrariesVersions = other.usesStaticLibrariesVersions;
this.legacyNativeLibraryPathString = other.legacyNativeLibraryPathString;
this.primaryCpuAbiString = other.primaryCpuAbiString;
this.secondaryCpuAbiString = other.secondaryCpuAbiString;
this.cpuAbiOverrideString = other.cpuAbiOverrideString;
this.timeStamp = other.timeStamp;
this.firstInstallTime = other.firstInstallTime;
this.lastUpdateTime = other.lastUpdateTime;
this.versionCode = other.versionCode;
this.uidError = other.uidError;
this.signatures = other.signatures;
this.installPermissionsFixed = other.installPermissionsFixed;
this.keySetData = other.keySetData;
this.installerPackageName = other.installerPackageName;
this.isOrphaned = other.isOrphaned;
this.volumeUuid = other.volumeUuid;
this.categoryHint = other.categoryHint;
this.updateAvailable = other.updateAvailable;
this.verificationInfo = other.verificationInfo;
if (mOldCodePaths != null) {
if (other.mOldCodePaths != null) {
mOldCodePaths.clear();
mOldCodePaths.addAll(other.mOldCodePaths);
} else {
mOldCodePaths = null;
}
}
mUserState.clear();
for (int i = 0; i < other.mUserState.size(); i++) {
mUserState.put(other.mUserState.keyAt(i), other.mUserState.valueAt(i));
}
return this;
}
}

View File

@@ -539,16 +539,18 @@ public final class Settings {
if((p.pkg != null) && (p.pkg.applicationInfo != null)) {
p.pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
}
mDisabledSysPackages.put(name, p);
final PackageSetting disabled;
if (replaced) {
// a little trick... when we install the new package, we don't
// want to modify the existing PackageSetting for the built-in
// version. so at this point we need a new PackageSetting that
// is okay to muck with.
PackageSetting newp = new PackageSetting(p);
replacePackageLPw(name, newp);
// version. so at this point we make a copy to place into the
// disabled set.
disabled = new PackageSetting(p);
} else {
disabled = p;
}
mDisabledSysPackages.put(name, disabled);
return true;
}
return false;
@@ -1105,19 +1107,6 @@ public final class Settings {
mInstallerPackages.remove(packageName);
}
private void replacePackageLPw(String name, PackageSetting newp) {
final PackageSetting p = mPackages.get(name);
if (p != null) {
if (p.sharedUser != null) {
p.sharedUser.removePackage(p);
p.sharedUser.addPackage(newp);
} else {
replaceUserIdLPw(p.appId, newp);
}
}
mPackages.put(name, newp);
}
private boolean addUserIdLPw(int uid, Object obj, Object name) {
if (uid > Process.LAST_APPLICATION_UID) {
return false;

View File

@@ -24,7 +24,6 @@ import android.util.ArraySet;
import android.util.proto.ProtoOutputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
@@ -69,24 +68,26 @@ public final class SharedUserSetting extends SettingBase {
proto.end(token);
}
void removePackage(PackageSetting packageSetting) {
if (packages.remove(packageSetting)) {
// recalculate the pkgFlags for this shared user if needed
if ((this.pkgFlags & packageSetting.pkgFlags) != 0) {
int aggregatedFlags = uidFlags;
for (PackageSetting ps : packages) {
aggregatedFlags |= ps.pkgFlags;
}
setFlags(aggregatedFlags);
}
if ((this.pkgPrivateFlags & packageSetting.pkgPrivateFlags) != 0) {
int aggregatedPrivateFlags = uidPrivateFlags;
for (PackageSetting ps : packages) {
aggregatedPrivateFlags |= ps.pkgPrivateFlags;
}
setPrivateFlags(aggregatedPrivateFlags);
}
boolean removePackage(PackageSetting packageSetting) {
if (!packages.remove(packageSetting)) {
return false;
}
// recalculate the pkgFlags for this shared user if needed
if ((this.pkgFlags & packageSetting.pkgFlags) != 0) {
int aggregatedFlags = uidFlags;
for (PackageSetting ps : packages) {
aggregatedFlags |= ps.pkgFlags;
}
setFlags(aggregatedFlags);
}
if ((this.pkgPrivateFlags & packageSetting.pkgPrivateFlags) != 0) {
int aggregatedPrivateFlags = uidPrivateFlags;
for (PackageSetting ps : packages) {
aggregatedPrivateFlags |= ps.pkgPrivateFlags;
}
setPrivateFlags(aggregatedPrivateFlags);
}
return true;
}
void addPackage(PackageSetting packageSetting) {
@@ -143,4 +144,16 @@ public final class SharedUserSetting extends SettingBase {
}
}
/** Updates all fields in this shared user setting from another. */
public SharedUserSetting updateFrom(SharedUserSetting sharedUser) {
copyFrom(sharedUser);
this.userId = sharedUser.userId;
this.uidFlags = sharedUser.uidFlags;
this.uidPrivateFlags = sharedUser.uidPrivateFlags;
this.seInfoTargetSdkVersion = sharedUser.seInfoTargetSdkVersion;
this.packages.clear();
this.packages.addAll(sharedUser.packages);
this.signaturesChanged = sharedUser.signaturesChanged;
return this;
}
}

View File

@@ -716,9 +716,9 @@ public class PackageManagerSettingsTests {
assertNotSame(origPkgSetting.mPermissionsState, testPkgSetting.mPermissionsState);
assertThat(origPkgSetting.mPermissionsState, is(testPkgSetting.mPermissionsState));
assertThat(origPkgSetting.name, is(testPkgSetting.name));
// oldCodePaths is _not_ copied
// assertNotSame(origPkgSetting.oldCodePaths, testPkgSetting.oldCodePaths);
// assertThat(origPkgSetting.oldCodePaths, is(not(testPkgSetting.oldCodePaths)));
// mOldCodePaths is _not_ copied
// assertNotSame(origPkgSetting.mOldCodePaths, testPkgSetting.mOldCodePaths);
// assertThat(origPkgSetting.mOldCodePaths, is(not(testPkgSetting.mOldCodePaths)));
assertSame(origPkgSetting.parentPackageName, testPkgSetting.parentPackageName);
assertThat(origPkgSetting.parentPackageName, is(testPkgSetting.parentPackageName));
assertSame(origPkgSetting.pkg, testPkgSetting.pkg);