Add task schedule API to remote access HAL.

These APIs allows a client to schedule a task to be executed later.
If the vehicle is off when the task is to be exectued, the vehicle
will be woken up, execute the task and shutdown. If the vehicle is
already up, the task will be exectued.

Test: None
Bug: 282792374
Change-Id: I97c4fdbe2cba035e8bd9ddede4c94d0331c39eef
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 06ba953..a201e8c 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>