List of usage examples for android.view.accessibility AccessibilityNodeInfo FOCUS_ACCESSIBILITY
int FOCUS_ACCESSIBILITY
To view the source code for android.view.accessibility AccessibilityNodeInfo FOCUS_ACCESSIBILITY.
Click Source Link
From source file:com.android.screenspeak.eventprocessor.ProcessorFocusAndSingleTap.java
private void followScrollEvent(AccessibilityNodeInfoCompat source, AccessibilityRecordCompat record, int movingDirection, boolean wasScrollAction) { AccessibilityNodeInfoCompat root = null; AccessibilityNodeInfoCompat accessibilityFocused = null; try {//from w w w .j a v a 2 s. c o m // First, see if we've already placed accessibility focus. root = AccessibilityServiceCompatUtils.getRootInAccessibilityFocusedWindow(mService); if (root == null) { return; } accessibilityFocused = root.findFocus(AccessibilityNodeInfo.FOCUS_ACCESSIBILITY); boolean validAccessibilityFocus = AccessibilityNodeInfoUtils.shouldFocusNode(accessibilityFocused); // there are cases when scrollable container was scrolled and application set // focus on node that is on new container page. We should keep this focus boolean hasInputFocus = accessibilityFocused != null && accessibilityFocused.isFocused(); if (validAccessibilityFocus && (hasInputFocus || !wasScrollAction)) { // focused on valid node and scrolled not by scroll action // keep focus return; } if (validAccessibilityFocus) { // focused on valid node and scrolled by scroll action // focus on next focusable node if (source == null) { source = record.getSource(); if (source == null) return; } if (!AccessibilityNodeInfoUtils.hasAncestor(accessibilityFocused, source)) { return; } TraversalStrategy traversal = new OrderedTraversalStrategy(root); try { focusNextFocusedNode(traversal, accessibilityFocused, movingDirection); } finally { traversal.recycle(); } } else { if (mLastFocusedItem == null) { // there was no focus - don't set focus return; } if (source == null) { source = record.getSource(); if (source == null) return; } if (mLastFocusedItem.equals(source) || AccessibilityNodeInfoUtils.hasAncestor(mLastFocusedItem, source)) { // There is no focus now, but it was on source node's child before // Try focusing the appropriate child node. if (tryFocusingChild(source, movingDirection)) { return; } // Finally, try focusing the scrollable node itself. tryFocusing(source); } } } finally { AccessibilityNodeInfoUtils.recycleNodes(root, accessibilityFocused); } }
From source file:com.android.talkback.eventprocessor.ProcessorFocusAndSingleTap.java
private void followScrollEvent(AccessibilityNodeInfoCompat source, AccessibilityRecordCompat record, @TraversalStrategy.SearchDirectionOrUnknown int direction, boolean wasScrollAction) { // SEARCH_FOCUS_UNKNOWN can be passed, so need to guarantee that direction is a // @TraversalStrategy.SearchDirection before continuing. if (direction == TraversalStrategy.SEARCH_FOCUS_UNKNOWN) { return;/* www . j a va 2 s . c o m*/ } AccessibilityNodeInfoCompat root = null; AccessibilityNodeInfoCompat accessibilityFocused = null; try { // First, see if we've already placed accessibility focus. root = AccessibilityServiceCompatUtils.getRootInAccessibilityFocusedWindow(mService); if (root == null) { return; } accessibilityFocused = root.findFocus(AccessibilityNodeInfo.FOCUS_ACCESSIBILITY); boolean validAccessibilityFocus = AccessibilityNodeInfoUtils.shouldFocusNode(accessibilityFocused); // there are cases when scrollable container was scrolled and application set // focus on node that is on new container page. We should keep this focus boolean hasInputFocus = accessibilityFocused != null && accessibilityFocused.isFocused(); if (validAccessibilityFocus && (hasInputFocus || !wasScrollAction)) { // focused on valid node and scrolled not by scroll action // keep focus return; } if (validAccessibilityFocus) { // focused on valid node and scrolled by scroll action // focus on next focusable node if (source == null) { source = record.getSource(); if (source == null) return; } if (!AccessibilityNodeInfoUtils.hasAncestor(accessibilityFocused, source)) { return; } TraversalStrategy traversal = TraversalStrategyUtils.getTraversalStrategy(root, direction); try { focusNextFocusedNode(traversal, accessibilityFocused, direction); } finally { traversal.recycle(); } } else { if (mLastFocusedItem == null) { // there was no focus - don't set focus return; } if (source == null) { source = record.getSource(); if (source == null) return; } if (mLastFocusedItem.equals(source) || AccessibilityNodeInfoUtils.hasAncestor(mLastFocusedItem, source)) { // There is no focus now, but it was on source node's child before // Try focusing the appropriate child node. if (tryFocusingChild(source, direction)) { return; } // Finally, try focusing the scrollable node itself. tryFocusing(source); } } } finally { AccessibilityNodeInfoUtils.recycleNodes(root, accessibilityFocused); } }
From source file:com.googlecode.eyesfree.brailleback.IMENavigationModeTest.java
/** * Tests that text and navigation mode is not triggered when the input view * is not shown, even if input is started. This distinction is needed to * handle Chrome correctly.// ww w . ja va2s .co m */ public void testTextAndNavigationModeRequiresStartInputView() { EditorInfo ei = new EditorInfo(); // Mock out the AccessibilityNodeInfo. // The class actually uses the compat variant, but on recent API // releases (including the test environment) they should call through. AccessibilityNodeInfo rawNode = mock(AccessibilityNodeInfo.class); when(mAccessibilityService.getRootInActiveWindow()).thenReturn(rawNode); when(rawNode.findFocus(AccessibilityNodeInfo.FOCUS_INPUT)).thenReturn(rawNode); when(rawNode.findFocus(AccessibilityNodeInfo.FOCUS_ACCESSIBILITY)).thenReturn(rawNode); when(rawNode.getClassName()).thenReturn("com.example.ExampleWebView"); when(mSelfBrailleManager.hasContentForNode(compatWrapperForNode(rawNode))).thenReturn(true); mIMENavMode.onActivate(); mIMENavMode.onCreateIME(); verify(mNext).onActivate(); mIMENavMode.onBindInput(); mIMENavMode.onStartInput(ei, false /* restarting */); assertEquals(mBrailleTranslator, mIMENavMode.getBrailleTranslator()); assertNull(mIMENavMode.getDisplayManager()); assertEquals(mFeedbackManager, mIMENavMode.getFeedbackManager()); verify(mSelfBrailleManager, atLeastOnce()).setImeOpen(false); AccessibilityEvent accessibilityEvent = AccessibilityEvent.obtain(); try { mIMENavMode.onObserveAccessibilityEvent(accessibilityEvent); verify(mNext).onObserveAccessibilityEvent(accessibilityEvent); } finally { accessibilityEvent.recycle(); } accessibilityEvent = AccessibilityEvent.obtain(); try { mIMENavMode.onAccessibilityEvent(accessibilityEvent); verify(mNext).onAccessibilityEvent(accessibilityEvent); } finally { accessibilityEvent.recycle(); } AccessibilityNodeInfoCompat node = AccessibilityNodeInfoCompat.obtain(); try { mIMENavMode.onInvalidateAccessibilityNode(node); verify(mNext).onInvalidateAccessibilityNode(node); } finally { node.recycle(); } DisplayManager.Content content = new DisplayManager.Content(""); mIMENavMode.onPanLeftOverflow(content); verify(mNext).onPanLeftOverflow(content); mIMENavMode.onPanRightOverflow(content); verify(mNext).onPanRightOverflow(content); BrailleInputEvent inputEvent = new BrailleInputEvent(BrailleInputEvent.CMD_KEY_ENTER, 0, 0); mIMENavMode.onMappedInputEvent(inputEvent, content); verify(mNext, never()).onMappedInputEvent(inputEvent, content); verify(mIME).sendAndroidKey(KeyEvent.KEYCODE_ENTER); inputEvent = new BrailleInputEvent(BrailleInputEvent.CMD_KEY_DEL, 0, 0); mIMENavMode.onMappedInputEvent(inputEvent, content); verify(mNext, never()).onMappedInputEvent(inputEvent, content); verify(mIME).sendAndroidKey(KeyEvent.KEYCODE_DEL); inputEvent = new BrailleInputEvent(BrailleInputEvent.CMD_BRAILLE_KEY, 0x1b, 0); mIMENavMode.onMappedInputEvent(inputEvent, content); verify(mNext, never()).onMappedInputEvent(inputEvent, content); verify(mIME).handleBrailleKey(0x1b); inputEvent = new BrailleInputEvent(BrailleInputEvent.CMD_NAV_ITEM_NEXT, 0, 0); mIMENavMode.onMappedInputEvent(inputEvent, content); verify(mNext).onMappedInputEvent(inputEvent, content); verify(mIME, never()).moveCursor(anyInt(), anyInt()); inputEvent = new BrailleInputEvent(BrailleInputEvent.CMD_ACTIVATE_CURRENT, 0, 0); mIMENavMode.onMappedInputEvent(inputEvent, content); verify(mNext).onMappedInputEvent(inputEvent, content); verify(mIME, never()).sendDefaultAction(); inputEvent = new BrailleInputEvent(BrailleInputEvent.CMD_ROUTE, 0, 0); mIMENavMode.onMappedInputEvent(inputEvent, content); verify(mNext).onMappedInputEvent(inputEvent, content); verify(mIME, never()).route(anyInt(), any(DisplayManager.Content.class)); mIMENavMode.onFinishInput(); mIMENavMode.onUnbindInput(); mIMENavMode.onDestroyIME(); verify(mSelfBrailleManager, never()).setImeOpen(true); // Deactivate, but make sure it didn't happen too early. verify(mNext, never()).onDeactivate(); mIMENavMode.onDeactivate(); verify(mNext).onDeactivate(); }
From source file:com.google.android.marvin.mytalkback.ProcessorFocusAndSingleTap.java
private boolean followScrollEvent(AccessibilityNodeInfoCompat source, boolean isMovingForward, boolean wasScrollAction) { AccessibilityNodeInfoCompat root = null; AccessibilityNodeInfoCompat focused = null; try {/*from w w w. j ava 2 s. c om*/ // First, see if we've already placed accessibility focus. root = AccessibilityServiceCompatUtils.getRootInActiveWindow(mService); if (root == null) { return false; } focused = root.findFocus(AccessibilityNodeInfo.FOCUS_ACCESSIBILITY); if (focused != null) { // If a node already has focus, ensure it should still have // focus. Return immediately if it's correctly focused and this // event is not the result a scroll action OR we successfully // refocus the node. if (AccessibilityNodeInfoUtils.shouldFocusNode(mService, focused) && (!wasScrollAction || mCursorController.refocus())) { return true; } LogUtils.log(this, Log.DEBUG, "Clear focus from %s", focused); focused.performAction(AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS); } // Try focusing the appropriate child node. if (tryFocusingChild(source, isMovingForward)) { return true; } // Finally, try focusing the scrollable node itself. if (tryFocusing(source)) { return true; } return false; } finally { AccessibilityNodeInfoUtils.recycleNodes(root, focused); } }
From source file:com.android.screenspeak.eventprocessor.ProcessorFocusAndSingleTap.java
/** * @param record the AccessbilityRecord for the event * @param isViewFocusedEvent true if the event is TYPE_VIEW_FOCUSED, otherwise it is * TYPE_VIEW_SELECTED./*from w w w . j a v a 2s.c om*/ */ private boolean setFocusOnView(AccessibilityRecordCompat record, boolean isViewFocusedEvent) { AccessibilityNodeInfoCompat source = null; AccessibilityNodeInfoCompat existing = null; AccessibilityNodeInfoCompat child = null; try { source = record.getSource(); if (source == null) { return false; } if (record.getItemCount() > 0) { final int index = (record.getCurrentItemIndex() - record.getFromIndex()); if (index >= 0 && index < source.getChildCount()) { child = source.getChild(index); if (child != null) { if (AccessibilityNodeInfoUtils.isTopLevelScrollItem(child) && tryFocusing(child)) { return true; } } } } if (!isViewFocusedEvent) { return false; } // Logic below is only specific to TYPE_VIEW_FOCUSED event // Try focusing the source node. if (tryFocusing(source)) { return true; } // If we fail and the source node already contains focus, abort. existing = source.findFocus(AccessibilityNodeInfo.FOCUS_ACCESSIBILITY); if (existing != null) { return false; } // If we fail to focus a node, perhaps because it is a focusable // but non-speaking container, we should still attempt to place // focus on a speaking child within the container. child = AccessibilityNodeInfoUtils.searchFromBfs(source, AccessibilityNodeInfoUtils.FILTER_SHOULD_FOCUS); return child != null && tryFocusing(child); } finally { AccessibilityNodeInfoUtils.recycleNodes(source, existing, child); } }
From source file:com.googlecode.eyesfree.brailleback.IMENavigationModeTest.java
/** * Tests the behaviour of the "text and navigation" mode. */// w ww . java 2s. c om public void testTextAndNavigationMode() { EditorInfo ei = new EditorInfo(); // Mock out the AccessibilityNodeInfo. // The class actually uses the compat variant, but on recent API // releases (including the test environment) they should call through. AccessibilityNodeInfo rawNode = mock(AccessibilityNodeInfo.class); when(mAccessibilityService.getRootInActiveWindow()).thenReturn(rawNode); when(rawNode.findFocus(AccessibilityNodeInfo.FOCUS_INPUT)).thenReturn(rawNode); when(rawNode.findFocus(AccessibilityNodeInfo.FOCUS_ACCESSIBILITY)).thenReturn(rawNode); when(rawNode.getClassName()).thenReturn("com.example.ExampleWebView"); when(mSelfBrailleManager.hasContentForNode(compatWrapperForNode(rawNode))).thenReturn(true); mIMENavMode.onActivate(); mIMENavMode.onCreateIME(); verify(mNext).onActivate(); mIMENavMode.onBindInput(); mIMENavMode.onStartInput(ei, false /* restarting */); verify(mSelfBrailleManager, atLeastOnce()).setImeOpen(false); verify(mSelfBrailleManager, never()).setImeOpen(true); mIMENavMode.onStartInputView(ei, false /* restarting */); assertEquals(mBrailleTranslator, mIMENavMode.getBrailleTranslator()); assertNull(mIMENavMode.getDisplayManager()); assertEquals(mFeedbackManager, mIMENavMode.getFeedbackManager()); verify(mSelfBrailleManager, atLeastOnce()).setImeOpen(true); AccessibilityEvent accessibilityEvent = AccessibilityEvent.obtain(); try { mIMENavMode.onObserveAccessibilityEvent(accessibilityEvent); verify(mNext).onObserveAccessibilityEvent(accessibilityEvent); } finally { accessibilityEvent.recycle(); } accessibilityEvent = AccessibilityEvent.obtain(); try { mIMENavMode.onAccessibilityEvent(accessibilityEvent); verify(mNext).onAccessibilityEvent(accessibilityEvent); } finally { accessibilityEvent.recycle(); } AccessibilityNodeInfoCompat node = AccessibilityNodeInfoCompat.obtain(); try { mIMENavMode.onInvalidateAccessibilityNode(node); verify(mNext).onInvalidateAccessibilityNode(node); } finally { node.recycle(); } DisplayManager.Content content = new DisplayManager.Content(""); mIMENavMode.onPanLeftOverflow(content); verify(mNext).onPanLeftOverflow(content); mIMENavMode.onPanRightOverflow(content); verify(mNext).onPanRightOverflow(content); BrailleInputEvent inputEvent = new BrailleInputEvent(BrailleInputEvent.CMD_KEY_ENTER, 0, 0); mIMENavMode.onMappedInputEvent(inputEvent, content); verify(mNext, never()).onMappedInputEvent(inputEvent, content); verify(mIME).sendAndroidKey(KeyEvent.KEYCODE_ENTER); inputEvent = new BrailleInputEvent(BrailleInputEvent.CMD_KEY_DEL, 0, 0); mIMENavMode.onMappedInputEvent(inputEvent, content); verify(mNext, never()).onMappedInputEvent(inputEvent, content); verify(mIME).sendAndroidKey(KeyEvent.KEYCODE_DEL); inputEvent = new BrailleInputEvent(BrailleInputEvent.CMD_BRAILLE_KEY, 0x1b, 0); mIMENavMode.onMappedInputEvent(inputEvent, content); verify(mNext, never()).onMappedInputEvent(inputEvent, content); verify(mIME).handleBrailleKey(0x1b); inputEvent = new BrailleInputEvent(BrailleInputEvent.CMD_ACTIVATE_CURRENT, 0, 0); mIMENavMode.onMappedInputEvent(inputEvent, content); verify(mNext).onMappedInputEvent(inputEvent, content); verify(mIME, never()).sendDefaultAction(); inputEvent = new BrailleInputEvent(BrailleInputEvent.CMD_ROUTE, 0, 0); mIMENavMode.onMappedInputEvent(inputEvent, content); verify(mNext).onMappedInputEvent(inputEvent, content); verify(mIME, never()).route(anyInt(), any(DisplayManager.Content.class)); // Nothing above this point should have triggered an action on the // accessibility node. verify(rawNode, never()).performAction(anyInt(), any(Bundle.class)); verifyEventCausesNavigation(BrailleInputEvent.CMD_NAV_ITEM_NEXT, ACTION_NEXT_AT_MOVEMENT_GRANULARITY, MOVEMENT_GRANULARITY_CHARACTER, rawNode, content); verifyEventCausesNavigation(BrailleInputEvent.CMD_NAV_ITEM_PREVIOUS, ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, MOVEMENT_GRANULARITY_CHARACTER, rawNode, content); verifyEventCausesNavigation(BrailleInputEvent.CMD_NAV_LINE_NEXT, ACTION_NEXT_AT_MOVEMENT_GRANULARITY, MOVEMENT_GRANULARITY_LINE, rawNode, content); verifyEventCausesNavigation(BrailleInputEvent.CMD_NAV_LINE_PREVIOUS, ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, MOVEMENT_GRANULARITY_LINE, rawNode, content); Mockito.reset(mSelfBrailleManager); mIMENavMode.onFinishInputView(true); verify(mSelfBrailleManager).setImeOpen(false); mIMENavMode.onFinishInput(); mIMENavMode.onUnbindInput(); mIMENavMode.onDestroyIME(); verify(mSelfBrailleManager, never()).setImeOpen(true); // Deactivate, but make sure it didn't happen too early. verify(mNext, never()).onDeactivate(); mIMENavMode.onDeactivate(); verify(mNext).onDeactivate(); }
From source file:com.android.screenspeak.eventprocessor.ProcessorFocusAndSingleTap.java
/** * Attempts to place focus within a new window. *//* w w w. ja v a2s .co m*/ private boolean ensureFocusConsistency() { AccessibilityNodeInfoCompat root = null; AccessibilityNodeInfoCompat focused = null; try { root = AccessibilityServiceCompatUtils.getRootInAccessibilityFocusedWindow(mService); if (root == null) { return false; } // First, see if we've already placed accessibility focus. focused = root.findFocus(AccessibilityNodeInfo.FOCUS_ACCESSIBILITY); if (focused != null) { if (AccessibilityNodeInfoUtils.shouldFocusNode(focused)) { return true; } LogUtils.log(Log.VERBOSE, "Clearing focus from invalid node"); PerformActionUtils.performAction(focused, AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS); } return false; } finally { AccessibilityNodeInfoUtils.recycleNodes(root, focused); } }
From source file:com.googlecode.eyesfree.brailleback.IMENavigationModeTest.java
/** * Tests the behaviour of the "modal editor" mode. *//*from w ww .ja v a 2 s. com*/ public void testModalEditorMode() { mIMENavMode.onActivate(); verify(mNext).onActivate(); EditorInfo ei = new EditorInfo(); // Mock out the AccessibilityNodeInfo. // The class actually uses the compat variant, but on recent API // releases (including the test environment) they should call through. AccessibilityNodeInfo rawNode = mock(AccessibilityNodeInfo.class); when(mAccessibilityService.getRootInActiveWindow()).thenReturn(rawNode); when(rawNode.findFocus(AccessibilityNodeInfo.FOCUS_ACCESSIBILITY)).thenReturn(rawNode); when(rawNode.getClassName()).thenReturn(EditText.class.getName()); when(rawNode.isFocused()).thenReturn(true); mIMENavMode.onCreateIME(); mIMENavMode.onBindInput(); mIMENavMode.onStartInput(ei, false /* restarting */); mIMENavMode.onStartInputView(ei, false /* restarting */); verify(mNext, times(1)).onDeactivate(); assertEquals(mBrailleTranslator, mIMENavMode.getBrailleTranslator()); assertEquals(mDisplayManager, mIMENavMode.getDisplayManager()); assertEquals(mFeedbackManager, mIMENavMode.getFeedbackManager()); AccessibilityEvent accessibilityEvent = AccessibilityEvent.obtain(); try { mIMENavMode.onObserveAccessibilityEvent(accessibilityEvent); verify(mNext).onObserveAccessibilityEvent(accessibilityEvent); } finally { accessibilityEvent.recycle(); } accessibilityEvent = AccessibilityEvent.obtain(); try { mIMENavMode.onAccessibilityEvent(accessibilityEvent); verify(mNext, never()).onAccessibilityEvent(accessibilityEvent); } finally { accessibilityEvent.recycle(); } AccessibilityNodeInfoCompat node = AccessibilityNodeInfoCompat.obtain(); try { mIMENavMode.onInvalidateAccessibilityNode(node); verify(mNext, never()).onInvalidateAccessibilityNode(node); } finally { node.recycle(); } // Move input focus away and back again. when(rawNode.isFocused()).thenReturn(false); accessibilityEvent = AccessibilityEvent.obtain(); accessibilityEvent.setEventType(AccessibilityEvent.TYPE_VIEW_FOCUSED); try { mIMENavMode.onObserveAccessibilityEvent(accessibilityEvent); verify(mNext, times(2)).onActivate(); when(rawNode.isFocused()).thenReturn(true); mIMENavMode.onObserveAccessibilityEvent(accessibilityEvent); verify(mNext, times(2)).onDeactivate(); } finally { accessibilityEvent.recycle(); } DisplayManager.Content content = new DisplayManager.Content(""); mIMENavMode.onPanLeftOverflow(content); verify(mNext).onPanLeftOverflow(content); mIMENavMode.onPanRightOverflow(content); verify(mNext).onPanRightOverflow(content); BrailleInputEvent inputEvent = new BrailleInputEvent(BrailleInputEvent.CMD_KEY_ENTER, 0, 0); mIMENavMode.onMappedInputEvent(inputEvent, content); verify(mNext, never()).onMappedInputEvent(inputEvent, content); verify(mIME).sendAndroidKey(KeyEvent.KEYCODE_ENTER); inputEvent = new BrailleInputEvent(BrailleInputEvent.CMD_KEY_DEL, 0, 0); mIMENavMode.onMappedInputEvent(inputEvent, content); verify(mNext, never()).onMappedInputEvent(inputEvent, content); verify(mIME).sendAndroidKey(KeyEvent.KEYCODE_DEL); inputEvent = new BrailleInputEvent(BrailleInputEvent.CMD_BRAILLE_KEY, 0x1b, 0); mIMENavMode.onMappedInputEvent(inputEvent, content); verify(mNext, never()).onMappedInputEvent(inputEvent, content); verify(mIME).handleBrailleKey(0x1b); inputEvent = new BrailleInputEvent(BrailleInputEvent.CMD_NAV_ITEM_NEXT, 0, 0); mIMENavMode.onMappedInputEvent(inputEvent, content); verify(mNext, never()).onMappedInputEvent(inputEvent, content); verify(mIME).moveCursor(BrailleIME.DIRECTION_FORWARD, AccessibilityNodeInfoCompat.MOVEMENT_GRANULARITY_CHARACTER); inputEvent = new BrailleInputEvent(BrailleInputEvent.CMD_ACTIVATE_CURRENT, 0, 0); mIMENavMode.onMappedInputEvent(inputEvent, content); verify(mNext, never()).onMappedInputEvent(inputEvent, content); verify(mIME).sendDefaultAction(); inputEvent = new BrailleInputEvent(BrailleInputEvent.CMD_ROUTE, 0, 0); mIMENavMode.onMappedInputEvent(inputEvent, content); verify(mNext, never()).onMappedInputEvent(inputEvent, content); verify(mIME).route(0, content); // Finishing and unbinding the input should activate the next nav mode // again. mIMENavMode.onFinishInputView(true); mIMENavMode.onFinishInput(); mIMENavMode.onUnbindInput(); verify(mNext, times(3)).onActivate(); mIMENavMode.onDestroyIME(); // Deactivate, but make sure it didn't happen too early. verify(mNext, times(2)).onDeactivate(); mIMENavMode.onDeactivate(); verify(mNext, times(3)).onDeactivate(); }