blob: 24207f3f35b9e5534e26260c792c8309a10104f7 [file] [log] [blame]
Anthony Chenda62fdcd52016-04-06 16:15:14 -07001/*
2 * Copyright (C) 2016 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
17package com.android.systemui.statusbar.policy;
18
19import android.content.BroadcastReceiver;
20import android.content.Context;
21import android.content.Intent;
22import android.content.IntentFilter;
23import android.os.BatteryManager;
24import android.os.Handler;
25import android.os.PowerManager;
26import android.util.Log;
27
28import java.io.FileDescriptor;
29import java.io.PrintWriter;
30import java.util.ArrayList;
31
32/**
33 * Default implementation of a {@link BatteryController}. This controller monitors for battery
34 * level change events that are broadcasted by the system.
35 */
36public class BatteryControllerImpl extends BroadcastReceiver implements BatteryController {
37 private static final String TAG = "BatteryController";
38
39 public static final String ACTION_LEVEL_TEST = "com.android.systemui.BATTERY_LEVEL_TEST";
40
41 private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
42
43 private final ArrayList<BatteryController.BatteryStateChangeCallback> mChangeCallbacks = new ArrayList<>();
44 private final PowerManager mPowerManager;
45 private final Handler mHandler;
46
47 protected int mLevel;
48 protected boolean mPluggedIn;
49 protected boolean mCharging;
50 protected boolean mCharged;
51 protected boolean mPowerSave;
52 private boolean mTestmode = false;
53
54 public BatteryControllerImpl(Context context) {
55 mHandler = new Handler();
56 mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
57
58 IntentFilter filter = new IntentFilter();
59 filter.addAction(Intent.ACTION_BATTERY_CHANGED);
60 filter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);
61 filter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGING);
62 filter.addAction(ACTION_LEVEL_TEST);
63 context.registerReceiver(this, filter);
64
65 updatePowerSave();
66 }
67
68 @Override
69 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
70 pw.println("BatteryController state:");
71 pw.print(" mLevel="); pw.println(mLevel);
72 pw.print(" mPluggedIn="); pw.println(mPluggedIn);
73 pw.print(" mCharging="); pw.println(mCharging);
74 pw.print(" mCharged="); pw.println(mCharged);
75 pw.print(" mPowerSave="); pw.println(mPowerSave);
76 }
77
78 @Override
79 public void setPowerSaveMode(boolean powerSave) {
80 mPowerManager.setPowerSaveMode(powerSave);
81 }
82
83 @Override
84 public void addStateChangedCallback(BatteryController.BatteryStateChangeCallback cb) {
85 mChangeCallbacks.add(cb);
86 cb.onBatteryLevelChanged(mLevel, mPluggedIn, mCharging);
87 cb.onPowerSaveChanged(mPowerSave);
88 }
89
90 @Override
91 public void removeStateChangedCallback(BatteryController.BatteryStateChangeCallback cb) {
92 mChangeCallbacks.remove(cb);
93 }
94
95 @Override
96 public void onReceive(final Context context, Intent intent) {
97 final String action = intent.getAction();
98 if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
99 if (mTestmode && !intent.getBooleanExtra("testmode", false)) return;
100 mLevel = (int)(100f
101 * intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0)
102 / intent.getIntExtra(BatteryManager.EXTRA_SCALE, 100));
103 mPluggedIn = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0) != 0;
104
105 final int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS,
106 BatteryManager.BATTERY_STATUS_UNKNOWN);
107 mCharged = status == BatteryManager.BATTERY_STATUS_FULL;
108 mCharging = mCharged || status == BatteryManager.BATTERY_STATUS_CHARGING;
109
110 fireBatteryLevelChanged();
111 } else if (action.equals(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED)) {
112 updatePowerSave();
113 } else if (action.equals(PowerManager.ACTION_POWER_SAVE_MODE_CHANGING)) {
114 setPowerSave(intent.getBooleanExtra(PowerManager.EXTRA_POWER_SAVE_MODE, false));
115 } else if (action.equals(ACTION_LEVEL_TEST)) {
116 mTestmode = true;
117 mHandler.post(new Runnable() {
118 int curLevel = 0;
119 int incr = 1;
120 int saveLevel = mLevel;
121 boolean savePlugged = mPluggedIn;
122 Intent dummy = new Intent(Intent.ACTION_BATTERY_CHANGED);
123 @Override
124 public void run() {
125 if (curLevel < 0) {
126 mTestmode = false;
127 dummy.putExtra("level", saveLevel);
128 dummy.putExtra("plugged", savePlugged);
129 dummy.putExtra("testmode", false);
130 } else {
131 dummy.putExtra("level", curLevel);
132 dummy.putExtra("plugged", incr > 0 ? BatteryManager.BATTERY_PLUGGED_AC
133 : 0);
134 dummy.putExtra("testmode", true);
135 }
136 context.sendBroadcast(dummy);
137
138 if (!mTestmode) return;
139
140 curLevel += incr;
141 if (curLevel == 100) {
142 incr *= -1;
143 }
144 mHandler.postDelayed(this, 200);
145 }
146 });
147 }
148 }
149
150 @Override
151 public boolean isPowerSave() {
152 return mPowerSave;
153 }
154
155 private void updatePowerSave() {
156 setPowerSave(mPowerManager.isPowerSaveMode());
157 }
158
159 private void setPowerSave(boolean powerSave) {
160 if (powerSave == mPowerSave) return;
161 mPowerSave = powerSave;
162 if (DEBUG) Log.d(TAG, "Power save is " + (mPowerSave ? "on" : "off"));
163 firePowerSaveChanged();
164 }
165
166 protected void fireBatteryLevelChanged() {
167 final int N = mChangeCallbacks.size();
168 for (int i = 0; i < N; i++) {
169 mChangeCallbacks.get(i).onBatteryLevelChanged(mLevel, mPluggedIn, mCharging);
170 }
171 }
172
173 private void firePowerSaveChanged() {
174 final int N = mChangeCallbacks.size();
175 for (int i = 0; i < N; i++) {
176 mChangeCallbacks.get(i).onPowerSaveChanged(mPowerSave);
177 }
178 }
179}