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