Home | History | Annotate | Download | only in cts
      1 /*
      2  * Copyright (C) 2011 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of 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,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 package android.speech.tts.cts;
     17 
     18 import android.os.ConditionVariable;
     19 import android.os.Environment;
     20 import android.speech.tts.TextToSpeech;
     21 import android.test.AndroidTestCase;
     22 
     23 import java.io.File;
     24 import java.io.FileOutputStream;
     25 import java.util.HashMap;
     26 import java.util.Map;
     27 import java.util.List;
     28 
     29 /**
     30  * Tests for {@link android.speech.tts.TextToSpeechService} using StubTextToSpeechService.
     31  */
     32 public class TextToSpeechServiceTest extends AndroidTestCase {
     33     private static final String UTTERANCE = "text to speech cts test";
     34     private static final String SAMPLE_FILE_NAME = "mytts.wav";
     35 
     36     private TextToSpeechWrapper mTts;
     37 
     38     @Override
     39     protected void setUp() throws Exception {
     40         super.setUp();
     41         StubTextToSpeechService.sSynthesizeTextWait = null;
     42         mTts = TextToSpeechWrapper.createTextToSpeechMockWrapper(getContext());
     43         assertNotNull(mTts);
     44     }
     45 
     46     @Override
     47     protected void tearDown() throws Exception {
     48         super.tearDown();
     49         mTts.shutdown();
     50     }
     51 
     52     private TextToSpeech getTts() {
     53         return mTts.getTts();
     54     }
     55 
     56     public void testSynthesizeToFile() throws Exception {
     57         File sampleFile = new File(getContext().getExternalFilesDir(null), SAMPLE_FILE_NAME);
     58         try {
     59             assertFalse(sampleFile.exists());
     60 
     61             int result =
     62                     getTts().synthesizeToFile(
     63                                     UTTERANCE, createParams("mocktofile"), sampleFile.getPath());
     64             assertEquals("synthesizeToFile() failed", TextToSpeech.SUCCESS, result);
     65 
     66             assertTrue("synthesizeToFile() completion timeout", mTts.waitForComplete("mocktofile"));
     67             assertTrue("synthesizeToFile() didn't produce a file", sampleFile.exists());
     68             assertTrue("synthesizeToFile() produced a non-sound file",
     69                     TextToSpeechWrapper.isSoundFile(sampleFile.getPath()));
     70         } finally {
     71             sampleFile.delete();
     72         }
     73         mTts.verify("mocktofile");
     74 
     75         final Map<String, Integer> chunksReceived = mTts.chunksReceived();
     76         final Map<String, List<Integer>> timePointsStart = mTts.timePointsStart();
     77         final Map<String, List<Integer>> timePointsEnd = mTts.timePointsEnd();
     78         final Map<String, List<Integer>> timePointsFrame = mTts.timePointsFrame();
     79         assertEquals(Integer.valueOf(10), chunksReceived.get("mocktofile"));
     80         // In the mock we set the start, end and frame to exactly these values for the time points.
     81         for (int i = 0; i < 10; i++) {
     82             assertEquals(Integer.valueOf(i * 5), timePointsStart.get("mocktofile").get(i));
     83             assertEquals(Integer.valueOf(i * 5 + 5), timePointsEnd.get("mocktofile").get(i));
     84             assertEquals(Integer.valueOf(i * 10), timePointsFrame.get("mocktofile").get(i));
     85         }
     86     }
     87 
     88     public void testMaxSpeechInputLength() {
     89       File sampleFile = new File(getContext().getExternalFilesDir(null), SAMPLE_FILE_NAME);
     90       try {
     91           assertFalse(sampleFile.exists());
     92           TextToSpeech tts = getTts();
     93 
     94           int maxLength = tts.getMaxSpeechInputLength();
     95           StringBuilder sb = new StringBuilder();
     96           for (int i = 0; i < maxLength; i++) {
     97             sb.append("c");
     98           }
     99           String valid = sb.toString();
    100           sb.append("c");
    101           String invalid = sb.toString();
    102 
    103           assertEquals(maxLength, valid.length());
    104           assertTrue(invalid.length() > maxLength);
    105           assertEquals(TextToSpeech.ERROR,
    106                   tts.synthesizeToFile(invalid, createParams("mockToFile"), sampleFile.getPath()));
    107           assertEquals(TextToSpeech.SUCCESS,
    108                   tts.synthesizeToFile(valid, createParams("mockToFile"), sampleFile.getPath()));
    109       } finally {
    110           sampleFile.delete();
    111       }
    112     }
    113 
    114     public void testSpeak() throws Exception {
    115         int result = getTts().speak(UTTERANCE, TextToSpeech.QUEUE_FLUSH, createParams("mockspeak"));
    116         assertEquals("speak() failed", TextToSpeech.SUCCESS, result);
    117         assertTrue("speak() completion timeout", waitForUtterance("mockspeak"));
    118         mTts.verify("mockspeak");
    119 
    120         final Map<String, Integer> chunksReceived = mTts.chunksReceived();
    121         assertEquals(Integer.valueOf(10), chunksReceived.get("mockspeak"));
    122     }
    123 
    124     public void testSpeakStop() throws Exception {
    125         final ConditionVariable synthesizeTextWait = new ConditionVariable();
    126         StubTextToSpeechService.sSynthesizeTextWait = synthesizeTextWait;
    127 
    128         getTts().stop();
    129         final int iterations = 20;
    130         for (int i = 0; i < iterations; i++) {
    131             int result = getTts().speak(UTTERANCE, TextToSpeech.QUEUE_ADD, null,
    132                     "stop_" + Integer.toString(i));
    133             assertEquals("speak() failed", TextToSpeech.SUCCESS, result);
    134         }
    135         getTts().stop();
    136 
    137         // Wake up the Stubs #onSynthesizeSpeech (one that will be stopped in-progress)
    138         synthesizeTextWait.open();
    139 
    140         for (int i = 0; i < iterations; i++) {
    141             assertTrue("speak() stop callback timeout", mTts.waitForStop(
    142                     "stop_" + Integer.toString(i)));
    143         }
    144     }
    145 
    146     public void testSpeakStopBehindOtherAudioPlayback() throws Exception {
    147         final ConditionVariable synthesizeTextWait = new ConditionVariable();
    148         final ConditionVariable synthesizeTextStartEvent = new ConditionVariable();
    149         StubTextToSpeechService.sSynthesizeTextWait = synthesizeTextWait;
    150         StubTextToSpeechService.sSynthesizeTextStartEvent = synthesizeTextStartEvent;
    151 
    152         // Make the audio playback queue busy by putting a 30s of silence.
    153         getTts().stop();
    154         getTts().playSilentUtterance(30000, TextToSpeech.QUEUE_ADD, "silence");
    155 
    156         // speak(), wait it to starting in the service, and stop().
    157         int result = getTts().speak(UTTERANCE, TextToSpeech.QUEUE_ADD, null, "stop");
    158         assertEquals("speak() failed", TextToSpeech.SUCCESS, result);
    159         assertTrue("synthesis not started", synthesizeTextStartEvent.block(10000));
    160         getTts().stop();
    161 
    162         // Wake up the Stubs #onSynthesizeSpeech (one that will be stopped in-progress)
    163         synthesizeTextWait.open();
    164 
    165         assertTrue("speak() stop callback timeout", mTts.waitForStop("stop"));
    166     }
    167 
    168     public void testMediaPlayerFails() throws Exception {
    169         File sampleFile = new File(getContext().getExternalFilesDir(null), "notsound.wav");
    170         try {
    171             assertFalse(TextToSpeechWrapper.isSoundFile(sampleFile.getPath()));
    172             FileOutputStream out = new FileOutputStream(sampleFile);
    173             out.write(new byte[] { 0x01, 0x02 });
    174             out.close();
    175             assertFalse(TextToSpeechWrapper.isSoundFile(sampleFile.getPath()));
    176         } finally {
    177             sampleFile.delete();
    178         }
    179     }
    180 
    181     private HashMap<String, String> createParams(String utteranceId) {
    182         HashMap<String, String> params = new HashMap<>();
    183         params.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, utteranceId);
    184         return params;
    185     }
    186 
    187     private boolean waitForUtterance(String utteranceId) throws InterruptedException {
    188         return mTts.waitForComplete(utteranceId);
    189     }
    190 
    191 }
    192