diff --git a/core/java/android/app/TaskInfo.java b/core/java/android/app/TaskInfo.java index f3f00e50715b3..f99d4e937f920 100644 --- a/core/java/android/app/TaskInfo.java +++ b/core/java/android/app/TaskInfo.java @@ -176,6 +176,13 @@ public class TaskInfo { */ public boolean isResizeable; + /** + * Screen orientation set by {@link #baseActivity} via + * {@link Activity#setRequestedOrientation(int)}. + * @hide + */ + public @ActivityInfo.ScreenOrientation int requestedOrientation; + TaskInfo() { // Do nothing } @@ -247,6 +254,7 @@ public class TaskInfo { ? ActivityInfo.CREATOR.createFromParcel(source) : null; isResizeable = source.readBoolean(); + requestedOrientation = source.readInt(); } /** @@ -297,6 +305,7 @@ public class TaskInfo { topActivityInfo.writeToParcel(dest, flags); } dest.writeBoolean(isResizeable); + dest.writeInt(requestedOrientation); } @Override @@ -315,6 +324,7 @@ public class TaskInfo { + " token=" + token + " topActivityType=" + topActivityType + " pictureInPictureParams=" + pictureInPictureParams - + " topActivityInfo=" + topActivityInfo; + + " topActivityInfo=" + topActivityInfo + + " requestedOrientation=" + requestedOrientation; } } diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java index d19fc013bd8d3..8d4ca5e46fae1 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java +++ b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java @@ -40,7 +40,6 @@ import android.app.PictureInPictureParams; import android.content.ComponentName; import android.content.Context; import android.content.pm.ActivityInfo; -import android.content.res.Configuration; import android.graphics.Rect; import android.os.Handler; import android.os.IBinder; @@ -104,7 +103,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements private final Rect mLastReportedBounds = new Rect(); private final int mEnterExitAnimationDuration; private final PipSurfaceTransactionHelper mSurfaceTransactionHelper; - private final Map mInitialState = new HashMap<>(); + private final Map mCompactState = new HashMap<>(); private final Divider mSplitDivider; // These callbacks are called on the update thread @@ -202,6 +201,8 @@ public class PipTaskOrganizer extends TaskOrganizer implements */ private boolean mShouldDeferEnteringPip; + private @ActivityInfo.ScreenOrientation int mRequestedOrientation; + @Inject public PipTaskOrganizer(Context context, @NonNull PipBoundsHandler boundsHandler, @NonNull PipSurfaceTransactionHelper surfaceTransactionHelper, @@ -281,11 +282,13 @@ public class PipTaskOrganizer extends TaskOrganizer implements mPipUiEventLoggerLogger.log( PipUiEventLogger.PipUiEventEnum.PICTURE_IN_PICTURE_EXPAND_TO_FULLSCREEN); - final Configuration initialConfig = mInitialState.remove(mToken.asBinder()); - final boolean orientationDiffers = initialConfig.windowConfiguration.getRotation() + final PipWindowConfigurationCompact config = mCompactState.remove(mToken.asBinder()); + config.syncWithScreenOrientation(mRequestedOrientation, + mPipBoundsHandler.getDisplayRotation()); + final boolean orientationDiffers = config.getRotation() != mPipBoundsHandler.getDisplayRotation(); final WindowContainerTransaction wct = new WindowContainerTransaction(); - final Rect destinationBounds = initialConfig.windowConfiguration.getBounds(); + final Rect destinationBounds = config.getBounds(); final int direction = syncWithSplitScreenBounds(destinationBounds) ? TRANSITION_DIRECTION_TO_SPLIT_SCREEN : TRANSITION_DIRECTION_TO_FULLSCREEN; @@ -351,7 +354,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements .setPipAnimationCallback(mPipAnimationCallback) .setDuration(mEnterExitAnimationDuration) .start()); - mInitialState.remove(mToken.asBinder()); + mCompactState.remove(mToken.asBinder()); mExitingPip = true; } @@ -377,8 +380,10 @@ public class PipTaskOrganizer extends TaskOrganizer implements mInPip = true; mExitingPip = false; mLeash = leash; - mInitialState.put(mToken.asBinder(), new Configuration(mTaskInfo.configuration)); + mCompactState.put(mToken.asBinder(), + new PipWindowConfigurationCompact(mTaskInfo.configuration.windowConfiguration)); mPictureInPictureParams = mTaskInfo.pictureInPictureParams; + mRequestedOrientation = info.requestedOrientation; mPipUiEventLoggerLogger.setTaskInfo(mTaskInfo); mPipUiEventLoggerLogger.log(PipUiEventLogger.PipUiEventEnum.PICTURE_IN_PICTURE_ENTER); @@ -521,6 +526,8 @@ public class PipTaskOrganizer extends TaskOrganizer implements @Override public void onTaskInfoChanged(ActivityManager.RunningTaskInfo info) { Objects.requireNonNull(mToken, "onTaskInfoChanged requires valid existing mToken"); + mRequestedOrientation = info.requestedOrientation; + // check PictureInPictureParams for aspect ratio change. final PictureInPictureParams newParams = info.pictureInPictureParams; if (newParams == null || !applyPictureInPictureParams(newParams)) { Log.d(TAG, "Ignored onTaskInfoChanged with PiP param: " + newParams); @@ -558,8 +565,6 @@ public class PipTaskOrganizer extends TaskOrganizer implements } /** - * TODO(b/152809058): consolidate the display info handling logic in SysUI - * * @param destinationBoundsOut the current destination bounds will be populated to this param */ @SuppressWarnings("unchecked") @@ -963,9 +968,9 @@ public class PipTaskOrganizer extends TaskOrganizer implements pw.println(innerPrefix + "mPictureInPictureParams=" + mPictureInPictureParams); pw.println(innerPrefix + "mLastReportedBounds=" + mLastReportedBounds); pw.println(innerPrefix + "mInitialState:"); - for (Map.Entry e : mInitialState.entrySet()) { + for (Map.Entry e : mCompactState.entrySet()) { pw.println(innerPrefix + " binder=" + e.getKey() - + " winConfig=" + e.getValue().windowConfiguration); + + " config=" + e.getValue()); } } diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipWindowConfigurationCompact.java b/packages/SystemUI/src/com/android/systemui/pip/PipWindowConfigurationCompact.java new file mode 100644 index 0000000000000..ba104d676cd2a --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/pip/PipWindowConfigurationCompact.java @@ -0,0 +1,80 @@ +/* + * 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.systemui.pip; + +import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; +import static android.view.Surface.ROTATION_0; +import static android.view.Surface.ROTATION_180; +import static android.view.Surface.ROTATION_270; +import static android.view.Surface.ROTATION_90; + +import android.app.WindowConfiguration; +import android.content.pm.ActivityInfo; +import android.graphics.Rect; +import android.view.Surface; + +/** + * Compact {@link WindowConfiguration} for PiP usage and supports operations such as rotate. + */ +class PipWindowConfigurationCompact { + private @Surface.Rotation int mRotation; + private Rect mBounds; + + PipWindowConfigurationCompact(WindowConfiguration windowConfiguration) { + mRotation = windowConfiguration.getRotation(); + mBounds = windowConfiguration.getBounds(); + } + + @Surface.Rotation int getRotation() { + return mRotation; + } + + Rect getBounds() { + return mBounds; + } + + void syncWithScreenOrientation(@ActivityInfo.ScreenOrientation int screenOrientation, + @Surface.Rotation int displayRotation) { + if (mBounds.top != 0 || mBounds.left != 0) { + // Supports fullscreen bounds like (0, 0, width, height) only now. + return; + } + boolean rotateNeeded = false; + if (ActivityInfo.isFixedOrientationPortrait(screenOrientation) + && (mRotation == ROTATION_90 || mRotation == ROTATION_270)) { + mRotation = ROTATION_0; + rotateNeeded = true; + } else if (ActivityInfo.isFixedOrientationLandscape(screenOrientation) + && (mRotation == ROTATION_0 || mRotation == ROTATION_180)) { + mRotation = ROTATION_90; + rotateNeeded = true; + } else if (screenOrientation == SCREEN_ORIENTATION_UNSPECIFIED + && mRotation != displayRotation) { + mRotation = displayRotation; + rotateNeeded = true; + } + if (rotateNeeded) { + mBounds.set(0, 0, mBounds.height(), mBounds.width()); + } + } + + @Override + public String toString() { + return "PipWindowConfigurationCompact(rotation=" + mRotation + + " bounds=" + mBounds + ")"; + } +} diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index 76927e2774129..954b7a026bf54 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -3627,6 +3627,9 @@ class Task extends WindowContainer { info.topActivityInfo = mReuseActivitiesReport.top != null ? mReuseActivitiesReport.top.info : null; + info.requestedOrientation = mReuseActivitiesReport.base != null + ? mReuseActivitiesReport.base.getRequestedOrientation() + : SCREEN_ORIENTATION_UNSET; } /** diff --git a/services/core/java/com/android/server/wm/TaskOrganizerController.java b/services/core/java/com/android/server/wm/TaskOrganizerController.java index f70bf18cdea57..e153befde8ad5 100644 --- a/services/core/java/com/android/server/wm/TaskOrganizerController.java +++ b/services/core/java/com/android/server/wm/TaskOrganizerController.java @@ -458,7 +458,8 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { || mTmpTaskInfo.topActivityType != lastInfo.topActivityType || mTmpTaskInfo.isResizeable != lastInfo.isResizeable || mTmpTaskInfo.pictureInPictureParams != lastInfo.pictureInPictureParams - || !TaskDescription.equals(mTmpTaskInfo.taskDescription, lastInfo.taskDescription); + || !TaskDescription.equals(mTmpTaskInfo.taskDescription, lastInfo.taskDescription) + || mTmpTaskInfo.requestedOrientation != lastInfo.requestedOrientation; if (!changed) { int cfgChanges = mTmpTaskInfo.configuration.diff(lastInfo.configuration); final int winCfgChanges = (cfgChanges & ActivityInfo.CONFIG_WINDOW_CONFIGURATION) != 0