summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/current.txt3
-rw-r--r--core/java/android/app/ApplicationPackageManager.java10
-rw-r--r--core/java/android/content/pm/IPackageManager.aidl1
-rw-r--r--core/java/android/content/pm/PackageManager.java35
-rw-r--r--services/java/com/android/server/pm/PackageManagerService.java46
-rw-r--r--services/java/com/android/server/pm/PackageVerificationState.java21
-rw-r--r--test-runner/src/android/test/mock/MockPackageManager.java6
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
*/