Merge "Infrastructure to support package verifier"
This commit is contained in:
@@ -772,18 +772,33 @@ public final class Pm {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String apkFilePath = nextArg();
|
final Uri apkURI;
|
||||||
|
final Uri verificationURI;
|
||||||
|
|
||||||
|
// Populate apkURI, must be present
|
||||||
|
final String apkFilePath = nextArg();
|
||||||
System.err.println("\tpkg: " + apkFilePath);
|
System.err.println("\tpkg: " + apkFilePath);
|
||||||
if (apkFilePath == null) {
|
if (apkFilePath != null) {
|
||||||
|
apkURI = Uri.fromFile(new File(apkFilePath));
|
||||||
|
} else {
|
||||||
System.err.println("Error: no package specified");
|
System.err.println("Error: no package specified");
|
||||||
showUsage();
|
showUsage();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Populate verificationURI, optionally present
|
||||||
|
final String verificationFilePath = nextArg();
|
||||||
|
if (verificationFilePath != null) {
|
||||||
|
System.err.println("\tver: " + verificationFilePath);
|
||||||
|
verificationURI = Uri.fromFile(new File(verificationFilePath));
|
||||||
|
} else {
|
||||||
|
verificationURI = null;
|
||||||
|
}
|
||||||
|
|
||||||
PackageInstallObserver obs = new PackageInstallObserver();
|
PackageInstallObserver obs = new PackageInstallObserver();
|
||||||
try {
|
try {
|
||||||
mPm.installPackage(Uri.fromFile(new File(apkFilePath)), obs, installFlags,
|
mPm.installPackageWithVerification(apkURI, obs, installFlags, installerPackageName,
|
||||||
installerPackageName);
|
verificationURI, null);
|
||||||
|
|
||||||
synchronized (obs) {
|
synchronized (obs) {
|
||||||
while (!obs.finished) {
|
while (!obs.finished) {
|
||||||
|
|||||||
@@ -41,11 +41,11 @@ import android.content.pm.ProviderInfo;
|
|||||||
import android.content.pm.ResolveInfo;
|
import android.content.pm.ResolveInfo;
|
||||||
import android.content.pm.ServiceInfo;
|
import android.content.pm.ServiceInfo;
|
||||||
import android.content.pm.UserInfo;
|
import android.content.pm.UserInfo;
|
||||||
|
import android.content.pm.ManifestDigest;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.content.res.XmlResourceParser;
|
import android.content.res.XmlResourceParser;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Parcel;
|
|
||||||
import android.os.Process;
|
import android.os.Process;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
@@ -940,6 +940,27 @@ final class ApplicationPackageManager extends PackageManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@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
|
@Override
|
||||||
public void setInstallerPackageName(String targetPackage,
|
public void setInstallerPackageName(String targetPackage,
|
||||||
String installerPackageName) {
|
String installerPackageName) {
|
||||||
|
|||||||
@@ -1529,6 +1529,18 @@ public class Intent implements Parcelable, Cloneable {
|
|||||||
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
|
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
|
||||||
public static final String ACTION_PACKAGE_FIRST_LAUNCH = "android.intent.action.PACKAGE_FIRST_LAUNCH";
|
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
|
* Broadcast Action: Resources for a set of packages (which were
|
||||||
* previously unavailable) are currently
|
* previously unavailable) are currently
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import android.content.pm.IPackageMoveObserver;
|
|||||||
import android.content.pm.IPackageStatsObserver;
|
import android.content.pm.IPackageStatsObserver;
|
||||||
import android.content.pm.InstrumentationInfo;
|
import android.content.pm.InstrumentationInfo;
|
||||||
import android.content.pm.PackageInfo;
|
import android.content.pm.PackageInfo;
|
||||||
|
import android.content.pm.ManifestDigest;
|
||||||
import android.content.pm.ParceledListSlice;
|
import android.content.pm.ParceledListSlice;
|
||||||
import android.content.pm.ProviderInfo;
|
import android.content.pm.ProviderInfo;
|
||||||
import android.content.pm.PermissionGroupInfo;
|
import android.content.pm.PermissionGroupInfo;
|
||||||
@@ -346,4 +347,10 @@ interface IPackageManager {
|
|||||||
|
|
||||||
UserInfo createUser(in String name, int flags);
|
UserInfo createUser(in String name, int flags);
|
||||||
boolean removeUser(int userId);
|
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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import android.content.Context;
|
|||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
import android.content.IntentSender;
|
import android.content.IntentSender;
|
||||||
|
import android.content.pm.ManifestDigest;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.content.res.XmlResourceParser;
|
import android.content.res.XmlResourceParser;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
@@ -289,11 +290,19 @@ public abstract class PackageManager {
|
|||||||
public static final int INSTALL_EXTERNAL = 0x00000008;
|
public static final int INSTALL_EXTERNAL = 0x00000008;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flag parameter for {@link #installPackage} to indicate that this
|
* Flag parameter for {@link #installPackage} to indicate that this package
|
||||||
* package has to be installed on the sdcard.
|
* has to be installed on the sdcard.
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public static final int INSTALL_INTERNAL = 0x00000010;
|
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
|
* Flag parameter for
|
||||||
@@ -482,6 +491,30 @@ public abstract class PackageManager {
|
|||||||
*/
|
*/
|
||||||
public static final int INSTALL_FAILED_MEDIA_UNAVAILABLE = -20;
|
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
|
* Installation parse return code: this is passed to the {@link IPackageInstallObserver} by
|
||||||
* {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}
|
* {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}
|
||||||
@@ -994,36 +1027,64 @@ public abstract class PackageManager {
|
|||||||
public static final String ACTION_CLEAN_EXTERNAL_STORAGE
|
public static final String ACTION_CLEAN_EXTERNAL_STORAGE
|
||||||
= "android.content.pm.CLEAN_EXTERNAL_STORAGE";
|
= "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
|
* Retrieve overall information about an application package that is
|
||||||
* installed on the system.
|
* installed on the system.
|
||||||
*
|
* <p>
|
||||||
* <p>Throws {@link NameNotFoundException} if a package with the given
|
* Throws {@link NameNotFoundException} if a package with the given name can
|
||||||
* name can not be found on the system.
|
* not be found on the system.
|
||||||
*
|
*
|
||||||
* @param packageName The full name (i.e. com.google.apps.contacts) of the
|
* @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
|
* @param flags Additional option flags. Use any combination of
|
||||||
* {@link #GET_ACTIVITIES},
|
* {@link #GET_ACTIVITIES}, {@link #GET_GIDS},
|
||||||
* {@link #GET_GIDS},
|
* {@link #GET_CONFIGURATIONS}, {@link #GET_INSTRUMENTATION},
|
||||||
* {@link #GET_CONFIGURATIONS},
|
* {@link #GET_PERMISSIONS}, {@link #GET_PROVIDERS},
|
||||||
* {@link #GET_INSTRUMENTATION},
|
* {@link #GET_RECEIVERS}, {@link #GET_SERVICES},
|
||||||
* {@link #GET_PERMISSIONS},
|
* {@link #GET_SIGNATURES}, {@link #GET_UNINSTALLED_PACKAGES} to
|
||||||
* {@link #GET_PROVIDERS},
|
* modify the data returned.
|
||||||
* {@link #GET_RECEIVERS},
|
* @return Returns a PackageInfo object containing information about the
|
||||||
* {@link #GET_SERVICES},
|
* package. If flag GET_UNINSTALLED_PACKAGES is set and if the
|
||||||
* {@link #GET_SIGNATURES},
|
* package is not found in the list of installed applications, the
|
||||||
* {@link #GET_UNINSTALLED_PACKAGES} to modify the data returned.
|
* package information is retrieved from the list of uninstalled
|
||||||
*
|
* applications(which includes installed applications as well as
|
||||||
* @return Returns a PackageInfo object containing information about the package.
|
* applications with data directory ie applications which had been
|
||||||
* 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).
|
* deleted with DONT_DELTE_DATA flag set).
|
||||||
*
|
|
||||||
* @see #GET_ACTIVITIES
|
* @see #GET_ACTIVITIES
|
||||||
* @see #GET_GIDS
|
* @see #GET_GIDS
|
||||||
* @see #GET_CONFIGURATIONS
|
* @see #GET_CONFIGURATIONS
|
||||||
@@ -1034,7 +1095,6 @@ public abstract class PackageManager {
|
|||||||
* @see #GET_SERVICES
|
* @see #GET_SERVICES
|
||||||
* @see #GET_SIGNATURES
|
* @see #GET_SIGNATURES
|
||||||
* @see #GET_UNINSTALLED_PACKAGES
|
* @see #GET_UNINSTALLED_PACKAGES
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public abstract PackageInfo getPackageInfo(String packageName, int flags)
|
public abstract PackageInfo getPackageInfo(String packageName, int flags)
|
||||||
throws NameNotFoundException;
|
throws NameNotFoundException;
|
||||||
@@ -2060,6 +2120,46 @@ public abstract class PackageManager {
|
|||||||
Uri packageURI, IPackageInstallObserver observer, int flags,
|
Uri packageURI, IPackageInstallObserver observer, int flags,
|
||||||
String installerPackageName);
|
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
|
* Change the installer associated with a given package. There are limitations
|
||||||
* on how the installer package can be changed; in particular:
|
* on how the installer package can be changed; in particular:
|
||||||
|
|||||||
@@ -3960,6 +3960,12 @@ public final class Settings {
|
|||||||
public static final String WEB_AUTOFILL_QUERY_URL =
|
public static final String WEB_AUTOFILL_QUERY_URL =
|
||||||
"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
|
* @hide
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -42,6 +42,7 @@
|
|||||||
<protected-broadcast android:name="android.intent.action.PACKAGE_RESTARTED" />
|
<protected-broadcast android:name="android.intent.action.PACKAGE_RESTARTED" />
|
||||||
<protected-broadcast android:name="android.intent.action.PACKAGE_DATA_CLEARED" />
|
<protected-broadcast android:name="android.intent.action.PACKAGE_DATA_CLEARED" />
|
||||||
<protected-broadcast android:name="android.intent.action.PACKAGE_FIRST_LAUNCH" />
|
<protected-broadcast android:name="android.intent.action.PACKAGE_FIRST_LAUNCH" />
|
||||||
|
<protected-broadcast android:name="android.intent.action.PACKAGE_NEEDS_VERIFICATION" />
|
||||||
<protected-broadcast android:name="android.intent.action.UID_REMOVED" />
|
<protected-broadcast android:name="android.intent.action.UID_REMOVED" />
|
||||||
<protected-broadcast android:name="android.intent.action.CONFIGURATION_CHANGED" />
|
<protected-broadcast android:name="android.intent.action.CONFIGURATION_CHANGED" />
|
||||||
<protected-broadcast android:name="android.intent.action.LOCALE_CHANGED" />
|
<protected-broadcast android:name="android.intent.action.LOCALE_CHANGED" />
|
||||||
@@ -1429,6 +1430,24 @@
|
|||||||
android:protectionLevel="signature" />
|
android:protectionLevel="signature" />
|
||||||
<uses-permission android:name="android.intent.category.MASTER_CLEAR.permission.C2D_MESSAGE"/>
|
<uses-permission android:name="android.intent.category.MASTER_CLEAR.permission.C2D_MESSAGE"/>
|
||||||
|
|
||||||
|
<!-- Package verifier needs to have this permission before the PackageManager will
|
||||||
|
trust it to verify packages.
|
||||||
|
@hide
|
||||||
|
-->
|
||||||
|
<permission android:name="android.permission.PACKAGE_VERIFICATION_AGENT"
|
||||||
|
android:label="@string/permlab_packageVerificationAgent"
|
||||||
|
android:description="@string/permdesc_packageVerificationAgent"
|
||||||
|
android:protectionLevel="signatureOrSystem" />
|
||||||
|
|
||||||
|
<!-- Must be required by package verifier receiver, to ensure that only the
|
||||||
|
system can interact with it.
|
||||||
|
@hide
|
||||||
|
-->
|
||||||
|
<permission android:name="android.permission.BIND_PACKAGE_VERIFIER"
|
||||||
|
android:label="@string/permlab_bindPackageVerifier"
|
||||||
|
android:description="@string/permdesc_bindPackageVerifier"
|
||||||
|
android:protectionLevel="signature" />
|
||||||
|
|
||||||
<!-- The system process is explicitly the only one allowed to launch the
|
<!-- The system process is explicitly the only one allowed to launch the
|
||||||
confirmation UI for full backup/restore -->
|
confirmation UI for full backup/restore -->
|
||||||
<uses-permission android:name="android.permission.CONFIRM_FULL_BACKUP"/>
|
<uses-permission android:name="android.permission.CONFIRM_FULL_BACKUP"/>
|
||||||
|
|||||||
@@ -2181,6 +2181,22 @@
|
|||||||
Browser\'s geolocation permissions. Malicious applications
|
Browser\'s geolocation permissions. Malicious applications
|
||||||
can use this to allow sending location information to arbitrary web sites.</string>
|
can use this to allow sending location information to arbitrary web sites.</string>
|
||||||
|
|
||||||
|
<!-- Title of an application permission which allows the application to verify whether
|
||||||
|
a different package is able to be installed by some internal logic. [CHAR LIMIT=40] -->
|
||||||
|
<string name="permlab_packageVerificationAgent">verify packages</string>
|
||||||
|
<!-- Description of an application permission which allows the application to verify whether
|
||||||
|
a different package is able to be installed by some internal heuristic. [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="permdesc_packageVerificationAgent">Allows the application to verify a package is
|
||||||
|
installable.</string>
|
||||||
|
|
||||||
|
<!-- Title of an application permission which allows the application to verify whether
|
||||||
|
a different package is able to be installed by some internal heuristic. [CHAR LIMIT=40] -->
|
||||||
|
<string name="permlab_bindPackageVerifier">bind to a package verifier</string>
|
||||||
|
<!-- Description of an application permission which allows the application to verify whether
|
||||||
|
a different package is able to be installed by some internal heuristic. [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="permdesc_bindPackageVerifier">Allows the holder to make requests of
|
||||||
|
package verifiers. Should never be needed for normal applications.</string>
|
||||||
|
|
||||||
<!-- If the user enters a password in a form on a website, a dialog will come up asking if they want to save the password. Text in the save password dialog, asking if the browser should remember a password. -->
|
<!-- If the user enters a password in a form on a website, a dialog will come up asking if they want to save the password. Text in the save password dialog, asking if the browser should remember a password. -->
|
||||||
<string name="save_password_message">Do you want the browser to remember this password?</string>
|
<string name="save_password_message">Do you want the browser to remember this password?</string>
|
||||||
<!-- If the user enters a password in a form on a website, a dialog will come up asking if they want to save the password. Button in the save password dialog, saying not to remember this password. -->
|
<!-- If the user enters a password in a form on a website, a dialog will come up asking if they want to save the password. Button in the save password dialog, saying not to remember this password. -->
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ import android.app.ActivityManagerNative;
|
|||||||
import android.app.IActivityManager;
|
import android.app.IActivityManager;
|
||||||
import android.app.admin.IDevicePolicyManager;
|
import android.app.admin.IDevicePolicyManager;
|
||||||
import android.app.backup.IBackupManager;
|
import android.app.backup.IBackupManager;
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.IIntentReceiver;
|
import android.content.IIntentReceiver;
|
||||||
@@ -69,6 +70,7 @@ import android.content.pm.ResolveInfo;
|
|||||||
import android.content.pm.ServiceInfo;
|
import android.content.pm.ServiceInfo;
|
||||||
import android.content.pm.Signature;
|
import android.content.pm.Signature;
|
||||||
import android.content.pm.UserInfo;
|
import android.content.pm.UserInfo;
|
||||||
|
import android.content.pm.ManifestDigest;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
@@ -188,6 +190,17 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|||||||
|
|
||||||
static final int REMOVE_CHATTY = 1<<16;
|
static final int REMOVE_CHATTY = 1<<16;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether verification is enabled by default.
|
||||||
|
*/
|
||||||
|
private static final boolean DEFAULT_VERIFY_ENABLE = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default maximum time to wait for the verification agent to return in
|
||||||
|
* milliseconds.
|
||||||
|
*/
|
||||||
|
private static final long DEFAULT_VERIFICATION_TIMEOUT = 60 * 1000;
|
||||||
|
|
||||||
static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
|
static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
|
||||||
|
|
||||||
static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
|
static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
|
||||||
@@ -333,6 +346,12 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|||||||
// Broadcast actions that are only available to the system.
|
// Broadcast actions that are only available to the system.
|
||||||
final HashSet<String> mProtectedBroadcasts = new HashSet<String>();
|
final HashSet<String> mProtectedBroadcasts = new HashSet<String>();
|
||||||
|
|
||||||
|
/** List of packages waiting for verification. */
|
||||||
|
final SparseArray<InstallArgs> mPendingVerification = new SparseArray<InstallArgs>();
|
||||||
|
|
||||||
|
/** Token for keys in mPendingVerification. */
|
||||||
|
private int mPendingVerificationToken = 0;
|
||||||
|
|
||||||
boolean mSystemReady;
|
boolean mSystemReady;
|
||||||
boolean mSafeMode;
|
boolean mSafeMode;
|
||||||
boolean mHasSystemUidErrors;
|
boolean mHasSystemUidErrors;
|
||||||
@@ -364,6 +383,8 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|||||||
static final int UPDATED_MEDIA_STATUS = 12;
|
static final int UPDATED_MEDIA_STATUS = 12;
|
||||||
static final int WRITE_SETTINGS = 13;
|
static final int WRITE_SETTINGS = 13;
|
||||||
static final int WRITE_STOPPED_PACKAGES = 14;
|
static final int WRITE_STOPPED_PACKAGES = 14;
|
||||||
|
static final int PACKAGE_VERIFIED = 15;
|
||||||
|
static final int CHECK_PENDING_VERIFICATION = 16;
|
||||||
|
|
||||||
static final int WRITE_SETTINGS_DELAY = 10*1000; // 10 seconds
|
static final int WRITE_SETTINGS_DELAY = 10*1000; // 10 seconds
|
||||||
|
|
||||||
@@ -444,10 +465,10 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|||||||
void doHandleMessage(Message msg) {
|
void doHandleMessage(Message msg) {
|
||||||
switch (msg.what) {
|
switch (msg.what) {
|
||||||
case INIT_COPY: {
|
case INIT_COPY: {
|
||||||
if (DEBUG_SD_INSTALL) Log.i(TAG, "init_copy");
|
if (DEBUG_INSTALL) Slog.i(TAG, "init_copy");
|
||||||
HandlerParams params = (HandlerParams) msg.obj;
|
HandlerParams params = (HandlerParams) msg.obj;
|
||||||
int idx = mPendingInstalls.size();
|
int idx = mPendingInstalls.size();
|
||||||
if (DEBUG_SD_INSTALL) Log.i(TAG, "idx=" + idx);
|
if (DEBUG_INSTALL) Slog.i(TAG, "idx=" + idx);
|
||||||
// If a bind was already initiated we dont really
|
// If a bind was already initiated we dont really
|
||||||
// need to do anything. The pending install
|
// need to do anything. The pending install
|
||||||
// will be processed later on.
|
// will be processed later on.
|
||||||
@@ -474,7 +495,7 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MCS_BOUND: {
|
case MCS_BOUND: {
|
||||||
if (DEBUG_SD_INSTALL) Log.i(TAG, "mcs_bound");
|
if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound");
|
||||||
if (msg.obj != null) {
|
if (msg.obj != null) {
|
||||||
mContainerService = (IMediaContainerService) msg.obj;
|
mContainerService = (IMediaContainerService) msg.obj;
|
||||||
}
|
}
|
||||||
@@ -525,8 +546,8 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MCS_RECONNECT : {
|
case MCS_RECONNECT: {
|
||||||
if (DEBUG_SD_INSTALL) Log.i(TAG, "mcs_reconnect");
|
if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect");
|
||||||
if (mPendingInstalls.size() > 0) {
|
if (mPendingInstalls.size() > 0) {
|
||||||
if (mBound) {
|
if (mBound) {
|
||||||
disconnectService();
|
disconnectService();
|
||||||
@@ -543,27 +564,31 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MCS_UNBIND : {
|
case MCS_UNBIND: {
|
||||||
// If there is no actual work left, then time to unbind.
|
// If there is no actual work left, then time to unbind.
|
||||||
if (DEBUG_SD_INSTALL) Log.i(TAG, "mcs_unbind");
|
if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind");
|
||||||
if (mPendingInstalls.size() == 0) {
|
|
||||||
|
if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) {
|
||||||
if (mBound) {
|
if (mBound) {
|
||||||
|
if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()");
|
||||||
|
|
||||||
disconnectService();
|
disconnectService();
|
||||||
}
|
}
|
||||||
} else {
|
} else if (mPendingInstalls.size() > 0) {
|
||||||
// There are more pending requests in queue.
|
// There are more pending requests in queue.
|
||||||
// Just post MCS_BOUND message to trigger processing
|
// Just post MCS_BOUND message to trigger processing
|
||||||
// of next pending install.
|
// of next pending install.
|
||||||
mHandler.sendEmptyMessage(MCS_BOUND);
|
mHandler.sendEmptyMessage(MCS_BOUND);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MCS_GIVE_UP: {
|
case MCS_GIVE_UP: {
|
||||||
if (DEBUG_SD_INSTALL) Log.i(TAG, "mcs_giveup too many retries");
|
if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries");
|
||||||
mPendingInstalls.remove(0);
|
mPendingInstalls.remove(0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SEND_PENDING_BROADCAST : {
|
case SEND_PENDING_BROADCAST: {
|
||||||
String packages[];
|
String packages[];
|
||||||
ArrayList<String> components[];
|
ArrayList<String> components[];
|
||||||
int size = 0;
|
int size = 0;
|
||||||
@@ -707,6 +732,52 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|||||||
}
|
}
|
||||||
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
|
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
|
||||||
} break;
|
} break;
|
||||||
|
case CHECK_PENDING_VERIFICATION: {
|
||||||
|
final int verificationId = msg.arg1;
|
||||||
|
final InstallArgs args = mPendingVerification.get(verificationId);
|
||||||
|
|
||||||
|
if (args != null) {
|
||||||
|
Slog.i(TAG, "Validation timed out for " + args.packageURI.toString());
|
||||||
|
mPendingVerification.remove(verificationId);
|
||||||
|
|
||||||
|
int ret = PackageManager.INSTALL_FAILED_VERIFICATION_TIMEOUT;
|
||||||
|
processPendingInstall(args, ret);
|
||||||
|
|
||||||
|
mHandler.sendEmptyMessage(MCS_UNBIND);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PACKAGE_VERIFIED: {
|
||||||
|
final int verificationId = msg.arg1;
|
||||||
|
final boolean verified = msg.arg2 == 1 ? true : false;
|
||||||
|
|
||||||
|
final InstallArgs args = mPendingVerification.get(verificationId);
|
||||||
|
if (args == null) {
|
||||||
|
Slog.w(TAG, "Invalid validation token " + verificationId + " received");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
mPendingVerification.remove(verificationId);
|
||||||
|
|
||||||
|
int ret;
|
||||||
|
if (verified) {
|
||||||
|
ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
|
||||||
|
try {
|
||||||
|
ret = args.copyApk(mContainerService, true);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
Slog.e(TAG, "Could not contact the ContainerService");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
processPendingInstall(args, ret);
|
||||||
|
|
||||||
|
mHandler.sendEmptyMessage(MCS_UNBIND);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4693,12 +4764,45 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|||||||
public void installPackage(
|
public void installPackage(
|
||||||
final Uri packageURI, final IPackageInstallObserver observer, final int flags,
|
final Uri packageURI, final IPackageInstallObserver observer, final int flags,
|
||||||
final String installerPackageName) {
|
final String installerPackageName) {
|
||||||
mContext.enforceCallingOrSelfPermission(
|
installPackageWithVerification(packageURI, observer, flags, installerPackageName, null,
|
||||||
android.Manifest.permission.INSTALL_PACKAGES, null);
|
null);
|
||||||
|
}
|
||||||
|
|
||||||
Message msg = mHandler.obtainMessage(INIT_COPY);
|
@Override
|
||||||
msg.obj = new InstallParams(packageURI, observer, flags,
|
public void installPackageWithVerification(Uri packageURI, IPackageInstallObserver observer,
|
||||||
installerPackageName);
|
int flags, String installerPackageName, Uri verificationURI,
|
||||||
|
ManifestDigest manifestDigest) {
|
||||||
|
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
|
||||||
|
|
||||||
|
final int uid = Binder.getCallingUid();
|
||||||
|
|
||||||
|
final int filteredFlags;
|
||||||
|
|
||||||
|
if (uid == Process.SHELL_UID || uid == 0) {
|
||||||
|
if (DEBUG_INSTALL) {
|
||||||
|
Slog.v(TAG, "Install from ADB");
|
||||||
|
}
|
||||||
|
filteredFlags = flags | PackageManager.INSTALL_FROM_ADB;
|
||||||
|
} else {
|
||||||
|
filteredFlags = flags & ~PackageManager.INSTALL_FROM_ADB;
|
||||||
|
}
|
||||||
|
|
||||||
|
final Message msg = mHandler.obtainMessage(INIT_COPY);
|
||||||
|
msg.obj = new InstallParams(packageURI, observer, filteredFlags, installerPackageName,
|
||||||
|
verificationURI, manifestDigest);
|
||||||
|
mHandler.sendMessage(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void verifyPendingInstall(int id, boolean verified, String message)
|
||||||
|
throws RemoteException {
|
||||||
|
mContext.enforceCallingOrSelfPermission(
|
||||||
|
android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, null);
|
||||||
|
|
||||||
|
final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
|
||||||
|
msg.arg1 = id;
|
||||||
|
msg.arg2 = verified ? 1 : 0;
|
||||||
|
msg.obj = message;
|
||||||
mHandler.sendMessage(msg);
|
mHandler.sendMessage(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4713,6 +4817,28 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|||||||
mHandler.sendMessage(msg);
|
mHandler.sendMessage(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the verification agent timeout.
|
||||||
|
*
|
||||||
|
* @return verification timeout in milliseconds
|
||||||
|
*/
|
||||||
|
private long getVerificationTimeout() {
|
||||||
|
return android.provider.Settings.Secure.getLong(mContext.getContentResolver(),
|
||||||
|
android.provider.Settings.Secure.PACKAGE_VERIFIER_TIMEOUT,
|
||||||
|
DEFAULT_VERIFICATION_TIMEOUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether or not package verification has been enabled.
|
||||||
|
*
|
||||||
|
* @return true if verification should be performed
|
||||||
|
*/
|
||||||
|
private boolean isVerificationEnabled() {
|
||||||
|
return android.provider.Settings.Secure.getInt(mContext.getContentResolver(),
|
||||||
|
android.provider.Settings.Secure.PACKAGE_VERIFIER_ENABLE,
|
||||||
|
DEFAULT_VERIFY_ENABLE ? 1 : 0) == 1 ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
public void setInstallerPackageName(String targetPackage, String installerPackageName) {
|
public void setInstallerPackageName(String targetPackage, String installerPackageName) {
|
||||||
final int uid = Binder.getCallingUid();
|
final int uid = Binder.getCallingUid();
|
||||||
// writer
|
// writer
|
||||||
@@ -4856,15 +4982,21 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class HandlerParams {
|
private abstract class HandlerParams {
|
||||||
final static int MAX_RETRIES = 4;
|
private static final int MAX_RETRIES = 4;
|
||||||
int retry = 0;
|
|
||||||
|
/**
|
||||||
|
* Number of times startCopy() has been attempted and had a non-fatal
|
||||||
|
* error.
|
||||||
|
*/
|
||||||
|
private int mRetries = 0;
|
||||||
|
|
||||||
final boolean startCopy() {
|
final boolean startCopy() {
|
||||||
boolean res;
|
boolean res;
|
||||||
try {
|
try {
|
||||||
if (DEBUG_SD_INSTALL) Log.i(TAG, "startCopy");
|
if (DEBUG_INSTALL) Slog.i(TAG, "startCopy");
|
||||||
retry++;
|
|
||||||
if (retry > MAX_RETRIES) {
|
if (++mRetries > MAX_RETRIES) {
|
||||||
Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");
|
Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");
|
||||||
mHandler.sendEmptyMessage(MCS_GIVE_UP);
|
mHandler.sendEmptyMessage(MCS_GIVE_UP);
|
||||||
handleServiceError();
|
handleServiceError();
|
||||||
@@ -4874,7 +5006,7 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|||||||
res = true;
|
res = true;
|
||||||
}
|
}
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
if (DEBUG_SD_INSTALL) Log.i(TAG, "Posting install MCS_RECONNECT");
|
if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT");
|
||||||
mHandler.sendEmptyMessage(MCS_RECONNECT);
|
mHandler.sendEmptyMessage(MCS_RECONNECT);
|
||||||
res = false;
|
res = false;
|
||||||
}
|
}
|
||||||
@@ -4883,10 +5015,11 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final void serviceError() {
|
final void serviceError() {
|
||||||
if (DEBUG_SD_INSTALL) Log.i(TAG, "serviceError");
|
if (DEBUG_INSTALL) Slog.i(TAG, "serviceError");
|
||||||
handleServiceError();
|
handleServiceError();
|
||||||
handleReturnCode();
|
handleReturnCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract void handleStartCopy() throws RemoteException;
|
abstract void handleStartCopy() throws RemoteException;
|
||||||
abstract void handleServiceError();
|
abstract void handleServiceError();
|
||||||
abstract void handleReturnCode();
|
abstract void handleReturnCode();
|
||||||
@@ -4969,15 +5102,20 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|||||||
int flags;
|
int flags;
|
||||||
final Uri packageURI;
|
final Uri packageURI;
|
||||||
final String installerPackageName;
|
final String installerPackageName;
|
||||||
|
final Uri verificationURI;
|
||||||
|
final ManifestDigest manifestDigest;
|
||||||
private InstallArgs mArgs;
|
private InstallArgs mArgs;
|
||||||
private int mRet;
|
private int mRet;
|
||||||
|
|
||||||
InstallParams(Uri packageURI,
|
InstallParams(Uri packageURI,
|
||||||
IPackageInstallObserver observer, int flags,
|
IPackageInstallObserver observer, int flags,
|
||||||
String installerPackageName) {
|
String installerPackageName, Uri verificationURI, ManifestDigest manifestDigest) {
|
||||||
this.packageURI = packageURI;
|
this.packageURI = packageURI;
|
||||||
this.flags = flags;
|
this.flags = flags;
|
||||||
this.observer = observer;
|
this.observer = observer;
|
||||||
this.installerPackageName = installerPackageName;
|
this.installerPackageName = installerPackageName;
|
||||||
|
this.verificationURI = verificationURI;
|
||||||
|
this.manifestDigest = manifestDigest;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int installLocationPolicy(PackageInfoLite pkgLite, int flags) {
|
private int installLocationPolicy(PackageInfoLite pkgLite, int flags) {
|
||||||
@@ -5102,13 +5240,70 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Create the file args now.
|
|
||||||
mArgs = createInstallArgs(this);
|
final InstallArgs args = createInstallArgs(this);
|
||||||
if (ret == PackageManager.INSTALL_SUCCEEDED) {
|
if (ret == PackageManager.INSTALL_SUCCEEDED) {
|
||||||
// Create copy only if we are not in an erroneous state.
|
/*
|
||||||
// Remote call to initiate copy using temporary file
|
* Determine if we have any installed package verifiers. If we
|
||||||
ret = mArgs.copyApk(mContainerService, true);
|
* do, then we'll defer to them to verify the packages.
|
||||||
|
*/
|
||||||
|
final Intent verification = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION,
|
||||||
|
packageURI);
|
||||||
|
verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||||
|
|
||||||
|
final List<ResolveInfo> receivers = queryIntentReceivers(verification, null,
|
||||||
|
PackageManager.GET_DISABLED_COMPONENTS);
|
||||||
|
if (isVerificationEnabled() && receivers.size() > 0) {
|
||||||
|
if (DEBUG_INSTALL) {
|
||||||
|
Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
|
||||||
|
+ verification.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
final int verificationId = mPendingVerificationToken++;
|
||||||
|
|
||||||
|
verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
|
||||||
|
|
||||||
|
verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
|
||||||
|
installerPackageName);
|
||||||
|
|
||||||
|
verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS, flags);
|
||||||
|
|
||||||
|
if (verificationURI != null) {
|
||||||
|
verification.putExtra(PackageManager.EXTRA_VERIFICATION_URI,
|
||||||
|
verificationURI);
|
||||||
|
}
|
||||||
|
|
||||||
|
mPendingVerification.append(verificationId, args);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Send the intent to the registered verification agents,
|
||||||
|
* but only start the verification timeout after the target
|
||||||
|
* BroadcastReceivers have run.
|
||||||
|
*/
|
||||||
|
mContext.sendOrderedBroadcast(verification,
|
||||||
|
android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
|
||||||
|
new BroadcastReceiver() {
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
final Message msg = mHandler
|
||||||
|
.obtainMessage(CHECK_PENDING_VERIFICATION);
|
||||||
|
msg.arg1 = verificationId;
|
||||||
|
mHandler.sendMessageDelayed(msg, getVerificationTimeout());
|
||||||
|
}
|
||||||
|
},
|
||||||
|
null, 0, null, null);
|
||||||
|
} else {
|
||||||
|
// Create copy only if we are not in an erroneous state.
|
||||||
|
// Remote call to initiate copy using temporary file
|
||||||
|
mArgs = args;
|
||||||
|
ret = args.copyApk(mContainerService, true);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// There was an error, so let the processPendingInstall() break
|
||||||
|
// the bad news... uh, through a call in handleReturnCode()
|
||||||
|
mArgs = args;
|
||||||
}
|
}
|
||||||
|
|
||||||
mRet = ret;
|
mRet = ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5233,14 +5428,15 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|||||||
final int flags;
|
final int flags;
|
||||||
final Uri packageURI;
|
final Uri packageURI;
|
||||||
final String installerPackageName;
|
final String installerPackageName;
|
||||||
|
final ManifestDigest manifestDigest;
|
||||||
|
|
||||||
InstallArgs(Uri packageURI,
|
InstallArgs(Uri packageURI, IPackageInstallObserver observer, int flags,
|
||||||
IPackageInstallObserver observer, int flags,
|
String installerPackageName, ManifestDigest manifestDigest) {
|
||||||
String installerPackageName) {
|
|
||||||
this.packageURI = packageURI;
|
this.packageURI = packageURI;
|
||||||
this.flags = flags;
|
this.flags = flags;
|
||||||
this.observer = observer;
|
this.observer = observer;
|
||||||
this.installerPackageName = installerPackageName;
|
this.installerPackageName = installerPackageName;
|
||||||
|
this.manifestDigest = manifestDigest;
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract void createCopyFile();
|
abstract void createCopyFile();
|
||||||
@@ -5265,12 +5461,12 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|||||||
boolean created = false;
|
boolean created = false;
|
||||||
|
|
||||||
FileInstallArgs(InstallParams params) {
|
FileInstallArgs(InstallParams params) {
|
||||||
super(params.packageURI, params.observer,
|
super(params.packageURI, params.observer, params.flags, params.installerPackageName,
|
||||||
params.flags, params.installerPackageName);
|
params.manifestDigest);
|
||||||
}
|
}
|
||||||
|
|
||||||
FileInstallArgs(String fullCodePath, String fullResourcePath, String nativeLibraryPath) {
|
FileInstallArgs(String fullCodePath, String fullResourcePath, String nativeLibraryPath) {
|
||||||
super(null, null, 0, null);
|
super(null, null, 0, null, null);
|
||||||
File codeFile = new File(fullCodePath);
|
File codeFile = new File(fullCodePath);
|
||||||
installDir = codeFile.getParentFile();
|
installDir = codeFile.getParentFile();
|
||||||
codeFileName = fullCodePath;
|
codeFileName = fullCodePath;
|
||||||
@@ -5279,7 +5475,7 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
FileInstallArgs(Uri packageURI, String pkgName, String dataDir) {
|
FileInstallArgs(Uri packageURI, String pkgName, String dataDir) {
|
||||||
super(packageURI, null, 0, null);
|
super(packageURI, null, 0, null, null);
|
||||||
installDir = isFwdLocked() ? mDrmAppPrivateInstallDir : mAppInstallDir;
|
installDir = isFwdLocked() ? mDrmAppPrivateInstallDir : mAppInstallDir;
|
||||||
String apkName = getNextCodePath(null, pkgName, ".apk");
|
String apkName = getNextCodePath(null, pkgName, ".apk");
|
||||||
codeFileName = new File(installDir, apkName + ".apk").getPath();
|
codeFileName = new File(installDir, apkName + ".apk").getPath();
|
||||||
@@ -5509,12 +5705,12 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|||||||
String libraryPath;
|
String libraryPath;
|
||||||
|
|
||||||
SdInstallArgs(InstallParams params) {
|
SdInstallArgs(InstallParams params) {
|
||||||
super(params.packageURI, params.observer,
|
super(params.packageURI, params.observer, params.flags, params.installerPackageName,
|
||||||
params.flags, params.installerPackageName);
|
params.manifestDigest);
|
||||||
}
|
}
|
||||||
|
|
||||||
SdInstallArgs(String fullCodePath, String fullResourcePath, String nativeLibraryPath) {
|
SdInstallArgs(String fullCodePath, String fullResourcePath, String nativeLibraryPath) {
|
||||||
super(null, null, PackageManager.INSTALL_EXTERNAL, null);
|
super(null, null, PackageManager.INSTALL_EXTERNAL, null, null);
|
||||||
// Extract cid from fullCodePath
|
// Extract cid from fullCodePath
|
||||||
int eidx = fullCodePath.lastIndexOf("/");
|
int eidx = fullCodePath.lastIndexOf("/");
|
||||||
String subStr1 = fullCodePath.substring(0, eidx);
|
String subStr1 = fullCodePath.substring(0, eidx);
|
||||||
@@ -5524,13 +5720,13 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SdInstallArgs(String cid) {
|
SdInstallArgs(String cid) {
|
||||||
super(null, null, PackageManager.INSTALL_EXTERNAL, null);
|
super(null, null, PackageManager.INSTALL_EXTERNAL, null, null);
|
||||||
this.cid = cid;
|
this.cid = cid;
|
||||||
setCachePath(PackageHelper.getSdDir(cid));
|
setCachePath(PackageHelper.getSdDir(cid));
|
||||||
}
|
}
|
||||||
|
|
||||||
SdInstallArgs(Uri packageURI, String cid) {
|
SdInstallArgs(Uri packageURI, String cid) {
|
||||||
super(packageURI, null, PackageManager.INSTALL_EXTERNAL, null);
|
super(packageURI, null, PackageManager.INSTALL_EXTERNAL, null, null);
|
||||||
this.cid = cid;
|
this.cid = cid;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6152,6 +6348,26 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|||||||
res.returnCode = pp.getParseError();
|
res.returnCode = pp.getParseError();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If the installer passed in a manifest digest, compare it now. */
|
||||||
|
if (args.manifestDigest != null) {
|
||||||
|
if (DEBUG_INSTALL) {
|
||||||
|
final String parsedManifest = pkg.manifestDigest == null ? "null"
|
||||||
|
: pkg.manifestDigest.toString();
|
||||||
|
Slog.d(TAG, "Comparing manifests: " + args.manifestDigest.toString() + " vs. "
|
||||||
|
+ parsedManifest);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!args.manifestDigest.equals(pkg.manifestDigest)) {
|
||||||
|
res.returnCode = PackageManager.INSTALL_FAILED_PACKAGE_CHANGED;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else if (DEBUG_INSTALL) {
|
||||||
|
final String parsedManifest = pkg.manifestDigest == null
|
||||||
|
? "null" : pkg.manifestDigest.toString();
|
||||||
|
Slog.d(TAG, "manifestDigest was not present, but parser got: " + parsedManifest);
|
||||||
|
}
|
||||||
|
|
||||||
// Get rid of all references to package scan path via parser.
|
// Get rid of all references to package scan path via parser.
|
||||||
pp = null;
|
pp = null;
|
||||||
String oldCodePath = null;
|
String oldCodePath = null;
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ import android.content.pm.ProviderInfo;
|
|||||||
import android.content.pm.ResolveInfo;
|
import android.content.pm.ResolveInfo;
|
||||||
import android.content.pm.ServiceInfo;
|
import android.content.pm.ServiceInfo;
|
||||||
import android.content.pm.UserInfo;
|
import android.content.pm.UserInfo;
|
||||||
|
import android.content.pm.ManifestDigest;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.content.res.XmlResourceParser;
|
import android.content.res.XmlResourceParser;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
@@ -533,4 +534,22 @@ public class MockPackageManager extends PackageManager {
|
|||||||
public void updateUserFlags(int id, int flags) {
|
public void updateUserFlags(int id, int flags) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void installPackageWithVerification(Uri packageURI, IPackageInstallObserver observer,
|
||||||
|
int flags, String installerPackageName, Uri verificationURI,
|
||||||
|
ManifestDigest manifestDigest) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void verifyPendingInstall(int id, boolean verified, String failureMessage) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user