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