5package io.flutter.plugin.platform;
7import static android.view.WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS;
8import static android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS;
9import static io.flutter.Build.API_LEVELS;
10import static org.junit.Assert.assertEquals;
11import static org.junit.Assert.assertFalse;
12import static org.junit.Assert.assertNotNull;
13import static org.junit.Assert.assertNull;
14import static org.junit.Assert.assertTrue;
15import static org.junit.Assert.fail;
16import static org.mockito.Mockito.any;
17import static org.mockito.Mockito.anyBoolean;
18import static org.mockito.Mockito.doThrow;
19import static org.mockito.Mockito.mock;
20import static org.mockito.Mockito.mockStatic;
21import static org.mockito.Mockito.never;
22import static org.mockito.Mockito.spy;
23import static org.mockito.Mockito.times;
24import static org.mockito.Mockito.verify;
25import static org.mockito.Mockito.when;
29import android.content.ClipboardManager;
30import android.content.ContentResolver;
33import android.content.res.AssetFileDescriptor;
38import android.view.WindowInsetsController;
39import android.view.WindowManager;
40import androidx.activity.OnBackPressedCallback;
41import androidx.fragment.app.FragmentActivity;
42import androidx.test.core.app.ApplicationProvider;
43import io.flutter.embedding.engine.systemchannels.PlatformChannel;
44import io.flutter.embedding.engine.systemchannels.PlatformChannel.Brightness;
45import io.flutter.embedding.engine.systemchannels.PlatformChannel.ClipboardContentFormat;
46import io.flutter.embedding.engine.systemchannels.PlatformChannel.SystemChromeStyle;
47import io.flutter.plugin.platform.PlatformPlugin.PlatformPluginDelegate;
48import java.io.IOException;
49import java.util.concurrent.atomic.AtomicBoolean;
51import org.junit.runner.RunWith;
52import org.mockito.ArgumentCaptor;
53import org.mockito.MockedStatic;
54import org.robolectric.Robolectric;
55import org.robolectric.RobolectricTestRunner;
56import org.robolectric.android.controller.ActivityController;
57import org.robolectric.annotation.Config;
58import org.robolectric.shadows.ShadowLooper;
61@RunWith(RobolectricTestRunner.class)
63 private final Context ctx = ApplicationProvider.getApplicationContext();
66 private ClipboardManager clipboardManager;
70 clipboardManager = spy(ctx.getSystemService(ClipboardManager.class));
71 when(mockActivity.getSystemService(Context.CLIPBOARD_SERVICE)).thenReturn(clipboardManager);
77 View fakeDecorView = mock(View.class);
78 Window fakeWindow = mock(Window.class);
79 Activity mockActivity = mock(Activity.class);
80 when(fakeWindow.getDecorView()).thenReturn(fakeDecorView);
81 when(mockActivity.getWindow()).thenReturn(fakeWindow);
83 setUpForTextClipboardTests(mockActivity);
86 ClipData
clip = ClipData.newPlainText(
"label",
"Text");
88 clipboardManager.setPrimaryClip(
clip);
94 View fakeDecorView = mock(View.class);
95 Window fakeWindow = mock(Window.class);
96 Activity mockActivity = mock(Activity.class);
97 when(fakeWindow.getDecorView()).thenReturn(fakeDecorView);
98 when(mockActivity.getWindow()).thenReturn(fakeWindow);
100 setUpForTextClipboardTests(mockActivity);
101 ContentResolver contentResolver = mock(ContentResolver.class);
102 ClipData.Item mockItem = mock(ClipData.Item.class);
103 Uri mockUri = mock(Uri.class);
104 AssetFileDescriptor mockAssetFileDescriptor = mock(AssetFileDescriptor.class);
106 when(mockActivity.getContentResolver()).thenReturn(contentResolver);
107 when(mockUri.getScheme()).thenReturn(
"content");
108 when(mockItem.getText()).thenReturn(
null);
109 when(mockItem.getUri()).thenReturn(mockUri);
110 when(contentResolver.openTypedAssetFileDescriptor(
any(Uri.class),
any(),
any()))
111 .thenReturn(mockAssetFileDescriptor);
112 when(mockItem.coerceToText(mockActivity)).thenReturn(
"something non-null");
113 doThrow(
new IOException()).when(mockAssetFileDescriptor).close();
115 ClipData
clip =
new ClipData(
"label",
new String[0], mockItem);
118 clipboardManager.setPrimaryClip(
clip);
125 View fakeDecorView = mock(View.class);
126 Window fakeWindow = mock(Window.class);
127 Activity mockActivity = mock(Activity.class);
128 when(fakeWindow.getDecorView()).thenReturn(fakeDecorView);
129 when(mockActivity.getWindow()).thenReturn(fakeWindow);
131 setUpForTextClipboardTests(mockActivity);
132 ContentResolver contentResolver = mock(ContentResolver.class);
133 ClipData.Item mockItem = mock(ClipData.Item.class);
134 Uri mockUri = mock(Uri.class);
136 when(mockActivity.getContentResolver()).thenReturn(contentResolver);
137 when(mockUri.getScheme()).thenReturn(
"content");
138 when(mockItem.getText()).thenReturn(
null);
139 when(mockItem.getUri()).thenReturn(mockUri);
140 when(contentResolver.openTypedAssetFileDescriptor(
any(Uri.class),
any(),
any()))
141 .thenReturn(mock(AssetFileDescriptor.class));
142 when(mockItem.coerceToText(mockActivity)).thenReturn(
"something non-null");
144 ClipData
clip =
new ClipData(
"label",
new String[0], mockItem);
147 clipboardManager.setPrimaryClip(
clip);
154 View fakeDecorView = mock(View.class);
155 Window fakeWindow = mock(Window.class);
156 Activity mockActivity = mock(Activity.class);
157 when(fakeWindow.getDecorView()).thenReturn(fakeDecorView);
158 when(mockActivity.getWindow()).thenReturn(fakeWindow);
160 setUpForTextClipboardTests(mockActivity);
161 ContentResolver contentResolver = ctx.getContentResolver();
163 when(mockActivity.getContentResolver()).thenReturn(contentResolver);
165 Uri uri = Uri.parse(
"content://media/external_primary/images/media/");
166 ClipData
clip = ClipData.newUri(contentResolver,
"URI", uri);
168 clipboardManager.setPrimaryClip(
clip);
174 View fakeDecorView = mock(View.class);
175 Window fakeWindow = mock(Window.class);
176 Activity mockActivity = mock(Activity.class);
177 when(fakeWindow.getDecorView()).thenReturn(fakeDecorView);
178 when(mockActivity.getWindow()).thenReturn(fakeWindow);
180 setUpForTextClipboardTests(mockActivity);
181 ContentResolver contentResolver = ctx.getContentResolver();
183 when(mockActivity.getContentResolver()).thenReturn(contentResolver);
185 Uri uri = Uri.parse(
"file:///");
186 ClipData
clip = ClipData.newUri(contentResolver,
"URI", uri);
188 clipboardManager.setPrimaryClip(
clip);
194 View fakeDecorView = mock(View.class);
195 Window fakeWindow = mock(Window.class);
196 Activity mockActivity = mock(Activity.class);
197 when(fakeWindow.getDecorView()).thenReturn(fakeDecorView);
198 when(mockActivity.getWindow()).thenReturn(fakeWindow);
200 setUpForTextClipboardTests(mockActivity);
201 ClipData.Item mockItem = mock(ClipData.Item.class);
203 when(mockItem.getText()).thenReturn(
null);
204 when(mockItem.getUri()).thenReturn(
null);
206 ClipData
clip =
new ClipData(
"label",
new String[0], mockItem);
208 clipboardManager.setPrimaryClip(
clip);
212 @SuppressWarnings(
"deprecation")
217 View fakeDecorView = mock(View.class);
218 Window fakeWindow = mock(Window.class);
219 Activity mockActivity = mock(Activity.class);
220 when(fakeWindow.getDecorView()).thenReturn(fakeDecorView);
221 when(mockActivity.getWindow()).thenReturn(fakeWindow);
223 setUpForTextClipboardTests(mockActivity);
226 ClipData
clip = ClipData.newPlainText(
"label",
"Text");
227 clipboardManager.setPrimaryClip(
clip);
231 clip = ClipData.newPlainText(
"",
"");
232 clipboardManager.setPrimaryClip(
clip);
238 clip = ClipData.newHtmlText(
"motto",
"Don't be evil",
"<b>Don't</b> be evil");
239 clipboardManager.setPrimaryClip(
clip);
243 clip =
new ClipData(
"label",
new String[] {
"text/something"},
new ClipData.Item(
"content"));
244 clipboardManager.setPrimaryClip(
clip);
250 "label",
new String[] {
"application/octet-stream"},
new ClipData.Item(
"content"));
251 clipboardManager.setPrimaryClip(
clip);
256 clipboardManager.clearPrimaryClip();
261 verify(clipboardManager, never()).getPrimaryClip();
262 verify(clipboardManager, never()).getText();
268 View fakeDecorView = mock(View.class);
269 Window fakeWindow = mock(Window.class);
270 Activity mockActivity = mock(Activity.class);
271 when(fakeWindow.getDecorView()).thenReturn(fakeDecorView);
272 when(mockActivity.getWindow()).thenReturn(fakeWindow);
289 verify(fakeWindow).setStatusBarColor(0xFF000000);
290 verify(fakeWindow).setNavigationBarColor(0XFFC70039);
291 verify(fakeWindow).setNavigationBarDividerColor(0XFF006DB3);
292 verify(fakeWindow).setStatusBarContrastEnforced(
true);
293 verify(fakeWindow).setNavigationBarContrastEnforced(
true);
309 verify(fakeWindow).setStatusBarColor(0XFF006DB3);
310 verify(fakeWindow).setNavigationBarColor(0XFF000000);
311 verify(fakeWindow,
times(2)).setNavigationBarDividerColor(0XFF006DB3);
312 verify(fakeWindow).setStatusBarContrastEnforced(
false);
313 verify(fakeWindow).setNavigationBarContrastEnforced(
false);
328 verify(fakeWindow,
times(2)).setStatusBarColor(0XFF006DB3);
329 verify(fakeWindow,
times(2)).setNavigationBarColor(0XFF000000);
330 verify(fakeWindow,
times(3)).setNavigationBarDividerColor(0XFF006DB3);
332 verify(fakeWindow,
times(1)).setStatusBarContrastEnforced(
true);
333 verify(fakeWindow,
times(1)).setNavigationBarContrastEnforced(
true);
334 verify(fakeWindow,
times(1)).setStatusBarContrastEnforced(
false);
335 verify(fakeWindow,
times(1)).setNavigationBarContrastEnforced(
false);
342 View fakeDecorView = mock(View.class);
343 Window fakeWindow = mock(Window.class);
344 Activity mockActivity = mock(Activity.class);
345 when(fakeWindow.getDecorView()).thenReturn(fakeDecorView);
346 when(mockActivity.getWindow()).thenReturn(fakeWindow);
350 WindowInsetsController fakeWindowInsetsController = mock(WindowInsetsController.class);
351 when(fakeWindow.getInsetsController()).thenReturn(fakeWindowInsetsController);
365 verify(fakeWindowInsetsController)
366 .setSystemBarsAppearance(0, APPEARANCE_LIGHT_NAVIGATION_BARS);
380 verify(fakeWindowInsetsController)
381 .setSystemBarsAppearance(
382 APPEARANCE_LIGHT_NAVIGATION_BARS, APPEARANCE_LIGHT_NAVIGATION_BARS);
389 View fakeDecorView = mock(View.class);
390 Window fakeWindow = mock(Window.class);
391 Activity mockActivity = mock(Activity.class);
392 when(fakeWindow.getDecorView()).thenReturn(fakeDecorView);
393 when(mockActivity.getWindow()).thenReturn(fakeWindow);
397 WindowInsetsController fakeWindowInsetsController = mock(WindowInsetsController.class);
398 when(fakeWindow.getInsetsController()).thenReturn(fakeWindowInsetsController);
412 verify(fakeWindowInsetsController).setSystemBarsAppearance(0, APPEARANCE_LIGHT_STATUS_BARS);
426 verify(fakeWindowInsetsController)
427 .setSystemBarsAppearance(APPEARANCE_LIGHT_STATUS_BARS, APPEARANCE_LIGHT_STATUS_BARS);
431 @SuppressWarnings(
"deprecation")
436 View fakeDecorView = mock(View.class);
437 Window fakeWindow = mock(Window.class);
438 Activity mockActivity = mock(Activity.class);
439 when(fakeWindow.getDecorView()).thenReturn(fakeDecorView);
440 when(mockActivity.getWindow()).thenReturn(fakeWindow);
446 verify(fakeDecorView)
447 .setSystemUiVisibility(
448 View.SYSTEM_UI_FLAG_LAYOUT_STABLE
449 | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
450 | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
451 | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
452 | View.SYSTEM_UI_FLAG_FULLSCREEN);
456 verify(fakeDecorView)
457 .setSystemUiVisibility(
458 View.SYSTEM_UI_FLAG_IMMERSIVE
459 | View.SYSTEM_UI_FLAG_LAYOUT_STABLE
460 | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
461 | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
462 | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
463 | View.SYSTEM_UI_FLAG_FULLSCREEN);
467 verify(fakeDecorView)
468 .setSystemUiVisibility(
469 View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
470 | View.SYSTEM_UI_FLAG_LAYOUT_STABLE
471 | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
472 | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
473 | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
474 | View.SYSTEM_UI_FLAG_FULLSCREEN);
480 verify(fakeDecorView)
481 .setSystemUiVisibility(
482 View.SYSTEM_UI_FLAG_LAYOUT_STABLE
483 | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
484 | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
488 @SuppressWarnings(
"deprecation")
492 ActivityController<Activity> controller = Robolectric.buildActivity(Activity.class);
494 Activity fakeActivity = controller.get();
505 .dispatchSystemUiVisibilityChanged(View.SYSTEM_UI_FLAG_FULLSCREEN);
512 ShadowLooper.runUiThreadTasksIncludingDelayedTasks();
515 verify(mockPlatformChannel).systemChromeChanged(
false);
518 @SuppressWarnings(
"deprecation")
522 ActivityController<Activity> controller = Robolectric.buildActivity(Activity.class);
524 Activity fakeActivity = controller.get();
531 fakeActivity.getWindow().getDecorView().dispatchSystemUiVisibilityChanged(0);
538 ShadowLooper.runUiThreadTasksIncludingDelayedTasks();
541 verify(mockPlatformChannel).systemChromeChanged(
true);
544 @SuppressWarnings(
"deprecation")
549 View fakeDecorView = mock(View.class);
550 Window fakeWindow = mock(Window.class);
551 Activity mockActivity = mock(Activity.class);
552 when(fakeWindow.getDecorView()).thenReturn(fakeDecorView);
553 when(mockActivity.getWindow()).thenReturn(fakeWindow);
558 verify(fakeDecorView, never())
559 .setSystemUiVisibility(
560 View.SYSTEM_UI_FLAG_LAYOUT_STABLE
561 | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
562 | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
565 @SuppressWarnings(
"deprecation")
570 View fakeDecorView = mock(View.class);
571 Window fakeWindow = mock(Window.class);
572 Activity mockActivity = mock(Activity.class);
573 when(fakeWindow.getDecorView()).thenReturn(fakeDecorView);
574 when(mockActivity.getWindow()).thenReturn(fakeWindow);
582 verify(fakeWindow).addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
585 WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
586 | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
591 Activity mockActivity = mock(Activity.class);
594 new PlatformPlugin(mockActivity, mockPlatformChannel, mockPlatformPluginDelegate);
598 verify(mockPlatformPluginDelegate,
times(1)).setFrameworkHandlesBack(
true);
603 Activity mockActivity = mock(Activity.class);
609 }
catch (NullPointerException
e) {
611 fail(
"NullPointerException was thrown");
617 Activity mockActivity = mock(Activity.class);
620 new PlatformPlugin(mockActivity, mockPlatformChannel, mockPlatformPluginDelegate);
626 verify(mockPlatformPluginDelegate,
times(1)).popSystemNavigator();
627 verify(mockActivity,
times(1)).finish();
632 Activity mockActivity = mock(Activity.class);
635 new PlatformPlugin(mockActivity, mockPlatformChannel, mockPlatformPluginDelegate);
641 verify(mockPlatformPluginDelegate,
times(1)).popSystemNavigator();
643 verify(mockActivity, never()).finish();
646 @SuppressWarnings(
"deprecation")
652 FragmentActivity activity = spy(Robolectric.setupActivity(FragmentActivity.class));
653 final AtomicBoolean onBackPressedCalled =
new AtomicBoolean(
false);
654 OnBackPressedCallback backCallback =
655 new OnBackPressedCallback(
true) {
657 public void handleOnBackPressed() {
658 onBackPressedCalled.set(
true);
661 activity.getOnBackPressedDispatcher().addCallback(backCallback);
666 new PlatformPlugin(activity, mockPlatformChannel, mockPlatformPluginDelegate);
670 verify(activity, never()).finish();
671 verify(mockPlatformPluginDelegate,
times(1)).popSystemNavigator();
672 assertTrue(onBackPressedCalled.get());
675 @SuppressWarnings(
"deprecation")
680 FragmentActivity activity = spy(Robolectric.setupActivity(FragmentActivity.class));
684 new PlatformPlugin(activity, mockPlatformChannel, mockPlatformPluginDelegate);
688 verify(mockPlatformPluginDelegate,
times(1)).popSystemNavigator();
690 verify(activity, never()).finish();
695 FragmentActivity mockFragmentActivity = mock(FragmentActivity.class);
699 new PlatformPlugin(mockFragmentActivity, mockPlatformChannel, mockPlatformPluginDelegate);
703 verify(mockFragmentActivity,
times(1)).setRequestedOrientation(0);
708 Activity mockActivity = mock(Activity.class);
714 verify(mockActivity,
times(1)).finish();
719 Activity mockActivity = mock(Activity.class);
723 new PlatformPlugin(mockActivity, mockPlatformChannel, mockPlatformPluginDelegate);
727 Intent choosenIntent =
new Intent();
728 MockedStatic<Intent> intentClass = mockStatic(Intent.class);
729 ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
731 .when(() -> Intent.createChooser(intentCaptor.capture(),
any()))
732 .thenReturn(choosenIntent);
734 final String expectedContent =
"Flutter";
738 verify(mockActivity,
times(1)).startActivity(choosenIntent);
742 Intent sendToIntent = intentCaptor.getValue();
743 assertEquals(sendToIntent.getAction(), Intent.ACTION_SEND);
744 assertEquals(sendToIntent.getType(),
"text/plain");
745 assertEquals(sendToIntent.getStringExtra(Intent.EXTRA_TEXT), expectedContent);
static SkISize times(const SkISize &size, float factor)
static void fail(const SkString &err)
static SkPath clip(const SkPath &path, const SkHalfPlane &plane)
def Build(configs, env, options)
SIT bool any(const Vec< 1, T > &x)