Voice Interaction from within an Activity

This allows an app to show a voice search button
and invoke a voice interaction session for use
within the activity. Once the activity exits, the
session is stopped.

Test application has a new activity that
demonstrates it with the test voice interaction
service.

This initial version is functional enough for
an integration test, with some more tests
and improvements to come later.

Bug: 22791070
Change-Id: Ib1e5bc8cae1fde40570c999b9cf4bb29efe4916d
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index fcea625..4bac2d6 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -3093,8 +3093,29 @@
                         didOne = true;
                     }
                 }
+            } else {
+                // Check if any of the activities are using voice
+                for (int activityNdx = tr.mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
+                    ActivityRecord r = tr.mActivities.get(activityNdx);
+                    if (r.voiceSession != null
+                            && r.voiceSession.asBinder() == sessionBinder) {
+                        // Inform of cancellation
+                        r.clearVoiceSessionLocked();
+                        try {
+                            r.app.thread.scheduleLocalVoiceInteractionStarted((IBinder) r.appToken,
+                                    null);
+                        } catch (RemoteException re) {
+                            // Ok
+                        }
+                        // TODO: VI This is redundant in some cases
+                        mService.finishRunningVoiceLocked();
+                        break;
+                    }
+                }
             }
         }
+        Slog.d(TAG, "ActivityStack.finishVoiceTask()");
+
         if (didOne) {
             mService.updateOomAdjLocked();
         }
@@ -4686,6 +4707,7 @@
         updateTaskMovement(task, true);
 
         if (!moving && task.mActivities.isEmpty()) {
+            // TODO: VI what about activity?
             final boolean isVoiceSession = task.voiceSession != null;
             if (isVoiceSession) {
                 try {
@@ -4790,6 +4812,7 @@
 
     void addConfigOverride(ActivityRecord r, TaskRecord task) {
         final Rect bounds = task.updateOverrideConfigurationFromLaunchBounds();
+        // TODO: VI deal with activity
         mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken,
                 r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen,
                 (r.info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0, r.userId, r.info.configChanges,