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