Merge "Respect "nosensor" and "locked" with ignoreOrientationRequest being set" into tm-qpr-dev

This commit is contained in:
TreeHugger Robot
2022-12-16 18:05:32 +00:00
committed by Android (Google) Code Review
13 changed files with 306 additions and 136 deletions

View File

@@ -3871,12 +3871,6 @@
"group": "WM_DEBUG_ORIENTATION", "group": "WM_DEBUG_ORIENTATION",
"at": "com\/android\/server\/wm\/TaskDisplayArea.java" "at": "com\/android\/server\/wm\/TaskDisplayArea.java"
}, },
"1648338379": {
"message": "Display id=%d is ignoring all orientation requests, return %d",
"level": "VERBOSE",
"group": "WM_DEBUG_ORIENTATION",
"at": "com\/android\/server\/wm\/DisplayContent.java"
},
"1653025361": { "1653025361": {
"message": "Register task fragment organizer=%s uid=%d pid=%d", "message": "Register task fragment organizer=%s uid=%d pid=%d",
"level": "VERBOSE", "level": "VERBOSE",
@@ -4117,6 +4111,12 @@
"group": "WM_DEBUG_WINDOW_ORGANIZER", "group": "WM_DEBUG_WINDOW_ORGANIZER",
"at": "com\/android\/server\/wm\/DisplayAreaPolicyBuilder.java" "at": "com\/android\/server\/wm\/DisplayAreaPolicyBuilder.java"
}, },
"1877863087": {
"message": "Display id=%d is ignoring orientation request for %d, return %d",
"level": "VERBOSE",
"group": "WM_DEBUG_ORIENTATION",
"at": "com\/android\/server\/wm\/DisplayContent.java"
},
"1878927091": { "1878927091": {
"message": "prepareSurface: No changes in animation for %s", "message": "prepareSurface: No changes in animation for %s",
"level": "VERBOSE", "level": "VERBOSE",

View File

@@ -7756,10 +7756,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
// configuration. This is important to cases where activities with incompatible // configuration. This is important to cases where activities with incompatible
// orientations launch, or user goes back from an activity of bi-orientation to an // orientations launch, or user goes back from an activity of bi-orientation to an
// activity with specified orientation. // activity with specified orientation.
if (getRequestedOrientation() == SCREEN_ORIENTATION_UNSET) {
return;
}
if (onDescendantOrientationChanged(this)) { if (onDescendantOrientationChanged(this)) {
// WM Shell can show additional UI elements, e.g. a restart button for size compat mode // WM Shell can show additional UI elements, e.g. a restart button for size compat mode
// so ensure that WM Shell is called when an activity becomes visible. // so ensure that WM Shell is called when an activity becomes visible.
@@ -8329,7 +8325,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
// If orientation is respected when insets are applied, then stableBounds will be empty. // If orientation is respected when insets are applied, then stableBounds will be empty.
boolean orientationRespectedWithInsets = boolean orientationRespectedWithInsets =
orientationRespectedWithInsets(parentBounds, stableBounds); orientationRespectedWithInsets(parentBounds, stableBounds);
if (handlesOrientationChangeFromDescendant() && orientationRespectedWithInsets) { if (orientationRespectedWithInsets
&& handlesOrientationChangeFromDescendant(mOrientation)) {
// No need to letterbox because of fixed orientation. Display will handle // No need to letterbox because of fixed orientation. Display will handle
// fixed-orientation requests and a display rotation is enough to respect requested // fixed-orientation requests and a display rotation is enough to respect requested
// orientation with insets applied. // orientation with insets applied.

View File

@@ -34,6 +34,8 @@ import static com.android.server.wm.DisplayAreaProto.WINDOW_CONTAINER;
import static com.android.server.wm.WindowContainerChildProto.DISPLAY_AREA; import static com.android.server.wm.WindowContainerChildProto.DISPLAY_AREA;
import android.annotation.Nullable; import android.annotation.Nullable;
import android.content.pm.ActivityInfo;
import android.content.pm.ActivityInfo.ScreenOrientation;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.graphics.Rect; import android.graphics.Rect;
import android.util.proto.ProtoOutputStream; import android.util.proto.ProtoOutputStream;
@@ -141,26 +143,30 @@ public class DisplayArea<T extends WindowContainer> extends WindowContainer<T> {
} }
@Override @Override
@ScreenOrientation
int getOrientation(int candidate) { int getOrientation(int candidate) {
mLastOrientationSource = null; final int orientation = super.getOrientation(candidate);
if (getIgnoreOrientationRequest()) { if (getIgnoreOrientationRequest(orientation)) {
// In all the other case, mLastOrientationSource will be reassigned to a new value
mLastOrientationSource = null;
return SCREEN_ORIENTATION_UNSET; return SCREEN_ORIENTATION_UNSET;
} }
return orientation;
return super.getOrientation(candidate);
} }
@Override @Override
boolean handlesOrientationChangeFromDescendant() { boolean handlesOrientationChangeFromDescendant(@ScreenOrientation int orientation) {
return !getIgnoreOrientationRequest() return !getIgnoreOrientationRequest(orientation)
&& super.handlesOrientationChangeFromDescendant(); && super.handlesOrientationChangeFromDescendant(orientation);
} }
@Override @Override
boolean onDescendantOrientationChanged(WindowContainer requestingContainer) { boolean onDescendantOrientationChanged(@Nullable WindowContainer requestingContainer) {
// If this is set to ignore the orientation request, we don't propagate descendant // If this is set to ignore the orientation request, we don't propagate descendant
// orientation request. // orientation request.
return !getIgnoreOrientationRequest() final int orientation = requestingContainer != null
? requestingContainer.mOrientation : SCREEN_ORIENTATION_UNSET;
return !getIgnoreOrientationRequest(orientation)
&& super.onDescendantOrientationChanged(requestingContainer); && super.onDescendantOrientationChanged(requestingContainer);
} }
@@ -224,6 +230,23 @@ public class DisplayArea<T extends WindowContainer> extends WindowContainer<T> {
} }
} }
/**
* @return {@value true} if we need to ignore the orientation in input.
*/
// TODO(b/262366204): Rename getIgnoreOrientationRequest to shouldIgnoreOrientationRequest
boolean getIgnoreOrientationRequest(@ScreenOrientation int orientation) {
// We always respect orientation request for ActivityInfo.SCREEN_ORIENTATION_LOCKED
// ActivityInfo.SCREEN_ORIENTATION_NOSENSOR.
// Main use case why this is important is Camera apps that rely on those
// properties to ensure that they will be able to determine Camera preview
// orientation correctly
if (orientation == ActivityInfo.SCREEN_ORIENTATION_LOCKED
|| orientation == ActivityInfo.SCREEN_ORIENTATION_NOSENSOR) {
return false;
}
return getIgnoreOrientationRequest();
}
boolean getIgnoreOrientationRequest() { boolean getIgnoreOrientationRequest() {
// Adding an exception for when ignoreOrientationRequest is overridden at runtime for all // Adding an exception for when ignoreOrientationRequest is overridden at runtime for all
// DisplayArea-s. For example, this is needed for the Kids Mode since many Kids apps aren't // DisplayArea-s. For example, this is needed for the Kids Mode since many Kids apps aren't
@@ -640,11 +663,9 @@ public class DisplayArea<T extends WindowContainer> extends WindowContainer<T> {
} }
@Override @Override
@ScreenOrientation
int getOrientation(int candidate) { int getOrientation(int candidate) {
mLastOrientationSource = null; mLastOrientationSource = null;
if (getIgnoreOrientationRequest()) {
return SCREEN_ORIENTATION_UNSET;
}
// Find a window requesting orientation. // Find a window requesting orientation.
final WindowState win = getWindow(mGetOrientingWindow); final WindowState win = getWindow(mGetOrientingWindow);

View File

@@ -1558,13 +1558,15 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
} }
@Override @Override
boolean onDescendantOrientationChanged(WindowContainer requestingContainer) { boolean onDescendantOrientationChanged(@Nullable WindowContainer requestingContainer) {
final Configuration config = updateOrientation( final Configuration config = updateOrientation(
requestingContainer, false /* forceUpdate */); requestingContainer, false /* forceUpdate */);
// If display rotation class tells us that it doesn't consider app requested orientation, // If display rotation class tells us that it doesn't consider app requested orientation,
// this display won't rotate just because of an app changes its requested orientation. Thus // this display won't rotate just because of an app changes its requested orientation. Thus
// it indicates that this display chooses not to handle this request. // it indicates that this display chooses not to handle this request.
final boolean handled = handlesOrientationChangeFromDescendant(); final int orientation = requestingContainer != null ? requestingContainer.mOrientation
: SCREEN_ORIENTATION_UNSET;
final boolean handled = handlesOrientationChangeFromDescendant(orientation);
if (config == null) { if (config == null) {
return handled; return handled;
} }
@@ -1587,8 +1589,8 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
} }
@Override @Override
boolean handlesOrientationChangeFromDescendant() { boolean handlesOrientationChangeFromDescendant(@ScreenOrientation int orientation) {
return !getIgnoreOrientationRequest() return !getIgnoreOrientationRequest(orientation)
&& !getDisplayRotation().isFixedToUserRotation(); && !getDisplayRotation().isFixedToUserRotation();
} }
@@ -1689,7 +1691,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
return ROTATION_UNDEFINED; return ROTATION_UNDEFINED;
} }
if (!WindowManagerService.ENABLE_FIXED_ROTATION_TRANSFORM if (!WindowManagerService.ENABLE_FIXED_ROTATION_TRANSFORM
|| getIgnoreOrientationRequest()) { || getIgnoreOrientationRequest(r.mOrientation)) {
return ROTATION_UNDEFINED; return ROTATION_UNDEFINED;
} }
if (r.mOrientation == ActivityInfo.SCREEN_ORIENTATION_BEHIND) { if (r.mOrientation == ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
@@ -2688,15 +2690,6 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
@ScreenOrientation @ScreenOrientation
@Override @Override
int getOrientation() { int getOrientation() {
mLastOrientationSource = null;
if (!handlesOrientationChangeFromDescendant()) {
// Return SCREEN_ORIENTATION_UNSPECIFIED so that Display respect sensor rotation
ProtoLog.v(WM_DEBUG_ORIENTATION,
"Display id=%d is ignoring all orientation requests, return %d",
mDisplayId, SCREEN_ORIENTATION_UNSPECIFIED);
return SCREEN_ORIENTATION_UNSPECIFIED;
}
if (mWmService.mDisplayFrozen) { if (mWmService.mDisplayFrozen) {
if (mWmService.mPolicy.isKeyguardLocked()) { if (mWmService.mPolicy.isKeyguardLocked()) {
// Use the last orientation the while the display is frozen with the keyguard // Use the last orientation the while the display is frozen with the keyguard
@@ -2712,6 +2705,16 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
} }
final int orientation = super.getOrientation(); final int orientation = super.getOrientation();
if (!handlesOrientationChangeFromDescendant(orientation)) {
mLastOrientationSource = null;
// Return SCREEN_ORIENTATION_UNSPECIFIED so that Display respect sensor rotation
ProtoLog.v(WM_DEBUG_ORIENTATION,
"Display id=%d is ignoring orientation request for %d, return %d",
mDisplayId, orientation, SCREEN_ORIENTATION_UNSPECIFIED);
return SCREEN_ORIENTATION_UNSPECIFIED;
}
if (orientation == SCREEN_ORIENTATION_UNSET) { if (orientation == SCREEN_ORIENTATION_UNSET) {
// Return SCREEN_ORIENTATION_UNSPECIFIED so that Display respect sensor rotation // Return SCREEN_ORIENTATION_UNSPECIFIED so that Display respect sensor rotation
ProtoLog.v(WM_DEBUG_ORIENTATION, ProtoLog.v(WM_DEBUG_ORIENTATION,
@@ -3832,18 +3835,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
/** Called when the focused {@link TaskDisplayArea} on this display may have changed. */ /** Called when the focused {@link TaskDisplayArea} on this display may have changed. */
void onLastFocusedTaskDisplayAreaChanged(@Nullable TaskDisplayArea taskDisplayArea) { void onLastFocusedTaskDisplayAreaChanged(@Nullable TaskDisplayArea taskDisplayArea) {
// Only record the TaskDisplayArea that handles orientation request. mOrientationRequestingTaskDisplayArea = taskDisplayArea;
if (taskDisplayArea != null && taskDisplayArea.handlesOrientationChangeFromDescendant()) {
mOrientationRequestingTaskDisplayArea = taskDisplayArea;
return;
}
// If the previous TDA no longer handles orientation request, clear it.
if (mOrientationRequestingTaskDisplayArea != null
&& !mOrientationRequestingTaskDisplayArea
.handlesOrientationChangeFromDescendant()) {
mOrientationRequestingTaskDisplayArea = null;
}
} }
/** /**
@@ -5053,13 +5045,10 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
} }
@Override @Override
int getOrientation(int candidate) { @ScreenOrientation
if (getIgnoreOrientationRequest()) { int getOrientation(@ScreenOrientation int candidate) {
return SCREEN_ORIENTATION_UNSET;
}
// IME does not participate in orientation. // IME does not participate in orientation.
return candidate; return getIgnoreOrientationRequest(candidate) ? SCREEN_ORIENTATION_UNSET : candidate;
} }
@Override @Override

View File

@@ -143,6 +143,7 @@ import android.app.WindowConfiguration;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.Intent; import android.content.Intent;
import android.content.pm.ActivityInfo; import android.content.pm.ActivityInfo;
import android.content.pm.ActivityInfo.ScreenOrientation;
import android.content.pm.ApplicationInfo; import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager; import android.content.pm.IPackageManager;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
@@ -2686,8 +2687,8 @@ class Task extends TaskFragment {
} }
@Override @Override
boolean handlesOrientationChangeFromDescendant() { boolean handlesOrientationChangeFromDescendant(@ScreenOrientation int orientation) {
if (!super.handlesOrientationChangeFromDescendant()) { if (!super.handlesOrientationChangeFromDescendant(orientation)) {
return false; return false;
} }
@@ -2702,7 +2703,7 @@ class Task extends TaskFragment {
// Check for leaf Task. // Check for leaf Task.
// Display won't rotate for the orientation request if the Task/TaskDisplayArea // Display won't rotate for the orientation request if the Task/TaskDisplayArea
// can't specify orientation. // can't specify orientation.
return canSpecifyOrientation() && getDisplayArea().canSpecifyOrientation(); return canSpecifyOrientation() && getDisplayArea().canSpecifyOrientation(orientation);
} }
void resize(boolean relayout, boolean forced) { void resize(boolean relayout, boolean forced) {

View File

@@ -41,6 +41,7 @@ import android.annotation.Nullable;
import android.app.ActivityOptions; import android.app.ActivityOptions;
import android.app.WindowConfiguration; import android.app.WindowConfiguration;
import android.content.pm.ActivityInfo; import android.content.pm.ActivityInfo;
import android.content.pm.ActivityInfo.ScreenOrientation;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.graphics.Color; import android.graphics.Color;
import android.os.UserHandle; import android.os.UserHandle;
@@ -633,22 +634,20 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> {
} }
@Override @Override
int getOrientation(int candidate) { @ScreenOrientation
mLastOrientationSource = null; int getOrientation(@ScreenOrientation int candidate) {
if (getIgnoreOrientationRequest()) { final int orientation = super.getOrientation(candidate);
return SCREEN_ORIENTATION_UNSET; if (!canSpecifyOrientation(orientation)) {
} mLastOrientationSource = null;
if (!canSpecifyOrientation()) {
// We only respect orientation of the focused TDA, which can be a child of this TDA. // We only respect orientation of the focused TDA, which can be a child of this TDA.
return reduceOnAllTaskDisplayAreas((taskDisplayArea, orientation) -> { return reduceOnAllTaskDisplayAreas((taskDisplayArea, taskOrientation) -> {
if (taskDisplayArea == this || orientation != SCREEN_ORIENTATION_UNSET) { if (taskDisplayArea == this || taskOrientation != SCREEN_ORIENTATION_UNSET) {
return orientation; return taskOrientation;
} }
return taskDisplayArea.getOrientation(candidate); return taskDisplayArea.getOrientation(candidate);
}, SCREEN_ORIENTATION_UNSET); }, SCREEN_ORIENTATION_UNSET);
} }
final int orientation = super.getOrientation(candidate);
if (orientation != SCREEN_ORIENTATION_UNSET if (orientation != SCREEN_ORIENTATION_UNSET
&& orientation != SCREEN_ORIENTATION_BEHIND) { && orientation != SCREEN_ORIENTATION_BEHIND) {
ProtoLog.v(WM_DEBUG_ORIENTATION, ProtoLog.v(WM_DEBUG_ORIENTATION,
@@ -1870,12 +1869,11 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> {
} }
/** Whether this task display area can request orientation. */ /** Whether this task display area can request orientation. */
boolean canSpecifyOrientation() { boolean canSpecifyOrientation(@ScreenOrientation int orientation) {
// Only allow to specify orientation if this TDA is not set to ignore orientation request, // Only allow to specify orientation if this TDA is the last focused one on this logical
// and it is the last focused one on this logical display that can request orientation // display that can request orientation request.
// request. return mDisplayContent.getOrientationRequestingTaskDisplayArea() == this
return !getIgnoreOrientationRequest() && !getIgnoreOrientationRequest(orientation);
&& mDisplayContent.getOrientationRequestingTaskDisplayArea() == this;
} }
void clearPreferredTopFocusableRootTask() { void clearPreferredTopFocusableRootTask() {

View File

@@ -1420,9 +1420,9 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
* @return {@code true} if it handles or will handle orientation change in the future; {@code * @return {@code true} if it handles or will handle orientation change in the future; {@code
* false} if it won't handle the change at anytime. * false} if it won't handle the change at anytime.
*/ */
boolean handlesOrientationChangeFromDescendant() { boolean handlesOrientationChangeFromDescendant(int orientation) {
final WindowContainer parent = getParent(); final WindowContainer parent = getParent();
return parent != null && parent.handlesOrientationChangeFromDescendant(); return parent != null && parent.handlesOrientationChangeFromDescendant(orientation);
} }
/** /**
@@ -1514,7 +1514,8 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
// portrait but the task is still in landscape. While updating from display, // portrait but the task is still in landscape. While updating from display,
// the task can be updated to portrait first so the configuration can be // the task can be updated to portrait first so the configuration can be
// computed in a consistent environment. // computed in a consistent environment.
&& (inMultiWindowMode() || !handlesOrientationChangeFromDescendant())) { && (inMultiWindowMode()
|| !handlesOrientationChangeFromDescendant(orientation))) {
// Resolve the requested orientation. // Resolve the requested orientation.
onConfigurationChanged(parent.getConfiguration()); onConfigurationChanged(parent.getConfiguration());
} }

View File

@@ -517,7 +517,7 @@ public class ActivityRecordTests extends WindowTestsBase {
// Mimic the behavior that display doesn't handle app's requested orientation. // Mimic the behavior that display doesn't handle app's requested orientation.
final DisplayContent dc = activity.getTask().getDisplayContent(); final DisplayContent dc = activity.getTask().getDisplayContent();
doReturn(false).when(dc).onDescendantOrientationChanged(any()); doReturn(false).when(dc).onDescendantOrientationChanged(any());
doReturn(false).when(dc).handlesOrientationChangeFromDescendant(); doReturn(false).when(dc).handlesOrientationChangeFromDescendant(anyInt());
final int requestedOrientation; final int requestedOrientation;
switch (newConfig.orientation) { switch (newConfig.orientation) {

View File

@@ -18,6 +18,8 @@ package com.android.server.wm;
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LOCKED;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
@@ -470,28 +472,6 @@ public class DisplayAreaTest extends WindowTestsBase {
area.getOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR)); area.getOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR));
} }
@Test
public void testSetIgnoreOrientationRequest() {
final DisplayArea.Tokens area = new DisplayArea.Tokens(mWm, ABOVE_TASKS, "test");
final WindowToken token = createWindowToken(TYPE_APPLICATION_OVERLAY);
spyOn(token);
doReturn(mock(DisplayContent.class)).when(token).getDisplayContent();
doNothing().when(token).setParent(any());
final WindowState win = createWindowState(token);
spyOn(win);
doNothing().when(win).setParent(any());
win.mAttrs.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
token.addChild(win, 0);
area.addChild(token);
doReturn(true).when(win).isVisible();
assertEquals(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE, area.getOrientation());
area.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
assertEquals(ActivityInfo.SCREEN_ORIENTATION_UNSET, area.getOrientation());
}
@Test @Test
public void testSetIgnoreOrientationRequest_notCallSuperOnDescendantOrientationChanged() { public void testSetIgnoreOrientationRequest_notCallSuperOnDescendantOrientationChanged() {
final TaskDisplayArea tda = mDisplayContent.getDefaultTaskDisplayArea(); final TaskDisplayArea tda = mDisplayContent.getDefaultTaskDisplayArea();
@@ -514,7 +494,49 @@ public class DisplayAreaTest extends WindowTestsBase {
} }
@Test @Test
public void testSetIgnoreOrientationRequest_updateOrientationRequestingTaskDisplayArea() { public void testSetIgnoreOrientationRequest_callSuperOnDescendantOrientationChangedNoSensor() {
final TaskDisplayArea tda = mDisplayContent.getDefaultTaskDisplayArea();
final Task stack =
new TaskBuilder(mSupervisor).setOnTop(!ON_TOP).setCreateActivity(true).build();
final ActivityRecord activity = stack.getTopNonFinishingActivity();
tda.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
activity.setRequestedOrientation(SCREEN_ORIENTATION_NOSENSOR);
verify(tda).onDescendantOrientationChanged(any());
verify(mDisplayContent).onDescendantOrientationChanged(any());
tda.setIgnoreOrientationRequest(false /* ignoreOrientationRequest */);
activity.setRequestedOrientation(SCREEN_ORIENTATION_NOSENSOR);
verify(tda).onDescendantOrientationChanged(any());
verify(mDisplayContent).onDescendantOrientationChanged(any());
}
@Test
public void testSetIgnoreOrientationRequest_callSuperOnDescendantOrientationChangedLocked() {
final TaskDisplayArea tda = mDisplayContent.getDefaultTaskDisplayArea();
final Task stack =
new TaskBuilder(mSupervisor).setOnTop(!ON_TOP).setCreateActivity(true).build();
final ActivityRecord activity = stack.getTopNonFinishingActivity();
tda.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
activity.setRequestedOrientation(SCREEN_ORIENTATION_LOCKED);
verify(tda).onDescendantOrientationChanged(any());
verify(mDisplayContent).onDescendantOrientationChanged(any());
tda.setIgnoreOrientationRequest(false /* ignoreOrientationRequest */);
activity.setRequestedOrientation(SCREEN_ORIENTATION_LOCKED);
verify(tda).onDescendantOrientationChanged(any());
verify(mDisplayContent).onDescendantOrientationChanged(any());
}
@Test
public void testGetOrientationRequestingTaskDisplayArea_updateOrientationTaskDisplayArea() {
final TaskDisplayArea tda = mDisplayContent.getDefaultTaskDisplayArea(); final TaskDisplayArea tda = mDisplayContent.getDefaultTaskDisplayArea();
final Task stack = final Task stack =
new TaskBuilder(mSupervisor).setOnTop(!ON_TOP).setCreateActivity(true).build(); new TaskBuilder(mSupervisor).setOnTop(!ON_TOP).setCreateActivity(true).build();
@@ -526,7 +548,7 @@ public class DisplayAreaTest extends WindowTestsBase {
// TDA is no longer handling orientation request, clear the last focused TDA. // TDA is no longer handling orientation request, clear the last focused TDA.
tda.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */); tda.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
assertThat(mDisplayContent.getOrientationRequestingTaskDisplayArea()).isNull(); assertThat(mDisplayContent.getOrientationRequestingTaskDisplayArea()).isEqualTo(tda);
// TDA now handles orientation request, update last focused TDA based on the focused app. // TDA now handles orientation request, update last focused TDA based on the focused app.
tda.setIgnoreOrientationRequest(false /* ignoreOrientationRequest */); tda.setIgnoreOrientationRequest(false /* ignoreOrientationRequest */);

View File

@@ -17,6 +17,8 @@
package com.android.server.wm; package com.android.server.wm;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LOCKED;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
@@ -162,6 +164,30 @@ public class DualDisplayAreaGroupPolicyTest extends WindowTestsBase {
verify(mDisplay, never()).onDescendantOrientationChanged(any()); verify(mDisplay, never()).onDescendantOrientationChanged(any());
} }
@Test
public void testIgnoreOrientationRequest_displayReceiveOrientationChangeForNoSensor() {
mFirstRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
mSecondRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
mDisplay.onLastFocusedTaskDisplayAreaChanged(mFirstTda);
prepareUnresizable(mFirstActivity, SCREEN_ORIENTATION_NOSENSOR);
verify(mFirstRoot).onDescendantOrientationChanged(any());
verify(mDisplay).onDescendantOrientationChanged(any());
}
@Test
public void testIgnoreOrientationRequest_displayReceiveOrientationChangeForLocked() {
mFirstRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
mSecondRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
mDisplay.onLastFocusedTaskDisplayAreaChanged(mFirstTda);
prepareUnresizable(mFirstActivity, SCREEN_ORIENTATION_LOCKED);
verify(mFirstRoot).onDescendantOrientationChanged(any());
verify(mDisplay).onDescendantOrientationChanged(any());
}
@Test @Test
public void testLaunchPortraitApp_fillsDisplayAreaGroup() { public void testLaunchPortraitApp_fillsDisplayAreaGroup() {
mFirstRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */); mFirstRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
@@ -214,6 +240,21 @@ public class DualDisplayAreaGroupPolicyTest extends WindowTestsBase {
newTaskBounds.height() * newTaskBounds.height() / newTaskBounds.width()); newTaskBounds.height() * newTaskBounds.height() / newTaskBounds.width());
} }
@Test
public void testLaunchNoSensorApp_noSizeCompatAfterRotation() {
mFirstRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
mSecondRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
mDisplay.onLastFocusedTaskDisplayAreaChanged(mFirstTda);
prepareUnresizable(mFirstActivity, SCREEN_ORIENTATION_NOSENSOR);
assertThat(mFirstActivity.isLetterboxedForFixedOrientationAndAspectRatio()).isFalse();
assertThat(mFirstActivity.inSizeCompatMode()).isFalse();
rotateDisplay(mDisplay, ROTATION_90);
assertThat(mFirstActivity.isLetterboxedForFixedOrientationAndAspectRatio()).isFalse();
assertThat(mFirstActivity.inSizeCompatMode()).isFalse();
}
@Test @Test
public void testLaunchLandscapeApp_activityIsLetterboxForFixedOrientationInDisplayAreaGroup() { public void testLaunchLandscapeApp_activityIsLetterboxForFixedOrientationInDisplayAreaGroup() {
mFirstRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */); mFirstRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
@@ -235,6 +276,26 @@ public class DualDisplayAreaGroupPolicyTest extends WindowTestsBase {
.isEqualTo(dagBounds.width() * dagBounds.width() / dagBounds.height()); .isEqualTo(dagBounds.width() * dagBounds.width() / dagBounds.height());
} }
@Test
public void testLaunchNoSensorApp_activityIsNotLetterboxForFixedOrientationDisplayAreaGroup() {
mFirstRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
mSecondRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
mDisplay.onLastFocusedTaskDisplayAreaChanged(mFirstTda);
prepareUnresizable(mFirstActivity, SCREEN_ORIENTATION_NOSENSOR);
assertThat(mFirstActivity.isLetterboxedForFixedOrientationAndAspectRatio()).isFalse();
}
@Test
public void testLaunchLockedApp_activityIsNotLetterboxForFixedOrientationInDisplayAreaGroup() {
mFirstRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
mSecondRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
mDisplay.onLastFocusedTaskDisplayAreaChanged(mFirstTda);
prepareUnresizable(mFirstActivity, SCREEN_ORIENTATION_LOCKED);
assertThat(mFirstActivity.isLetterboxedForFixedOrientationAndAspectRatio()).isFalse();
}
@Test @Test
public void testLaunchLandscapeApp_fixedOrientationLetterboxBecomesSizeCompatAfterRotation() { public void testLaunchLandscapeApp_fixedOrientationLetterboxBecomesSizeCompatAfterRotation() {
mFirstRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */); mFirstRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
@@ -264,6 +325,20 @@ public class DualDisplayAreaGroupPolicyTest extends WindowTestsBase {
assertThat(newActivityBounds.height()).isEqualTo(activityBounds.height()); assertThat(newActivityBounds.height()).isEqualTo(activityBounds.height());
} }
@Test
public void testLaunchNoSensorApp_fixedOrientationLetterboxBecomesSizeCompatAfterRotation() {
mFirstRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
mSecondRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
mDisplay.onLastFocusedTaskDisplayAreaChanged(mFirstTda);
prepareUnresizable(mFirstActivity, SCREEN_ORIENTATION_NOSENSOR);
rotateDisplay(mDisplay, ROTATION_90);
assertThat(mFirstActivity.isLetterboxedForFixedOrientationAndAspectRatio()).isFalse();
assertThat(mFirstActivity.inSizeCompatMode()).isFalse();
}
@Test @Test
public void testPlaceImeContainer_reparentToTargetDisplayAreaGroup() { public void testPlaceImeContainer_reparentToTargetDisplayAreaGroup() {
setupImeWindow(); setupImeWindow();

View File

@@ -29,8 +29,9 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.content.Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT; import static android.content.Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT;
import static android.content.pm.ActivityInfo.FLAG_ALWAYS_FOCUSABLE; import static android.content.pm.ActivityInfo.FLAG_ALWAYS_FOCUSABLE;
import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE; import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LOCKED;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
import static android.window.DisplayAreaOrganizer.FEATURE_VENDOR_FIRST; import static android.window.DisplayAreaOrganizer.FEATURE_VENDOR_FIRST;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
@@ -422,24 +423,26 @@ public class TaskDisplayAreaTests extends WindowTestsBase {
// Activity on TDA1 is focused // Activity on TDA1 is focused
mDisplayContent.setFocusedApp(firstActivity); mDisplayContent.setFocusedApp(firstActivity);
assertThat(firstTaskDisplayArea.canSpecifyOrientation()).isTrue(); final int testOrientation = SCREEN_ORIENTATION_PORTRAIT;
assertThat(secondTaskDisplayArea.canSpecifyOrientation()).isFalse();
assertThat(firstTaskDisplayArea.canSpecifyOrientation(testOrientation)).isTrue();
assertThat(secondTaskDisplayArea.canSpecifyOrientation(testOrientation)).isFalse();
// No focused app, TDA1 is still recorded as last focused. // No focused app, TDA1 is still recorded as last focused.
mDisplayContent.setFocusedApp(null); mDisplayContent.setFocusedApp(null);
assertThat(firstTaskDisplayArea.canSpecifyOrientation()).isTrue(); assertThat(firstTaskDisplayArea.canSpecifyOrientation(testOrientation)).isTrue();
assertThat(secondTaskDisplayArea.canSpecifyOrientation()).isFalse(); assertThat(secondTaskDisplayArea.canSpecifyOrientation(testOrientation)).isFalse();
// Activity on TDA2 is focused // Activity on TDA2 is focused
mDisplayContent.setFocusedApp(secondActivity); mDisplayContent.setFocusedApp(secondActivity);
assertThat(firstTaskDisplayArea.canSpecifyOrientation()).isFalse(); assertThat(firstTaskDisplayArea.canSpecifyOrientation(testOrientation)).isFalse();
assertThat(secondTaskDisplayArea.canSpecifyOrientation()).isTrue(); assertThat(secondTaskDisplayArea.canSpecifyOrientation(testOrientation)).isTrue();
} }
@Test @Test
public void testIsLastFocused_onlyCountIfTaskDisplayAreaHandlesOrientationRequest() { public void testCanSpecifyOrientation() {
final TaskDisplayArea firstTaskDisplayArea = mDisplayContent.getDefaultTaskDisplayArea(); final TaskDisplayArea firstTaskDisplayArea = mDisplayContent.getDefaultTaskDisplayArea();
final TaskDisplayArea secondTaskDisplayArea = createTaskDisplayArea( final TaskDisplayArea secondTaskDisplayArea = createTaskDisplayArea(
mDisplayContent, mRootWindowContainer.mWmService, "TestTaskDisplayArea", mDisplayContent, mRootWindowContainer.mWmService, "TestTaskDisplayArea",
@@ -455,34 +458,88 @@ public class TaskDisplayAreaTests extends WindowTestsBase {
firstTaskDisplayArea.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */); firstTaskDisplayArea.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
secondTaskDisplayArea.setIgnoreOrientationRequest(false /* ignoreOrientationRequest */); secondTaskDisplayArea.setIgnoreOrientationRequest(false /* ignoreOrientationRequest */);
// Activity on TDA1 is focused, but TDA1 doesn't respect orientation request final int testOrientation = SCREEN_ORIENTATION_PORTRAIT;
// Activity on TDA1 is focused, but TDA1 cannot specify orientation because
// ignoreOrientationRequest is true
// Activity on TDA2 has ignoreOrientationRequest false but it doesn't have focus so it
// cannot specify orientation
mDisplayContent.setFocusedApp(firstActivity); mDisplayContent.setFocusedApp(firstActivity);
assertThat(firstTaskDisplayArea.canSpecifyOrientation()).isFalse(); assertThat(firstTaskDisplayArea.canSpecifyOrientation(testOrientation)).isFalse();
assertThat(secondTaskDisplayArea.canSpecifyOrientation()).isFalse(); assertThat(secondTaskDisplayArea.canSpecifyOrientation(testOrientation)).isFalse();
// Activity on TDA2 is focused, and TDA2 respects orientation request // Activity on TDA1 is not focused, and so it cannot specify orientation
// Activity on TDA2 is focused, and it can specify orientation because
// ignoreOrientationRequest is false
mDisplayContent.setFocusedApp(secondActivity); mDisplayContent.setFocusedApp(secondActivity);
assertThat(firstTaskDisplayArea.canSpecifyOrientation()).isFalse(); assertThat(firstTaskDisplayArea.canSpecifyOrientation(testOrientation)).isFalse();
assertThat(secondTaskDisplayArea.canSpecifyOrientation()).isTrue(); assertThat(secondTaskDisplayArea.canSpecifyOrientation(testOrientation)).isTrue();
} }
@Test @Test
public void testIgnoreOrientationRequest() { public void testCanSpecifyOrientationNoSensor() {
final TaskDisplayArea taskDisplayArea = mDisplayContent.getDefaultTaskDisplayArea(); final TaskDisplayArea firstTaskDisplayArea = mDisplayContent.getDefaultTaskDisplayArea();
final Task task = taskDisplayArea.createRootTask( final TaskDisplayArea secondTaskDisplayArea = createTaskDisplayArea(
mDisplayContent, mRootWindowContainer.mWmService, "TestTaskDisplayArea",
FEATURE_VENDOR_FIRST);
final Task firstRootTask = firstTaskDisplayArea.createRootTask(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */); WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
final ActivityRecord activity = new ActivityBuilder(mAtm).setTask(task).build(); final Task secondRootTask = secondTaskDisplayArea.createRootTask(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
final ActivityRecord firstActivity = new ActivityBuilder(mAtm)
.setTask(firstRootTask).build();
final ActivityRecord secondActivity = new ActivityBuilder(mAtm)
.setTask(secondRootTask).build();
firstTaskDisplayArea.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
secondTaskDisplayArea.setIgnoreOrientationRequest(false /* ignoreOrientationRequest */);
mDisplayContent.setFocusedApp(activity); final int testOrientation = SCREEN_ORIENTATION_NOSENSOR;
activity.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE);
assertThat(taskDisplayArea.getOrientation()).isEqualTo(SCREEN_ORIENTATION_LANDSCAPE); // ignoreOrientationRequest is always false for SCREEN_ORIENTATION_NOSENSOR so
// only the TDAs with focus can specify orientations
mDisplayContent.setFocusedApp(firstActivity);
taskDisplayArea.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */); assertThat(firstTaskDisplayArea.canSpecifyOrientation(testOrientation)).isTrue();
assertThat(secondTaskDisplayArea.canSpecifyOrientation(testOrientation)).isFalse();
assertThat(taskDisplayArea.getOrientation()).isEqualTo(SCREEN_ORIENTATION_UNSET); mDisplayContent.setFocusedApp(secondActivity);
assertThat(firstTaskDisplayArea.canSpecifyOrientation(testOrientation)).isFalse();
assertThat(secondTaskDisplayArea.canSpecifyOrientation(testOrientation)).isTrue();
}
@Test
public void testCanSpecifyOrientationLocked() {
final TaskDisplayArea firstTaskDisplayArea = mDisplayContent.getDefaultTaskDisplayArea();
final TaskDisplayArea secondTaskDisplayArea = createTaskDisplayArea(
mDisplayContent, mRootWindowContainer.mWmService, "TestTaskDisplayArea",
FEATURE_VENDOR_FIRST);
final Task firstRootTask = firstTaskDisplayArea.createRootTask(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
final Task secondRootTask = secondTaskDisplayArea.createRootTask(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
final ActivityRecord firstActivity = new ActivityBuilder(mAtm)
.setTask(firstRootTask).build();
final ActivityRecord secondActivity = new ActivityBuilder(mAtm)
.setTask(secondRootTask).build();
firstTaskDisplayArea.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
secondTaskDisplayArea.setIgnoreOrientationRequest(false /* ignoreOrientationRequest */);
final int testOrientation = SCREEN_ORIENTATION_LOCKED;
// ignoreOrientationRequest is always false for SCREEN_ORIENTATION_NOSENSOR so
// only the TDAs with focus can specify orientations
mDisplayContent.setFocusedApp(firstActivity);
assertThat(firstTaskDisplayArea.canSpecifyOrientation(testOrientation)).isTrue();
assertThat(secondTaskDisplayArea.canSpecifyOrientation(testOrientation)).isFalse();
mDisplayContent.setFocusedApp(secondActivity);
assertThat(firstTaskDisplayArea.canSpecifyOrientation(testOrientation)).isFalse();
assertThat(secondTaskDisplayArea.canSpecifyOrientation(testOrientation)).isTrue();
} }
@Test @Test

View File

@@ -57,6 +57,7 @@ import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.same; import static org.mockito.ArgumentMatchers.same;
@@ -392,12 +393,16 @@ public class TaskTests extends WindowTestsBase {
leafTask1.getWindowConfiguration().setActivityType(ACTIVITY_TYPE_HOME); leafTask1.getWindowConfiguration().setActivityType(ACTIVITY_TYPE_HOME);
leafTask2.getWindowConfiguration().setActivityType(ACTIVITY_TYPE_STANDARD); leafTask2.getWindowConfiguration().setActivityType(ACTIVITY_TYPE_STANDARD);
// We need to use an orientation that is not an exception for the
// ignoreOrientationRequest flag.
final int orientation = SCREEN_ORIENTATION_PORTRAIT;
assertEquals(leafTask2, rootTask.getTopChild()); assertEquals(leafTask2, rootTask.getTopChild());
assertTrue(rootTask.handlesOrientationChangeFromDescendant()); assertTrue(rootTask.handlesOrientationChangeFromDescendant(orientation));
// Treat orientation request from home as handled. // Treat orientation request from home as handled.
assertTrue(leafTask1.handlesOrientationChangeFromDescendant()); assertTrue(leafTask1.handlesOrientationChangeFromDescendant(orientation));
// Orientation request from standard activity in multi window will not be handled. // Orientation request from standard activity in multi window will not be handled.
assertFalse(leafTask2.handlesOrientationChangeFromDescendant()); assertFalse(leafTask2.handlesOrientationChangeFromDescendant(orientation));
} }
@Test @Test
@@ -636,7 +641,8 @@ public class TaskTests extends WindowTestsBase {
doReturn(parentWindowContainer).when(task).getParent(); doReturn(parentWindowContainer).when(task).getParent();
doReturn(display.getDefaultTaskDisplayArea()).when(task).getDisplayArea(); doReturn(display.getDefaultTaskDisplayArea()).when(task).getDisplayArea();
doReturn(rootTask).when(task).getRootTask(); doReturn(rootTask).when(task).getRootTask();
doReturn(true).when(parentWindowContainer).handlesOrientationChangeFromDescendant(); doReturn(true).when(parentWindowContainer)
.handlesOrientationChangeFromDescendant(anyInt());
// Setting app to fixed portrait fits within parent, but Task shouldn't adjust the // Setting app to fixed portrait fits within parent, but Task shouldn't adjust the
// bounds because its parent says it will handle it at a later time. // bounds because its parent says it will handle it at a later time.

View File

@@ -662,13 +662,13 @@ public class WindowContainerTests extends WindowTestsBase {
public void testSetOrientation() { public void testSetOrientation() {
final TestWindowContainer root = spy(new TestWindowContainerBuilder(mWm).build()); final TestWindowContainer root = spy(new TestWindowContainerBuilder(mWm).build());
final TestWindowContainer child = spy(root.addChildWindow()); final TestWindowContainer child = spy(root.addChildWindow());
doReturn(true).when(root).handlesOrientationChangeFromDescendant(); doReturn(true).when(root).handlesOrientationChangeFromDescendant(anyInt());
child.getWindowConfiguration().setWindowingMode(WINDOWING_MODE_FULLSCREEN); child.getWindowConfiguration().setWindowingMode(WINDOWING_MODE_FULLSCREEN);
child.setOrientation(SCREEN_ORIENTATION_PORTRAIT); child.setOrientation(SCREEN_ORIENTATION_PORTRAIT);
// The ancestor should decide whether to dispatch the configuration change. // The ancestor should decide whether to dispatch the configuration change.
verify(child, never()).onConfigurationChanged(any()); verify(child, never()).onConfigurationChanged(any());
doReturn(false).when(root).handlesOrientationChangeFromDescendant(); doReturn(false).when(root).handlesOrientationChangeFromDescendant(anyInt());
child.setOrientation(SCREEN_ORIENTATION_LANDSCAPE); child.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
// The ancestor doesn't handle the request so the descendant applies the change directly. // The ancestor doesn't handle the request so the descendant applies the change directly.
verify(child).onConfigurationChanged(any()); verify(child).onConfigurationChanged(any());
@@ -843,11 +843,14 @@ public class WindowContainerTests extends WindowTestsBase {
final TestWindowContainerBuilder builder = new TestWindowContainerBuilder(mWm); final TestWindowContainerBuilder builder = new TestWindowContainerBuilder(mWm);
final TestWindowContainer root = spy(builder.build()); final TestWindowContainer root = spy(builder.build());
final TestWindowContainer child = root.addChildWindow(); // We use an orientation that is not an exception for the ignoreOrientationRequest flag
assertFalse(child.handlesOrientationChangeFromDescendant()); final int orientation = SCREEN_ORIENTATION_PORTRAIT;
Mockito.doReturn(true).when(root).handlesOrientationChangeFromDescendant(); final TestWindowContainer child = root.addChildWindow();
assertTrue(child.handlesOrientationChangeFromDescendant()); assertFalse(child.handlesOrientationChangeFromDescendant(orientation));
Mockito.doReturn(true).when(root).handlesOrientationChangeFromDescendant(anyInt());
assertTrue(child.handlesOrientationChangeFromDescendant(orientation));
} }
@Test @Test