• 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.hardware.usb.UsbManager;
24 import android.os.BatteryManager;
25 import android.os.PowerManager;
26 import android.util.Log;
27 
28 import androidx.annotation.IntDef;
29 import androidx.annotation.VisibleForTesting;
30 
31 import com.android.settings.Utils;
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}
39  */
40 public class BatteryBroadcastReceiver extends BroadcastReceiver {
41 
42     private static final String TAG = "BatteryBroadcastRcvr";
43     /**
44      * Callback if any of the monitored fields has been changed:
45      *
46      * Battery level(e.g. 100%->99%)
47      * Battery status(e.g. plugged->unplugged)
48      * Battery saver(e.g. off->on)
49      * Battery health(e.g. good->overheat)
50      * Battery charging status(e.g. default->long life)
51      */
52     public interface OnBatteryChangedListener {
onBatteryChanged(@atteryUpdateType int type)53         void onBatteryChanged(@BatteryUpdateType int type);
54     }
55 
56     @Retention(RetentionPolicy.SOURCE)
57     @IntDef({BatteryUpdateType.MANUAL,
58             BatteryUpdateType.BATTERY_LEVEL,
59             BatteryUpdateType.BATTERY_SAVER,
60             BatteryUpdateType.BATTERY_STATUS,
61             BatteryUpdateType.BATTERY_HEALTH,
62             BatteryUpdateType.CHARGING_STATUS,
63             BatteryUpdateType.BATTERY_NOT_PRESENT})
64     public @interface BatteryUpdateType {
65         int MANUAL = 0;
66         int BATTERY_LEVEL = 1;
67         int BATTERY_SAVER = 2;
68         int BATTERY_STATUS = 3;
69         int BATTERY_HEALTH = 4;
70         int CHARGING_STATUS = 5;
71         int BATTERY_NOT_PRESENT = 6;
72     }
73 
74     @VisibleForTesting
75     String mBatteryLevel;
76     @VisibleForTesting
77     String mBatteryStatus;
78     @VisibleForTesting
79     int mChargingStatus;
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         intentFilter.addAction(BatteryUtils.BYPASS_DOCK_DEFENDER_ACTION);
103         intentFilter.addAction(UsbManager.ACTION_USB_PORT_COMPLIANCE_CHANGED);
104 
105         final Intent intent = mContext.registerReceiver(this, intentFilter,
106                 Context.RECEIVER_EXPORTED);
107         updateBatteryStatus(intent, true /* forceUpdate */);
108     }
109 
unRegister()110     public void unRegister() {
111         mContext.unregisterReceiver(this);
112     }
113 
updateBatteryStatus(Intent intent, boolean forceUpdate)114     private void updateBatteryStatus(Intent intent, boolean forceUpdate) {
115         if (intent == null || mBatteryListener == null) {
116             return;
117         }
118         final String action = intent.getAction();
119         Log.d(TAG, "updateBatteryStatus: action=" + action);
120         if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
121             final String batteryLevel = Utils.getBatteryPercentage(intent);
122             final String batteryStatus =
123                     Utils.getBatteryStatus(mContext, intent, /* compactStatus= */ false);
124             final int chargingStatus = intent.getIntExtra(
125                     BatteryManager.EXTRA_CHARGING_STATUS, BatteryManager.CHARGING_POLICY_DEFAULT);
126             final int batteryHealth = intent.getIntExtra(
127                     BatteryManager.EXTRA_HEALTH, BatteryManager.BATTERY_HEALTH_UNKNOWN);
128             Log.d(
129                     TAG,
130                     "Battery changed: level: "
131                             + batteryLevel
132                             + "| status: "
133                             + batteryStatus
134                             + "| chargingStatus: "
135                             + chargingStatus
136                             + "| health: "
137                             + batteryHealth);
138             if (!Utils.isBatteryPresent(intent)) {
139                 Log.w(TAG, "Problem reading the battery meter.");
140                 mBatteryListener.onBatteryChanged(BatteryUpdateType.BATTERY_NOT_PRESENT);
141             } else if (forceUpdate) {
142                 mBatteryListener.onBatteryChanged(BatteryUpdateType.MANUAL);
143             } else if (chargingStatus != mChargingStatus) {
144                 mBatteryListener.onBatteryChanged(BatteryUpdateType.CHARGING_STATUS);
145             } else if (batteryHealth != mBatteryHealth) {
146                 mBatteryListener.onBatteryChanged(BatteryUpdateType.BATTERY_HEALTH);
147             } else if(!batteryLevel.equals(mBatteryLevel)) {
148                 mBatteryListener.onBatteryChanged(BatteryUpdateType.BATTERY_LEVEL);
149             } else if (!batteryStatus.equals(mBatteryStatus)) {
150                 mBatteryListener.onBatteryChanged(BatteryUpdateType.BATTERY_STATUS);
151             }
152             mBatteryLevel = batteryLevel;
153             mBatteryStatus = batteryStatus;
154             mChargingStatus = chargingStatus;
155             mBatteryHealth = batteryHealth;
156         } else if (PowerManager.ACTION_POWER_SAVE_MODE_CHANGED.equals(action)) {
157             mBatteryListener.onBatteryChanged(BatteryUpdateType.BATTERY_SAVER);
158         } else if (BatteryUtils.BYPASS_DOCK_DEFENDER_ACTION.equals(action)
159                 || UsbManager.ACTION_USB_PORT_COMPLIANCE_CHANGED.equals(action)) {
160             mBatteryListener.onBatteryChanged(BatteryUpdateType.BATTERY_STATUS);
161         }
162     }
163 }
164