• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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;
18 
19 import android.content.Context;
20 import android.os.BatteryManager;
21 import android.os.PowerManager;
22 import android.util.Log;
23 
24 import androidx.annotation.NonNull;
25 import androidx.annotation.Nullable;
26 import androidx.annotation.VisibleForTesting;
27 import androidx.preference.PreferenceScreen;
28 
29 import com.android.settings.R;
30 import com.android.settings.core.BasePreferenceController;
31 import com.android.settings.core.PreferenceControllerMixin;
32 import com.android.settings.fuelgauge.batterytip.tips.BatteryTip;
33 import com.android.settings.overlay.FeatureFactory;
34 import com.android.settingslib.Utils;
35 
36 /** Controller that update the battery header view */
37 public class BatteryHeaderTextPreferenceController extends BasePreferenceController
38         implements PreferenceControllerMixin, BatteryPreferenceController {
39     private static final String TAG = "BatteryHeaderTextPreferenceController";
40 
41     private final PowerManager mPowerManager;
42     private final BatterySettingsFeatureProvider mBatterySettingsFeatureProvider;
43 
44     @Nullable private BatteryTip mBatteryTip;
45 
46     @VisibleForTesting BatteryStatusFeatureProvider mBatteryStatusFeatureProvider;
47 
48     @Nullable @VisibleForTesting BatteryHeaderTextPreference mBatteryHeaderTextPreference;
49 
BatteryHeaderTextPreferenceController(Context context, String key)50     public BatteryHeaderTextPreferenceController(Context context, String key) {
51         super(context, key);
52         mPowerManager = context.getSystemService(PowerManager.class);
53         mBatteryStatusFeatureProvider =
54                 FeatureFactory.getFeatureFactory().getBatteryStatusFeatureProvider();
55         mBatterySettingsFeatureProvider =
56                 FeatureFactory.getFeatureFactory().getBatterySettingsFeatureProvider();
57     }
58 
59     @Override
displayPreference(PreferenceScreen screen)60     public void displayPreference(PreferenceScreen screen) {
61         super.displayPreference(screen);
62         mBatteryHeaderTextPreference = screen.findPreference(getPreferenceKey());
63 
64         if (mBatteryHeaderTextPreference != null
65                 && !com.android.settings.Utils.isBatteryPresent(mContext)) {
66             mBatteryHeaderTextPreference.setVisible(false);
67         }
68     }
69 
70     @Override
getAvailabilityStatus()71     public int getAvailabilityStatus() {
72         return AVAILABLE_UNSEARCHABLE;
73     }
74 
75     @NonNull
generateLabel(@onNull BatteryInfo info)76     private CharSequence generateLabel(@NonNull BatteryInfo info) {
77         if (Utils.containsIncompatibleChargers(mContext, TAG)) {
78             return mContext.getString(
79                     com.android.settingslib.R.string.battery_info_status_not_charging);
80         }
81         if (BatteryUtils.isBatteryDefenderOn(info)
82                 || FeatureFactory.getFeatureFactory()
83                         .getPowerUsageFeatureProvider()
84                         .isExtraDefend()) {
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(
90                         mContext, info.isLongLife)) {
91             return info.remainingLabel;
92         }
93         if (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 (mBatteryHeaderTextPreference != null && wirelessChargingLabel != null) {
100                 mBatteryHeaderTextPreference.setContentDescription(
101                         mBatterySettingsFeatureProvider.getWirelessChargingContentDescription(
102                                 mContext, info));
103                 return wirelessChargingLabel;
104             }
105         }
106         if (info.remainingLabel == null) {
107             return info.statusLabel;
108         }
109         if (info.statusLabel != null && !info.discharging) {
110             // Charging state
111             if (com.android.settingslib.fuelgauge.BatteryUtils.isChargingStringV2Enabled()) {
112                 return info.isFastCharging
113                         ? mContext.getString(
114                                 R.string.battery_state_and_duration,
115                                 info.statusLabel,
116                                 info.remainingLabel)
117                         : info.remainingLabel;
118             }
119             return mContext.getString(
120                     R.string.battery_state_and_duration, info.statusLabel, info.remainingLabel);
121         } else if (mPowerManager.isPowerSaveMode()) {
122             // Power save mode is on
123             final String powerSaverOn =
124                     mContext.getString(R.string.battery_tip_early_heads_up_done_title);
125             return mContext.getString(
126                     R.string.battery_state_and_duration, powerSaverOn, info.remainingLabel);
127         } else if (mBatteryTip != null && mBatteryTip.getType() == BatteryTip.TipType.LOW_BATTERY) {
128             // Low battery state
129             final String lowBattery = mContext.getString(R.string.low_battery_summary);
130             return mContext.getString(
131                     R.string.battery_state_and_duration, lowBattery, info.remainingLabel);
132         } else {
133             // Discharging state
134             return info.remainingLabel;
135         }
136     }
137 
138     /** Updates the battery header text with the given BatteryInfo. */
updateHeaderPreference(@onNull BatteryInfo info)139     public void updateHeaderPreference(@NonNull BatteryInfo info) {
140         if (mBatteryHeaderTextPreference != null
141                 && !mBatteryStatusFeatureProvider.triggerBatteryStatusUpdate(this, info)) {
142             mBatteryHeaderTextPreference.setText(generateLabel(info));
143         }
144     }
145 
146     /** Callback which updates the battery header text with the given label. */
147     @Override
updateBatteryStatus(String label, BatteryInfo info)148     public void updateBatteryStatus(String label, BatteryInfo info) {
149         if (mBatteryHeaderTextPreference == null) {
150             return;
151         }
152 
153         final CharSequence summary = label != null ? label : generateLabel(info);
154         mBatteryHeaderTextPreference.setText(summary);
155         Log.d(TAG, "updateBatteryStatus: " + label + " summary: " + summary);
156     }
157 
158     /** Update summary when battery tips are changed. */
updateHeaderByBatteryTips( @ullable BatteryTip batteryTip, @NonNull BatteryInfo batteryInfo)159     public void updateHeaderByBatteryTips(
160             @Nullable BatteryTip batteryTip, @NonNull BatteryInfo batteryInfo) {
161         mBatteryTip = batteryTip;
162 
163         if (mBatteryTip != null && batteryInfo != null) {
164             updateHeaderPreference(batteryInfo);
165         }
166     }
167 }
168