blob: 5ce4a20cacb5509337a834e7b7a944f2d14f133c [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.components.browser_ui.widget;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import android.annotation.TargetApi;
import android.app.Activity;
import android.graphics.Rect;
import android.os.Build;
import android.view.DisplayCutout;
import android.view.WindowInsets;
import android.widget.LinearLayout;
import androidx.test.filters.SmallTest;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.Robolectric;
import org.robolectric.annotation.Config;
import org.chromium.testing.local.LocalRobolectricTestRunner;
/**
* Tests for {@link InsetObserverView} class.
*/
@RunWith(LocalRobolectricTestRunner.class)
@Config(manifest = Config.NONE)
public class InsetObserverViewTest {
/** The rect values if the display cutout is present. */
private static final Rect DISPLAY_CUTOUT_RECT = new Rect(1, 1, 1, 1);
/** The rect values if there is no cutout. */
private static final Rect NO_CUTOUT_RECT = new Rect(0, 0, 0, 0);
@Mock
private InsetObserverView.WindowInsetObserver mObserver;
@Mock
private WindowInsets mInsets;
private Activity mActivity;
private InsetObserverView mView;
private LinearLayout mContentView;
@TargetApi(Build.VERSION_CODES.P)
private void setCutout(boolean hasCutout) {
DisplayCutout cutout = hasCutout ? new DisplayCutout(new Rect(1, 1, 1, 1), null) : null;
doReturn(cutout).when(mInsets).getDisplayCutout();
}
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mActivity = Robolectric.buildActivity(Activity.class).setup().get();
mContentView = new LinearLayout(mActivity);
mActivity.setContentView(mContentView);
mView = InsetObserverView.create(mActivity);
mView.addObserver(mObserver);
}
/** Test that applying new insets notifies observers. */
@Test
@SmallTest
public void applyInsets_NotifiesObservers() {
doReturn(1).when(mInsets).getSystemWindowInsetLeft();
doReturn(1).when(mInsets).getSystemWindowInsetTop();
doReturn(1).when(mInsets).getSystemWindowInsetRight();
doReturn(1).when(mInsets).getSystemWindowInsetBottom();
mView.onApplyWindowInsets(mInsets);
verify(mObserver, times(1)).onInsetChanged(1, 1, 1, 1);
// Apply the insets a second time; the observer should not be notified.
mView.onApplyWindowInsets(mInsets);
verify(mObserver, times(1)).onInsetChanged(1, 1, 1, 1);
doReturn(2).when(mInsets).getSystemWindowInsetBottom();
mView.onApplyWindowInsets(mInsets);
verify(mObserver).onInsetChanged(1, 1, 1, 2);
}
/** Test that applying new insets does not notify the observer. */
@Test
@SmallTest
@TargetApi(Build.VERSION_CODES.P)
public void applyInsets() {
setCutout(false);
mView.onApplyWindowInsets(mInsets);
verify(mObserver, never()).onSafeAreaChanged(any());
}
/** Test that applying new insets with a cutout notifies the observer. */
@Test
@SmallTest
@TargetApi(Build.VERSION_CODES.P)
public void applyInsets_WithCutout() {
setCutout(true);
mView.onApplyWindowInsets(mInsets);
verify(mObserver).onSafeAreaChanged(DISPLAY_CUTOUT_RECT);
}
/** Test applying new insets with a cutout and then remove the cutout. */
@Test
@SmallTest
@TargetApi(Build.VERSION_CODES.P)
public void applyInsets_WithCutout_WithoutCutout() {
setCutout(true);
mView.onApplyWindowInsets(mInsets);
verify(mObserver).onSafeAreaChanged(DISPLAY_CUTOUT_RECT);
reset(mObserver);
setCutout(false);
mView.onApplyWindowInsets(mInsets);
verify(mObserver).onSafeAreaChanged(NO_CUTOUT_RECT);
}
/** Test that applying new insets with a cutout but no observer is a no-op. */
@Test
@SmallTest
@TargetApi(Build.VERSION_CODES.P)
public void applyInsets_WithCutout_NoListener() {
setCutout(true);
mView.removeObserver(mObserver);
mView.onApplyWindowInsets(mInsets);
}
/** Test that applying new insets with no observer is a no-op. */
@Test
@SmallTest
@TargetApi(Build.VERSION_CODES.P)
public void applyInsets_NoListener() {
setCutout(false);
mView.removeObserver(mObserver);
mView.onApplyWindowInsets(mInsets);
}
}