1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 package com.android.settings.fuelgauge; 17 18 import android.content.Context; 19 import android.content.Intent; 20 import android.os.BatteryManager; 21 import android.os.PowerManager; 22 import android.util.Log; 23 24 import androidx.annotation.VisibleForTesting; 25 import androidx.preference.PreferenceScreen; 26 27 import com.android.settings.R; 28 import com.android.settings.core.BasePreferenceController; 29 import com.android.settings.core.PreferenceControllerMixin; 30 import com.android.settings.fuelgauge.batterytip.tips.BatteryTip; 31 import com.android.settings.overlay.FeatureFactory; 32 import com.android.settingslib.Utils; 33 import com.android.settingslib.widget.UsageProgressBarPreference; 34 35 /** Controller that update the battery header view */ 36 public class BatteryHeaderPreferenceController extends BasePreferenceController 37 implements PreferenceControllerMixin, BatteryPreferenceController { 38 private static final String TAG = "BatteryHeaderPreferenceController"; 39 40 @VisibleForTesting static final String KEY_BATTERY_HEADER = "battery_header"; 41 private static final int BATTERY_MAX_LEVEL = 100; 42 43 @VisibleForTesting BatteryStatusFeatureProvider mBatteryStatusFeatureProvider; 44 @VisibleForTesting UsageProgressBarPreference mBatteryUsageProgressBarPref; 45 46 private final PowerManager mPowerManager; 47 private final BatterySettingsFeatureProvider mBatterySettingsFeatureProvider; 48 49 private BatteryTip mBatteryTip; 50 BatteryHeaderPreferenceController(Context context, String key)51 public BatteryHeaderPreferenceController(Context context, String key) { 52 super(context, key); 53 mPowerManager = context.getSystemService(PowerManager.class); 54 mBatteryStatusFeatureProvider = 55 FeatureFactory.getFeatureFactory().getBatteryStatusFeatureProvider(); 56 mBatterySettingsFeatureProvider = 57 FeatureFactory.getFeatureFactory().getBatterySettingsFeatureProvider(); 58 } 59 60 @Override displayPreference(PreferenceScreen screen)61 public void displayPreference(PreferenceScreen screen) { 62 super.displayPreference(screen); 63 mBatteryUsageProgressBarPref = screen.findPreference(getPreferenceKey()); 64 // Set up empty space text first to prevent layout flaky before info loaded. 65 mBatteryUsageProgressBarPref.setBottomSummary(" "); 66 67 if (com.android.settings.Utils.isBatteryPresent(mContext)) { 68 quickUpdateHeaderPreference(); 69 } else { 70 mBatteryUsageProgressBarPref.setVisible(false); 71 } 72 } 73 74 @Override getAvailabilityStatus()75 public int getAvailabilityStatus() { 76 return AVAILABLE_UNSEARCHABLE; 77 } 78 generateLabel(BatteryInfo info)79 private CharSequence generateLabel(BatteryInfo info) { 80 if (Utils.containsIncompatibleChargers(mContext, TAG)) { 81 return mContext.getString( 82 com.android.settingslib.R.string.battery_info_status_not_charging); 83 } 84 if (BatteryUtils.isBatteryDefenderOn(info)) { 85 return mContext.getString( 86 com.android.settingslib.R.string.battery_info_status_charging_on_hold); 87 } 88 if (info.remainingLabel != null 89 && mBatterySettingsFeatureProvider.isChargingOptimizationMode(mContext)) { 90 return info.remainingLabel; 91 } 92 if (info.remainingLabel == null 93 || info.batteryStatus == BatteryManager.BATTERY_STATUS_NOT_CHARGING) { 94 return info.statusLabel; 95 } 96 if (info.pluggedStatus == BatteryManager.BATTERY_PLUGGED_WIRELESS) { 97 final CharSequence wirelessChargingLabel = 98 mBatterySettingsFeatureProvider.getWirelessChargingLabel(mContext, info); 99 if (wirelessChargingLabel != null) { 100 mBatteryUsageProgressBarPref.setBottomSummaryContentDescription( 101 mBatterySettingsFeatureProvider 102 .getWirelessChargingContentDescription(mContext, info)); 103 return wirelessChargingLabel; 104 } 105 } 106 if (info.statusLabel != null && !info.discharging) { 107 // Charging state 108 if (com.android.settingslib.fuelgauge.BatteryUtils.isChargingStringV2Enabled()) { 109 return info.isFastCharging 110 ? mContext.getString( 111 R.string.battery_state_and_duration, 112 info.statusLabel, 113 info.remainingLabel) 114 : info.remainingLabel; 115 } 116 return mContext.getString( 117 R.string.battery_state_and_duration, info.statusLabel, info.remainingLabel); 118 } else if (mPowerManager.isPowerSaveMode()) { 119 // Power save mode is on 120 final String powerSaverOn = 121 mContext.getString(R.string.battery_tip_early_heads_up_done_title); 122 return mContext.getString( 123 R.string.battery_state_and_duration, powerSaverOn, info.remainingLabel); 124 } else if (mBatteryTip != null && mBatteryTip.getType() == BatteryTip.TipType.LOW_BATTERY) { 125 // Low battery state 126 final String lowBattery = mContext.getString(R.string.low_battery_summary); 127 return mContext.getString( 128 R.string.battery_state_and_duration, lowBattery, info.remainingLabel); 129 } else { 130 // Discharging state 131 return info.remainingLabel; 132 } 133 } 134 updateHeaderPreference(BatteryInfo info)135 public void updateHeaderPreference(BatteryInfo info) { 136 if (!mBatteryStatusFeatureProvider.triggerBatteryStatusUpdate(this, info)) { 137 mBatteryUsageProgressBarPref.setBottomSummary(generateLabel(info)); 138 } 139 140 mBatteryUsageProgressBarPref.setUsageSummary( 141 formatBatteryPercentageText(info.batteryLevel)); 142 mBatteryUsageProgressBarPref.setPercent(info.batteryLevel, BATTERY_MAX_LEVEL); 143 } 144 145 /** Callback which receives text for the summary line. */ updateBatteryStatus(String label, BatteryInfo info)146 public void updateBatteryStatus(String label, BatteryInfo info) { 147 final CharSequence summary = label != null ? label : generateLabel(info); 148 mBatteryUsageProgressBarPref.setBottomSummary(summary); 149 Log.d(TAG, "updateBatteryStatus: " + label + " summary: " + summary); 150 } 151 quickUpdateHeaderPreference()152 public void quickUpdateHeaderPreference() { 153 Intent batteryBroadcast = 154 com.android.settingslib.fuelgauge.BatteryUtils.getBatteryIntent(mContext); 155 final int batteryLevel = Utils.getBatteryLevel(batteryBroadcast); 156 final boolean discharging = 157 batteryBroadcast.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1) == 0; 158 159 mBatteryUsageProgressBarPref.setUsageSummary(formatBatteryPercentageText(batteryLevel)); 160 mBatteryUsageProgressBarPref.setPercent(batteryLevel, BATTERY_MAX_LEVEL); 161 } 162 163 /** Update summary when battery tips changed. */ updateHeaderByBatteryTips(BatteryTip batteryTip, BatteryInfo batteryInfo)164 public void updateHeaderByBatteryTips(BatteryTip batteryTip, BatteryInfo batteryInfo) { 165 mBatteryTip = batteryTip; 166 167 if (mBatteryTip != null && batteryInfo != null) { 168 updateHeaderPreference(batteryInfo); 169 } 170 } 171 formatBatteryPercentageText(int batteryLevel)172 private CharSequence formatBatteryPercentageText(int batteryLevel) { 173 return com.android.settings.Utils.formatPercentage(batteryLevel); 174 } 175 } 176