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 24 import androidx.annotation.DrawableRes; 25 import androidx.annotation.IntDef; 26 import androidx.annotation.VisibleForTesting; 27 import androidx.preference.Preference; 28 29 import com.android.settings.widget.CardPreference; 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 TipType.INCOMPATIBLE_CHARGER}) 64 public @interface TipType { 65 int SMART_BATTERY_MANAGER = 0; 66 int APP_RESTRICTION = 1; 67 int HIGH_DEVICE_USAGE = 2; 68 int BATTERY_SAVER = 3; 69 int REDUCED_BATTERY = 4; 70 int LOW_BATTERY = 5; 71 int SUMMARY = 6; 72 int REMOVE_APP_RESTRICTION = 7; 73 int BATTERY_DEFENDER = 8; 74 int DOCK_DEFENDER = 9; 75 int INCOMPATIBLE_CHARGER = 10; 76 } 77 78 @VisibleForTesting 79 static final SparseIntArray TIP_ORDER; 80 static { 81 TIP_ORDER = new SparseIntArray(); TIP_ORDER.append(TipType.BATTERY_SAVER, 0)82 TIP_ORDER.append(TipType.BATTERY_SAVER, 0); TIP_ORDER.append(TipType.LOW_BATTERY, 1)83 TIP_ORDER.append(TipType.LOW_BATTERY, 1); TIP_ORDER.append(TipType.BATTERY_DEFENDER, 2)84 TIP_ORDER.append(TipType.BATTERY_DEFENDER, 2); TIP_ORDER.append(TipType.DOCK_DEFENDER, 3)85 TIP_ORDER.append(TipType.DOCK_DEFENDER, 3); TIP_ORDER.append(TipType.INCOMPATIBLE_CHARGER, 4)86 TIP_ORDER.append(TipType.INCOMPATIBLE_CHARGER, 4); TIP_ORDER.append(TipType.APP_RESTRICTION, 5)87 TIP_ORDER.append(TipType.APP_RESTRICTION, 5); TIP_ORDER.append(TipType.HIGH_DEVICE_USAGE, 6)88 TIP_ORDER.append(TipType.HIGH_DEVICE_USAGE, 6); TIP_ORDER.append(TipType.SUMMARY, 7)89 TIP_ORDER.append(TipType.SUMMARY, 7); TIP_ORDER.append(TipType.SMART_BATTERY_MANAGER, 8)90 TIP_ORDER.append(TipType.SMART_BATTERY_MANAGER, 8); TIP_ORDER.append(TipType.REDUCED_BATTERY, 9)91 TIP_ORDER.append(TipType.REDUCED_BATTERY, 9); TIP_ORDER.append(TipType.REMOVE_APP_RESTRICTION, 10)92 TIP_ORDER.append(TipType.REMOVE_APP_RESTRICTION, 10); 93 } 94 95 private static final String KEY_PREFIX = "key_battery_tip"; 96 97 protected int mType; 98 protected int mState; 99 protected boolean mShowDialog; 100 /** 101 * Whether we need to update battery tip when configuration change 102 */ 103 protected boolean mNeedUpdate; 104 BatteryTip(Parcel in)105 BatteryTip(Parcel in) { 106 mType = in.readInt(); 107 mState = in.readInt(); 108 mShowDialog = in.readBoolean(); 109 mNeedUpdate = in.readBoolean(); 110 } 111 BatteryTip(int type, int state, boolean showDialog)112 BatteryTip(int type, int state, boolean showDialog) { 113 mType = type; 114 mState = state; 115 mShowDialog = showDialog; 116 mNeedUpdate = true; 117 } 118 119 @Override describeContents()120 public int describeContents() { 121 return 0; 122 } 123 124 @Override writeToParcel(Parcel dest, int flags)125 public void writeToParcel(Parcel dest, int flags) { 126 dest.writeInt(mType); 127 dest.writeInt(mState); 128 dest.writeBoolean(mShowDialog); 129 dest.writeBoolean(mNeedUpdate); 130 } 131 getTitle(Context context)132 public abstract CharSequence getTitle(Context context); 133 getSummary(Context context)134 public abstract CharSequence getSummary(Context context); 135 136 /** Gets the drawable resource id for the icon. */ 137 @DrawableRes getIconId()138 public abstract int getIconId(); 139 140 /** 141 * Update the current {@link #mState} using the new {@code tip}. 142 * 143 * @param tip used to update 144 */ updateState(BatteryTip tip)145 public abstract void updateState(BatteryTip tip); 146 147 /** 148 * Check whether data is still make sense. If not, try recover. 149 * @param context used to do validate check 150 */ validateCheck(Context context)151 public void validateCheck(Context context) { 152 // do nothing 153 } 154 155 /** 156 * Log the battery tip 157 */ log(Context context, MetricsFeatureProvider metricsFeatureProvider)158 public abstract void log(Context context, MetricsFeatureProvider metricsFeatureProvider); 159 updatePreference(Preference preference)160 public void updatePreference(Preference preference) { 161 final Context context = preference.getContext(); 162 preference.setTitle(getTitle(context)); 163 preference.setSummary(getSummary(context)); 164 preference.setIcon(getIconId()); 165 final CardPreference cardPreference = castToCardPreferenceSafely(preference); 166 if (cardPreference != null) { 167 cardPreference.resetLayoutState(); 168 } 169 } 170 shouldShowDialog()171 public boolean shouldShowDialog() { 172 return mShowDialog; 173 } 174 needUpdate()175 public boolean needUpdate() { 176 return mNeedUpdate; 177 } 178 getKey()179 public String getKey() { 180 return KEY_PREFIX + mType; 181 } 182 getType()183 public int getType() { 184 return mType; 185 } 186 187 @StateType getState()188 public int getState() { 189 return mState; 190 } 191 isVisible()192 public boolean isVisible() { 193 return mState != StateType.INVISIBLE; 194 } 195 196 @Override compareTo(BatteryTip o)197 public int compareTo(BatteryTip o) { 198 return TIP_ORDER.get(mType) - TIP_ORDER.get(o.mType); 199 } 200 201 @Override toString()202 public String toString() { 203 return "type=" + mType + " state=" + mState; 204 } 205 castToCardPreferenceSafely(Preference preference)206 CardPreference castToCardPreferenceSafely(Preference preference) { 207 return preference instanceof CardPreference ? (CardPreference) preference : null; 208 } 209 } 210