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

Commit e8ed475e authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Load window decor's app name/icon in the bg thread" into main

parents bc441479 afa31d32
Loading
Loading
Loading
Loading
+26 −7
Original line number Diff line number Diff line
@@ -17,7 +17,6 @@
package com.android.wm.shell.apptoweb

import android.app.ActivityManager.RunningTaskInfo
import android.app.TaskInfo
import android.content.Context
import android.content.pm.verify.domain.DomainVerificationManager
import android.graphics.Bitmap
@@ -36,8 +35,17 @@ import android.widget.TextView
import android.window.TaskConstants
import com.android.wm.shell.R
import com.android.wm.shell.common.DisplayController
import com.android.wm.shell.shared.annotations.ShellBackgroundThread
import com.android.wm.shell.shared.annotations.ShellMainThread
import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalViewHostViewContainer
import com.android.wm.shell.windowdecor.common.WindowDecorTaskResourceLoader
import java.util.function.Supplier
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.MainCoroutineDispatcher
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext


/**
@@ -45,13 +53,14 @@ import java.util.function.Supplier
 */
internal class OpenByDefaultDialog(
    private val context: Context,
    private val taskInfo: TaskInfo,
    private val taskInfo: RunningTaskInfo,
    private val taskSurface: SurfaceControl,
    private val displayController: DisplayController,
    private val taskResourceLoader: WindowDecorTaskResourceLoader,
    private val surfaceControlTransactionSupplier: Supplier<SurfaceControl.Transaction>,
    @ShellMainThread private val mainDispatcher: MainCoroutineDispatcher,
    @ShellBackgroundThread private val bgScope: CoroutineScope,
    private val listener: DialogLifecycleListener,
    appIconBitmap: Bitmap?,
    appName: CharSequence?
) {
    private lateinit var dialog: OpenByDefaultDialogView
    private lateinit var viewHost: SurfaceControlViewHost
@@ -67,11 +76,20 @@ internal class OpenByDefaultDialog(
        context.getSystemService(DomainVerificationManager::class.java)!!
    private val packageName = taskInfo.baseActivity?.packageName!!

    private var loadAppInfoJob: Job? = null

    init {
        createDialog()
        initializeRadioButtons()
        bindAppInfo(appIconBitmap, appName)
        loadAppInfoJob = bgScope.launch {
            if (!isActive) return@launch
            val name = taskResourceLoader.getName(taskInfo)
            val icon = taskResourceLoader.getHeaderIcon(taskInfo)
            withContext(mainDispatcher.immediate) {
                if (!isActive) return@withContext
                bindAppInfo(icon, name)
            }
        }
    }

    /** Creates an open by default settings dialog. */
@@ -147,14 +165,15 @@ internal class OpenByDefaultDialog(
    }

    private fun closeMenu() {
        loadAppInfoJob?.cancel()
        dialogContainer?.releaseView()
        dialogContainer = null
        listener.onDialogDismissed()
    }

     private fun bindAppInfo(
        appIconBitmap: Bitmap?,
        appName: CharSequence?
        appIconBitmap: Bitmap,
        appName: CharSequence
    ) {
        appIconView.setImageBitmap(appIconBitmap)
        appNameView.text = appName
+27 −5
Original line number Diff line number Diff line
@@ -151,6 +151,7 @@ import com.android.wm.shell.windowdecor.CaptionWindowDecorViewModel;
import com.android.wm.shell.windowdecor.DesktopModeWindowDecorViewModel;
import com.android.wm.shell.windowdecor.WindowDecorViewModel;
import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalSystemViewContainer;
import com.android.wm.shell.windowdecor.common.WindowDecorTaskResourceLoader;
import com.android.wm.shell.windowdecor.common.viewhost.DefaultWindowDecorViewHostSupplier;
import com.android.wm.shell.windowdecor.common.viewhost.PooledWindowDecorViewHostSupplier;
import com.android.wm.shell.windowdecor.common.viewhost.WindowDecorViewHost;
@@ -769,6 +770,8 @@ public abstract class WMShellModule {
    @WMSingleton
    @Provides
    static DesktopTilingDecorViewModel provideDesktopTilingViewModel(Context context,
            @ShellMainThread MainCoroutineDispatcher mainDispatcher,
            @ShellBackgroundThread CoroutineScope bgScope,
            DisplayController displayController,
            RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
            SyncTransactionQueue syncQueue,
@@ -777,9 +780,12 @@ public abstract class WMShellModule {
            ToggleResizeDesktopTaskTransitionHandler toggleResizeDesktopTaskTransitionHandler,
            ReturnToDragStartAnimator returnToDragStartAnimator,
            @DynamicOverride DesktopUserRepositories desktopUserRepositories,
            DesktopModeEventLogger desktopModeEventLogger) {
            DesktopModeEventLogger desktopModeEventLogger,
            WindowDecorTaskResourceLoader windowDecorTaskResourceLoader) {
        return new DesktopTilingDecorViewModel(
                context,
                mainDispatcher,
                bgScope,
                displayController,
                rootTaskDisplayAreaOrganizer,
                syncQueue,
@@ -788,7 +794,8 @@ public abstract class WMShellModule {
                toggleResizeDesktopTaskTransitionHandler,
                returnToDragStartAnimator,
                desktopUserRepositories,
                desktopModeEventLogger
                desktopModeEventLogger,
                windowDecorTaskResourceLoader
        );
    }

@@ -905,6 +912,8 @@ public abstract class WMShellModule {
            @ShellMainThread ShellExecutor shellExecutor,
            @ShellMainThread Handler mainHandler,
            @ShellMainThread Choreographer mainChoreographer,
            @ShellMainThread MainCoroutineDispatcher mainDispatcher,
            @ShellBackgroundThread CoroutineScope bgScope,
            @ShellBackgroundThread ShellExecutor bgExecutor,
            ShellInit shellInit,
            ShellCommandHandler shellCommandHandler,
@@ -931,13 +940,15 @@ public abstract class WMShellModule {
            Optional<DesktopActivityOrientationChangeHandler> activityOrientationChangeHandler,
            FocusTransitionObserver focusTransitionObserver,
            DesktopModeEventLogger desktopModeEventLogger,
            DesktopModeUiEventLogger desktopModeUiEventLogger
            DesktopModeUiEventLogger desktopModeUiEventLogger,
            WindowDecorTaskResourceLoader taskResourceLoader
    ) {
        if (!DesktopModeStatus.canEnterDesktopModeOrShowAppHandle(context)) {
            return Optional.empty();
        }
        return Optional.of(new DesktopModeWindowDecorViewModel(context, shellExecutor, mainHandler,
                mainChoreographer, bgExecutor, shellInit, shellCommandHandler, windowManager,
                mainChoreographer, mainDispatcher, bgScope, bgExecutor,
                shellInit, shellCommandHandler, windowManager,
                taskOrganizer, desktopUserRepositories, displayController, shellController,
                displayInsetsController, syncQueue, transitions, desktopTasksController,
                desktopImmersiveController.get(),
@@ -945,7 +956,18 @@ public abstract class WMShellModule {
                assistContentRequester, windowDecorViewHostSupplier, multiInstanceHelper,
                desktopTasksLimiter, appHandleEducationController, appToWebEducationController,
                windowDecorCaptionHandleRepository, activityOrientationChangeHandler,
                focusTransitionObserver, desktopModeEventLogger, desktopModeUiEventLogger));
                focusTransitionObserver, desktopModeEventLogger, desktopModeUiEventLogger,
                taskResourceLoader));
    }

    @WMSingleton
    @Provides
    static WindowDecorTaskResourceLoader provideWindowDecorTaskResourceLoader(
            @NonNull Context context, @NonNull ShellInit shellInit,
            @NonNull ShellController shellController,
            @NonNull ShellCommandHandler shellCommandHandler) {
        return new WindowDecorTaskResourceLoader(context, shellInit, shellController,
                shellCommandHandler);
    }

    @WMSingleton
+25 −3
Original line number Diff line number Diff line
@@ -140,6 +140,7 @@ import com.android.wm.shell.sysui.ShellInit;
import com.android.wm.shell.transition.FocusTransitionObserver;
import com.android.wm.shell.transition.Transitions;
import com.android.wm.shell.windowdecor.DesktopModeWindowDecoration.ExclusionRegionListener;
import com.android.wm.shell.windowdecor.common.WindowDecorTaskResourceLoader;
import com.android.wm.shell.windowdecor.common.viewhost.WindowDecorViewHost;
import com.android.wm.shell.windowdecor.common.viewhost.WindowDecorViewHostSupplier;
import com.android.wm.shell.windowdecor.extension.InsetsStateKt;
@@ -150,7 +151,9 @@ import kotlin.Pair;
import kotlin.Unit;
import kotlin.jvm.functions.Function1;

import kotlinx.coroutines.CoroutineScope;
import kotlinx.coroutines.ExperimentalCoroutinesApi;
import kotlinx.coroutines.MainCoroutineDispatcher;

import java.io.PrintWriter;
import java.util.ArrayList;
@@ -177,6 +180,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
    private final ShellController mShellController;
    private final Context mContext;
    private final @ShellMainThread Handler mMainHandler;
    private final @ShellMainThread MainCoroutineDispatcher mMainDispatcher;
    private final @ShellBackgroundThread CoroutineScope mBgScope;
    private final @ShellBackgroundThread ShellExecutor mBgExecutor;
    private final Choreographer mMainChoreographer;
    private final DisplayController mDisplayController;
@@ -241,12 +246,15 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
    private final FocusTransitionObserver mFocusTransitionObserver;
    private final DesktopModeEventLogger mDesktopModeEventLogger;
    private final DesktopModeUiEventLogger mDesktopModeUiEventLogger;
    private final WindowDecorTaskResourceLoader mTaskResourceLoader;

    public DesktopModeWindowDecorViewModel(
            Context context,
            ShellExecutor shellExecutor,
            @ShellMainThread Handler mainHandler,
            Choreographer mainChoreographer,
            @ShellMainThread MainCoroutineDispatcher mainDispatcher,
            @ShellBackgroundThread CoroutineScope bgScope,
            @ShellBackgroundThread ShellExecutor bgExecutor,
            ShellInit shellInit,
            ShellCommandHandler shellCommandHandler,
@@ -273,12 +281,15 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
            Optional<DesktopActivityOrientationChangeHandler> activityOrientationChangeHandler,
            FocusTransitionObserver focusTransitionObserver,
            DesktopModeEventLogger desktopModeEventLogger,
            DesktopModeUiEventLogger desktopModeUiEventLogger) {
            DesktopModeUiEventLogger desktopModeUiEventLogger,
            WindowDecorTaskResourceLoader taskResourceLoader) {
        this(
                context,
                shellExecutor,
                mainHandler,
                mainChoreographer,
                mainDispatcher,
                bgScope,
                bgExecutor,
                shellInit,
                shellCommandHandler,
@@ -311,7 +322,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
                new TaskPositionerFactory(),
                focusTransitionObserver,
                desktopModeEventLogger,
                desktopModeUiEventLogger);
                desktopModeUiEventLogger,
                taskResourceLoader);
    }

    @VisibleForTesting
@@ -320,6 +332,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
            ShellExecutor shellExecutor,
            @ShellMainThread Handler mainHandler,
            Choreographer mainChoreographer,
            @ShellMainThread MainCoroutineDispatcher mainDispatcher,
            @ShellBackgroundThread CoroutineScope bgScope,
            @ShellBackgroundThread ShellExecutor bgExecutor,
            ShellInit shellInit,
            ShellCommandHandler shellCommandHandler,
@@ -352,11 +366,14 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
            TaskPositionerFactory taskPositionerFactory,
            FocusTransitionObserver focusTransitionObserver,
            DesktopModeEventLogger desktopModeEventLogger,
            DesktopModeUiEventLogger desktopModeUiEventLogger) {
            DesktopModeUiEventLogger desktopModeUiEventLogger,
            WindowDecorTaskResourceLoader taskResourceLoader) {
        mContext = context;
        mMainExecutor = shellExecutor;
        mMainHandler = mainHandler;
        mMainChoreographer = mainChoreographer;
        mMainDispatcher = mainDispatcher;
        mBgScope = bgScope;
        mBgExecutor = bgExecutor;
        mActivityTaskManager = mContext.getSystemService(ActivityTaskManager.class);
        mTaskOrganizer = taskOrganizer;
@@ -418,6 +435,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
        mFocusTransitionObserver = focusTransitionObserver;
        mDesktopModeEventLogger = desktopModeEventLogger;
        mDesktopModeUiEventLogger = desktopModeUiEventLogger;
        mTaskResourceLoader = taskResourceLoader;

        shellInit.addInitCallback(this::onInit, this);
    }
@@ -1640,12 +1658,16 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
                                : mContext,
                        mContext.createContextAsUser(UserHandle.of(taskInfo.userId), 0 /* flags */),
                        mDisplayController,
                        mTaskResourceLoader,
                        mSplitScreenController,
                        mDesktopUserRepositories,
                        mTaskOrganizer,
                        taskInfo,
                        taskSurface,
                        mMainHandler,
                        mMainExecutor,
                        mMainDispatcher,
                        mBgScope,
                        mBgExecutor,
                        mMainChoreographer,
                        mSyncQueue,
+97 −76

File changed.

Preview size limit exceeded, changes collapsed.

+55 −26
Original line number Diff line number Diff line
@@ -47,15 +47,25 @@ import androidx.compose.ui.graphics.toArgb
import androidx.core.view.isGone
import com.android.window.flags.Flags
import com.android.wm.shell.R
import com.android.wm.shell.shared.annotations.ShellBackgroundThread
import com.android.wm.shell.shared.annotations.ShellMainThread
import com.android.wm.shell.shared.split.SplitScreenConstants
import com.android.wm.shell.splitscreen.SplitScreenController
import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalSystemViewContainer
import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalViewContainer
import com.android.wm.shell.windowdecor.common.DecorThemeUtil
import com.android.wm.shell.windowdecor.common.calculateMenuPosition
import com.android.wm.shell.windowdecor.common.WindowDecorTaskResourceLoader
import com.android.wm.shell.windowdecor.extension.isFullscreen
import com.android.wm.shell.windowdecor.extension.isMultiWindow
import com.android.wm.shell.windowdecor.extension.isPinned
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.MainCoroutineDispatcher
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

/**
 * Handle menu opened when the appropriate button is clicked on.
@@ -66,11 +76,12 @@ import com.android.wm.shell.windowdecor.extension.isPinned
 * Additional Options: Miscellaneous functions including screenshot and closing task.
 */
class HandleMenu(
    @ShellMainThread private val mainDispatcher: CoroutineDispatcher,
    @ShellBackgroundThread private val bgScope: CoroutineScope,
    private val parentDecor: DesktopModeWindowDecoration,
    private val windowManagerWrapper: WindowManagerWrapper,
    private val taskResourceLoader: WindowDecorTaskResourceLoader,
    private val layoutResId: Int,
    private val appIconBitmap: Bitmap?,
    private val appName: CharSequence?,
    private val splitScreenController: SplitScreenController,
    private val shouldShowWindowingPill: Boolean,
    private val shouldShowNewWindowButton: Boolean,
@@ -103,7 +114,8 @@ class HandleMenu(

    @VisibleForTesting
    var handleMenuViewContainer: AdditionalViewContainer? = null
    private var handleMenuView: HandleMenuView? = null
    @VisibleForTesting
    var handleMenuView: HandleMenuView? = null

    // Position of the handle menu used for laying out the handle view.
    @VisibleForTesting
@@ -122,6 +134,8 @@ class HandleMenu(
        get() = SHOULD_SHOW_SCREENSHOT_BUTTON || shouldShowNewWindowButton ||
            shouldShowManageWindowsButton || shouldShowChangeAspectRatioButton

    private var loadAppInfoJob: Job? = null

    init {
        updateHandleMenuPillPositions(captionX, captionY)
    }
@@ -190,7 +204,7 @@ class HandleMenu(
            shouldShowDesktopModeButton = shouldShowDesktopModeButton,
            isBrowserApp = isBrowserApp
        ).apply {
            bind(taskInfo, appIconBitmap, appName, shouldShowMoreActionsPill)
            bind(taskInfo, shouldShowMoreActionsPill)
            this.onToDesktopClickListener = onToDesktopClickListener
            this.onToFullscreenClickListener = onToFullscreenClickListener
            this.onToSplitScreenClickListener = onToSplitScreenClickListener
@@ -204,7 +218,16 @@ class HandleMenu(
            this.onCloseMenuClickListener = onCloseMenuClickListener
            this.onOutsideTouchListener = onOutsideTouchListener
        }

        loadAppInfoJob = bgScope.launch {
            if (!isActive) return@launch
            val name = taskResourceLoader.getName(taskInfo)
            val icon = taskResourceLoader.getHeaderIcon(taskInfo)
            withContext(mainDispatcher) {
                if (!isActive) return@withContext
                handleMenuView.setAppName(name)
                handleMenuView.setAppIcon(icon)
            }
        }
        val x = handleMenuPosition.x.toInt()
        val y = handleMenuPosition.y.toInt()
        handleMenuViewContainer =
@@ -412,6 +435,7 @@ class HandleMenu(
        resources.configuration.layoutDirection == View.LAYOUT_DIRECTION_RTL

    fun close() {
        loadAppInfoJob?.cancel()
        handleMenuView?.animateCloseMenu {
            handleMenuViewContainer?.releaseView()
            handleMenuViewContainer = null
@@ -439,8 +463,10 @@ class HandleMenu(
        private val appInfoPill = rootView.requireViewById<View>(R.id.app_info_pill)
        private val collapseMenuButton = appInfoPill.requireViewById<HandleMenuImageButton>(
            R.id.collapse_menu_button)
        private val appIconView = appInfoPill.requireViewById<ImageView>(R.id.application_icon)
        private val appNameView = appInfoPill.requireViewById<TextView>(R.id.application_name)
        @VisibleForTesting
        val appIconView = appInfoPill.requireViewById<ImageView>(R.id.application_icon)
        @VisibleForTesting
        val appNameView = appInfoPill.requireViewById<TextView>(R.id.application_name)

        // Windowing Pill.
        private val windowingPill = rootView.requireViewById<View>(R.id.windowing_pill)
@@ -509,14 +535,12 @@ class HandleMenu(
        /** Binds the menu views to the new data. */
        fun bind(
            taskInfo: RunningTaskInfo,
            appIconBitmap: Bitmap?,
            appName: CharSequence?,
            shouldShowMoreActionsPill: Boolean
        ) {
            this.taskInfo = taskInfo
            this.style = calculateMenuStyle(taskInfo)

            bindAppInfoPill(style, appIconBitmap, appName)
            bindAppInfoPill(style)
            if (shouldShowWindowingPill) {
                bindWindowingPill(style)
            }
@@ -527,6 +551,16 @@ class HandleMenu(
            bindOpenInAppOrBrowserPill(style)
        }

        /** Sets the app's name. */
        fun setAppName(name: CharSequence) {
            appNameView.text = name
        }

        /** Sets the app's icon. */
        fun setAppIcon(icon: Bitmap) {
            appIconView.setImageBitmap(icon)
        }

        /** Animates the menu openInAppOrBrowserg. */
        fun animateOpenMenu() {
            if (taskInfo.isFullscreen || taskInfo.isMultiWindow) {
@@ -593,22 +627,14 @@ class HandleMenu(
            )
        }

        private fun bindAppInfoPill(
            style: MenuStyle,
            appIconBitmap: Bitmap?,
            appName: CharSequence?
        ) {
        private fun bindAppInfoPill(style: MenuStyle) {
            appInfoPill.background.setTint(style.backgroundColor)

            collapseMenuButton.apply {
                imageTintList = ColorStateList.valueOf(style.textColor)
                this.taskInfo = this@HandleMenuView.taskInfo
            }
            appIconView.setImageBitmap(appIconBitmap)
            appNameView.apply {
                text = appName
                setTextColor(style.textColor)
            }
            appNameView.setTextColor(style.textColor)
        }

        private fun bindWindowingPill(style: MenuStyle) {
@@ -698,11 +724,12 @@ class HandleMenu(
/** A factory interface to create a [HandleMenu]. */
interface HandleMenuFactory {
    fun create(
        @ShellMainThread mainDispatcher: MainCoroutineDispatcher,
        @ShellBackgroundThread bgScope: CoroutineScope,
        parentDecor: DesktopModeWindowDecoration,
        windowManagerWrapper: WindowManagerWrapper,
        taskResourceLoader: WindowDecorTaskResourceLoader,
        layoutResId: Int,
        appIconBitmap: Bitmap?,
        appName: CharSequence?,
        splitScreenController: SplitScreenController,
        shouldShowWindowingPill: Boolean,
        shouldShowNewWindowButton: Boolean,
@@ -721,11 +748,12 @@ interface HandleMenuFactory {
/** A [HandleMenuFactory] implementation that creates a [HandleMenu].  */
object DefaultHandleMenuFactory : HandleMenuFactory {
    override fun create(
        @ShellMainThread mainDispatcher: MainCoroutineDispatcher,
        @ShellBackgroundThread bgScope: CoroutineScope,
        parentDecor: DesktopModeWindowDecoration,
        windowManagerWrapper: WindowManagerWrapper,
        taskResourceLoader: WindowDecorTaskResourceLoader,
        layoutResId: Int,
        appIconBitmap: Bitmap?,
        appName: CharSequence?,
        splitScreenController: SplitScreenController,
        shouldShowWindowingPill: Boolean,
        shouldShowNewWindowButton: Boolean,
@@ -740,11 +768,12 @@ object DefaultHandleMenuFactory : HandleMenuFactory {
        captionY: Int,
    ): HandleMenu {
        return HandleMenu(
            mainDispatcher,
            bgScope,
            parentDecor,
            windowManagerWrapper,
            taskResourceLoader,
            layoutResId,
            appIconBitmap,
            appName,
            splitScreenController,
            shouldShowWindowingPill,
            shouldShowNewWindowButton,
Loading