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