Add a one-off shell command to disable verification
The package verification is provided by Play whose behavior is not controlled by framework. For CTS, such verification is unnecessary because we have dedicated GTS for that. We add a shell command to disable verification when installing packages in CTS to avoid unexpected behavior caused by external entities to improve stableness of tests. There is no reduction in safety: 1. This feature is only available to apps with shell permissions. Such apps can already skip verification by changing a settings value. 2. The command works in a one-off manner. This command will only allow the next created session to bypass verification. This command requires a uid which prevents accidentally granting the ability to other apps. Bug: 264963480 Test: atest CtsStagedInstallHostTestCases Change-Id: I26e60837139007e98e99f44aeb0eb13716d91523
This commit is contained in:
@@ -65,6 +65,8 @@ interface IPackageInstaller {
|
||||
|
||||
void bypassNextAllowedApexUpdateCheck(boolean value);
|
||||
|
||||
void disableVerificationForUid(int uid);
|
||||
|
||||
void setAllowUnlimitedSilentUpdates(String installerPackageName);
|
||||
void setSilentUpdatesThrottleTime(long throttleTimeInSeconds);
|
||||
void checkInstallConstraints(String installerPackageName, in List<String> packageNames,
|
||||
|
||||
@@ -184,6 +184,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
|
||||
private volatile boolean mOkToSendBroadcasts = false;
|
||||
private volatile boolean mBypassNextStagedInstallerCheck = false;
|
||||
private volatile boolean mBypassNextAllowedApexUpdateCheck = false;
|
||||
private volatile int mDisableVerificationForUid = INVALID_UID;
|
||||
|
||||
/**
|
||||
* File storing persisted {@link #mSessions} metadata.
|
||||
@@ -712,7 +713,16 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
|
||||
params.installFlags &= ~PackageManager.INSTALL_REQUEST_DOWNGRADE;
|
||||
}
|
||||
|
||||
if ((params.installFlags & ADB_DEV_MODE) != ADB_DEV_MODE) {
|
||||
if (mDisableVerificationForUid != INVALID_UID) {
|
||||
if (callingUid == mDisableVerificationForUid) {
|
||||
params.installFlags |= PackageManager.INSTALL_DISABLE_VERIFICATION;
|
||||
} else {
|
||||
// Clear the flag if current calling uid doesn't match the requested uid.
|
||||
params.installFlags &= ~PackageManager.INSTALL_DISABLE_VERIFICATION;
|
||||
}
|
||||
// Reset the field as this is a one-off request.
|
||||
mDisableVerificationForUid = INVALID_UID;
|
||||
} else if ((params.installFlags & ADB_DEV_MODE) != ADB_DEV_MODE) {
|
||||
// Only tools under specific conditions (test app installed through ADB, and
|
||||
// verification disabled flag specified) can disable verification.
|
||||
params.installFlags &= ~PackageManager.INSTALL_DISABLE_VERIFICATION;
|
||||
@@ -1367,6 +1377,14 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
|
||||
mBypassNextAllowedApexUpdateCheck = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disableVerificationForUid(int uid) {
|
||||
if (!isCalledBySystemOrShell(Binder.getCallingUid())) {
|
||||
throw new SecurityException("Operation not allowed for caller");
|
||||
}
|
||||
mDisableVerificationForUid = uid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an installer to allow for the unlimited silent updates.
|
||||
*/
|
||||
|
||||
@@ -342,6 +342,8 @@ class PackageManagerShellCommand extends ShellCommand {
|
||||
return runBypassStagedInstallerCheck();
|
||||
case "bypass-allowed-apex-update-check":
|
||||
return runBypassAllowedApexUpdateCheck();
|
||||
case "disable-verification-for-uid":
|
||||
return runDisableVerificationForUid();
|
||||
case "set-silent-updates-policy":
|
||||
return runSetSilentUpdatesPolicy();
|
||||
default: {
|
||||
@@ -514,6 +516,29 @@ class PackageManagerShellCommand extends ShellCommand {
|
||||
}
|
||||
}
|
||||
|
||||
private int runDisableVerificationForUid() {
|
||||
final PrintWriter pw = getOutPrintWriter();
|
||||
try {
|
||||
int uid = Integer.parseInt(getNextArgRequired());
|
||||
var amInternal = LocalServices.getService(ActivityManagerInternal.class);
|
||||
boolean isInstrumented =
|
||||
amInternal.getInstrumentationSourceUid(uid) != Process.INVALID_UID;
|
||||
if (isInstrumented) {
|
||||
mInterface.getPackageInstaller().disableVerificationForUid(uid);
|
||||
return 0;
|
||||
} else {
|
||||
// Only available for testing
|
||||
pw.println("Error: must specify an instrumented uid");
|
||||
return -1;
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
pw.println("Failure ["
|
||||
+ e.getClass().getName() + " - "
|
||||
+ e.getMessage() + "]");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
private int uninstallSystemUpdates(String packageName) {
|
||||
final PrintWriter pw = getOutPrintWriter();
|
||||
boolean failedUninstalls = false;
|
||||
|
||||
@@ -680,12 +680,15 @@ final class VerifyingSession {
|
||||
}
|
||||
|
||||
final int installerUid = mVerificationInfo == null ? -1 : mVerificationInfo.mInstallerUid;
|
||||
final boolean requestedDisableVerification =
|
||||
(mInstallFlags & PackageManager.INSTALL_DISABLE_VERIFICATION) != 0;
|
||||
|
||||
// Check if installing from ADB
|
||||
if ((mInstallFlags & PackageManager.INSTALL_FROM_ADB) != 0) {
|
||||
boolean requestedDisableVerification =
|
||||
(mInstallFlags & PackageManager.INSTALL_DISABLE_VERIFICATION) != 0;
|
||||
return isAdbVerificationEnabled(pkgInfoLite, userId, requestedDisableVerification);
|
||||
} else if (requestedDisableVerification) {
|
||||
// Skip verification for non-adb installs
|
||||
return false;
|
||||
}
|
||||
|
||||
// only when not installed from ADB, skip verification for instant apps when
|
||||
|
||||
Reference in New Issue
Block a user