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