From d84179bca22e86c8fb3c7adebd7cd7f94048bc13 Mon Sep 17 00:00:00 2001 From: Jernej Virag Date: Mon, 8 Jul 2024 09:54:56 +0200 Subject: Dispatch doze ticks on main thread after they've been handled This prevents UI crashes from code that expects ticks to be called on main thread. It still keeps Binder calls on background thread. Bug: 350625011 Bug: 330492575 Test: manually on a cheetah Flag: com.android.systemui.dozeui_scheduling_alarms_background_execution Change-Id: I6f05027a1c89cf6de5e3f5a4575f6ae9b21d4bd6 --- .../src/com/android/systemui/doze/DozeHost.java | 3 +++ .../src/com/android/systemui/doze/DozeUi.java | 11 +++++++++-- .../systemui/statusbar/phone/DozeServiceHost.java | 22 +++++++++++++++------- 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java index 8776ec5496c8..17b455d7ef6f 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java @@ -18,6 +18,8 @@ package com.android.systemui.doze; import android.annotation.NonNull; +import androidx.annotation.MainThread; + /** * Interface the doze service uses to communicate with the rest of system UI. */ @@ -27,6 +29,7 @@ public interface DozeHost { void startDozing(); void pulseWhileDozing(@NonNull PulseCallback callback, int reason); void stopDozing(); + @MainThread void dozeTimeTick(); boolean isPowerSaveActive(); boolean isPulsingBlocked(); diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java index 1a06418065a2..9def81a89e3a 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java @@ -27,6 +27,8 @@ import android.os.SystemClock; import android.text.format.Formatter; import android.util.Log; +import androidx.annotation.AnyThread; + import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.doze.dagger.DozeScope; @@ -55,7 +57,7 @@ public class DozeUi implements DozeMachine.Part { private final DozeParameters mDozeParameters; private final DozeLog mDozeLog; private final DelayableExecutor mBgExecutor; - private long mLastTimeTickElapsed = 0; + private volatile long mLastTimeTickElapsed = 0; // If time tick is scheduled and there's not a pending runnable to cancel: private volatile boolean mTimeTickScheduled; private final Runnable mCancelTimeTickerRunnable = new Runnable() { @@ -218,10 +220,15 @@ public class DozeUi implements DozeMachine.Part { return calendar.getTimeInMillis(); } + @AnyThread private void onTimeTick() { verifyLastTimeTick(); - mHost.dozeTimeTick(); + if (dozeuiSchedulingAlarmsBackgroundExecution()) { + mHandler.post(mHost::dozeTimeTick); + } else { + mHost.dozeTimeTick(); + } // Keep wakelock until a frame has been pushed. mHandler.post(mWakeLock.wrap(() -> {})); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java index 330383ff03af..a32d5fef58eb 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java @@ -29,8 +29,10 @@ import android.util.Log; import android.view.MotionEvent; import android.view.View; +import androidx.annotation.MainThread; import androidx.annotation.Nullable; +import com.android.app.tracing.TraceUtils; import com.android.internal.annotations.VisibleForTesting; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.systemui.assist.AssistManager; @@ -61,6 +63,8 @@ import com.android.systemui.util.IListenerSet; import dagger.Lazy; +import kotlin.Unit; + import kotlinx.coroutines.ExperimentalCoroutinesApi; import javax.inject.Inject; @@ -109,7 +113,7 @@ public final class DozeServiceHost implements DozeHost { private CentralSurfaces mCentralSurfaces; private boolean mAlwaysOnSuppressed; private boolean mPulsePending; - private DozeInteractor mDozeInteractor; + private final DozeInteractor mDozeInteractor; @Inject public DozeServiceHost(DozeLog dozeLog, PowerManager powerManager, @@ -337,13 +341,17 @@ public final class DozeServiceHost implements DozeHost { } @Override + @MainThread public void dozeTimeTick() { - mDozeInteractor.dozeTimeTick(); - mShadeLockscreenInteractor.dozeTimeTick(); - mAuthController.dozeTimeTick(); - if (mAmbientIndicationContainer instanceof DozeReceiver) { - ((DozeReceiver) mAmbientIndicationContainer).dozeTimeTick(); - } + TraceUtils.trace("DozeServiceHost#dozeTimeTick", () -> { + mDozeInteractor.dozeTimeTick(); + mShadeLockscreenInteractor.dozeTimeTick(); + mAuthController.dozeTimeTick(); + if (mAmbientIndicationContainer instanceof DozeReceiver) { + ((DozeReceiver) mAmbientIndicationContainer).dozeTimeTick(); + } + return Unit.INSTANCE; + }); } @Override -- cgit v1.2.3-59-g8ed1b