diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 0b044bee9e64f..505d246e4df89 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -2280,6 +2280,7 @@ package android.content.pm {
field public static final int PROTECTION_FLAG_DOCUMENTER = 262144; // 0x40000
field public static final int PROTECTION_FLAG_INCIDENT_REPORT_APPROVER = 1048576; // 0x100000
field public static final int PROTECTION_FLAG_OEM = 16384; // 0x4000
+ field public static final int PROTECTION_FLAG_RECENTS = 33554432; // 0x2000000
field public static final int PROTECTION_FLAG_RETAIL_DEMO = 16777216; // 0x1000000
field public static final int PROTECTION_FLAG_SYSTEM_TEXT_CLASSIFIER = 65536; // 0x10000
field public static final int PROTECTION_FLAG_WELLBEING = 131072; // 0x20000
diff --git a/core/java/android/content/pm/PermissionInfo.java b/core/java/android/content/pm/PermissionInfo.java
index c6450ffdf91c7..cd9ba6a5b4516 100644
--- a/core/java/android/content/pm/PermissionInfo.java
+++ b/core/java/android/content/pm/PermissionInfo.java
@@ -251,6 +251,16 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable {
@SystemApi
public static final int PROTECTION_FLAG_RETAIL_DEMO = 0x1000000;
+ /**
+ * Additional flag for {@link #protectionLevel}, corresponding
+ * to the recents value of
+ * {@link android.R.attr#protectionLevel}.
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final int PROTECTION_FLAG_RECENTS = 0x2000000;
+
/** @hide */
@IntDef(flag = true, prefix = { "PROTECTION_FLAG_" }, value = {
PROTECTION_FLAG_PRIVILEGED,
@@ -274,6 +284,7 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable {
PROTECTION_FLAG_APP_PREDICTOR,
PROTECTION_FLAG_COMPANION,
PROTECTION_FLAG_RETAIL_DEMO,
+ PROTECTION_FLAG_RECENTS,
})
@Retention(RetentionPolicy.SOURCE)
public @interface ProtectionFlags {}
@@ -532,6 +543,9 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable {
if ((level & PermissionInfo.PROTECTION_FLAG_RETAIL_DEMO) != 0) {
protLevel.append("|retailDemo");
}
+ if ((level & PermissionInfo.PROTECTION_FLAG_RECENTS) != 0) {
+ protLevel.append("|recents");
+ }
return protLevel.toString();
}
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index c32e8dc944865..85b19e7de04bb 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -303,6 +303,9 @@
+
+
diff --git a/services/core/java/android/content/pm/PackageManagerInternal.java b/services/core/java/android/content/pm/PackageManagerInternal.java
index f20566280bc8e..6989e320f4653 100644
--- a/services/core/java/android/content/pm/PackageManagerInternal.java
+++ b/services/core/java/android/content/pm/PackageManagerInternal.java
@@ -77,6 +77,7 @@ public abstract class PackageManagerInternal {
PACKAGE_WIFI,
PACKAGE_COMPANION,
PACKAGE_RETAIL_DEMO,
+ PACKAGE_RECENTS,
})
@Retention(RetentionPolicy.SOURCE)
public @interface KnownPackage {}
@@ -97,9 +98,10 @@ public abstract class PackageManagerInternal {
public static final int PACKAGE_WIFI = 13;
public static final int PACKAGE_COMPANION = 14;
public static final int PACKAGE_RETAIL_DEMO = 15;
+ public static final int PACKAGE_RECENTS = 16;
// Integer value of the last known package ID. Increases as new ID is added to KnownPackage.
// Please note the numbers should be continuous.
- public static final int LAST_KNOWN_PACKAGE = PACKAGE_RETAIL_DEMO;
+ public static final int LAST_KNOWN_PACKAGE = PACKAGE_RECENTS;
@IntDef(flag = true, prefix = "RESOLVE_", value = {
RESOLVE_NON_BROWSER_ONLY,
@@ -1060,6 +1062,8 @@ public abstract class PackageManagerInternal {
return "Retail Demo";
case PACKAGE_OVERLAY_CONFIG_SIGNATURE:
return "Overlay Config Signature";
+ case PACKAGE_RECENTS:
+ return "Recents";
}
return "Unknown";
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 38807112576a4..55f9feec10d3f 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -141,6 +141,7 @@ import android.annotation.AppIdInt;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.StringRes;
import android.annotation.UserIdInt;
import android.annotation.WorkerThread;
import android.app.ActivityManager;
@@ -1203,6 +1204,7 @@ public class PackageManagerService extends IPackageManager.Stub
public ViewCompiler viewCompiler;
public @Nullable String wellbeingPackage;
public @Nullable String retailDemoPackage;
+ public @Nullable String recentsPackage;
public ComponentName resolveComponentName;
public ArrayMap packages;
public boolean enableFreeCacheV2;
@@ -1737,6 +1739,7 @@ public class PackageManagerService extends IPackageManager.Stub
final @Nullable String mSharedSystemSharedLibraryPackageName;
final @Nullable String mRetailDemoPackage;
final @Nullable String mOverlayConfigSignaturePackage;
+ final @Nullable String mRecentsPackage;
private final PackageUsage mPackageUsage = new PackageUsage();
private final CompilerStats mCompilerStats = new CompilerStats();
@@ -2980,6 +2983,7 @@ public class PackageManagerService extends IPackageManager.Stub
mSystemTextClassifierPackageName = testParams.systemTextClassifierPackage;
mWellbeingPackage = testParams.wellbeingPackage;
mRetailDemoPackage = testParams.retailDemoPackage;
+ mRecentsPackage = testParams.recentsPackage;
mDocumenterPackage = testParams.documenterPackage;
mConfiguratorPackage = testParams.configuratorPackage;
mAppPredictionServicePackage = testParams.appPredictionServicePackage;
@@ -3564,6 +3568,7 @@ public class PackageManagerService extends IPackageManager.Stub
mIncidentReportApproverPackage = getIncidentReportApproverPackageName();
mRetailDemoPackage = getRetailDemoPackageName();
mOverlayConfigSignaturePackage = getOverlayConfigSignaturePackageName();
+ mRecentsPackage = getRecentsPackageName();
// Now that we know all of the shared libraries, update all clients to have
// the correct library paths.
@@ -21329,15 +21334,8 @@ public class PackageManagerService extends IPackageManager.Stub
@Override
public @Nullable String getAttentionServicePackageName() {
- final String flattenedComponentName =
- mContext.getString(R.string.config_defaultAttentionService);
- if (flattenedComponentName != null) {
- ComponentName componentName = ComponentName.unflattenFromString(flattenedComponentName);
- if (componentName != null && componentName.getPackageName() != null) {
- return ensureSystemPackageName(componentName.getPackageName());
- }
- }
- return null;
+ return ensureSystemPackageName(
+ getPackageFromComponentString(R.string.config_defaultAttentionService));
}
private @Nullable String getDocumenterPackageName() {
@@ -21372,17 +21370,8 @@ public class PackageManagerService extends IPackageManager.Stub
@Override
public String getAppPredictionServicePackageName() {
- String flattenedAppPredictionServiceComponentName =
- mContext.getString(R.string.config_defaultAppPredictionService);
- if (flattenedAppPredictionServiceComponentName == null) {
- return null;
- }
- ComponentName appPredictionServiceComponentName =
- ComponentName.unflattenFromString(flattenedAppPredictionServiceComponentName);
- if (appPredictionServiceComponentName == null) {
- return null;
- }
- return ensureSystemPackageName(appPredictionServiceComponentName.getPackageName());
+ return ensureSystemPackageName(
+ getPackageFromComponentString(R.string.config_defaultAppPredictionService));
}
private @NonNull String[] dropNonSystemPackages(@NonNull String[] pkgNames) {
@@ -21399,19 +21388,8 @@ public class PackageManagerService extends IPackageManager.Stub
@Override
public String getSystemCaptionsServicePackageName() {
- String flattenedSystemCaptionsServiceComponentName =
- mContext.getString(R.string.config_defaultSystemCaptionsService);
-
- if (TextUtils.isEmpty(flattenedSystemCaptionsServiceComponentName)) {
- return null;
- }
-
- ComponentName systemCaptionsServiceComponentName =
- ComponentName.unflattenFromString(flattenedSystemCaptionsServiceComponentName);
- if (systemCaptionsServiceComponentName == null) {
- return null;
- }
- return ensureSystemPackageName(systemCaptionsServiceComponentName.getPackageName());
+ return ensureSystemPackageName(
+ getPackageFromComponentString(R.string.config_defaultSystemCaptionsService));
}
@Override
@@ -21429,19 +21407,8 @@ public class PackageManagerService extends IPackageManager.Stub
@Override
public String getContentCaptureServicePackageName() {
- final String flattenedContentCaptureService =
- mContext.getString(R.string.config_defaultContentCaptureService);
-
- if (TextUtils.isEmpty(flattenedContentCaptureService)) {
- return null;
- }
-
- final ComponentName contentCaptureServiceComponentName =
- ComponentName.unflattenFromString(flattenedContentCaptureService);
- if (contentCaptureServiceComponentName == null) {
- return null;
- }
- return ensureSystemPackageName(contentCaptureServiceComponentName.getPackageName());
+ return ensureSystemPackageName(
+ getPackageFromComponentString(R.string.config_defaultContentCaptureService));
}
public String getOverlayConfigSignaturePackageName() {
@@ -21484,6 +21451,26 @@ public class PackageManagerService extends IPackageManager.Stub
return null;
}
+ @Nullable
+ private String getRecentsPackageName() {
+ return ensureSystemPackageName(
+ getPackageFromComponentString(R.string.config_recentsComponentName));
+
+ }
+
+ @Nullable
+ private String getPackageFromComponentString(@StringRes int stringResId) {
+ final String componentString = mContext.getString(stringResId);
+ if (TextUtils.isEmpty(componentString)) {
+ return null;
+ }
+ final ComponentName component = ComponentName.unflattenFromString(componentString);
+ if (component == null) {
+ return null;
+ }
+ return component.getPackageName();
+ }
+
@Nullable
private String ensureSystemPackageName(@Nullable String packageName) {
if (packageName == null) {
@@ -25092,6 +25079,8 @@ public class PackageManagerService extends IPackageManager.Stub
: new String[] {mRetailDemoPackage};
case PackageManagerInternal.PACKAGE_OVERLAY_CONFIG_SIGNATURE:
return filterOnlySystemPackages(getOverlayConfigSignaturePackageName());
+ case PackageManagerInternal.PACKAGE_RECENTS:
+ return filterOnlySystemPackages(mRecentsPackage);
default:
return ArrayUtils.emptyArray(String.class);
}
diff --git a/services/core/java/com/android/server/pm/permission/Permission.java b/services/core/java/com/android/server/pm/permission/Permission.java
index 687e96c3c9dd2..995b59e97e912 100644
--- a/services/core/java/com/android/server/pm/permission/Permission.java
+++ b/services/core/java/com/android/server/pm/permission/Permission.java
@@ -331,6 +331,10 @@ public final class Permission {
return (mPermissionInfo.protectionLevel & PermissionInfo.PROTECTION_FLAG_RETAIL_DEMO) != 0;
}
+ public boolean isRecents() {
+ return (mPermissionInfo.protectionLevel & PermissionInfo.PROTECTION_FLAG_RECENTS) != 0;
+ }
+
public void transfer(@NonNull String oldPackageName, @NonNull String newPackageName) {
if (!oldPackageName.equals(mPermissionInfo.packageName)) {
return;
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 1b35d29f0d6b0..fb1ed2f6b58bd 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -3616,6 +3616,13 @@ public class PermissionManagerService extends IPermissionManager.Stub {
// Special permission granted only to the OEM specified retail demo app
allowed = true;
}
+ if (!allowed && bp.isRecents()
+ && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
+ PackageManagerInternal.PACKAGE_RECENTS, UserHandle.USER_SYSTEM),
+ pkg.getPackageName())) {
+ // Special permission for the recents app.
+ allowed = true;
+ }
return allowed;
}