Home | History | Annotate | Download | only in tips
      1 /*
      2  * Copyright (C) 2018 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.batterytip.tips;
     18 
     19 import android.content.Context;
     20 import android.content.res.Resources;
     21 import android.icu.text.ListFormatter;
     22 import android.os.Parcel;
     23 import android.text.TextUtils;
     24 import android.util.Pair;
     25 
     26 import com.android.internal.annotations.VisibleForTesting;
     27 import com.android.internal.logging.nano.MetricsProto;
     28 import com.android.settings.R;
     29 import com.android.settings.Utils;
     30 import com.android.settings.fuelgauge.batterytip.AppInfo;
     31 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
     32 
     33 import java.util.ArrayList;
     34 import java.util.List;
     35 
     36 /**
     37  * Tip to suggest user to restrict some bad apps
     38  */
     39 public class RestrictAppTip extends BatteryTip {
     40     private List<AppInfo> mRestrictAppList;
     41 
     42     public RestrictAppTip(@StateType int state, List<AppInfo> restrictApps) {
     43         super(TipType.APP_RESTRICTION, state, state == StateType.NEW /* showDialog */);
     44         mRestrictAppList = restrictApps;
     45         mNeedUpdate = false;
     46     }
     47 
     48     public RestrictAppTip(@StateType int state, AppInfo appInfo) {
     49         super(TipType.APP_RESTRICTION, state, state == StateType.NEW /* showDialog */);
     50         mRestrictAppList = new ArrayList<>();
     51         mRestrictAppList.add(appInfo);
     52         mNeedUpdate = false;
     53     }
     54 
     55     @VisibleForTesting
     56     RestrictAppTip(Parcel in) {
     57         super(in);
     58         mRestrictAppList = in.createTypedArrayList(AppInfo.CREATOR);
     59     }
     60 
     61     @Override
     62     public CharSequence getTitle(Context context) {
     63         final int num = mRestrictAppList.size();
     64         final CharSequence appLabel = num > 0 ? Utils.getApplicationLabel(context,
     65                 mRestrictAppList.get(0).packageName) : "";
     66         final Resources resources = context.getResources();
     67 
     68         return mState == StateType.HANDLED
     69                 ? resources.getQuantityString(R.plurals.battery_tip_restrict_handled_title, num,
     70                 appLabel, num)
     71                 : resources.getQuantityString(R.plurals.battery_tip_restrict_title, num, num);
     72     }
     73 
     74     @Override
     75     public CharSequence getSummary(Context context) {
     76         final int num = mRestrictAppList.size();
     77         final CharSequence appLabel = num > 0 ? Utils.getApplicationLabel(context,
     78                 mRestrictAppList.get(0).packageName) : "";
     79         final int resId = mState == StateType.HANDLED
     80                 ? R.plurals.battery_tip_restrict_handled_summary
     81                 : R.plurals.battery_tip_restrict_summary;
     82         return context.getResources().getQuantityString(resId, num, appLabel, num);
     83     }
     84 
     85     @Override
     86     public int getIconId() {
     87         return mState == StateType.HANDLED
     88                 ? R.drawable.ic_perm_device_information_green_24dp
     89                 : R.drawable.ic_battery_alert_24dp;
     90     }
     91 
     92     @Override
     93     public void updateState(BatteryTip tip) {
     94         if (tip.mState == StateType.NEW) {
     95             // Display it if new anomaly comes
     96             mState = StateType.NEW;
     97             mRestrictAppList = ((RestrictAppTip) tip).mRestrictAppList;
     98             mShowDialog = true;
     99         } else if (mState == StateType.NEW && tip.mState == StateType.INVISIBLE) {
    100             // If anomaly becomes invisible, show it as handled
    101             mState = StateType.HANDLED;
    102             mShowDialog = false;
    103         } else {
    104             mState = tip.getState();
    105             mShowDialog = tip.shouldShowDialog();
    106             mRestrictAppList = ((RestrictAppTip) tip).mRestrictAppList;
    107         }
    108     }
    109 
    110     @Override
    111     public void log(Context context, MetricsFeatureProvider metricsFeatureProvider) {
    112         metricsFeatureProvider.action(context, MetricsProto.MetricsEvent.ACTION_APP_RESTRICTION_TIP,
    113                 mState);
    114         if (mState == StateType.NEW) {
    115             for (int i = 0, size = mRestrictAppList.size(); i < size; i++) {
    116                 final AppInfo appInfo = mRestrictAppList.get(i);
    117                 for (Integer anomalyType : appInfo.anomalyTypes) {
    118                     metricsFeatureProvider.action(context,
    119                             MetricsProto.MetricsEvent.ACTION_APP_RESTRICTION_TIP_LIST,
    120                             appInfo.packageName,
    121                             Pair.create(MetricsProto.MetricsEvent.FIELD_ANOMALY_TYPE, anomalyType));
    122                 }
    123 
    124             }
    125         }
    126     }
    127 
    128     public List<AppInfo> getRestrictAppList() {
    129         return mRestrictAppList;
    130     }
    131 
    132     /**
    133      * Construct the app list string(e.g. app1, app2, and app3)
    134      */
    135     public CharSequence getRestrictAppsString(Context context) {
    136         final List<CharSequence> appLabels = new ArrayList<>();
    137         for (int i = 0, size = mRestrictAppList.size(); i < size; i++) {
    138             appLabels.add(Utils.getApplicationLabel(context,
    139                     mRestrictAppList.get(i).packageName));
    140         }
    141 
    142         return ListFormatter.getInstance().format(appLabels);
    143     }
    144 
    145     @Override
    146     public String toString() {
    147         final StringBuilder stringBuilder = new StringBuilder(super.toString());
    148         stringBuilder.append(" {");
    149         for (int i = 0, size = mRestrictAppList.size(); i < size; i++) {
    150             final AppInfo appInfo = mRestrictAppList.get(i);
    151             stringBuilder.append(" " + appInfo.toString() + " ");
    152         }
    153         stringBuilder.append('}');
    154 
    155         return stringBuilder.toString();
    156     }
    157 
    158     @Override
    159     public void writeToParcel(Parcel dest, int flags) {
    160         super.writeToParcel(dest, flags);
    161         dest.writeTypedList(mRestrictAppList);
    162     }
    163 
    164     public static final Creator CREATOR = new Creator() {
    165         public BatteryTip createFromParcel(Parcel in) {
    166             return new RestrictAppTip(in);
    167         }
    168 
    169         public BatteryTip[] newArray(int size) {
    170             return new RestrictAppTip[size];
    171         }
    172     };
    173 }
    174