1 /*
2  * Copyright (C) 2017 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.BroadcastReceiver;
20 import android.content.Context;
21 import android.content.Intent;
22 import android.content.IntentFilter;
23 import android.os.PowerManager;
24 
25 import androidx.annotation.IntDef;
26 import androidx.annotation.VisibleForTesting;
27 
28 import com.android.settings.Utils;
29 import com.android.settings.homepage.contextualcards.slices.BatteryFixSlice;
30 
31 import java.lang.annotation.Retention;
32 import java.lang.annotation.RetentionPolicy;
33 
34 /**
35  * Use this broadcastReceiver to listen to the battery change, and it will invoke
36  * {@link OnBatteryChangedListener} if any of the following has been changed:
37  *
38  * 1. Battery level(e.g. 100%->99%)
39  * 2. Battery status(e.g. plugged->unplugged)
40  * 3. Battery saver(e.g. off->on)
41  */
42 public class BatteryBroadcastReceiver extends BroadcastReceiver {
43 
44     /**
45      * Callback when the following has been changed:
46      *
47      * Battery level(e.g. 100%->99%)
48      * Battery status(e.g. plugged->unplugged)
49      * Battery saver(e.g. off->on)
50      */
51     public interface OnBatteryChangedListener {
onBatteryChanged(@atteryUpdateType int type)52         void onBatteryChanged(@BatteryUpdateType int type);
53     }
54 
55     @Retention(RetentionPolicy.SOURCE)
56     @IntDef({BatteryUpdateType.MANUAL,
57             BatteryUpdateType.BATTERY_LEVEL,
58             BatteryUpdateType.BATTERY_SAVER,
59             BatteryUpdateType.BATTERY_STATUS})
60     public @interface BatteryUpdateType {
61         int MANUAL = 0;
62         int BATTERY_LEVEL = 1;
63         int BATTERY_SAVER = 2;
64         int BATTERY_STATUS = 3;
65     }
66 
67     @VisibleForTesting
68     String mBatteryLevel;
69     @VisibleForTesting
70     String mBatteryStatus;
71     private OnBatteryChangedListener mBatteryListener;
72     private Context mContext;
73 
BatteryBroadcastReceiver(Context context)74     public BatteryBroadcastReceiver(Context context) {
75         mContext = context;
76     }
77 
78     @Override
onReceive(Context context, Intent intent)79     public void onReceive(Context context, Intent intent) {
80         updateBatteryStatus(intent, false /* forceUpdate */);
81     }
82 
setBatteryChangedListener(OnBatteryChangedListener lsn)83     public void setBatteryChangedListener(OnBatteryChangedListener lsn) {
84         mBatteryListener = lsn;
85     }
86 
register()87     public void register() {
88         final IntentFilter intentFilter = new IntentFilter();
89         intentFilter.addAction(Intent.ACTION_BATTERY_CHANGED);
90         intentFilter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);
91 
92         final Intent intent = mContext.registerReceiver(this, intentFilter);
93         updateBatteryStatus(intent, true /* forceUpdate */);
94     }
95 
unRegister()96     public void unRegister() {
97         mContext.unregisterReceiver(this);
98     }
99 
updateBatteryStatus(Intent intent, boolean forceUpdate)100     private void updateBatteryStatus(Intent intent, boolean forceUpdate) {
101         if (intent != null && mBatteryListener != null) {
102             if (Intent.ACTION_BATTERY_CHANGED.equals(intent.getAction())) {
103                 final String batteryLevel = Utils.getBatteryPercentage(intent);
104                 final String batteryStatus = Utils.getBatteryStatus(
105                         mContext, intent);
106                 if (forceUpdate) {
107                     mBatteryListener.onBatteryChanged(BatteryUpdateType.MANUAL);
108                 } else if(!batteryLevel.equals(mBatteryLevel)) {
109                     mBatteryListener.onBatteryChanged(BatteryUpdateType.BATTERY_LEVEL);
110                 } else if (!batteryStatus.equals(mBatteryStatus)) {
111                     mBatteryListener.onBatteryChanged(BatteryUpdateType.BATTERY_STATUS);
112                 }
113                 mBatteryLevel = batteryLevel;
114                 mBatteryStatus = batteryStatus;
115             } else if (PowerManager.ACTION_POWER_SAVE_MODE_CHANGED.equals(intent.getAction())) {
116                 mBatteryListener.onBatteryChanged(BatteryUpdateType.BATTERY_SAVER);
117             }
118         }
119         BatteryFixSlice.updateBatteryTipAvailabilityCache(mContext);
120     }
121 }