Merge "Try to fix rounded corner overlay issue"

This commit is contained in:
Charles Chen
2020-12-16 11:44:27 +00:00
committed by Android (Google) Code Review
5 changed files with 64 additions and 11 deletions

View File

@@ -496,6 +496,32 @@ public interface WindowManagerPolicy extends WindowManagerPolicyConstants {
* @return int An arbitrary integer used to order windows, with lower numbers below higher ones.
*/
default int getWindowLayerFromTypeLw(int type, boolean canAddInternalSystemWindow) {
return getWindowLayerFromTypeLw(type, canAddInternalSystemWindow,
false /* roundedCornerOverlay */);
}
/**
* Returns the layer assignment for the window type. Allows you to control how different
* kinds of windows are ordered on-screen.
*
* @param type The type of window being assigned.
* @param canAddInternalSystemWindow If the owner window associated with the type we are
* evaluating can add internal system windows. I.e they have
* {@link Manifest.permission#INTERNAL_SYSTEM_WINDOW}. If true, alert window
* types {@link android.view.WindowManager.LayoutParams#isSystemAlertWindowType(int)}
* can be assigned layers greater than the layer for
* {@link android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY} Else, their
* layers would be lesser.
* @param roundedCornerOverlay {#code true} to indicate that the owner window is rounded corner
* overlay.
* @return int An arbitrary integer used to order windows, with lower numbers below higher ones.
*/
default int getWindowLayerFromTypeLw(int type, boolean canAddInternalSystemWindow,
boolean roundedCornerOverlay) {
// Always put the rounded corner layer to the top most.
if (roundedCornerOverlay && canAddInternalSystemWindow) {
return getMaxWindowLayer();
}
if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) {
return APPLICATION_LAYER;
}
@@ -598,8 +624,17 @@ public interface WindowManagerPolicy extends WindowManagerPolicyConstants {
}
}
// TODO(b/155340867): consider to remove the logic after using pure Surface for rounded corner
// overlay.
/**
* Returns the max window layer.
* <p>Note that the max window layer should be higher that the maximum value which reported
* by {@link #getWindowLayerFromTypeLw(int, boolean)} to contain rounded corner overlay.</p>
*
* @see WindowManager.LayoutParams#PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY
*/
default int getMaxWindowLayer() {
return 35;
return 36;
}
/**

View File

@@ -365,7 +365,7 @@ class DisplayAreaPolicyBuilder {
*/
private void build(@Nullable List<HierarchyBuilder> displayAreaGroupHierarchyBuilders) {
final WindowManagerPolicy policy = mRoot.mWmService.mPolicy;
final int maxWindowLayerCount = policy.getMaxWindowLayer();
final int maxWindowLayerCount = policy.getMaxWindowLayer() + 1;
final DisplayArea.Tokens[] displayAreaForLayer =
new DisplayArea.Tokens[maxWindowLayerCount];
final Map<Feature, List<DisplayArea<WindowContainer>>> featureAreas =
@@ -560,6 +560,7 @@ class DisplayAreaPolicyBuilder {
private final int mId;
private final boolean[] mLayers;
private NewDisplayAreaSupplier mNewDisplayAreaSupplier = DisplayArea::new;
private boolean mExcludeRoundedCorner = true;
/**
* Builds a new feature that applies to a set of window types as specified by the
@@ -578,7 +579,7 @@ class DisplayAreaPolicyBuilder {
mPolicy = policy;
mName = name;
mId = id;
mLayers = new boolean[mPolicy.getMaxWindowLayer()];
mLayers = new boolean[mPolicy.getMaxWindowLayer() + 1];
}
/**
@@ -633,7 +634,18 @@ class DisplayAreaPolicyBuilder {
return this;
}
// TODO(b/155340867): consider to remove the logic after using pure Surface for rounded
// corner overlay.
Builder setExcludeRoundedCornerOverlay(boolean excludeRoundedCorner) {
mExcludeRoundedCorner = excludeRoundedCorner;
return this;
}
Feature build() {
if (mExcludeRoundedCorner) {
// Always put the rounded corner layer to the top most layer.
mLayers[mPolicy.getMaxWindowLayer()] = false;
}
return new Feature(mName, mId, mLayers.clone(), mNewDisplayAreaSupplier);
}

View File

@@ -115,15 +115,11 @@ class RootDisplayArea extends DisplayArea<DisplayArea> {
@Nullable
DisplayArea.Tokens findAreaForToken(int windowType, boolean ownerCanManageAppTokens,
boolean roundedCornerOverlay) {
// TODO(b/159767464): cover TYPE_INPUT_METHOD(_DIALOG) case here. mAreaForLayer doesn't
// contain IME container.
int windowLayerFromType = mWmService.mPolicy.getWindowLayerFromTypeLw(windowType,
ownerCanManageAppTokens);
ownerCanManageAppTokens, roundedCornerOverlay);
if (windowLayerFromType == APPLICATION_LAYER) {
throw new IllegalArgumentException(
"There shouldn't be WindowToken on APPLICATION_LAYER");
} else if (roundedCornerOverlay) {
windowLayerFromType = mAreaForLayer.length - 1;
}
return mAreaForLayer[windowLayerFromType];
}

View File

@@ -827,15 +827,15 @@ class WindowToken extends WindowContainer<WindowState> {
* system bars, or in other words extend outside of the "Decor Frame"
*/
boolean canLayerAboveSystemBars() {
int layer = mWmService.mPolicy.getWindowLayerFromTypeLw(windowType,
mOwnerCanManageAppTokens);
int layer = getWindowLayerFromType();
int navLayer = mWmService.mPolicy.getWindowLayerFromTypeLw(TYPE_NAVIGATION_BAR,
mOwnerCanManageAppTokens);
return mOwnerCanManageAppTokens && (layer > navLayer);
}
int getWindowLayerFromType() {
return mWmService.mPolicy.getWindowLayerFromTypeLw(windowType, mOwnerCanManageAppTokens);
return mWmService.mPolicy.getWindowLayerFromTypeLw(windowType, mOwnerCanManageAppTokens,
mRoundedCornerOverlay);
}
int getOwnerUid() {

View File

@@ -22,6 +22,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
import static android.view.WindowManager.LayoutParams.TYPE_POINTER;
import static android.view.WindowManager.LayoutParams.TYPE_PRESENTATION;
import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
@@ -669,6 +670,15 @@ public class DisplayAreaPolicyBuilderTest {
assertThat(token2.isDescendantOf(mGroupRoot2)).isTrue();
}
@Test
public void testFeatureNotThrowArrayIndexOutOfBoundsException() {
final Feature feature1 = new Feature.Builder(mWms.mPolicy, "feature1",
FEATURE_VENDOR_FIRST + 5)
.all()
.except(TYPE_POINTER)
.build();
}
private static Resources resourcesWithProvider(String provider) {
Resources mock = mock(Resources.class);
when(mock.getString(