Loading core/java/android/app/TaskInfo.java +17 −0 Original line number Diff line number Diff line Loading @@ -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. */ Loading libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java +0 −1 Original line number Diff line number Diff line Loading @@ -106,5 +106,4 @@ public class FullscreenTaskListener implements ShellTaskOrganizer.TaskListener { public String toString() { return TAG + ":" + taskListenerTypeToString(TASK_LISTENER_TYPE_FULLSCREEN); } } libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java +51 −2 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading Loading @@ -255,6 +269,7 @@ public class ShellTaskOrganizer extends TaskOrganizer { if (listener != null) { listener.onTaskAppeared(info.getTaskInfo(), info.getLeash()); } notifySizeCompatUI(info.getTaskInfo(), listener); } @Override Loading @@ -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); } } } Loading @@ -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 */); } } Loading @@ -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*/); } Loading libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java +26 −2 Original line number Diff line number Diff line Loading @@ -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. */ Loading Loading @@ -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(); Loading Loading @@ -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); Loading Loading @@ -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 Loading Loading @@ -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() { Loading libs/WindowManager/Shell/src/com/android/wm/shell/sizecompatui/SizeCompatUI.java 0 → 100644 +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
core/java/android/app/TaskInfo.java +17 −0 Original line number Diff line number Diff line Loading @@ -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. */ Loading
libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java +0 −1 Original line number Diff line number Diff line Loading @@ -106,5 +106,4 @@ public class FullscreenTaskListener implements ShellTaskOrganizer.TaskListener { public String toString() { return TAG + ":" + taskListenerTypeToString(TASK_LISTENER_TYPE_FULLSCREEN); } }
libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java +51 −2 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading Loading @@ -255,6 +269,7 @@ public class ShellTaskOrganizer extends TaskOrganizer { if (listener != null) { listener.onTaskAppeared(info.getTaskInfo(), info.getLeash()); } notifySizeCompatUI(info.getTaskInfo(), listener); } @Override Loading @@ -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); } } } Loading @@ -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 */); } } Loading @@ -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*/); } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java +26 −2 Original line number Diff line number Diff line Loading @@ -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. */ Loading Loading @@ -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(); Loading Loading @@ -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); Loading Loading @@ -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 Loading Loading @@ -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() { Loading
libs/WindowManager/Shell/src/com/android/wm/shell/sizecompatui/SizeCompatUI.java 0 → 100644 +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); }