Support Enter Garage Mode in remote access HAL.
Handles task type in reference remote access HAL and passes to
remote access server through GRPC.
Update host-side TestWakeupClientService to handle vehicleInUse
and ApPowerBootupReason VHAL properties.
Update reference VHAL to get the property values rom a remote grpc
server.
Test: atest --host TestWakeupClientServiceImplUnitTest
Manual run TestWakeupClientServerHost verifies that reference
VHAL can get power properties.
Bug: 316233421
Change-Id: I188aa9eed2dedb3b81b4eb6f5685ca33b646b2f5
diff --git a/automotive/remoteaccess/hal/default/proto/wakeup_client.proto b/automotive/remoteaccess/hal/default/proto/wakeup_client.proto
index 14ba0a5..8ff6059 100644
--- a/automotive/remoteaccess/hal/default/proto/wakeup_client.proto
+++ b/automotive/remoteaccess/hal/default/proto/wakeup_client.proto
@@ -124,6 +124,11 @@
ErrorCode errorCode = 1;
}
+enum ScheduleTaskType {
+ CUSTOM = 0;
+ ENTER_GARAGE_MODE = 1;
+}
+
message GrpcScheduleInfo {
string clientId = 1;
string scheduleId = 2;
@@ -131,6 +136,7 @@
int32 count = 4;
int64 startTimeInEpochSeconds = 5;
int64 periodicInSeconds = 6;
+ ScheduleTaskType taskType = 7;
}
message UnscheduleTaskRequest {
@@ -162,3 +168,25 @@
message GetAllPendingScheduledTasksResponse {
repeated GrpcScheduleInfo allScheduledTasks = 1;
}
+
+/**
+ * Service provided by a power controller unit.
+ */
+service PowerController {
+ rpc IsVehicleInUse(IsVehicleInUseRequest) returns (IsVehicleInUseResponse) {}
+
+ rpc GetApPowerBootupReason(GetApPowerBootupReasonRequest)
+ returns (GetApPowerBootupReasonResponse) {}
+}
+
+message IsVehicleInUseRequest {}
+
+message IsVehicleInUseResponse {
+ bool isVehicleInUse = 1;
+}
+
+message GetApPowerBootupReasonRequest {}
+
+message GetApPowerBootupReasonResponse {
+ int32 bootupReason = 1;
+}
diff --git a/automotive/remoteaccess/hal/default/src/RemoteAccessService.cpp b/automotive/remoteaccess/hal/default/src/RemoteAccessService.cpp
index dbd5bed..91689b1 100644
--- a/automotive/remoteaccess/hal/default/src/RemoteAccessService.cpp
+++ b/automotive/remoteaccess/hal/default/src/RemoteAccessService.cpp
@@ -346,8 +346,8 @@
return ScopedAStatus::ok();
}
- // TODO(b/316233421): support ENTER_GARAGE_MODE type.
out->push_back(TaskType::CUSTOM);
+ out->push_back(TaskType::ENTER_GARAGE_MODE);
return ScopedAStatus::ok();
}
@@ -380,6 +380,8 @@
}
request.mutable_scheduleinfo()->set_clientid(scheduleInfo.clientId);
+ request.mutable_scheduleinfo()->set_tasktype(
+ static_cast<ScheduleTaskType>(scheduleInfo.taskType));
request.mutable_scheduleinfo()->set_scheduleid(scheduleInfo.scheduleId);
request.mutable_scheduleinfo()->set_data(scheduleInfo.taskData.data(),
scheduleInfo.taskData.size());
@@ -485,6 +487,7 @@
const GrpcScheduleInfo& rpcScheduleInfo = response.allscheduledtasks(i);
ScheduleInfo scheduleInfo = {
.clientId = rpcScheduleInfo.clientid(),
+ .taskType = static_cast<TaskType>(rpcScheduleInfo.tasktype()),
.scheduleId = rpcScheduleInfo.scheduleid(),
.taskData = stringToBytes(rpcScheduleInfo.data()),
.count = rpcScheduleInfo.count(),
diff --git a/automotive/remoteaccess/test_grpc_server/impl/include/TestWakeupClientServiceImpl.h b/automotive/remoteaccess/test_grpc_server/impl/include/TestWakeupClientServiceImpl.h
index 41cc5d0..7424571 100644
--- a/automotive/remoteaccess/test_grpc_server/impl/include/TestWakeupClientServiceImpl.h
+++ b/automotive/remoteaccess/test_grpc_server/impl/include/TestWakeupClientServiceImpl.h
@@ -30,6 +30,11 @@
namespace automotive {
namespace remoteaccess {
+// The following are the same as VehicleApPowerBootupReason defined in VHAL.
+constexpr int32_t BOOTUP_REASON_USER_POWER_ON = 0;
+constexpr int32_t BOOTUP_REASON_SYSTEM_REMOTE_ACCESS = 2;
+constexpr int32_t BOOTUP_REASON_SYSTEM_ENTER_GARAGE_MODE = 3;
+
// A class to generate fake task for testing. Not required for real implementation. In real
// implementation, the task should come from remote task server. This class is thread-safe.
class FakeTaskGenerator final {
@@ -98,50 +103,57 @@
};
// forward-declaration
-class TestWakeupClientServiceImpl;
+class ServiceImpl;
class TaskScheduleMsgHandler final : public android::MessageHandler {
public:
- TaskScheduleMsgHandler(TestWakeupClientServiceImpl* mImpl);
+ TaskScheduleMsgHandler(ServiceImpl* impl);
void handleMessage(const android::Message& message) override;
private:
- TestWakeupClientServiceImpl* mImpl;
+ ServiceImpl* mImpl;
};
-class TestWakeupClientServiceImpl : public WakeupClient::Service {
+class ServiceImpl {
public:
- TestWakeupClientServiceImpl();
+ ServiceImpl();
- ~TestWakeupClientServiceImpl();
+ virtual ~ServiceImpl() = 0;
// Stop the handling for all income requests. Prepare for shutdown.
void stopServer();
grpc::Status GetRemoteTasks(grpc::ServerContext* context, const GetRemoteTasksRequest* request,
- grpc::ServerWriter<GetRemoteTasksResponse>* writer) override;
+ grpc::ServerWriter<GetRemoteTasksResponse>* writer);
grpc::Status NotifyWakeupRequired(grpc::ServerContext* context,
const NotifyWakeupRequiredRequest* request,
- NotifyWakeupRequiredResponse* response) override;
+ NotifyWakeupRequiredResponse* response);
grpc::Status ScheduleTask(grpc::ServerContext* context, const ScheduleTaskRequest* request,
- ScheduleTaskResponse* response) override;
+ ScheduleTaskResponse* response);
grpc::Status UnscheduleTask(grpc::ServerContext* context, const UnscheduleTaskRequest* request,
- UnscheduleTaskResponse* response) override;
+ UnscheduleTaskResponse* response);
grpc::Status UnscheduleAllTasks(grpc::ServerContext* context,
const UnscheduleAllTasksRequest* request,
- UnscheduleAllTasksResponse* response) override;
+ UnscheduleAllTasksResponse* response);
grpc::Status IsTaskScheduled(grpc::ServerContext* context,
const IsTaskScheduledRequest* request,
- IsTaskScheduledResponse* response) override;
+ IsTaskScheduledResponse* response);
- grpc::Status GetAllPendingScheduledTasks(
- grpc::ServerContext* context, const GetAllPendingScheduledTasksRequest* request,
- GetAllPendingScheduledTasksResponse* response) override;
+ grpc::Status GetAllPendingScheduledTasks(grpc::ServerContext* context,
+ const GetAllPendingScheduledTasksRequest* request,
+ GetAllPendingScheduledTasksResponse* response);
+
+ grpc::Status IsVehicleInUse(grpc::ServerContext* context, const IsVehicleInUseRequest* request,
+ IsVehicleInUseResponse* response);
+
+ grpc::Status GetApPowerBootupReason(grpc::ServerContext* context,
+ const GetApPowerBootupReasonRequest* request,
+ GetApPowerBootupReasonResponse* response);
/**
* Starts generating fake tasks for the specific client repeatedly.
@@ -177,7 +189,7 @@
* This must be implemented by child class and contains device specific logic. E.g. this might
* be sending QEMU commands for the emulator device.
*/
- virtual void wakeupApplicationProcessor() = 0;
+ virtual void wakeupApplicationProcessor(int32_t bootupReason) = 0;
/**
* Cleans up a scheduled task info.
@@ -185,6 +197,16 @@
void cleanupScheduledTaskLocked(const std::string& clientId, const std::string& scheduleId)
REQUIRES(mLock);
+ /**
+ * Sets whether vehicle is in use.
+ */
+ void setVehicleInUse(bool vehicleInUse);
+
+ /**
+ * Sets the bootup reason.
+ */
+ void setBootupReason(int32_t bootupReason);
+
private:
friend class TaskScheduleMsgHandler;
@@ -218,6 +240,8 @@
std::atomic<bool> mServerStopped = false;
std::unordered_map<std::string, std::unordered_map<std::string, ScheduleInfo>>
mInfoByScheduleIdByClientId GUARDED_BY(mLock);
+ std::atomic<bool> mVehicleInUse = false;
+ std::atomic<int32_t> mBootupReason = BOOTUP_REASON_USER_POWER_ON;
// Thread-safe. For test impl only.
FakeTaskGenerator mFakeTaskGenerator;
@@ -232,6 +256,72 @@
void loop();
};
+class WakeupClientServiceImpl : public WakeupClient::Service {
+ public:
+ WakeupClientServiceImpl(ServiceImpl* impl) { mImpl = impl; }
+
+ grpc::Status GetRemoteTasks(grpc::ServerContext* context, const GetRemoteTasksRequest* request,
+ grpc::ServerWriter<GetRemoteTasksResponse>* writer) override {
+ return mImpl->GetRemoteTasks(context, request, writer);
+ }
+
+ grpc::Status NotifyWakeupRequired(grpc::ServerContext* context,
+ const NotifyWakeupRequiredRequest* request,
+ NotifyWakeupRequiredResponse* response) override {
+ return mImpl->NotifyWakeupRequired(context, request, response);
+ }
+
+ grpc::Status ScheduleTask(grpc::ServerContext* context, const ScheduleTaskRequest* request,
+ ScheduleTaskResponse* response) override {
+ return mImpl->ScheduleTask(context, request, response);
+ }
+
+ grpc::Status UnscheduleTask(grpc::ServerContext* context, const UnscheduleTaskRequest* request,
+ UnscheduleTaskResponse* response) override {
+ return mImpl->UnscheduleTask(context, request, response);
+ }
+
+ grpc::Status UnscheduleAllTasks(grpc::ServerContext* context,
+ const UnscheduleAllTasksRequest* request,
+ UnscheduleAllTasksResponse* response) override {
+ return mImpl->UnscheduleAllTasks(context, request, response);
+ }
+
+ grpc::Status IsTaskScheduled(grpc::ServerContext* context,
+ const IsTaskScheduledRequest* request,
+ IsTaskScheduledResponse* response) override {
+ return mImpl->IsTaskScheduled(context, request, response);
+ }
+
+ grpc::Status GetAllPendingScheduledTasks(
+ grpc::ServerContext* context, const GetAllPendingScheduledTasksRequest* request,
+ GetAllPendingScheduledTasksResponse* response) override {
+ return mImpl->GetAllPendingScheduledTasks(context, request, response);
+ }
+
+ private:
+ ServiceImpl* mImpl;
+};
+
+class PowerControllerServiceImpl : public PowerController::Service {
+ public:
+ PowerControllerServiceImpl(ServiceImpl* impl) { mImpl = impl; }
+
+ grpc::Status IsVehicleInUse(grpc::ServerContext* context, const IsVehicleInUseRequest* request,
+ IsVehicleInUseResponse* response) override {
+ return mImpl->IsVehicleInUse(context, request, response);
+ }
+
+ grpc::Status GetApPowerBootupReason(grpc::ServerContext* context,
+ const GetApPowerBootupReasonRequest* request,
+ GetApPowerBootupReasonResponse* response) override {
+ return mImpl->GetApPowerBootupReason(context, request, response);
+ }
+
+ private:
+ ServiceImpl* mImpl;
+};
+
} // namespace remoteaccess
} // namespace automotive
} // namespace hardware
diff --git a/automotive/remoteaccess/test_grpc_server/impl/src/TestWakeupClientServiceImpl.cpp b/automotive/remoteaccess/test_grpc_server/impl/src/TestWakeupClientServiceImpl.cpp
index eed3495..5d33fcb 100644
--- a/automotive/remoteaccess/test_grpc_server/impl/src/TestWakeupClientServiceImpl.cpp
+++ b/automotive/remoteaccess/test_grpc_server/impl/src/TestWakeupClientServiceImpl.cpp
@@ -38,7 +38,7 @@
using ::grpc::Status;
constexpr int64_t kTaskIntervalInMs = 5'000;
-constexpr int64_t kTaskTimeoutInMs = 20'000;
+constexpr int64_t kTaskTimeoutInMs = 60'000;
int64_t msToNs(int64_t ms) {
return std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::milliseconds(ms))
@@ -140,21 +140,21 @@
}
}
-TestWakeupClientServiceImpl::TestWakeupClientServiceImpl() {
+ServiceImpl::ServiceImpl() {
mTaskScheduleMsgHandler = android::sp<TaskScheduleMsgHandler>::make(this);
mLooper = android::sp<Looper>::make(/*opts=*/0);
mLooperThread = std::thread([this] { loop(); });
mTaskQueue = std::make_unique<TaskQueue>(mLooper);
}
-TestWakeupClientServiceImpl::~TestWakeupClientServiceImpl() {
+ServiceImpl::~ServiceImpl() {
if (mServerStopped) {
return;
}
stopServer();
}
-void TestWakeupClientServiceImpl::stopServer() {
+void ServiceImpl::stopServer() {
mTaskQueue->stopWait();
stopGeneratingFakeTask();
// Set the flag so that the loop thread will exit.
@@ -165,7 +165,7 @@
}
}
-void TestWakeupClientServiceImpl::loop() {
+void ServiceImpl::loop() {
Looper::setForThread(mLooper);
while (true) {
@@ -176,23 +176,22 @@
}
}
-void TestWakeupClientServiceImpl::injectTask(const std::string& taskData,
- const std::string& clientId) {
+void ServiceImpl::injectTask(const std::string& taskData, const std::string& clientId) {
GetRemoteTasksResponse response;
response.set_data(taskData);
response.set_clientid(clientId);
injectTaskResponse(response);
}
-void TestWakeupClientServiceImpl::injectTaskResponse(const GetRemoteTasksResponse& response) {
+void ServiceImpl::injectTaskResponse(const GetRemoteTasksResponse& response) {
printf("Receive a new task\n");
mTaskQueue->add(response);
if (mWakeupRequired) {
- wakeupApplicationProcessor();
+ wakeupApplicationProcessor(BOOTUP_REASON_SYSTEM_REMOTE_ACCESS);
}
}
-void TestWakeupClientServiceImpl::startGeneratingFakeTask(const std::string& clientId) {
+void ServiceImpl::startGeneratingFakeTask(const std::string& clientId) {
std::lock_guard<std::mutex> lockGuard(mLock);
if (mGeneratingFakeTask) {
printf("Fake task is already being generated\n");
@@ -203,7 +202,7 @@
printf("Started generating fake tasks\n");
}
-void TestWakeupClientServiceImpl::stopGeneratingFakeTask() {
+void ServiceImpl::stopGeneratingFakeTask() {
{
std::lock_guard<std::mutex> lockGuard(mLock);
if (!mGeneratingFakeTask) {
@@ -219,7 +218,7 @@
printf("Stopped generating fake tasks\n");
}
-void TestWakeupClientServiceImpl::fakeTaskGenerateLoop(const std::string& clientId) {
+void ServiceImpl::fakeTaskGenerateLoop(const std::string& clientId) {
// In actual implementation, this should communicate with the remote server and receives tasks
// from it. Here we simulate receiving one remote task every {kTaskIntervalInMs}ms.
while (true) {
@@ -237,9 +236,8 @@
}
}
-Status TestWakeupClientServiceImpl::GetRemoteTasks(ServerContext* context,
- const GetRemoteTasksRequest* request,
- ServerWriter<GetRemoteTasksResponse>* writer) {
+Status ServiceImpl::GetRemoteTasks(ServerContext* context, const GetRemoteTasksRequest* request,
+ ServerWriter<GetRemoteTasksResponse>* writer) {
printf("GetRemoteTasks called\n");
mRemoteTaskConnectionAlive = true;
while (true) {
@@ -277,15 +275,15 @@
return Status::CANCELLED;
}
-Status TestWakeupClientServiceImpl::NotifyWakeupRequired(ServerContext* context,
- const NotifyWakeupRequiredRequest* request,
- NotifyWakeupRequiredResponse* response) {
+Status ServiceImpl::NotifyWakeupRequired(ServerContext* context,
+ const NotifyWakeupRequiredRequest* request,
+ NotifyWakeupRequiredResponse* response) {
printf("NotifyWakeupRequired called\n");
if (request->iswakeuprequired() && !mWakeupRequired && !mTaskQueue->isEmpty()) {
// If wakeup is now required and previously not required, this means we have finished
// shutting down the device. If there are still pending tasks, try waking up AP again
// to finish executing those tasks.
- wakeupApplicationProcessor();
+ wakeupApplicationProcessor(BOOTUP_REASON_SYSTEM_REMOTE_ACCESS);
}
mWakeupRequired = request->iswakeuprequired();
if (mWakeupRequired) {
@@ -296,23 +294,22 @@
return Status::OK;
}
-void TestWakeupClientServiceImpl::cleanupScheduledTaskLocked(const std::string& clientId,
- const std::string& scheduleId) {
+void ServiceImpl::cleanupScheduledTaskLocked(const std::string& clientId,
+ const std::string& scheduleId) {
mInfoByScheduleIdByClientId[clientId].erase(scheduleId);
if (mInfoByScheduleIdByClientId[clientId].size() == 0) {
mInfoByScheduleIdByClientId.erase(clientId);
}
}
-TaskScheduleMsgHandler::TaskScheduleMsgHandler(TestWakeupClientServiceImpl* impl) : mImpl(impl) {}
+TaskScheduleMsgHandler::TaskScheduleMsgHandler(ServiceImpl* impl) : mImpl(impl) {}
void TaskScheduleMsgHandler::handleMessage(const android::Message& message) {
mImpl->handleAddTask(message.what);
}
-Status TestWakeupClientServiceImpl::ScheduleTask(ServerContext* context,
- const ScheduleTaskRequest* request,
- ScheduleTaskResponse* response) {
+Status ServiceImpl::ScheduleTask(ServerContext* context, const ScheduleTaskRequest* request,
+ ScheduleTaskResponse* response) {
std::lock_guard<std::mutex> lockGuard(mLock);
const GrpcScheduleInfo& grpcScheduleInfo = request->scheduleinfo();
@@ -359,8 +356,7 @@
return Status::OK;
}
-bool TestWakeupClientServiceImpl::getScheduleInfoLocked(int scheduleMsgId,
- ScheduleInfo** outScheduleInfoPtr) {
+bool ServiceImpl::getScheduleInfoLocked(int scheduleMsgId, ScheduleInfo** outScheduleInfoPtr) {
for (auto& [_, infoByScheduleId] : mInfoByScheduleIdByClientId) {
for (auto& [_, scheduleInfo] : infoByScheduleId) {
if (scheduleInfo.scheduleMsgId == scheduleMsgId) {
@@ -372,7 +368,7 @@
return false;
}
-void TestWakeupClientServiceImpl::handleAddTask(int scheduleMsgId) {
+void ServiceImpl::handleAddTask(int scheduleMsgId) {
std::lock_guard<std::mutex> lockGuard(mLock);
ScheduleInfo* scheduleInfoPtr;
@@ -385,15 +381,27 @@
const GrpcScheduleInfo& grpcScheduleInfo = *scheduleInfoPtr->grpcScheduleInfo;
const std::string scheduleId = grpcScheduleInfo.scheduleid();
const std::string clientId = grpcScheduleInfo.clientid();
-
- GetRemoteTasksResponse injectResponse;
- injectResponse.set_data(grpcScheduleInfo.data().data(), grpcScheduleInfo.data().size());
- injectResponse.set_clientid(clientId);
- injectTaskResponse(injectResponse);
scheduleInfoPtr->currentCount++;
+ ScheduleTaskType taskType = grpcScheduleInfo.tasktype();
+ printf("Sending scheduled tasks for scheduleId: %s, clientId: %s, taskCount: %d, "
+ "taskType: %d\n",
+ scheduleId.c_str(), clientId.c_str(), scheduleInfoPtr->currentCount,
+ static_cast<int>(taskType));
- printf("Sending scheduled tasks for scheduleId: %s, clientId: %s, taskCount: %d\n",
- scheduleId.c_str(), clientId.c_str(), scheduleInfoPtr->currentCount);
+ if (taskType == ScheduleTaskType::ENTER_GARAGE_MODE) {
+ if (mWakeupRequired) {
+ wakeupApplicationProcessor(BOOTUP_REASON_SYSTEM_ENTER_GARAGE_MODE);
+ } else {
+ printf("Ignore ENTER_GARAGE_MODE task type because the head unit is already running");
+ }
+ } else if (grpcScheduleInfo.tasktype() == ScheduleTaskType::CUSTOM) {
+ GetRemoteTasksResponse injectResponse;
+ injectResponse.set_data(grpcScheduleInfo.data().data(), grpcScheduleInfo.data().size());
+ injectResponse.set_clientid(clientId);
+ injectTaskResponse(injectResponse);
+ } else {
+ printf("Unknown task type: %d\n", static_cast<int>(taskType));
+ }
if (scheduleInfoPtr->totalCount != 0 &&
scheduleInfoPtr->currentCount == scheduleInfoPtr->totalCount) {
@@ -407,9 +415,8 @@
android::Message(scheduleMsgId));
}
-Status TestWakeupClientServiceImpl::UnscheduleTask(ServerContext* context,
- const UnscheduleTaskRequest* request,
- UnscheduleTaskResponse* response) {
+Status ServiceImpl::UnscheduleTask(ServerContext* context, const UnscheduleTaskRequest* request,
+ UnscheduleTaskResponse* response) {
std::lock_guard<std::mutex> lockGuard(mLock);
const std::string& clientId = request->clientid();
@@ -431,9 +438,9 @@
return Status::OK;
}
-Status TestWakeupClientServiceImpl::UnscheduleAllTasks(ServerContext* context,
- const UnscheduleAllTasksRequest* request,
- UnscheduleAllTasksResponse* response) {
+Status ServiceImpl::UnscheduleAllTasks(ServerContext* context,
+ const UnscheduleAllTasksRequest* request,
+ UnscheduleAllTasksResponse* response) {
std::lock_guard<std::mutex> lockGuard(mLock);
const std::string& clientId = request->clientid();
@@ -452,9 +459,8 @@
return Status::OK;
}
-Status TestWakeupClientServiceImpl::IsTaskScheduled(ServerContext* context,
- const IsTaskScheduledRequest* request,
- IsTaskScheduledResponse* response) {
+Status ServiceImpl::IsTaskScheduled(ServerContext* context, const IsTaskScheduledRequest* request,
+ IsTaskScheduledResponse* response) {
std::lock_guard<std::mutex> lockGuard(mLock);
const std::string& clientId = request->clientid();
@@ -475,9 +481,9 @@
return Status::OK;
}
-Status TestWakeupClientServiceImpl::GetAllPendingScheduledTasks(
- ServerContext* context, const GetAllPendingScheduledTasksRequest* request,
- GetAllPendingScheduledTasksResponse* response) {
+Status ServiceImpl::GetAllPendingScheduledTasks(ServerContext* context,
+ const GetAllPendingScheduledTasksRequest* request,
+ GetAllPendingScheduledTasksResponse* response) {
const std::string& clientId = request->clientid();
printf("GetAllPendingScheduledTasks called with client Id: %s\n", clientId.c_str());
response->clear_allscheduledtasks();
@@ -493,14 +499,35 @@
return Status::OK;
}
-bool TestWakeupClientServiceImpl::isWakeupRequired() {
+Status ServiceImpl::IsVehicleInUse(ServerContext* context, const IsVehicleInUseRequest* request,
+ IsVehicleInUseResponse* response) {
+ response->set_isvehicleinuse(mVehicleInUse);
+ return Status::OK;
+}
+
+Status ServiceImpl::GetApPowerBootupReason(ServerContext* context,
+ const GetApPowerBootupReasonRequest* request,
+ GetApPowerBootupReasonResponse* response) {
+ response->set_bootupreason(mBootupReason);
+ return Status::OK;
+}
+
+bool ServiceImpl::isWakeupRequired() {
return mWakeupRequired;
}
-bool TestWakeupClientServiceImpl::isRemoteTaskConnectionAlive() {
+bool ServiceImpl::isRemoteTaskConnectionAlive() {
return mRemoteTaskConnectionAlive;
}
+void ServiceImpl::setVehicleInUse(bool vehicleInUse) {
+ mVehicleInUse = vehicleInUse;
+}
+
+void ServiceImpl::setBootupReason(int32_t bootupReason) {
+ mBootupReason = bootupReason;
+}
+
} // namespace remoteaccess
} // namespace automotive
} // namespace hardware
diff --git a/automotive/remoteaccess/test_grpc_server/impl/src/main.cpp b/automotive/remoteaccess/test_grpc_server/impl/src/main.cpp
index 5443ad9..63324f3 100644
--- a/automotive/remoteaccess/test_grpc_server/impl/src/main.cpp
+++ b/automotive/remoteaccess/test_grpc_server/impl/src/main.cpp
@@ -33,7 +33,12 @@
#include <grpcpp/server.h>
#include <grpcpp/server_builder.h>
-using ::android::hardware::automotive::remoteaccess::TestWakeupClientServiceImpl;
+using ::android::hardware::automotive::remoteaccess::BOOTUP_REASON_SYSTEM_ENTER_GARAGE_MODE;
+using ::android::hardware::automotive::remoteaccess::BOOTUP_REASON_SYSTEM_REMOTE_ACCESS;
+using ::android::hardware::automotive::remoteaccess::BOOTUP_REASON_USER_POWER_ON;
+using ::android::hardware::automotive::remoteaccess::PowerControllerServiceImpl;
+using ::android::hardware::automotive::remoteaccess::ServiceImpl;
+using ::android::hardware::automotive::remoteaccess::WakeupClientServiceImpl;
using ::grpc::Server;
using ::grpc::ServerBuilder;
using ::grpc::ServerWriter;
@@ -48,11 +53,13 @@
pid_t emuPid = 0;
-void RunServer(const std::string& serviceAddr,
- std::shared_ptr<TestWakeupClientServiceImpl> service) {
+void RunServer(const std::string& serviceAddr, std::shared_ptr<ServiceImpl> service) {
ServerBuilder builder;
builder.AddListeningPort(serviceAddr, grpc::InsecureServerCredentials());
- builder.RegisterService(service.get());
+ WakeupClientServiceImpl wakeupClientService(service.get());
+ builder.RegisterService(&wakeupClientService);
+ PowerControllerServiceImpl powerControllerService(service.get());
+ builder.RegisterService(&powerControllerService);
std::unique_ptr<Server> server(builder.BuildAndStart());
printf("Test Remote Access GRPC Server listening on %s\n", serviceAddr.c_str());
server->Wait();
@@ -81,20 +88,21 @@
}
}
-bool powerOnEmu() {
+bool powerOnEmu(ServiceImpl* service, int32_t bootupReason) {
updateEmuStatus();
if (emuPid != 0) {
printf("The emulator is already running\n");
return false;
}
+ service->setBootupReason(bootupReason);
emuPid = runCommand(COMMAND_RUN_EMU);
printf("Emulator started in process: %d\n", emuPid);
return true;
}
-bool powerOn() {
+bool powerOn(ServiceImpl* service, int32_t bootupReason) {
#ifdef HOST
- return powerOnEmu();
+ return powerOnEmu(service, bootupReason);
#else
printf("power on is only supported on host\n");
return false;
@@ -133,21 +141,6 @@
#endif
}
-void setVehicleInUse(bool vehicleInUse) {
-#ifdef HOST
- printf("Set vehicleInUse to %d\n", vehicleInUse);
- int value = 0;
- if (vehicleInUse) {
- value = 1;
- }
- const char* command = getSetPropCommand(VEHICLE_IN_USE, value);
- runCommand(command);
- delete[] command;
-#else
- printf("set vehicleInUse is only supported on host\n");
-#endif
-}
-
void help() {
std::cout << "Remote Access Host Test Utility" << std::endl
<< "help:\t"
@@ -171,8 +164,7 @@
<< "(only supported on host)" << std::endl;
}
-void parseCommand(const std::string& userInput,
- std::shared_ptr<TestWakeupClientServiceImpl> service) {
+void parseCommand(const std::string& userInput, std::shared_ptr<ServiceImpl> service) {
if (userInput == "") {
// ignore empty line.
} else if (userInput == "help") {
@@ -199,8 +191,10 @@
printf("isWakeupRequired: %B, isRemoteTaskConnectionAlive: %B\n",
service->isWakeupRequired(), service->isRemoteTaskConnectionAlive());
} else if (userInput == "power on") {
- powerOn();
+ service->setVehicleInUse(true);
+ powerOn(service.get(), BOOTUP_REASON_USER_POWER_ON);
} else if (userInput == "power off") {
+ service->setVehicleInUse(false);
powerOff();
} else if (userInput.rfind("inject task", 0) == 0) {
std::stringstream ss;
@@ -226,7 +220,7 @@
printf("Remote task with client ID: %s, data: %s injected\n", clientId.c_str(),
taskData.c_str());
} else if (userInput == "set vehicleInUse") {
- setVehicleInUse(true);
+ service->setVehicleInUse(true);
} else {
printf("Unknown command, see 'help'\n");
}
@@ -242,14 +236,11 @@
exit(-1);
}
-class MyTestWakeupClientServiceImpl final : public TestWakeupClientServiceImpl {
+class MyServiceImpl final : public ServiceImpl {
public:
- void wakeupApplicationProcessor() override {
+ void wakeupApplicationProcessor(int32_t bootupReason) override {
#ifdef HOST
- if (powerOnEmu()) {
- // If we wake up AP to execute remote task, vehicle in use should be false.
- setVehicleInUse(false);
- }
+ powerOnEmu(this, bootupReason);
#else
wakeupAp();
#endif
@@ -262,8 +253,7 @@
serviceAddr = argv[1];
}
// Let the server thread run, we will force kill the server when we exit the program.
- std::shared_ptr<TestWakeupClientServiceImpl> service =
- std::make_shared<MyTestWakeupClientServiceImpl>();
+ std::shared_ptr<ServiceImpl> service = std::make_shared<MyServiceImpl>();
std::thread serverThread([serviceAddr, service] { RunServer(serviceAddr, service); });
// Register the signal handler for SIGTERM and SIGINT so that we can stop the emulator before
diff --git a/automotive/remoteaccess/test_grpc_server/impl/test/TestWakeupClientServiceImplUnitTest.cpp b/automotive/remoteaccess/test_grpc_server/impl/test/TestWakeupClientServiceImplUnitTest.cpp
index 63458ae..4bc0086 100644
--- a/automotive/remoteaccess/test_grpc_server/impl/test/TestWakeupClientServiceImplUnitTest.cpp
+++ b/automotive/remoteaccess/test_grpc_server/impl/test/TestWakeupClientServiceImplUnitTest.cpp
@@ -43,9 +43,9 @@
constexpr int64_t kTestPeriodicInSeconds = 123;
const std::string kTestGrpcAddr = "localhost:50051";
-class MyTestWakeupClientServiceImpl final : public TestWakeupClientServiceImpl {
+class MyTestWakeupClientServiceImpl final : public ServiceImpl {
public:
- void wakeupApplicationProcessor() override {
+ void wakeupApplicationProcessor([[maybe_unused]] int32_t bootupReason) override {
// Do nothing.
}
};
@@ -54,13 +54,14 @@
public:
virtual void SetUp() override {
mServerThread = std::thread([this] {
+ mService = std::make_unique<MyTestWakeupClientServiceImpl>();
+ ServerBuilder builder;
+ builder.AddListeningPort(kTestGrpcAddr, grpc::InsecureServerCredentials());
+ WakeupClientServiceImpl wakeupClientService(mService.get());
+ builder.RegisterService(&wakeupClientService);
+ mServer = builder.BuildAndStart();
{
std::unique_lock<std::mutex> lock(mLock);
- mService = std::make_unique<MyTestWakeupClientServiceImpl>();
- ServerBuilder builder;
- builder.AddListeningPort(kTestGrpcAddr, grpc::InsecureServerCredentials());
- builder.RegisterService(mService.get());
- mServer = builder.BuildAndStart();
mServerStartCv.notify_one();
}
mServer->Wait();
@@ -124,6 +125,7 @@
std::chrono::system_clock::now().time_since_epoch())
.count();
request.mutable_scheduleinfo()->set_clientid(kTestClientId);
+ request.mutable_scheduleinfo()->set_tasktype(ScheduleTaskType::CUSTOM);
request.mutable_scheduleinfo()->set_scheduleid(scheduleId);
request.mutable_scheduleinfo()->set_data(kTestData.data(), kTestData.size());
request.mutable_scheduleinfo()->set_count(count);
@@ -156,6 +158,7 @@
ScheduleTaskResponse response = {};
request.mutable_scheduleinfo()->set_clientid(kTestClientId);
+ request.mutable_scheduleinfo()->set_tasktype(ScheduleTaskType::CUSTOM);
request.mutable_scheduleinfo()->set_scheduleid(kTestScheduleId);
request.mutable_scheduleinfo()->set_data(kTestData.data(), kTestData.size());
request.mutable_scheduleinfo()->set_count(2);
@@ -191,6 +194,7 @@
request.mutable_scheduleinfo()->set_clientid(kTestClientId);
request.mutable_scheduleinfo()->set_scheduleid(kTestScheduleId);
+ request.mutable_scheduleinfo()->set_tasktype(ScheduleTaskType::CUSTOM);
request.mutable_scheduleinfo()->set_data(kTestData.data(), kTestData.size());
request.mutable_scheduleinfo()->set_count(2);
request.mutable_scheduleinfo()->set_starttimeinepochseconds(getNow() + 1);
@@ -315,6 +319,7 @@
for (int i = 0; i < 2; i++) {
EXPECT_EQ(response2.allscheduledtasks(i).clientid(), kTestClientId);
if (response2.allscheduledtasks(i).scheduleid() == scheduleId1) {
+ EXPECT_EQ(response2.allscheduledtasks(i).tasktype(), ScheduleTaskType::CUSTOM);
EXPECT_EQ(response2.allscheduledtasks(i).data(),
std::string(kTestData.begin(), kTestData.end()));
EXPECT_EQ(response2.allscheduledtasks(i).count(), count1);
@@ -322,6 +327,7 @@
EXPECT_EQ(response2.allscheduledtasks(i).periodicinseconds(), periodicInSeconds1);
} else {
EXPECT_EQ(response2.allscheduledtasks(i).scheduleid(), scheduleId2);
+ EXPECT_EQ(response2.allscheduledtasks(i).tasktype(), ScheduleTaskType::CUSTOM);
EXPECT_EQ(response2.allscheduledtasks(i).data(),
std::string(kTestData.begin(), kTestData.end()));
EXPECT_EQ(response2.allscheduledtasks(i).count(), count2);
diff --git a/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/src/JsonConfigLoader.cpp b/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/src/JsonConfigLoader.cpp
index 76db891..d987e6f 100644
--- a/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/src/JsonConfigLoader.cpp
+++ b/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/src/JsonConfigLoader.cpp
@@ -67,6 +67,7 @@
using ::aidl::android::hardware::automotive::vehicle::LowSpeedCollisionWarningState;
using ::aidl::android::hardware::automotive::vehicle::RawPropValues;
using ::aidl::android::hardware::automotive::vehicle::VehicleAirbagLocation;
+using ::aidl::android::hardware::automotive::vehicle::VehicleApPowerBootupReason;
using ::aidl::android::hardware::automotive::vehicle::VehicleApPowerStateReport;
using ::aidl::android::hardware::automotive::vehicle::VehicleApPowerStateReq;
using ::aidl::android::hardware::automotive::vehicle::VehicleAreaConfig;
@@ -300,6 +301,8 @@
std::make_unique<ConstantParser<CrossTrafficMonitoringWarningState>>();
mConstantParsersByType["LowSpeedAutomaticEmergencyBrakingState"] =
std::make_unique<ConstantParser<LowSpeedAutomaticEmergencyBrakingState>>();
+ mConstantParsersByType["VehicleApPowerBootupReason"] =
+ std::make_unique<ConstantParser<VehicleApPowerBootupReason>>();
mConstantParsersByType["Constants"] = std::make_unique<LocalVariableParser>();
#ifdef ENABLE_VEHICLE_HAL_TEST_PROPERTIES
mConstantParsersByType["TestVendorProperty"] =
diff --git a/automotive/vehicle/aidl/impl/default_config/config/DefaultProperties.json b/automotive/vehicle/aidl/impl/default_config/config/DefaultProperties.json
index 590eff9..1a7cdaf 100644
--- a/automotive/vehicle/aidl/impl/default_config/config/DefaultProperties.json
+++ b/automotive/vehicle/aidl/impl/default_config/config/DefaultProperties.json
@@ -3196,6 +3196,14 @@
}
},
{
+ "property": "VehicleProperty::AP_POWER_BOOTUP_REASON",
+ "defaultValue": {
+ "int32Values": [
+ "VehicleApPowerBootupReason::USER_POWER_ON"
+ ]
+ }
+ },
+ {
"property": "VehicleProperty::DISPLAY_BRIGHTNESS",
"defaultValue": {
"int32Values": [
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/Android.bp b/automotive/vehicle/aidl/impl/fake_impl/hardware/Android.bp
index e75f648..80e4087 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/Android.bp
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/Android.bp
@@ -27,11 +27,19 @@
],
local_include_dirs: ["include"],
export_include_dirs: ["include"],
- cflags: ["-DENABLE_VEHICLE_HAL_TEST_PROPERTIES"],
+ cflags: [
+ "-DENABLE_VEHICLE_HAL_TEST_PROPERTIES",
+ // Uncomment this if running on emulator and connecting to a local grpc server
+ // running on host 127.0.0.1:50051 (TestWakeupClientServerHost)
+ // "-DPOWER_GRPC_SERVICE_ADDRESS=\"10.0.2.2:50051\"",
+ ],
defaults: [
"VehicleHalDefaults",
"FakeVehicleHardwareDefaults",
],
+ whole_static_libs: [
+ "wakeup_client_protos",
+ ],
}
cc_defaults {
@@ -54,7 +62,9 @@
"Prebuilt_VehicleHalVendorClusterTestProperties_JSON",
],
shared_libs: [
+ "libgrpc++",
"libjsoncpp",
+ "libprotobuf-cpp-full",
],
export_static_lib_headers: ["VehicleHalUtils"],
}
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h b/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h
index 1153217..8d6c883 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h
@@ -32,6 +32,8 @@
#include <android-base/result.h>
#include <android-base/stringprintf.h>
#include <android-base/thread_annotations.h>
+#include <grpc++/grpc++.h>
+#include <wakeup_client.grpc.pb.h>
#include <memory>
#include <mutex>
@@ -240,6 +242,11 @@
VhalResult<void> synchronizeHvacTemp(int32_t hvacDualOnAreaId,
std::optional<float> newTempC) const;
std::optional<int32_t> getSyncedAreaIdIfHvacDualOn(int32_t hvacTemperatureSetAreaId) const;
+ ValueResultType getPowerPropFromExternalService(int32_t propId) const;
+ ValueResultType getVehicleInUse(
+ android::hardware::automotive::remoteaccess::PowerController::Stub* clientStub) const;
+ ValueResultType getApPowerBootupReason(
+ android::hardware::automotive::remoteaccess::PowerController::Stub* clientStub) const;
std::unordered_map<int32_t, ConfigDeclaration> loadConfigDeclarations();
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp b/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
index bcc765c..c4e7086 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
@@ -82,6 +82,12 @@
using ::aidl::android::hardware::automotive::vehicle::VehiclePropValue;
using ::aidl::android::hardware::automotive::vehicle::VehicleUnit;
+using ::android::hardware::automotive::remoteaccess::GetApPowerBootupReasonRequest;
+using ::android::hardware::automotive::remoteaccess::GetApPowerBootupReasonResponse;
+using ::android::hardware::automotive::remoteaccess::IsVehicleInUseRequest;
+using ::android::hardware::automotive::remoteaccess::IsVehicleInUseResponse;
+using ::android::hardware::automotive::remoteaccess::PowerController;
+
using ::android::base::EqualsIgnoreCase;
using ::android::base::Error;
using ::android::base::GetIntProperty;
@@ -256,6 +262,11 @@
},
},
};
+
+// The list of VHAL properties that might be handled by an external power controller.
+const std::unordered_set<int32_t> mPowerPropIds = {toInt(VehicleProperty::VEHICLE_IN_USE),
+ toInt(VehicleProperty::AP_POWER_BOOTUP_REASON)};
+
} // namespace
void FakeVehicleHardware::storePropInitialValue(const ConfigDeclaration& config) {
@@ -763,6 +774,13 @@
int32_t propId = value.prop;
ValueResultType result;
+#ifdef POWER_GRPC_SERVICE_ADDRESS
+ if (mPowerPropIds.find(propId) != mPowerPropIds.end()) {
+ *isSpecialValue = true;
+ return getPowerPropFromExternalService(propId);
+ }
+#endif
+
if (propId >= STARTING_VENDOR_CODE_PROPERTIES_FOR_TEST &&
propId < ENDING_VENDOR_CODE_PROPERTIES_FOR_TEST) {
*isSpecialValue = true;
@@ -844,6 +862,61 @@
return nullptr;
}
+FakeVehicleHardware::ValueResultType FakeVehicleHardware::getPowerPropFromExternalService(
+ [[maybe_unused]] int32_t propId) const {
+#ifdef POWER_GRPC_SERVICE_ADDRESS
+ auto channel =
+ grpc::CreateChannel(POWER_GRPC_SERVICE_ADDRESS, grpc::InsecureChannelCredentials());
+ auto clientStub = PowerController::NewStub(channel);
+ switch (propId) {
+ case toInt(VehicleProperty::VEHICLE_IN_USE):
+ return getVehicleInUse(clientStub.get());
+ case toInt(VehicleProperty::AP_POWER_BOOTUP_REASON):
+ return getApPowerBootupReason(clientStub.get());
+ default:
+ return StatusError(StatusCode::INTERNAL_ERROR)
+ << "Unsupported power property ID: " << propId;
+ }
+#else
+ // Must not reach here.
+ return StatusError(StatusCode::INTERNAL_ERROR);
+#endif
+}
+
+FakeVehicleHardware::ValueResultType FakeVehicleHardware::getVehicleInUse(
+ PowerController::Stub* clientStub) const {
+ IsVehicleInUseRequest request = {};
+ IsVehicleInUseResponse response = {};
+ grpc::ClientContext context;
+ auto status = clientStub->IsVehicleInUse(&context, request, &response);
+ if (!status.ok()) {
+ return StatusError(StatusCode::TRY_AGAIN) << "Cannot connect to GRPC service "
+ << ", error: " << status.error_message();
+ }
+ auto result = mValuePool->obtainBoolean(response.isvehicleinuse());
+ result->prop = toInt(VehicleProperty::VEHICLE_IN_USE);
+ result->areaId = 0;
+ result->timestamp = elapsedRealtimeNano();
+ return result;
+}
+
+FakeVehicleHardware::ValueResultType FakeVehicleHardware::getApPowerBootupReason(
+ PowerController::Stub* clientStub) const {
+ GetApPowerBootupReasonRequest request = {};
+ GetApPowerBootupReasonResponse response = {};
+ grpc::ClientContext context;
+ auto status = clientStub->GetApPowerBootupReason(&context, request, &response);
+ if (!status.ok()) {
+ return StatusError(StatusCode::TRY_AGAIN) << "Cannot connect to GRPC service "
+ << ", error: " << status.error_message();
+ }
+ auto result = mValuePool->obtainInt32(response.bootupreason());
+ result->prop = toInt(VehicleProperty::AP_POWER_BOOTUP_REASON);
+ result->areaId = 0;
+ result->timestamp = elapsedRealtimeNano();
+ return result;
+}
+
FakeVehicleHardware::ValueResultType FakeVehicleHardware::getEchoReverseBytes(
const VehiclePropValue& value) const {
auto readResult = mServerSidePropStore->readValue(value);
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/Android.bp b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/Android.bp
index b763d2f..ac70b51 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/Android.bp
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/Android.bp
@@ -41,7 +41,9 @@
"libgmock",
],
shared_libs: [
+ "libgrpc++",
"libjsoncpp",
+ "libprotobuf-cpp-full",
],
data: [
":VehicleHalDefaultProperties_JSON",
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp
index 90643aa..cab33e1 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp
@@ -506,6 +506,12 @@
continue;
}
+ if (propId == toInt(VehicleProperty::VEHICLE_IN_USE) ||
+ propId == toInt(VehicleProperty::AP_POWER_BOOTUP_REASON)) {
+ // These may be controller by an external power control unit.
+ continue;
+ }
+
if (isGlobalProp(propId)) {
if (config.initialValue == RawPropValues{}) {
addGetValueRequest(getValueRequests, expectedGetValueResults, requestId++,
diff --git a/automotive/vehicle/aidl/impl/utils/common/include/VehicleHalTypes.h b/automotive/vehicle/aidl/impl/utils/common/include/VehicleHalTypes.h
index 0c8ebbd..77facf2 100644
--- a/automotive/vehicle/aidl/impl/utils/common/include/VehicleHalTypes.h
+++ b/automotive/vehicle/aidl/impl/utils/common/include/VehicleHalTypes.h
@@ -65,6 +65,7 @@
#include <aidl/android/hardware/automotive/vehicle/StatusCode.h>
#include <aidl/android/hardware/automotive/vehicle/SubscribeOptions.h>
#include <aidl/android/hardware/automotive/vehicle/VehicleAirbagLocation.h>
+#include <aidl/android/hardware/automotive/vehicle/VehicleApPowerBootupReason.h>
#include <aidl/android/hardware/automotive/vehicle/VehicleApPowerStateReport.h>
#include <aidl/android/hardware/automotive/vehicle/VehicleApPowerStateReq.h>
#include <aidl/android/hardware/automotive/vehicle/VehicleArea.h>