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
This commit is contained in:
Yu Shan
2023-12-13 17:49:37 -08:00
parent efa6db774e
commit 8459a06838
10 changed files with 155 additions and 4 deletions

View File

@@ -41,6 +41,7 @@ interface IRemoteAccess {
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);

View File

@@ -36,6 +36,7 @@ package android.hardware.automotive.remoteaccess;
parcelable ScheduleInfo {
String clientId;
String scheduleId;
android.hardware.automotive.remoteaccess.TaskType taskType;
byte[] taskData;
int count;
long startTimeInEpochSeconds;

View File

@@ -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,
}

View File

@@ -19,12 +19,39 @@ package android.hardware.automotive.remoteaccess;
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 {
@@ -109,6 +136,17 @@ interface IRemoteAccess {
*/
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.
*
@@ -127,6 +165,8 @@ interface IRemoteAccess {
*
* <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);

View File

@@ -22,7 +22,7 @@ package android.hardware.automotive.remoteaccess;
@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

View File

@@ -16,6 +16,8 @@
package android.hardware.automotive.remoteaccess;
import android.hardware.automotive.remoteaccess.TaskType;
@VintfStability
@JavaDerive(equals=true, toString=true)
parcelable ScheduleInfo {
@@ -30,9 +32,15 @@ parcelable ScheduleInfo {
* scheduleId will return {@code EX_ILLEGAL_ARGUMENT}.
*/
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;
/**

View File

@@ -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,
}

View File

@@ -81,6 +81,9 @@ class RemoteAccessService
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;

View File

@@ -40,6 +40,7 @@ namespace {
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 @@ ScopedAStatus RemoteAccessService::isTaskScheduleSupported(bool* out) {
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 = {};

View File

@@ -48,6 +48,7 @@ using ::android::frameworks::automotive::vhal::VhalClientResult;
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 ::grpc::testing::MockClientReader;
using ::ndk::ScopedAStatus;
using ::testing::_;
using ::testing::DoAll;
using ::testing::ElementsAre;
using ::testing::Return;
using ::testing::SetArgPointee;
@@ -434,6 +436,14 @@ TEST_F(RemoteAccessServiceUnitTest, TestIsTaskScheduleSupported) {
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)