Bug 1464096 - 6. Add TextInputDelegate support in GeckoSessionTestRule; r=me
Support TextInputDelegate for use in tests.
MozReview-Commit-ID: DHnzKktsSOU
new file mode 100644
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/java/android/view/inputmethod/CursorAnchorInfo.java
@@ -0,0 +1,15 @@
+/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package android.view.inputmethod;
+
+/**
+ * This dummy class is used when running tests on Android versions prior to 21,
+ * when the CursorAnchorInfo class was first introduced. Without this class,
+ * tests will crash with ClassNotFoundException when the test rule uses reflection
+ * to access the TextInputDelegate interface.
+ */
+public class CursorAnchorInfo {
+}
--- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/rule/GeckoSessionTestRule.java
+++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/rule/GeckoSessionTestRule.java
@@ -7,16 +7,17 @@ package org.mozilla.geckoview.test.rule;
import org.mozilla.gecko.gfx.GeckoDisplay;
import org.mozilla.geckoview.BuildConfig;
import org.mozilla.geckoview.GeckoResponse;
import org.mozilla.geckoview.GeckoRuntime;
import org.mozilla.geckoview.GeckoRuntimeSettings;
import org.mozilla.geckoview.GeckoSession;
import org.mozilla.geckoview.GeckoSessionSettings;
+import org.mozilla.geckoview.SessionTextInput;
import org.mozilla.geckoview.test.rdp.Actor;
import org.mozilla.geckoview.test.rdp.Promise;
import org.mozilla.geckoview.test.rdp.RDPConnection;
import org.mozilla.geckoview.test.rdp.Tab;
import org.mozilla.geckoview.test.util.Callbacks;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.assertThat;
@@ -988,24 +989,36 @@ public class GeckoSessionTestRule extend
* Get the runtime set up for the current test.
*
* @return GeckoRuntime object.
*/
public @NonNull GeckoRuntime getRuntime() {
return sRuntime;
}
- protected static Method getCallbackSetter(final @NonNull Class<?> cls)
- throws NoSuchMethodException {
- return GeckoSession.class.getMethod("set" + cls.getSimpleName(), cls);
+ protected static Object setDelegate(final @NonNull Class<?> cls,
+ final @NonNull GeckoSession session,
+ final @Nullable Object delegate)
+ throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
+ if (cls == GeckoSession.TextInputDelegate.class) {
+ return SessionTextInput.class.getMethod("setDelegate",
+ cls).invoke(session.getTextInput(), delegate);
+ }
+ return GeckoSession.class.getMethod("set" + cls.getSimpleName(),
+ cls).invoke(session, delegate);
}
- protected static Method getCallbackGetter(final @NonNull Class<?> cls)
- throws NoSuchMethodException {
- return GeckoSession.class.getMethod("get" + cls.getSimpleName());
+ protected static Object getDelegate(final @NonNull Class<?> cls,
+ final @NonNull GeckoSession session)
+ throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
+ if (cls == GeckoSession.TextInputDelegate.class) {
+ return SessionTextInput.class.getMethod("getDelegate")
+ .invoke(session.getTextInput());
+ }
+ return GeckoSession.class.getMethod("get" + cls.getSimpleName()).invoke(session);
}
@NonNull
private Set<Class<?>> getCurrentDelegates() {
final List<ExternalDelegate<?>> waitDelegates = mWaitScopeDelegates.getExternalDelegates();
final List<ExternalDelegate<?>> testDelegates = mTestScopeDelegates.getExternalDelegates();
if (waitDelegates.isEmpty() && testDelegates.isEmpty()) {
@@ -1242,18 +1255,17 @@ public class GeckoSessionTestRule extend
}
} else if (!mClosedSession) {
openSession(mMainSession);
}
}
protected void prepareSession(final GeckoSession session) throws Throwable {
for (final Class<?> cls : DEFAULT_DELEGATES) {
- getCallbackSetter(cls).invoke(
- session, mNullDelegates.contains(cls) ? null : mCallbackProxy);
+ setDelegate(cls, session, mNullDelegates.contains(cls) ? null : mCallbackProxy);
}
}
/**
* Call open() on a session, and ensure it's ready for use by the test. In particular,
* remove any extra calls recorded as part of opening the session.
*
* @param session Session to open.
@@ -1644,17 +1656,17 @@ public class GeckoSessionTestRule extend
}
// Make sure all handlers are set though #delegateUntilTestEnd or #delegateDuringNextWait,
// instead of through GeckoSession directly, so that we can still record calls even with
// custom handlers set.
for (final Class<?> ifce : DEFAULT_DELEGATES) {
final Object callback;
try {
- callback = getCallbackGetter(ifce).invoke(session == null ? mMainSession : session);
+ callback = getDelegate(ifce, session == null ? mMainSession : session);
} catch (final NoSuchMethodException | IllegalAccessException |
InvocationTargetException e) {
throw unwrapRuntimeException(e);
}
if (mNullDelegates.contains(ifce)) {
// Null-delegates are initially null but are allowed to be any value.
continue;
}
--- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/util/Callbacks.kt
+++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/util/Callbacks.kt
@@ -3,24 +3,26 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.geckoview.test.util
import org.mozilla.geckoview.GeckoResponse
import org.mozilla.geckoview.GeckoSession
+import android.view.inputmethod.CursorAnchorInfo
+import android.view.inputmethod.ExtractedText
+import android.view.inputmethod.ExtractedTextRequest
+
class Callbacks private constructor() {
- object Default : All {
- }
+ object Default : All
interface All : ContentDelegate, NavigationDelegate, PermissionDelegate, ProgressDelegate,
- PromptDelegate, ScrollDelegate, SelectionActionDelegate,
- TrackingProtectionDelegate {
- }
+ PromptDelegate, ScrollDelegate, SelectionActionDelegate, TextInputDelegate,
+ TrackingProtectionDelegate
interface ContentDelegate : GeckoSession.ContentDelegate {
override fun onTitleChange(session: GeckoSession, title: String) {
}
override fun onFocusRequest(session: GeckoSession) {
}
@@ -129,9 +131,29 @@ class Callbacks private constructor() {
interface SelectionActionDelegate : GeckoSession.SelectionActionDelegate {
override fun onShowActionRequest(session: GeckoSession, selection: GeckoSession.SelectionActionDelegate.Selection, actions: Array<out String>, response: GeckoResponse<String>) {
}
override fun onHideAction(session: GeckoSession, reason: Int) {
}
}
+
+ interface TextInputDelegate : GeckoSession.TextInputDelegate {
+ override fun restartInput(session: GeckoSession, reason: Int) {
+ }
+
+ override fun showSoftInput(session: GeckoSession) {
+ }
+
+ override fun hideSoftInput(session: GeckoSession) {
+ }
+
+ override fun updateSelection(session: GeckoSession, selStart: Int, selEnd: Int, compositionStart: Int, compositionEnd: Int) {
+ }
+
+ override fun updateExtractedText(session: GeckoSession, request: ExtractedTextRequest, text: ExtractedText) {
+ }
+
+ override fun updateCursorAnchorInfo(session: GeckoSession, info: CursorAnchorInfo) {
+ }
+ }
}