VoiceInteractionSession.java revision d3fdb8bed8e836786253f9cd5ab640c7c5ed8501
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.service.voice;
1891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn
19c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackbornimport android.app.Dialog;
20c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackbornimport android.app.Instrumentation;
2191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport android.content.Context;
22c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackbornimport android.content.Intent;
23c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackbornimport android.content.res.TypedArray;
24e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackbornimport android.graphics.Rect;
25c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackbornimport android.graphics.Region;
26c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackbornimport android.inputmethodservice.SoftInputWindow;
2791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport android.os.Binder;
2891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport android.os.Bundle;
2991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport android.os.Handler;
3091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport android.os.IBinder;
3191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport android.os.Message;
3291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport android.os.RemoteException;
3391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport android.util.ArrayMap;
3491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport android.util.Log;
35e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackbornimport android.view.Gravity;
36c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackbornimport android.view.KeyEvent;
37c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackbornimport android.view.LayoutInflater;
38c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackbornimport android.view.View;
39c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackbornimport android.view.ViewGroup;
40c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackbornimport android.view.ViewTreeObserver;
41c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackbornimport android.view.WindowManager;
42c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackbornimport android.widget.FrameLayout;
43c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackbornimport com.android.internal.app.IVoiceInteractionManagerService;
4491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport com.android.internal.app.IVoiceInteractor;
4591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport com.android.internal.app.IVoiceInteractorCallback;
4691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport com.android.internal.app.IVoiceInteractorRequest;
4791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport com.android.internal.os.HandlerCaller;
4891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport com.android.internal.os.SomeArgs;
4991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn
50a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackbornimport java.lang.ref.WeakReference;
51a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn
52c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackbornimport static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
53c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackbornimport static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
54c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
55a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn/**
56a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn * An active voice interaction session, providing a facility for the implementation
57a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn * to interact with the user in the voice interaction layer.  This interface is no shown
58a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn * by default, but you can request that it be shown with {@link #showWindow()}, which
59a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn * will result in a later call to {@link #onCreateContentView()} in which the UI can be
60a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn * built
61a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn *
62a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn * <p>A voice interaction session can be self-contained, ultimately calling {@link #finish}
63a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn * when done.  It can also initiate voice interactions with applications by calling
64a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn * {@link #startVoiceActivity}</p>.
65a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn */
66c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackbornpublic abstract class VoiceInteractionSession implements KeyEvent.Callback {
6791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn    static final String TAG = "VoiceInteractionSession";
6891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn    static final boolean DEBUG = true;
6991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn
70c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    final Context mContext;
71c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    final HandlerCaller mHandlerCaller;
72c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
73c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    final KeyEvent.DispatcherState mDispatcherState = new KeyEvent.DispatcherState();
74c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
75c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    IVoiceInteractionManagerService mSystemService;
76c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    IBinder mToken;
77c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
78c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    int mTheme = 0;
79c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    LayoutInflater mInflater;
80c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    TypedArray mThemeAttrs;
81c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    View mRootView;
82c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    FrameLayout mContentFrame;
83c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    SoftInputWindow mWindow;
84c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
85c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    boolean mInitialized;
86c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    boolean mWindowAdded;
87c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    boolean mWindowVisible;
88c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    boolean mWindowWasVisible;
89c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    boolean mInShowWindow;
90c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
91c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    final ArrayMap<IBinder, Request> mActiveRequests = new ArrayMap<IBinder, Request>();
92c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
93c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    final Insets mTmpInsets = new Insets();
94c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    final int[] mTmpLocation = new int[2];
95c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
96a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn    final WeakReference<VoiceInteractionSession> mWeakRef
97a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn            = new WeakReference<VoiceInteractionSession>(this);
98a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn
9991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn    final IVoiceInteractor mInteractor = new IVoiceInteractor.Stub() {
10091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        @Override
10191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        public IVoiceInteractorRequest startConfirmation(String callingPackage,
102a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn                IVoiceInteractorCallback callback, CharSequence prompt, Bundle extras) {
103a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn            Request request = newRequest(callback);
10491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageOOOO(MSG_START_CONFIRMATION,
10591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                    new Caller(callingPackage, Binder.getCallingUid()), request,
10691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                    prompt, extras));
10791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            return request.mInterface;
10891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        }
10991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn
11091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        @Override
111d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James        public IVoiceInteractorRequest startCompleteVoice(String callingPackage,
112d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James                IVoiceInteractorCallback callback, CharSequence message, Bundle extras) {
113d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James            Request request = newRequest(callback);
114d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James            mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageOOOO(MSG_START_COMPLETE_VOICE,
115d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James                    new Caller(callingPackage, Binder.getCallingUid()), request,
116d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James                    message, extras));
117d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James            return request.mInterface;
118d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James        }
119d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James
120d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James        @Override
121a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn        public IVoiceInteractorRequest startAbortVoice(String callingPackage,
122a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn                IVoiceInteractorCallback callback, CharSequence message, Bundle extras) {
123a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn            Request request = newRequest(callback);
124a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn            mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageOOOO(MSG_START_ABORT_VOICE,
125a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn                    new Caller(callingPackage, Binder.getCallingUid()), request,
126a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn                    message, extras));
127a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn            return request.mInterface;
128a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn        }
129a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn
130a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn        @Override
13191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        public IVoiceInteractorRequest startCommand(String callingPackage,
13291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                IVoiceInteractorCallback callback, String command, Bundle extras) {
133a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn            Request request = newRequest(callback);
13491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageOOOO(MSG_START_COMMAND,
13591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                    new Caller(callingPackage, Binder.getCallingUid()), request,
13691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                    command, extras));
13791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            return request.mInterface;
13891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        }
13991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn
14091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        @Override
14191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        public boolean[] supportsCommands(String callingPackage, String[] commands) {
14291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            Message msg = mHandlerCaller.obtainMessageIOO(MSG_SUPPORTS_COMMANDS,
14391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                    0, new Caller(callingPackage, Binder.getCallingUid()), commands);
14491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            SomeArgs args = mHandlerCaller.sendMessageAndWait(msg);
14591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            if (args != null) {
14691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                boolean[] res = (boolean[])args.arg1;
14791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                args.recycle();
14891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                return res;
14991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            }
15091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            return new boolean[commands.length];
15191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        }
15291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn    };
15391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn
15491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn    final IVoiceInteractionSession mSession = new IVoiceInteractionSession.Stub() {
155c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        @Override
156c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        public void taskStarted(Intent intent, int taskId) {
157c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn            mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageIO(MSG_TASK_STARTED,
158c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                    taskId, intent));
159c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        }
160c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
161c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        @Override
162c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        public void taskFinished(Intent intent, int taskId) {
163c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn            mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageIO(MSG_TASK_FINISHED,
164c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                    taskId, intent));
165c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        }
166c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
167c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        @Override
168c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        public void closeSystemDialogs() {
169c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn            mHandlerCaller.sendMessage(mHandlerCaller.obtainMessage(MSG_CLOSE_SYSTEM_DIALOGS));
170c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        }
171c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
172c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        @Override
173c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        public void destroy() {
174c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn            mHandlerCaller.sendMessage(mHandlerCaller.obtainMessage(MSG_DESTROY));
175c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        }
17691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn    };
17791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn
17891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn    public static class Request {
17991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        final IVoiceInteractorRequest mInterface = new IVoiceInteractorRequest.Stub() {
18091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            @Override
18191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            public void cancel() throws RemoteException {
182a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn                VoiceInteractionSession session = mSession.get();
183a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn                if (session != null) {
184a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn                    session.mHandlerCaller.sendMessage(
185a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn                            session.mHandlerCaller.obtainMessageO(MSG_CANCEL, Request.this));
186a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn                }
18791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            }
18891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        };
18991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        final IVoiceInteractorCallback mCallback;
190a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn        final WeakReference<VoiceInteractionSession> mSession;
191a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn
192a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn        Request(IVoiceInteractorCallback callback, VoiceInteractionSession session) {
19391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            mCallback = callback;
194a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn            mSession = session.mWeakRef;
195a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn        }
196a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn
197a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn        void finishRequest() {
198a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn            VoiceInteractionSession session = mSession.get();
199a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn            if (session == null) {
200a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn                throw new IllegalStateException("VoiceInteractionSession has been destroyed");
201a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn            }
202a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn            Request req = session.removeRequest(mInterface.asBinder());
203a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn            if (req == null) {
204a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn                throw new IllegalStateException("Request not active: " + this);
205a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn            } else if (req != this) {
206a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn                throw new IllegalStateException("Current active request " + req
207a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn                        + " not same as calling request " + this);
208a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn            }
20991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        }
21091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn
21191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        public void sendConfirmResult(boolean confirmed, Bundle result) {
21291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            try {
21391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                if (DEBUG) Log.d(TAG, "sendConfirmResult: req=" + mInterface
21491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                        + " confirmed=" + confirmed + " result=" + result);
215a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn                finishRequest();
21691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                mCallback.deliverConfirmationResult(mInterface, confirmed, result);
21791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            } catch (RemoteException e) {
21891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            }
21991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        }
22091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn
221d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James        public void sendCompleteVoiceResult(Bundle result) {
222d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James            try {
223d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James                if (DEBUG) Log.d(TAG, "sendCompleteVoiceResult: req=" + mInterface
224d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James                        + " result=" + result);
225d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James                finishRequest();
226d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James                mCallback.deliverCompleteVoiceResult(mInterface, result);
227d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James            } catch (RemoteException e) {
228d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James            }
229d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James        }
230d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James
231a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn        public void sendAbortVoiceResult(Bundle result) {
232a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn            try {
233a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn                if (DEBUG) Log.d(TAG, "sendConfirmResult: req=" + mInterface
234a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn                        + " result=" + result);
235a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn                finishRequest();
236a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn                mCallback.deliverAbortVoiceResult(mInterface, result);
237a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn            } catch (RemoteException e) {
238a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn            }
239a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn        }
240a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn
24118f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn        public void sendCommandResult(boolean complete, Bundle result) {
24291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            try {
24391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                if (DEBUG) Log.d(TAG, "sendCommandResult: req=" + mInterface
24491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                        + " result=" + result);
245a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn                finishRequest();
24618f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn                mCallback.deliverCommandResult(mInterface, complete, result);
24791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            } catch (RemoteException e) {
24891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            }
24991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        }
25091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn
25191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        public void sendCancelResult() {
25291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            try {
25391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                if (DEBUG) Log.d(TAG, "sendCancelResult: req=" + mInterface);
254a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn                finishRequest();
25591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                mCallback.deliverCancel(mInterface);
25691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            } catch (RemoteException e) {
25791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            }
25891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        }
25991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn    }
26091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn
26191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn    public static class Caller {
26291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        final String packageName;
26391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        final int uid;
26491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn
26591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        Caller(String _packageName, int _uid) {
26691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            packageName = _packageName;
26791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            uid = _uid;
26891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        }
26991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn    }
27091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn
27191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn    static final int MSG_START_CONFIRMATION = 1;
272d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James    static final int MSG_START_COMPLETE_VOICE = 2;
273d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James    static final int MSG_START_ABORT_VOICE = 3;
274d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James    static final int MSG_START_COMMAND = 4;
275d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James    static final int MSG_SUPPORTS_COMMANDS = 5;
276d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James    static final int MSG_CANCEL = 6;
27791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn
278c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    static final int MSG_TASK_STARTED = 100;
279c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    static final int MSG_TASK_FINISHED = 101;
280c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    static final int MSG_CLOSE_SYSTEM_DIALOGS = 102;
281c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    static final int MSG_DESTROY = 103;
282c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
283c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    class MyCallbacks implements HandlerCaller.Callback, SoftInputWindow.Callback {
28491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        @Override
28591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        public void executeMessage(Message msg) {
286c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn            SomeArgs args;
28791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            switch (msg.what) {
28891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                case MSG_START_CONFIRMATION:
289c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                    args = (SomeArgs)msg.obj;
29091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                    if (DEBUG) Log.d(TAG, "onConfirm: req=" + ((Request) args.arg2).mInterface
29191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                            + " prompt=" + args.arg3 + " extras=" + args.arg4);
292a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn                    onConfirm((Caller)args.arg1, (Request)args.arg2, (CharSequence)args.arg3,
29391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                            (Bundle)args.arg4);
29491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                    break;
295d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James                case MSG_START_COMPLETE_VOICE:
296d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James                    args = (SomeArgs)msg.obj;
297d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James                    if (DEBUG) Log.d(TAG, "onCompleteVoice: req=" + ((Request) args.arg2).mInterface
298d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James                            + " message=" + args.arg3 + " extras=" + args.arg4);
299d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James                    onCompleteVoice((Caller) args.arg1, (Request) args.arg2,
300d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James                            (CharSequence) args.arg3, (Bundle) args.arg4);
301d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James                    break;
302a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn                case MSG_START_ABORT_VOICE:
303a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn                    args = (SomeArgs)msg.obj;
304a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn                    if (DEBUG) Log.d(TAG, "onAbortVoice: req=" + ((Request) args.arg2).mInterface
305a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn                            + " message=" + args.arg3 + " extras=" + args.arg4);
306a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn                    onAbortVoice((Caller) args.arg1, (Request) args.arg2, (CharSequence) args.arg3,
307a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn                            (Bundle) args.arg4);
308a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn                    break;
30991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                case MSG_START_COMMAND:
310c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                    args = (SomeArgs)msg.obj;
31191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                    if (DEBUG) Log.d(TAG, "onCommand: req=" + ((Request) args.arg2).mInterface
31291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                            + " command=" + args.arg3 + " extras=" + args.arg4);
31391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                    onCommand((Caller) args.arg1, (Request) args.arg2, (String) args.arg3,
31491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                            (Bundle) args.arg4);
31591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                    break;
31691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                case MSG_SUPPORTS_COMMANDS:
317c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                    args = (SomeArgs)msg.obj;
31891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                    if (DEBUG) Log.d(TAG, "onGetSupportedCommands: cmds=" + args.arg2);
31991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                    args.arg1 = onGetSupportedCommands((Caller) args.arg1, (String[]) args.arg2);
32091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                    break;
32191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                case MSG_CANCEL:
322c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                    args = (SomeArgs)msg.obj;
32391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                    if (DEBUG) Log.d(TAG, "onCancel: req=" + ((Request) args.arg1).mInterface);
32491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                    onCancel((Request)args.arg1);
32591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                    break;
326c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                case MSG_TASK_STARTED:
327c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                    if (DEBUG) Log.d(TAG, "onTaskStarted: intent=" + msg.obj
328c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                            + " taskId=" + msg.arg1);
329c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                    onTaskStarted((Intent) msg.obj, msg.arg1);
330c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                    break;
331c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                case MSG_TASK_FINISHED:
332c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                    if (DEBUG) Log.d(TAG, "onTaskFinished: intent=" + msg.obj
333c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                            + " taskId=" + msg.arg1);
334c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                    onTaskFinished((Intent) msg.obj, msg.arg1);
335c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                    break;
336c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                case MSG_CLOSE_SYSTEM_DIALOGS:
337c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                    if (DEBUG) Log.d(TAG, "onCloseSystemDialogs");
338c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                    onCloseSystemDialogs();
339c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                    break;
340c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                case MSG_DESTROY:
341c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                    if (DEBUG) Log.d(TAG, "doDestroy");
342c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                    doDestroy();
343c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                    break;
34491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            }
34591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        }
34691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn
347c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        @Override
348c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        public void onBackPressed() {
349c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn            VoiceInteractionSession.this.onBackPressed();
350c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        }
351c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    }
352c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
353c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    final MyCallbacks mCallbacks = new MyCallbacks();
354c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
355c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    /**
356c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn     * Information about where interesting parts of the input method UI appear.
357c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn     */
358c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    public static final class Insets {
359c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        /**
360e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn         * This is the part of the UI that is the main content.  It is
361c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn         * used to determine the basic space needed, to resize/pan the
362c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn         * application behind.  It is assumed that this inset does not
363c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn         * change very much, since any change will cause a full resize/pan
364c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn         * of the application behind.  This value is relative to the top edge
365c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn         * of the input method window.
366c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn         */
367e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn        public final Rect contentInsets = new Rect();
368c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
369c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        /**
370c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn         * This is the region of the UI that is touchable.  It is used when
371c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn         * {@link #touchableInsets} is set to {@link #TOUCHABLE_INSETS_REGION}.
372c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn         * The region should be specified relative to the origin of the window frame.
373c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn         */
374c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        public final Region touchableRegion = new Region();
375c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
376c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        /**
377c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn         * Option for {@link #touchableInsets}: the entire window frame
378c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn         * can be touched.
379c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn         */
380c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        public static final int TOUCHABLE_INSETS_FRAME
381c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME;
382c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
383c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        /**
384c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn         * Option for {@link #touchableInsets}: the area inside of
385c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn         * the content insets can be touched.
386c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn         */
387c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        public static final int TOUCHABLE_INSETS_CONTENT
388c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT;
389c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
390c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        /**
391c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn         * Option for {@link #touchableInsets}: the region specified by
392c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn         * {@link #touchableRegion} can be touched.
393c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn         */
394c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        public static final int TOUCHABLE_INSETS_REGION
395c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION;
396c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
397c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        /**
398c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn         * Determine which area of the window is touchable by the user.  May
399c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn         * be one of: {@link #TOUCHABLE_INSETS_FRAME},
400c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn         * {@link #TOUCHABLE_INSETS_CONTENT}, or {@link #TOUCHABLE_INSETS_REGION}.
401c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn         */
402c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        public int touchableInsets;
403c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    }
404c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
405c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    final ViewTreeObserver.OnComputeInternalInsetsListener mInsetsComputer =
406c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn            new ViewTreeObserver.OnComputeInternalInsetsListener() {
407c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        public void onComputeInternalInsets(ViewTreeObserver.InternalInsetsInfo info) {
408c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn            onComputeInsets(mTmpInsets);
409e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn            info.contentInsets.set(mTmpInsets.contentInsets);
410e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn            info.visibleInsets.set(mTmpInsets.contentInsets);
411c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn            info.touchableRegion.set(mTmpInsets.touchableRegion);
412c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn            info.setTouchableInsets(mTmpInsets.touchableInsets);
413c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        }
414c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    };
41591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn
41691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn    public VoiceInteractionSession(Context context) {
41791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        this(context, new Handler());
41891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn    }
41991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn
42091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn    public VoiceInteractionSession(Context context, Handler handler) {
42191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        mContext = context;
42291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        mHandlerCaller = new HandlerCaller(context, handler.getLooper(),
423c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                mCallbacks, true);
42491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn    }
42591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn
426a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn    Request newRequest(IVoiceInteractorCallback callback) {
427a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn        synchronized (this) {
428a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn            Request req = new Request(callback, this);
429a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn            mActiveRequests.put(req.mInterface.asBinder(), req);
430a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn            return req;
431a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn        }
432a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn    }
433a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn
434a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn    Request removeRequest(IBinder reqInterface) {
43591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        synchronized (this) {
436a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn            Request req = mActiveRequests.get(reqInterface);
43791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            if (req != null) {
438a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn                mActiveRequests.remove(req);
43991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            }
44091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            return req;
44191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        }
44291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn    }
44391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn
444c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    void doCreate(IVoiceInteractionManagerService service, IBinder token, Bundle args) {
445c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        mSystemService = service;
446c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        mToken = token;
447c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        onCreate(args);
448c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    }
449c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
450c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    void doDestroy() {
451c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        if (mInitialized) {
452c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn            mRootView.getViewTreeObserver().removeOnComputeInternalInsetsListener(
453c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                    mInsetsComputer);
454c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn            if (mWindowAdded) {
455c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                mWindow.dismiss();
456c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                mWindowAdded = false;
457c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn            }
458c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn            mInitialized = false;
459c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        }
460c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    }
461c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
462c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    void initViews() {
463c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        mInitialized = true;
464c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
465c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        mThemeAttrs = mContext.obtainStyledAttributes(android.R.styleable.VoiceInteractionSession);
466c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        mRootView = mInflater.inflate(
467c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                com.android.internal.R.layout.voice_interaction_session, null);
468c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        mRootView.setSystemUiVisibility(
469c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
470c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        mWindow.setContentView(mRootView);
471c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        mRootView.getViewTreeObserver().addOnComputeInternalInsetsListener(mInsetsComputer);
472c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
473c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        mContentFrame = (FrameLayout)mRootView.findViewById(android.R.id.content);
474c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    }
475c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
476c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    public void showWindow() {
477c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        if (DEBUG) Log.v(TAG, "Showing window: mWindowAdded=" + mWindowAdded
478c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                + " mWindowVisible=" + mWindowVisible);
479c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
480c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        if (mInShowWindow) {
481c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn            Log.w(TAG, "Re-entrance in to showWindow");
482c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn            return;
483c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        }
484c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
485c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        try {
486c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn            mInShowWindow = true;
487c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn            if (!mWindowVisible) {
488c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                mWindowVisible = true;
489c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                if (!mWindowAdded) {
490c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                    mWindowAdded = true;
491c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                    View v = onCreateContentView();
492c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                    if (v != null) {
493c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                        setContentView(v);
494c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                    }
495c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                }
496c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                mWindow.show();
497c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn            }
498c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        } finally {
499c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn            mWindowWasVisible = true;
500c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn            mInShowWindow = false;
501c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        }
502c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    }
503c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
504c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    public void hideWindow() {
505c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        if (mWindowVisible) {
506c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn            mWindow.hide();
507c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn            mWindowVisible = false;
508c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        }
509c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    }
510c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
511c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    /**
512c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn     * You can call this to customize the theme used by your IME's window.
513c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn     * This must be set before {@link #onCreate}, so you
514c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn     * will typically call it in your constructor with the resource ID
515c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn     * of your custom theme.
516c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn     */
517c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    public void setTheme(int theme) {
518c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        if (mWindow != null) {
519c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn            throw new IllegalStateException("Must be called before onCreate()");
520c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        }
521c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        mTheme = theme;
522c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    }
523c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
524a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn    /**
525a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * Ask that a new activity be started for voice interaction.  This will create a
526a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * new dedicated task in the activity manager for this voice interaction session;
527a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * this means that {@link Intent#FLAG_ACTIVITY_NEW_TASK Intent.FLAG_ACTIVITY_NEW_TASK}
528a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * will be set for you to make it a new task.
529a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     *
530a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * <p>The newly started activity will be displayed to the user in a special way, as
531a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * a layer under the voice interaction UI.</p>
532a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     *
533a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * <p>As the voice activity runs, it can retrieve a {@link android.app.VoiceInteractor}
534a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * through which it can perform voice interactions through your session.  These requests
535a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * for voice interactions will appear as callbacks on {@link #onGetSupportedCommands},
536a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * {@link #onConfirm}, {@link #onCommand}, and {@link #onCancel}.
537a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     *
538a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * <p>You will receive a call to {@link #onTaskStarted} when the task starts up
539a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * and {@link #onTaskFinished} when the last activity has finished.
540a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     *
541a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * @param intent The Intent to start this voice interaction.  The given Intent will
542a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * always have {@link Intent#CATEGORY_VOICE Intent.CATEGORY_VOICE} added to it, since
543a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * this is part of a voice interaction.
544a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     */
545c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    public void startVoiceActivity(Intent intent) {
546c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        if (mToken == null) {
547c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn            throw new IllegalStateException("Can't call before onCreate()");
548c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        }
549c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        try {
550e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn            intent.migrateExtraStreamToClipData();
551e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn            intent.prepareToLeaveProcess();
552c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn            int res = mSystemService.startVoiceActivity(mToken, intent,
553c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                    intent.resolveType(mContext.getContentResolver()));
554c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn            Instrumentation.checkStartActivityResult(res, intent);
555c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        } catch (RemoteException e) {
556c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        }
557c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    }
558c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
559a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn    /**
560a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * Convenience for inflating views.
561a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     */
562c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    public LayoutInflater getLayoutInflater() {
563c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        return mInflater;
564c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    }
565c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
566a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn    /**
567a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * Retrieve the window being used to show the session's UI.
568a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     */
569c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    public Dialog getWindow() {
570c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        return mWindow;
571c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    }
572c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
573a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn    /**
574a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * Finish the session.
575a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     */
576c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    public void finish() {
577c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        if (mToken == null) {
578c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn            throw new IllegalStateException("Can't call before onCreate()");
579c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        }
580c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        hideWindow();
581c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        try {
582c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn            mSystemService.finish(mToken);
583c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        } catch (RemoteException e) {
584c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        }
585c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    }
586c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
587a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn    /**
588a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * Initiatize a new session.
589a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     *
590a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * @param args The arguments that were supplied to
591a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * {@link VoiceInteractionService#startSession VoiceInteractionService.startSession}.
592a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     */
593c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    public void onCreate(Bundle args) {
594c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        mTheme = mTheme != 0 ? mTheme
595c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                : com.android.internal.R.style.Theme_DeviceDefault_VoiceInteractionSession;
596c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        mInflater = (LayoutInflater)mContext.getSystemService(
597c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                Context.LAYOUT_INFLATER_SERVICE);
598c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        mWindow = new SoftInputWindow(mContext, "VoiceInteractionSession", mTheme,
599e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn                mCallbacks, this, mDispatcherState,
600e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn                WindowManager.LayoutParams.TYPE_VOICE_INTERACTION, Gravity.TOP, true);
601c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        mWindow.getWindow().addFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
602c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        initViews();
603c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        mWindow.getWindow().setLayout(MATCH_PARENT, WRAP_CONTENT);
604c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        mWindow.setToken(mToken);
605c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    }
606c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
607a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn    /**
608a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * Last callback to the session as it is being finished.
609a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     */
610c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    public void onDestroy() {
611c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    }
612c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
613a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn    /**
614a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * Hook in which to create the session's UI.
615a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     */
616c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    public View onCreateContentView() {
617c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        return null;
618c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    }
619c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
620c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    public void setContentView(View view) {
621c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        mContentFrame.removeAllViews();
622c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        mContentFrame.addView(view, new FrameLayout.LayoutParams(
623c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                ViewGroup.LayoutParams.MATCH_PARENT,
624c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                ViewGroup.LayoutParams.WRAP_CONTENT));
625c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
626c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    }
627c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
628c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    public boolean onKeyDown(int keyCode, KeyEvent event) {
629c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        return false;
630c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    }
631c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
632c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    public boolean onKeyLongPress(int keyCode, KeyEvent event) {
633c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        return false;
634c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    }
635c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
636c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    public boolean onKeyUp(int keyCode, KeyEvent event) {
637c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        return false;
638c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    }
639c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
640c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    public boolean onKeyMultiple(int keyCode, int count, KeyEvent event) {
641c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        return false;
642c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    }
643c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
644c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    public void onBackPressed() {
645c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        finish();
646c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    }
647c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
648a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn    /**
649a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * Sessions automatically watch for requests that all system UI be closed (such as when
650a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * the user presses HOME), which will appear here.  The default implementation always
651a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * calls {@link #finish}.
652a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     */
653c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    public void onCloseSystemDialogs() {
654c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        finish();
655c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    }
656c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
657c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    /**
658c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn     * Compute the interesting insets into your UI.  The default implementation
659c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn     * uses the entire window frame as the insets.  The default touchable
660c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn     * insets are {@link Insets#TOUCHABLE_INSETS_FRAME}.
661c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn     *
662c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn     * @param outInsets Fill in with the current UI insets.
663c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn     */
664c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    public void onComputeInsets(Insets outInsets) {
665c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        int[] loc = mTmpLocation;
666c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        View decor = getWindow().getWindow().getDecorView();
667c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        decor.getLocationInWindow(loc);
668e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn        outInsets.contentInsets.top = 0;
669e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn        outInsets.contentInsets.left = 0;
670e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn        outInsets.contentInsets.right = 0;
671e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn        outInsets.contentInsets.bottom = 0;
672c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        outInsets.touchableInsets = Insets.TOUCHABLE_INSETS_FRAME;
673c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        outInsets.touchableRegion.setEmpty();
674c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    }
675c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
676a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn    /**
677a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * Called when a task initiated by {@link #startVoiceActivity(android.content.Intent)}
678a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * has actually started.
679a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     *
680a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * @param intent The original {@link Intent} supplied to
681a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * {@link #startVoiceActivity(android.content.Intent)}.
682a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * @param taskId Unique ID of the now running task.
683a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     */
684c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    public void onTaskStarted(Intent intent, int taskId) {
685c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    }
686c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
687a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn    /**
688a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * Called when the last activity of a task initiated by
689a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * {@link #startVoiceActivity(android.content.Intent)} has finished.  The default
690a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * implementation calls {@link #finish()} on the assumption that this represents
691a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * the completion of a voice action.  You can override the implementation if you would
692a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * like a different behavior.
693a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     *
694a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * @param intent The original {@link Intent} supplied to
695a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * {@link #startVoiceActivity(android.content.Intent)}.
696a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * @param taskId Unique ID of the finished task.
697a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     */
698c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    public void onTaskFinished(Intent intent, int taskId) {
699c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        finish();
700c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    }
701c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
702a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn    /**
703a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * Request to query for what extended commands the session supports.
704a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     *
705a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * @param caller Who is making the request.
706a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * @param commands An array of commands that are being queried.
707a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * @return Return an array of booleans indicating which of each entry in the
708a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * command array is supported.  A true entry in the array indicates the command
709a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * is supported; false indicates it is not.  The default implementation returns
710a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * an array of all false entries.
711a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     */
712a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn    public boolean[] onGetSupportedCommands(Caller caller, String[] commands) {
713a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn        return new boolean[commands.length];
714a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn    }
715a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn
716a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn    /**
717a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * Request to confirm with the user before proceeding with an unrecoverable operation,
718a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * corresponding to a {@link android.app.VoiceInteractor.ConfirmationRequest
719a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * VoiceInteractor.ConfirmationRequest}.
720a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     *
721a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * @param caller Who is making the request.
722a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * @param request The active request.
723a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * @param prompt The prompt informing the user of what will happen, as per
724a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * {@link android.app.VoiceInteractor.ConfirmationRequest VoiceInteractor.ConfirmationRequest}.
725a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * @param extras Any additional information, as per
726a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * {@link android.app.VoiceInteractor.ConfirmationRequest VoiceInteractor.ConfirmationRequest}.
727a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     */
728a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn    public abstract void onConfirm(Caller caller, Request request, CharSequence prompt,
729a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn            Bundle extras);
730a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn
731a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn    /**
732d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James     * Request to complete the voice interaction session because the voice activity successfully
733d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James     * completed its interaction using voice.  Corresponds to
734d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James     * {@link android.app.VoiceInteractor.CompleteVoiceRequest
735d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James     * VoiceInteractor.CompleteVoiceRequest}.  The default implementation just sends an empty
736d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James     * confirmation back to allow the activity to exit.
737d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James     *
738d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James     * @param caller Who is making the request.
739d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James     * @param request The active request.
740d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James     * @param message The message informing the user of the problem, as per
741d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James     * {@link android.app.VoiceInteractor.CompleteVoiceRequest
742d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James     * VoiceInteractor.CompleteVoiceRequest}.
743d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James     * @param extras Any additional information, as per
744d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James     * {@link android.app.VoiceInteractor.CompleteVoiceRequest
745d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James     * VoiceInteractor.CompleteVoiceRequest}.
746d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James     */
747d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James    public void onCompleteVoice(Caller caller, Request request, CharSequence message,
748d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James           Bundle extras) {
749d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James        request.sendCompleteVoiceResult(null);
750d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James    }
751d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James
752d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James    /**
753a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * Request to abort the voice interaction session because the voice activity can not
754a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * complete its interaction using voice.  Corresponds to
755a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * {@link android.app.VoiceInteractor.AbortVoiceRequest
756a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * VoiceInteractor.AbortVoiceRequest}.  The default implementation just sends an empty
757a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * confirmation back to allow the activity to exit.
758a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     *
759a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * @param caller Who is making the request.
760a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * @param request The active request.
761a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * @param message The message informing the user of the problem, as per
762a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * {@link android.app.VoiceInteractor.AbortVoiceRequest VoiceInteractor.AbortVoiceRequest}.
763a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * @param extras Any additional information, as per
764a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * {@link android.app.VoiceInteractor.AbortVoiceRequest VoiceInteractor.AbortVoiceRequest}.
765a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     */
766a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn    public void onAbortVoice(Caller caller, Request request, CharSequence message, Bundle extras) {
767a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn        request.sendAbortVoiceResult(null);
768a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn    }
769a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn
770a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn    /**
771a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * Process an arbitrary extended command from the caller,
772a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * corresponding to a {@link android.app.VoiceInteractor.CommandRequest
773a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * VoiceInteractor.CommandRequest}.
774a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     *
775a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * @param caller Who is making the request.
776a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * @param request The active request.
777a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * @param command The command that is being executed, as per
778a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * {@link android.app.VoiceInteractor.CommandRequest VoiceInteractor.CommandRequest}.
779a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * @param extras Any additional information, as per
780a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * {@link android.app.VoiceInteractor.CommandRequest VoiceInteractor.CommandRequest}.
781a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     */
78291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn    public abstract void onCommand(Caller caller, Request request, String command, Bundle extras);
783a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn
784a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn    /**
785a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * Called when the {@link android.app.VoiceInteractor} has asked to cancel a {@link Request}
786a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * that was previously delivered to {@link #onConfirm} or {@link #onCommand}.
787a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     *
788a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * @param request The request that is being canceled.
789a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     */
79091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn    public abstract void onCancel(Request request);
79191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn}
792