blob: bfc4fc7c89e0f05813207a3391efce80875e44be [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2006-2007 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.server.am;
18
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070019import android.bluetooth.BluetoothActivityEnergyInfo;
Jaikumar Ganesh3f034962010-09-27 17:02:23 -070020import android.bluetooth.BluetoothAdapter;
Amith Yamasani14fb81a2009-11-05 11:41:58 -080021import android.bluetooth.BluetoothHeadset;
Jaikumar Ganesh3f034962010-09-27 17:02:23 -070022import android.bluetooth.BluetoothProfile;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080023import android.content.Context;
Dianne Hackborne4a59512010-12-07 11:08:07 -080024import android.content.pm.ApplicationInfo;
Kenny Root3abd75b2011-09-29 11:00:41 -070025import android.content.pm.PackageManager;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070026import android.net.wifi.IWifiManager;
27import android.net.wifi.WifiActivityEnergyInfo;
Dianne Hackborn91268cf2013-06-13 19:06:50 -070028import android.os.BatteryStats;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029import android.os.Binder;
Jeff Brown6f357d32014-01-15 20:40:55 -080030import android.os.Handler;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080031import android.os.IBinder;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070032import android.os.Looper;
33import android.os.Message;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080034import android.os.Parcel;
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -070035import android.os.ParcelFileDescriptor;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -070036import android.os.PowerManagerInternal;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080037import android.os.Process;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070038import android.os.RemoteException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080039import android.os.ServiceManager;
Dianne Hackborne5167ca2014-03-08 14:39:10 -080040import android.os.SystemClock;
Dianne Hackborncbfd23e2013-06-11 14:26:53 -070041import android.os.UserHandle;
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -070042import android.os.WorkSource;
Adam Lesinskie08af192015-03-25 16:42:59 -070043import android.telephony.DataConnectionRealTimeInfo;
Wink Savillee9b06d72009-05-18 21:47:50 -070044import android.telephony.SignalStrength;
Dianne Hackborne4a59512010-12-07 11:08:07 -080045import android.telephony.TelephonyManager;
Joe Onorato8a9b2202010-02-26 18:56:32 -080046import android.util.Slog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080047
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070048import com.android.internal.annotations.GuardedBy;
Amith Yamasani32dbefd2009-06-19 09:21:17 -070049import com.android.internal.app.IBatteryStats;
Dianne Hackbornd953c532014-08-16 18:17:38 -070050import com.android.internal.os.BatteryStatsHelper;
Amith Yamasani32dbefd2009-06-19 09:21:17 -070051import com.android.internal.os.BatteryStatsImpl;
Amith Yamasanie43530a2009-08-21 13:11:37 -070052import com.android.internal.os.PowerProfile;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070053import com.android.server.FgThread;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -070054import com.android.server.LocalServices;
Amith Yamasani32dbefd2009-06-19 09:21:17 -070055
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -070056import java.io.File;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080057import java.io.FileDescriptor;
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -070058import java.io.IOException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080059import java.io.PrintWriter;
Dianne Hackborne4a59512010-12-07 11:08:07 -080060import java.util.List;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080061
62/**
63 * All information we are collecting about things that can happen that impact
64 * battery life.
65 */
Dianne Hackborncbefd8d2014-05-14 11:42:00 -070066public final class BatteryStatsService extends IBatteryStats.Stub
67 implements PowerManagerInternal.LowPowerModeListener {
Dianne Hackbornc51cf032014-03-02 19:08:15 -080068 static final String TAG = "BatteryStatsService";
69
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080070 static IBatteryStats sService;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080071 final BatteryStatsImpl mStats;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070072 final BatteryStatsHandler mHandler;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080073 Context mContext;
Jaikumar Ganesh3f034962010-09-27 17:02:23 -070074 private boolean mBluetoothPendingStats;
75 private BluetoothHeadset mBluetoothHeadset;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -070076 PowerManagerInternal mPowerManagerInternal;
Amith Yamasani3f7e35c2009-07-13 16:02:45 -070077
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070078 class BatteryStatsHandler extends Handler implements BatteryStatsImpl.ExternalStatsSync {
79 public static final int MSG_SYNC_EXTERNAL_STATS = 1;
80 public static final int MSG_WRITE_TO_DISK = 2;
81
82 public BatteryStatsHandler(Looper looper) {
83 super(looper);
84 }
85
86 @Override
87 public void handleMessage(Message msg) {
88 switch (msg.what) {
89 case MSG_SYNC_EXTERNAL_STATS:
90 updateExternalStats();
91 break;
92
93 case MSG_WRITE_TO_DISK:
94 updateExternalStats();
95 synchronized (mStats) {
96 mStats.writeAsyncLocked();
97 }
98 break;
99 }
100 }
101
102 @Override
103 public void scheduleSync() {
104 if (!hasMessages(MSG_SYNC_EXTERNAL_STATS)) {
105 sendEmptyMessage(MSG_SYNC_EXTERNAL_STATS);
106 }
107 }
108 }
109
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700110 BatteryStatsService(File systemDir, Handler handler) {
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700111 // Our handler here will be accessing the disk, use a different thread than
112 // what the ActivityManagerService gave us (no I/O on that one!).
113 mHandler = new BatteryStatsHandler(FgThread.getHandler().getLooper());
114
115 // BatteryStatsImpl expects the ActivityManagerService handler, so pass that one through.
116 mStats = new BatteryStatsImpl(systemDir, handler, mHandler);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800117 }
118
119 public void publish(Context context) {
120 mContext = context;
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700121 ServiceManager.addService(BatteryStats.SERVICE_NAME, asBinder());
Amith Yamasanie43530a2009-08-21 13:11:37 -0700122 mStats.setNumSpeedSteps(new PowerProfile(mContext).getNumSpeedSteps());
Amith Yamasanif37447b2009-10-08 18:28:01 -0700123 mStats.setRadioScanningTimeout(mContext.getResources().getInteger(
124 com.android.internal.R.integer.config_radioScanningTimeout)
125 * 1000L);
Adam Lesinskie08af192015-03-25 16:42:59 -0700126 mStats.setPowerProfile(new PowerProfile(context));
Jeff Brown2c43c332014-06-12 22:38:59 -0700127 }
128
129 /**
130 * At the time when the constructor runs, the power manager has not yet been
131 * initialized. So we initialize the low power observer later.
132 */
133 public void initPowerManagement() {
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700134 mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
135 mPowerManagerInternal.registerLowPowerModeObserver(this);
Dianne Hackborn8ad2af72015-03-17 17:00:24 -0700136 mStats.notePowerSaveMode(mPowerManagerInternal.getLowPowerModeEnabled());
Dianne Hackbornc51cf032014-03-02 19:08:15 -0800137 (new WakeupReasonThread()).start();
Jeff Brown2c43c332014-06-12 22:38:59 -0700138 }
139
Dianne Hackborn55280a92009-05-07 15:53:46 -0700140 public void shutdown() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800141 Slog.w("BatteryStats", "Writing battery stats before shutdown...");
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700142
143 updateExternalStats();
Dianne Hackborn55280a92009-05-07 15:53:46 -0700144 synchronized (mStats) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700145 mStats.shutdownLocked();
Dianne Hackborn55280a92009-05-07 15:53:46 -0700146 }
147 }
148
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800149 public static IBatteryStats getService() {
150 if (sService != null) {
151 return sService;
152 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700153 IBinder b = ServiceManager.getService(BatteryStats.SERVICE_NAME);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800154 sService = asInterface(b);
155 return sService;
156 }
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700157
158 @Override
159 public void onLowPowerModeChanged(boolean enabled) {
160 synchronized (mStats) {
Dianne Hackborn8ad2af72015-03-17 17:00:24 -0700161 mStats.notePowerSaveMode(enabled);
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700162 }
163 }
164
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800165 /**
166 * @return the current statistics object, which may be modified
167 * to reflect events that affect battery usage. You must lock the
168 * stats object before doing anything with it.
169 */
170 public BatteryStatsImpl getActiveStatistics() {
171 return mStats;
172 }
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700173
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700174 /**
175 * Schedules a write to disk to occur. This will cause the BatteryStatsImpl
176 * object to update with the latest info, then write to disk.
177 */
178 public void scheduleWriteToDisk() {
179 mHandler.sendEmptyMessage(BatteryStatsHandler.MSG_WRITE_TO_DISK);
180 }
181
Dianne Hackborn2f1993e2014-09-26 11:28:01 -0700182 // These are for direct use by the activity manager...
183
184 void addIsolatedUid(int isolatedUid, int appUid) {
185 synchronized (mStats) {
186 mStats.addIsolatedUidLocked(isolatedUid, appUid);
187 }
188 }
189
190 void removeIsolatedUid(int isolatedUid, int appUid) {
191 synchronized (mStats) {
192 mStats.removeIsolatedUidLocked(isolatedUid, appUid);
193 }
194 }
195
196 void noteProcessStart(String name, int uid) {
197 synchronized (mStats) {
198 mStats.noteProcessStartLocked(name, uid);
199 }
200 }
201
Dianne Hackborn1e01d162014-12-04 17:46:42 -0800202 void noteProcessCrash(String name, int uid) {
203 synchronized (mStats) {
204 mStats.noteProcessCrashLocked(name, uid);
205 }
206 }
207
208 void noteProcessAnr(String name, int uid) {
209 synchronized (mStats) {
210 mStats.noteProcessAnrLocked(name, uid);
211 }
212 }
213
Dianne Hackborn2f1993e2014-09-26 11:28:01 -0700214 void noteProcessState(String name, int uid, int state) {
215 synchronized (mStats) {
216 mStats.noteProcessStateLocked(name, uid, state);
217 }
218 }
219
220 void noteProcessFinish(String name, int uid) {
221 synchronized (mStats) {
222 mStats.noteProcessFinishLocked(name, uid);
223 }
224 }
225
226 // Public interface...
227
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800228 public byte[] getStatistics() {
229 mContext.enforceCallingPermission(
230 android.Manifest.permission.BATTERY_STATS, null);
Joe Onorato8a9b2202010-02-26 18:56:32 -0800231 //Slog.i("foo", "SENDING BATTERY INFO:");
232 //mStats.dumpLocked(new LogPrinter(Log.INFO, "foo", Log.LOG_ID_SYSTEM));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800233 Parcel out = Parcel.obtain();
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700234 updateExternalStats();
235 synchronized (mStats) {
236 mStats.writeToParcel(out, 0);
237 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800238 byte[] data = out.marshall();
239 out.recycle();
240 return data;
241 }
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700242
243 public ParcelFileDescriptor getStatisticsStream() {
244 mContext.enforceCallingPermission(
245 android.Manifest.permission.BATTERY_STATS, null);
246 //Slog.i("foo", "SENDING BATTERY INFO:");
247 //mStats.dumpLocked(new LogPrinter(Log.INFO, "foo", Log.LOG_ID_SYSTEM));
248 Parcel out = Parcel.obtain();
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700249 updateExternalStats();
250 synchronized (mStats) {
251 mStats.writeToParcel(out, 0);
252 }
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700253 byte[] data = out.marshall();
254 out.recycle();
255 try {
256 return ParcelFileDescriptor.fromData(data, "battery-stats");
257 } catch (IOException e) {
258 Slog.w(TAG, "Unable to create shared memory", e);
259 return null;
260 }
261 }
262
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700263 public boolean isCharging() {
264 synchronized (mStats) {
265 return mStats.isCharging();
266 }
267 }
268
Dianne Hackbornab5c0ea2014-04-29 14:53:32 -0700269 public long computeBatteryTimeRemaining() {
270 synchronized (mStats) {
271 long time = mStats.computeBatteryTimeRemaining(SystemClock.elapsedRealtime());
272 return time >= 0 ? (time/1000) : time;
273 }
274 }
275
276 public long computeChargeTimeRemaining() {
277 synchronized (mStats) {
278 long time = mStats.computeChargeTimeRemaining(SystemClock.elapsedRealtime());
279 return time >= 0 ? (time/1000) : time;
280 }
281 }
282
Dianne Hackborn099bc622014-01-22 13:39:16 -0800283 public void noteEvent(int code, String name, int uid) {
284 enforceCallingPermission();
285 synchronized (mStats) {
286 mStats.noteEventLocked(code, name, uid);
287 }
288 }
289
Dianne Hackbornfdb19562014-07-11 16:03:36 -0700290 public void noteSyncStart(String name, int uid) {
291 enforceCallingPermission();
292 synchronized (mStats) {
293 mStats.noteSyncStartLocked(name, uid);
294 }
295 }
296
297 public void noteSyncFinish(String name, int uid) {
298 enforceCallingPermission();
299 synchronized (mStats) {
300 mStats.noteSyncFinishLocked(name, uid);
301 }
302 }
303
304 public void noteJobStart(String name, int uid) {
305 enforceCallingPermission();
306 synchronized (mStats) {
307 mStats.noteJobStartLocked(name, uid);
308 }
309 }
310
311 public void noteJobFinish(String name, int uid) {
312 enforceCallingPermission();
313 synchronized (mStats) {
314 mStats.noteJobFinishLocked(name, uid);
315 }
316 }
317
Dianne Hackborn1e383822015-04-10 14:02:33 -0700318 public void noteAlarmStart(String name, int uid) {
319 enforceCallingPermission();
320 synchronized (mStats) {
321 mStats.noteAlarmStartLocked(name, uid);
322 }
323 }
324
325 public void noteAlarmFinish(String name, int uid) {
326 enforceCallingPermission();
327 synchronized (mStats) {
328 mStats.noteAlarmFinishLocked(name, uid);
329 }
330 }
331
Dianne Hackborna1f1a3c2014-02-24 18:12:28 -0800332 public void noteStartWakelock(int uid, int pid, String name, String historyName, int type,
Dianne Hackborn3d658bf2014-02-05 13:38:56 -0800333 boolean unimportantForLogging) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800334 enforceCallingPermission();
335 synchronized (mStats) {
Dianne Hackborne5167ca2014-03-08 14:39:10 -0800336 mStats.noteStartWakeLocked(uid, pid, name, historyName, type, unimportantForLogging,
Dianne Hackborn40c87252014-03-19 16:55:40 -0700337 SystemClock.elapsedRealtime(), SystemClock.uptimeMillis());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800338 }
339 }
340
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700341 public void noteStopWakelock(int uid, int pid, String name, String historyName, int type) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800342 enforceCallingPermission();
343 synchronized (mStats) {
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700344 mStats.noteStopWakeLocked(uid, pid, name, historyName, type,
345 SystemClock.elapsedRealtime(), SystemClock.uptimeMillis());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800346 }
347 }
348
Dianne Hackborna1f1a3c2014-02-24 18:12:28 -0800349 public void noteStartWakelockFromSource(WorkSource ws, int pid, String name,
350 String historyName, int type, boolean unimportantForLogging) {
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700351 enforceCallingPermission();
352 synchronized (mStats) {
Dianne Hackborna1f1a3c2014-02-24 18:12:28 -0800353 mStats.noteStartWakeFromSourceLocked(ws, pid, name, historyName,
354 type, unimportantForLogging);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700355 }
356 }
357
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700358 public void noteChangeWakelockFromSource(WorkSource ws, int pid, String name,
359 String historyName, int type, WorkSource newWs, int newPid, String newName,
Dianne Hackborne5167ca2014-03-08 14:39:10 -0800360 String newHistoryName, int newType, boolean newUnimportantForLogging) {
361 enforceCallingPermission();
362 synchronized (mStats) {
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700363 mStats.noteChangeWakelockFromSourceLocked(ws, pid, name, historyName, type,
Dianne Hackborne5167ca2014-03-08 14:39:10 -0800364 newWs, newPid, newName, newHistoryName, newType, newUnimportantForLogging);
365 }
366 }
367
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700368 public void noteStopWakelockFromSource(WorkSource ws, int pid, String name, String historyName,
369 int type) {
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700370 enforceCallingPermission();
371 synchronized (mStats) {
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700372 mStats.noteStopWakeFromSourceLocked(ws, pid, name, historyName, type);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700373 }
374 }
375
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800376 public void noteStartSensor(int uid, int sensor) {
377 enforceCallingPermission();
378 synchronized (mStats) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700379 mStats.noteStartSensorLocked(uid, sensor);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800380 }
381 }
382
383 public void noteStopSensor(int uid, int sensor) {
384 enforceCallingPermission();
385 synchronized (mStats) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700386 mStats.noteStopSensorLocked(uid, sensor);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800387 }
388 }
389
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800390 public void noteVibratorOn(int uid, long durationMillis) {
391 enforceCallingPermission();
392 synchronized (mStats) {
393 mStats.noteVibratorOnLocked(uid, durationMillis);
394 }
395 }
396
397 public void noteVibratorOff(int uid) {
398 enforceCallingPermission();
399 synchronized (mStats) {
400 mStats.noteVibratorOffLocked(uid);
401 }
402 }
403
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800404 public void noteStartGps(int uid) {
405 enforceCallingPermission();
406 synchronized (mStats) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700407 mStats.noteStartGpsLocked(uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800408 }
409 }
410
411 public void noteStopGps(int uid) {
412 enforceCallingPermission();
413 synchronized (mStats) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700414 mStats.noteStopGpsLocked(uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800415 }
416 }
417
Jeff Browne95c3cd2014-05-02 16:59:26 -0700418 public void noteScreenState(int state) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800419 enforceCallingPermission();
420 synchronized (mStats) {
Jeff Browne95c3cd2014-05-02 16:59:26 -0700421 mStats.noteScreenStateLocked(state);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800422 }
423 }
424
Dianne Hackborn617f8772009-03-31 15:04:46 -0700425 public void noteScreenBrightness(int brightness) {
426 enforceCallingPermission();
427 synchronized (mStats) {
428 mStats.noteScreenBrightnessLocked(brightness);
429 }
430 }
431
Dianne Hackborn617f8772009-03-31 15:04:46 -0700432 public void noteUserActivity(int uid, int event) {
433 enforceCallingPermission();
434 synchronized (mStats) {
435 mStats.noteUserActivityLocked(uid, event);
436 }
437 }
Jeff Browne95c3cd2014-05-02 16:59:26 -0700438
439 public void noteInteractive(boolean interactive) {
440 enforceCallingPermission();
441 synchronized (mStats) {
442 mStats.noteInteractiveLocked(interactive);
443 }
444 }
Dianne Hackborne13c4c02014-02-11 17:18:35 -0800445
Dianne Hackborn1e01d162014-12-04 17:46:42 -0800446 public void noteConnectivityChanged(int type, String extra) {
447 enforceCallingPermission();
448 synchronized (mStats) {
449 mStats.noteConnectivityChangedLocked(type, extra);
450 }
451 }
452
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -0700453 public void noteMobileRadioPowerState(int powerState, long timestampNs) {
Dianne Hackborne13c4c02014-02-11 17:18:35 -0800454 enforceCallingPermission();
455 synchronized (mStats) {
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -0700456 mStats.noteMobileRadioPowerState(powerState, timestampNs);
Dianne Hackborne13c4c02014-02-11 17:18:35 -0800457 }
458 }
459
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800460 public void notePhoneOn() {
461 enforceCallingPermission();
462 synchronized (mStats) {
463 mStats.notePhoneOnLocked();
464 }
465 }
466
467 public void notePhoneOff() {
468 enforceCallingPermission();
469 synchronized (mStats) {
470 mStats.notePhoneOffLocked();
471 }
472 }
The Android Open Source Project10592532009-03-18 17:39:46 -0700473
Wink Savillee9b06d72009-05-18 21:47:50 -0700474 public void notePhoneSignalStrength(SignalStrength signalStrength) {
Dianne Hackborn627bba72009-03-24 22:32:56 -0700475 enforceCallingPermission();
476 synchronized (mStats) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700477 mStats.notePhoneSignalStrengthLocked(signalStrength);
Dianne Hackborn627bba72009-03-24 22:32:56 -0700478 }
479 }
480
481 public void notePhoneDataConnectionState(int dataType, boolean hasData) {
482 enforceCallingPermission();
483 synchronized (mStats) {
484 mStats.notePhoneDataConnectionStateLocked(dataType, hasData);
485 }
486 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -0700487
Amith Yamasanif37447b2009-10-08 18:28:01 -0700488 public void notePhoneState(int state) {
Amith Yamasani32dbefd2009-06-19 09:21:17 -0700489 enforceCallingPermission();
Dianne Hackborne4a59512010-12-07 11:08:07 -0800490 int simState = TelephonyManager.getDefault().getSimState();
Amith Yamasani32dbefd2009-06-19 09:21:17 -0700491 synchronized (mStats) {
Dianne Hackborne4a59512010-12-07 11:08:07 -0800492 mStats.notePhoneStateLocked(state, simState);
Amith Yamasani32dbefd2009-06-19 09:21:17 -0700493 }
494 }
495
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700496 public void noteWifiOn() {
The Android Open Source Project10592532009-03-18 17:39:46 -0700497 enforceCallingPermission();
498 synchronized (mStats) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700499 mStats.noteWifiOnLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -0700500 }
501 }
502
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700503 public void noteWifiOff() {
The Android Open Source Project10592532009-03-18 17:39:46 -0700504 enforceCallingPermission();
505 synchronized (mStats) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700506 mStats.noteWifiOffLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -0700507 }
508 }
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700509
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700510 public void noteStartAudio(int uid) {
511 enforceCallingPermission();
512 synchronized (mStats) {
513 mStats.noteAudioOnLocked(uid);
514 }
515 }
516
517 public void noteStopAudio(int uid) {
518 enforceCallingPermission();
519 synchronized (mStats) {
520 mStats.noteAudioOffLocked(uid);
521 }
522 }
523
524 public void noteStartVideo(int uid) {
525 enforceCallingPermission();
526 synchronized (mStats) {
527 mStats.noteVideoOnLocked(uid);
528 }
529 }
530
531 public void noteStopVideo(int uid) {
532 enforceCallingPermission();
533 synchronized (mStats) {
534 mStats.noteVideoOffLocked(uid);
535 }
536 }
537
Dianne Hackborn10eaa852014-07-22 22:54:55 -0700538 public void noteResetAudio() {
539 enforceCallingPermission();
540 synchronized (mStats) {
541 mStats.noteResetAudioLocked();
542 }
543 }
544
545 public void noteResetVideo() {
546 enforceCallingPermission();
547 synchronized (mStats) {
548 mStats.noteResetVideoLocked();
549 }
550 }
551
Dianne Hackbornabc7c492014-06-30 16:57:46 -0700552 public void noteFlashlightOn() {
553 enforceCallingPermission();
554 synchronized (mStats) {
555 mStats.noteFlashlightOnLocked();
556 }
557 }
558
559 public void noteFlashlightOff() {
560 enforceCallingPermission();
561 synchronized (mStats) {
562 mStats.noteFlashlightOffLocked();
563 }
564 }
565
Adam Lesinskie08af192015-03-25 16:42:59 -0700566 @Override
567 public void noteWifiRadioPowerState(int powerState, long tsNanos) {
568 enforceCallingPermission();
569
570 // There was a change in WiFi power state.
571 // Collect data now for the past activity.
572 mHandler.scheduleSync();
573 }
574
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700575 public void noteWifiRunning(WorkSource ws) {
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700576 enforceCallingPermission();
577 synchronized (mStats) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700578 mStats.noteWifiRunningLocked(ws);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700579 }
580 }
581
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700582 public void noteWifiRunningChanged(WorkSource oldWs, WorkSource newWs) {
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700583 enforceCallingPermission();
584 synchronized (mStats) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700585 mStats.noteWifiRunningChangedLocked(oldWs, newWs);
586 }
587 }
588
589 public void noteWifiStopped(WorkSource ws) {
590 enforceCallingPermission();
591 synchronized (mStats) {
592 mStats.noteWifiStoppedLocked(ws);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700593 }
594 }
595
Dianne Hackbornca1bf212014-02-14 14:18:36 -0800596 public void noteWifiState(int wifiState, String accessPoint) {
597 enforceCallingPermission();
598 synchronized (mStats) {
599 mStats.noteWifiStateLocked(wifiState, accessPoint);
600 }
601 }
602
Dianne Hackborn3251b902014-06-20 14:40:53 -0700603 public void noteWifiSupplicantStateChanged(int supplState, boolean failedAuth) {
604 enforceCallingPermission();
605 synchronized (mStats) {
606 mStats.noteWifiSupplicantStateChangedLocked(supplState, failedAuth);
607 }
608 }
609
610 public void noteWifiRssiChanged(int newRssi) {
611 enforceCallingPermission();
612 synchronized (mStats) {
613 mStats.noteWifiRssiChangedLocked(newRssi);
614 }
615 }
616
The Android Open Source Project10592532009-03-18 17:39:46 -0700617 public void noteBluetoothOn() {
618 enforceCallingPermission();
Jaikumar Ganesh3f034962010-09-27 17:02:23 -0700619 BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
620 if (adapter != null) {
621 adapter.getProfileProxy(mContext, mBluetoothProfileServiceListener,
622 BluetoothProfile.HEADSET);
623 }
The Android Open Source Project10592532009-03-18 17:39:46 -0700624 synchronized (mStats) {
Jaikumar Ganesh3f034962010-09-27 17:02:23 -0700625 if (mBluetoothHeadset != null) {
626 mStats.noteBluetoothOnLocked();
627 mStats.setBtHeadset(mBluetoothHeadset);
628 } else {
629 mBluetoothPendingStats = true;
630 }
The Android Open Source Project10592532009-03-18 17:39:46 -0700631 }
632 }
Jaikumar Ganesh3f034962010-09-27 17:02:23 -0700633
634 private BluetoothProfile.ServiceListener mBluetoothProfileServiceListener =
635 new BluetoothProfile.ServiceListener() {
636 public void onServiceConnected(int profile, BluetoothProfile proxy) {
637 mBluetoothHeadset = (BluetoothHeadset) proxy;
638 synchronized (mStats) {
639 if (mBluetoothPendingStats) {
640 mStats.noteBluetoothOnLocked();
641 mStats.setBtHeadset(mBluetoothHeadset);
642 mBluetoothPendingStats = false;
643 }
644 }
645 }
646
647 public void onServiceDisconnected(int profile) {
648 mBluetoothHeadset = null;
649 }
650 };
651
The Android Open Source Project10592532009-03-18 17:39:46 -0700652 public void noteBluetoothOff() {
653 enforceCallingPermission();
654 synchronized (mStats) {
Jaikumar Ganesh3f034962010-09-27 17:02:23 -0700655 mBluetoothPendingStats = false;
The Android Open Source Project10592532009-03-18 17:39:46 -0700656 mStats.noteBluetoothOffLocked();
657 }
658 }
659
Dianne Hackbornca1bf212014-02-14 14:18:36 -0800660 public void noteBluetoothState(int bluetoothState) {
Dianne Hackborne13c4c02014-02-11 17:18:35 -0800661 enforceCallingPermission();
662 synchronized (mStats) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -0800663 mStats.noteBluetoothStateLocked(bluetoothState);
Dianne Hackborne13c4c02014-02-11 17:18:35 -0800664 }
665 }
666
The Android Open Source Project10592532009-03-18 17:39:46 -0700667 public void noteFullWifiLockAcquired(int uid) {
668 enforceCallingPermission();
669 synchronized (mStats) {
670 mStats.noteFullWifiLockAcquiredLocked(uid);
671 }
672 }
673
674 public void noteFullWifiLockReleased(int uid) {
675 enforceCallingPermission();
676 synchronized (mStats) {
677 mStats.noteFullWifiLockReleasedLocked(uid);
678 }
679 }
Nick Pelly6ccaa542012-06-15 15:22:47 -0700680
681 public void noteWifiScanStarted(int uid) {
The Android Open Source Project10592532009-03-18 17:39:46 -0700682 enforceCallingPermission();
683 synchronized (mStats) {
Nick Pelly6ccaa542012-06-15 15:22:47 -0700684 mStats.noteWifiScanStartedLocked(uid);
The Android Open Source Project10592532009-03-18 17:39:46 -0700685 }
686 }
Nick Pelly6ccaa542012-06-15 15:22:47 -0700687
688 public void noteWifiScanStopped(int uid) {
The Android Open Source Project10592532009-03-18 17:39:46 -0700689 enforceCallingPermission();
690 synchronized (mStats) {
Nick Pelly6ccaa542012-06-15 15:22:47 -0700691 mStats.noteWifiScanStoppedLocked(uid);
The Android Open Source Project10592532009-03-18 17:39:46 -0700692 }
693 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800694
Robert Greenwalt5347bd42009-05-13 15:10:16 -0700695 public void noteWifiMulticastEnabled(int uid) {
696 enforceCallingPermission();
697 synchronized (mStats) {
698 mStats.noteWifiMulticastEnabledLocked(uid);
699 }
700 }
701
702 public void noteWifiMulticastDisabled(int uid) {
703 enforceCallingPermission();
704 synchronized (mStats) {
705 mStats.noteWifiMulticastDisabledLocked(uid);
706 }
707 }
708
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700709 public void noteFullWifiLockAcquiredFromSource(WorkSource ws) {
710 enforceCallingPermission();
711 synchronized (mStats) {
712 mStats.noteFullWifiLockAcquiredFromSourceLocked(ws);
713 }
714 }
715
716 public void noteFullWifiLockReleasedFromSource(WorkSource ws) {
717 enforceCallingPermission();
718 synchronized (mStats) {
719 mStats.noteFullWifiLockReleasedFromSourceLocked(ws);
720 }
721 }
722
Nick Pelly6ccaa542012-06-15 15:22:47 -0700723 public void noteWifiScanStartedFromSource(WorkSource ws) {
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700724 enforceCallingPermission();
725 synchronized (mStats) {
Nick Pelly6ccaa542012-06-15 15:22:47 -0700726 mStats.noteWifiScanStartedFromSourceLocked(ws);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700727 }
728 }
729
Nick Pelly6ccaa542012-06-15 15:22:47 -0700730 public void noteWifiScanStoppedFromSource(WorkSource ws) {
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700731 enforceCallingPermission();
732 synchronized (mStats) {
Nick Pelly6ccaa542012-06-15 15:22:47 -0700733 mStats.noteWifiScanStoppedFromSourceLocked(ws);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700734 }
735 }
736
Robert Greenwalta029ea12013-09-25 16:38:12 -0700737 public void noteWifiBatchedScanStartedFromSource(WorkSource ws, int csph) {
738 enforceCallingPermission();
739 synchronized (mStats) {
740 mStats.noteWifiBatchedScanStartedFromSourceLocked(ws, csph);
741 }
742 }
743
744 public void noteWifiBatchedScanStoppedFromSource(WorkSource ws) {
745 enforceCallingPermission();
746 synchronized (mStats) {
747 mStats.noteWifiBatchedScanStoppedFromSourceLocked(ws);
748 }
749 }
750
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700751 public void noteWifiMulticastEnabledFromSource(WorkSource ws) {
752 enforceCallingPermission();
753 synchronized (mStats) {
754 mStats.noteWifiMulticastEnabledFromSourceLocked(ws);
755 }
756 }
757
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700758 @Override
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700759 public void noteWifiMulticastDisabledFromSource(WorkSource ws) {
760 enforceCallingPermission();
761 synchronized (mStats) {
762 mStats.noteWifiMulticastDisabledFromSourceLocked(ws);
763 }
764 }
765
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700766 @Override
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700767 public void noteNetworkInterfaceType(String iface, int networkType) {
Jeff Sharkey1059c3c2011-10-04 16:54:49 -0700768 enforceCallingPermission();
769 synchronized (mStats) {
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700770 mStats.noteNetworkInterfaceTypeLocked(iface, networkType);
Jeff Sharkey1059c3c2011-10-04 16:54:49 -0700771 }
772 }
773
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700774 @Override
775 public void noteNetworkStatsEnabled() {
776 enforceCallingPermission();
777 synchronized (mStats) {
778 mStats.noteNetworkStatsEnabledLocked();
779 }
780 }
781
Dianne Hackborn8ad2af72015-03-17 17:00:24 -0700782 @Override
783 public void noteDeviceIdleMode(boolean enabled, boolean fromActive, boolean fromMotion) {
784 enforceCallingPermission();
785 synchronized (mStats) {
786 mStats.noteDeviceIdleModeLocked(enabled, fromActive, fromMotion);
787 }
788 }
789
790 public void notePackageInstalled(String pkgName, int versionCode) {
791 enforceCallingPermission();
792 synchronized (mStats) {
793 mStats.notePackageInstalledLocked(pkgName, versionCode);
794 }
795 }
796
797 public void notePackageUninstalled(String pkgName) {
798 enforceCallingPermission();
799 synchronized (mStats) {
800 mStats.notePackageUninstalledLocked(pkgName);
801 }
802 }
803
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800804 public boolean isOnBattery() {
805 return mStats.isOnBattery();
806 }
807
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700808 public void setBatteryState(int status, int health, int plugType, int level,
809 int temp, int volt) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800810 enforceCallingPermission();
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700811 synchronized (mStats) {
812 final boolean onBattery = plugType == BatteryStatsImpl.BATTERY_PLUGGED_NONE;
813 if (mStats.isOnBattery() == onBattery) {
814 // The battery state has not changed, so we don't need to sync external
815 // stats immediately.
816 mStats.setBatteryStateLocked(status, health, plugType, level, temp, volt);
817 return;
818 }
819 }
820
821 // Sync external stats first as the battery has changed states. If we don't sync
822 // immediately here, we may not collect the relevant data later.
823 updateExternalStats();
824 synchronized (mStats) {
825 mStats.setBatteryStateLocked(status, health, plugType, level, temp, volt);
826 }
Evan Millar633a1742009-04-02 16:36:33 -0700827 }
828
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800829 public long getAwakeTimeBattery() {
830 mContext.enforceCallingOrSelfPermission(
831 android.Manifest.permission.BATTERY_STATS, null);
832 return mStats.getAwakeTimeBattery();
833 }
834
835 public long getAwakeTimePlugged() {
836 mContext.enforceCallingOrSelfPermission(
837 android.Manifest.permission.BATTERY_STATS, null);
838 return mStats.getAwakeTimePlugged();
839 }
840
841 public void enforceCallingPermission() {
842 if (Binder.getCallingPid() == Process.myPid()) {
843 return;
844 }
845 mContext.enforcePermission(android.Manifest.permission.UPDATE_DEVICE_STATS,
846 Binder.getCallingPid(), Binder.getCallingUid(), null);
847 }
Dianne Hackbornc51cf032014-03-02 19:08:15 -0800848
849 final class WakeupReasonThread extends Thread {
850 final int[] mIrqs = new int[32];
851 final String[] mReasons = new String[32];
852
853 WakeupReasonThread() {
854 super("BatteryStats_wakeupReason");
855 }
856
857 public void run() {
858 Process.setThreadPriority(Process.THREAD_PRIORITY_FOREGROUND);
859
860 try {
861 int num;
862 while ((num=nativeWaitWakeup(mIrqs, mReasons)) >= 0) {
863 synchronized (mStats) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700864 if (num > 0) {
865 for (int i=0; i<num; i++) {
866 mStats.noteWakeupReasonLocked(mReasons[i]);
867 }
868 } else {
869 mStats.noteWakeupReasonLocked("unknown");
Dianne Hackbornc51cf032014-03-02 19:08:15 -0800870 }
871 }
872 }
873 } catch (RuntimeException e) {
874 Slog.e(TAG, "Failure reading wakeup reasons", e);
875 }
876 }
877 }
878
879 private static native int nativeWaitWakeup(int[] outIrqs, String[] outReasons);
880
Dianne Hackbornae384452011-06-28 12:33:48 -0700881 private void dumpHelp(PrintWriter pw) {
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700882 pw.println("Battery stats (batterystats) dump options:");
Dianne Hackborn1e725a72015-03-24 18:23:19 -0700883 pw.println(" [--checkin] [--history] [--history-start] [--charged] [-c]");
Dianne Hackbornd4a8af72015-03-03 10:06:15 -0800884 pw.println(" [--daily] [--reset] [--write] [--new-daily] [--read-daily] [-h] [<package.name>]");
Dianne Hackbornae384452011-06-28 12:33:48 -0700885 pw.println(" --checkin: format output for a checkin report.");
Dianne Hackborn099bc622014-01-22 13:39:16 -0800886 pw.println(" --history: show only history data.");
Dianne Hackbornc51cf032014-03-02 19:08:15 -0800887 pw.println(" --history-start <num>: show only history data starting at given time offset.");
Dianne Hackbornc51cf032014-03-02 19:08:15 -0800888 pw.println(" --charged: only output data since last charged.");
Dianne Hackbornd4a8af72015-03-03 10:06:15 -0800889 pw.println(" --daily: only output full daily data.");
Dianne Hackbornae384452011-06-28 12:33:48 -0700890 pw.println(" --reset: reset the stats, clearing all current data.");
891 pw.println(" --write: force write current collected stats to disk.");
Dianne Hackbornd4a8af72015-03-03 10:06:15 -0800892 pw.println(" --new-daily: immediately create and write new daily stats record.");
893 pw.println(" --read-daily: read-load last written daily stats.");
Dianne Hackborncbfd23e2013-06-11 14:26:53 -0700894 pw.println(" <package.name>: optional name of package to filter output by.");
Dianne Hackbornfc064132014-06-02 12:42:12 -0700895 pw.println(" -h: print this help text.");
896 pw.println("Battery stats (batterystats) commands:");
897 pw.println(" enable|disable <option>");
898 pw.println(" Enable or disable a running option. Option state is not saved across boots.");
899 pw.println(" Options are:");
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700900 pw.println(" full-history: include additional detailed events in battery history:");
Dianne Hackborn1e383822015-04-10 14:02:33 -0700901 pw.println(" wake_lock_in, alarms and proc events");
Dianne Hackbornfc064132014-06-02 12:42:12 -0700902 pw.println(" no-auto-reset: don't automatically reset stats when unplugged");
Dianne Hackbornae384452011-06-28 12:33:48 -0700903 }
904
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700905 private int doEnableOrDisable(PrintWriter pw, int i, String[] args, boolean enable) {
906 i++;
907 if (i >= args.length) {
908 pw.println("Missing option argument for " + (enable ? "--enable" : "--disable"));
909 dumpHelp(pw);
910 return -1;
911 }
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700912 if ("full-wake-history".equals(args[i]) || "full-history".equals(args[i])) {
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700913 synchronized (mStats) {
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700914 mStats.setRecordAllHistoryLocked(enable);
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700915 }
Dianne Hackborn9a755432014-05-15 17:05:22 -0700916 } else if ("no-auto-reset".equals(args[i])) {
917 synchronized (mStats) {
918 mStats.setNoAutoReset(enable);
919 }
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700920 } else {
921 pw.println("Unknown enable/disable option: " + args[i]);
922 dumpHelp(pw);
923 return -1;
924 }
925 return i;
926 }
927
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700928
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800929 @Override
930 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Kenny Root3abd75b2011-09-29 11:00:41 -0700931 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
932 != PackageManager.PERMISSION_GRANTED) {
933 pw.println("Permission Denial: can't dump BatteryStats from from pid="
934 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
935 + " without permission " + android.Manifest.permission.DUMP);
936 return;
937 }
938
Dianne Hackbornc51cf032014-03-02 19:08:15 -0800939 int flags = 0;
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700940 boolean useCheckinFormat = false;
941 boolean isRealCheckin = false;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700942 boolean noOutput = false;
Dianne Hackborn16b0b562014-06-03 17:24:42 -0700943 boolean writeData = false;
Dianne Hackbornc51cf032014-03-02 19:08:15 -0800944 long historyStart = -1;
Dianne Hackborncbfd23e2013-06-11 14:26:53 -0700945 int reqUid = -1;
Dianne Hackborne4a59512010-12-07 11:08:07 -0800946 if (args != null) {
Dianne Hackbornc51cf032014-03-02 19:08:15 -0800947 for (int i=0; i<args.length; i++) {
948 String arg = args[i];
Dianne Hackborne4a59512010-12-07 11:08:07 -0800949 if ("--checkin".equals(arg)) {
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700950 useCheckinFormat = true;
951 isRealCheckin = true;
Dianne Hackborn099bc622014-01-22 13:39:16 -0800952 } else if ("--history".equals(arg)) {
Dianne Hackbornc51cf032014-03-02 19:08:15 -0800953 flags |= BatteryStats.DUMP_HISTORY_ONLY;
954 } else if ("--history-start".equals(arg)) {
955 flags |= BatteryStats.DUMP_HISTORY_ONLY;
956 i++;
957 if (i >= args.length) {
958 pw.println("Missing time argument for --history-since");
959 dumpHelp(pw);
960 return;
961 }
962 historyStart = Long.parseLong(args[i]);
Dianne Hackborn16b0b562014-06-03 17:24:42 -0700963 writeData = true;
Dianne Hackborn49021f52013-09-04 18:03:40 -0700964 } else if ("-c".equals(arg)) {
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700965 useCheckinFormat = true;
Dianne Hackbornc51cf032014-03-02 19:08:15 -0800966 flags |= BatteryStats.DUMP_INCLUDE_HISTORY;
Dianne Hackbornc51cf032014-03-02 19:08:15 -0800967 } else if ("--charged".equals(arg)) {
968 flags |= BatteryStats.DUMP_CHARGED_ONLY;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -0800969 } else if ("--daily".equals(arg)) {
970 flags |= BatteryStats.DUMP_DAILY_ONLY;
Dianne Hackborne4a59512010-12-07 11:08:07 -0800971 } else if ("--reset".equals(arg)) {
972 synchronized (mStats) {
Dianne Hackborn3d658bf2014-02-05 13:38:56 -0800973 mStats.resetAllStatsCmdLocked();
Dianne Hackborne4a59512010-12-07 11:08:07 -0800974 pw.println("Battery stats reset.");
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700975 noOutput = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800976 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700977 updateExternalStats();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700978 } else if ("--write".equals(arg)) {
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700979 updateExternalStats();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700980 synchronized (mStats) {
981 mStats.writeSyncLocked();
982 pw.println("Battery stats written.");
983 noOutput = true;
984 }
Dianne Hackbornd4a8af72015-03-03 10:06:15 -0800985 } else if ("--new-daily".equals(arg)) {
986 synchronized (mStats) {
987 mStats.recordDailyStatsLocked();
988 pw.println("New daily stats written.");
989 noOutput = true;
990 }
991 } else if ("--read-daily".equals(arg)) {
992 synchronized (mStats) {
993 mStats.readDailyStatsLocked();
994 pw.println("Last daily stats read.");
995 noOutput = true;
996 }
Dianne Hackbornfc064132014-06-02 12:42:12 -0700997 } else if ("--enable".equals(arg) || "enable".equals(arg)) {
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700998 i = doEnableOrDisable(pw, i, args, true);
999 if (i < 0) {
1000 return;
1001 }
1002 pw.println("Enabled: " + args[i]);
1003 return;
Dianne Hackbornfc064132014-06-02 12:42:12 -07001004 } else if ("--disable".equals(arg) || "disable".equals(arg)) {
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07001005 i = doEnableOrDisable(pw, i, args, false);
1006 if (i < 0) {
1007 return;
1008 }
1009 pw.println("Disabled: " + args[i]);
1010 return;
Dianne Hackbornae384452011-06-28 12:33:48 -07001011 } else if ("-h".equals(arg)) {
1012 dumpHelp(pw);
1013 return;
Mike Lockwoode8174042011-08-16 12:53:43 -07001014 } else if ("-a".equals(arg)) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07001015 flags |= BatteryStats.DUMP_VERBOSE;
Dianne Hackborncbfd23e2013-06-11 14:26:53 -07001016 } else if (arg.length() > 0 && arg.charAt(0) == '-'){
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001017 pw.println("Unknown option: " + arg);
Dianne Hackbornae384452011-06-28 12:33:48 -07001018 dumpHelp(pw);
Dianne Hackborncbfd23e2013-06-11 14:26:53 -07001019 return;
1020 } else {
1021 // Not an option, last argument must be a package name.
1022 try {
1023 reqUid = mContext.getPackageManager().getPackageUid(arg,
1024 UserHandle.getCallingUserId());
1025 } catch (PackageManager.NameNotFoundException e) {
1026 pw.println("Unknown package: " + arg);
1027 dumpHelp(pw);
1028 return;
1029 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001030 }
1031 }
Dianne Hackborne4a59512010-12-07 11:08:07 -08001032 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001033 if (noOutput) {
1034 return;
1035 }
Dianne Hackbornd953c532014-08-16 18:17:38 -07001036 if (BatteryStatsHelper.checkWifiOnly(mContext)) {
1037 flags |= BatteryStats.DUMP_DEVICE_WIFI_ONLY;
1038 }
Dianne Hackbornab4a81b2014-10-09 17:59:38 -07001039 if (reqUid >= 0) {
1040 // By default, if the caller is only interested in a specific package, then
1041 // we only dump the aggregated data since charged.
Dianne Hackborn1e725a72015-03-24 18:23:19 -07001042 if ((flags&(BatteryStats.DUMP_HISTORY_ONLY|BatteryStats.DUMP_CHARGED_ONLY)) == 0) {
Dianne Hackbornab4a81b2014-10-09 17:59:38 -07001043 flags |= BatteryStats.DUMP_CHARGED_ONLY;
1044 // Also if they are doing -c, we don't want history.
1045 flags &= ~BatteryStats.DUMP_INCLUDE_HISTORY;
1046 }
1047 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07001048
1049 // Fetch data from external sources and update the BatteryStatsImpl object with them.
1050 updateExternalStats();
1051
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07001052 if (useCheckinFormat) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08001053 List<ApplicationInfo> apps = mContext.getPackageManager().getInstalledApplications(0);
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07001054 if (isRealCheckin) {
1055 // For a real checkin, first we want to prefer to use the last complete checkin
1056 // file if there is one.
1057 synchronized (mStats.mCheckinFile) {
1058 if (mStats.mCheckinFile.exists()) {
1059 try {
1060 byte[] raw = mStats.mCheckinFile.readFully();
1061 if (raw != null) {
1062 Parcel in = Parcel.obtain();
1063 in.unmarshall(raw, 0, raw.length);
1064 in.setDataPosition(0);
1065 BatteryStatsImpl checkinStats = new BatteryStatsImpl(
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07001066 null, mStats.mHandler, null);
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07001067 checkinStats.readSummaryFromParcel(in);
1068 in.recycle();
1069 checkinStats.dumpCheckinLocked(mContext, pw, apps, flags,
1070 historyStart);
1071 mStats.mCheckinFile.delete();
1072 return;
1073 }
1074 } catch (IOException e) {
1075 Slog.w(TAG, "Failure reading checkin file "
1076 + mStats.mCheckinFile.getBaseFile(), e);
1077 }
1078 }
1079 }
1080 }
Dianne Hackborne4a59512010-12-07 11:08:07 -08001081 synchronized (mStats) {
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001082 mStats.dumpCheckinLocked(mContext, pw, apps, flags, historyStart);
Dianne Hackborn16b0b562014-06-03 17:24:42 -07001083 if (writeData) {
1084 mStats.writeAsyncLocked();
1085 }
Dianne Hackborne4a59512010-12-07 11:08:07 -08001086 }
1087 } else {
1088 synchronized (mStats) {
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001089 mStats.dumpLocked(mContext, pw, flags, reqUid, historyStart);
Dianne Hackborn16b0b562014-06-03 17:24:42 -07001090 if (writeData) {
1091 mStats.writeAsyncLocked();
1092 }
Dianne Hackborne4a59512010-12-07 11:08:07 -08001093 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001094 }
1095 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07001096
1097 // Objects for extracting data from external sources.
1098 private final Object mExternalStatsLock = new Object();
1099
1100 @GuardedBy("mExternalStatsLock")
1101 private IWifiManager mWifiManager;
1102
1103 // WiFi keeps an accumulated total of stats, unlike Bluetooth.
1104 // Keep the last WiFi stats so we can compute a delta.
1105 @GuardedBy("mExternalStatsLock")
1106 private WifiActivityEnergyInfo mLastInfo = new WifiActivityEnergyInfo(0, 0, 0, 0, 0, 0);
1107
1108 @GuardedBy("mExternalStatsLock")
1109 private WifiActivityEnergyInfo pullWifiEnergyInfoLocked() {
1110 if (mWifiManager == null) {
1111 mWifiManager = IWifiManager.Stub.asInterface(
1112 ServiceManager.getService(Context.WIFI_SERVICE));
1113 if (mWifiManager == null) {
1114 return null;
1115 }
1116 }
1117
1118 try {
1119 // We read the data even if we are not on battery. This is so that we keep the
1120 // correct delta from when we should start reading (aka when we are on battery).
1121 WifiActivityEnergyInfo info = mWifiManager.reportActivityInfo();
1122 if (info != null && info.isValid()) {
1123 // We will modify the last info object to be the delta, and store the new
1124 // WifiActivityEnergyInfo object as our last one.
1125 final WifiActivityEnergyInfo result = mLastInfo;
1126 result.mTimestamp = info.getTimeStamp();
1127 result.mStackState = info.getStackState();
1128 result.mControllerTxTimeMs =
Adam Lesinskie08af192015-03-25 16:42:59 -07001129 info.mControllerTxTimeMs - mLastInfo.mControllerTxTimeMs;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07001130 result.mControllerRxTimeMs =
Adam Lesinskie08af192015-03-25 16:42:59 -07001131 info.mControllerRxTimeMs - mLastInfo.mControllerRxTimeMs;
Bart Searse9b9b732015-04-07 06:14:04 +00001132 result.mControllerEnergyUsed =
Adam Lesinskie08af192015-03-25 16:42:59 -07001133 info.mControllerEnergyUsed - mLastInfo.mControllerEnergyUsed;
1134
1135 // WiFi calculates the idle time as a difference from the on time and the various
1136 // Rx + Tx times. There seems to be some missing time there because this sometimes
1137 // becomes negative. Just cap it at 0 and move on.
1138 result.mControllerIdleTimeMs =
1139 Math.max(0, info.mControllerIdleTimeMs - mLastInfo.mControllerIdleTimeMs);
1140
1141 if (result.mControllerTxTimeMs < 0 ||
1142 result.mControllerRxTimeMs < 0) {
1143 // The stats were reset by the WiFi system (which is why our delta is negative).
1144 // Returns the unaltered stats.
1145 result.mControllerEnergyUsed = info.mControllerEnergyUsed;
1146 result.mControllerRxTimeMs = info.mControllerRxTimeMs;
1147 result.mControllerTxTimeMs = info.mControllerTxTimeMs;
1148 result.mControllerIdleTimeMs = info.mControllerIdleTimeMs;
1149
1150 Slog.v(TAG, "WiFi energy data was reset, new WiFi energy data is " + result);
1151 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07001152 mLastInfo = info;
1153 return result;
1154 }
1155 } catch (RemoteException e) {
1156 // Nothing to report, WiFi is dead.
1157 }
1158 return null;
1159 }
1160
1161 @GuardedBy("mExternalStatsLock")
1162 private BluetoothActivityEnergyInfo pullBluetoothEnergyInfoLocked() {
1163 BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
1164 if (adapter != null) {
1165 BluetoothActivityEnergyInfo info = adapter.getControllerActivityEnergyInfo(
1166 BluetoothAdapter.ACTIVITY_ENERGY_INFO_REFRESHED);
1167 if (info != null && info.isValid()) {
1168 return info;
1169 }
1170 }
1171 return null;
1172 }
1173
1174 /**
1175 * Fetches data from external sources (WiFi controller, bluetooth chipset) and updates
1176 * batterystats with that information.
1177 *
1178 * We first grab a lock specific to this method, then once all the data has been collected,
1179 * we grab the mStats lock and update the data.
1180 */
1181 void updateExternalStats() {
1182 synchronized (mExternalStatsLock) {
Adam Lesinskie08af192015-03-25 16:42:59 -07001183 if (mContext == null) {
1184 // We haven't started yet (which means the BatteryStatsImpl object has
1185 // no power profile. Don't consume data we can't compute yet.
1186 return;
1187 }
1188
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07001189 final WifiActivityEnergyInfo wifiEnergyInfo = pullWifiEnergyInfoLocked();
1190 final BluetoothActivityEnergyInfo bluetoothEnergyInfo = pullBluetoothEnergyInfoLocked();
1191 synchronized (mStats) {
1192 mStats.updateKernelWakelocksLocked();
1193 mStats.updateMobileRadioStateLocked(SystemClock.elapsedRealtime());
1194 mStats.updateWifiStateLocked(wifiEnergyInfo);
1195 mStats.updateBluetoothStateLocked(bluetoothEnergyInfo);
1196 }
1197 }
1198 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001199}