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

Commit d49e5fa6 authored by Saho Kobayashi's avatar Saho Kobayashi
Browse files

Use FocusTransitionObserver in CompatUIController

This CL migrates the usages of TaskInfo#isFocused in
CompatUIController to FocusTransitionObserver
to support multi display because TaskInfo#isFocused is per
display.

Bug: 371095009
Test: atest CompatUIControllerTest
Flag: com.android.window.flags.enable_display_focus_in_shell_transitions
Change-Id: Ia6577c86388eaf5336c68130c4995f4b2369317e
parent b511fa5b
Loading
Loading
Loading
Loading
+10 −3
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager.RunningTaskInfo;
import android.app.TaskInfo;
import android.content.ComponentName;
import android.content.Context;
@@ -58,6 +59,7 @@ import com.android.wm.shell.desktopmode.DesktopUserRepositories;
import com.android.wm.shell.sysui.KeyguardChangeListener;
import com.android.wm.shell.sysui.ShellController;
import com.android.wm.shell.sysui.ShellInit;
import com.android.wm.shell.transition.FocusTransitionObserver;
import com.android.wm.shell.transition.Transitions;

import dagger.Lazy;
@@ -70,7 +72,6 @@ import java.util.Optional;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.IntPredicate;
import java.util.function.Predicate;

/**
@@ -195,6 +196,9 @@ public class CompatUIController implements OnDisplaysChangedListener,
    @NonNull
    private final CompatUIStatusManager mCompatUIStatusManager;

    @NonNull
    private final FocusTransitionObserver mFocusTransitionObserver;

    @NonNull
    private final Optional<DesktopUserRepositories> mDesktopUserRepositories;

@@ -212,7 +216,8 @@ public class CompatUIController implements OnDisplaysChangedListener,
            @NonNull CompatUIShellCommandHandler compatUIShellCommandHandler,
            @NonNull AccessibilityManager accessibilityManager,
            @NonNull CompatUIStatusManager compatUIStatusManager,
            @NonNull Optional<DesktopUserRepositories> desktopUserRepositories) {
            @NonNull Optional<DesktopUserRepositories> desktopUserRepositories,
            @NonNull FocusTransitionObserver focusTransitionObserver) {
        mContext = context;
        mShellController = shellController;
        mDisplayController = displayController;
@@ -229,6 +234,7 @@ public class CompatUIController implements OnDisplaysChangedListener,
                DISAPPEAR_DELAY_MS, flags);
        mCompatUIStatusManager = compatUIStatusManager;
        mDesktopUserRepositories = desktopUserRepositories;
        mFocusTransitionObserver = focusTransitionObserver;
        shellInit.addInitCallback(this::onInit, this);
    }

@@ -405,7 +411,8 @@ public class CompatUIController implements OnDisplaysChangedListener,
        // start tracking the buttons visibility for this task.
        if (mTopActivityTaskId != taskInfo.taskId
                && !taskInfo.isTopActivityTransparent
                && taskInfo.isVisible && taskInfo.isFocused) {
                && taskInfo.isVisible
                && mFocusTransitionObserver.hasGlobalFocus((RunningTaskInfo) taskInfo)) {
            mTopActivityTaskId = taskInfo.taskId;
            setHasShownUserAspectRatioSettingsButton(false);
        }
+4 −2
Original line number Diff line number Diff line
@@ -270,7 +270,8 @@ public abstract class WMShellBaseModule {
            @NonNull CompatUIState compatUIState,
            @NonNull CompatUIComponentIdGenerator componentIdGenerator,
            @NonNull CompatUIComponentFactory compatUIComponentFactory,
            CompatUIStatusManager compatUIStatusManager) {
            CompatUIStatusManager compatUIStatusManager,
            @NonNull FocusTransitionObserver focusTransitionObserver) {
        if (!context.getResources().getBoolean(R.bool.config_enableCompatUIController)) {
            return Optional.empty();
        }
@@ -295,7 +296,8 @@ public abstract class WMShellBaseModule {
                        compatUIShellCommandHandler.get(),
                        accessibilityManager.get(),
                        compatUIStatusManager,
                        desktopUserRepositories));
                        desktopUserRepositories,
                        focusTransitionObserver));
    }

    @WMSingleton
+35 −16
Original line number Diff line number Diff line
@@ -66,12 +66,11 @@ import com.android.wm.shell.desktopmode.DesktopRepository;
import com.android.wm.shell.desktopmode.DesktopUserRepositories;
import com.android.wm.shell.sysui.ShellController;
import com.android.wm.shell.sysui.ShellInit;
import com.android.wm.shell.transition.FocusTransitionObserver;
import com.android.wm.shell.transition.Transitions;

import dagger.Lazy;

import java.util.Optional;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
@@ -82,6 +81,8 @@ import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import java.util.Optional;

/**
 * Tests for {@link CompatUIController}.
 *
@@ -139,6 +140,8 @@ public class CompatUIControllerTest extends ShellTestCase {
    private DesktopUserRepositories mDesktopUserRepositories;
    @Mock
    private DesktopRepository mDesktopRepository;
    @Mock
    private FocusTransitionObserver mFocusTransitionObserver;

    @Captor
    ArgumentCaptor<OnInsetsChangedListener> mOnInsetsChangedListenerCaptor;
@@ -174,7 +177,8 @@ public class CompatUIControllerTest extends ShellTestCase {
                mMockDisplayController, mMockDisplayInsetsController, mMockImeController,
                mMockSyncQueue, mMockExecutor, mMockTransitionsLazy, mDockStateReader,
                mCompatUIConfiguration, mCompatUIShellCommandHandler, mAccessibilityManager,
                mCompatUIStatusManager, Optional.of(mDesktopUserRepositories)) {
                mCompatUIStatusManager, Optional.of(mDesktopUserRepositories),
                mFocusTransitionObserver) {
            @Override
            CompatUIWindowManager createCompatUiWindowManager(Context context, TaskInfo taskInfo,
                    ShellTaskOrganizer.TaskListener taskListener) {
@@ -292,6 +296,7 @@ public class CompatUIControllerTest extends ShellTestCase {
        doReturn(false).when(mMockRestartDialogLayout).updateCompatInfo(any(), any(), anyBoolean());

        TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, /* hasSizeCompat= */ true);
        when(mFocusTransitionObserver.hasGlobalFocus((RunningTaskInfo) taskInfo)).thenReturn(true);
        mController.onCompatInfoChanged(new CompatUIInfo(taskInfo, mMockTaskListener));

        verify(mController).createCompatUiWindowManager(any(), eq(taskInfo), eq(mMockTaskListener));
@@ -423,6 +428,7 @@ public class CompatUIControllerTest extends ShellTestCase {
        // Verify button remains hidden while IME is showing.
        TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, /* hasSizeCompat= */ true);
        mController.onCompatInfoChanged(new CompatUIInfo(taskInfo, mMockTaskListener));
        when(mFocusTransitionObserver.hasGlobalFocus((RunningTaskInfo) taskInfo)).thenReturn(false);

        verify(mMockCompatLayout).updateCompatInfo(taskInfo, mMockTaskListener,
                /* canShow= */ false);
@@ -455,6 +461,7 @@ public class CompatUIControllerTest extends ShellTestCase {
        // Verify button remains hidden while keyguard is showing.
        TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, /* hasSizeCompat= */ true);
        mController.onCompatInfoChanged(new CompatUIInfo(taskInfo, mMockTaskListener));
        when(mFocusTransitionObserver.hasGlobalFocus((RunningTaskInfo) taskInfo)).thenReturn(false);

        verify(mMockCompatLayout).updateCompatInfo(taskInfo, mMockTaskListener,
                /* canShow= */ false);
@@ -535,6 +542,7 @@ public class CompatUIControllerTest extends ShellTestCase {
    @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
    public void testRestartLayoutRecreatedIfNeeded() {
        final TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, /* hasSizeCompat= */ true);
        when(mFocusTransitionObserver.hasGlobalFocus((RunningTaskInfo) taskInfo)).thenReturn(false);
        doReturn(true).when(mMockRestartDialogLayout)
                .needsToBeRecreated(any(TaskInfo.class),
                        any(ShellTaskOrganizer.TaskListener.class));
@@ -550,6 +558,7 @@ public class CompatUIControllerTest extends ShellTestCase {
    @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
    public void testRestartLayoutNotRecreatedIfNotNeeded() {
        final TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, /* hasSizeCompat= */ true);
        when(mFocusTransitionObserver.hasGlobalFocus((RunningTaskInfo) taskInfo)).thenReturn(false);
        doReturn(false).when(mMockRestartDialogLayout)
                .needsToBeRecreated(any(TaskInfo.class),
                        any(ShellTaskOrganizer.TaskListener.class));
@@ -570,7 +579,8 @@ public class CompatUIControllerTest extends ShellTestCase {

        // Create new task
        final TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, /* hasSizeCompat= */ true,
                /* isVisible */ true, /* isFocused */ true);
                /* isVisible */ true);
        when(mFocusTransitionObserver.hasGlobalFocus((RunningTaskInfo) taskInfo)).thenReturn(true);

        // Simulate new task being shown
        mController.updateActiveTaskInfo(taskInfo);
@@ -586,7 +596,8 @@ public class CompatUIControllerTest extends ShellTestCase {
    public void testUpdateActiveTaskInfo_newTask_notVisibleOrFocused_notUpdated() {
        // Create new task
        final TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, /* hasSizeCompat= */ true,
                /* isVisible */ true, /* isFocused */ true);
                /* isVisible */ true);
        when(mFocusTransitionObserver.hasGlobalFocus((RunningTaskInfo) taskInfo)).thenReturn(true);

        // Simulate task being shown
        mController.updateActiveTaskInfo(taskInfo);
@@ -604,7 +615,8 @@ public class CompatUIControllerTest extends ShellTestCase {

        // Create visible but NOT focused task
        final TaskInfo taskInfo1 = createTaskInfo(DISPLAY_ID, newTaskId, /* hasSizeCompat= */ true,
                /* isVisible */ true, /* isFocused */ false);
                /* isVisible */ true);
        when(mFocusTransitionObserver.hasGlobalFocus((RunningTaskInfo) taskInfo)).thenReturn(false);

        // Simulate new task being shown
        mController.updateActiveTaskInfo(taskInfo1);
@@ -616,7 +628,8 @@ public class CompatUIControllerTest extends ShellTestCase {

        // Create focused but NOT visible task
        final TaskInfo taskInfo2 = createTaskInfo(DISPLAY_ID, newTaskId, /* hasSizeCompat= */ true,
                /* isVisible */ false, /* isFocused */ true);
                /* isVisible */ false);
        when(mFocusTransitionObserver.hasGlobalFocus((RunningTaskInfo) taskInfo)).thenReturn(true);

        // Simulate new task being shown
        mController.updateActiveTaskInfo(taskInfo2);
@@ -628,7 +641,8 @@ public class CompatUIControllerTest extends ShellTestCase {

        // Create NOT focused but NOT visible task
        final TaskInfo taskInfo3 = createTaskInfo(DISPLAY_ID, newTaskId, /* hasSizeCompat= */ true,
                /* isVisible */ false, /* isFocused */ false);
                /* isVisible */ false);
        when(mFocusTransitionObserver.hasGlobalFocus((RunningTaskInfo) taskInfo)).thenReturn(false);

        // Simulate new task being shown
        mController.updateActiveTaskInfo(taskInfo3);
@@ -644,7 +658,8 @@ public class CompatUIControllerTest extends ShellTestCase {
    public void testUpdateActiveTaskInfo_sameTask_notUpdated() {
        // Create new task
        final TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, /* hasSizeCompat= */ true,
                /* isVisible */ true, /* isFocused */ true);
                /* isVisible */ true);
        when(mFocusTransitionObserver.hasGlobalFocus((RunningTaskInfo) taskInfo)).thenReturn(true);

        // Simulate new task being shown
        mController.updateActiveTaskInfo(taskInfo);
@@ -672,7 +687,8 @@ public class CompatUIControllerTest extends ShellTestCase {
    public void testUpdateActiveTaskInfo_transparentTask_notUpdated() {
        // Create new task
        final TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, /* hasSizeCompat= */ true,
                /* isVisible */ true, /* isFocused */ true);
                /* isVisible */ true);
        when(mFocusTransitionObserver.hasGlobalFocus((RunningTaskInfo) taskInfo)).thenReturn(true);

        // Simulate new task being shown
        mController.updateActiveTaskInfo(taskInfo);
@@ -690,7 +706,8 @@ public class CompatUIControllerTest extends ShellTestCase {

        // Create transparent task
        final TaskInfo taskInfo1 = createTaskInfo(DISPLAY_ID, newTaskId, /* hasSizeCompat= */ true,
                /* isVisible */ true, /* isFocused */ true, /* isTopActivityTransparent */ true);
                /* isVisible */ true, /* isTopActivityTransparent */ true);
        when(mFocusTransitionObserver.hasGlobalFocus((RunningTaskInfo) taskInfo)).thenReturn(true);

        // Simulate new task being shown
        mController.updateActiveTaskInfo(taskInfo1);
@@ -706,6 +723,7 @@ public class CompatUIControllerTest extends ShellTestCase {
    public void testLetterboxEduLayout_notCreatedWhenLetterboxEducationIsDisabled() {
        TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, /* hasSizeCompat= */ true);
        taskInfo.appCompatTaskInfo.setLetterboxEducationEnabled(false);
        when(mFocusTransitionObserver.hasGlobalFocus((RunningTaskInfo) taskInfo)).thenReturn(false);

        mController.onCompatInfoChanged(new CompatUIInfo(taskInfo, mMockTaskListener));

@@ -719,6 +737,7 @@ public class CompatUIControllerTest extends ShellTestCase {
    public void testUpdateActiveTaskInfo_removeAllComponentWhenInDesktopModeFlagEnabled() {
        TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, /* hasSizeCompat= */ true);
        when(mDesktopUserRepositories.getCurrent().getVisibleTaskCount(DISPLAY_ID)).thenReturn(0);
        when(mFocusTransitionObserver.hasGlobalFocus((RunningTaskInfo) taskInfo)).thenReturn(false);

        mController.onCompatInfoChanged(new CompatUIInfo(taskInfo, mMockTaskListener));

@@ -737,6 +756,7 @@ public class CompatUIControllerTest extends ShellTestCase {
    public void testUpdateActiveTaskInfo_removeAllComponentWhenInDesktopModeFlagDisabled() {
        when(mDesktopUserRepositories.getCurrent().getVisibleTaskCount(DISPLAY_ID)).thenReturn(0);
        TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, /* hasSizeCompat= */ true);
        when(mFocusTransitionObserver.hasGlobalFocus((RunningTaskInfo) taskInfo)).thenReturn(false);

        mController.onCompatInfoChanged(new CompatUIInfo(taskInfo, mMockTaskListener));

@@ -751,23 +771,22 @@ public class CompatUIControllerTest extends ShellTestCase {

    private static TaskInfo createTaskInfo(int displayId, int taskId, boolean hasSizeCompat) {
        return createTaskInfo(displayId, taskId, hasSizeCompat, /* isVisible */ false,
                /* isFocused */ false, /* isTopActivityTransparent */ false);
                /* isTopActivityTransparent */ false);
    }

    private static TaskInfo createTaskInfo(int displayId, int taskId, boolean hasSizeCompat,
            boolean isVisible, boolean isFocused) {
            boolean isVisible) {
        return createTaskInfo(displayId, taskId, hasSizeCompat,
                isVisible, isFocused, /* isTopActivityTransparent */ false);
                isVisible, /* isTopActivityTransparent */ false);
    }

    private static TaskInfo createTaskInfo(int displayId, int taskId, boolean hasSizeCompat,
            boolean isVisible, boolean isFocused, boolean isTopActivityTransparent) {
            boolean isVisible, boolean isTopActivityTransparent) {
        RunningTaskInfo taskInfo = new RunningTaskInfo();
        taskInfo.taskId = taskId;
        taskInfo.displayId = displayId;
        taskInfo.appCompatTaskInfo.setTopActivityInSizeCompat(hasSizeCompat);
        taskInfo.isVisible = isVisible;
        taskInfo.isFocused = isFocused;
        taskInfo.isTopActivityTransparent = isTopActivityTransparent;
        taskInfo.appCompatTaskInfo.setLetterboxEducationEnabled(true);
        taskInfo.appCompatTaskInfo.setTopActivityLetterboxed(true);