Generate WindowInsets with new insets API

In previous CL[1], WindowMetrics#WindowInsets is provided
with legacy insets, which are stable insets and system
window insets. With the new insets mode enabled, we
should provide insets with new insets API.

[1]: f65e022caa

Bug: 150095967
Test: atest WindowMetricsTests
Change-Id: I251313b4b8c033dbad8b54e58cd166e2e1665d37
This commit is contained in:
Charles Chen
2020-02-24 15:42:59 +08:00
parent 82b4074d55
commit b8070fb66e
6 changed files with 81 additions and 24 deletions

View File

@@ -60,7 +60,6 @@ public class WindowContext extends ContextWrapper {
mWms = WindowManagerGlobal.getWindowManagerService();
mToken = new WindowTokenClient();
final ContextImpl contextImpl = createBaseWindowContext(base, mToken);
attachBaseContext(contextImpl);
contextImpl.setOuterContext(this);

View File

@@ -724,11 +724,12 @@ interface IWindowManager
/**
* Called to get the expected window insets.
* TODO(window-context): Remove when new insets flag is available.
*
* @return {@code true} if system bars are always comsumed.
*/
void getWindowInsets(in WindowManager.LayoutParams attrs, int displayId,
boolean getWindowInsets(in WindowManager.LayoutParams attrs, int displayId,
out Rect outContentInsets, out Rect outStableInsets,
out DisplayCutout.ParcelableWrapper displayCutout);
out DisplayCutout.ParcelableWrapper outDisplayCutout, out InsetsState outInsetsState);
/**
* Called to show global actions.

View File

@@ -80,6 +80,12 @@ public class InsetsState implements Parcelable {
})
public @interface InternalInsetsType {}
/**
* Special value to be used to by methods returning an {@link InternalInsetsType} to indicate
* that the objects/parameters aren't associated with an {@link InternalInsetsType}
*/
public static final int ITYPE_INVALID = -1;
static final int FIRST_TYPE = 0;
public static final int ITYPE_STATUS_BAR = FIRST_TYPE;

View File

@@ -18,8 +18,11 @@ package android.view;
import static android.view.View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
import static android.view.View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
import static android.view.View.SYSTEM_UI_FLAG_VISIBLE;
import static android.view.ViewRootImpl.NEW_INSETS_MODE_FULL;
import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;
import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
import android.annotation.NonNull;
import android.app.ResourcesManager;
@@ -215,9 +218,9 @@ public final class WindowManagerImpl implements WindowManager {
@Override
public WindowMetrics getCurrentWindowMetrics() {
final Context context = mParentWindow != null ? mParentWindow.getContext() : mContext;
final Rect bound = getCurrentBounds(context);
final Rect bounds = getCurrentBounds(context);
return new WindowMetrics(toSize(bound), computeWindowInsets());
return new WindowMetrics(toSize(bounds), computeWindowInsets(bounds));
}
private static Rect getCurrentBounds(Context context) {
@@ -228,7 +231,8 @@ public final class WindowManagerImpl implements WindowManager {
@Override
public WindowMetrics getMaximumWindowMetrics() {
return new WindowMetrics(toSize(getMaximumBounds()), computeWindowInsets());
final Rect maxBounds = getMaximumBounds();
return new WindowMetrics(toSize(maxBounds), computeWindowInsets(maxBounds));
}
private Size toSize(Rect frame) {
@@ -244,9 +248,8 @@ public final class WindowManagerImpl implements WindowManager {
return new Rect(0, 0, displaySize.x, displaySize.y);
}
private WindowInsets computeWindowInsets() {
// TODO(b/118118435): This can only be properly implemented
// once we flip the new insets mode flag.
// TODO(b/150095967): Set window type to LayoutParams
private WindowInsets computeWindowInsets(Rect bounds) {
// Initialize params which used for obtaining all system insets.
final WindowManager.LayoutParams params = new WindowManager.LayoutParams();
params.flags = FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR;
@@ -257,21 +260,34 @@ public final class WindowManagerImpl implements WindowManager {
params.setFitInsetsTypes(0);
params.setFitInsetsSides(0);
return getWindowInsetsFromServer(params);
return getWindowInsetsFromServer(params, bounds);
}
private WindowInsets getWindowInsetsFromServer(WindowManager.LayoutParams attrs) {
private WindowInsets getWindowInsetsFromServer(WindowManager.LayoutParams attrs, Rect bounds) {
try {
final Rect systemWindowInsets = new Rect();
final Rect stableInsets = new Rect();
final DisplayCutout.ParcelableWrapper displayCutout =
new DisplayCutout.ParcelableWrapper();
WindowManagerGlobal.getWindowManagerService().getWindowInsets(attrs,
mContext.getDisplayId(), systemWindowInsets, stableInsets, displayCutout);
return new WindowInsets.Builder()
.setSystemWindowInsets(Insets.of(systemWindowInsets))
.setStableInsets(Insets.of(stableInsets))
.setDisplayCutout(displayCutout.get()).build();
final InsetsState insetsState = new InsetsState();
final boolean alwaysConsumeSystemBars = WindowManagerGlobal.getWindowManagerService()
.getWindowInsets(attrs, mContext.getDisplayId(), systemWindowInsets,
stableInsets, displayCutout, insetsState);
final boolean isScreenRound =
mContext.getResources().getConfiguration().isScreenRound();
if (ViewRootImpl.sNewInsetsMode == NEW_INSETS_MODE_FULL) {
return insetsState.calculateInsets(bounds, null /* ignoringVisibilityState*/,
isScreenRound, alwaysConsumeSystemBars, displayCutout.get(),
systemWindowInsets, stableInsets, SOFT_INPUT_ADJUST_NOTHING,
SYSTEM_UI_FLAG_VISIBLE, null /* typeSideMap */);
} else {
return new WindowInsets.Builder()
.setAlwaysConsumeSystemBars(alwaysConsumeSystemBars)
.setRound(isScreenRound)
.setSystemWindowInsets(Insets.of(systemWindowInsets))
.setStableInsets(Insets.of(stableInsets))
.setDisplayCutout(displayCutout.get()).build();
}
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}

View File

@@ -18,10 +18,14 @@ package com.android.server.wm;
import static android.view.InsetsState.ITYPE_CAPTION_BAR;
import static android.view.InsetsState.ITYPE_IME;
import static android.view.InsetsState.ITYPE_INVALID;
import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
import static android.view.InsetsState.ITYPE_STATUS_BAR;
import static android.view.ViewRootImpl.NEW_INSETS_MODE_FULL;
import static android.view.ViewRootImpl.sNewInsetsMode;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -32,6 +36,7 @@ import android.view.InsetsSource;
import android.view.InsetsSourceControl;
import android.view.InsetsState;
import android.view.InsetsState.InternalInsetsType;
import android.view.WindowManager;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -75,15 +80,40 @@ class InsetsStateController {
* @param target The client we dispatch the state to.
* @return The state stripped of the necessary information.
*/
InsetsState getInsetsForDispatch(WindowState target) {
InsetsState getInsetsForDispatch(@NonNull WindowState target) {
final InsetsSourceProvider provider = target.getControllableInsetProvider();
if (provider == null) {
return mState;
}
final @InternalInsetsType int type = provider.getSource().getType();
return getInsetsForType(type);
}
InsetsState getInsetsForWindowMetrics(@NonNull WindowManager.LayoutParams attrs) {
final @InternalInsetsType int type = getInsetsTypeForWindowType(attrs.type);
if (type == ITYPE_INVALID) {
return mState;
}
return getInsetsForType(type);
}
@InternalInsetsType
private static int getInsetsTypeForWindowType(int type) {
switch(type) {
case TYPE_STATUS_BAR:
return ITYPE_STATUS_BAR;
case TYPE_NAVIGATION_BAR:
return ITYPE_NAVIGATION_BAR;
case TYPE_INPUT_METHOD:
return ITYPE_IME;
default:
return ITYPE_INVALID;
}
}
private InsetsState getInsetsForType(@InternalInsetsType int type) {
final InsetsState state = new InsetsState();
state.set(mState);
final int type = provider.getSource().getType();
state.removeSource(type);
// Navigation bar doesn't get influenced by anything else

View File

@@ -8009,9 +8009,9 @@ public class WindowManagerService extends IWindowManager.Stub
}
@Override
public void getWindowInsets(WindowManager.LayoutParams attrs,
public boolean getWindowInsets(WindowManager.LayoutParams attrs,
int displayId, Rect outContentInsets, Rect outStableInsets,
DisplayCutout.ParcelableWrapper displayCutout) {
DisplayCutout.ParcelableWrapper outDisplayCutout, InsetsState outInsetsState) {
final long origId = Binder.clearCallingIdentity();
try {
synchronized (mGlobalLock) {
@@ -8021,8 +8021,13 @@ public class WindowManagerService extends IWindowManager.Stub
+ "could not be found!");
}
final WindowToken windowToken = dc.getWindowToken(attrs.token);
dc.getDisplayPolicy().getLayoutHint(attrs, windowToken, mTmpRect /* outFrame */,
outContentInsets, outStableInsets, displayCutout);
final InsetsStateController insetsStateController =
dc.getInsetsStateController();
outInsetsState.set(insetsStateController.getInsetsForWindowMetrics(attrs));
return dc.getDisplayPolicy().getLayoutHint(attrs, windowToken,
mTmpRect /* outFrame */, outContentInsets, outStableInsets,
outDisplayCutout);
}
} finally {
Binder.restoreCallingIdentity(origId);