Make anomaly jobs persistent.

Before this cl, if user turn off device everday(i.e. OTA update), the
every day jobs may never have a chance to run.

This cl make the jobs persistent and don't reschedule it if we already
have one. In this way we can make sure the jobs roughly run everyday.

Bug: 77331929
Test: RunSettingsRoboTests
Change-Id: Ib497aca6b696afd9386515464845c5b0dd3c1207
This commit is contained in:
Lei Yu
2018-03-30 13:59:38 -07:00
parent d4482339d5
commit b3087c7f1f
4 changed files with 60 additions and 9 deletions

View File

@@ -45,9 +45,14 @@ public class AnomalyCleanupJobService extends JobService {
new JobInfo.Builder(R.integer.job_anomaly_clean_up, component)
.setPeriodic(CLEAN_UP_FREQUENCY_MS)
.setRequiresDeviceIdle(true)
.setRequiresCharging(true);
.setRequiresCharging(true)
.setPersisted(true);
final JobInfo pending = jobScheduler.getPendingJob(R.integer.job_anomaly_clean_up);
if (jobScheduler.schedule(jobBuilder.build()) != JobScheduler.RESULT_SUCCESS) {
// Don't schedule it if it already exists, to make sure it runs periodically even after
// reboot
if (pending == null && jobScheduler.schedule(jobBuilder.build())
!= JobScheduler.RESULT_SUCCESS) {
Log.i(TAG, "Anomaly clean up job service schedule failed.");
}
}

View File

@@ -55,9 +55,14 @@ public class AnomalyConfigJobService extends JobService {
new JobInfo.Builder(R.integer.job_anomaly_config_update, component)
.setPeriodic(CONFIG_UPDATE_FREQUENCY_MS)
.setRequiresDeviceIdle(true)
.setRequiresCharging(true);
.setRequiresCharging(true)
.setPersisted(true);
final JobInfo pending = jobScheduler.getPendingJob(R.integer.job_anomaly_config_update);
if (jobScheduler.schedule(jobBuilder.build()) != JobScheduler.RESULT_SUCCESS) {
// Don't schedule it if it already exists, to make sure it runs periodically even after
// reboot
if (pending == null && jobScheduler.schedule(jobBuilder.build())
!= JobScheduler.RESULT_SUCCESS) {
Log.i(TAG, "Anomaly config update job service schedule failed.");
}
}

View File

@@ -18,10 +18,16 @@ package com.android.settings.fuelgauge.batterytip;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertEquals;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.robolectric.RuntimeEnvironment.application;
import android.app.job.JobInfo;
import android.app.job.JobScheduler;
import android.content.Context;
import com.android.settings.R;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
@@ -30,6 +36,7 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.Shadows;
import org.robolectric.shadows.ShadowJobScheduler;
@@ -38,17 +45,24 @@ import java.util.concurrent.TimeUnit;
@RunWith(SettingsRobolectricTestRunner.class)
public class AnomalyCleanupJobServiceTest {
private Context mContext;
private JobScheduler mJobScheduler;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = spy(RuntimeEnvironment.application);
mJobScheduler = spy(mContext.getSystemService(JobScheduler.class));
when(mContext.getSystemService(JobScheduler.class)).thenReturn(mJobScheduler);
}
@Test
public void testScheduleCleanUp() {
AnomalyCleanupJobService.scheduleCleanUp(application);
AnomalyCleanupJobService.scheduleCleanUp(mContext);
ShadowJobScheduler shadowJobScheduler =
Shadows.shadowOf(application.getSystemService(JobScheduler.class));
Shadows.shadowOf(mContext.getSystemService(JobScheduler.class));
List<JobInfo> pendingJobs = shadowJobScheduler.getAllPendingJobs();
assertEquals(1, pendingJobs.size());
JobInfo pendingJob = pendingJobs.get(0);
@@ -56,5 +70,14 @@ public class AnomalyCleanupJobServiceTest {
assertThat(pendingJob.getIntervalMillis()).isEqualTo(TimeUnit.DAYS.toMillis(1));
assertThat(pendingJob.isRequireDeviceIdle()).isTrue();
assertThat(pendingJob.isRequireCharging()).isTrue();
assertThat(pendingJob.isPersisted()).isTrue();
}
@Test
public void testScheduleCleanUp_invokeTwice_onlyScheduleOnce() {
AnomalyCleanupJobService.scheduleCleanUp(mContext);
AnomalyCleanupJobService.scheduleCleanUp(mContext);
verify(mJobScheduler, times(1)).schedule(any());
}
}

View File

@@ -25,7 +25,9 @@ import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.robolectric.RuntimeEnvironment.application;
import android.app.StatsManager;
@@ -43,6 +45,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.Shadows;
import org.robolectric.shadows.ShadowJobScheduler;
@@ -57,12 +60,18 @@ public class AnomalyConfigJobServiceTest {
@Mock
private StatsManager mStatsManager;
private Context mContext;
private JobScheduler mJobScheduler;
private AnomalyConfigJobService mJobService;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = spy(RuntimeEnvironment.application);
mJobScheduler = spy(mContext.getSystemService(JobScheduler.class));
when(mContext.getSystemService(JobScheduler.class)).thenReturn(mJobScheduler);
mJobService = spy(new AnomalyConfigJobService());
doReturn(application.getSharedPreferences(AnomalyConfigJobService.PREF_DB,
Context.MODE_PRIVATE)).when(mJobService).getSharedPreferences(anyString(),
@@ -71,11 +80,11 @@ public class AnomalyConfigJobServiceTest {
}
@Test
public void testScheduleCleanUp() {
AnomalyConfigJobService.scheduleConfigUpdate(application);
public void testScheduleConfigUpdate() {
AnomalyConfigJobService.scheduleConfigUpdate(mContext);
ShadowJobScheduler shadowJobScheduler =
Shadows.shadowOf(application.getSystemService(JobScheduler.class));
Shadows.shadowOf(mContext.getSystemService(JobScheduler.class));
List<JobInfo> pendingJobs = shadowJobScheduler.getAllPendingJobs();
assertEquals(1, pendingJobs.size());
JobInfo pendingJob = pendingJobs.get(0);
@@ -83,6 +92,15 @@ public class AnomalyConfigJobServiceTest {
assertThat(pendingJob.getIntervalMillis()).isEqualTo(TimeUnit.DAYS.toMillis(1));
assertThat(pendingJob.isRequireDeviceIdle()).isTrue();
assertThat(pendingJob.isRequireCharging()).isTrue();
assertThat(pendingJob.isPersisted()).isTrue();
}
@Test
public void testScheduleConfigUpdate_invokeTwice_onlyScheduleOnce() {
AnomalyConfigJobService.scheduleConfigUpdate(mContext);
AnomalyConfigJobService.scheduleConfigUpdate(mContext);
verify(mJobScheduler, times(1)).schedule(any());
}
@Test