From 338ae2fd71ffb289ef5b4660e18292e895ef8571 Mon Sep 17 00:00:00 2001 From: jackqdyulei Date: Fri, 16 Feb 2018 10:06:08 -0800 Subject: [PATCH] Add JobService to delete obsolete anomaly data Bug: 72385333 Test: RunSettingsRoboTests Change-Id: I73e16b9785fe0e832acc9e4256c8f9fd1333721e --- AndroidManifest.xml | 3 + res/values/ids.xml | 1 + .../batterytip/AnomalyCleanUpJobService.java | 75 +++++++++++++++++++ .../batterytip/AnomalyDetectionReceiver.java | 4 +- .../batterytip/BatteryTipPolicy.java | 11 ++- .../AnomalyCleanUpJobServiceTest.java | 63 ++++++++++++++++ .../batterytip/BatteryTipPolicyTest.java | 5 +- 7 files changed, 159 insertions(+), 3 deletions(-) create mode 100644 src/com/android/settings/fuelgauge/batterytip/AnomalyCleanUpJobService.java create mode 100644 tests/robotests/src/com/android/settings/fuelgauge/batterytip/AnomalyCleanUpJobServiceTest.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index c039041ecb4..9332ac86d3e 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -3306,6 +3306,9 @@ + + diff --git a/res/values/ids.xml b/res/values/ids.xml index 66af163e2b8..d5c9291f2fb 100644 --- a/res/values/ids.xml +++ b/res/values/ids.xml @@ -18,6 +18,7 @@ --> + diff --git a/src/com/android/settings/fuelgauge/batterytip/AnomalyCleanUpJobService.java b/src/com/android/settings/fuelgauge/batterytip/AnomalyCleanUpJobService.java new file mode 100644 index 00000000000..d5f4879f8a7 --- /dev/null +++ b/src/com/android/settings/fuelgauge/batterytip/AnomalyCleanUpJobService.java @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.fuelgauge.batterytip; + +import android.app.job.JobInfo; +import android.app.job.JobParameters; +import android.app.job.JobScheduler; +import android.app.job.JobService; +import android.content.ComponentName; +import android.content.Context; +import android.os.AsyncTask; +import android.support.annotation.VisibleForTesting; +import android.util.Log; + +import com.android.settings.R; +import com.android.settingslib.utils.ThreadUtils; + +import java.util.concurrent.TimeUnit; + +/** A JobService to clean up obsolete data in anomaly database */ +public class AnomalyCleanUpJobService extends JobService { + private static final String TAG = "AnomalyCleanUpJobService"; + + @VisibleForTesting + static final long CLEAN_UP_FREQUENCY_MS = TimeUnit.DAYS.toMillis(1); + + public static void scheduleCleanUp(Context context) { + final JobScheduler jobScheduler = context.getSystemService(JobScheduler.class); + + final ComponentName component = new ComponentName(context, AnomalyCleanUpJobService.class); + final JobInfo.Builder jobBuilder = + new JobInfo.Builder(R.id.job_anomaly_clean_up, component) + .setMinimumLatency(CLEAN_UP_FREQUENCY_MS) + .setRequiresDeviceIdle(true) + .setPersisted(true); + + if (jobScheduler.schedule(jobBuilder.build()) != JobScheduler.RESULT_SUCCESS) { + Log.i(TAG, "Anomaly clean up job service schedule failed."); + } + } + + @Override + public boolean onStartJob(JobParameters params) { + final BatteryDatabaseManager batteryDatabaseManager = BatteryDatabaseManager + .getInstance(this); + final BatteryTipPolicy policy = new BatteryTipPolicy(this); + ThreadUtils.postOnBackgroundThread(() -> { + batteryDatabaseManager.deleteAllAnomaliesBeforeTimeStamp( + System.currentTimeMillis() - TimeUnit.HOURS.toMillis( + policy.dataHistoryRetainHour)); + jobFinished(params, false /* wantsReschedule */); + }); + + return true; + } + + @Override + public boolean onStopJob(JobParameters jobParameters) { + return true; + } +} diff --git a/src/com/android/settings/fuelgauge/batterytip/AnomalyDetectionReceiver.java b/src/com/android/settings/fuelgauge/batterytip/AnomalyDetectionReceiver.java index 834a355bd98..88f399ffcd5 100644 --- a/src/com/android/settings/fuelgauge/batterytip/AnomalyDetectionReceiver.java +++ b/src/com/android/settings/fuelgauge/batterytip/AnomalyDetectionReceiver.java @@ -36,7 +36,7 @@ public class AnomalyDetectionReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { - final BatteryDatabaseManager databaseManager = new BatteryDatabaseManager(context); + final BatteryDatabaseManager databaseManager = BatteryDatabaseManager.getInstance(context); final BatteryUtils batteryUtils = BatteryUtils.getInstance(context); final long configUid = intent.getLongExtra(StatsManager.EXTRA_STATS_CONFIG_UID, -1); final long configKey = intent.getLongExtra(StatsManager.EXTRA_STATS_CONFIG_KEY, -1); @@ -46,6 +46,8 @@ public class AnomalyDetectionReceiver extends BroadcastReceiver { Log.i(TAG, "Anomaly intent received. configUid = " + configUid + " configKey = " + configKey + " subscriptionId = " + subscriptionId); saveAnomalyToDatabase(databaseManager, batteryUtils, intent); + + AnomalyCleanUpJobService.scheduleCleanUp(context); } @VisibleForTesting diff --git a/src/com/android/settings/fuelgauge/batterytip/BatteryTipPolicy.java b/src/com/android/settings/fuelgauge/batterytip/BatteryTipPolicy.java index a580db1d311..4a7b51d9ab0 100644 --- a/src/com/android/settings/fuelgauge/batterytip/BatteryTipPolicy.java +++ b/src/com/android/settings/fuelgauge/batterytip/BatteryTipPolicy.java @@ -19,7 +19,6 @@ package com.android.settings.fuelgauge.batterytip; import android.content.Context; import android.provider.Settings; import android.support.annotation.VisibleForTesting; -import android.text.format.DateUtils; import android.util.KeyValueListParser; import android.util.Log; @@ -44,6 +43,7 @@ public class BatteryTipPolicy { private static final String KEY_REDUCED_BATTERY_PERCENT = "reduced_battery_percent"; private static final String KEY_LOW_BATTERY_ENABLED = "low_battery_enabled"; private static final String KEY_LOW_BATTERY_HOUR = "low_battery_hour"; + private static final String KEY_DATA_HISTORY_RETAIN_HOUR = "data_history_retain_hour"; /** * {@code true} if general battery tip is enabled @@ -143,6 +143,14 @@ public class BatteryTipPolicy { */ public final int lowBatteryHour; + /** + * TTL hour for anomaly data stored in database + * + * @see Settings.Global#BATTERY_TIP_CONSTANTS + * @see #KEY_DATA_HISTORY_RETAIN_HOUR + */ + public final int dataHistoryRetainHour; + private final KeyValueListParser mParser; public BatteryTipPolicy(Context context) { @@ -174,6 +182,7 @@ public class BatteryTipPolicy { reducedBatteryPercent = mParser.getInt(KEY_REDUCED_BATTERY_PERCENT, 50); lowBatteryEnabled = mParser.getBoolean(KEY_LOW_BATTERY_ENABLED, false); lowBatteryHour = mParser.getInt(KEY_LOW_BATTERY_HOUR, 16); + dataHistoryRetainHour = mParser.getInt(KEY_DATA_HISTORY_RETAIN_HOUR, 72); } } diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/AnomalyCleanUpJobServiceTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/AnomalyCleanUpJobServiceTest.java new file mode 100644 index 00000000000..3da7bbd7be3 --- /dev/null +++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/AnomalyCleanUpJobServiceTest.java @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.fuelgauge.batterytip; + +import static com.google.common.truth.Truth.assertThat; + +import static org.junit.Assert.assertEquals; +import static org.robolectric.RuntimeEnvironment.application; + +import android.app.job.JobInfo; +import android.app.job.JobScheduler; + +import com.android.settings.R; +import com.android.settings.TestConfig; +import com.android.settings.testutils.SettingsRobolectricTestRunner; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.MockitoAnnotations; +import org.robolectric.Shadows; +import org.robolectric.annotation.Config; +import org.robolectric.shadows.ShadowJobScheduler; + +import java.util.List; +import java.util.concurrent.TimeUnit; + +@RunWith(SettingsRobolectricTestRunner.class) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) +public class AnomalyCleanUpJobServiceTest { + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + } + + @Test + public void testScheduleCleanUp() { + AnomalyCleanUpJobService.scheduleCleanUp(application); + + ShadowJobScheduler shadowJobScheduler = Shadows.shadowOf( + application.getSystemService(JobScheduler.class)); + List pendingJobs = shadowJobScheduler.getAllPendingJobs(); + assertEquals(1, pendingJobs.size()); + JobInfo pendingJob = pendingJobs.get(0); + assertThat(pendingJob.getId()).isEqualTo(R.id.job_anomaly_clean_up); + assertThat(pendingJob.getMinLatencyMillis()).isEqualTo(TimeUnit.DAYS.toMillis(1)); + assertThat(pendingJob.isRequireDeviceIdle()).isTrue(); + } +} diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipPolicyTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipPolicyTest.java index 78c86f8d3e6..f36acee209a 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipPolicyTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipPolicyTest.java @@ -49,7 +49,8 @@ public class BatteryTipPolicyTest { + ",reduced_battery_enabled=true" + ",reduced_battery_percent=30" + ",low_battery_enabled=false" - + ",low_battery_hour=10"; + + ",low_battery_hour=10" + + ",data_history_retain_hour=24"; private Context mContext; @Before @@ -76,6 +77,7 @@ public class BatteryTipPolicyTest { assertThat(batteryTipPolicy.reducedBatteryPercent).isEqualTo(30); assertThat(batteryTipPolicy.lowBatteryEnabled).isFalse(); assertThat(batteryTipPolicy.lowBatteryHour).isEqualTo(10); + assertThat(batteryTipPolicy.dataHistoryRetainHour).isEqualTo(24); } @Test @@ -97,6 +99,7 @@ public class BatteryTipPolicyTest { assertThat(batteryTipPolicy.reducedBatteryPercent).isEqualTo(50); assertThat(batteryTipPolicy.lowBatteryEnabled).isFalse(); assertThat(batteryTipPolicy.lowBatteryHour).isEqualTo(16); + assertThat(batteryTipPolicy.dataHistoryRetainHour).isEqualTo(72); } }