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

Commit 10faec4b authored by Dianne Hackborn's avatar Dianne Hackborn Committed by Android Git Automerger
Browse files

am f0e5501e: Merge "Fix issue #22989030: Separate battery whitelists" into mnc-dev

* commit 'f0e5501e':
  Fix issue #22989030: Separate battery whitelists
parents 6dc2ac39 f0e5501e
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -76,6 +76,13 @@ public abstract class UsageStatsManagerInternal {
     */
    public abstract boolean isAppIdle(String packageName, int userId);

    /**
     * Returns all of the uids for a given user where all packages associating with that uid
     * are in the app idle state -- there are no associated apps that are not idle.  This means
     * all of the returned uids can be safely considered app idle.
     */
    public abstract int[] getIdleUidsForUser(int userId);

    /**
     * @return True if currently app idle parole mode is on.  This means all idle apps are allow to
     * run for a short period of time.
+4 −0
Original line number Diff line number Diff line
@@ -22,10 +22,14 @@ import android.os.UserHandle;
interface IDeviceIdleController {
    void addPowerSaveWhitelistApp(String name);
    void removePowerSaveWhitelistApp(String name);
    String[] getSystemPowerWhitelistExceptIdle();
    String[] getSystemPowerWhitelist();
    String[] getFullPowerWhitelistExceptIdle();
    String[] getFullPowerWhitelist();
    int[] getAppIdWhitelistExceptIdle();
    int[] getAppIdWhitelist();
    int[] getAppIdTempWhitelist();
    boolean isPowerSaveWhitelistExceptIdleApp(String name);
    boolean isPowerSaveWhitelistApp(String name);
    void addPowerSaveTempWhitelistApp(String name, long duration, int userId, String reason);
    long addPowerSaveTempWhitelistAppForMms(String name, int userId, String reason);
+8 −0
Original line number Diff line number Diff line
@@ -183,6 +183,14 @@ public class SparseIntArray implements Cloneable {
        return mValues[index];
    }

    /**
     * Directly set the value at a particular index.
     * @hide
     */
    public void setValueAt(int index, int value) {
        mValues[index] = value;
    }

    /**
     * Returns the index for which {@link #keyAt} would return the
     * specified key, or a negative number if the specified
+1 −1
Original line number Diff line number Diff line
@@ -141,6 +141,6 @@

    <!-- These are the standard packages that are white-listed to always have internet
         access while in power save mode, even if they aren't in the foreground. -->
    <allow-in-power-save package="com.android.providers.downloads" />
    <allow-in-power-save-except-idle package="com.android.providers.downloads" />

</permissions>
+202 −17
Original line number Diff line number Diff line
@@ -113,6 +113,7 @@ public class DeviceIdleController extends SystemService
    private Display mCurDisplay;
    private AnyMotionDetector mAnyMotionDetector;
    private boolean mEnabled;
    private boolean mForceIdle;
    private boolean mScreenOn;
    private boolean mCharging;
    private boolean mSigMotionActive;
@@ -151,7 +152,14 @@ public class DeviceIdleController extends SystemService
    public final AtomicFile mConfigFile;

    /**
     * Package names the system has white-listed to opt out of power save restrictions.
     * Package names the system has white-listed to opt out of power save restrictions,
     * except for device idle mode.
     */
    private final ArrayMap<String, Integer> mPowerSaveWhitelistAppsExceptIdle = new ArrayMap<>();

    /**
     * Package names the system has white-listed to opt out of power save restrictions for
     * all modes.
     */
    private final ArrayMap<String, Integer> mPowerSaveWhitelistApps = new ArrayMap<>();

@@ -160,11 +168,30 @@ public class DeviceIdleController extends SystemService
     */
    private final ArrayMap<String, Integer> mPowerSaveWhitelistUserApps = new ArrayMap<>();

    /**
     * App IDs of built-in system apps that have been white-listed except for idle modes.
     */
    private final SparseBooleanArray mPowerSaveWhitelistSystemAppIdsExceptIdle
            = new SparseBooleanArray();

    /**
     * App IDs of built-in system apps that have been white-listed.
     */
    private final SparseBooleanArray mPowerSaveWhitelistSystemAppIds = new SparseBooleanArray();

    /**
     * App IDs that have been white-listed to opt out of power save restrictions, except
     * for device idle modes.
     */
    private final SparseBooleanArray mPowerSaveWhitelistExceptIdleAppIds = new SparseBooleanArray();

    /**
     * Current app IDs that are in the complete power save white list, but shouldn't be
     * excluded from idle modes.  This array can be shared with others because it will not be
     * modified once set.
     */
    private int[] mPowerSaveWhitelistExceptIdleAppIdArray = new int[0];

    /**
     * App IDs that have been white-listed to opt out of power save restrictions.
     */
@@ -583,14 +610,26 @@ public class DeviceIdleController extends SystemService
            removePowerSaveWhitelistAppInternal(name);
        }

        @Override public String[] getSystemPowerWhitelistExceptIdle() {
            return getSystemPowerWhitelistExceptIdleInternal();
        }

        @Override public String[] getSystemPowerWhitelist() {
            return getSystemPowerWhitelistInternal();
        }

        @Override public String[] getFullPowerWhitelistExceptIdle() {
            return getFullPowerWhitelistExceptIdleInternal();
        }

        @Override public String[] getFullPowerWhitelist() {
            return getFullPowerWhitelistInternal();
        }

        @Override public int[] getAppIdWhitelistExceptIdle() {
            return getAppIdWhitelistExceptIdleInternal();
        }

        @Override public int[] getAppIdWhitelist() {
            return getAppIdWhitelistInternal();
        }
@@ -599,6 +638,10 @@ public class DeviceIdleController extends SystemService
            return getAppIdTempWhitelistInternal();
        }

        @Override public boolean isPowerSaveWhitelistExceptIdleApp(String name) {
            return isPowerSaveWhitelistExceptIdleAppInternal(name);
        }

        @Override public boolean isPowerSaveWhitelistApp(String name) {
            return isPowerSaveWhitelistAppInternal(name);
        }
@@ -679,6 +722,19 @@ public class DeviceIdleController extends SystemService
            mEnabled = getContext().getResources().getBoolean(
                    com.android.internal.R.bool.config_enableAutoPowerModes);
            SystemConfig sysConfig = SystemConfig.getInstance();
            ArraySet<String> allowPowerExceptIdle = sysConfig.getAllowInPowerSaveExceptIdle();
            for (int i=0; i<allowPowerExceptIdle.size(); i++) {
                String pkg = allowPowerExceptIdle.valueAt(i);
                try {
                    ApplicationInfo ai = pm.getApplicationInfo(pkg, 0);
                    if ((ai.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
                        int appid = UserHandle.getAppId(ai.uid);
                        mPowerSaveWhitelistAppsExceptIdle.put(ai.packageName, appid);
                        mPowerSaveWhitelistSystemAppIdsExceptIdle.put(appid, true);
                    }
                } catch (PackageManager.NameNotFoundException e) {
                }
            }
            ArraySet<String> allowPower = sysConfig.getAllowInPowerSave();
            for (int i=0; i<allowPower.size(); i++) {
                String pkg = allowPower.valueAt(i);
@@ -686,6 +742,10 @@ public class DeviceIdleController extends SystemService
                    ApplicationInfo ai = pm.getApplicationInfo(pkg, 0);
                    if ((ai.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
                        int appid = UserHandle.getAppId(ai.uid);
                        // These apps are on both the whitelist-except-idle as well
                        // as the full whitelist, so they apply in all cases.
                        mPowerSaveWhitelistAppsExceptIdle.put(ai.packageName, appid);
                        mPowerSaveWhitelistSystemAppIdsExceptIdle.put(appid, true);
                        mPowerSaveWhitelistApps.put(ai.packageName, appid);
                        mPowerSaveWhitelistSystemAppIds.put(appid, true);
                    }
@@ -783,17 +843,45 @@ public class DeviceIdleController extends SystemService
        return false;
    }

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

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

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

    public String[] getFullPowerWhitelistInternal() {
        synchronized (this) {
            int size = mPowerSaveWhitelistApps.size() + mPowerSaveWhitelistUserApps.size();
@@ -811,6 +899,13 @@ public class DeviceIdleController extends SystemService
        }
    }

    public boolean isPowerSaveWhitelistExceptIdleAppInternal(String packageName) {
        synchronized (this) {
            return mPowerSaveWhitelistAppsExceptIdle.containsKey(packageName)
                    || mPowerSaveWhitelistUserApps.containsKey(packageName);
        }
    }

    public boolean isPowerSaveWhitelistAppInternal(String packageName) {
        synchronized (this) {
            return mPowerSaveWhitelistApps.containsKey(packageName)
@@ -818,6 +913,12 @@ public class DeviceIdleController extends SystemService
        }
    }

    public int[] getAppIdWhitelistExceptIdleInternal() {
        synchronized (this) {
            return mPowerSaveWhitelistExceptIdleAppIdArray;
        }
    }

    public int[] getAppIdWhitelistInternal() {
        synchronized (this) {
            return mPowerSaveWhitelistAllAppIdArray;
@@ -921,6 +1022,9 @@ public class DeviceIdleController extends SystemService
                    Slog.d(TAG, "Removing UID " + uid + " from temp whitelist");
                }
                updateTempWhitelistAppIdsLocked();
                if (mNetworkPolicyTempWhitelistCallback != null) {
                    mHandler.post(mNetworkPolicyTempWhitelistCallback);
                }
                reportTempWhitelistChangedLocked();
                try {
                    mBatteryStats.noteEvent(BatteryStats.HistoryItem.EVENT_TEMP_WHITELIST_FINISH,
@@ -949,23 +1053,31 @@ public class DeviceIdleController extends SystemService
        if (DEBUG) Slog.d(TAG, "updateDisplayLocked: screenOn=" + screenOn);
        if (!screenOn && mScreenOn) {
            mScreenOn = false;
            if (!mForceIdle) {
                becomeInactiveIfAppropriateLocked();
            }
        } else if (screenOn) {
            mScreenOn = true;
            if (!mForceIdle) {
                becomeActiveLocked("screen", Process.myUid());
            }
        }
    }

    void updateChargingLocked(boolean charging) {
        if (DEBUG) Slog.i(TAG, "updateChargingLocked: charging=" + charging);
        if (!charging && mCharging) {
            mCharging = false;
            if (!mForceIdle) {
                becomeInactiveIfAppropriateLocked();
            }
        } else if (charging) {
            mCharging = charging;
            if (!mForceIdle) {
                becomeActiveLocked("charging", Process.myUid());
            }
        }
    }

    void scheduleReportActiveLocked(String activeReason, int activeUid) {
        Message msg = mHandler.obtainMessage(MSG_REPORT_ACTIVE, activeUid,
@@ -989,7 +1101,7 @@ public class DeviceIdleController extends SystemService

    void becomeInactiveIfAppropriateLocked() {
        if (DEBUG) Slog.d(TAG, "becomeInactiveIfAppropriateLocked()");
        if (!mScreenOn && !mCharging && mEnabled && mState == STATE_ACTIVE) {
        if (((!mScreenOn && !mCharging) || mForceIdle) && mEnabled && mState == STATE_ACTIVE) {
            // Screen has turned off; we are now going to become inactive and start
            // waiting to see if we will ultimately go idle.
            mState = STATE_INACTIVE;
@@ -1010,6 +1122,15 @@ public class DeviceIdleController extends SystemService
        becomeInactiveIfAppropriateLocked();
    }

    void exitForceIdleLocked() {
        if (mForceIdle) {
            mForceIdle = false;
            if (mScreenOn || mCharging) {
                becomeActiveLocked("exit-force-idle", Process.myUid());
            }
        }
    }

    void stepIdleStateLocked() {
        if (DEBUG) Slog.d(TAG, "stepIdleStateLocked: mState=" + mState);
        EventLogTags.writeDeviceIdleStep();
@@ -1138,20 +1259,28 @@ public class DeviceIdleController extends SystemService
          mNextAlarmTime, mSensingAlarmIntent);
    }

    private void updateWhitelistAppIdsLocked() {
        mPowerSaveWhitelistAllAppIds.clear();
        for (int i=0; i<mPowerSaveWhitelistApps.size(); i++) {
            mPowerSaveWhitelistAllAppIds.put(mPowerSaveWhitelistApps.valueAt(i), true);
    private static int[] buildAppIdArray(ArrayMap<String, Integer> systemApps,
            ArrayMap<String, Integer> userApps, SparseBooleanArray outAppIds) {
        outAppIds.clear();
        for (int i=0; i<systemApps.size(); i++) {
            outAppIds.put(systemApps.valueAt(i), true);
        }
        for (int i=0; i<mPowerSaveWhitelistUserApps.size(); i++) {
            mPowerSaveWhitelistAllAppIds.put(mPowerSaveWhitelistUserApps.valueAt(i), true);
        for (int i=0; i<userApps.size(); i++) {
            outAppIds.put(userApps.valueAt(i), true);
        }
        int size = mPowerSaveWhitelistAllAppIds.size();
        int size = outAppIds.size();
        int[] appids = new int[size];
        for (int i = 0; i < size; i++) {
            appids[i] = mPowerSaveWhitelistAllAppIds.keyAt(i);
            appids[i] = outAppIds.keyAt(i);
        }
        return appids;
    }
        mPowerSaveWhitelistAllAppIdArray = appids;

    private void updateWhitelistAppIdsLocked() {
        mPowerSaveWhitelistExceptIdleAppIdArray = buildAppIdArray(mPowerSaveWhitelistAppsExceptIdle,
                mPowerSaveWhitelistUserApps, mPowerSaveWhitelistExceptIdleAppIds);
        mPowerSaveWhitelistAllAppIdArray = buildAppIdArray(mPowerSaveWhitelistApps,
                mPowerSaveWhitelistUserApps, mPowerSaveWhitelistAllAppIds);
        if (mLocalPowerManager != null) {
            if (DEBUG) {
                Slog.d(TAG, "Setting wakelock whitelist to "
@@ -1320,6 +1449,9 @@ public class DeviceIdleController extends SystemService
        pw.println("Commands:");
        pw.println("  step");
        pw.println("    Immediately step to next state, without waiting for alarm.");
        pw.println("  force-idle");
        pw.println("    Force directly into idle mode, regardless of other device state.");
        pw.println("    Use \"step\" to get out.");
        pw.println("  disable");
        pw.println("    Completely disable device idle mode.");
        pw.println("  enable");
@@ -1362,6 +1494,7 @@ public class DeviceIdleController extends SystemService
                    synchronized (this) {
                        long token = Binder.clearCallingIdentity();
                        try {
                            exitForceIdleLocked();
                            stepIdleStateLocked();
                            pw.print("Stepped to: "); pw.println(stateToString(mState));
                        } finally {
@@ -1369,6 +1502,33 @@ public class DeviceIdleController extends SystemService
                        }
                    }
                    return;
                } else if ("force-idle".equals(arg)) {
                    synchronized (this) {
                        long token = Binder.clearCallingIdentity();
                        try {
                            if (!mEnabled) {
                                pw.println("Unable to go idle; not enabled");
                                return;
                            }
                            mForceIdle = true;
                            becomeInactiveIfAppropriateLocked();
                            int curState = mState;
                            while (curState != STATE_IDLE) {
                                stepIdleStateLocked();
                                if (curState == mState) {
                                    pw.print("Unable to go idle; stopped at ");
                                    pw.println(stateToString(mState));
                                    exitForceIdleLocked();
                                    return;
                                }
                                curState = mState;
                            }
                            pw.println("Now forced in to idle mode");
                        } finally {
                            Binder.restoreCallingIdentity(token);
                        }
                    }
                    return;
                } else if ("disable".equals(arg)) {
                    synchronized (this) {
                        long token = Binder.clearCallingIdentity();
@@ -1387,6 +1547,7 @@ public class DeviceIdleController extends SystemService
                    synchronized (this) {
                        long token = Binder.clearCallingIdentity();
                        try {
                            exitForceIdleLocked();
                            if (!mEnabled) {
                                mEnabled = true;
                                becomeInactiveIfAppropriateLocked();
@@ -1431,6 +1592,12 @@ public class DeviceIdleController extends SystemService
                            }
                        } else {
                            synchronized (this) {
                                for (int j=0; j<mPowerSaveWhitelistAppsExceptIdle.size(); j++) {
                                    pw.print("system-excidle,");
                                    pw.print(mPowerSaveWhitelistAppsExceptIdle.keyAt(j));
                                    pw.print(",");
                                    pw.println(mPowerSaveWhitelistAppsExceptIdle.valueAt(j));
                                }
                                for (int j=0; j<mPowerSaveWhitelistApps.size(); j++) {
                                    pw.print("system,");
                                    pw.print(mPowerSaveWhitelistApps.keyAt(j));
@@ -1481,7 +1648,15 @@ public class DeviceIdleController extends SystemService
        synchronized (this) {
            mConstants.dump(pw);

            int size = mPowerSaveWhitelistApps.size();
            int size = mPowerSaveWhitelistAppsExceptIdle.size();
            if (size > 0) {
                pw.println("  Whitelist (except idle) system apps:");
                for (int i = 0; i < size; i++) {
                    pw.print("    ");
                    pw.println(mPowerSaveWhitelistAppsExceptIdle.keyAt(i));
                }
            }
            size = mPowerSaveWhitelistApps.size();
            if (size > 0) {
                pw.println("  Whitelist system apps:");
                for (int i = 0; i < size; i++) {
@@ -1497,6 +1672,15 @@ public class DeviceIdleController extends SystemService
                    pw.println(mPowerSaveWhitelistUserApps.keyAt(i));
                }
            }
            size = mPowerSaveWhitelistExceptIdleAppIds.size();
            if (size > 0) {
                pw.println("  Whitelist (except idle) all app ids:");
                for (int i = 0; i < size; i++) {
                    pw.print("    ");
                    pw.print(mPowerSaveWhitelistExceptIdleAppIds.keyAt(i));
                    pw.println();
                }
            }
            size = mPowerSaveWhitelistAllAppIds.size();
            if (size > 0) {
                pw.println("  Whitelist all app ids:");
@@ -1531,6 +1715,7 @@ public class DeviceIdleController extends SystemService
            }

            pw.print("  mEnabled="); pw.println(mEnabled);
            pw.print("  mForceIdle="); pw.println(mForceIdle);
            pw.print("  mSigMotionSensor="); pw.println(mSigMotionSensor);
            pw.print("  mCurDisplay="); pw.println(mCurDisplay);
            pw.print("  mScreenOn="); pw.println(mScreenOn);
Loading