191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn/* 291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn * Copyright (C) 2014 The Android Open Source Project 391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn * 491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License"); 591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn * you may not use this file except in compliance with the License. 691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn * You may obtain a copy of the License at 791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn * 891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn * http://www.apache.org/licenses/LICENSE-2.0 991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn * 1091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn * Unless required by applicable law or agreed to in writing, software 1191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS, 1291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn * See the License for the specific language governing permissions and 1491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn * limitations under the License. 1591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn */ 1691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn 1791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornpackage android.app; 1891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn 19d7c0395d26694c594c3e64b16ab647c971aeb422Dianne Hackbornimport android.annotation.SystemApi; 2091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport android.content.Context; 2191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport android.os.Bundle; 2291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport android.os.IBinder; 2391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport android.os.Looper; 2491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport android.os.Message; 2591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport android.os.RemoteException; 2618f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackbornimport android.util.ArrayMap; 2791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport android.util.Log; 2891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport com.android.internal.app.IVoiceInteractor; 2991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport com.android.internal.app.IVoiceInteractorCallback; 3091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport com.android.internal.app.IVoiceInteractorRequest; 3191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport com.android.internal.os.HandlerCaller; 3291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport com.android.internal.os.SomeArgs; 3391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn 3420d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackbornimport java.util.ArrayList; 3591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn 3691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn/** 37d7c0395d26694c594c3e64b16ab647c971aeb422Dianne Hackborn * @hide 38a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn * Interface for an {@link Activity} to interact with the user through voice. Use 39a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn * {@link android.app.Activity#getVoiceInteractor() Activity.getVoiceInteractor} 40a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn * to retrieve the interface, if the activity is currently involved in a voice interaction. 41a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn * 42a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn * <p>The voice interactor revolves around submitting voice interaction requests to the 43a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn * back-end voice interaction service that is working with the user. These requests are 44a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn * submitted with {@link #submitRequest}, providing a new instance of a 45a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn * {@link Request} subclass describing the type of operation to perform -- currently the 46a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn * possible requests are {@link ConfirmationRequest} and {@link CommandRequest}. 47a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn * 48ca376027943a06e5237fd6a7df8ecf004c222d8eFabrice Di Meglio * <p>Once a request is submitted, the voice system will process it and eventually deliver 49a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn * the result to the request object. The application can cancel a pending request at any 50a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn * time. 51a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn * 52a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn * <p>The VoiceInteractor is integrated with Activity's state saving mechanism, so that 53a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn * if an activity is being restarted with retained state, it will retain the current 54a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn * VoiceInteractor and any outstanding requests. Because of this, you should always use 55a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn * {@link Request#getActivity() Request.getActivity} to get back to the activity of a 56ca376027943a06e5237fd6a7df8ecf004c222d8eFabrice Di Meglio * request, rather than holding on to the activity instance yourself, either explicitly 57a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn * or implicitly through a non-static inner class. 5891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn */ 59d7c0395d26694c594c3e64b16ab647c971aeb422Dianne Hackborn@SystemApi 6091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornpublic class VoiceInteractor { 6191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn static final String TAG = "VoiceInteractor"; 6291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn static final boolean DEBUG = true; 6391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn 6491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn final IVoiceInteractor mInteractor; 6520d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn 6620d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn Context mContext; 6720d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn Activity mActivity; 6820d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn 6991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn final HandlerCaller mHandlerCaller; 7091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn final HandlerCaller.Callback mHandlerCallerCallback = new HandlerCaller.Callback() { 7191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn @Override 7291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn public void executeMessage(Message msg) { 7391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn SomeArgs args = (SomeArgs)msg.obj; 7418f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn Request request; 7591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn switch (msg.what) { 7691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn case MSG_CONFIRMATION_RESULT: 7718f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn request = pullRequest((IVoiceInteractorRequest)args.arg1, true); 7891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn if (DEBUG) Log.d(TAG, "onConfirmResult: req=" 7918f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn + ((IVoiceInteractorRequest)args.arg1).asBinder() + "/" + request 8018f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn + " confirmed=" + msg.arg1 + " result=" + args.arg2); 8118f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn if (request != null) { 8218f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn ((ConfirmationRequest)request).onConfirmationResult(msg.arg1 != 0, 8318f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn (Bundle) args.arg2); 8418f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn request.clear(); 8518f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn } 8691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn break; 87d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James case MSG_COMPLETE_VOICE_RESULT: 88d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James request = pullRequest((IVoiceInteractorRequest)args.arg1, true); 89d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James if (DEBUG) Log.d(TAG, "onCompleteVoice: req=" 90d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James + ((IVoiceInteractorRequest)args.arg1).asBinder() + "/" + request 91d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James + " result=" + args.arg1); 92d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James if (request != null) { 93d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James ((CompleteVoiceRequest)request).onCompleteResult((Bundle) args.arg2); 94d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James request.clear(); 95d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James } 96d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James break; 97a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn case MSG_ABORT_VOICE_RESULT: 98a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn request = pullRequest((IVoiceInteractorRequest)args.arg1, true); 99a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn if (DEBUG) Log.d(TAG, "onAbortVoice: req=" 100a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn + ((IVoiceInteractorRequest)args.arg1).asBinder() + "/" + request 101a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn + " result=" + args.arg1); 102a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn if (request != null) { 103a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn ((AbortVoiceRequest)request).onAbortResult((Bundle) args.arg2); 104a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn request.clear(); 105a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn } 106a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn break; 10791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn case MSG_COMMAND_RESULT: 10818f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn request = pullRequest((IVoiceInteractorRequest)args.arg1, msg.arg1 != 0); 10991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn if (DEBUG) Log.d(TAG, "onCommandResult: req=" 11018f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn + ((IVoiceInteractorRequest)args.arg1).asBinder() + "/" + request 11191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn + " result=" + args.arg2); 11218f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn if (request != null) { 11318f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn ((CommandRequest)request).onCommandResult((Bundle) args.arg2); 11418f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn if (msg.arg1 != 0) { 11518f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn request.clear(); 11618f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn } 11718f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn } 11891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn break; 11991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn case MSG_CANCEL_RESULT: 12018f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn request = pullRequest((IVoiceInteractorRequest)args.arg1, true); 12191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn if (DEBUG) Log.d(TAG, "onCancelResult: req=" 12218f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn + ((IVoiceInteractorRequest)args.arg1).asBinder() + "/" + request); 12318f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn if (request != null) { 12418f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn request.onCancel(); 12518f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn request.clear(); 12618f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn } 12791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn break; 12891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn } 12991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn } 13091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn }; 13191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn 13218f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn final IVoiceInteractorCallback.Stub mCallback = new IVoiceInteractorCallback.Stub() { 13318f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn @Override 13418f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn public void deliverConfirmationResult(IVoiceInteractorRequest request, boolean confirmed, 13518f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn Bundle result) { 13618f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageIOO( 13718f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn MSG_CONFIRMATION_RESULT, confirmed ? 1 : 0, request, result)); 13818f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn } 13918f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn 14018f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn @Override 141d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James public void deliverCompleteVoiceResult(IVoiceInteractorRequest request, Bundle result) { 142d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageOO( 143d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James MSG_COMPLETE_VOICE_RESULT, request, result)); 144d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James } 145d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James 146d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James @Override 147a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn public void deliverAbortVoiceResult(IVoiceInteractorRequest request, Bundle result) { 148a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageOO( 149a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn MSG_ABORT_VOICE_RESULT, request, result)); 150a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn } 151a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn 152a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn @Override 15318f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn public void deliverCommandResult(IVoiceInteractorRequest request, boolean complete, 15418f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn Bundle result) { 15518f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageIOO( 15618f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn MSG_COMMAND_RESULT, complete ? 1 : 0, request, result)); 15718f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn } 15818f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn 15918f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn @Override 16018f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn public void deliverCancel(IVoiceInteractorRequest request) throws RemoteException { 16118f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageO( 16218f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn MSG_CANCEL_RESULT, request)); 16318f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn } 16418f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn }; 16518f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn 16618f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn final ArrayMap<IBinder, Request> mActiveRequests = new ArrayMap<IBinder, Request>(); 16791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn 16891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn static final int MSG_CONFIRMATION_RESULT = 1; 169d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James static final int MSG_COMPLETE_VOICE_RESULT = 2; 170d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James static final int MSG_ABORT_VOICE_RESULT = 3; 171d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James static final int MSG_COMMAND_RESULT = 4; 172d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James static final int MSG_CANCEL_RESULT = 5; 17391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn 17418f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn public static abstract class Request { 17518f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn IVoiceInteractorRequest mRequestInterface; 17618f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn Context mContext; 17718f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn Activity mActivity; 17891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn 17918f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn public Request() { 18091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn } 18191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn 18291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn public void cancel() { 18391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn try { 18491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn mRequestInterface.cancel(); 18591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn } catch (RemoteException e) { 18691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn Log.w(TAG, "Voice interactor has died", e); 18791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn } 18891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn } 18918f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn 19018f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn public Context getContext() { 19118f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn return mContext; 19218f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn } 19318f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn 19418f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn public Activity getActivity() { 19518f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn return mActivity; 19618f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn } 19718f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn 19818f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn public void onCancel() { 19918f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn } 20018f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn 20120d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn public void onAttached(Activity activity) { 20220d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn } 20320d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn 20420d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn public void onDetached() { 20520d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn } 20620d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn 20718f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn void clear() { 20818f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn mRequestInterface = null; 20918f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn mContext = null; 21018f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn mActivity = null; 21118f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn } 21218f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn 21318f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn abstract IVoiceInteractorRequest submit(IVoiceInteractor interactor, 21418f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn String packageName, IVoiceInteractorCallback callback) throws RemoteException; 21591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn } 21691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn 21718f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn public static class ConfirmationRequest extends Request { 21818f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn final CharSequence mPrompt; 21918f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn final Bundle mExtras; 22091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn 22118f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn /** 22218f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn * Confirms an operation with the user via the trusted system 22318f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn * VoiceInteractionService. This allows an Activity to complete an unsafe operation that 22418f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn * would require the user to touch the screen when voice interaction mode is not enabled. 22518f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn * The result of the confirmation will be returned through an asynchronous call to 22618f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn * either {@link #onConfirmationResult(boolean, android.os.Bundle)} or 22718f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn * {@link #onCancel()}. 22818f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn * 22918f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn * <p>In some cases this may be a simple yes / no confirmation or the confirmation could 23018f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn * include context information about how the action will be completed 23118f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn * (e.g. booking a cab might include details about how long until the cab arrives) 23218f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn * so the user can give a confirmation. 23318f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn * @param prompt Optional confirmation text to read to the user as the action being 23418f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn * confirmed. 23518f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn * @param extras Additional optional information. 23618f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn */ 23718f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn public ConfirmationRequest(CharSequence prompt, Bundle extras) { 23818f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn mPrompt = prompt; 23918f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn mExtras = extras; 24018f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn } 24191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn 24218f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn public void onConfirmationResult(boolean confirmed, Bundle result) { 24318f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn } 24491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn 24518f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn IVoiceInteractorRequest submit(IVoiceInteractor interactor, String packageName, 24618f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn IVoiceInteractorCallback callback) throws RemoteException { 247a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn return interactor.startConfirmation(packageName, callback, mPrompt, mExtras); 24818f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn } 249a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn } 250a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn 251d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James public static class CompleteVoiceRequest extends Request { 252d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James final CharSequence mMessage; 253d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James final Bundle mExtras; 254d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James 255d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James /** 256d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James * Reports that the current interaction was successfully completed with voice, so the 257d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James * application can report the final status to the user. When the response comes back, the 258d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James * voice system has handled the request and is ready to switch; at that point the 259d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James * application can start a new non-voice activity or finish. Be sure when starting the new 260d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James * activity to use {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK 261d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James * Intent.FLAG_ACTIVITY_NEW_TASK} to keep the new activity out of the current voice 262d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James * interaction task. 263d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James * 264d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James * @param message Optional message to tell user about the completion status of the task. 265d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James * @param extras Additional optional information. 266d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James */ 267d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James public CompleteVoiceRequest(CharSequence message, Bundle extras) { 268d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James mMessage = message; 269d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James mExtras = extras; 270d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James } 271d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James 272d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James public void onCompleteResult(Bundle result) { 273d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James } 274d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James 275d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James IVoiceInteractorRequest submit(IVoiceInteractor interactor, String packageName, 276d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James IVoiceInteractorCallback callback) throws RemoteException { 277d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James return interactor.startCompleteVoice(packageName, callback, mMessage, mExtras); 278d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James } 279d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James } 280d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James 281a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn public static class AbortVoiceRequest extends Request { 282a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn final CharSequence mMessage; 283a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn final Bundle mExtras; 284a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn 285a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn /** 286a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn * Reports that the current interaction can not be complete with voice, so the 287a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn * application will need to switch to a traditional input UI. Applications should 288a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn * only use this when they need to completely bail out of the voice interaction 289ca376027943a06e5237fd6a7df8ecf004c222d8eFabrice Di Meglio * and switch to a traditional UI. When the response comes back, the voice 290a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn * system has handled the request and is ready to switch; at that point the application 291a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn * can start a new non-voice activity. Be sure when starting the new activity 292a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn * to use {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK 293a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn * Intent.FLAG_ACTIVITY_NEW_TASK} to keep the new activity out of the current voice 294a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn * interaction task. 295a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn * 296a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn * @param message Optional message to tell user about not being able to complete 297a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn * the interaction with voice. 298a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn * @param extras Additional optional information. 299a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn */ 300a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn public AbortVoiceRequest(CharSequence message, Bundle extras) { 301a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn mMessage = message; 302a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn mExtras = extras; 303a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn } 304a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn 305a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn public void onAbortResult(Bundle result) { 306a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn } 307a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn 308a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn IVoiceInteractorRequest submit(IVoiceInteractor interactor, String packageName, 309a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn IVoiceInteractorCallback callback) throws RemoteException { 310a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn return interactor.startAbortVoice(packageName, callback, mMessage, mExtras); 311a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn } 312a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn } 31391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn 31418f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn public static class CommandRequest extends Request { 31518f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn final String mCommand; 31618f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn final Bundle mArgs; 31718f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn 31818f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn /** 31918f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn * Execute a command using the trusted system VoiceInteractionService. 32018f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn * This allows an Activity to request additional information from the user needed to 32118f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn * complete an action (e.g. booking a table might have several possible times that the 32218f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn * user could select from or an app might need the user to agree to a terms of service). 32318f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn * The result of the confirmation will be returned through an asynchronous call to 32418f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn * either {@link #onCommandResult(android.os.Bundle)} or 32518f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn * {@link #onCancel()}. 32618f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn * 32718f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn * <p>The command is a string that describes the generic operation to be performed. 32818f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn * The command will determine how the properties in extras are interpreted and the set of 32918f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn * available commands is expected to grow over time. An example might be 33018f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn * "com.google.voice.commands.REQUEST_NUMBER_BAGS" to request the number of bags as part of 33118f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn * airline check-in. (This is not an actual working example.) 33218f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn * 33318f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn * @param command The desired command to perform. 33418f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn * @param args Additional arguments to control execution of the command. 33518f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn */ 33618f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn public CommandRequest(String command, Bundle args) { 33718f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn mCommand = command; 33818f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn mArgs = args; 33991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn } 34091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn 34118f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn public void onCommandResult(Bundle result) { 34291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn } 34391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn 34418f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn IVoiceInteractorRequest submit(IVoiceInteractor interactor, String packageName, 34518f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn IVoiceInteractorCallback callback) throws RemoteException { 34694d937014272bc482680234ce83438eacff21e8bDianne Hackborn return interactor.startCommand(packageName, callback, mCommand, mArgs); 34791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn } 34818f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn } 34991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn 35020d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn VoiceInteractor(IVoiceInteractor interactor, Context context, Activity activity, 35118f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn Looper looper) { 35220d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn mInteractor = interactor; 35391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn mContext = context; 35418f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn mActivity = activity; 35591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn mHandlerCaller = new HandlerCaller(context, looper, mHandlerCallerCallback, true); 35691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn } 35791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn 35818f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn Request pullRequest(IVoiceInteractorRequest request, boolean complete) { 35991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn synchronized (mActiveRequests) { 36091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn Request req = mActiveRequests.get(request.asBinder()); 36118f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn if (req != null && complete) { 36218f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn mActiveRequests.remove(request.asBinder()); 36391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn } 36491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn return req; 36591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn } 36691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn } 36791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn 36820d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn private ArrayList<Request> makeRequestList() { 36920d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn final int N = mActiveRequests.size(); 37020d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn if (N < 1) { 37120d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn return null; 37220d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn } 37320d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn ArrayList<Request> list = new ArrayList<Request>(N); 37420d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn for (int i=0; i<N; i++) { 37520d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn list.add(mActiveRequests.valueAt(i)); 37620d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn } 37720d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn return list; 37820d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn } 37920d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn 38020d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn void attachActivity(Activity activity) { 38120d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn if (mActivity == activity) { 38220d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn return; 38320d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn } 38420d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn mContext = activity; 38520d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn mActivity = activity; 38620d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn ArrayList<Request> reqs = makeRequestList(); 38720d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn if (reqs != null) { 38820d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn for (int i=0; i<reqs.size(); i++) { 38920d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn Request req = reqs.get(i); 39020d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn req.mContext = activity; 39120d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn req.mActivity = activity; 39220d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn req.onAttached(activity); 39320d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn } 39420d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn } 39520d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn } 39620d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn 39720d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn void detachActivity() { 39820d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn ArrayList<Request> reqs = makeRequestList(); 39920d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn if (reqs != null) { 40020d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn for (int i=0; i<reqs.size(); i++) { 40120d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn Request req = reqs.get(i); 40220d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn req.onDetached(); 40320d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn req.mActivity = null; 40420d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn req.mContext = null; 40520d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn } 40620d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn } 40720d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn mContext = null; 40820d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn mActivity = null; 40920d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn } 41020d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn 41118f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn public boolean submitRequest(Request request) { 41291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn try { 41318f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn IVoiceInteractorRequest ireq = request.submit(mInteractor, 41418f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn mContext.getOpPackageName(), mCallback); 41518f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn request.mRequestInterface = ireq; 41618f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn request.mContext = mContext; 41718f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn request.mActivity = mActivity; 41818f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn synchronized (mActiveRequests) { 41918f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn mActiveRequests.put(ireq.asBinder(), request); 42018f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn } 42118f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn return true; 42291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn } catch (RemoteException e) { 42318f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn Log.w(TAG, "Remove voice interactor service died", e); 42418f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn return false; 42591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn } 42691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn } 42791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn 42891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn /** 42991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn * Queries the supported commands available from the VoiceinteractionService. 43091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn * The command is a string that describes the generic operation to be performed. 43191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn * An example might be "com.google.voice.commands.REQUEST_NUMBER_BAGS" to request the number 43291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn * of bags as part of airline check-in. (This is not an actual working example.) 43391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn * 43491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn * @param commands 43591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn */ 43691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn public boolean[] supportsCommands(String[] commands) { 43791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn try { 43891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn boolean[] res = mInteractor.supportsCommands(mContext.getOpPackageName(), commands); 43991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn if (DEBUG) Log.d(TAG, "supportsCommands: cmds=" + commands + " res=" + res); 44091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn return res; 44191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn } catch (RemoteException e) { 44291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn throw new RuntimeException("Voice interactor has died", e); 44391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn } 44491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn } 44591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn} 446