VoiceInteractionSession.java revision 5688b03f7f4fafd671451ff73103be0f2388b32e
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
195688b03f7f4fafd671451ff73103be0f2388b32eDianne Hackbornimport android.app.AssistStructure;
20c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackbornimport android.app.Dialog;
21c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackbornimport android.app.Instrumentation;
223d07c94c393831091958fe6a98811843db8973bdDianne Hackbornimport android.app.VoiceInteractor;
2391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport android.content.Context;
24c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackbornimport android.content.Intent;
25c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackbornimport android.content.res.TypedArray;
2627eac1d58fe0b7ca3a2e27f5ed64eff232745f45Dianne Hackbornimport android.graphics.Bitmap;
27e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackbornimport android.graphics.Rect;
28c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackbornimport android.graphics.Region;
29c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackbornimport android.inputmethodservice.SoftInputWindow;
3091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport android.os.Binder;
3191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport android.os.Bundle;
3291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport android.os.Handler;
3391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport android.os.IBinder;
3491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport android.os.Message;
3591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport android.os.RemoteException;
3691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport android.util.ArrayMap;
3791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport android.util.Log;
38e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackbornimport android.view.Gravity;
39c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackbornimport android.view.KeyEvent;
40c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackbornimport android.view.LayoutInflater;
41c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackbornimport android.view.View;
42c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackbornimport android.view.ViewGroup;
43c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackbornimport android.view.ViewTreeObserver;
44c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackbornimport android.view.WindowManager;
45c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackbornimport android.widget.FrameLayout;
46c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackbornimport com.android.internal.app.IVoiceInteractionManagerService;
4791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport com.android.internal.app.IVoiceInteractor;
4891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport com.android.internal.app.IVoiceInteractorCallback;
4991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport com.android.internal.app.IVoiceInteractorRequest;
5091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport com.android.internal.os.HandlerCaller;
5191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport com.android.internal.os.SomeArgs;
5291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn
53a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackbornimport java.lang.ref.WeakReference;
54a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn
55c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackbornimport static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
56c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
57a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn/**
584e106cedfecd1f6026a79870c2e427853cba7491Dianne Hackborn * An active voice interaction session, providing a facility for the implementation
59ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn * to interact with the user in the voice interaction layer.  The user interface is
60ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn * initially shown by default, and can be created be overriding {@link #onCreateContentView()}
61ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn * in which the UI can be built.
624e106cedfecd1f6026a79870c2e427853cba7491Dianne Hackborn *
634e106cedfecd1f6026a79870c2e427853cba7491Dianne Hackborn * <p>A voice interaction session can be self-contained, ultimately calling {@link #finish}
644e106cedfecd1f6026a79870c2e427853cba7491Dianne Hackborn * when done.  It can also initiate voice interactions with applications by calling
654e106cedfecd1f6026a79870c2e427853cba7491Dianne Hackborn * {@link #startVoiceActivity}</p>.
66a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn */
67c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackbornpublic abstract class VoiceInteractionSession implements KeyEvent.Callback {
6891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn    static final String TAG = "VoiceInteractionSession";
6991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn    static final boolean DEBUG = true;
7091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn
71c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    final Context mContext;
72c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    final HandlerCaller mHandlerCaller;
73c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
74c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    final KeyEvent.DispatcherState mDispatcherState = new KeyEvent.DispatcherState();
75c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
76c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    IVoiceInteractionManagerService mSystemService;
77c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    IBinder mToken;
78c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
79c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    int mTheme = 0;
80c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    LayoutInflater mInflater;
81c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    TypedArray mThemeAttrs;
82c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    View mRootView;
83c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    FrameLayout mContentFrame;
84c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    SoftInputWindow mWindow;
85c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
86c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    boolean mInitialized;
87c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    boolean mWindowAdded;
88c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    boolean mWindowVisible;
89c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    boolean mWindowWasVisible;
90c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    boolean mInShowWindow;
91c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
92c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    final ArrayMap<IBinder, Request> mActiveRequests = new ArrayMap<IBinder, Request>();
93c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
94c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    final Insets mTmpInsets = new Insets();
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
1113d07c94c393831091958fe6a98811843db8973bdDianne Hackborn        public IVoiceInteractorRequest startPickOption(String callingPackage,
1123d07c94c393831091958fe6a98811843db8973bdDianne Hackborn                IVoiceInteractorCallback callback, CharSequence prompt,
1133d07c94c393831091958fe6a98811843db8973bdDianne Hackborn                VoiceInteractor.PickOptionRequest.Option[] options, Bundle extras) {
1143d07c94c393831091958fe6a98811843db8973bdDianne Hackborn            Request request = newRequest(callback);
1153d07c94c393831091958fe6a98811843db8973bdDianne Hackborn            mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageOOOOO(MSG_START_PICK_OPTION,
1163d07c94c393831091958fe6a98811843db8973bdDianne Hackborn                    new Caller(callingPackage, Binder.getCallingUid()), request,
1173d07c94c393831091958fe6a98811843db8973bdDianne Hackborn                    prompt, options, extras));
1183d07c94c393831091958fe6a98811843db8973bdDianne Hackborn            return request.mInterface;
1193d07c94c393831091958fe6a98811843db8973bdDianne Hackborn        }
1203d07c94c393831091958fe6a98811843db8973bdDianne Hackborn
1213d07c94c393831091958fe6a98811843db8973bdDianne Hackborn        @Override
122d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James        public IVoiceInteractorRequest startCompleteVoice(String callingPackage,
123d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James                IVoiceInteractorCallback callback, CharSequence message, Bundle extras) {
124d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James            Request request = newRequest(callback);
125d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James            mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageOOOO(MSG_START_COMPLETE_VOICE,
126d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James                    new Caller(callingPackage, Binder.getCallingUid()), request,
127d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James                    message, extras));
128d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James            return request.mInterface;
129d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James        }
130d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James
131d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James        @Override
132a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn        public IVoiceInteractorRequest startAbortVoice(String callingPackage,
133a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn                IVoiceInteractorCallback callback, CharSequence message, Bundle extras) {
134a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn            Request request = newRequest(callback);
135a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn            mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageOOOO(MSG_START_ABORT_VOICE,
136a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn                    new Caller(callingPackage, Binder.getCallingUid()), request,
137a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn                    message, extras));
138a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn            return request.mInterface;
139a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn        }
140a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn
141a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn        @Override
14291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        public IVoiceInteractorRequest startCommand(String callingPackage,
14391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                IVoiceInteractorCallback callback, String command, Bundle extras) {
144a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn            Request request = newRequest(callback);
14591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageOOOO(MSG_START_COMMAND,
14691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                    new Caller(callingPackage, Binder.getCallingUid()), request,
14791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                    command, extras));
14891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            return request.mInterface;
14991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        }
15091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn
15191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        @Override
15291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        public boolean[] supportsCommands(String callingPackage, String[] commands) {
15391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            Message msg = mHandlerCaller.obtainMessageIOO(MSG_SUPPORTS_COMMANDS,
15491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                    0, new Caller(callingPackage, Binder.getCallingUid()), commands);
15591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            SomeArgs args = mHandlerCaller.sendMessageAndWait(msg);
15691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            if (args != null) {
15791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                boolean[] res = (boolean[])args.arg1;
15891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                args.recycle();
15991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                return res;
16091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            }
16191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            return new boolean[commands.length];
16291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        }
16391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn    };
16491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn
16591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn    final IVoiceInteractionSession mSession = new IVoiceInteractionSession.Stub() {
166c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        @Override
167ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn        public void show(Bundle sessionArgs, int flags) {
168ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn            mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageIO(MSG_SHOW,
169ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn                    flags, sessionArgs));
170ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn        }
171ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn
172ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn        @Override
173ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn        public void hide() {
174ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn            mHandlerCaller.sendMessage(mHandlerCaller.obtainMessage(MSG_HIDE));
175ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn        }
176ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn
177ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn        @Override
178ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn        public void handleAssist(Bundle assistBundle) {
1795688b03f7f4fafd671451ff73103be0f2388b32eDianne Hackborn            // We want to pre-warm the AssistStructure before handing it off to the main
1805688b03f7f4fafd671451ff73103be0f2388b32eDianne Hackborn            // thread.  There is a strong argument to be made that it should be handed
1815688b03f7f4fafd671451ff73103be0f2388b32eDianne Hackborn            // through as a separate param rather than part of the assistBundle.
1825688b03f7f4fafd671451ff73103be0f2388b32eDianne Hackborn            if (assistBundle != null) {
1835688b03f7f4fafd671451ff73103be0f2388b32eDianne Hackborn                Bundle assistContext = assistBundle.getBundle(Intent.EXTRA_ASSIST_CONTEXT);
1845688b03f7f4fafd671451ff73103be0f2388b32eDianne Hackborn                if (assistContext != null) {
1855688b03f7f4fafd671451ff73103be0f2388b32eDianne Hackborn                    AssistStructure as = AssistStructure.getAssistStructure(assistContext);
1865688b03f7f4fafd671451ff73103be0f2388b32eDianne Hackborn                    if (as != null) {
1875688b03f7f4fafd671451ff73103be0f2388b32eDianne Hackborn                        as.ensureData();
1885688b03f7f4fafd671451ff73103be0f2388b32eDianne Hackborn                    }
1895688b03f7f4fafd671451ff73103be0f2388b32eDianne Hackborn                }
1905688b03f7f4fafd671451ff73103be0f2388b32eDianne Hackborn            }
191ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn            mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageO(MSG_HANDLE_ASSIST,
192ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn                    assistBundle));
193ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn        }
194ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn
195ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn        @Override
19627eac1d58fe0b7ca3a2e27f5ed64eff232745f45Dianne Hackborn        public void handleScreenshot(Bitmap screenshot) {
19727eac1d58fe0b7ca3a2e27f5ed64eff232745f45Dianne Hackborn            mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageO(MSG_HANDLE_SCREENSHOT,
19827eac1d58fe0b7ca3a2e27f5ed64eff232745f45Dianne Hackborn                    screenshot));
19927eac1d58fe0b7ca3a2e27f5ed64eff232745f45Dianne Hackborn        }
20027eac1d58fe0b7ca3a2e27f5ed64eff232745f45Dianne Hackborn
20127eac1d58fe0b7ca3a2e27f5ed64eff232745f45Dianne Hackborn        @Override
202c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        public void taskStarted(Intent intent, int taskId) {
203c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn            mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageIO(MSG_TASK_STARTED,
204c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                    taskId, intent));
205c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        }
206c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
207c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        @Override
208c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        public void taskFinished(Intent intent, int taskId) {
209c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn            mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageIO(MSG_TASK_FINISHED,
210c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                    taskId, intent));
211c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        }
212c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
213c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        @Override
214c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        public void closeSystemDialogs() {
215c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn            mHandlerCaller.sendMessage(mHandlerCaller.obtainMessage(MSG_CLOSE_SYSTEM_DIALOGS));
216c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        }
217c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
218c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        @Override
219c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        public void destroy() {
220c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn            mHandlerCaller.sendMessage(mHandlerCaller.obtainMessage(MSG_DESTROY));
221c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        }
22291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn    };
22391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn
22491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn    public static class Request {
22591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        final IVoiceInteractorRequest mInterface = new IVoiceInteractorRequest.Stub() {
22691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            @Override
22791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            public void cancel() throws RemoteException {
228a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn                VoiceInteractionSession session = mSession.get();
229a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn                if (session != null) {
230a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn                    session.mHandlerCaller.sendMessage(
231a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn                            session.mHandlerCaller.obtainMessageO(MSG_CANCEL, Request.this));
232a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn                }
23391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            }
23491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        };
23591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        final IVoiceInteractorCallback mCallback;
236a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn        final WeakReference<VoiceInteractionSession> mSession;
237a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn
238a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn        Request(IVoiceInteractorCallback callback, VoiceInteractionSession session) {
23991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            mCallback = callback;
240a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn            mSession = session.mWeakRef;
241a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn        }
242a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn
243a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn        void finishRequest() {
244a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn            VoiceInteractionSession session = mSession.get();
245a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn            if (session == null) {
246a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn                throw new IllegalStateException("VoiceInteractionSession has been destroyed");
247a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn            }
248a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn            Request req = session.removeRequest(mInterface.asBinder());
249a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn            if (req == null) {
250a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn                throw new IllegalStateException("Request not active: " + this);
251a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn            } else if (req != this) {
252a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn                throw new IllegalStateException("Current active request " + req
253a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn                        + " not same as calling request " + this);
254a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn            }
25591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        }
25691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn
25791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        public void sendConfirmResult(boolean confirmed, Bundle result) {
25891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            try {
25991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                if (DEBUG) Log.d(TAG, "sendConfirmResult: req=" + mInterface
26091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                        + " confirmed=" + confirmed + " result=" + result);
261a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn                finishRequest();
26291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                mCallback.deliverConfirmationResult(mInterface, confirmed, result);
26391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            } catch (RemoteException e) {
26491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            }
26591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        }
26691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn
2673d07c94c393831091958fe6a98811843db8973bdDianne Hackborn        public void sendPickOptionResult(boolean finished,
2683d07c94c393831091958fe6a98811843db8973bdDianne Hackborn                VoiceInteractor.PickOptionRequest.Option[] selections, Bundle result) {
2693d07c94c393831091958fe6a98811843db8973bdDianne Hackborn            try {
2703d07c94c393831091958fe6a98811843db8973bdDianne Hackborn                if (DEBUG) Log.d(TAG, "sendPickOptionResult: req=" + mInterface
2713d07c94c393831091958fe6a98811843db8973bdDianne Hackborn                        + " finished=" + finished + " selections=" + selections
2723d07c94c393831091958fe6a98811843db8973bdDianne Hackborn                        + " result=" + result);
2733d07c94c393831091958fe6a98811843db8973bdDianne Hackborn                if (finished) {
2743d07c94c393831091958fe6a98811843db8973bdDianne Hackborn                    finishRequest();
2753d07c94c393831091958fe6a98811843db8973bdDianne Hackborn                }
2763d07c94c393831091958fe6a98811843db8973bdDianne Hackborn                mCallback.deliverPickOptionResult(mInterface, finished, selections, result);
2773d07c94c393831091958fe6a98811843db8973bdDianne Hackborn            } catch (RemoteException e) {
2783d07c94c393831091958fe6a98811843db8973bdDianne Hackborn            }
2793d07c94c393831091958fe6a98811843db8973bdDianne Hackborn        }
2803d07c94c393831091958fe6a98811843db8973bdDianne Hackborn
281d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James        public void sendCompleteVoiceResult(Bundle result) {
282d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James            try {
283d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James                if (DEBUG) Log.d(TAG, "sendCompleteVoiceResult: req=" + mInterface
284d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James                        + " result=" + result);
285d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James                finishRequest();
286d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James                mCallback.deliverCompleteVoiceResult(mInterface, result);
287d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James            } catch (RemoteException e) {
288d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James            }
289d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James        }
290d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James
291a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn        public void sendAbortVoiceResult(Bundle result) {
292a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn            try {
293a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn                if (DEBUG) Log.d(TAG, "sendConfirmResult: req=" + mInterface
294a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn                        + " result=" + result);
295a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn                finishRequest();
296a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn                mCallback.deliverAbortVoiceResult(mInterface, result);
297a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn            } catch (RemoteException e) {
298a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn            }
299a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn        }
300a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn
3013d07c94c393831091958fe6a98811843db8973bdDianne Hackborn        public void sendCommandResult(boolean finished, Bundle result) {
30291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            try {
30391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                if (DEBUG) Log.d(TAG, "sendCommandResult: req=" + mInterface
30491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                        + " result=" + result);
3053d07c94c393831091958fe6a98811843db8973bdDianne Hackborn                if (finished) {
3063d07c94c393831091958fe6a98811843db8973bdDianne Hackborn                    finishRequest();
3073d07c94c393831091958fe6a98811843db8973bdDianne Hackborn                }
3083d07c94c393831091958fe6a98811843db8973bdDianne Hackborn                mCallback.deliverCommandResult(mInterface, finished, result);
30991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            } catch (RemoteException e) {
31091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            }
31191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        }
31291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn
31391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        public void sendCancelResult() {
31491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            try {
31591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                if (DEBUG) Log.d(TAG, "sendCancelResult: req=" + mInterface);
316a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn                finishRequest();
31791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                mCallback.deliverCancel(mInterface);
31891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            } catch (RemoteException e) {
31991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            }
32091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        }
32191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn    }
32291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn
32391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn    public static class Caller {
32491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        final String packageName;
32591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        final int uid;
32691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn
32791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        Caller(String _packageName, int _uid) {
32891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            packageName = _packageName;
32991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            uid = _uid;
33091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        }
33191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn    }
33291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn
33391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn    static final int MSG_START_CONFIRMATION = 1;
3343d07c94c393831091958fe6a98811843db8973bdDianne Hackborn    static final int MSG_START_PICK_OPTION = 2;
3353d07c94c393831091958fe6a98811843db8973bdDianne Hackborn    static final int MSG_START_COMPLETE_VOICE = 3;
3363d07c94c393831091958fe6a98811843db8973bdDianne Hackborn    static final int MSG_START_ABORT_VOICE = 4;
3373d07c94c393831091958fe6a98811843db8973bdDianne Hackborn    static final int MSG_START_COMMAND = 5;
3383d07c94c393831091958fe6a98811843db8973bdDianne Hackborn    static final int MSG_SUPPORTS_COMMANDS = 6;
3393d07c94c393831091958fe6a98811843db8973bdDianne Hackborn    static final int MSG_CANCEL = 7;
34091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn
341c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    static final int MSG_TASK_STARTED = 100;
342c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    static final int MSG_TASK_FINISHED = 101;
343c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    static final int MSG_CLOSE_SYSTEM_DIALOGS = 102;
344c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    static final int MSG_DESTROY = 103;
345ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn    static final int MSG_HANDLE_ASSIST = 104;
34627eac1d58fe0b7ca3a2e27f5ed64eff232745f45Dianne Hackborn    static final int MSG_HANDLE_SCREENSHOT = 105;
34727eac1d58fe0b7ca3a2e27f5ed64eff232745f45Dianne Hackborn    static final int MSG_SHOW = 106;
34827eac1d58fe0b7ca3a2e27f5ed64eff232745f45Dianne Hackborn    static final int MSG_HIDE = 107;
349c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
350c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    class MyCallbacks implements HandlerCaller.Callback, SoftInputWindow.Callback {
35191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        @Override
35291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        public void executeMessage(Message msg) {
353c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn            SomeArgs args;
35491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            switch (msg.what) {
35591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                case MSG_START_CONFIRMATION:
356c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                    args = (SomeArgs)msg.obj;
35791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                    if (DEBUG) Log.d(TAG, "onConfirm: req=" + ((Request) args.arg2).mInterface
35891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                            + " prompt=" + args.arg3 + " extras=" + args.arg4);
359a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn                    onConfirm((Caller)args.arg1, (Request)args.arg2, (CharSequence)args.arg3,
36091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                            (Bundle)args.arg4);
36191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                    break;
3623d07c94c393831091958fe6a98811843db8973bdDianne Hackborn                case MSG_START_PICK_OPTION:
3633d07c94c393831091958fe6a98811843db8973bdDianne Hackborn                    args = (SomeArgs)msg.obj;
3643d07c94c393831091958fe6a98811843db8973bdDianne Hackborn                    if (DEBUG) Log.d(TAG, "onPickOption: req=" + ((Request) args.arg2).mInterface
3653d07c94c393831091958fe6a98811843db8973bdDianne Hackborn                            + " prompt=" + args.arg3 + " options=" + args.arg4
3663d07c94c393831091958fe6a98811843db8973bdDianne Hackborn                            + " extras=" + args.arg5);
3673d07c94c393831091958fe6a98811843db8973bdDianne Hackborn                    onPickOption((Caller)args.arg1, (Request)args.arg2, (CharSequence)args.arg3,
3683d07c94c393831091958fe6a98811843db8973bdDianne Hackborn                            (VoiceInteractor.PickOptionRequest.Option[])args.arg4,
3693d07c94c393831091958fe6a98811843db8973bdDianne Hackborn                            (Bundle)args.arg5);
3703d07c94c393831091958fe6a98811843db8973bdDianne Hackborn                    break;
371d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James                case MSG_START_COMPLETE_VOICE:
372d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James                    args = (SomeArgs)msg.obj;
373d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James                    if (DEBUG) Log.d(TAG, "onCompleteVoice: req=" + ((Request) args.arg2).mInterface
374d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James                            + " message=" + args.arg3 + " extras=" + args.arg4);
375d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James                    onCompleteVoice((Caller) args.arg1, (Request) args.arg2,
376d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James                            (CharSequence) args.arg3, (Bundle) args.arg4);
377d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James                    break;
378a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn                case MSG_START_ABORT_VOICE:
379a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn                    args = (SomeArgs)msg.obj;
380a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn                    if (DEBUG) Log.d(TAG, "onAbortVoice: req=" + ((Request) args.arg2).mInterface
381a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn                            + " message=" + args.arg3 + " extras=" + args.arg4);
382a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn                    onAbortVoice((Caller) args.arg1, (Request) args.arg2, (CharSequence) args.arg3,
383a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn                            (Bundle) args.arg4);
384a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn                    break;
38591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                case MSG_START_COMMAND:
386c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                    args = (SomeArgs)msg.obj;
38791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                    if (DEBUG) Log.d(TAG, "onCommand: req=" + ((Request) args.arg2).mInterface
38891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                            + " command=" + args.arg3 + " extras=" + args.arg4);
38991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                    onCommand((Caller) args.arg1, (Request) args.arg2, (String) args.arg3,
39091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                            (Bundle) args.arg4);
39191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                    break;
39291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                case MSG_SUPPORTS_COMMANDS:
393c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                    args = (SomeArgs)msg.obj;
39491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                    if (DEBUG) Log.d(TAG, "onGetSupportedCommands: cmds=" + args.arg2);
39591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                    args.arg1 = onGetSupportedCommands((Caller) args.arg1, (String[]) args.arg2);
39691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                    break;
39791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                case MSG_CANCEL:
398ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn                    if (DEBUG) Log.d(TAG, "onCancel: req=" + ((Request)msg.obj));
399ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn                    onCancel((Request)msg.obj);
40091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                    break;
401c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                case MSG_TASK_STARTED:
402c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                    if (DEBUG) Log.d(TAG, "onTaskStarted: intent=" + msg.obj
403c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                            + " taskId=" + msg.arg1);
404c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                    onTaskStarted((Intent) msg.obj, msg.arg1);
405c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                    break;
406c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                case MSG_TASK_FINISHED:
407c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                    if (DEBUG) Log.d(TAG, "onTaskFinished: intent=" + msg.obj
408c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                            + " taskId=" + msg.arg1);
409c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                    onTaskFinished((Intent) msg.obj, msg.arg1);
410c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                    break;
411c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                case MSG_CLOSE_SYSTEM_DIALOGS:
412c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                    if (DEBUG) Log.d(TAG, "onCloseSystemDialogs");
413c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                    onCloseSystemDialogs();
414c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                    break;
415c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                case MSG_DESTROY:
416c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                    if (DEBUG) Log.d(TAG, "doDestroy");
417c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                    doDestroy();
418c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                    break;
419ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn                case MSG_HANDLE_ASSIST:
42027eac1d58fe0b7ca3a2e27f5ed64eff232745f45Dianne Hackborn                    if (DEBUG) Log.d(TAG, "onHandleAssist: " + msg.obj);
421ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn                    onHandleAssist((Bundle) msg.obj);
422ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn                    break;
42327eac1d58fe0b7ca3a2e27f5ed64eff232745f45Dianne Hackborn                case MSG_HANDLE_SCREENSHOT:
42427eac1d58fe0b7ca3a2e27f5ed64eff232745f45Dianne Hackborn                    if (DEBUG) Log.d(TAG, "onHandleScreenshot: " + msg.obj);
42527eac1d58fe0b7ca3a2e27f5ed64eff232745f45Dianne Hackborn                    onHandleScreenshot((Bitmap) msg.obj);
42627eac1d58fe0b7ca3a2e27f5ed64eff232745f45Dianne Hackborn                    break;
427ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn                case MSG_SHOW:
428ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn                    if (DEBUG) Log.d(TAG, "doShow: args=" + msg.obj
429ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn                            + " flags=" + msg.arg1);
430ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn                    doShow((Bundle) msg.obj, msg.arg1);
431ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn                    break;
432ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn                case MSG_HIDE:
433ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn                    if (DEBUG) Log.d(TAG, "doHide");
434ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn                    doHide();
435ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn                    break;
43691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            }
43791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        }
43891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn
439c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        @Override
440c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        public void onBackPressed() {
441c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn            VoiceInteractionSession.this.onBackPressed();
442c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        }
443c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    }
444c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
445c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    final MyCallbacks mCallbacks = new MyCallbacks();
446c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
447c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    /**
448c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn     * Information about where interesting parts of the input method UI appear.
449c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn     */
450c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    public static final class Insets {
451c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        /**
452e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn         * This is the part of the UI that is the main content.  It is
453c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn         * used to determine the basic space needed, to resize/pan the
454c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn         * application behind.  It is assumed that this inset does not
455c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn         * change very much, since any change will cause a full resize/pan
456c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn         * of the application behind.  This value is relative to the top edge
457c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn         * of the input method window.
458c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn         */
459e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn        public final Rect contentInsets = new Rect();
460c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
461c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        /**
462c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn         * This is the region of the UI that is touchable.  It is used when
463c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn         * {@link #touchableInsets} is set to {@link #TOUCHABLE_INSETS_REGION}.
464c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn         * The region should be specified relative to the origin of the window frame.
465c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn         */
466c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        public final Region touchableRegion = new Region();
467c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
468c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        /**
469c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn         * Option for {@link #touchableInsets}: the entire window frame
470c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn         * can be touched.
471c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn         */
472c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        public static final int TOUCHABLE_INSETS_FRAME
473c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME;
474c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
475c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        /**
476c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn         * Option for {@link #touchableInsets}: the area inside of
477c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn         * the content insets can be touched.
478c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn         */
479c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        public static final int TOUCHABLE_INSETS_CONTENT
480c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT;
481c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
482c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        /**
483c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn         * Option for {@link #touchableInsets}: the region specified by
484c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn         * {@link #touchableRegion} can be touched.
485c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn         */
486c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        public static final int TOUCHABLE_INSETS_REGION
487c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION;
488c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
489c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        /**
490c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn         * Determine which area of the window is touchable by the user.  May
491c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn         * be one of: {@link #TOUCHABLE_INSETS_FRAME},
492c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn         * {@link #TOUCHABLE_INSETS_CONTENT}, or {@link #TOUCHABLE_INSETS_REGION}.
493c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn         */
494c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        public int touchableInsets;
495c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    }
496c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
497c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    final ViewTreeObserver.OnComputeInternalInsetsListener mInsetsComputer =
498c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn            new ViewTreeObserver.OnComputeInternalInsetsListener() {
499c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        public void onComputeInternalInsets(ViewTreeObserver.InternalInsetsInfo info) {
500c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn            onComputeInsets(mTmpInsets);
501e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn            info.contentInsets.set(mTmpInsets.contentInsets);
502e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn            info.visibleInsets.set(mTmpInsets.contentInsets);
503c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn            info.touchableRegion.set(mTmpInsets.touchableRegion);
504c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn            info.setTouchableInsets(mTmpInsets.touchableInsets);
505c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        }
506c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    };
50791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn
50891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn    public VoiceInteractionSession(Context context) {
50991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        this(context, new Handler());
51091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn    }
51191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn
51291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn    public VoiceInteractionSession(Context context, Handler handler) {
51391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        mContext = context;
51491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        mHandlerCaller = new HandlerCaller(context, handler.getLooper(),
515c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                mCallbacks, true);
51691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn    }
51791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn
518a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn    Request newRequest(IVoiceInteractorCallback callback) {
519a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn        synchronized (this) {
520a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn            Request req = new Request(callback, this);
521a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn            mActiveRequests.put(req.mInterface.asBinder(), req);
522a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn            return req;
523a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn        }
524a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn    }
525a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn
526a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn    Request removeRequest(IBinder reqInterface) {
52791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        synchronized (this) {
5288ef92bd311e6faf602c9705db663abd451590fffAndreas Gampe            return mActiveRequests.remove(reqInterface);
52991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        }
53091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn    }
53191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn
532ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn    void doCreate(IVoiceInteractionManagerService service, IBinder token, Bundle args,
533ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn            int startFlags) {
534c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        mSystemService = service;
535c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        mToken = token;
536ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn        onCreate(args, startFlags);
537c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    }
538c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
539ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn    void doShow(Bundle args, int flags) {
540ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn        if (DEBUG) Log.v(TAG, "Showing window: mWindowAdded=" + mWindowAdded
541ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn                + " mWindowVisible=" + mWindowVisible);
542ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn
543ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn        if (mInShowWindow) {
544ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn            Log.w(TAG, "Re-entrance in to showWindow");
545ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn            return;
546ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn        }
547ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn
548ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn        try {
549ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn            mInShowWindow = true;
550ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn            if (!mWindowVisible) {
551ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn                if (!mWindowAdded) {
552ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn                    mWindowAdded = true;
553ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn                    View v = onCreateContentView();
554ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn                    if (v != null) {
555ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn                        setContentView(v);
556ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn                    }
557ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn                }
558ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn            }
559ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn            onShow(args, flags);
560ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn            if (!mWindowVisible) {
561ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn                mWindowVisible = true;
562ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn                mWindow.show();
563ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn            }
564ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn        } finally {
565ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn            mWindowWasVisible = true;
566ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn            mInShowWindow = false;
567ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn        }
568ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn    }
569ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn
570ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn    void doHide() {
571ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn        if (mWindowVisible) {
572ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn            mWindow.hide();
573ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn            mWindowVisible = false;
574ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn            onHide();
575ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn        }
576ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn    }
577ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn
578c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    void doDestroy() {
5799a35d78cad1a4cf9639053c24139147e658ec055Dianne Hackborn        onDestroy();
580c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        if (mInitialized) {
581c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn            mRootView.getViewTreeObserver().removeOnComputeInternalInsetsListener(
582c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                    mInsetsComputer);
583c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn            if (mWindowAdded) {
584c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                mWindow.dismiss();
585c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                mWindowAdded = false;
586c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn            }
587c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn            mInitialized = false;
588c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        }
589c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    }
590c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
591c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    void initViews() {
592c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        mInitialized = true;
593c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
594c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        mThemeAttrs = mContext.obtainStyledAttributes(android.R.styleable.VoiceInteractionSession);
595c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        mRootView = mInflater.inflate(
596c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                com.android.internal.R.layout.voice_interaction_session, null);
597c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        mRootView.setSystemUiVisibility(
598c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
599c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        mWindow.setContentView(mRootView);
600c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        mRootView.getViewTreeObserver().addOnComputeInternalInsetsListener(mInsetsComputer);
601c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
602c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        mContentFrame = (FrameLayout)mRootView.findViewById(android.R.id.content);
603c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    }
604c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
605ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn    public void show() {
606ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn        try {
607ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn            mSystemService.showSessionFromSession(mToken, null, 0);
608ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn        } catch (RemoteException e) {
609c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        }
610ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn    }
611c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
612ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn    public void hide() {
613c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        try {
614ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn            mSystemService.hideSessionFromSession(mToken);
615ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn        } catch (RemoteException e) {
616c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        }
617c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    }
618c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
619ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn    /** TODO: remove */
620ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn    public void showWindow() {
621ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn    }
622ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn
623ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn    /** TODO: remove */
624c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    public void hideWindow() {
625c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    }
626c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
627c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    /**
628c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn     * You can call this to customize the theme used by your IME's window.
629c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn     * This must be set before {@link #onCreate}, so you
630c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn     * will typically call it in your constructor with the resource ID
631c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn     * of your custom theme.
632c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn     */
633c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    public void setTheme(int theme) {
634c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        if (mWindow != null) {
635c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn            throw new IllegalStateException("Must be called before onCreate()");
636c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        }
637c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        mTheme = theme;
638c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    }
639c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
640a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn    /**
641a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * Ask that a new activity be started for voice interaction.  This will create a
642a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * new dedicated task in the activity manager for this voice interaction session;
643a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * this means that {@link Intent#FLAG_ACTIVITY_NEW_TASK Intent.FLAG_ACTIVITY_NEW_TASK}
644a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * will be set for you to make it a new task.
645a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     *
646a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * <p>The newly started activity will be displayed to the user in a special way, as
647a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * a layer under the voice interaction UI.</p>
648a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     *
649a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * <p>As the voice activity runs, it can retrieve a {@link android.app.VoiceInteractor}
650a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * through which it can perform voice interactions through your session.  These requests
651a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * for voice interactions will appear as callbacks on {@link #onGetSupportedCommands},
652a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * {@link #onConfirm}, {@link #onCommand}, and {@link #onCancel}.
653a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     *
654a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * <p>You will receive a call to {@link #onTaskStarted} when the task starts up
655a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * and {@link #onTaskFinished} when the last activity has finished.
656a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     *
657a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * @param intent The Intent to start this voice interaction.  The given Intent will
658a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * always have {@link Intent#CATEGORY_VOICE Intent.CATEGORY_VOICE} added to it, since
659a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * this is part of a voice interaction.
660a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     */
661c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    public void startVoiceActivity(Intent intent) {
662c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        if (mToken == null) {
663c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn            throw new IllegalStateException("Can't call before onCreate()");
664c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        }
665c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        try {
666e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn            intent.migrateExtraStreamToClipData();
667e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn            intent.prepareToLeaveProcess();
668c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn            int res = mSystemService.startVoiceActivity(mToken, intent,
669c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                    intent.resolveType(mContext.getContentResolver()));
670c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn            Instrumentation.checkStartActivityResult(res, intent);
671c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        } catch (RemoteException e) {
672c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        }
673c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    }
674c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
675a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn    /**
6763d07c94c393831091958fe6a98811843db8973bdDianne Hackborn     * Set whether this session will keep the device awake while it is running a voice
6773d07c94c393831091958fe6a98811843db8973bdDianne Hackborn     * activity.  By default, the system holds a wake lock for it while in this state,
6783d07c94c393831091958fe6a98811843db8973bdDianne Hackborn     * so that it can work even if the screen is off.  Setting this to false removes that
6793d07c94c393831091958fe6a98811843db8973bdDianne Hackborn     * wake lock, allowing the CPU to go to sleep.  This is typically used if the
6803d07c94c393831091958fe6a98811843db8973bdDianne Hackborn     * session decides it has been waiting too long for a response from the user and
6813d07c94c393831091958fe6a98811843db8973bdDianne Hackborn     * doesn't want to let this continue to drain the battery.
6823d07c94c393831091958fe6a98811843db8973bdDianne Hackborn     *
6833d07c94c393831091958fe6a98811843db8973bdDianne Hackborn     * <p>Passing false here will release the wake lock, and you can call later with
6843d07c94c393831091958fe6a98811843db8973bdDianne Hackborn     * true to re-acquire it.  It will also be automatically re-acquired for you each
6853d07c94c393831091958fe6a98811843db8973bdDianne Hackborn     * time you start a new voice activity task -- that is when you call
6863d07c94c393831091958fe6a98811843db8973bdDianne Hackborn     * {@link #startVoiceActivity}.</p>
6873d07c94c393831091958fe6a98811843db8973bdDianne Hackborn     */
6883d07c94c393831091958fe6a98811843db8973bdDianne Hackborn    public void setKeepAwake(boolean keepAwake) {
6893d07c94c393831091958fe6a98811843db8973bdDianne Hackborn        try {
6903d07c94c393831091958fe6a98811843db8973bdDianne Hackborn            mSystemService.setKeepAwake(mToken, keepAwake);
6913d07c94c393831091958fe6a98811843db8973bdDianne Hackborn        } catch (RemoteException e) {
6923d07c94c393831091958fe6a98811843db8973bdDianne Hackborn        }
6933d07c94c393831091958fe6a98811843db8973bdDianne Hackborn    }
6943d07c94c393831091958fe6a98811843db8973bdDianne Hackborn
6953d07c94c393831091958fe6a98811843db8973bdDianne Hackborn    /**
696a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * Convenience for inflating views.
697a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     */
698c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    public LayoutInflater getLayoutInflater() {
699c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        return mInflater;
700c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    }
701c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
702a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn    /**
703a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * Retrieve the window being used to show the session's UI.
704a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     */
705c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    public Dialog getWindow() {
706c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        return mWindow;
707c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    }
708c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
709a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn    /**
710a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * Finish the session.
711a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     */
712c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    public void finish() {
713c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        if (mToken == null) {
714c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn            throw new IllegalStateException("Can't call before onCreate()");
715c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        }
716c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        hideWindow();
717c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        try {
718c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn            mSystemService.finish(mToken);
719c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        } catch (RemoteException e) {
720c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        }
721c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    }
722c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
723ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn    /** @hide */
724c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    public void onCreate(Bundle args) {
725c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        mTheme = mTheme != 0 ? mTheme
726c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                : com.android.internal.R.style.Theme_DeviceDefault_VoiceInteractionSession;
727c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        mInflater = (LayoutInflater)mContext.getSystemService(
728c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                Context.LAYOUT_INFLATER_SERVICE);
729c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        mWindow = new SoftInputWindow(mContext, "VoiceInteractionSession", mTheme,
730e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn                mCallbacks, this, mDispatcherState,
731ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn                WindowManager.LayoutParams.TYPE_VOICE_INTERACTION, Gravity.BOTTOM, true);
732c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        mWindow.getWindow().addFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
733c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        initViews();
734ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn        mWindow.getWindow().setLayout(MATCH_PARENT, MATCH_PARENT);
735c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        mWindow.setToken(mToken);
736c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    }
737c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
738a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn    /**
739ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn     * Initiatize a new session.  The given args and showFlags are the initial values
740ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn     * passed to {@link VoiceInteractionService#showSession VoiceInteractionService.showSession},
741ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn     * if possible.  Normally you should handle these in {@link #onShow}.
742ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn     */
743ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn    public void onCreate(Bundle args, int showFlags) {
744ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn        onCreate(args);
745ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn    }
746ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn
747ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn    /**
748ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn     * Called when the session UI is going to be shown.  This is called after
749ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn     * {@link #onCreateContentView} (if the session's content UI needed to be created) and
750ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn     * immediately prior to the window being shown.  This may be called while the window
751ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn     * is already shown, if a show request has come in while it is shown, to allow you to
752ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn     * update the UI to match the new show arguments.
753ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn     *
754ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn     * @param args The arguments that were supplied to
755ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn     * {@link VoiceInteractionService#showSession VoiceInteractionService.showSession}.
756ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn     * @param showFlags The show flags originally provided to
757ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn     * {@link VoiceInteractionService#showSession VoiceInteractionService.showSession}.
758ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn     */
759ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn    public void onShow(Bundle args, int showFlags) {
760ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn    }
761ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn
762ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn    /**
763ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn     * Called immediately after stopping to show the session UI.
764ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn     */
765ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn    public void onHide() {
766ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn    }
767ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn
768ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn    /**
769a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * Last callback to the session as it is being finished.
770a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     */
771c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    public void onDestroy() {
772c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    }
773c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
774a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn    /**
775a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * Hook in which to create the session's UI.
776a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     */
777c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    public View onCreateContentView() {
778c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        return null;
779c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    }
780c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
781c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    public void setContentView(View view) {
782c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        mContentFrame.removeAllViews();
783c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        mContentFrame.addView(view, new FrameLayout.LayoutParams(
784c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn                ViewGroup.LayoutParams.MATCH_PARENT,
785ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn                ViewGroup.LayoutParams.MATCH_PARENT));
786c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
787c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    }
788c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
789ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn    public void onHandleAssist(Bundle assistBundle) {
790ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn    }
791ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn
79227eac1d58fe0b7ca3a2e27f5ed64eff232745f45Dianne Hackborn    public void onHandleScreenshot(Bitmap screenshot) {
79327eac1d58fe0b7ca3a2e27f5ed64eff232745f45Dianne Hackborn    }
79427eac1d58fe0b7ca3a2e27f5ed64eff232745f45Dianne Hackborn
795c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    public boolean onKeyDown(int keyCode, KeyEvent event) {
796c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        return false;
797c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    }
798c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
799c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    public boolean onKeyLongPress(int keyCode, KeyEvent event) {
800c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        return false;
801c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    }
802c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
803c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    public boolean onKeyUp(int keyCode, KeyEvent event) {
804c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        return false;
805c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    }
806c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
807c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    public boolean onKeyMultiple(int keyCode, int count, KeyEvent event) {
808c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        return false;
809c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    }
810c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
811c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    public void onBackPressed() {
812ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn        hide();
813c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    }
814c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
815a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn    /**
816a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * Sessions automatically watch for requests that all system UI be closed (such as when
817a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * the user presses HOME), which will appear here.  The default implementation always
818a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * calls {@link #finish}.
819a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     */
820c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    public void onCloseSystemDialogs() {
821ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn        hide();
822c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    }
823c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
824c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    /**
825c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn     * Compute the interesting insets into your UI.  The default implementation
826ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn     * sets {@link Insets#contentInsets outInsets.contentInsets.top} to the height
827ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn     * of the window, meaning it should not adjust content underneath.  The default touchable
828ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn     * insets are {@link Insets#TOUCHABLE_INSETS_FRAME}, meaning it consumes all touch
829ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn     * events within its window frame.
830c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn     *
831c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn     * @param outInsets Fill in with the current UI insets.
832c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn     */
833c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    public void onComputeInsets(Insets outInsets) {
834e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn        outInsets.contentInsets.left = 0;
835e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn        outInsets.contentInsets.bottom = 0;
836ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn        outInsets.contentInsets.right = 0;
837ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn        View decor = getWindow().getWindow().getDecorView();
838ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn        outInsets.contentInsets.top = decor.getHeight();
839c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        outInsets.touchableInsets = Insets.TOUCHABLE_INSETS_FRAME;
840c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn        outInsets.touchableRegion.setEmpty();
841c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    }
842c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
843a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn    /**
844a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * Called when a task initiated by {@link #startVoiceActivity(android.content.Intent)}
845a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * has actually started.
846a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     *
847a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * @param intent The original {@link Intent} supplied to
848a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * {@link #startVoiceActivity(android.content.Intent)}.
849a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * @param taskId Unique ID of the now running task.
850a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     */
851c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    public void onTaskStarted(Intent intent, int taskId) {
852c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    }
853c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
854a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn    /**
855a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * Called when the last activity of a task initiated by
856a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * {@link #startVoiceActivity(android.content.Intent)} has finished.  The default
857a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * implementation calls {@link #finish()} on the assumption that this represents
858a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * the completion of a voice action.  You can override the implementation if you would
859a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * like a different behavior.
860a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     *
861a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * @param intent The original {@link Intent} supplied to
862a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * {@link #startVoiceActivity(android.content.Intent)}.
863a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * @param taskId Unique ID of the finished task.
864a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     */
865c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    public void onTaskFinished(Intent intent, int taskId) {
866ffeecb1bfb9b71f4b62c9ef1fbf7b58a7a63f655Dianne Hackborn        hide();
867c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn    }
868c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn
869a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn    /**
870a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * Request to query for what extended commands the session supports.
871a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     *
872a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * @param caller Who is making the request.
873a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * @param commands An array of commands that are being queried.
874a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * @return Return an array of booleans indicating which of each entry in the
875a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * command array is supported.  A true entry in the array indicates the command
876a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * is supported; false indicates it is not.  The default implementation returns
877a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * an array of all false entries.
878a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     */
879a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn    public boolean[] onGetSupportedCommands(Caller caller, String[] commands) {
880a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn        return new boolean[commands.length];
881a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn    }
882a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn
883a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn    /**
884a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * Request to confirm with the user before proceeding with an unrecoverable operation,
885a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * corresponding to a {@link android.app.VoiceInteractor.ConfirmationRequest
886a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * VoiceInteractor.ConfirmationRequest}.
887a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     *
888a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * @param caller Who is making the request.
889a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * @param request The active request.
890a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * @param prompt The prompt informing the user of what will happen, as per
891a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * {@link android.app.VoiceInteractor.ConfirmationRequest VoiceInteractor.ConfirmationRequest}.
892a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * @param extras Any additional information, as per
893a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * {@link android.app.VoiceInteractor.ConfirmationRequest VoiceInteractor.ConfirmationRequest}.
894a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     */
895a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn    public abstract void onConfirm(Caller caller, Request request, CharSequence prompt,
896a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn            Bundle extras);
897a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn
898a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn    /**
8993d07c94c393831091958fe6a98811843db8973bdDianne Hackborn     * Request for the user to pick one of N options, corresponding to a
9003d07c94c393831091958fe6a98811843db8973bdDianne Hackborn     * {@link android.app.VoiceInteractor.PickOptionRequest VoiceInteractor.PickOptionRequest}.
9013d07c94c393831091958fe6a98811843db8973bdDianne Hackborn     *
9023d07c94c393831091958fe6a98811843db8973bdDianne Hackborn     * @param caller Who is making the request.
9033d07c94c393831091958fe6a98811843db8973bdDianne Hackborn     * @param request The active request.
9043d07c94c393831091958fe6a98811843db8973bdDianne Hackborn     * @param prompt The prompt informing the user of what they are picking, as per
9053d07c94c393831091958fe6a98811843db8973bdDianne Hackborn     * {@link android.app.VoiceInteractor.PickOptionRequest VoiceInteractor.PickOptionRequest}.
9063d07c94c393831091958fe6a98811843db8973bdDianne Hackborn     * @param options The set of options the user is picking from, as per
9073d07c94c393831091958fe6a98811843db8973bdDianne Hackborn     * {@link android.app.VoiceInteractor.PickOptionRequest VoiceInteractor.PickOptionRequest}.
9083d07c94c393831091958fe6a98811843db8973bdDianne Hackborn     * @param extras Any additional information, as per
9093d07c94c393831091958fe6a98811843db8973bdDianne Hackborn     * {@link android.app.VoiceInteractor.PickOptionRequest VoiceInteractor.PickOptionRequest}.
9103d07c94c393831091958fe6a98811843db8973bdDianne Hackborn     */
9113d07c94c393831091958fe6a98811843db8973bdDianne Hackborn    public abstract void onPickOption(Caller caller, Request request, CharSequence prompt,
9123d07c94c393831091958fe6a98811843db8973bdDianne Hackborn            VoiceInteractor.PickOptionRequest.Option[] options, Bundle extras);
9133d07c94c393831091958fe6a98811843db8973bdDianne Hackborn
9143d07c94c393831091958fe6a98811843db8973bdDianne Hackborn    /**
915d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James     * Request to complete the voice interaction session because the voice activity successfully
916d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James     * completed its interaction using voice.  Corresponds to
917d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James     * {@link android.app.VoiceInteractor.CompleteVoiceRequest
918d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James     * VoiceInteractor.CompleteVoiceRequest}.  The default implementation just sends an empty
919d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James     * confirmation back to allow the activity to exit.
920d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James     *
921d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James     * @param caller Who is making the request.
922d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James     * @param request The active request.
923d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James     * @param message The message informing the user of the problem, as per
924d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James     * {@link android.app.VoiceInteractor.CompleteVoiceRequest
925d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James     * VoiceInteractor.CompleteVoiceRequest}.
926d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James     * @param extras Any additional information, as per
927d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James     * {@link android.app.VoiceInteractor.CompleteVoiceRequest
928d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James     * VoiceInteractor.CompleteVoiceRequest}.
929d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James     */
930d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James    public void onCompleteVoice(Caller caller, Request request, CharSequence message,
931d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James           Bundle extras) {
932d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James        request.sendCompleteVoiceResult(null);
933d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James    }
934d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James
935d3fdb8bed8e836786253f9cd5ab640c7c5ed8501Barnaby James    /**
936a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * Request to abort the voice interaction session because the voice activity can not
937a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * complete its interaction using voice.  Corresponds to
938a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * {@link android.app.VoiceInteractor.AbortVoiceRequest
939a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * VoiceInteractor.AbortVoiceRequest}.  The default implementation just sends an empty
940a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * confirmation back to allow the activity to exit.
941a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     *
942a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * @param caller Who is making the request.
943a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * @param request The active request.
944a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * @param message The message informing the user of the problem, as per
945a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * {@link android.app.VoiceInteractor.AbortVoiceRequest VoiceInteractor.AbortVoiceRequest}.
946a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * @param extras Any additional information, as per
947a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * {@link android.app.VoiceInteractor.AbortVoiceRequest VoiceInteractor.AbortVoiceRequest}.
948a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     */
949a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn    public void onAbortVoice(Caller caller, Request request, CharSequence message, Bundle extras) {
950a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn        request.sendAbortVoiceResult(null);
951a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn    }
952a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn
953a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn    /**
954a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * Process an arbitrary extended command from the caller,
955a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * corresponding to a {@link android.app.VoiceInteractor.CommandRequest
956a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * VoiceInteractor.CommandRequest}.
957a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     *
958a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * @param caller Who is making the request.
959a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * @param request The active request.
960a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * @param command The command that is being executed, as per
961a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * {@link android.app.VoiceInteractor.CommandRequest VoiceInteractor.CommandRequest}.
962a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * @param extras Any additional information, as per
963a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * {@link android.app.VoiceInteractor.CommandRequest VoiceInteractor.CommandRequest}.
964a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     */
96591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn    public abstract void onCommand(Caller caller, Request request, String command, Bundle extras);
966a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn
967a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn    /**
968a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * Called when the {@link android.app.VoiceInteractor} has asked to cancel a {@link Request}
969a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * that was previously delivered to {@link #onConfirm} or {@link #onCommand}.
970a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     *
971a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     * @param request The request that is being canceled.
972a2c076d54048258cf88ab14551ce5fdf5a09c6e8Dianne Hackborn     */
97391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn    public abstract void onCancel(Request request);
97491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn}
975