Add the KeyboardQuickSwitchView (1/2)

Preparatory change for adding the KeyboardQuickSwitchView and associated flows.

Test: Manually tested alt-tab and alt-shift-tab in and out of overview on a tablet and phone
Bug: 258854035
Change-Id: I468481a023e82d3ef7c7d4d44c5b9435173b49ae
This commit is contained in:
Schneider Victor-tulias
2023-01-24 15:05:08 -08:00
parent 5147b1d509
commit f908729fa8
14 changed files with 442 additions and 44 deletions

View File

@@ -24,8 +24,10 @@ import android.graphics.PointF;
import android.os.Build;
import android.os.SystemClock;
import android.os.Trace;
import android.view.View;
import androidx.annotation.BinderThread;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.UiThread;
@@ -48,7 +50,7 @@ import java.util.HashMap;
public class OverviewCommandHelper {
public static final int TYPE_SHOW = 1;
public static final int TYPE_SHOW_NEXT_FOCUS = 2;
public static final int TYPE_KEYBOARD_INPUT = 2;
public static final int TYPE_HIDE = 3;
public static final int TYPE_TOGGLE = 4;
public static final int TYPE_HOME = 5;
@@ -66,6 +68,13 @@ public class OverviewCommandHelper {
private final TaskAnimationManager mTaskAnimationManager;
private final ArrayList<CommandInfo> mPendingCommands = new ArrayList<>();
/**
* Index of the TaskView that should be focused when launching Overview. Persisted so that we
* do not lose the focus across multiple calls of
* {@link OverviewCommandHelper#executeCommand(CommandInfo)} for the same command
*/
private int mTaskFocusIndexOverride = -1;
public OverviewCommandHelper(TouchInteractionService service,
OverviewComponentObserver observer,
TaskAnimationManager taskAnimationManager) {
@@ -179,6 +188,7 @@ public class OverviewCommandHelper {
// already visible
return true;
case TYPE_HIDE: {
mTaskFocusIndexOverride = -1;
int currentPage = recents.getNextPage();
TaskView tv = (currentPage >= 0 && currentPage < recents.getTaskViewCount())
? (TaskView) recents.getPageAt(currentPage)
@@ -194,15 +204,9 @@ public class OverviewCommandHelper {
}
final Runnable completeCallback = () -> {
if (cmd.type == TYPE_SHOW_NEXT_FOCUS) {
RecentsView rv = activityInterface.getVisibleRecentsView();
// When the overview is launched via alt tab (cmd type is TYPE_SHOW_NEXT_FOCUS),
// the touch mode somehow is not change to false by the Android framework.
// The subsequent tab to go through tasks in overview can only be dispatched to
// focuses views, while focus can only be requested in
// {@link View#requestFocusNoSearch(int, Rect)} when touch mode is false. To note,
// here we launch overview from home.
rv.getViewRootImpl().touchModeChanged(false);
RecentsView rv = activityInterface.getVisibleRecentsView();
if (rv != null && (cmd.type == TYPE_KEYBOARD_INPUT || cmd.type == TYPE_HIDE)) {
updateRecentsViewFocus(rv);
}
scheduleNextTask(cmd);
};
@@ -280,40 +284,55 @@ public class OverviewCommandHelper {
cmd.removeListener(handler);
Trace.endAsyncSection(TRANSITION_NAME, 0);
if (cmd.type == TYPE_SHOW_NEXT_FOCUS) {
RecentsView rv =
mOverviewComponentObserver.getActivityInterface().getVisibleRecentsView();
if (rv != null) {
// When the overview is launched via alt tab (cmd type is TYPE_SHOW_NEXT_FOCUS),
// the touch mode somehow is not change to false by the Android framework.
// The subsequent tab to go through tasks in overview can only be dispatched to
// focuses views, while focus can only be requested in
// {@link View#requestFocusNoSearch(int, Rect)} when touch mode is false. To note,
// here we launch overview with live tile.
rv.getViewRootImpl().touchModeChanged(false);
// Ensure that recents view has focus so that it receives the followup key inputs
TaskView taskView = rv.getNextTaskView();
if (taskView == null) {
taskView = rv.getTaskViewAt(0);
if (taskView != null) {
taskView.requestFocus();
} else {
rv.requestFocus();
}
} else {
taskView.requestFocus();
}
}
RecentsView rv =
mOverviewComponentObserver.getActivityInterface().getVisibleRecentsView();
if (rv != null && (cmd.type == TYPE_KEYBOARD_INPUT || cmd.type == TYPE_HIDE)) {
updateRecentsViewFocus(rv);
}
scheduleNextTask(cmd);
}
private void updateRecentsViewFocus(@NonNull RecentsView rv) {
// When the overview is launched via alt tab (cmd type is TYPE_KEYBOARD_INPUT),
// the touch mode somehow is not change to false by the Android framework.
// The subsequent tab to go through tasks in overview can only be dispatched to
// focuses views, while focus can only be requested in
// {@link View#requestFocusNoSearch(int, Rect)} when touch mode is false. To note,
// here we launch overview with live tile.
rv.getViewRootImpl().touchModeChanged(false);
// Ensure that recents view has focus so that it receives the followup key inputs
TaskView taskView = rv.getTaskViewAt(mTaskFocusIndexOverride);
if (taskView != null) {
requestFocus(taskView);
return;
}
taskView = rv.getNextTaskView();
if (taskView != null) {
requestFocus(taskView);
return;
}
taskView = rv.getTaskViewAt(0);
if (taskView != null) {
requestFocus(taskView);
return;
}
requestFocus(rv);
}
private void requestFocus(@NonNull View view) {
view.post(() -> {
view.requestFocus();
view.requestAccessibilityFocus();
});
}
public void dump(PrintWriter pw) {
pw.println("OverviewCommandHelper:");
pw.println(" mPendingCommands=" + mPendingCommands.size());
if (!mPendingCommands.isEmpty()) {
pw.println(" pendingCommandType=" + mPendingCommands.get(0).type);
}
pw.println(" mTaskFocusIndexOverride=" + mTaskFocusIndexOverride);
}
private static class CommandInfo {