blob: 905adc0b02d9ebf53454bdaa379b8e3629bfa23f [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;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080021import android.content.Context;
Dianne Hackborne4a59512010-12-07 11:08:07 -080022import android.content.pm.ApplicationInfo;
Kenny Root3abd75b2011-09-29 11:00:41 -070023import android.content.pm.PackageManager;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070024import android.net.wifi.IWifiManager;
25import android.net.wifi.WifiActivityEnergyInfo;
Dianne Hackborn91268cf2013-06-13 19:06:50 -070026import android.os.BatteryStats;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080027import android.os.Binder;
Jeff Brown6f357d32014-01-15 20:40:55 -080028import android.os.Handler;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029import android.os.IBinder;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070030import android.os.Looper;
31import android.os.Message;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080032import android.os.Parcel;
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -070033import android.os.ParcelFileDescriptor;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -070034import android.os.PowerManagerInternal;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080035import android.os.Process;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070036import android.os.RemoteException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080037import android.os.ServiceManager;
Dianne Hackborne5167ca2014-03-08 14:39:10 -080038import android.os.SystemClock;
Dianne Hackborncbfd23e2013-06-11 14:26:53 -070039import android.os.UserHandle;
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -070040import android.os.WorkSource;
Wink Savillee9b06d72009-05-18 21:47:50 -070041import android.telephony.SignalStrength;
Dianne Hackborne4a59512010-12-07 11:08:07 -080042import android.telephony.TelephonyManager;
Joe Onorato8a9b2202010-02-26 18:56:32 -080043import android.util.Slog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080044
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070045import com.android.internal.annotations.GuardedBy;
Amith Yamasani32dbefd2009-06-19 09:21:17 -070046import com.android.internal.app.IBatteryStats;
Dianne Hackbornd953c532014-08-16 18:17:38 -070047import com.android.internal.os.BatteryStatsHelper;
Amith Yamasani32dbefd2009-06-19 09:21:17 -070048import com.android.internal.os.BatteryStatsImpl;
Amith Yamasanie43530a2009-08-21 13:11:37 -070049import com.android.internal.os.PowerProfile;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070050import com.android.server.FgThread;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -070051import com.android.server.LocalServices;
Amith Yamasani32dbefd2009-06-19 09:21:17 -070052
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -070053import java.io.File;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080054import java.io.FileDescriptor;
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -070055import java.io.IOException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080056import java.io.PrintWriter;
Dianne Hackborne4a59512010-12-07 11:08:07 -080057import java.util.List;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080058
59/**
60 * All information we are collecting about things that can happen that impact
61 * battery life.
62 */
Dianne Hackborncbefd8d2014-05-14 11:42:00 -070063public final class BatteryStatsService extends IBatteryStats.Stub
64 implements PowerManagerInternal.LowPowerModeListener {
Dianne Hackbornc51cf032014-03-02 19:08:15 -080065 static final String TAG = "BatteryStatsService";
66
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080067 static IBatteryStats sService;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080068 final BatteryStatsImpl mStats;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070069 final BatteryStatsHandler mHandler;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080070 Context mContext;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -070071 PowerManagerInternal mPowerManagerInternal;
Amith Yamasani3f7e35c2009-07-13 16:02:45 -070072
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070073 class BatteryStatsHandler extends Handler implements BatteryStatsImpl.ExternalStatsSync {
74 public static final int MSG_SYNC_EXTERNAL_STATS = 1;
75 public static final int MSG_WRITE_TO_DISK = 2;
76
77 public BatteryStatsHandler(Looper looper) {
78 super(looper);
79 }
80
81 @Override
82 public void handleMessage(Message msg) {
83 switch (msg.what) {
84 case MSG_SYNC_EXTERNAL_STATS:
Dianne Hackborn0c820db2015-04-14 17:47:34 -070085 updateExternalStats((String)msg.obj);
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070086 break;
87
88 case MSG_WRITE_TO_DISK:
Dianne Hackborn0c820db2015-04-14 17:47:34 -070089 updateExternalStats("write");
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070090 synchronized (mStats) {
91 mStats.writeAsyncLocked();
92 }
93 break;
94 }
95 }
96
97 @Override
Dianne Hackborn0c820db2015-04-14 17:47:34 -070098 public void scheduleSync(String reason) {
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070099 if (!hasMessages(MSG_SYNC_EXTERNAL_STATS)) {
Dianne Hackborn0c820db2015-04-14 17:47:34 -0700100 Message msg = Message.obtain(this, MSG_SYNC_EXTERNAL_STATS, reason);
101 sendMessage(msg);
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700102 }
103 }
104 }
105
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700106 BatteryStatsService(File systemDir, Handler handler) {
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700107 // Our handler here will be accessing the disk, use a different thread than
108 // what the ActivityManagerService gave us (no I/O on that one!).
109 mHandler = new BatteryStatsHandler(FgThread.getHandler().getLooper());
110
111 // BatteryStatsImpl expects the ActivityManagerService handler, so pass that one through.
112 mStats = new BatteryStatsImpl(systemDir, handler, mHandler);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800113 }
114
115 public void publish(Context context) {
116 mContext = context;
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700117 ServiceManager.addService(BatteryStats.SERVICE_NAME, asBinder());
Amith Yamasanie43530a2009-08-21 13:11:37 -0700118 mStats.setNumSpeedSteps(new PowerProfile(mContext).getNumSpeedSteps());
Amith Yamasanif37447b2009-10-08 18:28:01 -0700119 mStats.setRadioScanningTimeout(mContext.getResources().getInteger(
120 com.android.internal.R.integer.config_radioScanningTimeout)
121 * 1000L);
Adam Lesinskie08af192015-03-25 16:42:59 -0700122 mStats.setPowerProfile(new PowerProfile(context));
Jeff Brown2c43c332014-06-12 22:38:59 -0700123 }
124
125 /**
126 * At the time when the constructor runs, the power manager has not yet been
127 * initialized. So we initialize the low power observer later.
128 */
129 public void initPowerManagement() {
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700130 mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
131 mPowerManagerInternal.registerLowPowerModeObserver(this);
Dianne Hackborn8ad2af72015-03-17 17:00:24 -0700132 mStats.notePowerSaveMode(mPowerManagerInternal.getLowPowerModeEnabled());
Dianne Hackbornc51cf032014-03-02 19:08:15 -0800133 (new WakeupReasonThread()).start();
Jeff Brown2c43c332014-06-12 22:38:59 -0700134 }
135
Dianne Hackborn55280a92009-05-07 15:53:46 -0700136 public void shutdown() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800137 Slog.w("BatteryStats", "Writing battery stats before shutdown...");
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700138
Dianne Hackborn0c820db2015-04-14 17:47:34 -0700139 updateExternalStats("shutdown");
Dianne Hackborn55280a92009-05-07 15:53:46 -0700140 synchronized (mStats) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700141 mStats.shutdownLocked();
Dianne Hackborn55280a92009-05-07 15:53:46 -0700142 }
143 }
144
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800145 public static IBatteryStats getService() {
146 if (sService != null) {
147 return sService;
148 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700149 IBinder b = ServiceManager.getService(BatteryStats.SERVICE_NAME);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800150 sService = asInterface(b);
151 return sService;
152 }
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700153
154 @Override
155 public void onLowPowerModeChanged(boolean enabled) {
156 synchronized (mStats) {
Dianne Hackborn8ad2af72015-03-17 17:00:24 -0700157 mStats.notePowerSaveMode(enabled);
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700158 }
159 }
160
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800161 /**
162 * @return the current statistics object, which may be modified
163 * to reflect events that affect battery usage. You must lock the
164 * stats object before doing anything with it.
165 */
166 public BatteryStatsImpl getActiveStatistics() {
167 return mStats;
168 }
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700169
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700170 /**
171 * Schedules a write to disk to occur. This will cause the BatteryStatsImpl
172 * object to update with the latest info, then write to disk.
173 */
174 public void scheduleWriteToDisk() {
175 mHandler.sendEmptyMessage(BatteryStatsHandler.MSG_WRITE_TO_DISK);
176 }
177
Dianne Hackborn2f1993e2014-09-26 11:28:01 -0700178 // These are for direct use by the activity manager...
179
180 void addIsolatedUid(int isolatedUid, int appUid) {
181 synchronized (mStats) {
182 mStats.addIsolatedUidLocked(isolatedUid, appUid);
183 }
184 }
185
186 void removeIsolatedUid(int isolatedUid, int appUid) {
187 synchronized (mStats) {
188 mStats.removeIsolatedUidLocked(isolatedUid, appUid);
189 }
190 }
191
192 void noteProcessStart(String name, int uid) {
193 synchronized (mStats) {
194 mStats.noteProcessStartLocked(name, uid);
195 }
196 }
197
Dianne Hackborn1e01d162014-12-04 17:46:42 -0800198 void noteProcessCrash(String name, int uid) {
199 synchronized (mStats) {
200 mStats.noteProcessCrashLocked(name, uid);
201 }
202 }
203
204 void noteProcessAnr(String name, int uid) {
205 synchronized (mStats) {
206 mStats.noteProcessAnrLocked(name, uid);
207 }
208 }
209
Dianne Hackborn2f1993e2014-09-26 11:28:01 -0700210 void noteProcessState(String name, int uid, int state) {
211 synchronized (mStats) {
212 mStats.noteProcessStateLocked(name, uid, state);
213 }
214 }
215
216 void noteProcessFinish(String name, int uid) {
217 synchronized (mStats) {
218 mStats.noteProcessFinishLocked(name, uid);
219 }
220 }
221
222 // Public interface...
223
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800224 public byte[] getStatistics() {
225 mContext.enforceCallingPermission(
226 android.Manifest.permission.BATTERY_STATS, null);
Joe Onorato8a9b2202010-02-26 18:56:32 -0800227 //Slog.i("foo", "SENDING BATTERY INFO:");
228 //mStats.dumpLocked(new LogPrinter(Log.INFO, "foo", Log.LOG_ID_SYSTEM));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800229 Parcel out = Parcel.obtain();
Dianne Hackborn0c820db2015-04-14 17:47:34 -0700230 updateExternalStats("get-stats");
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700231 synchronized (mStats) {
232 mStats.writeToParcel(out, 0);
233 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800234 byte[] data = out.marshall();
235 out.recycle();
236 return data;
237 }
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700238
239 public ParcelFileDescriptor getStatisticsStream() {
240 mContext.enforceCallingPermission(
241 android.Manifest.permission.BATTERY_STATS, null);
242 //Slog.i("foo", "SENDING BATTERY INFO:");
243 //mStats.dumpLocked(new LogPrinter(Log.INFO, "foo", Log.LOG_ID_SYSTEM));
244 Parcel out = Parcel.obtain();
Dianne Hackborn0c820db2015-04-14 17:47:34 -0700245 updateExternalStats("get-stats");
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700246 synchronized (mStats) {
247 mStats.writeToParcel(out, 0);
248 }
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700249 byte[] data = out.marshall();
250 out.recycle();
251 try {
252 return ParcelFileDescriptor.fromData(data, "battery-stats");
253 } catch (IOException e) {
254 Slog.w(TAG, "Unable to create shared memory", e);
255 return null;
256 }
257 }
258
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700259 public boolean isCharging() {
260 synchronized (mStats) {
261 return mStats.isCharging();
262 }
263 }
264
Dianne Hackbornab5c0ea2014-04-29 14:53:32 -0700265 public long computeBatteryTimeRemaining() {
266 synchronized (mStats) {
267 long time = mStats.computeBatteryTimeRemaining(SystemClock.elapsedRealtime());
268 return time >= 0 ? (time/1000) : time;
269 }
270 }
271
272 public long computeChargeTimeRemaining() {
273 synchronized (mStats) {
274 long time = mStats.computeChargeTimeRemaining(SystemClock.elapsedRealtime());
275 return time >= 0 ? (time/1000) : time;
276 }
277 }
278
Dianne Hackborn099bc622014-01-22 13:39:16 -0800279 public void noteEvent(int code, String name, int uid) {
280 enforceCallingPermission();
281 synchronized (mStats) {
282 mStats.noteEventLocked(code, name, uid);
283 }
284 }
285
Dianne Hackbornfdb19562014-07-11 16:03:36 -0700286 public void noteSyncStart(String name, int uid) {
287 enforceCallingPermission();
288 synchronized (mStats) {
289 mStats.noteSyncStartLocked(name, uid);
290 }
291 }
292
293 public void noteSyncFinish(String name, int uid) {
294 enforceCallingPermission();
295 synchronized (mStats) {
296 mStats.noteSyncFinishLocked(name, uid);
297 }
298 }
299
300 public void noteJobStart(String name, int uid) {
301 enforceCallingPermission();
302 synchronized (mStats) {
303 mStats.noteJobStartLocked(name, uid);
304 }
305 }
306
307 public void noteJobFinish(String name, int uid) {
308 enforceCallingPermission();
309 synchronized (mStats) {
310 mStats.noteJobFinishLocked(name, uid);
311 }
312 }
313
Dianne Hackborn1e383822015-04-10 14:02:33 -0700314 public void noteAlarmStart(String name, int uid) {
315 enforceCallingPermission();
316 synchronized (mStats) {
317 mStats.noteAlarmStartLocked(name, uid);
318 }
319 }
320
321 public void noteAlarmFinish(String name, int uid) {
322 enforceCallingPermission();
323 synchronized (mStats) {
324 mStats.noteAlarmFinishLocked(name, uid);
325 }
326 }
327
Dianne Hackborna1f1a3c2014-02-24 18:12:28 -0800328 public void noteStartWakelock(int uid, int pid, String name, String historyName, int type,
Dianne Hackborn3d658bf2014-02-05 13:38:56 -0800329 boolean unimportantForLogging) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800330 enforceCallingPermission();
331 synchronized (mStats) {
Dianne Hackborne5167ca2014-03-08 14:39:10 -0800332 mStats.noteStartWakeLocked(uid, pid, name, historyName, type, unimportantForLogging,
Dianne Hackborn40c87252014-03-19 16:55:40 -0700333 SystemClock.elapsedRealtime(), SystemClock.uptimeMillis());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800334 }
335 }
336
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700337 public void noteStopWakelock(int uid, int pid, String name, String historyName, int type) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800338 enforceCallingPermission();
339 synchronized (mStats) {
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700340 mStats.noteStopWakeLocked(uid, pid, name, historyName, type,
341 SystemClock.elapsedRealtime(), SystemClock.uptimeMillis());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800342 }
343 }
344
Dianne Hackborna1f1a3c2014-02-24 18:12:28 -0800345 public void noteStartWakelockFromSource(WorkSource ws, int pid, String name,
346 String historyName, int type, boolean unimportantForLogging) {
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700347 enforceCallingPermission();
348 synchronized (mStats) {
Dianne Hackborna1f1a3c2014-02-24 18:12:28 -0800349 mStats.noteStartWakeFromSourceLocked(ws, pid, name, historyName,
350 type, unimportantForLogging);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700351 }
352 }
353
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700354 public void noteChangeWakelockFromSource(WorkSource ws, int pid, String name,
355 String historyName, int type, WorkSource newWs, int newPid, String newName,
Dianne Hackborne5167ca2014-03-08 14:39:10 -0800356 String newHistoryName, int newType, boolean newUnimportantForLogging) {
357 enforceCallingPermission();
358 synchronized (mStats) {
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700359 mStats.noteChangeWakelockFromSourceLocked(ws, pid, name, historyName, type,
Dianne Hackborne5167ca2014-03-08 14:39:10 -0800360 newWs, newPid, newName, newHistoryName, newType, newUnimportantForLogging);
361 }
362 }
363
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700364 public void noteStopWakelockFromSource(WorkSource ws, int pid, String name, String historyName,
365 int type) {
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700366 enforceCallingPermission();
367 synchronized (mStats) {
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700368 mStats.noteStopWakeFromSourceLocked(ws, pid, name, historyName, type);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700369 }
370 }
371
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800372 public void noteStartSensor(int uid, int sensor) {
373 enforceCallingPermission();
374 synchronized (mStats) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700375 mStats.noteStartSensorLocked(uid, sensor);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800376 }
377 }
378
379 public void noteStopSensor(int uid, int sensor) {
380 enforceCallingPermission();
381 synchronized (mStats) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700382 mStats.noteStopSensorLocked(uid, sensor);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800383 }
384 }
385
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800386 public void noteVibratorOn(int uid, long durationMillis) {
387 enforceCallingPermission();
388 synchronized (mStats) {
389 mStats.noteVibratorOnLocked(uid, durationMillis);
390 }
391 }
392
393 public void noteVibratorOff(int uid) {
394 enforceCallingPermission();
395 synchronized (mStats) {
396 mStats.noteVibratorOffLocked(uid);
397 }
398 }
399
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800400 public void noteStartGps(int uid) {
401 enforceCallingPermission();
402 synchronized (mStats) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700403 mStats.noteStartGpsLocked(uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800404 }
405 }
406
407 public void noteStopGps(int uid) {
408 enforceCallingPermission();
409 synchronized (mStats) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700410 mStats.noteStopGpsLocked(uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800411 }
412 }
413
Jeff Browne95c3cd2014-05-02 16:59:26 -0700414 public void noteScreenState(int state) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800415 enforceCallingPermission();
416 synchronized (mStats) {
Jeff Browne95c3cd2014-05-02 16:59:26 -0700417 mStats.noteScreenStateLocked(state);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800418 }
419 }
420
Dianne Hackborn617f8772009-03-31 15:04:46 -0700421 public void noteScreenBrightness(int brightness) {
422 enforceCallingPermission();
423 synchronized (mStats) {
424 mStats.noteScreenBrightnessLocked(brightness);
425 }
426 }
427
Dianne Hackborn617f8772009-03-31 15:04:46 -0700428 public void noteUserActivity(int uid, int event) {
429 enforceCallingPermission();
430 synchronized (mStats) {
431 mStats.noteUserActivityLocked(uid, event);
432 }
433 }
Jeff Browne95c3cd2014-05-02 16:59:26 -0700434
435 public void noteInteractive(boolean interactive) {
436 enforceCallingPermission();
437 synchronized (mStats) {
438 mStats.noteInteractiveLocked(interactive);
439 }
440 }
Dianne Hackborne13c4c02014-02-11 17:18:35 -0800441
Dianne Hackborn1e01d162014-12-04 17:46:42 -0800442 public void noteConnectivityChanged(int type, String extra) {
443 enforceCallingPermission();
444 synchronized (mStats) {
445 mStats.noteConnectivityChangedLocked(type, extra);
446 }
447 }
448
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -0700449 public void noteMobileRadioPowerState(int powerState, long timestampNs) {
Dianne Hackborne13c4c02014-02-11 17:18:35 -0800450 enforceCallingPermission();
451 synchronized (mStats) {
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -0700452 mStats.noteMobileRadioPowerState(powerState, timestampNs);
Dianne Hackborne13c4c02014-02-11 17:18:35 -0800453 }
454 }
455
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800456 public void notePhoneOn() {
457 enforceCallingPermission();
458 synchronized (mStats) {
459 mStats.notePhoneOnLocked();
460 }
461 }
462
463 public void notePhoneOff() {
464 enforceCallingPermission();
465 synchronized (mStats) {
466 mStats.notePhoneOffLocked();
467 }
468 }
The Android Open Source Project10592532009-03-18 17:39:46 -0700469
Wink Savillee9b06d72009-05-18 21:47:50 -0700470 public void notePhoneSignalStrength(SignalStrength signalStrength) {
Dianne Hackborn627bba72009-03-24 22:32:56 -0700471 enforceCallingPermission();
472 synchronized (mStats) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700473 mStats.notePhoneSignalStrengthLocked(signalStrength);
Dianne Hackborn627bba72009-03-24 22:32:56 -0700474 }
475 }
476
477 public void notePhoneDataConnectionState(int dataType, boolean hasData) {
478 enforceCallingPermission();
479 synchronized (mStats) {
480 mStats.notePhoneDataConnectionStateLocked(dataType, hasData);
481 }
482 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -0700483
Amith Yamasanif37447b2009-10-08 18:28:01 -0700484 public void notePhoneState(int state) {
Amith Yamasani32dbefd2009-06-19 09:21:17 -0700485 enforceCallingPermission();
Dianne Hackborne4a59512010-12-07 11:08:07 -0800486 int simState = TelephonyManager.getDefault().getSimState();
Amith Yamasani32dbefd2009-06-19 09:21:17 -0700487 synchronized (mStats) {
Dianne Hackborne4a59512010-12-07 11:08:07 -0800488 mStats.notePhoneStateLocked(state, simState);
Amith Yamasani32dbefd2009-06-19 09:21:17 -0700489 }
490 }
491
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700492 public void noteWifiOn() {
The Android Open Source Project10592532009-03-18 17:39:46 -0700493 enforceCallingPermission();
494 synchronized (mStats) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700495 mStats.noteWifiOnLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -0700496 }
497 }
498
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700499 public void noteWifiOff() {
The Android Open Source Project10592532009-03-18 17:39:46 -0700500 enforceCallingPermission();
501 synchronized (mStats) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700502 mStats.noteWifiOffLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -0700503 }
504 }
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700505
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700506 public void noteStartAudio(int uid) {
507 enforceCallingPermission();
508 synchronized (mStats) {
509 mStats.noteAudioOnLocked(uid);
510 }
511 }
512
513 public void noteStopAudio(int uid) {
514 enforceCallingPermission();
515 synchronized (mStats) {
516 mStats.noteAudioOffLocked(uid);
517 }
518 }
519
520 public void noteStartVideo(int uid) {
521 enforceCallingPermission();
522 synchronized (mStats) {
523 mStats.noteVideoOnLocked(uid);
524 }
525 }
526
527 public void noteStopVideo(int uid) {
528 enforceCallingPermission();
529 synchronized (mStats) {
530 mStats.noteVideoOffLocked(uid);
531 }
532 }
533
Dianne Hackborn10eaa852014-07-22 22:54:55 -0700534 public void noteResetAudio() {
535 enforceCallingPermission();
536 synchronized (mStats) {
537 mStats.noteResetAudioLocked();
538 }
539 }
540
541 public void noteResetVideo() {
542 enforceCallingPermission();
543 synchronized (mStats) {
544 mStats.noteResetVideoLocked();
545 }
546 }
547
Dianne Hackbornabc7c492014-06-30 16:57:46 -0700548 public void noteFlashlightOn() {
549 enforceCallingPermission();
550 synchronized (mStats) {
551 mStats.noteFlashlightOnLocked();
552 }
553 }
554
555 public void noteFlashlightOff() {
556 enforceCallingPermission();
557 synchronized (mStats) {
558 mStats.noteFlashlightOffLocked();
559 }
560 }
561
Adam Lesinskie08af192015-03-25 16:42:59 -0700562 @Override
563 public void noteWifiRadioPowerState(int powerState, long tsNanos) {
564 enforceCallingPermission();
565
566 // There was a change in WiFi power state.
567 // Collect data now for the past activity.
Dianne Hackborn0c820db2015-04-14 17:47:34 -0700568 mHandler.scheduleSync("wifi-data");
569 synchronized (mStats) {
570 mStats.noteWifiRadioPowerState(powerState, tsNanos);
571 }
Adam Lesinskie08af192015-03-25 16:42:59 -0700572 }
573
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700574 public void noteWifiRunning(WorkSource ws) {
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700575 enforceCallingPermission();
576 synchronized (mStats) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700577 mStats.noteWifiRunningLocked(ws);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700578 }
579 }
580
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700581 public void noteWifiRunningChanged(WorkSource oldWs, WorkSource newWs) {
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700582 enforceCallingPermission();
583 synchronized (mStats) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700584 mStats.noteWifiRunningChangedLocked(oldWs, newWs);
585 }
586 }
587
588 public void noteWifiStopped(WorkSource ws) {
589 enforceCallingPermission();
590 synchronized (mStats) {
591 mStats.noteWifiStoppedLocked(ws);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700592 }
593 }
594
Dianne Hackbornca1bf212014-02-14 14:18:36 -0800595 public void noteWifiState(int wifiState, String accessPoint) {
596 enforceCallingPermission();
597 synchronized (mStats) {
598 mStats.noteWifiStateLocked(wifiState, accessPoint);
599 }
600 }
601
Dianne Hackborn3251b902014-06-20 14:40:53 -0700602 public void noteWifiSupplicantStateChanged(int supplState, boolean failedAuth) {
603 enforceCallingPermission();
604 synchronized (mStats) {
605 mStats.noteWifiSupplicantStateChangedLocked(supplState, failedAuth);
606 }
607 }
608
609 public void noteWifiRssiChanged(int newRssi) {
610 enforceCallingPermission();
611 synchronized (mStats) {
612 mStats.noteWifiRssiChangedLocked(newRssi);
613 }
614 }
615
The Android Open Source Project10592532009-03-18 17:39:46 -0700616 public void noteFullWifiLockAcquired(int uid) {
617 enforceCallingPermission();
618 synchronized (mStats) {
619 mStats.noteFullWifiLockAcquiredLocked(uid);
620 }
621 }
622
623 public void noteFullWifiLockReleased(int uid) {
624 enforceCallingPermission();
625 synchronized (mStats) {
626 mStats.noteFullWifiLockReleasedLocked(uid);
627 }
628 }
Nick Pelly6ccaa542012-06-15 15:22:47 -0700629
630 public void noteWifiScanStarted(int uid) {
The Android Open Source Project10592532009-03-18 17:39:46 -0700631 enforceCallingPermission();
632 synchronized (mStats) {
Nick Pelly6ccaa542012-06-15 15:22:47 -0700633 mStats.noteWifiScanStartedLocked(uid);
The Android Open Source Project10592532009-03-18 17:39:46 -0700634 }
635 }
Nick Pelly6ccaa542012-06-15 15:22:47 -0700636
637 public void noteWifiScanStopped(int uid) {
The Android Open Source Project10592532009-03-18 17:39:46 -0700638 enforceCallingPermission();
639 synchronized (mStats) {
Nick Pelly6ccaa542012-06-15 15:22:47 -0700640 mStats.noteWifiScanStoppedLocked(uid);
The Android Open Source Project10592532009-03-18 17:39:46 -0700641 }
642 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800643
Robert Greenwalt5347bd42009-05-13 15:10:16 -0700644 public void noteWifiMulticastEnabled(int uid) {
645 enforceCallingPermission();
646 synchronized (mStats) {
647 mStats.noteWifiMulticastEnabledLocked(uid);
648 }
649 }
650
651 public void noteWifiMulticastDisabled(int uid) {
652 enforceCallingPermission();
653 synchronized (mStats) {
654 mStats.noteWifiMulticastDisabledLocked(uid);
655 }
656 }
657
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700658 public void noteFullWifiLockAcquiredFromSource(WorkSource ws) {
659 enforceCallingPermission();
660 synchronized (mStats) {
661 mStats.noteFullWifiLockAcquiredFromSourceLocked(ws);
662 }
663 }
664
665 public void noteFullWifiLockReleasedFromSource(WorkSource ws) {
666 enforceCallingPermission();
667 synchronized (mStats) {
668 mStats.noteFullWifiLockReleasedFromSourceLocked(ws);
669 }
670 }
671
Nick Pelly6ccaa542012-06-15 15:22:47 -0700672 public void noteWifiScanStartedFromSource(WorkSource ws) {
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700673 enforceCallingPermission();
674 synchronized (mStats) {
Nick Pelly6ccaa542012-06-15 15:22:47 -0700675 mStats.noteWifiScanStartedFromSourceLocked(ws);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700676 }
677 }
678
Nick Pelly6ccaa542012-06-15 15:22:47 -0700679 public void noteWifiScanStoppedFromSource(WorkSource ws) {
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700680 enforceCallingPermission();
681 synchronized (mStats) {
Nick Pelly6ccaa542012-06-15 15:22:47 -0700682 mStats.noteWifiScanStoppedFromSourceLocked(ws);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700683 }
684 }
685
Robert Greenwalta029ea12013-09-25 16:38:12 -0700686 public void noteWifiBatchedScanStartedFromSource(WorkSource ws, int csph) {
687 enforceCallingPermission();
688 synchronized (mStats) {
689 mStats.noteWifiBatchedScanStartedFromSourceLocked(ws, csph);
690 }
691 }
692
693 public void noteWifiBatchedScanStoppedFromSource(WorkSource ws) {
694 enforceCallingPermission();
695 synchronized (mStats) {
696 mStats.noteWifiBatchedScanStoppedFromSourceLocked(ws);
697 }
698 }
699
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700700 public void noteWifiMulticastEnabledFromSource(WorkSource ws) {
701 enforceCallingPermission();
702 synchronized (mStats) {
703 mStats.noteWifiMulticastEnabledFromSourceLocked(ws);
704 }
705 }
706
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700707 @Override
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700708 public void noteWifiMulticastDisabledFromSource(WorkSource ws) {
709 enforceCallingPermission();
710 synchronized (mStats) {
711 mStats.noteWifiMulticastDisabledFromSourceLocked(ws);
712 }
713 }
714
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700715 @Override
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700716 public void noteNetworkInterfaceType(String iface, int networkType) {
Jeff Sharkey1059c3c2011-10-04 16:54:49 -0700717 enforceCallingPermission();
718 synchronized (mStats) {
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700719 mStats.noteNetworkInterfaceTypeLocked(iface, networkType);
Jeff Sharkey1059c3c2011-10-04 16:54:49 -0700720 }
721 }
722
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700723 @Override
724 public void noteNetworkStatsEnabled() {
725 enforceCallingPermission();
726 synchronized (mStats) {
727 mStats.noteNetworkStatsEnabledLocked();
728 }
729 }
730
Dianne Hackborn8ad2af72015-03-17 17:00:24 -0700731 @Override
732 public void noteDeviceIdleMode(boolean enabled, boolean fromActive, boolean fromMotion) {
733 enforceCallingPermission();
734 synchronized (mStats) {
735 mStats.noteDeviceIdleModeLocked(enabled, fromActive, fromMotion);
736 }
737 }
738
739 public void notePackageInstalled(String pkgName, int versionCode) {
740 enforceCallingPermission();
741 synchronized (mStats) {
742 mStats.notePackageInstalledLocked(pkgName, versionCode);
743 }
744 }
745
746 public void notePackageUninstalled(String pkgName) {
747 enforceCallingPermission();
748 synchronized (mStats) {
749 mStats.notePackageUninstalledLocked(pkgName);
750 }
751 }
752
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800753 public boolean isOnBattery() {
754 return mStats.isOnBattery();
755 }
756
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700757 public void setBatteryState(int status, int health, int plugType, int level,
758 int temp, int volt) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800759 enforceCallingPermission();
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700760 synchronized (mStats) {
761 final boolean onBattery = plugType == BatteryStatsImpl.BATTERY_PLUGGED_NONE;
762 if (mStats.isOnBattery() == onBattery) {
763 // The battery state has not changed, so we don't need to sync external
764 // stats immediately.
765 mStats.setBatteryStateLocked(status, health, plugType, level, temp, volt);
766 return;
767 }
768 }
769
770 // Sync external stats first as the battery has changed states. If we don't sync
771 // immediately here, we may not collect the relevant data later.
Dianne Hackborn0c820db2015-04-14 17:47:34 -0700772 updateExternalStats("battery-state");
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700773 synchronized (mStats) {
774 mStats.setBatteryStateLocked(status, health, plugType, level, temp, volt);
775 }
Evan Millar633a1742009-04-02 16:36:33 -0700776 }
777
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800778 public long getAwakeTimeBattery() {
779 mContext.enforceCallingOrSelfPermission(
780 android.Manifest.permission.BATTERY_STATS, null);
781 return mStats.getAwakeTimeBattery();
782 }
783
784 public long getAwakeTimePlugged() {
785 mContext.enforceCallingOrSelfPermission(
786 android.Manifest.permission.BATTERY_STATS, null);
787 return mStats.getAwakeTimePlugged();
788 }
789
790 public void enforceCallingPermission() {
791 if (Binder.getCallingPid() == Process.myPid()) {
792 return;
793 }
794 mContext.enforcePermission(android.Manifest.permission.UPDATE_DEVICE_STATS,
795 Binder.getCallingPid(), Binder.getCallingUid(), null);
796 }
Dianne Hackbornc51cf032014-03-02 19:08:15 -0800797
798 final class WakeupReasonThread extends Thread {
799 final int[] mIrqs = new int[32];
800 final String[] mReasons = new String[32];
801
802 WakeupReasonThread() {
803 super("BatteryStats_wakeupReason");
804 }
805
806 public void run() {
807 Process.setThreadPriority(Process.THREAD_PRIORITY_FOREGROUND);
808
809 try {
810 int num;
811 while ((num=nativeWaitWakeup(mIrqs, mReasons)) >= 0) {
812 synchronized (mStats) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700813 if (num > 0) {
814 for (int i=0; i<num; i++) {
815 mStats.noteWakeupReasonLocked(mReasons[i]);
816 }
817 } else {
818 mStats.noteWakeupReasonLocked("unknown");
Dianne Hackbornc51cf032014-03-02 19:08:15 -0800819 }
820 }
821 }
822 } catch (RuntimeException e) {
823 Slog.e(TAG, "Failure reading wakeup reasons", e);
824 }
825 }
826 }
827
828 private static native int nativeWaitWakeup(int[] outIrqs, String[] outReasons);
829
Dianne Hackbornae384452011-06-28 12:33:48 -0700830 private void dumpHelp(PrintWriter pw) {
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700831 pw.println("Battery stats (batterystats) dump options:");
Dianne Hackborn1e725a72015-03-24 18:23:19 -0700832 pw.println(" [--checkin] [--history] [--history-start] [--charged] [-c]");
Dianne Hackbornd4a8af72015-03-03 10:06:15 -0800833 pw.println(" [--daily] [--reset] [--write] [--new-daily] [--read-daily] [-h] [<package.name>]");
Dianne Hackbornae384452011-06-28 12:33:48 -0700834 pw.println(" --checkin: format output for a checkin report.");
Dianne Hackborn099bc622014-01-22 13:39:16 -0800835 pw.println(" --history: show only history data.");
Dianne Hackbornc51cf032014-03-02 19:08:15 -0800836 pw.println(" --history-start <num>: show only history data starting at given time offset.");
Dianne Hackbornc51cf032014-03-02 19:08:15 -0800837 pw.println(" --charged: only output data since last charged.");
Dianne Hackbornd4a8af72015-03-03 10:06:15 -0800838 pw.println(" --daily: only output full daily data.");
Dianne Hackbornae384452011-06-28 12:33:48 -0700839 pw.println(" --reset: reset the stats, clearing all current data.");
840 pw.println(" --write: force write current collected stats to disk.");
Dianne Hackbornd4a8af72015-03-03 10:06:15 -0800841 pw.println(" --new-daily: immediately create and write new daily stats record.");
842 pw.println(" --read-daily: read-load last written daily stats.");
Dianne Hackborncbfd23e2013-06-11 14:26:53 -0700843 pw.println(" <package.name>: optional name of package to filter output by.");
Dianne Hackbornfc064132014-06-02 12:42:12 -0700844 pw.println(" -h: print this help text.");
845 pw.println("Battery stats (batterystats) commands:");
846 pw.println(" enable|disable <option>");
847 pw.println(" Enable or disable a running option. Option state is not saved across boots.");
848 pw.println(" Options are:");
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700849 pw.println(" full-history: include additional detailed events in battery history:");
Dianne Hackborn1e383822015-04-10 14:02:33 -0700850 pw.println(" wake_lock_in, alarms and proc events");
Dianne Hackbornfc064132014-06-02 12:42:12 -0700851 pw.println(" no-auto-reset: don't automatically reset stats when unplugged");
Dianne Hackbornae384452011-06-28 12:33:48 -0700852 }
853
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700854 private int doEnableOrDisable(PrintWriter pw, int i, String[] args, boolean enable) {
855 i++;
856 if (i >= args.length) {
857 pw.println("Missing option argument for " + (enable ? "--enable" : "--disable"));
858 dumpHelp(pw);
859 return -1;
860 }
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700861 if ("full-wake-history".equals(args[i]) || "full-history".equals(args[i])) {
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700862 synchronized (mStats) {
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700863 mStats.setRecordAllHistoryLocked(enable);
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700864 }
Dianne Hackborn9a755432014-05-15 17:05:22 -0700865 } else if ("no-auto-reset".equals(args[i])) {
866 synchronized (mStats) {
867 mStats.setNoAutoReset(enable);
868 }
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700869 } else {
870 pw.println("Unknown enable/disable option: " + args[i]);
871 dumpHelp(pw);
872 return -1;
873 }
874 return i;
875 }
876
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700877
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800878 @Override
879 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Kenny Root3abd75b2011-09-29 11:00:41 -0700880 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
881 != PackageManager.PERMISSION_GRANTED) {
882 pw.println("Permission Denial: can't dump BatteryStats from from pid="
883 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
884 + " without permission " + android.Manifest.permission.DUMP);
885 return;
886 }
887
Dianne Hackbornc51cf032014-03-02 19:08:15 -0800888 int flags = 0;
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700889 boolean useCheckinFormat = false;
890 boolean isRealCheckin = false;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700891 boolean noOutput = false;
Dianne Hackborn16b0b562014-06-03 17:24:42 -0700892 boolean writeData = false;
Dianne Hackbornc51cf032014-03-02 19:08:15 -0800893 long historyStart = -1;
Dianne Hackborncbfd23e2013-06-11 14:26:53 -0700894 int reqUid = -1;
Dianne Hackborne4a59512010-12-07 11:08:07 -0800895 if (args != null) {
Dianne Hackbornc51cf032014-03-02 19:08:15 -0800896 for (int i=0; i<args.length; i++) {
897 String arg = args[i];
Dianne Hackborne4a59512010-12-07 11:08:07 -0800898 if ("--checkin".equals(arg)) {
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700899 useCheckinFormat = true;
900 isRealCheckin = true;
Dianne Hackborn099bc622014-01-22 13:39:16 -0800901 } else if ("--history".equals(arg)) {
Dianne Hackbornc51cf032014-03-02 19:08:15 -0800902 flags |= BatteryStats.DUMP_HISTORY_ONLY;
903 } else if ("--history-start".equals(arg)) {
904 flags |= BatteryStats.DUMP_HISTORY_ONLY;
905 i++;
906 if (i >= args.length) {
907 pw.println("Missing time argument for --history-since");
908 dumpHelp(pw);
909 return;
910 }
911 historyStart = Long.parseLong(args[i]);
Dianne Hackborn16b0b562014-06-03 17:24:42 -0700912 writeData = true;
Dianne Hackborn49021f52013-09-04 18:03:40 -0700913 } else if ("-c".equals(arg)) {
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700914 useCheckinFormat = true;
Dianne Hackbornc51cf032014-03-02 19:08:15 -0800915 flags |= BatteryStats.DUMP_INCLUDE_HISTORY;
Dianne Hackbornc51cf032014-03-02 19:08:15 -0800916 } else if ("--charged".equals(arg)) {
917 flags |= BatteryStats.DUMP_CHARGED_ONLY;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -0800918 } else if ("--daily".equals(arg)) {
919 flags |= BatteryStats.DUMP_DAILY_ONLY;
Dianne Hackborne4a59512010-12-07 11:08:07 -0800920 } else if ("--reset".equals(arg)) {
921 synchronized (mStats) {
Dianne Hackborn3d658bf2014-02-05 13:38:56 -0800922 mStats.resetAllStatsCmdLocked();
Dianne Hackborne4a59512010-12-07 11:08:07 -0800923 pw.println("Battery stats reset.");
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700924 noOutput = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800925 }
Dianne Hackborn0c820db2015-04-14 17:47:34 -0700926 updateExternalStats("dump");
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700927 } else if ("--write".equals(arg)) {
Dianne Hackborn0c820db2015-04-14 17:47:34 -0700928 updateExternalStats("dump");
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700929 synchronized (mStats) {
930 mStats.writeSyncLocked();
931 pw.println("Battery stats written.");
932 noOutput = true;
933 }
Dianne Hackbornd4a8af72015-03-03 10:06:15 -0800934 } else if ("--new-daily".equals(arg)) {
935 synchronized (mStats) {
936 mStats.recordDailyStatsLocked();
937 pw.println("New daily stats written.");
938 noOutput = true;
939 }
940 } else if ("--read-daily".equals(arg)) {
941 synchronized (mStats) {
942 mStats.readDailyStatsLocked();
943 pw.println("Last daily stats read.");
944 noOutput = true;
945 }
Dianne Hackbornfc064132014-06-02 12:42:12 -0700946 } else if ("--enable".equals(arg) || "enable".equals(arg)) {
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700947 i = doEnableOrDisable(pw, i, args, true);
948 if (i < 0) {
949 return;
950 }
951 pw.println("Enabled: " + args[i]);
952 return;
Dianne Hackbornfc064132014-06-02 12:42:12 -0700953 } else if ("--disable".equals(arg) || "disable".equals(arg)) {
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700954 i = doEnableOrDisable(pw, i, args, false);
955 if (i < 0) {
956 return;
957 }
958 pw.println("Disabled: " + args[i]);
959 return;
Dianne Hackbornae384452011-06-28 12:33:48 -0700960 } else if ("-h".equals(arg)) {
961 dumpHelp(pw);
962 return;
Mike Lockwoode8174042011-08-16 12:53:43 -0700963 } else if ("-a".equals(arg)) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700964 flags |= BatteryStats.DUMP_VERBOSE;
Dianne Hackborncbfd23e2013-06-11 14:26:53 -0700965 } else if (arg.length() > 0 && arg.charAt(0) == '-'){
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700966 pw.println("Unknown option: " + arg);
Dianne Hackbornae384452011-06-28 12:33:48 -0700967 dumpHelp(pw);
Dianne Hackborncbfd23e2013-06-11 14:26:53 -0700968 return;
969 } else {
970 // Not an option, last argument must be a package name.
971 try {
972 reqUid = mContext.getPackageManager().getPackageUid(arg,
973 UserHandle.getCallingUserId());
974 } catch (PackageManager.NameNotFoundException e) {
975 pw.println("Unknown package: " + arg);
976 dumpHelp(pw);
977 return;
978 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800979 }
980 }
Dianne Hackborne4a59512010-12-07 11:08:07 -0800981 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700982 if (noOutput) {
983 return;
984 }
Dianne Hackbornd953c532014-08-16 18:17:38 -0700985 if (BatteryStatsHelper.checkWifiOnly(mContext)) {
986 flags |= BatteryStats.DUMP_DEVICE_WIFI_ONLY;
987 }
Dianne Hackbornab4a81b2014-10-09 17:59:38 -0700988 if (reqUid >= 0) {
989 // By default, if the caller is only interested in a specific package, then
990 // we only dump the aggregated data since charged.
Dianne Hackborn1e725a72015-03-24 18:23:19 -0700991 if ((flags&(BatteryStats.DUMP_HISTORY_ONLY|BatteryStats.DUMP_CHARGED_ONLY)) == 0) {
Dianne Hackbornab4a81b2014-10-09 17:59:38 -0700992 flags |= BatteryStats.DUMP_CHARGED_ONLY;
993 // Also if they are doing -c, we don't want history.
994 flags &= ~BatteryStats.DUMP_INCLUDE_HISTORY;
995 }
996 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700997
998 // Fetch data from external sources and update the BatteryStatsImpl object with them.
Dianne Hackborn0c820db2015-04-14 17:47:34 -0700999 updateExternalStats("dump");
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07001000
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07001001 if (useCheckinFormat) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08001002 List<ApplicationInfo> apps = mContext.getPackageManager().getInstalledApplications(0);
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07001003 if (isRealCheckin) {
1004 // For a real checkin, first we want to prefer to use the last complete checkin
1005 // file if there is one.
1006 synchronized (mStats.mCheckinFile) {
1007 if (mStats.mCheckinFile.exists()) {
1008 try {
1009 byte[] raw = mStats.mCheckinFile.readFully();
1010 if (raw != null) {
1011 Parcel in = Parcel.obtain();
1012 in.unmarshall(raw, 0, raw.length);
1013 in.setDataPosition(0);
1014 BatteryStatsImpl checkinStats = new BatteryStatsImpl(
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07001015 null, mStats.mHandler, null);
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07001016 checkinStats.readSummaryFromParcel(in);
1017 in.recycle();
1018 checkinStats.dumpCheckinLocked(mContext, pw, apps, flags,
1019 historyStart);
1020 mStats.mCheckinFile.delete();
1021 return;
1022 }
1023 } catch (IOException e) {
1024 Slog.w(TAG, "Failure reading checkin file "
1025 + mStats.mCheckinFile.getBaseFile(), e);
1026 }
1027 }
1028 }
1029 }
Dianne Hackborne4a59512010-12-07 11:08:07 -08001030 synchronized (mStats) {
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001031 mStats.dumpCheckinLocked(mContext, pw, apps, flags, historyStart);
Dianne Hackborn16b0b562014-06-03 17:24:42 -07001032 if (writeData) {
1033 mStats.writeAsyncLocked();
1034 }
Dianne Hackborne4a59512010-12-07 11:08:07 -08001035 }
1036 } else {
1037 synchronized (mStats) {
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001038 mStats.dumpLocked(mContext, pw, flags, reqUid, historyStart);
Dianne Hackborn16b0b562014-06-03 17:24:42 -07001039 if (writeData) {
1040 mStats.writeAsyncLocked();
1041 }
Dianne Hackborne4a59512010-12-07 11:08:07 -08001042 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001043 }
1044 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07001045
1046 // Objects for extracting data from external sources.
1047 private final Object mExternalStatsLock = new Object();
1048
1049 @GuardedBy("mExternalStatsLock")
1050 private IWifiManager mWifiManager;
1051
1052 // WiFi keeps an accumulated total of stats, unlike Bluetooth.
1053 // Keep the last WiFi stats so we can compute a delta.
1054 @GuardedBy("mExternalStatsLock")
1055 private WifiActivityEnergyInfo mLastInfo = new WifiActivityEnergyInfo(0, 0, 0, 0, 0, 0);
1056
1057 @GuardedBy("mExternalStatsLock")
1058 private WifiActivityEnergyInfo pullWifiEnergyInfoLocked() {
1059 if (mWifiManager == null) {
1060 mWifiManager = IWifiManager.Stub.asInterface(
1061 ServiceManager.getService(Context.WIFI_SERVICE));
1062 if (mWifiManager == null) {
1063 return null;
1064 }
1065 }
1066
1067 try {
1068 // We read the data even if we are not on battery. This is so that we keep the
1069 // correct delta from when we should start reading (aka when we are on battery).
1070 WifiActivityEnergyInfo info = mWifiManager.reportActivityInfo();
1071 if (info != null && info.isValid()) {
1072 // We will modify the last info object to be the delta, and store the new
1073 // WifiActivityEnergyInfo object as our last one.
1074 final WifiActivityEnergyInfo result = mLastInfo;
1075 result.mTimestamp = info.getTimeStamp();
1076 result.mStackState = info.getStackState();
1077 result.mControllerTxTimeMs =
Adam Lesinskie08af192015-03-25 16:42:59 -07001078 info.mControllerTxTimeMs - mLastInfo.mControllerTxTimeMs;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07001079 result.mControllerRxTimeMs =
Adam Lesinskie08af192015-03-25 16:42:59 -07001080 info.mControllerRxTimeMs - mLastInfo.mControllerRxTimeMs;
Bart Searse9b9b732015-04-07 06:14:04 +00001081 result.mControllerEnergyUsed =
Adam Lesinskie08af192015-03-25 16:42:59 -07001082 info.mControllerEnergyUsed - mLastInfo.mControllerEnergyUsed;
1083
1084 // WiFi calculates the idle time as a difference from the on time and the various
1085 // Rx + Tx times. There seems to be some missing time there because this sometimes
1086 // becomes negative. Just cap it at 0 and move on.
1087 result.mControllerIdleTimeMs =
1088 Math.max(0, info.mControllerIdleTimeMs - mLastInfo.mControllerIdleTimeMs);
1089
1090 if (result.mControllerTxTimeMs < 0 ||
1091 result.mControllerRxTimeMs < 0) {
1092 // The stats were reset by the WiFi system (which is why our delta is negative).
1093 // Returns the unaltered stats.
1094 result.mControllerEnergyUsed = info.mControllerEnergyUsed;
1095 result.mControllerRxTimeMs = info.mControllerRxTimeMs;
1096 result.mControllerTxTimeMs = info.mControllerTxTimeMs;
1097 result.mControllerIdleTimeMs = info.mControllerIdleTimeMs;
1098
1099 Slog.v(TAG, "WiFi energy data was reset, new WiFi energy data is " + result);
1100 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07001101 mLastInfo = info;
1102 return result;
1103 }
1104 } catch (RemoteException e) {
1105 // Nothing to report, WiFi is dead.
1106 }
1107 return null;
1108 }
1109
1110 @GuardedBy("mExternalStatsLock")
1111 private BluetoothActivityEnergyInfo pullBluetoothEnergyInfoLocked() {
1112 BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
1113 if (adapter != null) {
1114 BluetoothActivityEnergyInfo info = adapter.getControllerActivityEnergyInfo(
1115 BluetoothAdapter.ACTIVITY_ENERGY_INFO_REFRESHED);
1116 if (info != null && info.isValid()) {
1117 return info;
1118 }
1119 }
1120 return null;
1121 }
1122
1123 /**
1124 * Fetches data from external sources (WiFi controller, bluetooth chipset) and updates
1125 * batterystats with that information.
1126 *
1127 * We first grab a lock specific to this method, then once all the data has been collected,
1128 * we grab the mStats lock and update the data.
1129 */
Dianne Hackborn0c820db2015-04-14 17:47:34 -07001130 void updateExternalStats(String reason) {
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07001131 synchronized (mExternalStatsLock) {
Adam Lesinskie08af192015-03-25 16:42:59 -07001132 if (mContext == null) {
1133 // We haven't started yet (which means the BatteryStatsImpl object has
1134 // no power profile. Don't consume data we can't compute yet.
1135 return;
1136 }
1137
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07001138 final WifiActivityEnergyInfo wifiEnergyInfo = pullWifiEnergyInfoLocked();
1139 final BluetoothActivityEnergyInfo bluetoothEnergyInfo = pullBluetoothEnergyInfoLocked();
1140 synchronized (mStats) {
Dianne Hackborn0c820db2015-04-14 17:47:34 -07001141 if (mStats.mRecordAllHistory) {
1142 final long elapsedRealtime = SystemClock.elapsedRealtime();
1143 final long uptime = SystemClock.uptimeMillis();
1144 mStats.addHistoryEventLocked(elapsedRealtime, uptime,
1145 BatteryStats.HistoryItem.EVENT_COLLECT_EXTERNAL_STATS, reason, 0);
1146 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07001147 mStats.updateKernelWakelocksLocked();
1148 mStats.updateMobileRadioStateLocked(SystemClock.elapsedRealtime());
1149 mStats.updateWifiStateLocked(wifiEnergyInfo);
1150 mStats.updateBluetoothStateLocked(bluetoothEnergyInfo);
1151 }
1152 }
1153 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001154}