diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 4230b6a37a7..2ba87d7099a 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -4692,20 +4692,6 @@ android:permission="android.permission.MANAGE_SLICE_PERMISSIONS" android:exported="true" /> - - - - - - - - - { - batteryDatabaseManager.deleteAllAnomaliesBeforeTimeStamp( - System.currentTimeMillis() - - TimeUnit.DAYS.toMillis(policy.dataHistoryRetainDay)); - jobFinished(params, false /* wantsReschedule */); - }); - - return true; - } - - @Override - public boolean onStopJob(JobParameters jobParameters) { - return false; - } -} diff --git a/src/com/android/settings/fuelgauge/batterytip/AnomalyConfigJobService.java b/src/com/android/settings/fuelgauge/batterytip/AnomalyConfigJobService.java deleted file mode 100644 index fe75c8e25a1..00000000000 --- a/src/com/android/settings/fuelgauge/batterytip/AnomalyConfigJobService.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * 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.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.content.SharedPreferences; -import android.provider.Settings; -import android.text.TextUtils; -import android.util.Base64; -import android.util.Log; - -import androidx.annotation.VisibleForTesting; - -import com.android.settings.R; -import com.android.settingslib.utils.ThreadUtils; - -import java.util.concurrent.TimeUnit; - -/** A JobService check whether to update the anomaly config periodically */ -public class AnomalyConfigJobService extends JobService { - private static final String TAG = "AnomalyConfigJobService"; - - public static final String PREF_DB = "anomaly_pref"; - public static final String KEY_ANOMALY_CONFIG_VERSION = "anomaly_config_version"; - private static final int DEFAULT_VERSION = 0; - - @VisibleForTesting static final long CONFIG_UPDATE_FREQUENCY_MS = TimeUnit.DAYS.toMillis(1); - - public static void scheduleConfigUpdate(Context context) { - final JobScheduler jobScheduler = context.getSystemService(JobScheduler.class); - - final ComponentName component = new ComponentName(context, AnomalyConfigJobService.class); - final JobInfo.Builder jobBuilder = - new JobInfo.Builder(R.integer.job_anomaly_config_update, component) - .setPeriodic(CONFIG_UPDATE_FREQUENCY_MS) - .setRequiresDeviceIdle(true) - .setRequiresCharging(true) - .setPersisted(true); - final JobInfo pending = jobScheduler.getPendingJob(R.integer.job_anomaly_config_update); - - // 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."); - } - } - - @Override - public boolean onStartJob(JobParameters params) { - ThreadUtils.postOnBackgroundThread( - () -> { - final StatsManager statsManager = getSystemService(StatsManager.class); - checkAnomalyConfig(statsManager); - try { - BatteryTipUtils.uploadAnomalyPendingIntent(this, statsManager); - } catch (StatsManager.StatsUnavailableException e) { - Log.w(TAG, "Failed to uploadAnomalyPendingIntent.", e); - } - jobFinished(params, false /* wantsReschedule */); - }); - - return true; - } - - @Override - public boolean onStopJob(JobParameters jobParameters) { - return false; - } - - @VisibleForTesting - synchronized void checkAnomalyConfig(StatsManager statsManager) { - final SharedPreferences sharedPreferences = - getSharedPreferences(PREF_DB, Context.MODE_PRIVATE); - final int currentVersion = - sharedPreferences.getInt(KEY_ANOMALY_CONFIG_VERSION, DEFAULT_VERSION); - final int newVersion = - Settings.Global.getInt( - getContentResolver(), - Settings.Global.ANOMALY_CONFIG_VERSION, - DEFAULT_VERSION); - final String rawConfig = - Settings.Global.getString(getContentResolver(), Settings.Global.ANOMALY_CONFIG); - Log.i(TAG, "CurrentVersion: " + currentVersion + " new version: " + newVersion); - - if (newVersion > currentVersion) { - try { - statsManager.removeConfig(StatsManagerConfig.ANOMALY_CONFIG_KEY); - } catch (StatsManager.StatsUnavailableException e) { - Log.i( - TAG, - "When updating anomaly config, failed to first remove the old config " - + StatsManagerConfig.ANOMALY_CONFIG_KEY, - e); - } - if (!TextUtils.isEmpty(rawConfig)) { - try { - final byte[] config = Base64.decode(rawConfig, Base64.DEFAULT); - statsManager.addConfig(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.commit(); - } catch (IllegalArgumentException e) { - Log.e(TAG, "Anomaly raw config is in wrong format", e); - } catch (StatsManager.StatsUnavailableException e) { - Log.i( - TAG, - "Upload of anomaly config failed for configKey " - + StatsManagerConfig.ANOMALY_CONFIG_KEY, - e); - } - } - } - } -} diff --git a/src/com/android/settings/fuelgauge/batterytip/AnomalyConfigReceiver.java b/src/com/android/settings/fuelgauge/batterytip/AnomalyConfigReceiver.java deleted file mode 100644 index 538b0478b8d..00000000000 --- a/src/com/android/settings/fuelgauge/batterytip/AnomalyConfigReceiver.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * 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.util.Log; - -/** - * 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"; - - @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); - - // Check whether to update the config - AnomalyConfigJobService.scheduleConfigUpdate(context); - - try { - BatteryTipUtils.uploadAnomalyPendingIntent(context, statsManager); - } catch (StatsManager.StatsUnavailableException e) { - Log.w(TAG, "Failed to uploadAnomalyPendingIntent.", e); - } - - if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) { - AnomalyCleanupJobService.scheduleCleanUp(context); - } - } - } -} diff --git a/src/com/android/settings/fuelgauge/batterytip/AnomalyDetectionJobService.java b/src/com/android/settings/fuelgauge/batterytip/AnomalyDetectionJobService.java deleted file mode 100644 index a80987ddb17..00000000000 --- a/src/com/android/settings/fuelgauge/batterytip/AnomalyDetectionJobService.java +++ /dev/null @@ -1,267 +0,0 @@ -/* - * 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 android.os.StatsDimensionsValue.INT_VALUE_TYPE; -import static android.os.StatsDimensionsValue.TUPLE_VALUE_TYPE; - -import android.app.AppOpsManager; -import android.app.StatsManager; -import android.app.job.JobInfo; -import android.app.job.JobParameters; -import android.app.job.JobScheduler; -import android.app.job.JobService; -import android.app.job.JobWorkItem; -import android.app.settings.SettingsEnums; -import android.content.ComponentName; -import android.content.ContentResolver; -import android.content.Context; -import android.content.Intent; -import android.os.Bundle; -import android.os.StatsDimensionsValue; -import android.os.UserManager; -import android.provider.Settings; -import android.util.Log; - -import androidx.annotation.GuardedBy; -import androidx.annotation.VisibleForTesting; - -import com.android.internal.util.ArrayUtils; -import com.android.settings.R; -import com.android.settings.fuelgauge.BatteryUtils; -import com.android.settings.fuelgauge.PowerUsageFeatureProvider; -import com.android.settings.overlay.FeatureFactory; -import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; -import com.android.settingslib.fuelgauge.PowerAllowlistBackend; -import com.android.settingslib.utils.ThreadUtils; - -import java.time.Duration; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.TimeUnit; - -/** A JobService to store anomaly data to anomaly database */ -public class AnomalyDetectionJobService extends JobService { - private static final String TAG = "AnomalyDetectionService"; - private static final int ON = 1; - @VisibleForTesting static final int UID_NULL = -1; - @VisibleForTesting static final int STATSD_UID_FILED = 1; - @VisibleForTesting static final long MAX_DELAY_MS = Duration.ofDays(1).toMillis(); - - private final Object mLock = new Object(); - - @GuardedBy("mLock") - @VisibleForTesting - boolean mIsJobCanceled = false; - - public static void scheduleAnomalyDetection(Context context, Intent intent) { - final JobScheduler jobScheduler = context.getSystemService(JobScheduler.class); - final ComponentName component = - new ComponentName(context, AnomalyDetectionJobService.class); - final JobInfo.Builder jobBuilder = - new JobInfo.Builder(R.integer.job_anomaly_detection, component) - .setOverrideDeadline(MAX_DELAY_MS); - - if (jobScheduler.enqueue(jobBuilder.build(), new JobWorkItem(intent)) - != JobScheduler.RESULT_SUCCESS) { - Log.i(TAG, "Anomaly detection job service enqueue failed."); - } - } - - @Override - public boolean onStartJob(JobParameters params) { - synchronized (mLock) { - mIsJobCanceled = false; - } - ThreadUtils.postOnBackgroundThread( - () -> { - final Context context = AnomalyDetectionJobService.this; - final BatteryDatabaseManager batteryDatabaseManager = - BatteryDatabaseManager.getInstance(this); - final BatteryTipPolicy policy = new BatteryTipPolicy(this); - final BatteryUtils batteryUtils = BatteryUtils.getInstance(this); - final ContentResolver contentResolver = getContentResolver(); - final UserManager userManager = getSystemService(UserManager.class); - final PowerAllowlistBackend powerAllowlistBackend = - PowerAllowlistBackend.getInstance(context); - final PowerUsageFeatureProvider powerUsageFeatureProvider = - FeatureFactory.getFeatureFactory().getPowerUsageFeatureProvider(); - final MetricsFeatureProvider metricsFeatureProvider = - FeatureFactory.getFeatureFactory().getMetricsFeatureProvider(); - - for (JobWorkItem item = dequeueWork(params); - item != null; - item = dequeueWork(params)) { - saveAnomalyToDatabase( - context, - userManager, - batteryDatabaseManager, - batteryUtils, - policy, - powerAllowlistBackend, - contentResolver, - powerUsageFeatureProvider, - metricsFeatureProvider, - item.getIntent().getExtras()); - - completeWork(params, item); - } - }); - - return true; - } - - @Override - public boolean onStopJob(JobParameters jobParameters) { - synchronized (mLock) { - mIsJobCanceled = true; - } - return true; // Need to reschedule - } - - @VisibleForTesting - void saveAnomalyToDatabase( - Context context, - UserManager userManager, - BatteryDatabaseManager databaseManager, - BatteryUtils batteryUtils, - BatteryTipPolicy policy, - PowerAllowlistBackend powerAllowlistBackend, - ContentResolver contentResolver, - PowerUsageFeatureProvider powerUsageFeatureProvider, - MetricsFeatureProvider metricsFeatureProvider, - Bundle bundle) { - // The Example of intentDimsValue is: 35:{1:{1:{1:10013|}|}|} - final StatsDimensionsValue intentDimsValue = - bundle.getParcelable(StatsManager.EXTRA_STATS_DIMENSIONS_VALUE); - final long timeMs = - bundle.getLong( - AnomalyDetectionReceiver.KEY_ANOMALY_TIMESTAMP, System.currentTimeMillis()); - final ArrayList cookies = - bundle.getStringArrayList(StatsManager.EXTRA_STATS_BROADCAST_SUBSCRIBER_COOKIES); - final AnomalyInfo anomalyInfo = - new AnomalyInfo(!ArrayUtils.isEmpty(cookies) ? cookies.get(0) : ""); - Log.i(TAG, "Extra stats value: " + intentDimsValue.toString()); - - try { - final int uid = extractUidFromStatsDimensionsValue(intentDimsValue); - final boolean autoFeatureOn = - powerUsageFeatureProvider.isSmartBatterySupported() - ? Settings.Global.getInt( - contentResolver, - Settings.Global.ADAPTIVE_BATTERY_MANAGEMENT_ENABLED, - ON) - == ON - : Settings.Global.getInt( - contentResolver, - Settings.Global.APP_AUTO_RESTRICTION_ENABLED, - ON) - == ON; - final String packageName = batteryUtils.getPackageName(uid); - final long versionCode = batteryUtils.getAppLongVersionCode(packageName); - final String versionedPackage = packageName + "/" + versionCode; - if (batteryUtils.shouldHideAnomaly(powerAllowlistBackend, uid, anomalyInfo)) { - metricsFeatureProvider.action( - SettingsEnums.PAGE_UNKNOWN, - SettingsEnums.ACTION_ANOMALY_IGNORED, - SettingsEnums.PAGE_UNKNOWN, - versionedPackage, - anomalyInfo.anomalyType); - } else { - if (autoFeatureOn && anomalyInfo.autoRestriction) { - // Auto restrict this app - batteryUtils.setForceAppStandby(uid, packageName, AppOpsManager.MODE_IGNORED); - databaseManager.insertAnomaly( - uid, - packageName, - anomalyInfo.anomalyType, - AnomalyDatabaseHelper.State.AUTO_HANDLED, - timeMs); - } else { - databaseManager.insertAnomaly( - uid, - packageName, - anomalyInfo.anomalyType, - AnomalyDatabaseHelper.State.NEW, - timeMs); - } - metricsFeatureProvider.action( - SettingsEnums.PAGE_UNKNOWN, - SettingsEnums.ACTION_ANOMALY_TRIGGERED, - SettingsEnums.PAGE_UNKNOWN, - versionedPackage, - anomalyInfo.anomalyType); - } - - } catch (NullPointerException | IndexOutOfBoundsException e) { - Log.e(TAG, "Parse stats dimensions value error.", e); - } - } - - /** - * Extract the uid from {@link StatsDimensionsValue}
- *
- * The uid dimension has the format: {1:int} inside the tuple list. Here are some examples:
- * 1.Excessive bg anomaly: 27:{1:10089|}
- * 2.Wakeup alarm anomaly: 35:{1:{1:{1:10013|}|}|}
- * 3.Bluetooth anomaly: 3:{1:{1:{1:10140|}|}|} - */ - @VisibleForTesting - int extractUidFromStatsDimensionsValue(StatsDimensionsValue statsDimensionsValue) { - if (statsDimensionsValue == null) { - return UID_NULL; - } - if (statsDimensionsValue.isValueType(INT_VALUE_TYPE) - && statsDimensionsValue.getField() == STATSD_UID_FILED) { - // Find out the real uid - return statsDimensionsValue.getIntValue(); - } - if (statsDimensionsValue.isValueType(TUPLE_VALUE_TYPE)) { - final List values = statsDimensionsValue.getTupleValueList(); - for (int i = 0, size = values.size(); i < size; i++) { - int uid = extractUidFromStatsDimensionsValue(values.get(i)); - if (uid != UID_NULL) { - return uid; - } - } - } - - return UID_NULL; - } - - @VisibleForTesting - JobWorkItem dequeueWork(JobParameters parameters) { - synchronized (mLock) { - if (mIsJobCanceled) { - return null; - } - - return parameters.dequeueWork(); - } - } - - @VisibleForTesting - void completeWork(JobParameters parameters, JobWorkItem item) { - synchronized (mLock) { - if (mIsJobCanceled) { - return; - } - - parameters.completeWork(item); - } - } -} diff --git a/src/com/android/settings/fuelgauge/batterytip/AnomalyDetectionReceiver.java b/src/com/android/settings/fuelgauge/batterytip/AnomalyDetectionReceiver.java deleted file mode 100644 index 0d43addfaa9..00000000000 --- a/src/com/android/settings/fuelgauge/batterytip/AnomalyDetectionReceiver.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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.Bundle; -import android.util.Log; - -/** Receive the anomaly info from {@link StatsManager} */ -public class AnomalyDetectionReceiver extends BroadcastReceiver { - private static final String TAG = "SettingsAnomalyReceiver"; - - public static final String KEY_ANOMALY_TIMESTAMP = "key_anomaly_timestamp"; - - @Override - public void onReceive(Context context, Intent intent) { - 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); - - final Bundle bundle = intent.getExtras(); - if (bundle == null) { - return; - } - bundle.putLong(KEY_ANOMALY_TIMESTAMP, System.currentTimeMillis()); - - AnomalyDetectionJobService.scheduleAnomalyDetection(context, intent); - } -} diff --git a/src/com/android/settings/fuelgauge/batterytip/BatteryTipUtils.java b/src/com/android/settings/fuelgauge/batterytip/BatteryTipUtils.java index d65bd269413..7dc993c3b96 100644 --- a/src/com/android/settings/fuelgauge/batterytip/BatteryTipUtils.java +++ b/src/com/android/settings/fuelgauge/batterytip/BatteryTipUtils.java @@ -17,8 +17,6 @@ package com.android.settings.fuelgauge.batterytip; import android.app.AppOpsManager; -import android.app.PendingIntent; -import android.app.StatsManager; import android.content.Context; import android.content.Intent; import android.os.UserHandle; @@ -111,36 +109,8 @@ public class BatteryTipUtils { } } - /** - * Upload the {@link PendingIntent} to {@link StatsManager} for anomaly detection - * - * @throws StatsManager.StatsUnavailableException if failed to communicate with stats service - */ - public static void uploadAnomalyPendingIntent(Context context, StatsManager statsManager) - throws StatsManager.StatsUnavailableException { - final Intent extraIntent = new Intent(context, AnomalyDetectionReceiver.class); - final PendingIntent pendingIntent = - PendingIntent.getBroadcast( - context, - REQUEST_CODE, - extraIntent, - PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE); - statsManager.setBroadcastSubscriber( - pendingIntent, - StatsManagerConfig.ANOMALY_CONFIG_KEY, - StatsManagerConfig.SUBSCRIBER_ID); - } - - /** Detect and return anomaly apps after {@code timeAfterMs} */ + /** Detect and return anomaly apps after {@code timeAfterMs} */ public static List detectAnomalies(Context context, long timeAfterMs) { - final List highUsageApps = - BatteryDatabaseManager.getInstance(context) - .queryAllAnomalies(timeAfterMs, AnomalyDatabaseHelper.State.NEW); - // Remove it if it doesn't have label or been restricted - highUsageApps.removeIf( - AppLabelPredicate.getInstance(context) - .or(AppRestrictionPredicate.getInstance(context))); - - return highUsageApps; + return new ArrayList<>(); } } diff --git a/tests/robotests/src/com/android/settings/SettingsDumpServiceTest.java b/tests/robotests/src/com/android/settings/SettingsDumpServiceTest.java index 9d8841fb55a..e44d528ada5 100644 --- a/tests/robotests/src/com/android/settings/SettingsDumpServiceTest.java +++ b/tests/robotests/src/com/android/settings/SettingsDumpServiceTest.java @@ -29,10 +29,6 @@ import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; -import com.android.settings.fuelgauge.batterytip.AnomalyConfigJobService; - -import org.json.JSONException; -import org.json.JSONObject; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -83,22 +79,6 @@ public class SettingsDumpServiceTest { assertThat(mTestService.dumpDefaultBrowser()).isEqualTo(null); } - @Test - public void testDumpAnomalyDetection_returnAnomalyInfo() throws JSONException { - final SharedPreferences sharedPreferences = - RuntimeEnvironment.application.getSharedPreferences(AnomalyConfigJobService.PREF_DB, - Context.MODE_PRIVATE); - SharedPreferences.Editor editor = sharedPreferences.edit(); - editor.putInt(AnomalyConfigJobService.KEY_ANOMALY_CONFIG_VERSION, ANOMALY_VERSION); - editor.commit(); - doReturn(sharedPreferences).when(mTestService).getSharedPreferences(anyString(), anyInt()); - - final JSONObject jsonObject = mTestService.dumpAnomalyDetection(); - - assertThat(jsonObject.getInt(AnomalyConfigJobService.KEY_ANOMALY_CONFIG_VERSION)).isEqualTo( - ANOMALY_VERSION); - } - @Test public void testDump_printServiceAsKey() { mResolveInfo.activityInfo = new ActivityInfo(); diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/AnomalyCleanupJobServiceTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/AnomalyCleanupJobServiceTest.java deleted file mode 100644 index 22c59b058ce..00000000000 --- a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/AnomalyCleanupJobServiceTest.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * 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.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyBoolean; -import static org.mockito.Mockito.doNothing; -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 android.app.JobSchedulerImpl; -import android.app.job.IJobScheduler; -import android.app.job.JobInfo; -import android.app.job.JobParameters; -import android.app.job.JobScheduler; -import android.content.Context; -import android.os.Binder; - -import com.android.settings.R; -import com.android.settings.testutils.DatabaseTestUtils; - -import org.junit.After; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.robolectric.Robolectric; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; - -import java.util.List; -import java.util.concurrent.TimeUnit; - -@RunWith(RobolectricTestRunner.class) -public class AnomalyCleanupJobServiceTest { - private static final int UID = 1234; - private static final String PACKAGE_NAME = "com.android.package"; - private static final String PACKAGE_NAME_OLD = "com.android.package.old"; - private static final int ANOMALY_TYPE = 1; - private static final long TIMESTAMP_NOW = System.currentTimeMillis(); - private static final long TIMESTAMP_31_DAYS_BEFORE = TIMESTAMP_NOW - TimeUnit.DAYS.toMillis(31); - - private Context mContext; - private JobScheduler mJobScheduler; - @Mock private JobParameters mParams; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - - mContext = spy(RuntimeEnvironment.application); - mJobScheduler = - spy(new JobSchedulerImpl(mContext, IJobScheduler.Stub.asInterface(new Binder()))); - when(mContext.getSystemService(JobScheduler.class)).thenReturn(mJobScheduler); - } - - @After - public void cleanUp() { - DatabaseTestUtils.clearDb(mContext); - } - - @Test - public void scheduleCleanUp() { - AnomalyCleanupJobService.scheduleCleanUp(mContext); - - JobScheduler jobScheduler = mContext.getSystemService(JobScheduler.class); - List pendingJobs = jobScheduler.getAllPendingJobs(); - assertEquals(1, pendingJobs.size()); - JobInfo pendingJob = pendingJobs.get(0); - assertThat(pendingJob.getId()).isEqualTo(R.integer.job_anomaly_clean_up); - assertThat(pendingJob.getIntervalMillis()).isEqualTo(TimeUnit.DAYS.toMillis(1)); - assertThat(pendingJob.isRequireDeviceIdle()).isTrue(); - assertThat(pendingJob.isRequireCharging()).isTrue(); - assertThat(pendingJob.isPersisted()).isTrue(); - } - - @Test - public void scheduleCleanUp_invokeTwice_onlyScheduleOnce() { - AnomalyCleanupJobService.scheduleCleanUp(mContext); - AnomalyCleanupJobService.scheduleCleanUp(mContext); - - verify(mJobScheduler, times(1)).schedule(any()); - } - - @Test - @Ignore - public void onStartJob_cleanUpDataBefore30days() { - final BatteryDatabaseManager databaseManager = BatteryDatabaseManager.getInstance(mContext); - final AnomalyCleanupJobService service = - spy(Robolectric.setupService(AnomalyCleanupJobService.class)); - doNothing().when(service).jobFinished(any(), anyBoolean()); - - // Insert two records, one is current and the other one is 31 days before - databaseManager.insertAnomaly( - UID, PACKAGE_NAME, ANOMALY_TYPE, AnomalyDatabaseHelper.State.NEW, TIMESTAMP_NOW); - databaseManager.insertAnomaly( - UID, - PACKAGE_NAME_OLD, - ANOMALY_TYPE, - AnomalyDatabaseHelper.State.NEW, - TIMESTAMP_31_DAYS_BEFORE); - - service.onStartJob(mParams); - - // In database, it only contains the current record - final List appInfos = - databaseManager.queryAllAnomalies(0, AnomalyDatabaseHelper.State.NEW); - assertThat(appInfos) - .containsExactly( - new AppInfo.Builder() - .setUid(UID) - .setPackageName(PACKAGE_NAME) - .addAnomalyType(ANOMALY_TYPE) - .build()); - } -} diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/AnomalyConfigJobServiceTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/AnomalyConfigJobServiceTest.java deleted file mode 100644 index 345b8a1d7c9..00000000000 --- a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/AnomalyConfigJobServiceTest.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * 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.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.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.JobSchedulerImpl; -import android.app.StatsManager; -import android.app.job.IJobScheduler; -import android.app.job.JobInfo; -import android.app.job.JobScheduler; -import android.content.Context; -import android.os.Binder; -import android.provider.Settings; - -import com.android.settings.R; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; - -import java.util.List; -import java.util.concurrent.TimeUnit; - -@RunWith(RobolectricTestRunner.class) -public class AnomalyConfigJobServiceTest { - - private static final int ANOMALY_CONFIG_VERSION = 1; - private static final String ANOMALY_CONFIG = "X64s"; - @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(new JobSchedulerImpl(mContext, IJobScheduler.Stub.asInterface(new Binder()))); - when(mContext.getSystemService(JobScheduler.class)).thenReturn(mJobScheduler); - - mJobService = spy(new AnomalyConfigJobService()); - doReturn( - application.getSharedPreferences( - AnomalyConfigJobService.PREF_DB, Context.MODE_PRIVATE)) - .when(mJobService) - .getSharedPreferences(anyString(), anyInt()); - doReturn(application.getContentResolver()).when(mJobService).getContentResolver(); - } - - @Test - public void testScheduleConfigUpdate() { - AnomalyConfigJobService.scheduleConfigUpdate(mContext); - - JobScheduler jobScheduler = mContext.getSystemService(JobScheduler.class); - List pendingJobs = jobScheduler.getAllPendingJobs(); - assertEquals(1, pendingJobs.size()); - JobInfo pendingJob = pendingJobs.get(0); - assertThat(pendingJob.getId()).isEqualTo(R.integer.job_anomaly_config_update); - 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 - public void checkAnomalyConfig_newConfigExist_removeOldConfig() - throws StatsManager.StatsUnavailableException { - Settings.Global.putInt( - application.getContentResolver(), - Settings.Global.ANOMALY_CONFIG_VERSION, - ANOMALY_CONFIG_VERSION); - Settings.Global.putString( - application.getContentResolver(), Settings.Global.ANOMALY_CONFIG, ANOMALY_CONFIG); - - mJobService.checkAnomalyConfig(mStatsManager); - - verify(mStatsManager).removeConfig(StatsManagerConfig.ANOMALY_CONFIG_KEY); - } - - @Test - public void checkAnomalyConfig_newConfigExist_uploadNewConfig() - throws StatsManager.StatsUnavailableException { - Settings.Global.putInt( - application.getContentResolver(), - Settings.Global.ANOMALY_CONFIG_VERSION, - ANOMALY_CONFIG_VERSION); - Settings.Global.putString( - application.getContentResolver(), Settings.Global.ANOMALY_CONFIG, ANOMALY_CONFIG); - - mJobService.checkAnomalyConfig(mStatsManager); - - verify(mStatsManager).addConfig(eq(StatsManagerConfig.ANOMALY_CONFIG_KEY), any()); - } -} diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/AnomalyDetectionJobServiceTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/AnomalyDetectionJobServiceTest.java deleted file mode 100644 index 482f0d0ce02..00000000000 --- a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/AnomalyDetectionJobServiceTest.java +++ /dev/null @@ -1,378 +0,0 @@ -/* - * 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 android.os.StatsDimensionsValue.FLOAT_VALUE_TYPE; -import static android.os.StatsDimensionsValue.INT_VALUE_TYPE; -import static android.os.StatsDimensionsValue.TUPLE_VALUE_TYPE; - -import static com.google.common.truth.Truth.assertThat; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyBoolean; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.anyLong; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.app.JobSchedulerImpl; -import android.app.StatsManager; -import android.app.job.IJobScheduler; -import android.app.job.JobInfo; -import android.app.job.JobParameters; -import android.app.job.JobScheduler; -import android.app.job.JobWorkItem; -import android.app.settings.SettingsEnums; -import android.content.Context; -import android.content.Intent; -import android.os.Binder; -import android.os.Bundle; -import android.os.Process; -import android.os.StatsDimensionsValue; -import android.os.UserManager; - -import com.android.internal.logging.nano.MetricsProto; -import com.android.settings.R; -import com.android.settings.fuelgauge.BatteryUtils; -import com.android.settings.testutils.FakeFeatureFactory; -import com.android.settings.testutils.shadow.ShadowConnectivityManager; -import com.android.settingslib.fuelgauge.PowerAllowlistBackend; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.robolectric.Robolectric; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; -import org.robolectric.android.controller.ServiceController; -import org.robolectric.annotation.Config; - -import java.time.Duration; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.TimeUnit; - -@RunWith(RobolectricTestRunner.class) -@Config(shadows = {ShadowConnectivityManager.class}) -public class AnomalyDetectionJobServiceTest { - private static final int UID = 12345; - private static final String SYSTEM_PACKAGE = "com.android.system"; - private static final String SUBSCRIBER_COOKIES_AUTO_RESTRICTION = - "anomaly_type=6,auto_restriction=true"; - private static final String SUBSCRIBER_COOKIES_NOT_AUTO_RESTRICTION = - "anomaly_type=6,auto_restriction=false"; - private static final int ANOMALY_TYPE = 6; - private static final long VERSION_CODE = 15; - @Mock private UserManager mUserManager; - @Mock private BatteryDatabaseManager mBatteryDatabaseManager; - @Mock private BatteryUtils mBatteryUtils; - @Mock private PowerAllowlistBackend mPowerAllowlistBackend; - @Mock private StatsDimensionsValue mStatsDimensionsValue; - @Mock private JobParameters mJobParameters; - @Mock private JobWorkItem mJobWorkItem; - - private BatteryTipPolicy mPolicy; - private Bundle mBundle; - private AnomalyDetectionJobService mAnomalyDetectionJobService; - private FakeFeatureFactory mFeatureFactory; - private Context mContext; - private JobScheduler mJobScheduler; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - - mContext = spy(RuntimeEnvironment.application); - mJobScheduler = - spy(new JobSchedulerImpl(mContext, IJobScheduler.Stub.asInterface(new Binder()))); - when(mContext.getSystemService(JobScheduler.class)).thenReturn(mJobScheduler); - - mPolicy = new BatteryTipPolicy(mContext); - mBundle = new Bundle(); - mBundle.putParcelable(StatsManager.EXTRA_STATS_DIMENSIONS_VALUE, mStatsDimensionsValue); - mFeatureFactory = FakeFeatureFactory.setupForTest(); - when(mBatteryUtils.getAppLongVersionCode(any())).thenReturn(VERSION_CODE); - - final ServiceController controller = - Robolectric.buildService(AnomalyDetectionJobService.class); - mAnomalyDetectionJobService = spy(controller.get()); - doNothing().when(mAnomalyDetectionJobService).jobFinished(any(), anyBoolean()); - } - - @Test - public void scheduleCleanUp() { - AnomalyDetectionJobService.scheduleAnomalyDetection(mContext, new Intent()); - - JobScheduler jobScheduler = mContext.getSystemService(JobScheduler.class); - List pendingJobs = jobScheduler.getAllPendingJobs(); - assertThat(pendingJobs).hasSize(1); - - JobInfo pendingJob = pendingJobs.get(0); - assertThat(pendingJob.getId()).isEqualTo(R.integer.job_anomaly_detection); - assertThat(pendingJob.getMaxExecutionDelayMillis()) - .isEqualTo(Duration.ofDays(1).toMillis()); - } - - @Test - public void saveAnomalyToDatabase_systemAllowlisted_doNotSave() { - doReturn(UID).when(mAnomalyDetectionJobService).extractUidFromStatsDimensionsValue(any()); - doReturn(true) - .when(mPowerAllowlistBackend) - .isAllowlisted(any(String[].class), any(Integer.class)); - - mAnomalyDetectionJobService.saveAnomalyToDatabase( - mContext, - mUserManager, - mBatteryDatabaseManager, - mBatteryUtils, - mPolicy, - mPowerAllowlistBackend, - mContext.getContentResolver(), - mFeatureFactory.powerUsageFeatureProvider, - mFeatureFactory.metricsFeatureProvider, - mBundle); - - verify(mBatteryDatabaseManager, never()) - .insertAnomaly(anyInt(), anyString(), anyInt(), anyInt(), anyLong()); - } - - @Test - public void saveAnomalyToDatabase_systemApp_doNotSaveButLog() { - final ArrayList cookies = new ArrayList<>(); - cookies.add(SUBSCRIBER_COOKIES_AUTO_RESTRICTION); - mBundle.putStringArrayList(StatsManager.EXTRA_STATS_BROADCAST_SUBSCRIBER_COOKIES, cookies); - doReturn(SYSTEM_PACKAGE).when(mBatteryUtils).getPackageName(anyInt()); - doReturn(false).when(mPowerAllowlistBackend).isSysAllowlisted(SYSTEM_PACKAGE); - doReturn(Process.FIRST_APPLICATION_UID) - .when(mAnomalyDetectionJobService) - .extractUidFromStatsDimensionsValue(any()); - doReturn(true).when(mBatteryUtils).shouldHideAnomaly(any(), anyInt(), any()); - - mAnomalyDetectionJobService.saveAnomalyToDatabase( - mContext, - mUserManager, - mBatteryDatabaseManager, - mBatteryUtils, - mPolicy, - mPowerAllowlistBackend, - mContext.getContentResolver(), - mFeatureFactory.powerUsageFeatureProvider, - mFeatureFactory.metricsFeatureProvider, - mBundle); - - verify(mBatteryDatabaseManager, never()) - .insertAnomaly(anyInt(), anyString(), anyInt(), anyInt(), anyLong()); - verify(mFeatureFactory.metricsFeatureProvider) - .action( - SettingsEnums.PAGE_UNKNOWN, - MetricsProto.MetricsEvent.ACTION_ANOMALY_IGNORED, - SettingsEnums.PAGE_UNKNOWN, - SYSTEM_PACKAGE + "/" + VERSION_CODE, - ANOMALY_TYPE); - } - - @Test - public void saveAnomalyToDatabase_systemUid_doNotSave() { - doReturn(Process.SYSTEM_UID) - .when(mAnomalyDetectionJobService) - .extractUidFromStatsDimensionsValue(any()); - - mAnomalyDetectionJobService.saveAnomalyToDatabase( - mContext, - mUserManager, - mBatteryDatabaseManager, - mBatteryUtils, - mPolicy, - mPowerAllowlistBackend, - mContext.getContentResolver(), - mFeatureFactory.powerUsageFeatureProvider, - mFeatureFactory.metricsFeatureProvider, - mBundle); - - verify(mBatteryDatabaseManager, never()) - .insertAnomaly(anyInt(), anyString(), anyInt(), anyInt(), anyLong()); - } - - @Test - public void saveAnomalyToDatabase_uidNull_doNotSave() { - doReturn(AnomalyDetectionJobService.UID_NULL) - .when(mAnomalyDetectionJobService) - .extractUidFromStatsDimensionsValue(any()); - - mAnomalyDetectionJobService.saveAnomalyToDatabase( - mContext, - mUserManager, - mBatteryDatabaseManager, - mBatteryUtils, - mPolicy, - mPowerAllowlistBackend, - mContext.getContentResolver(), - mFeatureFactory.powerUsageFeatureProvider, - mFeatureFactory.metricsFeatureProvider, - mBundle); - - verify(mBatteryDatabaseManager, never()) - .insertAnomaly(anyInt(), anyString(), anyInt(), anyInt(), anyLong()); - } - - @Test - public void saveAnomalyToDatabase_normalAppWithAutoRestriction_save() { - final ArrayList cookies = new ArrayList<>(); - cookies.add(SUBSCRIBER_COOKIES_AUTO_RESTRICTION); - mBundle.putStringArrayList(StatsManager.EXTRA_STATS_BROADCAST_SUBSCRIBER_COOKIES, cookies); - doReturn(SYSTEM_PACKAGE).when(mBatteryUtils).getPackageName(anyInt()); - doReturn(false).when(mPowerAllowlistBackend).isSysAllowlisted(SYSTEM_PACKAGE); - doReturn(Process.FIRST_APPLICATION_UID) - .when(mAnomalyDetectionJobService) - .extractUidFromStatsDimensionsValue(any()); - - mAnomalyDetectionJobService.saveAnomalyToDatabase( - mContext, - mUserManager, - mBatteryDatabaseManager, - mBatteryUtils, - mPolicy, - mPowerAllowlistBackend, - mContext.getContentResolver(), - mFeatureFactory.powerUsageFeatureProvider, - mFeatureFactory.metricsFeatureProvider, - mBundle); - - verify(mBatteryDatabaseManager) - .insertAnomaly( - anyInt(), - anyString(), - eq(6), - eq(AnomalyDatabaseHelper.State.AUTO_HANDLED), - anyLong()); - verify(mFeatureFactory.metricsFeatureProvider) - .action( - SettingsEnums.PAGE_UNKNOWN, - MetricsProto.MetricsEvent.ACTION_ANOMALY_TRIGGERED, - SettingsEnums.PAGE_UNKNOWN, - SYSTEM_PACKAGE + "/" + VERSION_CODE, - ANOMALY_TYPE); - } - - @Test - public void saveAnomalyToDatabase_normalAppWithoutAutoRestriction_save() { - final ArrayList cookies = new ArrayList<>(); - cookies.add(SUBSCRIBER_COOKIES_NOT_AUTO_RESTRICTION); - mBundle.putStringArrayList(StatsManager.EXTRA_STATS_BROADCAST_SUBSCRIBER_COOKIES, cookies); - doReturn(SYSTEM_PACKAGE).when(mBatteryUtils).getPackageName(anyInt()); - doReturn(false).when(mPowerAllowlistBackend).isSysAllowlisted(SYSTEM_PACKAGE); - doReturn(Process.FIRST_APPLICATION_UID) - .when(mAnomalyDetectionJobService) - .extractUidFromStatsDimensionsValue(any()); - - mAnomalyDetectionJobService.saveAnomalyToDatabase( - mContext, - mUserManager, - mBatteryDatabaseManager, - mBatteryUtils, - mPolicy, - mPowerAllowlistBackend, - mContext.getContentResolver(), - mFeatureFactory.powerUsageFeatureProvider, - mFeatureFactory.metricsFeatureProvider, - mBundle); - - verify(mBatteryDatabaseManager) - .insertAnomaly( - anyInt(), - anyString(), - eq(6), - eq(AnomalyDatabaseHelper.State.NEW), - anyLong()); - verify(mFeatureFactory.metricsFeatureProvider) - .action( - SettingsEnums.PAGE_UNKNOWN, - MetricsProto.MetricsEvent.ACTION_ANOMALY_TRIGGERED, - SettingsEnums.PAGE_UNKNOWN, - SYSTEM_PACKAGE + "/" + VERSION_CODE, - ANOMALY_TYPE); - } - - @Test - public void extractUidFromStatsDimensionsValue_extractCorrectUid() { - // Build an integer dimensions value. - final StatsDimensionsValue intValue = mock(StatsDimensionsValue.class); - when(intValue.isValueType(INT_VALUE_TYPE)).thenReturn(true); - when(intValue.getField()).thenReturn(AnomalyDetectionJobService.STATSD_UID_FILED); - when(intValue.getIntValue()).thenReturn(UID); - - // Build a tuple dimensions value and put the previous integer dimensions value inside. - final StatsDimensionsValue tupleValue = mock(StatsDimensionsValue.class); - when(tupleValue.isValueType(TUPLE_VALUE_TYPE)).thenReturn(true); - final List statsDimensionsValues = new ArrayList<>(); - statsDimensionsValues.add(intValue); - when(tupleValue.getTupleValueList()).thenReturn(statsDimensionsValues); - - assertThat(mAnomalyDetectionJobService.extractUidFromStatsDimensionsValue(tupleValue)) - .isEqualTo(UID); - } - - @Test - public void extractUidFromStatsDimensionsValue_wrongFormat_returnNull() { - // Build a float dimensions value - final StatsDimensionsValue floatValue = mock(StatsDimensionsValue.class); - when(floatValue.isValueType(FLOAT_VALUE_TYPE)).thenReturn(true); - when(floatValue.getField()).thenReturn(AnomalyDetectionJobService.STATSD_UID_FILED); - when(floatValue.getFloatValue()).thenReturn(0f); - - assertThat(mAnomalyDetectionJobService.extractUidFromStatsDimensionsValue(floatValue)) - .isEqualTo(AnomalyDetectionJobService.UID_NULL); - } - - @Test - public void stopJobWhileDequeuingWork_shouldNotCrash() { - when(mJobParameters.dequeueWork()).thenThrow(new SecurityException()); - - mAnomalyDetectionJobService.onStopJob(mJobParameters); - - // Should not crash even job is stopped - mAnomalyDetectionJobService.dequeueWork(mJobParameters); - } - - @Test - public void stopJobWhileCompletingWork_shouldNotCrash() { - doThrow(new SecurityException()).when(mJobParameters).completeWork(any()); - - mAnomalyDetectionJobService.onStopJob(mJobParameters); - - // Should not crash even job is stopped - mAnomalyDetectionJobService.completeWork(mJobParameters, mJobWorkItem); - } - - @Test - public void restartWorkAfterBeenStopped_jobStarted() { - mAnomalyDetectionJobService.onStopJob(mJobParameters); - mAnomalyDetectionJobService.onStartJob(mJobParameters); - - assertThat(mAnomalyDetectionJobService.mIsJobCanceled).isFalse(); - } -}