Merge changes from topic "installPackages"
* changes: Allow installing DPCs with INSTALL_DPC_PACKAGES Add new INSTALL_DPC_PACKAGES permission
This commit is contained in:
committed by
Android (Google) Code Review
commit
8efd85d97a
@@ -118,6 +118,7 @@ package android {
|
||||
field public static final String HDMI_CEC = "android.permission.HDMI_CEC";
|
||||
field @Deprecated public static final String HIDE_NON_SYSTEM_OVERLAY_WINDOWS = "android.permission.HIDE_NON_SYSTEM_OVERLAY_WINDOWS";
|
||||
field public static final String INJECT_EVENTS = "android.permission.INJECT_EVENTS";
|
||||
field public static final String INSTALL_DPC_PACKAGES = "android.permission.INSTALL_DPC_PACKAGES";
|
||||
field public static final String INSTALL_DYNAMIC_SYSTEM = "android.permission.INSTALL_DYNAMIC_SYSTEM";
|
||||
field public static final String INSTALL_GRANT_RUNTIME_PERMISSIONS = "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS";
|
||||
field public static final String INSTALL_LOCATION_TIME_ZONE_PROVIDER_SERVICE = "android.permission.INSTALL_LOCATION_TIME_ZONE_PROVIDER_SERVICE";
|
||||
|
||||
@@ -128,6 +128,11 @@ public class ApkLite {
|
||||
*/
|
||||
private final int mRollbackDataPolicy;
|
||||
|
||||
/**
|
||||
* Indicates if this app contains a {@link android.app.admin.DeviceAdminReceiver}.
|
||||
*/
|
||||
private final boolean mHasDeviceAdminReceiver;
|
||||
|
||||
public ApkLite(String path, String packageName, String splitName, boolean isFeatureSplit,
|
||||
String configForSplit, String usesSplitName, boolean isSplitRequired, int versionCode,
|
||||
int versionCodeMajor, int revisionCode, int installLocation,
|
||||
@@ -137,7 +142,8 @@ public class ApkLite {
|
||||
String targetPackageName, boolean overlayIsStatic, int overlayPriority,
|
||||
String requiredSystemPropertyName, String requiredSystemPropertyValue,
|
||||
int minSdkVersion, int targetSdkVersion, int rollbackDataPolicy,
|
||||
Set<String> requiredSplitTypes, Set<String> splitTypes) {
|
||||
Set<String> requiredSplitTypes, Set<String> splitTypes,
|
||||
boolean hasDeviceAdminReceiver) {
|
||||
mPath = path;
|
||||
mPackageName = packageName;
|
||||
mSplitName = splitName;
|
||||
@@ -169,6 +175,7 @@ public class ApkLite {
|
||||
mMinSdkVersion = minSdkVersion;
|
||||
mTargetSdkVersion = targetSdkVersion;
|
||||
mRollbackDataPolicy = rollbackDataPolicy;
|
||||
mHasDeviceAdminReceiver = hasDeviceAdminReceiver;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -461,11 +468,16 @@ public class ApkLite {
|
||||
return mRollbackDataPolicy;
|
||||
}
|
||||
|
||||
@DataClass.Generated.Member
|
||||
public boolean isHasDeviceAdminReceiver() {
|
||||
return mHasDeviceAdminReceiver;
|
||||
}
|
||||
|
||||
@DataClass.Generated(
|
||||
time = 1631763761543L,
|
||||
time = 1635266936769L,
|
||||
codegenVersion = "1.0.23",
|
||||
sourceFile = "frameworks/base/core/java/android/content/pm/parsing/ApkLite.java",
|
||||
inputSignatures = "private final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.NonNull java.lang.String mPath\nprivate final @android.annotation.Nullable java.lang.String mSplitName\nprivate final @android.annotation.Nullable java.lang.String mUsesSplitName\nprivate final @android.annotation.Nullable java.lang.String mConfigForSplit\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mSplitTypes\nprivate final int mVersionCodeMajor\nprivate final int mVersionCode\nprivate final int mRevisionCode\nprivate final int mInstallLocation\nprivate final int mMinSdkVersion\nprivate final int mTargetSdkVersion\nprivate final @android.annotation.NonNull android.content.pm.VerifierInfo[] mVerifiers\nprivate final @android.annotation.NonNull android.content.pm.SigningDetails mSigningDetails\nprivate final boolean mFeatureSplit\nprivate final boolean mIsolatedSplits\nprivate final boolean mSplitRequired\nprivate final boolean mCoreApp\nprivate final boolean mDebuggable\nprivate final boolean mProfileableByShell\nprivate final boolean mMultiArch\nprivate final boolean mUse32bitAbi\nprivate final boolean mExtractNativeLibs\nprivate final boolean mUseEmbeddedDex\nprivate final @android.annotation.Nullable java.lang.String mTargetPackageName\nprivate final boolean mOverlayIsStatic\nprivate final int mOverlayPriority\nprivate final @android.annotation.Nullable java.lang.String mRequiredSystemPropertyName\nprivate final @android.annotation.Nullable java.lang.String mRequiredSystemPropertyValue\nprivate final int mRollbackDataPolicy\npublic long getLongVersionCode()\nprivate boolean hasAnyRequiredSplitTypes()\nclass ApkLite extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genConstDefs=false)")
|
||||
inputSignatures = "private final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.NonNull java.lang.String mPath\nprivate final @android.annotation.Nullable java.lang.String mSplitName\nprivate final @android.annotation.Nullable java.lang.String mUsesSplitName\nprivate final @android.annotation.Nullable java.lang.String mConfigForSplit\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mSplitTypes\nprivate final int mVersionCodeMajor\nprivate final int mVersionCode\nprivate final int mRevisionCode\nprivate final int mInstallLocation\nprivate final int mMinSdkVersion\nprivate final int mTargetSdkVersion\nprivate final @android.annotation.NonNull android.content.pm.VerifierInfo[] mVerifiers\nprivate final @android.annotation.NonNull android.content.pm.SigningDetails mSigningDetails\nprivate final boolean mFeatureSplit\nprivate final boolean mIsolatedSplits\nprivate final boolean mSplitRequired\nprivate final boolean mCoreApp\nprivate final boolean mDebuggable\nprivate final boolean mProfileableByShell\nprivate final boolean mMultiArch\nprivate final boolean mUse32bitAbi\nprivate final boolean mExtractNativeLibs\nprivate final boolean mUseEmbeddedDex\nprivate final @android.annotation.Nullable java.lang.String mTargetPackageName\nprivate final boolean mOverlayIsStatic\nprivate final int mOverlayPriority\nprivate final @android.annotation.Nullable java.lang.String mRequiredSystemPropertyName\nprivate final @android.annotation.Nullable java.lang.String mRequiredSystemPropertyValue\nprivate final int mRollbackDataPolicy\nprivate final boolean mHasDeviceAdminReceiver\npublic long getLongVersionCode()\nprivate boolean hasAnyRequiredSplitTypes()\nclass ApkLite extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genConstDefs=false)")
|
||||
@Deprecated
|
||||
private void __metadata() {}
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ import static android.content.pm.parsing.ParsingUtils.DEFAULT_TARGET_SDK_VERSION
|
||||
import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.app.admin.DeviceAdminReceiver;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.SigningDetails;
|
||||
@@ -399,6 +400,8 @@ public class ApkLiteParseUtils {
|
||||
String requiredSystemPropertyName = null;
|
||||
String requiredSystemPropertyValue = null;
|
||||
|
||||
boolean hasDeviceAdminReceiver = false;
|
||||
|
||||
// Only search the tree when the tag is the direct child of <manifest> tag
|
||||
int type;
|
||||
final int searchDepth = parser.getDepth() + 1;
|
||||
@@ -432,6 +435,10 @@ public class ApkLiteParseUtils {
|
||||
"useEmbeddedDex", false);
|
||||
rollbackDataPolicy = parser.getAttributeIntValue(ANDROID_RES_NAMESPACE,
|
||||
"rollbackDataPolicy", 0);
|
||||
String permission = parser.getAttributeValue(ANDROID_RES_NAMESPACE,
|
||||
"permission");
|
||||
boolean hasBindDeviceAdminPermission =
|
||||
android.Manifest.permission.BIND_DEVICE_ADMIN.equals(permission);
|
||||
|
||||
final int innerDepth = parser.getDepth();
|
||||
int innerType;
|
||||
@@ -449,6 +456,9 @@ public class ApkLiteParseUtils {
|
||||
if (ParsingPackageUtils.TAG_PROFILEABLE.equals(parser.getName())) {
|
||||
profilableByShell = parser.getAttributeBooleanValue(ANDROID_RES_NAMESPACE,
|
||||
"shell", profilableByShell);
|
||||
} else if (ParsingPackageUtils.TAG_RECEIVER.equals(parser.getName())) {
|
||||
hasDeviceAdminReceiver |= isDeviceAdminReceiver(
|
||||
parser, hasBindDeviceAdminPermission);
|
||||
}
|
||||
}
|
||||
} else if (ParsingPackageUtils.TAG_OVERLAY.equals(parser.getName())) {
|
||||
@@ -541,7 +551,42 @@ public class ApkLiteParseUtils {
|
||||
useEmbeddedDex, extractNativeLibs, isolatedSplits, targetPackage,
|
||||
overlayIsStatic, overlayPriority, requiredSystemPropertyName,
|
||||
requiredSystemPropertyValue, minSdkVersion, targetSdkVersion,
|
||||
rollbackDataPolicy, requiredSplitTypes.first, requiredSplitTypes.second));
|
||||
rollbackDataPolicy, requiredSplitTypes.first, requiredSplitTypes.second,
|
||||
hasDeviceAdminReceiver));
|
||||
}
|
||||
|
||||
private static boolean isDeviceAdminReceiver(
|
||||
XmlResourceParser parser, boolean applicationHasBindDeviceAdminPermission)
|
||||
throws XmlPullParserException, IOException {
|
||||
String permission = parser.getAttributeValue(ANDROID_RES_NAMESPACE,
|
||||
"permission");
|
||||
if (!applicationHasBindDeviceAdminPermission
|
||||
&& !android.Manifest.permission.BIND_DEVICE_ADMIN.equals(permission)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean hasDeviceAdminReceiver = false;
|
||||
final int depth = parser.getDepth();
|
||||
int type;
|
||||
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
|
||||
&& (type != XmlPullParser.END_TAG || parser.getDepth() > depth)) {
|
||||
if (type == XmlPullParser.END_TAG
|
||||
|| type == XmlPullParser.TEXT) {
|
||||
continue;
|
||||
}
|
||||
if (parser.getDepth() != depth + 1) {
|
||||
// Search only under <receiver>.
|
||||
continue;
|
||||
}
|
||||
if (!hasDeviceAdminReceiver && "meta-data".equals(parser.getName())) {
|
||||
String name = parser.getAttributeValue(ANDROID_RES_NAMESPACE,
|
||||
"name");
|
||||
if (DeviceAdminReceiver.DEVICE_ADMIN_META_DATA.equals(name)) {
|
||||
hasDeviceAdminReceiver = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return hasDeviceAdminReceiver;
|
||||
}
|
||||
|
||||
public static ParseResult<Pair<String, String>> parsePackageSplitNames(ParseInput input,
|
||||
|
||||
@@ -52,7 +52,6 @@ import android.content.pm.SigningDetails;
|
||||
import android.content.pm.parsing.component.ComponentMutateUtils;
|
||||
import android.content.pm.parsing.component.ComponentParseUtils;
|
||||
import android.content.pm.parsing.component.ParsedActivity;
|
||||
import android.content.pm.parsing.component.ParsedActivityImpl;
|
||||
import android.content.pm.parsing.component.ParsedActivityUtils;
|
||||
import android.content.pm.parsing.component.ParsedAttribution;
|
||||
import android.content.pm.parsing.component.ParsedAttributionUtils;
|
||||
@@ -191,6 +190,7 @@ public class ParsingPackageUtils {
|
||||
public static final String TAG_USES_SDK = "uses-sdk";
|
||||
public static final String TAG_USES_SPLIT = "uses-split";
|
||||
public static final String TAG_PROFILEABLE = "profileable";
|
||||
public static final String TAG_RECEIVER = "receiver";
|
||||
|
||||
public static final String METADATA_MAX_ASPECT_RATIO = "android.max_aspect";
|
||||
public static final String METADATA_SUPPORTS_SIZE_CHANGES = "android.supports_size_changes";
|
||||
|
||||
@@ -4215,6 +4215,16 @@
|
||||
<permission android:name="android.permission.INSTALL_TEST_ONLY_PACKAGE"
|
||||
android:protectionLevel="signature" />
|
||||
|
||||
<!-- @SystemApi Allows an application to install DPCs only, an application is
|
||||
considered a DPC if it has a {@link android.app.admin.DeviceAdminReceiver}
|
||||
protected by {@link android.Manifest.permission#BIND_DEVICE_ADMIN).
|
||||
This is a limited version of
|
||||
{@link android.Manifest.permission#INSTALL_PACKAGES}.
|
||||
@hide
|
||||
-->
|
||||
<permission android:name="android.permission.INSTALL_DPC_PACKAGES"
|
||||
android:protectionLevel="signature|role" />
|
||||
|
||||
<!-- Allows an application to use System Data Loaders.
|
||||
<p>Not for use by third-party applications.
|
||||
@hide
|
||||
|
||||
@@ -162,6 +162,7 @@
|
||||
<uses-permission android:name="android.permission.SET_ORIENTATION" />
|
||||
<uses-permission android:name="android.permission.INSTALL_PACKAGES" />
|
||||
<uses-permission android:name="android.permission.INSTALL_PACKAGE_UPDATES" />
|
||||
<uses-permission android:name="android.permission.INSTALL_DPC_PACKAGES" />
|
||||
<uses-permission android:name="com.android.permission.USE_INSTALLER_V2" />
|
||||
<uses-permission android:name="android.permission.INSTALL_TEST_ONLY_PACKAGE" />
|
||||
<uses-permission android:name="com.android.permission.USE_SYSTEM_DATA_LOADERS" />
|
||||
|
||||
@@ -392,6 +392,9 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
@GuardedBy("mLock")
|
||||
private int mParentSessionId;
|
||||
|
||||
@GuardedBy("mLock")
|
||||
private boolean mHasDeviceAdminReceiver;
|
||||
|
||||
static class FileEntry {
|
||||
private final int mIndex;
|
||||
private final InstallationFile mFile;
|
||||
@@ -927,11 +930,13 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
@UserActionRequirement
|
||||
private int computeUserActionRequirement() {
|
||||
final String packageName;
|
||||
final boolean hasDeviceAdminReceiver;
|
||||
synchronized (mLock) {
|
||||
if (mPermissionsManuallyAccepted) {
|
||||
return USER_ACTION_NOT_NEEDED;
|
||||
}
|
||||
packageName = mPackageName;
|
||||
hasDeviceAdminReceiver = mHasDeviceAdminReceiver;
|
||||
}
|
||||
|
||||
final boolean forcePermissionPrompt =
|
||||
@@ -954,6 +959,9 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
final boolean isUpdateWithoutUserActionPermissionGranted = (mPm.checkUidPermission(
|
||||
android.Manifest.permission.UPDATE_PACKAGES_WITHOUT_USER_ACTION, mInstallerUid)
|
||||
== PackageManager.PERMISSION_GRANTED);
|
||||
final boolean isInstallDpcPackagesPermissionGranted = (mPm.checkUidPermission(
|
||||
android.Manifest.permission.INSTALL_DPC_PACKAGES, mInstallerUid)
|
||||
== PackageManager.PERMISSION_GRANTED);
|
||||
final int targetPackageUid = mPm.getPackageUid(packageName, 0, userId);
|
||||
final boolean isUpdate = targetPackageUid != -1 || isApexSession();
|
||||
final InstallSourceInfo existingInstallSourceInfo = isUpdate
|
||||
@@ -967,7 +975,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
final boolean isSelfUpdate = targetPackageUid == mInstallerUid;
|
||||
final boolean isPermissionGranted = isInstallPermissionGranted
|
||||
|| (isUpdatePermissionGranted && isUpdate)
|
||||
|| (isSelfUpdatePermissionGranted && isSelfUpdate);
|
||||
|| (isSelfUpdatePermissionGranted && isSelfUpdate)
|
||||
|| (isInstallDpcPackagesPermissionGranted && hasDeviceAdminReceiver);
|
||||
final boolean isInstallerRoot = (mInstallerUid == Process.ROOT_UID);
|
||||
final boolean isInstallerSystem = (mInstallerUid == Process.SYSTEM_UID);
|
||||
|
||||
@@ -2854,6 +2863,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
}
|
||||
|
||||
mSigningDetails = apk.getSigningDetails();
|
||||
mHasDeviceAdminReceiver = apk.isHasDeviceAdminReceiver();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2944,6 +2954,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
if (mSigningDetails == SigningDetails.UNKNOWN) {
|
||||
mSigningDetails = apk.getSigningDetails();
|
||||
}
|
||||
mHasDeviceAdminReceiver = apk.isHasDeviceAdminReceiver();
|
||||
|
||||
assertApkConsistentLocked(String.valueOf(addedFile), apk);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user