diff options
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 32fc74f60d15..b0ce6a55e9ba 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 1f0a8caa0ccf..85e3bb4e33f8 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<PackageInstallerSession> 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 4ebf4768a973..f1a412b54124 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 | <INSTALLER>)"); - 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 <INSTALLER>]"); + pw.println(" [--throttle-time <SECONDS>] [--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 117acab6d079..700f72cfbb94 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 <code>-1</code> 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); } } |