Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 24c5a7c9 authored by Nicolo' Mazzucato's avatar Nicolo' Mazzucato
Browse files

Enable unfold animation progress calculation in arbitrary thread

This cl changes some classes to make unfold animation progresses calculation happen on an arbitrary thread. Now there are 2 consumers of progresses calulated in the background:

1. Launcher process. Launcher receives animation progresses from SystemUI. if SystemUI janks (e.g. due to notification measuring), launcher would have janked as well. After this change, Launcher receives the progresses calculted in the background, so it is unaffected by systemui main thread being blocked.

 2. The dark scrim added after unfold (controlled by "UnfoldLightRevealOverlayAnimation") is now fully independent from the main thread: as it also uses the background progress, and the window is using a separate UI thread, it will not jank when the systemui main thread is stuck.

For now the only missing part is receiving the screenStatus in the bg thread. When we tried it caused regressions in the past. All other signals can now happen either on the unfold progress thread or main.

Most classes have been changed to be created with an arbitrary Handler. In the unfold lib there are 2 now: (1) UnfoldMain and (2) UnfoldBg.

There are now 2 injectable versions of FoldStateProvider. The default one that uses the main thread (and should not have any change in behaviour), and the new one annotated with @UnfoldBgProgress, that receives and executes all (except screen state) the calculations in the background.

PhysicsBasedUnfoldTransitionProgressProvider can now use any of those. Only when the handler provided is different than the main one, another scheduler (that works in the background) is provided to the DynamicAnimation.

+ UnfoldLightRevealOverlayAnimation moved to the new UnfoldBg thread.

Bug: 277879146
Bug: 310572965
Bug: 307511460
Bug: 292472402
Flag: ACONFIG unfold_animation_background_progress DISABLED
Test: DeviceFoldStateProviderTest, PhysicsBasedUnfoldTransitionProgressProviderTest + manual + perfetto trace
Change-Id: I767263b6a5f3c6fd3b6f52c946d724599013a47c
parent 73330b61
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -113,6 +113,13 @@ flag {
    bug: "278054201"
}

flag {
    name: "unfold_animation_background_progress"
    namespace: "systemui"
    description: "Moves unfold animation progress calculation to a background thread"
    bug: "277879146"
}

flag {
    name: "qs_new_pipeline"
    namespace: "systemui"
+1 −2
Original line number Diff line number Diff line
@@ -32,8 +32,7 @@ constructor(private val activityManager: ActivityManager) : CurrentActivityTypeP
    override val isHomeActivity: Boolean?
        get() = _isHomeActivity

    private var _isHomeActivity: Boolean? = null

    @Volatile private var _isHomeActivity: Boolean? = null

    override fun init() {
        _isHomeActivity = activityManager.isOnHomeActivity()
+10 −13
Original line number Diff line number Diff line
@@ -18,18 +18,19 @@ import android.content.Context
import android.hardware.devicestate.DeviceStateManager
import com.android.systemui.unfold.updates.FoldProvider
import com.android.systemui.unfold.updates.FoldProvider.FoldCallback
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.Executor
import javax.inject.Inject
import javax.inject.Singleton

@Singleton
class DeviceStateManagerFoldProvider @Inject constructor(
    private val deviceStateManager: DeviceStateManager,
    private val context: Context
) : FoldProvider {
class DeviceStateManagerFoldProvider
@Inject
constructor(private val deviceStateManager: DeviceStateManager, private val context: Context) :
    FoldProvider {

    private val callbacks: MutableMap<FoldCallback,
            DeviceStateManager.DeviceStateCallback> = hashMapOf()
    private val callbacks =
        ConcurrentHashMap<FoldCallback, DeviceStateManager.DeviceStateCallback>()

    override fun registerCallback(callback: FoldCallback, executor: Executor) {
        val listener = FoldStateListener(context, callback)
@@ -39,13 +40,9 @@ class DeviceStateManagerFoldProvider @Inject constructor(

    override fun unregisterCallback(callback: FoldCallback) {
        val listener = callbacks.remove(callback)
        listener?.let {
            deviceStateManager.unregisterCallback(it)
        }
        listener?.let { deviceStateManager.unregisterCallback(it) }
    }

    private inner class FoldStateListener(
        context: Context,
        listener: FoldCallback
    ) : DeviceStateManager.FoldStateListener(context, { listener.onFoldUpdated(it) })
    private inner class FoldStateListener(context: Context, listener: FoldCallback) :
        DeviceStateManager.FoldStateListener(context, { listener.onFoldUpdated(it) })
}
+29 −6
Original line number Diff line number Diff line
@@ -15,24 +15,29 @@
package com.android.systemui.unfold.system

import android.os.Handler
import android.os.HandlerThread
import android.os.Looper
import android.os.Process
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.dagger.qualifiers.UiBackground
import com.android.systemui.unfold.config.ResourceUnfoldTransitionConfig
import com.android.systemui.unfold.config.UnfoldTransitionConfig
import com.android.systemui.unfold.dagger.UnfoldSingleThreadBg
import com.android.systemui.unfold.dagger.UnfoldBg
import com.android.systemui.unfold.dagger.UnfoldMain
import com.android.systemui.unfold.dagger.UnfoldSingleThreadBg
import com.android.systemui.unfold.updates.FoldProvider
import com.android.systemui.unfold.util.CurrentActivityTypeProvider
import dagger.Binds
import dagger.Module
import dagger.Provides
import java.util.concurrent.Executor
import javax.inject.Singleton

/**
 * Dagger module with system-only dependencies for the unfold animation.
 * The code that is used to calculate unfold transition progress
 * depends on some hidden APIs that are not available in normal
 * apps. In order to re-use this code and use alternative implementations
 * of these classes in other apps and hidden APIs here.
 * Dagger module with system-only dependencies for the unfold animation. The code that is used to
 * calculate unfold transition progress depends on some hidden APIs that are not available in normal
 * apps. In order to re-use this code and use alternative implementations of these classes in other
 * apps and hidden APIs here.
 */
@Module
abstract class SystemUnfoldSharedModule {
@@ -61,4 +66,22 @@ abstract class SystemUnfoldSharedModule {
    @Binds
    @UnfoldSingleThreadBg
    abstract fun backgroundExecutor(@UiBackground executor: Executor): Executor

    companion object {
        @Provides
        @UnfoldBg
        @Singleton
        fun unfoldBgProgressHandler(@UnfoldBg looper: Looper): Handler {
            return Handler(looper)
        }

        @Provides
        @UnfoldBg
        @Singleton
        fun provideBgLooper(): Looper {
            return HandlerThread("UnfoldBg", Process.THREAD_PRIORITY_FOREGROUND)
                .apply { start() }
                .looper
        }
    }
}
+19 −2
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.systemui.dagger;
import com.android.systemui.BootCompleteCacheImpl;
import com.android.systemui.CoreStartable;
import com.android.systemui.Dependency;
import com.android.systemui.Flags;
import com.android.systemui.InitController;
import com.android.systemui.SystemUIAppComponentFactoryBase;
import com.android.systemui.dagger.qualifiers.PerUser;
@@ -35,6 +36,7 @@ import com.android.systemui.unfold.FoldStateLogger;
import com.android.systemui.unfold.FoldStateLoggingProvider;
import com.android.systemui.unfold.SysUIUnfoldComponent;
import com.android.systemui.unfold.UnfoldTransitionProgressProvider;
import com.android.systemui.unfold.dagger.UnfoldBg;
import com.android.systemui.unfold.progress.UnfoldTransitionProgressForwarder;
import com.android.wm.shell.back.BackAnimation;
import com.android.wm.shell.bubbles.Bubbles;
@@ -144,7 +146,15 @@ public interface SysUIComponent {
        getConnectingDisplayViewModel().init();
        getFoldStateLoggingProvider().ifPresent(FoldStateLoggingProvider::init);
        getFoldStateLogger().ifPresent(FoldStateLogger::init);
        getUnfoldTransitionProgressProvider()

        Optional<UnfoldTransitionProgressProvider> unfoldTransitionProgressProvider;

        if (Flags.unfoldAnimationBackgroundProgress()) {
            unfoldTransitionProgressProvider = getBgUnfoldTransitionProgressProvider();
        } else {
            unfoldTransitionProgressProvider = getUnfoldTransitionProgressProvider();
        }
        unfoldTransitionProgressProvider
                .ifPresent(
                        (progressProvider) ->
                                getUnfoldTransitionProgressForwarder()
@@ -170,7 +180,14 @@ public interface SysUIComponent {
    ContextComponentHelper getContextComponentHelper();

    /**
     * Creates a UnfoldTransitionProgressProvider.
     * Creates a UnfoldTransitionProgressProvider that calculates progress in the background.
     */
    @SysUISingleton
    @UnfoldBg
    Optional<UnfoldTransitionProgressProvider> getBgUnfoldTransitionProgressProvider();

    /**
     * Creates a UnfoldTransitionProgressProvider that calculates progress in the main thread.
     */
    @SysUISingleton
    Optional<UnfoldTransitionProgressProvider> getUnfoldTransitionProgressProvider();
Loading