diff options
9 files changed, 331 insertions, 11 deletions
diff --git a/libs/WindowManager/Shell/res/values/ids.xml b/libs/WindowManager/Shell/res/values/ids.xml index debcba071d9c..122cde04f8e4 100644 --- a/libs/WindowManager/Shell/res/values/ids.xml +++ b/libs/WindowManager/Shell/res/values/ids.xml @@ -46,4 +46,9 @@ <item type="id" name="action_move_bubble_bar_right"/> <item type="id" name="dismiss_view"/> + + <!-- Accessibility actions for desktop windowing. --> + <item type="id" name="action_snap_left"/> + <item type="id" name="action_snap_right"/> + <item type="id" name="action_maximize_restore"/> </resources> diff --git a/libs/WindowManager/Shell/res/values/strings.xml b/libs/WindowManager/Shell/res/values/strings.xml index 468c345259d0..c29b927f61c2 100644 --- a/libs/WindowManager/Shell/res/values/strings.xml +++ b/libs/WindowManager/Shell/res/values/strings.xml @@ -333,6 +333,28 @@ <!-- Accessibility text for the Maximize Menu's snap right button [CHAR LIMIT=NONE] --> <string name="desktop_mode_maximize_menu_snap_right_button_text">Snap right</string> + <!-- Accessibility text for the Maximize Menu's snap left button [CHAR LIMIT=NONE] --> + <string name="desktop_mode_a11y_action_snap_left">Resize app window left</string> + <!-- Accessibility text for the Maximize Menu's snap right button [CHAR LIMIT=NONE] --> + <string name="desktop_mode_a11y_action_snap_right">Resize app window right</string> + <!-- Accessibility text for the Maximize Menu's snap maximize/restore [CHAR LIMIT=NONE] --> + <string name="desktop_mode_a11y_action_maximize_restore">Maximize or restore window size</string> + + <!-- Accessibility action replacement for caption handle menu split screen button [CHAR LIMIT=NONE] --> + <string name="app_handle_menu_talkback_split_screen_mode_button_text">Enter split screen mode</string> + <!-- Accessibility action replacement for caption handle menu enter desktop mode button [CHAR LIMIT=NONE] --> + <string name="app_handle_menu_talkback_desktop_mode_button_text">Enter desktop windowing mode</string> + <!-- Accessibility action replacement for maximize menu enter snap left button [CHAR LIMIT=NONE] --> + <string name="maximize_menu_talkback_action_snap_left_text">Resize window to left</string> + <!-- Accessibility action replacement for maximize menu enter snap right button [CHAR LIMIT=NONE] --> + <string name="maximize_menu_talkback_action_snap_right_text">Resize window to right</string> + <!-- Accessibility action replacement for maximize menu enter maximize/restore button [CHAR LIMIT=NONE] --> + <string name="maximize_menu_talkback_action_maximize_restore_text">Maximize or restore window size</string> + <!-- Accessibility action replacement for app header maximize/restore button [CHAR LIMIT=NONE] --> + <string name="maximize_button_talkback_action_maximize_restore_text">Maximize or restore window size</string> + <!-- Accessibility action replacement for app header minimize button [CHAR LIMIT=NONE] --> + <string name="minimize_button_talkback_action_maximize_restore_text">Minimize app window</string> + <!-- Accessibility text for open by default settings button [CHAR LIMIT=NONE] --> <string name="open_by_default_settings_text">Open by default settings</string> <!-- Subheader for open by default menu string. --> diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/AppHandleEducationController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/AppHandleEducationController.kt index 39dc48d6d206..5d8355625b94 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/AppHandleEducationController.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/AppHandleEducationController.kt @@ -140,6 +140,27 @@ class AppHandleEducationController( windowingEducationViewController.hideEducationTooltip() } } + + // Listens to a [NoCaption] state change to dismiss any tooltip if the app handle or app + // header is gone or de-focused (e.g. when a user swipes up to home, overview, or enters + // split screen) + applicationCoroutineScope.launch { + if ( + isAppHandleHintViewed() && + isEnterDesktopModeHintViewed() && + isExitDesktopModeHintViewed() + ) + return@launch + windowDecorCaptionHandleRepository.captionStateFlow + .filter { captionState -> + captionState is CaptionState.NoCaption && + !isAppHandleHintViewed() && + !isEnterDesktopModeHintViewed() && + !isExitDesktopModeHintViewed() + } + .flowOn(backgroundDispatcher) + .collectLatest { windowingEducationViewController.hideEducationTooltip() } + } } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java index 387dbfa807fc..b6765c477485 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java @@ -27,18 +27,17 @@ import static android.view.MotionEvent.ACTION_UP; import static android.window.DesktopModeFlags.ENABLE_CAPTION_COMPAT_INSET_FORCE_CONSUMPTION; import static android.window.DesktopModeFlags.ENABLE_CAPTION_COMPAT_INSET_FORCE_CONSUMPTION_ALWAYS; - import static com.android.wm.shell.shared.desktopmode.DesktopModeStatus.canEnterDesktopMode; import static com.android.wm.shell.shared.desktopmode.DesktopModeStatus.canEnterDesktopModeOrShowAppHandle; import static com.android.wm.shell.shared.desktopmode.DesktopModeTransitionSource.APP_HANDLE_MENU_BUTTON; import static com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT; +import static com.android.wm.shell.windowdecor.DragPositioningCallbackUtility.DragEventListener; import static com.android.wm.shell.windowdecor.DragResizeWindowGeometry.DisabledEdge; import static com.android.wm.shell.windowdecor.DragResizeWindowGeometry.DisabledEdge.NONE; import static com.android.wm.shell.windowdecor.DragResizeWindowGeometry.getFineResizeCornerSize; import static com.android.wm.shell.windowdecor.DragResizeWindowGeometry.getLargeResizeCornerSize; import static com.android.wm.shell.windowdecor.DragResizeWindowGeometry.getResizeEdgeHandleSize; import static com.android.wm.shell.windowdecor.DragResizeWindowGeometry.getResizeHandleEdgeInset; -import static com.android.wm.shell.windowdecor.DragPositioningCallbackUtility.DragEventListener; import android.annotation.NonNull; import android.annotation.Nullable; @@ -112,14 +111,14 @@ import kotlin.Unit; import kotlin.jvm.functions.Function0; import kotlin.jvm.functions.Function1; -import kotlinx.coroutines.CoroutineScope; -import kotlinx.coroutines.MainCoroutineDispatcher; - import java.util.List; import java.util.function.BiConsumer; import java.util.function.Consumer; import java.util.function.Supplier; +import kotlinx.coroutines.CoroutineScope; +import kotlinx.coroutines.MainCoroutineDispatcher; + /** * Defines visuals and behaviors of a window decoration of a caption bar and shadows. It works with * {@link DesktopModeWindowDecorViewModel}. @@ -579,6 +578,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin closeHandleMenu(); closeManageWindowsMenu(); closeMaximizeMenu(); + notifyNoCaptionHandle(); } updateDragResizeListener(oldDecorationSurface, inFullImmersive); updateMaximizeMenu(startT, inFullImmersive); @@ -717,7 +717,6 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin } private void notifyCaptionStateChanged() { - // TODO: b/366159408 - Ensure bounds sent with notification account for RTL mode. if (!canEnterDesktopMode(mContext) || !isEducationEnabled()) { return; } @@ -847,6 +846,9 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin mOnCaptionButtonClickListener, mOnCaptionLongClickListener, mOnCaptionGenericMotionListener, + mOnLeftSnapClickListener, + mOnRightSnapClickListener, + mOnMaximizeOrRestoreClickListener, mOnMaximizeHoverListener); } throw new IllegalArgumentException("Unexpected layout resource id"); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.kt index 053850480ecc..32a2f8294877 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.kt @@ -44,6 +44,8 @@ import android.window.SurfaceSyncGroup import androidx.annotation.StringRes import androidx.annotation.VisibleForTesting import androidx.compose.ui.graphics.toArgb +import androidx.core.view.ViewCompat +import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_CLICK import androidx.core.view.isGone import com.android.window.flags.Flags import com.android.wm.shell.R @@ -55,8 +57,8 @@ 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.common.calculateMenuPosition import com.android.wm.shell.windowdecor.extension.isFullscreen import com.android.wm.shell.windowdecor.extension.isMultiWindow import com.android.wm.shell.windowdecor.extension.isPinned @@ -536,6 +538,20 @@ class HandleMenu( } return@setOnTouchListener true } + + with(context.resources) { + // Update a11y read out to say "double tap to enter desktop windowing mode" + ViewCompat.replaceAccessibilityAction( + desktopBtn, ACTION_CLICK, + getString(R.string.app_handle_menu_talkback_desktop_mode_button_text), null + ) + + // Update a11y read out to say "double tap to enter split screen mode" + ViewCompat.replaceAccessibilityAction( + splitscreenBtn, ACTION_CLICK, + getString(R.string.app_handle_menu_talkback_split_screen_mode_button_text), null + ) + } } /** Binds the menu views to the new data. */ diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MaximizeMenu.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MaximizeMenu.kt index 1ce0366728b9..be3ea4e7b71e 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MaximizeMenu.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MaximizeMenu.kt @@ -34,6 +34,7 @@ import android.graphics.drawable.LayerDrawable import android.graphics.drawable.ShapeDrawable import android.graphics.drawable.StateListDrawable import android.graphics.drawable.shapes.RoundRectShape +import android.os.Bundle import android.util.StateSet import android.view.LayoutInflater import android.view.MotionEvent.ACTION_HOVER_ENTER @@ -51,12 +52,16 @@ import android.view.ViewGroup import android.view.WindowManager import android.view.WindowlessWindowManager import android.view.accessibility.AccessibilityEvent +import android.view.accessibility.AccessibilityNodeInfo +import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction import android.widget.Button import android.widget.TextView 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 @@ -403,6 +408,96 @@ class MaximizeMenu( true } + sizeToggleButton.accessibilityDelegate = object : View.AccessibilityDelegate() { + override fun onInitializeAccessibilityNodeInfo( + host: View, + info: AccessibilityNodeInfo + ) { + + super.onInitializeAccessibilityNodeInfo(host, info) + info.addAction(AccessibilityAction.ACTION_CLICK) + host.isClickable = true + } + + override fun performAccessibilityAction( + host: View, + action: Int, + args: Bundle? + ): Boolean { + if (action == AccessibilityAction.ACTION_CLICK.id) { + onMaximizeClickListener?.invoke() + } + return super.performAccessibilityAction(host, action, args) + } + } + + snapLeftButton.accessibilityDelegate = object : View.AccessibilityDelegate() { + override fun onInitializeAccessibilityNodeInfo( + host: View, + info: AccessibilityNodeInfo + ) { + super.onInitializeAccessibilityNodeInfo(host, info) + info.addAction(AccessibilityAction.ACTION_CLICK) + host.isClickable = true + } + + override fun performAccessibilityAction( + host: View, + action: Int, + args: Bundle? + ): Boolean { + if (action == AccessibilityAction.ACTION_CLICK.id) { + onLeftSnapClickListener?.invoke() + } + return super.performAccessibilityAction(host, action, args) + } + } + + snapRightButton.accessibilityDelegate = object : View.AccessibilityDelegate() { + override fun onInitializeAccessibilityNodeInfo( + host: View, + info: AccessibilityNodeInfo + ) { + super.onInitializeAccessibilityNodeInfo(host, info) + info.addAction(AccessibilityAction.ACTION_CLICK) + host.isClickable = true + } + + override fun performAccessibilityAction( + host: View, + action: Int, + args: Bundle? + ): Boolean { + if (action == AccessibilityAction.ACTION_CLICK.id) { + 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 diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHeaderViewHolder.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHeaderViewHolder.kt index 9f8ca7740182..db12f899f42f 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHeaderViewHolder.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHeaderViewHolder.kt @@ -27,10 +27,13 @@ import android.graphics.drawable.LayerDrawable import android.graphics.drawable.RippleDrawable import android.graphics.drawable.ShapeDrawable import android.graphics.drawable.shapes.RoundRectShape +import android.os.Bundle import android.view.View import android.view.View.OnLongClickListener import android.view.ViewTreeObserver.OnGlobalLayoutListener import android.view.accessibility.AccessibilityEvent +import android.view.accessibility.AccessibilityNodeInfo +import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction import android.widget.ImageButton import android.widget.ImageView import android.widget.TextView @@ -49,6 +52,8 @@ import com.android.internal.R.color.materialColorSurfaceDim import com.android.window.flags.Flags import com.android.wm.shell.R import android.window.DesktopModeFlags +import androidx.core.view.ViewCompat +import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat import com.android.wm.shell.windowdecor.MaximizeButtonView import com.android.wm.shell.windowdecor.common.DecorThemeUtil import com.android.wm.shell.windowdecor.common.OPACITY_100 @@ -71,7 +76,10 @@ class AppHeaderViewHolder( onCaptionButtonClickListener: View.OnClickListener, private val onLongClickListener: OnLongClickListener, onCaptionGenericMotionListener: View.OnGenericMotionListener, - onMaximizeHoverAnimationFinishedListener: () -> Unit + mOnLeftSnapClickListener: () -> Unit, + mOnRightSnapClickListener: () -> Unit, + mOnMaximizeOrRestoreClickListener: () -> Unit, + onMaximizeHoverAnimationFinishedListener: () -> Unit, ) : WindowDecorationViewHolder<AppHeaderViewHolder.HeaderData>(rootView) { data class HeaderData( @@ -153,6 +161,91 @@ class AppHeaderViewHolder( minimizeWindowButton.setOnTouchListener(onCaptionTouchListener) maximizeButtonView.onHoverAnimationFinishedListener = onMaximizeHoverAnimationFinishedListener + + val a11yActionSnapLeft = AccessibilityAction( + R.id.action_snap_left, + context.resources.getString(R.string.desktop_mode_a11y_action_snap_left) + ) + val a11yActionSnapRight = AccessibilityAction( + R.id.action_snap_right, + context.resources.getString(R.string.desktop_mode_a11y_action_snap_right) + ) + val a11yActionMaximizeRestore = AccessibilityAction( + R.id.action_maximize_restore, + context.resources.getString(R.string.desktop_mode_a11y_action_maximize_restore) + ) + + captionHandle.accessibilityDelegate = object : View.AccessibilityDelegate() { + override fun onInitializeAccessibilityNodeInfo( + host: View, + info: AccessibilityNodeInfo + ) { + super.onInitializeAccessibilityNodeInfo(host, info) + info.addAction(a11yActionSnapLeft) + info.addAction(a11yActionSnapRight) + info.addAction(a11yActionMaximizeRestore) + } + + override fun performAccessibilityAction( + host: View, + action: Int, + args: Bundle? + ): Boolean { + when (action) { + R.id.action_snap_left -> mOnLeftSnapClickListener.invoke() + R.id.action_snap_right -> mOnRightSnapClickListener.invoke() + R.id.action_maximize_restore -> mOnMaximizeOrRestoreClickListener.invoke() + } + + return super.performAccessibilityAction(host, action, args) + } + } + maximizeWindowButton.accessibilityDelegate = object : View.AccessibilityDelegate() { + override fun onInitializeAccessibilityNodeInfo( + host: View, + info: AccessibilityNodeInfo + ) { + super.onInitializeAccessibilityNodeInfo(host, info) + info.addAction(AccessibilityAction.ACTION_CLICK) + info.addAction(a11yActionSnapLeft) + info.addAction(a11yActionSnapRight) + info.addAction(a11yActionMaximizeRestore) + host.isClickable = true + } + + override fun performAccessibilityAction( + host: View, + action: Int, + args: Bundle? + ): Boolean { + when (action) { + AccessibilityAction.ACTION_CLICK.id -> host.performClick() + R.id.action_snap_left -> mOnLeftSnapClickListener.invoke() + R.id.action_snap_right -> mOnRightSnapClickListener.invoke() + R.id.action_maximize_restore -> mOnMaximizeOrRestoreClickListener.invoke() + } + + return super.performAccessibilityAction(host, action, args) + } + } + + with(context.resources) { + // Update a11y read out to say "double tap to maximize or restore window size" + ViewCompat.replaceAccessibilityAction( + maximizeWindowButton, + AccessibilityActionCompat.ACTION_CLICK, + getString(R.string.maximize_button_talkback_action_maximize_restore_text), + null + ) + + // Update a11y read out to say "double tap to minimize app window" + ViewCompat.replaceAccessibilityAction( + minimizeWindowButton, + AccessibilityActionCompat.ACTION_CLICK, + getString(R.string.minimize_button_talkback_action_maximize_restore_text), + null + ) + } } override fun bindData(data: HeaderData) { @@ -628,6 +721,9 @@ class AppHeaderViewHolder( onCaptionButtonClickListener: View.OnClickListener, onLongClickListener: OnLongClickListener, onCaptionGenericMotionListener: View.OnGenericMotionListener, + mOnLeftSnapClickListener: () -> Unit, + mOnRightSnapClickListener: () -> Unit, + mOnMaximizeOrRestoreClickListener: () -> Unit, onMaximizeHoverAnimationFinishedListener: () -> Unit, ): AppHeaderViewHolder = AppHeaderViewHolder( rootView, @@ -635,6 +731,9 @@ class AppHeaderViewHolder( onCaptionButtonClickListener, onLongClickListener, onCaptionGenericMotionListener, + mOnLeftSnapClickListener, + mOnRightSnapClickListener, + mOnMaximizeOrRestoreClickListener, onMaximizeHoverAnimationFinishedListener, ) } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/education/AppHandleEducationControllerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/education/AppHandleEducationControllerTest.kt index 7d2a8082c43e..1160a9286572 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/education/AppHandleEducationControllerTest.kt +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/education/AppHandleEducationControllerTest.kt @@ -175,6 +175,64 @@ class AppHandleEducationControllerTest : ShellTestCase() { } @Test + @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_APP_HANDLE_EDUCATION) + fun init_noCaptionStateNotified_shouldHideAllTooltips() = + testScope.runTest { + setShouldShowDesktopModeEducation(true) + + // Simulate no caption state notification + testCaptionStateFlow.value = CaptionState.NoCaption + waitForBufferDelay() + + verify(mockTooltipController, times(1)).hideEducationTooltip() + } + + @Test + @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_APP_HANDLE_EDUCATION) + fun init_appHandleHintViewed_shouldNotListenToNoCaptionNotification() = + testScope.runTest { + testDataStoreFlow.value = + createWindowingEducationProto(appHandleHintViewedTimestampMillis = 123L) + setShouldShowDesktopModeEducation(true) + + // Simulate no caption state notification + testCaptionStateFlow.value = CaptionState.NoCaption + waitForBufferDelay() + + verify(mockTooltipController, never()).hideEducationTooltip() + } + + @Test + @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_APP_HANDLE_EDUCATION) + fun init_enterDesktopModeHintViewed_shouldNotListenToNoCaptionNotification() = + testScope.runTest { + testDataStoreFlow.value = + createWindowingEducationProto(enterDesktopModeHintViewedTimestampMillis = 123L) + setShouldShowDesktopModeEducation(true) + + // Simulate no caption state notification + testCaptionStateFlow.value = CaptionState.NoCaption + waitForBufferDelay() + + verify(mockTooltipController, never()).hideEducationTooltip() + } + + @Test + @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_APP_HANDLE_EDUCATION) + fun init_exitDesktopModeHintViewed_shouldNotListenToNoCaptionNotification() = + testScope.runTest { + testDataStoreFlow.value = + createWindowingEducationProto(exitDesktopModeHintViewedTimestampMillis = 123L) + setShouldShowDesktopModeEducation(true) + + // Simulate no caption state notification + testCaptionStateFlow.value = CaptionState.NoCaption + waitForBufferDelay() + + verify(mockTooltipController, never()).hideEducationTooltip() + } + + @Test @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_APP_HANDLE_EDUCATION) fun init_flagDisabled_shouldNotCallShowEducationTooltip() = testScope.runTest { @@ -289,8 +347,7 @@ class AppHandleEducationControllerTest : ShellTestCase() { // Mark app handle hint viewed. testDataStoreFlow.value = createWindowingEducationProto(appHandleHintViewedTimestampMillis = 123L) - val systemPropertiesKey = "persist.windowing_force_show_desktop_mode_education" - whenever(SystemProperties.getBoolean(eq(systemPropertiesKey), anyBoolean())) + whenever(SystemProperties.getBoolean(eq(FORCE_SHOW_EDUCATION_SYSPROP), anyBoolean())) .thenReturn(true) setShouldShowDesktopModeEducation(true) @@ -396,5 +453,7 @@ class AppHandleEducationControllerTest : ShellTestCase() { private companion object { val APP_HANDLE_EDUCATION_DELAY_BUFFER_MILLIS: Long = APP_HANDLE_EDUCATION_DELAY_MILLIS + 1000L + + val FORCE_SHOW_EDUCATION_SYSPROP = "persist.windowing_force_show_desktop_mode_education" } } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java index 87198d14c839..76e1e805f5a9 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java @@ -297,7 +297,8 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase { .thenReturn(mMockHandleMenu); when(mMockMultiInstanceHelper.supportsMultiInstanceSplit(any(), anyInt())) .thenReturn(false); - when(mMockAppHeaderViewHolderFactory.create(any(), any(), any(), any(), any(), any())) + when(mMockAppHeaderViewHolderFactory + .create(any(), any(), any(), any(), any(), any(), any(), any(), any())) .thenReturn(mMockAppHeaderViewHolder); when(mMockDesktopUserRepositories.getCurrent()).thenReturn(mDesktopRepository); when(mMockDesktopUserRepositories.getProfile(anyInt())).thenReturn(mDesktopRepository); |