Home | History | Annotate | Download | only in anomaly
      1 /*
      2  * Copyright (C) 2017 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.settings.fuelgauge.anomaly;
     18 
     19 import android.os.Parcel;
     20 import android.os.Parcelable;
     21 import android.support.annotation.IntDef;
     22 import android.text.TextUtils;
     23 
     24 import java.lang.annotation.Retention;
     25 import java.lang.annotation.RetentionPolicy;
     26 import java.util.Objects;
     27 
     28 /**
     29  * Data that represents an app has been detected as anomaly. It contains
     30  *
     31  * 1. Basic information of the app(i.e. uid, package name)
     32  * 2. Type of anomaly
     33  * 3. Data that has been detected as anomaly(i.e wakelock time)
     34  */
     35 public class Anomaly implements Parcelable {
     36     @Retention(RetentionPolicy.SOURCE)
     37     @IntDef({AnomalyType.WAKE_LOCK,
     38             AnomalyType.WAKEUP_ALARM,
     39             AnomalyType.BLUETOOTH_SCAN})
     40     public @interface AnomalyType {
     41         int WAKE_LOCK = 0;
     42         int WAKEUP_ALARM = 1;
     43         int BLUETOOTH_SCAN = 2;
     44     }
     45 
     46     @Retention(RetentionPolicy.SOURCE)
     47     @IntDef({AnomalyActionType.FORCE_STOP,
     48             AnomalyActionType.BACKGROUND_CHECK,
     49             AnomalyActionType.LOCATION_CHECK,
     50             AnomalyActionType.STOP_AND_BACKGROUND_CHECK})
     51     public @interface AnomalyActionType {
     52         int FORCE_STOP = 0;
     53         int BACKGROUND_CHECK = 1;
     54         int LOCATION_CHECK = 2;
     55         int STOP_AND_BACKGROUND_CHECK = 3;
     56     }
     57 
     58     @AnomalyType
     59     public static final int[] ANOMALY_TYPE_LIST = {
     60             AnomalyType.WAKE_LOCK,
     61             AnomalyType.WAKEUP_ALARM,
     62             AnomalyType.BLUETOOTH_SCAN};
     63 
     64     /**
     65      * Type of this this anomaly
     66      */
     67     public final int type;
     68     public final int uid;
     69     public final int targetSdkVersion;
     70     public final long wakelockTimeMs;
     71     public final long bluetoothScanningTimeMs;
     72     public final int wakeupAlarmCount;
     73     /**
     74      * {@code true} if background restriction is enabled
     75      *
     76      * @see android.app.AppOpsManager.OP_RUN_IN_BACKGROUND
     77      */
     78     public final boolean backgroundRestrictionEnabled;
     79     /**
     80      * Display name of this anomaly, usually it is the app name
     81      */
     82     public final CharSequence displayName;
     83     public final String packageName;
     84 
     85     private Anomaly(Builder builder) {
     86         type = builder.mType;
     87         uid = builder.mUid;
     88         displayName = builder.mDisplayName;
     89         packageName = builder.mPackageName;
     90         wakelockTimeMs = builder.mWakeLockTimeMs;
     91         targetSdkVersion = builder.mTargetSdkVersion;
     92         backgroundRestrictionEnabled = builder.mBgRestrictionEnabled;
     93         bluetoothScanningTimeMs = builder.mBluetoothScanningTimeMs;
     94         wakeupAlarmCount = builder.mWakeupAlarmCount;
     95     }
     96 
     97     private Anomaly(Parcel in) {
     98         type = in.readInt();
     99         uid = in.readInt();
    100         displayName = in.readCharSequence();
    101         packageName = in.readString();
    102         wakelockTimeMs = in.readLong();
    103         targetSdkVersion = in.readInt();
    104         backgroundRestrictionEnabled = in.readBoolean();
    105         wakeupAlarmCount = in.readInt();
    106         bluetoothScanningTimeMs = in.readLong();
    107     }
    108 
    109     @Override
    110     public int describeContents() {
    111         return 0;
    112     }
    113 
    114     @Override
    115     public void writeToParcel(Parcel dest, int flags) {
    116         dest.writeInt(type);
    117         dest.writeInt(uid);
    118         dest.writeCharSequence(displayName);
    119         dest.writeString(packageName);
    120         dest.writeLong(wakelockTimeMs);
    121         dest.writeInt(targetSdkVersion);
    122         dest.writeBoolean(backgroundRestrictionEnabled);
    123         dest.writeInt(wakeupAlarmCount);
    124         dest.writeLong(bluetoothScanningTimeMs);
    125     }
    126 
    127     @Override
    128     public boolean equals(Object obj) {
    129         if (this == obj) {
    130             return true;
    131         }
    132         if (!(obj instanceof Anomaly)) {
    133             return false;
    134         }
    135 
    136         Anomaly other = (Anomaly) obj;
    137         return type == other.type
    138                 && uid == other.uid
    139                 && wakelockTimeMs == other.wakelockTimeMs
    140                 && TextUtils.equals(displayName, other.displayName)
    141                 && TextUtils.equals(packageName, other.packageName)
    142                 && targetSdkVersion == other.targetSdkVersion
    143                 && backgroundRestrictionEnabled == other.backgroundRestrictionEnabled
    144                 && wakeupAlarmCount == other.wakeupAlarmCount
    145                 && bluetoothScanningTimeMs == other.bluetoothScanningTimeMs;
    146     }
    147 
    148     @Override
    149     public int hashCode() {
    150         return Objects.hash(type, uid, displayName, packageName, wakelockTimeMs, targetSdkVersion,
    151                 backgroundRestrictionEnabled, wakeupAlarmCount, bluetoothScanningTimeMs);
    152     }
    153 
    154     @Override
    155     public String toString() {
    156         return "type=" + toAnomalyTypeText(type) + " uid=" + uid + " package=" + packageName +
    157                 " displayName=" + displayName + " wakelockTimeMs=" + wakelockTimeMs +
    158                 " wakeupAlarmCount=" + wakeupAlarmCount + " bluetoothTimeMs="
    159                 + bluetoothScanningTimeMs;
    160     }
    161 
    162     private String toAnomalyTypeText(@AnomalyType int type) {
    163         switch (type) {
    164             case AnomalyType.WAKEUP_ALARM:
    165                 return "wakeupAlarm";
    166             case AnomalyType.WAKE_LOCK:
    167                 return "wakelock";
    168             case AnomalyType.BLUETOOTH_SCAN:
    169                 return "unoptimizedBluetoothScan";
    170         }
    171 
    172         return "";
    173     }
    174 
    175     public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
    176         public Anomaly createFromParcel(Parcel in) {
    177             return new Anomaly(in);
    178         }
    179 
    180         public Anomaly[] newArray(int size) {
    181             return new Anomaly[size];
    182         }
    183     };
    184 
    185     public static final class Builder {
    186         @AnomalyType
    187         private int mType;
    188         private int mUid;
    189         private int mTargetSdkVersion;
    190         private CharSequence mDisplayName;
    191         private String mPackageName;
    192         private long mWakeLockTimeMs;
    193         private boolean mBgRestrictionEnabled;
    194         private int mWakeupAlarmCount;
    195         private long mBluetoothScanningTimeMs;
    196 
    197         public Builder setType(@AnomalyType int type) {
    198             mType = type;
    199             return this;
    200         }
    201 
    202         public Builder setUid(int uid) {
    203             mUid = uid;
    204             return this;
    205         }
    206 
    207         public Builder setDisplayName(CharSequence displayName) {
    208             mDisplayName = displayName;
    209             return this;
    210         }
    211 
    212         public Builder setPackageName(String packageName) {
    213             mPackageName = packageName;
    214             return this;
    215         }
    216 
    217         public Builder setWakeLockTimeMs(long wakeLockTimeMs) {
    218             mWakeLockTimeMs = wakeLockTimeMs;
    219             return this;
    220         }
    221 
    222         public Builder setTargetSdkVersion(int targetSdkVersion) {
    223             mTargetSdkVersion = targetSdkVersion;
    224             return this;
    225         }
    226 
    227         public Builder setBackgroundRestrictionEnabled(boolean bgRestrictionEnabled) {
    228             mBgRestrictionEnabled = bgRestrictionEnabled;
    229             return this;
    230         }
    231 
    232         public Builder setWakeupAlarmCount(int wakeupAlarmCount) {
    233             mWakeupAlarmCount = wakeupAlarmCount;
    234             return this;
    235         }
    236 
    237         public Builder setBluetoothScanningTimeMs(long bluetoothScanningTimeMs) {
    238             mBluetoothScanningTimeMs = bluetoothScanningTimeMs;
    239             return this;
    240         }
    241 
    242         public Anomaly build() {
    243             return new Anomaly(this);
    244         }
    245     }
    246 }
    247