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