Loading services/core/java/android/os/BatteryStatsInternal.java +3 −0 Original line number Diff line number Diff line Loading @@ -132,4 +132,7 @@ public abstract class BatteryStatsInternal { * @param uids the uids of all apps that have any alarm in this batch. */ public abstract void noteWakingAlarmBatch(long elapsedMillis, int... uids); /** See PowerStatsUidResolver.mapUid(). */ public abstract int getOwnerUid(int uid); } services/core/java/com/android/server/am/BatteryStatsService.java +8 −0 Original line number Diff line number Diff line Loading @@ -760,6 +760,14 @@ public final class BatteryStatsService extends IBatteryStats.Stub public void noteWakingAlarmBatch(long elapsedMillis, int... uids) { noteCpuWakingActivity(CPU_WAKEUP_SUBSYSTEM_ALARM, elapsedMillis, uids); } @Override public int getOwnerUid(int uid) { if (Process.isSdkSandboxUid(uid)) { return Process.getAppUidForSdkSandboxUid(uid); } return mPowerStatsUidResolver.mapUid(uid); } } /** Loading services/core/java/com/android/server/power/FrameworkStatsLogger.java 0 → 100644 +62 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.power; import android.os.WorkSource.WorkChain; import com.android.internal.util.FrameworkStatsLog; public class FrameworkStatsLogger { public enum WakelockEventType { ACQUIRE, RELEASE } /** Log WakelockStateChanged push atom without a WorkChain. */ public void wakelockStateChanged( int ownerUid, String tag, int powerManagerWakeLockLevel, WakelockEventType eventType) { int event = (eventType == WakelockEventType.ACQUIRE) ? FrameworkStatsLog.WAKELOCK_STATE_CHANGED__STATE__ACQUIRE : FrameworkStatsLog.WAKELOCK_STATE_CHANGED__STATE__RELEASE; FrameworkStatsLog.write_non_chained( FrameworkStatsLog.WAKELOCK_STATE_CHANGED, ownerUid, null, powerManagerWakeLockLevel, tag, event, FrameworkStatsLog.WAKELOCK_STATE_CHANGED__PROCESS_STATE__PROCESS_STATE_UNKNOWN); } /** Log WakelockStateChanged push atom with a WorkChain. */ public void wakelockStateChanged( String tag, WorkChain wc, int powerManagerWakeLockLevel, WakelockEventType eventType) { int event = (eventType == WakelockEventType.ACQUIRE) ? FrameworkStatsLog.WAKELOCK_STATE_CHANGED__STATE__ACQUIRE : FrameworkStatsLog.WAKELOCK_STATE_CHANGED__STATE__RELEASE; FrameworkStatsLog.write( FrameworkStatsLog.WAKELOCK_STATE_CHANGED, wc.getUids(), wc.getTags(), powerManagerWakeLockLevel, tag, event, FrameworkStatsLog.WAKELOCK_STATE_CHANGED__PROCESS_STATE__PROCESS_STATE_UNKNOWN); } } services/core/java/com/android/server/power/Notifier.java +76 −1 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ import android.media.RingtoneManager; import android.metrics.LogMaker; import android.net.Uri; import android.os.BatteryStats; import android.os.BatteryStatsInternal; import android.os.Bundle; import android.os.Handler; import android.os.IWakeLockCallback; Loading @@ -48,6 +49,7 @@ import android.os.VibrationAttributes; import android.os.VibrationEffect; import android.os.Vibrator; import android.os.WorkSource; import android.os.WorkSource.WorkChain; import android.provider.Settings; import android.telephony.TelephonyManager; import android.util.EventLog; Loading @@ -66,10 +68,12 @@ import com.android.server.LocalServices; import com.android.server.input.InputManagerInternal; import com.android.server.inputmethod.InputMethodManagerInternal; import com.android.server.policy.WindowManagerPolicy; import com.android.server.power.FrameworkStatsLogger.WakelockEventType; import com.android.server.power.feature.PowerManagerFlags; import com.android.server.statusbar.StatusBarManagerInternal; import java.io.PrintWriter; import java.util.List; import java.util.UUID; import java.util.concurrent.Executor; import java.util.concurrent.atomic.AtomicBoolean; Loading Loading @@ -195,6 +199,9 @@ public class Notifier { private final PowerManagerFlags mFlags; private final BatteryStatsInternal mBatteryStatsInternal; private final FrameworkStatsLogger mFrameworkStatsLogger; public Notifier(Looper looper, Context context, IBatteryStats batteryStats, SuspendBlocker suspendBlocker, WindowManagerPolicy policy, FaceDownDetector faceDownDetector, ScreenUndimDetector screenUndimDetector, Loading Loading @@ -241,6 +248,14 @@ public class Notifier { } catch (RemoteException ex) { } FrameworkStatsLog.write(FrameworkStatsLog.INTERACTIVE_STATE_CHANGED, FrameworkStatsLog.INTERACTIVE_STATE_CHANGED__STATE__ON); if (mFlags.isMoveWscLoggingToNotifierEnabled()) { mBatteryStatsInternal = mInjector.getBatteryStatsInternal(); mFrameworkStatsLogger = mInjector.getFrameworkStatsLogger(); } else { mBatteryStatsInternal = null; mFrameworkStatsLogger = null; } } /** Loading Loading @@ -277,6 +292,7 @@ public class Notifier { + ", ownerUid=" + ownerUid + ", ownerPid=" + ownerPid + ", workSource=" + workSource); } logWakelockStateChanged(flags, tag, ownerUid, workSource, WakelockEventType.ACQUIRE); notifyWakeLockListener(callback, tag, true, ownerUid, ownerPid, flags, workSource, packageName, historyTag); if (!mFlags.improveWakelockLatency()) { Loading Loading @@ -380,6 +396,10 @@ public class Notifier { + ", workSource=" + newWorkSource); } logWakelockStateChanged(flags, tag, ownerUid, workSource, WakelockEventType.RELEASE); logWakelockStateChanged( newFlags, newTag, newOwnerUid, newWorkSource, WakelockEventType.ACQUIRE); final boolean unimportantForLogging = newOwnerUid == Process.SYSTEM_UID && (newFlags & PowerManager.UNIMPORTANT_FOR_LOGGING) != 0; try { Loading Loading @@ -425,6 +445,7 @@ public class Notifier { + ", ownerUid=" + ownerUid + ", ownerPid=" + ownerPid + ", workSource=" + workSource); } logWakelockStateChanged(flags, tag, ownerUid, workSource, WakelockEventType.RELEASE); notifyWakeLockListener(callback, tag, false, ownerUid, ownerPid, flags, workSource, packageName, historyTag); if (!mFlags.improveWakelockLatency()) { Loading Loading @@ -1258,6 +1279,44 @@ public class Notifier { } } private void logWakelockStateChanged( int flags, String tag, int ownerUid, WorkSource workSource, WakelockEventType eventType) { if (mBatteryStatsInternal == null) { return; } final int type = flags & PowerManager.WAKE_LOCK_LEVEL_MASK; if (workSource == null || workSource.isEmpty()) { final int mappedUid = mBatteryStatsInternal.getOwnerUid(ownerUid); mFrameworkStatsLogger.wakelockStateChanged(mappedUid, tag, type, eventType); } else { for (int i = 0; i < workSource.size(); ++i) { final int mappedUid = mBatteryStatsInternal.getOwnerUid(workSource.getUid(i)); mFrameworkStatsLogger.wakelockStateChanged(mappedUid, tag, type, eventType); } List<WorkChain> workChains = workSource.getWorkChains(); if (workChains != null) { for (WorkChain workChain : workChains) { WorkChain mappedWorkChain = new WorkChain(); // Cache getUids() and getTags() because they make an arraycopy. int[] uids = workChain.getUids(); String[] tags = workChain.getTags(); for (int i = 0; i < workChain.getSize(); ++i) { final int mappedUid = mBatteryStatsInternal.getOwnerUid(uids[i]); mappedWorkChain.addNode(mappedUid, tags[i]); } mFrameworkStatsLogger.wakelockStateChanged( tag, mappedWorkChain, type, eventType); } } } } public interface Injector { /** * Gets the current time in millis Loading @@ -1273,9 +1332,15 @@ public class Notifier { * Gets the AppOpsManager system service */ AppOpsManager getAppOpsManager(Context context); /** Gets the BatteryStatsInternal object */ BatteryStatsInternal getBatteryStatsInternal(); /** Get the FrameworkStatsLogger object */ FrameworkStatsLogger getFrameworkStatsLogger(); } static class RealInjector implements Injector { class RealInjector implements Injector { @Override public long currentTimeMillis() { return System.currentTimeMillis(); Loading @@ -1290,5 +1355,15 @@ public class Notifier { public AppOpsManager getAppOpsManager(Context context) { return context.getSystemService(AppOpsManager.class); } @Override public BatteryStatsInternal getBatteryStatsInternal() { return LocalServices.getService(BatteryStatsInternal.class); } @Override public FrameworkStatsLogger getFrameworkStatsLogger() { return new FrameworkStatsLogger(); } } } services/core/java/com/android/server/power/feature/PowerManagerFlags.java +12 −0 Original line number Diff line number Diff line Loading @@ -55,6 +55,9 @@ public class PowerManagerFlags { Flags::policyReasonInDisplayPowerRequest ); private final FlagState mMoveWscLoggingToNotifier = new FlagState(Flags.FLAG_MOVE_WSC_LOGGING_TO_NOTIFIER, Flags::moveWscLoggingToNotifier); /** Returns whether early-screen-timeout-detector is enabled on not. */ public boolean isEarlyScreenTimeoutDetectorEnabled() { return mEarlyScreenTimeoutDetectorFlagState.isEnabled(); Loading Loading @@ -88,6 +91,14 @@ public class PowerManagerFlags { return mPolicyReasonInDisplayPowerRequest.isEnabled(); } /** * @return Whether we move WakelockStateChanged atom logging to Notifier (enabled) or leave it * in BatteryStatsImpl (disabled). */ public boolean isMoveWscLoggingToNotifierEnabled() { return mMoveWscLoggingToNotifier.isEnabled(); } /** * dumps all flagstates * @param pw printWriter Loading @@ -98,6 +109,7 @@ public class PowerManagerFlags { pw.println(" " + mImproveWakelockLatency); pw.println(" " + mPerDisplayWakeByTouch); pw.println(" " + mFrameworkWakelockInfo); pw.println(" " + mMoveWscLoggingToNotifier); } private static class FlagState { Loading Loading
services/core/java/android/os/BatteryStatsInternal.java +3 −0 Original line number Diff line number Diff line Loading @@ -132,4 +132,7 @@ public abstract class BatteryStatsInternal { * @param uids the uids of all apps that have any alarm in this batch. */ public abstract void noteWakingAlarmBatch(long elapsedMillis, int... uids); /** See PowerStatsUidResolver.mapUid(). */ public abstract int getOwnerUid(int uid); }
services/core/java/com/android/server/am/BatteryStatsService.java +8 −0 Original line number Diff line number Diff line Loading @@ -760,6 +760,14 @@ public final class BatteryStatsService extends IBatteryStats.Stub public void noteWakingAlarmBatch(long elapsedMillis, int... uids) { noteCpuWakingActivity(CPU_WAKEUP_SUBSYSTEM_ALARM, elapsedMillis, uids); } @Override public int getOwnerUid(int uid) { if (Process.isSdkSandboxUid(uid)) { return Process.getAppUidForSdkSandboxUid(uid); } return mPowerStatsUidResolver.mapUid(uid); } } /** Loading
services/core/java/com/android/server/power/FrameworkStatsLogger.java 0 → 100644 +62 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.power; import android.os.WorkSource.WorkChain; import com.android.internal.util.FrameworkStatsLog; public class FrameworkStatsLogger { public enum WakelockEventType { ACQUIRE, RELEASE } /** Log WakelockStateChanged push atom without a WorkChain. */ public void wakelockStateChanged( int ownerUid, String tag, int powerManagerWakeLockLevel, WakelockEventType eventType) { int event = (eventType == WakelockEventType.ACQUIRE) ? FrameworkStatsLog.WAKELOCK_STATE_CHANGED__STATE__ACQUIRE : FrameworkStatsLog.WAKELOCK_STATE_CHANGED__STATE__RELEASE; FrameworkStatsLog.write_non_chained( FrameworkStatsLog.WAKELOCK_STATE_CHANGED, ownerUid, null, powerManagerWakeLockLevel, tag, event, FrameworkStatsLog.WAKELOCK_STATE_CHANGED__PROCESS_STATE__PROCESS_STATE_UNKNOWN); } /** Log WakelockStateChanged push atom with a WorkChain. */ public void wakelockStateChanged( String tag, WorkChain wc, int powerManagerWakeLockLevel, WakelockEventType eventType) { int event = (eventType == WakelockEventType.ACQUIRE) ? FrameworkStatsLog.WAKELOCK_STATE_CHANGED__STATE__ACQUIRE : FrameworkStatsLog.WAKELOCK_STATE_CHANGED__STATE__RELEASE; FrameworkStatsLog.write( FrameworkStatsLog.WAKELOCK_STATE_CHANGED, wc.getUids(), wc.getTags(), powerManagerWakeLockLevel, tag, event, FrameworkStatsLog.WAKELOCK_STATE_CHANGED__PROCESS_STATE__PROCESS_STATE_UNKNOWN); } }
services/core/java/com/android/server/power/Notifier.java +76 −1 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ import android.media.RingtoneManager; import android.metrics.LogMaker; import android.net.Uri; import android.os.BatteryStats; import android.os.BatteryStatsInternal; import android.os.Bundle; import android.os.Handler; import android.os.IWakeLockCallback; Loading @@ -48,6 +49,7 @@ import android.os.VibrationAttributes; import android.os.VibrationEffect; import android.os.Vibrator; import android.os.WorkSource; import android.os.WorkSource.WorkChain; import android.provider.Settings; import android.telephony.TelephonyManager; import android.util.EventLog; Loading @@ -66,10 +68,12 @@ import com.android.server.LocalServices; import com.android.server.input.InputManagerInternal; import com.android.server.inputmethod.InputMethodManagerInternal; import com.android.server.policy.WindowManagerPolicy; import com.android.server.power.FrameworkStatsLogger.WakelockEventType; import com.android.server.power.feature.PowerManagerFlags; import com.android.server.statusbar.StatusBarManagerInternal; import java.io.PrintWriter; import java.util.List; import java.util.UUID; import java.util.concurrent.Executor; import java.util.concurrent.atomic.AtomicBoolean; Loading Loading @@ -195,6 +199,9 @@ public class Notifier { private final PowerManagerFlags mFlags; private final BatteryStatsInternal mBatteryStatsInternal; private final FrameworkStatsLogger mFrameworkStatsLogger; public Notifier(Looper looper, Context context, IBatteryStats batteryStats, SuspendBlocker suspendBlocker, WindowManagerPolicy policy, FaceDownDetector faceDownDetector, ScreenUndimDetector screenUndimDetector, Loading Loading @@ -241,6 +248,14 @@ public class Notifier { } catch (RemoteException ex) { } FrameworkStatsLog.write(FrameworkStatsLog.INTERACTIVE_STATE_CHANGED, FrameworkStatsLog.INTERACTIVE_STATE_CHANGED__STATE__ON); if (mFlags.isMoveWscLoggingToNotifierEnabled()) { mBatteryStatsInternal = mInjector.getBatteryStatsInternal(); mFrameworkStatsLogger = mInjector.getFrameworkStatsLogger(); } else { mBatteryStatsInternal = null; mFrameworkStatsLogger = null; } } /** Loading Loading @@ -277,6 +292,7 @@ public class Notifier { + ", ownerUid=" + ownerUid + ", ownerPid=" + ownerPid + ", workSource=" + workSource); } logWakelockStateChanged(flags, tag, ownerUid, workSource, WakelockEventType.ACQUIRE); notifyWakeLockListener(callback, tag, true, ownerUid, ownerPid, flags, workSource, packageName, historyTag); if (!mFlags.improveWakelockLatency()) { Loading Loading @@ -380,6 +396,10 @@ public class Notifier { + ", workSource=" + newWorkSource); } logWakelockStateChanged(flags, tag, ownerUid, workSource, WakelockEventType.RELEASE); logWakelockStateChanged( newFlags, newTag, newOwnerUid, newWorkSource, WakelockEventType.ACQUIRE); final boolean unimportantForLogging = newOwnerUid == Process.SYSTEM_UID && (newFlags & PowerManager.UNIMPORTANT_FOR_LOGGING) != 0; try { Loading Loading @@ -425,6 +445,7 @@ public class Notifier { + ", ownerUid=" + ownerUid + ", ownerPid=" + ownerPid + ", workSource=" + workSource); } logWakelockStateChanged(flags, tag, ownerUid, workSource, WakelockEventType.RELEASE); notifyWakeLockListener(callback, tag, false, ownerUid, ownerPid, flags, workSource, packageName, historyTag); if (!mFlags.improveWakelockLatency()) { Loading Loading @@ -1258,6 +1279,44 @@ public class Notifier { } } private void logWakelockStateChanged( int flags, String tag, int ownerUid, WorkSource workSource, WakelockEventType eventType) { if (mBatteryStatsInternal == null) { return; } final int type = flags & PowerManager.WAKE_LOCK_LEVEL_MASK; if (workSource == null || workSource.isEmpty()) { final int mappedUid = mBatteryStatsInternal.getOwnerUid(ownerUid); mFrameworkStatsLogger.wakelockStateChanged(mappedUid, tag, type, eventType); } else { for (int i = 0; i < workSource.size(); ++i) { final int mappedUid = mBatteryStatsInternal.getOwnerUid(workSource.getUid(i)); mFrameworkStatsLogger.wakelockStateChanged(mappedUid, tag, type, eventType); } List<WorkChain> workChains = workSource.getWorkChains(); if (workChains != null) { for (WorkChain workChain : workChains) { WorkChain mappedWorkChain = new WorkChain(); // Cache getUids() and getTags() because they make an arraycopy. int[] uids = workChain.getUids(); String[] tags = workChain.getTags(); for (int i = 0; i < workChain.getSize(); ++i) { final int mappedUid = mBatteryStatsInternal.getOwnerUid(uids[i]); mappedWorkChain.addNode(mappedUid, tags[i]); } mFrameworkStatsLogger.wakelockStateChanged( tag, mappedWorkChain, type, eventType); } } } } public interface Injector { /** * Gets the current time in millis Loading @@ -1273,9 +1332,15 @@ public class Notifier { * Gets the AppOpsManager system service */ AppOpsManager getAppOpsManager(Context context); /** Gets the BatteryStatsInternal object */ BatteryStatsInternal getBatteryStatsInternal(); /** Get the FrameworkStatsLogger object */ FrameworkStatsLogger getFrameworkStatsLogger(); } static class RealInjector implements Injector { class RealInjector implements Injector { @Override public long currentTimeMillis() { return System.currentTimeMillis(); Loading @@ -1290,5 +1355,15 @@ public class Notifier { public AppOpsManager getAppOpsManager(Context context) { return context.getSystemService(AppOpsManager.class); } @Override public BatteryStatsInternal getBatteryStatsInternal() { return LocalServices.getService(BatteryStatsInternal.class); } @Override public FrameworkStatsLogger getFrameworkStatsLogger() { return new FrameworkStatsLogger(); } } }
services/core/java/com/android/server/power/feature/PowerManagerFlags.java +12 −0 Original line number Diff line number Diff line Loading @@ -55,6 +55,9 @@ public class PowerManagerFlags { Flags::policyReasonInDisplayPowerRequest ); private final FlagState mMoveWscLoggingToNotifier = new FlagState(Flags.FLAG_MOVE_WSC_LOGGING_TO_NOTIFIER, Flags::moveWscLoggingToNotifier); /** Returns whether early-screen-timeout-detector is enabled on not. */ public boolean isEarlyScreenTimeoutDetectorEnabled() { return mEarlyScreenTimeoutDetectorFlagState.isEnabled(); Loading Loading @@ -88,6 +91,14 @@ public class PowerManagerFlags { return mPolicyReasonInDisplayPowerRequest.isEnabled(); } /** * @return Whether we move WakelockStateChanged atom logging to Notifier (enabled) or leave it * in BatteryStatsImpl (disabled). */ public boolean isMoveWscLoggingToNotifierEnabled() { return mMoveWscLoggingToNotifier.isEnabled(); } /** * dumps all flagstates * @param pw printWriter Loading @@ -98,6 +109,7 @@ public class PowerManagerFlags { pw.println(" " + mImproveWakelockLatency); pw.println(" " + mPerDisplayWakeByTouch); pw.println(" " + mFrameworkWakelockInfo); pw.println(" " + mMoveWscLoggingToNotifier); } private static class FlagState { Loading