From d8ff243265ad02b5d99024c210baed944344092b Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 12 Jul 2021 16:56:02 -0700 Subject: [PATCH] Fix the firebase scenario app run and assert that it does good things (#27295) --- ci/firebase_testlab.sh | 13 ++++++++++ .../engine/renderer/FlutterRenderer.java | 23 +++++++++++++++++- .../flutter/scenariosui/MemoryLeakTests.java | 2 +- .../scenariosui/PlatformTextureUiTests.java | 24 +++++++++---------- .../scenariosui/PlatformViewUiTests.java | 24 +++++++++---------- .../flutter/scenariosui/SpawnEngineTests.java | 2 +- .../dev/flutter/scenarios/TestActivity.java | 13 +++++----- testing/scenario_app/lib/main.dart | 18 +++++--------- 8 files changed, 73 insertions(+), 46 deletions(-) diff --git a/ci/firebase_testlab.sh b/ci/firebase_testlab.sh index 808035040b..9bd8f10074 100755 --- a/ci/firebase_testlab.sh +++ b/ci/firebase_testlab.sh @@ -33,3 +33,16 @@ gcloud --project flutter-infra firebase test android run \ --results-bucket=gs://flutter_firebase_testlab \ --results-dir="engine_scenario_test/$GIT_REVISION/$BUILD_ID" \ --device model=flame,version=29 + +errors=$(gsutil cat gs://flutter_firebase_testlab/engine_scenario_test/$GIT_REVISION/$BUILD_ID/\*/logcat | grep "[FE]/flutter" | true) +if [[ ! -z $errors ]]; then + echo "Errors detected in logcat:" + echo "$errors" + exit 1 +fi + +result_size=$(gsutil du gs://flutter_firebase_testlab/engine_scenario_test/$GIT_REVISION/$BUILD_ID/\*/game_loop_results/results_scenario_0.json | cut -d " " -f1) +if [[ $result_size == "0" ]]; then + echo "Failed to produce a timeline." + exit 1 +fi diff --git a/shell/platform/android/io/flutter/embedding/engine/renderer/FlutterRenderer.java b/shell/platform/android/io/flutter/embedding/engine/renderer/FlutterRenderer.java index 67570302ba..ce1e4779b1 100644 --- a/shell/platform/android/io/flutter/embedding/engine/renderer/FlutterRenderer.java +++ b/shell/platform/android/io/flutter/embedding/engine/renderer/FlutterRenderer.java @@ -236,8 +236,20 @@ public class FlutterRenderer implements TextureRegistry { isDisplayingFlutterUi = false; } - // TODO(mattcarroll): describe the native behavior that this invokes + /** + * Notifies Flutter that the viewport metrics, e.g. window height and width, have changed. + * + *

If the width, height, or devicePixelRatio are less than or equal to 0, this update is + * ignored. + * + * @param viewportMetrics The metrics to send to the Dart application. + */ public void setViewportMetrics(@NonNull ViewportMetrics viewportMetrics) { + // We might get called with just the DPR if width/height aren't available yet. + // Just ignore, as it will get called again when width/height are set. + if (!viewportMetrics.validate()) { + return; + } Log.v( TAG, "Setting viewport metrics\n" @@ -360,5 +372,14 @@ public class FlutterRenderer implements TextureRegistry { public int systemGestureInsetRight = 0; public int systemGestureInsetBottom = 0; public int systemGestureInsetLeft = 0; + + /** + * Whether this instance contains valid metrics for the Flutter application. + * + * @return True if width, height, and devicePixelRatio are > 0; false otherwise. + */ + boolean validate() { + return width > 0 && height > 0 && devicePixelRatio > 0; + } } } diff --git a/testing/scenario_app/android/app/src/androidTest/java/dev/flutter/scenariosui/MemoryLeakTests.java b/testing/scenario_app/android/app/src/androidTest/java/dev/flutter/scenariosui/MemoryLeakTests.java index 3ec310b5ef..efb41125ad 100644 --- a/testing/scenario_app/android/app/src/androidTest/java/dev/flutter/scenariosui/MemoryLeakTests.java +++ b/testing/scenario_app/android/app/src/androidTest/java/dev/flutter/scenariosui/MemoryLeakTests.java @@ -26,7 +26,7 @@ public class MemoryLeakTests { @FailTestOnLeak public void platformViewHybridComposition_launchActivityFinishAndLaunchAgain() throws Exception { Intent intent = new Intent(Intent.ACTION_MAIN); - intent.putExtra("scenario", "platform_view"); + intent.putExtra("scenario_name", "platform_view"); intent.putExtra("use_android_view", true); activityRule.launchActivity(intent); diff --git a/testing/scenario_app/android/app/src/androidTest/java/dev/flutter/scenariosui/PlatformTextureUiTests.java b/testing/scenario_app/android/app/src/androidTest/java/dev/flutter/scenariosui/PlatformTextureUiTests.java index 2723ed7b79..04a9601701 100644 --- a/testing/scenario_app/android/app/src/androidTest/java/dev/flutter/scenariosui/PlatformTextureUiTests.java +++ b/testing/scenario_app/android/app/src/androidTest/java/dev/flutter/scenariosui/PlatformTextureUiTests.java @@ -33,73 +33,73 @@ public class PlatformTextureUiTests { @Test public void testPlatformView() throws Exception { - intent.putExtra("scenario", "platform_view"); + intent.putExtra("scenario_name", "platform_view"); ScreenshotUtil.capture(activityRule.launchActivity(intent)); } @Test public void testPlatformViewMultiple() throws Exception { - intent.putExtra("scenario", "platform_view_multiple"); + intent.putExtra("scenario_name", "platform_view_multiple"); ScreenshotUtil.capture(activityRule.launchActivity(intent)); } @Test public void testPlatformViewMultipleBackgroundForeground() throws Exception { - intent.putExtra("scenario", "platform_view_multiple_background_foreground"); + intent.putExtra("scenario_name", "platform_view_multiple_background_foreground"); ScreenshotUtil.capture(activityRule.launchActivity(intent)); } @Test public void testPlatformViewCliprect() throws Exception { - intent.putExtra("scenario", "platform_view_cliprect"); + intent.putExtra("scenario_name", "platform_view_cliprect"); ScreenshotUtil.capture(activityRule.launchActivity(intent)); } @Test public void testPlatformViewCliprrect() throws Exception { - intent.putExtra("scenario", "platform_view_cliprrect"); + intent.putExtra("scenario_name", "platform_view_cliprrect"); ScreenshotUtil.capture(activityRule.launchActivity(intent)); } @Test public void testPlatformViewClippath() throws Exception { - intent.putExtra("scenario", "platform_view_clippath"); + intent.putExtra("scenario_name", "platform_view_clippath"); ScreenshotUtil.capture(activityRule.launchActivity(intent)); } @Test public void testPlatformViewTransform() throws Exception { - intent.putExtra("scenario", "platform_view_transform"); + intent.putExtra("scenario_name", "platform_view_transform"); ScreenshotUtil.capture(activityRule.launchActivity(intent)); } @Test public void testPlatformViewOpacity() throws Exception { - intent.putExtra("scenario", "platform_view_opacity"); + intent.putExtra("scenario_name", "platform_view_opacity"); ScreenshotUtil.capture(activityRule.launchActivity(intent)); } @Test public void testPlatformViewRotate() throws Exception { - intent.putExtra("scenario", "platform_view_rotate"); + intent.putExtra("scenario_name", "platform_view_rotate"); ScreenshotUtil.capture(activityRule.launchActivity(intent)); } @Test public void testPlatformViewMultipleWithoutOverlays() throws Exception { - intent.putExtra("scenario", "platform_view_multiple_without_overlays"); + intent.putExtra("scenario_name", "platform_view_multiple_without_overlays"); ScreenshotUtil.capture(activityRule.launchActivity(intent)); } @Test public void testPlatformViewTwoIntersectingOverlays() throws Exception { - intent.putExtra("scenario", "platform_view_two_intersecting_overlays"); + intent.putExtra("scenario_name", "platform_view_two_intersecting_overlays"); ScreenshotUtil.capture(activityRule.launchActivity(intent)); } @Test public void testPlatformViewWithoutOverlayIntersection() throws Exception { - intent.putExtra("scenario", "platform_view_no_overlay_intersection"); + intent.putExtra("scenario_name", "platform_view_no_overlay_intersection"); ScreenshotUtil.capture(activityRule.launchActivity(intent)); } } diff --git a/testing/scenario_app/android/app/src/androidTest/java/dev/flutter/scenariosui/PlatformViewUiTests.java b/testing/scenario_app/android/app/src/androidTest/java/dev/flutter/scenariosui/PlatformViewUiTests.java index 63b8667795..0d81e50ade 100644 --- a/testing/scenario_app/android/app/src/androidTest/java/dev/flutter/scenariosui/PlatformViewUiTests.java +++ b/testing/scenario_app/android/app/src/androidTest/java/dev/flutter/scenariosui/PlatformViewUiTests.java @@ -33,73 +33,73 @@ public class PlatformViewUiTests { @Test public void testPlatformView() throws Exception { - intent.putExtra("scenario", "platform_view"); + intent.putExtra("scenario_name", "platform_view"); ScreenshotUtil.capture(activityRule.launchActivity(intent)); } @Test public void testPlatformViewMultiple() throws Exception { - intent.putExtra("scenario", "platform_view_multiple"); + intent.putExtra("scenario_name", "platform_view_multiple"); ScreenshotUtil.capture(activityRule.launchActivity(intent)); } @Test public void testPlatformViewMultipleBackgroundForeground() throws Exception { - intent.putExtra("scenario", "platform_view_multiple_background_foreground"); + intent.putExtra("scenario_name", "platform_view_multiple_background_foreground"); ScreenshotUtil.capture(activityRule.launchActivity(intent)); } @Test public void testPlatformViewCliprect() throws Exception { - intent.putExtra("scenario", "platform_view_cliprect"); + intent.putExtra("scenario_name", "platform_view_cliprect"); ScreenshotUtil.capture(activityRule.launchActivity(intent)); } @Test public void testPlatformViewCliprrect() throws Exception { - intent.putExtra("scenario", "platform_view_cliprrect"); + intent.putExtra("scenario_name", "platform_view_cliprrect"); ScreenshotUtil.capture(activityRule.launchActivity(intent)); } @Test public void testPlatformViewClippath() throws Exception { - intent.putExtra("scenario", "platform_view_clippath"); + intent.putExtra("scenario_name", "platform_view_clippath"); ScreenshotUtil.capture(activityRule.launchActivity(intent)); } @Test public void testPlatformViewTransform() throws Exception { - intent.putExtra("scenario", "platform_view_transform"); + intent.putExtra("scenario_name", "platform_view_transform"); ScreenshotUtil.capture(activityRule.launchActivity(intent)); } @Test public void testPlatformViewOpacity() throws Exception { - intent.putExtra("scenario", "platform_view_opacity"); + intent.putExtra("scenario_name", "platform_view_opacity"); ScreenshotUtil.capture(activityRule.launchActivity(intent)); } @Test public void testPlatformViewRotate() throws Exception { - intent.putExtra("scenario", "platform_view_rotate"); + intent.putExtra("scenario_name", "platform_view_rotate"); ScreenshotUtil.capture(activityRule.launchActivity(intent)); } @Test public void testPlatformViewMultipleWithoutOverlays() throws Exception { - intent.putExtra("scenario", "platform_view_multiple_without_overlays"); + intent.putExtra("scenario_name", "platform_view_multiple_without_overlays"); ScreenshotUtil.capture(activityRule.launchActivity(intent)); } @Test public void testPlatformViewTwoIntersectingOverlays() throws Exception { - intent.putExtra("scenario", "platform_view_two_intersecting_overlays"); + intent.putExtra("scenario_name", "platform_view_two_intersecting_overlays"); ScreenshotUtil.capture(activityRule.launchActivity(intent)); } @Test public void testPlatformViewWithoutOverlayIntersection() throws Exception { - intent.putExtra("scenario", "platform_view_no_overlay_intersection"); + intent.putExtra("scenario_name", "platform_view_no_overlay_intersection"); ScreenshotUtil.capture(activityRule.launchActivity(intent)); } } diff --git a/testing/scenario_app/android/app/src/androidTest/java/dev/flutter/scenariosui/SpawnEngineTests.java b/testing/scenario_app/android/app/src/androidTest/java/dev/flutter/scenariosui/SpawnEngineTests.java index 96f91337a0..717ec3940a 100644 --- a/testing/scenario_app/android/app/src/androidTest/java/dev/flutter/scenariosui/SpawnEngineTests.java +++ b/testing/scenario_app/android/app/src/androidTest/java/dev/flutter/scenariosui/SpawnEngineTests.java @@ -31,7 +31,7 @@ public class SpawnEngineTests { @Test public void testSpawnedEngine() throws Exception { - intent.putExtra("scenario", "spawn_engine_works"); + intent.putExtra("scenario_name", "spawn_engine_works"); ScreenshotUtil.capture(activityRule.launchActivity(intent)); } } diff --git a/testing/scenario_app/android/app/src/main/java/dev/flutter/scenarios/TestActivity.java b/testing/scenario_app/android/app/src/main/java/dev/flutter/scenarios/TestActivity.java index 6abd080c1b..c6e810f320 100644 --- a/testing/scenario_app/android/app/src/main/java/dev/flutter/scenarios/TestActivity.java +++ b/testing/scenario_app/android/app/src/main/java/dev/flutter/scenarios/TestActivity.java @@ -39,7 +39,6 @@ public class TestActivity extends TestableFlutterActivity { if (Build.VERSION.SDK_INT > 22) { requestPermissions(new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1); } - // Run for one minute, get the timeline data, write it, and finish. final Uri logFileUri = launchIntent.getData(); new Handler() .postDelayed( @@ -47,7 +46,6 @@ public class TestActivity extends TestableFlutterActivity { @Override public void run() { writeTimelineData(logFileUri); - testFlutterLoaderCallbackWhenInitializedTwice(); } }, @@ -70,13 +68,14 @@ public class TestActivity extends TestableFlutterActivity { @Override public void onFlutterUiDisplayed() { final Intent launchIntent = getIntent(); - if (!launchIntent.hasExtra("scenario")) { - return; - } MethodChannel channel = new MethodChannel(getFlutterEngine().getDartExecutor(), "driver", JSONMethodCodec.INSTANCE); Map test = new HashMap<>(2); - test.put("name", launchIntent.getStringExtra("scenario")); + if (launchIntent.hasExtra("scenario_name")) { + test.put("name", launchIntent.getStringExtra("scenario_name")); + } else { + test.put("name", "animated_color_square"); + } test.put("use_android_view", launchIntent.getBooleanExtra("use_android_view", false)); channel.invokeMethod("set_scenario", test); } @@ -102,7 +101,7 @@ public class TestActivity extends TestableFlutterActivity { outputStream.write(reply.array()); outputStream.close(); } catch (IOException ex) { - Log.e(TAG, "Could not write timeline file: " + ex.toString()); + Log.e(TAG, "Could not write timeline file", ex); } finish(); }); diff --git a/testing/scenario_app/lib/main.dart b/testing/scenario_app/lib/main.dart index f1f23f6fb6..6cde43d198 100644 --- a/testing/scenario_app/lib/main.dart +++ b/testing/scenario_app/lib/main.dart @@ -6,7 +6,6 @@ import 'dart:convert'; import 'dart:developer' as developer; import 'dart:io'; -import 'dart:isolate'; import 'dart:typed_data'; import 'dart:ui'; @@ -41,7 +40,11 @@ void _handleDriverMessage(Map call) { Future _handlePlatformMessage( String name, ByteData data, PlatformMessageResponseCallback callback) async { - print('$name = ${utf8.decode(data.buffer.asUint8List())}'); + if (data != null) { + print('$name = ${utf8.decode(data.buffer.asUint8List())}'); + } else { + print(name); + } switch (name) { case 'driver': @@ -57,21 +60,12 @@ Future _handlePlatformMessage( } Future _getTimelineData() async { - final String isolateId = developer.Service.getIsolateID(Isolate.current); final developer.ServiceProtocolInfo info = await developer.Service.getInfo(); - final Uri cpuProfileTimelineUri = info.serverUri.resolve( - '_getCpuProfileTimeline?tags=None&isolateId=$isolateId', - ); final Uri vmServiceTimelineUri = info.serverUri.resolve('getVMTimeline'); - final Map cpuTimelineJson = await _getJson(cpuProfileTimelineUri); final Map vmServiceTimelineJson = await _getJson(vmServiceTimelineUri); - final Map cpuResult = cpuTimelineJson['result'] as Map; final Map vmServiceResult = vmServiceTimelineJson['result'] as Map; - return json.encode({ - 'stackFrames': cpuResult['stackFrames'], 'traceEvents': [ - ...cpuResult['traceEvents'] as List, ...vmServiceResult['traceEvents'] as List, ], }); @@ -82,7 +76,7 @@ Future> _getJson(Uri uri) async { final HttpClientRequest request = await client.getUrl(uri); final HttpClientResponse response = await request.close(); if (response.statusCode > 299) { - return null; + return {}; } final String data = await utf8.decodeStream(response); return json.decode(data) as Map; -- GitLab