Merge "Break install up into phases"
This commit is contained in:
committed by
Android (Google) Code Review
commit
6c109c76c9
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user