diff options
| -rw-r--r-- | api/current.txt | 2 | ||||
| -rw-r--r-- | api/system-current.txt | 2 | ||||
| -rw-r--r-- | core/java/android/os/BatteryStats.java | 112 | ||||
| -rw-r--r-- | core/java/android/os/IPowerManager.aidl | 1 | ||||
| -rw-r--r-- | core/java/android/os/PowerManager.java | 25 | ||||
| -rw-r--r-- | core/java/android/os/PowerManagerInternal.java | 4 | ||||
| -rw-r--r-- | core/java/com/android/internal/os/BatteryStatsImpl.java | 132 | ||||
| -rw-r--r-- | services/core/java/com/android/server/job/JobSchedulerService.java | 59 | ||||
| -rw-r--r-- | services/core/java/com/android/server/job/controllers/StateController.java | 6 | ||||
| -rw-r--r-- | services/core/java/com/android/server/net/NetworkPolicyManagerService.java | 14 | ||||
| -rw-r--r-- | services/core/java/com/android/server/power/DeviceIdleController.java (renamed from services/core/java/com/android/server/DeviceIdleController.java) | 83 | ||||
| -rw-r--r-- | services/core/java/com/android/server/power/PowerManagerService.java | 26 | ||||
| -rw-r--r-- | services/java/com/android/server/SystemServer.java | 2 |
13 files changed, 418 insertions, 50 deletions
diff --git a/api/current.txt b/api/current.txt index d8d8998d5a43..ecac8fefd514 100644 --- a/api/current.txt +++ b/api/current.txt @@ -22884,6 +22884,7 @@ package android.os { } public final class PowerManager { + method public boolean isDeviceIdleMode(); method public boolean isInteractive(); method public boolean isPowerSaveMode(); method public deprecated boolean isScreenOn(); @@ -22891,6 +22892,7 @@ package android.os { method public android.os.PowerManager.WakeLock newWakeLock(int, java.lang.String); method public void reboot(java.lang.String); field public static final int ACQUIRE_CAUSES_WAKEUP = 268435456; // 0x10000000 + field public static final java.lang.String ACTION_DEVICE_IDLE_MODE_CHANGED = "android.os.action.DEVICE_IDLE_MODE_CHANGED"; field public static final java.lang.String ACTION_POWER_SAVE_MODE_CHANGED = "android.os.action.POWER_SAVE_MODE_CHANGED"; field public static final deprecated int FULL_WAKE_LOCK = 26; // 0x1a field public static final int ON_AFTER_RELEASE = 536870912; // 0x20000000 diff --git a/api/system-current.txt b/api/system-current.txt index 71474a30ab50..e6cd44ba45bf 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -24676,6 +24676,7 @@ package android.os { } public final class PowerManager { + method public boolean isDeviceIdleMode(); method public boolean isInteractive(); method public boolean isPowerSaveMode(); method public deprecated boolean isScreenOn(); @@ -24684,6 +24685,7 @@ package android.os { method public void reboot(java.lang.String); method public void userActivity(long, int, int); field public static final int ACQUIRE_CAUSES_WAKEUP = 268435456; // 0x10000000 + field public static final java.lang.String ACTION_DEVICE_IDLE_MODE_CHANGED = "android.os.action.DEVICE_IDLE_MODE_CHANGED"; field public static final java.lang.String ACTION_POWER_SAVE_MODE_CHANGED = "android.os.action.POWER_SAVE_MODE_CHANGED"; field public static final deprecated int FULL_WAKE_LOCK = 26; // 0x1a field public static final int ON_AFTER_RELEASE = 536870912; // 0x20000000 diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java index cab03da7e4c0..26e6b85041fc 100644 --- a/core/java/android/os/BatteryStats.java +++ b/core/java/android/os/BatteryStats.java @@ -613,6 +613,9 @@ public abstract class BatteryStats implements Parcelable { if ((initMode&STEP_LEVEL_MODE_POWER_SAVE) != 0) { out.append('p'); } + if ((initMode&STEP_LEVEL_MODE_DEVICE_IDLE) != 0) { + out.append('i'); + } switch ((modMode&STEP_LEVEL_MODE_SCREEN_STATE) + 1) { case Display.STATE_OFF: out.append('F'); break; case Display.STATE_ON: out.append('O'); break; @@ -622,6 +625,9 @@ public abstract class BatteryStats implements Parcelable { if ((modMode&STEP_LEVEL_MODE_POWER_SAVE) != 0) { out.append('P'); } + if ((modMode&STEP_LEVEL_MODE_DEVICE_IDLE) != 0) { + out.append('I'); + } out.append('-'); appendHex(level, 4, out); out.append('-'); @@ -648,6 +654,9 @@ public abstract class BatteryStats implements Parcelable { case 'p': out |= (((long)STEP_LEVEL_MODE_POWER_SAVE) << STEP_LEVEL_INITIAL_MODE_SHIFT); break; + case 'i': out |= (((long)STEP_LEVEL_MODE_DEVICE_IDLE) + << STEP_LEVEL_INITIAL_MODE_SHIFT); + break; case 'F': out |= (((long)Display.STATE_OFF-1)<<STEP_LEVEL_MODIFIED_MODE_SHIFT); break; case 'O': out |= (((long)Display.STATE_ON-1)<<STEP_LEVEL_MODIFIED_MODE_SHIFT); @@ -660,6 +669,9 @@ public abstract class BatteryStats implements Parcelable { case 'P': out |= (((long)STEP_LEVEL_MODE_POWER_SAVE) << STEP_LEVEL_MODIFIED_MODE_SHIFT); break; + case 'I': out |= (((long)STEP_LEVEL_MODE_DEVICE_IDLE) + << STEP_LEVEL_MODIFIED_MODE_SHIFT); + break; } } i++; @@ -820,11 +832,18 @@ public abstract class BatteryStats implements Parcelable { } } + public static final class PackageChange { + public String mPackageName; + public boolean mUpdate; + public int mVersionCode; + } + public static final class DailyItem { public long mStartTime; public long mEndTime; public LevelStepTracker mDischargeSteps; public LevelStepTracker mChargeSteps; + public ArrayList<PackageChange> mPackageChanges; } public abstract DailyItem getDailyItemLocked(int daysAgo); @@ -1524,6 +1543,23 @@ public abstract class BatteryStats implements Parcelable { public abstract int getDeviceIdleModeEnabledCount(int which); /** + * Returns the time in microseconds that device has been in idling while on + * battery. This is broader than {@link #getDeviceIdleModeEnabledTime} -- it + * counts all of the time that we consider the device to be idle, whether or not + * it is currently in the actual device idle mode. + * + * {@hide} + */ + public abstract long getDeviceIdlingTime(long elapsedRealtimeUs, int which); + + /** + * Returns the number of times that the devie has started idling. + * + * {@hide} + */ + public abstract int getDeviceIdlingCount(int which); + + /** * Returns the number of times that connectivity state changed. * * {@hide} @@ -2069,45 +2105,44 @@ public abstract class BatteryStats implements Parcelable { // Step duration mode: power save is on. public static final int STEP_LEVEL_MODE_POWER_SAVE = 0x04; + // Step duration mode: device is currently in idle mode. + public static final int STEP_LEVEL_MODE_DEVICE_IDLE = 0x08; + public static final int[] STEP_LEVEL_MODES_OF_INTEREST = new int[] { STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE, + STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE|STEP_LEVEL_MODE_DEVICE_IDLE, + STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_DEVICE_IDLE, STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE, STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE, STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE, STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE, STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE, - STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE, - STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE, + STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE|STEP_LEVEL_MODE_DEVICE_IDLE, + STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_DEVICE_IDLE, }; public static final int[] STEP_LEVEL_MODE_VALUES = new int[] { (Display.STATE_OFF-1), (Display.STATE_OFF-1)|STEP_LEVEL_MODE_POWER_SAVE, + (Display.STATE_OFF-1)|STEP_LEVEL_MODE_DEVICE_IDLE, (Display.STATE_ON-1), (Display.STATE_ON-1)|STEP_LEVEL_MODE_POWER_SAVE, (Display.STATE_DOZE-1), (Display.STATE_DOZE-1)|STEP_LEVEL_MODE_POWER_SAVE, (Display.STATE_DOZE_SUSPEND-1), (Display.STATE_DOZE_SUSPEND-1)|STEP_LEVEL_MODE_POWER_SAVE, + (Display.STATE_DOZE_SUSPEND-1)|STEP_LEVEL_MODE_DEVICE_IDLE, }; public static final String[] STEP_LEVEL_MODE_LABELS = new String[] { "screen off", "screen off power save", + "screen off device idle", "screen on", "screen on power save", "screen doze", "screen doze power save", "screen doze-suspend", "screen doze-suspend power save", - }; - public static final String[] STEP_LEVEL_MODE_TAGS = new String[] { - "off", - "off-save", - "on", - "on-save", - "doze", - "doze-save", - "susp", - "susp-save", + "screen doze-suspend device idle", }; /** @@ -2140,6 +2175,8 @@ public abstract class BatteryStats implements Parcelable { */ public abstract LevelStepTracker getDailyChargeLevelStepTracker(); + public abstract ArrayList<PackageChange> getDailyPackageChanges(); + public abstract Map<String, ? extends Timer> getWakeupReasonStats(); public abstract Map<String, ? extends Timer> getKernelWakelockStats(); @@ -2338,6 +2375,7 @@ public abstract class BatteryStats implements Parcelable { final long interactiveTime = getInteractiveTime(rawRealtime, which); final long powerSaveModeEnabledTime = getPowerSaveModeEnabledTime(rawRealtime, which); final long deviceIdleModeEnabledTime = getDeviceIdleModeEnabledTime(rawRealtime, which); + final long deviceIdlingTime = getDeviceIdlingTime(rawRealtime, which); final int connChanges = getNumConnectivityChange(which); final long phoneOnTime = getPhoneOnTime(rawRealtime, which); final long wifiOnTime = getWifiOnTime(rawRealtime, which); @@ -2410,7 +2448,8 @@ public abstract class BatteryStats implements Parcelable { 0 /*legacy input event count*/, getMobileRadioActiveTime(rawRealtime, which) / 1000, getMobileRadioActiveAdjustedTime(which) / 1000, interactiveTime / 1000, powerSaveModeEnabledTime / 1000, connChanges, deviceIdleModeEnabledTime / 1000, - getDeviceIdleModeEnabledCount(which)); + getDeviceIdleModeEnabledCount(which), deviceIdlingTime / 1000, + getDeviceIdlingCount(which)); // Dump screen brightness stats Object[] args = new Object[NUM_SCREEN_BRIGHTNESS_BINS]; @@ -2879,6 +2918,7 @@ public abstract class BatteryStats implements Parcelable { final long interactiveTime = getInteractiveTime(rawRealtime, which); final long powerSaveModeEnabledTime = getPowerSaveModeEnabledTime(rawRealtime, which); final long deviceIdleModeEnabledTime = getDeviceIdleModeEnabledTime(rawRealtime, which); + final long deviceIdlingTime = getDeviceIdlingTime(rawRealtime, which); final long phoneOnTime = getPhoneOnTime(rawRealtime, which); final long wifiRunningTime = getGlobalWifiRunningTime(rawRealtime, which); final long wifiOnTime = getWifiOnTime(rawRealtime, which); @@ -2923,10 +2963,21 @@ public abstract class BatteryStats implements Parcelable { sb.append(")"); pw.println(sb.toString()); } - if (deviceIdleModeEnabledTime != 0) { + if (deviceIdlingTime != 0) { sb.setLength(0); sb.append(prefix); sb.append(" Device idling: "); + formatTimeMs(sb, deviceIdlingTime / 1000); + sb.append("("); + sb.append(formatRatioLocked(deviceIdlingTime, whichBatteryRealtime)); + sb.append(") "); sb.append(getDeviceIdlingCount(which)); + sb.append("x"); + pw.println(sb.toString()); + } + if (deviceIdleModeEnabledTime != 0) { + sb.setLength(0); + sb.append(prefix); + sb.append(" Idle mode time: "); formatTimeMs(sb, deviceIdleModeEnabledTime / 1000); sb.append("("); sb.append(formatRatioLocked(deviceIdleModeEnabledTime, whichBatteryRealtime)); @@ -4403,6 +4454,11 @@ public abstract class BatteryStats implements Parcelable { } else { lineArgs[3] = ""; } + if ((modMode&STEP_LEVEL_MODE_DEVICE_IDLE) == 0) { + lineArgs[3] = (initMode&STEP_LEVEL_MODE_DEVICE_IDLE) != 0 ? "i+" : "i-"; + } else { + lineArgs[3] = ""; + } dumpLine(pw, 0 /* uid */, "i" /* category */, header, (Object[])lineArgs); } else { pw.print(prefix); @@ -4427,6 +4483,12 @@ public abstract class BatteryStats implements Parcelable { ? "power-save-on" : "power-save-off"); haveModes = true; } + if ((modMode&STEP_LEVEL_MODE_DEVICE_IDLE) == 0) { + pw.print(haveModes ? ", " : " ("); + pw.print((initMode&STEP_LEVEL_MODE_DEVICE_IDLE) != 0 + ? "device-idle-on" : "device-idle-off"); + haveModes = true; + } if (haveModes) { pw.print(")"); } @@ -4558,6 +4620,23 @@ public abstract class BatteryStats implements Parcelable { } } + private void dumpDailyPackageChanges(PrintWriter pw, String prefix, + ArrayList<PackageChange> changes) { + if (changes == null) { + return; + } + pw.print(prefix); pw.println("Package changes:"); + for (int i=0; i<changes.size(); i++) { + PackageChange pc = changes.get(i); + if (pc.mUpdate) { + pw.print(prefix); pw.print(" Update "); pw.print(pc.mPackageName); + pw.print(" vers="); pw.println(pc.mVersionCode); + } else { + pw.print(prefix); pw.print(" Uninstall "); pw.println(pc.mPackageName); + } + } + } + /** * Dumps a human-readable summary of the battery statistics to the given PrintWriter. * @@ -4688,7 +4767,8 @@ public abstract class BatteryStats implements Parcelable { int[] outInt = new int[1]; LevelStepTracker dsteps = getDailyDischargeLevelStepTracker(); LevelStepTracker csteps = getDailyChargeLevelStepTracker(); - if (dsteps.mNumStepDurations > 0 || csteps.mNumStepDurations > 0) { + ArrayList<PackageChange> pkgc = getDailyPackageChanges(); + if (dsteps.mNumStepDurations > 0 || csteps.mNumStepDurations > 0 || pkgc != null) { if ((flags&DUMP_DAILY_ONLY) != 0) { if (dumpDurationSteps(pw, " ", " Current daily discharge step durations:", dsteps, false)) { @@ -4700,6 +4780,7 @@ public abstract class BatteryStats implements Parcelable { dumpDailyLevelStepSummary(pw, " ", "Charge", csteps, sb, outInt); } + dumpDailyPackageChanges(pw, " ", pkgc); } else { pw.println(" Current daily steps:"); dumpDailyLevelStepSummary(pw, " ", "Discharge", dsteps, @@ -4731,6 +4812,7 @@ public abstract class BatteryStats implements Parcelable { dumpDailyLevelStepSummary(pw, " ", "Charge", dit.mChargeSteps, sb, outInt); } + dumpDailyPackageChanges(pw, " ", dit.mPackageChanges); } else { dumpDailyLevelStepSummary(pw, " ", "Discharge", dit.mDischargeSteps, sb, outInt); diff --git a/core/java/android/os/IPowerManager.aidl b/core/java/android/os/IPowerManager.aidl index 16dac7d5ff27..418641f764ea 100644 --- a/core/java/android/os/IPowerManager.aidl +++ b/core/java/android/os/IPowerManager.aidl @@ -43,6 +43,7 @@ interface IPowerManager boolean isInteractive(); boolean isPowerSaveMode(); boolean setPowerSaveMode(boolean mode); + boolean isDeviceIdleMode(); void reboot(boolean confirm, String reason, boolean wait); void shutdown(boolean confirm, boolean wait); diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java index de970cbe525a..81745b3fb9b7 100644 --- a/core/java/android/os/PowerManager.java +++ b/core/java/android/os/PowerManager.java @@ -856,6 +856,23 @@ public final class PowerManager { } /** + * Returns true if the device is currently in idle mode. This happens when a device + * has been sitting unused and unmoving for a sufficiently long period of time, so that + * it decides to go into a lower power-use state. This may involve things like turning + * off network access to apps. You can monitor for changes to this state with + * {@link #ACTION_DEVICE_IDLE_MODE_CHANGED}. + * + * @return Returns true if currently in low power mode, else false. + */ + public boolean isDeviceIdleMode() { + try { + return mService.isDeviceIdleMode(); + } catch (RemoteException e) { + return false; + } + } + + /** * Turn off the device. * * @param confirm If true, shows a shutdown confirmation dialog. @@ -879,6 +896,14 @@ public final class PowerManager { = "android.os.action.POWER_SAVE_MODE_CHANGED"; /** + * Intent that is broadcast when the state of {@link #isDeviceIdleMode()} changes. + * This broadcast is only sent to registered receivers. + */ + @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String ACTION_DEVICE_IDLE_MODE_CHANGED + = "android.os.action.DEVICE_IDLE_MODE_CHANGED"; + + /** * Intent that is broadcast when the state of {@link #isPowerSaveMode()} is about to change. * This broadcast is only sent to registered receivers. * diff --git a/core/java/android/os/PowerManagerInternal.java b/core/java/android/os/PowerManagerInternal.java index 6f3176874cab..00ab262fda4e 100644 --- a/core/java/android/os/PowerManagerInternal.java +++ b/core/java/android/os/PowerManagerInternal.java @@ -117,7 +117,7 @@ public abstract class PowerManagerInternal { /** * Used by the dream manager to override certain properties while dozing. * - * @param screenState The overridden screen state, or {@link Display.STATE_UNKNOWN} + * @param screenState The overridden screen state, or {@link Display#STATE_UNKNOWN} * to disable the override. * @param screenBrightness The overridden screen brightness, or * {@link PowerManager#BRIGHTNESS_DEFAULT} to disable the override. @@ -132,4 +132,6 @@ public abstract class PowerManagerInternal { public interface LowPowerModeListener { public void onLowPowerModeChanged(boolean enabled); } + + public abstract void setDeviceIdleMode(boolean enabled); } diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index 65a970a3c55f..eaa0dc7c7969 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -109,7 +109,7 @@ public final class BatteryStatsImpl extends BatteryStats { private static final int MAGIC = 0xBA757475; // 'BATSTATS' // Current on-disk Parcel version - private static final int VERSION = 120 + (USE_OLD_HISTORY ? 1000 : 0); + private static final int VERSION = 121 + (USE_OLD_HISTORY ? 1000 : 0); // Maximum number of items we will record in the history. private static final int MAX_HISTORY_ITEMS = 2000; @@ -310,6 +310,9 @@ public final class BatteryStatsImpl extends BatteryStats { boolean mPowerSaveModeEnabled; StopwatchTimer mPowerSaveModeEnabledTimer; + boolean mDeviceIdling; + StopwatchTimer mDeviceIdlingTimer; + boolean mDeviceIdleModeEnabled; StopwatchTimer mDeviceIdleModeEnabledTimer; @@ -414,6 +417,7 @@ public final class BatteryStatsImpl extends BatteryStats { int mMinDischargeStepLevel; final LevelStepTracker mDischargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS); final LevelStepTracker mDailyDischargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS*2); + ArrayList<PackageChange> mDailyPackageChanges; int mLastChargeStepLevel; int mMaxChargeStepLevel; @@ -3417,9 +3421,26 @@ public final class BatteryStatsImpl extends BatteryStats { } public void noteDeviceIdleModeLocked(boolean enabled, boolean fromActive, boolean fromMotion) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + boolean nowIdling = enabled; + if (mDeviceIdling && !enabled && !fromActive && !fromMotion) { + // We don't go out of general idling mode until explicitly taken out of + // device idle through going active or significant motion. + nowIdling = true; + } + if (mDeviceIdling != nowIdling) { + mDeviceIdling = nowIdling; + int stepState = nowIdling ? STEP_LEVEL_MODE_DEVICE_IDLE : 0; + mModStepMode |= (mCurStepMode&STEP_LEVEL_MODE_DEVICE_IDLE) ^ stepState; + mCurStepMode = (mCurStepMode&~STEP_LEVEL_MODE_DEVICE_IDLE) | stepState; + if (enabled) { + mDeviceIdlingTimer.startRunningLocked(elapsedRealtime); + } else { + mDeviceIdlingTimer.stopRunningLocked(elapsedRealtime); + } + } if (mDeviceIdleModeEnabled != enabled) { - final long elapsedRealtime = SystemClock.elapsedRealtime(); - final long uptime = SystemClock.uptimeMillis(); mDeviceIdleModeEnabled = enabled; if (fromMotion) { addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_SIGNIFICANT_MOTION, @@ -3449,7 +3470,11 @@ public final class BatteryStatsImpl extends BatteryStats { final long uptime = SystemClock.uptimeMillis(); addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PACKAGE_INSTALLED, pkgName, versionCode); - mNumConnectivityChange++; + PackageChange pc = new PackageChange(); + pc.mPackageName = pkgName; + pc.mUpdate = true; + pc.mVersionCode = versionCode; + addPackageChange(pc); } public void notePackageUninstalledLocked(String pkgName) { @@ -3457,7 +3482,17 @@ public final class BatteryStatsImpl extends BatteryStats { final long uptime = SystemClock.uptimeMillis(); addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PACKAGE_UNINSTALLED, pkgName, 0); - mNumConnectivityChange++; + PackageChange pc = new PackageChange(); + pc.mPackageName = pkgName; + pc.mUpdate = true; + addPackageChange(pc); + } + + private void addPackageChange(PackageChange pc) { + if (mDailyPackageChanges == null) { + mDailyPackageChanges = new ArrayList<>(); + } + mDailyPackageChanges.add(pc); } public void notePhoneOnLocked() { @@ -4262,6 +4297,14 @@ public final class BatteryStatsImpl extends BatteryStats { return mDeviceIdleModeEnabledTimer.getCountLocked(which); } + @Override public long getDeviceIdlingTime(long elapsedRealtimeUs, int which) { + return mDeviceIdlingTimer.getTotalTimeLocked(elapsedRealtimeUs, which); + } + + @Override public int getDeviceIdlingCount(int which) { + return mDeviceIdlingTimer.getCountLocked(which); + } + @Override public int getNumConnectivityChange(int which) { int val = mNumConnectivityChange; if (which == STATS_CURRENT) { @@ -6724,6 +6767,7 @@ public final class BatteryStatsImpl extends BatteryStats { mInteractiveTimer = new StopwatchTimer(null, -10, null, mOnBatteryTimeBase); mPowerSaveModeEnabledTimer = new StopwatchTimer(null, -2, null, mOnBatteryTimeBase); mDeviceIdleModeEnabledTimer = new StopwatchTimer(null, -11, null, mOnBatteryTimeBase); + mDeviceIdlingTimer = new StopwatchTimer(null, -12, null, mOnBatteryTimeBase); mPhoneOnTimer = new StopwatchTimer(null, -3, null, mOnBatteryTimeBase); for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(null, -200-i, null, @@ -6849,6 +6893,11 @@ public final class BatteryStatsImpl extends BatteryStats { mDailyChargeStepTracker.mNumStepDurations, mDailyChargeStepTracker.mStepDurations); } + if (mDailyPackageChanges != null) { + hasData = true; + item.mPackageChanges = mDailyPackageChanges; + mDailyPackageChanges = null; + } mDailyDischargeStepTracker.init(); mDailyChargeStepTracker.init(); updateDailyDeadlineLocked(); @@ -6899,6 +6948,21 @@ public final class BatteryStatsImpl extends BatteryStats { out.attribute(null, "end", Long.toString(dit.mEndTime)); writeDailyLevelSteps(out, "dis", dit.mDischargeSteps, sb); writeDailyLevelSteps(out, "chg", dit.mChargeSteps, sb); + if (dit.mPackageChanges != null) { + for (int j=0; j<dit.mPackageChanges.size(); j++) { + PackageChange pc = dit.mPackageChanges.get(j); + if (pc.mUpdate) { + out.startTag(null, "upd"); + out.attribute(null, "pkg", pc.mPackageName); + out.attribute(null, "ver", Integer.toString(pc.mVersionCode)); + out.endTag(null, "upd"); + } else { + out.startTag(null, "rem"); + out.attribute(null, "pkg", pc.mPackageName); + out.endTag(null, "rem"); + } + } + } out.endTag(null, "item"); } out.endTag(null, "daily-items"); @@ -7011,6 +7075,26 @@ public final class BatteryStatsImpl extends BatteryStats { readDailyItemTagDetailsLocked(parser, dit, false, "dis"); } else if (tagName.equals("chg")) { readDailyItemTagDetailsLocked(parser, dit, true, "chg"); + } else if (tagName.equals("upd")) { + if (dit.mPackageChanges == null) { + dit.mPackageChanges = new ArrayList<>(); + } + PackageChange pc = new PackageChange(); + pc.mUpdate = true; + pc.mPackageName = parser.getAttributeValue(null, "pkg"); + String verStr = parser.getAttributeValue(null, "ver"); + pc.mVersionCode = verStr != null ? Integer.parseInt(verStr) : 0; + dit.mPackageChanges.add(pc); + XmlUtils.skipCurrentTag(parser); + } else if (tagName.equals("rem")) { + if (dit.mPackageChanges == null) { + dit.mPackageChanges = new ArrayList<>(); + } + PackageChange pc = new PackageChange(); + pc.mUpdate = false; + pc.mPackageName = parser.getAttributeValue(null, "pkg"); + dit.mPackageChanges.add(pc); + XmlUtils.skipCurrentTag(parser); } else { Slog.w(TAG, "Unknown element under <item>: " + parser.getName()); @@ -7295,6 +7379,7 @@ public final class BatteryStatsImpl extends BatteryStats { mInteractiveTimer.reset(false); mPowerSaveModeEnabledTimer.reset(false); mDeviceIdleModeEnabledTimer.reset(false); + mDeviceIdlingTimer.reset(false); mPhoneOnTimer.reset(false); mAudioOnTimer.reset(false); mVideoOnTimer.reset(false); @@ -8083,6 +8168,11 @@ public final class BatteryStatsImpl extends BatteryStats { return mDailyChargeStepTracker; } + @Override + public ArrayList<PackageChange> getDailyPackageChanges() { + return mDailyPackageChanges; + } + long getBatteryUptimeLocked() { return mOnBatteryTimeBase.getUptime(SystemClock.uptimeMillis() * 1000); } @@ -8583,6 +8673,20 @@ public final class BatteryStatsImpl extends BatteryStats { mChargeStepTracker.readFromParcel(in); mDailyDischargeStepTracker.readFromParcel(in); mDailyChargeStepTracker.readFromParcel(in); + int NPKG = in.readInt(); + if (NPKG > 0) { + mDailyPackageChanges = new ArrayList<>(NPKG); + while (NPKG > 0) { + NPKG--; + PackageChange pc = new PackageChange(); + pc.mPackageName = in.readString(); + pc.mUpdate = in.readInt() != 0; + pc.mVersionCode = in.readInt(); + mDailyPackageChanges.add(pc); + } + } else { + mDailyPackageChanges = null; + } mDailyStartTime = in.readLong(); mNextMinDailyDeadline = in.readLong(); mNextMaxDailyDeadline = in.readLong(); @@ -8599,6 +8703,7 @@ public final class BatteryStatsImpl extends BatteryStats { mPhoneOn = false; mPowerSaveModeEnabledTimer.readSummaryFromParcelLocked(in); mDeviceIdleModeEnabledTimer.readSummaryFromParcelLocked(in); + mDeviceIdlingTimer.readSummaryFromParcelLocked(in); mPhoneOnTimer.readSummaryFromParcelLocked(in); for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { mPhoneSignalStrengthsTimer[i].readSummaryFromParcelLocked(in); @@ -8890,6 +8995,18 @@ public final class BatteryStatsImpl extends BatteryStats { mChargeStepTracker.writeToParcel(out); mDailyDischargeStepTracker.writeToParcel(out); mDailyChargeStepTracker.writeToParcel(out); + if (mDailyPackageChanges != null) { + final int NPKG = mDailyPackageChanges.size(); + out.writeInt(NPKG); + for (int i=0; i<NPKG; i++) { + PackageChange pc = mDailyPackageChanges.get(i); + out.writeString(pc.mPackageName); + out.writeInt(pc.mUpdate ? 1 : 0); + out.writeInt(pc.mVersionCode); + } + } else { + out.writeInt(0); + } out.writeLong(mDailyStartTime); out.writeLong(mNextMinDailyDeadline); out.writeLong(mNextMaxDailyDeadline); @@ -8901,6 +9018,7 @@ public final class BatteryStatsImpl extends BatteryStats { mInteractiveTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); mPowerSaveModeEnabledTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); mDeviceIdleModeEnabledTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); + mDeviceIdlingTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); mPhoneOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { mPhoneSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); @@ -9201,6 +9319,7 @@ public final class BatteryStatsImpl extends BatteryStats { mPhoneOn = false; mPowerSaveModeEnabledTimer = new StopwatchTimer(null, -2, null, mOnBatteryTimeBase, in); mDeviceIdleModeEnabledTimer = new StopwatchTimer(null, -11, null, mOnBatteryTimeBase, in); + mDeviceIdlingTimer = new StopwatchTimer(null, -12, null, mOnBatteryTimeBase, in); mPhoneOnTimer = new StopwatchTimer(null, -3, null, mOnBatteryTimeBase, in); for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(null, -200-i, @@ -9367,6 +9486,7 @@ public final class BatteryStatsImpl extends BatteryStats { mInteractiveTimer.writeToParcel(out, uSecRealtime); mPowerSaveModeEnabledTimer.writeToParcel(out, uSecRealtime); mDeviceIdleModeEnabledTimer.writeToParcel(out, uSecRealtime); + mDeviceIdlingTimer.writeToParcel(out, uSecRealtime); mPhoneOnTimer.writeToParcel(out, uSecRealtime); for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { mPhoneSignalStrengthsTimer[i].writeToParcel(out, uSecRealtime); @@ -9507,6 +9627,8 @@ public final class BatteryStatsImpl extends BatteryStats { mPowerSaveModeEnabledTimer.logState(pr, " "); pr.println("*** Device idle mode timer:"); mDeviceIdleModeEnabledTimer.logState(pr, " "); + pr.println("*** Device idling timer:"); + mDeviceIdlingTimer.logState(pr, " "); pr.println("*** Phone timer:"); mPhoneOnTimer.logState(pr, " "); for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { diff --git a/services/core/java/com/android/server/job/JobSchedulerService.java b/services/core/java/com/android/server/job/JobSchedulerService.java index fe1260d5ab72..53bdbeaeccc4 100644 --- a/services/core/java/com/android/server/job/JobSchedulerService.java +++ b/services/core/java/com/android/server/job/JobSchedulerService.java @@ -41,6 +41,7 @@ import android.os.Binder; import android.os.Handler; import android.os.Looper; import android.os.Message; +import android.os.PowerManager; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemClock; @@ -109,21 +110,22 @@ public class JobSchedulerService extends com.android.server.SystemService * Track Services that have currently active or pending jobs. The index is provided by * {@link JobStatus#getServiceToken()} */ - final List<JobServiceContext> mActiveServices = new ArrayList<JobServiceContext>(); + final List<JobServiceContext> mActiveServices = new ArrayList<>(); /** List of controllers that will notify this service of updates to jobs. */ List<StateController> mControllers; /** * Queue of pending jobs. The JobServiceContext class will receive jobs from this list * when ready to execute them. */ - final ArrayList<JobStatus> mPendingJobs = new ArrayList<JobStatus>(); + final ArrayList<JobStatus> mPendingJobs = new ArrayList<>(); - final ArrayList<Integer> mStartedUsers = new ArrayList(); + final ArrayList<Integer> mStartedUsers = new ArrayList<>(); final JobHandler mHandler; final JobSchedulerStub mJobSchedulerStub; IBatteryStats mBatteryStats; + PowerManager mPowerManager; /** * Set to true once we are allowed to run third party apps. @@ -131,6 +133,11 @@ public class JobSchedulerService extends com.android.server.SystemService boolean mReadyToRock; /** + * True when in device idle mode, so we don't want to schedule any jobs. + */ + boolean mDeviceIdleMode; + + /** * Cleans up outstanding jobs when a package is removed. Even if it's being replaced later we * still clean up. On reinstall the package will have a new uid. */ @@ -154,6 +161,8 @@ public class JobSchedulerService extends com.android.server.SystemService Slog.d(TAG, "Removing jobs for user: " + userId); } cancelJobsForUser(userId); + } else if (PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED.equals(intent.getAction())) { + updateIdleMode(mPowerManager != null ? mPowerManager.isDeviceIdleMode() : false); } } }; @@ -199,7 +208,7 @@ public class JobSchedulerService extends com.android.server.SystemService return outList; } - private void cancelJobsForUser(int userHandle) { + void cancelJobsForUser(int userHandle) { List<JobStatus> jobsForUser; synchronized (mJobs) { jobsForUser = mJobs.getJobsByUser(userHandle); @@ -257,6 +266,40 @@ public class JobSchedulerService extends com.android.server.SystemService } } + void updateIdleMode(boolean enabled) { + boolean changed = false; + boolean rocking; + synchronized (mJobs) { + if (mDeviceIdleMode != enabled) { + changed = true; + } + rocking = mReadyToRock; + } + if (changed) { + if (rocking) { + for (int i=0; i<mControllers.size(); i++) { + mControllers.get(i).deviceIdleModeChanged(enabled); + } + } + synchronized (mJobs) { + mDeviceIdleMode = enabled; + if (enabled) { + // When becoming idle, make sure no jobs are actively running. + for (int i=0; i<mActiveServices.size(); i++) { + JobServiceContext jsc = mActiveServices.get(i); + final JobStatus executing = jsc.getRunningJob(); + if (executing != null) { + jsc.cancelExecutingJob(); + } + } + } else { + // When coming out of idle, allow thing to start back up. + mHandler.obtainMessage(MSG_CHECK_JOB).sendToTarget(); + } + } + } + } + /** * Initializes the system service. * <p> @@ -294,8 +337,10 @@ public class JobSchedulerService extends com.android.server.SystemService getContext().registerReceiverAsUser( mBroadcastReceiver, UserHandle.ALL, filter, null, null); final IntentFilter userFilter = new IntentFilter(Intent.ACTION_USER_REMOVED); + userFilter.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED); getContext().registerReceiverAsUser( mBroadcastReceiver, UserHandle.ALL, userFilter, null, null); + mPowerManager = (PowerManager)getContext().getSystemService(Context.POWER_SERVICE); } else if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) { synchronized (mJobs) { // Let's go! @@ -313,6 +358,7 @@ public class JobSchedulerService extends com.android.server.SystemService for (int i=0; i<jobs.size(); i++) { JobStatus job = jobs.valueAt(i); for (int controller=0; controller<mControllers.size(); controller++) { + mControllers.get(i).deviceIdleModeChanged(mDeviceIdleMode); mControllers.get(controller).maybeStartTrackingJob(job); } } @@ -667,6 +713,10 @@ public class JobSchedulerService extends com.android.server.SystemService */ private void maybeRunPendingJobsH() { synchronized (mJobs) { + if (mDeviceIdleMode) { + // If device is idle, we will not schedule jobs to run. + return; + } Iterator<JobStatus> it = mPendingJobs.iterator(); if (DEBUG) { Slog.d(TAG, "pending queue: " + mPendingJobs.size() + " jobs."); @@ -878,6 +928,7 @@ public class JobSchedulerService extends com.android.server.SystemService } pw.println(); pw.print("mReadyToRock="); pw.println(mReadyToRock); + pw.print("mDeviceIdleMode="); pw.println(mDeviceIdleMode); } pw.println(); } diff --git a/services/core/java/com/android/server/job/controllers/StateController.java b/services/core/java/com/android/server/job/controllers/StateController.java index 7d76fc02b44b..efd192844c34 100644 --- a/services/core/java/com/android/server/job/controllers/StateController.java +++ b/services/core/java/com/android/server/job/controllers/StateController.java @@ -31,12 +31,17 @@ public abstract class StateController { protected static final boolean DEBUG = false; protected Context mContext; protected StateChangedListener mStateChangedListener; + protected boolean mDeviceIdleMode; public StateController(StateChangedListener stateChangedListener, Context context) { mStateChangedListener = stateChangedListener; mContext = context; } + public void deviceIdleModeChanged(boolean enabled) { + mDeviceIdleMode = enabled; + } + /** * Implement the logic here to decide whether a job should be tracked by this controller. * This logic is put here so the JobManger can be completely agnostic of Controller logic. @@ -50,5 +55,4 @@ public abstract class StateController { public abstract void maybeStopTrackingJob(JobStatus jobStatus); public abstract void dumpControllerState(PrintWriter pw); - } diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java index 8d467756c67d..5de7d422ee80 100644 --- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java @@ -71,7 +71,9 @@ import static com.android.server.net.NetworkStatsService.ACTION_NETWORK_STATS_UP import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; import static org.xmlpull.v1.XmlPullParser.START_TAG; +import android.Manifest; import android.app.ActivityManager; +import android.app.AppGlobals; import android.app.IActivityManager; import android.app.INotificationManager; import android.app.IProcessObserver; @@ -83,6 +85,7 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.ApplicationInfo; +import android.content.pm.IPackageManager; import android.content.pm.PackageManager; import android.content.pm.UserInfo; import android.content.res.Resources; @@ -2021,6 +2024,17 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { void updateRulesForUidLocked(int uid) { if (!isUidValidForRules(uid)) return; + // quick check: if this uid doesn't have INTERNET permission, it doesn't have + // network access anyway, so it is a waste to mess with it here. + final IPackageManager ipm = AppGlobals.getPackageManager(); + try { + if (ipm.checkUidPermission(Manifest.permission.INTERNET, uid) + != PackageManager.PERMISSION_GRANTED) { + return; + } + } catch (RemoteException e) { + } + final int uidPolicy = mUidPolicy.get(uid, POLICY_NONE); final boolean uidForeground = isUidForegroundLocked(uid); diff --git a/services/core/java/com/android/server/DeviceIdleController.java b/services/core/java/com/android/server/power/DeviceIdleController.java index 062992d684bb..dd0044654c9c 100644 --- a/services/core/java/com/android/server/DeviceIdleController.java +++ b/services/core/java/com/android/server/power/DeviceIdleController.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.server; +package com.android.server.power; import android.app.AlarmManager; import android.app.PendingIntent; @@ -30,12 +30,16 @@ import android.hardware.TriggerEventListener; import android.hardware.display.DisplayManager; import android.net.INetworkPolicyManager; import android.os.Binder; +import android.os.PowerManager; +import android.os.PowerManagerInternal; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemClock; +import android.os.UserHandle; import android.util.TimeUtils; import android.view.Display; import com.android.internal.app.IBatteryStats; +import com.android.server.SystemService; import com.android.server.am.BatteryStatsService; import java.io.FileDescriptor; @@ -60,6 +64,11 @@ public class DeviceIdleController extends SystemService { */ private static final long DEFAULT_INACTIVE_TIMEOUT = 30*60*1000L; /** + * This is the time, after seeing motion, that we wait after becoming inactive from + * that until we start looking for motion again. + */ + private static final long DEFAULT_MOTION_INACTIVE_TIMEOUT = 10*60*1000L; + /** * This is the time, after the inactive timeout elapses, that we will wait looking * for significant motion until we truly consider the device to be idle. */ @@ -94,11 +103,13 @@ public class DeviceIdleController extends SystemService { private AlarmManager mAlarmManager; private IBatteryStats mBatteryStats; + private PowerManagerInternal mLocalPowerManager; private INetworkPolicyManager mNetworkPolicyManager; private DisplayManager mDisplayManager; private SensorManager mSensorManager; private Sensor mSigMotionSensor; private PendingIntent mAlarmIntent; + private Intent mIdleIntent; private Display mCurDisplay; private boolean mScreenOn; private boolean mCharging; @@ -124,6 +135,7 @@ public class DeviceIdleController extends SystemService { private int mState; + private long mInactiveTimeout; private long mNextAlarmTime; private long mNextIdlePendingDelay; private long mNextIdleDelay; @@ -181,6 +193,7 @@ public class DeviceIdleController extends SystemService { synchronized (this) { mAlarmManager = (AlarmManager) getContext().getSystemService(Context.ALARM_SERVICE); mBatteryStats = BatteryStatsService.getService(); + mLocalPowerManager = getLocalService(PowerManagerInternal.class); mNetworkPolicyManager = INetworkPolicyManager.Stub.asInterface( ServiceManager.getService(Context.NETWORK_POLICY_SERVICE)); mDisplayManager = (DisplayManager) getContext().getSystemService( @@ -193,6 +206,9 @@ public class DeviceIdleController extends SystemService { .setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); mAlarmIntent = PendingIntent.getBroadcast(getContext(), 0, intent, 0); + mIdleIntent = new Intent(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED); + mIdleIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); + IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_BATTERY_CHANGED); filter.addAction(ACTION_STEP_IDLE_STATE); @@ -205,6 +221,7 @@ public class DeviceIdleController extends SystemService { // a battery update the next time the level drops. mCharging = true; mState = STATE_ACTIVE; + mInactiveTimeout = DEFAULT_INACTIVE_TIMEOUT; updateDisplayLocked(); } @@ -238,12 +255,17 @@ public class DeviceIdleController extends SystemService { void becomeActiveLocked() { if (mState != STATE_ACTIVE) { + mLocalPowerManager.setDeviceIdleMode(false); try { mNetworkPolicyManager.setDeviceIdleMode(false); mBatteryStats.noteDeviceIdleMode(false, true, false); } catch (RemoteException e) { } + if (mState == STATE_IDLE) { + getContext().sendBroadcastAsUser(mIdleIntent, UserHandle.ALL); + } mState = STATE_ACTIVE; + mInactiveTimeout = DEFAULT_INACTIVE_TIMEOUT; mNextIdlePendingDelay = 0; mNextIdleDelay = 0; cancelAlarmLocked(); @@ -256,7 +278,9 @@ public class DeviceIdleController extends SystemService { // 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; - scheduleAlarmLocked(DEFAULT_INACTIVE_TIMEOUT, false); + mNextIdlePendingDelay = 0; + mNextIdleDelay = 0; + scheduleAlarmLocked(mInactiveTimeout, false); } } @@ -283,11 +307,13 @@ public class DeviceIdleController extends SystemService { mNextIdleDelay = DEFAULT_MAX_IDLE_TIMEOUT; } mState = STATE_IDLE; + mLocalPowerManager.setDeviceIdleMode(true); try { mNetworkPolicyManager.setDeviceIdleMode(true); mBatteryStats.noteDeviceIdleMode(true, false, false); } catch (RemoteException e) { } + getContext().sendBroadcastAsUser(mIdleIntent, UserHandle.ALL); break; case STATE_IDLE: // We have been idling long enough, now it is time to do some work. @@ -297,11 +323,13 @@ public class DeviceIdleController extends SystemService { mNextIdlePendingDelay = DEFAULT_MAX_IDLE_PENDING_TIMEOUT; } mState = STATE_IDLE_PENDING; + mLocalPowerManager.setDeviceIdleMode(false); try { mNetworkPolicyManager.setDeviceIdleMode(false); mBatteryStats.noteDeviceIdleMode(false, false, false); } catch (RemoteException e) { } + getContext().sendBroadcastAsUser(mIdleIntent, UserHandle.ALL); break; } } @@ -313,13 +341,18 @@ public class DeviceIdleController extends SystemService { // state to wait again for no motion. Note that we only monitor for significant // motion after moving out of the inactive state, so no need to worry about that. if (mState != STATE_ACTIVE) { - mState = STATE_INACTIVE; + mLocalPowerManager.setDeviceIdleMode(false); try { mNetworkPolicyManager.setDeviceIdleMode(false); mBatteryStats.noteDeviceIdleMode(false, false, true); } catch (RemoteException e) { } - stepIdleStateLocked(); + if (mState == STATE_IDLE) { + getContext().sendBroadcastAsUser(mIdleIntent, UserHandle.ALL); + } + mState = STATE_ACTIVE; + mInactiveTimeout = DEFAULT_MOTION_INACTIVE_TIMEOUT; + becomeInactiveIfAppropriateLocked(); } } @@ -399,26 +432,30 @@ public class DeviceIdleController extends SystemService { } } - pw.print(" mSigMotionSensor="); pw.println(mSigMotionSensor); - pw.print(" mCurDisplay="); pw.println(mCurDisplay); - pw.print(" mScreenOn="); pw.println(mScreenOn); - pw.print(" mCharging="); pw.println(mCharging); - pw.print(" mSigMotionActive="); pw.println(mSigMotionActive); - pw.print(" mState="); pw.println(stateToString(mState)); - if (mNextAlarmTime != 0) { - pw.print(" mNextAlarmTime="); - TimeUtils.formatDuration(mNextAlarmTime, SystemClock.elapsedRealtime(), pw); - pw.println(); - } - if (mNextIdlePendingDelay != 0) { - pw.print(" mNextIdlePendingDelay="); - TimeUtils.formatDuration(mNextIdlePendingDelay, pw); - pw.println(); - } - if (mNextIdleDelay != 0) { - pw.print(" mNextIdleDelay="); - TimeUtils.formatDuration(mNextIdleDelay, pw); + synchronized (this) { + pw.print(" mSigMotionSensor="); pw.println(mSigMotionSensor); + pw.print(" mCurDisplay="); pw.println(mCurDisplay); + pw.print(" mScreenOn="); pw.println(mScreenOn); + pw.print(" mCharging="); pw.println(mCharging); + pw.print(" mSigMotionActive="); pw.println(mSigMotionActive); + pw.print(" mState="); pw.println(stateToString(mState)); + pw.print(" mInactiveTimeout="); TimeUtils.formatDuration(mInactiveTimeout, pw); pw.println(); + if (mNextAlarmTime != 0) { + pw.print(" mNextAlarmTime="); + TimeUtils.formatDuration(mNextAlarmTime, SystemClock.elapsedRealtime(), pw); + pw.println(); + } + if (mNextIdlePendingDelay != 0) { + pw.print(" mNextIdlePendingDelay="); + TimeUtils.formatDuration(mNextIdlePendingDelay, pw); + pw.println(); + } + if (mNextIdleDelay != 0) { + pw.print(" mNextIdleDelay="); + TimeUtils.formatDuration(mNextIdleDelay, pw); + pw.println(); + } } } } diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java index 9e373b72d445..33b451d53cd8 100644 --- a/services/core/java/com/android/server/power/PowerManagerService.java +++ b/services/core/java/com/android/server/power/PowerManagerService.java @@ -420,6 +420,9 @@ public final class PowerManagerService extends SystemService // True if the battery level is currently considered low. private boolean mBatteryLevelLow; + // True if we are currently in device idle mode. + private boolean mDeviceIdleMode; + // True if theater mode is enabled private boolean mTheaterModeEnabled; @@ -2178,6 +2181,12 @@ public final class PowerManagerService extends SystemService } } + private boolean isDeviceIdleModeInternal() { + synchronized (mLock) { + return mDeviceIdleMode; + } + } + private void handleBatteryStateChangedLocked() { mDirty |= DIRTY_BATTERY_STATE; updatePowerStateLocked(); @@ -3050,6 +3059,16 @@ public final class PowerManagerService extends SystemService } } + @Override // Binder call + public boolean isDeviceIdleMode() { + final long ident = Binder.clearCallingIdentity(); + try { + return isDeviceIdleModeInternal(); + } finally { + Binder.restoreCallingIdentity(ident); + } + } + /** * Reboots the device. * @@ -3295,5 +3314,12 @@ public final class PowerManagerService extends SystemService mLowPowerModeListeners.add(listener); } } + + @Override + public void setDeviceIdleMode(boolean enabled) { + synchronized (mLock) { + mDeviceIdleMode = enabled; + } + } } } diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index ae2c54b722e9..afce948e66b9 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -66,7 +66,6 @@ import com.android.server.lights.LightsService; import com.android.server.media.MediaRouterService; import com.android.server.media.MediaSessionService; import com.android.server.media.projection.MediaProjectionManagerService; -import com.android.server.MidiService; import com.android.server.net.NetworkPolicyManagerService; import com.android.server.net.NetworkStatsService; import com.android.server.notification.NotificationManagerService; @@ -76,6 +75,7 @@ import com.android.server.pm.Installer; import com.android.server.pm.LauncherAppsService; import com.android.server.pm.PackageManagerService; import com.android.server.pm.UserManagerService; +import com.android.server.power.DeviceIdleController; import com.android.server.power.PowerManagerService; import com.android.server.power.ShutdownThread; import com.android.server.restrictions.RestrictionsManagerService; |