Merge Android 24Q2 Release (ab/11526283) to aosp-main-future

Bug: 337098550
Merged-In: I53a278f1317f5307441103dc42dc5be6f20d7075
Change-Id: I3a53ebf7339cdb886d3c1b733b8eee1847f8832a
This commit is contained in:
Xin Li 2024-05-24 08:28:04 -07:00
commit 64e598ce2b
1711 changed files with 68615 additions and 1813 deletions

View file

@ -119,7 +119,8 @@ void SoundDose::onNewMelValues(const std::vector<float>& mels, size_t offset, si
void SoundDose::MelCallback::onNewMelValues(const std::vector<float>& mels, size_t offset,
size_t length,
audio_port_handle_t deviceId
__attribute__((__unused__))) const {
__attribute__((__unused__)),
bool attenuated __attribute__((__unused__))) const {
mSoundDose.onNewMelValues(mels, offset, length, deviceId);
}

View file

@ -64,7 +64,7 @@ class SoundDose final : public BnSoundDose, public StreamDataProcessorInterface
// ------------------------------------ MelCallback ----------------------------------------
void onNewMelValues(const std::vector<float>& mels, size_t offset, size_t length,
audio_port_handle_t deviceId) const override;
audio_port_handle_t deviceId, bool attenuated) const override;
void onMomentaryExposure(float currentMel, audio_port_handle_t deviceId) const override;
SoundDose& mSoundDose; // must outlive MelCallback, not owning

View file

@ -50,9 +50,16 @@ aidl_interface {
"android.media.audio.common.types-V2",
],
},
{
version: "4",
imports: [
"android.media.audio.common.types-V3",
"android.hardware.audio.common-V3",
],
},
],
frozen: false,
frozen: true,
}

View file

@ -0,0 +1 @@
ee20ab2e2d0ffb894fc0b2ca33b72796d636793a

View file

@ -0,0 +1,45 @@
/*
* 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.
*/
///////////////////////////////////////////////////////////////////////////////
// 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.audiocontrol;
@Backing(type="int") @VintfStability
enum AudioFocusChange {
NONE = 0,
GAIN = 1,
GAIN_TRANSIENT = 2,
GAIN_TRANSIENT_MAY_DUCK = 3,
GAIN_TRANSIENT_EXCLUSIVE = 4,
LOSS = ((-1) * GAIN) /* -1 */,
LOSS_TRANSIENT = ((-1) * GAIN_TRANSIENT) /* -2 */,
LOSS_TRANSIENT_CAN_DUCK = ((-1) * GAIN_TRANSIENT_MAY_DUCK) /* -3 */,
}

View file

@ -0,0 +1,40 @@
/*
* Copyright (C) 2022 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.audiocontrol;
@VintfStability
parcelable AudioGainConfigInfo {
int zoneId;
String devicePortAddress;
int volumeIndex;
}

View file

@ -0,0 +1,42 @@
/*
* 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.
*/
///////////////////////////////////////////////////////////////////////////////
// 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.audiocontrol;
@VintfStability
parcelable DuckingInfo {
int zoneId;
String[] deviceAddressesToDuck;
String[] deviceAddressesToUnduck;
String[] usagesHoldingFocus;
@nullable android.hardware.audio.common.PlaybackTrackMetadata[] playbackMetaDataHoldingFocus;
}

View file

@ -0,0 +1,79 @@
/*
* 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.
*//**
* Important note on Metadata:
* Metadata qualifies a playback track for an output stream.
* This is highly closed to {@link android.media.AudioAttributes}.
* It allows to identify the audio stream rendered / requesting / abandonning the focus.
*
* AudioControl 1.0 was limited to identification through {@code AttributeUsage} listed as
* {@code audioUsage} in audio_policy_configuration.xsd.
*
* Any new OEM needs would not be possible without extension.
*
* Relying on {@link android.hardware.automotive.audiocontrol.PlaybackTrackMetadata} allows
* to use a combination of {@code AttributeUsage}, {@code AttributeContentType} and
* {@code AttributeTags} to identify the use case / routing thanks to
* {@link android.media.audiopolicy.AudioProductStrategy}.
* The belonging to a strategy is deduced by an AOSP logic (in sync at native and java layer).
*
* IMPORTANT NOTE ON TAGS:
* To limit the possibilies and prevent from confusion, we expect the String to follow
* a given formalism that will be enforced.
*
* 1 / By convention, tags shall be a "key=value" pair.
* Vendor must namespace their tag's key (for example com.google.strategy=VR) to avoid conflicts.
* vendor specific applications and must be prefixed by "VX_". Vendor must
*
* 2 / Tags reported here shall be the same as the tags used to define a given
* {@link android.media.audiopolicy.AudioProductStrategy} and so in
* audio_policy_engine_configuration.xml file.
*/
///////////////////////////////////////////////////////////////////////////////
// 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.audiocontrol;
@VintfStability
interface IAudioControl {
/**
* @deprecated use {@link android.hardware.audio.common.PlaybackTrackMetadata} instead.
*/
oneway void onAudioFocusChange(in String usage, in int zoneId, in android.hardware.automotive.audiocontrol.AudioFocusChange focusChange);
oneway void onDevicesToDuckChange(in android.hardware.automotive.audiocontrol.DuckingInfo[] duckingInfos);
oneway void onDevicesToMuteChange(in android.hardware.automotive.audiocontrol.MutingInfo[] mutingInfos);
oneway void registerFocusListener(in android.hardware.automotive.audiocontrol.IFocusListener listener);
oneway void setBalanceTowardRight(in float value);
oneway void setFadeTowardFront(in float value);
oneway void onAudioFocusChangeWithMetaData(in android.hardware.audio.common.PlaybackTrackMetadata playbackMetaData, in int zoneId, in android.hardware.automotive.audiocontrol.AudioFocusChange focusChange);
oneway void setAudioDeviceGainsChanged(in android.hardware.automotive.audiocontrol.Reasons[] reasons, in android.hardware.automotive.audiocontrol.AudioGainConfigInfo[] gains);
oneway void registerGainCallback(in android.hardware.automotive.audiocontrol.IAudioGainCallback callback);
void setModuleChangeCallback(in android.hardware.automotive.audiocontrol.IModuleChangeCallback callback);
void clearModuleChangeCallback();
}

View file

@ -0,0 +1,38 @@
/*
* Copyright (C) 2022 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.audiocontrol;
@VintfStability
interface IAudioGainCallback {
oneway void onAudioDeviceGainsChanged(in android.hardware.automotive.audiocontrol.Reasons[] reasons, in android.hardware.automotive.audiocontrol.AudioGainConfigInfo[] gains);
}

View file

@ -0,0 +1,41 @@
/*
* 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.
*/
///////////////////////////////////////////////////////////////////////////////
// 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.audiocontrol;
@VintfStability
interface IFocusListener {
oneway void abandonAudioFocus(in String usage, in int zoneId);
oneway void requestAudioFocus(in String usage, in int zoneId, in android.hardware.automotive.audiocontrol.AudioFocusChange focusGain);
oneway void abandonAudioFocusWithMetaData(in android.hardware.audio.common.PlaybackTrackMetadata playbackMetaData, in int zoneId);
oneway void requestAudioFocusWithMetaData(in android.hardware.audio.common.PlaybackTrackMetadata playbackMetaData, in int zoneId, in android.hardware.automotive.audiocontrol.AudioFocusChange focusGain);
}

View file

@ -0,0 +1,38 @@
/*
* 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.audiocontrol;
@VintfStability
interface IModuleChangeCallback {
oneway void onAudioPortsChanged(in android.media.audio.common.AudioPort[] audioPorts);
}

View file

@ -0,0 +1,40 @@
/*
* 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.
*/
///////////////////////////////////////////////////////////////////////////////
// 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.audiocontrol;
@VintfStability
parcelable MutingInfo {
int zoneId;
String[] deviceAddressesToMute;
String[] deviceAddressesToUnmute;
}

View file

@ -0,0 +1,47 @@
/*
* Copyright (C) 2022 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.audiocontrol;
@Backing(type="int") @VintfStability
enum Reasons {
FORCED_MASTER_MUTE = 0x1,
REMOTE_MUTE = 0x2,
TCU_MUTE = 0x4,
ADAS_DUCKING = 0x8,
NAV_DUCKING = 0x10,
PROJECTION_DUCKING = 0x20,
THERMAL_LIMITATION = 0x40,
SUSPEND_EXIT_VOL_LIMITATION = 0x80,
EXTERNAL_AMP_VOL_FEEDBACK = 0x100,
OTHER = 0x80000000,
}

View file

@ -27,11 +27,13 @@ cc_binary {
init_rc: ["audiocontrol-default.rc"],
vintf_fragments: ["audiocontrol-default.xml"],
vendor: true,
defaults: [
"latest_android_hardware_audio_common_ndk_shared",
"latest_android_hardware_automotive_audiocontrol_ndk_shared",
],
shared_libs: [
"android.hardware.audio.common@7.0-enums",
"android.hardware.audio.common-V1-ndk",
"android.frameworks.automotive.powerpolicy-V2-ndk",
"android.hardware.automotive.audiocontrol-V3-ndk",
"libbase",
"libbinder_ndk",
"libcutils",

View file

@ -48,23 +48,18 @@ static std::optional<std::string> readString(std::istream& s, std::streamsize n)
char buff[n];
auto got = s.read(buff, n).gcount();
if (!s.good() && !s.eof()) return std::nullopt;
return std::string(buff, 0, std::min(n, got));
return std::string(buff, got);
}
/*
parseConfigFile *used to* contain the body of parseConfigStream. However, it seems there's some
sort of odd behavior with IstreamInputStream and/or TextFormat::Parse, which causes HW Address
Sanitizer to flag a "tag-mismatch" in this function. Having the ifstream defined in a wrapper
function seems to solve this problem. The exact cause of this problem is yet unknown, but probably
lies somewhere in the protobuf implementation.
*/
static __attribute__((noinline)) std::optional<CanBusConfig> parseConfigStream(
std::ifstream& cfg_stream) {
std::optional<CanBusConfig> parseConfigFile(const std::string& filepath) {
std::ifstream cfg_stream(filepath);
// text headers that would be present in a plaintext proto config file.
static const std::array<std::string, 3> text_headers = {"buses", "#", "controller"};
auto cfg_file_snippet = readString(cfg_stream, 10);
if (!cfg_file_snippet.has_value()) {
LOG(ERROR) << "Can't read config from stream (maybe failed to open file?)";
LOG(ERROR) << "Can't open " << filepath << " for reading";
return std::nullopt;
}
cfg_stream.seekg(0);
@ -82,25 +77,16 @@ static __attribute__((noinline)) std::optional<CanBusConfig> parseConfigStream(
if (text_format) {
google::protobuf::io::IstreamInputStream pb_stream(&cfg_stream);
if (!google::protobuf::TextFormat::Parse(&pb_stream, &config)) {
LOG(ERROR) << "Parsing text format config failed";
LOG(ERROR) << "Failed to parse (text format) " << filepath;
return std::nullopt;
}
} else if (!config.ParseFromIstream(&cfg_stream)) {
LOG(ERROR) << "Parsing binary format config failed";
LOG(ERROR) << "Failed to parse (binary format) " << filepath;
return std::nullopt;
}
return config;
}
std::optional<CanBusConfig> parseConfigFile(const std::string& filepath) {
std::ifstream cfg_stream(filepath);
auto cfg_maybe = parseConfigStream(cfg_stream);
if (!cfg_maybe.has_value()) {
LOG(ERROR) << "Failed to parse " << filepath;
}
return cfg_maybe;
}
std::optional<BusConfig> fromPbBus(const Bus& pb_bus) {
BusConfig bus_cfg = {};
bus_cfg.name = pb_bus.name();

View file

@ -222,10 +222,9 @@ void EvsVideoEmulatedCamera::onCodecOutputAvailable(const int32_t index,
// Lock our output buffer for writing
uint8_t* pixels = nullptr;
int32_t bytesPerStride = 0;
auto& mapper = ::android::GraphicBufferMapper::get();
mapper.lock(renderBufferHandle, GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_SW_READ_NEVER,
::android::Rect(mWidth, mHeight), (void**)&pixels, nullptr, &bytesPerStride);
::android::Rect(mWidth, mHeight), (void**)&pixels);
// If we failed to lock the pixel buffer, we're about to crash, but log it first
if (!pixels) {
@ -247,13 +246,6 @@ void EvsVideoEmulatedCamera::onCodecOutputAvailable(const int32_t index,
*(pixels++) = *(v_head++);
}
const auto status =
AMediaCodec_releaseOutputBuffer(mVideoCodec.get(), index, /* render = */ false);
if (status != AMEDIA_OK) {
LOG(ERROR) << __func__
<< ": Received error in releasing output buffer. Error code: " << status;
}
// Release our output buffer
mapper.unlock(renderBufferHandle);
@ -306,6 +298,12 @@ void EvsVideoEmulatedCamera::renderOneFrame() {
return;
}
onCodecOutputAvailable(codecOutputputBufferIdx, info);
const auto release_status = AMediaCodec_releaseOutputBuffer(
mVideoCodec.get(), codecOutputputBufferIdx, /* render = */ false);
if (release_status != AMEDIA_OK) {
LOG(ERROR) << __func__
<< ": Received error in releasing output buffer. Error code: " << release_status;
}
}
void EvsVideoEmulatedCamera::initializeParameters() {

View file

@ -41,6 +41,11 @@ aidl_interface {
version: "1",
imports: [],
},
{
version: "2",
imports: [],
},
],
frozen: false,
frozen: true,
}

View file

@ -0,0 +1,7 @@
{
"auto-presubmit": [
{
"name": "VtsHalAutomotiveRemoteAccess_TargetTest"
}
]
}

View file

@ -0,0 +1 @@
65aaf23d323eed468f5d1e9ee4b7029ee6f1288a

View file

@ -0,0 +1,39 @@
/*
* Copyright (C) 2022 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;
@VintfStability
parcelable ApState {
boolean isReadyForRemoteTask;
boolean isWakeupRequired;
}

View file

@ -0,0 +1,50 @@
/*
* Copyright (C) 2022 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;
@VintfStability
interface IRemoteAccess {
String getVehicleId();
String getWakeupServiceName();
String getProcessorId();
void setRemoteTaskCallback(android.hardware.automotive.remoteaccess.IRemoteTaskCallback callback);
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);
boolean isTaskScheduled(String clientId, String scheduleId);
List<android.hardware.automotive.remoteaccess.ScheduleInfo> getAllPendingScheduledTasks(String clientId);
}

View file

@ -0,0 +1,38 @@
/*
* Copyright (C) 2022 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;
@VintfStability
interface IRemoteTaskCallback {
oneway void onRemoteTaskRequested(String clientId, in byte[] data);
}

View file

@ -0,0 +1,45 @@
/*
* 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;
android.hardware.automotive.remoteaccess.TaskType taskType;
byte[] taskData;
int count;
long startTimeInEpochSeconds;
long periodicInSeconds;
const int MAX_TASK_DATA_SIZE_IN_BYTES = 10240;
}

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

@ -41,9 +41,10 @@ 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);
boolean isTaskScheduled(String clientId, String scheduleId);
List<android.hardware.automotive.remoteaccess.ScheduleInfo> getAllScheduledTasks(String clientId);
List<android.hardware.automotive.remoteaccess.ScheduleInfo> getAllPendingScheduledTasks(String clientId);
}

View file

@ -36,8 +36,10 @@ package android.hardware.automotive.remoteaccess;
parcelable ScheduleInfo {
String clientId;
String scheduleId;
android.hardware.automotive.remoteaccess.TaskType taskType;
byte[] taskData;
int count;
long startTimeInEpochSeconds;
long periodicInSeconds;
const int MAX_TASK_DATA_SIZE_IN_BYTES = 10240;
}

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,11 @@ 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.
*
* <p>Must return {@code EX_ILLEGLA_ARGUMENT} if the scheduleInfo is not valid (e.g. count is
* a negative number).
*/
void scheduleTask(in ScheduleInfo scheduleInfo);
@ -161,5 +204,5 @@ interface IRemoteAccess {
*
* <p>The finished scheduled tasks will not be included.
*/
List<ScheduleInfo> getAllScheduledTasks(String clientId);
List<ScheduleInfo> getAllPendingScheduledTasks(String clientId);
}

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,9 +16,12 @@
package android.hardware.automotive.remoteaccess;
import android.hardware.automotive.remoteaccess.TaskType;
@VintfStability
@JavaDerive(equals=true, toString=true)
parcelable ScheduleInfo {
const int MAX_TASK_DATA_SIZE_IN_BYTES = 10240;
/**
* 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
@ -30,9 +33,17 @@ 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}.
*
* <p>The data size must be less than {@link MAX_TASK_DATA_SIZE_IN_BYTES}.
*/
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

@ -53,9 +53,6 @@ cc_binary {
defaults: ["remote-access-hal-defaults"],
vintf_fragments: ["remoteaccess-default-service.xml"],
init_rc: ["remoteaccess-default-service.rc"],
cflags: [
"-DGRPC_SERVICE_ADDRESS=\"10.0.2.2:50051\"",
],
}
cc_binary {
@ -63,10 +60,6 @@ cc_binary {
defaults: ["remote-access-hal-defaults"],
vintf_fragments: ["remoteaccess-default-service.xml"],
init_rc: ["remoteaccess-tcu-test-service.rc"],
cflags: [
"-DGRPC_SERVICE_ADDRESS=\"10.10.10.1:50051\"",
"-DGRPC_SERVICE_IFNAME=\"eth1\"",
],
}
cc_library {

View file

@ -75,8 +75,9 @@ class MockGrpcClientStub : public WakeupClient::StubInterface {
return Status::OK;
}
Status GetAllScheduledTasks(ClientContext* context, const GetAllScheduledTasksRequest& request,
GetAllScheduledTasksResponse* response) {
Status GetAllPendingScheduledTasks(ClientContext* context,
const GetAllPendingScheduledTasksRequest& request,
GetAllPendingScheduledTasksResponse* response) {
return Status::OK;
}
@ -165,17 +166,19 @@ class MockGrpcClientStub : public WakeupClient::StubInterface {
return nullptr;
}
ClientAsyncResponseReaderInterface<GetAllScheduledTasksResponse>* AsyncGetAllScheduledTasksRaw(
ClientAsyncResponseReaderInterface<GetAllPendingScheduledTasksResponse>*
AsyncGetAllPendingScheduledTasksRaw(
[[maybe_unused]] ClientContext* context,
[[maybe_unused]] const GetAllScheduledTasksRequest& request,
[[maybe_unused]] const GetAllPendingScheduledTasksRequest& request,
[[maybe_unused]] CompletionQueue* cq) {
return nullptr;
}
ClientAsyncResponseReaderInterface<GetAllScheduledTasksResponse>*
PrepareAsyncGetAllScheduledTasksRaw([[maybe_unused]] ClientContext* context,
[[maybe_unused]] const GetAllScheduledTasksRequest& request,
[[maybe_unused]] CompletionQueue* c) {
ClientAsyncResponseReaderInterface<GetAllPendingScheduledTasksResponse>*
PrepareAsyncGetAllPendingScheduledTasksRaw(
[[maybe_unused]] ClientContext* context,
[[maybe_unused]] const GetAllPendingScheduledTasksRequest& request,
[[maybe_unused]] CompletionQueue* c) {
return nullptr;
}
};

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;
@ -93,7 +96,7 @@ class RemoteAccessService
ndk::ScopedAStatus isTaskScheduled(const std::string& clientId, const std::string& scheduleId,
bool* out) override;
ndk::ScopedAStatus getAllScheduledTasks(
ndk::ScopedAStatus getAllPendingScheduledTasks(
const std::string& clientId,
std::vector<aidl::android::hardware::automotive::remoteaccess::ScheduleInfo>* out)
override;
@ -108,6 +111,8 @@ class RemoteAccessService
WakeupClient::StubInterface* mGrpcStub;
std::thread mThread;
// Whether the GRPC server exists. Only checked and set during init.
bool mGrpcServerExist = false;
std::mutex mLock;
std::condition_variable mCv;
std::shared_ptr<aidl::android::hardware::automotive::remoteaccess::IRemoteTaskCallback>
@ -118,7 +123,7 @@ class RemoteAccessService
// A mutex to make sure startTaskLoop does not overlap with stopTaskLoop.
std::mutex mStartStopTaskLoopLock;
bool mTaskLoopRunning GUARDED_BY(mStartStopTaskLoopLock) = false;
bool mGrpcConnected GUARDED_BY(mLock) = false;
bool mGrpcReadChannelOpen GUARDED_BY(mLock) = false;
std::unordered_map<std::string, size_t> mClientIdToTaskCount GUARDED_BY(mLock);
// Default wait time before retry connecting to remote access client is 10s.
@ -140,9 +145,10 @@ class RemoteAccessService
void debugInjectTask(int fd, std::string_view clientId, std::string_view taskData);
void debugInjectTaskNextReboot(int fd, std::string_view clientId, std::string_view taskData,
const char* latencyInSecStr);
void updateGrpcConnected(bool connected);
void updateGrpcReadChannelOpen(bool grpcReadChannelOpen);
android::base::Result<void> deliverRemoteTaskThroughCallback(const std::string& clientId,
std::string_view taskData);
bool isTaskScheduleSupported();
};
} // namespace remoteaccess

View file

@ -99,7 +99,8 @@ service WakeupClient {
*
* <p>The finished scheduled tasks will not be included.
*/
rpc GetAllScheduledTasks(GetAllScheduledTasksRequest) returns (GetAllScheduledTasksResponse) {}
rpc GetAllPendingScheduledTasks(GetAllPendingScheduledTasksRequest)
returns (GetAllPendingScheduledTasksResponse) {}
}
message GetRemoteTasksRequest {}
@ -123,6 +124,11 @@ message ScheduleTaskResponse {
ErrorCode errorCode = 1;
}
enum ScheduleTaskType {
CUSTOM = 0;
ENTER_GARAGE_MODE = 1;
}
message GrpcScheduleInfo {
string clientId = 1;
string scheduleId = 2;
@ -130,6 +136,7 @@ message GrpcScheduleInfo {
int32 count = 4;
int64 startTimeInEpochSeconds = 5;
int64 periodicInSeconds = 6;
ScheduleTaskType taskType = 7;
}
message UnscheduleTaskRequest {
@ -154,10 +161,32 @@ message IsTaskScheduledResponse {
bool isTaskScheduled = 1;
}
message GetAllScheduledTasksRequest {
message GetAllPendingScheduledTasksRequest {
string clientId = 1;
}
message GetAllScheduledTasksResponse {
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;
}

View file

@ -27,31 +27,66 @@
#include <libnetdevice/libnetdevice.h>
#include <stdlib.h>
namespace {
constexpr char GRPC_SERVICE_CONFIG_FILE[] = "/vendor/etc/automotive/powercontroller/serverconfig";
constexpr char SERVICE_NAME[] = "android.hardware.automotive.remoteaccess.IRemoteAccess/default";
int main(int /* argc */, char* /* argv */[]) {
#ifndef GRPC_SERVICE_ADDRESS
LOG(ERROR) << "GRPC_SERVICE_ADDRESS is not defined, exiting";
exit(1);
#endif
LOG(INFO) << "Registering RemoteAccessService as service, server: " << GRPC_SERVICE_ADDRESS
<< "...";
grpc::ChannelArguments grpcargs = {};
void maybeGetGrpcServiceInfo(std::string* address, std::string* ifname) {
std::ifstream ifs(GRPC_SERVICE_CONFIG_FILE);
if (!ifs) {
LOG(INFO) << "Cannot open grpc service config file at: " << GRPC_SERVICE_CONFIG_FILE
<< ", assume no service is available";
return;
}
int count = 0;
while (ifs.good()) {
std::string line;
ifs >> line;
// First line is address, second line, if present is ifname.
if (count == 0) {
*address = line;
} else {
*ifname = line;
break;
}
count++;
}
ifs.close();
}
} // namespace
int main(int /* argc */, char* /* argv */[]) {
std::string grpcServiceAddress = "";
std::string grpcServiceIfname = "";
maybeGetGrpcServiceInfo(&grpcServiceAddress, &grpcServiceIfname);
std::unique_ptr<android::hardware::automotive::remoteaccess::WakeupClient::Stub> grpcStub;
if (grpcServiceAddress != "") {
LOG(INFO) << "Registering RemoteAccessService as service, server: " << grpcServiceAddress
<< "...";
grpc::ChannelArguments grpcargs = {};
if (grpcServiceIfname != "") {
grpcargs.SetSocketMutator(
android::hardware::automotive::remoteaccess::MakeBindToDeviceSocketMutator(
grpcServiceIfname));
LOG(DEBUG) << "grpcServiceIfname specified as: " << grpcServiceIfname;
LOG(INFO) << "Waiting for interface: " << grpcServiceIfname;
android::netdevice::waitFor({grpcServiceIfname},
android::netdevice::WaitCondition::PRESENT_AND_UP);
LOG(INFO) << "Waiting for interface: " << grpcServiceIfname << " done";
}
auto channel = grpc::CreateChannel(grpcServiceAddress, grpc::InsecureChannelCredentials());
grpcStub = android::hardware::automotive::remoteaccess::WakeupClient::NewStub(channel);
} else {
LOG(INFO) << "grpcServiceAddress is not defined, work in fake mode";
}
#ifdef GRPC_SERVICE_IFNAME
grpcargs.SetSocketMutator(
android::hardware::automotive::remoteaccess::MakeBindToDeviceSocketMutator(
GRPC_SERVICE_IFNAME));
LOG(DEBUG) << "GRPC_SERVICE_IFNAME specified as: " << GRPC_SERVICE_IFNAME;
LOG(INFO) << "Waiting for interface: " << GRPC_SERVICE_IFNAME;
android::netdevice::waitFor({GRPC_SERVICE_IFNAME},
android::netdevice::WaitCondition::PRESENT_AND_UP);
LOG(INFO) << "Waiting for interface: " << GRPC_SERVICE_IFNAME << " done";
#endif
auto channel = grpc::CreateChannel(GRPC_SERVICE_ADDRESS, grpc::InsecureChannelCredentials());
auto clientStub = android::hardware::automotive::remoteaccess::WakeupClient::NewStub(channel);
auto service = ndk::SharedRefBase::make<
android::hardware::automotive::remoteaccess::RemoteAccessService>(clientStub.get());
android::hardware::automotive::remoteaccess::RemoteAccessService>(grpcStub.get());
binder_exception_t err = AServiceManager_addService(service->asBinder().get(), SERVICE_NAME);
if (err != EX_NONE) {

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;
@ -102,6 +103,10 @@ std::string boolToString(bool x) {
RemoteAccessService::RemoteAccessService(WakeupClient::StubInterface* grpcStub)
: mGrpcStub(grpcStub) {
if (mGrpcStub != nullptr) {
mGrpcServerExist = true;
}
std::ifstream debugTaskFile;
debugTaskFile.open(DEBUG_TASK_FILE, std::ios::in);
if (!debugTaskFile.is_open()) {
@ -176,9 +181,9 @@ void RemoteAccessService::maybeStopTaskLoop() {
mTaskLoopRunning = false;
}
void RemoteAccessService::updateGrpcConnected(bool connected) {
void RemoteAccessService::updateGrpcReadChannelOpen(bool grpcReadChannelOpen) {
std::lock_guard<std::mutex> lockGuard(mLock);
mGrpcConnected = connected;
mGrpcReadChannelOpen = grpcReadChannelOpen;
}
Result<void> RemoteAccessService::deliverRemoteTaskThroughCallback(const std::string& clientId,
@ -212,7 +217,7 @@ void RemoteAccessService::runTaskLoop() {
mGetRemoteTasksContext.reset(new ClientContext());
reader = mGrpcStub->GetRemoteTasks(mGetRemoteTasksContext.get(), request);
}
updateGrpcConnected(true);
updateGrpcReadChannelOpen(true);
GetRemoteTasksResponse response;
while (reader->Read(&response)) {
ALOGI("Receiving one task from remote task client");
@ -224,7 +229,7 @@ void RemoteAccessService::runTaskLoop() {
continue;
}
}
updateGrpcConnected(false);
updateGrpcReadChannelOpen(false);
Status status = reader->Finish();
mGetRemoteTasksContext.reset();
@ -297,6 +302,11 @@ ScopedAStatus RemoteAccessService::clearRemoteTaskCallback() {
}
ScopedAStatus RemoteAccessService::notifyApStateChange(const ApState& newState) {
if (!mGrpcServerExist) {
ALOGW("GRPC server does not exist, do nothing");
return ScopedAStatus::ok();
}
ClientContext context;
NotifyWakeupRequiredRequest request = {};
request.set_iswakeuprequired(newState.isWakeupRequired);
@ -314,16 +324,64 @@ ScopedAStatus RemoteAccessService::notifyApStateChange(const ApState& newState)
return ScopedAStatus::ok();
}
bool RemoteAccessService::isTaskScheduleSupported() {
if (!mGrpcServerExist) {
ALOGW("GRPC server does not exist, task scheduling not supported");
return false;
}
return true;
}
ScopedAStatus RemoteAccessService::isTaskScheduleSupported(bool* out) {
*out = true;
*out = isTaskScheduleSupported();
return ScopedAStatus::ok();
}
ndk::ScopedAStatus RemoteAccessService::getSupportedTaskTypesForScheduling(
std::vector<TaskType>* out) {
out->clear();
if (!isTaskScheduleSupported()) {
ALOGW("Task scheduleing is not supported, return empty task types");
return ScopedAStatus::ok();
}
out->push_back(TaskType::CUSTOM);
out->push_back(TaskType::ENTER_GARAGE_MODE);
return ScopedAStatus::ok();
}
ScopedAStatus RemoteAccessService::scheduleTask(const ScheduleInfo& scheduleInfo) {
if (!isTaskScheduleSupported()) {
ALOGW("Task scheduleing is not supported, return exception");
return ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
"task scheduling is not supported");
}
ClientContext context;
ScheduleTaskRequest request = {};
ScheduleTaskResponse response = {};
if (scheduleInfo.count < 0) {
return ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
"count must be >= 0");
}
if (scheduleInfo.startTimeInEpochSeconds < 0) {
return ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
"startTimeInEpochSeconds must be >= 0");
}
if (scheduleInfo.periodicInSeconds < 0) {
return ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
"periodicInSeconds must be >= 0");
}
if (scheduleInfo.taskData.size() > scheduleInfo.MAX_TASK_DATA_SIZE_IN_BYTES) {
return ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
"task data too big");
}
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());
@ -340,7 +398,8 @@ ScopedAStatus RemoteAccessService::scheduleTask(const ScheduleInfo& scheduleInfo
case ErrorCode::OK:
return ScopedAStatus::ok();
case ErrorCode::INVALID_ARG:
return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
return ScopedAStatus::fromExceptionCodeWithMessage(
EX_ILLEGAL_ARGUMENT, "received invalid_arg from grpc server");
default:
// Should not happen.
return ScopedAStatus::fromServiceSpecificErrorWithMessage(
@ -352,6 +411,11 @@ ScopedAStatus RemoteAccessService::scheduleTask(const ScheduleInfo& scheduleInfo
ScopedAStatus RemoteAccessService::unscheduleTask(const std::string& clientId,
const std::string& scheduleId) {
if (!isTaskScheduleSupported()) {
ALOGW("Task scheduleing is not supported, do nothing");
return ScopedAStatus::ok();
}
ClientContext context;
UnscheduleTaskRequest request = {};
UnscheduleTaskResponse response = {};
@ -365,6 +429,11 @@ ScopedAStatus RemoteAccessService::unscheduleTask(const std::string& clientId,
}
ScopedAStatus RemoteAccessService::unscheduleAllTasks(const std::string& clientId) {
if (!isTaskScheduleSupported()) {
ALOGW("Task scheduleing is not supported, do nothing");
return ScopedAStatus::ok();
}
ClientContext context;
UnscheduleAllTasksRequest request = {};
UnscheduleAllTasksResponse response = {};
@ -378,6 +447,12 @@ ScopedAStatus RemoteAccessService::unscheduleAllTasks(const std::string& clientI
ScopedAStatus RemoteAccessService::isTaskScheduled(const std::string& clientId,
const std::string& scheduleId, bool* out) {
if (!isTaskScheduleSupported()) {
ALOGW("Task scheduleing is not supported, return false");
*out = false;
return ScopedAStatus::ok();
}
ClientContext context;
IsTaskScheduledRequest request = {};
IsTaskScheduledResponse response = {};
@ -391,13 +466,19 @@ ScopedAStatus RemoteAccessService::isTaskScheduled(const std::string& clientId,
return ScopedAStatus::ok();
}
ScopedAStatus RemoteAccessService::getAllScheduledTasks(const std::string& clientId,
std::vector<ScheduleInfo>* out) {
ScopedAStatus RemoteAccessService::getAllPendingScheduledTasks(const std::string& clientId,
std::vector<ScheduleInfo>* out) {
if (!isTaskScheduleSupported()) {
ALOGW("Task scheduleing is not supported, return empty array");
out->clear();
return ScopedAStatus::ok();
}
ClientContext context;
GetAllScheduledTasksRequest request = {};
GetAllScheduledTasksResponse response = {};
GetAllPendingScheduledTasksRequest request = {};
GetAllPendingScheduledTasksResponse response = {};
request.set_clientid(clientId);
Status status = mGrpcStub->GetAllScheduledTasks(&context, request, &response);
Status status = mGrpcStub->GetAllPendingScheduledTasks(&context, request, &response);
if (!status.ok()) {
return rpcStatusToScopedAStatus(status, "Failed to call isTaskScheduled");
}
@ -406,6 +487,7 @@ ScopedAStatus RemoteAccessService::getAllScheduledTasks(const std::string& clien
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(),
@ -533,9 +615,11 @@ void RemoteAccessService::printCurrentStatus(int fd) {
dprintf(fd,
"\nRemoteAccess HAL status \n"
"Remote task callback registered: %s\n"
"Task receiving GRPC connection established: %s\n"
"GRPC server exist: %s\n"
"GRPC read channel for receiving tasks open: %s\n"
"Received task count by clientId: \n%s\n",
boolToString(mRemoteTaskCallback.get()).c_str(), boolToString(mGrpcConnected).c_str(),
boolToString(mRemoteTaskCallback.get()).c_str(), boolToString(mGrpcServerExist).c_str(),
boolToString(mGrpcReadChannelOpen).c_str(),
clientIdToTaskCountToStringLocked().c_str());
}

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;
@ -93,9 +95,9 @@ class MockGrpcClientStub : public WakeupClient::StubInterface {
MOCK_METHOD(Status, IsTaskScheduled,
(ClientContext * context, const IsTaskScheduledRequest& request,
IsTaskScheduledResponse* response));
MOCK_METHOD(Status, GetAllScheduledTasks,
(ClientContext * context, const GetAllScheduledTasksRequest& request,
GetAllScheduledTasksResponse* response));
MOCK_METHOD(Status, GetAllPendingScheduledTasks,
(ClientContext * context, const GetAllPendingScheduledTasksRequest& request,
GetAllPendingScheduledTasksResponse* response));
// Async methods which we do not care.
MOCK_METHOD(ClientAsyncReaderInterface<GetRemoteTasksResponse>*, AsyncGetRemoteTasksRaw,
(ClientContext * context, const GetRemoteTasksRequest& request, CompletionQueue* cq,
@ -139,13 +141,13 @@ class MockGrpcClientStub : public WakeupClient::StubInterface {
PrepareAsyncIsTaskScheduledRaw,
(ClientContext * context, const IsTaskScheduledRequest& request,
CompletionQueue* cq));
MOCK_METHOD(ClientAsyncResponseReaderInterface<GetAllScheduledTasksResponse>*,
AsyncGetAllScheduledTasksRaw,
(ClientContext * context, const GetAllScheduledTasksRequest& request,
MOCK_METHOD(ClientAsyncResponseReaderInterface<GetAllPendingScheduledTasksResponse>*,
AsyncGetAllPendingScheduledTasksRaw,
(ClientContext * context, const GetAllPendingScheduledTasksRequest& request,
CompletionQueue* cq));
MOCK_METHOD(ClientAsyncResponseReaderInterface<GetAllScheduledTasksResponse>*,
PrepareAsyncGetAllScheduledTasksRaw,
(ClientContext * context, const GetAllScheduledTasksRequest& request,
MOCK_METHOD(ClientAsyncResponseReaderInterface<GetAllPendingScheduledTasksResponse>*,
PrepareAsyncGetAllPendingScheduledTasksRaw,
(ClientContext * context, const GetAllPendingScheduledTasksRequest& request,
CompletionQueue* cq));
};
@ -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)
@ -463,7 +473,71 @@ TEST_F(RemoteAccessServiceUnitTest, TestScheduleTask) {
EXPECT_EQ(grpcRequest.scheduleinfo().periodicinseconds(), kTestPeriodicInSeconds);
}
TEST_F(RemoteAccessServiceUnitTest, TestScheduleTask_InvalidArg) {
TEST_F(RemoteAccessServiceUnitTest, TestScheduleTask_InvalidCount) {
ScheduleInfo scheduleInfo = {
.clientId = kTestClientId,
.scheduleId = kTestScheduleId,
.taskData = kTestData,
.count = -1,
.startTimeInEpochSeconds = kTestStartTimeInEpochSeconds,
.periodicInSeconds = kTestPeriodicInSeconds,
};
ScopedAStatus status = getService()->scheduleTask(scheduleInfo);
ASSERT_FALSE(status.isOk());
ASSERT_EQ(status.getExceptionCode(), EX_ILLEGAL_ARGUMENT);
}
TEST_F(RemoteAccessServiceUnitTest, TestScheduleTask_InvalidStartTimeInEpochSeconds) {
ScheduleInfo scheduleInfo = {
.clientId = kTestClientId,
.scheduleId = kTestScheduleId,
.taskData = kTestData,
.count = kTestCount,
.startTimeInEpochSeconds = -1,
.periodicInSeconds = kTestPeriodicInSeconds,
};
ScopedAStatus status = getService()->scheduleTask(scheduleInfo);
ASSERT_FALSE(status.isOk());
ASSERT_EQ(status.getExceptionCode(), EX_ILLEGAL_ARGUMENT);
}
TEST_F(RemoteAccessServiceUnitTest, TestScheduleTask_InvalidPeriodicInSeconds) {
ScheduleInfo scheduleInfo = {
.clientId = kTestClientId,
.scheduleId = kTestScheduleId,
.taskData = kTestData,
.count = kTestCount,
.startTimeInEpochSeconds = kTestStartTimeInEpochSeconds,
.periodicInSeconds = -1,
};
ScopedAStatus status = getService()->scheduleTask(scheduleInfo);
ASSERT_FALSE(status.isOk());
ASSERT_EQ(status.getExceptionCode(), EX_ILLEGAL_ARGUMENT);
}
TEST_F(RemoteAccessServiceUnitTest, TestScheduleTask_TaskDataTooLarge) {
ScheduleInfo scheduleInfo = {
.clientId = kTestClientId,
.scheduleId = kTestScheduleId,
.taskData = std::vector<uint8_t>(ScheduleInfo::MAX_TASK_DATA_SIZE_IN_BYTES + 1),
.count = kTestCount,
.startTimeInEpochSeconds = kTestStartTimeInEpochSeconds,
.periodicInSeconds = kTestPeriodicInSeconds,
};
ScopedAStatus status = getService()->scheduleTask(scheduleInfo);
ASSERT_FALSE(status.isOk());
ASSERT_EQ(status.getExceptionCode(), EX_ILLEGAL_ARGUMENT);
}
TEST_F(RemoteAccessServiceUnitTest, TestScheduleTask_InvalidArgFromGrpcServer) {
EXPECT_CALL(*getGrpcWakeupClientStub(), ScheduleTask)
.WillOnce([]([[maybe_unused]] ClientContext* context,
[[maybe_unused]] const ScheduleTaskRequest& request,
@ -563,13 +637,13 @@ TEST_F(RemoteAccessServiceUnitTest, TestIsTaskScheduled) {
EXPECT_EQ(grpcRequest.scheduleid(), kTestScheduleId);
}
TEST_F(RemoteAccessServiceUnitTest, testGetAllScheduledTasks) {
TEST_F(RemoteAccessServiceUnitTest, testGetAllPendingScheduledTasks) {
std::vector<ScheduleInfo> result;
GetAllScheduledTasksRequest grpcRequest = {};
EXPECT_CALL(*getGrpcWakeupClientStub(), GetAllScheduledTasks)
GetAllPendingScheduledTasksRequest grpcRequest = {};
EXPECT_CALL(*getGrpcWakeupClientStub(), GetAllPendingScheduledTasks)
.WillOnce([&grpcRequest]([[maybe_unused]] ClientContext* context,
const GetAllScheduledTasksRequest& request,
GetAllScheduledTasksResponse* response) {
const GetAllPendingScheduledTasksRequest& request,
GetAllPendingScheduledTasksResponse* response) {
grpcRequest = request;
GrpcScheduleInfo* newInfo = response->add_allscheduledtasks();
newInfo->set_clientid(kTestClientId);
@ -581,7 +655,7 @@ TEST_F(RemoteAccessServiceUnitTest, testGetAllScheduledTasks) {
return Status();
});
ScopedAStatus status = getService()->getAllScheduledTasks(kTestClientId, &result);
ScopedAStatus status = getService()->getAllPendingScheduledTasks(kTestClientId, &result);
ASSERT_TRUE(status.isOk());
EXPECT_EQ(grpcRequest.clientid(), kTestClientId);

View file

@ -30,6 +30,11 @@ namespace hardware {
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 {
@ -78,6 +83,7 @@ class TaskQueue final {
void waitForTask();
void stopWait();
bool isEmpty();
bool isStopped();
private:
friend class TaskTimeoutMessageHandler;
@ -87,7 +93,7 @@ class TaskQueue final {
GUARDED_BY(mLock);
// A variable to notify mTasks is not empty.
std::condition_variable mTasksNotEmptyCv;
std::atomic<bool> mStopped;
std::atomic<bool> mStopped = false;
android::sp<Looper> mLooper;
android::sp<TaskTimeoutMessageHandler> mTaskTimeoutMessageHandler;
std::atomic<int> mTaskIdCounter = 0;
@ -97,50 +103,57 @@ class TaskQueue final {
};
// 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 GetAllScheduledTasks(grpc::ServerContext* context,
const GetAllScheduledTasksRequest* request,
GetAllScheduledTasksResponse* 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.
@ -176,7 +189,7 @@ class TestWakeupClientServiceImpl : public WakeupClient::Service {
* 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.
@ -184,6 +197,16 @@ class TestWakeupClientServiceImpl : public WakeupClient::Service {
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;
@ -214,9 +237,11 @@ class TestWakeupClientServiceImpl : public WakeupClient::Service {
std::atomic<bool> mRemoteTaskConnectionAlive = false;
std::mutex mLock;
bool mGeneratingFakeTask GUARDED_BY(mLock);
std::atomic<bool> mServerStopped;
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;
@ -231,6 +256,72 @@ class TestWakeupClientServiceImpl : public WakeupClient::Service {
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

View file

@ -38,7 +38,7 @@ using ::grpc::ServerWriter;
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))
@ -105,6 +105,10 @@ void TaskQueue::waitForTask() {
});
}
bool TaskQueue::isStopped() {
return mStopped;
}
void TaskQueue::stopWait() {
mStopped = true;
{
@ -136,21 +140,21 @@ void TaskQueue::handleTaskTimeout() {
}
}
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.
@ -161,7 +165,7 @@ void TestWakeupClientServiceImpl::stopServer() {
}
}
void TestWakeupClientServiceImpl::loop() {
void ServiceImpl::loop() {
Looper::setForThread(mLooper);
while (true) {
@ -172,23 +176,22 @@ void TestWakeupClientServiceImpl::loop() {
}
}
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");
@ -199,7 +202,7 @@ void TestWakeupClientServiceImpl::startGeneratingFakeTask(const std::string& cli
printf("Started generating fake tasks\n");
}
void TestWakeupClientServiceImpl::stopGeneratingFakeTask() {
void ServiceImpl::stopGeneratingFakeTask() {
{
std::lock_guard<std::mutex> lockGuard(mLock);
if (!mGeneratingFakeTask) {
@ -215,7 +218,7 @@ void TestWakeupClientServiceImpl::stopGeneratingFakeTask() {
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) {
@ -233,15 +236,14 @@ void TestWakeupClientServiceImpl::fakeTaskGenerateLoop(const std::string& client
}
}
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) {
mTaskQueue->waitForTask();
if (mServerStopped) {
if (mTaskQueue->isStopped()) {
// Server stopped, exit the loop.
printf("Server stopped exit loop\n");
break;
@ -250,11 +252,13 @@ Status TestWakeupClientServiceImpl::GetRemoteTasks(ServerContext* context,
while (true) {
auto maybeTask = mTaskQueue->maybePopOne();
if (!maybeTask.has_value()) {
printf("no task left\n");
// No task left, loop again and wait for another task(s).
break;
}
// Loop through all the task in the queue but obtain lock for each element so we don't
// hold lock while writing the response.
printf("Sending one remote task\n");
const GetRemoteTasksResponse& response = maybeTask.value();
if (!writer->Write(response)) {
// Broken stream, maybe the client is shutting down.
@ -271,15 +275,15 @@ Status TestWakeupClientServiceImpl::GetRemoteTasks(ServerContext* context,
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) {
@ -290,23 +294,22 @@ Status TestWakeupClientServiceImpl::NotifyWakeupRequired(ServerContext* context,
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();
@ -353,8 +356,7 @@ Status TestWakeupClientServiceImpl::ScheduleTask(ServerContext* context,
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) {
@ -366,7 +368,7 @@ bool TestWakeupClientServiceImpl::getScheduleInfoLocked(int scheduleMsgId,
return false;
}
void TestWakeupClientServiceImpl::handleAddTask(int scheduleMsgId) {
void ServiceImpl::handleAddTask(int scheduleMsgId) {
std::lock_guard<std::mutex> lockGuard(mLock);
ScheduleInfo* scheduleInfoPtr;
@ -379,15 +381,27 @@ void TestWakeupClientServiceImpl::handleAddTask(int scheduleMsgId) {
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) {
@ -401,9 +415,8 @@ void TestWakeupClientServiceImpl::handleAddTask(int scheduleMsgId) {
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();
@ -425,9 +438,9 @@ Status TestWakeupClientServiceImpl::UnscheduleTask(ServerContext* context,
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();
@ -446,9 +459,8 @@ Status TestWakeupClientServiceImpl::UnscheduleAllTasks(ServerContext* context,
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();
@ -469,11 +481,11 @@ Status TestWakeupClientServiceImpl::IsTaskScheduled(ServerContext* context,
return Status::OK;
}
Status TestWakeupClientServiceImpl::GetAllScheduledTasks(ServerContext* context,
const GetAllScheduledTasksRequest* request,
GetAllScheduledTasksResponse* response) {
Status ServiceImpl::GetAllPendingScheduledTasks(ServerContext* context,
const GetAllPendingScheduledTasksRequest* request,
GetAllPendingScheduledTasksResponse* response) {
const std::string& clientId = request->clientid();
printf("GetAllScheduledTasks called with client Id: %s\n", clientId.c_str());
printf("GetAllPendingScheduledTasks called with client Id: %s\n", clientId.c_str());
response->clear_allscheduledtasks();
{
std::unique_lock lk(mLock);
@ -487,14 +499,35 @@ Status TestWakeupClientServiceImpl::GetAllScheduledTasks(ServerContext* context,
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

View file

@ -33,26 +33,40 @@
#include <grpcpp/server.h>
#include <grpcpp/server_builder.h>
using ::android::hardware::automotive::remoteaccess::TestWakeupClientServiceImpl;
namespace {
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;
constexpr int SHUTDOWN_REQUEST = 289410889;
constexpr int VEHICLE_IN_USE = 287313738;
const char* COMMAND_RUN_EMU = "source ~/.aae-toolbox/bin/bashrc && aae emulator run";
const char* COMMAND_SET_VHAL_PROP =
constexpr char COMMAND_RUN_EMU_LOCAL_IMAGE[] =
"source ~/.aae-toolbox/bin/bashrc && aae emulator run";
constexpr char COMMAND_RUN_EMU[] = "./launch_emu.sh -v \"-writable-system -selinux permissive\"";
constexpr char COMMAND_SET_VHAL_PROP[] =
"adb -s emulator-5554 wait-for-device && adb -s emulator-5554 root "
"&& sleep 1 && adb -s emulator-5554 wait-for-device && adb -s emulator-5554 shell "
"dumpsys android.hardware.automotive.vehicle.IVehicle/default --set %d -i %d";
pid_t emuPid = 0;
const char* runEmuCommand = COMMAND_RUN_EMU;
void RunServer(const std::string& serviceAddr,
std::shared_ptr<TestWakeupClientServiceImpl> service) {
} // namespace
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 +95,21 @@ void updateEmuStatus() {
}
}
bool powerOnEmu() {
bool powerOnEmu(ServiceImpl* service, int32_t bootupReason) {
updateEmuStatus();
if (emuPid != 0) {
printf("The emulator is already running\n");
return false;
}
emuPid = runCommand(COMMAND_RUN_EMU);
service->setBootupReason(bootupReason);
emuPid = runCommand(runEmuCommand);
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 +148,6 @@ void powerOff() {
#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 +171,7 @@ void help() {
<< "(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 +198,10 @@ void parseCommand(const std::string& userInput,
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 +227,7 @@ void parseCommand(const std::string& userInput,
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,28 +243,30 @@ void saHandler(int signum) {
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
};
};
// Usage: TestWakeupClientServerHost [--local-image] [service_address_to_start]
int main(int argc, char** argv) {
std::string serviceAddr = GRPC_SERVICE_ADDRESS;
if (argc > 1) {
serviceAddr = argv[1];
for (int i = 1; i < argc; i++) {
char* arg = argv[1];
if (strcmp(arg, "--local-image") == 0) {
runEmuCommand = COMMAND_RUN_EMU_LOCAL_IMAGE;
continue;
}
serviceAddr = arg;
}
// 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

View file

@ -43,9 +43,9 @@ constexpr int64_t kTestStartTimeInEpochSeconds = 2345;
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 @@ class TestWakeupClientServiceImplUnitTest : public ::testing::Test {
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 @@ class TestWakeupClientServiceImplUnitTest : public ::testing::Test {
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 @@ TEST_F(TestWakeupClientServiceImplUnitTest, TestScheduleTask) {
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 @@ TEST_F(TestWakeupClientServiceImplUnitTest, TestScheduleTask_conflictScheduleId)
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);
@ -280,7 +284,7 @@ TEST_F(TestWakeupClientServiceImplUnitTest, TestUnscheduleAllTasks) {
EXPECT_EQ(getRemoteTaskResponses().size(), 0);
}
TEST_F(TestWakeupClientServiceImplUnitTest, TestGetAllScheduledTasks) {
TEST_F(TestWakeupClientServiceImplUnitTest, TestGetAllPendingScheduledTasks) {
std::string scheduleId1 = "scheduleId1";
std::string scheduleId2 = "scheduleId2";
int64_t time1 = getNow();
@ -296,25 +300,26 @@ TEST_F(TestWakeupClientServiceImplUnitTest, TestGetAllScheduledTasks) {
ASSERT_TRUE(status.ok());
ClientContext context;
GetAllScheduledTasksRequest request;
GetAllScheduledTasksResponse response;
GetAllPendingScheduledTasksRequest request;
GetAllPendingScheduledTasksResponse response;
request.set_clientid("invalid client Id");
status = getStub()->GetAllScheduledTasks(&context, request, &response);
status = getStub()->GetAllPendingScheduledTasks(&context, request, &response);
ASSERT_TRUE(status.ok());
EXPECT_EQ(response.allscheduledtasks_size(), 0);
ClientContext context2;
GetAllScheduledTasksRequest request2;
GetAllScheduledTasksResponse response2;
GetAllPendingScheduledTasksRequest request2;
GetAllPendingScheduledTasksResponse response2;
request2.set_clientid(kTestClientId);
status = getStub()->GetAllScheduledTasks(&context2, request2, &response2);
status = getStub()->GetAllPendingScheduledTasks(&context2, request2, &response2);
ASSERT_TRUE(status.ok());
ASSERT_EQ(response2.allscheduledtasks_size(), 2);
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 @@ TEST_F(TestWakeupClientServiceImplUnitTest, TestGetAllScheduledTasks) {
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);

View file

@ -0,0 +1,50 @@
/*
* 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 {
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
// to get the below license kinds:
// SPDX-license-identifier-Apache-2.0
default_applicable_licenses: ["hardware_interfaces_license"],
}
cc_test {
name: "VtsHalAutomotiveRemoteAccess_TargetTest",
srcs: [
"src/*.cpp",
],
static_libs: [
"android.hardware.automotive.remoteaccess-V2-ndk",
"libgtest",
"libgmock",
],
shared_libs: [
"libbinder_ndk",
],
test_suites: [
"general-tests",
"vts",
"automotive-tests",
"automotive-general-tests",
],
defaults: [
"use_libaidlvintf_gtest_helper_static",
],
require_root: true,
disable_framework: true,
}

View file

@ -0,0 +1,453 @@
/*
* 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.
*/
#define LOG_TAG "VtsHalAutomotiveRemoteAccess"
#include <aidl/Gtest.h>
#include <aidl/Vintf.h>
#include <aidl/android/hardware/automotive/remoteaccess/ApState.h>
#include <aidl/android/hardware/automotive/remoteaccess/BnRemoteTaskCallback.h>
#include <aidl/android/hardware/automotive/remoteaccess/IRemoteAccess.h>
#include <aidl/android/hardware/automotive/remoteaccess/ScheduleInfo.h>
#include <aidl/android/hardware/automotive/remoteaccess/TaskType.h>
#include <android-base/thread_annotations.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <algorithm>
#include <chrono>
#include <string>
#include <thread>
#include <vector>
using ::aidl::android::hardware::automotive::remoteaccess::ApState;
using ::aidl::android::hardware::automotive::remoteaccess::BnRemoteTaskCallback;
using ::aidl::android::hardware::automotive::remoteaccess::IRemoteAccess;
using ::aidl::android::hardware::automotive::remoteaccess::ScheduleInfo;
using ::aidl::android::hardware::automotive::remoteaccess::TaskType;
using ::android::getAidlHalInstanceNames;
using ::android::PrintInstanceNameToString;
using ::android::base::ScopedLockAssertion;
using ::ndk::ScopedAStatus;
using ::ndk::SharedRefBase;
using ::ndk::SpAIBinder;
using ::testing::UnorderedElementsAre;
namespace {
const std::string TEST_CLIENT_ID = "TEST CLIENT ID";
const std::string TEST_SCHEDULE_ID = "TEST SCHEDULE ID";
const std::string TEST_SCHEDULE_ID_1 = "TEST SCHEDULE ID 1";
const std::string TEST_SCHEDULE_ID_2 = "TEST SCHEDULE ID 2";
const std::vector<uint8_t> TEST_TASK_DATA =
std::vector<uint8_t>({static_cast<uint8_t>(0xde), static_cast<uint8_t>(0xad),
static_cast<uint8_t>(0xbe), static_cast<uint8_t>(0xef)});
const int32_t JOB_DELAY_IN_SECONDS = 5;
} // namespace
class VtsHalAutomotiveRemoteAccessTargetTest : public testing::TestWithParam<std::string> {
public:
virtual void SetUp() override {
const std::string& name = GetParam();
mHal = IRemoteAccess::fromBinder(SpAIBinder(AServiceManager_waitForService(name.c_str())));
ASSERT_NE(mHal, nullptr) << "Failed to connect to remote access HAL: " << name;
}
virtual void TearDown() override {
if (mHal != nullptr) {
mHal->clearRemoteTaskCallback();
mHal->unscheduleAllTasks(TEST_CLIENT_ID);
}
}
protected:
std::shared_ptr<IRemoteAccess> mHal;
bool isTaskScheduleSupported();
int32_t getInterfaceVersion();
ScheduleInfo getTestScheduleInfo(int32_t delayInSeconds, int32_t count,
int32_t periodicInSeconds);
void setTaskCallbackAndReadyForTask(std::shared_ptr<BnRemoteTaskCallback> testCallback);
};
class TestRemoteTaskCallback final : public BnRemoteTaskCallback {
public:
ScopedAStatus onRemoteTaskRequested(const std::string& clientId,
const std::vector<uint8_t>& data) override {
{
std::unique_lock<std::mutex> lockGuard(mLock);
mClientIds.push_back(clientId);
mDataList.push_back(data);
}
mCv.notify_one();
return ScopedAStatus::ok();
}
const std::vector<std::string> getCalledClientIds() {
std::lock_guard<std::mutex> lockGuard(mLock);
return mClientIds;
}
const std::vector<std::vector<uint8_t>> getCalledDataList() {
std::lock_guard<std::mutex> lockGuard(mLock);
return mDataList;
}
bool waitForCallbacks(size_t count, int32_t timeoutInSeconds) {
std::unique_lock lk(mLock);
return mCv.wait_for(lk, std::chrono::seconds(timeoutInSeconds), [this, count] {
ScopedLockAssertion lockAssertion(mLock);
return mClientIds.size() >= count;
});
}
private:
std::mutex mLock;
std::vector<std::string> mClientIds GUARDED_BY(mLock);
std::vector<std::vector<uint8_t>> mDataList GUARDED_BY(mLock);
std::condition_variable mCv;
};
TEST_P(VtsHalAutomotiveRemoteAccessTargetTest, testGetVehicleId) {
std::string vehicleId;
ScopedAStatus status = mHal->getVehicleId(&vehicleId);
ASSERT_TRUE(status.isOk()) << "Failed to call getVehicleId";
ASSERT_FALSE(vehicleId.empty()) << "Vehicle ID must not be empty";
}
TEST_P(VtsHalAutomotiveRemoteAccessTargetTest, testGetWakeupServiceName) {
std::string wakeupServiceName;
ScopedAStatus status = mHal->getWakeupServiceName(&wakeupServiceName);
ASSERT_TRUE(status.isOk()) << "Failed to call getWakeupServiceName";
ASSERT_FALSE(wakeupServiceName.empty()) << "Wakeup service name must not be empty";
}
TEST_P(VtsHalAutomotiveRemoteAccessTargetTest, testGetProcessorId) {
std::string processorId;
ScopedAStatus status = mHal->getProcessorId(&processorId);
ASSERT_TRUE(status.isOk()) << "Failed to call getProcessorId";
}
TEST_P(VtsHalAutomotiveRemoteAccessTargetTest, testSetClearRemoteTaskCallback) {
std::shared_ptr<TestRemoteTaskCallback> testCallback =
SharedRefBase::make<TestRemoteTaskCallback>();
ScopedAStatus status = mHal->setRemoteTaskCallback(testCallback);
ASSERT_TRUE(status.isOk()) << "Failed to call setRemoteTaskCallback";
status = mHal->clearRemoteTaskCallback();
ASSERT_TRUE(status.isOk()) << "Failed to call clearRemoteTaskCallback";
}
TEST_P(VtsHalAutomotiveRemoteAccessTargetTest, testNotifyApStateChange) {
ApState apState = ApState{
.isReadyForRemoteTask = false,
.isWakeupRequired = false,
};
ScopedAStatus status = mHal->notifyApStateChange(apState);
ASSERT_TRUE(status.isOk()) << "Failed to call notifyApStateChange with state: "
<< apState.toString();
apState = ApState{
.isReadyForRemoteTask = true,
.isWakeupRequired = false,
};
ASSERT_TRUE(status.isOk()) << "Failed to call notifyApStateChange with state: "
<< apState.toString();
}
int32_t VtsHalAutomotiveRemoteAccessTargetTest::getInterfaceVersion() {
int32_t interfaceVersion = 0;
mHal->getInterfaceVersion(&interfaceVersion);
return interfaceVersion;
}
TEST_P(VtsHalAutomotiveRemoteAccessTargetTest, testIsTaskScheduleSupported) {
if (getInterfaceVersion() < 2) {
GTEST_SKIP() << "Require RemoteAccess HAL v2";
}
bool supported;
ScopedAStatus status = mHal->isTaskScheduleSupported(&supported);
ASSERT_TRUE(status.isOk()) << "Failed to call isTaskScheduleSupported";
}
bool VtsHalAutomotiveRemoteAccessTargetTest::isTaskScheduleSupported() {
bool supported = false;
mHal->isTaskScheduleSupported(&supported);
return supported;
}
TEST_P(VtsHalAutomotiveRemoteAccessTargetTest, testGetSupportedTaskTypesForScheduling) {
if (getInterfaceVersion() < 2) {
GTEST_SKIP() << "Require RemoteAccess HAL v2";
}
std::vector<TaskType> supportedTaskTypes;
ScopedAStatus status = mHal->getSupportedTaskTypesForScheduling(&supportedTaskTypes);
ASSERT_TRUE(status.isOk()) << "Failed to call getSupportedTaskTypesForScheduling";
if (!isTaskScheduleSupported()) {
ASSERT_TRUE(supportedTaskTypes.empty())
<< "getSupportedTaskTypesForScheduling must return empty array "
<< "if isTaskScheduleSupported is false";
return;
}
ASSERT_TRUE(std::find(supportedTaskTypes.begin(), supportedTaskTypes.end(), TaskType::CUSTOM) !=
supportedTaskTypes.end())
<< "getSupportedTaskTypesForScheduling must contain TaskType::CUSTOM";
}
ScheduleInfo VtsHalAutomotiveRemoteAccessTargetTest::getTestScheduleInfo(
int32_t delayInSeconds, int32_t count, int32_t periodicInSeconds) {
auto nowInEpochSeconds = std::chrono::duration_cast<std::chrono::seconds>(
std::chrono::system_clock::now().time_since_epoch())
.count();
return ScheduleInfo{
.clientId = TEST_CLIENT_ID,
.scheduleId = TEST_SCHEDULE_ID,
.taskType = TaskType::CUSTOM,
.taskData = TEST_TASK_DATA,
.count = count,
.startTimeInEpochSeconds = nowInEpochSeconds + delayInSeconds,
.periodicInSeconds = periodicInSeconds,
};
}
void VtsHalAutomotiveRemoteAccessTargetTest::setTaskCallbackAndReadyForTask(
std::shared_ptr<BnRemoteTaskCallback> testCallback) {
mHal->setRemoteTaskCallback(testCallback);
// Notify isReadForRemoteTask to be true.
mHal->notifyApStateChange(ApState{
.isReadyForRemoteTask = true,
.isWakeupRequired = false,
});
}
TEST_P(VtsHalAutomotiveRemoteAccessTargetTest, testScheduleTask) {
if (getInterfaceVersion() < 2) {
GTEST_SKIP() << "Require RemoteAccess HAL v2";
}
std::shared_ptr<TestRemoteTaskCallback> testCallback =
SharedRefBase::make<TestRemoteTaskCallback>();
setTaskCallbackAndReadyForTask(testCallback);
int32_t count = 2;
ScheduleInfo scheduleInfo = getTestScheduleInfo(
/*delayInSeconds=*/JOB_DELAY_IN_SECONDS, count, /*periodicInSeconds=*/1);
ScopedAStatus status = mHal->scheduleTask(scheduleInfo);
if (!isTaskScheduleSupported()) {
ASSERT_FALSE(status.isOk()) << "scheduleTask must return EX_ILLEGAL_ARGUMENT "
<< "if isTaskScheduleSupported is false";
ASSERT_EQ(status.getExceptionCode(), EX_ILLEGAL_ARGUMENT)
<< "scheduleTask must return EX_ILLEGAL_ARGUMENT "
<< "if isTaskScheduleSupported is false";
return;
}
ASSERT_TRUE(status.isOk()) << "Failed to call scheduleTask with scheduleInfo: "
<< scheduleInfo.toString();
int32_t timeoutInSeconds = JOB_DELAY_IN_SECONDS + 5;
bool gotCallbacks = testCallback->waitForCallbacks(count, timeoutInSeconds);
// unschedule the task before checking the result.
mHal->unscheduleTask(TEST_CLIENT_ID, TEST_SCHEDULE_ID);
ASSERT_TRUE(gotCallbacks) << "Callbacks is not called enough times before timeout: "
<< timeoutInSeconds << "s";
std::vector<std::vector<uint8_t>> dataList = testCallback->getCalledDataList();
std::vector<std::string> clientIds = testCallback->getCalledClientIds();
for (size_t i = 0; i < dataList.size(); i++) {
EXPECT_EQ(dataList[i], TEST_TASK_DATA) << "Must receive expected task data";
EXPECT_EQ(clientIds[i], TEST_CLIENT_ID) << "Must receive expected client id";
}
}
TEST_P(VtsHalAutomotiveRemoteAccessTargetTest, testUnscheduleTask) {
if (getInterfaceVersion() < 2) {
GTEST_SKIP() << "Require RemoteAccess HAL v2";
}
std::shared_ptr<TestRemoteTaskCallback> testCallback =
SharedRefBase::make<TestRemoteTaskCallback>();
setTaskCallbackAndReadyForTask(testCallback);
ScheduleInfo scheduleInfo = getTestScheduleInfo(
/*delayInSeconds=*/JOB_DELAY_IN_SECONDS, /*count=*/1, /*periodicInSeconds=*/0);
mHal->scheduleTask(scheduleInfo);
ScopedAStatus status = mHal->unscheduleTask(TEST_CLIENT_ID, TEST_SCHEDULE_ID);
ASSERT_TRUE(status.isOk()) << "Failed to call unscheduleTask";
// If not cancelled, should be called in 5s, wait for 6s and make sure no task arrives.
std::this_thread::sleep_for(std::chrono::seconds(JOB_DELAY_IN_SECONDS + 1));
ASSERT_TRUE(testCallback->getCalledClientIds().empty())
<< "Remote task callback must not be called if the task is cancelled";
}
TEST_P(VtsHalAutomotiveRemoteAccessTargetTest, testUnscheduleAllTasks) {
if (getInterfaceVersion() < 2) {
GTEST_SKIP() << "Require RemoteAccess HAL v2";
}
std::shared_ptr<TestRemoteTaskCallback> testCallback =
SharedRefBase::make<TestRemoteTaskCallback>();
setTaskCallbackAndReadyForTask(testCallback);
ScheduleInfo scheduleInfo = getTestScheduleInfo(
/*delayInSeconds=*/JOB_DELAY_IN_SECONDS, /*count=*/1, /*periodicInSeconds=*/0);
mHal->scheduleTask(scheduleInfo);
ScopedAStatus status = mHal->unscheduleAllTasks(TEST_CLIENT_ID);
ASSERT_TRUE(status.isOk()) << "Failed to call unscheduleAllTasks";
// If not cancelled, should be called in 5s, wait for 6s and make sure no task arrives.
std::this_thread::sleep_for(std::chrono::seconds(JOB_DELAY_IN_SECONDS + 1));
ASSERT_TRUE(testCallback->getCalledClientIds().empty())
<< "Remote task callback must not be called if the task is cancelled";
}
TEST_P(VtsHalAutomotiveRemoteAccessTargetTest, testIsTaskScheduled) {
if (getInterfaceVersion() < 2) {
GTEST_SKIP() << "Require RemoteAccess HAL v2";
}
std::shared_ptr<TestRemoteTaskCallback> testCallback =
SharedRefBase::make<TestRemoteTaskCallback>();
setTaskCallbackAndReadyForTask(testCallback);
ScheduleInfo scheduleInfo = getTestScheduleInfo(
/*delayInSeconds=*/JOB_DELAY_IN_SECONDS, /*count=*/1, /*periodicInSeconds=*/0);
mHal->scheduleTask(scheduleInfo);
bool scheduled;
ScopedAStatus status = mHal->isTaskScheduled(TEST_CLIENT_ID, TEST_SCHEDULE_ID, &scheduled);
ASSERT_TRUE(status.isOk()) << "Failed to call unscheduleTask";
if (!isTaskScheduleSupported()) {
ASSERT_FALSE(scheduled) << "isTaskScheduled must return false "
<< "if isTaskScheduleSupported is false";
return;
}
ASSERT_TRUE(scheduled) << "isTaskScheduled must return true if the task is scheduled";
mHal->unscheduleAllTasks(TEST_CLIENT_ID);
status = mHal->isTaskScheduled(TEST_CLIENT_ID, TEST_SCHEDULE_ID, &scheduled);
ASSERT_TRUE(status.isOk()) << "Failed to call unscheduleTask";
ASSERT_FALSE(scheduled) << "isTaskScheduled must return false if the task is not scheduled";
}
TEST_P(VtsHalAutomotiveRemoteAccessTargetTest, testGetAllPendingScheduledTasks) {
if (getInterfaceVersion() < 2) {
GTEST_SKIP() << "Require RemoteAccess HAL v2";
}
std::shared_ptr<TestRemoteTaskCallback> testCallback =
SharedRefBase::make<TestRemoteTaskCallback>();
setTaskCallbackAndReadyForTask(testCallback);
auto nowInEpochSeconds = std::chrono::duration_cast<std::chrono::seconds>(
std::chrono::system_clock::now().time_since_epoch())
.count();
ScheduleInfo scheduleInfo1 = ScheduleInfo{
.clientId = TEST_CLIENT_ID,
.scheduleId = TEST_SCHEDULE_ID_1,
.taskType = TaskType::CUSTOM,
.taskData = TEST_TASK_DATA,
.count = 1,
.startTimeInEpochSeconds = nowInEpochSeconds + 5,
.periodicInSeconds = 0,
};
ScheduleInfo scheduleInfo2 = ScheduleInfo{
.clientId = TEST_CLIENT_ID,
.scheduleId = TEST_SCHEDULE_ID_2,
.taskType = TaskType::CUSTOM,
.taskData = TEST_TASK_DATA,
.count = 10,
.startTimeInEpochSeconds = nowInEpochSeconds + 10,
.periodicInSeconds = 1,
};
mHal->scheduleTask(scheduleInfo1);
mHal->scheduleTask(scheduleInfo2);
std::vector<ScheduleInfo> outScheduleInfo;
ScopedAStatus status = mHal->getAllPendingScheduledTasks(TEST_CLIENT_ID, &outScheduleInfo);
ASSERT_TRUE(status.isOk()) << "Failed to call getAllPendingScheduledTasks";
if (!isTaskScheduleSupported()) {
ASSERT_TRUE(outScheduleInfo.empty())
<< "Must return empty array for getAllPendingScheduledTasks "
<< "if isTaskScheduleSupported is false";
return;
}
ASSERT_THAT(outScheduleInfo, UnorderedElementsAre(scheduleInfo1, scheduleInfo2))
<< "expected all pending schedule info mismatch";
mHal->unscheduleTask(TEST_CLIENT_ID, TEST_SCHEDULE_ID_1);
status = mHal->getAllPendingScheduledTasks(TEST_CLIENT_ID, &outScheduleInfo);
ASSERT_TRUE(status.isOk()) << "Failed to call getAllPendingScheduledTasks";
ASSERT_THAT(outScheduleInfo, UnorderedElementsAre(scheduleInfo2))
<< "expected all pending schedule info mismatch";
}
// It is possible that no remote access HAL is registered.
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(VtsHalAutomotiveRemoteAccessTargetTest);
INSTANTIATE_TEST_SUITE_P(PerInstance, VtsHalAutomotiveRemoteAccessTargetTest,
testing::ValuesIn(getAidlHalInstanceNames(IRemoteAccess::descriptor)),
PrintInstanceNameToString);
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
// Starts a process pool for callbacks.
ABinderProcess_setThreadPoolMaxThreadCount(1);
ABinderProcess_startThreadPool();
return RUN_ALL_TESTS();
}

View file

@ -494,7 +494,11 @@ void DefaultVehicleHal::onContinuousPropertyTimer(const std::vector<int32_t>& pr
}
for (int areaId : areaIds) {
auto v = pool.obtain(*mPropStore->refreshTimestamp(property, areaId));
auto refreshedProp = mPropStore->refreshTimestamp(property, areaId);
VehiclePropValuePtr v = nullptr;
if (refreshedProp != nullptr) {
v = pool.obtain(*refreshedProp);
}
if (v.get()) {
events.push_back(std::move(v));
}

View file

@ -25,3 +25,11 @@ cc_defaults {
"android.hardware.automotive.vehicle.property-V3-ndk",
],
}
rust_defaults {
name: "VehicleHalInterfaceRustDefaults",
rustlibs: [
"android.hardware.automotive.vehicle-V3-rust",
"android.hardware.automotive.vehicle.property-V3-rust",
],
}

View file

@ -24,9 +24,6 @@
{
"name": "VehiclePropertyAnnotationJavaTest"
},
{
"name": "FakeVehicleHardwareTest"
},
{
"name": "FakeVehicleHalValueGeneratorsTest"
},
@ -44,6 +41,9 @@
{
"name": "VtsHalAutomotiveVehicle_TargetTest"
},
{
"name": "FakeVehicleHardwareTest"
},
{
"name": "CarServiceUnitTest",
"options" : [

View file

@ -27,7 +27,7 @@ aidl_interface {
srcs: [
"android/hardware/automotive/vehicle/*.aidl",
],
frozen: false,
frozen: true,
stability: "vintf",
backend: {
cpp: {
@ -54,6 +54,10 @@ aidl_interface {
version: "2",
imports: [],
},
{
version: "3",
imports: [],
},
],
host_supported: true,

View file

@ -0,0 +1,2 @@
c6f1cc74f83dc53c6a5c08e6dbbb6e25e83e3a6b
c046ced69d333e4470cd211e2159cce84faae233

View file

@ -0,0 +1,39 @@
/*
* Copyright (C) 2021 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.vehicle;
@JavaDerive(equals=true, toString=true) @RustDerive(Clone=true) @VintfStability
parcelable GetValueRequest {
long requestId;
android.hardware.automotive.vehicle.VehiclePropValue prop;
}

View file

@ -0,0 +1,39 @@
/*
* Copyright (C) 2021 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.vehicle;
@JavaDerive(equals=true, toString=true) @VintfStability
parcelable GetValueRequests {
android.hardware.automotive.vehicle.GetValueRequest[] payloads;
@nullable ParcelFileDescriptor sharedMemoryFd;
}

View file

@ -0,0 +1,40 @@
/*
* Copyright (C) 2021 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.vehicle;
@JavaDerive(equals=true, toString=true) @RustDerive(Clone=true) @VintfStability
parcelable GetValueResult {
long requestId;
android.hardware.automotive.vehicle.StatusCode status = android.hardware.automotive.vehicle.StatusCode.OK;
@nullable android.hardware.automotive.vehicle.VehiclePropValue prop;
}

View file

@ -0,0 +1,39 @@
/*
* Copyright (C) 2021 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.vehicle;
@JavaDerive(equals=true, toString=true) @VintfStability
parcelable GetValueResults {
android.hardware.automotive.vehicle.GetValueResult[] payloads;
@nullable ParcelFileDescriptor sharedMemoryFd;
}

View file

@ -0,0 +1,46 @@
/*
* Copyright (C) 2021 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.vehicle;
@VintfStability
interface IVehicle {
android.hardware.automotive.vehicle.VehiclePropConfigs getAllPropConfigs();
android.hardware.automotive.vehicle.VehiclePropConfigs getPropConfigs(in int[] props);
void getValues(android.hardware.automotive.vehicle.IVehicleCallback callback, in android.hardware.automotive.vehicle.GetValueRequests requests);
void setValues(android.hardware.automotive.vehicle.IVehicleCallback callback, in android.hardware.automotive.vehicle.SetValueRequests requests);
void subscribe(in android.hardware.automotive.vehicle.IVehicleCallback callback, in android.hardware.automotive.vehicle.SubscribeOptions[] options, int maxSharedMemoryFileCount);
void unsubscribe(in android.hardware.automotive.vehicle.IVehicleCallback callback, in int[] propIds);
void returnSharedMemory(in android.hardware.automotive.vehicle.IVehicleCallback callback, long sharedMemoryId);
const long INVALID_MEMORY_ID = 0;
const int MAX_SHARED_MEMORY_FILES_PER_CLIENT = 3;
}

View file

@ -0,0 +1,41 @@
/*
* Copyright (C) 2021 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.vehicle;
@VintfStability
interface IVehicleCallback {
oneway void onGetValues(in android.hardware.automotive.vehicle.GetValueResults responses);
oneway void onSetValues(in android.hardware.automotive.vehicle.SetValueResults responses);
oneway void onPropertyEvent(in android.hardware.automotive.vehicle.VehiclePropValues propValues, int sharedMemoryFileCount);
oneway void onPropertySetError(in android.hardware.automotive.vehicle.VehiclePropErrors errors);
}

View file

@ -0,0 +1,42 @@
/*
* Copyright (C) 2021 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.vehicle;
@JavaDerive(equals=true, toString=true) @RustDerive(Clone=true) @VintfStability
parcelable RawPropValues {
int[] int32Values = {};
float[] floatValues;
long[] int64Values;
byte[] byteValues;
@utf8InCpp String stringValue;
}

View file

@ -0,0 +1,39 @@
/*
* Copyright (C) 2021 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.vehicle;
@JavaDerive(equals=true, toString=true) @RustDerive(Clone=true) @VintfStability
parcelable SetValueRequest {
long requestId;
android.hardware.automotive.vehicle.VehiclePropValue value;
}

View file

@ -0,0 +1,39 @@
/*
* Copyright (C) 2021 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.vehicle;
@JavaDerive(equals=true, toString=true) @VintfStability
parcelable SetValueRequests {
android.hardware.automotive.vehicle.SetValueRequest[] payloads;
@nullable ParcelFileDescriptor sharedMemoryFd;
}

View file

@ -0,0 +1,39 @@
/*
* Copyright (C) 2021 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.vehicle;
@JavaDerive(equals=true, toString=true) @RustDerive(Clone=true) @VintfStability
parcelable SetValueResult {
long requestId;
android.hardware.automotive.vehicle.StatusCode status = android.hardware.automotive.vehicle.StatusCode.OK;
}

View file

@ -0,0 +1,39 @@
/*
* Copyright (C) 2021 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.vehicle;
@JavaDerive(equals=true, toString=true) @VintfStability
parcelable SetValueResults {
android.hardware.automotive.vehicle.SetValueResult[] payloads;
@nullable ParcelFileDescriptor sharedMemoryFd;
}

View file

@ -0,0 +1,48 @@
/*
* Copyright (C) 2021 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.vehicle;
@Backing(type="int") @VintfStability
enum StatusCode {
OK = 0,
TRY_AGAIN = 1,
INVALID_ARG = 2,
NOT_AVAILABLE = 3,
ACCESS_DENIED = 4,
INTERNAL_ERROR = 5,
NOT_AVAILABLE_DISABLED = 6,
NOT_AVAILABLE_SPEED_LOW = 7,
NOT_AVAILABLE_SPEED_HIGH = 8,
NOT_AVAILABLE_POOR_VISIBILITY = 9,
NOT_AVAILABLE_SAFETY = 10,
}

View file

@ -0,0 +1,42 @@
/*
* Copyright (C) 2021 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.vehicle;
@JavaDerive(equals=true, toString=true) @RustDerive(Clone=true) @VintfStability
parcelable SubscribeOptions {
int propId;
int[] areaIds;
float sampleRate;
float resolution = 0.0f;
boolean enableVariableUpdateRate;
}

View file

@ -0,0 +1,47 @@
/*
* Copyright (C) 2021 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.vehicle;
@JavaDerive(equals=true, toString=true) @RustDerive(Clone=true) @VintfStability
parcelable VehicleAreaConfig {
int areaId;
int minInt32Value;
int maxInt32Value;
long minInt64Value;
long maxInt64Value;
float minFloatValue;
float maxFloatValue;
@nullable long[] supportedEnumValues;
android.hardware.automotive.vehicle.VehiclePropertyAccess access = android.hardware.automotive.vehicle.VehiclePropertyAccess.NONE;
boolean supportVariableUpdateRate;
}

View file

@ -0,0 +1,45 @@
/*
* Copyright (C) 2021 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.vehicle;
@JavaDerive(equals=true, toString=true) @RustDerive(Clone=true) @VintfStability
parcelable VehiclePropConfig {
int prop;
android.hardware.automotive.vehicle.VehiclePropertyAccess access = android.hardware.automotive.vehicle.VehiclePropertyAccess.NONE;
android.hardware.automotive.vehicle.VehiclePropertyChangeMode changeMode = android.hardware.automotive.vehicle.VehiclePropertyChangeMode.STATIC;
android.hardware.automotive.vehicle.VehicleAreaConfig[] areaConfigs;
int[] configArray;
@utf8InCpp String configString;
float minSampleRate;
float maxSampleRate;
}

View file

@ -0,0 +1,39 @@
/*
* Copyright (C) 2021 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.vehicle;
@JavaDerive(equals=true, toString=true) @VintfStability
parcelable VehiclePropConfigs {
android.hardware.automotive.vehicle.VehiclePropConfig[] payloads;
@nullable ParcelFileDescriptor sharedMemoryFd;
}

View file

@ -0,0 +1,40 @@
/*
* Copyright (C) 2021 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.vehicle;
@JavaDerive(equals=true, toString=true) @RustDerive(Clone=true) @VintfStability
parcelable VehiclePropError {
int propId;
int areaId;
android.hardware.automotive.vehicle.StatusCode errorCode = android.hardware.automotive.vehicle.StatusCode.OK;
}

View file

@ -0,0 +1,39 @@
/*
* Copyright (C) 2021 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.vehicle;
@JavaDerive(equals=true, toString=true) @VintfStability
parcelable VehiclePropErrors {
android.hardware.automotive.vehicle.VehiclePropError[] payloads;
@nullable ParcelFileDescriptor sharedMemoryFd;
}

View file

@ -0,0 +1,42 @@
/*
* Copyright (C) 2021 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.vehicle;
@JavaDerive(equals=true, toString=true) @RustDerive(Clone=true) @VintfStability
parcelable VehiclePropValue {
long timestamp;
int areaId;
int prop;
android.hardware.automotive.vehicle.VehiclePropertyStatus status = android.hardware.automotive.vehicle.VehiclePropertyStatus.AVAILABLE;
android.hardware.automotive.vehicle.RawPropValues value;
}

View file

@ -0,0 +1,40 @@
/*
* Copyright (C) 2021 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.vehicle;
@JavaDerive(equals=true, toString=true) @VintfStability
parcelable VehiclePropValues {
android.hardware.automotive.vehicle.VehiclePropValue[] payloads;
long sharedMemoryId;
@nullable ParcelFileDescriptor sharedMemoryFd;
}

View file

@ -0,0 +1,41 @@
/*
* Copyright (C) 2021 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.vehicle;
@Backing(type="int") @VintfStability
enum VehiclePropertyAccess {
NONE = 0x00,
READ = 0x01,
WRITE = 0x02,
READ_WRITE = 0x03,
}

View file

@ -0,0 +1,40 @@
/*
* Copyright (C) 2021 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.vehicle;
@Backing(type="int") @VintfStability
enum VehiclePropertyChangeMode {
STATIC = 0x00,
ON_CHANGE = 0x01,
CONTINUOUS = 0x02,
}

View file

@ -0,0 +1,40 @@
/*
* Copyright (C) 2021 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.vehicle;
@Backing(type="int") @VintfStability
enum VehiclePropertyStatus {
AVAILABLE = 0x00,
UNAVAILABLE = 0x01,
ERROR = 0x02,
}

View file

@ -46,8 +46,8 @@ parcelable SubscribeOptions {
*
* This value indicates the resolution at which continuous property updates should be sent to
* the platform. For example, if resolution is 0.01, the subscribed property value should be
* rounded to two decimal places. If the incoming resolution value is not an integer multiple of
* 10, VHAL should return a StatusCode::INVALID_ARG.
* rounded to two decimal places. If the incoming resolution value is not an integer power of
* 10 (i.e. 10^-2, 10^-1, 10^2, etc.), VHAL should return a StatusCode::INVALID_ARG.
*/
float resolution = 0.0f;

View file

@ -54,21 +54,25 @@ parcelable VehicleAreaConfig {
/**
* Defines if the area ID for this property is READ, WRITE or READ_WRITE. This only applies if
* the property is defined in the framework as a READ_WRITE property. Access (if set) should be
* equal to, or a superset of, the VehiclePropConfig.access of the property.
* equal to, or a superset of, the VehiclePropConfig.access of the property. If access is not
* set for this VehicleAreaConfig (i.e. access == VehiclePropertyAccess.NONE), then it will
* automatically be assumed that the areaId access is the same as the VehiclePropConfig.access
* of the property.
*
* For example, if a property is defined as READ_WRITE, but the OEM wants to specify certain
* area Ids as READ-only, the corresponding areaIds should have an access set to READ, while the
* others must be set to READ_WRITE. We do not support setting specific area Ids to WRITE-only
* when the property is READ-WRITE.
*
* Exclusively one of VehiclePropConfig and the VehicleAreaConfigs should be specified for a
* single property. If VehiclePropConfig.access is populated, none of the
* VehicleAreaConfig.access values should be populated. If VehicleAreaConfig.access values are
* populated, VehiclePropConfig.access must not be populated.
* VehiclePropConfig.access should be equal the maximal subset of the accesses set in
* VehiclePropConfig.areaConfigs, excluding those with access == VehiclePropertyAccess.NONE. For
* example, if a VehiclePropConfig has some area configs with an access of
* VehiclePropertyAccess.READ and others with an access of VehiclePropertyAccess.READ_WRITE, the
* VehiclePropConfig object's access should be VehiclePropertyAccess.READ.
*
* VehicleAreaConfigs should not be partially populated with access. If the OEM wants to specify
* access for one area Id, all other configs should be populated with their access levels as
* well.
* In the scenario where the OEM actually wants to set VehicleAreaConfig.access =
* VehiclePropertyAccess.NONE, the maximal subset rule should apply with this area config
* included, making the VehiclePropConfig.access = VehiclePropertyAccess.NONE.
*/
VehiclePropertyAccess access = VehiclePropertyAccess.NONE;

View file

@ -30,9 +30,20 @@ parcelable VehiclePropConfig {
/**
* Defines if the property is read or write or both.
*
* If populating VehicleAreaConfig.access fields for this property, this field should not be
* populated. If the OEM decides to populate this field, none of the VehicleAreaConfig.access
* fields should be populated.
* If any VehicleAreaConfig.access is not set (i.e. VehicleAreaConfig.access ==
* VehiclePropertyAccess.NONE) for this property, it will automatically be assumed that the
* areaId access is the same as the VehiclePropConfig.access.
*
* VehiclePropConfig.access should be equal the maximal subset of the accesses set in its
* areaConfigs, excluding those with access == VehiclePropertyAccess.NONE. For example, if a
* VehiclePropConfig has some area configs with an access of VehiclePropertyAccess.READ and
* others with an access of VehiclePropertyAccess.READ_WRITE, the VehiclePropConfig object's
* access should be VehiclePropertyAccess.READ.
*
* In the scenario where the OEM actually wants to set VehicleAreaConfig.access =
* VehiclePropertyAccess.NONE for a particular area config, the maximal subset rule should apply
* with this area config included, making the VehiclePropConfig.access =
* VehiclePropertyAccess.NONE.
*/
VehiclePropertyAccess access = VehiclePropertyAccess.NONE;

View file

@ -16,7 +16,7 @@
"value": 286261506
},
{
"name": "Model year of vehicle.",
"name": "INFO_MODEL_YEAR",
"value": 289407235
},
{
@ -440,6 +440,10 @@
"name": "Valet mode enabled",
"value": 287312389
},
{
"name": "Head up display (HUD) enabled",
"value": 354421254
},
{
"name": "HW_KEY_INPUT",
"value": 289475088
@ -774,7 +778,7 @@
},
{
"name": "ULTRASONICS_SENSOR_ORIENTATION",
"value": 406916129
"value": 409013281
},
{
"name": "ULTRASONICS_SENSOR_FIELD_OF_VIEW",
@ -788,6 +792,10 @@
"name": "ULTRASONICS_SENSOR_SUPPORTED_RANGES",
"value": 406916132
},
{
"name": "ULTRASONICS_SENSOR_MEASURED_DISTANCE",
"value": 406916133
},
{
"name": "OBD2 Live Sensor Data",
"value": 299896064
@ -1081,7 +1089,7 @@
"data_enum": "TrailerState"
},
{
"name": "Vehicles curb weight",
"name": "VEHICLE_CURB_WEIGHT",
"value": 289410886
},
{
@ -1120,6 +1128,14 @@
],
"data_enum": "VehicleAutonomousState"
},
{
"name": "CAMERA_SERVICE_CURRENT_STATE",
"value": 289476429,
"data_enums": [
"CameraServiceState"
],
"data_enum": "CameraServiceState"
},
{
"name": "AUTOMATIC_EMERGENCY_BRAKING_ENABLED",
"value": 287313920
@ -1360,6 +1376,19 @@
"ErrorState"
],
"data_enum": "CrossTrafficMonitoringWarningState"
},
{
"name": "LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_ENABLED",
"value": 287313957
},
{
"name": "LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_STATE",
"value": 289411110,
"data_enums": [
"LowSpeedAutomaticEmergencyBrakingState",
"ErrorState"
],
"data_enum": "LowSpeedAutomaticEmergencyBrakingState"
}
]
},
@ -2351,6 +2380,28 @@
}
]
},
{
"name": "LowSpeedAutomaticEmergencyBrakingState",
"package": "android.hardware.automotive.vehicle",
"values": [
{
"name": "OTHER",
"value": 0
},
{
"name": "ENABLED",
"value": 1
},
{
"name": "ACTIVATED",
"value": 2
},
{
"name": "USER_OVERRIDE",
"value": 3
}
]
},
{
"name": "LaneCenteringAssistState",
"package": "android.hardware.automotive.vehicle",
@ -2775,6 +2826,28 @@
}
]
},
{
"name": "CameraServiceState",
"package": "android.hardware.automotive.vehicle",
"values": [
{
"name": "UNAVAILABLE",
"value": 0
},
{
"name": "INACTIVE",
"value": 1
},
{
"name": "REQUESTED",
"value": 2
},
{
"name": "ACTIVE",
"value": 3
}
]
},
{
"name": "GsrComplianceRequirementType",
"package": "android.hardware.automotive.vehicle",

View file

@ -22,8 +22,7 @@
// clang-format off
#ifndef android_hardware_automotive_vehicle_aidl_generated_lib_AccessForVehicleProperty_H_
#define android_hardware_automotive_vehicle_aidl_generated_lib_AccessForVehicleProperty_H_
#pragma once
#include <aidl/android/hardware/automotive/vehicle/VehicleProperty.h>
#include <aidl/android/hardware/automotive/vehicle/VehiclePropertyAccess.h>
@ -125,6 +124,7 @@ std::unordered_map<VehicleProperty, VehiclePropertyAccess> AccessForVehiclePrope
{VehicleProperty::DISPLAY_BRIGHTNESS, VehiclePropertyAccess::READ_WRITE},
{VehicleProperty::PER_DISPLAY_BRIGHTNESS, VehiclePropertyAccess::READ_WRITE},
{VehicleProperty::VALET_MODE_ENABLED, VehiclePropertyAccess::READ_WRITE},
{VehicleProperty::HEAD_UP_DISPLAY_ENABLED, VehiclePropertyAccess::READ_WRITE},
{VehicleProperty::HW_KEY_INPUT, VehiclePropertyAccess::READ},
{VehicleProperty::HW_KEY_INPUT_V2, VehiclePropertyAccess::READ},
{VehicleProperty::HW_MOTION_INPUT, VehiclePropertyAccess::READ},
@ -204,6 +204,7 @@ std::unordered_map<VehicleProperty, VehiclePropertyAccess> AccessForVehiclePrope
{VehicleProperty::ULTRASONICS_SENSOR_FIELD_OF_VIEW, VehiclePropertyAccess::READ},
{VehicleProperty::ULTRASONICS_SENSOR_DETECTION_RANGE, VehiclePropertyAccess::READ},
{VehicleProperty::ULTRASONICS_SENSOR_SUPPORTED_RANGES, VehiclePropertyAccess::READ},
{VehicleProperty::ULTRASONICS_SENSOR_MEASURED_DISTANCE, VehiclePropertyAccess::READ},
{VehicleProperty::OBD2_LIVE_FRAME, VehiclePropertyAccess::READ},
{VehicleProperty::OBD2_FREEZE_FRAME, VehiclePropertyAccess::READ},
{VehicleProperty::OBD2_FREEZE_FRAME_INFO, VehiclePropertyAccess::READ},
@ -261,6 +262,7 @@ std::unordered_map<VehicleProperty, VehiclePropertyAccess> AccessForVehiclePrope
{VehicleProperty::VEHICLE_IN_USE, VehiclePropertyAccess::READ_WRITE},
{VehicleProperty::CLUSTER_HEARTBEAT, VehiclePropertyAccess::WRITE},
{VehicleProperty::VEHICLE_DRIVING_AUTOMATION_CURRENT_LEVEL, VehiclePropertyAccess::READ},
{VehicleProperty::CAMERA_SERVICE_CURRENT_STATE, VehiclePropertyAccess::WRITE},
{VehicleProperty::AUTOMATIC_EMERGENCY_BRAKING_ENABLED, VehiclePropertyAccess::READ_WRITE},
{VehicleProperty::AUTOMATIC_EMERGENCY_BRAKING_STATE, VehiclePropertyAccess::READ},
{VehicleProperty::FORWARD_COLLISION_WARNING_ENABLED, VehiclePropertyAccess::READ_WRITE},
@ -298,6 +300,8 @@ std::unordered_map<VehicleProperty, VehiclePropertyAccess> AccessForVehiclePrope
{VehicleProperty::LOW_SPEED_COLLISION_WARNING_STATE, VehiclePropertyAccess::READ},
{VehicleProperty::CROSS_TRAFFIC_MONITORING_ENABLED, VehiclePropertyAccess::READ_WRITE},
{VehicleProperty::CROSS_TRAFFIC_MONITORING_WARNING_STATE, VehiclePropertyAccess::READ},
{VehicleProperty::LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_ENABLED, VehiclePropertyAccess::READ_WRITE},
{VehicleProperty::LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_STATE, VehiclePropertyAccess::READ},
};
} // namespace vehicle
@ -305,5 +309,3 @@ std::unordered_map<VehicleProperty, VehiclePropertyAccess> AccessForVehiclePrope
} // namespace hardware
} // namespace android
} // aidl
#endif // android_hardware_automotive_vehicle_aidl_generated_lib_AccessForVehicleProperty_H_

View file

@ -22,8 +22,7 @@
// clang-format off
#ifndef android_hardware_automotive_vehicle_aidl_generated_lib_ChangeModeForVehicleProperty_H_
#define android_hardware_automotive_vehicle_aidl_generated_lib_ChangeModeForVehicleProperty_H_
#pragma once
#include <aidl/android/hardware/automotive/vehicle/VehicleProperty.h>
#include <aidl/android/hardware/automotive/vehicle/VehiclePropertyChangeMode.h>
@ -125,6 +124,7 @@ std::unordered_map<VehicleProperty, VehiclePropertyChangeMode> ChangeModeForVehi
{VehicleProperty::DISPLAY_BRIGHTNESS, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::PER_DISPLAY_BRIGHTNESS, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::VALET_MODE_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::HEAD_UP_DISPLAY_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::HW_KEY_INPUT, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::HW_KEY_INPUT_V2, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::HW_MOTION_INPUT, VehiclePropertyChangeMode::ON_CHANGE},
@ -204,6 +204,7 @@ std::unordered_map<VehicleProperty, VehiclePropertyChangeMode> ChangeModeForVehi
{VehicleProperty::ULTRASONICS_SENSOR_FIELD_OF_VIEW, VehiclePropertyChangeMode::STATIC},
{VehicleProperty::ULTRASONICS_SENSOR_DETECTION_RANGE, VehiclePropertyChangeMode::STATIC},
{VehicleProperty::ULTRASONICS_SENSOR_SUPPORTED_RANGES, VehiclePropertyChangeMode::STATIC},
{VehicleProperty::ULTRASONICS_SENSOR_MEASURED_DISTANCE, VehiclePropertyChangeMode::CONTINUOUS},
{VehicleProperty::OBD2_LIVE_FRAME, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::OBD2_FREEZE_FRAME, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::OBD2_FREEZE_FRAME_INFO, VehiclePropertyChangeMode::ON_CHANGE},
@ -261,6 +262,7 @@ std::unordered_map<VehicleProperty, VehiclePropertyChangeMode> ChangeModeForVehi
{VehicleProperty::VEHICLE_IN_USE, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::CLUSTER_HEARTBEAT, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::VEHICLE_DRIVING_AUTOMATION_CURRENT_LEVEL, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::CAMERA_SERVICE_CURRENT_STATE, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::AUTOMATIC_EMERGENCY_BRAKING_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::AUTOMATIC_EMERGENCY_BRAKING_STATE, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::FORWARD_COLLISION_WARNING_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
@ -298,6 +300,8 @@ std::unordered_map<VehicleProperty, VehiclePropertyChangeMode> ChangeModeForVehi
{VehicleProperty::LOW_SPEED_COLLISION_WARNING_STATE, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::CROSS_TRAFFIC_MONITORING_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::CROSS_TRAFFIC_MONITORING_WARNING_STATE, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_STATE, VehiclePropertyChangeMode::ON_CHANGE},
};
} // namespace vehicle
@ -305,5 +309,3 @@ std::unordered_map<VehicleProperty, VehiclePropertyChangeMode> ChangeModeForVehi
} // namespace hardware
} // namespace android
} // aidl
#endif // android_hardware_automotive_vehicle_aidl_generated_lib_ChangeModeForVehicleProperty_H_

View file

@ -0,0 +1,310 @@
/*
* 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.
*/
/**
* DO NOT EDIT MANUALLY!!!
*
* Generated by tools/generate_annotation_enums.py.
*/
// clang-format off
#pragma once
#include <aidl/android/hardware/automotive/vehicle/VehicleProperty.h>
#include <unordered_map>
namespace aidl {
namespace android {
namespace hardware {
namespace automotive {
namespace vehicle {
std::unordered_map<VehicleProperty, int32_t> VersionForVehicleProperty = {
{VehicleProperty::INFO_VIN, 2},
{VehicleProperty::INFO_MAKE, 2},
{VehicleProperty::INFO_MODEL, 2},
{VehicleProperty::INFO_MODEL_YEAR, 2},
{VehicleProperty::INFO_FUEL_CAPACITY, 2},
{VehicleProperty::INFO_FUEL_TYPE, 2},
{VehicleProperty::INFO_EV_BATTERY_CAPACITY, 2},
{VehicleProperty::INFO_EV_CONNECTOR_TYPE, 2},
{VehicleProperty::INFO_FUEL_DOOR_LOCATION, 2},
{VehicleProperty::INFO_EV_PORT_LOCATION, 2},
{VehicleProperty::INFO_DRIVER_SEAT, 2},
{VehicleProperty::INFO_EXTERIOR_DIMENSIONS, 2},
{VehicleProperty::INFO_MULTI_EV_PORT_LOCATIONS, 2},
{VehicleProperty::PERF_ODOMETER, 2},
{VehicleProperty::PERF_VEHICLE_SPEED, 2},
{VehicleProperty::PERF_VEHICLE_SPEED_DISPLAY, 2},
{VehicleProperty::PERF_STEERING_ANGLE, 2},
{VehicleProperty::PERF_REAR_STEERING_ANGLE, 2},
{VehicleProperty::ENGINE_COOLANT_TEMP, 2},
{VehicleProperty::ENGINE_OIL_LEVEL, 2},
{VehicleProperty::ENGINE_OIL_TEMP, 2},
{VehicleProperty::ENGINE_RPM, 2},
{VehicleProperty::WHEEL_TICK, 2},
{VehicleProperty::FUEL_LEVEL, 2},
{VehicleProperty::FUEL_DOOR_OPEN, 2},
{VehicleProperty::EV_BATTERY_LEVEL, 2},
{VehicleProperty::EV_CURRENT_BATTERY_CAPACITY, 2},
{VehicleProperty::EV_CHARGE_PORT_OPEN, 2},
{VehicleProperty::EV_CHARGE_PORT_CONNECTED, 2},
{VehicleProperty::EV_BATTERY_INSTANTANEOUS_CHARGE_RATE, 2},
{VehicleProperty::RANGE_REMAINING, 2},
{VehicleProperty::EV_BATTERY_AVERAGE_TEMPERATURE, 3},
{VehicleProperty::TIRE_PRESSURE, 2},
{VehicleProperty::CRITICALLY_LOW_TIRE_PRESSURE, 2},
{VehicleProperty::ENGINE_IDLE_AUTO_STOP_ENABLED, 2},
{VehicleProperty::IMPACT_DETECTED, 3},
{VehicleProperty::GEAR_SELECTION, 2},
{VehicleProperty::CURRENT_GEAR, 2},
{VehicleProperty::PARKING_BRAKE_ON, 2},
{VehicleProperty::PARKING_BRAKE_AUTO_APPLY, 2},
{VehicleProperty::EV_BRAKE_REGENERATION_LEVEL, 2},
{VehicleProperty::FUEL_LEVEL_LOW, 2},
{VehicleProperty::NIGHT_MODE, 2},
{VehicleProperty::TURN_SIGNAL_STATE, 2},
{VehicleProperty::IGNITION_STATE, 2},
{VehicleProperty::ABS_ACTIVE, 2},
{VehicleProperty::TRACTION_CONTROL_ACTIVE, 2},
{VehicleProperty::EV_STOPPING_MODE, 2},
{VehicleProperty::ELECTRONIC_STABILITY_CONTROL_ENABLED, 3},
{VehicleProperty::ELECTRONIC_STABILITY_CONTROL_STATE, 2},
{VehicleProperty::HVAC_FAN_SPEED, 2},
{VehicleProperty::HVAC_FAN_DIRECTION, 2},
{VehicleProperty::HVAC_TEMPERATURE_CURRENT, 2},
{VehicleProperty::HVAC_TEMPERATURE_SET, 2},
{VehicleProperty::HVAC_DEFROSTER, 2},
{VehicleProperty::HVAC_AC_ON, 2},
{VehicleProperty::HVAC_MAX_AC_ON, 2},
{VehicleProperty::HVAC_MAX_DEFROST_ON, 2},
{VehicleProperty::HVAC_RECIRC_ON, 2},
{VehicleProperty::HVAC_DUAL_ON, 2},
{VehicleProperty::HVAC_AUTO_ON, 2},
{VehicleProperty::HVAC_SEAT_TEMPERATURE, 2},
{VehicleProperty::HVAC_SIDE_MIRROR_HEAT, 2},
{VehicleProperty::HVAC_STEERING_WHEEL_HEAT, 2},
{VehicleProperty::HVAC_TEMPERATURE_DISPLAY_UNITS, 2},
{VehicleProperty::HVAC_ACTUAL_FAN_SPEED_RPM, 2},
{VehicleProperty::HVAC_POWER_ON, 2},
{VehicleProperty::HVAC_FAN_DIRECTION_AVAILABLE, 2},
{VehicleProperty::HVAC_AUTO_RECIRC_ON, 2},
{VehicleProperty::HVAC_SEAT_VENTILATION, 2},
{VehicleProperty::HVAC_ELECTRIC_DEFROSTER_ON, 2},
{VehicleProperty::HVAC_TEMPERATURE_VALUE_SUGGESTION, 2},
{VehicleProperty::DISTANCE_DISPLAY_UNITS, 2},
{VehicleProperty::FUEL_VOLUME_DISPLAY_UNITS, 2},
{VehicleProperty::TIRE_PRESSURE_DISPLAY_UNITS, 2},
{VehicleProperty::EV_BATTERY_DISPLAY_UNITS, 2},
{VehicleProperty::FUEL_CONSUMPTION_UNITS_DISTANCE_OVER_VOLUME, 2},
{VehicleProperty::VEHICLE_SPEED_DISPLAY_UNITS, 2},
{VehicleProperty::EXTERNAL_CAR_TIME, 2},
{VehicleProperty::ANDROID_EPOCH_TIME, 2},
{VehicleProperty::STORAGE_ENCRYPTION_BINDING_SEED, 2},
{VehicleProperty::ENV_OUTSIDE_TEMPERATURE, 2},
{VehicleProperty::AP_POWER_STATE_REQ, 2},
{VehicleProperty::AP_POWER_STATE_REPORT, 2},
{VehicleProperty::AP_POWER_BOOTUP_REASON, 2},
{VehicleProperty::DISPLAY_BRIGHTNESS, 2},
{VehicleProperty::PER_DISPLAY_BRIGHTNESS, 2},
{VehicleProperty::VALET_MODE_ENABLED, 3},
{VehicleProperty::HEAD_UP_DISPLAY_ENABLED, 3},
{VehicleProperty::HW_KEY_INPUT, 2},
{VehicleProperty::HW_KEY_INPUT_V2, 2},
{VehicleProperty::HW_MOTION_INPUT, 2},
{VehicleProperty::HW_ROTARY_INPUT, 2},
{VehicleProperty::HW_CUSTOM_INPUT, 2},
{VehicleProperty::DOOR_POS, 2},
{VehicleProperty::DOOR_MOVE, 2},
{VehicleProperty::DOOR_LOCK, 2},
{VehicleProperty::DOOR_CHILD_LOCK_ENABLED, 2},
{VehicleProperty::MIRROR_Z_POS, 2},
{VehicleProperty::MIRROR_Z_MOVE, 2},
{VehicleProperty::MIRROR_Y_POS, 2},
{VehicleProperty::MIRROR_Y_MOVE, 2},
{VehicleProperty::MIRROR_LOCK, 2},
{VehicleProperty::MIRROR_FOLD, 2},
{VehicleProperty::MIRROR_AUTO_FOLD_ENABLED, 2},
{VehicleProperty::MIRROR_AUTO_TILT_ENABLED, 2},
{VehicleProperty::SEAT_MEMORY_SELECT, 2},
{VehicleProperty::SEAT_MEMORY_SET, 2},
{VehicleProperty::SEAT_BELT_BUCKLED, 2},
{VehicleProperty::SEAT_BELT_HEIGHT_POS, 2},
{VehicleProperty::SEAT_BELT_HEIGHT_MOVE, 2},
{VehicleProperty::SEAT_FORE_AFT_POS, 2},
{VehicleProperty::SEAT_FORE_AFT_MOVE, 2},
{VehicleProperty::SEAT_BACKREST_ANGLE_1_POS, 2},
{VehicleProperty::SEAT_BACKREST_ANGLE_1_MOVE, 2},
{VehicleProperty::SEAT_BACKREST_ANGLE_2_POS, 2},
{VehicleProperty::SEAT_BACKREST_ANGLE_2_MOVE, 2},
{VehicleProperty::SEAT_HEIGHT_POS, 2},
{VehicleProperty::SEAT_HEIGHT_MOVE, 2},
{VehicleProperty::SEAT_DEPTH_POS, 2},
{VehicleProperty::SEAT_DEPTH_MOVE, 2},
{VehicleProperty::SEAT_TILT_POS, 2},
{VehicleProperty::SEAT_TILT_MOVE, 2},
{VehicleProperty::SEAT_LUMBAR_FORE_AFT_POS, 2},
{VehicleProperty::SEAT_LUMBAR_FORE_AFT_MOVE, 2},
{VehicleProperty::SEAT_LUMBAR_SIDE_SUPPORT_POS, 2},
{VehicleProperty::SEAT_LUMBAR_SIDE_SUPPORT_MOVE, 2},
{VehicleProperty::SEAT_HEADREST_HEIGHT_POS, 2},
{VehicleProperty::SEAT_HEADREST_HEIGHT_POS_V2, 2},
{VehicleProperty::SEAT_HEADREST_HEIGHT_MOVE, 2},
{VehicleProperty::SEAT_HEADREST_ANGLE_POS, 2},
{VehicleProperty::SEAT_HEADREST_ANGLE_MOVE, 2},
{VehicleProperty::SEAT_HEADREST_FORE_AFT_POS, 2},
{VehicleProperty::SEAT_HEADREST_FORE_AFT_MOVE, 2},
{VehicleProperty::SEAT_FOOTWELL_LIGHTS_STATE, 2},
{VehicleProperty::SEAT_FOOTWELL_LIGHTS_SWITCH, 2},
{VehicleProperty::SEAT_EASY_ACCESS_ENABLED, 2},
{VehicleProperty::SEAT_AIRBAG_ENABLED, 3},
{VehicleProperty::SEAT_AIRBAGS_DEPLOYED, 2},
{VehicleProperty::SEAT_CUSHION_SIDE_SUPPORT_POS, 2},
{VehicleProperty::SEAT_CUSHION_SIDE_SUPPORT_MOVE, 2},
{VehicleProperty::SEAT_LUMBAR_VERTICAL_POS, 2},
{VehicleProperty::SEAT_LUMBAR_VERTICAL_MOVE, 2},
{VehicleProperty::SEAT_WALK_IN_POS, 2},
{VehicleProperty::SEAT_BELT_PRETENSIONER_DEPLOYED, 3},
{VehicleProperty::SEAT_OCCUPANCY, 2},
{VehicleProperty::WINDOW_POS, 2},
{VehicleProperty::WINDOW_MOVE, 2},
{VehicleProperty::WINDOW_LOCK, 2},
{VehicleProperty::WINDSHIELD_WIPERS_PERIOD, 2},
{VehicleProperty::WINDSHIELD_WIPERS_STATE, 2},
{VehicleProperty::WINDSHIELD_WIPERS_SWITCH, 2},
{VehicleProperty::STEERING_WHEEL_DEPTH_POS, 2},
{VehicleProperty::STEERING_WHEEL_DEPTH_MOVE, 2},
{VehicleProperty::STEERING_WHEEL_HEIGHT_POS, 2},
{VehicleProperty::STEERING_WHEEL_HEIGHT_MOVE, 2},
{VehicleProperty::STEERING_WHEEL_THEFT_LOCK_ENABLED, 2},
{VehicleProperty::STEERING_WHEEL_LOCKED, 2},
{VehicleProperty::STEERING_WHEEL_EASY_ACCESS_ENABLED, 2},
{VehicleProperty::GLOVE_BOX_DOOR_POS, 2},
{VehicleProperty::GLOVE_BOX_LOCKED, 2},
{VehicleProperty::VEHICLE_MAP_SERVICE, 2},
{VehicleProperty::LOCATION_CHARACTERIZATION, 2},
{VehicleProperty::ULTRASONICS_SENSOR_POSITION, 3},
{VehicleProperty::ULTRASONICS_SENSOR_ORIENTATION, 3},
{VehicleProperty::ULTRASONICS_SENSOR_FIELD_OF_VIEW, 3},
{VehicleProperty::ULTRASONICS_SENSOR_DETECTION_RANGE, 3},
{VehicleProperty::ULTRASONICS_SENSOR_SUPPORTED_RANGES, 3},
{VehicleProperty::ULTRASONICS_SENSOR_MEASURED_DISTANCE, 3},
{VehicleProperty::OBD2_LIVE_FRAME, 2},
{VehicleProperty::OBD2_FREEZE_FRAME, 2},
{VehicleProperty::OBD2_FREEZE_FRAME_INFO, 2},
{VehicleProperty::OBD2_FREEZE_FRAME_CLEAR, 2},
{VehicleProperty::HEADLIGHTS_STATE, 2},
{VehicleProperty::HIGH_BEAM_LIGHTS_STATE, 2},
{VehicleProperty::FOG_LIGHTS_STATE, 2},
{VehicleProperty::HAZARD_LIGHTS_STATE, 2},
{VehicleProperty::HEADLIGHTS_SWITCH, 2},
{VehicleProperty::HIGH_BEAM_LIGHTS_SWITCH, 2},
{VehicleProperty::FOG_LIGHTS_SWITCH, 2},
{VehicleProperty::HAZARD_LIGHTS_SWITCH, 2},
{VehicleProperty::CABIN_LIGHTS_STATE, 2},
{VehicleProperty::CABIN_LIGHTS_SWITCH, 2},
{VehicleProperty::READING_LIGHTS_STATE, 2},
{VehicleProperty::READING_LIGHTS_SWITCH, 2},
{VehicleProperty::STEERING_WHEEL_LIGHTS_STATE, 2},
{VehicleProperty::STEERING_WHEEL_LIGHTS_SWITCH, 2},
{VehicleProperty::SUPPORT_CUSTOMIZE_VENDOR_PERMISSION, 2},
{VehicleProperty::DISABLED_OPTIONAL_FEATURES, 2},
{VehicleProperty::INITIAL_USER_INFO, 2},
{VehicleProperty::SWITCH_USER, 2},
{VehicleProperty::CREATE_USER, 2},
{VehicleProperty::REMOVE_USER, 2},
{VehicleProperty::USER_IDENTIFICATION_ASSOCIATION, 2},
{VehicleProperty::EVS_SERVICE_REQUEST, 2},
{VehicleProperty::POWER_POLICY_REQ, 2},
{VehicleProperty::POWER_POLICY_GROUP_REQ, 2},
{VehicleProperty::CURRENT_POWER_POLICY, 2},
{VehicleProperty::WATCHDOG_ALIVE, 2},
{VehicleProperty::WATCHDOG_TERMINATED_PROCESS, 2},
{VehicleProperty::VHAL_HEARTBEAT, 2},
{VehicleProperty::CLUSTER_SWITCH_UI, 2},
{VehicleProperty::CLUSTER_DISPLAY_STATE, 2},
{VehicleProperty::CLUSTER_REPORT_STATE, 2},
{VehicleProperty::CLUSTER_REQUEST_DISPLAY, 2},
{VehicleProperty::CLUSTER_NAVIGATION_STATE, 2},
{VehicleProperty::ELECTRONIC_TOLL_COLLECTION_CARD_TYPE, 2},
{VehicleProperty::ELECTRONIC_TOLL_COLLECTION_CARD_STATUS, 2},
{VehicleProperty::FRONT_FOG_LIGHTS_STATE, 2},
{VehicleProperty::FRONT_FOG_LIGHTS_SWITCH, 2},
{VehicleProperty::REAR_FOG_LIGHTS_STATE, 2},
{VehicleProperty::REAR_FOG_LIGHTS_SWITCH, 2},
{VehicleProperty::EV_CHARGE_CURRENT_DRAW_LIMIT, 2},
{VehicleProperty::EV_CHARGE_PERCENT_LIMIT, 2},
{VehicleProperty::EV_CHARGE_STATE, 2},
{VehicleProperty::EV_CHARGE_SWITCH, 2},
{VehicleProperty::EV_CHARGE_TIME_REMAINING, 2},
{VehicleProperty::EV_REGENERATIVE_BRAKING_STATE, 2},
{VehicleProperty::TRAILER_PRESENT, 2},
{VehicleProperty::VEHICLE_CURB_WEIGHT, 2},
{VehicleProperty::GENERAL_SAFETY_REGULATION_COMPLIANCE_REQUIREMENT, 2},
{VehicleProperty::SUPPORTED_PROPERTY_IDS, 2},
{VehicleProperty::SHUTDOWN_REQUEST, 2},
{VehicleProperty::VEHICLE_IN_USE, 2},
{VehicleProperty::CLUSTER_HEARTBEAT, 3},
{VehicleProperty::VEHICLE_DRIVING_AUTOMATION_CURRENT_LEVEL, 3},
{VehicleProperty::CAMERA_SERVICE_CURRENT_STATE, 3},
{VehicleProperty::AUTOMATIC_EMERGENCY_BRAKING_ENABLED, 2},
{VehicleProperty::AUTOMATIC_EMERGENCY_BRAKING_STATE, 2},
{VehicleProperty::FORWARD_COLLISION_WARNING_ENABLED, 2},
{VehicleProperty::FORWARD_COLLISION_WARNING_STATE, 2},
{VehicleProperty::BLIND_SPOT_WARNING_ENABLED, 2},
{VehicleProperty::BLIND_SPOT_WARNING_STATE, 2},
{VehicleProperty::LANE_DEPARTURE_WARNING_ENABLED, 2},
{VehicleProperty::LANE_DEPARTURE_WARNING_STATE, 2},
{VehicleProperty::LANE_KEEP_ASSIST_ENABLED, 2},
{VehicleProperty::LANE_KEEP_ASSIST_STATE, 2},
{VehicleProperty::LANE_CENTERING_ASSIST_ENABLED, 2},
{VehicleProperty::LANE_CENTERING_ASSIST_COMMAND, 2},
{VehicleProperty::LANE_CENTERING_ASSIST_STATE, 2},
{VehicleProperty::EMERGENCY_LANE_KEEP_ASSIST_ENABLED, 2},
{VehicleProperty::EMERGENCY_LANE_KEEP_ASSIST_STATE, 2},
{VehicleProperty::CRUISE_CONTROL_ENABLED, 2},
{VehicleProperty::CRUISE_CONTROL_TYPE, 2},
{VehicleProperty::CRUISE_CONTROL_STATE, 2},
{VehicleProperty::CRUISE_CONTROL_COMMAND, 2},
{VehicleProperty::CRUISE_CONTROL_TARGET_SPEED, 2},
{VehicleProperty::ADAPTIVE_CRUISE_CONTROL_TARGET_TIME_GAP, 2},
{VehicleProperty::ADAPTIVE_CRUISE_CONTROL_LEAD_VEHICLE_MEASURED_DISTANCE, 2},
{VehicleProperty::HANDS_ON_DETECTION_ENABLED, 2},
{VehicleProperty::HANDS_ON_DETECTION_DRIVER_STATE, 2},
{VehicleProperty::HANDS_ON_DETECTION_WARNING, 2},
{VehicleProperty::DRIVER_DROWSINESS_ATTENTION_SYSTEM_ENABLED, 3},
{VehicleProperty::DRIVER_DROWSINESS_ATTENTION_STATE, 3},
{VehicleProperty::DRIVER_DROWSINESS_ATTENTION_WARNING_ENABLED, 3},
{VehicleProperty::DRIVER_DROWSINESS_ATTENTION_WARNING, 3},
{VehicleProperty::DRIVER_DISTRACTION_SYSTEM_ENABLED, 3},
{VehicleProperty::DRIVER_DISTRACTION_STATE, 3},
{VehicleProperty::DRIVER_DISTRACTION_WARNING_ENABLED, 2},
{VehicleProperty::DRIVER_DISTRACTION_WARNING, 3},
{VehicleProperty::LOW_SPEED_COLLISION_WARNING_ENABLED, 3},
{VehicleProperty::LOW_SPEED_COLLISION_WARNING_STATE, 3},
{VehicleProperty::CROSS_TRAFFIC_MONITORING_ENABLED, 3},
{VehicleProperty::CROSS_TRAFFIC_MONITORING_WARNING_STATE, 3},
{VehicleProperty::LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_ENABLED, 3},
{VehicleProperty::LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_STATE, 3},
};
} // namespace vehicle
} // namespace automotive
} // namespace hardware
} // namespace android
} // aidl

View file

@ -117,6 +117,7 @@ public final class AccessForVehicleProperty {
Map.entry(VehicleProperty.DISPLAY_BRIGHTNESS, VehiclePropertyAccess.READ_WRITE),
Map.entry(VehicleProperty.PER_DISPLAY_BRIGHTNESS, VehiclePropertyAccess.READ_WRITE),
Map.entry(VehicleProperty.VALET_MODE_ENABLED, VehiclePropertyAccess.READ_WRITE),
Map.entry(VehicleProperty.HEAD_UP_DISPLAY_ENABLED, VehiclePropertyAccess.READ_WRITE),
Map.entry(VehicleProperty.HW_KEY_INPUT, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.HW_KEY_INPUT_V2, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.HW_MOTION_INPUT, VehiclePropertyAccess.READ),
@ -196,6 +197,7 @@ public final class AccessForVehicleProperty {
Map.entry(VehicleProperty.ULTRASONICS_SENSOR_FIELD_OF_VIEW, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.ULTRASONICS_SENSOR_DETECTION_RANGE, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.ULTRASONICS_SENSOR_SUPPORTED_RANGES, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.ULTRASONICS_SENSOR_MEASURED_DISTANCE, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.OBD2_LIVE_FRAME, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.OBD2_FREEZE_FRAME, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.OBD2_FREEZE_FRAME_INFO, VehiclePropertyAccess.READ),
@ -253,6 +255,7 @@ public final class AccessForVehicleProperty {
Map.entry(VehicleProperty.VEHICLE_IN_USE, VehiclePropertyAccess.READ_WRITE),
Map.entry(VehicleProperty.CLUSTER_HEARTBEAT, VehiclePropertyAccess.WRITE),
Map.entry(VehicleProperty.VEHICLE_DRIVING_AUTOMATION_CURRENT_LEVEL, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.CAMERA_SERVICE_CURRENT_STATE, VehiclePropertyAccess.WRITE),
Map.entry(VehicleProperty.AUTOMATIC_EMERGENCY_BRAKING_ENABLED, VehiclePropertyAccess.READ_WRITE),
Map.entry(VehicleProperty.AUTOMATIC_EMERGENCY_BRAKING_STATE, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.FORWARD_COLLISION_WARNING_ENABLED, VehiclePropertyAccess.READ_WRITE),
@ -289,7 +292,9 @@ public final class AccessForVehicleProperty {
Map.entry(VehicleProperty.LOW_SPEED_COLLISION_WARNING_ENABLED, VehiclePropertyAccess.READ_WRITE),
Map.entry(VehicleProperty.LOW_SPEED_COLLISION_WARNING_STATE, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.CROSS_TRAFFIC_MONITORING_ENABLED, VehiclePropertyAccess.READ_WRITE),
Map.entry(VehicleProperty.CROSS_TRAFFIC_MONITORING_WARNING_STATE, VehiclePropertyAccess.READ)
Map.entry(VehicleProperty.CROSS_TRAFFIC_MONITORING_WARNING_STATE, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_ENABLED, VehiclePropertyAccess.READ_WRITE),
Map.entry(VehicleProperty.LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_STATE, VehiclePropertyAccess.READ)
);
}

View file

@ -117,6 +117,7 @@ public final class ChangeModeForVehicleProperty {
Map.entry(VehicleProperty.DISPLAY_BRIGHTNESS, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.PER_DISPLAY_BRIGHTNESS, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.VALET_MODE_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.HEAD_UP_DISPLAY_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.HW_KEY_INPUT, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.HW_KEY_INPUT_V2, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.HW_MOTION_INPUT, VehiclePropertyChangeMode.ON_CHANGE),
@ -196,6 +197,7 @@ public final class ChangeModeForVehicleProperty {
Map.entry(VehicleProperty.ULTRASONICS_SENSOR_FIELD_OF_VIEW, VehiclePropertyChangeMode.STATIC),
Map.entry(VehicleProperty.ULTRASONICS_SENSOR_DETECTION_RANGE, VehiclePropertyChangeMode.STATIC),
Map.entry(VehicleProperty.ULTRASONICS_SENSOR_SUPPORTED_RANGES, VehiclePropertyChangeMode.STATIC),
Map.entry(VehicleProperty.ULTRASONICS_SENSOR_MEASURED_DISTANCE, VehiclePropertyChangeMode.CONTINUOUS),
Map.entry(VehicleProperty.OBD2_LIVE_FRAME, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.OBD2_FREEZE_FRAME, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.OBD2_FREEZE_FRAME_INFO, VehiclePropertyChangeMode.ON_CHANGE),
@ -253,6 +255,7 @@ public final class ChangeModeForVehicleProperty {
Map.entry(VehicleProperty.VEHICLE_IN_USE, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.CLUSTER_HEARTBEAT, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.VEHICLE_DRIVING_AUTOMATION_CURRENT_LEVEL, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.CAMERA_SERVICE_CURRENT_STATE, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.AUTOMATIC_EMERGENCY_BRAKING_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.AUTOMATIC_EMERGENCY_BRAKING_STATE, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.FORWARD_COLLISION_WARNING_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
@ -289,7 +292,9 @@ public final class ChangeModeForVehicleProperty {
Map.entry(VehicleProperty.LOW_SPEED_COLLISION_WARNING_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.LOW_SPEED_COLLISION_WARNING_STATE, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.CROSS_TRAFFIC_MONITORING_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.CROSS_TRAFFIC_MONITORING_WARNING_STATE, VehiclePropertyChangeMode.ON_CHANGE)
Map.entry(VehicleProperty.CROSS_TRAFFIC_MONITORING_WARNING_STATE, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_STATE, VehiclePropertyChangeMode.ON_CHANGE)
);
}

View file

@ -85,6 +85,7 @@ public final class EnumForVehicleProperty {
Map.entry(VehicleProperty.GENERAL_SAFETY_REGULATION_COMPLIANCE_REQUIREMENT, List.of(GsrComplianceRequirementType.class)),
Map.entry(VehicleProperty.SHUTDOWN_REQUEST, List.of(VehicleApPowerStateShutdownParam.class)),
Map.entry(VehicleProperty.VEHICLE_DRIVING_AUTOMATION_CURRENT_LEVEL, List.of(VehicleAutonomousState.class)),
Map.entry(VehicleProperty.CAMERA_SERVICE_CURRENT_STATE, List.of(CameraServiceState.class)),
Map.entry(VehicleProperty.AUTOMATIC_EMERGENCY_BRAKING_STATE, List.of(AutomaticEmergencyBrakingState.class, ErrorState.class)),
Map.entry(VehicleProperty.FORWARD_COLLISION_WARNING_STATE, List.of(ForwardCollisionWarningState.class, ErrorState.class)),
Map.entry(VehicleProperty.BLIND_SPOT_WARNING_STATE, List.of(BlindSpotWarningState.class, ErrorState.class)),
@ -103,7 +104,8 @@ public final class EnumForVehicleProperty {
Map.entry(VehicleProperty.DRIVER_DISTRACTION_STATE, List.of(DriverDistractionState.class, ErrorState.class)),
Map.entry(VehicleProperty.DRIVER_DISTRACTION_WARNING, List.of(DriverDistractionWarning.class, ErrorState.class)),
Map.entry(VehicleProperty.LOW_SPEED_COLLISION_WARNING_STATE, List.of(LowSpeedCollisionWarningState.class, ErrorState.class)),
Map.entry(VehicleProperty.CROSS_TRAFFIC_MONITORING_WARNING_STATE, List.of(CrossTrafficMonitoringWarningState.class, ErrorState.class))
Map.entry(VehicleProperty.CROSS_TRAFFIC_MONITORING_WARNING_STATE, List.of(CrossTrafficMonitoringWarningState.class, ErrorState.class)),
Map.entry(VehicleProperty.LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_STATE, List.of(LowSpeedAutomaticEmergencyBrakingState.class, ErrorState.class))
);
}

View file

@ -0,0 +1,65 @@
/*
* 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.
*/
/**
* DO NOT EDIT MANUALLY!!!
*
* Generated by tools/generate_annotation_enums.py.
*/
// clang-format off
package android.hardware.automotive.vehicle;
import java.util.Map;
public final class UnitsForVehicleProperty {
public static final Map<Integer, Integer> values = Map.ofEntries(
Map.entry(VehicleProperty.INFO_MODEL_YEAR, VehicleUnit.YEAR),
Map.entry(VehicleProperty.INFO_FUEL_CAPACITY, VehicleUnit.MILLILITER),
Map.entry(VehicleProperty.INFO_EV_BATTERY_CAPACITY, VehicleUnit.WATT_HOUR),
Map.entry(VehicleProperty.INFO_EXTERIOR_DIMENSIONS, VehicleUnit.MILLIMETER),
Map.entry(VehicleProperty.PERF_ODOMETER, VehicleUnit.KILOMETER),
Map.entry(VehicleProperty.PERF_VEHICLE_SPEED, VehicleUnit.METER_PER_SEC),
Map.entry(VehicleProperty.PERF_VEHICLE_SPEED_DISPLAY, VehicleUnit.METER_PER_SEC),
Map.entry(VehicleProperty.PERF_STEERING_ANGLE, VehicleUnit.DEGREES),
Map.entry(VehicleProperty.PERF_REAR_STEERING_ANGLE, VehicleUnit.DEGREES),
Map.entry(VehicleProperty.ENGINE_COOLANT_TEMP, VehicleUnit.CELSIUS),
Map.entry(VehicleProperty.ENGINE_OIL_TEMP, VehicleUnit.CELSIUS),
Map.entry(VehicleProperty.ENGINE_RPM, VehicleUnit.RPM),
Map.entry(VehicleProperty.FUEL_LEVEL, VehicleUnit.MILLILITER),
Map.entry(VehicleProperty.EV_BATTERY_LEVEL, VehicleUnit.WATT_HOUR),
Map.entry(VehicleProperty.EV_CURRENT_BATTERY_CAPACITY, VehicleUnit.WATT_HOUR),
Map.entry(VehicleProperty.EV_BATTERY_INSTANTANEOUS_CHARGE_RATE, VehicleUnit.MILLIWATTS),
Map.entry(VehicleProperty.RANGE_REMAINING, VehicleUnit.METER),
Map.entry(VehicleProperty.EV_BATTERY_AVERAGE_TEMPERATURE, VehicleUnit.CELSIUS),
Map.entry(VehicleProperty.TIRE_PRESSURE, VehicleUnit.KILOPASCAL),
Map.entry(VehicleProperty.CRITICALLY_LOW_TIRE_PRESSURE, VehicleUnit.KILOPASCAL),
Map.entry(VehicleProperty.HVAC_TEMPERATURE_CURRENT, VehicleUnit.CELSIUS),
Map.entry(VehicleProperty.HVAC_TEMPERATURE_SET, VehicleUnit.CELSIUS),
Map.entry(VehicleProperty.EXTERNAL_CAR_TIME, VehicleUnit.MILLI_SECS),
Map.entry(VehicleProperty.ANDROID_EPOCH_TIME, VehicleUnit.MILLI_SECS),
Map.entry(VehicleProperty.ENV_OUTSIDE_TEMPERATURE, VehicleUnit.CELSIUS),
Map.entry(VehicleProperty.WINDSHIELD_WIPERS_PERIOD, VehicleUnit.MILLI_SECS),
Map.entry(VehicleProperty.EV_CHARGE_CURRENT_DRAW_LIMIT, VehicleUnit.AMPERE),
Map.entry(VehicleProperty.EV_CHARGE_TIME_REMAINING, VehicleUnit.SECS),
Map.entry(VehicleProperty.CRUISE_CONTROL_TARGET_SPEED, VehicleUnit.METER_PER_SEC),
Map.entry(VehicleProperty.ADAPTIVE_CRUISE_CONTROL_TARGET_TIME_GAP, VehicleUnit.MILLI_SECS),
Map.entry(VehicleProperty.ADAPTIVE_CRUISE_CONTROL_LEAD_VEHICLE_MEASURED_DISTANCE, VehicleUnit.MILLIMETER)
);
}

View file

@ -130,12 +130,9 @@ class JsonConfigParser {
std::vector<T>* outPtr, std::vector<std::string>* errors);
// Parses a JSON field to VehiclePropertyAccess or VehiclePropertyChangeMode.
template <class T>
void parseAccessChangeMode(
const Json::Value& parentJsonNode, const std::string& fieldName, int propId,
const std::string& propStr,
const std::unordered_map<aidl::android::hardware::automotive::vehicle::VehicleProperty,
T>& defaultMap,
T* outPtr, std::vector<std::string>* errors);
void parseAccessChangeMode(const Json::Value& parentJsonNode, const std::string& fieldName,
const std::string& propStr, const T* defaultAccessChangeModePtr,
T* outPtr, std::vector<std::string>* errors);
// Parses a JSON field to RawPropValues.
//

View file

@ -37,6 +37,7 @@ namespace jsonconfigloader_impl {
using ::aidl::android::hardware::automotive::vehicle::AccessForVehicleProperty;
using ::aidl::android::hardware::automotive::vehicle::AutomaticEmergencyBrakingState;
using ::aidl::android::hardware::automotive::vehicle::BlindSpotWarningState;
using ::aidl::android::hardware::automotive::vehicle::CameraServiceState;
using ::aidl::android::hardware::automotive::vehicle::ChangeModeForVehicleProperty;
using ::aidl::android::hardware::automotive::vehicle::CrossTrafficMonitoringWarningState;
using ::aidl::android::hardware::automotive::vehicle::CruiseControlCommand;
@ -63,9 +64,11 @@ using ::aidl::android::hardware::automotive::vehicle::LaneCenteringAssistState;
using ::aidl::android::hardware::automotive::vehicle::LaneDepartureWarningState;
using ::aidl::android::hardware::automotive::vehicle::LaneKeepAssistState;
using ::aidl::android::hardware::automotive::vehicle::LocationCharacterization;
using ::aidl::android::hardware::automotive::vehicle::LowSpeedAutomaticEmergencyBrakingState;
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;
@ -258,6 +261,8 @@ JsonValueParser::JsonValueParser() {
std::make_unique<ConstantParser<ImpactSensorLocation>>();
mConstantParsersByType["EmergencyLaneKeepAssistState"] =
std::make_unique<ConstantParser<EmergencyLaneKeepAssistState>>();
mConstantParsersByType["CameraServiceState"] =
std::make_unique<ConstantParser<CameraServiceState>>();
mConstantParsersByType["CruiseControlType"] =
std::make_unique<ConstantParser<CruiseControlType>>();
mConstantParsersByType["CruiseControlState"] =
@ -297,6 +302,10 @@ JsonValueParser::JsonValueParser() {
std::make_unique<ConstantParser<ElectronicStabilityControlState>>();
mConstantParsersByType["CrossTrafficMonitoringWarningState"] =
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"] =
@ -484,10 +493,11 @@ bool JsonConfigParser::tryParseJsonArrayToVariable(const Json::Value& parentJson
}
template <class T>
void JsonConfigParser::parseAccessChangeMode(
const Json::Value& parentJsonNode, const std::string& fieldName, int propId,
const std::string& propStr, const std::unordered_map<VehicleProperty, T>& defaultMap,
T* outPtr, std::vector<std::string>* errors) {
void JsonConfigParser::parseAccessChangeMode(const Json::Value& parentJsonNode,
const std::string& fieldName,
const std::string& propStr,
const T* defaultAccessChangeModeValuePtr, T* outPtr,
std::vector<std::string>* errors) {
if (!parentJsonNode.isObject()) {
errors->push_back("Node: " + parentJsonNode.toStyledString() + " is not an object");
return;
@ -501,12 +511,11 @@ void JsonConfigParser::parseAccessChangeMode(
*outPtr = static_cast<T>(result.value());
return;
}
auto it = defaultMap.find(static_cast<VehicleProperty>(propId));
if (it == defaultMap.end()) {
if (defaultAccessChangeModeValuePtr == NULL) {
errors->push_back("No " + fieldName + " specified for property: " + propStr);
return;
}
*outPtr = it->second;
*outPtr = *defaultAccessChangeModeValuePtr;
return;
}
@ -543,6 +552,7 @@ void JsonConfigParser::parseAreas(const Json::Value& parentJsonNode, const std::
if (!parentJsonNode.isMember(fieldName)) {
return;
}
std::string propStr = parentJsonNode["property"].toStyledString();
const Json::Value& jsonValue = parentJsonNode[fieldName];
if (!jsonValue.isArray()) {
@ -558,6 +568,8 @@ void JsonConfigParser::parseAreas(const Json::Value& parentJsonNode, const std::
}
VehicleAreaConfig areaConfig = {};
areaConfig.areaId = areaId;
parseAccessChangeMode(jsonAreaConfig, "access", propStr, &(config->config.access),
&areaConfig.access, errors);
tryParseJsonValueToVariable(jsonAreaConfig, "minInt32Value", /*optional=*/true,
&areaConfig.minInt32Value, errors);
tryParseJsonValueToVariable(jsonAreaConfig, "maxInt32Value", /*optional=*/true,
@ -605,12 +617,21 @@ std::optional<ConfigDeclaration> JsonConfigParser::parseEachProperty(
configDecl.config.prop = propId;
std::string propStr = propJsonValue["property"].toStyledString();
parseAccessChangeMode(propJsonValue, "access", propId, propStr, AccessForVehicleProperty,
VehiclePropertyAccess* defaultAccessMode = NULL;
auto itAccess = AccessForVehicleProperty.find(static_cast<VehicleProperty>(propId));
if (itAccess != AccessForVehicleProperty.end()) {
defaultAccessMode = &itAccess->second;
}
VehiclePropertyChangeMode* defaultChangeMode = NULL;
auto itChangeMode = ChangeModeForVehicleProperty.find(static_cast<VehicleProperty>(propId));
if (itChangeMode != ChangeModeForVehicleProperty.end()) {
defaultChangeMode = &itChangeMode->second;
}
parseAccessChangeMode(propJsonValue, "access", propStr, defaultAccessMode,
&configDecl.config.access, errors);
parseAccessChangeMode(propJsonValue, "changeMode", propId, propStr,
ChangeModeForVehicleProperty, &configDecl.config.changeMode, errors);
parseAccessChangeMode(propJsonValue, "changeMode", propStr, defaultChangeMode,
&configDecl.config.changeMode, errors);
tryParseJsonValueToVariable(propJsonValue, "configString", /*optional=*/true,
&configDecl.config.configString, errors);
@ -628,19 +649,21 @@ std::optional<ConfigDeclaration> JsonConfigParser::parseEachProperty(
parseAreas(propJsonValue, "areas", &configDecl, errors);
if (errors->size() != initialErrorCount) {
return std::nullopt;
}
// If there is no area config, by default we allow variable update rate, so we have to add
// a global area config.
if (configDecl.config.areaConfigs.size() == 0) {
VehicleAreaConfig areaConfig = {
.areaId = 0,
.access = configDecl.config.access,
.supportVariableUpdateRate = true,
};
configDecl.config.areaConfigs.push_back(std::move(areaConfig));
}
if (errors->size() != initialErrorCount) {
return std::nullopt;
}
return configDecl;
}

View file

@ -287,6 +287,7 @@ TEST_F(JsonConfigLoaderUnitTest, testCheckDefaultAccessChangeMode) {
const VehiclePropConfig& propConfig = configs.begin()->second.config;
ASSERT_EQ(propConfig.access, VehiclePropertyAccess::READ);
ASSERT_EQ(propConfig.areaConfigs[0].access, VehiclePropertyAccess::READ);
ASSERT_EQ(propConfig.changeMode, VehiclePropertyChangeMode::STATIC);
}
@ -308,6 +309,7 @@ TEST_F(JsonConfigLoaderUnitTest, testAccessOverride) {
const VehiclePropConfig& propConfig = configs.begin()->second.config;
ASSERT_EQ(propConfig.access, VehiclePropertyAccess::WRITE);
ASSERT_EQ(propConfig.areaConfigs[0].access, VehiclePropertyAccess::WRITE);
ASSERT_EQ(propConfig.changeMode, VehiclePropertyChangeMode::STATIC);
}
@ -329,6 +331,7 @@ TEST_F(JsonConfigLoaderUnitTest, testChangeModeOverride) {
const VehiclePropConfig& propConfig = configs.begin()->second.config;
ASSERT_EQ(propConfig.access, VehiclePropertyAccess::READ);
ASSERT_EQ(propConfig.areaConfigs[0].access, VehiclePropertyAccess::READ);
ASSERT_EQ(propConfig.changeMode, VehiclePropertyChangeMode::ON_CHANGE);
}
@ -351,6 +354,7 @@ TEST_F(JsonConfigLoaderUnitTest, testCustomProp) {
const VehiclePropConfig& propConfig = configs.begin()->second.config;
ASSERT_EQ(propConfig.access, VehiclePropertyAccess::WRITE);
ASSERT_EQ(propConfig.areaConfigs[0].access, VehiclePropertyAccess::WRITE);
ASSERT_EQ(propConfig.changeMode, VehiclePropertyChangeMode::ON_CHANGE);
}
@ -550,10 +554,12 @@ TEST_F(JsonConfigLoaderUnitTest, testAreas_Simple) {
ASSERT_EQ(configs.size(), 1u);
const VehiclePropConfig& config = configs.begin()->second.config;
ASSERT_EQ(config.access, VehiclePropertyAccess::READ);
ASSERT_EQ(config.areaConfigs.size(), 1u);
const VehicleAreaConfig& areaConfig = config.areaConfigs[0];
ASSERT_EQ(areaConfig.minInt32Value, 1);
ASSERT_EQ(areaConfig.maxInt32Value, 7);
ASSERT_EQ(areaConfig.access, VehiclePropertyAccess::READ);
ASSERT_EQ(areaConfig.areaId, HVAC_ALL);
}
@ -635,9 +641,11 @@ TEST_F(JsonConfigLoaderUnitTest, testAreas_HandlesNoSupportedEnumValuesDeclared)
ASSERT_EQ(configs.size(), 1u);
const VehiclePropConfig& config = configs.begin()->second.config;
ASSERT_EQ(config.access, VehiclePropertyAccess::READ);
ASSERT_EQ(config.areaConfigs.size(), 1u);
const VehicleAreaConfig& areaConfig = config.areaConfigs[0];
ASSERT_EQ(areaConfig.access, VehiclePropertyAccess::READ);
ASSERT_EQ(areaConfig.areaId, 0);
ASSERT_FALSE(areaConfig.supportedEnumValues);
}
@ -662,9 +670,11 @@ TEST_F(JsonConfigLoaderUnitTest, testAreas_HandlesSupportedEnumValues) {
ASSERT_EQ(configs.size(), 1u);
const VehiclePropConfig& config = configs.begin()->second.config;
ASSERT_EQ(config.access, VehiclePropertyAccess::READ);
ASSERT_EQ(config.areaConfigs.size(), 1u);
const VehicleAreaConfig& areaConfig = config.areaConfigs[0];
ASSERT_EQ(areaConfig.access, VehiclePropertyAccess::READ);
ASSERT_EQ(areaConfig.areaId, 0);
ASSERT_TRUE(areaConfig.supportedEnumValues);
ASSERT_EQ(areaConfig.supportedEnumValues.value().size(), 2u);
@ -692,13 +702,107 @@ TEST_F(JsonConfigLoaderUnitTest, testAreas_HandlesEmptySupportedEnumValues) {
ASSERT_EQ(configs.size(), 1u);
const VehiclePropConfig& config = configs.begin()->second.config;
ASSERT_EQ(config.access, VehiclePropertyAccess::READ);
ASSERT_EQ(config.areaConfigs.size(), 1u);
const VehicleAreaConfig& areaConfig = config.areaConfigs[0];
ASSERT_EQ(areaConfig.access, VehiclePropertyAccess::READ);
ASSERT_EQ(areaConfig.areaId, 0);
ASSERT_FALSE(areaConfig.supportedEnumValues);
}
TEST_F(JsonConfigLoaderUnitTest, testAccess_areaOverrideGlobalDefault) {
std::istringstream iss(R"(
{
"properties": [{
"property": "VehicleProperty::CABIN_LIGHTS_SWITCH",
"areas": [{
"access": "VehiclePropertyAccess::READ",
"areaId": 0
}]
}]
}
)");
auto result = mLoader.loadPropConfig(iss);
ASSERT_TRUE(result.ok());
auto configs = result.value();
ASSERT_EQ(configs.size(), 1u);
const VehiclePropConfig& config = configs.begin()->second.config;
ASSERT_EQ(config.access, VehiclePropertyAccess::READ_WRITE);
ASSERT_EQ(config.areaConfigs.size(), 1u);
const VehicleAreaConfig& areaConfig = config.areaConfigs[0];
ASSERT_EQ(areaConfig.access, VehiclePropertyAccess::READ);
ASSERT_EQ(areaConfig.areaId, 0);
}
TEST_F(JsonConfigLoaderUnitTest, testAccess_globalOverrideDefault) {
std::istringstream iss(R"(
{
"properties": [{
"property": "VehicleProperty::CABIN_LIGHTS_SWITCH",
"areas": [{
"areaId": 0
}],
"access": "VehiclePropertyAccess::READ"
}]
}
)");
auto result = mLoader.loadPropConfig(iss);
ASSERT_TRUE(result.ok());
auto configs = result.value();
ASSERT_EQ(configs.size(), 1u);
const VehiclePropConfig& config = configs.begin()->second.config;
ASSERT_EQ(config.access, VehiclePropertyAccess::READ);
ASSERT_EQ(config.areaConfigs.size(), 1u);
const VehicleAreaConfig& areaConfig = config.areaConfigs[0];
ASSERT_EQ(areaConfig.access, VehiclePropertyAccess::READ);
ASSERT_EQ(areaConfig.areaId, 0);
}
TEST_F(JsonConfigLoaderUnitTest, testAccess_areaOverrideGlobal) {
std::istringstream iss(R"(
{
"properties": [{
"property": "VehicleProperty::CABIN_LIGHTS_SWITCH",
"areas": [{
"access": "VehiclePropertyAccess::WRITE",
"areaId": 0
},
{
"areaId": 1
}],
"access": "VehiclePropertyAccess::READ",
}]
}
)");
auto result = mLoader.loadPropConfig(iss);
ASSERT_TRUE(result.ok());
auto configs = result.value();
ASSERT_EQ(configs.size(), 1u);
const VehiclePropConfig& config = configs.begin()->second.config;
ASSERT_EQ(config.access, VehiclePropertyAccess::READ);
ASSERT_EQ(config.areaConfigs.size(), 2u);
const VehicleAreaConfig& areaConfig1 = config.areaConfigs[0];
ASSERT_EQ(areaConfig1.access, VehiclePropertyAccess::WRITE);
ASSERT_EQ(areaConfig1.areaId, 0);
const VehicleAreaConfig& areaConfig2 = config.areaConfigs[1];
ASSERT_EQ(areaConfig2.access, VehiclePropertyAccess::READ);
ASSERT_EQ(areaConfig2.areaId, 1);
}
} // namespace vehicle
} // namespace automotive
} // namespace hardware

View file

@ -3195,6 +3195,14 @@
]
}
},
{
"property": "VehicleProperty::AP_POWER_BOOTUP_REASON",
"defaultValue": {
"int32Values": [
"VehicleApPowerBootupReason::USER_POWER_ON"
]
}
},
{
"property": "VehicleProperty::DISPLAY_BRIGHTNESS",
"defaultValue": {
@ -3218,6 +3226,19 @@
]
}
},
{
"property": "VehicleProperty::HEAD_UP_DISPLAY_ENABLED",
"defaultValue": {
"int32Values": [
0
]
},
"areas": [
{
"areaId": "Constants::SEAT_1_LEFT"
}
]
},
{
"property": "VehicleProperty::OBD2_LIVE_FRAME",
"configArray": [
@ -3442,6 +3463,839 @@
]
}
},
{
"property": "VehicleProperty::ULTRASONICS_SENSOR_POSITION",
"comment":
"Default values for 12 individual ultrasonic sensors installed on the vehicle. Six sensors on the front bumper. Six sensors on the back bumper.",
"areas": [
{
"defaultValue": {
"int32Values": [
-1000,
3900,
0
]
},
"areaId": 1,
"comment": "Rough numbers representing front left most sensor."
},
{
"defaultValue": {
"int32Values": [
-600,
4000,
0
]
},
"areaId": 2,
"comment": "Rough numbers representing front 2nd to the left sensor."
},
{
"defaultValue": {
"int32Values": [
-200,
4000,
0
]
},
"areaId": 4,
"comment": "Rough numbers representing front 3rd to the left sensor."
},
{
"defaultValue": {
"int32Values": [
200,
4000,
0
]
},
"areaId": 8,
"comment": "Rough numbers representing front 3rd to the right sensor."
},
{
"defaultValue": {
"int32Values": [
600,
4000,
0
]
},
"areaId": 16,
"comment": "Rough numbers representing front 2nd to the right sensor."
},
{
"defaultValue": {
"int32Values": [
1000,
3900,
0
]
},
"areaId": 32,
"comment": "Rough numbers representing front right most sensor."
},
{
"defaultValue": {
"int32Values": [
-1000,
-900,
0
]
},
"areaId": 64,
"comment": "Rough numbers representing back left most sensor."
},
{
"defaultValue": {
"int32Values": [
-600,
-1000,
0
]
},
"areaId": 128,
"comment": "Rough numbers representing back 2nd to the left sensor."
},
{
"defaultValue": {
"int32Values": [
-200,
-1000,
0
]
},
"areaId": 256,
"comment": "Rough numbers representing back 3rd to the left sensor."
},
{
"defaultValue": {
"int32Values": [
200,
-1000,
0
]
},
"areaId": 512,
"comment": "Rough numbers representing back 3rd to the right sensor."
},
{
"defaultValue": {
"int32Values": [
600,
-1000,
0
]
},
"areaId": 1024,
"comment": "Rough numbers representing back 2nd to the right sensor."
},
{
"defaultValue": {
"int32Values": [
1000,
-900,
0
]
},
"areaId": 2048,
"comment": "Rough numbers representing back right most sensor."
}
]
},
{
"property": "VehicleProperty::ULTRASONICS_SENSOR_ORIENTATION",
"comment":
"Default values for 12 individual ultrasonic sensors installed on the vehicle. Six sensors on the front bumper. Six sensors on the back bumper.",
"areas": [
{
"defaultValue": {
"floatValues": [
0.924,
0,
0,
0.383
]
},
"areaId": 1,
"comment":
"Rough quaternion values [w, x, y, z] representing front left most sensor rotated 45 degrees counter-clockwise."
},
{
"defaultValue": {
"floatValues": [
1,
0,
0,
0
]
},
"areaId": 2,
"comment":
"Rough quaternion values [w, x, y, z] representing front 2nd to the left sensor rotated 0 degrees"
},
{
"defaultValue": {
"floatValues": [
1,
0,
0,
0
]
},
"areaId": 4,
"comment":
"Rough quaternion values [w, x, y, z] representing front 3rd to the left sensor rotated 0 degrees"
},
{
"defaultValue": {
"floatValues": [
1,
0,
0,
0
]
},
"areaId": 8,
"comment":
"Rough quaternion values [w, x, y, z] representing front 3rd to the right sensor rotated 0 degrees"
},
{
"defaultValue": {
"floatValues": [
1,
0,
0,
0
]
},
"areaId": 16,
"comment":
"Rough quaternion values [w, x, y, z] representing front 2nd to the right sensor rotated 0 degrees"
},
{
"defaultValue": {
"floatValues": [
0.924,
0,
0,
-0.383
]
},
"areaId": 32,
"comment":
"Rough quaternion values [w, x, y, z] representing front right most sensor rotated 45 degrees clockwise."
},
{
"defaultValue": {
"floatValues": [
60,
61,
62,
63
]
},
"areaId": 64,
"comment":
"Rough quaternion values [w, x, y, z] representing back left most sensor rotated 45 degrees counter-clockwise."
},
{
"defaultValue": {
"floatValues": [
70,
71,
72,
73
]
},
"areaId": 128,
"comment":
"Rough quaternion values [w, x, y, z] representing back 2nd to the left sensor rotated 0 degrees"
},
{
"defaultValue": {
"floatValues": [
81,
82,
83,
84
]
},
"areaId": 256,
"comment":
"Rough quaternion values [w, x, y, z] representing back 3rd to the right sensor rotated 0 degrees"
},
{
"defaultValue": {
"floatValues": [
90,
91,
92,
93
]
},
"areaId": 512,
"comment":
"Rough quaternion values [w, x, y, z] representing back 3rd to the right sensor rotated 0 degrees"
},
{
"defaultValue": {
"floatValues": [
100,
101,
102,
103
]
},
"areaId": 1024,
"comment":
"Rough quaternion values [w, x, y, z] representing back 2nd to the right sensor rotated 0 degrees"
},
{
"defaultValue": {
"floatValues": [
110,
111,
112,
113
]
},
"areaId": 2048,
"comment":
"Rough quaternion values [w, x, y, z] representing back right most sensor rotated 45 degrees clockwise."
}
]
},
{
"property": "VehicleProperty::ULTRASONICS_SENSOR_FIELD_OF_VIEW",
"comment":
"Default values for 12 individual ultrasonic sensors installed on the vehicle. Six sensors on the front bumper. Six sensors on the back bumper.",
"areas": [
{
"defaultValue": {
"int32Values": [
85,
45
]
},
"areaId": 1,
"comment": "Rough values representing front left most sensor."
},
{
"defaultValue": {
"int32Values": [
75,
45
]
},
"areaId": 2,
"comment": "Rough values representing front 2nd to the left sensor."
},
{
"defaultValue": {
"int32Values": [
75,
45
]
},
"areaId": 4,
"comment": "Rough values representing front 3rd to the left sensor."
},
{
"defaultValue": {
"int32Values": [
75,
45
]
},
"areaId": 8,
"comment": "Rough values representing front 3rd to the right sensor."
},
{
"defaultValue": {
"int32Values": [
75,
45
]
},
"areaId": 16,
"comment": "Rough values representing front 2nd to the right sensor."
},
{
"defaultValue": {
"int32Values": [
85,
45
]
},
"areaId": 32,
"comment": "Rough values representing front right most sensor."
},
{
"defaultValue": {
"int32Values": [
85,
45
]
},
"areaId": 64,
"comment": "Rough values representing back left most sensor."
},
{
"defaultValue": {
"int32Values": [
75,
45
]
},
"areaId": 128,
"comment": "Rough values representing back 2nd to the left sensor."
},
{
"defaultValue": {
"int32Values": [
75,
45
]
},
"areaId": 256,
"comment": "Rough values representing back 3rd to the left sensor."
},
{
"defaultValue": {
"int32Values": [
75,
45
]
},
"areaId": 512,
"comment": "Rough values representing back 3rd to the right sensor."
},
{
"defaultValue": {
"int32Values": [
75,
45
]
},
"areaId": 1024,
"comment": "Rough values representing back 2nd to the right sensor."
},
{
"defaultValue": {
"int32Values": [
85,
45
]
},
"areaId": 2048,
"comment": "Rough values representing back right most sensor."
}
]
},
{
"property": "VehicleProperty::ULTRASONICS_SENSOR_DETECTION_RANGE",
"areas": [
{
"defaultValue": {
"int32Values": [
150,
4000
]
},
"areaId": 1,
"comment": "Rough values representing front left most sensor."
},
{
"defaultValue": {
"int32Values": [
150,
3000
]
},
"areaId": 2,
"comment": "Rough values representing front 2nd to the left sensor."
},
{
"defaultValue": {
"int32Values": [
150,
3000
]
},
"areaId": 4,
"comment": "Rough values representing front 3rd to the left sensor."
},
{
"defaultValue": {
"int32Values": [
150,
3000
]
},
"areaId": 8,
"comment": "Rough values representing front 3rd to the right sensor."
},
{
"defaultValue": {
"int32Values": [
150,
3000
]
},
"areaId": 16,
"comment": "Rough values representing front 2nd to the right sensor."
},
{
"defaultValue": {
"int32Values": [
150,
4000
]
},
"areaId": 32,
"comment": "Rough values representing front right most sensor."
},
{
"defaultValue": {
"int32Values": [
150,
4000
]
},
"areaId": 64,
"comment": "Rough values representing back left most sensor."
},
{
"defaultValue": {
"int32Values": [
150,
3000
]
},
"areaId": 128,
"comment": "Rough values representing back 2nd to the left sensor."
},
{
"defaultValue": {
"int32Values": [
150,
3000
]
},
"areaId": 256,
"comment": "Rough values representing back 3rd to the left sensor."
},
{
"defaultValue": {
"int32Values": [
150,
3000
]
},
"areaId": 512,
"comment": "Rough values representing back 3rd to the right sensor."
},
{
"defaultValue": {
"int32Values": [
150,
3000
]
},
"areaId": 1024,
"comment": "Rough values representing back 2nd to the right sensor."
},
{
"defaultValue": {
"int32Values": [
150,
4000
]
},
"areaId": 2048,
"comment": "Rough values representing back right most sensor."
}
]
},
{
"property": "VehicleProperty::ULTRASONICS_SENSOR_SUPPORTED_RANGES",
"areas": [
{
"defaultValue": {
"int32Values": [
150,
999,
1000,
1999,
2000,
4000
]
},
"areaId": 1,
"comment": "Rough values representing front left most sensor."
},
{
"defaultValue": {
"int32Values": [
150,
999,
1000,
1999,
2000,
3000
]
},
"areaId": 2,
"comment": "Rough values representing front 2nd to the left sensor."
},
{
"defaultValue": {
"int32Values": [
150,
999,
1000,
1999,
2000,
3000
]
},
"areaId": 4,
"comment": "Rough values representing front 3rd to the left sensor."
},
{
"defaultValue": {
"int32Values": [
150,
999,
1000,
1999,
2000,
3000
]
},
"areaId": 8,
"comment": "Rough values representing front 3rd to the right sensor."
},
{
"defaultValue": {
"int32Values": [
150,
999,
1000,
1999,
2000,
3000
]
},
"areaId": 16,
"comment": "Rough values representing front 2nd to the right sensor."
},
{
"defaultValue": {
"int32Values": [
150,
999,
1000,
1999,
2000,
4000
]
},
"areaId": 32,
"comment": "Rough values representing front right most sensor."
},
{
"defaultValue": {
"int32Values": [
150,
999,
1000,
1999,
2000,
4000
]
},
"areaId": 64,
"comment": "Rough values representing back left most sensor."
},
{
"defaultValue": {
"int32Values": [
150,
999,
1000,
1999,
2000,
3000
]
},
"areaId": 128,
"comment": "Rough values representing back 2nd to the left sensor."
},
{
"defaultValue": {
"int32Values": [
150,
999,
1000,
3000
]
},
"areaId": 256,
"comment": "Rough values representing back 3rd to the left sensor."
},
{
"defaultValue": {
"int32Values": [
150,
999,
1000,
3000
]
},
"areaId": 512,
"comment": "Rough values representing back 3rd to the right sensor."
},
{
"defaultValue": {
"int32Values": [
150,
999,
1000,
1999,
2000,
3000
]
},
"areaId": 1024,
"comment": "Rough values representing back 2nd to the right sensor."
},
{
"defaultValue": {
"int32Values": [
150,
999,
1000,
1999,
2000,
4000
]
},
"areaId": 2048,
"comment": "Rough values representing back right most sensor."
}
]
},
{
"property": "VehicleProperty::ULTRASONICS_SENSOR_MEASURED_DISTANCE",
"areas": [
{
"defaultValue": {
"int32Values": [
2000,
10
]
},
"areaId": 1,
"comment": "Rough values representing front left most sensor."
},
{
"defaultValue": {
"int32Values": []
},
"areaId": 2,
"comment":
"Rough values representing front 2nd to the left sensor. Nothing detected."
},
{
"defaultValue": {
"int32Values": []
},
"areaId": 4,
"comment":
"Rough values representing front 3rd to the left sensor. Nothing detected."
},
{
"defaultValue": {
"int32Values": []
},
"areaId": 8,
"comment":
"Rough values representing front 3rd to the right sensor. Nothing detected."
},
{
"defaultValue": {
"int32Values": []
},
"areaId": 16,
"comment":
"Rough values representing front 2nd to the right sensor. Nothing detected."
},
{
"defaultValue": {
"int32Values": []
},
"areaId": 32,
"comment":
"Rough values representing front right most sensor. Nothing detected."
},
{
"defaultValue": {
"int32Values": []
},
"areaId": 64,
"comment": "Rough values representing back left most sensor. Nothing detected."
},
{
"defaultValue": {
"int32Values": []
},
"areaId": 128,
"comment":
"Rough values representing back 2nd to the left sensor. Nothing detected."
},
{
"defaultValue": {
"int32Values": []
},
"areaId": 256,
"comment":
"Rough values representing back 3rd to the left sensor. Nothing detected."
},
{
"defaultValue": {
"int32Values": [
1000
]
},
"areaId": 512,
"comment":
"Rough values representing back 3rd to the right sensor. Nothing detected."
},
{
"defaultValue": {
"int32Values": [
2000,
50
]
},
"areaId": 1024,
"comment": "Rough values representing back 2nd to the right sensor."
},
{
"defaultValue": {
"int32Values": [
2000
]
},
"areaId": 2048,
"comment":
"Rough values representing back right most sensor. No distance error."
}
],
"maxSampleRate": 10.0,
"minSampleRate": 1.0
},
{
"property": "VehicleProperty::ELECTRONIC_TOLL_COLLECTION_CARD_TYPE",
"defaultValue": {
@ -4191,6 +5045,51 @@
]
}
]
},
{
"property": "VehicleProperty::LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_ENABLED",
"defaultValue": {
"int32Values": [
1
]
}
},
{
"property": "VehicleProperty::LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_STATE",
"defaultValue": {
"int32Values": [
"LowSpeedAutomaticEmergencyBrakingState::ENABLED"
]
},
"areas": [
{
"areaId": 0,
"supportedEnumValues": [
"ErrorState::NOT_AVAILABLE_SAFETY",
"ErrorState::NOT_AVAILABLE_POOR_VISIBILITY",
"ErrorState::NOT_AVAILABLE_SPEED_HIGH",
"ErrorState::NOT_AVAILABLE_DISABLED",
"LowSpeedAutomaticEmergencyBrakingState::ENABLED",
"LowSpeedAutomaticEmergencyBrakingState::ACTIVATED",
"LowSpeedAutomaticEmergencyBrakingState::USER_OVERRIDE"
]
}
]
},
{
"property": "VehicleProperty::CAMERA_SERVICE_CURRENT_STATE",
"defaultValue": {
"int32Values": [
"CameraServiceState::UNAVAILABLE",
"CameraServiceState::UNAVAILABLE",
"CameraServiceState::UNAVAILABLE",
"CameraServiceState::UNAVAILABLE",
"CameraServiceState::UNAVAILABLE",
"CameraServiceState::UNAVAILABLE",
"CameraServiceState::UNAVAILABLE",
"CameraServiceState::UNAVAILABLE"
]
}
}
]
}

View file

@ -27,11 +27,16 @@ cc_library {
],
local_include_dirs: ["include"],
export_include_dirs: ["include"],
cflags: ["-DENABLE_VEHICLE_HAL_TEST_PROPERTIES"],
cflags: [
"-DENABLE_VEHICLE_HAL_TEST_PROPERTIES",
],
defaults: [
"VehicleHalDefaults",
"FakeVehicleHardwareDefaults",
],
whole_static_libs: [
"wakeup_client_protos",
],
host_supported: true,
}
@ -55,7 +60,9 @@ cc_defaults {
"Prebuilt_VehicleHalVendorClusterTestProperties_JSON",
],
shared_libs: [
"libgrpc++",
"libjsoncpp",
"libprotobuf-cpp-full",
],
export_static_lib_headers: ["VehicleHalUtils"],
}

View file

@ -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>
@ -187,6 +189,10 @@ class FakeVehicleHardware : public IVehicleHardware {
// Only used during initialization.
JsonConfigLoader mLoader;
// Only used during initialization. If not empty, points to an external grpc server that
// provides power controlling related properties.
std::string mPowerControllerServiceAddress = "";
void init();
// Stores the initial value to property store.
void storePropInitialValue(const ConfigDeclaration& config);
@ -240,6 +246,11 @@ class FakeVehicleHardware : public IVehicleHardware {
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();
@ -256,6 +267,7 @@ class FakeVehicleHardware : public IVehicleHardware {
std::string dumpSaveProperty(const std::vector<std::string>& options);
std::string dumpRestoreProperty(const std::vector<std::string>& options);
std::string dumpInjectEvent(const std::vector<std::string>& options);
std::string dumpSubscriptions();
template <typename T>
android::base::Result<T> safelyParseInt(int index, const std::string& s) {
@ -294,7 +306,7 @@ class FakeVehicleHardware : public IVehicleHardware {
void registerRefreshLocked(PropIdAreaId propIdAreaId, VehiclePropertyStore::EventMode eventMode,
float sampleRateHz) REQUIRES(mLock);
void unregisterRefreshLocked(PropIdAreaId propIdAreaId) REQUIRES(mLock);
void refreshTimeStampForInterval(int64_t intervalInNanos) EXCLUDES(mLock);
void refreshTimestampForInterval(int64_t intervalInNanos) EXCLUDES(mLock);
static aidl::android::hardware::automotive::vehicle::VehiclePropValue createHwInputKeyProp(
aidl::android::hardware::automotive::vehicle::VehicleHwKeyInputAction action,

View file

@ -51,6 +51,8 @@ namespace fake {
namespace {
#define PROP_ID_TO_CSTR(A) (propIdToString(A).c_str())
using ::aidl::android::hardware::automotive::vehicle::CruiseControlCommand;
using ::aidl::android::hardware::automotive::vehicle::CruiseControlType;
using ::aidl::android::hardware::automotive::vehicle::DriverDistractionState;
@ -80,6 +82,12 @@ using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyType;
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;
@ -106,6 +114,9 @@ constexpr char DEFAULT_CONFIG_DIR[] = "/vendor/etc/automotive/vhalconfig/";
// The directory for property configuration file that overrides the default configuration file.
// For config file format, see impl/default_config/config/README.md.
constexpr char OVERRIDE_CONFIG_DIR[] = "/vendor/etc/automotive/vhaloverride/";
// The optional config file for power controller grpc service that provides vehicleInUse and
// ApPowerBootupReason property.
constexpr char GRPC_SERVICE_CONFIG_FILE[] = "/vendor/etc/automotive/powercontroller/serverconfig";
// If OVERRIDE_PROPERTY is set, we will use the configuration files from OVERRIDE_CONFIG_DIR to
// overwrite the default configs.
constexpr char OVERRIDE_PROPERTY[] = "persist.vendor.vhal_init_value_override";
@ -246,7 +257,30 @@ const std::unordered_map<int32_t, std::vector<int32_t>> mAdasEnabledPropToAdasPr
toInt(VehicleProperty::CROSS_TRAFFIC_MONITORING_WARNING_STATE),
},
},
// LSAEB
{
toInt(VehicleProperty::LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_ENABLED),
{
toInt(VehicleProperty::LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_STATE),
},
},
};
// 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)};
void maybeGetGrpcServiceInfo(std::string* address) {
std::ifstream ifs(GRPC_SERVICE_CONFIG_FILE);
if (!ifs) {
ALOGI("Cannot open grpc service config file at: %s, assume no service is available",
GRPC_SERVICE_CONFIG_FILE);
return;
}
ifs >> *address;
ifs.close();
}
} // namespace
void FakeVehicleHardware::storePropInitialValue(const ConfigDeclaration& config) {
@ -342,6 +376,8 @@ std::unordered_map<int32_t, ConfigDeclaration> FakeVehicleHardware::loadConfigDe
}
void FakeVehicleHardware::init() {
maybeGetGrpcServiceInfo(&mPowerControllerServiceAddress);
for (auto& [_, configDeclaration] : loadConfigDeclarations()) {
VehiclePropConfig cfg = configDeclaration.config;
VehiclePropertyStore::TokenFunction tokenFunction = nullptr;
@ -723,7 +759,7 @@ std::optional<int32_t> FakeVehicleHardware::getSyncedAreaIdIfHvacDualOn(
FakeVehicleHardware::ValueResultType FakeVehicleHardware::getUserHalProp(
const VehiclePropValue& value) const {
auto propId = value.prop;
ALOGI("get(): getting value for prop %d from User HAL", propId);
ALOGI("get(): getting value for prop %s from User HAL", PROP_ID_TO_CSTR(propId));
auto result = mFakeUserHal->onGetProperty(value);
if (!result.ok()) {
@ -759,6 +795,13 @@ FakeVehicleHardware::ValueResultType FakeVehicleHardware::maybeGetSpecialValue(
int32_t propId = value.prop;
ValueResultType result;
if (mPowerControllerServiceAddress != "") {
if (mPowerPropIds.find(propId) != mPowerPropIds.end()) {
*isSpecialValue = true;
return getPowerPropFromExternalService(propId);
}
}
if (propId >= STARTING_VENDOR_CODE_PROPERTIES_FOR_TEST &&
propId < ENDING_VENDOR_CODE_PROPERTIES_FOR_TEST) {
*isSpecialValue = true;
@ -840,6 +883,58 @@ FakeVehicleHardware::ValueResultType FakeVehicleHardware::maybeGetSpecialValue(
return nullptr;
}
FakeVehicleHardware::ValueResultType FakeVehicleHardware::getPowerPropFromExternalService(
int32_t propId) const {
auto channel =
grpc::CreateChannel(mPowerControllerServiceAddress, 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;
}
}
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->status = VehiclePropertyStatus::AVAILABLE;
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->status = VehiclePropertyStatus::AVAILABLE;
result->timestamp = elapsedRealtimeNano();
return result;
}
FakeVehicleHardware::ValueResultType FakeVehicleHardware::getEchoReverseBytes(
const VehiclePropValue& value) const {
auto readResult = mServerSidePropStore->readValue(value);
@ -1086,7 +1181,7 @@ StatusCode FakeVehicleHardware::setValues(std::shared_ptr<const SetValuesCallbac
const std::vector<SetValueRequest>& requests) {
for (auto& request : requests) {
if (FAKE_VEHICLEHARDWARE_DEBUG) {
ALOGD("Set value for property ID: %d", request.value.prop);
ALOGD("Set value for property ID: %s", PROP_ID_TO_CSTR(request.value.prop));
}
// In a real VHAL implementation, you could either send the setValue request to vehicle bus
@ -1107,9 +1202,9 @@ VhalResult<void> FakeVehicleHardware::setValue(const VehiclePropValue& value) {
auto setSpecialValueResult = maybeSetSpecialValue(value, &isSpecialValue);
if (isSpecialValue) {
if (!setSpecialValueResult.ok()) {
return StatusError(getErrorCode(setSpecialValueResult))
<< StringPrintf("failed to set special value for property ID: %d, error: %s",
value.prop, getErrorMsg(setSpecialValueResult).c_str());
return StatusError(getErrorCode(setSpecialValueResult)) << StringPrintf(
"failed to set special value for property ID: %s, error: %s",
PROP_ID_TO_CSTR(value.prop), getErrorMsg(setSpecialValueResult).c_str());
}
return {};
}
@ -1148,7 +1243,7 @@ StatusCode FakeVehicleHardware::getValues(std::shared_ptr<const GetValuesCallbac
const std::vector<GetValueRequest>& requests) const {
for (auto& request : requests) {
if (FAKE_VEHICLEHARDWARE_DEBUG) {
ALOGD("getValues(%d)", request.prop.prop);
ALOGD("getValues(%s)", PROP_ID_TO_CSTR(request.prop.prop));
}
// In a real VHAL implementation, you could either send the getValue request to vehicle bus
@ -1187,8 +1282,8 @@ FakeVehicleHardware::ValueResultType FakeVehicleHardware::getValue(
if (isSpecialValue) {
if (!result.ok()) {
return StatusError(getErrorCode(result))
<< StringPrintf("failed to get special value: %d, error: %s", value.prop,
getErrorMsg(result).c_str());
<< StringPrintf("failed to get special value: %s, error: %s",
PROP_ID_TO_CSTR(value.prop), getErrorMsg(result).c_str());
} else {
return result;
}
@ -1247,6 +1342,8 @@ DumpResult FakeVehicleHardware::dump(const std::vector<std::string>& options) {
mAddExtraTestVendorConfigs = false;
result.refreshPropertyConfigs = true;
result.buffer = "successfully restored vendor configs";
} else if (EqualsIgnoreCase(option, "--dumpSub")) {
result.buffer = dumpSubscriptions();
} else {
result.buffer = StringPrintf("Invalid option: %s\n", option.c_str());
}
@ -1378,7 +1475,8 @@ std::string FakeVehicleHardware::genFakeDataCommand(const std::vector<std::strin
if (mGeneratorHub->unregisterGenerator(propId)) {
return "Linear event generator stopped successfully";
}
return StringPrintf("No linear event generator found for property: %d", propId);
return StringPrintf("No linear event generator found for property: %s",
PROP_ID_TO_CSTR(propId));
} else if (command == "--startjson") {
// --genfakedata --startjson --path path repetition
// or
@ -1648,6 +1746,26 @@ void FakeVehicleHardware::eventFromVehicleBus(const VehiclePropValue& value) {
mServerSidePropStore->writeValue(mValuePool->obtain(value));
}
std::string FakeVehicleHardware::dumpSubscriptions() {
std::scoped_lock<std::mutex> lockGuard(mLock);
std::string result = "Subscriptions: \n";
for (const auto& [interval, actionForInterval] : mActionByIntervalInNanos) {
for (const auto& propIdAreaId : actionForInterval.propIdAreaIdsToRefresh) {
const auto& refreshInfo = mRefreshInfoByPropIdAreaId[propIdAreaId];
bool vur = (refreshInfo.eventMode == VehiclePropertyStore::EventMode::ON_VALUE_CHANGE);
float sampleRateHz = 1'000'000'000. / refreshInfo.intervalInNanos;
result += StringPrintf("Continuous{property: %s, areaId: %d, rate: %lf hz, vur: %b}\n",
PROP_ID_TO_CSTR(propIdAreaId.propId), propIdAreaId.areaId,
sampleRateHz, vur);
}
}
for (const auto& propIdAreaId : mSubOnChangePropIdAreaIds) {
result += StringPrintf("OnChange{property: %s, areaId: %d}\n",
PROP_ID_TO_CSTR(propIdAreaId.propId), propIdAreaId.areaId);
}
return result;
}
std::string FakeVehicleHardware::dumpHelp() {
return "Usage: \n\n"
"[no args]: dumps (id and value) all supported properties \n"
@ -1715,8 +1833,9 @@ std::string FakeVehicleHardware::dumpOnePropertyById(int32_t propId, int32_t are
result = mServerSidePropStore->readValue(value);
}
if (!result.ok()) {
return StringPrintf("failed to read property value: %d, error: %s, code: %d\n", propId,
getErrorMsg(result).c_str(), getIntErrorCode(result));
return StringPrintf("failed to read property value: %s, error: %s, code: %d\n",
PROP_ID_TO_CSTR(propId), getErrorMsg(result).c_str(),
getIntErrorCode(result));
} else {
return result.value()->toString() + "\n";
@ -1731,7 +1850,7 @@ std::string FakeVehicleHardware::dumpListProperties() {
int rowNumber = 1;
std::string msg = StringPrintf("listing %zu properties\n", configs.size());
for (const auto& config : configs) {
msg += StringPrintf("%d: %d\n", rowNumber++, config.prop);
msg += StringPrintf("%d: %s\n", rowNumber++, PROP_ID_TO_CSTR(config.prop));
}
return msg;
}
@ -1764,7 +1883,7 @@ std::string FakeVehicleHardware::dumpSpecificProperty(const std::vector<std::str
int32_t prop = propResult.value();
auto result = mServerSidePropStore->getPropConfig(prop);
if (!result.ok()) {
msg += StringPrintf("No property %d\n", prop);
msg += StringPrintf("No property %s\n", PROP_ID_TO_CSTR(prop));
continue;
}
msg += dumpOnePropertyByConfig(rowNumber++, result.value());
@ -1950,8 +2069,9 @@ std::string FakeVehicleHardware::dumpGetPropertyWithArg(const std::vector<std::s
}
if (!result.ok()) {
return StringPrintf("failed to read property value: %d, error: %s, code: %d\n", prop.prop,
getErrorMsg(result).c_str(), getIntErrorCode(result));
return StringPrintf("failed to read property value: %s, error: %s, code: %d\n",
PROP_ID_TO_CSTR(prop.prop), getErrorMsg(result).c_str(),
getIntErrorCode(result));
}
return StringPrintf("Get property result: %s\n", result.value()->toString().c_str());
}
@ -2044,7 +2164,7 @@ std::string FakeVehicleHardware::dumpInjectEvent(const std::vector<std::string>&
eventFromVehicleBus(prop);
return StringPrintf("Event for property: %d injected", prop.prop);
return StringPrintf("Event for property: %s injected", PROP_ID_TO_CSTR(prop.prop));
}
StatusCode FakeVehicleHardware::checkHealth() {
@ -2107,7 +2227,7 @@ bool FakeVehicleHardware::isVariableUpdateRateSupported(const VehiclePropConfig&
return false;
}
void FakeVehicleHardware::refreshTimeStampForInterval(int64_t intervalInNanos) {
void FakeVehicleHardware::refreshTimestampForInterval(int64_t intervalInNanos) {
std::unordered_map<PropIdAreaId, VehiclePropertyStore::EventMode, PropIdAreaIdHash>
eventModeByPropIdAreaId;
@ -2157,7 +2277,7 @@ void FakeVehicleHardware::registerRefreshLocked(PropIdAreaId propIdAreaId,
// This is the first action for the interval, register a timer callback for that interval.
auto action = std::make_shared<RecurrentTimer::Callback>(
[this, intervalInNanos] { refreshTimeStampForInterval(intervalInNanos); });
[this, intervalInNanos] { refreshTimestampForInterval(intervalInNanos); });
mActionByIntervalInNanos[intervalInNanos] = ActionForInterval{
.propIdAreaIdsToRefresh = {propIdAreaId},
.recurrentAction = action,
@ -2199,7 +2319,7 @@ StatusCode FakeVehicleHardware::subscribePropIdAreaIdLocked(
case VehiclePropertyChangeMode::CONTINUOUS:
if (sampleRateHz == 0.f) {
ALOGE("Must not use sample rate 0 for a continuous property");
return StatusCode::INTERNAL_ERROR;
return StatusCode::INVALID_ARG;
}
// For continuous properties, we must generate a new onPropertyChange event
// periodically according to the sample rate.

View file

@ -42,7 +42,9 @@ cc_test {
"libgmock",
],
shared_libs: [
"libgrpc++",
"libjsoncpp",
"libprotobuf-cpp-full",
],
data: [
":VehicleHalDefaultProperties_JSON",

View file

@ -506,6 +506,12 @@ TEST_F(FakeVehicleHardwareTest, testGetDefaultValues) {
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++,
@ -2617,8 +2623,8 @@ TEST_F(FakeVehicleHardwareTest, testDumpSpecificPropertiesInvalidProp) {
DumpResult result = getHardware()->dump(options);
ASSERT_FALSE(result.callerShouldDumpState);
ASSERT_NE(result.buffer, "");
ASSERT_THAT(result.buffer, ContainsRegex(StringPrintf("1:.*prop: %s.*\nNo property %d\n",
prop1.c_str(), INVALID_PROP_ID)));
ASSERT_THAT(result.buffer, ContainsRegex(StringPrintf("1:.*prop: %s.*\nNo property INVALID\n",
prop1.c_str())));
}
TEST_F(FakeVehicleHardwareTest, testDumpSpecificPropertiesNoArg) {
@ -2701,8 +2707,7 @@ TEST_F(FakeVehicleHardwareTest, testDumpInjectEvent) {
{"--inject-event", propIdStr, "-i", "1234", "-t", std::to_string(timestamp)});
ASSERT_FALSE(result.callerShouldDumpState);
ASSERT_THAT(result.buffer,
ContainsRegex(StringPrintf("Event for property: %d injected", prop)));
ASSERT_THAT(result.buffer, ContainsRegex("Event for property: ENGINE_OIL_LEVEL injected"));
ASSERT_TRUE(waitForChangedProperties(prop, 0, /*count=*/1, milliseconds(1000)))
<< "No changed event received for injected event from vehicle bus";
auto events = getChangedProperties();
@ -3444,6 +3449,14 @@ TEST_F(FakeVehicleHardwareTest, testSubscribeUnusubscribe_onChange) {
<< "must not receive on change events if the propId, areaId is unsubscribed";
}
TEST_F(FakeVehicleHardwareTest, testSubscribeContinuous_rate0_mustReturnInvalidArg) {
int32_t propSpeed = toInt(VehicleProperty::PERF_VEHICLE_SPEED);
int32_t areaId = 0;
auto status = getHardware()->subscribe(newSubscribeOptions(propSpeed, areaId, 0));
ASSERT_EQ(status, StatusCode::INVALID_ARG);
}
TEST_F(FakeVehicleHardwareTest, testSetHvacTemperatureValueSuggestion) {
float CELSIUS = static_cast<float>(toInt(VehicleUnit::CELSIUS));
float FAHRENHEIT = static_cast<float>(toInt(VehicleUnit::FAHRENHEIT));

View file

@ -19,6 +19,7 @@
#include <aidl/android/hardware/automotive/vehicle/AutomaticEmergencyBrakingState.h>
#include <aidl/android/hardware/automotive/vehicle/BlindSpotWarningState.h>
#include <aidl/android/hardware/automotive/vehicle/CameraServiceState.h>
#include <aidl/android/hardware/automotive/vehicle/CrossTrafficMonitoringWarningState.h>
#include <aidl/android/hardware/automotive/vehicle/CruiseControlCommand.h>
#include <aidl/android/hardware/automotive/vehicle/CruiseControlState.h>
@ -50,6 +51,7 @@
#include <aidl/android/hardware/automotive/vehicle/LaneDepartureWarningState.h>
#include <aidl/android/hardware/automotive/vehicle/LaneKeepAssistState.h>
#include <aidl/android/hardware/automotive/vehicle/LocationCharacterization.h>
#include <aidl/android/hardware/automotive/vehicle/LowSpeedAutomaticEmergencyBrakingState.h>
#include <aidl/android/hardware/automotive/vehicle/LowSpeedCollisionWarningState.h>
#include <aidl/android/hardware/automotive/vehicle/Obd2CommonIgnitionMonitors.h>
#include <aidl/android/hardware/automotive/vehicle/Obd2FuelSystemStatus.h>
@ -64,6 +66,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>

View file

@ -235,7 +235,7 @@ class VehiclePropValuePool {
bool isDisposable(aidl::android::hardware::automotive::vehicle::VehiclePropertyType type,
size_t vectorSize) const {
return vectorSize > mMaxRecyclableVectorSize || isComplexType(type);
return vectorSize == 0 || vectorSize > mMaxRecyclableVectorSize || isComplexType(type);
}
RecyclableType obtainDisposable(

View file

@ -124,7 +124,6 @@ createVehiclePropValueVec(aidl::android::hardware::automotive::vehicle::VehicleP
break; // Valid, but nothing to do.
default:
ALOGE("createVehiclePropValue: unknown type: %d", toInt(type));
val.reset(nullptr);
}
return val;
}
@ -334,6 +333,23 @@ inline std::string propIdToString(int32_t propId) {
static_cast<aidl::android::hardware::automotive::vehicle::VehicleProperty>(propId));
}
template <typename T>
void roundToNearestResolution(std::vector<T>& arrayToSanitize, float resolution) {
if (resolution == 0) {
return;
}
for (size_t i = 0; i < arrayToSanitize.size(); i++) {
arrayToSanitize[i] = (T)((std::round(arrayToSanitize[i] / resolution)) * resolution);
}
}
inline void sanitizeByResolution(aidl::android::hardware::automotive::vehicle::RawPropValues* value,
float resolution) {
roundToNearestResolution(value->int32Values, resolution);
roundToNearestResolution(value->floatValues, resolution);
roundToNearestResolution(value->int64Values, resolution);
}
} // namespace vehicle
} // namespace automotive
} // namespace hardware

View file

@ -55,13 +55,6 @@ VehiclePropValuePool::RecyclableType VehiclePropValuePool::obtain(const VehicleP
int propId = src.prop;
VehiclePropertyType type = getPropType(propId);
size_t vectorSize = getVehicleRawValueVectorSize(src.value, type);
if (vectorSize == 0 && !isComplexType(type)) {
ALOGW("empty vehicle prop value, contains no content");
ALOGW("empty vehicle prop value, contains no content, prop: %d", propId);
// Return any empty VehiclePropValue.
return RecyclableType{new VehiclePropValue{}, mDisposableDeleter};
}
auto dest = obtain(type, vectorSize);
dest->prop = propId;

View file

@ -267,6 +267,20 @@ TEST_F(VehicleObjectPoolTest, testObtainCopyInt32Values) {
ASSERT_EQ(*gotValue, prop);
}
TEST_F(VehicleObjectPoolTest, testObtainCopyInt32ValuesEmptyArray) {
VehiclePropValue prop{
// INT32_VEC property.
.prop = toInt(VehicleProperty::INFO_FUEL_TYPE),
.areaId = 2,
.timestamp = 3,
.value = {.int32Values = {}},
};
auto gotValue = mValuePool->obtain(prop);
ASSERT_NE(gotValue, nullptr);
ASSERT_EQ(*gotValue, prop);
}
TEST_F(VehicleObjectPoolTest, testObtainCopyInt64Values) {
VehiclePropValue prop{
// INT64_VEC property.

View file

@ -66,6 +66,7 @@ cc_library {
],
header_libs: [
"IVehicleHardware",
"IVehicleGeneratedHeaders",
],
shared_libs: [
"libbinder_ndk",

View file

@ -49,6 +49,9 @@ class DefaultVehicleHal final : public aidl::android::hardware::automotive::vehi
explicit DefaultVehicleHal(std::unique_ptr<IVehicleHardware> hardware);
// Test-only
DefaultVehicleHal(std::unique_ptr<IVehicleHardware> hardware, int32_t testInterfaceVersion);
~DefaultVehicleHal();
ndk::ScopedAStatus getAllPropConfigs(
@ -153,6 +156,8 @@ class DefaultVehicleHal final : public aidl::android::hardware::automotive::vehi
mPropertyChangeEventsBatchingConsumer;
// Only set once during initialization.
std::chrono::nanoseconds mEventBatchingWindow;
// Only used for testing.
int32_t mTestInterfaceVersion = 0;
std::mutex mLock;
std::unordered_map<const AIBinder*, std::unique_ptr<OnBinderDiedContext>> mOnBinderDiedContexts
@ -227,6 +232,8 @@ class DefaultVehicleHal final : public aidl::android::hardware::automotive::vehi
std::vector<aidl::android::hardware::automotive::vehicle::VehiclePropValue>&&
batchedEvents);
int32_t getVhalInterfaceVersion();
// Puts the property change events into a queue so that they can handled in batch.
static void batchPropertyChangeEvent(
const std::weak_ptr<ConcurrentQueue<

View file

@ -25,6 +25,8 @@
#include <android-base/result.h>
#include <android-base/thread_annotations.h>
#include <cmath>
#include <limits>
#include <mutex>
#include <optional>
#include <unordered_map>
@ -39,6 +41,7 @@ namespace vehicle {
// A structure to represent subscription config for one subscription client.
struct SubConfig {
float sampleRateHz;
float resolution;
bool enableVur;
};
@ -47,14 +50,19 @@ class ContSubConfigs final {
public:
using ClientIdType = const AIBinder*;
void addClient(const ClientIdType& clientId, float sampleRateHz, bool enableVur);
void addClient(const ClientIdType& clientId, const SubConfig& subConfig);
void removeClient(const ClientIdType& clientId);
float getMaxSampleRateHz() const;
float getMinRequiredResolution() const;
bool isVurEnabled() const;
bool isVurEnabledForClient(const ClientIdType& clientId);
bool isVurEnabledForClient(const ClientIdType& clientId) const;
float getResolutionForClient(const ClientIdType& clientId) const;
private:
float mMaxSampleRateHz = 0.;
// Baseline for resolution is maximum possible float. We want to sanitize to the highest
// requested resolution, which is the smallest float value for resolution.
float mMinRequiredResolution = std::numeric_limits<float>::max();
bool mEnableVur;
std::unordered_map<ClientIdType, SubConfig> mConfigByClient;
@ -117,6 +125,9 @@ class SubscriptionManager final {
// Checks whether the sample rate is valid.
static bool checkSampleRateHz(float sampleRateHz);
// Checks whether the resolution is valid.
static bool checkResolution(float resolution);
private:
// Friend class for testing.
friend class DefaultVehicleHalTest;
@ -153,8 +164,8 @@ class SubscriptionManager final {
VhalResult<void> addContinuousSubscriberLocked(const ClientIdType& clientId,
const PropIdAreaId& propIdAreaId,
float sampleRateHz, bool enableVur)
REQUIRES(mLock);
float sampleRateHz, float resolution,
bool enableVur) REQUIRES(mLock);
VhalResult<void> addOnChangeSubscriberLocked(const PropIdAreaId& propIdAreaId) REQUIRES(mLock);
// Removes the subscription client for the continuous [propId, areaId].
VhalResult<void> removeContinuousSubscriberLocked(const ClientIdType& clientId,

Some files were not shown because too many files have changed in this diff Show more