Merge "Add task schedule API to remote access HAL." into main
diff --git a/automotive/remoteaccess/Android.bp b/automotive/remoteaccess/Android.bp
index 7cd6f60..e1e9041 100644
--- a/automotive/remoteaccess/Android.bp
+++ b/automotive/remoteaccess/Android.bp
@@ -42,6 +42,5 @@
             imports: [],
         },
     ],
-    frozen: true,
-
+    frozen: false,
 }
diff --git a/automotive/remoteaccess/aidl_api/android.hardware.automotive.remoteaccess/current/android/hardware/automotive/remoteaccess/IRemoteAccess.aidl b/automotive/remoteaccess/aidl_api/android.hardware.automotive.remoteaccess/current/android/hardware/automotive/remoteaccess/IRemoteAccess.aidl
index b0935c2..ccfa22d 100644
--- a/automotive/remoteaccess/aidl_api/android.hardware.automotive.remoteaccess/current/android/hardware/automotive/remoteaccess/IRemoteAccess.aidl
+++ b/automotive/remoteaccess/aidl_api/android.hardware.automotive.remoteaccess/current/android/hardware/automotive/remoteaccess/IRemoteAccess.aidl
@@ -40,4 +40,10 @@
   void setRemoteTaskCallback(android.hardware.automotive.remoteaccess.IRemoteTaskCallback callback);
   void clearRemoteTaskCallback();
   void notifyApStateChange(in android.hardware.automotive.remoteaccess.ApState state);
+  boolean isTaskScheduleSupported();
+  void scheduleTask(in android.hardware.automotive.remoteaccess.ScheduleInfo scheduleInfo);
+  void unscheduleTask(String clientId, String scheduleId);
+  void unscheduleAllTasks(String clientId);
+  boolean isTaskScheduled(String clientId, String scheduleId);
+  List<android.hardware.automotive.remoteaccess.ScheduleInfo> getAllScheduledTasks(String clientId);
 }
diff --git a/automotive/remoteaccess/aidl_api/android.hardware.automotive.remoteaccess/current/android/hardware/automotive/remoteaccess/ScheduleInfo.aidl b/automotive/remoteaccess/aidl_api/android.hardware.automotive.remoteaccess/current/android/hardware/automotive/remoteaccess/ScheduleInfo.aidl
new file mode 100644
index 0000000..a929e10
--- /dev/null
+++ b/automotive/remoteaccess/aidl_api/android.hardware.automotive.remoteaccess/current/android/hardware/automotive/remoteaccess/ScheduleInfo.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.remoteaccess;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable ScheduleInfo {
+  String clientId;
+  String scheduleId;
+  byte[] taskData;
+  int count;
+  long startTimeInEpochSeconds;
+  long periodicInSeconds;
+}
diff --git a/automotive/remoteaccess/android/hardware/automotive/remoteaccess/IRemoteAccess.aidl b/automotive/remoteaccess/android/hardware/automotive/remoteaccess/IRemoteAccess.aidl
index 0f4125f..4912651 100644
--- a/automotive/remoteaccess/android/hardware/automotive/remoteaccess/IRemoteAccess.aidl
+++ b/automotive/remoteaccess/android/hardware/automotive/remoteaccess/IRemoteAccess.aidl
@@ -18,6 +18,7 @@
 
 import android.hardware.automotive.remoteaccess.ApState;
 import android.hardware.automotive.remoteaccess.IRemoteTaskCallback;
+import android.hardware.automotive.remoteaccess.ScheduleInfo;
 
 /**
  * Interface representing a remote wakeup client.
@@ -96,4 +97,69 @@
      * <p>If {@code isWakeupRequired} is false, it must not try to wake up AP.
      */
     void notifyApStateChange(in ApState state);
+
+    /**
+     * Returns whether task scheduling is supported.
+     *
+     * <p>If this returns {@code true}, user may use {@link scheduleTask} to schedule a task to be
+     * executed at a later time. If the device is off when the task is scheduled to be executed,
+     * the device will be woken up to execute the task.
+     *
+     * @return {@code true} if serverless remote task scheduling is supported.
+     */
+    boolean isTaskScheduleSupported();
+
+    /**
+     * Schedules a task to be executed later even when the vehicle is off.
+     *
+     * <p>If {@link isTaskScheduleSupported} returns {@code false}. This is no-op.
+     *
+     * <p>This sends a scheduled task message to a device external to Android so that the device
+     * can wake up Android and deliver the task through {@link IRemoteTaskCallback}.
+     *
+     * <p>Note that the scheduled task execution is on a best-effort basis. Multiple situations
+     * might cause the task not to execute successfully:
+     *
+     * <ul>
+     * <li>The vehicle is low on battery and the other device decides not to wake up Android.
+     * <li>User turns off vehicle while the task is executing.
+     * <li>The task logic itself fails.
+     *
+     * <p>Must return {@code EX_ILLEGAL_ARGUMENT} if a pending schedule with the same
+     * {@code scheduleId} for this client exists.
+     */
+    void scheduleTask(in ScheduleInfo scheduleInfo);
+
+    /**
+     * Unschedules a scheduled task.
+     *
+     * <p>If {@link isTaskScheduleSupported} returns {@code false}. This is no-op.
+     *
+     * <p>Does nothing if a pending schedule with {@code clientId} and {@code scheduleId} does not
+     * exist.
+     */
+    void unscheduleTask(String clientId, String scheduleId);
+
+    /**
+     * Unschedules all scheduled tasks for the client.
+     *
+     * <p>If {@link isTaskScheduleSupported} returns {@code false}. This is no-op.
+     */
+    void unscheduleAllTasks(String clientId);
+
+    /**
+     * Returns whether the specified task is scheduled.
+     *
+     * <p>If {@link isTaskScheduleSupported} returns {@code false}, This must return {@code false}.
+     */
+    boolean isTaskScheduled(String clientId, String scheduleId);
+
+    /**
+     * Gets all pending scheduled tasks for the client.
+     *
+     * <p>If {@link isTaskScheduleSupported} returns {@code false}. This must return empty array.
+     *
+     * <p>The finished scheduled tasks will not be included.
+     */
+    List<ScheduleInfo> getAllScheduledTasks(String clientId);
 }
diff --git a/automotive/remoteaccess/android/hardware/automotive/remoteaccess/ScheduleInfo.aidl b/automotive/remoteaccess/android/hardware/automotive/remoteaccess/ScheduleInfo.aidl
new file mode 100644
index 0000000..cf1437b
--- /dev/null
+++ b/automotive/remoteaccess/android/hardware/automotive/remoteaccess/ScheduleInfo.aidl
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2023 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.hardware.automotive.remoteaccess;
+
+@VintfStability
+@JavaDerive(equals=true, toString=true)
+parcelable ScheduleInfo {
+    /**
+     * The ID used to identify the client this schedule is for. This must be one of the
+     * preconfigured remote access serverless client ID defined in car service resource
+     * {@code R.xml.remote_access_serverless_client_map}.
+     */
+    String clientId;
+    /**
+     * A unique scheduling ID (among the same client). Adding a new schedule info with a duplicate
+     * scheduleId will return {@code EX_ILLEGAL_ARGUMENT}.
+     */
+    String scheduleId;
+    /**
+     * The opaque task data that will be sent back to the remote task client app when the task is
+     * executed. It is not interpreted/parsed by the Android system.
+     */
+    byte[] taskData;
+    /**
+     * How many times this task will be executed. 0 means infinite.
+     *
+     * <p>This must be >= 0.
+     */
+    int count;
+    /**
+     * The start time in epoch seconds.
+     *
+     * <p>The external device issuing remote task must have a clock synced with the
+     * {@code System.currentTimeMillis()} used in Android system.
+     *
+     * <p>Optionally, the VHAL property {@code EPOCH_TIME} can be used to sync the time.
+     *
+     * <p>This must be >= 0.
+     */
+    long startTimeInEpochSeconds;
+    /**
+     * The interval (in seconds) between scheduled task execution.
+     *
+     * <p>This must be >=0. This is not useful when {@code count} is 1. If this is 0,
+     * The tasks will be delivered multiple times with no interval in between.
+     */
+    long periodicInSeconds;
+}
diff --git a/compatibility_matrices/compatibility_matrix.9.xml b/compatibility_matrices/compatibility_matrix.9.xml
index 57fa2bf..0013923 100644
--- a/compatibility_matrices/compatibility_matrix.9.xml
+++ b/compatibility_matrices/compatibility_matrix.9.xml
@@ -102,6 +102,7 @@
     </hal>
     <hal format="aidl" optional="true">
         <name>android.hardware.automotive.remoteaccess</name>
+        <version>1-2</version>
         <interface>
             <name>IRemoteAccess</name>
             <instance>default</instance>