summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Serik Beketayev <serikb@google.com> 2019-02-20 16:50:26 -0800
committer Suprabh Shukla <suprabh@google.com> 2019-04-05 04:32:41 +0000
commitc32088c1579a85fd5de455d5dde388e7f712b80a (patch)
treea648930a5156641a6e4c44cb6f17cf3687c0c5c1
parent442a4e7b163fdb72fcd3ff4253a0d3e8511d1b7c (diff)
Disable a wakeup alarm in car.
- Car in power off or suspend state should not wake up from alarm. Test: run added unit test. Bug: 123430582 Change-Id: I5cdf93fc816cd3e8a5d2a6d93616ff6040840613
-rw-r--r--services/core/java/com/android/server/AlarmManagerService.java25
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/AlarmManagerServiceTest.java53
2 files changed, 76 insertions, 2 deletions
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index 0f39029f47b9..47c85683b4e6 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -1697,6 +1697,8 @@ class AlarmManagerService extends SystemService {
return;
}
+ type = fixTypeIfAuto(type);
+
// Sanity check the window length. This will catch people mistakenly
// trying to pass an end-of-window timestamp rather than a duration.
if (windowLength > AlarmManager.INTERVAL_HALF_DAY) {
@@ -1812,6 +1814,21 @@ class AlarmManagerService extends SystemService {
}
/**
+ * In case of cars, we need to avoid scheduling wakeup alarms, since we don't want the system
+ * to wake up from suspend arbitrarily to perform app work.
+ */
+ private int fixTypeIfAuto(int type) {
+ if (mInjector.isAutomotive()) {
+ if (type == AlarmManager.ELAPSED_REALTIME_WAKEUP) {
+ type = AlarmManager.ELAPSED_REALTIME;
+ } else if (type == AlarmManager.RTC_WAKEUP) {
+ type = AlarmManager.RTC;
+ }
+ }
+ return type;
+ }
+
+ /**
* Return the minimum time that should elapse before an app in the specified bucket
* can receive alarms again
*/
@@ -2214,6 +2231,7 @@ class AlarmManagerService extends SystemService {
pw.print(" mLastTickSet="); pw.println(sdf.format(new Date(mLastTickSet)));
pw.print(" mLastTickAdded="); pw.println(sdf.format(new Date(mLastTickAdded)));
pw.print(" mLastTickRemoved="); pw.println(sdf.format(new Date(mLastTickRemoved)));
+ pw.print(" mIsAutomotive="); pw.println(mInjector.isAutomotive());
if (RECORD_ALARMS_IN_HISTORY) {
pw.println();
@@ -3838,9 +3856,12 @@ class AlarmManagerService extends SystemService {
static class Injector {
private long mNativeData;
private Context mContext;
+ private final boolean mIsAutomotive;
Injector(Context context) {
mContext = context;
+ mIsAutomotive = context.getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_AUTOMOTIVE);
}
void init() {
@@ -3929,6 +3950,10 @@ class AlarmManagerService extends SystemService {
ClockReceiver getClockReceiver(AlarmManagerService service) {
return service.new ClockReceiver();
}
+
+ boolean isAutomotive() {
+ return mIsAutomotive;
+ }
}
private class AlarmThread extends Thread
diff --git a/services/tests/mockingservicestests/src/com/android/server/AlarmManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/AlarmManagerServiceTest.java
index 7a40e449aaec..7a68e92cff6d 100644
--- a/services/tests/mockingservicestests/src/com/android/server/AlarmManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/AlarmManagerServiceTest.java
@@ -66,6 +66,7 @@ import android.app.usage.UsageStatsManagerInternal;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.PackageManager;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
@@ -118,6 +119,8 @@ public class AlarmManagerServiceTest {
private AlarmManagerService.ClockReceiver mClockReceiver;
@Mock
private PowerManager.WakeLock mWakeLock;
+ @Mock
+ private PackageManager mMockPackageManager;
private MockitoSession mMockingSession;
private Injector mInjector;
@@ -128,15 +131,21 @@ public class AlarmManagerServiceTest {
static class TestTimer {
private long mElapsed;
boolean mExpired;
+ int mType;
synchronized long getElapsed() {
return mElapsed;
}
- synchronized void set(long millisElapsed) {
+ synchronized void set(int type, long millisElapsed) {
+ mType = type;
mElapsed = millisElapsed;
}
+ synchronized int getType() {
+ return mType;
+ }
+
synchronized void expire() throws InterruptedException {
mExpired = true;
notifyAll();
@@ -146,6 +155,8 @@ public class AlarmManagerServiceTest {
}
public class Injector extends AlarmManagerService.Injector {
+ boolean mIsAutomotiveOverride;
+
Injector(Context context) {
super(context);
}
@@ -179,7 +190,7 @@ public class AlarmManagerServiceTest {
@Override
void setAlarm(int type, long millis) {
- mTestTimer.set(millis);
+ mTestTimer.set(type, millis);
}
@Override
@@ -211,6 +222,11 @@ public class AlarmManagerServiceTest {
PowerManager.WakeLock getAlarmWakeLock() {
return mWakeLock;
}
+
+ @Override
+ boolean isAutomotive() {
+ return mIsAutomotiveOverride;
+ }
}
@Before
@@ -237,6 +253,8 @@ public class AlarmManagerServiceTest {
when(mMockContext.getContentResolver()).thenReturn(mMockResolver);
doReturn("min_futurity=0,min_interval=0").when(() ->
Settings.Global.getString(mMockResolver, Settings.Global.ALARM_MANAGER_CONSTANTS));
+ when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
+
mInjector = new Injector(mMockContext);
mService = new AlarmManagerService(mMockContext, mInjector);
spyOn(mService);
@@ -933,6 +951,37 @@ public class AlarmManagerServiceTest {
}
@Test
+ public void alarmTypes() throws Exception {
+ final int[] typesToSet = {ELAPSED_REALTIME_WAKEUP, ELAPSED_REALTIME, RTC_WAKEUP, RTC};
+ final int[] typesExpected = {ELAPSED_REALTIME_WAKEUP, ELAPSED_REALTIME,
+ ELAPSED_REALTIME_WAKEUP, ELAPSED_REALTIME};
+ assertAlarmTypeConversion(typesToSet, typesExpected);
+ }
+
+ /**
+ * Confirm that wakeup alarms are never set for automotive.
+ */
+ @Test
+ public void alarmTypesForAuto() throws Exception {
+ mInjector.mIsAutomotiveOverride = true;
+ final int[] typesToSet = {ELAPSED_REALTIME_WAKEUP, ELAPSED_REALTIME, RTC_WAKEUP, RTC};
+ final int[] typesExpected = {ELAPSED_REALTIME, ELAPSED_REALTIME, ELAPSED_REALTIME,
+ ELAPSED_REALTIME};
+ assertAlarmTypeConversion(typesToSet, typesExpected);
+ }
+
+ private void assertAlarmTypeConversion(int[] typesToSet, int[] typesExpected) throws Exception {
+ for (int i = 0; i < typesToSet.length; i++) {
+ setTestAlarm(typesToSet[i], 1234, getNewMockPendingIntent());
+ final int typeSet = mTestTimer.getType();
+ assertEquals("Alarm of type " + typesToSet[i] + " was set to type " + typeSet,
+ typesExpected[i], typeSet);
+ mNowElapsedTest = mTestTimer.getElapsed();
+ mTestTimer.expire();
+ }
+ }
+
+ @Test
public void alarmCountOnInvalidSet() {
setTestAlarm(ELAPSED_REALTIME, mNowElapsedTest + 12345, null);
assertEquals(-1, mService.mAlarmsPerUid.get(TEST_CALLING_UID, -1));