Extract checks for Doze support to separate class
This commit is contained in:
parent
754837d5ef
commit
949902a860
3 changed files with 61 additions and 79 deletions
|
@ -1,56 +1,48 @@
|
||||||
package com.fsck.k9.helper;
|
package com.fsck.k9.helper;
|
||||||
|
|
||||||
import android.annotation.TargetApi;
|
|
||||||
import android.app.AlarmManager;
|
import android.app.AlarmManager;
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.PowerManager;
|
import android.support.annotation.RequiresApi;
|
||||||
import android.support.annotation.VisibleForTesting;
|
import android.support.annotation.VisibleForTesting;
|
||||||
|
|
||||||
|
import com.fsck.k9.power.DozeChecker;
|
||||||
|
|
||||||
|
|
||||||
public class K9AlarmManager {
|
public class K9AlarmManager {
|
||||||
private final AlarmManager alarmManager;
|
private final AlarmManager alarmManager;
|
||||||
private final PowerManager powerManager;
|
private final DozeChecker dozeChecker;
|
||||||
private final String packageName;
|
|
||||||
|
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
K9AlarmManager(Context context) {
|
|
||||||
alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
|
|
||||||
powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
|
|
||||||
packageName = context.getPackageName();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static K9AlarmManager getAlarmManager(Context context) {
|
public static K9AlarmManager getAlarmManager(Context context) {
|
||||||
return new K9AlarmManager(context);
|
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
|
||||||
|
DozeChecker dozeChecker = new DozeChecker(context);
|
||||||
|
return new K9AlarmManager(alarmManager, dozeChecker);
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
K9AlarmManager(AlarmManager alarmManager, DozeChecker dozeChecker) {
|
||||||
|
this.alarmManager = alarmManager;
|
||||||
|
this.dozeChecker = dozeChecker;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void set(int type, long triggerAtMillis, PendingIntent operation) {
|
public void set(int type, long triggerAtMillis, PendingIntent operation) {
|
||||||
if (isDozeSupported() && isDozeWhiteListed()) {
|
if (dozeChecker.isDeviceIdleModeSupported() && dozeChecker.isAppWhitelisted()) {
|
||||||
setAndAllowWhileIdle(type, triggerAtMillis, operation);
|
setAndAllowWhileIdle(type, triggerAtMillis, operation);
|
||||||
} else {
|
} else {
|
||||||
alarmManager.set(type, triggerAtMillis, operation);
|
alarmManager.set(type, triggerAtMillis, operation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TargetApi(Build.VERSION_CODES.M)
|
@RequiresApi(Build.VERSION_CODES.M)
|
||||||
public void setAndAllowWhileIdle(int type, long triggerAtMillis, PendingIntent operation) {
|
private void setAndAllowWhileIdle(int type, long triggerAtMillis, PendingIntent operation) {
|
||||||
alarmManager.setAndAllowWhileIdle(type, triggerAtMillis, operation);
|
alarmManager.setAndAllowWhileIdle(type, triggerAtMillis, operation);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void cancel(PendingIntent operation) {
|
public void cancel(PendingIntent operation) {
|
||||||
alarmManager.cancel(operation);
|
alarmManager.cancel(operation);
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
protected boolean isDozeSupported() {
|
|
||||||
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M;
|
|
||||||
}
|
|
||||||
|
|
||||||
@TargetApi(Build.VERSION_CODES.M)
|
|
||||||
private boolean isDozeWhiteListed() {
|
|
||||||
return powerManager.isIgnoringBatteryOptimizations(packageName);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
28
k9mail/src/main/java/com/fsck/k9/power/DozeChecker.java
Normal file
28
k9mail/src/main/java/com/fsck/k9/power/DozeChecker.java
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
package com.fsck.k9.power;
|
||||||
|
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.os.PowerManager;
|
||||||
|
import android.support.annotation.RequiresApi;
|
||||||
|
|
||||||
|
|
||||||
|
public class DozeChecker {
|
||||||
|
private final PowerManager powerManager;
|
||||||
|
private final String packageName;
|
||||||
|
|
||||||
|
|
||||||
|
public DozeChecker(Context context) {
|
||||||
|
powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
|
||||||
|
packageName = context.getPackageName();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDeviceIdleModeSupported() {
|
||||||
|
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M;
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.M)
|
||||||
|
public boolean isAppWhitelisted() {
|
||||||
|
return powerManager.isIgnoringBatteryOptimizations(packageName);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,13 +1,10 @@
|
||||||
package com.fsck.k9.helper;
|
package com.fsck.k9.helper;
|
||||||
|
|
||||||
|
|
||||||
import android.annotation.TargetApi;
|
|
||||||
import android.app.AlarmManager;
|
import android.app.AlarmManager;
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.content.Context;
|
|
||||||
import android.os.Build.VERSION_CODES;
|
|
||||||
import android.os.PowerManager;
|
|
||||||
|
|
||||||
|
import com.fsck.k9.power.DozeChecker;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
|
@ -19,7 +16,6 @@ import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
|
||||||
public class K9AlarmManagerTest {
|
public class K9AlarmManagerTest {
|
||||||
private static final String PACKAGE_NAME = "org.example.package";
|
|
||||||
private static final int TIMER_TYPE = AlarmManager.RTC_WAKEUP;
|
private static final int TIMER_TYPE = AlarmManager.RTC_WAKEUP;
|
||||||
private static final long TIMEOUT = 15L * 60L * 1000L;
|
private static final long TIMEOUT = 15L * 60L * 1000L;
|
||||||
private static final PendingIntent PENDING_INTENT = createDummyPendingIntent();
|
private static final PendingIntent PENDING_INTENT = createDummyPendingIntent();
|
||||||
|
@ -27,16 +23,21 @@ public class K9AlarmManagerTest {
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private AlarmManager systemAlarmManager;
|
private AlarmManager systemAlarmManager;
|
||||||
|
@Mock
|
||||||
|
private DozeChecker dozeChecker;
|
||||||
|
|
||||||
|
private K9AlarmManager alarmManager;
|
||||||
|
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
|
alarmManager = new K9AlarmManager(systemAlarmManager, dozeChecker);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void set_withoutDozeSupport_shouldCallSetOnAlarmManager() throws Exception {
|
public void set_withoutDozeSupport_shouldCallSetOnAlarmManager() throws Exception {
|
||||||
K9AlarmManager alarmManager = createK9AlarmManagerWithoutDozeSupport();
|
configureDozeSupport(false);
|
||||||
|
|
||||||
alarmManager.set(TIMER_TYPE, TIMEOUT, PENDING_INTENT);
|
alarmManager.set(TIMER_TYPE, TIMEOUT, PENDING_INTENT);
|
||||||
|
|
||||||
|
@ -45,27 +46,27 @@ public class K9AlarmManagerTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void set_withDozeSupportAndNotWhiteListed_shouldCallSetOnAlarmManager() throws Exception {
|
public void set_withDozeSupportAndNotWhiteListed_shouldCallSetOnAlarmManager() throws Exception {
|
||||||
K9AlarmManager alarmManager = createK9AlarmManagerWithDozeSupport(false);
|
configureDozeSupport(true);
|
||||||
|
|
||||||
alarmManager.set(TIMER_TYPE, TIMEOUT, PENDING_INTENT);
|
alarmManager.set(TIMER_TYPE, TIMEOUT, PENDING_INTENT);
|
||||||
|
|
||||||
verify(systemAlarmManager).set(TIMER_TYPE, TIMEOUT, PENDING_INTENT);
|
verify(systemAlarmManager).set(TIMER_TYPE, TIMEOUT, PENDING_INTENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TargetApi(VERSION_CODES.M)
|
|
||||||
@Test
|
@Test
|
||||||
public void set_withDozeSupportAndWhiteListed_shouldCallSetAndAllowWhileIdleOnAlarmManager() throws Exception {
|
public void set_withDozeSupportAndWhiteListed_shouldCallSetAndAllowWhileIdleOnAlarmManager() throws Exception {
|
||||||
K9AlarmManager alarmManager = createK9AlarmManagerWithDozeSupport(true);
|
configureDozeSupport(true);
|
||||||
|
addAppToBatteryOptimizationWhitelist();
|
||||||
|
|
||||||
alarmManager.set(TIMER_TYPE, TIMEOUT, PENDING_INTENT);
|
alarmManager.set(TIMER_TYPE, TIMEOUT, PENDING_INTENT);
|
||||||
|
|
||||||
verify(systemAlarmManager).setAndAllowWhileIdle(TIMER_TYPE, TIMEOUT, PENDING_INTENT);
|
verify(systemAlarmManager).setAndAllowWhileIdle(TIMER_TYPE, TIMEOUT, PENDING_INTENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TargetApi(VERSION_CODES.M)
|
|
||||||
@Test
|
@Test
|
||||||
public void cancel_shouldCallCancelOnAlarmManager() throws Exception {
|
public void cancel_shouldCallCancelOnAlarmManager() throws Exception {
|
||||||
K9AlarmManager alarmManager = createK9AlarmManagerWithDozeSupport(true);
|
configureDozeSupport(true);
|
||||||
|
addAppToBatteryOptimizationWhitelist();
|
||||||
|
|
||||||
alarmManager.cancel(PENDING_INTENT);
|
alarmManager.cancel(PENDING_INTENT);
|
||||||
|
|
||||||
|
@ -73,54 +74,15 @@ public class K9AlarmManagerTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private K9AlarmManager createK9AlarmManagerWithDozeSupport(boolean whiteListed) {
|
private void configureDozeSupport(boolean supported) {
|
||||||
PowerManager powerManager = createPowerManager(whiteListed);
|
when(dozeChecker.isDeviceIdleModeSupported()).thenReturn(supported);
|
||||||
Context context = createContext(powerManager);
|
|
||||||
|
|
||||||
return new TestK9AlarmManager(context, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private K9AlarmManager createK9AlarmManagerWithoutDozeSupport() {
|
private void addAppToBatteryOptimizationWhitelist() {
|
||||||
PowerManager powerManager = mock(PowerManager.class);
|
when(dozeChecker.isAppWhitelisted()).thenReturn(true);
|
||||||
Context context = createContext(powerManager);
|
|
||||||
|
|
||||||
return new TestK9AlarmManager(context, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@TargetApi(VERSION_CODES.M)
|
|
||||||
private PowerManager createPowerManager(boolean whiteListed) {
|
|
||||||
PowerManager powerManager = mock(PowerManager.class);
|
|
||||||
when(powerManager.isIgnoringBatteryOptimizations(PACKAGE_NAME)).thenReturn(whiteListed);
|
|
||||||
|
|
||||||
return powerManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Context createContext(PowerManager powerManager) {
|
|
||||||
Context context = mock(Context.class);
|
|
||||||
when(context.getPackageName()).thenReturn(PACKAGE_NAME);
|
|
||||||
when(context.getSystemService(Context.ALARM_SERVICE)).thenReturn(systemAlarmManager);
|
|
||||||
when(context.getSystemService(Context.POWER_SERVICE)).thenReturn(powerManager);
|
|
||||||
|
|
||||||
return context;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static PendingIntent createDummyPendingIntent() {
|
private static PendingIntent createDummyPendingIntent() {
|
||||||
return mock(PendingIntent.class);
|
return mock(PendingIntent.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class TestK9AlarmManager extends K9AlarmManager {
|
|
||||||
private final boolean dozeSupported;
|
|
||||||
|
|
||||||
|
|
||||||
TestK9AlarmManager(Context context, boolean dozeSupported) {
|
|
||||||
super(context);
|
|
||||||
this.dozeSupported = dozeSupported;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean isDozeSupported() {
|
|
||||||
return dozeSupported;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue