Loading libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java +3 −2 Original line number Diff line number Diff line Loading @@ -851,10 +851,11 @@ public abstract class WMShellModule { static DesktopWindowingEducationTooltipController provideDesktopWindowingEducationTooltipController( Context context, AdditionalSystemViewContainer.Factory additionalSystemViewContainerFactory AdditionalSystemViewContainer.Factory additionalSystemViewContainerFactory, DisplayController displayController ) { return new DesktopWindowingEducationTooltipController(context, additionalSystemViewContainerFactory); additionalSystemViewContainerFactory, displayController); } @OptIn(markerClass = ExperimentalCoroutinesApi.class) Loading libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/education/DesktopWindowingEducationTooltipController.kt +22 −1 Original line number Diff line number Diff line Loading @@ -30,9 +30,13 @@ import android.view.WindowManager import android.widget.ImageView import android.widget.LinearLayout import android.widget.TextView import android.window.DisplayAreaInfo import android.window.WindowContainerTransaction import androidx.dynamicanimation.animation.DynamicAnimation import androidx.dynamicanimation.animation.SpringForce import com.android.wm.shell.R import com.android.wm.shell.common.DisplayChangeController.OnDisplayChangingListener import com.android.wm.shell.common.DisplayController import com.android.wm.shell.shared.animation.PhysicsAnimator import com.android.wm.shell.windowdecor.WindowManagerWrapper import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalSystemViewContainer Loading @@ -44,7 +48,8 @@ import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalSystem class DesktopWindowingEducationTooltipController( private val context: Context, private val additionalSystemViewContainerFactory: AdditionalSystemViewContainer.Factory, ) { private val displayController: DisplayController, ) : OnDisplayChangingListener { // TODO: b/369384567 - Set tooltip color scheme to match LT/DT of app theme private var tooltipView: View? = null private var animator: PhysicsAnimator<View>? = null Loading @@ -53,6 +58,20 @@ class DesktopWindowingEducationTooltipController( } private var popupWindow: AdditionalSystemViewContainer? = null override fun onDisplayChange( displayId: Int, fromRotation: Int, toRotation: Int, newDisplayAreaInfo: DisplayAreaInfo?, t: WindowContainerTransaction? ) { // Exit if the rotation hasn't changed or is changed by 180 degrees. [fromRotation] and // [toRotation] can be one of the [@Surface.Rotation] values. if ((fromRotation % 2 == toRotation % 2)) return hideEducationTooltip() // TODO: b/370820018 - Update tooltip position on orientation change instead of dismissing } /** * Shows education tooltip. * Loading @@ -64,6 +83,7 @@ class DesktopWindowingEducationTooltipController( tooltipView = createEducationTooltipView(tooltipViewConfig, taskId) animator = createAnimator() animateShowTooltipTransition() displayController.addDisplayChangingController(this) } /** Hide the current education view if visible */ Loading Loading @@ -145,6 +165,7 @@ class DesktopWindowingEducationTooltipController( animator = null popupWindow?.releaseView() popupWindow = null displayController.removeDisplayChangingController(this) } private fun createTooltipPopupWindow( Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/education/DesktopWindowingEducationTooltipControllerTest.kt +29 −1 Original line number Diff line number Diff line Loading @@ -24,12 +24,16 @@ import android.testing.TestableContext import android.testing.TestableLooper import android.testing.TestableResources import android.view.MotionEvent import android.view.Surface.ROTATION_180 import android.view.Surface.ROTATION_90 import android.view.View import android.view.WindowManager import android.widget.TextView import android.window.WindowContainerTransaction import androidx.test.filters.SmallTest import com.android.wm.shell.R import com.android.wm.shell.ShellTestCase import com.android.wm.shell.common.DisplayController import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalSystemViewContainer import com.android.wm.shell.windowdecor.education.DesktopWindowingEducationTooltipController.TooltipArrowDirection import com.google.common.truth.Truth.assertThat Loading @@ -42,9 +46,11 @@ import org.mockito.MockitoAnnotations import org.mockito.kotlin.any import org.mockito.kotlin.anyOrNull import org.mockito.kotlin.argumentCaptor import org.mockito.kotlin.atLeastOnce import org.mockito.kotlin.mock import org.mockito.kotlin.times import org.mockito.kotlin.verify import org.mockito.kotlin.whenever @SmallTest @TestableLooper.RunWithLooper(setAsMainLooper = true) Loading @@ -52,6 +58,8 @@ import org.mockito.kotlin.verify class DesktopWindowingEducationTooltipControllerTest : ShellTestCase() { @Mock private lateinit var mockWindowManager: WindowManager @Mock private lateinit var mockViewContainerFactory: AdditionalSystemViewContainer.Factory @Mock private lateinit var mockDisplayController: DisplayController @Mock private lateinit var mockPopupWindow: AdditionalSystemViewContainer private lateinit var testableResources: TestableResources private lateinit var testableContext: TestableContext private lateinit var tooltipController: DesktopWindowingEducationTooltipController Loading @@ -69,7 +77,8 @@ class DesktopWindowingEducationTooltipControllerTest : ShellTestCase() { Context.LAYOUT_INFLATER_SERVICE, context.getSystemService(Context.LAYOUT_INFLATER_SERVICE)) testableContext.addMockSystemService(WindowManager::class.java, mockWindowManager) tooltipController = DesktopWindowingEducationTooltipController(testableContext, mockViewContainerFactory) DesktopWindowingEducationTooltipController( testableContext, mockViewContainerFactory, mockDisplayController) } @Test Loading Loading @@ -218,6 +227,25 @@ class DesktopWindowingEducationTooltipControllerTest : ShellTestCase() { verify(mockLambda).invoke() } @Test fun showEducationTooltip_displayRotationChanged_hidesTooltip() { whenever( mockViewContainerFactory.create(any(), any(), any(), any(), any(), any(), any(), any())) .thenReturn(mockPopupWindow) val tooltipViewConfig = createTooltipConfig() tooltipController.showEducationTooltip(tooltipViewConfig = tooltipViewConfig, taskId = 123) tooltipController.onDisplayChange( /* displayId= */ 123, /* fromRotation= */ ROTATION_90, /* toRotation= */ ROTATION_180, /* newDisplayAreaInfo= */ null, WindowContainerTransaction()) verify(mockPopupWindow, times(1)).releaseView() verify(mockDisplayController, atLeastOnce()).removeDisplayChangingController(any()) } private fun createTooltipConfig( @LayoutRes tooltipViewLayout: Int = R.layout.desktop_windowing_education_top_arrow_tooltip, tooltipViewGlobalCoordinates: Point = Point(0, 0), Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java +3 −2 Original line number Diff line number Diff line Loading @@ -851,10 +851,11 @@ public abstract class WMShellModule { static DesktopWindowingEducationTooltipController provideDesktopWindowingEducationTooltipController( Context context, AdditionalSystemViewContainer.Factory additionalSystemViewContainerFactory AdditionalSystemViewContainer.Factory additionalSystemViewContainerFactory, DisplayController displayController ) { return new DesktopWindowingEducationTooltipController(context, additionalSystemViewContainerFactory); additionalSystemViewContainerFactory, displayController); } @OptIn(markerClass = ExperimentalCoroutinesApi.class) Loading
libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/education/DesktopWindowingEducationTooltipController.kt +22 −1 Original line number Diff line number Diff line Loading @@ -30,9 +30,13 @@ import android.view.WindowManager import android.widget.ImageView import android.widget.LinearLayout import android.widget.TextView import android.window.DisplayAreaInfo import android.window.WindowContainerTransaction import androidx.dynamicanimation.animation.DynamicAnimation import androidx.dynamicanimation.animation.SpringForce import com.android.wm.shell.R import com.android.wm.shell.common.DisplayChangeController.OnDisplayChangingListener import com.android.wm.shell.common.DisplayController import com.android.wm.shell.shared.animation.PhysicsAnimator import com.android.wm.shell.windowdecor.WindowManagerWrapper import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalSystemViewContainer Loading @@ -44,7 +48,8 @@ import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalSystem class DesktopWindowingEducationTooltipController( private val context: Context, private val additionalSystemViewContainerFactory: AdditionalSystemViewContainer.Factory, ) { private val displayController: DisplayController, ) : OnDisplayChangingListener { // TODO: b/369384567 - Set tooltip color scheme to match LT/DT of app theme private var tooltipView: View? = null private var animator: PhysicsAnimator<View>? = null Loading @@ -53,6 +58,20 @@ class DesktopWindowingEducationTooltipController( } private var popupWindow: AdditionalSystemViewContainer? = null override fun onDisplayChange( displayId: Int, fromRotation: Int, toRotation: Int, newDisplayAreaInfo: DisplayAreaInfo?, t: WindowContainerTransaction? ) { // Exit if the rotation hasn't changed or is changed by 180 degrees. [fromRotation] and // [toRotation] can be one of the [@Surface.Rotation] values. if ((fromRotation % 2 == toRotation % 2)) return hideEducationTooltip() // TODO: b/370820018 - Update tooltip position on orientation change instead of dismissing } /** * Shows education tooltip. * Loading @@ -64,6 +83,7 @@ class DesktopWindowingEducationTooltipController( tooltipView = createEducationTooltipView(tooltipViewConfig, taskId) animator = createAnimator() animateShowTooltipTransition() displayController.addDisplayChangingController(this) } /** Hide the current education view if visible */ Loading Loading @@ -145,6 +165,7 @@ class DesktopWindowingEducationTooltipController( animator = null popupWindow?.releaseView() popupWindow = null displayController.removeDisplayChangingController(this) } private fun createTooltipPopupWindow( Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/education/DesktopWindowingEducationTooltipControllerTest.kt +29 −1 Original line number Diff line number Diff line Loading @@ -24,12 +24,16 @@ import android.testing.TestableContext import android.testing.TestableLooper import android.testing.TestableResources import android.view.MotionEvent import android.view.Surface.ROTATION_180 import android.view.Surface.ROTATION_90 import android.view.View import android.view.WindowManager import android.widget.TextView import android.window.WindowContainerTransaction import androidx.test.filters.SmallTest import com.android.wm.shell.R import com.android.wm.shell.ShellTestCase import com.android.wm.shell.common.DisplayController import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalSystemViewContainer import com.android.wm.shell.windowdecor.education.DesktopWindowingEducationTooltipController.TooltipArrowDirection import com.google.common.truth.Truth.assertThat Loading @@ -42,9 +46,11 @@ import org.mockito.MockitoAnnotations import org.mockito.kotlin.any import org.mockito.kotlin.anyOrNull import org.mockito.kotlin.argumentCaptor import org.mockito.kotlin.atLeastOnce import org.mockito.kotlin.mock import org.mockito.kotlin.times import org.mockito.kotlin.verify import org.mockito.kotlin.whenever @SmallTest @TestableLooper.RunWithLooper(setAsMainLooper = true) Loading @@ -52,6 +58,8 @@ import org.mockito.kotlin.verify class DesktopWindowingEducationTooltipControllerTest : ShellTestCase() { @Mock private lateinit var mockWindowManager: WindowManager @Mock private lateinit var mockViewContainerFactory: AdditionalSystemViewContainer.Factory @Mock private lateinit var mockDisplayController: DisplayController @Mock private lateinit var mockPopupWindow: AdditionalSystemViewContainer private lateinit var testableResources: TestableResources private lateinit var testableContext: TestableContext private lateinit var tooltipController: DesktopWindowingEducationTooltipController Loading @@ -69,7 +77,8 @@ class DesktopWindowingEducationTooltipControllerTest : ShellTestCase() { Context.LAYOUT_INFLATER_SERVICE, context.getSystemService(Context.LAYOUT_INFLATER_SERVICE)) testableContext.addMockSystemService(WindowManager::class.java, mockWindowManager) tooltipController = DesktopWindowingEducationTooltipController(testableContext, mockViewContainerFactory) DesktopWindowingEducationTooltipController( testableContext, mockViewContainerFactory, mockDisplayController) } @Test Loading Loading @@ -218,6 +227,25 @@ class DesktopWindowingEducationTooltipControllerTest : ShellTestCase() { verify(mockLambda).invoke() } @Test fun showEducationTooltip_displayRotationChanged_hidesTooltip() { whenever( mockViewContainerFactory.create(any(), any(), any(), any(), any(), any(), any(), any())) .thenReturn(mockPopupWindow) val tooltipViewConfig = createTooltipConfig() tooltipController.showEducationTooltip(tooltipViewConfig = tooltipViewConfig, taskId = 123) tooltipController.onDisplayChange( /* displayId= */ 123, /* fromRotation= */ ROTATION_90, /* toRotation= */ ROTATION_180, /* newDisplayAreaInfo= */ null, WindowContainerTransaction()) verify(mockPopupWindow, times(1)).releaseView() verify(mockDisplayController, atLeastOnce()).removeDisplayChangingController(any()) } private fun createTooltipConfig( @LayoutRes tooltipViewLayout: Int = R.layout.desktop_windowing_education_top_arrow_tooltip, tooltipViewGlobalCoordinates: Point = Point(0, 0), Loading