• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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 package com.android.systemui.battery;
17 
18 import static android.provider.Settings.System.SHOW_BATTERY_PERCENT;
19 
20 import android.content.ContentResolver;
21 import android.content.Context;
22 import android.database.ContentObserver;
23 import android.net.Uri;
24 import android.os.Handler;
25 import android.os.HandlerExecutor;
26 import android.provider.Settings;
27 import android.text.TextUtils;
28 import android.util.ArraySet;
29 import android.view.View;
30 
31 import androidx.annotation.NonNull;
32 
33 import com.android.systemui.dagger.SysUISingleton;
34 import com.android.systemui.dagger.qualifiers.Main;
35 import com.android.systemui.flags.FeatureFlags;
36 import com.android.systemui.flags.Flags;
37 import com.android.systemui.settings.UserTracker;
38 import com.android.systemui.statusbar.phone.StatusBarLocation;
39 import com.android.systemui.statusbar.phone.ui.StatusBarIconController;
40 import com.android.systemui.statusbar.policy.BatteryController;
41 import com.android.systemui.statusbar.policy.ConfigurationController;
42 import com.android.systemui.tuner.TunerService;
43 import com.android.systemui.util.ViewController;
44 
45 import java.io.PrintWriter;
46 
47 import javax.inject.Inject;
48 
49 /**
50  * Controller for {@link BatteryMeterView}.
51  * @deprecated once [NewStatusBarIcons] is rolled out, this class is no longer needed
52  */
53 public class BatteryMeterViewController extends ViewController<BatteryMeterView> {
54     private final ConfigurationController mConfigurationController;
55     private final TunerService mTunerService;
56     private final Handler mMainHandler;
57     private final ContentResolver mContentResolver;
58     private final FeatureFlags mFeatureFlags;
59     private final BatteryController mBatteryController;
60 
61     private final String mSlotBattery;
62     private final SettingObserver mSettingObserver;
63     private final UserTracker mUserTracker;
64     private final StatusBarLocation mLocation;
65 
66     private final ConfigurationController.ConfigurationListener mConfigurationListener =
67             new ConfigurationController.ConfigurationListener() {
68                 @Override
69                 public void onDensityOrFontScaleChanged() {
70                     mView.scaleBatteryMeterViews();
71                 }
72             };
73 
74     private final TunerService.Tunable mTunable = new TunerService.Tunable() {
75         @Override
76         public void onTuningChanged(String key, String newValue) {
77             if (StatusBarIconController.ICON_HIDE_LIST.equals(key)) {
78                 ArraySet<String> icons = StatusBarIconController.getIconHideList(
79                         getContext(), newValue);
80                 mView.setVisibility(icons.contains(mSlotBattery) ? View.GONE : View.VISIBLE);
81             }
82         }
83     };
84 
85     private final BatteryController.BatteryStateChangeCallback mBatteryStateChangeCallback =
86             new BatteryController.BatteryStateChangeCallback() {
87                 @Override
88                 public void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) {
89                     mView.onBatteryLevelChanged(level, pluggedIn);
90                 }
91 
92                 @Override
93                 public void onPowerSaveChanged(boolean isPowerSave) {
94                     mView.onPowerSaveChanged(isPowerSave);
95                 }
96 
97                 @Override
98                 public void onBatteryUnknownStateChanged(boolean isUnknown) {
99                     mView.onBatteryUnknownStateChanged(isUnknown);
100                 }
101 
102                 @Override
103                 public void onIsBatteryDefenderChanged(boolean isBatteryDefender) {
104                     mView.onIsBatteryDefenderChanged(isBatteryDefender);
105                 }
106 
107                 @Override
108                 public void onIsIncompatibleChargingChanged(boolean isIncompatibleCharging) {
109                     if (mFeatureFlags.isEnabled(Flags.INCOMPATIBLE_CHARGING_BATTERY_ICON)) {
110                         mView.onIsIncompatibleChargingChanged(isIncompatibleCharging);
111                     }
112                 }
113 
114                 @Override
115                 public void dump(@NonNull PrintWriter pw, @NonNull String[] args) {
116                     pw.print(super.toString());
117                     pw.println(" location=" + mLocation);
118                     mView.dump(pw, args);
119                 }
120             };
121 
122     private final UserTracker.Callback mUserChangedCallback =
123             new UserTracker.Callback() {
124                 @Override
125                 public void onUserChanged(int newUser, @NonNull Context userContext) {
126                     mContentResolver.unregisterContentObserver(mSettingObserver);
127                     registerShowBatteryPercentObserver(newUser);
128                     mView.updateShowPercent();
129                 }
130             };
131 
132     // Some places may need to show the battery conditionally, and not obey the tuner
133     private boolean mIgnoreTunerUpdates;
134     private boolean mIsSubscribedForTunerUpdates;
135 
136     @Inject
BatteryMeterViewController( BatteryMeterView view, StatusBarLocation location, UserTracker userTracker, ConfigurationController configurationController, TunerService tunerService, @Main Handler mainHandler, ContentResolver contentResolver, FeatureFlags featureFlags, BatteryController batteryController)137     public BatteryMeterViewController(
138             BatteryMeterView view,
139             StatusBarLocation location,
140             UserTracker userTracker,
141             ConfigurationController configurationController,
142             TunerService tunerService,
143             @Main Handler mainHandler,
144             ContentResolver contentResolver,
145             FeatureFlags featureFlags,
146             BatteryController batteryController) {
147         super(view);
148         mLocation = location;
149         mUserTracker = userTracker;
150         mConfigurationController = configurationController;
151         mTunerService = tunerService;
152         mMainHandler = mainHandler;
153         mContentResolver = contentResolver;
154         mFeatureFlags = featureFlags;
155         mBatteryController = batteryController;
156 
157         mView.setBatteryEstimateFetcher(mBatteryController::getEstimatedTimeRemainingString);
158 
159         mSlotBattery = getResources().getString(com.android.internal.R.string.status_bar_battery);
160         mSettingObserver = new SettingObserver(mMainHandler);
161     }
162 
163     @Override
onViewAttached()164     protected void onViewAttached() {
165         mConfigurationController.addCallback(mConfigurationListener);
166         subscribeForTunerUpdates();
167         mBatteryController.addCallback(mBatteryStateChangeCallback);
168 
169         registerShowBatteryPercentObserver(mUserTracker.getUserId());
170         registerGlobalBatteryUpdateObserver();
171         mUserTracker.addCallback(mUserChangedCallback, new HandlerExecutor(mMainHandler));
172 
173         mView.updateShowPercent();
174     }
175 
176     @Override
onViewDetached()177     protected void onViewDetached() {
178         mConfigurationController.removeCallback(mConfigurationListener);
179         unsubscribeFromTunerUpdates();
180         mBatteryController.removeCallback(mBatteryStateChangeCallback);
181 
182         mUserTracker.removeCallback(mUserChangedCallback);
183         mContentResolver.unregisterContentObserver(mSettingObserver);
184     }
185 
186     /**
187      * Turn off {@link BatteryMeterView}'s subscribing to the tuner for updates, and thus avoid it
188      * controlling its own visibility.
189      */
ignoreTunerUpdates()190     public void ignoreTunerUpdates() {
191         mIgnoreTunerUpdates = true;
192         unsubscribeFromTunerUpdates();
193     }
194 
subscribeForTunerUpdates()195     private void subscribeForTunerUpdates() {
196         if (mIsSubscribedForTunerUpdates || mIgnoreTunerUpdates) {
197             return;
198         }
199 
200         mTunerService.addTunable(mTunable, StatusBarIconController.ICON_HIDE_LIST);
201         mIsSubscribedForTunerUpdates = true;
202     }
203 
unsubscribeFromTunerUpdates()204     private void unsubscribeFromTunerUpdates() {
205         if (!mIsSubscribedForTunerUpdates) {
206             return;
207         }
208 
209         mTunerService.removeTunable(mTunable);
210         mIsSubscribedForTunerUpdates = false;
211     }
212 
registerShowBatteryPercentObserver(int user)213     private void registerShowBatteryPercentObserver(int user) {
214         mContentResolver.registerContentObserver(
215                 Settings.System.getUriFor(SHOW_BATTERY_PERCENT),
216                 false,
217                 mSettingObserver,
218                 user);
219     }
220 
registerGlobalBatteryUpdateObserver()221     private void registerGlobalBatteryUpdateObserver() {
222         mContentResolver.registerContentObserver(
223                 Settings.Global.getUriFor(Settings.Global.BATTERY_ESTIMATES_LAST_UPDATE_TIME),
224                 false,
225                 mSettingObserver);
226     }
227 
228     private final class SettingObserver extends ContentObserver {
SettingObserver(Handler handler)229         public SettingObserver(Handler handler) {
230             super(handler);
231         }
232 
233         @Override
onChange(boolean selfChange, Uri uri)234         public void onChange(boolean selfChange, Uri uri) {
235             super.onChange(selfChange, uri);
236             mView.updateShowPercent();
237             if (TextUtils.equals(uri.getLastPathSegment(),
238                     Settings.Global.BATTERY_ESTIMATES_LAST_UPDATE_TIME)) {
239                 // update the text for sure if the estimate in the cache was updated
240                 mView.updatePercentText();
241             }
242         }
243     }
244 
245     /** */
246     @SysUISingleton
247     public static class Factory {
248         private final UserTracker mUserTracker;
249         private final ConfigurationController mConfigurationController;
250         private final TunerService mTunerService;
251         private final @Main Handler mMainHandler;
252         private final ContentResolver mContentResolver;
253         private final FeatureFlags mFeatureFlags;
254         private final BatteryController mBatteryController;
255 
256         @Inject
Factory( UserTracker userTracker, ConfigurationController configurationController, TunerService tunerService, @Main Handler mainHandler, ContentResolver contentResolver, FeatureFlags featureFlags, BatteryController batteryController )257         public Factory(
258                 UserTracker userTracker,
259                 ConfigurationController configurationController,
260                 TunerService tunerService,
261                 @Main Handler mainHandler,
262                 ContentResolver contentResolver,
263                 FeatureFlags featureFlags,
264                 BatteryController batteryController
265         ) {
266             mUserTracker = userTracker;
267             mConfigurationController = configurationController;
268             mTunerService = tunerService;
269             mMainHandler = mainHandler;
270             mContentResolver = contentResolver;
271             mFeatureFlags = featureFlags;
272             mBatteryController = batteryController;
273         }
274 
275         /** */
create(View view, StatusBarLocation location)276         public BatteryMeterViewController create(View view, StatusBarLocation location) {
277             return new BatteryMeterViewController(
278                     (BatteryMeterView) view,
279                     location,
280                     mUserTracker,
281                     mConfigurationController,
282                     mTunerService,
283                     mMainHandler,
284                     mContentResolver,
285                     mFeatureFlags,
286                     mBatteryController
287             );
288         }
289     }
290 }
291