Merge "DO NOT MERGE Clean up logs in CarAssistUtils" into pi-car-dev
diff --git a/car-assist-client-lib/src/com/android/car/assist/client/BundleBuilder.java b/car-assist-client-lib/src/com/android/car/assist/client/BundleBuilder.java
index d0790cf..742eca6 100644
--- a/car-assist-client-lib/src/com/android/car/assist/client/BundleBuilder.java
+++ b/car-assist-client-lib/src/com/android/car/assist/client/BundleBuilder.java
@@ -16,13 +16,17 @@
 package com.android.car.assist.client;
 
 import static com.android.car.assist.CarVoiceInteractionSession.KEY_ACTION;
+import static com.android.car.assist.CarVoiceInteractionSession.KEY_EXCEPTION;
 import static com.android.car.assist.CarVoiceInteractionSession.KEY_NOTIFICATION;
+import static com.android.car.assist.CarVoiceInteractionSession.VOICE_ACTION_HANDLE_EXCEPTION;
 import static com.android.car.assist.CarVoiceInteractionSession.VOICE_ACTION_READ_NOTIFICATION;
 import static com.android.car.assist.CarVoiceInteractionSession.VOICE_ACTION_REPLY_NOTIFICATION;
 
 import android.os.Bundle;
 import android.service.notification.StatusBarNotification;
 
+import com.android.car.assist.CarVoiceInteractionSession.ExceptionValue;
+
 /**
  * Helper class for building Bundle arguments. Used by {@link CarAssistUtils}.
  */
@@ -54,4 +58,18 @@
         args.putParcelable(KEY_NOTIFICATION, notification);
         return args;
     }
+
+    /**
+     * Returns a {@link Bundle} to be delivered to Assistant to indicate that it should handle
+     * the specified {@input exception}.
+     *
+     * @return The bundle that can be sent to Assistant.
+     */
+    static Bundle buildAssistantHandleExceptionBundle(
+            @ExceptionValue String exception) {
+        Bundle args = new Bundle();
+        args.putString(KEY_ACTION, VOICE_ACTION_HANDLE_EXCEPTION);
+        args.putString(KEY_EXCEPTION, exception);
+        return args;
+    }
 }
diff --git a/car-assist-lib/src/com/android/car/assist/CarVoiceInteractionSession.java b/car-assist-lib/src/com/android/car/assist/CarVoiceInteractionSession.java
index 670bc5e..e2c6282 100644
--- a/car-assist-lib/src/com/android/car/assist/CarVoiceInteractionSession.java
+++ b/car-assist-lib/src/com/android/car/assist/CarVoiceInteractionSession.java
@@ -22,6 +22,8 @@
 import android.service.voice.VoiceInteractionService;
 import android.service.voice.VoiceInteractionSession;
 
+import androidx.annotation.StringDef;
+
 import com.android.car.assist.payloadhandlers.NotificationPayloadHandler;
 
 /**
@@ -42,6 +44,12 @@
     public static final String KEY_ACTION = "KEY_ACTION";
 
     /**
+     * The key used for the {@link CarVoiceInteractionSession#VOICE_ACTION_HANDLE_EXCEPTION} payload
+     * {@link Bundle}. Must map to a {@link ExceptionValue}.
+     */
+    public static final String KEY_EXCEPTION = "KEY_EXCEPTION";
+
+    /**
      * The key used for the payload {@link Bundle}, if a {@link StatusBarNotification} is used as
      * the payload.
      */
@@ -56,6 +64,26 @@
     /** Indicates to assistant that a reply action is being requested for a given payload. */
     public static final String VOICE_ACTION_REPLY_NOTIFICATION = "VOICE_ACTION_REPLY_NOTIFICATION";
 
+    /**
+     * Indicates to assistant that it should resolve the exception in the given payload (found in
+     * {@link CarVoiceInteractionSession#KEY_EXCEPTION}'s value).
+     */
+    public static final String VOICE_ACTION_HANDLE_EXCEPTION = "VOICE_ACTION_HANDLE_EXCEPTION";
+
+    /**
+     * The list of exceptions the active voice service must handle.
+     */
+    @StringDef({EXCEPTION_NOTIFICATION_LISTENER_PERMISSIONS_MISSING})
+    public @interface ExceptionValue {}
+
+    /**
+     * Indicates to assistant that it is missing the Notification Listener permission, and should
+     * request this permission from the user.
+     **/
+    public static final String EXCEPTION_NOTIFICATION_LISTENER_PERMISSIONS_MISSING =
+            "EXCEPTION_NOTIFICATION_LISTENER_PERMISSIONS_MISSING";
+
+
     private final NotificationPayloadHandler mNotificationPayloadHandler;
 
     public CarVoiceInteractionSession(Context context) {