From 24734440c017dd5314fd720bd8fbee2cf9e2874e Mon Sep 17 00:00:00 2001 From: Sahana Rao Date: Mon, 22 Mar 2021 11:39:59 +0000 Subject: [PATCH] Add manifest attribute requestOptmizedExternalStorageAccess Add new manifest attribute requestOptmizedExternalStorageAccess. When the flag is set, app requests for performance optimisations for file path operations. Apps get this performance optimisation by bypassing database operations as part of file path operations. Hence, when the flag is set, app will be resposible to keep MediaStore database consistent for its file path operations. App should hold android.Manifest.permission#MANAGE_EXTERNAL_STORAGE permission or SYSTEM_GALLERY role, otherwise the flag will be ignored. The default values is - True if * if app has android.Manifest.permission#MANAGE_EXTERNAL_STORAGE permission and targets targetSDK<=30. * app has SYSTEM_GALLERY role and targetSDK<=29. - False otherwise. Bug: 178209446 Test: atest android.scopedstorage.cts.device.BypassDatabaseOperationsTest Change-Id: I951c3001c2b7dbe163b3bfecef4ee8ad350230ae --- core/api/current.txt | 1 + core/api/system-current.txt | 1 + .../android/content/pm/ApplicationInfo.java | 36 +++++++++++++++++++ .../content/pm/parsing/ParsingPackage.java | 3 ++ .../pm/parsing/ParsingPackageImpl.java | 18 ++++++++++ .../pm/parsing/ParsingPackageRead.java | 3 ++ .../pm/parsing/ParsingPackageUtils.java | 6 ++++ core/res/res/values/attrs_manifest.xml | 19 ++++++++++ core/res/res/values/public.xml | 1 + 9 files changed, 88 insertions(+) diff --git a/core/api/current.txt b/core/api/current.txt index 7e2edd6af0b6c..cdc73dbb6ce82 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -1176,6 +1176,7 @@ package android { field public static final int reqNavigation = 16843306; // 0x101022a field public static final int reqTouchScreen = 16843303; // 0x1010227 field public static final int requestLegacyExternalStorage = 16844291; // 0x1010603 + field public static final int requestOptimizedExternalStorageAccess = 16844357; // 0x1010645 field public static final int requireDeviceScreenOn = 16844317; // 0x101061d field public static final int requireDeviceUnlock = 16843756; // 0x10103ec field public static final int required = 16843406; // 0x101028e diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 13b837963fcf5..94205563bc321 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -2424,6 +2424,7 @@ package android.content.om { package android.content.pm { public class ApplicationInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable { + method @Nullable public Boolean hasRequestOptimizedExternalStorageAccess(); method public boolean isEncryptionAware(); method public boolean isInstantApp(); method public boolean isOem(); diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java index 1a5dad5f75968..0da453d81be61 100644 --- a/core/java/android/content/pm/ApplicationInfo.java +++ b/core/java/android/content/pm/ApplicationInfo.java @@ -1410,6 +1410,13 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { @Nullable private Boolean nativeHeapZeroInit; + /** + * If {@code true} this app requests optimized external storage access. + * The request may not be honored due to policy or other reasons. + */ + @Nullable + private Boolean requestOptimizedExternalStorageAccess; + /** * Represents the default policy. The actual policy used will depend on other properties of * the application, e.g. the target SDK version. @@ -1566,6 +1573,10 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { if (nativeHeapZeroInit != null) { pw.println(prefix + "nativeHeapZeroInit=" + nativeHeapZeroInit); } + if (requestOptimizedExternalStorageAccess != null) { + pw.println(prefix + "requestOptimizedExternalStorageAccess=" + + requestOptimizedExternalStorageAccess); + } } super.dumpBack(pw, prefix); } @@ -1792,6 +1803,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { gwpAsanMode = orig.gwpAsanMode; memtagMode = orig.memtagMode; nativeHeapZeroInit = orig.nativeHeapZeroInit; + requestOptimizedExternalStorageAccess = orig.requestOptimizedExternalStorageAccess; } public String toString() { @@ -1880,6 +1892,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { dest.writeInt(gwpAsanMode); dest.writeInt(memtagMode); sForBoolean.parcel(nativeHeapZeroInit, dest, parcelableFlags); + sForBoolean.parcel(requestOptimizedExternalStorageAccess, dest, parcelableFlags); } public static final @android.annotation.NonNull Parcelable.Creator CREATOR @@ -1965,6 +1978,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { gwpAsanMode = source.readInt(); memtagMode = source.readInt(); nativeHeapZeroInit = sForBoolean.unparcel(source); + requestOptimizedExternalStorageAccess = sForBoolean.unparcel(source); } /** @@ -2078,6 +2092,24 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { return (privateFlags & PRIVATE_FLAG_REQUEST_LEGACY_EXTERNAL_STORAGE) != 0; } + /** + * @return + * + * + * @hide + */ + @SystemApi + @Nullable + public Boolean hasRequestOptimizedExternalStorageAccess() { + return requestOptimizedExternalStorageAccess; + } + /** * If {@code true} this app allows heap pointer tagging. * @@ -2351,6 +2383,10 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { /** {@hide} */ public void setGwpAsanMode(@GwpAsanMode int value) { gwpAsanMode = value; } /** {@hide} */ public void setMemtagMode(@MemtagMode int value) { memtagMode = value; } /** {@hide} */ public void setNativeHeapZeroInit(@Nullable Boolean value) { nativeHeapZeroInit = value; } + /** {@hide} */ + public void setRequestOptimizedExternalStorageAccess(@Nullable Boolean value) { + requestOptimizedExternalStorageAccess = value; + } /** {@hide} */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) diff --git a/core/java/android/content/pm/parsing/ParsingPackage.java b/core/java/android/content/pm/parsing/ParsingPackage.java index ba6416d0a396a..4dc9ce8be7501 100644 --- a/core/java/android/content/pm/parsing/ParsingPackage.java +++ b/core/java/android/content/pm/parsing/ParsingPackage.java @@ -257,6 +257,9 @@ public interface ParsingPackage extends ParsingPackageRead { ParsingPackage setNativeHeapZeroInit(@Nullable Boolean nativeHeapZeroInit); + ParsingPackage setRequestOptimizedExternalStorageAccess( + @Nullable Boolean requestOptimizedExternalStorageAccess); + ParsingPackage setCrossProfile(boolean crossProfile); ParsingPackage setFullBackupContent(int fullBackupContent); diff --git a/core/java/android/content/pm/parsing/ParsingPackageImpl.java b/core/java/android/content/pm/parsing/ParsingPackageImpl.java index b3c26abc57dc1..065ed2e95eca8 100644 --- a/core/java/android/content/pm/parsing/ParsingPackageImpl.java +++ b/core/java/android/content/pm/parsing/ParsingPackageImpl.java @@ -389,6 +389,10 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable { @DataClass.ParcelWith(ForBoolean.class) private Boolean nativeHeapZeroInit; + @Nullable + @DataClass.ParcelWith(ForBoolean.class) + private Boolean requestOptimizedExternalStorageAccess; + // TODO(chiuwinson): Non-null @Nullable private ArraySet mimeGroups; @@ -1068,6 +1072,7 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable { appInfo.setGwpAsanMode(gwpAsanMode); appInfo.setMemtagMode(memtagMode); appInfo.setNativeHeapZeroInit(nativeHeapZeroInit); + appInfo.setRequestOptimizedExternalStorageAccess(requestOptimizedExternalStorageAccess); appInfo.setBaseCodePath(mBaseApkPath); appInfo.setBaseResourcePath(mBaseApkPath); appInfo.setCodePath(mPath); @@ -1203,6 +1208,7 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable { dest.writeMap(this.mProperties); dest.writeInt(this.memtagMode); sForBoolean.parcel(this.nativeHeapZeroInit, dest, flags); + sForBoolean.parcel(this.requestOptimizedExternalStorageAccess, dest, flags); } public ParsingPackageImpl(Parcel in) { @@ -1326,6 +1332,7 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable { this.mProperties = in.createTypedArrayMap(Property.CREATOR); this.memtagMode = in.readInt(); this.nativeHeapZeroInit = sForBoolean.unparcel(in); + this.requestOptimizedExternalStorageAccess = sForBoolean.unparcel(in); assignDerivedFields(); } @@ -2105,6 +2112,12 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable { return nativeHeapZeroInit; } + @Nullable + @Override + public Boolean hasRequestOptimizedExternalStorageAccess() { + return requestOptimizedExternalStorageAccess; + } + @Override public boolean isPartiallyDirectBootAware() { return getBoolean(Booleans.PARTIALLY_DIRECT_BOOT_AWARE); @@ -2554,6 +2567,11 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable { return this; } + @Override + public ParsingPackageImpl setRequestOptimizedExternalStorageAccess(@Nullable Boolean value) { + requestOptimizedExternalStorageAccess = value; + return this; + } @Override public ParsingPackageImpl setPartiallyDirectBootAware(boolean value) { return setBoolean(Booleans.PARTIALLY_DIRECT_BOOT_AWARE, value); diff --git a/core/java/android/content/pm/parsing/ParsingPackageRead.java b/core/java/android/content/pm/parsing/ParsingPackageRead.java index 9f52183713939..47dfa9d13c7c6 100644 --- a/core/java/android/content/pm/parsing/ParsingPackageRead.java +++ b/core/java/android/content/pm/parsing/ParsingPackageRead.java @@ -902,6 +902,9 @@ public interface ParsingPackageRead extends Parcelable { @Nullable Boolean isNativeHeapZeroInit(); + @Nullable + Boolean hasRequestOptimizedExternalStorageAccess(); + // TODO(b/135203078): Hide and enforce going through PackageInfoUtils ApplicationInfo toAppInfoWithoutState(); diff --git a/core/java/android/content/pm/parsing/ParsingPackageUtils.java b/core/java/android/content/pm/parsing/ParsingPackageUtils.java index 2be0157836aef..0e1574c8da922 100644 --- a/core/java/android/content/pm/parsing/ParsingPackageUtils.java +++ b/core/java/android/content/pm/parsing/ParsingPackageUtils.java @@ -2012,6 +2012,12 @@ public class ParsingPackageUtils { pkg.setNativeHeapZeroInit(sa.getBoolean( R.styleable.AndroidManifestApplication_nativeHeapZeroInit, false)); } + if (sa.hasValue( + R.styleable.AndroidManifestApplication_requestOptimizedExternalStorageAccess)) { + pkg.setRequestOptimizedExternalStorageAccess(sa.getBoolean(R.styleable + .AndroidManifestApplication_requestOptimizedExternalStorageAccess, + false)); + } } finally { sa.recycle(); } diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml index 140163e476007..38e8f83ff767d 100644 --- a/core/res/res/values/attrs_manifest.xml +++ b/core/res/res/values/attrs_manifest.xml @@ -1853,6 +1853,25 @@ --> + + +