diff --git a/api/system-current.txt b/api/system-current.txt
index ad9f25cde3543..5e1b2fc8b8308 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 219258ef50b04..2337872a41441 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 c77c53f387e22..dffcc41cbbe62 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 companion 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 bc8019796d229..c7ec2cd6ca887 100644
--- a/core/java/com/android/internal/util/ArrayUtils.java
+++ b/core/java/com/android/internal/util/ArrayUtils.java
@@ -135,6 +135,13 @@ public class ArrayUtils {
return (T[]) cache;
}
+ /**
+ * Returns the same array or an empty one if it's null.
+ */
+ public static @NonNull T[] emptyIfNull(@Nullable T[] items, Class kind) {
+ return items != null ? items : emptyArray(kind);
+ }
+
/**
* Checks if given array is null or has zero elements.
*/
@@ -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[] filter(@Nullable T[] items,
+ @NonNull IntFunction arrayConstructor,
+ @NonNull java.util.function.Predicate 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 ba2f64d6db5f3..0f9df04f2bfb6 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1629,6 +1629,14 @@
+
+
+
+
+
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 85406c7e7cec3..367b9a82cc68b 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -3572,6 +3572,13 @@
- android.ext.services
+
+
+