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