1package test.io.flutter.embedding.engine;
3import static org.junit.Assert.assertEquals;
4import static org.junit.Assert.assertNotNull;
5import static org.junit.Assert.assertTrue;
6import static org.mockito.Mockito.any;
7import static org.mockito.Mockito.anyInt;
8import static org.mockito.Mockito.atLeast;
9import static org.mockito.Mockito.doAnswer;
10import static org.mockito.Mockito.doReturn;
11import static org.mockito.Mockito.eq;
12import static org.mockito.Mockito.mock;
13import static org.mockito.Mockito.never;
14import static org.mockito.Mockito.times;
15import static org.mockito.Mockito.verify;
16import static org.mockito.Mockito.when;
20import android.content.pm.PackageManager.NameNotFoundException;
21import android.content.res.Configuration;
22import android.content.res.Resources;
24import androidx.test.core.app.ApplicationProvider;
25import androidx.test.ext.junit.runners.AndroidJUnit4;
26import io.flutter.FlutterInjector;
27import io.flutter.embedding.engine.FlutterEngine;
28import io.flutter.embedding.engine.FlutterEngine.EngineLifecycleListener;
29import io.flutter.embedding.engine.FlutterEngineGroup;
30import io.flutter.embedding.engine.FlutterJNI;
31import io.flutter.embedding.engine.loader.FlutterLoader;
32import io.flutter.embedding.engine.plugins.FlutterPlugin;
33import io.flutter.embedding.engine.plugins.PluginRegistry;
34import io.flutter.plugin.platform.PlatformViewsController;
35import io.flutter.plugins.GeneratedPluginRegistrant;
37import org.junit.After;
38import org.junit.Before;
40import org.junit.runner.RunWith;
41import org.mockito.ArgumentCaptor;
42import org.mockito.Mock;
43import org.mockito.MockitoAnnotations;
44import org.mockito.invocation.InvocationOnMock;
45import org.mockito.stubbing.Answer;
46import org.robolectric.Robolectric;
47import org.robolectric.android.controller.ActivityController;
48import org.robolectric.annotation.Config;
49import org.robolectric.shadows.ShadowLog;
52@RunWith(AndroidJUnit4.class)
54 private final Context ctx = ApplicationProvider.getApplicationContext();
55 private final Context mockContext = mock(Context.class);
61 MockitoAnnotations.openMocks(
this);
63 Resources mockResources = mock(Resources.class);
64 Configuration mockConfiguration = mock(Configuration.class);
65 doReturn(mockResources).when(mockContext).getResources();
66 doReturn(mockConfiguration).when(mockResources).getConfiguration();
67 doReturn(LocaleList.getEmptyLocaleList()).when(mockConfiguration).getLocales();
70 when(flutterJNI.isAttached()).thenAnswer(invocation -> jniAttached);
74 public Object answer(InvocationOnMock invocation)
throws Throwable {
89 GeneratedPluginRegistrant.pluginRegistrationException =
null;
100 assertEquals(1, registeredEngines.size());
101 assertEquals(flutterEngine, registeredEngines.get(0));
107 ActivityController<Activity> activityController = Robolectric.buildActivity(Activity.class);
109 when(mockFlutterJNI.
isAttached()).thenReturn(
true);
113 new FlutterEngine(activityController.get(), mockFlutterLoader, mockFlutterJNI);
115 verify(mockFlutterJNI,
times(1))
116 .updateDisplayMetrics(
eq(0),
any(Float.class),
any(Float.class),
any(Float.class));
122 when(mockFlutterJNI.
isAttached()).thenReturn(
true);
129 verify(mockFlutterJNI,
times(1))
130 .dispatchPlatformMessage(
eq(
"flutter/localization"),
any(), anyInt(), anyInt());
138 GeneratedPluginRegistrant.pluginRegistrationException =
139 new RuntimeException(
"I'm a bug in the plugin");
146 assertEquals(0, registeredEngines.size());
151 ShadowLog.getLogsForTag(
"GeneratedPluginsRegister")
154 .contains(
"Tried to automatically register plugins"));
157 ShadowLog.getLogsForTag(
"GeneratedPluginsRegister").get(1).throwable.getCause());
159 GeneratedPluginRegistrant.pluginRegistrationException =
null;
170 assertTrue(registeredEngines.isEmpty());
186 assertTrue(registeredEngines.isEmpty());
193 when(mockFlutterJNI.
isAttached()).thenReturn(
true);
205 platformViewsController,
210 verify(mockFlutterJNI)
211 .addEngineLifecycleListener(engineLifecycleListenerArgumentCaptor.capture());
212 FlutterEngine.EngineLifecycleListener engineLifecycleListener =
213 engineLifecycleListenerArgumentCaptor.getValue();
214 assertNotNull(engineLifecycleListener);
217 engineLifecycleListener.onPreEngineRestart();
221 verify(platformViewsController,
times(1)).onPreEngineRestart();
234 platformViewsController,
237 verify(platformViewsController,
times(1)).onAttachedToJNI();
240 verify(platformViewsController,
times(1)).onDetachedFromJNI();
245 Context packageContext = mock(Context.class);
247 when(mockContext.createPackageContext(
any(), anyInt())).thenReturn(packageContext);
256 verify(mockContext, atLeast(1)).getApplicationContext();
261 Context packageContext = mock(Context.class);
262 when(mockContext.createPackageContext(
any(), anyInt())).thenReturn(packageContext);
271 verify(packageContext, atLeast(1)).getAssets();
272 verify(mockContext,
times(0)).getAssets();
281 Context packageContext = mock(Context.class);
283 when(mockContext.createPackageContext(
any(), anyInt())).thenReturn(packageContext);
287 verify(mockFlutterLoader,
times(1)).startInitialization(
any());
288 verify(mockFlutterLoader,
times(1)).ensureInitializationComplete(
any(),
any());
294 Context packageContext = mock(Context.class);
296 when(mockContext.createPackageContext(
any(), anyInt())).thenReturn(packageContext);
309 verify(listener,
times(1)).onEngineWillDestroy();
314 Context packageContext = mock(Context.class);
316 when(mockContext.createPackageContext(
any(), anyInt())).thenReturn(packageContext);
317 when(flutterJNI.isAttached()).thenReturn(
true);
327 verify(flutterJNI, never()).attachToNative();
332 Context packageContext = mock(Context.class);
334 when(mockContext.createPackageContext(
any(), anyInt())).thenReturn(packageContext);
335 when(flutterJNI.isAttached()).thenReturn(
true);
350 Context packageContext = mock(Context.class);
352 when(mockContext.createPackageContext(
any(), anyInt())).thenReturn(packageContext);
353 when(flutterJNI.isAttached()).thenReturn(
true);
372 registry.add(mockPlugin);
373 verify(mockPlugin).onAttachedToEngine(pluginBindingCaptor.capture());
374 assertNotNull(pluginBindingCaptor.getValue());
375 assertEquals(mockGroup, pluginBindingCaptor.getValue().getEngineGroup());
static SkISize times(const SkISize &size, float factor)
static bool eq(const SkM44 &a, const SkM44 &b, float tol)
Builder setFlutterLoader(@NonNull FlutterLoader flutterLoader)
static void setInstance(@NonNull FlutterInjector injector)
DartExecutor getDartExecutor()
PluginRegistry getPlugins()
void addEngineLifecycleListener(@NonNull EngineLifecycleListener listener)
boolean isExecutingDart()
boolean automaticallyRegisterPlugins()
static void clearRegisteredEngines()
static RuntimeException pluginRegistrationException
static List< FlutterEngine > getRegisteredEngines()
void itComesWithARunningDartExecutorIfJNIIsAlreadyAttached()
void itUsesApplicationContext()
void itCanUseFlutterLoaderInjectionViaFlutterInjector()
void itUpdatesDisplayMetricsOnConstructionWithActivityContext()
void itUsesPackageContextForAssetManager()
void itSendLocalesOnEngineInit()
void itNotifiesPlatformViewsControllerWhenDevHotRestart()
void itDoesNotAutomaticallyRegistersPluginsWhenFlutterLoaderDisablesIt()
void passesEngineGroupToPlugins()
void itNotifiesListenersForDestruction()
void itDoesNotAttachAgainWhenBuiltWithAnAttachedJNI()
void itAutomaticallyRegistersPluginsByDefault()
void itNotifiesPlatformViewsControllerAboutJNILifecycle()
void itDoesNotAutomaticallyRegistersPluginsWhenFlutterEngineDisablesIt()
void itCatchesAndDisplaysRegistrationExceptions()
SIT bool any(const Vec< 1, T > &x)