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

Commit 209f4816 authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 13548326 from 1d017d32 to 25Q3-release

Change-Id: Ie9df6921129cf5798ac6c6cf66d8367be44c33bd
parents ff35c9f5 1d017d32
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -64,6 +64,8 @@ public enum DesktopExperienceFlags {
    ENABLE_ACTIVITY_EMBEDDING_SUPPORT_FOR_CONNECTED_DISPLAYS(
            Flags::enableActivityEmbeddingSupportForConnectedDisplays, true,
            Flags.FLAG_ENABLE_ACTIVITY_EMBEDDING_SUPPORT_FOR_CONNECTED_DISPLAYS),
    ENABLE_APP_HANDLE_POSITION_REPORTING(Flags::enableAppHandlePositionReporting, false,
            Flags.FLAG_ENABLE_APP_HANDLE_POSITION_REPORTING),
    ENABLE_BLOCK_NON_DESKTOP_DISPLAY_WINDOW_DRAG_BUGFIX(
            Flags::enableBlockNonDesktopDisplayWindowDragBugfix, false,
            Flags.FLAG_ENABLE_BLOCK_NON_DESKTOP_DISPLAY_WINDOW_DRAG_BUGFIX),
+10 −0
Original line number Diff line number Diff line
@@ -1261,6 +1261,16 @@ flag {
    }
}

flag {
    name: "enable_app_handle_position_reporting"
    namespace: "lse_desktop_experience"
    description: "Report app handle position to the SysUi."
    bug: "412444130"
    metadata {
        purpose: PURPOSE_BUGFIX
    }
}

flag {
    name: "enable_desktop_app_launch_bugfix"
    namespace: "lse_desktop_experience"
+16 −14
Original line number Diff line number Diff line
@@ -123,7 +123,7 @@ import com.android.wm.shell.desktopmode.ReturnToDragStartAnimator;
import com.android.wm.shell.desktopmode.SpringDragToDesktopTransitionHandler;
import com.android.wm.shell.desktopmode.ToggleResizeDesktopTaskTransitionHandler;
import com.android.wm.shell.desktopmode.VisualIndicatorUpdateScheduler;
import com.android.wm.shell.desktopmode.WindowDecorCaptionHandleRepository;
import com.android.wm.shell.desktopmode.WindowDecorCaptionRepository;
import com.android.wm.shell.desktopmode.compatui.SystemModalsTransitionHandler;
import com.android.wm.shell.desktopmode.desktopfirst.DesktopDisplayModeController;
import com.android.wm.shell.desktopmode.desktopwallpaperactivity.DesktopWallpaperActivityTokenProvider;
@@ -1154,7 +1154,7 @@ public abstract class WMShellModule {
            AppHandleEducationController appHandleEducationController,
            AppToWebEducationController appToWebEducationController,
            AppHandleAndHeaderVisibilityHelper appHandleAndHeaderVisibilityHelper,
            WindowDecorCaptionHandleRepository windowDecorCaptionHandleRepository,
            WindowDecorCaptionRepository windowDecorCaptionRepository,
            Optional<DesktopActivityOrientationChangeHandler> activityOrientationChangeHandler,
            FocusTransitionObserver focusTransitionObserver,
            DesktopModeEventLogger desktopModeEventLogger,
@@ -1167,8 +1167,7 @@ public abstract class WMShellModule {
            Optional<CompatUIHandler> compatUI,
            DesksOrganizer desksOrganizer,
            DesktopState desktopState,
            DesktopConfig desktopConfig,
            AppHandleNotifier appHandleNotifier
            DesktopConfig desktopConfig
    ) {
        if (!desktopState.canEnterDesktopModeOrShowAppHandle()) {
            return Optional.empty();
@@ -1182,12 +1181,12 @@ public abstract class WMShellModule {
                rootTaskDisplayAreaOrganizer, interactionJankMonitor, genericLinksParser,
                assistContentRequester, windowDecorViewHostSupplier, multiInstanceHelper,
                desktopTasksLimiter, appHandleEducationController, appToWebEducationController,
                appHandleAndHeaderVisibilityHelper, windowDecorCaptionHandleRepository,
                appHandleAndHeaderVisibilityHelper, windowDecorCaptionRepository,
                activityOrientationChangeHandler, focusTransitionObserver, desktopModeEventLogger,
                desktopModeUiEventLogger, taskResourceLoader, recentsTransitionHandler,
                desktopModeCompatPolicy, desktopTilingDecorViewModel,
                multiDisplayDragMoveIndicatorController, compatUI.orElse(null),
                desksOrganizer, desktopState, desktopConfig, appHandleNotifier));
                desksOrganizer, desktopState, desktopConfig));
    }

    @WMSingleton
@@ -1525,8 +1524,11 @@ public abstract class WMShellModule {
    @WMSingleton
    @Provides
    static AppHandleNotifier provideAppHandleNotifier(
            @ShellMainThread ShellExecutor shellExecutor) {
        return new AppHandleNotifier(shellExecutor);
            @ShellMainThread ShellExecutor shellExecutor,
            WindowDecorCaptionRepository windowDecorCaptionRepository,
            @ShellMainThread CoroutineScope mainScope) {
        return new AppHandleNotifier(
                shellExecutor, windowDecorCaptionRepository, mainScope);
    }

    @WMSingleton
@@ -1546,8 +1548,8 @@ public abstract class WMShellModule {

    @WMSingleton
    @Provides
    static WindowDecorCaptionHandleRepository provideAppHandleRepository() {
        return new WindowDecorCaptionHandleRepository();
    static WindowDecorCaptionRepository provideAppHandleRepository() {
        return new WindowDecorCaptionRepository();
    }

    @WMSingleton
@@ -1582,7 +1584,7 @@ public abstract class WMShellModule {
            Context context,
            AppHandleEducationFilter appHandleEducationFilter,
            AppHandleEducationDatastoreRepository appHandleEducationDatastoreRepository,
            WindowDecorCaptionHandleRepository windowDecorCaptionHandleRepository,
            WindowDecorCaptionRepository windowDecorCaptionRepository,
            DesktopWindowingEducationTooltipController desktopWindowingEducationTooltipController,
            @ShellMainThread CoroutineScope applicationScope,
            @ShellBackgroundThread MainCoroutineDispatcher backgroundDispatcher,
@@ -1592,7 +1594,7 @@ public abstract class WMShellModule {
                context,
                appHandleEducationFilter,
                appHandleEducationDatastoreRepository,
                windowDecorCaptionHandleRepository,
                windowDecorCaptionRepository,
                desktopWindowingEducationTooltipController,
                applicationScope,
                backgroundDispatcher,
@@ -1622,13 +1624,13 @@ public abstract class WMShellModule {
            Context context,
            AppToWebEducationFilter appToWebEducationFilter,
            AppToWebEducationDatastoreRepository appToWebEducationDatastoreRepository,
            WindowDecorCaptionHandleRepository windowDecorCaptionHandleRepository,
            WindowDecorCaptionRepository windowDecorCaptionRepository,
            DesktopWindowingEducationPromoController desktopWindowingEducationPromoController,
            @ShellMainThread CoroutineScope applicationScope,
            @ShellBackgroundThread MainCoroutineDispatcher backgroundDispatcher,
            DesktopState desktopState) {
        return new AppToWebEducationController(context, appToWebEducationFilter,
                appToWebEducationDatastoreRepository, windowDecorCaptionHandleRepository,
                appToWebEducationDatastoreRepository, windowDecorCaptionRepository,
                desktopWindowingEducationPromoController, applicationScope,
                backgroundDispatcher, desktopState);
    }
+16 −4
Original line number Diff line number Diff line
@@ -21,13 +21,14 @@ import android.graphics.Rect
import com.android.wm.shell.desktopmode.CaptionState.AppHandle
import com.android.wm.shell.desktopmode.CaptionState.AppHeader
import com.android.wm.shell.desktopmode.CaptionState.NoCaption
import com.android.wm.shell.windowdecor.viewholder.AppHandleIdentifier
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow

/** Repository to observe caption state. */
class WindowDecorCaptionHandleRepository {
    private val _captionStateFlow = MutableStateFlow<CaptionState>(CaptionState.NoCaption)
class WindowDecorCaptionRepository {
    private val _captionStateFlow = MutableStateFlow<CaptionState>(NoCaption())
    /** Observer for app handle state changes. */
    val captionStateFlow: StateFlow<CaptionState> = _captionStateFlow
    private val _appToWebUsageFlow = MutableSharedFlow<Unit>()
@@ -51,14 +52,18 @@ class WindowDecorCaptionHandleRepository {
 * It can be one of three options:
 * * [AppHandle]: Indicating that there is at least one visible app handle on the screen.
 * * [AppHeader]: Indicating that there is at least one visible app chip on the screen.
 * * [NoCaption]: Signifying that no caption handle is currently visible on the device.
 * * [NoCaption]: Signifying that no caption handle visible for the given task.
 */
sealed class CaptionState {
    abstract val isFocused: Boolean

    data class AppHandle(
        val runningTaskInfo: RunningTaskInfo,
        val isHandleMenuExpanded: Boolean,
        val globalAppHandleBounds: Rect,
        val isCapturedLinkAvailable: Boolean,
        val appHandleIdentifier: AppHandleIdentifier,
        override val isFocused: Boolean,
    ) : CaptionState()

    data class AppHeader(
@@ -66,7 +71,14 @@ sealed class CaptionState {
        val isHeaderMenuExpanded: Boolean,
        val globalAppChipBounds: Rect,
        val isCapturedLinkAvailable: Boolean,
        override val isFocused: Boolean,
    ) : CaptionState()

    data object NoCaption : CaptionState()
    data class NoCaption(val taskId: Int = INVALID_TASK_ID) : CaptionState() {
        override val isFocused = false
    }

    private companion object {
        private const val INVALID_TASK_ID = -1
    }
}
+18 −8
Original line number Diff line number Diff line
@@ -23,16 +23,16 @@ import android.content.res.Resources
import android.graphics.Point
import android.os.SystemProperties
import android.view.View.LAYOUT_DIRECTION_RTL
import android.window.DesktopExperienceFlags
import com.android.window.flags.Flags
import com.android.wm.shell.R
import com.android.wm.shell.desktopmode.CaptionState
import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger
import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger.DesktopUiEventEnum
import com.android.wm.shell.desktopmode.WindowDecorCaptionHandleRepository
import com.android.wm.shell.desktopmode.WindowDecorCaptionRepository
import com.android.wm.shell.desktopmode.education.data.AppHandleEducationDatastoreRepository
import com.android.wm.shell.shared.annotations.ShellBackgroundThread
import com.android.wm.shell.shared.annotations.ShellMainThread
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus.canEnterDesktopMode
import com.android.wm.shell.shared.desktopmode.DesktopModeTransitionSource
import com.android.wm.shell.shared.desktopmode.DesktopState
import com.android.wm.shell.windowdecor.education.DesktopWindowingEducationTooltipController
@@ -61,7 +61,7 @@ class AppHandleEducationController(
    private val context: Context,
    private val appHandleEducationFilter: AppHandleEducationFilter,
    private val appHandleEducationDatastoreRepository: AppHandleEducationDatastoreRepository,
    private val windowDecorCaptionHandleRepository: WindowDecorCaptionHandleRepository,
    private val windowDecorCaptionRepository: WindowDecorCaptionRepository,
    private val windowingEducationViewController: DesktopWindowingEducationTooltipController,
    @ShellMainThread private val applicationCoroutineScope: CoroutineScope,
    @ShellBackgroundThread private val backgroundDispatcher: MainCoroutineDispatcher,
@@ -81,11 +81,12 @@ class AppHandleEducationController(
            // encourage users to open the app handle menu.
            applicationCoroutineScope.launch {
                if (isAppHandleHintViewed()) return@launch
                windowDecorCaptionHandleRepository.captionStateFlow
                windowDecorCaptionRepository.captionStateFlow
                    .debounce(APP_HANDLE_EDUCATION_DELAY_MILLIS)
                    .filter { captionState ->
                        captionState is CaptionState.AppHandle &&
                            !captionState.isHandleMenuExpanded &&
                            isCaptionFocused(captionState) &&
                            !isAppHandleHintViewed() &&
                            appHandleEducationFilter.shouldShowDesktopModeEducation(captionState)
                    }
@@ -104,11 +105,12 @@ class AppHandleEducationController(
            // encourage users to enter desktop mode.
            applicationCoroutineScope.launch {
                if (isEnterDesktopModeHintViewed()) return@launch
                windowDecorCaptionHandleRepository.captionStateFlow
                windowDecorCaptionRepository.captionStateFlow
                    .debounce(ENTER_DESKTOP_MODE_EDUCATION_DELAY_MILLIS)
                    .filter { captionState ->
                        captionState is CaptionState.AppHandle &&
                            captionState.isHandleMenuExpanded &&
                            isCaptionFocused(captionState) &&
                            !isEnterDesktopModeHintViewed() &&
                            appHandleEducationFilter.shouldShowDesktopModeEducation(captionState)
                    }
@@ -127,11 +129,12 @@ class AppHandleEducationController(
            // to let users know how to exit desktop mode.
            applicationCoroutineScope.launch {
                if (isExitDesktopModeHintViewed()) return@launch
                windowDecorCaptionHandleRepository.captionStateFlow
                windowDecorCaptionRepository.captionStateFlow
                    .debounce(APP_HANDLE_EDUCATION_DELAY_MILLIS)
                    .filter { captionState ->
                        captionState is CaptionState.AppHeader &&
                            !captionState.isHeaderMenuExpanded &&
                            isCaptionFocused(captionState) &&
                            !isExitDesktopModeHintViewed() &&
                            appHandleEducationFilter.shouldShowDesktopModeEducation(captionState)
                    }
@@ -156,9 +159,9 @@ class AppHandleEducationController(
                        isExitDesktopModeHintViewed()
                )
                    return@launch
                windowDecorCaptionHandleRepository.captionStateFlow
                windowDecorCaptionRepository.captionStateFlow
                    .filter { captionState ->
                        captionState is CaptionState.NoCaption &&
                        !isCaptionFocused(captionState) &&
                            !isAppHandleHintViewed() &&
                            !isEnterDesktopModeHintViewed() &&
                            !isExitDesktopModeHintViewed()
@@ -174,6 +177,13 @@ class AppHandleEducationController(
            block()
    }

    private fun isCaptionFocused(captionState: CaptionState) =
        if (!DesktopExperienceFlags.ENABLE_APP_HANDLE_POSITION_REPORTING.isTrue) {
            captionState !is CaptionState.NoCaption
        } else {
            captionState.isFocused
        }

    private fun showEducation(captionState: CaptionState) {
        val appHandleBounds = (captionState as CaptionState.AppHandle).globalAppHandleBounds
        val taskInfo = captionState.runningTaskInfo
Loading