Merge "Implement requestForegroundServiceExemption, without enabling it" into sc-dev

This commit is contained in:
Makoto Onuki
2021-05-11 15:55:14 +00:00
committed by Android (Google) Code Review
12 changed files with 96 additions and 3 deletions

View File

@@ -344,6 +344,9 @@ public class PowerExemptionManager {
*/
public static final int REASON_MEDIA_SESSION_CALLBACK = 317;
/** @hide The app requests out-out. */
public static final int REASON_OPT_OUT_REQUESTED = 1000;
/**
* The list of BG-FGS-Launch and temp-allow-list reason code.
* @hide
@@ -411,6 +414,7 @@ public class PowerExemptionManager {
REASON_EVENT_MMS,
REASON_SHELL,
REASON_MEDIA_SESSION_CALLBACK,
REASON_OPT_OUT_REQUESTED,
})
@Retention(RetentionPolicy.SOURCE)
public @interface ReasonCode {}
@@ -709,6 +713,8 @@ public class PowerExemptionManager {
return "SHELL";
case REASON_MEDIA_SESSION_CALLBACK:
return "MEDIA_SESSION_CALLBACK";
case REASON_OPT_OUT_REQUESTED:
return "REASON_OPT_OUT_REQUESTED";
default:
return "(unknown:" + reasonCode + ")";
}

View File

@@ -50,6 +50,10 @@ package android {
field public static final String UNDEFINED = "android.permission-group.UNDEFINED";
}
public static final class R.attr {
field public static final int requestForegroundServiceExemption;
}
public static final class R.bool {
field public static final int config_assistantOnTopOfDream = 17891333; // 0x1110005
field public static final int config_perDisplayFocusEnabled = 17891332; // 0x1110004
@@ -806,6 +810,7 @@ package android.content.pm {
}
public class ApplicationInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable {
method public boolean hasRequestForegroundServiceExemption();
method public boolean isPrivilegedApp();
method public boolean isSystemApp();
field public static final int PRIVATE_FLAG_PRIVILEGED = 8; // 0x8

View File

@@ -778,9 +778,18 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
*/
public static final int PRIVATE_FLAG_EXT_PROFILEABLE = 1 << 0;
/**
* Value for {@link #privateFlagsExt}: whether this application has requested
* exemption from the foreground service restriction introduced in S
* (https://developer.android.com/about/versions/12/foreground-services).
* @hide
*/
public static final int PRIVATE_FLAG_EXT_REQUEST_FOREGROUND_SERVICE_EXEMPTION = 1 << 1;
/** @hide */
@IntDef(flag = true, prefix = { "PRIVATE_FLAG_EXT_" }, value = {
PRIVATE_FLAG_EXT_PROFILEABLE,
PRIVATE_FLAG_EXT_REQUEST_FOREGROUND_SERVICE_EXEMPTION,
})
@Retention(RetentionPolicy.SOURCE)
public @interface ApplicationInfoPrivateFlagsExt {}
@@ -2444,6 +2453,17 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
return (privateFlags & ApplicationInfo.PRIVATE_FLAG_IS_RESOURCE_OVERLAY) != 0;
}
/**
* @return whether the app has requested exemption from the foreground service restrictions.
* This does not take any affect for now.
* @hide
*/
@TestApi
public boolean hasRequestForegroundServiceExemption() {
return (privateFlagsExt
& ApplicationInfo.PRIVATE_FLAG_EXT_REQUEST_FOREGROUND_SERVICE_EXEMPTION) != 0;
}
/**
* @hide
*/

View File

@@ -806,7 +806,9 @@ public class PackageInfoWithoutStateUtils {
public static int appInfoPrivateFlagsExt(ParsingPackageRead pkg) {
// @formatter:off
int privateFlagsExt =
flag(pkg.isProfileable(), ApplicationInfo.PRIVATE_FLAG_EXT_PROFILEABLE);
flag(pkg.isProfileable(), ApplicationInfo.PRIVATE_FLAG_EXT_PROFILEABLE)
| flag(pkg.hasRequestForegroundServiceExemption(),
ApplicationInfo.PRIVATE_FLAG_EXT_REQUEST_FOREGROUND_SERVICE_EXEMPTION);
// @formatter:on
return privateFlagsExt;
}

View File

@@ -338,6 +338,8 @@ public interface ParsingPackage extends ParsingPackageRead {
ParsingPackage setTheme(int theme);
ParsingPackage setRequestForegroundServiceExemption(boolean requestForegroundServiceExemption);
ParsingPackage setUpgradeKeySets(@NonNull Set<String> upgradeKeySets);
ParsingPackage setUse32BitAbi(boolean use32BitAbi);

View File

@@ -464,6 +464,7 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable {
CROSS_PROFILE,
ENABLED,
DISALLOW_PROFILING,
REQUEST_FOREGROUND_SERVICE_EXEMPTION,
})
public @interface Values {}
private static final long EXTERNAL_STORAGE = 1L;
@@ -512,6 +513,7 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable {
private static final long CROSS_PROFILE = 1L << 43;
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 ParsingPackageImpl setBoolean(@Booleans.Values long flag, boolean value) {
@@ -2198,6 +2200,11 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable {
return getBoolean(Booleans.PRESERVE_LEGACY_EXTERNAL_STORAGE);
}
@Override
public boolean hasRequestForegroundServiceExemption() {
return getBoolean(Booleans.REQUEST_FOREGROUND_SERVICE_EXEMPTION);
}
@Override
public ParsingPackageImpl setBaseRevisionCode(int value) {
baseRevisionCode = value;
@@ -2419,6 +2426,11 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable {
return this;
}
@Override
public ParsingPackageImpl setRequestForegroundServiceExemption(boolean value) {
return setBoolean(Booleans.REQUEST_FOREGROUND_SERVICE_EXEMPTION, value);
}
@Override
public ParsingPackageImpl setUiOptions(int value) {
uiOptions = value;

View File

@@ -906,10 +906,15 @@ public interface ParsingPackageRead extends Parcelable {
*/
@ApplicationInfo.NativeHeapZeroInitialized
int getNativeHeapZeroInitialized();
@Nullable
Boolean hasRequestRawExternalStorageAccess();
/**
* @see ApplicationInfo#hasRequestForegroundServiceExemption()
* @see R.styleable#AndroidManifest_requestForegroundServiceExemption
*/
boolean hasRequestForegroundServiceExemption();
// TODO(b/135203078): Hide and enforce going through PackageInfoUtils
ApplicationInfo toAppInfoWithoutState();

View File

@@ -2033,6 +2033,12 @@ public class ParsingPackageUtils {
.AndroidManifestApplication_requestRawExternalStorageAccess,
false));
}
if (sa.hasValue(
R.styleable.AndroidManifestApplication_requestForegroundServiceExemption)) {
pkg.setRequestForegroundServiceExemption(sa.getBoolean(R.styleable
.AndroidManifestApplication_requestForegroundServiceExemption,
false));
}
} finally {
sa.recycle();
}

View File

@@ -1954,6 +1954,13 @@
See the <a href="{@docRoot}about/versions/12/backup-restore">Changes in backup and restore</a>
document for the format of the XML file.-->
<attr name="dataExtractionRules" format="reference"/>
<!-- @hide Request exemption from the foreground service restrictions introduced in S
(https://developer.android.com/about/versions/12/foreground-services)
Note the framework <b>ignores</b> this attribute at this time. Once apps target S or above,
there's no way to be exempted (without using a privileged permission).
-->
<attr name="requestForegroundServiceExemption" format="boolean" />
</declare-styleable>
<!-- An attribution is a logical part of an app and is identified by a tag.

View File

@@ -3099,6 +3099,8 @@
<public name="durationBetweenRequestsMillis" />
<public name="showInInputMethodPicker" />
<public name="effectColor" />
<!-- @hide @TestApi -->
<public name="requestForegroundServiceExemption" />
</staging-public-group>
<staging-public-group type="drawable" first-id="0x010800b5">

View File

@@ -24,6 +24,7 @@ import static android.app.ActivityManager.PROCESS_STATE_TOP;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_MANIFEST;
import static android.os.PowerExemptionManager.REASON_ACTIVITY_VISIBILITY_GRACE_PERIOD;
import static android.os.PowerExemptionManager.REASON_OPT_OUT_REQUESTED;
import static android.os.PowerExemptionManager.REASON_OP_ACTIVATE_PLATFORM_VPN;
import static android.os.PowerExemptionManager.REASON_OP_ACTIVATE_VPN;
import static android.os.PowerExemptionManager.REASON_TEMP_ALLOWED_WHILE_IN_USE;
@@ -5874,7 +5875,12 @@ public final class ActiveServices {
ret = REASON_OP_ACTIVATE_PLATFORM_VPN;
}
}
if (ret == REASON_DENIED) {
if (mAm.mConstants.mFgsAllowOptOut
&& targetService.appInfo.hasRequestForegroundServiceExemption()) {
ret = REASON_OPT_OUT_REQUESTED;
}
}
return ret;
}

View File

@@ -110,6 +110,7 @@ final class ActivityManagerConstants extends ContentObserver {
static final String KEY_FGS_START_FOREGROUND_TIMEOUT = "fgs_start_foreground_timeout";
static final String KEY_FGS_ATOM_SAMPLE_RATE = "fgs_atom_sample_rate";
static final String KEY_KILL_FAS_CACHED_IDLE = "kill_fas_cached_idle";
static final String KEY_FGS_ALLOW_OPT_OUT = "fgs_allow_opt_out";
private static final int DEFAULT_MAX_CACHED_PROCESSES = 32;
private static final long DEFAULT_FGSERVICE_MIN_SHOWN_TIME = 2*1000;
@@ -161,6 +162,7 @@ final class ActivityManagerConstants extends ContentObserver {
*/
private static final int
DEFAULT_PUSH_MESSAGING_OVER_QUOTA_BEHAVIOR = 1;
private static final boolean DEFAULT_FGS_ALLOW_OPT_OUT = false;
// Flag stored in the DeviceConfig API.
/**
@@ -493,6 +495,12 @@ final class ActivityManagerConstants extends ContentObserver {
*/
volatile boolean mKillForceAppStandByAndCachedIdle = DEFAULT_KILL_FAS_CACHED_IDLE;
/**
* Whether to allow "opt-out" from the foreground service restrictions.
* (https://developer.android.com/about/versions/12/foreground-services)
*/
volatile boolean mFgsAllowOptOut = DEFAULT_FGS_ALLOW_OPT_OUT;
private final ActivityManagerService mService;
private ContentResolver mResolver;
private final KeyValueListParser mParser = new KeyValueListParser(',');
@@ -701,6 +709,9 @@ final class ActivityManagerConstants extends ContentObserver {
case KEY_KILL_FAS_CACHED_IDLE:
updateKillFasCachedIdle();
break;
case KEY_FGS_ALLOW_OPT_OUT:
updateFgsAllowOptOut();
break;
default:
break;
}
@@ -1040,6 +1051,13 @@ final class ActivityManagerConstants extends ContentObserver {
DEFAULT_KILL_FAS_CACHED_IDLE);
}
private void updateFgsAllowOptOut() {
mFgsAllowOptOut = DeviceConfig.getBoolean(
DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
KEY_FGS_ALLOW_OPT_OUT,
DEFAULT_FGS_ALLOW_OPT_OUT);
}
private void updateImperceptibleKillExemptions() {
IMPERCEPTIBLE_KILL_EXEMPT_PACKAGES.clear();
IMPERCEPTIBLE_KILL_EXEMPT_PACKAGES.addAll(mDefaultImperceptibleKillExemptPackages);
@@ -1260,6 +1278,8 @@ final class ActivityManagerConstants extends ContentObserver {
pw.print("="); pw.println(mFgsAtomSampleRate);
pw.print(" "); pw.print(KEY_PUSH_MESSAGING_OVER_QUOTA_BEHAVIOR);
pw.print("="); pw.println(mPushMessagingOverQuotaBehavior);
pw.print(" "); pw.print(KEY_FGS_ALLOW_OPT_OUT);
pw.print("="); pw.println(mFgsAllowOptOut);
pw.println();
if (mOverrideMaxCachedProcesses >= 0) {