blob: 79b141345f93f0acde791cde1228d83fd45022e1 [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 Lesinski010bf372016-04-11 12:18:18 -070019import android.annotation.Nullable;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070020import android.bluetooth.BluetoothActivityEnergyInfo;
Jaikumar Ganesh3f034962010-09-27 17:02:23 -070021import android.bluetooth.BluetoothAdapter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080022import android.content.Context;
Dianne Hackborne4a59512010-12-07 11:08:07 -080023import android.content.pm.ApplicationInfo;
Kenny Root3abd75b2011-09-29 11:00:41 -070024import android.content.pm.PackageManager;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070025import android.net.wifi.IWifiManager;
26import android.net.wifi.WifiActivityEnergyInfo;
Dianne Hackborn91268cf2013-06-13 19:06:50 -070027import android.os.BatteryStats;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080028import android.os.Binder;
Jeff Brown6f357d32014-01-15 20:40:55 -080029import android.os.Handler;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080030import android.os.IBinder;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070031import android.os.Looper;
32import android.os.Message;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080033import android.os.Parcel;
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -070034import android.os.ParcelFileDescriptor;
Adam Lesinski9ae9cba2015-07-08 17:09:34 -070035import android.os.ParcelFormatException;
Adam Lesinski010bf372016-04-11 12:18:18 -070036import android.os.Parcelable;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -070037import android.os.PowerManagerInternal;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080038import android.os.Process;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070039import android.os.RemoteException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080040import android.os.ServiceManager;
Adam Lesinski010bf372016-04-11 12:18:18 -070041import android.os.SynchronousResultReceiver;
Dianne Hackborne5167ca2014-03-08 14:39:10 -080042import android.os.SystemClock;
Dianne Hackborncbfd23e2013-06-11 14:26:53 -070043import android.os.UserHandle;
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -070044import android.os.WorkSource;
Joe Onorato713fec82016-03-04 10:34:02 -080045import android.os.health.HealthStatsParceler;
46import android.os.health.HealthStatsWriter;
47import android.os.health.UidHealthStats;
Adam Lesinski06f46cb2015-06-23 13:42:53 -070048import android.telephony.DataConnectionRealTimeInfo;
Adam Lesinski21f76aa2016-01-25 12:27:06 -080049import android.telephony.ModemActivityInfo;
Wink Savillee9b06d72009-05-18 21:47:50 -070050import android.telephony.SignalStrength;
Dianne Hackborne4a59512010-12-07 11:08:07 -080051import android.telephony.TelephonyManager;
Adam Lesinski61db88f2015-07-01 15:05:07 -070052import android.util.IntArray;
Joe Onorato8a9b2202010-02-26 18:56:32 -080053import android.util.Slog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080054
Adam Lesinskibd6704f2015-06-18 18:05:20 -070055import android.util.TimeUtils;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070056import com.android.internal.annotations.GuardedBy;
Amith Yamasani32dbefd2009-06-19 09:21:17 -070057import com.android.internal.app.IBatteryStats;
Dianne Hackbornd953c532014-08-16 18:17:38 -070058import com.android.internal.os.BatteryStatsHelper;
Amith Yamasani32dbefd2009-06-19 09:21:17 -070059import com.android.internal.os.BatteryStatsImpl;
Amith Yamasanie43530a2009-08-21 13:11:37 -070060import com.android.internal.os.PowerProfile;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -070061import com.android.server.LocalServices;
Adam Lesinski20b84df2016-04-19 17:33:33 -070062import com.android.server.ServiceThread;
Amith Yamasani32dbefd2009-06-19 09:21:17 -070063
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -070064import java.io.File;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080065import java.io.FileDescriptor;
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -070066import java.io.IOException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080067import java.io.PrintWriter;
Adam Lesinski515702c2015-07-23 18:13:38 -070068import java.nio.ByteBuffer;
69import java.nio.CharBuffer;
70import java.nio.charset.CharsetDecoder;
71import java.nio.charset.CodingErrorAction;
72import java.nio.charset.StandardCharsets;
Joe Onorato713fec82016-03-04 10:34:02 -080073import java.util.Arrays;
Dianne Hackborne4a59512010-12-07 11:08:07 -080074import java.util.List;
Adam Lesinski010bf372016-04-11 12:18:18 -070075import java.util.concurrent.TimeoutException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080076
77/**
78 * All information we are collecting about things that can happen that impact
79 * battery life.
80 */
Dianne Hackborncbefd8d2014-05-14 11:42:00 -070081public final class BatteryStatsService extends IBatteryStats.Stub
Badhri Jagan Sridharan68cdf192016-04-03 21:57:15 -070082 implements PowerManagerInternal.LowPowerModeListener,
83 BatteryStatsImpl.PlatformIdleStateCallback {
Dianne Hackbornc51cf032014-03-02 19:08:15 -080084 static final String TAG = "BatteryStatsService";
85
Adam Lesinski010bf372016-04-11 12:18:18 -070086 /**
87 * How long to wait on an individual subsystem to return its stats.
88 */
89 private static final long EXTERNAL_STATS_SYNC_TIMEOUT_MILLIS = 2000;
90
91 private static IBatteryStats sService;
92
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080093 final BatteryStatsImpl mStats;
Adam Lesinski010bf372016-04-11 12:18:18 -070094 private final BatteryStatsHandler mHandler;
95 private Context mContext;
96 private IWifiManager mWifiManager;
97 private TelephonyManager mTelephony;
98
99 // Lock acquired when extracting data from external sources.
100 private final Object mExternalStatsLock = new Object();
101
102 // WiFi keeps an accumulated total of stats, unlike Bluetooth.
103 // Keep the last WiFi stats so we can compute a delta.
104 @GuardedBy("mExternalStatsLock")
105 private WifiActivityEnergyInfo mLastInfo =
106 new WifiActivityEnergyInfo(0, 0, 0, new long[]{0}, 0, 0, 0);
Amith Yamasani3f7e35c2009-07-13 16:02:45 -0700107
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700108 class BatteryStatsHandler extends Handler implements BatteryStatsImpl.ExternalStatsSync {
109 public static final int MSG_SYNC_EXTERNAL_STATS = 1;
110 public static final int MSG_WRITE_TO_DISK = 2;
Adam Lesinski010bf372016-04-11 12:18:18 -0700111
Adam Lesinskia7c90c82015-06-18 14:52:24 -0700112 private int mUpdateFlags = 0;
Adam Lesinski61db88f2015-07-01 15:05:07 -0700113 private IntArray mUidsToRemove = new IntArray();
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700114
115 public BatteryStatsHandler(Looper looper) {
116 super(looper);
117 }
118
119 @Override
120 public void handleMessage(Message msg) {
121 switch (msg.what) {
122 case MSG_SYNC_EXTERNAL_STATS:
Adam Lesinskia7c90c82015-06-18 14:52:24 -0700123 final int updateFlags;
124 synchronized (this) {
125 removeMessages(MSG_SYNC_EXTERNAL_STATS);
126 updateFlags = mUpdateFlags;
127 mUpdateFlags = 0;
128 }
Adam Lesinski010bf372016-04-11 12:18:18 -0700129 updateExternalStatsSync((String)msg.obj, updateFlags);
Adam Lesinski56d82dd2015-07-14 16:27:40 -0700130
131 // other parts of the system could be calling into us
132 // from mStats in order to report of changes. We must grab the mStats
133 // lock before grabbing our own or we'll end up in a deadlock.
134 synchronized (mStats) {
135 synchronized (this) {
Adam Lesinski61db88f2015-07-01 15:05:07 -0700136 final int numUidsToRemove = mUidsToRemove.size();
137 for (int i = 0; i < numUidsToRemove; i++) {
138 mStats.removeIsolatedUidLocked(mUidsToRemove.get(i));
139 }
140 }
141 mUidsToRemove.clear();
142 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700143 break;
144
145 case MSG_WRITE_TO_DISK:
Adam Lesinski010bf372016-04-11 12:18:18 -0700146 updateExternalStatsSync("write", UPDATE_ALL);
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700147 synchronized (mStats) {
148 mStats.writeAsyncLocked();
149 }
150 break;
151 }
152 }
153
154 @Override
Adam Lesinski9f55cc72016-01-27 20:42:14 -0800155 public void scheduleSync(String reason, int updateFlags) {
Adam Lesinski61db88f2015-07-01 15:05:07 -0700156 synchronized (this) {
Adam Lesinski9f55cc72016-01-27 20:42:14 -0800157 scheduleSyncLocked(reason, updateFlags);
Adam Lesinski61db88f2015-07-01 15:05:07 -0700158 }
Adam Lesinskia7c90c82015-06-18 14:52:24 -0700159 }
160
Adam Lesinski61db88f2015-07-01 15:05:07 -0700161 @Override
162 public void scheduleCpuSyncDueToRemovedUid(int uid) {
Adam Lesinskia7c90c82015-06-18 14:52:24 -0700163 synchronized (this) {
Adam Lesinski61db88f2015-07-01 15:05:07 -0700164 scheduleSyncLocked("remove-uid", UPDATE_CPU);
165 mUidsToRemove.add(uid);
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700166 }
167 }
Adam Lesinski61db88f2015-07-01 15:05:07 -0700168
169 private void scheduleSyncLocked(String reason, int updateFlags) {
170 if (mUpdateFlags == 0) {
171 sendMessage(Message.obtain(this, MSG_SYNC_EXTERNAL_STATS, reason));
172 }
173 mUpdateFlags |= updateFlags;
174 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700175 }
176
Badhri Jagan Sridharan68cdf192016-04-03 21:57:15 -0700177 private native int getPlatformLowPowerStats(ByteBuffer outBuffer);
178 private CharsetDecoder mDecoderStat = StandardCharsets.UTF_8
179 .newDecoder()
180 .onMalformedInput(CodingErrorAction.REPLACE)
181 .onUnmappableCharacter(CodingErrorAction.REPLACE)
182 .replaceWith("?");
183 private ByteBuffer mUtf8BufferStat = ByteBuffer.allocateDirect(MAX_LOW_POWER_STATS_SIZE);
184 private CharBuffer mUtf16BufferStat = CharBuffer.allocate(MAX_LOW_POWER_STATS_SIZE);
185 private static final int MAX_LOW_POWER_STATS_SIZE = 512;
186
187 @Override
188 public String getPlatformLowPowerStats() {
189 mUtf8BufferStat.clear();
190 mUtf16BufferStat.clear();
191 mDecoderStat.reset();
192 int bytesWritten = getPlatformLowPowerStats(mUtf8BufferStat);
193 if (bytesWritten < 0) {
194 return null;
195 } else if (bytesWritten == 0) {
196 return "Empty";
197 }
198 mUtf8BufferStat.limit(bytesWritten);
199 mDecoderStat.decode(mUtf8BufferStat, mUtf16BufferStat, true);
200 mUtf16BufferStat.flip();
201 return mUtf16BufferStat.toString();
202 }
203
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700204 BatteryStatsService(File systemDir, Handler handler) {
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700205 // Our handler here will be accessing the disk, use a different thread than
206 // what the ActivityManagerService gave us (no I/O on that one!).
Adam Lesinski20b84df2016-04-19 17:33:33 -0700207 final ServiceThread thread = new ServiceThread("batterystats-sync",
208 Process.THREAD_PRIORITY_DEFAULT, true);
209 thread.start();
210 mHandler = new BatteryStatsHandler(thread.getLooper());
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700211
212 // BatteryStatsImpl expects the ActivityManagerService handler, so pass that one through.
Badhri Jagan Sridharan68cdf192016-04-03 21:57:15 -0700213 mStats = new BatteryStatsImpl(systemDir, handler, mHandler, this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800214 }
Badhri Jagan Sridharan68cdf192016-04-03 21:57:15 -0700215
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800216 public void publish(Context context) {
217 mContext = context;
Amith Yamasanif37447b2009-10-08 18:28:01 -0700218 mStats.setRadioScanningTimeout(mContext.getResources().getInteger(
219 com.android.internal.R.integer.config_radioScanningTimeout)
220 * 1000L);
Adam Lesinskie08af192015-03-25 16:42:59 -0700221 mStats.setPowerProfile(new PowerProfile(context));
Adam Lesinski6832f392015-09-05 18:05:40 -0700222 ServiceManager.addService(BatteryStats.SERVICE_NAME, asBinder());
Jeff Brown2c43c332014-06-12 22:38:59 -0700223 }
224
225 /**
226 * At the time when the constructor runs, the power manager has not yet been
227 * initialized. So we initialize the low power observer later.
228 */
229 public void initPowerManagement() {
Adam Lesinski010bf372016-04-11 12:18:18 -0700230 final PowerManagerInternal powerMgr = LocalServices.getService(PowerManagerInternal.class);
231 powerMgr.registerLowPowerModeObserver(this);
232 mStats.notePowerSaveMode(powerMgr.getLowPowerModeEnabled());
Dianne Hackbornc51cf032014-03-02 19:08:15 -0800233 (new WakeupReasonThread()).start();
Jeff Brown2c43c332014-06-12 22:38:59 -0700234 }
235
Dianne Hackborn55280a92009-05-07 15:53:46 -0700236 public void shutdown() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800237 Slog.w("BatteryStats", "Writing battery stats before shutdown...");
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700238
Adam Lesinski010bf372016-04-11 12:18:18 -0700239 updateExternalStatsSync("shutdown", BatteryStatsImpl.ExternalStatsSync.UPDATE_ALL);
Dianne Hackborn55280a92009-05-07 15:53:46 -0700240 synchronized (mStats) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700241 mStats.shutdownLocked();
Dianne Hackborn55280a92009-05-07 15:53:46 -0700242 }
Adam Lesinski20b84df2016-04-19 17:33:33 -0700243
244 // Shutdown the thread we made.
245 mHandler.getLooper().quit();
Dianne Hackborn55280a92009-05-07 15:53:46 -0700246 }
247
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800248 public static IBatteryStats getService() {
249 if (sService != null) {
250 return sService;
251 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700252 IBinder b = ServiceManager.getService(BatteryStats.SERVICE_NAME);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800253 sService = asInterface(b);
254 return sService;
255 }
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700256
257 @Override
258 public void onLowPowerModeChanged(boolean enabled) {
259 synchronized (mStats) {
Dianne Hackborn8ad2af72015-03-17 17:00:24 -0700260 mStats.notePowerSaveMode(enabled);
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700261 }
262 }
263
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800264 /**
265 * @return the current statistics object, which may be modified
266 * to reflect events that affect battery usage. You must lock the
267 * stats object before doing anything with it.
268 */
269 public BatteryStatsImpl getActiveStatistics() {
270 return mStats;
271 }
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700272
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700273 /**
274 * Schedules a write to disk to occur. This will cause the BatteryStatsImpl
275 * object to update with the latest info, then write to disk.
276 */
277 public void scheduleWriteToDisk() {
278 mHandler.sendEmptyMessage(BatteryStatsHandler.MSG_WRITE_TO_DISK);
279 }
280
Dianne Hackborn2f1993e2014-09-26 11:28:01 -0700281 // These are for direct use by the activity manager...
282
Adam Lesinskib83ffee2015-05-12 14:43:47 -0700283 /**
284 * Remove a UID from the BatteryStats and BatteryStats' external dependencies.
285 */
286 void removeUid(int uid) {
287 synchronized (mStats) {
288 mStats.removeUidStatsLocked(uid);
289 }
290 }
291
Dianne Hackborn2f1993e2014-09-26 11:28:01 -0700292 void addIsolatedUid(int isolatedUid, int appUid) {
293 synchronized (mStats) {
294 mStats.addIsolatedUidLocked(isolatedUid, appUid);
295 }
296 }
297
298 void removeIsolatedUid(int isolatedUid, int appUid) {
299 synchronized (mStats) {
Adam Lesinski61db88f2015-07-01 15:05:07 -0700300 mStats.scheduleRemoveIsolatedUidLocked(isolatedUid, appUid);
Dianne Hackborn2f1993e2014-09-26 11:28:01 -0700301 }
302 }
303
304 void noteProcessStart(String name, int uid) {
305 synchronized (mStats) {
306 mStats.noteProcessStartLocked(name, uid);
307 }
308 }
309
Dianne Hackborn1e01d162014-12-04 17:46:42 -0800310 void noteProcessCrash(String name, int uid) {
311 synchronized (mStats) {
312 mStats.noteProcessCrashLocked(name, uid);
313 }
314 }
315
316 void noteProcessAnr(String name, int uid) {
317 synchronized (mStats) {
318 mStats.noteProcessAnrLocked(name, uid);
319 }
320 }
321
Dianne Hackborn2f1993e2014-09-26 11:28:01 -0700322 void noteProcessFinish(String name, int uid) {
323 synchronized (mStats) {
324 mStats.noteProcessFinishLocked(name, uid);
325 }
326 }
327
Dianne Hackborna8d10942015-11-19 17:55:19 -0800328 void noteUidProcessState(int uid, int state) {
329 synchronized (mStats) {
330 mStats.noteUidProcessStateLocked(uid, state);
331 }
332 }
333
Dianne Hackborn2f1993e2014-09-26 11:28:01 -0700334 // Public interface...
335
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800336 public byte[] getStatistics() {
337 mContext.enforceCallingPermission(
338 android.Manifest.permission.BATTERY_STATS, null);
Joe Onorato8a9b2202010-02-26 18:56:32 -0800339 //Slog.i("foo", "SENDING BATTERY INFO:");
340 //mStats.dumpLocked(new LogPrinter(Log.INFO, "foo", Log.LOG_ID_SYSTEM));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800341 Parcel out = Parcel.obtain();
Adam Lesinski010bf372016-04-11 12:18:18 -0700342 updateExternalStatsSync("get-stats", BatteryStatsImpl.ExternalStatsSync.UPDATE_ALL);
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700343 synchronized (mStats) {
344 mStats.writeToParcel(out, 0);
345 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800346 byte[] data = out.marshall();
347 out.recycle();
348 return data;
349 }
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700350
351 public ParcelFileDescriptor getStatisticsStream() {
352 mContext.enforceCallingPermission(
353 android.Manifest.permission.BATTERY_STATS, null);
354 //Slog.i("foo", "SENDING BATTERY INFO:");
355 //mStats.dumpLocked(new LogPrinter(Log.INFO, "foo", Log.LOG_ID_SYSTEM));
356 Parcel out = Parcel.obtain();
Adam Lesinski010bf372016-04-11 12:18:18 -0700357 updateExternalStatsSync("get-stats", BatteryStatsImpl.ExternalStatsSync.UPDATE_ALL);
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700358 synchronized (mStats) {
359 mStats.writeToParcel(out, 0);
360 }
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700361 byte[] data = out.marshall();
362 out.recycle();
363 try {
364 return ParcelFileDescriptor.fromData(data, "battery-stats");
365 } catch (IOException e) {
366 Slog.w(TAG, "Unable to create shared memory", e);
367 return null;
368 }
369 }
370
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700371 public boolean isCharging() {
372 synchronized (mStats) {
373 return mStats.isCharging();
374 }
375 }
376
Dianne Hackbornab5c0ea2014-04-29 14:53:32 -0700377 public long computeBatteryTimeRemaining() {
378 synchronized (mStats) {
379 long time = mStats.computeBatteryTimeRemaining(SystemClock.elapsedRealtime());
380 return time >= 0 ? (time/1000) : time;
381 }
382 }
383
384 public long computeChargeTimeRemaining() {
385 synchronized (mStats) {
386 long time = mStats.computeChargeTimeRemaining(SystemClock.elapsedRealtime());
387 return time >= 0 ? (time/1000) : time;
388 }
389 }
390
Dianne Hackborn099bc622014-01-22 13:39:16 -0800391 public void noteEvent(int code, String name, int uid) {
392 enforceCallingPermission();
393 synchronized (mStats) {
394 mStats.noteEventLocked(code, name, uid);
395 }
396 }
397
Dianne Hackbornfdb19562014-07-11 16:03:36 -0700398 public void noteSyncStart(String name, int uid) {
399 enforceCallingPermission();
400 synchronized (mStats) {
401 mStats.noteSyncStartLocked(name, uid);
402 }
403 }
404
405 public void noteSyncFinish(String name, int uid) {
406 enforceCallingPermission();
407 synchronized (mStats) {
408 mStats.noteSyncFinishLocked(name, uid);
409 }
410 }
411
412 public void noteJobStart(String name, int uid) {
413 enforceCallingPermission();
414 synchronized (mStats) {
415 mStats.noteJobStartLocked(name, uid);
416 }
417 }
418
419 public void noteJobFinish(String name, int uid) {
420 enforceCallingPermission();
421 synchronized (mStats) {
422 mStats.noteJobFinishLocked(name, uid);
423 }
424 }
425
Dianne Hackborn1e383822015-04-10 14:02:33 -0700426 public void noteAlarmStart(String name, int uid) {
427 enforceCallingPermission();
428 synchronized (mStats) {
429 mStats.noteAlarmStartLocked(name, uid);
430 }
431 }
432
433 public void noteAlarmFinish(String name, int uid) {
434 enforceCallingPermission();
435 synchronized (mStats) {
436 mStats.noteAlarmFinishLocked(name, uid);
437 }
438 }
439
Dianne Hackborna1f1a3c2014-02-24 18:12:28 -0800440 public void noteStartWakelock(int uid, int pid, String name, String historyName, int type,
Dianne Hackborn3d658bf2014-02-05 13:38:56 -0800441 boolean unimportantForLogging) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800442 enforceCallingPermission();
443 synchronized (mStats) {
Dianne Hackborne5167ca2014-03-08 14:39:10 -0800444 mStats.noteStartWakeLocked(uid, pid, name, historyName, type, unimportantForLogging,
Dianne Hackborn40c87252014-03-19 16:55:40 -0700445 SystemClock.elapsedRealtime(), SystemClock.uptimeMillis());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800446 }
447 }
448
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700449 public void noteStopWakelock(int uid, int pid, String name, String historyName, int type) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800450 enforceCallingPermission();
451 synchronized (mStats) {
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700452 mStats.noteStopWakeLocked(uid, pid, name, historyName, type,
453 SystemClock.elapsedRealtime(), SystemClock.uptimeMillis());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800454 }
455 }
456
Dianne Hackborna1f1a3c2014-02-24 18:12:28 -0800457 public void noteStartWakelockFromSource(WorkSource ws, int pid, String name,
458 String historyName, int type, boolean unimportantForLogging) {
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700459 enforceCallingPermission();
460 synchronized (mStats) {
Dianne Hackborna1f1a3c2014-02-24 18:12:28 -0800461 mStats.noteStartWakeFromSourceLocked(ws, pid, name, historyName,
462 type, unimportantForLogging);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700463 }
464 }
465
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700466 public void noteChangeWakelockFromSource(WorkSource ws, int pid, String name,
467 String historyName, int type, WorkSource newWs, int newPid, String newName,
Dianne Hackborne5167ca2014-03-08 14:39:10 -0800468 String newHistoryName, int newType, boolean newUnimportantForLogging) {
469 enforceCallingPermission();
470 synchronized (mStats) {
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700471 mStats.noteChangeWakelockFromSourceLocked(ws, pid, name, historyName, type,
Dianne Hackborne5167ca2014-03-08 14:39:10 -0800472 newWs, newPid, newName, newHistoryName, newType, newUnimportantForLogging);
473 }
474 }
475
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700476 public void noteStopWakelockFromSource(WorkSource ws, int pid, String name, String historyName,
477 int type) {
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700478 enforceCallingPermission();
479 synchronized (mStats) {
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700480 mStats.noteStopWakeFromSourceLocked(ws, pid, name, historyName, type);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700481 }
482 }
483
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800484 public void noteStartSensor(int uid, int sensor) {
485 enforceCallingPermission();
486 synchronized (mStats) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700487 mStats.noteStartSensorLocked(uid, sensor);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800488 }
489 }
490
491 public void noteStopSensor(int uid, int sensor) {
492 enforceCallingPermission();
493 synchronized (mStats) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700494 mStats.noteStopSensorLocked(uid, sensor);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800495 }
496 }
497
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800498 public void noteVibratorOn(int uid, long durationMillis) {
499 enforceCallingPermission();
500 synchronized (mStats) {
501 mStats.noteVibratorOnLocked(uid, durationMillis);
502 }
503 }
504
505 public void noteVibratorOff(int uid) {
506 enforceCallingPermission();
507 synchronized (mStats) {
508 mStats.noteVibratorOffLocked(uid);
509 }
510 }
511
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800512 public void noteStartGps(int uid) {
513 enforceCallingPermission();
514 synchronized (mStats) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700515 mStats.noteStartGpsLocked(uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800516 }
517 }
518
519 public void noteStopGps(int uid) {
520 enforceCallingPermission();
521 synchronized (mStats) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700522 mStats.noteStopGpsLocked(uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800523 }
524 }
525
Jeff Browne95c3cd2014-05-02 16:59:26 -0700526 public void noteScreenState(int state) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800527 enforceCallingPermission();
528 synchronized (mStats) {
Jeff Browne95c3cd2014-05-02 16:59:26 -0700529 mStats.noteScreenStateLocked(state);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800530 }
531 }
532
Dianne Hackborn617f8772009-03-31 15:04:46 -0700533 public void noteScreenBrightness(int brightness) {
534 enforceCallingPermission();
535 synchronized (mStats) {
536 mStats.noteScreenBrightnessLocked(brightness);
537 }
538 }
539
Dianne Hackborn617f8772009-03-31 15:04:46 -0700540 public void noteUserActivity(int uid, int event) {
541 enforceCallingPermission();
542 synchronized (mStats) {
543 mStats.noteUserActivityLocked(uid, event);
544 }
545 }
Jeff Browne95c3cd2014-05-02 16:59:26 -0700546
Dianne Hackborn280a64e2015-07-13 14:48:08 -0700547 public void noteWakeUp(String reason, int reasonUid) {
548 enforceCallingPermission();
549 synchronized (mStats) {
550 mStats.noteWakeUpLocked(reason, reasonUid);
551 }
552 }
553
Jeff Browne95c3cd2014-05-02 16:59:26 -0700554 public void noteInteractive(boolean interactive) {
555 enforceCallingPermission();
556 synchronized (mStats) {
557 mStats.noteInteractiveLocked(interactive);
558 }
559 }
Dianne Hackborne13c4c02014-02-11 17:18:35 -0800560
Dianne Hackborn1e01d162014-12-04 17:46:42 -0800561 public void noteConnectivityChanged(int type, String extra) {
562 enforceCallingPermission();
563 synchronized (mStats) {
564 mStats.noteConnectivityChangedLocked(type, extra);
565 }
566 }
567
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -0700568 public void noteMobileRadioPowerState(int powerState, long timestampNs) {
Dianne Hackborne13c4c02014-02-11 17:18:35 -0800569 enforceCallingPermission();
570 synchronized (mStats) {
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -0700571 mStats.noteMobileRadioPowerState(powerState, timestampNs);
Dianne Hackborne13c4c02014-02-11 17:18:35 -0800572 }
573 }
574
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800575 public void notePhoneOn() {
576 enforceCallingPermission();
577 synchronized (mStats) {
578 mStats.notePhoneOnLocked();
579 }
580 }
581
582 public void notePhoneOff() {
583 enforceCallingPermission();
584 synchronized (mStats) {
585 mStats.notePhoneOffLocked();
586 }
587 }
The Android Open Source Project10592532009-03-18 17:39:46 -0700588
Wink Savillee9b06d72009-05-18 21:47:50 -0700589 public void notePhoneSignalStrength(SignalStrength signalStrength) {
Dianne Hackborn627bba72009-03-24 22:32:56 -0700590 enforceCallingPermission();
591 synchronized (mStats) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700592 mStats.notePhoneSignalStrengthLocked(signalStrength);
Dianne Hackborn627bba72009-03-24 22:32:56 -0700593 }
594 }
595
596 public void notePhoneDataConnectionState(int dataType, boolean hasData) {
597 enforceCallingPermission();
598 synchronized (mStats) {
599 mStats.notePhoneDataConnectionStateLocked(dataType, hasData);
600 }
601 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -0700602
Amith Yamasanif37447b2009-10-08 18:28:01 -0700603 public void notePhoneState(int state) {
Amith Yamasani32dbefd2009-06-19 09:21:17 -0700604 enforceCallingPermission();
Dianne Hackborne4a59512010-12-07 11:08:07 -0800605 int simState = TelephonyManager.getDefault().getSimState();
Amith Yamasani32dbefd2009-06-19 09:21:17 -0700606 synchronized (mStats) {
Dianne Hackborne4a59512010-12-07 11:08:07 -0800607 mStats.notePhoneStateLocked(state, simState);
Amith Yamasani32dbefd2009-06-19 09:21:17 -0700608 }
609 }
610
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700611 public void noteWifiOn() {
The Android Open Source Project10592532009-03-18 17:39:46 -0700612 enforceCallingPermission();
613 synchronized (mStats) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700614 mStats.noteWifiOnLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -0700615 }
616 }
617
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700618 public void noteWifiOff() {
The Android Open Source Project10592532009-03-18 17:39:46 -0700619 enforceCallingPermission();
620 synchronized (mStats) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700621 mStats.noteWifiOffLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -0700622 }
623 }
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700624
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700625 public void noteStartAudio(int uid) {
626 enforceCallingPermission();
627 synchronized (mStats) {
628 mStats.noteAudioOnLocked(uid);
629 }
630 }
631
632 public void noteStopAudio(int uid) {
633 enforceCallingPermission();
634 synchronized (mStats) {
635 mStats.noteAudioOffLocked(uid);
636 }
637 }
638
639 public void noteStartVideo(int uid) {
640 enforceCallingPermission();
641 synchronized (mStats) {
642 mStats.noteVideoOnLocked(uid);
643 }
644 }
645
646 public void noteStopVideo(int uid) {
647 enforceCallingPermission();
648 synchronized (mStats) {
649 mStats.noteVideoOffLocked(uid);
650 }
651 }
652
Dianne Hackborn10eaa852014-07-22 22:54:55 -0700653 public void noteResetAudio() {
654 enforceCallingPermission();
655 synchronized (mStats) {
656 mStats.noteResetAudioLocked();
657 }
658 }
659
660 public void noteResetVideo() {
661 enforceCallingPermission();
662 synchronized (mStats) {
663 mStats.noteResetVideoLocked();
664 }
665 }
666
Ruben Brunk6d2c3632015-05-26 17:32:16 -0700667 public void noteFlashlightOn(int uid) {
Dianne Hackbornabc7c492014-06-30 16:57:46 -0700668 enforceCallingPermission();
669 synchronized (mStats) {
Ruben Brunk6d2c3632015-05-26 17:32:16 -0700670 mStats.noteFlashlightOnLocked(uid);
Dianne Hackbornabc7c492014-06-30 16:57:46 -0700671 }
672 }
673
Ruben Brunk6d2c3632015-05-26 17:32:16 -0700674 public void noteFlashlightOff(int uid) {
Dianne Hackbornabc7c492014-06-30 16:57:46 -0700675 enforceCallingPermission();
676 synchronized (mStats) {
Ruben Brunk6d2c3632015-05-26 17:32:16 -0700677 mStats.noteFlashlightOffLocked(uid);
678 }
679 }
680
681 public void noteStartCamera(int uid) {
682 enforceCallingPermission();
683 synchronized (mStats) {
684 mStats.noteCameraOnLocked(uid);
685 }
686 }
687
688 public void noteStopCamera(int uid) {
689 enforceCallingPermission();
690 synchronized (mStats) {
691 mStats.noteCameraOffLocked(uid);
692 }
693 }
694
695 public void noteResetCamera() {
696 enforceCallingPermission();
697 synchronized (mStats) {
698 mStats.noteResetCameraLocked();
699 }
700 }
701
702 public void noteResetFlashlight() {
703 enforceCallingPermission();
704 synchronized (mStats) {
705 mStats.noteResetFlashlightLocked();
Dianne Hackbornabc7c492014-06-30 16:57:46 -0700706 }
707 }
708
Adam Lesinskie08af192015-03-25 16:42:59 -0700709 @Override
710 public void noteWifiRadioPowerState(int powerState, long tsNanos) {
711 enforceCallingPermission();
712
713 // There was a change in WiFi power state.
714 // Collect data now for the past activity.
Dianne Hackborn0c820db2015-04-14 17:47:34 -0700715 synchronized (mStats) {
Adam Lesinskia7c90c82015-06-18 14:52:24 -0700716 if (mStats.isOnBattery()) {
Adam Lesinski06f46cb2015-06-23 13:42:53 -0700717 final String type = (powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH ||
718 powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_MEDIUM) ? "active"
719 : "inactive";
Adam Lesinski9f55cc72016-01-27 20:42:14 -0800720 mHandler.scheduleSync("wifi-data: " + type,
721 BatteryStatsImpl.ExternalStatsSync.UPDATE_WIFI);
Adam Lesinskia7c90c82015-06-18 14:52:24 -0700722 }
Dianne Hackborn0c820db2015-04-14 17:47:34 -0700723 mStats.noteWifiRadioPowerState(powerState, tsNanos);
724 }
Adam Lesinskie08af192015-03-25 16:42:59 -0700725 }
726
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700727 public void noteWifiRunning(WorkSource ws) {
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700728 enforceCallingPermission();
729 synchronized (mStats) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700730 mStats.noteWifiRunningLocked(ws);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700731 }
732 }
733
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700734 public void noteWifiRunningChanged(WorkSource oldWs, WorkSource newWs) {
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700735 enforceCallingPermission();
736 synchronized (mStats) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700737 mStats.noteWifiRunningChangedLocked(oldWs, newWs);
738 }
739 }
740
741 public void noteWifiStopped(WorkSource ws) {
742 enforceCallingPermission();
743 synchronized (mStats) {
744 mStats.noteWifiStoppedLocked(ws);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700745 }
746 }
747
Dianne Hackbornca1bf212014-02-14 14:18:36 -0800748 public void noteWifiState(int wifiState, String accessPoint) {
749 enforceCallingPermission();
750 synchronized (mStats) {
751 mStats.noteWifiStateLocked(wifiState, accessPoint);
752 }
753 }
754
Dianne Hackborn3251b902014-06-20 14:40:53 -0700755 public void noteWifiSupplicantStateChanged(int supplState, boolean failedAuth) {
756 enforceCallingPermission();
757 synchronized (mStats) {
758 mStats.noteWifiSupplicantStateChangedLocked(supplState, failedAuth);
759 }
760 }
761
762 public void noteWifiRssiChanged(int newRssi) {
763 enforceCallingPermission();
764 synchronized (mStats) {
765 mStats.noteWifiRssiChangedLocked(newRssi);
766 }
767 }
768
The Android Open Source Project10592532009-03-18 17:39:46 -0700769 public void noteFullWifiLockAcquired(int uid) {
770 enforceCallingPermission();
771 synchronized (mStats) {
772 mStats.noteFullWifiLockAcquiredLocked(uid);
773 }
774 }
775
776 public void noteFullWifiLockReleased(int uid) {
777 enforceCallingPermission();
778 synchronized (mStats) {
779 mStats.noteFullWifiLockReleasedLocked(uid);
780 }
781 }
Nick Pelly6ccaa542012-06-15 15:22:47 -0700782
783 public void noteWifiScanStarted(int uid) {
The Android Open Source Project10592532009-03-18 17:39:46 -0700784 enforceCallingPermission();
785 synchronized (mStats) {
Nick Pelly6ccaa542012-06-15 15:22:47 -0700786 mStats.noteWifiScanStartedLocked(uid);
The Android Open Source Project10592532009-03-18 17:39:46 -0700787 }
788 }
Nick Pelly6ccaa542012-06-15 15:22:47 -0700789
790 public void noteWifiScanStopped(int uid) {
The Android Open Source Project10592532009-03-18 17:39:46 -0700791 enforceCallingPermission();
792 synchronized (mStats) {
Nick Pelly6ccaa542012-06-15 15:22:47 -0700793 mStats.noteWifiScanStoppedLocked(uid);
The Android Open Source Project10592532009-03-18 17:39:46 -0700794 }
795 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800796
Robert Greenwalt5347bd42009-05-13 15:10:16 -0700797 public void noteWifiMulticastEnabled(int uid) {
798 enforceCallingPermission();
799 synchronized (mStats) {
800 mStats.noteWifiMulticastEnabledLocked(uid);
801 }
802 }
803
804 public void noteWifiMulticastDisabled(int uid) {
805 enforceCallingPermission();
806 synchronized (mStats) {
807 mStats.noteWifiMulticastDisabledLocked(uid);
808 }
809 }
810
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700811 public void noteFullWifiLockAcquiredFromSource(WorkSource ws) {
812 enforceCallingPermission();
813 synchronized (mStats) {
814 mStats.noteFullWifiLockAcquiredFromSourceLocked(ws);
815 }
816 }
817
818 public void noteFullWifiLockReleasedFromSource(WorkSource ws) {
819 enforceCallingPermission();
820 synchronized (mStats) {
821 mStats.noteFullWifiLockReleasedFromSourceLocked(ws);
822 }
823 }
824
Nick Pelly6ccaa542012-06-15 15:22:47 -0700825 public void noteWifiScanStartedFromSource(WorkSource ws) {
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700826 enforceCallingPermission();
827 synchronized (mStats) {
Nick Pelly6ccaa542012-06-15 15:22:47 -0700828 mStats.noteWifiScanStartedFromSourceLocked(ws);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700829 }
830 }
831
Nick Pelly6ccaa542012-06-15 15:22:47 -0700832 public void noteWifiScanStoppedFromSource(WorkSource ws) {
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700833 enforceCallingPermission();
834 synchronized (mStats) {
Nick Pelly6ccaa542012-06-15 15:22:47 -0700835 mStats.noteWifiScanStoppedFromSourceLocked(ws);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700836 }
837 }
838
Robert Greenwalta029ea12013-09-25 16:38:12 -0700839 public void noteWifiBatchedScanStartedFromSource(WorkSource ws, int csph) {
840 enforceCallingPermission();
841 synchronized (mStats) {
842 mStats.noteWifiBatchedScanStartedFromSourceLocked(ws, csph);
843 }
844 }
845
846 public void noteWifiBatchedScanStoppedFromSource(WorkSource ws) {
847 enforceCallingPermission();
848 synchronized (mStats) {
849 mStats.noteWifiBatchedScanStoppedFromSourceLocked(ws);
850 }
851 }
852
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700853 public void noteWifiMulticastEnabledFromSource(WorkSource ws) {
854 enforceCallingPermission();
855 synchronized (mStats) {
856 mStats.noteWifiMulticastEnabledFromSourceLocked(ws);
857 }
858 }
859
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700860 @Override
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700861 public void noteWifiMulticastDisabledFromSource(WorkSource ws) {
862 enforceCallingPermission();
863 synchronized (mStats) {
864 mStats.noteWifiMulticastDisabledFromSourceLocked(ws);
865 }
866 }
867
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700868 @Override
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700869 public void noteNetworkInterfaceType(String iface, int networkType) {
Jeff Sharkey1059c3c2011-10-04 16:54:49 -0700870 enforceCallingPermission();
871 synchronized (mStats) {
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700872 mStats.noteNetworkInterfaceTypeLocked(iface, networkType);
Jeff Sharkey1059c3c2011-10-04 16:54:49 -0700873 }
874 }
875
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700876 @Override
877 public void noteNetworkStatsEnabled() {
878 enforceCallingPermission();
879 synchronized (mStats) {
880 mStats.noteNetworkStatsEnabledLocked();
881 }
882 }
883
Dianne Hackborn8ad2af72015-03-17 17:00:24 -0700884 @Override
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700885 public void noteDeviceIdleMode(int mode, String activeReason, int activeUid) {
Dianne Hackborn8ad2af72015-03-17 17:00:24 -0700886 enforceCallingPermission();
887 synchronized (mStats) {
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700888 mStats.noteDeviceIdleModeLocked(mode, activeReason, activeUid);
Dianne Hackborn8ad2af72015-03-17 17:00:24 -0700889 }
890 }
891
892 public void notePackageInstalled(String pkgName, int versionCode) {
893 enforceCallingPermission();
894 synchronized (mStats) {
895 mStats.notePackageInstalledLocked(pkgName, versionCode);
896 }
897 }
898
899 public void notePackageUninstalled(String pkgName) {
900 enforceCallingPermission();
901 synchronized (mStats) {
902 mStats.notePackageUninstalledLocked(pkgName);
903 }
904 }
905
Adam Lesinski6771d622016-01-15 18:14:47 -0800906 @Override
907 public void noteBleScanStarted(WorkSource ws) {
908 enforceCallingPermission();
Adam Lesinski9f55cc72016-01-27 20:42:14 -0800909 synchronized (mStats) {
910 mStats.noteBluetoothScanStartedFromSourceLocked(ws);
911 }
Adam Lesinski6771d622016-01-15 18:14:47 -0800912 }
913
914 @Override
915 public void noteBleScanStopped(WorkSource ws) {
916 enforceCallingPermission();
Adam Lesinski9f55cc72016-01-27 20:42:14 -0800917 synchronized (mStats) {
918 mStats.noteBluetoothScanStoppedFromSourceLocked(ws);
919 }
920 }
921
922 @Override
923 public void noteResetBleScan() {
924 enforceCallingPermission();
925 synchronized (mStats) {
926 mStats.noteResetBluetoothScanLocked();
927 }
Adam Lesinski6771d622016-01-15 18:14:47 -0800928 }
929
Adam Lesinski010bf372016-04-11 12:18:18 -0700930 @Override
931 public void noteWifiControllerActivity(WifiActivityEnergyInfo info) {
932 enforceCallingPermission();
933
934 if (info == null || !info.isValid()) {
935 Slog.e(TAG, "invalid wifi data given: " + info);
936 return;
937 }
938
939 synchronized (mStats) {
940 mStats.updateWifiStateLocked(info);
941 }
942 }
943
944 @Override
945 public void noteBluetoothControllerActivity(BluetoothActivityEnergyInfo info) {
946 enforceCallingPermission();
947 if (info == null || !info.isValid()) {
948 Slog.e(TAG, "invalid bluetooth data given: " + info);
949 return;
950 }
951
952 synchronized (mStats) {
953 mStats.updateBluetoothStateLocked(info);
954 }
955 }
956
957 @Override
958 public void noteModemControllerActivity(ModemActivityInfo info) {
959 enforceCallingPermission();
960
961 if (info == null || !info.isValid()) {
962 Slog.e(TAG, "invalid modem data given: " + info);
963 return;
964 }
965
966 synchronized (mStats) {
967 mStats.updateMobileRadioStateLocked(SystemClock.elapsedRealtime(), info);
968 }
969 }
970
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800971 public boolean isOnBattery() {
972 return mStats.isOnBattery();
973 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700974
Adam Lesinskid7616ef2015-07-27 11:43:05 -0700975 @Override
976 public void setBatteryState(final int status, final int health, final int plugType,
Adam Lesinskia8018ac2016-05-03 10:18:10 -0700977 final int level, final int temp, final int volt, final int chargeUAh) {
Adam Lesinskid7616ef2015-07-27 11:43:05 -0700978 enforceCallingPermission();
979
980 // BatteryService calls us here and we may update external state. It would be wrong
981 // to block such a low level service like BatteryService on external stats like WiFi.
982 mHandler.post(new Runnable() {
983 @Override
984 public void run() {
985 synchronized (mStats) {
986 final boolean onBattery = plugType == BatteryStatsImpl.BATTERY_PLUGGED_NONE;
987 if (mStats.isOnBattery() == onBattery) {
988 // The battery state has not changed, so we don't need to sync external
989 // stats immediately.
Adam Lesinski926969b2016-04-28 17:31:12 -0700990 mStats.setBatteryStateLocked(status, health, plugType, level, temp, volt,
Adam Lesinskia8018ac2016-05-03 10:18:10 -0700991 chargeUAh);
Adam Lesinskid7616ef2015-07-27 11:43:05 -0700992 return;
993 }
994 }
995
996 // Sync external stats first as the battery has changed states. If we don't sync
997 // immediately here, we may not collect the relevant data later.
Adam Lesinski010bf372016-04-11 12:18:18 -0700998 updateExternalStatsSync("battery-state", BatteryStatsImpl.ExternalStatsSync.UPDATE_ALL);
Adam Lesinskid7616ef2015-07-27 11:43:05 -0700999 synchronized (mStats) {
Adam Lesinski926969b2016-04-28 17:31:12 -07001000 mStats.setBatteryStateLocked(status, health, plugType, level, temp, volt,
Adam Lesinskia8018ac2016-05-03 10:18:10 -07001001 chargeUAh);
Adam Lesinskid7616ef2015-07-27 11:43:05 -07001002 }
1003 }
1004 });
Evan Millar633a1742009-04-02 16:36:33 -07001005 }
1006
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001007 public long getAwakeTimeBattery() {
1008 mContext.enforceCallingOrSelfPermission(
1009 android.Manifest.permission.BATTERY_STATS, null);
1010 return mStats.getAwakeTimeBattery();
1011 }
1012
1013 public long getAwakeTimePlugged() {
1014 mContext.enforceCallingOrSelfPermission(
1015 android.Manifest.permission.BATTERY_STATS, null);
1016 return mStats.getAwakeTimePlugged();
1017 }
1018
1019 public void enforceCallingPermission() {
1020 if (Binder.getCallingPid() == Process.myPid()) {
1021 return;
1022 }
1023 mContext.enforcePermission(android.Manifest.permission.UPDATE_DEVICE_STATS,
1024 Binder.getCallingPid(), Binder.getCallingUid(), null);
1025 }
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001026
1027 final class WakeupReasonThread extends Thread {
Adam Lesinski515702c2015-07-23 18:13:38 -07001028 private static final int MAX_REASON_SIZE = 512;
1029 private CharsetDecoder mDecoder;
1030 private ByteBuffer mUtf8Buffer;
1031 private CharBuffer mUtf16Buffer;
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001032
1033 WakeupReasonThread() {
1034 super("BatteryStats_wakeupReason");
1035 }
1036
1037 public void run() {
1038 Process.setThreadPriority(Process.THREAD_PRIORITY_FOREGROUND);
1039
Adam Lesinski515702c2015-07-23 18:13:38 -07001040 mDecoder = StandardCharsets.UTF_8
1041 .newDecoder()
1042 .onMalformedInput(CodingErrorAction.REPLACE)
1043 .onUnmappableCharacter(CodingErrorAction.REPLACE)
1044 .replaceWith("?");
1045
1046 mUtf8Buffer = ByteBuffer.allocateDirect(MAX_REASON_SIZE);
1047 mUtf16Buffer = CharBuffer.allocate(MAX_REASON_SIZE);
1048
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001049 try {
Adam Lesinski515702c2015-07-23 18:13:38 -07001050 String reason;
1051 while ((reason = waitWakeup()) != null) {
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001052 synchronized (mStats) {
Adam Lesinski515702c2015-07-23 18:13:38 -07001053 mStats.noteWakeupReasonLocked(reason);
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001054 }
1055 }
1056 } catch (RuntimeException e) {
1057 Slog.e(TAG, "Failure reading wakeup reasons", e);
1058 }
1059 }
Adam Lesinski515702c2015-07-23 18:13:38 -07001060
1061 private String waitWakeup() {
1062 mUtf8Buffer.clear();
1063 mUtf16Buffer.clear();
1064 mDecoder.reset();
1065
1066 int bytesWritten = nativeWaitWakeup(mUtf8Buffer);
1067 if (bytesWritten < 0) {
1068 return null;
1069 } else if (bytesWritten == 0) {
1070 return "unknown";
1071 }
1072
1073 // Set the buffer's limit to the number of bytes written.
1074 mUtf8Buffer.limit(bytesWritten);
1075
1076 // Decode the buffer from UTF-8 to UTF-16.
1077 // Unmappable characters will be replaced.
1078 mDecoder.decode(mUtf8Buffer, mUtf16Buffer, true);
1079 mUtf16Buffer.flip();
1080
1081 // Create a String from the UTF-16 buffer.
1082 return mUtf16Buffer.toString();
1083 }
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001084 }
1085
Adam Lesinski515702c2015-07-23 18:13:38 -07001086 private static native int nativeWaitWakeup(ByteBuffer outBuffer);
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001087
Dianne Hackbornae384452011-06-28 12:33:48 -07001088 private void dumpHelp(PrintWriter pw) {
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001089 pw.println("Battery stats (batterystats) dump options:");
Dianne Hackborn1e725a72015-03-24 18:23:19 -07001090 pw.println(" [--checkin] [--history] [--history-start] [--charged] [-c]");
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08001091 pw.println(" [--daily] [--reset] [--write] [--new-daily] [--read-daily] [-h] [<package.name>]");
Dianne Hackborn865b79b2015-08-18 17:33:00 -07001092 pw.println(" --checkin: generate output for a checkin report; will write (and clear) the");
1093 pw.println(" last old completed stats when they had been reset.");
1094 pw.println(" --c: write the current stats in checkin format.");
Dianne Hackborn099bc622014-01-22 13:39:16 -08001095 pw.println(" --history: show only history data.");
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001096 pw.println(" --history-start <num>: show only history data starting at given time offset.");
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001097 pw.println(" --charged: only output data since last charged.");
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08001098 pw.println(" --daily: only output full daily data.");
Dianne Hackbornae384452011-06-28 12:33:48 -07001099 pw.println(" --reset: reset the stats, clearing all current data.");
1100 pw.println(" --write: force write current collected stats to disk.");
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08001101 pw.println(" --new-daily: immediately create and write new daily stats record.");
1102 pw.println(" --read-daily: read-load last written daily stats.");
Dianne Hackborncbfd23e2013-06-11 14:26:53 -07001103 pw.println(" <package.name>: optional name of package to filter output by.");
Dianne Hackbornfc064132014-06-02 12:42:12 -07001104 pw.println(" -h: print this help text.");
1105 pw.println("Battery stats (batterystats) commands:");
1106 pw.println(" enable|disable <option>");
1107 pw.println(" Enable or disable a running option. Option state is not saved across boots.");
1108 pw.println(" Options are:");
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07001109 pw.println(" full-history: include additional detailed events in battery history:");
Dianne Hackborn1e383822015-04-10 14:02:33 -07001110 pw.println(" wake_lock_in, alarms and proc events");
Dianne Hackbornfc064132014-06-02 12:42:12 -07001111 pw.println(" no-auto-reset: don't automatically reset stats when unplugged");
Dianne Hackbornae384452011-06-28 12:33:48 -07001112 }
1113
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07001114 private int doEnableOrDisable(PrintWriter pw, int i, String[] args, boolean enable) {
1115 i++;
1116 if (i >= args.length) {
1117 pw.println("Missing option argument for " + (enable ? "--enable" : "--disable"));
1118 dumpHelp(pw);
1119 return -1;
1120 }
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07001121 if ("full-wake-history".equals(args[i]) || "full-history".equals(args[i])) {
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07001122 synchronized (mStats) {
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07001123 mStats.setRecordAllHistoryLocked(enable);
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07001124 }
Dianne Hackborn9a755432014-05-15 17:05:22 -07001125 } else if ("no-auto-reset".equals(args[i])) {
1126 synchronized (mStats) {
1127 mStats.setNoAutoReset(enable);
1128 }
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07001129 } else {
1130 pw.println("Unknown enable/disable option: " + args[i]);
1131 dumpHelp(pw);
1132 return -1;
1133 }
1134 return i;
1135 }
1136
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07001137
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001138 @Override
1139 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Kenny Root3abd75b2011-09-29 11:00:41 -07001140 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
1141 != PackageManager.PERMISSION_GRANTED) {
1142 pw.println("Permission Denial: can't dump BatteryStats from from pid="
1143 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1144 + " without permission " + android.Manifest.permission.DUMP);
1145 return;
1146 }
1147
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001148 int flags = 0;
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07001149 boolean useCheckinFormat = false;
1150 boolean isRealCheckin = false;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001151 boolean noOutput = false;
Dianne Hackborn16b0b562014-06-03 17:24:42 -07001152 boolean writeData = false;
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001153 long historyStart = -1;
Dianne Hackborncbfd23e2013-06-11 14:26:53 -07001154 int reqUid = -1;
Dianne Hackborne4a59512010-12-07 11:08:07 -08001155 if (args != null) {
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001156 for (int i=0; i<args.length; i++) {
1157 String arg = args[i];
Dianne Hackborne4a59512010-12-07 11:08:07 -08001158 if ("--checkin".equals(arg)) {
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07001159 useCheckinFormat = true;
1160 isRealCheckin = true;
Dianne Hackborn099bc622014-01-22 13:39:16 -08001161 } else if ("--history".equals(arg)) {
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001162 flags |= BatteryStats.DUMP_HISTORY_ONLY;
1163 } else if ("--history-start".equals(arg)) {
1164 flags |= BatteryStats.DUMP_HISTORY_ONLY;
1165 i++;
1166 if (i >= args.length) {
1167 pw.println("Missing time argument for --history-since");
1168 dumpHelp(pw);
1169 return;
1170 }
1171 historyStart = Long.parseLong(args[i]);
Dianne Hackborn16b0b562014-06-03 17:24:42 -07001172 writeData = true;
Dianne Hackborn49021f52013-09-04 18:03:40 -07001173 } else if ("-c".equals(arg)) {
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07001174 useCheckinFormat = true;
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001175 flags |= BatteryStats.DUMP_INCLUDE_HISTORY;
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001176 } else if ("--charged".equals(arg)) {
1177 flags |= BatteryStats.DUMP_CHARGED_ONLY;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08001178 } else if ("--daily".equals(arg)) {
1179 flags |= BatteryStats.DUMP_DAILY_ONLY;
Dianne Hackborne4a59512010-12-07 11:08:07 -08001180 } else if ("--reset".equals(arg)) {
1181 synchronized (mStats) {
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08001182 mStats.resetAllStatsCmdLocked();
Dianne Hackborne4a59512010-12-07 11:08:07 -08001183 pw.println("Battery stats reset.");
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001184 noOutput = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001185 }
Adam Lesinski010bf372016-04-11 12:18:18 -07001186 updateExternalStatsSync("dump", BatteryStatsImpl.ExternalStatsSync.UPDATE_ALL);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001187 } else if ("--write".equals(arg)) {
Adam Lesinski010bf372016-04-11 12:18:18 -07001188 updateExternalStatsSync("dump", BatteryStatsImpl.ExternalStatsSync.UPDATE_ALL);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001189 synchronized (mStats) {
1190 mStats.writeSyncLocked();
1191 pw.println("Battery stats written.");
1192 noOutput = true;
1193 }
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08001194 } else if ("--new-daily".equals(arg)) {
1195 synchronized (mStats) {
1196 mStats.recordDailyStatsLocked();
1197 pw.println("New daily stats written.");
1198 noOutput = true;
1199 }
1200 } else if ("--read-daily".equals(arg)) {
1201 synchronized (mStats) {
1202 mStats.readDailyStatsLocked();
1203 pw.println("Last daily stats read.");
1204 noOutput = true;
1205 }
Dianne Hackbornfc064132014-06-02 12:42:12 -07001206 } else if ("--enable".equals(arg) || "enable".equals(arg)) {
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07001207 i = doEnableOrDisable(pw, i, args, true);
1208 if (i < 0) {
1209 return;
1210 }
1211 pw.println("Enabled: " + args[i]);
1212 return;
Dianne Hackbornfc064132014-06-02 12:42:12 -07001213 } else if ("--disable".equals(arg) || "disable".equals(arg)) {
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07001214 i = doEnableOrDisable(pw, i, args, false);
1215 if (i < 0) {
1216 return;
1217 }
1218 pw.println("Disabled: " + args[i]);
1219 return;
Dianne Hackbornae384452011-06-28 12:33:48 -07001220 } else if ("-h".equals(arg)) {
1221 dumpHelp(pw);
1222 return;
Mike Lockwoode8174042011-08-16 12:53:43 -07001223 } else if ("-a".equals(arg)) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07001224 flags |= BatteryStats.DUMP_VERBOSE;
Dianne Hackborncbfd23e2013-06-11 14:26:53 -07001225 } else if (arg.length() > 0 && arg.charAt(0) == '-'){
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001226 pw.println("Unknown option: " + arg);
Dianne Hackbornae384452011-06-28 12:33:48 -07001227 dumpHelp(pw);
Dianne Hackborncbfd23e2013-06-11 14:26:53 -07001228 return;
1229 } else {
1230 // Not an option, last argument must be a package name.
1231 try {
Jeff Sharkeye06b4d12016-01-06 14:51:50 -07001232 reqUid = mContext.getPackageManager().getPackageUidAsUser(arg,
Dianne Hackborncbfd23e2013-06-11 14:26:53 -07001233 UserHandle.getCallingUserId());
1234 } catch (PackageManager.NameNotFoundException e) {
1235 pw.println("Unknown package: " + arg);
1236 dumpHelp(pw);
1237 return;
1238 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001239 }
1240 }
Dianne Hackborne4a59512010-12-07 11:08:07 -08001241 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001242 if (noOutput) {
1243 return;
1244 }
Dianne Hackborn13a6a9b2015-04-22 18:03:59 -07001245
1246 long ident = Binder.clearCallingIdentity();
1247 try {
1248 if (BatteryStatsHelper.checkWifiOnly(mContext)) {
1249 flags |= BatteryStats.DUMP_DEVICE_WIFI_ONLY;
1250 }
1251 // Fetch data from external sources and update the BatteryStatsImpl object with them.
Adam Lesinski010bf372016-04-11 12:18:18 -07001252 updateExternalStatsSync("dump", BatteryStatsImpl.ExternalStatsSync.UPDATE_ALL);
Dianne Hackborn13a6a9b2015-04-22 18:03:59 -07001253 } finally {
1254 Binder.restoreCallingIdentity(ident);
Dianne Hackbornd953c532014-08-16 18:17:38 -07001255 }
Dianne Hackborn13a6a9b2015-04-22 18:03:59 -07001256
Dianne Hackbornab4a81b2014-10-09 17:59:38 -07001257 if (reqUid >= 0) {
1258 // By default, if the caller is only interested in a specific package, then
1259 // we only dump the aggregated data since charged.
Dianne Hackborn1e725a72015-03-24 18:23:19 -07001260 if ((flags&(BatteryStats.DUMP_HISTORY_ONLY|BatteryStats.DUMP_CHARGED_ONLY)) == 0) {
Dianne Hackbornab4a81b2014-10-09 17:59:38 -07001261 flags |= BatteryStats.DUMP_CHARGED_ONLY;
1262 // Also if they are doing -c, we don't want history.
1263 flags &= ~BatteryStats.DUMP_INCLUDE_HISTORY;
1264 }
1265 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07001266
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07001267 if (useCheckinFormat) {
Dianne Hackborn9cfba352016-03-24 17:31:28 -07001268 List<ApplicationInfo> apps = mContext.getPackageManager().getInstalledApplications(
1269 PackageManager.MATCH_UNINSTALLED_PACKAGES | PackageManager.MATCH_ALL);
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07001270 if (isRealCheckin) {
1271 // For a real checkin, first we want to prefer to use the last complete checkin
1272 // file if there is one.
1273 synchronized (mStats.mCheckinFile) {
1274 if (mStats.mCheckinFile.exists()) {
1275 try {
1276 byte[] raw = mStats.mCheckinFile.readFully();
1277 if (raw != null) {
1278 Parcel in = Parcel.obtain();
1279 in.unmarshall(raw, 0, raw.length);
1280 in.setDataPosition(0);
1281 BatteryStatsImpl checkinStats = new BatteryStatsImpl(
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07001282 null, mStats.mHandler, null);
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07001283 checkinStats.readSummaryFromParcel(in);
1284 in.recycle();
1285 checkinStats.dumpCheckinLocked(mContext, pw, apps, flags,
1286 historyStart);
1287 mStats.mCheckinFile.delete();
1288 return;
1289 }
Adam Lesinski9ae9cba2015-07-08 17:09:34 -07001290 } catch (IOException | ParcelFormatException e) {
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07001291 Slog.w(TAG, "Failure reading checkin file "
1292 + mStats.mCheckinFile.getBaseFile(), e);
1293 }
1294 }
1295 }
1296 }
Dianne Hackborne4a59512010-12-07 11:08:07 -08001297 synchronized (mStats) {
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001298 mStats.dumpCheckinLocked(mContext, pw, apps, flags, historyStart);
Dianne Hackborn16b0b562014-06-03 17:24:42 -07001299 if (writeData) {
1300 mStats.writeAsyncLocked();
1301 }
Dianne Hackborne4a59512010-12-07 11:08:07 -08001302 }
1303 } else {
1304 synchronized (mStats) {
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001305 mStats.dumpLocked(mContext, pw, flags, reqUid, historyStart);
Dianne Hackborn16b0b562014-06-03 17:24:42 -07001306 if (writeData) {
1307 mStats.writeAsyncLocked();
1308 }
Dianne Hackborne4a59512010-12-07 11:08:07 -08001309 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001310 }
1311 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07001312
Adam Lesinski010bf372016-04-11 12:18:18 -07001313 private WifiActivityEnergyInfo extractDelta(WifiActivityEnergyInfo latest) {
1314 final long timePeriodMs = latest.mTimestamp - mLastInfo.mTimestamp;
1315 final long lastIdleMs = mLastInfo.mControllerIdleTimeMs;
1316 final long lastTxMs = mLastInfo.mControllerTxTimeMs;
1317 final long lastRxMs = mLastInfo.mControllerRxTimeMs;
1318 final long lastEnergy = mLastInfo.mControllerEnergyUsed;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07001319
Adam Lesinski010bf372016-04-11 12:18:18 -07001320 // We will modify the last info object to be the delta, and store the new
1321 // WifiActivityEnergyInfo object as our last one.
1322 final WifiActivityEnergyInfo delta = mLastInfo;
1323 delta.mTimestamp = latest.getTimeStamp();
1324 delta.mStackState = latest.getStackState();
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07001325
Adam Lesinski010bf372016-04-11 12:18:18 -07001326 // These times seem to be the most reliable.
1327 delta.mControllerTxTimeMs = latest.mControllerTxTimeMs - lastTxMs;
1328 delta.mControllerRxTimeMs = latest.mControllerRxTimeMs - lastRxMs;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07001329
Adam Lesinski010bf372016-04-11 12:18:18 -07001330 // WiFi calculates the idle time as a difference from the on time and the various
1331 // Rx + Tx times. There seems to be some missing time there because this sometimes
1332 // becomes negative. Just cap it at 0 and move on.
1333 // b/21613534
1334 delta.mControllerIdleTimeMs = Math.max(0, latest.mControllerIdleTimeMs - lastIdleMs);
1335 delta.mControllerEnergyUsed = Math.max(0, latest.mControllerEnergyUsed - lastEnergy);
1336
1337 if (delta.mControllerTxTimeMs < 0 || delta.mControllerRxTimeMs < 0) {
1338 // The stats were reset by the WiFi system (which is why our delta is negative).
1339 // Returns the unaltered stats.
1340 delta.mControllerEnergyUsed = latest.mControllerEnergyUsed;
1341 delta.mControllerRxTimeMs = latest.mControllerRxTimeMs;
1342 delta.mControllerTxTimeMs = latest.mControllerTxTimeMs;
1343 delta.mControllerIdleTimeMs = latest.mControllerIdleTimeMs;
1344
1345 Slog.v(TAG, "WiFi energy data was reset, new WiFi energy data is " + delta);
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07001346 }
1347
Adam Lesinski010bf372016-04-11 12:18:18 -07001348 // There is some accuracy error in reports so allow some slop in the results.
1349 final long SAMPLE_ERROR_MILLIS = 750;
1350 final long totalTimeMs = delta.mControllerIdleTimeMs + delta.mControllerRxTimeMs +
1351 delta.mControllerTxTimeMs;
1352 if (totalTimeMs > timePeriodMs + SAMPLE_ERROR_MILLIS) {
1353 StringBuilder sb = new StringBuilder();
1354 sb.append("Total time ");
1355 TimeUtils.formatDuration(totalTimeMs, sb);
1356 sb.append(" is longer than sample period ");
1357 TimeUtils.formatDuration(timePeriodMs, sb);
1358 sb.append(".\n");
1359 sb.append("Previous WiFi snapshot: ").append("idle=");
1360 TimeUtils.formatDuration(lastIdleMs, sb);
1361 sb.append(" rx=");
1362 TimeUtils.formatDuration(lastRxMs, sb);
1363 sb.append(" tx=");
1364 TimeUtils.formatDuration(lastTxMs, sb);
1365 sb.append(" e=").append(lastEnergy);
1366 sb.append("\n");
1367 sb.append("Current WiFi snapshot: ").append("idle=");
1368 TimeUtils.formatDuration(latest.mControllerIdleTimeMs, sb);
1369 sb.append(" rx=");
1370 TimeUtils.formatDuration(latest.mControllerRxTimeMs, sb);
1371 sb.append(" tx=");
1372 TimeUtils.formatDuration(latest.mControllerTxTimeMs, sb);
1373 sb.append(" e=").append(latest.mControllerEnergyUsed);
1374 Slog.wtf(TAG, sb.toString());
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07001375 }
Adam Lesinski010bf372016-04-11 12:18:18 -07001376
1377 mLastInfo = latest;
1378 return delta;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07001379 }
1380
Adam Lesinski010bf372016-04-11 12:18:18 -07001381 /**
1382 * Helper method to extract the Parcelable controller info from a
1383 * SynchronousResultReceiver.
1384 */
1385 private static <T extends Parcelable> T awaitControllerInfo(
1386 @Nullable SynchronousResultReceiver receiver) throws TimeoutException {
1387 if (receiver == null) {
1388 return null;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07001389 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07001390
Adam Lesinski010bf372016-04-11 12:18:18 -07001391 final SynchronousResultReceiver.Result result =
1392 receiver.awaitResult(EXTERNAL_STATS_SYNC_TIMEOUT_MILLIS);
1393 if (result.bundle != null) {
1394 // This is the final destination for the Bundle.
1395 result.bundle.setDefusable(true);
1396
1397 final T data = result.bundle.getParcelable(BatteryStats.RESULT_RECEIVER_CONTROLLER_KEY);
1398 if (data != null) {
1399 return data;
Adam Lesinski21f76aa2016-01-25 12:27:06 -08001400 }
Adam Lesinski21f76aa2016-01-25 12:27:06 -08001401 }
Adam Lesinski010bf372016-04-11 12:18:18 -07001402 Slog.e(TAG, "no controller energy info supplied");
Adam Lesinski21f76aa2016-01-25 12:27:06 -08001403 return null;
1404 }
1405
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07001406 /**
1407 * Fetches data from external sources (WiFi controller, bluetooth chipset) and updates
1408 * batterystats with that information.
1409 *
1410 * We first grab a lock specific to this method, then once all the data has been collected,
1411 * we grab the mStats lock and update the data.
Adam Lesinskic14c2732015-05-21 15:04:18 -07001412 *
Adam Lesinskic14c2732015-05-21 15:04:18 -07001413 * @param reason The reason why this collection was requested. Useful for debugging.
Adam Lesinskia7c90c82015-06-18 14:52:24 -07001414 * @param updateFlags Which external stats to update. Can be a combination of
Adam Lesinski9f55cc72016-01-27 20:42:14 -08001415 * {@link BatteryStatsImpl.ExternalStatsSync#UPDATE_CPU},
1416 * {@link BatteryStatsImpl.ExternalStatsSync#UPDATE_RADIO},
1417 * {@link BatteryStatsImpl.ExternalStatsSync#UPDATE_WIFI},
1418 * and {@link BatteryStatsImpl.ExternalStatsSync#UPDATE_BT}.
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07001419 */
Adam Lesinski010bf372016-04-11 12:18:18 -07001420 void updateExternalStatsSync(final String reason, int updateFlags) {
1421 SynchronousResultReceiver wifiReceiver = null;
1422 SynchronousResultReceiver bluetoothReceiver = null;
1423 SynchronousResultReceiver modemReceiver = null;
1424
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07001425 synchronized (mExternalStatsLock) {
Adam Lesinskie08af192015-03-25 16:42:59 -07001426 if (mContext == null) {
Adam Lesinski010bf372016-04-11 12:18:18 -07001427 // Don't do any work yet.
Adam Lesinskie08af192015-03-25 16:42:59 -07001428 return;
1429 }
1430
Adam Lesinski9f55cc72016-01-27 20:42:14 -08001431 if ((updateFlags & BatteryStatsImpl.ExternalStatsSync.UPDATE_WIFI) != 0) {
Adam Lesinski010bf372016-04-11 12:18:18 -07001432 if (mWifiManager == null) {
1433 mWifiManager = IWifiManager.Stub.asInterface(
1434 ServiceManager.getService(Context.WIFI_SERVICE));
1435 }
1436
1437 if (mWifiManager != null) {
1438 try {
1439 wifiReceiver = new SynchronousResultReceiver();
1440 mWifiManager.requestActivityInfo(wifiReceiver);
1441 } catch (RemoteException e) {
1442 // Oh well.
1443 }
1444 }
Adam Lesinskia7c90c82015-06-18 14:52:24 -07001445 }
1446
Adam Lesinski9f55cc72016-01-27 20:42:14 -08001447 if ((updateFlags & BatteryStatsImpl.ExternalStatsSync.UPDATE_BT) != 0) {
Adam Lesinski010bf372016-04-11 12:18:18 -07001448 final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
1449 if (adapter != null) {
1450 bluetoothReceiver = new SynchronousResultReceiver();
1451 adapter.requestControllerActivityEnergyInfo(
1452 BluetoothAdapter.ACTIVITY_ENERGY_INFO_REFRESHED,
1453 bluetoothReceiver);
1454 }
1455 }
1456
1457 if ((updateFlags & BatteryStatsImpl.ExternalStatsSync.UPDATE_RADIO) != 0) {
1458 if (mTelephony == null) {
1459 mTelephony = TelephonyManager.from(mContext);
1460 }
1461
1462 if (mTelephony != null) {
1463 modemReceiver = new SynchronousResultReceiver();
1464 mTelephony.requestModemActivityInfo(modemReceiver);
1465 }
1466 }
1467
1468 WifiActivityEnergyInfo wifiInfo = null;
1469 BluetoothActivityEnergyInfo bluetoothInfo = null;
1470 ModemActivityInfo modemInfo = null;
1471 try {
1472 wifiInfo = awaitControllerInfo(wifiReceiver);
1473 } catch (TimeoutException e) {
1474 Slog.w(TAG, "Timeout reading wifi stats");
1475 }
1476
1477 try {
1478 bluetoothInfo = awaitControllerInfo(bluetoothReceiver);
1479 } catch (TimeoutException e) {
1480 Slog.w(TAG, "Timeout reading bt stats");
1481 }
1482
1483 try {
1484 modemInfo = awaitControllerInfo(modemReceiver);
1485 } catch (TimeoutException e) {
1486 Slog.w(TAG, "Timeout reading modem stats");
Adam Lesinskic14c2732015-05-21 15:04:18 -07001487 }
1488
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07001489 synchronized (mStats) {
Adam Lesinski010bf372016-04-11 12:18:18 -07001490 mStats.addHistoryEventLocked(
1491 SystemClock.elapsedRealtime(),
1492 SystemClock.uptimeMillis(),
1493 BatteryStats.HistoryItem.EVENT_COLLECT_EXTERNAL_STATS,
1494 reason, 0);
1495
1496 mStats.updateCpuTimeLocked();
1497 mStats.updateKernelWakelocksLocked();
1498
1499 if (wifiInfo != null) {
1500 if (wifiInfo.isValid()) {
1501 mStats.updateWifiStateLocked(extractDelta(wifiInfo));
1502 } else {
1503 Slog.e(TAG, "wifi info is invalid: " + wifiInfo);
1504 }
Dianne Hackborn0c820db2015-04-14 17:47:34 -07001505 }
Adam Lesinski72478f02015-06-17 15:39:43 -07001506
Adam Lesinski010bf372016-04-11 12:18:18 -07001507 if (bluetoothInfo != null) {
1508 if (bluetoothInfo.isValid()) {
1509 mStats.updateBluetoothStateLocked(bluetoothInfo);
1510 } else {
1511 Slog.e(TAG, "bluetooth info is invalid: " + bluetoothInfo);
1512 }
Adam Lesinski72478f02015-06-17 15:39:43 -07001513 }
Adam Lesinskia7c90c82015-06-18 14:52:24 -07001514
Adam Lesinski010bf372016-04-11 12:18:18 -07001515 if (modemInfo != null) {
1516 if (modemInfo.isValid()) {
1517 mStats.updateMobileRadioStateLocked(SystemClock.elapsedRealtime(),
1518 modemInfo);
1519 } else {
1520 Slog.e(TAG, "modem info is invalid: " + modemInfo);
1521 }
Adam Lesinskia7c90c82015-06-18 14:52:24 -07001522 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07001523 }
1524 }
1525 }
Joe Onorato713fec82016-03-04 10:34:02 -08001526
1527 /**
1528 * Gets a snapshot of the system health for a particular uid.
1529 */
1530 @Override
1531 public HealthStatsParceler takeUidSnapshot(int requestUid) {
1532 if (requestUid != Binder.getCallingUid()) {
1533 mContext.enforceCallingOrSelfPermission(
1534 android.Manifest.permission.BATTERY_STATS, null);
1535 }
1536 long ident = Binder.clearCallingIdentity();
1537 try {
Adam Lesinski010bf372016-04-11 12:18:18 -07001538 updateExternalStatsSync("get-health-stats-for-uid",
Joe Onorato713fec82016-03-04 10:34:02 -08001539 BatteryStatsImpl.ExternalStatsSync.UPDATE_ALL);
1540 synchronized (mStats) {
1541 return getHealthStatsForUidLocked(requestUid);
1542 }
1543 } catch (Exception ex) {
1544 Slog.d(TAG, "Crashed while writing for takeUidSnapshot(" + requestUid + ")", ex);
1545 throw ex;
1546 } finally {
1547 Binder.restoreCallingIdentity(ident);
1548 }
1549 }
1550
1551 /**
1552 * Gets a snapshot of the system health for a number of uids.
1553 */
1554 @Override
1555 public HealthStatsParceler[] takeUidSnapshots(int[] requestUids) {
1556 if (!onlyCaller(requestUids)) {
1557 mContext.enforceCallingOrSelfPermission(
1558 android.Manifest.permission.BATTERY_STATS, null);
1559 }
1560 long ident = Binder.clearCallingIdentity();
1561 int i=-1;
1562 try {
Adam Lesinski010bf372016-04-11 12:18:18 -07001563 updateExternalStatsSync("get-health-stats-for-uids",
Joe Onorato713fec82016-03-04 10:34:02 -08001564 BatteryStatsImpl.ExternalStatsSync.UPDATE_ALL);
1565 synchronized (mStats) {
1566 final int N = requestUids.length;
1567 final HealthStatsParceler[] results = new HealthStatsParceler[N];
1568 for (i=0; i<N; i++) {
1569 results[i] = getHealthStatsForUidLocked(requestUids[i]);
1570 }
1571 return results;
1572 }
1573 } catch (Exception ex) {
1574 Slog.d(TAG, "Crashed while writing for takeUidSnapshots("
1575 + Arrays.toString(requestUids) + ") i=" + i, ex);
1576 throw ex;
1577 } finally {
1578 Binder.restoreCallingIdentity(ident);
1579 }
1580 }
1581
1582 /**
1583 * Returns whether the Binder.getCallingUid is the only thing in requestUids.
1584 */
1585 private static boolean onlyCaller(int[] requestUids) {
1586 final int caller = Binder.getCallingUid();
1587 final int N = requestUids.length;
1588 for (int i=0; i<N; i++) {
1589 if (requestUids[i] != caller) {
1590 return false;
1591 }
1592 }
1593 return true;
1594 }
1595
1596 /**
1597 * Gets a HealthStatsParceler for the given uid. You should probably call
Adam Lesinski010bf372016-04-11 12:18:18 -07001598 * updateExternalStatsSync first.
Joe Onorato713fec82016-03-04 10:34:02 -08001599 */
1600 HealthStatsParceler getHealthStatsForUidLocked(int requestUid) {
1601 final HealthStatsBatteryStatsWriter writer = new HealthStatsBatteryStatsWriter();
1602 final HealthStatsWriter uidWriter = new HealthStatsWriter(UidHealthStats.CONSTANTS);
1603 final BatteryStats.Uid uid = mStats.getUidStats().get(requestUid);
1604 if (uid != null) {
1605 writer.writeUid(uidWriter, mStats, uid);
1606 }
1607 return new HealthStatsParceler(uidWriter);
1608 }
1609
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001610}