• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 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 
17 package android.voiceinteraction.service;
18 
19 import android.app.VoiceInteractor;
20 import android.content.Context;
21 import android.content.Intent;
22 import android.content.pm.LauncherApps;
23 import android.os.AsyncTask;
24 import android.os.Bundle;
25 import android.service.voice.VoiceInteractionSession;
26 import android.util.Log;
27 import android.voiceinteraction.common.Utils;
28 
29 import java.util.ArrayList;
30 import java.util.List;
31 
32 public class MainInteractionSession extends VoiceInteractionSession {
33     static final String TAG = "MainInteractionSession";
34 
35     Intent mStartIntent;
36     List<MyTask> mUsedTasks = new ArrayList<MyTask>();
37 
MainInteractionSession(Context context)38     MainInteractionSession(Context context) {
39         super(context);
40     }
41 
42     @Override
onCreate()43     public void onCreate() {
44         super.onCreate();
45         Intent sessionStarted = new Intent();
46         sessionStarted.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
47         if (!getContext().getSystemService(LauncherApps.class).hasShortcutHostPermission()) {
48             sessionStarted.putExtra("error", "Does not have shortcut permission");
49         }
50         sessionStarted.setClassName("android.voiceinteraction.cts",
51                 "android.voiceinteraction.cts.VoiceInteractionTestReceiver");
52         Log.i(TAG, "onCreate(): broadcast intent=" + sessionStarted);
53         getContext().sendBroadcast(sessionStarted);
54     }
55 
56     @Override
onDestroy()57     public void onDestroy() {
58         Log.i(TAG, "Canceling the Asynctask in onDestroy()");
59         for (MyTask t : mUsedTasks) {
60             t.cancel(true);
61         }
62         super.onDestroy();
63     }
64 
65     @Override
onShow(Bundle args, int showFlags)66     public void onShow(Bundle args, int showFlags) {
67         if (args == null) {
68             Log.e(TAG, "onshow() received null args");
69             return;
70         }
71         mStartIntent = args.getParcelable("intent");
72         if (mStartIntent != null) {
73             startVoiceActivity(mStartIntent);
74         } else if ((showFlags & SHOW_SOURCE_ACTIVITY) == SHOW_SOURCE_ACTIVITY) {
75             // Verify args
76             if (args == null
77                     || !Utils.PRIVATE_OPTIONS_VALUE.equals(
78                             args.getString(Utils.PRIVATE_OPTIONS_KEY))) {
79                 throw new IllegalArgumentException("Incorrect arguments for SHOW_SOURCE_ACTIVITY");
80             }
81         }
82     }
83 
assertPromptFromTestApp(CharSequence prompt, Bundle extras)84     void assertPromptFromTestApp(CharSequence prompt, Bundle extras) {
85         String str = prompt.toString();
86         if (str.equals(Utils.TEST_PROMPT)) {
87             Log.i(TAG, "prompt received ok from TestApp in Session");
88         } else {
89             Utils.addErrorResult(extras, "Invalid prompt received: " + str);
90         }
91     }
92 
newTask()93     synchronized MyTask newTask() {
94         MyTask t = new MyTask();
95         mUsedTasks.add(t);
96         return t;
97     }
98 
99     @Override
onGetSupportedCommands(String[] commands)100     public boolean[] onGetSupportedCommands(String[] commands) {
101         boolean[] results = new boolean[commands.length];
102         Log.i(TAG, "in onGetSupportedCommands");
103         for (int idx = 0; idx < commands.length; idx++) {
104             results[idx] = Utils.TEST_COMMAND.equals(commands[idx]);
105             Log.i(TAG, "command " + commands[idx] + ", support = " + results[idx]);
106         }
107         return results;
108     }
109 
110     @Override
onRequestConfirmation(ConfirmationRequest request)111     public void onRequestConfirmation(ConfirmationRequest request) {
112         Bundle extras = request.getExtras();
113         CharSequence prompt = request.getVoicePrompt().getVoicePromptAt(0);
114         Log.i(TAG, "in Session onRequestConfirmation recvd. prompt=" + prompt +
115                 ", extras=" + Utils.toBundleString(extras));
116         assertPromptFromTestApp(prompt, extras);
117         AsyncTaskArg asyncTaskArg = new AsyncTaskArg().setRequest(request).setExtras(extras);
118         if (isTestTypeCancel(extras)) {
119             Log.i(TAG, "Sending Cancel.");
120             newTask().execute(
121                     asyncTaskArg.setTestType(Utils.TestCaseType.CONFIRMATION_REQUEST_CANCEL_TEST));
122         } else {
123             Log.i(TAG, "in Session sending sendConfirmationResult. " +
124                     Utils.toBundleString(extras));
125             newTask().execute(
126                     asyncTaskArg.setTestType(Utils.TestCaseType.CONFIRMATION_REQUEST_TEST));
127         }
128     }
129 
130     @Override
onRequestCompleteVoice(CompleteVoiceRequest request)131     public void onRequestCompleteVoice(CompleteVoiceRequest request) {
132         Bundle extras = request.getExtras();
133         CharSequence prompt = request.getVoicePrompt().getVoicePromptAt(0);
134         Log.i(TAG, "in Session onRequestCompleteVoice recvd. message=" +
135                 prompt + ", extras=" + Utils.toBundleString(extras));
136         assertPromptFromTestApp(prompt, extras);
137         AsyncTaskArg asyncTaskArg = new AsyncTaskArg().setRequest(request).setExtras(extras);
138         if (isTestTypeCancel(extras)) {
139             Log.i(TAG, "Sending Cancel.");
140             newTask().execute(
141                     asyncTaskArg.setTestType(Utils.TestCaseType.COMPLETION_REQUEST_CANCEL_TEST));
142         } else {
143             Log.i(TAG, "in Session sending sendConfirmationResult. " +
144                     Utils.toBundleString(extras));
145             newTask().execute(
146                     asyncTaskArg.setTestType(Utils.TestCaseType.COMPLETION_REQUEST_TEST));
147         }
148     }
149 
150     @Override
onRequestAbortVoice(AbortVoiceRequest request)151     public void onRequestAbortVoice(AbortVoiceRequest request) {
152         Bundle extras = request.getExtras();
153         CharSequence prompt = request.getVoicePrompt().getVoicePromptAt(0);
154         Log.i(TAG, "in Session onRequestAbortVoice recvd. message=" +
155                 prompt + ", extras=" + Utils.toBundleString(extras));
156         assertPromptFromTestApp(prompt, extras);
157         AsyncTaskArg asyncTaskArg = new AsyncTaskArg().setRequest(request).setExtras(extras);
158         if (isTestTypeCancel(extras)) {
159             Log.i(TAG, "Sending Cancel.");
160             newTask().execute(
161                     asyncTaskArg.setTestType(Utils.TestCaseType.ABORT_REQUEST_CANCEL_TEST));
162         } else {
163             Log.i(TAG, "in Session sending sendAbortResult. " +
164                 Utils.toBundleString(extras));
165             newTask().execute(asyncTaskArg.setTestType(Utils.TestCaseType.ABORT_REQUEST_TEST));
166         }
167     }
168 
169     @Override
onRequestCommand(CommandRequest request)170     public void onRequestCommand(CommandRequest request) {
171         Bundle extras = request.getExtras();
172         Log.i(TAG, "in Session onRequestCommand recvd. Bundle = " +
173                 Utils.toBundleString(extras));
174 
175         // Make sure that the input request has Utils.TEST_COMMAND sent by TestApp
176         String command = request.getCommand();
177         if (command.equals(Utils.TEST_COMMAND)) {
178             Log.i(TAG, "command received ok from TestApp in Session");
179         } else {
180             Utils.addErrorResult(extras, "Invalid TEST_COMMAND received: " + command);
181         }
182         // Add a field and value in the bundle to be sent to TestApp.
183         // TestApp will ensure that these are transmitted correctly.
184         extras.putString(Utils.TEST_ONCOMMAND_RESULT, Utils.TEST_ONCOMMAND_RESULT_VALUE);
185         AsyncTaskArg asyncTaskArg = new AsyncTaskArg().setRequest(request).setExtras(extras);
186         if (isTestTypeCancel(extras)) {
187             Log.i(TAG, "Sending Cancel.");
188             newTask().execute(
189                     asyncTaskArg.setTestType(Utils.TestCaseType.COMMANDREQUEST_CANCEL_TEST));
190         } else {
191             Log.i(TAG, "in Session sending sendResult. " +
192                     Utils.toBundleString(extras) + ", string_in_bundle: " +
193                     Utils.TEST_ONCOMMAND_RESULT + " = " + Utils.TEST_ONCOMMAND_RESULT_VALUE);
194             newTask().execute(asyncTaskArg.setTestType(Utils.TestCaseType.COMMANDREQUEST_TEST));
195         }
196     }
197 
assertPickOptionsFromTestApp(VoiceInteractor.PickOptionRequest.Option[] options, Bundle extras)198     void assertPickOptionsFromTestApp(VoiceInteractor.PickOptionRequest.Option[] options,
199             Bundle extras) {
200         if ((options.length != 2) ||
201             !options[0].getLabel().toString().equals(Utils.PICKOPTON_1) ||
202             !options[1].getLabel().toString().equals(Utils.PICKOPTON_2)) {
203             Utils.addErrorResult(extras, "Pickoptions Not received correctly in Session.");
204         } else {
205             Log.i(TAG, "Pickoptions received ok from TestApp in Session");
206         }
207     }
208 
209     @Override
onRequestPickOption(PickOptionRequest request)210     public void onRequestPickOption(PickOptionRequest request) {
211         Bundle extras = request.getExtras();
212         CharSequence prompt = request.getVoicePrompt().getVoicePromptAt(0);
213         Log.i(TAG, "in Session onRequestPickOption recvd. message=" +
214                 prompt + ", options = " + Utils.toOptionsString(request.getOptions()) +
215                 ", extras=" + Utils.toBundleString(extras));
216         VoiceInteractor.PickOptionRequest.Option[] picked
217             = new VoiceInteractor.PickOptionRequest.Option[1];
218         assertPromptFromTestApp(prompt, extras);
219         assertPickOptionsFromTestApp(request.getOptions(), extras);
220         picked[0] = new VoiceInteractor.PickOptionRequest.Option(Utils.PICKOPTON_3, 0);
221         AsyncTaskArg asyncTaskArg = new AsyncTaskArg().setRequest(request)
222                 .setExtras(extras)
223                 .setPickedOptions(picked);
224         if (isTestTypeCancel(extras)) {
225             Log.i(TAG, "in MainInteractionSession, Sending Cancel.");
226             newTask().execute(
227                     asyncTaskArg.setTestType(Utils.TestCaseType.PICKOPTION_REQUEST_CANCEL_TEST));
228         } else {
229             Log.i(TAG, "in MainInteractionSession sending sendPickOptionResult. " +
230                     Utils.toBundleString(extras));
231             newTask().execute(asyncTaskArg.setTestType(Utils.TestCaseType.PICKOPTION_REQUEST_TEST));
232         }
233     }
234 
isTestTypeCancel(Bundle extras)235     public static final boolean isTestTypeCancel(Bundle extras) {
236         Utils.TestCaseType testCaseType;
237         try {
238             testCaseType = Utils.TestCaseType.valueOf(extras.getString(Utils.TESTCASE_TYPE));
239         } catch (IllegalArgumentException | NullPointerException e) {
240             Log.wtf(TAG, "unexpected testCaseType value in Bundle received", e);
241             return true;
242         }
243         return testCaseType == Utils.TestCaseType.COMPLETION_REQUEST_CANCEL_TEST ||
244                 testCaseType == Utils.TestCaseType.COMMANDREQUEST_CANCEL_TEST ||
245                 testCaseType == Utils.TestCaseType.CONFIRMATION_REQUEST_CANCEL_TEST ||
246                 testCaseType == Utils.TestCaseType.PICKOPTION_REQUEST_CANCEL_TEST ||
247                 testCaseType == Utils.TestCaseType.ABORT_REQUEST_CANCEL_TEST;
248     }
249 
250     private class AsyncTaskArg {
251         ConfirmationRequest confReq;
252         CommandRequest commandReq;
253         CompleteVoiceRequest compReq;
254         AbortVoiceRequest abortReq;
255         PickOptionRequest pickReq;
256         Bundle extras;
257         VoiceInteractor.PickOptionRequest.Option[] picked;
258         Utils.TestCaseType testType;
259 
setTestType(Utils.TestCaseType t)260         AsyncTaskArg setTestType(Utils.TestCaseType t) {testType = t; return this;}
setRequest(CommandRequest r)261         AsyncTaskArg setRequest(CommandRequest r) {commandReq = r; return this;}
setRequest(ConfirmationRequest r)262         AsyncTaskArg setRequest(ConfirmationRequest r) {confReq = r; return this;}
setRequest(CompleteVoiceRequest r)263         AsyncTaskArg setRequest(CompleteVoiceRequest r) {compReq = r; return this;}
setRequest(AbortVoiceRequest r)264         AsyncTaskArg setRequest(AbortVoiceRequest r) {abortReq = r; return this;}
setRequest(PickOptionRequest r)265         AsyncTaskArg setRequest(PickOptionRequest r) {pickReq = r; return this;}
setExtras(Bundle e)266         AsyncTaskArg setExtras(Bundle e) {extras = e;  return this;}
setPickedOptions(VoiceInteractor.PickOptionRequest.Option[] p)267         AsyncTaskArg setPickedOptions(VoiceInteractor.PickOptionRequest.Option[] p) {
268             picked = p;
269             return this;
270         }
271     }
272 
273     private class MyTask extends AsyncTask<AsyncTaskArg, Void, Void> {
274         @Override
doInBackground(AsyncTaskArg... params)275         protected Void doInBackground(AsyncTaskArg... params) {
276             AsyncTaskArg arg = params[0];
277             Log.i(TAG, "in MyTask - doInBackground: requestType = " +
278                     arg.testType.toString());
279             switch (arg.testType) {
280                 case ABORT_REQUEST_CANCEL_TEST:
281                     arg.abortReq.cancel();
282                     break;
283                 case ABORT_REQUEST_TEST:
284                     arg.abortReq.sendAbortResult(arg.extras);
285                     break;
286                 case COMMANDREQUEST_CANCEL_TEST:
287                     arg.commandReq.cancel();
288                     break;
289                 case COMMANDREQUEST_TEST:
290                     Log.i(TAG, "in MyTask sendResult. " +
291                             Utils.toBundleString(arg.extras) + ", string_in_bundle: " +
292                             Utils.TEST_ONCOMMAND_RESULT + " = " +
293                             Utils.TEST_ONCOMMAND_RESULT_VALUE);
294                     arg.commandReq.sendResult(arg.extras);
295                     break;
296                 case COMPLETION_REQUEST_CANCEL_TEST:
297                     arg.compReq.cancel();
298                     break;
299                 case COMPLETION_REQUEST_TEST:
300                     arg.compReq.sendCompleteResult(arg.extras);
301                     break;
302                 case CONFIRMATION_REQUEST_CANCEL_TEST:
303                      arg.confReq.cancel();
304                      break;
305                 case CONFIRMATION_REQUEST_TEST:
306                      arg.confReq.sendConfirmationResult(true, arg.extras);
307                      break;
308                 case PICKOPTION_REQUEST_CANCEL_TEST:
309                      arg.pickReq.cancel();
310                      break;
311                 case PICKOPTION_REQUEST_TEST:
312                      StringBuilder buf = new StringBuilder();
313                      for (VoiceInteractor.PickOptionRequest.Option s : arg.picked) {
314                          buf.append("option: " + s.toString() + ", ");
315                      }
316                      Log.i(TAG, "******** Sending PickoptionResult: " +
317                              "picked: size = " + arg.picked.length +
318                              ", Options = " + buf.toString() +
319                              ", Bundle: " + Utils.toBundleString(arg.extras));
320                      arg.pickReq.sendPickOptionResult(arg.picked, arg.extras);
321                      break;
322                default:
323                    Log.i(TAG, "Doing nothing for the testcase type: " + arg.testType);
324                    break;
325             }
326             return null;
327         }
328     }
329 }
330