Merge "Fix issue #22124996: VI: Command Request not Active" into mnc-dev
diff --git a/api/current.txt b/api/current.txt
index 376c2c3..3ae5372 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5805,7 +5805,7 @@
 
 package android.app.assist {
 
-  public deprecated class AssistContent implements android.os.Parcelable {
+  public class AssistContent implements android.os.Parcelable {
     ctor public AssistContent();
     method public int describeContents();
     method public android.content.ClipData getClipData();
diff --git a/api/system-current.txt b/api/system-current.txt
index 57f3a30..8a633df 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -5937,7 +5937,7 @@
 
 package android.app.assist {
 
-  public deprecated class AssistContent implements android.os.Parcelable {
+  public class AssistContent implements android.os.Parcelable {
     ctor public AssistContent();
     method public int describeContents();
     method public android.content.ClipData getClipData();
diff --git a/core/java/android/app/assist/AssistContent.java b/core/java/android/app/assist/AssistContent.java
index 07b2d57..cddf47a 100644
--- a/core/java/android/app/assist/AssistContent.java
+++ b/core/java/android/app/assist/AssistContent.java
@@ -12,7 +12,6 @@
  * assistant at the user's request.  This is filled in by
  * {@link android.app.Activity#onProvideAssistContent Activity.onProvideAssistContent}.
  */
-@Deprecated
 public class AssistContent implements Parcelable {
     private boolean mIsAppProvidedIntent = false;
     private Intent mIntent;
diff --git a/core/java/android/service/voice/VoiceInteractionService.java b/core/java/android/service/voice/VoiceInteractionService.java
index 8119049..549c93e 100644
--- a/core/java/android/service/voice/VoiceInteractionService.java
+++ b/core/java/android/service/voice/VoiceInteractionService.java
@@ -172,15 +172,6 @@
         }
     }
 
-    /** @hide */
-    public void startSession(Bundle args, int flags) {
-        showSession(args, flags);
-    }
-    /** @hide */
-    public void startSession(Bundle args) {
-        startSession(args, 0);
-    }
-
     @Override
     public void onCreate() {
         super.onCreate();
diff --git a/core/java/android/service/voice/VoiceInteractionSession.java b/core/java/android/service/voice/VoiceInteractionSession.java
index f9e216a..7eb936a 100644
--- a/core/java/android/service/voice/VoiceInteractionSession.java
+++ b/core/java/android/service/voice/VoiceInteractionSession.java
@@ -71,7 +71,7 @@
  */
 public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCallbacks2 {
     static final String TAG = "VoiceInteractionSession";
-    static final boolean DEBUG = true;
+    static final boolean DEBUG = false;
 
     /**
      * Flag received in {@link #onShow}: originator requested that the session be started with
@@ -175,6 +175,7 @@
             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;
@@ -249,16 +250,12 @@
         }
     };
 
-    /** @hide */
-    public static class Caller {
-    }
-
     /**
      * 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 extends Caller {
+    public static class Request {
         final IVoiceInteractorRequest mInterface = new IVoiceInteractorRequest.Stub() {
             @Override
             public void cancel() throws RemoteException {
@@ -319,74 +316,8 @@
             }
         }
 
-        /** @hide */
-        public void sendConfirmResult(boolean confirmed, Bundle result) {
-            try {
-                if (DEBUG) Log.d(TAG, "sendConfirmResult: req=" + mInterface
-                        + " confirmed=" + confirmed + " result=" + result);
-                finishRequest();
-                mCallback.deliverConfirmationResult(mInterface, confirmed, result);
-            } catch (RemoteException e) {
-            }
-        }
-
-        /** @hide */
-        public 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) {
-            }
-        }
-
-        /** @hide */
-        public void sendCompleteVoiceResult(Bundle result) {
-            try {
-                if (DEBUG) Log.d(TAG, "sendCompleteVoiceResult: req=" + mInterface
-                        + " result=" + result);
-                finishRequest();
-                mCallback.deliverCompleteVoiceResult(mInterface, result);
-            } catch (RemoteException e) {
-            }
-        }
-
-        /** @hide */
-        public void sendAbortVoiceResult(Bundle result) {
-            try {
-                if (DEBUG) Log.d(TAG, "sendConfirmResult: req=" + mInterface
-                        + " result=" + result);
-                finishRequest();
-                mCallback.deliverAbortVoiceResult(mInterface, result);
-            } catch (RemoteException e) {
-            }
-        }
-
-        /** @hide */
-        public 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) {
-            }
-        }
-
-        /** @hide */
-        public void sendCancelResult() {
-            cancel();
-        }
-
         /**
-         * ASk the app to cancelLocked this current request.
+         * Ask the app to cancel this current request.
          */
         public void cancel() {
             try {
@@ -440,7 +371,13 @@
          * VoiceInteractor.ConfirmationRequest.onConfirmationResult}.
          */
         public void sendConfirmationResult(boolean confirmed, Bundle result) {
-            sendConfirmResult(confirmed, result);
+            try {
+                if (DEBUG) Log.d(TAG, "sendConfirmationResult: req=" + mInterface
+                        + " confirmed=" + confirmed + " result=" + result);
+                finishRequest();
+                mCallback.deliverConfirmationResult(mInterface, confirmed, result);
+            } catch (RemoteException e) {
+            }
         }
     }
 
@@ -487,6 +424,20 @@
             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),
@@ -553,7 +504,13 @@
          * VoiceInteractor.CompleteVoiceRequest.onCompleteResult}.
          */
         public void sendCompleteResult(Bundle result) {
-            sendCompleteVoiceResult(result);
+            try {
+                if (DEBUG) Log.d(TAG, "sendCompleteVoiceResult: req=" + mInterface
+                        + " result=" + result);
+                finishRequest();
+                mCallback.deliverCompleteVoiceResult(mInterface, result);
+            } catch (RemoteException e) {
+            }
         }
     }
 
@@ -596,7 +553,13 @@
          * VoiceInteractor.AbortVoiceRequest.onAbortResult}.
          */
         public void sendAbortResult(Bundle result) {
-            sendAbortVoiceResult(result);
+            try {
+                if (DEBUG) Log.d(TAG, "sendConfirmResult: req=" + mInterface
+                        + " result=" + result);
+                finishRequest();
+                mCallback.deliverAbortVoiceResult(mInterface, result);
+            } catch (RemoteException e) {
+            }
         }
     }
 
@@ -621,6 +584,18 @@
             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
@@ -829,11 +804,10 @@
         }
     }
 
-    void doCreate(IVoiceInteractionManagerService service, IBinder token, Bundle args,
-            int startFlags) {
+    void doCreate(IVoiceInteractionManagerService service, IBinder token) {
         mSystemService = service;
         mToken = token;
-        onCreate(args, startFlags);
+        onCreate();
     }
 
     void doShow(Bundle args, int flags, final IVoiceInteractionSessionShowCallback showCallback) {
@@ -919,11 +893,6 @@
         mContentFrame = (FrameLayout)mRootView.findViewById(android.R.id.content);
     }
 
-    /** @hide */
-    public void show() {
-        show(null, 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
@@ -958,14 +927,6 @@
         }
     }
 
-    /** @hide */
-    public void showWindow() {
-    }
-
-    /** @hide */
-    public void hideWindow() {
-    }
-
     /**
      * You can call this to customize the theme used by your IME's window.
      * This must be set before {@link #onCreate}, so you
@@ -1062,7 +1023,6 @@
         if (mToken == null) {
             throw new IllegalStateException("Can't call before onCreate()");
         }
-        hideWindow();
         try {
             mSystemService.finish(mToken);
         } catch (RemoteException e) {
@@ -1077,16 +1037,6 @@
         doOnCreate();
     }
 
-    /** @hide */
-    public void onCreate(Bundle args) {
-        doOnCreate();
-    }
-
-    /** @hide */
-    public void onCreate(Bundle args, int showFlags) {
-        doOnCreate();
-    }
-
     private void doOnCreate() {
         mTheme = mTheme != 0 ? mTheme
                 : com.android.internal.R.style.Theme_DeviceDefault_VoiceInteractionSession;
@@ -1244,34 +1194,6 @@
         hide();
     }
 
-    /** @hide */
-    public boolean[] onGetSupportedCommands(Caller caller, String[] commands) {
-        return new boolean[commands.length];
-    }
-    /** @hide */
-    public void onConfirm(Caller caller, Request request, CharSequence prompt,
-            Bundle extras) {
-    }
-    /** @hide */
-    public void onPickOption(Caller caller, Request request, CharSequence prompt,
-            VoiceInteractor.PickOptionRequest.Option[] options, Bundle extras) {
-    }
-    /** @hide */
-    public void onCompleteVoice(Caller caller, Request request, CharSequence message,
-           Bundle extras) {
-        request.sendCompleteVoiceResult(null);
-    }
-    /** @hide */
-    public void onAbortVoice(Caller caller, Request request, CharSequence message, Bundle extras) {
-        request.sendAbortVoiceResult(null);
-    }
-    /** @hide */
-    public void onCommand(Caller caller, Request request, String command, Bundle extras) {
-    }
-    /** @hide */
-    public void onCancel(Request request) {
-    }
-
     /**
      * Request to query for what extended commands the session supports.
      *
@@ -1282,7 +1204,7 @@
      * an array of all false entries.
      */
     public boolean[] onGetSupportedCommands(String[] commands) {
-        return onGetSupportedCommands(new Caller(), commands);
+        return new boolean[commands.length];
     }
 
     /**
@@ -1293,7 +1215,6 @@
      * @param request The active request.
      */
     public void onRequestConfirmation(ConfirmationRequest request) {
-        onConfirm(request, request, request.getPrompt(), request.getExtras());
     }
 
     /**
@@ -1303,8 +1224,6 @@
      * @param request The active request.
      */
     public void onRequestPickOption(PickOptionRequest request) {
-        onPickOption(request, request, request.getPrompt(), request.getOptions(),
-                request.getExtras());
     }
 
     /**
@@ -1317,7 +1236,6 @@
      * @param request The active request.
      */
     public void onRequestCompleteVoice(CompleteVoiceRequest request) {
-        onCompleteVoice(request, request, request.getMessage(), request.getExtras());
     }
 
     /**
@@ -1330,7 +1248,6 @@
      * @param request The active request.
      */
     public void onRequestAbortVoice(AbortVoiceRequest request) {
-        onAbortVoice(request, request, request.getMessage(), request.getExtras());
     }
 
     /**
@@ -1341,11 +1258,10 @@
      * @param request The active request.
      */
     public void onRequestCommand(CommandRequest request) {
-        onCommand(request, request, request.getCommand(), request.getExtras());
     }
 
     /**
-     * Called when the {@link android.app.VoiceInteractor} has asked to cancelLocked a {@link 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}.
@@ -1353,6 +1269,5 @@
      * @param request The request that is being canceled.
      */
     public void onCancelRequest(Request request) {
-        onCancel(request);
     }
 }
diff --git a/core/java/android/service/voice/VoiceInteractionSessionService.java b/core/java/android/service/voice/VoiceInteractionSessionService.java
index 8f988f3..fb9f973 100644
--- a/core/java/android/service/voice/VoiceInteractionSessionService.java
+++ b/core/java/android/service/voice/VoiceInteractionSessionService.java
@@ -109,7 +109,7 @@
         mSession = onNewSession(args);
         try {
             mSystemService.deliverNewSession(token, mSession.mSession, mSession.mInteractor);
-            mSession.doCreate(mSystemService, token, args, startFlags);
+            mSession.doCreate(mSystemService, token);
         } catch (RemoteException e) {
         }
     }
diff --git a/tests/Assist/src/com/android/test/assist/AssistInteractionSession.java b/tests/Assist/src/com/android/test/assist/AssistInteractionSession.java
index e4ea0bc..43f1e32 100644
--- a/tests/Assist/src/com/android/test/assist/AssistInteractionSession.java
+++ b/tests/Assist/src/com/android/test/assist/AssistInteractionSession.java
@@ -52,28 +52,23 @@
     }
 
     @Override
-    public void onConfirm(Caller caller,
-            Request request, CharSequence prompt, Bundle extras) {
-
+    public void onRequestConfirmation(ConfirmationRequest request) {
     }
 
     @Override
-    public void onPickOption(Caller caller,
-            Request request, CharSequence prompt,
-            VoiceInteractor.PickOptionRequest.Option[] options, Bundle extras) {
-
+    public void onRequestPickOption(PickOptionRequest request) {
     }
 
     @Override
-    public void onCommand(Caller caller,
-            Request request, String command, Bundle extras) {
-
+    public void onRequestCommand(CommandRequest request) {
     }
 
     @Override
-    public void onCreate(Bundle args) {
-        super.onCreate(args);
+    public void onCancelRequest(Request request) {
+    }
 
+    @Override
+    public void onCreate() {
         // Simulate slowness of Assist app
         try {
             Thread.sleep(1000);
@@ -83,11 +78,6 @@
     }
 
     @Override
-    public void onCancel(Request request) {
-
-    }
-
-    @Override
     public View onCreateContentView() {
         View v = getLayoutInflater().inflate(R.layout.assist, null);
         mScrim = v.findViewById(R.id.scrim);
diff --git a/tests/VoiceInteraction/res/layout/test_interaction.xml b/tests/VoiceInteraction/res/layout/test_interaction.xml
index 6209bd08..d1a7ad5 100644
--- a/tests/VoiceInteraction/res/layout/test_interaction.xml
+++ b/tests/VoiceInteraction/res/layout/test_interaction.xml
@@ -51,6 +51,19 @@
             android:text="@string/abortVoice"
             />
 
+    </LinearLayout>
+
+    <LinearLayout android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="16dp"
+        android:orientation="horizontal">
+
+        <Button android:id="@+id/command"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/commandVoice"
+            />
+
         <Button android:id="@+id/pick"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
diff --git a/tests/VoiceInteraction/res/values/strings.xml b/tests/VoiceInteraction/res/values/strings.xml
index 4cf4104..cf660e6 100644
--- a/tests/VoiceInteraction/res/values/strings.xml
+++ b/tests/VoiceInteraction/res/values/strings.xml
@@ -24,6 +24,7 @@
     <string name="abort">Abort</string>
     <string name="complete">Complete</string>
     <string name="abortVoice">Abort Voice</string>
+    <string name="commandVoice">Command</string>
     <string name="completeVoice">Complete Voice</string>
     <string name="pickVoice">Pick Voice</string>
     <string name="cancelVoice">Cancel</string>
diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java
index 578e356..8381aa1 100644
--- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java
+++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java
@@ -80,7 +80,8 @@
             Bundle args = new Bundle();
             args.putParcelable("intent", new Intent(this, TestInteractionActivity.class));
             args.putBundle("assist", intent.getExtras());
-            startSession(args, VoiceInteractionSession.SHOW_WITH_ASSIST | VoiceInteractionSession.SHOW_WITH_SCREENSHOT);
+            showSession(args, VoiceInteractionSession.SHOW_WITH_ASSIST
+                    | VoiceInteractionSession.SHOW_WITH_SCREENSHOT);
         } else {
             Log.w(TAG, "Not starting -- not current voice interaction service");
         }
diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java
index 97c1e85..a6585ba 100644
--- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java
+++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java
@@ -60,7 +60,7 @@
     static final int STATE_COMMAND = 4;
     static final int STATE_ABORT_VOICE = 5;
     static final int STATE_COMPLETE_VOICE = 6;
-    static final int STATE_DONE=7;
+    static final int STATE_DONE = 7;
 
     int mState = STATE_IDLE;
     VoiceInteractor.PickOptionRequest.Option[] mPendingOptions;
@@ -72,8 +72,8 @@
     }
 
     @Override
-    public void onCreate(Bundle args, int startFlags) {
-        super.onCreate(args, startFlags);
+    public void onCreate() {
+        super.onCreate();
         ActivityManager am = getContext().getSystemService(ActivityManager.class);
         am.setWatchHeapLimit(40 * 1024 * 1024);
     }
@@ -163,8 +163,8 @@
         if (screenshot != null) {
             mScreenshot.setImageBitmap(screenshot);
             mScreenshot.setAdjustViewBounds(true);
-            mScreenshot.setMaxWidth(screenshot.getWidth()/3);
-            mScreenshot.setMaxHeight(screenshot.getHeight()/3);
+            mScreenshot.setMaxWidth(screenshot.getWidth() / 3);
+            mScreenshot.setMaxHeight(screenshot.getHeight() / 3);
             mFullScreenshot.setImageBitmap(screenshot);
         } else {
             mScreenshot.setImageDrawable(null);
@@ -207,11 +207,12 @@
             updateState();
             startVoiceActivity(mStartIntent);
         } else if (v == mConfirmButton) {
-            if (mState == STATE_CONFIRM) {
-                mPendingRequest.sendConfirmResult(true, null);
+            if (mPendingRequest instanceof ConfirmationRequest) {
+                ((ConfirmationRequest)mPendingRequest).sendConfirmationResult(true, null);
                 mPendingRequest = null;
                 mState = STATE_LAUNCHING;
-            } else if (mState == STATE_PICK_OPTION) {
+            } else if (mPendingRequest instanceof PickOptionRequest) {
+                PickOptionRequest pick = (PickOptionRequest)mPendingRequest;
                 int numReturn = mPendingOptions.length/2;
                 if (numReturn <= 0) {
                     numReturn = 1;
@@ -223,23 +224,25 @@
                 }
                 mPendingOptions = picked;
                 if (picked.length <= 1) {
-                    mPendingRequest.sendPickOptionResult(true, picked, null);
+                    pick.sendPickOptionResult(picked, null);
                     mPendingRequest = null;
                     mState = STATE_LAUNCHING;
                 } else {
-                    mPendingRequest.sendPickOptionResult(false, picked, null);
+                    pick.sendIntermediatePickOptionResult(picked, null);
                     updatePickText();
                 }
-            } else if (mPendingRequest != null) {
-                mPendingRequest.sendCommandResult(true, null);
+            } else if (mPendingRequest instanceof CommandRequest) {
+                Bundle result = new Bundle();
+                result.putString("key", "a result!");
+                ((CommandRequest)mPendingRequest).sendResult(result);
                 mPendingRequest = null;
                 mState = STATE_LAUNCHING;
             }
-        } else if (v == mAbortButton) {
-            mPendingRequest.sendAbortVoiceResult(null);
+        } else if (v == mAbortButton && mPendingRequest instanceof AbortVoiceRequest) {
+            ((AbortVoiceRequest)mPendingRequest).sendAbortResult(null);
             mPendingRequest = null;
-        } else if (v == mCompleteButton) {
-            mPendingRequest.sendCompleteVoiceResult(null);
+        } else if (v == mCompleteButton && mPendingRequest instanceof CompleteVoiceRequest) {
+            ((CompleteVoiceRequest)mPendingRequest).sendCompleteResult(null);
             mPendingRequest = null;
         } else if (v == mScreenshot) {
             if (mFullScreenshot.getVisibility() != View.VISIBLE) {
@@ -261,29 +264,45 @@
     }
 
     @Override
-    public boolean[] onGetSupportedCommands(Caller caller, String[] commands) {
-        return new boolean[commands.length];
+    public boolean[] onGetSupportedCommands(String[] commands) {
+        boolean[] res = new boolean[commands.length];
+        for (int i=0; i<commands.length; i++) {
+            if ("com.android.test.voiceinteraction.COMMAND".equals(commands[i])) {
+                res[i] = true;
+            }
+        }
+        return res;
     }
 
+    void setPrompt(VoiceInteractor.Prompt prompt) {
+        if (prompt == null) {
+            mText.setText("(null)");
+            mPendingPrompt = "";
+        } else {
+            mText.setText(prompt.getVisualPrompt());
+            mPendingPrompt = prompt.getVisualPrompt();
+        }
+    }
+      
     @Override
-    public void onConfirm(Caller caller, Request request, CharSequence prompt, Bundle extras) {
-        Log.i(TAG, "onConfirm: prompt=" + prompt + " extras=" + extras);
-        mText.setText(prompt);
+    public void onRequestConfirmation(ConfirmationRequest request) {
+        Log.i(TAG, "onConfirm: prompt=" + request.getVoicePrompt() + " extras="
+                + request.getExtras());
+        setPrompt(request.getVoicePrompt());
         mConfirmButton.setText("Confirm");
         mPendingRequest = request;
-        mPendingPrompt = prompt;
         mState = STATE_CONFIRM;
         updateState();
     }
 
     @Override
-    public void onPickOption(Caller caller, Request request, CharSequence prompt,
-            VoiceInteractor.PickOptionRequest.Option[] options, Bundle extras) {
-        Log.i(TAG, "onPickOption: prompt=" + prompt + " options=" + options + " extras=" + extras);
+    public void onRequestPickOption(PickOptionRequest request) {
+        Log.i(TAG, "onPickOption: prompt=" + request.getVoicePrompt() + " options="
+                + request.getOptions() + " extras=" + request.getExtras());
         mConfirmButton.setText("Pick Option");
         mPendingRequest = request;
-        mPendingPrompt = prompt;
-        mPendingOptions = options;
+        setPrompt(request.getVoicePrompt());
+        mPendingOptions = request.getOptions();
         mState = STATE_PICK_OPTION;
         updatePickText();
         updateState();
@@ -303,27 +322,33 @@
     }
 
     @Override
-    public void onCompleteVoice(Caller caller, Request request, CharSequence message, Bundle extras) {
-        Log.i(TAG, "onCompleteVoice: message=" + message + " extras=" + extras);
-        mText.setText(message);
+    public void onRequestCompleteVoice(CompleteVoiceRequest request) {
+        Log.i(TAG, "onCompleteVoice: message=" + request.getVoicePrompt() + " extras="
+                + request.getExtras());
+        setPrompt(request.getVoicePrompt());
         mPendingRequest = request;
         mState = STATE_COMPLETE_VOICE;
         updateState();
     }
 
     @Override
-    public void onAbortVoice(Caller caller, Request request, CharSequence message, Bundle extras) {
-        Log.i(TAG, "onAbortVoice: message=" + message + " extras=" + extras);
-        mText.setText(message);
+    public void onRequestAbortVoice(AbortVoiceRequest request) {
+        Log.i(TAG, "onAbortVoice: message=" + request.getVoicePrompt() + " extras="
+                + request.getExtras());
+        setPrompt(request.getVoicePrompt());
         mPendingRequest = request;
         mState = STATE_ABORT_VOICE;
         updateState();
     }
 
     @Override
-    public void onCommand(Caller caller, Request request, String command, Bundle extras) {
-        Log.i(TAG, "onCommand: command=" + command + " extras=" + extras);
-        mText.setText("Command: " + command);
+    public void onRequestCommand(CommandRequest request) {
+        Bundle extras = request.getExtras();
+        if (extras != null) {
+            extras.getString("arg");
+        }
+        Log.i(TAG, "onCommand: command=" + request.getCommand() + " extras=" + extras);
+        mText.setText("Command: " + request.getCommand() + ", " + extras);
         mConfirmButton.setText("Finish Command");
         mPendingRequest = request;
         mState = STATE_COMMAND;
@@ -331,8 +356,13 @@
     }
 
     @Override
-    public void onCancel(Request request) {
+    public void onCancelRequest(Request request) {
         Log.i(TAG, "onCancel");
-        request.sendCancelResult();
+        if (mPendingRequest == request) {
+            mPendingRequest = null;
+            mState = STATE_LAUNCHING;
+            updateState();
+        }
+        request.cancel();
     }
 }
diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/TestInteractionActivity.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/TestInteractionActivity.java
index 943c647..2487e1ca 100644
--- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/TestInteractionActivity.java
+++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/TestInteractionActivity.java
@@ -33,6 +33,7 @@
 
     static final String REQUEST_ABORT = "abort";
     static final String REQUEST_COMPLETE = "complete";
+    static final String REQUEST_COMMAND = "command";
     static final String REQUEST_PICK = "pick";
     static final String REQUEST_CONFIRM = "confirm";
 
@@ -41,6 +42,7 @@
     TextView mLog;
     Button mAbortButton;
     Button mCompleteButton;
+    Button mCommandButton;
     Button mPickButton;
     Button mJumpOutButton;
     Button mCancelButton;
@@ -68,6 +70,8 @@
         mAbortButton.setOnClickListener(this);
         mCompleteButton = (Button)findViewById(R.id.complete);
         mCompleteButton.setOnClickListener(this);
+        mCommandButton = (Button)findViewById(R.id.command);
+        mCommandButton.setOnClickListener(this);
         mPickButton = (Button)findViewById(R.id.pick);
         mPickButton.setOnClickListener(this);
         mJumpOutButton = (Button)findViewById(R.id.jump);
@@ -117,6 +121,9 @@
         } else if (v == mCompleteButton) {
             VoiceInteractor.CompleteVoiceRequest req = new TestCompleteVoice();
             mInteractor.submitRequest(req, REQUEST_COMPLETE);
+        } else if (v == mCommandButton) {
+            VoiceInteractor.CommandRequest req = new TestCommand("Some arg");
+            mInteractor.submitRequest(req, REQUEST_COMMAND);
         } else if (v == mPickButton) {
             VoiceInteractor.PickOptionRequest.Option[] options =
                     new VoiceInteractor.PickOptionRequest.Option[5];
@@ -176,6 +183,37 @@
         }
     }
 
+    static class TestCommand extends VoiceInteractor.CommandRequest {
+        public TestCommand(String arg) {
+            super("com.android.test.voiceinteraction.COMMAND", makeBundle(arg));
+        }
+        @Override public void onCancel() {
+            Log.i(TAG, "Canceled!");
+            ((TestInteractionActivity)getActivity()).mLog.append("Canceled command\n");
+        }
+        @Override
+        public void onCommandResult(boolean finished, Bundle result) {
+            Log.i(TAG, "Command result: finished=" + finished + " result=" + result);
+            StringBuilder sb = new StringBuilder();
+            if (finished) {
+                sb.append("Command final result: ");
+            } else {
+                sb.append("Command intermediate result: ");
+            }
+            if (result != null) {
+                result.getString("key");
+            }
+            sb.append(result);
+            sb.append("\n");
+            ((TestInteractionActivity)getActivity()).mLog.append(sb.toString());
+        }
+        static Bundle makeBundle(String arg) {
+            Bundle b = new Bundle();
+            b.putString("key", arg);
+            return b;
+        }
+    }
+
     static class TestPickOption extends VoiceInteractor.PickOptionRequest {
         public TestPickOption(Option[] options) {
             super(new VoiceInteractor.Prompt("Need to pick something"), options, null);
@@ -200,10 +238,8 @@
                 }
                 sb.append(selections[i].getLabel());
             }
+            sb.append("\n");
             ((TestInteractionActivity)getActivity()).mLog.append(sb.toString());
-            if (finished) {
-                getActivity().finish();
-            }
         }
     }
 }