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

Commit 4139bc10 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Move wm component initialization to shell main thread"

parents b8bfc0a0 cae66a13
Loading
Loading
Loading
Loading
+4 −4
Original line number Original line Diff line number Diff line
@@ -168,8 +168,8 @@ public abstract class WMShellBaseModule {


    @WMSingleton
    @WMSingleton
    @Provides
    @Provides
    static DragAndDrop provideDragAndDrop(DragAndDropController dragAndDropController) {
    static Optional<DragAndDrop> provideDragAndDrop(DragAndDropController dragAndDropController) {
        return dragAndDropController.asDragAndDrop();
        return Optional.of(dragAndDropController.asDragAndDrop());
    }
    }


    @WMSingleton
    @WMSingleton
@@ -184,8 +184,8 @@ public abstract class WMShellBaseModule {


    @WMSingleton
    @WMSingleton
    @Provides
    @Provides
    static CompatUI provideCompatUI(CompatUIController compatUIController) {
    static Optional<CompatUI> provideCompatUI(CompatUIController compatUIController) {
        return compatUIController.asCompatUI();
        return Optional.of(compatUIController.asCompatUI());
    }
    }


    @WMSingleton
    @WMSingleton
+30 −10
Original line number Original line Diff line number Diff line
@@ -27,7 +27,10 @@ import android.os.HandlerThread;
import android.os.Looper;
import android.os.Looper;
import android.os.Trace;
import android.os.Trace;


import androidx.annotation.Nullable;

import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
import com.android.wm.shell.R;
import com.android.wm.shell.common.HandlerExecutor;
import com.android.wm.shell.common.HandlerExecutor;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.annotations.ChoreographerSfVsync;
import com.android.wm.shell.common.annotations.ChoreographerSfVsync;
@@ -35,7 +38,6 @@ import com.android.wm.shell.common.annotations.ExternalMainThread;
import com.android.wm.shell.common.annotations.ShellAnimationThread;
import com.android.wm.shell.common.annotations.ShellAnimationThread;
import com.android.wm.shell.common.annotations.ShellMainThread;
import com.android.wm.shell.common.annotations.ShellMainThread;
import com.android.wm.shell.common.annotations.ShellSplashscreenThread;
import com.android.wm.shell.common.annotations.ShellSplashscreenThread;
import com.android.wm.shell.R;


import dagger.Module;
import dagger.Module;
import dagger.Provides;
import dagger.Provides;
@@ -53,7 +55,7 @@ public abstract class WMShellConcurrencyModule {
    /**
    /**
     * Returns whether to enable a separate shell thread for the shell features.
     * Returns whether to enable a separate shell thread for the shell features.
     */
     */
    private static boolean enableShellMainThread(Context context) {
    public static boolean enableShellMainThread(Context context) {
        return context.getResources().getBoolean(R.bool.config_enableShellMainThread);
        return context.getResources().getBoolean(R.bool.config_enableShellMainThread);
    }
    }


@@ -84,18 +86,36 @@ public abstract class WMShellConcurrencyModule {
        return new HandlerExecutor(sysuiMainHandler);
        return new HandlerExecutor(sysuiMainHandler);
    }
    }


    /**
     * Creates a shell main thread to be injected into the shell components.  This does not provide
     * the {@param HandleThread}, but is used to create the thread prior to initializing the
     * WM component, and is explicitly bound.
     *
     * See {@link com.android.systemui.SystemUIFactory#init(Context, boolean)}.
     */
    public static HandlerThread createShellMainThread() {
        HandlerThread mainThread = new HandlerThread("wmshell.main", THREAD_PRIORITY_DISPLAY);
        return mainThread;
    }

    /**
    /**
     * Shell main-thread Handler, don't use this unless really necessary (ie. need to dedupe
     * Shell main-thread Handler, don't use this unless really necessary (ie. need to dedupe
     * multiple types of messages, etc.)
     * multiple types of messages, etc.)
     *
     * @param mainThread If non-null, this thread is expected to be started already
     */
     */
    @WMSingleton
    @WMSingleton
    @Provides
    @Provides
    @ShellMainThread
    @ShellMainThread
    public static Handler provideShellMainHandler(Context context,
    public static Handler provideShellMainHandler(Context context,
            @Nullable @ShellMainThread HandlerThread mainThread,
            @ExternalMainThread Handler sysuiMainHandler) {
            @ExternalMainThread Handler sysuiMainHandler) {
        if (enableShellMainThread(context)) {
        if (enableShellMainThread(context)) {
             HandlerThread mainThread = new HandlerThread("wmshell.main", THREAD_PRIORITY_DISPLAY);
            if (mainThread == null) {
                // If this thread wasn't pre-emptively started, then create and start it
                mainThread = createShellMainThread();
                mainThread.start();
                mainThread.start();
            }
            if (Build.IS_DEBUGGABLE) {
            if (Build.IS_DEBUGGABLE) {
                mainThread.getLooper().setTraceTag(Trace.TRACE_TAG_WINDOW_MANAGER);
                mainThread.getLooper().setTraceTag(Trace.TRACE_TAG_WINDOW_MANAGER);
                mainThread.getLooper().setSlowLogThresholdMs(MSGQ_SLOW_DISPATCH_THRESHOLD_MS,
                mainThread.getLooper().setSlowLogThresholdMs(MSGQ_SLOW_DISPATCH_THRESHOLD_MS,
+36 −3
Original line number Original line Diff line number Diff line
@@ -21,6 +21,7 @@ import android.content.Context;
import android.content.res.AssetManager;
import android.content.res.AssetManager;
import android.content.res.Resources;
import android.content.res.Resources;
import android.os.Handler;
import android.os.Handler;
import android.os.HandlerThread;
import android.util.Log;
import android.util.Log;


import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.annotations.VisibleForTesting;
@@ -28,6 +29,7 @@ import com.android.systemui.dagger.DaggerGlobalRootComponent;
import com.android.systemui.dagger.GlobalRootComponent;
import com.android.systemui.dagger.GlobalRootComponent;
import com.android.systemui.dagger.SysUIComponent;
import com.android.systemui.dagger.SysUIComponent;
import com.android.systemui.dagger.WMComponent;
import com.android.systemui.dagger.WMComponent;
import com.android.wm.shell.dagger.WMShellConcurrencyModule;
import com.android.systemui.navigationbar.gestural.BackGestureTfClassifierProvider;
import com.android.systemui.navigationbar.gestural.BackGestureTfClassifierProvider;
import com.android.systemui.screenshot.ScreenshotNotificationSmartActionsProvider;
import com.android.systemui.screenshot.ScreenshotNotificationSmartActionsProvider;
import com.android.wm.shell.transition.ShellTransitions;
import com.android.wm.shell.transition.ShellTransitions;
@@ -96,8 +98,9 @@ public class SystemUIFactory {
                && android.os.Process.myUserHandle().isSystem()
                && android.os.Process.myUserHandle().isSystem()
                && ActivityThread.currentProcessName().equals(ActivityThread.currentPackageName());
                && ActivityThread.currentProcessName().equals(ActivityThread.currentPackageName());
        mRootComponent = buildGlobalRootComponent(context);
        mRootComponent = buildGlobalRootComponent(context);

        // Stand up WMComponent
        // Stand up WMComponent
        mWMComponent = mRootComponent.getWMComponentBuilder().build();
        setupWmComponent(context);
        if (mInitializeComponents) {
        if (mInitializeComponents) {
            // Only initialize when not starting from tests since this currently initializes some
            // Only initialize when not starting from tests since this currently initializes some
            // components that shouldn't be run in the test environment
            // components that shouldn't be run in the test environment
@@ -124,8 +127,8 @@ public class SystemUIFactory {
                    .setDisplayAreaHelper(mWMComponent.getDisplayAreaHelper())
                    .setDisplayAreaHelper(mWMComponent.getDisplayAreaHelper())
                    .setTaskSurfaceHelper(mWMComponent.getTaskSurfaceHelper())
                    .setTaskSurfaceHelper(mWMComponent.getTaskSurfaceHelper())
                    .setRecentTasks(mWMComponent.getRecentTasks())
                    .setRecentTasks(mWMComponent.getRecentTasks())
                    .setCompatUI(Optional.of(mWMComponent.getCompatUI()))
                    .setCompatUI(mWMComponent.getCompatUI())
                    .setDragAndDrop(Optional.of(mWMComponent.getDragAndDrop()))
                    .setDragAndDrop(mWMComponent.getDragAndDrop())
                    .setBackAnimation(mWMComponent.getBackAnimation());
                    .setBackAnimation(mWMComponent.getBackAnimation());
        } else {
        } else {
            // TODO: Call on prepareSysUIComponentBuilder but not with real components. Other option
            // TODO: Call on prepareSysUIComponentBuilder but not with real components. Other option
@@ -160,6 +163,36 @@ public class SystemUIFactory {
        dependency.start();
        dependency.start();
    }
    }


    /**
     * Sets up {@link #mWMComponent}. On devices where the Shell runs on its own main thread,
     * this will pre-create the thread to ensure that the components are constructed on the
     * same thread, to reduce the likelihood of side effects from running the constructors on
     * a different thread than the rest of the class logic.
     */
    private void setupWmComponent(Context context) {
        WMComponent.Builder wmBuilder = mRootComponent.getWMComponentBuilder();
        if (!mInitializeComponents || !WMShellConcurrencyModule.enableShellMainThread(context)) {
            // If running under tests or shell thread is not enabled, we don't need anything special
            mWMComponent = wmBuilder.build();
            return;
        }

        // If the shell main thread is enabled, initialize the component on that thread
        HandlerThread shellThread = WMShellConcurrencyModule.createShellMainThread();
        shellThread.start();

        // Use an async handler since we don't care about synchronization
        Handler shellHandler = Handler.createAsync(shellThread.getLooper());
        boolean built = shellHandler.runWithScissors(() -> {
            wmBuilder.setShellMainThread(shellThread);
            mWMComponent = wmBuilder.build();
        }, 5000);
        if (!built) {
            Log.w(TAG, "Failed to initialize WMComponent");
            throw new RuntimeException();
        }
    }

    /**
    /**
     * Prepares the SysUIComponent builder before it is built.
     * Prepares the SysUIComponent builder before it is built.
     * @param sysUIBuilder the builder provided by the root component's getSysUIComponent() method
     * @param sysUIBuilder the builder provided by the root component's getSysUIComponent() method
+11 −2
Original line number Original line Diff line number Diff line
@@ -17,6 +17,9 @@
package com.android.systemui.dagger;
package com.android.systemui.dagger;


import android.content.Context;
import android.content.Context;
import android.os.HandlerThread;

import androidx.annotation.Nullable;


import com.android.systemui.SystemUIFactory;
import com.android.systemui.SystemUIFactory;
import com.android.systemui.tv.TvWMComponent;
import com.android.systemui.tv.TvWMComponent;
@@ -26,6 +29,7 @@ import com.android.wm.shell.TaskViewFactory;
import com.android.wm.shell.apppairs.AppPairs;
import com.android.wm.shell.apppairs.AppPairs;
import com.android.wm.shell.back.BackAnimation;
import com.android.wm.shell.back.BackAnimation;
import com.android.wm.shell.bubbles.Bubbles;
import com.android.wm.shell.bubbles.Bubbles;
import com.android.wm.shell.common.annotations.ShellMainThread;
import com.android.wm.shell.compatui.CompatUI;
import com.android.wm.shell.compatui.CompatUI;
import com.android.wm.shell.dagger.TvWMShellModule;
import com.android.wm.shell.dagger.TvWMShellModule;
import com.android.wm.shell.dagger.WMShellModule;
import com.android.wm.shell.dagger.WMShellModule;
@@ -44,6 +48,7 @@ import com.android.wm.shell.transition.ShellTransitions;


import java.util.Optional;
import java.util.Optional;


import dagger.BindsInstance;
import dagger.Subcomponent;
import dagger.Subcomponent;


/**
/**
@@ -64,6 +69,10 @@ public interface WMComponent {
     */
     */
    @Subcomponent.Builder
    @Subcomponent.Builder
    interface Builder {
    interface Builder {

        @BindsInstance
        Builder setShellMainThread(@Nullable @ShellMainThread HandlerThread t);

        WMComponent build();
        WMComponent build();
    }
    }


@@ -120,10 +129,10 @@ public interface WMComponent {
    Optional<RecentTasks> getRecentTasks();
    Optional<RecentTasks> getRecentTasks();


    @WMSingleton
    @WMSingleton
    CompatUI getCompatUI();
    Optional<CompatUI> getCompatUI();


    @WMSingleton
    @WMSingleton
    DragAndDrop getDragAndDrop();
    Optional<DragAndDrop> getDragAndDrop();


    @WMSingleton
    @WMSingleton
    Optional<BackAnimation> getBackAnimation();
    Optional<BackAnimation> getBackAnimation();