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
This commit is contained in:
Sahana Rao
2021-03-22 11:39:59 +00:00
parent 385414ee28
commit 24734440c0
9 changed files with 88 additions and 0 deletions

View File

@@ -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

View File

@@ -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();

View File

@@ -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<ApplicationInfo> 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
* <ul>
* <li>{@code true} if this app requested optimized external storage access
* <li>{@code false} if this app requests to disable optimized external storage access.
* <li>{@code null} if the app didn't specify
* {@link android.R.styleable#AndroidManifestApplication_requestOptimizedExternalStorageAccess}
* in its manifest file.
* </ul>
*
* @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)

View File

@@ -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);

View File

@@ -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<String> 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);

View File

@@ -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();

View File

@@ -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();
}

View File

@@ -1853,6 +1853,25 @@
-->
<attr name="preserveLegacyExternalStorage" format="boolean" />
<!-- If {@code true} this app would like optimized external storage access.
<p> This flag can only be used by apps holding
<ul>
<li>{@link android.Manifest.permission#MANAGE_EXTERNAL_STORAGE} permission or
<li>{@link android.app.role}#SYSTEM_GALLERY role.
</ul>
When the flag is set, bulk file path operations will be optimized.
The default value is {@code true} if
<ul>
<li>app has {@link android.Manifest.permission#MANAGE_EXTERNAL_STORAGE} permission and
targets targetSDK<=30.
<li>app has {@link android.app.role}#SYSTEM_GALLERY role and targetSDK<=29
</ul>
{@code false} otherwise.
-->
<attr name="requestOptimizedExternalStorageAccess" format="boolean" />
<!-- If {@code true} this app declares that it should be visible to all other apps on
device, regardless of what they declare via the {@code queries} tags in their
manifest.

View File

@@ -3092,6 +3092,7 @@
<public name="attributionTags"/>
<public name="suppressesSpellChecker" />
<public name="usesPermissionFlags" />
<public name="requestOptimizedExternalStorageAccess" />
</public-group>
<public-group type="drawable" first-id="0x010800b5">