Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
FlutterLoaderTest.java
Go to the documentation of this file.
1// Copyright 2013 The Flutter 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
5package io.flutter.embedding.engine.loader;
6
7import static android.os.Looper.getMainLooper;
8import static io.flutter.Build.API_LEVELS;
9import static junit.framework.TestCase.assertFalse;
10import static junit.framework.TestCase.assertTrue;
11import static org.mockito.Mockito.any;
12import static org.mockito.Mockito.anyLong;
13import static org.mockito.Mockito.anyString;
14import static org.mockito.Mockito.eq;
15import static org.mockito.Mockito.mock;
16import static org.mockito.Mockito.never;
17import static org.mockito.Mockito.spy;
18import static org.mockito.Mockito.times;
19import static org.mockito.Mockito.verify;
20import static org.robolectric.Shadows.shadowOf;
21
22import android.annotation.TargetApi;
23import android.app.ActivityManager;
24import android.content.Context;
25import android.os.Bundle;
26import android.util.DisplayMetrics;
27import androidx.test.core.app.ApplicationProvider;
28import androidx.test.ext.junit.runners.AndroidJUnit4;
29import io.flutter.embedding.engine.FlutterJNI;
30import java.util.Arrays;
31import java.util.List;
32import java.util.concurrent.Callable;
33import java.util.concurrent.ExecutorService;
34import org.junit.Test;
35import org.junit.runner.RunWith;
36import org.mockito.ArgumentCaptor;
37import org.robolectric.annotation.Config;
38
39@Config(manifest = Config.NONE)
40@RunWith(AndroidJUnit4.class)
41public class FlutterLoaderTest {
42 private final Context ctx = ApplicationProvider.getApplicationContext();
43
44 @Test
46 FlutterLoader flutterLoader = new FlutterLoader();
47 assertFalse(flutterLoader.initialized());
48 }
49
50 @Test
52 FlutterJNI mockFlutterJNI = mock(FlutterJNI.class);
53 FlutterLoader flutterLoader = new FlutterLoader(mockFlutterJNI);
54
55 assertFalse(flutterLoader.initialized());
56 flutterLoader.startInitialization(ctx);
57 flutterLoader.ensureInitializationComplete(ctx, null);
58 shadowOf(getMainLooper()).idle();
59 assertTrue(flutterLoader.initialized());
60 verify(mockFlutterJNI, times(1)).loadLibrary();
61 verify(mockFlutterJNI, times(1)).updateRefreshRate();
62 }
63
64 @Test
66 FlutterJNI mockFlutterJNI = mock(FlutterJNI.class);
67 FlutterLoader flutterLoader = new FlutterLoader(mockFlutterJNI);
68
69 assertFalse(flutterLoader.initialized());
70 flutterLoader.startInitialization(ctx);
71 flutterLoader.ensureInitializationComplete(ctx, null);
72 shadowOf(getMainLooper()).idle();
73
74 ActivityManager activityManager =
75 (ActivityManager) ctx.getSystemService(Context.ACTIVITY_SERVICE);
76 ActivityManager.MemoryInfo memInfo = new ActivityManager.MemoryInfo();
77 activityManager.getMemoryInfo(memInfo);
78 int oldGenHeapSizeMegaBytes = (int) (memInfo.totalMem / 1e6 / 2);
79 final String oldGenHeapArg = "--old-gen-heap-size=" + oldGenHeapSizeMegaBytes;
80 ArgumentCaptor<String[]> shellArgsCaptor = ArgumentCaptor.forClass(String[].class);
81 verify(mockFlutterJNI, times(1))
82 .init(eq(ctx), shellArgsCaptor.capture(), anyString(), anyString(), anyString(), anyLong());
83 List<String> arguments = Arrays.asList(shellArgsCaptor.getValue());
84 assertTrue(arguments.contains(oldGenHeapArg));
85 }
86
87 @Test
89 FlutterJNI mockFlutterJNI = mock(FlutterJNI.class);
90 FlutterLoader flutterLoader = new FlutterLoader(mockFlutterJNI);
91
92 assertFalse(flutterLoader.initialized());
93 flutterLoader.startInitialization(ctx);
94 flutterLoader.ensureInitializationComplete(ctx, null);
95 shadowOf(getMainLooper()).idle();
96
97 DisplayMetrics displayMetrics = ctx.getResources().getDisplayMetrics();
98 int screenWidth = displayMetrics.widthPixels;
99 int screenHeight = displayMetrics.heightPixels;
100 int resourceCacheMaxBytesThreshold = screenWidth * screenHeight * 12 * 4;
101 final String resourceCacheMaxBytesThresholdArg =
102 "--resource-cache-max-bytes-threshold=" + resourceCacheMaxBytesThreshold;
103 ArgumentCaptor<String[]> shellArgsCaptor = ArgumentCaptor.forClass(String[].class);
104 verify(mockFlutterJNI, times(1))
105 .init(eq(ctx), shellArgsCaptor.capture(), anyString(), anyString(), anyString(), anyLong());
106 List<String> arguments = Arrays.asList(shellArgsCaptor.getValue());
107 assertTrue(arguments.contains(resourceCacheMaxBytesThresholdArg));
108 }
109
110 @Test
112 FlutterJNI mockFlutterJNI = mock(FlutterJNI.class);
113 FlutterLoader flutterLoader = new FlutterLoader(mockFlutterJNI);
114
115 assertFalse(flutterLoader.initialized());
116 flutterLoader.startInitialization(ctx);
117 flutterLoader.ensureInitializationComplete(ctx, null);
118 shadowOf(getMainLooper()).idle();
119
120 final String leakVMArg = "--leak-vm=true";
121 ArgumentCaptor<String[]> shellArgsCaptor = ArgumentCaptor.forClass(String[].class);
122 verify(mockFlutterJNI, times(1))
123 .init(eq(ctx), shellArgsCaptor.capture(), anyString(), anyString(), anyString(), anyLong());
124 List<String> arguments = Arrays.asList(shellArgsCaptor.getValue());
125 assertTrue(arguments.contains(leakVMArg));
126 }
127
128 @Test
130 FlutterJNI mockFlutterJNI = mock(FlutterJNI.class);
131 FlutterLoader flutterLoader = new FlutterLoader(mockFlutterJNI);
132 Bundle metaData = new Bundle();
133 metaData.putBoolean("io.flutter.embedding.android.LeakVM", false);
134 ctx.getApplicationInfo().metaData = metaData;
135
136 FlutterLoader.Settings settings = new FlutterLoader.Settings();
137 assertFalse(flutterLoader.initialized());
138 flutterLoader.startInitialization(ctx, settings);
139 flutterLoader.ensureInitializationComplete(ctx, null);
140 shadowOf(getMainLooper()).idle();
141
142 final String leakVMArg = "--leak-vm=false";
143 ArgumentCaptor<String[]> shellArgsCaptor = ArgumentCaptor.forClass(String[].class);
144 verify(mockFlutterJNI, times(1))
145 .init(eq(ctx), shellArgsCaptor.capture(), anyString(), anyString(), anyString(), anyLong());
146 List<String> arguments = Arrays.asList(shellArgsCaptor.getValue());
147 assertTrue(arguments.contains(leakVMArg));
148 }
149
150 @Test
152 FlutterJNI mockFlutterJNI = mock(FlutterJNI.class);
153 ExecutorService mockExecutorService = mock(ExecutorService.class);
154 FlutterLoader flutterLoader = new FlutterLoader(mockFlutterJNI, mockExecutorService);
155
156 assertFalse(flutterLoader.initialized());
157 flutterLoader.startInitialization(ctx);
158 verify(mockExecutorService, times(1)).submit(any(Callable.class));
159 }
160
161 @Test
163 FlutterJNI mockFlutterJNI = mock(FlutterJNI.class);
164 FlutterLoader flutterLoader = new FlutterLoader(mockFlutterJNI);
165
166 assertFalse(flutterLoader.initialized());
167 flutterLoader.startInitialization(ctx);
168 flutterLoader.ensureInitializationComplete(ctx, null);
169 shadowOf(getMainLooper()).idle();
170
171 final String enableImpellerArg = "--enable-impeller";
172 ArgumentCaptor<String[]> shellArgsCaptor = ArgumentCaptor.forClass(String[].class);
173 verify(mockFlutterJNI, times(1))
174 .init(eq(ctx), shellArgsCaptor.capture(), anyString(), anyString(), anyString(), anyLong());
175 List<String> arguments = Arrays.asList(shellArgsCaptor.getValue());
176 assertFalse(arguments.contains(enableImpellerArg));
177 }
178
179 @Test
181 FlutterJNI mockFlutterJNI = mock(FlutterJNI.class);
182 FlutterLoader flutterLoader = new FlutterLoader(mockFlutterJNI);
183
184 assertFalse(flutterLoader.initialized());
185 flutterLoader.startInitialization(ctx);
186 flutterLoader.ensureInitializationComplete(ctx, null);
187 shadowOf(getMainLooper()).idle();
188
189 final String enableVulkanValidationArg = "--enable-vulkan-validation";
190 ArgumentCaptor<String[]> shellArgsCaptor = ArgumentCaptor.forClass(String[].class);
191 verify(mockFlutterJNI, times(1))
192 .init(eq(ctx), shellArgsCaptor.capture(), anyString(), anyString(), anyString(), anyLong());
193 List<String> arguments = Arrays.asList(shellArgsCaptor.getValue());
194 assertFalse(arguments.contains(enableVulkanValidationArg));
195 }
196
197 @Test
199 FlutterJNI mockFlutterJNI = mock(FlutterJNI.class);
200 FlutterLoader flutterLoader = new FlutterLoader(mockFlutterJNI);
201 Bundle metaData = new Bundle();
202 metaData.putBoolean("io.flutter.embedding.android.EnableImpeller", true);
203 ctx.getApplicationInfo().metaData = metaData;
204
205 FlutterLoader.Settings settings = new FlutterLoader.Settings();
206 assertFalse(flutterLoader.initialized());
207 flutterLoader.startInitialization(ctx, settings);
208 flutterLoader.ensureInitializationComplete(ctx, null);
209 shadowOf(getMainLooper()).idle();
210
211 final String enableImpellerArg = "--enable-impeller";
212 ArgumentCaptor<String[]> shellArgsCaptor = ArgumentCaptor.forClass(String[].class);
213 verify(mockFlutterJNI, times(1))
214 .init(eq(ctx), shellArgsCaptor.capture(), anyString(), anyString(), anyString(), anyLong());
215 List<String> arguments = Arrays.asList(shellArgsCaptor.getValue());
216 assertTrue(arguments.contains(enableImpellerArg));
217 }
218
219 @Test
220 @TargetApi(API_LEVELS.API_23)
221 @Config(sdk = API_LEVELS.API_23)
222 public void itReportsFpsToVsyncWaiterAndroidM() {
223 FlutterJNI mockFlutterJNI = mock(FlutterJNI.class);
224 FlutterLoader flutterLoader = new FlutterLoader(mockFlutterJNI);
225
226 Context appContextSpy = spy(ctx);
227
228 assertFalse(flutterLoader.initialized());
229 flutterLoader.startInitialization(appContextSpy);
230 verify(appContextSpy, never()).getSystemService(anyString());
231 }
232}
static SkISize times(const SkISize &size, float factor)
static bool eq(const SkM44 &a, const SkM44 &b, float tol)
Definition M44Test.cpp:18
Type::kYUV Type::kRGBA() int(0.7 *637)
void ensureInitializationComplete( @NonNull Context applicationContext, @Nullable String[] args)
void startInitialization(@NonNull Context applicationContext)