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

Commit 771dfa64 authored by Mariia Sandrikova's avatar Mariia Sandrikova Committed by Android (Google) Code Review
Browse files

Merge "Move letterbox task positioning to LetterboxTaskListener."

parents 7989e6e3 2d81132f
Loading
Loading
Loading
Loading
+24 −1
Original line number Diff line number Diff line
@@ -24,6 +24,8 @@ import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.IBinder;
import android.os.Parcel;
import android.os.RemoteException;
@@ -180,6 +182,20 @@ public class TaskInfo {
     */
    public boolean isResizeable;

    /**
     * Activity bounds if this task or its top activity is presented in letterbox mode and
     * {@code null} otherwise.
     * @hide
     */
    @Nullable
    public Rect letterboxActivityBounds;

    /**
     * Relative position of the task's top left corner in the parent container.
     * @hide
     */
    public Point positionInParent;

    /**
     * The launch cookies associated with activities in this task if any.
     * @see ActivityOptions#setLaunchCookie(IBinder)
@@ -256,6 +272,8 @@ public class TaskInfo {
        topActivityInfo = source.readTypedObject(ActivityInfo.CREATOR);
        isResizeable = source.readBoolean();
        source.readBinderList(launchCookies);
        letterboxActivityBounds = source.readTypedObject(Rect.CREATOR);
        positionInParent = source.readTypedObject(Point.CREATOR);
    }

    /**
@@ -287,6 +305,8 @@ public class TaskInfo {
        dest.writeTypedObject(topActivityInfo, flags);
        dest.writeBoolean(isResizeable);
        dest.writeBinderList(launchCookies);
        dest.writeTypedObject(letterboxActivityBounds, flags);
        dest.writeTypedObject(positionInParent, flags);
    }

    @Override
@@ -306,6 +326,9 @@ public class TaskInfo {
                + " topActivityType=" + topActivityType
                + " pictureInPictureParams=" + pictureInPictureParams
                + " topActivityInfo=" + topActivityInfo
                + " launchCookies" + launchCookies;
                + " launchCookies" + launchCookies
                + " letterboxActivityBounds=" + letterboxActivityBounds
                + " positionInParent=" + positionInParent
                + "}";
    }
}
+18 −0
Original line number Diff line number Diff line
@@ -55,6 +55,12 @@
      "group": "WM_SHELL_TASK_ORG",
      "at": "com\/android\/wm\/shell\/ShellTaskOrganizer.java"
    },
    "-848099324": {
      "message": "Letterbox Task Appeared: #%d",
      "level": "VERBOSE",
      "group": "WM_SHELL_TASK_ORG",
      "at": "com\/android\/wm\/shell\/LetterboxTaskListener.java"
    },
    "-712674749": {
      "message": "Clip description: %s",
      "level": "VERBOSE",
@@ -115,12 +121,24 @@
      "group": "WM_SHELL_TASK_ORG",
      "at": "com\/android\/wm\/shell\/ShellTaskOrganizer.java"
    },
    "1104702476": {
      "message": "Letterbox Task Changed: #%d",
      "level": "VERBOSE",
      "group": "WM_SHELL_TASK_ORG",
      "at": "com\/android\/wm\/shell\/LetterboxTaskListener.java"
    },
    "1184615936": {
      "message": "Set drop target window visibility: displayId=%d visibility=%d",
      "level": "VERBOSE",
      "group": "WM_SHELL_DRAG_AND_DROP",
      "at": "com\/android\/wm\/shell\/draganddrop\/DragAndDropController.java"
    },
    "1218010718": {
      "message": "Letterbox Task Vanished: #%d",
      "level": "VERBOSE",
      "group": "WM_SHELL_TASK_ORG",
      "at": "com\/android\/wm\/shell\/LetterboxTaskListener.java"
    },
    "1481772149": {
      "message": "Current target: %s",
      "level": "VERBOSE",
+6 −33
Original line number Diff line number Diff line
@@ -20,9 +20,7 @@ import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_FULLSCR
import static com.android.wm.shell.ShellTaskOrganizer.taskListenerTypeToString;

import android.app.ActivityManager;
import android.content.res.Configuration;
import android.graphics.Rect;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Slog;
import android.view.SurfaceControl;

@@ -39,7 +37,7 @@ class FullscreenTaskListener implements ShellTaskOrganizer.TaskListener {

    private final SyncTransactionQueue mSyncQueue;

    private final ArrayMap<Integer, SurfaceControl> mTasks = new ArrayMap<>();
    private final ArraySet<Integer> mTasks = new ArraySet<>();

    FullscreenTaskListener(SyncTransactionQueue syncQueue) {
        mSyncQueue = syncQueue;
@@ -48,17 +46,17 @@ class FullscreenTaskListener implements ShellTaskOrganizer.TaskListener {
    @Override
    public void onTaskAppeared(ActivityManager.RunningTaskInfo taskInfo, SurfaceControl leash) {
        synchronized (mTasks) {
            if (mTasks.containsKey(taskInfo.taskId)) {
            if (mTasks.contains(taskInfo.taskId)) {
                throw new RuntimeException("Task appeared more than once: #" + taskInfo.taskId);
            }
            ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Fullscreen Task Appeared: #%d",
                    taskInfo.taskId);
            mTasks.put(taskInfo.taskId, leash);
            mTasks.add(taskInfo.taskId);
            mSyncQueue.runInSync(t -> {
                // Reset several properties back to fullscreen (PiP, for example, leaves all these
                // properties in a bad state).
                updateSurfacePosition(t, taskInfo, leash);
                t.setWindowCrop(leash, null);
                t.setPosition(leash, 0, 0);
                // TODO(shell-transitions): Eventually set everything in transition so there's no
                //                          SF Transaction here.
                if (!Transitions.ENABLE_SHELL_TRANSITIONS) {
@@ -73,7 +71,7 @@ class FullscreenTaskListener implements ShellTaskOrganizer.TaskListener {
    @Override
    public void onTaskVanished(ActivityManager.RunningTaskInfo taskInfo) {
        synchronized (mTasks) {
            if (mTasks.remove(taskInfo.taskId) == null) {
            if (!mTasks.remove(taskInfo.taskId)) {
                Slog.e(TAG, "Task already vanished: #" + taskInfo.taskId);
                return;
            }
@@ -82,23 +80,6 @@ class FullscreenTaskListener implements ShellTaskOrganizer.TaskListener {
        }
    }

    @Override
    public void onTaskInfoChanged(ActivityManager.RunningTaskInfo taskInfo) {
        synchronized (mTasks) {
            if (!mTasks.containsKey(taskInfo.taskId)) {
                Slog.e(TAG, "Changed Task wasn't appeared or already vanished: #"
                        + taskInfo.taskId);
                return;
            }
            final SurfaceControl leash = mTasks.get(taskInfo.taskId);
            mSyncQueue.runInSync(t -> {
                // Reposition the task in case the bounds has been changed (such as Task level
                // letterboxing).
                updateSurfacePosition(t, taskInfo, leash);
            });
        }
    }

    @Override
    public void dump(@NonNull PrintWriter pw, String prefix) {
        final String innerPrefix = prefix + "  ";
@@ -112,12 +93,4 @@ class FullscreenTaskListener implements ShellTaskOrganizer.TaskListener {
        return TAG + ":" + taskListenerTypeToString(TASK_LISTENER_TYPE_FULLSCREEN);
    }

    /** Places the Task surface to the latest position. */
    private static void updateSurfacePosition(SurfaceControl.Transaction t,
            ActivityManager.RunningTaskInfo taskInfo, SurfaceControl leash) {
        // TODO(170725334) drop this after ag/12876439
        final Configuration config = taskInfo.getConfiguration();
        final Rect bounds = config.windowConfiguration.getBounds();
        t.setPosition(leash, bounds.left, bounds.top);
    }
}
+110 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.wm.shell;

import android.app.ActivityManager;
import android.graphics.Point;
import android.graphics.Rect;
import android.util.Slog;
import android.util.SparseArray;
import android.view.SurfaceControl;

import com.android.internal.protolog.common.ProtoLog;
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.protolog.ShellProtoLogGroup;

/**
  * Organizes a task in {@link android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN} when
  * it's presented in the letterbox mode either because orientations of a top activity and a device
  * don't match or because a top activity is in a size compat mode.
  */
final class LetterboxTaskListener implements ShellTaskOrganizer.TaskListener {
    private static final String TAG = "LetterboxTaskListener";

    private final SyncTransactionQueue mSyncQueue;

    private final SparseArray<SurfaceControl> mLeashByTaskId = new SparseArray<>();

    LetterboxTaskListener(SyncTransactionQueue syncQueue) {
        mSyncQueue = syncQueue;
    }

    @Override
    public void onTaskAppeared(ActivityManager.RunningTaskInfo taskInfo, SurfaceControl leash) {
        synchronized (mLeashByTaskId) {
            if (mLeashByTaskId.get(taskInfo.taskId) != null) {
                throw new RuntimeException("Task appeared more than once: #" + taskInfo.taskId);
            }
            ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Letterbox Task Appeared: #%d",
                    taskInfo.taskId);
            mLeashByTaskId.put(taskInfo.taskId, leash);
            final Rect taskBounds = taskInfo.getConfiguration().windowConfiguration.getBounds();
            final Rect activtyBounds = taskInfo.letterboxActivityBounds;
            final Point taskPositionInParent = taskInfo.positionInParent;
            mSyncQueue.runInSync(t -> {
                setPositionAndWindowCrop(
                        t, leash, activtyBounds, taskBounds, taskPositionInParent);
                if (!Transitions.ENABLE_SHELL_TRANSITIONS) {
                    t.setAlpha(leash, 1f);
                    t.setMatrix(leash, 1, 0, 0, 1);
                    t.show(leash);
                }
            });
        }
    }

    @Override
    public void onTaskVanished(ActivityManager.RunningTaskInfo taskInfo) {
        synchronized (mLeashByTaskId) {
            if (mLeashByTaskId.get(taskInfo.taskId) == null) {
                Slog.e(TAG, "Task already vanished: #" + taskInfo.taskId);
                return;
            }
            mLeashByTaskId.remove(taskInfo.taskId);
            ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Letterbox Task Vanished: #%d",
                    taskInfo.taskId);
        }
    }

    @Override
    public void onTaskInfoChanged(ActivityManager.RunningTaskInfo taskInfo) {
        synchronized (mLeashByTaskId) {
            ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Letterbox Task Changed: #%d",
                    taskInfo.taskId);
            final SurfaceControl leash = mLeashByTaskId.get(taskInfo.taskId);
            final Rect taskBounds = taskInfo.getConfiguration().windowConfiguration.getBounds();
            final Rect activtyBounds = taskInfo.letterboxActivityBounds;
            final Point taskPositionInParent = taskInfo.positionInParent;
            mSyncQueue.runInSync(t -> {
                setPositionAndWindowCrop(
                        t, leash, activtyBounds, taskBounds, taskPositionInParent);
            });
        }
    }

    private static void setPositionAndWindowCrop(
                SurfaceControl.Transaction transaction,
                SurfaceControl leash,
                final Rect activityBounds,
                final Rect taskBounds,
                final Point taskPositionInParent) {
        Rect activtyInTaskCoordinates =  new Rect(activityBounds);
        activtyInTaskCoordinates.offset(-taskBounds.left, -taskBounds.top);
        transaction.setPosition(leash, taskPositionInParent.x, taskPositionInParent.y);
        transaction.setWindowCrop(leash, activtyInTaskCoordinates);
    }
}
+12 −6
Original line number Diff line number Diff line
@@ -45,7 +45,6 @@ import com.android.internal.protolog.common.ProtoLog;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.common.TransactionPool;
import com.android.wm.shell.protolog.ShellProtoLogGroup;

import java.io.PrintWriter;
import java.util.ArrayList;
@@ -65,6 +64,7 @@ public class ShellTaskOrganizer extends TaskOrganizer {
    public static final int TASK_LISTENER_TYPE_MULTI_WINDOW = -3;
    public static final int TASK_LISTENER_TYPE_PIP = -4;
    public static final int TASK_LISTENER_TYPE_SPLIT_SCREEN = -5;
    public static final int TASK_LISTENER_TYPE_LETTERBOX = -6;

    @IntDef(prefix = {"TASK_LISTENER_TYPE_"}, value = {
            TASK_LISTENER_TYPE_UNDEFINED,
@@ -72,6 +72,7 @@ public class ShellTaskOrganizer extends TaskOrganizer {
            TASK_LISTENER_TYPE_MULTI_WINDOW,
            TASK_LISTENER_TYPE_PIP,
            TASK_LISTENER_TYPE_SPLIT_SCREEN,
            TASK_LISTENER_TYPE_LETTERBOX,
    })
    public @interface TaskListenerType {}

@@ -118,6 +119,7 @@ public class ShellTaskOrganizer extends TaskOrganizer {
            ShellExecutor mainExecutor, ShellExecutor animExecutor) {
        super(taskOrganizerController, mainExecutor);
        addListenerForType(new FullscreenTaskListener(syncQueue), TASK_LISTENER_TYPE_FULLSCREEN);
        addListenerForType(new LetterboxTaskListener(syncQueue), TASK_LISTENER_TYPE_LETTERBOX);
        mTransitions = new Transitions(this, transactionPool, mainExecutor, animExecutor);
        if (Transitions.ENABLE_SHELL_TRANSITIONS) registerTransitionPlayer(mTransitions);
    }
@@ -329,8 +331,7 @@ public class ShellTaskOrganizer extends TaskOrganizer {
        if (listener != null) return listener;

        // Next we try type specific listeners.
        final int windowingMode = getWindowingMode(runningTaskInfo);
        final int taskListenerType = windowingModeToTaskListenerType(windowingMode);
        final int taskListenerType = taskInfoToTaskListenerType(runningTaskInfo);
        return mTaskListeners.get(taskListenerType);
    }

@@ -339,11 +340,14 @@ public class ShellTaskOrganizer extends TaskOrganizer {
        return taskInfo.configuration.windowConfiguration.getWindowingMode();
    }

    private static @TaskListenerType int windowingModeToTaskListenerType(
            @WindowingMode int windowingMode) {
    @VisibleForTesting
    static @TaskListenerType int taskInfoToTaskListenerType(RunningTaskInfo runningTaskInfo) {
        final int windowingMode = getWindowingMode(runningTaskInfo);
        switch (windowingMode) {
            case WINDOWING_MODE_FULLSCREEN:
                return TASK_LISTENER_TYPE_FULLSCREEN;
                return runningTaskInfo.letterboxActivityBounds != null
                        ? TASK_LISTENER_TYPE_LETTERBOX
                        : TASK_LISTENER_TYPE_FULLSCREEN;
            case WINDOWING_MODE_MULTI_WINDOW:
                return TASK_LISTENER_TYPE_MULTI_WINDOW;
            case WINDOWING_MODE_SPLIT_SCREEN_PRIMARY:
@@ -362,6 +366,8 @@ public class ShellTaskOrganizer extends TaskOrganizer {
        switch (type) {
            case TASK_LISTENER_TYPE_FULLSCREEN:
                return "TASK_LISTENER_TYPE_FULLSCREEN";
            case TASK_LISTENER_TYPE_LETTERBOX:
                return "TASK_LISTENER_TYPE_LETTERBOX";
            case TASK_LISTENER_TYPE_MULTI_WINDOW:
                return "TASK_LISTENER_TYPE_MULTI_WINDOW";
            case TASK_LISTENER_TYPE_SPLIT_SCREEN:
Loading