1package io.flutter.plugin.text;
3import static io.flutter.Build.API_LEVELS;
4import static org.junit.Assert.assertEquals;
5import static org.mockito.Mockito.any;
6import static org.mockito.Mockito.anyInt;
7import static org.mockito.Mockito.mock;
8import static org.mockito.Mockito.times;
9import static org.mockito.Mockito.verify;
10import static org.mockito.Mockito.when;
12import android.annotation.TargetApi;
15import android.content.pm.ActivityInfo;
16import android.content.pm.PackageItemInfo;
17import android.content.pm.PackageManager;
18import android.content.pm.ResolveInfo;
19import androidx.annotation.RequiresApi;
20import androidx.test.ext.junit.runners.AndroidJUnit4;
21import io.flutter.embedding.engine.dart.DartExecutor;
22import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
23import io.flutter.embedding.engine.systemchannels.ProcessTextChannel;
24import io.flutter.plugin.common.BinaryMessenger;
25import io.flutter.plugin.common.MethodCall;
26import io.flutter.plugin.common.MethodChannel;
27import io.flutter.plugin.common.StandardMethodCodec;
28import java.lang.reflect.Field;
29import java.nio.ByteBuffer;
30import java.util.ArrayList;
31import java.util.Arrays;
35import org.junit.runner.RunWith;
36import org.mockito.ArgumentCaptor;
38@RunWith(AndroidJUnit4.class)
39@TargetApi(API_LEVELS.API_24)
40@RequiresApi(API_LEVELS.API_24)
43 private static void sendToBinaryMessageHandler(
47 binaryMessageHandler.onMessage(
51 @SuppressWarnings(
"deprecation")
58 ProcessTextChannel.ProcessTextMethodHandler mockHandler =
60 PackageManager mockPackageManager = mock(PackageManager.class);
66 verify(mockBinaryMessenger,
times(1))
67 .setMessageHandler(
any(String.class), binaryMessageHandlerCaptor.capture());
69 BinaryMessenger.BinaryMessageHandler binaryMessageHandler =
70 binaryMessageHandlerCaptor.getValue();
72 sendToBinaryMessageHandler(binaryMessageHandler,
"ProcessText.queryTextActions",
null);
74 verify(mockHandler).queryTextActions();
77 @SuppressWarnings(
"deprecation")
82 PackageManager mockPackageManager = mock(PackageManager.class);
87 ResolveInfo action1 = createFakeResolveInfo(
"Action1", mockPackageManager);
88 ResolveInfo action2 = createFakeResolveInfo(
"Action2", mockPackageManager);
89 List<ResolveInfo> infos =
new ArrayList<ResolveInfo>(Arrays.asList(action1, action2));
90 Intent intent =
new Intent().setAction(Intent.ACTION_PROCESS_TEXT).setType(
"text/plain");
91 when(mockPackageManager.queryIntentActivities(
92 any(Intent.class),
any(PackageManager.ResolveInfoFlags.class)))
98 final String action1Id =
"mockActivityName.Action1";
99 final String action2Id =
"mockActivityName.Action2";
100 assertEquals(textActions, Map.of(action1Id,
"Action1", action2Id,
"Action2"));
103 @SuppressWarnings(
"deprecation")
108 PackageManager mockPackageManager = mock(PackageManager.class);
113 ResolveInfo action1 = createFakeResolveInfo(
"Action1", mockPackageManager);
114 ResolveInfo action2 = createFakeResolveInfo(
"Action2", mockPackageManager);
115 List<ResolveInfo> infos =
new ArrayList<ResolveInfo>(Arrays.asList(action1, action2));
116 when(mockPackageManager.queryIntentActivities(
117 any(Intent.class),
any(PackageManager.ResolveInfoFlags.class)))
123 final String action1Id =
"mockActivityName.Action1";
124 final String action2Id =
"mockActivityName.Action2";
125 assertEquals(textActions, Map.of(action1Id,
"Action1", action2Id,
"Action2"));
129 Activity mockActivity = mock(Activity.class);
130 when(mockActivityPluginBinding.
getActivity()).thenReturn(mockActivity);
134 String textToBeProcessed =
"Flutter!";
139 ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
140 verify(mockActivity,
times(1)).startActivityForResult(intentCaptor.capture(), anyInt());
141 Intent intent = intentCaptor.getValue();
142 assertEquals(intent.getStringExtra(Intent.EXTRA_PROCESS_TEXT), textToBeProcessed);
145 Intent resultIntent =
new Intent();
149 verify(
result).success(
null);
152 @SuppressWarnings(
"deprecation")
157 PackageManager mockPackageManager = mock(PackageManager.class);
162 ResolveInfo action1 = createFakeResolveInfo(
"Action1", mockPackageManager);
163 ResolveInfo action2 = createFakeResolveInfo(
"Action2", mockPackageManager);
164 List<ResolveInfo> infos =
new ArrayList<ResolveInfo>(Arrays.asList(action1, action2));
165 when(mockPackageManager.queryIntentActivities(
166 any(Intent.class),
any(PackageManager.ResolveInfoFlags.class)))
172 final String action1Id =
"mockActivityName.Action1";
173 final String action2Id =
"mockActivityName.Action2";
174 assertEquals(textActions, Map.of(action1Id,
"Action1", action2Id,
"Action2"));
178 Activity mockActivity = mock(Activity.class);
179 when(mockActivityPluginBinding.
getActivity()).thenReturn(mockActivity);
183 String textToBeProcessed =
"Flutter!";
188 ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
189 verify(mockActivity,
times(1)).startActivityForResult(intentCaptor.capture(), anyInt());
190 Intent intent = intentCaptor.getValue();
191 assertEquals(intent.getStringExtra(Intent.EXTRA_PROCESS_TEXT), textToBeProcessed);
194 String processedText =
"Flutter!!!";
195 Intent resultIntent =
new Intent();
196 resultIntent.putExtra(Intent.EXTRA_PROCESS_TEXT, processedText);
200 verify(
result).success(processedText);
203 @SuppressWarnings(
"deprecation")
208 PackageManager mockPackageManager = mock(PackageManager.class);
213 ResolveInfo action1 = createFakeResolveInfo(
"Action1", mockPackageManager);
214 ResolveInfo action2 = createFakeResolveInfo(
"Action2", mockPackageManager);
215 List<ResolveInfo> infos =
new ArrayList<ResolveInfo>(Arrays.asList(action1, action2));
216 when(mockPackageManager.queryIntentActivities(
217 any(Intent.class),
any(PackageManager.ResolveInfoFlags.class)))
223 final String action1Id =
"mockActivityName.Action1";
224 final String action2Id =
"mockActivityName.Action2";
225 assertEquals(textActions, Map.of(action1Id,
"Action1", action2Id,
"Action2"));
229 Activity mockActivity = mock(Activity.class);
230 when(mockActivityPluginBinding.
getActivity()).thenReturn(mockActivity);
234 String textToBeProcessed =
"Flutter!";
239 ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
240 verify(mockActivity,
times(1)).startActivityForResult(intentCaptor.capture(), anyInt());
241 Intent intent = intentCaptor.getValue();
242 assertEquals(intent.getStringExtra(Intent.EXTRA_PROCESS_TEXT), textToBeProcessed);
245 final int externalRequestCode = 42;
246 processTextPlugin.
onActivityResult(externalRequestCode, Activity.RESULT_OK,
new Intent());
249 String processedText =
"Flutter!!!";
250 Intent resultIntent =
new Intent();
251 resultIntent.putExtra(Intent.EXTRA_PROCESS_TEXT, processedText);
255 verify(
result).success(processedText);
258 private ResolveInfo createFakeResolveInfo(String label, PackageManager mockPackageManager) {
259 ResolveInfo resolveInfo = mock(ResolveInfo.class);
260 ActivityInfo activityInfo =
new ActivityInfo();
261 when(resolveInfo.loadLabel(mockPackageManager)).thenReturn(label);
265 Field activityField = ResolveInfo.class.getDeclaredField(
"activityInfo");
266 activityField.setAccessible(
true);
267 activityField.set(resolveInfo, activityInfo);
268 Field packageNameField = PackageItemInfo.class.getDeclaredField(
"packageName");
269 packageNameField.setAccessible(
true);
270 packageNameField.set(activityInfo,
"mockActivityPackageName");
271 Field nameField = PackageItemInfo.class.getDeclaredField(
"name");
272 nameField.setAccessible(
true);
273 nameField.set(activityInfo,
"mockActivityName." + label);
274 }
catch (Exception ex) {
static SkISize times(const SkISize &size, float factor)
void setMethodHandler(@Nullable ProcessTextMethodHandler processTextMethodHandler)
ByteBuffer encodeMethodCall(@NonNull MethodCall methodCall)
static final StandardMethodCodec INSTANCE
void respondsToProcessTextChannelMessage()
void performQueryTextActions()
void performProcessTextActionWithReturnedValue()
void doNotCrashOnNonRelatedActivityResult()
void performProcessTextActionWithNoReturnedValue()
void processTextAction( @NonNull String id, @NonNull String text, @NonNull boolean readOnly, @NonNull MethodChannel.Result result)
void onAttachedToActivity(@NonNull ActivityPluginBinding binding)
boolean onActivityResult(int requestCode, int resultCode, @Nullable Intent intent)
Map< String, String > queryTextActions()
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
SIT bool any(const Vec< 1, T > &x)