Loading libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUiEventLogger.kt +29 −1 Original line number Diff line number Diff line Loading @@ -167,7 +167,35 @@ class DesktopModeUiEventLogger( @UiEvent(doc = "Exit desktop mode education tooltip on the app header menu is clicked") EXIT_DESKTOP_MODE_EDUCATION_TOOLTIP_CLICKED(2104), @UiEvent(doc = "Exit desktop mode education tooltip is dismissed by the user") EXIT_DESKTOP_MODE_EDUCATION_TOOLTIP_DISMISSED(2105); EXIT_DESKTOP_MODE_EDUCATION_TOOLTIP_DISMISSED(2105), @UiEvent(doc = "A11y service opened app handle menu by selecting handle from fullscreen") A11Y_APP_HANDLE_MENU_OPENED(2156), @UiEvent(doc = "A11y service opened app handle menu through Switch Access actions menu ") A11Y_SYSTEM_ACTION_APP_HANDLE_MENU(2157), @UiEvent(doc = "A11y service selected desktop mode from app handle menu") A11Y_APP_HANDLE_MENU_DESKTOP_VIEW(2158), @UiEvent(doc = "A11y service selected fullscreen mode from app handle menu") A11Y_APP_HANDLE_MENU_FULLSCREEN(2159), @UiEvent(doc = "A11y service selected split screen mode from app handle menu") A11Y_APP_HANDLE_MENU_SPLIT_SCREEN(2160), @UiEvent(doc = "A11y service selected maximize/restore button from app header") A11Y_APP_WINDOW_MAXIMIZE_RESTORE_BUTTON(2161), @UiEvent(doc = "A11y service selected minimize button from app header") A11Y_APP_WINDOW_MINIMIZE_BUTTON(2162), @UiEvent(doc = "A11y service selected close button from app header") A11Y_APP_WINDOW_CLOSE_BUTTON(2163), @UiEvent(doc = "A11y service selected maximize button from app header maximize menu") A11Y_MAXIMIZE_MENU_MAXIMIZE(2164), @UiEvent(doc = "A11y service selected resize left button from app header maximize menu") A11Y_MAXIMIZE_MENU_RESIZE_LEFT(2165), @UiEvent(doc = "A11y service selected resize right button from app header maximize menu") A11Y_MAXIMIZE_MENU_RESIZE_RIGHT(2166), @UiEvent(doc = "A11y service triggered a11y action to maximize/restore app window") A11Y_ACTION_MAXIMIZE_RESTORE(2167), @UiEvent(doc = "A11y service triggered a11y action to resize app window left") A11Y_ACTION_RESIZE_LEFT(2168), @UiEvent(doc = "A11y service triggered a11y action to resize app window right") A11Y_ACTION_RESIZE_RIGHT(2169); override fun getId(): Int = mId } Loading libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java +1 −0 Original line number Diff line number Diff line Loading @@ -1802,6 +1802,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel, mMultiInstanceHelper, mWindowDecorCaptionHandleRepository, mDesktopModeEventLogger, mDesktopModeUiEventLogger, mDesktopModeCompatPolicy); mWindowDecorByTaskId.put(taskInfo.taskId, windowDecoration); Loading libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java +15 −6 Original line number Diff line number Diff line Loading @@ -93,6 +93,7 @@ import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.desktopmode.CaptionState; import com.android.wm.shell.desktopmode.DesktopModeEventLogger; import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger; import com.android.wm.shell.desktopmode.DesktopModeUtils; import com.android.wm.shell.desktopmode.DesktopUserRepositories; import com.android.wm.shell.desktopmode.WindowDecorCaptionHandleRepository; Loading Loading @@ -211,6 +212,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin private final MultiInstanceHelper mMultiInstanceHelper; private final WindowDecorCaptionHandleRepository mWindowDecorCaptionHandleRepository; private final DesktopUserRepositories mDesktopUserRepositories; private final DesktopModeUiEventLogger mDesktopModeUiEventLogger; private boolean mIsRecentsTransitionRunning = false; private boolean mIsDragging = false; private Runnable mLoadAppInfoRunnable; Loading Loading @@ -243,6 +245,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin MultiInstanceHelper multiInstanceHelper, WindowDecorCaptionHandleRepository windowDecorCaptionHandleRepository, DesktopModeEventLogger desktopModeEventLogger, DesktopModeUiEventLogger desktopModeUiEventLogger, DesktopModeCompatPolicy desktopModeCompatPolicy) { this (context, userContext, displayController, taskResourceLoader, splitScreenController, desktopUserRepositories, taskOrganizer, taskInfo, taskSurface, handler, Loading @@ -257,7 +260,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin DefaultMaximizeMenuFactory.INSTANCE, DefaultHandleMenuFactory.INSTANCE, multiInstanceHelper, windowDecorCaptionHandleRepository, desktopModeEventLogger, desktopModeCompatPolicy); desktopModeUiEventLogger, desktopModeCompatPolicy); } DesktopModeWindowDecoration( Loading Loading @@ -294,6 +297,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin MultiInstanceHelper multiInstanceHelper, WindowDecorCaptionHandleRepository windowDecorCaptionHandleRepository, DesktopModeEventLogger desktopModeEventLogger, DesktopModeUiEventLogger desktopModeUiEventLogger, DesktopModeCompatPolicy desktopModeCompatPolicy) { super(context, userContext, displayController, taskOrganizer, taskInfo, taskSurface, surfaceControlBuilderSupplier, surfaceControlTransactionSupplier, Loading Loading @@ -321,6 +325,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin mTaskResourceLoader = taskResourceLoader; mTaskResourceLoader.onWindowDecorCreated(taskInfo); mDesktopModeCompatPolicy = desktopModeCompatPolicy; mDesktopModeUiEventLogger = desktopModeUiEventLogger; } /** Loading Loading @@ -895,10 +900,10 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin mOnCaptionTouchListener, mOnCaptionButtonClickListener, mWindowManagerWrapper, mHandler mHandler, mDesktopModeUiEventLogger ); } else if (mRelayoutParams.mLayoutResId == R.layout.desktop_mode_app_header) { } else if (mRelayoutParams.mLayoutResId == R.layout.desktop_mode_app_header) { return mAppHeaderViewHolderFactory.create( mResult.mRootView, mOnCaptionTouchListener, Loading @@ -908,7 +913,8 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin mOnLeftSnapClickListener, mOnRightSnapClickListener, mOnMaximizeOrRestoreClickListener, mOnMaximizeHoverListener); mOnMaximizeHoverListener, mDesktopModeUiEventLogger); } throw new IllegalArgumentException("Unexpected layout resource id"); } Loading Loading @@ -1372,7 +1378,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin mMaximizeMenu = mMaximizeMenuFactory.create(mSyncQueue, mRootTaskDisplayAreaOrganizer, mDisplayController, mTaskInfo, mContext, (width, height) -> calculateMaximizeMenuPosition(width, height), mSurfaceControlTransactionSupplier); mSurfaceControlTransactionSupplier, mDesktopModeUiEventLogger); mMaximizeMenu.show( /* isTaskInImmersiveMode= */ Loading Loading @@ -1488,6 +1494,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin shouldShowRestartButton, isBrowserApp, isBrowserApp ? getAppLink() : getBrowserLink(), mDesktopModeUiEventLogger, mResult.mCaptionWidth, mResult.mCaptionHeight, mResult.mCaptionX, Loading Loading @@ -1973,6 +1980,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin MultiInstanceHelper multiInstanceHelper, WindowDecorCaptionHandleRepository windowDecorCaptionHandleRepository, DesktopModeEventLogger desktopModeEventLogger, DesktopModeUiEventLogger desktopModeUiEventLogger, DesktopModeCompatPolicy desktopModeCompatPolicy) { return new DesktopModeWindowDecoration( context, Loading Loading @@ -2000,6 +2008,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin multiInstanceHelper, windowDecorCaptionHandleRepository, desktopModeEventLogger, desktopModeUiEventLogger, desktopModeCompatPolicy); } } Loading libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.kt +51 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import android.graphics.Bitmap import android.graphics.Point import android.graphics.PointF import android.graphics.Rect import android.os.Bundle import android.view.LayoutInflater import android.view.MotionEvent import android.view.MotionEvent.ACTION_OUTSIDE Loading @@ -35,6 +36,7 @@ import android.view.SurfaceControl import android.view.View import android.view.WindowInsets.Type.systemBars import android.view.WindowManager import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction import android.widget.ImageButton import android.widget.ImageView import android.widget.Space Loading @@ -49,6 +51,10 @@ import androidx.core.view.isGone import com.android.window.flags.Flags import com.android.wm.shell.R import com.android.wm.shell.bubbles.ContextUtils.isRtl import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger.DesktopUiEventEnum.A11Y_APP_HANDLE_MENU_DESKTOP_VIEW import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger.DesktopUiEventEnum.A11Y_APP_HANDLE_MENU_FULLSCREEN import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger.DesktopUiEventEnum.A11Y_APP_HANDLE_MENU_SPLIT_SCREEN import com.android.wm.shell.shared.annotations.ShellBackgroundThread import com.android.wm.shell.shared.annotations.ShellMainThread import com.android.wm.shell.shared.bubbles.BubbleAnythingFlagHelper Loading Loading @@ -97,6 +103,7 @@ class HandleMenu( private val shouldShowRestartButton: Boolean, private val isBrowserApp: Boolean, private val openInAppOrBrowserIntent: Intent?, private val desktopModeUiEventLogger: DesktopModeUiEventLogger, private val captionWidth: Int, private val captionHeight: Int, captionX: Int, Loading Loading @@ -208,6 +215,7 @@ class HandleMenu( ) { val handleMenuView = HandleMenuView( context = context, desktopModeUiEventLogger = desktopModeUiEventLogger, menuWidth = menuWidth, captionHeight = captionHeight, shouldShowWindowingPill = shouldShowWindowingPill, Loading Loading @@ -475,6 +483,7 @@ class HandleMenu( @SuppressLint("ClickableViewAccessibility") class HandleMenuView( private val context: Context, private val desktopModeUiEventLogger: DesktopModeUiEventLogger, menuWidth: Int, captionHeight: Int, private val shouldShowWindowingPill: Boolean, Loading Loading @@ -615,6 +624,45 @@ class HandleMenu( return@setOnTouchListener true } desktopBtn.accessibilityDelegate = object : View.AccessibilityDelegate() { override fun performAccessibilityAction( host: View, action: Int, args: Bundle? ): Boolean { if (action == AccessibilityAction.ACTION_CLICK.id) { desktopModeUiEventLogger.log(taskInfo, A11Y_APP_HANDLE_MENU_DESKTOP_VIEW) } return super.performAccessibilityAction(host, action, args) } } fullscreenBtn.accessibilityDelegate = object : View.AccessibilityDelegate() { override fun performAccessibilityAction( host: View, action: Int, args: Bundle? ): Boolean { if (action == AccessibilityAction.ACTION_CLICK.id) { desktopModeUiEventLogger.log(taskInfo, A11Y_APP_HANDLE_MENU_FULLSCREEN) } return super.performAccessibilityAction(host, action, args) } } splitscreenBtn.accessibilityDelegate = object : View.AccessibilityDelegate() { override fun performAccessibilityAction( host: View, action: Int, args: Bundle? ): Boolean { if (action == AccessibilityAction.ACTION_CLICK.id) { desktopModeUiEventLogger.log(taskInfo, A11Y_APP_HANDLE_MENU_SPLIT_SCREEN) } return super.performAccessibilityAction(host, action, args) } } with(context) { // Update a11y announcement out to say "double tap to enter Fullscreen" ViewCompat.replaceAccessibilityAction( Loading Loading @@ -917,6 +965,7 @@ interface HandleMenuFactory { shouldShowRestartButton: Boolean, isBrowserApp: Boolean, openInAppOrBrowserIntent: Intent?, desktopModeUiEventLogger: DesktopModeUiEventLogger, captionWidth: Int, captionHeight: Int, captionX: Int, Loading @@ -942,6 +991,7 @@ object DefaultHandleMenuFactory : HandleMenuFactory { shouldShowRestartButton: Boolean, isBrowserApp: Boolean, openInAppOrBrowserIntent: Intent?, desktopModeUiEventLogger: DesktopModeUiEventLogger, captionWidth: Int, captionHeight: Int, captionX: Int, Loading @@ -963,6 +1013,7 @@ object DefaultHandleMenuFactory : HandleMenuFactory { shouldShowRestartButton, isBrowserApp, openInAppOrBrowserIntent, desktopModeUiEventLogger, captionWidth, captionHeight, captionX, Loading libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MaximizeMenu.kt +43 −46 Original line number Diff line number Diff line Loading @@ -60,14 +60,16 @@ import android.window.TaskConstants import androidx.compose.material3.ColorScheme import androidx.compose.ui.graphics.toArgb import androidx.core.animation.addListener import androidx.core.view.ViewCompat import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat import androidx.core.view.isGone import androidx.core.view.isVisible import com.android.wm.shell.R import com.android.wm.shell.RootTaskDisplayAreaOrganizer import com.android.wm.shell.common.DisplayController import com.android.wm.shell.common.SyncTransactionQueue import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger.DesktopUiEventEnum.A11Y_MAXIMIZE_MENU_MAXIMIZE import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger.DesktopUiEventEnum.A11Y_MAXIMIZE_MENU_RESIZE_LEFT import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger.DesktopUiEventEnum.A11Y_MAXIMIZE_MENU_RESIZE_RIGHT import com.android.wm.shell.desktopmode.isTaskMaximized import com.android.wm.shell.shared.animation.Interpolators.EMPHASIZED_DECELERATE import com.android.wm.shell.shared.animation.Interpolators.FAST_OUT_LINEAR_IN Loading @@ -91,7 +93,8 @@ class MaximizeMenu( private val taskInfo: RunningTaskInfo, private val decorWindowContext: Context, private val positionSupplier: (Int, Int) -> Point, private val transactionSupplier: Supplier<Transaction> = Supplier { Transaction() } private val transactionSupplier: Supplier<Transaction> = Supplier { Transaction() }, private val desktopModeUiEventLogger: DesktopModeUiEventLogger ) { private var maximizeMenu: AdditionalViewHostViewContainer? = null private var maximizeMenuView: MaximizeMenuView? = null Loading Loading @@ -132,7 +135,7 @@ class MaximizeMenu( onLeftSnapClickListener = onLeftSnapClickListener, onRightSnapClickListener = onRightSnapClickListener, onHoverListener = onHoverListener, onOutsideTouchListener = onOutsideTouchListener onOutsideTouchListener = onOutsideTouchListener, ) maximizeMenuView?.let { view -> view.animateOpenMenu(onEnd = { Loading Loading @@ -167,7 +170,7 @@ class MaximizeMenu( onLeftSnapClickListener: () -> Unit, onRightSnapClickListener: () -> Unit, onHoverListener: (Boolean) -> Unit, onOutsideTouchListener: () -> Unit onOutsideTouchListener: () -> Unit, ) { val t = transactionSupplier.get() val builder = SurfaceControl.Builder() Loading @@ -186,6 +189,7 @@ class MaximizeMenu( "MaximizeMenu") maximizeMenuView = MaximizeMenuView( context = decorWindowContext, desktopModeUiEventLogger = desktopModeUiEventLogger, sizeToggleDirection = getSizeToggleDirection(), immersiveConfig = if (showImmersiveOption) { MaximizeMenuView.ImmersiveConfig.Visible( Loading Loading @@ -265,6 +269,7 @@ class MaximizeMenu( */ class MaximizeMenuView( context: Context, private val desktopModeUiEventLogger: DesktopModeUiEventLogger, private val sizeToggleDirection: SizeToggleDirection, immersiveConfig: ImmersiveConfig, showSnapOptions: Boolean, Loading Loading @@ -425,7 +430,10 @@ class MaximizeMenu( ) { super.onInitializeAccessibilityNodeInfo(host, info) info.addAction(AccessibilityAction.ACTION_CLICK) info.addAction(AccessibilityAction( AccessibilityAction.ACTION_CLICK.id, context.getString(R.string.maximize_menu_talkback_action_maximize_restore_text) )) host.isClickable = true } Loading @@ -435,6 +443,7 @@ class MaximizeMenu( args: Bundle? ): Boolean { if (action == AccessibilityAction.ACTION_CLICK.id) { desktopModeUiEventLogger.log(taskInfo, A11Y_MAXIMIZE_MENU_MAXIMIZE) onMaximizeClickListener?.invoke() } return super.performAccessibilityAction(host, action, args) Loading @@ -447,7 +456,10 @@ class MaximizeMenu( info: AccessibilityNodeInfo ) { super.onInitializeAccessibilityNodeInfo(host, info) info.addAction(AccessibilityAction.ACTION_CLICK) info.addAction(AccessibilityAction( AccessibilityAction.ACTION_CLICK.id, context.getString(R.string.maximize_menu_talkback_action_snap_left_text) )) host.isClickable = true } Loading @@ -457,6 +469,7 @@ class MaximizeMenu( args: Bundle? ): Boolean { if (action == AccessibilityAction.ACTION_CLICK.id) { desktopModeUiEventLogger.log(taskInfo, A11Y_MAXIMIZE_MENU_RESIZE_LEFT) onLeftSnapClickListener?.invoke() } return super.performAccessibilityAction(host, action, args) Loading @@ -469,7 +482,10 @@ class MaximizeMenu( info: AccessibilityNodeInfo ) { super.onInitializeAccessibilityNodeInfo(host, info) info.addAction(AccessibilityAction.ACTION_CLICK) info.addAction(AccessibilityAction( AccessibilityAction.ACTION_CLICK.id, context.getString(R.string.maximize_menu_talkback_action_snap_right_text) )) host.isClickable = true } Loading @@ -479,35 +495,13 @@ class MaximizeMenu( args: Bundle? ): Boolean { if (action == AccessibilityAction.ACTION_CLICK.id) { desktopModeUiEventLogger.log(taskInfo, A11Y_MAXIMIZE_MENU_RESIZE_RIGHT) onRightSnapClickListener?.invoke() } return super.performAccessibilityAction(host, action, args) } } with(context.resources) { ViewCompat.replaceAccessibilityAction( snapLeftButton, AccessibilityActionCompat.ACTION_CLICK, getString(R.string.maximize_menu_talkback_action_snap_left_text), null ) ViewCompat.replaceAccessibilityAction( snapRightButton, AccessibilityActionCompat.ACTION_CLICK, getString(R.string.maximize_menu_talkback_action_snap_right_text), null ) ViewCompat.replaceAccessibilityAction( sizeToggleButton, AccessibilityActionCompat.ACTION_CLICK, getString(R.string.maximize_menu_talkback_action_maximize_restore_text), null ) } // Maximize/restore button. val sizeToggleBtnTextId = if (sizeToggleDirection == SizeToggleDirection.RESTORE) R.string.desktop_mode_maximize_menu_restore_button_text Loading Loading @@ -793,14 +787,14 @@ class MaximizeMenu( /** Measure width of the root view of this menu. */ fun measureWidth(): Int { rootView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED); return rootView.getMeasuredWidth() rootView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED) return rootView.measuredWidth } /** Measure height of the root view of this menu. */ fun measureHeight(): Int { rootView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED); return rootView.getMeasuredHeight() rootView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED) return rootView.measuredHeight } private fun deactivateSnapOptions() { Loading Loading @@ -1048,7 +1042,8 @@ interface MaximizeMenuFactory { taskInfo: RunningTaskInfo, decorWindowContext: Context, positionSupplier: (Int, Int) -> Point, transactionSupplier: Supplier<Transaction> transactionSupplier: Supplier<Transaction>, desktopModeUiEventLogger: DesktopModeUiEventLogger, ): MaximizeMenu } Loading @@ -1061,7 +1056,8 @@ object DefaultMaximizeMenuFactory : MaximizeMenuFactory { taskInfo: RunningTaskInfo, decorWindowContext: Context, positionSupplier: (Int, Int) -> Point, transactionSupplier: Supplier<Transaction> transactionSupplier: Supplier<Transaction>, desktopModeUiEventLogger: DesktopModeUiEventLogger, ): MaximizeMenu { return MaximizeMenu( syncQueue, Loading @@ -1070,7 +1066,8 @@ object DefaultMaximizeMenuFactory : MaximizeMenuFactory { taskInfo, decorWindowContext, positionSupplier, transactionSupplier transactionSupplier, desktopModeUiEventLogger ) } } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUiEventLogger.kt +29 −1 Original line number Diff line number Diff line Loading @@ -167,7 +167,35 @@ class DesktopModeUiEventLogger( @UiEvent(doc = "Exit desktop mode education tooltip on the app header menu is clicked") EXIT_DESKTOP_MODE_EDUCATION_TOOLTIP_CLICKED(2104), @UiEvent(doc = "Exit desktop mode education tooltip is dismissed by the user") EXIT_DESKTOP_MODE_EDUCATION_TOOLTIP_DISMISSED(2105); EXIT_DESKTOP_MODE_EDUCATION_TOOLTIP_DISMISSED(2105), @UiEvent(doc = "A11y service opened app handle menu by selecting handle from fullscreen") A11Y_APP_HANDLE_MENU_OPENED(2156), @UiEvent(doc = "A11y service opened app handle menu through Switch Access actions menu ") A11Y_SYSTEM_ACTION_APP_HANDLE_MENU(2157), @UiEvent(doc = "A11y service selected desktop mode from app handle menu") A11Y_APP_HANDLE_MENU_DESKTOP_VIEW(2158), @UiEvent(doc = "A11y service selected fullscreen mode from app handle menu") A11Y_APP_HANDLE_MENU_FULLSCREEN(2159), @UiEvent(doc = "A11y service selected split screen mode from app handle menu") A11Y_APP_HANDLE_MENU_SPLIT_SCREEN(2160), @UiEvent(doc = "A11y service selected maximize/restore button from app header") A11Y_APP_WINDOW_MAXIMIZE_RESTORE_BUTTON(2161), @UiEvent(doc = "A11y service selected minimize button from app header") A11Y_APP_WINDOW_MINIMIZE_BUTTON(2162), @UiEvent(doc = "A11y service selected close button from app header") A11Y_APP_WINDOW_CLOSE_BUTTON(2163), @UiEvent(doc = "A11y service selected maximize button from app header maximize menu") A11Y_MAXIMIZE_MENU_MAXIMIZE(2164), @UiEvent(doc = "A11y service selected resize left button from app header maximize menu") A11Y_MAXIMIZE_MENU_RESIZE_LEFT(2165), @UiEvent(doc = "A11y service selected resize right button from app header maximize menu") A11Y_MAXIMIZE_MENU_RESIZE_RIGHT(2166), @UiEvent(doc = "A11y service triggered a11y action to maximize/restore app window") A11Y_ACTION_MAXIMIZE_RESTORE(2167), @UiEvent(doc = "A11y service triggered a11y action to resize app window left") A11Y_ACTION_RESIZE_LEFT(2168), @UiEvent(doc = "A11y service triggered a11y action to resize app window right") A11Y_ACTION_RESIZE_RIGHT(2169); override fun getId(): Int = mId } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java +1 −0 Original line number Diff line number Diff line Loading @@ -1802,6 +1802,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel, mMultiInstanceHelper, mWindowDecorCaptionHandleRepository, mDesktopModeEventLogger, mDesktopModeUiEventLogger, mDesktopModeCompatPolicy); mWindowDecorByTaskId.put(taskInfo.taskId, windowDecoration); Loading
libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java +15 −6 Original line number Diff line number Diff line Loading @@ -93,6 +93,7 @@ import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.desktopmode.CaptionState; import com.android.wm.shell.desktopmode.DesktopModeEventLogger; import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger; import com.android.wm.shell.desktopmode.DesktopModeUtils; import com.android.wm.shell.desktopmode.DesktopUserRepositories; import com.android.wm.shell.desktopmode.WindowDecorCaptionHandleRepository; Loading Loading @@ -211,6 +212,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin private final MultiInstanceHelper mMultiInstanceHelper; private final WindowDecorCaptionHandleRepository mWindowDecorCaptionHandleRepository; private final DesktopUserRepositories mDesktopUserRepositories; private final DesktopModeUiEventLogger mDesktopModeUiEventLogger; private boolean mIsRecentsTransitionRunning = false; private boolean mIsDragging = false; private Runnable mLoadAppInfoRunnable; Loading Loading @@ -243,6 +245,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin MultiInstanceHelper multiInstanceHelper, WindowDecorCaptionHandleRepository windowDecorCaptionHandleRepository, DesktopModeEventLogger desktopModeEventLogger, DesktopModeUiEventLogger desktopModeUiEventLogger, DesktopModeCompatPolicy desktopModeCompatPolicy) { this (context, userContext, displayController, taskResourceLoader, splitScreenController, desktopUserRepositories, taskOrganizer, taskInfo, taskSurface, handler, Loading @@ -257,7 +260,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin DefaultMaximizeMenuFactory.INSTANCE, DefaultHandleMenuFactory.INSTANCE, multiInstanceHelper, windowDecorCaptionHandleRepository, desktopModeEventLogger, desktopModeCompatPolicy); desktopModeUiEventLogger, desktopModeCompatPolicy); } DesktopModeWindowDecoration( Loading Loading @@ -294,6 +297,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin MultiInstanceHelper multiInstanceHelper, WindowDecorCaptionHandleRepository windowDecorCaptionHandleRepository, DesktopModeEventLogger desktopModeEventLogger, DesktopModeUiEventLogger desktopModeUiEventLogger, DesktopModeCompatPolicy desktopModeCompatPolicy) { super(context, userContext, displayController, taskOrganizer, taskInfo, taskSurface, surfaceControlBuilderSupplier, surfaceControlTransactionSupplier, Loading Loading @@ -321,6 +325,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin mTaskResourceLoader = taskResourceLoader; mTaskResourceLoader.onWindowDecorCreated(taskInfo); mDesktopModeCompatPolicy = desktopModeCompatPolicy; mDesktopModeUiEventLogger = desktopModeUiEventLogger; } /** Loading Loading @@ -895,10 +900,10 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin mOnCaptionTouchListener, mOnCaptionButtonClickListener, mWindowManagerWrapper, mHandler mHandler, mDesktopModeUiEventLogger ); } else if (mRelayoutParams.mLayoutResId == R.layout.desktop_mode_app_header) { } else if (mRelayoutParams.mLayoutResId == R.layout.desktop_mode_app_header) { return mAppHeaderViewHolderFactory.create( mResult.mRootView, mOnCaptionTouchListener, Loading @@ -908,7 +913,8 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin mOnLeftSnapClickListener, mOnRightSnapClickListener, mOnMaximizeOrRestoreClickListener, mOnMaximizeHoverListener); mOnMaximizeHoverListener, mDesktopModeUiEventLogger); } throw new IllegalArgumentException("Unexpected layout resource id"); } Loading Loading @@ -1372,7 +1378,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin mMaximizeMenu = mMaximizeMenuFactory.create(mSyncQueue, mRootTaskDisplayAreaOrganizer, mDisplayController, mTaskInfo, mContext, (width, height) -> calculateMaximizeMenuPosition(width, height), mSurfaceControlTransactionSupplier); mSurfaceControlTransactionSupplier, mDesktopModeUiEventLogger); mMaximizeMenu.show( /* isTaskInImmersiveMode= */ Loading Loading @@ -1488,6 +1494,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin shouldShowRestartButton, isBrowserApp, isBrowserApp ? getAppLink() : getBrowserLink(), mDesktopModeUiEventLogger, mResult.mCaptionWidth, mResult.mCaptionHeight, mResult.mCaptionX, Loading Loading @@ -1973,6 +1980,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin MultiInstanceHelper multiInstanceHelper, WindowDecorCaptionHandleRepository windowDecorCaptionHandleRepository, DesktopModeEventLogger desktopModeEventLogger, DesktopModeUiEventLogger desktopModeUiEventLogger, DesktopModeCompatPolicy desktopModeCompatPolicy) { return new DesktopModeWindowDecoration( context, Loading Loading @@ -2000,6 +2008,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin multiInstanceHelper, windowDecorCaptionHandleRepository, desktopModeEventLogger, desktopModeUiEventLogger, desktopModeCompatPolicy); } } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.kt +51 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import android.graphics.Bitmap import android.graphics.Point import android.graphics.PointF import android.graphics.Rect import android.os.Bundle import android.view.LayoutInflater import android.view.MotionEvent import android.view.MotionEvent.ACTION_OUTSIDE Loading @@ -35,6 +36,7 @@ import android.view.SurfaceControl import android.view.View import android.view.WindowInsets.Type.systemBars import android.view.WindowManager import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction import android.widget.ImageButton import android.widget.ImageView import android.widget.Space Loading @@ -49,6 +51,10 @@ import androidx.core.view.isGone import com.android.window.flags.Flags import com.android.wm.shell.R import com.android.wm.shell.bubbles.ContextUtils.isRtl import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger.DesktopUiEventEnum.A11Y_APP_HANDLE_MENU_DESKTOP_VIEW import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger.DesktopUiEventEnum.A11Y_APP_HANDLE_MENU_FULLSCREEN import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger.DesktopUiEventEnum.A11Y_APP_HANDLE_MENU_SPLIT_SCREEN import com.android.wm.shell.shared.annotations.ShellBackgroundThread import com.android.wm.shell.shared.annotations.ShellMainThread import com.android.wm.shell.shared.bubbles.BubbleAnythingFlagHelper Loading Loading @@ -97,6 +103,7 @@ class HandleMenu( private val shouldShowRestartButton: Boolean, private val isBrowserApp: Boolean, private val openInAppOrBrowserIntent: Intent?, private val desktopModeUiEventLogger: DesktopModeUiEventLogger, private val captionWidth: Int, private val captionHeight: Int, captionX: Int, Loading Loading @@ -208,6 +215,7 @@ class HandleMenu( ) { val handleMenuView = HandleMenuView( context = context, desktopModeUiEventLogger = desktopModeUiEventLogger, menuWidth = menuWidth, captionHeight = captionHeight, shouldShowWindowingPill = shouldShowWindowingPill, Loading Loading @@ -475,6 +483,7 @@ class HandleMenu( @SuppressLint("ClickableViewAccessibility") class HandleMenuView( private val context: Context, private val desktopModeUiEventLogger: DesktopModeUiEventLogger, menuWidth: Int, captionHeight: Int, private val shouldShowWindowingPill: Boolean, Loading Loading @@ -615,6 +624,45 @@ class HandleMenu( return@setOnTouchListener true } desktopBtn.accessibilityDelegate = object : View.AccessibilityDelegate() { override fun performAccessibilityAction( host: View, action: Int, args: Bundle? ): Boolean { if (action == AccessibilityAction.ACTION_CLICK.id) { desktopModeUiEventLogger.log(taskInfo, A11Y_APP_HANDLE_MENU_DESKTOP_VIEW) } return super.performAccessibilityAction(host, action, args) } } fullscreenBtn.accessibilityDelegate = object : View.AccessibilityDelegate() { override fun performAccessibilityAction( host: View, action: Int, args: Bundle? ): Boolean { if (action == AccessibilityAction.ACTION_CLICK.id) { desktopModeUiEventLogger.log(taskInfo, A11Y_APP_HANDLE_MENU_FULLSCREEN) } return super.performAccessibilityAction(host, action, args) } } splitscreenBtn.accessibilityDelegate = object : View.AccessibilityDelegate() { override fun performAccessibilityAction( host: View, action: Int, args: Bundle? ): Boolean { if (action == AccessibilityAction.ACTION_CLICK.id) { desktopModeUiEventLogger.log(taskInfo, A11Y_APP_HANDLE_MENU_SPLIT_SCREEN) } return super.performAccessibilityAction(host, action, args) } } with(context) { // Update a11y announcement out to say "double tap to enter Fullscreen" ViewCompat.replaceAccessibilityAction( Loading Loading @@ -917,6 +965,7 @@ interface HandleMenuFactory { shouldShowRestartButton: Boolean, isBrowserApp: Boolean, openInAppOrBrowserIntent: Intent?, desktopModeUiEventLogger: DesktopModeUiEventLogger, captionWidth: Int, captionHeight: Int, captionX: Int, Loading @@ -942,6 +991,7 @@ object DefaultHandleMenuFactory : HandleMenuFactory { shouldShowRestartButton: Boolean, isBrowserApp: Boolean, openInAppOrBrowserIntent: Intent?, desktopModeUiEventLogger: DesktopModeUiEventLogger, captionWidth: Int, captionHeight: Int, captionX: Int, Loading @@ -963,6 +1013,7 @@ object DefaultHandleMenuFactory : HandleMenuFactory { shouldShowRestartButton, isBrowserApp, openInAppOrBrowserIntent, desktopModeUiEventLogger, captionWidth, captionHeight, captionX, Loading
libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MaximizeMenu.kt +43 −46 Original line number Diff line number Diff line Loading @@ -60,14 +60,16 @@ import android.window.TaskConstants import androidx.compose.material3.ColorScheme import androidx.compose.ui.graphics.toArgb import androidx.core.animation.addListener import androidx.core.view.ViewCompat import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat import androidx.core.view.isGone import androidx.core.view.isVisible import com.android.wm.shell.R import com.android.wm.shell.RootTaskDisplayAreaOrganizer import com.android.wm.shell.common.DisplayController import com.android.wm.shell.common.SyncTransactionQueue import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger.DesktopUiEventEnum.A11Y_MAXIMIZE_MENU_MAXIMIZE import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger.DesktopUiEventEnum.A11Y_MAXIMIZE_MENU_RESIZE_LEFT import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger.DesktopUiEventEnum.A11Y_MAXIMIZE_MENU_RESIZE_RIGHT import com.android.wm.shell.desktopmode.isTaskMaximized import com.android.wm.shell.shared.animation.Interpolators.EMPHASIZED_DECELERATE import com.android.wm.shell.shared.animation.Interpolators.FAST_OUT_LINEAR_IN Loading @@ -91,7 +93,8 @@ class MaximizeMenu( private val taskInfo: RunningTaskInfo, private val decorWindowContext: Context, private val positionSupplier: (Int, Int) -> Point, private val transactionSupplier: Supplier<Transaction> = Supplier { Transaction() } private val transactionSupplier: Supplier<Transaction> = Supplier { Transaction() }, private val desktopModeUiEventLogger: DesktopModeUiEventLogger ) { private var maximizeMenu: AdditionalViewHostViewContainer? = null private var maximizeMenuView: MaximizeMenuView? = null Loading Loading @@ -132,7 +135,7 @@ class MaximizeMenu( onLeftSnapClickListener = onLeftSnapClickListener, onRightSnapClickListener = onRightSnapClickListener, onHoverListener = onHoverListener, onOutsideTouchListener = onOutsideTouchListener onOutsideTouchListener = onOutsideTouchListener, ) maximizeMenuView?.let { view -> view.animateOpenMenu(onEnd = { Loading Loading @@ -167,7 +170,7 @@ class MaximizeMenu( onLeftSnapClickListener: () -> Unit, onRightSnapClickListener: () -> Unit, onHoverListener: (Boolean) -> Unit, onOutsideTouchListener: () -> Unit onOutsideTouchListener: () -> Unit, ) { val t = transactionSupplier.get() val builder = SurfaceControl.Builder() Loading @@ -186,6 +189,7 @@ class MaximizeMenu( "MaximizeMenu") maximizeMenuView = MaximizeMenuView( context = decorWindowContext, desktopModeUiEventLogger = desktopModeUiEventLogger, sizeToggleDirection = getSizeToggleDirection(), immersiveConfig = if (showImmersiveOption) { MaximizeMenuView.ImmersiveConfig.Visible( Loading Loading @@ -265,6 +269,7 @@ class MaximizeMenu( */ class MaximizeMenuView( context: Context, private val desktopModeUiEventLogger: DesktopModeUiEventLogger, private val sizeToggleDirection: SizeToggleDirection, immersiveConfig: ImmersiveConfig, showSnapOptions: Boolean, Loading Loading @@ -425,7 +430,10 @@ class MaximizeMenu( ) { super.onInitializeAccessibilityNodeInfo(host, info) info.addAction(AccessibilityAction.ACTION_CLICK) info.addAction(AccessibilityAction( AccessibilityAction.ACTION_CLICK.id, context.getString(R.string.maximize_menu_talkback_action_maximize_restore_text) )) host.isClickable = true } Loading @@ -435,6 +443,7 @@ class MaximizeMenu( args: Bundle? ): Boolean { if (action == AccessibilityAction.ACTION_CLICK.id) { desktopModeUiEventLogger.log(taskInfo, A11Y_MAXIMIZE_MENU_MAXIMIZE) onMaximizeClickListener?.invoke() } return super.performAccessibilityAction(host, action, args) Loading @@ -447,7 +456,10 @@ class MaximizeMenu( info: AccessibilityNodeInfo ) { super.onInitializeAccessibilityNodeInfo(host, info) info.addAction(AccessibilityAction.ACTION_CLICK) info.addAction(AccessibilityAction( AccessibilityAction.ACTION_CLICK.id, context.getString(R.string.maximize_menu_talkback_action_snap_left_text) )) host.isClickable = true } Loading @@ -457,6 +469,7 @@ class MaximizeMenu( args: Bundle? ): Boolean { if (action == AccessibilityAction.ACTION_CLICK.id) { desktopModeUiEventLogger.log(taskInfo, A11Y_MAXIMIZE_MENU_RESIZE_LEFT) onLeftSnapClickListener?.invoke() } return super.performAccessibilityAction(host, action, args) Loading @@ -469,7 +482,10 @@ class MaximizeMenu( info: AccessibilityNodeInfo ) { super.onInitializeAccessibilityNodeInfo(host, info) info.addAction(AccessibilityAction.ACTION_CLICK) info.addAction(AccessibilityAction( AccessibilityAction.ACTION_CLICK.id, context.getString(R.string.maximize_menu_talkback_action_snap_right_text) )) host.isClickable = true } Loading @@ -479,35 +495,13 @@ class MaximizeMenu( args: Bundle? ): Boolean { if (action == AccessibilityAction.ACTION_CLICK.id) { desktopModeUiEventLogger.log(taskInfo, A11Y_MAXIMIZE_MENU_RESIZE_RIGHT) onRightSnapClickListener?.invoke() } return super.performAccessibilityAction(host, action, args) } } with(context.resources) { ViewCompat.replaceAccessibilityAction( snapLeftButton, AccessibilityActionCompat.ACTION_CLICK, getString(R.string.maximize_menu_talkback_action_snap_left_text), null ) ViewCompat.replaceAccessibilityAction( snapRightButton, AccessibilityActionCompat.ACTION_CLICK, getString(R.string.maximize_menu_talkback_action_snap_right_text), null ) ViewCompat.replaceAccessibilityAction( sizeToggleButton, AccessibilityActionCompat.ACTION_CLICK, getString(R.string.maximize_menu_talkback_action_maximize_restore_text), null ) } // Maximize/restore button. val sizeToggleBtnTextId = if (sizeToggleDirection == SizeToggleDirection.RESTORE) R.string.desktop_mode_maximize_menu_restore_button_text Loading Loading @@ -793,14 +787,14 @@ class MaximizeMenu( /** Measure width of the root view of this menu. */ fun measureWidth(): Int { rootView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED); return rootView.getMeasuredWidth() rootView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED) return rootView.measuredWidth } /** Measure height of the root view of this menu. */ fun measureHeight(): Int { rootView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED); return rootView.getMeasuredHeight() rootView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED) return rootView.measuredHeight } private fun deactivateSnapOptions() { Loading Loading @@ -1048,7 +1042,8 @@ interface MaximizeMenuFactory { taskInfo: RunningTaskInfo, decorWindowContext: Context, positionSupplier: (Int, Int) -> Point, transactionSupplier: Supplier<Transaction> transactionSupplier: Supplier<Transaction>, desktopModeUiEventLogger: DesktopModeUiEventLogger, ): MaximizeMenu } Loading @@ -1061,7 +1056,8 @@ object DefaultMaximizeMenuFactory : MaximizeMenuFactory { taskInfo: RunningTaskInfo, decorWindowContext: Context, positionSupplier: (Int, Int) -> Point, transactionSupplier: Supplier<Transaction> transactionSupplier: Supplier<Transaction>, desktopModeUiEventLogger: DesktopModeUiEventLogger, ): MaximizeMenu { return MaximizeMenu( syncQueue, Loading @@ -1070,7 +1066,8 @@ object DefaultMaximizeMenuFactory : MaximizeMenuFactory { taskInfo, decorWindowContext, positionSupplier, transactionSupplier transactionSupplier, desktopModeUiEventLogger ) } }