/TalkBack/src/com/google/android/marvin/talkback/ProcessorScrollPosition.java
Java | 127 lines | 71 code | 22 blank | 34 comment | 10 complexity | de31af636d089e63f48cd2cb25ca1872 MD5 | raw file
1/* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 * use this file except in compliance with the License. You may obtain a copy of 6 * the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 * License for the specific language governing permissions and limitations under 14 * the License. 15 */ 16 17package com.google.android.marvin.talkback; 18 19import android.content.Context; 20import android.os.Handler; 21import android.os.Message; 22import android.speech.tts.TextToSpeech; 23import android.text.TextUtils; 24import android.view.accessibility.AccessibilityEvent; 25 26import com.google.android.marvin.talkback.TalkBackService.EventProcessor; 27 28class ProcessorScrollPosition implements EventProcessor { 29 private final Context mContext; 30 private final SpeechController mSpeechController; 31 private final ScrollPositionHandler mHandler; 32 33 public ProcessorScrollPosition(Context context, SpeechController speechController) { 34 mContext = context; 35 mSpeechController = speechController; 36 mHandler = new ScrollPositionHandler(); 37 } 38 39 @Override 40 public void process(AccessibilityEvent event) { 41 final int eventType = event.getEventType(); 42 43 mHandler.cancelScrollTimeout(); 44 45 if (eventType != AccessibilityEvent.TYPE_VIEW_SCROLLED) { 46 return; 47 } 48 49 final CharSequence text = Utils.getEventText(mContext, event); 50 51 if (!TextUtils.isEmpty(text)) { 52 return; 53 } 54 55 mHandler.startScrollTimeout(event); 56 } 57 58 /** 59 * Given an {@link AccessibilityEvent}, speaks a scroll position. 60 * 61 * @param event The source event. 62 */ 63 private void handleScrollTimeout(AccessibilityEvent event) { 64 final int fromIndex = event.getFromIndex() + 1; 65 final int toIndex = event.getToIndex() + 1; 66 final int itemCount = event.getItemCount(); 67 68 // If the from index or the item count are invalid, don't announce 69 // anything. 70 if (fromIndex < 0 || itemCount < 0) { 71 return; 72 } 73 74 final String text; 75 76 // If the from and to indices are the same, or if the to index is 77 // invalid, only announce the item at the from index. Otherwise, 78 // announce the range of visible items. 79 if ((fromIndex == toIndex) || toIndex < 0) { 80 text = mContext.getString(R.string.template_scroll_from_count, fromIndex, itemCount); 81 } else { 82 text = 83 mContext.getString(R.string.template_scroll_from_to_count, fromIndex, toIndex, 84 itemCount); 85 } 86 87 mSpeechController.cleanUpAndSpeak(text, TextToSpeech.QUEUE_FLUSH); 88 } 89 90 private class ScrollPositionHandler extends Handler { 91 /** Message identifier for a scroll position notification. */ 92 private static final int SCROLL_TIMEOUT = 1; 93 94 /** Timeout before reading a scroll position notification. */ 95 private static final long DELAY_SCROLL_TIMEOUT = 1000; 96 97 @Override 98 public void handleMessage(Message msg) { 99 switch (msg.what) { 100 case SCROLL_TIMEOUT: { 101 final AccessibilityEvent event = (AccessibilityEvent) msg.obj; 102 handleScrollTimeout(event); 103 event.recycle(); 104 break; 105 } 106 } 107 } 108 109 /** 110 * Starts the scroll position timeout. Call this for every VIEW_SCROLLED 111 * event. 112 */ 113 private void startScrollTimeout(AccessibilityEvent event) { 114 final AccessibilityEvent eventClone = AccessibilityEvent.obtain(event); 115 final Message msg = obtainMessage(SCROLL_TIMEOUT, eventClone); 116 117 sendMessageDelayed(msg, DELAY_SCROLL_TIMEOUT); 118 } 119 120 /** 121 * Removes the scroll position timeout. Call this for every event. 122 */ 123 private void cancelScrollTimeout() { 124 removeMessages(SCROLL_TIMEOUT); 125 } 126 } 127}