summaryrefslogtreecommitdiffstats
path: root/core/java/android
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/os/BatteryStats.java112
-rw-r--r--core/java/android/os/IPowerManager.aidl1
-rw-r--r--core/java/android/os/PowerManager.java25
-rw-r--r--core/java/android/os/PowerManagerInternal.java4
-rw-r--r--core/java/android/widget/Editor.java72
5 files changed, 186 insertions, 28 deletions
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index cab03da..26e6b85 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 16dac7d..418641f 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 de970cb..81745b3 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 6f31768..00ab262 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/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 3fca463..87fcd81 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -3348,7 +3348,7 @@ public class Editor {
// Minimum touch target size for handles
private int mMinSize;
// Indicates the line of text that the handle is on.
- protected int mLine = -1;
+ protected int mPrevLine = -1;
public HandleView(Drawable drawableLtr, Drawable drawableRtl) {
super(mTextView.getContext());
@@ -3499,7 +3499,7 @@ public class Editor {
addPositionToTouchUpFilter(offset);
}
final int line = layout.getLineForOffset(offset);
- mLine = line;
+ mPrevLine = line;
mPositionX = (int) (layout.getPrimaryHorizontal(offset) - 0.5f - mHotspotX -
getHorizontalOffset() + getCursorOffset());
@@ -3839,19 +3839,22 @@ public class Editor {
public void updatePosition(float x, float y) {
final int trueOffset = mTextView.getOffsetForPosition(x, y);
final int currLine = mTextView.getLineAtCoordinate(y);
- int offset = trueOffset;
- boolean positionCursor = false;
+ // Don't select white space on different lines.
+ if (isWhitespaceLine(mPrevLine, currLine, trueOffset)) return;
+
+ boolean positionCursor = false;
+ int offset = trueOffset;
int end = getWordEnd(offset, true);
int start = getWordStart(offset);
if (offset < mPrevOffset) {
// User is increasing the selection.
- if (!mInWord || currLine < mLine) {
+ if (!mInWord || currLine < mPrevLine) {
// We're not in a word, or we're on a different line so we'll expand by
// word. First ensure the user has at least entered the next word.
int offsetToWord = Math.min((end - start) / 2, 2);
- if (offset <= end - offsetToWord || currLine < mLine) {
+ if (offset <= end - offsetToWord || currLine < mPrevLine) {
offset = start;
} else {
offset = mPrevOffset;
@@ -3863,7 +3866,7 @@ public class Editor {
positionCursor = true;
} else if (offset - mTouchWordOffset > mPrevOffset) {
// User is shrinking the selection.
- if (currLine > mLine) {
+ if (currLine > mPrevLine) {
// We're on a different line, so we'll snap to word boundaries.
offset = end;
}
@@ -3878,7 +3881,7 @@ public class Editor {
final int selectionEnd = mTextView.getSelectionEnd();
if (offset >= selectionEnd) {
// We can't cross the handles so let's just constrain the Y value.
- int alteredOffset = mTextView.getOffsetAtCoordinate(mLine, x);
+ int alteredOffset = mTextView.getOffsetAtCoordinate(mPrevLine, x);
if (alteredOffset >= selectionEnd) {
// Can't pass the other drag handle.
offset = Math.max(0, selectionEnd - 1);
@@ -3939,6 +3942,10 @@ public class Editor {
public void updatePosition(float x, float y) {
final int trueOffset = mTextView.getOffsetForPosition(x, y);
final int currLine = mTextView.getLineAtCoordinate(y);
+
+ // Don't select white space on different lines.
+ if (isWhitespaceLine(mPrevLine, currLine, trueOffset)) return;
+
int offset = trueOffset;
boolean positionCursor = false;
@@ -3947,11 +3954,11 @@ public class Editor {
if (offset > mPrevOffset) {
// User is increasing the selection.
- if (!mInWord || currLine > mLine) {
+ if (!mInWord || currLine > mPrevLine) {
// We're not in a word, or we're on a different line so we'll expand by
// word. First ensure the user has at least entered the next word.
int midPoint = Math.min((end - start) / 2, 2);
- if (offset >= start + midPoint || currLine > mLine) {
+ if (offset >= start + midPoint || currLine > mPrevLine) {
offset = end;
} else {
offset = mPrevOffset;
@@ -3963,7 +3970,7 @@ public class Editor {
positionCursor = true;
} else if (offset + mTouchWordOffset < mPrevOffset) {
// User is shrinking the selection.
- if (currLine > mLine) {
+ if (currLine > mPrevLine) {
// We're on a different line, so we'll snap to word boundaries.
offset = getWordStart(offset);
}
@@ -3977,7 +3984,7 @@ public class Editor {
final int selectionStart = mTextView.getSelectionStart();
if (offset <= selectionStart) {
// We can't cross the handles so let's just constrain the Y value.
- int alteredOffset = mTextView.getOffsetAtCoordinate(mLine, x);
+ int alteredOffset = mTextView.getOffsetAtCoordinate(mPrevLine, x);
int length = mTextView.getText().length();
if (alteredOffset <= selectionStart) {
// Can't pass the other drag handle.
@@ -4002,6 +4009,36 @@ public class Editor {
}
/**
+ * Checks whether selection is happening on a different line than previous and
+ * if that line only contains whitespace up to the touch location.
+ *
+ * @param prevLine The previous line the selection was on.
+ * @param currLine The current line being selected.
+ * @param offset The offset in the text where the touch occurred.
+ * @return Whether or not it was just a white space line being selected.
+ */
+ private boolean isWhitespaceLine(int prevLine, int currLine, int offset) {
+ if (prevLine == currLine) {
+ // Same line; don't care.
+ return false;
+ }
+ CharSequence text = mTextView.getText();
+ if (offset == text.length()) {
+ // No character at the last position.
+ return false;
+ }
+ int lineEndOffset = mTextView.getLayout().getLineEnd(currLine);
+ for (int cp, i = offset; i < lineEndOffset; i += Character.charCount(cp)) {
+ cp = Character.codePointAt(text, i);
+ if (!Character.isSpaceChar(cp) && !Character.isWhitespace(cp)) {
+ // There are non white space chars on the line.
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
* A CursorController instance can be used to control a cursor in the text.
*/
private interface CursorController extends ViewTreeObserver.OnTouchModeChangeListener {
@@ -4081,6 +4118,8 @@ public class Editor {
private int mStartOffset = -1;
// Indicates whether the user is selecting text and using the drag accelerator.
private boolean mDragAcceleratorActive;
+ // Indicates the line of text the drag accelerator is on.
+ private int mPrevLine = -1;
SelectionModifierCursorController() {
resetTouchOffsets();
@@ -4173,6 +4212,8 @@ public class Editor {
}
}
+ // New selection, reset line.
+ mPrevLine = mTextView.getLineAtCoordinate(y);
mDownPositionX = x;
mDownPositionY = y;
mGestureStayedInTapRegion = true;
@@ -4229,6 +4270,13 @@ public class Editor {
if (my > fingerOffset) my -= fingerOffset;
offset = mTextView.getOffsetForPosition(mx, my);
+ int currLine = mTextView.getLineAtCoordinate(my);
+
+ // Don't select white space on different lines.
+ if (isWhitespaceLine(mPrevLine, currLine, offset)) return;
+
+ mPrevLine = currLine;
+
// Perform the check for closeness at edge of view, if we're very close
// don't adjust the offset to be in front of the finger - otherwise the
// user can't select words at the edge.