• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.app.Activity;
19 import android.content.Context;
20 import android.content.Intent;
21 import android.content.IntentFilter;
22 import android.icu.text.NumberFormat;
23 import android.os.BatteryManager;
24 import android.os.PowerManager;
25 import android.text.TextUtils;
26 import android.util.Log;
27 
28 import androidx.annotation.VisibleForTesting;
29 import androidx.preference.PreferenceFragmentCompat;
30 import androidx.preference.PreferenceScreen;
31 
32 import com.android.settings.R;
33 import com.android.settings.core.BasePreferenceController;
34 import com.android.settings.core.PreferenceControllerMixin;
35 import com.android.settings.fuelgauge.batterytip.tips.BatteryTip;
36 import com.android.settings.overlay.FeatureFactory;
37 import com.android.settings.widget.EntityHeaderController;
38 import com.android.settingslib.Utils;
39 import com.android.settingslib.core.lifecycle.Lifecycle;
40 import com.android.settingslib.core.lifecycle.LifecycleObserver;
41 import com.android.settingslib.core.lifecycle.events.OnStart;
42 import com.android.settingslib.widget.UsageProgressBarPreference;
43 
44 /**
45  * Controller that update the battery header view
46  */
47 public class BatteryHeaderPreferenceController extends BasePreferenceController
48         implements PreferenceControllerMixin, LifecycleObserver, OnStart,
49         BatteryPreferenceController {
50     private static final String TAG = "BatteryHeaderPreferenceController";
51 
52     @VisibleForTesting
53     static final String KEY_BATTERY_HEADER = "battery_header";
54     private static final int BATTERY_MAX_LEVEL = 100;
55 
56     @VisibleForTesting
57     BatteryStatusFeatureProvider mBatteryStatusFeatureProvider;
58     @VisibleForTesting
59     UsageProgressBarPreference mBatteryUsageProgressBarPref;
60 
61     private Activity mActivity;
62     private PreferenceFragmentCompat mHost;
63     private Lifecycle mLifecycle;
64     private BatteryTip mBatteryTip;
65     private final PowerManager mPowerManager;
66 
BatteryHeaderPreferenceController(Context context, String key)67     public BatteryHeaderPreferenceController(Context context, String key) {
68         super(context, key);
69         mPowerManager = context.getSystemService(PowerManager.class);
70         mBatteryStatusFeatureProvider = FeatureFactory.getFactory(context)
71                 .getBatteryStatusFeatureProvider(context);
72     }
73 
setActivity(Activity activity)74     public void setActivity(Activity activity) {
75         mActivity = activity;
76     }
77 
setFragment(PreferenceFragmentCompat fragment)78     public void setFragment(PreferenceFragmentCompat fragment) {
79         mHost = fragment;
80     }
81 
setLifecycle(Lifecycle lifecycle)82     public void setLifecycle(Lifecycle lifecycle) {
83         mLifecycle = lifecycle;
84     }
85 
86     @Override
displayPreference(PreferenceScreen screen)87     public void displayPreference(PreferenceScreen screen) {
88         super.displayPreference(screen);
89         mBatteryUsageProgressBarPref = screen.findPreference(getPreferenceKey());
90         // Set up loading text first to prevent layout flaky before info loaded.
91         mBatteryUsageProgressBarPref.setBottomSummary(
92                 mContext.getString(R.string.settings_license_activity_loading));
93 
94         if (com.android.settings.Utils.isBatteryPresent(mContext)) {
95             quickUpdateHeaderPreference();
96         } else {
97             mBatteryUsageProgressBarPref.setVisible(false);
98         }
99     }
100 
101     @Override
getAvailabilityStatus()102     public int getAvailabilityStatus() {
103         return AVAILABLE_UNSEARCHABLE;
104     }
105 
106     @Override
onStart()107     public void onStart() {
108         EntityHeaderController.newInstance(mActivity, mHost, null /* header view */)
109                 .setRecyclerView(mHost.getListView(), mLifecycle);
110     }
111 
generateLabel(BatteryInfo info)112     private CharSequence generateLabel(BatteryInfo info) {
113         if (Utils.containsIncompatibleChargers(mContext, TAG)) {
114             return mContext.getString(R.string.battery_info_status_not_charging);
115         } else if (BatteryUtils.isBatteryDefenderOn(info)) {
116             return null;
117         } else if (info.remainingLabel == null
118                 || info.batteryStatus == BatteryManager.BATTERY_STATUS_NOT_CHARGING) {
119             // Present status only if no remaining time or status anomalous
120             return info.statusLabel;
121         } else if (info.statusLabel != null && !info.discharging) {
122             // Charging state
123             return mContext.getString(
124                     R.string.battery_state_and_duration, info.statusLabel, info.remainingLabel);
125         } else if (mPowerManager.isPowerSaveMode()) {
126             // Power save mode is on
127             final String powerSaverOn = mContext.getString(
128                     R.string.battery_tip_early_heads_up_done_title);
129             return mContext.getString(
130                     R.string.battery_state_and_duration, powerSaverOn, info.remainingLabel);
131         } else if (mBatteryTip != null
132                 && mBatteryTip.getType() == BatteryTip.TipType.LOW_BATTERY) {
133             // Low battery state
134             final String lowBattery = mContext.getString(R.string.low_battery_summary);
135             return mContext.getString(
136                     R.string.battery_state_and_duration, lowBattery, info.remainingLabel);
137         } else {
138             // Discharging state
139             return info.remainingLabel;
140         }
141     }
142 
updateHeaderPreference(BatteryInfo info)143     public void updateHeaderPreference(BatteryInfo info) {
144         if (!mBatteryStatusFeatureProvider.triggerBatteryStatusUpdate(this, info)) {
145             mBatteryUsageProgressBarPref.setBottomSummary(generateLabel(info));
146         }
147 
148         mBatteryUsageProgressBarPref.setUsageSummary(
149                 formatBatteryPercentageText(info.batteryLevel));
150         mBatteryUsageProgressBarPref.setPercent(info.batteryLevel, BATTERY_MAX_LEVEL);
151     }
152 
153     /**
154      * Callback which receives text for the summary line.
155      */
updateBatteryStatus(String label, BatteryInfo info)156     public void updateBatteryStatus(String label, BatteryInfo info) {
157         final CharSequence summary = label != null ? label : generateLabel(info);
158         mBatteryUsageProgressBarPref.setBottomSummary(summary);
159         Log.d(TAG, "updateBatteryStatus: " + label + " summary: " + summary);
160     }
161 
quickUpdateHeaderPreference()162     public void quickUpdateHeaderPreference() {
163         Intent batteryBroadcast = com.android.settingslib.fuelgauge.BatteryUtils
164                 .getBatteryIntent(mContext);
165         final int batteryLevel = Utils.getBatteryLevel(batteryBroadcast);
166         final boolean discharging =
167                 batteryBroadcast.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1) == 0;
168 
169         mBatteryUsageProgressBarPref.setUsageSummary(formatBatteryPercentageText(batteryLevel));
170         mBatteryUsageProgressBarPref.setPercent(batteryLevel, BATTERY_MAX_LEVEL);
171     }
172 
173     /**
174      * Update summary when battery tips changed.
175      */
updateHeaderByBatteryTips(BatteryTip batteryTip, BatteryInfo batteryInfo)176     public void updateHeaderByBatteryTips(BatteryTip batteryTip, BatteryInfo batteryInfo) {
177         mBatteryTip = batteryTip;
178 
179         if (mBatteryTip != null && batteryInfo != null) {
180             updateHeaderPreference(batteryInfo);
181         }
182     }
183 
formatBatteryPercentageText(int batteryLevel)184     private CharSequence formatBatteryPercentageText(int batteryLevel) {
185         return TextUtils.expandTemplate(mContext.getText(R.string.battery_header_title_alternate),
186                 NumberFormat.getIntegerInstance().format(batteryLevel));
187     }
188 }
189