From b3087c7f1fa50449ebc75c3712bd4a9dbc872c1d Mon Sep 17 00:00:00 2001 From: Lei Yu Date: Fri, 30 Mar 2018 13:59:38 -0700 Subject: [PATCH] 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 --- .../batterytip/AnomalyCleanupJobService.java | 9 +++++-- .../batterytip/AnomalyConfigJobService.java | 9 +++++-- .../AnomalyCleanupJobServiceTest.java | 27 +++++++++++++++++-- .../AnomalyConfigJobServiceTest.java | 24 ++++++++++++++--- 4 files changed, 60 insertions(+), 9 deletions(-) diff --git a/src/com/android/settings/fuelgauge/batterytip/AnomalyCleanupJobService.java b/src/com/android/settings/fuelgauge/batterytip/AnomalyCleanupJobService.java index 0c10d72802f..9e57433bcb7 100644 --- a/src/com/android/settings/fuelgauge/batterytip/AnomalyCleanupJobService.java +++ b/src/com/android/settings/fuelgauge/batterytip/AnomalyCleanupJobService.java @@ -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."); } } diff --git a/src/com/android/settings/fuelgauge/batterytip/AnomalyConfigJobService.java b/src/com/android/settings/fuelgauge/batterytip/AnomalyConfigJobService.java index 85865bba8f6..98eb23e3632 100644 --- a/src/com/android/settings/fuelgauge/batterytip/AnomalyConfigJobService.java +++ b/src/com/android/settings/fuelgauge/batterytip/AnomalyConfigJobService.java @@ -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."); } } diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/AnomalyCleanupJobServiceTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/AnomalyCleanupJobServiceTest.java index 98e4c57a683..a39276df44f 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/AnomalyCleanupJobServiceTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/AnomalyCleanupJobServiceTest.java @@ -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 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()); } } diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/AnomalyConfigJobServiceTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/AnomalyConfigJobServiceTest.java index 5ff2c70288b..90af7b17c2a 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/AnomalyConfigJobServiceTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/AnomalyConfigJobServiceTest.java @@ -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 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