diff options
-rwxr-xr-x | api/system-current.txt | 1 | ||||
-rw-r--r-- | api/test-current.txt | 1 | ||||
-rw-r--r-- | core/java/android/content/pm/PermissionInfo.java | 12 | ||||
-rw-r--r-- | core/java/com/android/internal/util/ArrayUtils.java | 43 | ||||
-rw-r--r-- | core/res/AndroidManifest.xml | 8 | ||||
-rw-r--r-- | core/res/res/values/attrs_manifest.xml | 3 | ||||
-rw-r--r-- | core/res/res/values/config.xml | 7 | ||||
-rw-r--r-- | packages/CompanionDeviceManager/Android.bp | 1 | ||||
-rw-r--r-- | packages/CompanionDeviceManager/AndroidManifest.xml | 1 | ||||
-rw-r--r-- | services/core/java/android/content/pm/PackageManagerInternal.java | 5 | ||||
-rw-r--r-- | services/core/java/com/android/server/pm/PackageManagerService.java | 24 | ||||
-rw-r--r-- | services/core/java/com/android/server/pm/permission/BasePermission.java | 3 | ||||
-rw-r--r-- | services/core/java/com/android/server/pm/permission/PermissionManagerService.java | 7 |
13 files changed, 114 insertions, 2 deletions
diff --git a/api/system-current.txt b/api/system-current.txt index ad9f25cde354..5e1b2fc8b830 100755 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -2175,6 +2175,7 @@ package android.content.pm { public class PermissionInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable { field public static final int FLAG_REMOVED = 2; // 0x2 field public static final int PROTECTION_FLAG_APP_PREDICTOR = 2097152; // 0x200000 + field public static final int PROTECTION_FLAG_COMPANION = 8388608; // 0x800000 field public static final int PROTECTION_FLAG_CONFIGURATOR = 524288; // 0x80000 field public static final int PROTECTION_FLAG_DOCUMENTER = 262144; // 0x40000 field public static final int PROTECTION_FLAG_INCIDENT_REPORT_APPROVER = 1048576; // 0x100000 diff --git a/api/test-current.txt b/api/test-current.txt index 219258ef50b0..2337872a4144 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -809,6 +809,7 @@ package android.content.pm { public class PermissionInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable { field public static final int FLAG_REMOVED = 2; // 0x2 field public static final int PROTECTION_FLAG_APP_PREDICTOR = 2097152; // 0x200000 + field public static final int PROTECTION_FLAG_COMPANION = 8388608; // 0x800000 field public static final int PROTECTION_FLAG_CONFIGURATOR = 524288; // 0x80000 field public static final int PROTECTION_FLAG_DOCUMENTER = 262144; // 0x40000 field public static final int PROTECTION_FLAG_INCIDENT_REPORT_APPROVER = 1048576; // 0x100000 diff --git a/core/java/android/content/pm/PermissionInfo.java b/core/java/android/content/pm/PermissionInfo.java index c77c53f387e2..dffcc41cbbe6 100644 --- a/core/java/android/content/pm/PermissionInfo.java +++ b/core/java/android/content/pm/PermissionInfo.java @@ -248,6 +248,17 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable { @TestApi public static final int PROTECTION_FLAG_TELEPHONY = 0x400000; + /** + * Additional flag for {@link #protectionLevel}, corresponding + * to the <code>companion</code> value of + * {@link android.R.attr#protectionLevel}. + * + * @hide + */ + @SystemApi + @TestApi + public static final int PROTECTION_FLAG_COMPANION = 0x800000; + /** @hide */ @IntDef(flag = true, prefix = { "PROTECTION_FLAG_" }, value = { PROTECTION_FLAG_PRIVILEGED, @@ -270,6 +281,7 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable { PROTECTION_FLAG_INCIDENT_REPORT_APPROVER, PROTECTION_FLAG_APP_PREDICTOR, PROTECTION_FLAG_TELEPHONY, + PROTECTION_FLAG_COMPANION, }) @Retention(RetentionPolicy.SOURCE) public @interface ProtectionFlags {} diff --git a/core/java/com/android/internal/util/ArrayUtils.java b/core/java/com/android/internal/util/ArrayUtils.java index bc8019796d22..c7ec2cd6ca88 100644 --- a/core/java/com/android/internal/util/ArrayUtils.java +++ b/core/java/com/android/internal/util/ArrayUtils.java @@ -136,6 +136,13 @@ public class ArrayUtils { } /** + * Returns the same array or an empty one if it's null. + */ + public static @NonNull <T> T[] emptyIfNull(@Nullable T[] items, Class<T> kind) { + return items != null ? items : emptyArray(kind); + } + + /** * Checks if given array is null or has zero elements. */ public static boolean isEmpty(@Nullable Collection<?> array) { @@ -751,6 +758,42 @@ public class ArrayUtils { return result; } + /** + * Returns an array containing elements from the given one that match the given predicate. + */ + public static @Nullable <T> T[] filter(@Nullable T[] items, + @NonNull IntFunction<T[]> arrayConstructor, + @NonNull java.util.function.Predicate<T> predicate) { + if (isEmpty(items)) { + return items; + } + + int matchesCount = 0; + int size = size(items); + for (int i = 0; i < size; i++) { + if (predicate.test(items[i])) { + matchesCount++; + } + } + if (matchesCount == 0) { + return items; + } + if (matchesCount == items.length) { + return items; + } + if (matchesCount == 0) { + return null; + } + T[] result = arrayConstructor.apply(matchesCount); + int outIdx = 0; + for (int i = 0; i < size; i++) { + if (predicate.test(items[i])) { + result[outIdx++] = items[i]; + } + } + return result; + } + public static boolean startsWith(byte[] cur, byte[] val) { if (cur == null || val == null) return false; if (cur.length < val.length) return false; diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index ba2f64d6db5f..0f9df04f2bfb 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -1629,6 +1629,14 @@ <permission android:name="android.permission.NETWORK_SETTINGS" android:protectionLevel="signature|telephony" /> + <!-- Allows holder to request bluetooth/wifi scan bypassing global "use location" setting and + location permissions. + <p>Not for use by third-party or privileged applications. + @hide + --> + <permission android:name="android.permission.RADIO_SCAN_WITHOUT_LOCATION" + android:protectionLevel="signature|companion" /> + <!-- Allows SetupWizard to call methods in Networking services <p>Not for use by any other third-party or privileged applications. @SystemApi diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml index 166cde0d7005..b17d473409ac 100644 --- a/core/res/res/values/attrs_manifest.xml +++ b/core/res/res/values/attrs_manifest.xml @@ -298,6 +298,9 @@ <!-- Additional flag from base permission type: this permission can be automatically granted to the system telephony apps --> <flag name="telephony" value="0x400000" /> + <!-- Additional flag from base permission type: this permission can be automatically + granted to the system companion device manager service --> + <flag name="companion" value="0x800000" /> </attr> <!-- Flags indicating more context for a permission group. --> diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 85406c7e7cec..367b9a82cc68 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -3572,6 +3572,13 @@ <item>android.ext.services</item> </string-array> + <!-- The package name for the system companion device manager service. + This service must be trusted, as it can be activated without explicit consent of the user. + Example: "com.android.companiondevicemanager" + See android.companion.CompanionDeviceManager. + --> + <string name="config_companionDeviceManagerPackage" translatable="false"></string> + <!-- The package name for the default wellbeing app. This package must be trusted, as it has the permissions to control other applications on the device. diff --git a/packages/CompanionDeviceManager/Android.bp b/packages/CompanionDeviceManager/Android.bp index a379bfccbe29..1453ec3b63cb 100644 --- a/packages/CompanionDeviceManager/Android.bp +++ b/packages/CompanionDeviceManager/Android.bp @@ -15,5 +15,6 @@ android_app { name: "CompanionDeviceManager", srcs: ["src/**/*.java"], + platform_apis: true, } diff --git a/packages/CompanionDeviceManager/AndroidManifest.xml b/packages/CompanionDeviceManager/AndroidManifest.xml index 42885e8193a7..a9c668599a2a 100644 --- a/packages/CompanionDeviceManager/AndroidManifest.xml +++ b/packages/CompanionDeviceManager/AndroidManifest.xml @@ -29,6 +29,7 @@ <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/> + <uses-permission android:name="android.permission.RADIO_SCAN_WITHOUT_LOCATION"/> <application android:allowClearUserData="true" diff --git a/services/core/java/android/content/pm/PackageManagerInternal.java b/services/core/java/android/content/pm/PackageManagerInternal.java index d2f1113ec5a9..78f278e2f049 100644 --- a/services/core/java/android/content/pm/PackageManagerInternal.java +++ b/services/core/java/android/content/pm/PackageManagerInternal.java @@ -63,6 +63,9 @@ public abstract class PackageManagerInternal { public static final int PACKAGE_INCIDENT_REPORT_APPROVER = 10; public static final int PACKAGE_APP_PREDICTOR = 11; public static final int PACKAGE_TELEPHONY = 12; + public static final int PACKAGE_WIFI = 13; + public static final int PACKAGE_COMPANION = 14; + @IntDef(value = { PACKAGE_SYSTEM, PACKAGE_SETUP_WIZARD, @@ -77,6 +80,8 @@ public abstract class PackageManagerInternal { PACKAGE_INCIDENT_REPORT_APPROVER, PACKAGE_APP_PREDICTOR, PACKAGE_TELEPHONY, + PACKAGE_WIFI, + PACKAGE_COMPANION, }) @Retention(RetentionPolicy.SOURCE) public @interface KnownPackage {} diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index cb362b0f0a23..99515a4cf304 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -96,6 +96,8 @@ import static com.android.internal.annotations.VisibleForTesting.Visibility; import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE; import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_PARENT; import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME; +import static com.android.internal.util.ArrayUtils.emptyIfNull; +import static com.android.internal.util.ArrayUtils.filter; import static com.android.server.pm.ComponentResolver.RESOLVE_PRIORITY_SORTER; import static com.android.server.pm.InstructionSets.getAppDexInstructionSets; import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet; @@ -249,7 +251,6 @@ import android.os.storage.VolumeInfo; import android.os.storage.VolumeRecord; import android.permission.IPermissionManager; import android.provider.DeviceConfig; -import android.provider.MediaStore; import android.provider.Settings.Global; import android.provider.Settings.Secure; import android.security.KeyStore; @@ -385,6 +386,7 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.BiConsumer; import java.util.function.Consumer; +import java.util.function.Predicate; import java.util.stream.Collectors; /** @@ -19261,6 +19263,18 @@ public class PackageManagerService extends IPackageManager.Stub return ensureSystemPackageName(appPredictionServiceComponentName.getPackageName()); } + private @NonNull String[] dropNonSystemPackages(@NonNull String[] pkgNames) { + return emptyIfNull(filter(pkgNames, String[]::new, mIsSystemPackage), String.class); + } + + private Predicate<String> mIsSystemPackage = (pkgName) -> { + if ("android".equals(pkgName)) { + return true; + } + AndroidPackage pkg = mPackages.get(pkgName); + return pkg != null && pkg.isSystem(); + }; + @Override public String getSystemCaptionsServicePackageName() { String flattenedSystemCaptionsServiceComponentName = @@ -22539,7 +22553,11 @@ public class PackageManagerService extends IPackageManager.Stub @Override public @NonNull String[] getKnownPackageNames(int knownPackage, int userId) { - switch (knownPackage) { + return dropNonSystemPackages(getKnownPackageNamesInternal(knownPackage, userId)); + } + + private String[] getKnownPackageNamesInternal(int knownPackage, int userId) { + switch(knownPackage) { case PackageManagerInternal.PACKAGE_BROWSER: return new String[]{mPermissionManager.getDefaultBrowser(userId)}; case PackageManagerInternal.PACKAGE_INSTALLER: @@ -22566,6 +22584,8 @@ public class PackageManagerService extends IPackageManager.Stub return filterOnlySystemPackages(mAppPredictionServicePackage); case PackageManagerInternal.PACKAGE_TELEPHONY: return filterOnlySystemPackages(mTelephonyPackages); + case PackageManagerInternal.PACKAGE_COMPANION: + return filterOnlySystemPackages("com.android.companiondevicemanager"); default: return ArrayUtils.emptyArray(String.class); } diff --git a/services/core/java/com/android/server/pm/permission/BasePermission.java b/services/core/java/com/android/server/pm/permission/BasePermission.java index 05545cdbe50a..565a85fd1ac1 100644 --- a/services/core/java/com/android/server/pm/permission/BasePermission.java +++ b/services/core/java/com/android/server/pm/permission/BasePermission.java @@ -280,6 +280,9 @@ public final class BasePermission { public boolean isTelephony() { return (protectionLevel & PermissionInfo.PROTECTION_FLAG_TELEPHONY) != 0; } + public boolean isCompanion() { + return (protectionLevel & PermissionInfo.PROTECTION_FLAG_COMPANION) != 0; + } public void transfer(@NonNull String origPackageName, @NonNull String newPackageName) { if (!origPackageName.equals(sourcePackageName)) { diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java index 8ce1a52afd0c..a6617a9161f4 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java @@ -3279,6 +3279,13 @@ public class PermissionManagerService extends IPermissionManager.Stub { // Special permissions for the system telephony apps. allowed = true; } + if (!allowed && bp.isCompanion() + && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames( + PackageManagerInternal.PACKAGE_COMPANION, UserHandle.USER_SYSTEM), + pkg.getPackageName())) { + // Special permissions for the system companion device manager. + allowed = true; + } } return allowed; } |