diff --git a/core/api/current.txt b/core/api/current.txt index 928c011e3d6ce..ca7388427859f 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -341,6 +341,7 @@ package android { field public static final int allowSingleTap = 16843353; // 0x1010259 field public static final int allowTaskReparenting = 16843268; // 0x1010204 field public static final int allowUndo = 16843999; // 0x10104df + field public static final int allowUntrustedActivityEmbedding; field public static final int alpha = 16843551; // 0x101031f field public static final int alphabeticModifiers = 16844110; // 0x101054e field public static final int alphabeticShortcut = 16843235; // 0x10101e3 @@ -905,6 +906,7 @@ package android { field public static final int keyboardNavigationCluster = 16844096; // 0x1010540 field public static final int keycode = 16842949; // 0x10100c5 field public static final int killAfterRestore = 16843420; // 0x101029c + field public static final int knownActivityEmbeddingCerts; field public static final int knownCerts = 16844330; // 0x101062a field public static final int lStar = 16844359; // 0x1010647 field public static final int label = 16842753; // 0x1010001 @@ -10966,6 +10968,7 @@ package android.content.pm { ctor public ActivityInfo(android.content.pm.ActivityInfo); method public int describeContents(); method public void dump(android.util.Printer, String); + method @NonNull public java.util.Set getKnownActivityEmbeddingCerts(); method public final int getThemeResource(); field public static final int COLOR_MODE_DEFAULT = 0; // 0x0 field public static final int COLOR_MODE_HDR = 2; // 0x2 @@ -10993,6 +10996,7 @@ package android.content.pm { field public static final int DOCUMENT_LAUNCH_NEVER = 3; // 0x3 field public static final int DOCUMENT_LAUNCH_NONE = 0; // 0x0 field public static final int FLAG_ALLOW_TASK_REPARENTING = 64; // 0x40 + field public static final int FLAG_ALLOW_UNTRUSTED_ACTIVITY_EMBEDDING = 268435456; // 0x10000000 field public static final int FLAG_ALWAYS_RETAIN_TASK_STATE = 8; // 0x8 field public static final int FLAG_AUTO_REMOVE_FROM_RECENTS = 8192; // 0x2000 field public static final int FLAG_CLEAR_TASK_ON_LAUNCH = 4; // 0x4 @@ -11082,6 +11086,7 @@ package android.content.pm { method public void dump(android.util.Printer, String); method public static CharSequence getCategoryTitle(android.content.Context, int); method public int getGwpAsanMode(); + method @NonNull public java.util.Set getKnownActivityEmbeddingCerts(); method public int getMemtagMode(); method public int getNativeHeapZeroInitialized(); method public int getRequestRawExternalStorageAccess(); diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java index 8bea006071bf6..0673b3ad5b0a6 100644 --- a/core/java/android/content/pm/ActivityInfo.java +++ b/core/java/android/content/pm/ActivityInfo.java @@ -18,6 +18,8 @@ package android.content.pm; import android.annotation.FloatRange; import android.annotation.IntDef; +import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.TestApi; import android.app.Activity; import android.app.compat.CompatChanges; @@ -35,10 +37,16 @@ import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.os.UserHandle; +import android.util.ArraySet; import android.util.Printer; +import com.android.internal.util.Parcelling; + import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.util.Collections; +import java.util.Locale; +import java.util.Set; /** * Information you can retrieve about a particular application @@ -48,6 +56,9 @@ import java.lang.annotation.RetentionPolicy; */ public class ActivityInfo extends ComponentInfo implements Parcelable { + private static final Parcelling.BuiltIn.ForStringSet sForStringSet = + Parcelling.Cache.getOrCreate(Parcelling.BuiltIn.ForStringSet.class); + // NOTE: When adding new data members be sure to update the copy-constructor, Parcel // constructor, and writeToParcel. @@ -524,6 +535,13 @@ public class ActivityInfo extends ComponentInfo implements Parcelable { */ public static final int FLAG_PREFER_MINIMAL_POST_PROCESSING = 0x2000000; + /** + * Bit in {@link #flags}: If set, indicates that the activity can be embedded by untrusted + * hosts. In this case the interactions with and visibility of the embedded activity may be + * limited. Set from the {@link android.R.attr#allowUntrustedActivityEmbedding} attribute. + */ + public static final int FLAG_ALLOW_UNTRUSTED_ACTIVITY_EMBEDDING = 0x10000000; + /** * @hide Bit in {@link #flags}: If set, this component will only be seen * by the system user. Only works with broadcast receivers. Set from the @@ -561,7 +579,8 @@ public class ActivityInfo extends ComponentInfo implements Parcelable { * {@link #FLAG_STATE_NOT_NEEDED}, {@link #FLAG_EXCLUDE_FROM_RECENTS}, * {@link #FLAG_ALLOW_TASK_REPARENTING}, {@link #FLAG_NO_HISTORY}, * {@link #FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS}, - * {@link #FLAG_HARDWARE_ACCELERATED}, {@link #FLAG_SINGLE_USER}. + * {@link #FLAG_HARDWARE_ACCELERATED}, {@link #FLAG_SINGLE_USER}, + * {@link #FLAG_ALLOW_UNTRUSTED_ACTIVITY_EMBEDDING}. */ public int flags; @@ -1079,6 +1098,13 @@ public class ActivityInfo extends ComponentInfo implements Parcelable { @EnabledSince(targetSdkVersion = Build.VERSION_CODES.S) private static final long CHECK_MIN_WIDTH_HEIGHT_FOR_MULTI_WINDOW = 197654537L; + /** + * Optional set of a certificates identifying apps that are allowed to embed this activity. From + * the "knownActivityEmbeddingCerts" attribute. + */ + @Nullable + private Set mKnownActivityEmbeddingCerts; + /** * Convert Java change bits to native. * @@ -1227,6 +1253,7 @@ public class ActivityInfo extends ComponentInfo implements Parcelable { launchMode = orig.launchMode; documentLaunchMode = orig.documentLaunchMode; permission = orig.permission; + mKnownActivityEmbeddingCerts = orig.mKnownActivityEmbeddingCerts; taskAffinity = orig.taskAffinity; targetActivity = orig.targetActivity; flags = orig.flags; @@ -1442,6 +1469,31 @@ public class ActivityInfo extends ComponentInfo implements Parcelable { return mMinAspectRatio; } + /** + * Gets the trusted host certificate digests of apps that are allowed to embed this activity. + * The digests are computed using the SHA-256 digest algorithm. + * @see android.R.attr#knownActivityEmbeddingCerts + */ + @NonNull + public Set getKnownActivityEmbeddingCerts() { + return mKnownActivityEmbeddingCerts == null ? Collections.emptySet() + : mKnownActivityEmbeddingCerts; + } + + /** + * Sets the trusted host certificates of apps that are allowed to embed this activity. + * @see #getKnownActivityEmbeddingCerts() + * @hide + */ + public void setKnownActivityEmbeddingCerts(@NonNull Set knownActivityEmbeddingCerts) { + // Convert the provided digest to upper case for consistent Set membership + // checks when verifying the signing certificate digests of requesting apps. + mKnownActivityEmbeddingCerts = new ArraySet<>(); + for (String knownCert : knownActivityEmbeddingCerts) { + mKnownActivityEmbeddingCerts.add(knownCert.toUpperCase(Locale.US)); + } + } + private boolean isChangeEnabled(long changeId) { return CompatChanges.isChangeEnabled(changeId, applicationInfo.packageName, UserHandle.getUserHandleForUid(applicationInfo.uid)); @@ -1573,6 +1625,9 @@ public class ActivityInfo extends ComponentInfo implements Parcelable { if (supportsSizeChanges) { pw.println(prefix + "supportsSizeChanges=true"); } + if (mKnownActivityEmbeddingCerts != null) { + pw.println(prefix + "knownActivityEmbeddingCerts=" + mKnownActivityEmbeddingCerts); + } super.dumpBack(pw, prefix, dumpFlags); } @@ -1618,6 +1673,7 @@ public class ActivityInfo extends ComponentInfo implements Parcelable { dest.writeFloat(mMaxAspectRatio); dest.writeFloat(mMinAspectRatio); dest.writeBoolean(supportsSizeChanges); + sForStringSet.parcel(mKnownActivityEmbeddingCerts, dest, flags); } /** @@ -1739,6 +1795,10 @@ public class ActivityInfo extends ComponentInfo implements Parcelable { mMaxAspectRatio = source.readFloat(); mMinAspectRatio = source.readFloat(); supportsSizeChanges = source.readBoolean(); + mKnownActivityEmbeddingCerts = sForStringSet.unparcel(source); + if (mKnownActivityEmbeddingCerts.isEmpty()) { + mKnownActivityEmbeddingCerts = null; + } } /** diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java index 567f649ea7623..2528e16ce7b70 100644 --- a/core/java/android/content/pm/ApplicationInfo.java +++ b/core/java/android/content/pm/ApplicationInfo.java @@ -35,6 +35,7 @@ import android.os.Parcelable; import android.os.UserHandle; import android.os.storage.StorageManager; import android.util.ArrayMap; +import android.util.ArraySet; import android.util.Printer; import android.util.SparseArray; import android.util.proto.ProtoOutputStream; @@ -52,7 +53,9 @@ import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.List; +import java.util.Locale; import java.util.Objects; +import java.util.Set; import java.util.UUID; /** @@ -62,6 +65,8 @@ import java.util.UUID; */ public class ApplicationInfo extends PackageItemInfo implements Parcelable { private static ForBoolean sForBoolean = Parcelling.Cache.getOrCreate(ForBoolean.class); + private static final Parcelling.BuiltIn.ForStringSet sForStringSet = + Parcelling.Cache.getOrCreate(Parcelling.BuiltIn.ForStringSet.class); /** * Default task affinity of all activities in this application. See @@ -1550,6 +1555,13 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { */ private int localeConfigRes; + /** + * Optional set of a certificates identifying apps that are allowed to embed activities of this + * application. From the "knownActivityEmbeddingCerts" attribute. + */ + @Nullable + private Set mKnownActivityEmbeddingCerts; + public void dump(Printer pw, String prefix) { dump(pw, prefix, DUMP_FLAG_ALL); } @@ -1673,6 +1685,9 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { } } pw.println(prefix + "createTimestamp=" + createTimestamp); + if (mKnownActivityEmbeddingCerts != null) { + pw.println(prefix + "knownActivityEmbeddingCerts=" + mKnownActivityEmbeddingCerts); + } super.dumpBack(pw, prefix); } @@ -1787,6 +1802,11 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { } proto.end(detailToken); } + if (!ArrayUtils.isEmpty(mKnownActivityEmbeddingCerts)) { + for (String knownCert : mKnownActivityEmbeddingCerts) { + proto.write(ApplicationInfoProto.KNOWN_ACTIVITY_EMBEDDING_CERTS, knownCert); + } + } proto.end(token); } @@ -1837,6 +1857,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { super(orig); taskAffinity = orig.taskAffinity; permission = orig.permission; + mKnownActivityEmbeddingCerts = orig.mKnownActivityEmbeddingCerts; processName = orig.processName; className = orig.className; theme = orig.theme; @@ -2006,6 +2027,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { } } dest.writeInt(localeConfigRes); + sForStringSet.parcel(mKnownActivityEmbeddingCerts, dest, flags); } public static final @android.annotation.NonNull Parcelable.Creator CREATOR @@ -2102,6 +2124,10 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { } } localeConfigRes = source.readInt(); + mKnownActivityEmbeddingCerts = sForStringSet.unparcel(source); + if (mKnownActivityEmbeddingCerts.isEmpty()) { + mKnownActivityEmbeddingCerts = null; + } } /** @@ -2658,7 +2684,6 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { return localeConfigRes; } - /** * List of all shared libraries this application is linked against. This * list will only be set if the {@link PackageManager#GET_SHARED_LIBRARY_FILES @@ -2675,4 +2700,29 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { return sharedLibraryInfos; } + /** + * Gets the trusted host certificate digests of apps that are allowed to embed activities of + * this application. The digests are computed using the SHA-256 digest algorithm. + * @see android.R.attr#knownActivityEmbeddingCerts + */ + @NonNull + public Set getKnownActivityEmbeddingCerts() { + return mKnownActivityEmbeddingCerts == null ? Collections.emptySet() + : mKnownActivityEmbeddingCerts; + } + + /** + * Sets the trusted host certificates of apps that are allowed to embed activities of this + * application. + * @see #getKnownActivityEmbeddingCerts() + * @hide + */ + public void setKnownActivityEmbeddingCerts(@NonNull Set knownActivityEmbeddingCerts) { + // Convert the provided digest to upper case for consistent Set membership + // checks when verifying the signing certificate digests of requesting apps. + mKnownActivityEmbeddingCerts = new ArraySet<>(); + for (String knownCert : knownActivityEmbeddingCerts) { + mKnownActivityEmbeddingCerts.add(knownCert.toUpperCase(Locale.US)); + } + } } diff --git a/core/proto/android/content/package_item_info.proto b/core/proto/android/content/package_item_info.proto index 5c6116a09b770..279a5d0c17f84 100644 --- a/core/proto/android/content/package_item_info.proto +++ b/core/proto/android/content/package_item_info.proto @@ -115,4 +115,5 @@ message ApplicationInfoProto { } optional Detail detail = 17; repeated string overlay_paths = 18; + repeated string known_activity_embedding_certs = 19; } diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml index cb40e86f15359..6dc975b4112c5 100644 --- a/core/res/res/values/attrs_manifest.xml +++ b/core/res/res/values/attrs_manifest.xml @@ -1048,6 +1048,24 @@

The default value of this attribute is false. --> + + + + + + + + +