| jackqdyulei | 605dbc6 | 2017-05-19 13:29:09 -0700 | [diff] [blame] | 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. |
| jackqdyulei | 605dbc6 | 2017-05-19 13:29:09 -0700 | [diff] [blame] | 14 | */ |
| 15 | |
| 16 | package com.android.settings.fuelgauge; |
| 17 | |
| 18 | import android.content.Context; |
| 19 | import android.content.Intent; |
| jackqdyulei | 1964875 | 2017-06-26 17:54:09 -0700 | [diff] [blame] | 20 | import android.os.BatteryManager; |
| Weien Wang | 27e9617 | 2018-05-21 12:10:11 +0800 | [diff] [blame] | 21 | import android.os.PowerManager; |
| ykhung | c234196 | 2023-05-03 18:03:59 +0800 | [diff] [blame] | 22 | import android.util.Log; |
| jackqdyulei | 605dbc6 | 2017-05-19 13:29:09 -0700 | [diff] [blame] | 23 | |
| Fan Zhang | 23f8d59 | 2018-08-28 15:11:40 -0700 | [diff] [blame] | 24 | import androidx.annotation.VisibleForTesting; |
| Fan Zhang | 23f8d59 | 2018-08-28 15:11:40 -0700 | [diff] [blame] | 25 | import androidx.preference.PreferenceScreen; |
| 26 | |
| jackqdyulei | 605dbc6 | 2017-05-19 13:29:09 -0700 | [diff] [blame] | 27 | import com.android.settings.R; |
| jackqdyulei | 076b674 | 2018-07-24 10:49:05 -0700 | [diff] [blame] | 28 | import com.android.settings.core.BasePreferenceController; |
| Tony Mantler | 1d583e1 | 2017-06-13 13:09:25 -0700 | [diff] [blame] | 29 | import com.android.settings.core.PreferenceControllerMixin; |
| Wesley.CW Wang | 11d74e7 | 2021-04-06 15:14:59 +0800 | [diff] [blame] | 30 | import com.android.settings.fuelgauge.batterytip.tips.BatteryTip; |
| Jeffrey Carlyle | 4e2071a | 2020-05-27 09:28:17 -0700 | [diff] [blame] | 31 | import com.android.settings.overlay.FeatureFactory; |
| jackqdyulei | 605dbc6 | 2017-05-19 13:29:09 -0700 | [diff] [blame] | 32 | import com.android.settingslib.Utils; |
| Wesley.CW Wang | f4bc353 | 2021-02-04 16:44:55 +0800 | [diff] [blame] | 33 | import com.android.settingslib.widget.UsageProgressBarPreference; |
| jackqdyulei | 605dbc6 | 2017-05-19 13:29:09 -0700 | [diff] [blame] | 34 | |
| Jun Lan | cca804e | 2023-11-02 18:55:52 +0800 | [diff] [blame] | 35 | /** Controller that update the battery header view */ |
| jackqdyulei | 076b674 | 2018-07-24 10:49:05 -0700 | [diff] [blame] | 36 | public class BatteryHeaderPreferenceController extends BasePreferenceController |
| Chaohui Wang | 0aca2ff | 2023-08-24 14:01:54 +0800 | [diff] [blame] | 37 | implements PreferenceControllerMixin, BatteryPreferenceController { |
| ykhung | c234196 | 2023-05-03 18:03:59 +0800 | [diff] [blame] | 38 | private static final String TAG = "BatteryHeaderPreferenceController"; |
| 39 | |
| Jun Lan | cca804e | 2023-11-02 18:55:52 +0800 | [diff] [blame] | 40 | @VisibleForTesting static final String KEY_BATTERY_HEADER = "battery_header"; |
| Wesley.CW Wang | f4bc353 | 2021-02-04 16:44:55 +0800 | [diff] [blame] | 41 | private static final int BATTERY_MAX_LEVEL = 100; |
| Fan Zhang | fe23da5 | 2017-06-03 17:17:27 -0700 | [diff] [blame] | 42 | |
| Jun Lan | cca804e | 2023-11-02 18:55:52 +0800 | [diff] [blame] | 43 | @VisibleForTesting BatteryStatusFeatureProvider mBatteryStatusFeatureProvider; |
| 44 | @VisibleForTesting UsageProgressBarPreference mBatteryUsageProgressBarPref; |
| jackqdyulei | 605dbc6 | 2017-05-19 13:29:09 -0700 | [diff] [blame] | 45 | |
| Weien Wang | 27e9617 | 2018-05-21 12:10:11 +0800 | [diff] [blame] | 46 | private final PowerManager mPowerManager; |
| Yiling Chuang | 37a35d5 | 2024-04-15 07:24:59 +0000 | [diff] [blame] | 47 | private final BatterySettingsFeatureProvider mBatterySettingsFeatureProvider; |
| 48 | |
| 49 | private BatteryTip mBatteryTip; |
| Fan Zhang | fe23da5 | 2017-06-03 17:17:27 -0700 | [diff] [blame] | 50 | |
| jackqdyulei | 076b674 | 2018-07-24 10:49:05 -0700 | [diff] [blame] | 51 | public BatteryHeaderPreferenceController(Context context, String key) { |
| 52 | super(context, key); |
| Weien Wang | 27e9617 | 2018-05-21 12:10:11 +0800 | [diff] [blame] | 53 | mPowerManager = context.getSystemService(PowerManager.class); |
| Jun Lan | cca804e | 2023-11-02 18:55:52 +0800 | [diff] [blame] | 54 | mBatteryStatusFeatureProvider = |
| 55 | FeatureFactory.getFeatureFactory().getBatteryStatusFeatureProvider(); |
| Yiling Chuang | 37a35d5 | 2024-04-15 07:24:59 +0000 | [diff] [blame] | 56 | mBatterySettingsFeatureProvider = |
| 57 | FeatureFactory.getFeatureFactory().getBatterySettingsFeatureProvider(); |
| jackqdyulei | 605dbc6 | 2017-05-19 13:29:09 -0700 | [diff] [blame] | 58 | } |
| 59 | |
| 60 | @Override |
| 61 | public void displayPreference(PreferenceScreen screen) { |
| 62 | super.displayPreference(screen); |
| Wesley.CW Wang | f4bc353 | 2021-02-04 16:44:55 +0800 | [diff] [blame] | 63 | mBatteryUsageProgressBarPref = screen.findPreference(getPreferenceKey()); |
| Wesley Wang | 3ceffc3 | 2024-05-15 18:46:31 +0800 | [diff] [blame] | 64 | // Set up empty space text first to prevent layout flaky before info loaded. |
| 65 | mBatteryUsageProgressBarPref.setBottomSummary(" "); |
| jackqdyulei | 605dbc6 | 2017-05-19 13:29:09 -0700 | [diff] [blame] | 66 | |
| Mill Chen | ad99e2e | 2020-10-21 16:32:56 +0800 | [diff] [blame] | 67 | if (com.android.settings.Utils.isBatteryPresent(mContext)) { |
| 68 | quickUpdateHeaderPreference(); |
| 69 | } else { |
| Wesley.CW Wang | 756028a | 2021-04-08 18:01:15 +0800 | [diff] [blame] | 70 | mBatteryUsageProgressBarPref.setVisible(false); |
| Mill Chen | ad99e2e | 2020-10-21 16:32:56 +0800 | [diff] [blame] | 71 | } |
| jackqdyulei | 605dbc6 | 2017-05-19 13:29:09 -0700 | [diff] [blame] | 72 | } |
| 73 | |
| 74 | @Override |
| jackqdyulei | 076b674 | 2018-07-24 10:49:05 -0700 | [diff] [blame] | 75 | public int getAvailabilityStatus() { |
| 76 | return AVAILABLE_UNSEARCHABLE; |
| jackqdyulei | 605dbc6 | 2017-05-19 13:29:09 -0700 | [diff] [blame] | 77 | } |
| 78 | |
| Stephane Lee | b60870c | 2020-11-04 15:21:05 -0800 | [diff] [blame] | 79 | private CharSequence generateLabel(BatteryInfo info) { |
| Yiling Chuang | 7b77729 | 2024-05-06 03:57:22 +0000 | [diff] [blame] | 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 | } |
| Yiling Chuang | 8bcaab7 | 2024-05-09 10:52:30 +0000 | [diff] [blame] | 88 | if (info.remainingLabel != null |
| 89 | && mBatterySettingsFeatureProvider.isChargingOptimizationMode(mContext)) { |
| 90 | return info.remainingLabel; |
| 91 | } |
| Yiling Chuang | 7b77729 | 2024-05-06 03:57:22 +0000 | [diff] [blame] | 92 | if (info.remainingLabel == null |
| 93 | || info.batteryStatus == BatteryManager.BATTERY_STATUS_NOT_CHARGING) { |
| 94 | return info.statusLabel; |
| 95 | } |
| Yiling Chuang | 37a35d5 | 2024-04-15 07:24:59 +0000 | [diff] [blame] | 96 | if (info.pluggedStatus == BatteryManager.BATTERY_PLUGGED_WIRELESS) { |
| 97 | final CharSequence wirelessChargingLabel = |
| 98 | mBatterySettingsFeatureProvider.getWirelessChargingLabel(mContext, info); |
| 99 | if (wirelessChargingLabel != null) { |
| Yiling Chuang | 6dc8193 | 2024-06-06 09:43:43 +0000 | [diff] [blame] | 100 | mBatteryUsageProgressBarPref.setBottomSummaryContentDescription( |
| 101 | mBatterySettingsFeatureProvider |
| 102 | .getWirelessChargingContentDescription(mContext, info)); |
| Yiling Chuang | 37a35d5 | 2024-04-15 07:24:59 +0000 | [diff] [blame] | 103 | return wirelessChargingLabel; |
| 104 | } |
| 105 | } |
| Yiling Chuang | 7b77729 | 2024-05-06 03:57:22 +0000 | [diff] [blame] | 106 | if (info.statusLabel != null && !info.discharging) { |
| Wesley.CW Wang | 11d74e7 | 2021-04-06 15:14:59 +0800 | [diff] [blame] | 107 | // Charging state |
| Pajace Chen | 6f3c97f | 2024-04-06 09:17:59 +0800 | [diff] [blame] | 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 | } |
| Wesley.CW Wang | 11d74e7 | 2021-04-06 15:14:59 +0800 | [diff] [blame] | 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 |
| Jun Lan | cca804e | 2023-11-02 18:55:52 +0800 | [diff] [blame] | 120 | final String powerSaverOn = |
| 121 | mContext.getString(R.string.battery_tip_early_heads_up_done_title); |
| Wesley.CW Wang | 11d74e7 | 2021-04-06 15:14:59 +0800 | [diff] [blame] | 122 | return mContext.getString( |
| 123 | R.string.battery_state_and_duration, powerSaverOn, info.remainingLabel); |
| Jun Lan | cca804e | 2023-11-02 18:55:52 +0800 | [diff] [blame] | 124 | } else if (mBatteryTip != null && mBatteryTip.getType() == BatteryTip.TipType.LOW_BATTERY) { |
| Wesley.CW Wang | 11d74e7 | 2021-04-06 15:14:59 +0800 | [diff] [blame] | 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); |
| Stephane Lee | b60870c | 2020-11-04 15:21:05 -0800 | [diff] [blame] | 129 | } else { |
| Wesley.CW Wang | 11d74e7 | 2021-04-06 15:14:59 +0800 | [diff] [blame] | 130 | // Discharging state |
| Stephane Lee | b60870c | 2020-11-04 15:21:05 -0800 | [diff] [blame] | 131 | return info.remainingLabel; |
| 132 | } |
| 133 | } |
| 134 | |
| jackqdyulei | 605dbc6 | 2017-05-19 13:29:09 -0700 | [diff] [blame] | 135 | public void updateHeaderPreference(BatteryInfo info) { |
| Wesley.CW Wang | d324393 | 2021-04-07 20:00:59 +0800 | [diff] [blame] | 136 | if (!mBatteryStatusFeatureProvider.triggerBatteryStatusUpdate(this, info)) { |
| 137 | mBatteryUsageProgressBarPref.setBottomSummary(generateLabel(info)); |
| 138 | } |
| 139 | |
| Wesley.CW Wang | f4bc353 | 2021-02-04 16:44:55 +0800 | [diff] [blame] | 140 | mBatteryUsageProgressBarPref.setUsageSummary( |
| 141 | formatBatteryPercentageText(info.batteryLevel)); |
| Wesley.CW Wang | f4bc353 | 2021-02-04 16:44:55 +0800 | [diff] [blame] | 142 | mBatteryUsageProgressBarPref.setPercent(info.batteryLevel, BATTERY_MAX_LEVEL); |
| jackqdyulei | 605dbc6 | 2017-05-19 13:29:09 -0700 | [diff] [blame] | 143 | } |
| jackqdyulei | 1964875 | 2017-06-26 17:54:09 -0700 | [diff] [blame] | 144 | |
| Jun Lan | cca804e | 2023-11-02 18:55:52 +0800 | [diff] [blame] | 145 | /** Callback which receives text for the summary line. */ |
| Stephane Lee | b60870c | 2020-11-04 15:21:05 -0800 | [diff] [blame] | 146 | public void updateBatteryStatus(String label, BatteryInfo info) { |
| ykhung | c234196 | 2023-05-03 18:03:59 +0800 | [diff] [blame] | 147 | final CharSequence summary = label != null ? label : generateLabel(info); |
| 148 | mBatteryUsageProgressBarPref.setBottomSummary(summary); |
| 149 | Log.d(TAG, "updateBatteryStatus: " + label + " summary: " + summary); |
| Jeffrey Carlyle | 4e2071a | 2020-05-27 09:28:17 -0700 | [diff] [blame] | 150 | } |
| 151 | |
| jackqdyulei | 1964875 | 2017-06-26 17:54:09 -0700 | [diff] [blame] | 152 | public void quickUpdateHeaderPreference() { |
| Jun Lan | cca804e | 2023-11-02 18:55:52 +0800 | [diff] [blame] | 153 | Intent batteryBroadcast = |
| 154 | com.android.settingslib.fuelgauge.BatteryUtils.getBatteryIntent(mContext); |
| jackqdyulei | 1964875 | 2017-06-26 17:54:09 -0700 | [diff] [blame] | 155 | final int batteryLevel = Utils.getBatteryLevel(batteryBroadcast); |
| 156 | final boolean discharging = |
| 157 | batteryBroadcast.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1) == 0; |
| Jyotiraditya Panda | 7d6af24 | 2024-02-22 22:42:00 +0900 | [diff] [blame^] | 158 | final int chargeCounterUah = |
| 159 | batteryBroadcast.getIntExtra(BatteryManager.EXTRA_CHARGE_COUNTER, -1); |
| jackqdyulei | 1964875 | 2017-06-26 17:54:09 -0700 | [diff] [blame] | 160 | |
| Wesley.CW Wang | f4bc353 | 2021-02-04 16:44:55 +0800 | [diff] [blame] | 161 | mBatteryUsageProgressBarPref.setUsageSummary(formatBatteryPercentageText(batteryLevel)); |
| 162 | mBatteryUsageProgressBarPref.setPercent(batteryLevel, BATTERY_MAX_LEVEL); |
| Jyotiraditya Panda | 7d6af24 | 2024-02-22 22:42:00 +0900 | [diff] [blame^] | 163 | |
| 164 | if (chargeCounterUah != -1) { |
| 165 | int chargeCounter = chargeCounterUah / 1_000; |
| 166 | mBatteryUsageProgressBarPref.setTotalSummary( |
| 167 | formatBatteryChargeCounterText(chargeCounter)); |
| 168 | } |
| Mill Chen | ad99e2e | 2020-10-21 16:32:56 +0800 | [diff] [blame] | 169 | } |
| 170 | |
| Jun Lan | cca804e | 2023-11-02 18:55:52 +0800 | [diff] [blame] | 171 | /** Update summary when battery tips changed. */ |
| Wesley.CW Wang | 11d74e7 | 2021-04-06 15:14:59 +0800 | [diff] [blame] | 172 | public void updateHeaderByBatteryTips(BatteryTip batteryTip, BatteryInfo batteryInfo) { |
| 173 | mBatteryTip = batteryTip; |
| 174 | |
| 175 | if (mBatteryTip != null && batteryInfo != null) { |
| 176 | updateHeaderPreference(batteryInfo); |
| 177 | } |
| 178 | } |
| 179 | |
| jackqdyulei | fd0f48d | 2019-01-02 15:22:55 -0800 | [diff] [blame] | 180 | private CharSequence formatBatteryPercentageText(int batteryLevel) { |
| mxyyiyi | 8ce68ba | 2024-03-20 13:42:57 +0800 | [diff] [blame] | 181 | return com.android.settings.Utils.formatPercentage(batteryLevel); |
| jackqdyulei | 1964875 | 2017-06-26 17:54:09 -0700 | [diff] [blame] | 182 | } |
| Jyotiraditya Panda | 7d6af24 | 2024-02-22 22:42:00 +0900 | [diff] [blame^] | 183 | |
| 184 | private CharSequence formatBatteryChargeCounterText(int chargeCounter) { |
| 185 | return mContext.getString(R.string.battery_charge_counter_summary, chargeCounter); |
| 186 | } |
| jackqdyulei | 605dbc6 | 2017-05-19 13:29:09 -0700 | [diff] [blame] | 187 | } |