From afbc4fee9d7dcaa002a263e7064169a0781bc370 Mon Sep 17 00:00:00 2001 From: Erik Wolsheimer Date: Sun, 16 May 2021 15:32:50 -0700 Subject: [PATCH] Add application-level 'attributionsAreUserVisible' attribute Bug: 176902658 Test: Manual Change-Id: I56dc9caa6d98b75bc6732bbca0e5adc67bb745e5 --- core/api/current.txt | 2 ++ .../android/content/pm/ApplicationInfo.java | 17 +++++++++++++++++ .../parsing/PackageInfoWithoutStateUtils.java | 14 +++++++++++++- .../content/pm/parsing/ParsingPackage.java | 2 ++ .../content/pm/parsing/ParsingPackageImpl.java | 12 ++++++++++++ .../content/pm/parsing/ParsingPackageRead.java | 7 ++++++- .../content/pm/parsing/ParsingPackageUtils.java | 1 + core/res/res/values/attrs_manifest.xml | 6 ++++++ core/res/res/values/public.xml | 1 + .../server/pm/parsing/pkg/PkgAppInfo.java | 6 ++++++ 10 files changed, 66 insertions(+), 2 deletions(-) diff --git a/core/api/current.txt b/core/api/current.txt index a3d71f176706f..c6968a42bd90e 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -340,6 +340,7 @@ package android { field public static final int appCategory = 16844101; // 0x1010545 field public static final int appComponentFactory = 16844154; // 0x101057a field public static final int attributionTags; + field public static final int attributionsAreUserVisible; field public static final int author = 16843444; // 0x10102b4 field public static final int authorities = 16842776; // 0x1010018 field public static final int autoAdvanceViewId = 16843535; // 0x101030f @@ -11933,6 +11934,7 @@ package android.content.pm { public class ApplicationInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable { ctor public ApplicationInfo(); ctor public ApplicationInfo(android.content.pm.ApplicationInfo); + method public boolean areAttributionsUserVisible(); method public int describeContents(); method public void dump(android.util.Printer, String); method public static CharSequence getCategoryTitle(android.content.Context, int); diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java index 8b0e992368069..2c4ff58892634 100644 --- a/core/java/android/content/pm/ApplicationInfo.java +++ b/core/java/android/content/pm/ApplicationInfo.java @@ -786,10 +786,18 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { */ public static final int PRIVATE_FLAG_EXT_REQUEST_FOREGROUND_SERVICE_EXEMPTION = 1 << 1; + /** + * Value for {@link #privateFlagsExt}: whether attributions provided by the application are + * meant to be user-visible. + * @hide + */ + public static final int PRIVATE_FLAG_EXT_ATTRIBUTIONS_ARE_USER_VISIBLE = 1 << 2; + /** @hide */ @IntDef(flag = true, prefix = { "PRIVATE_FLAG_EXT_" }, value = { PRIVATE_FLAG_EXT_PROFILEABLE, PRIVATE_FLAG_EXT_REQUEST_FOREGROUND_SERVICE_EXEMPTION, + PRIVATE_FLAG_EXT_ATTRIBUTIONS_ARE_USER_VISIBLE, }) @Retention(RetentionPolicy.SOURCE) public @interface ApplicationInfoPrivateFlagsExt {} @@ -2436,6 +2444,15 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { return (privateFlagsExt & PRIVATE_FLAG_EXT_PROFILEABLE) != 0; } + /** + * Returns whether attributions provided by the application are meant to be user-visible. + * Defaults to false if application info is retrieved without + * {@link PackageManager#GET_ATTRIBUTIONS}. + */ + public boolean areAttributionsUserVisible() { + return (privateFlagsExt & PRIVATE_FLAG_EXT_ATTRIBUTIONS_ARE_USER_VISIBLE) != 0; + } + /** * Returns true if the app has declared in its manifest that it wants its split APKs to be * loaded into isolated Contexts, with their own ClassLoaders and Resources objects. diff --git a/core/java/android/content/pm/parsing/PackageInfoWithoutStateUtils.java b/core/java/android/content/pm/parsing/PackageInfoWithoutStateUtils.java index d407b106b5a30..c9054fd8976da 100644 --- a/core/java/android/content/pm/parsing/PackageInfoWithoutStateUtils.java +++ b/core/java/android/content/pm/parsing/PackageInfoWithoutStateUtils.java @@ -298,6 +298,16 @@ public class PackageInfoWithoutStateUtils { pi.attributions[i] = generateAttribution(pkg.getAttributions().get(i)); } } + if (pkg.areAttributionsUserVisible()) { + pi.applicationInfo.privateFlagsExt + |= ApplicationInfo.PRIVATE_FLAG_EXT_ATTRIBUTIONS_ARE_USER_VISIBLE; + } else { + pi.applicationInfo.privateFlagsExt + &= ~ApplicationInfo.PRIVATE_FLAG_EXT_ATTRIBUTIONS_ARE_USER_VISIBLE; + } + } else { + pi.applicationInfo.privateFlagsExt + &= ~ApplicationInfo.PRIVATE_FLAG_EXT_ATTRIBUTIONS_ARE_USER_VISIBLE; } if (apexInfo != null) { @@ -809,7 +819,9 @@ public class PackageInfoWithoutStateUtils { int privateFlagsExt = flag(pkg.isProfileable(), ApplicationInfo.PRIVATE_FLAG_EXT_PROFILEABLE) | flag(pkg.hasRequestForegroundServiceExemption(), - ApplicationInfo.PRIVATE_FLAG_EXT_REQUEST_FOREGROUND_SERVICE_EXEMPTION); + ApplicationInfo.PRIVATE_FLAG_EXT_REQUEST_FOREGROUND_SERVICE_EXEMPTION) + | flag(pkg.areAttributionsUserVisible(), + ApplicationInfo.PRIVATE_FLAG_EXT_ATTRIBUTIONS_ARE_USER_VISIBLE); // @formatter:on return privateFlagsExt; } diff --git a/core/java/android/content/pm/parsing/ParsingPackage.java b/core/java/android/content/pm/parsing/ParsingPackage.java index 2413e6d99f5f6..ed68dbf0087c8 100644 --- a/core/java/android/content/pm/parsing/ParsingPackage.java +++ b/core/java/android/content/pm/parsing/ParsingPackage.java @@ -362,6 +362,8 @@ public interface ParsingPackage extends ParsingPackageRead { ParsingPackage setCompileSdkVersionCodename(String compileSdkVersionCodename); + ParsingPackage setAttributionsAreUserVisible(boolean attributionsAreUserVisible); + // TODO(b/135203078): This class no longer has access to ParsedPackage, find a replacement // for moving to the next step @CallSuper diff --git a/core/java/android/content/pm/parsing/ParsingPackageImpl.java b/core/java/android/content/pm/parsing/ParsingPackageImpl.java index b0342aa95fc99..f0b76499093c9 100644 --- a/core/java/android/content/pm/parsing/ParsingPackageImpl.java +++ b/core/java/android/content/pm/parsing/ParsingPackageImpl.java @@ -514,6 +514,7 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable { private static final long ENABLED = 1L << 44; private static final long DISALLOW_PROFILING = 1L << 45; private static final long REQUEST_FOREGROUND_SERVICE_EXEMPTION = 1L << 46; + private static final long ATTRIBUTIONS_ARE_USER_VISIBLE = 1L << 47; } private ParsingPackageImpl setBoolean(@Booleans.Values long flag, boolean value) { @@ -2205,6 +2206,11 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable { return getBoolean(Booleans.REQUEST_FOREGROUND_SERVICE_EXEMPTION); } + @Override + public boolean areAttributionsUserVisible() { + return getBoolean(Booleans.ATTRIBUTIONS_ARE_USER_VISIBLE); + } + @Override public ParsingPackageImpl setBaseRevisionCode(int value) { baseRevisionCode = value; @@ -2760,4 +2766,10 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable { this.zygotePreloadName = zygotePreloadName; return this; } + + @Override + public ParsingPackage setAttributionsAreUserVisible(boolean attributionsAreUserVisible) { + setBoolean(Booleans.ATTRIBUTIONS_ARE_USER_VISIBLE, attributionsAreUserVisible); + return this; + } } diff --git a/core/java/android/content/pm/parsing/ParsingPackageRead.java b/core/java/android/content/pm/parsing/ParsingPackageRead.java index 35a2b9aeb338b..a6e189d32b542 100644 --- a/core/java/android/content/pm/parsing/ParsingPackageRead.java +++ b/core/java/android/content/pm/parsing/ParsingPackageRead.java @@ -46,7 +46,6 @@ import android.util.SparseArray; import android.util.SparseIntArray; import java.security.PublicKey; -import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Set; @@ -922,4 +921,10 @@ public interface ParsingPackageRead extends Parcelable { * same as toAppInfoWithoutState except without flag computation. */ ApplicationInfo toAppInfoWithoutStateWithoutFlags(); + + /** + * Whether or not the app has said its attribution tags can be made user-visible. + * @see ApplicationInfo#areAttributionsUserVisible() + */ + boolean areAttributionsUserVisible(); } diff --git a/core/java/android/content/pm/parsing/ParsingPackageUtils.java b/core/java/android/content/pm/parsing/ParsingPackageUtils.java index 022ba16e9da8c..b74760ac8bc42 100644 --- a/core/java/android/content/pm/parsing/ParsingPackageUtils.java +++ b/core/java/android/content/pm/parsing/ParsingPackageUtils.java @@ -2198,6 +2198,7 @@ public class ParsingPackageUtils { .setUsesNonSdkApi(bool(false, R.styleable.AndroidManifestApplication_usesNonSdkApi, sa)) .setVmSafeMode(bool(false, R.styleable.AndroidManifestApplication_vmSafeMode, sa)) .setAutoRevokePermissions(anInt(R.styleable.AndroidManifestApplication_autoRevokePermissions, sa)) + .setAttributionsAreUserVisible(bool(false, R.styleable.AndroidManifestApplication_attributionsAreUserVisible, sa)) // targetSdkVersion gated .setAllowAudioPlaybackCapture(bool(targetSdk >= Build.VERSION_CODES.Q, R.styleable.AndroidManifestApplication_allowAudioPlaybackCapture, sa)) .setBaseHardwareAccelerated(bool(targetSdk >= Build.VERSION_CODES.ICE_CREAM_SANDWICH, R.styleable.AndroidManifestApplication_hardwareAccelerated, sa)) diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml index ef0dc37329c71..ed0d8c838d060 100644 --- a/core/res/res/values/attrs_manifest.xml +++ b/core/res/res/values/attrs_manifest.xml @@ -1538,6 +1538,9 @@ + + + @@ -1961,6 +1964,9 @@ there's no way to be exempted (without using a privileged permission). --> + + + + diff --git a/services/core/java/com/android/server/pm/parsing/pkg/PkgAppInfo.java b/services/core/java/com/android/server/pm/parsing/pkg/PkgAppInfo.java index 0cb425f9243bd..728e1bc652c06 100644 --- a/services/core/java/com/android/server/pm/parsing/pkg/PkgAppInfo.java +++ b/services/core/java/com/android/server/pm/parsing/pkg/PkgAppInfo.java @@ -212,6 +212,12 @@ interface PkgAppInfo { */ int getRoundIconRes(); + /** + * @see ApplicationInfo#areAttributionsUserVisible() + * @see R.styleable#AndroidManifestApplication_attributionsAreUserVisible + */ + boolean areAttributionsUserVisible(); + /** @see ApplicationInfo#seInfo */ @Nullable String getSeInfo();