List of usage examples for android.view.accessibility AccessibilityEvent getEventTime
public long getEventTime()
From source file:com.android.screenspeak.eventprocessor.ProcessorEventQueue.java
/** * Computes the queuing mode for the current utterance. * * @param utterance to compute queuing from * @return A queuing mode, one of:/*from w w w . j a v a 2 s . c o m*/ * <ul> * <li>{@link SpeechController#QUEUE_MODE_INTERRUPT} * <li>{@link SpeechController#QUEUE_MODE_QUEUE} * <li>{@link SpeechController#QUEUE_MODE_UNINTERRUPTIBLE} * </ul> */ private int computeQueuingMode(Utterance utterance, AccessibilityEvent event) { final Bundle metadata = utterance.getMetadata(); final int eventType = event.getEventType(); // Queue events that occur automatically after window state changes. if (((event.getEventType() & AccessibilityEventProcessor.AUTOMATIC_AFTER_STATE_CHANGE) != 0) && ((event.getEventTime() - mLastWindowStateChanged) < AccessibilityEventProcessor.DELAY_AUTO_AFTER_STATE)) { return SpeechController.QUEUE_MODE_QUEUE; } if (eventType == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED) { AccessibilityRecordCompat record = AccessibilityEventCompat.asRecord(event); AccessibilityNodeInfoCompat node = record.getSource(); if (node != null) { int liveRegionMode = node.getLiveRegion(); if (liveRegionMode == View.ACCESSIBILITY_LIVE_REGION_POLITE) { return SpeechController.QUEUE_MODE_QUEUE; } } } int queueMode = metadata.getInt(Utterance.KEY_METADATA_QUEUING, SpeechController.QUEUE_MODE_INTERRUPT); // Always collapse events of the same type. if (mLastEventType == eventType && queueMode != SpeechController.QUEUE_MODE_UNINTERRUPTIBLE) { return SpeechController.QUEUE_MODE_INTERRUPT; } mLastEventType = eventType; return queueMode; }
From source file:com.android.talkback.eventprocessor.AccessibilityEventProcessor.java
/** * Helper method for {@link #shouldDropEvent} that filters out selected events that occur * in close proximity to focused events. * * A selected event should be kept if:/*from w ww . ja va2 s. co m*/ * - The most recent focused event occurred over {@link #DELAY_SELECTED_AFTER_FOCUS} ms ago. * - The most recent focused event occurred on a different branch of the accessibility node * tree, i.e., not in an ancestor or descendant of the selected event. * * @param event The view-selected event to consider retaining. * @return Whether to retain the event. */ private boolean shouldKeepViewSelectedEvent(final AccessibilityEvent event) { if (mLastFocusedEvent == null) { return true; } if (event.getEventTime() - mLastFocusedEvent.getEventTime() > DELAY_SELECTED_AFTER_FOCUS) { return true; } // AccessibilityEvent.getSource will obtain() an AccessibilityNodeInfo, so it is our // responsibility to recycle() it. AccessibilityNodeInfo selectedSource = event.getSource(); AccessibilityNodeInfo focusedSource = mLastFocusedEvent.getSource(); try { // Note: AccessibilityNodeInfoCompat constructor will silently succeed when wrapping // a null object. if (selectedSource != null && focusedSource != null) { AccessibilityNodeInfoCompat selectedSourceCompat = new AccessibilityNodeInfoCompat(selectedSource); AccessibilityNodeInfoCompat focusedSourceCompat = new AccessibilityNodeInfoCompat(focusedSource); if (AccessibilityNodeInfoUtils.areInSameBranch(selectedSourceCompat, focusedSourceCompat)) { return false; } } // In different branch (or we could not check branches of accessibility node tree). return true; } finally { if (selectedSource != null) { selectedSource.recycle(); } if (focusedSource != null) { focusedSource.recycle(); } } }
From source file:com.google.android.marvin.mytalkback.ProcessorFocusAndSingleTap.java
private void handleWindowStateChange(AccessibilityEvent event) { mLastWindowStateChangedEvent = event.getEventTime(); // Invalidate scrolling information. if (mLastScrollSource != null) { mLastScrollSource.recycle();/*w ww. java 2 s . co m*/ mLastScrollSource = null; } mLastScrollAction = 0; mLastScrollFromIndex = -1; mLastScrollToIndex = -1; // Since we may get WINDOW_STATE_CHANGE events from the keyboard even // though the active window is still another app, only clear focus if // the event's window ID matches the cursor's window ID. final AccessibilityNodeInfoCompat cursor = mCursorController.getCursor(); if ((cursor != null) && (cursor.getWindowId() == event.getWindowId())) { mCursorController.clearCursor(); } AccessibilityNodeInfoUtils.recycleNodes(cursor); }
From source file:com.google.android.marvin.mytalkback.ProcessorFocusAndSingleTap.java
private boolean shouldDropFocusEvent(AccessibilityEvent event, AccessibilityNodeInfoCompat node) { final long eventTime = event.getEventTime(); return ((eventTime - mLastViewScrolledEvent) < TIMEOUT_VIEW_SCROLLED) || ((eventTime - mLastWindowStateChangedEvent) < TIMEOUT_WINDOW_STATE_CHANGED); }
From source file:com.google.android.marvin.mytalkback.ProcessorFocusAndSingleTap.java
private void handleViewScrolled(AccessibilityEvent event, AccessibilityRecordCompat record) { mLastViewScrolledEvent = event.getEventTime(); final AccessibilityNodeInfoCompat source = record.getSource(); if (source == null) { LogUtils.log(this, Log.ERROR, "Drop scroll with no source node"); return;//from w w w. jav a 2 s . c om } // Only move focus if we've already seen the source. if (source.equals(mLastScrollSource)) { final boolean isMovingForward = (mLastScrollAction == AccessibilityNodeInfo.ACTION_SCROLL_FORWARD) || (event.getFromIndex() > mLastScrollFromIndex) || (event.getToIndex() > mLastScrollToIndex); final boolean wasScrollAction = (mLastScrollAction != 0); mHandler.followScrollDelayed(source, isMovingForward, wasScrollAction); // Performing a scroll action results in smooth scrolling, which may // send multiple events spaced at least 100ms apart. mHandler.clearScrollActionDelayed(); } else { setScrollActionImmediately(0); } if (mLastScrollSource != null) { mLastScrollSource.recycle(); } mLastScrollSource = source; mLastScrollFromIndex = record.getFromIndex(); mLastScrollToIndex = record.getToIndex(); }
From source file:com.android.talkback.eventprocessor.ProcessorFocusAndSingleTap.java
public boolean isFromRefocusAction(AccessibilityEvent event) { long eventTime = event.getEventTime(); int eventType = event.getEventType(); if (eventType != AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED && eventType != AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED) { return false; }//from w ww.j a va2 s. c om AccessibilityNodeInfo source = event.getSource(); try { return mLastRefocusStartTime < eventTime && (mLastRefocusEndTime > eventTime || mLastRefocusEndTime < mLastRefocusStartTime) && mLastRefocusedNode != null && mLastRefocusedNode.getInfo().equals(source); } finally { if (source != null) { source.recycle(); } } }
From source file:com.android.screenspeak.eventprocessor.AccessibilityEventProcessor.java
/** * Returns whether the device should drop this event. Caches notifications * if necessary.//from w w w .j av a 2 s . c o m * * @param event The current event. * @return {@code true} if the event should be dropped. */ private boolean shouldDropEvent(AccessibilityEvent event) { // Always drop null events. if (event == null) { return true; } // Always drop events if the service is suspended. if (!ScreenSpeakService.isServiceActive()) { return true; } // If touch exploration is enabled, drop automatically generated events // that are sent immediately after a window state change... unless we // decide to keep the event. if (AccessibilityManagerCompat.isTouchExplorationEnabled(mAccessibilityManager) && ((event.getEventType() & AUTOMATIC_AFTER_STATE_CHANGE) != 0) && ((event.getEventTime() - mLastWindowStateChanged) < DELAY_AUTO_AFTER_STATE) && !shouldKeepAutomaticEvent(event)) { if (LogUtils.LOG_LEVEL <= Log.VERBOSE) { Log.v(LOGTAG, "Drop event after window state change"); } return true; } // Real notification events always have parcelable data. final boolean isNotification = (event.getEventType() == AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED) && (event.getParcelableData() != null); final boolean isPhoneActive = (mCallStateMonitor != null) && (mCallStateMonitor.getCurrentCallState() != TelephonyManager.CALL_STATE_IDLE); final boolean shouldSpeakCallerId = (mSpeakCallerId && (mCallStateMonitor != null) && (mCallStateMonitor.getCurrentCallState() == TelephonyManager.CALL_STATE_RINGING)); if (mRingerModeAndScreenMonitor != null && !mRingerModeAndScreenMonitor.isScreenOn() && !shouldSpeakCallerId) { if (!mSpeakWhenScreenOff) { // If the user doesn't allow speech when the screen is // off, drop the event immediately. if (LogUtils.LOG_LEVEL <= Log.VERBOSE) { Log.v(LOGTAG, "Drop event due to screen state and user pref"); } return true; } else if (!isNotification) { // If the user allows speech when the screen is off, drop // all non-notification events. if (LogUtils.LOG_LEVEL <= Log.VERBOSE) { Log.v(LOGTAG, "Drop non-notification event due to screen state"); } return true; } } final boolean canInterruptRadialMenu = AccessibilityEventUtils.eventMatchesAnyType(event, MASK_EVENT_TYPES_INTERRUPT_RADIAL_MENU); final boolean silencedByRadialMenu = (mService.getMenuManager().isMenuShowing() && !canInterruptRadialMenu); // Don't speak events that cannot interrupt the radial menu, if showing if (silencedByRadialMenu) { if (LogUtils.LOG_LEVEL <= Log.VERBOSE) { Log.v(LOGTAG, "Drop event due to radial menu state"); } return true; } // Don't speak notification events if the user is touch exploring or a phone call is active. if (isNotification && (mIsUserTouchExploring || isPhoneActive)) { if (LogUtils.LOG_LEVEL <= Log.VERBOSE) { Log.v(LOGTAG, "Drop notification due to touch or phone state"); } return true; } final int touchscreenState = mService.getResources().getConfiguration().touchscreen; final boolean isTouchInteractionStateChange = AccessibilityEventUtils.eventMatchesAnyType(event, MASK_EVENT_TYPES_TOUCH_STATE_CHANGES); // Drop all events related to touch interaction state on devices that don't support touch. return (touchscreenState == Configuration.TOUCHSCREEN_NOTOUCH) && isTouchInteractionStateChange; }
From source file:com.ucmap.dingdinghelper.services.DingDingHelperAccessibilityService.java
/** * ???//from www . j a v a 2s . c o m */ @RequiresApi(api = Build.VERSION_CODES.KITKAT) @Override public void onAccessibilityEvent(AccessibilityEvent event) { tag_callback_time = System.currentTimeMillis(); int eventType = event.getEventType(); Log.i("Info", " eventType: " + eventType + " getEventTime: " + event.getEventTime() + " getAction" + event.getAction() + "getContentChangeTypes:" + event.getContentChangeTypes() + " getText :" + event.getText().toString() + "getPackageName :" + event.getPackageName() + "getRecordCount : " + event.getRecordCount() + " getClassName:" + event.getClassName() + " :" + event.getClass() + " getParcelableData:" + event.getParcelableData()); switch (eventType) { /*??*/ case AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED: windowContentChanged(); break; //??? case AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED: notificationChanged(event); break; //Activity??? case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED: windowChanged(event); break; } }
From source file:com.android.talkback.eventprocessor.AccessibilityEventProcessor.java
/** * Returns whether the device should drop this event. Caches notifications * if necessary.// w w w . j av a 2 s .c om * * @param event The current event. * @return {@code true} if the event should be dropped. */ private boolean shouldDropEvent(AccessibilityEvent event) { // Always drop null events. if (event == null) { return true; } // Always drop events if the service is suspended. if (!TalkBackService.isServiceActive()) { return true; } // If touch exploration is enabled, drop automatically generated events // that are sent immediately after a window state change... unless we // decide to keep the event. if (AccessibilityManagerCompat.isTouchExplorationEnabled(mAccessibilityManager) && ((event.getEventType() & AUTOMATIC_AFTER_STATE_CHANGE) != 0) && ((event.getEventTime() - mLastWindowStateChanged) < DELAY_AUTO_AFTER_STATE) && !shouldKeepAutomaticEvent(event)) { if (LogUtils.LOG_LEVEL <= Log.VERBOSE) { Log.v(LOGTAG, "Drop event after window state change"); } return true; } // Some view-selected events are spurious if sent immediately after a focused event. if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_SELECTED && !shouldKeepViewSelectedEvent(event)) { if (LogUtils.LOG_LEVEL <= Log.VERBOSE) { Log.v(LOGTAG, "Drop selected event after focused event"); } return true; } // Real notification events always have parcelable data. final boolean isNotification = (event.getEventType() == AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED) && (event.getParcelableData() != null); final boolean isPhoneActive = (mCallStateMonitor != null) && (mCallStateMonitor.getCurrentCallState() != TelephonyManager.CALL_STATE_IDLE); final boolean isPhoneRinging = (mCallStateMonitor != null) && (mCallStateMonitor.getCurrentCallState() == TelephonyManager.CALL_STATE_RINGING); // Sometimes the dialer's window-state-changed event gets sent right before the // TelephonyManager transitions to CALL_STATE_RINGING, so we need to check isDialerEvent(). final boolean shouldSpeakCallerId = isPhoneRinging || isDialerEvent(event); if (mRingerModeAndScreenMonitor != null && !mRingerModeAndScreenMonitor.isScreenOn() && !shouldSpeakCallerId) { if (!mSpeakWhenScreenOff) { // If the user doesn't allow speech when the screen is // off, drop the event immediately. if (LogUtils.LOG_LEVEL <= Log.VERBOSE) { Log.v(LOGTAG, "Drop event due to screen state and user pref"); } return true; } else if (!isNotification) { // If the user allows speech when the screen is off, drop // all non-notification events. if (LogUtils.LOG_LEVEL <= Log.VERBOSE) { Log.v(LOGTAG, "Drop non-notification event due to screen state"); } return true; } } final boolean canInterruptRadialMenu = AccessibilityEventUtils.eventMatchesAnyType(event, MASK_EVENT_TYPES_INTERRUPT_RADIAL_MENU); final boolean silencedByRadialMenu = (mService.getMenuManager().isMenuShowing() && !canInterruptRadialMenu); // Don't speak events that cannot interrupt the radial menu, if showing if (silencedByRadialMenu) { if (LogUtils.LOG_LEVEL <= Log.VERBOSE) { Log.v(LOGTAG, "Drop event due to radial menu state"); } return true; } // Don't speak notification events if the user is touch exploring or a phone call is active. if (isNotification && (mIsUserTouchExploring || isPhoneActive)) { if (LogUtils.LOG_LEVEL <= Log.VERBOSE) { Log.v(LOGTAG, "Drop notification due to touch or phone state"); } return true; } final int touchscreenState = mService.getResources().getConfiguration().touchscreen; final boolean isTouchInteractionStateChange = AccessibilityEventUtils.eventMatchesAnyType(event, MASK_EVENT_TYPES_TOUCH_STATE_CHANGES); // Drop all events related to touch interaction state on devices that don't support touch. return (touchscreenState == Configuration.TOUCHSCREEN_NOTOUCH) && isTouchInteractionStateChange; }
From source file:Main.java
/** * @return If the <code>first</code> event is equal to the <code>second</code>. *///from w w w .j a v a 2 s . co m public static boolean eventEquals(AccessibilityEvent first, AccessibilityEvent second) { // TODO: The framework should implement AccessibilityEvent#equals() if (first == null || second == null) { return false; } if (first.getEventType() != second.getEventType()) { return false; } if (first.getPackageName() == null) { if (second.getPackageName() != null) { return false; } } else if (!first.getPackageName().equals(second.getPackageName())) { return false; } if (first.getClassName() == null) { if (second.getClassName() != null) { return false; } } else if (!first.getClassName().equals(second.getClassName())) { return false; } if (!first.getText().equals(second.getText())) { // The result of getText() is never null. return false; } if (first.getContentDescription() == null) { if (second.getContentDescription() != null) { return false; } } else if (!first.getContentDescription().equals(second.getContentDescription())) { return false; } if (first.getBeforeText() == null) { if (second.getBeforeText() != null) { return false; } } else if (!first.getBeforeText().equals(second.getBeforeText())) { return false; } if (first.getParcelableData() != null) { // Parcelable data may not implement equals() correctly. return false; } if (first.getAddedCount() != second.getAddedCount()) { return false; } if (first.isChecked() != second.isChecked()) { return false; } if (first.isEnabled() != second.isEnabled()) { return false; } if (first.getFromIndex() != second.getFromIndex()) { return false; } if (first.isFullScreen() != second.isFullScreen()) { return false; } if (first.getCurrentItemIndex() != second.getCurrentItemIndex()) { return false; } if (first.getItemCount() != second.getItemCount()) { return false; } if (first.isPassword() != second.isPassword()) { return false; } if (first.getRemovedCount() != second.getRemovedCount()) { return false; } if (first.getEventTime() != second.getEventTime()) { return false; } return true; }