Merge "[VoiceInteraction] Add two callbacks to notify the client side"
diff --git a/core/api/current.txt b/core/api/current.txt
index 6396715..141725d 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -40519,7 +40519,9 @@
     method public android.os.IBinder onBind(android.content.Intent);
     method @NonNull public java.util.Set<java.lang.String> onGetSupportedVoiceActions(@NonNull java.util.Set<java.lang.String>);
     method public void onLaunchVoiceAssistFromKeyguard();
+    method public void onPrepareToShowSession(@NonNull android.os.Bundle, int);
     method public void onReady();
+    method public void onShowSessionFailed();
     method public void onShutdown();
     method public void setDisabledShowContext(int);
     method public final void setUiHints(@NonNull android.os.Bundle);
diff --git a/core/java/android/service/voice/IVoiceInteractionService.aidl b/core/java/android/service/voice/IVoiceInteractionService.aidl
index 24819a6..efae5c1 100644
--- a/core/java/android/service/voice/IVoiceInteractionService.aidl
+++ b/core/java/android/service/voice/IVoiceInteractionService.aidl
@@ -16,6 +16,8 @@
 
 package android.service.voice;
 
+import android.os.Bundle;
+
 import com.android.internal.app.IVoiceActionCheckCallback;
 
 /**
@@ -28,4 +30,6 @@
     void launchVoiceAssistFromKeyguard();
     void getActiveServiceSupportedActions(in List<String> voiceActions,
      in IVoiceActionCheckCallback callback);
+    void prepareToShowSession(in Bundle args, int flags);
+    void showSessionFailed();
 }
diff --git a/core/java/android/service/voice/VoiceInteractionService.java b/core/java/android/service/voice/VoiceInteractionService.java
index 9e1518d..d49b5a5 100644
--- a/core/java/android/service/voice/VoiceInteractionService.java
+++ b/core/java/android/service/voice/VoiceInteractionService.java
@@ -160,6 +160,20 @@
                             voiceActions,
                             callback));
         }
+
+        @Override
+        public void prepareToShowSession(Bundle args, int flags) {
+            Handler.getMain().executeOrSendMessage(PooledLambda.obtainMessage(
+                    VoiceInteractionService::onPrepareToShowSession,
+                    VoiceInteractionService.this, args, flags));
+        }
+
+        @Override
+        public void showSessionFailed() {
+            Handler.getMain().executeOrSendMessage(PooledLambda.obtainMessage(
+                    VoiceInteractionService::onShowSessionFailed,
+                    VoiceInteractionService.this));
+        }
     };
 
     IVoiceInteractionManagerService mSystemService;
@@ -184,6 +198,31 @@
     }
 
     /**
+     * Notify the interactor when the system prepares to show session. The system is going to
+     * bind the session service.
+     *
+     * @param args  The arguments that were supplied to {@link #showSession(Bundle, int)}.
+     * @param flags The show flags originally provided to {@link #showSession(Bundle, int)}.
+     * @see #showSession(Bundle, int)
+     * @see #onShowSessionFailed()
+     * @see VoiceInteractionSession#onShow(Bundle, int)
+     * @see VoiceInteractionSession#show(Bundle, int)
+     */
+    public void onPrepareToShowSession(@NonNull Bundle args, int flags) {
+    }
+
+    /**
+     * Called when the show session failed. E.g. When the system bound the session service failed.
+     *
+     * @see #showSession(Bundle, int)
+     * @see #onPrepareToShowSession(Bundle, int)
+     * @see VoiceInteractionSession#onShow(Bundle, int)
+     * @see VoiceInteractionSession#show(Bundle, int)
+     */
+    public void onShowSessionFailed() {
+    }
+
+    /**
      * Check whether the given service component is the currently active
      * VoiceInteractionService.
      */
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
index 9643282..13c0f17 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
@@ -251,11 +251,29 @@
             @Nullable String attributionTag,
             @Nullable IVoiceInteractionSessionShowCallback showCallback,
             @Nullable IBinder activityToken) {
+        try {
+            if (mService != null) {
+                mService.prepareToShowSession(args, flags);
+            }
+        } catch (RemoteException e) {
+            Slog.w(TAG, "RemoteException while calling prepareToShowSession", e);
+        }
+
         if (mActiveSession == null) {
             mActiveSession = new VoiceInteractionSessionConnection(mServiceStub,
                     mSessionComponentName, mUser, mContext, this,
                     mInfo.getServiceInfo().applicationInfo.uid, mHandler);
         }
+        if (!mActiveSession.mBound) {
+            try {
+                if (mService != null) {
+                    mService.showSessionFailed();
+                }
+            } catch (RemoteException e) {
+                Slog.w(TAG, "RemoteException while calling showSessionFailed", e);
+            }
+        }
+
         List<ActivityAssistInfo> allVisibleActivities =
                 LocalServices.getService(ActivityTaskManagerInternal.class)
                         .getTopVisibleActivities();