Skip to content

Commit

Permalink
flutter view add test 2 (flutter#55188)
Browse files Browse the repository at this point in the history
- **add test back with no other changes**
- **Add legacy test and setup shadow**
2 and 3 of 5 flutter/flutter/issues/154746

Improved legacy testing by validating a fullscreen and non fullscreen codepaths. 

Added `.git-blame-ignore-revs` because git was failing to give blame values with that file missing. I dont think I added a global config anywhere but adding an empty file should not cause a problem.
  • Loading branch information
reidbaker authored Sep 16, 2024
1 parent 464e460 commit a8c9c31
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 8 deletions.
Empty file added .git-blame-ignore-revs
Empty file.
5 changes: 5 additions & 0 deletions shell/platform/android/test/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,8 @@ See [Updating Embedding Dependencies](/tools/cipd/android_embedding_bundle).
### My new test won't compile. It can't find one of my imports.

See [Updating Embedding Dependencies](/tools/cipd/android_embedding_bundle).

### My test does not show log output in the console

Import `org.robolectric.shadows.ShadowLog;` then
Use `ShadowLog.stream = System.out;` in your test or setup method.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import static junit.framework.TestCase.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
Expand Down Expand Up @@ -36,7 +37,6 @@
import android.view.DisplayCutout;
import android.view.Surface;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowInsets;
import android.view.WindowManager;
import android.widget.FrameLayout;
Expand Down Expand Up @@ -69,6 +69,7 @@
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import org.robolectric.shadows.ShadowDisplay;
import org.robolectric.shadows.ShadowViewGroup;

@Config(manifest = Config.NONE)
@RunWith(AndroidJUnit4.class)
Expand All @@ -83,6 +84,8 @@ public class FlutterViewTest {
public void setUp() {
MockitoAnnotations.openMocks(this);
when(mockFlutterJni.isAttached()).thenReturn(true);
// Uncomment the following line to enable logging output in test.
// ShadowLog.stream = System.out;
}

@SuppressWarnings("deprecation")
Expand Down Expand Up @@ -937,6 +940,92 @@ public void ViewportMetrics_initializedPhysicalTouchSlop() {
assertFalse(-1 == viewportMetricsCaptor.getValue().physicalTouchSlop);
}

@SuppressWarnings("deprecation")
// Robolectric.setupActivity
// TODO(reidbaker): https://github.com/flutter/flutter/issues/133151
// This test uses the API 30+ Algorithm for window insets. The legacy algorithm is
// set to -1 values, so it is clear if the wrong algorithm is used.
@Test
@TargetApi(30)
@Config(sdk = 30)
public void setPaddingTopToZeroForFullscreenMode() {
FlutterView flutterView = new FlutterView(Robolectric.setupActivity(Activity.class));
FlutterEngine flutterEngine = spy(new FlutterEngine(ctx, mockFlutterLoader, mockFlutterJni));
FlutterRenderer flutterRenderer = spy(new FlutterRenderer(mockFlutterJni));
when(flutterEngine.getRenderer()).thenReturn(flutterRenderer);

// When we attach a new FlutterView to the engine without any system insets, the viewport
// metrics
// default to 0.
flutterView.attachToFlutterEngine(flutterEngine);
ArgumentCaptor<FlutterRenderer.ViewportMetrics> viewportMetricsCaptor =
ArgumentCaptor.forClass(FlutterRenderer.ViewportMetrics.class);
verify(flutterRenderer).setViewportMetrics(viewportMetricsCaptor.capture());
assertEquals(0, viewportMetricsCaptor.getValue().viewPaddingTop);

// Then we simulate the system applying a window inset.
WindowInsets windowInsets =
new WindowInsets.Builder()
.setInsets(
android.view.WindowInsets.Type.navigationBars()
| android.view.WindowInsets.Type.statusBars(),
Insets.of(100, 100, 100, 100))
.build();
flutterView.onApplyWindowInsets(windowInsets);

// Verify.
verify(flutterRenderer, times(3)).setViewportMetrics(viewportMetricsCaptor.capture());
validateViewportMetricPadding(viewportMetricsCaptor, 100, 100, 100, 100);
}

@SuppressWarnings("deprecation")
// Robolectric.setupActivity
// TODO(reidbaker): https://github.com/flutter/flutter/issues/133151
// This test uses the pre-API 30 Algorithm for window insets.
@Test
@TargetApi(28)
@Config(
sdk = 28,
shadows = {
FlutterViewTest.ShadowFullscreenView.class,
})
public void setPaddingTopToZeroForFullscreenModeLegacy() {
FlutterView flutterView = spy(new FlutterView(ctx));
FlutterEngine flutterEngine = spy(new FlutterEngine(ctx, mockFlutterLoader, mockFlutterJni));
FlutterRenderer flutterRenderer = spy(new FlutterRenderer(mockFlutterJni));
when(flutterEngine.getRenderer()).thenReturn(flutterRenderer);

// When we attach a new FlutterView to the engine without any system insets, the viewport
// metrics
// default to 0.
flutterView.attachToFlutterEngine(flutterEngine);
ArgumentCaptor<FlutterRenderer.ViewportMetrics> viewportMetricsCaptor =
ArgumentCaptor.forClass(FlutterRenderer.ViewportMetrics.class);
verify(flutterRenderer).setViewportMetrics(viewportMetricsCaptor.capture());
assertEquals(0, viewportMetricsCaptor.getValue().viewPaddingTop);
clearInvocations(flutterRenderer);
// Then we simulate the system applying a window inset.
WindowInsets windowInsets = mock(WindowInsets.class);
mockSystemWindowInsets(windowInsets, 100, 100, 100, 100);
flutterView.onApplyWindowInsets(windowInsets);

// Verify.
verify(flutterRenderer, times(1)).setViewportMetrics(viewportMetricsCaptor.capture());
validateViewportMetricPadding(viewportMetricsCaptor, 100, 100, 100, 0);
clearInvocations(flutterRenderer);

// Validation when fullscreen
when(flutterView.getWindowSystemUiVisibility()).thenReturn(View.SYSTEM_UI_FLAG_FULLSCREEN);

// Then we simulate the system applying a window inset.
mockSystemWindowInsets(windowInsets, 100, 100, 100, 100);
flutterView.onApplyWindowInsets(windowInsets);

// Verify.
verify(flutterRenderer, times(1)).setViewportMetrics(viewportMetricsCaptor.capture());
validateViewportMetricPadding(viewportMetricsCaptor, 100, 0, 100, 0);
}

@SuppressWarnings("deprecation")
private void setExpectedDisplayRotation(int rotation) {
ShadowDisplay display =
Expand Down Expand Up @@ -976,17 +1065,12 @@ private void mockSystemGestureInsetsIfNeed(WindowInsets windowInsets) {
/*
* A custom shadow that reports fullscreen flag for system UI visibility
*/
@Implements(View.class)
@Implements(FrameLayout.class)
@SuppressWarnings("deprecation")
public static class ShadowFullscreenView {
public static class ShadowFullscreenView extends ShadowViewGroup {
@Implementation
public int getWindowSystemUiVisibility() {
return View.SYSTEM_UI_FLAG_FULLSCREEN;
}
}

// ViewGroup is the first shadow in the type hierarchy for FlutterView. Shadows need to mimic
// production classes' view hierarchy.
@Implements(ViewGroup.class)
public static class ShadowFullscreenViewGroup extends ShadowFullscreenView {}
}

0 comments on commit a8c9c31

Please sign in to comment.