Fix NPE when using hinge split type without FoldingFeature
Before this CL, we only compute SplitType in getRelBounds.
However, we actually obtain the bounds to check minimum
dimensions in #computeSplitAttributes.
This CL moves the splitType calculation to
#getPrimaryBounds and #getSecondaryBounds to cover the
minimum dimensions to fix NPE.
Test: atest ActivityEmbeddingBoundsTests
on device without foldingFeature
Test: atest SplitPresenterTest
Bug: 263565586
Change-Id: Ibb826c25f072cdffd5b5adcd19571fe446d64f51
This commit is contained in:
@@ -710,24 +710,16 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
|
|||||||
@NonNull SplitAttributes splitAttributes) {
|
@NonNull SplitAttributes splitAttributes) {
|
||||||
final Configuration taskConfiguration = taskProperties.getConfiguration();
|
final Configuration taskConfiguration = taskProperties.getConfiguration();
|
||||||
final FoldingFeature foldingFeature = getFoldingFeature(taskProperties);
|
final FoldingFeature foldingFeature = getFoldingFeature(taskProperties);
|
||||||
final SplitType splitType = computeSplitType(splitAttributes, taskConfiguration,
|
if (!shouldShowSplit(splitAttributes)) {
|
||||||
foldingFeature);
|
|
||||||
final SplitAttributes computedSplitAttributes = new SplitAttributes.Builder()
|
|
||||||
.setSplitType(splitType)
|
|
||||||
.setLayoutDirection(splitAttributes.getLayoutDirection())
|
|
||||||
.build();
|
|
||||||
if (!shouldShowSplit(computedSplitAttributes)) {
|
|
||||||
return new Rect();
|
return new Rect();
|
||||||
}
|
}
|
||||||
final Rect bounds;
|
final Rect bounds;
|
||||||
switch (position) {
|
switch (position) {
|
||||||
case POSITION_START:
|
case POSITION_START:
|
||||||
bounds = getPrimaryBounds(taskConfiguration, computedSplitAttributes,
|
bounds = getPrimaryBounds(taskConfiguration, splitAttributes, foldingFeature);
|
||||||
foldingFeature);
|
|
||||||
break;
|
break;
|
||||||
case POSITION_END:
|
case POSITION_END:
|
||||||
bounds = getSecondaryBounds(taskConfiguration, computedSplitAttributes,
|
bounds = getSecondaryBounds(taskConfiguration, splitAttributes, foldingFeature);
|
||||||
foldingFeature);
|
|
||||||
break;
|
break;
|
||||||
case POSITION_FILL:
|
case POSITION_FILL:
|
||||||
default:
|
default:
|
||||||
@@ -742,29 +734,76 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
|
|||||||
@NonNull
|
@NonNull
|
||||||
private Rect getPrimaryBounds(@NonNull Configuration taskConfiguration,
|
private Rect getPrimaryBounds(@NonNull Configuration taskConfiguration,
|
||||||
@NonNull SplitAttributes splitAttributes, @Nullable FoldingFeature foldingFeature) {
|
@NonNull SplitAttributes splitAttributes, @Nullable FoldingFeature foldingFeature) {
|
||||||
if (!shouldShowSplit(splitAttributes)) {
|
final SplitAttributes computedSplitAttributes = updateSplitAttributesType(splitAttributes,
|
||||||
|
computeSplitType(splitAttributes, taskConfiguration, foldingFeature));
|
||||||
|
if (!shouldShowSplit(computedSplitAttributes)) {
|
||||||
return new Rect();
|
return new Rect();
|
||||||
}
|
}
|
||||||
switch (splitAttributes.getLayoutDirection()) {
|
switch (computedSplitAttributes.getLayoutDirection()) {
|
||||||
case SplitAttributes.LayoutDirection.LEFT_TO_RIGHT: {
|
case SplitAttributes.LayoutDirection.LEFT_TO_RIGHT: {
|
||||||
return getLeftContainerBounds(taskConfiguration, splitAttributes, foldingFeature);
|
return getLeftContainerBounds(taskConfiguration, computedSplitAttributes,
|
||||||
|
foldingFeature);
|
||||||
}
|
}
|
||||||
case SplitAttributes.LayoutDirection.RIGHT_TO_LEFT: {
|
case SplitAttributes.LayoutDirection.RIGHT_TO_LEFT: {
|
||||||
return getRightContainerBounds(taskConfiguration, splitAttributes, foldingFeature);
|
return getRightContainerBounds(taskConfiguration, computedSplitAttributes,
|
||||||
|
foldingFeature);
|
||||||
}
|
}
|
||||||
case SplitAttributes.LayoutDirection.LOCALE: {
|
case SplitAttributes.LayoutDirection.LOCALE: {
|
||||||
final boolean isLtr = taskConfiguration.getLayoutDirection()
|
final boolean isLtr = taskConfiguration.getLayoutDirection()
|
||||||
== View.LAYOUT_DIRECTION_LTR;
|
== View.LAYOUT_DIRECTION_LTR;
|
||||||
return isLtr
|
return isLtr
|
||||||
? getLeftContainerBounds(taskConfiguration, splitAttributes, foldingFeature)
|
? getLeftContainerBounds(taskConfiguration, computedSplitAttributes,
|
||||||
: getRightContainerBounds(taskConfiguration, splitAttributes,
|
foldingFeature)
|
||||||
|
: getRightContainerBounds(taskConfiguration, computedSplitAttributes,
|
||||||
foldingFeature);
|
foldingFeature);
|
||||||
}
|
}
|
||||||
case SplitAttributes.LayoutDirection.TOP_TO_BOTTOM: {
|
case SplitAttributes.LayoutDirection.TOP_TO_BOTTOM: {
|
||||||
return getTopContainerBounds(taskConfiguration, splitAttributes, foldingFeature);
|
return getTopContainerBounds(taskConfiguration, computedSplitAttributes,
|
||||||
|
foldingFeature);
|
||||||
}
|
}
|
||||||
case SplitAttributes.LayoutDirection.BOTTOM_TO_TOP: {
|
case SplitAttributes.LayoutDirection.BOTTOM_TO_TOP: {
|
||||||
return getBottomContainerBounds(taskConfiguration, splitAttributes, foldingFeature);
|
return getBottomContainerBounds(taskConfiguration, computedSplitAttributes,
|
||||||
|
foldingFeature);
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException("Unknown layout direction:"
|
||||||
|
+ computedSplitAttributes.getLayoutDirection());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
private Rect getSecondaryBounds(@NonNull Configuration taskConfiguration,
|
||||||
|
@NonNull SplitAttributes splitAttributes, @Nullable FoldingFeature foldingFeature) {
|
||||||
|
final SplitAttributes computedSplitAttributes = updateSplitAttributesType(splitAttributes,
|
||||||
|
computeSplitType(splitAttributes, taskConfiguration, foldingFeature));
|
||||||
|
if (!shouldShowSplit(computedSplitAttributes)) {
|
||||||
|
return new Rect();
|
||||||
|
}
|
||||||
|
switch (computedSplitAttributes.getLayoutDirection()) {
|
||||||
|
case SplitAttributes.LayoutDirection.LEFT_TO_RIGHT: {
|
||||||
|
return getRightContainerBounds(taskConfiguration, computedSplitAttributes,
|
||||||
|
foldingFeature);
|
||||||
|
}
|
||||||
|
case SplitAttributes.LayoutDirection.RIGHT_TO_LEFT: {
|
||||||
|
return getLeftContainerBounds(taskConfiguration, computedSplitAttributes,
|
||||||
|
foldingFeature);
|
||||||
|
}
|
||||||
|
case SplitAttributes.LayoutDirection.LOCALE: {
|
||||||
|
final boolean isLtr = taskConfiguration.getLayoutDirection()
|
||||||
|
== View.LAYOUT_DIRECTION_LTR;
|
||||||
|
return isLtr
|
||||||
|
? getRightContainerBounds(taskConfiguration, computedSplitAttributes,
|
||||||
|
foldingFeature)
|
||||||
|
: getLeftContainerBounds(taskConfiguration, computedSplitAttributes,
|
||||||
|
foldingFeature);
|
||||||
|
}
|
||||||
|
case SplitAttributes.LayoutDirection.TOP_TO_BOTTOM: {
|
||||||
|
return getBottomContainerBounds(taskConfiguration, computedSplitAttributes,
|
||||||
|
foldingFeature);
|
||||||
|
}
|
||||||
|
case SplitAttributes.LayoutDirection.BOTTOM_TO_TOP: {
|
||||||
|
return getTopContainerBounds(taskConfiguration, computedSplitAttributes,
|
||||||
|
foldingFeature);
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
throw new IllegalArgumentException("Unknown layout direction:"
|
throw new IllegalArgumentException("Unknown layout direction:"
|
||||||
@@ -772,38 +811,17 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
/**
|
||||||
private Rect getSecondaryBounds(@NonNull Configuration taskConfiguration,
|
* Returns the {@link SplitAttributes} that update the {@link SplitType} to
|
||||||
@NonNull SplitAttributes splitAttributes, @Nullable FoldingFeature foldingFeature) {
|
* {@code splitTypeToUpdate}.
|
||||||
if (!shouldShowSplit(splitAttributes)) {
|
*/
|
||||||
return new Rect();
|
private static SplitAttributes updateSplitAttributesType(
|
||||||
}
|
@NonNull SplitAttributes splitAttributes, @NonNull SplitType splitTypeToUpdate) {
|
||||||
switch (splitAttributes.getLayoutDirection()) {
|
return new SplitAttributes.Builder()
|
||||||
case SplitAttributes.LayoutDirection.LEFT_TO_RIGHT: {
|
.setSplitType(splitTypeToUpdate)
|
||||||
return getRightContainerBounds(taskConfiguration, splitAttributes, foldingFeature);
|
.setLayoutDirection(splitAttributes.getLayoutDirection())
|
||||||
}
|
.setAnimationBackgroundColor(splitAttributes.getAnimationBackgroundColor())
|
||||||
case SplitAttributes.LayoutDirection.RIGHT_TO_LEFT: {
|
.build();
|
||||||
return getLeftContainerBounds(taskConfiguration, splitAttributes, foldingFeature);
|
|
||||||
}
|
|
||||||
case SplitAttributes.LayoutDirection.LOCALE: {
|
|
||||||
final boolean isLtr = taskConfiguration.getLayoutDirection()
|
|
||||||
== View.LAYOUT_DIRECTION_LTR;
|
|
||||||
return isLtr
|
|
||||||
? getRightContainerBounds(taskConfiguration, splitAttributes,
|
|
||||||
foldingFeature)
|
|
||||||
: getLeftContainerBounds(taskConfiguration, splitAttributes,
|
|
||||||
foldingFeature);
|
|
||||||
}
|
|
||||||
case SplitAttributes.LayoutDirection.TOP_TO_BOTTOM: {
|
|
||||||
return getBottomContainerBounds(taskConfiguration, splitAttributes, foldingFeature);
|
|
||||||
}
|
|
||||||
case SplitAttributes.LayoutDirection.BOTTOM_TO_TOP: {
|
|
||||||
return getTopContainerBounds(taskConfiguration, splitAttributes, foldingFeature);
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
throw new IllegalArgumentException("Unknown layout direction:"
|
|
||||||
+ splitAttributes.getLayoutDirection());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@@ -898,7 +916,8 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private FoldingFeature getFoldingFeature(@NonNull TaskProperties taskProperties) {
|
@VisibleForTesting
|
||||||
|
FoldingFeature getFoldingFeature(@NonNull TaskProperties taskProperties) {
|
||||||
final int displayId = taskProperties.getDisplayId();
|
final int displayId = taskProperties.getDisplayId();
|
||||||
final WindowConfiguration windowConfiguration = taskProperties.getConfiguration()
|
final WindowConfiguration windowConfiguration = taskProperties.getConfiguration()
|
||||||
.windowConfiguration;
|
.windowConfiguration;
|
||||||
|
|||||||
@@ -729,6 +729,27 @@ public class SplitPresenterTest {
|
|||||||
splitPairRule, SPLIT_ATTRIBUTES, null /* minDimensionsPair */));
|
splitPairRule, SPLIT_ATTRIBUTES, null /* minDimensionsPair */));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testComputeSplitAttributesOnHingeSplitTypeOnDeviceWithoutFoldingFeature() {
|
||||||
|
final SplitAttributes hingeSplitAttrs = new SplitAttributes.Builder()
|
||||||
|
.setSplitType(new SplitAttributes.SplitType.HingeSplitType(
|
||||||
|
SplitAttributes.SplitType.RatioSplitType.splitEqually()))
|
||||||
|
.build();
|
||||||
|
final SplitPairRule splitPairRule = createSplitPairRuleBuilder(
|
||||||
|
activityPair -> true,
|
||||||
|
activityIntentPair -> true,
|
||||||
|
windowMetrics -> windowMetrics.getBounds().equals(TASK_BOUNDS))
|
||||||
|
.setFinishSecondaryWithPrimary(DEFAULT_FINISH_SECONDARY_WITH_PRIMARY)
|
||||||
|
.setFinishPrimaryWithSecondary(DEFAULT_FINISH_PRIMARY_WITH_SECONDARY)
|
||||||
|
.setDefaultSplitAttributes(hingeSplitAttrs)
|
||||||
|
.build();
|
||||||
|
final TaskContainer.TaskProperties taskProperties = getTaskProperties();
|
||||||
|
doReturn(null).when(mPresenter).getFoldingFeature(any());
|
||||||
|
|
||||||
|
assertEquals(hingeSplitAttrs, mPresenter.computeSplitAttributes(taskProperties,
|
||||||
|
splitPairRule, hingeSplitAttrs, null /* minDimensionsPair */));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetTaskWindowMetrics() {
|
public void testGetTaskWindowMetrics() {
|
||||||
final Configuration taskConfig = new Configuration();
|
final Configuration taskConfig = new Configuration();
|
||||||
|
|||||||
Reference in New Issue
Block a user