Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 19b55867 authored by Hui Yu's avatar Hui Yu
Browse files

DeviceIdleController updates AMS with temp allowlist type.

1. add a "type" parameter to AMS.updateDeviceIdleTempWhitelist() which is
called by DeviceIdleController.
2. The default temp allowlist type is TEMPORARY_WHITELIST_TYPE_FOREGROUND_SERVICE_ALLOWED
which allows BG-FGS launch.
3. AMS.tempWhitelistUidLocked() already has a type parameter. Other API
to add temp allowlist can also add type parameter other than the
default.

Bug: 175244558.
Test: atest cts/tests/app/src/android/app/cts/ActivityManagerFgsBgStartTest.java

Change-Id: Ib42c445c15966bd260964782a7254ed2a7ffa405
parent ab9dd642
Loading
Loading
Loading
Loading
+13 −2
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.server;

import android.app.BroadcastOptions;

import com.android.server.deviceidle.IDeviceIdleConstraint;

public interface DeviceIdleInternal {
@@ -32,8 +34,17 @@ public interface DeviceIdleInternal {
    void addPowerSaveTempWhitelistApp(int callingUid, String packageName,
            long duration, int userId, boolean sync, String reason);

    // duration in milliseconds
    void addPowerSaveTempWhitelistAppDirect(int uid, long duration, boolean sync,
    /**
     * Called by ActivityManagerService to directly add UID to DeviceIdleController's temp
     * allowlist.
     * @param uid
     * @param duration duration in milliseconds
     * @param type temp allowlist type defined at {@link BroadcastOptions.TempAllowListType}
     * @param sync
     * @param reason
     */
    void addPowerSaveTempWhitelistAppDirect(int uid, long duration,
            @BroadcastOptions.TempAllowListType int type, boolean sync,
            String reason);

    // duration in milliseconds
+29 −16
Original line number Diff line number Diff line
@@ -21,6 +21,8 @@ import android.annotation.NonNull;
import android.app.ActivityManager;
import android.app.ActivityManagerInternal;
import android.app.AlarmManager;
import android.app.BroadcastOptions;
import android.app.BroadcastOptions.TempAllowListType;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -1941,9 +1943,9 @@ public class DeviceIdleController extends SystemService

        // duration in milliseconds
        @Override
        public void addPowerSaveTempWhitelistAppDirect(int uid, long duration, boolean sync,
                String reason) {
            addPowerSaveTempWhitelistAppDirectInternal(0, uid, duration, sync, reason);
        public void addPowerSaveTempWhitelistAppDirect(int uid, long duration,
                @TempAllowListType int type, boolean sync, String reason) {
            addPowerSaveTempWhitelistAppDirectInternal(0, uid, duration, type, sync, reason);
        }

        // duration in milliseconds
@@ -2719,7 +2721,9 @@ public class DeviceIdleController extends SystemService
            long duration, int userId, boolean sync, String reason) {
        try {
            int uid = getContext().getPackageManager().getPackageUidAsUser(packageName, userId);
            addPowerSaveTempWhitelistAppDirectInternal(callingUid, uid, duration, sync, reason);
            addPowerSaveTempWhitelistAppDirectInternal(callingUid, uid, duration,
                    BroadcastOptions.TEMPORARY_WHITELIST_TYPE_FOREGROUND_SERVICE_ALLOWED, sync,
                    reason);
        } catch (NameNotFoundException e) {
        }
    }
@@ -2729,7 +2733,7 @@ public class DeviceIdleController extends SystemService
     * app an exemption to access network and acquire wakelocks.
     */
    void addPowerSaveTempWhitelistAppDirectInternal(int callingUid, int uid,
            long duration, boolean sync, String reason) {
            long duration, @TempAllowListType int type, boolean sync, String reason) {
        final long timeNow = SystemClock.elapsedRealtime();
        boolean informWhitelistChanged = false;
        int appId = UserHandle.getAppId(uid);
@@ -2761,7 +2765,7 @@ public class DeviceIdleController extends SystemService
                } catch (RemoteException e) {
                }
                postTempActiveTimeoutMessage(uid, duration);
                updateTempWhitelistAppIdsLocked(appId, true);
                updateTempWhitelistAppIdsLocked(uid, true, duration, type);
                if (sync) {
                    informWhitelistChanged = true;
                } else {
@@ -2786,8 +2790,7 @@ public class DeviceIdleController extends SystemService
        try {
            final int uid = getContext().getPackageManager().getPackageUidAsUser(
                    packageName, userId);
            final int appId = UserHandle.getAppId(uid);
            removePowerSaveTempWhitelistAppDirectInternal(appId);
            removePowerSaveTempWhitelistAppDirectInternal(uid);
        } catch (NameNotFoundException e) {
        }
    }
@@ -2821,7 +2824,8 @@ public class DeviceIdleController extends SystemService
            Slog.d(TAG, "checkTempAppWhitelistTimeout: uid=" + uid + ", timeNow=" + timeNow);
        }
        synchronized (this) {
            Pair<MutableLong, String> entry = mTempWhitelistAppIdEndTimes.get(appId);
            Pair<MutableLong, String> entry =
                    mTempWhitelistAppIdEndTimes.get(appId);
            if (entry == null) {
                // Nothing to do
                return;
@@ -2832,7 +2836,7 @@ public class DeviceIdleController extends SystemService
            } else {
                // Need more time
                if (DEBUG) {
                    Slog.d(TAG, "Time to remove AppId " + appId + ": " + entry.first.value);
                    Slog.d(TAG, "Time to remove uid " + uid + ": " + entry.first.value);
                }
                postTempActiveTimeoutMessage(uid, entry.first.value - timeNow);
            }
@@ -2841,12 +2845,12 @@ public class DeviceIdleController extends SystemService

    @GuardedBy("this")
    private void onAppRemovedFromTempWhitelistLocked(int uid, String reason) {
        final int appId = UserHandle.getAppId(uid);
        if (DEBUG) {
            Slog.d(TAG, "Removing uid " + uid + " from temp whitelist");
        }
        updateTempWhitelistAppIdsLocked(appId, false);
        mHandler.obtainMessage(MSG_REPORT_TEMP_APP_WHITELIST_CHANGED_TO_NPMS, appId, 0)
        final int appId = UserHandle.getAppId(uid);
        updateTempWhitelistAppIdsLocked(uid, false, 0, 0);
        mHandler.obtainMessage(MSG_REPORT_TEMP_APP_WHITELIST_CHANGED, appId, 0)
                .sendToTarget();
        reportTempWhitelistChangedLocked(uid, false);
        try {
@@ -3869,7 +3873,16 @@ public class DeviceIdleController extends SystemService
        passWhiteListsToForceAppStandbyTrackerLocked();
    }

    private void updateTempWhitelistAppIdsLocked(int appId, boolean adding) {
    /**
     * update temp allowlist.
     * @param uid uid to add or remove from temp allowlist.
     * @param adding true to add to temp allowlist, false to remove from temp allowlist.
     * @param durationMs duration in milliseconds to add to temp allowlist, only valid when
     *                   param adding is true.
     * @param type temp allowlist type defined at {@link BroadcastOptions.TempAllowListType}
     */
    private void updateTempWhitelistAppIdsLocked(int uid, boolean adding, long durationMs,
            @TempAllowListType int type) {
        final int size = mTempWhitelistAppIdEndTimes.size();
        if (mTempWhitelistAppIdArray.length != size) {
            mTempWhitelistAppIdArray = new int[size];
@@ -3882,8 +3895,8 @@ public class DeviceIdleController extends SystemService
                Slog.d(TAG, "Setting activity manager temp whitelist to "
                        + Arrays.toString(mTempWhitelistAppIdArray));
            }
            mLocalActivityManager.updateDeviceIdleTempWhitelist(mTempWhitelistAppIdArray, appId,
                    adding);
            mLocalActivityManager.updateDeviceIdleTempWhitelist(mTempWhitelistAppIdArray, uid,
                    adding, durationMs, type);
        }
        if (mLocalPowerManager != null) {
            if (DEBUG) {
+9 −4
Original line number Diff line number Diff line
@@ -98,7 +98,7 @@ public abstract class ActivityManagerInternal {
    public abstract void killForegroundAppsForUser(@UserIdInt int userId);

    /**
     * Sets how long a {@link PendingIntent} can be temporarily whitelist to by bypass restrictions
     * Sets how long a {@link PendingIntent} can be temporarily allowlisted to bypass restrictions
     * such as Power Save mode.
     * @param target
     * @param whitelistToken
@@ -132,9 +132,14 @@ public abstract class ActivityManagerInternal {

    /**
     * Update information about which app IDs are on the temp whitelist.
     */
    public abstract void updateDeviceIdleTempWhitelist(int[] appids, int changingAppId,
            boolean adding);
     * @param appids the updated list of appIds in temp allowlist.
     * @param changingUid uid to add or remove to temp allowlist.
     * @param adding true to add to temp allowlist, false to remove from temp allowlist.
     * @param durationMs when adding is true, the duration to be in temp allowlist.
     * @param type temp allowlist type defined at {@link BroadcastOptions.TempAllowListType}.
     */
    public abstract void updateDeviceIdleTempWhitelist(int[] appids, int changingUid,
            boolean adding, long durationMs, @BroadcastOptions.TempAllowListType int type);

    /**
     * Get the procstate for the UID.  The return value will be between
+1 −0
Original line number Diff line number Diff line
@@ -626,6 +626,7 @@ message ActivityManagerServiceDumpProcessesProto {
        optional int32 target_uid = 1;
        optional int64 duration_ms = 2;
        optional string tag = 3;
        optional int32 type = 4;
    }
    repeated PendingTempWhitelist pending_temp_whitelist = 26;

+22 −10
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ import static android.app.ActivityManager.PROCESS_STATE_TOP;
import static android.app.ActivityManagerInternal.ALLOW_FULL_ONLY;
import static android.app.ActivityManagerInternal.ALLOW_NON_FULL;
import static android.app.AppOpsManager.OP_NONE;
import static android.app.BroadcastOptions.TEMPORARY_WHITELIST_TYPE_FOREGROUND_SERVICE_ALLOWED;
import static android.content.pm.ApplicationInfo.HIDDEN_API_ENFORCEMENT_DEFAULT;
import static android.content.pm.PackageManager.GET_SHARED_LIBRARY_FILES;
import static android.content.pm.PackageManager.MATCH_ALL;
@@ -1085,11 +1086,13 @@ public class ActivityManagerService extends IActivityManager.Stub
        final int targetUid;
        final long duration;
        final String tag;
        final int type;
        PendingTempWhitelist(int _targetUid, long _duration, String _tag) {
        PendingTempWhitelist(int _targetUid, long _duration, String _tag, int _type) {
            targetUid = _targetUid;
            duration = _duration;
            tag = _tag;
            type = _type;
        }
        void dumpDebug(ProtoOutputStream proto, long fieldId) {
@@ -1097,6 +1100,7 @@ public class ActivityManagerService extends IActivityManager.Stub
            proto.write(ActivityManagerServiceDumpProcessesProto.PendingTempWhitelist.TARGET_UID, targetUid);
            proto.write(ActivityManagerServiceDumpProcessesProto.PendingTempWhitelist.DURATION_MS, duration);
            proto.write(ActivityManagerServiceDumpProcessesProto.PendingTempWhitelist.TAG, tag);
            proto.write(ActivityManagerServiceDumpProcessesProto.PendingTempWhitelist.TYPE, type);
            proto.end(token);
        }
    }
@@ -5526,8 +5530,7 @@ public class ActivityManagerService extends IActivityManager.Stub
    }
    boolean isWhitelistedForFgsStartLocked(int uid) {
        final int appId = UserHandle.getAppId(uid);
        return Arrays.binarySearch(mDeviceIdleExceptIdleWhitelist, appId) >= 0
        return Arrays.binarySearch(mDeviceIdleExceptIdleWhitelist, UserHandle.getAppId(uid)) >= 0
                || mFgsStartTempAllowList.isAllowed(uid);
    }
@@ -9298,6 +9301,8 @@ public class ActivityManagerService extends IActivityManager.Stub
                    TimeUtils.formatDuration(ptw.duration, pw);
                    pw.print(" ");
                    pw.println(ptw.tag);
                    pw.print(" ");
                    pw.print(ptw.type);
                }
            }
        }
@@ -15359,11 +15364,12 @@ public class ActivityManagerService extends IActivityManager.Stub
     */
    @GuardedBy("this")
    void tempWhitelistUidLocked(int targetUid, long duration, String tag, int type) {
        mPendingTempWhitelist.put(targetUid, new PendingTempWhitelist(targetUid, duration, tag));
        mPendingTempWhitelist.put(targetUid,
                new PendingTempWhitelist(targetUid, duration, tag, type));
        setUidTempWhitelistStateLocked(targetUid, true);
        mUiHandler.obtainMessage(PUSH_TEMP_WHITELIST_UI_MSG).sendToTarget();
        if (type == BroadcastOptions.TEMPORARY_WHITELIST_TYPE_FOREGROUND_SERVICE_ALLOWED) {
        if (type == TEMPORARY_WHITELIST_TYPE_FOREGROUND_SERVICE_ALLOWED) {
            mFgsStartTempAllowList.add(targetUid, duration);
        }
    }
@@ -15389,7 +15395,7 @@ public class ActivityManagerService extends IActivityManager.Stub
            for (int i = 0; i < N; i++) {
                PendingTempWhitelist ptw = list[i];
                mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(ptw.targetUid,
                        ptw.duration, true, ptw.tag);
                        ptw.duration, ptw.type, true, ptw.tag);
            }
        }
@@ -15406,8 +15412,8 @@ public class ActivityManagerService extends IActivityManager.Stub
    }
    @GuardedBy("this")
    final void setAppIdTempWhitelistStateLocked(int appId, boolean onWhitelist) {
        mOomAdjuster.setAppIdTempWhitelistStateLocked(appId, onWhitelist);
    final void setAppIdTempWhitelistStateLocked(int uid, boolean onWhitelist) {
        mOomAdjuster.setAppIdTempWhitelistStateLocked(uid, onWhitelist);
    }
    @GuardedBy("this")
@@ -15999,10 +16005,16 @@ public class ActivityManagerService extends IActivityManager.Stub
        }
        @Override
        public void updateDeviceIdleTempWhitelist(int[] appids, int changingAppId, boolean adding) {
        public void updateDeviceIdleTempWhitelist(int[] appids, int changingUid, boolean adding,
                long durationMs, @BroadcastOptions.TempAllowListType int type) {
            synchronized (ActivityManagerService.this) {
                mDeviceIdleTempWhitelist = appids;
                setAppIdTempWhitelistStateLocked(changingAppId, adding);
                if (adding) {
                    if (type == TEMPORARY_WHITELIST_TYPE_FOREGROUND_SERVICE_ALLOWED) {
                        mFgsStartTempAllowList.add(changingUid, durationMs);
                    }
                }
                setAppIdTempWhitelistStateLocked(changingUid, adding);
            }
        }
Loading