Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5014fbd6 authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

Apply "attributionTags" to all component types.

Components within an application are often a good boundary for
developers to declare "attribution" information, such as an Activity
or Service used to offer a specific sub-feature.

This change expands the "android:attributionTags" manifest attribute
to apply to all component types, and it then automatically configures
the associated Context with Context.createAttributionContext() with
no additional developer action required.  Developers can still
manually use Context.createAttributionContext() to adjust the
attribution tag again if desired.

Bug: 187097694
Test: atest CtsAppOpsTestCases:AttributionTest
Test: atest CtsAppTestCases:android.app.cts.AttributionTagsTest
Change-Id: Ia16c66e7b63bcbfb8c0d7348e9b5d4adb2a1f45d
parent dd6dd3b1
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -11883,7 +11883,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;
@@ -12075,6 +12074,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;
+9 −1
Original line number Diff line number Diff line
@@ -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();
+9 −1
Original line number Diff line number Diff line
@@ -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;

+1 −20
Original line number Diff line number Diff line
@@ -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();
    }

    /**
+37 −0
Original line number Diff line number Diff line
@@ -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.
     * <p>
     * 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.
     * <p>
     * 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);
Loading