Fix getOrientation from adjacent TaskFragments
Before, we returned SCREEN_ORIENTATION_UNSET from TaskFragments in split. Now, we returned SCREEN_ORIENTATION_UNSPECIFIED just like system split screen, so that the display can update to device orientation after exiting a fullscreen fixed-orientation activity to ActivityEmbedding split. Bug: 255646506 Test: atest WmTests:TaskFragmentTest Change-Id: Iee97547aa5697df050b1e01070d9bad643325f14
This commit is contained in:
@@ -20,9 +20,6 @@ import static android.app.ActivityTaskManager.INVALID_TASK_ID;
|
||||
import static android.app.ActivityTaskManager.RESIZE_MODE_FORCED;
|
||||
import static android.app.ActivityTaskManager.RESIZE_MODE_SYSTEM_SCREEN_ROTATION;
|
||||
import static android.app.ITaskStackListener.FORCED_RESIZEABLE_REASON_SPLIT_SCREEN;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
|
||||
@@ -3128,20 +3125,6 @@ class Task extends TaskFragment {
|
||||
return mTaskDescription;
|
||||
}
|
||||
|
||||
@Override
|
||||
int getOrientation(int candidate) {
|
||||
return canSpecifyOrientation() ? super.getOrientation(candidate) : SCREEN_ORIENTATION_UNSET;
|
||||
}
|
||||
|
||||
private boolean canSpecifyOrientation() {
|
||||
final int windowingMode = getWindowingMode();
|
||||
final int activityType = getActivityType();
|
||||
return windowingMode == WINDOWING_MODE_FULLSCREEN
|
||||
|| activityType == ACTIVITY_TYPE_HOME
|
||||
|| activityType == ACTIVITY_TYPE_RECENTS
|
||||
|| activityType == ACTIVITY_TYPE_ASSISTANT;
|
||||
}
|
||||
|
||||
@Override
|
||||
void forAllLeafTasks(Consumer<Task> callback, boolean traverseTopToBottom) {
|
||||
final int count = mChildren.size();
|
||||
|
||||
@@ -27,7 +27,6 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
|
||||
import static android.content.Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT;
|
||||
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
|
||||
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
|
||||
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
|
||||
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
|
||||
|
||||
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ORIENTATION;
|
||||
@@ -649,17 +648,6 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> {
|
||||
}, SCREEN_ORIENTATION_UNSET);
|
||||
}
|
||||
|
||||
// Apps and their containers are not allowed to specify an orientation of non floating
|
||||
// visible tasks created by organizer and that has an adjacent task.
|
||||
final Task nonFloatingTopTask =
|
||||
getTask(t -> !t.getWindowConfiguration().tasksAreFloating());
|
||||
if (nonFloatingTopTask != null) {
|
||||
final Task task = nonFloatingTopTask.getCreatedByOrganizerTask();
|
||||
if (task != null && task.getAdjacentTaskFragment() != null && task.isVisible()) {
|
||||
return SCREEN_ORIENTATION_UNSPECIFIED;
|
||||
}
|
||||
}
|
||||
|
||||
final int orientation = super.getOrientation(candidate);
|
||||
if (orientation != SCREEN_ORIENTATION_UNSET
|
||||
&& orientation != SCREEN_ORIENTATION_BEHIND) {
|
||||
|
||||
@@ -17,7 +17,9 @@
|
||||
package com.android.server.wm;
|
||||
|
||||
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
|
||||
import static android.app.WindowConfiguration.ROTATION_UNDEFINED;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
|
||||
@@ -27,6 +29,8 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
|
||||
import static android.content.pm.ActivityInfo.FLAG_ALLOW_UNTRUSTED_ACTIVITY_EMBEDDING;
|
||||
import static android.content.pm.ActivityInfo.FLAG_RESUME_WHILE_PAUSING;
|
||||
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
|
||||
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
|
||||
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
|
||||
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
|
||||
import static android.content.res.Configuration.ORIENTATION_UNDEFINED;
|
||||
@@ -76,6 +80,7 @@ import android.app.servertransaction.ClientTransaction;
|
||||
import android.app.servertransaction.NewIntentItem;
|
||||
import android.app.servertransaction.PauseActivityItem;
|
||||
import android.app.servertransaction.ResumeActivityItem;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.Rect;
|
||||
@@ -1807,6 +1812,51 @@ class TaskFragment extends WindowContainer<WindowContainer> {
|
||||
}
|
||||
}
|
||||
|
||||
@ActivityInfo.ScreenOrientation
|
||||
@Override
|
||||
int getOrientation(@ActivityInfo.ScreenOrientation int candidate) {
|
||||
if (shouldReportOrientationUnspecified()) {
|
||||
return SCREEN_ORIENTATION_UNSPECIFIED;
|
||||
}
|
||||
if (canSpecifyOrientation()) {
|
||||
return super.getOrientation(candidate);
|
||||
}
|
||||
return SCREEN_ORIENTATION_UNSET;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not to allow this container to specify an app requested orientation.
|
||||
*
|
||||
* This is different from {@link #providesOrientation()} that
|
||||
* 1. The container may still provide an orientation even if it can't specify the app requested
|
||||
* one, such as {@link #shouldReportOrientationUnspecified()}
|
||||
* 2. Even if the container can specify an app requested orientation, it may not be used by the
|
||||
* parent container if it is {@link ActivityInfo#SCREEN_ORIENTATION_UNSPECIFIED}.
|
||||
*/
|
||||
boolean canSpecifyOrientation() {
|
||||
final int windowingMode = getWindowingMode();
|
||||
final int activityType = getActivityType();
|
||||
return windowingMode == WINDOWING_MODE_FULLSCREEN
|
||||
|| activityType == ACTIVITY_TYPE_HOME
|
||||
|| activityType == ACTIVITY_TYPE_RECENTS
|
||||
|| activityType == ACTIVITY_TYPE_ASSISTANT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not the parent container should use the orientation provided by this container
|
||||
* even if it is {@link ActivityInfo#SCREEN_ORIENTATION_UNSPECIFIED}.
|
||||
*/
|
||||
@Override
|
||||
boolean providesOrientation() {
|
||||
return super.providesOrientation() || shouldReportOrientationUnspecified();
|
||||
}
|
||||
|
||||
private boolean shouldReportOrientationUnspecified() {
|
||||
// Apps and their containers are not allowed to specify orientation from adjacent
|
||||
// TaskFragment.
|
||||
return getAdjacentTaskFragment() != null && isVisibleRequested();
|
||||
}
|
||||
|
||||
@Override
|
||||
void forAllTaskFragments(Consumer<TaskFragment> callback, boolean traverseTopToBottom) {
|
||||
super.forAllTaskFragments(callback, traverseTopToBottom);
|
||||
|
||||
@@ -23,6 +23,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
|
||||
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
|
||||
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
|
||||
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
|
||||
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
|
||||
import static android.os.Process.FIRST_APPLICATION_UID;
|
||||
|
||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.any;
|
||||
@@ -547,4 +548,31 @@ public class TaskFragmentTest extends WindowTestsBase {
|
||||
activity0.moveFocusableActivityToTop("test");
|
||||
assertEquals(activity0, mDisplayContent.mFocusedApp);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsVisibleWithAdjacent_reportOrientationUnspecified() {
|
||||
final Task task = createTask(mDisplayContent);
|
||||
final TaskFragment tf0 = createTaskFragmentWithParentTask(task);
|
||||
final TaskFragment tf1 = createTaskFragmentWithParentTask(task);
|
||||
tf0.setAdjacentTaskFragment(tf1);
|
||||
tf0.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
|
||||
tf1.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
|
||||
task.setBounds(0, 0, 1200, 1000);
|
||||
tf0.setBounds(0, 0, 600, 1000);
|
||||
tf1.setBounds(600, 0, 1200, 1000);
|
||||
final ActivityRecord activity0 = tf0.getTopMostActivity();
|
||||
final ActivityRecord activity1 = tf1.getTopMostActivity();
|
||||
doReturn(true).when(activity0).isVisibleRequested();
|
||||
doReturn(true).when(activity1).isVisibleRequested();
|
||||
|
||||
assertEquals(SCREEN_ORIENTATION_UNSPECIFIED, tf0.getOrientation(SCREEN_ORIENTATION_UNSET));
|
||||
assertEquals(SCREEN_ORIENTATION_UNSPECIFIED, tf1.getOrientation(SCREEN_ORIENTATION_UNSET));
|
||||
assertEquals(SCREEN_ORIENTATION_UNSPECIFIED, task.getOrientation(SCREEN_ORIENTATION_UNSET));
|
||||
|
||||
activity0.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE);
|
||||
|
||||
assertEquals(SCREEN_ORIENTATION_UNSPECIFIED, tf0.getOrientation(SCREEN_ORIENTATION_UNSET));
|
||||
assertEquals(SCREEN_ORIENTATION_UNSPECIFIED, tf1.getOrientation(SCREEN_ORIENTATION_UNSET));
|
||||
assertEquals(SCREEN_ORIENTATION_UNSPECIFIED, task.getOrientation(SCREEN_ORIENTATION_UNSET));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user