diff --git a/shell/platform/android/io/flutter/plugin/platform/PlatformPlugin.java b/shell/platform/android/io/flutter/plugin/platform/PlatformPlugin.java index 58618b2b83247..6dbfedd9bb114 100644 --- a/shell/platform/android/io/flutter/plugin/platform/PlatformPlugin.java +++ b/shell/platform/android/io/flutter/plugin/platform/PlatformPlugin.java @@ -13,6 +13,7 @@ import android.content.Context; import android.content.Intent; import android.content.res.AssetFileDescriptor; +import android.net.Uri; import android.os.Build; import android.view.HapticFeedbackConstants; import android.view.SoundEffectConstants; @@ -520,21 +521,46 @@ private CharSequence getClipboardData(PlatformChannel.ClipboardContentFormat for if (!clipboard.hasPrimaryClip()) return null; - CharSequence charSequence = null; + CharSequence itemText = null; try { ClipData clip = clipboard.getPrimaryClip(); if (clip == null) return null; if (format == null || format == PlatformChannel.ClipboardContentFormat.PLAIN_TEXT) { ClipData.Item item = clip.getItemAt(0); - AssetFileDescriptor assetFileDescriptor = null; - if (item.getUri() != null) - assetFileDescriptor = - activity - .getContentResolver() - .openTypedAssetFileDescriptor(item.getUri(), "text/*", null); - charSequence = item.coerceToText(activity); - if (assetFileDescriptor != null) assetFileDescriptor.close(); - return charSequence; + // First, try getting clipboard data as text; no further processing + // required if so. + itemText = item.getText(); + if (itemText == null) { + // Clipboard data does not contain text, so check whether or not it + // contains a URI to extract text from. + Uri itemUri = item.getUri(); + + if (itemUri == null) { + Log.w( + TAG, "Clipboard item contained no textual content nor a URI to retrieve it from."); + return null; + } + + // Will only try to extract text from URI if it has the content scheme. + String uriScheme = itemUri.getScheme(); + + if (!uriScheme.equals("content")) { + Log.w( + TAG, + "Clipboard item contains a Uri with scheme '" + uriScheme + "'that is unhandled."); + return null; + } + + AssetFileDescriptor assetFileDescriptor = + activity.getContentResolver().openTypedAssetFileDescriptor(itemUri, "text/*", null); + + // Safely return clipboard data coerced into text; will return either + // itemText or text retrieved from its URI. + itemText = item.coerceToText(activity); + if (assetFileDescriptor != null) assetFileDescriptor.close(); + } + + return itemText; } } catch (SecurityException e) { Log.w( @@ -545,10 +571,11 @@ private CharSequence getClipboardData(PlatformChannel.ClipboardContentFormat for e); return null; } catch (FileNotFoundException e) { + Log.w(TAG, "Clipboard text was unable to be received from content URI."); return null; } catch (IOException e) { - Log.w(TAG, "Failed to close AssetFileDescriptor while accessing clipboard data.", e); - return charSequence; + Log.w(TAG, "Failed to close AssetFileDescriptor while trying to read text from URI.", e); + return itemText; } return null; diff --git a/shell/platform/android/test/io/flutter/plugin/platform/PlatformPluginTest.java b/shell/platform/android/test/io/flutter/plugin/platform/PlatformPluginTest.java index a9ced69401eee..3d5fdbce74806 100644 --- a/shell/platform/android/test/io/flutter/plugin/platform/PlatformPluginTest.java +++ b/shell/platform/android/test/io/flutter/plugin/platform/PlatformPluginTest.java @@ -13,10 +13,7 @@ import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyBoolean; -import static org.mockito.Mockito.anyString; -import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mockStatic; import static org.mockito.Mockito.never; @@ -27,7 +24,6 @@ import android.app.Activity; import android.content.ClipData; -import android.content.ClipDescription; import android.content.ClipboardManager; import android.content.ContentResolver; import android.content.Context; @@ -63,17 +59,26 @@ @RunWith(RobolectricTestRunner.class) public class PlatformPluginTest { private final Context ctx = ApplicationProvider.getApplicationContext(); + private final PlatformChannel mockPlatformChannel = mock(PlatformChannel.class); + + private ClipboardManager clipboardManager; + private ClipboardContentFormat clipboardFormat; + + public void setUpForTextClipboardTests(Activity mockActivity) { + clipboardManager = spy(ctx.getSystemService(ClipboardManager.class)); + when(mockActivity.getSystemService(Context.CLIPBOARD_SERVICE)).thenReturn(clipboardManager); + clipboardFormat = ClipboardContentFormat.PLAIN_TEXT; + } @Config(sdk = Build.VERSION_CODES.KITKAT) @Test public void itIgnoresNewHapticEventsOnOldAndroidPlatforms() { View fakeDecorView = mock(View.class); Window fakeWindow = mock(Window.class); + Activity mockActivity = mock(Activity.class); when(fakeWindow.getDecorView()).thenReturn(fakeDecorView); - Activity fakeActivity = mock(Activity.class); - when(fakeActivity.getWindow()).thenReturn(fakeWindow); - PlatformChannel fakePlatformChannel = mock(PlatformChannel.class); - PlatformPlugin platformPlugin = new PlatformPlugin(fakeActivity, fakePlatformChannel); + when(mockActivity.getWindow()).thenReturn(fakeWindow); + PlatformPlugin platformPlugin = new PlatformPlugin(mockActivity, mockPlatformChannel); // HEAVY_IMPACT haptic response is only available on "M" (23) and later. platformPlugin.vibrateHapticFeedback(PlatformChannel.HapticFeedbackType.HEAVY_IMPACT); @@ -82,53 +87,141 @@ public void itIgnoresNewHapticEventsOnOldAndroidPlatforms() { platformPlugin.vibrateHapticFeedback(PlatformChannel.HapticFeedbackType.SELECTION_CLICK); } - @Config(sdk = Build.VERSION_CODES.Q) @Test - public void platformPlugin_getClipboardData() throws IOException { - ClipboardManager clipboardManager = ctx.getSystemService(ClipboardManager.class); + public void platformPlugin_getClipboardDataIsNonNullWhenPlainTextCopied() throws IOException { + View fakeDecorView = mock(View.class); + Window fakeWindow = mock(Window.class); + Activity mockActivity = mock(Activity.class); + when(fakeWindow.getDecorView()).thenReturn(fakeDecorView); + when(mockActivity.getWindow()).thenReturn(fakeWindow); + PlatformPlugin platformPlugin = new PlatformPlugin(mockActivity, mockPlatformChannel); + setUpForTextClipboardTests(mockActivity); + // Primary clip contains non-text media. + ClipData clip = ClipData.newPlainText("label", "Text"); + assertNull(platformPlugin.mPlatformMessageHandler.getClipboardData(clipboardFormat)); + clipboardManager.setPrimaryClip(clip); + assertNotNull(platformPlugin.mPlatformMessageHandler.getClipboardData(clipboardFormat)); + } + + @Test + public void platformPlugin_getClipboardDataIsNonNullWhenIOExceptionThrown() throws IOException { View fakeDecorView = mock(View.class); Window fakeWindow = mock(Window.class); + Activity mockActivity = mock(Activity.class); when(fakeWindow.getDecorView()).thenReturn(fakeDecorView); - Activity fakeActivity = mock(Activity.class); - when(fakeActivity.getWindow()).thenReturn(fakeWindow); - when(fakeActivity.getSystemService(Context.CLIPBOARD_SERVICE)).thenReturn(clipboardManager); - PlatformChannel fakePlatformChannel = mock(PlatformChannel.class); - PlatformPlugin platformPlugin = new PlatformPlugin(fakeActivity, fakePlatformChannel); - - // Successfully get the contents of the primary clip when they contain text. - ClipboardContentFormat clipboardFormat = ClipboardContentFormat.PLAIN_TEXT; + when(mockActivity.getWindow()).thenReturn(fakeWindow); + PlatformPlugin platformPlugin = new PlatformPlugin(mockActivity, mockPlatformChannel); + setUpForTextClipboardTests(mockActivity); + ContentResolver contentResolver = mock(ContentResolver.class); + ClipData.Item mockItem = mock(ClipData.Item.class); + Uri mockUri = mock(Uri.class); + AssetFileDescriptor mockAssetFileDescriptor = mock(AssetFileDescriptor.class); + + when(mockActivity.getContentResolver()).thenReturn(contentResolver); + when(mockUri.getScheme()).thenReturn("content"); + when(mockItem.getText()).thenReturn(null); + when(mockItem.getUri()).thenReturn(mockUri); + when(contentResolver.openTypedAssetFileDescriptor(any(Uri.class), any(), any())) + .thenReturn(mockAssetFileDescriptor); + when(mockItem.coerceToText(mockActivity)).thenReturn("something non-null"); + doThrow(new IOException()).when(mockAssetFileDescriptor).close(); + + ClipData clip = new ClipData("label", new String[0], mockItem); + + assertNull(platformPlugin.mPlatformMessageHandler.getClipboardData(clipboardFormat)); + clipboardManager.setPrimaryClip(clip); + assertNotNull(platformPlugin.mPlatformMessageHandler.getClipboardData(clipboardFormat)); + } + + @Test + public void platformPlugin_getClipboardDataIsNonNullWhenContentUriWithTextProvided() + throws IOException { + View fakeDecorView = mock(View.class); + Window fakeWindow = mock(Window.class); + Activity mockActivity = mock(Activity.class); + when(fakeWindow.getDecorView()).thenReturn(fakeDecorView); + when(mockActivity.getWindow()).thenReturn(fakeWindow); + PlatformPlugin platformPlugin = new PlatformPlugin(mockActivity, mockPlatformChannel); + setUpForTextClipboardTests(mockActivity); + ContentResolver contentResolver = mock(ContentResolver.class); + ClipData.Item mockItem = mock(ClipData.Item.class); + Uri mockUri = mock(Uri.class); + + when(mockActivity.getContentResolver()).thenReturn(contentResolver); + when(mockUri.getScheme()).thenReturn("content"); + when(mockItem.getText()).thenReturn(null); + when(mockItem.getUri()).thenReturn(mockUri); + when(contentResolver.openTypedAssetFileDescriptor(any(Uri.class), any(), any())) + .thenReturn(mock(AssetFileDescriptor.class)); + when(mockItem.coerceToText(mockActivity)).thenReturn("something non-null"); + + ClipData clip = new ClipData("label", new String[0], mockItem); + assertNull(platformPlugin.mPlatformMessageHandler.getClipboardData(clipboardFormat)); - ClipData clip = ClipData.newPlainText("label", "Text"); clipboardManager.setPrimaryClip(clip); assertNotNull(platformPlugin.mPlatformMessageHandler.getClipboardData(clipboardFormat)); + } + + @Test + public void platformPlugin_getClipboardDataIsNullWhenContentUriProvidedContainsNoText() + throws IOException { + View fakeDecorView = mock(View.class); + Window fakeWindow = mock(Window.class); + Activity mockActivity = mock(Activity.class); + when(fakeWindow.getDecorView()).thenReturn(fakeDecorView); + when(mockActivity.getWindow()).thenReturn(fakeWindow); + PlatformPlugin platformPlugin = new PlatformPlugin(mockActivity, mockPlatformChannel); + setUpForTextClipboardTests(mockActivity); + ContentResolver contentResolver = ctx.getContentResolver(); + + when(mockActivity.getContentResolver()).thenReturn(contentResolver); - // Return null when the primary clip contains non-text media. - ContentResolver contentResolver = spy(ctx.getContentResolver()); - when(fakeActivity.getContentResolver()).thenReturn(contentResolver); Uri uri = Uri.parse("content://media/external_primary/images/media/"); - clip = ClipData.newUri(contentResolver, "URI", uri); + ClipData clip = ClipData.newUri(contentResolver, "URI", uri); + clipboardManager.setPrimaryClip(clip); assertNull(platformPlugin.mPlatformMessageHandler.getClipboardData(clipboardFormat)); + } - // Still return text when the AssetFileDescriptor throws an IOException. - when(fakeActivity.getContentResolver()).thenReturn(contentResolver); - ClipDescription clipDescription = - new ClipDescription( - "label", - new String[] { - ClipDescription.MIMETYPE_TEXT_PLAIN, ClipDescription.MIMETYPE_TEXT_URILIST - }); - ClipData.Item clipDataItem = new ClipData.Item("Text", null, uri); - ClipData clipData = new ClipData(clipDescription, clipDataItem); - clipboardManager.setPrimaryClip(clipData); - AssetFileDescriptor fakeAssetFileDescriptor = mock(AssetFileDescriptor.class); - doReturn(fakeAssetFileDescriptor) - .when(contentResolver) - .openTypedAssetFileDescriptor(eq(uri), anyString(), eq(null)); - doThrow(new IOException()).when(fakeAssetFileDescriptor).close(); - assertNotNull(platformPlugin.mPlatformMessageHandler.getClipboardData(clipboardFormat)); - verify(fakeAssetFileDescriptor).close(); + @Test + public void platformPlugin_getClipboardDataIsNullWhenNonContentUriProvided() throws IOException { + View fakeDecorView = mock(View.class); + Window fakeWindow = mock(Window.class); + Activity mockActivity = mock(Activity.class); + when(fakeWindow.getDecorView()).thenReturn(fakeDecorView); + when(mockActivity.getWindow()).thenReturn(fakeWindow); + PlatformPlugin platformPlugin = new PlatformPlugin(mockActivity, mockPlatformChannel); + setUpForTextClipboardTests(mockActivity); + ContentResolver contentResolver = ctx.getContentResolver(); + + when(mockActivity.getContentResolver()).thenReturn(contentResolver); + + Uri uri = Uri.parse("file:///"); + ClipData clip = ClipData.newUri(contentResolver, "URI", uri); + + clipboardManager.setPrimaryClip(clip); + assertNull(platformPlugin.mPlatformMessageHandler.getClipboardData(clipboardFormat)); + } + + @Test + public void platformPlugin_getClipboardDataIsNullWhenItemHasNoTextNorUri() throws IOException { + View fakeDecorView = mock(View.class); + Window fakeWindow = mock(Window.class); + Activity mockActivity = mock(Activity.class); + when(fakeWindow.getDecorView()).thenReturn(fakeDecorView); + when(mockActivity.getWindow()).thenReturn(fakeWindow); + PlatformPlugin platformPlugin = new PlatformPlugin(mockActivity, mockPlatformChannel); + setUpForTextClipboardTests(mockActivity); + ClipData.Item mockItem = mock(ClipData.Item.class); + + when(mockItem.getText()).thenReturn(null); + when(mockItem.getUri()).thenReturn(null); + + ClipData clip = new ClipData("label", new String[0], mockItem); + + clipboardManager.setPrimaryClip(clip); + assertNull(platformPlugin.mPlatformMessageHandler.getClipboardData(clipboardFormat)); } @SuppressWarnings("deprecation") @@ -136,16 +229,13 @@ public void platformPlugin_getClipboardData() throws IOException { @Config(sdk = Build.VERSION_CODES.P) @Test public void platformPlugin_hasStrings() { - ClipboardManager clipboardManager = spy(ctx.getSystemService(ClipboardManager.class)); - View fakeDecorView = mock(View.class); Window fakeWindow = mock(Window.class); + Activity mockActivity = mock(Activity.class); when(fakeWindow.getDecorView()).thenReturn(fakeDecorView); - Activity fakeActivity = mock(Activity.class); - when(fakeActivity.getWindow()).thenReturn(fakeWindow); - when(fakeActivity.getSystemService(Context.CLIPBOARD_SERVICE)).thenReturn(clipboardManager); - PlatformChannel fakePlatformChannel = mock(PlatformChannel.class); - PlatformPlugin platformPlugin = new PlatformPlugin(fakeActivity, fakePlatformChannel); + when(mockActivity.getWindow()).thenReturn(fakeWindow); + PlatformPlugin platformPlugin = new PlatformPlugin(mockActivity, mockPlatformChannel); + setUpForTextClipboardTests(mockActivity); // Plain text ClipData clip = ClipData.newPlainText("label", "Text"); @@ -192,11 +282,10 @@ public void platformPlugin_hasStrings() { public void setNavigationBarDividerColor() { View fakeDecorView = mock(View.class); Window fakeWindow = mock(Window.class); + Activity mockActivity = mock(Activity.class); when(fakeWindow.getDecorView()).thenReturn(fakeDecorView); - Activity fakeActivity = mock(Activity.class); - when(fakeActivity.getWindow()).thenReturn(fakeWindow); - PlatformChannel fakePlatformChannel = mock(PlatformChannel.class); - PlatformPlugin platformPlugin = new PlatformPlugin(fakeActivity, fakePlatformChannel); + when(mockActivity.getWindow()).thenReturn(fakeWindow); + PlatformPlugin platformPlugin = new PlatformPlugin(mockActivity, mockPlatformChannel); if (Build.VERSION.SDK_INT >= 28) { // Default style test @@ -265,16 +354,16 @@ public void setNavigationBarDividerColor() { @Config(sdk = Build.VERSION_CODES.R) @Test public void setNavigationBarIconBrightness() { + View fakeDecorView = mock(View.class); + Window fakeWindow = mock(Window.class); + Activity mockActivity = mock(Activity.class); + when(fakeWindow.getDecorView()).thenReturn(fakeDecorView); + when(mockActivity.getWindow()).thenReturn(fakeWindow); + PlatformPlugin platformPlugin = new PlatformPlugin(mockActivity, mockPlatformChannel); + if (Build.VERSION.SDK_INT >= 30) { - View fakeDecorView = mock(View.class); WindowInsetsController fakeWindowInsetsController = mock(WindowInsetsController.class); - Window fakeWindow = mock(Window.class); - when(fakeWindow.getDecorView()).thenReturn(fakeDecorView); when(fakeWindow.getInsetsController()).thenReturn(fakeWindowInsetsController); - Activity fakeActivity = mock(Activity.class); - when(fakeActivity.getWindow()).thenReturn(fakeWindow); - PlatformChannel fakePlatformChannel = mock(PlatformChannel.class); - PlatformPlugin platformPlugin = new PlatformPlugin(fakeActivity, fakePlatformChannel); SystemChromeStyle style = new SystemChromeStyle( @@ -312,16 +401,16 @@ public void setNavigationBarIconBrightness() { @Config(sdk = Build.VERSION_CODES.R) @Test public void setStatusBarIconBrightness() { + View fakeDecorView = mock(View.class); + Window fakeWindow = mock(Window.class); + Activity mockActivity = mock(Activity.class); + when(fakeWindow.getDecorView()).thenReturn(fakeDecorView); + when(mockActivity.getWindow()).thenReturn(fakeWindow); + PlatformPlugin platformPlugin = new PlatformPlugin(mockActivity, mockPlatformChannel); + if (Build.VERSION.SDK_INT >= 30) { - View fakeDecorView = mock(View.class); WindowInsetsController fakeWindowInsetsController = mock(WindowInsetsController.class); - Window fakeWindow = mock(Window.class); - when(fakeWindow.getDecorView()).thenReturn(fakeDecorView); when(fakeWindow.getInsetsController()).thenReturn(fakeWindowInsetsController); - Activity fakeActivity = mock(Activity.class); - when(fakeActivity.getWindow()).thenReturn(fakeWindow); - PlatformChannel fakePlatformChannel = mock(PlatformChannel.class); - PlatformPlugin platformPlugin = new PlatformPlugin(fakeActivity, fakePlatformChannel); SystemChromeStyle style = new SystemChromeStyle( @@ -361,11 +450,10 @@ public void setStatusBarIconBrightness() { public void setSystemUiMode() { View fakeDecorView = mock(View.class); Window fakeWindow = mock(Window.class); + Activity mockActivity = mock(Activity.class); when(fakeWindow.getDecorView()).thenReturn(fakeDecorView); - Activity fakeActivity = mock(Activity.class); - when(fakeActivity.getWindow()).thenReturn(fakeWindow); - PlatformChannel fakePlatformChannel = mock(PlatformChannel.class); - PlatformPlugin platformPlugin = new PlatformPlugin(fakeActivity, fakePlatformChannel); + when(mockActivity.getWindow()).thenReturn(fakeWindow); + PlatformPlugin platformPlugin = new PlatformPlugin(mockActivity, mockPlatformChannel); if (Build.VERSION.SDK_INT >= 28) { platformPlugin.mPlatformMessageHandler.showSystemUiMode( @@ -420,8 +508,7 @@ public void setSystemUiModeListener_overlaysAreHidden() { controller.setup(); Activity fakeActivity = controller.get(); - PlatformChannel fakePlatformChannel = mock(PlatformChannel.class); - PlatformPlugin platformPlugin = new PlatformPlugin(fakeActivity, fakePlatformChannel); + PlatformPlugin platformPlugin = new PlatformPlugin(fakeActivity, mockPlatformChannel); // Subscribe to system UI visibility events. platformPlugin.mPlatformMessageHandler.setSystemUiChangeListener(); @@ -434,13 +521,13 @@ public void setSystemUiModeListener_overlaysAreHidden() { // No events should have been sent to the platform channel yet. They are scheduled for // the next frame. - verify(fakePlatformChannel, never()).systemChromeChanged(anyBoolean()); + verify(mockPlatformChannel, never()).systemChromeChanged(anyBoolean()); // Simulate the next frame. ShadowLooper.runUiThreadTasksIncludingDelayedTasks(); // Now the platform channel should receive the event. - verify(fakePlatformChannel).systemChromeChanged(false); + verify(mockPlatformChannel).systemChromeChanged(false); } @SuppressWarnings("deprecation") @@ -450,9 +537,7 @@ public void setSystemUiModeListener_overlaysAreVisible() { ActivityController controller = Robolectric.buildActivity(Activity.class); controller.setup(); Activity fakeActivity = controller.get(); - - PlatformChannel fakePlatformChannel = mock(PlatformChannel.class); - PlatformPlugin platformPlugin = new PlatformPlugin(fakeActivity, fakePlatformChannel); + PlatformPlugin platformPlugin = new PlatformPlugin(fakeActivity, mockPlatformChannel); // Subscribe to system Ui visibility events. platformPlugin.mPlatformMessageHandler.setSystemUiChangeListener(); @@ -462,13 +547,13 @@ public void setSystemUiModeListener_overlaysAreVisible() { // No events should have been sent to the platform channel yet. They are scheduled for // the next frame. - verify(fakePlatformChannel, never()).systemChromeChanged(anyBoolean()); + verify(mockPlatformChannel, never()).systemChromeChanged(anyBoolean()); // Simulate the next frame. ShadowLooper.runUiThreadTasksIncludingDelayedTasks(); // Now the platform channel should receive the event. - verify(fakePlatformChannel).systemChromeChanged(true); + verify(mockPlatformChannel).systemChromeChanged(true); } @SuppressWarnings("deprecation") @@ -478,11 +563,10 @@ public void setSystemUiModeListener_overlaysAreVisible() { public void doNotEnableEdgeToEdgeOnOlderSdk() { View fakeDecorView = mock(View.class); Window fakeWindow = mock(Window.class); + Activity mockActivity = mock(Activity.class); when(fakeWindow.getDecorView()).thenReturn(fakeDecorView); - Activity fakeActivity = mock(Activity.class); - when(fakeActivity.getWindow()).thenReturn(fakeWindow); - PlatformChannel fakePlatformChannel = mock(PlatformChannel.class); - PlatformPlugin platformPlugin = new PlatformPlugin(fakeActivity, fakePlatformChannel); + when(mockActivity.getWindow()).thenReturn(fakeWindow); + PlatformPlugin platformPlugin = new PlatformPlugin(mockActivity, mockPlatformChannel); platformPlugin.mPlatformMessageHandler.showSystemUiMode( PlatformChannel.SystemUiMode.EDGE_TO_EDGE); @@ -500,11 +584,10 @@ public void doNotEnableEdgeToEdgeOnOlderSdk() { public void verifyWindowFlagsSetToStyleOverlays() { View fakeDecorView = mock(View.class); Window fakeWindow = mock(Window.class); + Activity mockActivity = mock(Activity.class); when(fakeWindow.getDecorView()).thenReturn(fakeDecorView); - Activity fakeActivity = mock(Activity.class); - when(fakeActivity.getWindow()).thenReturn(fakeWindow); - PlatformChannel fakePlatformChannel = mock(PlatformChannel.class); - PlatformPlugin platformPlugin = new PlatformPlugin(fakeActivity, fakePlatformChannel); + when(mockActivity.getWindow()).thenReturn(fakeWindow); + PlatformPlugin platformPlugin = new PlatformPlugin(mockActivity, mockPlatformChannel); SystemChromeStyle style = new SystemChromeStyle( @@ -521,7 +604,6 @@ public void verifyWindowFlagsSetToStyleOverlays() { @Test public void setFrameworkHandlesBackFlutterActivity() { Activity mockActivity = mock(Activity.class); - PlatformChannel mockPlatformChannel = mock(PlatformChannel.class); PlatformPluginDelegate mockPlatformPluginDelegate = mock(PlatformPluginDelegate.class); PlatformPlugin platformPlugin = new PlatformPlugin(mockActivity, mockPlatformChannel, mockPlatformPluginDelegate); @@ -534,12 +616,12 @@ public void setFrameworkHandlesBackFlutterActivity() { @Test public void popSystemNavigatorFlutterActivity() { Activity mockActivity = mock(Activity.class); - PlatformChannel mockPlatformChannel = mock(PlatformChannel.class); PlatformPluginDelegate mockPlatformPluginDelegate = mock(PlatformPluginDelegate.class); - when(mockPlatformPluginDelegate.popSystemNavigator()).thenReturn(false); PlatformPlugin platformPlugin = new PlatformPlugin(mockActivity, mockPlatformChannel, mockPlatformPluginDelegate); + when(mockPlatformPluginDelegate.popSystemNavigator()).thenReturn(false); + platformPlugin.mPlatformMessageHandler.popSystemNavigator(); verify(mockPlatformPluginDelegate, times(1)).popSystemNavigator(); @@ -549,12 +631,12 @@ public void popSystemNavigatorFlutterActivity() { @Test public void doesNotDoAnythingByDefaultIfPopSystemNavigatorOverridden() { Activity mockActivity = mock(Activity.class); - PlatformChannel mockPlatformChannel = mock(PlatformChannel.class); PlatformPluginDelegate mockPlatformPluginDelegate = mock(PlatformPluginDelegate.class); - when(mockPlatformPluginDelegate.popSystemNavigator()).thenReturn(true); PlatformPlugin platformPlugin = new PlatformPlugin(mockActivity, mockPlatformChannel, mockPlatformPluginDelegate); + when(mockPlatformPluginDelegate.popSystemNavigator()).thenReturn(true); + platformPlugin.mPlatformMessageHandler.popSystemNavigator(); verify(mockPlatformPluginDelegate, times(1)).popSystemNavigator(); @@ -579,7 +661,6 @@ public void handleOnBackPressed() { }; activity.getOnBackPressedDispatcher().addCallback(backCallback); - PlatformChannel mockPlatformChannel = mock(PlatformChannel.class); PlatformPluginDelegate mockPlatformPluginDelegate = mock(PlatformPluginDelegate.class); when(mockPlatformPluginDelegate.popSystemNavigator()).thenReturn(false); PlatformPlugin platformPlugin = @@ -598,7 +679,6 @@ public void handleOnBackPressed() { @Test public void doesNotDoAnythingByDefaultIfFragmentPopSystemNavigatorOverridden() { FragmentActivity activity = spy(Robolectric.setupActivity(FragmentActivity.class)); - PlatformChannel mockPlatformChannel = mock(PlatformChannel.class); PlatformPluginDelegate mockPlatformPluginDelegate = mock(PlatformPluginDelegate.class); when(mockPlatformPluginDelegate.popSystemNavigator()).thenReturn(true); PlatformPlugin platformPlugin = @@ -614,7 +694,6 @@ public void doesNotDoAnythingByDefaultIfFragmentPopSystemNavigatorOverridden() { @Test public void setRequestedOrientationFlutterFragment() { FragmentActivity mockFragmentActivity = mock(FragmentActivity.class); - PlatformChannel mockPlatformChannel = mock(PlatformChannel.class); PlatformPluginDelegate mockPlatformPluginDelegate = mock(PlatformPluginDelegate.class); when(mockPlatformPluginDelegate.popSystemNavigator()).thenReturn(false); PlatformPlugin platformPlugin =