[Android] Check for text to paste before trying to retrieve data from URI (flutter/engine#48166)

Adds a check to retrieve explicit text from Clipboard items via [`getText`](https://developer.android.com/reference/android/content/ClipData.Item#getText()) before attempting to retrieve data if the Clipboard item (`ClipData.Item`) has an associated URI. Also adds more error handling for edge cases concerning URIs (the URI not having the content scheme or being null).

Fixes https://github.com/flutter/flutter/issues/74320. Some content providers will not send URIs containing the `text/*` pattern or have the content scheme (`content://`), but ultimately we should expect Clipboard items to either fall **not** into one of those categories or have an explicit textual value available via `getText`. In case this is not true, though, checks for non-content URIs and null URIs are added, as well :)

Tested on a Samsung tablet with pasting from MS Word, MS Excel, and Samsung Notes.

[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
This commit is contained in:
Camille Simon 2023-11-30 16:04:42 -08:00 committed by GitHub
parent 3ffeaa87b6
commit 7965fd759e
2 changed files with 214 additions and 108 deletions

View File

@ -13,6 +13,7 @@ import android.content.ClipboardManager;
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 @@ public class PlatformPlugin {
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 @@ public class PlatformPlugin {
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;

View File

@ -13,10 +13,7 @@ import static org.junit.Assert.assertNull;
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 static org.mockito.Mockito.when;
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 @@ import org.robolectric.shadows.ShadowLooper;
@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 class PlatformPluginTest {
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);
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);
// Successfully get the contents of the primary clip when they contain text.
ClipboardContentFormat clipboardFormat = ClipboardContentFormat.PLAIN_TEXT;
assertNull(platformPlugin.mPlatformMessageHandler.getClipboardData(clipboardFormat));
// 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);
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));
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 class PlatformPluginTest {
@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 class PlatformPluginTest {
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 class PlatformPluginTest {
@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 class PlatformPluginTest {
@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 class PlatformPluginTest {
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 class PlatformPluginTest {
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 class PlatformPluginTest {
// 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 class PlatformPluginTest {
ActivityController<Activity> 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 class PlatformPluginTest {
// 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 class PlatformPluginTest {
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 class PlatformPluginTest {
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 class PlatformPluginTest {
@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 class PlatformPluginTest {
@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 class PlatformPluginTest {
@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 class PlatformPluginTest {
};
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 class PlatformPluginTest {
@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 class PlatformPluginTest {
@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 =