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