Merge changes I191b3b99,I40340ddb
* changes: Minor optimisations to InstallSource. Add originatingPackageName to InstallSource.
This commit is contained in:
@@ -119,6 +119,9 @@ message PackageProto {
|
||||
|
||||
// The package that requested the installation of this one.
|
||||
optional string initiating_package_name = 1;
|
||||
|
||||
// The package on behalf of which the initiiating package requested the install.
|
||||
optional string originating_package_name = 2;
|
||||
}
|
||||
|
||||
// Name of package. e.g. "com.android.providers.telephony".
|
||||
|
||||
@@ -18,8 +18,6 @@ package com.android.server.pm;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
|
||||
import com.android.internal.util.IndentingPrintWriter;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
@@ -31,12 +29,24 @@ final class InstallSource {
|
||||
* An instance of InstallSource representing an absence of knowledge of the source of
|
||||
* a package. Used in preference to null.
|
||||
*/
|
||||
static final InstallSource EMPTY = new InstallSource(null, null, false);
|
||||
static final InstallSource EMPTY = new InstallSource(null, null, null, false);
|
||||
|
||||
/** We also memoize this case because it is common - all un-updated system apps. */
|
||||
private static final InstallSource EMPTY_ORPHANED = new InstallSource(null, null, null, true);
|
||||
|
||||
/** The package that requested the installation, if known. */
|
||||
@Nullable
|
||||
final String initiatingPackageName;
|
||||
|
||||
/**
|
||||
* The package on behalf of which the initiating package requested the installation, if any.
|
||||
* For example if a downloaded APK is installed via the Package Installer this could be the
|
||||
* app that performed the download. This value is provided by the initiating package and not
|
||||
* verified by the framework.
|
||||
*/
|
||||
@Nullable
|
||||
final String originatingPackageName;
|
||||
|
||||
/**
|
||||
* Package name of the app that installed this package (the installer of record). Note that
|
||||
* this may be modified.
|
||||
@@ -48,47 +58,55 @@ final class InstallSource {
|
||||
final boolean isOrphaned;
|
||||
|
||||
static InstallSource create(@Nullable String initiatingPackageName,
|
||||
@Nullable String installerPackageName) {
|
||||
return create(initiatingPackageName, installerPackageName, false);
|
||||
}
|
||||
|
||||
static InstallSource create(@Nullable String initiatingPackageName,
|
||||
@Nullable String installerPackageName, boolean isOrphaned) {
|
||||
if (initiatingPackageName == null && installerPackageName == null && !isOrphaned) {
|
||||
return EMPTY;
|
||||
}
|
||||
return new InstallSource(
|
||||
initiatingPackageName == null ? null : initiatingPackageName.intern(),
|
||||
installerPackageName == null ? null : installerPackageName.intern(),
|
||||
@Nullable String originatingPackageName, @Nullable String installerPackageName,
|
||||
boolean isOrphaned) {
|
||||
return createInternal(
|
||||
intern(initiatingPackageName),
|
||||
intern(originatingPackageName),
|
||||
intern(installerPackageName),
|
||||
isOrphaned);
|
||||
}
|
||||
|
||||
private InstallSource(@Nullable String initiatingPackageName,
|
||||
@Nullable String installerPackageName, boolean isOrphaned) {
|
||||
this.initiatingPackageName = initiatingPackageName;
|
||||
this.isOrphaned = isOrphaned;
|
||||
this.installerPackageName = installerPackageName;
|
||||
private static InstallSource createInternal(@Nullable String initiatingPackageName,
|
||||
@Nullable String originatingPackageName, @Nullable String installerPackageName,
|
||||
boolean isOrphaned) {
|
||||
if (initiatingPackageName == null && originatingPackageName == null
|
||||
&& installerPackageName == null) {
|
||||
return isOrphaned ? EMPTY_ORPHANED : EMPTY;
|
||||
}
|
||||
return new InstallSource(initiatingPackageName, originatingPackageName,
|
||||
installerPackageName, isOrphaned);
|
||||
}
|
||||
|
||||
void dump(IndentingPrintWriter pw) {
|
||||
pw.printPair("installerPackageName", installerPackageName);
|
||||
pw.printPair("installInitiatingPackageName", initiatingPackageName);
|
||||
private InstallSource(@Nullable String initiatingPackageName,
|
||||
@Nullable String originatingPackageName, @Nullable String installerPackageName,
|
||||
boolean isOrphaned) {
|
||||
this.initiatingPackageName = initiatingPackageName;
|
||||
this.originatingPackageName = originatingPackageName;
|
||||
this.installerPackageName = installerPackageName;
|
||||
this.isOrphaned = isOrphaned;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an InstallSource the same as this one except with the specified installerPackageName.
|
||||
*/
|
||||
InstallSource setInstallerPackage(String installerPackageName) {
|
||||
return Objects.equals(installerPackageName, this.installerPackageName) ? this
|
||||
: create(initiatingPackageName, installerPackageName, isOrphaned);
|
||||
if (Objects.equals(installerPackageName, this.installerPackageName)) {
|
||||
return this;
|
||||
}
|
||||
return createInternal(initiatingPackageName, originatingPackageName,
|
||||
intern(installerPackageName), isOrphaned);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an InstallSource the same as this one except with the specified value for isOrphaned.
|
||||
*/
|
||||
InstallSource setIsOrphaned(boolean isOrphaned) {
|
||||
return isOrphaned == this.isOrphaned ? this
|
||||
: create(initiatingPackageName, installerPackageName, isOrphaned);
|
||||
if (isOrphaned == this.isOrphaned) {
|
||||
return this;
|
||||
}
|
||||
return createInternal(initiatingPackageName, originatingPackageName, installerPackageName,
|
||||
isOrphaned);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -102,6 +120,7 @@ final class InstallSource {
|
||||
|
||||
boolean modified = false;
|
||||
String initiatingPackageName = this.initiatingPackageName;
|
||||
String originatingPackageName = this.originatingPackageName;
|
||||
String installerPackageName = this.installerPackageName;
|
||||
boolean isOrphaned = this.isOrphaned;
|
||||
|
||||
@@ -109,14 +128,25 @@ final class InstallSource {
|
||||
initiatingPackageName = null;
|
||||
modified = true;
|
||||
}
|
||||
if (packageName.equals(originatingPackageName)) {
|
||||
originatingPackageName = null;
|
||||
modified = true;
|
||||
}
|
||||
if (packageName.equals(installerPackageName)) {
|
||||
installerPackageName = null;
|
||||
isOrphaned = true;
|
||||
modified = true;
|
||||
}
|
||||
|
||||
return modified
|
||||
? create(initiatingPackageName, installerPackageName, isOrphaned)
|
||||
: this;
|
||||
if (!modified) {
|
||||
return this;
|
||||
}
|
||||
return createInternal(initiatingPackageName, originatingPackageName, installerPackageName,
|
||||
isOrphaned);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String intern(@Nullable String packageName) {
|
||||
return packageName == null ? null : packageName.intern();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -512,6 +512,16 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
|
||||
}
|
||||
}
|
||||
|
||||
String originatingPackageName = null;
|
||||
if (params.originatingUid != SessionParams.UID_UNKNOWN
|
||||
&& params.originatingUid != callingUid) {
|
||||
String[] packages = mPm.getPackagesForUid(params.originatingUid);
|
||||
if (packages != null && packages.length > 0) {
|
||||
// Choose an arbitrary representative package in the case of a shared UID.
|
||||
originatingPackageName = packages[0];
|
||||
}
|
||||
}
|
||||
|
||||
if (Build.IS_DEBUGGABLE || isDowngradeAllowedForCaller(callingUid)) {
|
||||
params.installFlags |= PackageManager.INSTALL_ALLOW_DOWNGRADE;
|
||||
} else {
|
||||
@@ -624,7 +634,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
|
||||
}
|
||||
}
|
||||
InstallSource installSource = InstallSource.create(installerPackageName,
|
||||
requestedInstallerPackageName);
|
||||
originatingPackageName, requestedInstallerPackageName, false);
|
||||
session = new PackageInstallerSession(mInternalCallback, mContext, mPm, this,
|
||||
mInstallThread.getLooper(), mStagingManager, sessionId, userId, callingUid,
|
||||
installSource, params, createdMillis,
|
||||
|
||||
@@ -148,6 +148,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
private static final String ATTR_INSTALLER_UID = "installerUid";
|
||||
private static final String ATTR_INITIATING_PACKAGE_NAME =
|
||||
"installInitiatingPackageName";
|
||||
private static final String ATTR_ORIGINATING_PACKAGE_NAME =
|
||||
"installOriginatingPackageName";
|
||||
private static final String ATTR_CREATED_MILLIS = "createdMillis";
|
||||
private static final String ATTR_UPDATED_MILLIS = "updatedMillis";
|
||||
private static final String ATTR_SESSION_STAGE_DIR = "sessionStageDir";
|
||||
@@ -1227,7 +1229,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
}
|
||||
|
||||
mInstallerUid = newOwnerAppInfo.uid;
|
||||
mInstallSource = InstallSource.create(packageName, packageName);
|
||||
mInstallSource = InstallSource.create(packageName, null, packageName, false);
|
||||
}
|
||||
|
||||
// Persist the fact that we've sealed ourselves to prevent
|
||||
@@ -2336,7 +2338,9 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
|
||||
pw.printPair("userId", userId);
|
||||
pw.printPair("mOriginalInstallerUid", mOriginalInstallerUid);
|
||||
mInstallSource.dump(pw);
|
||||
pw.printPair("installerPackageName", mInstallSource.installerPackageName);
|
||||
pw.printPair("installInitiatingPackageName", mInstallSource.initiatingPackageName);
|
||||
pw.printPair("installOriginatingPackageName", mInstallSource.originatingPackageName);
|
||||
pw.printPair("mInstallerUid", mInstallerUid);
|
||||
pw.printPair("createdMillis", createdMillis);
|
||||
pw.printPair("updatedMillis", updatedMillis);
|
||||
@@ -2420,6 +2424,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
writeIntAttribute(out, ATTR_INSTALLER_UID, mInstallerUid);
|
||||
writeStringAttribute(out, ATTR_INITIATING_PACKAGE_NAME,
|
||||
mInstallSource.initiatingPackageName);
|
||||
writeStringAttribute(out, ATTR_ORIGINATING_PACKAGE_NAME,
|
||||
mInstallSource.originatingPackageName);
|
||||
writeLongAttribute(out, ATTR_CREATED_MILLIS, createdMillis);
|
||||
writeLongAttribute(out, ATTR_UPDATED_MILLIS, updatedMillis);
|
||||
if (stageDir != null) {
|
||||
@@ -2527,6 +2533,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
installerPackageName, PackageManager.MATCH_UNINSTALLED_PACKAGES, userId));
|
||||
final String installInitiatingPackageName =
|
||||
readStringAttribute(in, ATTR_INITIATING_PACKAGE_NAME);
|
||||
final String installOriginatingPackageName =
|
||||
readStringAttribute(in, ATTR_ORIGINATING_PACKAGE_NAME);
|
||||
final long createdMillis = readLongAttribute(in, ATTR_CREATED_MILLIS);
|
||||
long updatedMillis = readLongAttribute(in, ATTR_UPDATED_MILLIS);
|
||||
final String stageDirRaw = readStringAttribute(in, ATTR_SESSION_STAGE_DIR);
|
||||
@@ -2619,7 +2627,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
}
|
||||
|
||||
InstallSource installSource = InstallSource.create(installInitiatingPackageName,
|
||||
installerPackageName);
|
||||
installOriginatingPackageName, installerPackageName, false);
|
||||
return new PackageInstallerSession(callback, context, pm, sessionProvider,
|
||||
installerThread, stagingManager, sessionId, userId, installerUid,
|
||||
installSource, params, createdMillis, stageDir, stageCid,
|
||||
|
||||
@@ -209,6 +209,8 @@ public final class PackageSetting extends PackageSettingBase {
|
||||
long sourceToken = proto.start(PackageProto.INSTALL_SOURCE);
|
||||
proto.write(PackageProto.InstallSourceProto.INITIATING_PACKAGE_NAME,
|
||||
installSource.initiatingPackageName);
|
||||
proto.write(PackageProto.InstallSourceProto.ORIGINATING_PACKAGE_NAME,
|
||||
installSource.originatingPackageName);
|
||||
proto.end(sourceToken);
|
||||
}
|
||||
writeUsersInfoToProto(proto, PackageProto.USERS);
|
||||
|
||||
@@ -2848,6 +2848,9 @@ public final class Settings {
|
||||
if (installSource.initiatingPackageName != null) {
|
||||
serializer.attribute(null, "installInitiator", installSource.initiatingPackageName);
|
||||
}
|
||||
if (installSource.originatingPackageName != null) {
|
||||
serializer.attribute(null, "installOriginator", installSource.originatingPackageName);
|
||||
}
|
||||
if (pkg.volumeUuid != null) {
|
||||
serializer.attribute(null, "volumeUuid", pkg.volumeUuid);
|
||||
}
|
||||
@@ -3605,6 +3608,7 @@ public final class Settings {
|
||||
String systemStr = null;
|
||||
String installerPackageName = null;
|
||||
String isOrphaned = null;
|
||||
String installOriginatingPackageName = null;
|
||||
String installInitiatingPackageName = null;
|
||||
String volumeUuid = null;
|
||||
String categoryHintString = null;
|
||||
@@ -3653,6 +3657,7 @@ public final class Settings {
|
||||
installerPackageName = parser.getAttributeValue(null, "installer");
|
||||
isOrphaned = parser.getAttributeValue(null, "isOrphaned");
|
||||
installInitiatingPackageName = parser.getAttributeValue(null, "installInitiator");
|
||||
installOriginatingPackageName = parser.getAttributeValue(null, "installOriginator");
|
||||
volumeUuid = parser.getAttributeValue(null, "volumeUuid");
|
||||
categoryHintString = parser.getAttributeValue(null, "categoryHint");
|
||||
if (categoryHintString != null) {
|
||||
@@ -3808,7 +3813,8 @@ public final class Settings {
|
||||
if (packageSetting != null) {
|
||||
packageSetting.uidError = "true".equals(uidError);
|
||||
packageSetting.installSource = InstallSource.create(
|
||||
installInitiatingPackageName, installerPackageName, "true".equals(isOrphaned));
|
||||
installInitiatingPackageName, installOriginatingPackageName,
|
||||
installerPackageName, "true".equals(isOrphaned));
|
||||
packageSetting.volumeUuid = volumeUuid;
|
||||
packageSetting.categoryHint = categoryHint;
|
||||
packageSetting.legacyNativeLibraryPathString = legacyNativeLibraryPathStr;
|
||||
|
||||
@@ -156,6 +156,8 @@ public class PackageInstallerSessionTest {
|
||||
if (isMultiPackage) {
|
||||
params.isMultiPackage = true;
|
||||
}
|
||||
InstallSource installSource = InstallSource.create("testInstaller", null, "testInstaller",
|
||||
false);
|
||||
return new PackageInstallerSession(
|
||||
/* callback */ null,
|
||||
/* context */null,
|
||||
@@ -166,7 +168,7 @@ public class PackageInstallerSessionTest {
|
||||
/* sessionId */ sessionId,
|
||||
/* userId */ 456,
|
||||
/* installerUid */ -1,
|
||||
/* installSource */ InstallSource.create("testInstaller", "testInstaller"),
|
||||
/* installSource */ installSource,
|
||||
/* sessionParams */ params,
|
||||
/* createdMillis */ 0L,
|
||||
/* stageDir */ mTmpDir,
|
||||
|
||||
Reference in New Issue
Block a user