From 821adcea1ef8987f484a05689aadc3feea6e3123 Mon Sep 17 00:00:00 2001 From: jackqdyulei Date: Mon, 29 Jan 2018 19:20:37 -0800 Subject: [PATCH 1/4] Add AnomalyDetectionReceiver This BroadcastReceiver is triggered when anomaly happens. Inside it we need to extract anomaly info and store it in the database. Bug: 72385333 Test: Will add robo test once robo framework is updated(b/73172999) Change-Id: Ib36af377fa2dff8026e7f0fcbec9575366e39cf9 --- AndroidManifest.xml | 5 ++ .../batterytip/AnomalyDetectionReceiver.java | 75 +++++++++++++++++++ .../batterytip/StatsManagerConfig.java | 28 +++++++ 3 files changed, 108 insertions(+) create mode 100644 src/com/android/settings/fuelgauge/batterytip/AnomalyDetectionReceiver.java create mode 100644 src/com/android/settings/fuelgauge/batterytip/StatsManagerConfig.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 19172141b7b..026b7ea9da9 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -3294,6 +3294,11 @@ + + + diff --git a/src/com/android/settings/fuelgauge/batterytip/AnomalyDetectionReceiver.java b/src/com/android/settings/fuelgauge/batterytip/AnomalyDetectionReceiver.java new file mode 100644 index 00000000000..10ef726e686 --- /dev/null +++ b/src/com/android/settings/fuelgauge/batterytip/AnomalyDetectionReceiver.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.StatsManager; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.os.StatsDimensionsValue; +import android.support.annotation.VisibleForTesting; +import android.util.Log; + +import com.android.settings.fuelgauge.BatteryUtils; + +import java.util.List; + +/** + * Receive the anomaly info from {@link StatsManager} + */ +public class AnomalyDetectionReceiver extends BroadcastReceiver { + private static final String TAG = "SettingsAnomalyReceiver"; + + @Override + public void onReceive(Context context, Intent intent) { + final BatteryDatabaseManager databaseManager = new BatteryDatabaseManager(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); + final long subscriptionId = intent.getLongExtra(StatsManager.EXTRA_STATS_SUBSCRIPTION_ID, + -1); + + Log.i(TAG, "Anomaly intent received. configUid = " + configUid + " configKey = " + + configKey + " subscriptionId = " + subscriptionId); + saveAnomalyToDatabase(databaseManager, batteryUtils, intent); + } + + @VisibleForTesting + void saveAnomalyToDatabase(BatteryDatabaseManager databaseManager, BatteryUtils batteryUtils + , Intent intent) { + // The Example of intentDimsValue is: 35:{1:{1:{1:10013|}|}|} + StatsDimensionsValue intentDimsValue = + intent.getParcelableExtra(StatsManager.EXTRA_STATS_DIMENSIONS_VALUE); + List intentTuple = intentDimsValue.getTupleValueList(); + + if (!intentTuple.isEmpty()) { + try { + // TODO(b/72385333): find more robust way to extract the uid. + final StatsDimensionsValue intentTupleValue = intentTuple.get(0) + .getTupleValueList().get(0).getTupleValueList().get(0); + final int uid = intentTupleValue.getIntValue(); + // TODD(b/72385333): extract anomaly type + final int anomalyType = 0; + final String packageName = batteryUtils.getPackageName(uid); + final long timeMs = System.currentTimeMillis(); + databaseManager.insertAnomaly(packageName, anomalyType, timeMs); + } catch (NullPointerException | IndexOutOfBoundsException e) { + Log.e(TAG, "Parse stats dimensions value error.", e); + } + } + } +} diff --git a/src/com/android/settings/fuelgauge/batterytip/StatsManagerConfig.java b/src/com/android/settings/fuelgauge/batterytip/StatsManagerConfig.java new file mode 100644 index 00000000000..2f0a6e49b55 --- /dev/null +++ b/src/com/android/settings/fuelgauge/batterytip/StatsManagerConfig.java @@ -0,0 +1,28 @@ +/* + * 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; + +/** + * This class provides all the configs needed if we want to use {@link android.app.StatsManager} + */ +public class StatsManagerConfig { + /** + * The key that represents the anomaly config. + * This value is used in {@link android.app.StatsManager#addConfiguration(long, byte[])} + */ + public static final long ANOMALY_CONFIG_KEY = 1; +} From e1604d3657fb3fd9143283ddaf33e01f46a727c0 Mon Sep 17 00:00:00 2001 From: jackqdyulei Date: Wed, 31 Jan 2018 20:24:47 -0800 Subject: [PATCH 2/4] Add AnomalyConfigReceiver This receiver receives the following intent: 1. android.app.action.STATSD_STARTED 2. android.intent.action.BOOT_COMPLETED Also it does: 1. Check whether to upload/update config(future cl) 2. Send PendingIntent to StatsManager Bug: 72385333 Test: Will add robo test once robo framework is updated(b/73172999) Change-Id: Iff7240663ecc1e080581683743b3027093945566 --- AndroidManifest.xml | 7 ++ .../batterytip/AnomalyConfigReceiver.java | 65 +++++++++++++++++++ .../batterytip/StatsManagerConfig.java | 5 ++ 3 files changed, 77 insertions(+) create mode 100644 src/com/android/settings/fuelgauge/batterytip/AnomalyConfigReceiver.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 026b7ea9da9..c039041ecb4 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -3299,6 +3299,13 @@ + + + + + + + diff --git a/src/com/android/settings/fuelgauge/batterytip/AnomalyConfigReceiver.java b/src/com/android/settings/fuelgauge/batterytip/AnomalyConfigReceiver.java new file mode 100644 index 00000000000..9d6f78d9e46 --- /dev/null +++ b/src/com/android/settings/fuelgauge/batterytip/AnomalyConfigReceiver.java @@ -0,0 +1,65 @@ +/* + * 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.PendingIntent; +import android.app.StatsManager; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.os.Process; +import android.os.StatsDimensionsValue; +import android.util.Log; + +import com.android.internal.annotations.VisibleForTesting; +import com.android.settings.fuelgauge.BatteryUtils; + +import java.util.List; + +/** + * Receive broadcast when {@link StatsManager} restart, then check the anomaly config and + * prepare info for {@link StatsManager} + */ +public class AnomalyConfigReceiver extends BroadcastReceiver { + private static final String TAG = "AnomalyConfigReceiver"; + private static final int REQUEST_CODE = 0; + + @Override + public void onReceive(Context context, Intent intent) { + if (StatsManager.ACTION_STATSD_STARTED.equals(intent.getAction()) + || Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) { + final StatsManager statsManager = context.getSystemService(StatsManager.class); + + //TODO(b/72385333): Check whether to update the config + final Intent extraIntent = new Intent(); + extraIntent.setClass(context, AnomalyDetectionReceiver.class); + final PendingIntent pendingIntent = PendingIntent.getBroadcast(context, REQUEST_CODE, + extraIntent, PendingIntent.FLAG_UPDATE_CURRENT); + + uploadPendingIntent(statsManager, pendingIntent); + } + } + + @VisibleForTesting + void uploadPendingIntent(StatsManager statsManager, PendingIntent pendingIntent) { + Log.i(TAG, "Upload PendingIntent to StatsManager. configKey: " + + StatsManagerConfig.ANOMALY_CONFIG_KEY + " subId: " + + StatsManagerConfig.SUBSCRIBER_ID); + statsManager.setBroadcastSubscriber(StatsManagerConfig.ANOMALY_CONFIG_KEY, + StatsManagerConfig.SUBSCRIBER_ID, pendingIntent); + } +} diff --git a/src/com/android/settings/fuelgauge/batterytip/StatsManagerConfig.java b/src/com/android/settings/fuelgauge/batterytip/StatsManagerConfig.java index 2f0a6e49b55..3b5e97dd0f9 100644 --- a/src/com/android/settings/fuelgauge/batterytip/StatsManagerConfig.java +++ b/src/com/android/settings/fuelgauge/batterytip/StatsManagerConfig.java @@ -25,4 +25,9 @@ public class StatsManagerConfig { * This value is used in {@link android.app.StatsManager#addConfiguration(long, byte[])} */ public static final long ANOMALY_CONFIG_KEY = 1; + + /** + * The key that represents subscriber, which is settings app. + */ + public static final long SUBSCRIBER_ID = 1; } From 10b7c0c39d3d586b37dee5ea56f809041b3caf1f Mon Sep 17 00:00:00 2001 From: jackqdyulei Date: Fri, 2 Feb 2018 10:29:40 -0800 Subject: [PATCH 3/4] Add code to handle anomaly config update Store a local version number in Settings. If new version comes, upload config to StatsManager. Bug: 72385333 Test: Will add robo test once robo framework is updated(b/73172999) Change-Id: I03f5ee6f6e013746397d39b8d2b52ce587825b11 --- .../batterytip/AnomalyConfigReceiver.java | 45 +++++++++++++++---- .../batterytip/AnomalyDetectionReceiver.java | 1 + 2 files changed, 38 insertions(+), 8 deletions(-) diff --git a/src/com/android/settings/fuelgauge/batterytip/AnomalyConfigReceiver.java b/src/com/android/settings/fuelgauge/batterytip/AnomalyConfigReceiver.java index 9d6f78d9e46..f658627b547 100644 --- a/src/com/android/settings/fuelgauge/batterytip/AnomalyConfigReceiver.java +++ b/src/com/android/settings/fuelgauge/batterytip/AnomalyConfigReceiver.java @@ -21,14 +21,12 @@ import android.app.StatsManager; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; -import android.os.Process; -import android.os.StatsDimensionsValue; +import android.content.SharedPreferences; +import android.provider.Settings; +import android.util.Base64; import android.util.Log; import com.android.internal.annotations.VisibleForTesting; -import com.android.settings.fuelgauge.BatteryUtils; - -import java.util.List; /** * Receive broadcast when {@link StatsManager} restart, then check the anomaly config and @@ -37,6 +35,9 @@ import java.util.List; public class AnomalyConfigReceiver extends BroadcastReceiver { private static final String TAG = "AnomalyConfigReceiver"; private static final int REQUEST_CODE = 0; + private static final String PREF_DB = "anomaly_pref"; + private static final String KEY_ANOMALY_CONFIG_VERSION = "anomaly_config_version"; + private static final int DEFAULT_VERSION = 0; @Override public void onReceive(Context context, Intent intent) { @@ -44,9 +45,11 @@ public class AnomalyConfigReceiver extends BroadcastReceiver { || Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) { final StatsManager statsManager = context.getSystemService(StatsManager.class); - //TODO(b/72385333): Check whether to update the config - final Intent extraIntent = new Intent(); - extraIntent.setClass(context, AnomalyDetectionReceiver.class); + // Check whether to update the config + checkAnomalyConfig(context, statsManager); + + // Upload PendingIntent to StatsManager + final Intent extraIntent = new Intent(context, AnomalyDetectionReceiver.class); final PendingIntent pendingIntent = PendingIntent.getBroadcast(context, REQUEST_CODE, extraIntent, PendingIntent.FLAG_UPDATE_CURRENT); @@ -62,4 +65,30 @@ public class AnomalyConfigReceiver extends BroadcastReceiver { statsManager.setBroadcastSubscriber(StatsManagerConfig.ANOMALY_CONFIG_KEY, StatsManagerConfig.SUBSCRIBER_ID, pendingIntent); } + + private void checkAnomalyConfig(Context context, StatsManager statsManager) { + final SharedPreferences sharedPreferences = context.getSharedPreferences(PREF_DB, + Context.MODE_PRIVATE); + final int currentVersion = sharedPreferences.getInt(KEY_ANOMALY_CONFIG_VERSION, + DEFAULT_VERSION); + final int newVersion = Settings.Global.getInt(context.getContentResolver(), + Settings.Global.ANOMALY_CONFIG_VERSION, DEFAULT_VERSION); + Log.i(TAG, "CurrentVersion: " + currentVersion + " new version: " + newVersion); + + if (newVersion > currentVersion) { + final byte[] config = Base64.decode( + Settings.Global.getString(context.getContentResolver(), + Settings.Global.ANOMALY_CONFIG), Base64.DEFAULT); + if (statsManager.addConfiguration(StatsManagerConfig.ANOMALY_CONFIG_KEY, config)) { + Log.i(TAG, "Upload the anomaly config. configKey: " + + StatsManagerConfig.ANOMALY_CONFIG_KEY); + SharedPreferences.Editor editor = sharedPreferences.edit(); + editor.putInt(KEY_ANOMALY_CONFIG_VERSION, newVersion); + editor.apply(); + } else { + Log.i(TAG, "Upload the anomaly config failed. configKey: " + + StatsManagerConfig.ANOMALY_CONFIG_KEY); + } + } + } } diff --git a/src/com/android/settings/fuelgauge/batterytip/AnomalyDetectionReceiver.java b/src/com/android/settings/fuelgauge/batterytip/AnomalyDetectionReceiver.java index 10ef726e686..834a355bd98 100644 --- a/src/com/android/settings/fuelgauge/batterytip/AnomalyDetectionReceiver.java +++ b/src/com/android/settings/fuelgauge/batterytip/AnomalyDetectionReceiver.java @@ -54,6 +54,7 @@ public class AnomalyDetectionReceiver extends BroadcastReceiver { // The Example of intentDimsValue is: 35:{1:{1:{1:10013|}|}|} StatsDimensionsValue intentDimsValue = intent.getParcelableExtra(StatsManager.EXTRA_STATS_DIMENSIONS_VALUE); + Log.i(TAG, "Extra stats value: " + intentDimsValue.toString()); List intentTuple = intentDimsValue.getTupleValueList(); if (!intentTuple.isEmpty()) { From 338ae2fd71ffb289ef5b4660e18292e895ef8571 Mon Sep 17 00:00:00 2001 From: jackqdyulei Date: Fri, 16 Feb 2018 10:06:08 -0800 Subject: [PATCH 4/4] 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); } }