blob: 87cd773cb26fcafd0018b070177561629425a332 [file] [log] [blame]
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.cts.mockime;
import static android.inputmethodservice.InputMethodService.FINISH_INPUT_NO_FALLBACK_CONNECTION;
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity;
import android.app.UiAutomation;
import android.app.compat.CompatChanges;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.ParcelFileDescriptor;
import android.os.SystemClock;
import android.os.UserHandle;
import android.provider.Settings;
import android.text.TextUtils;
import android.view.KeyEvent;
import android.view.inputmethod.CompletionInfo;
import android.view.inputmethod.CorrectionInfo;
import android.view.inputmethod.ExtractedTextRequest;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputContentInfo;
import android.view.inputmethod.InputMethodManager;
import android.view.inputmethod.TextAttribute;
import androidx.annotation.AnyThread;
import androidx.annotation.GuardedBy;
import androidx.annotation.IntRange;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.compatibility.common.util.PollingCheck;
import org.junit.AssumptionViolatedException;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* Represents an active Mock IME session, which provides basic primitives to write end-to-end tests
* for IME APIs.
*
* <p>To use {@link MockIme} via {@link MockImeSession}, you need to </p>
* <p>Public methods are not thread-safe.</p>
*/
public class MockImeSession implements AutoCloseable {
private final String mImeEventActionName =
"com.android.cts.mockime.action.IME_EVENT." + SystemClock.elapsedRealtimeNanos();
private static final long TIMEOUT = TimeUnit.SECONDS.toMillis(10);
@NonNull
private final Context mContext;
@NonNull
private final UiAutomation mUiAutomation;
@NonNull
private final AtomicBoolean mActive = new AtomicBoolean(true);
private final HandlerThread mHandlerThread = new HandlerThread("EventReceiver");
private static final class EventStore {
private static final int INITIAL_ARRAY_SIZE = 32;
@NonNull
public final ImeEvent[] mArray;
public int mLength;
EventStore() {
mArray = new ImeEvent[INITIAL_ARRAY_SIZE];
mLength = 0;
}
EventStore(EventStore src, int newLength) {
mArray = new ImeEvent[newLength];
mLength = src.mLength;
System.arraycopy(src.mArray, 0, mArray, 0, src.mLength);
}
public EventStore add(ImeEvent event) {
if (mLength + 1 <= mArray.length) {
mArray[mLength] = event;
++mLength;
return this;
} else {
return new EventStore(this, mLength * 2).add(event);
}
}
public ImeEventStream.ImeEventArray takeSnapshot() {
return new ImeEventStream.ImeEventArray(mArray, mLength);
}
}
private static final class MockImeEventReceiver extends BroadcastReceiver {
private final Object mLock = new Object();
@GuardedBy("mLock")
@NonNull
private EventStore mCurrentEventStore = new EventStore();
@NonNull
private final String mActionName;
MockImeEventReceiver(@NonNull String actionName) {
mActionName = actionName;
}
@Override
public void onReceive(Context context, Intent intent) {
if (TextUtils.equals(mActionName, intent.getAction())) {
synchronized (mLock) {
mCurrentEventStore =
mCurrentEventStore.add(ImeEvent.fromBundle(intent.getExtras()));
}
}
}
public ImeEventStream.ImeEventArray takeEventSnapshot() {
synchronized (mLock) {
return mCurrentEventStore.takeSnapshot();
}
}
}
private final MockImeEventReceiver mEventReceiver =
new MockImeEventReceiver(mImeEventActionName);
private final ImeEventStream mEventStream =
new ImeEventStream(mEventReceiver::takeEventSnapshot);
private static String executeShellCommand(
@NonNull UiAutomation uiAutomation, @NonNull String command) throws IOException {
try (ParcelFileDescriptor.AutoCloseInputStream in =
new ParcelFileDescriptor.AutoCloseInputStream(
uiAutomation.executeShellCommand(command))) {
final StringBuilder sb = new StringBuilder();
final byte[] buffer = new byte[4096];
while (true) {
final int numRead = in.read(buffer);
if (numRead <= 0) {
break;
}
sb.append(new String(buffer, 0, numRead));
}
return sb.toString();
}
}
@Nullable
private String getCurrentInputMethodId() {
// TODO: Replace this with IMM#getCurrentInputMethodIdForTesting()
return Settings.Secure.getString(mContext.getContentResolver(),
Settings.Secure.DEFAULT_INPUT_METHOD);
}
@Nullable
private static void writeMockImeSettings(@NonNull Context context,
@NonNull String imeEventActionName,
@Nullable ImeSettings.Builder imeSettings) throws Exception {
final Bundle bundle = ImeSettings.serializeToBundle(imeEventActionName, imeSettings);
context.getContentResolver().call(SettingsProvider.AUTHORITY, "write", null, bundle);
}
private ComponentName getMockImeComponentName() {
return MockIme.getComponentName();
}
private String getMockImeId() {
return MockIme.getImeId();
}
private MockImeSession(@NonNull Context context, @NonNull UiAutomation uiAutomation) {
mContext = context;
mUiAutomation = uiAutomation;
}
private void initialize(@Nullable ImeSettings.Builder imeSettings) throws Exception {
// Make sure that MockIME is not selected.
if (mContext.getSystemService(InputMethodManager.class)
.getInputMethodList()
.stream()
.anyMatch(info -> getMockImeComponentName().equals(info.getComponent()))) {
executeShellCommand(mUiAutomation, "ime reset");
}
if (mContext.getSystemService(InputMethodManager.class)
.getEnabledInputMethodList()
.stream()
.anyMatch(info -> getMockImeComponentName().equals(info.getComponent()))) {
throw new IllegalStateException();
}
writeMockImeSettings(mContext, mImeEventActionName, imeSettings);
mHandlerThread.start();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
mContext.registerReceiver(mEventReceiver,
new IntentFilter(mImeEventActionName), null /* broadcastPermission */,
new Handler(mHandlerThread.getLooper()), Context.RECEIVER_EXPORTED);
} else {
mContext.registerReceiver(mEventReceiver,
new IntentFilter(mImeEventActionName), null /* broadcastPermission */,
new Handler(mHandlerThread.getLooper()));
}
executeShellCommand(mUiAutomation, "ime enable " + getMockImeId());
executeShellCommand(mUiAutomation, "ime set " + getMockImeId());
PollingCheck.check("Make sure that MockIME becomes available", TIMEOUT,
() -> getMockImeId().equals(getCurrentInputMethodId()));
}
/** @see #create(Context, UiAutomation, ImeSettings.Builder) */
@NonNull
public static MockImeSession create(@NonNull Context context) throws Exception {
return create(context, getInstrumentation().getUiAutomation(), new ImeSettings.Builder());
}
/**
* Creates a new Mock IME session. During this session, you can receive various events from
* {@link MockIme}.
*
* @param context {@link Context} to be used to receive inter-process events from the
* {@link MockIme} (e.g. via {@link BroadcastReceiver}
* @param uiAutomation {@link UiAutomation} object to change the device state that are typically
* guarded by permissions.
* @param imeSettings Key-value pairs to be passed to the {@link MockIme}.
* @return A session object, with which you can retrieve event logs from the {@link MockIme} and
* can clean up the session.
*/
@NonNull
public static MockImeSession create(
@NonNull Context context,
@NonNull UiAutomation uiAutomation,
@Nullable ImeSettings.Builder imeSettings) throws Exception {
final String unavailabilityReason = getUnavailabilityReason(context);
if (unavailabilityReason != null) {
throw new AssumptionViolatedException(unavailabilityReason);
}
final MockImeSession client = new MockImeSession(context, uiAutomation);
client.initialize(imeSettings);
return client;
}
/**
* Checks if the {@link MockIme} can be used in this device.
*
* @return {@code null} if it can be used, or message describing why if it cannot.
*/
@Nullable
public static String getUnavailabilityReason(@NonNull Context context) {
if (!context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_INPUT_METHODS)) {
return "Device must support installable IMEs that implement InputMethodService API";
}
return null;
}
/**
* Whether {@link MockIme} enabled a compatibility flag to finish input without fallback
* input connection when device interactive state changed. See detailed description in
* {@link MockImeSession#setEnabledFinishInputNoFallbackConnection}.
*
* @return {@code true} if the compatibility flag is enabled.
*/
public static boolean isFinishInputNoFallbackConnectionEnabled() {
AtomicBoolean result = new AtomicBoolean();
runWithShellPermissionIdentity(() ->
result.set(CompatChanges.isChangeEnabled(FINISH_INPUT_NO_FALLBACK_CONNECTION,
MockIme.getComponentName().getPackageName(), UserHandle.CURRENT)));
return result.get();
}
/**
* @return {@link ImeEventStream} object that stores events sent from {@link MockIme} since the
* session is created.
*/
public ImeEventStream openEventStream() {
return mEventStream.copy();
}
/**
* @return {@code true} until {@link #close()} gets called.
*/
@AnyThread
public boolean isActive() {
return mActive.get();
}
/**
* Closes the active session and de-selects {@link MockIme}. Currently which IME will be
* selected next is up to the system.
*/
public void close() throws Exception {
mActive.set(false);
executeShellCommand(mUiAutomation, "ime reset");
PollingCheck.check("Make sure that MockIME becomes unavailable", TIMEOUT, () ->
mContext.getSystemService(InputMethodManager.class)
.getEnabledInputMethodList()
.stream()
.noneMatch(info -> getMockImeComponentName().equals(info.getComponent())));
mContext.unregisterReceiver(mEventReceiver);
mHandlerThread.quitSafely();
mContext.getContentResolver().call(SettingsProvider.AUTHORITY, "delete", null, null);
}
/**
* Common logic to send a special command to {@link MockIme}.
*
* @param commandName command to be passed to {@link MockIme}
* @param params {@link Bundle} to be passed to {@link MockIme} as a parameter set of
* {@code commandName}
* @return {@link ImeCommand} that is sent to {@link MockIme}. It can be passed to
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to
* wait until this event is handled by {@link MockIme}.
*/
@NonNull
private ImeCommand callCommandInternal(@NonNull String commandName, @NonNull Bundle params) {
final ImeCommand command = new ImeCommand(
commandName, SystemClock.elapsedRealtimeNanos(), true, params);
final Intent intent = new Intent();
intent.setPackage(MockIme.getComponentName().getPackageName());
intent.setAction(MockIme.getCommandActionName(mImeEventActionName));
intent.putExtras(command.toBundle());
mContext.sendBroadcast(intent);
return command;
}
/**
* Lets {@link MockIme} suspend {@link MockIme.AbstractInputMethodImpl#createSession(
* android.view.inputmethod.InputMethod.SessionCallback)} until {@link #resumeCreateSession()}.
*
* <p>This is useful to test a tricky timing issue that the IME client initiated the
* IME session but {@link android.view.inputmethod.InputMethodSession} is not available
* yet.</p>
*
* <p>For simplicity and stability, {@link #suspendCreateSession()} must be called before
* {@link MockIme.AbstractInputMethodImpl#createSession(
* android.view.inputmethod.InputMethod.SessionCallback)} gets called again.</p>
*
* @return {@link ImeCommand} object that can be passed to
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to
* wait until this event is handled by {@link MockIme}.
*/
@NonNull
public ImeCommand suspendCreateSession() {
return callCommandInternal("suspendCreateSession", new Bundle());
}
/**
* Lets {@link MockIme} resume suspended {@link MockIme.AbstractInputMethodImpl#createSession(
* android.view.inputmethod.InputMethod.SessionCallback)}.
*
* <p>Does nothing if {@link #suspendCreateSession()} was not called.</p>
*
* @return {@link ImeCommand} object that can be passed to
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to
* wait until this event is handled by {@link MockIme}.
*/
@NonNull
public ImeCommand resumeCreateSession() {
return callCommandInternal("resumeCreateSession", new Bundle());
}
/**
* Lets {@link MockIme} to call
* {@link android.inputmethodservice.InputMethodService#getCurrentInputConnection()} and
* memorize it for later {@link InputConnection}-related operations.
*
* <p>Only the last one will be memorized if this method gets called multiple times.</p>
*
* @return {@link ImeCommand} object that can be passed to
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to
* wait until this event is handled by {@link MockIme}.
* @see #unmemorizeCurrentInputConnection()
*/
@NonNull
public ImeCommand memorizeCurrentInputConnection() {
final Bundle params = new Bundle();
return callCommandInternal("memorizeCurrentInputConnection", params);
}
/**
* Lets {@link MockIme} to forget memorized {@link InputConnection} if any. Does nothing
* otherwise.
*
* @return {@link ImeCommand} object that can be passed to
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to
* wait until this event is handled by {@link MockIme}.
* @see #memorizeCurrentInputConnection()
*/
@NonNull
public ImeCommand unmemorizeCurrentInputConnection() {
final Bundle params = new Bundle();
return callCommandInternal("unmemorizeCurrentInputConnection", params);
}
/**
* Lets {@link MockIme} to call {@link InputConnection#getTextBeforeCursor(int, int)} with the
* given parameters.
*
* <p>This triggers {@code getCurrentInputConnection().getTextBeforeCursor(n, flag)}.</p>
*
* <p>Use {@link ImeEvent#getReturnCharSequenceValue()} for {@link ImeEvent} returned from
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to see the
* value returned from the API.</p>
*
* <p>This can be affected by {@link #memorizeCurrentInputConnection()}.</p>
*
* @param n to be passed as the {@code n} parameter.
* @param flag to be passed as the {@code flag} parameter.
* @return {@link ImeCommand} object that can be passed to
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to
* wait until this event is handled by {@link MockIme}.
*/
@NonNull
public ImeCommand callGetTextBeforeCursor(int n, int flag) {
final Bundle params = new Bundle();
params.putInt("n", n);
params.putInt("flag", flag);
return callCommandInternal("getTextBeforeCursor", params);
}
/**
* Lets {@link MockIme} to call {@link InputConnection#getTextAfterCursor(int, int)} with the
* given parameters.
*
* <p>This triggers {@code getCurrentInputConnection().getTextAfterCursor(n, flag)}.</p>
*
* <p>Use {@link ImeEvent#getReturnCharSequenceValue()} for {@link ImeEvent} returned from
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to see the
* value returned from the API.</p>
*
* <p>This can be affected by {@link #memorizeCurrentInputConnection()}.</p>
*
* @param n to be passed as the {@code n} parameter.
* @param flag to be passed as the {@code flag} parameter.
* @return {@link ImeCommand} object that can be passed to
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to
* wait until this event is handled by {@link MockIme}.
*/
@NonNull
public ImeCommand callGetTextAfterCursor(int n, int flag) {
final Bundle params = new Bundle();
params.putInt("n", n);
params.putInt("flag", flag);
return callCommandInternal("getTextAfterCursor", params);
}
/**
* Lets {@link MockIme} to call {@link InputConnection#getSelectedText(int)} with the
* given parameters.
*
* <p>This triggers {@code getCurrentInputConnection().getSelectedText(flag)}.</p>
*
* <p>Use {@link ImeEvent#getReturnCharSequenceValue()} for {@link ImeEvent} returned from
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to see the
* value returned from the API.</p>
*
* <p>This can be affected by {@link #memorizeCurrentInputConnection()}.</p>
*
* @param flag to be passed as the {@code flag} parameter.
* @return {@link ImeCommand} object that can be passed to
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to
* wait until this event is handled by {@link MockIme}.
*/
@NonNull
public ImeCommand callGetSelectedText(int flag) {
final Bundle params = new Bundle();
params.putInt("flag", flag);
return callCommandInternal("getSelectedText", params);
}
/**
* Lets {@link MockIme} to call {@link InputConnection#getSurroundingText(int, int, int)} with
* the given parameters.
*
* <p>This triggers {@code getCurrentInputConnection().getSurroundingText(int, int, int)}.</p>
*
* <p>Use {@link ImeEvent#getReturnParcelableValue()} for {@link ImeEvent} returned from
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to see the
* value returned from the API.</p>
*
* <p>This can be affected by {@link #memorizeCurrentInputConnection()}.</p>
*
* @param beforeLength The expected length of the text before the cursor.
* @param afterLength The expected length of the text after the cursor.
* @param flags Supplies additional options controlling how the text is returned. May be either
* {@code 0} or {@link InputConnection#GET_TEXT_WITH_STYLES}.
* @return {@link ImeCommand} object that can be passed to
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to
* wait until this event is handled by {@link MockIme}.
*/
@NonNull
public ImeCommand callGetSurroundingText(@IntRange(from = 0) int beforeLength,
@IntRange(from = 0) int afterLength, int flags) {
final Bundle params = new Bundle();
params.putInt("beforeLength", beforeLength);
params.putInt("afterLength", afterLength);
params.putInt("flags", flags);
return callCommandInternal("getSurroundingText", params);
}
/**
* Lets {@link MockIme} to call {@link InputConnection#getCursorCapsMode(int)} with the given
* parameters.
*
* <p>This triggers {@code getCurrentInputConnection().getCursorCapsMode(reqModes)}.</p>
*
* <p>Use {@link ImeEvent#getReturnIntegerValue()} for {@link ImeEvent} returned from
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to see the
* value returned from the API.</p>
*
* <p>This can be affected by {@link #memorizeCurrentInputConnection()}.</p>
*
* @param reqModes to be passed as the {@code reqModes} parameter.
* @return {@link ImeCommand} object that can be passed to
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to
* wait until this event is handled by {@link MockIme}.
*/
@NonNull
public ImeCommand callGetCursorCapsMode(int reqModes) {
final Bundle params = new Bundle();
params.putInt("reqModes", reqModes);
return callCommandInternal("getCursorCapsMode", params);
}
/**
* Lets {@link MockIme} to call
* {@link InputConnection#getExtractedText(ExtractedTextRequest, int)} with the given
* parameters.
*
* <p>This triggers {@code getCurrentInputConnection().getExtractedText(request, flags)}.</p>
*
* <p>Use {@link ImeEvent#getReturnParcelableValue()} for {@link ImeEvent} returned from
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to see the
* value returned from the API.</p>
*
* <p>This can be affected by {@link #memorizeCurrentInputConnection()}.</p>
*
* @param request to be passed as the {@code request} parameter
* @param flags to be passed as the {@code flags} parameter
* @return {@link ImeCommand} object that can be passed to
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to
* wait until this event is handled by {@link MockIme}.
*/
@NonNull
public ImeCommand callGetExtractedText(@Nullable ExtractedTextRequest request, int flags) {
final Bundle params = new Bundle();
params.putParcelable("request", request);
params.putInt("flags", flags);
return callCommandInternal("getExtractedText", params);
}
/**
* Lets {@link MockIme} to call {@link InputConnection#deleteSurroundingText(int, int)} with the
* given parameters.
*
* <p>This triggers
* {@code getCurrentInputConnection().deleteSurroundingText(beforeLength, afterLength)}.</p>
*
* <p>Use {@link ImeEvent#getReturnBooleanValue()} for {@link ImeEvent} returned from
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to see the
* value returned from the API.</p>
*
* <p>This can be affected by {@link #memorizeCurrentInputConnection()}.</p>
*
* @param beforeLength to be passed as the {@code beforeLength} parameter
* @param afterLength to be passed as the {@code afterLength} parameter
* @return {@link ImeCommand} object that can be passed to
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to
* wait until this event is handled by {@link MockIme}.
*/
@NonNull
public ImeCommand callDeleteSurroundingText(int beforeLength, int afterLength) {
final Bundle params = new Bundle();
params.putInt("beforeLength", beforeLength);
params.putInt("afterLength", afterLength);
return callCommandInternal("deleteSurroundingText", params);
}
/**
* Lets {@link MockIme} to call
* {@link InputConnection#deleteSurroundingTextInCodePoints(int, int)} with the given
* parameters.
*
* <p>This triggers {@code getCurrentInputConnection().deleteSurroundingTextInCodePoints(
* beforeLength, afterLength)}.</p>
*
* <p>Use {@link ImeEvent#getReturnBooleanValue()} for {@link ImeEvent} returned from
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to see the
* value returned from the API.</p>
*
* <p>This can be affected by {@link #memorizeCurrentInputConnection()}.</p>
*
* @param beforeLength to be passed as the {@code beforeLength} parameter
* @param afterLength to be passed as the {@code afterLength} parameter
* @return {@link ImeCommand} object that can be passed to
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to
* wait until this event is handled by {@link MockIme}.
*/
@NonNull
public ImeCommand callDeleteSurroundingTextInCodePoints(int beforeLength, int afterLength) {
final Bundle params = new Bundle();
params.putInt("beforeLength", beforeLength);
params.putInt("afterLength", afterLength);
return callCommandInternal("deleteSurroundingTextInCodePoints", params);
}
/**
* Lets {@link MockIme} to call {@link InputConnection#setComposingText(CharSequence, int)} with
* the given parameters.
*
* <p>This triggers
* {@code getCurrentInputConnection().setComposingText(text, newCursorPosition)}.</p>
*
* <p>Use {@link ImeEvent#getReturnBooleanValue()} for {@link ImeEvent} returned from
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to see the
* value returned from the API.</p>
*
* <p>This can be affected by {@link #memorizeCurrentInputConnection()}.</p>
*
* @param text to be passed as the {@code text} parameter
* @param newCursorPosition to be passed as the {@code newCursorPosition} parameter
* @return {@link ImeCommand} object that can be passed to
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to
* wait until this event is handled by {@link MockIme}.
*/
@NonNull
public ImeCommand callSetComposingText(@Nullable CharSequence text, int newCursorPosition) {
final Bundle params = new Bundle();
params.putCharSequence("text", text);
params.putInt("newCursorPosition", newCursorPosition);
return callCommandInternal("setComposingText(CharSequence,int)", params);
}
/**
* Lets {@link MockIme} to call
* {@link InputConnection#setComposingText(CharSequence, int, TextAttribute)} with the given
* parameters.
*
* <p>This triggers
* {@code getCurrentInputConnection().setComposingText(text, newCursorPosition, textAttribute)}.
* </p>
*
* <p>Use {@link ImeEvent#getReturnBooleanValue()} for {@link ImeEvent} returned from
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to see the
* value returned from the API.</p>
*
* <p>This can be affected by {@link #memorizeCurrentInputConnection()}.</p>
*
* @param text to be passed as the {@code text} parameter
* @param newCursorPosition to be passed as the {@code newCursorPosition} parameter
* @param textAttribute to be passed as the {@code textAttribute} parameter
* @return {@link ImeCommand} object that can be passed to
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to
* wait until this event is handled by {@link MockIme}
*/
@NonNull
public ImeCommand callSetComposingText(@Nullable CharSequence text, int newCursorPosition,
@Nullable TextAttribute textAttribute) {
final Bundle params = new Bundle();
params.putCharSequence("text", text);
params.putInt("newCursorPosition", newCursorPosition);
params.putParcelable("textAttribute", textAttribute);
return callCommandInternal("setComposingText(CharSequence,int,TextAttribute)", params);
}
/**
* Lets {@link MockIme} to call {@link InputConnection#setComposingRegion(int, int)} with the
* given parameters.
*
* <p>This triggers {@code getCurrentInputConnection().setComposingRegion(start, end)}.</p>
*
* <p>Use {@link ImeEvent#getReturnBooleanValue()} for {@link ImeEvent} returned from
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to see the
* value returned from the API.</p>
*
* <p>This can be affected by {@link #memorizeCurrentInputConnection()}.</p>
*
* @param start to be passed as the {@code start} parameter
* @param end to be passed as the {@code end} parameter
* @return {@link ImeCommand} object that can be passed to
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to
* wait until this event is handled by {@link MockIme}.
*/
@NonNull
public ImeCommand callSetComposingRegion(int start, int end) {
final Bundle params = new Bundle();
params.putInt("start", start);
params.putInt("end", end);
return callCommandInternal("setComposingRegion(int,int)", params);
}
/**
* Lets {@link MockIme} to call
* {@link InputConnection#setComposingRegion(int, int, TextAttribute)} with the given
* parameters.
*
* <p>This triggers
* {@code getCurrentInputConnection().setComposingRegion(start, end, TextAttribute)}.</p>
*
* <p>Use {@link ImeEvent#getReturnBooleanValue()} for {@link ImeEvent} returned from
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to see the
* value returned from the API.</p>
*
* <p>This can be affected by {@link #memorizeCurrentInputConnection()}.</p>
*
* @param start to be passed as the {@code start} parameter
* @param end to be passed as the {@code end} parameter
* @return {@link ImeCommand} object that can be passed to
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to
* wait until this event is handled by {@link MockIme}.
*/
@NonNull
public ImeCommand callSetComposingRegion(int start, int end,
@Nullable TextAttribute textAttribute) {
final Bundle params = new Bundle();
params.putInt("start", start);
params.putInt("end", end);
params.putParcelable("textAttribute", textAttribute);
return callCommandInternal("setComposingRegion(int,int,TextAttribute)", params);
}
/**
* Lets {@link MockIme} to call {@link InputConnection#finishComposingText()} with the given
* parameters.
*
* <p>This triggers {@code getCurrentInputConnection().finishComposingText()}.</p>
*
* <p>Use {@link ImeEvent#getReturnBooleanValue()} for {@link ImeEvent} returned from
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to see the
* value returned from the API.</p>
*
* <p>This can be affected by {@link #memorizeCurrentInputConnection()}.</p>
*
* @return {@link ImeCommand} object that can be passed to
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to
* wait until this event is handled by {@link MockIme}.
*/
@NonNull
public ImeCommand callFinishComposingText() {
final Bundle params = new Bundle();
return callCommandInternal("finishComposingText", params);
}
/**
* Lets {@link MockIme} to call {@link InputConnection#commitText(CharSequence, int)} with the
* given parameters.
*
* <p>This triggers {@code getCurrentInputConnection().commitText(text, newCursorPosition)}.</p>
*
* <p>Use {@link ImeEvent#getReturnBooleanValue()} for {@link ImeEvent} returned from
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to see the
* value returned from the API.</p>
*
* <p>This can be affected by {@link #memorizeCurrentInputConnection()}.</p>
*
* @param text to be passed as the {@code text} parameter
* @param newCursorPosition to be passed as the {@code newCursorPosition} parameter
* @return {@link ImeCommand} object that can be passed to
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to
* wait until this event is handled by {@link MockIme}
*/
@NonNull
public ImeCommand callCommitText(@Nullable CharSequence text, int newCursorPosition) {
final Bundle params = new Bundle();
params.putCharSequence("text", text);
params.putInt("newCursorPosition", newCursorPosition);
return callCommandInternal("commitText(CharSequence,int)", params);
}
/**
* Lets {@link MockIme} to call
* {@link InputConnection#commitText(CharSequence, int, TextAttribute)} with the given
* parameters.
*
* <p>This triggers
* {@code getCurrentInputConnection().commitText(text, newCursorPosition, TextAttribute)}.</p>
*
* <p>Use {@link ImeEvent#getReturnBooleanValue()} for {@link ImeEvent} returned from
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to see the
* value returned from the API.</p>
*
* <p>This can be affected by {@link #memorizeCurrentInputConnection()}.</p>
*
* @param text to be passed as the {@code text} parameter
* @param newCursorPosition to be passed as the {@code newCursorPosition} parameter
* @return {@link ImeCommand} object that can be passed to
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to
* wait until this event is handled by {@link MockIme}
*/
@NonNull
public ImeCommand callCommitText(@Nullable CharSequence text, int newCursorPosition,
@Nullable TextAttribute textAttribute) {
final Bundle params = new Bundle();
params.putCharSequence("text", text);
params.putInt("newCursorPosition", newCursorPosition);
params.putParcelable("textAttribute", textAttribute);
return callCommandInternal("commitText(CharSequence,int,TextAttribute)", params);
}
/**
* Lets {@link MockIme} to call {@link InputConnection#commitCompletion(CompletionInfo)} with
* the given parameters.
*
* <p>This triggers {@code getCurrentInputConnection().commitCompletion(text)}.</p>
*
* <p>Use {@link ImeEvent#getReturnBooleanValue()} for {@link ImeEvent} returned from
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to see the
* value returned from the API.</p>
*
* <p>This can be affected by {@link #memorizeCurrentInputConnection()}.</p>
*
* @param text to be passed as the {@code text} parameter
* @return {@link ImeCommand} object that can be passed to
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to
* wait until this event is handled by {@link MockIme}
*/
@NonNull
public ImeCommand callCommitCompletion(@Nullable CompletionInfo text) {
final Bundle params = new Bundle();
params.putParcelable("text", text);
return callCommandInternal("commitCompletion", params);
}
/**
* Lets {@link MockIme} to call {@link InputConnection#commitCorrection(CorrectionInfo)} with
* the given parameters.
*
* <p>This triggers {@code getCurrentInputConnection().commitCorrection(correctionInfo)}.</p>
*
* <p>Use {@link ImeEvent#getReturnBooleanValue()} for {@link ImeEvent} returned from
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to see the
* value returned from the API.</p>
*
* <p>This can be affected by {@link #memorizeCurrentInputConnection()}.</p>
*
* @param correctionInfo to be passed as the {@code correctionInfo} parameter
* @return {@link ImeCommand} object that can be passed to
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to
* wait until this event is handled by {@link MockIme}
*/
@NonNull
public ImeCommand callCommitCorrection(@Nullable CorrectionInfo correctionInfo) {
final Bundle params = new Bundle();
params.putParcelable("correctionInfo", correctionInfo);
return callCommandInternal("commitCorrection", params);
}
/**
* Lets {@link MockIme} to call {@link InputConnection#setSelection(int, int)} with the given
* parameters.
*
* <p>This triggers {@code getCurrentInputConnection().setSelection(start, end)}.</p>
*
* <p>Use {@link ImeEvent#getReturnBooleanValue()} for {@link ImeEvent} returned from
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to see the
* value returned from the API.</p>
*
* <p>This can be affected by {@link #memorizeCurrentInputConnection()}.</p>
*
* @param start to be passed as the {@code start} parameter
* @param end to be passed as the {@code end} parameter
* @return {@link ImeCommand} object that can be passed to
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to
* wait until this event is handled by {@link MockIme}
*/
@NonNull
public ImeCommand callSetSelection(int start, int end) {
final Bundle params = new Bundle();
params.putInt("start", start);
params.putInt("end", end);
return callCommandInternal("setSelection", params);
}
/**
* Lets {@link MockIme} to call {@link InputConnection#performEditorAction(int)} with the given
* parameters.
*
* <p>This triggers {@code getCurrentInputConnection().performEditorAction(editorAction)}.</p>
*
* <p>Use {@link ImeEvent#getReturnBooleanValue()} for {@link ImeEvent} returned from
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to see the
* value returned from the API.</p>
*
* <p>This can be affected by {@link #memorizeCurrentInputConnection()}.</p>
*
* @param editorAction to be passed as the {@code editorAction} parameter
* @return {@link ImeCommand} object that can be passed to
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to
* wait until this event is handled by {@link MockIme}
*/
@NonNull
public ImeCommand callPerformEditorAction(int editorAction) {
final Bundle params = new Bundle();
params.putInt("editorAction", editorAction);
return callCommandInternal("performEditorAction", params);
}
/**
* Lets {@link MockIme} to call {@link InputConnection#performContextMenuAction(int)} with the
* given parameters.
*
* <p>This triggers {@code getCurrentInputConnection().performContextMenuAction(id)}.</p>
*
* <p>Use {@link ImeEvent#getReturnBooleanValue()} for {@link ImeEvent} returned from
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to see the
* value returned from the API.</p>
*
* <p>This can be affected by {@link #memorizeCurrentInputConnection()}.</p>
*
* @param id to be passed as the {@code id} parameter
* @return {@link ImeCommand} object that can be passed to
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to
* wait until this event is handled by {@link MockIme}
*/
@NonNull
public ImeCommand callPerformContextMenuAction(int id) {
final Bundle params = new Bundle();
params.putInt("id", id);
return callCommandInternal("performContextMenuAction", params);
}
/**
* Lets {@link MockIme} to call {@link InputConnection#beginBatchEdit()} with the given
* parameters.
*
* <p>This triggers {@code getCurrentInputConnection().beginBatchEdit()}.</p>
*
* <p>Use {@link ImeEvent#getReturnBooleanValue()} for {@link ImeEvent} returned from
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to see the
* value returned from the API.</p>
*
* <p>This can be affected by {@link #memorizeCurrentInputConnection()}.</p>
*
* @return {@link ImeCommand} object that can be passed to
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to
* wait until this event is handled by {@link MockIme}
*/
@NonNull
public ImeCommand callBeginBatchEdit() {
final Bundle params = new Bundle();
return callCommandInternal("beginBatchEdit", params);
}
/**
* Lets {@link MockIme} to call {@link InputConnection#endBatchEdit()} with the given
* parameters.
*
* <p>This triggers {@code getCurrentInputConnection().endBatchEdit()}.</p>
*
* <p>Use {@link ImeEvent#getReturnBooleanValue()} for {@link ImeEvent} returned from
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to see the
* value returned from the API.</p>
*
* <p>This can be affected by {@link #memorizeCurrentInputConnection()}.</p>
*
* @return {@link ImeCommand} object that can be passed to
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to
* wait until this event is handled by {@link MockIme}
*/
@NonNull
public ImeCommand callEndBatchEdit() {
final Bundle params = new Bundle();
return callCommandInternal("endBatchEdit", params);
}
/**
* Lets {@link MockIme} to call {@link InputConnection#sendKeyEvent(KeyEvent)} with the given
* parameters.
*
* <p>This triggers {@code getCurrentInputConnection().sendKeyEvent(event)}.</p>
*
* <p>Use {@link ImeEvent#getReturnBooleanValue()} for {@link ImeEvent} returned from
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to see the
* value returned from the API.</p>
*
* <p>This can be affected by {@link #memorizeCurrentInputConnection()}.</p>
*
* @param event to be passed as the {@code event} parameter
* @return {@link ImeCommand} object that can be passed to
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to
* wait until this event is handled by {@link MockIme}
*/
@NonNull
public ImeCommand callSendKeyEvent(@Nullable KeyEvent event) {
final Bundle params = new Bundle();
params.putParcelable("event", event);
return callCommandInternal("sendKeyEvent", params);
}
/**
* Lets {@link MockIme} to call {@link InputConnection#performSpellCheck()}.
*
* <p>This triggers {@code getCurrentInputConnection().performSpellCheck()}.</p>
*
* <p>This can be affected by {@link #memorizeCurrentInputConnection()}.</p>
* @return {@link ImeCommand} object that can be passed to
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to
* wait until this event is handled by {@link MockIme}
*/
@NonNull
public ImeCommand callPerformSpellCheck() {
return callCommandInternal("performSpellCheck", new Bundle());
}
/**
* Lets {@link MockIme} to call {@link InputConnection#takeSnapshot()}.
*
* <p>This triggers {@code getCurrentInputConnection().takeSnapshot()}.</p>
*
* <p>This can be affected by {@link #memorizeCurrentInputConnection()}.</p>
* @return {@link ImeCommand} object that can be passed to
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to
* wait until this event is handled by {@link MockIme}
*/
@NonNull
public ImeCommand callTakeSnapshot() {
return callCommandInternal("takeSnapshot", new Bundle());
}
/**
* Lets {@link MockIme} to call {@link InputConnection#clearMetaKeyStates(int)} with the given
* parameters.
*
* <p>This triggers {@code getCurrentInputConnection().sendKeyEvent(event)}.</p>
*
* <p>Use {@link ImeEvent#getReturnBooleanValue()} for {@link ImeEvent} returned from
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to see the
* value returned from the API.</p>
*
* <p>This can be affected by {@link #memorizeCurrentInputConnection()}.</p>
*
* @param states to be passed as the {@code states} parameter
* @return {@link ImeCommand} object that can be passed to
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to
* wait until this event is handled by {@link MockIme}
*/
@NonNull
public ImeCommand callClearMetaKeyStates(int states) {
final Bundle params = new Bundle();
params.putInt("states", states);
return callCommandInternal("clearMetaKeyStates", params);
}
/**
* Lets {@link MockIme} to call {@link InputConnection#reportFullscreenMode(boolean)} with the
* given parameters.
*
* <p>This triggers {@code getCurrentInputConnection().reportFullscreenMode(enabled)}.</p>
*
* <p>Use {@link ImeEvent#getReturnBooleanValue()} for {@link ImeEvent} returned from
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to see the
* value returned from the API.</p>
*
* <p>This can be affected by {@link #memorizeCurrentInputConnection()}.</p>
*
* @param enabled to be passed as the {@code enabled} parameter
* @return {@link ImeCommand} object that can be passed to
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to
* wait until this event is handled by {@link MockIme}
*/
@NonNull
public ImeCommand callReportFullscreenMode(boolean enabled) {
final Bundle params = new Bundle();
params.putBoolean("enabled", enabled);
return callCommandInternal("reportFullscreenMode", params);
}
/**
* Lets {@link MockIme} to call {@link InputConnection#performPrivateCommand(String, Bundle)}
* with the given parameters.
*
* <p>This triggers {@code getCurrentInputConnection().performPrivateCommand(action, data)}.</p>
*
* <p>Use {@link ImeEvent#getReturnBooleanValue()} for {@link ImeEvent} returned from
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to see the
* value returned from the API.</p>
*
* <p>This can be affected by {@link #memorizeCurrentInputConnection()}.</p>
*
* @param action to be passed as the {@code action} parameter
* @param data to be passed as the {@code data} parameter
* @return {@link ImeCommand} object that can be passed to
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to
* wait until this event is handled by {@link MockIme}
*/
@NonNull
public ImeCommand callPerformPrivateCommand(@Nullable String action, Bundle data) {
final Bundle params = new Bundle();
params.putString("action", action);
params.putBundle("data", data);
return callCommandInternal("performPrivateCommand", params);
}
/**
* Lets {@link MockIme} to call {@link InputConnection#requestCursorUpdates(int)} with the given
* parameters.
*
* <p>This triggers {@code getCurrentInputConnection().requestCursorUpdates(cursorUpdateMode)}.
* </p>
*
* <p>Use {@link ImeEvent#getReturnBooleanValue()} for {@link ImeEvent} returned from
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to see the
* value returned from the API.</p>
*
* <p>This can be affected by {@link #memorizeCurrentInputConnection()}.</p>
*
* @param cursorUpdateMode to be passed as the {@code cursorUpdateMode} parameter
* @return {@link ImeCommand} object that can be passed to
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to
* wait until this event is handled by {@link MockIme}
*/
@NonNull
public ImeCommand callRequestCursorUpdates(int cursorUpdateMode) {
final Bundle params = new Bundle();
params.putInt("cursorUpdateMode", cursorUpdateMode);
return callCommandInternal("requestCursorUpdates", params);
}
/**
* Lets {@link MockIme} to call {@link InputConnection#requestCursorUpdates(int, int)} with the
* given parameters.
*
* <p>This triggers {@code getCurrentInputConnection().requestCursorUpdates(
* cursorUpdateMode, cursorUpdateFilter)}.
* </p>
*
* <p>Use {@link ImeEvent#getReturnBooleanValue()} for {@link ImeEvent} returned from
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to see the
* value returned from the API.</p>
*
* <p>This can be affected by {@link #memorizeCurrentInputConnection()}.</p>
*
* @param cursorUpdateMode to be passed as the {@code cursorUpdateMode} parameter
* @param cursorUpdateFilter to be passed as the {@code cursorUpdateFilter} parameter
* @return {@link ImeCommand} object that can be passed to
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to
* wait until this event is handled by {@link MockIme}
*/
@NonNull
public ImeCommand callRequestCursorUpdates(int cursorUpdateMode, int cursorUpdateFilter) {
final Bundle params = new Bundle();
params.putInt("cursorUpdateMode", cursorUpdateMode);
params.putInt("cursorUpdateFilter", cursorUpdateFilter);
return callCommandInternal("requestCursorUpdates", params);
}
/**
* Lets {@link MockIme} to call {@link InputConnection#getHandler()} with the given parameters.
*
* <p>This triggers {@code getCurrentInputConnection().getHandler()}.</p>
*
* <p>Use {@link ImeEvent#isNullReturnValue()} for {@link ImeEvent} returned from
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to see the
* value returned from the API was {@code null} or not.</p>
*
* <p>This can be affected by {@link #memorizeCurrentInputConnection()}.</p>
*
* @return {@link ImeCommand} object that can be passed to
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to
* wait until this event is handled by {@link MockIme}
*/
@NonNull
public ImeCommand callGetHandler() {
final Bundle params = new Bundle();
return callCommandInternal("getHandler", params);
}
/**
* Lets {@link MockIme} to call {@link InputConnection#closeConnection()} with the given
* parameters.
*
* <p>This triggers {@code getCurrentInputConnection().closeConnection()}.</p>
*
* <p>Return value information is not available for this command.</p>
*
* <p>This can be affected by {@link #memorizeCurrentInputConnection()}.</p>
*
* @return {@link ImeCommand} object that can be passed to
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to
* wait until this event is handled by {@link MockIme}
*/
@NonNull
public ImeCommand callCloseConnection() {
final Bundle params = new Bundle();
return callCommandInternal("closeConnection", params);
}
/**
* Lets {@link MockIme} to call
* {@link InputConnection#commitContent(InputContentInfo, int, Bundle)} with the given
* parameters.
*
* <p>This triggers
* {@code getCurrentInputConnection().commitContent(inputContentInfo, flags, opts)}.</p>
*
* <p>Use {@link ImeEvent#getReturnBooleanValue()} for {@link ImeEvent} returned from
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to see the
* value returned from the API.</p>
*
* <p>This can be affected by {@link #memorizeCurrentInputConnection()}.</p>
*
* @param inputContentInfo to be passed as the {@code inputContentInfo} parameter
* @param flags to be passed as the {@code flags} parameter
* @param opts to be passed as the {@code opts} parameter
* @return {@link ImeCommand} object that can be passed to
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to
* wait until this event is handled by {@link MockIme}
*/
@NonNull
public ImeCommand callCommitContent(@NonNull InputContentInfo inputContentInfo, int flags,
@Nullable Bundle opts) {
final Bundle params = new Bundle();
params.putParcelable("inputContentInfo", inputContentInfo);
params.putInt("flags", flags);
params.putBundle("opts", opts);
return callCommandInternal("commitContent", params);
}
/**
* Lets {@link MockIme} to call {@link InputConnection#setImeConsumesInput(boolean)} with the
* given parameters.
*
* <p>This triggers {@code getCurrentInputConnection().setImeConsumesInput(boolean)}.</p>
*
* <p>Use {@link ImeEvent#getReturnBooleanValue()} for {@link ImeEvent} returned from
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to see the
* value returned from the API.</p>
*
* <p>This can be affected by {@link #memorizeCurrentInputConnection()}.</p>
*
* @param imeConsumesInput to be passed as the {@code imeConsumesInput} parameter
* @return {@link ImeCommand} object that can be passed to
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to
* wait until this event is handled by {@link MockIme}
*/
@NonNull
public ImeCommand callSetImeConsumesInput(boolean imeConsumesInput) {
final Bundle params = new Bundle();
params.putBoolean("imeConsumesInput", imeConsumesInput);
return callCommandInternal("setImeConsumesInput", params);
}
/**
* Lets {@link MockIme} to call
* {@link android.inputmethodservice.InputMethodService#setBackDisposition(int)} with the given
* parameters.
*
* <p>This triggers {@code setBackDisposition(backDisposition)}.</p>
*
* @param backDisposition to be passed as the {@code backDisposition} parameter
* @return {@link ImeCommand} object that can be passed to
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to
* wait until this event is handled by {@link MockIme}
*/
@NonNull
public ImeCommand callSetBackDisposition(int backDisposition) {
final Bundle params = new Bundle();
params.putInt("backDisposition", backDisposition);
return callCommandInternal("setBackDisposition", params);
}
/**
* Lets {@link MockIme} to call
* {@link android.inputmethodservice.InputMethodService#requestHideSelf(int)} with the given
* parameters.
*
* <p>This triggers {@code requestHideSelf(flags)}.</p>
*
* @param flags to be passed as the {@code flags} parameter
* @return {@link ImeCommand} object that can be passed to
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to
* wait until this event is handled by {@link MockIme}
*/
@NonNull
public ImeCommand callRequestHideSelf(int flags) {
final Bundle params = new Bundle();
params.putInt("flags", flags);
return callCommandInternal("requestHideSelf", params);
}
/**
* Lets {@link MockIme} to call
* {@link android.inputmethodservice.InputMethodService#requestShowSelf(int)} with the given
* parameters.
*
* <p>This triggers {@code requestShowSelf(flags)}.</p>
*
* @param flags to be passed as the {@code flags} parameter
* @return {@link ImeCommand} object that can be passed to
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to
* wait until this event is handled by {@link MockIme}
*/
@NonNull
public ImeCommand callRequestShowSelf(int flags) {
final Bundle params = new Bundle();
params.putInt("flags", flags);
return callCommandInternal("requestShowSelf", params);
}
/**
* Lets {@link MockIme} call
* {@link android.inputmethodservice.InputMethodService#sendDownUpKeyEvents(int)} with the given
* {@code keyEventCode}.
*
* @param keyEventCode to be passed as the {@code keyEventCode} parameter.
* @return {@link ImeCommand} object that can be passed to
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to
* wait until this event is handled by {@link MockIme}
*/
@NonNull
public ImeCommand callSendDownUpKeyEvents(int keyEventCode) {
final Bundle params = new Bundle();
params.putInt("keyEventCode", keyEventCode);
return callCommandInternal("sendDownUpKeyEvents", params);
}
/**
* Lets {@link MockIme} call
* {@link android.content.pm.PackageManager#getApplicationInfo(String, int)} with the given
* {@code packageName} and {@code flags}.
*
* @param packageName the package name to be passed to
* {@link android.content.pm.PackageManager#getApplicationInfo(String, int)}.
* @param flags the flags to be passed to
* {@link android.content.pm.PackageManager#getApplicationInfo(String, int)}.
* @return {@link ImeCommand} object that can be passed to
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to
* wait until this event is handled by {@link MockIme}.
*/
@NonNull
public ImeCommand callGetApplicationInfo(@NonNull String packageName, int flags) {
final Bundle params = new Bundle();
params.putString("packageName", packageName);
params.putInt("flags", flags);
return callCommandInternal("getApplicationInfo", params);
}
@NonNull
public ImeCommand callGetDisplayId() {
final Bundle params = new Bundle();
return callCommandInternal("getDisplayId", params);
}
/**
* Verifies {@code InputMethodService.getLayoutInflater().getContext()} is equal to
* {@code InputMethodService.this}.
*
* @return {@link ImeCommand} object that can be passed to
* {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to
* wait until this event is handled by {@link MockIme}
*/
@NonNull
public ImeCommand verifyLayoutInflaterContext() {
final Bundle params = new Bundle();
return callCommandInternal("verifyLayoutInflaterContext", params);
}
@NonNull
public ImeCommand callSetHeight(int height) {
final Bundle params = new Bundle();
params.putInt("height", height);
return callCommandInternal("setHeight", params);
}
@NonNull
public ImeCommand callSetInlineSuggestionsExtras(@NonNull Bundle bundle) {
return callCommandInternal("setInlineSuggestionsExtras", bundle);
}
@NonNull
public ImeCommand callVerifyExtractViewNotNull() {
return callCommandInternal("verifyExtractViewNotNull", new Bundle());
}
@NonNull
public ImeCommand callVerifyGetDisplay() {
return callCommandInternal("verifyGetDisplay", new Bundle());
}
@NonNull
public ImeCommand callVerifyIsUiContext() {
return callCommandInternal("verifyIsUiContext", new Bundle());
}
@NonNull
public ImeCommand callVerifyGetWindowManager() {
return callCommandInternal("verifyGetWindowManager", new Bundle());
}
@NonNull
public ImeCommand callVerifyGetViewConfiguration() {
return callCommandInternal("verifyGetViewConfiguration", new Bundle());
}
@NonNull
public ImeCommand callVerifyGetGestureDetector() {
return callCommandInternal("verifyGetGestureDetector", new Bundle());
}
@NonNull
public ImeCommand callVerifyGetWindowManagerOnDisplayContext() {
return callCommandInternal("verifyGetWindowManagerOnDisplayContext", new Bundle());
}
@NonNull
public ImeCommand callVerifyGetViewConfigurationOnDisplayContext() {
return callCommandInternal("verifyGetViewConfigurationOnDisplayContext", new Bundle());
}
@NonNull
public ImeCommand callVerifyGetGestureDetectorOnDisplayContext() {
return callCommandInternal("verifyGetGestureDetectorOnDisplayContext", new Bundle());
}
@NonNull
public ImeCommand callGetStylusHandwritingWindowVisibility() {
return callCommandInternal("getStylusHandwritingWindowVisibility", new Bundle());
}
@NonNull
public ImeCommand callSetStylusHandwritingInkView() {
return callCommandInternal("setStylusHandwritingInkView", new Bundle());
}
@NonNull
public ImeCommand callGetStylusHandwritingEvents() {
return callCommandInternal("getStylusHandwritingEvents", new Bundle());
}
@NonNull
public ImeCommand callFinishStylusHandwriting() {
return callCommandInternal("finishStylusHandwriting", new Bundle());
}
@NonNull
public ImeCommand callGetCurrentWindowMetricsBounds() {
return callCommandInternal("getCurrentWindowMetricsBounds", new Bundle());
}
}