Merge "Moved emulated User HAL capabilities into a library." into rvc-dev
This commit is contained in:
commit
d2115c9876
7 changed files with 338 additions and 196 deletions
|
@ -75,7 +75,10 @@ cc_library_static {
|
|||
],
|
||||
local_include_dirs: ["common/include/vhal_v2_0"],
|
||||
export_include_dirs: ["impl"],
|
||||
whole_static_libs: ["android.hardware.automotive.vehicle@2.0-manager-lib"],
|
||||
whole_static_libs: [
|
||||
"android.hardware.automotive.vehicle@2.0-emulated-user-hal-lib",
|
||||
"android.hardware.automotive.vehicle@2.0-manager-lib",
|
||||
],
|
||||
shared_libs: [
|
||||
"libbase",
|
||||
"libjsoncpp",
|
||||
|
@ -87,6 +90,16 @@ cc_library_static {
|
|||
],
|
||||
}
|
||||
|
||||
// Library used to emulate User HAL behavior through lshal debug requests.
|
||||
cc_library_static {
|
||||
name: "android.hardware.automotive.vehicle@2.0-emulated-user-hal-lib",
|
||||
vendor: true,
|
||||
defaults: ["vhal_v2_0_defaults"],
|
||||
srcs: [
|
||||
"impl/vhal_v2_0/EmulatedUserHal.cpp",
|
||||
],
|
||||
}
|
||||
|
||||
cc_test {
|
||||
name: "android.hardware.automotive.vehicle@2.0-manager-unit-tests",
|
||||
vendor: true,
|
||||
|
|
|
@ -79,8 +79,6 @@ constexpr int WHEEL_FRONT_LEFT = (int)VehicleAreaWheel::LEFT_FRONT;
|
|||
constexpr int WHEEL_FRONT_RIGHT = (int)VehicleAreaWheel::RIGHT_FRONT;
|
||||
constexpr int WHEEL_REAR_LEFT = (int)VehicleAreaWheel::LEFT_REAR;
|
||||
constexpr int WHEEL_REAR_RIGHT = (int)VehicleAreaWheel::RIGHT_REAR;
|
||||
constexpr int INITIAL_USER_INFO = (int)VehicleProperty::INITIAL_USER_INFO;
|
||||
constexpr int SWITCH_USER = (int)VehicleProperty::SWITCH_USER;
|
||||
|
||||
/**
|
||||
* This property is used for test purpose to generate fake events. Here is the test package that
|
||||
|
|
|
@ -0,0 +1,186 @@
|
|||
/*
|
||||
* Copyright (C) 2020 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.
|
||||
*/
|
||||
#define LOG_TAG "EmulatedUserHal"
|
||||
|
||||
#include <cutils/log.h>
|
||||
#include <utils/SystemClock.h>
|
||||
|
||||
#include "EmulatedUserHal.h"
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace automotive {
|
||||
namespace vehicle {
|
||||
namespace V2_0 {
|
||||
|
||||
namespace impl {
|
||||
|
||||
constexpr int INITIAL_USER_INFO = static_cast<int>(VehicleProperty::INITIAL_USER_INFO);
|
||||
constexpr int SWITCH_USER = static_cast<int>(VehicleProperty::SWITCH_USER);
|
||||
|
||||
bool EmulatedUserHal::isSupported(int32_t prop) {
|
||||
switch (prop) {
|
||||
case INITIAL_USER_INFO:
|
||||
case SWITCH_USER:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
android::base::Result<std::unique_ptr<VehiclePropValue>> EmulatedUserHal::onSetProperty(
|
||||
const VehiclePropValue& value) {
|
||||
ALOGV("onSetProperty(): %s", toString(value).c_str());
|
||||
|
||||
switch (value.prop) {
|
||||
case INITIAL_USER_INFO:
|
||||
return onSetInitialUserInfoResponse(value);
|
||||
case SWITCH_USER:
|
||||
return onSetSwitchUserResponse(value);
|
||||
default:
|
||||
return android::base::Error(static_cast<int>(StatusCode::INVALID_ARG))
|
||||
<< "Unsupported property: " << toString(value);
|
||||
}
|
||||
}
|
||||
|
||||
android::base::Result<std::unique_ptr<VehiclePropValue>>
|
||||
EmulatedUserHal::onSetInitialUserInfoResponse(const VehiclePropValue& value) {
|
||||
if (value.value.int32Values.size() == 0) {
|
||||
ALOGE("set(INITIAL_USER_INFO): no int32values, ignoring it: %s", toString(value).c_str());
|
||||
return android::base::Error(static_cast<int>(StatusCode::INVALID_ARG))
|
||||
<< "no int32values on " << toString(value);
|
||||
}
|
||||
|
||||
if (value.areaId != 0) {
|
||||
ALOGD("set(INITIAL_USER_INFO) called from lshal; storing it: %s", toString(value).c_str());
|
||||
mInitialUserResponseFromCmd.reset(new VehiclePropValue(value));
|
||||
return {};
|
||||
}
|
||||
|
||||
ALOGD("set(INITIAL_USER_INFO) called from Android: %s", toString(value).c_str());
|
||||
|
||||
int32_t requestId = value.value.int32Values[0];
|
||||
if (mInitialUserResponseFromCmd != nullptr) {
|
||||
ALOGI("replying INITIAL_USER_INFO with lshal value: %s",
|
||||
toString(*mInitialUserResponseFromCmd).c_str());
|
||||
return sendUserHalResponse(std::move(mInitialUserResponseFromCmd), requestId);
|
||||
}
|
||||
|
||||
// Returns default response
|
||||
auto updatedValue = std::unique_ptr<VehiclePropValue>(new VehiclePropValue);
|
||||
updatedValue->prop = INITIAL_USER_INFO;
|
||||
updatedValue->timestamp = elapsedRealtimeNano();
|
||||
updatedValue->value.int32Values.resize(2);
|
||||
updatedValue->value.int32Values[0] = requestId;
|
||||
updatedValue->value.int32Values[1] = (int32_t)InitialUserInfoResponseAction::DEFAULT;
|
||||
|
||||
ALOGI("no lshal response; replying with InitialUserInfoResponseAction::DEFAULT: %s",
|
||||
toString(*updatedValue).c_str());
|
||||
|
||||
return updatedValue;
|
||||
}
|
||||
|
||||
android::base::Result<std::unique_ptr<VehiclePropValue>> EmulatedUserHal::onSetSwitchUserResponse(
|
||||
const VehiclePropValue& value) {
|
||||
if (value.value.int32Values.size() == 0) {
|
||||
ALOGE("set(SWITCH_USER): no int32values, ignoring it: %s", toString(value).c_str());
|
||||
return android::base::Error(static_cast<int>(StatusCode::INVALID_ARG))
|
||||
<< "no int32values on " << toString(value);
|
||||
}
|
||||
|
||||
if (value.areaId != 0) {
|
||||
ALOGD("set(SWITCH_USER) called from lshal; storing it: %s", toString(value).c_str());
|
||||
mSwitchUserResponseFromCmd.reset(new VehiclePropValue(value));
|
||||
return {};
|
||||
}
|
||||
ALOGD("set(SWITCH_USER) called from Android: %s", toString(value).c_str());
|
||||
|
||||
int32_t requestId = value.value.int32Values[0];
|
||||
if (mSwitchUserResponseFromCmd != nullptr) {
|
||||
ALOGI("replying SWITCH_USER with lshal value: %s",
|
||||
toString(*mSwitchUserResponseFromCmd).c_str());
|
||||
return sendUserHalResponse(std::move(mSwitchUserResponseFromCmd), requestId);
|
||||
}
|
||||
|
||||
// Returns default response
|
||||
auto updatedValue = std::unique_ptr<VehiclePropValue>(new VehiclePropValue);
|
||||
updatedValue->prop = SWITCH_USER;
|
||||
updatedValue->timestamp = elapsedRealtimeNano();
|
||||
updatedValue->value.int32Values.resize(3);
|
||||
updatedValue->value.int32Values[0] = requestId;
|
||||
updatedValue->value.int32Values[1] = (int32_t)SwitchUserMessageType::VEHICLE_RESPONSE;
|
||||
updatedValue->value.int32Values[2] = (int32_t)SwitchUserStatus::SUCCESS;
|
||||
|
||||
ALOGI("no lshal response; replying with VEHICLE_RESPONSE / SUCCESS: %s",
|
||||
toString(*updatedValue).c_str());
|
||||
|
||||
return updatedValue;
|
||||
}
|
||||
|
||||
android::base::Result<std::unique_ptr<VehiclePropValue>> EmulatedUserHal::sendUserHalResponse(
|
||||
std::unique_ptr<VehiclePropValue> response, int32_t requestId) {
|
||||
switch (response->areaId) {
|
||||
case 1:
|
||||
ALOGD("returning response with right request id");
|
||||
response->value.int32Values[0] = requestId;
|
||||
break;
|
||||
case 2:
|
||||
ALOGD("returning response with wrong request id");
|
||||
response->value.int32Values[0] = -requestId;
|
||||
break;
|
||||
case 3:
|
||||
ALOGD("not generating a property change event because of lshal prop: %s",
|
||||
toString(*response).c_str());
|
||||
return android::base::Error(static_cast<int>(StatusCode::NOT_AVAILABLE))
|
||||
<< "not generating a property change event because of lshal prop: "
|
||||
<< toString(*response);
|
||||
default:
|
||||
ALOGE("invalid action on lshal response: %s", toString(*response).c_str());
|
||||
return android::base::Error(static_cast<int>(StatusCode::INTERNAL_ERROR))
|
||||
<< "invalid action on lshal response: " << toString(*response);
|
||||
}
|
||||
|
||||
ALOGD("updating property to: %s", toString(*response).c_str());
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
void EmulatedUserHal::showDumpHelp(int fd) {
|
||||
dprintf(fd, "%s: dumps state used for user management\n", kUserHalDumpOption);
|
||||
}
|
||||
|
||||
void EmulatedUserHal::dump(int fd, std::string indent) {
|
||||
if (mInitialUserResponseFromCmd != nullptr) {
|
||||
dprintf(fd, "%sInitialUserInfo response: %s\n", indent.c_str(),
|
||||
toString(*mInitialUserResponseFromCmd).c_str());
|
||||
} else {
|
||||
dprintf(fd, "%sNo InitialUserInfo response\n", indent.c_str());
|
||||
}
|
||||
if (mSwitchUserResponseFromCmd != nullptr) {
|
||||
dprintf(fd, "%sSwitchUser response: %s\n", indent.c_str(),
|
||||
toString(*mSwitchUserResponseFromCmd).c_str());
|
||||
} else {
|
||||
dprintf(fd, "%sNo SwitchUser response\n", indent.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace impl
|
||||
|
||||
} // namespace V2_0
|
||||
} // namespace vehicle
|
||||
} // namespace automotive
|
||||
} // namespace hardware
|
||||
} // namespace android
|
115
automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedUserHal.h
Normal file
115
automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedUserHal.h
Normal file
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* Copyright (C) 2020 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.
|
||||
*/
|
||||
|
||||
#ifndef android_hardware_automotive_vehicle_V2_0_impl_EmulatedUserHal_H_
|
||||
#define android_hardware_automotive_vehicle_V2_0_impl_EmulatedUserHal_H_
|
||||
|
||||
#include <android-base/result.h>
|
||||
|
||||
#include <android/hardware/automotive/vehicle/2.0/types.h>
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace automotive {
|
||||
namespace vehicle {
|
||||
namespace V2_0 {
|
||||
|
||||
namespace impl {
|
||||
|
||||
constexpr char kUserHalDumpOption[] = "--user-hal";
|
||||
|
||||
/**
|
||||
* Class used to emulate User HAL behavior through lshal debug requests.
|
||||
*/
|
||||
class EmulatedUserHal {
|
||||
public:
|
||||
EmulatedUserHal() {}
|
||||
|
||||
~EmulatedUserHal() = default;
|
||||
|
||||
/**
|
||||
* Checks if the emulator can handle the property.
|
||||
*/
|
||||
bool isSupported(int32_t prop);
|
||||
|
||||
/**
|
||||
* Lets the emulator handle the property.
|
||||
*
|
||||
* @return updated property and StatusCode
|
||||
*/
|
||||
android::base::Result<std::unique_ptr<VehiclePropValue>> onSetProperty(
|
||||
const VehiclePropValue& value);
|
||||
|
||||
/**
|
||||
* Shows the User HAL emulation help.
|
||||
*/
|
||||
void showDumpHelp(int fd);
|
||||
|
||||
/**
|
||||
* Dump its contents.
|
||||
*/
|
||||
void dump(int fd, std::string indent);
|
||||
|
||||
private:
|
||||
/**
|
||||
* INITIAL_USER_INFO is called by Android when it starts, and it's expecting a property change
|
||||
* indicating what the initial user should be.
|
||||
*
|
||||
* During normal circumstances, the emulator will reply right away, passing a response if
|
||||
* InitialUserInfoResponseAction::DEFAULT (so Android could use its own logic to decide which
|
||||
* user to boot).
|
||||
*
|
||||
* But during development / testing, the behavior can be changed using lshal dump, which must
|
||||
* use the areaId to indicate what should happen next.
|
||||
*
|
||||
* So, the behavior of set(INITIAL_USER_INFO) is:
|
||||
*
|
||||
* - if it has an areaId, store the property into mInitialUserResponseFromCmd (as it was called
|
||||
* by lshal).
|
||||
* - else if mInitialUserResponseFromCmd is not set, return a response with the same request id
|
||||
* and InitialUserInfoResponseAction::DEFAULT
|
||||
* - else the behavior is defined by the areaId on mInitialUserResponseFromCmd:
|
||||
* - if it's 1, reply with mInitialUserResponseFromCmd and the right request id
|
||||
* - if it's 2, reply with mInitialUserResponseFromCmd but a wrong request id (so Android can
|
||||
* test this error scenario)
|
||||
* - if it's 3, then don't send a property change (so Android can emulate a timeout)
|
||||
*
|
||||
*/
|
||||
android::base::Result<std::unique_ptr<VehiclePropValue>> onSetInitialUserInfoResponse(
|
||||
const VehiclePropValue& value);
|
||||
|
||||
/**
|
||||
* Used to emulate SWITCH_USER - see onSetInitialUserInfoResponse() for usage.
|
||||
*/
|
||||
android::base::Result<std::unique_ptr<VehiclePropValue>> onSetSwitchUserResponse(
|
||||
const VehiclePropValue& value);
|
||||
|
||||
android::base::Result<std::unique_ptr<VehiclePropValue>> sendUserHalResponse(
|
||||
std::unique_ptr<VehiclePropValue> response, int32_t requestId);
|
||||
|
||||
std::unique_ptr<VehiclePropValue> mInitialUserResponseFromCmd;
|
||||
std::unique_ptr<VehiclePropValue> mSwitchUserResponseFromCmd;
|
||||
};
|
||||
|
||||
} // namespace impl
|
||||
|
||||
} // namespace V2_0
|
||||
} // namespace vehicle
|
||||
} // namespace automotive
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
|
||||
#endif // android_hardware_automotive_vehicle_V2_0_impl_EmulatedUserHal_H_
|
|
@ -38,9 +38,6 @@ namespace impl {
|
|||
class EmulatedPassthroughConnector : public PassthroughConnector {
|
||||
public:
|
||||
bool onDump(const hidl_handle& fd, const hidl_vec<hidl_string>& options) override;
|
||||
|
||||
private:
|
||||
void dumpUserHal(int fd, std::string indent);
|
||||
};
|
||||
|
||||
bool EmulatedPassthroughConnector::onDump(const hidl_handle& handle,
|
||||
|
@ -50,12 +47,12 @@ bool EmulatedPassthroughConnector::onDump(const hidl_handle& handle,
|
|||
if (options.size() > 0) {
|
||||
if (options[0] == "--help") {
|
||||
dprintf(fd, "Emulator-specific usage:\n");
|
||||
dprintf(fd, "--user-hal: dumps state used for user management \n");
|
||||
mEmulatedUserHal.showDumpHelp(fd);
|
||||
dprintf(fd, "\n");
|
||||
// Include caller's help options
|
||||
return true;
|
||||
} else if (options[0] == "--user-hal") {
|
||||
dumpUserHal(fd, "");
|
||||
} else if (options[0] == kUserHalDumpOption) {
|
||||
mEmulatedUserHal.dump(fd, "");
|
||||
return false;
|
||||
|
||||
} else {
|
||||
|
@ -65,27 +62,12 @@ bool EmulatedPassthroughConnector::onDump(const hidl_handle& handle,
|
|||
}
|
||||
|
||||
dprintf(fd, "Emulator-specific state:\n");
|
||||
dumpUserHal(fd, " ");
|
||||
mEmulatedUserHal.dump(fd, " ");
|
||||
dprintf(fd, "\n");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void EmulatedPassthroughConnector::dumpUserHal(int fd, std::string indent) {
|
||||
if (mInitialUserResponseFromCmd != nullptr) {
|
||||
dprintf(fd, "%sInitialUserInfo response: %s\n", indent.c_str(),
|
||||
toString(*mInitialUserResponseFromCmd).c_str());
|
||||
} else {
|
||||
dprintf(fd, "%sNo InitialUserInfo response\n", indent.c_str());
|
||||
}
|
||||
if (mSwitchUserResponseFromCmd != nullptr) {
|
||||
dprintf(fd, "%sSwitchUser response: %s\n", indent.c_str(),
|
||||
toString(*mSwitchUserResponseFromCmd).c_str());
|
||||
} else {
|
||||
dprintf(fd, "%sNo SwitchUser response\n", indent.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
PassthroughConnectorPtr makeEmulatedPassthroughConnector() {
|
||||
return std::make_unique<EmulatedPassthroughConnector>();
|
||||
}
|
||||
|
|
|
@ -181,6 +181,23 @@ VehicleHalServer::VehiclePropValuePtr VehicleHalServer::createHwInputKeyProp(
|
|||
}
|
||||
|
||||
StatusCode VehicleHalServer::onSetProperty(const VehiclePropValue& value, bool updateStatus) {
|
||||
if (mEmulatedUserHal.isSupported(value.prop)) {
|
||||
LOG(INFO) << "onSetProperty(): property " << value.prop << " will be handled by UserHal";
|
||||
|
||||
const auto& ret = mEmulatedUserHal.onSetProperty(value);
|
||||
if (!ret.ok()) {
|
||||
LOG(ERROR) << "onSetProperty(): HAL returned error: " << ret.error().message();
|
||||
return StatusCode(ret.error().code());
|
||||
}
|
||||
auto updatedValue = ret.value().get();
|
||||
if (updatedValue != nullptr) {
|
||||
LOG(INFO) << "onSetProperty(): updating property returned by HAL: "
|
||||
<< toString(*updatedValue);
|
||||
onPropertyValueFromCar(*updatedValue, updateStatus);
|
||||
}
|
||||
return StatusCode::OK;
|
||||
}
|
||||
|
||||
// Some properties need to be treated non-trivially
|
||||
switch (value.prop) {
|
||||
case kGenerateFakeDataControllingProperty:
|
||||
|
@ -245,10 +262,6 @@ StatusCode VehicleHalServer::onSetProperty(const VehiclePropValue& value, bool u
|
|||
break;
|
||||
}
|
||||
break;
|
||||
case INITIAL_USER_INFO:
|
||||
return onSetInitialUserInfoResponse(value, updateStatus);
|
||||
case SWITCH_USER:
|
||||
return onSetSwitchUserResponse(value, updateStatus);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -262,165 +275,4 @@ StatusCode VehicleHalServer::onSetProperty(const VehiclePropValue& value, bool u
|
|||
return StatusCode::OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* INITIAL_USER_INFO is called by Android when it starts, and it's expecting a property change
|
||||
* indicating what the initial user should be.
|
||||
*
|
||||
* During normal circumstances, the emulator will reply right away, passing a response if
|
||||
* InitialUserInfoResponseAction::DEFAULT (so Android could use its own logic to decide which user
|
||||
* to boot).
|
||||
*
|
||||
* But during development / testing, the behavior can be changed using lshal dump, which must use
|
||||
* the areaId to indicate what should happen next.
|
||||
*
|
||||
* So, the behavior of set(INITIAL_USER_INFO) is:
|
||||
*
|
||||
* - if it has an areaId, store the property into mInitialUserResponseFromCmd (as it was called by
|
||||
* lshal).
|
||||
* - else if mInitialUserResponseFromCmd is not set, return a response with the same request id and
|
||||
* InitialUserInfoResponseAction::DEFAULT
|
||||
* - else the behavior is defined by the areaId on mInitialUserResponseFromCmd:
|
||||
* - if it's 1, reply with mInitialUserResponseFromCmd and the right request id
|
||||
* - if it's 2, reply with mInitialUserResponseFromCmd but a wrong request id (so Android can test
|
||||
* this error scenario)
|
||||
* - if it's 3, then don't send a property change (so Android can emulate a timeout)
|
||||
*
|
||||
*/
|
||||
StatusCode VehicleHalServer::onSetInitialUserInfoResponse(const VehiclePropValue& value,
|
||||
bool updateStatus) {
|
||||
// TODO: LOG calls below might be more suited to be DEBUG, but those are not being logged
|
||||
// (even when explicitly calling setprop log.tag. As this class should be using ALOG instead of
|
||||
// LOG, it's not worth investigating why...
|
||||
|
||||
if (value.value.int32Values.size() == 0) {
|
||||
LOG(ERROR) << "set(INITIAL_USER_INFO): no int32values, ignoring it: " << toString(value);
|
||||
return StatusCode::INVALID_ARG;
|
||||
}
|
||||
|
||||
if (value.areaId != 0) {
|
||||
LOG(INFO) << "set(INITIAL_USER_INFO) called from lshal; storing it: " << toString(value);
|
||||
mInitialUserResponseFromCmd.reset(new VehiclePropValue(value));
|
||||
return StatusCode::OK;
|
||||
}
|
||||
LOG(INFO) << "set(INITIAL_USER_INFO) called from Android: " << toString(value);
|
||||
|
||||
int32_t requestId = value.value.int32Values[0];
|
||||
|
||||
// Create the update property and set common values
|
||||
auto updatedValue = createVehiclePropValue(VehiclePropertyType::MIXED, 0);
|
||||
updatedValue->prop = INITIAL_USER_INFO;
|
||||
updatedValue->timestamp = elapsedRealtimeNano();
|
||||
|
||||
if (mInitialUserResponseFromCmd == nullptr) {
|
||||
updatedValue->value.int32Values.resize(2);
|
||||
updatedValue->value.int32Values[0] = requestId;
|
||||
updatedValue->value.int32Values[1] = (int32_t)InitialUserInfoResponseAction::DEFAULT;
|
||||
LOG(INFO) << "no lshal response; returning InitialUserInfoResponseAction::DEFAULT: "
|
||||
<< toString(*updatedValue);
|
||||
onPropertyValueFromCar(*updatedValue, updateStatus);
|
||||
return StatusCode::OK;
|
||||
}
|
||||
|
||||
// mInitialUserResponseFromCmd is used for just one request
|
||||
std::unique_ptr<VehiclePropValue> response = std::move(mInitialUserResponseFromCmd);
|
||||
|
||||
// TODO(b/150409377): rather than populate the raw values directly, it should use the
|
||||
// libraries that convert a InitialUserInfoResponse into a VehiclePropValue)
|
||||
|
||||
switch (response->areaId) {
|
||||
case 1:
|
||||
LOG(INFO) << "returning response with right request id";
|
||||
*updatedValue = *response;
|
||||
updatedValue->areaId = 0;
|
||||
updatedValue->value.int32Values[0] = requestId;
|
||||
break;
|
||||
case 2:
|
||||
LOG(INFO) << "returning response with wrong request id";
|
||||
*updatedValue = *response;
|
||||
updatedValue->areaId = 0;
|
||||
updatedValue->value.int32Values[0] = -requestId;
|
||||
break;
|
||||
case 3:
|
||||
LOG(INFO) << "not generating a property change event because of lshal prop: "
|
||||
<< toString(*response);
|
||||
return StatusCode::OK;
|
||||
default:
|
||||
LOG(ERROR) << "invalid action on lshal response: " << toString(*response);
|
||||
return StatusCode::INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
LOG(INFO) << "updating property to: " << toString(*updatedValue);
|
||||
onPropertyValueFromCar(*updatedValue, updateStatus);
|
||||
return StatusCode::OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to emulate SWITCH_USER - see onSetInitialUserInfoResponse() for usage.
|
||||
*/
|
||||
StatusCode VehicleHalServer::onSetSwitchUserResponse(const VehiclePropValue& value,
|
||||
bool updateStatus) {
|
||||
if (value.value.int32Values.size() == 0) {
|
||||
LOG(ERROR) << "set(SWITCH_USER): no int32values, ignoring it: " << toString(value);
|
||||
return StatusCode::INVALID_ARG;
|
||||
}
|
||||
|
||||
if (value.areaId != 0) {
|
||||
LOG(INFO) << "set(SWITCH_USER) called from lshal; storing it: " << toString(value);
|
||||
mSwitchUserResponseFromCmd.reset(new VehiclePropValue(value));
|
||||
return StatusCode::OK;
|
||||
}
|
||||
LOG(INFO) << "set(SWITCH_USER) called from Android: " << toString(value);
|
||||
|
||||
int32_t requestId = value.value.int32Values[0];
|
||||
|
||||
// Create the update property and set common values
|
||||
auto updatedValue = createVehiclePropValue(VehiclePropertyType::MIXED, 0);
|
||||
updatedValue->prop = SWITCH_USER;
|
||||
updatedValue->timestamp = elapsedRealtimeNano();
|
||||
|
||||
if (mSwitchUserResponseFromCmd == nullptr) {
|
||||
updatedValue->value.int32Values.resize(3);
|
||||
updatedValue->value.int32Values[0] = requestId;
|
||||
updatedValue->value.int32Values[1] = (int32_t)SwitchUserMessageType::VEHICLE_RESPONSE;
|
||||
updatedValue->value.int32Values[2] = (int32_t)SwitchUserStatus::SUCCESS;
|
||||
LOG(INFO) << "no lshal response; returning VEHICLE_RESPONSE / SUCCESS: "
|
||||
<< toString(*updatedValue);
|
||||
onPropertyValueFromCar(*updatedValue, updateStatus);
|
||||
return StatusCode::OK;
|
||||
}
|
||||
|
||||
// mSwitchUserResponseFromCmd is used for just one request
|
||||
std::unique_ptr<VehiclePropValue> response = std::move(mSwitchUserResponseFromCmd);
|
||||
|
||||
// TODO(b/150409377): move code below to a local function like sendUserHalResponse(),
|
||||
// as it's the same for all (like onSetInitialUserInfoResponse)
|
||||
|
||||
switch (response->areaId) {
|
||||
case 1:
|
||||
LOG(INFO) << "returning response with right request id";
|
||||
*updatedValue = *response;
|
||||
updatedValue->areaId = 0;
|
||||
updatedValue->value.int32Values[0] = requestId;
|
||||
break;
|
||||
case 2:
|
||||
LOG(INFO) << "returning response with wrong request id";
|
||||
*updatedValue = *response;
|
||||
updatedValue->areaId = 0;
|
||||
updatedValue->value.int32Values[0] = -requestId;
|
||||
break;
|
||||
case 3:
|
||||
LOG(INFO) << "not generating a property change event because of lshal prop: "
|
||||
<< toString(*response);
|
||||
return StatusCode::OK;
|
||||
default:
|
||||
LOG(ERROR) << "invalid action on lshal response: " << toString(*response);
|
||||
return StatusCode::INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
LOG(INFO) << "updating property to: " << toString(*updatedValue);
|
||||
onPropertyValueFromCar(*updatedValue, updateStatus);
|
||||
|
||||
return StatusCode::OK;
|
||||
}
|
||||
|
||||
} // namespace android::hardware::automotive::vehicle::V2_0::impl
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include <vhal_v2_0/VehicleObjectPool.h>
|
||||
#include <vhal_v2_0/VehicleServer.h>
|
||||
|
||||
#include "EmulatedUserHal.h"
|
||||
#include "GeneratorHub.h"
|
||||
|
||||
namespace android::hardware::automotive::vehicle::V2_0::impl {
|
||||
|
@ -53,15 +54,10 @@ class VehicleHalServer : public IVehicleServer {
|
|||
VehiclePropValuePtr createHwInputKeyProp(VehicleHwKeyInputAction action, int32_t keyCode,
|
||||
int32_t targetDisplay);
|
||||
|
||||
StatusCode onSetInitialUserInfoResponse(const VehiclePropValue& value, bool updateStatus);
|
||||
StatusCode onSetSwitchUserResponse(const VehiclePropValue& value, bool updateStatus);
|
||||
|
||||
// data members
|
||||
|
||||
protected:
|
||||
// TODO(b/146207078): it might be clearer to move members below to an EmulatedUserHal class
|
||||
std::unique_ptr<VehiclePropValue> mInitialUserResponseFromCmd;
|
||||
std::unique_ptr<VehiclePropValue> mSwitchUserResponseFromCmd;
|
||||
EmulatedUserHal mEmulatedUserHal;
|
||||
|
||||
private:
|
||||
GeneratorHub mGeneratorHub{
|
||||
|
|
Loading…
Reference in a new issue