From ab61f0cbdb627aae78b4802b61d4d5007733077f Mon Sep 17 00:00:00 2001 From: Rhed Jao Date: Wed, 9 Jun 2021 12:38:38 +0800 Subject: [PATCH] Add support to update the throttle time of silent updates To improve the performance of SilentUpdateHostsideTests in the Cts, this cl adds support to update the throttle time of silent updates using the pm command. The `pm set-silent-updates-policy --throttle-time TIME` could be invoked to shorten the testing waiting time for the repeated silent updates. Bug: 189506896 Test: atest SilentUpdateHostsideTests Change-Id: I2f9ab58d16b7f1173f1ee45b6b842ad1f18136a4 --- .../android/content/pm/IPackageInstaller.aidl | 1 + .../server/pm/PackageInstallerService.java | 11 +++++ .../server/pm/PackageManagerShellCommand.java | 45 ++++++++++++++----- .../android/server/pm/SilentUpdatePolicy.java | 28 ++++++++++-- 4 files changed, 72 insertions(+), 13 deletions(-) diff --git a/core/java/android/content/pm/IPackageInstaller.aidl b/core/java/android/content/pm/IPackageInstaller.aidl index 32fc74f60d155..b0ce6a55e9ba0 100644 --- a/core/java/android/content/pm/IPackageInstaller.aidl +++ b/core/java/android/content/pm/IPackageInstaller.aidl @@ -63,4 +63,5 @@ interface IPackageInstaller { void bypassNextStagedInstallerCheck(boolean value); void setAllowUnlimitedSilentUpdates(String installerPackageName); + void setSilentUpdatesThrottleTime(long throttleTimeInSeconds); } diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java index 1f0a8caa0ccfa..85e3bb4e33f82 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerService.java +++ b/services/core/java/com/android/server/pm/PackageInstallerService.java @@ -1103,6 +1103,17 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements mSilentUpdatePolicy.setAllowUnlimitedSilentUpdates(installerPackageName); } + /** + * Set the silent updates throttle time in seconds. + */ + @Override + public void setSilentUpdatesThrottleTime(long throttleTimeInSeconds) { + if (!isCalledBySystemOrShell(Binder.getCallingUid())) { + throw new SecurityException("Caller not allowed to set silent updates throttle time"); + } + mSilentUpdatePolicy.setSilentUpdatesThrottleTime(throttleTimeInSeconds); + } + private static int getSessionCount(SparseArray sessions, int installerUid) { int count = 0; diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java index 4ebf4768a9731..f1a412b54124f 100644 --- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java +++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java @@ -307,8 +307,8 @@ class PackageManagerShellCommand extends ShellCommand { return runLogVisibility(); case "bypass-staged-installer-check": return runBypassStagedInstallerCheck(); - case "allow-unlimited-silent-updates": - return runAllowUnlimitedSilentUpdates(); + case "set-silent-updates-policy": + return runSetSilentUpdatesPolicy(); default: { Boolean domainVerificationResult = mDomainVerificationShell.runCommand(this, cmd); @@ -3041,12 +3041,20 @@ class PackageManagerShellCommand extends ShellCommand { } } - private int runAllowUnlimitedSilentUpdates() { + private int runSetSilentUpdatesPolicy() { final PrintWriter pw = getOutPrintWriter(); String opt; + String installerPackageName = null; + Long throttleTimeInSeconds = null; boolean reset = false; while ((opt = getNextOption()) != null) { switch (opt) { + case "--allow-unlimited-silent-updates": + installerPackageName = getNextArgRequired(); + break; + case "--throttle-time": + throttleTimeInSeconds = Long.parseLong(getNextArgRequired()); + break; case "--reset": reset = true; break; @@ -3055,10 +3063,24 @@ class PackageManagerShellCommand extends ShellCommand { return -1; } } + if (throttleTimeInSeconds != null && throttleTimeInSeconds < 0) { + pw.println("Error: Invalid value for \"--throttle-time\":" + throttleTimeInSeconds); + return -1; + } - final String installerPackageName = reset ? null : getNextArgRequired(); try { - mInterface.getPackageInstaller().setAllowUnlimitedSilentUpdates(installerPackageName); + final IPackageInstaller installer = mInterface.getPackageInstaller(); + if (reset) { + installer.setAllowUnlimitedSilentUpdates(null /* installerPackageName */); + installer.setSilentUpdatesThrottleTime(-1 /* restore to the default */); + } else { + if (installerPackageName != null) { + installer.setAllowUnlimitedSilentUpdates(installerPackageName); + } + if (throttleTimeInSeconds != null) { + installer.setSilentUpdatesThrottleTime(throttleTimeInSeconds); + } + } } catch (RemoteException e) { pw.println("Failure [" + e.getClass().getName() + " - " @@ -3892,11 +3914,14 @@ class PackageManagerShellCommand extends ShellCommand { pw.println(" --enable: turn on debug logging (default)"); pw.println(" --disable: turn off debug logging"); pw.println(""); - pw.println(" allow-unlimited-silent-updates (--reset | )"); - pw.println(" Allows unlimited silent updated installation requests from the installer"); - pw.println(" without the throttle time."); - pw.println(" --reset: clear the allowed installer and tracks of silent updates in"); - pw.println(" the system."); + pw.println(" set-silent-updates-policy [--allow-unlimited-silent-updates ]"); + pw.println(" [--throttle-time ] [--reset]"); + pw.println(" Sets the policies of the silent updates."); + pw.println(" --allow-unlimited-silent-updates: allows unlimited silent updated"); + pw.println(" installation requests from the installer without the throttle time."); + pw.println(" --throttle-time: update the silent updates throttle time in seconds."); + pw.println(" --reset: restore the installer and throttle time to the default, and"); + pw.println(" clear tracks of silent updates in the system."); pw.println(""); mDomainVerificationShell.printHelp(pw); pw.println(""); diff --git a/services/core/java/com/android/server/pm/SilentUpdatePolicy.java b/services/core/java/com/android/server/pm/SilentUpdatePolicy.java index 117acab6d0798..700f72cfbb947 100644 --- a/services/core/java/com/android/server/pm/SilentUpdatePolicy.java +++ b/services/core/java/com/android/server/pm/SilentUpdatePolicy.java @@ -33,7 +33,8 @@ import java.util.concurrent.TimeUnit; * in the {@link PackageInstallerSession}. */ public class SilentUpdatePolicy { - // A throttle time to prevent the installer from silently updating the same app repeatedly. + // The default throttle time to prevent the installer from silently updating the same app + // repeatedly. private static final long SILENT_UPDATE_THROTTLE_TIME_MS = TimeUnit.SECONDS.toMillis(30); // Map to the uptime timestamp for each installer and app of the silent update. @@ -44,6 +45,9 @@ public class SilentUpdatePolicy { @GuardedBy("mSilentUpdateInfos") private String mAllowUnlimitedSilentUpdatesInstaller; + @GuardedBy("mSilentUpdateInfos") + private long mSilentUpdateThrottleTimeMs = SILENT_UPDATE_THROTTLE_TIME_MS; + /** * Checks if the silent update is allowed by the given installer and app package name. * @@ -58,7 +62,11 @@ public class SilentUpdatePolicy { return true; } final long lastSilentUpdatedMs = getTimestampMs(installerPackageName, packageName); - return SystemClock.uptimeMillis() - lastSilentUpdatedMs > SILENT_UPDATE_THROTTLE_TIME_MS; + final long throttleTimeMs; + synchronized (mSilentUpdateInfos) { + throttleTimeMs = mSilentUpdateThrottleTimeMs; + } + return SystemClock.uptimeMillis() - lastSilentUpdatedMs > throttleTimeMs; } /** @@ -99,11 +107,25 @@ public class SilentUpdatePolicy { } } + /** + * Set the silent updates throttle time in seconds. + * + * @param throttleTimeInSeconds The throttle time to set, or -1 to restore the + * value to the default. + */ + void setSilentUpdatesThrottleTime(long throttleTimeInSeconds) { + synchronized (mSilentUpdateInfos) { + mSilentUpdateThrottleTimeMs = throttleTimeInSeconds >= 0 + ? TimeUnit.SECONDS.toMillis(throttleTimeInSeconds) + : SILENT_UPDATE_THROTTLE_TIME_MS; + } + } + private void pruneLocked(long uptime) { final int size = mSilentUpdateInfos.size(); for (int i = size - 1; i >= 0; i--) { final long lastSilentUpdatedMs = mSilentUpdateInfos.valueAt(i); - if (uptime - lastSilentUpdatedMs > SILENT_UPDATE_THROTTLE_TIME_MS) { + if (uptime - lastSilentUpdatedMs > mSilentUpdateThrottleTimeMs) { mSilentUpdateInfos.removeAt(i); } }