diff options
Diffstat (limited to 'src/io/appium/droiddriver/actions/TextAction.java')
-rw-r--r-- | src/io/appium/droiddriver/actions/TextAction.java | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/src/io/appium/droiddriver/actions/TextAction.java b/src/io/appium/droiddriver/actions/TextAction.java new file mode 100644 index 0000000..b108b00 --- /dev/null +++ b/src/io/appium/droiddriver/actions/TextAction.java @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2013 DroidDriver committers + * + * 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 io.appium.droiddriver.actions; + +import android.annotation.SuppressLint; +import android.os.Build; +import android.os.SystemClock; +import android.view.KeyCharacterMap; +import android.view.KeyEvent; + +import io.appium.droiddriver.UiElement; +import io.appium.droiddriver.exceptions.ActionException; +import io.appium.droiddriver.util.Preconditions; +import io.appium.droiddriver.util.Strings; + +/** + * An action to type text. + */ +public class TextAction extends KeyAction { + + @SuppressLint("InlinedApi") + @SuppressWarnings("deprecation") + private static final KeyCharacterMap KEY_CHAR_MAP = + Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB ? KeyCharacterMap + .load(KeyCharacterMap.BUILT_IN_KEYBOARD) : KeyCharacterMap + .load(KeyCharacterMap.VIRTUAL_KEYBOARD); + + private final String text; + + /** + * Defaults timeoutMillis to 100. + */ + public TextAction(String text) { + this(text, 100L, false); + } + + public TextAction(String text, long timeoutMillis, boolean checkFocused) { + super(timeoutMillis, checkFocused); + this.text = Preconditions.checkNotNull(text); + } + + @Override + public boolean perform(InputInjector injector, UiElement element) { + maybeCheckFocused(element); + + // TODO: recycle events? + KeyEvent[] events = KEY_CHAR_MAP.getEvents(text.toCharArray()); + boolean success = false; + + if (events != null) { + for (KeyEvent event : events) { + // We have to change the time of an event before injecting it because + // all KeyEvents returned by KeyCharacterMap.getEvents() have the same + // time stamp and the system rejects too old events. Hence, it is + // possible for an event to become stale before it is injected if it + // takes too long to inject the preceding ones. + KeyEvent modifiedEvent = KeyEvent.changeTimeRepeat(event, SystemClock.uptimeMillis(), 0); + success = injector.injectInputEvent(modifiedEvent); + if (!success) { + break; + } + } + } else { + throw new ActionException("The given text is not supported: " + text); + } + return success; + } + + @Override + public String toString() { + return Strings.toStringHelper(this).addValue(text).toString(); + } +} |