summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apex/jobscheduler/framework/java/com/android/server/DeviceIdleInternal.java9
-rw-r--r--apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java39
-rw-r--r--core/java/android/app/ActivityManagerInternal.java5
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerConstants.java41
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java21
5 files changed, 98 insertions, 17 deletions
diff --git a/apex/jobscheduler/framework/java/com/android/server/DeviceIdleInternal.java b/apex/jobscheduler/framework/java/com/android/server/DeviceIdleInternal.java
index a9ca5cf5a26a..caf7e7f4a4ed 100644
--- a/apex/jobscheduler/framework/java/com/android/server/DeviceIdleInternal.java
+++ b/apex/jobscheduler/framework/java/com/android/server/DeviceIdleInternal.java
@@ -96,4 +96,13 @@ public interface DeviceIdleInternal {
* that the device is stationary or in motion.
*/
void unregisterStationaryListener(StationaryListener listener);
+
+ /**
+ * Apply some restrictions on temp allowlist type based on the reasonCode.
+ * @param reasonCode temp allowlist reason code.
+ * @param defaultType default temp allowlist type if reasonCode can not decide a type.
+ * @return temp allowlist type based on the reasonCode.
+ */
+ @TempAllowListType int getTempAllowListType(@ReasonCode int reasonCode,
+ @TempAllowListType int defaultType);
}
diff --git a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
index 57c8300b66f6..60f5769a46f7 100644
--- a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
+++ b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
@@ -19,6 +19,7 @@ package com.android.server;
import static android.os.PowerExemptionManager.REASON_SHELL;
import static android.os.PowerExemptionManager.REASON_UNKNOWN;
import static android.os.PowerExemptionManager.TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED;
+import static android.os.PowerExemptionManager.TEMPORARY_ALLOW_LIST_TYPE_NONE;
import static android.os.Process.INVALID_UID;
import android.Manifest;
@@ -58,6 +59,7 @@ import android.os.Handler;
import android.os.IDeviceIdleController;
import android.os.Looper;
import android.os.Message;
+import android.os.PowerExemptionManager;
import android.os.PowerExemptionManager.ReasonCode;
import android.os.PowerExemptionManager.TempAllowListType;
import android.os.PowerManager;
@@ -2015,6 +2017,12 @@ public class DeviceIdleController extends SystemService
public void unregisterStationaryListener(StationaryListener listener) {
DeviceIdleController.this.unregisterStationaryListener(listener);
}
+
+ @Override
+ public @TempAllowListType int getTempAllowListType(@ReasonCode int reasonCode,
+ @TempAllowListType int defaultType) {
+ return DeviceIdleController.this.getTempAllowListType(reasonCode, defaultType);
+ }
}
private class LocalPowerAllowlistService implements PowerAllowlistInternal {
@@ -2689,6 +2697,18 @@ public class DeviceIdleController extends SystemService
}
}
+ private @TempAllowListType int getTempAllowListType(@ReasonCode int reasonCode,
+ @TempAllowListType int defaultType) {
+ switch (reasonCode) {
+ case PowerExemptionManager.REASON_PUSH_MESSAGING_OVER_QUOTA:
+ return mLocalActivityManager.getPushMessagingOverQuotaBehavior();
+ case PowerExemptionManager.REASON_DENIED:
+ return TEMPORARY_ALLOW_LIST_TYPE_NONE;
+ default:
+ return defaultType;
+ }
+ }
+
void addPowerSaveTempAllowlistAppChecked(String packageName, long duration,
int userId, @ReasonCode int reasonCode, @Nullable String reason)
throws RemoteException {
@@ -2705,9 +2725,12 @@ public class DeviceIdleController extends SystemService
"addPowerSaveTempWhitelistApp", null);
final long token = Binder.clearCallingIdentity();
try {
- addPowerSaveTempAllowlistAppInternal(callingUid,
- packageName, duration, TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED,
- userId, true, reasonCode, reason);
+ @TempAllowListType int type = getTempAllowListType(reasonCode,
+ TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED);
+ if (type != TEMPORARY_ALLOW_LIST_TYPE_NONE) {
+ addPowerSaveTempAllowlistAppInternal(callingUid,
+ packageName, duration, type, userId, true, reasonCode, reason);
+ }
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -2741,16 +2764,6 @@ public class DeviceIdleController extends SystemService
void addPowerSaveTempAllowlistAppInternal(int callingUid, String packageName,
long durationMs, @TempAllowListType int tempAllowListType, int userId, boolean sync,
@ReasonCode int reasonCode, @Nullable String reason) {
- synchronized (this) {
- int callingAppId = UserHandle.getAppId(callingUid);
- if (callingAppId >= Process.FIRST_APPLICATION_UID) {
- if (!mPowerSaveWhitelistSystemAppIds.get(callingAppId)) {
- throw new SecurityException(
- "Calling app " + UserHandle.formatUid(callingUid)
- + " is not on whitelist");
- }
- }
- }
try {
int uid = getContext().getPackageManager().getPackageUidAsUser(packageName, userId);
addPowerSaveTempWhitelistAppDirectInternal(callingUid, uid, durationMs,
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index 605340061994..ab610e4e71c6 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -583,4 +583,9 @@ public abstract class ActivityManagerInternal {
* Is the FGS started from an uid temporarily allowed to have while-in-use permission?
*/
public abstract boolean isTempAllowlistedForFgsWhileInUse(int uid);
+
+ /**
+ * Return the temp allowlist type when server push messaging is over the quota.
+ */
+ public abstract @TempAllowListType int getPushMessagingOverQuotaBehavior();
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerConstants.java b/services/core/java/com/android/server/am/ActivityManagerConstants.java
index bf574521b895..d8eccef8488e 100644
--- a/services/core/java/com/android/server/am/ActivityManagerConstants.java
+++ b/services/core/java/com/android/server/am/ActivityManagerConstants.java
@@ -16,6 +16,9 @@
package com.android.server.am;
+import static android.os.PowerExemptionManager.TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED;
+import static android.os.PowerExemptionManager.TEMPORARY_ALLOW_LIST_TYPE_NONE;
+
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
import android.app.ActivityThread;
@@ -27,6 +30,7 @@ import android.net.Uri;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
+import android.os.PowerExemptionManager;
import android.provider.DeviceConfig;
import android.provider.DeviceConfig.OnPropertiesChangedListener;
import android.provider.DeviceConfig.Properties;
@@ -139,6 +143,11 @@ final class ActivityManagerConstants extends ContentObserver {
private static final long DEFAULT_FG_TO_BG_FGS_GRACE_DURATION = 5 * 1000;
private static final int DEFAULT_FGS_START_FOREGROUND_TIMEOUT_MS = 10 * 1000;
private static final float DEFAULT_FGS_ATOM_SAMPLE_RATE = 1; // 100 %
+ /**
+ * Same as {@link TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED}
+ */
+ private static final int
+ DEFAULT_PUSH_MESSAGING_OVER_QUOTA_BEHAVIOR = 1;
// Flag stored in the DeviceConfig API.
/**
@@ -210,6 +219,13 @@ final class ActivityManagerConstants extends ContentObserver {
private static final String KEY_DEFERRED_FGS_NOTIFICATION_EXCLUSION_TIME =
"deferred_fgs_notification_exclusion_time";
+ /**
+ * Default value for mPushMessagingOverQuotaBehavior if not explicitly set in
+ * Settings.Global.
+ */
+ private static final String KEY_PUSH_MESSAGING_OVER_QUOTA_BEHAVIOR =
+ "push_messaging_over_quota_behavior";
+
// Maximum number of cached processes we will allow.
public int MAX_CACHED_PROCESSES = DEFAULT_MAX_CACHED_PROCESSES;
@@ -413,6 +429,13 @@ final class ActivityManagerConstants extends ContentObserver {
// before another FGS notifiction from that app can be deferred.
volatile long mFgsNotificationDeferralExclusionTime = 2 * 60 * 1000L;
+ /**
+ * When server pushing message is over the quote, select one of the temp allow list type as
+ * defined in {@link PowerExemptionManager.TempAllowListType}
+ */
+ volatile @PowerExemptionManager.TempAllowListType int mPushMessagingOverQuotaBehavior =
+ DEFAULT_PUSH_MESSAGING_OVER_QUOTA_BEHAVIOR;
+
/*
* At boot time, broadcast receiver ACTION_BOOT_COMPLETED, ACTION_LOCKED_BOOT_COMPLETED and
* ACTION_PRE_BOOT_COMPLETED are temp allowlisted to start FGS for a duration of time in
@@ -605,6 +628,9 @@ final class ActivityManagerConstants extends ContentObserver {
case KEY_DEFERRED_FGS_NOTIFICATION_EXCLUSION_TIME:
updateFgsNotificationDeferralExclusionTime();
break;
+ case KEY_PUSH_MESSAGING_OVER_QUOTA_BEHAVIOR:
+ updatePushMessagingOverQuotaBehavior();
+ break;
case KEY_OOMADJ_UPDATE_POLICY:
updateOomAdjUpdatePolicy();
break;
@@ -909,6 +935,19 @@ final class ActivityManagerConstants extends ContentObserver {
/*default value*/ 2 * 60 * 1000L);
}
+ private void updatePushMessagingOverQuotaBehavior() {
+ mPushMessagingOverQuotaBehavior = DeviceConfig.getInt(
+ DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
+ KEY_PUSH_MESSAGING_OVER_QUOTA_BEHAVIOR,
+ DEFAULT_PUSH_MESSAGING_OVER_QUOTA_BEHAVIOR);
+ if (mPushMessagingOverQuotaBehavior < TEMPORARY_ALLOW_LIST_TYPE_NONE
+ || mPushMessagingOverQuotaBehavior
+ > TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED) {
+ mPushMessagingOverQuotaBehavior =
+ DEFAULT_PUSH_MESSAGING_OVER_QUOTA_BEHAVIOR;
+ }
+ }
+
private void updateOomAdjUpdatePolicy() {
OOMADJ_UPDATE_QUICK = DeviceConfig.getInt(
DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
@@ -1166,6 +1205,8 @@ final class ActivityManagerConstants extends ContentObserver {
pw.print("="); pw.println(mFgsStartRestrictionCheckCallerTargetSdk);
pw.print(" "); pw.print(KEY_FGS_ATOM_SAMPLE_RATE);
pw.print("="); pw.println(mDefaultFgsAtomSampleRate);
+ pw.print(" "); pw.print(KEY_PUSH_MESSAGING_OVER_QUOTA_BEHAVIOR);
+ pw.print("="); pw.println(mPushMessagingOverQuotaBehavior);
pw.println();
if (mOverrideMaxCachedProcesses >= 0) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 00b13b1bb6b0..9aedf1504df5 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -51,7 +51,8 @@ import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_NORMAL;
import static android.os.IServiceManager.DUMP_FLAG_PROTO;
import static android.os.InputConstants.DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
import static android.os.PowerExemptionManager.REASON_SYSTEM_ALLOW_LISTED;
-import static android.os.PowerWhitelistManager.TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED;
+import static android.os.PowerExemptionManager.TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED;
+import static android.os.PowerExemptionManager.TEMPORARY_ALLOW_LIST_TYPE_NONE;
import static android.os.Process.BLUETOOTH_UID;
import static android.os.Process.FIRST_APPLICATION_UID;
import static android.os.Process.INVALID_UID;
@@ -14603,15 +14604,20 @@ public class ActivityManagerService extends IActivityManager.Stub
*/
@GuardedBy("this")
void tempAllowlistUidLocked(int targetUid, long duration, @ReasonCode int reasonCode,
- String reason, int type, int callingUid) {
+ String reason, @TempAllowListType int type, int callingUid) {
synchronized (mProcLock) {
+ // The temp allowlist type could change according to the reasonCode.
+ type = mLocalDeviceIdleController.getTempAllowListType(reasonCode, type);
+ if (type == TEMPORARY_ALLOW_LIST_TYPE_NONE) {
+ return;
+ }
mPendingTempAllowlist.put(targetUid,
new PendingTempAllowlist(targetUid, duration, reasonCode, reason, type,
callingUid));
setUidTempAllowlistStateLSP(targetUid, true);
mUiHandler.obtainMessage(PUSH_TEMP_ALLOWLIST_UI_MSG).sendToTarget();
- if (type == TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED) {
+ if (type == TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED) {
mFgsStartTempAllowList.add(targetUid, duration,
new FgsTempAllowListItem(duration, reasonCode, reason, callingUid));
}
@@ -15285,7 +15291,7 @@ public class ActivityManagerService extends IActivityManager.Stub
synchronized (mProcLock) {
mDeviceIdleTempAllowlist = appids;
if (adding) {
- if (type == TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED) {
+ if (type == TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED) {
mFgsStartTempAllowList.add(changingUid, durationMs,
new FgsTempAllowListItem(durationMs, reasonCode, reason,
callingUid));
@@ -16152,6 +16158,13 @@ public class ActivityManagerService extends IActivityManager.Stub
return mServices.canAllowWhileInUsePermissionInFgsLocked(pid, uid, packageName);
}
}
+
+ @Override
+ public @TempAllowListType int getPushMessagingOverQuotaBehavior() {
+ synchronized (ActivityManagerService.this) {
+ return mConstants.mPushMessagingOverQuotaBehavior;
+ }
+ }
}
long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {