forked from flutter/engine
-
Notifications
You must be signed in to change notification settings - Fork 2
/
FlutterEngineConnectionRegistryTest.java
209 lines (161 loc) · 7.78 KB
/
FlutterEngineConnectionRegistryTest.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
package io.flutter.embedding.engine;
import static org.junit.Assert.*;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import androidx.annotation.NonNull;
import androidx.lifecycle.Lifecycle;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import io.flutter.embedding.android.ExclusiveAppComponent;
import io.flutter.embedding.engine.loader.FlutterLoader;
import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.embedding.engine.plugins.activity.ActivityAware;
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
import io.flutter.plugin.common.PluginRegistry;
import io.flutter.plugin.platform.PlatformViewsController;
import java.util.concurrent.atomic.AtomicBoolean;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.annotation.Config;
// Run with Robolectric so that Log calls don't crash.
@Config(manifest = Config.NONE)
@RunWith(AndroidJUnit4.class)
public class FlutterEngineConnectionRegistryTest {
@Test
public void itDoesNotRegisterTheSamePluginTwice() {
Context context = mock(Context.class);
FlutterEngine flutterEngine = mock(FlutterEngine.class);
PlatformViewsController platformViewsController = mock(PlatformViewsController.class);
when(flutterEngine.getPlatformViewsController()).thenReturn(platformViewsController);
FlutterLoader flutterLoader = mock(FlutterLoader.class);
FakeFlutterPlugin fakePlugin1 = new FakeFlutterPlugin();
FakeFlutterPlugin fakePlugin2 = new FakeFlutterPlugin();
FlutterEngineConnectionRegistry registry =
new FlutterEngineConnectionRegistry(context, flutterEngine, flutterLoader, null);
// Verify that the registry doesn't think it contains our plugin yet.
assertFalse(registry.has(fakePlugin1.getClass()));
// Add our plugin to the registry.
registry.add(fakePlugin1);
// Verify that the registry now thinks it contains our plugin.
assertTrue(registry.has(fakePlugin1.getClass()));
assertEquals(1, fakePlugin1.attachmentCallCount);
// Add a different instance of the same plugin class.
registry.add(fakePlugin2);
// Verify that the registry did not detach the 1st plugin, and
// it did not attach the 2nd plugin.
assertEquals(1, fakePlugin1.attachmentCallCount);
assertEquals(0, fakePlugin1.detachmentCallCount);
assertEquals(0, fakePlugin2.attachmentCallCount);
assertEquals(0, fakePlugin2.detachmentCallCount);
}
@Test
public void activityResultListenerCanBeRemovedFromListener() {
Context context = mock(Context.class);
FlutterEngine flutterEngine = mock(FlutterEngine.class);
PlatformViewsController platformViewsController = mock(PlatformViewsController.class);
when(flutterEngine.getPlatformViewsController()).thenReturn(platformViewsController);
FlutterLoader flutterLoader = mock(FlutterLoader.class);
ExclusiveAppComponent appComponent = mock(ExclusiveAppComponent.class);
Activity activity = mock(Activity.class);
when(appComponent.getAppComponent()).thenReturn(activity);
Intent intent = mock(Intent.class);
when(activity.getIntent()).thenReturn(intent);
Lifecycle lifecycle = mock(Lifecycle.class);
AtomicBoolean isFirstCall = new AtomicBoolean(true);
// Set up the environment to get the required internal data
FlutterEngineConnectionRegistry registry =
new FlutterEngineConnectionRegistry(context, flutterEngine, flutterLoader, null);
FakeActivityAwareFlutterPlugin fakePlugin = new FakeActivityAwareFlutterPlugin();
registry.add(fakePlugin);
registry.attachToActivity(appComponent, lifecycle);
// The binding is now available via `fakePlugin.binding`: Create and add the listeners
FakeActivityResultListener listener1 =
new FakeActivityResultListener(isFirstCall, fakePlugin.binding);
FakeActivityResultListener listener2 =
new FakeActivityResultListener(isFirstCall, fakePlugin.binding);
fakePlugin.binding.addActivityResultListener(listener1);
fakePlugin.binding.addActivityResultListener(listener2);
// fire the onActivityResult which should invoke both listeners
registry.onActivityResult(0, 0, intent);
assertEquals(1, listener1.callCount);
assertEquals(1, listener2.callCount);
// fire it again to check if the first called listener was removed
registry.onActivityResult(0, 0, intent);
// The order of the listeners in the HashSet is random: So just check the sum of calls
assertEquals(3, listener1.callCount + listener2.callCount);
}
@Test
public void softwareRendering() {
Context context = mock(Context.class);
FlutterEngine flutterEngine = mock(FlutterEngine.class);
PlatformViewsController platformViewsController = mock(PlatformViewsController.class);
when(flutterEngine.getPlatformViewsController()).thenReturn(platformViewsController);
FlutterLoader flutterLoader = mock(FlutterLoader.class);
ExclusiveAppComponent appComponent = mock(ExclusiveAppComponent.class);
Activity activity = mock(Activity.class);
when(appComponent.getAppComponent()).thenReturn(activity);
// Test attachToActivity with an Activity that has no Intent.
FlutterEngineConnectionRegistry registry =
new FlutterEngineConnectionRegistry(context, flutterEngine, flutterLoader, null);
registry.attachToActivity(appComponent, mock(Lifecycle.class));
verify(platformViewsController).setSoftwareRendering(false);
Intent intent = mock(Intent.class);
when(intent.getBooleanExtra("enable-software-rendering", false)).thenReturn(false);
when(activity.getIntent()).thenReturn(intent);
registry.attachToActivity(appComponent, mock(Lifecycle.class));
verify(platformViewsController, times(2)).setSoftwareRendering(false);
when(intent.getBooleanExtra("enable-software-rendering", false)).thenReturn(true);
registry.attachToActivity(appComponent, mock(Lifecycle.class));
verify(platformViewsController).setSoftwareRendering(true);
}
private static class FakeFlutterPlugin implements FlutterPlugin {
public int attachmentCallCount = 0;
public int detachmentCallCount = 0;
@Override
public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) {
attachmentCallCount += 1;
}
@Override
public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
detachmentCallCount += 1;
}
}
private static class FakeActivityAwareFlutterPlugin implements FlutterPlugin, ActivityAware {
public ActivityPluginBinding binding;
@Override
public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) {}
@Override
public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {}
@Override
public void onAttachedToActivity(final ActivityPluginBinding binding) {
this.binding = binding;
}
@Override
public void onDetachedFromActivityForConfigChanges() {}
@Override
public void onReattachedToActivityForConfigChanges(final ActivityPluginBinding binding) {}
@Override
public void onDetachedFromActivity() {}
}
private static class FakeActivityResultListener implements PluginRegistry.ActivityResultListener {
public int callCount = 0;
private final AtomicBoolean isFirstCall;
private final ActivityPluginBinding binding;
public FakeActivityResultListener(AtomicBoolean isFirstCall, ActivityPluginBinding binding) {
this.isFirstCall = isFirstCall;
this.binding = binding;
}
@Override
public boolean onActivityResult(
final int requestCode, final int resultCode, final Intent data) {
callCount++;
if (isFirstCall.get()) {
isFirstCall.set(false);
binding.removeActivityResultListener(this);
}
return false;
}
}
}