/**
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.service.voice;

import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;

import android.annotation.CallbackExecutor;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.Activity;
import android.app.Dialog;
import android.app.DirectAction;
import android.app.Instrumentation;
import android.app.VoiceInteractor;
import android.app.assist.AssistContent;
import android.app.assist.AssistStructure;
import android.content.ComponentCallbacks2;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ParceledListSlice;
import android.content.res.Configuration;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.graphics.Region;
import android.inputmethodservice.SoftInputWindow;
import android.os.Binder;
import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.Handler;
import android.os.IBinder;
import android.os.ICancellationSignal;
import android.os.Message;
import android.os.RemoteCallback;
import android.os.RemoteException;
import android.os.UserHandle;
import android.util.ArrayMap;
import android.util.DebugUtils;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.WindowManager;
import android.widget.FrameLayout;

import com.android.internal.annotations.Immutable;
import com.android.internal.app.IVoiceInteractionManagerService;
import com.android.internal.app.IVoiceInteractionSessionShowCallback;
import com.android.internal.app.IVoiceInteractor;
import com.android.internal.app.IVoiceInteractorCallback;
import com.android.internal.app.IVoiceInteractorRequest;
import com.android.internal.os.HandlerCaller;
import com.android.internal.os.SomeArgs;
import com.android.internal.util.Preconditions;
import com.android.internal.util.function.pooled.PooledLambda;

import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.lang.ref.WeakReference;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executor;
import java.util.function.Consumer;

/**
 * An active voice interaction session, providing a facility for the implementation
 * to interact with the user in the voice interaction layer.  The user interface is
 * initially shown by default, and can be created be overriding {@link #onCreateContentView()}
 * in which the UI can be built.
 *
 * <p>A voice interaction session can be self-contained, ultimately calling {@link #finish}
 * when done.  It can also initiate voice interactions with applications by calling
 * {@link #startVoiceActivity}</p>.
 */
public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCallbacks2 {
    static final String TAG = "VoiceInteractionSession";
    static final boolean DEBUG = false;

    /**
     * Flag received in {@link #onShow}: originator requested that the session be started with
     * assist data from the currently focused activity.
     */
    public static final int SHOW_WITH_ASSIST = 1<<0;

    /**
     * Flag received in {@link #onShow}: originator requested that the session be started with
     * a screen shot of the currently focused activity.
     */
    public static final int SHOW_WITH_SCREENSHOT = 1<<1;

    /**
     * Flag for use with {@link #onShow}: indicates that the session has been started from the
     * system assist gesture.
     */
    public static final int SHOW_SOURCE_ASSIST_GESTURE = 1<<2;

    /**
     * Flag for use with {@link #onShow}: indicates that the application itself has invoked
     * the assistant.
     */
    public static final int SHOW_SOURCE_APPLICATION = 1<<3;

    /**
     * Flag for use with {@link #onShow}: indicates that an Activity has invoked the voice
     * interaction service for a local interaction using
     * {@link Activity#startLocalVoiceInteraction(Bundle)}.
     */
    public static final int SHOW_SOURCE_ACTIVITY = 1<<4;

    /**
     * Flag for use with {@link #onShow}: indicates that the voice interaction service was invoked
     * from a physical button.
     */
    public static final int SHOW_SOURCE_PUSH_TO_TALK = 1 << 5;

    /**
     * Flag for use with {@link #onShow}: indicates that the voice interaction service was invoked
     * from a notification.
     */
    public static final int SHOW_SOURCE_NOTIFICATION = 1 << 6;

    /**
     * Flag for use with {@link #onShow}: indicates that the voice interaction service was invoked
     * from an Android automotive system UI.
     */
    public static final int SHOW_SOURCE_AUTOMOTIVE_SYSTEM_UI = 1 << 7;

    final Context mContext;
    final HandlerCaller mHandlerCaller;

    final KeyEvent.DispatcherState mDispatcherState = new KeyEvent.DispatcherState();

    IVoiceInteractionManagerService mSystemService;
    IBinder mToken;

    int mTheme = 0;
    LayoutInflater mInflater;
    TypedArray mThemeAttrs;
    View mRootView;
    FrameLayout mContentFrame;
    SoftInputWindow mWindow;

    boolean mUiEnabled = true;
    boolean mInitialized;
    boolean mWindowAdded;
    boolean mWindowVisible;
    boolean mWindowWasVisible;
    boolean mInShowWindow;

    final ArrayMap<IBinder, Request> mActiveRequests = new ArrayMap<IBinder, Request>();

    final Insets mTmpInsets = new Insets();

    final WeakReference<VoiceInteractionSession> mWeakRef
            = new WeakReference<VoiceInteractionSession>(this);

    // Registry of remote callbacks pending a reply with reply handles.
    final Map<SafeResultListener, Consumer<Bundle>> mRemoteCallbacks = new ArrayMap<>();

    ICancellationSignal mKillCallback;

    final IVoiceInteractor mInteractor = new IVoiceInteractor.Stub() {
        @Override
        public IVoiceInteractorRequest startConfirmation(String callingPackage,
                IVoiceInteractorCallback callback, VoiceInteractor.Prompt prompt, Bundle extras) {
            ConfirmationRequest request = new ConfirmationRequest(callingPackage,
                    Binder.getCallingUid(), callback, VoiceInteractionSession.this,
                    prompt, extras);
            addRequest(request);
            mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageO(MSG_START_CONFIRMATION,
                    request));
            return request.mInterface;
        }

        @Override
        public IVoiceInteractorRequest startPickOption(String callingPackage,
                IVoiceInteractorCallback callback, VoiceInteractor.Prompt prompt,
                VoiceInteractor.PickOptionRequest.Option[] options, Bundle extras) {
            PickOptionRequest request = new PickOptionRequest(callingPackage,
                    Binder.getCallingUid(), callback, VoiceInteractionSession.this,
                    prompt, options, extras);
            addRequest(request);
            mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageO(MSG_START_PICK_OPTION,
                    request));
            return request.mInterface;
        }

        @Override
        public IVoiceInteractorRequest startCompleteVoice(String callingPackage,
                IVoiceInteractorCallback callback, VoiceInteractor.Prompt message, Bundle extras) {
            CompleteVoiceRequest request = new CompleteVoiceRequest(callingPackage,
                    Binder.getCallingUid(), callback, VoiceInteractionSession.this,
                    message, extras);
            addRequest(request);
            mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageO(MSG_START_COMPLETE_VOICE,
                    request));
            return request.mInterface;
        }

        @Override
        public IVoiceInteractorRequest startAbortVoice(String callingPackage,
                IVoiceInteractorCallback callback, VoiceInteractor.Prompt message, Bundle extras) {
            AbortVoiceRequest request = new AbortVoiceRequest(callingPackage,
                    Binder.getCallingUid(), callback, VoiceInteractionSession.this,
                    message, extras);
            addRequest(request);
            mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageO(MSG_START_ABORT_VOICE,
                    request));
            return request.mInterface;
        }

        @Override
        public IVoiceInteractorRequest startCommand(String callingPackage,
                IVoiceInteractorCallback callback, String command, Bundle extras) {
            CommandRequest request = new CommandRequest(callingPackage,
                    Binder.getCallingUid(), callback, VoiceInteractionSession.this,
                    command, extras);
            addRequest(request);
            mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageO(MSG_START_COMMAND,
                    request));
            return request.mInterface;
        }

        @Override
        public boolean[] supportsCommands(String callingPackage, String[] commands) {
            Message msg = mHandlerCaller.obtainMessageIOO(MSG_SUPPORTS_COMMANDS,
                    0, commands, null);
            SomeArgs args = mHandlerCaller.sendMessageAndWait(msg);
            if (args != null) {
                boolean[] res = (boolean[])args.arg1;
                args.recycle();
                return res;
            }
            return new boolean[commands.length];
        }

        @Override
        public void notifyDirectActionsChanged(int taskId, IBinder assistToken) {
            mHandlerCaller.getHandler().sendMessage(PooledLambda.obtainMessage(
                    VoiceInteractionSession::onDirectActionsInvalidated,
                    VoiceInteractionSession.this, new ActivityId(taskId, assistToken))
            );
        }

        @Override
        public void setKillCallback(ICancellationSignal callback) {
            mKillCallback = callback;
        }
    };

    final IVoiceInteractionSession mSession = new IVoiceInteractionSession.Stub() {
        @Override
        public void show(Bundle sessionArgs, int flags,
                IVoiceInteractionSessionShowCallback showCallback) {
            mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageIOO(MSG_SHOW,
                    flags, sessionArgs, showCallback));
        }

        @Override
        public void hide() {
            // Remove any pending messages to show the session
            mHandlerCaller.removeMessages(MSG_SHOW);
            mHandlerCaller.sendMessage(mHandlerCaller.obtainMessage(MSG_HIDE));
        }

        @Override
        public void handleAssist(final int taskId, final IBinder assistToken, final Bundle data,
                final AssistStructure structure, final AssistContent content, final int index,
                final int count) {
            // We want to pre-warm the AssistStructure before handing it off to the main
            // thread.  We also want to do this on a separate thread, so that if the app
            // is for some reason slow (due to slow filling in of async children in the
            // structure), we don't block other incoming IPCs (such as the screenshot) to
            // us (since we are a oneway interface, they get serialized).  (Okay?)
            Thread retriever = new Thread("AssistStructure retriever") {
                @Override
                public void run() {
                    Throwable failure = null;
                    if (structure != null) {
                        try {
                            structure.ensureData();
                        } catch (Throwable e) {
                            Log.w(TAG, "Failure retrieving AssistStructure", e);
                            failure = e;
                        }
                    }

                    SomeArgs args = SomeArgs.obtain();
                    args.argi1 = taskId;
                    args.arg1 = data;
                    args.arg2 = (failure == null) ? structure : null;
                    args.arg3 = failure;
                    args.arg4 = content;
                    args.arg5 = assistToken;
                    args.argi5 = index;
                    args.argi6 = count;

                    mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageO(
                            MSG_HANDLE_ASSIST, args));
                }
            };
            retriever.start();
        }

        @Override
        public void handleScreenshot(Bitmap screenshot) {
            mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageO(MSG_HANDLE_SCREENSHOT,
                    screenshot));
        }

        @Override
        public void taskStarted(Intent intent, int taskId) {
            mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageIO(MSG_TASK_STARTED,
                    taskId, intent));
        }

        @Override
        public void taskFinished(Intent intent, int taskId) {
            mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageIO(MSG_TASK_FINISHED,
                    taskId, intent));
        }

        @Override
        public void closeSystemDialogs() {
            mHandlerCaller.sendMessage(mHandlerCaller.obtainMessage(MSG_CLOSE_SYSTEM_DIALOGS));
        }

        @Override
        public void onLockscreenShown() {
            mHandlerCaller.sendMessage(mHandlerCaller.obtainMessage(MSG_ON_LOCKSCREEN_SHOWN));
        }

        @Override
        public void destroy() {
            mHandlerCaller.sendMessage(mHandlerCaller.obtainMessage(MSG_DESTROY));
        }
    };

    /**
     * Base class representing a request from a voice-driver app to perform a particular
     * voice operation with the user.  See related subclasses for the types of requests
     * that are possible.
     */
    public static class Request {
        final IVoiceInteractorRequest mInterface = new IVoiceInteractorRequest.Stub() {
            @Override
            public void cancel() throws RemoteException {
                VoiceInteractionSession session = mSession.get();
                if (session != null) {
                    session.mHandlerCaller.sendMessage(
                            session.mHandlerCaller.obtainMessageO(MSG_CANCEL, Request.this));
                }
            }
        };
        final String mCallingPackage;
        final int mCallingUid;
        final IVoiceInteractorCallback mCallback;
        final WeakReference<VoiceInteractionSession> mSession;
        final Bundle mExtras;

        Request(String packageName, int uid, IVoiceInteractorCallback callback,
                VoiceInteractionSession session, Bundle extras) {
            mCallingPackage = packageName;
            mCallingUid = uid;
            mCallback = callback;
            mSession = session.mWeakRef;
            mExtras = extras;
        }

        /**
         * Return the uid of the application that initiated the request.
         */
        public int getCallingUid() {
            return mCallingUid;
        }

        /**
         * Return the package name of the application that initiated the request.
         */
        public String getCallingPackage() {
            return mCallingPackage;
        }

        /**
         * Return any additional extra information that was supplied as part of the request.
         */
        public Bundle getExtras() {
            return mExtras;
        }

        /**
         * Check whether this request is currently active.  A request becomes inactive after
         * calling {@link #cancel} or a final result method that completes the request.  After
         * this point, further interactions with the request will result in
         * {@link java.lang.IllegalStateException} errors; you should not catch these errors,
         * but can use this method if you need to determine the state of the request.  Returns
         * true if the request is still active.
         */
        public boolean isActive() {
            VoiceInteractionSession session = mSession.get();
            if (session == null) {
                return false;
            }
            return session.isRequestActive(mInterface.asBinder());
        }

        void finishRequest() {
            VoiceInteractionSession session = mSession.get();
            if (session == null) {
                throw new IllegalStateException("VoiceInteractionSession has been destroyed");
            }
            Request req = session.removeRequest(mInterface.asBinder());
            if (req == null) {
                throw new IllegalStateException("Request not active: " + this);
            } else if (req != this) {
                throw new IllegalStateException("Current active request " + req
                        + " not same as calling request " + this);
            }
        }

        /**
         * Ask the app to cancel this current request.
         * This also finishes the request (it is no longer active).
         */
        public void cancel() {
            try {
                if (DEBUG) Log.d(TAG, "sendCancelResult: req=" + mInterface);
                finishRequest();
                mCallback.deliverCancel(mInterface);
            } catch (RemoteException e) {
            }
        }

        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder(128);
            DebugUtils.buildShortClassTag(this, sb);
            sb.append(" ");
            sb.append(mInterface.asBinder());
            sb.append(" pkg=");
            sb.append(mCallingPackage);
            sb.append(" uid=");
            UserHandle.formatUid(sb, mCallingUid);
            sb.append('}');
            return sb.toString();
        }

        void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
            writer.print(prefix); writer.print("mInterface=");
            writer.println(mInterface.asBinder());
            writer.print(prefix); writer.print("mCallingPackage="); writer.print(mCallingPackage);
            writer.print(" mCallingUid="); UserHandle.formatUid(writer, mCallingUid);
            writer.println();
            writer.print(prefix); writer.print("mCallback=");
            writer.println(mCallback.asBinder());
            if (mExtras != null) {
                writer.print(prefix); writer.print("mExtras=");
                writer.println(mExtras);
            }
        }
    }

    /**
     * A request for confirmation from the user of an operation, as per
     * {@link android.app.VoiceInteractor.ConfirmationRequest
     * VoiceInteractor.ConfirmationRequest}.
     */
    public static final class ConfirmationRequest extends Request {
        final VoiceInteractor.Prompt mPrompt;

        ConfirmationRequest(String packageName, int uid, IVoiceInteractorCallback callback,
                VoiceInteractionSession session, VoiceInteractor.Prompt prompt, Bundle extras) {
            super(packageName, uid, callback, session, extras);
            mPrompt = prompt;
        }

        /**
         * Return the prompt informing the user of what will happen, as per
         * {@link android.app.VoiceInteractor.ConfirmationRequest
         * VoiceInteractor.ConfirmationRequest}.
         */
        @Nullable
        public VoiceInteractor.Prompt getVoicePrompt() {
            return mPrompt;
        }

        /**
         * Return the prompt informing the user of what will happen, as per
         * {@link android.app.VoiceInteractor.ConfirmationRequest
         * VoiceInteractor.ConfirmationRequest}.
         * @deprecated Prefer {@link #getVoicePrompt()} which allows multiple voice prompts.
         */
        @Deprecated
        @Nullable
        public CharSequence getPrompt() {
            return (mPrompt != null ? mPrompt.getVoicePromptAt(0) : null);
        }

        /**
         * Report that the voice interactor has confirmed the operation with the user, resulting
         * in a call to
         * {@link android.app.VoiceInteractor.ConfirmationRequest#onConfirmationResult
         * VoiceInteractor.ConfirmationRequest.onConfirmationResult}.
         * This finishes the request (it is no longer active).
         */
        public void sendConfirmationResult(boolean confirmed, Bundle result) {
            try {
                if (DEBUG) Log.d(TAG, "sendConfirmationResult: req=" + mInterface
                        + " confirmed=" + confirmed + " result=" + result);
                finishRequest();
                mCallback.deliverConfirmationResult(mInterface, confirmed, result);
            } catch (RemoteException e) {
            }
        }

        void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
            super.dump(prefix, fd, writer, args);
            writer.print(prefix); writer.print("mPrompt=");
            writer.println(mPrompt);
        }
    }

    /**
     * A request for the user to pick from a set of option, as per
     * {@link android.app.VoiceInteractor.PickOptionRequest VoiceInteractor.PickOptionRequest}.
     */
    public static final class PickOptionRequest extends Request {
        final VoiceInteractor.Prompt mPrompt;
        final VoiceInteractor.PickOptionRequest.Option[] mOptions;

        PickOptionRequest(String packageName, int uid, IVoiceInteractorCallback callback,
                VoiceInteractionSession session, VoiceInteractor.Prompt prompt,
                VoiceInteractor.PickOptionRequest.Option[] options, Bundle extras) {
            super(packageName, uid, callback, session, extras);
            mPrompt = prompt;
            mOptions = options;
        }

        /**
         * Return the prompt informing the user of what they are picking, as per
         * {@link android.app.VoiceInteractor.PickOptionRequest VoiceInteractor.PickOptionRequest}.
         */
        @Nullable
        public VoiceInteractor.Prompt getVoicePrompt() {
            return mPrompt;
        }

        /**
         * Return the prompt informing the user of what they are picking, as per
         * {@link android.app.VoiceInteractor.PickOptionRequest VoiceInteractor.PickOptionRequest}.
         * @deprecated Prefer {@link #getVoicePrompt()} which allows multiple voice prompts.
         */
        @Deprecated
        @Nullable
        public CharSequence getPrompt() {
            return (mPrompt != null ? mPrompt.getVoicePromptAt(0) : null);
        }

        /**
         * Return the set of options the user is picking from, as per
         * {@link android.app.VoiceInteractor.PickOptionRequest VoiceInteractor.PickOptionRequest}.
         */
        public VoiceInteractor.PickOptionRequest.Option[] getOptions() {
            return mOptions;
        }

        void sendPickOptionResult(boolean finished,
                VoiceInteractor.PickOptionRequest.Option[] selections, Bundle result) {
            try {
                if (DEBUG) Log.d(TAG, "sendPickOptionResult: req=" + mInterface
                        + " finished=" + finished + " selections=" + selections
                        + " result=" + result);
                if (finished) {
                    finishRequest();
                }
                mCallback.deliverPickOptionResult(mInterface, finished, selections, result);
            } catch (RemoteException e) {
            }
        }

        /**
         * Report an intermediate option selection from the request, without completing it (the
         * request is still active and the app is waiting for the final option selection),
         * resulting in a call to
         * {@link android.app.VoiceInteractor.PickOptionRequest#onPickOptionResult
         * VoiceInteractor.PickOptionRequest.onPickOptionResult} with false for finished.
         */
        public void sendIntermediatePickOptionResult(
                VoiceInteractor.PickOptionRequest.Option[] selections, Bundle result) {
            sendPickOptionResult(false, selections, result);
        }

        /**
         * Report the final option selection for the request, completing the request
         * and resulting in a call to
         * {@link android.app.VoiceInteractor.PickOptionRequest#onPickOptionResult
         * VoiceInteractor.PickOptionRequest.onPickOptionResult} with false for finished.
         * This finishes the request (it is no longer active).
         */
        public void sendPickOptionResult(
                VoiceInteractor.PickOptionRequest.Option[] selections, Bundle result) {
            sendPickOptionResult(true, selections, result);
        }

        void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
            super.dump(prefix, fd, writer, args);
            writer.print(prefix); writer.print("mPrompt=");
            writer.println(mPrompt);
            if (mOptions != null) {
                writer.print(prefix); writer.println("Options:");
                for (int i=0; i<mOptions.length; i++) {
                    VoiceInteractor.PickOptionRequest.Option op = mOptions[i];
                    writer.print(prefix); writer.print("  #"); writer.print(i); writer.println(":");
                    writer.print(prefix); writer.print("    mLabel=");
                    writer.println(op.getLabel());
                    writer.print(prefix); writer.print("    mIndex=");
                    writer.println(op.getIndex());
                    if (op.countSynonyms() > 0) {
                        writer.print(prefix); writer.println("    Synonyms:");
                        for (int j=0; j<op.countSynonyms(); j++) {
                            writer.print(prefix); writer.print("      #"); writer.print(j);
                            writer.print(": "); writer.println(op.getSynonymAt(j));
                        }
                    }
                    if (op.getExtras() != null) {
                        writer.print(prefix); writer.print("    mExtras=");
                        writer.println(op.getExtras());
                    }
                }
            }
        }
    }

    /**
     * A request to simply inform the user that the voice operation has completed, as per
     * {@link android.app.VoiceInteractor.CompleteVoiceRequest
     * VoiceInteractor.CompleteVoiceRequest}.
     */
    public static final class CompleteVoiceRequest extends Request {
        final VoiceInteractor.Prompt mPrompt;

        CompleteVoiceRequest(String packageName, int uid, IVoiceInteractorCallback callback,
                VoiceInteractionSession session, VoiceInteractor.Prompt prompt, Bundle extras) {
            super(packageName, uid, callback, session, extras);
            mPrompt = prompt;
        }

        /**
         * Return the message informing the user of the completion, as per
         * {@link android.app.VoiceInteractor.CompleteVoiceRequest
         * VoiceInteractor.CompleteVoiceRequest}.
         */
        @Nullable
        public VoiceInteractor.Prompt getVoicePrompt() {
            return mPrompt;
        }

        /**
         * Return the message informing the user of the completion, as per
         * {@link android.app.VoiceInteractor.CompleteVoiceRequest
         * VoiceInteractor.CompleteVoiceRequest}.
         * @deprecated Prefer {@link #getVoicePrompt()} which allows a separate visual message.
         */
        @Deprecated
        @Nullable
        public CharSequence getMessage() {
            return (mPrompt != null ? mPrompt.getVoicePromptAt(0) : null);
        }

        /**
         * Report that the voice interactor has finished completing the voice operation, resulting
         * in a call to
         * {@link android.app.VoiceInteractor.CompleteVoiceRequest#onCompleteResult
         * VoiceInteractor.CompleteVoiceRequest.onCompleteResult}.
         * This finishes the request (it is no longer active).
         */
        public void sendCompleteResult(Bundle result) {
            try {
                if (DEBUG) Log.d(TAG, "sendCompleteVoiceResult: req=" + mInterface
                        + " result=" + result);
                finishRequest();
                mCallback.deliverCompleteVoiceResult(mInterface, result);
            } catch (RemoteException e) {
            }
        }

        void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
            super.dump(prefix, fd, writer, args);
            writer.print(prefix); writer.print("mPrompt=");
            writer.println(mPrompt);
        }
    }

    /**
     * A request to report that the current user interaction can not be completed with voice, as per
     * {@link android.app.VoiceInteractor.AbortVoiceRequest VoiceInteractor.AbortVoiceRequest}.
     */
    public static final class AbortVoiceRequest extends Request {
        final VoiceInteractor.Prompt mPrompt;

        AbortVoiceRequest(String packageName, int uid, IVoiceInteractorCallback callback,
                VoiceInteractionSession session, VoiceInteractor.Prompt prompt, Bundle extras) {
            super(packageName, uid, callback, session, extras);
            mPrompt = prompt;
        }

        /**
         * Return the message informing the user of the problem, as per
         * {@link android.app.VoiceInteractor.AbortVoiceRequest VoiceInteractor.AbortVoiceRequest}.
         */
        @Nullable
        public VoiceInteractor.Prompt getVoicePrompt() {
            return mPrompt;
        }

        /**
         * Return the message informing the user of the problem, as per
         * {@link android.app.VoiceInteractor.AbortVoiceRequest VoiceInteractor.AbortVoiceRequest}.
         * @deprecated Prefer {@link #getVoicePrompt()} which allows a separate visual message.
         */
        @Deprecated
        @Nullable
        public CharSequence getMessage() {
            return (mPrompt != null ? mPrompt.getVoicePromptAt(0) : null);
        }

        /**
         * Report that the voice interactor has finished aborting the voice operation, resulting
         * in a call to
         * {@link android.app.VoiceInteractor.AbortVoiceRequest#onAbortResult
         * VoiceInteractor.AbortVoiceRequest.onAbortResult}.  This finishes the request (it
         * is no longer active).
         */
        public void sendAbortResult(Bundle result) {
            try {
                if (DEBUG) Log.d(TAG, "sendConfirmResult: req=" + mInterface
                        + " result=" + result);
                finishRequest();
                mCallback.deliverAbortVoiceResult(mInterface, result);
            } catch (RemoteException e) {
            }
        }

        void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
            super.dump(prefix, fd, writer, args);
            writer.print(prefix); writer.print("mPrompt=");
            writer.println(mPrompt);
        }
    }

    /**
     * A generic vendor-specific request, as per
     * {@link android.app.VoiceInteractor.CommandRequest VoiceInteractor.CommandRequest}.
     */
    public static final class CommandRequest extends Request {
        final String mCommand;

        CommandRequest(String packageName, int uid, IVoiceInteractorCallback callback,
                VoiceInteractionSession session, String command, Bundle extras) {
            super(packageName, uid, callback, session, extras);
            mCommand = command;
        }

        /**
         * Return the command that is being executed, as per
         * {@link android.app.VoiceInteractor.CommandRequest VoiceInteractor.CommandRequest}.
         */
        public String getCommand() {
            return mCommand;
        }

        void sendCommandResult(boolean finished, Bundle result) {
            try {
                if (DEBUG) Log.d(TAG, "sendCommandResult: req=" + mInterface
                        + " result=" + result);
                if (finished) {
                    finishRequest();
                }
                mCallback.deliverCommandResult(mInterface, finished, result);
            } catch (RemoteException e) {
            }
        }

        /**
         * Report an intermediate result of the request, without completing it (the request
         * is still active and the app is waiting for the final result), resulting in a call to
         * {@link android.app.VoiceInteractor.CommandRequest#onCommandResult
         * VoiceInteractor.CommandRequest.onCommandResult} with false for isCompleted.
         */
        public void sendIntermediateResult(Bundle result) {
            sendCommandResult(false, result);
        }

        /**
         * Report the final result of the request, completing the request and resulting in a call to
         * {@link android.app.VoiceInteractor.CommandRequest#onCommandResult
         * VoiceInteractor.CommandRequest.onCommandResult} with true for isCompleted.
         * This finishes the request (it is no longer active).
         */
        public void sendResult(Bundle result) {
            sendCommandResult(true, result);
        }

        void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
            super.dump(prefix, fd, writer, args);
            writer.print(prefix); writer.print("mCommand=");
            writer.println(mCommand);
        }
    }

    static final int MSG_START_CONFIRMATION = 1;
    static final int MSG_START_PICK_OPTION = 2;
    static final int MSG_START_COMPLETE_VOICE = 3;
    static final int MSG_START_ABORT_VOICE = 4;
    static final int MSG_START_COMMAND = 5;
    static final int MSG_SUPPORTS_COMMANDS = 6;
    static final int MSG_CANCEL = 7;

    static final int MSG_TASK_STARTED = 100;
    static final int MSG_TASK_FINISHED = 101;
    static final int MSG_CLOSE_SYSTEM_DIALOGS = 102;
    static final int MSG_DESTROY = 103;
    static final int MSG_HANDLE_ASSIST = 104;
    static final int MSG_HANDLE_SCREENSHOT = 105;
    static final int MSG_SHOW = 106;
    static final int MSG_HIDE = 107;
    static final int MSG_ON_LOCKSCREEN_SHOWN = 108;

    class MyCallbacks implements HandlerCaller.Callback, SoftInputWindow.Callback {
        @Override
        public void executeMessage(Message msg) {
            SomeArgs args = null;
            switch (msg.what) {
                case MSG_START_CONFIRMATION:
                    if (DEBUG) Log.d(TAG, "onConfirm: req=" + msg.obj);
                    onRequestConfirmation((ConfirmationRequest) msg.obj);
                    break;
                case MSG_START_PICK_OPTION:
                    if (DEBUG) Log.d(TAG, "onPickOption: req=" + msg.obj);
                    onRequestPickOption((PickOptionRequest) msg.obj);
                    break;
                case MSG_START_COMPLETE_VOICE:
                    if (DEBUG) Log.d(TAG, "onCompleteVoice: req=" + msg.obj);
                    onRequestCompleteVoice((CompleteVoiceRequest) msg.obj);
                    break;
                case MSG_START_ABORT_VOICE:
                    if (DEBUG) Log.d(TAG, "onAbortVoice: req=" + msg.obj);
                    onRequestAbortVoice((AbortVoiceRequest) msg.obj);
                    break;
                case MSG_START_COMMAND:
                    if (DEBUG) Log.d(TAG, "onCommand: req=" + msg.obj);
                    onRequestCommand((CommandRequest) msg.obj);
                    break;
                case MSG_SUPPORTS_COMMANDS:
                    args = (SomeArgs)msg.obj;
                    if (DEBUG) Log.d(TAG, "onGetSupportedCommands: cmds=" + args.arg1);
                    args.arg1 = onGetSupportedCommands((String[]) args.arg1);
                    args.complete();
                    args = null;
                    break;
                case MSG_CANCEL:
                    if (DEBUG) Log.d(TAG, "onCancel: req=" + ((Request)msg.obj));
                    onCancelRequest((Request) msg.obj);
                    break;
                case MSG_TASK_STARTED:
                    if (DEBUG) Log.d(TAG, "onTaskStarted: intent=" + msg.obj
                            + " taskId=" + msg.arg1);
                    onTaskStarted((Intent) msg.obj, msg.arg1);
                    break;
                case MSG_TASK_FINISHED:
                    if (DEBUG) Log.d(TAG, "onTaskFinished: intent=" + msg.obj
                            + " taskId=" + msg.arg1);
                    onTaskFinished((Intent) msg.obj, msg.arg1);
                    break;
                case MSG_CLOSE_SYSTEM_DIALOGS:
                    if (DEBUG) Log.d(TAG, "onCloseSystemDialogs");
                    onCloseSystemDialogs();
                    break;
                case MSG_DESTROY:
                    if (DEBUG) Log.d(TAG, "doDestroy");
                    doDestroy();
                    break;
                case MSG_HANDLE_ASSIST:
                    args = (SomeArgs)msg.obj;
                    if (DEBUG) Log.d(TAG, "onHandleAssist: taskId=" + args.argi1
                            + "assistToken=" + args.arg5 + " data=" + args.arg1
                            + " structure=" + args.arg2 + " content=" + args.arg3
                            + " activityIndex=" + args.argi5 + " activityCount=" + args.argi6);
                    doOnHandleAssist(args.argi1, (IBinder) args.arg5, (Bundle) args.arg1,
                            (AssistStructure) args.arg2, (Throwable) args.arg3,
                            (AssistContent) args.arg4, args.argi5, args.argi6);
                    break;
                case MSG_HANDLE_SCREENSHOT:
                    if (DEBUG) Log.d(TAG, "onHandleScreenshot: " + msg.obj);
                    onHandleScreenshot((Bitmap) msg.obj);
                    break;
                case MSG_SHOW:
                    args = (SomeArgs)msg.obj;
                    if (DEBUG) Log.d(TAG, "doShow: args=" + args.arg1
                            + " flags=" + msg.arg1
                            + " showCallback=" + args.arg2);
                    doShow((Bundle) args.arg1, msg.arg1,
                            (IVoiceInteractionSessionShowCallback) args.arg2);
                    break;
                case MSG_HIDE:
                    if (DEBUG) Log.d(TAG, "doHide");
                    doHide();
                    break;
                case MSG_ON_LOCKSCREEN_SHOWN:
                    if (DEBUG) Log.d(TAG, "onLockscreenShown");
                    onLockscreenShown();
                    break;
            }
            if (args != null) {
                args.recycle();
            }
        }

        @Override
        public void onBackPressed() {
            VoiceInteractionSession.this.onBackPressed();
        }
    }

    final MyCallbacks mCallbacks = new MyCallbacks();

    /**
     * Information about where interesting parts of the input method UI appear.
     */
    public static final class Insets {
        /**
         * This is the part of the UI that is the main content.  It is
         * used to determine the basic space needed, to resize/pan the
         * application behind.  It is assumed that this inset does not
         * change very much, since any change will cause a full resize/pan
         * of the application behind.  This value is relative to the top edge
         * of the input method window.
         */
        public final Rect contentInsets = new Rect();

        /**
         * This is the region of the UI that is touchable.  It is used when
         * {@link #touchableInsets} is set to {@link #TOUCHABLE_INSETS_REGION}.
         * The region should be specified relative to the origin of the window frame.
         */
        public final Region touchableRegion = new Region();

        /**
         * Option for {@link #touchableInsets}: the entire window frame
         * can be touched.
         */
        public static final int TOUCHABLE_INSETS_FRAME
                = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME;

        /**
         * Option for {@link #touchableInsets}: the area inside of
         * the content insets can be touched.
         */
        public static final int TOUCHABLE_INSETS_CONTENT
                = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT;

        /**
         * Option for {@link #touchableInsets}: the region specified by
         * {@link #touchableRegion} can be touched.
         */
        public static final int TOUCHABLE_INSETS_REGION
                = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION;

        /**
         * Determine which area of the window is touchable by the user.  May
         * be one of: {@link #TOUCHABLE_INSETS_FRAME},
         * {@link #TOUCHABLE_INSETS_CONTENT}, or {@link #TOUCHABLE_INSETS_REGION}.
         */
        public int touchableInsets;
    }

    final ViewTreeObserver.OnComputeInternalInsetsListener mInsetsComputer =
            new ViewTreeObserver.OnComputeInternalInsetsListener() {
        public void onComputeInternalInsets(ViewTreeObserver.InternalInsetsInfo info) {
            onComputeInsets(mTmpInsets);
            info.contentInsets.set(mTmpInsets.contentInsets);
            info.visibleInsets.set(mTmpInsets.contentInsets);
            info.touchableRegion.set(mTmpInsets.touchableRegion);
            info.setTouchableInsets(mTmpInsets.touchableInsets);
        }
    };

    public VoiceInteractionSession(Context context) {
        this(context, new Handler());
    }

    public VoiceInteractionSession(Context context, Handler handler) {
        mContext = context;
        mHandlerCaller = new HandlerCaller(context, handler.getLooper(),
                mCallbacks, true);
    }

    public Context getContext() {
        return mContext;
    }

    void addRequest(Request req) {
        synchronized (this) {
            mActiveRequests.put(req.mInterface.asBinder(), req);
        }
    }

    boolean isRequestActive(IBinder reqInterface) {
        synchronized (this) {
            return mActiveRequests.containsKey(reqInterface);
        }
    }

    Request removeRequest(IBinder reqInterface) {
        synchronized (this) {
            return mActiveRequests.remove(reqInterface);
        }
    }

    void doCreate(IVoiceInteractionManagerService service, IBinder token) {
        mSystemService = service;
        mToken = token;
        onCreate();
    }

    void doShow(Bundle args, int flags, final IVoiceInteractionSessionShowCallback showCallback) {
        if (DEBUG) Log.v(TAG, "Showing window: mWindowAdded=" + mWindowAdded
                + " mWindowVisible=" + mWindowVisible);

        if (mInShowWindow) {
            Log.w(TAG, "Re-entrance in to showWindow");
            return;
        }

        try {
            mInShowWindow = true;
            onPrepareShow(args, flags);
            if (!mWindowVisible) {
                ensureWindowAdded();
            }
            onShow(args, flags);
            if (!mWindowVisible) {
                mWindowVisible = true;
                if (mUiEnabled) {
                    mWindow.show();
                }
            }
            if (showCallback != null) {
                if (mUiEnabled) {
                    mRootView.invalidate();
                    mRootView.getViewTreeObserver().addOnPreDrawListener(
                            new ViewTreeObserver.OnPreDrawListener() {
                                @Override
                                public boolean onPreDraw() {
                                    mRootView.getViewTreeObserver().removeOnPreDrawListener(this);
                                    try {
                                        showCallback.onShown();
                                    } catch (RemoteException e) {
                                        Log.w(TAG, "Error calling onShown", e);
                                    }
                                    return true;
                                }
                            });
                } else {
                    try {
                        showCallback.onShown();
                    } catch (RemoteException e) {
                        Log.w(TAG, "Error calling onShown", e);
                    }
                }
            }
        } finally {
            mWindowWasVisible = true;
            mInShowWindow = false;
        }
    }

    void doHide() {
        if (mWindowVisible) {
            ensureWindowHidden();
            mWindowVisible = false;
            onHide();
        }
    }

    void doDestroy() {
        onDestroy();
        if (mKillCallback != null) {
            try {
                mKillCallback.cancel();
            } catch (RemoteException e) {
                /* ignore */
            }
            mKillCallback = null;
        }
        if (mInitialized) {
            mRootView.getViewTreeObserver().removeOnComputeInternalInsetsListener(
                    mInsetsComputer);
            if (mWindowAdded) {
                mWindow.dismiss();
                mWindowAdded = false;
            }
            mInitialized = false;
        }
    }

    void ensureWindowCreated() {
        if (mInitialized) {
            return;
        }

        if (!mUiEnabled) {
            throw new IllegalStateException("setUiEnabled is false");
        }

        mInitialized = true;
        mInflater = (LayoutInflater)mContext.getSystemService(
                Context.LAYOUT_INFLATER_SERVICE);
        mWindow = new SoftInputWindow(mContext, "VoiceInteractionSession", mTheme,
                mCallbacks, this, mDispatcherState,
                WindowManager.LayoutParams.TYPE_VOICE_INTERACTION, Gravity.BOTTOM, true);
        mWindow.getWindow().getAttributes().setFitInsetsTypes(0 /* types */);
        mWindow.getWindow().addFlags(
                WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED |
                        WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN |
                        WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR);

        mThemeAttrs = mContext.obtainStyledAttributes(android.R.styleable.VoiceInteractionSession);
        mRootView = mInflater.inflate(
                com.android.internal.R.layout.voice_interaction_session, null);
        mRootView.setSystemUiVisibility(
                View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                        | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
        mWindow.setContentView(mRootView);
        mRootView.getViewTreeObserver().addOnComputeInternalInsetsListener(mInsetsComputer);

        mContentFrame = (FrameLayout)mRootView.findViewById(android.R.id.content);

        mWindow.getWindow().setLayout(MATCH_PARENT, MATCH_PARENT);
        mWindow.setToken(mToken);
    }

    void ensureWindowAdded() {
        if (mUiEnabled && !mWindowAdded) {
            mWindowAdded = true;
            ensureWindowCreated();
            View v = onCreateContentView();
            if (v != null) {
                setContentView(v);
            }
        }
    }

    void ensureWindowHidden() {
        if (mWindow != null) {
            mWindow.hide();
        }
    }

    /**
     * Equivalent to {@link VoiceInteractionService#setDisabledShowContext
     * VoiceInteractionService.setDisabledShowContext(int)}.
     */
    public void setDisabledShowContext(int flags) {
        try {
            mSystemService.setDisabledShowContext(flags);
        } catch (RemoteException e) {
        }
    }

    /**
     * Equivalent to {@link VoiceInteractionService#getDisabledShowContext
     * VoiceInteractionService.getDisabledShowContext}.
     */
    public int getDisabledShowContext() {
        try {
            return mSystemService.getDisabledShowContext();
        } catch (RemoteException e) {
            return 0;
        }
    }

    /**
     * Return which show context flags have been disabled by the user through the system
     * settings UI, so the session will never get this data.  Returned flags are any combination of
     * {@link VoiceInteractionSession#SHOW_WITH_ASSIST VoiceInteractionSession.SHOW_WITH_ASSIST} and
     * {@link VoiceInteractionSession#SHOW_WITH_SCREENSHOT
     * VoiceInteractionSession.SHOW_WITH_SCREENSHOT}.  Note that this only tells you about
     * global user settings, not about restrictions that may be applied contextual based on
     * the current application the user is in or other transient states.
     */
    public int getUserDisabledShowContext() {
        try {
            return mSystemService.getUserDisabledShowContext();
        } catch (RemoteException e) {
            return 0;
        }
    }

    /**
     * Show the UI for this session.  This asks the system to go through the process of showing
     * your UI, which will eventually culminate in {@link #onShow}.  This is similar to calling
     * {@link VoiceInteractionService#showSession VoiceInteractionService.showSession}.
     * @param args Arbitrary arguments that will be propagated {@link #onShow}.
     * @param flags Indicates additional optional behavior that should be performed.  May
     * be any combination of
     * {@link VoiceInteractionSession#SHOW_WITH_ASSIST VoiceInteractionSession.SHOW_WITH_ASSIST} and
     * {@link VoiceInteractionSession#SHOW_WITH_SCREENSHOT
     * VoiceInteractionSession.SHOW_WITH_SCREENSHOT}
     * to request that the system generate and deliver assist data on the current foreground
     * app as part of showing the session UI.
     */
    public void show(Bundle args, int flags) {
        if (mToken == null) {
            throw new IllegalStateException("Can't call before onCreate()");
        }
        try {
            mSystemService.showSessionFromSession(mToken, args, flags);
        } catch (RemoteException e) {
        }
    }

    /**
     * Hide the session's UI, if currently shown.  Call this when you are done with your
     * user interaction.
     */
    public void hide() {
        if (mToken == null) {
            throw new IllegalStateException("Can't call before onCreate()");
        }
        try {
            mSystemService.hideSessionFromSession(mToken);
        } catch (RemoteException e) {
        }
    }

    /**
     * Control whether the UI layer for this session is enabled.  It is enabled by default.
     * If set to false, you will not be able to provide a UI through {@link #onCreateContentView()}.
     */
    public void setUiEnabled(boolean enabled) {
        if (mUiEnabled != enabled) {
            mUiEnabled = enabled;
            if (mWindowVisible) {
                if (enabled) {
                    ensureWindowAdded();
                    mWindow.show();
                } else {
                    ensureWindowHidden();
                }
            }
        }
    }

    /**
     * You can call this to customize the theme used by your IME's window.
     * This must be set before {@link #onCreate}, so you
     * will typically call it in your constructor with the resource ID
     * of your custom theme.
     */
    public void setTheme(int theme) {
        if (mWindow != null) {
            throw new IllegalStateException("Must be called before onCreate()");
        }
        mTheme = theme;
    }

    /**
     * Ask that a new activity be started for voice interaction.  This will create a
     * new dedicated task in the activity manager for this voice interaction session;
     * this means that {@link Intent#FLAG_ACTIVITY_NEW_TASK Intent.FLAG_ACTIVITY_NEW_TASK}
     * will be set for you to make it a new task.
     *
     * <p>The newly started activity will be displayed to the user in a special way, as
     * a layer under the voice interaction UI.</p>
     *
     * <p>As the voice activity runs, it can retrieve a {@link android.app.VoiceInteractor}
     * through which it can perform voice interactions through your session.  These requests
     * for voice interactions will appear as callbacks on {@link #onGetSupportedCommands},
     * {@link #onRequestConfirmation}, {@link #onRequestPickOption},
     * {@link #onRequestCompleteVoice}, {@link #onRequestAbortVoice},
     * or {@link #onRequestCommand}
     *
     * <p>You will receive a call to {@link #onTaskStarted} when the task starts up
     * and {@link #onTaskFinished} when the last activity has finished.
     *
     * @param intent The Intent to start this voice interaction.  The given Intent will
     * always have {@link Intent#CATEGORY_VOICE Intent.CATEGORY_VOICE} added to it, since
     * this is part of a voice interaction.
     */
    public void startVoiceActivity(Intent intent) {
        if (mToken == null) {
            throw new IllegalStateException("Can't call before onCreate()");
        }
        try {
            intent.migrateExtraStreamToClipData();
            intent.prepareToLeaveProcess(mContext);
            int res = mSystemService.startVoiceActivity(mToken, intent,
                    intent.resolveType(mContext.getContentResolver()), mContext.getFeatureId());
            Instrumentation.checkStartActivityResult(res, intent);
        } catch (RemoteException e) {
        }
    }

    /**
     * <p>Ask that a new assistant activity be started.  This will create a new task in the
     * in activity manager: this means that
     * {@link Intent#FLAG_ACTIVITY_NEW_TASK Intent.FLAG_ACTIVITY_NEW_TASK}
     * will be set for you to make it a new task.</p>
     *
     * <p>The newly started activity will be displayed on top of other activities in the system
     * in a new layer that is not affected by multi-window mode.  Tasks started from this activity
     * will go into the normal activity layer and not this new layer.</p>
     *
     * <p>By default, the system will create a window for the UI for this session.  If you are using
     * an assistant activity instead, then you can disable the window creation by calling
     * {@link #setUiEnabled} in {@link #onPrepareShow(Bundle, int)}.</p>
     */
    public void startAssistantActivity(Intent intent) {
        if (mToken == null) {
            throw new IllegalStateException("Can't call before onCreate()");
        }
        try {
            intent.migrateExtraStreamToClipData();
            intent.prepareToLeaveProcess(mContext);
            int res = mSystemService.startAssistantActivity(mToken, intent,
                    intent.resolveType(mContext.getContentResolver()), mContext.getFeatureId());
            Instrumentation.checkStartActivityResult(res, intent);
        } catch (RemoteException e) {
        }
    }

    /**
     * Requests a list of supported actions from an app.
     *
     * @param activityId Ths activity id of the app to get the actions from.
     * @param resultExecutor The handler to receive the callback
     * @param cancellationSignal A signal to cancel the operation in progress,
     *     or {@code null} if none.
     * @param callback The callback to receive the response
     */
    public final void requestDirectActions(@NonNull ActivityId activityId,
            @Nullable CancellationSignal cancellationSignal,
            @NonNull @CallbackExecutor Executor resultExecutor,
            @NonNull Consumer<List<DirectAction>> callback) {
        Preconditions.checkNotNull(activityId);
        Preconditions.checkNotNull(resultExecutor);
        Preconditions.checkNotNull(callback);
        if (mToken == null) {
            throw new IllegalStateException("Can't call before onCreate()");
        }

        if (cancellationSignal != null) {
            cancellationSignal.throwIfCanceled();
        }

        final RemoteCallback cancellationCallback = (cancellationSignal != null)
                ? new RemoteCallback(b -> {
                    if (b != null) {
                        final IBinder cancellation = b.getBinder(
                                VoiceInteractor.KEY_CANCELLATION_SIGNAL);
                        if (cancellation != null) {
                            cancellationSignal.setRemote(ICancellationSignal.Stub.asInterface(
                                    cancellation));
                        }
                    }
                })
                : null;

        try {
            mSystemService.requestDirectActions(mToken, activityId.getTaskId(),
                    activityId.getAssistToken(), cancellationCallback,
                    new RemoteCallback(createSafeResultListener((result) -> {
                List<DirectAction> list;
                if (result == null) {
                    list = Collections.emptyList();
                } else {
                    final ParceledListSlice<DirectAction> pls = result.getParcelable(
                            DirectAction.KEY_ACTIONS_LIST);
                    if (pls != null) {
                        final List<DirectAction> receivedList = pls.getList();
                        list = (receivedList != null) ? receivedList : Collections.emptyList();
                    } else {
                        list = Collections.emptyList();
                    }
                }
                resultExecutor.execute(() -> callback.accept(list));
            })));
        } catch (RemoteException e) {
            e.rethrowFromSystemServer();
        }
    }

    /**
     * Called when the direct actions are invalidated.
     */
    public void onDirectActionsInvalidated(@NonNull ActivityId activityId) {

    }

    /**
     * Asks that an action be performed by the app. This will send a request to the app which
     * provided this action.
     *
     * <p> An action could take time to execute and the result is provided asynchronously
     * via a callback. If the action is taking longer and you want to cancel its execution
     * you can pass in a cancellation signal through which to notify the app to abort the
     * action.
     *
     * @param action The action to be performed.
     * @param extras Any optional extras sent to the app as part of the request
     * @param cancellationSignal A signal to cancel the operation in progress,
     *                          or {@code null} if none.
     * @param resultExecutor The handler to receive the callback.
     * @param resultListener The callback to receive the response.
     *
     * @see #requestDirectActions(ActivityId, CancellationSignal, Executor, Consumer)
     * @see Activity#onGetDirectActions(CancellationSignal, Consumer)
     */
    public final void performDirectAction(@NonNull DirectAction action, @Nullable Bundle extras,
            @Nullable CancellationSignal cancellationSignal,
            @NonNull @CallbackExecutor Executor resultExecutor,
            @NonNull Consumer<Bundle> resultListener) {
        if (mToken == null) {
            throw new IllegalStateException("Can't call before onCreate()");
        }
        Preconditions.checkNotNull(resultExecutor);
        Preconditions.checkNotNull(resultListener);

        if (cancellationSignal != null) {
            cancellationSignal.throwIfCanceled();
        }

        final RemoteCallback cancellationCallback = (cancellationSignal != null)
                ? new RemoteCallback(createSafeResultListener(b -> {
                    if (b != null) {
                        final IBinder cancellation = b.getBinder(
                                VoiceInteractor.KEY_CANCELLATION_SIGNAL);
                        if (cancellation != null) {
                            cancellationSignal.setRemote(ICancellationSignal.Stub.asInterface(
                                    cancellation));
                        }
                    }
                }))
                : null;

        final RemoteCallback resultCallback = new RemoteCallback(createSafeResultListener(b -> {
            if (b != null) {
                resultExecutor.execute(() -> resultListener.accept(b));
            } else {
                resultExecutor.execute(() -> resultListener.accept(Bundle.EMPTY));
            }
        }));

        try {
            mSystemService.performDirectAction(mToken, action.getId(), extras,
                    action.getTaskId(), action.getActivityId(), cancellationCallback,
                    resultCallback);
        } catch (RemoteException e) {
            e.rethrowFromSystemServer();
        }
    }

    /**
     * Set whether this session will keep the device awake while it is running a voice
     * activity.  By default, the system holds a wake lock for it while in this state,
     * so that it can work even if the screen is off.  Setting this to false removes that
     * wake lock, allowing the CPU to go to sleep.  This is typically used if the
     * session decides it has been waiting too long for a response from the user and
     * doesn't want to let this continue to drain the battery.
     *
     * <p>Passing false here will release the wake lock, and you can call later with
     * true to re-acquire it.  It will also be automatically re-acquired for you each
     * time you start a new voice activity task -- that is when you call
     * {@link #startVoiceActivity}.</p>
     */
    public void setKeepAwake(boolean keepAwake) {
        if (mToken == null) {
            throw new IllegalStateException("Can't call before onCreate()");
        }
        try {
            mSystemService.setKeepAwake(mToken, keepAwake);
        } catch (RemoteException e) {
        }
    }

    /**
     * Request that all system dialogs (and status bar shade etc) be closed, allowing
     * access to the session's UI.  This will <em>not</em> cause the lock screen to be
     * dismissed.
     */
    public void closeSystemDialogs() {
        if (mToken == null) {
            throw new IllegalStateException("Can't call before onCreate()");
        }
        try {
            mSystemService.closeSystemDialogs(mToken);
        } catch (RemoteException e) {
        }
    }

    /**
     * Convenience for inflating views.
     */
    public LayoutInflater getLayoutInflater() {
        ensureWindowCreated();
        return mInflater;
    }

    /**
     * Retrieve the window being used to show the session's UI.
     */
    public Dialog getWindow() {
        ensureWindowCreated();
        return mWindow;
    }

    /**
     * Finish the session.  This completely destroys the session -- the next time it is shown,
     * an entirely new one will be created.  You do not normally call this function; instead,
     * use {@link #hide} and allow the system to destroy your session if it needs its RAM.
     */
    public void finish() {
        if (mToken == null) {
            throw new IllegalStateException("Can't call before onCreate()");
        }
        try {
            mSystemService.finish(mToken);
        } catch (RemoteException e) {
        }
    }

    /**
     * Initiatize a new session.  At this point you don't know exactly what this
     * session will be used for; you will find that out in {@link #onShow}.
     */
    public void onCreate() {
        doOnCreate();
    }

    private void doOnCreate() {
        mTheme = mTheme != 0 ? mTheme
                : com.android.internal.R.style.Theme_DeviceDefault_VoiceInteractionSession;
    }

    /**
     * Called prior to {@link #onShow} before any UI setup has occurred.  Not generally useful.
     *
     * @param args The arguments that were supplied to
     * {@link VoiceInteractionService#showSession VoiceInteractionService.showSession}.
     * @param showFlags The show flags originally provided to
     * {@link VoiceInteractionService#showSession VoiceInteractionService.showSession}.
     */
    public void onPrepareShow(Bundle args, int showFlags) {
    }

    /**
     * Called when the session UI is going to be shown.  This is called after
     * {@link #onCreateContentView} (if the session's content UI needed to be created) and
     * immediately prior to the window being shown.  This may be called while the window
     * is already shown, if a show request has come in while it is shown, to allow you to
     * update the UI to match the new show arguments.
     *
     * @param args The arguments that were supplied to
     * {@link VoiceInteractionService#showSession VoiceInteractionService.showSession}.
     * @param showFlags The show flags originally provided to
     * {@link VoiceInteractionService#showSession VoiceInteractionService.showSession}.
     */
    public void onShow(Bundle args, int showFlags) {
    }

    /**
     * Called immediately after stopping to show the session UI.
     */
    public void onHide() {
    }

    /**
     * Last callback to the session as it is being finished.
     */
    public void onDestroy() {
    }

    /**
     * Hook in which to create the session's UI.
     */
    public View onCreateContentView() {
        return null;
    }

    public void setContentView(View view) {
        ensureWindowCreated();
        mContentFrame.removeAllViews();
        mContentFrame.addView(view, new FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT));
        mContentFrame.requestApplyInsets();
    }

    void doOnHandleAssist(int taskId, IBinder assistToken, Bundle data, AssistStructure structure,
            Throwable failure, AssistContent content, int index, int count) {
        if (failure != null) {
            onAssistStructureFailure(failure);
        }
        AssistState assistState = new AssistState(new ActivityId(taskId, assistToken),
                data, structure, content, index, count);
        onHandleAssist(assistState);
    }

    /**
     * Called when there has been a failure transferring the {@link AssistStructure} to
     * the assistant.  This may happen, for example, if the data is too large and results
     * in an out of memory exception, or the client has provided corrupt data.  This will
     * be called immediately before {@link #onHandleAssist} and the AssistStructure supplied
     * there afterwards will be null.
     *
     * @param failure The failure exception that was thrown when building the
     * {@link AssistStructure}.
     */
    public void onAssistStructureFailure(Throwable failure) {
    }

    /**
     * Called to receive data from the application that the user was currently viewing when
     * an assist session is started.  If the original show request did not specify
     * {@link #SHOW_WITH_ASSIST}, this method will not be called.
     *
     * @param data Arbitrary data supplied by the app through
     * {@link android.app.Activity#onProvideAssistData Activity.onProvideAssistData}.
     * May be null if assist data has been disabled by the user or device policy.
     * @param structure If available, the structure definition of all windows currently
     * displayed by the app.  May be null if assist data has been disabled by the user
     * or device policy; will be an empty stub if the application has disabled assist
     * by marking its window as secure.
     * @param content Additional content data supplied by the app through
     * {@link android.app.Activity#onProvideAssistContent Activity.onProvideAssistContent}.
     * May be null if assist data has been disabled by the user or device policy; will
     * not be automatically filled in with data from the app if the app has marked its
     * window as secure.
     *
     * @deprecated use {@link #onHandleAssist(AssistState)}
     */
    @Deprecated
    public void onHandleAssist(@Nullable Bundle data, @Nullable AssistStructure structure,
            @Nullable AssistContent content) {
    }

    /**
     * Called to receive data from the application that the user was currently viewing when
     * an assist session is started.  If the original show request did not specify
     * {@link #SHOW_WITH_ASSIST}, this method will not be called.
     *
     * <p>This method is called for all activities along with an index and count that indicates
     * which activity the data is for. {@code index} will be between 0 and {@code count}-1 and
     * this method is called once for each activity in no particular order. The {@code count}
     * indicates how many activities to expect assist data for, including the top focused one.
     * The focused activity can be determined by calling {@link AssistState#isFocused()}.
     *
     * <p>To be responsive to assist requests, process assist data as soon as it is received,
     * without waiting for all queued activities to return assist data.
     *
     * @param state The state object capturing the state of an activity.
     */
    public void onHandleAssist(@NonNull AssistState state) {
        if (state.getIndex() == 0) {
            onHandleAssist(state.getAssistData(), state.getAssistStructure(),
                    state.getAssistContent());
        } else {
            onHandleAssistSecondary(state.getAssistData(), state.getAssistStructure(),
                    state.getAssistContent(), state.getIndex(), state.getCount());
        }
    }

    /**
     * Called to receive data from other applications that the user was or is interacting with,
     * that are currently on the screen in a multi-window display environment, not including the
     * currently focused activity. This could be
     * a free-form window, a picture-in-picture window, or another window in a split-screen display.
     * <p>
     * This method is very similar to
     * {@link #onHandleAssist} except that it is called
     * for additional non-focused activities along with an index and count that indicates
     * which additional activity the data is for. {@code index} will be between 1 and
     * {@code count}-1 and this method is called once for each additional window, in no particular
     * order. The {@code count} indicates how many windows to expect assist data for, including the
     * top focused activity, which continues to be returned via {@link #onHandleAssist}.
     * <p>
     * To be responsive to assist requests, process assist data as soon as it is received,
     * without waiting for all queued activities to return assist data.
     *
     * @param data Arbitrary data supplied by the app through
     * {@link android.app.Activity#onProvideAssistData Activity.onProvideAssistData}.
     * May be null if assist data has been disabled by the user or device policy.
     * @param structure If available, the structure definition of all windows currently
     * displayed by the app.  May be null if assist data has been disabled by the user
     * or device policy; will be an empty stub if the application has disabled assist
     * by marking its window as secure.
     * @param content Additional content data supplied by the app through
     * {@link android.app.Activity#onProvideAssistContent Activity.onProvideAssistContent}.
     * May be null if assist data has been disabled by the user or device policy; will
     * not be automatically filled in with data from the app if the app has marked its
     * window as secure.
     * @param index the index of the additional activity that this data
     *        is for.
     * @param count the total number of additional activities for which the assist data is being
     *        returned, including the focused activity that is returned via
     *        {@link #onHandleAssist}.
     *
     * @deprecated use {@link #onHandleAssist(AssistState)}
     */
    @Deprecated
    public void onHandleAssistSecondary(@Nullable Bundle data, @Nullable AssistStructure structure,
            @Nullable AssistContent content, int index, int count) {
    }

    /**
     * Called to receive a screenshot of what the user was currently viewing when an assist
     * session is started.  May be null if screenshots are disabled by the user, policy,
     * or application.  If the original show request did not specify
     * {@link #SHOW_WITH_SCREENSHOT}, this method will not be called.
     */
    public void onHandleScreenshot(@Nullable Bitmap screenshot) {
    }

    public boolean onKeyDown(int keyCode, KeyEvent event) {
        return false;
    }

    public boolean onKeyLongPress(int keyCode, KeyEvent event) {
        return false;
    }

    public boolean onKeyUp(int keyCode, KeyEvent event) {
        return false;
    }

    public boolean onKeyMultiple(int keyCode, int count, KeyEvent event) {
        return false;
    }

    /**
     * Called when the user presses the back button while focus is in the session UI.  Note
     * that this will only happen if the session UI has requested input focus in its window;
     * otherwise, the back key will go to whatever window has focus and do whatever behavior
     * it normally has there.  The default implementation simply calls {@link #hide}.
     */
    public void onBackPressed() {
        hide();
    }

    /**
     * Sessions automatically watch for requests that all system UI be closed (such as when
     * the user presses HOME), which will appear here.  The default implementation always
     * calls {@link #hide}.
     */
    public void onCloseSystemDialogs() {
        hide();
    }

    /**
     * Called when the lockscreen was shown.
     */
    public void onLockscreenShown() {
        hide();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
    }

    @Override
    public void onLowMemory() {
    }

    @Override
    public void onTrimMemory(int level) {
    }

    /**
     * Compute the interesting insets into your UI.  The default implementation
     * sets {@link Insets#contentInsets outInsets.contentInsets.top} to the height
     * of the window, meaning it should not adjust content underneath.  The default touchable
     * insets are {@link Insets#TOUCHABLE_INSETS_FRAME}, meaning it consumes all touch
     * events within its window frame.
     *
     * @param outInsets Fill in with the current UI insets.
     */
    public void onComputeInsets(Insets outInsets) {
        outInsets.contentInsets.left = 0;
        outInsets.contentInsets.bottom = 0;
        outInsets.contentInsets.right = 0;
        View decor = getWindow().getWindow().getDecorView();
        outInsets.contentInsets.top = decor.getHeight();
        outInsets.touchableInsets = Insets.TOUCHABLE_INSETS_FRAME;
        outInsets.touchableRegion.setEmpty();
    }

    /**
     * Called when a task initiated by {@link #startVoiceActivity(android.content.Intent)}
     * has actually started.
     *
     * @param intent The original {@link Intent} supplied to
     * {@link #startVoiceActivity(android.content.Intent)}.
     * @param taskId Unique ID of the now running task.
     */
    public void onTaskStarted(Intent intent, int taskId) {
    }

    /**
     * Called when the last activity of a task initiated by
     * {@link #startVoiceActivity(android.content.Intent)} has finished.  The default
     * implementation calls {@link #finish()} on the assumption that this represents
     * the completion of a voice action.  You can override the implementation if you would
     * like a different behavior.
     *
     * @param intent The original {@link Intent} supplied to
     * {@link #startVoiceActivity(android.content.Intent)}.
     * @param taskId Unique ID of the finished task.
     */
    public void onTaskFinished(Intent intent, int taskId) {
        hide();
    }

    /**
     * Request to query for what extended commands the session supports.
     *
     * @param commands An array of commands that are being queried.
     * @return Return an array of booleans indicating which of each entry in the
     * command array is supported.  A true entry in the array indicates the command
     * is supported; false indicates it is not.  The default implementation returns
     * an array of all false entries.
     */
    public boolean[] onGetSupportedCommands(String[] commands) {
        return new boolean[commands.length];
    }

    /**
     * Request to confirm with the user before proceeding with an unrecoverable operation,
     * corresponding to a {@link android.app.VoiceInteractor.ConfirmationRequest
     * VoiceInteractor.ConfirmationRequest}.
     *
     * @param request The active request.
     */
    public void onRequestConfirmation(ConfirmationRequest request) {
    }

    /**
     * Request for the user to pick one of N options, corresponding to a
     * {@link android.app.VoiceInteractor.PickOptionRequest VoiceInteractor.PickOptionRequest}.
     *
     * @param request The active request.
     */
    public void onRequestPickOption(PickOptionRequest request) {
    }

    /**
     * Request to complete the voice interaction session because the voice activity successfully
     * completed its interaction using voice.  Corresponds to
     * {@link android.app.VoiceInteractor.CompleteVoiceRequest
     * VoiceInteractor.CompleteVoiceRequest}.  The default implementation just sends an empty
     * confirmation back to allow the activity to exit.
     *
     * @param request The active request.
     */
    public void onRequestCompleteVoice(CompleteVoiceRequest request) {
    }

    /**
     * Request to abort the voice interaction session because the voice activity can not
     * complete its interaction using voice.  Corresponds to
     * {@link android.app.VoiceInteractor.AbortVoiceRequest
     * VoiceInteractor.AbortVoiceRequest}.  The default implementation just sends an empty
     * confirmation back to allow the activity to exit.
     *
     * @param request The active request.
     */
    public void onRequestAbortVoice(AbortVoiceRequest request) {
    }

    /**
     * Process an arbitrary extended command from the caller,
     * corresponding to a {@link android.app.VoiceInteractor.CommandRequest
     * VoiceInteractor.CommandRequest}.
     *
     * @param request The active request.
     */
    public void onRequestCommand(CommandRequest request) {
    }

    /**
     * Called when the {@link android.app.VoiceInteractor} has asked to cancel a {@link Request}
     * that was previously delivered to {@link #onRequestConfirmation},
     * {@link #onRequestPickOption}, {@link #onRequestCompleteVoice}, {@link #onRequestAbortVoice},
     * or {@link #onRequestCommand}.
     *
     * @param request The request that is being canceled.
     */
    public void onCancelRequest(Request request) {
    }

    /**
     * Print the Service's state into the given stream.  This gets invoked by
     * {@link VoiceInteractionSessionService} when its Service
     * {@link android.app.Service#dump} method is called.
     *
     * @param prefix Text to print at the front of each line.
     * @param fd The raw file descriptor that the dump is being sent to.
     * @param writer The PrintWriter to which you should dump your state.  This will be
     * closed for you after you return.
     * @param args additional arguments to the dump request.
     */
    public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
        writer.print(prefix); writer.print("mToken="); writer.println(mToken);
        writer.print(prefix); writer.print("mTheme=#"); writer.println(Integer.toHexString(mTheme));
        writer.print(prefix); writer.print("mUiEnabled="); writer.println(mUiEnabled);
        writer.print(" mInitialized="); writer.println(mInitialized);
        writer.print(prefix); writer.print("mWindowAdded="); writer.print(mWindowAdded);
        writer.print(" mWindowVisible="); writer.println(mWindowVisible);
        writer.print(prefix); writer.print("mWindowWasVisible="); writer.print(mWindowWasVisible);
        writer.print(" mInShowWindow="); writer.println(mInShowWindow);
        if (mActiveRequests.size() > 0) {
            writer.print(prefix); writer.println("Active requests:");
            String innerPrefix = prefix + "    ";
            for (int i=0; i<mActiveRequests.size(); i++) {
                Request req = mActiveRequests.valueAt(i);
                writer.print(prefix); writer.print("  #"); writer.print(i);
                writer.print(": ");
                writer.println(req);
                req.dump(innerPrefix, fd, writer, args);

            }
        }
    }

    private SafeResultListener createSafeResultListener(
            @NonNull Consumer<Bundle> consumer) {
        synchronized (this) {
            final SafeResultListener listener = new SafeResultListener(consumer, this);
            mRemoteCallbacks.put(listener, consumer);
            return listener;
        }
    }

    private Consumer<Bundle> removeSafeResultListener(@NonNull SafeResultListener listener) {
        synchronized (this) {
            return mRemoteCallbacks.remove(listener);
        }
    }

    /**
     * Represents assist state captured when this session was started.
     * It contains the various assist data objects and a reference to
     * the source activity.
     */
    @Immutable
    public static final class AssistState {
        private final @NonNull ActivityId mActivityId;
        private final int mIndex;
        private final int mCount;
        private final @Nullable Bundle mData;
        private final @Nullable AssistStructure mStructure;
        private final @Nullable AssistContent mContent;

        AssistState(@NonNull ActivityId activityId, @Nullable Bundle data,
                @Nullable AssistStructure structure, @Nullable AssistContent content,
                int index, int count) {
            mActivityId = activityId;
            mIndex = index;
            mCount = count;
            mData = data;
            mStructure = structure;
            mContent = content;
        }

        /**
         * @return whether the source activity is focused.
         */
        public boolean isFocused() {
            return mIndex == 0;
        }

        /**
         * @return the index of the activity that this state is for or -1
         *     if there was no assist data captured.
         */
        public @IntRange(from = -1) int getIndex() {
            return mIndex;
        }

        /**s
         * @return the total number of activities for which the assist data is
         * being returned.
         */
        public @IntRange(from = 0) int getCount() {
            return mCount;
        }

        /**
         * @return the id of the source activity
         */
        public @NonNull ActivityId getActivityId() {
            return mActivityId;
        }

        /**
         * @return Arbitrary data supplied by the app through
         * {@link android.app.Activity#onProvideAssistData Activity.onProvideAssistData}.
         * May be null if assist data has been disabled by the user or device policy.
         */
        public @Nullable Bundle getAssistData() {
            return mData;
        }

        /**
         * @return If available, the structure definition of all windows currently
         * displayed by the app. May be null if assist data has been disabled by the user
         * or device policy; will be an empty stub if the application has disabled assist
         * by marking its window as secure.
         */
        public @Nullable AssistStructure getAssistStructure() {
            return mStructure;
        }

        /**
         * @return Additional content data supplied by the app through
         * {@link android.app.Activity#onProvideAssistContent Activity.onProvideAssistContent}.
         * May be null if assist data has been disabled by the user or device policy; will
         * not be automatically filled in with data from the app if the app has marked its
         * window as secure.
         */
        public @Nullable AssistContent getAssistContent() {
            return mContent;
        }
    }

    /**
     * Represents the id of an assist source activity. You can use
     * {@link #equals(Object)} to compare instances of this class.
     */
    public static class ActivityId {
        private final int mTaskId;
        private final IBinder mAssistToken;

        ActivityId(int taskId, IBinder assistToken) {
            mTaskId = taskId;
            mAssistToken = assistToken;
        }

        int getTaskId() {
            return mTaskId;
        }

        IBinder getAssistToken() {
            return mAssistToken;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) {
                return true;
            }
            if (o == null || getClass() != o.getClass()) {
                return false;
            }

            ActivityId that = (ActivityId) o;

            if (mTaskId != that.mTaskId) {
                return false;
            }
            return mAssistToken != null
                    ? mAssistToken.equals(that.mAssistToken)
                    : that.mAssistToken == null;
        }

        @Override
        public int hashCode() {
            int result = mTaskId;
            result = 31 * result + (mAssistToken != null ? mAssistToken.hashCode() : 0);
            return result;
        }
    }

    private static class SafeResultListener implements RemoteCallback.OnResultListener {
        private final @NonNull WeakReference<VoiceInteractionSession> mWeakSession;

        SafeResultListener(@NonNull Consumer<Bundle> action,
                @NonNull VoiceInteractionSession session) {
            mWeakSession = new WeakReference<>(session);
        }

        @Override
        public void onResult(Bundle result) {
            final VoiceInteractionSession session = mWeakSession.get();
            if (session != null) {
                final Consumer<Bundle> consumer = session.removeSafeResultListener(this);
                if (consumer != null) {
                    consumer.accept(result);
                }
            }
        }
    }
}
