1 /* 2 * Copyright (C) 2023 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.batteryusage; 18 19 import android.content.Context; 20 import android.os.Bundle; 21 import android.text.TextUtils; 22 import android.util.Pair; 23 24 import com.android.settings.R; 25 import com.android.settings.SettingsActivity; 26 import com.android.settings.core.SubSettingLauncher; 27 28 import java.util.function.Function; 29 30 final class AnomalyEventWrapper { 31 private static final String TAG = "AnomalyEventWrapper"; 32 33 private final Context mContext; 34 private final PowerAnomalyEvent mPowerAnomalyEvent; 35 36 private final int mCardStyleId; 37 private final int mResourceIndex; 38 39 private SubSettingLauncher mSubSettingLauncher = null; 40 private Pair<Integer, Integer> mHighlightSlotPair = null; 41 private BatteryDiffEntry mRelatedBatteryDiffEntry = null; 42 AnomalyEventWrapper(Context context, PowerAnomalyEvent powerAnomalyEvent)43 AnomalyEventWrapper(Context context, PowerAnomalyEvent powerAnomalyEvent) { 44 mContext = context; 45 mPowerAnomalyEvent = powerAnomalyEvent; 46 // Set basic battery tips card info 47 mCardStyleId = mPowerAnomalyEvent.getType().getNumber(); 48 mResourceIndex = mPowerAnomalyEvent.getKey().getNumber(); 49 } 50 getInfo(Function<WarningBannerInfo, T> warningBannerInfoSupplier, Function<WarningItemInfo, T> warningItemInfoSupplier)51 private <T> T getInfo(Function<WarningBannerInfo, T> warningBannerInfoSupplier, 52 Function<WarningItemInfo, T> warningItemInfoSupplier) { 53 if (warningBannerInfoSupplier != null && mPowerAnomalyEvent.hasWarningBannerInfo()) { 54 return warningBannerInfoSupplier.apply(mPowerAnomalyEvent.getWarningBannerInfo()); 55 } else if (warningItemInfoSupplier != null && mPowerAnomalyEvent.hasWarningItemInfo()) { 56 return warningItemInfoSupplier.apply(mPowerAnomalyEvent.getWarningItemInfo()); 57 } 58 return null; 59 } 60 getResourceId(int resourceId, int resourceIndex, String defType)61 private int getResourceId(int resourceId, int resourceIndex, String defType) { 62 final String key = getStringFromArrayResource(resourceId, resourceIndex); 63 return TextUtils.isEmpty(key) ? 0 64 : mContext.getResources().getIdentifier(key, defType, mContext.getPackageName()); 65 } 66 getString(Function<WarningBannerInfo, String> warningBannerInfoSupplier, Function<WarningItemInfo, String> warningItemInfoSupplier, int resourceId, int resourceIndex)67 private String getString(Function<WarningBannerInfo, String> warningBannerInfoSupplier, 68 Function<WarningItemInfo, String> warningItemInfoSupplier, 69 int resourceId, int resourceIndex) { 70 final String string = getInfo(warningBannerInfoSupplier, warningItemInfoSupplier); 71 return (!TextUtils.isEmpty(string) || resourceId <= 0) ? string 72 : getStringFromArrayResource(resourceId, resourceIndex); 73 } 74 getStringFromArrayResource(int resourceId, int resourceIndex)75 private String getStringFromArrayResource(int resourceId, int resourceIndex) { 76 if (resourceId <= 0 || resourceIndex < 0) { 77 return null; 78 } 79 final String[] stringArray = mContext.getResources().getStringArray(resourceId); 80 return (resourceIndex >= 0 && resourceIndex < stringArray.length) 81 ? stringArray[resourceIndex] : null; 82 } 83 setRelatedBatteryDiffEntry(BatteryDiffEntry batteryDiffEntry)84 void setRelatedBatteryDiffEntry(BatteryDiffEntry batteryDiffEntry) { 85 mRelatedBatteryDiffEntry = batteryDiffEntry; 86 } 87 getEventId()88 String getEventId() { 89 return mPowerAnomalyEvent.hasEventId() ? mPowerAnomalyEvent.getEventId() : null; 90 } 91 getIconResId()92 int getIconResId() { 93 return getResourceId(R.array.battery_tips_card_icons, mCardStyleId, "drawable"); 94 } 95 getColorResId()96 int getColorResId() { 97 return getResourceId(R.array.battery_tips_card_colors, mCardStyleId, "color"); 98 } 99 getTitleString()100 String getTitleString() { 101 final String protoTitleString = getInfo(WarningBannerInfo::getTitleString, 102 WarningItemInfo::getTitleString); 103 if (!TextUtils.isEmpty(protoTitleString)) { 104 return protoTitleString; 105 } 106 final int titleFormatResId = getResourceId(R.array.power_anomaly_title_ids, 107 mResourceIndex, "string"); 108 if (mPowerAnomalyEvent.hasWarningBannerInfo()) { 109 return mContext.getString(titleFormatResId); 110 } else if (mPowerAnomalyEvent.hasWarningItemInfo() && mRelatedBatteryDiffEntry != null) { 111 final String appLabel = mRelatedBatteryDiffEntry.getAppLabel(); 112 return mContext.getString(titleFormatResId, appLabel); 113 } 114 return null; 115 } 116 getMainBtnString()117 String getMainBtnString() { 118 return getString(WarningBannerInfo::getMainButtonString, 119 WarningItemInfo::getMainButtonString, 120 R.array.power_anomaly_main_btn_strings, mResourceIndex); 121 } 122 getDismissBtnString()123 String getDismissBtnString() { 124 return getString(WarningBannerInfo::getCancelButtonString, 125 WarningItemInfo::getCancelButtonString, 126 R.array.power_anomaly_dismiss_btn_strings, mResourceIndex); 127 } 128 getAnomalyHintString()129 String getAnomalyHintString() { 130 return getStringFromArrayResource(R.array.power_anomaly_hint_messages, mResourceIndex); 131 } 132 getDismissRecordKey()133 String getDismissRecordKey() { 134 return mPowerAnomalyEvent.getDismissRecordKey(); 135 } 136 hasAnomalyEntryKey()137 boolean hasAnomalyEntryKey() { 138 return getAnomalyEntryKey() != null; 139 } 140 getAnomalyEntryKey()141 String getAnomalyEntryKey() { 142 return mPowerAnomalyEvent.hasWarningItemInfo() 143 && mPowerAnomalyEvent.getWarningItemInfo().hasItemKey() 144 ? mPowerAnomalyEvent.getWarningItemInfo().getItemKey() : null; 145 } 146 hasSubSettingLauncher()147 boolean hasSubSettingLauncher() { 148 if (mSubSettingLauncher == null) { 149 mSubSettingLauncher = getSubSettingLauncher(); 150 } 151 return mSubSettingLauncher != null; 152 } 153 getSubSettingLauncher()154 SubSettingLauncher getSubSettingLauncher() { 155 if (mSubSettingLauncher != null) { 156 return mSubSettingLauncher; 157 } 158 final String destinationClassName = getInfo( 159 WarningBannerInfo::getMainButtonDestination, null); 160 if (!TextUtils.isEmpty(destinationClassName)) { 161 final Integer sourceMetricsCategory = getInfo( 162 WarningBannerInfo::getMainButtonSourceMetricsCategory, null); 163 final String preferenceHighlightKey = getInfo( 164 WarningBannerInfo::getMainButtonSourceHighlightKey, null); 165 Bundle arguments = Bundle.EMPTY; 166 if (!TextUtils.isEmpty(preferenceHighlightKey)) { 167 arguments = new Bundle(1); 168 arguments.putString(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY, 169 preferenceHighlightKey); 170 } 171 mSubSettingLauncher = new SubSettingLauncher(mContext) 172 .setDestination(destinationClassName) 173 .setSourceMetricsCategory(sourceMetricsCategory) 174 .setArguments(arguments); 175 } 176 return mSubSettingLauncher; 177 } 178 hasHighlightSlotPair(BatteryLevelData batteryLevelData)179 boolean hasHighlightSlotPair(BatteryLevelData batteryLevelData) { 180 if (mHighlightSlotPair == null) { 181 mHighlightSlotPair = getHighlightSlotPair(batteryLevelData); 182 } 183 return mHighlightSlotPair != null; 184 } 185 getHighlightSlotPair(BatteryLevelData batteryLevelData)186 Pair<Integer, Integer> getHighlightSlotPair(BatteryLevelData batteryLevelData) { 187 if (mHighlightSlotPair != null) { 188 return mHighlightSlotPair; 189 } 190 if (!mPowerAnomalyEvent.hasWarningItemInfo()) { 191 return null; 192 } 193 final WarningItemInfo warningItemInfo = mPowerAnomalyEvent.getWarningItemInfo(); 194 final Long startTimestamp = warningItemInfo.hasStartTimestamp() 195 ? warningItemInfo.getStartTimestamp() : null; 196 final Long endTimestamp = warningItemInfo.hasEndTimestamp() 197 ? warningItemInfo.getEndTimestamp() : null; 198 if (startTimestamp != null && endTimestamp != null) { 199 mHighlightSlotPair = batteryLevelData 200 .getIndexByTimestamps(startTimestamp, endTimestamp); 201 if (mHighlightSlotPair.first == BatteryChartViewModel.SELECTED_INDEX_INVALID 202 || mHighlightSlotPair.second == BatteryChartViewModel.SELECTED_INDEX_INVALID) { 203 // Drop invalid mHighlightSlotPair index 204 mHighlightSlotPair = null; 205 } 206 } 207 return mHighlightSlotPair; 208 } 209 updateTipsCardPreference(BatteryTipsCardPreference preference)210 boolean updateTipsCardPreference(BatteryTipsCardPreference preference) { 211 final String titleString = getTitleString(); 212 if (TextUtils.isEmpty(titleString)) { 213 return false; 214 } 215 preference.setTitle(titleString); 216 preference.setIconResourceId(getIconResId()); 217 preference.setMainButtonStrokeColorResourceId(getColorResId()); 218 preference.setMainButtonLabel(getMainBtnString()); 219 preference.setDismissButtonLabel(getDismissBtnString()); 220 return true; 221 } 222 launchSubSetting()223 boolean launchSubSetting() { 224 if (!hasSubSettingLauncher()) { 225 return false; 226 } 227 // Navigate to sub setting page 228 mSubSettingLauncher.launch(); 229 return true; 230 } 231 } 232