summaryrefslogtreecommitdiffstats
path: root/core/java
diff options
context:
space:
mode:
authorDianne Hackborn <hackbod@google.com>2015-06-12 19:38:38 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2015-06-12 19:38:39 +0000
commite554cc96597d4b738f14a1514772e4d49e78c542 (patch)
treecdee6876faa1c56d2e0ec3dc0cfb51f2913372db /core/java
parent17de4b2a73996366ff3d7759793a6809654caebe (diff)
parent3d1933c45fe9ba2389ebd166d96abeceab1971d1 (diff)
downloadframeworks_base-e554cc96597d4b738f14a1514772e4d49e78c542.zip
frameworks_base-e554cc96597d4b738f14a1514772e4d49e78c542.tar.gz
frameworks_base-e554cc96597d4b738f14a1514772e4d49e78c542.tar.bz2
Merge "Implement some control over ALLOW_WHILE_IDLE alarms." into mnc-dev
Diffstat (limited to 'core/java')
-rw-r--r--core/java/android/app/AlarmManager.java23
-rw-r--r--core/java/android/util/TimeUtils.java86
2 files changed, 75 insertions, 34 deletions
diff --git a/core/java/android/app/AlarmManager.java b/core/java/android/app/AlarmManager.java
index 5e7bd0d..9ea1606 100644
--- a/core/java/android/app/AlarmManager.java
+++ b/core/java/android/app/AlarmManager.java
@@ -142,13 +142,22 @@ public class AlarmManager {
public static final int FLAG_ALLOW_WHILE_IDLE = 1<<2;
/**
+ * Flag for alarms: same as {@link #FLAG_ALLOW_WHILE_IDLE}, but doesn't have restrictions
+ * on how frequently it can be scheduled. Only available (and automatically applied) to
+ * system alarms.
+ *
+ * @hide
+ */
+ public static final int FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED = 1<<3;
+
+ /**
* Flag for alarms: this alarm marks the point where we would like to come out of idle
* mode. It may be moved by the alarm manager to match the first wake-from-idle alarm.
* Scheduling an alarm with this flag puts the alarm manager in to idle mode, where it
* avoids scheduling any further alarms until the marker alarm is executed.
* @hide
*/
- public static final int FLAG_IDLE_UNTIL = 1<<3;
+ public static final int FLAG_IDLE_UNTIL = 1<<4;
private final IAlarmManager mService;
private final boolean mAlwaysExact;
@@ -565,6 +574,12 @@ public class AlarmManager {
* of the device when idle (and thus cause significant battery blame to the app scheduling
* them), so they should be used with care.
*
+ * <p>To reduce abuse, there are restrictions on how frequently these alarms will go off
+ * for a particular application. Under normal system operation, it will not dispatch these
+ * alarms more than about every minute (at which point every such pending alarm is
+ * dispatched); when in low-power idle modes this duration may be significantly longer,
+ * such as 15 minutes.</p>
+ *
* <p>Unlike other alarms, the system is free to reschedule this type of alarm to happen
* out of order with any other alarms, even those from the same app. This will clearly happen
* when the device is idle (since this alarm can go off while idle, when any other alarms
@@ -608,6 +623,12 @@ public class AlarmManager {
* of the device when idle (and thus cause significant battery blame to the app scheduling
* them), so they should be used with care.
*
+ * <p>To reduce abuse, there are restrictions on how frequently these alarms will go off
+ * for a particular application. Under normal system operation, it will not dispatch these
+ * alarms more than about every minute (at which point every such pending alarm is
+ * dispatched); when in low-power idle modes this duration may be significantly longer,
+ * such as 15 minutes.</p>
+ *
* <p>Unlike other alarms, the system is free to reschedule this type of alarm to happen
* out of order with any other alarms, even those from the same app. This will clearly happen
* when the device is idle (since this alarm can go off while idle, when any other alarms
diff --git a/core/java/android/util/TimeUtils.java b/core/java/android/util/TimeUtils.java
index f7d2821..353388d 100644
--- a/core/java/android/util/TimeUtils.java
+++ b/core/java/android/util/TimeUtils.java
@@ -246,41 +246,65 @@ public class TimeUtils {
public static final long NANOS_PER_MS = 1000000;
private static final Object sFormatSync = new Object();
- private static char[] sFormatStr = new char[HUNDRED_DAY_FIELD_LEN+5];
-
- private static final long LARGEST_DURATION = (1000 * DateUtils.DAY_IN_MILLIS) - 1;
+ private static char[] sFormatStr = new char[HUNDRED_DAY_FIELD_LEN+10];
+ private static char[] sTmpFormatStr = new char[HUNDRED_DAY_FIELD_LEN+10];
static private int accumField(int amt, int suffix, boolean always, int zeropad) {
- if (amt > 99 || (always && zeropad >= 3)) {
- return 3+suffix;
- }
- if (amt > 9 || (always && zeropad >= 2)) {
- return 2+suffix;
- }
- if (always || amt > 0) {
- return 1+suffix;
+ if (amt > 999) {
+ int num = 0;
+ while (amt != 0) {
+ num++;
+ amt /= 10;
+ }
+ return num + suffix;
+ } else {
+ if (amt > 99 || (always && zeropad >= 3)) {
+ return 3+suffix;
+ }
+ if (amt > 9 || (always && zeropad >= 2)) {
+ return 2+suffix;
+ }
+ if (always || amt > 0) {
+ return 1+suffix;
+ }
}
return 0;
}
- static private int printField(char[] formatStr, int amt, char suffix, int pos,
+ static private int printFieldLocked(char[] formatStr, int amt, char suffix, int pos,
boolean always, int zeropad) {
if (always || amt > 0) {
final int startPos = pos;
- if ((always && zeropad >= 3) || amt > 99) {
- int dig = amt/100;
- formatStr[pos] = (char)(dig + '0');
- pos++;
- amt -= (dig*100);
- }
- if ((always && zeropad >= 2) || amt > 9 || startPos != pos) {
- int dig = amt/10;
- formatStr[pos] = (char)(dig + '0');
+ if (amt > 999) {
+ int tmp = 0;
+ while (amt != 0 && tmp < sTmpFormatStr.length) {
+ int dig = amt % 10;
+ sTmpFormatStr[tmp] = (char)(dig + '0');
+ tmp++;
+ amt /= 10;
+ }
+ tmp--;
+ while (tmp >= 0) {
+ formatStr[pos] = sTmpFormatStr[tmp];
+ pos++;
+ tmp--;
+ }
+ } else {
+ if ((always && zeropad >= 3) || amt > 99) {
+ int dig = amt/100;
+ formatStr[pos] = (char)(dig + '0');
+ pos++;
+ amt -= (dig*100);
+ }
+ if ((always && zeropad >= 2) || amt > 9 || startPos != pos) {
+ int dig = amt/10;
+ formatStr[pos] = (char)(dig + '0');
+ pos++;
+ amt -= (dig*10);
+ }
+ formatStr[pos] = (char)(amt + '0');
pos++;
- amt -= (dig*10);
}
- formatStr[pos] = (char)(amt + '0');
- pos++;
formatStr[pos] = suffix;
pos++;
}
@@ -312,10 +336,6 @@ public class TimeUtils {
duration = -duration;
}
- if (duration > LARGEST_DURATION) {
- duration = LARGEST_DURATION;
- }
-
int millis = (int)(duration%1000);
int seconds = (int) Math.floor(duration / 1000);
int days = 0, hours = 0, minutes = 0;
@@ -353,11 +373,11 @@ public class TimeUtils {
int start = pos;
boolean zeropad = fieldLen != 0;
- pos = printField(formatStr, days, 'd', pos, false, 0);
- pos = printField(formatStr, hours, 'h', pos, pos != start, zeropad ? 2 : 0);
- pos = printField(formatStr, minutes, 'm', pos, pos != start, zeropad ? 2 : 0);
- pos = printField(formatStr, seconds, 's', pos, pos != start, zeropad ? 2 : 0);
- pos = printField(formatStr, millis, 'm', pos, true, (zeropad && pos != start) ? 3 : 0);
+ pos = printFieldLocked(formatStr, days, 'd', pos, false, 0);
+ pos = printFieldLocked(formatStr, hours, 'h', pos, pos != start, zeropad ? 2 : 0);
+ pos = printFieldLocked(formatStr, minutes, 'm', pos, pos != start, zeropad ? 2 : 0);
+ pos = printFieldLocked(formatStr, seconds, 's', pos, pos != start, zeropad ? 2 : 0);
+ pos = printFieldLocked(formatStr, millis, 'm', pos, true, (zeropad && pos != start) ? 3 : 0);
formatStr[pos] = 's';
return pos + 1;
}