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.batterytip.tips; 18 19 import android.content.Context; 20 import android.os.Parcel; 21 import android.os.Parcelable; 22 import android.util.SparseIntArray; 23 import android.view.View; 24 25 import androidx.annotation.IdRes; 26 import androidx.annotation.IntDef; 27 import androidx.annotation.VisibleForTesting; 28 import androidx.preference.Preference; 29 30 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; 31 32 import java.lang.annotation.Retention; 33 import java.lang.annotation.RetentionPolicy; 34 35 /** 36 * Base model for a battery tip(e.g. suggest user to turn on battery saver) 37 * 38 * Each {@link BatteryTip} contains basic data(e.g. title, summary, icon) as well as the 39 * pre-defined action(e.g. turn on battery saver) 40 */ 41 public abstract class BatteryTip implements Comparable<BatteryTip>, Parcelable { 42 @Retention(RetentionPolicy.SOURCE) 43 @IntDef({StateType.NEW, 44 StateType.HANDLED, 45 StateType.INVISIBLE}) 46 public @interface StateType { 47 int NEW = 0; 48 int HANDLED = 1; 49 int INVISIBLE = 2; 50 } 51 52 @Retention(RetentionPolicy.SOURCE) 53 @IntDef({TipType.SUMMARY, 54 TipType.BATTERY_SAVER, 55 TipType.HIGH_DEVICE_USAGE, 56 TipType.SMART_BATTERY_MANAGER, 57 TipType.APP_RESTRICTION, 58 TipType.REDUCED_BATTERY, 59 TipType.LOW_BATTERY, 60 TipType.REMOVE_APP_RESTRICTION, 61 TipType.BATTERY_DEFENDER, 62 TipType.DOCK_DEFENDER}) 63 public @interface TipType { 64 int SMART_BATTERY_MANAGER = 0; 65 int APP_RESTRICTION = 1; 66 int HIGH_DEVICE_USAGE = 2; 67 int BATTERY_SAVER = 3; 68 int REDUCED_BATTERY = 4; 69 int LOW_BATTERY = 5; 70 int SUMMARY = 6; 71 int REMOVE_APP_RESTRICTION = 7; 72 int BATTERY_DEFENDER = 8; 73 int DOCK_DEFENDER = 9; 74 } 75 76 @VisibleForTesting 77 static final SparseIntArray TIP_ORDER; 78 static { 79 TIP_ORDER = new SparseIntArray(); TIP_ORDER.append(TipType.BATTERY_SAVER, 0)80 TIP_ORDER.append(TipType.BATTERY_SAVER, 0); TIP_ORDER.append(TipType.LOW_BATTERY, 1)81 TIP_ORDER.append(TipType.LOW_BATTERY, 1); TIP_ORDER.append(TipType.BATTERY_DEFENDER, 2)82 TIP_ORDER.append(TipType.BATTERY_DEFENDER, 2); TIP_ORDER.append(TipType.DOCK_DEFENDER, 3)83 TIP_ORDER.append(TipType.DOCK_DEFENDER, 3); TIP_ORDER.append(TipType.APP_RESTRICTION, 4)84 TIP_ORDER.append(TipType.APP_RESTRICTION, 4); TIP_ORDER.append(TipType.HIGH_DEVICE_USAGE, 5)85 TIP_ORDER.append(TipType.HIGH_DEVICE_USAGE, 5); TIP_ORDER.append(TipType.SUMMARY, 6)86 TIP_ORDER.append(TipType.SUMMARY, 6); TIP_ORDER.append(TipType.SMART_BATTERY_MANAGER, 7)87 TIP_ORDER.append(TipType.SMART_BATTERY_MANAGER, 7); TIP_ORDER.append(TipType.REDUCED_BATTERY, 8)88 TIP_ORDER.append(TipType.REDUCED_BATTERY, 8); TIP_ORDER.append(TipType.REMOVE_APP_RESTRICTION, 9)89 TIP_ORDER.append(TipType.REMOVE_APP_RESTRICTION, 9); 90 } 91 92 private static final String KEY_PREFIX = "key_battery_tip"; 93 94 protected int mType; 95 protected int mState; 96 protected boolean mShowDialog; 97 /** 98 * Whether we need to update battery tip when configuration change 99 */ 100 protected boolean mNeedUpdate; 101 BatteryTip(Parcel in)102 BatteryTip(Parcel in) { 103 mType = in.readInt(); 104 mState = in.readInt(); 105 mShowDialog = in.readBoolean(); 106 mNeedUpdate = in.readBoolean(); 107 } 108 BatteryTip(int type, int state, boolean showDialog)109 BatteryTip(int type, int state, boolean showDialog) { 110 mType = type; 111 mState = state; 112 mShowDialog = showDialog; 113 mNeedUpdate = true; 114 } 115 116 @Override describeContents()117 public int describeContents() { 118 return 0; 119 } 120 121 @Override writeToParcel(Parcel dest, int flags)122 public void writeToParcel(Parcel dest, int flags) { 123 dest.writeInt(mType); 124 dest.writeInt(mState); 125 dest.writeBoolean(mShowDialog); 126 dest.writeBoolean(mNeedUpdate); 127 } 128 getTitle(Context context)129 public abstract CharSequence getTitle(Context context); 130 getSummary(Context context)131 public abstract CharSequence getSummary(Context context); 132 133 @IdRes getIconId()134 public abstract int getIconId(); 135 136 /** 137 * Update the current {@link #mState} using the new {@code tip}. 138 * 139 * @param tip used to update 140 */ updateState(BatteryTip tip)141 public abstract void updateState(BatteryTip tip); 142 143 /** 144 * Check whether data is still make sense. If not, try recover. 145 * @param context used to do validate check 146 */ validateCheck(Context context)147 public void validateCheck(Context context) { 148 // do nothing 149 } 150 151 /** 152 * Log the battery tip 153 */ log(Context context, MetricsFeatureProvider metricsFeatureProvider)154 public abstract void log(Context context, MetricsFeatureProvider metricsFeatureProvider); 155 updatePreference(Preference preference)156 public void updatePreference(Preference preference) { 157 final Context context = preference.getContext(); 158 preference.setTitle(getTitle(context)); 159 preference.setSummary(getSummary(context)); 160 preference.setIcon(getIconId()); 161 @IdRes int iconTintColorId = getIconTintColorId(); 162 if (iconTintColorId != View.NO_ID) { 163 preference.getIcon().setTint(context.getColor(iconTintColorId)); 164 } 165 } 166 167 /** Returns the color resid for tinting {@link #getIconId()} or {@link View#NO_ID} if none. */ getIconTintColorId()168 public @IdRes int getIconTintColorId() { 169 return View.NO_ID; 170 } 171 shouldShowDialog()172 public boolean shouldShowDialog() { 173 return mShowDialog; 174 } 175 needUpdate()176 public boolean needUpdate() { 177 return mNeedUpdate; 178 } 179 getKey()180 public String getKey() { 181 return KEY_PREFIX + mType; 182 } 183 getType()184 public int getType() { 185 return mType; 186 } 187 188 @StateType getState()189 public int getState() { 190 return mState; 191 } 192 isVisible()193 public boolean isVisible() { 194 return mState != StateType.INVISIBLE; 195 } 196 197 @Override compareTo(BatteryTip o)198 public int compareTo(BatteryTip o) { 199 return TIP_ORDER.get(mType) - TIP_ORDER.get(o.mType); 200 } 201 202 @Override toString()203 public String toString() { 204 return "type=" + mType + " state=" + mState; 205 } 206 } 207