[device_info]  Support v2 android embedding. (#2163)

diff --git a/packages/device_info/CHANGELOG.md b/packages/device_info/CHANGELOG.md
index 62d4960..1fff8c7 100644
--- a/packages/device_info/CHANGELOG.md
+++ b/packages/device_info/CHANGELOG.md
@@ -1,3 +1,11 @@
+## 0.4.1
+
+* Support the v2 Android embedding.
+* Update to AndroidX.
+* Migrate to using the new e2e test binding.
+* Add a e2e test.
+
+
 ## 0.4.0+4
 
 * Define clang module for iOS.
diff --git a/packages/device_info/android/build.gradle b/packages/device_info/android/build.gradle
index df08280..7dfea2d 100644
--- a/packages/device_info/android/build.gradle
+++ b/packages/device_info/android/build.gradle
@@ -45,3 +45,29 @@
         disable 'InvalidPackage'
     }
 }
+
+// TODO(cyanglaz): Remove this hack once androidx.lifecycle is included on stable. https://github.com/flutter/flutter/issues/42348
+afterEvaluate {
+    def containsEmbeddingDependencies = false
+    for (def configuration : configurations.all) {
+        for (def dependency : configuration.dependencies) {
+            if (dependency.group == 'io.flutter' &&
+                dependency.name.startsWith('flutter_embedding') &&
+                dependency.isTransitive())
+            {
+                containsEmbeddingDependencies = true
+                break
+            }
+        }
+    }
+    if (!containsEmbeddingDependencies) {
+        android {
+            dependencies {
+                def lifecycle_version = "1.1.1"
+                api "android.arch.lifecycle:runtime:$lifecycle_version"
+                api "android.arch.lifecycle:common:$lifecycle_version"
+                api "android.arch.lifecycle:common-java8:$lifecycle_version"
+            }
+        }
+    }
+}
diff --git a/packages/device_info/android/src/main/java/io/flutter/plugins/deviceinfo/DeviceInfoPlugin.java b/packages/device_info/android/src/main/java/io/flutter/plugins/deviceinfo/DeviceInfoPlugin.java
index a22009f..8ad0f5d 100644
--- a/packages/device_info/android/src/main/java/io/flutter/plugins/deviceinfo/DeviceInfoPlugin.java
+++ b/packages/device_info/android/src/main/java/io/flutter/plugins/deviceinfo/DeviceInfoPlugin.java
@@ -4,120 +4,43 @@
 
 package io.flutter.plugins.deviceinfo;
 
-import android.annotation.SuppressLint;
-import android.content.Context;
-import android.os.Build;
-import android.os.Build.VERSION;
-import android.os.Build.VERSION_CODES;
-import android.provider.Settings;
-import io.flutter.plugin.common.MethodCall;
+import android.content.ContentResolver;
+import io.flutter.embedding.engine.plugins.FlutterPlugin;
+import io.flutter.plugin.common.BinaryMessenger;
 import io.flutter.plugin.common.MethodChannel;
-import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
-import io.flutter.plugin.common.MethodChannel.Result;
 import io.flutter.plugin.common.PluginRegistry.Registrar;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Map;
 
 /** DeviceInfoPlugin */
-public class DeviceInfoPlugin implements MethodCallHandler {
-  private final Context context;
+public class DeviceInfoPlugin implements FlutterPlugin {
 
-  /** Substitute for missing values. */
-  private static final String[] EMPTY_STRING_LIST = new String[] {};
+  MethodChannel channel;
 
   /** Plugin registration. */
   public static void registerWith(Registrar registrar) {
-    final MethodChannel channel =
-        new MethodChannel(registrar.messenger(), "plugins.flutter.io/device_info");
-    channel.setMethodCallHandler(new DeviceInfoPlugin(registrar.context()));
-  }
-
-  /** Do not allow direct instantiation. */
-  private DeviceInfoPlugin(Context context) {
-    this.context = context;
+    DeviceInfoPlugin plugin = new DeviceInfoPlugin();
+    plugin.setupMethodChannel(registrar.messenger(), registrar.context().getContentResolver());
   }
 
   @Override
-  public void onMethodCall(MethodCall call, Result result) {
-    if (call.method.equals("getAndroidDeviceInfo")) {
-      Map<String, Object> build = new HashMap<>();
-      build.put("board", Build.BOARD);
-      build.put("bootloader", Build.BOOTLOADER);
-      build.put("brand", Build.BRAND);
-      build.put("device", Build.DEVICE);
-      build.put("display", Build.DISPLAY);
-      build.put("fingerprint", Build.FINGERPRINT);
-      build.put("hardware", Build.HARDWARE);
-      build.put("host", Build.HOST);
-      build.put("id", Build.ID);
-      build.put("manufacturer", Build.MANUFACTURER);
-      build.put("model", Build.MODEL);
-      build.put("product", Build.PRODUCT);
-      if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) {
-        build.put("supported32BitAbis", Arrays.asList(Build.SUPPORTED_32_BIT_ABIS));
-        build.put("supported64BitAbis", Arrays.asList(Build.SUPPORTED_64_BIT_ABIS));
-        build.put("supportedAbis", Arrays.asList(Build.SUPPORTED_ABIS));
-      } else {
-        build.put("supported32BitAbis", Arrays.asList(EMPTY_STRING_LIST));
-        build.put("supported64BitAbis", Arrays.asList(EMPTY_STRING_LIST));
-        build.put("supportedAbis", Arrays.asList(EMPTY_STRING_LIST));
-      }
-      build.put("tags", Build.TAGS);
-      build.put("type", Build.TYPE);
-      build.put("isPhysicalDevice", !isEmulator());
-      build.put("androidId", getAndroidId());
-
-      Map<String, Object> version = new HashMap<>();
-      if (VERSION.SDK_INT >= VERSION_CODES.M) {
-        version.put("baseOS", VERSION.BASE_OS);
-        version.put("previewSdkInt", VERSION.PREVIEW_SDK_INT);
-        version.put("securityPatch", VERSION.SECURITY_PATCH);
-      }
-      version.put("codename", VERSION.CODENAME);
-      version.put("incremental", VERSION.INCREMENTAL);
-      version.put("release", VERSION.RELEASE);
-      version.put("sdkInt", VERSION.SDK_INT);
-      build.put("version", version);
-
-      result.success(build);
-    } else {
-      result.notImplemented();
-    }
+  public void onAttachedToEngine(FlutterPlugin.FlutterPluginBinding binding) {
+    setupMethodChannel(
+        binding.getFlutterEngine().getDartExecutor(),
+        binding.getApplicationContext().getContentResolver());
   }
 
-  /**
-   * Returns the Android hardware device ID that is unique between the device + user and app
-   * signing. This key will change if the app is uninstalled or its data is cleared. Device factory
-   * reset will also result in a value change.
-   *
-   * @return The android ID
-   */
-  @SuppressLint("HardwareIds")
-  private String getAndroidId() {
-    return Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
+  @Override
+  public void onDetachedFromEngine(FlutterPlugin.FlutterPluginBinding binding) {
+    tearDownChannel();
   }
 
-  /**
-   * A simple emulator-detection based on the flutter tools detection logic and a couple of legacy
-   * detection systems
-   */
-  private boolean isEmulator() {
-    return (Build.BRAND.startsWith("generic") && Build.DEVICE.startsWith("generic"))
-        || Build.FINGERPRINT.startsWith("generic")
-        || Build.FINGERPRINT.startsWith("unknown")
-        || Build.HARDWARE.contains("goldfish")
-        || Build.HARDWARE.contains("ranchu")
-        || Build.MODEL.contains("google_sdk")
-        || Build.MODEL.contains("Emulator")
-        || Build.MODEL.contains("Android SDK built for x86")
-        || Build.MANUFACTURER.contains("Genymotion")
-        || Build.PRODUCT.contains("sdk_google")
-        || Build.PRODUCT.contains("google_sdk")
-        || Build.PRODUCT.contains("sdk")
-        || Build.PRODUCT.contains("sdk_x86")
-        || Build.PRODUCT.contains("vbox86p")
-        || Build.PRODUCT.contains("emulator")
-        || Build.PRODUCT.contains("simulator");
+  private void setupMethodChannel(BinaryMessenger messenger, ContentResolver contentResolver) {
+    channel = new MethodChannel(messenger, "plugins.flutter.io/device_info");
+    final MethodCallHandlerImpl handler = new MethodCallHandlerImpl(contentResolver);
+    channel.setMethodCallHandler(handler);
+  }
+
+  private void tearDownChannel() {
+    channel.setMethodCallHandler(null);
+    channel = null;
   }
 }
diff --git a/packages/device_info/android/src/main/java/io/flutter/plugins/deviceinfo/MethodCallHandlerImpl.java b/packages/device_info/android/src/main/java/io/flutter/plugins/deviceinfo/MethodCallHandlerImpl.java
new file mode 100644
index 0000000..22ea1f0
--- /dev/null
+++ b/packages/device_info/android/src/main/java/io/flutter/plugins/deviceinfo/MethodCallHandlerImpl.java
@@ -0,0 +1,115 @@
+// Copyright 2017 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 io.flutter.plugins.deviceinfo;
+
+import android.annotation.SuppressLint;
+import android.content.ContentResolver;
+import android.os.Build;
+import android.provider.Settings;
+import io.flutter.plugin.common.MethodCall;
+import io.flutter.plugin.common.MethodChannel;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * The implementation of {@link MethodChannel.MethodCallHandler} for the plugin. Responsible for
+ * receiving method calls from method channel.
+ */
+class MethodCallHandlerImpl implements MethodChannel.MethodCallHandler {
+
+  private ContentResolver contentResolver;
+
+  /** Substitute for missing values. */
+  private static final String[] EMPTY_STRING_LIST = new String[] {};
+
+  /** Constructs DeviceInfo. The {@code contentResolver} must not be null. */
+  MethodCallHandlerImpl(ContentResolver contentResolver) {
+    this.contentResolver = contentResolver;
+  }
+
+  @Override
+  public void onMethodCall(MethodCall call, MethodChannel.Result result) {
+    if (call.method.equals("getAndroidDeviceInfo")) {
+      Map<String, Object> build = new HashMap<>();
+      build.put("board", Build.BOARD);
+      build.put("bootloader", Build.BOOTLOADER);
+      build.put("brand", Build.BRAND);
+      build.put("device", Build.DEVICE);
+      build.put("display", Build.DISPLAY);
+      build.put("fingerprint", Build.FINGERPRINT);
+      build.put("hardware", Build.HARDWARE);
+      build.put("host", Build.HOST);
+      build.put("id", Build.ID);
+      build.put("manufacturer", Build.MANUFACTURER);
+      build.put("model", Build.MODEL);
+      build.put("product", Build.PRODUCT);
+      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+        build.put("supported32BitAbis", Arrays.asList(Build.SUPPORTED_32_BIT_ABIS));
+        build.put("supported64BitAbis", Arrays.asList(Build.SUPPORTED_64_BIT_ABIS));
+        build.put("supportedAbis", Arrays.asList(Build.SUPPORTED_ABIS));
+      } else {
+        build.put("supported32BitAbis", Arrays.asList(EMPTY_STRING_LIST));
+        build.put("supported64BitAbis", Arrays.asList(EMPTY_STRING_LIST));
+        build.put("supportedAbis", Arrays.asList(EMPTY_STRING_LIST));
+      }
+      build.put("tags", Build.TAGS);
+      build.put("type", Build.TYPE);
+      build.put("isPhysicalDevice", !isEmulator());
+      build.put("androidId", getAndroidId());
+
+      Map<String, Object> version = new HashMap<>();
+      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+        version.put("baseOS", Build.VERSION.BASE_OS);
+        version.put("previewSdkInt", Build.VERSION.PREVIEW_SDK_INT);
+        version.put("securityPatch", Build.VERSION.SECURITY_PATCH);
+      }
+      version.put("codename", Build.VERSION.CODENAME);
+      version.put("incremental", Build.VERSION.INCREMENTAL);
+      version.put("release", Build.VERSION.RELEASE);
+      version.put("sdkInt", Build.VERSION.SDK_INT);
+      build.put("version", version);
+
+      result.success(build);
+    } else {
+      result.notImplemented();
+    }
+  }
+
+  /**
+   * Returns the Android hardware device ID that is unique between the device + user and app
+   * signing. This key will change if the app is uninstalled or its data is cleared. Device factory
+   * reset will also result in a value change.
+   *
+   * @return The android ID
+   */
+  @SuppressLint("HardwareIds")
+  private String getAndroidId() {
+    return Settings.Secure.getString(contentResolver, Settings.Secure.ANDROID_ID);
+  }
+
+  /**
+   * A simple emulator-detection based on the flutter tools detection logic and a couple of legacy
+   * detection systems
+   */
+  private boolean isEmulator() {
+    return (Build.BRAND.startsWith("generic") && Build.DEVICE.startsWith("generic"))
+        || Build.FINGERPRINT.startsWith("generic")
+        || Build.FINGERPRINT.startsWith("unknown")
+        || Build.HARDWARE.contains("goldfish")
+        || Build.HARDWARE.contains("ranchu")
+        || Build.MODEL.contains("google_sdk")
+        || Build.MODEL.contains("Emulator")
+        || Build.MODEL.contains("Android SDK built for x86")
+        || Build.MANUFACTURER.contains("Genymotion")
+        || Build.PRODUCT.contains("sdk_google")
+        || Build.PRODUCT.contains("google_sdk")
+        || Build.PRODUCT.contains("sdk")
+        || Build.PRODUCT.contains("sdk_x86")
+        || Build.PRODUCT.contains("vbox86p")
+        || Build.PRODUCT.contains("emulator")
+        || Build.PRODUCT.contains("simulator");
+  }
+}
diff --git a/packages/device_info/example/android/app/src/main/AndroidManifest.xml b/packages/device_info/example/android/app/src/main/AndroidManifest.xml
index b46ebe8..45242ab 100644
--- a/packages/device_info/example/android/app/src/main/AndroidManifest.xml
+++ b/packages/device_info/example/android/app/src/main/AndroidManifest.xml
@@ -4,12 +4,19 @@
     <uses-permission android:name="android.permission.INTERNET"/>
 
     <application android:name="io.flutter.app.FlutterApplication" android:label="device_info_example" android:icon="@mipmap/ic_launcher">
-        <activity android:name="io.flutter.plugins.deviceinfoexample.MainActivity"
+        <activity android:name=".EmbeddingV1Activity"
                   android:launchMode="singleTop"
                   android:theme="@android:style/Theme.Black.NoTitleBar"
                   android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection"
                   android:hardwareAccelerated="true"
+                  android:exported="true"
                   android:windowSoftInputMode="adjustResize">
+        </activity>
+        <activity android:name=".MainActivity"
+            android:theme="@android:style/Theme.Black.NoTitleBar"
+            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection"
+            android:hardwareAccelerated="true"
+            android:windowSoftInputMode="adjustResize">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN"/>
                 <category android:name="android.intent.category.LAUNCHER"/>
diff --git a/packages/device_info/example/android/app/src/main/java/io/flutter/plugins/deviceinfoexample/EmbeddingV1Activity.java b/packages/device_info/example/android/app/src/main/java/io/flutter/plugins/deviceinfoexample/EmbeddingV1Activity.java
new file mode 100644
index 0000000..0bfaee8
--- /dev/null
+++ b/packages/device_info/example/android/app/src/main/java/io/flutter/plugins/deviceinfoexample/EmbeddingV1Activity.java
@@ -0,0 +1,17 @@
+// Copyright 2017 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 io.flutter.plugins.deviceinfoexample;
+
+import android.os.Bundle;
+import io.flutter.app.FlutterActivity;
+import io.flutter.plugins.GeneratedPluginRegistrant;
+
+public class EmbeddingV1Activity extends FlutterActivity {
+  @Override
+  protected void onCreate(Bundle savedInstanceState) {
+    super.onCreate(savedInstanceState);
+    GeneratedPluginRegistrant.registerWith(this);
+  }
+}
diff --git a/packages/device_info/example/android/app/src/main/java/io/flutter/plugins/deviceinfoexample/EmbeddingV1ActivityTest.java b/packages/device_info/example/android/app/src/main/java/io/flutter/plugins/deviceinfoexample/EmbeddingV1ActivityTest.java
new file mode 100644
index 0000000..2bec9fb
--- /dev/null
+++ b/packages/device_info/example/android/app/src/main/java/io/flutter/plugins/deviceinfoexample/EmbeddingV1ActivityTest.java
@@ -0,0 +1,13 @@
+package io.flutter.plugins.deviceinfoexample;
+
+import androidx.test.rule.ActivityTestRule;
+import dev.flutter.plugins.e2e.FlutterRunner;
+import org.junit.Rule;
+import org.junit.runner.RunWith;
+
+@RunWith(FlutterRunner.class)
+public class EmbeddingV1ActivityTest {
+  @Rule
+  public ActivityTestRule<EmbeddingV1Activity> rule =
+      new ActivityTestRule<>(EmbeddingV1Activity.class);
+}
diff --git a/packages/device_info/example/android/app/src/main/java/io/flutter/plugins/deviceinfoexample/MainActivity.java b/packages/device_info/example/android/app/src/main/java/io/flutter/plugins/deviceinfoexample/MainActivity.java
index 06a3172..b820542 100644
--- a/packages/device_info/example/android/app/src/main/java/io/flutter/plugins/deviceinfoexample/MainActivity.java
+++ b/packages/device_info/example/android/app/src/main/java/io/flutter/plugins/deviceinfoexample/MainActivity.java
@@ -1,17 +1,20 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
+// Copyright 2019 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 io.flutter.plugins.deviceinfoexample;
 
-import android.os.Bundle;
-import io.flutter.app.FlutterActivity;
-import io.flutter.plugins.GeneratedPluginRegistrant;
+import io.flutter.embedding.android.FlutterActivity;
+import io.flutter.embedding.engine.FlutterEngine;
+import io.flutter.plugins.deviceinfo.DeviceInfoPlugin;
 
 public class MainActivity extends FlutterActivity {
+
+  // TODO(cyanglaz): Remove this once v2 of GeneratedPluginRegistrant rolls to stable.
+  // https://github.com/flutter/flutter/issues/42694
   @Override
-  protected void onCreate(Bundle savedInstanceState) {
-    super.onCreate(savedInstanceState);
-    GeneratedPluginRegistrant.registerWith(this);
+  public void configureFlutterEngine(FlutterEngine flutterEngine) {
+    super.configureFlutterEngine(flutterEngine);
+    flutterEngine.getPlugins().add(new DeviceInfoPlugin());
   }
 }
diff --git a/packages/device_info/example/android/app/src/main/java/io/flutter/plugins/deviceinfoexample/MainActivityTest.java b/packages/device_info/example/android/app/src/main/java/io/flutter/plugins/deviceinfoexample/MainActivityTest.java
new file mode 100644
index 0000000..36967eb
--- /dev/null
+++ b/packages/device_info/example/android/app/src/main/java/io/flutter/plugins/deviceinfoexample/MainActivityTest.java
@@ -0,0 +1,15 @@
+// Copyright 2019 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 io.flutter.plugins.deviceinfoexample;
+
+import androidx.test.rule.ActivityTestRule;
+import dev.flutter.plugins.e2e.FlutterRunner;
+import org.junit.Rule;
+import org.junit.runner.RunWith;
+
+@RunWith(FlutterRunner.class)
+public class MainActivityTest {
+  @Rule public ActivityTestRule<MainActivity> rule = new ActivityTestRule<>(MainActivity.class);
+}
diff --git a/packages/device_info/example/android/gradle.properties b/packages/device_info/example/android/gradle.properties
index 8bd86f6..38c8d45 100644
--- a/packages/device_info/example/android/gradle.properties
+++ b/packages/device_info/example/android/gradle.properties
@@ -1 +1,4 @@
 org.gradle.jvmargs=-Xmx1536M
+android.enableR8=true
+android.useAndroidX=true
+android.enableJetifier=true
diff --git a/packages/device_info/example/pubspec.yaml b/packages/device_info/example/pubspec.yaml
index 65b7bf8..148b7b9 100644
--- a/packages/device_info/example/pubspec.yaml
+++ b/packages/device_info/example/pubspec.yaml
@@ -7,5 +7,15 @@
   device_info:
     path: ../
 
+dev_dependencies:
+  flutter_driver:
+    sdk: flutter
+  e2e: ^0.2.0
+
 flutter:
   uses-material-design: true
+
+environment:
+  sdk: ">=2.0.0-dev.28.0 <3.0.0"
+  flutter: ">=1.9.1+hotfix.2 <2.0.0"
+
diff --git a/packages/device_info/example/test_driver/device_info_e2e.dart b/packages/device_info/example/test_driver/device_info_e2e.dart
new file mode 100644
index 0000000..db8a73f
--- /dev/null
+++ b/packages/device_info/example/test_driver/device_info_e2e.dart
@@ -0,0 +1,32 @@
+// Copyright 2019, the Chromium project authors.  Please see the AUTHORS file
+// for details. 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_test/flutter_test.dart';
+import 'package:device_info/device_info.dart';
+import 'package:e2e/e2e.dart';
+
+void main() {
+  E2EWidgetsFlutterBinding.ensureInitialized();
+
+  IosDeviceInfo iosInfo;
+  AndroidDeviceInfo androidInfo;
+
+  setUpAll(() async {
+    final DeviceInfoPlugin deviceInfoPlugin = DeviceInfoPlugin();
+    if (Platform.isIOS) {
+      iosInfo = await deviceInfoPlugin.iosInfo;
+    } else if (Platform.isAndroid) {
+      androidInfo = await deviceInfoPlugin.androidInfo;
+    }
+  });
+
+  testWidgets('Can get non-null device model', (WidgetTester tester) async {
+    if (Platform.isIOS) {
+      expect(iosInfo.model, isNotNull);
+    } else if (Platform.isAndroid) {
+      expect(androidInfo.model, isNotNull);
+    }
+  });
+}
diff --git a/packages/device_info/example/test_driver/device_info_e2e_test.dart b/packages/device_info/example/test_driver/device_info_e2e_test.dart
new file mode 100644
index 0000000..ff6e9ce
--- /dev/null
+++ b/packages/device_info/example/test_driver/device_info_e2e_test.dart
@@ -0,0 +1,15 @@
+// Copyright 2019, the Chromium project authors.  Please see the AUTHORS file
+// for details. 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:async';
+import 'dart:io';
+import 'package:flutter_driver/flutter_driver.dart';
+
+Future<void> main() async {
+  final FlutterDriver driver = await FlutterDriver.connect();
+  final String result =
+      await driver.requestData(null, timeout: const Duration(minutes: 1));
+  driver.close();
+  exit(result == 'pass' ? 0 : 1);
+}
diff --git a/packages/device_info/pubspec.yaml b/packages/device_info/pubspec.yaml
index bc192a8..580df14 100644
--- a/packages/device_info/pubspec.yaml
+++ b/packages/device_info/pubspec.yaml
@@ -3,7 +3,7 @@
   (make, model, etc.), and Android or iOS version the app is running on.
 author: Flutter Team <flutter-dev@googlegroups.com>
 homepage: https://github.com/flutter/plugins/tree/master/packages/device_info
-version: 0.4.0+4
+version: 0.4.1
 
 flutter:
   plugin:
@@ -15,6 +15,12 @@
   flutter:
     sdk: flutter
 
+dev_dependencies:
+  test: ^1.3.0
+  flutter_test:
+    sdk: flutter
+  e2e: ^0.2.0
+
 environment:
   sdk: ">=2.0.0-dev.28.0 <3.0.0"
-  flutter: ">=1.5.0 <2.0.0"
+  flutter: ">=1.6.7 <2.0.0"