/*
 * 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.app;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.RemoteException;
import android.util.ArrayMap;
import android.util.DebugUtils;
import android.util.Log;
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 java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;

/**
 * Interface for an {@link Activity} to interact with the user through voice.  Use
 * {@link android.app.Activity#getVoiceInteractor() Activity.getVoiceInteractor}
 * to retrieve the interface, if the activity is currently involved in a voice interaction.
 *
 * <p>The voice interactor revolves around submitting voice interaction requests to the
 * back-end voice interaction service that is working with the user.  These requests are
 * submitted with {@link #submitRequest}, providing a new instance of a
 * {@link Request} subclass describing the type of operation to perform -- currently the
 * possible requests are {@link ConfirmationRequest} and {@link CommandRequest}.
 *
 * <p>Once a request is submitted, the voice system will process it and eventually deliver
 * the result to the request object.  The application can cancel a pending request at any
 * time.
 *
 * <p>The VoiceInteractor is integrated with Activity's state saving mechanism, so that
 * if an activity is being restarted with retained state, it will retain the current
 * VoiceInteractor and any outstanding requests.  Because of this, you should always use
 * {@link Request#getActivity() Request.getActivity} to get back to the activity of a
 * request, rather than holding on to the activity instance yourself, either explicitly
 * or implicitly through a non-static inner class.
 */
public final class VoiceInteractor {
    static final String TAG = "VoiceInteractor";
    static final boolean DEBUG = false;

    static final Request[] NO_REQUESTS = new Request[0];

    final IVoiceInteractor mInteractor;

    Context mContext;
    Activity mActivity;
    boolean mRetaining;

    final HandlerCaller mHandlerCaller;
    final HandlerCaller.Callback mHandlerCallerCallback = new HandlerCaller.Callback() {
        @Override
        public void executeMessage(Message msg) {
            SomeArgs args = (SomeArgs)msg.obj;
            Request request;
            boolean complete;
            switch (msg.what) {
                case MSG_CONFIRMATION_RESULT:
                    request = pullRequest((IVoiceInteractorRequest)args.arg1, true);
                    if (DEBUG) Log.d(TAG, "onConfirmResult: req="
                            + ((IVoiceInteractorRequest)args.arg1).asBinder() + "/" + request
                            + " confirmed=" + msg.arg1 + " result=" + args.arg2);
                    if (request != null) {
                        ((ConfirmationRequest)request).onConfirmationResult(msg.arg1 != 0,
                                (Bundle) args.arg2);
                        request.clear();
                    }
                    break;
                case MSG_PICK_OPTION_RESULT:
                    complete = msg.arg1 != 0;
                    request = pullRequest((IVoiceInteractorRequest)args.arg1, complete);
                    if (DEBUG) Log.d(TAG, "onPickOptionResult: req="
                            + ((IVoiceInteractorRequest)args.arg1).asBinder() + "/" + request
                            + " finished=" + complete + " selection=" + args.arg2
                            + " result=" + args.arg3);
                    if (request != null) {
                        ((PickOptionRequest)request).onPickOptionResult(complete,
                                (PickOptionRequest.Option[]) args.arg2, (Bundle) args.arg3);
                        if (complete) {
                            request.clear();
                        }
                    }
                    break;
                case MSG_COMPLETE_VOICE_RESULT:
                    request = pullRequest((IVoiceInteractorRequest)args.arg1, true);
                    if (DEBUG) Log.d(TAG, "onCompleteVoice: req="
                            + ((IVoiceInteractorRequest)args.arg1).asBinder() + "/" + request
                            + " result=" + args.arg2);
                    if (request != null) {
                        ((CompleteVoiceRequest)request).onCompleteResult((Bundle) args.arg2);
                        request.clear();
                    }
                    break;
                case MSG_ABORT_VOICE_RESULT:
                    request = pullRequest((IVoiceInteractorRequest)args.arg1, true);
                    if (DEBUG) Log.d(TAG, "onAbortVoice: req="
                            + ((IVoiceInteractorRequest)args.arg1).asBinder() + "/" + request
                            + " result=" + args.arg2);
                    if (request != null) {
                        ((AbortVoiceRequest)request).onAbortResult((Bundle) args.arg2);
                        request.clear();
                    }
                    break;
                case MSG_COMMAND_RESULT:
                    complete = msg.arg1 != 0;
                    request = pullRequest((IVoiceInteractorRequest)args.arg1, complete);
                    if (DEBUG) Log.d(TAG, "onCommandResult: req="
                            + ((IVoiceInteractorRequest)args.arg1).asBinder() + "/" + request
                            + " completed=" + msg.arg1 + " result=" + args.arg2);
                    if (request != null) {
                        ((CommandRequest)request).onCommandResult(msg.arg1 != 0,
                                (Bundle) args.arg2);
                        if (complete) {
                            request.clear();
                        }
                    }
                    break;
                case MSG_CANCEL_RESULT:
                    request = pullRequest((IVoiceInteractorRequest)args.arg1, true);
                    if (DEBUG) Log.d(TAG, "onCancelResult: req="
                            + ((IVoiceInteractorRequest)args.arg1).asBinder() + "/" + request);
                    if (request != null) {
                        request.onCancel();
                        request.clear();
                    }
                    break;
            }
        }
    };

    final IVoiceInteractorCallback.Stub mCallback = new IVoiceInteractorCallback.Stub() {
        @Override
        public void deliverConfirmationResult(IVoiceInteractorRequest request, boolean finished,
                Bundle result) {
            mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageIOO(
                    MSG_CONFIRMATION_RESULT, finished ? 1 : 0, request, result));
        }

        @Override
        public void deliverPickOptionResult(IVoiceInteractorRequest request,
                boolean finished, PickOptionRequest.Option[] options, Bundle result) {
            mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageIOOO(
                    MSG_PICK_OPTION_RESULT, finished ? 1 : 0, request, options, result));
        }

        @Override
        public void deliverCompleteVoiceResult(IVoiceInteractorRequest request, Bundle result) {
            mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageOO(
                    MSG_COMPLETE_VOICE_RESULT, request, result));
        }

        @Override
        public void deliverAbortVoiceResult(IVoiceInteractorRequest request, Bundle result) {
            mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageOO(
                    MSG_ABORT_VOICE_RESULT, request, result));
        }

        @Override
        public void deliverCommandResult(IVoiceInteractorRequest request, boolean complete,
                Bundle result) {
            mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageIOO(
                    MSG_COMMAND_RESULT, complete ? 1 : 0, request, result));
        }

        @Override
        public void deliverCancel(IVoiceInteractorRequest request) throws RemoteException {
            mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageOO(
                    MSG_CANCEL_RESULT, request, null));
        }
    };

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

    static final int MSG_CONFIRMATION_RESULT = 1;
    static final int MSG_PICK_OPTION_RESULT = 2;
    static final int MSG_COMPLETE_VOICE_RESULT = 3;
    static final int MSG_ABORT_VOICE_RESULT = 4;
    static final int MSG_COMMAND_RESULT = 5;
    static final int MSG_CANCEL_RESULT = 6;

    /**
     * Base class for voice interaction requests that can be submitted to the interactor.
     * Do not instantiate this directly -- instead, use the appropriate subclass.
     */
    public static abstract class Request {
        IVoiceInteractorRequest mRequestInterface;
        Context mContext;
        Activity mActivity;
        String mName;

        Request() {
        }

        /**
         * Return the name this request was submitted through
         * {@link #submitRequest(android.app.VoiceInteractor.Request, String)}.
         */
        public String getName() {
            return mName;
        }

        /**
         * Cancel this active request.
         */
        public void cancel() {
            if (mRequestInterface == null) {
                throw new IllegalStateException("Request " + this + " is no longer active");
            }
            try {
                mRequestInterface.cancel();
            } catch (RemoteException e) {
                Log.w(TAG, "Voice interactor has died", e);
            }
        }

        /**
         * Return the current {@link Context} this request is associated with.  May change
         * if the activity hosting it goes through a configuration change.
         */
        public Context getContext() {
            return mContext;
        }

        /**
         * Return the current {@link Activity} this request is associated with.  Will change
         * if the activity is restarted such as through a configuration change.
         */
        public Activity getActivity() {
            return mActivity;
        }

        /**
         * Report from voice interaction service: this operation has been canceled, typically
         * as a completion of a previous call to {@link #cancel} or when the user explicitly
         * cancelled.
         */
        public void onCancel() {
        }

        /**
         * The request is now attached to an activity, or being re-attached to a new activity
         * after a configuration change.
         */
        public void onAttached(Activity activity) {
        }

        /**
         * The request is being detached from an activity.
         */
        public void onDetached() {
        }

        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder(128);
            DebugUtils.buildShortClassTag(this, sb);
            sb.append(" ");
            sb.append(getRequestTypeName());
            sb.append(" name=");
            sb.append(mName);
            sb.append('}');
            return sb.toString();
        }

        void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
            writer.print(prefix); writer.print("mRequestInterface=");
            writer.println(mRequestInterface.asBinder());
            writer.print(prefix); writer.print("mActivity="); writer.println(mActivity);
            writer.print(prefix); writer.print("mName="); writer.println(mName);
        }

        String getRequestTypeName() {
            return "Request";
        }

        void clear() {
            mRequestInterface = null;
            mContext = null;
            mActivity = null;
            mName = null;
        }

        abstract IVoiceInteractorRequest submit(IVoiceInteractor interactor,
                String packageName, IVoiceInteractorCallback callback) throws RemoteException;
    }

    /**
     * Confirms an operation with the user via the trusted system
     * VoiceInteractionService.  This allows an Activity to complete an unsafe operation that
     * would require the user to touch the screen when voice interaction mode is not enabled.
     * The result of the confirmation will be returned through an asynchronous call to
     * either {@link #onConfirmationResult(boolean, android.os.Bundle)} or
     * {@link #onCancel()} - these methods should be overridden to define the application specific
     *  behavior.
     *
     * <p>In some cases this may be a simple yes / no confirmation or the confirmation could
     * include context information about how the action will be completed
     * (e.g. booking a cab might include details about how long until the cab arrives)
     * so the user can give a confirmation.
     */
    public static class ConfirmationRequest extends Request {
        final Prompt mPrompt;
        final Bundle mExtras;

        /**
         * Create a new confirmation request.
         * @param prompt Optional confirmation to speak to the user or null if nothing
         *     should be spoken.
         * @param extras Additional optional information or null.
         */
        public ConfirmationRequest(@Nullable Prompt prompt, @Nullable Bundle extras) {
            mPrompt = prompt;
            mExtras = extras;
        }

        /**
         * Create a new confirmation request.
         * @param prompt Optional confirmation to speak to the user or null if nothing
         *     should be spoken.
         * @param extras Additional optional information or null.
         * @hide
         */
        public ConfirmationRequest(CharSequence prompt, Bundle extras) {
            mPrompt = (prompt != null ? new Prompt(prompt) : null);
            mExtras = extras;
        }

        /**
         * Handle the confirmation result. Override this method to define
         * the behavior when the user confirms or rejects the operation.
         * @param confirmed Whether the user confirmed or rejected the operation.
         * @param result Additional result information or null.
         */
        public void onConfirmationResult(boolean confirmed, Bundle 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 (mExtras != null) {
                writer.print(prefix); writer.print("mExtras="); writer.println(mExtras);
            }
        }

        String getRequestTypeName() {
            return "Confirmation";
        }

        IVoiceInteractorRequest submit(IVoiceInteractor interactor, String packageName,
                IVoiceInteractorCallback callback) throws RemoteException {
            return interactor.startConfirmation(packageName, callback, mPrompt, mExtras);
        }
    }

    /**
     * Select a single option from multiple potential options with the user via the trusted system
     * VoiceInteractionService. Typically, the application would present this visually as
     * a list view to allow selecting the option by touch.
     * The result of the confirmation will be returned through an asynchronous call to
     * either {@link #onPickOptionResult} or {@link #onCancel()} - these methods should
     * be overridden to define the application specific behavior.
     */
    public static class PickOptionRequest extends Request {
        final Prompt mPrompt;
        final Option[] mOptions;
        final Bundle mExtras;

        /**
         * Represents a single option that the user may select using their voice. The 
         * {@link #getIndex()} method should be used as a unique ID to identify the option
         * when it is returned from the voice interactor.
         */
        public static final class Option implements Parcelable {
            final CharSequence mLabel;
            final int mIndex;
            ArrayList<CharSequence> mSynonyms;
            Bundle mExtras;

            /**
             * Creates an option that a user can select with their voice by matching the label
             * or one of several synonyms.
             * @param label The label that will both be matched against what the user speaks
             *     and displayed visually.
             * @hide
             */
            public Option(CharSequence label) {
                mLabel = label;
                mIndex = -1;
            }

            /**
             * Creates an option that a user can select with their voice by matching the label
             * or one of several synonyms.
             * @param label The label that will both be matched against what the user speaks
             *     and displayed visually.
             * @param index The location of this option within the overall set of options.
             *     Can be used to help identify the option when it is returned from the
             *     voice interactor.
             */
            public Option(CharSequence label, int index) {
                mLabel = label;
                mIndex = index;
            }

            /**
             * Add a synonym term to the option to indicate an alternative way the content
             * may be matched.
             * @param synonym The synonym that will be matched against what the user speaks,
             *     but not displayed.
             */
            public Option addSynonym(CharSequence synonym) {
                if (mSynonyms == null) {
                    mSynonyms = new ArrayList<>();
                }
                mSynonyms.add(synonym);
                return this;
            }

            public CharSequence getLabel() {
                return mLabel;
            }

            /**
             * Return the index that was supplied in the constructor.
             * If the option was constructed without an index, -1 is returned.
             */
            public int getIndex() {
                return mIndex;
            }

            public int countSynonyms() {
                return mSynonyms != null ? mSynonyms.size() : 0;
            }

            public CharSequence getSynonymAt(int index) {
                return mSynonyms != null ? mSynonyms.get(index) : null;
            }

            /**
             * Set optional extra information associated with this option.  Note that this
             * method takes ownership of the supplied extras Bundle.
             */
            public void setExtras(Bundle extras) {
                mExtras = extras;
            }

            /**
             * Return any optional extras information associated with this option, or null
             * if there is none.  Note that this method returns a reference to the actual
             * extras Bundle in the option, so modifications to it will directly modify the
             * extras in the option.
             */
            public Bundle getExtras() {
                return mExtras;
            }

            Option(Parcel in) {
                mLabel = in.readCharSequence();
                mIndex = in.readInt();
                mSynonyms = in.readCharSequenceList();
                mExtras = in.readBundle();
            }

            @Override
            public int describeContents() {
                return 0;
            }

            @Override
            public void writeToParcel(Parcel dest, int flags) {
                dest.writeCharSequence(mLabel);
                dest.writeInt(mIndex);
                dest.writeCharSequenceList(mSynonyms);
                dest.writeBundle(mExtras);
            }

            public static final Parcelable.Creator<Option> CREATOR
                    = new Parcelable.Creator<Option>() {
                public Option createFromParcel(Parcel in) {
                    return new Option(in);
                }

                public Option[] newArray(int size) {
                    return new Option[size];
                }
            };
        };

        /**
         * Create a new pick option request.
         * @param prompt Optional question to be asked of the user when the options are
         *     presented or null if nothing should be asked.
         * @param options The set of {@link Option}s the user is selecting from.
         * @param extras Additional optional information or null.
         */
        public PickOptionRequest(@Nullable Prompt prompt, Option[] options,
                @Nullable Bundle extras) {
            mPrompt = prompt;
            mOptions = options;
            mExtras = extras;
        }

        /**
         * Create a new pick option request.
         * @param prompt Optional question to be asked of the user when the options are
         *     presented or null if nothing should be asked.
         * @param options The set of {@link Option}s the user is selecting from.
         * @param extras Additional optional information or null.
         * @hide
         */
        public PickOptionRequest(CharSequence prompt, Option[] options, Bundle extras) {
            mPrompt = (prompt != null ? new Prompt(prompt) : null);
            mOptions = options;
            mExtras = extras;
        }

        /**
         * Called when a single option is confirmed or narrowed to one of several options. Override
         * this method to define the behavior when the user selects an option or narrows down the
         * set of options.
         * @param finished True if the voice interaction has finished making a selection, in
         *     which case {@code selections} contains the final result.  If false, this request is
         *     still active and you will continue to get calls on it.
         * @param selections Either a single {@link Option} or one of several {@link Option}s the
         *     user has narrowed the choices down to.
         * @param result Additional optional information.
         */
        public void onPickOptionResult(boolean finished, Option[] selections, Bundle 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++) {
                    Option op = mOptions[i];
                    writer.print(prefix); writer.print("  #"); writer.print(i); writer.println(":");
                    writer.print(prefix); writer.print("    mLabel="); writer.println(op.mLabel);
                    writer.print(prefix); writer.print("    mIndex="); writer.println(op.mIndex);
                    if (op.mSynonyms != null && op.mSynonyms.size() > 0) {
                        writer.print(prefix); writer.println("    Synonyms:");
                        for (int j=0; j<op.mSynonyms.size(); j++) {
                            writer.print(prefix); writer.print("      #"); writer.print(j);
                            writer.print(": "); writer.println(op.mSynonyms.get(j));
                        }
                    }
                    if (op.mExtras != null) {
                        writer.print(prefix); writer.print("    mExtras=");
                        writer.println(op.mExtras);
                    }
                }
            }
            if (mExtras != null) {
                writer.print(prefix); writer.print("mExtras="); writer.println(mExtras);
            }
        }

        String getRequestTypeName() {
            return "PickOption";
        }

        IVoiceInteractorRequest submit(IVoiceInteractor interactor, String packageName,
                IVoiceInteractorCallback callback) throws RemoteException {
            return interactor.startPickOption(packageName, callback, mPrompt, mOptions, mExtras);
        }
    }

    /**
     * Reports that the current interaction was successfully completed with voice, so the
     * application can report the final status to the user. When the response comes back, the
     * voice system has handled the request and is ready to switch; at that point the
     * application can start a new non-voice activity or finish.  Be sure when starting the new
     * activity to use {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK
     * Intent.FLAG_ACTIVITY_NEW_TASK} to keep the new activity out of the current voice
     * interaction task.
     */
    public static class CompleteVoiceRequest extends Request {
        final Prompt mPrompt;
        final Bundle mExtras;

        /**
         * Create a new completed voice interaction request.
         * @param prompt Optional message to speak to the user about the completion status of
         *     the task or null if nothing should be spoken.
         * @param extras Additional optional information or null.
         */
        public CompleteVoiceRequest(@Nullable Prompt prompt, @Nullable Bundle extras) {
            mPrompt = prompt;
            mExtras = extras;
        }

        /**
         * Create a new completed voice interaction request.
         * @param message Optional message to speak to the user about the completion status of
         *     the task or null if nothing should be spoken.
         * @param extras Additional optional information or null.
         * @hide
         */
        public CompleteVoiceRequest(CharSequence message, Bundle extras) {
            mPrompt = (message != null ? new Prompt(message) : null);
            mExtras = extras;
        }

        public void onCompleteResult(Bundle 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 (mExtras != null) {
                writer.print(prefix); writer.print("mExtras="); writer.println(mExtras);
            }
        }

        String getRequestTypeName() {
            return "CompleteVoice";
        }

        IVoiceInteractorRequest submit(IVoiceInteractor interactor, String packageName,
                IVoiceInteractorCallback callback) throws RemoteException {
            return interactor.startCompleteVoice(packageName, callback, mPrompt, mExtras);
        }
    }

    /**
     * Reports that the current interaction can not be complete with voice, so the
     * application will need to switch to a traditional input UI.  Applications should
     * only use this when they need to completely bail out of the voice interaction
     * and switch to a traditional UI.  When the response comes back, the voice
     * system has handled the request and is ready to switch; at that point the application
     * can start a new non-voice activity.  Be sure when starting the new activity
     * to use {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK
     * Intent.FLAG_ACTIVITY_NEW_TASK} to keep the new activity out of the current voice
     * interaction task.
     */
    public static class AbortVoiceRequest extends Request {
        final Prompt mPrompt;
        final Bundle mExtras;

        /**
         * Create a new voice abort request.
         * @param prompt Optional message to speak to the user indicating why the task could
         *     not be completed by voice or null if nothing should be spoken.
         * @param extras Additional optional information or null.
         */
        public AbortVoiceRequest(@Nullable Prompt prompt, @Nullable Bundle extras) {
            mPrompt = prompt;
            mExtras = extras;
        }

        /**
         * Create a new voice abort request.
         * @param message Optional message to speak to the user indicating why the task could
         *     not be completed by voice or null if nothing should be spoken.
         * @param extras Additional optional information or null.
         * @hide
         */
        public AbortVoiceRequest(CharSequence message, Bundle extras) {
            mPrompt = (message != null ? new Prompt(message) : null);
            mExtras = extras;
        }

        public void onAbortResult(Bundle 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 (mExtras != null) {
                writer.print(prefix); writer.print("mExtras="); writer.println(mExtras);
            }
        }

        String getRequestTypeName() {
            return "AbortVoice";
        }

        IVoiceInteractorRequest submit(IVoiceInteractor interactor, String packageName,
                IVoiceInteractorCallback callback) throws RemoteException {
            return interactor.startAbortVoice(packageName, callback, mPrompt, mExtras);
        }
    }

    /**
     * Execute a vendor-specific command using the trusted system VoiceInteractionService.
     * This allows an Activity to request additional information from the user needed to
     * complete an action (e.g. booking a table might have several possible times that the
     * user could select from or an app might need the user to agree to a terms of service).
     * The result of the confirmation will be returned through an asynchronous call to
     * either {@link #onCommandResult(boolean, android.os.Bundle)} or
     * {@link #onCancel()}.
     *
     * <p>The command is a string that describes the generic operation to be performed.
     * The command will determine how the properties in extras are interpreted and the set of
     * available commands is expected to grow over time.  An example might be
     * "com.google.voice.commands.REQUEST_NUMBER_BAGS" to request the number of bags as part of
     * airline check-in.  (This is not an actual working example.)
     */
    public static class CommandRequest extends Request {
        final String mCommand;
        final Bundle mArgs;

        /**
         * Create a new generic command request.
         * @param command The desired command to perform.
         * @param args Additional arguments to control execution of the command.
         */
        public CommandRequest(String command, Bundle args) {
            mCommand = command;
            mArgs = args;
        }

        /**
         * Results for CommandRequest can be returned in partial chunks.
         * The isCompleted is set to true iff all results have been returned, indicating the
         * CommandRequest has completed.
         */
        public void onCommandResult(boolean isCompleted, Bundle 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);
            if (mArgs != null) {
                writer.print(prefix); writer.print("mArgs="); writer.println(mArgs);
            }
        }

        String getRequestTypeName() {
            return "Command";
        }

        IVoiceInteractorRequest submit(IVoiceInteractor interactor, String packageName,
                IVoiceInteractorCallback callback) throws RemoteException {
            return interactor.startCommand(packageName, callback, mCommand, mArgs);
        }
    }

    /**
     * A set of voice prompts to use with the voice interaction system to confirm an action, select
     * an option, or do similar operations. Multiple voice prompts may be provided for variety. A
     * visual prompt must be provided, which might not match the spoken version. For example, the
     * confirmation "Are you sure you want to purchase this item?" might use a visual label like
     * "Purchase item".
     */
    public static class Prompt implements Parcelable {
        // Mandatory voice prompt. Must contain at least one item, which must not be null.
        private final CharSequence[] mVoicePrompts;

        // Mandatory visual prompt.
        private final CharSequence mVisualPrompt;

        /**
         * Constructs a prompt set.
         * @param voicePrompts An array of one or more voice prompts. Must not be empty or null.
         * @param visualPrompt A prompt to display on the screen. Must not be null.
         */
        public Prompt(@NonNull CharSequence[] voicePrompts, @NonNull CharSequence visualPrompt) {
            if (voicePrompts == null) {
                throw new NullPointerException("voicePrompts must not be null");
            }
            if (voicePrompts.length == 0) {
                throw new IllegalArgumentException("voicePrompts must not be empty");
            }
            if (visualPrompt == null) {
                throw new NullPointerException("visualPrompt must not be null");
            }
            this.mVoicePrompts = voicePrompts;
            this.mVisualPrompt = visualPrompt;
        }

        /**
         * Constructs a prompt set with single prompt used for all interactions. This is most useful
         * in test apps. Non-trivial apps should prefer the detailed constructor.
         */
        public Prompt(@NonNull CharSequence prompt) {
            this.mVoicePrompts = new CharSequence[] { prompt };
            this.mVisualPrompt = prompt;
        }

        /**
         * Returns a prompt to use for voice interactions.
         */
        @NonNull
        public CharSequence getVoicePromptAt(int index) {
            return mVoicePrompts[index];
        }

        /**
         * Returns the number of different voice prompts.
         */
        public int countVoicePrompts() {
            return mVoicePrompts.length;
        }

        /**
         * Returns the prompt to use for visual display.
         */
        @NonNull
        public CharSequence getVisualPrompt() {
            return mVisualPrompt;
        }

        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder(128);
            DebugUtils.buildShortClassTag(this, sb);
            if (mVisualPrompt != null && mVoicePrompts != null && mVoicePrompts.length == 1
                && mVisualPrompt.equals(mVoicePrompts[0])) {
                sb.append(" ");
                sb.append(mVisualPrompt);
            } else {
                if (mVisualPrompt != null) {
                    sb.append(" visual="); sb.append(mVisualPrompt);
                }
                if (mVoicePrompts != null) {
                    sb.append(", voice=");
                    for (int i=0; i<mVoicePrompts.length; i++) {
                        if (i > 0) sb.append(" | ");
                        sb.append(mVoicePrompts[i]);
                    }
                }
            }
            sb.append('}');
            return sb.toString();
        }

        /** Constructor to support Parcelable behavior. */
        Prompt(Parcel in) {
            mVoicePrompts = in.readCharSequenceArray();
            mVisualPrompt = in.readCharSequence();
        }

        @Override
        public int describeContents() {
            return 0;
        }

        @Override
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeCharSequenceArray(mVoicePrompts);
            dest.writeCharSequence(mVisualPrompt);
        }

        public static final Creator<Prompt> CREATOR
                = new Creator<Prompt>() {
            public Prompt createFromParcel(Parcel in) {
                return new Prompt(in);
            }

            public Prompt[] newArray(int size) {
                return new Prompt[size];
            }
        };
    }

    VoiceInteractor(IVoiceInteractor interactor, Context context, Activity activity,
            Looper looper) {
        mInteractor = interactor;
        mContext = context;
        mActivity = activity;
        mHandlerCaller = new HandlerCaller(context, looper, mHandlerCallerCallback, true);
    }

    Request pullRequest(IVoiceInteractorRequest request, boolean complete) {
        synchronized (mActiveRequests) {
            Request req = mActiveRequests.get(request.asBinder());
            if (req != null && complete) {
                mActiveRequests.remove(request.asBinder());
            }
            return req;
        }
    }

    private ArrayList<Request> makeRequestList() {
        final int N = mActiveRequests.size();
        if (N < 1) {
            return null;
        }
        ArrayList<Request> list = new ArrayList<>(N);
        for (int i=0; i<N; i++) {
            list.add(mActiveRequests.valueAt(i));
        }
        return list;
    }

    void attachActivity(Activity activity) {
        mRetaining = false;
        if (mActivity == activity) {
            return;
        }
        mContext = activity;
        mActivity = activity;
        ArrayList<Request> reqs = makeRequestList();
        if (reqs != null) {
            for (int i=0; i<reqs.size(); i++) {
                Request req = reqs.get(i);
                req.mContext = activity;
                req.mActivity = activity;
                req.onAttached(activity);
            }
        }
    }

    void retainInstance() {
        mRetaining = true;
    }

    void detachActivity() {
        ArrayList<Request> reqs = makeRequestList();
        if (reqs != null) {
            for (int i=0; i<reqs.size(); i++) {
                Request req = reqs.get(i);
                req.onDetached();
                req.mActivity = null;
                req.mContext = null;
            }
        }
        if (!mRetaining) {
            reqs = makeRequestList();
            if (reqs != null) {
                for (int i=0; i<reqs.size(); i++) {
                    Request req = reqs.get(i);
                    req.cancel();
                }
            }
            mActiveRequests.clear();
        }
        mContext = null;
        mActivity = null;
    }

    public boolean submitRequest(Request request) {
        return submitRequest(request, null);
    }

    /**
     * Submit a new {@link Request} to the voice interaction service.  The request must be
     * one of the available subclasses -- {@link ConfirmationRequest}, {@link PickOptionRequest},
     * {@link CompleteVoiceRequest}, {@link AbortVoiceRequest}, or {@link CommandRequest}.
     *
     * @param request The desired request to submit.
     * @param name An optional name for this request, or null. This can be used later with
     * {@link #getActiveRequests} and {@link #getActiveRequest} to find the request.
     *
     * @return Returns true of the request was successfully submitted, else false.
     */
    public boolean submitRequest(Request request, String name) {
        try {
            if (request.mRequestInterface != null) {
                throw new IllegalStateException("Given " + request + " is already active");
            }
            IVoiceInteractorRequest ireq = request.submit(mInteractor,
                    mContext.getOpPackageName(), mCallback);
            request.mRequestInterface = ireq;
            request.mContext = mContext;
            request.mActivity = mActivity;
            request.mName = name;
            synchronized (mActiveRequests) {
                mActiveRequests.put(ireq.asBinder(), request);
            }
            return true;
        } catch (RemoteException e) {
            Log.w(TAG, "Remove voice interactor service died", e);
            return false;
        }
    }

    /**
     * Return all currently active requests.
     */
    public Request[] getActiveRequests() {
        synchronized (mActiveRequests) {
            final int N = mActiveRequests.size();
            if (N <= 0) {
                return NO_REQUESTS;
            }
            Request[] requests = new Request[N];
            for (int i=0; i<N; i++) {
                requests[i] = mActiveRequests.valueAt(i);
            }
            return requests;
        }
    }

    /**
     * Return any currently active request that was submitted with the given name.
     *
     * @param name The name used to submit the request, as per
     * {@link #submitRequest(android.app.VoiceInteractor.Request, String)}.
     * @return Returns the active request with that name, or null if there was none.
     */
    public Request getActiveRequest(String name) {
        synchronized (mActiveRequests) {
            final int N = mActiveRequests.size();
            for (int i=0; i<N; i++) {
                Request req = mActiveRequests.valueAt(i);
                if (name == req.getName() || (name != null && name.equals(req.getName()))) {
                    return req;
                }
            }
        }
        return null;
    }

    /**
     * Queries the supported commands available from the VoiceInteractionService.
     * The command is a string that describes the generic operation to be performed.
     * An example might be "org.example.commands.PICK_DATE" to ask the user to pick
     * a date.  (Note: This is not an actual working example.)
     *
     * @param commands The array of commands to query for support.
     * @return Array of booleans indicating whether each command is supported or not.
     */
    public boolean[] supportsCommands(String[] commands) {
        try {
            boolean[] res = mInteractor.supportsCommands(mContext.getOpPackageName(), commands);
            if (DEBUG) Log.d(TAG, "supportsCommands: cmds=" + commands + " res=" + res);
            return res;
        } catch (RemoteException e) {
            throw new RuntimeException("Voice interactor has died", e);
        }
    }

    void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
        String innerPrefix = prefix + "    ";
        if (mActiveRequests.size() > 0) {
            writer.print(prefix); writer.println("Active voice requests:");
            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);
            }
        }
        writer.print(prefix); writer.println("VoiceInteractor misc state:");
        writer.print(prefix); writer.print("  mInteractor=");
        writer.println(mInteractor.asBinder());
        writer.print(prefix); writer.print("  mActivity="); writer.println(mActivity);
    }
}
