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
This commit is contained in:
committed by
Suprabh Shukla
parent
442a4e7b16
commit
c32088c157
@@ -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) {
|
||||
@@ -1811,6 +1813,21 @@ class AlarmManagerService extends SystemService {
|
||||
return mConstants.APP_STANDBY_QUOTAS[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
||||
@@ -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);
|
||||
@@ -932,6 +950,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);
|
||||
|
||||
Reference in New Issue
Block a user