summaryrefslogtreecommitdiff
path: root/chromium/ui/android
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-12 14:27:29 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-13 09:35:20 +0000
commitc30a6232df03e1efbd9f3b226777b07e087a1122 (patch)
treee992f45784689f373bcc38d1b79a239ebe17ee23 /chromium/ui/android
parent7b5b123ac58f58ffde0f4f6e488bcd09aa4decd3 (diff)
downloadqtwebengine-chromium-85-based.tar.gz
BASELINE: Update Chromium to 85.0.4183.14085-based
Change-Id: Iaa42f4680837c57725b1344f108c0196741f6057 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/ui/android')
-rw-r--r--chromium/ui/android/BUILD.gn24
-rw-r--r--chromium/ui/android/event_forwarder.cc17
-rw-r--r--chromium/ui/android/event_forwarder.h1
-rw-r--r--chromium/ui/android/junit/AndroidManifest.xml19
-rw-r--r--chromium/ui/android/junit/src/org/chromium/ui/base/ActivityAndroidPermissionDelegateTest.java260
-rw-r--r--chromium/ui/android/junit/src/org/chromium/ui/base/LocalizationUtilsTest.java4
-rw-r--r--chromium/ui/android/junit/src/org/chromium/ui/base/SelectFileDialogTest.java44
-rw-r--r--chromium/ui/android/junit/src/org/chromium/ui/base/TestActivity.java14
-rw-r--r--chromium/ui/android/junit/src/org/chromium/ui/drawable/StateListDrawableBuilderTest.java19
-rw-r--r--chromium/ui/android/junit/src/org/chromium/ui/modaldialog/ModalDialogManagerTest.java15
-rw-r--r--chromium/ui/android/view_android.cc31
-rw-r--r--chromium/ui/android/view_android.h12
-rw-r--r--chromium/ui/android/view_android_unittests.cc4
13 files changed, 411 insertions, 53 deletions
diff --git a/chromium/ui/android/BUILD.gn b/chromium/ui/android/BUILD.gn
index 0f5c728944c..7b8a034042b 100644
--- a/chromium/ui/android/BUILD.gn
+++ b/chromium/ui/android/BUILD.gn
@@ -66,6 +66,7 @@ component("android") {
"//skia",
"//third_party/blink/public:blink_headers",
"//ui/base",
+ "//ui/base/cursor:cursor_base",
"//ui/base/cursor/mojom:cursor_type",
"//ui/compositor",
"//ui/display",
@@ -213,7 +214,9 @@ android_library("ui_utils_java") {
deps = [
"//base:base_java",
"//components/payments/mojom:mojom_java",
- "//third_party/android_deps:android_support_v7_appcompat_java",
+ "//third_party/android_deps:androidx_appcompat_appcompat_java",
+ "//third_party/android_deps:androidx_appcompat_appcompat_resources_java",
+ "//third_party/android_deps:androidx_core_core_java",
"//third_party/blink/public/mojom:mojom_platform_java",
]
}
@@ -317,6 +320,7 @@ android_library("ui_full_java") {
"java/src/org/chromium/ui/resources/system/SystemResourceLoader.java",
"java/src/org/chromium/ui/text/NoUnderlineClickableSpan.java",
"java/src/org/chromium/ui/text/SpanApplier.java",
+ "java/src/org/chromium/ui/util/AccessibilityUtil.java",
"java/src/org/chromium/ui/util/ColorUtils.java",
"java/src/org/chromium/ui/util/TokenHolder.java",
"java/src/org/chromium/ui/vr/VrModeObserver.java",
@@ -345,6 +349,7 @@ android_library("ui_full_java") {
"//base:jni_java",
"//third_party/android_deps:android_support_v7_appcompat_java",
"//third_party/android_deps:androidx_annotation_annotation_java",
+ "//third_party/android_deps:androidx_appcompat_appcompat_resources_java",
"//third_party/android_deps:androidx_asynclayoutinflater_asynclayoutinflater_java",
"//third_party/android_deps:androidx_recyclerview_recyclerview_java",
"//ui/base/cursor/mojom:cursor_type_java",
@@ -366,6 +371,7 @@ android_library("ui_java_test_support") {
"javatests/src/org/chromium/ui/test/util/UiRestriction.java",
"javatests/src/org/chromium/ui/test/util/UiRestrictionSkipCheck.java",
"javatests/src/org/chromium/ui/test/util/modelutil/FakeViewProvider.java",
+ "junit/src/org/chromium/ui/base/TestActivity.java",
]
deps = [
":ui_java",
@@ -378,19 +384,20 @@ android_library("ui_java_test_support") {
}
android_resources("ui_javatest_resources") {
- custom_package = "org.chromium.test.ui"
+ testonly = true
sources = [
"junit/res/layout/inflated_view.xml",
"junit/res/layout/layout_view_builder_test.xml",
"junit/res/layout/main_view.xml",
]
+ android_manifest = "junit/AndroidManifest.xml"
}
junit_binary("ui_junit_tests") {
- package_name = "org.chromium.test.ui"
sources = [
"junit/src/org/chromium/ui/AsyncViewProviderTest.java",
"junit/src/org/chromium/ui/AsyncViewStubTest.java",
+ "junit/src/org/chromium/ui/base/ActivityAndroidPermissionDelegateTest.java",
"junit/src/org/chromium/ui/base/ApplicationViewportInsetSupplierTest.java",
"junit/src/org/chromium/ui/base/ClipboardTest.java",
"junit/src/org/chromium/ui/base/EventOffsetHandlerTest.java",
@@ -425,7 +432,17 @@ junit_binary("ui_junit_tests") {
"//base:base_java_test_support",
"//base:base_junit_test_support",
"//base/test:test_support_java",
+ "//third_party/android_deps:androidx_annotation_annotation_java",
+ "//third_party/android_deps:androidx_appcompat_appcompat_java",
+ "//third_party/android_deps:androidx_appcompat_appcompat_resources_java",
+ "//third_party/android_deps:androidx_asynclayoutinflater_asynclayoutinflater_java",
+ "//third_party/android_deps:androidx_test_core_java",
+ "//third_party/android_deps:androidx_test_ext_junit_java",
+ "//third_party/android_deps:androidx_test_runner_java",
+ "//third_party/hamcrest:hamcrest_java",
+ "//third_party/mockito:mockito_java",
]
+ android_manifest = "junit/AndroidManifest.xml"
}
test("ui_android_unittests") {
@@ -471,6 +488,7 @@ android_library("clipboard_java_test_support") {
deps = [
"//base:base_java",
"//base:base_java_test_support",
+ "//base:jni_java",
]
}
diff --git a/chromium/ui/android/event_forwarder.cc b/chromium/ui/android/event_forwarder.cc
index cd3643cbe37..8eac9e2ecbf 100644
--- a/chromium/ui/android/event_forwarder.cc
+++ b/chromium/ui/android/event_forwarder.cc
@@ -72,6 +72,7 @@ jboolean EventForwarder::OnTouchEvent(JNIEnv* env,
jfloat raw_pos_y,
jint android_tool_type_0,
jint android_tool_type_1,
+ jint android_gesture_classification,
jint android_button_state,
jint android_meta_state,
jboolean for_touch_handle) {
@@ -84,9 +85,9 @@ jboolean EventForwarder::OnTouchEvent(JNIEnv* env,
ui::MotionEventAndroid event(
env, motion_event.obj(), 1.f / view_->GetDipScale(), 0.f, 0.f, 0.f,
time_ms, android_action, pointer_count, history_size, action_index,
- 0 /* action_button */, android_button_state, android_meta_state,
- raw_pos_x - pos_x_0, raw_pos_y - pos_y_0, for_touch_handle, &pointer0,
- &pointer1);
+ 0 /* action_button */, android_gesture_classification,
+ android_button_state, android_meta_state, raw_pos_x - pos_x_0,
+ raw_pos_y - pos_y_0, for_touch_handle, &pointer0, &pointer1);
return view_->OnTouchEvent(event);
}
@@ -113,10 +114,10 @@ void EventForwarder::OnMouseEvent(JNIEnv* env,
ui::MotionEventAndroid event(
env, nullptr /* event */, 1.f / view_->GetDipScale(), 0.f, 0.f, 0.f,
time_ms, android_action, 1 /* pointer_count */, 0 /* history_size */,
- 0 /* action_index */, android_action_button, android_button_state,
- android_meta_state, 0 /* raw_offset_x_pixels */,
- 0 /* raw_offset_y_pixels */, false /* for_touch_handle */, &pointer,
- nullptr);
+ 0 /* action_index */, android_action_button,
+ 0 /* gesture_classification */, android_button_state, android_meta_state,
+ 0 /* raw_offset_x_pixels */, 0 /* raw_offset_y_pixels */,
+ false /* for_touch_handle */, &pointer, nullptr);
view_->OnMouseEvent(event);
}
@@ -168,7 +169,7 @@ jboolean EventForwarder::OnGenericMotionEvent(
ui::MotionEventAndroid::Pointer pointer0(0, x, y, 0, 0, 0, 0, 0);
ui::MotionEventAndroid event(
env, motion_event.obj(), 1.f / view_->GetDipScale(), 0.f, 0.f, 0.f,
- time_ms, 0, 1, 0, 0, 0, 0, 0, 0, 0, false, &pointer0, nullptr);
+ time_ms, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, false, &pointer0, nullptr);
return view_->OnGenericMotionEvent(event);
}
diff --git a/chromium/ui/android/event_forwarder.h b/chromium/ui/android/event_forwarder.h
index 18b75e76384..cfdbd57fa7c 100644
--- a/chromium/ui/android/event_forwarder.h
+++ b/chromium/ui/android/event_forwarder.h
@@ -46,6 +46,7 @@ class EventForwarder {
jfloat raw_pos_y,
jint android_tool_type_0,
jint android_tool_type_1,
+ jint android_gesture_classification,
jint android_button_state,
jint android_meta_state,
jboolean is_touch_handle_event);
diff --git a/chromium/ui/android/junit/AndroidManifest.xml b/chromium/ui/android/junit/AndroidManifest.xml
new file mode 100644
index 00000000000..26fe399d700
--- /dev/null
+++ b/chromium/ui/android/junit/AndroidManifest.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<!-- This manifest is required for tests using
+ androidx.test.core.app.ActivityScenario to work.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="org.chromium.test.ui">
+
+ <!-- Value used by ActivityAndroidPermissionDelegateTest -->
+ <uses-permission android:name="android.permission.INTERNET"/>
+
+ <application android:theme="@style/Theme.AppCompat.Light">
+ <activity android:name="org.chromium.ui.base.TestActivity"/>
+ </application>
+</manifest>
diff --git a/chromium/ui/android/junit/src/org/chromium/ui/base/ActivityAndroidPermissionDelegateTest.java b/chromium/ui/android/junit/src/org/chromium/ui/base/ActivityAndroidPermissionDelegateTest.java
new file mode 100644
index 00000000000..1df70151bcb
--- /dev/null
+++ b/chromium/ui/android/junit/src/org/chromium/ui/base/ActivityAndroidPermissionDelegateTest.java
@@ -0,0 +1,260 @@
+// 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 static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+
+import android.content.pm.PackageManager;
+
+import androidx.test.core.app.ActivityScenario;
+import androidx.test.ext.junit.rules.ActivityScenarioRule;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.robolectric.Shadows;
+import org.robolectric.shadows.ShadowActivity;
+import org.robolectric.shadows.ShadowActivity.PermissionsRequest;
+
+import org.chromium.base.test.BaseRobolectricTestRunner;
+
+import java.lang.ref.WeakReference;
+
+/**
+ * Robolectric unit tests for {@link ActivityAndroidPermissionDelegate} and
+ * {@link AndroidPermissionDelegateWithRequester}.
+ */
+@RunWith(BaseRobolectricTestRunner.class)
+public class ActivityAndroidPermissionDelegateTest {
+ /**
+ * Rule managing the lifecycle of activity in each {@code @Test}.
+ * <p>
+ * To access the activity and run code on its main thread, use
+ * {@link ActivityScenario#onActivity}:
+ * <pre>
+ * mActivityScenarios.getScenario().onActivity(activity -> {
+ * // Your test code using the activity here.
+ * });
+ * </pre>
+ */
+ @Rule
+ public ActivityScenarioRule<TestActivity> mActivityScenarios =
+ new ActivityScenarioRule<>(TestActivity.class);
+
+ @Test
+ public void testHasPermissionDenied() {
+ mActivityScenarios.getScenario().onActivity(activity -> {
+ AndroidPermissionDelegate permissionDelegate =
+ new ActivityAndroidPermissionDelegate(new WeakReference(activity));
+
+ boolean hasPermission =
+ permissionDelegate.hasPermission(android.Manifest.permission.INTERNET);
+
+ assertFalse("The default result of hasPermission should be false", hasPermission);
+ });
+ }
+
+ @Test
+ public void testHasPermissionGranted() {
+ mActivityScenarios.getScenario().onActivity(activity -> {
+ Shadows.shadowOf(activity).grantPermissions(android.Manifest.permission.INTERNET);
+ AndroidPermissionDelegate permissionDelegate =
+ new ActivityAndroidPermissionDelegate(new WeakReference(activity));
+
+ boolean hasPermission =
+ permissionDelegate.hasPermission(android.Manifest.permission.INTERNET);
+
+ assertTrue("hasPermission should return true if permission is granted", hasPermission);
+ });
+ }
+
+ @Test
+ public void testCanRequestPermissionInitial() {
+ mActivityScenarios.getScenario().onActivity(activity -> {
+ AndroidPermissionDelegate permissionDelegate =
+ new ActivityAndroidPermissionDelegate(new WeakReference(activity));
+
+ boolean canRequest =
+ permissionDelegate.canRequestPermission(android.Manifest.permission.INTERNET);
+
+ assertTrue("The default result of canRequestPermission should be true", canRequest);
+ });
+ }
+
+ @Test
+ public void testRequestPermissionsGranted() {
+ mActivityScenarios.getScenario().onActivity(activity -> {
+ AndroidPermissionDelegate permissionDelegate =
+ new ActivityAndroidPermissionDelegate(new WeakReference(activity));
+ PermissionCallback callback = Mockito.mock(PermissionCallback.class);
+
+ // Request permission
+ permissionDelegate.requestPermissions(
+ new String[] {android.Manifest.permission.INTERNET}, callback);
+
+ PermissionsRequest lastRequest =
+ Shadows.shadowOf(activity).getLastRequestedPermission();
+ assertEquals(new String[] {android.Manifest.permission.INTERNET},
+ lastRequest.requestedPermissions);
+ verify(callback,
+ never().description("PermissionCallback should not receive results before "
+ + "handlePermissionResult is invoked"))
+ .onRequestPermissionsResult(any(), any());
+
+ // Respond to the request
+ int[] grantResults = new int[] {PackageManager.PERMISSION_GRANTED};
+ permissionDelegate.handlePermissionResult(
+ lastRequest.requestCode, lastRequest.requestedPermissions, grantResults);
+
+ verify(callback,
+ Mockito.description(
+ "handlePermissionResult should invoke the PermissionCallback"))
+ .onRequestPermissionsResult(lastRequest.requestedPermissions, grantResults);
+ });
+ }
+
+ @Test
+ public void testRequestPermissionsDenied() {
+ mActivityScenarios.getScenario().onActivity(activity -> {
+ AndroidPermissionDelegate permissionDelegate =
+ new ActivityAndroidPermissionDelegate(new WeakReference(activity));
+ PermissionCallback callback = Mockito.mock(PermissionCallback.class);
+
+ // Request permission
+ permissionDelegate.requestPermissions(
+ new String[] {android.Manifest.permission.INTERNET}, callback);
+
+ PermissionsRequest lastRequest =
+ Shadows.shadowOf(activity).getLastRequestedPermission();
+ assertEquals(new String[] {android.Manifest.permission.INTERNET},
+ lastRequest.requestedPermissions);
+ verify(callback,
+ never().description("PermissionCallback should not receive results before "
+ + "handlePermissionResult is invoked"))
+ .onRequestPermissionsResult(any(), any());
+
+ // Respond to the request
+ int[] grantResults = new int[] {PackageManager.PERMISSION_DENIED};
+ permissionDelegate.handlePermissionResult(
+ lastRequest.requestCode, lastRequest.requestedPermissions, grantResults);
+
+ verify(callback,
+ Mockito.description(
+ "handlePermissionResult should invoke the PermissionCallback"))
+ .onRequestPermissionsResult(lastRequest.requestedPermissions, grantResults);
+ });
+ }
+
+ @Test
+ public void testCanRequestPermissionAfterRequestGranted() {
+ mActivityScenarios.getScenario().onActivity(activity -> {
+ AndroidPermissionDelegate permissionDelegate =
+ new ActivityAndroidPermissionDelegate(new WeakReference(activity));
+ performRequestPermission(permissionDelegate, Shadows.shadowOf(activity),
+ android.Manifest.permission.INTERNET, PackageManager.PERMISSION_GRANTED);
+
+ boolean canRequest =
+ permissionDelegate.canRequestPermission(android.Manifest.permission.INTERNET);
+
+ assertTrue("After a granted permission request canRequestPermission should return true",
+ canRequest);
+ });
+ }
+
+ @Test
+ public void testCanRequestPermissionAfterRequestDenied() {
+ mActivityScenarios.getScenario().onActivity(activity -> {
+ AndroidPermissionDelegate permissionDelegate =
+ new ActivityAndroidPermissionDelegate(new WeakReference(activity));
+ performRequestPermission(permissionDelegate, Shadows.shadowOf(activity),
+ android.Manifest.permission.INTERNET, PackageManager.PERMISSION_DENIED);
+
+ boolean canRequest =
+ permissionDelegate.canRequestPermission(android.Manifest.permission.INTERNET);
+
+ assertFalse(
+ "After a denied permission request canRequestPermission should return false",
+ canRequest);
+ });
+ }
+
+ @Test
+ public void testCanRequestPermissionWithShowRequestRationale() {
+ mActivityScenarios.getScenario().onActivity(activity -> {
+ AndroidPermissionDelegate permissionDelegate =
+ new ActivityAndroidPermissionDelegate(new WeakReference(activity));
+ performRequestPermission(permissionDelegate, Shadows.shadowOf(activity),
+ android.Manifest.permission.INTERNET, PackageManager.PERMISSION_DENIED);
+ Shadows.shadowOf(activity.getPackageManager())
+ .setShouldShowRequestPermissionRationale(
+ android.Manifest.permission.INTERNET, true);
+
+ boolean canRequest =
+ permissionDelegate.canRequestPermission(android.Manifest.permission.INTERNET);
+
+ assertTrue("When shouldShowRequestPermissionRationale is true "
+ + "canRequestPermission should return true",
+ canRequest);
+ });
+ }
+
+ @Test
+ public void testCanRequestPermissionAfterHasPermissionGranted() {
+ mActivityScenarios.getScenario().onActivity(activity -> {
+ AndroidPermissionDelegate permissionDelegate =
+ new ActivityAndroidPermissionDelegate(new WeakReference(activity));
+ performRequestPermission(permissionDelegate, Shadows.shadowOf(activity),
+ android.Manifest.permission.INTERNET, PackageManager.PERMISSION_DENIED);
+
+ Shadows.shadowOf(activity).grantPermissions(android.Manifest.permission.INTERNET);
+ permissionDelegate.hasPermission(android.Manifest.permission.INTERNET);
+ Shadows.shadowOf(activity).denyPermissions(android.Manifest.permission.INTERNET);
+
+ boolean canRequest =
+ permissionDelegate.canRequestPermission(android.Manifest.permission.INTERNET);
+
+ assertTrue("After hasPermission sees that a permission is granted "
+ + "canRequestPermission should return true",
+ canRequest);
+ });
+ }
+
+ @Test
+ public void testCanRequestPermissionWhileGranted() {
+ mActivityScenarios.getScenario().onActivity(activity -> {
+ AndroidPermissionDelegate permissionDelegate =
+ new ActivityAndroidPermissionDelegate(new WeakReference(activity));
+ performRequestPermission(permissionDelegate, Shadows.shadowOf(activity),
+ android.Manifest.permission.INTERNET, PackageManager.PERMISSION_DENIED);
+ Shadows.shadowOf(activity).grantPermissions(android.Manifest.permission.INTERNET);
+
+ boolean canRequest =
+ permissionDelegate.canRequestPermission(android.Manifest.permission.INTERNET);
+
+ assertTrue(
+ "If a permission is currently granted canRequestPermission should return true",
+ canRequest);
+ });
+ }
+
+ /**
+ * Calls {@link AndroidPermissionDelegate#requestPermissions} and {@link
+ * AndroidPermissionDelegate#handlePermissionResult} for a single permission.
+ */
+ private void performRequestPermission(AndroidPermissionDelegate permissionDelegate,
+ ShadowActivity shadowActivity, String permission, int grantResult) {
+ permissionDelegate.requestPermissions(
+ new String[] {permission}, Mockito.mock(PermissionCallback.class));
+ PermissionsRequest lastRequest = shadowActivity.getLastRequestedPermission();
+ permissionDelegate.handlePermissionResult(
+ lastRequest.requestCode, lastRequest.requestedPermissions, new int[] {grantResult});
+ }
+}
diff --git a/chromium/ui/android/junit/src/org/chromium/ui/base/LocalizationUtilsTest.java b/chromium/ui/android/junit/src/org/chromium/ui/base/LocalizationUtilsTest.java
index 09724c4210f..2698c6be83e 100644
--- a/chromium/ui/android/junit/src/org/chromium/ui/base/LocalizationUtilsTest.java
+++ b/chromium/ui/android/junit/src/org/chromium/ui/base/LocalizationUtilsTest.java
@@ -4,12 +4,12 @@
package org.chromium.ui.base;
-import android.support.test.filters.SmallTest;
-
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import androidx.test.filters.SmallTest;
+
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.annotation.Config;
diff --git a/chromium/ui/android/junit/src/org/chromium/ui/base/SelectFileDialogTest.java b/chromium/ui/android/junit/src/org/chromium/ui/base/SelectFileDialogTest.java
index 49e622b471b..cd5fe373955 100644
--- a/chromium/ui/android/junit/src/org/chromium/ui/base/SelectFileDialogTest.java
+++ b/chromium/ui/android/junit/src/org/chromium/ui/base/SelectFileDialogTest.java
@@ -5,6 +5,8 @@
package org.chromium.ui.base;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
import android.net.Uri;
import android.webkit.MimeTypeMap;
@@ -16,8 +18,12 @@ import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowMimeTypeMap;
import org.chromium.base.ContextUtils;
+import org.chromium.base.PathUtils;
import org.chromium.base.test.BaseRobolectricTestRunner;
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
@@ -153,4 +159,42 @@ public class SelectFileDialogTest {
assertEquals(task.mFilePaths[1].toString(),
"///storage/emulated/0/DCIM/Camera/IMG_1.jpg");
}
+
+ @Test
+ public void testFilePathSelected() throws IOException {
+ SelectFileDialog selectFileDialog = new SelectFileDialog(0);
+ PathUtils.setPrivateDataDirectorySuffix("test");
+ String dataDir = new File(PathUtils.getDataDirectory()).getCanonicalPath();
+
+ SelectFileDialog.FilePathSelectedTask task = selectFileDialog.new FilePathSelectedTask(
+ ContextUtils.getApplicationContext(), dataDir, null);
+ assertFalse(task.doInBackground());
+
+ task = selectFileDialog.new FilePathSelectedTask(
+ ContextUtils.getApplicationContext(), dataDir + "/tmp/xyz.jpg", null);
+ assertFalse(task.doInBackground());
+
+ task = selectFileDialog.new FilePathSelectedTask(
+ ContextUtils.getApplicationContext(), dataDir + "/../xyz.jpg", null);
+ assertTrue(task.doInBackground());
+
+ task = selectFileDialog.new FilePathSelectedTask(
+ ContextUtils.getApplicationContext(), dataDir + "/tmp/../xyz.jpg", null);
+ assertFalse(task.doInBackground());
+
+ task = selectFileDialog.new FilePathSelectedTask(
+ ContextUtils.getApplicationContext(), "/data/local/tmp.jpg", null);
+ assertTrue(task.doInBackground());
+
+ Path path = new File(dataDir).toPath();
+ String parent = path.getParent().toString();
+ String lastComponent = path.getName(path.getNameCount() - 1).toString();
+ task = selectFileDialog.new FilePathSelectedTask(ContextUtils.getApplicationContext(),
+ parent + "/./" + lastComponent + "/xyz.jpg", null);
+ assertFalse(task.doInBackground());
+
+ task = selectFileDialog.new FilePathSelectedTask(ContextUtils.getApplicationContext(),
+ dataDir + "/../" + lastComponent + "/xyz.jpg", null);
+ assertFalse(task.doInBackground());
+ }
}
diff --git a/chromium/ui/android/junit/src/org/chromium/ui/base/TestActivity.java b/chromium/ui/android/junit/src/org/chromium/ui/base/TestActivity.java
new file mode 100644
index 00000000000..aaabcf4097f
--- /dev/null
+++ b/chromium/ui/android/junit/src/org/chromium/ui/base/TestActivity.java
@@ -0,0 +1,14 @@
+// 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 androidx.appcompat.app.AppCompatActivity;
+
+/**
+ * Activity used in {@code ui/base} tests.
+ * <p>
+ * This activity is declared in {@code ui/android/junit/AndroidManifest.xml}.
+ */
+public class TestActivity extends AppCompatActivity {}
diff --git a/chromium/ui/android/junit/src/org/chromium/ui/drawable/StateListDrawableBuilderTest.java b/chromium/ui/android/junit/src/org/chromium/ui/drawable/StateListDrawableBuilderTest.java
index 4b033999efa..8a13da1e3c3 100644
--- a/chromium/ui/android/junit/src/org/chromium/ui/drawable/StateListDrawableBuilderTest.java
+++ b/chromium/ui/android/junit/src/org/chromium/ui/drawable/StateListDrawableBuilderTest.java
@@ -15,7 +15,6 @@ import org.junit.runner.RunWith;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.shadow.api.Shadow;
-import org.robolectric.shadows.ShadowStateListDrawable;
import org.chromium.base.test.BaseRobolectricTestRunner;
import org.chromium.ui.shadows.ShadowAnimatedStateListDrawable;
@@ -31,23 +30,7 @@ public class StateListDrawableBuilderTest {
private static final int DEFAULT_DRAWABLE = 45678;
@Test
- @Config(sdk = 19)
- public void testPreL() {
- StateListDrawableBuilder b = new StateListDrawableBuilder(RuntimeEnvironment.application);
- b.addState(CHECKED_DRAWABLE, android.R.attr.state_checked);
- b.addState(DEFAULT_DRAWABLE, WILDCARD_STATE);
- StateListDrawable result = b.build();
- assertEquals(result.getClass(), StateListDrawable.class);
- ShadowStateListDrawable drawable = shadowOf(result);
- assertEquals(CHECKED_DRAWABLE,
- shadowOf(drawable.getDrawableForState(CHECKED_STATE)).getCreatedFromResId());
- assertEquals(DEFAULT_DRAWABLE,
- shadowOf(drawable.getDrawableForState(WILDCARD_STATE)).getCreatedFromResId());
- }
-
- @Test
- @Config(sdk = 21)
- public void testPostL() {
+ public void testBuild() {
StateListDrawableBuilder b = new StateListDrawableBuilder(RuntimeEnvironment.application);
b.addState(CHECKED_DRAWABLE, android.R.attr.state_checked);
b.addState(DEFAULT_DRAWABLE, WILDCARD_STATE);
diff --git a/chromium/ui/android/junit/src/org/chromium/ui/modaldialog/ModalDialogManagerTest.java b/chromium/ui/android/junit/src/org/chromium/ui/modaldialog/ModalDialogManagerTest.java
index 0e7e800f582..f23cb9c94ee 100644
--- a/chromium/ui/android/junit/src/org/chromium/ui/modaldialog/ModalDialogManagerTest.java
+++ b/chromium/ui/android/junit/src/org/chromium/ui/modaldialog/ModalDialogManagerTest.java
@@ -79,16 +79,19 @@ public class ModalDialogManagerTest {
@Feature({"ModalDialogManagerObserver"})
public void testModalDialogObserver() {
// Show two dialogs and make sure show is only called on one until it is hidden.
- verify(mObserver, times(0)).onDialogShown(mDialogModels.get(0));
+ verify(mObserver, times(0)).onDialogAdded(mDialogModels.get(0));
mModalDialogManager.showDialog(mDialogModels.get(0), ModalDialogType.APP);
mModalDialogManager.showDialog(mDialogModels.get(1), ModalDialogType.APP);
- verify(mObserver, times(1)).onDialogShown(mDialogModels.get(0));
- verify(mObserver, times(0)).onDialogShown(mDialogModels.get(1));
+ verify(mObserver, times(1)).onDialogAdded(mDialogModels.get(0));
+ verify(mObserver, times(0)).onDialogAdded(mDialogModels.get(1));
- verify(mObserver, times(0)).onDialogHidden(mDialogModels.get(0));
+ verify(mObserver, times(0)).onDialogDismissed(mDialogModels.get(0));
mModalDialogManager.dismissDialog(mDialogModels.get(0), ModalDialogType.APP);
- verify(mObserver, times(1)).onDialogHidden(mDialogModels.get(0));
- verify(mObserver, times(1)).onDialogShown(mDialogModels.get(1));
+ verify(mObserver, times(1)).onDialogDismissed(mDialogModels.get(0));
+ verify(mObserver, times(1)).onDialogAdded(mDialogModels.get(1));
+
+ mModalDialogManager.dismissDialog(mDialogModels.get(1), ModalDialogType.APP);
+ verify(mObserver, times(1)).onLastDialogDismissed();
}
/** Tests showing a dialog when no dialog is currently showing. */
diff --git a/chromium/ui/android/view_android.cc b/chromium/ui/android/view_android.cc
index 7d2e6ded2f0..9de5d840506 100644
--- a/chromium/ui/android/view_android.cc
+++ b/chromium/ui/android/view_android.cc
@@ -14,9 +14,11 @@
#include "base/stl_util.h"
#include "cc/layers/layer.h"
#include "components/viz/common/frame_sinks/copy_output_request.h"
+#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/android/event_forwarder.h"
#include "ui/android/ui_android_jni_headers/ViewAndroidDelegate_jni.h"
#include "ui/android/window_android.h"
+#include "ui/base/cursor/cursor.h"
#include "ui/base/cursor/mojom/cursor_type.mojom-shared.h"
#include "ui/base/layout.h"
#include "ui/events/android/drag_event_android.h"
@@ -25,6 +27,7 @@
#include "ui/events/android/key_event_android.h"
#include "ui/events/android/motion_event_android.h"
#include "ui/gfx/android/java_bitmap.h"
+#include "ui/gfx/geometry/point.h"
#include "url/gurl.h"
namespace ui {
@@ -389,25 +392,25 @@ bool ViewAndroid::StartDragAndDrop(const JavaRef<jstring>& jtext,
jimage);
}
-void ViewAndroid::OnCursorChanged(int type,
- const SkBitmap& custom_image,
- const gfx::Point& hotspot) {
+void ViewAndroid::OnCursorChanged(const Cursor& cursor) {
ScopedJavaLocalRef<jobject> delegate(GetViewAndroidDelegate());
if (delegate.is_null())
return;
JNIEnv* env = base::android::AttachCurrentThread();
- if (type == static_cast<int>(ui::mojom::CursorType::kCustom)) {
- if (custom_image.drawsNothing()) {
+ if (cursor.type() == mojom::CursorType::kCustom) {
+ const SkBitmap& bitmap = cursor.custom_bitmap();
+ const gfx::Point& hotspot = cursor.custom_hotspot();
+ if (bitmap.drawsNothing()) {
Java_ViewAndroidDelegate_onCursorChanged(
- env, delegate, static_cast<int>(ui::mojom::CursorType::kPointer));
+ env, delegate, static_cast<int>(mojom::CursorType::kPointer));
return;
}
- ScopedJavaLocalRef<jobject> java_bitmap =
- gfx::ConvertToJavaBitmap(&custom_image);
+ ScopedJavaLocalRef<jobject> java_bitmap = gfx::ConvertToJavaBitmap(&bitmap);
Java_ViewAndroidDelegate_onCursorChangedToCustom(env, delegate, java_bitmap,
hotspot.x(), hotspot.y());
} else {
- Java_ViewAndroidDelegate_onCursorChanged(env, delegate, type);
+ Java_ViewAndroidDelegate_onCursorChanged(env, delegate,
+ static_cast<int>(cursor.type()));
}
}
@@ -461,6 +464,16 @@ void ViewAndroid::OnBrowserControlsHeightChanged() {
}
}
+void ViewAndroid::OnVerticalScrollDirectionChanged(bool direction_up,
+ float current_scroll_ratio) {
+ ScopedJavaLocalRef<jobject> delegate(GetViewAndroidDelegate());
+ if (delegate.is_null())
+ return;
+ JNIEnv* env = base::android::AttachCurrentThread();
+ Java_ViewAndroidDelegate_onVerticalScrollDirectionChanged(
+ env, delegate, direction_up, current_scroll_ratio);
+}
+
void ViewAndroid::OnSizeChanged(int width, int height) {
// Match-parent view must not receive size events.
DCHECK(!match_parent());
diff --git a/chromium/ui/android/view_android.h b/chromium/ui/android/view_android.h
index cf88a186583..5c989d6b05e 100644
--- a/chromium/ui/android/view_android.h
+++ b/chromium/ui/android/view_android.h
@@ -18,8 +18,6 @@
#include "ui/android/view_android_observer.h"
#include "ui/gfx/geometry/rect_f.h"
-class SkBitmap;
-
namespace cc {
class Layer;
}
@@ -34,6 +32,7 @@ class CopyOutputRequest;
}
namespace ui {
+class Cursor;
class DragEventAndroid;
class EventForwarder;
class EventHandlerAndroid;
@@ -154,9 +153,7 @@ class UI_ANDROID_EXPORT ViewAndroid {
void OnSizeChanged(int width, int height);
void OnPhysicalBackingSizeChanged(const gfx::Size& size);
- void OnCursorChanged(int type,
- const SkBitmap& custom_image,
- const gfx::Point& hotspot);
+ void OnCursorChanged(const Cursor& cursor);
void OnBackgroundColorChanged(unsigned int color);
void OnTopControlsChanged(float top_controls_offset,
float top_content_offset,
@@ -164,6 +161,11 @@ class UI_ANDROID_EXPORT ViewAndroid {
void OnBottomControlsChanged(float bottom_controls_offset,
float bottom_controls_min_height_offset);
void OnBrowserControlsHeightChanged();
+ // |current_scroll_ratio| is the ratio of vertical scroll in [0, 1] range.
+ // Scroll at top of page is 0, and bottom of page is 1. It is defined as 0
+ // if page is not scrollable, though this should not be called in that case.
+ void OnVerticalScrollDirectionChanged(bool direction_up,
+ float current_scroll_ratio);
// Gets the Visual Viewport inset to apply in physical pixels.
int GetViewportInsetBottom();
diff --git a/chromium/ui/android/view_android_unittests.cc b/chromium/ui/android/view_android_unittests.cc
index d42e19b6484..b24c1ad5285 100644
--- a/chromium/ui/android/view_android_unittests.cc
+++ b/chromium/ui/android/view_android_unittests.cc
@@ -76,8 +76,8 @@ class ViewAndroidBoundsTest : public testing::Test {
ui::MotionEventAndroid::Pointer pointer0(0, x, y, 0, 0, 0, 0, 0);
ui::MotionEventAndroid::Pointer pointer1(0, 0, 0, 0, 0, 0, 0, 0);
ui::MotionEventAndroid event(nullptr, JavaParamRef<jobject>(nullptr), 1.f,
- 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, false,
- &pointer0, &pointer1);
+ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ false, &pointer0, &pointer1);
root_.OnTouchEvent(event);
}