Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.

Commit 3ad2d83

Browse files
author
Chris Yang
authored
[sensor] Support v2 android embedder. (#2164)
1 parent 08fd95c commit 3ad2d83

File tree

14 files changed

+243
-54
lines changed

14 files changed

+243
-54
lines changed

packages/sensors/CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
## 0.4.1
2+
3+
* Support the v2 Android embedder.
4+
* Update to AndroidX.
5+
* Migrate to using the new e2e test binding.
6+
* Add a e2e test.
7+
18
## 0.4.0+3
29

310
* Update and migrate iOS example project.

packages/sensors/android/build.gradle

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,29 @@ android {
4545
disable 'InvalidPackage'
4646
}
4747
}
48+
49+
// TODO(cyanglaz): Remove this hack once androidx.lifecycle is included on stable. https://github.com/flutter/flutter/issues/42348
50+
afterEvaluate {
51+
def containsEmbeddingDependencies = false
52+
for (def configuration : configurations.all) {
53+
for (def dependency : configuration.dependencies) {
54+
if (dependency.group == 'io.flutter' &&
55+
dependency.name.startsWith('flutter_embedding') &&
56+
dependency.isTransitive())
57+
{
58+
containsEmbeddingDependencies = true
59+
break
60+
}
61+
}
62+
}
63+
if (!containsEmbeddingDependencies) {
64+
android {
65+
dependencies {
66+
def lifecycle_version = "1.1.1"
67+
api "android.arch.lifecycle:runtime:$lifecycle_version"
68+
api "android.arch.lifecycle:common:$lifecycle_version"
69+
api "android.arch.lifecycle:common-java8:$lifecycle_version"
70+
}
71+
}
72+
}
73+
}

packages/sensors/android/src/main/java/io/flutter/plugins/sensors/SensorsPlugin.java

Lines changed: 40 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -6,71 +6,67 @@
66

77
import android.content.Context;
88
import android.hardware.Sensor;
9-
import android.hardware.SensorEvent;
10-
import android.hardware.SensorEventListener;
119
import android.hardware.SensorManager;
10+
import io.flutter.embedding.engine.plugins.FlutterPlugin;
11+
import io.flutter.plugin.common.BinaryMessenger;
1212
import io.flutter.plugin.common.EventChannel;
1313
import io.flutter.plugin.common.PluginRegistry.Registrar;
1414

1515
/** SensorsPlugin */
16-
public class SensorsPlugin implements EventChannel.StreamHandler {
16+
public class SensorsPlugin implements FlutterPlugin {
1717
private static final String ACCELEROMETER_CHANNEL_NAME =
1818
"plugins.flutter.io/sensors/accelerometer";
1919
private static final String GYROSCOPE_CHANNEL_NAME = "plugins.flutter.io/sensors/gyroscope";
2020
private static final String USER_ACCELEROMETER_CHANNEL_NAME =
2121
"plugins.flutter.io/sensors/user_accel";
2222

23+
private EventChannel accelerometerChannel;
24+
private EventChannel userAccelChannel;
25+
private EventChannel gyroscopeChannel;
26+
2327
/** Plugin registration. */
2428
public static void registerWith(Registrar registrar) {
25-
final EventChannel accelerometerChannel =
26-
new EventChannel(registrar.messenger(), ACCELEROMETER_CHANNEL_NAME);
27-
accelerometerChannel.setStreamHandler(
28-
new SensorsPlugin(registrar.context(), Sensor.TYPE_ACCELEROMETER));
29-
30-
final EventChannel userAccelChannel =
31-
new EventChannel(registrar.messenger(), USER_ACCELEROMETER_CHANNEL_NAME);
32-
userAccelChannel.setStreamHandler(
33-
new SensorsPlugin(registrar.context(), Sensor.TYPE_LINEAR_ACCELERATION));
34-
35-
final EventChannel gyroscopeChannel =
36-
new EventChannel(registrar.messenger(), GYROSCOPE_CHANNEL_NAME);
37-
gyroscopeChannel.setStreamHandler(
38-
new SensorsPlugin(registrar.context(), Sensor.TYPE_GYROSCOPE));
39-
}
40-
41-
private SensorEventListener sensorEventListener;
42-
private final SensorManager sensorManager;
43-
private final Sensor sensor;
44-
45-
private SensorsPlugin(Context context, int sensorType) {
46-
sensorManager = (SensorManager) context.getSystemService(context.SENSOR_SERVICE);
47-
sensor = sensorManager.getDefaultSensor(sensorType);
29+
SensorsPlugin plugin = new SensorsPlugin();
30+
plugin.setupEventChannels(registrar.context(), registrar.messenger());
4831
}
4932

5033
@Override
51-
public void onListen(Object arguments, EventChannel.EventSink events) {
52-
sensorEventListener = createSensorEventListener(events);
53-
sensorManager.registerListener(sensorEventListener, sensor, sensorManager.SENSOR_DELAY_NORMAL);
34+
public void onAttachedToEngine(FlutterPluginBinding binding) {
35+
final Context context = binding.getApplicationContext();
36+
setupEventChannels(context, binding.getFlutterEngine().getDartExecutor());
5437
}
5538

5639
@Override
57-
public void onCancel(Object arguments) {
58-
sensorManager.unregisterListener(sensorEventListener);
40+
public void onDetachedFromEngine(FlutterPluginBinding binding) {
41+
teardownEventChannels();
5942
}
6043

61-
SensorEventListener createSensorEventListener(final EventChannel.EventSink events) {
62-
return new SensorEventListener() {
63-
@Override
64-
public void onAccuracyChanged(Sensor sensor, int accuracy) {}
44+
private void setupEventChannels(Context context, BinaryMessenger messenger) {
45+
accelerometerChannel = new EventChannel(messenger, ACCELEROMETER_CHANNEL_NAME);
46+
final StreamHandlerImpl accelerationStreamHandler =
47+
new StreamHandlerImpl(
48+
(SensorManager) context.getSystemService(context.SENSOR_SERVICE),
49+
Sensor.TYPE_ACCELEROMETER);
50+
accelerometerChannel.setStreamHandler(accelerationStreamHandler);
51+
52+
userAccelChannel = new EventChannel(messenger, USER_ACCELEROMETER_CHANNEL_NAME);
53+
final StreamHandlerImpl linearAccelerationStreamHandler =
54+
new StreamHandlerImpl(
55+
(SensorManager) context.getSystemService(context.SENSOR_SERVICE),
56+
Sensor.TYPE_LINEAR_ACCELERATION);
57+
userAccelChannel.setStreamHandler(linearAccelerationStreamHandler);
58+
59+
gyroscopeChannel = new EventChannel(messenger, GYROSCOPE_CHANNEL_NAME);
60+
final StreamHandlerImpl gyroScopeStreamHandler =
61+
new StreamHandlerImpl(
62+
(SensorManager) context.getSystemService(context.SENSOR_SERVICE),
63+
Sensor.TYPE_GYROSCOPE);
64+
gyroscopeChannel.setStreamHandler(gyroScopeStreamHandler);
65+
}
6566

66-
@Override
67-
public void onSensorChanged(SensorEvent event) {
68-
double[] sensorValues = new double[event.values.length];
69-
for (int i = 0; i < event.values.length; i++) {
70-
sensorValues[i] = event.values[i];
71-
}
72-
events.success(sensorValues);
73-
}
74-
};
67+
private void teardownEventChannels() {
68+
accelerometerChannel.setStreamHandler(null);
69+
userAccelChannel.setStreamHandler(null);
70+
gyroscopeChannel.setStreamHandler(null);
7571
}
7672
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// Copyright 2019 The Chromium Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
package io.flutter.plugins.sensors;
6+
7+
import android.hardware.Sensor;
8+
import android.hardware.SensorEvent;
9+
import android.hardware.SensorEventListener;
10+
import android.hardware.SensorManager;
11+
import io.flutter.plugin.common.EventChannel;
12+
13+
class StreamHandlerImpl implements EventChannel.StreamHandler {
14+
15+
private SensorEventListener sensorEventListener;
16+
private final SensorManager sensorManager;
17+
private final Sensor sensor;
18+
19+
StreamHandlerImpl(SensorManager sensorManager, int sensorType) {
20+
this.sensorManager = sensorManager;
21+
sensor = sensorManager.getDefaultSensor(sensorType);
22+
}
23+
24+
@Override
25+
public void onListen(Object arguments, EventChannel.EventSink events) {
26+
sensorEventListener = createSensorEventListener(events);
27+
sensorManager.registerListener(sensorEventListener, sensor, sensorManager.SENSOR_DELAY_NORMAL);
28+
}
29+
30+
@Override
31+
public void onCancel(Object arguments) {
32+
sensorManager.unregisterListener(sensorEventListener);
33+
}
34+
35+
SensorEventListener createSensorEventListener(final EventChannel.EventSink events) {
36+
return new SensorEventListener() {
37+
@Override
38+
public void onAccuracyChanged(Sensor sensor, int accuracy) {}
39+
40+
@Override
41+
public void onSensorChanged(SensorEvent event) {
42+
double[] sensorValues = new double[event.values.length];
43+
for (int i = 0; i < event.values.length; i++) {
44+
sensorValues[i] = event.values[i];
45+
}
46+
events.success(sensorValues);
47+
}
48+
};
49+
}
50+
}

packages/sensors/example/android/app/src/main/AndroidManifest.xml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,18 @@
44
<uses-permission android:name="android.permission.INTERNET"/>
55

66
<application android:name="io.flutter.app.FlutterApplication" android:label="sensors_example" android:icon="@mipmap/ic_launcher">
7-
<activity android:name=".MainActivity"
7+
<activity android:name=".EmbeddingV1Activity"
88
android:launchMode="singleTop"
99
android:theme="@android:style/Theme.Black.NoTitleBar"
1010
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection"
1111
android:hardwareAccelerated="true"
1212
android:windowSoftInputMode="adjustResize">
13+
</activity>
14+
<activity android:name=".MainActivity"
15+
android:theme="@android:style/Theme.Black.NoTitleBar"
16+
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection"
17+
android:hardwareAccelerated="true"
18+
android:windowSoftInputMode="adjustResize">
1319
<intent-filter>
1420
<action android:name="android.intent.action.MAIN"/>
1521
<category android:name="android.intent.category.LAUNCHER"/>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright 2019 The Chromium Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
package io.flutter.plugins.sensorsexample;
6+
7+
import android.os.Bundle;
8+
import io.flutter.app.FlutterActivity;
9+
import io.flutter.plugins.GeneratedPluginRegistrant;
10+
11+
public class EmbeddingV1Activity extends FlutterActivity {
12+
@Override
13+
protected void onCreate(Bundle savedInstanceState) {
14+
super.onCreate(savedInstanceState);
15+
GeneratedPluginRegistrant.registerWith(this);
16+
}
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package io.flutter.plugins.sensorsexample;
2+
3+
import androidx.test.rule.ActivityTestRule;
4+
import dev.flutter.plugins.e2e.FlutterRunner;
5+
import org.junit.Rule;
6+
import org.junit.runner.RunWith;
7+
8+
@RunWith(FlutterRunner.class)
9+
public class EmbeddingV1ActivityTest {
10+
@Rule
11+
public ActivityTestRule<EmbeddingV1Activity> rule =
12+
new ActivityTestRule<>(EmbeddingV1Activity.class);
13+
}
Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,20 @@
1+
// Copyright 2019 The Chromium Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
15
package io.flutter.plugins.sensorsexample;
26

3-
import android.os.Bundle;
4-
import io.flutter.app.FlutterActivity;
5-
import io.flutter.plugins.GeneratedPluginRegistrant;
7+
import io.flutter.embedding.android.FlutterActivity;
8+
import io.flutter.embedding.engine.FlutterEngine;
9+
import io.flutter.plugins.sensors.SensorsPlugin;
610

711
public class MainActivity extends FlutterActivity {
12+
13+
// TODO(cyanglaz): Remove this once v2 of GeneratedPluginRegistrant rolls to stable.
14+
// https://github.com/flutter/flutter/issues/42694
815
@Override
9-
protected void onCreate(Bundle savedInstanceState) {
10-
super.onCreate(savedInstanceState);
11-
GeneratedPluginRegistrant.registerWith(this);
16+
public void configureFlutterEngine(FlutterEngine flutterEngine) {
17+
super.configureFlutterEngine(flutterEngine);
18+
flutterEngine.getPlugins().add(new SensorsPlugin());
1219
}
1320
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Copyright 2019 The Chromium Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
package io.flutter.plugins.sensorsexample;
6+
7+
import androidx.test.rule.ActivityTestRule;
8+
import dev.flutter.plugins.e2e.FlutterRunner;
9+
import org.junit.Rule;
10+
import org.junit.runner.RunWith;
11+
12+
@RunWith(FlutterRunner.class)
13+
public class MainActivityTest {
14+
@Rule public ActivityTestRule<MainActivity> rule = new ActivityTestRule<>(MainActivity.class);
15+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
11
org.gradle.jvmargs=-Xmx1536M
2+
android.enableR8=true
3+
android.useAndroidX=true
4+
android.enableJetifier=true

packages/sensors/example/pubspec.yaml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,15 @@ dependencies:
77
sensors:
88
path: ../
99

10-
flutter:
10+
dev_dependencies:
11+
flutter_driver:
12+
sdk: flutter
13+
e2e: ^0.2.0
1114

15+
flutter:
1216
uses-material-design: true
17+
18+
environment:
19+
sdk: ">=2.0.0-dev.28.0 <3.0.0"
20+
flutter: ">=1.9.1+hotfix.2 <2.0.0"
21+
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Copyright 2019, the Chromium project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import 'dart:async';
6+
import 'dart:io';
7+
import 'package:flutter_driver/flutter_driver.dart';
8+
9+
Future<void> main() async {
10+
final FlutterDriver driver = await FlutterDriver.connect();
11+
final String result =
12+
await driver.requestData(null, timeout: const Duration(minutes: 1));
13+
driver.close();
14+
exit(result == 'pass' ? 0 : 1);
15+
}

packages/sensors/pubspec.yaml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ description: Flutter plugin for accessing the Android and iOS accelerometer and
33
gyroscope sensors.
44
author: Flutter Team <[email protected]>
55
homepage: https://github.com/flutter/plugins/tree/master/packages/sensors
6-
version: 0.4.0+3
6+
version: 0.4.1
77

88
flutter:
99
plugin:
@@ -19,7 +19,8 @@ dev_dependencies:
1919
test: ^1.3.0
2020
flutter_test:
2121
sdk: flutter
22+
e2e: ^0.2.0
2223

2324
environment:
2425
sdk: ">=2.0.0-dev.28.0 <3.0.0"
25-
flutter: ">=0.1.4 <2.0.0"
26+
flutter: ">=1.6.7 <2.0.0"
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Copyright 2019, the Chromium project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import 'dart:async';
6+
import 'package:flutter_test/flutter_test.dart';
7+
import 'package:sensors/sensors.dart';
8+
import 'package:e2e/e2e.dart';
9+
10+
void main() {
11+
E2EWidgetsFlutterBinding.ensureInitialized();
12+
13+
testWidgets('Can subscript to accelerometerEvents and get non-null events',
14+
(WidgetTester tester) async {
15+
final Completer<AccelerometerEvent> completer =
16+
Completer<AccelerometerEvent>();
17+
StreamSubscription<AccelerometerEvent> subscription;
18+
subscription = accelerometerEvents.listen((AccelerometerEvent event) {
19+
completer.complete(event);
20+
subscription.cancel();
21+
});
22+
expect(await completer.future, isNotNull);
23+
});
24+
}

0 commit comments

Comments
 (0)