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 com.example.android.ttsengine;
17 
18 import android.app.Activity;
19 import android.content.Intent;
20 import android.os.Bundle;
21 import android.speech.tts.TextToSpeech;
22 import android.text.TextUtils;
23 import android.util.Log;
24 
25 import java.io.IOException;
26 import java.io.InputStream;
27 import java.util.ArrayList;
28 import java.util.Arrays;
29 import java.util.List;
30 
31 /*
32  * Checks if the voice data is present.
33  */
34 public class CheckVoiceData extends Activity {
35     private static final String TAG = "CheckVoiceData";
36 
37     private static final String[] SUPPORTED_LANGUAGES = { "eng-GBR", "eng-USA" };
38 
39     @Override
onCreate(Bundle savedInstanceState)40     protected void onCreate(Bundle savedInstanceState) {
41         super.onCreate(savedInstanceState);
42 
43         Intent intent = getIntent();
44         List<String> checkLanguages = getCheckVoiceDataFor(intent);
45 
46         // If the call didn't specify which languages to check, check
47         // for all the supported ones.
48         if (checkLanguages.isEmpty()) {
49             checkLanguages = Arrays.asList(SUPPORTED_LANGUAGES);
50         }
51 
52         ArrayList<String> available = new ArrayList<String>();
53         ArrayList<String> unavailable = new ArrayList<String>();
54 
55         for (String lang : checkLanguages) {
56             // This check is required because checkLanguages might contain
57             // an arbitrary list of languages if the intent specified them
58             // {@link #getCheckVoiceDataFor}.
59             if (isLanguageSupported(lang)) {
60                 if (isDataInstalled(lang)) {
61                     available.add(lang);
62                 } else {
63                     unavailable.add(lang);
64                 }
65             }
66         }
67 
68         int result;
69         if (!checkLanguages.isEmpty() && available.isEmpty()) {
70             // No voices available at all.
71             result = TextToSpeech.Engine.CHECK_VOICE_DATA_FAIL;
72         } else if (!unavailable.isEmpty()) {
73             // Some voices are available, but some have missing
74             // data.
75             result = TextToSpeech.Engine.CHECK_VOICE_DATA_MISSING_DATA;
76         } else {
77             // All voices are available.
78             result = TextToSpeech.Engine.CHECK_VOICE_DATA_PASS;
79         }
80 
81         // We now return the list of available and unavailable voices
82         // as well as the return code.
83         Intent returnData = new Intent();
84         returnData.putStringArrayListExtra(
85                 TextToSpeech.Engine.EXTRA_AVAILABLE_VOICES, available);
86         returnData.putStringArrayListExtra(
87                 TextToSpeech.Engine.EXTRA_UNAVAILABLE_VOICES, unavailable);
88         setResult(result, returnData);
89         finish();
90     }
91 
92     /**
93      * The intent that launches this activity can contain an intent extra
94      * {@link TextToSpeech.Engine.EXTRA_CHECK_VOICE_DATA_FOR} that might specify
95      * a given language to check voice data for. If the intent does not contain
96      * this extra, we assume that a voice check for all supported languages
97      * was requested.
98      */
getCheckVoiceDataFor(Intent intent)99     private List<String> getCheckVoiceDataFor(Intent intent) {
100         ArrayList<String> list = intent.getStringArrayListExtra(
101                 TextToSpeech.Engine.EXTRA_CHECK_VOICE_DATA_FOR);
102         ArrayList<String> ret = new ArrayList<String>();
103         if (list != null) {
104             for (String lang : list) {
105                 if (!TextUtils.isEmpty(lang)) {
106                     ret.add(lang);
107                 }
108             }
109         }
110         return ret;
111     }
112 
113     /**
114      * Checks whether a given language is in the list of supported languages.
115      */
isLanguageSupported(String input)116     private boolean isLanguageSupported(String input) {
117         for (String lang : SUPPORTED_LANGUAGES) {
118             if (lang.equals(input)) {
119                 return true;
120             }
121         }
122 
123         return false;
124     }
125 
126     /*
127      * Note that in our example, all data is packaged in our APK as
128      * assets (it could be a raw resource as well). This check is unnecessary
129      * because it will always succeed.
130      *
131      * If for example, engine data was downloaded or installed on external storage,
132      * this check would make much more sense.
133      */
isDataInstalled(String lang)134     private boolean isDataInstalled(String lang) {
135         try {
136             InputStream is = getAssets().open(lang + ".freq");
137 
138             if (is != null) {
139                 is.close();
140             } else {
141                 return false;
142             }
143         } catch (IOException e) {
144             Log.w(TAG, "Unable to find data for: " + lang + ", exception: " + e);
145             return false;
146         }
147 
148         // The asset InputStream was non null, and therefore this
149         // data file is available.
150         return true;
151     }
152 }
153