Loading services/core/java/com/android/server/power/Notifier.java +52 −10 Original line number Diff line number Diff line Loading @@ -64,6 +64,7 @@ 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.feature.PowerManagerFlags; import com.android.server.statusbar.StatusBarManagerInternal; import java.io.PrintWriter; Loading Loading @@ -187,11 +188,16 @@ public class Notifier { private final AtomicBoolean mIsPlayingChargingStartedFeedback = new AtomicBoolean(false); private final Injector mInjector; private final PowerManagerFlags mFlags; public Notifier(Looper looper, Context context, IBatteryStats batteryStats, SuspendBlocker suspendBlocker, WindowManagerPolicy policy, FaceDownDetector faceDownDetector, ScreenUndimDetector screenUndimDetector, Executor backgroundExecutor) { Executor backgroundExecutor, PowerManagerFlags powerManagerFlags, Injector injector) { mContext = context; mFlags = powerManagerFlags; mBatteryStats = batteryStats; mAppOps = mContext.getSystemService(AppOpsManager.class); mSuspendBlocker = suspendBlocker; Loading Loading @@ -224,8 +230,8 @@ public class Notifier { mShowWirelessChargingAnimationConfig = context.getResources().getBoolean( com.android.internal.R.bool.config_showBuiltinWirelessChargingAnim); mWakeLockLog = new WakeLockLog(context); mInjector = (injector == null) ? new RealInjector() : injector; mWakeLockLog = mInjector.getWakeLockLog(context); // Initialize interactive state for battery stats. try { mBatteryStats.noteInteractive(true); Loading Loading @@ -267,7 +273,7 @@ public class Notifier { + ", ownerUid=" + ownerUid + ", ownerPid=" + ownerPid + ", workSource=" + workSource); } notifyWakeLockListener(callback, tag, true); notifyWakeLockListener(callback, tag, true, ownerUid, flags); final int monitorType = getBatteryStatsWakeLockMonitorType(flags); if (monitorType >= 0) { try { Loading @@ -287,8 +293,9 @@ public class Notifier { } } mWakeLockLog.onWakeLockAcquired(tag, ownerUid, flags); if (!mFlags.improveWakelockLatency()) { mWakeLockLog.onWakeLockAcquired(tag, ownerUid, flags, /*eventTime=*/ -1); } mWakefulnessSessionObserver.onWakeLockAcquired(flags); } Loading Loading @@ -406,7 +413,7 @@ public class Notifier { + ", ownerUid=" + ownerUid + ", ownerPid=" + ownerPid + ", workSource=" + workSource); } notifyWakeLockListener(callback, tag, false); notifyWakeLockListener(callback, tag, false, ownerUid, flags); final int monitorType = getBatteryStatsWakeLockMonitorType(flags); if (monitorType >= 0) { try { Loading @@ -422,8 +429,9 @@ public class Notifier { // Ignore } } mWakeLockLog.onWakeLockReleased(tag, ownerUid); if (!mFlags.improveWakelockLatency()) { mWakeLockLog.onWakeLockReleased(tag, ownerUid, /*eventTime=*/ -1); } mWakefulnessSessionObserver.onWakeLockReleased(flags, releaseReason); } Loading Loading @@ -1040,10 +1048,19 @@ public class Notifier { return enabled && dndOff; } private void notifyWakeLockListener(IWakeLockCallback callback, String tag, boolean isEnabled) { private void notifyWakeLockListener(IWakeLockCallback callback, String tag, boolean isEnabled, int ownerUid, int flags) { if (callback != null) { long currentTime = mInjector.currentTimeMillis(); mHandler.post(() -> { try { if (mFlags.improveWakelockLatency()) { if (isEnabled) { mWakeLockLog.onWakeLockAcquired(tag, ownerUid, flags, currentTime); } else { mWakeLockLog.onWakeLockReleased(tag, ownerUid, currentTime); } } callback.onStateChanged(isEnabled); } catch (RemoteException e) { Slog.e(TAG, "Wakelock.mCallback [" + tag + "] is already dead.", e); Loading @@ -1057,6 +1074,7 @@ public class Notifier { public NotifierHandler(Looper looper) { super(looper, null, true /*async*/); } @Override public void handleMessage(Message msg) { switch (msg.what) { Loading Loading @@ -1085,4 +1103,28 @@ public class Notifier { } } } public interface Injector { /** * Gets the current time in millis */ long currentTimeMillis(); /** * Gets the WakeLockLog object */ WakeLockLog getWakeLockLog(Context context); } static class RealInjector implements Injector { @Override public long currentTimeMillis() { return System.currentTimeMillis(); } @Override public WakeLockLog getWakeLockLog(Context context) { return new WakeLockLog(context); } } } services/core/java/com/android/server/power/PowerManagerService.java +3 −3 Original line number Diff line number Diff line Loading @@ -988,10 +988,10 @@ public final class PowerManagerService extends SystemService Notifier createNotifier(Looper looper, Context context, IBatteryStats batteryStats, SuspendBlocker suspendBlocker, WindowManagerPolicy policy, FaceDownDetector faceDownDetector, ScreenUndimDetector screenUndimDetector, Executor backgroundExecutor) { Executor backgroundExecutor, PowerManagerFlags powerManagerFlags) { return new Notifier( looper, context, batteryStats, suspendBlocker, policy, faceDownDetector, screenUndimDetector, backgroundExecutor); screenUndimDetector, backgroundExecutor, powerManagerFlags, /*injector=*/ null); } SuspendBlocker createSuspendBlocker(PowerManagerService service, String name) { Loading Loading @@ -1373,7 +1373,7 @@ public final class PowerManagerService extends SystemService mNotifier = mInjector.createNotifier(Looper.getMainLooper(), mContext, mBatteryStats, mInjector.createSuspendBlocker(this, "PowerManagerService.Broadcasts"), mPolicy, mFaceDownDetector, mScreenUndimDetector, BackgroundThread.getExecutor()); BackgroundThread.getExecutor(), mFeatureFlags); mPowerGroups.append(Display.DEFAULT_DISPLAY_GROUP, new PowerGroup(WAKEFULNESS_AWAKE, mPowerGroupWakefulnessChangeListener, Loading services/core/java/com/android/server/power/WakeLockLog.java +10 −6 Original line number Diff line number Diff line Loading @@ -154,9 +154,10 @@ final class WakeLockLog { * @param tag The wake lock tag * @param ownerUid The owner UID of the wake lock. * @param flags Flags used for the wake lock. * @param eventTime The time at which the event occurred */ public void onWakeLockAcquired(String tag, int ownerUid, int flags) { onWakeLockEvent(TYPE_ACQUIRE, tag, ownerUid, flags); public void onWakeLockAcquired(String tag, int ownerUid, int flags, long eventTime) { onWakeLockEvent(TYPE_ACQUIRE, tag, ownerUid, flags, eventTime); } /** Loading @@ -164,9 +165,10 @@ final class WakeLockLog { * * @param tag The wake lock tag * @param ownerUid The owner UID of the wake lock. * @param eventTime The time at which the event occurred */ public void onWakeLockReleased(String tag, int ownerUid) { onWakeLockEvent(TYPE_RELEASE, tag, ownerUid, 0 /* flags */); public void onWakeLockReleased(String tag, int ownerUid, long eventTime) { onWakeLockEvent(TYPE_RELEASE, tag, ownerUid, 0 /* flags */, eventTime); } /** Loading Loading @@ -242,9 +244,10 @@ final class WakeLockLog { * @param tag The wake lock's identifying tag. * @param ownerUid The owner UID of the wake lock. * @param flags The flags used with the wake lock. * @param eventTime The time at which the event occurred */ private void onWakeLockEvent(int eventType, String tag, int ownerUid, int flags) { int flags, long eventTime) { if (tag == null) { Slog.w(TAG, "Insufficient data to log wakelock [tag: " + tag + ", ownerUid: " + ownerUid Loading @@ -252,7 +255,8 @@ final class WakeLockLog { return; } final long time = mInjector.currentTimeMillis(); final long time = (eventTime == -1) ? mInjector.currentTimeMillis() : eventTime; final int translatedFlags = eventType == TYPE_ACQUIRE ? translateFlagsFromPowerManager(flags) : 0; Loading services/core/java/com/android/server/power/feature/PowerManagerFlags.java +13 −0 Original line number Diff line number Diff line Loading @@ -35,11 +35,23 @@ public class PowerManagerFlags { Flags.FLAG_ENABLE_EARLY_SCREEN_TIMEOUT_DETECTOR, Flags::enableEarlyScreenTimeoutDetector); private final FlagState mImproveWakelockLatency = new FlagState( Flags.FLAG_IMPROVE_WAKELOCK_LATENCY, Flags::improveWakelockLatency ); /** Returns whether early-screen-timeout-detector is enabled on not. */ public boolean isEarlyScreenTimeoutDetectorEnabled() { return mEarlyScreenTimeoutDetectorFlagState.isEnabled(); } /** * @return Whether to improve the wakelock acquire/release latency or not */ public boolean improveWakelockLatency() { return mImproveWakelockLatency.isEnabled(); } /** * dumps all flagstates * @param pw printWriter Loading @@ -47,6 +59,7 @@ public class PowerManagerFlags { public void dump(PrintWriter pw) { pw.println("PowerManagerFlags:"); pw.println(" " + mEarlyScreenTimeoutDetectorFlagState); pw.println(" " + mImproveWakelockLatency); } private static class FlagState { Loading services/core/java/com/android/server/power/feature/power_flags.aconfig +8 −0 Original line number Diff line number Diff line Loading @@ -10,3 +10,11 @@ flag { bug: "309861917" is_fixed_read_only: true } flag { name: "improve_wakelock_latency" namespace: "power" description: "Feature flag for tracking the optimizations to improve the latency of acquiring and releasing a wakelock." bug: "339590565" is_fixed_read_only: true } No newline at end of file Loading
services/core/java/com/android/server/power/Notifier.java +52 −10 Original line number Diff line number Diff line Loading @@ -64,6 +64,7 @@ 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.feature.PowerManagerFlags; import com.android.server.statusbar.StatusBarManagerInternal; import java.io.PrintWriter; Loading Loading @@ -187,11 +188,16 @@ public class Notifier { private final AtomicBoolean mIsPlayingChargingStartedFeedback = new AtomicBoolean(false); private final Injector mInjector; private final PowerManagerFlags mFlags; public Notifier(Looper looper, Context context, IBatteryStats batteryStats, SuspendBlocker suspendBlocker, WindowManagerPolicy policy, FaceDownDetector faceDownDetector, ScreenUndimDetector screenUndimDetector, Executor backgroundExecutor) { Executor backgroundExecutor, PowerManagerFlags powerManagerFlags, Injector injector) { mContext = context; mFlags = powerManagerFlags; mBatteryStats = batteryStats; mAppOps = mContext.getSystemService(AppOpsManager.class); mSuspendBlocker = suspendBlocker; Loading Loading @@ -224,8 +230,8 @@ public class Notifier { mShowWirelessChargingAnimationConfig = context.getResources().getBoolean( com.android.internal.R.bool.config_showBuiltinWirelessChargingAnim); mWakeLockLog = new WakeLockLog(context); mInjector = (injector == null) ? new RealInjector() : injector; mWakeLockLog = mInjector.getWakeLockLog(context); // Initialize interactive state for battery stats. try { mBatteryStats.noteInteractive(true); Loading Loading @@ -267,7 +273,7 @@ public class Notifier { + ", ownerUid=" + ownerUid + ", ownerPid=" + ownerPid + ", workSource=" + workSource); } notifyWakeLockListener(callback, tag, true); notifyWakeLockListener(callback, tag, true, ownerUid, flags); final int monitorType = getBatteryStatsWakeLockMonitorType(flags); if (monitorType >= 0) { try { Loading @@ -287,8 +293,9 @@ public class Notifier { } } mWakeLockLog.onWakeLockAcquired(tag, ownerUid, flags); if (!mFlags.improveWakelockLatency()) { mWakeLockLog.onWakeLockAcquired(tag, ownerUid, flags, /*eventTime=*/ -1); } mWakefulnessSessionObserver.onWakeLockAcquired(flags); } Loading Loading @@ -406,7 +413,7 @@ public class Notifier { + ", ownerUid=" + ownerUid + ", ownerPid=" + ownerPid + ", workSource=" + workSource); } notifyWakeLockListener(callback, tag, false); notifyWakeLockListener(callback, tag, false, ownerUid, flags); final int monitorType = getBatteryStatsWakeLockMonitorType(flags); if (monitorType >= 0) { try { Loading @@ -422,8 +429,9 @@ public class Notifier { // Ignore } } mWakeLockLog.onWakeLockReleased(tag, ownerUid); if (!mFlags.improveWakelockLatency()) { mWakeLockLog.onWakeLockReleased(tag, ownerUid, /*eventTime=*/ -1); } mWakefulnessSessionObserver.onWakeLockReleased(flags, releaseReason); } Loading Loading @@ -1040,10 +1048,19 @@ public class Notifier { return enabled && dndOff; } private void notifyWakeLockListener(IWakeLockCallback callback, String tag, boolean isEnabled) { private void notifyWakeLockListener(IWakeLockCallback callback, String tag, boolean isEnabled, int ownerUid, int flags) { if (callback != null) { long currentTime = mInjector.currentTimeMillis(); mHandler.post(() -> { try { if (mFlags.improveWakelockLatency()) { if (isEnabled) { mWakeLockLog.onWakeLockAcquired(tag, ownerUid, flags, currentTime); } else { mWakeLockLog.onWakeLockReleased(tag, ownerUid, currentTime); } } callback.onStateChanged(isEnabled); } catch (RemoteException e) { Slog.e(TAG, "Wakelock.mCallback [" + tag + "] is already dead.", e); Loading @@ -1057,6 +1074,7 @@ public class Notifier { public NotifierHandler(Looper looper) { super(looper, null, true /*async*/); } @Override public void handleMessage(Message msg) { switch (msg.what) { Loading Loading @@ -1085,4 +1103,28 @@ public class Notifier { } } } public interface Injector { /** * Gets the current time in millis */ long currentTimeMillis(); /** * Gets the WakeLockLog object */ WakeLockLog getWakeLockLog(Context context); } static class RealInjector implements Injector { @Override public long currentTimeMillis() { return System.currentTimeMillis(); } @Override public WakeLockLog getWakeLockLog(Context context) { return new WakeLockLog(context); } } }
services/core/java/com/android/server/power/PowerManagerService.java +3 −3 Original line number Diff line number Diff line Loading @@ -988,10 +988,10 @@ public final class PowerManagerService extends SystemService Notifier createNotifier(Looper looper, Context context, IBatteryStats batteryStats, SuspendBlocker suspendBlocker, WindowManagerPolicy policy, FaceDownDetector faceDownDetector, ScreenUndimDetector screenUndimDetector, Executor backgroundExecutor) { Executor backgroundExecutor, PowerManagerFlags powerManagerFlags) { return new Notifier( looper, context, batteryStats, suspendBlocker, policy, faceDownDetector, screenUndimDetector, backgroundExecutor); screenUndimDetector, backgroundExecutor, powerManagerFlags, /*injector=*/ null); } SuspendBlocker createSuspendBlocker(PowerManagerService service, String name) { Loading Loading @@ -1373,7 +1373,7 @@ public final class PowerManagerService extends SystemService mNotifier = mInjector.createNotifier(Looper.getMainLooper(), mContext, mBatteryStats, mInjector.createSuspendBlocker(this, "PowerManagerService.Broadcasts"), mPolicy, mFaceDownDetector, mScreenUndimDetector, BackgroundThread.getExecutor()); BackgroundThread.getExecutor(), mFeatureFlags); mPowerGroups.append(Display.DEFAULT_DISPLAY_GROUP, new PowerGroup(WAKEFULNESS_AWAKE, mPowerGroupWakefulnessChangeListener, Loading
services/core/java/com/android/server/power/WakeLockLog.java +10 −6 Original line number Diff line number Diff line Loading @@ -154,9 +154,10 @@ final class WakeLockLog { * @param tag The wake lock tag * @param ownerUid The owner UID of the wake lock. * @param flags Flags used for the wake lock. * @param eventTime The time at which the event occurred */ public void onWakeLockAcquired(String tag, int ownerUid, int flags) { onWakeLockEvent(TYPE_ACQUIRE, tag, ownerUid, flags); public void onWakeLockAcquired(String tag, int ownerUid, int flags, long eventTime) { onWakeLockEvent(TYPE_ACQUIRE, tag, ownerUid, flags, eventTime); } /** Loading @@ -164,9 +165,10 @@ final class WakeLockLog { * * @param tag The wake lock tag * @param ownerUid The owner UID of the wake lock. * @param eventTime The time at which the event occurred */ public void onWakeLockReleased(String tag, int ownerUid) { onWakeLockEvent(TYPE_RELEASE, tag, ownerUid, 0 /* flags */); public void onWakeLockReleased(String tag, int ownerUid, long eventTime) { onWakeLockEvent(TYPE_RELEASE, tag, ownerUid, 0 /* flags */, eventTime); } /** Loading Loading @@ -242,9 +244,10 @@ final class WakeLockLog { * @param tag The wake lock's identifying tag. * @param ownerUid The owner UID of the wake lock. * @param flags The flags used with the wake lock. * @param eventTime The time at which the event occurred */ private void onWakeLockEvent(int eventType, String tag, int ownerUid, int flags) { int flags, long eventTime) { if (tag == null) { Slog.w(TAG, "Insufficient data to log wakelock [tag: " + tag + ", ownerUid: " + ownerUid Loading @@ -252,7 +255,8 @@ final class WakeLockLog { return; } final long time = mInjector.currentTimeMillis(); final long time = (eventTime == -1) ? mInjector.currentTimeMillis() : eventTime; final int translatedFlags = eventType == TYPE_ACQUIRE ? translateFlagsFromPowerManager(flags) : 0; Loading
services/core/java/com/android/server/power/feature/PowerManagerFlags.java +13 −0 Original line number Diff line number Diff line Loading @@ -35,11 +35,23 @@ public class PowerManagerFlags { Flags.FLAG_ENABLE_EARLY_SCREEN_TIMEOUT_DETECTOR, Flags::enableEarlyScreenTimeoutDetector); private final FlagState mImproveWakelockLatency = new FlagState( Flags.FLAG_IMPROVE_WAKELOCK_LATENCY, Flags::improveWakelockLatency ); /** Returns whether early-screen-timeout-detector is enabled on not. */ public boolean isEarlyScreenTimeoutDetectorEnabled() { return mEarlyScreenTimeoutDetectorFlagState.isEnabled(); } /** * @return Whether to improve the wakelock acquire/release latency or not */ public boolean improveWakelockLatency() { return mImproveWakelockLatency.isEnabled(); } /** * dumps all flagstates * @param pw printWriter Loading @@ -47,6 +59,7 @@ public class PowerManagerFlags { public void dump(PrintWriter pw) { pw.println("PowerManagerFlags:"); pw.println(" " + mEarlyScreenTimeoutDetectorFlagState); pw.println(" " + mImproveWakelockLatency); } private static class FlagState { Loading
services/core/java/com/android/server/power/feature/power_flags.aconfig +8 −0 Original line number Diff line number Diff line Loading @@ -10,3 +10,11 @@ flag { bug: "309861917" is_fixed_read_only: true } flag { name: "improve_wakelock_latency" namespace: "power" description: "Feature flag for tracking the optimizations to improve the latency of acquiring and releasing a wakelock." bug: "339590565" is_fixed_read_only: true } No newline at end of file