diff options
| author | 2019-02-20 16:50:26 -0800 | |
|---|---|---|
| committer | 2019-04-05 04:32:41 +0000 | |
| commit | c32088c1579a85fd5de455d5dde388e7f712b80a (patch) | |
| tree | a648930a5156641a6e4c44cb6f17cf3687c0c5c1 | |
| parent | 442a4e7b163fdb72fcd3ff4253a0d3e8511d1b7c (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.java | 25 | ||||
| -rw-r--r-- | services/tests/mockingservicestests/src/com/android/server/AlarmManagerServiceTest.java | 53 |
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)); |