diff --git a/src/com/android/settings/fuelgauge/BatteryUtils.java b/src/com/android/settings/fuelgauge/BatteryUtils.java index b579fd9d176..e98ed82cd12 100644 --- a/src/com/android/settings/fuelgauge/BatteryUtils.java +++ b/src/com/android/settings/fuelgauge/BatteryUtils.java @@ -15,10 +15,13 @@ */ package com.android.settings.fuelgauge; +import android.app.AppOpsManager; import android.content.Context; +import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.os.BatteryStats; import android.os.Bundle; +import android.os.Build; import android.os.SystemClock; import android.os.UserManager; import android.support.annotation.IntDef; @@ -47,6 +50,7 @@ import java.util.List; */ public class BatteryUtils { public static final int UID_NULL = -1; + public static final int SDK_NULL = -1; @Retention(RetentionPolicy.SOURCE) @IntDef({StatusType.FOREGROUND, @@ -66,6 +70,7 @@ public class BatteryUtils { private static BatteryUtils sInstance; private PackageManager mPackageManager; + private AppOpsManager mAppOpsManager; @VisibleForTesting PowerUsageFeatureProvider mPowerUsageFeatureProvider; @@ -79,6 +84,7 @@ public class BatteryUtils { @VisibleForTesting BatteryUtils(Context context) { mPackageManager = context.getPackageManager(); + mAppOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE); mPowerUsageFeatureProvider = FeatureFactory.getFactory( context).getPowerUsageFeatureProvider(context); } @@ -263,6 +269,37 @@ public class BatteryUtils { return ArrayUtils.isEmpty(packageNames) ? null : packageNames[0]; } + /** + * Find the targetSdkVersion for package with name {@code packageName} + * + * @return the targetSdkVersion, or {@link #SDK_NULL} if {@code packageName} doesn't exist + */ + public int getTargetSdkVersion(final String packageName) { + try { + ApplicationInfo info = mPackageManager.getApplicationInfo(packageName, + PackageManager.GET_META_DATA); + + return info.targetSdkVersion; + } catch (PackageManager.NameNotFoundException e) { + Log.e(TAG, "Cannot find package: " + packageName, e); + } + + return SDK_NULL; + } + + /** + * Check whether background restriction is enabled + */ + public boolean isBackgroundRestrictionEnabled(final int targetSdkVersion, final int uid, + final String packageName) { + if (targetSdkVersion >= Build.VERSION_CODES.O) { + return true; + } + final int mode = mAppOpsManager + .checkOpNoThrow(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName); + return mode == AppOpsManager.MODE_IGNORED || mode == AppOpsManager.MODE_ERRORED; + } + /** * Sort the {@code usageList} based on {@link BatterySipper#totalPowerMah} */ @@ -337,7 +374,7 @@ public class BatteryUtils { } private boolean isDataCorrupted() { - return mPackageManager == null; + return mPackageManager == null || mAppOpsManager == null; } @VisibleForTesting diff --git a/src/com/android/settings/fuelgauge/anomaly/Anomaly.java b/src/com/android/settings/fuelgauge/anomaly/Anomaly.java index 2a4282a0789..dba964ffd48 100644 --- a/src/com/android/settings/fuelgauge/anomaly/Anomaly.java +++ b/src/com/android/settings/fuelgauge/anomaly/Anomaly.java @@ -46,16 +46,18 @@ public class Anomaly implements Parcelable { @Retention(RetentionPolicy.SOURCE) @IntDef({AnomalyActionType.FORCE_STOP, AnomalyActionType.BACKGROUND_CHECK, - AnomalyActionType.LOCATION_CHECK}) + AnomalyActionType.LOCATION_CHECK, + AnomalyActionType.STOP_AND_BACKGROUND_CHECK}) public @interface AnomalyActionType { int FORCE_STOP = 0; int BACKGROUND_CHECK = 1; int LOCATION_CHECK = 2; + int STOP_AND_BACKGROUND_CHECK = 3; } @AnomalyType - public static final int[] ANOMALY_TYPE_LIST = - {AnomalyType.WAKE_LOCK, + public static final int[] ANOMALY_TYPE_LIST = { + AnomalyType.WAKE_LOCK, AnomalyType.WAKEUP_ALARM, AnomalyType.BLUETOOTH_SCAN}; @@ -64,7 +66,14 @@ public class Anomaly implements Parcelable { */ public final int type; public final int uid; + public final int targetSdkVersion; public final long wakelockTimeMs; + /** + * {@code true} if background restriction is enabled + * + * @see android.app.AppOpsManager.OP_RUN_IN_BACKGROUND + */ + public final boolean backgroundRestrictionEnabled; /** * Display name of this anomaly, usually it is the app name */ @@ -77,6 +86,8 @@ public class Anomaly implements Parcelable { displayName = builder.mDisplayName; packageName = builder.mPackageName; wakelockTimeMs = builder.mWakeLockTimeMs; + targetSdkVersion = builder.mTargetSdkVersion; + backgroundRestrictionEnabled = builder.mBgRestrictionEnabled; } private Anomaly(Parcel in) { @@ -85,6 +96,8 @@ public class Anomaly implements Parcelable { displayName = in.readCharSequence(); packageName = in.readString(); wakelockTimeMs = in.readLong(); + targetSdkVersion = in.readInt(); + backgroundRestrictionEnabled = in.readBoolean(); } @Override @@ -99,6 +112,8 @@ public class Anomaly implements Parcelable { dest.writeCharSequence(displayName); dest.writeString(packageName); dest.writeLong(wakelockTimeMs); + dest.writeInt(targetSdkVersion); + dest.writeBoolean(backgroundRestrictionEnabled); } @Override @@ -115,12 +130,15 @@ public class Anomaly implements Parcelable { && uid == other.uid && wakelockTimeMs == other.wakelockTimeMs && TextUtils.equals(displayName, other.displayName) - && TextUtils.equals(packageName, other.packageName); + && TextUtils.equals(packageName, other.packageName) + && targetSdkVersion == other.targetSdkVersion + && backgroundRestrictionEnabled == other.backgroundRestrictionEnabled; } @Override public int hashCode() { - return Objects.hash(type, uid, displayName, packageName, wakelockTimeMs); + return Objects.hash(type, uid, displayName, packageName, wakelockTimeMs, targetSdkVersion, + backgroundRestrictionEnabled); } public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { @@ -137,9 +155,11 @@ public class Anomaly implements Parcelable { @AnomalyType private int mType; private int mUid; + private int mTargetSdkVersion; private CharSequence mDisplayName; private String mPackageName; private long mWakeLockTimeMs; + private boolean mBgRestrictionEnabled; public Builder setType(@AnomalyType int type) { mType = type; @@ -166,6 +186,16 @@ public class Anomaly implements Parcelable { return this; } + public Builder setTargetSdkVersion(int targetSdkVersion) { + mTargetSdkVersion = targetSdkVersion; + return this; + } + + public Builder setBackgroundRestrictionEnabled(boolean bgRestrictionEnabled) { + mBgRestrictionEnabled = bgRestrictionEnabled; + return this; + } + public Anomaly build() { return new Anomaly(this); } diff --git a/src/com/android/settings/fuelgauge/anomaly/AnomalyDialogFragment.java b/src/com/android/settings/fuelgauge/anomaly/AnomalyDialogFragment.java index 452cc35f30a..69d03b94c1b 100644 --- a/src/com/android/settings/fuelgauge/anomaly/AnomalyDialogFragment.java +++ b/src/com/android/settings/fuelgauge/anomaly/AnomalyDialogFragment.java @@ -90,7 +90,7 @@ public class AnomalyDialogFragment extends InstrumentedDialogFragment implements return; } - final AnomalyAction anomalyAction = mAnomalyUtils.getAnomalyAction(mAnomaly.type); + final AnomalyAction anomalyAction = mAnomalyUtils.getAnomalyAction(mAnomaly); final int metricsKey = getArguments().getInt(ARG_METRICS_KEY); anomalyAction.handlePositiveAction(mAnomaly, metricsKey); @@ -103,16 +103,18 @@ public class AnomalyDialogFragment extends InstrumentedDialogFragment implements mAnomaly = bundle.getParcelable(ARG_ANOMALY); final Context context = getContext(); - final AnomalyAction anomalyAction = mAnomalyUtils.getAnomalyAction(mAnomaly.type); + final AnomalyAction anomalyAction = mAnomalyUtils.getAnomalyAction(mAnomaly); switch (anomalyAction.getActionType()) { case Anomaly.AnomalyActionType.FORCE_STOP: return new AlertDialog.Builder(context) .setTitle(R.string.dialog_stop_title) - .setMessage(getString(R.string.dialog_stop_message, mAnomaly.displayName)) + .setMessage(getString(mAnomaly.type == Anomaly.AnomalyType.WAKE_LOCK + ? R.string.dialog_stop_message + : R.string.dialog_stop_message_wakeup_alarm, mAnomaly.displayName)) .setPositiveButton(R.string.dialog_stop_ok, this) .setNegativeButton(R.string.dlg_cancel, null) .create(); - case Anomaly.AnomalyActionType.BACKGROUND_CHECK: + case Anomaly.AnomalyActionType.STOP_AND_BACKGROUND_CHECK: return new AlertDialog.Builder(context) .setTitle(R.string.dialog_background_check_title) .setMessage(getString(R.string.dialog_background_check_message, diff --git a/src/com/android/settings/fuelgauge/anomaly/AnomalyUtils.java b/src/com/android/settings/fuelgauge/anomaly/AnomalyUtils.java index 9d0e1d0c871..8ac9e6f2983 100644 --- a/src/com/android/settings/fuelgauge/anomaly/AnomalyUtils.java +++ b/src/com/android/settings/fuelgauge/anomaly/AnomalyUtils.java @@ -17,12 +17,13 @@ package com.android.settings.fuelgauge.anomaly; import android.content.Context; +import android.os.Build; import android.support.annotation.VisibleForTesting; import com.android.settings.fuelgauge.anomaly.action.AnomalyAction; -import com.android.settings.fuelgauge.anomaly.action.BackgroundCheckAction; import com.android.settings.fuelgauge.anomaly.action.ForceStopAction; import com.android.settings.fuelgauge.anomaly.action.LocationCheckAction; +import com.android.settings.fuelgauge.anomaly.action.StopAndBackgroundCheckAction; import com.android.settings.fuelgauge.anomaly.checker.AnomalyDetector; import com.android.settings.fuelgauge.anomaly.checker.BluetoothScanAnomalyDetector; import com.android.settings.fuelgauge.anomaly.checker.WakeLockAnomalyDetector; @@ -49,16 +50,22 @@ public class AnomalyUtils { /** * Return the corresponding {@link AnomalyAction} according to - * {@link com.android.settings.fuelgauge.anomaly.Anomaly.AnomalyType} + * {@link com.android.settings.fuelgauge.anomaly.Anomaly} * * @return corresponding {@link AnomalyAction}, or null if cannot find it. */ - public AnomalyAction getAnomalyAction(@Anomaly.AnomalyType int anomalyType) { - switch (anomalyType) { + public AnomalyAction getAnomalyAction(Anomaly anomaly) { + switch (anomaly.type) { case Anomaly.AnomalyType.WAKE_LOCK: return new ForceStopAction(mContext); case Anomaly.AnomalyType.WAKEUP_ALARM: - return new BackgroundCheckAction(mContext); + if (anomaly.targetSdkVersion >= Build.VERSION_CODES.O + || (anomaly.targetSdkVersion < Build.VERSION_CODES.O + && anomaly.backgroundRestrictionEnabled)) { + return new ForceStopAction(mContext); + } else { + return new StopAndBackgroundCheckAction(mContext); + } case Anomaly.AnomalyType.BLUETOOTH_SCAN: return new LocationCheckAction(mContext); default: diff --git a/src/com/android/settings/fuelgauge/anomaly/action/BackgroundCheckAction.java b/src/com/android/settings/fuelgauge/anomaly/action/BackgroundCheckAction.java index 799bddcd85a..5526cc903b3 100644 --- a/src/com/android/settings/fuelgauge/anomaly/action/BackgroundCheckAction.java +++ b/src/com/android/settings/fuelgauge/anomaly/action/BackgroundCheckAction.java @@ -18,8 +18,11 @@ package com.android.settings.fuelgauge.anomaly.action; import android.app.AppOpsManager; import android.content.Context; +import android.os.Build; +import android.support.annotation.VisibleForTesting; import com.android.internal.logging.nano.MetricsProto; +import com.android.settings.fuelgauge.BatteryUtils; import com.android.settings.fuelgauge.anomaly.Anomaly; /** @@ -28,6 +31,8 @@ import com.android.settings.fuelgauge.anomaly.Anomaly; public class BackgroundCheckAction extends AnomalyAction { private AppOpsManager mAppOpsManager; + @VisibleForTesting + BatteryUtils mBatteryUtils; public BackgroundCheckAction(Context context) { super(context); @@ -38,17 +43,17 @@ public class BackgroundCheckAction extends AnomalyAction { @Override public void handlePositiveAction(Anomaly anomaly, int contextMetricsKey) { super.handlePositiveAction(anomaly, contextMetricsKey); - - mAppOpsManager.setMode(AppOpsManager.OP_RUN_IN_BACKGROUND, anomaly.uid, anomaly.packageName, - AppOpsManager.MODE_IGNORED); + if (anomaly.targetSdkVersion < Build.VERSION_CODES.O) { + mAppOpsManager.setMode(AppOpsManager.OP_RUN_IN_BACKGROUND, anomaly.uid, + anomaly.packageName, + AppOpsManager.MODE_IGNORED); + } } @Override public boolean isActionActive(Anomaly anomaly) { - final int mode = mAppOpsManager - .checkOpNoThrow(AppOpsManager.OP_RUN_IN_BACKGROUND, anomaly.uid, - anomaly.packageName); - return mode != AppOpsManager.MODE_IGNORED && mode != AppOpsManager.MODE_ERRORED; + return !mBatteryUtils.isBackgroundRestrictionEnabled(anomaly.targetSdkVersion, anomaly.uid, + anomaly.packageName); } @Override diff --git a/src/com/android/settings/fuelgauge/anomaly/action/StopAndBackgroundCheckAction.java b/src/com/android/settings/fuelgauge/anomaly/action/StopAndBackgroundCheckAction.java new file mode 100644 index 00000000000..dba221a35f2 --- /dev/null +++ b/src/com/android/settings/fuelgauge/anomaly/action/StopAndBackgroundCheckAction.java @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2017 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.anomaly.action; + +import android.content.Context; +import android.support.annotation.VisibleForTesting; + +import com.android.settings.fuelgauge.anomaly.Anomaly; + +/** + * Force stop and background check action for anomaly app, this action will + * 1. Force stop the app + * 2. Turn on background check + */ +public class StopAndBackgroundCheckAction extends AnomalyAction { + @VisibleForTesting + ForceStopAction mForceStopAction; + @VisibleForTesting + BackgroundCheckAction mBackgroundCheckAction; + + public StopAndBackgroundCheckAction(Context context) { + this(context, new ForceStopAction(context), new BackgroundCheckAction(context)); + } + + @VisibleForTesting + StopAndBackgroundCheckAction(Context context, ForceStopAction forceStopAction, + BackgroundCheckAction backgroundCheckAction) { + super(context); + mForceStopAction = forceStopAction; + mBackgroundCheckAction = backgroundCheckAction; + } + + @Override + public void handlePositiveAction(Anomaly anomaly, int metricsKey) { + mForceStopAction.handlePositiveAction(anomaly, metricsKey); + mBackgroundCheckAction.handlePositiveAction(anomaly, metricsKey); + } + + @Override + public boolean isActionActive(Anomaly anomaly) { + return mForceStopAction.isActionActive(anomaly) + && mBackgroundCheckAction.isActionActive(anomaly); + } + + @Override + public int getActionType() { + return Anomaly.AnomalyActionType.STOP_AND_BACKGROUND_CHECK; + } +} diff --git a/src/com/android/settings/fuelgauge/anomaly/checker/BluetoothScanAnomalyDetector.java b/src/com/android/settings/fuelgauge/anomaly/checker/BluetoothScanAnomalyDetector.java index 4281743bfd5..f66c61c165c 100644 --- a/src/com/android/settings/fuelgauge/anomaly/checker/BluetoothScanAnomalyDetector.java +++ b/src/com/android/settings/fuelgauge/anomaly/checker/BluetoothScanAnomalyDetector.java @@ -42,24 +42,21 @@ public class BluetoothScanAnomalyDetector implements AnomalyDetector { private static final String TAG = "BluetoothScanAnomalyDetector"; @VisibleForTesting BatteryUtils mBatteryUtils; - @VisibleForTesting - AnomalyAction mAnomalyAction; private long mBluetoothScanningThreshold; private Context mContext; + private AnomalyUtils mAnomalyUtils; public BluetoothScanAnomalyDetector(Context context) { - this(context, new AnomalyDetectionPolicy(context), - AnomalyUtils.getInstance(context).getAnomalyAction( - Anomaly.AnomalyType.BLUETOOTH_SCAN)); + this(context, new AnomalyDetectionPolicy(context), AnomalyUtils.getInstance(context)); } @VisibleForTesting BluetoothScanAnomalyDetector(Context context, AnomalyDetectionPolicy policy, - AnomalyAction anomalyAction) { + AnomalyUtils anomalyUtils) { mContext = context; mBatteryUtils = BatteryUtils.getInstance(context); - mAnomalyAction = anomalyAction; mBluetoothScanningThreshold = policy.bluetoothScanThreshold; + mAnomalyUtils = anomalyUtils; } @Override @@ -98,7 +95,7 @@ public class BluetoothScanAnomalyDetector implements AnomalyDetector { .setPackageName(packageName) .build(); - if (mAnomalyAction.isActionActive(anomaly)) { + if (mAnomalyUtils.getAnomalyAction(anomaly).isActionActive(anomaly)) { anomalies.add(anomaly); } } diff --git a/src/com/android/settings/fuelgauge/anomaly/checker/WakeLockAnomalyDetector.java b/src/com/android/settings/fuelgauge/anomaly/checker/WakeLockAnomalyDetector.java index 5fa0e4164c4..959ceb5bbe1 100644 --- a/src/com/android/settings/fuelgauge/anomaly/checker/WakeLockAnomalyDetector.java +++ b/src/com/android/settings/fuelgauge/anomaly/checker/WakeLockAnomalyDetector.java @@ -29,7 +29,6 @@ import com.android.settings.fuelgauge.BatteryUtils; import com.android.settings.fuelgauge.anomaly.Anomaly; import com.android.settings.fuelgauge.anomaly.AnomalyDetectionPolicy; import com.android.settings.fuelgauge.anomaly.AnomalyUtils; -import com.android.settings.fuelgauge.anomaly.action.AnomalyAction; import java.util.ArrayList; import java.util.List; @@ -39,27 +38,25 @@ import java.util.List; */ public class WakeLockAnomalyDetector implements AnomalyDetector { private static final String TAG = "WakeLockAnomalyChecker"; - private PackageManager mPackageManager; - private Context mContext; @VisibleForTesting BatteryUtils mBatteryUtils; @VisibleForTesting long mWakeLockThresholdMs; - @VisibleForTesting - AnomalyAction mAnomalyAction; + private PackageManager mPackageManager; + private Context mContext; + private AnomalyUtils mAnomalyUtils; public WakeLockAnomalyDetector(Context context) { - this(context, new AnomalyDetectionPolicy(context)); + this(context, new AnomalyDetectionPolicy(context), AnomalyUtils.getInstance(context)); } @VisibleForTesting - WakeLockAnomalyDetector(Context context, AnomalyDetectionPolicy policy) { + WakeLockAnomalyDetector(Context context, AnomalyDetectionPolicy policy, + AnomalyUtils anomalyUtils) { mContext = context; mPackageManager = context.getPackageManager(); mBatteryUtils = BatteryUtils.getInstance(context); - mAnomalyAction = AnomalyUtils.getInstance(context).getAnomalyAction( - Anomaly.AnomalyType.WAKE_LOCK); - + mAnomalyUtils = anomalyUtils; mWakeLockThresholdMs = policy.wakeLockThreshold; } @@ -94,15 +91,20 @@ public class WakeLockAnomalyDetector implements AnomalyDetector { final String packageName = mBatteryUtils.getPackageName(uid.getUid()); final CharSequence displayName = Utils.getApplicationLabel(mContext, packageName); + final int targetSdkVersion = mBatteryUtils.getTargetSdkVersion(packageName); Anomaly anomaly = new Anomaly.Builder() .setUid(uid.getUid()) .setType(Anomaly.AnomalyType.WAKE_LOCK) .setDisplayName(displayName) .setPackageName(packageName) + .setTargetSdkVersion(targetSdkVersion) + .setBackgroundRestrictionEnabled( + mBatteryUtils.isBackgroundRestrictionEnabled(targetSdkVersion, + uid.getUid(), packageName)) .build(); - if (mAnomalyAction.isActionActive(anomaly)) { + if (mAnomalyUtils.getAnomalyAction(anomaly).isActionActive(anomaly)) { anomalies.add(anomaly); } } diff --git a/src/com/android/settings/fuelgauge/anomaly/checker/WakeupAlarmAnomalyDetector.java b/src/com/android/settings/fuelgauge/anomaly/checker/WakeupAlarmAnomalyDetector.java index 55686e01483..f6ff7aa8f51 100644 --- a/src/com/android/settings/fuelgauge/anomaly/checker/WakeupAlarmAnomalyDetector.java +++ b/src/com/android/settings/fuelgauge/anomaly/checker/WakeupAlarmAnomalyDetector.java @@ -41,21 +41,20 @@ public class WakeupAlarmAnomalyDetector implements AnomalyDetector { private static final String TAG = "WakeupAlarmAnomalyDetector"; @VisibleForTesting BatteryUtils mBatteryUtils; - @VisibleForTesting - AnomalyAction mAnomalyAction; private long mWakeupAlarmThreshold; private Context mContext; + private AnomalyUtils mAnomalyUtils; public WakeupAlarmAnomalyDetector(Context context) { - this(context, new AnomalyDetectionPolicy(context)); + this(context, new AnomalyDetectionPolicy(context), AnomalyUtils.getInstance(context)); } @VisibleForTesting - WakeupAlarmAnomalyDetector(Context context, AnomalyDetectionPolicy policy) { + WakeupAlarmAnomalyDetector(Context context, AnomalyDetectionPolicy policy, + AnomalyUtils anomalyUtils) { mContext = context; mBatteryUtils = BatteryUtils.getInstance(context); - mAnomalyAction = AnomalyUtils.getInstance(context).getAnomalyAction( - Anomaly.AnomalyType.WAKEUP_ALARM); + mAnomalyUtils = anomalyUtils; mWakeupAlarmThreshold = policy.wakeupAlarmThreshold; } @@ -98,7 +97,7 @@ public class WakeupAlarmAnomalyDetector implements AnomalyDetector { .setPackageName(packageName) .build(); - if (mAnomalyAction.isActionActive(anomaly)) { + if (mAnomalyUtils.getAnomalyAction(anomaly).isActionActive(anomaly)) { anomalies.add(anomaly); } } diff --git a/tests/robotests/src/com/android/settings/applications/InstalledAppDetailsTest.java b/tests/robotests/src/com/android/settings/applications/InstalledAppDetailsTest.java index a57036161ba..e20a43556ab 100644 --- a/tests/robotests/src/com/android/settings/applications/InstalledAppDetailsTest.java +++ b/tests/robotests/src/com/android/settings/applications/InstalledAppDetailsTest.java @@ -18,6 +18,7 @@ package com.android.settings.applications; import android.app.AlertDialog; +import android.app.AppOpsManager; import android.app.Fragment; import android.app.LoaderManager; import android.app.admin.DevicePolicyManager; @@ -113,6 +114,8 @@ public final class InstalledAppDetailsTest { private BatteryUtils mBatteryUtils; @Mock private LoaderManager mLoaderManager; + @Mock + private AppOpsManager mAppOpsManager; private FakeFeatureFactory mFeatureFactory; private InstalledAppDetails mAppDetail; @@ -138,6 +141,7 @@ public final class InstalledAppDetailsTest { doReturn(mActivity).when(mAppDetail).getActivity(); doReturn(mShadowContext).when(mAppDetail).getContext(); doReturn(mPackageManager).when(mActivity).getPackageManager(); + doReturn(mAppOpsManager).when(mActivity).getSystemService(Context.APP_OPS_SERVICE); // Default to not considering any apps to be instant (individual tests can override this). ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider", diff --git a/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java b/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java index 0cabb05ff3d..7f2aeb68f4e 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java @@ -30,6 +30,7 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import android.app.Activity; +import android.app.AppOpsManager; import android.app.Fragment; import android.app.LoaderManager; import android.content.Context; @@ -116,6 +117,8 @@ public class AdvancedPowerUsageDetailTest { @Mock private PackageManager mPackageManager; @Mock + private AppOpsManager mAppOpsManager; + @Mock private LoaderManager mLoaderManager; @Mock private AnomalySummaryPreferenceController mAnomalySummaryPreferenceController; @@ -184,6 +187,7 @@ public class AdvancedPowerUsageDetailTest { mTestActivity = spy(new SettingsActivity()); doReturn(mPackageManager).when(mTestActivity).getPackageManager(); + doReturn(mAppOpsManager).when(mTestActivity).getSystemService(Context.APP_OPS_SERVICE); final ArgumentCaptor captor = ArgumentCaptor.forClass(Bundle.class); diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java index 034028aa9f9..aa19055f1b7 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java @@ -15,9 +15,13 @@ */ package com.android.settings.fuelgauge; +import android.app.AppOpsManager; import android.content.Context; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; import android.os.BatteryStats; import android.os.Bundle; +import android.os.Build; import android.os.Process; import android.os.SystemClock; import android.os.UserManager; @@ -58,6 +62,7 @@ import static org.mockito.Mockito.RETURNS_DEEP_STUBS; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -96,6 +101,8 @@ public class BatteryUtilsTest { private static final int DISCHARGE_AMOUNT = 80; private static final double PERCENT_SYSTEM_USAGE = 60; private static final double PRECISION = 0.001; + private static final int SDK_VERSION = Build.VERSION_CODES.L; + private static final String PACKAGE_NAME = "com.android.app"; @Mock private BatteryStats.Uid mUid; @@ -123,6 +130,12 @@ public class BatteryUtilsTest { private Bundle mBundle; @Mock private UserManager mUserManager; + @Mock + private PackageManager mPackageManager; + @Mock + private AppOpsManager mAppOpsManager; + @Mock + private ApplicationInfo mApplicationInfo; @Mock(answer = Answers.RETURNS_DEEP_STUBS) private Context mContext; @Mock(answer = Answers.RETURNS_DEEP_STUBS) @@ -177,10 +190,11 @@ public class BatteryUtilsTest { mIdleBatterySipper.drainType = BatterySipper.DrainType.IDLE; mIdleBatterySipper.totalPowerMah = BATTERY_IDLE_USAGE; - mBatteryUtils = BatteryUtils.getInstance(RuntimeEnvironment.application); + final Context shadowContext = spy(RuntimeEnvironment.application); + doReturn(mPackageManager).when(shadowContext).getPackageManager(); + doReturn(mAppOpsManager).when(shadowContext).getSystemService(Context.APP_OPS_SERVICE); + mBatteryUtils = spy(new BatteryUtils(shadowContext)); mBatteryUtils.mPowerUsageFeatureProvider = mProvider; - - mBatteryUtils = spy(new BatteryUtils(RuntimeEnvironment.application)); } @Test @@ -392,6 +406,44 @@ public class BatteryUtilsTest { TIME_SINCE_LAST_FULL_CHARGE_US); } + @Test + public void testGetTargetSdkVersion_packageExist_returnSdk() throws + PackageManager.NameNotFoundException { + doReturn(mApplicationInfo).when(mPackageManager).getApplicationInfo(PACKAGE_NAME, + PackageManager.GET_META_DATA); + mApplicationInfo.targetSdkVersion = SDK_VERSION; + + assertThat(mBatteryUtils.getTargetSdkVersion(PACKAGE_NAME)).isEqualTo(SDK_VERSION); + } + + @Test + public void testGetTargetSdkVersion_packageNotExist_returnSdkNull() throws + PackageManager.NameNotFoundException { + doThrow(new PackageManager.NameNotFoundException()).when( + mPackageManager).getApplicationInfo(PACKAGE_NAME, PackageManager.GET_META_DATA); + + assertThat(mBatteryUtils.getTargetSdkVersion(PACKAGE_NAME)).isEqualTo( + BatteryUtils.SDK_NULL); + } + + @Test + public void testBackgroundRestrictionOn_restrictionOn_returnTrue() { + doReturn(AppOpsManager.MODE_IGNORED).when(mAppOpsManager).checkOpNoThrow( + AppOpsManager.OP_RUN_IN_BACKGROUND, UID, PACKAGE_NAME); + + assertThat(mBatteryUtils.isBackgroundRestrictionEnabled(SDK_VERSION, UID, + PACKAGE_NAME)).isTrue(); + } + + @Test + public void testBackgroundRestrictionOn_restrictionOff_returnFalse() { + doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager).checkOpNoThrow( + AppOpsManager.OP_RUN_IN_BACKGROUND, UID, PACKAGE_NAME); + + assertThat(mBatteryUtils.isBackgroundRestrictionEnabled(SDK_VERSION, UID, + PACKAGE_NAME)).isFalse(); + } + private BatterySipper createTestSmearBatterySipper(long topTime, double totalPowerMah, int uidCode, boolean isUidNull) { final BatterySipper sipper = mock(BatterySipper.class); diff --git a/tests/robotests/src/com/android/settings/fuelgauge/anomaly/AnomalyDialogFragmentTest.java b/tests/robotests/src/com/android/settings/fuelgauge/anomaly/AnomalyDialogFragmentTest.java index e8e4bab8b16..1111804dd8d 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/anomaly/AnomalyDialogFragmentTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/anomaly/AnomalyDialogFragmentTest.java @@ -18,6 +18,7 @@ package com.android.settings.fuelgauge.anomaly; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyInt; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; @@ -27,6 +28,7 @@ import static org.robolectric.Shadows.shadowOf; import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; +import android.os.Build; import com.android.settings.R; import com.android.settings.fuelgauge.anomaly.action.AnomalyAction; @@ -57,6 +59,7 @@ public class AnomalyDialogFragmentTest { private AnomalyAction mAnomalyAction; private Anomaly mWakeLockAnomaly; private Anomaly mWakeupAlarmAnomaly; + private Anomaly mWakeupAlarmAnomaly2; private Anomaly mBluetoothAnomaly; private AnomalyDialogFragment mAnomalyDialogFragment; private Context mContext; @@ -78,6 +81,13 @@ public class AnomalyDialogFragmentTest { .setPackageName(PACKAGE_NAME) .setDisplayName(DISPLAY_NAME) .build(); + mWakeupAlarmAnomaly2 = new Anomaly.Builder() + .setType(Anomaly.AnomalyType.WAKEUP_ALARM) + .setUid(UID) + .setPackageName(PACKAGE_NAME) + .setDisplayName(DISPLAY_NAME) + .setTargetSdkVersion(Build.VERSION_CODES.O) + .build(); mBluetoothAnomaly = new Anomaly.Builder() .setType(Anomaly.AnomalyType.BLUETOOTH_SCAN) .setUid(UID) @@ -116,7 +126,7 @@ public class AnomalyDialogFragmentTest { } @Test - public void testOnCreateDialog_wakeupAlarmAnomaly_fireBackgroundCheckDialog() { + public void testOnCreateDialog_wakeupAlarmAnomalyPriorO_fireStopAndBackgroundCheckDialog() { mAnomalyDialogFragment = AnomalyDialogFragment.newInstance(mWakeupAlarmAnomaly, 0 /* metricskey */); @@ -136,12 +146,33 @@ public class AnomalyDialogFragmentTest { mContext.getString(R.string.dlg_cancel)); } + @Test + public void testOnCreateDialog_wakeupAlarmAnomalyTargetingO_fireForceStopDialog() { + mAnomalyDialogFragment = AnomalyDialogFragment.newInstance(mWakeupAlarmAnomaly2, + 0 /* metricskey */); + + FragmentTestUtil.startFragment(mAnomalyDialogFragment); + + final AlertDialog dialog = (AlertDialog) ShadowDialog.getLatestDialog(); + ShadowAlertDialog shadowDialog = shadowOf(dialog); + + assertThat(shadowDialog.getMessage()).isEqualTo( + mContext.getString(R.string.dialog_stop_message_wakeup_alarm, + mWakeLockAnomaly.displayName)); + assertThat(shadowDialog.getTitle()).isEqualTo( + mContext.getString(R.string.dialog_stop_title)); + assertThat(dialog.getButton(DialogInterface.BUTTON_POSITIVE).getText()).isEqualTo( + mContext.getString(R.string.dialog_stop_ok)); + assertThat(dialog.getButton(DialogInterface.BUTTON_NEGATIVE).getText()).isEqualTo( + mContext.getString(R.string.dlg_cancel)); + } + @Test public void testOnCreateDialog_bluetoothAnomaly_fireLocationCheckDialog() { mAnomalyDialogFragment = spy(AnomalyDialogFragment.newInstance(mBluetoothAnomaly, 0 /* metricskey */)); mAnomalyDialogFragment.mAnomalyUtils = mAnomalyUtils; - doReturn(mAnomalyAction).when(mAnomalyUtils).getAnomalyAction(anyInt()); + doReturn(mAnomalyAction).when(mAnomalyUtils).getAnomalyAction(any()); doNothing().when(mAnomalyDialogFragment).initAnomalyUtils(); doReturn(Anomaly.AnomalyActionType.LOCATION_CHECK).when(mAnomalyAction).getActionType(); diff --git a/tests/robotests/src/com/android/settings/fuelgauge/anomaly/AnomalyTest.java b/tests/robotests/src/com/android/settings/fuelgauge/anomaly/AnomalyTest.java index 55b8308a964..759f0fd91c5 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/anomaly/AnomalyTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/anomaly/AnomalyTest.java @@ -18,6 +18,8 @@ package com.android.settings.fuelgauge.anomaly; import static com.google.common.truth.Truth.assertThat; +import android.os.Build; + import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; @@ -30,6 +32,7 @@ import org.robolectric.annotation.Config; public class AnomalyTest { private static int TYPE = Anomaly.AnomalyType.WAKE_LOCK; private static int UID = 111; + private static int SDK_VERSION = Build.VERSION_CODES.L; private static long WAKE_LOCK_TIME_MS = 1500; private static String PACKAGE_NAME = "com.android.settings"; private static String DISPLAY_NAME = "settings"; @@ -42,6 +45,8 @@ public class AnomalyTest { .setWakeLockTimeMs(WAKE_LOCK_TIME_MS) .setPackageName(PACKAGE_NAME) .setDisplayName(DISPLAY_NAME) + .setTargetSdkVersion(SDK_VERSION) + .setBackgroundRestrictionEnabled(true) .build(); assertThat(anomaly.type).isEqualTo(TYPE); @@ -49,5 +54,7 @@ public class AnomalyTest { assertThat(anomaly.wakelockTimeMs).isEqualTo(WAKE_LOCK_TIME_MS); assertThat(anomaly.packageName).isEqualTo(PACKAGE_NAME); assertThat(anomaly.displayName).isEqualTo(DISPLAY_NAME); + assertThat(anomaly.targetSdkVersion).isEqualTo(SDK_VERSION); + assertThat(anomaly.backgroundRestrictionEnabled).isTrue(); } } diff --git a/tests/robotests/src/com/android/settings/fuelgauge/anomaly/AnomalyUtilsTest.java b/tests/robotests/src/com/android/settings/fuelgauge/anomaly/AnomalyUtilsTest.java index 15bca7e1712..8cd5a063b72 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/anomaly/AnomalyUtilsTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/anomaly/AnomalyUtilsTest.java @@ -18,9 +18,11 @@ package com.android.settings.fuelgauge.anomaly; import static com.google.common.truth.Truth.assertThat; +import android.os.Build; + +import com.android.settings.fuelgauge.anomaly.action.StopAndBackgroundCheckAction; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; -import com.android.settings.fuelgauge.anomaly.action.BackgroundCheckAction; import com.android.settings.fuelgauge.anomaly.action.ForceStopAction; import com.android.settings.fuelgauge.anomaly.checker.WakeLockAnomalyDetector; import com.android.settings.testutils.shadow.ShadowKeyValueListParserWrapperImpl; @@ -45,22 +47,51 @@ public class AnomalyUtilsTest { @Test public void testGetAnomalyAction_typeWakeLock_returnForceStop() { - assertThat(mAnomalyUtils.getAnomalyAction(Anomaly.AnomalyType.WAKE_LOCK)).isInstanceOf( + Anomaly anomaly = new Anomaly.Builder() + .setType(Anomaly.AnomalyType.WAKE_LOCK) + .build(); + assertThat(mAnomalyUtils.getAnomalyAction(anomaly)).isInstanceOf( ForceStopAction.class); } - @Test - public void testGetAnomalyAction_typeWakeUpAlarm_returnBackgroundCheck() { - assertThat(mAnomalyUtils.getAnomalyAction(Anomaly.AnomalyType.WAKEUP_ALARM)).isInstanceOf( - BackgroundCheckAction.class); - } - @Test public void testGetAnomalyDetector_typeWakeLock_returnWakeLockDetector() { assertThat(mAnomalyUtils.getAnomalyDetector(Anomaly.AnomalyType.WAKE_LOCK)).isInstanceOf( WakeLockAnomalyDetector.class); } + @Test + public void testGetAnomalyAction_typeWakeUpAlarmTargetO_returnForceStop() { + Anomaly anomaly = new Anomaly.Builder() + .setType(Anomaly.AnomalyType.WAKEUP_ALARM) + .setTargetSdkVersion(Build.VERSION_CODES.O) + .build(); + assertThat(mAnomalyUtils.getAnomalyAction(anomaly)).isInstanceOf( + ForceStopAction.class); + } + + @Test + public void testGetAnomalyAction_typeWakeUpAlarmTargetPriorOAndBgOff_returnStopAndBackground() { + Anomaly anomaly = new Anomaly.Builder() + .setType(Anomaly.AnomalyType.WAKEUP_ALARM) + .setTargetSdkVersion(Build.VERSION_CODES.L) + .setBackgroundRestrictionEnabled(false) + .build(); + assertThat(mAnomalyUtils.getAnomalyAction(anomaly)).isInstanceOf( + StopAndBackgroundCheckAction.class); + } + + @Test + public void testGetAnomalyAction_typeWakeUpAlarmTargetPriorOAndBgOn_returnForceStop() { + Anomaly anomaly = new Anomaly.Builder() + .setType(Anomaly.AnomalyType.WAKEUP_ALARM) + .setTargetSdkVersion(Build.VERSION_CODES.L) + .setBackgroundRestrictionEnabled(true) + .build(); + assertThat(mAnomalyUtils.getAnomalyAction(anomaly)).isInstanceOf( + ForceStopAction.class); + } + @Test public void testGetAnomalyDetector_typeWakeUpAlarm_returnWakeUpAlarmDetector() { assertThat(mAnomalyUtils.getAnomalyDetector(Anomaly.AnomalyType.WAKEUP_ALARM)).isInstanceOf( diff --git a/tests/robotests/src/com/android/settings/fuelgauge/anomaly/action/BackgroundCheckActionTest.java b/tests/robotests/src/com/android/settings/fuelgauge/anomaly/action/BackgroundCheckActionTest.java index ae783ab4e49..e2b8656c5cf 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/anomaly/action/BackgroundCheckActionTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/anomaly/action/BackgroundCheckActionTest.java @@ -23,7 +23,9 @@ import static org.mockito.Mockito.verify; import android.app.AppOpsManager; import android.content.Context; +import android.os.Build; +import com.android.settings.fuelgauge.BatteryUtils; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; import com.android.settings.fuelgauge.anomaly.Anomaly; @@ -42,11 +44,14 @@ import org.robolectric.annotation.Config; public class BackgroundCheckActionTest { private static final String PACKAGE_NAME = "com.android.app"; private static final int UID = 111; + private static final int SDK_VERSION = Build.VERSION_CODES.L; @Mock(answer = Answers.RETURNS_DEEP_STUBS) private Context mContext; @Mock - private AppOpsManager mAppOpsManagerr; + private AppOpsManager mAppOpsManager; + @Mock + private BatteryUtils mBatteryUtils; private Anomaly mAnomaly; private BackgroundCheckAction mBackgroundCheckAction; @@ -55,35 +60,37 @@ public class BackgroundCheckActionTest { MockitoAnnotations.initMocks(this); FakeFeatureFactory.setupForTest(mContext); - doReturn(mAppOpsManagerr).when(mContext).getSystemService(Context.APP_OPS_SERVICE); + doReturn(mAppOpsManager).when(mContext).getSystemService(Context.APP_OPS_SERVICE); mAnomaly = new Anomaly.Builder() .setUid(UID) .setPackageName(PACKAGE_NAME) + .setTargetSdkVersion(SDK_VERSION) .build(); mBackgroundCheckAction = new BackgroundCheckAction(mContext); + mBackgroundCheckAction.mBatteryUtils = mBatteryUtils; } @Test public void testHandlePositiveAction_forceStopPackage() { mBackgroundCheckAction.handlePositiveAction(mAnomaly, 0 /* metricskey */); - verify(mAppOpsManagerr).setMode(AppOpsManager.OP_RUN_IN_BACKGROUND, UID, PACKAGE_NAME, + verify(mAppOpsManager).setMode(AppOpsManager.OP_RUN_IN_BACKGROUND, UID, PACKAGE_NAME, AppOpsManager.MODE_IGNORED); } @Test public void testIsActionActive_modeAllowed_returnTrue() { - doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManagerr).checkOpNoThrow( - AppOpsManager.OP_RUN_IN_BACKGROUND, UID, PACKAGE_NAME); + doReturn(false).when(mBatteryUtils).isBackgroundRestrictionEnabled(SDK_VERSION, UID, + PACKAGE_NAME); assertThat(mBackgroundCheckAction.isActionActive(mAnomaly)).isTrue(); } @Test public void testIsActionActive_modeIgnored_returnFalse() { - doReturn(AppOpsManager.MODE_IGNORED).when(mAppOpsManagerr).checkOpNoThrow( - AppOpsManager.OP_RUN_IN_BACKGROUND, UID, PACKAGE_NAME); + doReturn(true).when(mBatteryUtils).isBackgroundRestrictionEnabled(SDK_VERSION, UID, + PACKAGE_NAME); assertThat(mBackgroundCheckAction.isActionActive(mAnomaly)).isFalse(); } diff --git a/tests/robotests/src/com/android/settings/fuelgauge/anomaly/action/StopAndBackgroundActionTest.java b/tests/robotests/src/com/android/settings/fuelgauge/anomaly/action/StopAndBackgroundActionTest.java new file mode 100644 index 00000000000..c06bddd92c4 --- /dev/null +++ b/tests/robotests/src/com/android/settings/fuelgauge/anomaly/action/StopAndBackgroundActionTest.java @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2017 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.anomaly.action; + +import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.verify; + +import android.content.Context; + +import com.android.settings.TestConfig; +import com.android.settings.fuelgauge.anomaly.Anomaly; +import com.android.settings.testutils.FakeFeatureFactory; +import com.android.settings.testutils.SettingsRobolectricTestRunner; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Answers; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.annotation.Config; + +@RunWith(SettingsRobolectricTestRunner.class) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) +public class StopAndBackgroundActionTest { + private static final String PACKAGE_NAME = "com.android.app"; + private static final int UID = 111; + private static final int METRICS_KEY = 3; + + @Mock(answer = Answers.RETURNS_DEEP_STUBS) + private Context mContext; + @Mock + private BackgroundCheckAction mBackgroundCheckAction; + @Mock + private ForceStopAction mForceStopAction; + private StopAndBackgroundCheckAction mStopAndBackgroundCheckAction; + private Anomaly mAnomaly; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + mAnomaly = new Anomaly.Builder() + .setUid(UID) + .setPackageName(PACKAGE_NAME) + .build(); + + FakeFeatureFactory.setupForTest(mContext); + mStopAndBackgroundCheckAction = new StopAndBackgroundCheckAction(mContext, mForceStopAction, + mBackgroundCheckAction); + } + + @Test + public void testHandlePositiveAction_stopAndBackgroundCheck() { + mStopAndBackgroundCheckAction.handlePositiveAction(mAnomaly, METRICS_KEY); + + verify(mBackgroundCheckAction).handlePositiveAction(mAnomaly, METRICS_KEY); + verify(mForceStopAction).handlePositiveAction(mAnomaly, METRICS_KEY); + } + + @Test + public void testIsActionActive_restrictionEnabled_returnFalse() { + doReturn(true).when(mForceStopAction).isActionActive(mAnomaly); + + assertThat(mStopAndBackgroundCheckAction.isActionActive(mAnomaly)).isFalse(); + } + + @Test + public void testIsActionActive_appNotRunning_returnFalse() { + doReturn(true).when(mBackgroundCheckAction).isActionActive(mAnomaly); + + assertThat(mStopAndBackgroundCheckAction.isActionActive(mAnomaly)).isFalse(); + } + + @Test + public void testIsActionActive_appStoppedAndRestrictionOn_returnFalse() { + assertThat(mStopAndBackgroundCheckAction.isActionActive(mAnomaly)).isFalse(); + } +} diff --git a/tests/robotests/src/com/android/settings/fuelgauge/anomaly/checker/BluetoothScanAnomalyDetectorTest.java b/tests/robotests/src/com/android/settings/fuelgauge/anomaly/checker/BluetoothScanAnomalyDetectorTest.java index a687e2f49e1..d21687c19cd 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/anomaly/checker/BluetoothScanAnomalyDetectorTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/anomaly/checker/BluetoothScanAnomalyDetectorTest.java @@ -36,6 +36,7 @@ import com.android.settings.TestConfig; import com.android.settings.fuelgauge.BatteryUtils; import com.android.settings.fuelgauge.anomaly.Anomaly; import com.android.settings.fuelgauge.anomaly.AnomalyDetectionPolicy; +import com.android.settings.fuelgauge.anomaly.AnomalyUtils; import com.android.settings.fuelgauge.anomaly.action.AnomalyAction; import com.android.settings.testutils.SettingsRobolectricTestRunner; @@ -80,6 +81,8 @@ public class BluetoothScanAnomalyDetectorTest { private AnomalyDetectionPolicy mPolicy; @Mock private AnomalyAction mAnomalyAction; + @Mock + private AnomalyUtils mAnomalyUtils; private BluetoothScanAnomalyDetector mBluetoothScanAnomalyDetector; private Context mContext; @@ -92,6 +95,7 @@ public class BluetoothScanAnomalyDetectorTest { mContext = spy(RuntimeEnvironment.application); ReflectionHelpers.setField(mPolicy, "bluetoothScanThreshold", 30 * DateUtils.MINUTE_IN_MILLIS); + doReturn(mAnomalyAction).when(mAnomalyUtils).getAnomalyAction(any()); mAnomalySipper.uidObj = mAnomalyUid; doReturn(ANOMALY_UID).when(mAnomalyUid).getUid(); @@ -106,10 +110,9 @@ public class BluetoothScanAnomalyDetectorTest { mUsageList.add(mTargetSipper); doReturn(mUsageList).when(mBatteryStatsHelper).getUsageList(); - mBluetoothScanAnomalyDetector = spy( - new BluetoothScanAnomalyDetector(mContext, mPolicy, mAnomalyAction)); + mBluetoothScanAnomalyDetector = spy(new BluetoothScanAnomalyDetector(mContext, mPolicy, + mAnomalyUtils)); mBluetoothScanAnomalyDetector.mBatteryUtils = mBatteryUtils; - mBluetoothScanAnomalyDetector.mAnomalyAction = mAnomalyAction; doReturn(false).when(mBatteryUtils).shouldHideSipper(any()); doReturn(true).when(mAnomalyAction).isActionActive(any()); diff --git a/tests/robotests/src/com/android/settings/fuelgauge/anomaly/checker/WakeLockAnomalyDetectorTest.java b/tests/robotests/src/com/android/settings/fuelgauge/anomaly/checker/WakeLockAnomalyDetectorTest.java index 19ab7d61cba..f53e8a04447 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/anomaly/checker/WakeLockAnomalyDetectorTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/anomaly/checker/WakeLockAnomalyDetectorTest.java @@ -34,6 +34,7 @@ import android.text.format.DateUtils; import com.android.internal.os.BatterySipper; import com.android.internal.os.BatteryStatsHelper; +import com.android.settings.fuelgauge.anomaly.AnomalyUtils; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; import com.android.settings.fuelgauge.BatteryUtils; @@ -92,6 +93,8 @@ public class WakeLockAnomalyDetectorTest { private AnomalyDetectionPolicy mPolicy; @Mock private AnomalyAction mAnomalyAction; + @Mock + private AnomalyUtils mAnomalyUtils; private WakeLockAnomalyDetector mWakelockAnomalyDetector; private Context mContext; @@ -109,10 +112,11 @@ public class WakeLockAnomalyDetectorTest { doReturn(mApplicationInfo).when(mPackageManager) .getApplicationInfo(nullable(String.class), anyInt()); doReturn(true).when(mAnomalyAction).isActionActive(any()); + doReturn(mAnomalyAction).when(mAnomalyUtils).getAnomalyAction(any()); - mWakelockAnomalyDetector = spy(new WakeLockAnomalyDetector(mContext, mPolicy)); + mWakelockAnomalyDetector = spy( + new WakeLockAnomalyDetector(mContext, mPolicy, mAnomalyUtils)); mWakelockAnomalyDetector.mBatteryUtils = mBatteryUtils; - mWakelockAnomalyDetector.mAnomalyAction = mAnomalyAction; mAnomalySipper.uidObj = mAnomalyUid; doReturn(ANOMALY_WAKELOCK_TIME_MS).when(mWakelockAnomalyDetector) diff --git a/tests/robotests/src/com/android/settings/fuelgauge/anomaly/checker/WakeupAlarmAnomalyDetectorTest.java b/tests/robotests/src/com/android/settings/fuelgauge/anomaly/checker/WakeupAlarmAnomalyDetectorTest.java index e7c26641e6c..a16db6e924d 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/anomaly/checker/WakeupAlarmAnomalyDetectorTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/anomaly/checker/WakeupAlarmAnomalyDetectorTest.java @@ -33,6 +33,7 @@ import android.util.ArrayMap; import com.android.internal.os.BatterySipper; import com.android.internal.os.BatteryStatsHelper; +import com.android.settings.fuelgauge.anomaly.AnomalyUtils; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; import com.android.settings.fuelgauge.BatteryUtils; @@ -89,6 +90,8 @@ public class WakeupAlarmAnomalyDetectorTest { private AnomalyDetectionPolicy mPolicy; @Mock private AnomalyAction mAnomalyAction; + @Mock + private AnomalyUtils mAnomalyUtils; private WakeupAlarmAnomalyDetector mWakeupAlarmAnomalyDetector; private Context mContext; @@ -105,6 +108,7 @@ public class WakeupAlarmAnomalyDetectorTest { doReturn(RUNNING_TIME_MS).when(mBatteryUtils).calculateRunningTimeBasedOnStatsType(any(), anyInt()); doReturn(true).when(mAnomalyAction).isActionActive(any()); + doReturn(mAnomalyAction).when(mAnomalyUtils).getAnomalyAction(any()); mAnomalySipper.uidObj = mAnomalyUid; doReturn(ANOMALY_UID).when(mAnomalyUid).getUid(); @@ -119,9 +123,9 @@ public class WakeupAlarmAnomalyDetectorTest { mUsageList.add(mTargetSipper); doReturn(mUsageList).when(mBatteryStatsHelper).getUsageList(); - mWakeupAlarmAnomalyDetector = spy(new WakeupAlarmAnomalyDetector(mContext, mPolicy)); + mWakeupAlarmAnomalyDetector = spy( + new WakeupAlarmAnomalyDetector(mContext, mPolicy, mAnomalyUtils)); mWakeupAlarmAnomalyDetector.mBatteryUtils = mBatteryUtils; - mWakeupAlarmAnomalyDetector.mAnomalyAction = mAnomalyAction; } @Test