• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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.settings.fuelgauge.batteryusage;
17 
18 import static com.android.settings.fuelgauge.BatteryBroadcastReceiver.BatteryUpdateType;
19 
20 import android.app.Activity;
21 import android.content.Context;
22 import android.os.BatteryUsageStats;
23 import android.os.Bundle;
24 import android.os.UserManager;
25 import android.util.Log;
26 
27 import androidx.annotation.IntDef;
28 import androidx.annotation.NonNull;
29 import androidx.annotation.VisibleForTesting;
30 import androidx.loader.app.LoaderManager;
31 import androidx.loader.content.Loader;
32 
33 import com.android.settings.dashboard.DashboardFragment;
34 import com.android.settings.fuelgauge.BatteryBroadcastReceiver;
35 
36 import java.lang.annotation.Retention;
37 import java.lang.annotation.RetentionPolicy;
38 
39 /**
40  * Common base class for things that need to show the battery usage graph.
41  */
42 public abstract class PowerUsageBase extends DashboardFragment {
43     private static final String TAG = "PowerUsageBase";
44 
45     @VisibleForTesting
46     static final String KEY_REFRESH_TYPE = "refresh_type";
47     @VisibleForTesting
48     static final String KEY_INCLUDE_HISTORY = "include_history";
49     @VisibleForTesting
50     BatteryUsageStats mBatteryUsageStats;
51 
52     protected UserManager mUm;
53     protected boolean mIsBatteryPresent = true;
54     private BatteryBroadcastReceiver mBatteryBroadcastReceiver;
55 
56     @VisibleForTesting
57     final BatteryUsageStatsLoaderCallbacks mBatteryUsageStatsLoaderCallbacks =
58             new BatteryUsageStatsLoaderCallbacks();
59 
60     @Retention(RetentionPolicy.SOURCE)
61     @IntDef({
62             LoaderIndex.BATTERY_USAGE_STATS_LOADER,
63             LoaderIndex.BATTERY_INFO_LOADER,
64             LoaderIndex.BATTERY_TIP_LOADER,
65             LoaderIndex.BATTERY_LEVEL_DATA_LOADER
66 
67     })
68     public @interface LoaderIndex {
69         int BATTERY_USAGE_STATS_LOADER = 0;
70         int BATTERY_INFO_LOADER = 1;
71         int BATTERY_TIP_LOADER = 2;
72         int BATTERY_LEVEL_DATA_LOADER = 3;
73     }
74 
75     @Override
onAttach(Activity activity)76     public void onAttach(Activity activity) {
77         super.onAttach(activity);
78         mUm = (UserManager) activity.getSystemService(Context.USER_SERVICE);
79     }
80 
81     @Override
onCreate(Bundle icicle)82     public void onCreate(Bundle icicle) {
83         super.onCreate(icicle);
84 
85         mBatteryBroadcastReceiver = new BatteryBroadcastReceiver(getContext());
86         mBatteryBroadcastReceiver.setBatteryChangedListener(type -> {
87             if (type == BatteryBroadcastReceiver.BatteryUpdateType.BATTERY_NOT_PRESENT) {
88                 mIsBatteryPresent = false;
89             }
90             restartBatteryStatsLoader(type);
91         });
92     }
93 
94     @Override
onStart()95     public void onStart() {
96         super.onStart();
97         mBatteryBroadcastReceiver.register();
98     }
99 
100     @Override
onStop()101     public void onStop() {
102         super.onStop();
103         mBatteryBroadcastReceiver.unRegister();
104         closeBatteryUsageStatsIfNeeded();
105     }
106 
restartBatteryStatsLoader(int refreshType)107     protected void restartBatteryStatsLoader(int refreshType) {
108         final Bundle bundle = new Bundle();
109         bundle.putInt(KEY_REFRESH_TYPE, refreshType);
110         bundle.putBoolean(KEY_INCLUDE_HISTORY, false);
111         restartLoader(LoaderIndex.BATTERY_USAGE_STATS_LOADER, bundle,
112                 mBatteryUsageStatsLoaderCallbacks);
113     }
114 
getLoaderManagerForCurrentFragment()115     protected LoaderManager getLoaderManagerForCurrentFragment() {
116         return LoaderManager.getInstance(this);
117     }
118 
restartLoader(int loaderId, Bundle bundle, LoaderManager.LoaderCallbacks<?> loaderCallbacks)119     protected void restartLoader(int loaderId, Bundle bundle,
120             LoaderManager.LoaderCallbacks<?> loaderCallbacks) {
121         LoaderManager loaderManager = getLoaderManagerForCurrentFragment();
122         Loader<?> loader = loaderManager.getLoader(
123                 loaderId);
124         if (loader != null && !loader.isReset()) {
125             loaderManager.restartLoader(loaderId, bundle,
126                     loaderCallbacks);
127         } else {
128             loaderManager.initLoader(loaderId, bundle,
129                     loaderCallbacks);
130         }
131     }
132 
onLoadFinished(@atteryUpdateType int refreshType)133     protected void onLoadFinished(@BatteryUpdateType int refreshType) {
134         refreshUi(refreshType);
135     }
136 
refreshUi(@atteryUpdateType int refreshType)137     protected abstract void refreshUi(@BatteryUpdateType int refreshType);
138 
139     private class BatteryUsageStatsLoaderCallbacks
140             implements LoaderManager.LoaderCallbacks<BatteryUsageStats> {
141         private int mRefreshType;
142 
143         @Override
144         @NonNull
onCreateLoader(int id, Bundle args)145         public Loader<BatteryUsageStats> onCreateLoader(int id, Bundle args) {
146             mRefreshType = args.getInt(KEY_REFRESH_TYPE);
147             return new BatteryUsageStatsLoader(getContext(), args.getBoolean(KEY_INCLUDE_HISTORY));
148         }
149 
150         @Override
onLoadFinished(Loader<BatteryUsageStats> loader, BatteryUsageStats batteryUsageStats)151         public void onLoadFinished(Loader<BatteryUsageStats> loader,
152                 BatteryUsageStats batteryUsageStats) {
153             closeBatteryUsageStatsIfNeeded();
154             mBatteryUsageStats = batteryUsageStats;
155             PowerUsageBase.this.onLoadFinished(mRefreshType);
156         }
157 
158         @Override
onLoaderReset(Loader<BatteryUsageStats> loader)159         public void onLoaderReset(Loader<BatteryUsageStats> loader) {
160         }
161     }
162 
closeBatteryUsageStatsIfNeeded()163     private void closeBatteryUsageStatsIfNeeded() {
164         if (mBatteryUsageStats == null) {
165             return;
166         }
167         try {
168             mBatteryUsageStats.close();
169         } catch (Exception e) {
170             Log.e(TAG, "BatteryUsageStats.close() failed", e);
171         } finally {
172             mBatteryUsageStats = null;
173         }
174     }
175 }
176