• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
17 package com.android.server.am;
18 
19 import static android.content.pm.PackageManager.PERMISSION_DENIED;
20 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED;
21 import static android.os.BatteryStats.POWER_DATA_UNAVAILABLE;
22 
23 import android.annotation.NonNull;
24 import android.app.StatsManager;
25 import android.bluetooth.BluetoothActivityEnergyInfo;
26 import android.content.ContentResolver;
27 import android.content.Context;
28 import android.content.pm.ApplicationInfo;
29 import android.content.pm.PackageManager;
30 import android.hardware.power.stats.PowerEntity;
31 import android.hardware.power.stats.State;
32 import android.hardware.power.stats.StateResidency;
33 import android.hardware.power.stats.StateResidencyResult;
34 import android.net.ConnectivityManager;
35 import android.net.INetworkManagementEventObserver;
36 import android.net.Network;
37 import android.net.NetworkCapabilities;
38 import android.os.BatteryManagerInternal;
39 import android.os.BatteryStats;
40 import android.os.BatteryStatsInternal;
41 import android.os.BatteryUsageStats;
42 import android.os.BatteryUsageStatsQuery;
43 import android.os.Binder;
44 import android.os.Handler;
45 import android.os.HandlerThread;
46 import android.os.IBinder;
47 import android.os.INetworkManagementService;
48 import android.os.Parcel;
49 import android.os.ParcelFileDescriptor;
50 import android.os.ParcelFormatException;
51 import android.os.PowerManager.ServiceType;
52 import android.os.PowerManagerInternal;
53 import android.os.PowerSaveState;
54 import android.os.Process;
55 import android.os.RemoteException;
56 import android.os.ServiceManager;
57 import android.os.SystemClock;
58 import android.os.UserHandle;
59 import android.os.WorkSource;
60 import android.os.connectivity.CellularBatteryStats;
61 import android.os.connectivity.GpsBatteryStats;
62 import android.os.connectivity.WifiActivityEnergyInfo;
63 import android.os.connectivity.WifiBatteryStats;
64 import android.os.health.HealthStatsParceler;
65 import android.os.health.HealthStatsWriter;
66 import android.os.health.UidHealthStats;
67 import android.power.PowerStatsInternal;
68 import android.provider.Settings;
69 import android.telephony.DataConnectionRealTimeInfo;
70 import android.telephony.ModemActivityInfo;
71 import android.telephony.SignalStrength;
72 import android.telephony.TelephonyManager;
73 import android.util.Slog;
74 import android.util.StatsEvent;
75 
76 import com.android.internal.annotations.GuardedBy;
77 import com.android.internal.app.IBatteryStats;
78 import com.android.internal.os.BackgroundThread;
79 import com.android.internal.os.BatteryStatsHelper;
80 import com.android.internal.os.BatteryStatsImpl;
81 import com.android.internal.os.BatteryUsageStatsProvider;
82 import com.android.internal.os.BatteryUsageStatsStore;
83 import com.android.internal.os.BinderCallsStats;
84 import com.android.internal.os.PowerProfile;
85 import com.android.internal.os.RailStats;
86 import com.android.internal.os.RpmStats;
87 import com.android.internal.os.SystemServerCpuThreadReader.SystemServiceCpuThreadTimes;
88 import com.android.internal.util.DumpUtils;
89 import com.android.internal.util.FrameworkStatsLog;
90 import com.android.internal.util.ParseUtils;
91 import com.android.internal.util.function.pooled.PooledLambda;
92 import com.android.net.module.util.NetworkCapabilitiesUtils;
93 import com.android.net.module.util.PermissionUtils;
94 import com.android.server.LocalServices;
95 import com.android.server.Watchdog;
96 import com.android.server.net.BaseNetworkObserver;
97 import com.android.server.pm.UserManagerInternal;
98 
99 import java.io.File;
100 import java.io.FileDescriptor;
101 import java.io.IOException;
102 import java.io.PrintWriter;
103 import java.nio.ByteBuffer;
104 import java.nio.CharBuffer;
105 import java.nio.charset.CharsetDecoder;
106 import java.nio.charset.CodingErrorAction;
107 import java.nio.charset.StandardCharsets;
108 import java.util.Arrays;
109 import java.util.Collection;
110 import java.util.HashMap;
111 import java.util.List;
112 import java.util.Map;
113 import java.util.concurrent.CountDownLatch;
114 import java.util.concurrent.ExecutionException;
115 import java.util.concurrent.Future;
116 import java.util.concurrent.TimeUnit;
117 
118 /**
119  * All information we are collecting about things that can happen that impact
120  * battery life.
121  */
122 public final class BatteryStatsService extends IBatteryStats.Stub
123         implements PowerManagerInternal.LowPowerModeListener,
124         BatteryStatsImpl.PlatformIdleStateCallback,
125         BatteryStatsImpl.MeasuredEnergyRetriever,
126         Watchdog.Monitor {
127     static final String TAG = "BatteryStatsService";
128     static final boolean DBG = false;
129     private static final boolean BATTERY_USAGE_STORE_ENABLED = true;
130 
131     private static IBatteryStats sService;
132 
133     final BatteryStatsImpl mStats;
134     private final BatteryUsageStatsStore mBatteryUsageStatsStore;
135     private final BatteryStatsImpl.UserInfoProvider mUserManagerUserInfoProvider;
136     private final Context mContext;
137     private final BatteryExternalStatsWorker mWorker;
138     private final BatteryUsageStatsProvider mBatteryUsageStatsProvider;
139 
getRailEnergyPowerStats(RailStats railStats)140     private native void getRailEnergyPowerStats(RailStats railStats);
141     private CharsetDecoder mDecoderStat = StandardCharsets.UTF_8
142                     .newDecoder()
143                     .onMalformedInput(CodingErrorAction.REPLACE)
144                     .onUnmappableCharacter(CodingErrorAction.REPLACE)
145                     .replaceWith("?");
146     private static final int MAX_LOW_POWER_STATS_SIZE = 16384;
147     private static final int POWER_STATS_QUERY_TIMEOUT_MILLIS = 2000;
148     private static final String EMPTY = "Empty";
149 
150     private final HandlerThread mHandlerThread;
151     private final Handler mHandler;
152     private final Object mLock = new Object();
153 
154     private final Object mPowerStatsLock = new Object();
155     @GuardedBy("mPowerStatsLock")
156     private PowerStatsInternal mPowerStatsInternal = null;
157     @GuardedBy("mPowerStatsLock")
158     private Map<Integer, String> mEntityNames = new HashMap();
159     @GuardedBy("mPowerStatsLock")
160     private Map<Integer, Map<Integer, String>> mStateNames = new HashMap();
161 
162     @GuardedBy("mStats")
163     private int mLastPowerStateFromRadio = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
164     @GuardedBy("mStats")
165     private int mLastPowerStateFromWifi = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
166     private final INetworkManagementEventObserver mActivityChangeObserver =
167             new BaseNetworkObserver() {
168                 @Override
169                 public void interfaceClassDataActivityChanged(int transportType, boolean active,
170                         long tsNanos, int uid) {
171                     final int powerState = active
172                             ? DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH
173                             : DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
174                     final long timestampNanos;
175                     if (tsNanos <= 0) {
176                         timestampNanos = SystemClock.elapsedRealtimeNanos();
177                     } else {
178                         timestampNanos = tsNanos;
179                     }
180 
181                     switch (transportType) {
182                         case NetworkCapabilities.TRANSPORT_CELLULAR:
183                             noteMobileRadioPowerState(powerState, timestampNanos, uid);
184                             break;
185                         case NetworkCapabilities.TRANSPORT_WIFI:
186                             noteWifiRadioPowerState(powerState, timestampNanos, uid);
187                             break;
188                         default:
189                             Slog.d(TAG, "Received unexpected transport in "
190                                     + "interfaceClassDataActivityChanged unexpected type: "
191                                     + transportType);
192                     }
193                 }
194             };
195 
196     private BatteryManagerInternal mBatteryManagerInternal;
197 
populatePowerEntityMaps()198     private void populatePowerEntityMaps() {
199         PowerEntity[] entities = mPowerStatsInternal.getPowerEntityInfo();
200         if (entities == null) {
201             return;
202         }
203 
204         for (int i = 0; i < entities.length; i++) {
205             final PowerEntity entity = entities[i];
206             Map<Integer, String> states = new HashMap();
207             for (int j = 0; j < entity.states.length; j++) {
208                 final State state = entity.states[j];
209                 states.put(state.id, state.name);
210             }
211 
212             mEntityNames.put(entity.id, entity.name);
213             mStateNames.put(entity.id, states);
214         }
215     }
216 
217     /**
218      * Replaces the information in the given rpmStats with up-to-date information.
219      */
220     @Override
fillLowPowerStats(RpmStats rpmStats)221     public void fillLowPowerStats(RpmStats rpmStats) {
222         synchronized (mPowerStatsLock) {
223             if (mPowerStatsInternal == null || mEntityNames.isEmpty() || mStateNames.isEmpty()) {
224                 return;
225             }
226         }
227 
228         final StateResidencyResult[] results;
229         try {
230             results = mPowerStatsInternal.getStateResidencyAsync(new int[0])
231                     .get(POWER_STATS_QUERY_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
232         } catch (Exception e) {
233             Slog.e(TAG, "Failed to getStateResidencyAsync", e);
234             return;
235         }
236 
237         if (results == null) return;
238 
239         for (int i = 0; i < results.length; i++) {
240             final StateResidencyResult result = results[i];
241             RpmStats.PowerStateSubsystem subsystem =
242                     rpmStats.getSubsystem(mEntityNames.get(result.id));
243 
244             for (int j = 0; j < result.stateResidencyData.length; j++) {
245                 final StateResidency stateResidency = result.stateResidencyData[j];
246                 subsystem.putState(mStateNames.get(result.id).get(stateResidency.id),
247                         stateResidency.totalTimeInStateMs,
248                         (int) stateResidency.totalStateEntryCount);
249             }
250         }
251     }
252 
253     @Override
fillRailDataStats(RailStats railStats)254     public void fillRailDataStats(RailStats railStats) {
255         if (DBG) Slog.d(TAG, "begin getRailEnergyPowerStats");
256         try {
257             getRailEnergyPowerStats(railStats);
258         } finally {
259             if (DBG) Slog.d(TAG, "end getRailEnergyPowerStats");
260         }
261     }
262 
263     @Override
getSubsystemLowPowerStats()264     public String getSubsystemLowPowerStats() {
265         synchronized (mPowerStatsLock) {
266             if (mPowerStatsInternal == null || mEntityNames.isEmpty() || mStateNames.isEmpty()) {
267                 return EMPTY;
268             }
269         }
270 
271         final StateResidencyResult[] results;
272         try {
273             results = mPowerStatsInternal.getStateResidencyAsync(new int[0])
274                     .get(POWER_STATS_QUERY_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
275         } catch (Exception e) {
276             Slog.e(TAG, "Failed to getStateResidencyAsync", e);
277             return EMPTY;
278         }
279 
280         if (results == null || results.length == 0) return EMPTY;
281 
282         int charsLeft = MAX_LOW_POWER_STATS_SIZE;
283         StringBuilder builder = new StringBuilder("SubsystemPowerState");
284         for (int i = 0; i < results.length; i++) {
285             final StateResidencyResult result = results[i];
286             StringBuilder subsystemBuilder = new StringBuilder();
287             subsystemBuilder.append(" subsystem_" + i);
288             subsystemBuilder.append(" name=" + mEntityNames.get(result.id));
289 
290             for (int j = 0; j < result.stateResidencyData.length; j++) {
291                 final StateResidency stateResidency = result.stateResidencyData[j];
292                 subsystemBuilder.append(" state_" + j);
293                 subsystemBuilder.append(" name=" + mStateNames.get(result.id).get(
294                         stateResidency.id));
295                 subsystemBuilder.append(" time=" + stateResidency.totalTimeInStateMs);
296                 subsystemBuilder.append(" count=" + stateResidency.totalStateEntryCount);
297                 subsystemBuilder.append(" last entry=" + stateResidency.lastEntryTimestampMs);
298             }
299 
300             if (subsystemBuilder.length() <= charsLeft) {
301                 charsLeft -= subsystemBuilder.length();
302                 builder.append(subsystemBuilder);
303             } else {
304                 Slog.e(TAG, "getSubsystemLowPowerStats: buffer not enough");
305                 break;
306             }
307         }
308 
309         return builder.toString();
310     }
311 
312     private ConnectivityManager.NetworkCallback mNetworkCallback =
313             new ConnectivityManager.NetworkCallback() {
314         @Override
315         public void onCapabilitiesChanged(@NonNull Network network,
316                 @NonNull NetworkCapabilities networkCapabilities) {
317             final String state = networkCapabilities.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)
318                     ? "CONNECTED" : "SUSPENDED";
319             noteConnectivityChanged(NetworkCapabilitiesUtils.getDisplayTransport(
320                     networkCapabilities.getTransportTypes()), state);
321         }
322 
323         @Override
324         public void onLost(Network network) {
325             noteConnectivityChanged(-1, "DISCONNECTED");
326         }
327     };
328 
BatteryStatsService(Context context, File systemDir, Handler handler)329     BatteryStatsService(Context context, File systemDir, Handler handler) {
330         // BatteryStatsImpl expects the ActivityManagerService handler, so pass that one through.
331         mContext = context;
332         mUserManagerUserInfoProvider = new BatteryStatsImpl.UserInfoProvider() {
333             private UserManagerInternal umi;
334             @Override
335             public int[] getUserIds() {
336                 if (umi == null) {
337                     umi = LocalServices.getService(UserManagerInternal.class);
338                 }
339                 return (umi != null) ? umi.getUserIds() : null;
340             }
341         };
342         mHandlerThread = new HandlerThread("batterystats-handler");
343         mHandlerThread.start();
344         mHandler = new Handler(mHandlerThread.getLooper());
345 
346         mStats = new BatteryStatsImpl(systemDir, handler, this,
347                 this, mUserManagerUserInfoProvider);
348         mWorker = new BatteryExternalStatsWorker(context, mStats);
349         mStats.setExternalStatsSyncLocked(mWorker);
350         mStats.setRadioScanningTimeoutLocked(mContext.getResources().getInteger(
351                 com.android.internal.R.integer.config_radioScanningTimeout) * 1000L);
352         mStats.setPowerProfileLocked(new PowerProfile(context));
353         mStats.startTrackingSystemServerCpuTime();
354 
355         if (BATTERY_USAGE_STORE_ENABLED) {
356             mBatteryUsageStatsStore =
357                     new BatteryUsageStatsStore(context, mStats, systemDir, mHandler);
358         } else {
359             mBatteryUsageStatsStore = null;
360         }
361         mBatteryUsageStatsProvider = new BatteryUsageStatsProvider(context, mStats,
362                 mBatteryUsageStatsStore);
363     }
364 
publish()365     public void publish() {
366         LocalServices.addService(BatteryStatsInternal.class, new LocalService());
367         ServiceManager.addService(BatteryStats.SERVICE_NAME, asBinder());
368     }
369 
systemServicesReady()370     public void systemServicesReady() {
371         mStats.systemServicesReady(mContext);
372         mWorker.systemServicesReady();
373         final INetworkManagementService nms = INetworkManagementService.Stub.asInterface(
374                 ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE));
375         final ConnectivityManager cm = mContext.getSystemService(ConnectivityManager.class);
376         try {
377             nms.registerObserver(mActivityChangeObserver);
378             cm.registerDefaultNetworkCallback(mNetworkCallback);
379         } catch (RemoteException e) {
380             Slog.e(TAG, "Could not register INetworkManagement event observer " + e);
381         }
382 
383         synchronized (mPowerStatsLock) {
384             mPowerStatsInternal = LocalServices.getService(PowerStatsInternal.class);
385             if (mPowerStatsInternal != null) {
386                 populatePowerEntityMaps();
387             } else {
388                 Slog.e(TAG, "Could not register PowerStatsInternal");
389             }
390         }
391         mBatteryManagerInternal = LocalServices.getService(BatteryManagerInternal.class);
392 
393         Watchdog.getInstance().addMonitor(this);
394 
395         final DataConnectionStats dataConnectionStats = new DataConnectionStats(mContext, mHandler);
396         dataConnectionStats.startMonitoring();
397 
398         registerStatsCallbacks();
399     }
400 
401     /**
402      * Notifies BatteryStatsService that the system server is ready.
403      */
onSystemReady()404     public void onSystemReady() {
405         mStats.onSystemReady();
406         if (BATTERY_USAGE_STORE_ENABLED) {
407             mBatteryUsageStatsStore.onSystemReady();
408         }
409     }
410 
411     private final class LocalService extends BatteryStatsInternal {
412         @Override
getWifiIfaces()413         public String[] getWifiIfaces() {
414             return mStats.getWifiIfaces().clone();
415         }
416 
417         @Override
getMobileIfaces()418         public String[] getMobileIfaces() {
419             return mStats.getMobileIfaces().clone();
420         }
421 
422         @Override
getSystemServiceCpuThreadTimes()423         public SystemServiceCpuThreadTimes getSystemServiceCpuThreadTimes() {
424             return mStats.getSystemServiceCpuThreadTimes();
425         }
426 
427         @Override
noteJobsDeferred(int uid, int numDeferred, long sinceLast)428         public void noteJobsDeferred(int uid, int numDeferred, long sinceLast) {
429             if (DBG) Slog.d(TAG, "Jobs deferred " + uid + ": " + numDeferred + " " + sinceLast);
430             BatteryStatsService.this.noteJobsDeferred(uid, numDeferred, sinceLast);
431         }
432 
433         @Override
noteBinderCallStats(int workSourceUid, long incrementatCallCount, Collection<BinderCallsStats.CallStat> callStats)434         public void noteBinderCallStats(int workSourceUid, long incrementatCallCount,
435                 Collection<BinderCallsStats.CallStat> callStats) {
436             synchronized (BatteryStatsService.this.mLock) {
437                 mHandler.sendMessage(PooledLambda.obtainMessage(
438                         mStats::noteBinderCallStats, workSourceUid, incrementatCallCount, callStats,
439                         SystemClock.elapsedRealtime(), SystemClock.uptimeMillis()));
440             }
441         }
442 
443         @Override
noteBinderThreadNativeIds(int[] binderThreadNativeTids)444         public void noteBinderThreadNativeIds(int[] binderThreadNativeTids) {
445             synchronized (BatteryStatsService.this.mLock) {
446                 mStats.noteBinderThreadNativeIds(binderThreadNativeTids);
447             }
448         }
449     }
450 
451     @Override
monitor()452     public void monitor() {
453         synchronized (mLock) {
454         }
455         synchronized (mStats) {
456         }
457     }
458 
awaitUninterruptibly(Future<?> future)459     private static void awaitUninterruptibly(Future<?> future) {
460         while (true) {
461             try {
462                 future.get();
463                 return;
464             } catch (ExecutionException e) {
465                 return;
466             } catch (InterruptedException e) {
467                 // Keep looping
468             }
469         }
470     }
471 
syncStats(String reason, int flags)472     private void syncStats(String reason, int flags) {
473         awaitUninterruptibly(mWorker.scheduleSync(reason, flags));
474     }
475 
awaitCompletion()476     private void awaitCompletion() {
477         final CountDownLatch latch = new CountDownLatch(1);
478         mHandler.post(() -> {
479             latch.countDown();
480         });
481         try {
482             latch.await();
483         } catch (InterruptedException e) {
484         }
485     }
486 
487     /**
488      * At the time when the constructor runs, the power manager has not yet been
489      * initialized.  So we initialize the low power observer later.
490      */
initPowerManagement()491     public void initPowerManagement() {
492         final PowerManagerInternal powerMgr = LocalServices.getService(PowerManagerInternal.class);
493         powerMgr.registerLowPowerModeObserver(this);
494         synchronized (mStats) {
495             mStats.notePowerSaveModeLocked(
496                     powerMgr.getLowPowerState(ServiceType.BATTERY_STATS).batterySaverEnabled,
497                     SystemClock.elapsedRealtime(), SystemClock.uptimeMillis(), true);
498         }
499         (new WakeupReasonThread()).start();
500     }
501 
shutdown()502     public void shutdown() {
503         Slog.w("BatteryStats", "Writing battery stats before shutdown...");
504 
505         // Drain the handler queue to make sure we've handled all pending works.
506         awaitCompletion();
507 
508         syncStats("shutdown", BatteryExternalStatsWorker.UPDATE_ALL);
509 
510         synchronized (mStats) {
511             mStats.shutdownLocked();
512         }
513 
514         // Shutdown the thread we made.
515         mWorker.shutdown();
516     }
517 
getService()518     public static IBatteryStats getService() {
519         if (sService != null) {
520             return sService;
521         }
522         IBinder b = ServiceManager.getService(BatteryStats.SERVICE_NAME);
523         sService = asInterface(b);
524         return sService;
525     }
526 
527     @Override
getServiceType()528     public int getServiceType() {
529         return ServiceType.BATTERY_STATS;
530     }
531 
532     @Override
onLowPowerModeChanged(final PowerSaveState result)533     public void onLowPowerModeChanged(final PowerSaveState result) {
534         synchronized (mLock) {
535             final long elapsedRealtime = SystemClock.elapsedRealtime();
536             final long uptime = SystemClock.uptimeMillis();
537             mHandler.post(() -> {
538                 synchronized (mStats) {
539                     mStats.notePowerSaveModeLocked(result.batterySaverEnabled,
540                             elapsedRealtime, uptime, false);
541                 }
542             });
543         }
544     }
545 
546     /**
547      * @return the current statistics object, which may be modified
548      * to reflect events that affect battery usage.  You must lock the
549      * stats object before doing anything with it.
550      */
getActiveStatistics()551     public BatteryStatsImpl getActiveStatistics() {
552         return mStats;
553     }
554 
555     /**
556      * Schedules a write to disk to occur. This will cause the BatteryStatsImpl
557      * object to update with the latest info, then write to disk.
558      */
scheduleWriteToDisk()559     public void scheduleWriteToDisk() {
560         synchronized (mLock) {
561             // We still schedule it on the handler so we'll have all existing pending works done.
562             mHandler.post(() -> {
563                 mWorker.scheduleWrite();
564             });
565         }
566     }
567 
568     // These are for direct use by the activity manager...
569 
570     /**
571      * Remove a UID from the BatteryStats and BatteryStats' external dependencies.
572      */
removeUid(final int uid)573     void removeUid(final int uid) {
574         synchronized (mLock) {
575             final long elapsedRealtime = SystemClock.elapsedRealtime();
576             mHandler.post(() -> {
577                 synchronized (mStats) {
578                     mStats.removeUidStatsLocked(uid, elapsedRealtime);
579                 }
580             });
581         }
582     }
583 
onCleanupUser(final int userId)584     void onCleanupUser(final int userId) {
585         synchronized (mLock) {
586             final long elapsedRealtime = SystemClock.elapsedRealtime();
587             mHandler.post(() -> {
588                 synchronized (mStats) {
589                     mStats.onCleanupUserLocked(userId, elapsedRealtime);
590                 }
591             });
592         }
593     }
594 
onUserRemoved(final int userId)595     void onUserRemoved(final int userId) {
596         synchronized (mLock) {
597             mHandler.post(() -> {
598                 synchronized (mStats) {
599                     mStats.onUserRemovedLocked(userId);
600                 }
601             });
602         }
603     }
604 
addIsolatedUid(final int isolatedUid, final int appUid)605     void addIsolatedUid(final int isolatedUid, final int appUid) {
606         synchronized (mLock) {
607             final long elapsedRealtime = SystemClock.elapsedRealtime();
608             final long uptime = SystemClock.uptimeMillis();
609             mHandler.post(() -> {
610                 synchronized (mStats) {
611                     mStats.addIsolatedUidLocked(isolatedUid, appUid, elapsedRealtime, uptime);
612                 }
613             });
614         }
615     }
616 
removeIsolatedUid(final int isolatedUid, final int appUid)617     void removeIsolatedUid(final int isolatedUid, final int appUid) {
618         synchronized (mLock) {
619             mHandler.post(() -> {
620                 synchronized (mStats) {
621                     mStats.scheduleRemoveIsolatedUidLocked(isolatedUid, appUid);
622                 }
623             });
624         }
625     }
626 
noteProcessStart(final String name, final int uid)627     void noteProcessStart(final String name, final int uid) {
628         synchronized (mLock) {
629             final long elapsedRealtime = SystemClock.elapsedRealtime();
630             final long uptime = SystemClock.uptimeMillis();
631             mHandler.post(() -> {
632                 synchronized (mStats) {
633                     mStats.noteProcessStartLocked(name, uid, elapsedRealtime, uptime);
634                 }
635             });
636         }
637         FrameworkStatsLog.write(FrameworkStatsLog.PROCESS_LIFE_CYCLE_STATE_CHANGED, uid, name,
638                 FrameworkStatsLog.PROCESS_LIFE_CYCLE_STATE_CHANGED__STATE__STARTED);
639     }
640 
noteProcessCrash(String name, int uid)641     void noteProcessCrash(String name, int uid) {
642         synchronized (mLock) {
643             final long elapsedRealtime = SystemClock.elapsedRealtime();
644             final long uptime = SystemClock.uptimeMillis();
645             mHandler.post(() -> {
646                 synchronized (mStats) {
647                     mStats.noteProcessCrashLocked(name, uid, elapsedRealtime, uptime);
648                 }
649             });
650         }
651         FrameworkStatsLog.write(FrameworkStatsLog.PROCESS_LIFE_CYCLE_STATE_CHANGED, uid, name,
652                 FrameworkStatsLog.PROCESS_LIFE_CYCLE_STATE_CHANGED__STATE__CRASHED);
653     }
654 
noteProcessAnr(String name, int uid)655     void noteProcessAnr(String name, int uid) {
656         synchronized (mLock) {
657             final long elapsedRealtime = SystemClock.elapsedRealtime();
658             final long uptime = SystemClock.uptimeMillis();
659             mHandler.post(() -> {
660                 synchronized (mStats) {
661                     mStats.noteProcessAnrLocked(name, uid, elapsedRealtime, uptime);
662                 }
663             });
664         }
665     }
666 
noteProcessFinish(String name, int uid)667     void noteProcessFinish(String name, int uid) {
668         synchronized (mLock) {
669             final long elapsedRealtime = SystemClock.elapsedRealtime();
670             final long uptime = SystemClock.uptimeMillis();
671             mHandler.post(() -> {
672                 synchronized (mStats) {
673                     mStats.noteProcessFinishLocked(name, uid, elapsedRealtime, uptime);
674                 }
675             });
676         }
677         FrameworkStatsLog.write(FrameworkStatsLog.PROCESS_LIFE_CYCLE_STATE_CHANGED, uid, name,
678                 FrameworkStatsLog.PROCESS_LIFE_CYCLE_STATE_CHANGED__STATE__FINISHED);
679     }
680 
681     /** @param state Process state from ActivityManager.java. */
noteUidProcessState(int uid, int state)682     void noteUidProcessState(int uid, int state) {
683         synchronized (mLock) {
684             final long elapsedRealtime = SystemClock.elapsedRealtime();
685             final long uptime = SystemClock.uptimeMillis();
686             mHandler.post(() -> {
687                 synchronized (mStats) {
688                     mStats.noteUidProcessStateLocked(uid, state, elapsedRealtime, uptime);
689                 }
690             });
691         }
692     }
693 
694     // Public interface...
695 
696     /**
697      * Returns BatteryUsageStats, which contains power attribution data on a per-subsystem
698      * and per-UID basis.
699      */
getBatteryUsageStats(List<BatteryUsageStatsQuery> queries)700     public List<BatteryUsageStats> getBatteryUsageStats(List<BatteryUsageStatsQuery> queries) {
701         mContext.enforceCallingOrSelfPermission(
702                 android.Manifest.permission.BATTERY_STATS, null);
703         awaitCompletion();
704 
705         if (mBatteryUsageStatsProvider.shouldUpdateStats(queries,
706                 mWorker.getLastCollectionTimeStamp())) {
707             syncStats("get-stats", BatteryExternalStatsWorker.UPDATE_ALL);
708         }
709 
710         return mBatteryUsageStatsProvider.getBatteryUsageStats(queries);
711     }
712 
getStatistics()713     public byte[] getStatistics() {
714         mContext.enforceCallingPermission(
715                 android.Manifest.permission.BATTERY_STATS, null);
716         //Slog.i("foo", "SENDING BATTERY INFO:");
717         //mStats.dumpLocked(new LogPrinter(Log.INFO, "foo", Log.LOG_ID_SYSTEM));
718         Parcel out = Parcel.obtain();
719         // Drain the handler queue to make sure we've handled all pending works, so we'll get
720         // an accurate stats.
721         awaitCompletion();
722         syncStats("get-stats", BatteryExternalStatsWorker.UPDATE_ALL);
723         synchronized (mStats) {
724             mStats.writeToParcel(out, 0);
725         }
726         byte[] data = out.marshall();
727         out.recycle();
728         return data;
729     }
730 
731     /**
732      * Returns parceled BatteryStats as a MemoryFile.
733      *
734      * @param forceUpdate If true, runs a sync to get fresh battery stats. Otherwise,
735      *                  returns the current values.
736      */
getStatisticsStream(boolean forceUpdate)737     public ParcelFileDescriptor getStatisticsStream(boolean forceUpdate) {
738         mContext.enforceCallingOrSelfPermission(
739                 android.Manifest.permission.BATTERY_STATS, null);
740         //Slog.i("foo", "SENDING BATTERY INFO:");
741         //mStats.dumpLocked(new LogPrinter(Log.INFO, "foo", Log.LOG_ID_SYSTEM));
742         Parcel out = Parcel.obtain();
743         if (forceUpdate) {
744             // Drain the handler queue to make sure we've handled all pending works, so we'll get
745             // an accurate stats.
746             awaitCompletion();
747             syncStats("get-stats", BatteryExternalStatsWorker.UPDATE_ALL);
748         }
749         synchronized (mStats) {
750             mStats.writeToParcel(out, 0);
751         }
752         byte[] data = out.marshall();
753         if (DBG) Slog.d(TAG, "getStatisticsStream parcel size is:" + data.length);
754         out.recycle();
755         try {
756             return ParcelFileDescriptor.fromData(data, "battery-stats");
757         } catch (IOException e) {
758             Slog.w(TAG, "Unable to create shared memory", e);
759             return null;
760         }
761     }
762 
763     /** Register callbacks for statsd pulled atoms. */
registerStatsCallbacks()764     private void registerStatsCallbacks() {
765         final StatsManager statsManager = mContext.getSystemService(StatsManager.class);
766         final StatsPullAtomCallbackImpl pullAtomCallback = new StatsPullAtomCallbackImpl();
767 
768         statsManager.setPullAtomCallback(
769                 FrameworkStatsLog.BATTERY_USAGE_STATS_SINCE_RESET,
770                 null, // use default PullAtomMetadata values
771                 BackgroundThread.getExecutor(), pullAtomCallback);
772         statsManager.setPullAtomCallback(
773                 FrameworkStatsLog.BATTERY_USAGE_STATS_SINCE_RESET_USING_POWER_PROFILE_MODEL,
774                 null, // use default PullAtomMetadata values
775                 BackgroundThread.getExecutor(), pullAtomCallback);
776         statsManager.setPullAtomCallback(
777                 FrameworkStatsLog.BATTERY_USAGE_STATS_BEFORE_RESET,
778                 null, // use default PullAtomMetadata values
779                 BackgroundThread.getExecutor(), pullAtomCallback);
780     }
781 
782     /** StatsPullAtomCallback for pulling BatteryUsageStats data. */
783     private class StatsPullAtomCallbackImpl implements StatsManager.StatsPullAtomCallback {
784         @Override
onPullAtom(int atomTag, List<StatsEvent> data)785         public int onPullAtom(int atomTag, List<StatsEvent> data) {
786             final BatteryUsageStats bus;
787             switch (atomTag) {
788                 case FrameworkStatsLog.BATTERY_USAGE_STATS_SINCE_RESET:
789                     bus = getBatteryUsageStats(List.of(BatteryUsageStatsQuery.DEFAULT)).get(0);
790                     break;
791                 case FrameworkStatsLog.BATTERY_USAGE_STATS_SINCE_RESET_USING_POWER_PROFILE_MODEL:
792                     final BatteryUsageStatsQuery powerProfileQuery =
793                             new BatteryUsageStatsQuery.Builder().powerProfileModeledOnly().build();
794                     bus = getBatteryUsageStats(List.of(powerProfileQuery)).get(0);
795                     break;
796                 case FrameworkStatsLog.BATTERY_USAGE_STATS_BEFORE_RESET:
797                     if (!BATTERY_USAGE_STORE_ENABLED) {
798                         return StatsManager.PULL_SKIP;
799                     }
800 
801                     final long sessionStart = mBatteryUsageStatsStore
802                             .getLastBatteryUsageStatsBeforeResetAtomPullTimestamp();
803                     final long sessionEnd = mStats.getStartClockTime();
804                     final BatteryUsageStatsQuery query = new BatteryUsageStatsQuery.Builder()
805                             .aggregateSnapshots(sessionStart, sessionEnd)
806                             .build();
807                     bus = getBatteryUsageStats(List.of(query)).get(0);
808                     mBatteryUsageStatsStore
809                             .setLastBatteryUsageStatsBeforeResetAtomPullTimestamp(sessionEnd);
810                     break;
811                 default:
812                     throw new UnsupportedOperationException("Unknown tagId=" + atomTag);
813             }
814             final byte[] statsProto = bus.getStatsProto();
815 
816             data.add(FrameworkStatsLog.buildStatsEvent(atomTag, statsProto));
817 
818             return StatsManager.PULL_SUCCESS;
819         }
820     }
821 
isCharging()822     public boolean isCharging() {
823         synchronized (mStats) {
824             return mStats.isCharging();
825         }
826     }
827 
computeBatteryTimeRemaining()828     public long computeBatteryTimeRemaining() {
829         synchronized (mStats) {
830             long time = mStats.computeBatteryTimeRemaining(SystemClock.elapsedRealtime());
831             return time >= 0 ? (time/1000) : time;
832         }
833     }
834 
computeChargeTimeRemaining()835     public long computeChargeTimeRemaining() {
836         synchronized (mStats) {
837             long time = mStats.computeChargeTimeRemaining(SystemClock.elapsedRealtime());
838             return time >= 0 ? (time/1000) : time;
839         }
840     }
841 
noteEvent(final int code, final String name, final int uid)842     public void noteEvent(final int code, final String name, final int uid) {
843         enforceCallingPermission();
844         if (name == null) {
845             // TODO(b/194733136): Replace with an IllegalArgumentException throw.
846             Slog.wtfStack(TAG, "noteEvent called with null name. code = " + code);
847             return;
848         }
849 
850         synchronized (mLock) {
851             final long elapsedRealtime = SystemClock.elapsedRealtime();
852             final long uptime = SystemClock.uptimeMillis();
853             mHandler.post(() -> {
854                 synchronized (mStats) {
855                     mStats.noteEventLocked(code, name, uid, elapsedRealtime, uptime);
856                 }
857             });
858         }
859     }
860 
noteSyncStart(final String name, final int uid)861     public void noteSyncStart(final String name, final int uid) {
862         enforceCallingPermission();
863         synchronized (mLock) {
864             final long elapsedRealtime = SystemClock.elapsedRealtime();
865             final long uptime = SystemClock.uptimeMillis();
866             mHandler.post(() -> {
867                 synchronized (mStats) {
868                     mStats.noteSyncStartLocked(name, uid, elapsedRealtime, uptime);
869                 }
870             });
871         }
872         FrameworkStatsLog.write_non_chained(FrameworkStatsLog.SYNC_STATE_CHANGED, uid, null,
873                 name, FrameworkStatsLog.SYNC_STATE_CHANGED__STATE__ON);
874     }
875 
noteSyncFinish(final String name, final int uid)876     public void noteSyncFinish(final String name, final int uid) {
877         enforceCallingPermission();
878         synchronized (mLock) {
879             final long elapsedRealtime = SystemClock.elapsedRealtime();
880             final long uptime = SystemClock.uptimeMillis();
881             mHandler.post(() -> {
882                 synchronized (mStats) {
883                     mStats.noteSyncFinishLocked(name, uid, elapsedRealtime, uptime);
884                 }
885             });
886         }
887         FrameworkStatsLog.write_non_chained(FrameworkStatsLog.SYNC_STATE_CHANGED, uid, null,
888                 name, FrameworkStatsLog.SYNC_STATE_CHANGED__STATE__OFF);
889     }
890 
891     /** A scheduled job was started. */
noteJobStart(final String name, final int uid)892     public void noteJobStart(final String name, final int uid) {
893         enforceCallingPermission();
894         synchronized (mLock) {
895             final long elapsedRealtime = SystemClock.elapsedRealtime();
896             final long uptime = SystemClock.uptimeMillis();
897             mHandler.post(() -> {
898                 synchronized (mStats) {
899                     mStats.noteJobStartLocked(name, uid, elapsedRealtime, uptime);
900                 }
901             });
902         }
903     }
904 
905     /** A scheduled job was finished. */
noteJobFinish(final String name, final int uid, final int stopReason)906     public void noteJobFinish(final String name, final int uid, final int stopReason) {
907         enforceCallingPermission();
908         synchronized (mLock) {
909             final long elapsedRealtime = SystemClock.elapsedRealtime();
910             final long uptime = SystemClock.uptimeMillis();
911             mHandler.post(() -> {
912                 synchronized (mStats) {
913                     mStats.noteJobFinishLocked(name, uid, stopReason, elapsedRealtime, uptime);
914                 }
915             });
916         }
917     }
918 
noteJobsDeferred(final int uid, final int numDeferred, final long sinceLast)919     void noteJobsDeferred(final int uid, final int numDeferred, final long sinceLast) {
920         // No need to enforce calling permission, as it is called from an internal interface
921         synchronized (mLock) {
922             final long elapsedRealtime = SystemClock.elapsedRealtime();
923             final long uptime = SystemClock.uptimeMillis();
924             mHandler.post(() -> {
925                 synchronized (mStats) {
926                     mStats.noteJobsDeferredLocked(uid, numDeferred, sinceLast,
927                             elapsedRealtime, uptime);
928                 }
929             });
930         }
931     }
932 
noteWakupAlarm(final String name, final int uid, final WorkSource workSource, final String tag)933     public void noteWakupAlarm(final String name, final int uid, final WorkSource workSource,
934             final String tag) {
935         enforceCallingPermission();
936         final WorkSource localWs = workSource != null ? new WorkSource(workSource) : null;
937         synchronized (mLock) {
938             final long elapsedRealtime = SystemClock.elapsedRealtime();
939             final long uptime = SystemClock.uptimeMillis();
940             mHandler.post(() -> {
941                 synchronized (mStats) {
942                     mStats.noteWakupAlarmLocked(name, uid, localWs, tag,
943                             elapsedRealtime, uptime);
944                 }
945             });
946         }
947     }
948 
noteAlarmStart(final String name, final WorkSource workSource, final int uid)949     public void noteAlarmStart(final String name, final WorkSource workSource, final int uid) {
950         enforceCallingPermission();
951         final WorkSource localWs = workSource != null ? new WorkSource(workSource) : null;
952         synchronized (mLock) {
953             final long elapsedRealtime = SystemClock.elapsedRealtime();
954             final long uptime = SystemClock.uptimeMillis();
955             mHandler.post(() -> {
956                 synchronized (mStats) {
957                     mStats.noteAlarmStartLocked(name, localWs, uid, elapsedRealtime, uptime);
958                 }
959             });
960         }
961     }
962 
noteAlarmFinish(final String name, final WorkSource workSource, final int uid)963     public void noteAlarmFinish(final String name, final WorkSource workSource, final int uid) {
964         enforceCallingPermission();
965         final WorkSource localWs = workSource != null ? new WorkSource(workSource) : null;
966         synchronized (mLock) {
967             final long elapsedRealtime = SystemClock.elapsedRealtime();
968             final long uptime = SystemClock.uptimeMillis();
969             mHandler.post(() -> {
970                 synchronized (mStats) {
971                     mStats.noteAlarmFinishLocked(name, localWs, uid, elapsedRealtime, uptime);
972                 }
973             });
974         }
975     }
976 
noteStartWakelock(final int uid, final int pid, final String name, final String historyName, final int type, final boolean unimportantForLogging)977     public void noteStartWakelock(final int uid, final int pid, final String name,
978             final String historyName, final int type, final boolean unimportantForLogging) {
979         enforceCallingPermission();
980         synchronized (mLock) {
981             final long elapsedRealtime = SystemClock.elapsedRealtime();
982             final long uptime = SystemClock.uptimeMillis();
983             mHandler.post(() -> {
984                 synchronized (mStats) {
985                     mStats.noteStartWakeLocked(uid, pid, null, name, historyName, type,
986                             unimportantForLogging, elapsedRealtime, uptime);
987                 }
988             });
989         }
990     }
991 
noteStopWakelock(final int uid, final int pid, final String name, final String historyName, final int type)992     public void noteStopWakelock(final int uid, final int pid, final String name,
993             final String historyName, final int type) {
994         enforceCallingPermission();
995         synchronized (mLock) {
996             final long elapsedRealtime = SystemClock.elapsedRealtime();
997             final long uptime = SystemClock.uptimeMillis();
998             mHandler.post(() -> {
999                 synchronized (mStats) {
1000                     mStats.noteStopWakeLocked(uid, pid, null, name, historyName, type,
1001                             elapsedRealtime, uptime);
1002                 }
1003             });
1004         }
1005     }
1006 
noteStartWakelockFromSource(final WorkSource ws, final int pid, final String name, final String historyName, final int type, final boolean unimportantForLogging)1007     public void noteStartWakelockFromSource(final WorkSource ws, final int pid, final String name,
1008             final String historyName, final int type, final boolean unimportantForLogging) {
1009         enforceCallingPermission();
1010         final WorkSource localWs = ws != null ? new WorkSource(ws) : null;
1011         synchronized (mLock) {
1012             final long elapsedRealtime = SystemClock.elapsedRealtime();
1013             final long uptime = SystemClock.uptimeMillis();
1014             mHandler.post(() -> {
1015                 synchronized (mStats) {
1016                     mStats.noteStartWakeFromSourceLocked(localWs, pid, name, historyName,
1017                             type, unimportantForLogging, elapsedRealtime, uptime);
1018                 }
1019             });
1020         }
1021     }
1022 
noteChangeWakelockFromSource(final WorkSource ws, final int pid, final String name, final String historyName, final int type, final WorkSource newWs, final int newPid, final String newName, final String newHistoryName, final int newType, final boolean newUnimportantForLogging)1023     public void noteChangeWakelockFromSource(final WorkSource ws, final int pid, final String name,
1024             final String historyName, final int type, final WorkSource newWs, final int newPid,
1025             final String newName, final String newHistoryName, final int newType,
1026             final boolean newUnimportantForLogging) {
1027         enforceCallingPermission();
1028         final WorkSource localWs = ws != null ? new WorkSource(ws) : null;
1029         final WorkSource localNewWs = newWs != null ? new WorkSource(newWs) : null;
1030         synchronized (mLock) {
1031             final long elapsedRealtime = SystemClock.elapsedRealtime();
1032             final long uptime = SystemClock.uptimeMillis();
1033             mHandler.post(() -> {
1034                 synchronized (mStats) {
1035                     mStats.noteChangeWakelockFromSourceLocked(localWs, pid, name, historyName, type,
1036                             localNewWs, newPid, newName, newHistoryName, newType,
1037                             newUnimportantForLogging, elapsedRealtime, uptime);
1038                 }
1039             });
1040         }
1041     }
1042 
noteStopWakelockFromSource(final WorkSource ws, final int pid, final String name, final String historyName, final int type)1043     public void noteStopWakelockFromSource(final WorkSource ws, final int pid, final String name,
1044             final String historyName, final int type) {
1045         enforceCallingPermission();
1046         final WorkSource localWs = ws != null ? new WorkSource(ws) : null;
1047         synchronized (mLock) {
1048             final long elapsedRealtime = SystemClock.elapsedRealtime();
1049             final long uptime = SystemClock.uptimeMillis();
1050             mHandler.post(() -> {
1051                 synchronized (mStats) {
1052                     mStats.noteStopWakeFromSourceLocked(localWs, pid, name, historyName, type,
1053                             elapsedRealtime, uptime);
1054                 }
1055             });
1056         }
1057     }
1058 
1059     @Override
noteLongPartialWakelockStart(final String name, final String historyName, final int uid)1060     public void noteLongPartialWakelockStart(final String name, final String historyName,
1061             final int uid) {
1062         enforceCallingPermission();
1063         synchronized (mLock) {
1064             final long elapsedRealtime = SystemClock.elapsedRealtime();
1065             final long uptime = SystemClock.uptimeMillis();
1066             mHandler.post(() -> {
1067                 synchronized (mStats) {
1068                     mStats.noteLongPartialWakelockStart(name, historyName, uid,
1069                             elapsedRealtime, uptime);
1070                 }
1071             });
1072         }
1073     }
1074 
1075     @Override
noteLongPartialWakelockStartFromSource(final String name, final String historyName, final WorkSource workSource)1076     public void noteLongPartialWakelockStartFromSource(final String name, final String historyName,
1077             final WorkSource workSource) {
1078         enforceCallingPermission();
1079         final WorkSource localWs = workSource != null ? new WorkSource(workSource) : null;
1080         synchronized (mLock) {
1081             final long elapsedRealtime = SystemClock.elapsedRealtime();
1082             final long uptime = SystemClock.uptimeMillis();
1083             mHandler.post(() -> {
1084                 synchronized (mStats) {
1085                     mStats.noteLongPartialWakelockStartFromSource(name, historyName, localWs,
1086                             elapsedRealtime, uptime);
1087                 }
1088             });
1089         }
1090     }
1091 
1092     @Override
noteLongPartialWakelockFinish(final String name, final String historyName, final int uid)1093     public void noteLongPartialWakelockFinish(final String name, final String historyName,
1094             final int uid) {
1095         enforceCallingPermission();
1096         synchronized (mLock) {
1097             final long elapsedRealtime = SystemClock.elapsedRealtime();
1098             final long uptime = SystemClock.uptimeMillis();
1099             mHandler.post(() -> {
1100                 synchronized (mStats) {
1101                     mStats.noteLongPartialWakelockFinish(name, historyName, uid,
1102                             elapsedRealtime, uptime);
1103                 }
1104             });
1105         }
1106     }
1107 
1108     @Override
noteLongPartialWakelockFinishFromSource(final String name, final String historyName, final WorkSource workSource)1109     public void noteLongPartialWakelockFinishFromSource(final String name, final String historyName,
1110             final WorkSource workSource) {
1111         enforceCallingPermission();
1112         final WorkSource localWs = workSource != null ? new WorkSource(workSource) : null;
1113         synchronized (mLock) {
1114             final long elapsedRealtime = SystemClock.elapsedRealtime();
1115             final long uptime = SystemClock.uptimeMillis();
1116             mHandler.post(() -> {
1117                 synchronized (mStats) {
1118                     mStats.noteLongPartialWakelockFinishFromSource(name, historyName, localWs,
1119                             elapsedRealtime, uptime);
1120                 }
1121             });
1122         }
1123     }
1124 
noteStartSensor(final int uid, final int sensor)1125     public void noteStartSensor(final int uid, final int sensor) {
1126         enforceCallingPermission();
1127         synchronized (mLock) {
1128             final long elapsedRealtime = SystemClock.elapsedRealtime();
1129             final long uptime = SystemClock.uptimeMillis();
1130             mHandler.post(() -> {
1131                 synchronized (mStats) {
1132                     mStats.noteStartSensorLocked(uid, sensor, elapsedRealtime, uptime);
1133                 }
1134             });
1135         }
1136         FrameworkStatsLog.write_non_chained(FrameworkStatsLog.SENSOR_STATE_CHANGED, uid,
1137                 null, sensor, FrameworkStatsLog.SENSOR_STATE_CHANGED__STATE__ON);
1138     }
1139 
noteStopSensor(final int uid, final int sensor)1140     public void noteStopSensor(final int uid, final int sensor) {
1141         enforceCallingPermission();
1142         synchronized (mLock) {
1143             final long elapsedRealtime = SystemClock.elapsedRealtime();
1144             final long uptime = SystemClock.uptimeMillis();
1145             mHandler.post(() -> {
1146                 synchronized (mStats) {
1147                     mStats.noteStopSensorLocked(uid, sensor, elapsedRealtime, uptime);
1148                 }
1149             });
1150         }
1151         FrameworkStatsLog.write_non_chained(FrameworkStatsLog.SENSOR_STATE_CHANGED, uid,
1152                 null, sensor, FrameworkStatsLog.SENSOR_STATE_CHANGED__STATE__OFF);
1153     }
1154 
noteVibratorOn(final int uid, final long durationMillis)1155     public void noteVibratorOn(final int uid, final long durationMillis) {
1156         enforceCallingPermission();
1157         synchronized (mLock) {
1158             final long elapsedRealtime = SystemClock.elapsedRealtime();
1159             final long uptime = SystemClock.uptimeMillis();
1160             mHandler.post(() -> {
1161                 synchronized (mStats) {
1162                     mStats.noteVibratorOnLocked(uid, durationMillis, elapsedRealtime, uptime);
1163                 }
1164             });
1165         }
1166     }
1167 
noteVibratorOff(final int uid)1168     public void noteVibratorOff(final int uid) {
1169         enforceCallingPermission();
1170         synchronized (mLock) {
1171             final long elapsedRealtime = SystemClock.elapsedRealtime();
1172             final long uptime = SystemClock.uptimeMillis();
1173             mHandler.post(() -> {
1174                 synchronized (mStats) {
1175                     mStats.noteVibratorOffLocked(uid, elapsedRealtime, uptime);
1176                 }
1177             });
1178         }
1179     }
1180 
1181     @Override
noteGpsChanged(final WorkSource oldWs, final WorkSource newWs)1182     public void noteGpsChanged(final WorkSource oldWs, final WorkSource newWs) {
1183         enforceCallingPermission();
1184         final WorkSource localOldWs = oldWs != null ? new WorkSource(oldWs) : null;
1185         final WorkSource localNewWs = newWs != null ? new WorkSource(newWs) : null;
1186         synchronized (mLock) {
1187             final long elapsedRealtime = SystemClock.elapsedRealtime();
1188             final long uptime = SystemClock.uptimeMillis();
1189             mHandler.post(() -> {
1190                 synchronized (mStats) {
1191                     mStats.noteGpsChangedLocked(localOldWs, localNewWs, elapsedRealtime, uptime);
1192                 }
1193             });
1194         }
1195     }
1196 
noteGpsSignalQuality(final int signalLevel)1197     public void noteGpsSignalQuality(final int signalLevel) {
1198         synchronized (mLock) {
1199             final long elapsedRealtime = SystemClock.elapsedRealtime();
1200             final long uptime = SystemClock.uptimeMillis();
1201             mHandler.post(() -> {
1202                 synchronized (mStats) {
1203                     mStats.noteGpsSignalQualityLocked(signalLevel, elapsedRealtime, uptime);
1204                 }
1205             });
1206         }
1207     }
1208 
noteScreenState(final int state)1209     public void noteScreenState(final int state) {
1210         enforceCallingPermission();
1211         synchronized (mLock) {
1212             final long elapsedRealtime = SystemClock.elapsedRealtime();
1213             final long uptime = SystemClock.uptimeMillis();
1214             final long currentTime = System.currentTimeMillis();
1215             mHandler.post(() -> {
1216                 if (DBG) Slog.d(TAG, "begin noteScreenState");
1217                 synchronized (mStats) {
1218                     mStats.noteScreenStateLocked(state, elapsedRealtime, uptime, currentTime);
1219                 }
1220                 if (DBG) Slog.d(TAG, "end noteScreenState");
1221             });
1222         }
1223         FrameworkStatsLog.write(FrameworkStatsLog.SCREEN_STATE_CHANGED, state);
1224     }
1225 
noteScreenBrightness(final int brightness)1226     public void noteScreenBrightness(final int brightness) {
1227         enforceCallingPermission();
1228         synchronized (mLock) {
1229             final long elapsedRealtime = SystemClock.elapsedRealtime();
1230             final long uptime = SystemClock.uptimeMillis();
1231             mHandler.post(() -> {
1232                 synchronized (mStats) {
1233                     mStats.noteScreenBrightnessLocked(brightness, elapsedRealtime, uptime);
1234                 }
1235             });
1236         }
1237         FrameworkStatsLog.write(FrameworkStatsLog.SCREEN_BRIGHTNESS_CHANGED, brightness);
1238     }
1239 
noteUserActivity(final int uid, final int event)1240     public void noteUserActivity(final int uid, final int event) {
1241         enforceCallingPermission();
1242         synchronized (mLock) {
1243             final long elapsedRealtime = SystemClock.elapsedRealtime();
1244             final long uptime = SystemClock.uptimeMillis();
1245             mHandler.post(() -> {
1246                 synchronized (mStats) {
1247                     mStats.noteUserActivityLocked(uid, event, elapsedRealtime, uptime);
1248                 }
1249             });
1250         }
1251     }
1252 
noteWakeUp(final String reason, final int reasonUid)1253     public void noteWakeUp(final String reason, final int reasonUid) {
1254         enforceCallingPermission();
1255         synchronized (mLock) {
1256             final long elapsedRealtime = SystemClock.elapsedRealtime();
1257             final long uptime = SystemClock.uptimeMillis();
1258             mHandler.post(() -> {
1259                 synchronized (mStats) {
1260                     mStats.noteWakeUpLocked(reason, reasonUid, elapsedRealtime, uptime);
1261                 }
1262             });
1263         }
1264     }
1265 
noteInteractive(final boolean interactive)1266     public void noteInteractive(final boolean interactive) {
1267         enforceCallingPermission();
1268         synchronized (mLock) {
1269             final long elapsedRealtime = SystemClock.elapsedRealtime();
1270             mHandler.post(() -> {
1271                 synchronized (mStats) {
1272                     mStats.noteInteractiveLocked(interactive, elapsedRealtime);
1273                 }
1274             });
1275         }
1276     }
1277 
noteConnectivityChanged(final int type, final String extra)1278     public void noteConnectivityChanged(final int type, final String extra) {
1279         enforceCallingPermission();
1280         synchronized (mLock) {
1281             final long elapsedRealtime = SystemClock.elapsedRealtime();
1282             final long uptime = SystemClock.uptimeMillis();
1283             mHandler.post(() -> {
1284                 synchronized (mStats) {
1285                     mStats.noteConnectivityChangedLocked(type, extra, elapsedRealtime, uptime);
1286                 }
1287             });
1288         }
1289     }
1290 
noteMobileRadioPowerState(final int powerState, final long timestampNs, final int uid)1291     public void noteMobileRadioPowerState(final int powerState, final long timestampNs,
1292             final int uid) {
1293         enforceCallingPermission();
1294         synchronized (mLock) {
1295             final long elapsedRealtime = SystemClock.elapsedRealtime();
1296             final long uptime = SystemClock.uptimeMillis();
1297             mHandler.post(() -> {
1298                 final boolean update;
1299                 synchronized (mStats) {
1300                     // Ignore if no power state change.
1301                     if (mLastPowerStateFromRadio == powerState) return;
1302 
1303                     mLastPowerStateFromRadio = powerState;
1304                     update = mStats.noteMobileRadioPowerStateLocked(powerState, timestampNs, uid,
1305                             elapsedRealtime, uptime);
1306                 }
1307 
1308                 if (update) {
1309                     mWorker.scheduleSync("modem-data", BatteryExternalStatsWorker.UPDATE_RADIO);
1310                 }
1311             });
1312         }
1313         FrameworkStatsLog.write_non_chained(
1314                 FrameworkStatsLog.MOBILE_RADIO_POWER_STATE_CHANGED, uid, null, powerState);
1315     }
1316 
notePhoneOn()1317     public void notePhoneOn() {
1318         enforceCallingPermission();
1319         synchronized (mLock) {
1320             final long elapsedRealtime = SystemClock.elapsedRealtime();
1321             final long uptime = SystemClock.uptimeMillis();
1322             mHandler.post(() -> {
1323                 synchronized (mStats) {
1324                     mStats.notePhoneOnLocked(elapsedRealtime, uptime);
1325                 }
1326             });
1327         }
1328     }
1329 
notePhoneOff()1330     public void notePhoneOff() {
1331         enforceCallingPermission();
1332         synchronized (mLock) {
1333             final long elapsedRealtime = SystemClock.elapsedRealtime();
1334             final long uptime = SystemClock.uptimeMillis();
1335             mHandler.post(() -> {
1336                 synchronized (mStats) {
1337                     mStats.notePhoneOffLocked(elapsedRealtime, uptime);
1338                 }
1339             });
1340         }
1341     }
1342 
notePhoneSignalStrength(final SignalStrength signalStrength)1343     public void notePhoneSignalStrength(final SignalStrength signalStrength) {
1344         enforceCallingPermission();
1345         synchronized (mLock) {
1346             final long elapsedRealtime = SystemClock.elapsedRealtime();
1347             final long uptime = SystemClock.uptimeMillis();
1348             mHandler.post(() -> {
1349                 synchronized (mStats) {
1350                     mStats.notePhoneSignalStrengthLocked(signalStrength, elapsedRealtime, uptime);
1351                 }
1352             });
1353         }
1354     }
1355 
notePhoneDataConnectionState(final int dataType, final boolean hasData, final int serviceType)1356     public void notePhoneDataConnectionState(final int dataType, final boolean hasData,
1357             final int serviceType) {
1358         enforceCallingPermission();
1359         synchronized (mLock) {
1360             final long elapsedRealtime = SystemClock.elapsedRealtime();
1361             final long uptime = SystemClock.uptimeMillis();
1362             mHandler.post(() -> {
1363                 synchronized (mStats) {
1364                     mStats.notePhoneDataConnectionStateLocked(dataType, hasData, serviceType,
1365                             elapsedRealtime, uptime);
1366                 }
1367             });
1368         }
1369     }
1370 
notePhoneState(final int state)1371     public void notePhoneState(final int state) {
1372         enforceCallingPermission();
1373         synchronized (mLock) {
1374             final long elapsedRealtime = SystemClock.elapsedRealtime();
1375             final long uptime = SystemClock.uptimeMillis();
1376             mHandler.post(() -> {
1377                 int simState = mContext.getSystemService(TelephonyManager.class).getSimState();
1378                 synchronized (mStats) {
1379                     mStats.notePhoneStateLocked(state, simState, elapsedRealtime, uptime);
1380                 }
1381             });
1382         }
1383     }
1384 
noteWifiOn()1385     public void noteWifiOn() {
1386         enforceCallingPermission();
1387         synchronized (mLock) {
1388             final long elapsedRealtime = SystemClock.elapsedRealtime();
1389             final long uptime = SystemClock.uptimeMillis();
1390             mHandler.post(() -> {
1391                 synchronized (mStats) {
1392                     mStats.noteWifiOnLocked(elapsedRealtime, uptime);
1393                 }
1394             });
1395         }
1396         FrameworkStatsLog.write(FrameworkStatsLog.WIFI_ENABLED_STATE_CHANGED,
1397                 FrameworkStatsLog.WIFI_ENABLED_STATE_CHANGED__STATE__ON);
1398     }
1399 
noteWifiOff()1400     public void noteWifiOff() {
1401         enforceCallingPermission();
1402         synchronized (mLock) {
1403             final long elapsedRealtime = SystemClock.elapsedRealtime();
1404             final long uptime = SystemClock.uptimeMillis();
1405             mHandler.post(() -> {
1406                 synchronized (mStats) {
1407                     mStats.noteWifiOffLocked(elapsedRealtime, uptime);
1408                 }
1409             });
1410         }
1411         FrameworkStatsLog.write(FrameworkStatsLog.WIFI_ENABLED_STATE_CHANGED,
1412                 FrameworkStatsLog.WIFI_ENABLED_STATE_CHANGED__STATE__OFF);
1413     }
1414 
noteStartAudio(final int uid)1415     public void noteStartAudio(final int uid) {
1416         enforceCallingPermission();
1417         synchronized (mLock) {
1418             final long elapsedRealtime = SystemClock.elapsedRealtime();
1419             final long uptime = SystemClock.uptimeMillis();
1420             mHandler.post(() -> {
1421                 synchronized (mStats) {
1422                     mStats.noteAudioOnLocked(uid, elapsedRealtime, uptime);
1423                 }
1424             });
1425         }
1426         FrameworkStatsLog.write_non_chained(FrameworkStatsLog.AUDIO_STATE_CHANGED, uid,
1427                 null, FrameworkStatsLog.AUDIO_STATE_CHANGED__STATE__ON);
1428     }
1429 
noteStopAudio(final int uid)1430     public void noteStopAudio(final int uid) {
1431         enforceCallingPermission();
1432         synchronized (mLock) {
1433             final long elapsedRealtime = SystemClock.elapsedRealtime();
1434             final long uptime = SystemClock.uptimeMillis();
1435             mHandler.post(() -> {
1436                 synchronized (mStats) {
1437                     mStats.noteAudioOffLocked(uid, elapsedRealtime, uptime);
1438                 }
1439             });
1440         }
1441         FrameworkStatsLog.write_non_chained(FrameworkStatsLog.AUDIO_STATE_CHANGED, uid,
1442                 null, FrameworkStatsLog.AUDIO_STATE_CHANGED__STATE__OFF);
1443     }
1444 
noteStartVideo(final int uid)1445     public void noteStartVideo(final int uid) {
1446         enforceCallingPermission();
1447         synchronized (mLock) {
1448             final long elapsedRealtime = SystemClock.elapsedRealtime();
1449             final long uptime = SystemClock.uptimeMillis();
1450             mHandler.post(() -> {
1451                 synchronized (mStats) {
1452                     mStats.noteVideoOnLocked(uid, elapsedRealtime, uptime);
1453                 }
1454             });
1455         }
1456         FrameworkStatsLog.write_non_chained(FrameworkStatsLog.MEDIA_CODEC_STATE_CHANGED,
1457                 uid, null, FrameworkStatsLog.MEDIA_CODEC_STATE_CHANGED__STATE__ON);
1458     }
1459 
noteStopVideo(final int uid)1460     public void noteStopVideo(final int uid) {
1461         enforceCallingPermission();
1462         synchronized (mLock) {
1463             final long elapsedRealtime = SystemClock.elapsedRealtime();
1464             final long uptime = SystemClock.uptimeMillis();
1465             mHandler.post(() -> {
1466                 synchronized (mStats) {
1467                     mStats.noteVideoOffLocked(uid, elapsedRealtime, uptime);
1468                 }
1469             });
1470         }
1471         FrameworkStatsLog.write_non_chained(FrameworkStatsLog.MEDIA_CODEC_STATE_CHANGED,
1472                 uid, null, FrameworkStatsLog.MEDIA_CODEC_STATE_CHANGED__STATE__OFF);
1473     }
1474 
noteResetAudio()1475     public void noteResetAudio() {
1476         enforceCallingPermission();
1477         synchronized (mLock) {
1478             final long elapsedRealtime = SystemClock.elapsedRealtime();
1479             final long uptime = SystemClock.uptimeMillis();
1480             mHandler.post(() -> {
1481                 synchronized (mStats) {
1482                     mStats.noteResetAudioLocked(elapsedRealtime, uptime);
1483                 }
1484             });
1485         }
1486         FrameworkStatsLog.write_non_chained(FrameworkStatsLog.AUDIO_STATE_CHANGED, -1, null,
1487                 FrameworkStatsLog.AUDIO_STATE_CHANGED__STATE__RESET);
1488     }
1489 
noteResetVideo()1490     public void noteResetVideo() {
1491         enforceCallingPermission();
1492         synchronized (mLock) {
1493             final long elapsedRealtime = SystemClock.elapsedRealtime();
1494             final long uptime = SystemClock.uptimeMillis();
1495             mHandler.post(() -> {
1496                 synchronized (mStats) {
1497                     mStats.noteResetVideoLocked(elapsedRealtime, uptime);
1498                 }
1499             });
1500         }
1501         FrameworkStatsLog.write_non_chained(FrameworkStatsLog.MEDIA_CODEC_STATE_CHANGED, -1,
1502                 null, FrameworkStatsLog.MEDIA_CODEC_STATE_CHANGED__STATE__RESET);
1503     }
1504 
noteFlashlightOn(final int uid)1505     public void noteFlashlightOn(final int uid) {
1506         enforceCallingPermission();
1507         synchronized (mLock) {
1508             final long elapsedRealtime = SystemClock.elapsedRealtime();
1509             final long uptime = SystemClock.uptimeMillis();
1510             mHandler.post(() -> {
1511                 synchronized (mStats) {
1512                     mStats.noteFlashlightOnLocked(uid, elapsedRealtime, uptime);
1513                 }
1514             });
1515         }
1516         FrameworkStatsLog.write_non_chained(FrameworkStatsLog.FLASHLIGHT_STATE_CHANGED, uid,
1517                 null, FrameworkStatsLog.FLASHLIGHT_STATE_CHANGED__STATE__ON);
1518     }
1519 
noteFlashlightOff(final int uid)1520     public void noteFlashlightOff(final int uid) {
1521         enforceCallingPermission();
1522         synchronized (mLock) {
1523             final long elapsedRealtime = SystemClock.elapsedRealtime();
1524             final long uptime = SystemClock.uptimeMillis();
1525             mHandler.post(() -> {
1526                 synchronized (mStats) {
1527                     mStats.noteFlashlightOffLocked(uid, elapsedRealtime, uptime);
1528                 }
1529             });
1530         }
1531         FrameworkStatsLog.write_non_chained(FrameworkStatsLog.FLASHLIGHT_STATE_CHANGED, uid,
1532                 null, FrameworkStatsLog.FLASHLIGHT_STATE_CHANGED__STATE__OFF);
1533     }
1534 
noteStartCamera(final int uid)1535     public void noteStartCamera(final int uid) {
1536         enforceCallingPermission();
1537         if (DBG) Slog.d(TAG, "begin noteStartCamera");
1538         synchronized (mLock) {
1539             final long elapsedRealtime = SystemClock.elapsedRealtime();
1540             final long uptime = SystemClock.uptimeMillis();
1541             mHandler.post(() -> {
1542                 synchronized (mStats) {
1543                     mStats.noteCameraOnLocked(uid, elapsedRealtime, uptime);
1544                 }
1545             });
1546         }
1547         if (DBG) Slog.d(TAG, "end noteStartCamera");
1548         FrameworkStatsLog.write_non_chained(FrameworkStatsLog.CAMERA_STATE_CHANGED, uid,
1549                 null, FrameworkStatsLog.CAMERA_STATE_CHANGED__STATE__ON);
1550     }
1551 
noteStopCamera(final int uid)1552     public void noteStopCamera(final int uid) {
1553         enforceCallingPermission();
1554         synchronized (mLock) {
1555             final long elapsedRealtime = SystemClock.elapsedRealtime();
1556             final long uptime = SystemClock.uptimeMillis();
1557             mHandler.post(() -> {
1558                 synchronized (mStats) {
1559                     mStats.noteCameraOffLocked(uid, elapsedRealtime, uptime);
1560                 }
1561             });
1562         }
1563         FrameworkStatsLog.write_non_chained(FrameworkStatsLog.CAMERA_STATE_CHANGED, uid,
1564                 null, FrameworkStatsLog.CAMERA_STATE_CHANGED__STATE__OFF);
1565     }
1566 
noteResetCamera()1567     public void noteResetCamera() {
1568         enforceCallingPermission();
1569         synchronized (mLock) {
1570             final long elapsedRealtime = SystemClock.elapsedRealtime();
1571             final long uptime = SystemClock.uptimeMillis();
1572             mHandler.post(() -> {
1573                 synchronized (mStats) {
1574                     mStats.noteResetCameraLocked(elapsedRealtime, uptime);
1575                 }
1576             });
1577         }
1578         FrameworkStatsLog.write_non_chained(FrameworkStatsLog.CAMERA_STATE_CHANGED, -1,
1579                 null, FrameworkStatsLog.CAMERA_STATE_CHANGED__STATE__RESET);
1580     }
1581 
noteResetFlashlight()1582     public void noteResetFlashlight() {
1583         enforceCallingPermission();
1584         synchronized (mLock) {
1585             final long elapsedRealtime = SystemClock.elapsedRealtime();
1586             final long uptime = SystemClock.uptimeMillis();
1587             mHandler.post(() -> {
1588                 synchronized (mStats) {
1589                     mStats.noteResetFlashlightLocked(elapsedRealtime, uptime);
1590                 }
1591             });
1592         }
1593         FrameworkStatsLog.write_non_chained(FrameworkStatsLog.FLASHLIGHT_STATE_CHANGED, -1,
1594                 null, FrameworkStatsLog.FLASHLIGHT_STATE_CHANGED__STATE__RESET);
1595     }
1596 
1597     @Override
noteWifiRadioPowerState(final int powerState, final long tsNanos, final int uid)1598     public void noteWifiRadioPowerState(final int powerState, final long tsNanos, final int uid) {
1599         enforceCallingPermission();
1600         synchronized (mLock) {
1601             final long elapsedRealtime = SystemClock.elapsedRealtime();
1602             final long uptime = SystemClock.uptimeMillis();
1603             mHandler.post(() -> {
1604                 // There was a change in WiFi power state.
1605                 // Collect data now for the past activity.
1606                 synchronized (mStats) {
1607                     // Ignore if no power state change.
1608                     if (mLastPowerStateFromWifi == powerState) return;
1609 
1610                     mLastPowerStateFromWifi = powerState;
1611                     if (mStats.isOnBattery()) {
1612                         final String type =
1613                                 (powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH
1614                                 || powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_MEDIUM)
1615                                 ? "active" : "inactive";
1616                         mWorker.scheduleSync("wifi-data: " + type,
1617                                 BatteryExternalStatsWorker.UPDATE_WIFI);
1618                     }
1619                     mStats.noteWifiRadioPowerState(powerState, tsNanos, uid,
1620                             elapsedRealtime, uptime);
1621                 }
1622             });
1623         }
1624         FrameworkStatsLog.write_non_chained(
1625                 FrameworkStatsLog.WIFI_RADIO_POWER_STATE_CHANGED, uid, null, powerState);
1626     }
1627 
noteWifiRunning(final WorkSource ws)1628     public void noteWifiRunning(final WorkSource ws) {
1629         enforceCallingPermission();
1630         final WorkSource localWs = ws != null ? new WorkSource(ws) : null;
1631         synchronized (mLock) {
1632             final long elapsedRealtime = SystemClock.elapsedRealtime();
1633             final long uptime = SystemClock.uptimeMillis();
1634             mHandler.post(() -> {
1635                 synchronized (mStats) {
1636                     mStats.noteWifiRunningLocked(localWs, elapsedRealtime, uptime);
1637                 }
1638             });
1639         }
1640         // TODO: Log WIFI_RUNNING_STATE_CHANGED in a better spot to include Hotspot too.
1641         FrameworkStatsLog.write(FrameworkStatsLog.WIFI_RUNNING_STATE_CHANGED,
1642                 ws, FrameworkStatsLog.WIFI_RUNNING_STATE_CHANGED__STATE__ON);
1643     }
1644 
noteWifiRunningChanged(final WorkSource oldWs, final WorkSource newWs)1645     public void noteWifiRunningChanged(final WorkSource oldWs, final WorkSource newWs) {
1646         enforceCallingPermission();
1647         final WorkSource localOldWs = oldWs != null ? new WorkSource(oldWs) : null;
1648         final WorkSource localNewWs = newWs != null ? new WorkSource(newWs) : null;
1649         synchronized (mLock) {
1650             final long elapsedRealtime = SystemClock.elapsedRealtime();
1651             final long uptime = SystemClock.uptimeMillis();
1652             mHandler.post(() -> {
1653                 synchronized (mStats) {
1654                     mStats.noteWifiRunningChangedLocked(
1655                             localOldWs, localNewWs, elapsedRealtime, uptime);
1656                 }
1657             });
1658         }
1659         FrameworkStatsLog.write(FrameworkStatsLog.WIFI_RUNNING_STATE_CHANGED,
1660                 newWs, FrameworkStatsLog.WIFI_RUNNING_STATE_CHANGED__STATE__ON);
1661         FrameworkStatsLog.write(FrameworkStatsLog.WIFI_RUNNING_STATE_CHANGED,
1662                 oldWs, FrameworkStatsLog.WIFI_RUNNING_STATE_CHANGED__STATE__OFF);
1663     }
1664 
noteWifiStopped(final WorkSource ws)1665     public void noteWifiStopped(final WorkSource ws) {
1666         enforceCallingPermission();
1667         final WorkSource localWs = ws != null ? new WorkSource(ws) : ws;
1668         synchronized (mLock) {
1669             final long elapsedRealtime = SystemClock.elapsedRealtime();
1670             final long uptime = SystemClock.uptimeMillis();
1671             mHandler.post(() -> {
1672                 synchronized (mStats) {
1673                     mStats.noteWifiStoppedLocked(localWs, elapsedRealtime, uptime);
1674                 }
1675             });
1676         }
1677         FrameworkStatsLog.write(FrameworkStatsLog.WIFI_RUNNING_STATE_CHANGED,
1678                 ws, FrameworkStatsLog.WIFI_RUNNING_STATE_CHANGED__STATE__OFF);
1679     }
1680 
noteWifiState(final int wifiState, final String accessPoint)1681     public void noteWifiState(final int wifiState, final String accessPoint) {
1682         enforceCallingPermission();
1683         synchronized (mLock) {
1684             final long elapsedRealtime = SystemClock.elapsedRealtime();
1685             mHandler.post(() -> {
1686                 synchronized (mStats) {
1687                     mStats.noteWifiStateLocked(wifiState, accessPoint, elapsedRealtime);
1688                 }
1689             });
1690         }
1691     }
1692 
noteWifiSupplicantStateChanged(final int supplState, final boolean failedAuth)1693     public void noteWifiSupplicantStateChanged(final int supplState, final boolean failedAuth) {
1694         enforceCallingPermission();
1695         synchronized (mLock) {
1696             final long elapsedRealtime = SystemClock.elapsedRealtime();
1697             final long uptime = SystemClock.uptimeMillis();
1698             mHandler.post(() -> {
1699                 synchronized (mStats) {
1700                     mStats.noteWifiSupplicantStateChangedLocked(supplState, failedAuth,
1701                             elapsedRealtime, uptime);
1702                 }
1703             });
1704         }
1705     }
1706 
noteWifiRssiChanged(final int newRssi)1707     public void noteWifiRssiChanged(final int newRssi) {
1708         enforceCallingPermission();
1709         synchronized (mLock) {
1710             final long elapsedRealtime = SystemClock.elapsedRealtime();
1711             final long uptime = SystemClock.uptimeMillis();
1712             mHandler.post(() -> {
1713                 synchronized (mStats) {
1714                     mStats.noteWifiRssiChangedLocked(newRssi, elapsedRealtime, uptime);
1715                 }
1716             });
1717         }
1718     }
1719 
noteFullWifiLockAcquired(final int uid)1720     public void noteFullWifiLockAcquired(final int uid) {
1721         enforceCallingPermission();
1722         synchronized (mLock) {
1723             final long elapsedRealtime = SystemClock.elapsedRealtime();
1724             final long uptime = SystemClock.uptimeMillis();
1725             mHandler.post(() -> {
1726                 synchronized (mStats) {
1727                     mStats.noteFullWifiLockAcquiredLocked(uid, elapsedRealtime, uptime);
1728                 }
1729             });
1730         }
1731     }
1732 
noteFullWifiLockReleased(final int uid)1733     public void noteFullWifiLockReleased(final int uid) {
1734         enforceCallingPermission();
1735         synchronized (mLock) {
1736             final long elapsedRealtime = SystemClock.elapsedRealtime();
1737             final long uptime = SystemClock.uptimeMillis();
1738             mHandler.post(() -> {
1739                 synchronized (mStats) {
1740                     mStats.noteFullWifiLockReleasedLocked(uid, elapsedRealtime, uptime);
1741                 }
1742             });
1743         }
1744     }
1745 
noteWifiScanStarted(final int uid)1746     public void noteWifiScanStarted(final int uid) {
1747         enforceCallingPermission();
1748         synchronized (mLock) {
1749             final long elapsedRealtime = SystemClock.elapsedRealtime();
1750             final long uptime = SystemClock.uptimeMillis();
1751             mHandler.post(() -> {
1752                 synchronized (mStats) {
1753                     mStats.noteWifiScanStartedLocked(uid, elapsedRealtime, uptime);
1754                 }
1755             });
1756         }
1757     }
1758 
noteWifiScanStopped(final int uid)1759     public void noteWifiScanStopped(final int uid) {
1760         enforceCallingPermission();
1761         synchronized (mLock) {
1762             final long elapsedRealtime = SystemClock.elapsedRealtime();
1763             final long uptime = SystemClock.uptimeMillis();
1764             mHandler.post(() -> {
1765                 synchronized (mStats) {
1766                     mStats.noteWifiScanStoppedLocked(uid, elapsedRealtime, uptime);
1767                 }
1768             });
1769         }
1770     }
1771 
noteWifiMulticastEnabled(final int uid)1772     public void noteWifiMulticastEnabled(final int uid) {
1773         enforceCallingPermission();
1774         synchronized (mLock) {
1775             final long elapsedRealtime = SystemClock.elapsedRealtime();
1776             final long uptime = SystemClock.uptimeMillis();
1777             mHandler.post(() -> {
1778                 synchronized (mStats) {
1779                     mStats.noteWifiMulticastEnabledLocked(uid, elapsedRealtime, uptime);
1780                 }
1781             });
1782         }
1783     }
1784 
noteWifiMulticastDisabled(final int uid)1785     public void noteWifiMulticastDisabled(final int uid) {
1786         enforceCallingPermission();
1787         synchronized (mLock) {
1788             final long elapsedRealtime = SystemClock.elapsedRealtime();
1789             final long uptime = SystemClock.uptimeMillis();
1790             mHandler.post(() -> {
1791                 synchronized (mStats) {
1792                     mStats.noteWifiMulticastDisabledLocked(uid, elapsedRealtime, uptime);
1793                 }
1794             });
1795         }
1796     }
1797 
noteFullWifiLockAcquiredFromSource(final WorkSource ws)1798     public void noteFullWifiLockAcquiredFromSource(final WorkSource ws) {
1799         enforceCallingPermission();
1800         final WorkSource localWs = ws != null ? new WorkSource(ws) : null;
1801         synchronized (mLock) {
1802             final long elapsedRealtime = SystemClock.elapsedRealtime();
1803             final long uptime = SystemClock.uptimeMillis();
1804             mHandler.post(() -> {
1805                 synchronized (mStats) {
1806                     mStats.noteFullWifiLockAcquiredFromSourceLocked(
1807                             localWs, elapsedRealtime, uptime);
1808                 }
1809             });
1810         }
1811     }
1812 
noteFullWifiLockReleasedFromSource(final WorkSource ws)1813     public void noteFullWifiLockReleasedFromSource(final WorkSource ws) {
1814         enforceCallingPermission();
1815         final WorkSource localWs = ws != null ? new WorkSource(ws) : null;
1816         synchronized (mLock) {
1817             final long elapsedRealtime = SystemClock.elapsedRealtime();
1818             final long uptime = SystemClock.uptimeMillis();
1819             mHandler.post(() -> {
1820                 synchronized (mStats) {
1821                     mStats.noteFullWifiLockReleasedFromSourceLocked(
1822                             localWs, elapsedRealtime, uptime);
1823                 }
1824             });
1825         }
1826     }
1827 
noteWifiScanStartedFromSource(final WorkSource ws)1828     public void noteWifiScanStartedFromSource(final WorkSource ws) {
1829         enforceCallingPermission();
1830         final WorkSource localWs = ws != null ? new WorkSource(ws) : null;
1831         synchronized (mLock) {
1832             final long elapsedRealtime = SystemClock.elapsedRealtime();
1833             final long uptime = SystemClock.uptimeMillis();
1834             mHandler.post(() -> {
1835                 synchronized (mStats) {
1836                     mStats.noteWifiScanStartedFromSourceLocked(localWs, elapsedRealtime, uptime);
1837                 }
1838             });
1839         }
1840     }
1841 
noteWifiScanStoppedFromSource(final WorkSource ws)1842     public void noteWifiScanStoppedFromSource(final WorkSource ws) {
1843         enforceCallingPermission();
1844         final WorkSource localWs = ws != null ? new WorkSource(ws) : null;
1845         synchronized (mLock) {
1846             final long elapsedRealtime = SystemClock.elapsedRealtime();
1847             final long uptime = SystemClock.uptimeMillis();
1848             mHandler.post(() -> {
1849                 synchronized (mStats) {
1850                     mStats.noteWifiScanStoppedFromSourceLocked(localWs, elapsedRealtime, uptime);
1851                 }
1852             });
1853         }
1854     }
1855 
noteWifiBatchedScanStartedFromSource(final WorkSource ws, final int csph)1856     public void noteWifiBatchedScanStartedFromSource(final WorkSource ws, final int csph) {
1857         enforceCallingPermission();
1858         final WorkSource localWs = ws != null ? new WorkSource(ws) : null;
1859         synchronized (mLock) {
1860             final long elapsedRealtime = SystemClock.elapsedRealtime();
1861             final long uptime = SystemClock.uptimeMillis();
1862             mHandler.post(() -> {
1863                 synchronized (mStats) {
1864                     mStats.noteWifiBatchedScanStartedFromSourceLocked(localWs, csph,
1865                             elapsedRealtime, uptime);
1866                 }
1867             });
1868         }
1869     }
1870 
noteWifiBatchedScanStoppedFromSource(final WorkSource ws)1871     public void noteWifiBatchedScanStoppedFromSource(final WorkSource ws) {
1872         enforceCallingPermission();
1873         final WorkSource localWs = ws != null ? new WorkSource(ws) : null;
1874         synchronized (mLock) {
1875             final long elapsedRealtime = SystemClock.elapsedRealtime();
1876             final long uptime = SystemClock.uptimeMillis();
1877             mHandler.post(() -> {
1878                 synchronized (mStats) {
1879                     mStats.noteWifiBatchedScanStoppedFromSourceLocked(
1880                             localWs, elapsedRealtime, uptime);
1881                 }
1882             });
1883         }
1884     }
1885 
1886     @Override
noteNetworkInterfaceForTransports(final String iface, int[] transportTypes)1887     public void noteNetworkInterfaceForTransports(final String iface, int[] transportTypes) {
1888         PermissionUtils.enforceNetworkStackPermission(mContext);
1889         synchronized (mLock) {
1890             mHandler.post(() -> {
1891                 mStats.noteNetworkInterfaceForTransports(iface, transportTypes);
1892             });
1893         }
1894     }
1895 
1896     @Override
noteNetworkStatsEnabled()1897     public void noteNetworkStatsEnabled() {
1898         enforceCallingPermission();
1899         // During device boot, qtaguid isn't enabled until after the inital
1900         // loading of battery stats. Now that they're enabled, take our initial
1901         // snapshot for future delta calculation.
1902         synchronized (mLock) {
1903             // Still schedule it on the handler to make sure we have existing pending works done
1904             mHandler.post(() -> {
1905                 mWorker.scheduleSync("network-stats-enabled",
1906                         BatteryExternalStatsWorker.UPDATE_RADIO
1907                         | BatteryExternalStatsWorker.UPDATE_WIFI);
1908             });
1909         }
1910     }
1911 
1912     @Override
noteDeviceIdleMode(final int mode, final String activeReason, final int activeUid)1913     public void noteDeviceIdleMode(final int mode, final String activeReason, final int activeUid) {
1914         enforceCallingPermission();
1915         synchronized (mLock) {
1916             final long elapsedRealtime = SystemClock.elapsedRealtime();
1917             final long uptime = SystemClock.uptimeMillis();
1918             mHandler.post(() -> {
1919                 synchronized (mStats) {
1920                     mStats.noteDeviceIdleModeLocked(mode, activeReason, activeUid,
1921                             elapsedRealtime, uptime);
1922                 }
1923             });
1924         }
1925     }
1926 
notePackageInstalled(final String pkgName, final long versionCode)1927     public void notePackageInstalled(final String pkgName, final long versionCode) {
1928         enforceCallingPermission();
1929         synchronized (mLock) {
1930             final long elapsedRealtime = SystemClock.elapsedRealtime();
1931             final long uptime = SystemClock.uptimeMillis();
1932             mHandler.post(() -> {
1933                 synchronized (mStats) {
1934                     mStats.notePackageInstalledLocked(pkgName, versionCode,
1935                             elapsedRealtime, uptime);
1936                 }
1937             });
1938         }
1939     }
1940 
notePackageUninstalled(final String pkgName)1941     public void notePackageUninstalled(final String pkgName) {
1942         enforceCallingPermission();
1943         synchronized (mLock) {
1944             final long elapsedRealtime = SystemClock.elapsedRealtime();
1945             final long uptime = SystemClock.uptimeMillis();
1946             mHandler.post(() -> {
1947                 synchronized (mStats) {
1948                     mStats.notePackageUninstalledLocked(pkgName, elapsedRealtime, uptime);
1949                 }
1950             });
1951         }
1952     }
1953 
1954     @Override
noteBleScanStarted(final WorkSource ws, final boolean isUnoptimized)1955     public void noteBleScanStarted(final WorkSource ws, final boolean isUnoptimized) {
1956         enforceCallingPermission();
1957         final WorkSource localWs = ws != null ? new WorkSource(ws) : null;
1958         synchronized (mLock) {
1959             final long elapsedRealtime = SystemClock.elapsedRealtime();
1960             final long uptime = SystemClock.uptimeMillis();
1961             mHandler.post(() -> {
1962                 synchronized (mStats) {
1963                     mStats.noteBluetoothScanStartedFromSourceLocked(localWs, isUnoptimized,
1964                             elapsedRealtime, uptime);
1965                 }
1966             });
1967         }
1968     }
1969 
1970     @Override
noteBleScanStopped(final WorkSource ws, final boolean isUnoptimized)1971     public void noteBleScanStopped(final WorkSource ws, final boolean isUnoptimized) {
1972         enforceCallingPermission();
1973         final WorkSource localWs = ws != null ? new WorkSource(ws) : null;
1974         synchronized (mLock) {
1975             final long elapsedRealtime = SystemClock.elapsedRealtime();
1976             final long uptime = SystemClock.uptimeMillis();
1977             mHandler.post(() -> {
1978                 synchronized (mStats) {
1979                     mStats.noteBluetoothScanStoppedFromSourceLocked(localWs, isUnoptimized,
1980                             uptime, elapsedRealtime);
1981                 }
1982             });
1983         }
1984     }
1985 
1986     @Override
noteResetBleScan()1987     public void noteResetBleScan() {
1988         enforceCallingPermission();
1989         synchronized (mLock) {
1990             final long elapsedRealtime = SystemClock.elapsedRealtime();
1991             final long uptime = SystemClock.uptimeMillis();
1992             mHandler.post(() -> {
1993                 synchronized (mStats) {
1994                     mStats.noteResetBluetoothScanLocked(elapsedRealtime, uptime);
1995                 }
1996             });
1997         }
1998     }
1999 
2000     @Override
noteBleScanResults(final WorkSource ws, final int numNewResults)2001     public void noteBleScanResults(final WorkSource ws, final int numNewResults) {
2002         enforceCallingPermission();
2003         final WorkSource localWs = ws != null ? new WorkSource(ws) : null;
2004         synchronized (mLock) {
2005             final long elapsedRealtime = SystemClock.elapsedRealtime();
2006             final long uptime = SystemClock.uptimeMillis();
2007             mHandler.post(() -> {
2008                 synchronized (mStats) {
2009                     mStats.noteBluetoothScanResultsFromSourceLocked(localWs, numNewResults,
2010                             elapsedRealtime, uptime);
2011                 }
2012             });
2013         }
2014     }
2015 
2016     @Override
noteWifiControllerActivity(final WifiActivityEnergyInfo info)2017     public void noteWifiControllerActivity(final WifiActivityEnergyInfo info) {
2018         enforceCallingPermission();
2019 
2020         if (info == null || !info.isValid()) {
2021             Slog.e(TAG, "invalid wifi data given: " + info);
2022             return;
2023         }
2024 
2025         synchronized (mLock) {
2026             final long elapsedRealtime = SystemClock.elapsedRealtime();
2027             final long uptime = SystemClock.uptimeMillis();
2028             mHandler.post(() -> {
2029                 mStats.updateWifiState(info, POWER_DATA_UNAVAILABLE, elapsedRealtime, uptime);
2030             });
2031         }
2032     }
2033 
2034     @Override
noteBluetoothControllerActivity(final BluetoothActivityEnergyInfo info)2035     public void noteBluetoothControllerActivity(final BluetoothActivityEnergyInfo info) {
2036         enforceCallingPermission();
2037         if (info == null || !info.isValid()) {
2038             Slog.e(TAG, "invalid bluetooth data given: " + info);
2039             return;
2040         }
2041 
2042         synchronized (mLock) {
2043             final long elapsedRealtime = SystemClock.elapsedRealtime();
2044             final long uptime = SystemClock.uptimeMillis();
2045             mHandler.post(() -> {
2046                 synchronized (mStats) {
2047                     mStats.updateBluetoothStateLocked(
2048                             info, POWER_DATA_UNAVAILABLE, elapsedRealtime, uptime);
2049                 }
2050             });
2051         }
2052     }
2053 
2054     @Override
noteModemControllerActivity(final ModemActivityInfo info)2055     public void noteModemControllerActivity(final ModemActivityInfo info) {
2056         enforceCallingPermission();
2057 
2058         if (info == null) {
2059             Slog.e(TAG, "invalid modem data given: " + info);
2060             return;
2061         }
2062 
2063         synchronized (mLock) {
2064             final long elapsedRealtime = SystemClock.elapsedRealtime();
2065             final long uptime = SystemClock.uptimeMillis();
2066             mHandler.post(() -> {
2067                 mStats.noteModemControllerActivity(info, POWER_DATA_UNAVAILABLE, elapsedRealtime,
2068                         uptime);
2069             });
2070         }
2071     }
2072 
isOnBattery()2073     public boolean isOnBattery() {
2074         return mStats.isOnBattery();
2075     }
2076 
2077     @Override
setBatteryState(final int status, final int health, final int plugType, final int level, final int temp, final int volt, final int chargeUAh, final int chargeFullUAh, final long chargeTimeToFullSeconds)2078     public void setBatteryState(final int status, final int health, final int plugType,
2079             final int level, final int temp, final int volt, final int chargeUAh,
2080             final int chargeFullUAh, final long chargeTimeToFullSeconds) {
2081         enforceCallingPermission();
2082 
2083         synchronized (mLock) {
2084             final long elapsedRealtime = SystemClock.elapsedRealtime();
2085             final long uptime = SystemClock.uptimeMillis();
2086             final long currentTime = System.currentTimeMillis();
2087             // We still schedule this task over the handler thread to make sure we've had
2088             // all existing pending work handled before setting the battery state
2089             mHandler.post(() -> {
2090                 // BatteryService calls us here and we may update external state. It would be wrong
2091                 // to block such a low level service like BatteryService on external stats like WiFi
2092                 mWorker.scheduleRunnable(() -> {
2093                     synchronized (mStats) {
2094                         final boolean onBattery = BatteryStatsImpl.isOnBattery(plugType, status);
2095                         if (mStats.isOnBattery() == onBattery) {
2096                             // The battery state has not changed, so we don't need to sync external
2097                             // stats immediately.
2098                             mStats.setBatteryStateLocked(status, health, plugType, level, temp,
2099                                     volt, chargeUAh, chargeFullUAh, chargeTimeToFullSeconds,
2100                                     elapsedRealtime, uptime, currentTime);
2101                             return;
2102                         }
2103                     }
2104 
2105                     // Sync external stats first as the battery has changed states. If we don't sync
2106                     // before changing the state, we may not collect the relevant data later.
2107                     // Order here is guaranteed since we're scheduling from the same thread and we
2108                     // are using a single threaded executor.
2109                     mWorker.scheduleSync("battery-state", BatteryExternalStatsWorker.UPDATE_ALL);
2110                     mWorker.scheduleRunnable(() -> {
2111                         synchronized (mStats) {
2112                             mStats.setBatteryStateLocked(status, health, plugType, level, temp,
2113                                     volt, chargeUAh, chargeFullUAh, chargeTimeToFullSeconds,
2114                                     elapsedRealtime, uptime, currentTime);
2115                         }
2116                     });
2117                 });
2118             });
2119         }
2120     }
2121 
getAwakeTimeBattery()2122     public long getAwakeTimeBattery() {
2123         mContext.enforceCallingOrSelfPermission(
2124                 android.Manifest.permission.BATTERY_STATS, null);
2125         return mStats.getAwakeTimeBattery();
2126     }
2127 
getAwakeTimePlugged()2128     public long getAwakeTimePlugged() {
2129         mContext.enforceCallingOrSelfPermission(
2130                 android.Manifest.permission.BATTERY_STATS, null);
2131         return mStats.getAwakeTimePlugged();
2132     }
2133 
enforceCallingPermission()2134     public void enforceCallingPermission() {
2135         if (Binder.getCallingPid() == Process.myPid()) {
2136             return;
2137         }
2138         mContext.enforcePermission(android.Manifest.permission.UPDATE_DEVICE_STATS,
2139                 Binder.getCallingPid(), Binder.getCallingUid(), null);
2140     }
2141 
2142     final class WakeupReasonThread extends Thread {
2143         private static final int MAX_REASON_SIZE = 512;
2144         private CharsetDecoder mDecoder;
2145         private ByteBuffer mUtf8Buffer;
2146         private CharBuffer mUtf16Buffer;
2147 
WakeupReasonThread()2148         WakeupReasonThread() {
2149             super("BatteryStats_wakeupReason");
2150         }
2151 
run()2152         public void run() {
2153             Process.setThreadPriority(Process.THREAD_PRIORITY_FOREGROUND);
2154 
2155             mDecoder = StandardCharsets.UTF_8
2156                     .newDecoder()
2157                     .onMalformedInput(CodingErrorAction.REPLACE)
2158                     .onUnmappableCharacter(CodingErrorAction.REPLACE)
2159                     .replaceWith("?");
2160 
2161             mUtf8Buffer = ByteBuffer.allocateDirect(MAX_REASON_SIZE);
2162             mUtf16Buffer = CharBuffer.allocate(MAX_REASON_SIZE);
2163 
2164             try {
2165                 String reason;
2166                 while ((reason = waitWakeup()) != null) {
2167                     // Wait for the completion of pending works if there is any
2168                     awaitCompletion();
2169 
2170                     synchronized (mStats) {
2171                         mStats.noteWakeupReasonLocked(reason,
2172                                 SystemClock.elapsedRealtime(), SystemClock.uptimeMillis());
2173                     }
2174                 }
2175             } catch (RuntimeException e) {
2176                 Slog.e(TAG, "Failure reading wakeup reasons", e);
2177             }
2178         }
2179 
waitWakeup()2180         private String waitWakeup() {
2181             mUtf8Buffer.clear();
2182             mUtf16Buffer.clear();
2183             mDecoder.reset();
2184 
2185             int bytesWritten = nativeWaitWakeup(mUtf8Buffer);
2186             if (bytesWritten < 0) {
2187                 return null;
2188             } else if (bytesWritten == 0) {
2189                 return "unknown";
2190             }
2191 
2192             // Set the buffer's limit to the number of bytes written.
2193             mUtf8Buffer.limit(bytesWritten);
2194 
2195             // Decode the buffer from UTF-8 to UTF-16.
2196             // Unmappable characters will be replaced.
2197             mDecoder.decode(mUtf8Buffer, mUtf16Buffer, true);
2198             mUtf16Buffer.flip();
2199 
2200             // Create a String from the UTF-16 buffer.
2201             return mUtf16Buffer.toString();
2202         }
2203     }
2204 
nativeWaitWakeup(ByteBuffer outBuffer)2205     private static native int nativeWaitWakeup(ByteBuffer outBuffer);
2206 
dumpHelp(PrintWriter pw)2207     private void dumpHelp(PrintWriter pw) {
2208         pw.println("Battery stats (batterystats) dump options:");
2209         pw.println("  [--checkin] [--proto] [--history] [--history-start] [--charged] [-c]");
2210         pw.println("  [--daily] [--reset] [--write] [--new-daily] [--read-daily] [-h] [<package.name>]");
2211         pw.println("  --checkin: generate output for a checkin report; will write (and clear) the");
2212         pw.println("             last old completed stats when they had been reset.");
2213         pw.println("  -c: write the current stats in checkin format.");
2214         pw.println("  --proto: write the current aggregate stats (without history) in proto format.");
2215         pw.println("  --history: show only history data.");
2216         pw.println("  --history-start <num>: show only history data starting at given time offset.");
2217         pw.println("  --history-create-events <num>: create <num> of battery history events.");
2218         pw.println("  --charged: only output data since last charged.");
2219         pw.println("  --daily: only output full daily data.");
2220         pw.println("  --reset: reset the stats, clearing all current data.");
2221         pw.println("  --write: force write current collected stats to disk.");
2222         pw.println("  --new-daily: immediately create and write new daily stats record.");
2223         pw.println("  --read-daily: read-load last written daily stats.");
2224         pw.println("  --settings: dump the settings key/values related to batterystats");
2225         pw.println("  --cpu: dump cpu stats for debugging purpose");
2226         pw.println("  <package.name>: optional name of package to filter output by.");
2227         pw.println("  -h: print this help text.");
2228         pw.println("Battery stats (batterystats) commands:");
2229         pw.println("  enable|disable <option>");
2230         pw.println("    Enable or disable a running option.  Option state is not saved across boots.");
2231         pw.println("    Options are:");
2232         pw.println("      full-history: include additional detailed events in battery history:");
2233         pw.println("          wake_lock_in, alarms and proc events");
2234         pw.println("      no-auto-reset: don't automatically reset stats when unplugged");
2235         pw.println("      pretend-screen-off: pretend the screen is off, even if screen state changes");
2236     }
2237 
dumpSettings(PrintWriter pw)2238     private void dumpSettings(PrintWriter pw) {
2239         // Wait for the completion of pending works if there is any
2240         awaitCompletion();
2241         synchronized (mStats) {
2242             mStats.dumpConstantsLocked(pw);
2243         }
2244     }
2245 
dumpCpuStats(PrintWriter pw)2246     private void dumpCpuStats(PrintWriter pw) {
2247         // Wait for the completion of pending works if there is any
2248         awaitCompletion();
2249         synchronized (mStats) {
2250             mStats.dumpCpuStatsLocked(pw);
2251         }
2252     }
2253 
dumpMeasuredEnergyStats(PrintWriter pw)2254     private void dumpMeasuredEnergyStats(PrintWriter pw) {
2255         // Wait for the completion of pending works if there is any
2256         awaitCompletion();
2257         syncStats("dump", BatteryExternalStatsWorker.UPDATE_ALL);
2258         synchronized (mStats) {
2259             mStats.dumpMeasuredEnergyStatsLocked(pw);
2260         }
2261     }
2262 
doEnableOrDisable(PrintWriter pw, int i, String[] args, boolean enable)2263     private int doEnableOrDisable(PrintWriter pw, int i, String[] args, boolean enable) {
2264         i++;
2265         if (i >= args.length) {
2266             pw.println("Missing option argument for " + (enable ? "--enable" : "--disable"));
2267             dumpHelp(pw);
2268             return -1;
2269         }
2270         if ("full-wake-history".equals(args[i]) || "full-history".equals(args[i])) {
2271             // Wait for the completion of pending works if there is any
2272             awaitCompletion();
2273             synchronized (mStats) {
2274                 mStats.setRecordAllHistoryLocked(enable);
2275             }
2276         } else if ("no-auto-reset".equals(args[i])) {
2277             // Wait for the completion of pending works if there is any
2278             awaitCompletion();
2279             synchronized (mStats) {
2280                 mStats.setNoAutoReset(enable);
2281             }
2282         } else if ("pretend-screen-off".equals(args[i])) {
2283             // Wait for the completion of pending works if there is any
2284             awaitCompletion();
2285             synchronized (mStats) {
2286                 mStats.setPretendScreenOff(enable);
2287             }
2288         } else {
2289             pw.println("Unknown enable/disable option: " + args[i]);
2290             dumpHelp(pw);
2291             return -1;
2292         }
2293         return i;
2294     }
2295 
2296 
2297     @Override
dump(FileDescriptor fd, PrintWriter pw, String[] args)2298     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2299         if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
2300 
2301         int flags = 0;
2302         boolean useCheckinFormat = false;
2303         boolean toProto = false;
2304         boolean isRealCheckin = false;
2305         boolean noOutput = false;
2306         boolean writeData = false;
2307         long historyStart = -1;
2308         int reqUid = -1;
2309         if (args != null) {
2310             for (int i=0; i<args.length; i++) {
2311                 String arg = args[i];
2312                 if ("--checkin".equals(arg)) {
2313                     useCheckinFormat = true;
2314                     isRealCheckin = true;
2315                 } else if ("--history".equals(arg)) {
2316                     flags |= BatteryStats.DUMP_HISTORY_ONLY;
2317                 } else if ("--history-start".equals(arg)) {
2318                     flags |= BatteryStats.DUMP_HISTORY_ONLY;
2319                     i++;
2320                     if (i >= args.length) {
2321                         pw.println("Missing time argument for --history-since");
2322                         dumpHelp(pw);
2323                         return;
2324                     }
2325                     historyStart = ParseUtils.parseLong(args[i], 0);
2326                     writeData = true;
2327                 } else if ("--history-create-events".equals(arg)) {
2328                     i++;
2329                     if (i >= args.length) {
2330                         pw.println("Missing events argument for --history-create-events");
2331                         dumpHelp(pw);
2332                         return;
2333                     }
2334                     final long events = ParseUtils.parseLong(args[i], 0);
2335                     awaitCompletion();
2336                     synchronized (mStats) {
2337                         mStats.createFakeHistoryEvents(events);
2338                         pw.println("Battery history create events started.");
2339                         noOutput = true;
2340                     }
2341                 } else if ("-c".equals(arg)) {
2342                     useCheckinFormat = true;
2343                     flags |= BatteryStats.DUMP_INCLUDE_HISTORY;
2344                 } else if ("--proto".equals(arg)) {
2345                     toProto = true;
2346                 } else if ("--charged".equals(arg)) {
2347                     flags |= BatteryStats.DUMP_CHARGED_ONLY;
2348                 } else if ("--daily".equals(arg)) {
2349                     flags |= BatteryStats.DUMP_DAILY_ONLY;
2350                 } else if ("--reset".equals(arg)) {
2351                     awaitCompletion();
2352                     synchronized (mStats) {
2353                         mStats.resetAllStatsCmdLocked();
2354                         pw.println("Battery stats reset.");
2355                         noOutput = true;
2356                     }
2357                 } else if ("--write".equals(arg)) {
2358                     awaitCompletion();
2359                     syncStats("dump", BatteryExternalStatsWorker.UPDATE_ALL);
2360                     synchronized (mStats) {
2361                         mStats.writeSyncLocked();
2362                         pw.println("Battery stats written.");
2363                         noOutput = true;
2364                     }
2365                 } else if ("--new-daily".equals(arg)) {
2366                     awaitCompletion();
2367                     synchronized (mStats) {
2368                         mStats.recordDailyStatsLocked();
2369                         pw.println("New daily stats written.");
2370                         noOutput = true;
2371                     }
2372                 } else if ("--read-daily".equals(arg)) {
2373                     awaitCompletion();
2374                     synchronized (mStats) {
2375                         mStats.readDailyStatsLocked();
2376                         pw.println("Last daily stats read.");
2377                         noOutput = true;
2378                     }
2379                 } else if ("--enable".equals(arg) || "enable".equals(arg)) {
2380                     i = doEnableOrDisable(pw, i, args, true);
2381                     if (i < 0) {
2382                         return;
2383                     }
2384                     pw.println("Enabled: " + args[i]);
2385                     return;
2386                 } else if ("--disable".equals(arg) || "disable".equals(arg)) {
2387                     i = doEnableOrDisable(pw, i, args, false);
2388                     if (i < 0) {
2389                         return;
2390                     }
2391                     pw.println("Disabled: " + args[i]);
2392                     return;
2393                 } else if ("-h".equals(arg)) {
2394                     dumpHelp(pw);
2395                     return;
2396                 } else if ("--settings".equals(arg)) {
2397                     dumpSettings(pw);
2398                     return;
2399                 } else if ("--cpu".equals(arg)) {
2400                     dumpCpuStats(pw);
2401                     return;
2402                 } else  if ("--measured-energy".equals(arg)) {
2403                     dumpMeasuredEnergyStats(pw);
2404                     return;
2405                 } else if ("-a".equals(arg)) {
2406                     flags |= BatteryStats.DUMP_VERBOSE;
2407                 } else if (arg.length() > 0 && arg.charAt(0) == '-'){
2408                     pw.println("Unknown option: " + arg);
2409                     dumpHelp(pw);
2410                     return;
2411                 } else {
2412                     // Not an option, last argument must be a package name.
2413                     try {
2414                         reqUid = mContext.getPackageManager().getPackageUidAsUser(arg,
2415                                 UserHandle.getCallingUserId());
2416                     } catch (PackageManager.NameNotFoundException e) {
2417                         pw.println("Unknown package: " + arg);
2418                         dumpHelp(pw);
2419                         return;
2420                     }
2421                 }
2422             }
2423         }
2424         if (noOutput) {
2425             return;
2426         }
2427 
2428         final long ident = Binder.clearCallingIdentity();
2429         try {
2430             if (BatteryStatsHelper.checkWifiOnly(mContext)) {
2431                 flags |= BatteryStats.DUMP_DEVICE_WIFI_ONLY;
2432             }
2433             awaitCompletion();
2434             // Fetch data from external sources and update the BatteryStatsImpl object with them.
2435             syncStats("dump", BatteryExternalStatsWorker.UPDATE_ALL);
2436         } finally {
2437             Binder.restoreCallingIdentity(ident);
2438         }
2439 
2440         if (reqUid >= 0) {
2441             // By default, if the caller is only interested in a specific package, then
2442             // we only dump the aggregated data since charged.
2443             if ((flags&(BatteryStats.DUMP_HISTORY_ONLY|BatteryStats.DUMP_CHARGED_ONLY)) == 0) {
2444                 flags |= BatteryStats.DUMP_CHARGED_ONLY;
2445                 // Also if they are doing -c, we don't want history.
2446                 flags &= ~BatteryStats.DUMP_INCLUDE_HISTORY;
2447             }
2448         }
2449 
2450         if (toProto) {
2451             List<ApplicationInfo> apps = mContext.getPackageManager().getInstalledApplications(
2452                     PackageManager.MATCH_ANY_USER | PackageManager.MATCH_ALL);
2453             if (isRealCheckin) {
2454                 // For a real checkin, first we want to prefer to use the last complete checkin
2455                 // file if there is one.
2456                 synchronized (mStats.mCheckinFile) {
2457                     if (mStats.mCheckinFile.exists()) {
2458                         try {
2459                             byte[] raw = mStats.mCheckinFile.readFully();
2460                             if (raw != null) {
2461                                 Parcel in = Parcel.obtain();
2462                                 in.unmarshall(raw, 0, raw.length);
2463                                 in.setDataPosition(0);
2464                                 BatteryStatsImpl checkinStats = new BatteryStatsImpl(
2465                                         null, mStats.mHandler, null, null,
2466                                         mUserManagerUserInfoProvider);
2467                                 checkinStats.readSummaryFromParcel(in);
2468                                 in.recycle();
2469                                 checkinStats.dumpProtoLocked(
2470                                         mContext, fd, apps, flags, historyStart);
2471                                 mStats.mCheckinFile.delete();
2472                                 return;
2473                             }
2474                         } catch (IOException | ParcelFormatException e) {
2475                             Slog.w(TAG, "Failure reading checkin file "
2476                                     + mStats.mCheckinFile.getBaseFile(), e);
2477                         }
2478                     }
2479                 }
2480             }
2481             if (DBG) Slog.d(TAG, "begin dumpProtoLocked from UID " + Binder.getCallingUid());
2482             awaitCompletion();
2483             synchronized (mStats) {
2484                 mStats.dumpProtoLocked(mContext, fd, apps, flags, historyStart);
2485                 if (writeData) {
2486                     mStats.writeAsyncLocked();
2487                 }
2488             }
2489             if (DBG) Slog.d(TAG, "end dumpProtoLocked");
2490         } else if (useCheckinFormat) {
2491             List<ApplicationInfo> apps = mContext.getPackageManager().getInstalledApplications(
2492                     PackageManager.MATCH_ANY_USER | PackageManager.MATCH_ALL);
2493             if (isRealCheckin) {
2494                 // For a real checkin, first we want to prefer to use the last complete checkin
2495                 // file if there is one.
2496                 synchronized (mStats.mCheckinFile) {
2497                     if (mStats.mCheckinFile.exists()) {
2498                         try {
2499                             byte[] raw = mStats.mCheckinFile.readFully();
2500                             if (raw != null) {
2501                                 Parcel in = Parcel.obtain();
2502                                 in.unmarshall(raw, 0, raw.length);
2503                                 in.setDataPosition(0);
2504                                 BatteryStatsImpl checkinStats = new BatteryStatsImpl(
2505                                         null, mStats.mHandler, null, null,
2506                                         mUserManagerUserInfoProvider);
2507                                 checkinStats.readSummaryFromParcel(in);
2508                                 in.recycle();
2509                                 checkinStats.dumpCheckinLocked(mContext, pw, apps, flags,
2510                                         historyStart);
2511                                 mStats.mCheckinFile.delete();
2512                                 return;
2513                             }
2514                         } catch (IOException | ParcelFormatException e) {
2515                             Slog.w(TAG, "Failure reading checkin file "
2516                                     + mStats.mCheckinFile.getBaseFile(), e);
2517                         }
2518                     }
2519                 }
2520             }
2521             if (DBG) Slog.d(TAG, "begin dumpCheckinLocked from UID " + Binder.getCallingUid());
2522             awaitCompletion();
2523             synchronized (mStats) {
2524                 mStats.dumpCheckinLocked(mContext, pw, apps, flags, historyStart);
2525                 if (writeData) {
2526                     mStats.writeAsyncLocked();
2527                 }
2528             }
2529             if (DBG) Slog.d(TAG, "end dumpCheckinLocked");
2530         } else {
2531             if (DBG) Slog.d(TAG, "begin dumpLocked from UID " + Binder.getCallingUid());
2532             awaitCompletion();
2533             synchronized (mStats) {
2534                 mStats.dumpLocked(mContext, pw, flags, reqUid, historyStart);
2535                 if (writeData) {
2536                     mStats.writeAsyncLocked();
2537                 }
2538             }
2539             if (DBG) Slog.d(TAG, "end dumpLocked");
2540         }
2541     }
2542 
2543     /**
2544      * Gets a snapshot of cellular stats
2545      * @hide
2546      */
getCellularBatteryStats()2547     public CellularBatteryStats getCellularBatteryStats() {
2548         if (mContext.checkCallingOrSelfPermission(
2549                 android.Manifest.permission.UPDATE_DEVICE_STATS) == PERMISSION_DENIED) {
2550             mContext.enforceCallingOrSelfPermission(
2551                     android.Manifest.permission.BATTERY_STATS, null);
2552         }
2553 
2554         // Wait for the completion of pending works if there is any
2555         awaitCompletion();
2556         synchronized (mStats) {
2557             return mStats.getCellularBatteryStats();
2558         }
2559     }
2560 
2561     /**
2562      * Gets a snapshot of Wifi stats
2563      * @hide
2564      */
getWifiBatteryStats()2565     public WifiBatteryStats getWifiBatteryStats() {
2566         if (mContext.checkCallingOrSelfPermission(
2567                 android.Manifest.permission.UPDATE_DEVICE_STATS) == PERMISSION_DENIED) {
2568             mContext.enforceCallingOrSelfPermission(
2569                     android.Manifest.permission.BATTERY_STATS, null);
2570         }
2571 
2572         // Wait for the completion of pending works if there is any
2573         awaitCompletion();
2574         synchronized (mStats) {
2575             return mStats.getWifiBatteryStats();
2576         }
2577     }
2578 
2579     /**
2580      * Gets a snapshot of Gps stats
2581      * @hide
2582      */
getGpsBatteryStats()2583     public GpsBatteryStats getGpsBatteryStats() {
2584         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BATTERY_STATS, null);
2585 
2586         // Wait for the completion of pending works if there is any
2587         awaitCompletion();
2588         synchronized (mStats) {
2589             return mStats.getGpsBatteryStats();
2590         }
2591     }
2592 
2593     /**
2594      * Gets a snapshot of the system health for a particular uid.
2595      */
2596     @Override
takeUidSnapshot(int requestUid)2597     public HealthStatsParceler takeUidSnapshot(int requestUid) {
2598         if (requestUid != Binder.getCallingUid()) {
2599             mContext.enforceCallingOrSelfPermission(
2600                     android.Manifest.permission.BATTERY_STATS, null);
2601         }
2602         final long ident = Binder.clearCallingIdentity();
2603         try {
2604             // Wait for the completion of pending works if there is any
2605             awaitCompletion();
2606             if (shouldCollectExternalStats()) {
2607                 syncStats("get-health-stats-for-uids", BatteryExternalStatsWorker.UPDATE_ALL);
2608             }
2609             synchronized (mStats) {
2610                 return getHealthStatsForUidLocked(requestUid);
2611             }
2612         } catch (Exception ex) {
2613             Slog.w(TAG, "Crashed while writing for takeUidSnapshot(" + requestUid + ")", ex);
2614             throw ex;
2615         } finally {
2616             Binder.restoreCallingIdentity(ident);
2617         }
2618     }
2619 
2620     /**
2621      * Gets a snapshot of the system health for a number of uids.
2622      */
2623     @Override
takeUidSnapshots(int[] requestUids)2624     public HealthStatsParceler[] takeUidSnapshots(int[] requestUids) {
2625         if (!onlyCaller(requestUids)) {
2626             mContext.enforceCallingOrSelfPermission(
2627                     android.Manifest.permission.BATTERY_STATS, null);
2628         }
2629         final long ident = Binder.clearCallingIdentity();
2630         int i=-1;
2631         try {
2632             // Wait for the completion of pending works if there is any
2633             awaitCompletion();
2634             if (shouldCollectExternalStats()) {
2635                 syncStats("get-health-stats-for-uids", BatteryExternalStatsWorker.UPDATE_ALL);
2636             }
2637             synchronized (mStats) {
2638                 final int N = requestUids.length;
2639                 final HealthStatsParceler[] results = new HealthStatsParceler[N];
2640                 for (i=0; i<N; i++) {
2641                     results[i] = getHealthStatsForUidLocked(requestUids[i]);
2642                 }
2643                 return results;
2644             }
2645         } catch (Exception ex) {
2646             if (DBG) Slog.d(TAG, "Crashed while writing for takeUidSnapshots("
2647                     + Arrays.toString(requestUids) + ") i=" + i, ex);
2648             throw ex;
2649         } finally {
2650             Binder.restoreCallingIdentity(ident);
2651         }
2652     }
2653 
shouldCollectExternalStats()2654     private boolean shouldCollectExternalStats() {
2655         return (SystemClock.elapsedRealtime() - mWorker.getLastCollectionTimeStamp())
2656                 > mStats.getExternalStatsCollectionRateLimitMs();
2657     }
2658 
2659     /**
2660      * Returns whether the Binder.getCallingUid is the only thing in requestUids.
2661      */
onlyCaller(int[] requestUids)2662     private static boolean onlyCaller(int[] requestUids) {
2663         final int caller = Binder.getCallingUid();
2664         final int N = requestUids.length;
2665         for (int i=0; i<N; i++) {
2666             if (requestUids[i] != caller) {
2667                 return false;
2668             }
2669         }
2670         return true;
2671     }
2672 
2673     /**
2674      * Gets a HealthStatsParceler for the given uid. You should probably call
2675      * updateExternalStatsSync first.
2676      */
getHealthStatsForUidLocked(int requestUid)2677     HealthStatsParceler getHealthStatsForUidLocked(int requestUid) {
2678         final HealthStatsBatteryStatsWriter writer = new HealthStatsBatteryStatsWriter();
2679         final HealthStatsWriter uidWriter = new HealthStatsWriter(UidHealthStats.CONSTANTS);
2680         final BatteryStats.Uid uid = mStats.getUidStats().get(requestUid);
2681         if (uid != null) {
2682             writer.writeUid(uidWriter, mStats, uid);
2683         }
2684         return new HealthStatsParceler(uidWriter);
2685     }
2686 
2687     /**
2688      * Delay for sending ACTION_CHARGING after device is plugged in.
2689      *
2690      * @hide
2691      */
setChargingStateUpdateDelayMillis(int delayMillis)2692     public boolean setChargingStateUpdateDelayMillis(int delayMillis) {
2693         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.POWER_SAVER, null);
2694         final long ident = Binder.clearCallingIdentity();
2695 
2696         try {
2697             final ContentResolver contentResolver = mContext.getContentResolver();
2698             return Settings.Global.putLong(contentResolver,
2699                     Settings.Global.BATTERY_CHARGING_STATE_UPDATE_DELAY,
2700                     delayMillis);
2701         } finally {
2702             Binder.restoreCallingIdentity(ident);
2703         }
2704     }
2705 
updateForegroundTimeIfOnBattery(final String packageName, final int uid, final long cpuTimeDiff)2706     void updateForegroundTimeIfOnBattery(final String packageName, final int uid,
2707             final long cpuTimeDiff) {
2708         synchronized (mLock) {
2709             final long elapsedRealtime = SystemClock.elapsedRealtime();
2710             final long uptime = SystemClock.uptimeMillis();
2711             mHandler.post(() -> {
2712                 if (!isOnBattery()) {
2713                     return;
2714                 }
2715                 synchronized (mStats) {
2716                     final BatteryStatsImpl.Uid.Proc ps =
2717                             mStats.getProcessStatsLocked(uid, packageName, elapsedRealtime, uptime);
2718                     if (ps != null) {
2719                         ps.addForegroundTimeLocked(cpuTimeDiff);
2720                     }
2721                 }
2722             });
2723         }
2724     }
2725 
noteCurrentTimeChanged()2726     void noteCurrentTimeChanged() {
2727         synchronized (mLock) {
2728             final long currentTime = System.currentTimeMillis();
2729             final long elapsedRealtime = SystemClock.elapsedRealtime();
2730             final long uptime = SystemClock.uptimeMillis();
2731             mHandler.post(() -> {
2732                 synchronized (mStats) {
2733                     mStats.noteCurrentTimeChangedLocked(currentTime, elapsedRealtime, uptime);
2734                 }
2735             });
2736         }
2737     }
2738 
updateBatteryStatsOnActivityUsage(final String packageName, final String className, final int uid, final int userId, final boolean resumed)2739     void updateBatteryStatsOnActivityUsage(final String packageName, final String className,
2740             final int uid, final int userId, final boolean resumed) {
2741         synchronized (mLock) {
2742             final long elapsedRealtime = SystemClock.elapsedRealtime();
2743             final long uptime = SystemClock.uptimeMillis();
2744             mHandler.post(() -> {
2745                 synchronized (mStats) {
2746                     if (resumed) {
2747                         mStats.noteActivityResumedLocked(uid, elapsedRealtime, uptime);
2748                     } else {
2749                         mStats.noteActivityPausedLocked(uid, elapsedRealtime, uptime);
2750                     }
2751                 }
2752             });
2753         }
2754         FrameworkStatsLog.write(FrameworkStatsLog.ACTIVITY_FOREGROUND_STATE_CHANGED,
2755                 uid, packageName, className,
2756                 resumed
2757                         ? FrameworkStatsLog.ACTIVITY_FOREGROUND_STATE_CHANGED__STATE__FOREGROUND
2758                         : FrameworkStatsLog.ACTIVITY_FOREGROUND_STATE_CHANGED__STATE__BACKGROUND);
2759     }
2760 
noteProcessDied(final int uid, final int pid)2761     void noteProcessDied(final int uid, final int pid) {
2762         synchronized (mLock) {
2763             mHandler.post(() -> {
2764                 synchronized (mStats) {
2765                     mStats.noteProcessDiedLocked(uid, pid);
2766                 }
2767             });
2768         }
2769     }
2770 
reportExcessiveCpu(final int uid, final String processName, final long uptimeSince, long cputimeUsed)2771     void reportExcessiveCpu(final int uid, final String processName, final long uptimeSince,
2772             long cputimeUsed) {
2773         synchronized (mLock) {
2774             mHandler.post(() -> {
2775                 synchronized (mStats) {
2776                     mStats.reportExcessiveCpuLocked(uid, processName, uptimeSince, cputimeUsed);
2777                 }
2778             });
2779         }
2780     }
2781 
noteServiceStartRunning(int uid, String pkg, String name)2782     void noteServiceStartRunning(int uid, String pkg, String name) {
2783         synchronized (mLock) {
2784             final long elapsedRealtime = SystemClock.elapsedRealtime();
2785             final long uptime = SystemClock.uptimeMillis();
2786             mHandler.post(() -> {
2787                 synchronized (mStats) {
2788                     final BatteryStatsImpl.Uid.Pkg.Serv stats = mStats.getServiceStatsLocked(uid,
2789                             pkg, name, elapsedRealtime, uptime);
2790                     stats.startRunningLocked(uptime);
2791                 }
2792             });
2793         }
2794     }
2795 
noteServiceStopRunning(int uid, String pkg, String name)2796     void noteServiceStopRunning(int uid, String pkg, String name) {
2797         synchronized (mLock) {
2798             final long elapsedRealtime = SystemClock.elapsedRealtime();
2799             final long uptime = SystemClock.uptimeMillis();
2800             mHandler.post(() -> {
2801                 synchronized (mStats) {
2802                     final BatteryStatsImpl.Uid.Pkg.Serv stats = mStats.getServiceStatsLocked(uid,
2803                             pkg, name, elapsedRealtime, uptime);
2804                     stats.stopRunningLocked(uptime);
2805                 }
2806             });
2807         }
2808     }
2809 
noteServiceStartLaunch(int uid, String pkg, String name)2810     void noteServiceStartLaunch(int uid, String pkg, String name) {
2811         synchronized (mLock) {
2812             final long elapsedRealtime = SystemClock.elapsedRealtime();
2813             final long uptime = SystemClock.uptimeMillis();
2814             mHandler.post(() -> {
2815                 synchronized (mStats) {
2816                     final BatteryStatsImpl.Uid.Pkg.Serv stats = mStats.getServiceStatsLocked(uid,
2817                             pkg, name, elapsedRealtime, uptime);
2818                     stats.startLaunchedLocked(uptime);
2819                 }
2820             });
2821         }
2822     }
2823 
noteServiceStopLaunch(int uid, String pkg, String name)2824     void noteServiceStopLaunch(int uid, String pkg, String name) {
2825         synchronized (mLock) {
2826             final long elapsedRealtime = SystemClock.elapsedRealtime();
2827             final long uptime = SystemClock.uptimeMillis();
2828             mHandler.post(() -> {
2829                 synchronized (mStats) {
2830                     final BatteryStatsImpl.Uid.Pkg.Serv stats = mStats.getServiceStatsLocked(uid,
2831                             pkg, name, elapsedRealtime, uptime);
2832                     stats.stopLaunchedLocked(uptime);
2833                 }
2834             });
2835         }
2836     }
2837 
2838     /**
2839      * Sets battery AC charger to enabled/disabled, and freezes the battery state.
2840      */
2841     @Override
setChargerAcOnline(boolean online, boolean forceUpdate)2842     public void setChargerAcOnline(boolean online, boolean forceUpdate) {
2843         mBatteryManagerInternal.setChargerAcOnline(online, forceUpdate);
2844     }
2845 
2846     /**
2847      * Sets battery level, and freezes the battery state.
2848      */
2849     @Override
setBatteryLevel(int level, boolean forceUpdate)2850     public void setBatteryLevel(int level, boolean forceUpdate) {
2851         mBatteryManagerInternal.setBatteryLevel(level, forceUpdate);
2852     }
2853 
2854     /**
2855      * Unplugs battery, and freezes the battery state.
2856      */
2857     @Override
unplugBattery(boolean forceUpdate)2858     public void unplugBattery(boolean forceUpdate) {
2859         mBatteryManagerInternal.unplugBattery(forceUpdate);
2860     }
2861 
2862     /**
2863      * Unfreezes battery state, returning to current hardware values.
2864      */
2865     @Override
resetBattery(boolean forceUpdate)2866     public void resetBattery(boolean forceUpdate) {
2867         mBatteryManagerInternal.resetBattery(forceUpdate);
2868     }
2869 
2870     /**
2871      * Suspend charging even if plugged in.
2872      */
2873     @Override
suspendBatteryInput()2874     public void suspendBatteryInput() {
2875         mBatteryManagerInternal.suspendBatteryInput();
2876     }
2877 }
2878