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

Commit 98d2d061 authored by Chris Li's avatar Chris Li
Browse files

Allow non-resizable apps in split-screen (7/n)

Add interface for SizeCompatUIController in WM shell to use
when refactoring SizeCompatModeActivityController from system UI.

Bug: 176061101
Bug: 178327644
Test: atest WMShellUnitTests:ShellTaskOrganizerTests
Change-Id: I37f72396e1769b7773722be6575506fc430b2739
parent 0ac1939c
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -336,6 +336,23 @@ public class TaskInfo {
                && isVisible == that.isVisible;
    }

    /**
     * @return {@code true} if parameters that are important for size compat have changed.
     * @hide
     */
    public boolean equalsForSizeCompat(@Nullable TaskInfo that) {
        if (that == null) {
            return false;
        }
        return displayId == that.displayId
                && taskId == that.taskId
                && topActivityInSizeCompat == that.topActivityInSizeCompat
                // TopActivityToken and bounds are important if top activity is in size compat
                && (!topActivityInSizeCompat || topActivityToken.equals(that.topActivityToken))
                && (!topActivityInSizeCompat || configuration.windowConfiguration.getBounds()
                    .equals(that.configuration.windowConfiguration.getBounds()));
    }

    /**
     * Reads the TaskInfo from a parcel.
     */
+0 −1
Original line number Diff line number Diff line
@@ -106,5 +106,4 @@ public class FullscreenTaskListener implements ShellTaskOrganizer.TaskListener {
    public String toString() {
        return TAG + ":" + taskListenerTypeToString(TASK_LISTENER_TYPE_FULLSCREEN);
    }

}
+51 −2
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@ import androidx.annotation.Nullable;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.protolog.common.ProtoLog;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.sizecompatui.SizeCompatUI;
import com.android.wm.shell.startingsurface.StartingSurfaceDrawer;

import java.io.PrintWriter;
@@ -102,18 +103,31 @@ public class ShellTaskOrganizer extends TaskOrganizer {
    private final Object mLock = new Object();
    private final StartingSurfaceDrawer mStartingSurfaceDrawer;

    /**
     * In charge of showing size compat UI. Can be {@code null} if device doesn't support size
     * compat.
     */
    @Nullable
    private final SizeCompatUI mSizeCompatUI;

    public ShellTaskOrganizer(ShellExecutor mainExecutor, Context context) {
        this(null, mainExecutor, context);
        this(null /* taskOrganizerController */, mainExecutor, context, null /* sizeCompatUI */);
    }

    public ShellTaskOrganizer(ShellExecutor mainExecutor, Context context, @Nullable
            SizeCompatUI sizeCompatUI) {
        this(null /* taskOrganizerController */, mainExecutor, context, sizeCompatUI);
    }

    @VisibleForTesting
    ShellTaskOrganizer(ITaskOrganizerController taskOrganizerController, ShellExecutor mainExecutor,
            Context context) {
            Context context, @Nullable SizeCompatUI sizeCompatUI) {
        super(taskOrganizerController, mainExecutor);
        // TODO(b/131727939) temporarily live here, the starting surface drawer should be controlled
        //  by a controller, that class should be create while porting
        //  ActivityRecord#addStartingWindow to WMShell.
        mStartingSurfaceDrawer = new StartingSurfaceDrawer(context, mainExecutor);
        mSizeCompatUI = sizeCompatUI;
    }

    @Override
@@ -255,6 +269,7 @@ public class ShellTaskOrganizer extends TaskOrganizer {
        if (listener != null) {
            listener.onTaskAppeared(info.getTaskInfo(), info.getLeash());
        }
        notifySizeCompatUI(info.getTaskInfo(), listener);
    }

    @Override
@@ -270,6 +285,10 @@ public class ShellTaskOrganizer extends TaskOrganizer {
            if (!updated && newListener != null) {
                newListener.onTaskInfoChanged(taskInfo);
            }
            if (updated || !taskInfo.equalsForSizeCompat(data.getTaskInfo())) {
                // Notify the size compat UI if the listener or task info changed.
                notifySizeCompatUI(taskInfo, newListener);
            }
        }
    }

@@ -294,6 +313,8 @@ public class ShellTaskOrganizer extends TaskOrganizer {
            if (listener != null) {
                listener.onTaskVanished(taskInfo);
            }
            // Pass null for listener to remove the size compat UI on this task if there is any.
            notifySizeCompatUI(taskInfo, null /* taskListener */);
        }
    }

@@ -320,6 +341,34 @@ public class ShellTaskOrganizer extends TaskOrganizer {
        return true;
    }

    /**
     * Notifies {@link SizeCompatUI} about the size compat info changed on the give Task to update
     * the UI accordingly.
     *
     * @param taskInfo the new Task info
     * @param taskListener listener to handle the Task Surface placement. {@code null} if task is
     *                     vanished.
     */
    private void notifySizeCompatUI(RunningTaskInfo taskInfo, @Nullable TaskListener taskListener) {
        if (mSizeCompatUI == null) {
            return;
        }

        // The task is vanished, notify to remove size compat UI on this Task if there is any.
        if (taskListener == null) {
            mSizeCompatUI.onSizeCompatInfoChanged(taskInfo.displayId, taskInfo.taskId,
                    null /* taskConfig */, null /* sizeCompatActivity*/,
                    null /* taskListener */);
            return;
        }

        mSizeCompatUI.onSizeCompatInfoChanged(taskInfo.displayId, taskInfo.taskId,
                taskInfo.configuration.windowConfiguration.getBounds(),
                // null if the top activity not in size compat.
                taskInfo.topActivityInSizeCompat ? taskInfo.topActivityToken : null,
                taskListener);
    }

    private TaskListener getTaskListener(RunningTaskInfo runningTaskInfo) {
        return getTaskListener(runningTaskInfo, false /*removeLaunchCookieIfNeeded*/);
    }
+26 −2
Original line number Diff line number Diff line
@@ -159,6 +159,14 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged
        }
    }

    private void dispatchVisibilityChanged(int displayId, boolean isShowing) {
        synchronized (mPositionProcessors) {
            for (ImePositionProcessor pp : mPositionProcessors) {
                pp.onImeVisibilityChanged(displayId, isShowing);
            }
        }
    }

    /**
     * Adds an {@link ImePositionProcessor} to be called during ime position updates.
     */
@@ -212,7 +220,7 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged
                return;
            }

            mImeShowing = insetsState.getSourceOrDefaultVisibility(InsetsState.ITYPE_IME);
            updateImeVisibility(insetsState.getSourceOrDefaultVisibility(InsetsState.ITYPE_IME));

            final InsetsSource newSource = insetsState.getSource(InsetsState.ITYPE_IME);
            final Rect newFrame = newSource.getFrame();
@@ -371,7 +379,7 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged
                seek = true;
            }
            mAnimationDirection = show ? DIRECTION_SHOW : DIRECTION_HIDE;
            mImeShowing = show;
            updateImeVisibility(show);
            mAnimation = ValueAnimator.ofFloat(startY, endY);
            mAnimation.setDuration(
                    show ? ANIMATION_DURATION_SHOW_MS : ANIMATION_DURATION_HIDE_MS);
@@ -455,6 +463,13 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged
            }
        }

        private void updateImeVisibility(boolean isShowing) {
            if (mImeShowing != isShowing) {
                mImeShowing = isShowing;
                dispatchVisibilityChanged(mDisplayId, isShowing);
            }
        }

        @VisibleForTesting
        @BinderThread
        public class DisplayWindowInsetsControllerImpl
@@ -563,6 +578,15 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged
        default void onImeEndPositioning(int displayId, boolean cancel,
                SurfaceControl.Transaction t) {
        }

        /**
         * Called when the IME visibility changed.
         *
         * @param isShowing {@code true} if the IME is shown.
         */
        default void onImeVisibilityChanged(int displayId, boolean isShowing) {

        }
    }

    public IInputMethodManager getImms() {
+45 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 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.sizecompatui;

import android.annotation.Nullable;
import android.graphics.Rect;
import android.os.IBinder;

import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.annotations.ExternalThread;

/**
 * Interface to engage size compat mode UI.
 */
@ExternalThread
public interface SizeCompatUI {
    /**
     * Called when the Task info changed. Creates and updates the restart button if there is an
     * activity in size compat, or removes the restart button if there is no size compat activity.
     *
     * @param displayId display the task and activity are in.
     * @param taskId task the activity is in.
     * @param taskBounds task bounds to place the restart button in.
     * @param sizeCompatActivity the size compat activity in the task. Can be {@code null} if the
     *                           top activity in this Task is not in size compat.
     * @param taskListener listener to handle the Task Surface placement.
     */
    void onSizeCompatInfoChanged(int displayId, int taskId, @Nullable Rect taskBounds,
            @Nullable IBinder sizeCompatActivity,
            @Nullable ShellTaskOrganizer.TaskListener taskListener);
}
Loading