diff --git a/packages/sensors/CHANGELOG.md b/packages/sensors/CHANGELOG.md
index d90ea5aeb6df..8b02f99683b7 100644
--- a/packages/sensors/CHANGELOG.md
+++ b/packages/sensors/CHANGELOG.md
@@ -1,3 +1,10 @@
+## 0.4.1
+
+* Support the v2 Android embedder.
+* Update to AndroidX.
+* Migrate to using the new e2e test binding.
+* Add a e2e test.
+
## 0.4.0+3
* Update and migrate iOS example project.
diff --git a/packages/sensors/android/build.gradle b/packages/sensors/android/build.gradle
index 56a76026f57a..47e7f63623b7 100644
--- a/packages/sensors/android/build.gradle
+++ b/packages/sensors/android/build.gradle
@@ -45,3 +45,29 @@ android {
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/sensors/android/src/main/java/io/flutter/plugins/sensors/SensorsPlugin.java b/packages/sensors/android/src/main/java/io/flutter/plugins/sensors/SensorsPlugin.java
index 65c47707029b..063f40641bcf 100644
--- a/packages/sensors/android/src/main/java/io/flutter/plugins/sensors/SensorsPlugin.java
+++ b/packages/sensors/android/src/main/java/io/flutter/plugins/sensors/SensorsPlugin.java
@@ -6,71 +6,67 @@
import android.content.Context;
import android.hardware.Sensor;
-import android.hardware.SensorEvent;
-import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
+import io.flutter.embedding.engine.plugins.FlutterPlugin;
+import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.EventChannel;
import io.flutter.plugin.common.PluginRegistry.Registrar;
/** SensorsPlugin */
-public class SensorsPlugin implements EventChannel.StreamHandler {
+public class SensorsPlugin implements FlutterPlugin {
private static final String ACCELEROMETER_CHANNEL_NAME =
"plugins.flutter.io/sensors/accelerometer";
private static final String GYROSCOPE_CHANNEL_NAME = "plugins.flutter.io/sensors/gyroscope";
private static final String USER_ACCELEROMETER_CHANNEL_NAME =
"plugins.flutter.io/sensors/user_accel";
+ private EventChannel accelerometerChannel;
+ private EventChannel userAccelChannel;
+ private EventChannel gyroscopeChannel;
+
/** Plugin registration. */
public static void registerWith(Registrar registrar) {
- final EventChannel accelerometerChannel =
- new EventChannel(registrar.messenger(), ACCELEROMETER_CHANNEL_NAME);
- accelerometerChannel.setStreamHandler(
- new SensorsPlugin(registrar.context(), Sensor.TYPE_ACCELEROMETER));
-
- final EventChannel userAccelChannel =
- new EventChannel(registrar.messenger(), USER_ACCELEROMETER_CHANNEL_NAME);
- userAccelChannel.setStreamHandler(
- new SensorsPlugin(registrar.context(), Sensor.TYPE_LINEAR_ACCELERATION));
-
- final EventChannel gyroscopeChannel =
- new EventChannel(registrar.messenger(), GYROSCOPE_CHANNEL_NAME);
- gyroscopeChannel.setStreamHandler(
- new SensorsPlugin(registrar.context(), Sensor.TYPE_GYROSCOPE));
- }
-
- private SensorEventListener sensorEventListener;
- private final SensorManager sensorManager;
- private final Sensor sensor;
-
- private SensorsPlugin(Context context, int sensorType) {
- sensorManager = (SensorManager) context.getSystemService(context.SENSOR_SERVICE);
- sensor = sensorManager.getDefaultSensor(sensorType);
+ SensorsPlugin plugin = new SensorsPlugin();
+ plugin.setupEventChannels(registrar.context(), registrar.messenger());
}
@Override
- public void onListen(Object arguments, EventChannel.EventSink events) {
- sensorEventListener = createSensorEventListener(events);
- sensorManager.registerListener(sensorEventListener, sensor, sensorManager.SENSOR_DELAY_NORMAL);
+ public void onAttachedToEngine(FlutterPluginBinding binding) {
+ final Context context = binding.getApplicationContext();
+ setupEventChannels(context, binding.getFlutterEngine().getDartExecutor());
}
@Override
- public void onCancel(Object arguments) {
- sensorManager.unregisterListener(sensorEventListener);
+ public void onDetachedFromEngine(FlutterPluginBinding binding) {
+ teardownEventChannels();
}
- SensorEventListener createSensorEventListener(final EventChannel.EventSink events) {
- return new SensorEventListener() {
- @Override
- public void onAccuracyChanged(Sensor sensor, int accuracy) {}
+ private void setupEventChannels(Context context, BinaryMessenger messenger) {
+ accelerometerChannel = new EventChannel(messenger, ACCELEROMETER_CHANNEL_NAME);
+ final StreamHandlerImpl accelerationStreamHandler =
+ new StreamHandlerImpl(
+ (SensorManager) context.getSystemService(context.SENSOR_SERVICE),
+ Sensor.TYPE_ACCELEROMETER);
+ accelerometerChannel.setStreamHandler(accelerationStreamHandler);
+
+ userAccelChannel = new EventChannel(messenger, USER_ACCELEROMETER_CHANNEL_NAME);
+ final StreamHandlerImpl linearAccelerationStreamHandler =
+ new StreamHandlerImpl(
+ (SensorManager) context.getSystemService(context.SENSOR_SERVICE),
+ Sensor.TYPE_LINEAR_ACCELERATION);
+ userAccelChannel.setStreamHandler(linearAccelerationStreamHandler);
+
+ gyroscopeChannel = new EventChannel(messenger, GYROSCOPE_CHANNEL_NAME);
+ final StreamHandlerImpl gyroScopeStreamHandler =
+ new StreamHandlerImpl(
+ (SensorManager) context.getSystemService(context.SENSOR_SERVICE),
+ Sensor.TYPE_GYROSCOPE);
+ gyroscopeChannel.setStreamHandler(gyroScopeStreamHandler);
+ }
- @Override
- public void onSensorChanged(SensorEvent event) {
- double[] sensorValues = new double[event.values.length];
- for (int i = 0; i < event.values.length; i++) {
- sensorValues[i] = event.values[i];
- }
- events.success(sensorValues);
- }
- };
+ private void teardownEventChannels() {
+ accelerometerChannel.setStreamHandler(null);
+ userAccelChannel.setStreamHandler(null);
+ gyroscopeChannel.setStreamHandler(null);
}
}
diff --git a/packages/sensors/android/src/main/java/io/flutter/plugins/sensors/StreamHandlerImpl.java b/packages/sensors/android/src/main/java/io/flutter/plugins/sensors/StreamHandlerImpl.java
new file mode 100644
index 000000000000..ac0546109f96
--- /dev/null
+++ b/packages/sensors/android/src/main/java/io/flutter/plugins/sensors/StreamHandlerImpl.java
@@ -0,0 +1,50 @@
+// 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.sensors;
+
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
+import io.flutter.plugin.common.EventChannel;
+
+class StreamHandlerImpl implements EventChannel.StreamHandler {
+
+ private SensorEventListener sensorEventListener;
+ private final SensorManager sensorManager;
+ private final Sensor sensor;
+
+ StreamHandlerImpl(SensorManager sensorManager, int sensorType) {
+ this.sensorManager = sensorManager;
+ sensor = sensorManager.getDefaultSensor(sensorType);
+ }
+
+ @Override
+ public void onListen(Object arguments, EventChannel.EventSink events) {
+ sensorEventListener = createSensorEventListener(events);
+ sensorManager.registerListener(sensorEventListener, sensor, sensorManager.SENSOR_DELAY_NORMAL);
+ }
+
+ @Override
+ public void onCancel(Object arguments) {
+ sensorManager.unregisterListener(sensorEventListener);
+ }
+
+ SensorEventListener createSensorEventListener(final EventChannel.EventSink events) {
+ return new SensorEventListener() {
+ @Override
+ public void onAccuracyChanged(Sensor sensor, int accuracy) {}
+
+ @Override
+ public void onSensorChanged(SensorEvent event) {
+ double[] sensorValues = new double[event.values.length];
+ for (int i = 0; i < event.values.length; i++) {
+ sensorValues[i] = event.values[i];
+ }
+ events.success(sensorValues);
+ }
+ };
+ }
+}
diff --git a/packages/sensors/example/android/app/src/main/AndroidManifest.xml b/packages/sensors/example/android/app/src/main/AndroidManifest.xml
index 92a8fc62ea99..67d4eb5e4a5f 100644
--- a/packages/sensors/example/android/app/src/main/AndroidManifest.xml
+++ b/packages/sensors/example/android/app/src/main/AndroidManifest.xml
@@ -4,12 +4,18 @@
-
+
+
diff --git a/packages/sensors/example/android/app/src/main/java/io/flutter/plugins/sensorsexample/EmbeddingV1Activity.java b/packages/sensors/example/android/app/src/main/java/io/flutter/plugins/sensorsexample/EmbeddingV1Activity.java
new file mode 100644
index 000000000000..c91a3a942ba5
--- /dev/null
+++ b/packages/sensors/example/android/app/src/main/java/io/flutter/plugins/sensorsexample/EmbeddingV1Activity.java
@@ -0,0 +1,17 @@
+// 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.sensorsexample;
+
+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/sensors/example/android/app/src/main/java/io/flutter/plugins/sensorsexample/EmbeddingV1ActivityTest.java b/packages/sensors/example/android/app/src/main/java/io/flutter/plugins/sensorsexample/EmbeddingV1ActivityTest.java
new file mode 100644
index 000000000000..6d0274f50e2c
--- /dev/null
+++ b/packages/sensors/example/android/app/src/main/java/io/flutter/plugins/sensorsexample/EmbeddingV1ActivityTest.java
@@ -0,0 +1,13 @@
+package io.flutter.plugins.sensorsexample;
+
+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 rule =
+ new ActivityTestRule<>(EmbeddingV1Activity.class);
+}
diff --git a/packages/sensors/example/android/app/src/main/java/io/flutter/plugins/sensorsexample/MainActivity.java b/packages/sensors/example/android/app/src/main/java/io/flutter/plugins/sensorsexample/MainActivity.java
index d4dad76b9b61..38d05d82afb5 100644
--- a/packages/sensors/example/android/app/src/main/java/io/flutter/plugins/sensorsexample/MainActivity.java
+++ b/packages/sensors/example/android/app/src/main/java/io/flutter/plugins/sensorsexample/MainActivity.java
@@ -1,13 +1,20 @@
+// 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.sensorsexample;
-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.sensors.SensorsPlugin;
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 SensorsPlugin());
}
}
diff --git a/packages/sensors/example/android/app/src/main/java/io/flutter/plugins/sensorsexample/MainActivityTest.java b/packages/sensors/example/android/app/src/main/java/io/flutter/plugins/sensorsexample/MainActivityTest.java
new file mode 100644
index 000000000000..dee5dffe3553
--- /dev/null
+++ b/packages/sensors/example/android/app/src/main/java/io/flutter/plugins/sensorsexample/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.sensorsexample;
+
+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 rule = new ActivityTestRule<>(MainActivity.class);
+}
diff --git a/packages/sensors/example/android/gradle.properties b/packages/sensors/example/android/gradle.properties
index 8bd86f680510..38c8d4544ff1 100644
--- a/packages/sensors/example/android/gradle.properties
+++ b/packages/sensors/example/android/gradle.properties
@@ -1 +1,4 @@
org.gradle.jvmargs=-Xmx1536M
+android.enableR8=true
+android.useAndroidX=true
+android.enableJetifier=true
diff --git a/packages/sensors/example/pubspec.yaml b/packages/sensors/example/pubspec.yaml
index 0da50897c809..c82faa93999c 100644
--- a/packages/sensors/example/pubspec.yaml
+++ b/packages/sensors/example/pubspec.yaml
@@ -7,6 +7,15 @@ dependencies:
sensors:
path: ../
-flutter:
+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/sensors/example/test_driver/test/sensors_e2e_test.dart b/packages/sensors/example/test_driver/test/sensors_e2e_test.dart
new file mode 100644
index 000000000000..ff6e9ce74ad9
--- /dev/null
+++ b/packages/sensors/example/test_driver/test/sensors_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 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/sensors/pubspec.yaml b/packages/sensors/pubspec.yaml
index 2cb3395c7dbc..6db40e93f193 100644
--- a/packages/sensors/pubspec.yaml
+++ b/packages/sensors/pubspec.yaml
@@ -3,7 +3,7 @@ description: Flutter plugin for accessing the Android and iOS accelerometer and
gyroscope sensors.
author: Flutter Team
homepage: https://github.com/flutter/plugins/tree/master/packages/sensors
-version: 0.4.0+3
+version: 0.4.1
flutter:
plugin:
@@ -19,7 +19,8 @@ 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: ">=0.1.4 <2.0.0"
+ flutter: ">=1.6.7 <2.0.0"
diff --git a/packages/sensors/test/sensors_e2e.dart b/packages/sensors/test/sensors_e2e.dart
new file mode 100644
index 000000000000..acc356dfc235
--- /dev/null
+++ b/packages/sensors/test/sensors_e2e.dart
@@ -0,0 +1,24 @@
+// 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 'package:flutter_test/flutter_test.dart';
+import 'package:sensors/sensors.dart';
+import 'package:e2e/e2e.dart';
+
+void main() {
+ E2EWidgetsFlutterBinding.ensureInitialized();
+
+ testWidgets('Can subscript to accelerometerEvents and get non-null events',
+ (WidgetTester tester) async {
+ final Completer completer =
+ Completer();
+ StreamSubscription subscription;
+ subscription = accelerometerEvents.listen((AccelerometerEvent event) {
+ completer.complete(event);
+ subscription.cancel();
+ });
+ expect(await completer.future, isNotNull);
+ });
+}