Commit b56f77e5 authored by ckitagawa's avatar ckitagawa Committed by Commit Bot

[Fixit] Re-implement ClipboardAndroid Tests

This CL attempts to re-implement
ui/base/clipboard/clipboard_android_unittests.cc which was deleted in
http://crrev.com/2839753007 as part of removing GetApplicationContext.

This CL does 2 things
1. clipboard_unittests.cc was made part of interactive_ui_tests
   (for context see crbug/434620); however, this target is not run on
   Android. Since gtests aren't sharded on Android (no clipboard
   contention) we can include clipboard_unittests.cc in an Android
   specific target to cover clipboard_android.{h|cc}. Note that this
   requires disabling some tests in clipboard_test_template.h that
   work with TestClipboard but not ClipboardAndroid (see inline bugs).
2. This adds the Android platform specific ClipboardAndroidTest.java
   with a testcase that simulates another application copying to the
   clipboard and correctly propagating that to Chrome's clipboard. This
   test needs to be driven from Java as per the re-implementation
   discussion in crbug/715619.

Also related from crbug/434620 is the request for a last modified time
testcase. However, this appears to reference preference-related
functions which no longer exist.

Bug: 434620, 715619, 1064968
Change-Id: I5e1b74711c638b947dde0dd205f575dd07cdb436
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2121045
Commit-Queue: Calder Kitagawa <ckitagawa@chromium.org>
Reviewed-by: default avatarYaron Friedman <yfriedman@chromium.org>
Reviewed-by: default avatarTheresa  <twellington@chromium.org>
Reviewed-by: default avatarGang Wu <gangwu@chromium.org>
Reviewed-by: default avatarDarwin Huang <huangdarwin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#755345}
parent 8fa00285
...@@ -959,6 +959,7 @@ android_library("chrome_test_java") { ...@@ -959,6 +959,7 @@ android_library("chrome_test_java") {
"//third_party/ub-uiautomator:ub_uiautomator_java", "//third_party/ub-uiautomator:ub_uiautomator_java",
"//ui/android:ui_java", "//ui/android:ui_java",
"//ui/android:ui_java_test_support", "//ui/android:ui_java_test_support",
"//ui/android:ui_javatests",
"//ui/base/mojom:mojom_java", "//ui/base/mojom:mojom_java",
"//url:gurl_java", "//url:gurl_java",
"//url/mojom:url_mojom_gurl_java", "//url/mojom:url_mojom_gurl_java",
...@@ -1302,6 +1303,7 @@ chrome_common_shared_library("libchromefortest") { ...@@ -1302,6 +1303,7 @@ chrome_common_shared_library("libchromefortest") {
"//components/sync/test/fake_server:fake_server_android", "//components/sync/test/fake_server:fake_server_android",
"//content/public/test/android:content_native_test_support", "//content/public/test/android:content_native_test_support",
"//content/test:test_support", "//content/test:test_support",
"//ui/base/clipboard:clipboard_test_support",
] ]
if (enable_vr) { if (enable_vr) {
deps += [ "//chrome/browser/android/vr:test_support" ] deps += [ "//chrome/browser/android/vr:test_support" ]
...@@ -1622,6 +1624,7 @@ java_group("chrome_public_base_module_java_for_test") { ...@@ -1622,6 +1624,7 @@ java_group("chrome_public_base_module_java_for_test") {
"//components/minidump_uploader:minidump_uploader_java", "//components/minidump_uploader:minidump_uploader_java",
"//components/paint_preview/player/android:player_java_test_support", "//components/paint_preview/player/android:player_java_test_support",
"//content/public/test/android:content_java_test_support", "//content/public/test/android:content_java_test_support",
"//ui/android:ui_javatests",
] ]
} }
......
...@@ -476,6 +476,9 @@ junit_binary("ui_junit_tests") { ...@@ -476,6 +476,9 @@ junit_binary("ui_junit_tests") {
test("ui_android_unittests") { test("ui_android_unittests") {
sources = [ sources = [
# Clipboard unittests are run here for Android as gtests on Android are not
# sharded. On other OSs these are run as part of interactive_ui_tests.
"//ui/base/clipboard/clipboard_unittest.cc",
"overscroll_refresh_unittest.cc", "overscroll_refresh_unittest.cc",
"resources/resource_manager_impl_unittest.cc", "resources/resource_manager_impl_unittest.cc",
"run_all_unittests.cc", "run_all_unittests.cc",
...@@ -495,9 +498,35 @@ test("ui_android_unittests") { ...@@ -495,9 +498,35 @@ test("ui_android_unittests") {
"//testing/gmock", "//testing/gmock",
"//testing/gtest", "//testing/gtest",
"//ui/base", "//ui/base",
"//ui/base/clipboard",
"//ui/base/clipboard:clipboard_test_support",
"//ui/compositor", "//ui/compositor",
"//ui/events", "//ui/events",
"//ui/gfx", "//ui/gfx",
"//ui/resources:ui_test_pak", "//ui/resources:ui_test_pak",
] ]
} }
android_library("ui_javatests") {
testonly = true
sources = [ "javatests/src/org/chromium/ui/base/ClipboardAndroidTest.java" ]
deps = [
":ui_java",
":ui_java_test_support",
"//base:base_java",
"//base:base_java_test_support",
"//base:jni_java",
"//content/public/test/android:content_java_test_support",
"//third_party/junit",
]
annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ]
}
generate_jni("ui_javatest_jni_headers") {
testonly = true
sources = [ "javatests/src/org/chromium/ui/base/ClipboardAndroidTest.java" ]
}
...@@ -11,6 +11,7 @@ include_rules = [ ...@@ -11,6 +11,7 @@ include_rules = [
"+components/viz/client", "+components/viz/client",
"+components/viz/common", "+components/viz/common",
"+components/viz/host", "+components/viz/host",
"+content/public/test/android/javatests/src/org/chromium/content_public/browser/test",
"+services/viz/public/mojom", "+services/viz/public/mojom",
"+skia/ext", "+skia/ext",
"+third_party/skia", "+third_party/skia",
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.ui.base;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.support.test.filters.SmallTest;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.chromium.base.annotations.JNINamespace;
import org.chromium.base.annotations.NativeMethods;
import org.chromium.base.test.BaseJUnit4ClassRunner;
import org.chromium.content_public.browser.test.NativeLibraryTestRule;
import org.chromium.content_public.browser.test.util.CriteriaHelper;
import org.chromium.content_public.browser.test.util.TestThreadUtils;
import org.chromium.ui.test.util.DummyUiActivityTestCase;
/**
* Clipboard tests for Android platform that depend on access to the ClipboardManager.
*/
@JNINamespace("ui")
@RunWith(BaseJUnit4ClassRunner.class)
public class ClipboardAndroidTest extends DummyUiActivityTestCase {
@Rule
public NativeLibraryTestRule mNativeLibraryTestRule = new NativeLibraryTestRule();
@Override
public void setUpTest() throws Exception {
super.setUpTest();
mNativeLibraryTestRule.loadNativeLibraryNoBrowserProcess();
}
@Override
public void tearDownTest() throws Exception {
ClipboardAndroidTestJni.get().cleanup();
}
/**
* Test that if another application writes some text to the pasteboard the clipboard properly
* invalidates other types.
*/
@Test
@SmallTest
public void internalClipboardInvalidation() {
CriteriaHelper.pollUiThread(() -> getActivity().hasWindowFocus());
// Write to the clipboard in native and ensure that is propagated to the platform clipboard.
final String originalText = "foo";
TestThreadUtils.runOnUiThreadBlocking(() -> {
Assert.assertTrue("Original text was not written to the native clipboard.",
ClipboardAndroidTestJni.get().nativeWriteHtml(originalText));
});
// Assert that the ClipboardManager contains the original text. Then simulate another
// application writing to the clipboard.
final String invalidatingText = "Hello, World!";
TestThreadUtils.runOnUiThreadBlocking(() -> {
ClipboardManager clipboardManager =
(ClipboardManager) getActivity().getSystemService(Context.CLIPBOARD_SERVICE);
Assert.assertEquals("Original text not found in ClipboardManager.", originalText,
Clipboard.getInstance().clipDataToHtmlText(clipboardManager.getPrimaryClip()));
clipboardManager.setPrimaryClip(ClipData.newPlainText(null, invalidatingText));
});
// Assert that the overwrite from another application is registered by the native clipboard.
TestThreadUtils.runOnUiThreadBlocking(() -> {
Assert.assertTrue("Invalidating text not found in the native clipboard.",
ClipboardAndroidTestJni.get().nativeClipboardContains(invalidatingText));
});
}
@NativeMethods
interface Natives {
void cleanup();
boolean nativeWriteHtml(String htmlText);
boolean nativeClipboardContains(String text);
}
}
...@@ -182,6 +182,10 @@ jumbo_source_set("clipboard_test_support") { ...@@ -182,6 +182,10 @@ jumbo_source_set("clipboard_test_support") {
"test/test_clipboard.cc", "test/test_clipboard.cc",
"test/test_clipboard.h", "test/test_clipboard.h",
] ]
if (is_android) {
sources += [ "clipboard_android_test_support.cc" ]
}
} }
public_deps = [ public_deps = [
...@@ -191,6 +195,10 @@ jumbo_source_set("clipboard_test_support") { ...@@ -191,6 +195,10 @@ jumbo_source_set("clipboard_test_support") {
] ]
deps = [ "//base/test:test_support" ] deps = [ "//base/test:test_support" ]
if (is_android) {
deps += [ "//ui/android:ui_javatest_jni_headers" ]
}
} }
source_set("clipboard_test") { source_set("clipboard_test") {
......
include_rules = [ include_rules = [
"+mojo/public/cpp/base", "+mojo/public/cpp/base",
"+third_party/mozilla", "+third_party/mozilla",
"+ui/android/ui_javatest_jni_headers/ClipboardAndroidTest_jni.h",
"+ui/base/ui_base_jni_headers", "+ui/base/ui_base_jni_headers",
"-ui/ozone/*", "-ui/ozone/*",
"+ui/ozone/buildflags.h", "+ui/ozone/buildflags.h",
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/android/ui_javatest_jni_headers/ClipboardAndroidTest_jni.h"
#include <string>
#include "base/android/jni_string.h"
#include "base/logging.h"
#include "base/strings/utf_string_conversions.h"
#include "ui/base/clipboard/clipboard_android.h"
#include "ui/base/clipboard/clipboard_buffer.h"
#include "ui/base/clipboard/scoped_clipboard_writer.h"
namespace ui {
void JNI_ClipboardAndroidTest_Cleanup(JNIEnv* env) {
Clipboard::DestroyClipboardForCurrentThread();
}
jboolean JNI_ClipboardAndroidTest_NativeWriteHtml(
JNIEnv* env,
const base::android::JavaParamRef<jstring>& j_html_text) {
{
// Simulate something writing HTML to the clipboard in native.
// NOTE: Android requires both a plaintext and HTML version.
base::string16 html_text;
base::android::ConvertJavaStringToUTF16(env, j_html_text, &html_text);
std::string url;
ScopedClipboardWriter clipboard_writer(ClipboardBuffer::kCopyPaste);
clipboard_writer.WriteHTML(html_text, url);
clipboard_writer.WriteText(html_text);
}
auto* clipboard = Clipboard::GetForCurrentThread();
return clipboard->IsFormatAvailable(ClipboardFormatType::GetHtmlType(),
ClipboardBuffer::kCopyPaste) &&
clipboard->IsFormatAvailable(ClipboardFormatType::GetPlainTextType(),
ClipboardBuffer::kCopyPaste);
}
jboolean JNI_ClipboardAndroidTest_NativeClipboardContains(
JNIEnv* env,
const base::android::JavaParamRef<jstring>& j_text) {
// The Java side of the test pretended to be another app using
// ClipboardManager. This should update the native side of the clipboard as
// well as the Android side.
auto* clipboard = Clipboard::GetForCurrentThread();
if (clipboard->IsFormatAvailable(ClipboardFormatType::GetHtmlType(),
ClipboardBuffer::kCopyPaste)) {
LOG(ERROR) << "HTML still in clipboard.";
return false;
}
if (!clipboard->IsFormatAvailable(ClipboardFormatType::GetPlainTextType(),
ClipboardBuffer::kCopyPaste)) {
LOG(ERROR) << "Plain text not in clipboard.";
return false;
}
std::string expected_text;
base::android::ConvertJavaStringToUTF8(env, j_text, &expected_text);
std::string contents;
clipboard->ReadAsciiText(ClipboardBuffer::kCopyPaste, &contents);
if (expected_text != contents) {
LOG(ERROR) << "Clipboard contents do not match. Expected: " << expected_text
<< " Actual: " << contents;
return false;
}
return true;
}
} // namespace ui
...@@ -175,6 +175,9 @@ TYPED_TEST(ClipboardTest, HTMLTest) { ...@@ -175,6 +175,9 @@ TYPED_TEST(ClipboardTest, HTMLTest) {
#endif // defined(OS_WIN) #endif // defined(OS_WIN)
} }
#if !defined(OS_ANDROID)
// TODO(crbug/1064968): This test fails with ClipboardAndroid, but passes with
// the TestClipboard as RTF isn't implemented in ClipboardAndroid.
TYPED_TEST(ClipboardTest, RTFTest) { TYPED_TEST(ClipboardTest, RTFTest) {
std::string rtf = std::string rtf =
"{\\rtf1\\ansi{\\fonttbl\\f0\\fswiss Helvetica;}\\f0\\pard\n" "{\\rtf1\\ansi{\\fonttbl\\f0\\fswiss Helvetica;}\\f0\\pard\n"
...@@ -194,6 +197,7 @@ TYPED_TEST(ClipboardTest, RTFTest) { ...@@ -194,6 +197,7 @@ TYPED_TEST(ClipboardTest, RTFTest) {
this->clipboard().ReadRTF(ClipboardBuffer::kCopyPaste, &result); this->clipboard().ReadRTF(ClipboardBuffer::kCopyPaste, &result);
EXPECT_EQ(rtf, result); EXPECT_EQ(rtf, result);
} }
#endif // !defined(OS_ANDROID)
// TODO(msisov, tonikitoo): Enable test once ClipboardOzone implements // TODO(msisov, tonikitoo): Enable test once ClipboardOzone implements
// selection support. https://crbug.com/911992 // selection support. https://crbug.com/911992
...@@ -282,6 +286,10 @@ TYPED_TEST(ClipboardTest, UnicodeHTMLTest) { ...@@ -282,6 +286,10 @@ TYPED_TEST(ClipboardTest, UnicodeHTMLTest) {
{ {
ScopedClipboardWriter clipboard_writer(ClipboardBuffer::kCopyPaste); ScopedClipboardWriter clipboard_writer(ClipboardBuffer::kCopyPaste);
clipboard_writer.WriteHTML(markup, url); clipboard_writer.WriteHTML(markup, url);
#if defined(OS_ANDROID)
// Android requires HTML and plain text representations to be written.
clipboard_writer.WriteText(markup);
#endif
} }
EXPECT_THAT(this->GetAvailableTypes(ClipboardBuffer::kCopyPaste), EXPECT_THAT(this->GetAvailableTypes(ClipboardBuffer::kCopyPaste),
...@@ -447,6 +455,10 @@ constexpr U8x4 kN32 = ...@@ -447,6 +455,10 @@ constexpr U8x4 kN32 =
constexpr U8x4 kN32Opaque = constexpr U8x4 kN32Opaque =
(kN32_SkColorType == kRGBA_8888_SkColorType) ? kRGBAOpaque : kBGRAOpaque; (kN32_SkColorType == kRGBA_8888_SkColorType) ? kRGBAOpaque : kBGRAOpaque;
#if !defined(OS_ANDROID)
// TODO(https://crbug.com/1056650): Re-enable these tests after fixing the root
// cause. This test only fails on Android.
// Either RGBA_8888 or BGRA_8888 will be equivalent to N32, but the other // Either RGBA_8888 or BGRA_8888 will be equivalent to N32, but the other
// won't be. // won't be.
TYPED_TEST(ClipboardTest, Bitmap_RGBA_Premul) { TYPED_TEST(ClipboardTest, Bitmap_RGBA_Premul) {
...@@ -467,32 +479,25 @@ TYPED_TEST(ClipboardTest, Bitmap_RGBA_Opaque) { ...@@ -467,32 +479,25 @@ TYPED_TEST(ClipboardTest, Bitmap_RGBA_Opaque) {
SkImageInfo::Make(1, 1, kRGBA_8888_SkColorType, kOpaque_SkAlphaType), SkImageInfo::Make(1, 1, kRGBA_8888_SkColorType, kOpaque_SkAlphaType),
&kRGBAOpaque, &kN32Opaque); &kRGBAOpaque, &kN32Opaque);
} }
#if !defined(OS_ANDROID)
// TODO(https://crbug.com/1056650): Re-enable these tests after fixing the root
// cause. This test only fails on Android.
TYPED_TEST(ClipboardTest, Bitmap_BGRA_Premul) { TYPED_TEST(ClipboardTest, Bitmap_BGRA_Premul) {
TestBitmapWrite( TestBitmapWrite(
&this->clipboard(), &this->clipboard(),
SkImageInfo::Make(1, 1, kBGRA_8888_SkColorType, kPremul_SkAlphaType), SkImageInfo::Make(1, 1, kBGRA_8888_SkColorType, kPremul_SkAlphaType),
&kBGRAPremul, &kN32); &kBGRAPremul, &kN32);
} }
#endif // !defined(OS_ANDROID)
TYPED_TEST(ClipboardTest, Bitmap_BGRA_Unpremul) { TYPED_TEST(ClipboardTest, Bitmap_BGRA_Unpremul) {
TestBitmapWrite( TestBitmapWrite(
&this->clipboard(), &this->clipboard(),
SkImageInfo::Make(1, 1, kBGRA_8888_SkColorType, kUnpremul_SkAlphaType), SkImageInfo::Make(1, 1, kBGRA_8888_SkColorType, kUnpremul_SkAlphaType),
&kBGRAUnpremul, &kN32); &kBGRAUnpremul, &kN32);
} }
#if !defined(OS_ANDROID)
// TODO(https://crbug.com/1056650): Re-enable these tests after fixing the root
// cause. This test only fails on Android.
TYPED_TEST(ClipboardTest, Bitmap_BGRA_Opaque) { TYPED_TEST(ClipboardTest, Bitmap_BGRA_Opaque) {
TestBitmapWrite( TestBitmapWrite(
&this->clipboard(), &this->clipboard(),
SkImageInfo::Make(1, 1, kBGRA_8888_SkColorType, kOpaque_SkAlphaType), SkImageInfo::Make(1, 1, kBGRA_8888_SkColorType, kOpaque_SkAlphaType),
&kBGRAOpaque, &kN32Opaque); &kBGRAOpaque, &kN32Opaque);
} }
#endif // !defined(OS_ANDROID)
// Used by HTMLCanvasElement. // Used by HTMLCanvasElement.
TYPED_TEST(ClipboardTest, Bitmap_F16_Premul) { TYPED_TEST(ClipboardTest, Bitmap_F16_Premul) {
...@@ -537,6 +542,7 @@ TYPED_TEST(ClipboardTest, Bitmap_N32_Premul_2x7) { ...@@ -537,6 +542,7 @@ TYPED_TEST(ClipboardTest, Bitmap_N32_Premul_2x7) {
}; };
TestBitmapWrite(&this->clipboard(), SkImageInfo::MakeN32Premul(2, 7), b, b); TestBitmapWrite(&this->clipboard(), SkImageInfo::MakeN32Premul(2, 7), b, b);
} }
#endif // !defined(OS_ANDROID)
} // namespace } // namespace
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment