PageRenderTime 38ms CodeModel.GetById 24ms app.highlight 10ms RepoModel.GetById 1ms app.codeStats 1ms

/TalkBack/src/com/google/android/marvin/talkback/ProcessorScrollPosition.java

http://eyes-free.googlecode.com/
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}