Merge "Create a general mapping between window types and inset types." into rvc-dev am: e88d949e0a

Change-Id: I9d40f6e4035f8cfa07de512f1327722e93c04302
This commit is contained in:
Automerger Merge Worker
2020-03-17 18:11:23 +00:00
4 changed files with 125 additions and 0 deletions

View File

@@ -89,6 +89,7 @@ import android.view.accessibility.AccessibilityNodeInfo;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
@@ -2895,6 +2896,18 @@ public interface WindowManager extends ViewManager {
private boolean mFitInsetsIgnoringVisibility = false;
/**
* {@link InsetsState.InternalInsetsType}s to be applied to the window
* If {@link #type} has the predefined insets (like {@link #TYPE_STATUS_BAR} or
* {@link #TYPE_NAVIGATION_BAR}), this field will be ignored.
*
* <p>Note: provide only one inset corresponding to the window type (like
* {@link InsetsState.InternalInsetsType#ITYPE_STATUS_BAR} or
* {@link InsetsState.InternalInsetsType#ITYPE_NAVIGATION_BAR})</p>
* @hide
*/
public @InsetsState.InternalInsetsType int[] providesInsetsTypes;
/**
* Specifies types of insets that this window should avoid overlapping during layout.
*
@@ -3116,6 +3129,12 @@ public interface WindowManager extends ViewManager {
out.writeInt(mFitInsetsSides);
out.writeBoolean(mFitInsetsIgnoringVisibility);
out.writeBoolean(preferMinimalPostProcessing);
if (providesInsetsTypes != null) {
out.writeInt(providesInsetsTypes.length);
out.writeIntArray(providesInsetsTypes);
} else {
out.writeInt(0);
}
}
public static final @android.annotation.NonNull Parcelable.Creator<LayoutParams> CREATOR
@@ -3177,6 +3196,11 @@ public interface WindowManager extends ViewManager {
mFitInsetsSides = in.readInt();
mFitInsetsIgnoringVisibility = in.readBoolean();
preferMinimalPostProcessing = in.readBoolean();
int insetsTypesLength = in.readInt();
if (insetsTypesLength > 0) {
providesInsetsTypes = new int[insetsTypesLength];
in.readIntArray(providesInsetsTypes);
}
}
@SuppressWarnings({"PointlessBitwiseExpression"})
@@ -3437,6 +3461,11 @@ public interface WindowManager extends ViewManager {
changes |= LAYOUT_CHANGED;
}
if (!Arrays.equals(providesInsetsTypes, o.providesInsetsTypes)) {
providesInsetsTypes = o.providesInsetsTypes;
changes |= LAYOUT_CHANGED;
}
return changes;
}
@@ -3609,6 +3638,14 @@ public interface WindowManager extends ViewManager {
sb.append(System.lineSeparator());
sb.append(prefix).append(" fitIgnoreVis");
}
if (providesInsetsTypes != null) {
sb.append(System.lineSeparator());
sb.append(prefix).append(" insetsTypes=");
for (int i = 0; i < providesInsetsTypes.length; ++i) {
if (i > 0) sb.append(' ');
sb.append(InsetsState.typeToString(providesInsetsTypes[i]));
}
}
sb.append('}');
return sb.toString();

View File

@@ -28,6 +28,7 @@ import static android.view.Display.TYPE_INTERNAL;
import static android.view.InsetsState.ITYPE_BOTTOM_DISPLAY_CUTOUT;
import static android.view.InsetsState.ITYPE_BOTTOM_GESTURES;
import static android.view.InsetsState.ITYPE_BOTTOM_TAPPABLE_ELEMENT;
import static android.view.InsetsState.ITYPE_CAPTION_BAR;
import static android.view.InsetsState.ITYPE_IME;
import static android.view.InsetsState.ITYPE_LEFT_DISPLAY_CUTOUT;
import static android.view.InsetsState.ITYPE_LEFT_GESTURES;
@@ -1024,6 +1025,13 @@ public class DisplayPolicy {
case TYPE_STATUS_BAR_PANEL:
return WindowManagerGlobal.ADD_INVALID_TYPE;
}
if (attrs.providesInsetsTypes != null) {
mContext.enforcePermission(
android.Manifest.permission.STATUS_BAR_SERVICE, callingPid, callingUid,
"DisplayPolicy");
enforceSingleInsetsTypeCorrespondingToWindowType(attrs.providesInsetsTypes);
}
return ADD_OKAY;
}
@@ -1110,6 +1118,28 @@ public class DisplayPolicy {
});
if (DEBUG_LAYOUT) Slog.i(TAG, "NAVIGATION BAR: " + mNavigationBar);
break;
default:
if (attrs.providesInsetsTypes != null) {
for (int insetsType : attrs.providesInsetsTypes) {
mDisplayContent.setInsetProvider(insetsType, win, null);
}
}
break;
}
}
private static void enforceSingleInsetsTypeCorrespondingToWindowType(int[] insetsTypes) {
int count = 0;
for (int insetsType : insetsTypes) {
switch (insetsType) {
case ITYPE_NAVIGATION_BAR:
case ITYPE_STATUS_BAR:
case ITYPE_CAPTION_BAR:
if (++count > 1) {
throw new IllegalArgumentException(
"Multiple InsetsTypes corresponding to Window type");
}
}
}
}

View File

@@ -20,6 +20,7 @@ android_test {
"mockito-target-extended-minus-junit4",
"platform-test-annotations",
"servicestests-utils",
"testng",
"truth-prebuilt",
"testables",
"ub-uiautomator",

View File

@@ -20,6 +20,9 @@ import static android.view.Gravity.BOTTOM;
import static android.view.Gravity.LEFT;
import static android.view.Gravity.RIGHT;
import static android.view.Gravity.TOP;
import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
import static android.view.InsetsState.ITYPE_STATUS_BAR;
import static android.view.InsetsState.ITYPE_TOP_GESTURES;
import static android.view.Surface.ROTATION_0;
import static android.view.Surface.ROTATION_270;
import static android.view.Surface.ROTATION_90;
@@ -42,13 +45,17 @@ import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertThat;
import static org.junit.Assume.assumeTrue;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.spy;
import static org.testng.Assert.expectThrows;
import android.app.WindowConfiguration;
import android.graphics.Insets;
@@ -153,6 +160,56 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
assertEquals(0, mWindow.mAttrs.subtreeSystemUiVisibility);
}
@Test
public void addingWindow_withInsetsTypes() {
WindowState win = createWindow(null, TYPE_STATUS_BAR_SUB_PANEL, "StatusBarSubPanel");
win.mAttrs.providesInsetsTypes = new int[]{ITYPE_STATUS_BAR, ITYPE_TOP_GESTURES};
win.getFrameLw().set(0, 0, 500, 100);
addWindow(win);
InsetsStateController controller = mDisplayContent.getInsetsStateController();
controller.onPostLayout();
InsetsSourceProvider statusBarProvider = controller.getSourceProvider(ITYPE_STATUS_BAR);
assertEquals(new Rect(0, 0, 500, 100), statusBarProvider.getSource().getFrame());
assertEquals(Insets.of(0, 100, 0, 0),
statusBarProvider.getSource().calculateInsets(new Rect(0, 0, 500, 500),
false /* ignoreVisibility */));
InsetsSourceProvider topGesturesProvider = controller.getSourceProvider(ITYPE_TOP_GESTURES);
assertEquals(new Rect(0, 0, 500, 100), topGesturesProvider.getSource().getFrame());
assertEquals(Insets.of(0, 100, 0, 0),
topGesturesProvider.getSource().calculateInsets(new Rect(0, 0, 500, 500),
false /* ignoreVisibility */));
InsetsSourceProvider navigationBarProvider = controller.getSourceProvider(
ITYPE_NAVIGATION_BAR);
assertNotEquals(new Rect(0, 0, 500, 100), navigationBarProvider.getSource().getFrame());
}
@Test
public void addingWindow_ignoresInsetsTypes_InWindowTypeWithPredefinedInsets() {
mDisplayPolicy.removeWindowLw(mStatusBarWindow); // Removes the existing one.
WindowState win = createWindow(null, TYPE_STATUS_BAR, "StatusBar");
win.mAttrs.providesInsetsTypes = new int[]{ITYPE_STATUS_BAR};
win.getFrameLw().set(0, 0, 500, 100);
addWindow(win);
mDisplayContent.getInsetsStateController().onPostLayout();
InsetsSourceProvider provider =
mDisplayContent.getInsetsStateController().getSourceProvider(ITYPE_STATUS_BAR);
assertNotEquals(new Rect(0, 0, 500, 100), provider.getSource().getFrame());
}
@Test
public void addingWindow_throwsException_WithMultipleInsetTypes() {
WindowState win = createWindow(null, TYPE_STATUS_BAR_SUB_PANEL, "StatusBarSubPanel");
win.mAttrs.providesInsetsTypes = new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR};
expectThrows(IllegalArgumentException.class, () -> addWindow(win));
}
@Test
public void layoutWindowLw_fitStatusBars() {
assumeTrue(ViewRootImpl.sNewInsetsMode == ViewRootImpl.NEW_INSETS_MODE_FULL);