/*
* Copyright (C) 2015 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.android.talkback;
import android.app.Instrumentation;
import android.test.suitebuilder.annotation.MediumTest;
import android.view.KeyEvent;
import com.android.talkback.FeedbackItem;
import com.android.talkback.SpeechController;
import com.google.android.marvin.talkback.TalkBackService;
import com.googlecode.eyesfree.testing.TalkBackInstrumentationTestCase;
import java.util.ArrayList;
import java.util.List;
public class SpeechControllerTest extends TalkBackInstrumentationTestCase {
private TalkBackService mTalkBack;
private Instrumentation mInstrumentation;
private SpeechController mSpeechController;
@Override
protected void setUp() throws Exception {
super.setUp();
mInstrumentation = getInstrumentation();
mTalkBack = getService();
assertNotNull("Obtained TalkBack instance", mTalkBack);
mSpeechController = getService().getSpeechController();
}
@Override
protected void tearDown() throws Exception {
mSpeechController.setSpeechListener(null);
super.tearDown();
}
@MediumTest
public void testInterrupt_interruptsTts() {
speak("Peter Piper picked a peck of pickled peppers.");
mInstrumentation.waitForIdleSync();
waitForAccessibilityIdleSync();
assertTrue(mSpeechController.isSpeakingOrSpeechQueued());
mTalkBack.getSpeechController().interrupt();
mInstrumentation.waitForIdleSync();
waitForAccessibilityIdleSync();
assertFalse(mSpeechController.isSpeakingOrSpeechQueued());
}
@MediumTest
public void testLeftCtrlKey_interruptsTts() {
speak("Peter Piper picked a peck of pickled peppers.");
mInstrumentation.waitForIdleSync();
waitForAccessibilityIdleSync();
assertTrue(mSpeechController.isSpeakingOrSpeechQueued());
sendCtrlCombo(KeyEvent.KEYCODE_CTRL_LEFT, KeyEvent.KEYCODE_UNKNOWN);
mInstrumentation.waitForIdleSync();
waitForAccessibilityIdleSync();
assertFalse(mSpeechController.isSpeakingOrSpeechQueued());
}
@MediumTest
public void testRightCtrlKey_interruptsTts() {
speak("Peter Piper picked a peck of pickled peppers.");
mInstrumentation.waitForIdleSync();
waitForAccessibilityIdleSync();
assertTrue(mSpeechController.isSpeakingOrSpeechQueued());
sendCtrlCombo(KeyEvent.KEYCODE_CTRL_RIGHT, KeyEvent.KEYCODE_UNKNOWN);
mInstrumentation.waitForIdleSync();
waitForAccessibilityIdleSync();
assertFalse(mSpeechController.isSpeakingOrSpeechQueued());
}
@MediumTest
public void testCtrlZCombo_doesNotInterruptTts() {
speak("Peter Piper picked a peck of pickled peppers.");
mInstrumentation.waitForIdleSync();
waitForAccessibilityIdleSync();
assertTrue(mSpeechController.isSpeakingOrSpeechQueued());
sendCtrlCombo(KeyEvent.KEYCODE_CTRL_LEFT, KeyEvent.KEYCODE_Z);
mInstrumentation.waitForIdleSync();
waitForAccessibilityIdleSync();
assertTrue(mSpeechController.isSpeakingOrSpeechQueued());
}
@MediumTest
public void testDuplicates_skipDuplicates() {
startRecordingRawSpeech();
speakQueued("Duplicate", FeedbackItem.FLAG_SKIP_DUPLICATE);
speakQueued("Duplicate", FeedbackItem.FLAG_SKIP_DUPLICATE);
speakQueued("Unique", FeedbackItem.FLAG_SKIP_DUPLICATE);
speakQueued("Duplicate", FeedbackItem.FLAG_SKIP_DUPLICATE);
speakQueued("Unique", FeedbackItem.FLAG_SKIP_DUPLICATE);
assertEquals(2, getRawSpeechHistory().size());
}
@MediumTest
public void testDuplicates_keepDuplicates() {
startRecordingRawSpeech();
speakQueued("Duplicate", 0);
speakQueued("Duplicate", 0);
speakQueued("Unique", 0);
speakQueued("Duplicate", 0);
speakQueued("Unique", 0);
assertEquals(5, getRawSpeechHistory().size());
}
public void testLastUtterance() {
// Wait for "TalkBack on".
mInstrumentation.waitForIdleSync();
// Clear the speech queue.
mSpeechController.interrupt();
mInstrumentation.waitForIdleSync();
// The text "Google" should speak and appear in history.
startRecordingRawSpeech();
speakWithHistory("Google");
stopRecordingAndAssertRawSpeech("Google");
}
public void testSpellLastUtterance() {
// Wait for "TalkBack on".
mInstrumentation.waitForIdleSync();
// Clear the speech queue.
mSpeechController.interrupt();
mInstrumentation.waitForIdleSync();
// The text "Google" should speak and appear in history.
startRecordingRawSpeech(RECORD_STARTED);
speakWithHistory("Google");
// Need to wait for "Google" to actually start speaking before spelling.
stopRecordingAndAssertRawSpeech("Google");
// Spell and check.
startRecordingRawSpeech(RECORD_QUEUED);
mSpeechController.spellLastUtterance();
stopRecordingAndAssertRawSpeech("capital G, o, o, g, l, e");
}
private void speak(String speech) {
mInstrumentation.waitForIdleSync();
waitForAccessibilityIdleSync();
mSpeechController.speak(speech, SpeechController.QUEUE_MODE_INTERRUPT,
FeedbackItem.FLAG_NO_HISTORY, null);
}
private void speakWithHistory(String speech) {
mInstrumentation.waitForIdleSync();
waitForAccessibilityIdleSync();
mSpeechController.speak(speech, SpeechController.QUEUE_MODE_INTERRUPT, 0, null);
}
private void speakQueued(String speech, int flags) {
mSpeechController.speak(speech, SpeechController.QUEUE_MODE_QUEUE, flags, null);
}
/**
* Emulates the behavior of a user entering a keycombo involving the Ctrl key by first pressing
* down the Ctrl key, then pressing down another key, then lifting the second key, then lifting
* the Ctrl key.
* @param ctrlKeyCode should be one of KeyEvent.KEYCODE_CTRL_LEFT or KeyEvent.KEYCODE_CTRL_RIGHT
* @param secondKeyCode a second key to form the combo, or KeyEvent.KEYCODE_UNKNOWN to only
* simulate pressing the Ctrl key
*/
private void sendCtrlCombo(int ctrlKeyCode, int secondKeyCode) {
KeyEvent ctrlKeyDown = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, ctrlKeyCode, 0,
KeyEvent.META_CTRL_ON);
KeyEvent secondKeyDown = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, secondKeyCode, 0,
KeyEvent.META_CTRL_ON);
KeyEvent secondKeyUp = new KeyEvent(0, 0, KeyEvent.ACTION_UP, secondKeyCode, 0,
KeyEvent.META_CTRL_ON);
KeyEvent ctrlKeyUp = new KeyEvent(0, 0, KeyEvent.ACTION_UP, ctrlKeyCode, 0,
KeyEvent.META_CTRL_ON);
mTalkBack.onKeyEventShared(ctrlKeyDown);
if (secondKeyCode != KeyEvent.KEYCODE_UNKNOWN) {
mTalkBack.onKeyEventShared(secondKeyDown);
mTalkBack.onKeyEventShared(secondKeyUp);
}
mTalkBack.onKeyEventShared(ctrlKeyUp);
}
}