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

Commit 190f2cb7 authored by Dianne Hackborn's avatar Dianne Hackborn
Browse files

Add separate information about user whitelist.

Use this in the alarm manager to allow user whitelisted apps
to have free access to scheduling alarms.

Coming next: lifting sync/job restrictions.

Change-Id: Ib36bd811f866c7af43845edf051e7972397cea22
parent 58a73855
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -25,10 +25,12 @@ interface IDeviceIdleController {
    void removePowerSaveWhitelistApp(String name);
    String[] getSystemPowerWhitelistExceptIdle();
    String[] getSystemPowerWhitelist();
    String[] getUserPowerWhitelist();
    String[] getFullPowerWhitelistExceptIdle();
    String[] getFullPowerWhitelist();
    int[] getAppIdWhitelistExceptIdle();
    int[] getAppIdWhitelist();
    int[] getAppIdUserWhitelist();
    int[] getAppIdTempWhitelist();
    boolean isPowerSaveWhitelistExceptIdleApp(String name);
    boolean isPowerSaveWhitelistApp(String name);
+30 −8
Original line number Diff line number Diff line
@@ -149,6 +149,12 @@ class AlarmManagerService extends SystemService {
    long mAllowWhileIdleMinTime;
    int mNumTimeChanged;

    /**
     * The current set of user whitelisted apps for device idle mode, meaning these are allowed
     * to freely schedule alarms.
     */
    int[] mDeviceIdleUserWhitelist = new int[0];

    /**
     * For each uid, this is the last time we dispatched an "allow while idle" alarm,
     * used to determine the earliest we can dispatch the next such alarm.
@@ -936,6 +942,7 @@ class AlarmManagerService extends SystemService {
        }

        publishBinderService(Context.ALARM_SERVICE, mService);
        publishLocalService(LocalService.class, new LocalService());
    }

    @Override
@@ -1251,14 +1258,6 @@ class AlarmManagerService extends SystemService {
                flags &= ~AlarmManager.FLAG_IDLE_UNTIL;
            }

            // If the caller is a core system component, and not calling to do work on behalf
            // of someone else, then always set ALLOW_WHILE_IDLE_UNRESTRICTED.  This means we
            // will allow these alarms to go off as normal even while idle, with no timing
            // restrictions.
            if (callingUid < Process.FIRST_APPLICATION_UID && workSource == null) {
                flags |= AlarmManager.FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED;
            }

            // If this is an exact time alarm, then it can't be batched with other alarms.
            if (windowLength == AlarmManager.WINDOW_EXACT) {
                flags |= AlarmManager.FLAG_STANDALONE;
@@ -1268,6 +1267,16 @@ class AlarmManagerService extends SystemService {
            // use it to wake early from idle if needed.
            if (alarmClock != null) {
                flags |= AlarmManager.FLAG_WAKE_FROM_IDLE | AlarmManager.FLAG_STANDALONE;

            // If the caller is a core system component or on the user's whitelist, and not calling
            // to do work on behalf of someone else, then always set ALLOW_WHILE_IDLE_UNRESTRICTED.
            // This means we will allow these alarms to go off as normal even while idle, with no
            // timing restrictions.
            } else if (workSource == null && (callingUid < Process.FIRST_APPLICATION_UID
                    || Arrays.binarySearch(mDeviceIdleUserWhitelist,
                            UserHandle.getAppId(callingUid)) >= 0)) {
                flags |= AlarmManager.FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED;
                flags &= ~AlarmManager.FLAG_ALLOW_WHILE_IDLE;
            }

            setImpl(type, triggerAtTime, windowLength, interval, operation, directReceiver,
@@ -1344,6 +1353,12 @@ class AlarmManagerService extends SystemService {
        }
    };

    public final class LocalService {
        public void setDeviceIdleUserWhitelist(int[] appids) {
            setDeviceIdleUserWhitelistImpl(appids);
        }
    }

    void dumpImpl(PrintWriter pw) {
        synchronized (mLock) {
            pw.println("Current Alarm Manager state:");
@@ -1386,6 +1401,7 @@ class AlarmManagerService extends SystemService {
            pw.print("  Next wakeup: "); TimeUtils.formatDuration(mNextWakeup, nowELAPSED, pw);
                    pw.print(" = "); pw.println(sdf.format(new Date(nextWakeupRTC)));
            pw.print("  Num time change events: "); pw.println(mNumTimeChanged);
            pw.println("  mDeviceIdleUserWhitelist=" + Arrays.toString(mDeviceIdleUserWhitelist));

            pw.println();
            pw.println("  Next alarm clock information: ");
@@ -1678,6 +1694,12 @@ class AlarmManagerService extends SystemService {
        }
    }

    void setDeviceIdleUserWhitelistImpl(int[] appids) {
        synchronized (mLock) {
            mDeviceIdleUserWhitelist = appids;
        }
    }

    AlarmManager.AlarmClockInfo getNextAlarmClockImpl(int userId) {
        synchronized (mLock) {
            return mNextAlarmClockForUser.get(userId);
+65 −4
Original line number Diff line number Diff line
@@ -120,6 +120,7 @@ public class DeviceIdleController extends SystemService
    private AlarmManager mAlarmManager;
    private IBatteryStats mBatteryStats;
    private PowerManagerInternal mLocalPowerManager;
    private AlarmManagerService.LocalService mLocalAlarmManager;
    private INetworkPolicyManager mNetworkPolicyManager;
    private DisplayManager mDisplayManager;
    private SensorManager mSensorManager;
@@ -267,6 +268,17 @@ public class DeviceIdleController extends SystemService
     */
    private int[] mPowerSaveWhitelistAllAppIdArray = new int[0];

    /**
     * App IDs that have been white-listed by the user to opt out of power save restrictions.
     */
    private final SparseBooleanArray mPowerSaveWhitelistUserAppIds = new SparseBooleanArray();

    /**
     * Current app IDs that are in the user power save white list.  This array can
     * be shared with others because it will not be modified once set.
     */
    private int[] mPowerSaveWhitelistUserAppIdArray = new int[0];

    /**
     * List of end times for UIDs that are temporarily marked as being allowed to access
     * the network and acquire wakelocks. Times are in milliseconds.
@@ -963,6 +975,10 @@ public class DeviceIdleController extends SystemService
            return getSystemPowerWhitelistInternal();
        }

        @Override public String[] getUserPowerWhitelist() {
            return getUserPowerWhitelistInternal();
        }

        @Override public String[] getFullPowerWhitelistExceptIdle() {
            return getFullPowerWhitelistExceptIdleInternal();
        }
@@ -979,6 +995,10 @@ public class DeviceIdleController extends SystemService
            return getAppIdWhitelistInternal();
        }

        @Override public int[] getAppIdUserWhitelist() {
            return getAppIdUserWhitelistInternal();
        }

        @Override public int[] getAppIdTempWhitelist() {
            return getAppIdTempWhitelistInternal();
        }
@@ -1160,6 +1180,7 @@ public class DeviceIdleController extends SystemService
                mAlarmManager = (AlarmManager) getContext().getSystemService(Context.ALARM_SERVICE);
                mBatteryStats = BatteryStatsService.getService();
                mLocalPowerManager = getLocalService(PowerManagerInternal.class);
                mLocalAlarmManager = getLocalService(AlarmManagerService.LocalService.class);
                mNetworkPolicyManager = INetworkPolicyManager.Stub.asInterface(
                        ServiceManager.getService(Context.NETWORK_POLICY_SERVICE));
                mDisplayManager = (DisplayManager) getContext().getSystemService(
@@ -1226,6 +1247,7 @@ public class DeviceIdleController extends SystemService
                getContext().registerReceiver(mReceiver, filter);

                mLocalPowerManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAllAppIdArray);
                mLocalAlarmManager.setDeviceIdleUserWhitelist(mPowerSaveWhitelistUserAppIdArray);

                mDisplayManager.registerDisplayListener(mDisplayListener, null);
                updateDisplayLocked();
@@ -1284,6 +1306,17 @@ public class DeviceIdleController extends SystemService
        }
    }

    public String[] getUserPowerWhitelistInternal() {
        synchronized (this) {
            int size = mPowerSaveWhitelistUserApps.size();
            String[] apps = new String[size];
            for (int i = 0; i < mPowerSaveWhitelistUserApps.size(); i++) {
                apps[i] = mPowerSaveWhitelistUserApps.keyAt(i);
            }
            return apps;
        }
    }

    public String[] getFullPowerWhitelistExceptIdleInternal() {
        synchronized (this) {
            int size = mPowerSaveWhitelistAppsExceptIdle.size() + mPowerSaveWhitelistUserApps.size();
@@ -1344,6 +1377,12 @@ public class DeviceIdleController extends SystemService
        }
    }

    public int[] getAppIdUserWhitelistInternal() {
        synchronized (this) {
            return mPowerSaveWhitelistUserAppIdArray;
        }
    }

    public int[] getAppIdTempWhitelistInternal() {
        synchronized (this) {
            return mTempWhitelistAppIdArray;
@@ -1986,12 +2025,16 @@ public class DeviceIdleController extends SystemService
    private static int[] buildAppIdArray(ArrayMap<String, Integer> systemApps,
            ArrayMap<String, Integer> userApps, SparseBooleanArray outAppIds) {
        outAppIds.clear();
        if (systemApps != null) {
            for (int i = 0; i < systemApps.size(); i++) {
                outAppIds.put(systemApps.valueAt(i), true);
            }
        }
        if (userApps != null) {
            for (int i = 0; i < userApps.size(); i++) {
                outAppIds.put(userApps.valueAt(i), true);
            }
        }
        int size = outAppIds.size();
        int[] appids = new int[size];
        for (int i = 0; i < size; i++) {
@@ -2005,6 +2048,8 @@ public class DeviceIdleController extends SystemService
                mPowerSaveWhitelistUserApps, mPowerSaveWhitelistExceptIdleAppIds);
        mPowerSaveWhitelistAllAppIdArray = buildAppIdArray(mPowerSaveWhitelistApps,
                mPowerSaveWhitelistUserApps, mPowerSaveWhitelistAllAppIds);
        mPowerSaveWhitelistUserAppIdArray = buildAppIdArray(null,
                mPowerSaveWhitelistUserApps, mPowerSaveWhitelistUserAppIds);
        if (mLocalPowerManager != null) {
            if (DEBUG) {
                Slog.d(TAG, "Setting wakelock whitelist to "
@@ -2012,6 +2057,13 @@ public class DeviceIdleController extends SystemService
            }
            mLocalPowerManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAllAppIdArray);
        }
        if (mLocalAlarmManager != null) {
            if (DEBUG) {
                Slog.d(TAG, "Setting alarm whitelist to "
                        + Arrays.toString(mPowerSaveWhitelistUserAppIdArray));
            }
            mLocalAlarmManager.setDeviceIdleUserWhitelist(mPowerSaveWhitelistUserAppIdArray);
        }
    }

    private void updateTempWhitelistAppIdsLocked() {
@@ -2478,6 +2530,15 @@ public class DeviceIdleController extends SystemService
                    pw.println();
                }
            }
            size = mPowerSaveWhitelistUserAppIds.size();
            if (size > 0) {
                pw.println("  Whitelist user app ids:");
                for (int i = 0; i < size; i++) {
                    pw.print("    ");
                    pw.print(mPowerSaveWhitelistUserAppIds.keyAt(i));
                    pw.println();
                }
            }
            size = mPowerSaveWhitelistAllAppIds.size();
            if (size > 0) {
                pw.println("  Whitelist all app ids:");