diff options
| -rw-r--r-- | api/current.txt | 3 | ||||
| -rw-r--r-- | core/java/android/app/ApplicationPackageManager.java | 10 | ||||
| -rw-r--r-- | core/java/android/content/pm/IPackageManager.aidl | 1 | ||||
| -rw-r--r-- | core/java/android/content/pm/PackageManager.java | 35 | ||||
| -rw-r--r-- | services/java/com/android/server/pm/PackageManagerService.java | 46 | ||||
| -rw-r--r-- | services/java/com/android/server/pm/PackageVerificationState.java | 21 | ||||
| -rw-r--r-- | test-runner/src/android/test/mock/MockPackageManager.java | 6 |
7 files changed, 112 insertions, 10 deletions
diff --git a/api/current.txt b/api/current.txt index f97744e..ae1fc62 100644 --- a/api/current.txt +++ b/api/current.txt @@ -6532,6 +6532,7 @@ package android.content.pm { method public abstract void setComponentEnabledSetting(android.content.ComponentName, int, int); method public abstract void setInstallerPackageName(java.lang.String, java.lang.String); method public abstract void verifyPendingInstall(int, int); + method public abstract void extendVerificationTimeout(int, int, long); field public static final int COMPONENT_ENABLED_STATE_DEFAULT = 0; // 0x0 field public static final int COMPONENT_ENABLED_STATE_DISABLED = 2; // 0x2 field public static final int COMPONENT_ENABLED_STATE_DISABLED_USER = 3; // 0x3 @@ -6602,6 +6603,7 @@ package android.content.pm { field public static final int SIGNATURE_UNKNOWN_PACKAGE = -4; // 0xfffffffc field public static final int VERIFICATION_ALLOW = 1; // 0x1 field public static final int VERIFICATION_REJECT = -1; // 0xffffffff + field public static final long MAXIMUM_VERIFICATION_TIMEOUT = 360000L; // 0x36ee80L } public static class PackageManager.NameNotFoundException extends android.util.AndroidException { @@ -21371,6 +21373,7 @@ package android.test.mock { method public void setComponentEnabledSetting(android.content.ComponentName, int, int); method public void setInstallerPackageName(java.lang.String, java.lang.String); method public void verifyPendingInstall(int, int); + method public void extendVerificationTimeout(int, int, long); } public class MockResources extends android.content.res.Resources { diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java index 86ee8a0..f3f75ce 100644 --- a/core/java/android/app/ApplicationPackageManager.java +++ b/core/java/android/app/ApplicationPackageManager.java @@ -1006,6 +1006,16 @@ final class ApplicationPackageManager extends PackageManager { } @Override + public void extendVerificationTimeout(int id, int verificationCodeAtTimeout, + long millisecondsToDelay) { + try { + mPM.extendVerificationTimeout(id, verificationCodeAtTimeout, millisecondsToDelay); + } catch (RemoteException e) { + // Should never happen! + } + } + + @Override public void setInstallerPackageName(String targetPackage, String installerPackageName) { try { diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl index 3f4b994..0be8b83 100644 --- a/core/java/android/content/pm/IPackageManager.aidl +++ b/core/java/android/content/pm/IPackageManager.aidl @@ -370,6 +370,7 @@ interface IPackageManager { in ContainerEncryptionParams encryptionParams); void verifyPendingInstall(int id, int verificationCode); + void extendVerificationTimeout(int id, int verificationCodeAtTimeout, long millisecondsToDelay); VerifierDeviceIdentity getVerifierDeviceIdentity(); diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index 0461dd1..b3e98e7 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -762,6 +762,14 @@ public abstract class PackageManager { public static final int VERIFICATION_REJECT = -1; /** + * Can be used as the {@code millisecondsToDelay} argument for + * {@link PackageManager#extendVerificationTimeout}. This is the + * maximum time {@code PackageManager} waits for the verification + * agent to return (in milliseconds). + */ + public static final long MAXIMUM_VERIFICATION_TIMEOUT = 60*60*1000; + + /** * Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}: The device's * audio pipeline is low-latency, more suitable for audio applications sensitive to delays or * lag in sound input or output. @@ -2274,6 +2282,33 @@ public abstract class PackageManager { public abstract void verifyPendingInstall(int id, int verificationCode); /** + * Allows a package listening to the + * {@link Intent#ACTION_PACKAGE_NEEDS_VERIFICATION package verification + * broadcast} to extend the default timeout for a response and declare what + * action to perform after the timeout occurs. The response must include + * the {@code verificationCodeAtTimeout} which is one of + * {@link PackageManager#VERIFICATION_ALLOW} or + * {@link PackageManager#VERIFICATION_REJECT}. + * + * This method may only be called once per package id. Additional calls + * will have no effect. + * + * @param id pending package identifier as passed via the + * {@link PackageManager#EXTRA_VERIFICATION_ID} Intent extra + * @param verificationCodeAtTimeout either + * {@link PackageManager#VERIFICATION_ALLOW} or + * {@link PackageManager#VERIFICATION_REJECT}. + * @param millisecondsToDelay the amount of time requested for the timeout. + * Must be positive and less than + * {@link PackageManager#MAXIMUM_VERIFICATION_TIMEOUT}. + * + * @throws IllegalArgumentException if {@code millisecondsToDelay} is out + * of bounds or {@code verificationCodeAtTimeout} is unknown. + */ + public abstract void extendVerificationTimeout(int id, + int verificationCodeAtTimeout, long millisecondsToDelay); + + /** * Change the installer associated with a given package. There are limitations * on how the installer package can be changed; in particular: * <ul> diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java index a76f854..4252b90 100644 --- a/services/java/com/android/server/pm/PackageManagerService.java +++ b/services/java/com/android/server/pm/PackageManagerService.java @@ -780,7 +780,7 @@ public class PackageManagerService extends IPackageManager.Stub { final int verificationId = msg.arg1; final PackageVerificationState state = mPendingVerification.get(verificationId); - if (state != null) { + if ((state != null) && !state.timeoutExtended()) { final InstallArgs args = state.getInstallArgs(); Slog.i(TAG, "Verification timed out for " + args.packageURI.toString()); mPendingVerification.remove(verificationId); @@ -788,20 +788,20 @@ public class PackageManagerService extends IPackageManager.Stub { int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; if (getDefaultVerificationResponse() == PackageManager.VERIFICATION_ALLOW) { - Slog.i(TAG, "Continuing with installation of " + args.packageURI.toString()); - state.setVerifierResponse(Binder.getCallingUid(), PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT); - try { - ret = args.copyApk(mContainerService, true); - } catch (RemoteException e) { - Slog.e(TAG, "Could not contact the ContainerService"); - } + Slog.i(TAG, "Continuing with installation of " + + args.packageURI.toString()); + state.setVerifierResponse(Binder.getCallingUid(), + PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT); + try { + ret = args.copyApk(mContainerService, true); + } catch (RemoteException e) { + Slog.e(TAG, "Could not contact the ContainerService"); + } } processPendingInstall(args, ret); - mHandler.sendEmptyMessage(MCS_UNBIND); } - break; } case PACKAGE_VERIFIED: { @@ -5393,6 +5393,32 @@ public class PackageManagerService extends IPackageManager.Stub { mHandler.sendMessage(msg); } + @Override + public void extendVerificationTimeout(int id, int verificationCodeAtTimeout, + long millisecondsToDelay) { + final PackageVerificationState state = mPendingVerification.get(id); + final PackageVerificationResponse response = new PackageVerificationResponse( + verificationCodeAtTimeout, Binder.getCallingUid()); + + if ((millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) + || (millisecondsToDelay < 0)) { + throw new IllegalArgumentException("millisecondsToDelay is out of bounds."); + } + if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW) + || (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) { + throw new IllegalArgumentException("verificationCodeAtTimeout is unknown."); + } + + if ((state != null) && !state.timeoutExtended()) { + state.extendTimeout(); + + final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED); + msg.arg1 = id; + msg.obj = response; + mHandler.sendMessageDelayed(msg, millisecondsToDelay); + } + } + private ComponentName matchComponentForVerifier(String packageName, List<ResolveInfo> receivers) { ActivityInfo targetReceiver = null; diff --git a/services/java/com/android/server/pm/PackageVerificationState.java b/services/java/com/android/server/pm/PackageVerificationState.java index e5b89c1..3214e88 100644 --- a/services/java/com/android/server/pm/PackageVerificationState.java +++ b/services/java/com/android/server/pm/PackageVerificationState.java @@ -43,6 +43,8 @@ class PackageVerificationState { private boolean mRequiredVerificationPassed; + private boolean mExtendedTimeout; + /** * Create a new package verification state where {@code requiredVerifierUid} * is the user ID for the package that must reply affirmative before things @@ -55,6 +57,7 @@ class PackageVerificationState { mRequiredVerifierUid = requiredVerifierUid; mArgs = args; mSufficientVerifierUids = new SparseBooleanArray(); + mExtendedTimeout = false; } public InstallArgs getInstallArgs() { @@ -146,4 +149,22 @@ class PackageVerificationState { return true; } + + /** + * Extend the timeout for this Package to be verified. + */ + public void extendTimeout() { + if (!mExtendedTimeout) { + mExtendedTimeout = true; + } + } + + /** + * Returns whether the timeout was extended for verification. + * + * @return {@code true} if a timeout was already extended. + */ + public boolean timeoutExtended() { + return mExtendedTimeout; + } } diff --git a/test-runner/src/android/test/mock/MockPackageManager.java b/test-runner/src/android/test/mock/MockPackageManager.java index 0fb51f0..ac40fc6b 100644 --- a/test-runner/src/android/test/mock/MockPackageManager.java +++ b/test-runner/src/android/test/mock/MockPackageManager.java @@ -536,6 +536,12 @@ public class MockPackageManager extends PackageManager { throw new UnsupportedOperationException(); } + @Override + public void extendVerificationTimeout(int id, int verificationCodeAtTimeout, + long millisecondsToDelay) { + throw new UnsupportedOperationException(); + } + /** * @hide */ |
