Add TaskType to ScheduleInfo.
Add a task type field to schedule serverless remote task. We want
to introduce an ENTER_GARAGE_MODE type where the external system
can set the AP_POWER_BOOT_UP_REASON and makes android enter
garage mode.
Test: atest RemoteAccessServiceUnitTest
Bug: 316233421
Change-Id: Iddbd2a14aa6f4672a2e27f0a05ec2b73b7d1aab2
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 ccfa22d..e6f4808 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
@@ -41,6 +41,7 @@
void clearRemoteTaskCallback();
void notifyApStateChange(in android.hardware.automotive.remoteaccess.ApState state);
boolean isTaskScheduleSupported();
+ android.hardware.automotive.remoteaccess.TaskType[] getSupportedTaskTypesForScheduling();
void scheduleTask(in android.hardware.automotive.remoteaccess.ScheduleInfo scheduleInfo);
void unscheduleTask(String clientId, String scheduleId);
void unscheduleAllTasks(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
index a929e10..a5d81cf 100644
--- 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
@@ -36,6 +36,7 @@
parcelable ScheduleInfo {
String clientId;
String scheduleId;
+ android.hardware.automotive.remoteaccess.TaskType taskType;
byte[] taskData;
int count;
long startTimeInEpochSeconds;
diff --git a/automotive/remoteaccess/aidl_api/android.hardware.automotive.remoteaccess/current/android/hardware/automotive/remoteaccess/TaskType.aidl b/automotive/remoteaccess/aidl_api/android.hardware.automotive.remoteaccess/current/android/hardware/automotive/remoteaccess/TaskType.aidl
new file mode 100644
index 0000000..da70626
--- /dev/null
+++ b/automotive/remoteaccess/aidl_api/android.hardware.automotive.remoteaccess/current/android/hardware/automotive/remoteaccess/TaskType.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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;
+@Backing(type="int") @VintfStability
+enum TaskType {
+ CUSTOM = 0,
+ ENTER_GARAGE_MODE = 1,
+}
diff --git a/automotive/remoteaccess/android/hardware/automotive/remoteaccess/IRemoteAccess.aidl b/automotive/remoteaccess/android/hardware/automotive/remoteaccess/IRemoteAccess.aidl
index 4912651..9863ed7 100644
--- a/automotive/remoteaccess/android/hardware/automotive/remoteaccess/IRemoteAccess.aidl
+++ b/automotive/remoteaccess/android/hardware/automotive/remoteaccess/IRemoteAccess.aidl
@@ -19,12 +19,39 @@
import android.hardware.automotive.remoteaccess.ApState;
import android.hardware.automotive.remoteaccess.IRemoteTaskCallback;
import android.hardware.automotive.remoteaccess.ScheduleInfo;
+import android.hardware.automotive.remoteaccess.TaskType;
/**
- * Interface representing a remote wakeup client.
+ * The remote access HAL.
*
- * A wakeup client is a binary outside Android framework that communicates with
- * a wakeup server and receives wake up command.
+ * <p>This HAL represents an external system that is always on even when Android
+ * is powered off. It is capable of wakeing up and notifying Android when a
+ * remote task arrives.
+ *
+ * <p>For cloud-based remote access, a cloud server will issue the remote task
+ * to the external system, which will then be forwarded to Android. The client
+ * is expected to call {@code setRemoteTaskCallback} to register the remote
+ * task callback and uses the information returned from {@code getVehicleId},
+ * {@code getWakeupServiceName} and {@code getProcessorId} to register with
+ * a remote server.
+ *
+ * <p>For serverless remote access, the remote task comes from the external
+ * system alone and no server is involved. The external system may support
+ * scheduling a remote task to executed later through {@code scheduleTask}.
+ *
+ * <p>For both cloud-based and serverless remote access, the ideal use case
+ * is to wake up Android when the vehicle is not in use and then shutdown
+ * Android after the task is complete. However, user may access the vehicle
+ * during this period, and Android must not be shutdown if this happens.
+ *
+ * <p>If this interface is implemented, then VHAL property
+ * {@code VEHICLE_IN_USE} must be supported to represent whether the vehicle is
+ * currently in use. Android will check this before sending the shutdown
+ * request.
+ *
+ * <p>The external power controller system must also check whether vehicle is
+ * in use upon receiving the shutdown request and makes sure that an
+ * user-unexpected shutdown must not happen.
*/
@VintfStability
interface IRemoteAccess {
@@ -110,6 +137,17 @@
boolean isTaskScheduleSupported();
/**
+ * Returns the supported task types for scheduling.
+ *
+ * <p>If task scheduling is not supported, this returns an empty array.
+ *
+ * <p>Otherwise, at least {@code TaskType.CUSTOM} must be supported.
+ *
+ * @return An array of supported task types.
+ */
+ TaskType[] getSupportedTaskTypesForScheduling();
+
+ /**
* Schedules a task to be executed later even when the vehicle is off.
*
* <p>If {@link isTaskScheduleSupported} returns {@code false}. This is no-op.
@@ -127,6 +165,8 @@
*
* <p>Must return {@code EX_ILLEGAL_ARGUMENT} if a pending schedule with the same
* {@code scheduleId} for this client exists.
+ *
+ * <p>Must return {@code EX_ILLEGAL_ARGUMENT} if the task type is not supported.
*/
void scheduleTask(in ScheduleInfo scheduleInfo);
diff --git a/automotive/remoteaccess/android/hardware/automotive/remoteaccess/IRemoteTaskCallback.aidl b/automotive/remoteaccess/android/hardware/automotive/remoteaccess/IRemoteTaskCallback.aidl
index 2cd7a5d..ee6f900 100644
--- a/automotive/remoteaccess/android/hardware/automotive/remoteaccess/IRemoteTaskCallback.aidl
+++ b/automotive/remoteaccess/android/hardware/automotive/remoteaccess/IRemoteTaskCallback.aidl
@@ -22,7 +22,7 @@
@VintfStability
interface IRemoteTaskCallback {
/**
- * A callback that is called when a remote task is requested.
+ * A callback that is called when a custom type remote task is requested.
*
* The data is passed down from the remote server to the remote task client
* which is an Android application, and is not interpreted/parsed by the
diff --git a/automotive/remoteaccess/android/hardware/automotive/remoteaccess/ScheduleInfo.aidl b/automotive/remoteaccess/android/hardware/automotive/remoteaccess/ScheduleInfo.aidl
index cf1437b..40fba6f 100644
--- a/automotive/remoteaccess/android/hardware/automotive/remoteaccess/ScheduleInfo.aidl
+++ b/automotive/remoteaccess/android/hardware/automotive/remoteaccess/ScheduleInfo.aidl
@@ -16,6 +16,8 @@
package android.hardware.automotive.remoteaccess;
+import android.hardware.automotive.remoteaccess.TaskType;
+
@VintfStability
@JavaDerive(equals=true, toString=true)
parcelable ScheduleInfo {
@@ -31,8 +33,14 @@
*/
String scheduleId;
/**
+ * The type for the task.
+ */
+ TaskType taskType;
+ /**
* 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.
+ *
+ * <p>This is only used for {@code TaskType.CUSTOM}.
*/
byte[] taskData;
/**
diff --git a/automotive/remoteaccess/android/hardware/automotive/remoteaccess/TaskType.aidl b/automotive/remoteaccess/android/hardware/automotive/remoteaccess/TaskType.aidl
new file mode 100644
index 0000000..761eb15
--- /dev/null
+++ b/automotive/remoteaccess/android/hardware/automotive/remoteaccess/TaskType.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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
+@Backing(type="int")
+enum TaskType {
+ /**
+ * A custom task that is opaque to anyone other than the remote task client app.
+ *
+ * <p>The opaque task data in the {@code ScheduleInfo} will be sent back to the app when the
+ * task is to be executed.
+ */
+ CUSTOM = 0,
+ /**
+ * Enters the garage mode if allowed.
+ *
+ * <p>Make the Android system enters garage mode if vehicle is currently not in use and
+ * entering garage mode is allowed (e.g. battery level is high enough).
+ *
+ * <p>This is based on best-effort and it is not guaranteed.
+ *
+ * <p>If allowed, the external system should set {@code AP_POWER_BOOTUP_REASON} to
+ * {@code SYSTEM_ENTER_GARAGE_MODE} and then boot up (or resume) the head unit.
+ */
+ ENTER_GARAGE_MODE = 1,
+}
diff --git a/automotive/remoteaccess/hal/default/include/RemoteAccessService.h b/automotive/remoteaccess/hal/default/include/RemoteAccessService.h
index 1fc4037..23b4ebe 100644
--- a/automotive/remoteaccess/hal/default/include/RemoteAccessService.h
+++ b/automotive/remoteaccess/hal/default/include/RemoteAccessService.h
@@ -81,6 +81,9 @@
ndk::ScopedAStatus isTaskScheduleSupported(bool* out) override;
+ ndk::ScopedAStatus getSupportedTaskTypesForScheduling(
+ std::vector<aidl::android::hardware::automotive::remoteaccess::TaskType>* out) override;
+
ndk::ScopedAStatus scheduleTask(
const aidl::android::hardware::automotive::remoteaccess::ScheduleInfo& scheduleInfo)
override;
diff --git a/automotive/remoteaccess/hal/default/src/RemoteAccessService.cpp b/automotive/remoteaccess/hal/default/src/RemoteAccessService.cpp
index 0944d86..5521134 100644
--- a/automotive/remoteaccess/hal/default/src/RemoteAccessService.cpp
+++ b/automotive/remoteaccess/hal/default/src/RemoteAccessService.cpp
@@ -40,6 +40,7 @@
using ::aidl::android::hardware::automotive::remoteaccess::ApState;
using ::aidl::android::hardware::automotive::remoteaccess::IRemoteTaskCallback;
using ::aidl::android::hardware::automotive::remoteaccess::ScheduleInfo;
+using ::aidl::android::hardware::automotive::remoteaccess::TaskType;
using ::aidl::android::hardware::automotive::vehicle::VehicleProperty;
using ::android::base::Error;
using ::android::base::ParseInt;
@@ -319,6 +320,13 @@
return ScopedAStatus::ok();
}
+ndk::ScopedAStatus RemoteAccessService::getSupportedTaskTypesForScheduling(
+ std::vector<TaskType>* out) {
+ // TODO(b/316233421): support ENTER_GARAGE_MODE type.
+ out->push_back(TaskType::CUSTOM);
+ return ScopedAStatus::ok();
+}
+
ScopedAStatus RemoteAccessService::scheduleTask(const ScheduleInfo& scheduleInfo) {
ClientContext context;
ScheduleTaskRequest request = {};
diff --git a/automotive/remoteaccess/hal/default/test/RemoteAccessServiceUnitTest.cpp b/automotive/remoteaccess/hal/default/test/RemoteAccessServiceUnitTest.cpp
index c0038c2..4af0003 100644
--- a/automotive/remoteaccess/hal/default/test/RemoteAccessServiceUnitTest.cpp
+++ b/automotive/remoteaccess/hal/default/test/RemoteAccessServiceUnitTest.cpp
@@ -48,6 +48,7 @@
using ::aidl::android::hardware::automotive::remoteaccess::ApState;
using ::aidl::android::hardware::automotive::remoteaccess::BnRemoteTaskCallback;
using ::aidl::android::hardware::automotive::remoteaccess::ScheduleInfo;
+using ::aidl::android::hardware::automotive::remoteaccess::TaskType;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropValue;
using ::grpc::ClientAsyncReaderInterface;
@@ -61,6 +62,7 @@
using ::ndk::ScopedAStatus;
using ::testing::_;
using ::testing::DoAll;
+using ::testing::ElementsAre;
using ::testing::Return;
using ::testing::SetArgPointee;
@@ -434,6 +436,14 @@
EXPECT_TRUE(out);
}
+TEST_F(RemoteAccessServiceUnitTest, TestGetSupportedTaskTypesForScheduling) {
+ std::vector<TaskType> out;
+ ScopedAStatus status = getService()->getSupportedTaskTypesForScheduling(&out);
+
+ EXPECT_TRUE(status.isOk());
+ EXPECT_THAT(out, ElementsAre(TaskType::CUSTOM));
+}
+
TEST_F(RemoteAccessServiceUnitTest, TestScheduleTask) {
ScheduleTaskRequest grpcRequest = {};
EXPECT_CALL(*getGrpcWakeupClientStub(), ScheduleTask)