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