/* * Copyright (C) 2017 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.settings.fuelgauge; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.BatteryManager; import android.os.PowerManager; import android.util.Log; import androidx.annotation.IntDef; import androidx.annotation.VisibleForTesting; import com.android.settings.Utils; import com.android.settings.homepage.contextualcards.slices.BatteryFixSlice; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** * Use this broadcastReceiver to listen to the battery change, and it will invoke * {@link OnBatteryChangedListener} if any of the following has been changed: * * 1. Battery level(e.g. 100%->99%) * 2. Battery status(e.g. plugged->unplugged) * 3. Battery saver(e.g. off->on) * 4. Battery health(e.g. good->overheat) */ public class BatteryBroadcastReceiver extends BroadcastReceiver { private static final String TAG = "BatteryBroadcastRcvr"; /** * Callback when the following has been changed: * * Battery level(e.g. 100%->99%) * Battery status(e.g. plugged->unplugged) * Battery saver(e.g. off->on) * Battery health(e.g. good->overheat) */ public interface OnBatteryChangedListener { void onBatteryChanged(@BatteryUpdateType int type); } @Retention(RetentionPolicy.SOURCE) @IntDef({BatteryUpdateType.MANUAL, BatteryUpdateType.BATTERY_LEVEL, BatteryUpdateType.BATTERY_SAVER, BatteryUpdateType.BATTERY_STATUS, BatteryUpdateType.BATTERY_HEALTH, BatteryUpdateType.BATTERY_NOT_PRESENT}) public @interface BatteryUpdateType { int MANUAL = 0; int BATTERY_LEVEL = 1; int BATTERY_SAVER = 2; int BATTERY_STATUS = 3; int BATTERY_HEALTH = 4; int BATTERY_NOT_PRESENT = 5; } @VisibleForTesting String mBatteryLevel; @VisibleForTesting String mBatteryStatus; @VisibleForTesting int mBatteryHealth; private OnBatteryChangedListener mBatteryListener; private Context mContext; public BatteryBroadcastReceiver(Context context) { mContext = context; } @Override public void onReceive(Context context, Intent intent) { updateBatteryStatus(intent, false /* forceUpdate */); } public void setBatteryChangedListener(OnBatteryChangedListener lsn) { mBatteryListener = lsn; } public void register() { final IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(Intent.ACTION_BATTERY_CHANGED); intentFilter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED); final Intent intent = mContext.registerReceiver(this, intentFilter); updateBatteryStatus(intent, true /* forceUpdate */); } public void unRegister() { mContext.unregisterReceiver(this); } private void updateBatteryStatus(Intent intent, boolean forceUpdate) { if (intent != null && mBatteryListener != null) { if (Intent.ACTION_BATTERY_CHANGED.equals(intent.getAction())) { final String batteryLevel = Utils.getBatteryPercentage(intent); final String batteryStatus = Utils.getBatteryStatus(mContext, intent); final int batteryHealth = intent.getIntExtra( BatteryManager.EXTRA_HEALTH, BatteryManager.BATTERY_HEALTH_UNKNOWN); if (!Utils.isBatteryPresent(intent)) { Log.w(TAG, "Problem reading the battery meter."); mBatteryListener.onBatteryChanged(BatteryUpdateType.BATTERY_NOT_PRESENT); } else if (forceUpdate) { mBatteryListener.onBatteryChanged(BatteryUpdateType.MANUAL); } else if (batteryHealth != mBatteryHealth) { mBatteryListener.onBatteryChanged(BatteryUpdateType.BATTERY_HEALTH); } else if(!batteryLevel.equals(mBatteryLevel)) { mBatteryListener.onBatteryChanged(BatteryUpdateType.BATTERY_LEVEL); } else if (!batteryStatus.equals(mBatteryStatus)) { mBatteryListener.onBatteryChanged(BatteryUpdateType.BATTERY_STATUS); } mBatteryLevel = batteryLevel; mBatteryStatus = batteryStatus; mBatteryHealth = batteryHealth; } else if (PowerManager.ACTION_POWER_SAVE_MODE_CHANGED.equals(intent.getAction())) { mBatteryListener.onBatteryChanged(BatteryUpdateType.BATTERY_SAVER); } } BatteryFixSlice.updateBatteryTipAvailabilityCache(mContext); } }