1 // Copyright 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 package org.chromium.android_webview; 6 7 import android.os.Handler; 8 import android.os.Message; 9 import android.view.View; 10 import android.view.accessibility.AccessibilityEvent; 11 12 /** 13 * Helper used to post the VIEW_SCROLLED accessibility event. 14 * 15 * TODO(mkosiba): Investigate whether this is behavior we want to share with the chrome/ layer. 16 * TODO(mkosiba): We currently don't handle JS-initiated scrolling for layers other than the root 17 * layer. 18 */ 19 class ScrollAccessibilityHelper { 20 // This is copied straight out of android.view.ViewConfiguration. 21 private static final long SEND_RECURRING_ACCESSIBILITY_EVENTS_INTERVAL_MILLIS = 100; 22 23 private class HandlerCallback implements Handler.Callback { 24 public static final int MSG_VIEW_SCROLLED = 1; 25 26 private View mEventSender; 27 HandlerCallback(View eventSender)28 public HandlerCallback(View eventSender) { 29 mEventSender = eventSender; 30 } 31 32 @Override handleMessage(Message msg)33 public boolean handleMessage(Message msg) { 34 switch(msg.what) { 35 case MSG_VIEW_SCROLLED: 36 mMsgViewScrolledQueued = false; 37 mEventSender.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SCROLLED); 38 break; 39 default: 40 throw new IllegalStateException( 41 "AccessibilityInjector: unhandled message: " + msg.what); 42 } 43 return true; 44 } 45 } 46 47 private Handler mHandler; 48 private boolean mMsgViewScrolledQueued; 49 ScrollAccessibilityHelper(View eventSender)50 public ScrollAccessibilityHelper(View eventSender) { 51 mHandler = new Handler(new HandlerCallback(eventSender)); 52 } 53 54 /** 55 * Post a callback to send a {@link AccessibilityEvent#TYPE_VIEW_SCROLLED} event. 56 * This event is sent at most once every 57 * {@link android.view.ViewConfiguration#getSendRecurringAccessibilityEventsInterval()} 58 */ postViewScrolledAccessibilityEventCallback()59 public void postViewScrolledAccessibilityEventCallback() { 60 if (mMsgViewScrolledQueued) 61 return; 62 mMsgViewScrolledQueued = true; 63 64 Message msg = mHandler.obtainMessage(HandlerCallback.MSG_VIEW_SCROLLED); 65 mHandler.sendMessageDelayed(msg, SEND_RECURRING_ACCESSIBILITY_EVENTS_INTERVAL_MILLIS); 66 } 67 removePostedViewScrolledAccessibilityEventCallback()68 public void removePostedViewScrolledAccessibilityEventCallback() { 69 if (!mMsgViewScrolledQueued) 70 return; 71 mMsgViewScrolledQueued = false; 72 73 mHandler.removeMessages(HandlerCallback.MSG_VIEW_SCROLLED); 74 } 75 removePostedCallbacks()76 public void removePostedCallbacks() { 77 removePostedViewScrolledAccessibilityEventCallback(); 78 } 79 } 80