Merge "Make caption a insets source" into rvc-dev am: ac30aafd29
Change-Id: I5c486a30fe0828cfef21e2804a6dd9e3c4415d85
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
|
||||
package android.view;
|
||||
|
||||
import static android.view.InsetsState.ITYPE_CAPTION_BAR;
|
||||
import static android.view.InsetsState.ITYPE_IME;
|
||||
import static android.view.InsetsState.toInternalType;
|
||||
import static android.view.InsetsState.toPublicType;
|
||||
@@ -367,6 +368,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
|
||||
private int mLastLegacySystemUiFlags;
|
||||
private DisplayCutout mLastDisplayCutout;
|
||||
private boolean mStartingAnimation;
|
||||
private int mCaptionInsetsHeight = 0;
|
||||
|
||||
private SyncRtSurfaceTransactionApplier mApplier;
|
||||
|
||||
@@ -460,7 +462,8 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
|
||||
|
||||
@VisibleForTesting
|
||||
public boolean onStateChanged(InsetsState state) {
|
||||
boolean localStateChanged = !mState.equals(state);
|
||||
boolean localStateChanged = !mState.equals(state, true /* excludingCaptionInsets */)
|
||||
|| !captionInsetsUnchanged();
|
||||
if (!localStateChanged && mLastDispachedState.equals(state)) {
|
||||
return false;
|
||||
}
|
||||
@@ -470,7 +473,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
|
||||
if (localStateChanged) {
|
||||
mViewRoot.notifyInsetsChanged();
|
||||
}
|
||||
if (!mState.equals(mLastDispachedState)) {
|
||||
if (!mState.equals(mLastDispachedState, true /* excludingCaptionInsets */)) {
|
||||
sendStateToWindowManager();
|
||||
}
|
||||
return true;
|
||||
@@ -488,6 +491,23 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
|
||||
mState.removeSource(source.getType());
|
||||
}
|
||||
}
|
||||
if (mCaptionInsetsHeight != 0) {
|
||||
mState.getSource(ITYPE_CAPTION_BAR).setFrame(new Rect(mFrame.left, mFrame.top,
|
||||
mFrame.right, mFrame.top + mCaptionInsetsHeight));
|
||||
}
|
||||
}
|
||||
|
||||
private boolean captionInsetsUnchanged() {
|
||||
if (mState.peekSource(ITYPE_CAPTION_BAR) == null
|
||||
&& mCaptionInsetsHeight == 0) {
|
||||
return true;
|
||||
}
|
||||
if (mState.peekSource(ITYPE_CAPTION_BAR) != null
|
||||
&& mCaptionInsetsHeight
|
||||
== mState.peekSource(ITYPE_CAPTION_BAR).getFrame().height()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -964,6 +984,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
|
||||
InsetsState tmpState = new InsetsState();
|
||||
for (int i = mSourceConsumers.size() - 1; i >= 0; i--) {
|
||||
final InsetsSourceConsumer consumer = mSourceConsumers.valueAt(i);
|
||||
if (consumer.getType() == ITYPE_CAPTION_BAR) continue;
|
||||
if (consumer.getControl() != null) {
|
||||
tmpState.addSource(mState.getSource(consumer.getType()));
|
||||
}
|
||||
@@ -1104,6 +1125,11 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
|
||||
return mViewRoot.mWindowAttributes.insetsFlags.appearance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCaptionInsetsHeight(int height) {
|
||||
mCaptionInsetsHeight = height;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSystemBarsBehavior(@Behavior int behavior) {
|
||||
mViewRoot.mWindowAttributes.privateFlags |= PRIVATE_FLAG_BEHAVIOR_CONTROLLED;
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package android.view;
|
||||
|
||||
import static android.view.InsetsState.ITYPE_CAPTION_BAR;
|
||||
import static android.view.InsetsState.ITYPE_IME;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
@@ -118,6 +119,12 @@ public class InsetsSource implements Parcelable {
|
||||
if (!getIntersection(frame, relativeFrame, mTmpFrame)) {
|
||||
return Insets.NONE;
|
||||
}
|
||||
// During drag-move and drag-resizing, the caption insets position may not get updated
|
||||
// before the app frame get updated. To layout the app content correctly during drag events,
|
||||
// we always return the insets with the corresponding height covering the top.
|
||||
if (getType() == ITYPE_CAPTION_BAR) {
|
||||
return Insets.of(0, frame.height(), 0, 0);
|
||||
}
|
||||
|
||||
// TODO: Currently, non-floating IME always intersects at bottom due to issues with cutout.
|
||||
// However, we should let the policy decide from the server.
|
||||
|
||||
@@ -45,6 +45,8 @@ import android.view.WindowInsets.Type;
|
||||
import android.view.WindowInsets.Type.InsetsType;
|
||||
import android.view.WindowManager.LayoutParams.SoftInputModeFlags;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
@@ -498,6 +500,19 @@ public class InsetsState implements Parcelable {
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
return equals(o, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* An equals method can exclude the caption insets. This is useful because we assemble the
|
||||
* caption insets information on the client side, and when we communicate with server, it's
|
||||
* excluded.
|
||||
* @param excludingCaptionInsets {@code true} if we want to compare two InsetsState objects but
|
||||
* ignore the caption insets source value.
|
||||
* @return {@code true} if the two InsetsState objects are equal, {@code false} otherwise.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
public boolean equals(Object o, boolean excludingCaptionInsets) {
|
||||
if (this == o) { return true; }
|
||||
if (o == null || getClass() != o.getClass()) { return false; }
|
||||
|
||||
@@ -506,11 +521,24 @@ public class InsetsState implements Parcelable {
|
||||
if (!mDisplayFrame.equals(state.mDisplayFrame)) {
|
||||
return false;
|
||||
}
|
||||
if (mSources.size() != state.mSources.size()) {
|
||||
int size = mSources.size();
|
||||
int otherSize = state.mSources.size();
|
||||
if (excludingCaptionInsets) {
|
||||
if (mSources.get(ITYPE_CAPTION_BAR) != null) {
|
||||
size--;
|
||||
}
|
||||
if (state.mSources.get(ITYPE_CAPTION_BAR) != null) {
|
||||
otherSize--;
|
||||
}
|
||||
}
|
||||
if (size != otherSize) {
|
||||
return false;
|
||||
}
|
||||
for (int i = mSources.size() - 1; i >= 0; i--) {
|
||||
InsetsSource source = mSources.valueAt(i);
|
||||
if (excludingCaptionInsets) {
|
||||
if (source.getType() == ITYPE_CAPTION_BAR) continue;
|
||||
}
|
||||
InsetsSource otherSource = state.mSources.get(source.getType());
|
||||
if (otherSource == null) {
|
||||
return false;
|
||||
|
||||
@@ -42,6 +42,7 @@ public class PendingInsetsController implements WindowInsetsController {
|
||||
private InsetsController mReplayedInsetsController;
|
||||
private ArrayList<OnControllableInsetsChangedListener> mControllableInsetsChangedListeners
|
||||
= new ArrayList<>();
|
||||
private int mCaptionInsetsHeight = 0;
|
||||
|
||||
@Override
|
||||
public void show(int types) {
|
||||
@@ -79,6 +80,11 @@ public class PendingInsetsController implements WindowInsetsController {
|
||||
return mAppearance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCaptionInsetsHeight(int height) {
|
||||
mCaptionInsetsHeight = height;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSystemBarsBehavior(int behavior) {
|
||||
if (mReplayedInsetsController != null) {
|
||||
@@ -134,6 +140,9 @@ public class PendingInsetsController implements WindowInsetsController {
|
||||
if (mAppearanceMask != 0) {
|
||||
controller.setSystemBarsAppearance(mAppearance, mAppearanceMask);
|
||||
}
|
||||
if (mCaptionInsetsHeight != 0) {
|
||||
controller.setCaptionInsetsHeight(mCaptionInsetsHeight);
|
||||
}
|
||||
int size = mRequests.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
mRequests.get(i).replay(controller);
|
||||
|
||||
@@ -28768,6 +28768,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
|
||||
publicAlternatives = "Use {@link WindowInsets#getInsets(int)}")
|
||||
final Rect mStableInsets = new Rect();
|
||||
|
||||
/**
|
||||
* Current caption insets to the display coordinate.
|
||||
*/
|
||||
final Rect mCaptionInsets = new Rect();
|
||||
|
||||
final DisplayCutout.ParcelableWrapper mDisplayCutout =
|
||||
new DisplayCutout.ParcelableWrapper(DisplayCutout.NO_CUTOUT);
|
||||
|
||||
|
||||
@@ -158,6 +158,7 @@ import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.os.IResultReceiver;
|
||||
import com.android.internal.os.SomeArgs;
|
||||
import com.android.internal.policy.DecorView;
|
||||
import com.android.internal.policy.PhoneFallbackEventHandler;
|
||||
import com.android.internal.util.Preconditions;
|
||||
import com.android.internal.view.BaseSurfaceHolder;
|
||||
@@ -2221,6 +2222,19 @@ public final class ViewRootImpl implements ViewParent,
|
||||
Trace.traceEnd(Trace.TRACE_TAG_VIEW);
|
||||
}
|
||||
|
||||
private boolean updateCaptionInsets() {
|
||||
if (!(mView instanceof DecorView)) return false;
|
||||
final int captionInsetsHeight = ((DecorView) mView).getCaptionInsetsHeight();
|
||||
final Rect captionFrame = new Rect();
|
||||
if (captionInsetsHeight != 0) {
|
||||
captionFrame.set(mWinFrame.left, mWinFrame.top, mWinFrame.right,
|
||||
mWinFrame.top + captionInsetsHeight);
|
||||
}
|
||||
if (mAttachInfo.mCaptionInsets.equals(captionFrame)) return false;
|
||||
mAttachInfo.mCaptionInsets.set(captionFrame);
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean shouldDispatchCutout() {
|
||||
return mWindowAttributes.layoutInDisplayCutoutMode
|
||||
== LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
|
||||
@@ -2592,6 +2606,9 @@ public final class ViewRootImpl implements ViewParent,
|
||||
mAttachInfo.mAlwaysConsumeSystemBars = mPendingAlwaysConsumeSystemBars;
|
||||
dispatchApplyInsets = true;
|
||||
}
|
||||
if (updateCaptionInsets()) {
|
||||
dispatchApplyInsets = true;
|
||||
}
|
||||
if (dispatchApplyInsets || mLastSystemUiVisibility !=
|
||||
mAttachInfo.mSystemUiVisibility || mApplyInsetsRequested) {
|
||||
mLastSystemUiVisibility = mAttachInfo.mSystemUiVisibility;
|
||||
|
||||
@@ -49,9 +49,6 @@ import android.transition.Transition;
|
||||
import android.transition.TransitionManager;
|
||||
import android.util.Pair;
|
||||
import android.view.View.OnApplyWindowInsetsListener;
|
||||
import android.view.ViewGroup.LayoutParams;
|
||||
import android.view.WindowInsets.Side.InsetsSide;
|
||||
import android.view.WindowInsets.Type.InsetsType;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
|
||||
import java.util.Collections;
|
||||
@@ -323,7 +320,7 @@ public abstract class Window {
|
||||
@UnsupportedAppUsage
|
||||
private boolean mDestroyed;
|
||||
|
||||
private boolean mOverlayWithDecorCaptionEnabled = false;
|
||||
private boolean mOverlayWithDecorCaptionEnabled = true;
|
||||
private boolean mCloseOnSwipeEnabled = false;
|
||||
|
||||
// The current window attributes.
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
package android.view;
|
||||
|
||||
import static android.view.WindowInsets.Type.CAPTION_BAR;
|
||||
import static android.view.WindowInsets.Type.DISPLAY_CUTOUT;
|
||||
import static android.view.WindowInsets.Type.FIRST;
|
||||
import static android.view.WindowInsets.Type.IME;
|
||||
|
||||
@@ -195,6 +195,15 @@ public interface WindowInsetsController {
|
||||
*/
|
||||
@Appearance int getSystemBarsAppearance();
|
||||
|
||||
/**
|
||||
* Notify the caption insets height change. The information will be used on the client side to,
|
||||
* make sure the InsetsState has the correct caption insets.
|
||||
*
|
||||
* @param height the height of caption bar insets.
|
||||
* @hide
|
||||
*/
|
||||
void setCaptionInsetsHeight(int height);
|
||||
|
||||
/**
|
||||
* Controls the behavior of system bars.
|
||||
*
|
||||
|
||||
@@ -78,7 +78,6 @@ import android.view.ContextThemeWrapper;
|
||||
import android.view.Gravity;
|
||||
import android.view.InputQueue;
|
||||
import android.view.InsetsState;
|
||||
import android.view.InsetsController;
|
||||
import android.view.InsetsState.InternalInsetsType;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.KeyboardShortcutGroup;
|
||||
@@ -1174,6 +1173,12 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
|
||||
false /* matchVertical */, statusBarNeedsLeftInset, statusBarSideInset,
|
||||
animate && !disallowAnimate,
|
||||
mForceWindowDrawsBarBackgrounds, state);
|
||||
|
||||
if (mHasCaption) {
|
||||
final int captionColor = calculateStatusBarColor();
|
||||
mDecorCaptionView.getCaption().setBackgroundColor(captionColor);
|
||||
updateDecorCaptionShade();
|
||||
}
|
||||
}
|
||||
|
||||
// When we expand the window with FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS or
|
||||
@@ -1355,7 +1360,7 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
|
||||
: state.attributes.isPresent(insetsState, mWindow.getAttributes().flags, force);
|
||||
boolean show = state.attributes.isVisible(state.present, color,
|
||||
mWindow.getAttributes().flags, force);
|
||||
boolean showView = show && !isResizing() && size > 0;
|
||||
boolean showView = show && !isResizing() && !mHasCaption && size > 0;
|
||||
|
||||
boolean visibilityChanged = false;
|
||||
View view = state.view;
|
||||
@@ -2021,6 +2026,7 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
|
||||
if (getForeground() != null) {
|
||||
drawableChanged();
|
||||
}
|
||||
getWindowInsetsController().setCaptionInsetsHeight(getCaptionInsetsHeight());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2094,6 +2100,7 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
|
||||
mDecorCaptionView.onConfigurationChanged(displayWindowDecor);
|
||||
enableCaption(displayWindowDecor);
|
||||
}
|
||||
getWindowInsetsController().setCaptionInsetsHeight(getCaptionInsetsHeight());
|
||||
}
|
||||
|
||||
void onResourcesLoaded(LayoutInflater inflater, int layoutResource) {
|
||||
@@ -2182,11 +2189,11 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
|
||||
inflater = inflater.from(context);
|
||||
final DecorCaptionView view = (DecorCaptionView) inflater.inflate(R.layout.decor_caption,
|
||||
null);
|
||||
setDecorCaptionShade(context, view);
|
||||
setDecorCaptionShade(view);
|
||||
return view;
|
||||
}
|
||||
|
||||
private void setDecorCaptionShade(Context context, DecorCaptionView view) {
|
||||
private void setDecorCaptionShade(DecorCaptionView view) {
|
||||
final int shade = mWindow.getDecorCaptionShade();
|
||||
switch (shade) {
|
||||
case DECOR_CAPTION_SHADE_LIGHT:
|
||||
@@ -2196,15 +2203,10 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
|
||||
setDarkDecorCaptionShade(view);
|
||||
break;
|
||||
default: {
|
||||
TypedValue value = new TypedValue();
|
||||
context.getTheme().resolveAttribute(R.attr.colorPrimary, value, true);
|
||||
// We invert the shade depending on brightness of the theme. Dark shade for light
|
||||
// theme and vice versa. Thanks to this the buttons should be visible on the
|
||||
// background.
|
||||
if (Color.luminance(value.data) < 0.5) {
|
||||
setLightDecorCaptionShade(view);
|
||||
} else {
|
||||
if ((getWindowSystemUiVisibility() & SYSTEM_UI_FLAG_LIGHT_STATUS_BAR) != 0) {
|
||||
setDarkDecorCaptionShade(view);
|
||||
} else {
|
||||
setLightDecorCaptionShade(view);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -2213,7 +2215,7 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
|
||||
|
||||
void updateDecorCaptionShade() {
|
||||
if (mDecorCaptionView != null) {
|
||||
setDecorCaptionShade(getContext(), mDecorCaptionView);
|
||||
setDecorCaptionShade(mDecorCaptionView);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2483,6 +2485,15 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
|
||||
return isShowingCaption() ? mDecorCaptionView.getCaptionHeight() : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* @return the height of insets covering the top of window content area.
|
||||
*/
|
||||
public int getCaptionInsetsHeight() {
|
||||
if (!mWindow.isOverlayWithDecorCaptionEnabled()) return 0;
|
||||
return getCaptionHeight();
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a DIP measure into physical pixels.
|
||||
* @param dip The dip value.
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
package com.android.internal.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Rect;
|
||||
import android.os.RemoteException;
|
||||
import android.util.AttributeSet;
|
||||
@@ -53,8 +52,7 @@ import java.util.ArrayList;
|
||||
* <li>..</li>
|
||||
* </ul>
|
||||
*
|
||||
* Although this ViewGroup has only two direct sub-Views, its behavior is more complex due to
|
||||
* overlaying caption on the content and drawing.
|
||||
* Here describe the behavior of overlaying caption on the content and drawing.
|
||||
*
|
||||
* First, no matter where the content View gets added, it will always be the first child and the
|
||||
* caption will be the second. This way the caption will always be drawn on top of the content when
|
||||
@@ -66,11 +64,9 @@ import java.util.ArrayList;
|
||||
* <li>DecorCaptionView.onInterceptTouchEvent() will try intercepting the touch events if the
|
||||
* down action is performed on top close or maximize buttons; the reason for that is we want these
|
||||
* buttons to always work.</li>
|
||||
* <li>The content View will receive the touch event. Mind that content is actually underneath the
|
||||
* caption, so we need to introduce our own dispatch ordering. We achieve this by overriding
|
||||
* {@link #buildTouchDispatchChildList()}.</li>
|
||||
* <li>If the touch event is not consumed by the content View, it will go to the caption View
|
||||
* and the dragging logic will be executed.</li>
|
||||
* <li>The caption view will try to consume the event to apply the dragging logic.</li>
|
||||
* <li>If the touch event is not consumed by the caption, the content View will receive the touch
|
||||
* event</li>
|
||||
* </ul>
|
||||
*/
|
||||
public class DecorCaptionView extends ViewGroup implements View.OnTouchListener,
|
||||
@@ -137,11 +133,6 @@ public class DecorCaptionView extends ViewGroup implements View.OnTouchListener,
|
||||
mOwner = owner;
|
||||
mShow = show;
|
||||
mOverlayWithAppContent = owner.isOverlayWithDecorCaptionEnabled();
|
||||
if (mOverlayWithAppContent) {
|
||||
// The caption is covering the content, so we make its background transparent to make
|
||||
// the content visible.
|
||||
mCaption.setBackgroundColor(Color.TRANSPARENT);
|
||||
}
|
||||
updateCaptionVisibility();
|
||||
// By changing the outline provider to BOUNDS, the window can remove its
|
||||
// background without removing the shadow.
|
||||
@@ -235,18 +226,6 @@ public class DecorCaptionView extends ViewGroup implements View.OnTouchListener,
|
||||
return mDragging || mCheckForDragging;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArrayList<View> buildTouchDispatchChildList() {
|
||||
mTouchDispatchList.ensureCapacity(3);
|
||||
if (mCaption != null) {
|
||||
mTouchDispatchList.add(mCaption);
|
||||
}
|
||||
if (mContent != null) {
|
||||
mTouchDispatchList.add(mContent);
|
||||
}
|
||||
return mTouchDispatchList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldDelayChildPressedState() {
|
||||
return false;
|
||||
|
||||
@@ -21,6 +21,7 @@ import static android.view.InsetsController.ANIMATION_TYPE_NONE;
|
||||
import static android.view.InsetsController.ANIMATION_TYPE_SHOW;
|
||||
import static android.view.InsetsSourceConsumer.ShowResult.IME_SHOW_DELAYED;
|
||||
import static android.view.InsetsSourceConsumer.ShowResult.SHOW_IMMEDIATELY;
|
||||
import static android.view.InsetsState.ITYPE_CAPTION_BAR;
|
||||
import static android.view.InsetsState.ITYPE_IME;
|
||||
import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
|
||||
import static android.view.InsetsState.ITYPE_STATUS_BAR;
|
||||
@@ -88,7 +89,6 @@ import java.util.concurrent.CountDownLatch;
|
||||
@Presubmit
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class InsetsControllerTest {
|
||||
|
||||
private InsetsController mController;
|
||||
private SurfaceSession mSession = new SurfaceSession();
|
||||
private SurfaceControl mLeash;
|
||||
@@ -665,6 +665,26 @@ public class InsetsControllerTest {
|
||||
InstrumentationRegistry.getInstrumentation().waitForIdleSync();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCaptionInsetsStateAssemble() {
|
||||
InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
|
||||
mController.onFrameChanged(new Rect(0, 0, 100, 300));
|
||||
final InsetsState state = new InsetsState(mController.getState(), true);
|
||||
final Rect captionFrame = new Rect(0, 0, 100, 100);
|
||||
mController.setCaptionInsetsHeight(100);
|
||||
mController.onStateChanged(state);
|
||||
final InsetsState currentState = new InsetsState(mController.getState());
|
||||
// The caption bar source should be synced with the info in mAttachInfo.
|
||||
assertEquals(captionFrame, currentState.peekSource(ITYPE_CAPTION_BAR).getFrame());
|
||||
assertTrue(currentState.equals(state, true /* excludingCaptionInsets*/));
|
||||
mController.setCaptionInsetsHeight(0);
|
||||
mController.onStateChanged(state);
|
||||
// The caption bar source should not be there at all, because we don't add empty
|
||||
// caption to the state from the server.
|
||||
assertNull(mController.getState().peekSource(ITYPE_CAPTION_BAR));
|
||||
});
|
||||
}
|
||||
|
||||
private void waitUntilNextFrame() throws Exception {
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
Choreographer.getMainThreadInstance().postCallback(Choreographer.CALLBACK_COMMIT,
|
||||
|
||||
@@ -153,6 +153,35 @@ public class InsetsStateTest {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testCalculateInsets_captionStatusBarOverlap() throws Exception {
|
||||
try (InsetsModeSession session =
|
||||
new InsetsModeSession(ViewRootImpl.NEW_INSETS_MODE_FULL)) {
|
||||
mState.getSource(ITYPE_STATUS_BAR).setFrame(new Rect(0, 0, 100, 100));
|
||||
mState.getSource(ITYPE_STATUS_BAR).setVisible(true);
|
||||
mState.getSource(ITYPE_CAPTION_BAR).setFrame(new Rect(0, 0, 100, 300));
|
||||
mState.getSource(ITYPE_CAPTION_BAR).setVisible(true);
|
||||
|
||||
Rect visibleInsets = mState.calculateVisibleInsets(
|
||||
new Rect(0, 0, 100, 400), SOFT_INPUT_ADJUST_NOTHING);
|
||||
assertEquals(new Rect(0, 300, 0, 0), visibleInsets);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCalculateInsets_captionBarOffset() throws Exception {
|
||||
try (InsetsModeSession session =
|
||||
new InsetsModeSession(ViewRootImpl.NEW_INSETS_MODE_FULL)) {
|
||||
mState.getSource(ITYPE_CAPTION_BAR).setFrame(new Rect(0, 0, 100, 300));
|
||||
mState.getSource(ITYPE_CAPTION_BAR).setVisible(true);
|
||||
|
||||
Rect visibleInsets = mState.calculateVisibleInsets(
|
||||
new Rect(0, 0, 150, 400), SOFT_INPUT_ADJUST_NOTHING);
|
||||
assertEquals(new Rect(0, 300, 0, 0), visibleInsets);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStripForDispatch() {
|
||||
mState.getSource(ITYPE_STATUS_BAR).setFrame(new Rect(0, 0, 100, 100));
|
||||
|
||||
Reference in New Issue
Block a user