diff --git a/core/api/current.txt b/core/api/current.txt index e2981f5936c6b..a9df1a4ab1b37 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -11882,7 +11882,6 @@ package android.content.pm { field public static final int SCREEN_ORIENTATION_USER_LANDSCAPE = 11; // 0xb field public static final int SCREEN_ORIENTATION_USER_PORTRAIT = 12; // 0xc field public static final int UIOPTION_SPLIT_ACTION_BAR_WHEN_NARROW = 1; // 0x1 - field public String[] attributionTags; field public int colorMode; field public int configChanges; field public int documentLaunchMode; @@ -12074,6 +12073,7 @@ package android.content.pm { method public final int getLogoResource(); method public boolean isEnabled(); field public android.content.pm.ApplicationInfo applicationInfo; + field public String[] attributionTags; field public int descriptionRes; field public boolean directBootAware; field public boolean enabled; diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index a8f7a14068ba0..b1438eae65064 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -3510,7 +3510,7 @@ public final class ActivityThread extends ClientTransactionHandler StrictMode.incrementExpectedActivityCount(activity.getClass()); r.intent.setExtrasClassLoader(cl); r.intent.prepareToEnterProcess(isProtectedComponent(r.activityInfo), - activity.getAttributionSource()); + appContext.getAttributionSource()); if (r.state != null) { r.state.setClassLoader(cl); } @@ -4442,6 +4442,10 @@ public final class ActivityThread extends ClientTransactionHandler if (data.info.splitName != null) { context = (ContextImpl) context.createContextForSplit(data.info.splitName); } + if (data.info.attributionTags != null && data.info.attributionTags.length > 0) { + final String attributionTag = data.info.attributionTags[0]; + context = (ContextImpl) context.createAttributionContext(attributionTag); + } // Service resources must be initialized with the same loaders as the application // context. context.getResources().addLoaders( @@ -7353,6 +7357,10 @@ public final class ActivityThread extends ClientTransactionHandler throw new RuntimeException(e); } } + if (info.attributionTags != null && info.attributionTags.length > 0) { + final String attributionTag = info.attributionTags[0]; + c = c.createAttributionContext(attributionTag); + } try { final java.lang.ClassLoader cl = c.getClassLoader(); diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index 17cba84acbebb..73c17b9cc96f7 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -3036,8 +3036,16 @@ class ContextImpl extends Context { } } + final String attributionTag; + if (activityInfo.attributionTags != null && activityInfo.attributionTags.length > 0) { + attributionTag = activityInfo.attributionTags[0]; + } else { + attributionTag = null; + } + ContextImpl context = new ContextImpl(null, mainThread, packageInfo, ContextParams.EMPTY, - null, null, activityInfo.splitName, activityToken, null, 0, classLoader, null); + attributionTag, null, activityInfo.splitName, activityToken, null, 0, classLoader, + null); context.mContextType = CONTEXT_TYPE_ACTIVITY; context.mIsConfigurationBasedContext = true; diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java index fbed90787a97c..03f6380e279f2 100644 --- a/core/java/android/content/pm/ActivityInfo.java +++ b/core/java/android/content/pm/ActivityInfo.java @@ -17,8 +17,8 @@ package android.content.pm; import android.annotation.IntDef; -import android.annotation.SuppressLint; import android.annotation.TestApi; +import android.app.Activity; import android.app.compat.CompatChanges; import android.compat.annotation.ChangeId; import android.compat.annotation.Disabled; @@ -1174,13 +1174,6 @@ public class ActivityInfo extends ComponentInfo implements Parcelable { */ public WindowLayout windowLayout; - /** - * Attribution tags for finer grained calls if a {@link - * android.content.Context#sendBroadcast(Intent, String)} is used with a permission. - */ - @SuppressLint("MissingNullability") - public String[] attributionTags; - public ActivityInfo() { } @@ -1209,7 +1202,6 @@ public class ActivityInfo extends ComponentInfo implements Parcelable { mMaxAspectRatio = orig.mMaxAspectRatio; mMinAspectRatio = orig.mMinAspectRatio; supportsSizeChanges = orig.supportsSizeChanges; - attributionTags = orig.attributionTags; } /** @@ -1532,15 +1524,6 @@ public class ActivityInfo extends ComponentInfo implements Parcelable { if (supportsSizeChanges) { pw.println(prefix + "supportsSizeChanges=true"); } - if (attributionTags != null && attributionTags.length > 0) { - StringBuilder tags = new StringBuilder(); - tags.append(attributionTags[0]); - for (int i = 1; i < attributionTags.length; i++) { - tags.append(", "); - tags.append(attributionTags[i]); - } - pw.println(prefix + "attributionTags=[" + tags + "]"); - } super.dumpBack(pw, prefix, dumpFlags); } @@ -1586,7 +1569,6 @@ public class ActivityInfo extends ComponentInfo implements Parcelable { dest.writeFloat(mMaxAspectRatio); dest.writeFloat(mMinAspectRatio); dest.writeBoolean(supportsSizeChanges); - dest.writeString8Array(attributionTags); } /** @@ -1706,7 +1688,6 @@ public class ActivityInfo extends ComponentInfo implements Parcelable { mMaxAspectRatio = source.readFloat(); mMinAspectRatio = source.readFloat(); supportsSizeChanges = source.readBoolean(); - attributionTags = source.createString8Array(); } /** diff --git a/core/java/android/content/pm/ComponentInfo.java b/core/java/android/content/pm/ComponentInfo.java index c67d00e88707e..42847c85103c7 100644 --- a/core/java/android/content/pm/ComponentInfo.java +++ b/core/java/android/content/pm/ComponentInfo.java @@ -16,8 +16,14 @@ package android.content.pm; +import android.annotation.SuppressLint; +import android.app.Activity; +import android.app.Service; import android.compat.annotation.UnsupportedAppUsage; +import android.content.BroadcastReceiver; import android.content.ComponentName; +import android.content.ContentResolver; +import android.content.Context; import android.graphics.drawable.Drawable; import android.os.Build; import android.os.Parcel; @@ -51,6 +57,25 @@ public class ComponentInfo extends PackageItemInfo { */ public String splitName; + /** + * Set of attribution tags that should be automatically applied to this + * component. + *
+ * When this component represents an {@link Activity}, {@link Service}, + * {@link ContentResolver} or {@link BroadcastReceiver}, each instance will + * be automatically configured with {@link Context#createAttributionContext} + * using the first attribution tag contained here. + *
+ * Additionally, when this component represents a {@link BroadcastReceiver}
+ * and the sender of a broadcast requires the receiver to hold one or more
+ * specific permissions, those permission checks will be performed using
+ * each of the attributions tags contained here.
+ *
+ * @see Context#createAttributionContext(String)
+ */
+ @SuppressLint({"MissingNullability", "MutableBareField"})
+ public String[] attributionTags;
+
/**
* A string resource identifier (in the package's resources) containing
* a user-readable description of the component. From the "description"
@@ -87,6 +112,7 @@ public class ComponentInfo extends PackageItemInfo {
applicationInfo = orig.applicationInfo;
processName = orig.processName;
splitName = orig.splitName;
+ attributionTags = orig.attributionTags;
descriptionRes = orig.descriptionRes;
enabled = orig.enabled;
exported = orig.exported;
@@ -172,6 +198,15 @@ public class ComponentInfo extends PackageItemInfo {
if (splitName != null) {
pw.println(prefix + "splitName=" + splitName);
}
+ if (attributionTags != null && attributionTags.length > 0) {
+ StringBuilder tags = new StringBuilder();
+ tags.append(attributionTags[0]);
+ for (int i = 1; i < attributionTags.length; i++) {
+ tags.append(", ");
+ tags.append(attributionTags[i]);
+ }
+ pw.println(prefix + "attributionTags=[" + tags + "]");
+ }
pw.println(prefix + "enabled=" + enabled + " exported=" + exported
+ " directBootAware=" + directBootAware);
if (descriptionRes != 0) {
@@ -200,6 +235,7 @@ public class ComponentInfo extends PackageItemInfo {
applicationInfo.writeToParcel(dest, parcelableFlags);
dest.writeString8(processName);
dest.writeString8(splitName);
+ dest.writeString8Array(attributionTags);
dest.writeInt(descriptionRes);
dest.writeInt(enabled ? 1 : 0);
dest.writeInt(exported ? 1 : 0);
@@ -211,6 +247,7 @@ public class ComponentInfo extends PackageItemInfo {
applicationInfo = ApplicationInfo.CREATOR.createFromParcel(source);
processName = source.readString8();
splitName = source.readString8();
+ attributionTags = source.createString8Array();
descriptionRes = source.readInt();
enabled = (source.readInt() != 0);
exported = (source.readInt() != 0);
diff --git a/core/java/android/content/pm/parsing/PackageInfoWithoutStateUtils.java b/core/java/android/content/pm/parsing/PackageInfoWithoutStateUtils.java
index a9d70c524af07..d407b106b5a30 100644
--- a/core/java/android/content/pm/parsing/PackageInfoWithoutStateUtils.java
+++ b/core/java/android/content/pm/parsing/PackageInfoWithoutStateUtils.java
@@ -713,6 +713,7 @@ public class PackageInfoWithoutStateUtils {
componentInfo.directBootAware = mainComponent.isDirectBootAware();
componentInfo.enabled = mainComponent.isEnabled();
componentInfo.splitName = mainComponent.getSplitName();
+ componentInfo.attributionTags = mainComponent.getAttributionTags();
}
private static void assignSharedFieldsForPackageItemInfo(
diff --git a/core/java/android/content/pm/parsing/component/ParsedActivity.java b/core/java/android/content/pm/parsing/component/ParsedActivity.java
index 9285ccb3cf0ca..6f478accedd77 100644
--- a/core/java/android/content/pm/parsing/component/ParsedActivity.java
+++ b/core/java/android/content/pm/parsing/component/ParsedActivity.java
@@ -82,9 +82,6 @@ public class ParsedActivity extends ParsedMainComponent {
@Nullable
ActivityInfo.WindowLayout windowLayout;
- @Nullable
- String[] attributionTags;
-
public ParsedActivity(ParsedActivity other) {
super(other);
this.theme = other.theme;
@@ -110,7 +107,6 @@ public class ParsedActivity extends ParsedMainComponent {
this.rotationAnimation = other.rotationAnimation;
this.colorMode = other.colorMode;
this.windowLayout = other.windowLayout;
- this.attributionTags = other.attributionTags;
}
/**
@@ -176,7 +172,6 @@ public class ParsedActivity extends ParsedMainComponent {
alias.requestedVrComponent = target.requestedVrComponent;
alias.directBootAware = target.directBootAware;
alias.setProcessName(target.getProcessName());
- alias.attributionTags = target.attributionTags;
return alias;
// Not all attributes from the target ParsedActivity are copied to the alias.
@@ -304,7 +299,6 @@ public class ParsedActivity extends ParsedMainComponent {
} else {
dest.writeBoolean(false);
}
- dest.writeString8Array(this.attributionTags);
}
public ParsedActivity() {
@@ -338,7 +332,6 @@ public class ParsedActivity extends ParsedMainComponent {
if (in.readBoolean()) {
windowLayout = new ActivityInfo.WindowLayout(in);
}
- this.attributionTags = in.createString8Array();
}
public static final Parcelable.Creator