From e89b1513524901271fb134bb4fe7085348db96fa Mon Sep 17 00:00:00 2001
From: gaaclarke <30870216+gaaclarke@users.noreply.github.com>
Date: Tue, 9 Feb 2021 09:46:11 -0800
Subject: [PATCH] Added memory benchmark for flutter engine groups. (#75374)
---
.../multiple_flutters/android/.gitignore | 15 ++
.../multiple_flutters/android/app/.gitignore | 1 +
.../android/app/build.gradle | 54 ++++++
.../android/app/proguard-rules.pro | 21 +++
.../android/app/src/main/AndroidManifest.xml | 26 +++
.../java/dev/flutter/multipleflutters/App.kt | 22 +++
.../flutter/multipleflutters/MainActivity.kt | 75 ++++++++
.../drawable-v24/ic_launcher_foreground.xml | 34 ++++
.../res/drawable/ic_launcher_background.xml | 173 ++++++++++++++++++
.../app/src/main/res/values-night/themes.xml | 20 ++
.../app/src/main/res/values/colors.xml | 13 ++
.../app/src/main/res/values/strings.xml | 7 +
.../app/src/main/res/values/themes.xml | 20 ++
.../multiple_flutters/android/build.gradle | 30 +++
.../android/gradle.properties | 21 +++
.../gradle/wrapper/gradle-wrapper.properties | 6 +
.../multiple_flutters/android/settings.gradle | 11 ++
.../multiple_flutters/module/.gitignore | 48 +++++
.../multiple_flutters/module/.metadata | 10 +
.../multiple_flutters/module/lib/main.dart | 71 +++++++
.../multiple_flutters/module/pubspec.yaml | 29 +++
.../flutter_engine_group_performance.dart | 87 +++++++++
22 files changed, 794 insertions(+)
create mode 100644 dev/benchmarks/multiple_flutters/android/.gitignore
create mode 100644 dev/benchmarks/multiple_flutters/android/app/.gitignore
create mode 100644 dev/benchmarks/multiple_flutters/android/app/build.gradle
create mode 100644 dev/benchmarks/multiple_flutters/android/app/proguard-rules.pro
create mode 100644 dev/benchmarks/multiple_flutters/android/app/src/main/AndroidManifest.xml
create mode 100644 dev/benchmarks/multiple_flutters/android/app/src/main/java/dev/flutter/multipleflutters/App.kt
create mode 100644 dev/benchmarks/multiple_flutters/android/app/src/main/java/dev/flutter/multipleflutters/MainActivity.kt
create mode 100644 dev/benchmarks/multiple_flutters/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
create mode 100644 dev/benchmarks/multiple_flutters/android/app/src/main/res/drawable/ic_launcher_background.xml
create mode 100644 dev/benchmarks/multiple_flutters/android/app/src/main/res/values-night/themes.xml
create mode 100644 dev/benchmarks/multiple_flutters/android/app/src/main/res/values/colors.xml
create mode 100644 dev/benchmarks/multiple_flutters/android/app/src/main/res/values/strings.xml
create mode 100644 dev/benchmarks/multiple_flutters/android/app/src/main/res/values/themes.xml
create mode 100644 dev/benchmarks/multiple_flutters/android/build.gradle
create mode 100644 dev/benchmarks/multiple_flutters/android/gradle.properties
create mode 100644 dev/benchmarks/multiple_flutters/android/gradle/wrapper/gradle-wrapper.properties
create mode 100644 dev/benchmarks/multiple_flutters/android/settings.gradle
create mode 100644 dev/benchmarks/multiple_flutters/module/.gitignore
create mode 100644 dev/benchmarks/multiple_flutters/module/.metadata
create mode 100644 dev/benchmarks/multiple_flutters/module/lib/main.dart
create mode 100644 dev/benchmarks/multiple_flutters/module/pubspec.yaml
create mode 100644 dev/devicelab/bin/tasks/flutter_engine_group_performance.dart
diff --git a/dev/benchmarks/multiple_flutters/android/.gitignore b/dev/benchmarks/multiple_flutters/android/.gitignore
new file mode 100644
index 0000000000..aa724b7707
--- /dev/null
+++ b/dev/benchmarks/multiple_flutters/android/.gitignore
@@ -0,0 +1,15 @@
+*.iml
+.gradle
+/local.properties
+/.idea/caches
+/.idea/libraries
+/.idea/modules.xml
+/.idea/workspace.xml
+/.idea/navEditor.xml
+/.idea/assetWizardSettings.xml
+.DS_Store
+/build
+/captures
+.externalNativeBuild
+.cxx
+local.properties
diff --git a/dev/benchmarks/multiple_flutters/android/app/.gitignore b/dev/benchmarks/multiple_flutters/android/app/.gitignore
new file mode 100644
index 0000000000..42afabfd2a
--- /dev/null
+++ b/dev/benchmarks/multiple_flutters/android/app/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/dev/benchmarks/multiple_flutters/android/app/build.gradle b/dev/benchmarks/multiple_flutters/android/app/build.gradle
new file mode 100644
index 0000000000..c3166e2e2f
--- /dev/null
+++ b/dev/benchmarks/multiple_flutters/android/app/build.gradle
@@ -0,0 +1,54 @@
+// Copyright 2014 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+plugins {
+ id 'com.android.application'
+ id 'kotlin-android'
+}
+
+android {
+ signingConfigs {
+ self {
+ }
+ }
+ compileSdkVersion 30
+
+ defaultConfig {
+ applicationId "dev.flutter.multipleflutters"
+ minSdkVersion 24
+ targetSdkVersion 30
+ versionCode 1
+ versionName "1.0"
+
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ signingConfig debug.signingConfig
+ }
+ }
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+ kotlinOptions {
+ jvmTarget = '1.8'
+ }
+}
+
+dependencies {
+
+ implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
+ implementation 'androidx.core:core-ktx:1.2.0'
+ implementation 'androidx.appcompat:appcompat:1.1.0'
+ implementation 'com.google.android.material:material:1.1.0'
+ implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
+ testImplementation 'junit:junit:4.+'
+ androidTestImplementation 'androidx.test.ext:junit:1.1.1'
+ androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
+ implementation project(':flutter')
+}
\ No newline at end of file
diff --git a/dev/benchmarks/multiple_flutters/android/app/proguard-rules.pro b/dev/benchmarks/multiple_flutters/android/app/proguard-rules.pro
new file mode 100644
index 0000000000..481bb43481
--- /dev/null
+++ b/dev/benchmarks/multiple_flutters/android/app/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
\ No newline at end of file
diff --git a/dev/benchmarks/multiple_flutters/android/app/src/main/AndroidManifest.xml b/dev/benchmarks/multiple_flutters/android/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000000..ccec715e40
--- /dev/null
+++ b/dev/benchmarks/multiple_flutters/android/app/src/main/AndroidManifest.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/dev/benchmarks/multiple_flutters/android/app/src/main/java/dev/flutter/multipleflutters/App.kt b/dev/benchmarks/multiple_flutters/android/app/src/main/java/dev/flutter/multipleflutters/App.kt
new file mode 100644
index 0000000000..cd13fc4f2e
--- /dev/null
+++ b/dev/benchmarks/multiple_flutters/android/app/src/main/java/dev/flutter/multipleflutters/App.kt
@@ -0,0 +1,22 @@
+// Copyright 2014 The Flutter 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 dev.flutter.multipleflutters
+
+import android.app.Application
+import io.flutter.embedding.engine.FlutterEngineGroup
+
+/**
+ * Application class for this app.
+ *
+ * This holds onto our engine group.
+ */
+class App : Application() {
+ lateinit var engines: FlutterEngineGroup
+
+ override fun onCreate() {
+ super.onCreate()
+ engines = FlutterEngineGroup(this)
+ }
+}
diff --git a/dev/benchmarks/multiple_flutters/android/app/src/main/java/dev/flutter/multipleflutters/MainActivity.kt b/dev/benchmarks/multiple_flutters/android/app/src/main/java/dev/flutter/multipleflutters/MainActivity.kt
new file mode 100644
index 0000000000..374bdf2f94
--- /dev/null
+++ b/dev/benchmarks/multiple_flutters/android/app/src/main/java/dev/flutter/multipleflutters/MainActivity.kt
@@ -0,0 +1,75 @@
+// Copyright 2014 The Flutter 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 dev.flutter.multipleflutters
+
+import android.content.Intent
+import androidx.appcompat.app.AppCompatActivity
+import android.os.Bundle
+import android.view.View
+import android.widget.FrameLayout
+import android.widget.LinearLayout
+import android.widget.TextView
+import androidx.fragment.app.FragmentActivity
+import androidx.fragment.app.FragmentManager
+import io.flutter.FlutterInjector
+import io.flutter.embedding.android.FlutterFragment
+import io.flutter.embedding.engine.FlutterEngineCache
+import io.flutter.embedding.engine.dart.DartExecutor
+
+class MainActivity : FragmentActivity() {
+ private val numberOfFlutters = 2
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ val root = LinearLayout(this)
+ root.layoutParams = LinearLayout.LayoutParams(
+ LinearLayout.LayoutParams.MATCH_PARENT,
+ LinearLayout.LayoutParams.MATCH_PARENT
+ )
+ root.orientation = LinearLayout.VERTICAL
+ root.weightSum = numberOfFlutters.toFloat()
+
+ val fragmentManager: FragmentManager = supportFragmentManager
+
+ setContentView(root)
+
+ val app = applicationContext as App
+ val dartEntrypoint =
+ DartExecutor.DartEntrypoint(
+ FlutterInjector.instance().flutterLoader().findAppBundlePath(), "main"
+ )
+ val topEngine = app.engines.createAndRunEngine(this, dartEntrypoint)
+ val bottomEngine = app.engines.createAndRunEngine(this, dartEntrypoint)
+ for (i in 0 until numberOfFlutters) {
+ val flutterContainer = FrameLayout(this)
+ root.addView(flutterContainer)
+ flutterContainer.id = 12345 + i
+ flutterContainer.layoutParams = LinearLayout.LayoutParams(
+ FrameLayout.LayoutParams.MATCH_PARENT,
+ FrameLayout.LayoutParams.MATCH_PARENT,
+ 1.0f
+ )
+ val engine = if (i == 0) topEngine else bottomEngine
+ FlutterEngineCache.getInstance().put(i.toString(), engine)
+ val flutterFragment =
+ FlutterFragment.withCachedEngine(i.toString()).build()
+ fragmentManager
+ .beginTransaction()
+ .add(
+ 12345 + i,
+ flutterFragment
+ )
+ .commit()
+ }
+ }
+
+ override fun onDestroy() {
+ for (i in 0 until numberOfFlutters) {
+ FlutterEngineCache.getInstance().remove(i.toString())
+ }
+
+ super.onDestroy()
+ }
+}
diff --git a/dev/benchmarks/multiple_flutters/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/dev/benchmarks/multiple_flutters/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
new file mode 100644
index 0000000000..39557594a9
--- /dev/null
+++ b/dev/benchmarks/multiple_flutters/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/dev/benchmarks/multiple_flutters/android/app/src/main/res/drawable/ic_launcher_background.xml b/dev/benchmarks/multiple_flutters/android/app/src/main/res/drawable/ic_launcher_background.xml
new file mode 100644
index 0000000000..d8d9777331
--- /dev/null
+++ b/dev/benchmarks/multiple_flutters/android/app/src/main/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,173 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/dev/benchmarks/multiple_flutters/android/app/src/main/res/values-night/themes.xml b/dev/benchmarks/multiple_flutters/android/app/src/main/res/values-night/themes.xml
new file mode 100644
index 0000000000..0a36411f72
--- /dev/null
+++ b/dev/benchmarks/multiple_flutters/android/app/src/main/res/values-night/themes.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/dev/benchmarks/multiple_flutters/android/app/src/main/res/values/colors.xml b/dev/benchmarks/multiple_flutters/android/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000000..5a297dbb61
--- /dev/null
+++ b/dev/benchmarks/multiple_flutters/android/app/src/main/res/values/colors.xml
@@ -0,0 +1,13 @@
+
+
+
+ #FFBB86FC
+ #FF6200EE
+ #FF3700B3
+ #FF03DAC5
+ #FF018786
+ #FF000000
+ #FFFFFFFF
+
\ No newline at end of file
diff --git a/dev/benchmarks/multiple_flutters/android/app/src/main/res/values/strings.xml b/dev/benchmarks/multiple_flutters/android/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000000..4af3827607
--- /dev/null
+++ b/dev/benchmarks/multiple_flutters/android/app/src/main/res/values/strings.xml
@@ -0,0 +1,7 @@
+
+
+
+ Multiple Flutters
+
\ No newline at end of file
diff --git a/dev/benchmarks/multiple_flutters/android/app/src/main/res/values/themes.xml b/dev/benchmarks/multiple_flutters/android/app/src/main/res/values/themes.xml
new file mode 100644
index 0000000000..db959bf88d
--- /dev/null
+++ b/dev/benchmarks/multiple_flutters/android/app/src/main/res/values/themes.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/dev/benchmarks/multiple_flutters/android/build.gradle b/dev/benchmarks/multiple_flutters/android/build.gradle
new file mode 100644
index 0000000000..2bf4a9184f
--- /dev/null
+++ b/dev/benchmarks/multiple_flutters/android/build.gradle
@@ -0,0 +1,30 @@
+// Copyright 2014 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+buildscript {
+ ext.kotlin_version = "1.3.72"
+ repositories {
+ google()
+ jcenter()
+ }
+ dependencies {
+ classpath "com.android.tools.build:gradle:4.1.2"
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+
+ // NOTE: Do not place your application dependencies here; they belong
+ // in the individual module build.gradle files
+ }
+}
+
+allprojects {
+ repositories {
+ google()
+ jcenter()
+ }
+}
+
+task clean(type: Delete) {
+ delete rootProject.buildDir
+}
\ No newline at end of file
diff --git a/dev/benchmarks/multiple_flutters/android/gradle.properties b/dev/benchmarks/multiple_flutters/android/gradle.properties
new file mode 100644
index 0000000000..98bed167dc
--- /dev/null
+++ b/dev/benchmarks/multiple_flutters/android/gradle.properties
@@ -0,0 +1,21 @@
+# Project-wide Gradle settings.
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
+# AndroidX package structure to make it clearer which packages are bundled with the
+# Android operating system, and which are packaged with your app"s APK
+# https://developer.android.com/topic/libraries/support-library/androidx-rn
+android.useAndroidX=true
+# Automatically convert third-party libraries to use AndroidX
+android.enableJetifier=true
+# Kotlin code style for this project: "official" or "obsolete":
+kotlin.code.style=official
\ No newline at end of file
diff --git a/dev/benchmarks/multiple_flutters/android/gradle/wrapper/gradle-wrapper.properties b/dev/benchmarks/multiple_flutters/android/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000000..b9e13077bc
--- /dev/null
+++ b/dev/benchmarks/multiple_flutters/android/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Jan 27 11:54:04 PST 2021
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip
diff --git a/dev/benchmarks/multiple_flutters/android/settings.gradle b/dev/benchmarks/multiple_flutters/android/settings.gradle
new file mode 100644
index 0000000000..cddcd9ce67
--- /dev/null
+++ b/dev/benchmarks/multiple_flutters/android/settings.gradle
@@ -0,0 +1,11 @@
+// Copyright 2014 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+include ':app'
+rootProject.name = "Multiple Flutters"
+setBinding(new Binding([gradle: this])) // new
+evaluate(new File( // new
+ settingsDir.parentFile, // new
+ './module/.android/include_flutter.groovy' // new
+))
\ No newline at end of file
diff --git a/dev/benchmarks/multiple_flutters/module/.gitignore b/dev/benchmarks/multiple_flutters/module/.gitignore
new file mode 100644
index 0000000000..ff612b3be4
--- /dev/null
+++ b/dev/benchmarks/multiple_flutters/module/.gitignore
@@ -0,0 +1,48 @@
+.DS_Store
+.dart_tool/
+
+.packages
+.pub/
+
+.idea/
+.vagrant/
+.sconsign.dblite
+.svn/
+
+*.swp
+profile
+
+DerivedData/
+
+.generated/
+
+*.pbxuser
+*.mode1v3
+*.mode2v3
+*.perspectivev3
+
+!default.pbxuser
+!default.mode1v3
+!default.mode2v3
+!default.perspectivev3
+
+xcuserdata
+
+*.moved-aside
+
+*.pyc
+*sync/
+Icon?
+.tags*
+
+build/
+.android/
+.ios/
+.flutter-plugins
+.flutter-plugins-dependencies
+
+# Symbolication related
+app.*.symbols
+
+# Obfuscation related
+app.*.map.json
diff --git a/dev/benchmarks/multiple_flutters/module/.metadata b/dev/benchmarks/multiple_flutters/module/.metadata
new file mode 100644
index 0000000000..bdc27cb22d
--- /dev/null
+++ b/dev/benchmarks/multiple_flutters/module/.metadata
@@ -0,0 +1,10 @@
+# This file tracks properties of this Flutter project.
+# Used by Flutter tool to assess capabilities and perform upgrades etc.
+#
+# This file should be version controlled and should not be manually edited.
+
+version:
+ revision: 1d3f6971600f6e3fb144a30fab2b889e34af0c22
+ channel: master
+
+project_type: module
diff --git a/dev/benchmarks/multiple_flutters/module/lib/main.dart b/dev/benchmarks/multiple_flutters/module/lib/main.dart
new file mode 100644
index 0000000000..6b77189f9f
--- /dev/null
+++ b/dev/benchmarks/multiple_flutters/module/lib/main.dart
@@ -0,0 +1,71 @@
+// Copyright 2014 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'package:flutter/material.dart';
+
+void main() => runApp(const MyApp(Colors.blue));
+
+@pragma('vm:entry-point')
+void topMain() => runApp(const MyApp(Colors.green));
+
+@pragma('vm:entry-point')
+void bottomMain() => runApp(const MyApp(Colors.purple));
+
+class MyApp extends StatelessWidget {
+ const MyApp(this.color);
+
+ final Color color;
+
+ @override
+ Widget build(BuildContext context) {
+ return MaterialApp(
+ title: 'Flutter Demo',
+ theme: ThemeData(
+ primarySwatch: color as MaterialColor,
+ ),
+ home: const MyHomePage(title: 'Flutter Demo Home Page'),
+ );
+ }
+}
+
+class MyHomePage extends StatefulWidget {
+ const MyHomePage({Key key, this.title}) : super(key: key);
+ final String title;
+
+ @override
+ _MyHomePageState createState() => _MyHomePageState();
+}
+
+class _MyHomePageState extends State {
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ appBar: AppBar(
+ title: Text(widget.title),
+ ),
+ body: Center(
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ const Text(
+ 'You have pushed the button this many times:',
+ ),
+ Text(
+ '0',
+ style: Theme.of(context).textTheme.headline4,
+ ),
+ TextButton(
+ onPressed: () {},
+ child: const Text('Add'),
+ ),
+ TextButton(
+ onPressed: () {},
+ child: const Text('Next'),
+ ),
+ ],
+ ),
+ ),
+ );
+ }
+}
diff --git a/dev/benchmarks/multiple_flutters/module/pubspec.yaml b/dev/benchmarks/multiple_flutters/module/pubspec.yaml
new file mode 100644
index 0000000000..8175300985
--- /dev/null
+++ b/dev/benchmarks/multiple_flutters/module/pubspec.yaml
@@ -0,0 +1,29 @@
+name: multiple_flutters_module
+description: A module that is embedded in the multiple_flutters benchmark test.
+
+version: 1.0.0+1
+
+environment:
+ sdk: '>=2.8.1 <3.0.0'
+
+dependencies:
+ flutter:
+ sdk: flutter
+
+ cupertino_icons: 1.0.2
+
+ characters: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ collection: 1.15.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ meta: 1.3.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ typed_data: 1.3.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ vector_math: 2.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+
+flutter:
+ uses-material-design: true
+
+ module:
+ androidX: true
+ androidPackage: com.example.multiple_flutters_module
+ iosBundleIdentifier: com.example.multipleFluttersModule
+
+# PUBSPEC CHECKSUM: 6f0e
diff --git a/dev/devicelab/bin/tasks/flutter_engine_group_performance.dart b/dev/devicelab/bin/tasks/flutter_engine_group_performance.dart
new file mode 100644
index 0000000000..a916e1fb6c
--- /dev/null
+++ b/dev/devicelab/bin/tasks/flutter_engine_group_performance.dart
@@ -0,0 +1,87 @@
+// Copyright 2014 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:flutter_devicelab/framework/adb.dart';
+import 'package:flutter_devicelab/framework/framework.dart';
+import 'package:flutter_devicelab/framework/task_result.dart';
+import 'package:flutter_devicelab/framework/utils.dart' as utils;
+import 'package:flutter_devicelab/tasks/perf_tests.dart' show ListStatistics;
+import 'package:path/path.dart' as path;
+
+const String _bundleName = 'dev.flutter.multipleflutters';
+const String _activityName = 'MainActivity';
+const int _numberOfIterations = 10;
+
+Future _withApkInstall(
+ String apkPath, String bundleName, Function(AndroidDevice) body) async {
+ final DeviceDiscovery devices = DeviceDiscovery();
+ final AndroidDevice device = await devices.workingDevice as AndroidDevice;
+ await device.unlock();
+ await device.adb(['install', '-r', apkPath]);
+ try {
+ await body(device);
+ } finally {
+ await device.adb(['uninstall', bundleName]);
+ }
+}
+
+Future _doTest() async {
+ try {
+ final String flutterDirectory = utils.flutterDirectory.path;
+ final String multipleFluttersPath =
+ path.join(flutterDirectory, 'dev', 'benchmarks', 'multiple_flutters');
+ final String modulePath = path.join(multipleFluttersPath, 'module');
+ final String androidPath = path.join(multipleFluttersPath, 'android');
+
+ final String gradlew = Platform.isWindows ? 'gradlew.bat' : 'gradlew';
+ final String gradlewExecutable =
+ Platform.isWindows ? '.\\$gradlew' : './$gradlew';
+ final String flutterPath = path.join(flutterDirectory, 'bin', 'flutter');
+ await utils.eval(flutterPath, ['pub', 'get'],
+ workingDirectory: modulePath);
+ await utils.eval(gradlewExecutable, ['assembleRelease'],
+ workingDirectory: androidPath);
+
+ final String apkPath = path.join(multipleFluttersPath, 'android', 'app',
+ 'build', 'outputs', 'apk', 'release', 'app-release.apk');
+
+ TaskResult result;
+ await _withApkInstall(apkPath, _bundleName, (AndroidDevice device) async {
+ final List totalMemorySamples = [];
+ for (int i = 0; i < _numberOfIterations; ++i) {
+ await device.adb([
+ 'shell',
+ 'am',
+ 'start',
+ '-n',
+ '$_bundleName/$_bundleName.$_activityName'
+ ]);
+ await Future.delayed(const Duration(seconds: 10));
+ final Map memoryStats =
+ await device.getMemoryStats(_bundleName);
+ final int totalMemory = memoryStats['total_kb'] as int;
+ totalMemorySamples.add(totalMemory);
+ await device.stop(_bundleName);
+ }
+ final ListStatistics totalMemoryStatistics =
+ ListStatistics(totalMemorySamples);
+
+ final Map results = {
+ ...totalMemoryStatistics.asMap('totalMemory')
+ };
+ result = TaskResult.success(results,
+ benchmarkScoreKeys: results.keys.toList());
+ });
+
+ return result ?? TaskResult.failure('no results found');
+ } catch (ex) {
+ return TaskResult.failure(ex.toString());
+ }
+}
+
+Future main() async {
+ task(_doTest);
+}