未验证 提交 9cbf50a5 编写于 作者: W Wyte Krongapiradee 提交者: GitHub

Avoid unintended clipboard access (#27215)

上级 dfd43abb
......@@ -7,6 +7,7 @@ package io.flutter.plugin.platform;
import android.app.Activity;
import android.app.ActivityManager.TaskDescription;
import android.content.ClipData;
import android.content.ClipDescription;
import android.content.ClipboardManager;
import android.content.Context;
import android.os.Build;
......@@ -124,10 +125,7 @@ public class PlatformPlugin {
@Override
public boolean clipboardHasStrings() {
CharSequence data =
PlatformPlugin.this.getClipboardData(
PlatformChannel.ClipboardContentFormat.PLAIN_TEXT);
return data != null && data.length() > 0;
return PlatformPlugin.this.clipboardHasStrings();
}
};
......@@ -490,4 +488,20 @@ public class PlatformPlugin {
ClipData clip = ClipData.newPlainText("text label?", text);
clipboard.setPrimaryClip(clip);
}
private boolean clipboardHasStrings() {
ClipboardManager clipboard =
(ClipboardManager) activity.getSystemService(Context.CLIPBOARD_SERVICE);
// Android 12 introduces a toast message that appears when an app reads the clipboard. To avoid
// unintended access, call the appropriate APIs to receive information about the current content
// that's on the clipboard (rather than the actual content itself).
if (!clipboard.hasPrimaryClip()) {
return false;
}
ClipDescription description = clipboard.getPrimaryClipDescription();
if (description == null) {
return false;
}
return description.hasMimeType("text/*");
}
}
......@@ -7,6 +7,7 @@ import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
......@@ -96,10 +97,11 @@ public class PlatformPluginTest {
assertEquals(dataInputStream.read(), uriInputStream.read());
}
@Config(sdk = 28)
@Test
public void platformPlugin_hasStrings() {
ClipboardManager clipboardManager =
RuntimeEnvironment.application.getSystemService(ClipboardManager.class);
spy(RuntimeEnvironment.application.getSystemService(ClipboardManager.class));
View fakeDecorView = mock(View.class);
Window fakeWindow = mock(Window.class);
......@@ -110,13 +112,44 @@ public class PlatformPluginTest {
PlatformChannel fakePlatformChannel = mock(PlatformChannel.class);
PlatformPlugin platformPlugin = new PlatformPlugin(fakeActivity, fakePlatformChannel);
// Plain text
ClipData clip = ClipData.newPlainText("label", "Text");
clipboardManager.setPrimaryClip(clip);
assertTrue(platformPlugin.mPlatformMessageHandler.clipboardHasStrings());
// Empty plain text
clip = ClipData.newPlainText("", "");
clipboardManager.setPrimaryClip(clip);
// Without actually accessing clipboard data (preferred behavior), it is not possible to
// distinguish between empty and non-empty string contents.
assertTrue(platformPlugin.mPlatformMessageHandler.clipboardHasStrings());
// HTML text
clip = ClipData.newHtmlText("motto", "Don't be evil", "<b>Don't</b> be evil");
clipboardManager.setPrimaryClip(clip);
assertTrue(platformPlugin.mPlatformMessageHandler.clipboardHasStrings());
// Text MIME type
clip = new ClipData("label", new String[] {"text/something"}, new ClipData.Item("content"));
clipboardManager.setPrimaryClip(clip);
assertTrue(platformPlugin.mPlatformMessageHandler.clipboardHasStrings());
// Other MIME type
clip =
new ClipData(
"label", new String[] {"application/octet-stream"}, new ClipData.Item("content"));
clipboardManager.setPrimaryClip(clip);
assertFalse(platformPlugin.mPlatformMessageHandler.clipboardHasStrings());
if (Build.VERSION.SDK_INT >= 28) {
// Empty clipboard
clipboardManager.clearPrimaryClip();
assertFalse(platformPlugin.mPlatformMessageHandler.clipboardHasStrings());
}
// Verify that the clipboard contents are never accessed.
verify(clipboardManager, never()).getPrimaryClip();
verify(clipboardManager, never()).getText();
}
@Config(sdk = 29)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册