am b6ca3544: Small code cleanups
* commit 'b6ca354431367b625daf9fff5fbe4b1f5ef996ab': Small code cleanupsmain
commit
25d1595ab4
|
@ -71,12 +71,11 @@ public final class AccessibilityEntityProvider extends AccessibilityNodeProvider
|
||||||
/** The current keyboard view. */
|
/** The current keyboard view. */
|
||||||
private KeyboardView mKeyboardView;
|
private KeyboardView mKeyboardView;
|
||||||
|
|
||||||
public AccessibilityEntityProvider(KeyboardView keyboardView, InputMethodService inputMethod) {
|
public AccessibilityEntityProvider(final KeyboardView keyboardView,
|
||||||
|
final InputMethodService inputMethod) {
|
||||||
mInputMethodService = inputMethod;
|
mInputMethodService = inputMethod;
|
||||||
|
|
||||||
mKeyCodeDescriptionMapper = KeyCodeDescriptionMapper.getInstance();
|
mKeyCodeDescriptionMapper = KeyCodeDescriptionMapper.getInstance();
|
||||||
mAccessibilityUtils = AccessibilityUtils.getInstance();
|
mAccessibilityUtils = AccessibilityUtils.getInstance();
|
||||||
|
|
||||||
setView(keyboardView);
|
setView(keyboardView);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,21 +84,19 @@ public final class AccessibilityEntityProvider extends AccessibilityNodeProvider
|
||||||
*
|
*
|
||||||
* @param keyboardView The keyboard view to represent.
|
* @param keyboardView The keyboard view to represent.
|
||||||
*/
|
*/
|
||||||
public void setView(KeyboardView keyboardView) {
|
public void setView(final KeyboardView keyboardView) {
|
||||||
mKeyboardView = keyboardView;
|
mKeyboardView = keyboardView;
|
||||||
updateParentLocation();
|
updateParentLocation();
|
||||||
|
|
||||||
// Since this class is constructed lazily, we might not get a subsequent
|
// Since this class is constructed lazily, we might not get a subsequent
|
||||||
// call to setKeyboard() and therefore need to call it now.
|
// call to setKeyboard() and therefore need to call it now.
|
||||||
setKeyboard(mKeyboardView.getKeyboard());
|
setKeyboard();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the keyboard represented by this node provider.
|
* Sets the keyboard represented by this node provider.
|
||||||
*
|
|
||||||
* @param keyboard The keyboard to represent.
|
|
||||||
*/
|
*/
|
||||||
public void setKeyboard(Keyboard keyboard) {
|
public void setKeyboard() {
|
||||||
assignVirtualViewIds();
|
assignVirtualViewIds();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,19 +109,16 @@ public final class AccessibilityEntityProvider extends AccessibilityNodeProvider
|
||||||
* @return A populated {@link AccessibilityEvent} for the key.
|
* @return A populated {@link AccessibilityEvent} for the key.
|
||||||
* @see AccessibilityEvent
|
* @see AccessibilityEvent
|
||||||
*/
|
*/
|
||||||
public AccessibilityEvent createAccessibilityEvent(Key key, int eventType) {
|
public AccessibilityEvent createAccessibilityEvent(final Key key, final int eventType) {
|
||||||
final int virtualViewId = generateVirtualViewIdForKey(key);
|
final int virtualViewId = generateVirtualViewIdForKey(key);
|
||||||
final String keyDescription = getKeyDescription(key);
|
final String keyDescription = getKeyDescription(key);
|
||||||
|
|
||||||
final AccessibilityEvent event = AccessibilityEvent.obtain(eventType);
|
final AccessibilityEvent event = AccessibilityEvent.obtain(eventType);
|
||||||
event.setPackageName(mKeyboardView.getContext().getPackageName());
|
event.setPackageName(mKeyboardView.getContext().getPackageName());
|
||||||
event.setClassName(key.getClass().getName());
|
event.setClassName(key.getClass().getName());
|
||||||
event.setContentDescription(keyDescription);
|
event.setContentDescription(keyDescription);
|
||||||
event.setEnabled(true);
|
event.setEnabled(true);
|
||||||
|
|
||||||
final AccessibilityRecordCompat record = new AccessibilityRecordCompat(event);
|
final AccessibilityRecordCompat record = new AccessibilityRecordCompat(event);
|
||||||
record.setSource(mKeyboardView, virtualViewId);
|
record.setSource(mKeyboardView, virtualViewId);
|
||||||
|
|
||||||
return event;
|
return event;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,68 +139,65 @@ public final class AccessibilityEntityProvider extends AccessibilityNodeProvider
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @param virtualViewId A client defined virtual view id.
|
* @param virtualViewId A client defined virtual view id.
|
||||||
* @return A populated {@link AccessibilityNodeInfoCompat} for a virtual
|
* @return A populated {@link AccessibilityNodeInfoCompat} for a virtual descendant or the host
|
||||||
* descendant or the host View.
|
* View.
|
||||||
* @see AccessibilityNodeInfoCompat
|
* @see AccessibilityNodeInfoCompat
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public AccessibilityNodeInfoCompat createAccessibilityNodeInfo(int virtualViewId) {
|
public AccessibilityNodeInfoCompat createAccessibilityNodeInfo(final int virtualViewId) {
|
||||||
AccessibilityNodeInfoCompat info = null;
|
|
||||||
|
|
||||||
if (virtualViewId == UNDEFINED) {
|
if (virtualViewId == UNDEFINED) {
|
||||||
return null;
|
return null;
|
||||||
} else if (virtualViewId == View.NO_ID) {
|
}
|
||||||
|
if (virtualViewId == View.NO_ID) {
|
||||||
// We are requested to create an AccessibilityNodeInfo describing
|
// We are requested to create an AccessibilityNodeInfo describing
|
||||||
// this View, i.e. the root of the virtual sub-tree.
|
// this View, i.e. the root of the virtual sub-tree.
|
||||||
info = AccessibilityNodeInfoCompat.obtain(mKeyboardView);
|
final AccessibilityNodeInfoCompat rootInfo =
|
||||||
ViewCompat.onInitializeAccessibilityNodeInfo(mKeyboardView, info);
|
AccessibilityNodeInfoCompat.obtain(mKeyboardView);
|
||||||
|
ViewCompat.onInitializeAccessibilityNodeInfo(mKeyboardView, rootInfo);
|
||||||
|
|
||||||
// Add the virtual children of the root View.
|
// Add the virtual children of the root View.
|
||||||
final Keyboard keyboard = mKeyboardView.getKeyboard();
|
final Keyboard keyboard = mKeyboardView.getKeyboard();
|
||||||
final Key[] keys = keyboard.mKeys;
|
final Key[] keys = keyboard.mKeys;
|
||||||
for (Key key : keys) {
|
for (Key key : keys) {
|
||||||
final int childVirtualViewId = generateVirtualViewIdForKey(key);
|
final int childVirtualViewId = generateVirtualViewIdForKey(key);
|
||||||
info.addChild(mKeyboardView, childVirtualViewId);
|
rootInfo.addChild(mKeyboardView, childVirtualViewId);
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Find the view that corresponds to the given id.
|
|
||||||
final Key key = mVirtualViewIdToKey.get(virtualViewId);
|
|
||||||
if (key == null) {
|
|
||||||
Log.e(TAG, "Invalid virtual view ID: " + virtualViewId);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
final String keyDescription = getKeyDescription(key);
|
|
||||||
final Rect boundsInParent = key.mHitBox;
|
|
||||||
|
|
||||||
// Calculate the key's in-screen bounds.
|
|
||||||
mTempBoundsInScreen.set(boundsInParent);
|
|
||||||
mTempBoundsInScreen.offset(
|
|
||||||
CoordinateUtils.x(mParentLocation), CoordinateUtils.y(mParentLocation));
|
|
||||||
|
|
||||||
final Rect boundsInScreen = mTempBoundsInScreen;
|
|
||||||
|
|
||||||
// Obtain and initialize an AccessibilityNodeInfo with
|
|
||||||
// information about the virtual view.
|
|
||||||
info = AccessibilityNodeInfoCompat.obtain();
|
|
||||||
info.setPackageName(mKeyboardView.getContext().getPackageName());
|
|
||||||
info.setClassName(key.getClass().getName());
|
|
||||||
info.setContentDescription(keyDescription);
|
|
||||||
info.setBoundsInParent(boundsInParent);
|
|
||||||
info.setBoundsInScreen(boundsInScreen);
|
|
||||||
info.setParent(mKeyboardView);
|
|
||||||
info.setSource(mKeyboardView, virtualViewId);
|
|
||||||
info.setBoundsInScreen(boundsInScreen);
|
|
||||||
info.setEnabled(true);
|
|
||||||
info.setVisibleToUser(true);
|
|
||||||
|
|
||||||
if (mAccessibilityFocusedView == virtualViewId) {
|
|
||||||
info.addAction(AccessibilityNodeInfoCompat.ACTION_CLEAR_ACCESSIBILITY_FOCUS);
|
|
||||||
} else {
|
|
||||||
info.addAction(AccessibilityNodeInfoCompat.ACTION_ACCESSIBILITY_FOCUS);
|
|
||||||
}
|
}
|
||||||
|
return rootInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Find the view that corresponds to the given id.
|
||||||
|
final Key key = mVirtualViewIdToKey.get(virtualViewId);
|
||||||
|
if (key == null) {
|
||||||
|
Log.e(TAG, "Invalid virtual view ID: " + virtualViewId);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
final String keyDescription = getKeyDescription(key);
|
||||||
|
final Rect boundsInParent = key.mHitBox;
|
||||||
|
|
||||||
|
// Calculate the key's in-screen bounds.
|
||||||
|
mTempBoundsInScreen.set(boundsInParent);
|
||||||
|
mTempBoundsInScreen.offset(
|
||||||
|
CoordinateUtils.x(mParentLocation), CoordinateUtils.y(mParentLocation));
|
||||||
|
final Rect boundsInScreen = mTempBoundsInScreen;
|
||||||
|
|
||||||
|
// Obtain and initialize an AccessibilityNodeInfo with information about the virtual view.
|
||||||
|
final AccessibilityNodeInfoCompat info = AccessibilityNodeInfoCompat.obtain();
|
||||||
|
info.setPackageName(mKeyboardView.getContext().getPackageName());
|
||||||
|
info.setClassName(key.getClass().getName());
|
||||||
|
info.setContentDescription(keyDescription);
|
||||||
|
info.setBoundsInParent(boundsInParent);
|
||||||
|
info.setBoundsInScreen(boundsInScreen);
|
||||||
|
info.setParent(mKeyboardView);
|
||||||
|
info.setSource(mKeyboardView, virtualViewId);
|
||||||
|
info.setBoundsInScreen(boundsInScreen);
|
||||||
|
info.setEnabled(true);
|
||||||
|
info.setVisibleToUser(true);
|
||||||
|
|
||||||
|
if (mAccessibilityFocusedView == virtualViewId) {
|
||||||
|
info.addAction(AccessibilityNodeInfoCompat.ACTION_CLEAR_ACCESSIBILITY_FOCUS);
|
||||||
|
} else {
|
||||||
|
info.addAction(AccessibilityNodeInfoCompat.ACTION_ACCESSIBILITY_FOCUS);
|
||||||
|
}
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,7 +207,7 @@ public final class AccessibilityEntityProvider extends AccessibilityNodeProvider
|
||||||
*
|
*
|
||||||
* @param key The key to press.
|
* @param key The key to press.
|
||||||
*/
|
*/
|
||||||
void simulateKeyPress(Key key) {
|
void simulateKeyPress(final Key key) {
|
||||||
final int x = key.mHitBox.centerX();
|
final int x = key.mHitBox.centerX();
|
||||||
final int y = key.mHitBox.centerY();
|
final int y = key.mHitBox.centerY();
|
||||||
final long downTime = SystemClock.uptimeMillis();
|
final long downTime = SystemClock.uptimeMillis();
|
||||||
|
@ -227,19 +218,17 @@ public final class AccessibilityEntityProvider extends AccessibilityNodeProvider
|
||||||
|
|
||||||
mKeyboardView.onTouchEvent(downEvent);
|
mKeyboardView.onTouchEvent(downEvent);
|
||||||
mKeyboardView.onTouchEvent(upEvent);
|
mKeyboardView.onTouchEvent(upEvent);
|
||||||
|
|
||||||
downEvent.recycle();
|
downEvent.recycle();
|
||||||
upEvent.recycle();
|
upEvent.recycle();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean performAction(int virtualViewId, int action, Bundle arguments) {
|
public boolean performAction(final int virtualViewId, final int action,
|
||||||
|
final Bundle arguments) {
|
||||||
final Key key = mVirtualViewIdToKey.get(virtualViewId);
|
final Key key = mVirtualViewIdToKey.get(virtualViewId);
|
||||||
|
|
||||||
if (key == null) {
|
if (key == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return performActionForKey(key, action, arguments);
|
return performActionForKey(key, action, arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,10 +238,9 @@ public final class AccessibilityEntityProvider extends AccessibilityNodeProvider
|
||||||
* @param key The on which to perform the action.
|
* @param key The on which to perform the action.
|
||||||
* @param action The action to perform.
|
* @param action The action to perform.
|
||||||
* @param arguments The action's arguments.
|
* @param arguments The action's arguments.
|
||||||
* @return The result of performing the action, or false if the action is
|
* @return The result of performing the action, or false if the action is not supported.
|
||||||
* not supported.
|
|
||||||
*/
|
*/
|
||||||
boolean performActionForKey(Key key, int action, Bundle arguments) {
|
boolean performActionForKey(final Key key, final int action, final Bundle arguments) {
|
||||||
final int virtualViewId = generateVirtualViewIdForKey(key);
|
final int virtualViewId = generateVirtualViewIdForKey(key);
|
||||||
|
|
||||||
switch (action) {
|
switch (action) {
|
||||||
|
@ -272,9 +260,9 @@ public final class AccessibilityEntityProvider extends AccessibilityNodeProvider
|
||||||
sendAccessibilityEventForKey(
|
sendAccessibilityEventForKey(
|
||||||
key, AccessibilityEventCompat.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED);
|
key, AccessibilityEventCompat.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED);
|
||||||
return true;
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -283,7 +271,7 @@ public final class AccessibilityEntityProvider extends AccessibilityNodeProvider
|
||||||
* @param key The key that's sending the event.
|
* @param key The key that's sending the event.
|
||||||
* @param eventType The type of event to send.
|
* @param eventType The type of event to send.
|
||||||
*/
|
*/
|
||||||
void sendAccessibilityEventForKey(Key key, int eventType) {
|
void sendAccessibilityEventForKey(final Key key, final int eventType) {
|
||||||
final AccessibilityEvent event = createAccessibilityEvent(key, eventType);
|
final AccessibilityEvent event = createAccessibilityEvent(key, eventType);
|
||||||
mAccessibilityUtils.requestSendAccessibilityEvent(event);
|
mAccessibilityUtils.requestSendAccessibilityEvent(event);
|
||||||
}
|
}
|
||||||
|
@ -294,12 +282,11 @@ public final class AccessibilityEntityProvider extends AccessibilityNodeProvider
|
||||||
* @param key The key to describe.
|
* @param key The key to describe.
|
||||||
* @return The context-specific description of the key.
|
* @return The context-specific description of the key.
|
||||||
*/
|
*/
|
||||||
private String getKeyDescription(Key key) {
|
private String getKeyDescription(final Key key) {
|
||||||
final EditorInfo editorInfo = mInputMethodService.getCurrentInputEditorInfo();
|
final EditorInfo editorInfo = mInputMethodService.getCurrentInputEditorInfo();
|
||||||
final boolean shouldObscure = mAccessibilityUtils.shouldObscureInput(editorInfo);
|
final boolean shouldObscure = mAccessibilityUtils.shouldObscureInput(editorInfo);
|
||||||
final String keyDescription = mKeyCodeDescriptionMapper.getDescriptionForKey(
|
final String keyDescription = mKeyCodeDescriptionMapper.getDescriptionForKey(
|
||||||
mKeyboardView.getContext(), mKeyboardView.getKeyboard(), key, shouldObscure);
|
mKeyboardView.getContext(), mKeyboardView.getKeyboard(), key, shouldObscure);
|
||||||
|
|
||||||
return keyDescription;
|
return keyDescription;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -311,7 +298,6 @@ public final class AccessibilityEntityProvider extends AccessibilityNodeProvider
|
||||||
if (keyboard == null) {
|
if (keyboard == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mVirtualViewIdToKey.clear();
|
mVirtualViewIdToKey.clear();
|
||||||
|
|
||||||
final Key[] keys = keyboard.mKeys;
|
final Key[] keys = keyboard.mKeys;
|
||||||
|
@ -335,7 +321,7 @@ public final class AccessibilityEntityProvider extends AccessibilityNodeProvider
|
||||||
* @param key The key to identify.
|
* @param key The key to identify.
|
||||||
* @return A virtual view identifier.
|
* @return A virtual view identifier.
|
||||||
*/
|
*/
|
||||||
private static int generateVirtualViewIdForKey(Key key) {
|
private static int generateVirtualViewIdForKey(final Key key) {
|
||||||
// The key x- and y-coordinates are stable between layout changes.
|
// The key x- and y-coordinates are stable between layout changes.
|
||||||
// Generate an identifier by bit-shifting the x-coordinate to the
|
// Generate an identifier by bit-shifting the x-coordinate to the
|
||||||
// left-half of the integer and OR'ing with the y-coordinate.
|
// left-half of the integer and OR'ing with the y-coordinate.
|
||||||
|
|
|
@ -55,7 +55,7 @@ public final class AccessibilityUtils {
|
||||||
*/
|
*/
|
||||||
private static final boolean ENABLE_ACCESSIBILITY = true;
|
private static final boolean ENABLE_ACCESSIBILITY = true;
|
||||||
|
|
||||||
public static void init(InputMethodService inputMethod) {
|
public static void init(final InputMethodService inputMethod) {
|
||||||
if (!ENABLE_ACCESSIBILITY) return;
|
if (!ENABLE_ACCESSIBILITY) return;
|
||||||
|
|
||||||
// These only need to be initialized if the kill switch is off.
|
// These only need to be initialized if the kill switch is off.
|
||||||
|
@ -72,7 +72,7 @@ public final class AccessibilityUtils {
|
||||||
// This class is not publicly instantiable.
|
// This class is not publicly instantiable.
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initInternal(Context context) {
|
private void initInternal(final Context context) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mAccessibilityManager =
|
mAccessibilityManager =
|
||||||
(AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE);
|
(AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE);
|
||||||
|
@ -100,9 +100,8 @@ public final class AccessibilityUtils {
|
||||||
* @param event The event to check.
|
* @param event The event to check.
|
||||||
* @return {@true} is the event is a touch exploration event
|
* @return {@true} is the event is a touch exploration event
|
||||||
*/
|
*/
|
||||||
public boolean isTouchExplorationEvent(MotionEvent event) {
|
public boolean isTouchExplorationEvent(final MotionEvent event) {
|
||||||
final int action = event.getAction();
|
final int action = event.getAction();
|
||||||
|
|
||||||
return action == MotionEvent.ACTION_HOVER_ENTER
|
return action == MotionEvent.ACTION_HOVER_ENTER
|
||||||
|| action == MotionEvent.ACTION_HOVER_EXIT
|
|| action == MotionEvent.ACTION_HOVER_EXIT
|
||||||
|| action == MotionEvent.ACTION_HOVER_MOVE;
|
|| action == MotionEvent.ACTION_HOVER_MOVE;
|
||||||
|
@ -114,7 +113,7 @@ public final class AccessibilityUtils {
|
||||||
*
|
*
|
||||||
* @return {@code true} if the device should obscure password characters.
|
* @return {@code true} if the device should obscure password characters.
|
||||||
*/
|
*/
|
||||||
public boolean shouldObscureInput(EditorInfo editorInfo) {
|
public boolean shouldObscureInput(final EditorInfo editorInfo) {
|
||||||
if (editorInfo == null) return false;
|
if (editorInfo == null) return false;
|
||||||
|
|
||||||
// The user can optionally force speaking passwords.
|
// The user can optionally force speaking passwords.
|
||||||
|
@ -140,7 +139,7 @@ public final class AccessibilityUtils {
|
||||||
* @param view The source view.
|
* @param view The source view.
|
||||||
* @param text The text to speak.
|
* @param text The text to speak.
|
||||||
*/
|
*/
|
||||||
public void announceForAccessibility(View view, CharSequence text) {
|
public void announceForAccessibility(final View view, final CharSequence text) {
|
||||||
if (!mAccessibilityManager.isEnabled()) {
|
if (!mAccessibilityManager.isEnabled()) {
|
||||||
Log.e(TAG, "Attempted to speak when accessibility was disabled!");
|
Log.e(TAG, "Attempted to speak when accessibility was disabled!");
|
||||||
return;
|
return;
|
||||||
|
@ -157,8 +156,9 @@ public final class AccessibilityUtils {
|
||||||
event.setEnabled(true);
|
event.setEnabled(true);
|
||||||
event.getText().add(text);
|
event.getText().add(text);
|
||||||
|
|
||||||
// Platforms starting at SDK 16 should use announce events.
|
// Platforms starting at SDK version 16 (Build.VERSION_CODES.JELLY_BEAN) should use
|
||||||
if (Build.VERSION.SDK_INT >= 16) {
|
// announce events.
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
|
||||||
event.setEventType(AccessibilityEventCompat.TYPE_ANNOUNCEMENT);
|
event.setEventType(AccessibilityEventCompat.TYPE_ANNOUNCEMENT);
|
||||||
} else {
|
} else {
|
||||||
event.setEventType(AccessibilityEvent.TYPE_VIEW_FOCUSED);
|
event.setEventType(AccessibilityEvent.TYPE_VIEW_FOCUSED);
|
||||||
|
@ -181,7 +181,8 @@ public final class AccessibilityUtils {
|
||||||
* @param editorInfo The input connection's editor info attribute.
|
* @param editorInfo The input connection's editor info attribute.
|
||||||
* @param restarting Whether the connection is being restarted.
|
* @param restarting Whether the connection is being restarted.
|
||||||
*/
|
*/
|
||||||
public void onStartInputViewInternal(View view, EditorInfo editorInfo, boolean restarting) {
|
public void onStartInputViewInternal(final View view, final EditorInfo editorInfo,
|
||||||
|
final boolean restarting) {
|
||||||
if (shouldObscureInput(editorInfo)) {
|
if (shouldObscureInput(editorInfo)) {
|
||||||
final CharSequence text = mContext.getText(R.string.spoken_use_headphones);
|
final CharSequence text = mContext.getText(R.string.spoken_use_headphones);
|
||||||
announceForAccessibility(view, text);
|
announceForAccessibility(view, text);
|
||||||
|
@ -194,7 +195,7 @@ public final class AccessibilityUtils {
|
||||||
*
|
*
|
||||||
* @param event The event to send.
|
* @param event The event to send.
|
||||||
*/
|
*/
|
||||||
public void requestSendAccessibilityEvent(AccessibilityEvent event) {
|
public void requestSendAccessibilityEvent(final AccessibilityEvent event) {
|
||||||
if (mAccessibilityManager.isEnabled()) {
|
if (mAccessibilityManager.isEnabled()) {
|
||||||
mAccessibilityManager.sendAccessibilityEvent(event);
|
mAccessibilityManager.sendAccessibilityEvent(event);
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,12 +42,11 @@ public final class AccessibleKeyboardViewProxy extends AccessibilityDelegateComp
|
||||||
private Key mLastHoverKey = null;
|
private Key mLastHoverKey = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inset in pixels to look for keys when the user's finger exits the
|
* Inset in pixels to look for keys when the user's finger exits the keyboard area.
|
||||||
* keyboard area.
|
|
||||||
*/
|
*/
|
||||||
private int mEdgeSlop;
|
private int mEdgeSlop;
|
||||||
|
|
||||||
public static void init(InputMethodService inputMethod) {
|
public static void init(final InputMethodService inputMethod) {
|
||||||
sInstance.initInternal(inputMethod);
|
sInstance.initInternal(inputMethod);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,7 +58,7 @@ public final class AccessibleKeyboardViewProxy extends AccessibilityDelegateComp
|
||||||
// Not publicly instantiable.
|
// Not publicly instantiable.
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initInternal(InputMethodService inputMethod) {
|
private void initInternal(final InputMethodService inputMethod) {
|
||||||
mInputMethod = inputMethod;
|
mInputMethod = inputMethod;
|
||||||
mEdgeSlop = inputMethod.getResources().getDimensionPixelSize(
|
mEdgeSlop = inputMethod.getResources().getDimensionPixelSize(
|
||||||
R.dimen.accessibility_edge_slop);
|
R.dimen.accessibility_edge_slop);
|
||||||
|
@ -70,61 +69,61 @@ public final class AccessibleKeyboardViewProxy extends AccessibilityDelegateComp
|
||||||
*
|
*
|
||||||
* @param view The view to wrap.
|
* @param view The view to wrap.
|
||||||
*/
|
*/
|
||||||
public void setView(MainKeyboardView view) {
|
public void setView(final MainKeyboardView view) {
|
||||||
if (view == null) {
|
if (view == null) {
|
||||||
// Ignore null views.
|
// Ignore null views.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mView = view;
|
mView = view;
|
||||||
|
|
||||||
// Ensure that the view has an accessibility delegate.
|
// Ensure that the view has an accessibility delegate.
|
||||||
ViewCompat.setAccessibilityDelegate(view, this);
|
ViewCompat.setAccessibilityDelegate(view, this);
|
||||||
|
|
||||||
if (mAccessibilityNodeProvider != null) {
|
if (mAccessibilityNodeProvider == null) {
|
||||||
mAccessibilityNodeProvider.setView(view);
|
return;
|
||||||
}
|
}
|
||||||
|
mAccessibilityNodeProvider.setView(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setKeyboard(Keyboard keyboard) {
|
public void setKeyboard() {
|
||||||
if (mAccessibilityNodeProvider != null) {
|
if (mAccessibilityNodeProvider == null) {
|
||||||
mAccessibilityNodeProvider.setKeyboard(keyboard);
|
return;
|
||||||
}
|
}
|
||||||
|
mAccessibilityNodeProvider.setKeyboard();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Proxy method for View.getAccessibilityNodeProvider(). This method is
|
* Proxy method for View.getAccessibilityNodeProvider(). This method is called in SDK
|
||||||
* called in SDK version 15 and higher to obtain the virtual node hierarchy
|
* version 15 (Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) and higher to obtain the virtual
|
||||||
* provider.
|
* node hierarchy provider.
|
||||||
*
|
*
|
||||||
* @return The accessibility node provider for the current keyboard.
|
* @return The accessibility node provider for the current keyboard.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public AccessibilityEntityProvider getAccessibilityNodeProvider(View host) {
|
public AccessibilityEntityProvider getAccessibilityNodeProvider(final View host) {
|
||||||
return getAccessibilityNodeProvider();
|
return getAccessibilityNodeProvider();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Intercepts touch events before dispatch when touch exploration is turned
|
* Intercepts touch events before dispatch when touch exploration is turned on in ICS and
|
||||||
* on in ICS and higher.
|
* higher.
|
||||||
*
|
*
|
||||||
* @param event The motion event being dispatched.
|
* @param event The motion event being dispatched.
|
||||||
* @return {@code true} if the event is handled
|
* @return {@code true} if the event is handled
|
||||||
*/
|
*/
|
||||||
public boolean dispatchTouchEvent(MotionEvent event) {
|
public boolean dispatchTouchEvent(final MotionEvent event) {
|
||||||
// To avoid accidental key presses during touch exploration, always drop
|
// To avoid accidental key presses during touch exploration, always drop
|
||||||
// touch events generated by the user.
|
// touch events generated by the user.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Receives hover events when touch exploration is turned on in SDK versions
|
* Receives hover events when touch exploration is turned on in SDK versions ICS and higher.
|
||||||
* ICS and higher.
|
|
||||||
*
|
*
|
||||||
* @param event The hover event.
|
* @param event The hover event.
|
||||||
* @return {@code true} if the event is handled
|
* @return {@code true} if the event is handled
|
||||||
*/
|
*/
|
||||||
public boolean dispatchHoverEvent(MotionEvent event, PointerTracker tracker) {
|
public boolean dispatchHoverEvent(final MotionEvent event, final PointerTracker tracker) {
|
||||||
final int x = (int) event.getX();
|
final int x = (int) event.getX();
|
||||||
final int y = (int) event.getY();
|
final int y = (int) event.getY();
|
||||||
final Key previousKey = mLastHoverKey;
|
final Key previousKey = mLastHoverKey;
|
||||||
|
@ -135,7 +134,6 @@ public final class AccessibleKeyboardViewProxy extends AccessibilityDelegateComp
|
||||||
} else {
|
} else {
|
||||||
key = null;
|
key = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
mLastHoverKey = key;
|
mLastHoverKey = key;
|
||||||
|
|
||||||
switch (event.getAction()) {
|
switch (event.getAction()) {
|
||||||
|
@ -173,30 +171,29 @@ public final class AccessibleKeyboardViewProxy extends AccessibilityDelegateComp
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility method to determine whether the given point, in local
|
* Utility method to determine whether the given point, in local coordinates, is inside the
|
||||||
* coordinates, is inside the view, where the area of the view is contracted
|
* view, where the area of the view is contracted by the edge slop factor.
|
||||||
* by the edge slop factor.
|
|
||||||
*
|
*
|
||||||
* @param localX The local x-coordinate.
|
* @param localX The local x-coordinate.
|
||||||
* @param localY The local y-coordinate.
|
* @param localY The local y-coordinate.
|
||||||
*/
|
*/
|
||||||
private boolean pointInView(int localX, int localY) {
|
private boolean pointInView(final int localX, final int localY) {
|
||||||
return (localX >= mEdgeSlop) && (localY >= mEdgeSlop)
|
return (localX >= mEdgeSlop) && (localY >= mEdgeSlop)
|
||||||
&& (localX < (mView.getWidth() - mEdgeSlop))
|
&& (localX < (mView.getWidth() - mEdgeSlop))
|
||||||
&& (localY < (mView.getHeight() - mEdgeSlop));
|
&& (localY < (mView.getHeight() - mEdgeSlop));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simulates a transition between two {@link Key}s by sending a HOVER_EXIT
|
* Simulates a transition between two {@link Key}s by sending a HOVER_EXIT on the previous key,
|
||||||
* on the previous key, a HOVER_ENTER on the current key, and a HOVER_MOVE
|
* a HOVER_ENTER on the current key, and a HOVER_MOVE on the current key.
|
||||||
* on the current key.
|
|
||||||
*
|
*
|
||||||
* @param currentKey The currently hovered key.
|
* @param currentKey The currently hovered key.
|
||||||
* @param previousKey The previously hovered key.
|
* @param previousKey The previously hovered key.
|
||||||
* @param event The event that triggered the transition.
|
* @param event The event that triggered the transition.
|
||||||
* @return {@code true} if the event was handled.
|
* @return {@code true} if the event was handled.
|
||||||
*/
|
*/
|
||||||
private boolean onTransitionKey(Key currentKey, Key previousKey, MotionEvent event) {
|
private boolean onTransitionKey(final Key currentKey, final Key previousKey,
|
||||||
|
final MotionEvent event) {
|
||||||
final int savedAction = event.getAction();
|
final int savedAction = event.getAction();
|
||||||
|
|
||||||
event.setAction(MotionEvent.ACTION_HOVER_EXIT);
|
event.setAction(MotionEvent.ACTION_HOVER_EXIT);
|
||||||
|
@ -214,19 +211,18 @@ public final class AccessibleKeyboardViewProxy extends AccessibilityDelegateComp
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles a hover event on a key. If {@link Key} extended View, this would
|
* Handles a hover event on a key. If {@link Key} extended View, this would be analogous to
|
||||||
* be analogous to calling View.onHoverEvent(MotionEvent).
|
* calling View.onHoverEvent(MotionEvent).
|
||||||
*
|
*
|
||||||
* @param key The currently hovered key.
|
* @param key The currently hovered key.
|
||||||
* @param event The hover event.
|
* @param event The hover event.
|
||||||
* @return {@code true} if the event was handled.
|
* @return {@code true} if the event was handled.
|
||||||
*/
|
*/
|
||||||
private boolean onHoverKey(Key key, MotionEvent event) {
|
private boolean onHoverKey(final Key key, final MotionEvent event) {
|
||||||
// Null keys can't receive events.
|
// Null keys can't receive events.
|
||||||
if (key == null) {
|
if (key == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
final AccessibilityEntityProvider provider = getAccessibilityNodeProvider();
|
final AccessibilityEntityProvider provider = getAccessibilityNodeProvider();
|
||||||
|
|
||||||
switch (event.getAction()) {
|
switch (event.getAction()) {
|
||||||
|
@ -241,7 +237,6 @@ public final class AccessibleKeyboardViewProxy extends AccessibilityDelegateComp
|
||||||
key, AccessibilityEventCompat.TYPE_VIEW_HOVER_EXIT);
|
key, AccessibilityEventCompat.TYPE_VIEW_HOVER_EXIT);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -268,7 +263,6 @@ public final class AccessibleKeyboardViewProxy extends AccessibilityDelegateComp
|
||||||
default:
|
default:
|
||||||
text = context.getText(R.string.spoken_description_shiftmode_off);
|
text = context.getText(R.string.spoken_description_shiftmode_off);
|
||||||
}
|
}
|
||||||
|
|
||||||
AccessibilityUtils.getInstance().announceForAccessibility(mView, text);
|
AccessibilityUtils.getInstance().announceForAccessibility(mView, text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -307,7 +301,6 @@ public final class AccessibleKeyboardViewProxy extends AccessibilityDelegateComp
|
||||||
if (resId < 0) {
|
if (resId < 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final String text = context.getString(resId);
|
final String text = context.getString(resId);
|
||||||
AccessibilityUtils.getInstance().announceForAccessibility(mView, text);
|
AccessibilityUtils.getInstance().announceForAccessibility(mView, text);
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,17 +93,17 @@ public final class KeyCodeDescriptionMapper {
|
||||||
* @param keyboard The keyboard on which the key resides.
|
* @param keyboard The keyboard on which the key resides.
|
||||||
* @param key The key from which to obtain a description.
|
* @param key The key from which to obtain a description.
|
||||||
* @param shouldObscure {@true} if text (e.g. non-control) characters should be obscured.
|
* @param shouldObscure {@true} if text (e.g. non-control) characters should be obscured.
|
||||||
* @return a character sequence describing the action performed by pressing
|
* @return a character sequence describing the action performed by pressing the key
|
||||||
* the key
|
|
||||||
*/
|
*/
|
||||||
public String getDescriptionForKey(Context context, Keyboard keyboard, Key key,
|
public String getDescriptionForKey(final Context context, final Keyboard keyboard,
|
||||||
boolean shouldObscure) {
|
final Key key, final boolean shouldObscure) {
|
||||||
final int code = key.mCode;
|
final int code = key.mCode;
|
||||||
|
|
||||||
if (code == Constants.CODE_SWITCH_ALPHA_SYMBOL) {
|
if (code == Constants.CODE_SWITCH_ALPHA_SYMBOL) {
|
||||||
final String description = getDescriptionForSwitchAlphaSymbol(context, keyboard);
|
final String description = getDescriptionForSwitchAlphaSymbol(context, keyboard);
|
||||||
if (description != null)
|
if (description != null) {
|
||||||
return description;
|
return description;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (code == Constants.CODE_SHIFT) {
|
if (code == Constants.CODE_SHIFT) {
|
||||||
|
@ -127,7 +127,6 @@ public final class KeyCodeDescriptionMapper {
|
||||||
if (key.mCode != Constants.CODE_UNSPECIFIED) {
|
if (key.mCode != Constants.CODE_UNSPECIFIED) {
|
||||||
return getDescriptionForKeyCode(context, keyboard, key, shouldObscure);
|
return getDescriptionForKeyCode(context, keyboard, key, shouldObscure);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,10 +137,10 @@ public final class KeyCodeDescriptionMapper {
|
||||||
*
|
*
|
||||||
* @param context The package's context.
|
* @param context The package's context.
|
||||||
* @param keyboard The keyboard on which the key resides.
|
* @param keyboard The keyboard on which the key resides.
|
||||||
* @return a character sequence describing the action performed by pressing
|
* @return a character sequence describing the action performed by pressing the key
|
||||||
* the key
|
|
||||||
*/
|
*/
|
||||||
private String getDescriptionForSwitchAlphaSymbol(Context context, Keyboard keyboard) {
|
private String getDescriptionForSwitchAlphaSymbol(final Context context,
|
||||||
|
final Keyboard keyboard) {
|
||||||
final KeyboardId keyboardId = keyboard.mId;
|
final KeyboardId keyboardId = keyboard.mId;
|
||||||
final int elementId = keyboardId.mElementId;
|
final int elementId = keyboardId.mElementId;
|
||||||
final int resId;
|
final int resId;
|
||||||
|
@ -168,7 +167,6 @@ public final class KeyCodeDescriptionMapper {
|
||||||
Log.e(TAG, "Missing description for keyboard element ID:" + elementId);
|
Log.e(TAG, "Missing description for keyboard element ID:" + elementId);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return context.getString(resId);
|
return context.getString(resId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,7 +177,7 @@ public final class KeyCodeDescriptionMapper {
|
||||||
* @param keyboard The keyboard on which the key resides.
|
* @param keyboard The keyboard on which the key resides.
|
||||||
* @return A context-sensitive description of the "Shift" key.
|
* @return A context-sensitive description of the "Shift" key.
|
||||||
*/
|
*/
|
||||||
private String getDescriptionForShiftKey(Context context, Keyboard keyboard) {
|
private String getDescriptionForShiftKey(final Context context, final Keyboard keyboard) {
|
||||||
final KeyboardId keyboardId = keyboard.mId;
|
final KeyboardId keyboardId = keyboard.mId;
|
||||||
final int elementId = keyboardId.mElementId;
|
final int elementId = keyboardId.mElementId;
|
||||||
final int resId;
|
final int resId;
|
||||||
|
@ -197,7 +195,6 @@ public final class KeyCodeDescriptionMapper {
|
||||||
default:
|
default:
|
||||||
resId = R.string.spoken_description_shift;
|
resId = R.string.spoken_description_shift;
|
||||||
}
|
}
|
||||||
|
|
||||||
return context.getString(resId);
|
return context.getString(resId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,10 +204,10 @@ public final class KeyCodeDescriptionMapper {
|
||||||
* @param context The package's context.
|
* @param context The package's context.
|
||||||
* @param keyboard The keyboard on which the key resides.
|
* @param keyboard The keyboard on which the key resides.
|
||||||
* @param key The key to describe.
|
* @param key The key to describe.
|
||||||
* @return Returns a context-sensitive description of the "Enter" action
|
* @return Returns a context-sensitive description of the "Enter" action key.
|
||||||
* key.
|
|
||||||
*/
|
*/
|
||||||
private String getDescriptionForActionKey(Context context, Keyboard keyboard, Key key) {
|
private String getDescriptionForActionKey(final Context context, final Keyboard keyboard,
|
||||||
|
final Key key) {
|
||||||
final KeyboardId keyboardId = keyboard.mId;
|
final KeyboardId keyboardId = keyboard.mId;
|
||||||
final int actionId = keyboardId.imeActionId();
|
final int actionId = keyboardId.imeActionId();
|
||||||
final int resId;
|
final int resId;
|
||||||
|
@ -243,7 +240,6 @@ public final class KeyCodeDescriptionMapper {
|
||||||
default:
|
default:
|
||||||
resId = R.string.spoken_description_return;
|
resId = R.string.spoken_description_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return context.getString(resId);
|
return context.getString(resId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -265,11 +261,10 @@ public final class KeyCodeDescriptionMapper {
|
||||||
* @param keyboard The keyboard on which the key resides.
|
* @param keyboard The keyboard on which the key resides.
|
||||||
* @param key The key from which to obtain a description.
|
* @param key The key from which to obtain a description.
|
||||||
* @param shouldObscure {@true} if text (e.g. non-control) characters should be obscured.
|
* @param shouldObscure {@true} if text (e.g. non-control) characters should be obscured.
|
||||||
* @return a character sequence describing the action performed by pressing
|
* @return a character sequence describing the action performed by pressing the key
|
||||||
* the key
|
|
||||||
*/
|
*/
|
||||||
private String getDescriptionForKeyCode(Context context, Keyboard keyboard, Key key,
|
private String getDescriptionForKeyCode(final Context context, final Keyboard keyboard,
|
||||||
boolean shouldObscure) {
|
final Key key, final boolean shouldObscure) {
|
||||||
final int code = key.mCode;
|
final int code = key.mCode;
|
||||||
|
|
||||||
// If the key description should be obscured, now is the time to do it.
|
// If the key description should be obscured, now is the time to do it.
|
||||||
|
@ -277,15 +272,15 @@ public final class KeyCodeDescriptionMapper {
|
||||||
if (shouldObscure && isDefinedNonCtrl) {
|
if (shouldObscure && isDefinedNonCtrl) {
|
||||||
return context.getString(OBSCURED_KEY_RES_ID);
|
return context.getString(OBSCURED_KEY_RES_ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mKeyCodeMap.indexOfKey(code) >= 0) {
|
if (mKeyCodeMap.indexOfKey(code) >= 0) {
|
||||||
return context.getString(mKeyCodeMap.get(code));
|
return context.getString(mKeyCodeMap.get(code));
|
||||||
} else if (isDefinedNonCtrl) {
|
|
||||||
return Character.toString((char) code);
|
|
||||||
} else if (!TextUtils.isEmpty(key.mLabel)) {
|
|
||||||
return key.mLabel;
|
|
||||||
} else {
|
|
||||||
return context.getString(R.string.spoken_description_unknown, code);
|
|
||||||
}
|
}
|
||||||
|
if (isDefinedNonCtrl) {
|
||||||
|
return Character.toString((char) code);
|
||||||
|
}
|
||||||
|
if (!TextUtils.isEmpty(key.mLabel)) {
|
||||||
|
return key.mLabel;
|
||||||
|
}
|
||||||
|
return context.getString(R.string.spoken_description_unknown, code);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,8 +31,8 @@ public final class CompatUtils {
|
||||||
private static final String INPUT_METHOD_SUBTYPE_SETTINGS =
|
private static final String INPUT_METHOD_SUBTYPE_SETTINGS =
|
||||||
"android.settings.INPUT_METHOD_SUBTYPE_SETTINGS";
|
"android.settings.INPUT_METHOD_SUBTYPE_SETTINGS";
|
||||||
|
|
||||||
public static Intent getInputLanguageSelectionIntent(String inputMethodId,
|
public static Intent getInputLanguageSelectionIntent(final String inputMethodId,
|
||||||
int flagsForSubtypeSettings) {
|
final int flagsForSubtypeSettings) {
|
||||||
// Refer to android.provider.Settings.ACTION_INPUT_METHOD_SUBTYPE_SETTINGS
|
// Refer to android.provider.Settings.ACTION_INPUT_METHOD_SUBTYPE_SETTINGS
|
||||||
final String action = INPUT_METHOD_SUBTYPE_SETTINGS;
|
final String action = INPUT_METHOD_SUBTYPE_SETTINGS;
|
||||||
final Intent intent = new Intent(action);
|
final Intent intent = new Intent(action);
|
||||||
|
@ -45,7 +45,7 @@ public final class CompatUtils {
|
||||||
return intent;
|
return intent;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Class<?> getClass(String className) {
|
public static Class<?> getClass(final String className) {
|
||||||
try {
|
try {
|
||||||
return Class.forName(className);
|
return Class.forName(className);
|
||||||
} catch (ClassNotFoundException e) {
|
} catch (ClassNotFoundException e) {
|
||||||
|
@ -53,8 +53,8 @@ public final class CompatUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Method getMethod(Class<?> targetClass, String name,
|
public static Method getMethod(final Class<?> targetClass, final String name,
|
||||||
Class<?>... parameterTypes) {
|
final Class<?>... parameterTypes) {
|
||||||
if (targetClass == null || TextUtils.isEmpty(name)) return null;
|
if (targetClass == null || TextUtils.isEmpty(name)) return null;
|
||||||
try {
|
try {
|
||||||
return targetClass.getMethod(name, parameterTypes);
|
return targetClass.getMethod(name, parameterTypes);
|
||||||
|
@ -66,7 +66,7 @@ public final class CompatUtils {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Field getField(Class<?> targetClass, String name) {
|
public static Field getField(final Class<?> targetClass, final String name) {
|
||||||
if (targetClass == null || TextUtils.isEmpty(name)) return null;
|
if (targetClass == null || TextUtils.isEmpty(name)) return null;
|
||||||
try {
|
try {
|
||||||
return targetClass.getField(name);
|
return targetClass.getField(name);
|
||||||
|
@ -78,7 +78,8 @@ public final class CompatUtils {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Constructor<?> getConstructor(Class<?> targetClass, Class<?> ... types) {
|
public static Constructor<?> getConstructor(final Class<?> targetClass,
|
||||||
|
final Class<?> ... types) {
|
||||||
if (targetClass == null || types == null) return null;
|
if (targetClass == null || types == null) return null;
|
||||||
try {
|
try {
|
||||||
return targetClass.getConstructor(types);
|
return targetClass.getConstructor(types);
|
||||||
|
@ -90,7 +91,7 @@ public final class CompatUtils {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Object newInstance(Constructor<?> constructor, Object ... args) {
|
public static Object newInstance(final Constructor<?> constructor, final Object ... args) {
|
||||||
if (constructor == null) return null;
|
if (constructor == null) return null;
|
||||||
try {
|
try {
|
||||||
return constructor.newInstance(args);
|
return constructor.newInstance(args);
|
||||||
|
@ -100,8 +101,8 @@ public final class CompatUtils {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Object invoke(
|
public static Object invoke(final Object receiver, final Object defaultValue,
|
||||||
Object receiver, Object defaultValue, Method method, Object... args) {
|
final Method method, final Object... args) {
|
||||||
if (method == null) return defaultValue;
|
if (method == null) return defaultValue;
|
||||||
try {
|
try {
|
||||||
return method.invoke(receiver, args);
|
return method.invoke(receiver, args);
|
||||||
|
@ -111,7 +112,8 @@ public final class CompatUtils {
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Object getFieldValue(Object receiver, Object defaultValue, Field field) {
|
public static Object getFieldValue(final Object receiver, final Object defaultValue,
|
||||||
|
final Field field) {
|
||||||
if (field == null) return defaultValue;
|
if (field == null) return defaultValue;
|
||||||
try {
|
try {
|
||||||
return field.get(receiver);
|
return field.get(receiver);
|
||||||
|
@ -121,7 +123,7 @@ public final class CompatUtils {
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setFieldValue(Object receiver, Field field, Object value) {
|
public static void setFieldValue(final Object receiver, final Field field, final Object value) {
|
||||||
if (field == null) return;
|
if (field == null) return;
|
||||||
try {
|
try {
|
||||||
field.set(receiver, value);
|
field.set(receiver, value);
|
||||||
|
|
|
@ -21,23 +21,23 @@ import android.view.inputmethod.EditorInfo;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
public final class EditorInfoCompatUtils {
|
public final class EditorInfoCompatUtils {
|
||||||
// EditorInfo.IME_FLAG_FORCE_ASCII has been introduced since API#16 (JellyBean).
|
// Note that EditorInfo.IME_FLAG_FORCE_ASCII has been introduced
|
||||||
|
// in API level 16 (Build.VERSION_CODES.JELLY_BEAN).
|
||||||
private static final Field FIELD_IME_FLAG_FORCE_ASCII = CompatUtils.getField(
|
private static final Field FIELD_IME_FLAG_FORCE_ASCII = CompatUtils.getField(
|
||||||
EditorInfo.class, "IME_FLAG_FORCE_ASCII");
|
EditorInfo.class, "IME_FLAG_FORCE_ASCII");
|
||||||
private static final Integer OBJ_IME_FLAG_FORCE_ASCII = (Integer) CompatUtils
|
private static final Integer OBJ_IME_FLAG_FORCE_ASCII = (Integer) CompatUtils.getFieldValue(
|
||||||
.getFieldValue(null, null, FIELD_IME_FLAG_FORCE_ASCII);
|
null /* receiver */, null /* defaultValue */, FIELD_IME_FLAG_FORCE_ASCII);
|
||||||
|
|
||||||
private EditorInfoCompatUtils() {
|
private EditorInfoCompatUtils() {
|
||||||
// This utility class is not publicly instantiable.
|
// This utility class is not publicly instantiable.
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean hasFlagForceAscii(int imeOptions) {
|
public static boolean hasFlagForceAscii(final int imeOptions) {
|
||||||
if (OBJ_IME_FLAG_FORCE_ASCII == null)
|
if (OBJ_IME_FLAG_FORCE_ASCII == null) return false;
|
||||||
return false;
|
|
||||||
return (imeOptions & OBJ_IME_FLAG_FORCE_ASCII) != 0;
|
return (imeOptions & OBJ_IME_FLAG_FORCE_ASCII) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String imeActionName(int imeOptions) {
|
public static String imeActionName(final int imeOptions) {
|
||||||
final int actionId = imeOptions & EditorInfo.IME_MASK_ACTION;
|
final int actionId = imeOptions & EditorInfo.IME_MASK_ACTION;
|
||||||
switch (actionId) {
|
switch (actionId) {
|
||||||
case EditorInfo.IME_ACTION_UNSPECIFIED:
|
case EditorInfo.IME_ACTION_UNSPECIFIED:
|
||||||
|
@ -61,7 +61,7 @@ public final class EditorInfoCompatUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String imeOptionsName(int imeOptions) {
|
public static String imeOptionsName(final int imeOptions) {
|
||||||
final String action = imeActionName(imeOptions);
|
final String action = imeActionName(imeOptions);
|
||||||
final StringBuilder flags = new StringBuilder();
|
final StringBuilder flags = new StringBuilder();
|
||||||
if ((imeOptions & EditorInfo.IME_FLAG_NO_ENTER_ACTION) != 0) {
|
if ((imeOptions & EditorInfo.IME_FLAG_NO_ENTER_ACTION) != 0) {
|
||||||
|
|
|
@ -23,6 +23,8 @@ import android.view.inputmethod.InputMethodManager;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
public final class InputMethodManagerCompatWrapper {
|
public final class InputMethodManagerCompatWrapper {
|
||||||
|
// Note that InputMethodManager.switchToNextInputMethod() has been introduced
|
||||||
|
// in API level 16 (Build.VERSION_CODES.JELLY_BEAN).
|
||||||
private static final Method METHOD_switchToNextInputMethod = CompatUtils.getMethod(
|
private static final Method METHOD_switchToNextInputMethod = CompatUtils.getMethod(
|
||||||
InputMethodManager.class, "switchToNextInputMethod", IBinder.class, Boolean.TYPE);
|
InputMethodManager.class, "switchToNextInputMethod", IBinder.class, Boolean.TYPE);
|
||||||
|
|
||||||
|
@ -33,7 +35,7 @@ public final class InputMethodManagerCompatWrapper {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean switchToNextInputMethod(final IBinder token, final boolean onlyCurrentIme) {
|
public boolean switchToNextInputMethod(final IBinder token, final boolean onlyCurrentIme) {
|
||||||
return (Boolean)CompatUtils.invoke(mImm, false, METHOD_switchToNextInputMethod, token,
|
return (Boolean)CompatUtils.invoke(mImm, false /* defaultValue */,
|
||||||
onlyCurrentIme);
|
METHOD_switchToNextInputMethod, token, onlyCurrentIme);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,8 @@ import android.inputmethodservice.InputMethodService;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
public final class InputMethodServiceCompatUtils {
|
public final class InputMethodServiceCompatUtils {
|
||||||
|
// Note that InputMethodService.enableHardwareAcceleration() has been introduced
|
||||||
|
// in API level 17 (Build.VERSION_CODES.JELLY_BEAN_MR1).
|
||||||
private static final Method METHOD_enableHardwareAcceleration =
|
private static final Method METHOD_enableHardwareAcceleration =
|
||||||
CompatUtils.getMethod(InputMethodService.class, "enableHardwareAcceleration");
|
CompatUtils.getMethod(InputMethodService.class, "enableHardwareAcceleration");
|
||||||
|
|
||||||
|
@ -28,7 +30,8 @@ public final class InputMethodServiceCompatUtils {
|
||||||
// This utility class is not publicly instantiable.
|
// This utility class is not publicly instantiable.
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean enableHardwareAcceleration(InputMethodService ims) {
|
public static boolean enableHardwareAcceleration(final InputMethodService ims) {
|
||||||
return (Boolean)CompatUtils.invoke(ims, false, METHOD_enableHardwareAcceleration);
|
return (Boolean)CompatUtils.invoke(ims, false /* defaultValue */,
|
||||||
|
METHOD_enableHardwareAcceleration);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,8 @@ package com.android.inputmethod.compat;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
public final class SettingsSecureCompatUtils {
|
public final class SettingsSecureCompatUtils {
|
||||||
|
// Note that Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD has been introduced
|
||||||
|
// in API level 15 (Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1).
|
||||||
private static final Field FIELD_ACCESSIBILITY_SPEAK_PASSWORD = CompatUtils.getField(
|
private static final Field FIELD_ACCESSIBILITY_SPEAK_PASSWORD = CompatUtils.getField(
|
||||||
android.provider.Settings.Secure.class, "ACCESSIBILITY_SPEAK_PASSWORD");
|
android.provider.Settings.Secure.class, "ACCESSIBILITY_SPEAK_PASSWORD");
|
||||||
|
|
||||||
|
@ -30,5 +32,5 @@ public final class SettingsSecureCompatUtils {
|
||||||
* Whether to speak passwords while in accessibility mode.
|
* Whether to speak passwords while in accessibility mode.
|
||||||
*/
|
*/
|
||||||
public static final String ACCESSIBILITY_SPEAK_PASSWORD = (String) CompatUtils.getFieldValue(
|
public static final String ACCESSIBILITY_SPEAK_PASSWORD = (String) CompatUtils.getFieldValue(
|
||||||
null, null, FIELD_ACCESSIBILITY_SPEAK_PASSWORD);
|
null /* receiver */, null /* defaultValue */, FIELD_ACCESSIBILITY_SPEAK_PASSWORD);
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,11 +34,12 @@ import java.util.ArrayList;
|
||||||
public final class SuggestionSpanUtils {
|
public final class SuggestionSpanUtils {
|
||||||
private static final String TAG = SuggestionSpanUtils.class.getSimpleName();
|
private static final String TAG = SuggestionSpanUtils.class.getSimpleName();
|
||||||
|
|
||||||
// Note that SuggestionSpan.FLAG_AUTO_CORRECTION was added in API level 15.
|
// Note that SuggestionSpan.FLAG_AUTO_CORRECTION has been introduced
|
||||||
public static final Field FIELD_FLAG_AUTO_CORRECTION =
|
// in API level 15 (Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1).
|
||||||
CompatUtils.getField(SuggestionSpan.class, "FLAG_AUTO_CORRECTION");
|
public static final Field FIELD_FLAG_AUTO_CORRECTION = CompatUtils.getField(
|
||||||
public static final Integer OBJ_FLAG_AUTO_CORRECTION =
|
SuggestionSpan.class, "FLAG_AUTO_CORRECTION");
|
||||||
(Integer) CompatUtils.getFieldValue(null, null, FIELD_FLAG_AUTO_CORRECTION);
|
public static final Integer OBJ_FLAG_AUTO_CORRECTION = (Integer) CompatUtils.getFieldValue(
|
||||||
|
null /* receiver */, null /* defaultValue */, FIELD_FLAG_AUTO_CORRECTION);
|
||||||
|
|
||||||
static {
|
static {
|
||||||
if (LatinImeLogger.sDBG) {
|
if (LatinImeLogger.sDBG) {
|
||||||
|
@ -58,8 +59,9 @@ public final class SuggestionSpanUtils {
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
final Spannable spannable = new SpannableString(text);
|
final Spannable spannable = new SpannableString(text);
|
||||||
final SuggestionSpan suggestionSpan = new SuggestionSpan(context, null, new String[] {},
|
final SuggestionSpan suggestionSpan = new SuggestionSpan(context, null /* locale */,
|
||||||
(int)OBJ_FLAG_AUTO_CORRECTION, SuggestionSpanPickedNotificationReceiver.class);
|
new String[] {} /* suggestions */, (int)OBJ_FLAG_AUTO_CORRECTION,
|
||||||
|
SuggestionSpanPickedNotificationReceiver.class);
|
||||||
spannable.setSpan(suggestionSpan, 0, text.length(),
|
spannable.setSpan(suggestionSpan, 0, text.length(),
|
||||||
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE | Spanned.SPAN_COMPOSING);
|
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE | Spanned.SPAN_COMPOSING);
|
||||||
return spannable;
|
return spannable;
|
||||||
|
@ -87,8 +89,8 @@ public final class SuggestionSpanUtils {
|
||||||
|
|
||||||
// TODO: We should avoid adding suggestion span candidates that came from the bigram
|
// TODO: We should avoid adding suggestion span candidates that came from the bigram
|
||||||
// prediction.
|
// prediction.
|
||||||
final SuggestionSpan suggestionSpan = new SuggestionSpan(context, null,
|
final SuggestionSpan suggestionSpan = new SuggestionSpan(context, null /* locale */,
|
||||||
suggestionsList.toArray(new String[suggestionsList.size()]), 0,
|
suggestionsList.toArray(new String[suggestionsList.size()]), 0 /* flags */,
|
||||||
SuggestionSpanPickedNotificationReceiver.class);
|
SuggestionSpanPickedNotificationReceiver.class);
|
||||||
spannable.setSpan(suggestionSpan, 0, pickedWord.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
spannable.setSpan(suggestionSpan, 0, pickedWord.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||||
return spannable;
|
return spannable;
|
||||||
|
|
|
@ -21,10 +21,13 @@ import android.view.textservice.SuggestionsInfo;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
public final class SuggestionsInfoCompatUtils {
|
public final class SuggestionsInfoCompatUtils {
|
||||||
private static final Field FIELD_RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS = CompatUtils.getField(
|
// Note that SuggestionsInfo.RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS has been introduced
|
||||||
SuggestionsInfo.class, "RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS");
|
// in API level 15 (Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1).
|
||||||
private static final Integer OBJ_RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS = (Integer) CompatUtils
|
private static final Field FIELD_RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS =
|
||||||
.getFieldValue(null, null, FIELD_RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS);
|
CompatUtils.getField(SuggestionsInfo.class, "RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS");
|
||||||
|
private static final Integer OBJ_RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS =
|
||||||
|
(Integer) CompatUtils.getFieldValue(null /* receiver */, null /* defaultValue */,
|
||||||
|
FIELD_RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS);
|
||||||
private static final int RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS =
|
private static final int RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS =
|
||||||
OBJ_RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS != null
|
OBJ_RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS != null
|
||||||
? OBJ_RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS : 0;
|
? OBJ_RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS : 0;
|
||||||
|
|
|
@ -530,7 +530,7 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
|
||||||
|
|
||||||
// This always needs to be set since the accessibility state can
|
// This always needs to be set since the accessibility state can
|
||||||
// potentially change without the keyboard being set again.
|
// potentially change without the keyboard being set again.
|
||||||
AccessibleKeyboardViewProxy.getInstance().setKeyboard(keyboard);
|
AccessibleKeyboardViewProxy.getInstance().setKeyboard();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note that this method is called from a non-UI thread.
|
// Note that this method is called from a non-UI thread.
|
||||||
|
|
|
@ -45,7 +45,7 @@ public final class AdditionalSubtype {
|
||||||
final String keyboardLayoutSetName, final String extraValue) {
|
final String keyboardLayoutSetName, final String extraValue) {
|
||||||
final String layoutExtraValue = KEYBOARD_LAYOUT_SET + "=" + keyboardLayoutSetName;
|
final String layoutExtraValue = KEYBOARD_LAYOUT_SET + "=" + keyboardLayoutSetName;
|
||||||
final String layoutDisplayNameExtraValue;
|
final String layoutDisplayNameExtraValue;
|
||||||
if (Build.VERSION.SDK_INT >= /* JELLY_BEAN */ 15
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN
|
||||||
&& SubtypeLocale.isExceptionalLocale(localeString)) {
|
&& SubtypeLocale.isExceptionalLocale(localeString)) {
|
||||||
final String layoutDisplayName = SubtypeLocale.getKeyboardLayoutSetDisplayName(
|
final String layoutDisplayName = SubtypeLocale.getKeyboardLayoutSetDisplayName(
|
||||||
keyboardLayoutSetName);
|
keyboardLayoutSetName);
|
||||||
|
|
|
@ -111,7 +111,7 @@ public final class Constants {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class TextUtils {
|
public static final class TextUtils {
|
||||||
/**
|
/**
|
||||||
* Capitalization mode for {@link android.text.TextUtils#getCapsMode}: don't capitalize
|
* Capitalization mode for {@link android.text.TextUtils#getCapsMode}: don't capitalize
|
||||||
* characters. This value may be used with
|
* characters. This value may be used with
|
||||||
|
@ -126,7 +126,7 @@ public final class Constants {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Dictionary {
|
public static final class Dictionary {
|
||||||
public static final int MAX_WORD_LENGTH = 48;
|
public static final int MAX_WORD_LENGTH = 48;
|
||||||
|
|
||||||
private Dictionary() {
|
private Dictionary() {
|
||||||
|
|
|
@ -38,7 +38,7 @@ public final class DictionaryCollection extends Dictionary {
|
||||||
mDictionaries = CollectionUtils.newCopyOnWriteArrayList();
|
mDictionaries = CollectionUtils.newCopyOnWriteArrayList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public DictionaryCollection(final String dictType, Dictionary... dictionaries) {
|
public DictionaryCollection(final String dictType, final Dictionary... dictionaries) {
|
||||||
super(dictType);
|
super(dictType);
|
||||||
if (null == dictionaries) {
|
if (null == dictionaries) {
|
||||||
mDictionaries = CollectionUtils.newCopyOnWriteArrayList();
|
mDictionaries = CollectionUtils.newCopyOnWriteArrayList();
|
||||||
|
@ -48,7 +48,7 @@ public final class DictionaryCollection extends Dictionary {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public DictionaryCollection(final String dictType, Collection<Dictionary> dictionaries) {
|
public DictionaryCollection(final String dictType, final Collection<Dictionary> dictionaries) {
|
||||||
super(dictType);
|
super(dictType);
|
||||||
mDictionaries = CollectionUtils.newCopyOnWriteArrayList(dictionaries);
|
mDictionaries = CollectionUtils.newCopyOnWriteArrayList(dictionaries);
|
||||||
mDictionaries.removeAll(Collections.singleton(null));
|
mDictionaries.removeAll(Collections.singleton(null));
|
||||||
|
|
|
@ -35,6 +35,7 @@ import android.graphics.Rect;
|
||||||
import android.inputmethodservice.InputMethodService;
|
import android.inputmethodservice.InputMethodService;
|
||||||
import android.media.AudioManager;
|
import android.media.AudioManager;
|
||||||
import android.net.ConnectivityManager;
|
import android.net.ConnectivityManager;
|
||||||
|
import android.os.Build.VERSION_CODES;
|
||||||
import android.os.Debug;
|
import android.os.Debug;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.HandlerThread;
|
import android.os.HandlerThread;
|
||||||
|
@ -1318,10 +1319,8 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 16 is android.os.Build.VERSION_CODES.JELLY_BEAN but we can't write it because
|
|
||||||
// we want to be able to compile against the Ice Cream Sandwich SDK.
|
|
||||||
if (Constants.CODE_ENTER == code && mTargetApplicationInfo != null
|
if (Constants.CODE_ENTER == code && mTargetApplicationInfo != null
|
||||||
&& mTargetApplicationInfo.targetSdkVersion < 16) {
|
&& mTargetApplicationInfo.targetSdkVersion < VERSION_CODES.JELLY_BEAN) {
|
||||||
// Backward compatibility mode. Before Jelly bean, the keyboard would simulate
|
// Backward compatibility mode. Before Jelly bean, the keyboard would simulate
|
||||||
// a hardware keyboard event on pressing enter or delete. This is bad for many
|
// a hardware keyboard event on pressing enter or delete. This is bad for many
|
||||||
// reasons (there are race conditions with commits) but some applications are
|
// reasons (there are race conditions with commits) but some applications are
|
||||||
|
@ -1736,10 +1735,8 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
|
||||||
// This should never happen.
|
// This should never happen.
|
||||||
Log.e(TAG, "Backspace when we don't know the selection position");
|
Log.e(TAG, "Backspace when we don't know the selection position");
|
||||||
}
|
}
|
||||||
// 16 is android.os.Build.VERSION_CODES.JELLY_BEAN but we can't write it because
|
|
||||||
// we want to be able to compile against the Ice Cream Sandwich SDK.
|
|
||||||
if (mTargetApplicationInfo != null
|
if (mTargetApplicationInfo != null
|
||||||
&& mTargetApplicationInfo.targetSdkVersion < 16) {
|
&& mTargetApplicationInfo.targetSdkVersion < VERSION_CODES.JELLY_BEAN) {
|
||||||
// Backward compatibility mode. Before Jelly bean, the keyboard would simulate
|
// Backward compatibility mode. Before Jelly bean, the keyboard would simulate
|
||||||
// a hardware keyboard event on pressing enter or delete. This is bad for many
|
// a hardware keyboard event on pressing enter or delete. This is bad for many
|
||||||
// reasons (there are race conditions with commits) but some applications are
|
// reasons (there are race conditions with commits) but some applications are
|
||||||
|
|
|
@ -29,7 +29,7 @@ import android.view.inputmethod.EditorInfo;
|
||||||
* the IME needs to take a note of what it has to replace and where it is.
|
* the IME needs to take a note of what it has to replace and where it is.
|
||||||
* This class encapsulates this data.
|
* This class encapsulates this data.
|
||||||
*/
|
*/
|
||||||
public class PositionalInfoForUserDictPendingAddition {
|
public final class PositionalInfoForUserDictPendingAddition {
|
||||||
final private String mOriginalWord;
|
final private String mOriginalWord;
|
||||||
final private int mCursorPos; // Position of the cursor after the word
|
final private int mCursorPos; // Position of the cursor after the word
|
||||||
final private EditorInfo mEditorInfo; // On what binding this has been added
|
final private EditorInfo mEditorInfo; // On what binding this has been added
|
||||||
|
|
|
@ -284,40 +284,40 @@ public final class RichInputConnection {
|
||||||
if (DEBUG_BATCH_NESTING) checkBatchEdit();
|
if (DEBUG_BATCH_NESTING) checkBatchEdit();
|
||||||
if (keyEvent.getAction() == KeyEvent.ACTION_DOWN) {
|
if (keyEvent.getAction() == KeyEvent.ACTION_DOWN) {
|
||||||
if (DEBUG_PREVIOUS_TEXT) checkConsistencyForDebug();
|
if (DEBUG_PREVIOUS_TEXT) checkConsistencyForDebug();
|
||||||
// This method is only called for enter or backspace when speaking to old
|
// This method is only called for enter or backspace when speaking to old applications
|
||||||
// applications (target SDK <= 15), or for digits.
|
// (target SDK <= 15 (Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1)), or for digits.
|
||||||
// When talking to new applications we never use this method because it's inherently
|
// When talking to new applications we never use this method because it's inherently
|
||||||
// racy and has unpredictable results, but for backward compatibility we continue
|
// racy and has unpredictable results, but for backward compatibility we continue
|
||||||
// sending the key events for only Enter and Backspace because some applications
|
// sending the key events for only Enter and Backspace because some applications
|
||||||
// mistakenly catch them to do some stuff.
|
// mistakenly catch them to do some stuff.
|
||||||
switch (keyEvent.getKeyCode()) {
|
switch (keyEvent.getKeyCode()) {
|
||||||
case KeyEvent.KEYCODE_ENTER:
|
case KeyEvent.KEYCODE_ENTER:
|
||||||
mCommittedTextBeforeComposingText.append("\n");
|
mCommittedTextBeforeComposingText.append("\n");
|
||||||
mCurrentCursorPosition += 1;
|
mCurrentCursorPosition += 1;
|
||||||
break;
|
break;
|
||||||
case KeyEvent.KEYCODE_DEL:
|
case KeyEvent.KEYCODE_DEL:
|
||||||
if (0 == mComposingText.length()) {
|
if (0 == mComposingText.length()) {
|
||||||
if (mCommittedTextBeforeComposingText.length() > 0) {
|
if (mCommittedTextBeforeComposingText.length() > 0) {
|
||||||
mCommittedTextBeforeComposingText.delete(
|
mCommittedTextBeforeComposingText.delete(
|
||||||
mCommittedTextBeforeComposingText.length() - 1,
|
mCommittedTextBeforeComposingText.length() - 1,
|
||||||
mCommittedTextBeforeComposingText.length());
|
mCommittedTextBeforeComposingText.length());
|
||||||
}
|
|
||||||
} else {
|
|
||||||
mComposingText.delete(mComposingText.length() - 1, mComposingText.length());
|
|
||||||
}
|
}
|
||||||
if (mCurrentCursorPosition > 0) mCurrentCursorPosition -= 1;
|
} else {
|
||||||
break;
|
mComposingText.delete(mComposingText.length() - 1, mComposingText.length());
|
||||||
case KeyEvent.KEYCODE_UNKNOWN:
|
}
|
||||||
if (null != keyEvent.getCharacters()) {
|
if (mCurrentCursorPosition > 0) mCurrentCursorPosition -= 1;
|
||||||
mCommittedTextBeforeComposingText.append(keyEvent.getCharacters());
|
break;
|
||||||
mCurrentCursorPosition += keyEvent.getCharacters().length();
|
case KeyEvent.KEYCODE_UNKNOWN:
|
||||||
}
|
if (null != keyEvent.getCharacters()) {
|
||||||
break;
|
mCommittedTextBeforeComposingText.append(keyEvent.getCharacters());
|
||||||
default:
|
mCurrentCursorPosition += keyEvent.getCharacters().length();
|
||||||
final String text = new String(new int[] { keyEvent.getUnicodeChar() }, 0, 1);
|
}
|
||||||
mCommittedTextBeforeComposingText.append(text);
|
break;
|
||||||
mCurrentCursorPosition += text.length();
|
default:
|
||||||
break;
|
final String text = new String(new int[] { keyEvent.getUnicodeChar() }, 0, 1);
|
||||||
|
mCommittedTextBeforeComposingText.append(text);
|
||||||
|
mCurrentCursorPosition += text.length();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (null != mIC) {
|
if (null != mIC) {
|
||||||
|
|
|
@ -130,7 +130,8 @@ public final class SubtypeLocale {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getSubtypeNameId(String localeString, String keyboardLayoutName) {
|
public static int getSubtypeNameId(String localeString, String keyboardLayoutName) {
|
||||||
if (Build.VERSION.SDK_INT >= /* JELLY_BEAN */ 15 && isExceptionalLocale(localeString)) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN
|
||||||
|
&& isExceptionalLocale(localeString)) {
|
||||||
return sExceptionalLocaleToWithLayoutNameIdsMap.get(localeString);
|
return sExceptionalLocaleToWithLayoutNameIdsMap.get(localeString);
|
||||||
}
|
}
|
||||||
final String key = localeString.equals(NO_LANGUAGE)
|
final String key = localeString.equals(NO_LANGUAGE)
|
||||||
|
@ -166,8 +167,9 @@ public final class SubtypeLocale {
|
||||||
// zz azerty T No language (AZERTY) in system locale
|
// zz azerty T No language (AZERTY) in system locale
|
||||||
|
|
||||||
public static String getSubtypeDisplayName(final InputMethodSubtype subtype, Resources res) {
|
public static String getSubtypeDisplayName(final InputMethodSubtype subtype, Resources res) {
|
||||||
final String replacementString = (Build.VERSION.SDK_INT >= /* JELLY_BEAN */ 15
|
final String replacementString =
|
||||||
&& subtype.containsExtraValueKey(UNTRANSLATABLE_STRING_IN_SUBTYPE_NAME))
|
(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN
|
||||||
|
&& subtype.containsExtraValueKey(UNTRANSLATABLE_STRING_IN_SUBTYPE_NAME))
|
||||||
? subtype.getExtraValueOf(UNTRANSLATABLE_STRING_IN_SUBTYPE_NAME)
|
? subtype.getExtraValueOf(UNTRANSLATABLE_STRING_IN_SUBTYPE_NAME)
|
||||||
: getSubtypeLocaleDisplayName(subtype.getLocale());
|
: getSubtypeLocaleDisplayName(subtype.getLocale());
|
||||||
final int nameResId = subtype.getNameResId();
|
final int nameResId = subtype.getNameResId();
|
||||||
|
|
|
@ -24,6 +24,7 @@ import android.content.Intent;
|
||||||
import android.database.ContentObserver;
|
import android.database.ContentObserver;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
import android.os.Build;
|
||||||
import android.provider.UserDictionary.Words;
|
import android.provider.UserDictionary.Words;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
@ -43,8 +44,7 @@ public class UserBinaryDictionary extends ExpandableBinaryDictionary {
|
||||||
final static String SHORTCUT = "shortcut";
|
final static String SHORTCUT = "shortcut";
|
||||||
private static final String[] PROJECTION_QUERY;
|
private static final String[] PROJECTION_QUERY;
|
||||||
static {
|
static {
|
||||||
// 16 is JellyBean, but we want this to compile against ICS.
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
|
||||||
if (android.os.Build.VERSION.SDK_INT >= 16) {
|
|
||||||
PROJECTION_QUERY = new String[] {
|
PROJECTION_QUERY = new String[] {
|
||||||
Words.WORD,
|
Words.WORD,
|
||||||
SHORTCUT,
|
SHORTCUT,
|
||||||
|
@ -90,13 +90,14 @@ public class UserBinaryDictionary extends ExpandableBinaryDictionary {
|
||||||
mObserver = new ContentObserver(null) {
|
mObserver = new ContentObserver(null) {
|
||||||
@Override
|
@Override
|
||||||
public void onChange(final boolean self) {
|
public void onChange(final boolean self) {
|
||||||
// This hook is deprecated as of API level 16, but should still be supported for
|
// This hook is deprecated as of API level 16 (Build.VERSION_CODES.JELLY_BEAN),
|
||||||
// cases where the IME is running on an older version of the platform.
|
// but should still be supported for cases where the IME is running on an older
|
||||||
|
// version of the platform.
|
||||||
onChange(self, null);
|
onChange(self, null);
|
||||||
}
|
}
|
||||||
// The following hook is only available as of API level 16, and as such it will only
|
// The following hook is only available as of API level 16
|
||||||
// work on JellyBean+ devices. On older versions of the platform, the hook
|
// (Build.VERSION_CODES.JELLY_BEAN), and as such it will only work on JellyBean+
|
||||||
// above will be called instead.
|
// devices. On older versions of the platform, the hook above will be called instead.
|
||||||
@Override
|
@Override
|
||||||
public void onChange(final boolean self, final Uri uri) {
|
public void onChange(final boolean self, final Uri uri) {
|
||||||
setRequiresReload(true);
|
setRequiresReload(true);
|
||||||
|
@ -233,8 +234,7 @@ public class UserBinaryDictionary extends ExpandableBinaryDictionary {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addWords(final Cursor cursor) {
|
private void addWords(final Cursor cursor) {
|
||||||
// 16 is JellyBean, but we want this to compile against ICS.
|
final boolean hasShortcutColumn = Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN;
|
||||||
final boolean hasShortcutColumn = android.os.Build.VERSION.SDK_INT >= 16;
|
|
||||||
clearFusionDictionary();
|
clearFusionDictionary();
|
||||||
if (cursor == null) return;
|
if (cursor == null) return;
|
||||||
if (cursor.moveToFirst()) {
|
if (cursor.moveToFirst()) {
|
||||||
|
|
|
@ -48,6 +48,7 @@ public final class UserHistoryDictIOUtils {
|
||||||
public void setBigram(final String word1, final String word2, final int frequency);
|
public void setBigram(final String word1, final String word2, final int frequency);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@UsedForTesting
|
||||||
public interface BigramDictionaryInterface {
|
public interface BigramDictionaryInterface {
|
||||||
public int getFrequency(final String word1, final String word2);
|
public int getFrequency(final String word1, final String word2);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,8 @@ package com.android.inputmethod.latin;
|
||||||
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.android.inputmethod.annotations.UsedForTesting;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
@ -26,6 +28,7 @@ import java.util.Set;
|
||||||
* All bigrams including stale ones in SQL DB should be stored in this class to avoid adding stale
|
* All bigrams including stale ones in SQL DB should be stored in this class to avoid adding stale
|
||||||
* bigrams when we write to the SQL DB.
|
* bigrams when we write to the SQL DB.
|
||||||
*/
|
*/
|
||||||
|
@UsedForTesting
|
||||||
public final class UserHistoryDictionaryBigramList {
|
public final class UserHistoryDictionaryBigramList {
|
||||||
public static final byte FORGETTING_CURVE_INITIAL_VALUE = 0;
|
public static final byte FORGETTING_CURVE_INITIAL_VALUE = 0;
|
||||||
private static final String TAG = UserHistoryDictionaryBigramList.class.getSimpleName();
|
private static final String TAG = UserHistoryDictionaryBigramList.class.getSimpleName();
|
||||||
|
|
|
@ -61,7 +61,7 @@ public final class Utils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* package */ static class RingCharBuffer {
|
/* package */ static final class RingCharBuffer {
|
||||||
private static RingCharBuffer sRingCharBuffer = new RingCharBuffer();
|
private static RingCharBuffer sRingCharBuffer = new RingCharBuffer();
|
||||||
private static final char PLACEHOLDER_DELIMITER_CHAR = '\uFFFC';
|
private static final char PLACEHOLDER_DELIMITER_CHAR = '\uFFFC';
|
||||||
private static final int INVALID_COORDINATE = -2;
|
private static final int INVALID_COORDINATE = -2;
|
||||||
|
@ -203,7 +203,7 @@ public final class Utils {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialization-on-demand holder
|
// Initialization-on-demand holder
|
||||||
private static class OnDemandInitializationHolder {
|
private static final class OnDemandInitializationHolder {
|
||||||
public static final UsabilityStudyLogUtils sInstance = new UsabilityStudyLogUtils();
|
public static final UsabilityStudyLogUtils sInstance = new UsabilityStudyLogUtils();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,6 +56,7 @@ public final class BinaryDictInputOutput {
|
||||||
private static final int MAX_PASSES = 24;
|
private static final int MAX_PASSES = 24;
|
||||||
private static final int MAX_JUMPS = 12;
|
private static final int MAX_JUMPS = 12;
|
||||||
|
|
||||||
|
@UsedForTesting
|
||||||
public interface FusionDictionaryBufferInterface {
|
public interface FusionDictionaryBufferInterface {
|
||||||
public int readUnsignedByte();
|
public int readUnsignedByte();
|
||||||
public int readUnsignedShort();
|
public int readUnsignedShort();
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
package com.android.inputmethod.latin.makedict;
|
package com.android.inputmethod.latin.makedict;
|
||||||
|
|
||||||
|
import com.android.inputmethod.annotations.UsedForTesting;
|
||||||
import com.android.inputmethod.latin.Constants;
|
import com.android.inputmethod.latin.Constants;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -29,6 +30,7 @@ import java.util.LinkedList;
|
||||||
/**
|
/**
|
||||||
* A dictionary that can fusion heads and tails of words for more compression.
|
* A dictionary that can fusion heads and tails of words for more compression.
|
||||||
*/
|
*/
|
||||||
|
@UsedForTesting
|
||||||
public final class FusionDictionary implements Iterable<Word> {
|
public final class FusionDictionary implements Iterable<Word> {
|
||||||
private static final boolean DBG = MakedictLog.DBG;
|
private static final boolean DBG = MakedictLog.DBG;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue