1 /*
2  * Copyright (C) 2010 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.systemui.statusbar.policy;
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 java.io.FileDescriptor;
28 import java.io.PrintWriter;
29 import java.util.ArrayList;
30 
31 public class BatteryController extends BroadcastReceiver {
32     private static final String TAG = "BatteryController";
33     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
34 
35     private final ArrayList<BatteryStateChangeCallback> mChangeCallbacks = new ArrayList<>();
36     private final PowerManager mPowerManager;
37 
38     private int mLevel;
39     private boolean mPluggedIn;
40     private boolean mCharging;
41     private boolean mCharged;
42     private boolean mPowerSave;
43 
BatteryController(Context context)44     public BatteryController(Context context) {
45         mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
46 
47         IntentFilter filter = new IntentFilter();
48         filter.addAction(Intent.ACTION_BATTERY_CHANGED);
49         filter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);
50         filter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGING);
51         context.registerReceiver(this, filter);
52 
53         updatePowerSave();
54     }
55 
dump(FileDescriptor fd, PrintWriter pw, String[] args)56     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
57         pw.println("BatteryController state:");
58         pw.print("  mLevel="); pw.println(mLevel);
59         pw.print("  mPluggedIn="); pw.println(mPluggedIn);
60         pw.print("  mCharging="); pw.println(mCharging);
61         pw.print("  mCharged="); pw.println(mCharged);
62         pw.print("  mPowerSave="); pw.println(mPowerSave);
63     }
64 
addStateChangedCallback(BatteryStateChangeCallback cb)65     public void addStateChangedCallback(BatteryStateChangeCallback cb) {
66         mChangeCallbacks.add(cb);
67         cb.onBatteryLevelChanged(mLevel, mPluggedIn, mCharging);
68     }
69 
removeStateChangedCallback(BatteryStateChangeCallback cb)70     public void removeStateChangedCallback(BatteryStateChangeCallback cb) {
71         mChangeCallbacks.remove(cb);
72     }
73 
onReceive(Context context, Intent intent)74     public void onReceive(Context context, Intent intent) {
75         final String action = intent.getAction();
76         if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
77             mLevel = (int)(100f
78                     * intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0)
79                     / intent.getIntExtra(BatteryManager.EXTRA_SCALE, 100));
80             mPluggedIn = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0) != 0;
81 
82             final int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS,
83                     BatteryManager.BATTERY_STATUS_UNKNOWN);
84             mCharged = status == BatteryManager.BATTERY_STATUS_FULL;
85             mCharging = mCharged || status == BatteryManager.BATTERY_STATUS_CHARGING;
86 
87             fireBatteryLevelChanged();
88         } else if (action.equals(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED)) {
89             updatePowerSave();
90         } else if (action.equals(PowerManager.ACTION_POWER_SAVE_MODE_CHANGING)) {
91             setPowerSave(intent.getBooleanExtra(PowerManager.EXTRA_POWER_SAVE_MODE, false));
92         }
93     }
94 
isPowerSave()95     public boolean isPowerSave() {
96         return mPowerSave;
97     }
98 
updatePowerSave()99     private void updatePowerSave() {
100         setPowerSave(mPowerManager.isPowerSaveMode());
101     }
102 
setPowerSave(boolean powerSave)103     private void setPowerSave(boolean powerSave) {
104         if (powerSave == mPowerSave) return;
105         mPowerSave = powerSave;
106         if (DEBUG) Log.d(TAG, "Power save is " + (mPowerSave ? "on" : "off"));
107         firePowerSaveChanged();
108     }
109 
fireBatteryLevelChanged()110     private void fireBatteryLevelChanged() {
111         final int N = mChangeCallbacks.size();
112         for (int i = 0; i < N; i++) {
113             mChangeCallbacks.get(i).onBatteryLevelChanged(mLevel, mPluggedIn, mCharging);
114         }
115     }
116 
firePowerSaveChanged()117     private void firePowerSaveChanged() {
118         final int N = mChangeCallbacks.size();
119         for (int i = 0; i < N; i++) {
120             mChangeCallbacks.get(i).onPowerSaveChanged();
121         }
122     }
123 
124     public interface BatteryStateChangeCallback {
onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging)125         void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging);
onPowerSaveChanged()126         void onPowerSaveChanged();
127     }
128 }
129