summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/proto/android/service/package.proto3
-rw-r--r--services/core/java/com/android/server/pm/InstallSource.java62
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerService.java12
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerSession.java14
-rw-r--r--services/core/java/com/android/server/pm/PackageSetting.java2
-rw-r--r--services/core/java/com/android/server/pm/Settings.java8
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/PackageInstallerSessionTest.java4
7 files changed, 76 insertions, 29 deletions
diff --git a/core/proto/android/service/package.proto b/core/proto/android/service/package.proto
index d010c8ff8ad9..004b096496db 100644
--- a/core/proto/android/service/package.proto
+++ b/core/proto/android/service/package.proto
@@ -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".
diff --git a/services/core/java/com/android/server/pm/InstallSource.java b/services/core/java/com/android/server/pm/InstallSource.java
index 990eba15234e..c7b502636d77 100644
--- a/services/core/java/com/android/server/pm/InstallSource.java
+++ b/services/core/java/com/android/server/pm/InstallSource.java
@@ -18,8 +18,6 @@ package com.android.server.pm;
import android.annotation.Nullable;
-import com.android.internal.util.IndentingPrintWriter;
-
import java.util.Objects;
/**
@@ -31,13 +29,22 @@ 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);
/** 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 +55,49 @@ final class InstallSource {
final boolean isOrphaned;
static InstallSource create(@Nullable String initiatingPackageName,
- @Nullable String installerPackageName) {
- return create(initiatingPackageName, installerPackageName, false);
- }
+ @Nullable String originatingPackageName, @Nullable String installerPackageName,
+ boolean isOrphaned) {
- static InstallSource create(@Nullable String initiatingPackageName,
- @Nullable String installerPackageName, boolean isOrphaned) {
- if (initiatingPackageName == null && installerPackageName == null && !isOrphaned) {
+ if (initiatingPackageName == null && originatingPackageName == null
+ && installerPackageName == null && !isOrphaned) {
return EMPTY;
}
return new InstallSource(
initiatingPackageName == null ? null : initiatingPackageName.intern(),
+ originatingPackageName == null ? null : originatingPackageName.intern(),
installerPackageName == null ? null : installerPackageName.intern(),
isOrphaned);
}
private InstallSource(@Nullable String initiatingPackageName,
- @Nullable String installerPackageName, boolean isOrphaned) {
+ @Nullable String originatingPackageName, @Nullable String installerPackageName,
+ boolean isOrphaned) {
this.initiatingPackageName = initiatingPackageName;
- this.isOrphaned = isOrphaned;
+ this.originatingPackageName = originatingPackageName;
this.installerPackageName = installerPackageName;
- }
-
- void dump(IndentingPrintWriter pw) {
- pw.printPair("installerPackageName", installerPackageName);
- pw.printPair("installInitiatingPackageName", initiatingPackageName);
+ 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 create(initiatingPackageName, originatingPackageName, 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 create(initiatingPackageName, originatingPackageName, installerPackageName,
+ isOrphaned);
}
/**
@@ -102,6 +111,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 +119,20 @@ 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 create(initiatingPackageName, originatingPackageName, installerPackageName,
+ isOrphaned);
}
}
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index ed2bb3d53649..6564e71936eb 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -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,
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index feb1271d8c79..631df0ff9845 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -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,
diff --git a/services/core/java/com/android/server/pm/PackageSetting.java b/services/core/java/com/android/server/pm/PackageSetting.java
index 4fca91a83724..12548918bfcc 100644
--- a/services/core/java/com/android/server/pm/PackageSetting.java
+++ b/services/core/java/com/android/server/pm/PackageSetting.java
@@ -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);
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 66c77f583c57..5f3650c21b8e 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -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;
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageInstallerSessionTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageInstallerSessionTest.java
index 3c1044728fcc..b751308a4bb4 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageInstallerSessionTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageInstallerSessionTest.java
@@ -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,