Infrastructure to support package verifier
Allow a package verifier to approve or disapprove of a package being
installed.
Change-Id: Ibfea0f2b1aaa4ab1589a4e59f96144702b9bf94b
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 4cff12f..4b2a8d2 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -41,11 +41,11 @@
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.content.pm.UserInfo;
+import android.content.pm.ManifestDigest;
import android.content.res.Resources;
import android.content.res.XmlResourceParser;
import android.graphics.drawable.Drawable;
import android.net.Uri;
-import android.os.Parcel;
import android.os.Process;
import android.os.RemoteException;
import android.util.Log;
@@ -941,6 +941,27 @@
}
@Override
+ public void installPackageWithVerification(Uri packageURI, IPackageInstallObserver observer,
+ int flags, String installerPackageName, Uri verificationURI,
+ ManifestDigest manifestDigest) {
+ try {
+ mPM.installPackageWithVerification(packageURI, observer, flags, installerPackageName,
+ verificationURI, manifestDigest);
+ } catch (RemoteException e) {
+ // Should never happen!
+ }
+ }
+
+ @Override
+ public void verifyPendingInstall(int id, boolean verified, String failureMessage) {
+ try {
+ mPM.verifyPendingInstall(id, verified, failureMessage);
+ } catch (RemoteException e) {
+ // Should never happen!
+ }
+ }
+
+ @Override
public void setInstallerPackageName(String targetPackage,
String installerPackageName) {
try {
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 2579ced..8d6cee1 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1530,6 +1530,18 @@
public static final String ACTION_PACKAGE_FIRST_LAUNCH = "android.intent.action.PACKAGE_FIRST_LAUNCH";
/**
+ * Broadcast Action: Sent to the system package verifier when a package
+ * needs to be verified. The data contains the package URI.
+ * <p class="note">
+ * This is a protected intent that can only be sent by the system.
+ * </p>
+ *
+ * @hide
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_PACKAGE_NEEDS_VERIFICATION = "android.intent.action.PACKAGE_NEEDS_VERIFICATION";
+
+ /**
* Broadcast Action: Resources for a set of packages (which were
* previously unavailable) are currently
* available since the media on which they exist is available.
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 37b6822..d7607e3 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -30,6 +30,7 @@
import android.content.pm.IPackageStatsObserver;
import android.content.pm.InstrumentationInfo;
import android.content.pm.PackageInfo;
+import android.content.pm.ManifestDigest;
import android.content.pm.ParceledListSlice;
import android.content.pm.ProviderInfo;
import android.content.pm.PermissionGroupInfo;
@@ -346,4 +347,10 @@
UserInfo createUser(in String name, int flags);
boolean removeUser(int userId);
+
+ void installPackageWithVerification(in Uri packageURI, in IPackageInstallObserver observer,
+ int flags, in String installerPackageName, in Uri verificationURI,
+ in ManifestDigest manifestDigest);
+
+ void verifyPendingInstall(int id, boolean verified, in String message);
}
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index dd684cd..5c641f1 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -23,6 +23,7 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentSender;
+import android.content.pm.ManifestDigest;
import android.content.res.Resources;
import android.content.res.XmlResourceParser;
import android.graphics.drawable.Drawable;
@@ -289,11 +290,19 @@
public static final int INSTALL_EXTERNAL = 0x00000008;
/**
- * Flag parameter for {@link #installPackage} to indicate that this
- * package has to be installed on the sdcard.
- * @hide
- */
- public static final int INSTALL_INTERNAL = 0x00000010;
+ * Flag parameter for {@link #installPackage} to indicate that this package
+ * has to be installed on the sdcard.
+ * @hide
+ */
+ public static final int INSTALL_INTERNAL = 0x00000010;
+
+ /**
+ * Flag parameter for {@link #installPackage} to indicate that this install
+ * was initiated via ADB.
+ *
+ * @hide
+ */
+ public static final int INSTALL_FROM_ADB = 0x00000020;
/**
* Flag parameter for
@@ -483,6 +492,30 @@
public static final int INSTALL_FAILED_MEDIA_UNAVAILABLE = -20;
/**
+ * Installation return code: this is passed to the {@link IPackageInstallObserver} by
+ * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if
+ * the new package couldn't be installed because the verification timed out.
+ * @hide
+ */
+ public static final int INSTALL_FAILED_VERIFICATION_TIMEOUT = -21;
+
+ /**
+ * Installation return code: this is passed to the {@link IPackageInstallObserver} by
+ * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if
+ * the new package couldn't be installed because the verification did not succeed.
+ * @hide
+ */
+ public static final int INSTALL_FAILED_VERIFICATION_FAILURE = -22;
+
+ /**
+ * Installation return code: this is passed to the {@link IPackageInstallObserver} by
+ * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if
+ * the package changed from what the calling program expected.
+ * @hide
+ */
+ public static final int INSTALL_FAILED_PACKAGE_CHANGED = -23;
+
+ /**
* Installation parse return code: this is passed to the {@link IPackageInstallObserver} by
* {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}
* if the parser was given a path that is not a file, or does not end with the expected
@@ -995,35 +1028,63 @@
= "android.content.pm.CLEAN_EXTERNAL_STORAGE";
/**
+ * Extra field name for the URI to a verification file. Passed to a package
+ * verifier.
+ *
+ * @hide
+ */
+ public static final String EXTRA_VERIFICATION_URI = "android.content.pm.extra.VERIFICATION_URI";
+
+ /**
+ * Extra field name for the ID of a package pending verification. Passed to
+ * a package verifier and is used to call back to
+ * {@link PackageManager#verifyPendingInstall(int, boolean)}
+ *
+ * @hide
+ */
+ public static final String EXTRA_VERIFICATION_ID = "android.content.pm.extra.VERIFICATION_ID";
+
+ /**
+ * Extra field name for the package identifier which is trying to install
+ * the package.
+ *
+ * @hide
+ */
+ public static final String EXTRA_VERIFICATION_INSTALLER_PACKAGE
+ = "android.content.pm.extra.VERIFICATION_INSTALLER_PACKAGE";
+
+ /**
+ * Extra field name for the requested install flags for a package pending
+ * verification. Passed to a package verifier.
+ *
+ * @hide
+ */
+ public static final String EXTRA_VERIFICATION_INSTALL_FLAGS
+ = "android.content.pm.extra.VERIFICATION_INSTALL_FLAGS";
+
+ /**
* Retrieve overall information about an application package that is
* installed on the system.
- *
- * <p>Throws {@link NameNotFoundException} if a package with the given
- * name can not be found on the system.
+ * <p>
+ * Throws {@link NameNotFoundException} if a package with the given name can
+ * not be found on the system.
*
* @param packageName The full name (i.e. com.google.apps.contacts) of the
- * desired package.
-
+ * desired package.
* @param flags Additional option flags. Use any combination of
- * {@link #GET_ACTIVITIES},
- * {@link #GET_GIDS},
- * {@link #GET_CONFIGURATIONS},
- * {@link #GET_INSTRUMENTATION},
- * {@link #GET_PERMISSIONS},
- * {@link #GET_PROVIDERS},
- * {@link #GET_RECEIVERS},
- * {@link #GET_SERVICES},
- * {@link #GET_SIGNATURES},
- * {@link #GET_UNINSTALLED_PACKAGES} to modify the data returned.
- *
- * @return Returns a PackageInfo object containing information about the package.
- * If flag GET_UNINSTALLED_PACKAGES is set and if the package is not
- * found in the list of installed applications, the package information is
- * retrieved from the list of uninstalled applications(which includes
- * installed applications as well as applications
- * with data directory ie applications which had been
+ * {@link #GET_ACTIVITIES}, {@link #GET_GIDS},
+ * {@link #GET_CONFIGURATIONS}, {@link #GET_INSTRUMENTATION},
+ * {@link #GET_PERMISSIONS}, {@link #GET_PROVIDERS},
+ * {@link #GET_RECEIVERS}, {@link #GET_SERVICES},
+ * {@link #GET_SIGNATURES}, {@link #GET_UNINSTALLED_PACKAGES} to
+ * modify the data returned.
+ * @return Returns a PackageInfo object containing information about the
+ * package. If flag GET_UNINSTALLED_PACKAGES is set and if the
+ * package is not found in the list of installed applications, the
+ * package information is retrieved from the list of uninstalled
+ * applications(which includes installed applications as well as
+ * applications with data directory ie applications which had been
* deleted with DONT_DELTE_DATA flag set).
- *
* @see #GET_ACTIVITIES
* @see #GET_GIDS
* @see #GET_CONFIGURATIONS
@@ -1034,7 +1095,6 @@
* @see #GET_SERVICES
* @see #GET_SIGNATURES
* @see #GET_UNINSTALLED_PACKAGES
- *
*/
public abstract PackageInfo getPackageInfo(String packageName, int flags)
throws NameNotFoundException;
@@ -2061,6 +2121,46 @@
String installerPackageName);
/**
+ * Similar to
+ * {@link #installPackage(Uri, IPackageInstallObserver, int, String)} but
+ * with an extra verification file provided.
+ *
+ * @param packageURI The location of the package file to install. This can
+ * be a 'file:' or a 'content:' URI.
+ * @param observer An observer callback to get notified when the package
+ * installation is complete.
+ * {@link IPackageInstallObserver#packageInstalled(String, int)}
+ * will be called when that happens. observer may be null to
+ * indicate that no callback is desired.
+ * @param flags - possible values: {@link #INSTALL_FORWARD_LOCK},
+ * {@link #INSTALL_REPLACE_EXISTING}, {@link #INSTALL_ALLOW_TEST}
+ * .
+ * @param installerPackageName Optional package name of the application that
+ * is performing the installation. This identifies which market
+ * the package came from.
+ * @param verificationURI The location of the supplementary verification
+ * file. This can be a 'file:' or a 'content:' URI.
+ * @hide
+ */
+ public abstract void installPackageWithVerification(Uri packageURI,
+ IPackageInstallObserver observer, int flags, String installerPackageName,
+ Uri verificationURI, ManifestDigest manifestDigest);
+
+ /**
+ * Allows a package listening to the
+ * {@link Intent#ACTION_PACKAGE_NEEDS_VERIFICATION package verification
+ * broadcast} to respond to the package manager.
+ *
+ * @param id pending package identifier as passed via the
+ * {@link PackageManager#EXTRA_VERIFICATION_ID} Intent extra
+ * @param verified whether the package was verified as valid
+ * @param failureMessage if verification was false, this is the error
+ * message that may be shown to the user
+ * @hide
+ */
+ public abstract void verifyPendingInstall(int id, boolean verified, String failureMessage);
+
+ /**
* 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/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index f8702b9..de06f20 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -3960,6 +3960,12 @@
public static final String WEB_AUTOFILL_QUERY_URL =
"web_autofill_query_url";
+ /** Whether package verification is enabled. {@hide} */
+ public static final String PACKAGE_VERIFIER_ENABLE = "verifier_enable";
+
+ /** Timeout for package verification. {@hide} */
+ public static final String PACKAGE_VERIFIER_TIMEOUT = "verifier_timeout";
+
/**
* @hide
*/