Merge "Push the frame to InsetsSourceProvider" into tm-dev am: 017ebacdaf
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/17252604 Change-Id: I3171c1e92cad1c81822ffce971178e5c1eb8f4cb
This commit is contained in:
@@ -114,6 +114,7 @@ import android.os.UserHandle;
|
||||
import android.util.ArraySet;
|
||||
import android.util.PrintWriterPrinter;
|
||||
import android.util.Slog;
|
||||
import android.util.SparseArray;
|
||||
import android.view.DisplayCutout;
|
||||
import android.view.DisplayInfo;
|
||||
import android.view.Gravity;
|
||||
@@ -1151,9 +1152,8 @@ public class DisplayPolicy {
|
||||
}
|
||||
},
|
||||
|
||||
// For IME we use regular frame.
|
||||
(displayFrames, windowContainer, inOutFrame) -> {
|
||||
inOutFrame.set(win.getFrame());
|
||||
// For IME, we don't modify the frame.
|
||||
});
|
||||
|
||||
mDisplayContent.setInsetProvider(ITYPE_BOTTOM_MANDATORY_GESTURES, win,
|
||||
@@ -1488,9 +1488,30 @@ public class DisplayPolicy {
|
||||
displayFrames.mInsetsState, displayFrames.mDisplayCutoutSafe,
|
||||
displayFrames.mUnrestricted, win.getWindowingMode(), UNSPECIFIED_LENGTH,
|
||||
UNSPECIFIED_LENGTH, win.getRequestedVisibilities(),
|
||||
null /* attachedWindowFrame */, win.mGlobalScale,
|
||||
sTmpClientFrames);
|
||||
controller.computeSimulatedState(win, displayFrames, sTmpClientFrames.frame);
|
||||
null /* attachedWindowFrame */, win.mGlobalScale, sTmpClientFrames);
|
||||
final SparseArray<InsetsSource> sources = win.getProvidedInsetsSources();
|
||||
final InsetsState state = displayFrames.mInsetsState;
|
||||
for (int index = sources.size() - 1; index >= 0; index--) {
|
||||
final int type = sources.keyAt(index);
|
||||
state.addSource(controller.getSourceProvider(type).createSimulatedSource(
|
||||
displayFrames, sTmpClientFrames.frame));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(b/161810301): No one is calling this since we haven't moved window layout to the client.
|
||||
// When that happens, this should be called when the display rotation is
|
||||
// changed, so that we can dispatch the correct insets to all the clients
|
||||
// before the insets source windows report their frames to the server.
|
||||
void updateInsetsSourceFramesExceptIme(DisplayFrames displayFrames) {
|
||||
for (int i = mInsetsSourceWindowsExceptIme.size() - 1; i >= 0; i--) {
|
||||
final WindowState win = mInsetsSourceWindowsExceptIme.valueAt(i);
|
||||
mWindowLayout.computeFrames(win.getLayoutingAttrs(displayFrames.mRotation),
|
||||
displayFrames.mInsetsState, displayFrames.mDisplayCutoutSafe,
|
||||
displayFrames.mUnrestricted, win.getWindowingMode(), UNSPECIFIED_LENGTH,
|
||||
UNSPECIFIED_LENGTH, win.getRequestedVisibilities(),
|
||||
null /* attachedWindowFrame */, win.mGlobalScale, sTmpClientFrames);
|
||||
win.updateSourceFrame(sTmpClientFrames.frame);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1519,10 +1540,6 @@ public class DisplayPolicy {
|
||||
displayFrames = win.getDisplayFrames(displayFrames);
|
||||
|
||||
final WindowManager.LayoutParams attrs = win.getLayoutingAttrs(displayFrames.mRotation);
|
||||
final WindowFrames windowFrames = win.getWindowFrames();
|
||||
final Rect pf = windowFrames.mParentFrame;
|
||||
final Rect df = windowFrames.mDisplayFrame;
|
||||
final Rect f = windowFrames.mFrame;
|
||||
final Rect attachedWindowFrame = attached != null ? attached.getFrame() : null;
|
||||
|
||||
// If this window has different LayoutParams for rotations, we cannot trust its requested
|
||||
@@ -1531,25 +1548,10 @@ public class DisplayPolicy {
|
||||
final int requestedWidth = trustedSize ? win.mRequestedWidth : UNSPECIFIED_LENGTH;
|
||||
final int requestedHeight = trustedSize ? win.mRequestedHeight : UNSPECIFIED_LENGTH;
|
||||
|
||||
sTmpLastParentFrame.set(pf);
|
||||
|
||||
mWindowLayout.computeFrames(attrs, win.getInsetsState(), displayFrames.mDisplayCutoutSafe,
|
||||
win.getBounds(), win.getWindowingMode(), requestedWidth, requestedHeight,
|
||||
win.getRequestedVisibilities(), attachedWindowFrame, win.mGlobalScale,
|
||||
sTmpClientFrames);
|
||||
windowFrames.setParentFrameWasClippedByDisplayCutout(
|
||||
sTmpClientFrames.isParentFrameClippedByDisplayCutout);
|
||||
|
||||
if (DEBUG_LAYOUT) Slog.v(TAG, "Compute frame " + attrs.getTitle()
|
||||
+ ": sim=#" + Integer.toHexString(attrs.softInputMode)
|
||||
+ " attach=" + attached + " type=" + attrs.type
|
||||
+ " flags=" + ViewDebug.flagsToString(LayoutParams.class, "flags", attrs.flags)
|
||||
+ " pf=" + pf.toShortString() + " df=" + df.toShortString()
|
||||
+ " f=" + f.toShortString());
|
||||
|
||||
if (!sTmpLastParentFrame.equals(pf)) {
|
||||
windowFrames.setContentChanged(true);
|
||||
}
|
||||
|
||||
win.setFrames(sTmpClientFrames);
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ import static com.android.server.wm.WindowManagerService.H.UPDATE_MULTI_WINDOW_S
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Trace;
|
||||
import android.util.proto.ProtoOutputStream;
|
||||
import android.view.InsetsSource;
|
||||
@@ -79,8 +80,8 @@ final class ImeInsetsSourceProvider extends WindowContainerInsetsSourceProvider
|
||||
}
|
||||
|
||||
@Override
|
||||
void updateSourceFrame() {
|
||||
super.updateSourceFrame();
|
||||
void updateSourceFrame(Rect frame) {
|
||||
super.updateSourceFrame(frame);
|
||||
onSourceChanged();
|
||||
}
|
||||
|
||||
|
||||
@@ -84,6 +84,7 @@ abstract class InsetsSourceProvider {
|
||||
private TriConsumer<DisplayFrames, WindowContainer, Rect> mImeFrameProvider;
|
||||
private final Rect mImeOverrideFrame = new Rect();
|
||||
private boolean mIsLeashReadyForDispatching;
|
||||
private final Rect mSourceFrame = new Rect();
|
||||
private final Rect mLastSourceFrame = new Rect();
|
||||
|
||||
private final Consumer<Transaction> mSetLeashPositionConsumer = t -> {
|
||||
@@ -183,8 +184,8 @@ abstract class InsetsSourceProvider {
|
||||
mImeFrameProvider = imeFrameProvider;
|
||||
if (windowContainer == null) {
|
||||
setServerVisible(false);
|
||||
mSource.setFrame(new Rect());
|
||||
mSource.setVisibleFrame(null);
|
||||
mSourceFrame.setEmpty();
|
||||
} else {
|
||||
mWindowContainer.getProvidedInsetsSources().put(mSource.getType(), mSource);
|
||||
if (mControllable) {
|
||||
@@ -208,7 +209,7 @@ abstract class InsetsSourceProvider {
|
||||
* The source frame can affect the layout of other windows, so this should be called once the
|
||||
* window container gets laid out.
|
||||
*/
|
||||
void updateSourceFrame() {
|
||||
void updateSourceFrame(Rect frame) {
|
||||
if (mWindowContainer == null) {
|
||||
return;
|
||||
}
|
||||
@@ -230,39 +231,25 @@ abstract class InsetsSourceProvider {
|
||||
return;
|
||||
}
|
||||
|
||||
if (win.mGivenInsetsPending) {
|
||||
// If the given insets are pending, they are not reliable for now. The source frame
|
||||
// should be updated after the new given insets are sent to window manager.
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure we set the valid source frame only when server visible is true, because the
|
||||
// frame may not yet determined that server side doesn't think the window is ready to
|
||||
// visible. (i.e. No surface, pending insets that were given during layout, etc..)
|
||||
if (mServerVisible) {
|
||||
mTmpRect.set(win.getFrame());
|
||||
if (mFrameProvider != null) {
|
||||
mFrameProvider.accept(mWindowContainer.getDisplayContent().mDisplayFrames,
|
||||
mWindowContainer, mTmpRect);
|
||||
} else {
|
||||
mTmpRect.inset(win.mGivenContentInsets);
|
||||
}
|
||||
mSourceFrame.set(frame);
|
||||
if (mFrameProvider != null) {
|
||||
mFrameProvider.accept(mWindowContainer.getDisplayContent().mDisplayFrames,
|
||||
mWindowContainer, mSourceFrame);
|
||||
} else {
|
||||
mTmpRect.setEmpty();
|
||||
mSourceFrame.inset(win.mGivenContentInsets);
|
||||
}
|
||||
mSource.setFrame(mTmpRect);
|
||||
updateSourceFrameForServerVisibility();
|
||||
|
||||
if (mImeFrameProvider != null) {
|
||||
mImeOverrideFrame.set(win.getFrame());
|
||||
mImeOverrideFrame.set(frame);
|
||||
mImeFrameProvider.accept(mWindowContainer.getDisplayContent().mDisplayFrames,
|
||||
mWindowContainer,
|
||||
mImeOverrideFrame);
|
||||
mWindowContainer, mImeOverrideFrame);
|
||||
}
|
||||
|
||||
if (win.mGivenVisibleInsets.left != 0 || win.mGivenVisibleInsets.top != 0
|
||||
|| win.mGivenVisibleInsets.right != 0
|
||||
|| win.mGivenVisibleInsets.bottom != 0) {
|
||||
mTmpRect.set(win.getFrame());
|
||||
mTmpRect.set(frame);
|
||||
mTmpRect.inset(win.mGivenVisibleInsets);
|
||||
mSource.setVisibleFrame(mTmpRect);
|
||||
} else {
|
||||
@@ -270,13 +257,24 @@ abstract class InsetsSourceProvider {
|
||||
}
|
||||
}
|
||||
|
||||
private void updateSourceFrameForServerVisibility() {
|
||||
// Make sure we set the valid source frame only when server visible is true, because the
|
||||
// frame may not yet determined that server side doesn't think the window is ready to
|
||||
// visible. (i.e. No surface, pending insets that were given during layout, etc..)
|
||||
if (mServerVisible) {
|
||||
mSource.setFrame(mSourceFrame);
|
||||
} else {
|
||||
mSource.setFrame(0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/** @return A new source computed by the specified window frame in the given display frames. */
|
||||
InsetsSource createSimulatedSource(DisplayFrames displayFrames, Rect winFrame) {
|
||||
InsetsSource createSimulatedSource(DisplayFrames displayFrames, Rect frame) {
|
||||
// Don't copy visible frame because it might not be calculated in the provided display
|
||||
// frames and it is not significant for this usage.
|
||||
final InsetsSource source = new InsetsSource(mSource.getType());
|
||||
source.setVisible(mSource.isVisible());
|
||||
mTmpRect.set(winFrame);
|
||||
mTmpRect.set(frame);
|
||||
if (mFrameProvider != null) {
|
||||
mFrameProvider.accept(displayFrames, mWindowContainer, mTmpRect);
|
||||
}
|
||||
@@ -296,7 +294,6 @@ abstract class InsetsSourceProvider {
|
||||
? windowState.wouldBeVisibleIfPolicyIgnored() && windowState.isVisibleByPolicy()
|
||||
: mWindowContainer.isVisibleRequested();
|
||||
setServerVisible(isServerVisible);
|
||||
updateSourceFrame();
|
||||
if (mControl != null) {
|
||||
boolean changed = false;
|
||||
final Point position = getWindowFrameSurfacePosition();
|
||||
@@ -496,6 +493,7 @@ abstract class InsetsSourceProvider {
|
||||
@VisibleForTesting
|
||||
void setServerVisible(boolean serverVisible) {
|
||||
mServerVisible = serverVisible;
|
||||
updateSourceFrameForServerVisibility();
|
||||
updateVisibility();
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,6 @@ import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_IME;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Trace;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.ArraySet;
|
||||
@@ -204,23 +203,6 @@ class InsetsStateController {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes insets state of the insets provider window in the display frames.
|
||||
*
|
||||
* @param win The owner window of insets provider.
|
||||
* @param displayFrames The display frames to create insets source.
|
||||
* @param winFrame The frame of the insets source window.
|
||||
*/
|
||||
void computeSimulatedState(WindowState win, DisplayFrames displayFrames, Rect winFrame) {
|
||||
final InsetsState state = displayFrames.mInsetsState;
|
||||
for (int i = mProviders.size() - 1; i >= 0; i--) {
|
||||
final WindowContainerInsetsSourceProvider provider = mProviders.valueAt(i);
|
||||
if (provider.mWindowContainer == win) {
|
||||
state.addSource(provider.createSimulatedSource(displayFrames, winFrame));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean isFakeTarget(@InternalInsetsType int type, InsetsControlTarget target) {
|
||||
return mTypeFakeControlTargetMap.get(type) == target;
|
||||
}
|
||||
|
||||
@@ -2156,6 +2156,7 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
w.mGivenTouchableRegion.scale(w.mGlobalScale);
|
||||
}
|
||||
w.setDisplayLayoutNeeded();
|
||||
w.updateSourceFrame(w.getFrame());
|
||||
mWindowPlacerLocked.performSurfacePlacement();
|
||||
w.getDisplayContent().getInputMonitor().updateInputWindowsLw(true);
|
||||
|
||||
|
||||
@@ -142,7 +142,6 @@ import static com.android.server.wm.WindowManagerDebugConfig.DEBUG;
|
||||
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
|
||||
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_CONFIGURATION;
|
||||
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_INPUT_METHOD;
|
||||
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT;
|
||||
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_POWER;
|
||||
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW_VERBOSE;
|
||||
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
|
||||
@@ -1402,11 +1401,15 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
|
||||
mHaveFrame = true;
|
||||
|
||||
final WindowFrames windowFrames = mWindowFrames;
|
||||
mTmpRect.set(windowFrames.mParentFrame);
|
||||
windowFrames.mDisplayFrame.set(clientWindowFrames.displayFrame);
|
||||
windowFrames.mParentFrame.set(clientWindowFrames.parentFrame);
|
||||
windowFrames.mFrame.set(clientWindowFrames.frame);
|
||||
windowFrames.setParentFrameWasClippedByDisplayCutout(
|
||||
clientWindowFrames.isParentFrameClippedByDisplayCutout);
|
||||
|
||||
if (mRequestedWidth != mLastRequestedWidth || mRequestedHeight != mLastRequestedHeight) {
|
||||
if (mRequestedWidth != mLastRequestedWidth || mRequestedHeight != mLastRequestedHeight
|
||||
|| !mTmpRect.equals(windowFrames.mParentFrame)) {
|
||||
mLastRequestedWidth = mRequestedWidth;
|
||||
mLastRequestedHeight = mRequestedHeight;
|
||||
windowFrames.setContentChanged(true);
|
||||
@@ -1435,16 +1438,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
|
||||
windowFrames.mRelFrame.offsetTo(windowFrames.mFrame.left - parentLeft,
|
||||
windowFrames.mFrame.top - parentTop);
|
||||
|
||||
if (DEBUG_LAYOUT || DEBUG) {
|
||||
final int pw = windowFrames.mParentFrame.width();
|
||||
final int ph = windowFrames.mParentFrame.height();
|
||||
Slog.v(TAG, "Resolving (mRequestedWidth="
|
||||
+ mRequestedWidth + ", mRequestedheight="
|
||||
+ mRequestedHeight + ") to" + " (pw=" + pw + ", ph=" + ph
|
||||
+ "): frame=" + windowFrames.mFrame.toShortString()
|
||||
+ " " + mAttrs.getTitle());
|
||||
}
|
||||
|
||||
if (mAttrs.type == TYPE_DOCK_DIVIDER) {
|
||||
if (!windowFrames.mFrame.equals(windowFrames.mLastFrame)) {
|
||||
mMovedByResize = true;
|
||||
@@ -1459,9 +1452,19 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
|
||||
}
|
||||
}
|
||||
|
||||
// Update the source frame to provide insets to other windows during layout.
|
||||
if (mControllableInsetProvider != null) {
|
||||
mControllableInsetProvider.updateSourceFrame();
|
||||
updateSourceFrame(windowFrames.mFrame);
|
||||
}
|
||||
|
||||
void updateSourceFrame(Rect winFrame) {
|
||||
if (mGivenInsetsPending) {
|
||||
// The given insets are pending, and they are not reliable for now. The source frame
|
||||
// should be updated after the new given insets are sent to window manager.
|
||||
return;
|
||||
}
|
||||
final SparseArray<InsetsSource> providedSources = getProvidedInsetsSources();
|
||||
final InsetsStateController controller = getDisplayContent().getInsetsStateController();
|
||||
for (int i = providedSources.size() - 1; i >= 0; i--) {
|
||||
controller.getSourceProvider(providedSources.keyAt(i)).updateSourceFrame(winFrame);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -157,6 +157,7 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
|
||||
win.getFrame().set(0, 0, 500, 100);
|
||||
|
||||
addWindow(win);
|
||||
win.updateSourceFrame(win.getFrame());
|
||||
InsetsStateController controller = mDisplayContent.getInsetsStateController();
|
||||
controller.onPostLayout();
|
||||
|
||||
@@ -185,6 +186,7 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
|
||||
win.getFrame().set(0, 0, 500, 100);
|
||||
|
||||
addWindow(win);
|
||||
win.updateSourceFrame(win.getFrame());
|
||||
mDisplayContent.getInsetsStateController().onPostLayout();
|
||||
|
||||
InsetsSourceProvider provider =
|
||||
|
||||
@@ -280,6 +280,7 @@ public class InsetsStateControllerTest extends WindowTestsBase {
|
||||
rect.set(0, 1, 2, 3)));
|
||||
getController().getSourceProvider(ITYPE_IME).setWindowContainer(ime, null, null);
|
||||
statusBar.setControllableInsetProvider(statusBarProvider);
|
||||
statusBar.updateSourceFrame(statusBar.getFrame());
|
||||
|
||||
statusBarProvider.onPostLayout();
|
||||
|
||||
|
||||
@@ -64,6 +64,7 @@ public class WindowContainerInsetsSourceProviderTest extends WindowTestsBase {
|
||||
statusBar.getFrame().set(0, 0, 500, 100);
|
||||
statusBar.mHasSurface = true;
|
||||
mProvider.setWindowContainer(statusBar, null, null);
|
||||
mProvider.updateSourceFrame(statusBar.getFrame());
|
||||
mProvider.onPostLayout();
|
||||
assertEquals(new Rect(0, 0, 500, 100), mProvider.getSource().getFrame());
|
||||
assertEquals(Insets.of(0, 100, 0, 0),
|
||||
@@ -81,6 +82,7 @@ public class WindowContainerInsetsSourceProviderTest extends WindowTestsBase {
|
||||
ime.mGivenVisibleInsets.set(0, 0, 0, 75);
|
||||
ime.mHasSurface = true;
|
||||
mProvider.setWindowContainer(ime, null, null);
|
||||
mProvider.updateSourceFrame(ime.getFrame());
|
||||
mProvider.onPostLayout();
|
||||
assertEquals(new Rect(0, 0, 500, 40), mProvider.getSource().getFrame());
|
||||
assertEquals(new Rect(0, 0, 500, 25), mProvider.getSource().getVisibleFrame());
|
||||
@@ -96,6 +98,7 @@ public class WindowContainerInsetsSourceProviderTest extends WindowTestsBase {
|
||||
final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
|
||||
statusBar.getFrame().set(0, 0, 500, 100);
|
||||
mProvider.setWindowContainer(statusBar, null, null);
|
||||
mProvider.updateSourceFrame(statusBar.getFrame());
|
||||
mProvider.onPostLayout();
|
||||
assertEquals(Insets.NONE, mProvider.getSource().calculateInsets(new Rect(0, 0, 500, 500),
|
||||
false /* ignoreVisibility */));
|
||||
@@ -110,6 +113,7 @@ public class WindowContainerInsetsSourceProviderTest extends WindowTestsBase {
|
||||
(displayFrames, windowState, rect) -> {
|
||||
rect.set(10, 10, 20, 20);
|
||||
}, null);
|
||||
mProvider.updateSourceFrame(statusBar.getFrame());
|
||||
mProvider.onPostLayout();
|
||||
assertEquals(new Rect(10, 10, 20, 20), mProvider.getSource().getFrame());
|
||||
}
|
||||
@@ -181,7 +185,7 @@ public class WindowContainerInsetsSourceProviderTest extends WindowTestsBase {
|
||||
mImeProvider.setWindowContainer(inputMethod, null, null);
|
||||
mImeProvider.setServerVisible(false);
|
||||
mImeSource.setVisible(true);
|
||||
mImeProvider.updateSourceFrame();
|
||||
mImeProvider.updateSourceFrame(inputMethod.getFrame());
|
||||
assertEquals(new Rect(0, 0, 0, 0), mImeSource.getFrame());
|
||||
Insets insets = mImeSource.calculateInsets(new Rect(0, 0, 500, 500),
|
||||
false /* ignoreVisibility */);
|
||||
@@ -189,7 +193,7 @@ public class WindowContainerInsetsSourceProviderTest extends WindowTestsBase {
|
||||
|
||||
mImeProvider.setServerVisible(true);
|
||||
mImeSource.setVisible(true);
|
||||
mImeProvider.updateSourceFrame();
|
||||
mImeProvider.updateSourceFrame(inputMethod.getFrame());
|
||||
assertEquals(inputMethod.getFrame(), mImeSource.getFrame());
|
||||
insets = mImeSource.calculateInsets(new Rect(0, 0, 500, 500),
|
||||
false /* ignoreVisibility */);
|
||||
@@ -229,6 +233,7 @@ public class WindowContainerInsetsSourceProviderTest extends WindowTestsBase {
|
||||
statusBar.getFrame().set(0, 0, 500, 100);
|
||||
statusBar.mHasSurface = true;
|
||||
mProvider.setWindowContainer(statusBar, null, null);
|
||||
mProvider.updateSourceFrame(statusBar.getFrame());
|
||||
mProvider.onPostLayout();
|
||||
assertEquals(new Rect(0, 0, 500, 100), mProvider.getSource().getFrame());
|
||||
// Still apply top insets if window overlaps even if it's top doesn't exactly match
|
||||
|
||||
Reference in New Issue
Block a user