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.icu.text.ListFormatter; 22 import android.os.Parcel; 23 import android.util.ArrayMap; 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 import com.android.settingslib.utils.StringUtil; 32 33 import java.util.ArrayList; 34 import java.util.List; 35 import java.util.Map; 36 37 /** Tip to suggest user to restrict some bad apps */ 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 = 64 num > 0 65 ? Utils.getApplicationLabel(context, mRestrictAppList.get(0).packageName) 66 : ""; 67 68 Map<String, Object> arguments = new ArrayMap<>(); 69 arguments.put("count", num); 70 arguments.put("label", appLabel); 71 return mState == StateType.HANDLED 72 ? StringUtil.getIcuPluralsString( 73 context, arguments, R.string.battery_tip_restrict_handled_title) 74 : StringUtil.getIcuPluralsString( 75 context, arguments, R.string.battery_tip_restrict_title); 76 } 77 78 @Override getSummary(Context context)79 public CharSequence getSummary(Context context) { 80 final int num = mRestrictAppList.size(); 81 final CharSequence appLabel = 82 num > 0 83 ? Utils.getApplicationLabel(context, mRestrictAppList.get(0).packageName) 84 : ""; 85 final int resId = 86 mState == StateType.HANDLED 87 ? R.string.battery_tip_restrict_handled_summary 88 : R.string.battery_tip_restrict_summary; 89 Map<String, Object> arguments = new ArrayMap<>(); 90 arguments.put("count", num); 91 arguments.put("label", appLabel); 92 return StringUtil.getIcuPluralsString(context, arguments, resId); 93 } 94 95 @Override getIconId()96 public int getIconId() { 97 return mState == StateType.HANDLED 98 ? R.drawable.ic_perm_device_information_theme 99 : R.drawable.ic_battery_alert_theme; 100 } 101 102 @Override updateState(BatteryTip tip)103 public void updateState(BatteryTip tip) { 104 if (tip.mState == StateType.NEW) { 105 // Display it if new anomaly comes 106 mState = StateType.NEW; 107 mRestrictAppList = ((RestrictAppTip) tip).mRestrictAppList; 108 mShowDialog = true; 109 } else if (mState == StateType.NEW && tip.mState == StateType.INVISIBLE) { 110 // If anomaly becomes invisible, show it as handled 111 mState = StateType.HANDLED; 112 mShowDialog = false; 113 } else { 114 mState = tip.getState(); 115 mShowDialog = tip.shouldShowDialog(); 116 mRestrictAppList = ((RestrictAppTip) tip).mRestrictAppList; 117 } 118 } 119 120 @Override validateCheck(Context context)121 public void validateCheck(Context context) { 122 super.validateCheck(context); 123 124 // Set it invisible if there is no valid app 125 mRestrictAppList.removeIf(AppLabelPredicate.getInstance(context)); 126 if (mRestrictAppList.isEmpty()) { 127 mState = StateType.INVISIBLE; 128 } 129 } 130 131 @Override log(Context context, MetricsFeatureProvider metricsFeatureProvider)132 public void log(Context context, MetricsFeatureProvider metricsFeatureProvider) { 133 metricsFeatureProvider.action(context, SettingsEnums.ACTION_APP_RESTRICTION_TIP, mState); 134 if (mState == StateType.NEW) { 135 for (int i = 0, size = mRestrictAppList.size(); i < size; i++) { 136 final AppInfo appInfo = mRestrictAppList.get(i); 137 for (Integer anomalyType : appInfo.anomalyTypes) { 138 metricsFeatureProvider.action( 139 SettingsEnums.PAGE_UNKNOWN, 140 SettingsEnums.ACTION_APP_RESTRICTION_TIP_LIST, 141 SettingsEnums.PAGE_UNKNOWN, 142 appInfo.packageName, 143 anomalyType); 144 } 145 } 146 } 147 } 148 getRestrictAppList()149 public List<AppInfo> getRestrictAppList() { 150 return mRestrictAppList; 151 } 152 153 /** Construct the app list string(e.g. app1, app2, and app3) */ getRestrictAppsString(Context context)154 public CharSequence getRestrictAppsString(Context context) { 155 final List<CharSequence> appLabels = new ArrayList<>(); 156 for (int i = 0, size = mRestrictAppList.size(); i < size; i++) { 157 appLabels.add(Utils.getApplicationLabel(context, mRestrictAppList.get(i).packageName)); 158 } 159 160 return ListFormatter.getInstance().format(appLabels); 161 } 162 163 @Override toString()164 public String toString() { 165 final StringBuilder stringBuilder = new StringBuilder(super.toString()); 166 stringBuilder.append(" {"); 167 for (int i = 0, size = mRestrictAppList.size(); i < size; i++) { 168 final AppInfo appInfo = mRestrictAppList.get(i); 169 stringBuilder.append(" " + appInfo.toString() + " "); 170 } 171 stringBuilder.append('}'); 172 173 return stringBuilder.toString(); 174 } 175 176 @Override writeToParcel(Parcel dest, int flags)177 public void writeToParcel(Parcel dest, int flags) { 178 super.writeToParcel(dest, flags); 179 dest.writeTypedList(mRestrictAppList); 180 } 181 182 public static final Creator CREATOR = 183 new Creator() { 184 public BatteryTip createFromParcel(Parcel in) { 185 return new RestrictAppTip(in); 186 } 187 188 public BatteryTip[] newArray(int size) { 189 return new RestrictAppTip[size]; 190 } 191 }; 192 } 193