Merge changes from topic "proto_package_name"
* changes:
A more generalized package name for VHal proto IDLs
Protobuf message converter should be a public utility library
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 76594fb..1eca2a1 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -84,3 +84,4 @@
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/vendor/bin/hw/android.hardware.cas@1.1*)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/vendor/etc/init/android.hardware.cas@1.1*)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/vendor/etc/vintf/manifest/android.hardware.cas@1.1*)
+$(call add-clean-step, rm -rf $(OUT_DIR)/soong/.intermediates/hardware/interfaces/wifi/1.4/android.hardware.wifi@1.4-adapter_genc++/)
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index 0140275..6740bb5 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -2,6 +2,7 @@
ignore_merged_commits = true
[Builtin Hooks]
+bpfmt = true
clang_format = true
[Hook Scripts]
diff --git a/audio/6.0/IDevice.hal b/audio/6.0/IDevice.hal
index 520e776..c2e310c 100644
--- a/audio/6.0/IDevice.hal
+++ b/audio/6.0/IDevice.hal
@@ -168,6 +168,25 @@
generates (Result retval, AudioPatchHandle patch);
/**
+ * Updates an audio patch.
+ *
+ * Use of this function is preferred to releasing and re-creating a patch
+ * as the HAL module can figure out a way of switching the route without
+ * causing audio disruption.
+ *
+ * @param previousPatch handle of the previous patch to update.
+ * @param sources new patch sources.
+ * @param sinks new patch sinks.
+ * @return retval operation completion status.
+ * @return patch updated patch handle.
+ */
+ updateAudioPatch(
+ AudioPatchHandle previousPatch,
+ vec<AudioPortConfig> sources,
+ vec<AudioPortConfig> sinks) generates (
+ Result retval, AudioPatchHandle patch);
+
+ /**
* Release an audio patch.
*
* @param patch patch handle.
@@ -286,9 +305,37 @@
* all currently allocated resources. It is recommended to close
* the device on the client side as soon as it is becomes unused.
*
+ * Note that all streams must be closed by the client before
+ * attempting to close the device they belong to.
+ *
* @return retval OK in case the success.
- * INVALID_STATE if the device was already closed.
+ * INVALID_STATE if the device was already closed
+ * or there are streams currently opened.
*/
@exit
close() generates (Result retval);
+
+ /**
+ * Applies an audio effect to an audio device.
+ *
+ * @param device identifies the sink or source device this effect must be applied to.
+ * "device" is the AudioPortHandle indicated for the device when the audio
+ * patch connecting that device was created.
+ * @param effectId effect ID (obtained from IEffectsFactory.createEffect) of
+ * the effect to add.
+ * @return retval operation completion status.
+ */
+ addDeviceEffect(AudioPortHandle device, uint64_t effectId) generates (Result retval);
+
+ /**
+ * Stops applying an audio effect to an audio device.
+ *
+ * @param device identifies the sink or source device this effect was applied to.
+ * "device" is the AudioPortHandle indicated for the device when the audio
+ * patch is created at the audio HAL.
+ * @param effectId effect ID (obtained from IEffectsFactory.createEffect) of
+ * the effect.
+ * @return retval operation completion status.
+ */
+ removeDeviceEffect(AudioPortHandle device, uint64_t effectId) generates (Result retval);
};
diff --git a/audio/6.0/IStream.hal b/audio/6.0/IStream.hal
index d7d3c84..2ea1ab3 100644
--- a/audio/6.0/IStream.hal
+++ b/audio/6.0/IStream.hal
@@ -274,6 +274,7 @@
*
* @param minSizeFrames minimum buffer size requested. The actual buffer
* size returned in struct MmapBufferInfo can be larger.
+ * The size must be a positive value.
* @return retval OK in case the success.
* NOT_SUPPORTED on non mmap mode streams
* NOT_INITIALIZED in case of memory allocation error
diff --git a/audio/common/6.0/Android.bp b/audio/common/6.0/Android.bp
index 1a4e054..94f1cf8 100644
--- a/audio/common/6.0/Android.bp
+++ b/audio/common/6.0/Android.bp
@@ -12,6 +12,6 @@
interfaces: [
"android.hidl.safe_union@1.0",
],
- gen_java: false,
+ gen_java: true,
gen_java_constants: true,
}
diff --git a/audio/common/6.0/types.hal b/audio/common/6.0/types.hal
index 0c97c36..e69d969 100644
--- a/audio/common/6.0/types.hal
+++ b/audio/common/6.0/types.hal
@@ -156,6 +156,11 @@
@export(name="audio_session_t", value_prefix="AUDIO_SESSION_")
enum AudioSessionConsts : int32_t {
/**
+ * Session for effects attached to a particular sink or source audio device
+ * (e.g an effect only applied to a speaker)
+ */
+ DEVICE = -2,
+ /**
* Session for effects attached to a particular output stream
* (value must be less than 0)
*/
@@ -734,6 +739,7 @@
MMAP_NOIRQ = 0x10, // input operates in MMAP no IRQ mode.
VOIP_TX = 0x20, // preferred input for VoIP calls.
HW_AV_SYNC = 0x40, // input connected to an output that uses a hardware A/V sync
+ DIRECT = 0x80, // for acquiring encoded streams
};
@export(name="audio_usage_t", value_prefix="AUDIO_USAGE_")
@@ -754,6 +760,7 @@
GAME = 14,
VIRTUAL_SOURCE = 15,
ASSISTANT = 16,
+ CALL_ASSISTANT = 17,
};
/** Type of audio generated by an application. */
diff --git a/audio/common/all-versions/default/service/Android.bp b/audio/common/all-versions/default/service/Android.bp
index 4565730..f58a599 100644
--- a/audio/common/all-versions/default/service/Android.bp
+++ b/audio/common/all-versions/default/service/Android.bp
@@ -41,6 +41,7 @@
"android.hardware.soundtrigger@2.0",
"android.hardware.soundtrigger@2.1",
"android.hardware.soundtrigger@2.2",
+ "android.hardware.soundtrigger@2.3",
],
}
diff --git a/audio/common/all-versions/default/service/service.cpp b/audio/common/all-versions/default/service/service.cpp
index 2730f3b..00bcb19 100644
--- a/audio/common/all-versions/default/service/service.cpp
+++ b/audio/common/all-versions/default/service/service.cpp
@@ -29,6 +29,7 @@
#include <android/hardware/soundtrigger/2.0/ISoundTriggerHw.h>
#include <android/hardware/soundtrigger/2.1/ISoundTriggerHw.h>
#include <android/hardware/soundtrigger/2.2/ISoundTriggerHw.h>
+#include <android/hardware/soundtrigger/2.3/ISoundTriggerHw.h>
#include <binder/ProcessState.h>
#include <cutils/properties.h>
#include <hidl/HidlTransportSupport.h>
@@ -78,9 +79,9 @@
"Could not register audio effect API");
// clang-format on
- ALOGW_IF((registerPassthroughServiceImplementations<soundtrigger::V2_2::ISoundTriggerHw,
- soundtrigger::V2_1::ISoundTriggerHw,
- soundtrigger::V2_0::ISoundTriggerHw>()),
+ ALOGW_IF((registerPassthroughServiceImplementations<
+ soundtrigger::V2_3::ISoundTriggerHw, soundtrigger::V2_2::ISoundTriggerHw,
+ soundtrigger::V2_1::ISoundTriggerHw, soundtrigger::V2_0::ISoundTriggerHw>()),
"Could not register soundtrigger API");
ALOGW_IF(registerPassthroughServiceImplementations<
diff --git a/audio/core/all-versions/default/Conversions.cpp b/audio/core/all-versions/default/Conversions.cpp
index 11872c0..eddff55 100644
--- a/audio/core/all-versions/default/Conversions.cpp
+++ b/audio/core/all-versions/default/Conversions.cpp
@@ -19,6 +19,7 @@
#include <stdio.h>
#include <log/log.h>
+#include <media/AudioContainers.h>
namespace android {
namespace hardware {
@@ -31,26 +32,22 @@
char halAddress[AUDIO_DEVICE_MAX_ADDRESS_LEN];
memset(halAddress, 0, sizeof(halAddress));
uint32_t halDevice = static_cast<uint32_t>(address.device);
- const bool isInput = (halDevice & AUDIO_DEVICE_BIT_IN) != 0;
- if (isInput) halDevice &= ~AUDIO_DEVICE_BIT_IN;
- if ((!isInput && (halDevice & AUDIO_DEVICE_OUT_ALL_A2DP) != 0) ||
- (isInput && (halDevice & AUDIO_DEVICE_IN_BLUETOOTH_A2DP) != 0)) {
+ if (getAudioDeviceOutAllA2dpSet().count(halDevice) > 0 ||
+ halDevice == AUDIO_DEVICE_IN_BLUETOOTH_A2DP) {
snprintf(halAddress, sizeof(halAddress), "%02X:%02X:%02X:%02X:%02X:%02X",
address.address.mac[0], address.address.mac[1], address.address.mac[2],
address.address.mac[3], address.address.mac[4], address.address.mac[5]);
- } else if ((!isInput && (halDevice & AUDIO_DEVICE_OUT_IP) != 0) ||
- (isInput && (halDevice & AUDIO_DEVICE_IN_IP) != 0)) {
+ } else if (halDevice == AUDIO_DEVICE_OUT_IP || halDevice == AUDIO_DEVICE_IN_IP) {
snprintf(halAddress, sizeof(halAddress), "%d.%d.%d.%d", address.address.ipv4[0],
address.address.ipv4[1], address.address.ipv4[2], address.address.ipv4[3]);
- } else if ((!isInput && (halDevice & AUDIO_DEVICE_OUT_ALL_USB) != 0) ||
- (isInput && (halDevice & AUDIO_DEVICE_IN_ALL_USB) != 0)) {
+ } else if (getAudioDeviceOutAllUsbSet().count(halDevice) > 0 ||
+ getAudioDeviceInAllUsbSet().count(halDevice) > 0) {
snprintf(halAddress, sizeof(halAddress), "card=%d;device=%d", address.address.alsa.card,
address.address.alsa.device);
- } else if ((!isInput && (halDevice & AUDIO_DEVICE_OUT_BUS) != 0) ||
- (isInput && (halDevice & AUDIO_DEVICE_IN_BUS) != 0)) {
+ } else if (halDevice == AUDIO_DEVICE_OUT_BUS || halDevice == AUDIO_DEVICE_IN_BUS) {
snprintf(halAddress, sizeof(halAddress), "%s", address.busAddress.c_str());
- } else if ((!isInput && (halDevice & AUDIO_DEVICE_OUT_REMOTE_SUBMIX)) != 0 ||
- (isInput && (halDevice & AUDIO_DEVICE_IN_REMOTE_SUBMIX) != 0)) {
+ } else if (halDevice == AUDIO_DEVICE_OUT_REMOTE_SUBMIX ||
+ halDevice == AUDIO_DEVICE_IN_REMOTE_SUBMIX) {
snprintf(halAddress, sizeof(halAddress), "%s", address.rSubmixAddress.c_str());
}
return halAddress;
@@ -67,32 +64,28 @@
return OK;
}
- const bool isInput = (device & AUDIO_DEVICE_BIT_IN) != 0;
- if (isInput) device &= ~AUDIO_DEVICE_BIT_IN;
- if ((!isInput && (device & AUDIO_DEVICE_OUT_ALL_A2DP) != 0) ||
- (isInput && (device & AUDIO_DEVICE_IN_BLUETOOTH_A2DP) != 0)) {
+ if (getAudioDeviceOutAllA2dpSet().count(device) > 0 ||
+ device == AUDIO_DEVICE_IN_BLUETOOTH_A2DP) {
int status =
sscanf(halAddress, "%hhX:%hhX:%hhX:%hhX:%hhX:%hhX", &address->address.mac[0],
&address->address.mac[1], &address->address.mac[2], &address->address.mac[3],
&address->address.mac[4], &address->address.mac[5]);
return status == 6 ? OK : BAD_VALUE;
- } else if ((!isInput && (device & AUDIO_DEVICE_OUT_IP) != 0) ||
- (isInput && (device & AUDIO_DEVICE_IN_IP) != 0)) {
+ } else if (device == AUDIO_DEVICE_OUT_IP || device == AUDIO_DEVICE_IN_IP) {
int status =
sscanf(halAddress, "%hhu.%hhu.%hhu.%hhu", &address->address.ipv4[0],
&address->address.ipv4[1], &address->address.ipv4[2], &address->address.ipv4[3]);
return status == 4 ? OK : BAD_VALUE;
- } else if ((!isInput && (device & AUDIO_DEVICE_OUT_ALL_USB)) != 0 ||
- (isInput && (device & AUDIO_DEVICE_IN_ALL_USB)) != 0) {
+ } else if (getAudioDeviceOutAllUsbSet().count(device) > 0 ||
+ getAudioDeviceInAllUsbSet().count(device) > 0) {
int status = sscanf(halAddress, "card=%d;device=%d", &address->address.alsa.card,
&address->address.alsa.device);
return status == 2 ? OK : BAD_VALUE;
- } else if ((!isInput && (device & AUDIO_DEVICE_OUT_BUS) != 0) ||
- (isInput && (device & AUDIO_DEVICE_IN_BUS) != 0)) {
+ } else if (device == AUDIO_DEVICE_OUT_BUS || device == AUDIO_DEVICE_IN_BUS) {
address->busAddress = halAddress;
return OK;
- } else if ((!isInput && (device & AUDIO_DEVICE_OUT_REMOTE_SUBMIX)) != 0 ||
- (isInput && (device & AUDIO_DEVICE_IN_REMOTE_SUBMIX) != 0)) {
+ } else if (device == AUDIO_DEVICE_OUT_REMOTE_SUBMIX ||
+ device == AUDIO_DEVICE_IN_REMOTE_SUBMIX) {
address->rSubmixAddress = halAddress;
return OK;
}
diff --git a/audio/core/all-versions/default/Device.cpp b/audio/core/all-versions/default/Device.cpp
index 5ea4c8d..47e31c1 100644
--- a/audio/core/all-versions/default/Device.cpp
+++ b/audio/core/all-versions/default/Device.cpp
@@ -18,6 +18,7 @@
#include "core/default/Device.h"
#include <HidlUtils.h>
+#include "common/all-versions/default/EffectMap.h"
#include "core/default/Conversions.h"
#include "core/default/StreamIn.h"
#include "core/default/StreamOut.h"
@@ -25,6 +26,7 @@
//#define LOG_NDEBUG 0
+#include <inttypes.h>
#include <memory.h>
#include <string.h>
#include <algorithm>
@@ -53,10 +55,14 @@
void Device::closeInputStream(audio_stream_in_t* stream) {
mDevice->close_input_stream(mDevice, stream);
+ LOG_ALWAYS_FATAL_IF(mOpenedStreamsCount == 0, "mOpenedStreamsCount is already 0");
+ --mOpenedStreamsCount;
}
void Device::closeOutputStream(audio_stream_out_t* stream) {
mDevice->close_output_stream(mDevice, stream);
+ LOG_ALWAYS_FATAL_IF(mOpenedStreamsCount == 0, "mOpenedStreamsCount is already 0");
+ --mOpenedStreamsCount;
}
char* Device::halGetParameters(const char* keys) {
@@ -80,26 +86,29 @@
ALOGW("Can not set a master volume (%f) outside [0,1]", volume);
return Result::INVALID_ARGUMENTS;
}
- return analyzeStatus("set_master_volume", mDevice->set_master_volume(mDevice, volume));
+ return analyzeStatus("set_master_volume", mDevice->set_master_volume(mDevice, volume),
+ {ENOSYS} /*ignore*/);
}
Return<void> Device::getMasterVolume(getMasterVolume_cb _hidl_cb) {
Result retval(Result::NOT_SUPPORTED);
float volume = 0;
if (mDevice->get_master_volume != NULL) {
- retval = analyzeStatus("get_master_volume", mDevice->get_master_volume(mDevice, &volume));
+ retval = analyzeStatus("get_master_volume", mDevice->get_master_volume(mDevice, &volume),
+ {ENOSYS} /*ignore*/);
}
_hidl_cb(retval, volume);
return Void();
}
Return<Result> Device::setMicMute(bool mute) {
- return analyzeStatus("set_mic_mute", mDevice->set_mic_mute(mDevice, mute));
+ return analyzeStatus("set_mic_mute", mDevice->set_mic_mute(mDevice, mute), {ENOSYS} /*ignore*/);
}
Return<void> Device::getMicMute(getMicMute_cb _hidl_cb) {
bool mute = false;
- Result retval = analyzeStatus("get_mic_mute", mDevice->get_mic_mute(mDevice, &mute));
+ Result retval = analyzeStatus("get_mic_mute", mDevice->get_mic_mute(mDevice, &mute),
+ {ENOSYS} /*ignore*/);
_hidl_cb(retval, mute);
return Void();
}
@@ -107,7 +116,8 @@
Return<Result> Device::setMasterMute(bool mute) {
Result retval(Result::NOT_SUPPORTED);
if (mDevice->set_master_mute != NULL) {
- retval = analyzeStatus("set_master_mute", mDevice->set_master_mute(mDevice, mute));
+ retval = analyzeStatus("set_master_mute", mDevice->set_master_mute(mDevice, mute),
+ {ENOSYS} /*ignore*/);
}
return retval;
}
@@ -116,7 +126,8 @@
Result retval(Result::NOT_SUPPORTED);
bool mute = false;
if (mDevice->get_master_mute != NULL) {
- retval = analyzeStatus("get_master_mute", mDevice->get_master_mute(mDevice, &mute));
+ retval = analyzeStatus("get_master_mute", mDevice->get_master_mute(mDevice, &mute),
+ {ENOSYS} /*ignore*/);
}
_hidl_cb(retval, mute);
return Void();
@@ -158,6 +169,7 @@
sp<IStreamOut> streamOut;
if (status == OK) {
streamOut = new StreamOut(this, halStream);
+ ++mOpenedStreamsCount;
}
HidlUtils::audioConfigFromHal(halConfig, suggestedConfig);
return {analyzeStatus("open_output_stream", status, {EINVAL} /*ignore*/), streamOut};
@@ -184,6 +196,7 @@
sp<IStreamIn> streamIn;
if (status == OK) {
streamIn = new StreamIn(this, halStream);
+ ++mOpenedStreamsCount;
}
HidlUtils::audioConfigFromHal(halConfig, suggestedConfig);
return {analyzeStatus("open_input_stream", status, {EINVAL} /*ignore*/), streamIn};
@@ -256,12 +269,21 @@
Return<void> Device::createAudioPatch(const hidl_vec<AudioPortConfig>& sources,
const hidl_vec<AudioPortConfig>& sinks,
createAudioPatch_cb _hidl_cb) {
+ auto [retval, patch] = createOrUpdateAudioPatch(
+ static_cast<AudioPatchHandle>(AudioHandleConsts::AUDIO_PATCH_HANDLE_NONE), sources,
+ sinks);
+ _hidl_cb(retval, patch);
+ return Void();
+}
+
+std::tuple<Result, AudioPatchHandle> Device::createOrUpdateAudioPatch(
+ AudioPatchHandle patch, const hidl_vec<AudioPortConfig>& sources,
+ const hidl_vec<AudioPortConfig>& sinks) {
Result retval(Result::NOT_SUPPORTED);
- AudioPatchHandle patch = 0;
if (version() >= AUDIO_DEVICE_API_VERSION_3_0) {
std::unique_ptr<audio_port_config[]> halSources(HidlUtils::audioPortConfigsToHal(sources));
std::unique_ptr<audio_port_config[]> halSinks(HidlUtils::audioPortConfigsToHal(sinks));
- audio_patch_handle_t halPatch = AUDIO_PATCH_HANDLE_NONE;
+ audio_patch_handle_t halPatch = static_cast<audio_patch_handle_t>(patch);
retval = analyzeStatus("create_audio_patch",
mDevice->create_audio_patch(mDevice, sources.size(), &halSources[0],
sinks.size(), &halSinks[0], &halPatch));
@@ -269,8 +291,7 @@
patch = static_cast<AudioPatchHandle>(halPatch);
}
}
- _hidl_cb(retval, patch);
- return Void();
+ return {retval, patch};
}
Return<Result> Device::releaseAudioPatch(int32_t patch) {
@@ -383,7 +404,7 @@
#endif
Result Device::doClose() {
- if (mIsClosed) return Result::INVALID_STATE;
+ if (mIsClosed || mOpenedStreamsCount != 0) return Result::INVALID_STATE;
mIsClosed = true;
return analyzeStatus("close", audio_hw_device_close(mDevice));
}
@@ -392,6 +413,52 @@
Return<Result> Device::close() {
return doClose();
}
+
+Return<Result> Device::addDeviceEffect(AudioPortHandle device, uint64_t effectId) {
+ if (version() < AUDIO_DEVICE_API_VERSION_3_1 || mDevice->add_device_effect == nullptr) {
+ return Result::NOT_SUPPORTED;
+ }
+
+ effect_handle_t halEffect = EffectMap::getInstance().get(effectId);
+ if (halEffect != NULL) {
+ return analyzeStatus("add_device_effect",
+ mDevice->add_device_effect(
+ mDevice, static_cast<audio_port_handle_t>(device), halEffect));
+ } else {
+ ALOGW("%s Invalid effect ID passed from client: %" PRIu64 "", __func__, effectId);
+ return Result::INVALID_ARGUMENTS;
+ }
+}
+
+Return<Result> Device::removeDeviceEffect(AudioPortHandle device, uint64_t effectId) {
+ if (version() < AUDIO_DEVICE_API_VERSION_3_1 || mDevice->remove_device_effect == nullptr) {
+ return Result::NOT_SUPPORTED;
+ }
+
+ effect_handle_t halEffect = EffectMap::getInstance().get(effectId);
+ if (halEffect != NULL) {
+ return analyzeStatus("remove_device_effect",
+ mDevice->remove_device_effect(
+ mDevice, static_cast<audio_port_handle_t>(device), halEffect));
+ } else {
+ ALOGW("%s Invalid effect ID passed from client: %" PRIu64 "", __func__, effectId);
+ return Result::INVALID_ARGUMENTS;
+ }
+}
+
+Return<void> Device::updateAudioPatch(int32_t previousPatch,
+ const hidl_vec<AudioPortConfig>& sources,
+ const hidl_vec<AudioPortConfig>& sinks,
+ createAudioPatch_cb _hidl_cb) {
+ if (previousPatch != static_cast<int32_t>(AudioHandleConsts::AUDIO_PATCH_HANDLE_NONE)) {
+ auto [retval, patch] = createOrUpdateAudioPatch(previousPatch, sources, sinks);
+ _hidl_cb(retval, patch);
+ } else {
+ _hidl_cb(Result::INVALID_ARGUMENTS, previousPatch);
+ }
+ return Void();
+}
+
#endif
} // namespace implementation
diff --git a/audio/core/all-versions/default/PrimaryDevice.cpp b/audio/core/all-versions/default/PrimaryDevice.cpp
index 3cf0932..679f85d 100644
--- a/audio/core/all-versions/default/PrimaryDevice.cpp
+++ b/audio/core/all-versions/default/PrimaryDevice.cpp
@@ -168,6 +168,21 @@
Return<Result> PrimaryDevice::close() {
return mDevice->close();
}
+
+Return<Result> PrimaryDevice::addDeviceEffect(AudioPortHandle device, uint64_t effectId) {
+ return mDevice->addDeviceEffect(device, effectId);
+}
+
+Return<Result> PrimaryDevice::removeDeviceEffect(AudioPortHandle device, uint64_t effectId) {
+ return mDevice->removeDeviceEffect(device, effectId);
+}
+
+Return<void> PrimaryDevice::updateAudioPatch(int32_t previousPatch,
+ const hidl_vec<AudioPortConfig>& sources,
+ const hidl_vec<AudioPortConfig>& sinks,
+ updateAudioPatch_cb _hidl_cb) {
+ return mDevice->updateAudioPatch(previousPatch, sources, sinks, _hidl_cb);
+}
#endif
// Methods from ::android::hardware::audio::CPP_VERSION::IPrimaryDevice follow.
diff --git a/audio/core/all-versions/default/StreamOut.cpp b/audio/core/all-versions/default/StreamOut.cpp
index 396d354..1a2a764 100644
--- a/audio/core/all-versions/default/StreamOut.cpp
+++ b/audio/core/all-versions/default/StreamOut.cpp
@@ -318,7 +318,8 @@
ALOGW("Can not set a stream output volume {%f, %f} outside [0,1]", left, right);
return Result::INVALID_ARGUMENTS;
}
- return Stream::analyzeStatus("set_volume", mStream->set_volume(mStream, left, right));
+ return Stream::analyzeStatus("set_volume", mStream->set_volume(mStream, left, right),
+ {ENOSYS} /*ignore*/);
}
Return<void> StreamOut::prepareForWriting(uint32_t frameSize, uint32_t framesCount,
@@ -403,7 +404,8 @@
Return<void> StreamOut::getRenderPosition(getRenderPosition_cb _hidl_cb) {
uint32_t halDspFrames;
Result retval = Stream::analyzeStatus("get_render_position",
- mStream->get_render_position(mStream, &halDspFrames));
+ mStream->get_render_position(mStream, &halDspFrames),
+ {ENOSYS} /*ignore*/);
_hidl_cb(retval, halDspFrames);
return Void();
}
@@ -413,7 +415,8 @@
int64_t timestampUs = 0;
if (mStream->get_next_write_timestamp != NULL) {
retval = Stream::analyzeStatus("get_next_write_timestamp",
- mStream->get_next_write_timestamp(mStream, ×tampUs));
+ mStream->get_next_write_timestamp(mStream, ×tampUs),
+ {ENOSYS} /*ignore*/);
}
_hidl_cb(retval, timestampUs);
return Void();
@@ -427,7 +430,7 @@
if (result == 0) {
mCallback = callback;
}
- return Stream::analyzeStatus("set_callback", result);
+ return Stream::analyzeStatus("set_callback", result, {ENOSYS} /*ignore*/);
}
Return<Result> StreamOut::clearCallback() {
@@ -473,13 +476,15 @@
}
Return<Result> StreamOut::pause() {
- return mStream->pause != NULL ? Stream::analyzeStatus("pause", mStream->pause(mStream))
- : Result::NOT_SUPPORTED;
+ return mStream->pause != NULL
+ ? Stream::analyzeStatus("pause", mStream->pause(mStream), {ENOSYS} /*ignore*/)
+ : Result::NOT_SUPPORTED;
}
Return<Result> StreamOut::resume() {
- return mStream->resume != NULL ? Stream::analyzeStatus("resume", mStream->resume(mStream))
- : Result::NOT_SUPPORTED;
+ return mStream->resume != NULL
+ ? Stream::analyzeStatus("resume", mStream->resume(mStream), {ENOSYS} /*ignore*/)
+ : Result::NOT_SUPPORTED;
}
Return<bool> StreamOut::supportsDrain() {
@@ -488,14 +493,17 @@
Return<Result> StreamOut::drain(AudioDrain type) {
return mStream->drain != NULL
- ? Stream::analyzeStatus(
- "drain", mStream->drain(mStream, static_cast<audio_drain_type_t>(type)))
- : Result::NOT_SUPPORTED;
+ ? Stream::analyzeStatus(
+ "drain",
+ mStream->drain(mStream, static_cast<audio_drain_type_t>(type)),
+ {ENOSYS} /*ignore*/)
+ : Result::NOT_SUPPORTED;
}
Return<Result> StreamOut::flush() {
- return mStream->flush != NULL ? Stream::analyzeStatus("flush", mStream->flush(mStream))
- : Result::NOT_SUPPORTED;
+ return mStream->flush != NULL
+ ? Stream::analyzeStatus("flush", mStream->flush(mStream), {ENOSYS} /*ignore*/)
+ : Result::NOT_SUPPORTED;
}
// static
@@ -505,7 +513,7 @@
// to return it sometimes. EAGAIN may be returned by A2DP audio HAL
// implementation. ENODATA can also be reported while the writer is
// continuously querying it, but the stream has been stopped.
- static const std::vector<int> ignoredErrors{EINVAL, EAGAIN, ENODATA};
+ static const std::vector<int> ignoredErrors{EINVAL, EAGAIN, ENODATA, ENOSYS};
Result retval(Result::NOT_SUPPORTED);
if (stream->get_presentation_position == NULL) return retval;
struct timespec halTimeStamp;
diff --git a/audio/core/all-versions/default/include/core/default/Device.h b/audio/core/all-versions/default/include/core/default/Device.h
index dc53a39..b0e72d9 100644
--- a/audio/core/all-versions/default/include/core/default/Device.h
+++ b/audio/core/all-versions/default/include/core/default/Device.h
@@ -116,8 +116,12 @@
#endif
#if MAJOR_VERSION >= 6
Return<Result> close() override;
+ Return<Result> addDeviceEffect(AudioPortHandle device, uint64_t effectId) override;
+ Return<Result> removeDeviceEffect(AudioPortHandle device, uint64_t effectId) override;
+ Return<void> updateAudioPatch(int32_t previousPatch, const hidl_vec<AudioPortConfig>& sources,
+ const hidl_vec<AudioPortConfig>& sinks,
+ createAudioPatch_cb _hidl_cb) override;
#endif
-
Return<void> debug(const hidl_handle& fd, const hidl_vec<hidl_string>& options) override;
// Utility methods for extending interfaces.
@@ -130,10 +134,14 @@
private:
bool mIsClosed;
audio_hw_device_t* mDevice;
+ int mOpenedStreamsCount = 0;
virtual ~Device();
Result doClose();
+ std::tuple<Result, AudioPatchHandle> createOrUpdateAudioPatch(
+ AudioPatchHandle patch, const hidl_vec<AudioPortConfig>& sources,
+ const hidl_vec<AudioPortConfig>& sinks);
// Methods from ParametersUtil.
char* halGetParameters(const char* keys) override;
diff --git a/audio/core/all-versions/default/include/core/default/PrimaryDevice.h b/audio/core/all-versions/default/include/core/default/PrimaryDevice.h
index f5f3848..ccdb7b2 100644
--- a/audio/core/all-versions/default/include/core/default/PrimaryDevice.h
+++ b/audio/core/all-versions/default/include/core/default/PrimaryDevice.h
@@ -98,6 +98,11 @@
#endif
#if MAJOR_VERSION >= 6
Return<Result> close() override;
+ Return<Result> addDeviceEffect(AudioPortHandle device, uint64_t effectId) override;
+ Return<Result> removeDeviceEffect(AudioPortHandle device, uint64_t effectId) override;
+ Return<void> updateAudioPatch(int32_t previousPatch, const hidl_vec<AudioPortConfig>& sources,
+ const hidl_vec<AudioPortConfig>& sinks,
+ updateAudioPatch_cb _hidl_cb) override;
#endif
Return<void> debug(const hidl_handle& fd, const hidl_vec<hidl_string>& options) override;
diff --git a/audio/core/all-versions/default/include/core/default/Stream.h b/audio/core/all-versions/default/include/core/default/Stream.h
index 91df0c7..ce0003b 100644
--- a/audio/core/all-versions/default/include/core/default/Stream.h
+++ b/audio/core/all-versions/default/include/core/default/Stream.h
@@ -157,6 +157,10 @@
native_handle_t* hidlHandle = nullptr;
if (mStream->create_mmap_buffer != NULL) {
+ if (minSizeFrames <= 0) {
+ retval = Result::INVALID_ARGUMENTS;
+ goto exit;
+ }
struct audio_mmap_buffer_info halInfo;
retval = Stream::analyzeStatus(
"create_mmap_buffer", mStream->create_mmap_buffer(mStream, minSizeFrames, &halInfo));
@@ -184,6 +188,7 @@
info.burstSizeFrames = halInfo.burst_size_frames;
}
}
+exit:
_hidl_cb(retval, info);
if (hidlHandle != nullptr) {
native_handle_delete(hidlHandle);
diff --git a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp
index 81f963d..709b7cd 100644
--- a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp
+++ b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp
@@ -52,7 +52,6 @@
doc::test(
"Make sure getMicrophones always succeeds"
"and getActiveMicrophones always succeeds when recording from these microphones.");
- AudioIoHandle ioHandle = (AudioIoHandle)AudioHandleConsts::AUDIO_IO_HANDLE_NONE;
AudioConfig config{};
config.channelMask = mkEnumBitfield(AudioChannelMask::IN_MONO);
config.sampleRateHz = 8000;
@@ -65,18 +64,14 @@
continue;
}
sp<IStreamIn> stream;
+ StreamHelper<IStreamIn> helper(stream);
AudioConfig suggestedConfig{};
- ASSERT_OK(getDevice()->openInputStream(ioHandle, microphone.deviceAddress, config,
- flags, initMetadata,
- returnIn(res, stream, suggestedConfig)));
- if (res != Result::OK) {
- ASSERT_TRUE(stream == nullptr);
- AudioConfig suggestedConfigRetry{};
- ASSERT_OK(getDevice()->openInputStream(
- ioHandle, microphone.deviceAddress, suggestedConfig, flags, initMetadata,
- returnIn(res, stream, suggestedConfigRetry)));
- }
- ASSERT_OK(res);
+ ASSERT_NO_FATAL_FAILURE(helper.open(
+ [&](AudioIoHandle handle, AudioConfig config, auto cb) {
+ return getDevice()->openInputStream(handle, microphone.deviceAddress,
+ config, flags, initMetadata, cb);
+ },
+ config, &res, &suggestedConfig));
hidl_vec<MicrophoneInfo> activeMicrophones;
Result readRes;
typedef MessageQueue<IStreamIn::ReadParameters, kSynchronizedReadWrite> CommandMQ;
@@ -110,13 +105,8 @@
ASSERT_OK(res);
ASSERT_NE(0U, activeMicrophones.size());
}
- stream->close();
-#if MAJOR_VERSION <= 5
- // Workaround for b/139329877. Ensures the stream gets closed on the audio hal side.
- stream.clear();
- IPCThreadState::self()->flushCommands();
- usleep(1000);
-#endif
+ helper.close(true /*clear*/, &res);
+ ASSERT_OK(res);
if (efGroup) {
EventFlag::deleteEventFlag(&efGroup);
}
diff --git a/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp
index 7e931ff..09ef330 100644
--- a/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp
+++ b/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp
@@ -83,7 +83,6 @@
for (auto& config : configs) {
// Some combinations of flags declared in the config file require special
// treatment.
- bool special = false;
if (flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
config.offloadInfo.sampleRateHz = config.sampleRateHz;
config.offloadInfo.channelMask = config.channelMask;
@@ -94,22 +93,13 @@
config.offloadInfo.bitWidth = 16;
config.offloadInfo.bufferSize = 256; // arbitrary value
config.offloadInfo.usage = AudioUsage::MEDIA;
- result.emplace_back(
- device, config,
- AudioOutputFlag(AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD));
- special = true;
- }
- if ((flags & AUDIO_OUTPUT_FLAG_DIRECT) &&
- !(flags &
- (AUDIO_OUTPUT_FLAG_HW_AV_SYNC | AUDIO_OUTPUT_FLAG_MMAP_NOIRQ))) {
result.emplace_back(device, config,
- AudioOutputFlag(AUDIO_OUTPUT_FLAG_DIRECT));
- special = true;
- }
- if (flags & AUDIO_OUTPUT_FLAG_PRIMARY) { // ignore the flag
- flags &= ~AUDIO_OUTPUT_FLAG_PRIMARY;
- }
- if (!special) {
+ AudioOutputFlag(AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD |
+ AUDIO_OUTPUT_FLAG_DIRECT));
+ } else {
+ if (flags & AUDIO_OUTPUT_FLAG_PRIMARY) { // ignore the flag
+ flags &= ~AUDIO_OUTPUT_FLAG_PRIMARY;
+ }
result.emplace_back(device, config, AudioOutputFlag(flags));
}
}
@@ -145,3 +135,58 @@
}();
return parameters;
}
+
+TEST_P(AudioHidlDeviceTest, CloseDeviceWithOpenedOutputStreams) {
+ doc::test("Verify that a device can't be closed if there are streams opened");
+ DeviceAddress address{.device = AudioDevice::OUT_DEFAULT};
+ AudioConfig config{};
+ auto flags = hidl_bitfield<AudioOutputFlag>(AudioOutputFlag::NONE);
+ SourceMetadata initMetadata = {{{AudioUsage::MEDIA, AudioContentType::MUSIC, 1 /* gain */}}};
+ sp<IStreamOut> stream;
+ StreamHelper<IStreamOut> helper(stream);
+ AudioConfig suggestedConfig{};
+ ASSERT_NO_FATAL_FAILURE(helper.open(
+ [&](AudioIoHandle handle, AudioConfig config, auto cb) {
+ return getDevice()->openOutputStream(handle, address, config, flags, initMetadata,
+ cb);
+ },
+ config, &res, &suggestedConfig));
+ ASSERT_RESULT(Result::INVALID_STATE, getDevice()->close());
+ ASSERT_NO_FATAL_FAILURE(helper.close(true /*clear*/, &res));
+ ASSERT_OK(getDevice()->close());
+ ASSERT_TRUE(resetDevice());
+}
+
+TEST_P(AudioHidlDeviceTest, CloseDeviceWithOpenedInputStreams) {
+ doc::test("Verify that a device can't be closed if there are streams opened");
+ auto module = getCachedPolicyConfig().getModuleFromName(getDeviceName());
+ if (module->getInputProfiles().empty()) {
+ GTEST_SKIP() << "Device doesn't have input profiles";
+ }
+ DeviceAddress address{.device = AudioDevice::IN_DEFAULT};
+ AudioConfig config{};
+ auto flags = hidl_bitfield<AudioInputFlag>(AudioInputFlag::NONE);
+ SinkMetadata initMetadata = {{{.source = AudioSource::MIC, .gain = 1}}};
+ sp<IStreamIn> stream;
+ StreamHelper<IStreamIn> helper(stream);
+ AudioConfig suggestedConfig{};
+ ASSERT_NO_FATAL_FAILURE(helper.open(
+ [&](AudioIoHandle handle, AudioConfig config, auto cb) {
+ return getDevice()->openInputStream(handle, address, config, flags, initMetadata,
+ cb);
+ },
+ config, &res, &suggestedConfig));
+ ASSERT_RESULT(Result::INVALID_STATE, getDevice()->close());
+ ASSERT_NO_FATAL_FAILURE(helper.close(true /*clear*/, &res));
+ ASSERT_OK(getDevice()->close());
+ ASSERT_TRUE(resetDevice());
+}
+
+TEST_P(AudioPatchHidlTest, UpdatePatchInvalidHandle) {
+ doc::test("Verify that passing an invalid handle to updateAudioPatch is checked");
+ AudioPatchHandle ignored;
+ ASSERT_OK(getDevice()->updateAudioPatch(
+ static_cast<int32_t>(AudioHandleConsts::AUDIO_PATCH_HANDLE_NONE),
+ hidl_vec<AudioPortConfig>(), hidl_vec<AudioPortConfig>(), returnIn(res, ignored)));
+ ASSERT_RESULT(Result::INVALID_ARGUMENTS, res);
+}
diff --git a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
index 6fc9339..d0d39e8 100644
--- a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
+++ b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
@@ -718,12 +718,6 @@
::testing::Values(AudioInputFlag::NONE)),
&DeviceConfigParameterToString);
INSTANTIATE_TEST_CASE_P(
- SupportedInputBufferSize, RequiredInputBufferSizeTest,
- ::testing::Combine(::testing::ValuesIn(getDeviceParameters()),
- ::testing::ValuesIn(ConfigHelper::getSupportedCaptureAudioConfig()),
- ::testing::Values(AudioInputFlag::NONE)),
- &DeviceConfigParameterToString);
-INSTANTIATE_TEST_CASE_P(
RecommendedCaptureAudioConfigSupport, OptionalInputBufferSizeTest,
::testing::Combine(
::testing::ValuesIn(getDeviceParametersForPrimaryDeviceTests()),
@@ -815,62 +809,84 @@
////////////////////////// open{Output,Input}Stream //////////////////////////
//////////////////////////////////////////////////////////////////////////////
+// This class is also used by some device tests.
template <class Stream>
-class OpenStreamTest : public AudioHidlTestWithDeviceConfigParameter {
- protected:
+class StreamHelper {
+ public:
+ // StreamHelper doesn't own the stream, this is for simpler stream lifetime management.
+ explicit StreamHelper(sp<Stream>& stream) : mStream(stream) {}
template <class Open>
- void testOpen(Open openStream, const AudioConfig& config) {
+ void open(Open openStream, const AudioConfig& config, Result* res,
+ AudioConfig* suggestedConfigPtr) {
// FIXME: Open a stream without an IOHandle
// This is not required to be accepted by hal implementations
AudioIoHandle ioHandle = (AudioIoHandle)AudioHandleConsts::AUDIO_IO_HANDLE_NONE;
AudioConfig suggestedConfig{};
- ASSERT_OK(openStream(ioHandle, config, returnIn(res, stream, suggestedConfig)));
-
- // TODO: only allow failure for RecommendedPlaybackAudioConfig
- switch (res) {
+ bool retryWithSuggestedConfig = true;
+ if (suggestedConfigPtr == nullptr) {
+ suggestedConfigPtr = &suggestedConfig;
+ retryWithSuggestedConfig = false;
+ }
+ ASSERT_OK(openStream(ioHandle, config, returnIn(*res, mStream, *suggestedConfigPtr)));
+ switch (*res) {
case Result::OK:
- ASSERT_TRUE(stream != nullptr);
- audioConfig = config;
+ ASSERT_TRUE(mStream != nullptr);
+ *suggestedConfigPtr = config;
break;
case Result::INVALID_ARGUMENTS:
- ASSERT_TRUE(stream == nullptr);
- AudioConfig suggestedConfigRetry;
- // Could not open stream with config, try again with the
- // suggested one
- ASSERT_OK(openStream(ioHandle, suggestedConfig,
- returnIn(res, stream, suggestedConfigRetry)));
- // This time it must succeed
- ASSERT_OK(res);
- ASSERT_TRUE(stream != nullptr);
- audioConfig = suggestedConfig;
+ ASSERT_TRUE(mStream == nullptr);
+ if (retryWithSuggestedConfig) {
+ AudioConfig suggestedConfigRetry;
+ ASSERT_OK(openStream(ioHandle, *suggestedConfigPtr,
+ returnIn(*res, mStream, suggestedConfigRetry)));
+ ASSERT_OK(*res);
+ ASSERT_TRUE(mStream != nullptr);
+ }
break;
default:
- FAIL() << "Invalid return status: " << ::testing::PrintToString(res);
+ FAIL() << "Invalid return status: " << ::testing::PrintToString(*res);
}
+ }
+ void close(bool clear, Result* res) {
+ auto ret = mStream->close();
+ EXPECT_TRUE(ret.isOk());
+ *res = ret;
+ if (clear) {
+ mStream.clear();
+#if MAJOR_VERSION <= 5
+ // FIXME: there is no way to know when the remote IStream is being destroyed
+ // Binder does not support testing if an object is alive, thus
+ // wait for 100ms to let the binder destruction propagates and
+ // the remote device has the time to be destroyed.
+ // flushCommand makes sure all local command are sent, thus should reduce
+ // the latency between local and remote destruction.
+ IPCThreadState::self()->flushCommands();
+ usleep(100 * 1000);
+#endif
+ }
+ }
+
+ private:
+ sp<Stream>& mStream;
+};
+
+template <class Stream>
+class OpenStreamTest : public AudioHidlTestWithDeviceConfigParameter {
+ protected:
+ OpenStreamTest() : AudioHidlTestWithDeviceConfigParameter(), helper(stream) {}
+ template <class Open>
+ void testOpen(Open openStream, const AudioConfig& config) {
+ // TODO: only allow failure for RecommendedPlaybackAudioConfig
+ ASSERT_NO_FATAL_FAILURE(helper.open(openStream, config, &res, &audioConfig));
open = true;
}
- Return<Result> closeStream() {
+ Result closeStream(bool clear = true) {
open = false;
- auto res = stream->close();
- stream.clear();
- waitForStreamDestruction();
+ helper.close(clear, &res);
return res;
}
- static void waitForStreamDestruction() {
-#if MAJOR_VERSION <= 5
- // FIXME: there is no way to know when the remote IStream is being destroyed
- // Binder does not support testing if an object is alive, thus
- // wait for 100ms to let the binder destruction propagates and
- // the remote device has the time to be destroyed.
- // flushCommand makes sure all local command are sent, thus should reduce
- // the latency between local and remote destruction.
- IPCThreadState::self()->flushCommands();
- usleep(100 * 1000);
-#endif
- }
-
private:
void TearDown() override {
if (open) {
@@ -883,6 +899,7 @@
AudioConfig audioConfig;
DeviceAddress address = {};
sp<Stream> stream;
+ StreamHelper<Stream> helper;
bool open = false;
};
@@ -931,12 +948,6 @@
::testing::Values(AudioOutputFlag::NONE)),
&DeviceConfigParameterToString);
INSTANTIATE_TEST_CASE_P(
- SupportedOutputStreamConfig, OutputStreamTest,
- ::testing::Combine(::testing::ValuesIn(getDeviceParameters()),
- ::testing::ValuesIn(ConfigHelper::getSupportedPlaybackAudioConfig()),
- ::testing::Values(AudioOutputFlag::NONE)),
- &DeviceConfigParameterToString);
-INSTANTIATE_TEST_CASE_P(
RecommendedOutputStreamConfigSupport, OutputStreamTest,
::testing::Combine(
::testing::ValuesIn(getDeviceParametersForPrimaryDeviceTests()),
@@ -946,7 +957,7 @@
#elif MAJOR_VERSION >= 6
// For V6 and above test according to the audio policy manager configuration.
// This is more correct as CDD is written from the apps perspective.
-// Audio system provides necessary format conversions for the missing configurations.
+// Audio system provides necessary format conversions for missing configurations.
INSTANTIATE_TEST_CASE_P(DeclaredOutputStreamConfigSupport, OutputStreamTest,
::testing::ValuesIn(getOutputDeviceConfigParameters()),
&DeviceConfigParameterToString);
@@ -992,12 +1003,6 @@
::testing::Values(AudioInputFlag::NONE)),
&DeviceConfigParameterToString);
INSTANTIATE_TEST_CASE_P(
- SupportedInputStreamConfig, InputStreamTest,
- ::testing::Combine(::testing::ValuesIn(getDeviceParameters()),
- ::testing::ValuesIn(ConfigHelper::getSupportedCaptureAudioConfig()),
- ::testing::Values(AudioInputFlag::NONE)),
- &DeviceConfigParameterToString);
-INSTANTIATE_TEST_CASE_P(
RecommendedInputStreamConfigSupport, InputStreamTest,
::testing::Combine(
::testing::ValuesIn(getDeviceParametersForPrimaryDeviceTests()),
@@ -1007,7 +1012,7 @@
#elif MAJOR_VERSION >= 6
// For V6 and above test according to the audio policy manager configuration.
// This is more correct as CDD is written from the apps perspective.
-// Audio system provides necessary format conversions for the missing configurations.
+// Audio system provides necessary format conversions for missing configurations.
INSTANTIATE_TEST_CASE_P(DeclaredInputStreamConfigSupport, InputStreamTest,
::testing::ValuesIn(getInputDeviceConfigParameters()),
&DeviceConfigParameterToString);
@@ -1196,11 +1201,8 @@
TEST_IO_STREAM(close, "Make sure a stream can be closed", ASSERT_OK(closeStream()))
// clang-format off
TEST_IO_STREAM(closeTwice, "Make sure a stream can not be closed twice",
- auto streamCopy = stream;
- ASSERT_OK(closeStream());
- ASSERT_RESULT(Result::INVALID_STATE, streamCopy->close());
- streamCopy.clear();
- waitForStreamDestruction())
+ ASSERT_OK(closeStream(false /*clear*/));
+ ASSERT_EQ(Result::INVALID_STATE, closeStream()))
// clang-format on
static void testMmapBufferOfInvalidSize(IStream* stream) {
diff --git a/audio/core/all-versions/vts/functional/ConfigHelper.h b/audio/core/all-versions/vts/functional/ConfigHelper.h
index 48aae8c..a2f4116 100644
--- a/audio/core/all-versions/vts/functional/ConfigHelper.h
+++ b/audio/core/all-versions/vts/functional/ConfigHelper.h
@@ -57,12 +57,6 @@
{24000, 48000}, {AudioFormat::PCM_16_BIT});
}
- static const vector<AudioConfig> getSupportedPlaybackAudioConfig() {
- // TODO: retrieve audio config supported by the platform
- // as declared in the policy configuration
- return {};
- }
-
static const vector<AudioConfig> getRequiredSupportCaptureAudioConfig() {
if (!primaryHasMic()) return {};
return combineAudioConfig({AudioChannelMask::IN_MONO}, {8000, 11025, 16000, 44100},
@@ -73,11 +67,6 @@
return combineAudioConfig({AudioChannelMask::IN_STEREO}, {22050, 48000},
{AudioFormat::PCM_16_BIT});
}
- static const vector<AudioConfig> getSupportedCaptureAudioConfig() {
- // TODO: retrieve audio config supported by the platform
- // as declared in the policy configuration
- return {};
- }
static vector<AudioConfig> combineAudioConfig(vector<audio_channel_mask_t> channelMasks,
vector<uint32_t> sampleRates,
diff --git a/audio/core/all-versions/vts/functional/DeviceManager.h b/audio/core/all-versions/vts/functional/DeviceManager.h
index d849f85..cb6584d 100644
--- a/audio/core/all-versions/vts/functional/DeviceManager.h
+++ b/audio/core/all-versions/vts/functional/DeviceManager.h
@@ -113,7 +113,11 @@
#elif MAJOR_VERSION >= 6
{
sp<IDevice> device = getExisting(std::make_tuple(factoryName, name));
- if (device != nullptr) device->close();
+ if (device != nullptr) {
+ auto ret = device->close();
+ ALOGE_IF(!ret.isOk(), "Device %s::%s close failed: %s", factoryName.c_str(),
+ name.c_str(), ret.description().c_str());
+ }
}
return InterfaceManager::reset(std::make_tuple(factoryName, name), false);
#endif
diff --git a/audio/effect/6.0/IEffectsFactory.hal b/audio/effect/6.0/IEffectsFactory.hal
index e08b2de..4c37bad 100644
--- a/audio/effect/6.0/IEffectsFactory.hal
+++ b/audio/effect/6.0/IEffectsFactory.hal
@@ -48,11 +48,15 @@
* stream.
* @param ioHandle identifies the output or input stream this effect is
* directed to in audio HAL.
+ * @param device identifies the sink or source device this effect is directed to in the
+ * audio HAL. Must be specified if session is AudioSessionConsts.DEVICE.
+ * "device" is the AudioPortHandle used for the device when the audio
+ * patch is created at the audio HAL.
* @return retval operation completion status.
* @return result the interface for the created effect.
* @return effectId the unique ID of the effect to be used with
* IStream::addEffect and IStream::removeEffect methods.
*/
- createEffect(Uuid uid, AudioSession session, AudioIoHandle ioHandle)
+ createEffect(Uuid uid, AudioSession session, AudioIoHandle ioHandle, AudioPortHandle device)
generates (Result retval, IEffect result, uint64_t effectId);
};
diff --git a/audio/effect/all-versions/default/Effect.cpp b/audio/effect/all-versions/default/Effect.cpp
index e11e123..406a571 100644
--- a/audio/effect/all-versions/default/Effect.cpp
+++ b/audio/effect/all-versions/default/Effect.cpp
@@ -709,7 +709,10 @@
#elif MAJOR_VERSION >= 6
// No need to join the processing thread, it is part of the API contract that the client
// must finish processing before closing the effect.
- return analyzeStatus("EffectRelease", "", sContextCallFunction, EffectRelease(mHandle));
+ Result retval =
+ analyzeStatus("EffectRelease", "", sContextCallFunction, EffectRelease(mHandle));
+ EffectMap::getInstance().remove(mHandle);
+ return retval;
#endif
}
diff --git a/audio/effect/all-versions/default/EffectsFactory.cpp b/audio/effect/all-versions/default/EffectsFactory.cpp
index 6283e7b..acce7de 100644
--- a/audio/effect/all-versions/default/EffectsFactory.cpp
+++ b/audio/effect/all-versions/default/EffectsFactory.cpp
@@ -133,9 +133,9 @@
return Void();
}
-Return<void> EffectsFactory::getDescriptor(const Uuid& uid, getDescriptor_cb _hidl_cb) {
+Return<void> EffectsFactory::getDescriptor(const Uuid& uuid, getDescriptor_cb _hidl_cb) {
effect_uuid_t halUuid;
- HidlUtils::uuidToHal(uid, &halUuid);
+ HidlUtils::uuidToHal(uuid, &halUuid);
effect_descriptor_t halDescriptor;
status_t status = EffectGetDescriptor(&halUuid, &halDescriptor);
EffectDescriptor descriptor;
@@ -154,13 +154,31 @@
return Void();
}
-Return<void> EffectsFactory::createEffect(const Uuid& uid, int32_t session, int32_t ioHandle,
- createEffect_cb _hidl_cb) {
+#if MAJOR_VERSION <= 5
+Return<void> EffectsFactory::createEffect(const Uuid& uuid, int32_t session, int32_t ioHandle,
+ EffectsFactory::createEffect_cb _hidl_cb) {
+ return createEffectImpl(uuid, session, ioHandle, AUDIO_PORT_HANDLE_NONE, _hidl_cb);
+}
+#else
+Return<void> EffectsFactory::createEffect(const Uuid& uuid, int32_t session, int32_t ioHandle,
+ int32_t device,
+ EffectsFactory::createEffect_cb _hidl_cb) {
+ return createEffectImpl(uuid, session, ioHandle, device, _hidl_cb);
+}
+#endif
+
+Return<void> EffectsFactory::createEffectImpl(const Uuid& uuid, int32_t session, int32_t ioHandle,
+ int32_t device, createEffect_cb _hidl_cb) {
effect_uuid_t halUuid;
- HidlUtils::uuidToHal(uid, &halUuid);
+ HidlUtils::uuidToHal(uuid, &halUuid);
effect_handle_t handle;
Result retval(Result::OK);
- status_t status = EffectCreate(&halUuid, session, ioHandle, &handle);
+ status_t status;
+ if (session == AUDIO_SESSION_DEVICE) {
+ status = EffectCreateOnDevice(&halUuid, device, ioHandle, &handle);
+ } else {
+ status = EffectCreate(&halUuid, session, ioHandle, &handle);
+ }
sp<IEffect> effect;
uint64_t effectId = EffectMap::INVALID_ID;
if (status == OK) {
diff --git a/audio/effect/all-versions/default/EffectsFactory.h b/audio/effect/all-versions/default/EffectsFactory.h
index f0d09ec..0b86836 100644
--- a/audio/effect/all-versions/default/EffectsFactory.h
+++ b/audio/effect/all-versions/default/EffectsFactory.h
@@ -47,9 +47,15 @@
struct EffectsFactory : public IEffectsFactory {
// Methods from ::android::hardware::audio::effect::CPP_VERSION::IEffectsFactory follow.
Return<void> getAllDescriptors(getAllDescriptors_cb _hidl_cb) override;
- Return<void> getDescriptor(const Uuid& uid, getDescriptor_cb _hidl_cb) override;
- Return<void> createEffect(const Uuid& uid, int32_t session, int32_t ioHandle,
+ Return<void> getDescriptor(const Uuid& uuid, getDescriptor_cb _hidl_cb) override;
+#if MAJOR_VERSION <= 5
+ Return<void> createEffect(const Uuid& uuid, int32_t session, int32_t ioHandle,
createEffect_cb _hidl_cb) override;
+#else
+ Return<void> createEffect(const Uuid& uuid, int32_t session, int32_t ioHandle, int32_t device,
+ createEffect_cb _hidl_cb) override;
+#endif
+
Return<void> debugDump(
const hidl_handle& fd); //< in CPP_VERSION::IEffectsFactory only, alias of debug
Return<void> debug(const hidl_handle& fd, const hidl_vec<hidl_string>& options) override;
@@ -57,6 +63,8 @@
private:
static sp<IEffect> dispatchEffectInstanceCreation(const effect_descriptor_t& halDescriptor,
effect_handle_t handle);
+ Return<void> createEffectImpl(const Uuid& uuid, int32_t session, int32_t ioHandle,
+ int32_t device, createEffect_cb _hidl_cb);
};
extern "C" IEffectsFactory* HIDL_FETCH_IEffectsFactory(const char* name);
diff --git a/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp b/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp
index 3c712b5..c151d3a 100644
--- a/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp
+++ b/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp
@@ -134,13 +134,16 @@
Result retval = Result::NOT_INITIALIZED;
sp<IEffect> effect;
ret = effectsFactory->createEffect(
- effectUuid, 1 /*session*/, 1 /*ioHandle*/,
- [&](Result r, const sp<IEffect>& result, uint64_t /*effectId*/) {
- retval = r;
- if (r == Result::OK) {
- effect = result;
- }
- });
+ effectUuid, 1 /*session*/, 1 /*ioHandle*/,
+#if MAJOR_VERSION >= 6
+ 0 /*device*/,
+#endif
+ [&](Result r, const sp<IEffect>& result, uint64_t /*effectId*/) {
+ retval = r;
+ if (r == Result::OK) {
+ effect = result;
+ }
+ });
EXPECT_TRUE(ret.isOk());
EXPECT_EQ(Result::OK, retval);
EXPECT_NE(nullptr, effect.get());
@@ -236,12 +239,15 @@
Uuid effectUuid;
findEffectInstance(type, &effectUuid);
Return<void> ret = effectsFactory->createEffect(
- effectUuid, 1 /*session*/, 1 /*ioHandle*/,
- [&](Result r, const sp<IEffect>& result, uint64_t /*effectId*/) {
- if (r == Result::OK) {
- effect = result;
- }
- });
+ effectUuid, 1 /*session*/, 1 /*ioHandle*/,
+#if MAJOR_VERSION >= 6
+ 0 /*device*/,
+#endif
+ [&](Result r, const sp<IEffect>& result, uint64_t /*effectId*/) {
+ if (r == Result::OK) {
+ effect = result;
+ }
+ });
ASSERT_TRUE(ret.isOk());
}
diff --git a/automotive/can/1.0/default/CanBus.cpp b/automotive/can/1.0/default/CanBus.cpp
index 42d2e3c..86df5dc 100644
--- a/automotive/can/1.0/default/CanBus.cpp
+++ b/automotive/can/1.0/default/CanBus.cpp
@@ -22,6 +22,8 @@
#include <libnetdevice/can.h>
#include <libnetdevice/libnetdevice.h>
#include <linux/can.h>
+#include <linux/can/error.h>
+#include <linux/can/raw.h>
namespace android {
namespace hardware {
@@ -220,6 +222,21 @@
}
/**
+ * Helper function to determine if a flag meets the requirements of a
+ * FilterFlag. See definition of FilterFlag in types.hal
+ *
+ * \param filterFlag FilterFlag object to match flag against
+ * \param flag bool object from CanMessage object
+ */
+static bool satisfiesFilterFlag(FilterFlag filterFlag, bool flag) {
+ // TODO(b/144458917) add testing for this to VTS tests
+ if (filterFlag == FilterFlag::DONT_CARE) return true;
+ if (filterFlag == FilterFlag::REQUIRE) return flag;
+ if (filterFlag == FilterFlag::EXCLUDE) return !flag;
+ return false;
+}
+
+/**
* Match the filter set against message id.
*
* For details on the filters syntax, please see CanMessageFilter at
@@ -229,13 +246,16 @@
* \param id Message id to filter
* \return true if the message id matches the filter, false otherwise
*/
-static bool match(const hidl_vec<CanMessageFilter>& filter, CanMessageId id) {
+static bool match(const hidl_vec<CanMessageFilter>& filter, CanMessageId id, bool isExtendedId,
+ bool isRtr) {
if (filter.size() == 0) return true;
bool anyNonInvertedPresent = false;
bool anyNonInvertedSatisfied = false;
for (auto& rule : filter) {
- const bool satisfied = ((id & rule.mask) == rule.id) == !rule.inverted;
+ const bool satisfied = ((id & rule.mask) == rule.id) == !rule.inverted &&
+ satisfiesFilterFlag(rule.rtr, isRtr) &&
+ satisfiesFilterFlag(rule.extendedFormat, isExtendedId);
if (rule.inverted) {
// Any inverted (blacklist) rule not being satisfied invalidates the whole filter set.
if (!satisfied) return false;
@@ -247,11 +267,54 @@
return !anyNonInvertedPresent || anyNonInvertedSatisfied;
}
+void CanBus::notifyErrorListeners(ErrorEvent err, bool isFatal) {
+ std::lock_guard<std::mutex> lck(mErrListenersGuard);
+ for (auto& listener : mErrListeners) {
+ if (!listener->onError(err, isFatal).isOk()) {
+ LOG(WARNING) << "Failed to notify listener about error";
+ }
+ }
+}
+
+static ErrorEvent parseErrorFrame(const struct canfd_frame& frame) {
+ // decode error frame (to a degree)
+ if ((frame.can_id & (CAN_ERR_BUSERROR | CAN_ERR_BUSOFF)) != 0) {
+ return ErrorEvent::BUS_ERROR;
+ }
+ if ((frame.data[1] & CAN_ERR_CRTL_TX_OVERFLOW) != 0) {
+ return ErrorEvent::TX_OVERFLOW;
+ }
+ if ((frame.data[1] & CAN_ERR_CRTL_RX_OVERFLOW) != 0) {
+ return ErrorEvent::RX_OVERFLOW;
+ }
+ if ((frame.data[2] & CAN_ERR_PROT_OVERLOAD) != 0) {
+ return ErrorEvent::BUS_OVERLOAD;
+ }
+ if ((frame.can_id & CAN_ERR_PROT) != 0) {
+ return ErrorEvent::MALFORMED_INPUT;
+ }
+ if ((frame.can_id & (CAN_ERR_CRTL | CAN_ERR_TRX | CAN_ERR_RESTARTED)) != 0) {
+ // "controller restarted" constitutes a HARDWARE_ERROR imo
+ return ErrorEvent::HARDWARE_ERROR;
+ }
+ return ErrorEvent::UNKNOWN_ERROR;
+}
+
void CanBus::onRead(const struct canfd_frame& frame, std::chrono::nanoseconds timestamp) {
+ if ((frame.can_id & CAN_ERR_FLAG) != 0) {
+ // error bit is set
+ LOG(WARNING) << "CAN Error frame received";
+ // TODO(b/144458917) consider providing different values for isFatal, depending on error
+ notifyErrorListeners(parseErrorFrame(frame), false);
+ return;
+ }
+
CanMessage message = {};
- message.id = frame.can_id;
+ message.id = frame.can_id & CAN_EFF_MASK; // mask out eff/rtr/err flags
message.payload = hidl_vec<uint8_t>(frame.data, frame.data + frame.len);
message.timestamp = timestamp.count();
+ message.isExtendedId = (frame.can_id & CAN_EFF_FLAG) != 0;
+ message.remoteTransmissionRequest = (frame.can_id & CAN_RTR_FLAG) != 0;
if (UNLIKELY(kSuperVerbose)) {
LOG(VERBOSE) << "Got message " << toString(message);
@@ -259,7 +322,9 @@
std::lock_guard<std::mutex> lck(mMsgListenersGuard);
for (auto& listener : mMsgListeners) {
- if (!match(listener.filter, message.id)) continue;
+ if (!match(listener.filter, message.id, message.remoteTransmissionRequest,
+ message.isExtendedId))
+ continue;
if (!listener.callback->onReceive(message).isOk() && !listener.failedOnce) {
listener.failedOnce = true;
LOG(WARNING) << "Failed to notify listener about message";
@@ -274,15 +339,7 @@
mDownAfterUse = false;
eventType = ErrorEvent::INTERFACE_DOWN;
}
-
- {
- std::lock_guard<std::mutex> lck(mErrListenersGuard);
- for (auto& listener : mErrListeners) {
- if (!listener->onError(eventType, true).isOk()) {
- LOG(WARNING) << "Failed to notify listener about error";
- }
- }
- }
+ notifyErrorListeners(eventType, true);
const auto errcb = mErrCb;
if (errcb != nullptr) errcb();
diff --git a/automotive/can/1.0/default/CanBus.h b/automotive/can/1.0/default/CanBus.h
index 365e90c..da3fc5a 100644
--- a/automotive/can/1.0/default/CanBus.h
+++ b/automotive/can/1.0/default/CanBus.h
@@ -89,6 +89,8 @@
void clearMsgListeners();
void clearErrListeners();
+ void notifyErrorListeners(ErrorEvent err, bool isFatal);
+
void onRead(const struct canfd_frame& frame, std::chrono::nanoseconds timestamp);
void onError(int errnoVal);
diff --git a/automotive/can/1.0/default/libnetdevice/can.cpp b/automotive/can/1.0/default/libnetdevice/can.cpp
index 87617dd..6452d9b 100644
--- a/automotive/can/1.0/default/libnetdevice/can.cpp
+++ b/automotive/can/1.0/default/libnetdevice/can.cpp
@@ -24,12 +24,16 @@
#include <android-base/unique_fd.h>
#include <linux/can.h>
+#include <linux/can/error.h>
#include <linux/can/netlink.h>
+#include <linux/can/raw.h>
namespace android {
namespace netdevice {
namespace can {
+static constexpr can_err_mask_t kErrMask = CAN_ERR_MASK;
+
base::unique_fd socket(const std::string& ifname) {
struct sockaddr_can addr = {};
addr.can_family = AF_CAN;
@@ -45,6 +49,11 @@
return {};
}
+ if (setsockopt(sock.get(), SOL_CAN_RAW, CAN_RAW_ERR_FILTER, &kErrMask, sizeof(kErrMask)) < 0) {
+ LOG(ERROR) << "Can't receive error frames, CAN setsockpt failed: " << strerror(errno);
+ return {};
+ }
+
if (0 != fcntl(sock.get(), F_SETFL, O_RDWR | O_NONBLOCK)) {
LOG(ERROR) << "Couldn't put CAN socket in non-blocking mode";
return {};
diff --git a/automotive/can/1.0/default/service.cpp b/automotive/can/1.0/default/service.cpp
index 7ef44fc..ebc2f8c 100644
--- a/automotive/can/1.0/default/service.cpp
+++ b/automotive/can/1.0/default/service.cpp
@@ -32,8 +32,8 @@
configureRpcThreadpool(16, true);
LOG(DEBUG) << "CAN controller service starting...";
- CanController canController;
- if (canController.registerAsService("socketcan") != OK) {
+ sp<CanController> canController(new CanController);
+ if (canController->registerAsService("socketcan") != OK) {
LOG(FATAL) << "Failed to register CAN controller";
return;
}
diff --git a/automotive/can/1.0/tools/canhaldump.cpp b/automotive/can/1.0/tools/canhaldump.cpp
index 99fd14a..55b2a34 100644
--- a/automotive/can/1.0/tools/canhaldump.cpp
+++ b/automotive/can/1.0/tools/canhaldump.cpp
@@ -20,6 +20,7 @@
#include <android/hidl/manager/1.2/IServiceManager.h>
#include <hidl-utils/hidl-utils.h>
+#include <linux/can.h>
#include <chrono>
#include <iomanip>
#include <iostream>
@@ -42,12 +43,14 @@
CanMessageListener(std::string name) : name(name) {}
virtual Return<void> onReceive(const V1_0::CanMessage& message) {
- std::cout << " " << name << " " << std::hex << std::uppercase << std::setw(3)
+ int msgIdWidth = 3;
+ if (message.isExtendedId) msgIdWidth = 8;
+ std::cout << " " << name << " " << std::hex << std::uppercase << std::setw(msgIdWidth)
<< std::setfill('0') << message.id << std::setw(0);
+ std::cout << " [" << message.payload.size() << "] ";
if (message.remoteTransmissionRequest) {
- std::cout << " RTR";
+ std::cout << "remote request";
} else {
- std::cout << " [" << message.payload.size() << "] ";
for (const auto byte : message.payload) {
std::cout << " " << std::setfill('0') << std::setw(2) << unsigned(byte);
}
diff --git a/automotive/can/1.0/types.hal b/automotive/can/1.0/types.hal
index 6f690f7..f09c940 100644
--- a/automotive/can/1.0/types.hal
+++ b/automotive/can/1.0/types.hal
@@ -58,6 +58,15 @@
* If this flag is set, payload must be empty.
*/
bool remoteTransmissionRequest;
+
+ /**
+ * Flag indicating if the message has an extended ID.
+ *
+ * Extended ID's are 29 bits long, as opposed to the standard 11 bit ID.
+ * It can not simply be inferred from the length of the ID itself, as the
+ * message ID 0x00000123 != message ID 0x123.
+ */
+ bool isExtendedId;
};
/**
@@ -70,11 +79,30 @@
* one) and all inverted filters must match. In other words:
* - a single matching non-inverted filter makes the whole set matching;
* - a single non-matching inverted filter makes the whole set non-matching.
+ *
+ * Additional less common options for filtering include:
+ * rtr - Remote Transmission Request; another ECU requests DLC bytes of data on this message ID
+ * extendedFormat - 29 bit message ID is used instead of 11 bits
*/
struct CanMessageFilter {
CanMessageId id;
uint32_t mask;
bool inverted;
+ FilterFlag rtr;
+ FilterFlag extendedFormat;
+};
+
+
+/**
+ * Types of filter that can be applied to a CanMessageFilter
+ */
+enum FilterFlag : uint8_t {
+ /** Default, FilterFlag doesn't effect what messages filtered */
+ DONT_CARE = 0,
+ /** This FilterFlag MUST be present in received messages to pass though the filter */
+ REQUIRE,
+ /** This FilterFlag must NOT be present in received messages to pass though the filter */
+ EXCLUDE,
};
enum Result : uint8_t {
diff --git a/automotive/can/1.0/vts/functional/VtsHalCanBusV1_0TargetTest.cpp b/automotive/can/1.0/vts/functional/VtsHalCanBusV1_0TargetTest.cpp
index 1a05716..250caf2 100644
--- a/automotive/can/1.0/vts/functional/VtsHalCanBusV1_0TargetTest.cpp
+++ b/automotive/can/1.0/vts/functional/VtsHalCanBusV1_0TargetTest.cpp
@@ -123,9 +123,9 @@
TEST_F(CanBusHalTest, ListenSomeFilter) {
hidl_vec<CanMessageFilter> filters = {
- {0x123, 0x1FF, false},
- {0x001, 0x00F, true},
- {0x200, 0x100, false},
+ {0x123, 0x1FF, false, FilterFlag::DONT_CARE, FilterFlag::DONT_CARE},
+ {0x001, 0x00F, true, FilterFlag::DONT_CARE, FilterFlag::DONT_CARE},
+ {0x200, 0x100, false, FilterFlag::DONT_CARE, FilterFlag::DONT_CARE},
};
const auto [result, closeHandle] = listen(filters, new CanMessageListener());
diff --git a/automotive/can/1.0/vts/functional/VtsHalCanBusVirtualV1_0TargetTest.cpp b/automotive/can/1.0/vts/functional/VtsHalCanBusVirtualV1_0TargetTest.cpp
index 225984d..695b9fb 100644
--- a/automotive/can/1.0/vts/functional/VtsHalCanBusVirtualV1_0TargetTest.cpp
+++ b/automotive/can/1.0/vts/functional/VtsHalCanBusVirtualV1_0TargetTest.cpp
@@ -244,14 +244,14 @@
auto bus2 = makeBus();
hidl_vec<CanMessageFilter> filterPositive = {
- {0x101, 0x100, false},
- {0x010, 0x0F0, false},
+ {0x101, 0x100, false, FilterFlag::DONT_CARE, FilterFlag::DONT_CARE},
+ {0x010, 0x0F0, false, FilterFlag::DONT_CARE, FilterFlag::DONT_CARE},
};
auto listenerPositive = bus2.listen(filterPositive);
hidl_vec<CanMessageFilter> filterNegative = {
- {0x123, 0x0FF, true},
- {0x004, 0x00F, true},
+ {0x123, 0x0FF, true, FilterFlag::DONT_CARE, FilterFlag::DONT_CARE},
+ {0x004, 0x00F, true, FilterFlag::DONT_CARE, FilterFlag::DONT_CARE},
};
auto listenerNegative = bus2.listen(filterNegative);
diff --git a/automotive/evs/common/utils/default/Android.bp b/automotive/evs/common/utils/default/Android.bp
index 7734f5c..776ef81 100644
--- a/automotive/evs/common/utils/default/Android.bp
+++ b/automotive/evs/common/utils/default/Android.bp
@@ -15,6 +15,7 @@
//
cc_library_static {
+ host_supported: true,
name: "android.hardware.automotive.evs@common-default-lib",
vendor_available: true,
relative_install_path: "hw",
diff --git a/automotive/evs/common/utils/default/test/fuzz/Android.bp b/automotive/evs/common/utils/default/test/fuzz/Android.bp
new file mode 100644
index 0000000..105ec68
--- /dev/null
+++ b/automotive/evs/common/utils/default/test/fuzz/Android.bp
@@ -0,0 +1,99 @@
+//
+// Copyright (C) 2019 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.
+//
+
+cc_fuzz {
+ host_supported: true,
+ name : "FormatConvertFuzzer_copyNV21toRGB32",
+ srcs: [
+ "FormatConvertFuzzer.cpp",
+ ],
+ static_libs: [
+ "android.hardware.automotive.evs@common-default-lib"
+ ],
+ cflags: [
+ "-DCOPY_NV21_TO_RGB32",
+ ],
+}
+
+cc_fuzz {
+ host_supported: true,
+ name : "FormatConvertFuzzer_copyNV21toBGR32",
+ srcs: [
+ "FormatConvertFuzzer.cpp",
+ ],
+ static_libs: [
+ "android.hardware.automotive.evs@common-default-lib"
+ ],
+ cflags: [
+ "-DCOPY_NV21_TO_BGR32",
+ ],
+}
+
+cc_fuzz {
+ host_supported: true,
+ name : "FormatConvertFuzzer_copyYV12toRGB32",
+ srcs: [
+ "FormatConvertFuzzer.cpp",
+ ],
+ static_libs: [
+ "android.hardware.automotive.evs@common-default-lib"
+ ],
+ cflags: [
+ "-DCOPY_YV12_TO_RGB32",
+ ],
+}
+
+cc_fuzz {
+ host_supported: true,
+ name : "FormatConvertFuzzer_copyYV12toBGR32",
+ srcs: [
+ "FormatConvertFuzzer.cpp",
+ ],
+ static_libs: [
+ "android.hardware.automotive.evs@common-default-lib"
+ ],
+ cflags: [
+ "-DCOPY_YV12_TO_BGR32",
+ ],
+}
+
+cc_fuzz {
+ host_supported: true,
+ name : "FormatConvertFuzzer_copyYUYVtoRGB32",
+ srcs: [
+ "FormatConvertFuzzer.cpp",
+ ],
+ static_libs: [
+ "android.hardware.automotive.evs@common-default-lib"
+ ],
+ cflags: [
+ "-DCOPY_YUYV_TO_RGB32",
+ ],
+}
+
+cc_fuzz {
+ host_supported: true,
+ name : "FormatConvertFuzzer_copyYUYVtoBGR32",
+ srcs: [
+ "FormatConvertFuzzer.cpp",
+ ],
+ static_libs: [
+ "android.hardware.automotive.evs@common-default-lib"
+ ],
+ cflags: [
+ "-DCOPY_YUYV_TO_BGR32",
+ ],
+}
diff --git a/automotive/evs/common/utils/default/test/fuzz/FormatConvertFuzzer.cpp b/automotive/evs/common/utils/default/test/fuzz/FormatConvertFuzzer.cpp
new file mode 100644
index 0000000..583a455
--- /dev/null
+++ b/automotive/evs/common/utils/default/test/fuzz/FormatConvertFuzzer.cpp
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#include <cmath>
+#include <cstdlib>
+#include <cstring>
+#include <ctime>
+#include "FormatConvert.h"
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, std::size_t size) {
+ if (size < 256) {
+ return 0;
+ }
+
+ std::srand(std::time(nullptr)); // use current time as seed for random generator
+ int random_variable = std::rand() % 10;
+ int width = (int)sqrt(size);
+ int height = width * ((float)random_variable / 10.0);
+
+ uint8_t* src = (uint8_t*)malloc(sizeof(uint8_t) * size);
+ memcpy(src, data, sizeof(uint8_t) * (size));
+ uint32_t* tgt = (uint32_t*)malloc(sizeof(uint32_t) * size);
+
+#ifdef COPY_NV21_TO_RGB32
+ android::hardware::automotive::evs::common::Utils::copyNV21toRGB32(width, height, src, tgt, 0);
+#elif COPY_NV21_TO_BGR32
+ android::hardware::automotive::evs::common::Utils::copyNV21toBGR32(width, height, src, tgt, 0);
+#elif COPY_YV12_TO_RGB32
+ android::hardware::automotive::evs::common::Utils::copyYV12toRGB32(width, height, src, tgt, 0);
+#elif COPY_YV12_TO_BGR32
+ android::hardware::automotive::evs::common::Utils::copyYV12toBGR32(width, height, src, tgt, 0);
+#elif COPY_YUYV_TO_RGB32
+ android::hardware::automotive::evs::common::Utils::copyYUYVtoRGB32(width, height, src, 0, tgt,
+ 0);
+#elif COPY_YUYV_TO_BGR32
+ android::hardware::automotive::evs::common::Utils::copyYUYVtoBGR32(width, height, src, 0, tgt,
+ 0);
+#endif
+
+ free(src);
+ free(tgt);
+
+ return 0;
+}
diff --git a/automotive/occupant_awareness/aidl/Android.bp b/automotive/occupant_awareness/aidl/Android.bp
new file mode 100644
index 0000000..6e9e8aa
--- /dev/null
+++ b/automotive/occupant_awareness/aidl/Android.bp
@@ -0,0 +1,13 @@
+aidl_interface {
+ name: "android.hardware.automotive.occupant_awareness",
+ vendor_available: true,
+ srcs: [
+ "android/hardware/automotive/occupant_awareness/*.aidl",
+ ],
+ stability: "vintf",
+ backend: {
+ java: {
+ enabled: false,
+ },
+ }
+}
diff --git a/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/ConfidenceLevel.aidl b/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/ConfidenceLevel.aidl
new file mode 100644
index 0000000..8597ddb
--- /dev/null
+++ b/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/ConfidenceLevel.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2019 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.occupant_awareness;
+
+@VintfStability
+@Backing(type="byte")
+enum ConfidenceLevel {
+ /**
+ * No prediction could be made.
+ */
+ NONE,
+ /**
+ * Best-guess, low-confidence prediction. Predictions exceeding this threshold are adequate
+ * for non-critical applications.
+ */
+ LOW,
+ /**
+ * High-confidence prediction. Predictions exceeding this threshold are adequate for
+ * applications that require reliable predictions.
+ */
+ HIGH,
+ /**
+ * Highest confidence rate achievable.
+ */
+ MAX,
+}
diff --git a/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/DriverMonitoringDetection.aidl b/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/DriverMonitoringDetection.aidl
new file mode 100644
index 0000000..f5cc9d5
--- /dev/null
+++ b/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/DriverMonitoringDetection.aidl
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2019 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.occupant_awareness;
+
+import android.hardware.automotive.occupant_awareness.ConfidenceLevel;
+
+@VintfStability
+parcelable DriverMonitoringDetection {
+ /*
+ * Confidence of the computed attention data.
+ */
+ ConfidenceLevel confidenceScore;
+ /*
+ * Is the driver currently looking on-road?
+ */
+ boolean isLookingOnRoad;
+ /*
+ * Duration the driver has been looking on or off road, in milliseconds.
+ */
+ long gazeDurationMillis;
+}
+
diff --git a/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/GazeDetection.aidl b/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/GazeDetection.aidl
new file mode 100644
index 0000000..fc36e13
--- /dev/null
+++ b/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/GazeDetection.aidl
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2019 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.occupant_awareness;
+
+import android.hardware.automotive.occupant_awareness.VehicleRegion;
+import android.hardware.automotive.occupant_awareness.ConfidenceLevel;
+
+@VintfStability
+parcelable GazeDetection {
+ /*
+ * Confidence level for the gaze detection.
+ */
+ ConfidenceLevel gazeConfidence;
+ /*
+ * Head position, in millimeters. The vehicle coordinate system is specified in the cabin space
+ * configuration. headPosition is double[3] array.
+ */
+ double[] headPosition;
+ /*
+ * Unit vector for the head pose direction. The vehicle coordinate system is specified in the
+ * cabin space configuration. headAngleUnitVector is double[3] array.
+ */
+ double[] headAngleUnitVector;
+ /*
+ * Unit vector for the gaze direction. The vehicle coordinate system is specified in the cabin
+ * space configuration. gazeAngleUnitVector is double[3] array.
+ */
+ double[] gazeAngleUnitVector;
+ /*
+ * Current gaze target.
+ */
+ VehicleRegion gazeTarget;
+ /*
+ * Custom gaze target string. This only need to be populated when gazeTarget is CUSTOM_TARGET.
+ * Vendors should use "com.vendor_name.target_name" format to avoid name collision with other
+ * vendors.
+ */
+ String customGazeTarget;
+ /*
+ * Duration that the subject has been looking at the current gaze target in milliseconds.
+ */
+ long timeOnTargetMillis;
+}
diff --git a/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/IOccupantAwareness.aidl b/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/IOccupantAwareness.aidl
new file mode 100644
index 0000000..1df0bda
--- /dev/null
+++ b/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/IOccupantAwareness.aidl
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2019 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.occupant_awareness;
+
+import android.hardware.automotive.occupant_awareness.OccupantAwarenessStatus;
+import android.hardware.automotive.occupant_awareness.Role;
+import android.hardware.automotive.occupant_awareness.IOccupantAwarenessClientCallback;
+import android.hardware.automotive.occupant_awareness.OccupantDetections;
+
+@VintfStability
+interface IOccupantAwareness {
+ /*
+ * System not able to generate any occupancy awareness.
+ */
+ const int CAP_NONE = 0;
+ /*
+ * System is able to detect the presence of humans.
+ */
+ const int CAP_PRESENCE_DETECTION = 1 << 0;
+ /*
+ * System is able to detect the gaze of humans.
+ */
+ const int CAP_GAZE_DETECTION = 1 << 1;
+ /*
+ * System is able to compute the attention details of humans.
+ */
+ const int CAP_DRIVER_MONITORING_DETECTION = 1 << 2;
+
+ /**
+ * Starts the occupant awareness detection system. This is a non-blocking function call.
+ * Once system is ready, state will be modified. State update can be inrquired using callback
+ * or getState() function.
+ * @return status is the current system state.
+ */
+ OccupantAwarenessStatus startDetection();
+
+ /**
+ * Stops the occupant awareness detection system. This is a non-blocking function call.
+ * Once system is reset, state will be modified. State update can be inrquired using callback
+ * or getState() function.
+ * @return status is the current system state.
+ */
+ OccupantAwarenessStatus stopDetection();
+
+ /**
+ * Returns list of Awareness Capability supported for the given type of occupants.
+ *
+ * @param out Bitwise OR of supported capabilities (CAP_* mask).
+ */
+ int getCapabilityForRole(in Role occupantRole);
+
+ /**
+ * Inquires the current state of the occupant awareness system.
+ * @param occupantRole specifies the role of occupants of interest.
+ * @param detectionCapability specifies a single detection capability (CAP_* ) of interest.
+ *
+ * @return status is the current system state.
+ */
+ OccupantAwarenessStatus getState(in Role occupantRole, in int detectionCapability);
+
+ /**
+ * Registers a callback for data streaming. Only single callback is supported. setCallback()
+ * should replace existing callback with new callback.
+ * @return: returns ok if successful.
+ */
+ void setCallback(in IOccupantAwarenessClientCallback callback);
+
+ /**
+ * Returns the most recent set of detections.
+ * @param OccupantDetections output detections.
+ * @return returns ok if successful.
+ */
+ void getLatestDetection(out OccupantDetections detections);
+}
diff --git a/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/IOccupantAwarenessClientCallback.aidl b/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/IOccupantAwarenessClientCallback.aidl
new file mode 100644
index 0000000..69f7b0b
--- /dev/null
+++ b/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/IOccupantAwarenessClientCallback.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2019 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.occupant_awareness;
+
+import android.hardware.automotive.occupant_awareness.OccupantAwarenessStatus;
+import android.hardware.automotive.occupant_awareness.OccupantDetections;
+
+@VintfStability
+interface IOccupantAwarenessClientCallback {
+ /**
+ * A callback invoked when the system status changes.
+ *
+ * @param detectionFlags The detection subsystem(s) whose status has changed.
+ * @param status The new system status.
+ */
+ oneway void onSystemStatusChanged(in int detectionFlags, in OccupantAwarenessStatus status);
+
+ /**
+ * A callback invoked when a new set of detections are available.
+ *
+ * @param detections Occupant detections.
+ */
+ oneway void onDetectionEvent(in OccupantDetections detections);
+}
diff --git a/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/OccupantAwarenessStatus.aidl b/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/OccupantAwarenessStatus.aidl
new file mode 100644
index 0000000..6a3453d
--- /dev/null
+++ b/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/OccupantAwarenessStatus.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2019 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.occupant_awareness;
+
+@VintfStability
+@Backing(type="byte")
+enum OccupantAwarenessStatus {
+ /*
+ * System is online and ready to serve requests.
+ */
+ READY = 0,
+ /**
+ * Detection is not supported in this vehicle due to a permanent lack of capabilities. Clients
+ * need not retry.
+ */
+ NOT_SUPPORTED = 1,
+ /*
+ * The system has not yet been initialized. No requests can be served until the
+ * initialization process completes. This state does not indicate any error and
+ * clients should retry later.
+ */
+ NOT_INITIALIZED = 2,
+ /*
+ * A permanent failure has occurred. No detections will be provided.
+ */
+ FAILURE = 3,
+}
diff --git a/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/OccupantDetection.aidl b/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/OccupantDetection.aidl
new file mode 100644
index 0000000..47ca35a
--- /dev/null
+++ b/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/OccupantDetection.aidl
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2019 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.occupant_awareness;
+
+import android.hardware.automotive.occupant_awareness.Role;
+import android.hardware.automotive.occupant_awareness.PresenceDetection;
+import android.hardware.automotive.occupant_awareness.GazeDetection;
+import android.hardware.automotive.occupant_awareness.DriverMonitoringDetection;
+
+/*
+ * A complete detection for a single occupant in the vehicle. Includes data about the subject's
+ * presence in the vehicle, gaze and attention.
+ */
+ @VintfStability
+parcelable OccupantDetection {
+ /*
+ * Role of the occupant (e.g., driver, passenger).
+ */
+ Role role;
+ /*
+ * Occupant presence state for a single occupant.
+ * If the vector is empty, no data could be generated.
+ */
+ PresenceDetection[] presenceData;
+ /*
+ * Gaze data for a single occupant.
+ * If the vector is empty, no data could be generated.
+ */
+ GazeDetection[] gazeData;
+ /*
+ * Attention data for a single occupant.
+ * If the vector is empty, no data could be generated.
+ */
+ DriverMonitoringDetection[] attentionData;
+}
+
diff --git a/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/OccupantDetections.aidl b/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/OccupantDetections.aidl
new file mode 100644
index 0000000..e8f6621
--- /dev/null
+++ b/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/OccupantDetections.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2019 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.occupant_awareness;
+
+import android.hardware.automotive.occupant_awareness.OccupantDetection;
+
+@VintfStability
+parcelable OccupantDetections {
+ /**
+ * Timestamp that the underlying source image was captured, in milliseconds since Jan 1, 1970
+ * (Unix time).
+ */
+ long timeStampMillis;
+ /**
+ * A vector of detections for all occupants in the vehicle. One OccupantDetection will be
+ * generated per detected face.
+ */
+ OccupantDetection[] detections;
+}
+
diff --git a/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/PresenceDetection.aidl b/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/PresenceDetection.aidl
new file mode 100644
index 0000000..a018106
--- /dev/null
+++ b/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/PresenceDetection.aidl
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2019 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.occupant_awareness;
+
+@VintfStability
+parcelable PresenceDetection {
+ /*
+ * Boolean representing whether an occupant was detected.
+ */
+ boolean isOccupantDetected;
+ /**
+ * Duration that a particular occupant has been continuously
+ * detected, in milliseconds. Will be zero duration if the occupant is not
+ * currently detected.
+ */
+ long detectionDurationMillis;
+}
diff --git a/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/Role.aidl b/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/Role.aidl
new file mode 100644
index 0000000..42e86ad
--- /dev/null
+++ b/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/Role.aidl
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2019 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.occupant_awareness;
+
+@VintfStability
+@Backing(type="int")
+enum Role {
+ /*
+ * All valid role(s) must have at least 1 bit set.
+ */
+ INVALID = 0,
+ /*
+ * System could not determine role for this occupant.
+ */
+ UNKNOWN = 1 << 0,
+ /*
+ * Occupants that the system detects as front seat passengers.
+ */
+ FRONT_PASSENGER = 1 << 1,
+ /*
+ * Occupants that the system detects as driver(s).
+ */
+ DRIVER = 1 << 2,
+ /*
+ * Occupants on left seat of row 2.
+ */
+ ROW_2_PASSENGER_LEFT = 1 << 3,
+ /*
+ * Occupants on center seat of row 2.
+ */
+ ROW_2_PASSENGER_CENTER = 1 << 4,
+ /*
+ * Occupants on right seat of row 2.
+ */
+ ROW_2_PASSENGER_RIGHT = 1 << 5,
+ /*
+ * Occupants on left seat of row 3.
+ */
+ ROW_3_PASSENGER_LEFT = 1 << 6,
+ /*
+ * Occupants on center seat of row 3.
+ */
+ ROW_3_PASSENGER_CENTER = 1 << 7,
+ /*
+ * Occupants on right seat of row 3.
+ */
+ ROW_3_PASSENGER_RIGHT = 1 << 8,
+
+ /*
+ * Occupants that the system detects as front seat occupant.
+ * FRONT_OCCUPANTS = DRIVER | FRONT_PASSENGER
+ */
+ FRONT_OCCUPANTS = 1 << 1 | 1 << 2,
+ /*
+ * Occupants of row 2.
+ * ROW_2_OCCUPANTS = ROW_2_PASSENGER_LEFT | ROW_2_PASSENGER_CENTER | ROW_2_PASSENGER_RIGHT
+ */
+ ROW_2_OCCUPANTS = 1 << 3 | 1 << 4 | 1 << 5,
+ /*
+ * Occupants of row 3.
+ * ROW_3_OCCUPANTS = ROW_3_PASSENGER_LEFT | ROW_3_PASSENGER_CENTER | ROW_3_PASSENGER_RIGHT
+ */
+ ROW_3_OCCUPANTS = 1 << 6 | 1 << 7 | 1 << 8,
+ /*
+ * All the occupants in the vehicle.
+ * ALL_OCCUPANTS = UNKNOWN | FRONT_OCCUPANTS | ROW_2_OCCUPANTS | ROW_3_OCCUPANTS
+ */
+ ALL_OCCUPANTS = 0x1FF,
+}
diff --git a/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/VehicleRegion.aidl b/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/VehicleRegion.aidl
new file mode 100644
index 0000000..9ee9d52
--- /dev/null
+++ b/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/VehicleRegion.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2019 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.occupant_awareness;
+
+@VintfStability
+@Backing(type="int")
+enum VehicleRegion {
+ /*
+ * List of targets in the car.
+ */
+ UNKNOWN = 0,
+ INSTRUMENT_CLUSTER = 1,
+ REAR_VIEW_MIRROR = 2,
+ LEFT_SIDE_MIRROR = 3,
+ RIGHT_SIDE_MIRROR = 4,
+ FORWARD_ROADWAY = 5,
+ LEFT_ROADWAY = 6,
+ RIGHT_ROADWAY = 7,
+ HEAD_UNIT_DISPLAY = 8,
+ /*
+ * Vendors can use this value along with customGazeTarget string to uniquely identify their
+ * custom region.
+ */
+ CUSTOM_TARGET = 200,
+}
diff --git a/automotive/occupant_awareness/aidl/default/Android.bp b/automotive/occupant_awareness/aidl/default/Android.bp
new file mode 100644
index 0000000..1b2fba2
--- /dev/null
+++ b/automotive/occupant_awareness/aidl/default/Android.bp
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+cc_binary {
+ name: "android.hardware.automotive.occupant_awareness@1.0-service",
+ init_rc: ["android.hardware.automotive.occupant_awareness@1.0-service.rc"],
+ relative_install_path: "hw",
+ vendor: true,
+ srcs: [
+ "service.cpp",
+ "OccupantAwareness.cpp",
+ ],
+ shared_libs: [
+ "libbase",
+ "libbinder_ndk",
+ "libutils",
+ "android.hardware.automotive.occupant_awareness-ndk_platform",
+ ],
+}
diff --git a/automotive/occupant_awareness/aidl/default/OccupantAwareness.cpp b/automotive/occupant_awareness/aidl/default/OccupantAwareness.cpp
new file mode 100644
index 0000000..a156075
--- /dev/null
+++ b/automotive/occupant_awareness/aidl/default/OccupantAwareness.cpp
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#include "OccupantAwareness.h"
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace occupant_awareness {
+namespace V1_0 {
+namespace implementation {
+
+using ndk::ScopedAStatus;
+
+static const int32_t kAllCapabilities = OccupantAwareness::CAP_PRESENCE_DETECTION |
+ OccupantAwareness::CAP_GAZE_DETECTION |
+ OccupantAwareness::CAP_DRIVER_MONITORING_DETECTION;
+
+ScopedAStatus OccupantAwareness::startDetection(OccupantAwarenessStatus* status) {
+ std::lock_guard<std::mutex> lock(mMutex);
+ if (mStatus != OccupantAwarenessStatus::NOT_SUPPORTED) {
+ mStatus = OccupantAwarenessStatus::NOT_SUPPORTED;
+ if (mCallback) {
+ mCallback->onSystemStatusChanged(kAllCapabilities,
+ OccupantAwarenessStatus::NOT_SUPPORTED);
+ }
+ }
+ *status = mStatus;
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus OccupantAwareness::stopDetection(OccupantAwarenessStatus* status) {
+ std::lock_guard<std::mutex> lock(mMutex);
+ if (mStatus != OccupantAwarenessStatus::NOT_INITIALIZED) {
+ mStatus = OccupantAwarenessStatus::NOT_INITIALIZED;
+ if (mCallback) {
+ mCallback->onSystemStatusChanged(kAllCapabilities,
+ OccupantAwarenessStatus::NOT_INITIALIZED);
+ }
+ }
+ *status = mStatus;
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus OccupantAwareness::getCapabilityForRole(Role occupantRole, int32_t* capabilities) {
+ if (!isValidRole(occupantRole)) {
+ return ScopedAStatus::fromExceptionCode(EX_TRANSACTION_FAILED);
+ }
+
+ // No awareness capability for default HAL.
+ *capabilities = 0;
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus OccupantAwareness::getState(Role occupantRole, int detectionCapability,
+ OccupantAwarenessStatus* status) {
+ if (!isValidRole(occupantRole)) {
+ return ScopedAStatus::fromExceptionCode(EX_TRANSACTION_FAILED);
+ }
+
+ if (!isValidDetectionCapabilities(detectionCapability) ||
+ !isSingularCapability(detectionCapability)) {
+ return ScopedAStatus::fromExceptionCode(EX_TRANSACTION_FAILED);
+ }
+
+ std::lock_guard<std::mutex> lock(mMutex);
+ *status = mStatus;
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus OccupantAwareness::setCallback(
+ const std::shared_ptr<IOccupantAwarenessClientCallback>& callback) {
+ if (callback == nullptr) {
+ return ScopedAStatus::fromExceptionCode(EX_TRANSACTION_FAILED);
+ }
+
+ std::lock_guard<std::mutex> lock(mMutex);
+ mCallback = callback;
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus OccupantAwareness::getLatestDetection(OccupantDetections* detections) {
+ // No detection generated for default hal.
+ (void)detections;
+ return ScopedAStatus::fromExceptionCode(EX_TRANSACTION_FAILED);
+}
+
+bool OccupantAwareness::isValidRole(Role occupantRole) {
+ int intVal = static_cast<int>(occupantRole);
+ int allOccupants = static_cast<int>(Role::ALL_OCCUPANTS);
+ return (occupantRole != Role::INVALID) && ((intVal & (~allOccupants)) == 0);
+}
+
+bool OccupantAwareness::isValidDetectionCapabilities(int detectionCapabilities) {
+ return (detectionCapabilities != CAP_NONE) &&
+ ((detectionCapabilities & (~kAllCapabilities)) == 0);
+}
+
+bool OccupantAwareness::isSingularCapability(int detectionCapability) {
+ // Check whether the value is 0, or the value has only one bit set.
+ return (detectionCapability & (detectionCapability - 1)) == 0;
+}
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace occupant_awareness
+} // namespace automotive
+} // namespace hardware
+} // namespace android
diff --git a/automotive/occupant_awareness/aidl/default/OccupantAwareness.h b/automotive/occupant_awareness/aidl/default/OccupantAwareness.h
new file mode 100644
index 0000000..ac51aa4
--- /dev/null
+++ b/automotive/occupant_awareness/aidl/default/OccupantAwareness.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#pragma once
+#include <aidl/android/hardware/automotive/occupant_awareness/BnOccupantAwareness.h>
+#include <aidl/android/hardware/automotive/occupant_awareness/BnOccupantAwarenessClientCallback.h>
+#include <utils/StrongPointer.h>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace occupant_awareness {
+namespace V1_0 {
+namespace implementation {
+
+using ::aidl::android::hardware::automotive::occupant_awareness::BnOccupantAwareness;
+using ::aidl::android::hardware::automotive::occupant_awareness::IOccupantAwarenessClientCallback;
+using ::aidl::android::hardware::automotive::occupant_awareness::OccupantAwarenessStatus;
+using ::aidl::android::hardware::automotive::occupant_awareness::OccupantDetections;
+using ::aidl::android::hardware::automotive::occupant_awareness::Role;
+
+/**
+ * The default HAL mimics a system which has no Occupant awareness capability. The hal does not
+ * do any useful work, and returns appropriate failure code / status.
+ **/
+class OccupantAwareness : public BnOccupantAwareness {
+ public:
+ // Methods from ::android::hardware::automotive::occupant_awareness::IOccupantAwareness
+ // follow.
+ ndk::ScopedAStatus startDetection(OccupantAwarenessStatus* status) override;
+ ndk::ScopedAStatus stopDetection(OccupantAwarenessStatus* status) override;
+ ndk::ScopedAStatus getCapabilityForRole(Role occupantRole, int32_t* capabilities) override;
+ ndk::ScopedAStatus getState(Role occupantRole, int detectionCapability,
+ OccupantAwarenessStatus* status) override;
+ ndk::ScopedAStatus setCallback(
+ const std::shared_ptr<IOccupantAwarenessClientCallback>& callback) override;
+ ndk::ScopedAStatus getLatestDetection(OccupantDetections* detections) override;
+
+ private:
+ bool isValidRole(Role occupantRole);
+ bool isValidDetectionCapabilities(int detectionCapabilities);
+ bool isSingularCapability(int detectionCapability);
+
+ std::mutex mMutex;
+ std::shared_ptr<IOccupantAwarenessClientCallback> mCallback = nullptr;
+ OccupantAwarenessStatus mStatus = OccupantAwarenessStatus::NOT_INITIALIZED;
+};
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace occupant_awareness
+} // namespace automotive
+} // namespace hardware
+} // namespace android
diff --git a/automotive/occupant_awareness/aidl/default/android.hardware.automotive.occupant_awareness@1.0-service.rc b/automotive/occupant_awareness/aidl/default/android.hardware.automotive.occupant_awareness@1.0-service.rc
new file mode 100644
index 0000000..35d5bca
--- /dev/null
+++ b/automotive/occupant_awareness/aidl/default/android.hardware.automotive.occupant_awareness@1.0-service.rc
@@ -0,0 +1,4 @@
+service hal_occupant_awareness_default /vendor/bin/hw/android.hardware.automotive.occupant_awareness@1.0-service
+ class hal
+ user system
+ group system
diff --git a/automotive/occupant_awareness/aidl/default/service.cpp b/automotive/occupant_awareness/aidl/default/service.cpp
new file mode 100644
index 0000000..44960fb
--- /dev/null
+++ b/automotive/occupant_awareness/aidl/default/service.cpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2016 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 "android.hardware.automotive.occupant_awareness@1.0-service"
+
+#include <unistd.h>
+
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+
+#include "OccupantAwareness.h"
+
+using ::aidl::android::hardware::automotive::occupant_awareness::IOccupantAwareness;
+using ::android::hardware::automotive::occupant_awareness::V1_0::implementation::OccupantAwareness;
+using ::ndk::ScopedAStatus;
+using ::ndk::SharedRefBase;
+
+const static char kOccupantAwarenessServiceName[] = "default";
+
+int main() {
+ ABinderProcess_setThreadPoolMaxThreadCount(0);
+ LOG(INFO) << "Occupant Awareness service is starting";
+ std::shared_ptr<OccupantAwareness> occupantAwareness = SharedRefBase::make<OccupantAwareness>();
+
+ const std::string instance =
+ std::string() + IOccupantAwareness::descriptor + "/" + kOccupantAwarenessServiceName;
+
+ binder_status_t status =
+ AServiceManager_addService(occupantAwareness->asBinder().get(), instance.c_str());
+ if (status == STATUS_OK) {
+ LOG(INFO) << "Service " << kOccupantAwarenessServiceName << " is ready";
+ ABinderProcess_joinThreadPool();
+ } else {
+ LOG(ERROR) << "Could not register service " << kOccupantAwarenessServiceName
+ << ", status: " << status;
+ }
+
+ // In normal operation, we don't expect the thread pool to exit.
+ LOG(ERROR) << "Occupant Awareness service is shutting down";
+ return 1;
+}
diff --git a/automotive/occupant_awareness/aidl/mock/Android.bp b/automotive/occupant_awareness/aidl/mock/Android.bp
new file mode 100644
index 0000000..4b30866
--- /dev/null
+++ b/automotive/occupant_awareness/aidl/mock/Android.bp
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+cc_binary {
+ name: "android.hardware.automotive.occupant_awareness@1.0-service_mock",
+ relative_install_path: "hw",
+ vendor: true,
+ srcs: [
+ "service.cpp",
+ "OccupantAwareness.cpp",
+ "DetectionGenerator.cpp",
+ ],
+ shared_libs: [
+ "libbase",
+ "libbinder_ndk",
+ "libutils",
+ "android.hardware.automotive.occupant_awareness-ndk_platform",
+ ],
+}
diff --git a/automotive/occupant_awareness/aidl/mock/DetectionGenerator.cpp b/automotive/occupant_awareness/aidl/mock/DetectionGenerator.cpp
new file mode 100644
index 0000000..79d4dbc
--- /dev/null
+++ b/automotive/occupant_awareness/aidl/mock/DetectionGenerator.cpp
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#include <utils/SystemClock.h>
+
+#include "DetectionGenerator.h"
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace occupant_awareness {
+namespace V1_0 {
+namespace implementation {
+
+using ::aidl::android::hardware::automotive::occupant_awareness::ConfidenceLevel;
+using ::aidl::android::hardware::automotive::occupant_awareness::DriverMonitoringDetection;
+using ::aidl::android::hardware::automotive::occupant_awareness::OccupantDetection;
+using ::aidl::android::hardware::automotive::occupant_awareness::PresenceDetection;
+
+static int64_t kNanoSecondsPerMilliSecond = 1000 * 1000;
+
+OccupantDetections DetectionGenerator::GetNextDetections() {
+ OccupantDetections detections;
+ detections.timeStampMillis = android::elapsedRealtimeNano() / kNanoSecondsPerMilliSecond;
+ int remainingRoles = getSupportedRoles();
+ while (remainingRoles) {
+ int currentRole = remainingRoles & (~(remainingRoles - 1));
+ remainingRoles = remainingRoles & (remainingRoles - 1);
+
+ OccupantDetection occupantDetection;
+ occupantDetection.role = static_cast<Role>(currentRole);
+
+ // Add presence detection object for this occupant.
+ PresenceDetection presenceDetection;
+ presenceDetection.isOccupantDetected = true;
+ presenceDetection.detectionDurationMillis = detections.timeStampMillis;
+ occupantDetection.presenceData.emplace_back(presenceDetection);
+
+ if (occupantDetection.role == Role::DRIVER) {
+ // Add driver monitoring detection object for this occupant.
+ DriverMonitoringDetection driverMonitoringDetection;
+ driverMonitoringDetection.confidenceScore = ConfidenceLevel::HIGH;
+ driverMonitoringDetection.isLookingOnRoad = 0;
+ driverMonitoringDetection.gazeDurationMillis = detections.timeStampMillis;
+ occupantDetection.attentionData.emplace_back(driverMonitoringDetection);
+ }
+
+ detections.detections.emplace_back(occupantDetection);
+ }
+ return detections;
+}
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace occupant_awareness
+} // namespace automotive
+} // namespace hardware
+} // namespace android
diff --git a/automotive/occupant_awareness/aidl/mock/DetectionGenerator.h b/automotive/occupant_awareness/aidl/mock/DetectionGenerator.h
new file mode 100644
index 0000000..0884685
--- /dev/null
+++ b/automotive/occupant_awareness/aidl/mock/DetectionGenerator.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/automotive/occupant_awareness/BnOccupantAwareness.h>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace occupant_awareness {
+namespace V1_0 {
+namespace implementation {
+
+using ::aidl::android::hardware::automotive::occupant_awareness::BnOccupantAwareness;
+using ::aidl::android::hardware::automotive::occupant_awareness::OccupantDetections;
+using ::aidl::android::hardware::automotive::occupant_awareness::Role;
+
+class DetectionGenerator {
+ public:
+ static int getSupportedRoles() {
+ return static_cast<int>(Role::DRIVER) | static_cast<int>(Role::FRONT_PASSENGER);
+ }
+ static int getSupportedCapabilities() {
+ return static_cast<int>(BnOccupantAwareness::CAP_PRESENCE_DETECTION) |
+ static_cast<int>(BnOccupantAwareness::CAP_DRIVER_MONITORING_DETECTION);
+ }
+
+ OccupantDetections GetNextDetections();
+};
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace occupant_awareness
+} // namespace automotive
+} // namespace hardware
+} // namespace android
diff --git a/automotive/occupant_awareness/aidl/mock/OccupantAwareness.cpp b/automotive/occupant_awareness/aidl/mock/OccupantAwareness.cpp
new file mode 100644
index 0000000..910760a
--- /dev/null
+++ b/automotive/occupant_awareness/aidl/mock/OccupantAwareness.cpp
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#include <utils/SystemClock.h>
+
+#include "OccupantAwareness.h"
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace occupant_awareness {
+namespace V1_0 {
+namespace implementation {
+
+using ndk::ScopedAStatus;
+
+static const int32_t kAllCapabilities = OccupantAwareness::CAP_PRESENCE_DETECTION |
+ OccupantAwareness::CAP_GAZE_DETECTION |
+ OccupantAwareness::CAP_DRIVER_MONITORING_DETECTION;
+
+constexpr int64_t kNanoSecondsPerMilliSecond = 1000 * 1000;
+
+ScopedAStatus OccupantAwareness::startDetection(OccupantAwarenessStatus* status) {
+ std::lock_guard<std::mutex> lock(mMutex);
+ if (mStatus != OccupantAwarenessStatus::NOT_INITIALIZED) {
+ return ScopedAStatus::fromExceptionCode(EX_TRANSACTION_FAILED);
+ }
+
+ mStatus = OccupantAwarenessStatus::READY;
+ mWorkerThread = std::thread(startWorkerThread, this);
+ if (mCallback) {
+ mCallback->onSystemStatusChanged(kAllCapabilities, mStatus);
+ }
+
+ *status = mStatus;
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus OccupantAwareness::stopDetection(OccupantAwarenessStatus* status) {
+ std::lock_guard<std::mutex> lock(mMutex);
+ if (mStatus != OccupantAwarenessStatus::READY) {
+ return ScopedAStatus::fromExceptionCode(EX_TRANSACTION_FAILED);
+ }
+
+ mStatus = OccupantAwarenessStatus::NOT_INITIALIZED;
+ mWorkerThread.join();
+ if (mCallback) {
+ mCallback->onSystemStatusChanged(kAllCapabilities, mStatus);
+ }
+
+ *status = mStatus;
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus OccupantAwareness::getCapabilityForRole(Role occupantRole, int32_t* capabilities) {
+ if (!isValidRole(occupantRole)) {
+ return ScopedAStatus::fromExceptionCode(EX_TRANSACTION_FAILED);
+ }
+
+ int intVal = static_cast<int>(occupantRole);
+ if ((intVal & DetectionGenerator::getSupportedRoles()) == intVal) {
+ int capabilities_ = DetectionGenerator::getSupportedCapabilities();
+ if (occupantRole != Role::DRIVER) {
+ capabilities_ &= ~CAP_DRIVER_MONITORING_DETECTION;
+ }
+ *capabilities = capabilities_;
+ } else {
+ *capabilities = 0;
+ }
+
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus OccupantAwareness::getState(Role occupantRole, int detectionCapability,
+ OccupantAwarenessStatus* status) {
+ if (!isValidRole(occupantRole)) {
+ return ScopedAStatus::fromExceptionCode(EX_TRANSACTION_FAILED);
+ }
+
+ if (!isValidDetectionCapabilities(detectionCapability) ||
+ !isSingularCapability(detectionCapability)) {
+ return ScopedAStatus::fromExceptionCode(EX_TRANSACTION_FAILED);
+ }
+
+ int roleVal = static_cast<int>(occupantRole);
+
+ if (((roleVal & DetectionGenerator::getSupportedRoles()) != roleVal) ||
+ ((detectionCapability & DetectionGenerator::getSupportedCapabilities()) !=
+ detectionCapability)) {
+ *status = OccupantAwarenessStatus::NOT_SUPPORTED;
+ return ScopedAStatus::ok();
+ }
+
+ std::lock_guard<std::mutex> lock(mMutex);
+ *status = mStatus;
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus OccupantAwareness::setCallback(
+ const std::shared_ptr<IOccupantAwarenessClientCallback>& callback) {
+ if (callback == nullptr) {
+ return ScopedAStatus::fromExceptionCode(EX_TRANSACTION_FAILED);
+ }
+
+ std::lock_guard<std::mutex> lock(mMutex);
+ mCallback = callback;
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus OccupantAwareness::getLatestDetection(OccupantDetections* detections) {
+ std::lock_guard<std::mutex> lock(mMutex);
+
+ if (mStatus != OccupantAwarenessStatus::READY) {
+ return ScopedAStatus::fromExceptionCode(EX_TRANSACTION_FAILED);
+ }
+
+ *detections = mLatestDetections;
+ return ScopedAStatus::ok();
+}
+
+bool OccupantAwareness::isValidRole(Role occupantRole) {
+ int intVal = static_cast<int>(occupantRole);
+ int allOccupants = static_cast<int>(Role::ALL_OCCUPANTS);
+ return (occupantRole != Role::INVALID) && ((intVal & (~allOccupants)) == 0);
+}
+
+bool OccupantAwareness::isValidDetectionCapabilities(int detectionCapabilities) {
+ return (detectionCapabilities != OccupantAwareness::CAP_NONE) &&
+ ((detectionCapabilities & (~kAllCapabilities)) == 0);
+}
+
+bool OccupantAwareness::isSingularCapability(int detectionCapability) {
+ // Check whether the value is 0, or the value has only one bit set.
+ return (detectionCapability & (detectionCapability - 1)) == 0;
+}
+
+void OccupantAwareness::startWorkerThread(OccupantAwareness* occupantAwareness) {
+ occupantAwareness->workerThreadFunction();
+}
+
+void OccupantAwareness::workerThreadFunction() {
+ bool isFirstDetection = true;
+ int64_t prevDetectionTimeMs;
+ while (mStatus == OccupantAwarenessStatus::READY) {
+ int64_t currentTimeMs = android::elapsedRealtimeNano() / kNanoSecondsPerMilliSecond;
+ if ((isFirstDetection) || (currentTimeMs - prevDetectionTimeMs > mDetectionDurationMs)) {
+ std::lock_guard<std::mutex> lock(mMutex);
+ mLatestDetections = mGenerator.GetNextDetections();
+ if (mCallback != nullptr) {
+ mCallback->onDetectionEvent(mLatestDetections);
+ }
+ isFirstDetection = false;
+ prevDetectionTimeMs = currentTimeMs;
+ }
+ }
+}
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace occupant_awareness
+} // namespace automotive
+} // namespace hardware
+} // namespace android
diff --git a/automotive/occupant_awareness/aidl/mock/OccupantAwareness.h b/automotive/occupant_awareness/aidl/mock/OccupantAwareness.h
new file mode 100644
index 0000000..c5f6dd6
--- /dev/null
+++ b/automotive/occupant_awareness/aidl/mock/OccupantAwareness.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#pragma once
+
+#include <thread>
+
+#include <aidl/android/hardware/automotive/occupant_awareness/BnOccupantAwareness.h>
+#include <aidl/android/hardware/automotive/occupant_awareness/BnOccupantAwarenessClientCallback.h>
+#include <utils/StrongPointer.h>
+
+#include "DetectionGenerator.h"
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace occupant_awareness {
+namespace V1_0 {
+namespace implementation {
+
+using ::aidl::android::hardware::automotive::occupant_awareness::BnOccupantAwareness;
+using ::aidl::android::hardware::automotive::occupant_awareness::IOccupantAwarenessClientCallback;
+using ::aidl::android::hardware::automotive::occupant_awareness::OccupantAwarenessStatus;
+using ::aidl::android::hardware::automotive::occupant_awareness::OccupantDetections;
+using ::aidl::android::hardware::automotive::occupant_awareness::Role;
+
+/**
+ * The mock HAL can detect presence of Driver and front passenger, and driver awareness detection
+ * for driver.
+ **/
+class OccupantAwareness : public BnOccupantAwareness {
+ public:
+ // Methods from ::android::hardware::automotive::occupant_awareness::IOccupantAwareness
+ // follow.
+ ndk::ScopedAStatus startDetection(OccupantAwarenessStatus* status) override;
+ ndk::ScopedAStatus stopDetection(OccupantAwarenessStatus* status) override;
+ ndk::ScopedAStatus getCapabilityForRole(Role occupantRole, int32_t* capabilities) override;
+ ndk::ScopedAStatus getState(Role occupantRole, int detectionCapability,
+ OccupantAwarenessStatus* status) override;
+ ndk::ScopedAStatus setCallback(
+ const std::shared_ptr<IOccupantAwarenessClientCallback>& callback) override;
+ ndk::ScopedAStatus getLatestDetection(OccupantDetections* detections) override;
+
+ private:
+ bool isValidRole(Role occupantRole);
+ bool isValidDetectionCapabilities(int detectionCapabilities);
+ bool isSingularCapability(int detectionCapability);
+
+ void workerThreadFunction();
+ static void startWorkerThread(OccupantAwareness* occupantAwareness);
+
+ std::mutex mMutex;
+ std::shared_ptr<IOccupantAwarenessClientCallback> mCallback = nullptr;
+ OccupantAwarenessStatus mStatus = OccupantAwarenessStatus::NOT_INITIALIZED;
+
+ OccupantDetections mLatestDetections;
+ std::thread mWorkerThread;
+
+ DetectionGenerator mGenerator;
+
+ // Generate a new detection every 1ms.
+ const int64_t mDetectionDurationMs = 1;
+};
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace occupant_awareness
+} // namespace automotive
+} // namespace hardware
+} // namespace android
diff --git a/automotive/occupant_awareness/aidl/mock/service.cpp b/automotive/occupant_awareness/aidl/mock/service.cpp
new file mode 100644
index 0000000..d8860df
--- /dev/null
+++ b/automotive/occupant_awareness/aidl/mock/service.cpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2016 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 "android.hardware.automotive.occupant_awareness@1.0-service_mock"
+
+#include <unistd.h>
+
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+
+#include "OccupantAwareness.h"
+
+using ::aidl::android::hardware::automotive::occupant_awareness::IOccupantAwareness;
+using ::android::hardware::automotive::occupant_awareness::V1_0::implementation::OccupantAwareness;
+using ::ndk::ScopedAStatus;
+using ::ndk::SharedRefBase;
+
+const static char kOccupantAwarenessServiceName[] = "default";
+
+int main() {
+ ABinderProcess_setThreadPoolMaxThreadCount(0);
+ LOG(INFO) << "Occupant Awareness service is starting";
+ std::shared_ptr<OccupantAwareness> occupantAwareness = SharedRefBase::make<OccupantAwareness>();
+
+ const std::string instance =
+ std::string() + IOccupantAwareness::descriptor + "/" + kOccupantAwarenessServiceName;
+
+ binder_status_t status =
+ AServiceManager_addService(occupantAwareness->asBinder().get(), instance.c_str());
+ if (status == STATUS_OK) {
+ LOG(INFO) << "Service " << kOccupantAwarenessServiceName << " is ready";
+ ABinderProcess_joinThreadPool();
+ } else {
+ LOG(ERROR) << "Could not register service " << kOccupantAwarenessServiceName
+ << ", status: " << status;
+ }
+
+ // In normal operation, we don't expect the thread pool to exit.
+ LOG(ERROR) << "Occupant Awareness service is shutting down";
+ return 1;
+}
diff --git a/automotive/occupant_awareness/aidl/vts/functional/Android.bp b/automotive/occupant_awareness/aidl/vts/functional/Android.bp
new file mode 100644
index 0000000..1256b69
--- /dev/null
+++ b/automotive/occupant_awareness/aidl/vts/functional/Android.bp
@@ -0,0 +1,17 @@
+cc_test {
+ name: "VtsHalOccupantAwarenessV1_0TargetTest",
+ defaults: [
+ "VtsHalTargetTestDefaults",
+ "use_libaidlvintf_gtest_helper_static",
+ ],
+ srcs: ["VtsHalOccupantAwarenessV1_0TargetTest.cpp"],
+ shared_libs: [
+ "libbinder",
+ ],
+ static_libs: [
+ "android.hardware.automotive.occupant_awareness-cpp",
+ ],
+ test_suites: [
+ "vts-core",
+ ],
+}
diff --git a/automotive/occupant_awareness/aidl/vts/functional/VtsHalOccupantAwarenessV1_0TargetTest.cpp b/automotive/occupant_awareness/aidl/vts/functional/VtsHalOccupantAwarenessV1_0TargetTest.cpp
new file mode 100644
index 0000000..c431f9d
--- /dev/null
+++ b/automotive/occupant_awareness/aidl/vts/functional/VtsHalOccupantAwarenessV1_0TargetTest.cpp
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) 2019 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 "**** HAL log ****"
+
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <android-base/logging.h>
+#include <android/hardware/automotive/occupant_awareness/BnOccupantAwarenessClientCallback.h>
+#include <android/hardware/automotive/occupant_awareness/IOccupantAwareness.h>
+#include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+#include <gtest/gtest.h>
+
+#include <chrono>
+#include <future>
+#include <vector>
+
+using namespace android::hardware::automotive::occupant_awareness;
+using android::hardware::automotive::occupant_awareness::IOccupantAwareness;
+
+using android::ProcessState;
+using android::sp;
+using android::String16;
+using android::binder::Status;
+
+constexpr auto kTimeout = std::chrono::seconds(3);
+
+#define EXPECT_OK(ret) ASSERT_TRUE((ret).isOk())
+
+class OccupantAwarenessCallback : public BnOccupantAwarenessClientCallback {
+ public:
+ OccupantAwarenessCallback(const std::function<void(int, OccupantAwarenessStatus)>& callback)
+ : mCallback(callback) {}
+ Status onSystemStatusChanged(int detectionFlags, OccupantAwarenessStatus status) override {
+ mCallback(detectionFlags, status);
+ return Status::ok();
+ }
+
+ Status onDetectionEvent(const OccupantDetections& detections) override {
+ (void)detections;
+ return Status::ok();
+ }
+
+ private:
+ std::function<void(int, OccupantAwarenessStatus)> mCallback;
+};
+
+class OccupantAwarenessAidl : public testing::TestWithParam<std::string> {
+ public:
+ virtual void SetUp() override {
+ mOccupantAwarenessService =
+ android::waitForDeclaredService<IOccupantAwareness>(String16(GetParam().c_str()));
+ ASSERT_NE(mOccupantAwarenessService, nullptr);
+ }
+
+ sp<IOccupantAwareness> mOccupantAwarenessService;
+};
+
+// Test that startDetection() returns within the timeout.
+TEST_P(OccupantAwarenessAidl, StartDetectionTest) {
+ auto start = std::chrono::system_clock::now();
+ OccupantAwarenessStatus occupantAwarenessStatus;
+ Status status = mOccupantAwarenessService->startDetection(&occupantAwarenessStatus);
+ auto elapsed = std::chrono::system_clock::now() - start;
+ EXPECT_OK(status);
+ ASSERT_LE(elapsed, kTimeout);
+
+ EXPECT_OK(mOccupantAwarenessService->stopDetection(&occupantAwarenessStatus));
+}
+
+// Test that getCapabilityForRole() returns supported capabilities for the role. The test only
+// verifies that the IPC call returns successfully and does not verify the supported capabilities.
+TEST_P(OccupantAwarenessAidl, GetCapabilityTest) {
+ std::vector<Role> rolesToTest = {Role::FRONT_PASSENGER, Role::DRIVER,
+ Role::ROW_2_PASSENGER_LEFT, Role::ROW_2_PASSENGER_CENTER,
+ Role::ROW_2_PASSENGER_RIGHT, Role::ROW_3_PASSENGER_LEFT,
+ Role::ROW_3_PASSENGER_CENTER, Role::ROW_3_PASSENGER_RIGHT,
+ Role::FRONT_OCCUPANTS, Role::ROW_2_OCCUPANTS,
+ Role::ROW_3_OCCUPANTS, Role::ALL_OCCUPANTS};
+
+ for (auto role : rolesToTest) {
+ int32_t capabilities;
+ EXPECT_OK(mOccupantAwarenessService->getCapabilityForRole(role, &capabilities));
+ }
+}
+
+// Test that getCapabilityForRole() returns failure when arguments are invalid.
+TEST_P(OccupantAwarenessAidl, GetCapabilityFailureTest) {
+ int32_t capabilities;
+ EXPECT_FALSE(
+ mOccupantAwarenessService->getCapabilityForRole(Role::INVALID, &capabilities).isOk());
+
+ Role invalidRole = static_cast<Role>(static_cast<int>(Role::ALL_OCCUPANTS) + 1);
+ EXPECT_FALSE(
+ mOccupantAwarenessService->getCapabilityForRole(invalidRole, &capabilities).isOk());
+}
+
+// Test that getState() returns within the timeout. The test do not attempt to verify the state, but
+// only checks that the IPC call returns successfully.
+TEST_P(OccupantAwarenessAidl, GetStateTest) {
+ std::vector<Role> rolesToTest = {Role::FRONT_PASSENGER, Role::DRIVER,
+ Role::ROW_2_PASSENGER_LEFT, Role::ROW_2_PASSENGER_CENTER,
+ Role::ROW_2_PASSENGER_RIGHT, Role::ROW_3_PASSENGER_LEFT,
+ Role::ROW_3_PASSENGER_CENTER, Role::ROW_3_PASSENGER_RIGHT,
+ Role::FRONT_OCCUPANTS, Role::ROW_2_OCCUPANTS,
+ Role::ROW_3_OCCUPANTS, Role::ALL_OCCUPANTS};
+
+ std::vector<int> detectionCapabilities = {IOccupantAwareness::CAP_PRESENCE_DETECTION,
+ IOccupantAwareness::CAP_GAZE_DETECTION,
+ IOccupantAwareness::CAP_DRIVER_MONITORING_DETECTION};
+
+ for (auto role : rolesToTest) {
+ for (auto detectionCapability : detectionCapabilities) {
+ OccupantAwarenessStatus oasStatus;
+ EXPECT_OK(mOccupantAwarenessService->getState(role, detectionCapability, &oasStatus));
+ }
+ }
+}
+
+// Test that getState() returns failure with invalid args.
+TEST_P(OccupantAwarenessAidl, GetStateFailureTest) {
+ // Verify that getState() returns error when role is invalid (0).
+ OccupantAwarenessStatus oasStatus;
+ EXPECT_FALSE(mOccupantAwarenessService
+ ->getState(Role::INVALID, IOccupantAwareness::CAP_PRESENCE_DETECTION,
+ &oasStatus)
+ .isOk());
+
+ // Verify that getState() returns error when role is invalid (invalid flag).
+ int invalidRole = static_cast<int>(Role::ALL_OCCUPANTS) + 1;
+ EXPECT_FALSE(mOccupantAwarenessService
+ ->getState(static_cast<Role>(invalidRole),
+ IOccupantAwareness::CAP_PRESENCE_DETECTION, &oasStatus)
+ .isOk());
+
+ // Verify that getState() returns error when capability is invalid (none).
+ EXPECT_FALSE(mOccupantAwarenessService
+ ->getState(Role::FRONT_PASSENGER, IOccupantAwareness::CAP_NONE, &oasStatus)
+ .isOk());
+
+ // Verify that getState() returns error when capability is invalid (invalid flag).
+ int invalidDetectionFlags = 0x10;
+ EXPECT_FALSE(mOccupantAwarenessService
+ ->getState(Role::FRONT_PASSENGER, invalidDetectionFlags, &oasStatus)
+ .isOk());
+}
+
+// Test that setCallback() returns within the timeout.
+TEST_P(OccupantAwarenessAidl, SetCallbackTest) {
+ sp<OccupantAwarenessCallback> callback =
+ new OccupantAwarenessCallback([](int detectionFlags, OccupantAwarenessStatus status) {
+ (void)detectionFlags;
+ (void)status;
+ });
+ auto start = std::chrono::system_clock::now();
+ Status status = mOccupantAwarenessService->setCallback(callback);
+ auto elapsed = std::chrono::system_clock::now() - start;
+ EXPECT_OK(status);
+ ASSERT_LE(elapsed, kTimeout);
+}
+
+// Test that setCallback() returns failure with invalid args.
+TEST_P(OccupantAwarenessAidl, SetCallbackFailureTest) {
+ sp<OccupantAwarenessCallback> callback = nullptr;
+ Status status = mOccupantAwarenessService->setCallback(callback);
+ EXPECT_FALSE(status.isOk());
+}
+
+// Test that getLatestDetection() returns within the timeout.
+TEST_P(OccupantAwarenessAidl, GetLatestDetectionTest) {
+ auto start = std::chrono::system_clock::now();
+ OccupantDetections detections;
+ // Do not check status here, since error status is returned when no detection is present.
+ (void)mOccupantAwarenessService->getLatestDetection(&detections);
+ auto elapsed = std::chrono::system_clock::now() - start;
+ ASSERT_LE(elapsed, kTimeout);
+}
+
+INSTANTIATE_TEST_SUITE_P(
+ InstantiationName, OccupantAwarenessAidl,
+ testing::ValuesIn(android::getAidlHalInstanceNames(IOccupantAwareness::descriptor)),
+ android::PrintInstanceNameToString);
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ ProcessState::self()->setThreadPoolMaxThreadCount(1);
+ ProcessState::self()->startThreadPool();
+ return RUN_ALL_TESTS();
+}
diff --git a/automotive/vehicle/2.0/types.hal b/automotive/vehicle/2.0/types.hal
index 279d5cd..24fcf76 100644
--- a/automotive/vehicle/2.0/types.hal
+++ b/automotive/vehicle/2.0/types.hal
@@ -2381,6 +2381,26 @@
| VehiclePropertyType:BOOLEAN
| VehicleArea:GLOBAL),
+ /**
+ * Allow disabling optional featurs from vhal.
+ *
+ * This property reports optional features that should be disabled.
+ * All allowed optional features for the system is declared in Car service overlay,
+ * config_allowed_optional_car_features.
+ * This property allows disabling features defined in the overlay. Without this property,
+ * all the features declared in the overlay will be enabled.
+ *
+ * Value read should include all features disabled with ',' separation.
+ * ex) "com.android.car.user.CarUserNoticeService,storage_monitoring"
+ * @change_mode VehiclePropertyChangeMode:STATIC
+ * @access VehiclePropertyAccess:READ
+ */
+ DISABLED_OPTIONAL_FEATURES = (
+ 0x0F06
+ | VehiclePropertyGroup:SYSTEM
+ | VehiclePropertyType:STRING
+ | VehicleArea:GLOBAL),
+
};
/**
diff --git a/biometrics/face/1.0/vts/functional/Android.bp b/biometrics/face/1.0/vts/functional/Android.bp
index fa68c4e..f2598a7 100644
--- a/biometrics/face/1.0/vts/functional/Android.bp
+++ b/biometrics/face/1.0/vts/functional/Android.bp
@@ -19,6 +19,6 @@
defaults: ["VtsHalTargetTestDefaults"],
srcs: ["VtsHalBiometricsFaceV1_0TargetTest.cpp"],
static_libs: ["android.hardware.biometrics.face@1.0"],
- test_suites: ["general-tests"],
+ test_suites: ["general-tests", "vts-core"],
}
diff --git a/biometrics/face/1.0/vts/functional/VtsHalBiometricsFaceV1_0TargetTest.cpp b/biometrics/face/1.0/vts/functional/VtsHalBiometricsFaceV1_0TargetTest.cpp
index a4e95ed..7ac44a4 100644
--- a/biometrics/face/1.0/vts/functional/VtsHalBiometricsFaceV1_0TargetTest.cpp
+++ b/biometrics/face/1.0/vts/functional/VtsHalBiometricsFaceV1_0TargetTest.cpp
@@ -20,9 +20,10 @@
#include <android/hardware/biometrics/face/1.0/IBiometricsFaceClientCallback.h>
#include <VtsHalHidlTargetCallbackBase.h>
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
#include <android-base/logging.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include <chrono>
#include <cstdint>
@@ -124,27 +125,11 @@
}
};
-// Test environment for the BiometricsFace HAL.
-class FaceHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // Get the test environment singleton.
- static FaceHidlEnvironment* Instance() {
- static FaceHidlEnvironment* instance = new FaceHidlEnvironment;
- return instance;
- }
-
- void registerTestServices() override { registerTestService<IBiometricsFace>(); }
-
- private:
- FaceHidlEnvironment() = default;
-};
-
// Test class for the BiometricsFace HAL.
-class FaceHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+class FaceHidlTest : public ::testing::TestWithParam<std::string> {
public:
void SetUp() override {
- mService = ::testing::VtsHalHidlTargetTestBase::getService<IBiometricsFace>(
- FaceHidlEnvironment::Instance()->getServiceName<IBiometricsFace>());
+ mService = IBiometricsFace::getService(GetParam());
ASSERT_NE(mService, nullptr);
mCallback = new FaceCallback();
mCallback->SetWaitTimeoutDefault(kTimeout);
@@ -167,7 +152,7 @@
// generateChallenge should always return a unique, cryptographically secure,
// non-zero number.
-TEST_F(FaceHidlTest, GenerateChallengeTest) {
+TEST_P(FaceHidlTest, GenerateChallengeTest) {
std::map<uint64_t, int> m;
for (int i = 0; i < kGenerateChallengeIterations; ++i) {
Return<void> ret =
@@ -182,7 +167,7 @@
}
// enroll with an invalid (all zeroes) HAT should fail.
-TEST_F(FaceHidlTest, EnrollZeroHatTest) {
+TEST_P(FaceHidlTest, EnrollZeroHatTest) {
// Filling HAT with zeros
hidl_vec<uint8_t> token(69);
for (size_t i = 0; i < 69; i++) {
@@ -200,7 +185,7 @@
}
// enroll with an invalid HAT should fail.
-TEST_F(FaceHidlTest, EnrollGarbageHatTest) {
+TEST_P(FaceHidlTest, EnrollGarbageHatTest) {
// Filling HAT with pseudorandom invalid data.
// Using default seed to make the test reproducible.
std::mt19937 gen(std::mt19937::default_seed);
@@ -221,7 +206,7 @@
}
// setFeature with an invalid (all zeros) HAT should fail.
-TEST_F(FaceHidlTest, SetFeatureZeroHatTest) {
+TEST_P(FaceHidlTest, SetFeatureZeroHatTest) {
hidl_vec<uint8_t> token(69);
for (size_t i = 0; i < 69; i++) {
token[i] = 0;
@@ -232,7 +217,7 @@
}
// setFeature with an invalid HAT should fail.
-TEST_F(FaceHidlTest, SetFeatureGarbageHatTest) {
+TEST_P(FaceHidlTest, SetFeatureGarbageHatTest) {
// Filling HAT with pseudorandom invalid data.
// Using default seed to make the test reproducible.
std::mt19937 gen(std::mt19937::default_seed);
@@ -254,16 +239,16 @@
ASSERT_TRUE(res.isOk());
}
-TEST_F(FaceHidlTest, GetFeatureRequireAttentionTest) {
+TEST_P(FaceHidlTest, GetFeatureRequireAttentionTest) {
assertGetFeatureFails(mService, 0 /* faceId */, Feature::REQUIRE_ATTENTION);
}
-TEST_F(FaceHidlTest, GetFeatureRequireDiversityTest) {
+TEST_P(FaceHidlTest, GetFeatureRequireDiversityTest) {
assertGetFeatureFails(mService, 0 /* faceId */, Feature::REQUIRE_DIVERSITY);
}
// revokeChallenge should always return within the timeout
-TEST_F(FaceHidlTest, RevokeChallengeTest) {
+TEST_P(FaceHidlTest, RevokeChallengeTest) {
auto start = std::chrono::system_clock::now();
Return<Status> ret = mService->revokeChallenge();
auto elapsed = std::chrono::system_clock::now() - start;
@@ -272,14 +257,14 @@
}
// The call to getAuthenticatorId should succeed.
-TEST_F(FaceHidlTest, GetAuthenticatorIdTest) {
+TEST_P(FaceHidlTest, GetAuthenticatorIdTest) {
Return<void> ret = mService->getAuthenticatorId(
[](const OptionalUint64& res) { ASSERT_EQ(Status::OK, res.status); });
ASSERT_TRUE(ret.isOk());
}
// The call to enumerate should succeed.
-TEST_F(FaceHidlTest, EnumerateTest) {
+TEST_P(FaceHidlTest, EnumerateTest) {
Return<Status> ret = mService->enumerate();
ASSERT_EQ(Status::OK, static_cast<Status>(ret));
auto res = mCallback->WaitForCallback(kCallbackNameOnEnumerate);
@@ -288,21 +273,21 @@
}
// The call to remove should succeed for any faceId
-TEST_F(FaceHidlTest, RemoveFaceTest) {
+TEST_P(FaceHidlTest, RemoveFaceTest) {
// Remove a face
Return<Status> ret = mService->remove(kFaceId);
ASSERT_EQ(Status::OK, static_cast<Status>(ret));
}
// Remove should accept 0 to delete all faces
-TEST_F(FaceHidlTest, RemoveAllFacesTest) {
+TEST_P(FaceHidlTest, RemoveAllFacesTest) {
// Remove all faces
Return<Status> ret = mService->remove(0);
ASSERT_EQ(Status::OK, static_cast<Status>(ret));
}
// Active user should successfully set to a writable location.
-TEST_F(FaceHidlTest, SetActiveUserTest) {
+TEST_P(FaceHidlTest, SetActiveUserTest) {
// Create an active user
Return<Status> ret = mService->setActiveUser(2, kFacedataDir);
ASSERT_EQ(Status::OK, static_cast<Status>(ret));
@@ -313,7 +298,7 @@
}
// Active user should fail to set to an unwritable location.
-TEST_F(FaceHidlTest, SetActiveUserUnwritableTest) {
+TEST_P(FaceHidlTest, SetActiveUserUnwritableTest) {
// Create an active user to an unwritable location (device root dir)
Return<Status> ret = mService->setActiveUser(3, "/");
ASSERT_NE(Status::OK, static_cast<Status>(ret));
@@ -324,7 +309,7 @@
}
// Active user should fail to set to a null location.
-TEST_F(FaceHidlTest, SetActiveUserNullTest) {
+TEST_P(FaceHidlTest, SetActiveUserNullTest) {
// Create an active user to a null location.
Return<Status> ret = mService->setActiveUser(4, nullptr);
ASSERT_NE(Status::OK, static_cast<Status>(ret));
@@ -336,7 +321,7 @@
// Cancel should always return CANCELED from any starting state including
// the IDLE state.
-TEST_F(FaceHidlTest, CancelTest) {
+TEST_P(FaceHidlTest, CancelTest) {
Return<Status> ret = mService->cancel();
// check that we were able to make an IPC request successfully
ASSERT_EQ(Status::OK, static_cast<Status>(ret));
@@ -347,7 +332,7 @@
EXPECT_EQ(FaceError::CANCELED, res.args->error);
}
-TEST_F(FaceHidlTest, OnLockoutChangedTest) {
+TEST_P(FaceHidlTest, OnLockoutChangedTest) {
// Update active user and ensure onLockoutChanged was called.
Return<Status> ret = mService->setActiveUser(kUserId + 1, kFacedataDir);
ASSERT_EQ(Status::OK, static_cast<Status>(ret));
@@ -359,11 +344,7 @@
} // anonymous namespace
-int main(int argc, char** argv) {
- ::testing::AddGlobalTestEnvironment(FaceHidlEnvironment::Instance());
- ::testing::InitGoogleTest(&argc, argv);
- FaceHidlEnvironment::Instance()->init(&argc, argv);
- int status = RUN_ALL_TESTS();
- LOG(INFO) << "Test result = " << status;
- return status;
-}
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, FaceHidlTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(IBiometricsFace::descriptor)),
+ android::hardware::PrintInstanceNameToString);
diff --git a/bluetooth/audio/2.0/vts/functional/Android.bp b/bluetooth/audio/2.0/vts/functional/Android.bp
index b672fe4..b778b97 100644
--- a/bluetooth/audio/2.0/vts/functional/Android.bp
+++ b/bluetooth/audio/2.0/vts/functional/Android.bp
@@ -9,4 +9,5 @@
shared_libs: [
"libfmq",
],
+ test_suites: ["general-tests", "vts-core"],
}
diff --git a/bluetooth/audio/2.0/vts/functional/VtsHalBluetoothAudioV2_0TargetTest.cpp b/bluetooth/audio/2.0/vts/functional/VtsHalBluetoothAudioV2_0TargetTest.cpp
index 9572d3f..b3cb6f7 100644
--- a/bluetooth/audio/2.0/vts/functional/VtsHalBluetoothAudioV2_0TargetTest.cpp
+++ b/bluetooth/audio/2.0/vts/functional/VtsHalBluetoothAudioV2_0TargetTest.cpp
@@ -21,12 +21,13 @@
#include <android/hardware/bluetooth/audio/2.0/IBluetoothAudioProvider.h>
#include <android/hardware/bluetooth/audio/2.0/IBluetoothAudioProvidersFactory.h>
#include <fmq/MessageQueue.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
#include <hidl/MQDescriptor.h>
+#include <hidl/ServiceManagement.h>
#include <utils/Log.h>
#include <VtsHalHidlTargetCallbackBase.h>
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
using ::android::sp;
using ::android::hardware::hidl_vec;
@@ -105,34 +106,13 @@
}
} // namespace
-// Test environment for Bluetooth Audio HAL.
-class BluetoothAudioHidlEnvironment
- : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static BluetoothAudioHidlEnvironment* Instance() {
- static BluetoothAudioHidlEnvironment* instance =
- new BluetoothAudioHidlEnvironment;
- return instance;
- }
-
- virtual void registerTestServices() override {
- registerTestService<IBluetoothAudioProvidersFactory>();
- }
-
- private:
- BluetoothAudioHidlEnvironment() {}
-};
-
// The base test class for Bluetooth Audio HAL.
class BluetoothAudioProvidersFactoryHidlTest
- : public ::testing::VtsHalHidlTargetTestBase {
+ : public ::testing::TestWithParam<std::string> {
public:
virtual void SetUp() override {
- providers_factory_ = ::testing::VtsHalHidlTargetTestBase::getService<
- IBluetoothAudioProvidersFactory>(
- BluetoothAudioHidlEnvironment::Instance()
- ->getServiceName<IBluetoothAudioProvidersFactory>());
+ providers_factory_ =
+ IBluetoothAudioProvidersFactory::getService(GetParam());
ASSERT_NE(providers_factory_, nullptr);
}
@@ -300,13 +280,13 @@
/**
* Test whether we can get the FactoryService from HIDL
*/
-TEST_F(BluetoothAudioProvidersFactoryHidlTest, GetProvidersFactoryService) {}
+TEST_P(BluetoothAudioProvidersFactoryHidlTest, GetProvidersFactoryService) {}
/**
* Test whether we can open a provider for each provider returned by
* getProviderCapabilities() with non-empty capabalities
*/
-TEST_F(BluetoothAudioProvidersFactoryHidlTest,
+TEST_P(BluetoothAudioProvidersFactoryHidlTest,
OpenProviderAndCheckCapabilitiesBySession) {
for (auto session_type : session_types_) {
GetProviderCapabilitiesHelper(session_type);
@@ -341,14 +321,14 @@
/**
* Test whether we can open a provider of type
*/
-TEST_F(BluetoothAudioProviderA2dpSoftwareHidlTest, OpenA2dpSoftwareProvider) {}
+TEST_P(BluetoothAudioProviderA2dpSoftwareHidlTest, OpenA2dpSoftwareProvider) {}
/**
* Test whether each provider of type
* SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH can be started and stopped with
* different PCM config
*/
-TEST_F(BluetoothAudioProviderA2dpSoftwareHidlTest,
+TEST_P(BluetoothAudioProviderA2dpSoftwareHidlTest,
StartAndEndA2dpSoftwareSessionWithPossiblePcmConfig) {
bool is_codec_config_valid;
std::unique_ptr<DataMQ> tempDataMQ;
@@ -616,14 +596,14 @@
/**
* Test whether we can open a provider of type
*/
-TEST_F(BluetoothAudioProviderA2dpHardwareHidlTest, OpenA2dpHardwareProvider) {}
+TEST_P(BluetoothAudioProviderA2dpHardwareHidlTest, OpenA2dpHardwareProvider) {}
/**
* Test whether each provider of type
* SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
* SBC hardware encoding config
*/
-TEST_F(BluetoothAudioProviderA2dpHardwareHidlTest,
+TEST_P(BluetoothAudioProviderA2dpHardwareHidlTest,
StartAndEndA2dpSbcHardwareSession) {
if (!IsOffloadSupported()) {
return;
@@ -658,7 +638,7 @@
* SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
* AAC hardware encoding config
*/
-TEST_F(BluetoothAudioProviderA2dpHardwareHidlTest,
+TEST_P(BluetoothAudioProviderA2dpHardwareHidlTest,
StartAndEndA2dpAacHardwareSession) {
if (!IsOffloadSupported()) {
return;
@@ -693,7 +673,7 @@
* SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
* LDAC hardware encoding config
*/
-TEST_F(BluetoothAudioProviderA2dpHardwareHidlTest,
+TEST_P(BluetoothAudioProviderA2dpHardwareHidlTest,
StartAndEndA2dpLdacHardwareSession) {
if (!IsOffloadSupported()) {
return;
@@ -728,7 +708,7 @@
* SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
* AptX hardware encoding config
*/
-TEST_F(BluetoothAudioProviderA2dpHardwareHidlTest,
+TEST_P(BluetoothAudioProviderA2dpHardwareHidlTest,
StartAndEndA2dpAptxHardwareSession) {
if (!IsOffloadSupported()) {
return;
@@ -767,7 +747,7 @@
* SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
* an invalid codec config
*/
-TEST_F(BluetoothAudioProviderA2dpHardwareHidlTest,
+TEST_P(BluetoothAudioProviderA2dpHardwareHidlTest,
StartAndEndA2dpHardwareSessionInvalidCodecConfig) {
if (!IsOffloadSupported()) {
return;
@@ -857,7 +837,7 @@
* SessionType::HEARING_AID_HARDWARE_ENCODING_DATAPATH can be started and
* stopped with SBC hardware encoding config
*/
-TEST_F(BluetoothAudioProviderHearingAidSoftwareHidlTest,
+TEST_P(BluetoothAudioProviderHearingAidSoftwareHidlTest,
OpenHearingAidSoftwareProvider) {}
/**
@@ -865,7 +845,7 @@
* SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH can be started and
* stopped with different PCM config
*/
-TEST_F(BluetoothAudioProviderHearingAidSoftwareHidlTest,
+TEST_P(BluetoothAudioProviderHearingAidSoftwareHidlTest,
StartAndEndHearingAidSessionWithPossiblePcmConfig) {
bool is_codec_config_valid;
std::unique_ptr<DataMQ> tempDataMQ;
@@ -904,12 +884,25 @@
} // SampleRate
}
-int main(int argc, char** argv) {
- ::testing::AddGlobalTestEnvironment(
- BluetoothAudioHidlEnvironment::Instance());
- ::testing::InitGoogleTest(&argc, argv);
- BluetoothAudioHidlEnvironment::Instance()->init(&argc, argv);
- int status = RUN_ALL_TESTS();
- LOG(INFO) << "Test result = " << status;
- return status;
-}
+static const std::vector<std::string> kAudioInstances =
+ android::hardware::getAllHalInstanceNames(
+ IBluetoothAudioProvidersFactory::descriptor);
+
+INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAudioProvidersFactoryHidlTest,
+ testing::ValuesIn(kAudioInstances),
+ android::hardware::PrintInstanceNameToString);
+
+INSTANTIATE_TEST_SUITE_P(PerInstance,
+ BluetoothAudioProviderA2dpSoftwareHidlTest,
+ testing::ValuesIn(kAudioInstances),
+ android::hardware::PrintInstanceNameToString);
+
+INSTANTIATE_TEST_SUITE_P(PerInstance,
+ BluetoothAudioProviderA2dpHardwareHidlTest,
+ testing::ValuesIn(kAudioInstances),
+ android::hardware::PrintInstanceNameToString);
+
+INSTANTIATE_TEST_SUITE_P(PerInstance,
+ BluetoothAudioProviderHearingAidSoftwareHidlTest,
+ testing::ValuesIn(kAudioInstances),
+ android::hardware::PrintInstanceNameToString);
\ No newline at end of file
diff --git a/broadcastradio/1.1/default/service.cpp b/broadcastradio/1.1/default/service.cpp
index f8af0b7..29dc76f 100644
--- a/broadcastradio/1.1/default/service.cpp
+++ b/broadcastradio/1.1/default/service.cpp
@@ -20,6 +20,7 @@
#include "BroadcastRadioFactory.h"
+using android::sp;
using android::hardware::configureRpcThreadpool;
using android::hardware::joinRpcThreadpool;
using android::hardware::broadcastradio::V1_1::implementation::BroadcastRadioFactory;
@@ -27,8 +28,8 @@
int main(int /* argc */, char** /* argv */) {
configureRpcThreadpool(4, true);
- BroadcastRadioFactory broadcastRadioFactory;
- auto status = broadcastRadioFactory.registerAsService();
+ sp<BroadcastRadioFactory> broadcastRadioFactory(new BroadcastRadioFactory());
+ auto status = broadcastRadioFactory->registerAsService();
CHECK_EQ(status, android::OK) << "Failed to register Broadcast Radio HAL implementation";
joinRpcThreadpool();
diff --git a/broadcastradio/2.0/default/service.cpp b/broadcastradio/2.0/default/service.cpp
index 349aba2..bd746fd 100644
--- a/broadcastradio/2.0/default/service.cpp
+++ b/broadcastradio/2.0/default/service.cpp
@@ -19,6 +19,7 @@
#include "BroadcastRadio.h"
#include "VirtualRadio.h"
+using android::sp;
using android::hardware::configureRpcThreadpool;
using android::hardware::joinRpcThreadpool;
using android::hardware::broadcastradio::V2_0::implementation::BroadcastRadio;
@@ -30,13 +31,13 @@
android::base::SetMinimumLogSeverity(android::base::VERBOSE);
configureRpcThreadpool(4, true);
- BroadcastRadio broadcastRadio(gAmFmRadio);
- auto amFmStatus = broadcastRadio.registerAsService("amfm");
+ sp<BroadcastRadio> broadcastRadio(new BroadcastRadio(gAmFmRadio));
+ auto amFmStatus = broadcastRadio->registerAsService("amfm");
CHECK_EQ(amFmStatus, android::OK)
<< "Failed to register Broadcast Radio AM/FM HAL implementation";
- BroadcastRadio dabRadio(gDabRadio);
- auto dabStatus = dabRadio.registerAsService("dab");
+ sp<BroadcastRadio> dabRadio(new BroadcastRadio(gDabRadio));
+ auto dabStatus = dabRadio->registerAsService("dab");
CHECK_EQ(dabStatus, android::OK) << "Failed to register Broadcast Radio DAB HAL implementation";
joinRpcThreadpool();
diff --git a/broadcastradio/2.0/vts/OWNERS b/broadcastradio/2.0/vts/OWNERS
index 12adf57..1ff7407 100644
--- a/broadcastradio/2.0/vts/OWNERS
+++ b/broadcastradio/2.0/vts/OWNERS
@@ -3,5 +3,4 @@
twasilczyk@google.com
# VTS team
-yuexima@google.com
-yim@google.com
+dshi@google.com
diff --git a/broadcastradio/2.0/vts/functional/Android.bp b/broadcastradio/2.0/vts/functional/Android.bp
index 3e18a54..49bb665 100644
--- a/broadcastradio/2.0/vts/functional/Android.bp
+++ b/broadcastradio/2.0/vts/functional/Android.bp
@@ -17,9 +17,6 @@
cc_test {
name: "VtsHalBroadcastradioV2_0TargetTest",
defaults: ["VtsHalTargetTestDefaults"],
- cppflags: [
- "-std=c++1z",
- ],
srcs: ["VtsHalBroadcastradioV2_0TargetTest.cpp"],
static_libs: [
"android.hardware.broadcastradio@2.0",
@@ -28,5 +25,8 @@
"android.hardware.broadcastradio@vts-utils-lib",
"libgmock",
],
- test_suites: ["general-tests"],
+ test_suites: [
+ "general-tests",
+ "vts-core",
+ ],
}
diff --git a/broadcastradio/2.0/vts/functional/VtsHalBroadcastradioV2_0TargetTest.cpp b/broadcastradio/2.0/vts/functional/VtsHalBroadcastradioV2_0TargetTest.cpp
index e36f4d9..d170a6d 100644
--- a/broadcastradio/2.0/vts/functional/VtsHalBroadcastradioV2_0TargetTest.cpp
+++ b/broadcastradio/2.0/vts/functional/VtsHalBroadcastradioV2_0TargetTest.cpp
@@ -16,7 +16,6 @@
#define EGMOCK_VERBOSE 1
-#include <VtsHalHidlTargetTestBase.h>
#include <android-base/logging.h>
#include <android-base/strings.h>
#include <android/hardware/broadcastradio/2.0/IBroadcastRadio.h>
@@ -25,11 +24,13 @@
#include <android/hardware/broadcastradio/2.0/types.h>
#include <broadcastradio-utils-2x/Utils.h>
#include <broadcastradio-vts-utils/call-barrier.h>
-#include <broadcastradio-vts-utils/environment-utils.h>
#include <broadcastradio-vts-utils/mock-timeout.h>
#include <broadcastradio-vts-utils/pointer-utils.h>
#include <cutils/bitops.h>
#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include <chrono>
#include <optional>
@@ -52,7 +53,6 @@
using testing::Invoke;
using testing::SaveArg;
-using broadcastradio::vts::BroadcastRadioHidlEnvironment;
using broadcastradio::vts::CallBarrier;
using broadcastradio::vts::clearAndWait;
using utils::make_identifier;
@@ -100,10 +100,8 @@
MOCK_METHOD1(onListUpdated, Return<void>(const hidl_vec<Announcement>&));
};
-static BroadcastRadioHidlEnvironment<IBroadcastRadio>* gEnv = nullptr;
-
-class BroadcastRadioHalTest : public ::testing::VtsHalHidlTargetTestBase {
- protected:
+class BroadcastRadioHalTest : public ::testing::TestWithParam<std::string> {
+ protected:
virtual void SetUp() override;
virtual void TearDown() override;
@@ -185,7 +183,7 @@
EXPECT_EQ(nullptr, mModule.get()) << "Module is already open";
// lookup HIDL service (radio module)
- mModule = getService<IBroadcastRadio>(gEnv->getServiceName<IBroadcastRadio>());
+ mModule = IBroadcastRadio::getService(GetParam());
ASSERT_NE(nullptr, mModule.get()) << "Couldn't find broadcast radio HAL implementation";
// get module properties
@@ -243,10 +241,10 @@
auto startResult = mSession->startProgramListUpdates({});
if (startResult == Result::NOT_SUPPORTED) {
printSkipped("Program list not supported");
- return nullopt;
+ return std::nullopt;
}
EXPECT_EQ(Result::OK, startResult);
- if (startResult != Result::OK) return nullopt;
+ if (startResult != Result::OK) return std::nullopt;
EXPECT_TIMEOUT_CALL_WAIT(*mCallback, onProgramListReady, timeout::programListScan);
@@ -264,7 +262,7 @@
* - the method succeeds when called for the second time without
* closing previous session.
*/
-TEST_F(BroadcastRadioHalTest, OpenSession) {
+TEST_P(BroadcastRadioHalTest, OpenSession) {
// simply open session for the first time
ASSERT_TRUE(openSession());
@@ -308,7 +306,7 @@
* - all channel grids (frequency ranges and spacings) are valid;
* - seek spacing is a multiple of the manual spacing value.
*/
-TEST_F(BroadcastRadioHalTest, GetAmFmRegionConfig) {
+TEST_P(BroadcastRadioHalTest, GetAmFmRegionConfig) {
AmFmRegionConfig config;
bool supported = getAmFmRegionConfig(false, &config);
if (!supported) {
@@ -341,7 +339,7 @@
* - all channel grids (frequency ranges and spacings) are valid;
* - seek spacing is not set.
*/
-TEST_F(BroadcastRadioHalTest, GetAmFmRegionConfigCapabilities) {
+TEST_P(BroadcastRadioHalTest, GetAmFmRegionConfigCapabilities) {
AmFmRegionConfig config;
bool supported = getAmFmRegionConfig(true, &config);
if (!supported) {
@@ -369,7 +367,7 @@
* - all channel labels match correct format;
* - all channel frequencies are in correct range.
*/
-TEST_F(BroadcastRadioHalTest, GetDabRegionConfig) {
+TEST_P(BroadcastRadioHalTest, GetDabRegionConfig) {
Result halResult;
hidl_vec<DabTableEntry> config;
auto cb = [&](Result result, hidl_vec<DabTableEntry> configCb) {
@@ -411,7 +409,7 @@
* invoked carrying a proper selector;
* - program changes exactly to what was requested.
*/
-TEST_F(BroadcastRadioHalTest, FmTune) {
+TEST_P(BroadcastRadioHalTest, FmTune) {
ASSERT_TRUE(openSession());
uint64_t freq = 100100; // 100.1 FM
@@ -458,7 +456,7 @@
* - if the selector is not supported, it's ignored;
* - if it is supported, an invalid value results with INVALID_ARGUMENTS;
*/
-TEST_F(BroadcastRadioHalTest, TuneFailsWithInvalid) {
+TEST_P(BroadcastRadioHalTest, TuneFailsWithInvalid) {
ASSERT_TRUE(openSession());
vector<ProgramIdentifier> invalid = {
@@ -489,7 +487,7 @@
* Verifies that:
* - tune fails with NOT_SUPPORTED when program selector is not initialized.
*/
-TEST_F(BroadcastRadioHalTest, TuneFailsWithEmpty) {
+TEST_P(BroadcastRadioHalTest, TuneFailsWithEmpty) {
ASSERT_TRUE(openSession());
// Program type is 1-based, so 0 will always be invalid.
@@ -506,7 +504,7 @@
* - the program info is changed within timeout::tune;
* - works both directions and with or without skipping sub-channel.
*/
-TEST_F(BroadcastRadioHalTest, Seek) {
+TEST_P(BroadcastRadioHalTest, Seek) {
ASSERT_TRUE(openSession());
// TODO(b/69958777): see FmTune workaround
@@ -531,7 +529,7 @@
* - the program info is changed within timeout::tune if the method succeeded;
* - works both directions.
*/
-TEST_F(BroadcastRadioHalTest, Step) {
+TEST_P(BroadcastRadioHalTest, Step) {
ASSERT_TRUE(openSession());
// TODO(b/69958777): see FmTune workaround
@@ -558,7 +556,7 @@
* Verifies that:
* - the method does not crash after being invoked multiple times.
*/
-TEST_F(BroadcastRadioHalTest, Cancel) {
+TEST_P(BroadcastRadioHalTest, Cancel) {
ASSERT_TRUE(openSession());
for (int i = 0; i < 10; i++) {
@@ -576,7 +574,7 @@
* Verifies that:
* - callback is called for empty parameters set.
*/
-TEST_F(BroadcastRadioHalTest, NoParameters) {
+TEST_P(BroadcastRadioHalTest, NoParameters) {
ASSERT_TRUE(openSession());
hidl_vec<VendorKeyValue> halResults = {};
@@ -605,7 +603,7 @@
* - unknown parameters are ignored;
* - callback is called also for empty results set.
*/
-TEST_F(BroadcastRadioHalTest, UnknownParameters) {
+TEST_P(BroadcastRadioHalTest, UnknownParameters) {
ASSERT_TRUE(openSession());
hidl_vec<VendorKeyValue> halResults = {};
@@ -633,7 +631,7 @@
* Verifies that:
* - the method does not crash after being invoked multiple times.
*/
-TEST_F(BroadcastRadioHalTest, Close) {
+TEST_P(BroadcastRadioHalTest, Close) {
ASSERT_TRUE(openSession());
for (int i = 0; i < 10; i++) {
@@ -648,7 +646,7 @@
* Verifies that:
* - getImage call handles argument 0 gracefully.
*/
-TEST_F(BroadcastRadioHalTest, GetNoImage) {
+TEST_P(BroadcastRadioHalTest, GetNoImage) {
size_t len = 0;
auto result = mModule->getImage(0, [&](hidl_vec<uint8_t> rawImage) { len = rawImage.size(); });
@@ -663,7 +661,7 @@
* - isConfigFlagSet either succeeds or ends with NOT_SUPPORTED or INVALID_STATE;
* - call success or failure is consistent with setConfigFlag.
*/
-TEST_F(BroadcastRadioHalTest, FetchConfigFlags) {
+TEST_P(BroadcastRadioHalTest, FetchConfigFlags) {
ASSERT_TRUE(openSession());
for (auto flag : gConfigFlagValues) {
@@ -691,7 +689,7 @@
* - setConfigFlag either succeeds or ends with NOT_SUPPORTED or INVALID_STATE;
* - isConfigFlagSet reflects the state requested immediately after the set call.
*/
-TEST_F(BroadcastRadioHalTest, SetConfigFlags) {
+TEST_P(BroadcastRadioHalTest, SetConfigFlags) {
ASSERT_TRUE(openSession());
auto get = [&](ConfigFlag flag) {
@@ -743,7 +741,7 @@
* - the complete list is fetched within timeout::programListScan;
* - stopProgramListUpdates does not crash.
*/
-TEST_F(BroadcastRadioHalTest, GetProgramList) {
+TEST_P(BroadcastRadioHalTest, GetProgramList) {
ASSERT_TRUE(openSession());
getProgramList();
@@ -757,7 +755,7 @@
* - the identifier matches the name;
* - there is only one identifier of that type.
*/
-TEST_F(BroadcastRadioHalTest, HdRadioStationNameId) {
+TEST_P(BroadcastRadioHalTest, HdRadioStationNameId) {
ASSERT_TRUE(openSession());
auto list = getProgramList();
@@ -785,7 +783,7 @@
* - if it succeeds, it returns a valid close handle (which is a nullptr otherwise);
* - closing handle does not crash.
*/
-TEST_F(BroadcastRadioHalTest, AnnouncementListenerRegistration) {
+TEST_P(BroadcastRadioHalTest, AnnouncementListenerRegistration) {
sp<AnnouncementListenerMock> listener = new AnnouncementListenerMock();
Result halResult = Result::UNKNOWN_ERROR;
@@ -811,6 +809,11 @@
closeHandle->close();
}
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, BroadcastRadioHalTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(IBroadcastRadio::descriptor)),
+ android::hardware::PrintInstanceNameToString);
+
} // namespace vts
} // namespace V2_0
} // namespace broadcastradio
@@ -818,14 +821,8 @@
} // namespace android
int main(int argc, char** argv) {
- using android::hardware::broadcastradio::V2_0::vts::gEnv;
- using android::hardware::broadcastradio::V2_0::IBroadcastRadio;
- using android::hardware::broadcastradio::vts::BroadcastRadioHidlEnvironment;
android::base::SetDefaultTag("BcRadio.vts");
android::base::SetMinimumLogSeverity(android::base::VERBOSE);
- gEnv = new BroadcastRadioHidlEnvironment<IBroadcastRadio>;
- ::testing::AddGlobalTestEnvironment(gEnv);
::testing::InitGoogleTest(&argc, argv);
- gEnv->init(&argc, argv);
return RUN_ALL_TESTS();
}
diff --git a/broadcastradio/common/vts/utils/include/broadcastradio-vts-utils/pointer-utils.h b/broadcastradio/common/vts/utils/include/broadcastradio-vts-utils/pointer-utils.h
index 0b6f5eb..1d76008 100644
--- a/broadcastradio/common/vts/utils/include/broadcastradio-vts-utils/pointer-utils.h
+++ b/broadcastradio/common/vts/utils/include/broadcastradio-vts-utils/pointer-utils.h
@@ -19,6 +19,8 @@
#include <chrono>
#include <thread>
+using namespace std::chrono_literals;
+
namespace android {
namespace hardware {
namespace broadcastradio {
diff --git a/camera/common/1.0/default/HandleImporter.cpp b/camera/common/1.0/default/HandleImporter.cpp
index 76f9778..ac32c95 100644
--- a/camera/common/1.0/default/HandleImporter.cpp
+++ b/camera/common/1.0/default/HandleImporter.cpp
@@ -252,8 +252,7 @@
// No need to use bytesPerPixel and bytesPerStride because we are using
// an 1-D buffer and accressRegion.
mMapperV4->lock(buffer, cpuUsage, accessRegion, acquireFenceHandle,
- [&](const auto& tmpError, const auto& tmpPtr, const auto& /*bytesPerPixel*/,
- const auto& /*bytesPerStride*/) {
+ [&](const auto& tmpError, const auto& tmpPtr) {
if (tmpError == MapperErrorV4::NONE) {
ret = tmpPtr;
} else {
@@ -301,7 +300,13 @@
}
if (mMapperV4 != nullptr) {
- return lockYCbCrInternal<IMapperV4, MapperErrorV4>(mMapperV4, buf, cpuUsage, accessRegion);
+ // No device currently supports IMapper 4.0 so it is safe to just return an error code here.
+ //
+ // This will be supported by a combination of lock and BufferMetadata getters. We are going
+ // to refactor all the IAllocator/IMapper versioning code into a shared library. We will
+ // then add the IMapper 4.0 lockYCbCr support then.
+ ALOGE("%s: MapperV4 doesn't support lockYCbCr directly!", __FUNCTION__);
+ return {};
}
if (mMapperV3 != nullptr) {
diff --git a/camera/device/3.6/Android.bp b/camera/device/3.6/Android.bp
new file mode 100644
index 0000000..8766b93
--- /dev/null
+++ b/camera/device/3.6/Android.bp
@@ -0,0 +1,24 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+hidl_interface {
+ name: "android.hardware.camera.device@3.6",
+ root: "android.hardware",
+ vndk: {
+ enabled: true,
+ },
+ srcs: [
+ "types.hal",
+ "ICameraDeviceSession.hal",
+ "ICameraOfflineSession.hal",
+ ],
+ interfaces: [
+ "android.hardware.camera.common@1.0",
+ "android.hardware.camera.device@3.2",
+ "android.hardware.camera.device@3.3",
+ "android.hardware.camera.device@3.4",
+ "android.hardware.camera.device@3.5",
+ "android.hardware.graphics.common@1.0",
+ "android.hidl.base@1.0",
+ ],
+ gen_java: false,
+}
diff --git a/camera/device/3.6/ICameraDeviceSession.hal b/camera/device/3.6/ICameraDeviceSession.hal
new file mode 100644
index 0000000..00ebcc3
--- /dev/null
+++ b/camera/device/3.6/ICameraDeviceSession.hal
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2019 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.camera.device@3.6;
+
+import android.hardware.camera.common@1.0::Status;
+import @3.5::ICameraDeviceSession;
+import @3.5::StreamConfiguration;
+import ICameraOfflineSession;
+
+/**
+ * Camera device active session interface.
+ *
+ * Obtained via ICameraDevice::open(), this interface contains the methods to
+ * configure and request captures from an active camera device.
+ */
+interface ICameraDeviceSession extends @3.5::ICameraDeviceSession {
+ /**
+ * configureStreams_3_6:
+ *
+ * Identical to @3.5::ICameraDeviceSession.configureStreams, except that:
+ *
+ * - a boolean supportOffline is added to HalStreamConfiguration to indicate
+ * if this stream can be switched to offline mode later.
+ *
+ * @return status Status code for the operation, one of:
+ * OK:
+ * On successful stream configuration.
+ * INTERNAL_ERROR:
+ * If there has been a fatal error and the device is no longer
+ * operational. Only close() can be called successfully by the
+ * framework after this error is returned.
+ * ILLEGAL_ARGUMENT:
+ * If the requested stream configuration is invalid. Some examples
+ * of invalid stream configurations include:
+ * - Including more than 1 INPUT stream
+ * - Not including any OUTPUT streams
+ * - Including streams with unsupported formats, or an unsupported
+ * size for that format.
+ * - Including too many output streams of a certain format.
+ * - Unsupported rotation configuration
+ * - Stream sizes/formats don't satisfy the
+ * StreamConfigurationMode requirements
+ * for non-NORMAL mode, or the requested operation_mode is not
+ * supported by the HAL.
+ * - Unsupported usage flag
+ * The camera service cannot filter out all possible illegal stream
+ * configurations, since some devices may support more simultaneous
+ * streams or larger stream resolutions than the minimum required
+ * for a given camera device hardware level. The HAL must return an
+ * ILLEGAL_ARGUMENT for any unsupported stream set, and then be
+ * ready to accept a future valid stream configuration in a later
+ * configureStreams call.
+ * @return halConfiguration The stream parameters desired by the HAL for
+ * each stream, including maximum buffers, the usage flags, and the
+ * override format.
+ */
+ configureStreams_3_6(@3.5::StreamConfiguration requestedConfiguration)
+ generates (Status status, HalStreamConfiguration halConfiguration);
+
+ /**
+ * switchToOffline:
+ *
+ * Switch the current running session from actively streaming mode to the
+ * offline mode. See ICameraOfflineSession for more details.
+ *
+ * The streamsToKeep argument contains list of streams IDs where application
+ * still needs its output. For all streams application does not need anymore,
+ * camera HAL can send ERROR_BUFFER to speed up the transition, or even send
+ * ERROR_REQUEST if all output targets of a request is not needed. By the
+ * time this call returns, camera HAL must have returned all buffers coming
+ * from streams no longer needed and have erased buffer caches of such streams.
+ *
+ * For all requests that are going to be transferred to offline session,
+ * the ICameraDeviceSession is responsible to capture all input buffers from
+ * the image sensor before the switchToOffline call returns. Before
+ * switchToOffline returns, camera HAL must have completed all requests not
+ * switching to offline mode, and collected information on what streams and
+ * requests are going to continue in the offline session, in the
+ * offlineSessionInfo output argument.
+ *
+ * If there are no requests qualified to be transferred to offline session,
+ * the camera HAL must return a null ICameraOfflineSession object with OK
+ * status. In this scenario, the camera HAL still must flush all inflight
+ * requests and unconfigure all streams before returning this call.
+ *
+ * After switchToOffline returns, the ICameraDeviceSession must be back to
+ * unconfigured state as if it is just created and no streams are configured.
+ * Also, camera HAL must not call any methods in ICameraDeviceCallback since
+ * all unfinished requests are now transferred to the offline session.
+ * After the call returns, camera service may then call close to close
+ * the camera device, or call configureStream* again to reconfigure the
+ * camera and then send new capture requests with processCaptureRequest. In
+ * the latter case, it is legitimate for camera HAL to call methods in
+ * ICameraDeviceCallback again in response to the newly submitted capture
+ * requests.
+ *
+ * @return status Status code for the operation, one of:
+ * OK:
+ * On switching to offline session and unconfiguring streams
+ * successfully.
+ * ILLEGAL_ARGUMENT:
+ * If camera does not support offline mode in any one of streams
+ * in streamsToKeep argument. Note that the camera HAL must report
+ * if a stream supports offline mode in HalStreamConfiguration
+ * output of configureStreams_3_6 method. If all streams in
+ * streamsToKeep argument support offline mode, then the camera HAL
+ * must not return this error.
+ *
+ *
+ * @return offlineSessionInfo Information on what streams and requests will
+ * be transferred to offline session to continue processing.
+ *
+ * @return offlineSession The offline session object camera service will use
+ * to interact with.
+ */
+ switchToOffline(vec<int32_t> streamsToKeep) generates (Status status,
+ CameraOfflineSessionInfo offlineSessionInfo, ICameraOfflineSession offlineSession);
+};
diff --git a/camera/device/3.6/ICameraOfflineSession.hal b/camera/device/3.6/ICameraOfflineSession.hal
new file mode 100644
index 0000000..03cea64
--- /dev/null
+++ b/camera/device/3.6/ICameraOfflineSession.hal
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2019 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.camera.device@3.6;
+
+import @3.5::ICameraDeviceCallback;
+
+/**
+ * Camera device offline session interface.
+ *
+ * Obtained via ICameraDeviceSession::switchToOffline(), this interface contains
+ * the methods and callback interfaces that define how camera service interacts
+ * with an offline session.
+ *
+ * An offline session contains some unfinished capture requests that were submitted
+ * to the parent ICameraDeviceSession before calling switchToOffline, and is
+ * responsible for delivering these capture results back to camera service regardless
+ * of whether the parent camera device is still opened or not. An offline session must
+ * not have access to the camera device's image sensor. During switchToOffline
+ * call, camera HAL must capture all necessary frames from the image sensor that
+ * is needed for completing the requests offline later.
+ */
+interface ICameraOfflineSession {
+ /**
+ * Set the callbacks for offline session to communicate with camera service.
+ *
+ * Offline session is responsible to store all callbacks the camera HAL
+ * generated after the return of ICameraDeviceSession::switchToOffline, and
+ * send them to camera service once this method is called.
+ *
+ * Camera service must not call this method more than once, so these
+ * callbacks can be assumed to be constant after the first setCallback call.
+ */
+ setCallback(ICameraDeviceCallback cb);
+
+ /**
+ * getCaptureResultMetadataQueue:
+ *
+ * Retrieves the queue used along with
+ * ICameraDeviceCallback#processCaptureResult.
+ *
+ * Clients to ICameraOfflineSession must:
+ * - Call getCaptureRequestMetadataQueue to retrieve the fast message queue;
+ * - In implementation of ICameraDeviceCallback, test whether
+ * .fmqResultSize field is zero.
+ * - If .fmqResultSize != 0, read result metadata from the fast message
+ * queue;
+ * - otherwise, read result metadata in CaptureResult.result.
+ *
+ * @return queue the queue that implementation writes result metadata to.
+ */
+ getCaptureResultMetadataQueue() generates (fmq_sync<uint8_t> queue);
+
+ /**
+ * Close the offline session and release all resources.
+ *
+ * Camera service may call this method before or after the offline session
+ * has finished all requests it needs to handle. If there are still unfinished
+ * requests when close is called, camera HAL must send ERROR_REQUEST for
+ * all unfinished requests and return all buffers via
+ * ICameraDeviceCallback#processCaptureResult or
+ * ICameraDeviceCallback#returnStreamBuffers.
+ * Also, all buffer caches maintained by the offline session must be erased
+ * before the close call returns.
+ */
+ close();
+};
diff --git a/camera/device/3.6/types.hal b/camera/device/3.6/types.hal
new file mode 100644
index 0000000..743b139
--- /dev/null
+++ b/camera/device/3.6/types.hal
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2019 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.camera.device@3.6;
+
+import @3.2::BufferCache;
+import @3.4::HalStream;
+
+/**
+ * OfflineRequest:
+ *
+ * Information about a capture request being switched to offline mode via the
+ * ICameraDeviceSession#switchToOffline method.
+ *
+ */
+struct OfflineRequest {
+ /**
+ * Must match a inflight CaptureRequest sent by camera service
+ */
+ uint32_t frameNumber;
+
+ /**
+ * Stream IDs for outputs that will be returned via ICameraDeviceCallback.
+ * The stream ID must be within one of offline stream listed in
+ * CameraOfflineSessionInfo.
+ * Camera service will validate these pending buffers are matching camera
+ * service's record to make sure no buffers are leaked during the
+ * switchToOffline call.
+ */
+ vec<int32_t> pendingStreams;
+};
+
+/**
+ * OfflineStream:
+ *
+ * Information about a stream being switched to offline mode via the
+ * ICameraDeviceSession#switchToOffline method.
+ *
+ */
+struct OfflineStream {
+ /**
+ * IDs of a stream to be transferred to offline session.
+ *
+ * For devices that do not support HAL buffer management, this must be
+ * one of stream ID listed in streamsToKeep argument of the
+ * switchToOffline call.
+ * For devices that support HAL buffer management, this could be any stream
+ * that was configured right before calling switchToOffline.
+ */
+ int32_t id;
+
+ /**
+ * Number of outstanding buffers that will be returned via offline session
+ */
+ uint32_t numOutstandingBuffers;
+
+ /**
+ * Buffer ID of buffers currently cached between camera service and this
+ * stream, which may or may not be owned by the camera HAL right now.
+ * See StreamBuffer#bufferId for more details.
+ */
+ vec<uint64_t> circulatingBufferIds;
+};
+
+/**
+ * CameraOfflineSessionInfo:
+ *
+ * Information about pending outputs that's being transferred to an offline
+ * session from an active session using the
+ * ICameraDeviceSession#switchToOffline method.
+ *
+ */
+struct CameraOfflineSessionInfo {
+ /**
+ * Information on what streams will be preserved in offline session.
+ * Streams not listed here will be removed by camera service after
+ * switchToOffline call returns.
+ */
+ vec<OfflineStream> offlineStreams;
+
+ /**
+ * Information for requests that will be handled by offline session
+ * Camera service will validate this matches what camera service has on
+ * record.
+ */
+ vec<OfflineRequest> offlineRequests;
+};
+
+/**
+ * HalStream:
+ *
+ * The camera HAL's response to each requested stream configuration.
+ *
+ * This version extends the @3.4 HalStream with the physicalCameraId
+ * field
+ */
+struct HalStream {
+ /**
+ * The definition of HalStream from the prior version.
+ */
+ @3.4::HalStream v3_4;
+
+ /**
+ * Whether this stream can be switch to offline mode.
+ *
+ * For devices that does not support the OFFLINE_PROCESSING capability, this
+ * fields will always be false.
+ *
+ * For devices support the OFFLINE_PROCESSING capability: any input stream
+ * and any output stream that can be output of the input stream must set
+ * this field to true. Also any stream of YUV420_888 format or JPEG format,
+ * with CPU_READ usage flag, must set this field to true. All other streams
+ * are up to camera HAL to advertise support or not, though it is not
+ * recommended to list support for streams with hardware composer or video
+ * encoder usage flags as these streams tend to be targeted continuously and
+ * can lead to long latency when trying to switch to offline.
+ *
+ */
+ bool supportOffline;
+};
+
+/**
+ * HalStreamConfiguration:
+ *
+ * Identical to @3.4::HalStreamConfiguration, except that it contains @3.6::HalStream entries.
+ *
+ */
+struct HalStreamConfiguration {
+ vec<HalStream> streams;
+};
diff --git a/camera/metadata/3.2/types.hal b/camera/metadata/3.2/types.hal
index cef0397..f5034cc 100644
--- a/camera/metadata/3.2/types.hal
+++ b/camera/metadata/3.2/types.hal
@@ -410,7 +410,7 @@
*
* <p>List of the maximum number of regions that can be used for metering in
* auto-exposure (AE), auto-white balance (AWB), and auto-focus (AF);
- * this corresponds to the the maximum number of elements in
+ * this corresponds to the maximum number of elements in
* ANDROID_CONTROL_AE_REGIONS, ANDROID_CONTROL_AWB_REGIONS,
* and ANDROID_CONTROL_AF_REGIONS.</p>
*
diff --git a/camera/metadata/3.5/Android.bp b/camera/metadata/3.5/Android.bp
index 4ebd069..224c369 100644
--- a/camera/metadata/3.5/Android.bp
+++ b/camera/metadata/3.5/Android.bp
@@ -16,4 +16,3 @@
],
gen_java: true,
}
-
diff --git a/camera/metadata/3.5/types.hal b/camera/metadata/3.5/types.hal
index b9451c8..62899ec 100644
--- a/camera/metadata/3.5/types.hal
+++ b/camera/metadata/3.5/types.hal
@@ -35,12 +35,22 @@
* '/system/media/camera/docs/docs.html' in the corresponding Android source tree.</p>
*/
enum CameraMetadataTag : @3.4::CameraMetadataTag {
- /** android.control.availableBokehCapabilities [static, int32[], public]
+ /** android.control.availableBokehMaxSizes [static, int32[], ndk_public]
*
- * <p>The list of bokeh modes that are supported by this camera device, and each bokeh mode's
- * maximum streaming (non-stall) size with bokeh effect.</p>
+ * <p>The list of bokeh modes for ANDROID_CONTROL_BOKEH_MODE that are supported by this camera
+ * device, and each bokeh mode's maximum streaming (non-stall) size with bokeh effect.</p>
+ *
+ * @see ANDROID_CONTROL_BOKEH_MODE
*/
- ANDROID_CONTROL_AVAILABLE_BOKEH_CAPABILITIES = android.hardware.camera.metadata@3.3::CameraMetadataTag:ANDROID_CONTROL_END_3_3,
+ ANDROID_CONTROL_AVAILABLE_BOKEH_MAX_SIZES = android.hardware.camera.metadata@3.3::CameraMetadataTag:ANDROID_CONTROL_END_3_3,
+
+ /** android.control.availableBokehZoomRatioRanges [static, float[], ndk_public]
+ *
+ * <p>The ranges of supported zoom ratio for non-OFF ANDROID_CONTROL_BOKEH_MODE.</p>
+ *
+ * @see ANDROID_CONTROL_BOKEH_MODE
+ */
+ ANDROID_CONTROL_AVAILABLE_BOKEH_ZOOM_RATIO_RANGES,
/** android.control.bokehMode [dynamic, enum, public]
*
@@ -48,6 +58,18 @@
*/
ANDROID_CONTROL_BOKEH_MODE,
+ /** android.control.zoomRatioRange [static, float[], public]
+ *
+ * <p>Minimum and maximum zoom ratios supported by this camera device.</p>
+ */
+ ANDROID_CONTROL_ZOOM_RATIO_RANGE,
+
+ /** android.control.zoomRatio [dynamic, float, public]
+ *
+ * <p>The desired zoom ratio</p>
+ */
+ ANDROID_CONTROL_ZOOM_RATIO,
+
ANDROID_CONTROL_END_3_5,
};
@@ -71,4 +93,5 @@
enum CameraMetadataEnumAndroidRequestAvailableCapabilities :
@3.4::CameraMetadataEnumAndroidRequestAvailableCapabilities {
ANDROID_REQUEST_AVAILABLE_CAPABILITIES_SYSTEM_CAMERA,
+ ANDROID_REQUEST_AVAILABLE_CAPABILITIES_OFFLINE_PROCESSING,
};
diff --git a/camera/provider/2.4/vts/functional/Android.bp b/camera/provider/2.4/vts/functional/Android.bp
index 5fe7b19..d14ccfa 100644
--- a/camera/provider/2.4/vts/functional/Android.bp
+++ b/camera/provider/2.4/vts/functional/Android.bp
@@ -41,16 +41,11 @@
"android.hardware.camera.metadata@3.4",
"android.hardware.camera.provider@2.4",
"android.hardware.camera.provider@2.5",
- "android.hardware.graphics.allocator@2.0",
- "android.hardware.graphics.allocator@3.0",
- "android.hardware.graphics.allocator@4.0",
"android.hardware.graphics.common@1.0",
- "android.hardware.graphics.mapper@2.0",
- "android.hardware.graphics.mapper@3.0",
- "android.hardware.graphics.mapper@4.0",
"android.hidl.allocator@1.0",
"libgrallocusage",
"libhidlmemory",
+ "libgralloctypes",
],
- test_suites: ["general-tests"],
+ test_suites: ["general-tests", "vts-core"],
}
diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
index 6505440..650ec8b 100644
--- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
+++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
@@ -20,53 +20,50 @@
#include <chrono>
#include <mutex>
#include <regex>
+#include <string>
#include <unordered_map>
#include <unordered_set>
#include <condition_variable>
#include <inttypes.h>
-#include <android/hardware/camera/device/1.0/ICameraDevice.h>
-#include <android/hardware/camera/device/3.2/ICameraDevice.h>
-#include <android/hardware/camera/device/3.5/ICameraDevice.h>
-#include <android/hardware/camera/device/3.3/ICameraDeviceSession.h>
-#include <android/hardware/camera/device/3.4/ICameraDeviceSession.h>
-#include <android/hardware/camera/device/3.5/ICameraDeviceSession.h>
-#include <android/hardware/camera/device/3.4/ICameraDeviceCallback.h>
-#include <android/hardware/camera/device/3.5/ICameraDeviceCallback.h>
-#include <android/hardware/camera/provider/2.4/ICameraProvider.h>
-#include <android/hardware/camera/provider/2.5/ICameraProvider.h>
-#include <android/hardware/camera/metadata/3.4/types.h>
-#include <android/hidl/manager/1.0/IServiceManager.h>
-#include <binder/MemoryHeapBase.h>
#include <CameraMetadata.h>
#include <CameraParameters.h>
+#include <android/hardware/camera/device/1.0/ICameraDevice.h>
+#include <android/hardware/camera/device/3.2/ICameraDevice.h>
+#include <android/hardware/camera/device/3.3/ICameraDeviceSession.h>
+#include <android/hardware/camera/device/3.4/ICameraDeviceCallback.h>
+#include <android/hardware/camera/device/3.4/ICameraDeviceSession.h>
+#include <android/hardware/camera/device/3.5/ICameraDevice.h>
+#include <android/hardware/camera/device/3.5/ICameraDeviceCallback.h>
+#include <android/hardware/camera/device/3.5/ICameraDeviceSession.h>
+#include <android/hardware/camera/metadata/3.4/types.h>
+#include <android/hardware/camera/provider/2.4/ICameraProvider.h>
+#include <android/hardware/camera/provider/2.5/ICameraProvider.h>
+#include <android/hidl/manager/1.0/IServiceManager.h>
+#include <binder/MemoryHeapBase.h>
#include <cutils/properties.h>
#include <fmq/MessageQueue.h>
#include <grallocusage/GrallocUsageConversion.h>
#include <gui/BufferItemConsumer.h>
#include <gui/BufferQueue.h>
#include <gui/Surface.h>
+#include <gtest/gtest.h>
#include <hardware/gralloc.h>
#include <hardware/gralloc1.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
+#include <log/log.h>
#include <system/camera.h>
#include <system/camera_metadata.h>
#include <ui/GraphicBuffer.h>
+#include <ui/GraphicBufferAllocator.h>
+#include <ui/GraphicBufferMapper.h>
-#include <android/hardware/graphics/allocator/2.0/IAllocator.h>
-#include <android/hardware/graphics/allocator/3.0/IAllocator.h>
-#include <android/hardware/graphics/allocator/4.0/IAllocator.h>
-#include <android/hardware/graphics/mapper/2.0/IMapper.h>
-#include <android/hardware/graphics/mapper/2.0/types.h>
-#include <android/hardware/graphics/mapper/3.0/IMapper.h>
-#include <android/hardware/graphics/mapper/4.0/IMapper.h>
#include <android/hidl/allocator/1.0/IAllocator.h>
#include <android/hidl/memory/1.0/IMapper.h>
#include <android/hidl/memory/1.0/IMemory.h>
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
-
using namespace ::android::hardware::camera::device;
using ::android::hardware::Return;
using ::android::hardware::Void;
@@ -288,27 +285,6 @@
}
}
-// Test environment for camera
-class CameraHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static CameraHidlEnvironment* Instance() {
- static CameraHidlEnvironment* instance = new CameraHidlEnvironment;
- return instance;
- }
-
- virtual void HidlSetUp() override { ALOGI("SetUp CameraHidlEnvironment"); }
-
- virtual void HidlTearDown() override { ALOGI("TearDown CameraHidlEnvironment"); }
-
- virtual void registerTestServices() override { registerTestService<ICameraProvider>(); }
-
- private:
- CameraHidlEnvironment() {}
-
- GTEST_DISALLOW_COPY_AND_ASSIGN_(CameraHidlEnvironment);
-};
-
struct BufferItemHander: public BufferItemConsumer::FrameAvailableListener {
BufferItemHander(wp<BufferItemConsumer> consumer) : mConsumer(consumer) {}
@@ -549,12 +525,13 @@
}
// The main test class for camera HIDL HAL.
-class CameraHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+class CameraHidlTest : public ::testing::TestWithParam<std::string> {
public:
virtual void SetUp() override {
- string service_name = CameraHidlEnvironment::Instance()->getServiceName<ICameraProvider>();
+ std::string service_name = GetParam();
ALOGI("get service with name: %s", service_name.c_str());
- mProvider = ::testing::VtsHalHidlTargetTestBase::getService<ICameraProvider>(service_name);
+ mProvider = ICameraProvider::getService(service_name);
+
ASSERT_NE(mProvider, nullptr);
uint32_t id;
@@ -779,6 +756,7 @@
const hidl_vec<hidl_string>& deviceNames);
void verifyCameraCharacteristics(Status status, const CameraMetadata& chars);
void verifyBokehCharacteristics(const camera_metadata_t* metadata);
+ void verifyZoomCharacteristics(const camera_metadata_t* metadata);
void verifyRecommendedConfigs(const CameraMetadata& metadata);
void verifyMonochromeCharacteristics(const CameraMetadata& chars, int deviceVersion);
void verifyMonochromeCameraResult(
@@ -800,6 +778,8 @@
void verifySessionReconfigurationQuery(sp<device::V3_5::ICameraDeviceSession> session3_5,
camera_metadata* oldSessionParams, camera_metadata* newSessionParams);
+ void verifyRequestTemplate(const camera_metadata_t* metadata, RequestTemplate requestTemplate);
+
bool isDepthOnly(camera_metadata_t* staticMeta);
static Status getAvailableOutputStreams(const camera_metadata_t *staticMeta,
@@ -883,7 +863,7 @@
// return from HAL but framework.
::android::Vector<StreamBuffer> resultOutputBuffers;
- std::unordered_set<string> expectedPhysicalResults;
+ std::unordered_set<std::string> expectedPhysicalResults;
InFlightRequest() :
shutterTimestamp(0),
@@ -917,7 +897,7 @@
InFlightRequest(ssize_t numBuffers, bool hasInput,
bool partialResults, uint32_t partialCount,
- const std::unordered_set<string>& extraPhysicalResult,
+ const std::unordered_set<std::string>& extraPhysicalResult,
std::shared_ptr<ResultMetadataQueue> queue = nullptr) :
shutterTimestamp(0),
errorCodeValid(false),
@@ -1578,7 +1558,7 @@
}
// Test devices with first_api_level >= P does not advertise device@1.0
-TEST_F(CameraHidlTest, noHal1AfterP) {
+TEST_P(CameraHidlTest, noHal1AfterP) {
constexpr int32_t HAL1_PHASE_OUT_API_LEVEL = 28;
int32_t firstApiLevel = 0;
getFirstApiLevel(&firstApiLevel);
@@ -1603,7 +1583,7 @@
// Test if ICameraProvider::isTorchModeSupported returns Status::OK
// Also if first_api_level >= Q torch API must be supported.
-TEST_F(CameraHidlTest, isTorchModeSupported) {
+TEST_P(CameraHidlTest, isTorchModeSupported) {
constexpr int32_t API_LEVEL_Q = 29;
int32_t firstApiLevel = 0;
getFirstApiLevel(&firstApiLevel);
@@ -1620,7 +1600,7 @@
}
// TODO: consider removing this test if getCameraDeviceNames() has the same coverage
-TEST_F(CameraHidlTest, getCameraIdList) {
+TEST_P(CameraHidlTest, getCameraIdList) {
Return<void> ret;
ret = mProvider->getCameraIdList([&](auto status, const auto& idList) {
ALOGI("getCameraIdList returns status:%d", (int)status);
@@ -1633,7 +1613,7 @@
}
// Test if ICameraProvider::getVendorTags returns Status::OK
-TEST_F(CameraHidlTest, getVendorTags) {
+TEST_P(CameraHidlTest, getVendorTags) {
Return<void> ret;
ret = mProvider->getVendorTags([&](auto status, const auto& vendorTagSecs) {
ALOGI("getVendorTags returns status:%d numSections %zu", (int)status, vendorTagSecs.size());
@@ -1651,7 +1631,7 @@
}
// Test if ICameraProvider::setCallback returns Status::OK
-TEST_F(CameraHidlTest, setCallback) {
+TEST_P(CameraHidlTest, setCallback) {
struct ProviderCb : public ICameraProviderCallback {
virtual Return<void> cameraDeviceStatusChange(
const hidl_string& cameraDeviceName,
@@ -1679,7 +1659,7 @@
}
// Test if ICameraProvider::getCameraDeviceInterface returns Status::OK and non-null device
-TEST_F(CameraHidlTest, getCameraDeviceInterface) {
+TEST_P(CameraHidlTest, getCameraDeviceInterface) {
hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
for (const auto& name : cameraDeviceNames) {
@@ -1721,7 +1701,7 @@
// Verify that the device resource cost can be retrieved and the values are
// sane.
-TEST_F(CameraHidlTest, getResourceCost) {
+TEST_P(CameraHidlTest, getResourceCost) {
hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
for (const auto& name : cameraDeviceNames) {
@@ -1791,7 +1771,7 @@
// Verify that the static camera info can be retrieved
// successfully.
-TEST_F(CameraHidlTest, getCameraInfo) {
+TEST_P(CameraHidlTest, getCameraInfo) {
hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
for (const auto& name : cameraDeviceNames) {
@@ -1839,7 +1819,7 @@
}
// Check whether preview window can be configured
-TEST_F(CameraHidlTest, setPreviewWindow) {
+TEST_P(CameraHidlTest, setPreviewWindow) {
hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
for (const auto& name : cameraDeviceNames) {
@@ -1859,7 +1839,7 @@
}
// Verify that setting preview window fails in case device is not open
-TEST_F(CameraHidlTest, setPreviewWindowInvalid) {
+TEST_P(CameraHidlTest, setPreviewWindowInvalid) {
hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
for (const auto& name : cameraDeviceNames) {
@@ -1884,7 +1864,7 @@
}
// Start and stop preview checking whether it gets enabled in between.
-TEST_F(CameraHidlTest, startStopPreview) {
+TEST_P(CameraHidlTest, startStopPreview) {
hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
for (const auto& name : cameraDeviceNames) {
@@ -1909,7 +1889,7 @@
// Start preview without active preview window. Preview should start as soon
// as a valid active window gets configured.
-TEST_F(CameraHidlTest, startStopPreviewDelayed) {
+TEST_P(CameraHidlTest, startStopPreviewDelayed) {
hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
for (const auto& name : cameraDeviceNames) {
@@ -1939,7 +1919,7 @@
}
// Verify that image capture behaves as expected along with preview callbacks.
-TEST_F(CameraHidlTest, takePicture) {
+TEST_P(CameraHidlTest, takePicture) {
hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
for (const auto& name : cameraDeviceNames) {
@@ -1988,7 +1968,7 @@
}
// Image capture should fail in case preview didn't get enabled first.
-TEST_F(CameraHidlTest, takePictureFail) {
+TEST_P(CameraHidlTest, takePictureFail) {
hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
for (const auto& name : cameraDeviceNames) {
@@ -2008,7 +1988,7 @@
}
// Verify that image capture can be cancelled.
-TEST_F(CameraHidlTest, cancelPicture) {
+TEST_P(CameraHidlTest, cancelPicture) {
hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
for (const auto& name : cameraDeviceNames) {
@@ -2035,7 +2015,7 @@
}
// Image capture cancel is a no-op when image capture is not running.
-TEST_F(CameraHidlTest, cancelPictureNOP) {
+TEST_P(CameraHidlTest, cancelPictureNOP) {
hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
for (const auto& name : cameraDeviceNames) {
@@ -2058,7 +2038,7 @@
}
// Test basic video recording.
-TEST_F(CameraHidlTest, startStopRecording) {
+TEST_P(CameraHidlTest, startStopRecording) {
hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
for (const auto& name : cameraDeviceNames) {
@@ -2136,7 +2116,7 @@
}
// It shouldn't be possible to start recording without enabling preview first.
-TEST_F(CameraHidlTest, startRecordingFail) {
+TEST_P(CameraHidlTest, startRecordingFail) {
hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
for (const auto& name : cameraDeviceNames) {
@@ -2160,7 +2140,7 @@
}
// Check autofocus support if available.
-TEST_F(CameraHidlTest, autoFocus) {
+TEST_P(CameraHidlTest, autoFocus) {
hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
std::vector<const char*> focusModes = {CameraParameters::FOCUS_MODE_AUTO,
CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE,
@@ -2221,7 +2201,7 @@
}
// In case autofocus is supported verify that it can be cancelled.
-TEST_F(CameraHidlTest, cancelAutoFocus) {
+TEST_P(CameraHidlTest, cancelAutoFocus) {
hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
for (const auto& name : cameraDeviceNames) {
@@ -2267,7 +2247,7 @@
}
// Check whether face detection is available and try to enable&disable.
-TEST_F(CameraHidlTest, sendCommandFaceDetection) {
+TEST_P(CameraHidlTest, sendCommandFaceDetection) {
hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
for (const auto& name : cameraDeviceNames) {
@@ -2322,7 +2302,7 @@
}
// Check whether smooth zoom is available and try to enable&disable.
-TEST_F(CameraHidlTest, sendCommandSmoothZoom) {
+TEST_P(CameraHidlTest, sendCommandSmoothZoom) {
hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
for (const auto& name : cameraDeviceNames) {
@@ -2370,7 +2350,7 @@
}
// Basic sanity tests related to camera parameters.
-TEST_F(CameraHidlTest, getSetParameters) {
+TEST_P(CameraHidlTest, getSetParameters) {
hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
for (const auto& name : cameraDeviceNames) {
@@ -2462,7 +2442,7 @@
// Verify that the static camera characteristics can be retrieved
// successfully.
-TEST_F(CameraHidlTest, getCameraCharacteristics) {
+TEST_P(CameraHidlTest, getCameraCharacteristics) {
hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
for (const auto& name : cameraDeviceNames) {
@@ -2528,7 +2508,7 @@
//In case it is supported verify that torch can be enabled.
//Check for corresponding toch callbacks as well.
-TEST_F(CameraHidlTest, setTorchMode) {
+TEST_P(CameraHidlTest, setTorchMode) {
hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
bool torchControlSupported = false;
Return<void> ret;
@@ -2666,7 +2646,7 @@
}
// Check dump functionality.
-TEST_F(CameraHidlTest, dumpState) {
+TEST_P(CameraHidlTest, dumpState) {
hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
Return<void> ret;
@@ -2731,7 +2711,7 @@
}
// Open, dumpStates, then close
-TEST_F(CameraHidlTest, openClose) {
+TEST_P(CameraHidlTest, openClose) {
hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
Return<void> ret;
@@ -2824,7 +2804,7 @@
// Check whether all common default request settings can be sucessfully
// constructed.
-TEST_F(CameraHidlTest, constructDefaultRequestSettings) {
+TEST_P(CameraHidlTest, constructDefaultRequestSettings) {
hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
for (const auto& name : cameraDeviceNames) {
@@ -2881,13 +2861,7 @@
metadata, &expectedSize);
ASSERT_TRUE((result == 0) ||
(result == CAMERA_METADATA_VALIDATION_SHIFTED));
- size_t entryCount =
- get_camera_metadata_entry_count(metadata);
- // TODO: we can do better than 0 here. Need to check how many required
- // request keys we've defined for each template
- ASSERT_GT(entryCount, 0u);
- ALOGI("template %u metadata entry count is %zu",
- t, entryCount);
+ verifyRequestTemplate(metadata, reqTemplate);
} else {
ASSERT_EQ(0u, req.size());
}
@@ -2914,7 +2888,7 @@
// Verify that all supported stream formats and sizes can be configured
// successfully.
-TEST_F(CameraHidlTest, configureStreamsAvailableOutputs) {
+TEST_P(CameraHidlTest, configureStreamsAvailableOutputs) {
hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
std::vector<AvailableStream> outputStreams;
@@ -3022,7 +2996,7 @@
}
// Check for correct handling of invalid/incorrect configuration parameters.
-TEST_F(CameraHidlTest, configureStreamsInvalidOutputs) {
+TEST_P(CameraHidlTest, configureStreamsInvalidOutputs) {
hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
std::vector<AvailableStream> outputStreams;
@@ -3218,7 +3192,7 @@
// Check whether all supported ZSL output stream combinations can be
// configured successfully.
-TEST_F(CameraHidlTest, configureStreamsZSLInputOutputs) {
+TEST_P(CameraHidlTest, configureStreamsZSLInputOutputs) {
hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
std::vector<AvailableStream> inputStreams;
std::vector<AvailableZSLInputOutput> inputOutputMap;
@@ -3384,7 +3358,7 @@
// Check whether session parameters are supported. If Hal support for them
// exist, then try to configure a preview stream using them.
-TEST_F(CameraHidlTest, configureStreamsWithSessionParameters) {
+TEST_P(CameraHidlTest, configureStreamsWithSessionParameters) {
hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
std::vector<AvailableStream> outputPreviewStreams;
AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
@@ -3503,7 +3477,7 @@
// Verify that all supported preview + still capture stream combinations
// can be configured successfully.
-TEST_F(CameraHidlTest, configureStreamsPreviewStillOutputs) {
+TEST_P(CameraHidlTest, configureStreamsPreviewStillOutputs) {
hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
std::vector<AvailableStream> outputBlobStreams;
std::vector<AvailableStream> outputPreviewStreams;
@@ -3626,7 +3600,7 @@
// In case constrained mode is supported, test whether it can be
// configured. Additionally check for common invalid inputs when
// using this mode.
-TEST_F(CameraHidlTest, configureStreamsConstrainedOutputs) {
+TEST_P(CameraHidlTest, configureStreamsConstrainedOutputs) {
hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
for (const auto& name : cameraDeviceNames) {
@@ -3831,7 +3805,7 @@
// Verify that all supported video + snapshot stream combinations can
// be configured successfully.
-TEST_F(CameraHidlTest, configureStreamsVideoStillOutputs) {
+TEST_P(CameraHidlTest, configureStreamsVideoStillOutputs) {
hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
std::vector<AvailableStream> outputBlobStreams;
std::vector<AvailableStream> outputVideoStreams;
@@ -3952,7 +3926,7 @@
}
// Generate and verify a camera capture request
-TEST_F(CameraHidlTest, processCaptureRequestPreview) {
+TEST_P(CameraHidlTest, processCaptureRequestPreview) {
hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
@@ -4120,7 +4094,7 @@
}
// Generate and verify a multi-camera capture request
-TEST_F(CameraHidlTest, processMultiCaptureRequestPreview) {
+TEST_P(CameraHidlTest, processMultiCaptureRequestPreview) {
hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
static_cast<int32_t>(PixelFormat::YCBCR_420_888)};
@@ -4189,7 +4163,7 @@
// Leave only 2 physical devices in the id set.
auto it = physicalIds.begin();
- string physicalDeviceId = *it; it++;
+ std::string physicalDeviceId = *it; it++;
physicalIds.erase(++it, physicalIds.end());
ASSERT_EQ(physicalIds.size(), 2u);
@@ -4367,7 +4341,7 @@
}
// Generate and verify a burst containing alternating sensor sensitivity values
-TEST_F(CameraHidlTest, processCaptureRequestBurstISO) {
+TEST_P(CameraHidlTest, processCaptureRequestBurstISO) {
hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
@@ -4525,7 +4499,7 @@
// Test whether an incorrect capture request with missing settings will
// be reported correctly.
-TEST_F(CameraHidlTest, processCaptureRequestInvalidSinglePreview) {
+TEST_P(CameraHidlTest, processCaptureRequestInvalidSinglePreview) {
hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
std::vector<AvailableStream> outputPreviewStreams;
AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
@@ -4600,7 +4574,7 @@
// Check whether an invalid capture request with missing output buffers
// will be reported correctly.
-TEST_F(CameraHidlTest, processCaptureRequestInvalidBuffer) {
+TEST_P(CameraHidlTest, processCaptureRequestInvalidBuffer) {
hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
std::vector<AvailableStream> outputBlobStreams;
AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
@@ -4665,7 +4639,7 @@
}
// Generate, trigger and flush a preview request
-TEST_F(CameraHidlTest, flushPreviewRequest) {
+TEST_P(CameraHidlTest, flushPreviewRequest) {
hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
std::vector<AvailableStream> outputPreviewStreams;
AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
@@ -4808,7 +4782,7 @@
}
// Verify that camera flushes correctly without any pending requests.
-TEST_F(CameraHidlTest, flushEmpty) {
+TEST_P(CameraHidlTest, flushEmpty) {
hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
std::vector<AvailableStream> outputPreviewStreams;
AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
@@ -4853,7 +4827,7 @@
}
// Test camera provider@2.5 notify method
-TEST_F(CameraHidlTest, providerDeviceStateNotification) {
+TEST_P(CameraHidlTest, providerDeviceStateNotification) {
notifyDeviceState(provider::V2_5::DeviceState::BACK_COVERED);
notifyDeviceState(provider::V2_5::DeviceState::NORMAL);
@@ -5695,6 +5669,11 @@
return;
}
+ camera_metadata_ro_entry entry;
+ int retcode = find_camera_metadata_ro_entry(metadata,
+ ANDROID_CONTROL_ZOOM_RATIO_RANGE, &entry);
+ bool hasZoomRatioRange = (0 == retcode && entry.count == 2);
+
std::string version, cameraId;
ASSERT_TRUE(::matchDeviceName(cameraName, mProviderType, &version, &cameraId));
std::unordered_set<std::string> physicalIds;
@@ -5702,15 +5681,37 @@
for (auto physicalId : physicalIds) {
ASSERT_NE(physicalId, cameraId);
bool isPublicId = false;
+ std::string fullPublicId;
for (auto& deviceName : deviceNames) {
std::string publicVersion, publicId;
ASSERT_TRUE(::matchDeviceName(deviceName, mProviderType, &publicVersion, &publicId));
if (physicalId == publicId) {
isPublicId = true;
+ fullPublicId = deviceName;
break;
}
}
if (isPublicId) {
+ ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> subDevice;
+ Return<void> ret;
+ ret = mProvider->getCameraDeviceInterface_V3_x(
+ fullPublicId, [&](auto status, const auto& device) {
+ ASSERT_EQ(Status::OK, status);
+ ASSERT_NE(device, nullptr);
+ subDevice = device;
+ });
+ ASSERT_TRUE(ret.isOk());
+
+ ret = subDevice->getCameraCharacteristics(
+ [&](auto status, const auto& chars) {
+ ASSERT_EQ(Status::OK, status);
+ retcode = find_camera_metadata_ro_entry(
+ (const camera_metadata_t *)chars.data(),
+ ANDROID_CONTROL_ZOOM_RATIO_RANGE, &entry);
+ bool subCameraHasZoomRatioRange = (0 == retcode && entry.count == 2);
+ ASSERT_EQ(hasZoomRatioRange, subCameraHasZoomRatioRange);
+ });
+ ASSERT_TRUE(ret.isOk());
continue;
}
@@ -5726,6 +5727,12 @@
[&](auto status, const auto& chars) {
verifyCameraCharacteristics(status, chars);
verifyMonochromeCharacteristics(chars, deviceVersion);
+
+ retcode = find_camera_metadata_ro_entry(
+ (const camera_metadata_t *)chars.data(),
+ ANDROID_CONTROL_ZOOM_RATIO_RANGE, &entry);
+ bool subCameraHasZoomRatioRange = (0 == retcode && entry.count == 2);
+ ASSERT_EQ(hasZoomRatioRange, subCameraHasZoomRatioRange);
});
ASSERT_TRUE(ret.isOk());
@@ -5745,8 +5752,7 @@
// Make sure ANDROID_LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID is available in
// result keys.
if (deviceVersion >= CAMERA_DEVICE_API_VERSION_3_5) {
- camera_metadata_ro_entry entry;
- int retcode = find_camera_metadata_ro_entry(metadata,
+ retcode = find_camera_metadata_ro_entry(metadata,
ANDROID_REQUEST_AVAILABLE_RESULT_KEYS, &entry);
if ((0 == retcode) && (entry.count > 0)) {
ASSERT_NE(std::find(entry.data.i32, entry.data.i32 + entry.count,
@@ -5846,6 +5852,7 @@
}
verifyBokehCharacteristics(metadata);
+ verifyZoomCharacteristics(metadata);
}
void CameraHidlTest::verifyBokehCharacteristics(const camera_metadata_t* metadata) {
@@ -5876,38 +5883,51 @@
retcode = find_camera_metadata_ro_entry(metadata,
ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS, &entry);
- bool hasBokehCharacteristicsKey = false;
+ bool hasBokehMaxSizesKey = false;
+ bool hasBokehZoomRatioRangesKey = false;
if ((0 == retcode) && (entry.count > 0)) {
- hasBokehCharacteristicsKey = std::find(entry.data.i32, entry.data.i32+entry.count,
- ANDROID_CONTROL_AVAILABLE_BOKEH_CAPABILITIES) != entry.data.i32+entry.count;
+ hasBokehMaxSizesKey = std::find(entry.data.i32, entry.data.i32+entry.count,
+ ANDROID_CONTROL_AVAILABLE_BOKEH_MAX_SIZES) != entry.data.i32+entry.count;
+ hasBokehZoomRatioRangesKey = std::find(entry.data.i32, entry.data.i32+entry.count,
+ ANDROID_CONTROL_AVAILABLE_BOKEH_ZOOM_RATIO_RANGES) != entry.data.i32+entry.count;
} else {
ADD_FAILURE() << "Get camera availableCharacteristicsKeys failed!";
}
+
+ camera_metadata_ro_entry maxSizesEntry;
retcode = find_camera_metadata_ro_entry(metadata,
- ANDROID_CONTROL_AVAILABLE_BOKEH_CAPABILITIES, &entry);
- bool hasAvailableBokehCaps = (0 == retcode && entry.count > 0);
+ ANDROID_CONTROL_AVAILABLE_BOKEH_MAX_SIZES, &maxSizesEntry);
+ bool hasBokehMaxSizes = (0 == retcode && maxSizesEntry.count > 0);
+
+ camera_metadata_ro_entry zoomRatioRangesEntry;
+ retcode = find_camera_metadata_ro_entry(metadata,
+ ANDROID_CONTROL_AVAILABLE_BOKEH_ZOOM_RATIO_RANGES, &zoomRatioRangesEntry);
+ bool hasBokehZoomRatioRanges = (0 == retcode && zoomRatioRangesEntry.count > 0);
// Bokeh keys must all be available, or all be unavailable.
- bool noBokeh = !hasBokehRequestKey && !hasBokehResultKey && !hasBokehCharacteristicsKey &&
- !hasAvailableBokehCaps;
+ bool noBokeh = !hasBokehRequestKey && !hasBokehResultKey && !hasBokehMaxSizesKey &&
+ !hasBokehZoomRatioRangesKey && !hasBokehMaxSizes && !hasBokehZoomRatioRanges;
if (noBokeh) {
return;
}
- bool hasBokeh = hasBokehRequestKey && hasBokehResultKey && hasBokehCharacteristicsKey &&
- hasAvailableBokehCaps;
+ bool hasBokeh = hasBokehRequestKey && hasBokehResultKey && hasBokehMaxSizesKey &&
+ hasBokehZoomRatioRangesKey && hasBokehMaxSizes && hasBokehZoomRatioRanges;
ASSERT_TRUE(hasBokeh);
// Must have OFF, and must have one of STILL_CAPTURE and CONTINUOUS.
- ASSERT_TRUE(entry.count == 6 || entry.count == 9);
+ // Only valid combinations: {OFF, CONTINUOUS}, {OFF, STILL_CAPTURE}, and
+ // {OFF, CONTINUOUS, STILL_CAPTURE}.
+ ASSERT_TRUE((maxSizesEntry.count == 6 && zoomRatioRangesEntry.count == 2) ||
+ (maxSizesEntry.count == 9 && zoomRatioRangesEntry.count == 4));
bool hasOffMode = false;
bool hasStillCaptureMode = false;
bool hasContinuousMode = false;
std::vector<AvailableStream> outputStreams;
ASSERT_EQ(Status::OK, getAvailableOutputStreams(metadata, outputStreams));
- for (int i = 0; i < entry.count; i += 3) {
- int32_t mode = entry.data.i32[i];
- int32_t maxWidth = entry.data.i32[i+1];
- int32_t maxHeight = entry.data.i32[i+2];
+ for (int i = 0, j = 0; i < maxSizesEntry.count && j < zoomRatioRangesEntry.count; i += 3) {
+ int32_t mode = maxSizesEntry.data.i32[i];
+ int32_t maxWidth = maxSizesEntry.data.i32[i+1];
+ int32_t maxHeight = maxSizesEntry.data.i32[i+2];
switch (mode) {
case ANDROID_CONTROL_BOKEH_MODE_OFF:
hasOffMode = true;
@@ -5915,9 +5935,11 @@
break;
case ANDROID_CONTROL_BOKEH_MODE_STILL_CAPTURE:
hasStillCaptureMode = true;
+ j += 2;
break;
case ANDROID_CONTROL_BOKEH_MODE_CONTINUOUS:
hasContinuousMode = true;
+ j += 2;
break;
default:
ADD_FAILURE() << "Invalid bokehMode advertised: " << mode;
@@ -5925,6 +5947,7 @@
}
if (mode != ANDROID_CONTROL_BOKEH_MODE_OFF) {
+ // Make sure size is supported.
bool sizeSupported = false;
for (const auto& stream : outputStreams) {
if ((stream.format == static_cast<int32_t>(PixelFormat::YCBCR_420_888) ||
@@ -5935,12 +5958,102 @@
}
}
ASSERT_TRUE(sizeSupported);
+
+ // Make sure zoom range is valid
+ float minZoomRatio = zoomRatioRangesEntry.data.f[0];
+ float maxZoomRatio = zoomRatioRangesEntry.data.f[1];
+ ASSERT_GT(minZoomRatio, 0.0f);
+ ASSERT_LE(minZoomRatio, maxZoomRatio);
}
}
ASSERT_TRUE(hasOffMode);
ASSERT_TRUE(hasStillCaptureMode || hasContinuousMode);
}
+void CameraHidlTest::verifyZoomCharacteristics(const camera_metadata_t* metadata) {
+ camera_metadata_ro_entry entry;
+ int retcode = 0;
+
+ // Check key availability in capabilities, request and result.
+ retcode = find_camera_metadata_ro_entry(metadata,
+ ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM, &entry);
+ float maxDigitalZoom = 1.0;
+ if ((0 == retcode) && (entry.count == 1)) {
+ maxDigitalZoom = entry.data.f[0];
+ } else {
+ ADD_FAILURE() << "Get camera scalerAvailableMaxDigitalZoom failed!";
+ }
+
+ retcode = find_camera_metadata_ro_entry(metadata,
+ ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS, &entry);
+ bool hasZoomRequestKey = false;
+ if ((0 == retcode) && (entry.count > 0)) {
+ hasZoomRequestKey = std::find(entry.data.i32, entry.data.i32+entry.count,
+ ANDROID_CONTROL_ZOOM_RATIO) != entry.data.i32+entry.count;
+ } else {
+ ADD_FAILURE() << "Get camera availableRequestKeys failed!";
+ }
+
+ retcode = find_camera_metadata_ro_entry(metadata,
+ ANDROID_REQUEST_AVAILABLE_RESULT_KEYS, &entry);
+ bool hasZoomResultKey = false;
+ if ((0 == retcode) && (entry.count > 0)) {
+ hasZoomResultKey = std::find(entry.data.i32, entry.data.i32+entry.count,
+ ANDROID_CONTROL_ZOOM_RATIO) != entry.data.i32+entry.count;
+ } else {
+ ADD_FAILURE() << "Get camera availableResultKeys failed!";
+ }
+
+ retcode = find_camera_metadata_ro_entry(metadata,
+ ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS, &entry);
+ bool hasZoomCharacteristicsKey = false;
+ if ((0 == retcode) && (entry.count > 0)) {
+ hasZoomCharacteristicsKey = std::find(entry.data.i32, entry.data.i32+entry.count,
+ ANDROID_CONTROL_ZOOM_RATIO_RANGE) != entry.data.i32+entry.count;
+ } else {
+ ADD_FAILURE() << "Get camera availableCharacteristicsKeys failed!";
+ }
+
+ retcode = find_camera_metadata_ro_entry(metadata,
+ ANDROID_CONTROL_ZOOM_RATIO_RANGE, &entry);
+ bool hasZoomRatioRange = (0 == retcode && entry.count == 2);
+
+ // Zoom keys must all be available, or all be unavailable.
+ bool noZoomRatio = !hasZoomRequestKey && !hasZoomResultKey && !hasZoomCharacteristicsKey &&
+ !hasZoomRatioRange;
+ if (noZoomRatio) {
+ return;
+ }
+ bool hasZoomRatio = hasZoomRequestKey && hasZoomResultKey && hasZoomCharacteristicsKey &&
+ hasZoomRatioRange;
+ ASSERT_TRUE(hasZoomRatio);
+
+ float minZoomRatio = entry.data.f[0];
+ float maxZoomRatio = entry.data.f[1];
+ if (maxDigitalZoom != maxZoomRatio) {
+ ADD_FAILURE() << "Maximum zoom ratio is different than maximum digital zoom!";
+ }
+ if (minZoomRatio > maxZoomRatio) {
+ ADD_FAILURE() << "Maximum zoom ratio is less than minimum zoom ratio!";
+ }
+ if (minZoomRatio > 1.0f) {
+ ADD_FAILURE() << "Minimum zoom ratio is more than 1.0!";
+ }
+ if (maxZoomRatio < 1.0f) {
+ ADD_FAILURE() << "Maximum zoom ratio is less than 1.0!";
+ }
+
+ // Make sure CROPPING_TYPE is CENTER_ONLY
+ retcode = find_camera_metadata_ro_entry(metadata,
+ ANDROID_SCALER_CROPPING_TYPE, &entry);
+ if ((0 == retcode) && (entry.count == 1)) {
+ int8_t croppingType = entry.data.u8[0];
+ ASSERT_EQ(croppingType, ANDROID_SCALER_CROPPING_TYPE_CENTER_ONLY);
+ } else {
+ ADD_FAILURE() << "Get camera scalerCroppingType failed!";
+ }
+}
+
void CameraHidlTest::verifyMonochromeCharacteristics(const CameraMetadata& chars,
int deviceVersion) {
const camera_metadata_t* metadata = (camera_metadata_t*)chars.data();
@@ -6311,102 +6424,15 @@
PixelFormat format, hidl_handle *buffer_handle /*out*/) {
ASSERT_NE(buffer_handle, nullptr);
- sp<android::hardware::graphics::allocator::V2_0::IAllocator> allocator =
- android::hardware::graphics::allocator::V2_0::IAllocator::getService();
- sp<android::hardware::graphics::allocator::V3_0::IAllocator> allocatorV3 =
- android::hardware::graphics::allocator::V3_0::IAllocator::getService();
- sp<android::hardware::graphics::allocator::V4_0::IAllocator> allocatorV4 =
- android::hardware::graphics::allocator::V4_0::IAllocator::getService();
+ buffer_handle_t buffer;
+ uint32_t stride;
- sp<android::hardware::graphics::mapper::V4_0::IMapper> mapperV4 =
- android::hardware::graphics::mapper::V4_0::IMapper::getService();
- sp<android::hardware::graphics::mapper::V3_0::IMapper> mapperV3 =
- android::hardware::graphics::mapper::V3_0::IMapper::getService();
- sp<android::hardware::graphics::mapper::V2_0::IMapper> mapper =
- android::hardware::graphics::mapper::V2_0::IMapper::getService();
- if (mapperV4 != nullptr && allocatorV4 != nullptr) {
- ::android::hardware::hidl_vec<uint8_t> descriptor;
- android::hardware::graphics::mapper::V4_0::IMapper::BufferDescriptorInfo descriptorInfo{};
- descriptorInfo.name = "VtsHalCameraProviderV2_4";
- descriptorInfo.width = width;
- descriptorInfo.height = height;
- descriptorInfo.layerCount = 1;
- descriptorInfo.format =
- static_cast<android::hardware::graphics::common::V1_2::PixelFormat>(format);
- descriptorInfo.usage = usage;
+ android::status_t err = android::GraphicBufferAllocator::get().allocateRawHandle(
+ width, height, static_cast<int32_t>(format), 1u /*layerCount*/, usage, &buffer, &stride,
+ "VtsHalCameraProviderV2_4");
+ ASSERT_EQ(err, android::NO_ERROR);
- auto ret = mapperV4->createDescriptor(
- descriptorInfo, [&descriptor](android::hardware::graphics::mapper::V4_0::Error err,
- ::android::hardware::hidl_vec<uint8_t> desc) {
- ASSERT_EQ(err, android::hardware::graphics::mapper::V4_0::Error::NONE);
- descriptor = desc;
- });
- ASSERT_TRUE(ret.isOk());
-
- ret = allocatorV4->allocate(
- descriptor, 1u,
- [&](android::hardware::graphics::mapper::V4_0::Error err, uint32_t /*stride*/,
- const ::android::hardware::hidl_vec<::android::hardware::hidl_handle>&
- buffers) {
- ASSERT_EQ(android::hardware::graphics::mapper::V4_0::Error::NONE, err);
- ASSERT_EQ(buffers.size(), 1u);
- *buffer_handle = buffers[0];
- });
- ASSERT_TRUE(ret.isOk());
- } else if (mapperV3 != nullptr && allocatorV3 != nullptr) {
- ::android::hardware::hidl_vec<uint32_t> descriptor;
- android::hardware::graphics::mapper::V3_0::IMapper::BufferDescriptorInfo descriptorInfo {};
- descriptorInfo.width = width;
- descriptorInfo.height = height;
- descriptorInfo.layerCount = 1;
- descriptorInfo.format =
- static_cast<android::hardware::graphics::common::V1_2::PixelFormat>(format);
- descriptorInfo.usage = usage;
-
- auto ret = mapperV3->createDescriptor(
- descriptorInfo, [&descriptor](android::hardware::graphics::mapper::V3_0::Error err,
- ::android::hardware::hidl_vec<uint32_t> desc) {
- ASSERT_EQ(err, android::hardware::graphics::mapper::V3_0::Error::NONE);
- descriptor = desc;
- });
- ASSERT_TRUE(ret.isOk());
-
- ret = allocatorV3->allocate(descriptor, 1u,
- [&](android::hardware::graphics::mapper::V3_0::Error err, uint32_t /*stride*/,
- const ::android::hardware::hidl_vec<::android::hardware::hidl_handle>& buffers) {
- ASSERT_EQ(android::hardware::graphics::mapper::V3_0::Error::NONE, err);
- ASSERT_EQ(buffers.size(), 1u);
- *buffer_handle = buffers[0];
- });
- ASSERT_TRUE(ret.isOk());
- } else {
- ::android::hardware::hidl_vec<uint32_t> descriptor;
- ASSERT_NE(mapper.get(), nullptr);
- ASSERT_NE(allocator.get(), nullptr);
- android::hardware::graphics::mapper::V2_0::IMapper::BufferDescriptorInfo descriptorInfo {};
- descriptorInfo.width = width;
- descriptorInfo.height = height;
- descriptorInfo.layerCount = 1;
- descriptorInfo.format = format;
- descriptorInfo.usage = usage;
-
- auto ret = mapper->createDescriptor(
- descriptorInfo, [&descriptor](android::hardware::graphics::mapper::V2_0::Error err,
- ::android::hardware::hidl_vec<uint32_t> desc) {
- ASSERT_EQ(err, android::hardware::graphics::mapper::V2_0::Error::NONE);
- descriptor = desc;
- });
- ASSERT_TRUE(ret.isOk());
-
- ret = allocator->allocate(descriptor, 1u,
- [&](android::hardware::graphics::mapper::V2_0::Error err, uint32_t /*stride*/,
- const ::android::hardware::hidl_vec<::android::hardware::hidl_handle>& buffers) {
- ASSERT_EQ(android::hardware::graphics::mapper::V2_0::Error::NONE, err);
- ASSERT_EQ(buffers.size(), 1u);
- *buffer_handle = buffers[0];
- });
- ASSERT_TRUE(ret.isOk());
- }
+ buffer_handle->setTo(const_cast<native_handle_t*>(buffer), true /*shouldOwn*/);
}
void CameraHidlTest::verifyRecommendedConfigs(const CameraMetadata& chars) {
@@ -6526,11 +6552,27 @@
}
}
-int main(int argc, char **argv) {
- ::testing::AddGlobalTestEnvironment(CameraHidlEnvironment::Instance());
- ::testing::InitGoogleTest(&argc, argv);
- CameraHidlEnvironment::Instance()->init(&argc, argv);
- int status = RUN_ALL_TESTS();
- ALOGI("Test result = %d", status);
- return status;
+void CameraHidlTest::verifyRequestTemplate(const camera_metadata_t* metadata,
+ RequestTemplate requestTemplate) {
+ ASSERT_NE(nullptr, metadata);
+ size_t entryCount =
+ get_camera_metadata_entry_count(metadata);
+ ALOGI("template %u metadata entry count is %zu", (int32_t)requestTemplate, entryCount);
+ // TODO: we can do better than 0 here. Need to check how many required
+ // request keys we've defined for each template
+ ASSERT_GT(entryCount, 0u);
+
+ // Check zoomRatio
+ camera_metadata_ro_entry zoomRatioEntry;
+ int foundZoomRatio = find_camera_metadata_ro_entry(metadata,
+ ANDROID_CONTROL_ZOOM_RATIO, &zoomRatioEntry);
+ if (foundZoomRatio == 0) {
+ ASSERT_EQ(zoomRatioEntry.count, 1);
+ ASSERT_EQ(zoomRatioEntry.data.f[0], 1.0f);
+ }
}
+
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, CameraHidlTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(ICameraProvider::descriptor)),
+ android::hardware::PrintInstanceNameToString);
diff --git a/cas/1.2/Android.bp b/cas/1.2/Android.bp
index af98b2e..fbb38b0 100644
--- a/cas/1.2/Android.bp
+++ b/cas/1.2/Android.bp
@@ -7,10 +7,10 @@
enabled: true,
},
srcs: [
+ "types.hal",
"ICas.hal",
"ICasListener.hal",
"IMediaCasService.hal",
- "types.hal",
],
interfaces: [
"android.hardware.cas@1.0",
diff --git a/common/aidl/Android.bp b/common/aidl/Android.bp
new file mode 100644
index 0000000..6f2d292
--- /dev/null
+++ b/common/aidl/Android.bp
@@ -0,0 +1,21 @@
+aidl_interface {
+ name: "vintf-common",
+ host_supported: true,
+ vendor_available: true,
+ vndk: {
+ enabled: true,
+ support_system_process: true,
+ },
+ srcs: [
+ "android/hardware/common/*.aidl",
+ ],
+ stability: "vintf",
+ backend: {
+ java: {
+ enabled: false,
+ },
+ cpp: {
+ enabled: false,
+ },
+ },
+}
diff --git a/common/aidl/android/hardware/common/NativeHandle.aidl b/common/aidl/android/hardware/common/NativeHandle.aidl
new file mode 100644
index 0000000..2c250a2
--- /dev/null
+++ b/common/aidl/android/hardware/common/NativeHandle.aidl
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2019 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.common;
+
+/**
+ * Representation of a native handle.
+ */
+@VintfStability
+parcelable NativeHandle {
+ ParcelFileDescriptor[] fds;
+ int[] ints;
+}
diff --git a/compatibility_matrices/Android.bp b/compatibility_matrices/Android.bp
index 799ab07..7883dd9 100644
--- a/compatibility_matrices/Android.bp
+++ b/compatibility_matrices/Android.bp
@@ -83,8 +83,8 @@
"compatibility_matrix.current.xml",
],
kernel_configs: [
- "kernel_config_current_4.9",
"kernel_config_current_4.14",
"kernel_config_current_4.19",
+ "kernel_config_current_5.4",
]
}
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index 4bd8332..1e3f743 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -49,6 +49,13 @@
<instance>default</instance>
</interface>
</hal>
+ <hal format="aidl" optional="true">
+ <name>android.hardware.automotive.occupant_awareness</name>
+ <interface>
+ <name>IOccupantAwareness</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
<hal format="hidl" optional="true">
<name>android.hardware.automotive.vehicle</name>
<version>2.0</version>
@@ -155,7 +162,7 @@
</hal>
<hal format="hidl" optional="true">
<name>android.hardware.drm</name>
- <version>1.0-2</version>
+ <version>1.0-3</version>
<interface>
<name>ICryptoFactory</name>
<regex-instance>.*</regex-instance>
@@ -189,7 +196,7 @@
- test DeviceManifestTest#GnssHalVersionCompatibility.
-->
<version>1.1</version>
- <version>2.0</version>
+ <version>2.0-1</version>
<interface>
<name>IGnss</name>
<instance>default</instance>
@@ -349,7 +356,7 @@
</hal>
<hal format="hidl" optional="true">
<name>android.hardware.radio</name>
- <version>1.4</version>
+ <version>1.5</version>
<interface>
<name>IRadio</name>
<instance>slot1</instance>
@@ -367,10 +374,7 @@
</hal>
<hal format="hidl" optional="true">
<name>android.hardware.radio.config</name>
- <!--
- See compatibility_matrix.4.xml on versioning of radio config HAL.
- -->
- <version>1.1</version>
+ <version>1.3</version>
<interface>
<name>IRadioConfig</name>
<instance>default</instance>
@@ -384,6 +388,13 @@
<instance>default</instance>
</interface>
</hal>
+ <hal format="aidl" optional="true">
+ <name>android.hardware.rebootescrow</name>
+ <interface>
+ <name>IRebootEscrow</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
<hal format="hidl" optional="true">
<name>android.hardware.secure_element</name>
<version>1.0</version>
@@ -404,7 +415,7 @@
</hal>
<hal format="hidl" optional="true">
<name>android.hardware.soundtrigger</name>
- <version>2.0-2</version>
+ <version>2.0-3</version>
<interface>
<name>ISoundTriggerHw</name>
<instance>default</instance>
@@ -508,7 +519,7 @@
</hal>
<hal format="hidl" optional="true">
<name>android.hardware.wifi.hostapd</name>
- <version>1.0-1</version>
+ <version>1.0-2</version>
<interface>
<name>IHostapd</name>
<instance>default</instance>
diff --git a/contexthub/1.0/vts/functional/Android.bp b/contexthub/1.0/vts/functional/Android.bp
index aef0340..9e99c33 100644
--- a/contexthub/1.0/vts/functional/Android.bp
+++ b/contexthub/1.0/vts/functional/Android.bp
@@ -19,6 +19,8 @@
defaults: ["VtsHalTargetTestDefaults"],
srcs: ["VtsHalContexthubV1_0TargetTest.cpp"],
static_libs: ["android.hardware.contexthub@1.0"],
- test_suites: ["general-tests"],
+ test_suites: [
+ "general-tests",
+ "vts-core",
+ ],
}
-
diff --git a/contexthub/1.0/vts/functional/OWNERS b/contexthub/1.0/vts/functional/OWNERS
index 045cc4e..161b2f0 100644
--- a/contexthub/1.0/vts/functional/OWNERS
+++ b/contexthub/1.0/vts/functional/OWNERS
@@ -4,5 +4,5 @@
stange@google.com
#VTS team
-yim@google.com
+dshi@google.com
trong@google.com
diff --git a/contexthub/1.0/vts/functional/VtsHalContexthubV1_0TargetTest.cpp b/contexthub/1.0/vts/functional/VtsHalContexthubV1_0TargetTest.cpp
index 629477a..a1d173b 100644
--- a/contexthub/1.0/vts/functional/VtsHalContexthubV1_0TargetTest.cpp
+++ b/contexthub/1.0/vts/functional/VtsHalContexthubV1_0TargetTest.cpp
@@ -16,13 +16,14 @@
#define LOG_TAG "contexthub_hidl_hal_test"
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
#include <android-base/logging.h>
#include <android/hardware/contexthub/1.0/IContexthub.h>
#include <android/hardware/contexthub/1.0/IContexthubCallback.h>
#include <android/hardware/contexthub/1.0/types.h>
#include <android/log.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include <log/log.h>
#include <cinttypes>
@@ -76,69 +77,44 @@
}
// Gets a list of valid hub IDs in the system
-std::vector<uint32_t> getHubIds() {
- static std::vector<uint32_t> hubIds;
+std::vector<std::string> getHubIds(const std::string& service_name) {
+ std::vector<std::string> hubIds;
- if (hubIds.size() == 0) {
- sp<IContexthub> hubApi = ::testing::VtsHalHidlTargetTestBase::getService<IContexthub>();
+ sp<IContexthub> hubApi = IContexthub::getService(service_name);
if (hubApi != nullptr) {
- for (const ContextHub& hub : getHubsSync(hubApi)) {
- hubIds.push_back(hub.hubId);
- }
+ for (const ContextHub& hub : getHubsSync(hubApi)) {
+ hubIds.push_back(std::to_string(hub.hubId));
+ }
}
- }
- ALOGD("Running tests against all %zu reported hubs", hubIds.size());
- return hubIds;
+ ALOGD("Running tests against all %zu reported hubs for service %s", hubIds.size(),
+ service_name.c_str());
+ return hubIds;
}
-// Test environment for Contexthub HIDL HAL.
-class ContexthubHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static ContexthubHidlEnvironment* Instance() {
- static ContexthubHidlEnvironment* instance = new ContexthubHidlEnvironment;
- return instance;
- }
+// Test fixture parameterized by hub ID, initializes the HAL and makes the context hub API handle
+// available.
+class ContexthubHidlTest : public ::testing::TestWithParam<std::tuple<std::string, std::string>> {
+ public:
+ virtual void SetUp() override {
+ hubApi = IContexthub::getService(std::get<0>(GetParam()));
+ ASSERT_NE(hubApi, nullptr);
- virtual void registerTestServices() override { registerTestService<IContexthub>(); }
- private:
- ContexthubHidlEnvironment() {}
-};
+ // getHubs() must be called at least once for proper initialization of the
+ // HAL implementation
+ getHubsSync(hubApi);
+ }
-// Base test fixture that initializes the HAL and makes the context hub API
-// handle available
-class ContexthubHidlTestBase : public ::testing::VtsHalHidlTargetTestBase {
- public:
- virtual void SetUp() override {
- hubApi = ::testing::VtsHalHidlTargetTestBase::getService<IContexthub>(
- ContexthubHidlEnvironment::Instance()->getServiceName<IContexthub>());
- ASSERT_NE(hubApi, nullptr);
+ uint32_t getHubId() { return std::stoi(std::get<1>(GetParam())); }
- // getHubs() must be called at least once for proper initialization of the
- // HAL implementation
- getHubsSync(hubApi);
- }
+ Result registerCallback(sp<IContexthubCallback> cb) {
+ Result result = hubApi->registerCallback(getHubId(), cb);
+ ALOGD("Registered callback, result %" PRIu32, result);
+ return result;
+ }
- virtual void TearDown() override {}
-
- sp<IContexthub> hubApi;
-};
-
-// Test fixture parameterized by hub ID
-class ContexthubHidlTest : public ContexthubHidlTestBase,
- public ::testing::WithParamInterface<uint32_t> {
- public:
- uint32_t getHubId() {
- return GetParam();
- }
-
- Result registerCallback(sp<IContexthubCallback> cb) {
- Result result = hubApi->registerCallback(getHubId(), cb);
- ALOGD("Registered callback, result %" PRIu32, result);
- return result;
- }
+ sp<IContexthub> hubApi;
};
// Base callback implementation that just logs all callbacks by default
@@ -202,24 +178,24 @@
}
// Ensures that the metadata reported in getHubs() is sane
-TEST_F(ContexthubHidlTestBase, TestGetHubs) {
- hidl_vec<ContextHub> hubs = getHubsSync(hubApi);
- ALOGD("System reports %zu hubs", hubs.size());
+TEST_P(ContexthubHidlTest, TestGetHubs) {
+ hidl_vec<ContextHub> hubs = getHubsSync(hubApi);
+ ALOGD("System reports %zu hubs", hubs.size());
- for (const ContextHub& hub : hubs) {
- ALOGD("Checking hub ID %" PRIu32, hub.hubId);
+ for (const ContextHub& hub : hubs) {
+ ALOGD("Checking hub ID %" PRIu32, hub.hubId);
- EXPECT_FALSE(hub.name.empty());
- EXPECT_FALSE(hub.vendor.empty());
- EXPECT_FALSE(hub.toolchain.empty());
- EXPECT_GT(hub.peakMips, 0);
- EXPECT_GE(hub.stoppedPowerDrawMw, 0);
- EXPECT_GE(hub.sleepPowerDrawMw, 0);
- EXPECT_GT(hub.peakPowerDrawMw, 0);
+ EXPECT_FALSE(hub.name.empty());
+ EXPECT_FALSE(hub.vendor.empty());
+ EXPECT_FALSE(hub.toolchain.empty());
+ EXPECT_GT(hub.peakMips, 0);
+ EXPECT_GE(hub.stoppedPowerDrawMw, 0);
+ EXPECT_GE(hub.sleepPowerDrawMw, 0);
+ EXPECT_GT(hub.peakPowerDrawMw, 0);
- // Minimum 128 byte MTU as required by CHRE API v1.0
- EXPECT_GE(hub.maxSupportedMsgLen, UINT32_C(128));
- }
+ // Minimum 128 byte MTU as required by CHRE API v1.0
+ EXPECT_GE(hub.maxSupportedMsgLen, UINT32_C(128));
+ }
}
TEST_P(ContexthubHidlTest, TestRegisterCallback) {
@@ -388,20 +364,28 @@
cb->promise.get_future()));
}
-// Parameterize all SingleContexthubTest tests against each valid hub ID
-INSTANTIATE_TEST_CASE_P(HubIdSpecificTests, ContexthubHidlTest,
- ::testing::ValuesIn(getHubIds()));
-INSTANTIATE_TEST_CASE_P(HubIdSpecificTests, ContexthubTxnTest,
- ::testing::ValuesIn(getHubIds()));
+// Return the test parameters of a vecter of tuples for all IContexthub services and each of its hub
+// id: <service name of IContexthub, hub id of the IContexthub service>
+static std::vector<std::tuple<std::string, std::string>> get_parameters() {
+ std::vector<std::tuple<std::string, std::string>> parameters;
+ std::vector<std::string> service_names =
+ android::hardware::getAllHalInstanceNames(IContexthub::descriptor);
+ for (const std::string& service_name : service_names) {
+ std::vector<std::string> ids = getHubIds(service_name);
+ for (const std::string& id : ids) {
+ parameters.push_back(std::make_tuple(service_name, id));
+ }
+ }
-} // anonymous namespace
-
-int main(int argc, char **argv) {
- ::testing::AddGlobalTestEnvironment(ContexthubHidlEnvironment::Instance());
- ::testing::InitGoogleTest(&argc, argv);
- ContexthubHidlEnvironment::Instance()->init(&argc, argv);
- int status = RUN_ALL_TESTS();
- ALOGI ("Test result = %d", status);
- return status;
+ return parameters;
}
+static std::vector<std::tuple<std::string, std::string>> kTestParameters = get_parameters();
+
+INSTANTIATE_TEST_SUITE_P(HubIdSpecificTests, ContexthubHidlTest, testing::ValuesIn(kTestParameters),
+ android::hardware::PrintInstanceTupleNameToString<>);
+
+INSTANTIATE_TEST_SUITE_P(HubIdSpecificTests, ContexthubTxnTest, testing::ValuesIn(kTestParameters),
+ android::hardware::PrintInstanceTupleNameToString<>);
+
+} // anonymous namespace
diff --git a/current.txt b/current.txt
index d5082af..30bee15 100644
--- a/current.txt
+++ b/current.txt
@@ -298,7 +298,13 @@
3661fa0623056922fdc4235ac5a9c91a2d066ab6f1ab4297e3b240fe302ba500 android.hardware.audio.effect@4.0::IPresetReverbEffect
e88e520f8c98a62fccd8d5316c6687808f775de145d1405a7a9a66587ee6a001 android.hardware.audio.effect@4.0::IVirtualizerEffect
fe28829dab10d171783b79ac9cc45412739f8ff275e90228d7c6370ef189b859 android.hardware.audio.effect@4.0::IVisualizerEffect
-21c8a702579356480236c6851b5b2c16b9bd369ce12bdd6ffdc4626a89f34f73 android.hardware.audio.effect@4.0::types
+21c8a702579356480236c6851b5b2c16b9bd369ce12bdd6ffdc4626a89f34f73 android.hardware.audio.effect@4.0::types
+a0f93c768c353cecee6237fe479bce47404eb10b629fafe07e32a054fd67f2af android.hardware.automotive.audiocontrol@1.0::IAudioControl
+f2904a4c108ad1b93eb2fa4e43b82bd01ce1ff26156316e49d1d9fc80dfecaad android.hardware.automotive.evs@1.0::IEvsCamera
+94cba6ad04c83aa840de2ed52b74ba2126a26dd960225e61ac36703315279a80 android.hardware.automotive.evs@1.0::IEvsCameraStream
+5ea36fb043d9e3b413219de3dfd7b046b48af4fda39f167f3528652e986cb76d android.hardware.automotive.evs@1.0::IEvsDisplay
+b15c5d8f28be4f0469c11d184ebca616895f109d553a6c31018789d8c1bc0ac5 android.hardware.automotive.evs@1.0::IEvsEnumerator
+3b17c1fdfc389e0abe626c37054954b07201127d890c2bc05d47613ec1f4de4f android.hardware.automotive.evs@1.0::types
42a06dc288f61b0690580f3d37b30b663c31d74d50bb58d0772386b550d5faab android.hardware.authsecret@1.0::IAuthSecret
32cc50cc2a7658ec613c0c2dd2accbf6a05113b749852879e818b8b7b438db19 android.hardware.bluetooth.a2dp@1.0::IBluetoothAudioHost
ff4be64d7992f8bec97dff37f35450e79b3430c61f85f54322ce45bef229dc3b android.hardware.bluetooth.a2dp@1.0::IBluetoothAudioOffload
@@ -572,19 +578,50 @@
cfa81f229b69f9011c58f48264fcb552447430fe68610eac514e811e65bc306a android.hardware.wifi.supplicant@1.2::types
# ABI preserving changes to HALs during Android R
+c3ec182ce325862b7d79e526f3e170c02cfee1497ed309d7c60d0de4ca636b0b android.hardware.automotive.audiocontrol@1.0::IAudioControl
+1b6d0927615ddbf4c56a993fa1845bca15543e315fb6f48c77276e2fa2918ac5 android.hardware.automotive.evs@1.0::IEvsCamera
+3901859d36b7b4d32910d61cd1e8982b0ffeb8fb77b457ac6349e8bf1abcd595 android.hardware.automotive.evs@1.0::IEvsCameraStream
+578f640c653726d58f99c84a7e1bb63862e21ef7cbb4f7d95c3cc62de00dca35 android.hardware.automotive.evs@1.0::IEvsDisplay
+f5bc6aa840db933cb9fd36668b06d3e2021cf5384bb70e459f22e2f2f921fba5 android.hardware.automotive.evs@1.0::IEvsEnumerator
+d3a344b7bd4c0d2658ae7209f55a979b8f53f361fd00f4fca29d5baa56d11fd2 android.hardware.automotive.evs@1.0::types
2410dd02d67786a732d36e80b0f8ccf55086604ef37f9838e2013ff2c571e404 android.hardware.camera.device@3.5::types
+cd06a7911b9acd4a653bbf7133888878fbcb3f84be177c7a3f1becaae3d8618f android.hardware.camera.metadata@3.2::types
b69a7615c508acf5c5201efd1bfa3262167874fc3594e2db5a3ff93addd8ac75 android.hardware.keymaster@4.0::IKeymasterDevice
eb2fa0c883c2185d514be0b84c179b283753ef0c1b77b45b4f359bd23bba8b75 android.hardware.neuralnetworks@1.0::IPreparedModel
f1109cbb10297b7429a11fab42afa912710b303c9bf20bd5cdb8bd57b9c84186 android.hardware.neuralnetworks@1.0::types
-9d8ee57c490ffeaa28f702eaea8d198cb510e4bbfb99e6cb5f63e73341057c7c android.hardware.neuralnetworks@1.1::types
+5f6d3097ba84cb63c430787123f4de1b31c11f90b531b98eae9a8623a5ae962a android.hardware.neuralnetworks@1.1::types
fb382e986c10b8fbb797a8546e8f9ea6d1107bfe6f3fb7e57f6bbbf1f807a906 android.hardware.neuralnetworks@1.2::IDevice
40e71cd693de5b832325c5d8f081f2ff20a7ba2b89d401cee5b4b3eb0e241681 android.hardware.neuralnetworks@1.2::IPreparedModel
-72de91c3feba4b19c159cd1c413cbea596b78240caa43e31194e20e6f5b05c49 android.hardware.neuralnetworks@1.2::types
+2d5483fbf59d5fd2de94665a6df05da5c3d09de67561d0db5e9f09e59e9aea46 android.hardware.neuralnetworks@1.2::types
a785a57447a81e9c130eef6904c3a5c256076c6a04588c40620ebd6fa2660d77 android.hardware.radio@1.2::types
1a6e2bd289f22931c526b21916910f1d4c436b7acb9556e4243de4ce8e6cc2e4 android.hardware.soundtrigger@2.0::ISoundTriggerHwCallback
fd65298e1e09e0e3c781ab18305920d757dbe55a3b459ce17814ec5cf6dfee99 android.hardware.wifi@1.0::IWifiP2pIface
# HALs released in Android R
+e966a3437d6a98d9d9e14e9d672088771716031900c0deb55a0946c751a03a44 android.hardware.audio@6.0::types
+dd3e9280be60a5e042331c1046d13938e2cc323dc4b267cc74d544bf62fc0314 android.hardware.audio@6.0::IDevice
+2402876cbc23c0de3690a665eca84fd3857d1808dba5cad25ce272f81ecef8c9 android.hardware.audio@6.0::IDevicesFactory
+bca5379d5065e2e08b6ad7308ffc8a71a972fc0698bec678ea32eea786d01cb5 android.hardware.audio@6.0::IPrimaryDevice
+fd1f1b29f26b42e886220f04a08086c00e5ade9d7b53f095438e578ab9d42a93 android.hardware.audio@6.0::IStream
+2df5d5866b37776f25079c0e54b54350a2abe4e025a59c9e02a7d3abe8ca00e8 android.hardware.audio@6.0::IStreamIn
+78e4138cc8307c11fc777c3bd376e581ba4ba48196b05ca1d7cdfa515c87b48a android.hardware.audio@6.0::IStreamOut
+997fdaad7a9d17ee7e01feb7031a753e2365e72ad30b11d950e9183fabdf3844 android.hardware.audio@6.0::IStreamOutCallback
+1349686814402fa10f711cc5763bc629aafc64a5f5843b4b21b8cd86ffb923e6 android.hardware.audio.common@6.0::types
+817930d58412d662cb45e641c50cb62c727e4a3e3ffe7029a53cad9677b97d58 android.hardware.audio.effect@6.0::types
+525bec6b44f1103869c269a128d51b8dccd73af5340ba863c8886c68357c7faf android.hardware.audio.effect@6.0::IAcousticEchoCancelerEffect
+8d76bbe3719d051a8e9a1dcf9244f37f5b0a491feb249fa48391edf7cb4f3131 android.hardware.audio.effect@6.0::IAutomaticGainControlEffect
+461b1114cb35d89f87e5694e0792ba53c112a7fa9a14d9b95188cf9c4764be23 android.hardware.audio.effect@6.0::IBassBoostEffect
+8bc597d166e07e9eba633267fc2872c4c53d13d3f0025b778c98e13324a165de android.hardware.audio.effect@6.0::IDownmixEffect
+9ee022c81e79da6051fde0836c1c1c4d5414e0c9a6cccc0ce17a90346ceb1391 android.hardware.audio.effect@6.0::IEffect
+75c99a70577d543359910a0b378bcbf5a0d6076712e58e6864cd8803f76c8684 android.hardware.audio.effect@6.0::IEffectBufferProviderCallback
+b138d519696f23af2c7cb92c532178c35f4b3a5c1b689260b1c308fe00249f8b android.hardware.audio.effect@6.0::IEffectsFactory
+dd377f404a8e71f6191d295e10067db629b0f0c28e594af906f2bea5d87fe2cc android.hardware.audio.effect@6.0::IEnvironmentalReverbEffect
+455e085e136767302ec34d02b51a085c310e79bf500b76dda7c96a7f3637f11a android.hardware.audio.effect@6.0::IEqualizerEffect
+24b5e107a0cbd2b322f764a4d5f7fb8b5d8c337a060b9a4a26b9af050c57b5d0 android.hardware.audio.effect@6.0::ILoudnessEnhancerEffect
+4aae0a13f53a8ce20fad372de2d1d864a0bae194b0f1b1d2c090367af8615af2 android.hardware.audio.effect@6.0::INoiseSuppressionEffect
+5237c42d3913ef569f07bec802568084b615155d05a7951e75085da54856508c android.hardware.audio.effect@6.0::IPresetReverbEffect
+282193799d60bff27a84c65a36218c1e7d8f582f5828e2e059383d1b90aa56bd android.hardware.audio.effect@6.0::IVirtualizerEffect
+0868e00f7c5ee16723bda1a8f57099763d04100ae7126a1c2d3a9a87c844a7e8 android.hardware.audio.effect@6.0::IVisualizerEffect
79e115c8f8970b8b914bafc66df5425e065fda4dcda97222966ef12451d2a1cc android.hardware.bluetooth@1.1::IBluetoothHci
40ab2c6866c18d32baf6e49e3053949e79601f56963a791e93e68b9ee18f718d android.hardware.bluetooth@1.1::IBluetoothHciCallbacks
07d0a252b2d8fa35887908a996ba395cf392968395fc30afab791f46e0c22a52 android.hardware.boot@1.1::IBootControl
@@ -593,6 +630,13 @@
9811f867def49b420d8c707f7e38d3bdd64f835244e1d2a5e9762ab9835672dc android.hardware.cas@1.2::ICasListener
f18695dd36ee205640b8326a17453858a7b4596653aaa6ef0016b0aef1bd4dac android.hardware.cas@1.2::IMediaCasService
4d85e814f94949dae4dc6cb82bbd7d6bb24ffafda6ddb2eac928d2a4fc2e21ce android.hardware.cas@1.2::types
+66931c2506fbb5af61f20138cb05e0a09e7bf67d6964c231d27c648933bb33ec android.hardware.drm@1.3::ICryptoFactory
+994d08ab27d613022c258a9ec48cece7adf2a305e92df5d76ef923e2c6665f64 android.hardware.drm@1.3::IDrmFactory
+3dacec7801968e1e4479724dc0180442d9e915466bff051f80996266b1a51c2c android.hardware.gnss@2.1::IGnss
+ba62e1e8993bfb9f27fa04816fa0f2241ae2d01edfa3d0c04182e2e5de80045c android.hardware.gnss@2.1::IGnssCallback
+ccdf3c0fb2c02a6d4dc57afb276c3497ae8172b80b00ebc0bf8a0238dd38b01d android.hardware.gnss@2.1::IGnssConfiguration
+5a125c49ca83629e22afc8c39e865509343bfa2c38f0baea9a186bbac103492d android.hardware.gnss@2.1::IGnssMeasurement
+0bfb291708dd4a7c6ec6b9883e2b8592357edde8d7e962ef83918e4a2154ce69 android.hardware.gnss@2.1::IGnssMeasurementCallback
ce8dbe76eb9ee94b46ef98f725be992e760a5751073d4f4912484026541371f3 android.hardware.health@2.1::IHealth
26f04510a0b57aba5167c5c0a7c2f077c2acbb98b81902a072517829fd9fd67f android.hardware.health@2.1::IHealthInfoCallback
db47f4ceceb1f06c656f39caa70c557b0f8471ef59fd58611bea667ffca20101 android.hardware.health@2.1::types
@@ -602,16 +646,24 @@
df9c79c4fdde2821550c6d5c3d07f5ec0adfb1b702561ce543c906ddef698703 android.hardware.media.c2@1.1::IComponent
a3eddd9bbdc87e8c22764070037dd1154f1cf006e6fba93364c4f85d4c134a19 android.hardware.media.c2@1.1::IComponentStore
9e59fffceed0dd72a9799e04505db5f777bbbea1af0695ba4107ef6d967c6fda android.hardware.neuralnetworks@1.3::IDevice
-4a6c3b3556da951b4def21ba579a227c022980fe4465df6cdfbe20628fa75f5a android.hardware.neuralnetworks@1.3::IPreparedModel
+258825966435b3ed08832055bb736d81516013e405f161d9ccde9a90cfcdde83 android.hardware.neuralnetworks@1.3::IPreparedModel
94e803236398bed1febb11cc21051bc42ec003700139b099d6c479e02a7ca3c3 android.hardware.neuralnetworks@1.3::IPreparedModelCallback
-103cb87c5ed46851badac097f8d190da60f39b5ab32d60e2e93f64d3014ea75c android.hardware.neuralnetworks@1.3::types
+cf1d55e8c68300090747ab90b94c22e4c859b29c84ced68a317c595bb115eab2 android.hardware.neuralnetworks@1.3::types
3e01d4446cd69fd1c48f8572efd97487bc179564b32bd795800b97bbe10be37b android.hardware.wifi@1.4::IWifi
+36b3acf78ac4ecf8156be8741c1d8332cdce7a1ebf4dfa1562952f14a94e6c87 android.hardware.wifi.hostapd@1.2::IHostapd
+2defa258951e25a132aaeb36e3febe6f41bf9c6dbb1b1ebdf0b41708ab4e107e android.hardware.wifi.hostapd@1.2::types
a64467bae843569f0d465c5be7f0c7a5b987985b55a3ef4794dd5afc68538650 android.hardware.wifi.supplicant@1.3::ISupplicant
-44445b8a03d7b9e68b2fbd954672c18a8fce9e32851b0692f4f4ab3407f86ecb android.hardware.wifi.supplicant@1.3::ISupplicantStaIface
+213457930af81ff3ea344fbc9d4a0d0a2bb70527f96b7b6a32ee3b5e4c17057e android.hardware.wifi.supplicant@1.3::ISupplicantStaIface
619fc9839ec6e369cfa9b28e3e9412e6885720ff8f9b5750c1b6ffb905120391 android.hardware.wifi.supplicant@1.3::ISupplicantStaIfaceCallback
-c9273429fcf98d797d3bb07fdba6f1be95bf960f9255cde169fd1ca4db85f856 android.hardware.wifi.supplicant@1.3::ISupplicantStaNetwork
+a6163000e2804472924733bcf8b4269db776460cc4df64f9c4dc8350d7aeafc5 android.hardware.wifi.supplicant@1.3::ISupplicantStaNetwork
9b0a3ab6f4f74b971ed094426d8a443e29b512ff03e1ab50c07156396cdb2483 android.hardware.wifi.supplicant@1.3::types
-274fb1254a6d1a97824ec5c880eeefc0e410dc6d3a2a4c34052201169d2b7de0 android.hardware.radio@1.5::types
-c8e81d912827a5d49b2ddcdc4eb4556c5d231a899a1dca879309e04210daa4a0 android.hardware.radio@1.5::IRadio
-a62a93faf173b14a6175b683ebf61ffa568dc61f81e369d2dce7b1265e86cf2f android.hardware.radio@1.5::IRadioIndication
-260ce05806d753d728f844d405e832179ed7d9b65986ec18fef3d21cf7285587 android.hardware.radio@1.5::IRadioResponse
\ No newline at end of file
+0e3c23f1c815469fdcdc39bc33a486817771c7c6b6e5303f2f25569499fc6c69 android.hardware.radio@1.5::types
+2bc87cde08fcd8d9a0f5d4a2b8560ea793264d94f5b763a6b22d4a63d0f3cd5a android.hardware.radio@1.5::IRadio
+3afac66f21a33bc9c4b80481c7d5540038348651d9a7d8af64ea13610af138da android.hardware.radio@1.5::IRadioIndication
+67c8d90dab3f5b8f1e9cf123d6d1f9e581d382846eacc14476335798b9670885 android.hardware.radio@1.5::IRadioResponse
+55f0a15642869ec98a55ea0a5ac049d3e1a6245ff7750deb6bcb7182057eee83 android.hardware.radio.config@1.3::types
+b27ab0cd40b0b078cdcd024bfe1061c4c4c065f3519eeb9347fa359a3268a5ae android.hardware.radio.config@1.3::IRadioConfig
+742360c775313438b0f82256eac62fb5bbc76a6ae6f388573f3aa142fb2c1eea android.hardware.radio.config@1.3::IRadioConfigIndication
+7683fed9d253956071f18b152e6be657719536f98d9b534433d5e411bcde5061 android.hardware.radio.config@1.3::IRadioConfigResponse
+c411dc16855fcb786cd5e08fe2889acbd72fd54217bd27fe0373813de230ce5f android.hardware.soundtrigger@2.3::types
+5abad7b54d3400fab633cb7a36ffc1747e037bf805d3d9e3517cb6aabf26b002 android.hardware.soundtrigger@2.3::ISoundTriggerHw
diff --git a/drm/1.0/Android.bp b/drm/1.0/Android.bp
index a950c57..9049af2 100644
--- a/drm/1.0/Android.bp
+++ b/drm/1.0/Android.bp
@@ -17,5 +17,5 @@
interfaces: [
"android.hidl.base@1.0",
],
- gen_java: false,
+ gen_java: true,
}
diff --git a/drm/1.3/Android.bp b/drm/1.3/Android.bp
new file mode 100644
index 0000000..b0ffcb9
--- /dev/null
+++ b/drm/1.3/Android.bp
@@ -0,0 +1,20 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+hidl_interface {
+ name: "android.hardware.drm@1.3",
+ root: "android.hardware",
+ vndk: {
+ enabled: true,
+ },
+ srcs: [
+ "IDrmFactory.hal",
+ "ICryptoFactory.hal",
+ ],
+ interfaces: [
+ "android.hardware.drm@1.0",
+ "android.hardware.drm@1.1",
+ "android.hardware.drm@1.2",
+ "android.hidl.base@1.0",
+ ],
+ gen_java: false,
+}
diff --git a/drm/1.3/ICryptoFactory.hal b/drm/1.3/ICryptoFactory.hal
new file mode 100644
index 0000000..d7864eb
--- /dev/null
+++ b/drm/1.3/ICryptoFactory.hal
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2019 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.drm@1.3;
+
+import @1.2::ICryptoFactory;
+
+/**
+ * ICryptoFactory is the main entry point for interacting with a vendor's
+ * crypto HAL to create crypto plugins. Crypto plugins create crypto sessions
+ * which are used by a codec to decrypt protected video content.
+ *
+ * The 1.3 factory must always create 1.2 ICryptoPlugin interfaces, which are
+ * returned via the 1.0 createPlugin method.
+ *
+ * The ICryptoFactory hal is required because all top-level interfaces
+ * have to be updated in a minor uprev.
+ */
+interface ICryptoFactory extends @1.2::ICryptoFactory {
+};
diff --git a/drm/1.3/IDrmFactory.hal b/drm/1.3/IDrmFactory.hal
new file mode 100644
index 0000000..5208028
--- /dev/null
+++ b/drm/1.3/IDrmFactory.hal
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2019 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.drm@1.3;
+
+import @1.2::IDrmFactory;
+
+/**
+ * IDrmFactory is the main entry point for interacting with a vendor's
+ * drm HAL to create drm plugin instances. A drm plugin instance
+ * creates drm sessions which are used to obtain keys for a crypto
+ * session so it can decrypt protected video content.
+ *
+ * The 1.3 factory must always create 1.2 IDrmPlugin interfaces, which are
+ * returned via the 1.0 createPlugin method.
+ */
+
+interface IDrmFactory extends @1.2::IDrmFactory {
+ /**
+ * Return vector of uuids identifying crypto schemes supported by this HAL.
+ *
+ * @return schemes Vector of uuids for which isCryptoSchemeSupported is true;
+ * each uuid can be used as input to createPlugin.
+ */
+ getSupportedCryptoSchemes() generates(vec<uint8_t[16]> schemes);
+};
diff --git a/gatekeeper/1.0/vts/functional/Android.bp b/gatekeeper/1.0/vts/functional/Android.bp
index f55e5d2..a115285 100644
--- a/gatekeeper/1.0/vts/functional/Android.bp
+++ b/gatekeeper/1.0/vts/functional/Android.bp
@@ -19,5 +19,5 @@
defaults: ["VtsHalTargetTestDefaults"],
srcs: ["VtsHalGatekeeperV1_0TargetTest.cpp"],
static_libs: ["android.hardware.gatekeeper@1.0"],
- test_suites: ["general-tests"],
+ test_suites: ["general-tests", "vts-core"],
}
diff --git a/gatekeeper/1.0/vts/functional/VtsHalGatekeeperV1_0TargetTest.cpp b/gatekeeper/1.0/vts/functional/VtsHalGatekeeperV1_0TargetTest.cpp
index 715e9fc..afc737c 100644
--- a/gatekeeper/1.0/vts/functional/VtsHalGatekeeperV1_0TargetTest.cpp
+++ b/gatekeeper/1.0/vts/functional/VtsHalGatekeeperV1_0TargetTest.cpp
@@ -24,7 +24,10 @@
#include <inttypes.h>
#include <unistd.h>
+#include <gtest/gtest.h>
#include <hardware/hw_auth_token.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include <android/log.h>
#include <android/hardware/gatekeeper/1.0/IGatekeeper.h>
@@ -32,9 +35,6 @@
#include <log/log.h>
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
-
using ::android::hardware::hidl_string;
using ::android::hardware::hidl_vec;
using ::android::hardware::gatekeeper::V1_0::IGatekeeper;
@@ -78,22 +78,8 @@
return auth_token;
}
-// Test environment for Gatekeeper HIDL HAL.
-class GatekeeperHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static GatekeeperHidlEnvironment* Instance() {
- static GatekeeperHidlEnvironment* instance = new GatekeeperHidlEnvironment;
- return instance;
- }
-
- virtual void registerTestServices() override { registerTestService<IGatekeeper>(); }
- private:
- GatekeeperHidlEnvironment() {}
-};
-
// The main test class for Gatekeeper HIDL HAL.
-class GatekeeperHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+class GatekeeperHidlTest : public ::testing::TestWithParam<std::string> {
protected:
void setUid(uint32_t uid) { uid_ = uid; }
@@ -204,8 +190,7 @@
GatekeeperHidlTest() : uid_(0) {}
virtual void SetUp() override {
GatekeeperResponse rsp;
- gatekeeper_ = ::testing::VtsHalHidlTargetTestBase::getService<IGatekeeper>(
- GatekeeperHidlEnvironment::Instance()->getServiceName<IGatekeeper>());
+ gatekeeper_ = IGatekeeper::getService(GetParam());
ASSERT_NE(nullptr, gatekeeper_.get());
doDeleteAllUsers(rsp);
}
@@ -219,7 +204,7 @@
/**
* Ensure we can enroll new password
*/
-TEST_F(GatekeeperHidlTest, EnrollSuccess) {
+TEST_P(GatekeeperHidlTest, EnrollSuccess) {
hidl_vec<uint8_t> password;
GatekeeperResponse rsp;
ALOGI("Testing Enroll (expected success)");
@@ -231,7 +216,7 @@
/**
* Ensure we can not enroll empty password
*/
-TEST_F(GatekeeperHidlTest, EnrollNoPassword) {
+TEST_P(GatekeeperHidlTest, EnrollNoPassword) {
hidl_vec<uint8_t> password;
GatekeeperResponse rsp;
ALOGI("Testing Enroll (expected failure)");
@@ -242,7 +227,7 @@
/**
* Ensure we can successfully verify previously enrolled password
*/
-TEST_F(GatekeeperHidlTest, VerifySuccess) {
+TEST_P(GatekeeperHidlTest, VerifySuccess) {
GatekeeperResponse enrollRsp;
GatekeeperResponse verifyRsp;
hidl_vec<uint8_t> password;
@@ -258,7 +243,7 @@
* Ensure we can securely update password (keep the same
* secure user_id) if we prove we know old password
*/
-TEST_F(GatekeeperHidlTest, TrustedReenroll) {
+TEST_P(GatekeeperHidlTest, TrustedReenroll) {
GatekeeperResponse enrollRsp;
GatekeeperRequest reenrollReq;
GatekeeperResponse reenrollRsp;
@@ -297,7 +282,7 @@
* Ensure we can update password (and get new
* secure user_id) if we don't know old password
*/
-TEST_F(GatekeeperHidlTest, UntrustedReenroll) {
+TEST_P(GatekeeperHidlTest, UntrustedReenroll) {
GatekeeperResponse enrollRsp;
GatekeeperResponse reenrollRsp;
GatekeeperResponse verifyRsp;
@@ -327,7 +312,7 @@
/**
* Ensure we dont get successful verify with invalid data
*/
-TEST_F(GatekeeperHidlTest, VerifyNoData) {
+TEST_P(GatekeeperHidlTest, VerifyNoData) {
hidl_vec<uint8_t> password;
hidl_vec<uint8_t> passwordHandle;
GatekeeperResponse verifyRsp;
@@ -341,7 +326,7 @@
/**
* Ensure we can not verify password after we enrolled it and then deleted user
*/
-TEST_F(GatekeeperHidlTest, DeleteUserTest) {
+TEST_P(GatekeeperHidlTest, DeleteUserTest) {
hidl_vec<uint8_t> password;
GatekeeperResponse enrollRsp;
GatekeeperResponse verifyRsp;
@@ -368,7 +353,7 @@
/**
* Ensure we can not delete a user that does not exist
*/
-TEST_F(GatekeeperHidlTest, DeleteInvalidUserTest) {
+TEST_P(GatekeeperHidlTest, DeleteInvalidUserTest) {
hidl_vec<uint8_t> password;
GatekeeperResponse enrollRsp;
GatekeeperResponse verifyRsp;
@@ -400,7 +385,7 @@
* Ensure we can not verify passwords after we enrolled them and then deleted
* all users
*/
-TEST_F(GatekeeperHidlTest, DeleteAllUsersTest) {
+TEST_P(GatekeeperHidlTest, DeleteAllUsersTest) {
struct UserData {
uint32_t userId;
hidl_vec<uint8_t> password;
@@ -448,11 +433,7 @@
ALOGI("Testing deleteAllUsers done: rsp=%" PRIi32, delAllRsp.code);
}
-int main(int argc, char **argv) {
- ::testing::AddGlobalTestEnvironment(GatekeeperHidlEnvironment::Instance());
- ::testing::InitGoogleTest(&argc, argv);
- GatekeeperHidlEnvironment::Instance()->init(&argc, argv);
- int status = RUN_ALL_TESTS();
- ALOGI("Test result = %d", status);
- return status;
-}
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, GatekeeperHidlTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(IGatekeeper::descriptor)),
+ android::hardware::PrintInstanceNameToString);
diff --git a/gnss/1.0/vts/functional/VtsHalGnssV1_0TargetTest.cpp b/gnss/1.0/vts/functional/VtsHalGnssV1_0TargetTest.cpp
index 1a80ecf..6183a1a 100644
--- a/gnss/1.0/vts/functional/VtsHalGnssV1_0TargetTest.cpp
+++ b/gnss/1.0/vts/functional/VtsHalGnssV1_0TargetTest.cpp
@@ -22,6 +22,7 @@
#include <log/log.h>
#include <chrono>
+#include <cmath>
#include <condition_variable>
#include <mutex>
@@ -403,6 +404,34 @@
}
/*
+ * InjectSeedLocation:
+ * Injects a seed location and ensures the injected seed location is not fused in the resulting
+ * GNSS location.
+ */
+TEST_P(GnssHalTest, InjectSeedLocation) {
+ // An arbitrary position in North Pacific Ocean (where no VTS labs will ever likely be located).
+ const double seedLatDegrees = 32.312894;
+ const double seedLngDegrees = -172.954117;
+ const float seedAccuracyMeters = 150.0;
+
+ auto result = gnss_hal_->injectLocation(seedLatDegrees, seedLngDegrees, seedAccuracyMeters);
+ ASSERT_TRUE(result.isOk());
+ EXPECT_TRUE(result);
+
+ StartAndGetSingleLocation(false);
+
+ // Ensure we don't get a location anywhere within 111km (1 degree of lat or lng) of the seed
+ // location.
+ EXPECT_TRUE(std::abs(last_location_.latitudeDegrees - seedLatDegrees) > 1.0 ||
+ std::abs(last_location_.longitudeDegrees - seedLngDegrees) > 1.0);
+
+ StopAndClearLocations();
+
+ auto resultVoid = gnss_hal_->deleteAidingData(IGnss::GnssAidingData::DELETE_POSITION);
+ ASSERT_TRUE(resultVoid.isOk());
+}
+
+/*
* GetAllExtentions:
* Tries getting all optional extensions, and ensures a valid return
* null or actual extension, no crash.
diff --git a/gnss/1.1/default/Android.bp b/gnss/1.1/default/Android.bp
index 95bd7f3..9c498d5 100644
--- a/gnss/1.1/default/Android.bp
+++ b/gnss/1.1/default/Android.bp
@@ -14,6 +14,8 @@
"libhidlbase",
"libutils",
"liblog",
+ "android.hardware.gnss@2.1",
+ "android.hardware.gnss@2.0",
"android.hardware.gnss@1.1",
"android.hardware.gnss@1.0",
],
diff --git a/gnss/1.1/default/Gnss.cpp b/gnss/1.1/default/Gnss.cpp
index 4abe707..5043649 100644
--- a/gnss/1.1/default/Gnss.cpp
+++ b/gnss/1.1/default/Gnss.cpp
@@ -44,7 +44,7 @@
auto svStatus = this->getMockSvStatus();
this->reportSvStatus(svStatus);
- auto location = Utils::getMockLocation();
+ auto location = Utils::getMockLocationV1_0();
this->reportLocation(location);
std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMs));
@@ -197,14 +197,14 @@
Return<GnssSvStatus> Gnss::getMockSvStatus() const {
std::unique_lock<std::recursive_mutex> lock(mGnssConfiguration->getMutex());
GnssSvInfo mockGnssSvInfoList[] = {
- Utils::getSvInfo(3, GnssConstellationType::GPS, 32.5, 59.1, 166.5),
- Utils::getSvInfo(5, GnssConstellationType::GPS, 27.0, 29.0, 56.5),
- Utils::getSvInfo(17, GnssConstellationType::GPS, 30.5, 71.0, 77.0),
- Utils::getSvInfo(26, GnssConstellationType::GPS, 24.1, 28.0, 253.0),
- Utils::getSvInfo(5, GnssConstellationType::GLONASS, 20.5, 11.5, 116.0),
- Utils::getSvInfo(17, GnssConstellationType::GLONASS, 21.5, 28.5, 186.0),
- Utils::getSvInfo(18, GnssConstellationType::GLONASS, 28.3, 38.8, 69.0),
- Utils::getSvInfo(10, GnssConstellationType::GLONASS, 25.0, 66.0, 247.0)};
+ Utils::getMockSvInfoV1_0(3, GnssConstellationType::GPS, 32.5, 59.1, 166.5),
+ Utils::getMockSvInfoV1_0(5, GnssConstellationType::GPS, 27.0, 29.0, 56.5),
+ Utils::getMockSvInfoV1_0(17, GnssConstellationType::GPS, 30.5, 71.0, 77.0),
+ Utils::getMockSvInfoV1_0(26, GnssConstellationType::GPS, 24.1, 28.0, 253.0),
+ Utils::getMockSvInfoV1_0(5, GnssConstellationType::GLONASS, 20.5, 11.5, 116.0),
+ Utils::getMockSvInfoV1_0(17, GnssConstellationType::GLONASS, 21.5, 28.5, 186.0),
+ Utils::getMockSvInfoV1_0(18, GnssConstellationType::GLONASS, 28.3, 38.8, 69.0),
+ Utils::getMockSvInfoV1_0(10, GnssConstellationType::GLONASS, 25.0, 66.0, 247.0)};
GnssSvStatus svStatus = {.numSvs = sizeof(mockGnssSvInfoList) / sizeof(GnssSvInfo)};
for (uint32_t i = 0; i < svStatus.numSvs; i++) {
diff --git a/gnss/1.1/vts/functional/gnss_hal_test.cpp b/gnss/1.1/vts/functional/gnss_hal_test.cpp
index 2c8a7b1..88fbff8 100644
--- a/gnss/1.1/vts/functional/gnss_hal_test.cpp
+++ b/gnss/1.1/vts/functional/gnss_hal_test.cpp
@@ -172,7 +172,54 @@
hasGnssHalVersion_2_0 = registered.size() != 0;
});
- return hasGnssHalVersion_1_1 && !hasGnssHalVersion_2_0;
+ bool hasGnssHalVersion_2_1 = false;
+ manager->listManifestByInterface(
+ "android.hardware.gnss@2.1::IGnss",
+ [&hasGnssHalVersion_2_1](const hidl_vec<hidl_string>& registered) {
+ hasGnssHalVersion_2_1 = registered.size() != 0;
+ });
+
+ return hasGnssHalVersion_1_1 && !hasGnssHalVersion_2_0 && !hasGnssHalVersion_2_1;
+}
+
+GnssConstellationType GnssHalTest::startLocationAndGetNonGpsConstellation(
+ const int locations_to_await, const int gnss_sv_info_list_timeout) {
+ gnss_cb_->location_cbq_.reset();
+ StartAndCheckLocations(locations_to_await);
+ const int location_called_count = gnss_cb_->location_cbq_.calledCount();
+
+ // Tolerate 1 less sv status to handle edge cases in reporting.
+ int sv_status_cbq_size = gnss_cb_->sv_status_cbq_.size();
+ EXPECT_GE(sv_status_cbq_size + 1, locations_to_await);
+ ALOGD("Observed %d GnssSvStatus, while awaiting %d Locations (%d received)", sv_status_cbq_size,
+ locations_to_await, location_called_count);
+
+ // Find first non-GPS constellation to blacklist
+ GnssConstellationType constellation_to_blacklist = GnssConstellationType::UNKNOWN;
+ for (int i = 0; i < sv_status_cbq_size; ++i) {
+ IGnssCallback::GnssSvStatus gnss_sv_status;
+ gnss_cb_->sv_status_cbq_.retrieve(gnss_sv_status, gnss_sv_info_list_timeout);
+ for (uint32_t iSv = 0; iSv < gnss_sv_status.numSvs; iSv++) {
+ const auto& gnss_sv = gnss_sv_status.gnssSvList[iSv];
+ if ((gnss_sv.svFlag & IGnssCallback::GnssSvFlags::USED_IN_FIX) &&
+ (gnss_sv.constellation != GnssConstellationType::UNKNOWN) &&
+ (gnss_sv.constellation != GnssConstellationType::GPS)) {
+ // found a non-GPS constellation
+ constellation_to_blacklist = gnss_sv.constellation;
+ break;
+ }
+ }
+ if (constellation_to_blacklist != GnssConstellationType::UNKNOWN) {
+ break;
+ }
+ }
+
+ if (constellation_to_blacklist == GnssConstellationType::UNKNOWN) {
+ ALOGI("No non-GPS constellations found, constellation blacklist test less effective.");
+ // Proceed functionally to blacklist something.
+ constellation_to_blacklist = GnssConstellationType::GLONASS;
+ }
+ return constellation_to_blacklist;
}
GnssHalTest::GnssCallback::GnssCallback()
diff --git a/gnss/1.1/vts/functional/gnss_hal_test.h b/gnss/1.1/vts/functional/gnss_hal_test.h
index 169cd62..88b7723 100644
--- a/gnss/1.1/vts/functional/gnss_hal_test.h
+++ b/gnss/1.1/vts/functional/gnss_hal_test.h
@@ -28,6 +28,7 @@
using android::hardware::gnss::V1_0::GnssLocation;
using android::hardware::gnss::common::GnssCallbackEventQueue;
+using android::hardware::gnss::V1_0::GnssConstellationType;
using android::hardware::gnss::V1_0::GnssLocationFlags;
using android::hardware::gnss::V1_1::IGnss;
using android::hardware::gnss::V1_1::IGnssCallback;
@@ -139,6 +140,17 @@
*/
bool IsGnssHalVersion_1_1() const;
+ /*
+ * startLocationAndGetNonGpsConstellation:
+ * 1. Start location
+ * 2. Find and return first non-GPS constellation
+ *
+ * Note that location is not stopped in this method. The client should call
+ * StopAndClearLocations() after the call.
+ */
+ GnssConstellationType startLocationAndGetNonGpsConstellation(
+ const int locations_to_await, const int gnss_sv_info_list_timeout);
+
sp<IGnss> gnss_hal_; // GNSS HAL to call into
sp<GnssCallback> gnss_cb_; // Primary callback interface
};
diff --git a/gnss/1.1/vts/functional/gnss_hal_test_cases.cpp b/gnss/1.1/vts/functional/gnss_hal_test_cases.cpp
index 79da84a..e0d8b54 100644
--- a/gnss/1.1/vts/functional/gnss_hal_test_cases.cpp
+++ b/gnss/1.1/vts/functional/gnss_hal_test_cases.cpp
@@ -352,7 +352,7 @@
}
/*
- * BlacklistConstellation:
+ * BlacklistConstellationWithLocationOff:
*
* 1) Turns on location, waits for 3 locations, ensuring they are valid, and checks corresponding
* GnssStatus for any non-GPS constellations.
@@ -361,50 +361,22 @@
* GnssStatus does not use any constellation but GPS.
* 4a & b) Clean up by turning off location, and send in empty blacklist.
*/
-TEST_P(GnssHalTest, BlacklistConstellation) {
+TEST_P(GnssHalTest, BlacklistConstellationWithLocationOff) {
if (!IsGnssHalVersion_1_1()) {
ALOGI("Test BlacklistConstellation skipped. GNSS HAL version is greater than 1.1.");
return;
}
const int kLocationsToAwait = 3;
-
- gnss_cb_->location_cbq_.reset();
- StartAndCheckLocations(kLocationsToAwait);
- const int location_called_count = gnss_cb_->location_cbq_.calledCount();
-
- // Tolerate 1 less sv status to handle edge cases in reporting.
- int sv_status_cbq_size = gnss_cb_->sv_status_cbq_.size();
- EXPECT_GE(sv_status_cbq_size + 1, kLocationsToAwait);
- ALOGD("Observed %d GnssSvStatus, while awaiting %d Locations (%d received)", sv_status_cbq_size,
- kLocationsToAwait, location_called_count);
+ const int kGnssSvStatusTimeout = 2;
// Find first non-GPS constellation to blacklist
- const int kGnssSvStatusTimeout = 2;
- GnssConstellationType constellation_to_blacklist = GnssConstellationType::UNKNOWN;
- for (int i = 0; i < sv_status_cbq_size; ++i) {
- IGnssCallback::GnssSvStatus gnss_sv_status;
- gnss_cb_->sv_status_cbq_.retrieve(gnss_sv_status, kGnssSvStatusTimeout);
- for (uint32_t iSv = 0; iSv < gnss_sv_status.numSvs; iSv++) {
- const auto& gnss_sv = gnss_sv_status.gnssSvList[iSv];
- if ((gnss_sv.svFlag & IGnssCallback::GnssSvFlags::USED_IN_FIX) &&
- (gnss_sv.constellation != GnssConstellationType::UNKNOWN) &&
- (gnss_sv.constellation != GnssConstellationType::GPS)) {
- // found a non-GPS constellation
- constellation_to_blacklist = gnss_sv.constellation;
- break;
- }
- }
- if (constellation_to_blacklist != GnssConstellationType::UNKNOWN) {
- break;
- }
- }
+ GnssConstellationType constellation_to_blacklist =
+ startLocationAndGetNonGpsConstellation(kLocationsToAwait, kGnssSvStatusTimeout);
- if (constellation_to_blacklist == GnssConstellationType::UNKNOWN) {
- ALOGI("No non-GPS constellations found, constellation blacklist test less effective.");
- // Proceed functionally to blacklist something.
- constellation_to_blacklist = GnssConstellationType::GLONASS;
- }
+ // Turns off location
+ StopAndClearLocations();
+
IGnssConfiguration::BlacklistedSource source_to_blacklist;
source_to_blacklist.constellation = constellation_to_blacklist;
source_to_blacklist.svid = 0; // documented wildcard for all satellites in this constellation
@@ -418,6 +390,7 @@
sources.resize(1);
sources[0] = source_to_blacklist;
+ // setBlacklist when location is off.
auto result = gnss_configuration_hal->setBlacklist(sources);
ASSERT_TRUE(result.isOk());
EXPECT_TRUE(result);
@@ -429,7 +402,80 @@
StartAndCheckLocations(kLocationsToAwait);
// Tolerate 1 less sv status to handle edge cases in reporting.
- sv_status_cbq_size = gnss_cb_->sv_status_cbq_.size();
+ int sv_status_cbq_size = gnss_cb_->sv_status_cbq_.size();
+ EXPECT_GE(sv_status_cbq_size + 1, kLocationsToAwait);
+ ALOGD("Observed %d GnssSvStatus, while awaiting %d Locations", sv_status_cbq_size,
+ kLocationsToAwait);
+ for (int i = 0; i < sv_status_cbq_size; ++i) {
+ IGnssCallback::GnssSvStatus gnss_sv_status;
+ gnss_cb_->sv_status_cbq_.retrieve(gnss_sv_status, kGnssSvStatusTimeout);
+ for (uint32_t iSv = 0; iSv < gnss_sv_status.numSvs; iSv++) {
+ const auto& gnss_sv = gnss_sv_status.gnssSvList[iSv];
+ EXPECT_FALSE((gnss_sv.constellation == source_to_blacklist.constellation) &&
+ (gnss_sv.svFlag & IGnssCallback::GnssSvFlags::USED_IN_FIX));
+ }
+ }
+
+ // clean up
+ StopAndClearLocations();
+ sources.resize(0);
+ result = gnss_configuration_hal->setBlacklist(sources);
+ ASSERT_TRUE(result.isOk());
+ EXPECT_TRUE(result);
+}
+
+/*
+ * BlacklistConstellationWithLocationOn:
+ *
+ * 1) Turns on location, waits for 3 locations, ensuring they are valid, and checks corresponding
+ * GnssStatus for any non-GPS constellations.
+ * 2a & b) Blacklist first non-GPS constellation, and turn off location.
+ * 3) Restart location, wait for 3 locations, ensuring they are valid, and checks corresponding
+ * GnssStatus does not use any constellation but GPS.
+ * 4a & b) Clean up by turning off location, and send in empty blacklist.
+ */
+TEST_P(GnssHalTest, BlacklistConstellationWithLocationOn) {
+ if (!IsGnssHalVersion_1_1()) {
+ ALOGI("Test BlacklistConstellation skipped. GNSS HAL version is greater than 1.1.");
+ return;
+ }
+
+ const int kLocationsToAwait = 3;
+ const int kGnssSvStatusTimeout = 2;
+
+ // Find first non-GPS constellation to blacklist
+ GnssConstellationType constellation_to_blacklist =
+ startLocationAndGetNonGpsConstellation(kLocationsToAwait, kGnssSvStatusTimeout);
+
+ IGnssConfiguration::BlacklistedSource source_to_blacklist;
+ source_to_blacklist.constellation = constellation_to_blacklist;
+ source_to_blacklist.svid = 0; // documented wildcard for all satellites in this constellation
+
+ auto gnss_configuration_hal_return = gnss_hal_->getExtensionGnssConfiguration_1_1();
+ ASSERT_TRUE(gnss_configuration_hal_return.isOk());
+ sp<IGnssConfiguration> gnss_configuration_hal = gnss_configuration_hal_return;
+ ASSERT_NE(gnss_configuration_hal, nullptr);
+
+ hidl_vec<IGnssConfiguration::BlacklistedSource> sources;
+ sources.resize(1);
+ sources[0] = source_to_blacklist;
+
+ // setBlacklist when location is still on
+ auto result = gnss_configuration_hal->setBlacklist(sources);
+ ASSERT_TRUE(result.isOk());
+ EXPECT_TRUE(result);
+
+ // Turns off location
+ StopAndClearLocations();
+
+ // retry and ensure constellation not used
+ gnss_cb_->sv_status_cbq_.reset();
+
+ gnss_cb_->location_cbq_.reset();
+ StartAndCheckLocations(kLocationsToAwait);
+
+ // Tolerate 1 less sv status to handle edge cases in reporting.
+ int sv_status_cbq_size = gnss_cb_->sv_status_cbq_.size();
EXPECT_GE(sv_status_cbq_size + 1, kLocationsToAwait);
ALOGD("Observed %d GnssSvStatus, while awaiting %d Locations", sv_status_cbq_size,
kLocationsToAwait);
diff --git a/gnss/2.0/default/Android.bp b/gnss/2.0/default/Android.bp
index 3ba89da..37de55d 100644
--- a/gnss/2.0/default/Android.bp
+++ b/gnss/2.0/default/Android.bp
@@ -25,7 +25,7 @@
"AGnss.cpp",
"AGnssRil.cpp",
"Gnss.cpp",
- "GnssBatching.cpp",
+ "GnssBatching.cpp",
"GnssMeasurement.cpp",
"GnssMeasurementCorrections.cpp",
"GnssVisibilityControl.cpp",
@@ -35,9 +35,10 @@
"libhidlbase",
"libutils",
"liblog",
- "android.hardware.gnss@2.0",
"android.hardware.gnss.measurement_corrections@1.0",
"android.hardware.gnss.visibility_control@1.0",
+ "android.hardware.gnss@2.1",
+ "android.hardware.gnss@2.0",
"android.hardware.gnss@1.0",
"android.hardware.gnss@1.1",
],
diff --git a/gnss/2.0/default/Gnss.cpp b/gnss/2.0/default/Gnss.cpp
index 3d64fc3..09f2fc0 100644
--- a/gnss/2.0/default/Gnss.cpp
+++ b/gnss/2.0/default/Gnss.cpp
@@ -19,7 +19,6 @@
#include "Gnss.h"
#include <log/log.h>
-#include <utils/SystemClock.h>
#include "AGnss.h"
#include "AGnssRil.h"
@@ -47,24 +46,6 @@
sp<V2_0::IGnssCallback> Gnss::sGnssCallback_2_0 = nullptr;
sp<V1_1::IGnssCallback> Gnss::sGnssCallback_1_1 = nullptr;
-namespace {
-
-V2_0::GnssLocation getMockLocationV2_0() {
- const ElapsedRealtime timestamp = {
- .flags = ElapsedRealtimeFlags::HAS_TIMESTAMP_NS |
- ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS,
- .timestampNs = static_cast<uint64_t>(::android::elapsedRealtimeNano()),
- // This is an hardcoded value indicating a 1ms of uncertainty between the two clocks.
- // In an actual implementation provide an estimate of the synchronization uncertainty
- // or don't set the field.
- .timeUncertaintyNs = 1000000};
-
- V2_0::GnssLocation location = {.v1_0 = Utils::getMockLocation(), .elapsedRealtime = timestamp};
- return location;
-}
-
-} // namespace
-
Gnss::Gnss() : mMinIntervalMs(1000) {}
Gnss::~Gnss() {
@@ -86,7 +67,7 @@
mIsActive = true;
mThread = std::thread([this]() {
while (mIsActive == true) {
- const auto location = getMockLocationV2_0();
+ const auto location = Utils::getMockLocationV2_0();
this->reportLocation(location);
std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMs));
diff --git a/gnss/2.0/default/GnssMeasurement.cpp b/gnss/2.0/default/GnssMeasurement.cpp
index 1f95ff9..d778d50 100644
--- a/gnss/2.0/default/GnssMeasurement.cpp
+++ b/gnss/2.0/default/GnssMeasurement.cpp
@@ -16,6 +16,7 @@
#define LOG_TAG "GnssMeasurement"
#include "GnssMeasurement.h"
+#include "Utils.h"
#include <log/log.h>
#include <utils/SystemClock.h>
@@ -29,6 +30,7 @@
using GnssConstellationType = V2_0::GnssConstellationType;
using GnssMeasurementFlags = V1_0::IGnssMeasurementCallback::GnssMeasurementFlags;
using GnssMeasurementState = V2_0::IGnssMeasurementCallback::GnssMeasurementState;
+using Utils = common::Utils;
sp<V2_0::IGnssMeasurementCallback> GnssMeasurement::sCallback = nullptr;
@@ -81,7 +83,7 @@
mIsActive = true;
mThread = std::thread([this]() {
while (mIsActive == true) {
- auto measurement = this->getMockMeasurement();
+ auto measurement = Utils::getMockMeasurementV2_0();
this->reportMeasurement(measurement);
std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMillis));
@@ -97,60 +99,6 @@
}
}
-GnssData GnssMeasurement::getMockMeasurement() {
- V1_0::IGnssMeasurementCallback::GnssMeasurement measurement_1_0 = {
- .flags = (uint32_t)GnssMeasurementFlags::HAS_CARRIER_FREQUENCY,
- .svid = (int16_t)6,
- .constellation = V1_0::GnssConstellationType::UNKNOWN,
- .timeOffsetNs = 0.0,
- .receivedSvTimeInNs = 8195997131077,
- .receivedSvTimeUncertaintyInNs = 15,
- .cN0DbHz = 30.0,
- .pseudorangeRateMps = -484.13739013671875,
- .pseudorangeRateUncertaintyMps = 1.0379999876022339,
- .accumulatedDeltaRangeState = (uint32_t)V1_0::IGnssMeasurementCallback::
- GnssAccumulatedDeltaRangeState::ADR_STATE_UNKNOWN,
- .accumulatedDeltaRangeM = 0.0,
- .accumulatedDeltaRangeUncertaintyM = 0.0,
- .carrierFrequencyHz = 1.59975e+09,
- .multipathIndicator =
- V1_0::IGnssMeasurementCallback::GnssMultipathIndicator::INDICATOR_UNKNOWN};
- V1_1::IGnssMeasurementCallback::GnssMeasurement measurement_1_1 = {.v1_0 = measurement_1_0};
- V2_0::IGnssMeasurementCallback::GnssMeasurement measurement_2_0 = {
- .v1_1 = measurement_1_1,
- .codeType = "C",
- .state = GnssMeasurementState::STATE_CODE_LOCK | GnssMeasurementState::STATE_BIT_SYNC |
- GnssMeasurementState::STATE_SUBFRAME_SYNC |
- GnssMeasurementState::STATE_TOW_DECODED |
- GnssMeasurementState::STATE_GLO_STRING_SYNC |
- GnssMeasurementState::STATE_GLO_TOD_DECODED,
- .constellation = GnssConstellationType::GLONASS,
- };
-
- hidl_vec<IGnssMeasurementCallback::GnssMeasurement> measurements(1);
- measurements[0] = measurement_2_0;
- V1_0::IGnssMeasurementCallback::GnssClock clock = {.timeNs = 2713545000000,
- .fullBiasNs = -1226701900521857520,
- .biasNs = 0.59689998626708984,
- .biasUncertaintyNs = 47514.989972114563,
- .driftNsps = -51.757811607455452,
- .driftUncertaintyNsps = 310.64968328491528,
- .hwClockDiscontinuityCount = 1};
-
- ElapsedRealtime timestamp = {
- .flags = ElapsedRealtimeFlags::HAS_TIMESTAMP_NS |
- ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS,
- .timestampNs = static_cast<uint64_t>(::android::elapsedRealtimeNano()),
- // This is an hardcoded value indicating a 1ms of uncertainty between the two clocks.
- // In an actual implementation provide an estimate of the synchronization uncertainty
- // or don't set the field.
- .timeUncertaintyNs = 1000000};
-
- GnssData gnssData = {
- .measurements = measurements, .clock = clock, .elapsedRealtime = timestamp};
- return gnssData;
-}
-
void GnssMeasurement::reportMeasurement(const GnssData& data) {
ALOGD("reportMeasurement()");
std::unique_lock<std::mutex> lock(mMutex);
diff --git a/gnss/2.0/default/GnssMeasurement.h b/gnss/2.0/default/GnssMeasurement.h
index c24c00e..d8ffd59 100644
--- a/gnss/2.0/default/GnssMeasurement.h
+++ b/gnss/2.0/default/GnssMeasurement.h
@@ -59,7 +59,6 @@
private:
void start();
void stop();
- GnssData getMockMeasurement();
void reportMeasurement(const GnssData&);
static sp<IGnssMeasurementCallback> sCallback;
diff --git a/gnss/2.0/vts/functional/Android.bp b/gnss/2.0/vts/functional/Android.bp
index 9aa1334..da5289d 100644
--- a/gnss/2.0/vts/functional/Android.bp
+++ b/gnss/2.0/vts/functional/Android.bp
@@ -28,6 +28,7 @@
"android.hardware.gnss@1.0",
"android.hardware.gnss@1.1",
"android.hardware.gnss@2.0",
+ "android.hardware.gnss@2.1",
"android.hardware.gnss@common-vts-lib",
],
test_suites: ["general-tests", "vts-core"],
diff --git a/gnss/2.0/vts/functional/gnss_hal_test.cpp b/gnss/2.0/vts/functional/gnss_hal_test.cpp
index 8ca3f68..b3a3203 100644
--- a/gnss/2.0/vts/functional/gnss_hal_test.cpp
+++ b/gnss/2.0/vts/functional/gnss_hal_test.cpp
@@ -16,11 +16,14 @@
#define LOG_TAG "GnssHalTest"
+#include <android/hidl/manager/1.2/IServiceManager.h>
#include <gnss_hal_test.h>
+#include <gtest/gtest.h>
+#include <hidl/ServiceManagement.h>
#include <chrono>
#include "Utils.h"
-#include <gtest/gtest.h>
+using ::android::hardware::hidl_string;
using ::android::hardware::gnss::common::Utils;
@@ -99,7 +102,6 @@
EXPECT_TRUE(result.isOk());
EXPECT_TRUE(result);
-
/*
* GnssLocationProvider support of AGPS SUPL & XtraDownloader is not available in VTS,
* so allow time to demodulate ephemeris over the air.
@@ -148,6 +150,27 @@
}
}
+bool GnssHalTest::IsGnssHalVersion_2_0() const {
+ using ::android::hidl::manager::V1_2::IServiceManager;
+ sp<IServiceManager> manager = ::android::hardware::defaultServiceManager1_2();
+
+ bool hasGnssHalVersion_2_0 = false;
+ manager->listManifestByInterface(
+ "android.hardware.gnss@2.0::IGnss",
+ [&hasGnssHalVersion_2_0](const hidl_vec<hidl_string>& registered) {
+ hasGnssHalVersion_2_0 = registered.size() != 0;
+ });
+
+ bool hasGnssHalVersion_2_1 = false;
+ manager->listManifestByInterface(
+ "android.hardware.gnss@2.1::IGnss",
+ [&hasGnssHalVersion_2_1](const hidl_vec<hidl_string>& registered) {
+ hasGnssHalVersion_2_1 = registered.size() != 0;
+ });
+
+ return hasGnssHalVersion_2_0 && !hasGnssHalVersion_2_1;
+}
+
GnssHalTest::GnssCallback::GnssCallback()
: info_cbq_("system_info"),
name_cbq_("name"),
diff --git a/gnss/2.0/vts/functional/gnss_hal_test.h b/gnss/2.0/vts/functional/gnss_hal_test.h
index 4f7b87a..55dc1bc 100644
--- a/gnss/2.0/vts/functional/gnss_hal_test.h
+++ b/gnss/2.0/vts/functional/gnss_hal_test.h
@@ -181,6 +181,12 @@
void StopAndClearLocations();
/*
+ * IsGnssHalVersion_2_0:
+ * returns true if the GNSS HAL version is exactly 2.0.
+ */
+ bool IsGnssHalVersion_2_0() const;
+
+ /*
* SetPositionMode:
* Helper function to set positioning mode and verify output
*/
diff --git a/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp b/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp
index c442cc6..0fa08b9 100644
--- a/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp
+++ b/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp
@@ -182,6 +182,10 @@
* 3. state is valid.
*/
TEST_P(GnssHalTest, TestGnssMeasurementFields) {
+ if (!IsGnssHalVersion_2_0()) {
+ ALOGI("Test GnssMeasurementFields skipped. GNSS HAL version is greater than 2.0.");
+ return;
+ }
const int kFirstGnssMeasurementTimeoutSeconds = 10;
auto gnssMeasurement = gnss_hal_->getExtensionGnssMeasurement_2_0();
@@ -464,7 +468,7 @@
}
EXPECT_LE(location_called_count, i);
if (location_called_count != i) {
- ALOGW("GetLocationLowPower test - not enough locations received. %d vs. %d expected ",
+ ALOGW("GetLocationLowPower test - too many locations received. %d vs. %d expected ",
location_called_count, i);
}
@@ -601,6 +605,11 @@
* formerly strongest satellite
*/
TEST_P(GnssHalTest, BlacklistIndividualSatellites) {
+ if (!IsGnssHalVersion_2_0()) {
+ ALOGI("Test BlacklistIndividualSatellites skipped. GNSS HAL version is greater than 2.0.");
+ return;
+ }
+
if (!(gnss_cb_->last_capabilities_ & IGnssCallback::Capabilities::SATELLITE_BLACKLIST)) {
ALOGI("Test BlacklistIndividualSatellites skipped. SATELLITE_BLACKLIST capability"
" not supported.");
@@ -746,6 +755,11 @@
* 4a & b) Clean up by turning off location, and send in empty blacklist.
*/
TEST_P(GnssHalTest, BlacklistConstellation) {
+ if (!IsGnssHalVersion_2_0()) {
+ ALOGI("Test BlacklistConstellation skipped. GNSS HAL version is greater than 2.0.");
+ return;
+ }
+
if (!(gnss_cb_->last_capabilities_ & IGnssCallback::Capabilities::SATELLITE_BLACKLIST)) {
ALOGI("Test BlacklistConstellation skipped. SATELLITE_BLACKLIST capability not supported.");
return;
diff --git a/gnss/2.1/Android.bp b/gnss/2.1/Android.bp
new file mode 100644
index 0000000..8b0c374
--- /dev/null
+++ b/gnss/2.1/Android.bp
@@ -0,0 +1,25 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+hidl_interface {
+ name: "android.hardware.gnss@2.1",
+ root: "android.hardware",
+ vndk: {
+ enabled: true,
+ },
+ srcs: [
+ "IGnss.hal",
+ "IGnssCallback.hal",
+ "IGnssMeasurement.hal",
+ "IGnssMeasurementCallback.hal",
+ "IGnssConfiguration.hal",
+ ],
+ interfaces: [
+ "android.hardware.gnss.measurement_corrections@1.0",
+ "android.hardware.gnss.visibility_control@1.0",
+ "android.hardware.gnss@1.0",
+ "android.hardware.gnss@1.1",
+ "android.hardware.gnss@2.0",
+ "android.hidl.base@1.0",
+ ],
+ gen_java: true,
+}
diff --git a/gnss/2.1/IGnss.hal b/gnss/2.1/IGnss.hal
new file mode 100644
index 0000000..2d63392
--- /dev/null
+++ b/gnss/2.1/IGnss.hal
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2019 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.gnss@2.1;
+
+import @2.0::IGnss;
+
+import IGnssCallback;
+import IGnssMeasurement;
+import IGnssConfiguration;
+
+/**
+ * Represents the standard GNSS (Global Navigation Satellite System) interface.
+ */
+interface IGnss extends @2.0::IGnss {
+ /**
+ * Opens the interface and provides the callback routines to the implementation of this
+ * interface.
+ *
+ * The framework calls this method to instruct the GPS engine to prepare for serving requests
+ * from the framework. The GNSS HAL implementation must respond to all GNSS requests from the
+ * framework upon successful return from this method until cleanup() method is called to
+ * close this interface.
+ *
+ * @param callback Callback interface for IGnss.
+ *
+ * @return success Returns true on success.
+ */
+ setCallback_2_1(IGnssCallback callback) generates (bool success);
+
+ /**
+ * This method returns the IGnssMeasurement interface.
+ *
+ * At least one of getExtensionGnssMeasurement(), getExtensionGnssMeasurement_1_1(),
+ * getExtensionGnssMeasurement_2_0(), and getExtensionGnssMeasurement_2_1() methods must return
+ * a non-null handle, and the other methods must return nullptr.
+ *
+ * @return gnssMeasurementIface Handle to the IGnssMeasurement interface.
+ */
+ getExtensionGnssMeasurement_2_1() generates (IGnssMeasurement gnssMeasurementIface);
+
+ /**
+ * This method returns the IGnssConfiguration interface.
+ *
+ * At least one of getExtensionGnssConfiguration(), getExtensionGnssConfiguration_1_1(),
+ * getExtensionGnssConfiguration_2_0(), and getExtensionGnssConfiguration_2_1() methods must
+ * return a non-null handle, and the other methods must return nullptr.
+ *
+ * @return gnssConfigurationIface Handle to the IGnssConfiguration interface.
+ */
+ getExtensionGnssConfiguration_2_1() generates (IGnssConfiguration gnssConfigurationIface);
+};
\ No newline at end of file
diff --git a/gnss/2.1/IGnssCallback.hal b/gnss/2.1/IGnssCallback.hal
new file mode 100644
index 0000000..da70742
--- /dev/null
+++ b/gnss/2.1/IGnssCallback.hal
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2019 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.gnss@2.1;
+
+import @2.0::IGnssCallback;
+
+/**
+ * This interface is required for the HAL to communicate certain information
+ * like status and location info back to the platform, the platform implements
+ * the interfaces and passes a handle to the HAL.
+ */
+interface IGnssCallback extends @2.0::IGnssCallback {
+
+ /** Extends a GnssSvInfo, adding a basebandCN0DbHz. */
+ struct GnssSvInfo {
+ /**
+ * GNSS satellite information for a single satellite and frequency.
+ */
+ @2.0::IGnssCallback.GnssSvInfo v2_0;
+
+ /**
+ * Baseband Carrier-to-noise density in dB-Hz, typically in the range [0, 63]. It contains
+ * the measured C/N0 value for the signal measured at the baseband.
+ *
+ * This is typically a few dB weaker than the value estimated for C/N0 at the antenna port,
+ * which is reported in cN0DbHz.
+ *
+ * If a signal has separate components (e.g. Pilot and Data channels) and the receiver only
+ * processes one of the components, then the reported basebandCN0DbHz reflects only the
+ * component that is processed.
+ *
+ * This value is mandatory. Like cN0DbHz, it may be reported as 0 for satellites being
+ * reported that may be searched for, but not yet tracked.
+ */
+ double basebandCN0DbHz;
+ };
+
+ /**
+ * Callback for the HAL to pass a vector of GnssSvInfo back to the client.
+ *
+ * @param svInfoList SV info list information from HAL.
+ */
+ gnssSvStatusCb_2_1(vec<GnssSvInfo> svInfoList);
+};
diff --git a/gnss/2.1/IGnssConfiguration.hal b/gnss/2.1/IGnssConfiguration.hal
new file mode 100644
index 0000000..8360ba9
--- /dev/null
+++ b/gnss/2.1/IGnssConfiguration.hal
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2019 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.gnss@2.1;
+
+import @2.0::IGnssConfiguration;
+import @2.0::GnssConstellationType;
+
+/**
+ * Extended interface for GNSS Configuration support.
+ */
+interface IGnssConfiguration extends @2.0::IGnssConfiguration {
+ /**
+ * Represents a blacklisted source, updating the GnssConstellationType to 2.0, which supports
+ * IRNSS.
+ */
+ struct BlacklistedSource {
+ /**
+ * Defines the constellation of the given satellite(s).
+ */
+ GnssConstellationType constellation;
+
+ /**
+ * Satellite (space vehicle) ID number, as defined in GnssSvInfo::svid
+ *
+ * Or 0 to blacklist all svid's for the specified constellation
+ */
+ int16_t svid;
+ };
+
+ /**
+ * Injects a vector of BlacklistedSource(s) which the HAL must not use to calculate the
+ * GNSS location output.
+ *
+ * The superset of all satellite sources provided, including wildcards, in the latest call
+ * to this method, is the set of satellites sources that must not be used in calculating
+ * location.
+ *
+ * All measurements from the specified satellites, across frequency bands, are blacklisted
+ * together.
+ *
+ * If this method is never called after the IGnssConfiguration.hal connection is made on boot,
+ * or is called with an empty vector, then no satellites are to be blacklisted as a result of
+ * this API.
+ *
+ * This blacklist must be considered as an additional source of which satellites
+ * should not be trusted for location on top of existing sources of similar information
+ * such as satellite broadcast health being unhealthy and measurement outlier removal.
+ *
+ * @param blacklist The BlacklistedSource(s) of satellites the HAL must not use.
+ *
+ * @return success Whether the HAL accepts and abides by the provided blacklist.
+ */
+ setBlacklist_2_1(vec<BlacklistedSource> blacklist) generates (bool success);
+};
\ No newline at end of file
diff --git a/gnss/2.1/IGnssMeasurement.hal b/gnss/2.1/IGnssMeasurement.hal
new file mode 100644
index 0000000..d2c76e6
--- /dev/null
+++ b/gnss/2.1/IGnssMeasurement.hal
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2019 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.gnss@2.1;
+
+import @1.0::IGnssMeasurement;
+import @1.1::IGnssMeasurement;
+import @2.0::IGnssMeasurement;
+import IGnssMeasurementCallback;
+
+/**
+ * Extended interface for GNSS Measurements support.
+ */
+interface IGnssMeasurement extends @2.0::IGnssMeasurement {
+
+ /**
+ * Initializes the interface and registers the callback routines with the HAL. After a
+ * successful call to 'setCallback_2_1' the HAL must begin to provide updates at an average
+ * output rate of 1Hz (occasional intra-measurement time offsets in the range from 0-2000msec
+ * can be tolerated.)
+ *
+ * @param callback Handle to GnssMeasurement callback interface.
+ * @param enableFullTracking If true, GNSS chipset must switch off duty cycling. In such mode
+ * no clock discontinuities are expected and, when supported, carrier phase should be
+ * continuous in good signal conditions. All non-blacklisted, healthy constellations,
+ * satellites and frequency bands that the chipset supports must be reported in this mode.
+ * The GNSS chipset is allowed to consume more power in this mode. If false, API must behave
+ * as in HAL V1_0, optimizing power via duty cycling, constellations and frequency limits,
+ * etc.
+ *
+ * @return initRet Returns SUCCESS if successful. Returns ERROR_ALREADY_INIT if a callback has
+ * already been registered without a corresponding call to 'close'. Returns ERROR_GENERIC
+ * for any other error. The HAL must not generate any other updates upon returning this
+ * error code.
+ */
+ setCallback_2_1(IGnssMeasurementCallback callback, bool enableFullTracking)
+ generates (GnssMeasurementStatus initRet);
+};
diff --git a/gnss/2.1/IGnssMeasurementCallback.hal b/gnss/2.1/IGnssMeasurementCallback.hal
new file mode 100644
index 0000000..ca6175f
--- /dev/null
+++ b/gnss/2.1/IGnssMeasurementCallback.hal
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2019 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.gnss@2.1;
+
+import @1.0::IGnssMeasurementCallback;
+import @1.1::IGnssMeasurementCallback;
+import @2.0::IGnssMeasurementCallback;
+import @2.0::ElapsedRealtime;
+
+/** The callback interface to report measurements from the HAL. */
+interface IGnssMeasurementCallback extends @2.0::IGnssMeasurementCallback {
+
+ /**
+ * Extends a GNSS Measurement, adding a basebandCN0DbHz.
+ */
+ struct GnssMeasurement {
+ /**
+ * GNSS measurement information for a single satellite and frequency, as in the 2.0 version
+ * of the HAL.
+ */
+ @2.0::IGnssMeasurementCallback.GnssMeasurement v2_0;
+
+ /**
+ * Baseband Carrier-to-noise density in dB-Hz, typically in the range [0, 63]. It contains
+ * the measured C/N0 value for the signal measured at the baseband.
+ *
+ * This is typically a few dB weaker than the value estimated for C/N0 at the antenna port,
+ * which is reported in cN0DbHz.
+ *
+ * If a signal has separate components (e.g. Pilot and Data channels) and the receiver only
+ * processes one of the components, then the reported basebandCN0DbHz reflects only the
+ * component that is processed.
+ *
+ * This value is mandatory.
+ */
+ double basebandCN0DbHz;
+ };
+
+ /**
+ * Complete set of GNSS Measurement data, same as 2.0 with additional double (i.e.,
+ * basebandCN0DbHz) in measurements.
+ */
+ struct GnssData {
+ /** The full set of satellite measurement observations. */
+ vec<GnssMeasurement> measurements;
+
+ /** The GNSS clock time reading. */
+ GnssClock clock;
+
+ /**
+ * Timing information of the GNSS data synchronized with SystemClock.elapsedRealtimeNanos()
+ * clock.
+ */
+ ElapsedRealtime elapsedRealtime;
+ };
+
+ /**
+ * Callback for the hal to pass a GnssData structure back to the client.
+ *
+ * @param data Contains a reading of GNSS measurements.
+ */
+ gnssMeasurementCb_2_1(GnssData data);
+};
diff --git a/gnss/2.1/default/Android.bp b/gnss/2.1/default/Android.bp
new file mode 100644
index 0000000..7ef9990
--- /dev/null
+++ b/gnss/2.1/default/Android.bp
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+cc_binary {
+ name: "android.hardware.gnss@2.1-service",
+ init_rc: ["android.hardware.gnss@2.1-service.rc"],
+ relative_install_path: "hw",
+ vendor: true,
+ vintf_fragments: ["android.hardware.gnss@2.1-service.xml"],
+ srcs: [
+ "Gnss.cpp",
+ "GnssMeasurement.cpp",
+ "GnssMeasurementCorrections.cpp",
+ "GnssConfiguration.cpp",
+ "service.cpp",
+ ],
+ shared_libs: [
+ "libhidlbase",
+ "libutils",
+ "liblog",
+ "android.hardware.gnss.measurement_corrections@1.0",
+ "android.hardware.gnss.visibility_control@1.0",
+ "android.hardware.gnss@2.1",
+ "android.hardware.gnss@1.0",
+ "android.hardware.gnss@1.1",
+ "android.hardware.gnss@2.0",
+ ],
+ static_libs: [
+ "android.hardware.gnss@common-default-lib",
+ ],
+}
diff --git a/gnss/2.1/default/Gnss.cpp b/gnss/2.1/default/Gnss.cpp
new file mode 100644
index 0000000..6b61a82
--- /dev/null
+++ b/gnss/2.1/default/Gnss.cpp
@@ -0,0 +1,358 @@
+/*
+ * Copyright (C) 2019 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 "Gnss"
+
+#include "Gnss.h"
+#include "GnssMeasurement.h"
+#include "GnssMeasurementCorrections.h"
+#include "Utils.h"
+
+#include <log/log.h>
+
+using ::android::hardware::gnss::common::Utils;
+using ::android::hardware::gnss::measurement_corrections::V1_0::implementation::
+ GnssMeasurementCorrections;
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_1 {
+namespace implementation {
+
+sp<V2_1::IGnssCallback> Gnss::sGnssCallback_2_1 = nullptr;
+sp<V2_0::IGnssCallback> Gnss::sGnssCallback_2_0 = nullptr;
+
+Gnss::Gnss() : mMinIntervalMs(1000), mGnssConfiguration{new GnssConfiguration()} {}
+
+Gnss::~Gnss() {
+ stop();
+}
+
+Return<bool> Gnss::start() {
+ ALOGD("start");
+ if (mIsActive) {
+ ALOGW("Gnss has started. Restarting...");
+ stop();
+ }
+
+ mIsActive = true;
+ mThread = std::thread([this]() {
+ while (mIsActive == true) {
+ auto svStatus = filterBlacklistedSatellitesV2_1(Utils::getMockSvInfoListV2_1());
+ this->reportSvStatus(svStatus);
+
+ const auto location = Utils::getMockLocationV2_0();
+ this->reportLocation(location);
+
+ std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMs));
+ }
+ });
+ return true;
+}
+
+hidl_vec<GnssSvInfo> Gnss::filterBlacklistedSatellitesV2_1(hidl_vec<GnssSvInfo> gnssSvInfoList) {
+ for (uint32_t i = 0; i < gnssSvInfoList.size(); i++) {
+ if (mGnssConfiguration->isBlacklistedV2_1(gnssSvInfoList[i])) {
+ gnssSvInfoList[i].v2_0.v1_0.svFlag &=
+ ~static_cast<uint8_t>(V1_0::IGnssCallback::GnssSvFlags::USED_IN_FIX);
+ }
+ }
+ return gnssSvInfoList;
+}
+
+Return<bool> Gnss::stop() {
+ ALOGD("stop");
+ mIsActive = false;
+ if (mThread.joinable()) {
+ mThread.join();
+ }
+ return true;
+}
+
+// Methods from V1_0::IGnss follow.
+Return<bool> Gnss::setCallback(const sp<V1_0::IGnssCallback>&) {
+ // TODO implement
+ return bool{};
+}
+
+Return<void> Gnss::cleanup() {
+ sGnssCallback_2_1 = nullptr;
+ sGnssCallback_2_0 = nullptr;
+ return Void();
+}
+
+Return<bool> Gnss::injectTime(int64_t, int64_t, int32_t) {
+ // TODO implement
+ return bool{};
+}
+
+Return<bool> Gnss::injectLocation(double, double, float) {
+ // TODO implement
+ return bool{};
+}
+
+Return<void> Gnss::deleteAidingData(V1_0::IGnss::GnssAidingData) {
+ // TODO implement
+ return Void();
+}
+
+Return<bool> Gnss::setPositionMode(V1_0::IGnss::GnssPositionMode,
+ V1_0::IGnss::GnssPositionRecurrence, uint32_t, uint32_t,
+ uint32_t) {
+ // TODO implement
+ return bool{};
+}
+
+Return<sp<V1_0::IAGnssRil>> Gnss::getExtensionAGnssRil() {
+ // TODO implement
+ return ::android::sp<V1_0::IAGnssRil>{};
+}
+
+Return<sp<V1_0::IGnssGeofencing>> Gnss::getExtensionGnssGeofencing() {
+ // TODO implement
+ return ::android::sp<V1_0::IGnssGeofencing>{};
+}
+
+Return<sp<V1_0::IAGnss>> Gnss::getExtensionAGnss() {
+ // TODO implement
+ return ::android::sp<V1_0::IAGnss>{};
+}
+
+Return<sp<V1_0::IGnssNi>> Gnss::getExtensionGnssNi() {
+ // TODO implement
+ return ::android::sp<V1_0::IGnssNi>{};
+}
+
+Return<sp<V1_0::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement() {
+ // TODO implement
+ return ::android::sp<V1_0::IGnssMeasurement>{};
+}
+
+Return<sp<V1_0::IGnssNavigationMessage>> Gnss::getExtensionGnssNavigationMessage() {
+ // TODO implement
+ return ::android::sp<V1_0::IGnssNavigationMessage>{};
+}
+
+Return<sp<V1_0::IGnssXtra>> Gnss::getExtensionXtra() {
+ // TODO implement
+ return ::android::sp<V1_0::IGnssXtra>{};
+}
+
+Return<sp<V1_0::IGnssConfiguration>> Gnss::getExtensionGnssConfiguration() {
+ // TODO implement
+ return ::android::sp<V1_0::IGnssConfiguration>{};
+}
+
+Return<sp<V1_0::IGnssDebug>> Gnss::getExtensionGnssDebug() {
+ // TODO implement
+ return ::android::sp<V1_0::IGnssDebug>{};
+}
+
+Return<sp<V1_0::IGnssBatching>> Gnss::getExtensionGnssBatching() {
+ // TODO implement
+ return ::android::sp<V1_0::IGnssBatching>{};
+}
+
+// Methods from V1_1::IGnss follow.
+Return<bool> Gnss::setCallback_1_1(const sp<V1_1::IGnssCallback>&) {
+ // TODO implement
+ return bool{};
+}
+
+Return<bool> Gnss::setPositionMode_1_1(V1_0::IGnss::GnssPositionMode,
+ V1_0::IGnss::GnssPositionRecurrence, uint32_t minIntervalMs,
+ uint32_t, uint32_t, bool) {
+ mMinIntervalMs = minIntervalMs;
+ return true;
+}
+
+Return<sp<V1_1::IGnssConfiguration>> Gnss::getExtensionGnssConfiguration_1_1() {
+ // TODO implement
+ return ::android::sp<V1_1::IGnssConfiguration>{};
+}
+
+Return<sp<V1_1::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement_1_1() {
+ // TODO implement
+ return ::android::sp<V1_1::IGnssMeasurement>{};
+}
+
+Return<bool> Gnss::injectBestLocation(const V1_0::GnssLocation&) {
+ // TODO implement
+ return bool{};
+}
+
+// Methods from V2_0::IGnss follow.
+Return<bool> Gnss::setCallback_2_0(const sp<V2_0::IGnssCallback>& callback) {
+ ALOGD("Gnss::setCallback_2_0");
+ if (callback == nullptr) {
+ ALOGE("%s: Null callback ignored", __func__);
+ return false;
+ }
+
+ sGnssCallback_2_0 = callback;
+
+ using Capabilities = V2_0::IGnssCallback::Capabilities;
+ const auto capabilities = Capabilities::MEASUREMENTS | Capabilities::MEASUREMENT_CORRECTIONS |
+ Capabilities::LOW_POWER_MODE | Capabilities::SATELLITE_BLACKLIST;
+ auto ret = sGnssCallback_2_0->gnssSetCapabilitiesCb_2_0(capabilities);
+ if (!ret.isOk()) {
+ ALOGE("%s: Unable to invoke callback", __func__);
+ }
+
+ V1_1::IGnssCallback::GnssSystemInfo gnssInfo = {.yearOfHw = 2019};
+
+ ret = sGnssCallback_2_0->gnssSetSystemInfoCb(gnssInfo);
+ if (!ret.isOk()) {
+ ALOGE("%s: Unable to invoke callback", __func__);
+ }
+
+ auto gnssName = "Google Mock GNSS Implementation v2.1";
+ ret = sGnssCallback_2_0->gnssNameCb(gnssName);
+ if (!ret.isOk()) {
+ ALOGE("%s: Unable to invoke callback", __func__);
+ }
+
+ return true;
+}
+
+Return<sp<V2_0::IGnssConfiguration>> Gnss::getExtensionGnssConfiguration_2_0() {
+ ALOGD("Gnss::getExtensionGnssConfiguration_2_0");
+ return mGnssConfiguration;
+}
+
+Return<sp<V2_0::IGnssDebug>> Gnss::getExtensionGnssDebug_2_0() {
+ // TODO implement
+ return ::android::sp<V2_0::IGnssDebug>{};
+}
+
+Return<sp<V2_0::IAGnss>> Gnss::getExtensionAGnss_2_0() {
+ // TODO implement
+ return ::android::sp<V2_0::IAGnss>{};
+}
+
+Return<sp<V2_0::IAGnssRil>> Gnss::getExtensionAGnssRil_2_0() {
+ // TODO implement
+ return ::android::sp<V2_0::IAGnssRil>{};
+}
+
+Return<sp<V2_0::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement_2_0() {
+ ALOGD("Gnss::getExtensionGnssMeasurement_2_0");
+ return new GnssMeasurement();
+}
+
+Return<sp<measurement_corrections::V1_0::IMeasurementCorrections>>
+Gnss::getExtensionMeasurementCorrections() {
+ ALOGD("Gnss::getExtensionMeasurementCorrections()");
+ return new GnssMeasurementCorrections();
+}
+
+Return<sp<visibility_control::V1_0::IGnssVisibilityControl>> Gnss::getExtensionVisibilityControl() {
+ // TODO implement
+ return ::android::sp<visibility_control::V1_0::IGnssVisibilityControl>{};
+}
+
+Return<sp<V2_0::IGnssBatching>> Gnss::getExtensionGnssBatching_2_0() {
+ // TODO implement
+ return ::android::sp<V2_0::IGnssBatching>{};
+}
+
+Return<bool> Gnss::injectBestLocation_2_0(const V2_0::GnssLocation&) {
+ // TODO(b/124012850): Implement function.
+ return bool{};
+}
+
+// Methods from V2_1::IGnss follow.
+Return<bool> Gnss::setCallback_2_1(const sp<V2_1::IGnssCallback>& callback) {
+ ALOGD("Gnss::setCallback_2_1");
+ if (callback == nullptr) {
+ ALOGE("%s: Null callback ignored", __func__);
+ return false;
+ }
+
+ sGnssCallback_2_1 = callback;
+
+ using Capabilities = V2_0::IGnssCallback::Capabilities;
+ const auto capabilities = Capabilities::MEASUREMENTS | Capabilities::MEASUREMENT_CORRECTIONS |
+ Capabilities::LOW_POWER_MODE | Capabilities::SATELLITE_BLACKLIST;
+ auto ret = sGnssCallback_2_1->gnssSetCapabilitiesCb_2_0(capabilities);
+ if (!ret.isOk()) {
+ ALOGE("%s: Unable to invoke callback", __func__);
+ }
+
+ V1_1::IGnssCallback::GnssSystemInfo gnssInfo = {.yearOfHw = 2020};
+
+ ret = sGnssCallback_2_1->gnssSetSystemInfoCb(gnssInfo);
+ if (!ret.isOk()) {
+ ALOGE("%s: Unable to invoke callback", __func__);
+ }
+
+ auto gnssName = "Android Mock GNSS Implementation v2.1";
+ ret = sGnssCallback_2_1->gnssNameCb(gnssName);
+ if (!ret.isOk()) {
+ ALOGE("%s: Unable to invoke callback", __func__);
+ }
+
+ return true;
+}
+
+Return<sp<V2_1::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement_2_1() {
+ ALOGD("Gnss::getExtensionGnssMeasurement_2_1");
+ return new GnssMeasurement();
+}
+
+Return<sp<V2_1::IGnssConfiguration>> Gnss::getExtensionGnssConfiguration_2_1() {
+ ALOGD("Gnss::getExtensionGnssConfiguration_2_1");
+ return mGnssConfiguration;
+}
+
+void Gnss::reportSvStatus(const hidl_vec<GnssSvInfo>& svInfoList) const {
+ std::unique_lock<std::mutex> lock(mMutex);
+ // TODO(skz): update this to call 2_0 callback if non-null
+ if (sGnssCallback_2_1 == nullptr) {
+ ALOGE("%s: sGnssCallback v2.1 is null.", __func__);
+ return;
+ }
+ auto ret = sGnssCallback_2_1->gnssSvStatusCb_2_1(svInfoList);
+ if (!ret.isOk()) {
+ ALOGE("%s: Unable to invoke callback", __func__);
+ }
+}
+
+void Gnss::reportLocation(const V2_0::GnssLocation& location) const {
+ std::unique_lock<std::mutex> lock(mMutex);
+ if (sGnssCallback_2_1 != nullptr) {
+ auto ret = sGnssCallback_2_1->gnssLocationCb_2_0(location);
+ if (!ret.isOk()) {
+ ALOGE("%s: Unable to invoke callback v2.1", __func__);
+ }
+ return;
+ }
+ if (sGnssCallback_2_0 == nullptr) {
+ ALOGE("%s: No non-null callback", __func__);
+ return;
+ }
+ auto ret = sGnssCallback_2_0->gnssLocationCb_2_0(location);
+ if (!ret.isOk()) {
+ ALOGE("%s: Unable to invoke callback v2.0", __func__);
+ }
+}
+
+} // namespace implementation
+} // namespace V2_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/gnss/2.1/default/Gnss.h b/gnss/2.1/default/Gnss.h
new file mode 100644
index 0000000..7917bbd
--- /dev/null
+++ b/gnss/2.1/default/Gnss.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#pragma once
+
+#include <android/hardware/gnss/2.1/IGnss.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+#include <atomic>
+#include <mutex>
+#include <thread>
+#include "GnssConfiguration.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_1 {
+
+using GnssSvInfo = IGnssCallback::GnssSvInfo;
+
+namespace implementation {
+
+struct Gnss : public IGnss {
+ Gnss();
+ ~Gnss();
+ // Methods from V1_0::IGnss follow.
+ Return<bool> setCallback(const sp<V1_0::IGnssCallback>& callback) override;
+ Return<bool> start() override;
+ Return<bool> stop() override;
+ Return<void> cleanup() override;
+ Return<bool> injectTime(int64_t timeMs, int64_t timeReferenceMs,
+ int32_t uncertaintyMs) override;
+ Return<bool> injectLocation(double latitudeDegrees, double longitudeDegrees,
+ float accuracyMeters) override;
+ Return<void> deleteAidingData(V1_0::IGnss::GnssAidingData aidingDataFlags) override;
+ Return<bool> setPositionMode(V1_0::IGnss::GnssPositionMode mode,
+ V1_0::IGnss::GnssPositionRecurrence recurrence,
+ uint32_t minIntervalMs, uint32_t preferredAccuracyMeters,
+ uint32_t preferredTimeMs) override;
+ Return<sp<V1_0::IAGnssRil>> getExtensionAGnssRil() override;
+ Return<sp<V1_0::IGnssGeofencing>> getExtensionGnssGeofencing() override;
+ Return<sp<V1_0::IAGnss>> getExtensionAGnss() override;
+ Return<sp<V1_0::IGnssNi>> getExtensionGnssNi() override;
+ Return<sp<V1_0::IGnssMeasurement>> getExtensionGnssMeasurement() override;
+ Return<sp<V1_0::IGnssNavigationMessage>> getExtensionGnssNavigationMessage() override;
+ Return<sp<V1_0::IGnssXtra>> getExtensionXtra() override;
+ Return<sp<V1_0::IGnssConfiguration>> getExtensionGnssConfiguration() override;
+ Return<sp<V1_0::IGnssDebug>> getExtensionGnssDebug() override;
+ Return<sp<V1_0::IGnssBatching>> getExtensionGnssBatching() override;
+
+ // Methods from V1_1::IGnss follow.
+ Return<bool> setCallback_1_1(const sp<V1_1::IGnssCallback>& callback) override;
+ Return<bool> setPositionMode_1_1(V1_0::IGnss::GnssPositionMode mode,
+ V1_0::IGnss::GnssPositionRecurrence recurrence,
+ uint32_t minIntervalMs, uint32_t preferredAccuracyMeters,
+ uint32_t preferredTimeMs, bool lowPowerMode) override;
+ Return<sp<V1_1::IGnssConfiguration>> getExtensionGnssConfiguration_1_1() override;
+ Return<sp<V1_1::IGnssMeasurement>> getExtensionGnssMeasurement_1_1() override;
+ Return<bool> injectBestLocation(const V1_0::GnssLocation& location) override;
+
+ // Methods from V2_0::IGnss follow.
+ Return<bool> setCallback_2_0(const sp<V2_0::IGnssCallback>& callback) override;
+ Return<sp<V2_0::IGnssConfiguration>> getExtensionGnssConfiguration_2_0() override;
+ Return<sp<V2_0::IGnssDebug>> getExtensionGnssDebug_2_0() override;
+ Return<sp<V2_0::IAGnss>> getExtensionAGnss_2_0() override;
+ Return<sp<V2_0::IAGnssRil>> getExtensionAGnssRil_2_0() override;
+ Return<sp<V2_0::IGnssMeasurement>> getExtensionGnssMeasurement_2_0() override;
+ Return<sp<measurement_corrections::V1_0::IMeasurementCorrections>>
+ getExtensionMeasurementCorrections() override;
+ Return<sp<visibility_control::V1_0::IGnssVisibilityControl>> getExtensionVisibilityControl()
+ override;
+ Return<sp<V2_0::IGnssBatching>> getExtensionGnssBatching_2_0() override;
+ Return<bool> injectBestLocation_2_0(const V2_0::GnssLocation& location) override;
+
+ // Methods from V2_1::IGnss follow.
+ Return<bool> setCallback_2_1(const sp<V2_1::IGnssCallback>& callback) override;
+ Return<sp<V2_1::IGnssMeasurement>> getExtensionGnssMeasurement_2_1() override;
+ Return<sp<V2_1::IGnssConfiguration>> getExtensionGnssConfiguration_2_1() override;
+
+ private:
+ void reportLocation(const V2_0::GnssLocation&) const;
+ void reportSvStatus(const hidl_vec<GnssSvInfo>&) const;
+
+ static sp<V2_1::IGnssCallback> sGnssCallback_2_1;
+ static sp<V2_0::IGnssCallback> sGnssCallback_2_0;
+ std::atomic<long> mMinIntervalMs;
+ sp<GnssConfiguration> mGnssConfiguration;
+ std::atomic<bool> mIsActive;
+ std::thread mThread;
+ mutable std::mutex mMutex;
+ hidl_vec<GnssSvInfo> filterBlacklistedSatellitesV2_1(hidl_vec<GnssSvInfo> gnssSvInfoList);
+};
+
+} // namespace implementation
+} // namespace V2_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/gnss/2.1/default/GnssConfiguration.cpp b/gnss/2.1/default/GnssConfiguration.cpp
new file mode 100644
index 0000000..cd8f07f
--- /dev/null
+++ b/gnss/2.1/default/GnssConfiguration.cpp
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2019 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 "GnssConfiguration"
+
+#include "GnssConfiguration.h"
+#include <log/log.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_1 {
+namespace implementation {
+
+// Methods from ::android::hardware::gnss::V1_0::IGnssConfiguration follow.
+Return<bool> GnssConfiguration::setSuplEs(bool enable) {
+ ALOGD("setSuplEs enable: %d", enable);
+ // Method deprecated in 2.0 and not expected to be called by the framework.
+ return false;
+}
+
+Return<bool> GnssConfiguration::setSuplVersion(uint32_t) {
+ return true;
+}
+
+Return<bool> GnssConfiguration::setSuplMode(hidl_bitfield<SuplMode>) {
+ return true;
+}
+
+Return<bool> GnssConfiguration::setGpsLock(hidl_bitfield<GpsLock> gpsLock) {
+ ALOGD("setGpsLock gpsLock: %hhu", static_cast<GpsLock>(gpsLock));
+ // Method deprecated in 2.0 and not expected to be called by the framework.
+ return false;
+}
+
+Return<bool> GnssConfiguration::setLppProfile(hidl_bitfield<LppProfile>) {
+ return true;
+}
+
+Return<bool> GnssConfiguration::setGlonassPositioningProtocol(hidl_bitfield<GlonassPosProtocol>) {
+ return true;
+}
+
+Return<bool> GnssConfiguration::setEmergencySuplPdn(bool) {
+ return true;
+}
+
+// Methods from ::android::hardware::gnss::V1_1::IGnssConfiguration follow.
+Return<bool> GnssConfiguration::setBlacklist(
+ const hidl_vec<V1_1::IGnssConfiguration::BlacklistedSource>&) {
+ // TODO (b/122463906): Reuse 1.1 implementation.
+ return bool{};
+}
+
+// Methods from ::android::hardware::gnss::V2_0::IGnssConfiguration follow.
+Return<bool> GnssConfiguration::setEsExtensionSec(uint32_t emergencyExtensionSeconds) {
+ ALOGD("setEsExtensionSec emergencyExtensionSeconds: %d", emergencyExtensionSeconds);
+ return true;
+}
+
+// Methods from ::android::hardware::gnss::V2_1::IGnssConfiguration follow.
+Return<bool> GnssConfiguration::setBlacklist_2_1(
+ const hidl_vec<V2_1::IGnssConfiguration::BlacklistedSource>& sourceList) {
+ std::unique_lock<std::recursive_mutex> lock(mMutex);
+ mBlacklistedConstellationSet.clear();
+ mBlacklistedSourceSet.clear();
+ for (auto source : sourceList) {
+ if (source.svid == 0) {
+ // Wildcard blacklist, i.e., blacklist entire constellation.
+ mBlacklistedConstellationSet.insert(source.constellation);
+ } else {
+ mBlacklistedSourceSet.insert(source);
+ }
+ }
+ return true;
+}
+
+Return<bool> GnssConfiguration::isBlacklistedV2_1(const GnssSvInfoV2_1& gnssSvInfo) const {
+ std::unique_lock<std::recursive_mutex> lock(mMutex);
+ if (mBlacklistedConstellationSet.find(gnssSvInfo.v2_0.constellation) !=
+ mBlacklistedConstellationSet.end()) {
+ return true;
+ }
+ BlacklistedSourceV2_1 source = {.constellation = gnssSvInfo.v2_0.constellation,
+ .svid = gnssSvInfo.v2_0.v1_0.svid};
+ return (mBlacklistedSourceSet.find(source) != mBlacklistedSourceSet.end());
+}
+
+} // namespace implementation
+} // namespace V2_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
\ No newline at end of file
diff --git a/gnss/2.1/default/GnssConfiguration.h b/gnss/2.1/default/GnssConfiguration.h
new file mode 100644
index 0000000..662d61d
--- /dev/null
+++ b/gnss/2.1/default/GnssConfiguration.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_GNSS_V2_1_GNSSCONFIGURATION_H
+#define ANDROID_HARDWARE_GNSS_V2_1_GNSSCONFIGURATION_H
+
+#include <android/hardware/gnss/2.1/IGnssCallback.h>
+#include <android/hardware/gnss/2.1/IGnssConfiguration.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+#include <mutex>
+#include <unordered_set>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_1 {
+namespace implementation {
+
+using ::android::sp;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+
+using BlacklistedSourceV2_1 =
+ ::android::hardware::gnss::V2_1::IGnssConfiguration::BlacklistedSource;
+using GnssConstellationTypeV2_0 = V2_0::GnssConstellationType;
+using GnssSvInfoV2_1 = V2_1::IGnssCallback::GnssSvInfo;
+
+struct BlacklistedSourceHashV2_1 {
+ inline int operator()(const BlacklistedSourceV2_1& source) const {
+ return int(source.constellation) * 1000 + int(source.svid);
+ }
+};
+
+struct BlacklistedSourceEqualV2_1 {
+ inline bool operator()(const BlacklistedSourceV2_1& s1, const BlacklistedSourceV2_1& s2) const {
+ return (s1.constellation == s2.constellation) && (s1.svid == s2.svid);
+ }
+};
+
+using BlacklistedSourceSetV2_1 =
+ std::unordered_set<BlacklistedSourceV2_1, BlacklistedSourceHashV2_1,
+ BlacklistedSourceEqualV2_1>;
+using BlacklistedConstellationSetV2_1 = std::unordered_set<GnssConstellationTypeV2_0>;
+
+struct GnssConfiguration : public IGnssConfiguration {
+ // Methods from ::android::hardware::gnss::V1_0::IGnssConfiguration follow.
+ Return<bool> setSuplEs(bool enabled) override;
+ Return<bool> setSuplVersion(uint32_t version) override;
+ Return<bool> setSuplMode(hidl_bitfield<SuplMode> mode) override;
+ Return<bool> setGpsLock(hidl_bitfield<GpsLock> lock) override;
+ Return<bool> setLppProfile(hidl_bitfield<LppProfile> lppProfile) override;
+ Return<bool> setGlonassPositioningProtocol(hidl_bitfield<GlonassPosProtocol> protocol) override;
+ Return<bool> setEmergencySuplPdn(bool enable) override;
+
+ // Methods from ::android::hardware::gnss::V1_1::IGnssConfiguration follow.
+ Return<bool> setBlacklist(
+ const hidl_vec<V1_1::IGnssConfiguration::BlacklistedSource>& blacklist) override;
+
+ std::recursive_mutex& getMutex() const;
+
+ // Methods from ::android::hardware::gnss::V2_0::IGnssConfiguration follow.
+ Return<bool> setEsExtensionSec(uint32_t emergencyExtensionSeconds) override;
+
+ // Methods from ::android::hardware::gnss::V2_1::IGnssConfiguration follow.
+ Return<bool> setBlacklist_2_1(
+ const hidl_vec<V2_1::IGnssConfiguration::BlacklistedSource>& blacklist) override;
+
+ Return<bool> isBlacklistedV2_1(const GnssSvInfoV2_1& gnssSvInfo) const;
+
+ private:
+ mutable std::recursive_mutex mMutex;
+
+ BlacklistedSourceSetV2_1 mBlacklistedSourceSet;
+ BlacklistedConstellationSetV2_1 mBlacklistedConstellationSet;
+};
+
+} // namespace implementation
+} // namespace V2_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GNSS_V2_1_GNSSCONFIGURATION_H
\ No newline at end of file
diff --git a/gnss/2.1/default/GnssMeasurement.cpp b/gnss/2.1/default/GnssMeasurement.cpp
new file mode 100644
index 0000000..34e20e5
--- /dev/null
+++ b/gnss/2.1/default/GnssMeasurement.cpp
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2019 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 "GnssMeasurement"
+
+#include "GnssMeasurement.h"
+#include <log/log.h>
+#include "Utils.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+
+using common::Utils;
+
+namespace V2_1 {
+namespace implementation {
+
+sp<V2_1::IGnssMeasurementCallback> GnssMeasurement::sCallback_2_1 = nullptr;
+sp<V2_0::IGnssMeasurementCallback> GnssMeasurement::sCallback_2_0 = nullptr;
+
+GnssMeasurement::GnssMeasurement() : mMinIntervalMillis(1000) {}
+
+GnssMeasurement::~GnssMeasurement() {
+ stop();
+}
+
+// Methods from V1_0::IGnssMeasurement follow.
+Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> GnssMeasurement::setCallback(
+ const sp<V1_0::IGnssMeasurementCallback>&) {
+ // TODO implement
+ return V1_0::IGnssMeasurement::GnssMeasurementStatus{};
+}
+
+Return<void> GnssMeasurement::close() {
+ ALOGD("close");
+ std::unique_lock<std::mutex> lock(mMutex);
+ stop();
+ sCallback_2_1 = nullptr;
+ sCallback_2_0 = nullptr;
+ return Void();
+}
+
+// Methods from V1_1::IGnssMeasurement follow.
+Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> GnssMeasurement::setCallback_1_1(
+ const sp<V1_1::IGnssMeasurementCallback>&, bool) {
+ // TODO implement
+ return V1_0::IGnssMeasurement::GnssMeasurementStatus{};
+}
+
+// Methods from V2_0::IGnssMeasurement follow.
+Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> GnssMeasurement::setCallback_2_0(
+ const sp<V2_0::IGnssMeasurementCallback>& callback, bool) {
+ ALOGD("setCallback_2_0");
+ std::unique_lock<std::mutex> lock(mMutex);
+ sCallback_2_0 = callback;
+
+ if (mIsActive) {
+ ALOGW("GnssMeasurement callback already set. Resetting the callback...");
+ stop();
+ }
+ start();
+
+ return V1_0::IGnssMeasurement::GnssMeasurementStatus::SUCCESS;
+}
+
+// Methods from V2_1::IGnssMeasurement follow.
+Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> GnssMeasurement::setCallback_2_1(
+ const sp<V2_1::IGnssMeasurementCallback>& callback, bool) {
+ ALOGD("setCallback_2_1");
+ std::unique_lock<std::mutex> lock(mMutex);
+ sCallback_2_1 = callback;
+
+ if (mIsActive) {
+ ALOGW("GnssMeasurement callback already set. Resetting the callback...");
+ stop();
+ }
+ start();
+
+ return V1_0::IGnssMeasurement::GnssMeasurementStatus::SUCCESS;
+}
+
+void GnssMeasurement::start() {
+ ALOGD("start");
+ mIsActive = true;
+ mThread = std::thread([this]() {
+ while (mIsActive == true) {
+ if (sCallback_2_1 != nullptr) {
+ auto measurement = Utils::getMockMeasurementV2_1();
+ this->reportMeasurement(measurement);
+ } else {
+ auto measurement = Utils::getMockMeasurementV2_0();
+ this->reportMeasurement(measurement);
+ }
+
+ std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMillis));
+ }
+ });
+}
+
+void GnssMeasurement::stop() {
+ ALOGD("stop");
+ mIsActive = false;
+ if (mThread.joinable()) {
+ mThread.join();
+ }
+}
+
+void GnssMeasurement::reportMeasurement(const GnssDataV2_0& data) {
+ ALOGD("reportMeasurement()");
+ std::unique_lock<std::mutex> lock(mMutex);
+ if (sCallback_2_0 == nullptr) {
+ ALOGE("%s: GnssMeasurement::sCallback_2_0 is null.", __func__);
+ return;
+ }
+ auto ret = sCallback_2_0->gnssMeasurementCb_2_0(data);
+ if (!ret.isOk()) {
+ ALOGE("%s: Unable to invoke callback", __func__);
+ }
+}
+
+void GnssMeasurement::reportMeasurement(const GnssDataV2_1& data) {
+ ALOGD("reportMeasurement()");
+ std::unique_lock<std::mutex> lock(mMutex);
+ if (sCallback_2_1 == nullptr) {
+ ALOGE("%s: GnssMeasurement::sCallback_2_1 is null.", __func__);
+ return;
+ }
+ auto ret = sCallback_2_1->gnssMeasurementCb_2_1(data);
+ if (!ret.isOk()) {
+ ALOGE("%s: Unable to invoke callback", __func__);
+ }
+}
+
+} // namespace implementation
+} // namespace V2_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/gnss/2.1/default/GnssMeasurement.h b/gnss/2.1/default/GnssMeasurement.h
new file mode 100644
index 0000000..3ed7bc5
--- /dev/null
+++ b/gnss/2.1/default/GnssMeasurement.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#pragma once
+
+#include <android/hardware/gnss/2.1/IGnssMeasurement.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+#include <atomic>
+#include <mutex>
+#include <thread>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_1 {
+namespace implementation {
+
+using GnssDataV2_1 = V2_1::IGnssMeasurementCallback::GnssData;
+using GnssDataV2_0 = V2_0::IGnssMeasurementCallback::GnssData;
+
+using ::android::sp;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+
+struct GnssMeasurement : public IGnssMeasurement {
+ GnssMeasurement();
+ ~GnssMeasurement();
+ // Methods from V1_0::IGnssMeasurement follow.
+ Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> setCallback(
+ const sp<V1_0::IGnssMeasurementCallback>& callback) override;
+ Return<void> close() override;
+
+ // Methods from V1_1::IGnssMeasurement follow.
+ Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> setCallback_1_1(
+ const sp<V1_1::IGnssMeasurementCallback>& callback, bool enableFullTracking) override;
+
+ // Methods from V2_0::IGnssMeasurement follow.
+ Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> setCallback_2_0(
+ const sp<V2_0::IGnssMeasurementCallback>& callback, bool enableFullTracking) override;
+
+ // Methods from V2_1::IGnssMeasurement follow.
+ Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> setCallback_2_1(
+ const sp<V2_1::IGnssMeasurementCallback>& callback, bool enableFullTracking) override;
+
+ private:
+ void start();
+ void stop();
+ void reportMeasurement(const GnssDataV2_0&);
+ void reportMeasurement(const GnssDataV2_1&);
+
+ static sp<V2_1::IGnssMeasurementCallback> sCallback_2_1;
+ static sp<V2_0::IGnssMeasurementCallback> sCallback_2_0;
+ std::atomic<long> mMinIntervalMillis;
+ std::atomic<bool> mIsActive;
+ std::thread mThread;
+ mutable std::mutex mMutex;
+};
+
+} // namespace implementation
+} // namespace V2_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/gnss/2.1/default/GnssMeasurementCorrections.cpp b/gnss/2.1/default/GnssMeasurementCorrections.cpp
new file mode 100644
index 0000000..2bf5601
--- /dev/null
+++ b/gnss/2.1/default/GnssMeasurementCorrections.cpp
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2019 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 "GnssMeasurementCorrections"
+
+#include "GnssMeasurementCorrections.h"
+#include <log/log.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace measurement_corrections {
+namespace V1_0 {
+namespace implementation {
+
+// Methods from V1_0::IMeasurementCorrections follow.
+Return<bool> GnssMeasurementCorrections::setCorrections(const MeasurementCorrections& corrections) {
+ ALOGD("setCorrections");
+ ALOGD("corrections = lat: %f, lng: %f, alt: %f, hUnc: %f, vUnc: %f, toa: %llu, "
+ "satCorrections.size: %d",
+ corrections.latitudeDegrees, corrections.longitudeDegrees, corrections.altitudeMeters,
+ corrections.horizontalPositionUncertaintyMeters,
+ corrections.verticalPositionUncertaintyMeters,
+ static_cast<unsigned long long>(corrections.toaGpsNanosecondsOfWeek),
+ static_cast<int>(corrections.satCorrections.size()));
+ for (auto singleSatCorrection : corrections.satCorrections) {
+ ALOGD("singleSatCorrection = flags: %d, constellation: %d, svid: %d, cfHz: %f, probLos: %f,"
+ " epl: %f, eplUnc: %f",
+ static_cast<int>(singleSatCorrection.singleSatCorrectionFlags),
+ static_cast<int>(singleSatCorrection.constellation),
+ static_cast<int>(singleSatCorrection.svid), singleSatCorrection.carrierFrequencyHz,
+ singleSatCorrection.probSatIsLos, singleSatCorrection.excessPathLengthMeters,
+ singleSatCorrection.excessPathLengthUncertaintyMeters);
+ ALOGD("reflecting plane = lat: %f, lng: %f, alt: %f, azm: %f",
+ singleSatCorrection.reflectingPlane.latitudeDegrees,
+ singleSatCorrection.reflectingPlane.longitudeDegrees,
+ singleSatCorrection.reflectingPlane.altitudeMeters,
+ singleSatCorrection.reflectingPlane.azimuthDegrees);
+ }
+
+ return true;
+}
+
+Return<bool> GnssMeasurementCorrections::setCallback(
+ const sp<V1_0::IMeasurementCorrectionsCallback>& callback) {
+ using Capabilities = V1_0::IMeasurementCorrectionsCallback::Capabilities;
+ auto ret =
+ callback->setCapabilitiesCb(Capabilities::LOS_SATS | Capabilities::EXCESS_PATH_LENGTH |
+ Capabilities::REFLECTING_PLANE);
+ if (!ret.isOk()) {
+ ALOGE("%s: Unable to invoke callback", __func__);
+ return false;
+ }
+ return true;
+}
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace measurement_corrections
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/gnss/2.1/default/GnssMeasurementCorrections.h b/gnss/2.1/default/GnssMeasurementCorrections.h
new file mode 100644
index 0000000..4339bed
--- /dev/null
+++ b/gnss/2.1/default/GnssMeasurementCorrections.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#pragma once
+
+#include <android/hardware/gnss/measurement_corrections/1.0/IMeasurementCorrections.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace measurement_corrections {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::sp;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+
+struct GnssMeasurementCorrections : public IMeasurementCorrections {
+ // Methods from V1_0::IMeasurementCorrections follow.
+ Return<bool> setCorrections(const MeasurementCorrections& corrections) override;
+ Return<bool> setCallback(const sp<V1_0::IMeasurementCorrectionsCallback>& callback) override;
+};
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace measurement_corrections
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/gnss/2.1/default/OWNERS b/gnss/2.1/default/OWNERS
new file mode 100644
index 0000000..b7b4a2e
--- /dev/null
+++ b/gnss/2.1/default/OWNERS
@@ -0,0 +1,4 @@
+gomo@google.com
+smalkos@google.com
+wyattriley@google.com
+yuhany@google.com
diff --git a/gnss/2.1/default/android.hardware.gnss@2.1-service.rc b/gnss/2.1/default/android.hardware.gnss@2.1-service.rc
new file mode 100644
index 0000000..5926c77
--- /dev/null
+++ b/gnss/2.1/default/android.hardware.gnss@2.1-service.rc
@@ -0,0 +1,4 @@
+service vendor.gnss-2-1 /vendor/bin/hw/android.hardware.gnss@2.1-service
+ class hal
+ user system
+ group system
diff --git a/gnss/2.1/default/android.hardware.gnss@2.1-service.xml b/gnss/2.1/default/android.hardware.gnss@2.1-service.xml
new file mode 100644
index 0000000..12a1fdf
--- /dev/null
+++ b/gnss/2.1/default/android.hardware.gnss@2.1-service.xml
@@ -0,0 +1,12 @@
+<manifest version="1.0" type="device">
+ <hal format="hidl">
+ <name>android.hardware.gnss</name>
+ <transport>hwbinder</transport>
+ <version>2.1</version>
+ <version>1.1</version>
+ <interface>
+ <name>IGnss</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+</manifest>
diff --git a/gnss/2.1/default/service.cpp b/gnss/2.1/default/service.cpp
new file mode 100644
index 0000000..5e004d5
--- /dev/null
+++ b/gnss/2.1/default/service.cpp
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2019 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 "android.hardware.gnss@2.1-service"
+
+#include <hidl/HidlSupport.h>
+#include <hidl/HidlTransportSupport.h>
+#include "Gnss.h"
+
+using ::android::OK;
+using ::android::sp;
+using ::android::hardware::configureRpcThreadpool;
+using ::android::hardware::joinRpcThreadpool;
+using ::android::hardware::gnss::V2_1::IGnss;
+using ::android::hardware::gnss::V2_1::implementation::Gnss;
+
+int main(int /* argc */, char* /* argv */[]) {
+ sp<IGnss> gnss = new Gnss();
+ configureRpcThreadpool(1, true /* will join */);
+ if (gnss->registerAsService() != OK) {
+ ALOGE("Could not register gnss 2.1 service.");
+ return 1;
+ }
+ joinRpcThreadpool();
+
+ ALOGE("Service exited!");
+ return 1;
+}
\ No newline at end of file
diff --git a/gnss/2.1/vts/OWNERS b/gnss/2.1/vts/OWNERS
new file mode 100644
index 0000000..b7b4a2e
--- /dev/null
+++ b/gnss/2.1/vts/OWNERS
@@ -0,0 +1,4 @@
+gomo@google.com
+smalkos@google.com
+wyattriley@google.com
+yuhany@google.com
diff --git a/gnss/2.1/vts/functional/Android.bp b/gnss/2.1/vts/functional/Android.bp
new file mode 100644
index 0000000..8340499
--- /dev/null
+++ b/gnss/2.1/vts/functional/Android.bp
@@ -0,0 +1,35 @@
+//
+// Copyright (C) 2019 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.
+//
+
+cc_test {
+ name: "VtsHalGnssV2_1TargetTest",
+ defaults: ["VtsHalTargetTestDefaults"],
+ srcs: [
+ "gnss_hal_test.cpp",
+ "gnss_hal_test_cases.cpp",
+ "VtsHalGnssV2_1TargetTest.cpp",
+ ],
+ static_libs: [
+ "android.hardware.gnss.measurement_corrections@1.0",
+ "android.hardware.gnss.visibility_control@1.0",
+ "android.hardware.gnss@1.0",
+ "android.hardware.gnss@1.1",
+ "android.hardware.gnss@2.0",
+ "android.hardware.gnss@2.1",
+ "android.hardware.gnss@common-vts-lib",
+ ],
+ test_suites: ["general-tests", "vts-core"],
+}
diff --git a/gnss/2.1/vts/functional/VtsHalGnssV2_1TargetTest.cpp b/gnss/2.1/vts/functional/VtsHalGnssV2_1TargetTest.cpp
new file mode 100644
index 0000000..e61d885
--- /dev/null
+++ b/gnss/2.1/vts/functional/VtsHalGnssV2_1TargetTest.cpp
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2019 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 "VtsHalGnssV2_1TargetTest"
+
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
+
+#include "gnss_hal_test.h"
+
+using android::hardware::gnss::V2_1::IGnss;
+
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, GnssHalTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(IGnss::descriptor)),
+ android::hardware::PrintInstanceNameToString);
\ No newline at end of file
diff --git a/gnss/2.1/vts/functional/gnss_hal_test.cpp b/gnss/2.1/vts/functional/gnss_hal_test.cpp
new file mode 100644
index 0000000..22268f6
--- /dev/null
+++ b/gnss/2.1/vts/functional/gnss_hal_test.cpp
@@ -0,0 +1,258 @@
+/*
+ * Copyright (C) 2019 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 "GnssHalTest"
+
+#include <gnss_hal_test.h>
+#include <chrono>
+#include "Utils.h"
+
+#include <gtest/gtest.h>
+
+using ::android::hardware::gnss::common::Utils;
+
+// Implementations for the main test class for GNSS HAL
+void GnssHalTest::SetUp() {
+ gnss_hal_ = IGnss::getService(GetParam());
+ ASSERT_NE(gnss_hal_, nullptr);
+
+ SetUpGnssCallback();
+}
+
+void GnssHalTest::TearDown() {
+ if (gnss_hal_ != nullptr) {
+ gnss_hal_->cleanup();
+ gnss_hal_ = nullptr;
+ }
+
+ // Set to nullptr to destruct the callback event queues and warn of any unprocessed events.
+ gnss_cb_ = nullptr;
+}
+
+void GnssHalTest::SetUpGnssCallback() {
+ gnss_cb_ = new GnssCallback();
+ ASSERT_NE(gnss_cb_, nullptr);
+
+ auto result = gnss_hal_->setCallback_2_1(gnss_cb_);
+ if (!result.isOk()) {
+ ALOGE("result of failed setCallback %s", result.description().c_str());
+ }
+
+ ASSERT_TRUE(result.isOk());
+ ASSERT_TRUE(result);
+
+ /*
+ * All capabilities, name and systemInfo callbacks should trigger
+ */
+ EXPECT_TRUE(gnss_cb_->capabilities_cbq_.retrieve(gnss_cb_->last_capabilities_, TIMEOUT_SEC));
+ EXPECT_TRUE(gnss_cb_->info_cbq_.retrieve(gnss_cb_->last_info_, TIMEOUT_SEC));
+ EXPECT_TRUE(gnss_cb_->name_cbq_.retrieve(gnss_cb_->last_name_, TIMEOUT_SEC));
+
+ EXPECT_EQ(gnss_cb_->capabilities_cbq_.calledCount(), 1);
+ EXPECT_EQ(gnss_cb_->info_cbq_.calledCount(), 1);
+ EXPECT_EQ(gnss_cb_->name_cbq_.calledCount(), 1);
+}
+
+void GnssHalTest::StopAndClearLocations() {
+ const auto result = gnss_hal_->stop();
+
+ EXPECT_TRUE(result.isOk());
+ EXPECT_TRUE(result);
+
+ /*
+ * Clear notify/waiting counter, allowing up till the timeout after
+ * the last reply for final startup messages to arrive (esp. system
+ * info.)
+ */
+ while (gnss_cb_->location_cbq_.retrieve(gnss_cb_->last_location_, TIMEOUT_SEC)) {
+ }
+ gnss_cb_->location_cbq_.reset();
+}
+
+void GnssHalTest::SetPositionMode(const int min_interval_msec, const bool low_power_mode) {
+ const int kPreferredAccuracy = 0; // Ideally perfect (matches GnssLocationProvider)
+ const int kPreferredTimeMsec = 0; // Ideally immediate
+
+ const auto result = gnss_hal_->setPositionMode_1_1(
+ IGnss::GnssPositionMode::MS_BASED, IGnss::GnssPositionRecurrence::RECURRENCE_PERIODIC,
+ min_interval_msec, kPreferredAccuracy, kPreferredTimeMsec, low_power_mode);
+
+ ASSERT_TRUE(result.isOk());
+ EXPECT_TRUE(result);
+}
+
+bool GnssHalTest::StartAndCheckFirstLocation() {
+ const auto result = gnss_hal_->start();
+
+ EXPECT_TRUE(result.isOk());
+ EXPECT_TRUE(result);
+
+ /*
+ * GnssLocationProvider support of AGPS SUPL & XtraDownloader is not available in VTS,
+ * so allow time to demodulate ephemeris over the air.
+ */
+ const int kFirstGnssLocationTimeoutSeconds = 75;
+
+ EXPECT_TRUE(gnss_cb_->location_cbq_.retrieve(gnss_cb_->last_location_,
+ kFirstGnssLocationTimeoutSeconds));
+ int locationCalledCount = gnss_cb_->location_cbq_.calledCount();
+ EXPECT_EQ(locationCalledCount, 1);
+
+ if (locationCalledCount > 0) {
+ // don't require speed on first fix
+ CheckLocation(gnss_cb_->last_location_, false);
+ return true;
+ }
+ return false;
+}
+
+void GnssHalTest::CheckLocation(const GnssLocation_2_0& location, bool check_speed) {
+ const bool check_more_accuracies =
+ (gnss_cb_->info_cbq_.calledCount() > 0 && gnss_cb_->last_info_.yearOfHw >= 2017);
+
+ Utils::checkLocation(location.v1_0, check_speed, check_more_accuracies);
+}
+
+void GnssHalTest::StartAndCheckLocations(int count) {
+ const int kMinIntervalMsec = 500;
+ const int kLocationTimeoutSubsequentSec = 2;
+ const bool kLowPowerMode = false;
+
+ SetPositionMode(kMinIntervalMsec, kLowPowerMode);
+
+ EXPECT_TRUE(StartAndCheckFirstLocation());
+
+ for (int i = 1; i < count; i++) {
+ EXPECT_TRUE(gnss_cb_->location_cbq_.retrieve(gnss_cb_->last_location_,
+ kLocationTimeoutSubsequentSec));
+ int locationCalledCount = gnss_cb_->location_cbq_.calledCount();
+ EXPECT_EQ(locationCalledCount, i + 1);
+ // Don't cause confusion by checking details if no location yet
+ if (locationCalledCount > 0) {
+ // Should be more than 1 location by now, but if not, still don't check first fix speed
+ CheckLocation(gnss_cb_->last_location_, locationCalledCount > 1);
+ }
+ }
+}
+
+GnssConstellationType GnssHalTest::startLocationAndGetNonGpsConstellation(
+ const int locations_to_await, const int gnss_sv_info_list_timeout) {
+ gnss_cb_->location_cbq_.reset();
+ StartAndCheckLocations(locations_to_await);
+ const int location_called_count = gnss_cb_->location_cbq_.calledCount();
+
+ // Tolerate 1 less sv status to handle edge cases in reporting.
+ int sv_info_list_cbq_size = gnss_cb_->sv_info_list_cbq_.size();
+ EXPECT_GE(sv_info_list_cbq_size + 1, locations_to_await);
+ ALOGD("Observed %d GnssSvInfo, while awaiting %d Locations (%d received)",
+ sv_info_list_cbq_size, locations_to_await, location_called_count);
+
+ // Find first non-GPS constellation to blacklist
+ GnssConstellationType constellation_to_blacklist = GnssConstellationType::UNKNOWN;
+ for (int i = 0; i < sv_info_list_cbq_size; ++i) {
+ hidl_vec<IGnssCallback_2_1::GnssSvInfo> sv_info_vec;
+ gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, gnss_sv_info_list_timeout);
+ for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
+ const auto& gnss_sv = sv_info_vec[iSv];
+ if ((gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX) &&
+ (gnss_sv.v2_0.constellation != GnssConstellationType::UNKNOWN) &&
+ (gnss_sv.v2_0.constellation != GnssConstellationType::GPS)) {
+ // found a non-GPS constellation
+ constellation_to_blacklist = gnss_sv.v2_0.constellation;
+ break;
+ }
+ }
+ if (constellation_to_blacklist != GnssConstellationType::UNKNOWN) {
+ break;
+ }
+ }
+
+ if (constellation_to_blacklist == GnssConstellationType::UNKNOWN) {
+ ALOGI("No non-GPS constellations found, constellation blacklist test less effective.");
+ // Proceed functionally to blacklist something.
+ constellation_to_blacklist = GnssConstellationType::GLONASS;
+ }
+
+ return constellation_to_blacklist;
+}
+
+GnssHalTest::GnssCallback::GnssCallback()
+ : info_cbq_("system_info"),
+ name_cbq_("name"),
+ capabilities_cbq_("capabilities"),
+ location_cbq_("location"),
+ sv_info_list_cbq_("sv_info") {}
+
+Return<void> GnssHalTest::GnssCallback::gnssSetSystemInfoCb(
+ const IGnssCallback_1_0::GnssSystemInfo& info) {
+ ALOGI("Info received, year %d", info.yearOfHw);
+ info_cbq_.store(info);
+ return Void();
+}
+
+Return<void> GnssHalTest::GnssCallback::gnssSetCapabilitesCb(uint32_t capabilities) {
+ ALOGI("Capabilities received %d", capabilities);
+ capabilities_cbq_.store(capabilities);
+ return Void();
+}
+
+Return<void> GnssHalTest::GnssCallback::gnssSetCapabilitiesCb_2_0(uint32_t capabilities) {
+ ALOGI("Capabilities (v2.0) received %d", capabilities);
+ capabilities_cbq_.store(capabilities);
+ return Void();
+}
+
+Return<void> GnssHalTest::GnssCallback::gnssNameCb(const android::hardware::hidl_string& name) {
+ ALOGI("Name received: %s", name.c_str());
+ name_cbq_.store(name);
+ return Void();
+}
+
+Return<void> GnssHalTest::GnssCallback::gnssLocationCb(const GnssLocation_1_0& location) {
+ ALOGI("Location received");
+ GnssLocation_2_0 location_v2_0;
+ location_v2_0.v1_0 = location;
+ return gnssLocationCbImpl(location_v2_0);
+}
+
+Return<void> GnssHalTest::GnssCallback::gnssLocationCb_2_0(const GnssLocation_2_0& location) {
+ ALOGI("Location (v2.0) received");
+ return gnssLocationCbImpl(location);
+}
+
+Return<void> GnssHalTest::GnssCallback::gnssLocationCbImpl(const GnssLocation_2_0& location) {
+ location_cbq_.store(location);
+ return Void();
+}
+
+Return<void> GnssHalTest::GnssCallback::gnssSvStatusCb(const IGnssCallback_1_0::GnssSvStatus&) {
+ ALOGI("gnssSvStatusCb");
+ return Void();
+}
+
+Return<void> GnssHalTest::GnssCallback::gnssSvStatusCb_2_1(
+ const hidl_vec<IGnssCallback_2_1::GnssSvInfo>& svInfoList) {
+ ALOGI("gnssSvStatusCb_2_1. Size = %d", (int)svInfoList.size());
+ sv_info_list_cbq_.store(svInfoList);
+ return Void();
+}
+
+Return<void> GnssHalTest::GnssMeasurementCallback::gnssMeasurementCb_2_1(
+ const IGnssMeasurementCallback_2_1::GnssData& data) {
+ ALOGD("GnssMeasurement v2.1 received. Size = %d", (int)data.measurements.size());
+ measurement_cbq_.store(data);
+ return Void();
+}
diff --git a/gnss/2.1/vts/functional/gnss_hal_test.h b/gnss/2.1/vts/functional/gnss_hal_test.h
new file mode 100644
index 0000000..6b67e13
--- /dev/null
+++ b/gnss/2.1/vts/functional/gnss_hal_test.h
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef GNSS_HAL_TEST_H_
+#define GNSS_HAL_TEST_H_
+
+#include <android/hardware/gnss/2.1/IGnss.h>
+#include "GnssCallbackEventQueue.h"
+
+#include <gtest/gtest.h>
+
+using android::hardware::hidl_vec;
+using android::hardware::Return;
+using android::hardware::Void;
+
+using android::hardware::gnss::common::GnssCallbackEventQueue;
+using android::hardware::gnss::V1_0::GnssLocationFlags;
+using android::hardware::gnss::V2_0::GnssConstellationType;
+using android::hardware::gnss::V2_1::IGnss;
+
+using GnssLocation_1_0 = android::hardware::gnss::V1_0::GnssLocation;
+using GnssLocation_2_0 = android::hardware::gnss::V2_0::GnssLocation;
+
+using IGnssCallback_1_0 = android::hardware::gnss::V1_0::IGnssCallback;
+using IGnssCallback_2_0 = android::hardware::gnss::V2_0::IGnssCallback;
+using IGnssCallback_2_1 = android::hardware::gnss::V2_1::IGnssCallback;
+
+using IGnssMeasurementCallback_1_0 = android::hardware::gnss::V1_0::IGnssMeasurementCallback;
+using IGnssMeasurementCallback_1_1 = android::hardware::gnss::V1_1::IGnssMeasurementCallback;
+using IGnssMeasurementCallback_2_0 = android::hardware::gnss::V2_0::IGnssMeasurementCallback;
+using IGnssMeasurementCallback_2_1 = android::hardware::gnss::V2_1::IGnssMeasurementCallback;
+
+using android::sp;
+
+#define TIMEOUT_SEC 2 // for basic commands/responses
+
+// The main test class for GNSS HAL.
+class GnssHalTest : public testing::TestWithParam<std::string> {
+ public:
+ virtual void SetUp() override;
+
+ virtual void TearDown() override;
+
+ /* Callback class for data & Event. */
+ class GnssCallback : public IGnssCallback_2_1 {
+ public:
+ IGnssCallback_1_0::GnssSystemInfo last_info_;
+ android::hardware::hidl_string last_name_;
+ uint32_t last_capabilities_;
+ GnssLocation_2_0 last_location_;
+
+ GnssCallbackEventQueue<IGnssCallback_1_0::GnssSystemInfo> info_cbq_;
+ GnssCallbackEventQueue<android::hardware::hidl_string> name_cbq_;
+ GnssCallbackEventQueue<uint32_t> capabilities_cbq_;
+ GnssCallbackEventQueue<GnssLocation_2_0> location_cbq_;
+ GnssCallbackEventQueue<hidl_vec<IGnssCallback_2_1::GnssSvInfo>> sv_info_list_cbq_;
+
+ GnssCallback();
+ virtual ~GnssCallback() = default;
+
+ // Dummy callback handlers
+ Return<void> gnssStatusCb(const IGnssCallback_1_0::GnssStatusValue /* status */) override {
+ return Void();
+ }
+ Return<void> gnssNmeaCb(int64_t /* timestamp */,
+ const android::hardware::hidl_string& /* nmea */) override {
+ return Void();
+ }
+ Return<void> gnssAcquireWakelockCb() override { return Void(); }
+ Return<void> gnssReleaseWakelockCb() override { return Void(); }
+ Return<void> gnssRequestLocationCb(bool /* independentFromGnss */) override {
+ return Void();
+ }
+ Return<void> gnssRequestTimeCb() override { return Void(); }
+ // Actual (test) callback handlers
+ Return<void> gnssNameCb(const android::hardware::hidl_string& name) override;
+ Return<void> gnssLocationCb(const GnssLocation_1_0& location) override;
+ Return<void> gnssSetCapabilitesCb(uint32_t capabilities) override;
+ Return<void> gnssSetSystemInfoCb(const IGnssCallback_1_0::GnssSystemInfo& info) override;
+ Return<void> gnssSvStatusCb(const IGnssCallback_1_0::GnssSvStatus& svStatus) override;
+
+ // New in v2.0
+ Return<void> gnssLocationCb_2_0(const GnssLocation_2_0& location) override;
+ Return<void> gnssRequestLocationCb_2_0(bool /* independentFromGnss */,
+ bool /* isUserEmergency */) override {
+ return Void();
+ }
+ Return<void> gnssSetCapabilitiesCb_2_0(uint32_t capabilities) override;
+ Return<void> gnssSvStatusCb_2_0(const hidl_vec<IGnssCallback_2_0::GnssSvInfo>&) override {
+ return Void();
+ }
+
+ // New in v2.1
+ Return<void> gnssSvStatusCb_2_1(
+ const hidl_vec<IGnssCallback_2_1::GnssSvInfo>& svInfoList) override;
+
+ private:
+ Return<void> gnssLocationCbImpl(const GnssLocation_2_0& location);
+ };
+
+ /* Callback class for GnssMeasurement. */
+ class GnssMeasurementCallback : public IGnssMeasurementCallback_2_1 {
+ public:
+ GnssCallbackEventQueue<IGnssMeasurementCallback_2_1::GnssData> measurement_cbq_;
+
+ GnssMeasurementCallback() : measurement_cbq_("measurement"){};
+ virtual ~GnssMeasurementCallback() = default;
+
+ // Methods from V1_0::IGnssMeasurementCallback follow.
+ Return<void> GnssMeasurementCb(const IGnssMeasurementCallback_1_0::GnssData&) override {
+ return Void();
+ }
+
+ // Methods from V1_1::IGnssMeasurementCallback follow.
+ Return<void> gnssMeasurementCb(const IGnssMeasurementCallback_1_1::GnssData&) override {
+ return Void();
+ }
+
+ // Methods from V2_0::IGnssMeasurementCallback follow.
+ Return<void> gnssMeasurementCb_2_0(const IGnssMeasurementCallback_2_0::GnssData&) override {
+ return Void();
+ }
+
+ // Methods from V2_1::IGnssMeasurementCallback follow.
+ Return<void> gnssMeasurementCb_2_1(const IGnssMeasurementCallback_2_1::GnssData&) override;
+ };
+
+ /*
+ * SetUpGnssCallback:
+ * Set GnssCallback and verify the result.
+ */
+ void SetUpGnssCallback();
+
+ /*
+ * StartAndCheckFirstLocation:
+ * Helper function to start location, and check the first one.
+ *
+ * <p> Note this leaves the Location request active, to enable Stop call vs. other call
+ * reordering tests.
+ *
+ * returns true if a location was successfully generated
+ */
+ bool StartAndCheckFirstLocation();
+
+ /*
+ * CheckLocation:
+ * Helper function to vet Location fields
+ *
+ * check_speed: true if speed related fields are also verified.
+ */
+ void CheckLocation(const GnssLocation_2_0& location, const bool check_speed);
+
+ /*
+ * StartAndCheckLocations:
+ * Helper function to collect, and check a number of
+ * normal ~1Hz locations.
+ *
+ * Note this leaves the Location request active, to enable Stop call vs. other call
+ * reordering tests.
+ */
+ void StartAndCheckLocations(int count);
+
+ /*
+ * StopAndClearLocations:
+ * Helper function to stop locations, and clear any remaining notifications
+ */
+ void StopAndClearLocations();
+
+ /*
+ * SetPositionMode:
+ * Helper function to set positioning mode and verify output
+ */
+ void SetPositionMode(const int min_interval_msec, const bool low_power_mode);
+
+ /*
+ * startLocationAndGetNonGpsConstellation:
+ * 1. Start location
+ * 2. Find and return first non-GPS constellation
+ *
+ * Note that location is not stopped in this method. The client should call
+ * StopAndClearLocations() after the call.
+ */
+ GnssConstellationType startLocationAndGetNonGpsConstellation(
+ const int locations_to_await, const int gnss_sv_info_list_timeout);
+
+ sp<IGnss> gnss_hal_; // GNSS HAL to call into
+ sp<GnssCallback> gnss_cb_; // Primary callback interface
+};
+
+#endif // GNSS_HAL_TEST_H_
diff --git a/gnss/2.1/vts/functional/gnss_hal_test_cases.cpp b/gnss/2.1/vts/functional/gnss_hal_test_cases.cpp
new file mode 100644
index 0000000..2c51717
--- /dev/null
+++ b/gnss/2.1/vts/functional/gnss_hal_test_cases.cpp
@@ -0,0 +1,536 @@
+/*
+ * Copyright (C) 2019 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 "GnssHalTestCases"
+
+#include <gnss_hal_test.h>
+#include "Utils.h"
+
+#include <gtest/gtest.h>
+
+using android::hardware::hidl_string;
+using android::hardware::hidl_vec;
+
+using android::hardware::gnss::common::Utils;
+
+using IGnssMeasurement_2_1 = android::hardware::gnss::V2_1::IGnssMeasurement;
+using IGnssMeasurement_2_0 = android::hardware::gnss::V2_0::IGnssMeasurement;
+using IGnssMeasurement_1_1 = android::hardware::gnss::V1_1::IGnssMeasurement;
+using IGnssMeasurement_1_0 = android::hardware::gnss::V1_0::IGnssMeasurement;
+using IGnssConfiguration_2_1 = android::hardware::gnss::V2_1::IGnssConfiguration;
+using IGnssConfiguration_2_0 = android::hardware::gnss::V2_0::IGnssConfiguration;
+using IGnssConfiguration_1_1 = android::hardware::gnss::V1_1::IGnssConfiguration;
+using IGnssConfiguration_1_0 = android::hardware::gnss::V1_0::IGnssConfiguration;
+
+using android::hardware::gnss::V2_0::GnssConstellationType;
+using android::hardware::gnss::V2_1::IGnssConfiguration;
+
+/*
+ * SetupTeardownCreateCleanup:
+ * Requests the gnss HAL then calls cleanup
+ *
+ * Empty test fixture to verify basic Setup & Teardown
+ */
+TEST_P(GnssHalTest, SetupTeardownCreateCleanup) {}
+
+/*
+ * TestGnssMeasurementExtension:
+ * Gets the GnssMeasurementExtension and verifies that it returns an actual extension.
+ */
+TEST_P(GnssHalTest, TestGnssMeasurementExtension) {
+ auto gnssMeasurement_2_1 = gnss_hal_->getExtensionGnssMeasurement_2_1();
+ auto gnssMeasurement_2_0 = gnss_hal_->getExtensionGnssMeasurement_2_0();
+ auto gnssMeasurement_1_1 = gnss_hal_->getExtensionGnssMeasurement_1_1();
+ auto gnssMeasurement_1_0 = gnss_hal_->getExtensionGnssMeasurement();
+ ASSERT_TRUE(gnssMeasurement_2_1.isOk() && gnssMeasurement_2_0.isOk() &&
+ gnssMeasurement_1_1.isOk() && gnssMeasurement_1_0.isOk());
+ sp<IGnssMeasurement_2_1> iGnssMeas_2_1 = gnssMeasurement_2_1;
+ sp<IGnssMeasurement_2_0> iGnssMeas_2_0 = gnssMeasurement_2_0;
+ sp<IGnssMeasurement_1_1> iGnssMeas_1_1 = gnssMeasurement_1_1;
+ sp<IGnssMeasurement_1_0> iGnssMeas_1_0 = gnssMeasurement_1_0;
+ // At least one interface is non-null.
+ int numNonNull = (int)(iGnssMeas_2_1 != nullptr) + (int)(iGnssMeas_2_0 != nullptr) +
+ (int)(iGnssMeas_1_1 != nullptr) + (int)(iGnssMeas_1_0 != nullptr);
+ ASSERT_TRUE(numNonNull >= 1);
+}
+
+/*
+ * TestGnssConfigurationExtension:
+ * Gets the GnssConfigurationExtension and verifies that it returns an actual extension.
+ */
+TEST_P(GnssHalTest, TestGnssConfigurationExtension) {
+ auto gnssConfiguration_2_1 = gnss_hal_->getExtensionGnssConfiguration_2_1();
+ auto gnssConfiguration_2_0 = gnss_hal_->getExtensionGnssConfiguration_2_0();
+ auto gnssConfiguration_1_1 = gnss_hal_->getExtensionGnssConfiguration_1_1();
+ auto gnssConfiguration_1_0 = gnss_hal_->getExtensionGnssConfiguration();
+ ASSERT_TRUE(gnssConfiguration_2_1.isOk() && gnssConfiguration_2_0.isOk() &&
+ gnssConfiguration_1_1.isOk() && gnssConfiguration_1_0.isOk());
+ sp<IGnssConfiguration_2_1> iGnssConfig_2_1 = gnssConfiguration_2_1;
+ sp<IGnssConfiguration_2_0> iGnssConfig_2_0 = gnssConfiguration_2_0;
+ sp<IGnssConfiguration_1_1> iGnssConfig_1_1 = gnssConfiguration_1_1;
+ sp<IGnssConfiguration_1_0> iGnssConfig_1_0 = gnssConfiguration_1_0;
+ // At least one interface is non-null.
+ int numNonNull = (int)(iGnssConfig_2_1 != nullptr) + (int)(iGnssConfig_2_0 != nullptr) +
+ (int)(iGnssConfig_1_1 != nullptr) + (int)(iGnssConfig_1_0 != nullptr);
+ ASSERT_TRUE(numNonNull >= 1);
+}
+
+/*
+ * TestGnssMeasurementFields:
+ * Sets a GnssMeasurementCallback, waits for a measurement, and verifies
+ * 1. basebandCN0DbHz is valid
+ */
+TEST_P(GnssHalTest, TestGnssMeasurementFields) {
+ const int kFirstGnssMeasurementTimeoutSeconds = 10;
+
+ auto gnssMeasurement = gnss_hal_->getExtensionGnssMeasurement_2_1();
+ ASSERT_TRUE(gnssMeasurement.isOk());
+
+ // Skip test if GnssMeasurement v2.1 is not supported
+ sp<IGnssMeasurement_2_1> iGnssMeasurement = gnssMeasurement;
+ if (iGnssMeasurement == nullptr) {
+ return;
+ }
+
+ sp<GnssMeasurementCallback> callback = new GnssMeasurementCallback();
+ auto result = iGnssMeasurement->setCallback_2_1(callback, /* enableFullTracking= */ true);
+ ASSERT_TRUE(result.isOk());
+ EXPECT_EQ(result, IGnssMeasurement_1_0::GnssMeasurementStatus::SUCCESS);
+
+ IGnssMeasurementCallback_2_1::GnssData lastMeasurement;
+ ASSERT_TRUE(callback->measurement_cbq_.retrieve(lastMeasurement,
+ kFirstGnssMeasurementTimeoutSeconds));
+ EXPECT_EQ(callback->measurement_cbq_.calledCount(), 1);
+ ASSERT_TRUE(lastMeasurement.measurements.size() > 0);
+ for (auto measurement : lastMeasurement.measurements) {
+ // Verify basebandCn0DbHz is valid.
+ ASSERT_TRUE(measurement.basebandCN0DbHz > 0.0 && measurement.basebandCN0DbHz <= 65.0);
+ }
+
+ iGnssMeasurement->close();
+}
+
+/*
+ * TestGnssSvInfoFields:
+ * Gets 1 location and a GnssSvInfo, and verifies
+ * 1. basebandCN0DbHz is valid.
+ */
+TEST_P(GnssHalTest, TestGnssSvInfoFields) {
+ gnss_cb_->location_cbq_.reset();
+ StartAndCheckFirstLocation();
+ int location_called_count = gnss_cb_->location_cbq_.calledCount();
+
+ // Tolerate 1 less sv status to handle edge cases in reporting.
+ int sv_info_list_cbq_size = gnss_cb_->sv_info_list_cbq_.size();
+ EXPECT_GE(sv_info_list_cbq_size, 0);
+ ALOGD("Observed %d GnssSvStatus, while awaiting one location (%d received)",
+ sv_info_list_cbq_size, location_called_count);
+
+ hidl_vec<IGnssCallback_2_1::GnssSvInfo> last_sv_info_list;
+ ASSERT_TRUE(gnss_cb_->sv_info_list_cbq_.retrieve(last_sv_info_list, 1));
+
+ bool nonZeroCn0Found = false;
+ for (auto sv_info : last_sv_info_list) {
+ ASSERT_TRUE(sv_info.basebandCN0DbHz >= 0.0 && sv_info.basebandCN0DbHz <= 65.0);
+ if (sv_info.basebandCN0DbHz > 0.0) {
+ nonZeroCn0Found = true;
+ }
+ }
+ // Assert at least one value is non-zero. Zero is ok in status as it's possibly
+ // reporting a searched but not found satellite.
+ ASSERT_TRUE(nonZeroCn0Found);
+ StopAndClearLocations();
+}
+
+/*
+ * FindStrongFrequentNonGpsSource:
+ *
+ * Search through a GnssSvStatus list for the strongest non-GPS satellite observed enough times
+ *
+ * returns the strongest source,
+ * or a source with constellation == UNKNOWN if none are found sufficient times
+ * TODO(skz): create a template for this to reduce code duplication of v2.1 and v2.0 since both
+ * are using vectors.
+ */
+IGnssConfiguration::BlacklistedSource FindStrongFrequentNonGpsSource(
+ const std::list<hidl_vec<IGnssCallback_2_1::GnssSvInfo>> sv_info_list,
+ const int min_observations) {
+ struct ComparableBlacklistedSource {
+ IGnssConfiguration::BlacklistedSource id;
+
+ ComparableBlacklistedSource() {
+ id.constellation = GnssConstellationType::UNKNOWN;
+ id.svid = 0;
+ }
+
+ bool operator<(const ComparableBlacklistedSource& compare) const {
+ return ((id.svid < compare.id.svid) || ((id.svid == compare.id.svid) &&
+ (id.constellation < compare.id.constellation)));
+ }
+ };
+
+ struct SignalCounts {
+ int observations;
+ float max_cn0_dbhz;
+ };
+
+ std::map<ComparableBlacklistedSource, SignalCounts> mapSignals;
+
+ for (const auto& sv_info_vec : sv_info_list) {
+ for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
+ const auto& gnss_sv = sv_info_vec[iSv];
+ if ((gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX) &&
+ (gnss_sv.v2_0.constellation != GnssConstellationType::GPS)) {
+ ComparableBlacklistedSource source;
+ source.id.svid = gnss_sv.v2_0.v1_0.svid;
+ source.id.constellation = gnss_sv.v2_0.constellation;
+
+ const auto& itSignal = mapSignals.find(source);
+ if (itSignal == mapSignals.end()) {
+ SignalCounts counts;
+ counts.observations = 1;
+ counts.max_cn0_dbhz = gnss_sv.v2_0.v1_0.cN0Dbhz;
+ mapSignals.insert(
+ std::pair<ComparableBlacklistedSource, SignalCounts>(source, counts));
+ } else {
+ itSignal->second.observations++;
+ if (itSignal->second.max_cn0_dbhz < gnss_sv.v2_0.v1_0.cN0Dbhz) {
+ itSignal->second.max_cn0_dbhz = gnss_sv.v2_0.v1_0.cN0Dbhz;
+ }
+ }
+ }
+ }
+ }
+
+ float max_cn0_dbhz_with_sufficient_count = 0.;
+ int total_observation_count = 0;
+ int blacklisted_source_count_observation = 0;
+
+ ComparableBlacklistedSource source_to_blacklist; // initializes to zero = UNKNOWN constellation
+ for (auto const& pairSignal : mapSignals) {
+ total_observation_count += pairSignal.second.observations;
+ if ((pairSignal.second.observations >= min_observations) &&
+ (pairSignal.second.max_cn0_dbhz > max_cn0_dbhz_with_sufficient_count)) {
+ source_to_blacklist = pairSignal.first;
+ blacklisted_source_count_observation = pairSignal.second.observations;
+ max_cn0_dbhz_with_sufficient_count = pairSignal.second.max_cn0_dbhz;
+ }
+ }
+ ALOGD("Among %d observations, chose svid %d, constellation %d, "
+ "with %d observations at %.1f max CNo",
+ total_observation_count, source_to_blacklist.id.svid,
+ (int)source_to_blacklist.id.constellation, blacklisted_source_count_observation,
+ max_cn0_dbhz_with_sufficient_count);
+
+ return source_to_blacklist.id;
+}
+
+/*
+ * BlacklistIndividualSatellites:
+ *
+ * 1) Turns on location, waits for 3 locations, ensuring they are valid, and checks corresponding
+ * GnssStatus for common satellites (strongest and one other.)
+ * 2a & b) Turns off location, and blacklists common satellites.
+ * 3) Restart location, wait for 3 locations, ensuring they are valid, and checks corresponding
+ * GnssStatus does not use those satellites.
+ * 4a & b) Turns off location, and send in empty blacklist.
+ * 5a) Restart location, wait for 3 locations, ensuring they are valid, and checks corresponding
+ * GnssStatus does re-use at least the previously strongest satellite
+ * 5b) Retry a few times, in case GNSS search strategy takes a while to reacquire even the
+ * formerly strongest satellite
+ */
+TEST_P(GnssHalTest, BlacklistIndividualSatellites) {
+ const int kLocationsToAwait = 3;
+ const int kRetriesToUnBlacklist = 10;
+
+ gnss_cb_->location_cbq_.reset();
+ StartAndCheckLocations(kLocationsToAwait);
+ int location_called_count = gnss_cb_->location_cbq_.calledCount();
+
+ // Tolerate 1 less sv status to handle edge cases in reporting.
+ int sv_info_list_cbq_size = gnss_cb_->sv_info_list_cbq_.size();
+ EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait);
+ ALOGD("Observed %d GnssSvInfo, while awaiting %d Locations (%d received)",
+ sv_info_list_cbq_size, kLocationsToAwait, location_called_count);
+
+ /*
+ * Identify strongest SV seen at least kLocationsToAwait -1 times
+ * Why -1? To avoid test flakiness in case of (plausible) slight flakiness in strongest signal
+ * observability (one epoch RF null)
+ */
+
+ const int kGnssSvInfoListTimeout = 2;
+ std::list<hidl_vec<IGnssCallback_2_1::GnssSvInfo>> sv_info_vec_list;
+ int count = gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec_list, sv_info_list_cbq_size,
+ kGnssSvInfoListTimeout);
+
+ ASSERT_EQ(count, sv_info_list_cbq_size);
+
+ IGnssConfiguration::BlacklistedSource source_to_blacklist =
+ FindStrongFrequentNonGpsSource(sv_info_vec_list, kLocationsToAwait - 1);
+
+ if (source_to_blacklist.constellation == GnssConstellationType::UNKNOWN) {
+ // Cannot find a non-GPS satellite. Let the test pass.
+ ALOGD("Cannot find a non-GPS satellite. Letting the test pass.");
+ return;
+ }
+
+ // Stop locations, blacklist the common SV
+ StopAndClearLocations();
+
+ auto gnss_configuration_hal_return = gnss_hal_->getExtensionGnssConfiguration_2_1();
+ ASSERT_TRUE(gnss_configuration_hal_return.isOk());
+ sp<IGnssConfiguration> gnss_configuration_hal = gnss_configuration_hal_return;
+ ASSERT_NE(gnss_configuration_hal, nullptr);
+
+ hidl_vec<IGnssConfiguration::BlacklistedSource> sources;
+ sources.resize(1);
+ sources[0] = source_to_blacklist;
+
+ auto result = gnss_configuration_hal->setBlacklist_2_1(sources);
+ ASSERT_TRUE(result.isOk());
+ EXPECT_TRUE(result);
+
+ // retry and ensure satellite not used
+ gnss_cb_->sv_info_list_cbq_.reset();
+
+ gnss_cb_->location_cbq_.reset();
+ StartAndCheckLocations(kLocationsToAwait);
+
+ // early exit if test is being run with insufficient signal
+ location_called_count = gnss_cb_->location_cbq_.calledCount();
+ if (location_called_count == 0) {
+ ALOGE("0 Gnss locations received - ensure sufficient signal and retry");
+ }
+ ASSERT_TRUE(location_called_count > 0);
+
+ // Tolerate 1 less sv status to handle edge cases in reporting.
+ sv_info_list_cbq_size = gnss_cb_->sv_info_list_cbq_.size();
+ EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait);
+ ALOGD("Observed %d GnssSvInfo, while awaiting %d Locations (%d received)",
+ sv_info_list_cbq_size, kLocationsToAwait, location_called_count);
+ for (int i = 0; i < sv_info_list_cbq_size; ++i) {
+ hidl_vec<IGnssCallback_2_1::GnssSvInfo> sv_info_vec;
+ gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
+ for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
+ const auto& gnss_sv = sv_info_vec[iSv];
+ EXPECT_FALSE((gnss_sv.v2_0.v1_0.svid == source_to_blacklist.svid) &&
+ (gnss_sv.v2_0.constellation == source_to_blacklist.constellation) &&
+ (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
+ }
+ }
+
+ // clear blacklist and restart - this time updating the blacklist while location is still on
+ sources.resize(0);
+
+ result = gnss_configuration_hal->setBlacklist_2_1(sources);
+ ASSERT_TRUE(result.isOk());
+ EXPECT_TRUE(result);
+
+ bool strongest_sv_is_reobserved = false;
+ // do several loops awaiting a few locations, allowing non-immediate reacquisition strategies
+ int unblacklist_loops_remaining = kRetriesToUnBlacklist;
+ while (!strongest_sv_is_reobserved && (unblacklist_loops_remaining-- > 0)) {
+ StopAndClearLocations();
+ gnss_cb_->sv_info_list_cbq_.reset();
+
+ gnss_cb_->location_cbq_.reset();
+ StartAndCheckLocations(kLocationsToAwait);
+
+ // early exit loop if test is being run with insufficient signal
+ location_called_count = gnss_cb_->location_cbq_.calledCount();
+ if (location_called_count == 0) {
+ ALOGE("0 Gnss locations received - ensure sufficient signal and retry");
+ }
+ ASSERT_TRUE(location_called_count > 0);
+
+ // Tolerate 1 less sv status to handle edge cases in reporting.
+ sv_info_list_cbq_size = gnss_cb_->sv_info_list_cbq_.size();
+ EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait);
+ ALOGD("Clear blacklist, observed %d GnssSvInfo, while awaiting %d Locations"
+ ", tries remaining %d",
+ sv_info_list_cbq_size, kLocationsToAwait, unblacklist_loops_remaining);
+
+ for (int i = 0; i < sv_info_list_cbq_size; ++i) {
+ hidl_vec<IGnssCallback_2_1::GnssSvInfo> sv_info_vec;
+ gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
+ for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
+ const auto& gnss_sv = sv_info_vec[iSv];
+ if ((gnss_sv.v2_0.v1_0.svid == source_to_blacklist.svid) &&
+ (gnss_sv.v2_0.constellation == source_to_blacklist.constellation) &&
+ (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX)) {
+ strongest_sv_is_reobserved = true;
+ break;
+ }
+ }
+ if (strongest_sv_is_reobserved) break;
+ }
+ }
+ EXPECT_TRUE(strongest_sv_is_reobserved);
+ StopAndClearLocations();
+}
+
+/*
+ * BlacklistConstellationLocationOff:
+ *
+ * 1) Turns on location, waits for 3 locations, ensuring they are valid, and checks corresponding
+ * GnssStatus for any non-GPS constellations.
+ * 2a & b) Turns off location, and blacklist first non-GPS constellations.
+ * 3) Restart location, wait for 3 locations, ensuring they are valid, and checks corresponding
+ * GnssStatus does not use any constellation but GPS.
+ * 4a & b) Clean up by turning off location, and send in empty blacklist.
+ */
+TEST_P(GnssHalTest, BlacklistConstellationLocationOff) {
+ const int kLocationsToAwait = 3;
+ const int kGnssSvInfoListTimeout = 2;
+
+ // Find first non-GPS constellation to blacklist
+ GnssConstellationType constellation_to_blacklist =
+ startLocationAndGetNonGpsConstellation(kLocationsToAwait, kGnssSvInfoListTimeout);
+
+ // Turns off location
+ StopAndClearLocations();
+
+ IGnssConfiguration::BlacklistedSource source_to_blacklist_1;
+ source_to_blacklist_1.constellation = constellation_to_blacklist;
+ source_to_blacklist_1.svid = 0; // documented wildcard for all satellites in this constellation
+
+ // IRNSS was added in 2.0. Always attempt to blacklist IRNSS to verify that the new enum is
+ // supported.
+ IGnssConfiguration::BlacklistedSource source_to_blacklist_2;
+ source_to_blacklist_2.constellation = GnssConstellationType::IRNSS;
+ source_to_blacklist_2.svid = 0; // documented wildcard for all satellites in this constellation
+
+ auto gnss_configuration_hal_return = gnss_hal_->getExtensionGnssConfiguration_2_1();
+ ASSERT_TRUE(gnss_configuration_hal_return.isOk());
+ sp<IGnssConfiguration> gnss_configuration_hal = gnss_configuration_hal_return;
+ ASSERT_NE(gnss_configuration_hal, nullptr);
+
+ hidl_vec<IGnssConfiguration::BlacklistedSource> sources;
+ sources.resize(2);
+ sources[0] = source_to_blacklist_1;
+ sources[1] = source_to_blacklist_2;
+
+ auto result = gnss_configuration_hal->setBlacklist_2_1(sources);
+ ASSERT_TRUE(result.isOk());
+ EXPECT_TRUE(result);
+
+ // retry and ensure constellation not used
+ gnss_cb_->sv_info_list_cbq_.reset();
+
+ gnss_cb_->location_cbq_.reset();
+ StartAndCheckLocations(kLocationsToAwait);
+
+ // Tolerate 1 less sv status to handle edge cases in reporting.
+ int sv_info_list_cbq_size = gnss_cb_->sv_info_list_cbq_.size();
+ EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait);
+ ALOGD("Observed %d GnssSvInfo, while awaiting %d Locations", sv_info_list_cbq_size,
+ kLocationsToAwait);
+ for (int i = 0; i < sv_info_list_cbq_size; ++i) {
+ hidl_vec<IGnssCallback_2_1::GnssSvInfo> sv_info_vec;
+ gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
+ for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
+ const auto& gnss_sv = sv_info_vec[iSv];
+ EXPECT_FALSE((gnss_sv.v2_0.constellation == source_to_blacklist_1.constellation) &&
+ (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
+ EXPECT_FALSE((gnss_sv.v2_0.constellation == source_to_blacklist_2.constellation) &&
+ (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
+ }
+ }
+
+ // clean up
+ StopAndClearLocations();
+ sources.resize(0);
+ result = gnss_configuration_hal->setBlacklist_2_1(sources);
+ ASSERT_TRUE(result.isOk());
+ EXPECT_TRUE(result);
+}
+
+/*
+ * BlacklistConstellationLocationOn:
+ *
+ * 1) Turns on location, waits for 3 locations, ensuring they are valid, and checks corresponding
+ * GnssStatus for any non-GPS constellations.
+ * 2a & b) Blacklist first non-GPS constellation, and turn off location.
+ * 3) Restart location, wait for 3 locations, ensuring they are valid, and checks corresponding
+ * GnssStatus does not use any constellation but GPS.
+ * 4a & b) Clean up by turning off location, and send in empty blacklist.
+ */
+TEST_P(GnssHalTest, BlacklistConstellationLocationOn) {
+ const int kLocationsToAwait = 3;
+ const int kGnssSvInfoListTimeout = 2;
+
+ // Find first non-GPS constellation to blacklist
+ GnssConstellationType constellation_to_blacklist =
+ startLocationAndGetNonGpsConstellation(kLocationsToAwait, kGnssSvInfoListTimeout);
+
+ IGnssConfiguration::BlacklistedSource source_to_blacklist_1;
+ source_to_blacklist_1.constellation = constellation_to_blacklist;
+ source_to_blacklist_1.svid = 0; // documented wildcard for all satellites in this constellation
+
+ // IRNSS was added in 2.0. Always attempt to blacklist IRNSS to verify that the new enum is
+ // supported.
+ IGnssConfiguration::BlacklistedSource source_to_blacklist_2;
+ source_to_blacklist_2.constellation = GnssConstellationType::IRNSS;
+ source_to_blacklist_2.svid = 0; // documented wildcard for all satellites in this constellation
+
+ auto gnss_configuration_hal_return = gnss_hal_->getExtensionGnssConfiguration_2_1();
+ ASSERT_TRUE(gnss_configuration_hal_return.isOk());
+ sp<IGnssConfiguration> gnss_configuration_hal = gnss_configuration_hal_return;
+ ASSERT_NE(gnss_configuration_hal, nullptr);
+
+ hidl_vec<IGnssConfiguration::BlacklistedSource> sources;
+ sources.resize(2);
+ sources[0] = source_to_blacklist_1;
+ sources[1] = source_to_blacklist_2;
+
+ auto result = gnss_configuration_hal->setBlacklist_2_1(sources);
+ ASSERT_TRUE(result.isOk());
+ EXPECT_TRUE(result);
+
+ // Turns off location
+ StopAndClearLocations();
+
+ // retry and ensure constellation not used
+ gnss_cb_->sv_info_list_cbq_.reset();
+
+ gnss_cb_->location_cbq_.reset();
+ StartAndCheckLocations(kLocationsToAwait);
+
+ // Tolerate 1 less sv status to handle edge cases in reporting.
+ int sv_info_list_cbq_size = gnss_cb_->sv_info_list_cbq_.size();
+ EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait);
+ ALOGD("Observed %d GnssSvInfo, while awaiting %d Locations", sv_info_list_cbq_size,
+ kLocationsToAwait);
+ for (int i = 0; i < sv_info_list_cbq_size; ++i) {
+ hidl_vec<IGnssCallback_2_1::GnssSvInfo> sv_info_vec;
+ gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
+ for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
+ const auto& gnss_sv = sv_info_vec[iSv];
+ EXPECT_FALSE((gnss_sv.v2_0.constellation == source_to_blacklist_1.constellation) &&
+ (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
+ EXPECT_FALSE((gnss_sv.v2_0.constellation == source_to_blacklist_2.constellation) &&
+ (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
+ }
+ }
+
+ // clean up
+ StopAndClearLocations();
+ sources.resize(0);
+ result = gnss_configuration_hal->setBlacklist_2_1(sources);
+ ASSERT_TRUE(result.isOk());
+ EXPECT_TRUE(result);
+}
\ No newline at end of file
diff --git a/gnss/common/utils/default/Android.bp b/gnss/common/utils/default/Android.bp
index 4ea97fa..577f6ae 100644
--- a/gnss/common/utils/default/Android.bp
+++ b/gnss/common/utils/default/Android.bp
@@ -28,6 +28,10 @@
],
export_include_dirs: ["include"],
shared_libs: [
+ "libhidlbase",
+ "libutils",
"android.hardware.gnss@1.0",
+ "android.hardware.gnss@2.0",
+ "android.hardware.gnss@2.1",
],
}
diff --git a/gnss/common/utils/default/Utils.cpp b/gnss/common/utils/default/Utils.cpp
index b9a06e8..ccb91b1 100644
--- a/gnss/common/utils/default/Utils.cpp
+++ b/gnss/common/utils/default/Utils.cpp
@@ -16,6 +16,7 @@
#include <Constants.h>
#include <Utils.h>
+#include <utils/SystemClock.h>
namespace android {
namespace hardware {
@@ -23,31 +24,193 @@
namespace common {
using GnssSvFlags = V1_0::IGnssCallback::GnssSvFlags;
+using GnssMeasurementFlags = V1_0::IGnssMeasurementCallback::GnssMeasurementFlags;
+using GnssMeasurementStateV2_0 = V2_0::IGnssMeasurementCallback::GnssMeasurementState;
+using ElapsedRealtime = V2_0::ElapsedRealtime;
+using ElapsedRealtimeFlags = V2_0::ElapsedRealtimeFlags;
+using GnssConstellationTypeV2_0 = V2_0::GnssConstellationType;
+using IGnssMeasurementCallbackV2_0 = V2_0::IGnssMeasurementCallback;
-GnssLocation Utils::getMockLocation() {
- GnssLocation location = {.gnssLocationFlags = 0xFF,
- .latitudeDegrees = kMockLatitudeDegrees,
- .longitudeDegrees = kMockLongitudeDegrees,
- .altitudeMeters = kMockAltitudeMeters,
- .speedMetersPerSec = kMockSpeedMetersPerSec,
- .bearingDegrees = kMockBearingDegrees,
- .horizontalAccuracyMeters = kMockHorizontalAccuracyMeters,
- .verticalAccuracyMeters = kMockVerticalAccuracyMeters,
- .speedAccuracyMetersPerSecond = kMockSpeedAccuracyMetersPerSecond,
- .bearingAccuracyDegrees = kMockBearingAccuracyDegrees,
- .timestamp = kMockTimestamp};
+GnssDataV2_1 Utils::getMockMeasurementV2_1() {
+ GnssDataV2_0 gnssDataV2_0 = Utils::getMockMeasurementV2_0();
+ V2_1::IGnssMeasurementCallback::GnssMeasurement gnssMeasurementV2_1 = {
+ .v2_0 = gnssDataV2_0.measurements[0],
+ .basebandCN0DbHz = 25.0,
+ };
+ hidl_vec<V2_1::IGnssMeasurementCallback::GnssMeasurement> measurements(1);
+ measurements[0] = gnssMeasurementV2_1;
+ GnssDataV2_1 gnssDataV2_1 = {
+ .measurements = measurements,
+ .clock = gnssDataV2_0.clock,
+ .elapsedRealtime = gnssDataV2_0.elapsedRealtime,
+ };
+ return gnssDataV2_1;
+}
+
+GnssDataV2_0 Utils::getMockMeasurementV2_0() {
+ V1_0::IGnssMeasurementCallback::GnssMeasurement measurement_1_0 = {
+ .flags = (uint32_t)GnssMeasurementFlags::HAS_CARRIER_FREQUENCY,
+ .svid = (int16_t)6,
+ .constellation = V1_0::GnssConstellationType::UNKNOWN,
+ .timeOffsetNs = 0.0,
+ .receivedSvTimeInNs = 8195997131077,
+ .receivedSvTimeUncertaintyInNs = 15,
+ .cN0DbHz = 30.0,
+ .pseudorangeRateMps = -484.13739013671875,
+ .pseudorangeRateUncertaintyMps = 1.0379999876022339,
+ .accumulatedDeltaRangeState = (uint32_t)V1_0::IGnssMeasurementCallback::
+ GnssAccumulatedDeltaRangeState::ADR_STATE_UNKNOWN,
+ .accumulatedDeltaRangeM = 0.0,
+ .accumulatedDeltaRangeUncertaintyM = 0.0,
+ .carrierFrequencyHz = 1.59975e+09,
+ .multipathIndicator =
+ V1_0::IGnssMeasurementCallback::GnssMultipathIndicator::INDICATOR_UNKNOWN};
+ V1_1::IGnssMeasurementCallback::GnssMeasurement measurement_1_1 = {.v1_0 = measurement_1_0};
+ V2_0::IGnssMeasurementCallback::GnssMeasurement measurement_2_0 = {
+ .v1_1 = measurement_1_1,
+ .codeType = "C",
+ .state = GnssMeasurementStateV2_0::STATE_CODE_LOCK |
+ GnssMeasurementStateV2_0::STATE_BIT_SYNC |
+ GnssMeasurementStateV2_0::STATE_SUBFRAME_SYNC |
+ GnssMeasurementStateV2_0::STATE_TOW_DECODED |
+ GnssMeasurementStateV2_0::STATE_GLO_STRING_SYNC |
+ GnssMeasurementStateV2_0::STATE_GLO_TOD_DECODED,
+ .constellation = GnssConstellationTypeV2_0::GLONASS,
+ };
+
+ hidl_vec<IGnssMeasurementCallbackV2_0::GnssMeasurement> measurements(1);
+ measurements[0] = measurement_2_0;
+ V1_0::IGnssMeasurementCallback::GnssClock clock = {.timeNs = 2713545000000,
+ .fullBiasNs = -1226701900521857520,
+ .biasNs = 0.59689998626708984,
+ .biasUncertaintyNs = 47514.989972114563,
+ .driftNsps = -51.757811607455452,
+ .driftUncertaintyNsps = 310.64968328491528,
+ .hwClockDiscontinuityCount = 1};
+
+ ElapsedRealtime timestamp = {
+ .flags = ElapsedRealtimeFlags::HAS_TIMESTAMP_NS |
+ ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS,
+ .timestampNs = static_cast<uint64_t>(::android::elapsedRealtimeNano()),
+ // This is an hardcoded value indicating a 1ms of uncertainty between the two clocks.
+ // In an actual implementation provide an estimate of the synchronization uncertainty
+ // or don't set the field.
+ .timeUncertaintyNs = 1000000};
+
+ GnssDataV2_0 gnssData = {
+ .measurements = measurements, .clock = clock, .elapsedRealtime = timestamp};
+ return gnssData;
+}
+
+V2_0::GnssLocation Utils::getMockLocationV2_0() {
+ const V2_0::ElapsedRealtime timestamp = {
+ .flags = V2_0::ElapsedRealtimeFlags::HAS_TIMESTAMP_NS |
+ V2_0::ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS,
+ .timestampNs = static_cast<uint64_t>(::android::elapsedRealtimeNano()),
+ // This is an hardcoded value indicating a 1ms of uncertainty between the two clocks.
+ // In an actual implementation provide an estimate of the synchronization uncertainty
+ // or don't set the field.
+ .timeUncertaintyNs = 1000000};
+
+ V2_0::GnssLocation location = {.v1_0 = Utils::getMockLocationV1_0(),
+ .elapsedRealtime = timestamp};
return location;
}
-GnssSvInfo Utils::getSvInfo(int16_t svid, GnssConstellationType type, float cN0DbHz,
- float elevationDegrees, float azimuthDegrees) {
- GnssSvInfo svInfo = {.svid = svid,
- .constellation = type,
- .cN0Dbhz = cN0DbHz,
- .elevationDegrees = elevationDegrees,
- .azimuthDegrees = azimuthDegrees,
- .svFlag = GnssSvFlags::USED_IN_FIX | GnssSvFlags::HAS_EPHEMERIS_DATA |
- GnssSvFlags::HAS_ALMANAC_DATA};
+V1_0::GnssLocation Utils::getMockLocationV1_0() {
+ V1_0::GnssLocation location = {
+ .gnssLocationFlags = 0xFF,
+ .latitudeDegrees = kMockLatitudeDegrees,
+ .longitudeDegrees = kMockLongitudeDegrees,
+ .altitudeMeters = kMockAltitudeMeters,
+ .speedMetersPerSec = kMockSpeedMetersPerSec,
+ .bearingDegrees = kMockBearingDegrees,
+ .horizontalAccuracyMeters = kMockHorizontalAccuracyMeters,
+ .verticalAccuracyMeters = kMockVerticalAccuracyMeters,
+ .speedAccuracyMetersPerSecond = kMockSpeedAccuracyMetersPerSecond,
+ .bearingAccuracyDegrees = kMockBearingAccuracyDegrees,
+ .timestamp = kMockTimestamp};
+ return location;
+}
+
+hidl_vec<GnssSvInfoV2_1> Utils::getMockSvInfoListV2_1() {
+ GnssSvInfoV1_0 gnssSvInfoV1_0 =
+ Utils::getMockSvInfoV1_0(3, V1_0::GnssConstellationType::GPS, 32.5, 59.1, 166.5);
+ GnssSvInfoV2_0 gnssSvInfoV2_0 =
+ Utils::getMockSvInfoV2_0(gnssSvInfoV1_0, V2_0::GnssConstellationType::GPS);
+ hidl_vec<GnssSvInfoV2_1> gnssSvInfoList = {
+ Utils::getMockSvInfoV2_1(gnssSvInfoV2_0, 27.5),
+ getMockSvInfoV2_1(
+ getMockSvInfoV2_0(getMockSvInfoV1_0(5, V1_0::GnssConstellationType::GPS, 27.0,
+ 29.0, 56.5),
+ V2_0::GnssConstellationType::GPS),
+ 22.0),
+ getMockSvInfoV2_1(
+ getMockSvInfoV2_0(getMockSvInfoV1_0(17, V1_0::GnssConstellationType::GPS, 30.5,
+ 71.0, 77.0),
+ V2_0::GnssConstellationType::GPS),
+ 25.5),
+ getMockSvInfoV2_1(
+ getMockSvInfoV2_0(getMockSvInfoV1_0(26, V1_0::GnssConstellationType::GPS, 24.1,
+ 28.0, 253.0),
+ V2_0::GnssConstellationType::GPS),
+ 19.1),
+ getMockSvInfoV2_1(
+ getMockSvInfoV2_0(getMockSvInfoV1_0(5, V1_0::GnssConstellationType::GLONASS,
+ 20.5, 11.5, 116.0),
+ V2_0::GnssConstellationType::GLONASS),
+ 15.5),
+ getMockSvInfoV2_1(
+ getMockSvInfoV2_0(getMockSvInfoV1_0(17, V1_0::GnssConstellationType::GLONASS,
+ 21.5, 28.5, 186.0),
+ V2_0::GnssConstellationType::GLONASS),
+ 16.5),
+ getMockSvInfoV2_1(
+ getMockSvInfoV2_0(getMockSvInfoV1_0(18, V1_0::GnssConstellationType::GLONASS,
+ 28.3, 38.8, 69.0),
+ V2_0::GnssConstellationType::GLONASS),
+ 25.3),
+ getMockSvInfoV2_1(
+ getMockSvInfoV2_0(getMockSvInfoV1_0(10, V1_0::GnssConstellationType::GLONASS,
+ 25.0, 66.0, 247.0),
+ V2_0::GnssConstellationType::GLONASS),
+ 20.0),
+ getMockSvInfoV2_1(
+ getMockSvInfoV2_0(getMockSvInfoV1_0(3, V1_0::GnssConstellationType::UNKNOWN,
+ 22.0, 35.0, 112.0),
+ V2_0::GnssConstellationType::IRNSS),
+ 19.7),
+ };
+ return gnssSvInfoList;
+}
+
+GnssSvInfoV2_1 Utils::getMockSvInfoV2_1(GnssSvInfoV2_0 gnssSvInfoV2_0, float basebandCN0DbHz) {
+ GnssSvInfoV2_1 gnssSvInfoV2_1 = {
+ .v2_0 = gnssSvInfoV2_0,
+ .basebandCN0DbHz = basebandCN0DbHz,
+ };
+ return gnssSvInfoV2_1;
+}
+
+GnssSvInfoV2_0 Utils::getMockSvInfoV2_0(GnssSvInfoV1_0 gnssSvInfoV1_0,
+ V2_0::GnssConstellationType type) {
+ GnssSvInfoV2_0 gnssSvInfoV2_0 = {
+ .v1_0 = gnssSvInfoV1_0,
+ .constellation = type,
+ };
+ return gnssSvInfoV2_0;
+}
+
+GnssSvInfoV1_0 Utils::getMockSvInfoV1_0(int16_t svid, V1_0::GnssConstellationType type,
+ float cN0DbHz, float elevationDegrees,
+ float azimuthDegrees) {
+ GnssSvInfoV1_0 svInfo = {.svid = svid,
+ .constellation = type,
+ .cN0Dbhz = cN0DbHz,
+ .elevationDegrees = elevationDegrees,
+ .azimuthDegrees = azimuthDegrees,
+ .svFlag = GnssSvFlags::USED_IN_FIX | GnssSvFlags::HAS_EPHEMERIS_DATA |
+ GnssSvFlags::HAS_ALMANAC_DATA};
return svInfo;
}
diff --git a/gnss/common/utils/default/include/Utils.h b/gnss/common/utils/default/include/Utils.h
index 47c8812..e0c61a4 100644
--- a/gnss/common/utils/default/include/Utils.h
+++ b/gnss/common/utils/default/include/Utils.h
@@ -18,20 +18,34 @@
#define android_hardware_gnss_common_default_Utils_H_
#include <android/hardware/gnss/1.0/IGnss.h>
+#include <android/hardware/gnss/2.0/IGnss.h>
+#include <android/hardware/gnss/2.1/IGnss.h>
-using GnssConstellationType = ::android::hardware::gnss::V1_0::GnssConstellationType;
-using GnssLocation = ::android::hardware::gnss::V1_0::GnssLocation;
-using GnssSvInfo = ::android::hardware::gnss::V1_0::IGnssCallback::GnssSvInfo;
+using ::android::hardware::hidl_vec;
namespace android {
namespace hardware {
namespace gnss {
namespace common {
+using GnssDataV2_0 = V2_0::IGnssMeasurementCallback::GnssData;
+using GnssDataV2_1 = V2_1::IGnssMeasurementCallback::GnssData;
+using GnssSvInfoV1_0 = V1_0::IGnssCallback::GnssSvInfo;
+using GnssSvInfoV2_0 = V2_0::IGnssCallback::GnssSvInfo;
+using GnssSvInfoV2_1 = V2_1::IGnssCallback::GnssSvInfo;
+
struct Utils {
- static GnssLocation getMockLocation();
- static GnssSvInfo getSvInfo(int16_t svid, GnssConstellationType type, float cN0DbHz,
- float elevationDegrees, float azimuthDegrees);
+ static GnssDataV2_0 getMockMeasurementV2_0();
+ static GnssDataV2_1 getMockMeasurementV2_1();
+ static V2_0::GnssLocation getMockLocationV2_0();
+ static V1_0::GnssLocation getMockLocationV1_0();
+ static hidl_vec<GnssSvInfoV2_1> getMockSvInfoListV2_1();
+ static GnssSvInfoV2_1 getMockSvInfoV2_1(GnssSvInfoV2_0 gnssSvInfoV2_0, float basebandCN0DbHz);
+ static GnssSvInfoV2_0 getMockSvInfoV2_0(GnssSvInfoV1_0 gnssSvInfoV1_0,
+ V2_0::GnssConstellationType type);
+ static GnssSvInfoV1_0 getMockSvInfoV1_0(int16_t svid, V1_0::GnssConstellationType type,
+ float cN0DbHz, float elevationDegrees,
+ float azimuthDegrees);
};
} // namespace common
diff --git a/graphics/allocator/4.0/IAllocator.hal b/graphics/allocator/4.0/IAllocator.hal
index 9931685..7934867 100644
--- a/graphics/allocator/4.0/IAllocator.hal
+++ b/graphics/allocator/4.0/IAllocator.hal
@@ -20,14 +20,6 @@
interface IAllocator {
/**
- * Retrieves implementation-defined debug information, which will be
- * displayed during, for example, `dumpsys SurfaceFlinger`.
- *
- * @return debugInfo is a string of debug information.
- */
- dumpDebugInfo() generates (string debugInfo);
-
- /**
* Allocates buffers with the properties specified by the descriptor.
*
* Allocations should be optimized for usage bits provided in the
diff --git a/graphics/common/aidl/Android.bp b/graphics/common/aidl/Android.bp
index e0c7674..fcd4efc 100644
--- a/graphics/common/aidl/Android.bp
+++ b/graphics/common/aidl/Android.bp
@@ -10,6 +10,9 @@
"android/hardware/graphics/common/*.aidl",
],
stability: "vintf",
+ imports: [
+ "vintf-common"
+ ],
backend: {
java: {
enabled: false,
diff --git a/graphics/common/aidl/android/hardware/graphics/common/BufferUsage.aidl b/graphics/common/aidl/android/hardware/graphics/common/BufferUsage.aidl
new file mode 100644
index 0000000..5f9888a
--- /dev/null
+++ b/graphics/common/aidl/android/hardware/graphics/common/BufferUsage.aidl
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2019 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.graphics.common;
+
+/**
+ * Buffer usage definitions.
+ */
+@VintfStability
+@Backing(type="long")
+enum BufferUsage {
+ /** bit 0-3 is an enum */
+ CPU_READ_MASK = 0xf,
+ /** buffer is never read by CPU */
+ CPU_READ_NEVER = 0,
+ /** buffer is rarely read by CPU */
+ CPU_READ_RARELY = 2,
+ /** buffer is often read by CPU */
+ CPU_READ_OFTEN = 3,
+
+ /** bit 4-7 is an enum */
+ CPU_WRITE_MASK = 0xf << 4,
+ /** buffer is never written by CPU */
+ CPU_WRITE_NEVER = 0 << 4,
+ /** buffer is rarely written by CPU */
+ CPU_WRITE_RARELY = 2 << 4,
+ /** buffer is often written by CPU */
+ CPU_WRITE_OFTEN = 3 << 4,
+
+ /** buffer is used as a GPU texture */
+ GPU_TEXTURE = 1 << 8,
+
+ /** buffer is used as a GPU render target */
+ GPU_RENDER_TARGET = 1 << 9,
+
+ /** bit 10 must be zero */
+
+ /** buffer is used as a composer HAL overlay layer */
+ COMPOSER_OVERLAY = 1 << 11,
+ /** buffer is used as a composer HAL client target */
+ COMPOSER_CLIENT_TARGET = 1 << 12,
+
+ /** bit 13 must be zero */
+
+ /**
+ * Buffer is allocated with hardware-level protection against copying the
+ * contents (or information derived from the contents) into unprotected
+ * memory.
+ */
+ PROTECTED = 1 << 14,
+
+ /** buffer is used as a hwcomposer HAL cursor layer */
+ COMPOSER_CURSOR = 1 << 15,
+
+ /** buffer is used as a video encoder input */
+ VIDEO_ENCODER = 1 << 16,
+
+ /** buffer is used as a camera HAL output */
+ CAMERA_OUTPUT = 1 << 17,
+
+ /** buffer is used as a camera HAL input */
+ CAMERA_INPUT = 1 << 18,
+
+ /** bit 19 must be zero */
+
+ /** buffer is used as a renderscript allocation */
+ RENDERSCRIPT = 1 << 20,
+
+ /** bit 21 must be zero */
+
+ /** buffer is used as a video decoder output */
+ VIDEO_DECODER = 1 << 22,
+
+ /** buffer is used as a sensor direct report output */
+ SENSOR_DIRECT_DATA = 1 << 23,
+
+ /** buffer is used as a cube map texture */
+ GPU_CUBE_MAP = 1 << 25,
+
+ /** buffer contains a complete mipmap hierarchy */
+ GPU_MIPMAP_COMPLETE = 1 << 26,
+
+ /**
+ * Buffer is used as input for HEIC encoder.
+ */
+ HW_IMAGE_ENCODER = 1 << 27,
+
+ /**
+ * buffer is used as as an OpenGL shader storage or uniform
+ * buffer object
+ */
+ GPU_DATA_BUFFER = 1 << 24,
+
+ /** bits 25-27 must be zero and are reserved for future versions */
+ /** bits 28-31 are reserved for vendor extensions */
+ VENDOR_MASK = 0xf << 28,
+
+ /** bits 32-47 must be zero and are reserved for future versions */
+ /** bits 48-63 are reserved for vendor extensions */
+ VENDOR_MASK_HI = 0xffff << 48,
+}
diff --git a/graphics/common/aidl/android/hardware/graphics/common/Dataspace.aidl b/graphics/common/aidl/android/hardware/graphics/common/Dataspace.aidl
index 81a21ab..42cdd81 100644
--- a/graphics/common/aidl/android/hardware/graphics/common/Dataspace.aidl
+++ b/graphics/common/aidl/android/hardware/graphics/common/Dataspace.aidl
@@ -208,8 +208,6 @@
*/
STANDARD_ADOBE_RGB = 11 << 16, // 11 << STANDARD_SHIFT
-
-
TRANSFER_SHIFT = 22,
/**
@@ -396,9 +394,7 @@
* The values are encoded using the full range ([0,255] for 8-bit) for all
* components.
*/
- SRGB_LINEAR = 1 << 16 | 1 << 22 | 1 << 27, // deprecated, use V0_SRGB_LINEAR
-
- V0_SRGB_LINEAR = 1 << 16 | 1 << 22 | 1 << 27, // STANDARD_BT709 | TRANSFER_LINEAR | RANGE_FULL
+ SRGB_LINEAR = 1 << 16 | 1 << 22 | 1 << 27, // STANDARD_BT709 | TRANSFER_LINEAR | RANGE_FULL
/**
@@ -413,7 +409,7 @@
* Values beyond the range [0.0 - 1.0] would correspond to other colors
* spaces and/or HDR content.
*/
- V0_SCRGB_LINEAR = 1 << 16 | 1 << 22 | 3 << 27, // STANDARD_BT709 | TRANSFER_LINEAR | RANGE_EXTENDED
+ SCRGB_LINEAR = 1 << 16 | 1 << 22 | 3 << 27, // STANDARD_BT709 | TRANSFER_LINEAR | RANGE_EXTENDED
/**
@@ -429,9 +425,7 @@
*
* Use full range and BT.709 standard.
*/
- SRGB = 1 << 16 | 2 << 22 | 1 << 27, // deprecated, use V0_SRGB
-
- V0_SRGB = 1 << 16 | 2 << 22 | 1 << 27, // STANDARD_BT709 | TRANSFER_SRGB | RANGE_FULL
+ SRGB = 1 << 16 | 2 << 22 | 1 << 27, // STANDARD_BT709 | TRANSFER_SRGB | RANGE_FULL
/**
@@ -446,7 +440,7 @@
* Values beyond the range [0.0 - 1.0] would correspond to other colors
* spaces and/or HDR content.
*/
- V0_SCRGB = 1 << 16 | 2 << 22 | 3 << 27, // STANDARD_BT709 | TRANSFER_SRGB | RANGE_EXTENDED
+ SCRGB = 1 << 16 | 2 << 22 | 3 << 27, // STANDARD_BT709 | TRANSFER_SRGB | RANGE_EXTENDED
/**
* YCbCr Colorspaces
@@ -464,22 +458,18 @@
*
* Same model as BT.601-625, but all values (Y, Cb, Cr) range from 0 to 255
*
- * Use full range, BT.601 transfer and BT.601_625 standard.
+ * Use full range, SMPTE 170M transfer and BT.601_625 standard.
*/
- JFIF = 2 << 16 | 3 << 22 | 1 << 27, // deprecated, use V0_JFIF
-
- V0_JFIF = 2 << 16 | 3 << 22 | 1 << 27, // STANDARD_BT601_625 | TRANSFER_SMPTE_170M | RANGE_FULL
+ JFIF = 2 << 16 | 3 << 22 | 1 << 27, // STANDARD_BT601_625 | TRANSFER_SMPTE_170M | RANGE_FULL
/**
* ITU-R Recommendation 601 (BT.601) - 625-line
*
* Standard-definition television, 625 Lines (PAL)
*
- * Use limited range, BT.601 transfer and BT.601_625 standard.
+ * Use limited range, SMPTE 170M transfer and BT.601_625 standard.
*/
- BT601_625 = 2 << 16 | 3 << 22 | 2 << 27, // deprecated, use V0_BT601_625
-
- V0_BT601_625 = 2 << 16 | 3 << 22 | 2 << 27, // STANDARD_BT601_625 | TRANSFER_SMPTE_170M | RANGE_LIMITED
+ BT601_625 = 2 << 16 | 3 << 22 | 2 << 27, // STANDARD_BT601_625 | TRANSFER_SMPTE_170M | RANGE_LIMITED
/**
@@ -487,22 +477,18 @@
*
* Standard-definition television, 525 Lines (NTSC)
*
- * Use limited range, BT.601 transfer and BT.601_525 standard.
+ * Use limited range, SMPTE 170M transfer and BT.601_525 standard.
*/
- BT601_525 = 4 << 16 | 3 << 22 | 2 << 27, // deprecated, use V0_BT601_525
-
- V0_BT601_525 = 4 << 16 | 3 << 22 | 2 << 27, // STANDARD_BT601_525 | TRANSFER_SMPTE_170M | RANGE_LIMITED
+ BT601_525 = 4 << 16 | 3 << 22 | 2 << 27, // STANDARD_BT601_525 | TRANSFER_SMPTE_170M | RANGE_LIMITED
/**
* ITU-R Recommendation 709 (BT.709)
*
* High-definition television
*
- * Use limited range, BT.709 transfer and BT.709 standard.
+ * Use limited range, SMPTE 170M transfer and BT.709 standard.
*/
- BT709 = 1 << 16 | 3 << 22 | 2 << 27, // deprecated, use V0_BT709
-
- V0_BT709 = 1 << 16 | 3 << 22 | 2 << 27, // STANDARD_BT709 | TRANSFER_SMPTE_170M | RANGE_LIMITED
+ BT709 = 1 << 16 | 3 << 22 | 2 << 27, // STANDARD_BT709 | TRANSFER_SMPTE_170M | RANGE_LIMITED
/**
@@ -570,7 +556,7 @@
*
* Ultra High-definition television
*
- * Use full range, BT.709 transfer and BT2020 standard
+ * Use full range, SMPTE 170M transfer and BT2020 standard
*/
BT2020 = 6 << 16 | 3 << 22 | 1 << 27, // STANDARD_BT2020 | TRANSFER_SMPTE_170M | RANGE_FULL
@@ -622,7 +608,7 @@
*
* Ultra High-definition television
*
- * Use limited range, BT.709 transfer and BT2020 standard
+ * Use limited range, SMPTE 170M transfer and BT2020 standard
*/
BT2020_ITU = 6 << 16 | 3 << 22 | 2 << 27, // STANDARD_BT2020 | TRANSFER_SMPTE_170M | RANGE_LIMITED
@@ -679,4 +665,13 @@
* according to ISO/IEC 23008-12.
*/
HEIF = 0x1004,
+
+ /**
+ * ITU-R Recommendation 709 (BT.709)
+ *
+ * High-definition television
+ *
+ * Use full range, SMPTE 170M transfer and BT.709 standard.
+ */
+ BT709_FULL_RANGE = 1 << 16 | 3 << 22 | 1 << 27, // STANDARD_BT709 | TRANSFER_SMPTE_170M | RANGE_FULL
}
diff --git a/graphics/common/aidl/android/hardware/graphics/common/HardwareBuffer.aidl b/graphics/common/aidl/android/hardware/graphics/common/HardwareBuffer.aidl
new file mode 100644
index 0000000..5a22c0f
--- /dev/null
+++ b/graphics/common/aidl/android/hardware/graphics/common/HardwareBuffer.aidl
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2019 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.graphics.common;
+
+import android.hardware.common.NativeHandle;
+import android.hardware.graphics.common.HardwareBufferDescription;
+
+/**
+ * Stable AIDL counterpart of AHardwareBuffer.
+ *
+ * @note This is different from the public HardwareBuffer.
+ * @sa +ndk libnativewindow#AHardwareBuffer
+ */
+@VintfStability
+parcelable HardwareBuffer {
+ HardwareBufferDescription description;
+ NativeHandle handle;
+}
diff --git a/graphics/common/aidl/android/hardware/graphics/common/HardwareBufferDescription.aidl b/graphics/common/aidl/android/hardware/graphics/common/HardwareBufferDescription.aidl
new file mode 100644
index 0000000..e1e3492
--- /dev/null
+++ b/graphics/common/aidl/android/hardware/graphics/common/HardwareBufferDescription.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2019 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.graphics.common;
+
+import android.hardware.graphics.common.BufferUsage;
+import android.hardware.graphics.common.PixelFormat;
+
+/**
+ * Stable AIDL counterpart of AHardwareBuffer_Desc.
+ *
+ * @sa +ndk libnativewindow#AHardwareBuffer_Desc
+ */
+@VintfStability
+parcelable HardwareBufferDescription {
+ int width;
+ int height;
+ int layers;
+ PixelFormat format;
+ BufferUsage usage;
+ int stride;
+}
diff --git a/graphics/common/aidl/android/hardware/graphics/common/PixelFormat.aidl b/graphics/common/aidl/android/hardware/graphics/common/PixelFormat.aidl
new file mode 100644
index 0000000..4942462
--- /dev/null
+++ b/graphics/common/aidl/android/hardware/graphics/common/PixelFormat.aidl
@@ -0,0 +1,516 @@
+/*
+ * Copyright 2019 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.graphics.common;
+
+/**
+ * Pixel formats for graphics buffers.
+ */
+@VintfStability
+@Backing(type="int")
+enum PixelFormat {
+ /**
+ * This value may be used in an operation where the format is optional.
+ */
+ UNSPECIFIED = 0,
+ /**
+ * 32-bit format that has 8-bit R, G, B, and A components, in that order,
+ * from the lowest memory address to the highest memory address.
+ *
+ * The component values are unsigned normalized to the range [0, 1], whose
+ * interpretation is defined by the dataspace.
+ */
+ RGBA_8888 = 0x1,
+
+ /**
+ * 32-bit format that has 8-bit R, G, B, and unused components, in that
+ * order, from the lowest memory address to the highest memory address.
+ *
+ * The component values are unsigned normalized to the range [0, 1], whose
+ * interpretation is defined by the dataspace.
+ */
+ RGBX_8888 = 0x2,
+
+ /**
+ * 24-bit format that has 8-bit R, G, and B components, in that order,
+ * from the lowest memory address to the highest memory address.
+ *
+ * The component values are unsigned normalized to the range [0, 1], whose
+ * interpretation is defined by the dataspace.
+ */
+ RGB_888 = 0x3,
+
+ /**
+ * 16-bit packed format that has 5-bit R, 6-bit G, and 5-bit B components,
+ * in that order, from the most-sigfinicant bits to the least-significant
+ * bits.
+ *
+ * The component values are unsigned normalized to the range [0, 1], whose
+ * interpretation is defined by the dataspace.
+ */
+ RGB_565 = 0x4,
+
+ /**
+ * 32-bit format that has 8-bit B, G, R, and A components, in that order,
+ * from the lowest memory address to the highest memory address.
+ *
+ * The component values are unsigned normalized to the range [0, 1], whose
+ * interpretation is defined by the dataspace.
+ */
+ BGRA_8888 = 0x5,
+
+ /**
+ * Legacy formats deprecated in favor of YCBCR_420_888.
+ */
+ YCBCR_422_SP = 0x10, // NV16
+ YCRCB_420_SP = 0x11, // NV21
+ YCBCR_422_I = 0x14, // YUY2
+
+ /**
+ * 64-bit format that has 16-bit R, G, B, and A components, in that order,
+ * from the lowest memory address to the highest memory address.
+ *
+ * The component values are signed floats, whose interpretation is defined
+ * by the dataspace.
+ */
+ RGBA_FP16 = 0x16,
+
+ /**
+ * RAW16 is a single-channel, 16-bit, little endian format, typically
+ * representing raw Bayer-pattern images from an image sensor, with minimal
+ * processing.
+ *
+ * The exact pixel layout of the data in the buffer is sensor-dependent, and
+ * needs to be queried from the camera device.
+ *
+ * Generally, not all 16 bits are used; more common values are 10 or 12
+ * bits. If not all bits are used, the lower-order bits are filled first.
+ * All parameters to interpret the raw data (black and white points,
+ * color space, etc) must be queried from the camera device.
+ *
+ * This format assumes
+ * - an even width
+ * - an even height
+ * - a horizontal stride multiple of 16 pixels
+ * - a vertical stride equal to the height
+ * - strides are specified in pixels, not in bytes
+ *
+ * size = stride * height * 2
+ *
+ * This format must be accepted by the allocator when used with the
+ * following usage flags:
+ *
+ * - BufferUsage::CAMERA_*
+ * - BufferUsage::CPU_*
+ * - BufferUsage::RENDERSCRIPT
+ *
+ * The mapping of the dataspace to buffer contents for RAW16 is as
+ * follows:
+ *
+ * Dataspace value | Buffer contents
+ * -------------------------------+-----------------------------------------
+ * Dataspace::ARBITRARY | Raw image sensor data, layout is as
+ * | defined above.
+ * Dataspace::DEPTH | Unprocessed implementation-dependent raw
+ * | depth measurements, opaque with 16 bit
+ * | samples.
+ * Other | Unsupported
+ */
+ RAW16 = 0x20,
+
+ /**
+ * BLOB is used to carry task-specific data which does not have a standard
+ * image structure. The details of the format are left to the two
+ * endpoints.
+ *
+ * A typical use case is for transporting JPEG-compressed images from the
+ * Camera HAL to the framework or to applications.
+ *
+ * Buffers of this format must have a height of 1, and width equal to their
+ * size in bytes.
+ *
+ * The mapping of the dataspace to buffer contents for BLOB is as
+ * follows:
+ *
+ * Dataspace value | Buffer contents
+ * -------------------------------+-----------------------------------------
+ * Dataspace::JFIF | An encoded JPEG image
+ * Dataspace::DEPTH | An android_depth_points buffer
+ * Dataspace::SENSOR | Sensor event data.
+ * Other | Unsupported
+ */
+ BLOB = 0x21,
+
+ /**
+ * A format indicating that the choice of format is entirely up to the
+ * allocator.
+ *
+ * The allocator should examine the usage bits passed in when allocating a
+ * buffer with this format, and it should derive the pixel format from
+ * those usage flags. This format must never be used with any of the
+ * BufferUsage::CPU_* usage flags.
+ *
+ * Even when the internally chosen format has an alpha component, the
+ * clients must assume the alpha vlaue to be 1.0.
+ *
+ * The interpretation of the component values is defined by the dataspace.
+ */
+ IMPLEMENTATION_DEFINED = 0x22,
+
+ /**
+ * This format allows platforms to use an efficient YCbCr/YCrCb 4:2:0
+ * buffer layout, while still describing the general format in a
+ * layout-independent manner. While called YCbCr, it can be used to
+ * describe formats with either chromatic ordering, as well as
+ * whole planar or semiplanar layouts.
+ *
+ * This format must be accepted by the allocator when BufferUsage::CPU_*
+ * are set.
+ *
+ * Buffers with this format must be locked with IMapper::lockYCbCr.
+ * Locking with IMapper::lock must return an error.
+ *
+ * The interpretation of the component values is defined by the dataspace.
+ */
+ YCBCR_420_888 = 0x23,
+
+ /**
+ * RAW_OPAQUE is a format for unprocessed raw image buffers coming from an
+ * image sensor. The actual structure of buffers of this format is
+ * implementation-dependent.
+ *
+ * This format must be accepted by the allocator when used with the
+ * following usage flags:
+ *
+ * - BufferUsage::CAMERA_*
+ * - BufferUsage::CPU_*
+ * - BufferUsage::RENDERSCRIPT
+ *
+ * The mapping of the dataspace to buffer contents for RAW_OPAQUE is as
+ * follows:
+ *
+ * Dataspace value | Buffer contents
+ * -------------------------------+-----------------------------------------
+ * Dataspace::ARBITRARY | Raw image sensor data.
+ * Other | Unsupported
+ */
+ RAW_OPAQUE = 0x24,
+
+ /**
+ * RAW10 is a single-channel, 10-bit per pixel, densely packed in each row,
+ * unprocessed format, usually representing raw Bayer-pattern images coming from
+ * an image sensor.
+ *
+ * In an image buffer with this format, starting from the first pixel of each
+ * row, each 4 consecutive pixels are packed into 5 bytes (40 bits). Each one
+ * of the first 4 bytes contains the top 8 bits of each pixel, The fifth byte
+ * contains the 2 least significant bits of the 4 pixels, the exact layout data
+ * for each 4 consecutive pixels is illustrated below (Pi[j] stands for the jth
+ * bit of the ith pixel):
+ *
+ * bit 7 bit 0
+ * =====|=====|=====|=====|=====|=====|=====|=====|
+ * Byte 0: |P0[9]|P0[8]|P0[7]|P0[6]|P0[5]|P0[4]|P0[3]|P0[2]|
+ * |-----|-----|-----|-----|-----|-----|-----|-----|
+ * Byte 1: |P1[9]|P1[8]|P1[7]|P1[6]|P1[5]|P1[4]|P1[3]|P1[2]|
+ * |-----|-----|-----|-----|-----|-----|-----|-----|
+ * Byte 2: |P2[9]|P2[8]|P2[7]|P2[6]|P2[5]|P2[4]|P2[3]|P2[2]|
+ * |-----|-----|-----|-----|-----|-----|-----|-----|
+ * Byte 3: |P3[9]|P3[8]|P3[7]|P3[6]|P3[5]|P3[4]|P3[3]|P3[2]|
+ * |-----|-----|-----|-----|-----|-----|-----|-----|
+ * Byte 4: |P3[1]|P3[0]|P2[1]|P2[0]|P1[1]|P1[0]|P0[1]|P0[0]|
+ * ===============================================
+ *
+ * This format assumes
+ * - a width multiple of 4 pixels
+ * - an even height
+ * - a vertical stride equal to the height
+ * - strides are specified in bytes, not in pixels
+ *
+ * size = stride * height
+ *
+ * When stride is equal to width * (10 / 8), there will be no padding bytes at
+ * the end of each row, the entire image data is densely packed. When stride is
+ * larger than width * (10 / 8), padding bytes will be present at the end of each
+ * row (including the last row).
+ *
+ * This format must be accepted by the allocator when used with the
+ * following usage flags:
+ *
+ * - BufferUsage::CAMERA_*
+ * - BufferUsage::CPU_*
+ * - BufferUsage::RENDERSCRIPT
+ *
+ * The mapping of the dataspace to buffer contents for RAW10 is as
+ * follows:
+ *
+ * Dataspace value | Buffer contents
+ * -------------------------------+-----------------------------------------
+ * Dataspace::ARBITRARY | Raw image sensor data.
+ * Other | Unsupported
+ */
+ RAW10 = 0x25,
+
+ /**
+ * RAW12 is a single-channel, 12-bit per pixel, densely packed in each row,
+ * unprocessed format, usually representing raw Bayer-pattern images coming from
+ * an image sensor.
+ *
+ * In an image buffer with this format, starting from the first pixel of each
+ * row, each two consecutive pixels are packed into 3 bytes (24 bits). The first
+ * and second byte contains the top 8 bits of first and second pixel. The third
+ * byte contains the 4 least significant bits of the two pixels, the exact layout
+ * data for each two consecutive pixels is illustrated below (Pi[j] stands for
+ * the jth bit of the ith pixel):
+ *
+ * bit 7 bit 0
+ * ======|======|======|======|======|======|======|======|
+ * Byte 0: |P0[11]|P0[10]|P0[ 9]|P0[ 8]|P0[ 7]|P0[ 6]|P0[ 5]|P0[ 4]|
+ * |------|------|------|------|------|------|------|------|
+ * Byte 1: |P1[11]|P1[10]|P1[ 9]|P1[ 8]|P1[ 7]|P1[ 6]|P1[ 5]|P1[ 4]|
+ * |------|------|------|------|------|------|------|------|
+ * Byte 2: |P1[ 3]|P1[ 2]|P1[ 1]|P1[ 0]|P0[ 3]|P0[ 2]|P0[ 1]|P0[ 0]|
+ * =======================================================
+ *
+ * This format assumes:
+ * - a width multiple of 4 pixels
+ * - an even height
+ * - a vertical stride equal to the height
+ * - strides are specified in bytes, not in pixels
+ *
+ * size = stride * height
+ *
+ * When stride is equal to width * (12 / 8), there will be no padding bytes at
+ * the end of each row, the entire image data is densely packed. When stride is
+ * larger than width * (12 / 8), padding bytes will be present at the end of
+ * each row (including the last row).
+ *
+ * This format must be accepted by the allocator when used with the
+ * following usage flags:
+ *
+ * - BufferUsage::CAMERA_*
+ * - BufferUsage::CPU_*
+ * - BufferUsage::RENDERSCRIPT
+ *
+ * The mapping of the dataspace to buffer contents for RAW12 is as
+ * follows:
+ *
+ * Dataspace value | Buffer contents
+ * -------------------------------+-----------------------------------------
+ * Dataspace::ARBITRARY | Raw image sensor data.
+ * Other | Unsupported
+ */
+ RAW12 = 0x26,
+
+ /** 0x27 to 0x2A are reserved for flexible formats */
+
+ /**
+ * 32-bit packed format that has 2-bit A, 10-bit B, G, and R components,
+ * in that order, from the most-sigfinicant bits to the least-significant
+ * bits.
+ *
+ * The component values are unsigned normalized to the range [0, 1], whose
+ * interpretation is defined by the dataspace.
+ */
+ RGBA_1010102 = 0x2B,
+
+ /**
+ * 0x100 - 0x1FF
+ *
+ * This range is reserved for vendor extensions. Formats in this range
+ * must support BufferUsage::GPU_TEXTURE. Clients must assume they do not
+ * have an alpha component.
+ */
+
+ /**
+ * Y8 is a YUV planar format comprised of a WxH Y plane, with each pixel
+ * being represented by 8 bits. It is equivalent to just the Y plane from
+ * YV12.
+ *
+ * This format assumes
+ * - an even width
+ * - an even height
+ * - a horizontal stride multiple of 16 pixels
+ * - a vertical stride equal to the height
+ *
+ * size = stride * height
+ *
+ * This format must be accepted by the allocator when used with the
+ * following usage flags:
+ *
+ * - BufferUsage::CAMERA_*
+ * - BufferUsage::CPU_*
+ *
+ * The component values are unsigned normalized to the range [0, 1], whose
+ * interpretation is defined by the dataspace.
+ */
+ Y8 = 0x20203859,
+
+ /**
+ * Y16 is a YUV planar format comprised of a WxH Y plane, with each pixel
+ * being represented by 16 bits. It is just like Y8, but has double the
+ * bits per pixel (little endian).
+ *
+ * This format assumes
+ * - an even width
+ * - an even height
+ * - a horizontal stride multiple of 16 pixels
+ * - a vertical stride equal to the height
+ * - strides are specified in pixels, not in bytes
+ *
+ * size = stride * height * 2
+ *
+ * This format must be accepted by the allocator when used with the
+ * following usage flags:
+ *
+ * - BufferUsage::CAMERA_*
+ * - BufferUsage::CPU_*
+ *
+ * The component values are unsigned normalized to the range [0, 1], whose
+ * interpretation is defined by the dataspace. When the dataspace is
+ * Dataspace::DEPTH, each pixel is a distance value measured by a depth
+ * camera, plus an associated confidence value.
+ */
+ Y16 = 0x20363159,
+
+ /**
+ * YV12 is a 4:2:0 YCrCb planar format comprised of a WxH Y plane followed
+ * by (W/2) x (H/2) Cr and Cb planes.
+ *
+ * This format assumes
+ * - an even width
+ * - an even height
+ * - a horizontal stride multiple of 16 pixels
+ * - a vertical stride equal to the height
+ *
+ * y_size = stride * height
+ * c_stride = ALIGN(stride/2, 16)
+ * c_size = c_stride * height/2
+ * size = y_size + c_size * 2
+ * cr_offset = y_size
+ * cb_offset = y_size + c_size
+ *
+ * This range is reserved for vendor extensions. Formats in this range
+ * must support BufferUsage::GPU_TEXTURE. Clients must assume they do not
+ * have an alpha component.
+ *
+ * This format must be accepted by the allocator when used with the
+ * following usage flags:
+ *
+ * - BufferUsage::CAMERA_*
+ * - BufferUsage::CPU_*
+ * - BufferUsage::GPU_TEXTURE
+ *
+ * The component values are unsigned normalized to the range [0, 1], whose
+ * interpretation is defined by the dataspace.
+ */
+ YV12 = 0x32315659, // YCrCb 4:2:0 Planar
+
+ /**
+ * 16-bit format that has a single 16-bit depth component.
+ *
+ * The component values are unsigned normalized to the range [0, 1], whose
+ * interpretation is defined by the dataspace.
+ */
+ DEPTH_16 = 0x30,
+
+ /**
+ * 32-bit format that has a single 24-bit depth component and, optionally,
+ * 8 bits that are unused.
+ *
+ * The component values are unsigned normalized to the range [0, 1], whose
+ * interpretation is defined by the dataspace.
+ */
+ DEPTH_24 = 0x31,
+
+ /**
+ * 32-bit format that has a 24-bit depth component and an 8-bit stencil
+ * component packed into 32-bits.
+ *
+ * The depth component values are unsigned normalized to the range [0, 1],
+ * whose interpretation is defined by the dataspace. The stencil values are
+ * unsigned integers, whose interpretation is defined by the dataspace.
+ */
+ DEPTH_24_STENCIL_8 = 0x32,
+
+ /**
+ * 32-bit format that has a single 32-bit depth component.
+ *
+ * The component values are signed floats, whose interpretation is defined
+ * by the dataspace.
+ */
+ DEPTH_32F = 0x33,
+
+ /**
+ * Two-component format that has a 32-bit depth component, an 8-bit stencil
+ * component, and optionally 24-bits unused.
+ *
+ * The depth component values are signed floats, whose interpretation is
+ * defined by the dataspace. The stencil bits are unsigned integers, whose
+ * interpretation is defined by the dataspace.
+ */
+ DEPTH_32F_STENCIL_8 = 0x34,
+
+ /**
+ * 8-bit format that has a single 8-bit stencil component.
+ *
+ * The component values are unsigned integers, whose interpretation is
+ * defined by the dataspace.
+ */
+ STENCIL_8 = 0x35,
+
+ /**
+ * P010 is a 4:2:0 YCbCr semiplanar format comprised of a WxH Y plane
+ * followed immediately by a Wx(H/2) CbCr plane. Each sample is
+ * represented by a 16-bit little-endian value, with the lower 6 bits set
+ * to zero.
+ *
+ * This format assumes
+ * - an even height
+ * - a vertical stride equal to the height
+ *
+ * stride_in_bytes = stride * 2
+ * y_size = stride_in_bytes * height
+ * cbcr_size = stride_in_bytes * (height / 2)
+ * cb_offset = y_size
+ * cr_offset = cb_offset + 2
+ *
+ * This format must be accepted by the allocator when used with the
+ * following usage flags:
+ *
+ * - BufferUsage::VIDEO_*
+ * - BufferUsage::CPU_*
+ * - BufferUsage::GPU_TEXTURE
+ *
+ * The component values are unsigned normalized to the range [0, 1], whose
+ * interpretation is defined by the dataspace.
+ *
+ * This format is appropriate for 10bit video content.
+ *
+ * Buffers with this format must be locked with IMapper::lockYCbCr
+ * or with IMapper::lock.
+ */
+ YCBCR_P010 = 0x36,
+
+ /**
+ * 24-bit format that has 8-bit H, S, and V components, in that order,
+ * from the lowest memory address to the highest memory address.
+ *
+ * The component values are unsigned normalized to the range [0, 1], whose
+ * interpretation is defined by the dataspace.
+ */
+ HSV_888 = 0x37,
+}
diff --git a/graphics/composer/2.1/utils/hwc2on1adapter/HWC2On1Adapter.cpp b/graphics/composer/2.1/utils/hwc2on1adapter/HWC2On1Adapter.cpp
index 5a75ae1..3702171 100644
--- a/graphics/composer/2.1/utils/hwc2on1adapter/HWC2On1Adapter.cpp
+++ b/graphics/composer/2.1/utils/hwc2on1adapter/HWC2On1Adapter.cpp
@@ -2590,13 +2590,6 @@
std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
- // If the HWC2-side callback hasn't been registered yet, buffer this until
- // it is registered
- if (mCallbacks.count(Callback::Hotplug) == 0) {
- mPendingHotplugs.emplace_back(hwc1DisplayId, connected);
- return;
- }
-
hwc2_display_t displayId = UINT64_MAX;
if (mHwc1DisplayMap.count(hwc1DisplayId) == 0) {
if (connected == 0) {
@@ -2625,6 +2618,13 @@
mDisplays.erase(displayId);
}
+ // If the HWC2-side callback hasn't been registered yet, buffer this until
+ // it is registered
+ if (mCallbacks.count(Callback::Hotplug) == 0) {
+ mPendingHotplugs.emplace_back(hwc1DisplayId, connected);
+ return;
+ }
+
const auto& callbackInfo = mCallbacks[Callback::Hotplug];
// Call back without the state lock held
diff --git a/graphics/composer/2.1/utils/vts/ComposerVts.cpp b/graphics/composer/2.1/utils/vts/ComposerVts.cpp
index a0745ce..a8e1480 100644
--- a/graphics/composer/2.1/utils/vts/ComposerVts.cpp
+++ b/graphics/composer/2.1/utils/vts/ComposerVts.cpp
@@ -369,10 +369,7 @@
accessRegion.top = accessRegionRect.top;
accessRegion.width = accessRegionRect.width;
accessRegion.height = accessRegionRect.height;
- int32_t bytesPerPixel;
- int32_t bytesPerStride;
- return mGralloc4->lock(bufferHandle, cpuUsage, accessRegion, acquireFence, &bytesPerPixel,
- &bytesPerStride);
+ return mGralloc4->lock(bufferHandle, cpuUsage, accessRegion, acquireFence);
} else if (mGralloc3) {
IMapper3::Rect accessRegion;
accessRegion.left = accessRegionRect.left;
diff --git a/graphics/composer/2.2/utils/command-buffer/include/composer-command-buffer/2.2/ComposerCommandBuffer.h b/graphics/composer/2.2/utils/command-buffer/include/composer-command-buffer/2.2/ComposerCommandBuffer.h
index 138d700..35162a6 100644
--- a/graphics/composer/2.2/utils/command-buffer/include/composer-command-buffer/2.2/ComposerCommandBuffer.h
+++ b/graphics/composer/2.2/utils/command-buffer/include/composer-command-buffer/2.2/ComposerCommandBuffer.h
@@ -93,17 +93,18 @@
}
protected:
- void beginCommand_2_2(IComposerClient::Command command, uint16_t length) {
- V2_1::CommandWriterBase::beginCommand(
- static_cast<V2_1::IComposerClient::Command>(static_cast<int32_t>(command)), length);
- }
-
void writeFloatColor(const IComposerClient::FloatColor& color) {
writeFloat(color.r);
writeFloat(color.g);
writeFloat(color.b);
writeFloat(color.a);
}
+
+ private:
+ void beginCommand_2_2(IComposerClient::Command command, uint16_t length) {
+ V2_1::CommandWriterBase::beginCommand(
+ static_cast<V2_1::IComposerClient::Command>(static_cast<int32_t>(command)), length);
+ }
};
// This class helps parse a command queue. Note that all sizes/lengths are in
diff --git a/graphics/composer/2.2/utils/passthrough/include/composer-passthrough/2.2/HwcHal.h b/graphics/composer/2.2/utils/passthrough/include/composer-passthrough/2.2/HwcHal.h
index 93da0a5..9b3aa90 100644
--- a/graphics/composer/2.2/utils/passthrough/include/composer-passthrough/2.2/HwcHal.h
+++ b/graphics/composer/2.2/utils/passthrough/include/composer-passthrough/2.2/HwcHal.h
@@ -173,6 +173,14 @@
Error getRenderIntents(Display display, ColorMode mode,
std::vector<RenderIntent>* outIntents) override {
if (!mDispatch.getRenderIntents) {
+ IComposerClient::DisplayType type;
+ if (getDisplayType(display, &type) == Error::BAD_DISPLAY) {
+ return Error::BAD_DISPLAY;
+ }
+ if (mode < ColorMode::NATIVE || mode > ColorMode::DISPLAY_P3) {
+ return Error::BAD_PARAMETER;
+ }
+
*outIntents = std::vector<RenderIntent>({RenderIntent::COLORIMETRIC});
return Error::NONE;
}
@@ -199,6 +207,9 @@
Error setColorMode_2_2(Display display, ColorMode mode, RenderIntent intent) override {
if (!mDispatch.setColorModeWithRenderIntent) {
+ if (intent < RenderIntent::COLORIMETRIC || intent > RenderIntent::TONE_MAP_ENHANCE) {
+ return Error::BAD_PARAMETER;
+ }
if (intent != RenderIntent::COLORIMETRIC) {
return Error::UNSUPPORTED;
}
@@ -282,6 +293,7 @@
private:
using BaseType2_1 = V2_1::passthrough::detail::HwcHalImpl<Hal>;
using BaseType2_1::getColorModes;
+ using BaseType2_1::getDisplayType;
using BaseType2_1::mDevice;
using BaseType2_1::setColorMode;
using BaseType2_1::createVirtualDisplay;
diff --git a/graphics/composer/2.2/vts/functional/Android.bp b/graphics/composer/2.2/vts/functional/Android.bp
index 21ba9f3..f987516 100644
--- a/graphics/composer/2.2/vts/functional/Android.bp
+++ b/graphics/composer/2.2/vts/functional/Android.bp
@@ -57,5 +57,6 @@
"android.hardware.graphics.composer@2.1-command-buffer",
"android.hardware.graphics.composer@2.2-command-buffer",
],
- test_suites: ["general-tests"],
+ disable_framework: true,
+ test_suites: ["general-tests", "vts-core"],
}
diff --git a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp
index 6a6f7de..044bd96 100644
--- a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp
+++ b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp
@@ -16,14 +16,15 @@
#define LOG_TAG "graphics_composer_hidl_hal_readback_tests@2.2"
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
#include <composer-command-buffer/2.2/ComposerCommandBuffer.h>
#include <composer-vts/2.1/GraphicsComposerCallback.h>
#include <composer-vts/2.1/TestCommandReader.h>
#include <composer-vts/2.2/ComposerVts.h>
#include <composer-vts/2.2/ReadbackVts.h>
#include <composer-vts/2.2/RenderEngineVts.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include <ui/GraphicBuffer.h>
#include <ui/GraphicBufferAllocator.h>
#include <ui/PixelFormat.h>
@@ -50,29 +51,12 @@
using V2_1::vts::TestCommandReader;
using vts::Gralloc;
-// Test environment for graphics.composer
-class GraphicsComposerHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static GraphicsComposerHidlEnvironment* Instance() {
- static GraphicsComposerHidlEnvironment* instance = new GraphicsComposerHidlEnvironment;
- return instance;
- }
- virtual void registerTestServices() override { registerTestService<IComposer>(); }
-
- private:
- GraphicsComposerHidlEnvironment() {}
- GTEST_DISALLOW_COPY_AND_ASSIGN_(GraphicsComposerHidlEnvironment);
-};
-
-class GraphicsCompositionTest : public ::testing::VtsHalHidlTargetTestBase {
+class GraphicsCompositionTestBase : public ::testing::Test {
protected:
using PowerMode = V2_1::IComposerClient::PowerMode;
- void SetUp() override {
- VtsHalHidlTargetTestBase::SetUp();
+ void SetUpBase(const std::string& service_name) {
ASSERT_NO_FATAL_FAILURE(
- mComposer = std::make_unique<Composer>(
- GraphicsComposerHidlEnvironment::Instance()->getServiceName<IComposer>()));
+ mComposer = std::make_unique<Composer>(IComposer::getService(service_name)));
ASSERT_NO_FATAL_FAILURE(mComposerClient = mComposer->createClient());
mComposerCallback = new V2_1::vts::GraphicsComposerCallback;
mComposerClient->registerCallback(mComposerCallback);
@@ -132,7 +116,6 @@
EXPECT_EQ(0, mComposerCallback->getInvalidRefreshCount());
EXPECT_EQ(0, mComposerCallback->getInvalidVsyncCount());
}
- VtsHalHidlTargetTestBase::TearDown();
}
void clearCommandReaderState() {
@@ -198,7 +181,13 @@
}
};
-TEST_F(GraphicsCompositionTest, SingleSolidColorLayer) {
+class GraphicsCompositionTest : public GraphicsCompositionTestBase,
+ public testing::WithParamInterface<std::string> {
+ public:
+ void SetUp() override { SetUpBase(GetParam()); }
+};
+
+TEST_P(GraphicsCompositionTest, SingleSolidColorLayer) {
for (ColorMode mode : mTestColorModes) {
std::cout << "---Testing Color Mode " << ReadbackHelper::getColorModeString(mode) << "---"
<< std::endl;
@@ -260,7 +249,7 @@
}
}
-TEST_F(GraphicsCompositionTest, SetLayerBuffer) {
+TEST_P(GraphicsCompositionTest, SetLayerBuffer) {
for (ColorMode mode : mTestColorModes) {
std::cout << "---Testing Color Mode " << ReadbackHelper::getColorModeString(mode) << "---"
<< std::endl;
@@ -332,7 +321,7 @@
}
}
-TEST_F(GraphicsCompositionTest, SetLayerBufferNoEffect) {
+TEST_P(GraphicsCompositionTest, SetLayerBufferNoEffect) {
for (ColorMode mode : mTestColorModes) {
std::cout << "---Testing Color Mode " << ReadbackHelper::getColorModeString(mode) << "---"
<< std::endl;
@@ -394,7 +383,7 @@
}
}
-TEST_F(GraphicsCompositionTest, ClientComposition) {
+TEST_P(GraphicsCompositionTest, ClientComposition) {
ASSERT_NO_FATAL_FAILURE(
mComposerClient->setClientTargetSlotCount(mPrimaryDisplay, kClientTargetSlotCount));
@@ -511,7 +500,7 @@
}
}
-TEST_F(GraphicsCompositionTest, DeviceAndClientComposition) {
+TEST_P(GraphicsCompositionTest, DeviceAndClientComposition) {
ASSERT_NO_FATAL_FAILURE(
mComposerClient->setClientTargetSlotCount(mPrimaryDisplay, kClientTargetSlotCount));
@@ -637,7 +626,7 @@
}
}
-TEST_F(GraphicsCompositionTest, SetLayerDamage) {
+TEST_P(GraphicsCompositionTest, SetLayerDamage) {
for (ColorMode mode : mTestColorModes) {
std::cout << "---Testing Color Mode " << ReadbackHelper::getColorModeString(mode) << "---"
<< std::endl;
@@ -722,7 +711,7 @@
}
}
-TEST_F(GraphicsCompositionTest, SetLayerPlaneAlpha) {
+TEST_P(GraphicsCompositionTest, SetLayerPlaneAlpha) {
for (ColorMode mode : mTestColorModes) {
std::cout << "---Testing Color Mode " << ReadbackHelper::getColorModeString(mode) << "---"
<< std::endl;
@@ -783,7 +772,7 @@
}
}
-TEST_F(GraphicsCompositionTest, SetLayerSourceCrop) {
+TEST_P(GraphicsCompositionTest, SetLayerSourceCrop) {
for (ColorMode mode : mTestColorModes) {
std::cout << "---Testing Color Mode " << ReadbackHelper::getColorModeString(mode) << "---"
<< std::endl;
@@ -854,7 +843,7 @@
}
}
-TEST_F(GraphicsCompositionTest, SetLayerZOrder) {
+TEST_P(GraphicsCompositionTest, SetLayerZOrder) {
for (ColorMode mode : mTestColorModes) {
std::cout << "---Testing Color Mode " << ReadbackHelper::getColorModeString(mode) << "---"
<< std::endl;
@@ -941,18 +930,17 @@
}
}
-class GraphicsBlendModeCompositionTest : public GraphicsCompositionTest,
- public ::testing::WithParamInterface<float> {
+class GraphicsBlendModeCompositionTest
+ : public GraphicsCompositionTestBase,
+ public testing::WithParamInterface<std::tuple<string, string>> {
public:
void SetUp() override {
- GraphicsCompositionTest::SetUp();
+ SetUpBase(std::get<0>(GetParam()));
mTestColorModes = {ColorMode::SRGB}; // TODO: add more color mode support
mBackgroundColor = BLACK;
mTopLayerColor = RED;
}
- void TearDown() override { GraphicsCompositionTest::TearDown(); }
-
void setBackgroundColor(IComposerClient::Color color) { mBackgroundColor = color; }
void setTopLayerColor(IComposerClient::Color color) { mTopLayerColor = color; }
@@ -977,7 +965,7 @@
ASSERT_NO_FATAL_FAILURE(layer->setBuffer(topLayerPixelColors));
layer->setBlendMode(blendMode);
- layer->setAlpha(GetParam());
+ layer->setAlpha(std::stof(std::get<1>(GetParam())));
mLayers.push_back(backgroundLayer);
mLayers.push_back(layer);
@@ -1023,7 +1011,8 @@
IComposerClient::Color mTopLayerColor;
};
-TEST_P(GraphicsBlendModeCompositionTest, None) {
+// TODO(b/145557764): Re-enable after the bug is fixed.
+TEST_P(GraphicsBlendModeCompositionTest, DISABLED_None) {
for (ColorMode mode : mTestColorModes) {
std::cout << "---Testing Color Mode " << ReadbackHelper::getColorModeString(mode) << "---"
<< std::endl;
@@ -1188,9 +1177,6 @@
}
}
-INSTANTIATE_TEST_CASE_P(BlendModeTest, GraphicsBlendModeCompositionTest,
- ::testing::Values(.2, 1.0));
-
class GraphicsTransformCompositionTest : public GraphicsCompositionTest {
protected:
void SetUp() override {
@@ -1229,7 +1215,7 @@
int mSideLength;
};
-TEST_F(GraphicsTransformCompositionTest, FLIP_H) {
+TEST_P(GraphicsTransformCompositionTest, FLIP_H) {
for (ColorMode mode : mTestColorModes) {
std::cout << "---Testing Color Mode " << ReadbackHelper::getColorModeString(mode) << "---"
<< std::endl;
@@ -1284,7 +1270,7 @@
}
}
-TEST_F(GraphicsTransformCompositionTest, FLIP_V) {
+TEST_P(GraphicsTransformCompositionTest, FLIP_V) {
for (ColorMode mode : mTestColorModes) {
std::cout << "---Testing Color Mode " << ReadbackHelper::getColorModeString(mode) << "---"
<< std::endl;
@@ -1339,7 +1325,7 @@
}
}
-TEST_F(GraphicsTransformCompositionTest, ROT_180) {
+TEST_P(GraphicsTransformCompositionTest, ROT_180) {
for (ColorMode mode : mTestColorModes) {
std::cout << "---Testing Color Mode " << ReadbackHelper::getColorModeString(mode) << "---"
<< std::endl;
@@ -1395,6 +1381,23 @@
}
}
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, GraphicsCompositionTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(IComposer::descriptor)),
+ android::hardware::PrintInstanceNameToString);
+
+INSTANTIATE_TEST_CASE_P(
+ BlendModeTest, GraphicsBlendModeCompositionTest,
+ testing::Combine(
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(IComposer::descriptor)),
+ testing::Values("0.2", "1.0")),
+ android::hardware::PrintInstanceTupleNameToString<>);
+
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, GraphicsTransformCompositionTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(IComposer::descriptor)),
+ android::hardware::PrintInstanceNameToString);
+
} // anonymous namespace
} // namespace vts
} // namespace V2_2
diff --git a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp
index 51832f9..95a0f69 100644
--- a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp
+++ b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp
@@ -16,12 +16,14 @@
#define LOG_TAG "graphics_composer_hidl_hal_test@2.2"
-#include <VtsHalHidlTargetTestBase.h>
#include <android-base/logging.h>
#include <android/hardware/graphics/mapper/2.0/IMapper.h>
#include <composer-vts/2.1/GraphicsComposerCallback.h>
#include <composer-vts/2.1/TestCommandReader.h>
#include <composer-vts/2.2/ComposerVts.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include <mapper-vts/2.0/MapperVts.h>
namespace android {
@@ -41,29 +43,11 @@
using common::V1_1::RenderIntent;
using mapper::V2_0::IMapper;
-// Test environment for graphics.composer
-class GraphicsComposerHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static GraphicsComposerHidlEnvironment* Instance() {
- static GraphicsComposerHidlEnvironment* instance = new GraphicsComposerHidlEnvironment;
- return instance;
- }
-
- virtual void registerTestServices() override { registerTestService<IComposer>(); }
-
- private:
- GraphicsComposerHidlEnvironment() {}
-
- GTEST_DISALLOW_COPY_AND_ASSIGN_(GraphicsComposerHidlEnvironment);
-};
-
-class GraphicsComposerHidlTest : public ::testing::VtsHalHidlTargetTestBase {
- protected:
+class GraphicsComposerHidlTest : public ::testing::TestWithParam<std::string> {
+ protected:
void SetUp() override {
ASSERT_NO_FATAL_FAILURE(
- mComposer = std::make_unique<Composer>(
- GraphicsComposerHidlEnvironment::Instance()->getServiceName<IComposer>()));
+ mComposer = std::make_unique<Composer>(IComposer::getService(GetParam())));
ASSERT_NO_FATAL_FAILURE(mComposerClient = mComposer->createClient());
mComposerCallback = new V2_1::vts::GraphicsComposerCallback;
@@ -188,7 +172,7 @@
/**
* Test IComposerClient::Command::SET_LAYER_PER_FRAME_METADATA.
*/
-TEST_F(GraphicsComposerHidlCommandTest, SET_LAYER_PER_FRAME_METADATA) {
+TEST_P(GraphicsComposerHidlCommandTest, SET_LAYER_PER_FRAME_METADATA) {
Layer layer;
ASSERT_NO_FATAL_FAILURE(layer =
mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount));
@@ -239,7 +223,7 @@
/**
* Test IComposerClient::getPerFrameMetadataKeys.
*/
-TEST_F(GraphicsComposerHidlTest, GetPerFrameMetadataKeys) {
+TEST_P(GraphicsComposerHidlTest, GetPerFrameMetadataKeys) {
std::vector<IComposerClient::PerFrameMetadataKey> keys;
Error error = Error::NONE;
mComposerClient->getRaw()->getPerFrameMetadataKeys(
@@ -261,7 +245,7 @@
*
* Test that virtual displays can be created and has the correct display type.
*/
-TEST_F(GraphicsComposerHidlTest, CreateVirtualDisplay_2_2) {
+TEST_P(GraphicsComposerHidlTest, CreateVirtualDisplay_2_2) {
if (mComposerClient->getMaxVirtualDisplayCount() == 0) {
GTEST_SUCCEED() << "no virtual display support";
return;
@@ -286,7 +270,7 @@
* Test that IComposerClient::getClientTargetSupport returns true for the
* required client targets.
*/
-TEST_F(GraphicsComposerHidlTest, GetClientTargetSupport_2_2) {
+TEST_P(GraphicsComposerHidlTest, GetClientTargetSupport_2_2) {
std::vector<Config> configs = mComposerClient->getDisplayConfigs(mPrimaryDisplay);
for (auto config : configs) {
int32_t width = mComposerClient->getDisplayAttribute(mPrimaryDisplay, config,
@@ -310,7 +294,7 @@
* Error::BAD_DISPLAY when passed in an invalid display handle
*/
-TEST_F(GraphicsComposerHidlTest, GetClientTargetSupport_2_2BadDisplay) {
+TEST_P(GraphicsComposerHidlTest, GetClientTargetSupport_2_2BadDisplay) {
std::vector<Config> configs = mComposerClient->getDisplayConfigs(mPrimaryDisplay);
for (auto config : configs) {
int32_t width = mComposerClient->getDisplayAttribute(mPrimaryDisplay, config,
@@ -332,7 +316,7 @@
/**
* Test IComposerClient::setPowerMode_2_2.
*/
-TEST_F(GraphicsComposerHidlTest, SetPowerMode_2_2) {
+TEST_P(GraphicsComposerHidlTest, SetPowerMode_2_2) {
std::vector<IComposerClient::PowerMode> modes;
modes.push_back(IComposerClient::PowerMode::OFF);
modes.push_back(IComposerClient::PowerMode::ON_SUSPEND);
@@ -349,7 +333,7 @@
* Test that IComposerClient::setPowerMode_2_2 succeeds for different varations
* of PowerMode
*/
-TEST_F(GraphicsComposerHidlTest, SetPowerMode_2_2Variations) {
+TEST_P(GraphicsComposerHidlTest, SetPowerMode_2_2Variations) {
std::vector<IComposerClient::PowerMode> modes;
modes.push_back(IComposerClient::PowerMode::OFF);
@@ -404,7 +388,7 @@
* Tests that IComposerClient::setPowerMode_2_2 returns BAD_DISPLAY when passed an
* invalid display handle
*/
-TEST_F(GraphicsComposerHidlTest, SetPowerMode_2_2BadDisplay) {
+TEST_P(GraphicsComposerHidlTest, SetPowerMode_2_2BadDisplay) {
Error error = mComposerClient->getRaw()->setPowerMode_2_2(mInvalidDisplayId,
IComposerClient::PowerMode::ON);
ASSERT_EQ(Error::BAD_DISPLAY, error);
@@ -416,7 +400,7 @@
* Test that IComposerClient::setPowerMode_2_2 returns BAD_PARAMETER when passed
* an invalid PowerMode
*/
-TEST_F(GraphicsComposerHidlTest, SetPowerMode_2_2BadParameter) {
+TEST_P(GraphicsComposerHidlTest, SetPowerMode_2_2BadParameter) {
Error error = mComposerClient->getRaw()->setPowerMode_2_2(
mPrimaryDisplay, static_cast<IComposerClient::PowerMode>(-1));
ASSERT_EQ(Error::BAD_PARAMETER, error);
@@ -428,7 +412,7 @@
* Test that IComposerClient::setPowerMode_2_2 returns UNSUPPORTED when passed
* DOZE or DOZE_SUPPORT on a device that does not support these modes
*/
-TEST_F(GraphicsComposerHidlTest, SetPowerMode_2_2Unsupported) {
+TEST_P(GraphicsComposerHidlTest, SetPowerMode_2_2Unsupported) {
if (!mComposerClient->getDozeSupport(mPrimaryDisplay)) {
Error error = mComposerClient->getRaw()->setPowerMode_2_2(mPrimaryDisplay,
IComposerClient::PowerMode::DOZE);
@@ -445,7 +429,7 @@
*
* Test IComposerClient::setReadbackBuffer
*/
-TEST_F(GraphicsComposerHidlTest, SetReadbackBuffer) {
+TEST_P(GraphicsComposerHidlTest, SetReadbackBuffer) {
if (!mHasReadbackBuffer) {
return;
}
@@ -469,7 +453,7 @@
* Test that IComposerClient::setReadbackBuffer returns an Error::BAD_DISPLAY
* when passed an invalid display handle
*/
-TEST_F(GraphicsComposerHidlTest, SetReadbackBufferBadDisplay) {
+TEST_P(GraphicsComposerHidlTest, SetReadbackBufferBadDisplay) {
if (!mHasReadbackBuffer) {
return;
}
@@ -493,7 +477,7 @@
* Test that IComposerClient::setReadbackBuffer returns Error::BAD_PARAMETER
* when passed an invalid buffer handle
*/
-TEST_F(GraphicsComposerHidlTest, SetReadbackBufferBadParameter) {
+TEST_P(GraphicsComposerHidlTest, SetReadbackBufferBadParameter) {
if (!mHasReadbackBuffer) {
return;
}
@@ -502,7 +486,7 @@
ASSERT_EQ(Error::BAD_PARAMETER, error);
}
-TEST_F(GraphicsComposerHidlTest, GetReadbackBufferFenceInactive) {
+TEST_P(GraphicsComposerHidlTest, GetReadbackBufferFenceInactive) {
if (!mHasReadbackBuffer) {
return;
}
@@ -516,7 +500,7 @@
/**
* Test IComposerClient::Command::SET_LAYER_FLOAT_COLOR.
*/
-TEST_F(GraphicsComposerHidlCommandTest, SET_LAYER_FLOAT_COLOR) {
+TEST_P(GraphicsComposerHidlCommandTest, SET_LAYER_FLOAT_COLOR) {
V2_1::Layer layer;
ASSERT_NO_FATAL_FAILURE(layer =
mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount));
@@ -554,7 +538,7 @@
/**
* Test IComposerClient::getDataspaceSaturationMatrix.
*/
-TEST_F(GraphicsComposerHidlTest, GetDataspaceSaturationMatrix) {
+TEST_P(GraphicsComposerHidlTest, GetDataspaceSaturationMatrix) {
auto matrix = mComposerClient->getDataspaceSaturationMatrix(Dataspace::SRGB_LINEAR);
// the last row is known
ASSERT_EQ(0.0f, matrix[12]);
@@ -570,7 +554,7 @@
* Error::BAD_PARAMETER when passed a dataspace other than
* Dataspace::SRGB_LINEAR
*/
-TEST_F(GraphicsComposerHidlTest, GetDataspaceSaturationMatrixBadParameter) {
+TEST_P(GraphicsComposerHidlTest, GetDataspaceSaturationMatrixBadParameter) {
mComposerClient->getRaw()->getDataspaceSaturationMatrix(
Dataspace::UNKNOWN,
[&](const auto& tmpError, const auto&) { ASSERT_EQ(Error::BAD_PARAMETER, tmpError); });
@@ -579,7 +563,7 @@
/**
* Test IComposerClient::getColorMode_2_2.
*/
-TEST_F(GraphicsComposerHidlTest, GetColorMode_2_2) {
+TEST_P(GraphicsComposerHidlTest, GetColorMode_2_2) {
std::vector<ColorMode> modes = mComposerClient->getColorModes(mPrimaryDisplay);
auto nativeMode = std::find(modes.cbegin(), modes.cend(), ColorMode::NATIVE);
@@ -592,7 +576,7 @@
* Test that IComposerClient::getColorMode returns Error::BAD_DISPLAY when
* passed an invalid display handle
*/
-TEST_F(GraphicsComposerHidlTest, GetColorMode_2_2BadDisplay) {
+TEST_P(GraphicsComposerHidlTest, GetColorMode_2_2BadDisplay) {
mComposerClient->getRaw()->getColorModes_2_2(
mInvalidDisplayId,
[&](const auto& tmpError, const auto&) { ASSERT_EQ(Error::BAD_DISPLAY, tmpError); });
@@ -601,7 +585,7 @@
/**
* Test IComposerClient::getRenderIntents.
*/
-TEST_F(GraphicsComposerHidlTest, GetRenderIntents) {
+TEST_P(GraphicsComposerHidlTest, GetRenderIntents) {
std::vector<ColorMode> modes = mComposerClient->getColorModes(mPrimaryDisplay);
for (auto mode : modes) {
std::vector<RenderIntent> intents =
@@ -631,7 +615,7 @@
* Test that IComposerClient::getRenderIntent returns Error::BAD_DISPLAY when
* passed an invalid display handle
*/
-TEST_F(GraphicsComposerHidlTest, GetRenderIntentsBadDisplay) {
+TEST_P(GraphicsComposerHidlTest, GetRenderIntentsBadDisplay) {
std::vector<ColorMode> modes = mComposerClient->getColorModes(mPrimaryDisplay);
for (auto mode : modes) {
mComposerClient->getRaw()->getRenderIntents(
@@ -646,7 +630,7 @@
* Test that IComposerClient::getRenderIntents returns Error::BAD_PARAMETER when
* pased either an invalid Color mode or an invalid Render Intent
*/
-TEST_F(GraphicsComposerHidlTest, GetRenderIntentsBadParameter) {
+TEST_P(GraphicsComposerHidlTest, GetRenderIntentsBadParameter) {
mComposerClient->getRaw()->getRenderIntents(
mPrimaryDisplay, static_cast<ColorMode>(-1),
[&](const auto& tmpError, const auto&) { EXPECT_EQ(Error::BAD_PARAMETER, tmpError); });
@@ -655,7 +639,7 @@
/**
* Test IComposerClient::setColorMode_2_2.
*/
-TEST_F(GraphicsComposerHidlTest, SetColorMode_2_2) {
+TEST_P(GraphicsComposerHidlTest, SetColorMode_2_2) {
std::vector<ColorMode> modes = mComposerClient->getColorModes(mPrimaryDisplay);
for (auto mode : modes) {
std::vector<RenderIntent> intents =
@@ -674,7 +658,7 @@
* Test that IComposerClient::setColorMode_2_2 returns an Error::BAD_DISPLAY
* when passed an invalid display handle
*/
-TEST_F(GraphicsComposerHidlTest, SetColorMode_2_2BadDisplay) {
+TEST_P(GraphicsComposerHidlTest, SetColorMode_2_2BadDisplay) {
Error error = mComposerClient->getRaw()->setColorMode_2_2(mInvalidDisplayId, ColorMode::NATIVE,
RenderIntent::COLORIMETRIC);
@@ -687,7 +671,7 @@
* Test that IComposerClient::setColorMode_2_2 returns Error::BAD_PARAMETER when
* passed an invalid Color mode or an invalid render intent
*/
-TEST_F(GraphicsComposerHidlTest, SetColorMode_2_2BadParameter) {
+TEST_P(GraphicsComposerHidlTest, SetColorMode_2_2BadParameter) {
Error colorModeError = mComposerClient->getRaw()->setColorMode_2_2(
mPrimaryDisplay, static_cast<ColorMode>(-1), RenderIntent::COLORIMETRIC);
EXPECT_EQ(Error::BAD_PARAMETER, colorModeError);
@@ -697,6 +681,16 @@
EXPECT_EQ(Error::BAD_PARAMETER, renderIntentError);
}
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, GraphicsComposerHidlTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(IComposer::descriptor)),
+ android::hardware::PrintInstanceNameToString);
+
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, GraphicsComposerHidlCommandTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(IComposer::descriptor)),
+ android::hardware::PrintInstanceNameToString);
+
} // namespace
} // namespace vts
} // namespace V2_2
@@ -704,12 +698,3 @@
} // namespace graphics
} // namespace hardware
} // namespace android
-
-int main(int argc, char** argv) {
- using android::hardware::graphics::composer::V2_2::vts::GraphicsComposerHidlEnvironment;
- ::testing::AddGlobalTestEnvironment(GraphicsComposerHidlEnvironment::Instance());
- ::testing::InitGoogleTest(&argc, argv);
- GraphicsComposerHidlEnvironment::Instance()->init(&argc, argv);
- int status = RUN_ALL_TESTS();
- return status;
-}
diff --git a/graphics/composer/2.3/utils/command-buffer/include/composer-command-buffer/2.3/ComposerCommandBuffer.h b/graphics/composer/2.3/utils/command-buffer/include/composer-command-buffer/2.3/ComposerCommandBuffer.h
index 11863fa..3dfda19 100644
--- a/graphics/composer/2.3/utils/command-buffer/include/composer-command-buffer/2.3/ComposerCommandBuffer.h
+++ b/graphics/composer/2.3/utils/command-buffer/include/composer-command-buffer/2.3/ComposerCommandBuffer.h
@@ -79,6 +79,7 @@
void setLayerPerFrameMetadataBlobs(
const hidl_vec<IComposerClient::PerFrameMetadataBlob>& metadata) {
+ // in units of uint32_t's
size_t commandLength = 0;
if (metadata.size() > std::numeric_limits<uint32_t>::max()) {
@@ -86,12 +87,12 @@
return;
}
- // number of blobs
- commandLength += metadata.size();
+ // space for numElements
+ commandLength += 1;
for (auto metadataBlob : metadata) {
- commandLength += sizeof(int32_t); // key of metadata blob
- commandLength += 1; // size information of metadata blob
+ commandLength += 1; // key of metadata blob
+ commandLength += 1; // size information of metadata blob
// metadata content size
size_t metadataSize = metadataBlob.blob.size() / sizeof(uint32_t);
@@ -119,17 +120,18 @@
}
protected:
- void beginCommand_2_3(IComposerClient::Command command, uint16_t length) {
- V2_2::CommandWriterBase::beginCommand_2_2(
- static_cast<V2_2::IComposerClient::Command>(static_cast<int32_t>(command)), length);
- }
-
void writeBlob(uint32_t length, const unsigned char* blob) {
memcpy(&mData[mDataWritten], blob, length);
uint32_t numElements = length / 4;
mDataWritten += numElements;
mDataWritten += (length - (numElements * 4) > 0) ? 1 : 0;
}
+
+ private:
+ void beginCommand_2_3(IComposerClient::Command command, uint16_t length) {
+ V2_1::CommandWriterBase::beginCommand(
+ static_cast<V2_1::IComposerClient::Command>(static_cast<int32_t>(command)), length);
+ }
};
// This class helps parse a command queue. Note that all sizes/lengths are in
diff --git a/graphics/composer/2.3/utils/vts/include/composer-vts/2.3/ComposerVts.h b/graphics/composer/2.3/utils/vts/include/composer-vts/2.3/ComposerVts.h
index 0d4e5b8..e5ac842 100644
--- a/graphics/composer/2.3/utils/vts/include/composer-vts/2.3/ComposerVts.h
+++ b/graphics/composer/2.3/utils/vts/include/composer-vts/2.3/ComposerVts.h
@@ -49,12 +49,10 @@
public:
Composer();
explicit Composer(const std::string& name);
+ explicit Composer(const sp<IComposer>& composer);
std::unique_ptr<ComposerClient> createClient();
- protected:
- explicit Composer(const sp<IComposer>& composer);
-
private:
const sp<IComposer> mComposer;
};
diff --git a/graphics/composer/2.3/vts/functional/Android.bp b/graphics/composer/2.3/vts/functional/Android.bp
index b729062..fa4823e 100644
--- a/graphics/composer/2.3/vts/functional/Android.bp
+++ b/graphics/composer/2.3/vts/functional/Android.bp
@@ -49,4 +49,6 @@
"android.hardware.graphics.composer@2.2-command-buffer",
"android.hardware.graphics.composer@2.3-command-buffer",
],
+ disable_framework: true,
+ test_suites: ["general-tests", "vts-core"],
}
diff --git a/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp b/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp
index dafe587..94766af 100644
--- a/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp
+++ b/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp
@@ -18,13 +18,15 @@
#include <algorithm>
-#include <VtsHalHidlTargetTestBase.h>
#include <android-base/logging.h>
#include <android/hardware/graphics/mapper/2.0/IMapper.h>
#include <composer-command-buffer/2.3/ComposerCommandBuffer.h>
#include <composer-vts/2.1/GraphicsComposerCallback.h>
#include <composer-vts/2.1/TestCommandReader.h>
#include <composer-vts/2.3/ComposerVts.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include <mapper-vts/2.0/MapperVts.h>
namespace android {
@@ -43,29 +45,11 @@
using mapper::V2_0::IMapper;
using V2_2::vts::Gralloc;
-// Test environment for graphics.composer
-class GraphicsComposerHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static GraphicsComposerHidlEnvironment* Instance() {
- static GraphicsComposerHidlEnvironment* instance = new GraphicsComposerHidlEnvironment;
- return instance;
- }
-
- virtual void registerTestServices() override { registerTestService<IComposer>(); }
-
- private:
- GraphicsComposerHidlEnvironment() {}
-
- GTEST_DISALLOW_COPY_AND_ASSIGN_(GraphicsComposerHidlEnvironment);
-};
-
-class GraphicsComposerHidlTest : public ::testing::VtsHalHidlTargetTestBase {
- protected:
+class GraphicsComposerHidlTest : public ::testing::TestWithParam<std::string> {
+ protected:
void SetUp() override {
ASSERT_NO_FATAL_FAILURE(
- mComposer = std::make_unique<Composer>(
- GraphicsComposerHidlEnvironment::Instance()->getServiceName<IComposer>()));
+ mComposer = std::make_unique<Composer>(IComposer::getService(GetParam())));
ASSERT_NO_FATAL_FAILURE(mComposerClient = mComposer->createClient());
mComposerCallback = new V2_1::vts::GraphicsComposerCallback;
@@ -175,7 +159,7 @@
*
* TODO: Check that ports are unique for multiple displays.
*/
-TEST_F(GraphicsComposerHidlTest, GetDisplayIdentificationData) {
+TEST_P(GraphicsComposerHidlTest, GetDisplayIdentificationData) {
uint8_t port0;
std::vector<uint8_t> data0;
if (mComposerClient->getDisplayIdentificationData(mPrimaryDisplay, &port0, &data0)) {
@@ -193,7 +177,7 @@
/**
* Test IComposerClient::Command::SET_LAYER_PER_FRAME_METADATA.
*/
-TEST_F(GraphicsComposerHidlCommandTest, SET_LAYER_PER_FRAME_METADATA) {
+TEST_P(GraphicsComposerHidlCommandTest, SET_LAYER_PER_FRAME_METADATA) {
Layer layer;
ASSERT_NO_FATAL_FAILURE(layer =
mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount));
@@ -244,7 +228,7 @@
/**
* Test IComposerClient::getHdrCapabilities_2_3
*/
-TEST_F(GraphicsComposerHidlTest, GetHdrCapabilities_2_3) {
+TEST_P(GraphicsComposerHidlTest, GetHdrCapabilities_2_3) {
float maxLuminance;
float maxAverageLuminance;
float minLuminance;
@@ -256,7 +240,7 @@
/**
* Test IComposerClient::getPerFrameMetadataKeys_2_3
*/
-TEST_F(GraphicsComposerHidlTest, GetPerFrameMetadataKeys_2_3) {
+TEST_P(GraphicsComposerHidlTest, GetPerFrameMetadataKeys_2_3) {
std::vector<IComposerClient::PerFrameMetadataKey> keys;
mComposerClient->getRaw()->getPerFrameMetadataKeys_2_3(
mPrimaryDisplay, [&](const auto tmpError, const auto outKeys) {
@@ -270,7 +254,7 @@
/**
* TestIComposerClient::getReadbackBufferAttributes_2_3
*/
-TEST_F(GraphicsComposerHidlTest, GetReadbackBufferAttributes_2_3) {
+TEST_P(GraphicsComposerHidlTest, GetReadbackBufferAttributes_2_3) {
Dataspace dataspace;
PixelFormat pixelFormat;
@@ -288,7 +272,7 @@
/**
* Test IComposerClient::getClientTargetSupport_2_3
*/
-TEST_F(GraphicsComposerHidlTest, GetClientTargetSupport_2_3) {
+TEST_P(GraphicsComposerHidlTest, GetClientTargetSupport_2_3) {
std::vector<V2_1::Config> configs = mComposerClient->getDisplayConfigs(mPrimaryDisplay);
for (auto config : configs) {
int32_t width = mComposerClient->getDisplayAttribute(mPrimaryDisplay, config,
@@ -311,7 +295,7 @@
* Error::BAD_DISPLAY when passed in an invalid display handle
*/
-TEST_F(GraphicsComposerHidlTest, GetClientTargetSupport_2_3BadDisplay) {
+TEST_P(GraphicsComposerHidlTest, GetClientTargetSupport_2_3BadDisplay) {
std::vector<V2_1::Config> configs = mComposerClient->getDisplayConfigs(mPrimaryDisplay);
for (auto config : configs) {
int32_t width = mComposerClient->getDisplayAttribute(mPrimaryDisplay, config,
@@ -333,7 +317,7 @@
/**
* Test IComposerClient::getRenderIntents_2_3
*/
-TEST_F(GraphicsComposerHidlTest, GetRenderIntents_2_3) {
+TEST_P(GraphicsComposerHidlTest, GetRenderIntents_2_3) {
std::vector<ColorMode> modes = mComposerClient->getColorModes_2_3(mPrimaryDisplay);
for (auto mode : modes) {
std::vector<RenderIntent> intents =
@@ -363,7 +347,7 @@
* Test that IComposerClient::getRenderIntents_2_3 returns Error::BAD_DISPLAY when
* passed an invalid display handle
*/
-TEST_F(GraphicsComposerHidlTest, GetRenderIntents_2_3BadDisplay) {
+TEST_P(GraphicsComposerHidlTest, GetRenderIntents_2_3BadDisplay) {
std::vector<ColorMode> modes = mComposerClient->getColorModes_2_3(mPrimaryDisplay);
for (auto mode : modes) {
mComposerClient->getRaw()->getRenderIntents_2_3(
@@ -378,7 +362,7 @@
* Test that IComposerClient::getRenderIntents_2_3 returns Error::BAD_PARAMETER when
* pased either an invalid Color mode or an invalid Render Intent
*/
-TEST_F(GraphicsComposerHidlTest, GetRenderIntents_2_3BadParameter) {
+TEST_P(GraphicsComposerHidlTest, GetRenderIntents_2_3BadParameter) {
mComposerClient->getRaw()->getRenderIntents_2_3(
mPrimaryDisplay, static_cast<ColorMode>(-1),
[&](const auto& tmpError, const auto&) { EXPECT_EQ(Error::BAD_PARAMETER, tmpError); });
@@ -387,7 +371,7 @@
/**
* IComposerClient::getColorModes_2_3
*/
-TEST_F(GraphicsComposerHidlTest, GetColorModes_2_3) {
+TEST_P(GraphicsComposerHidlTest, GetColorModes_2_3) {
std::vector<ColorMode> colorModes = mComposerClient->getColorModes_2_3(mPrimaryDisplay);
auto native = std::find(colorModes.cbegin(), colorModes.cend(), ColorMode::NATIVE);
@@ -400,7 +384,7 @@
* Test that IComposerClient::getColorModes_2_3 returns Error::BAD_DISPLAY when
* passed an invalid display handle
*/
-TEST_F(GraphicsComposerHidlTest, GetColorMode_2_3BadDisplay) {
+TEST_P(GraphicsComposerHidlTest, GetColorMode_2_3BadDisplay) {
mComposerClient->getRaw()->getColorModes_2_3(
mInvalidDisplayId,
[&](const auto& tmpError, const auto&) { ASSERT_EQ(Error::BAD_DISPLAY, tmpError); });
@@ -409,7 +393,7 @@
/**
* IComposerClient::setColorMode_2_3
*/
-TEST_F(GraphicsComposerHidlTest, SetColorMode_2_3) {
+TEST_P(GraphicsComposerHidlTest, SetColorMode_2_3) {
std::vector<ColorMode> colorModes = mComposerClient->getColorModes_2_3(mPrimaryDisplay);
for (auto mode : colorModes) {
std::vector<RenderIntent> intents =
@@ -430,7 +414,7 @@
* Test that IComposerClient::setColorMode_2_3 returns an Error::BAD_DISPLAY
* when passed an invalid display handle
*/
-TEST_F(GraphicsComposerHidlTest, SetColorMode_2_3BadDisplay) {
+TEST_P(GraphicsComposerHidlTest, SetColorMode_2_3BadDisplay) {
Error error = mComposerClient->getRaw()->setColorMode_2_3(mInvalidDisplayId, ColorMode::NATIVE,
RenderIntent::COLORIMETRIC);
@@ -443,7 +427,7 @@
* Test that IComposerClient::setColorMode_2_3 returns Error::BAD_PARAMETER when
* passed an invalid Color mode or an invalid render intent
*/
-TEST_F(GraphicsComposerHidlTest, SetColorMode_2_3BadParameter) {
+TEST_P(GraphicsComposerHidlTest, SetColorMode_2_3BadParameter) {
Error colorModeError = mComposerClient->getRaw()->setColorMode_2_3(
mPrimaryDisplay, static_cast<ColorMode>(-1), RenderIntent::COLORIMETRIC);
EXPECT_EQ(Error::BAD_PARAMETER, colorModeError);
@@ -458,7 +442,7 @@
* TODO Add color to the layer, use matrix to keep only red component,
* and check.
*/
-TEST_F(GraphicsComposerHidlTest, SetLayerColorTransform) {
+TEST_P(GraphicsComposerHidlTest, SetLayerColorTransform) {
Layer layer;
ASSERT_NO_FATAL_FAILURE(layer =
mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount));
@@ -485,7 +469,7 @@
}
}
-TEST_F(GraphicsComposerHidlTest, GetDisplayedContentSamplingAttributes) {
+TEST_P(GraphicsComposerHidlTest, GetDisplayedContentSamplingAttributes) {
int constexpr invalid = -1;
auto format = static_cast<PixelFormat>(invalid);
auto dataspace = static_cast<Dataspace>(invalid);
@@ -505,7 +489,7 @@
static_cast<hidl_bitfield<IComposerClient::FormatColorComponent>>(invalid));
};
-TEST_F(GraphicsComposerHidlTest, SetDisplayedContentSamplingEnabled) {
+TEST_P(GraphicsComposerHidlTest, SetDisplayedContentSamplingEnabled) {
auto const maxFrames = 10;
auto const enableAllComponents = 0;
auto error = mComposerClient->setDisplayedContentSamplingEnabled(
@@ -523,7 +507,7 @@
EXPECT_EQ(error, Error::NONE);
}
-TEST_F(GraphicsComposerHidlTest, GetDisplayedContentSample) {
+TEST_P(GraphicsComposerHidlTest, GetDisplayedContentSample) {
int constexpr invalid = -1;
auto format = static_cast<PixelFormat>(invalid);
auto dataspace = static_cast<Dataspace>(invalid);
@@ -558,7 +542,7 @@
* getDisplayCapabilities is required in composer 2.3
* Test some constraints.
*/
-TEST_F(GraphicsComposerHidlTest, getDisplayCapabilitiesBasic) {
+TEST_P(GraphicsComposerHidlTest, getDisplayCapabilitiesBasic) {
std::vector<IComposerClient::DisplayCapability> capabilities;
const auto error = mComposerClient->getDisplayCapabilities(mPrimaryDisplay, &capabilities);
ASSERT_EQ(Error::NONE, error);
@@ -572,13 +556,13 @@
EXPECT_EQ(mComposerClient->getDisplayBrightnessSupport(mPrimaryDisplay), hasBrightnessSupport);
}
-TEST_F(GraphicsComposerHidlTest, getDisplayCapabilitiesBadDisplay) {
+TEST_P(GraphicsComposerHidlTest, getDisplayCapabilitiesBadDisplay) {
std::vector<IComposerClient::DisplayCapability> capabilities;
const auto error = mComposerClient->getDisplayCapabilities(mInvalidDisplayId, &capabilities);
EXPECT_EQ(Error::BAD_DISPLAY, error);
}
-TEST_F(GraphicsComposerHidlTest, SetLayerPerFrameMetadataBlobs) {
+TEST_P(GraphicsComposerHidlTest, SetLayerPerFrameMetadataBlobs) {
Layer layer;
ASSERT_NO_FATAL_FAILURE(layer =
mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount));
@@ -604,7 +588,7 @@
/*
* Test that if brightness operations are supported, setDisplayBrightness works as expected.
*/
-TEST_F(GraphicsComposerHidlTest, setDisplayBrightness) {
+TEST_P(GraphicsComposerHidlTest, setDisplayBrightness) {
std::vector<IComposerClient::DisplayCapability> capabilities;
const auto error = mComposerClient->getDisplayCapabilities(mPrimaryDisplay, &capabilities);
ASSERT_EQ(Error::NONE, error);
@@ -627,6 +611,16 @@
EXPECT_EQ(mComposerClient->setDisplayBrightness(mPrimaryDisplay, -2.0f), Error::BAD_PARAMETER);
}
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, GraphicsComposerHidlTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(IComposer::descriptor)),
+ android::hardware::PrintInstanceNameToString);
+
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, GraphicsComposerHidlCommandTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(IComposer::descriptor)),
+ android::hardware::PrintInstanceNameToString);
+
} // namespace
} // namespace vts
} // namespace V2_3
@@ -634,12 +628,3 @@
} // namespace graphics
} // namespace hardware
} // namespace android
-
-int main(int argc, char** argv) {
- using android::hardware::graphics::composer::V2_3::vts::GraphicsComposerHidlEnvironment;
- ::testing::AddGlobalTestEnvironment(GraphicsComposerHidlEnvironment::Instance());
- ::testing::InitGoogleTest(&argc, argv);
- GraphicsComposerHidlEnvironment::Instance()->init(&argc, argv);
- int status = RUN_ALL_TESTS();
- return status;
-}
diff --git a/graphics/mapper/2.0/utils/vts/MapperVts.cpp b/graphics/mapper/2.0/utils/vts/MapperVts.cpp
index d08ac56..d4e4dde 100644
--- a/graphics/mapper/2.0/utils/vts/MapperVts.cpp
+++ b/graphics/mapper/2.0/utils/vts/MapperVts.cpp
@@ -16,8 +16,6 @@
#include <mapper-vts/2.0/MapperVts.h>
-#include <VtsHalHidlTargetTestBase.h>
-
namespace android {
namespace hardware {
namespace graphics {
@@ -30,10 +28,10 @@
}
void Gralloc::init(const std::string& allocatorServiceName, const std::string& mapperServiceName) {
- mAllocator = ::testing::VtsHalHidlTargetTestBase::getService<IAllocator>(allocatorServiceName);
+ mAllocator = IAllocator::getService(allocatorServiceName);
ASSERT_NE(nullptr, mAllocator.get()) << "failed to get allocator service";
- mMapper = ::testing::VtsHalHidlTargetTestBase::getService<IMapper>(mapperServiceName);
+ mMapper = IMapper::getService(mapperServiceName);
ASSERT_NE(nullptr, mMapper.get()) << "failed to get mapper service";
ASSERT_FALSE(mMapper->isRemote()) << "mapper is not in passthrough mode";
}
diff --git a/graphics/mapper/2.0/utils/vts/include/mapper-vts/2.0/MapperVts.h b/graphics/mapper/2.0/utils/vts/include/mapper-vts/2.0/MapperVts.h
index 6c2c9a6..fc8a102 100644
--- a/graphics/mapper/2.0/utils/vts/include/mapper-vts/2.0/MapperVts.h
+++ b/graphics/mapper/2.0/utils/vts/include/mapper-vts/2.0/MapperVts.h
@@ -22,6 +22,7 @@
#include <android/hardware/graphics/allocator/2.0/IAllocator.h>
#include <android/hardware/graphics/mapper/2.0/IMapper.h>
+#include <gtest/gtest.h>
#include <utils/StrongPointer.h>
namespace android {
diff --git a/graphics/mapper/2.0/vts/functional/Android.bp b/graphics/mapper/2.0/vts/functional/Android.bp
index 853c2a3..a055b61 100644
--- a/graphics/mapper/2.0/vts/functional/Android.bp
+++ b/graphics/mapper/2.0/vts/functional/Android.bp
@@ -24,5 +24,5 @@
"android.hardware.graphics.mapper@2.0",
"android.hardware.graphics.mapper@2.0-vts",
],
- test_suites: ["general-tests"],
+ test_suites: ["general-tests", "vts-core"],
}
diff --git a/graphics/mapper/2.0/vts/functional/VtsHalGraphicsMapperV2_0TargetTest.cpp b/graphics/mapper/2.0/vts/functional/VtsHalGraphicsMapperV2_0TargetTest.cpp
index 5ec0af2..b079a4b 100644
--- a/graphics/mapper/2.0/vts/functional/VtsHalGraphicsMapperV2_0TargetTest.cpp
+++ b/graphics/mapper/2.0/vts/functional/VtsHalGraphicsMapperV2_0TargetTest.cpp
@@ -20,8 +20,10 @@
#include <thread>
#include <vector>
-#include <VtsHalHidlTargetTestBase.h>
#include <android-base/logging.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include <mapper-vts/2.0/MapperVts.h>
namespace android {
@@ -35,28 +37,12 @@
using android::hardware::graphics::common::V1_0::BufferUsage;
using android::hardware::graphics::common::V1_0::PixelFormat;
-// Test environment for graphics.mapper.
-class GraphicsMapperHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static GraphicsMapperHidlEnvironment* Instance() {
- static GraphicsMapperHidlEnvironment* instance = new GraphicsMapperHidlEnvironment;
- return instance;
- }
-
- virtual void registerTestServices() override {
- registerTestService<IAllocator>();
- registerTestService<IMapper>();
- }
-};
-
-class GraphicsMapperHidlTest : public ::testing::VtsHalHidlTargetTestBase {
- protected:
+class GraphicsMapperHidlTest
+ : public ::testing::TestWithParam<std::tuple<std::string, std::string>> {
+ protected:
void SetUp() override {
- ASSERT_NO_FATAL_FAILURE(
- mGralloc = std::make_unique<Gralloc>(
- GraphicsMapperHidlEnvironment::Instance()->getServiceName<IAllocator>(),
- GraphicsMapperHidlEnvironment::Instance()->getServiceName<IMapper>()));
+ ASSERT_NO_FATAL_FAILURE(mGralloc = std::make_unique<Gralloc>(std::get<0>(GetParam()),
+ std::get<1>(GetParam())));
mDummyDescriptorInfo.width = 64;
mDummyDescriptorInfo.height = 64;
@@ -75,14 +61,14 @@
/**
* Test IAllocator::dumpDebugInfo by calling it.
*/
-TEST_F(GraphicsMapperHidlTest, AllocatorDumpDebugInfo) {
+TEST_P(GraphicsMapperHidlTest, AllocatorDumpDebugInfo) {
mGralloc->dumpDebugInfo();
}
/**
* Test IAllocator::allocate with valid buffer descriptors.
*/
-TEST_F(GraphicsMapperHidlTest, AllocatorAllocate) {
+TEST_P(GraphicsMapperHidlTest, AllocatorAllocate) {
BufferDescriptor descriptor;
ASSERT_NO_FATAL_FAILURE(descriptor = mGralloc->createDescriptor(mDummyDescriptorInfo));
@@ -105,7 +91,7 @@
/**
* Test IAllocator::allocate with invalid buffer descriptors.
*/
-TEST_F(GraphicsMapperHidlTest, AllocatorAllocateNegative) {
+TEST_P(GraphicsMapperHidlTest, AllocatorAllocateNegative) {
// this assumes any valid descriptor is non-empty
BufferDescriptor descriptor;
mGralloc->getAllocator()->allocate(descriptor, 1,
@@ -117,7 +103,7 @@
/**
* Test IAllocator::allocate does not leak.
*/
-TEST_F(GraphicsMapperHidlTest, AllocatorAllocateNoLeak) {
+TEST_P(GraphicsMapperHidlTest, AllocatorAllocateNoLeak) {
auto info = mDummyDescriptorInfo;
info.width = 1024;
info.height = 1024;
@@ -131,7 +117,7 @@
/**
* Test that IAllocator::allocate is thread-safe.
*/
-TEST_F(GraphicsMapperHidlTest, AllocatorAllocateThreaded) {
+TEST_P(GraphicsMapperHidlTest, AllocatorAllocateThreaded) {
BufferDescriptor descriptor;
ASSERT_NO_FATAL_FAILURE(descriptor = mGralloc->createDescriptor(mDummyDescriptorInfo));
@@ -161,14 +147,14 @@
/**
* Test IMapper::createDescriptor with valid descriptor info.
*/
-TEST_F(GraphicsMapperHidlTest, CreateDescriptorBasic) {
+TEST_P(GraphicsMapperHidlTest, CreateDescriptorBasic) {
ASSERT_NO_FATAL_FAILURE(mGralloc->createDescriptor(mDummyDescriptorInfo));
}
/**
* Test IMapper::createDescriptor with invalid descriptor info.
*/
-TEST_F(GraphicsMapperHidlTest, CreateDescriptorNegative) {
+TEST_P(GraphicsMapperHidlTest, CreateDescriptorNegative) {
auto info = mDummyDescriptorInfo;
info.width = 0;
mGralloc->getMapper()->createDescriptor(info, [&](const auto& tmpError, const auto&) {
@@ -179,7 +165,7 @@
/**
* Test IMapper::importBuffer and IMapper::freeBuffer with allocated buffers.
*/
-TEST_F(GraphicsMapperHidlTest, ImportFreeBufferBasic) {
+TEST_P(GraphicsMapperHidlTest, ImportFreeBufferBasic) {
const native_handle_t* bufferHandle;
ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(mDummyDescriptorInfo, true));
ASSERT_NO_FATAL_FAILURE(mGralloc->freeBuffer(bufferHandle));
@@ -188,7 +174,7 @@
/**
* Test IMapper::importBuffer and IMapper::freeBuffer with cloned buffers.
*/
-TEST_F(GraphicsMapperHidlTest, ImportFreeBufferClone) {
+TEST_P(GraphicsMapperHidlTest, ImportFreeBufferClone) {
const native_handle_t* clonedBufferHandle;
ASSERT_NO_FATAL_FAILURE(clonedBufferHandle = mGralloc->allocate(mDummyDescriptorInfo, false));
@@ -206,7 +192,7 @@
/**
* Test IMapper::importBuffer and IMapper::freeBuffer cross mapper instances.
*/
-TEST_F(GraphicsMapperHidlTest, ImportFreeBufferSingleton) {
+TEST_P(GraphicsMapperHidlTest, ImportFreeBufferSingleton) {
const native_handle_t* rawHandle;
ASSERT_NO_FATAL_FAILURE(rawHandle = mGralloc->allocate(mDummyDescriptorInfo, false));
@@ -218,10 +204,8 @@
// free the imported handle with another mapper
std::unique_ptr<Gralloc> anotherGralloc;
- ASSERT_NO_FATAL_FAILURE(
- anotherGralloc = std::make_unique<Gralloc>(
- GraphicsMapperHidlEnvironment::Instance()->getServiceName<IAllocator>(),
- GraphicsMapperHidlEnvironment::Instance()->getServiceName<IMapper>()));
+ ASSERT_NO_FATAL_FAILURE(anotherGralloc = std::make_unique<Gralloc>(std::get<0>(GetParam()),
+ std::get<1>(GetParam())));
Error error = mGralloc->getMapper()->freeBuffer(importedHandle);
ASSERT_EQ(Error::NONE, error);
@@ -231,7 +215,7 @@
/**
* Test IMapper::importBuffer and IMapper::freeBuffer do not leak.
*/
-TEST_F(GraphicsMapperHidlTest, ImportFreeBufferNoLeak) {
+TEST_P(GraphicsMapperHidlTest, ImportFreeBufferNoLeak) {
auto info = mDummyDescriptorInfo;
info.width = 1024;
info.height = 1024;
@@ -245,7 +229,7 @@
/**
* Test IMapper::importBuffer with invalid buffers.
*/
-TEST_F(GraphicsMapperHidlTest, ImportBufferNegative) {
+TEST_P(GraphicsMapperHidlTest, ImportBufferNegative) {
native_handle_t* invalidHandle = nullptr;
mGralloc->getMapper()->importBuffer(invalidHandle, [&](const auto& tmpError, const auto&) {
EXPECT_EQ(Error::BAD_BUFFER, tmpError)
@@ -263,7 +247,7 @@
/**
* Test IMapper::freeBuffer with invalid buffers.
*/
-TEST_F(GraphicsMapperHidlTest, FreeBufferNegative) {
+TEST_P(GraphicsMapperHidlTest, FreeBufferNegative) {
native_handle_t* invalidHandle = nullptr;
Error error = mGralloc->getMapper()->freeBuffer(invalidHandle);
EXPECT_EQ(Error::BAD_BUFFER, error) << "freeBuffer with nullptr did not fail with BAD_BUFFER";
@@ -286,7 +270,7 @@
/**
* Test IMapper::lock and IMapper::unlock.
*/
-TEST_F(GraphicsMapperHidlTest, LockUnlockBasic) {
+TEST_P(GraphicsMapperHidlTest, LockUnlockBasic) {
const auto& info = mDummyDescriptorInfo;
const native_handle_t* bufferHandle;
@@ -332,7 +316,7 @@
* Test IMapper::lockYCbCr. This locks a YV12 buffer, and makes sure we can
* write to and read from it.
*/
-TEST_F(GraphicsMapperHidlTest, LockYCbCrBasic) {
+TEST_P(GraphicsMapperHidlTest, LockYCbCrBasic) {
auto info = mDummyDescriptorInfo;
info.format = PixelFormat::YV12;
@@ -391,7 +375,7 @@
/**
* Test IMapper::unlock with invalid buffers.
*/
-TEST_F(GraphicsMapperHidlTest, UnlockNegative) {
+TEST_P(GraphicsMapperHidlTest, UnlockNegative) {
native_handle_t* invalidHandle = nullptr;
mGralloc->getMapper()->unlock(invalidHandle, [&](const auto& tmpError, const auto&) {
EXPECT_EQ(Error::BAD_BUFFER, tmpError)
@@ -426,6 +410,14 @@
#endif
}
+INSTANTIATE_TEST_CASE_P(
+ PerInstance, GraphicsMapperHidlTest,
+ testing::Combine(
+ testing::ValuesIn(
+ android::hardware::getAllHalInstanceNames(IAllocator::descriptor)),
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(IMapper::descriptor))),
+ android::hardware::PrintInstanceTupleNameToString<>);
+
} // namespace
} // namespace vts
} // namespace V2_0
@@ -433,13 +425,3 @@
} // namespace graphics
} // namespace hardware
} // namespace android
-
-int main(int argc, char** argv) {
- using android::hardware::graphics::mapper::V2_0::vts::GraphicsMapperHidlEnvironment;
- ::testing::AddGlobalTestEnvironment(GraphicsMapperHidlEnvironment::Instance());
- ::testing::InitGoogleTest(&argc, argv);
- GraphicsMapperHidlEnvironment::Instance()->init(&argc, argv);
- int status = RUN_ALL_TESTS();
- LOG(INFO) << "Test result = " << status;
- return status;
-}
diff --git a/graphics/mapper/2.1/utils/vts/Android.bp b/graphics/mapper/2.1/utils/vts/Android.bp
index ca02aad..abbe50a 100644
--- a/graphics/mapper/2.1/utils/vts/Android.bp
+++ b/graphics/mapper/2.1/utils/vts/Android.bp
@@ -16,14 +16,13 @@
cc_library_static {
name: "android.hardware.graphics.mapper@2.1-vts",
- defaults: ["hidl_defaults"],
+ defaults: ["hidl_defaults", "VtsHalTargetTestDefaults"],
srcs: ["MapperVts.cpp"],
cflags: [
"-O0",
"-g",
],
static_libs: [
- "VtsHalHidlTargetTestBase",
"android.hardware.graphics.allocator@2.0",
"android.hardware.graphics.mapper@2.0",
"android.hardware.graphics.mapper@2.0-vts",
diff --git a/graphics/mapper/2.1/utils/vts/MapperVts.cpp b/graphics/mapper/2.1/utils/vts/MapperVts.cpp
index 36f9cbb..239de74 100644
--- a/graphics/mapper/2.1/utils/vts/MapperVts.cpp
+++ b/graphics/mapper/2.1/utils/vts/MapperVts.cpp
@@ -16,8 +16,6 @@
#include <mapper-vts/2.1/MapperVts.h>
-#include <VtsHalHidlTargetTestBase.h>
-
namespace android {
namespace hardware {
namespace graphics {
diff --git a/graphics/mapper/2.1/vts/functional/Android.bp b/graphics/mapper/2.1/vts/functional/Android.bp
index afd8e7f..bb76c74 100644
--- a/graphics/mapper/2.1/vts/functional/Android.bp
+++ b/graphics/mapper/2.1/vts/functional/Android.bp
@@ -26,5 +26,5 @@
"android.hardware.graphics.mapper@2.0-vts",
"android.hardware.graphics.mapper@2.1-vts",
],
- test_suites: ["general-tests"],
+ test_suites: ["general-tests", "vts-core"],
}
diff --git a/graphics/mapper/2.1/vts/functional/VtsHalGraphicsMapperV2_1TargetTest.cpp b/graphics/mapper/2.1/vts/functional/VtsHalGraphicsMapperV2_1TargetTest.cpp
index 5e7cf93..1185945 100644
--- a/graphics/mapper/2.1/vts/functional/VtsHalGraphicsMapperV2_1TargetTest.cpp
+++ b/graphics/mapper/2.1/vts/functional/VtsHalGraphicsMapperV2_1TargetTest.cpp
@@ -16,9 +16,11 @@
#define LOG_TAG "VtsHalGraphicsMapperV2_1TargetTest"
-#include <VtsHalHidlTargetTestBase.h>
#include <android-base/logging.h>
#include <android/hardware/graphics/mapper/2.1/IMapper.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include <mapper-vts/2.1/MapperVts.h>
namespace android {
@@ -34,28 +36,12 @@
using android::hardware::graphics::common::V1_1::PixelFormat;
using V2_0::Error;
-// Test environment for graphics.mapper.
-class GraphicsMapperHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static GraphicsMapperHidlEnvironment* Instance() {
- static GraphicsMapperHidlEnvironment* instance = new GraphicsMapperHidlEnvironment;
- return instance;
- }
-
- virtual void registerTestServices() override {
- registerTestService<IAllocator>();
- registerTestService<IMapper>();
- }
-};
-
-class GraphicsMapperHidlTest : public ::testing::VtsHalHidlTargetTestBase {
- protected:
+class GraphicsMapperHidlTest
+ : public ::testing::TestWithParam<std::tuple<std::string, std::string>> {
+ protected:
void SetUp() override {
- ASSERT_NO_FATAL_FAILURE(
- mGralloc = std::make_unique<Gralloc>(
- GraphicsMapperHidlEnvironment::Instance()->getServiceName<IAllocator>(),
- GraphicsMapperHidlEnvironment::Instance()->getServiceName<IMapper>()));
+ ASSERT_NO_FATAL_FAILURE(mGralloc = std::make_unique<Gralloc>(std::get<0>(GetParam()),
+ std::get<1>(GetParam())));
mDummyDescriptorInfo.width = 64;
mDummyDescriptorInfo.height = 64;
@@ -74,7 +60,7 @@
/**
* Test that IMapper::validateBufferSize works.
*/
-TEST_F(GraphicsMapperHidlTest, ValidateBufferSizeBasic) {
+TEST_P(GraphicsMapperHidlTest, ValidateBufferSizeBasic) {
const native_handle_t* bufferHandle;
uint32_t stride;
ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(mDummyDescriptorInfo, true, &stride));
@@ -87,7 +73,7 @@
/**
* Test IMapper::validateBufferSize with invalid buffers.
*/
-TEST_F(GraphicsMapperHidlTest, ValidateBufferSizeBadBuffer) {
+TEST_P(GraphicsMapperHidlTest, ValidateBufferSizeBadBuffer) {
native_handle_t* invalidHandle = nullptr;
Error ret = mGralloc->getMapper()->validateBufferSize(invalidHandle, mDummyDescriptorInfo,
mDummyDescriptorInfo.width);
@@ -114,7 +100,7 @@
/**
* Test IMapper::validateBufferSize with invalid descriptor and/or stride.
*/
-TEST_F(GraphicsMapperHidlTest, ValidateBufferSizeBadValue) {
+TEST_P(GraphicsMapperHidlTest, ValidateBufferSizeBadValue) {
auto info = mDummyDescriptorInfo;
info.width = 1024;
info.height = 1024;
@@ -161,7 +147,7 @@
/**
* Test IMapper::getTransportSize.
*/
-TEST_F(GraphicsMapperHidlTest, GetTransportSizeBasic) {
+TEST_P(GraphicsMapperHidlTest, GetTransportSizeBasic) {
const native_handle_t* bufferHandle;
uint32_t numFds;
uint32_t numInts;
@@ -173,7 +159,7 @@
/**
* Test IMapper::getTransportSize with invalid buffers.
*/
-TEST_F(GraphicsMapperHidlTest, GetTransportSizeBadBuffer) {
+TEST_P(GraphicsMapperHidlTest, GetTransportSizeBadBuffer) {
native_handle_t* invalidHandle = nullptr;
mGralloc->getMapper()->getTransportSize(
invalidHandle, [&](const auto& tmpError, const auto&, const auto&) {
@@ -203,14 +189,14 @@
/**
* Test IMapper::createDescriptor with valid descriptor info.
*/
-TEST_F(GraphicsMapperHidlTest, CreateDescriptor_2_1Basic) {
+TEST_P(GraphicsMapperHidlTest, CreateDescriptor_2_1Basic) {
ASSERT_NO_FATAL_FAILURE(mGralloc->createDescriptor(mDummyDescriptorInfo));
}
/**
* Test IMapper::createDescriptor with invalid descriptor info.
*/
-TEST_F(GraphicsMapperHidlTest, CreateDescriptor_2_1Negative) {
+TEST_P(GraphicsMapperHidlTest, CreateDescriptor_2_1Negative) {
auto info = mDummyDescriptorInfo;
info.width = 0;
mGralloc->getMapper()->createDescriptor_2_1(info, [&](const auto& tmpError, const auto&) {
@@ -218,22 +204,18 @@
});
}
+INSTANTIATE_TEST_CASE_P(
+ PerInstance, GraphicsMapperHidlTest,
+ testing::Combine(
+ testing::ValuesIn(
+ android::hardware::getAllHalInstanceNames(IAllocator::descriptor)),
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(IMapper::descriptor))),
+ android::hardware::PrintInstanceTupleNameToString<>);
+
} // namespace
} // namespace vts
} // namespace V2_1
} // namespace mapper
} // namespace graphics
} // namespace hardware
-} // namespace android
-
-int main(int argc, char** argv) {
- using android::hardware::graphics::mapper::V2_1::vts::GraphicsMapperHidlEnvironment;
- ::testing::AddGlobalTestEnvironment(GraphicsMapperHidlEnvironment::Instance());
- ::testing::InitGoogleTest(&argc, argv);
- GraphicsMapperHidlEnvironment::Instance()->init(&argc, argv);
-
- int status = RUN_ALL_TESTS();
- LOG(INFO) << "Test result = " << status;
-
- return status;
-}
+} // namespace android
\ No newline at end of file
diff --git a/graphics/mapper/3.0/utils/vts/MapperVts.cpp b/graphics/mapper/3.0/utils/vts/MapperVts.cpp
index c94e8db..de886a9 100644
--- a/graphics/mapper/3.0/utils/vts/MapperVts.cpp
+++ b/graphics/mapper/3.0/utils/vts/MapperVts.cpp
@@ -16,8 +16,6 @@
#include <mapper-vts/3.0/MapperVts.h>
-#include <VtsHalHidlTargetTestBase.h>
-
namespace android {
namespace hardware {
namespace graphics {
@@ -35,19 +33,19 @@
}
void Gralloc::init(const std::string& allocatorServiceName, const std::string& mapperServiceName) {
- mAllocator = ::testing::VtsHalHidlTargetTestBase::getService<IAllocator>(allocatorServiceName);
+ mAllocator = IAllocator::getService(allocatorServiceName);
ASSERT_NE(nullptr, mAllocator.get()) << "failed to get allocator service";
- mMapper = ::testing::VtsHalHidlTargetTestBase::getService<IMapper>(mapperServiceName);
+ mMapper = IMapper::getService(mapperServiceName);
ASSERT_NE(nullptr, mMapper.get()) << "failed to get mapper service";
ASSERT_FALSE(mMapper->isRemote()) << "mapper is not in passthrough mode";
}
void Gralloc::initNoErr(const std::string& allocatorServiceName,
const std::string& mapperServiceName) {
- mAllocator = ::testing::VtsHalHidlTargetTestBase::getService<IAllocator>(allocatorServiceName);
+ mAllocator = IAllocator::getService(allocatorServiceName);
- mMapper = ::testing::VtsHalHidlTargetTestBase::getService<IMapper>(mapperServiceName);
+ mMapper = IMapper::getService(mapperServiceName);
if (mMapper.get()) {
ASSERT_FALSE(mMapper->isRemote()) << "mapper is not in passthrough mode";
}
diff --git a/graphics/mapper/3.0/utils/vts/include/mapper-vts/3.0/MapperVts.h b/graphics/mapper/3.0/utils/vts/include/mapper-vts/3.0/MapperVts.h
index 1141a88..b2fbebb1 100644
--- a/graphics/mapper/3.0/utils/vts/include/mapper-vts/3.0/MapperVts.h
+++ b/graphics/mapper/3.0/utils/vts/include/mapper-vts/3.0/MapperVts.h
@@ -22,6 +22,7 @@
#include <android/hardware/graphics/allocator/3.0/IAllocator.h>
#include <android/hardware/graphics/mapper/3.0/IMapper.h>
+#include <gtest/gtest.h>
#include <utils/StrongPointer.h>
namespace android {
diff --git a/graphics/mapper/3.0/vts/functional/Android.bp b/graphics/mapper/3.0/vts/functional/Android.bp
index 77075a5..f01670e 100644
--- a/graphics/mapper/3.0/vts/functional/Android.bp
+++ b/graphics/mapper/3.0/vts/functional/Android.bp
@@ -26,5 +26,5 @@
"android.hardware.graphics.mapper@3.0",
"android.hardware.graphics.mapper@3.0-vts",
],
- test_suites: ["general-tests"],
+ test_suites: ["general-tests", "vts-core"],
}
diff --git a/graphics/mapper/3.0/vts/functional/VtsHalGraphicsMapperV3_0TargetTest.cpp b/graphics/mapper/3.0/vts/functional/VtsHalGraphicsMapperV3_0TargetTest.cpp
index ff73ecf..92b5994 100644
--- a/graphics/mapper/3.0/vts/functional/VtsHalGraphicsMapperV3_0TargetTest.cpp
+++ b/graphics/mapper/3.0/vts/functional/VtsHalGraphicsMapperV3_0TargetTest.cpp
@@ -20,8 +20,10 @@
#include <thread>
#include <vector>
-#include <VtsHalHidlTargetTestBase.h>
#include <android-base/logging.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include <mapper-vts/3.0/MapperVts.h>
namespace android {
@@ -35,28 +37,12 @@
using android::hardware::graphics::common::V1_2::BufferUsage;
using android::hardware::graphics::common::V1_2::PixelFormat;
-// Test environment for graphics.mapper.
-class GraphicsMapperHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static GraphicsMapperHidlEnvironment* Instance() {
- static GraphicsMapperHidlEnvironment* instance = new GraphicsMapperHidlEnvironment;
- return instance;
- }
-
- virtual void registerTestServices() override {
- registerTestService<IAllocator>();
- registerTestService<IMapper>();
- }
-};
-
-class GraphicsMapperHidlTest : public ::testing::VtsHalHidlTargetTestBase {
- protected:
+class GraphicsMapperHidlTest
+ : public ::testing::TestWithParam<std::tuple<std::string, std::string>> {
+ protected:
void SetUp() override {
- ASSERT_NO_FATAL_FAILURE(
- mGralloc = std::make_unique<Gralloc>(
- GraphicsMapperHidlEnvironment::Instance()->getServiceName<IAllocator>(),
- GraphicsMapperHidlEnvironment::Instance()->getServiceName<IMapper>()));
+ ASSERT_NO_FATAL_FAILURE(mGralloc = std::make_unique<Gralloc>(std::get<0>(GetParam()),
+ std::get<1>(GetParam())));
mDummyDescriptorInfo.width = 64;
mDummyDescriptorInfo.height = 64;
@@ -75,14 +61,14 @@
/**
* Test IAllocator::dumpDebugInfo by calling it.
*/
-TEST_F(GraphicsMapperHidlTest, AllocatorDumpDebugInfo) {
+TEST_P(GraphicsMapperHidlTest, AllocatorDumpDebugInfo) {
mGralloc->dumpDebugInfo();
}
/**
* Test IAllocator::allocate with valid buffer descriptors.
*/
-TEST_F(GraphicsMapperHidlTest, AllocatorAllocate) {
+TEST_P(GraphicsMapperHidlTest, AllocatorAllocate) {
BufferDescriptor descriptor;
ASSERT_NO_FATAL_FAILURE(descriptor = mGralloc->createDescriptor(mDummyDescriptorInfo));
@@ -105,7 +91,7 @@
/**
* Test IAllocator::allocate with invalid buffer descriptors.
*/
-TEST_F(GraphicsMapperHidlTest, AllocatorAllocateNegative) {
+TEST_P(GraphicsMapperHidlTest, AllocatorAllocateNegative) {
// this assumes any valid descriptor is non-empty
BufferDescriptor descriptor;
mGralloc->getAllocator()->allocate(descriptor, 1,
@@ -117,7 +103,7 @@
/**
* Test IAllocator::allocate does not leak.
*/
-TEST_F(GraphicsMapperHidlTest, AllocatorAllocateNoLeak) {
+TEST_P(GraphicsMapperHidlTest, AllocatorAllocateNoLeak) {
auto info = mDummyDescriptorInfo;
info.width = 1024;
info.height = 1024;
@@ -131,7 +117,7 @@
/**
* Test that IAllocator::allocate is thread-safe.
*/
-TEST_F(GraphicsMapperHidlTest, AllocatorAllocateThreaded) {
+TEST_P(GraphicsMapperHidlTest, AllocatorAllocateThreaded) {
BufferDescriptor descriptor;
ASSERT_NO_FATAL_FAILURE(descriptor = mGralloc->createDescriptor(mDummyDescriptorInfo));
@@ -161,14 +147,14 @@
/**
* Test IMapper::createDescriptor with valid descriptor info.
*/
-TEST_F(GraphicsMapperHidlTest, CreateDescriptorBasic) {
+TEST_P(GraphicsMapperHidlTest, CreateDescriptorBasic) {
ASSERT_NO_FATAL_FAILURE(mGralloc->createDescriptor(mDummyDescriptorInfo));
}
/**
* Test IMapper::createDescriptor with invalid descriptor info.
*/
-TEST_F(GraphicsMapperHidlTest, CreateDescriptorNegative) {
+TEST_P(GraphicsMapperHidlTest, CreateDescriptorNegative) {
auto info = mDummyDescriptorInfo;
info.width = 0;
mGralloc->getMapper()->createDescriptor(info, [&](const auto& tmpError, const auto&) {
@@ -179,7 +165,7 @@
/**
* Test IMapper::importBuffer and IMapper::freeBuffer with allocated buffers.
*/
-TEST_F(GraphicsMapperHidlTest, ImportFreeBufferBasic) {
+TEST_P(GraphicsMapperHidlTest, ImportFreeBufferBasic) {
const native_handle_t* bufferHandle;
ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(mDummyDescriptorInfo, true));
ASSERT_NO_FATAL_FAILURE(mGralloc->freeBuffer(bufferHandle));
@@ -188,7 +174,7 @@
/**
* Test IMapper::importBuffer and IMapper::freeBuffer with cloned buffers.
*/
-TEST_F(GraphicsMapperHidlTest, ImportFreeBufferClone) {
+TEST_P(GraphicsMapperHidlTest, ImportFreeBufferClone) {
const native_handle_t* clonedBufferHandle;
ASSERT_NO_FATAL_FAILURE(clonedBufferHandle = mGralloc->allocate(mDummyDescriptorInfo, false));
@@ -206,7 +192,7 @@
/**
* Test IMapper::importBuffer and IMapper::freeBuffer cross mapper instances.
*/
-TEST_F(GraphicsMapperHidlTest, ImportFreeBufferSingleton) {
+TEST_P(GraphicsMapperHidlTest, ImportFreeBufferSingleton) {
const native_handle_t* rawHandle;
ASSERT_NO_FATAL_FAILURE(rawHandle = mGralloc->allocate(mDummyDescriptorInfo, false));
@@ -218,10 +204,8 @@
// free the imported handle with another mapper
std::unique_ptr<Gralloc> anotherGralloc;
- ASSERT_NO_FATAL_FAILURE(
- anotherGralloc = std::make_unique<Gralloc>(
- GraphicsMapperHidlEnvironment::Instance()->getServiceName<IAllocator>(),
- GraphicsMapperHidlEnvironment::Instance()->getServiceName<IMapper>()));
+ ASSERT_NO_FATAL_FAILURE(anotherGralloc = std::make_unique<Gralloc>(std::get<0>(GetParam()),
+ std::get<1>(GetParam())));
Error error = mGralloc->getMapper()->freeBuffer(importedHandle);
ASSERT_EQ(Error::NONE, error);
@@ -231,7 +215,7 @@
/**
* Test IMapper::importBuffer and IMapper::freeBuffer do not leak.
*/
-TEST_F(GraphicsMapperHidlTest, ImportFreeBufferNoLeak) {
+TEST_P(GraphicsMapperHidlTest, ImportFreeBufferNoLeak) {
auto info = mDummyDescriptorInfo;
info.width = 1024;
info.height = 1024;
@@ -245,7 +229,7 @@
/**
* Test IMapper::importBuffer with invalid buffers.
*/
-TEST_F(GraphicsMapperHidlTest, ImportBufferNegative) {
+TEST_P(GraphicsMapperHidlTest, ImportBufferNegative) {
native_handle_t* invalidHandle = nullptr;
mGralloc->getMapper()->importBuffer(invalidHandle, [&](const auto& tmpError, const auto&) {
EXPECT_EQ(Error::BAD_BUFFER, tmpError)
@@ -263,7 +247,7 @@
/**
* Test IMapper::freeBuffer with invalid buffers.
*/
-TEST_F(GraphicsMapperHidlTest, FreeBufferNegative) {
+TEST_P(GraphicsMapperHidlTest, FreeBufferNegative) {
native_handle_t* invalidHandle = nullptr;
Error error = mGralloc->getMapper()->freeBuffer(invalidHandle);
EXPECT_EQ(Error::BAD_BUFFER, error) << "freeBuffer with nullptr did not fail with BAD_BUFFER";
@@ -286,7 +270,7 @@
/**
* Test IMapper::lock and IMapper::unlock.
*/
-TEST_F(GraphicsMapperHidlTest, LockUnlockBasic) {
+TEST_P(GraphicsMapperHidlTest, LockUnlockBasic) {
const auto& info = mDummyDescriptorInfo;
const native_handle_t* bufferHandle;
@@ -346,7 +330,7 @@
* Test IMapper::lockYCbCr. This locks a YV12 buffer, and makes sure we can
* write to and read from it.
*/
-TEST_F(GraphicsMapperHidlTest, LockYCbCrBasic) {
+TEST_P(GraphicsMapperHidlTest, LockYCbCrBasic) {
auto info = mDummyDescriptorInfo;
info.format = PixelFormat::YV12;
@@ -405,7 +389,7 @@
/**
* Test IMapper::unlock with invalid buffers.
*/
-TEST_F(GraphicsMapperHidlTest, UnlockNegative) {
+TEST_P(GraphicsMapperHidlTest, UnlockNegative) {
native_handle_t* invalidHandle = nullptr;
mGralloc->getMapper()->unlock(invalidHandle, [&](const auto& tmpError, const auto&) {
EXPECT_EQ(Error::BAD_BUFFER, tmpError)
@@ -443,7 +427,7 @@
/**
* Test IMapper::isSupported with required format RGBA_8888
*/
-TEST_F(GraphicsMapperHidlTest, IsSupportedRGBA8888) {
+TEST_P(GraphicsMapperHidlTest, IsSupportedRGBA8888) {
const auto& info = mDummyDescriptorInfo;
bool supported = false;
@@ -454,7 +438,7 @@
/**
* Test IMapper::isSupported with required format YV12
*/
-TEST_F(GraphicsMapperHidlTest, IsSupportedYV12) {
+TEST_P(GraphicsMapperHidlTest, IsSupportedYV12) {
auto info = mDummyDescriptorInfo;
info.format = PixelFormat::YV12;
bool supported = false;
@@ -466,7 +450,7 @@
/**
* Test IMapper::isSupported with optional format Y16
*/
-TEST_F(GraphicsMapperHidlTest, IsSupportedY16) {
+TEST_P(GraphicsMapperHidlTest, IsSupportedY16) {
auto info = mDummyDescriptorInfo;
info.format = PixelFormat::Y16;
bool supported = false;
@@ -474,6 +458,14 @@
ASSERT_NO_FATAL_FAILURE(supported = mGralloc->isSupported(info));
}
+INSTANTIATE_TEST_CASE_P(
+ PerInstance, GraphicsMapperHidlTest,
+ testing::Combine(
+ testing::ValuesIn(
+ android::hardware::getAllHalInstanceNames(IAllocator::descriptor)),
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(IMapper::descriptor))),
+ android::hardware::PrintInstanceTupleNameToString<>);
+
} // namespace
} // namespace vts
} // namespace V3_0
@@ -481,13 +473,3 @@
} // namespace graphics
} // namespace hardware
} // namespace android
-
-int main(int argc, char** argv) {
- using android::hardware::graphics::mapper::V3_0::vts::GraphicsMapperHidlEnvironment;
- ::testing::AddGlobalTestEnvironment(GraphicsMapperHidlEnvironment::Instance());
- ::testing::InitGoogleTest(&argc, argv);
- GraphicsMapperHidlEnvironment::Instance()->init(&argc, argv);
- int status = RUN_ALL_TESTS();
- LOG(INFO) << "Test result = " << status;
- return status;
-}
diff --git a/graphics/mapper/4.0/IMapper.hal b/graphics/mapper/4.0/IMapper.hal
index 4560b06..03dfef1 100644
--- a/graphics/mapper/4.0/IMapper.hal
+++ b/graphics/mapper/4.0/IMapper.hal
@@ -56,6 +56,12 @@
* BufferUsage.
*/
bitfield<BufferUsage> usage;
+
+ /**
+ * The size in bytes of the reserved region associated with the buffer.
+ * See getReservedRegion for more information.
+ */
+ uint64_t reservedSize;
};
struct Rect {
@@ -71,9 +77,10 @@
*
* Since the buffer descriptor fully describes a buffer, any device
* dependent or device independent checks must be performed here whenever
- * possible. Specifically, when layered buffers are not supported, this
- * function must return `UNSUPPORTED` if `description.layers` is great than
- * 1.
+ * possible. When layered buffers are not supported, this function must
+ * return `UNSUPPORTED` if `description.layers` is great than 1. This
+ * function may return `UNSUPPORTED` if `description.reservedSize` is
+ * larger than a page.
*
* @param description Attributes of the descriptor.
* @return error Error status of the call, which may be
@@ -199,16 +206,20 @@
* outside of @p accessRegion is undefined, except that it must not cause
* process termination.
*
+ * This function can lock both single-planar and multi-planar formats. The caller
+ * should use get() to get information about the buffer they are locking.
+ * get() can be used to get information about the planes, offsets, stride,
+ * etc.
+ *
+ * This function must also work on buffers with
+ * `AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_*` if supported by the device, as well
+ * as with any other formats requested by multimedia codecs when they are
+ * configured with a flexible-YUV-compatible color format.
+ *
* On success, @p data must be filled with a pointer to the locked buffer
* memory. This address will represent the top-left corner of the entire
* buffer, even if @p accessRegion does not begin at the top-left corner.
*
- * On success, bytesPerPixel must contain the number of bytes per pixel in
- * the buffer. If the bytesPerPixel is unknown or variable, a value of -1
- * should be returned. bytesPerStride must contain the bytes per stride of
- * the buffer. If the bytesPerStride is unknown or variable, a value of -1
- * should be returned.
- *
* The locked buffer must adhere to the format requested at allocation time
* in the BufferDescriptorInfo.
*
@@ -231,55 +242,13 @@
* - `NO_RESOURCES` if the buffer cannot be locked at this time. Note
* that locking may succeed at a later time.
* @return data CPU-accessible pointer to the buffer data.
- * @return bytesPerPixel the number of bytes per pixel in the buffer
- * @return bytesPerStride the number of bytes per stride of the buffer
*/
lock(pointer buffer,
uint64_t cpuUsage,
Rect accessRegion,
handle acquireFence)
generates (Error error,
- pointer data,
- int32_t bytesPerPixel,
- int32_t bytesPerStride);
-
- /**
- * Locks a YCbCr buffer for the specified CPU usage.
- *
- * This is largely the same as lock(), except that instead of returning a
- * pointer directly to the buffer data, it returns a `YCbCrLayout` struct
- * describing how to access the data planes.
- *
- * This function must work on buffers with
- * `AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_*` if supported by the device, as well
- * as with any other formats requested by multimedia codecs when they are
- * configured with a flexible-YUV-compatible color format.
- *
- * @param buffer Buffer to lock.
- * @param cpuUsage CPU usage flags to request. See +ndk
- * libnativewindow#AHardwareBuffer_UsageFlags for possible values.
- * @param accessRegion Portion of the buffer that the client intends to
- * access.
- * @param acquireFence Handle containing a file descriptor referring to a
- * sync fence object, which will be signaled when it is safe for the
- * mapper to lock the buffer. @p acquireFence may be empty if it is
- * already safe to lock.
- * @return error Error status of the call, which may be
- * - `NONE` upon success.
- * - `BAD_BUFFER` if the buffer is invalid or is incompatible with this
- * function.
- * - `BAD_VALUE` if @p cpuUsage is 0, contains non-CPU usage flags, or
- * is incompatible with the buffer.
- * - `NO_RESOURCES` if the buffer cannot be locked at this time. Note
- * that locking may succeed at a later time.
- * @return layout Data layout of the locked buffer.
- */
- lockYCbCr(pointer buffer,
- uint64_t cpuUsage,
- Rect accessRegion,
- handle acquireFence)
- generates (Error error,
- YCbCrLayout layout);
+ pointer data);
/**
* Unlocks a buffer to indicate all CPU accesses to the buffer have
@@ -297,6 +266,50 @@
unlock(pointer buffer) generates (Error error, handle releaseFence);
/**
+ * Flushes the contents of a locked buffer.
+ *
+ * This function flushes the CPUs caches for the range of all the buffer's
+ * planes and metadata. This should behave similarly to unlock() except the
+ * buffer should remain mapped to the CPU.
+ *
+ * The client is still responsible for calling unlock() when it is done
+ * with all CPU accesses to the buffer.
+ *
+ * If non-CPU blocks are simultaneously writing the buffer, the locked
+ * copy should still be flushed but what happens is undefined except that
+ * it should not cause any crashes.
+ *
+ * @param buffer Buffer to flush.
+ * @return error Error status of the call, which may be
+ * - `NONE` upon success.
+ * - `BAD_BUFFER` if the buffer is invalid or not locked.
+ * @return releaseFence Handle containing a file descriptor referring to a
+ * sync fence object. The sync fence object will be signaled when the
+ * mapper has completed any pending work. @p releaseFence may be an
+ * empty fence.
+ */
+ flushLockedBuffer(pointer buffer) generates (Error error, handle releaseFence);
+
+ /**
+ * Rereads the contents of a locked buffer.
+ *
+ * This should fetch the most recent copy of the locked buffer.
+ *
+ * It may reread locked copies of the buffer in other processes.
+ *
+ * The client is still responsible for calling unlock() when it is done
+ * with all CPU accesses to the buffer.
+ *
+ * @param buffer Buffer to reread.
+ * @return error Error status of the call, which may be
+ * - `NONE` upon success.
+ * - `BAD_BUFFER` if the buffer is invalid or not locked.
+ * - `NO_RESOURCES` if the buffer cannot be reread at this time. Note
+ * that rereading may succeed at a later time.
+ */
+ rereadLockedBuffer(pointer buffer) generates(Error error);
+
+ /**
* Test whether the given BufferDescriptorInfo is allocatable.
*
* If this function returns true, it means that a buffer with the given
@@ -553,5 +566,80 @@
*/
listSupportedMetadataTypes()
generates (Error error, vec<MetadataTypeDescription> descriptions);
+
+ struct MetadataDump {
+ /**
+ * The type of metadata being dumped.
+ */
+ MetadataType metadataType;
+ /**
+ * The byte stream representation of the metadata. If the metadata is not
+ * gettable, the vector must be empty.
+ */
+ vec<uint8_t> metadata;
+ };
+
+ struct BufferDump {
+ /**
+ * A vector of all the metadata that is being dumped for a particular buffer.
+ */
+ vec<MetadataDump> metadataDump;
+ };
+
+ /**
+ * Dumps a buffer's metadata.
+ *
+ * @param buffer Buffer that is being dumped
+ * @return error Error status of the call, which may be
+ * - `NONE` upon success.
+ * - `BAD_BUFFER` if the raw handle is invalid.
+ * - `NO_RESOURCES` if the get cannot be fullfilled due to unavailability of
+ * resources.
+ * @return bufferDump Struct representing the metadata being dumped
+ */
+ dumpBuffer(pointer buffer)
+ generates (Error error, BufferDump bufferDump);
+
+ /**
+ * Dumps the metadata for all the buffers in the current process.
+ *
+ * @return error Error status of the call, which may be
+ * - `NONE` upon success.
+ * - `NO_RESOURCES` if the get cannot be fullfilled due to unavailability of
+ * resources.
+ * @return bufferDumps Vector of structs representing the buffers being dumped
+ */
+ dumpBuffers()
+ generates (Error error, vec<BufferDump> bufferDumps);
+
+ /**
+ * Returns the region of shared memory associated with the buffer that is
+ * reserved for client use.
+ *
+ * The shared memory may be allocated from any shared memory allocator.
+ * The shared memory must be CPU-accessible and virtually contiguous. The
+ * starting address must be word-aligned.
+ *
+ * This function may only be called after importBuffer() has been called by the
+ * client. The reserved region must remain accessible until freeBuffer() has
+ * been called. After freeBuffer() has been called, the client must not access
+ * the reserved region.
+ *
+ * This reserved memory may be used in future versions of Android to
+ * help clients implement backwards compatible features without requiring
+ * IAllocator/IMapper updates.
+ *
+ * @param buffer Imported buffer handle.
+ * @return error Error status of the call, which may be
+ * - `NONE` upon success.
+ * - `BAD_BUFFER` if the buffer is invalid.
+ * @return reservedRegion CPU-accessible pointer to the reserved region
+ * @return reservedSize the size of the reservedRegion that was requested
+ * in the BufferDescriptorInfo.
+ */
+ getReservedRegion(pointer buffer)
+ generates (Error error,
+ pointer reservedRegion,
+ uint64_t reservedSize);
};
diff --git a/graphics/mapper/4.0/types.hal b/graphics/mapper/4.0/types.hal
index 2fdfa65..00b6607 100644
--- a/graphics/mapper/4.0/types.hal
+++ b/graphics/mapper/4.0/types.hal
@@ -53,32 +53,3 @@
*/
typedef vec<uint8_t> BufferDescriptor;
-/**
- * Structure for describing YCbCr formats for consumption by applications.
- * This is used with PixelFormat::YCBCR_*_888.
- *
- * Buffer chroma subsampling is defined in the format.
- * e.g. PixelFormat::YCBCR_420_888 has subsampling 4:2:0.
- *
- * Buffers must have a 8 bit depth.
- *
- * y, cb, and cr point to the first byte of their respective planes.
- *
- * Stride describes the distance in bytes from the first value of one row of
- * the image to the first value of the next row. It includes the width of the
- * image plus padding.
- * yStride is the stride of the luma plane.
- * cStride is the stride of the chroma planes.
- *
- * chromaStep is the distance in bytes from one chroma pixel value to the
- * next. This is 2 bytes for semiplanar (because chroma values are interleaved
- * and each chroma value is one byte) and 1 for planar.
- */
-struct YCbCrLayout {
- pointer y;
- pointer cb;
- pointer cr;
- uint32_t yStride;
- uint32_t cStride;
- uint32_t chromaStep;
-};
diff --git a/graphics/mapper/4.0/utils/vts/MapperVts.cpp b/graphics/mapper/4.0/utils/vts/MapperVts.cpp
index 531f311..cb90fa0 100644
--- a/graphics/mapper/4.0/utils/vts/MapperVts.cpp
+++ b/graphics/mapper/4.0/utils/vts/MapperVts.cpp
@@ -17,8 +17,6 @@
#include <gralloctypes/Gralloc4.h>
#include <mapper-vts/4.0/MapperVts.h>
-#include <VtsHalHidlTargetTestBase.h>
-
namespace android {
namespace hardware {
namespace graphics {
@@ -36,19 +34,19 @@
}
void Gralloc::init(const std::string& allocatorServiceName, const std::string& mapperServiceName) {
- mAllocator = ::testing::VtsHalHidlTargetTestBase::getService<IAllocator>(allocatorServiceName);
+ mAllocator = IAllocator::getService(allocatorServiceName);
ASSERT_NE(nullptr, mAllocator.get()) << "failed to get allocator service";
- mMapper = ::testing::VtsHalHidlTargetTestBase::getService<IMapper>(mapperServiceName);
+ mMapper = IMapper::getService(mapperServiceName);
ASSERT_NE(nullptr, mMapper.get()) << "failed to get mapper service";
ASSERT_FALSE(mMapper->isRemote()) << "mapper is not in passthrough mode";
}
void Gralloc::initNoErr(const std::string& allocatorServiceName,
const std::string& mapperServiceName) {
- mAllocator = ::testing::VtsHalHidlTargetTestBase::getService<IAllocator>(allocatorServiceName);
+ mAllocator = IAllocator::getService(allocatorServiceName);
- mMapper = ::testing::VtsHalHidlTargetTestBase::getService<IMapper>(mapperServiceName);
+ mMapper = IMapper::getService(mapperServiceName);
if (mMapper.get()) {
ASSERT_FALSE(mMapper->isRemote()) << "mapper is not in passthrough mode";
}
@@ -73,13 +71,6 @@
return mAllocator;
}
-std::string Gralloc::dumpDebugInfo() {
- std::string debugInfo;
- mAllocator->dumpDebugInfo([&](const auto& tmpDebugInfo) { debugInfo = tmpDebugInfo.c_str(); });
-
- return debugInfo;
-}
-
const native_handle_t* Gralloc::cloneBuffer(const hidl_handle& rawHandle) {
const native_handle_t* bufferHandle = native_handle_clone(rawHandle.getNativeHandle());
EXPECT_NE(nullptr, bufferHandle);
@@ -199,8 +190,7 @@
}
void* Gralloc::lock(const native_handle_t* bufferHandle, uint64_t cpuUsage,
- const IMapper::Rect& accessRegion, int acquireFence, int32_t* outBytesPerPixel,
- int32_t* outBytesPerStride) {
+ const IMapper::Rect& accessRegion, int acquireFence) {
auto buffer = const_cast<native_handle_t*>(bufferHandle);
NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
@@ -211,17 +201,11 @@
acquireFenceHandle = h;
}
- *outBytesPerPixel = -1;
- *outBytesPerStride = -1;
-
void* data = nullptr;
mMapper->lock(buffer, cpuUsage, accessRegion, acquireFenceHandle,
- [&](const auto& tmpError, const auto& tmpData, int32_t tmpBytesPerPixel,
- int32_t tmpBytesPerStride) {
+ [&](const auto& tmpError, const auto& tmpData) {
ASSERT_EQ(Error::NONE, tmpError) << "failed to lock buffer " << buffer;
data = tmpData;
- *outBytesPerPixel = tmpBytesPerPixel;
- *outBytesPerStride = tmpBytesPerStride;
});
if (acquireFence >= 0) {
@@ -231,33 +215,6 @@
return data;
}
-YCbCrLayout Gralloc::lockYCbCr(const native_handle_t* bufferHandle, uint64_t cpuUsage,
- const IMapper::Rect& accessRegion, int acquireFence) {
- auto buffer = const_cast<native_handle_t*>(bufferHandle);
-
- NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
- hidl_handle acquireFenceHandle;
- if (acquireFence >= 0) {
- auto h = native_handle_init(acquireFenceStorage, 1, 0);
- h->data[0] = acquireFence;
- acquireFenceHandle = h;
- }
-
- YCbCrLayout layout = {};
- mMapper->lockYCbCr(buffer, cpuUsage, accessRegion, acquireFenceHandle,
- [&](const auto& tmpError, const auto& tmpLayout) {
- ASSERT_EQ(Error::NONE, tmpError)
- << "failed to lockYCbCr buffer " << buffer;
- layout = tmpLayout;
- });
-
- if (acquireFence >= 0) {
- close(acquireFence);
- }
-
- return layout;
-}
-
int Gralloc::unlock(const native_handle_t* bufferHandle) {
auto buffer = const_cast<native_handle_t*>(bufferHandle);
@@ -280,6 +237,34 @@
return releaseFence;
}
+int Gralloc::flushLockedBuffer(const native_handle_t* bufferHandle) {
+ auto buffer = const_cast<native_handle_t*>(bufferHandle);
+
+ int releaseFence = -1;
+ mMapper->flushLockedBuffer(buffer, [&](const auto& tmpError, const auto& tmpReleaseFence) {
+ ASSERT_EQ(Error::NONE, tmpError) << "failed to flush locked buffer " << buffer;
+
+ auto fenceHandle = tmpReleaseFence.getNativeHandle();
+ if (fenceHandle) {
+ ASSERT_EQ(0, fenceHandle->numInts) << "invalid fence handle " << fenceHandle;
+ if (fenceHandle->numFds == 1) {
+ releaseFence = dup(fenceHandle->data[0]);
+ ASSERT_LT(0, releaseFence) << "failed to dup fence fd";
+ } else {
+ ASSERT_EQ(0, fenceHandle->numFds) << " invalid fence handle " << fenceHandle;
+ }
+ }
+ });
+
+ return releaseFence;
+}
+
+void Gralloc::rereadLockedBuffer(const native_handle_t* bufferHandle) {
+ auto buffer = const_cast<native_handle_t*>(bufferHandle);
+
+ ASSERT_EQ(Error::NONE, mMapper->rereadLockedBuffer(buffer));
+}
+
bool Gralloc::validateBufferSize(const native_handle_t* bufferHandle,
const IMapper::BufferDescriptorInfo& descriptorInfo,
uint32_t stride) {
@@ -344,6 +329,19 @@
return err;
}
+Error Gralloc::getReservedRegion(const native_handle_t* bufferHandle, void** outReservedRegion,
+ uint64_t* outReservedSize) {
+ Error err;
+ mMapper->getReservedRegion(
+ const_cast<native_handle_t*>(bufferHandle),
+ [&](const auto& tmpError, const auto& tmpReservedRegion, const auto& tmpReservedSize) {
+ err = tmpError;
+ *outReservedRegion = tmpReservedRegion;
+ *outReservedSize = tmpReservedSize;
+ });
+ return err;
+}
+
} // namespace vts
} // namespace V4_0
} // namespace mapper
diff --git a/graphics/mapper/4.0/utils/vts/include/mapper-vts/4.0/MapperVts.h b/graphics/mapper/4.0/utils/vts/include/mapper-vts/4.0/MapperVts.h
index 28555fa..cd40aa4 100644
--- a/graphics/mapper/4.0/utils/vts/include/mapper-vts/4.0/MapperVts.h
+++ b/graphics/mapper/4.0/utils/vts/include/mapper-vts/4.0/MapperVts.h
@@ -22,6 +22,7 @@
#include <android/hardware/graphics/allocator/4.0/IAllocator.h>
#include <android/hardware/graphics/mapper/4.0/IMapper.h>
+#include <gtest/gtest.h>
#include <utils/StrongPointer.h>
namespace android {
@@ -44,8 +45,6 @@
sp<IAllocator> getAllocator() const;
- std::string dumpDebugInfo();
-
// When import is false, this simply calls IAllocator::allocate. When import
// is true, the returned buffers are also imported into the mapper.
//
@@ -70,12 +69,12 @@
// in and out of the mapper. The ownership of the fd is always transferred
// with each of these functions.
void* lock(const native_handle_t* bufferHandle, uint64_t cpuUsage,
- const IMapper::Rect& accessRegion, int acquireFence, int32_t* outBytesPerPixel,
- int32_t* outBytesPerStride);
- YCbCrLayout lockYCbCr(const native_handle_t* bufferHandle, uint64_t cpuUsage,
- const IMapper::Rect& accessRegion, int acquireFence);
+ const IMapper::Rect& accessRegion, int acquireFence);
int unlock(const native_handle_t* bufferHandle);
+ int flushLockedBuffer(const native_handle_t* bufferHandle);
+ void rereadLockedBuffer(const native_handle_t* bufferHandle);
+
bool validateBufferSize(const native_handle_t* bufferHandle,
const IMapper::BufferDescriptorInfo& descriptorInfo, uint32_t stride);
void getTransportSize(const native_handle_t* bufferHandle, uint32_t* outNumFds,
@@ -93,6 +92,9 @@
const IMapper::MetadataType& metadataType,
hidl_vec<uint8_t>* outVec);
+ Error getReservedRegion(const native_handle_t* bufferHandle, void** outReservedRegion,
+ uint64_t* outReservedSize);
+
private:
void init(const std::string& allocatorServiceName, const std::string& mapperServiceName);
diff --git a/graphics/mapper/4.0/vts/functional/Android.bp b/graphics/mapper/4.0/vts/functional/Android.bp
index 5a7548a..926cf31 100644
--- a/graphics/mapper/4.0/vts/functional/Android.bp
+++ b/graphics/mapper/4.0/vts/functional/Android.bp
@@ -20,6 +20,9 @@
srcs: ["VtsHalGraphicsMapperV4_0TargetTest.cpp"],
static_libs: [
"android.hardware.graphics.mapper@4.0-vts",
+ "libgralloctypes",
+ "libsync",
+ "vintf-graphics-common-ndk_platform",
],
shared_libs: [
"android.hardware.graphics.allocator@4.0",
@@ -27,8 +30,9 @@
"android.hardware.graphics.common@1.1",
"android.hardware.graphics.common@1.2",
"android.hardware.graphics.mapper@4.0",
- "libgralloctypes",
- "vintf-graphics-common-ndk_platform",
],
- test_suites: ["general-tests"],
+ header_libs: [
+ "libsystem_headers",
+ ],
+ test_suites: ["general-tests", "vts-core"],
}
diff --git a/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp b/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp
index 2a66cbf..c4b1c53 100644
--- a/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp
+++ b/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp
@@ -16,14 +16,21 @@
#define LOG_TAG "VtsHalGraphicsMapperV4_0TargetTest"
+#include <unistd.h>
#include <chrono>
#include <thread>
#include <vector>
-#include <VtsHalHidlTargetTestBase.h>
+#include <aidl/android/hardware/graphics/common/PlaneLayoutComponentType.h>
+
#include <android-base/logging.h>
+#include <android/sync.h>
#include <gralloctypes/Gralloc4.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include <mapper-vts/4.0/MapperVts.h>
+#include <system/graphics.h>
namespace android {
namespace hardware {
@@ -41,33 +48,18 @@
using aidl::android::hardware::graphics::common::ExtendableType;
using aidl::android::hardware::graphics::common::PlaneLayout;
using aidl::android::hardware::graphics::common::PlaneLayoutComponent;
+using aidl::android::hardware::graphics::common::PlaneLayoutComponentType;
using aidl::android::hardware::graphics::common::StandardMetadataType;
using DecodeFunction = std::function<void(const IMapper::BufferDescriptorInfo& descriptorInfo,
const hidl_vec<uint8_t>& vec)>;
-// Test environment for graphics.mapper.
-class GraphicsMapperHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static GraphicsMapperHidlEnvironment* Instance() {
- static GraphicsMapperHidlEnvironment* instance = new GraphicsMapperHidlEnvironment;
- return instance;
- }
-
- virtual void registerTestServices() override {
- registerTestService<IAllocator>();
- registerTestService<IMapper>();
- }
-};
-
-class GraphicsMapperHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+class GraphicsMapperHidlTest
+ : public ::testing::TestWithParam<std::tuple<std::string, std::string>> {
protected:
void SetUp() override {
- ASSERT_NO_FATAL_FAILURE(
- mGralloc = std::make_unique<Gralloc>(
- GraphicsMapperHidlEnvironment::Instance()->getServiceName<IAllocator>(),
- GraphicsMapperHidlEnvironment::Instance()->getServiceName<IMapper>()));
+ ASSERT_NO_FATAL_FAILURE(mGralloc = std::make_unique<Gralloc>(std::get<0>(GetParam()),
+ std::get<1>(GetParam())));
ASSERT_NE(nullptr, mGralloc->getAllocator().get());
ASSERT_NE(nullptr, mGralloc->getMapper().get());
@@ -78,6 +70,7 @@
mDummyDescriptorInfo.format = PixelFormat::RGBA_8888;
mDummyDescriptorInfo.usage =
static_cast<uint64_t>(BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN);
+ mDummyDescriptorInfo.reservedSize = 0;
}
void TearDown() override {}
@@ -124,7 +117,9 @@
int64_t offsetInBitsA = -1;
for (const auto& component : planeLayout.components) {
- EXPECT_EQ(GRALLOC4_PLANE_LAYOUT_COMPONENT_TYPE, component.type.name);
+ if (!gralloc4::isStandardPlaneLayoutComponentType(component.type)) {
+ continue;
+ }
EXPECT_EQ(8, component.sizeInBits);
if (component.type.value == gralloc4::PlaneLayoutComponentType_R.value) {
offsetInBitsR = component.offsetInBits;
@@ -161,6 +156,130 @@
EXPECT_EQ(planeLayout.heightInSamples, planeLayout.crop.bottom);
}
+ void verifyBufferDump(const IMapper::BufferDump& bufferDump,
+ const native_handle_t* bufferHandle = nullptr) {
+ std::set<StandardMetadataType> foundMetadataTypes;
+
+ const std::vector<IMapper::MetadataDump> metadataDump = bufferDump.metadataDump;
+
+ for (const auto& dump : metadataDump) {
+ const auto& metadataType = dump.metadataType;
+ const auto& metadata = dump.metadata;
+
+ if (!gralloc4::isStandardMetadataType(metadataType)) {
+ continue;
+ }
+
+ StandardMetadataType type = gralloc4::getStandardMetadataTypeValue(metadataType);
+
+ if (sRequiredMetadataTypes.find(type) == sRequiredMetadataTypes.end()) {
+ continue;
+ }
+
+ ASSERT_EQ(foundMetadataTypes.find(type), foundMetadataTypes.end());
+ foundMetadataTypes.insert(type);
+
+ if (!bufferHandle) {
+ continue;
+ }
+
+ hidl_vec<uint8_t> metadataFromGet;
+ ASSERT_EQ(Error::NONE, mGralloc->get(bufferHandle, metadataType, &metadataFromGet));
+
+ ASSERT_EQ(metadataFromGet, metadata);
+ }
+
+ EXPECT_EQ(sRequiredMetadataTypes, foundMetadataTypes);
+ }
+
+ void getAndroidYCbCr(const native_handle_t* bufferHandle, uint8_t* data,
+ android_ycbcr* outYCbCr) {
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(Error::NONE,
+ mGralloc->get(bufferHandle, gralloc4::MetadataType_PlaneLayouts, &vec));
+ std::vector<PlaneLayout> planeLayouts;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodePlaneLayouts(vec, &planeLayouts));
+
+ outYCbCr->y = nullptr;
+ outYCbCr->cb = nullptr;
+ outYCbCr->cr = nullptr;
+ outYCbCr->ystride = 0;
+ outYCbCr->cstride = 0;
+ outYCbCr->chroma_step = 0;
+
+ for (const auto& planeLayout : planeLayouts) {
+ for (const auto& planeLayoutComponent : planeLayout.components) {
+ if (!gralloc4::isStandardPlaneLayoutComponentType(planeLayoutComponent.type)) {
+ continue;
+ }
+ ASSERT_EQ(0, planeLayoutComponent.offsetInBits % 8);
+
+ uint8_t* tmpData =
+ data + planeLayout.offsetInBytes + (planeLayoutComponent.offsetInBits / 8);
+ uint64_t sampleIncrementInBytes;
+
+ auto type = static_cast<PlaneLayoutComponentType>(planeLayoutComponent.type.value);
+ switch (type) {
+ case PlaneLayoutComponentType::Y:
+ ASSERT_EQ(nullptr, outYCbCr->y);
+ ASSERT_EQ(8, planeLayoutComponent.sizeInBits);
+ ASSERT_EQ(8, planeLayout.sampleIncrementInBits);
+ outYCbCr->y = tmpData;
+ outYCbCr->ystride = planeLayout.strideInBytes;
+ break;
+
+ case PlaneLayoutComponentType::CB:
+ case PlaneLayoutComponentType::CR:
+ ASSERT_EQ(0, planeLayout.sampleIncrementInBits % 8);
+
+ sampleIncrementInBytes = planeLayout.sampleIncrementInBits / 8;
+ ASSERT_TRUE(sampleIncrementInBytes == 1 || sampleIncrementInBytes == 2);
+
+ if (outYCbCr->cstride == 0 && outYCbCr->chroma_step == 0) {
+ outYCbCr->cstride = planeLayout.strideInBytes;
+ outYCbCr->chroma_step = sampleIncrementInBytes;
+ } else {
+ ASSERT_EQ(outYCbCr->cstride, planeLayout.strideInBytes);
+ ASSERT_EQ(outYCbCr->chroma_step, sampleIncrementInBytes);
+ }
+
+ if (type == PlaneLayoutComponentType::CB) {
+ ASSERT_EQ(nullptr, outYCbCr->cb);
+ outYCbCr->cb = tmpData;
+ } else {
+ ASSERT_EQ(nullptr, outYCbCr->cr);
+ outYCbCr->cr = tmpData;
+ }
+ break;
+ default:
+ break;
+ };
+ }
+ }
+
+ ASSERT_NE(nullptr, outYCbCr->y);
+ ASSERT_NE(nullptr, outYCbCr->cb);
+ ASSERT_NE(nullptr, outYCbCr->cr);
+ }
+
+ void fillRGBA8888(uint8_t* data, uint32_t height, size_t strideInBytes, size_t widthInBytes,
+ uint32_t seed = 0) {
+ for (uint32_t y = 0; y < height; y++) {
+ memset(data, y + seed, widthInBytes);
+ data += strideInBytes;
+ }
+ }
+
+ void verifyRGBA8888(uint8_t* data, uint32_t height, size_t strideInBytes, size_t widthInBytes,
+ uint32_t seed = 0) {
+ for (uint32_t y = 0; y < height; y++) {
+ for (size_t i = 0; i < widthInBytes; i++) {
+ EXPECT_EQ(static_cast<uint8_t>(y + seed), data[i]);
+ }
+ data += strideInBytes;
+ }
+ }
+
std::unique_ptr<Gralloc> mGralloc;
IMapper::BufferDescriptorInfo mDummyDescriptorInfo{};
static const std::set<StandardMetadataType> sRequiredMetadataTypes;
@@ -187,16 +306,9 @@
};
/**
- * Test IAllocator::dumpDebugInfo by calling it.
- */
-TEST_F(GraphicsMapperHidlTest, AllocatorDumpDebugInfo) {
- mGralloc->dumpDebugInfo();
-}
-
-/**
* Test IAllocator::allocate with valid buffer descriptors.
*/
-TEST_F(GraphicsMapperHidlTest, AllocatorAllocate) {
+TEST_P(GraphicsMapperHidlTest, AllocatorAllocate) {
BufferDescriptor descriptor;
ASSERT_NO_FATAL_FAILURE(descriptor = mGralloc->createDescriptor(mDummyDescriptorInfo));
@@ -219,7 +331,7 @@
/**
* Test IAllocator::allocate with invalid buffer descriptors.
*/
-TEST_F(GraphicsMapperHidlTest, AllocatorAllocateNegative) {
+TEST_P(GraphicsMapperHidlTest, AllocatorAllocateNegative) {
// this assumes any valid descriptor is non-empty
BufferDescriptor descriptor;
mGralloc->getAllocator()->allocate(descriptor, 1,
@@ -231,7 +343,7 @@
/**
* Test IAllocator::allocate does not leak.
*/
-TEST_F(GraphicsMapperHidlTest, AllocatorAllocateNoLeak) {
+TEST_P(GraphicsMapperHidlTest, AllocatorAllocateNoLeak) {
auto info = mDummyDescriptorInfo;
info.width = 1024;
info.height = 1024;
@@ -245,7 +357,7 @@
/**
* Test that IAllocator::allocate is thread-safe.
*/
-TEST_F(GraphicsMapperHidlTest, AllocatorAllocateThreaded) {
+TEST_P(GraphicsMapperHidlTest, AllocatorAllocateThreaded) {
BufferDescriptor descriptor;
ASSERT_NO_FATAL_FAILURE(descriptor = mGralloc->createDescriptor(mDummyDescriptorInfo));
@@ -276,14 +388,14 @@
/**
* Test IMapper::createDescriptor with valid descriptor info.
*/
-TEST_F(GraphicsMapperHidlTest, CreateDescriptorBasic) {
+TEST_P(GraphicsMapperHidlTest, CreateDescriptorBasic) {
ASSERT_NO_FATAL_FAILURE(mGralloc->createDescriptor(mDummyDescriptorInfo));
}
/**
* Test IMapper::createDescriptor with invalid descriptor info.
*/
-TEST_F(GraphicsMapperHidlTest, CreateDescriptorNegative) {
+TEST_P(GraphicsMapperHidlTest, CreateDescriptorNegative) {
auto info = mDummyDescriptorInfo;
info.width = 0;
mGralloc->getMapper()->createDescriptor(info, [&](const auto& tmpError, const auto&) {
@@ -294,7 +406,7 @@
/**
* Test IMapper::importBuffer and IMapper::freeBuffer with allocated buffers.
*/
-TEST_F(GraphicsMapperHidlTest, ImportFreeBufferBasic) {
+TEST_P(GraphicsMapperHidlTest, ImportFreeBufferBasic) {
const native_handle_t* bufferHandle;
ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(mDummyDescriptorInfo, true));
ASSERT_NO_FATAL_FAILURE(mGralloc->freeBuffer(bufferHandle));
@@ -303,7 +415,7 @@
/**
* Test IMapper::importBuffer and IMapper::freeBuffer with cloned buffers.
*/
-TEST_F(GraphicsMapperHidlTest, ImportFreeBufferClone) {
+TEST_P(GraphicsMapperHidlTest, ImportFreeBufferClone) {
const native_handle_t* clonedBufferHandle;
ASSERT_NO_FATAL_FAILURE(clonedBufferHandle = mGralloc->allocate(mDummyDescriptorInfo, false));
@@ -321,7 +433,7 @@
/**
* Test IMapper::importBuffer and IMapper::freeBuffer cross mapper instances.
*/
-TEST_F(GraphicsMapperHidlTest, ImportFreeBufferSingleton) {
+TEST_P(GraphicsMapperHidlTest, ImportFreeBufferSingleton) {
const native_handle_t* rawHandle;
ASSERT_NO_FATAL_FAILURE(rawHandle = mGralloc->allocate(mDummyDescriptorInfo, false));
@@ -333,10 +445,8 @@
// free the imported handle with another mapper
std::unique_ptr<Gralloc> anotherGralloc;
- ASSERT_NO_FATAL_FAILURE(
- anotherGralloc = std::make_unique<Gralloc>(
- GraphicsMapperHidlEnvironment::Instance()->getServiceName<IAllocator>(),
- GraphicsMapperHidlEnvironment::Instance()->getServiceName<IMapper>()));
+ ASSERT_NO_FATAL_FAILURE(anotherGralloc = std::make_unique<Gralloc>(std::get<0>(GetParam()),
+ std::get<1>(GetParam())));
Error error = mGralloc->getMapper()->freeBuffer(importedHandle);
ASSERT_EQ(Error::NONE, error);
@@ -346,7 +456,7 @@
/**
* Test IMapper::importBuffer and IMapper::freeBuffer do not leak.
*/
-TEST_F(GraphicsMapperHidlTest, ImportFreeBufferNoLeak) {
+TEST_P(GraphicsMapperHidlTest, ImportFreeBufferNoLeak) {
auto info = mDummyDescriptorInfo;
info.width = 1024;
info.height = 1024;
@@ -360,7 +470,7 @@
/**
* Test IMapper::importBuffer with invalid buffers.
*/
-TEST_F(GraphicsMapperHidlTest, ImportBufferNegative) {
+TEST_P(GraphicsMapperHidlTest, ImportBufferNegative) {
native_handle_t* invalidHandle = nullptr;
mGralloc->getMapper()->importBuffer(invalidHandle, [&](const auto& tmpError, const auto&) {
EXPECT_EQ(Error::BAD_BUFFER, tmpError)
@@ -378,7 +488,7 @@
/**
* Test IMapper::freeBuffer with invalid buffers.
*/
-TEST_F(GraphicsMapperHidlTest, FreeBufferNegative) {
+TEST_P(GraphicsMapperHidlTest, FreeBufferNegative) {
native_handle_t* invalidHandle = nullptr;
Error error = mGralloc->getMapper()->freeBuffer(invalidHandle);
EXPECT_EQ(Error::BAD_BUFFER, error) << "freeBuffer with nullptr did not fail with BAD_BUFFER";
@@ -401,7 +511,7 @@
/**
* Test IMapper::lock and IMapper::unlock.
*/
-TEST_F(GraphicsMapperHidlTest, LockUnlockBasic) {
+TEST_P(GraphicsMapperHidlTest, LockUnlockBasic) {
const auto& info = mDummyDescriptorInfo;
const native_handle_t* bufferHandle;
@@ -413,43 +523,18 @@
static_cast<int32_t>(info.height)};
int fence = -1;
uint8_t* data;
- int32_t bytesPerPixel = -1;
- int32_t bytesPerStride = -1;
ASSERT_NO_FATAL_FAILURE(
- data = static_cast<uint8_t*>(mGralloc->lock(bufferHandle, info.usage, region, fence,
- &bytesPerPixel, &bytesPerStride)));
-
- // Valid return values are -1 for unsupported or the number bytes for supported which is >=0
- EXPECT_GT(bytesPerPixel, -1);
- EXPECT_GT(bytesPerStride, -1);
+ data = static_cast<uint8_t*>(mGralloc->lock(bufferHandle, info.usage, region, fence)));
// RGBA_8888
- size_t strideInBytes = stride * 4;
- size_t writeInBytes = info.width * 4;
-
- for (uint32_t y = 0; y < info.height; y++) {
- memset(data, y, writeInBytes);
- data += strideInBytes;
- }
+ fillRGBA8888(data, info.height, stride * 4, info.width * 4);
ASSERT_NO_FATAL_FAILURE(fence = mGralloc->unlock(bufferHandle));
- bytesPerPixel = -1;
- bytesPerStride = -1;
-
// lock again for reading
ASSERT_NO_FATAL_FAILURE(
- data = static_cast<uint8_t*>(mGralloc->lock(bufferHandle, info.usage, region, fence,
- &bytesPerPixel, &bytesPerStride)));
- for (uint32_t y = 0; y < info.height; y++) {
- for (size_t i = 0; i < writeInBytes; i++) {
- EXPECT_EQ(static_cast<uint8_t>(y), data[i]);
- }
- data += strideInBytes;
- }
-
- EXPECT_GT(bytesPerPixel, -1);
- EXPECT_GT(bytesPerStride, -1);
+ data = static_cast<uint8_t*>(mGralloc->lock(bufferHandle, info.usage, region, fence)));
+ ASSERT_NO_FATAL_FAILURE(verifyRGBA8888(data, info.height, stride * 4, info.width * 4));
ASSERT_NO_FATAL_FAILURE(fence = mGralloc->unlock(bufferHandle));
if (fence >= 0) {
@@ -457,13 +542,9 @@
}
}
-/**
- * Test IMapper::lockYCbCr. This locks a YV12 buffer, and makes sure we can
- * write to and read from it.
- */
-TEST_F(GraphicsMapperHidlTest, LockYCbCrBasic) {
+TEST_P(GraphicsMapperHidlTest, Lock_YCBCR_420_888) {
auto info = mDummyDescriptorInfo;
- info.format = PixelFormat::YV12;
+ info.format = PixelFormat::YCBCR_420_888;
const native_handle_t* bufferHandle;
uint32_t stride;
@@ -473,20 +554,30 @@
const IMapper::Rect region{0, 0, static_cast<int32_t>(info.width),
static_cast<int32_t>(info.height)};
int fence = -1;
- YCbCrLayout layout;
- ASSERT_NO_FATAL_FAILURE(layout = mGralloc->lockYCbCr(bufferHandle, info.usage, region, fence));
+ uint8_t* data;
- auto yData = static_cast<uint8_t*>(layout.y);
- auto cbData = static_cast<uint8_t*>(layout.cb);
- auto crData = static_cast<uint8_t*>(layout.cr);
+ ASSERT_NO_FATAL_FAILURE(
+ data = static_cast<uint8_t*>(mGralloc->lock(bufferHandle, info.usage, region, fence)));
+
+ android_ycbcr yCbCr;
+ ASSERT_NO_FATAL_FAILURE(getAndroidYCbCr(bufferHandle, data, &yCbCr));
+
+ auto yData = static_cast<uint8_t*>(yCbCr.y);
+ auto cbData = static_cast<uint8_t*>(yCbCr.cb);
+ auto crData = static_cast<uint8_t*>(yCbCr.cr);
+ auto yStride = yCbCr.ystride;
+ auto cStride = yCbCr.cstride;
+ auto chromaStep = yCbCr.chroma_step;
+
for (uint32_t y = 0; y < info.height; y++) {
for (uint32_t x = 0; x < info.width; x++) {
auto val = static_cast<uint8_t>(info.height * y + x);
- yData[layout.yStride * y + x] = val;
- if (y % 2 == 0 && x % 2 == 0) {
- cbData[layout.cStride * y / 2 + x / 2] = val;
- crData[layout.cStride * y / 2 + x / 2] = val;
+ yData[yStride * y + x] = val;
+
+ if (y % chromaStep && x % chromaStep == 0) {
+ cbData[cStride * y / chromaStep + x / chromaStep] = val;
+ crData[cStride * y / chromaStep + x / chromaStep] = val;
}
}
}
@@ -494,19 +585,23 @@
ASSERT_NO_FATAL_FAILURE(fence = mGralloc->unlock(bufferHandle));
// lock again for reading
- ASSERT_NO_FATAL_FAILURE(layout = mGralloc->lockYCbCr(bufferHandle, info.usage, region, fence));
+ ASSERT_NO_FATAL_FAILURE(
+ data = static_cast<uint8_t*>(mGralloc->lock(bufferHandle, info.usage, region, fence)));
- yData = static_cast<uint8_t*>(layout.y);
- cbData = static_cast<uint8_t*>(layout.cb);
- crData = static_cast<uint8_t*>(layout.cr);
+ ASSERT_NO_FATAL_FAILURE(getAndroidYCbCr(bufferHandle, data, &yCbCr));
+
+ yData = static_cast<uint8_t*>(yCbCr.y);
+ cbData = static_cast<uint8_t*>(yCbCr.cb);
+ crData = static_cast<uint8_t*>(yCbCr.cr);
for (uint32_t y = 0; y < info.height; y++) {
for (uint32_t x = 0; x < info.width; x++) {
auto val = static_cast<uint8_t>(info.height * y + x);
- EXPECT_EQ(val, yData[layout.yStride * y + x]);
- if (y % 2 == 0 && x % 2 == 0) {
- EXPECT_EQ(val, cbData[layout.cStride * y / 2 + x / 2]);
- EXPECT_EQ(val, crData[layout.cStride * y / 2 + x / 2]);
+ EXPECT_EQ(val, yData[yStride * y + x]);
+
+ if (y % chromaStep == 0 && x % chromaStep == 0) {
+ EXPECT_EQ(val, cbData[cStride * y / chromaStep + x / chromaStep]);
+ EXPECT_EQ(val, crData[cStride * y / chromaStep + x / chromaStep]);
}
}
}
@@ -520,7 +615,7 @@
/**
* Test IMapper::unlock with bad access region
*/
-TEST_F(GraphicsMapperHidlTest, LockBadAccessRegion) {
+TEST_P(GraphicsMapperHidlTest, LockBadAccessRegion) {
const auto& info = mDummyDescriptorInfo;
const native_handle_t* bufferHandle;
@@ -540,8 +635,7 @@
auto buffer = const_cast<native_handle_t*>(bufferHandle);
mGralloc->getMapper()->lock(buffer, info.usage, accessRegion, acquireFenceHandle,
- [&](const auto& tmpError, const auto& /*tmpData*/,
- int32_t /*tmpBytesPerPixel*/, int32_t /*tmpBytesPerStride*/) {
+ [&](const auto& tmpError, const auto& /*tmpData*/) {
EXPECT_EQ(Error::BAD_VALUE, tmpError)
<< "locking with a bad access region should fail";
});
@@ -563,7 +657,7 @@
/**
* Test IMapper::unlock with invalid buffers.
*/
-TEST_F(GraphicsMapperHidlTest, UnlockNegative) {
+TEST_P(GraphicsMapperHidlTest, UnlockNegative) {
native_handle_t* invalidHandle = nullptr;
mGralloc->getMapper()->unlock(invalidHandle, [&](const auto& tmpError, const auto&) {
EXPECT_EQ(Error::BAD_BUFFER, tmpError)
@@ -599,9 +693,78 @@
}
/**
+ * Test IMapper::flush and IMapper::reread.
+ */
+TEST_P(GraphicsMapperHidlTest, FlushRereadBasic) {
+ const auto& info = mDummyDescriptorInfo;
+
+ const native_handle_t* rawHandle;
+ uint32_t stride;
+ ASSERT_NO_FATAL_FAILURE(
+ rawHandle = mGralloc->allocate(mDummyDescriptorInfo, false, false, &stride));
+
+ const native_handle_t* writeBufferHandle;
+ const native_handle_t* readBufferHandle;
+ ASSERT_NO_FATAL_FAILURE(writeBufferHandle = mGralloc->importBuffer(rawHandle));
+ ASSERT_NO_FATAL_FAILURE(readBufferHandle = mGralloc->importBuffer(rawHandle));
+
+ // lock buffer for writing
+ const IMapper::Rect region{0, 0, static_cast<int32_t>(info.width),
+ static_cast<int32_t>(info.height)};
+ uint8_t* writeData;
+ ASSERT_NO_FATAL_FAILURE(
+ writeData = static_cast<uint8_t*>(mGralloc->lock(
+ writeBufferHandle, static_cast<uint64_t>(BufferUsage::CPU_WRITE_OFTEN), region,
+ -1)));
+
+ uint8_t* readData;
+ ASSERT_NO_FATAL_FAILURE(
+ readData = static_cast<uint8_t*>(mGralloc->lock(
+ readBufferHandle, static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN), region,
+ -1)));
+
+ fillRGBA8888(writeData, info.height, stride * 4, info.width * 4);
+
+ int fence;
+ ASSERT_NO_FATAL_FAILURE(fence = mGralloc->flushLockedBuffer(writeBufferHandle));
+ ASSERT_EQ(0, sync_wait(fence, 3500));
+ close(fence);
+
+ ASSERT_NO_FATAL_FAILURE(mGralloc->rereadLockedBuffer(readBufferHandle));
+
+ ASSERT_NO_FATAL_FAILURE(verifyRGBA8888(readData, info.height, stride * 4, info.width * 4));
+
+ ASSERT_NO_FATAL_FAILURE(fence = mGralloc->unlock(readBufferHandle));
+ if (fence >= 0) {
+ close(fence);
+ }
+ ASSERT_NO_FATAL_FAILURE(fence = mGralloc->unlock(writeBufferHandle));
+ if (fence >= 0) {
+ close(fence);
+ }
+}
+
+/**
+ * Test IMapper::flushLockedBuffer with bad buffer
+ */
+TEST_P(GraphicsMapperHidlTest, FlushLockedBufferBadBuffer) {
+ ASSERT_NO_FATAL_FAILURE(mGralloc->getMapper()->flushLockedBuffer(
+ nullptr, [&](const auto& tmpError, const auto& /*tmpReleaseFence*/) {
+ ASSERT_EQ(Error::BAD_BUFFER, tmpError);
+ }));
+}
+
+/**
+ * Test IMapper::rereadLockedBuffer with bad buffer
+ */
+TEST_P(GraphicsMapperHidlTest, RereadLockedBufferBadBuffer) {
+ ASSERT_EQ(Error::BAD_BUFFER, mGralloc->getMapper()->rereadLockedBuffer(nullptr));
+}
+
+/**
* Test IMapper::isSupported with required format RGBA_8888
*/
-TEST_F(GraphicsMapperHidlTest, IsSupportedRGBA8888) {
+TEST_P(GraphicsMapperHidlTest, IsSupportedRGBA8888) {
const auto& info = mDummyDescriptorInfo;
bool supported = false;
@@ -612,7 +775,7 @@
/**
* Test IMapper::isSupported with required format YV12
*/
-TEST_F(GraphicsMapperHidlTest, IsSupportedYV12) {
+TEST_P(GraphicsMapperHidlTest, IsSupportedYV12) {
auto info = mDummyDescriptorInfo;
info.format = PixelFormat::YV12;
bool supported = false;
@@ -624,7 +787,7 @@
/**
* Test IMapper::isSupported with optional format Y16
*/
-TEST_F(GraphicsMapperHidlTest, IsSupportedY16) {
+TEST_P(GraphicsMapperHidlTest, IsSupportedY16) {
auto info = mDummyDescriptorInfo;
info.format = PixelFormat::Y16;
bool supported = false;
@@ -635,7 +798,7 @@
/**
* Test IMapper::get(BufferId)
*/
-TEST_F(GraphicsMapperHidlTest, GetBufferId) {
+TEST_P(GraphicsMapperHidlTest, GetBufferId) {
testGet(mDummyDescriptorInfo, gralloc4::MetadataType_BufferId,
[](const IMapper::BufferDescriptorInfo& /*info*/, const hidl_vec<uint8_t>& vec) {
uint64_t bufferId = 0;
@@ -646,7 +809,7 @@
/**
* Test IMapper::get(Name)
*/
-TEST_F(GraphicsMapperHidlTest, GetName) {
+TEST_P(GraphicsMapperHidlTest, GetName) {
testGet(mDummyDescriptorInfo, gralloc4::MetadataType_Name,
[](const IMapper::BufferDescriptorInfo& info, const hidl_vec<uint8_t>& vec) {
std::string name;
@@ -658,7 +821,7 @@
/**
* Test IMapper::get(Width)
*/
-TEST_F(GraphicsMapperHidlTest, GetWidth) {
+TEST_P(GraphicsMapperHidlTest, GetWidth) {
testGet(mDummyDescriptorInfo, gralloc4::MetadataType_Width,
[](const IMapper::BufferDescriptorInfo& info, const hidl_vec<uint8_t>& vec) {
uint64_t width = 0;
@@ -670,7 +833,7 @@
/**
* Test IMapper::get(Height)
*/
-TEST_F(GraphicsMapperHidlTest, GetHeight) {
+TEST_P(GraphicsMapperHidlTest, GetHeight) {
testGet(mDummyDescriptorInfo, gralloc4::MetadataType_Height,
[](const IMapper::BufferDescriptorInfo& info, const hidl_vec<uint8_t>& vec) {
uint64_t height = 0;
@@ -682,7 +845,7 @@
/**
* Test IMapper::get(LayerCount)
*/
-TEST_F(GraphicsMapperHidlTest, GetLayerCount) {
+TEST_P(GraphicsMapperHidlTest, GetLayerCount) {
testGet(mDummyDescriptorInfo, gralloc4::MetadataType_LayerCount,
[](const IMapper::BufferDescriptorInfo& info, const hidl_vec<uint8_t>& vec) {
uint64_t layerCount = 0;
@@ -694,7 +857,7 @@
/**
* Test IMapper::get(PixelFormatRequested)
*/
-TEST_F(GraphicsMapperHidlTest, GetPixelFormatRequested) {
+TEST_P(GraphicsMapperHidlTest, GetPixelFormatRequested) {
testGet(mDummyDescriptorInfo, gralloc4::MetadataType_PixelFormatRequested,
[](const IMapper::BufferDescriptorInfo& info, const hidl_vec<uint8_t>& vec) {
PixelFormat pixelFormatRequested = PixelFormat::BLOB;
@@ -707,7 +870,7 @@
/**
* Test IMapper::get(PixelFormatFourCC)
*/
-TEST_F(GraphicsMapperHidlTest, GetPixelFormatFourCC) {
+TEST_P(GraphicsMapperHidlTest, GetPixelFormatFourCC) {
testGet(mDummyDescriptorInfo, gralloc4::MetadataType_PixelFormatFourCC,
[](const IMapper::BufferDescriptorInfo& /*info*/, const hidl_vec<uint8_t>& vec) {
uint32_t pixelFormatFourCC = 0;
@@ -718,7 +881,7 @@
/**
* Test IMapper::get(PixelFormatModifier)
*/
-TEST_F(GraphicsMapperHidlTest, GetPixelFormatModifier) {
+TEST_P(GraphicsMapperHidlTest, GetPixelFormatModifier) {
testGet(mDummyDescriptorInfo, gralloc4::MetadataType_PixelFormatModifier,
[](const IMapper::BufferDescriptorInfo& /*info*/, const hidl_vec<uint8_t>& vec) {
uint64_t pixelFormatModifier = 0;
@@ -729,7 +892,7 @@
/**
* Test IMapper::get(Usage)
*/
-TEST_F(GraphicsMapperHidlTest, GetUsage) {
+TEST_P(GraphicsMapperHidlTest, GetUsage) {
testGet(mDummyDescriptorInfo, gralloc4::MetadataType_Usage,
[](const IMapper::BufferDescriptorInfo& info, const hidl_vec<uint8_t>& vec) {
uint64_t usage = 0;
@@ -741,7 +904,7 @@
/**
* Test IMapper::get(AllocationSize)
*/
-TEST_F(GraphicsMapperHidlTest, GetAllocationSize) {
+TEST_P(GraphicsMapperHidlTest, GetAllocationSize) {
testGet(mDummyDescriptorInfo, gralloc4::MetadataType_AllocationSize,
[](const IMapper::BufferDescriptorInfo& /*info*/, const hidl_vec<uint8_t>& vec) {
uint64_t allocationSize = 0;
@@ -752,7 +915,7 @@
/**
* Test IMapper::get(ProtectedContent)
*/
-TEST_F(GraphicsMapperHidlTest, GetProtectedContent) {
+TEST_P(GraphicsMapperHidlTest, GetProtectedContent) {
auto info = mDummyDescriptorInfo;
info.usage = BufferUsage::PROTECTED | BufferUsage::COMPOSER_OVERLAY;
@@ -774,7 +937,7 @@
/**
* Test IMapper::get(Compression)
*/
-TEST_F(GraphicsMapperHidlTest, GetCompression) {
+TEST_P(GraphicsMapperHidlTest, GetCompression) {
auto info = mDummyDescriptorInfo;
info.usage = static_cast<uint64_t>(BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN);
@@ -791,7 +954,7 @@
/**
* Test IMapper::get(Interlaced)
*/
-TEST_F(GraphicsMapperHidlTest, GetInterlaced) {
+TEST_P(GraphicsMapperHidlTest, GetInterlaced) {
testGet(mDummyDescriptorInfo, gralloc4::MetadataType_Interlaced,
[](const IMapper::BufferDescriptorInfo& /*info*/, const hidl_vec<uint8_t>& vec) {
ExtendableType interlaced = gralloc4::Interlaced_TopBottom;
@@ -805,7 +968,7 @@
/**
* Test IMapper::get(ChromaSiting)
*/
-TEST_F(GraphicsMapperHidlTest, GetChromaSiting) {
+TEST_P(GraphicsMapperHidlTest, GetChromaSiting) {
testGet(mDummyDescriptorInfo, gralloc4::MetadataType_ChromaSiting,
[](const IMapper::BufferDescriptorInfo& /*info*/, const hidl_vec<uint8_t>& vec) {
ExtendableType chromaSiting = gralloc4::ChromaSiting_Unknown;
@@ -819,7 +982,7 @@
/**
* Test IMapper::get(PlaneLayouts)
*/
-TEST_F(GraphicsMapperHidlTest, GetPlaneLayouts) {
+TEST_P(GraphicsMapperHidlTest, GetPlaneLayouts) {
const native_handle_t* bufferHandle = nullptr;
ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(mDummyDescriptorInfo, true));
@@ -835,7 +998,7 @@
/**
* Test IMapper::get(Dataspace)
*/
-TEST_F(GraphicsMapperHidlTest, GetDataspace) {
+TEST_P(GraphicsMapperHidlTest, GetDataspace) {
testGet(mDummyDescriptorInfo, gralloc4::MetadataType_Dataspace,
[](const IMapper::BufferDescriptorInfo& /*info*/, const hidl_vec<uint8_t>& vec) {
Dataspace dataspace = Dataspace::DISPLAY_P3;
@@ -847,7 +1010,7 @@
/**
* Test IMapper::get(BlendMode)
*/
-TEST_F(GraphicsMapperHidlTest, GetBlendMode) {
+TEST_P(GraphicsMapperHidlTest, GetBlendMode) {
testGet(mDummyDescriptorInfo, gralloc4::MetadataType_BlendMode,
[](const IMapper::BufferDescriptorInfo& /*info*/, const hidl_vec<uint8_t>& vec) {
BlendMode blendMode = BlendMode::NONE;
@@ -859,7 +1022,7 @@
/**
* Test IMapper::get(metadata) with a bad buffer
*/
-TEST_F(GraphicsMapperHidlTest, GetMetadataBadValue) {
+TEST_P(GraphicsMapperHidlTest, GetMetadataBadValue) {
const native_handle_t* bufferHandle = nullptr;
hidl_vec<uint8_t> vec;
ASSERT_EQ(Error::BAD_BUFFER,
@@ -914,7 +1077,7 @@
/**
* Test IMapper::get(metadata) for unsupported metadata
*/
-TEST_F(GraphicsMapperHidlTest, GetUnsupportedMetadata) {
+TEST_P(GraphicsMapperHidlTest, GetUnsupportedMetadata) {
const native_handle_t* bufferHandle = nullptr;
ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(mDummyDescriptorInfo, true));
@@ -928,7 +1091,7 @@
/**
* Test IMapper::get(metadata) for unsupported standard metadata
*/
-TEST_F(GraphicsMapperHidlTest, GetUnsupportedStandardMetadata) {
+TEST_P(GraphicsMapperHidlTest, GetUnsupportedStandardMetadata) {
const native_handle_t* bufferHandle = nullptr;
ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(mDummyDescriptorInfo, true));
@@ -942,7 +1105,7 @@
/**
* Test IMapper::set(PixelFormatFourCC)
*/
-TEST_F(GraphicsMapperHidlTest, SetPixelFormatFourCC) {
+TEST_P(GraphicsMapperHidlTest, SetPixelFormatFourCC) {
uint32_t pixelFormatFourCC = 0x34324142; // DRM_FORMAT_BGRA8888
hidl_vec<uint8_t> vec;
ASSERT_EQ(NO_ERROR, gralloc4::encodePixelFormatFourCC(pixelFormatFourCC, &vec));
@@ -958,7 +1121,7 @@
/**
* Test IMapper::set(PixelFormatModifier)
*/
-TEST_F(GraphicsMapperHidlTest, SetPixelFormatModifier) {
+TEST_P(GraphicsMapperHidlTest, SetPixelFormatModifier) {
uint64_t pixelFormatModifier = 10;
hidl_vec<uint8_t> vec;
ASSERT_EQ(NO_ERROR, gralloc4::encodePixelFormatModifier(pixelFormatModifier, &vec));
@@ -975,7 +1138,7 @@
/**
* Test IMapper::set(Usage) remove flag
*/
-TEST_F(GraphicsMapperHidlTest, SetUsageRemoveBit) {
+TEST_P(GraphicsMapperHidlTest, SetUsageRemoveBit) {
uint64_t usage = static_cast<uint64_t>(BufferUsage::CPU_WRITE_OFTEN);
hidl_vec<uint8_t> vec;
ASSERT_EQ(NO_ERROR, gralloc4::encodeUsage(usage, &vec));
@@ -990,7 +1153,7 @@
/**
* Test IMapper::set(Usage) add flag
*/
-TEST_F(GraphicsMapperHidlTest, SetUsageAddBit) {
+TEST_P(GraphicsMapperHidlTest, SetUsageAddBit) {
uint64_t usage = mDummyDescriptorInfo.usage | static_cast<uint64_t>(BufferUsage::GPU_TEXTURE);
hidl_vec<uint8_t> vec;
ASSERT_EQ(NO_ERROR, gralloc4::encodeUsage(usage, &vec));
@@ -1006,7 +1169,7 @@
/**
* Test IMapper::set(Usage) to test protected content
*/
-TEST_F(GraphicsMapperHidlTest, SetUsageProtected) {
+TEST_P(GraphicsMapperHidlTest, SetUsageProtected) {
const native_handle_t* bufferHandle = nullptr;
auto info = mDummyDescriptorInfo;
info.usage = BufferUsage::PROTECTED | BufferUsage::COMPOSER_OVERLAY;
@@ -1033,7 +1196,7 @@
/**
* Test IMapper::set(AllocationSize)
*/
-TEST_F(GraphicsMapperHidlTest, SetAllocationSize) {
+TEST_P(GraphicsMapperHidlTest, SetAllocationSize) {
uint64_t allocationSize = 1000000;
hidl_vec<uint8_t> vec;
ASSERT_EQ(NO_ERROR, gralloc4::encodeAllocationSize(allocationSize, &vec));
@@ -1049,7 +1212,7 @@
/**
* Test IMapper::set(ProtectedContent)
*/
-TEST_F(GraphicsMapperHidlTest, SetProtectedContent) {
+TEST_P(GraphicsMapperHidlTest, SetProtectedContent) {
const native_handle_t* bufferHandle = nullptr;
auto info = mDummyDescriptorInfo;
info.usage = BufferUsage::PROTECTED | BufferUsage::COMPOSER_OVERLAY;
@@ -1077,7 +1240,7 @@
/**
* Test IMapper::set(Compression)
*/
-TEST_F(GraphicsMapperHidlTest, SetCompression) {
+TEST_P(GraphicsMapperHidlTest, SetCompression) {
auto info = mDummyDescriptorInfo;
info.usage = static_cast<uint64_t>(BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN);
@@ -1098,7 +1261,7 @@
/**
* Test IMapper::set(Interlaced)
*/
-TEST_F(GraphicsMapperHidlTest, SetInterlaced) {
+TEST_P(GraphicsMapperHidlTest, SetInterlaced) {
ExtendableType interlaced = gralloc4::Interlaced_RightLeft;
hidl_vec<uint8_t> vec;
ASSERT_EQ(NO_ERROR, gralloc4::encodeInterlaced(interlaced, &vec));
@@ -1116,7 +1279,7 @@
/**
* Test IMapper::set(ChromaSiting)
*/
-TEST_F(GraphicsMapperHidlTest, SetChromaSiting) {
+TEST_P(GraphicsMapperHidlTest, SetChromaSiting) {
ExtendableType chromaSiting = gralloc4::ChromaSiting_SitedInterstitial;
hidl_vec<uint8_t> vec;
ASSERT_EQ(NO_ERROR, gralloc4::encodeChromaSiting(chromaSiting, &vec));
@@ -1134,7 +1297,7 @@
/**
* Test IMapper::set(PlaneLayouts)
*/
-TEST_F(GraphicsMapperHidlTest, SetPlaneLayouts) {
+TEST_P(GraphicsMapperHidlTest, SetPlaneLayouts) {
const native_handle_t* bufferHandle = nullptr;
auto info = mDummyDescriptorInfo;
ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(info, true));
@@ -1235,8 +1398,8 @@
/**
* Test IMapper::set(Dataspace)
*/
-TEST_F(GraphicsMapperHidlTest, SetDataspace) {
- Dataspace dataspace = Dataspace::V0_SRGB_LINEAR;
+TEST_P(GraphicsMapperHidlTest, SetDataspace) {
+ Dataspace dataspace = Dataspace::SRGB_LINEAR;
hidl_vec<uint8_t> vec;
ASSERT_EQ(NO_ERROR, gralloc4::encodeDataspace(dataspace, &vec));
@@ -1251,7 +1414,7 @@
/**
* Test IMapper::set(BlendMode)
*/
-TEST_F(GraphicsMapperHidlTest, SetBlendMode) {
+TEST_P(GraphicsMapperHidlTest, SetBlendMode) {
BlendMode blendMode = BlendMode::PREMULTIPLIED;
hidl_vec<uint8_t> vec;
ASSERT_EQ(NO_ERROR, gralloc4::encodeBlendMode(blendMode, &vec));
@@ -1267,7 +1430,7 @@
/**
* Test IMapper::set(metadata) with a bad buffer
*/
-TEST_F(GraphicsMapperHidlTest, SetMetadataNullBuffer) {
+TEST_P(GraphicsMapperHidlTest, SetMetadataNullBuffer) {
const native_handle_t* bufferHandle = nullptr;
hidl_vec<uint8_t> vec;
ASSERT_EQ(Error::BAD_BUFFER, mGralloc->set(bufferHandle, gralloc4::MetadataType_BufferId, vec));
@@ -1304,7 +1467,7 @@
/**
* Test IMapper::set(metadata) for constant metadata
*/
-TEST_F(GraphicsMapperHidlTest, SetConstantMetadata) {
+TEST_P(GraphicsMapperHidlTest, SetConstantMetadata) {
const native_handle_t* bufferHandle = nullptr;
ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(mDummyDescriptorInfo, true));
@@ -1323,7 +1486,7 @@
/**
* Test IMapper::set(metadata) for bad metadata
*/
-TEST_F(GraphicsMapperHidlTest, SetBadMetadata) {
+TEST_P(GraphicsMapperHidlTest, SetBadMetadata) {
const native_handle_t* bufferHandle = nullptr;
ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(mDummyDescriptorInfo, true));
@@ -1363,7 +1526,7 @@
/**
* Test IMapper::getFromBufferDescriptorInfo(BufferId)
*/
-TEST_F(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoBufferId) {
+TEST_P(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoBufferId) {
hidl_vec<uint8_t> vec;
ASSERT_EQ(Error::UNSUPPORTED,
mGralloc->getFromBufferDescriptorInfo(mDummyDescriptorInfo,
@@ -1373,7 +1536,7 @@
/**
* Test IMapper::getFromBufferDescriptorInfo(Name)
*/
-TEST_F(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoName) {
+TEST_P(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoName) {
hidl_vec<uint8_t> vec;
ASSERT_EQ(Error::NONE, mGralloc->getFromBufferDescriptorInfo(
mDummyDescriptorInfo, gralloc4::MetadataType_Name, &vec));
@@ -1386,7 +1549,7 @@
/**
* Test IMapper::getFromBufferDescriptorInfo(Width)
*/
-TEST_F(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoWidth) {
+TEST_P(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoWidth) {
hidl_vec<uint8_t> vec;
ASSERT_EQ(Error::NONE, mGralloc->getFromBufferDescriptorInfo(
mDummyDescriptorInfo, gralloc4::MetadataType_Width, &vec));
@@ -1399,7 +1562,7 @@
/**
* Test IMapper::getFromBufferDescriptorInfo(Height)
*/
-TEST_F(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoHeight) {
+TEST_P(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoHeight) {
hidl_vec<uint8_t> vec;
ASSERT_EQ(Error::NONE, mGralloc->getFromBufferDescriptorInfo(
mDummyDescriptorInfo, gralloc4::MetadataType_Height, &vec));
@@ -1412,7 +1575,7 @@
/**
* Test IMapper::getFromBufferDescriptorInfo(PixelFormatRequested)
*/
-TEST_F(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoPixelFormatRequested) {
+TEST_P(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoPixelFormatRequested) {
hidl_vec<uint8_t> vec;
ASSERT_EQ(Error::NONE,
mGralloc->getFromBufferDescriptorInfo(
@@ -1426,7 +1589,7 @@
/**
* Test IMapper::getFromBufferDescriptorInfo(PixelFormatFourCC)
*/
-TEST_F(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoPixelFormatFourCC) {
+TEST_P(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoPixelFormatFourCC) {
hidl_vec<uint8_t> vec;
Error err = mGralloc->getFromBufferDescriptorInfo(
mDummyDescriptorInfo, gralloc4::MetadataType_PixelFormatFourCC, &vec);
@@ -1442,7 +1605,7 @@
/**
* Test IMapper::getFromBufferDescriptorInfo(PixelFormatModifier)
*/
-TEST_F(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoPixelFormatModifier) {
+TEST_P(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoPixelFormatModifier) {
hidl_vec<uint8_t> vec;
Error err = mGralloc->getFromBufferDescriptorInfo(
mDummyDescriptorInfo, gralloc4::MetadataType_PixelFormatModifier, &vec);
@@ -1458,7 +1621,7 @@
/**
* Test IMapper::getFromBufferDescriptorInfo(Usage)
*/
-TEST_F(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoUsage) {
+TEST_P(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoUsage) {
hidl_vec<uint8_t> vec;
ASSERT_EQ(Error::NONE, mGralloc->getFromBufferDescriptorInfo(
mDummyDescriptorInfo, gralloc4::MetadataType_Usage, &vec));
@@ -1471,7 +1634,7 @@
/**
* Test IMapper::getFromBufferDescriptorInfo(AllocationSize)
*/
-TEST_F(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoAllocationSize) {
+TEST_P(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoAllocationSize) {
hidl_vec<uint8_t> vec;
Error err = mGralloc->getFromBufferDescriptorInfo(mDummyDescriptorInfo,
gralloc4::MetadataType_AllocationSize, &vec);
@@ -1487,7 +1650,7 @@
/**
* Test IMapper::getFromBufferDescriptorInfo(ProtectedContent)
*/
-TEST_F(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoProtectedContent) {
+TEST_P(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoProtectedContent) {
auto info = mDummyDescriptorInfo;
info.usage = BufferUsage::PROTECTED | BufferUsage::COMPOSER_OVERLAY;
@@ -1503,7 +1666,7 @@
/**
* Test IMapper::getFromBufferDescriptorInfo(Compression)
*/
-TEST_F(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoCompression) {
+TEST_P(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoCompression) {
auto info = mDummyDescriptorInfo;
info.usage = static_cast<uint64_t>(BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN);
@@ -1521,7 +1684,7 @@
/**
* Test IMapper::getFromBufferDescriptorInfo(Interlaced)
*/
-TEST_F(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoInterlaced) {
+TEST_P(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoInterlaced) {
hidl_vec<uint8_t> vec;
ASSERT_EQ(Error::NONE, mGralloc->getFromBufferDescriptorInfo(
mDummyDescriptorInfo, gralloc4::MetadataType_Interlaced, &vec));
@@ -1536,7 +1699,7 @@
/**
* Test IMapper::getFromBufferDescriptorInfo(ChromaSiting)
*/
-TEST_F(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoChromaSiting) {
+TEST_P(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoChromaSiting) {
hidl_vec<uint8_t> vec;
ASSERT_EQ(Error::NONE,
mGralloc->getFromBufferDescriptorInfo(mDummyDescriptorInfo,
@@ -1552,7 +1715,7 @@
/**
* Test IMapper::getFromBufferDescriptorInfo(PlaneLayouts)
*/
-TEST_F(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoPlaneLayouts) {
+TEST_P(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoPlaneLayouts) {
hidl_vec<uint8_t> vec;
ASSERT_EQ(Error::NONE,
mGralloc->getFromBufferDescriptorInfo(mDummyDescriptorInfo,
@@ -1566,7 +1729,7 @@
/**
* Test IMapper::getFromBufferDescriptorInfo(Dataspace)
*/
-TEST_F(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoDataspace) {
+TEST_P(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoDataspace) {
hidl_vec<uint8_t> vec;
ASSERT_EQ(Error::NONE, mGralloc->getFromBufferDescriptorInfo(
mDummyDescriptorInfo, gralloc4::MetadataType_Dataspace, &vec));
@@ -1579,7 +1742,7 @@
/**
* Test IMapper::getFromBufferDescriptorInfo(BlendMode)
*/
-TEST_F(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoBlendMode) {
+TEST_P(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoBlendMode) {
hidl_vec<uint8_t> vec;
ASSERT_EQ(Error::NONE, mGralloc->getFromBufferDescriptorInfo(
mDummyDescriptorInfo, gralloc4::MetadataType_BlendMode, &vec));
@@ -1592,7 +1755,7 @@
/**
* Test IMapper::getFromBufferDescriptorInfo(metadata) for unsupported metadata
*/
-TEST_F(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoUnsupportedMetadata) {
+TEST_P(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoUnsupportedMetadata) {
MetadataType metadataTypeFake = {"FAKE", 1};
hidl_vec<uint8_t> vec;
@@ -1604,7 +1767,7 @@
/**
* Test IMapper::getFromBufferDescriptorInfo(metadata) for unsupported standard metadata
*/
-TEST_F(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoUnsupportedStandardMetadata) {
+TEST_P(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoUnsupportedStandardMetadata) {
MetadataType metadataTypeFake = {GRALLOC4_STANDARD_METADATA_TYPE, 9999};
hidl_vec<uint8_t> vec;
@@ -1616,7 +1779,7 @@
/**
* Test IMapper::listSupportedMetadataTypes()
*/
-TEST_F(GraphicsMapperHidlTest, ListSupportedMetadataTypes) {
+TEST_P(GraphicsMapperHidlTest, ListSupportedMetadataTypes) {
hidl_vec<IMapper::MetadataTypeDescription> descriptions;
mGralloc->getMapper()->listSupportedMetadataTypes(
[&](const auto& tmpError, const auto& tmpDescriptions) {
@@ -1661,6 +1824,183 @@
ASSERT_EQ(sRequiredMetadataTypes, foundMetadataTypes);
}
+/**
+ * Test IMapper::dumpBuffer()
+ */
+TEST_P(GraphicsMapperHidlTest, DumpBuffer) {
+ const native_handle_t* bufferHandle = nullptr;
+ ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(mDummyDescriptorInfo, true));
+ auto buffer = const_cast<native_handle_t*>(bufferHandle);
+
+ IMapper::BufferDump bufferDump;
+ mGralloc->getMapper()->dumpBuffer(buffer, [&](const auto& tmpError, const auto& tmpBufferDump) {
+ ASSERT_EQ(Error::NONE, tmpError);
+ bufferDump = tmpBufferDump;
+ });
+
+ ASSERT_NO_FATAL_FAILURE(verifyBufferDump(bufferDump, buffer));
+}
+
+/**
+ * Test IMapper::dumpBuffer() with an invalid buffer
+ */
+TEST_P(GraphicsMapperHidlTest, DumpBufferNullBuffer) {
+ native_handle_t* bufferHandle = nullptr;
+ auto buffer = const_cast<native_handle_t*>(bufferHandle);
+
+ mGralloc->getMapper()->dumpBuffer(buffer,
+ [&](const auto& tmpError, const auto& /*tmpBufferDump*/) {
+ ASSERT_EQ(Error::BAD_BUFFER, tmpError);
+ });
+}
+
+/**
+ * Test IMapper::dumpBuffer() multiple
+ */
+TEST_P(GraphicsMapperHidlTest, DumpBuffers) {
+ size_t bufferCount = 10;
+
+ for (int i = 0; i < bufferCount; i++) {
+ ASSERT_NO_FATAL_FAILURE(mGralloc->allocate(mDummyDescriptorInfo, true));
+ }
+
+ hidl_vec<IMapper::BufferDump> bufferDump;
+ mGralloc->getMapper()->dumpBuffers([&](const auto& tmpError, const auto& tmpBufferDump) {
+ ASSERT_EQ(Error::NONE, tmpError);
+ bufferDump = tmpBufferDump;
+ });
+
+ ASSERT_EQ(bufferCount, bufferDump.size());
+
+ for (const auto& dump : bufferDump) {
+ ASSERT_NO_FATAL_FAILURE(verifyBufferDump(dump));
+ }
+}
+
+/**
+ * Test IMapper::getReservedRegion()
+ */
+TEST_P(GraphicsMapperHidlTest, GetReservedRegion) {
+ const native_handle_t* bufferHandle = nullptr;
+ auto info = mDummyDescriptorInfo;
+
+ const int pageSize = getpagesize();
+ ASSERT_GE(0, pageSize);
+ std::vector<uint64_t> requestedReservedSizes{1, 10, 333, static_cast<uint64_t>(pageSize) / 2,
+ static_cast<uint64_t>(pageSize)};
+
+ for (auto requestedReservedSize : requestedReservedSizes) {
+ info.reservedSize = requestedReservedSize;
+
+ ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(info, true));
+
+ void* reservedRegion = nullptr;
+ uint64_t reservedSize = 0;
+ ASSERT_EQ(Error::NONE,
+ mGralloc->getReservedRegion(bufferHandle, &reservedRegion, &reservedSize));
+ ASSERT_NE(nullptr, reservedRegion);
+ ASSERT_EQ(requestedReservedSize, reservedSize);
+
+ uint8_t testValue = 1;
+ memset(reservedRegion, testValue, reservedSize);
+ for (uint64_t i = 0; i < reservedSize; i++) {
+ ASSERT_EQ(testValue, static_cast<uint8_t*>(reservedRegion)[i]);
+ }
+ }
+}
+
+/**
+ * Test IMapper::getReservedRegion() request over a page
+ */
+TEST_P(GraphicsMapperHidlTest, GetLargeReservedRegion) {
+ const native_handle_t* bufferHandle = nullptr;
+ auto info = mDummyDescriptorInfo;
+
+ const int pageSize = getpagesize();
+ ASSERT_GE(0, pageSize);
+ std::vector<uint64_t> requestedReservedSizes{static_cast<uint64_t>(pageSize) * 2,
+ static_cast<uint64_t>(pageSize) * 10,
+ static_cast<uint64_t>(pageSize) * 1000};
+
+ for (auto requestedReservedSize : requestedReservedSizes) {
+ info.reservedSize = requestedReservedSize;
+
+ BufferDescriptor descriptor;
+ ASSERT_NO_FATAL_FAILURE(descriptor = mGralloc->createDescriptor(info));
+
+ Error err;
+ mGralloc->getAllocator()->allocate(
+ descriptor, 1,
+ [&](const auto& tmpError, const auto&, const auto&) { err = tmpError; });
+ if (err == Error::UNSUPPORTED) {
+ continue;
+ }
+ ASSERT_EQ(Error::NONE, err);
+
+ void* reservedRegion = nullptr;
+ uint64_t reservedSize = 0;
+ err = mGralloc->getReservedRegion(bufferHandle, &reservedRegion, &reservedSize);
+
+ ASSERT_EQ(Error::NONE, err);
+ ASSERT_NE(nullptr, reservedRegion);
+ ASSERT_EQ(requestedReservedSize, reservedSize);
+ }
+}
+
+/**
+ * Test IMapper::getReservedRegion() across multiple mappers
+ */
+TEST_P(GraphicsMapperHidlTest, GetReservedRegionMultiple) {
+ const native_handle_t* bufferHandle = nullptr;
+ auto info = mDummyDescriptorInfo;
+
+ const int pageSize = getpagesize();
+ ASSERT_GE(0, pageSize);
+ info.reservedSize = pageSize;
+
+ ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(info, true));
+
+ void* reservedRegion1 = nullptr;
+ uint64_t reservedSize1 = 0;
+ ASSERT_EQ(Error::NONE,
+ mGralloc->getReservedRegion(bufferHandle, &reservedRegion1, &reservedSize1));
+ ASSERT_NE(nullptr, reservedRegion1);
+ ASSERT_EQ(info.reservedSize, reservedSize1);
+
+ std::unique_ptr<Gralloc> anotherGralloc;
+ ASSERT_NO_FATAL_FAILURE(anotherGralloc = std::make_unique<Gralloc>(std::get<0>(GetParam()),
+ std::get<1>(GetParam())));
+
+ void* reservedRegion2 = nullptr;
+ uint64_t reservedSize2 = 0;
+ ASSERT_EQ(Error::NONE,
+ mGralloc->getReservedRegion(bufferHandle, &reservedRegion2, &reservedSize2));
+ ASSERT_EQ(reservedRegion1, reservedRegion2);
+ ASSERT_EQ(reservedSize1, reservedSize2);
+}
+
+/**
+ * Test IMapper::getReservedRegion() with a bad buffer
+ */
+TEST_P(GraphicsMapperHidlTest, GetReservedRegionBadBuffer) {
+ const native_handle_t* bufferHandle = nullptr;
+
+ void* reservedRegion = nullptr;
+ uint64_t reservedSize = 0;
+ ASSERT_EQ(Error::BAD_BUFFER,
+ mGralloc->getReservedRegion(bufferHandle, &reservedRegion, &reservedSize));
+ ASSERT_EQ(nullptr, reservedRegion);
+ ASSERT_EQ(0, reservedSize);
+}
+
+INSTANTIATE_TEST_CASE_P(
+ PerInstance, GraphicsMapperHidlTest,
+ testing::Combine(
+ testing::ValuesIn(
+ android::hardware::getAllHalInstanceNames(IAllocator::descriptor)),
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(IMapper::descriptor))),
+ android::hardware::PrintInstanceTupleNameToString<>);
+
} // namespace
} // namespace vts
} // namespace V4_0
@@ -1668,13 +2008,3 @@
} // namespace graphics
} // namespace hardware
} // namespace android
-
-int main(int argc, char** argv) {
- using android::hardware::graphics::mapper::V4_0::vts::GraphicsMapperHidlEnvironment;
- ::testing::AddGlobalTestEnvironment(GraphicsMapperHidlEnvironment::Instance());
- ::testing::InitGoogleTest(&argc, argv);
- GraphicsMapperHidlEnvironment::Instance()->init(&argc, argv);
- int status = RUN_ALL_TESTS();
- LOG(INFO) << "Test result = " << status;
- return status;
-}
diff --git a/health/1.0/default/Android.bp b/health/1.0/default/Android.bp
index 049e393..7581335 100644
--- a/health/1.0/default/Android.bp
+++ b/health/1.0/default/Android.bp
@@ -18,3 +18,55 @@
}
+cc_library_static {
+ name: "android.hardware.health@1.0-impl-helper",
+ vendor: true,
+ srcs: ["Health.cpp"],
+
+ header_libs: [
+ "libbase_headers",
+ "libhealthd_headers",
+ ],
+
+ shared_libs: [
+ "libcutils",
+ "libhidlbase",
+ "liblog",
+ "libutils",
+ "android.hardware.health@1.0",
+ ],
+
+ static_libs: [
+ "android.hardware.health@1.0-convert",
+ ],
+}
+
+cc_library_shared {
+ name: "android.hardware.health@1.0-impl",
+ vendor: true,
+ relative_install_path: "hw",
+
+ static_libs: [
+ "android.hardware.health@1.0-impl-helper",
+ "android.hardware.health@1.0-convert",
+ "libhealthd.default",
+ ],
+}
+
+cc_binary {
+ name: "android.hardware.health@1.0-service",
+ vendor: true,
+ relative_install_path: "hw",
+ init_rc: ["android.hardware.health@1.0-service.rc"],
+ srcs: ["HealthService.cpp"],
+
+ shared_libs: [
+ "liblog",
+ "libcutils",
+ "libdl",
+ "libbase",
+ "libutils",
+ "libhidlbase",
+ "android.hardware.health@1.0",
+ ],
+}
diff --git a/health/1.0/default/Android.mk b/health/1.0/default/Android.mk
deleted file mode 100644
index bbf37af..0000000
--- a/health/1.0/default/Android.mk
+++ /dev/null
@@ -1,45 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.health@1.0-impl
-LOCAL_PROPRIETARY_MODULE := true
-LOCAL_MODULE_RELATIVE_PATH := hw
-LOCAL_C_INCLUDES := system/core/base/include
-LOCAL_SRC_FILES := \
- Health.cpp \
-
-LOCAL_HEADER_LIBRARIES := libhealthd_headers
-
-LOCAL_SHARED_LIBRARIES := \
- libcutils \
- libhidlbase \
- liblog \
- libutils \
- android.hardware.health@1.0 \
-
-LOCAL_STATIC_LIBRARIES := android.hardware.health@1.0-convert
-
-LOCAL_HAL_STATIC_LIBRARIES := libhealthd
-
-include $(BUILD_SHARED_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_PROPRIETARY_MODULE := true
-LOCAL_MODULE_RELATIVE_PATH := hw
-LOCAL_MODULE := android.hardware.health@1.0-service
-LOCAL_INIT_RC := android.hardware.health@1.0-service.rc
-LOCAL_SRC_FILES := \
- HealthService.cpp \
-
-LOCAL_SHARED_LIBRARIES := \
- liblog \
- libcutils \
- libdl \
- libbase \
- libutils \
- libhidlbase \
- android.hardware.health@1.0 \
-
-include $(BUILD_EXECUTABLE)
-
-include $(call first-makefiles-under,$(LOCAL_PATH))
diff --git a/health/1.0/default/README.md b/health/1.0/default/README.md
new file mode 100644
index 0000000..1ded7de
--- /dev/null
+++ b/health/1.0/default/README.md
@@ -0,0 +1,66 @@
+# Implement the 2.1 HAL instead!
+
+It is strongly recommended that you implement the 2.1 HAL directly. See
+`hardware/interfaces/health/2.1/README.md` for more details.
+
+# Implement Health 1.0 HAL
+
+1. Install common binderized service. The binderized service `dlopen()`s
+ passthrough implementations on the device, so there is no need to write
+ your own.
+
+ ```mk
+ # Install default binderized implementation to vendor.
+ PRODUCT_PACKAGES += android.hardware.health@1.0-service
+ ```
+
+1. Add proper VINTF manifest entry to your device manifest. Example:
+
+ ```xml
+ <hal format="hidl">
+ <name>android.hardware.health</name>
+ <transport>hwbinder</transport>
+ <version>1.0</version>
+ <interface>
+ <name>IHealth</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ ```
+
+1. Install the proper passthrough implemetation.
+
+ 1. If you want to use the default implementation (with default `libhealthd`),
+ add the following to `device.mk`:
+
+ ```mk
+ PRODUCT_PACKAGES += \
+ android.hardware.health@1.0-impl
+ ```
+
+ 1. Otherwise, if you have a customized `libhealthd.<board>`:
+
+ 1. Define your passthrough implementation. Example (replace `<device>`
+ and `<board>` accordingly):
+
+ ```bp
+ cc_library_shared {
+ name: "android.hardware.health@1.0-impl-<device>",
+ vendor: true,
+ relative_install_path: "hw",
+
+ static_libs: [
+ "android.hardware.health@1.0-impl-helper",
+ "android.hardware.health@1.0-convert",
+ "libhealthd.<board>",
+ ],
+ }
+ ```
+
+ 1. Add to `device.mk`.
+
+ ```
+ PRODUCT_PACKAGES += android.hardware.health@1.0-impl-<device>
+ ```
+
+ 1. Define appropriate SELinux permissions.
diff --git a/health/2.0/default/healthd_common_adapter.cpp b/health/2.0/default/healthd_common_adapter.cpp
index 8fc689d..0b5d869 100644
--- a/health/2.0/default/healthd_common_adapter.cpp
+++ b/health/2.0/default/healthd_common_adapter.cpp
@@ -49,11 +49,14 @@
static std::unique_ptr<HealthLoopAdapter> health_loop;
int healthd_register_event(int fd, void (*handler)(uint32_t), EventWakeup wakeup) {
+ if (!health_loop) return -1;
+
auto wrapped_handler = [handler](auto*, uint32_t epevents) { handler(epevents); };
return health_loop->RegisterEvent(fd, wrapped_handler, wakeup);
}
void healthd_battery_update_internal(bool charger_online) {
+ if (!health_loop) return;
health_loop->AdjustWakealarmPeriods(charger_online);
}
diff --git a/health/2.0/vts/functional/Android.bp b/health/2.0/vts/functional/Android.bp
index b090548..43571ef 100644
--- a/health/2.0/vts/functional/Android.bp
+++ b/health/2.0/vts/functional/Android.bp
@@ -23,5 +23,5 @@
"android.hardware.health@1.0",
"android.hardware.health@2.0",
],
- test_suites: ["general-tests"],
+ test_suites: ["general-tests", "vts-core"],
}
diff --git a/health/2.0/vts/functional/VtsHalHealthV2_0TargetTest.cpp b/health/2.0/vts/functional/VtsHalHealthV2_0TargetTest.cpp
index 6e13a98..49891b7 100644
--- a/health/2.0/vts/functional/VtsHalHealthV2_0TargetTest.cpp
+++ b/health/2.0/vts/functional/VtsHalHealthV2_0TargetTest.cpp
@@ -20,17 +20,18 @@
#include <set>
#include <string>
-#include <VtsHalHidlTargetTestBase.h>
#include <android-base/logging.h>
#include <android/hardware/health/2.0/IHealth.h>
#include <android/hardware/health/2.0/types.h>
#include <gflags/gflags.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
+#include <log/log.h>
using ::testing::AssertionFailure;
using ::testing::AssertionResult;
using ::testing::AssertionSuccess;
-using ::testing::VtsHalHidlTargetTestBase;
-using ::testing::VtsHalHidlTargetTestEnvBase;
DEFINE_bool(force, false, "Force test healthd even when the default instance is present.");
@@ -74,30 +75,13 @@
using V1_0::BatteryStatus;
-// Test environment for graphics.composer
-class HealthHidlEnvironment : public VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static HealthHidlEnvironment* Instance() {
- static HealthHidlEnvironment* instance = new HealthHidlEnvironment;
- return instance;
- }
-
- virtual void registerTestServices() override { registerTestService<IHealth>(); }
-
- private:
- HealthHidlEnvironment() {}
-
- GTEST_DISALLOW_COPY_AND_ASSIGN_(HealthHidlEnvironment);
-};
-
-class HealthHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+class HealthHidlTest : public ::testing::TestWithParam<std::string> {
public:
virtual void SetUp() override {
- std::string serviceName = HealthHidlEnvironment::Instance()->getServiceName<IHealth>();
+ std::string serviceName = GetParam();
if (serviceName == "backup" && !FLAGS_force &&
- ::testing::VtsHalHidlTargetTestBase::getService<IHealth>() != nullptr) {
+ IHealth::getService() != nullptr) {
LOG(INFO) << "Skipping tests on healthd because the default instance is present. "
<< "Use --force if you really want to test healthd.";
GTEST_SKIP();
@@ -105,7 +89,7 @@
LOG(INFO) << "get service with name:" << serviceName;
ASSERT_FALSE(serviceName.empty());
- mHealth = ::testing::VtsHalHidlTargetTestBase::getService<IHealth>(serviceName);
+ mHealth = IHealth::getService(serviceName);
ASSERT_NE(mHealth, nullptr);
}
@@ -156,7 +140,7 @@
* Test whether callbacks work. Tested functions are IHealth::registerCallback,
* unregisterCallback, and update.
*/
-TEST_F(HealthHidlTest, Callbacks) {
+TEST_P(HealthHidlTest, Callbacks) {
SKIP_IF_SKIPPED();
using namespace std::chrono_literals;
sp<Callback> firstCallback = new Callback();
@@ -193,7 +177,7 @@
ASSERT_ALL_OK(mHealth->unregisterCallback(secondCallback));
}
-TEST_F(HealthHidlTest, UnregisterNonExistentCallback) {
+TEST_P(HealthHidlTest, UnregisterNonExistentCallback) {
SKIP_IF_SKIPPED();
sp<Callback> callback = new Callback();
auto ret = mHealth->unregisterCallback(callback);
@@ -278,7 +262,7 @@
/*
* Tests the values returned by getChargeCounter() from interface IHealth.
*/
-TEST_F(HealthHidlTest, getChargeCounter) {
+TEST_P(HealthHidlTest, getChargeCounter) {
SKIP_IF_SKIPPED();
EXPECT_OK(mHealth->getChargeCounter([](auto result, auto value) {
EXPECT_VALID_OR_UNSUPPORTED_PROP(result, std::to_string(value), value > 0);
@@ -288,7 +272,7 @@
/*
* Tests the values returned by getCurrentNow() from interface IHealth.
*/
-TEST_F(HealthHidlTest, getCurrentNow) {
+TEST_P(HealthHidlTest, getCurrentNow) {
SKIP_IF_SKIPPED();
EXPECT_OK(mHealth->getCurrentNow([](auto result, auto value) {
EXPECT_VALID_OR_UNSUPPORTED_PROP(result, std::to_string(value), value != INT32_MIN);
@@ -298,7 +282,7 @@
/*
* Tests the values returned by getCurrentAverage() from interface IHealth.
*/
-TEST_F(HealthHidlTest, getCurrentAverage) {
+TEST_P(HealthHidlTest, getCurrentAverage) {
SKIP_IF_SKIPPED();
EXPECT_OK(mHealth->getCurrentAverage([](auto result, auto value) {
EXPECT_VALID_OR_UNSUPPORTED_PROP(result, std::to_string(value), value != INT32_MIN);
@@ -308,7 +292,7 @@
/*
* Tests the values returned by getCapacity() from interface IHealth.
*/
-TEST_F(HealthHidlTest, getCapacity) {
+TEST_P(HealthHidlTest, getCapacity) {
SKIP_IF_SKIPPED();
EXPECT_OK(mHealth->getCapacity([](auto result, auto value) {
EXPECT_VALID_OR_UNSUPPORTED_PROP(result, std::to_string(value), 0 <= value && value <= 100);
@@ -318,7 +302,7 @@
/*
* Tests the values returned by getEnergyCounter() from interface IHealth.
*/
-TEST_F(HealthHidlTest, getEnergyCounter) {
+TEST_P(HealthHidlTest, getEnergyCounter) {
SKIP_IF_SKIPPED();
EXPECT_OK(mHealth->getEnergyCounter([](auto result, auto value) {
EXPECT_VALID_OR_UNSUPPORTED_PROP(result, std::to_string(value), value != INT64_MIN);
@@ -328,7 +312,7 @@
/*
* Tests the values returned by getChargeStatus() from interface IHealth.
*/
-TEST_F(HealthHidlTest, getChargeStatus) {
+TEST_P(HealthHidlTest, getChargeStatus) {
SKIP_IF_SKIPPED();
EXPECT_OK(mHealth->getChargeStatus([](auto result, auto value) {
EXPECT_VALID_OR_UNSUPPORTED_PROP(
@@ -340,7 +324,7 @@
/*
* Tests the values returned by getStorageInfo() from interface IHealth.
*/
-TEST_F(HealthHidlTest, getStorageInfo) {
+TEST_P(HealthHidlTest, getStorageInfo) {
SKIP_IF_SKIPPED();
EXPECT_OK(mHealth->getStorageInfo([](auto result, auto& value) {
EXPECT_VALID_OR_UNSUPPORTED_PROP(result, toString(value), verifyStorageInfo(value));
@@ -350,7 +334,7 @@
/*
* Tests the values returned by getDiskStats() from interface IHealth.
*/
-TEST_F(HealthHidlTest, getDiskStats) {
+TEST_P(HealthHidlTest, getDiskStats) {
SKIP_IF_SKIPPED();
EXPECT_OK(mHealth->getDiskStats([](auto result, auto& value) {
EXPECT_VALID_OR_UNSUPPORTED_PROP(result, toString(value), true);
@@ -360,25 +344,24 @@
/*
* Tests the values returned by getHealthInfo() from interface IHealth.
*/
-TEST_F(HealthHidlTest, getHealthInfo) {
+TEST_P(HealthHidlTest, getHealthInfo) {
SKIP_IF_SKIPPED();
EXPECT_OK(mHealth->getHealthInfo([](auto result, auto& value) {
EXPECT_VALID_OR_UNSUPPORTED_PROP(result, toString(value), verifyHealthInfo(value));
}));
}
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, HealthHidlTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(IHealth::descriptor)),
+ android::hardware::PrintInstanceNameToString);
} // namespace V2_0
} // namespace health
} // namespace hardware
} // namespace android
int main(int argc, char** argv) {
- using ::android::hardware::health::V2_0::HealthHidlEnvironment;
- ::testing::AddGlobalTestEnvironment(HealthHidlEnvironment::Instance());
::testing::InitGoogleTest(&argc, argv);
- HealthHidlEnvironment::Instance()->init(&argc, argv);
gflags::ParseCommandLineFlags(&argc, &argv, true /* remove flags */);
- int status = RUN_ALL_TESTS();
- LOG(INFO) << "Test result = " << status;
- return status;
+ return RUN_ALL_TESTS();
}
diff --git a/keymaster/3.0/vts/functional/Android.bp b/keymaster/3.0/vts/functional/Android.bp
index 69aa56d..36a6861 100644
--- a/keymaster/3.0/vts/functional/Android.bp
+++ b/keymaster/3.0/vts/functional/Android.bp
@@ -29,5 +29,5 @@
"libcrypto_static",
"libsoftkeymasterdevice",
],
- test_suites: ["general-tests"],
+ test_suites: ["general-tests", "vts-core"],
}
diff --git a/keymaster/3.0/vts/functional/AndroidTest.xml b/keymaster/3.0/vts/functional/AndroidTest.xml
new file mode 100644
index 0000000..71e41fc
--- /dev/null
+++ b/keymaster/3.0/vts/functional/AndroidTest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 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.
+-->
+<configuration description="Runs VtsHalKeymasterV3_0TargetTest.">
+ <option name="test-suite-tag" value="apct" />
+ <option name="test-suite-tag" value="apct-native" />
+
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
+ </target_preparer>
+
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="cleanup" value="true" />
+ <option name="push" value="VtsHalKeymasterV3_0TargetTest->/data/local/tmp/VtsHalKeymasterV3_0TargetTest" />
+ </target_preparer>
+
+ <test class="com.android.tradefed.testtype.GTest" >
+ <option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="module-name" value="VtsHalKeymasterV3_0TargetTest" />
+ <option name="native-test-timeout" value="900000"/>
+ </test>
+</configuration>
diff --git a/keymaster/3.0/vts/functional/keymaster_hidl_hal_test.cpp b/keymaster/3.0/vts/functional/keymaster_hidl_hal_test.cpp
index ccb5622..ae32764 100644
--- a/keymaster/3.0/vts/functional/keymaster_hidl_hal_test.cpp
+++ b/keymaster/3.0/vts/functional/keymaster_hidl_hal_test.cpp
@@ -25,17 +25,15 @@
#include <android/hardware/keymaster/3.0/IKeymasterDevice.h>
#include <android/hardware/keymaster/3.0/types.h>
-
#include <cutils/properties.h>
-
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include <keymaster/keymaster_configuration.h>
#include "authorization_set.h"
#include "key_param_output.h"
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
-
#include "attestation_record.h"
#include "openssl_utils.h"
@@ -413,33 +411,19 @@
} // namespace
-// Test environment for Keymaster HIDL HAL.
-class KeymasterHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static KeymasterHidlEnvironment* Instance() {
- static KeymasterHidlEnvironment* instance = new KeymasterHidlEnvironment;
- return instance;
- }
-
- virtual void registerTestServices() override { registerTestService<IKeymasterDevice>(); }
- private:
- KeymasterHidlEnvironment() {}
-};
-
-class KeymasterHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+class KeymasterHidlTest : public ::testing::TestWithParam<std::string> {
public:
void TearDown() override {
if (key_blob_.size()) {
CheckedDeleteKey();
}
AbortIfNeeded();
+
+ keymaster_.clear();
}
- // SetUpTestCase runs only once per test case, not once per test.
- static void SetUpTestCase() {
- keymaster_ = ::testing::VtsHalHidlTargetTestBase::getService<IKeymasterDevice>(
- KeymasterHidlEnvironment::Instance()->getServiceName<IKeymasterDevice>());
+ void SetUp() override {
+ keymaster_ = IKeymasterDevice::getService(GetParam());
ASSERT_NE(keymaster_, nullptr);
ASSERT_TRUE(
@@ -461,11 +445,9 @@
os_patch_level_ = ::keymaster::GetOsPatchlevel();
}
- static void TearDownTestCase() { keymaster_.clear(); }
-
- static IKeymasterDevice& keymaster() { return *keymaster_; }
- static uint32_t os_version() { return os_version_; }
- static uint32_t os_patch_level() { return os_patch_level_; }
+ IKeymasterDevice& keymaster() { return *keymaster_; }
+ uint32_t os_version() { return os_version_; }
+ uint32_t os_patch_level() { return os_patch_level_; }
AuthorizationSet UserAuths() { return AuthorizationSetBuilder().Authorization(TAG_USER_ID, 7); }
@@ -929,134 +911,121 @@
}
}
- static bool IsSecure() { return is_secure_; }
- static bool SupportsEc() { return supports_ec_; }
- static bool SupportsSymmetric() { return supports_symmetric_; }
- static bool SupportsAllDigests() { return supports_all_digests_; }
- static bool SupportsAttestation() { return supports_attestation_; }
+ bool IsSecure() { return is_secure_; }
+ bool SupportsEc() { return supports_ec_; }
+ bool SupportsSymmetric() { return supports_symmetric_; }
+ bool SupportsAllDigests() { return supports_all_digests_; }
+ bool SupportsAttestation() { return supports_attestation_; }
- static bool Km2Profile() {
+ bool Km2Profile() {
return SupportsAttestation() && SupportsAllDigests() && SupportsSymmetric() &&
SupportsEc() && IsSecure();
}
- static bool Km1Profile() {
+ bool Km1Profile() {
return !SupportsAttestation() && SupportsSymmetric() && SupportsEc() && IsSecure();
}
- static bool Km0Profile() {
+ bool Km0Profile() {
return !SupportsAttestation() && !SupportsAllDigests() && !SupportsSymmetric() &&
IsSecure();
}
- static bool SwOnlyProfile() {
+ bool SwOnlyProfile() {
return !SupportsAttestation() && !SupportsAllDigests() && !SupportsSymmetric() &&
!SupportsEc() && !IsSecure();
}
+ bool verify_attestation_record(const string& challenge, const string& app_id,
+ AuthorizationSet expected_sw_enforced,
+ AuthorizationSet expected_tee_enforced,
+ const hidl_vec<uint8_t>& attestation_cert) {
+ X509_Ptr cert(parse_cert_blob(attestation_cert));
+ EXPECT_TRUE(!!cert.get());
+ if (!cert.get()) return false;
+
+ ASN1_OCTET_STRING* attest_rec = get_attestation_record(cert.get());
+ EXPECT_TRUE(!!attest_rec);
+ if (!attest_rec) return false;
+
+ AuthorizationSet att_sw_enforced;
+ AuthorizationSet att_tee_enforced;
+ uint32_t att_attestation_version;
+ uint32_t att_keymaster_version;
+ SecurityLevel att_attestation_security_level;
+ SecurityLevel att_keymaster_security_level;
+ HidlBuf att_challenge;
+ HidlBuf att_unique_id;
+ HidlBuf att_app_id;
+ EXPECT_EQ(ErrorCode::OK,
+ parse_attestation_record(attest_rec->data, //
+ attest_rec->length, //
+ &att_attestation_version, //
+ &att_attestation_security_level, //
+ &att_keymaster_version, //
+ &att_keymaster_security_level, //
+ &att_challenge, //
+ &att_sw_enforced, //
+ &att_tee_enforced, //
+ &att_unique_id));
+
+ EXPECT_TRUE(att_attestation_version == 1 || att_attestation_version == 2);
+
+ expected_sw_enforced.push_back(TAG_ATTESTATION_APPLICATION_ID, HidlBuf(app_id));
+
+ if (!IsSecure()) {
+ // SW is KM3
+ EXPECT_EQ(att_keymaster_version, 3U);
+ }
+
+ if (SupportsSymmetric()) {
+ EXPECT_GE(att_keymaster_version, 1U);
+ }
+
+ if (SupportsAttestation()) {
+ EXPECT_GE(att_keymaster_version, 2U);
+ }
+
+ EXPECT_EQ(IsSecure() ? SecurityLevel::TRUSTED_ENVIRONMENT : SecurityLevel::SOFTWARE,
+ att_keymaster_security_level);
+ EXPECT_EQ(SupportsAttestation() ? SecurityLevel::TRUSTED_ENVIRONMENT
+ : SecurityLevel::SOFTWARE,
+ att_attestation_security_level);
+
+ EXPECT_EQ(challenge.length(), att_challenge.size());
+ EXPECT_EQ(0, memcmp(challenge.data(), att_challenge.data(), challenge.length()));
+
+ att_sw_enforced.Sort();
+ expected_sw_enforced.Sort();
+ EXPECT_EQ(filter_tags(expected_sw_enforced), filter_tags(att_sw_enforced))
+ << "(Possibly b/38394619)";
+
+ att_tee_enforced.Sort();
+ expected_tee_enforced.Sort();
+ EXPECT_EQ(filter_tags(expected_tee_enforced), filter_tags(att_tee_enforced))
+ << "(Possibly b/38394619)";
+
+ return true;
+ }
+
HidlBuf key_blob_;
KeyCharacteristics key_characteristics_;
OperationHandle op_handle_ = kOpHandleSentinel;
private:
- static sp<IKeymasterDevice> keymaster_;
- static uint32_t os_version_;
- static uint32_t os_patch_level_;
+ sp<IKeymasterDevice> keymaster_;
+ uint32_t os_version_;
+ uint32_t os_patch_level_;
- static bool is_secure_;
- static bool supports_ec_;
- static bool supports_symmetric_;
- static bool supports_attestation_;
- static bool supports_all_digests_;
- static hidl_string name_;
- static hidl_string author_;
+ bool is_secure_;
+ bool supports_ec_;
+ bool supports_symmetric_;
+ bool supports_attestation_;
+ bool supports_all_digests_;
+ hidl_string name_;
+ hidl_string author_;
};
-bool verify_attestation_record(const string& challenge, const string& app_id,
- AuthorizationSet expected_sw_enforced,
- AuthorizationSet expected_tee_enforced,
- const hidl_vec<uint8_t>& attestation_cert) {
- X509_Ptr cert(parse_cert_blob(attestation_cert));
- EXPECT_TRUE(!!cert.get());
- if (!cert.get()) return false;
-
- ASN1_OCTET_STRING* attest_rec = get_attestation_record(cert.get());
- EXPECT_TRUE(!!attest_rec);
- if (!attest_rec) return false;
-
- AuthorizationSet att_sw_enforced;
- AuthorizationSet att_tee_enforced;
- uint32_t att_attestation_version;
- uint32_t att_keymaster_version;
- SecurityLevel att_attestation_security_level;
- SecurityLevel att_keymaster_security_level;
- HidlBuf att_challenge;
- HidlBuf att_unique_id;
- HidlBuf att_app_id;
- EXPECT_EQ(ErrorCode::OK,
- parse_attestation_record(attest_rec->data, //
- attest_rec->length, //
- &att_attestation_version, //
- &att_attestation_security_level, //
- &att_keymaster_version, //
- &att_keymaster_security_level, //
- &att_challenge, //
- &att_sw_enforced, //
- &att_tee_enforced, //
- &att_unique_id));
-
- EXPECT_TRUE(att_attestation_version == 1 || att_attestation_version == 2);
-
- expected_sw_enforced.push_back(TAG_ATTESTATION_APPLICATION_ID,
- HidlBuf(app_id));
-
- if (!KeymasterHidlTest::IsSecure()) {
- // SW is KM3
- EXPECT_EQ(att_keymaster_version, 3U);
- }
-
- if (KeymasterHidlTest::SupportsSymmetric()) {
- EXPECT_GE(att_keymaster_version, 1U);
- }
-
- if (KeymasterHidlTest::SupportsAttestation()) {
- EXPECT_GE(att_keymaster_version, 2U);
- }
-
- EXPECT_EQ(KeymasterHidlTest::IsSecure() ? SecurityLevel::TRUSTED_ENVIRONMENT
- : SecurityLevel::SOFTWARE,
- att_keymaster_security_level);
- EXPECT_EQ(KeymasterHidlTest::SupportsAttestation() ? SecurityLevel::TRUSTED_ENVIRONMENT
- : SecurityLevel::SOFTWARE,
- att_attestation_security_level);
-
- EXPECT_EQ(challenge.length(), att_challenge.size());
- EXPECT_EQ(0, memcmp(challenge.data(), att_challenge.data(), challenge.length()));
-
- att_sw_enforced.Sort();
- expected_sw_enforced.Sort();
- EXPECT_EQ(filter_tags(expected_sw_enforced), filter_tags(att_sw_enforced))
- << "(Possibly b/38394619)";
-
- att_tee_enforced.Sort();
- expected_tee_enforced.Sort();
- EXPECT_EQ(filter_tags(expected_tee_enforced), filter_tags(att_tee_enforced))
- << "(Possibly b/38394619)";
-
- return true;
-}
-
-sp<IKeymasterDevice> KeymasterHidlTest::keymaster_;
-uint32_t KeymasterHidlTest::os_version_;
-uint32_t KeymasterHidlTest::os_patch_level_;
-bool KeymasterHidlTest::is_secure_;
-bool KeymasterHidlTest::supports_ec_;
-bool KeymasterHidlTest::supports_symmetric_;
-bool KeymasterHidlTest::supports_all_digests_;
-bool KeymasterHidlTest::supports_attestation_;
-hidl_string KeymasterHidlTest::name_;
-hidl_string KeymasterHidlTest::author_;
-
typedef KeymasterHidlTest KeymasterVersionTest;
/*
@@ -1065,7 +1034,7 @@
* Queries keymaster to find the set of features it supports. Fails if the combination doesn't
* correspond to any well-defined keymaster version.
*/
-TEST_F(KeymasterVersionTest, SensibleFeatures) {
+TEST_P(KeymasterVersionTest, SensibleFeatures) {
EXPECT_TRUE(Km2Profile() || Km1Profile() || Km0Profile() || SwOnlyProfile())
<< "Keymaster feature set doesn't fit any reasonable profile. Reported features:"
<< "SupportsAttestation [" << SupportsAttestation() << "], "
@@ -1124,7 +1093,7 @@
* Verifies that keymaster can generate all required RSA key sizes, and that the resulting keys have
* correct characteristics.
*/
-TEST_F(NewKeyGenerationTest, Rsa) {
+TEST_P(NewKeyGenerationTest, Rsa) {
for (auto key_size : {1024, 2048, 3072, 4096}) {
HidlBuf key_blob;
KeyCharacteristics key_characteristics;
@@ -1158,7 +1127,7 @@
*
* Verifies that failing to specify a key size for RSA key generation returns UNSUPPORTED_KEY_SIZE.
*/
-TEST_F(NewKeyGenerationTest, RsaNoDefaultSize) {
+TEST_P(NewKeyGenerationTest, RsaNoDefaultSize) {
ASSERT_EQ(ErrorCode::UNSUPPORTED_KEY_SIZE,
GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_ALGORITHM, Algorithm::RSA)
@@ -1172,7 +1141,7 @@
* Verifies that keymaster can generate all required EC key sizes, and that the resulting keys have
* correct characteristics.
*/
-TEST_F(NewKeyGenerationTest, Ecdsa) {
+TEST_P(NewKeyGenerationTest, Ecdsa) {
for (auto key_size : {224, 256, 384, 521}) {
HidlBuf key_blob;
KeyCharacteristics key_characteristics;
@@ -1203,7 +1172,7 @@
*
* Verifies that failing to specify a key size for EC key generation returns UNSUPPORTED_KEY_SIZE.
*/
-TEST_F(NewKeyGenerationTest, EcdsaDefaultSize) {
+TEST_P(NewKeyGenerationTest, EcdsaDefaultSize) {
ASSERT_EQ(ErrorCode::UNSUPPORTED_KEY_SIZE,
GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_ALGORITHM, Algorithm::EC)
@@ -1217,7 +1186,7 @@
* Verifies that failing to specify an invalid key size for EC key generation returns
* UNSUPPORTED_KEY_SIZE.
*/
-TEST_F(NewKeyGenerationTest, EcdsaInvalidSize) {
+TEST_P(NewKeyGenerationTest, EcdsaInvalidSize) {
ASSERT_EQ(ErrorCode::UNSUPPORTED_KEY_SIZE,
GenerateKey(AuthorizationSetBuilder().EcdsaSigningKey(190).Digest(Digest::NONE)));
}
@@ -1228,7 +1197,7 @@
* Verifies that specifying mismatched key size and curve for EC key generation returns
* INVALID_ARGUMENT.
*/
-TEST_F(NewKeyGenerationTest, EcdsaMismatchKeySize) {
+TEST_P(NewKeyGenerationTest, EcdsaMismatchKeySize) {
ASSERT_EQ(ErrorCode::INVALID_ARGUMENT,
GenerateKey(AuthorizationSetBuilder()
.EcdsaSigningKey(224)
@@ -1237,7 +1206,7 @@
<< "(Possibly b/36233343)";
}
-TEST_F(NewKeyGenerationTest, EcdsaAllValidSizes) {
+TEST_P(NewKeyGenerationTest, EcdsaAllValidSizes) {
size_t valid_sizes[] = {224, 256, 384, 521};
for (size_t size : valid_sizes) {
EXPECT_EQ(ErrorCode::OK,
@@ -1252,7 +1221,7 @@
*
* Verifies that keymaster supports all required EC curves.
*/
-TEST_F(NewKeyGenerationTest, EcdsaAllValidCurves) {
+TEST_P(NewKeyGenerationTest, EcdsaAllValidCurves) {
EcCurve curves[] = {EcCurve::P_224, EcCurve::P_256, EcCurve::P_384, EcCurve::P_521};
for (auto curve : curves) {
EXPECT_EQ(
@@ -1269,7 +1238,7 @@
* Verifies that keymaster supports all required digests, and that the resulting keys have correct
* characteristics.
*/
-TEST_F(NewKeyGenerationTest, Hmac) {
+TEST_P(NewKeyGenerationTest, Hmac) {
for (auto digest : {Digest::MD5, Digest::SHA1, Digest::SHA_2_224, Digest::SHA_2_256,
Digest::SHA_2_384, Digest::SHA_2_512}) {
HidlBuf key_blob;
@@ -1318,7 +1287,7 @@
*
* Verifies that keymaster supports all key sizes, and rejects all invalid key sizes.
*/
-TEST_F(NewKeyGenerationTest, HmacCheckKeySizes) {
+TEST_P(NewKeyGenerationTest, HmacCheckKeySizes) {
for (size_t key_size = 0; key_size <= 512; ++key_size) {
if (key_size < 64 || key_size % 8 != 0) {
// To keep this test from being very slow, we only test a random fraction of non-byte
@@ -1349,7 +1318,7 @@
* test is probabilistic in order to keep the runtime down, but any failure prints out the specific
* MAC length that failed, so reproducing a failed run will be easy.
*/
-TEST_F(NewKeyGenerationTest, HmacCheckMinMacLengths) {
+TEST_P(NewKeyGenerationTest, HmacCheckMinMacLengths) {
for (size_t min_mac_length = 0; min_mac_length <= 256; ++min_mac_length) {
if (min_mac_length < 64 || min_mac_length % 8 != 0) {
// To keep this test from being very long, we only test a random fraction of non-byte
@@ -1379,7 +1348,7 @@
*
* Verifies that keymaster rejects HMAC key generation with multiple specified digest algorithms.
*/
-TEST_F(NewKeyGenerationTest, HmacMultipleDigests) {
+TEST_P(NewKeyGenerationTest, HmacMultipleDigests) {
ASSERT_EQ(ErrorCode::UNSUPPORTED_DIGEST,
GenerateKey(AuthorizationSetBuilder()
.HmacKey(128)
@@ -1393,7 +1362,7 @@
*
* Verifies that keymaster rejects HMAC key generation with no digest or Digest::NONE
*/
-TEST_F(NewKeyGenerationTest, HmacDigestNone) {
+TEST_P(NewKeyGenerationTest, HmacDigestNone) {
ASSERT_EQ(
ErrorCode::UNSUPPORTED_DIGEST,
GenerateKey(AuthorizationSetBuilder().HmacKey(128).Authorization(TAG_MIN_MAC_LENGTH, 128)));
@@ -1413,7 +1382,7 @@
* Verifies that getKeyCharacteristics functions, and that generated and retrieved key
* characteristics match.
*/
-TEST_F(GetKeyCharacteristicsTest, SimpleRsa) {
+TEST_P(GetKeyCharacteristicsTest, SimpleRsa) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.RsaSigningKey(1024, 3)
.Digest(Digest::NONE)
@@ -1438,7 +1407,7 @@
*
* Verifies that raw RSA signature operations succeed.
*/
-TEST_F(SigningOperationsTest, RsaSuccess) {
+TEST_P(SigningOperationsTest, RsaSuccess) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.RsaSigningKey(1024, 3)
.Digest(Digest::NONE)
@@ -1454,7 +1423,7 @@
*
* Verifies that RSA-PSS signature operations succeed.
*/
-TEST_F(SigningOperationsTest, RsaPssSha256Success) {
+TEST_P(SigningOperationsTest, RsaPssSha256Success) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.RsaSigningKey(1024, 3)
.Digest(Digest::SHA_2_256)
@@ -1472,7 +1441,7 @@
* Verifies that keymaster rejects signature operations that specify a padding mode when the key
* supports only unpadded operations.
*/
-TEST_F(SigningOperationsTest, RsaPaddingNoneDoesNotAllowOther) {
+TEST_P(SigningOperationsTest, RsaPaddingNoneDoesNotAllowOther) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.RsaSigningKey(1024, 3)
.Digest(Digest::NONE)
@@ -1492,7 +1461,7 @@
*
* Verifies that digested RSA-PKCS1 signature operations succeed.
*/
-TEST_F(SigningOperationsTest, RsaPkcs1Sha256Success) {
+TEST_P(SigningOperationsTest, RsaPkcs1Sha256Success) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.RsaSigningKey(1024, 3)
.Digest(Digest::SHA_2_256)
@@ -1509,7 +1478,7 @@
*
* Verifies that undigested RSA-PKCS1 signature operations succeed.
*/
-TEST_F(SigningOperationsTest, RsaPkcs1NoDigestSuccess) {
+TEST_P(SigningOperationsTest, RsaPkcs1NoDigestSuccess) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.RsaSigningKey(1024, 3)
.Digest(Digest::NONE)
@@ -1527,7 +1496,7 @@
* Verifies that undigested RSA-PKCS1 signature operations fail with the correct error code when
* given a too-long message.
*/
-TEST_F(SigningOperationsTest, RsaPkcs1NoDigestTooLong) {
+TEST_P(SigningOperationsTest, RsaPkcs1NoDigestTooLong) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.RsaSigningKey(1024, 3)
.Digest(Digest::NONE)
@@ -1555,7 +1524,7 @@
* uses SHA512, which has a digest_size == 512, so the message size is 1040 bits, too large for a
* 1024-bit key.
*/
-TEST_F(SigningOperationsTest, RsaPssSha512TooSmallKey) {
+TEST_P(SigningOperationsTest, RsaPssSha512TooSmallKey) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.RsaSigningKey(1024, 3)
.Digest(Digest::SHA_2_512)
@@ -1574,7 +1543,7 @@
* Verifies that raw RSA signature operations fail with the correct error code when
* given a too-long message.
*/
-TEST_F(SigningOperationsTest, RsaNoPaddingTooLong) {
+TEST_P(SigningOperationsTest, RsaNoPaddingTooLong) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.RsaSigningKey(1024, 3)
.Digest(Digest::NONE)
@@ -1608,7 +1577,7 @@
* Verifies that operations can be aborted correctly. Uses an RSA signing operation for the test,
* but the behavior should be algorithm and purpose-independent.
*/
-TEST_F(SigningOperationsTest, RsaAbort) {
+TEST_P(SigningOperationsTest, RsaAbort) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.RsaSigningKey(1024, 3)
.Digest(Digest::NONE)
@@ -1633,7 +1602,7 @@
* Verifies that RSA operations fail with the correct error (but key gen succeeds) when used with a
* padding mode inappropriate for RSA.
*/
-TEST_F(SigningOperationsTest, RsaUnsupportedPadding) {
+TEST_P(SigningOperationsTest, RsaUnsupportedPadding) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.RsaSigningKey(1024, 3)
.Authorization(TAG_NO_AUTH_REQUIRED)
@@ -1650,7 +1619,7 @@
*
* Verifies that RSA PSS operations fail when no digest is used. PSS requires a digest.
*/
-TEST_F(SigningOperationsTest, RsaNoDigest) {
+TEST_P(SigningOperationsTest, RsaNoDigest) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.RsaSigningKey(1024, 3)
.Authorization(TAG_NO_AUTH_REQUIRED)
@@ -1670,7 +1639,7 @@
* Verifies that RSA operations fail when no padding mode is specified. PaddingMode::NONE is
* supported in some cases (as validated in other tests), but a mode must be specified.
*/
-TEST_F(SigningOperationsTest, RsaNoPadding) {
+TEST_P(SigningOperationsTest, RsaNoPadding) {
// Padding must be specified
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.RsaKey(1024, 3)
@@ -1686,7 +1655,7 @@
*
* Verifies that raw RSA signatures succeed with a message shorter than the key size.
*/
-TEST_F(SigningOperationsTest, RsaTooShortMessage) {
+TEST_P(SigningOperationsTest, RsaTooShortMessage) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.RsaSigningKey(1024, 3)
@@ -1707,7 +1676,7 @@
*
* Verifies that RSA encryption keys cannot be used to sign.
*/
-TEST_F(SigningOperationsTest, RsaSignWithEncryptionKey) {
+TEST_P(SigningOperationsTest, RsaSignWithEncryptionKey) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.RsaEncryptionKey(1024, 3)
@@ -1724,7 +1693,7 @@
* Verifies that attempting a raw signature of a message which is the same length as the key, but
* numerically larger than the public modulus, fails with the correct error.
*/
-TEST_F(SigningOperationsTest, RsaSignTooLargeMessage) {
+TEST_P(SigningOperationsTest, RsaSignTooLargeMessage) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.RsaSigningKey(1024, 3)
@@ -1746,7 +1715,7 @@
*
* Verifies that ECDSA operations succeed with all possible key sizes and hashes.
*/
-TEST_F(SigningOperationsTest, EcdsaAllSizesAndHashes) {
+TEST_P(SigningOperationsTest, EcdsaAllSizesAndHashes) {
for (auto key_size : {224, 256, 384, 521}) {
for (auto digest : {
Digest::SHA1, Digest::SHA_2_224, Digest::SHA_2_256, Digest::SHA_2_384,
@@ -1773,7 +1742,7 @@
*
* Verifies that ECDSA operations succeed with all possible curves.
*/
-TEST_F(SigningOperationsTest, EcdsaAllCurves) {
+TEST_P(SigningOperationsTest, EcdsaAllCurves) {
for (auto curve : {EcCurve::P_224, EcCurve::P_256, EcCurve::P_384, EcCurve::P_521}) {
ErrorCode error = GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
@@ -1795,7 +1764,7 @@
* work because ECDSA actually only signs the leftmost L_n bits of the message, however large it may
* be. Not using digesting is a bad idea, but in some cases digesting is done by the framework.
*/
-TEST_F(SigningOperationsTest, EcdsaNoDigestHugeData) {
+TEST_P(SigningOperationsTest, EcdsaNoDigestHugeData) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.EcdsaSigningKey(224)
@@ -1809,7 +1778,7 @@
*
* Verifies that attempts to use AES keys to sign fail in the correct way.
*/
-TEST_F(SigningOperationsTest, AesEcbSign) {
+TEST_P(SigningOperationsTest, AesEcbSign) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.SigningKey()
@@ -1832,7 +1801,7 @@
*
* Verifies that HMAC works with all digests.
*/
-TEST_F(SigningOperationsTest, HmacAllDigests) {
+TEST_P(SigningOperationsTest, HmacAllDigests) {
for (auto digest : {Digest::SHA1, Digest::SHA_2_224, Digest::SHA_2_256, Digest::SHA_2_384,
Digest::SHA_2_512}) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
@@ -1855,7 +1824,7 @@
* Verifies that HMAC fails in the correct way when asked to generate a MAC larger than the digest
* size.
*/
-TEST_F(SigningOperationsTest, HmacSha256TooLargeMacLength) {
+TEST_P(SigningOperationsTest, HmacSha256TooLargeMacLength) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.HmacKey(128)
@@ -1876,7 +1845,7 @@
* Verifies that HMAC fails in the correct way when asked to generate a MAC smaller than the
* specified minimum MAC length.
*/
-TEST_F(SigningOperationsTest, HmacSha256TooSmallMacLength) {
+TEST_P(SigningOperationsTest, HmacSha256TooSmallMacLength) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.HmacKey(128)
@@ -1896,7 +1865,7 @@
*
* Validates against the test vectors from RFC 4231 test case 3.
*/
-TEST_F(SigningOperationsTest, HmacRfc4231TestCase3) {
+TEST_P(SigningOperationsTest, HmacRfc4231TestCase3) {
string key(20, 0xaa);
string message(50, 0xdd);
uint8_t sha_224_expected[] = {
@@ -1933,7 +1902,7 @@
*
* Validates against the test vectors from RFC 4231 test case 5.
*/
-TEST_F(SigningOperationsTest, HmacRfc4231TestCase5) {
+TEST_P(SigningOperationsTest, HmacRfc4231TestCase5) {
string key(20, 0x0c);
string message = "Test With Truncation";
@@ -1965,7 +1934,7 @@
*
* Validates against the test vectors from RFC 4231 test case 6.
*/
-TEST_F(SigningOperationsTest, HmacRfc4231TestCase6) {
+TEST_P(SigningOperationsTest, HmacRfc4231TestCase6) {
string key(131, 0xaa);
string message = "Test Using Larger Than Block-Size Key - Hash Key First";
@@ -2003,7 +1972,7 @@
*
* Validates against the test vectors from RFC 4231 test case 7.
*/
-TEST_F(SigningOperationsTest, HmacRfc4231TestCase7) {
+TEST_P(SigningOperationsTest, HmacRfc4231TestCase7) {
string key(131, 0xaa);
string message = "This is a test using a larger than block-size key and a larger than "
"block-size data. The key needs to be hashed before being used by the HMAC "
@@ -2045,7 +2014,7 @@
*
* Verifies that a simple RSA signature/verification sequence succeeds.
*/
-TEST_F(VerificationOperationsTest, RsaSuccess) {
+TEST_P(VerificationOperationsTest, RsaSuccess) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.RsaSigningKey(1024, 3)
@@ -2063,7 +2032,7 @@
*
* Verifies RSA signature/verification for all padding modes and digests.
*/
-TEST_F(VerificationOperationsTest, RsaAllPaddingsAndDigests) {
+TEST_P(VerificationOperationsTest, RsaAllPaddingsAndDigests) {
ASSERT_EQ(ErrorCode::OK,
GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
@@ -2159,7 +2128,7 @@
*
* Verifies ECDSA signature/verification for all digests and curves.
*/
-TEST_F(VerificationOperationsTest, EcdsaAllDigestsAndCurves) {
+TEST_P(VerificationOperationsTest, EcdsaAllDigestsAndCurves) {
auto digests = {
Digest::NONE, Digest::SHA1, Digest::SHA_2_224,
Digest::SHA_2_256, Digest::SHA_2_384, Digest::SHA_2_512,
@@ -2242,7 +2211,7 @@
*
* Verifies HMAC signing and verification, but that a signing key cannot be used to verify.
*/
-TEST_F(VerificationOperationsTest, HmacSigningKeyCannotVerify) {
+TEST_P(VerificationOperationsTest, HmacSigningKeyCannotVerify) {
string key_material = "HelloThisIsAKey";
HidlBuf signing_key, verification_key;
@@ -2290,7 +2259,7 @@
*
* Verifies that attempting to export RSA keys in PKCS#8 format fails with the correct error.
*/
-TEST_F(ExportKeyTest, RsaUnsupportedKeyFormat) {
+TEST_P(ExportKeyTest, RsaUnsupportedKeyFormat) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.RsaSigningKey(1024, 3)
.Digest(Digest::NONE)
@@ -2305,7 +2274,7 @@
* Verifies that attempting to export RSA keys from corrupted key blobs fails. This is essentially
* a poor-man's key blob fuzzer.
*/
-TEST_F(ExportKeyTest, RsaCorruptedKeyBlob) {
+TEST_P(ExportKeyTest, RsaCorruptedKeyBlob) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.RsaSigningKey(1024, 3)
@@ -2328,7 +2297,7 @@
* Verifies that attempting to export ECDSA keys from corrupted key blobs fails. This is
* essentially a poor-man's key blob fuzzer.
*/
-TEST_F(ExportKeyTest, EcCorruptedKeyBlob) {
+TEST_P(ExportKeyTest, EcCorruptedKeyBlob) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.EcdsaSigningKey(EcCurve::P_256)
@@ -2349,7 +2318,7 @@
*
* Verifies that attempting to export AES keys fails in the expected way.
*/
-TEST_F(ExportKeyTest, AesKeyUnexportable) {
+TEST_P(ExportKeyTest, AesKeyUnexportable) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.AesEncryptionKey(128)
@@ -2368,7 +2337,7 @@
*
* Verifies that importing and using an RSA key pair works correctly.
*/
-TEST_F(ImportKeyTest, RsaSuccess) {
+TEST_P(ImportKeyTest, RsaSuccess) {
ASSERT_EQ(ErrorCode::OK, ImportKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.RsaSigningKey(1024, 65537)
@@ -2395,7 +2364,7 @@
* Verifies that importing an RSA key pair with a size that doesn't match the key fails in the
* correct way.
*/
-TEST_F(ImportKeyTest, RsaKeySizeMismatch) {
+TEST_P(ImportKeyTest, RsaKeySizeMismatch) {
ASSERT_EQ(ErrorCode::IMPORT_PARAMETER_MISMATCH,
ImportKey(AuthorizationSetBuilder()
.RsaSigningKey(2048 /* Doesn't match key */, 65537)
@@ -2410,7 +2379,7 @@
* Verifies that importing an RSA key pair with a public exponent that doesn't match the key fails
* in the correct way.
*/
-TEST_F(ImportKeyTest, RsaPublicExponentMismatch) {
+TEST_P(ImportKeyTest, RsaPublicExponentMismatch) {
ASSERT_EQ(ErrorCode::IMPORT_PARAMETER_MISMATCH,
ImportKey(AuthorizationSetBuilder()
.RsaSigningKey(1024, 3 /* Doesn't match key */)
@@ -2424,7 +2393,7 @@
*
* Verifies that importing and using an ECDSA P-256 key pair works correctly.
*/
-TEST_F(ImportKeyTest, EcdsaSuccess) {
+TEST_P(ImportKeyTest, EcdsaSuccess) {
ASSERT_EQ(ErrorCode::OK, ImportKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.EcdsaSigningKey(256)
@@ -2450,7 +2419,7 @@
*
* Verifies that importing and using an ECDSA P-521 key pair works correctly.
*/
-TEST_F(ImportKeyTest, Ecdsa521Success) {
+TEST_P(ImportKeyTest, Ecdsa521Success) {
ASSERT_EQ(ErrorCode::OK, ImportKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.EcdsaSigningKey(521)
@@ -2477,7 +2446,7 @@
* Verifies that importing an ECDSA key pair with a size that doesn't match the key fails in the
* correct way.
*/
-TEST_F(ImportKeyTest, EcdsaSizeMismatch) {
+TEST_P(ImportKeyTest, EcdsaSizeMismatch) {
ASSERT_EQ(ErrorCode::IMPORT_PARAMETER_MISMATCH,
ImportKey(AuthorizationSetBuilder()
.EcdsaSigningKey(224 /* Doesn't match key */)
@@ -2491,7 +2460,7 @@
* Verifies that importing an ECDSA key pair with a curve that doesn't match the key fails in the
* correct way.
*/
-TEST_F(ImportKeyTest, EcdsaCurveMismatch) {
+TEST_P(ImportKeyTest, EcdsaCurveMismatch) {
if (SupportsSymmetric() && !SupportsAttestation()) {
// KM1 hardware doesn't know about curves
return;
@@ -2510,7 +2479,7 @@
*
* Verifies that importing and using an AES key works.
*/
-TEST_F(ImportKeyTest, AesSuccess) {
+TEST_P(ImportKeyTest, AesSuccess) {
string key = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
ASSERT_EQ(ErrorCode::OK, ImportKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
@@ -2537,7 +2506,7 @@
*
* Verifies that importing and using an HMAC key works.
*/
-TEST_F(ImportKeyTest, HmacKeySuccess) {
+TEST_P(ImportKeyTest, HmacKeySuccess) {
string key = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
ASSERT_EQ(ErrorCode::OK, ImportKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
@@ -2563,7 +2532,7 @@
*
* Verifies that raw RSA encryption works.
*/
-TEST_F(EncryptionOperationsTest, RsaNoPaddingSuccess) {
+TEST_P(EncryptionOperationsTest, RsaNoPaddingSuccess) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.RsaEncryptionKey(1024, 3)
@@ -2586,7 +2555,7 @@
*
* Verifies that raw RSA encryption of short messages works.
*/
-TEST_F(EncryptionOperationsTest, RsaNoPaddingShortMessage) {
+TEST_P(EncryptionOperationsTest, RsaNoPaddingShortMessage) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.RsaEncryptionKey(1024, 3)
@@ -2615,7 +2584,7 @@
*
* Verifies that raw RSA encryption of too-long messages fails in the expected way.
*/
-TEST_F(EncryptionOperationsTest, RsaNoPaddingTooLong) {
+TEST_P(EncryptionOperationsTest, RsaNoPaddingTooLong) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.RsaEncryptionKey(1024, 3)
@@ -2635,7 +2604,7 @@
*
* Verifies that raw RSA encryption of too-large (numerically) messages fails in the expected way.
*/
-TEST_F(EncryptionOperationsTest, RsaNoPaddingTooLarge) {
+TEST_P(EncryptionOperationsTest, RsaNoPaddingTooLarge) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.RsaEncryptionKey(1024, 3)
@@ -2677,7 +2646,7 @@
*
* Verifies that RSA-OAEP encryption operations work, with all digests.
*/
-TEST_F(EncryptionOperationsTest, RsaOaepSuccess) {
+TEST_P(EncryptionOperationsTest, RsaOaepSuccess) {
auto digests = {Digest::MD5, Digest::SHA1, Digest::SHA_2_224,
Digest::SHA_2_256, Digest::SHA_2_384, Digest::SHA_2_512};
@@ -2729,7 +2698,7 @@
* Verifies that RSA-OAEP encryption operations fail in the correct way when asked to operate
* without a digest.
*/
-TEST_F(EncryptionOperationsTest, RsaOaepInvalidDigest) {
+TEST_P(EncryptionOperationsTest, RsaOaepInvalidDigest) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.RsaEncryptionKey(1024, 3)
@@ -2747,7 +2716,7 @@
* Verifies that RSA-OAEP encryption operations fail in the correct way when asked to decrypt with a
* different digest than was used to encrypt.
*/
-TEST_F(EncryptionOperationsTest, RsaOaepDecryptWithWrongDigest) {
+TEST_P(EncryptionOperationsTest, RsaOaepDecryptWithWrongDigest) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.RsaEncryptionKey(1024, 3)
@@ -2773,7 +2742,7 @@
* Verifies that RSA-OAEP encryption operations fail in the correct way when asked to encrypt a
* too-large message.
*/
-TEST_F(EncryptionOperationsTest, RsaOaepTooLarge) {
+TEST_P(EncryptionOperationsTest, RsaOaepTooLarge) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.RsaEncryptionKey(1024, 3)
@@ -2796,7 +2765,7 @@
*
* Verifies that RSA PKCS encryption/decrypts works.
*/
-TEST_F(EncryptionOperationsTest, RsaPkcs1Success) {
+TEST_P(EncryptionOperationsTest, RsaPkcs1Success) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.RsaEncryptionKey(1024, 3)
@@ -2835,7 +2804,7 @@
*
* Verifies that RSA PKCS encryption fails in the correct way when the mssage is too large.
*/
-TEST_F(EncryptionOperationsTest, RsaPkcs1TooLarge) {
+TEST_P(EncryptionOperationsTest, RsaPkcs1TooLarge) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.RsaEncryptionKey(1024, 3)
@@ -2855,7 +2824,7 @@
*
* Verifies that attempting to use ECDSA keys to encrypt fails in the correct way.
*/
-TEST_F(EncryptionOperationsTest, EcdsaEncrypt) {
+TEST_P(EncryptionOperationsTest, EcdsaEncrypt) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.EcdsaSigningKey(224)
@@ -2872,7 +2841,7 @@
*
* Verifies that attempting to use HMAC keys to encrypt fails in the correct way.
*/
-TEST_F(EncryptionOperationsTest, HmacEncrypt) {
+TEST_P(EncryptionOperationsTest, HmacEncrypt) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.HmacKey(128)
@@ -2894,7 +2863,7 @@
*
* Verifies that AES ECB mode works.
*/
-TEST_F(EncryptionOperationsTest, AesEcbRoundTripSuccess) {
+TEST_P(EncryptionOperationsTest, AesEcbRoundTripSuccess) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.AesEncryptionKey(128)
@@ -2923,7 +2892,7 @@
*
* Verifies that AES encryption fails in the correct way when an unauthorized mode is specified.
*/
-TEST_F(EncryptionOperationsTest, AesWrongMode) {
+TEST_P(EncryptionOperationsTest, AesWrongMode) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.AesEncryptionKey(128)
@@ -2943,7 +2912,7 @@
* Verifies that AES encryption fails in the correct way when provided an input that is not a
* multiple of the block size and no padding is specified.
*/
-TEST_F(EncryptionOperationsTest, AesEcbNoPaddingWrongInputSize) {
+TEST_P(EncryptionOperationsTest, AesEcbNoPaddingWrongInputSize) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.AesEncryptionKey(128)
@@ -2964,7 +2933,7 @@
*
* Verifies that AES PKCS7 padding works for any message length.
*/
-TEST_F(EncryptionOperationsTest, AesEcbPkcs7Padding) {
+TEST_P(EncryptionOperationsTest, AesEcbPkcs7Padding) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.AesEncryptionKey(128)
@@ -2989,7 +2958,7 @@
* Verifies that AES enryption fails in the correct way when an unauthorized padding mode is
* specified.
*/
-TEST_F(EncryptionOperationsTest, AesEcbWrongPadding) {
+TEST_P(EncryptionOperationsTest, AesEcbWrongPadding) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.AesEncryptionKey(128)
@@ -3010,7 +2979,7 @@
*
* Verifies that AES decryption fails in the correct way when the padding is corrupted.
*/
-TEST_F(EncryptionOperationsTest, AesEcbPkcs7PaddingCorrupted) {
+TEST_P(EncryptionOperationsTest, AesEcbPkcs7PaddingCorrupted) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.AesEncryptionKey(128)
@@ -3041,7 +3010,7 @@
*
* Verifies that AES CTR mode works.
*/
-TEST_F(EncryptionOperationsTest, AesCtrRoundTripSuccess) {
+TEST_P(EncryptionOperationsTest, AesCtrRoundTripSuccess) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.AesEncryptionKey(128)
@@ -3088,7 +3057,7 @@
*
* Verifies that AES works, all modes, when provided data in various size increments.
*/
-TEST_F(EncryptionOperationsTest, AesIncremental) {
+TEST_P(EncryptionOperationsTest, AesIncremental) {
auto block_modes = {
BlockMode::ECB, BlockMode::CBC, BlockMode::CTR, BlockMode::GCM,
};
@@ -3226,7 +3195,7 @@
*
* Verifies AES CTR implementation against SP800-38A test vectors.
*/
-TEST_F(EncryptionOperationsTest, AesCtrSp80038aTestVector) {
+TEST_P(EncryptionOperationsTest, AesCtrSp80038aTestVector) {
for (size_t i = 0; i < 3; i++) {
const AesCtrSp80038aTestVector& test(kAesCtrSp80038aTestVectors[i]);
const string key = hex2str(test.key);
@@ -3242,7 +3211,7 @@
*
* Verifies that keymaster rejects use of CTR mode with PKCS7 padding in the correct way.
*/
-TEST_F(EncryptionOperationsTest, AesCtrIncompatiblePaddingMode) {
+TEST_P(EncryptionOperationsTest, AesCtrIncompatiblePaddingMode) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.AesEncryptionKey(128)
@@ -3257,7 +3226,7 @@
*
* Verifies that keymaster fails correctly when the user supplies an incorrect-size nonce.
*/
-TEST_F(EncryptionOperationsTest, AesCtrInvalidCallerNonce) {
+TEST_P(EncryptionOperationsTest, AesCtrInvalidCallerNonce) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.AesEncryptionKey(128)
@@ -3289,7 +3258,7 @@
*
* Verifies that keymaster fails correctly when the user supplies an incorrect-size nonce.
*/
-TEST_F(EncryptionOperationsTest, AesCbcRoundTripSuccess) {
+TEST_P(EncryptionOperationsTest, AesCbcRoundTripSuccess) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.AesEncryptionKey(128)
@@ -3322,7 +3291,7 @@
*
* Verifies that AES caller-provided nonces work correctly.
*/
-TEST_F(EncryptionOperationsTest, AesCallerNonce) {
+TEST_P(EncryptionOperationsTest, AesCallerNonce) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.AesEncryptionKey(128)
@@ -3371,7 +3340,7 @@
* Verifies that caller-provided nonces are not permitted when not specified in the key
* authorizations.
*/
-TEST_F(EncryptionOperationsTest, AesCallerNonceProhibited) {
+TEST_P(EncryptionOperationsTest, AesCallerNonceProhibited) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.AesEncryptionKey(128)
@@ -3406,7 +3375,7 @@
*
* Verifies that AES GCM mode works.
*/
-TEST_F(EncryptionOperationsTest, AesGcmRoundTripSuccess) {
+TEST_P(EncryptionOperationsTest, AesGcmRoundTripSuccess) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.AesEncryptionKey(128)
@@ -3454,7 +3423,7 @@
*
* Verifies that AES GCM mode fails correctly when a too-short tag length is specified.
*/
-TEST_F(EncryptionOperationsTest, AesGcmTooShortTag) {
+TEST_P(EncryptionOperationsTest, AesGcmTooShortTag) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.AesEncryptionKey(128)
@@ -3475,7 +3444,7 @@
*
* Verifies that AES GCM mode fails correctly when a too-short tag is provided to decryption.
*/
-TEST_F(EncryptionOperationsTest, AesGcmTooShortTagOnDecrypt) {
+TEST_P(EncryptionOperationsTest, AesGcmTooShortTagOnDecrypt) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.AesEncryptionKey(128)
@@ -3518,7 +3487,7 @@
*
* Verifies that AES GCM mode fails correctly when the decryption key is incorrect.
*/
-TEST_F(EncryptionOperationsTest, AesGcmCorruptKey) {
+TEST_P(EncryptionOperationsTest, AesGcmCorruptKey) {
const uint8_t nonce_bytes[] = {
0xb7, 0x94, 0x37, 0xae, 0x08, 0xff, 0x35, 0x5d, 0x7d, 0x8a, 0x4d, 0x0f,
};
@@ -3570,7 +3539,7 @@
* Verifies that AES GCM mode works when provided additional authenticated data, but no data to
* encrypt.
*/
-TEST_F(EncryptionOperationsTest, AesGcmAadNoData) {
+TEST_P(EncryptionOperationsTest, AesGcmAadNoData) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.AesEncryptionKey(128)
@@ -3616,7 +3585,7 @@
*
* Verifies that AES GCM mode works when provided additional authenticated data in multiple chunks.
*/
-TEST_F(EncryptionOperationsTest, AesGcmMultiPartAad) {
+TEST_P(EncryptionOperationsTest, AesGcmMultiPartAad) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.AesEncryptionKey(128)
@@ -3675,7 +3644,7 @@
*
* Verifies that AES GCM mode fails correctly when given AAD after data to encipher.
*/
-TEST_F(EncryptionOperationsTest, AesGcmAadOutOfOrder) {
+TEST_P(EncryptionOperationsTest, AesGcmAadOutOfOrder) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.AesEncryptionKey(128)
@@ -3724,7 +3693,7 @@
*
* Verifies that AES GCM decryption fails correctly when additional authenticated date is wrong.
*/
-TEST_F(EncryptionOperationsTest, AesGcmBadAad) {
+TEST_P(EncryptionOperationsTest, AesGcmBadAad) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.AesEncryptionKey(128)
@@ -3768,7 +3737,7 @@
*
* Verifies that AES GCM decryption fails correctly when the nonce is incorrect.
*/
-TEST_F(EncryptionOperationsTest, AesGcmWrongNonce) {
+TEST_P(EncryptionOperationsTest, AesGcmWrongNonce) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.AesEncryptionKey(128)
@@ -3812,7 +3781,7 @@
*
* Verifies that AES GCM decryption fails correctly when the tag is wrong.
*/
-TEST_F(EncryptionOperationsTest, AesGcmCorruptTag) {
+TEST_P(EncryptionOperationsTest, AesGcmCorruptTag) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.AesEncryptionKey(128)
@@ -3862,7 +3831,7 @@
*
* Verifies that the max uses per boot tag works correctly with AES keys.
*/
-TEST_F(MaxOperationsTest, TestLimitAes) {
+TEST_P(MaxOperationsTest, TestLimitAes) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.AesEncryptionKey(128)
@@ -3887,7 +3856,7 @@
*
* Verifies that the max uses per boot tag works correctly with RSA keys.
*/
-TEST_F(MaxOperationsTest, TestLimitRsa) {
+TEST_P(MaxOperationsTest, TestLimitRsa) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.RsaSigningKey(1024, 3)
@@ -3914,7 +3883,7 @@
* Verifies that the addRngEntropy method doesn't blow up. There's no way to test that entropy is
* actually added.
*/
-TEST_F(AddEntropyTest, AddEntropy) {
+TEST_P(AddEntropyTest, AddEntropy) {
EXPECT_EQ(ErrorCode::OK, keymaster().addRngEntropy(HidlBuf("foo")));
}
@@ -3923,7 +3892,7 @@
*
* Verifies that the addRngEntropy method doesn't blow up when given an empty buffer.
*/
-TEST_F(AddEntropyTest, AddEmptyEntropy) {
+TEST_P(AddEntropyTest, AddEmptyEntropy) {
EXPECT_EQ(ErrorCode::OK, keymaster().addRngEntropy(HidlBuf()));
}
@@ -3932,7 +3901,7 @@
*
* Verifies that the addRngEntropy method doesn't blow up when given a largish amount of data.
*/
-TEST_F(AddEntropyTest, AddLargeEntropy) {
+TEST_P(AddEntropyTest, AddLargeEntropy) {
EXPECT_EQ(ErrorCode::OK, keymaster().addRngEntropy(HidlBuf(string(2 * 1024, 'a'))));
}
@@ -3943,7 +3912,7 @@
*
* Verifies that attesting to RSA keys works and generates the expected output.
*/
-TEST_F(AttestationTest, RsaAttestation) {
+TEST_P(AttestationTest, RsaAttestation) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.RsaSigningKey(1024, 3)
@@ -3971,7 +3940,7 @@
*
* Verifies that attesting to RSA requires app ID.
*/
-TEST_F(AttestationTest, RsaAttestationRequiresAppId) {
+TEST_P(AttestationTest, RsaAttestationRequiresAppId) {
ASSERT_EQ(ErrorCode::OK,
GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
@@ -3992,7 +3961,7 @@
*
* Verifies that attesting to EC keys works and generates the expected output.
*/
-TEST_F(AttestationTest, EcAttestation) {
+TEST_P(AttestationTest, EcAttestation) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.EcdsaSigningKey(EcCurve::P_256)
@@ -4020,7 +3989,7 @@
*
* Verifies that attesting to EC keys requires app ID
*/
-TEST_F(AttestationTest, EcAttestationRequiresAttestationAppId) {
+TEST_P(AttestationTest, EcAttestationRequiresAttestationAppId) {
ASSERT_EQ(ErrorCode::OK,
GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
@@ -4040,7 +4009,7 @@
*
* Verifies that attesting to AES keys fails in the expected way.
*/
-TEST_F(AttestationTest, AesAttestation) {
+TEST_P(AttestationTest, AesAttestation) {
ASSERT_EQ(ErrorCode::OK,
GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
@@ -4063,7 +4032,7 @@
*
* Verifies that attesting to HMAC keys fails in the expected way.
*/
-TEST_F(AttestationTest, HmacAttestation) {
+TEST_P(AttestationTest, HmacAttestation) {
ASSERT_EQ(ErrorCode::OK,
GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
@@ -4090,7 +4059,7 @@
* This test checks that if rollback protection is implemented, DeleteKey invalidates a formerly
* valid key blob.
*/
-TEST_F(KeyDeletionTest, DeleteKey) {
+TEST_P(KeyDeletionTest, DeleteKey) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.RsaSigningKey(1024, 3)
.Digest(Digest::NONE)
@@ -4135,7 +4104,7 @@
*
* This test checks that the HAL excepts invalid key blobs.
*/
-TEST_F(KeyDeletionTest, DeleteInvalidKey) {
+TEST_P(KeyDeletionTest, DeleteInvalidKey) {
// Generate key just to check if rollback protection is implemented
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.RsaSigningKey(1024, 3)
@@ -4172,7 +4141,7 @@
* been provisioned. Use this test only on dedicated testing devices that have no valuable
* credentials stored in Keystore/Keymaster.
*/
-TEST_F(KeyDeletionTest, DeleteAllKeys) {
+TEST_P(KeyDeletionTest, DeleteAllKeys) {
if (!arm_deleteAllKeys) return;
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.RsaSigningKey(1024, 3)
@@ -4207,6 +4176,45 @@
key_blob_ = HidlBuf();
}
+static const auto kKeymasterDeviceChoices =
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(IKeymasterDevice::descriptor));
+
+INSTANTIATE_TEST_SUITE_P(PerInstance, NewKeyGenerationTest, kKeymasterDeviceChoices,
+ android::hardware::PrintInstanceNameToString);
+
+INSTANTIATE_TEST_SUITE_P(PerInstance, KeymasterVersionTest, kKeymasterDeviceChoices,
+ android::hardware::PrintInstanceNameToString);
+
+INSTANTIATE_TEST_SUITE_P(PerInstance, GetKeyCharacteristicsTest, kKeymasterDeviceChoices,
+ android::hardware::PrintInstanceNameToString);
+
+INSTANTIATE_TEST_SUITE_P(PerInstance, SigningOperationsTest, kKeymasterDeviceChoices,
+ android::hardware::PrintInstanceNameToString);
+
+INSTANTIATE_TEST_SUITE_P(PerInstance, VerificationOperationsTest, kKeymasterDeviceChoices,
+ android::hardware::PrintInstanceNameToString);
+
+INSTANTIATE_TEST_SUITE_P(PerInstance, ExportKeyTest, kKeymasterDeviceChoices,
+ android::hardware::PrintInstanceNameToString);
+
+INSTANTIATE_TEST_SUITE_P(PerInstance, ImportKeyTest, kKeymasterDeviceChoices,
+ android::hardware::PrintInstanceNameToString);
+
+INSTANTIATE_TEST_SUITE_P(PerInstance, EncryptionOperationsTest, kKeymasterDeviceChoices,
+ android::hardware::PrintInstanceNameToString);
+
+INSTANTIATE_TEST_SUITE_P(PerInstance, MaxOperationsTest, kKeymasterDeviceChoices,
+ android::hardware::PrintInstanceNameToString);
+
+INSTANTIATE_TEST_SUITE_P(PerInstance, AddEntropyTest, kKeymasterDeviceChoices,
+ android::hardware::PrintInstanceNameToString);
+
+INSTANTIATE_TEST_SUITE_P(PerInstance, AttestationTest, kKeymasterDeviceChoices,
+ android::hardware::PrintInstanceNameToString);
+
+INSTANTIATE_TEST_SUITE_P(PerInstance, KeyDeletionTest, kKeymasterDeviceChoices,
+ android::hardware::PrintInstanceNameToString);
+
} // namespace test
} // namespace V3_0
} // namespace keymaster
@@ -4214,10 +4222,7 @@
} // namespace android
int main(int argc, char** argv) {
- using android::hardware::keymaster::V3_0::test::KeymasterHidlEnvironment;
- ::testing::AddGlobalTestEnvironment(KeymasterHidlEnvironment::Instance());
::testing::InitGoogleTest(&argc, argv);
- KeymasterHidlEnvironment::Instance()->init(&argc, argv);
for (int i = 1; i < argc; ++i) {
if (argv[i][0] == '-') {
if (std::string(argv[i]) == "--arm_deleteAllKeys") {
diff --git a/keymaster/4.0/vts/functional/Android.bp b/keymaster/4.0/vts/functional/Android.bp
index 0401362..5649f20 100644
--- a/keymaster/4.0/vts/functional/Android.bp
+++ b/keymaster/4.0/vts/functional/Android.bp
@@ -29,5 +29,5 @@
"libkeymaster4support",
"libsoftkeymasterdevice",
],
- test_suites: ["general-tests"],
+ test_suites: ["general-tests", "vts-core"],
}
diff --git a/keymaster/4.0/vts/functional/AndroidTest.xml b/keymaster/4.0/vts/functional/AndroidTest.xml
new file mode 100644
index 0000000..dcf7129
--- /dev/null
+++ b/keymaster/4.0/vts/functional/AndroidTest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 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.
+-->
+<configuration description="Runs VtsHalKeymasterV4_0TargetTest.">
+ <option name="test-suite-tag" value="apct" />
+ <option name="test-suite-tag" value="apct-native" />
+
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
+ </target_preparer>
+
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="cleanup" value="true" />
+ <option name="push" value="VtsHalKeymasterV4_0TargetTest->/data/local/tmp/VtsHalKeymasterV4_0TargetTest" />
+ </target_preparer>
+
+ <test class="com.android.tradefed.testtype.GTest" >
+ <option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="module-name" value="VtsHalKeymasterV4_0TargetTest" />
+ <option name="native-test-timeout" value="900000"/>
+ </test>
+</configuration>
diff --git a/keymaster/4.0/vts/functional/HmacKeySharingTest.cpp b/keymaster/4.0/vts/functional/HmacKeySharingTest.cpp
index f159796..c228ef7 100644
--- a/keymaster/4.0/vts/functional/HmacKeySharingTest.cpp
+++ b/keymaster/4.0/vts/functional/HmacKeySharingTest.cpp
@@ -101,7 +101,7 @@
}
};
-TEST_F(HmacKeySharingTest, GetParameters) {
+TEST_P(HmacKeySharingTest, GetParameters) {
auto result1 = getHmacSharingParameters(keymaster());
EXPECT_EQ(ErrorCode::OK, result1.error);
@@ -114,7 +114,7 @@
<< "A given keymaster should always return the same nonce until restart.";
}
-TEST_F(HmacKeySharingTest, ComputeSharedHmac) {
+TEST_P(HmacKeySharingTest, ComputeSharedHmac) {
auto params = getHmacSharingParameters(all_keymasters());
ASSERT_EQ(all_keymasters().size(), params.size())
<< "One or more keymasters failed to provide parameters.";
@@ -143,8 +143,8 @@
template <class F>
class final_action {
public:
- explicit final_action(F f) : f_(move(f)) {}
- ~final_action() { f_(); }
+ explicit final_action(F f) : f_(std::move(f)) {}
+ ~final_action() { f_(); }
private:
F f_;
@@ -155,7 +155,7 @@
return final_action<F>(f);
}
-TEST_F(HmacKeySharingTest, ComputeSharedHmacCorruptNonce) {
+TEST_P(HmacKeySharingTest, ComputeSharedHmacCorruptNonce) {
// Important: The execution of this test gets the keymaster implementations on the device out of
// sync with respect to the HMAC key. Granted that VTS tests aren't run on in-use production
// devices, this still has the potential to cause confusion. To mitigate that, we always
@@ -194,7 +194,7 @@
}
}
-TEST_F(HmacKeySharingTest, ComputeSharedHmacCorruptSeed) {
+TEST_P(HmacKeySharingTest, ComputeSharedHmacCorruptSeed) {
// Important: The execution of this test gets the keymaster implementations on the device out of
// sync with respect to the HMAC key. Granted that VTS tests aren't run on in-use production
// devices, this still has the potential to cause confusion. To mitigate that, we always
@@ -236,6 +236,11 @@
}
}
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, HmacKeySharingTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(IKeymasterDevice::descriptor)),
+ android::hardware::PrintInstanceNameToString);
+
} // namespace test
} // namespace V4_0
} // namespace keymaster
diff --git a/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp b/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp
index 4838e7e..07409f6 100644
--- a/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp
+++ b/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp
@@ -41,18 +41,9 @@
namespace test {
-sp<IKeymasterDevice> KeymasterHidlTest::keymaster_;
-std::vector<sp<IKeymasterDevice>> KeymasterHidlTest::all_keymasters_;
-uint32_t KeymasterHidlTest::os_version_;
-uint32_t KeymasterHidlTest::os_patch_level_;
-SecurityLevel KeymasterHidlTest::securityLevel_;
-hidl_string KeymasterHidlTest::name_;
-hidl_string KeymasterHidlTest::author_;
-string KeymasterHidlTest::service_name_;
-
void KeymasterHidlTest::InitializeKeymaster() {
- service_name_ = KeymasterHidlEnvironment::Instance()->getServiceName<IKeymasterDevice>();
- keymaster_ = ::testing::VtsHalHidlTargetTestBase::getService<IKeymasterDevice>(service_name_);
+ service_name_ = GetParam();
+ keymaster_ = IKeymasterDevice::getService(service_name_);
ASSERT_NE(keymaster_, nullptr);
ASSERT_TRUE(keymaster_
@@ -65,8 +56,7 @@
.isOk());
}
-void KeymasterHidlTest::SetUpTestCase() {
-
+void KeymasterHidlTest::SetUp() {
InitializeKeymaster();
os_version_ = ::keymaster::GetOsVersion();
@@ -79,8 +69,7 @@
IKeymasterDevice::descriptor, [&](const hidl_vec<hidl_string>& names) {
for (auto& name : names) {
if (name == service_name_) continue;
- auto keymaster =
- ::testing::VtsHalHidlTargetTestBase::getService<IKeymasterDevice>(name);
+ auto keymaster = IKeymasterDevice::getService(name);
ASSERT_NE(keymaster, nullptr);
all_keymasters_.push_back(keymaster);
}
@@ -222,8 +211,8 @@
std::chrono::time_point<std::chrono::system_clock> reported_time{
std::chrono::milliseconds(sw_enforced[i].f.dateTime)};
// The test is flaky for EC keys, so a buffer time of 120 seconds will be added.
- EXPECT_LE(creation - 120s, reported_time);
- EXPECT_LE(reported_time, now + 1s);
+ EXPECT_LE(creation - std::chrono::seconds(120), reported_time);
+ EXPECT_LE(reported_time, now + std::chrono::seconds(1));
}
}
}
diff --git a/keymaster/4.0/vts/functional/KeymasterHidlTest.h b/keymaster/4.0/vts/functional/KeymasterHidlTest.h
index b09da45..adceead 100644
--- a/keymaster/4.0/vts/functional/KeymasterHidlTest.h
+++ b/keymaster/4.0/vts/functional/KeymasterHidlTest.h
@@ -14,14 +14,13 @@
* limitations under the License.
*/
-#ifndef HARDWARE_INTERFACES_KEYMASTER_40_VTS_FUNCTIONAL_KEYMASTER_HIDL_TEST_H_
-#define HARDWARE_INTERFACES_KEYMASTER_40_VTS_FUNCTIONAL_KEYMASTER_HIDL_TEST_H_
+#pragma once
#include <android/hardware/keymaster/4.0/IKeymasterDevice.h>
#include <android/hardware/keymaster/4.0/types.h>
-
-#include <VtsHalHidlTargetTestBase.h>
-
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include <keymaster/keymaster_configuration.h>
#include <keymasterV4_0/authorization_set.h>
@@ -69,43 +68,24 @@
constexpr uint64_t kOpHandleSentinel = 0xFFFFFFFFFFFFFFFF;
-class KeymasterHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static KeymasterHidlEnvironment* Instance() {
- static KeymasterHidlEnvironment* instance = new KeymasterHidlEnvironment;
- return instance;
- }
-
- void registerTestServices() override { registerTestService<IKeymasterDevice>(); }
-
- private:
- KeymasterHidlEnvironment(){};
-
- GTEST_DISALLOW_COPY_AND_ASSIGN_(KeymasterHidlEnvironment);
-};
-
-class KeymasterHidlTest : public ::testing::VtsHalHidlTargetTestBase {
- public:
+class KeymasterHidlTest : public ::testing::TestWithParam<std::string> {
+ public:
+ void SetUp();
void TearDown() override {
if (key_blob_.size()) {
CheckedDeleteKey();
}
AbortIfNeeded();
- }
-
- // SetUpTestCase runs only once per test case, not once per test.
- static void SetUpTestCase();
- static void InitializeKeymaster();
- static void TearDownTestCase() {
keymaster_.clear();
all_keymasters_.clear();
}
- static IKeymasterDevice& keymaster() { return *keymaster_; }
- static const std::vector<sp<IKeymasterDevice>>& all_keymasters() { return all_keymasters_; }
- static uint32_t os_version() { return os_version_; }
- static uint32_t os_patch_level() { return os_patch_level_; }
+ void InitializeKeymaster();
+
+ IKeymasterDevice& keymaster() { return *keymaster_; }
+ const std::vector<sp<IKeymasterDevice>>& all_keymasters() { return all_keymasters_; }
+ uint32_t os_version() { return os_version_; }
+ uint32_t os_patch_level() { return os_patch_level_; }
ErrorCode GenerateKey(const AuthorizationSet& key_desc, HidlBuf* key_blob,
KeyCharacteristics* key_characteristics);
@@ -216,8 +196,8 @@
std::pair<ErrorCode, HidlBuf> UpgradeKey(const HidlBuf& key_blob);
- static bool IsSecure() { return securityLevel_ != SecurityLevel::SOFTWARE; }
- static SecurityLevel SecLevel() { return securityLevel_; }
+ bool IsSecure() { return securityLevel_ != SecurityLevel::SOFTWARE; }
+ SecurityLevel SecLevel() { return securityLevel_; }
std::vector<uint32_t> ValidKeySizes(Algorithm algorithm);
std::vector<uint32_t> InvalidKeySizes(Algorithm algorithm);
@@ -233,15 +213,15 @@
OperationHandle op_handle_ = kOpHandleSentinel;
private:
- static sp<IKeymasterDevice> keymaster_;
- static std::vector<sp<IKeymasterDevice>> all_keymasters_;
- static uint32_t os_version_;
- static uint32_t os_patch_level_;
+ sp<IKeymasterDevice> keymaster_;
+ std::vector<sp<IKeymasterDevice>> all_keymasters_;
+ uint32_t os_version_;
+ uint32_t os_patch_level_;
- static SecurityLevel securityLevel_;
- static hidl_string name_;
- static hidl_string author_;
- static string service_name_;
+ SecurityLevel securityLevel_;
+ hidl_string name_;
+ hidl_string author_;
+ string service_name_;
};
} // namespace test
@@ -249,5 +229,3 @@
} // namespace keymaster
} // namespace hardware
} // namespace android
-
-#endif // HARDWARE_INTERFACES_KEYMASTER_40_VTS_FUNCTIONAL_KEYMASTER_HIDL_TEST_H_
diff --git a/keymaster/4.0/vts/functional/VerificationTokenTest.cpp b/keymaster/4.0/vts/functional/VerificationTokenTest.cpp
index de28683..693f4ae 100644
--- a/keymaster/4.0/vts/functional/VerificationTokenTest.cpp
+++ b/keymaster/4.0/vts/functional/VerificationTokenTest.cpp
@@ -75,7 +75,7 @@
* thing we really can test is that tokens can be created by TEE keymasters, and that the
* timestamps increase as expected.
*/
-TEST_F(VerificationTokenTest, TestCreation) {
+TEST_P(VerificationTokenTest, TestCreation) {
auto result1 = verifyAuthorization(
1 /* operation handle */, AuthorizationSet() /* paramtersToVerify */, HardwareAuthToken());
ASSERT_TRUE(result1.callSuccessful);
@@ -134,7 +134,7 @@
* stamp is included in the mac but on failure we know that it is not. Other than in the test
* case above we call verifyAuthorization with the exact same set of parameters.
*/
-TEST_F(VerificationTokenTest, MacChangesOnChangingTimestamp) {
+TEST_P(VerificationTokenTest, MacChangesOnChangingTimestamp) {
auto result1 =
verifyAuthorization(0 /* operation handle */,
AuthorizationSet() /* paramtersToVerify */, HardwareAuthToken());
@@ -185,6 +185,11 @@
memcmp(result1.token.mac.data(), result2.token.mac.data(), result1.token.mac.size()));
}
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, VerificationTokenTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(IKeymasterDevice::descriptor)),
+ android::hardware::PrintInstanceNameToString);
+
} // namespace test
} // namespace V4_0
} // namespace keymaster
diff --git a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
index 0e12283..f78eb43 100644
--- a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
+++ b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
@@ -423,27 +423,33 @@
EXPECT_EQ(ErrorCode::OK, error);
if (avb_verification_enabled()) {
- property_get("ro.boot.vbmeta.digest", property_value, "nogood");
- EXPECT_NE(strcmp(property_value, "nogood"), 0);
+ EXPECT_NE(property_get("ro.boot.vbmeta.digest", property_value, ""), 0);
string prop_string(property_value);
EXPECT_EQ(prop_string.size(), 64);
EXPECT_EQ(prop_string, bin2hex(verified_boot_hash));
- property_get("ro.boot.vbmeta.device_state", property_value, "nogood");
- EXPECT_NE(strcmp(property_value, "nogood"), 0);
+ EXPECT_NE(property_get("ro.boot.vbmeta.device_state", property_value, ""), 0);
if (!strcmp(property_value, "unlocked")) {
EXPECT_FALSE(device_locked);
} else {
EXPECT_TRUE(device_locked);
}
+
+ // Check that the expected result from VBMeta matches the build type. Only a user build
+ // should have AVB reporting the device is locked.
+ EXPECT_NE(property_get("ro.build.type", property_value, ""), 0);
+ if (!strcmp(property_value, "user")) {
+ EXPECT_TRUE(device_locked);
+ } else {
+ EXPECT_FALSE(device_locked);
+ }
}
// Verified boot key should be all 0's if the boot state is not verified or self signed
std::string empty_boot_key(32, '\0');
std::string verified_boot_key_str((const char*)verified_boot_key.data(),
verified_boot_key.size());
- property_get("ro.boot.verifiedbootstate", property_value, "nogood");
- EXPECT_NE(property_value, "nogood");
+ EXPECT_NE(property_get("ro.boot.verifiedbootstate", property_value, ""), 0);
if (!strcmp(property_value, "green")) {
EXPECT_EQ(verified_boot_state, KM_VERIFIED_BOOT_VERIFIED);
EXPECT_NE(0, memcmp(verified_boot_key.data(), empty_boot_key.data(),
@@ -522,14 +528,14 @@
* Verifies that keymaster can generate all required RSA key sizes, and that the resulting keys have
* correct characteristics.
*/
-TEST_F(NewKeyGenerationTest, Rsa) {
+TEST_P(NewKeyGenerationTest, Rsa) {
for (auto key_size : ValidKeySizes(Algorithm::RSA)) {
HidlBuf key_blob;
KeyCharacteristics key_characteristics;
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
- .RsaSigningKey(key_size, 3)
- .Digest(Digest::NONE)
- .Padding(PaddingMode::NONE),
+ .RsaSigningKey(key_size, 65537)
+ .Digest(Digest::NONE)
+ .Padding(PaddingMode::NONE),
&key_blob, &key_characteristics));
ASSERT_GT(key_blob.size(), 0U);
@@ -546,7 +552,7 @@
EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::RSA));
EXPECT_TRUE(crypto_params.Contains(TAG_KEY_SIZE, key_size))
<< "Key size " << key_size << "missing";
- EXPECT_TRUE(crypto_params.Contains(TAG_RSA_PUBLIC_EXPONENT, 3U));
+ EXPECT_TRUE(crypto_params.Contains(TAG_RSA_PUBLIC_EXPONENT, 65537U));
CheckedDeleteKey(&key_blob);
}
@@ -557,7 +563,7 @@
*
* Verifies that creation date time is correct.
*/
-TEST_F(NewKeyGenerationTest, RsaCheckCreationDateTime) {
+TEST_P(NewKeyGenerationTest, RsaCheckCreationDateTime) {
KeyCharacteristics key_characteristics;
auto creation_time = std::chrono::system_clock::now();
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
@@ -575,15 +581,16 @@
*
* Verifies that keymaster cannot generate any RSA key sizes that are designated as invalid.
*/
-TEST_F(NewKeyGenerationTest, NoInvalidRsaSizes) {
+TEST_P(NewKeyGenerationTest, NoInvalidRsaSizes) {
for (auto key_size : InvalidKeySizes(Algorithm::RSA)) {
HidlBuf key_blob;
KeyCharacteristics key_characteristics;
- ASSERT_EQ(ErrorCode::UNSUPPORTED_KEY_SIZE, GenerateKey(AuthorizationSetBuilder()
- .RsaSigningKey(key_size, 3)
- .Digest(Digest::NONE)
- .Padding(PaddingMode::NONE),
- &key_blob, &key_characteristics));
+ ASSERT_EQ(ErrorCode::UNSUPPORTED_KEY_SIZE,
+ GenerateKey(AuthorizationSetBuilder()
+ .RsaSigningKey(key_size, 65537)
+ .Digest(Digest::NONE)
+ .Padding(PaddingMode::NONE),
+ &key_blob, &key_characteristics));
}
}
@@ -592,7 +599,7 @@
*
* Verifies that failing to specify a key size for RSA key generation returns UNSUPPORTED_KEY_SIZE.
*/
-TEST_F(NewKeyGenerationTest, RsaNoDefaultSize) {
+TEST_P(NewKeyGenerationTest, RsaNoDefaultSize) {
ASSERT_EQ(ErrorCode::UNSUPPORTED_KEY_SIZE,
GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_ALGORITHM, Algorithm::RSA)
@@ -606,7 +613,7 @@
* Verifies that keymaster can generate all required EC key sizes, and that the resulting keys have
* correct characteristics.
*/
-TEST_F(NewKeyGenerationTest, Ecdsa) {
+TEST_P(NewKeyGenerationTest, Ecdsa) {
for (auto key_size : ValidKeySizes(Algorithm::EC)) {
HidlBuf key_blob;
KeyCharacteristics key_characteristics;
@@ -638,7 +645,7 @@
*
* Verifies that creation date time is correct.
*/
-TEST_F(NewKeyGenerationTest, EcCheckCreationDateTime) {
+TEST_P(NewKeyGenerationTest, EcCheckCreationDateTime) {
KeyCharacteristics key_characteristics;
auto creation_time = std::chrono::system_clock::now();
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
@@ -655,7 +662,7 @@
*
* Verifies that failing to specify a key size for EC key generation returns UNSUPPORTED_KEY_SIZE.
*/
-TEST_F(NewKeyGenerationTest, EcdsaDefaultSize) {
+TEST_P(NewKeyGenerationTest, EcdsaDefaultSize) {
ASSERT_EQ(ErrorCode::UNSUPPORTED_KEY_SIZE,
GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_ALGORITHM, Algorithm::EC)
@@ -668,7 +675,7 @@
*
* Verifies that specifying an invalid key size for EC key generation returns UNSUPPORTED_KEY_SIZE.
*/
-TEST_F(NewKeyGenerationTest, EcdsaInvalidSize) {
+TEST_P(NewKeyGenerationTest, EcdsaInvalidSize) {
for (auto key_size : InvalidKeySizes(Algorithm::EC)) {
HidlBuf key_blob;
KeyCharacteristics key_characteristics;
@@ -688,7 +695,7 @@
* Verifies that specifying mismatched key size and curve for EC key generation returns
* INVALID_ARGUMENT.
*/
-TEST_F(NewKeyGenerationTest, EcdsaMismatchKeySize) {
+TEST_P(NewKeyGenerationTest, EcdsaMismatchKeySize) {
if (SecLevel() == SecurityLevel::STRONGBOX) return;
ASSERT_EQ(ErrorCode::INVALID_ARGUMENT,
@@ -703,7 +710,7 @@
*
* Verifies that keymaster supports all required EC key sizes.
*/
-TEST_F(NewKeyGenerationTest, EcdsaAllValidSizes) {
+TEST_P(NewKeyGenerationTest, EcdsaAllValidSizes) {
auto valid_sizes = ValidKeySizes(Algorithm::EC);
for (size_t size : valid_sizes) {
EXPECT_EQ(ErrorCode::OK,
@@ -719,7 +726,7 @@
*
* Verifies that keymaster does not support any curve designated as unsupported.
*/
-TEST_F(NewKeyGenerationTest, EcdsaAllValidCurves) {
+TEST_P(NewKeyGenerationTest, EcdsaAllValidCurves) {
Digest digest;
if (SecLevel() == SecurityLevel::STRONGBOX) {
digest = Digest::SHA_2_256;
@@ -742,7 +749,7 @@
* Verifies that keymaster supports all required digests, and that the resulting keys have correct
* characteristics.
*/
-TEST_F(NewKeyGenerationTest, Hmac) {
+TEST_P(NewKeyGenerationTest, Hmac) {
for (auto digest : ValidDigests(false /* withNone */, true /* withMD5 */)) {
HidlBuf key_blob;
KeyCharacteristics key_characteristics;
@@ -778,7 +785,7 @@
*
* Verifies that keymaster supports all key sizes, and rejects all invalid key sizes.
*/
-TEST_F(NewKeyGenerationTest, HmacCheckKeySizes) {
+TEST_P(NewKeyGenerationTest, HmacCheckKeySizes) {
for (size_t key_size = 0; key_size <= 512; ++key_size) {
if (key_size < 64 || key_size % 8 != 0) {
// To keep this test from being very slow, we only test a random fraction of non-byte
@@ -811,7 +818,7 @@
* test is probabilistic in order to keep the runtime down, but any failure prints out the specific
* MAC length that failed, so reproducing a failed run will be easy.
*/
-TEST_F(NewKeyGenerationTest, HmacCheckMinMacLengths) {
+TEST_P(NewKeyGenerationTest, HmacCheckMinMacLengths) {
for (size_t min_mac_length = 0; min_mac_length <= 256; ++min_mac_length) {
if (min_mac_length < 64 || min_mac_length % 8 != 0) {
// To keep this test from being very long, we only test a random fraction of non-byte
@@ -843,7 +850,7 @@
*
* Verifies that keymaster rejects HMAC key generation with multiple specified digest algorithms.
*/
-TEST_F(NewKeyGenerationTest, HmacMultipleDigests) {
+TEST_P(NewKeyGenerationTest, HmacMultipleDigests) {
if (SecLevel() == SecurityLevel::STRONGBOX) return;
ASSERT_EQ(ErrorCode::UNSUPPORTED_DIGEST,
@@ -859,7 +866,7 @@
*
* Verifies that keymaster rejects HMAC key generation with no digest or Digest::NONE
*/
-TEST_F(NewKeyGenerationTest, HmacDigestNone) {
+TEST_P(NewKeyGenerationTest, HmacDigestNone) {
ASSERT_EQ(
ErrorCode::UNSUPPORTED_DIGEST,
GenerateKey(AuthorizationSetBuilder().HmacKey(128).Authorization(TAG_MIN_MAC_LENGTH, 128)));
@@ -878,7 +885,7 @@
*
* Verifies that raw RSA signature operations succeed.
*/
-TEST_F(SigningOperationsTest, RsaSuccess) {
+TEST_P(SigningOperationsTest, RsaSuccess) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.RsaSigningKey(2048, 65537)
.Digest(Digest::NONE)
@@ -894,7 +901,7 @@
*
* Verifies that getting RSA key characteristics requires the correct app ID/data.
*/
-TEST_F(SigningOperationsTest, RsaGetKeyCharacteristicsRequiresCorrectAppIdAppData) {
+TEST_P(SigningOperationsTest, RsaGetKeyCharacteristicsRequiresCorrectAppIdAppData) {
HidlBuf key_blob;
KeyCharacteristics key_characteristics;
ASSERT_EQ(ErrorCode::OK,
@@ -915,7 +922,7 @@
*
* Verifies that using an RSA key requires the correct app ID/data.
*/
-TEST_F(SigningOperationsTest, RsaUseRequiresCorrectAppIdAppData) {
+TEST_P(SigningOperationsTest, RsaUseRequiresCorrectAppIdAppData) {
ASSERT_EQ(ErrorCode::OK,
GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
@@ -957,7 +964,7 @@
*
* Verifies that RSA-PSS signature operations succeed.
*/
-TEST_F(SigningOperationsTest, RsaPssSha256Success) {
+TEST_P(SigningOperationsTest, RsaPssSha256Success) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.RsaSigningKey(2048, 65537)
.Digest(Digest::SHA_2_256)
@@ -975,7 +982,7 @@
* Verifies that keymaster rejects signature operations that specify a padding mode when the key
* supports only unpadded operations.
*/
-TEST_F(SigningOperationsTest, RsaPaddingNoneDoesNotAllowOther) {
+TEST_P(SigningOperationsTest, RsaPaddingNoneDoesNotAllowOther) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.RsaSigningKey(2048, 65537)
.Digest(Digest::NONE)
@@ -997,7 +1004,7 @@
* TRUSTED_CONFIRMATION_REQUIRED and no valid confirmation token
* presented.
*/
-TEST_F(SigningOperationsTest, NoUserConfirmation) {
+TEST_P(SigningOperationsTest, NoUserConfirmation) {
if (SecLevel() == SecurityLevel::STRONGBOX) return;
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.RsaSigningKey(1024, 65537)
@@ -1019,7 +1026,7 @@
*
* Verifies that digested RSA-PKCS1 signature operations succeed.
*/
-TEST_F(SigningOperationsTest, RsaPkcs1Sha256Success) {
+TEST_P(SigningOperationsTest, RsaPkcs1Sha256Success) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.RsaSigningKey(2048, 65537)
.Digest(Digest::SHA_2_256)
@@ -1036,7 +1043,7 @@
*
* Verifies that undigested RSA-PKCS1 signature operations succeed.
*/
-TEST_F(SigningOperationsTest, RsaPkcs1NoDigestSuccess) {
+TEST_P(SigningOperationsTest, RsaPkcs1NoDigestSuccess) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.RsaSigningKey(2048, 65537)
.Digest(Digest::NONE)
@@ -1054,7 +1061,7 @@
* Verifies that undigested RSA-PKCS1 signature operations fail with the correct error code when
* given a too-long message.
*/
-TEST_F(SigningOperationsTest, RsaPkcs1NoDigestTooLong) {
+TEST_P(SigningOperationsTest, RsaPkcs1NoDigestTooLong) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.RsaSigningKey(2048, 65537)
.Digest(Digest::NONE)
@@ -1082,7 +1089,7 @@
* uses SHA512, which has a digest_size == 512, so the message size is 1040 bits, too large for a
* 1024-bit key.
*/
-TEST_F(SigningOperationsTest, RsaPssSha512TooSmallKey) {
+TEST_P(SigningOperationsTest, RsaPssSha512TooSmallKey) {
if (SecLevel() == SecurityLevel::STRONGBOX) return;
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.RsaSigningKey(1024, 65537)
@@ -1101,7 +1108,7 @@
* Verifies that raw RSA signature operations fail with the correct error code when
* given a too-long message.
*/
-TEST_F(SigningOperationsTest, RsaNoPaddingTooLong) {
+TEST_P(SigningOperationsTest, RsaNoPaddingTooLong) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.RsaSigningKey(2048, 65537)
.Digest(Digest::NONE)
@@ -1135,7 +1142,7 @@
* Verifies that operations can be aborted correctly. Uses an RSA signing operation for the test,
* but the behavior should be algorithm and purpose-independent.
*/
-TEST_F(SigningOperationsTest, RsaAbort) {
+TEST_P(SigningOperationsTest, RsaAbort) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.RsaSigningKey(2048, 65537)
.Digest(Digest::NONE)
@@ -1160,7 +1167,7 @@
* Verifies that RSA operations fail with the correct error (but key gen succeeds) when used with a
* padding mode inappropriate for RSA.
*/
-TEST_F(SigningOperationsTest, RsaUnsupportedPadding) {
+TEST_P(SigningOperationsTest, RsaUnsupportedPadding) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.RsaSigningKey(2048, 65537)
.Authorization(TAG_NO_AUTH_REQUIRED)
@@ -1177,7 +1184,7 @@
*
* Verifies that RSA PSS operations fail when no digest is used. PSS requires a digest.
*/
-TEST_F(SigningOperationsTest, RsaNoDigest) {
+TEST_P(SigningOperationsTest, RsaNoDigest) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.RsaSigningKey(2048, 65537)
.Authorization(TAG_NO_AUTH_REQUIRED)
@@ -1197,7 +1204,7 @@
* Verifies that RSA operations fail when no padding mode is specified. PaddingMode::NONE is
* supported in some cases (as validated in other tests), but a mode must be specified.
*/
-TEST_F(SigningOperationsTest, RsaNoPadding) {
+TEST_P(SigningOperationsTest, RsaNoPadding) {
// Padding must be specified
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.RsaKey(2048, 65537)
@@ -1213,7 +1220,7 @@
*
* Verifies that raw RSA signatures succeed with a message shorter than the key size.
*/
-TEST_F(SigningOperationsTest, RsaTooShortMessage) {
+TEST_P(SigningOperationsTest, RsaTooShortMessage) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.RsaSigningKey(2048, 65537)
@@ -1234,7 +1241,7 @@
*
* Verifies that RSA encryption keys cannot be used to sign.
*/
-TEST_F(SigningOperationsTest, RsaSignWithEncryptionKey) {
+TEST_P(SigningOperationsTest, RsaSignWithEncryptionKey) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.RsaEncryptionKey(2048, 65537)
@@ -1251,7 +1258,7 @@
* Verifies that attempting a raw signature of a message which is the same length as the key, but
* numerically larger than the public modulus, fails with the correct error.
*/
-TEST_F(SigningOperationsTest, RsaSignTooLargeMessage) {
+TEST_P(SigningOperationsTest, RsaSignTooLargeMessage) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.RsaSigningKey(2048, 65537)
@@ -1273,7 +1280,7 @@
*
* Verifies that ECDSA operations succeed with all possible key sizes and hashes.
*/
-TEST_F(SigningOperationsTest, EcdsaAllSizesAndHashes) {
+TEST_P(SigningOperationsTest, EcdsaAllSizesAndHashes) {
for (auto key_size : ValidKeySizes(Algorithm::EC)) {
for (auto digest : ValidDigests(false /* withNone */, false /* withMD5 */)) {
ErrorCode error = GenerateKey(AuthorizationSetBuilder()
@@ -1297,7 +1304,7 @@
*
* Verifies that ECDSA operations succeed with all possible curves.
*/
-TEST_F(SigningOperationsTest, EcdsaAllCurves) {
+TEST_P(SigningOperationsTest, EcdsaAllCurves) {
for (auto curve : ValidCurves()) {
ErrorCode error = GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
@@ -1319,7 +1326,7 @@
* work because ECDSA actually only signs the leftmost L_n bits of the message, however large it may
* be. Not using digesting is a bad idea, but in some cases digesting is done by the framework.
*/
-TEST_F(SigningOperationsTest, EcdsaNoDigestHugeData) {
+TEST_P(SigningOperationsTest, EcdsaNoDigestHugeData) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.EcdsaSigningKey(256)
@@ -1333,7 +1340,7 @@
*
* Verifies that getting EC key characteristics requires the correct app ID/data.
*/
-TEST_F(SigningOperationsTest, EcGetKeyCharacteristicsRequiresCorrectAppIdAppData) {
+TEST_P(SigningOperationsTest, EcGetKeyCharacteristicsRequiresCorrectAppIdAppData) {
HidlBuf key_blob;
KeyCharacteristics key_characteristics;
ASSERT_EQ(ErrorCode::OK,
@@ -1353,7 +1360,7 @@
*
* Verifies that using an EC key requires the correct app ID/data.
*/
-TEST_F(SigningOperationsTest, EcUseRequiresCorrectAppIdAppData) {
+TEST_P(SigningOperationsTest, EcUseRequiresCorrectAppIdAppData) {
ASSERT_EQ(ErrorCode::OK,
GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
@@ -1390,7 +1397,7 @@
*
* Verifies that attempts to use AES keys to sign fail in the correct way.
*/
-TEST_F(SigningOperationsTest, AesEcbSign) {
+TEST_P(SigningOperationsTest, AesEcbSign) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.SigningKey()
@@ -1409,7 +1416,7 @@
*
* Verifies that HMAC works with all digests.
*/
-TEST_F(SigningOperationsTest, HmacAllDigests) {
+TEST_P(SigningOperationsTest, HmacAllDigests) {
for (auto digest : ValidDigests(false /* withNone */, false /* withMD5 */)) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
@@ -1431,7 +1438,7 @@
* Verifies that HMAC fails in the correct way when asked to generate a MAC larger than the digest
* size.
*/
-TEST_F(SigningOperationsTest, HmacSha256TooLargeMacLength) {
+TEST_P(SigningOperationsTest, HmacSha256TooLargeMacLength) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.HmacKey(128)
@@ -1452,7 +1459,7 @@
* Verifies that HMAC fails in the correct way when asked to generate a MAC smaller than the
* specified minimum MAC length.
*/
-TEST_F(SigningOperationsTest, HmacSha256TooSmallMacLength) {
+TEST_P(SigningOperationsTest, HmacSha256TooSmallMacLength) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.HmacKey(128)
@@ -1472,7 +1479,7 @@
*
* Validates against the test vectors from RFC 4231 test case 3.
*/
-TEST_F(SigningOperationsTest, HmacRfc4231TestCase3) {
+TEST_P(SigningOperationsTest, HmacRfc4231TestCase3) {
string key(20, 0xaa);
string message(50, 0xdd);
uint8_t sha_224_expected[] = {
@@ -1511,7 +1518,7 @@
*
* Validates against the test vectors from RFC 4231 test case 5.
*/
-TEST_F(SigningOperationsTest, HmacRfc4231TestCase5) {
+TEST_P(SigningOperationsTest, HmacRfc4231TestCase5) {
string key(20, 0x0c);
string message = "Test With Truncation";
@@ -1547,7 +1554,7 @@
*
* Verifies that a simple RSA signature/verification sequence succeeds.
*/
-TEST_F(VerificationOperationsTest, RsaSuccess) {
+TEST_P(VerificationOperationsTest, RsaSuccess) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.RsaSigningKey(2048, 65537)
@@ -1565,7 +1572,7 @@
*
* Verifies RSA signature/verification for all padding modes and digests.
*/
-TEST_F(VerificationOperationsTest, RsaAllPaddingsAndDigests) {
+TEST_P(VerificationOperationsTest, RsaAllPaddingsAndDigests) {
auto authorizations = AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.RsaSigningKey(2048, 65537)
@@ -1659,7 +1666,7 @@
*
* Verifies ECDSA signature/verification for all digests and curves.
*/
-TEST_F(VerificationOperationsTest, EcdsaAllDigestsAndCurves) {
+TEST_P(VerificationOperationsTest, EcdsaAllDigestsAndCurves) {
auto digests = ValidDigests(true /* withNone */, false /* withMD5 */);
string message = "1234567890";
@@ -1739,7 +1746,7 @@
*
* Verifies HMAC signing and verification, but that a signing key cannot be used to verify.
*/
-TEST_F(VerificationOperationsTest, HmacSigningKeyCannotVerify) {
+TEST_P(VerificationOperationsTest, HmacSigningKeyCannotVerify) {
string key_material = "HelloThisIsAKey";
HidlBuf signing_key, verification_key;
@@ -1787,7 +1794,7 @@
*
* Verifies that attempting to export RSA keys in PKCS#8 format fails with the correct error.
*/
-TEST_F(ExportKeyTest, RsaUnsupportedKeyFormat) {
+TEST_P(ExportKeyTest, RsaUnsupportedKeyFormat) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.RsaSigningKey(2048, 65537)
.Digest(Digest::NONE)
@@ -1802,7 +1809,7 @@
* Verifies that attempting to export RSA keys from corrupted key blobs fails. This is essentially
* a poor-man's key blob fuzzer.
*/
-TEST_F(ExportKeyTest, RsaCorruptedKeyBlob) {
+TEST_P(ExportKeyTest, RsaCorruptedKeyBlob) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.RsaSigningKey(2048, 65537)
@@ -1825,7 +1832,7 @@
* Verifies that attempting to export ECDSA keys from corrupted key blobs fails. This is
* essentially a poor-man's key blob fuzzer.
*/
-TEST_F(ExportKeyTest, EcCorruptedKeyBlob) {
+TEST_P(ExportKeyTest, EcCorruptedKeyBlob) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.EcdsaSigningKey(EcCurve::P_256)
@@ -1846,7 +1853,7 @@
*
* Verifies that attempting to export AES keys fails in the expected way.
*/
-TEST_F(ExportKeyTest, AesKeyUnexportable) {
+TEST_P(ExportKeyTest, AesKeyUnexportable) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.AesEncryptionKey(128)
@@ -1894,7 +1901,7 @@
*
* Verifies that importing and using an RSA key pair works correctly.
*/
-TEST_F(ImportKeyTest, RsaSuccess) {
+TEST_P(ImportKeyTest, RsaSuccess) {
ASSERT_EQ(ErrorCode::OK, ImportKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.RsaSigningKey(1024, 65537)
@@ -1921,7 +1928,7 @@
* Verifies that importing an RSA key pair with a size that doesn't match the key fails in the
* correct way.
*/
-TEST_F(ImportKeyTest, RsaKeySizeMismatch) {
+TEST_P(ImportKeyTest, RsaKeySizeMismatch) {
ASSERT_EQ(ErrorCode::IMPORT_PARAMETER_MISMATCH,
ImportKey(AuthorizationSetBuilder()
.RsaSigningKey(2048 /* Doesn't match key */, 65537)
@@ -1936,7 +1943,7 @@
* Verifies that importing an RSA key pair with a public exponent that doesn't match the key fails
* in the correct way.
*/
-TEST_F(ImportKeyTest, RsaPublicExponentMismatch) {
+TEST_P(ImportKeyTest, RsaPublicExponentMismatch) {
ASSERT_EQ(ErrorCode::IMPORT_PARAMETER_MISMATCH,
ImportKey(AuthorizationSetBuilder()
.RsaSigningKey(1024, 3 /* Doesn't match key */)
@@ -1950,7 +1957,7 @@
*
* Verifies that importing and using an ECDSA P-256 key pair works correctly.
*/
-TEST_F(ImportKeyTest, EcdsaSuccess) {
+TEST_P(ImportKeyTest, EcdsaSuccess) {
ASSERT_EQ(ErrorCode::OK, ImportKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.EcdsaSigningKey(256)
@@ -1975,7 +1982,7 @@
*
* Verifies that importing and using an ECDSA P-256 key pair encoded using RFC5915 works correctly.
*/
-TEST_F(ImportKeyTest, EcdsaP256RFC5915Success) {
+TEST_P(ImportKeyTest, EcdsaP256RFC5915Success) {
ASSERT_EQ(ErrorCode::OK, ImportKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.EcdsaSigningKey(256)
@@ -2000,7 +2007,7 @@
*
* Verifies that importing and using an ECDSA P-256 key pair encoded using SEC1 works correctly.
*/
-TEST_F(ImportKeyTest, EcdsaP256SEC1Success) {
+TEST_P(ImportKeyTest, EcdsaP256SEC1Success) {
ASSERT_EQ(ErrorCode::OK, ImportKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.EcdsaSigningKey(256)
@@ -2025,7 +2032,7 @@
*
* Verifies that importing and using an ECDSA P-521 key pair works correctly.
*/
-TEST_F(ImportKeyTest, Ecdsa521Success) {
+TEST_P(ImportKeyTest, Ecdsa521Success) {
if (SecLevel() == SecurityLevel::STRONGBOX) return;
ASSERT_EQ(ErrorCode::OK, ImportKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
@@ -2051,7 +2058,7 @@
* Verifies that importing an ECDSA key pair with a size that doesn't match the key fails in the
* correct way.
*/
-TEST_F(ImportKeyTest, EcdsaSizeMismatch) {
+TEST_P(ImportKeyTest, EcdsaSizeMismatch) {
ASSERT_EQ(ErrorCode::IMPORT_PARAMETER_MISMATCH,
ImportKey(AuthorizationSetBuilder()
.EcdsaSigningKey(224 /* Doesn't match key */)
@@ -2065,7 +2072,7 @@
* Verifies that importing an ECDSA key pair with a curve that doesn't match the key fails in the
* correct way.
*/
-TEST_F(ImportKeyTest, EcdsaCurveMismatch) {
+TEST_P(ImportKeyTest, EcdsaCurveMismatch) {
ASSERT_EQ(ErrorCode::IMPORT_PARAMETER_MISMATCH,
ImportKey(AuthorizationSetBuilder()
.EcdsaSigningKey(EcCurve::P_224 /* Doesn't match key */)
@@ -2078,7 +2085,7 @@
*
* Verifies that importing and using an AES key works.
*/
-TEST_F(ImportKeyTest, AesSuccess) {
+TEST_P(ImportKeyTest, AesSuccess) {
string key = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
ASSERT_EQ(ErrorCode::OK, ImportKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
@@ -2105,7 +2112,7 @@
*
* Verifies that importing and using an HMAC key works.
*/
-TEST_F(ImportKeyTest, HmacKeySuccess) {
+TEST_P(ImportKeyTest, HmacKeySuccess) {
string key = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
ASSERT_EQ(ErrorCode::OK, ImportKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
@@ -2180,7 +2187,7 @@
class ImportWrappedKeyTest : public KeymasterHidlTest {};
-TEST_F(ImportWrappedKeyTest, Success) {
+TEST_P(ImportWrappedKeyTest, Success) {
auto wrapping_key_desc = AuthorizationSetBuilder()
.RsaEncryptionKey(2048, 65537)
.Digest(Digest::SHA_2_256)
@@ -2201,7 +2208,7 @@
EXPECT_EQ(message, plaintext);
}
-TEST_F(ImportWrappedKeyTest, SuccessMasked) {
+TEST_P(ImportWrappedKeyTest, SuccessMasked) {
auto wrapping_key_desc = AuthorizationSetBuilder()
.RsaEncryptionKey(2048, 65537)
.Digest(Digest::SHA_2_256)
@@ -2216,7 +2223,7 @@
.Padding(PaddingMode::RSA_OAEP)));
}
-TEST_F(ImportWrappedKeyTest, WrongMask) {
+TEST_P(ImportWrappedKeyTest, WrongMask) {
auto wrapping_key_desc = AuthorizationSetBuilder()
.RsaEncryptionKey(2048, 65537)
.Digest(Digest::SHA_2_256)
@@ -2231,7 +2238,7 @@
.Padding(PaddingMode::RSA_OAEP)));
}
-TEST_F(ImportWrappedKeyTest, WrongPurpose) {
+TEST_P(ImportWrappedKeyTest, WrongPurpose) {
auto wrapping_key_desc = AuthorizationSetBuilder()
.RsaEncryptionKey(2048, 65537)
.Digest(Digest::SHA_2_256)
@@ -2252,7 +2259,7 @@
*
* Verifies that raw RSA encryption works.
*/
-TEST_F(EncryptionOperationsTest, RsaNoPaddingSuccess) {
+TEST_P(EncryptionOperationsTest, RsaNoPaddingSuccess) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.RsaEncryptionKey(2048, 65537)
@@ -2275,7 +2282,7 @@
*
* Verifies that raw RSA encryption of short messages works.
*/
-TEST_F(EncryptionOperationsTest, RsaNoPaddingShortMessage) {
+TEST_P(EncryptionOperationsTest, RsaNoPaddingShortMessage) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.RsaEncryptionKey(2048, 65537)
@@ -2304,7 +2311,7 @@
*
* Verifies that raw RSA encryption of too-long messages fails in the expected way.
*/
-TEST_F(EncryptionOperationsTest, RsaNoPaddingTooLong) {
+TEST_P(EncryptionOperationsTest, RsaNoPaddingTooLong) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.RsaEncryptionKey(2048, 65537)
@@ -2324,7 +2331,7 @@
*
* Verifies that raw RSA encryption of too-large (numerically) messages fails in the expected way.
*/
-TEST_F(EncryptionOperationsTest, RsaNoPaddingTooLarge) {
+TEST_P(EncryptionOperationsTest, RsaNoPaddingTooLarge) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.RsaEncryptionKey(2048, 65537)
@@ -2366,7 +2373,7 @@
*
* Verifies that RSA-OAEP encryption operations work, with all digests.
*/
-TEST_F(EncryptionOperationsTest, RsaOaepSuccess) {
+TEST_P(EncryptionOperationsTest, RsaOaepSuccess) {
auto digests = ValidDigests(false /* withNone */, true /* withMD5 */);
size_t key_size = 2048; // Need largish key for SHA-512 test.
@@ -2417,7 +2424,7 @@
* Verifies that RSA-OAEP encryption operations fail in the correct way when asked to operate
* without a digest.
*/
-TEST_F(EncryptionOperationsTest, RsaOaepInvalidDigest) {
+TEST_P(EncryptionOperationsTest, RsaOaepInvalidDigest) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.RsaEncryptionKey(2048, 65537)
@@ -2435,7 +2442,7 @@
* Verifies that RSA-OAEP encryption operations fail in the correct way when asked to decrypt with a
* different digest than was used to encrypt.
*/
-TEST_F(EncryptionOperationsTest, RsaOaepDecryptWithWrongDigest) {
+TEST_P(EncryptionOperationsTest, RsaOaepDecryptWithWrongDigest) {
if (SecLevel() == SecurityLevel::STRONGBOX) return;
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
@@ -2463,7 +2470,7 @@
* Verifies that RSA-OAEP encryption operations fail in the correct way when asked to encrypt a
* too-large message.
*/
-TEST_F(EncryptionOperationsTest, RsaOaepTooLarge) {
+TEST_P(EncryptionOperationsTest, RsaOaepTooLarge) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.RsaEncryptionKey(2048, 65537)
@@ -2486,7 +2493,7 @@
*
* Verifies that RSA PKCS encryption/decrypts works.
*/
-TEST_F(EncryptionOperationsTest, RsaPkcs1Success) {
+TEST_P(EncryptionOperationsTest, RsaPkcs1Success) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.RsaEncryptionKey(2048, 65537)
@@ -2525,7 +2532,7 @@
*
* Verifies that RSA PKCS encryption fails in the correct way when the mssage is too large.
*/
-TEST_F(EncryptionOperationsTest, RsaPkcs1TooLarge) {
+TEST_P(EncryptionOperationsTest, RsaPkcs1TooLarge) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.RsaEncryptionKey(2048, 65537)
@@ -2545,7 +2552,7 @@
*
* Verifies that attempting to use ECDSA keys to encrypt fails in the correct way.
*/
-TEST_F(EncryptionOperationsTest, EcdsaEncrypt) {
+TEST_P(EncryptionOperationsTest, EcdsaEncrypt) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.EcdsaSigningKey(256)
@@ -2560,7 +2567,7 @@
*
* Verifies that attempting to use HMAC keys to encrypt fails in the correct way.
*/
-TEST_F(EncryptionOperationsTest, HmacEncrypt) {
+TEST_P(EncryptionOperationsTest, HmacEncrypt) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.HmacKey(128)
@@ -2580,7 +2587,7 @@
*
* Verifies that AES ECB mode works.
*/
-TEST_F(EncryptionOperationsTest, AesEcbRoundTripSuccess) {
+TEST_P(EncryptionOperationsTest, AesEcbRoundTripSuccess) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.AesEncryptionKey(128)
@@ -2609,7 +2616,7 @@
*
* Verifies that AES encryption fails in the correct way when an unauthorized mode is specified.
*/
-TEST_F(EncryptionOperationsTest, AesWrongMode) {
+TEST_P(EncryptionOperationsTest, AesWrongMode) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.AesEncryptionKey(128)
@@ -2628,7 +2635,7 @@
*
* Verifies that AES encryption fails in the correct way when an unauthorized purpose is specified.
*/
-TEST_F(EncryptionOperationsTest, AesWrongPurpose) {
+TEST_P(EncryptionOperationsTest, AesWrongPurpose) {
auto err = GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.AesKey(128)
@@ -2663,7 +2670,7 @@
* Verifies that AES encryption fails in the correct way when provided an input that is not a
* multiple of the block size and no padding is specified.
*/
-TEST_F(EncryptionOperationsTest, AesEcbNoPaddingWrongInputSize) {
+TEST_P(EncryptionOperationsTest, AesEcbNoPaddingWrongInputSize) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.AesEncryptionKey(128)
@@ -2684,7 +2691,7 @@
*
* Verifies that AES PKCS7 padding works for any message length.
*/
-TEST_F(EncryptionOperationsTest, AesEcbPkcs7Padding) {
+TEST_P(EncryptionOperationsTest, AesEcbPkcs7Padding) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.AesEncryptionKey(128)
@@ -2709,7 +2716,7 @@
* Verifies that AES enryption fails in the correct way when an unauthorized padding mode is
* specified.
*/
-TEST_F(EncryptionOperationsTest, AesEcbWrongPadding) {
+TEST_P(EncryptionOperationsTest, AesEcbWrongPadding) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.AesEncryptionKey(128)
@@ -2730,7 +2737,7 @@
*
* Verifies that AES decryption fails in the correct way when the padding is corrupted.
*/
-TEST_F(EncryptionOperationsTest, AesEcbPkcs7PaddingCorrupted) {
+TEST_P(EncryptionOperationsTest, AesEcbPkcs7PaddingCorrupted) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.AesEncryptionKey(128)
@@ -2761,7 +2768,7 @@
*
* Verifies that AES CTR mode works.
*/
-TEST_F(EncryptionOperationsTest, AesCtrRoundTripSuccess) {
+TEST_P(EncryptionOperationsTest, AesCtrRoundTripSuccess) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.AesEncryptionKey(128)
@@ -2808,7 +2815,7 @@
*
* Verifies that AES works, all modes, when provided data in various size increments.
*/
-TEST_F(EncryptionOperationsTest, AesIncremental) {
+TEST_P(EncryptionOperationsTest, AesIncremental) {
auto block_modes = {
BlockMode::ECB, BlockMode::CBC, BlockMode::CTR, BlockMode::GCM,
};
@@ -2947,7 +2954,7 @@
*
* Verifies AES CTR implementation against SP800-38A test vectors.
*/
-TEST_F(EncryptionOperationsTest, AesCtrSp80038aTestVector) {
+TEST_P(EncryptionOperationsTest, AesCtrSp80038aTestVector) {
std::vector<uint32_t> InvalidSizes = InvalidKeySizes(Algorithm::AES);
for (size_t i = 0; i < 3; i++) {
const AesCtrSp80038aTestVector& test(kAesCtrSp80038aTestVectors[i]);
@@ -2967,7 +2974,7 @@
*
* Verifies that keymaster rejects use of CTR mode with PKCS7 padding in the correct way.
*/
-TEST_F(EncryptionOperationsTest, AesCtrIncompatiblePaddingMode) {
+TEST_P(EncryptionOperationsTest, AesCtrIncompatiblePaddingMode) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.AesEncryptionKey(128)
@@ -2982,7 +2989,7 @@
*
* Verifies that keymaster fails correctly when the user supplies an incorrect-size nonce.
*/
-TEST_F(EncryptionOperationsTest, AesCtrInvalidCallerNonce) {
+TEST_P(EncryptionOperationsTest, AesCtrInvalidCallerNonce) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.AesEncryptionKey(128)
@@ -3014,7 +3021,7 @@
*
* Verifies that keymaster fails correctly when the user supplies an incorrect-size nonce.
*/
-TEST_F(EncryptionOperationsTest, AesCbcRoundTripSuccess) {
+TEST_P(EncryptionOperationsTest, AesCbcRoundTripSuccess) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.AesEncryptionKey(128)
@@ -3047,7 +3054,7 @@
*
* Verifies that AES caller-provided nonces work correctly.
*/
-TEST_F(EncryptionOperationsTest, AesCallerNonce) {
+TEST_P(EncryptionOperationsTest, AesCallerNonce) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.AesEncryptionKey(128)
@@ -3096,7 +3103,7 @@
* Verifies that caller-provided nonces are not permitted when not specified in the key
* authorizations.
*/
-TEST_F(EncryptionOperationsTest, AesCallerNonceProhibited) {
+TEST_P(EncryptionOperationsTest, AesCallerNonceProhibited) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.AesEncryptionKey(128)
@@ -3131,7 +3138,7 @@
*
* Verifies that AES GCM mode works.
*/
-TEST_F(EncryptionOperationsTest, AesGcmRoundTripSuccess) {
+TEST_P(EncryptionOperationsTest, AesGcmRoundTripSuccess) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.AesEncryptionKey(128)
@@ -3182,7 +3189,7 @@
* Verifies that AES GCM mode works, even when there's a long delay
* between operations.
*/
-TEST_F(EncryptionOperationsTest, AesGcmRoundTripWithDelaySuccess) {
+TEST_P(EncryptionOperationsTest, AesGcmRoundTripWithDelaySuccess) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.AesEncryptionKey(128)
@@ -3235,7 +3242,7 @@
*
* Verifies that encrypting the same data with different nonces produces different outputs.
*/
-TEST_F(EncryptionOperationsTest, AesGcmDifferentNonces) {
+TEST_P(EncryptionOperationsTest, AesGcmDifferentNonces) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.AesEncryptionKey(128)
@@ -3267,7 +3274,7 @@
*
* Verifies that AES GCM mode fails correctly when a too-short tag length is specified.
*/
-TEST_F(EncryptionOperationsTest, AesGcmTooShortTag) {
+TEST_P(EncryptionOperationsTest, AesGcmTooShortTag) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.AesEncryptionKey(128)
@@ -3288,7 +3295,7 @@
*
* Verifies that AES GCM mode fails correctly when a too-short tag is provided to decryption.
*/
-TEST_F(EncryptionOperationsTest, AesGcmTooShortTagOnDecrypt) {
+TEST_P(EncryptionOperationsTest, AesGcmTooShortTagOnDecrypt) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.AesEncryptionKey(128)
@@ -3331,7 +3338,7 @@
*
* Verifies that AES GCM mode fails correctly when the decryption key is incorrect.
*/
-TEST_F(EncryptionOperationsTest, AesGcmCorruptKey) {
+TEST_P(EncryptionOperationsTest, AesGcmCorruptKey) {
const uint8_t nonce_bytes[] = {
0xb7, 0x94, 0x37, 0xae, 0x08, 0xff, 0x35, 0x5d, 0x7d, 0x8a, 0x4d, 0x0f,
};
@@ -3383,7 +3390,7 @@
* Verifies that AES GCM mode works when provided additional authenticated data, but no data to
* encrypt.
*/
-TEST_F(EncryptionOperationsTest, AesGcmAadNoData) {
+TEST_P(EncryptionOperationsTest, AesGcmAadNoData) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.AesEncryptionKey(128)
@@ -3428,7 +3435,7 @@
*
* Verifies that AES GCM mode works when provided additional authenticated data in multiple chunks.
*/
-TEST_F(EncryptionOperationsTest, AesGcmMultiPartAad) {
+TEST_P(EncryptionOperationsTest, AesGcmMultiPartAad) {
const size_t tag_bits = 128;
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
@@ -3489,7 +3496,7 @@
*
* Verifies that AES GCM mode fails correctly when given AAD after data to encipher.
*/
-TEST_F(EncryptionOperationsTest, AesGcmAadOutOfOrder) {
+TEST_P(EncryptionOperationsTest, AesGcmAadOutOfOrder) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.AesEncryptionKey(128)
@@ -3537,7 +3544,7 @@
*
* Verifies that AES GCM decryption fails correctly when additional authenticated date is wrong.
*/
-TEST_F(EncryptionOperationsTest, AesGcmBadAad) {
+TEST_P(EncryptionOperationsTest, AesGcmBadAad) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.AesEncryptionKey(128)
@@ -3581,7 +3588,7 @@
*
* Verifies that AES GCM decryption fails correctly when the nonce is incorrect.
*/
-TEST_F(EncryptionOperationsTest, AesGcmWrongNonce) {
+TEST_P(EncryptionOperationsTest, AesGcmWrongNonce) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.AesEncryptionKey(128)
@@ -3625,7 +3632,7 @@
*
* Verifies that AES GCM decryption fails correctly when the tag is wrong.
*/
-TEST_F(EncryptionOperationsTest, AesGcmCorruptTag) {
+TEST_P(EncryptionOperationsTest, AesGcmCorruptTag) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.AesEncryptionKey(128)
@@ -3673,7 +3680,7 @@
*
* Verifies that 3DES is basically functional.
*/
-TEST_F(EncryptionOperationsTest, TripleDesEcbRoundTripSuccess) {
+TEST_P(EncryptionOperationsTest, TripleDesEcbRoundTripSuccess) {
auto auths = AuthorizationSetBuilder()
.TripleDesEncryptionKey(168)
.BlockMode(BlockMode::ECB)
@@ -3702,7 +3709,7 @@
*
* Verifies that CBC keys reject ECB usage.
*/
-TEST_F(EncryptionOperationsTest, TripleDesEcbNotAuthorized) {
+TEST_P(EncryptionOperationsTest, TripleDesEcbNotAuthorized) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.TripleDesEncryptionKey(168)
.BlockMode(BlockMode::CBC)
@@ -3718,7 +3725,7 @@
*
* Tests ECB mode with PKCS#7 padding, various message sizes.
*/
-TEST_F(EncryptionOperationsTest, TripleDesEcbPkcs7Padding) {
+TEST_P(EncryptionOperationsTest, TripleDesEcbPkcs7Padding) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.TripleDesEncryptionKey(168)
.BlockMode(BlockMode::ECB)
@@ -3741,7 +3748,7 @@
*
* Verifies that keys configured for no padding reject PKCS7 padding
*/
-TEST_F(EncryptionOperationsTest, TripleDesEcbNoPaddingKeyWithPkcs7Padding) {
+TEST_P(EncryptionOperationsTest, TripleDesEcbNoPaddingKeyWithPkcs7Padding) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.TripleDesEncryptionKey(168)
.BlockMode(BlockMode::ECB)
@@ -3759,7 +3766,7 @@
*
* Verifies that corrupted padding is detected.
*/
-TEST_F(EncryptionOperationsTest, TripleDesEcbPkcs7PaddingCorrupted) {
+TEST_P(EncryptionOperationsTest, TripleDesEcbPkcs7PaddingCorrupted) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.TripleDesEncryptionKey(168)
.BlockMode(BlockMode::ECB)
@@ -3875,7 +3882,7 @@
*
* Verifies that NIST (plus a few extra) test vectors produce the correct results.
*/
-TEST_F(EncryptionOperationsTest, TripleDesTestVector) {
+TEST_P(EncryptionOperationsTest, TripleDesTestVector) {
constexpr size_t num_tests = sizeof(kTripleDesTestVectors) / sizeof(TripleDesTestVector);
for (auto* test = kTripleDesTestVectors; test < kTripleDesTestVectors + num_tests; ++test) {
SCOPED_TRACE(test->name);
@@ -3890,7 +3897,7 @@
*
* Validates CBC mode functionality.
*/
-TEST_F(EncryptionOperationsTest, TripleDesCbcRoundTripSuccess) {
+TEST_P(EncryptionOperationsTest, TripleDesCbcRoundTripSuccess) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.TripleDesEncryptionKey(168)
.BlockMode(BlockMode::CBC)
@@ -3919,7 +3926,7 @@
*
* Validates that 3DES keys can allow caller-specified IVs, and use them correctly.
*/
-TEST_F(EncryptionOperationsTest, TripleDesCallerIv) {
+TEST_P(EncryptionOperationsTest, TripleDesCallerIv) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.TripleDesEncryptionKey(168)
.BlockMode(BlockMode::CBC)
@@ -3954,7 +3961,7 @@
*
* Verifies that 3DES keys without TAG_CALLER_NONCE do not allow caller-specified IVS.
*/
-TEST_F(EncryptionOperationsTest, TripleDesCallerNonceProhibited) {
+TEST_P(EncryptionOperationsTest, TripleDesCallerNonceProhibited) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.TripleDesEncryptionKey(168)
.BlockMode(BlockMode::CBC)
@@ -3986,7 +3993,7 @@
*
* Verifies that 3DES ECB-only keys do not allow CBC usage.
*/
-TEST_F(EncryptionOperationsTest, TripleDesCbcNotAuthorized) {
+TEST_P(EncryptionOperationsTest, TripleDesCbcNotAuthorized) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.TripleDesEncryptionKey(168)
.BlockMode(BlockMode::ECB)
@@ -4004,7 +4011,7 @@
*
* Verifies that unpadded CBC operations reject inputs that are not a multiple of block size.
*/
-TEST_F(EncryptionOperationsTest, TripleDesCbcNoPaddingWrongInputSize) {
+TEST_P(EncryptionOperationsTest, TripleDesCbcNoPaddingWrongInputSize) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.TripleDesEncryptionKey(168)
.BlockMode(BlockMode::CBC)
@@ -4026,7 +4033,7 @@
*
* Verifies that PKCS7 padding works correctly in CBC mode.
*/
-TEST_F(EncryptionOperationsTest, TripleDesCbcPkcs7Padding) {
+TEST_P(EncryptionOperationsTest, TripleDesCbcPkcs7Padding) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.TripleDesEncryptionKey(168)
.BlockMode(BlockMode::CBC)
@@ -4049,7 +4056,7 @@
*
* Verifies that a key that requires PKCS7 padding cannot be used in unpadded mode.
*/
-TEST_F(EncryptionOperationsTest, TripleDesCbcNoPaddingKeyWithPkcs7Padding) {
+TEST_P(EncryptionOperationsTest, TripleDesCbcNoPaddingKeyWithPkcs7Padding) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.TripleDesEncryptionKey(168)
.BlockMode(BlockMode::CBC)
@@ -4069,7 +4076,7 @@
*
* Verifies that corrupted PKCS7 padding is rejected during decryption.
*/
-TEST_F(EncryptionOperationsTest, TripleDesCbcPkcs7PaddingCorrupted) {
+TEST_P(EncryptionOperationsTest, TripleDesCbcPkcs7PaddingCorrupted) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.TripleDesEncryptionKey(168)
.BlockMode(BlockMode::CBC)
@@ -4100,7 +4107,7 @@
*
* Verifies that 3DES CBC works with many different input sizes.
*/
-TEST_F(EncryptionOperationsTest, TripleDesCbcIncrementalNoPadding) {
+TEST_P(EncryptionOperationsTest, TripleDesCbcIncrementalNoPadding) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.TripleDesEncryptionKey(168)
.BlockMode(BlockMode::CBC)
@@ -4145,7 +4152,7 @@
*
* Verifies that the max uses per boot tag works correctly with AES keys.
*/
-TEST_F(MaxOperationsTest, TestLimitAes) {
+TEST_P(MaxOperationsTest, TestLimitAes) {
if (SecLevel() == SecurityLevel::STRONGBOX) return;
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
@@ -4172,7 +4179,7 @@
*
* Verifies that the max uses per boot tag works correctly with RSA keys.
*/
-TEST_F(MaxOperationsTest, TestLimitRsa) {
+TEST_P(MaxOperationsTest, TestLimitRsa) {
if (SecLevel() == SecurityLevel::STRONGBOX) return;
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
@@ -4201,7 +4208,7 @@
* Verifies that the addRngEntropy method doesn't blow up. There's no way to test that entropy is
* actually added.
*/
-TEST_F(AddEntropyTest, AddEntropy) {
+TEST_P(AddEntropyTest, AddEntropy) {
EXPECT_EQ(ErrorCode::OK, keymaster().addRngEntropy(HidlBuf("foo")));
}
@@ -4210,7 +4217,7 @@
*
* Verifies that the addRngEntropy method doesn't blow up when given an empty buffer.
*/
-TEST_F(AddEntropyTest, AddEmptyEntropy) {
+TEST_P(AddEntropyTest, AddEmptyEntropy) {
EXPECT_EQ(ErrorCode::OK, keymaster().addRngEntropy(HidlBuf()));
}
@@ -4219,7 +4226,7 @@
*
* Verifies that the addRngEntropy method doesn't blow up when given a largish amount of data.
*/
-TEST_F(AddEntropyTest, AddLargeEntropy) {
+TEST_P(AddEntropyTest, AddLargeEntropy) {
EXPECT_EQ(ErrorCode::OK, keymaster().addRngEntropy(HidlBuf(string(2 * 1024, 'a'))));
}
@@ -4230,7 +4237,7 @@
*
* Verifies that attesting to RSA keys works and generates the expected output.
*/
-TEST_F(AttestationTest, RsaAttestation) {
+TEST_P(AttestationTest, RsaAttestation) {
auto creation_time = std::chrono::system_clock::now();
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
@@ -4264,7 +4271,7 @@
*
* Verifies that attesting to RSA requires app ID.
*/
-TEST_F(AttestationTest, RsaAttestationRequiresAppId) {
+TEST_P(AttestationTest, RsaAttestationRequiresAppId) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.RsaSigningKey(2048, 65537)
@@ -4284,7 +4291,7 @@
*
* Verifies that attesting to EC keys works and generates the expected output.
*/
-TEST_F(AttestationTest, EcAttestation) {
+TEST_P(AttestationTest, EcAttestation) {
auto creation_time = std::chrono::system_clock::now();
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
@@ -4315,7 +4322,7 @@
*
* Verifies that attesting to EC keys requires app ID
*/
-TEST_F(AttestationTest, EcAttestationRequiresAttestationAppId) {
+TEST_P(AttestationTest, EcAttestationRequiresAttestationAppId) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.EcdsaSigningKey(EcCurve::P_256)
@@ -4337,7 +4344,7 @@
* byte. Proper DER encoding specifies that for lengths greather than 127, one byte should be used
* to specify how many following bytes will be used to encode the length.
*/
-TEST_F(AttestationTest, AttestationApplicationIDLengthProperlyEncoded) {
+TEST_P(AttestationTest, AttestationApplicationIDLengthProperlyEncoded) {
std::vector<uint32_t> app_id_lengths{143, 258};
for (uint32_t length : app_id_lengths) {
auto creation_time = std::chrono::system_clock::now();
@@ -4367,7 +4374,7 @@
*
* Verifies that attesting to AES keys fails in the expected way.
*/
-TEST_F(AttestationTest, AesAttestation) {
+TEST_P(AttestationTest, AesAttestation) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.AesEncryptionKey(128)
@@ -4387,7 +4394,7 @@
*
* Verifies that attesting to HMAC keys fails in the expected way.
*/
-TEST_F(AttestationTest, HmacAttestation) {
+TEST_P(AttestationTest, HmacAttestation) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.HmacKey(128)
@@ -4411,7 +4418,7 @@
* This test checks that if rollback protection is implemented, DeleteKey invalidates a formerly
* valid key blob.
*/
-TEST_F(KeyDeletionTest, DeleteKey) {
+TEST_P(KeyDeletionTest, DeleteKey) {
auto error = GenerateKey(AuthorizationSetBuilder()
.RsaSigningKey(2048, 65537)
.Digest(Digest::NONE)
@@ -4443,7 +4450,7 @@
*
* This test checks that the HAL excepts invalid key blobs..
*/
-TEST_F(KeyDeletionTest, DeleteInvalidKey) {
+TEST_P(KeyDeletionTest, DeleteInvalidKey) {
// Generate key just to check if rollback protection is implemented
auto error = GenerateKey(AuthorizationSetBuilder()
.RsaSigningKey(2048, 65537)
@@ -4479,7 +4486,7 @@
* been provisioned. Use this test only on dedicated testing devices that have no valuable
* credentials stored in Keystore/Keymaster.
*/
-TEST_F(KeyDeletionTest, DeleteAllKeys) {
+TEST_P(KeyDeletionTest, DeleteAllKeys) {
if (!arm_deleteAllKeys) return;
auto error = GenerateKey(AuthorizationSetBuilder()
.RsaSigningKey(2048, 65537)
@@ -4515,7 +4522,7 @@
*
* Verifies that calling upgrade key on an up-to-date key works (i.e. does nothing).
*/
-TEST_F(UpgradeKeyTest, UpgradeKey) {
+TEST_P(UpgradeKeyTest, UpgradeKey) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.AesEncryptionKey(128)
.Padding(PaddingMode::NONE)
@@ -4527,7 +4534,6 @@
EXPECT_EQ(result, std::make_pair(ErrorCode::OK, HidlBuf()));
}
-
using ClearOperationsTest = KeymasterHidlTest;
/*
@@ -4538,7 +4544,7 @@
* that aborting the operations clears the operations.
*
*/
-TEST_F(ClearOperationsTest, TooManyOperations) {
+TEST_P(ClearOperationsTest, TooManyOperations) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.RsaEncryptionKey(2048, 65537)
@@ -4570,8 +4576,7 @@
* Verifies that the service is restarted after death and the ongoing
* operations are cleared.
*/
-TEST_F(ClearOperationsTest, ServiceDeath) {
-
+TEST_P(ClearOperationsTest, ServiceDeath) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.RsaEncryptionKey(2048, 65537)
@@ -4611,7 +4616,7 @@
*
* Verifies that passing large input data to finish either succeeds or fails as expected.
*/
-TEST_F(TransportLimitTest, LargeFinishInput) {
+TEST_P(TransportLimitTest, LargeFinishInput) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.AesEncryptionKey(128)
@@ -4656,18 +4661,53 @@
CheckedDeleteKey();
}
+static const auto kKeymasterDeviceChoices =
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(IKeymasterDevice::descriptor));
+
+INSTANTIATE_TEST_SUITE_P(PerInstance, NewKeyGenerationTest, kKeymasterDeviceChoices,
+ android::hardware::PrintInstanceNameToString);
+
+INSTANTIATE_TEST_SUITE_P(PerInstance, ImportKeyTest, kKeymasterDeviceChoices,
+ android::hardware::PrintInstanceNameToString);
+
+INSTANTIATE_TEST_SUITE_P(PerInstance, ImportWrappedKeyTest, kKeymasterDeviceChoices,
+ android::hardware::PrintInstanceNameToString);
+
+INSTANTIATE_TEST_SUITE_P(PerInstance, SigningOperationsTest, kKeymasterDeviceChoices,
+ android::hardware::PrintInstanceNameToString);
+
+INSTANTIATE_TEST_SUITE_P(PerInstance, VerificationOperationsTest, kKeymasterDeviceChoices,
+ android::hardware::PrintInstanceNameToString);
+
+INSTANTIATE_TEST_SUITE_P(PerInstance, ExportKeyTest, kKeymasterDeviceChoices,
+ android::hardware::PrintInstanceNameToString);
+
+INSTANTIATE_TEST_SUITE_P(PerInstance, EncryptionOperationsTest, kKeymasterDeviceChoices,
+ android::hardware::PrintInstanceNameToString);
+
+INSTANTIATE_TEST_SUITE_P(PerInstance, MaxOperationsTest, kKeymasterDeviceChoices,
+ android::hardware::PrintInstanceNameToString);
+
+INSTANTIATE_TEST_SUITE_P(PerInstance, AddEntropyTest, kKeymasterDeviceChoices,
+ android::hardware::PrintInstanceNameToString);
+
+INSTANTIATE_TEST_SUITE_P(PerInstance, AttestationTest, kKeymasterDeviceChoices,
+ android::hardware::PrintInstanceNameToString);
+
+INSTANTIATE_TEST_SUITE_P(PerInstance, KeyDeletionTest, kKeymasterDeviceChoices,
+ android::hardware::PrintInstanceNameToString);
+
+INSTANTIATE_TEST_SUITE_P(PerInstance, TransportLimitTest, kKeymasterDeviceChoices,
+ android::hardware::PrintInstanceNameToString);
+
} // namespace test
} // namespace V4_0
} // namespace keymaster
} // namespace hardware
} // namespace android
-using android::hardware::keymaster::V4_0::test::KeymasterHidlEnvironment;
-
int main(int argc, char** argv) {
- ::testing::AddGlobalTestEnvironment(KeymasterHidlEnvironment::Instance());
::testing::InitGoogleTest(&argc, argv);
- KeymasterHidlEnvironment::Instance()->init(&argc, argv);
for (int i = 1; i < argc; ++i) {
if (argv[i][0] == '-') {
if (std::string(argv[i]) == "--arm_deleteAllKeys") {
diff --git a/keymaster/4.0/vts/performance/Android.bp b/keymaster/4.0/vts/performance/Android.bp
new file mode 100644
index 0000000..9434bc9
--- /dev/null
+++ b/keymaster/4.0/vts/performance/Android.bp
@@ -0,0 +1,29 @@
+//
+// Copyright (C) 2019 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.
+//
+
+cc_benchmark {
+ name: "keymaster_benchmark",
+ defaults: ["VtsHalTargetTestDefaults"],
+ srcs: [
+ "Benchmark.cpp",
+ ],
+ static_libs: [
+ "android.hardware.keymaster@4.0",
+ "libkeymaster4support",
+ "libsoftkeymasterdevice",
+ "libchrome"
+ ],
+}
diff --git a/keymaster/4.0/vts/performance/Benchmark.cpp b/keymaster/4.0/vts/performance/Benchmark.cpp
new file mode 100644
index 0000000..96ef5bf
--- /dev/null
+++ b/keymaster/4.0/vts/performance/Benchmark.cpp
@@ -0,0 +1,717 @@
+/*
+ * Copyright (C) 2019 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 "keymaster_benchmark"
+
+#include <android/hardware/keymaster/4.0/IKeymasterDevice.h>
+#include <android/hardware/keymaster/4.0/types.h>
+#include <keymaster/keymaster_configuration.h>
+#include <keymasterV4_0/authorization_set.h>
+
+#include <android/hidl/manager/1.0/IServiceManager.h>
+#include <binder/IServiceManager.h>
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include <iostream>
+
+#include <log/log.h>
+#include <utils/StrongPointer.h>
+
+#include <benchmark/benchmark.h>
+#include <hidl/Status.h>
+
+#include <base/command_line.h>
+
+namespace android {
+namespace hardware {
+namespace keymaster {
+namespace V4_0 {
+namespace test {
+
+// libutils:
+using android::OK;
+using android::sp;
+using android::status_t;
+
+// libhidl:
+using android::hardware::hidl_vec;
+using android::hardware::Return;
+using android::hardware::Void;
+
+// IKeymaster:
+using android::IServiceManager;
+using android::hardware::hidl_string;
+using android::hardware::keymaster::V4_0::AuthorizationSet;
+using android::hardware::keymaster::V4_0::AuthorizationSetBuilder;
+using android::hardware::keymaster::V4_0::BlockMode;
+using android::hardware::keymaster::V4_0::ErrorCode;
+using android::hardware::keymaster::V4_0::IKeymasterDevice;
+using android::hardware::keymaster::V4_0::KeyCharacteristics;
+using android::hardware::keymaster::V4_0::SecurityLevel;
+
+// Standard library:
+using std::cerr;
+using std::cout;
+using std::endl;
+using std::optional;
+using std::string;
+using std::unique_ptr;
+using std::vector;
+
+class HidlBuf : public hidl_vec<uint8_t> {
+ typedef hidl_vec<uint8_t> super;
+
+ public:
+ HidlBuf() {}
+ HidlBuf(const super& other) : super(other) {}
+ HidlBuf(super&& other) : super(std::move(other)) {}
+ explicit HidlBuf(const std::string& other) : HidlBuf() { *this = other; }
+
+ HidlBuf& operator=(const super& other) {
+ super::operator=(other);
+ return *this;
+ }
+
+ HidlBuf& operator=(super&& other) {
+ super::operator=(std::move(other));
+ return *this;
+ }
+
+ HidlBuf& operator=(const string& other) {
+ resize(other.size());
+ std::copy(other.begin(), other.end(), begin());
+ return *this;
+ }
+
+ string to_string() const { return string(reinterpret_cast<const char*>(data()), size()); }
+};
+
+#define SMALL_MESSAGE_SIZE 64
+#define MEDIUM_MESSAGE_SIZE 1024
+#define LARGE_MESSAGE_SIZE 131072
+
+class KeymasterWrapper {
+ private:
+ sp<IKeymasterDevice> keymaster_;
+ SecurityLevel securityLevel_;
+ hidl_string name_;
+ hidl_string author_;
+ HidlBuf key_blob_;
+ KeyCharacteristics key_characteristics_;
+ ErrorCode error_;
+ string key_transform_;
+ string keymaster_name_;
+ uint32_t os_version_;
+ uint32_t os_patch_level_;
+ std::vector<string> message_cache_;
+
+ bool GenerateKey(const AuthorizationSet& authSet) {
+ return (keymaster_
+ ->generateKey(
+ authSet.hidl_data(),
+ [&](ErrorCode hidl_error, const hidl_vec<uint8_t>& hidl_key_blob,
+ const KeyCharacteristics& hidl_key_characteristics) {
+ error_ = hidl_error;
+ key_blob_ = hidl_key_blob;
+ key_characteristics_ = std::move(hidl_key_characteristics);
+ })
+ .isOk() &&
+ error_ == ErrorCode::OK);
+ }
+
+ bool GenerateKey(Algorithm algorithm, int keySize, Digest digest = Digest::NONE,
+ PaddingMode padding = PaddingMode::NONE, optional<BlockMode> blockMode = {}) {
+ AuthorizationSetBuilder authSet = AuthorizationSetBuilder()
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .Authorization(TAG_PURPOSE, KeyPurpose::ENCRYPT)
+ .Authorization(TAG_PURPOSE, KeyPurpose::DECRYPT)
+ .Authorization(TAG_PURPOSE, KeyPurpose::SIGN)
+ .Authorization(TAG_PURPOSE, KeyPurpose::VERIFY)
+ .Authorization(TAG_KEY_SIZE, keySize)
+ .Authorization(TAG_ALGORITHM, algorithm)
+ .Digest(digest)
+ .Authorization(TAG_MIN_MAC_LENGTH, 128)
+ .Padding(padding);
+ if (blockMode) {
+ authSet.BlockMode(*blockMode);
+ }
+ if (algorithm == Algorithm::RSA) {
+ authSet.Authorization(TAG_RSA_PUBLIC_EXPONENT, 65537U);
+ }
+ return GenerateKey(authSet);
+ }
+
+ KeymasterWrapper(const sp<IKeymasterDevice> keymaster) {
+ os_version_ = ::keymaster::GetOsVersion();
+ os_patch_level_ = ::keymaster::GetOsPatchlevel();
+ keymaster_ = keymaster;
+ keymaster_->getHardwareInfo([&](SecurityLevel securityLevel, const hidl_string& name,
+ const hidl_string& author) {
+ securityLevel_ = securityLevel;
+ name_ = name;
+ author_ = author;
+ });
+
+ message_cache_.push_back(string(SMALL_MESSAGE_SIZE, 'x'));
+ message_cache_.push_back(string(MEDIUM_MESSAGE_SIZE, 'x'));
+ message_cache_.push_back(string(LARGE_MESSAGE_SIZE, 'x'));
+ }
+
+ public:
+ static KeymasterWrapper* newInstance(const std::string& keymaster_name) {
+ auto keymaster = IKeymasterDevice::getService(keymaster_name);
+ if (!keymaster) {
+ std::cerr << "Error: unable to find keymaster service named " << keymaster_name
+ << std::endl;
+ return nullptr;
+ }
+ return new KeymasterWrapper(keymaster);
+ }
+
+ bool GenerateKey(string transform, int keySize, bool sign = false) {
+ if (transform == key_transform_) {
+ return true;
+ } else if (key_transform_ != "") {
+ // Deleting old key first
+ if (!DeleteKey()) {
+ return false;
+ }
+ }
+ optional<Algorithm> algorithm = getAlgorithm(transform);
+ if (!algorithm) {
+ cerr << "Error: invalid algorithm " << transform << endl;
+ return false;
+ }
+ key_transform_ = transform;
+ return GenerateKey(*algorithm, keySize, getDigest(transform), getPadding(transform, sign),
+ getBlockMode(transform));
+ }
+
+ bool DeleteKey() {
+ key_blob_ = HidlBuf();
+ key_transform_ = "";
+ return keymaster_->deleteKey(key_blob_).isOk();
+ }
+
+ AuthorizationSet getOperationParams(string transform, bool sign = false) {
+ AuthorizationSetBuilder builder = AuthorizationSetBuilder()
+ .Padding(getPadding(transform, sign))
+ .Authorization(TAG_MAC_LENGTH, 128)
+ .Digest(getDigest(transform));
+ optional<BlockMode> blockMode = getBlockMode(transform);
+ if (blockMode) {
+ builder.BlockMode(*blockMode);
+ }
+ return std::move(builder);
+ }
+
+ optional<OperationHandle> EncryptBegin(AuthorizationSet& in_params,
+ AuthorizationSet* out_params = new AuthorizationSet) {
+ return Begin(KeyPurpose::ENCRYPT, in_params, out_params);
+ }
+
+ optional<OperationHandle> DecryptBegin(AuthorizationSet& in_params,
+ AuthorizationSet* out_params = new AuthorizationSet) {
+ return Begin(KeyPurpose::DECRYPT, in_params, out_params);
+ }
+
+ optional<OperationHandle> SignBegin(AuthorizationSet& in_params,
+ AuthorizationSet* out_params = new AuthorizationSet) {
+ return Begin(KeyPurpose::SIGN, in_params, out_params);
+ }
+
+ optional<OperationHandle> VerifyBegin(AuthorizationSet& in_params,
+ AuthorizationSet* out_params = new AuthorizationSet) {
+ return Begin(KeyPurpose::VERIFY, in_params, out_params);
+ }
+
+ optional<OperationHandle> Begin(KeyPurpose operation, const AuthorizationSet& in_params,
+ AuthorizationSet* out_params) {
+ OperationHandle op_handle;
+ if (!keymaster_
+ ->begin(operation, key_blob_, in_params.hidl_data(), HardwareAuthToken(),
+ [&](ErrorCode hidl_error,
+ const hidl_vec<KeyParameter>& hidl_out_params,
+ uint64_t hidl_op_handle) {
+ error_ = hidl_error;
+ out_params->push_back(AuthorizationSet(hidl_out_params));
+ op_handle = hidl_op_handle;
+ })
+ .isOk() ||
+ error_ != ErrorCode::OK) {
+ keymaster_->abort(op_handle);
+ return {};
+ }
+ return op_handle;
+ }
+
+ optional<string> ProcessMessage(const OperationHandle& op_handle, const string& message,
+ const AuthorizationSet& in_params,
+ AuthorizationSet* out_params = new AuthorizationSet,
+ const string& signature = "") {
+ static const int HIDL_BUFFER_LIMIT = 1 << 14; // 16KB
+
+ string output;
+ size_t input_consumed = 0;
+ while (message.length() - input_consumed > 0) {
+ if (!keymaster_
+ ->update(op_handle, in_params.hidl_data(),
+ HidlBuf(message.substr(input_consumed, HIDL_BUFFER_LIMIT)),
+ HardwareAuthToken(), VerificationToken(),
+ [&](ErrorCode hidl_error, uint32_t hidl_input_consumed,
+ const hidl_vec<KeyParameter>& hidl_out_params,
+ const HidlBuf& hidl_output) {
+ error_ = hidl_error;
+ out_params->push_back(AuthorizationSet(hidl_out_params));
+ output.append(hidl_output.to_string());
+ input_consumed += hidl_input_consumed;
+ })
+ .isOk() ||
+ error_ != ErrorCode::OK) {
+ keymaster_->abort(op_handle);
+ return {};
+ }
+ }
+
+ if (!keymaster_
+ ->finish(op_handle, in_params.hidl_data(),
+ HidlBuf(message.substr(input_consumed)), HidlBuf(signature),
+ HardwareAuthToken(), VerificationToken(),
+ [&](ErrorCode hidl_error,
+ const hidl_vec<KeyParameter>& hidl_out_params,
+ const HidlBuf& hidl_output) {
+ error_ = hidl_error;
+ out_params->push_back(AuthorizationSet(hidl_out_params));
+ output.append(hidl_output.to_string());
+ })
+ .isOk() ||
+ error_ != ErrorCode::OK) {
+ keymaster_->abort(op_handle);
+ return {};
+ }
+
+ return output;
+ }
+
+ int getError() { return static_cast<int>(error_); }
+
+ const string getHardwareName() { return name_; }
+
+ SecurityLevel getSecurityLevel() { return securityLevel_; }
+
+ const string& GenerateMessage(int size) {
+ for (const string& message : message_cache_) {
+ if (message.size() == size) {
+ return message;
+ }
+ }
+ string message = string(size, 'x');
+ message_cache_.push_back(message);
+ return std::move(message);
+ }
+
+ optional<BlockMode> getBlockMode(string transform) {
+ if (transform.find("/ECB") != string::npos) {
+ return BlockMode::ECB;
+ } else if (transform.find("/CBC") != string::npos) {
+ return BlockMode::CBC;
+ } else if (transform.find("/CTR") != string::npos) {
+ return BlockMode::CTR;
+ } else if (transform.find("/GCM") != string::npos) {
+ return BlockMode::GCM;
+ }
+ return {};
+ }
+
+ PaddingMode getPadding(string transform, bool sign) {
+ if (transform.find("/PKCS7") != string::npos) {
+ return PaddingMode::PKCS7;
+ } else if (transform.find("/PSS") != string::npos) {
+ return PaddingMode::RSA_PSS;
+ } else if (transform.find("/OAEP") != string::npos) {
+ return PaddingMode::RSA_OAEP;
+ } else if (transform.find("/PKCS1") != string::npos) {
+ return sign ? PaddingMode::RSA_PKCS1_1_5_SIGN : PaddingMode::RSA_PKCS1_1_5_ENCRYPT;
+ } else if (sign && transform.find("RSA") != string::npos) {
+ // RSA defaults to PKCS1 for sign
+ return PaddingMode::RSA_PKCS1_1_5_SIGN;
+ }
+ return PaddingMode::NONE;
+ }
+
+ optional<Algorithm> getAlgorithm(string transform) {
+ if (transform.find("AES") != string::npos) {
+ return Algorithm::AES;
+ } else if (transform.find("Hmac") != string::npos) {
+ return Algorithm::HMAC;
+ } else if (transform.find("DESede") != string::npos) {
+ return Algorithm::TRIPLE_DES;
+ } else if (transform.find("RSA") != string::npos) {
+ return Algorithm::RSA;
+ } else if (transform.find("EC") != string::npos) {
+ return Algorithm::EC;
+ }
+ cerr << "Can't find algorithm for " << transform << endl;
+ return {};
+ }
+
+ Digest getDigest(string transform) {
+ if (transform.find("MD5") != string::npos) {
+ return Digest::MD5;
+ } else if (transform.find("SHA1") != string::npos ||
+ transform.find("SHA-1") != string::npos) {
+ return Digest::SHA1;
+ } else if (transform.find("SHA224") != string::npos) {
+ return Digest::SHA_2_224;
+ } else if (transform.find("SHA256") != string::npos) {
+ return Digest::SHA_2_256;
+ } else if (transform.find("SHA384") != string::npos) {
+ return Digest::SHA_2_384;
+ } else if (transform.find("SHA512") != string::npos) {
+ return Digest::SHA_2_512;
+ } else if (transform.find("RSA") != string::npos &&
+ transform.find("OAEP") != string::npos) {
+ return Digest::SHA1;
+ }
+ return Digest::NONE;
+ }
+};
+
+KeymasterWrapper* keymaster;
+
+static void settings(benchmark::internal::Benchmark* benchmark) {
+ benchmark->Unit(benchmark::kMillisecond);
+}
+
+static void addDefaultLabel(benchmark::State& state) {
+ string secLevel;
+ switch (keymaster->getSecurityLevel()) {
+ case SecurityLevel::STRONGBOX:
+ secLevel = "STRONGBOX";
+ break;
+ case SecurityLevel::SOFTWARE:
+ secLevel = "SOFTWARE";
+ break;
+ case SecurityLevel::TRUSTED_ENVIRONMENT:
+ secLevel = "TEE";
+ break;
+ }
+ state.SetLabel("hardware_name:" + keymaster->getHardwareName() + " sec_level:" + secLevel);
+}
+
+// clang-format off
+#define BENCHMARK_KM(func, transform, keySize) \
+ BENCHMARK_CAPTURE(func, transform/keySize, #transform "/" #keySize, keySize)->Apply(settings);
+#define BENCHMARK_KM_MSG(func, transform, keySize, msgSize) \
+ BENCHMARK_CAPTURE(func, transform/keySize/msgSize, #transform "/" #keySize "/" #msgSize, \
+ keySize, msgSize) \
+ ->Apply(settings);
+
+#define BENCHMARK_KM_ALL_MSGS(func, transform, keySize) \
+ BENCHMARK_KM_MSG(func, transform, keySize, SMALL_MESSAGE_SIZE) \
+ BENCHMARK_KM_MSG(func, transform, keySize, MEDIUM_MESSAGE_SIZE) \
+ BENCHMARK_KM_MSG(func, transform, keySize, LARGE_MESSAGE_SIZE)
+
+#define BENCHMARK_KM_CIPHER(transform, keySize, msgSize) \
+ BENCHMARK_KM_MSG(encrypt, transform, keySize, msgSize) \
+ BENCHMARK_KM_MSG(decrypt, transform, keySize, msgSize)
+
+#define BENCHMARK_KM_CIPHER_ALL_MSGS(transform, keySize) \
+ BENCHMARK_KM_ALL_MSGS(encrypt, transform, keySize) \
+ BENCHMARK_KM_ALL_MSGS(decrypt, transform, keySize)
+
+#define BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, keySize) \
+ BENCHMARK_KM_ALL_MSGS(sign, transform, keySize) \
+ BENCHMARK_KM_ALL_MSGS(verify, transform, keySize)
+// clang-format on
+
+/*
+ * ============= KeyGen TESTS ==================
+ */
+static void keygen(benchmark::State& state, string transform, int keySize) {
+ addDefaultLabel(state);
+ for (auto _ : state) {
+ keymaster->GenerateKey(transform, keySize);
+ state.PauseTiming();
+ keymaster->DeleteKey();
+ state.ResumeTiming();
+ }
+}
+
+BENCHMARK_KM(keygen, AES, 128);
+BENCHMARK_KM(keygen, AES, 256);
+
+BENCHMARK_KM(keygen, RSA, 2048);
+BENCHMARK_KM(keygen, RSA, 3072);
+BENCHMARK_KM(keygen, RSA, 4096);
+
+BENCHMARK_KM(keygen, EC, 224);
+BENCHMARK_KM(keygen, EC, 256);
+BENCHMARK_KM(keygen, EC, 384);
+BENCHMARK_KM(keygen, EC, 521);
+
+BENCHMARK_KM(keygen, DESede, 168);
+
+BENCHMARK_KM(keygen, Hmac, 64);
+BENCHMARK_KM(keygen, Hmac, 128);
+BENCHMARK_KM(keygen, Hmac, 256);
+BENCHMARK_KM(keygen, Hmac, 512);
+BENCHMARK_KM(keygen, Hmac, 1024);
+BENCHMARK_KM(keygen, Hmac, 2048);
+BENCHMARK_KM(keygen, Hmac, 4096);
+BENCHMARK_KM(keygen, Hmac, 8192);
+
+/*
+ * ============= SIGNATURE TESTS ==================
+ */
+
+static void sign(benchmark::State& state, string transform, int keySize, int msgSize) {
+ addDefaultLabel(state);
+ if (!keymaster->GenerateKey(transform, keySize, true)) {
+ state.SkipWithError(
+ ("Key generation error, " + std::to_string(keymaster->getError())).c_str());
+ return;
+ }
+ auto params = keymaster->getOperationParams(transform, true);
+ string message = keymaster->GenerateMessage(msgSize);
+
+ for (auto _ : state) {
+ state.PauseTiming();
+ auto opHandle = keymaster->SignBegin(params);
+ if (!opHandle) {
+ state.SkipWithError(
+ ("Error beginning sign, " + std::to_string(keymaster->getError())).c_str());
+ return;
+ }
+ state.ResumeTiming();
+ if (!keymaster->ProcessMessage(*opHandle, message, params)) {
+ state.SkipWithError(("Sign error, " + std::to_string(keymaster->getError())).c_str());
+ break;
+ }
+ }
+}
+
+static void verify(benchmark::State& state, string transform, int keySize, int msgSize) {
+ addDefaultLabel(state);
+ if (!keymaster->GenerateKey(transform, keySize, true)) {
+ state.SkipWithError(
+ ("Key generation error, " + std::to_string(keymaster->getError())).c_str());
+ return;
+ }
+ AuthorizationSet out_params;
+ AuthorizationSet in_params = keymaster->getOperationParams(transform, true);
+ string message = keymaster->GenerateMessage(msgSize);
+ auto opHandle = keymaster->SignBegin(in_params, &out_params);
+ if (!opHandle) {
+ state.SkipWithError(
+ ("Error beginning sign, " + std::to_string(keymaster->getError())).c_str());
+ return;
+ }
+ optional<string> signature =
+ keymaster->ProcessMessage(*opHandle, message, in_params, &out_params);
+ if (!signature) {
+ state.SkipWithError(("Sign error, " + std::to_string(keymaster->getError())).c_str());
+ return;
+ }
+ in_params.push_back(out_params);
+ for (auto _ : state) {
+ state.PauseTiming();
+ opHandle = keymaster->VerifyBegin(in_params);
+ if (!opHandle) {
+ state.SkipWithError(
+ ("Verify begin error, " + std::to_string(keymaster->getError())).c_str());
+ return;
+ }
+ state.ResumeTiming();
+ if (!keymaster->ProcessMessage(*opHandle, message, in_params, &out_params, *signature)) {
+ state.SkipWithError(("Verify error, " + std::to_string(keymaster->getError())).c_str());
+ break;
+ }
+ }
+}
+
+// clang-format off
+#define BENCHMARK_KM_SIGNATURE_ALL_HMAC_KEYS(transform) \
+ BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 64) \
+ BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 128) \
+ BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 256) \
+ BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 512) \
+ BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 1024) \
+ BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 2024) \
+ BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 4096) \
+ BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 8192)
+
+BENCHMARK_KM_SIGNATURE_ALL_HMAC_KEYS(HmacSHA1)
+BENCHMARK_KM_SIGNATURE_ALL_HMAC_KEYS(HmacSHA256)
+BENCHMARK_KM_SIGNATURE_ALL_HMAC_KEYS(HmacSHA224)
+BENCHMARK_KM_SIGNATURE_ALL_HMAC_KEYS(HmacSHA256)
+BENCHMARK_KM_SIGNATURE_ALL_HMAC_KEYS(HmacSHA384)
+BENCHMARK_KM_SIGNATURE_ALL_HMAC_KEYS(HmacSHA512)
+
+#define BENCHMARK_KM_SIGNATURE_ALL_ECDSA_KEYS(transform) \
+ BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 224) \
+ BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 256) \
+ BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 384) \
+ BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 521)
+
+BENCHMARK_KM_SIGNATURE_ALL_ECDSA_KEYS(NONEwithECDSA);
+BENCHMARK_KM_SIGNATURE_ALL_ECDSA_KEYS(SHA1withECDSA);
+BENCHMARK_KM_SIGNATURE_ALL_ECDSA_KEYS(SHA224withECDSA);
+BENCHMARK_KM_SIGNATURE_ALL_ECDSA_KEYS(SHA256withECDSA);
+BENCHMARK_KM_SIGNATURE_ALL_ECDSA_KEYS(SHA384withECDSA);
+BENCHMARK_KM_SIGNATURE_ALL_ECDSA_KEYS(SHA512withECDSA);
+
+#define BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(transform) \
+ BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 2048) \
+ BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 3072) \
+ BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 4096)
+
+BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(MD5withRSA);
+BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(SHA1withRSA);
+BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(SHA224withRSA);
+BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(SHA384withRSA);
+BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(SHA512withRSA);
+
+BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(MD5withRSA/PSS);
+BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(SHA1withRSA/PSS);
+BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(SHA224withRSA/PSS);
+BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(SHA384withRSA/PSS);
+BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(SHA512withRSA/PSS);
+// clang-format on
+
+/*
+ * ============= CIPHER TESTS ==================
+ */
+
+static void encrypt(benchmark::State& state, string transform, int keySize, int msgSize) {
+ addDefaultLabel(state);
+ if (!keymaster->GenerateKey(transform, keySize)) {
+ state.SkipWithError(
+ ("Key generation error, " + std::to_string(keymaster->getError())).c_str());
+ return;
+ }
+ auto params = keymaster->getOperationParams(transform);
+ string message = keymaster->GenerateMessage(msgSize);
+
+ for (auto _ : state) {
+ state.PauseTiming();
+ auto opHandle = keymaster->EncryptBegin(params);
+ if (!opHandle) {
+ state.SkipWithError(
+ ("Encryption begin error, " + std::to_string(keymaster->getError())).c_str());
+ return;
+ }
+ state.ResumeTiming();
+ if (!keymaster->ProcessMessage(*opHandle, message, params)) {
+ state.SkipWithError(
+ ("Encryption error, " + std::to_string(keymaster->getError())).c_str());
+ break;
+ }
+ }
+}
+
+static void decrypt(benchmark::State& state, string transform, int keySize, int msgSize) {
+ addDefaultLabel(state);
+ if (!keymaster->GenerateKey(transform, keySize)) {
+ state.SkipWithError(
+ ("Key generation error, " + std::to_string(keymaster->getError())).c_str());
+ return;
+ }
+ AuthorizationSet out_params;
+ AuthorizationSet in_params = keymaster->getOperationParams(transform);
+ string message = keymaster->GenerateMessage(msgSize);
+ auto opHandle = keymaster->EncryptBegin(in_params, &out_params);
+ if (!opHandle) {
+ state.SkipWithError(
+ ("Encryption begin error, " + std::to_string(keymaster->getError())).c_str());
+ return;
+ }
+ auto encryptedMessage = keymaster->ProcessMessage(*opHandle, message, in_params, &out_params);
+ if (!encryptedMessage) {
+ state.SkipWithError(("Encryption error, " + std::to_string(keymaster->getError())).c_str());
+ return;
+ }
+ in_params.push_back(out_params);
+ for (auto _ : state) {
+ state.PauseTiming();
+ opHandle = keymaster->DecryptBegin(in_params);
+ if (!opHandle) {
+ state.SkipWithError(
+ ("Decryption begin error, " + std::to_string(keymaster->getError())).c_str());
+ return;
+ }
+ state.ResumeTiming();
+ if (!keymaster->ProcessMessage(*opHandle, *encryptedMessage, in_params)) {
+ state.SkipWithError(
+ ("Decryption error, " + std::to_string(keymaster->getError())).c_str());
+ break;
+ }
+ }
+}
+
+// clang-format off
+// AES
+#define BENCHMARK_KM_CIPHER_ALL_AES_KEYS(transform) \
+ BENCHMARK_KM_CIPHER_ALL_MSGS(transform, 128) \
+ BENCHMARK_KM_CIPHER_ALL_MSGS(transform, 256)
+
+BENCHMARK_KM_CIPHER_ALL_AES_KEYS(AES/CBC/NoPadding);
+BENCHMARK_KM_CIPHER_ALL_AES_KEYS(AES/CBC/PKCS7Padding);
+BENCHMARK_KM_CIPHER_ALL_AES_KEYS(AES/CTR/NoPadding);
+BENCHMARK_KM_CIPHER_ALL_AES_KEYS(AES/ECB/NoPadding);
+BENCHMARK_KM_CIPHER_ALL_AES_KEYS(AES/ECB/PKCS7Padding);
+BENCHMARK_KM_CIPHER_ALL_AES_KEYS(AES/GCM/NoPadding);
+
+// Triple DES
+BENCHMARK_KM_CIPHER_ALL_MSGS(DESede/CBC/NoPadding, 168);
+BENCHMARK_KM_CIPHER_ALL_MSGS(DESede/CBC/PKCS7Padding, 168);
+BENCHMARK_KM_CIPHER_ALL_MSGS(DESede/ECB/NoPadding, 168);
+BENCHMARK_KM_CIPHER_ALL_MSGS(DESede/ECB/PKCS7Padding, 168);
+
+#define BENCHMARK_KM_CIPHER_ALL_RSA_KEYS(transform, msgSize) \
+ BENCHMARK_KM_CIPHER(transform, 2048, msgSize) \
+ BENCHMARK_KM_CIPHER(transform, 3072, msgSize) \
+ BENCHMARK_KM_CIPHER(transform, 4096, msgSize)
+
+BENCHMARK_KM_CIPHER_ALL_RSA_KEYS(RSA/ECB/NoPadding, SMALL_MESSAGE_SIZE);
+BENCHMARK_KM_CIPHER_ALL_RSA_KEYS(RSA/ECB/PKCS1Padding, SMALL_MESSAGE_SIZE);
+BENCHMARK_KM_CIPHER_ALL_RSA_KEYS(RSA/ECB/OAEPPadding, SMALL_MESSAGE_SIZE);
+// clang-format on
+
+} // namespace test
+} // namespace V4_0
+} // namespace keymaster
+} // namespace hardware
+} // namespace android
+
+int main(int argc, char** argv) {
+ ::benchmark::Initialize(&argc, argv);
+ base::CommandLine::Init(argc, argv);
+ base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
+ auto service_name = command_line->GetSwitchValueASCII("service_name");
+ if (service_name.empty()) {
+ service_name = "default";
+ }
+ android::hardware::keymaster::V4_0::test::keymaster =
+ android::hardware::keymaster::V4_0::test::KeymasterWrapper::newInstance(service_name);
+ if (!android::hardware::keymaster::V4_0::test::keymaster) {
+ return 1;
+ }
+ ::benchmark::RunSpecifiedBenchmarks();
+}
\ No newline at end of file
diff --git a/keymaster/4.0/vts/performance/README b/keymaster/4.0/vts/performance/README
new file mode 100644
index 0000000..57d984a
--- /dev/null
+++ b/keymaster/4.0/vts/performance/README
@@ -0,0 +1,19 @@
+# Keymaster Benchmark
+
+The Keymaster Benchmark is a standalone tool for measuring the performance of keymaster implementations.
+
+## Building
+
+Build:
+`m keymaster_benchmark`
+
+Transfer to device/emulator:
+`adb sync data`
+
+The benchmark executable should will be located at `data/benchmarktest/keymaster_benchmark/keymaster_benchmark` on the device.
+
+## Usage
+
+Keymaster Benchmark is built on [Google microbenchmark library](https://github.com/google/benchmark).
+All of the commandline arguments provided by the microbenchmark library are valid, such as `--benchmark_filter=<regex>` or `benchmark_out_format={json|console|csv}`.
+In addition to the command line arguments provided by microbenchmark, `--service_name=<service_name>` is provided allow specification of the keymaster service name, e.g. specify `--service_name=strongbox` to benchmark strongbox.
diff --git a/keymaster/4.1/Android.bp b/keymaster/4.1/Android.bp
index eaa7e41..3b505d8 100644
--- a/keymaster/4.1/Android.bp
+++ b/keymaster/4.1/Android.bp
@@ -12,6 +12,7 @@
"IOperation.hal",
],
interfaces: [
+ "android.hardware.keymaster@3.0",
"android.hardware.keymaster@4.0",
"android.hidl.base@1.0",
],
diff --git a/neuralnetworks/1.1/types.hal b/neuralnetworks/1.1/types.hal
index 3d78fb6..da7ba78 100644
--- a/neuralnetworks/1.1/types.hal
+++ b/neuralnetworks/1.1/types.hal
@@ -125,7 +125,7 @@
* Outputs:
* * 0: A tensor of the same {@link OperandType} as input0.
* For a {@link OperandType::TENSOR_QUANT8_ASYMM} tensor,
- * the scale and zeroPoint must be same as input0.
+ * the scale and zeroPoint must be the same as input0.
*/
MEAN = 31,
diff --git a/neuralnetworks/1.2/types.hal b/neuralnetworks/1.2/types.hal
index ef71ea8..b111d96 100644
--- a/neuralnetworks/1.2/types.hal
+++ b/neuralnetworks/1.2/types.hal
@@ -1954,7 +1954,7 @@
* Outputs:
* * 0: A tensor of the same {@link OperandType} as input0.
* For a {@link OperandType::TENSOR_QUANT8_ASYMM} tensor,
- * the scale and zeroPoint must be same as input0.
+ * the scale and zeroPoint must be the same as input0.
*/
MEAN = @1.1::OperationType:MEAN,
diff --git a/neuralnetworks/1.2/vts/functional/GeneratedTestHarness.cpp b/neuralnetworks/1.2/vts/functional/GeneratedTestHarness.cpp
index c1bf494..4909214 100644
--- a/neuralnetworks/1.2/vts/functional/GeneratedTestHarness.cpp
+++ b/neuralnetworks/1.2/vts/functional/GeneratedTestHarness.cpp
@@ -29,13 +29,14 @@
#include <android/hardware/neuralnetworks/1.2/IPreparedModelCallback.h>
#include <android/hidl/allocator/1.0/IAllocator.h>
#include <android/hidl/memory/1.0/IMemory.h>
+#include <gtest/gtest.h>
#include <hidlmemory/mapping.h>
-#include <gtest/gtest.h>
#include <algorithm>
#include <chrono>
#include <iostream>
#include <numeric>
+#include <vector>
#include "1.0/Utils.h"
#include "1.2/Callbacks.h"
@@ -333,9 +334,9 @@
void EvaluatePreparedModel(const sp<IPreparedModel>& preparedModel, const TestModel& testModel,
bool testDynamicOutputShape) {
- std::initializer_list<OutputType> outputTypesList;
- std::initializer_list<MeasureTiming> measureTimingList;
- std::initializer_list<Executor> executorList;
+ std::vector<OutputType> outputTypesList;
+ std::vector<MeasureTiming> measureTimingList;
+ std::vector<Executor> executorList;
if (testDynamicOutputShape) {
outputTypesList = {OutputType::UNSPECIFIED, OutputType::INSUFFICIENT};
diff --git a/neuralnetworks/1.3/IPreparedModel.hal b/neuralnetworks/1.3/IPreparedModel.hal
index c04809f..7aea416 100644
--- a/neuralnetworks/1.3/IPreparedModel.hal
+++ b/neuralnetworks/1.3/IPreparedModel.hal
@@ -18,9 +18,11 @@
import @1.0::ErrorStatus;
import @1.0::Request;
-import @1.2::MeasureTiming;
import @1.2::IExecutionCallback;
import @1.2::IPreparedModel;
+import @1.2::MeasureTiming;
+import @1.2::OutputShape;
+import @1.2::Timing;
/**
* IPreparedModel describes a model that has been prepared for execution and
@@ -62,8 +64,8 @@
* values, the execution should complete successfully (ErrorStatus::NONE):
* There must be no failure unless the device itself is in a bad state.
*
- * Any number of calls to the execute, execute_1_2, execute_1_3, and executeSynchronously
- * functions, in any combination, may be made concurrently, even on the same
+ * Any number of calls to the execute* and executeSynchronously* functions,
+ * in any combination, may be made concurrently, even on the same
* IPreparedModel object.
*
* @param request The input and output information on which the prepared
@@ -87,4 +89,60 @@
*/
execute_1_3(Request request, MeasureTiming measure, IExecutionCallback callback)
generates (ErrorStatus status);
+
+ /**
+ * Performs a synchronous execution on a prepared model.
+ *
+ * The execution is performed synchronously with respect to the caller.
+ * executeSynchronously_1_3 must verify the inputs to the function are
+ * correct. If there is an error, executeSynchronously_1_3 must immediately
+ * return with the appropriate ErrorStatus value. If the inputs to the
+ * function are valid and there is no error, executeSynchronously_1_3 must
+ * perform the execution, and must not return until the execution is
+ * complete.
+ *
+ * The caller must not change the content of any data object referenced by
+ * 'request' (described by the {@link @1.0::DataLocation} of a
+ * {@link @1.0::RequestArgument}) until executeSynchronously_1_3
+ * returns. executeSynchronously_1_3 must not change the content of any of the
+ * data objects corresponding to 'request' inputs.
+ *
+ * If the prepared model was prepared from a model wherein all tensor
+ * operands have fully specified dimensions, and the inputs to the function
+ * are valid, and at execution time every operation's input operands have
+ * legal values, then the execution should complete successfully
+ * (ErrorStatus::NONE): There must be no failure unless the device itself is
+ * in a bad state.
+ *
+ * Any number of calls to the execute* and executeSynchronously* functions,
+ * in any combination, may be made concurrently, even on the same
+ * IPreparedModel object.
+ *
+ * @param request The input and output information on which the prepared
+ * model is to be executed.
+ * @param measure Specifies whether or not to measure duration of the execution.
+ * The duration runs from the time the driver sees the call
+ * to the executeSynchronously_1_3 function to the time the driver
+ * returns from the function.
+ * @return status Error status of the execution, must be:
+ * - NONE if execution is performed successfully
+ * - DEVICE_UNAVAILABLE if driver is offline or busy
+ * - GENERAL_FAILURE if there is an unspecified error
+ * - OUTPUT_INSUFFICIENT_SIZE if at least one output
+ * operand buffer is not large enough to store the
+ * corresponding output
+ * - INVALID_ARGUMENT if one of the input arguments is
+ * invalid
+ * @return outputShapes A list of shape information of model output operands.
+ * The index into "outputShapes" corresponds to the index
+ * of the output operand in the Request outputs vector.
+ * outputShapes must be empty unless the status is either
+ * NONE or OUTPUT_INSUFFICIENT_SIZE.
+ * @return Timing Duration of execution. Unless measure is YES and status is
+ * NONE, all times must be reported as UINT64_MAX. A driver may
+ * choose to report any time as UINT64_MAX, indicating that
+ * measurement is not available.
+ */
+ executeSynchronously_1_3(Request request, MeasureTiming measure)
+ generates (ErrorStatus status, vec<OutputShape> outputShapes, Timing timing);
};
diff --git a/neuralnetworks/1.3/types.hal b/neuralnetworks/1.3/types.hal
index db86bf6..84c4813 100644
--- a/neuralnetworks/1.3/types.hal
+++ b/neuralnetworks/1.3/types.hal
@@ -149,6 +149,7 @@
* * {@link OperandType::TENSOR_FLOAT16} (since HAL version 1.2)
* * {@link OperandType::TENSOR_FLOAT32}
* * {@link OperandType::TENSOR_QUANT8_ASYMM}
+ * * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} (since HAL version 1.3)
*
* Supported tensor rank: 4, with "NHWC" or "NCHW" data layout.
* With the default data layout NHWC, the data is stored in the order of:
@@ -210,7 +211,8 @@
* Outputs:
* * 0: The output 4-D tensor, of shape
* [batches, out_height, out_width, depth].
- * For a {@link OperandType::TENSOR_QUANT8_ASYMM} tensor,
+ * For a {@link OperandType::TENSOR_QUANT8_ASYMM} and
+ * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} tensor,
* the scale and zeroPoint must be the same as input0.
*/
AVERAGE_POOL_2D = @1.2::OperationType:AVERAGE_POOL_2D,
@@ -226,6 +228,7 @@
* * {@link OperandType::TENSOR_FLOAT32}
* * {@link OperandType::TENSOR_QUANT8_ASYMM}
* (full support since HAL version 1.2, see the input section)
+ * * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} (since HAL version 1.3)
*
* Supported tensor rank: up to 4
*
@@ -235,6 +238,9 @@
* Before HAL version 1.2, all input tensors of
* {@link OperandType::TENSOR_QUANT8_ASYMM}
* must have the same scale and zeroPoint as the output tensor.
+ * Input tensors of
+ * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED}
+ * are allowed to have different scale and zeroPoint.
* Since HAL version 1.2, zero-sized tensors are supported.
* * n: An {@link OperandType::INT32} scalar, specifying the
* concatenation axis.
@@ -245,6 +251,8 @@
* Since HAL version 1.2, for a {@link OperandType::TENSOR_QUANT8_ASYMM} tensor,
* the scale and zeroPoint values can be different from
* input tensors. Before HAL version 1.2 they have to be the same as for the input tensors.
+ * For a {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} tensor,
+ * the scale and zeroPoint values can be different from input tensors.
*/
CONCATENATION = @1.2::OperationType:CONCATENATION,
@@ -954,6 +962,7 @@
* * {@link OperandType::TENSOR_FLOAT16} (since HAL version 1.2)
* * {@link OperandType::TENSOR_FLOAT32}
* * {@link OperandType::TENSOR_QUANT8_ASYMM}
+ * * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} (since HAL version 1.3)
*
* Supported tensor rank: up to 4.
*
@@ -965,6 +974,8 @@
* * 0: The output tensor of same shape as input0.
* For {@link OperandType::TENSOR_QUANT8_ASYMM},
* the scale must be 1.f / 256 and the zeroPoint must be 0.
+ * For {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED},
+ * the scale must be 1.f / 256 and the zeroPoint must be -128.
*/
LOGISTIC = @1.2::OperationType:LOGISTIC,
@@ -1259,6 +1270,7 @@
* * {@link OperandType::TENSOR_FLOAT16} (since HAL version 1.2)
* * {@link OperandType::TENSOR_FLOAT32}
* * {@link OperandType::TENSOR_QUANT8_ASYMM}
+ * * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} (since HAL version 1.3)
*
* Supported tensor rank: 4, with "NHWC" or "NCHW" data layout.
* With the default data layout NHWC, the data is stored in the order of:
@@ -1320,7 +1332,8 @@
* Outputs:
* * 0: The output 4-D tensor, of shape
* [batches, out_height, out_width, depth].
- * For a {@link OperandType::TENSOR_QUANT8_ASYMM} tensor,
+ * For a {@link OperandType::TENSOR_QUANT8_ASYMM} and
+ * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} tensor,
* the scale and zeroPoint must be the same as input0.
*/
MAX_POOL_2D = @1.2::OperationType:MAX_POOL_2D,
@@ -1380,6 +1393,7 @@
* * {@link OperandType::TENSOR_FLOAT16} (since HAL version 1.2)
* * {@link OperandType::TENSOR_FLOAT32}
* * {@link OperandType::TENSOR_QUANT8_ASYMM}
+ * * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} (since HAL version 1.3)
*
* Supported tensor rank: up to 4.
*
@@ -1389,7 +1403,8 @@
*
* Outputs:
* * 0: The output tensor of same shape as input0.
- * For a {@link OperandType::TENSOR_QUANT8_ASYMM} tensor,
+ * For a {@link OperandType::TENSOR_QUANT8_ASYMM} and
+ * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} tensor,
* the scale and zeroPoint must be the same as input0.
*/
RELU = @1.2::OperationType:RELU,
@@ -1405,6 +1420,7 @@
* * {@link OperandType::TENSOR_FLOAT16} (since HAL version 1.2)
* * {@link OperandType::TENSOR_FLOAT32}
* * {@link OperandType::TENSOR_QUANT8_ASYMM}
+ * * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} (since HAL version 1.3)
*
* Supported tensor rank: up to 4.
*
@@ -1414,7 +1430,8 @@
*
* Outputs:
* * 0: The output tensor of the same shape as input0.
- * For a {@link OperandType::TENSOR_QUANT8_ASYMM} tensor,
+ * For a {@link OperandType::TENSOR_QUANT8_ASYMM} and
+ * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} tensor,
* the scale and zeroPoint must be the same as input0.
*/
RELU1 = @1.2::OperationType:RELU1,
@@ -1430,6 +1447,7 @@
* * {@link OperandType::TENSOR_FLOAT16} (since HAL version 1.2)
* * {@link OperandType::TENSOR_FLOAT32}
* * {@link OperandType::TENSOR_QUANT8_ASYMM}
+ * * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} (since HAL version 1.3)
*
* Supported tensor rank: up to 4.
*
@@ -1439,7 +1457,8 @@
*
* Outputs:
* * 0: The output tensor of same shape as input0.
- * For a {@link OperandType::TENSOR_QUANT8_ASYMM} tensor,
+ * For a {@link OperandType::TENSOR_QUANT8_ASYMM} and
+ * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} tensor,
* the scale and zeroPoint must be the same as input0.
*/
RELU6 = @1.2::OperationType:RELU6,
@@ -1454,6 +1473,7 @@
* * {@link OperandType::TENSOR_FLOAT16} (since HAL version 1.2)
* * {@link OperandType::TENSOR_FLOAT32}
* * {@link OperandType::TENSOR_QUANT8_ASYMM}
+ * * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} (since HAL version 1.3)
*
* Supported tensor rank: up to 4.
*
@@ -1470,7 +1490,8 @@
*
* Outputs:
* * 0: The output tensor, of shape specified by the input shape.
- * For a {@link OperandType::TENSOR_QUANT8_ASYMM} tensor,
+ * For a {@link OperandType::TENSOR_QUANT8_ASYMM} and
+ * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} tensor,
* the scale and zeroPoint must be the same as input0.
*/
RESHAPE = @1.2::OperationType:RESHAPE,
@@ -1760,6 +1781,7 @@
* * {@link OperandType::TENSOR_FLOAT16} (since HAL version 1.2)
* * {@link OperandType::TENSOR_FLOAT32}
* * {@link OperandType::TENSOR_QUANT8_ASYMM} (since HAL version 1.2)
+ * * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} (since HAL version 1.3)
*
* Supported tensor rank: up to 4.
*
@@ -1771,6 +1793,8 @@
* * 0: The output tensor of same shape as input0.
* For {@link OperandType::TENSOR_QUANT8_ASYMM},
* the scale must be 1.f / 128 and the zeroPoint must be 128.
+ * For {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED},
+ * the scale must be 1.f / 128 and the zeroPoint must be 0.
*/
TANH = @1.2::OperationType:TANH,
@@ -1866,6 +1890,7 @@
* * {@link OperandType::TENSOR_FLOAT16} (since HAL version 1.2)
* * {@link OperandType::TENSOR_FLOAT32}
* * {@link OperandType::TENSOR_QUANT8_ASYMM}
+ * * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} (since HAL version 1.3)
*
* Supported tensor rank: up to 4
*
@@ -1885,8 +1910,9 @@
*
* Outputs:
* * 0: A tensor of the same {@link OperandType} as input0.
- * For a {@link OperandType::TENSOR_QUANT8_ASYMM} tensor,
- * the scale and zeroPoint must be same as input0.
+ * For a {@link OperandType::TENSOR_QUANT8_ASYMM} and
+ * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} tensor,
+ * the scale and zeroPoint must be the same as input0.
*/
MEAN = @1.2::OperationType:MEAN,
@@ -1993,6 +2019,7 @@
* * {@link OperandType::TENSOR_FLOAT16} (since HAL version 1.2)
* * {@link OperandType::TENSOR_FLOAT32}
* * {@link OperandType::TENSOR_QUANT8_ASYMM}
+ * * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} (since HAL version 1.3)
*
* Supported tensor rank: up to 4
*
@@ -2008,7 +2035,8 @@
* * 0: A tensor of the same {@link OperandType} as input0. Contains the
* same data as input, but has one or more dimensions of size 1
* removed.
- * For a {@link OperandType::TENSOR_QUANT8_ASYMM} tensor,
+ * For a {@link OperandType::TENSOR_QUANT8_ASYMM} and
+ * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} tensor,
* the scale and zeroPoint must be the same as input0.
*/
SQUEEZE = @1.2::OperationType:SQUEEZE,
@@ -2026,6 +2054,7 @@
* * {@link OperandType::TENSOR_FLOAT16} (since HAL version 1.2)
* * {@link OperandType::TENSOR_FLOAT32}
* * {@link OperandType::TENSOR_QUANT8_ASYMM}
+ * * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} (since HAL version 1.3)
*
* Supported tensor rank: up to 4
*
@@ -2055,7 +2084,8 @@
* Outputs:
* * 0: A tensor of the same {@link OperandType} as input0 and rank (n - k),
* where k is the number of bits set in shrink_axis_mask.
- * For a {@link OperandType::TENSOR_QUANT8_ASYMM} tensor,
+ * For a {@link OperandType::TENSOR_QUANT8_ASYMM} and
+ * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} tensor,
* the scale and zeroPoint must be the same as input0.
*/
STRIDED_SLICE = @1.2::OperationType:STRIDED_SLICE,
@@ -3808,6 +3838,7 @@
* * {@link OperandType::TENSOR_FLOAT16}
* * {@link OperandType::TENSOR_FLOAT32}
* * {@link OperandType::TENSOR_QUANT8_ASYMM}
+ * * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} (since HAL version 1.3)
*
* Supported tensor rank: up to 4
*
@@ -3820,7 +3851,8 @@
*
* Outputs:
* * 0: A tensor of the same {@link OperandType} as input0.
- * For a {@link OperandType::TENSOR_QUANT8_ASYMM} tensor,
+ * For a {@link OperandType::TENSOR_QUANT8_ASYMM} and
+ * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} tensor,
* the scale and zeroPoint must be the same as input0.
*/
REDUCE_MAX = @1.2::OperationType:REDUCE_MAX,
@@ -3837,6 +3869,7 @@
* * {@link OperandType::TENSOR_FLOAT16}
* * {@link OperandType::TENSOR_FLOAT32}
* * {@link OperandType::TENSOR_QUANT8_ASYMM}
+ * * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} (since HAL version 1.3)
*
* Supported tensor rank: up to 4
*
@@ -3849,7 +3882,8 @@
*
* Outputs:
* * 0: A tensor of the same {@link OperandType} as input0.
- * For a {@link OperandType::TENSOR_QUANT8_ASYMM} tensor,
+ * For a {@link OperandType::TENSOR_QUANT8_ASYMM} and
+ * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} tensor,
* the scale and zeroPoint must be the same as input0.
*/
REDUCE_MIN = @1.2::OperationType:REDUCE_MIN,
diff --git a/neuralnetworks/1.3/vts/functional/GeneratedTestHarness.cpp b/neuralnetworks/1.3/vts/functional/GeneratedTestHarness.cpp
index 3e947f5..be894f2 100644
--- a/neuralnetworks/1.3/vts/functional/GeneratedTestHarness.cpp
+++ b/neuralnetworks/1.3/vts/functional/GeneratedTestHarness.cpp
@@ -34,13 +34,14 @@
#include <android/hardware/neuralnetworks/1.3/types.h>
#include <android/hidl/allocator/1.0/IAllocator.h>
#include <android/hidl/memory/1.0/IMemory.h>
+#include <gtest/gtest.h>
#include <hidlmemory/mapping.h>
-#include <gtest/gtest.h>
#include <algorithm>
#include <chrono>
#include <iostream>
#include <numeric>
+#include <vector>
#include "1.0/Utils.h"
#include "1.2/Callbacks.h"
@@ -214,7 +215,7 @@
hidl_vec<OutputShape>* outputShapes,
Timing* timing) {
ErrorStatus result;
- Return<void> ret = preparedModel->executeSynchronously(
+ Return<void> ret = preparedModel->executeSynchronously_1_3(
request, measure,
[&result, outputShapes, timing](ErrorStatus error, const hidl_vec<OutputShape>& shapes,
const Timing& time) {
@@ -368,9 +369,9 @@
void EvaluatePreparedModel(const sp<IPreparedModel>& preparedModel, const TestModel& testModel,
TestKind testKind) {
- std::initializer_list<OutputType> outputTypesList;
- std::initializer_list<MeasureTiming> measureTimingList;
- std::initializer_list<Executor> executorList;
+ std::vector<OutputType> outputTypesList;
+ std::vector<MeasureTiming> measureTimingList;
+ std::vector<Executor> executorList;
switch (testKind) {
case TestKind::GENERAL: {
@@ -403,11 +404,9 @@
const TestModel& testModel,
const sp<IPreparedModel>& preparedCoupledModel,
const TestModel& coupledModel) {
- std::initializer_list<OutputType> outputTypesList = {OutputType::FULLY_SPECIFIED};
- std::initializer_list<MeasureTiming> measureTimingList = {MeasureTiming::NO,
- MeasureTiming::YES};
- std::initializer_list<Executor> executorList = {Executor::ASYNC, Executor::SYNC,
- Executor::BURST};
+ const std::vector<OutputType> outputTypesList = {OutputType::FULLY_SPECIFIED};
+ const std::vector<MeasureTiming> measureTimingList = {MeasureTiming::NO, MeasureTiming::YES};
+ const std::vector<Executor> executorList = {Executor::ASYNC, Executor::SYNC, Executor::BURST};
for (const OutputType outputType : outputTypesList) {
for (const MeasureTiming measureTiming : measureTimingList) {
diff --git a/neuralnetworks/1.3/vts/functional/ValidateModel.cpp b/neuralnetworks/1.3/vts/functional/ValidateModel.cpp
index 46bbd3f..65880b7 100644
--- a/neuralnetworks/1.3/vts/functional/ValidateModel.cpp
+++ b/neuralnetworks/1.3/vts/functional/ValidateModel.cpp
@@ -323,8 +323,8 @@
// - CAST's argument can be any of TENSOR_(FLOAT16|FLOAT32|INT32|QUANT8_ASYMM).
// - RANDOM_MULTINOMIAL's argument can be either TENSOR_FLOAT16 or TENSOR_FLOAT32.
// - DEQUANTIZE input can be any of
- // TENSOR_(QUANT8_ASYMM|QUANT8_SYMM|QUANT8_SYMM_PER_CHANNEL), output can
- // be of either TENSOR_FLOAT16 or TENSOR_FLOAT32.
+ // TENSOR_(QUANT8_ASYMM|QUANT8_ASYMM_SIGNED|QUANT8_SYMM|QUANT8_SYMM_PER_CHANNEL),
+ // output can be of either TENSOR_FLOAT16 or TENSOR_FLOAT32.
// - QUANTIZE input can be either TENSOR_FLOAT16 or TENSOR_FLOAT32
// - CONV_2D filter type (arg 1) can be QUANT8_ASYMM or QUANT8_SYMM_PER_CHANNEL
// - DEPTHWISE_CONV_2D filter type (arg 1) can be QUANT8_ASYMM or QUANT8_SYMM_PER_CHANNEL
@@ -340,11 +340,22 @@
case OperationType::ARGMAX:
case OperationType::ARGMIN: {
if (type == OperandType::TENSOR_FLOAT16 || type == OperandType::TENSOR_FLOAT32 ||
- type == OperandType::TENSOR_INT32 || type == OperandType::TENSOR_QUANT8_ASYMM) {
+ type == OperandType::TENSOR_INT32 || type == OperandType::TENSOR_QUANT8_ASYMM ||
+ type == OperandType::TENSOR_QUANT8_ASYMM_SIGNED) {
return true;
}
} break;
- case OperationType::QUANTIZE:
+ case OperationType::QUANTIZE: {
+ if (operand == operation.inputs[0] &&
+ (type == OperandType::TENSOR_FLOAT16 || type == OperandType::TENSOR_FLOAT32)) {
+ return true;
+ }
+ if (operand == operation.outputs[0] &&
+ (type == OperandType::TENSOR_QUANT8_ASYMM ||
+ type == OperandType::TENSOR_QUANT8_ASYMM_SIGNED)) {
+ return true;
+ }
+ } break;
case OperationType::RANDOM_MULTINOMIAL: {
if (operand == operation.inputs[0] &&
(type == OperandType::TENSOR_FLOAT16 || type == OperandType::TENSOR_FLOAT32)) {
@@ -354,6 +365,7 @@
case OperationType::DEQUANTIZE: {
if (operand == operation.inputs[0] &&
(type == OperandType::TENSOR_QUANT8_ASYMM ||
+ type == OperandType::TENSOR_QUANT8_ASYMM_SIGNED ||
type == OperandType::TENSOR_QUANT8_SYMM ||
type == OperandType::TENSOR_QUANT8_SYMM_PER_CHANNEL)) {
return true;
diff --git a/neuralnetworks/1.3/vts/functional/ValidateRequest.cpp b/neuralnetworks/1.3/vts/functional/ValidateRequest.cpp
index 2cf30d5..8092d04 100644
--- a/neuralnetworks/1.3/vts/functional/ValidateRequest.cpp
+++ b/neuralnetworks/1.3/vts/functional/ValidateRequest.cpp
@@ -79,9 +79,9 @@
// synchronous
{
- SCOPED_TRACE(message + " [executeSynchronously]");
+ SCOPED_TRACE(message + " [executeSynchronously_1_3]");
- Return<void> executeStatus = preparedModel->executeSynchronously(
+ Return<void> executeStatus = preparedModel->executeSynchronously_1_3(
request, measure,
[](ErrorStatus error, const hidl_vec<OutputShape>& outputShapes,
const Timing& timing) {
@@ -158,8 +158,8 @@
}
void validateRequestFailure(const sp<IPreparedModel>& preparedModel, const Request& request) {
- SCOPED_TRACE("Expecting request to fail [executeSynchronously]");
- Return<void> executeStatus = preparedModel->executeSynchronously(
+ SCOPED_TRACE("Expecting request to fail [executeSynchronously_1_3]");
+ Return<void> executeStatus = preparedModel->executeSynchronously_1_3(
request, MeasureTiming::NO,
[](ErrorStatus error, const hidl_vec<OutputShape>& outputShapes, const Timing& timing) {
ASSERT_NE(ErrorStatus::NONE, error);
diff --git a/oemlock/1.0/vts/functional/Android.bp b/oemlock/1.0/vts/functional/Android.bp
index 28d6bf6..90de347 100644
--- a/oemlock/1.0/vts/functional/Android.bp
+++ b/oemlock/1.0/vts/functional/Android.bp
@@ -19,5 +19,5 @@
defaults: ["VtsHalTargetTestDefaults"],
srcs: ["VtsHalOemLockV1_0TargetTest.cpp"],
static_libs: ["android.hardware.oemlock@1.0"],
- test_suites: ["general-tests"],
+ test_suites: ["general-tests", "vts-core"],
}
diff --git a/oemlock/1.0/vts/functional/VtsHalOemLockV1_0TargetTest.cpp b/oemlock/1.0/vts/functional/VtsHalOemLockV1_0TargetTest.cpp
index 05462a8..bafe87d 100644
--- a/oemlock/1.0/vts/functional/VtsHalOemLockV1_0TargetTest.cpp
+++ b/oemlock/1.0/vts/functional/VtsHalOemLockV1_0TargetTest.cpp
@@ -14,9 +14,9 @@
* limitations under the License.
*/
#include <android/hardware/oemlock/1.0/IOemLock.h>
-
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
using ::android::hardware::oemlock::V1_0::IOemLock;
using ::android::hardware::oemlock::V1_0::OemLockStatus;
@@ -25,22 +25,9 @@
using ::android::hardware::hidl_vec;
using ::android::sp;
-// Test environment for OemLock HIDL HAL.
-class OemLockHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static OemLockHidlEnvironment* Instance() {
- static OemLockHidlEnvironment* instance = new OemLockHidlEnvironment;
- return instance;
- }
-
- virtual void registerTestServices() override { registerTestService<IOemLock>(); }
-};
-
-struct OemLockHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+struct OemLockHidlTest : public ::testing::TestWithParam<std::string> {
virtual void SetUp() override {
- oemlock = ::testing::VtsHalHidlTargetTestBase::getService<IOemLock>(
- OemLockHidlEnvironment::Instance()->getServiceName<IOemLock>());
+ oemlock = IOemLock::getService(GetParam());
ASSERT_NE(oemlock, nullptr);
}
@@ -52,7 +39,7 @@
/*
* Check the name can be retrieved
*/
-TEST_F(OemLockHidlTest, GetName) {
+TEST_P(OemLockHidlTest, GetName) {
std::string name;
OemLockStatus status;
@@ -72,7 +59,7 @@
/*
* Check the unlock allowed by device state can be queried
*/
-TEST_F(OemLockHidlTest, QueryUnlockAllowedByDevice) {
+TEST_P(OemLockHidlTest, QueryUnlockAllowedByDevice) {
bool allowed;
OemLockStatus status;
@@ -92,7 +79,7 @@
/*
* Check unlock allowed by device state can be toggled
*/
-TEST_F(OemLockHidlTest, AllowedByDeviceCanBeToggled) {
+TEST_P(OemLockHidlTest, AllowedByDeviceCanBeToggled) {
bool allowed;
OemLockStatus status;
@@ -129,7 +116,7 @@
/*
* Check the unlock allowed by device state can be queried
*/
-TEST_F(OemLockHidlTest, QueryUnlockAllowedByCarrier) {
+TEST_P(OemLockHidlTest, QueryUnlockAllowedByCarrier) {
bool allowed;
OemLockStatus status;
@@ -153,7 +140,7 @@
* is a valid implementation so the test will pass. If there is no signature
* required, the test will toggle the value.
*/
-TEST_F(OemLockHidlTest, CarrierUnlock) {
+TEST_P(OemLockHidlTest, CarrierUnlock) {
const hidl_vec<uint8_t> noSignature = {};
bool allowed;
OemLockStatus status;
@@ -201,11 +188,7 @@
ASSERT_EQ(allowed, originallyAllowed);
};
-int main(int argc, char** argv) {
- ::testing::AddGlobalTestEnvironment(OemLockHidlEnvironment::Instance());
- ::testing::InitGoogleTest(&argc, argv);
- OemLockHidlEnvironment::Instance()->init(&argc, argv);
- int status = RUN_ALL_TESTS();
- ALOGI("Test result = %d", status);
- return status;
-}
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, OemLockHidlTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(IOemLock::descriptor)),
+ android::hardware::PrintInstanceNameToString);
diff --git a/radio/1.0/vts/functional/Android.bp b/radio/1.0/vts/functional/Android.bp
index 9dec2f2..2351d90 100644
--- a/radio/1.0/vts/functional/Android.bp
+++ b/radio/1.0/vts/functional/Android.bp
@@ -33,7 +33,8 @@
static_libs: [
"android.hardware.radio@1.0",
],
- test_suites: ["general-tests"],
+ test_config: "vts_hal_radio_target_test.xml",
+ test_suites: ["general-tests", "vts-core"],
}
cc_test {
@@ -47,7 +48,8 @@
static_libs: [
"android.hardware.radio@1.0",
],
- test_suites: ["general-tests"],
+ test_config: "vts_hal_sap_target_test.xml",
+ test_suites: ["general-tests", "vts-core"],
}
cc_library_static {
diff --git a/radio/1.0/vts/functional/VtsHalRadioV1_0TargetTest.cpp b/radio/1.0/vts/functional/VtsHalRadioV1_0TargetTest.cpp
index d53c062..9d61b52 100644
--- a/radio/1.0/vts/functional/VtsHalRadioV1_0TargetTest.cpp
+++ b/radio/1.0/vts/functional/VtsHalRadioV1_0TargetTest.cpp
@@ -14,12 +14,18 @@
* limitations under the License.
*/
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include <radio_hidl_hal_utils_v1_0.h>
+INSTANTIATE_TEST_SUITE_P(PerInstance, RadioHidlTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(
+ ::android::hardware::radio::V1_0::IRadio::descriptor)),
+ android::hardware::PrintInstanceNameToString);
+
int main(int argc, char** argv) {
- ::testing::AddGlobalTestEnvironment(RadioHidlEnvironment::Instance());
::testing::InitGoogleTest(&argc, argv);
- RadioHidlEnvironment::Instance()->init(&argc, argv);
// setup seed for rand function
int seedSrand = time(NULL);
diff --git a/radio/1.0/vts/functional/VtsHalSapV1_0TargetTest.cpp b/radio/1.0/vts/functional/VtsHalSapV1_0TargetTest.cpp
index 859e6fb..b80b971 100644
--- a/radio/1.0/vts/functional/VtsHalSapV1_0TargetTest.cpp
+++ b/radio/1.0/vts/functional/VtsHalSapV1_0TargetTest.cpp
@@ -14,12 +14,18 @@
* limitations under the License.
*/
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include <sap_hidl_hal_utils.h>
+INSTANTIATE_TEST_SUITE_P(PerInstance, SapHidlTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(
+ ::android::hardware::radio::V1_0::ISap::descriptor)),
+ android::hardware::PrintInstanceNameToString);
+
int main(int argc, char** argv) {
- ::testing::AddGlobalTestEnvironment(SapHidlEnvironment::Instance());
::testing::InitGoogleTest(&argc, argv);
- SapHidlEnvironment::Instance()->init(&argc, argv);
// setup seed for rand function
int seedSrand = time(NULL);
diff --git a/radio/1.0/vts/functional/radio_hidl_hal_cell_broadcast.cpp b/radio/1.0/vts/functional/radio_hidl_hal_cell_broadcast.cpp
index 2c1eb60..125ea0c 100644
--- a/radio/1.0/vts/functional/radio_hidl_hal_cell_broadcast.cpp
+++ b/radio/1.0/vts/functional/radio_hidl_hal_cell_broadcast.cpp
@@ -21,7 +21,7 @@
/*
* Test IRadio.setGsmBroadcastConfig() for the response returned.
*/
-TEST_F(RadioHidlTest, setGsmBroadcastConfig) {
+TEST_P(RadioHidlTest, setGsmBroadcastConfig) {
serial = GetRandomSerialNumber();
// Create GsmBroadcastSmsConfigInfo #1
@@ -84,7 +84,7 @@
/*
* Test IRadio.getGsmBroadcastConfig() for the response returned.
*/
-TEST_F(RadioHidlTest, getGsmBroadcastConfig) {
+TEST_P(RadioHidlTest, getGsmBroadcastConfig) {
serial = GetRandomSerialNumber();
radio->getGsmBroadcastConfig(serial);
@@ -104,7 +104,7 @@
/*
* Test IRadio.setCdmaBroadcastConfig() for the response returned.
*/
-TEST_F(RadioHidlTest, setCdmaBroadcastConfig) {
+TEST_P(RadioHidlTest, setCdmaBroadcastConfig) {
serial = GetRandomSerialNumber();
CdmaBroadcastSmsConfigInfo cbSmsConfig;
@@ -131,7 +131,7 @@
/*
* Test IRadio.getCdmaBroadcastConfig() for the response returned.
*/
-TEST_F(RadioHidlTest, getCdmaBroadcastConfig) {
+TEST_P(RadioHidlTest, getCdmaBroadcastConfig) {
serial = GetRandomSerialNumber();
radio->getCdmaBroadcastConfig(serial);
@@ -149,7 +149,7 @@
/*
* Test IRadio.setCdmaBroadcastActivation() for the response returned.
*/
-TEST_F(RadioHidlTest, setCdmaBroadcastActivation) {
+TEST_P(RadioHidlTest, setCdmaBroadcastActivation) {
serial = GetRandomSerialNumber();
bool activate = false;
@@ -169,7 +169,7 @@
/*
* Test IRadio.setGsmBroadcastActivation() for the response returned.
*/
-TEST_F(RadioHidlTest, setGsmBroadcastActivation) {
+TEST_P(RadioHidlTest, setGsmBroadcastActivation) {
serial = GetRandomSerialNumber();
bool activate = false;
diff --git a/radio/1.0/vts/functional/radio_hidl_hal_data.cpp b/radio/1.0/vts/functional/radio_hidl_hal_data.cpp
index eaef3ed..d937d74 100644
--- a/radio/1.0/vts/functional/radio_hidl_hal_data.cpp
+++ b/radio/1.0/vts/functional/radio_hidl_hal_data.cpp
@@ -21,7 +21,7 @@
/*
* Test IRadio.getDataRegistrationState() for the response returned.
*/
-TEST_F(RadioHidlTest, getDataRegistrationState) {
+TEST_P(RadioHidlTest, getDataRegistrationState) {
serial = GetRandomSerialNumber();
radio->getDataRegistrationState(serial);
@@ -99,7 +99,7 @@
/*
* Test IRadio.setupDataCall() for the response returned.
*/
-TEST_F(RadioHidlTest, setupDataCall) {
+TEST_P(RadioHidlTest, setupDataCall) {
serial = GetRandomSerialNumber();
RadioTechnology radioTechnology = RadioTechnology::LTE;
@@ -147,7 +147,7 @@
/*
* Test IRadio.deactivateDataCall() for the response returned.
*/
-TEST_F(RadioHidlTest, deactivateDataCall) {
+TEST_P(RadioHidlTest, deactivateDataCall) {
serial = GetRandomSerialNumber();
int cid = 1;
bool reasonRadioShutDown = false;
@@ -169,7 +169,7 @@
/*
* Test IRadio.getDataCallList() for the response returned.
*/
-TEST_F(RadioHidlTest, getDataCallList) {
+TEST_P(RadioHidlTest, getDataCallList) {
serial = GetRandomSerialNumber();
radio->getDataCallList(serial);
@@ -188,7 +188,7 @@
/*
* Test IRadio.setInitialAttachApn() for the response returned.
*/
-TEST_F(RadioHidlTest, setInitialAttachApn) {
+TEST_P(RadioHidlTest, setInitialAttachApn) {
serial = GetRandomSerialNumber();
DataProfileInfo dataProfileInfo;
@@ -231,7 +231,7 @@
/*
* Test IRadio.setDataAllowed() for the response returned.
*/
-TEST_F(RadioHidlTest, setDataAllowed) {
+TEST_P(RadioHidlTest, setDataAllowed) {
serial = GetRandomSerialNumber();
bool allow = true;
@@ -249,7 +249,7 @@
/*
* Test IRadio.setDataProfile() for the response returned.
*/
-TEST_F(RadioHidlTest, setDataProfile) {
+TEST_P(RadioHidlTest, setDataProfile) {
serial = GetRandomSerialNumber();
// Create a dataProfileInfo
diff --git a/radio/1.0/vts/functional/radio_hidl_hal_icc.cpp b/radio/1.0/vts/functional/radio_hidl_hal_icc.cpp
index 2670d96..60cb2fe 100644
--- a/radio/1.0/vts/functional/radio_hidl_hal_icc.cpp
+++ b/radio/1.0/vts/functional/radio_hidl_hal_icc.cpp
@@ -19,7 +19,7 @@
/*
* Test IRadio.getIccCardStatus() for the response returned.
*/
-TEST_F(RadioHidlTest, getIccCardStatus) {
+TEST_P(RadioHidlTest, getIccCardStatus) {
EXPECT_LE(cardStatus.applications.size(), (unsigned int)RadioConst::CARD_MAX_APPS);
EXPECT_LT(cardStatus.gsmUmtsSubscriptionAppIndex, (int)RadioConst::CARD_MAX_APPS);
EXPECT_LT(cardStatus.cdmaSubscriptionAppIndex, (int)RadioConst::CARD_MAX_APPS);
@@ -29,7 +29,7 @@
/*
* Test IRadio.supplyIccPinForApp() for the response returned
*/
-TEST_F(RadioHidlTest, supplyIccPinForApp) {
+TEST_P(RadioHidlTest, supplyIccPinForApp) {
serial = GetRandomSerialNumber();
// Pass wrong password and check PASSWORD_INCORRECT returned for 3GPP and
@@ -54,7 +54,7 @@
/*
* Test IRadio.supplyIccPukForApp() for the response returned.
*/
-TEST_F(RadioHidlTest, supplyIccPukForApp) {
+TEST_P(RadioHidlTest, supplyIccPukForApp) {
serial = GetRandomSerialNumber();
// Pass wrong password and check PASSWORD_INCORRECT returned for 3GPP and
@@ -78,7 +78,7 @@
/*
* Test IRadio.supplyIccPin2ForApp() for the response returned.
*/
-TEST_F(RadioHidlTest, supplyIccPin2ForApp) {
+TEST_P(RadioHidlTest, supplyIccPin2ForApp) {
serial = GetRandomSerialNumber();
// Pass wrong password and check PASSWORD_INCORRECT returned for 3GPP and
@@ -104,7 +104,7 @@
/*
* Test IRadio.supplyIccPuk2ForApp() for the response returned.
*/
-TEST_F(RadioHidlTest, supplyIccPuk2ForApp) {
+TEST_P(RadioHidlTest, supplyIccPuk2ForApp) {
serial = GetRandomSerialNumber();
// Pass wrong password and check PASSWORD_INCORRECT returned for 3GPP and
@@ -128,7 +128,7 @@
/*
* Test IRadio.changeIccPinForApp() for the response returned.
*/
-TEST_F(RadioHidlTest, changeIccPinForApp) {
+TEST_P(RadioHidlTest, changeIccPinForApp) {
serial = GetRandomSerialNumber();
// Pass wrong password and check PASSWORD_INCORRECT returned for 3GPP and
@@ -153,7 +153,7 @@
/*
* Test IRadio.changeIccPin2ForApp() for the response returned.
*/
-TEST_F(RadioHidlTest, changeIccPin2ForApp) {
+TEST_P(RadioHidlTest, changeIccPin2ForApp) {
serial = GetRandomSerialNumber();
// Pass wrong password and check PASSWORD_INCORRECT returned for 3GPP and
@@ -179,7 +179,7 @@
/*
* Test IRadio.getImsiForApp() for the response returned.
*/
-TEST_F(RadioHidlTest, getImsiForApp) {
+TEST_P(RadioHidlTest, getImsiForApp) {
serial = GetRandomSerialNumber();
// Check success returned while getting imsi for 3GPP and 3GPP2 apps only
@@ -208,7 +208,7 @@
/*
* Test IRadio.iccIOForApp() for the response returned.
*/
-TEST_F(RadioHidlTest, iccIOForApp) {
+TEST_P(RadioHidlTest, iccIOForApp) {
serial = GetRandomSerialNumber();
for (int i = 0; i < (int)cardStatus.applications.size(); i++) {
@@ -233,7 +233,7 @@
/*
* Test IRadio.iccTransmitApduBasicChannel() for the response returned.
*/
-TEST_F(RadioHidlTest, iccTransmitApduBasicChannel) {
+TEST_P(RadioHidlTest, iccTransmitApduBasicChannel) {
serial = GetRandomSerialNumber();
SimApdu msg;
memset(&msg, 0, sizeof(msg));
@@ -250,7 +250,7 @@
/*
* Test IRadio.iccOpenLogicalChannel() for the response returned.
*/
-TEST_F(RadioHidlTest, iccOpenLogicalChannel) {
+TEST_P(RadioHidlTest, iccOpenLogicalChannel) {
serial = GetRandomSerialNumber();
int p2 = 0x04;
// Specified in ISO 7816-4 clause 7.1.1 0x04 means that FCP template is requested.
@@ -265,7 +265,7 @@
/*
* Test IRadio.iccCloseLogicalChannel() for the response returned.
*/
-TEST_F(RadioHidlTest, iccCloseLogicalChannel) {
+TEST_P(RadioHidlTest, iccCloseLogicalChannel) {
serial = GetRandomSerialNumber();
// Try closing invalid channel and check INVALID_ARGUMENTS returned as error
radio->iccCloseLogicalChannel(serial, 0);
@@ -279,7 +279,7 @@
/*
* Test IRadio.iccTransmitApduLogicalChannel() for the response returned.
*/
-TEST_F(RadioHidlTest, iccTransmitApduLogicalChannel) {
+TEST_P(RadioHidlTest, iccTransmitApduLogicalChannel) {
serial = GetRandomSerialNumber();
SimApdu msg;
memset(&msg, 0, sizeof(msg));
@@ -296,7 +296,7 @@
/*
* Test IRadio.requestIccSimAuthentication() for the response returned.
*/
-TEST_F(RadioHidlTest, requestIccSimAuthentication) {
+TEST_P(RadioHidlTest, requestIccSimAuthentication) {
serial = GetRandomSerialNumber();
// Pass wrong challenge string and check RadioError::INVALID_ARGUMENTS
@@ -315,7 +315,7 @@
/*
* Test IRadio.supplyNetworkDepersonalization() for the response returned.
*/
-TEST_F(RadioHidlTest, supplyNetworkDepersonalization) {
+TEST_P(RadioHidlTest, supplyNetworkDepersonalization) {
serial = GetRandomSerialNumber();
radio->supplyNetworkDepersonalization(serial, hidl_string("test"));
diff --git a/radio/1.0/vts/functional/radio_hidl_hal_ims.cpp b/radio/1.0/vts/functional/radio_hidl_hal_ims.cpp
index 4331c06..e253dcf 100644
--- a/radio/1.0/vts/functional/radio_hidl_hal_ims.cpp
+++ b/radio/1.0/vts/functional/radio_hidl_hal_ims.cpp
@@ -21,7 +21,7 @@
/*
* Test IRadio.getClir() for the response returned.
*/
-TEST_F(RadioHidlTest, getClir) {
+TEST_P(RadioHidlTest, getClir) {
serial = GetRandomSerialNumber();
radio->getClir(serial);
@@ -39,7 +39,7 @@
/*
* Test IRadio.setClir() for the response returned.
*/
-TEST_F(RadioHidlTest, setClir) {
+TEST_P(RadioHidlTest, setClir) {
serial = GetRandomSerialNumber();
int32_t status = 1;
@@ -57,7 +57,7 @@
/*
* Test IRadio.getFacilityLockForApp() for the response returned.
*/
-TEST_F(RadioHidlTest, getFacilityLockForApp) {
+TEST_P(RadioHidlTest, getFacilityLockForApp) {
serial = GetRandomSerialNumber();
std::string facility = "";
std::string password = "";
@@ -80,7 +80,7 @@
/*
* Test IRadio.setFacilityLockForApp() for the response returned.
*/
-TEST_F(RadioHidlTest, setFacilityLockForApp) {
+TEST_P(RadioHidlTest, setFacilityLockForApp) {
serial = GetRandomSerialNumber();
std::string facility = "";
bool lockState = false;
@@ -104,7 +104,7 @@
/*
* Test IRadio.setBarringPassword() for the response returned.
*/
-TEST_F(RadioHidlTest, setBarringPassword) {
+TEST_P(RadioHidlTest, setBarringPassword) {
serial = GetRandomSerialNumber();
std::string facility = "";
std::string oldPassword = "";
@@ -127,7 +127,7 @@
/*
* Test IRadio.getClip() for the response returned.
*/
-TEST_F(RadioHidlTest, getClip) {
+TEST_P(RadioHidlTest, getClip) {
serial = GetRandomSerialNumber();
radio->getClip(serial);
@@ -145,7 +145,7 @@
/*
* Test IRadio.setSuppServiceNotifications() for the response returned.
*/
-TEST_F(RadioHidlTest, setSuppServiceNotifications) {
+TEST_P(RadioHidlTest, setSuppServiceNotifications) {
serial = GetRandomSerialNumber();
bool enable = false;
@@ -164,7 +164,7 @@
/*
* Test IRadio.requestIsimAuthentication() for the response returned.
*/
-TEST_F(RadioHidlTest, requestIsimAuthentication) {
+TEST_P(RadioHidlTest, requestIsimAuthentication) {
serial = GetRandomSerialNumber();
std::string challenge = "";
@@ -186,7 +186,7 @@
/*
* Test IRadio.getImsRegistrationState() for the response returned.
*/
-TEST_F(RadioHidlTest, getImsRegistrationState) {
+TEST_P(RadioHidlTest, getImsRegistrationState) {
serial = GetRandomSerialNumber();
radio->getImsRegistrationState(serial);
diff --git a/radio/1.0/vts/functional/radio_hidl_hal_misc.cpp b/radio/1.0/vts/functional/radio_hidl_hal_misc.cpp
index 3499762..d04cb36 100644
--- a/radio/1.0/vts/functional/radio_hidl_hal_misc.cpp
+++ b/radio/1.0/vts/functional/radio_hidl_hal_misc.cpp
@@ -19,7 +19,7 @@
/*
* Test IRadio.getSignalStrength() for the response returned.
*/
-TEST_F(RadioHidlTest, getSignalStrength) {
+TEST_P(RadioHidlTest, getSignalStrength) {
serial = GetRandomSerialNumber();
radio->getSignalStrength(serial);
@@ -35,7 +35,7 @@
/*
* Test IRadio.getVoiceRegistrationState() for the response returned.
*/
-TEST_F(RadioHidlTest, getVoiceRegistrationState) {
+TEST_P(RadioHidlTest, getVoiceRegistrationState) {
serial = GetRandomSerialNumber();
radio->getVoiceRegistrationState(serial);
@@ -51,7 +51,7 @@
/*
* Test IRadio.getOperator() for the response returned.
*/
-TEST_F(RadioHidlTest, getOperator) {
+TEST_P(RadioHidlTest, getOperator) {
serial = GetRandomSerialNumber();
radio->getOperator(serial);
@@ -67,7 +67,7 @@
/*
* Test IRadio.setRadioPower() for the response returned.
*/
-TEST_F(RadioHidlTest, setRadioPower) {
+TEST_P(RadioHidlTest, setRadioPower) {
serial = GetRandomSerialNumber();
radio->setRadioPower(serial, 1);
@@ -83,7 +83,7 @@
/*
* Test IRadio.getNetworkSelectionMode() for the response returned.
*/
-TEST_F(RadioHidlTest, getNetworkSelectionMode) {
+TEST_P(RadioHidlTest, getNetworkSelectionMode) {
serial = GetRandomSerialNumber();
radio->getNetworkSelectionMode(serial);
@@ -99,7 +99,7 @@
/*
* Test IRadio.setNetworkSelectionModeAutomatic() for the response returned.
*/
-TEST_F(RadioHidlTest, setNetworkSelectionModeAutomatic) {
+TEST_P(RadioHidlTest, setNetworkSelectionModeAutomatic) {
serial = GetRandomSerialNumber();
radio->setNetworkSelectionModeAutomatic(serial);
@@ -118,7 +118,7 @@
/*
* Test IRadio.setNetworkSelectionModeManual() for the response returned.
*/
-TEST_F(RadioHidlTest, setNetworkSelectionModeManual) {
+TEST_P(RadioHidlTest, setNetworkSelectionModeManual) {
serial = GetRandomSerialNumber();
radio->setNetworkSelectionModeManual(serial, "123456");
@@ -137,7 +137,7 @@
/*
* Test IRadio.getAvailableNetworks() for the response returned.
*/
-TEST_F(RadioHidlTest, getAvailableNetworks) {
+TEST_P(RadioHidlTest, getAvailableNetworks) {
serial = GetRandomSerialNumber();
radio->getAvailableNetworks(serial);
@@ -158,7 +158,7 @@
/*
* Test IRadio.getBasebandVersion() for the response returned.
*/
-TEST_F(RadioHidlTest, getBasebandVersion) {
+TEST_P(RadioHidlTest, getBasebandVersion) {
serial = GetRandomSerialNumber();
radio->getBasebandVersion(serial);
@@ -174,7 +174,7 @@
/*
* Test IRadio.setBandMode() for the response returned.
*/
-TEST_F(RadioHidlTest, setBandMode) {
+TEST_P(RadioHidlTest, setBandMode) {
serial = GetRandomSerialNumber();
radio->setBandMode(serial, RadioBandMode::BAND_MODE_USA);
@@ -191,7 +191,7 @@
/*
* Test IRadio.getAvailableBandModes() for the response returned.
*/
-TEST_F(RadioHidlTest, getAvailableBandModes) {
+TEST_P(RadioHidlTest, getAvailableBandModes) {
serial = GetRandomSerialNumber();
radio->getAvailableBandModes(serial);
@@ -207,7 +207,7 @@
/*
* Test IRadio.setPreferredNetworkType() for the response returned.
*/
-TEST_F(RadioHidlTest, setPreferredNetworkType) {
+TEST_P(RadioHidlTest, setPreferredNetworkType) {
serial = GetRandomSerialNumber();
radio->setPreferredNetworkType(serial, PreferredNetworkType::GSM_ONLY);
@@ -224,7 +224,7 @@
/*
* Test IRadio.getPreferredNetworkType() for the response returned.
*/
-TEST_F(RadioHidlTest, getPreferredNetworkType) {
+TEST_P(RadioHidlTest, getPreferredNetworkType) {
serial = GetRandomSerialNumber();
radio->getPreferredNetworkType(serial);
@@ -240,7 +240,7 @@
/*
* Test IRadio.getNeighboringCids() for the response returned.
*/
-TEST_F(RadioHidlTest, getNeighboringCids) {
+TEST_P(RadioHidlTest, getNeighboringCids) {
serial = GetRandomSerialNumber();
radio->getNeighboringCids(serial);
@@ -258,7 +258,7 @@
/*
* Test IRadio.setLocationUpdates() for the response returned.
*/
-TEST_F(RadioHidlTest, setLocationUpdates) {
+TEST_P(RadioHidlTest, setLocationUpdates) {
serial = GetRandomSerialNumber();
radio->setLocationUpdates(serial, true);
@@ -275,7 +275,7 @@
/*
* Test IRadio.setCdmaRoamingPreference() for the response returned.
*/
-TEST_F(RadioHidlTest, setCdmaRoamingPreference) {
+TEST_P(RadioHidlTest, setCdmaRoamingPreference) {
serial = GetRandomSerialNumber();
radio->setCdmaRoamingPreference(serial, CdmaRoamingType::HOME_NETWORK);
@@ -293,7 +293,7 @@
/*
* Test IRadio.getCdmaRoamingPreference() for the response returned.
*/
-TEST_F(RadioHidlTest, getCdmaRoamingPreference) {
+TEST_P(RadioHidlTest, getCdmaRoamingPreference) {
serial = GetRandomSerialNumber();
radio->getCdmaRoamingPreference(serial);
@@ -312,7 +312,7 @@
/*
* Test IRadio.getTTYMode() for the response returned.
*/
-TEST_F(RadioHidlTest, getTTYMode) {
+TEST_P(RadioHidlTest, getTTYMode) {
serial = GetRandomSerialNumber();
radio->getTTYMode(serial);
@@ -328,7 +328,7 @@
/*
* Test IRadio.setTTYMode() for the response returned.
*/
-TEST_F(RadioHidlTest, setTTYMode) {
+TEST_P(RadioHidlTest, setTTYMode) {
serial = GetRandomSerialNumber();
radio->setTTYMode(serial, TtyMode::OFF);
@@ -344,7 +344,7 @@
/*
* Test IRadio.setPreferredVoicePrivacy() for the response returned.
*/
-TEST_F(RadioHidlTest, setPreferredVoicePrivacy) {
+TEST_P(RadioHidlTest, setPreferredVoicePrivacy) {
serial = GetRandomSerialNumber();
radio->setPreferredVoicePrivacy(serial, true);
@@ -361,7 +361,7 @@
/*
* Test IRadio.getPreferredVoicePrivacy() for the response returned.
*/
-TEST_F(RadioHidlTest, getPreferredVoicePrivacy) {
+TEST_P(RadioHidlTest, getPreferredVoicePrivacy) {
serial = GetRandomSerialNumber();
radio->getPreferredVoicePrivacy(serial);
@@ -378,7 +378,7 @@
/*
* Test IRadio.getCDMASubscription() for the response returned.
*/
-TEST_F(RadioHidlTest, getCDMASubscription) {
+TEST_P(RadioHidlTest, getCDMASubscription) {
serial = GetRandomSerialNumber();
radio->getCDMASubscription(serial);
@@ -396,7 +396,7 @@
/*
* Test IRadio.getDeviceIdentity() for the response returned.
*/
-TEST_F(RadioHidlTest, getDeviceIdentity) {
+TEST_P(RadioHidlTest, getDeviceIdentity) {
serial = GetRandomSerialNumber();
radio->getDeviceIdentity(serial);
@@ -413,7 +413,7 @@
/*
* Test IRadio.exitEmergencyCallbackMode() for the response returned.
*/
-TEST_F(RadioHidlTest, exitEmergencyCallbackMode) {
+TEST_P(RadioHidlTest, exitEmergencyCallbackMode) {
serial = GetRandomSerialNumber();
radio->exitEmergencyCallbackMode(serial);
@@ -431,7 +431,7 @@
/*
* Test IRadio.getCdmaSubscriptionSource() for the response returned.
*/
-TEST_F(RadioHidlTest, getCdmaSubscriptionSource) {
+TEST_P(RadioHidlTest, getCdmaSubscriptionSource) {
serial = GetRandomSerialNumber();
radio->getCdmaSubscriptionSource(serial);
@@ -449,7 +449,7 @@
/*
* Test IRadio.setCdmaSubscriptionSource() for the response returned.
*/
-TEST_F(RadioHidlTest, setCdmaSubscriptionSource) {
+TEST_P(RadioHidlTest, setCdmaSubscriptionSource) {
serial = GetRandomSerialNumber();
radio->setCdmaSubscriptionSource(serial, CdmaSubscriptionSource::RUIM_SIM);
@@ -468,7 +468,7 @@
/*
* Test IRadio.getVoiceRadioTechnology() for the response returned.
*/
-TEST_F(RadioHidlTest, getVoiceRadioTechnology) {
+TEST_P(RadioHidlTest, getVoiceRadioTechnology) {
serial = GetRandomSerialNumber();
radio->getVoiceRadioTechnology(serial);
@@ -484,7 +484,7 @@
/*
* Test IRadio.getCellInfoList() for the response returned.
*/
-TEST_F(RadioHidlTest, getCellInfoList) {
+TEST_P(RadioHidlTest, getCellInfoList) {
serial = GetRandomSerialNumber();
radio->getCellInfoList(serial);
@@ -502,7 +502,7 @@
/*
* Test IRadio.setCellInfoListRate() for the response returned.
*/
-TEST_F(RadioHidlTest, setCellInfoListRate) {
+TEST_P(RadioHidlTest, setCellInfoListRate) {
serial = GetRandomSerialNumber();
// TODO(sanketpadawe): RIL crashes with value of rate = 10
@@ -520,7 +520,7 @@
/*
* Test IRadio.nvReadItem() for the response returned.
*/
-TEST_F(RadioHidlTest, nvReadItem) {
+TEST_P(RadioHidlTest, nvReadItem) {
serial = GetRandomSerialNumber();
radio->nvReadItem(serial, NvItem::LTE_BAND_ENABLE_25);
@@ -537,7 +537,7 @@
/*
* Test IRadio.nvWriteItem() for the response returned.
*/
-TEST_F(RadioHidlTest, nvWriteItem) {
+TEST_P(RadioHidlTest, nvWriteItem) {
serial = GetRandomSerialNumber();
NvWriteItem item;
memset(&item, 0, sizeof(item));
@@ -557,7 +557,7 @@
/*
* Test IRadio.nvWriteCdmaPrl() for the response returned.
*/
-TEST_F(RadioHidlTest, nvWriteCdmaPrl) {
+TEST_P(RadioHidlTest, nvWriteCdmaPrl) {
serial = GetRandomSerialNumber();
std::vector<uint8_t> prl = {1, 2, 3, 4, 5};
@@ -575,7 +575,7 @@
/*
* Test IRadio.nvResetConfig() for the response returned.
*/
-TEST_F(RadioHidlTest, nvResetConfig) {
+TEST_P(RadioHidlTest, nvResetConfig) {
serial = GetRandomSerialNumber();
radio->nvResetConfig(serial, ResetNvType::ERASE);
@@ -592,7 +592,7 @@
/*
* Test IRadio.setUiccSubscription() for the response returned.
*/
-TEST_F(RadioHidlTest, setUiccSubscription) {
+TEST_P(RadioHidlTest, setUiccSubscription) {
serial = GetRandomSerialNumber();
SelectUiccSub item;
memset(&item, 0, sizeof(item));
@@ -614,7 +614,7 @@
/*
* Test IRadio.getHardwareConfig() for the response returned.
*/
-TEST_F(RadioHidlTest, getHardwareConfig) {
+TEST_P(RadioHidlTest, getHardwareConfig) {
serial = GetRandomSerialNumber();
radio->getHardwareConfig(serial);
@@ -631,7 +631,7 @@
/*
* Test IRadio.requestShutdown() for the response returned.
*/
-TEST_F(RadioHidlTest, requestShutdown) {
+TEST_P(RadioHidlTest, requestShutdown) {
serial = GetRandomSerialNumber();
radio->requestShutdown(serial);
@@ -648,7 +648,7 @@
/*
* Test IRadio.getRadioCapability() for the response returned.
*/
-TEST_F(RadioHidlTest, getRadioCapability) {
+TEST_P(RadioHidlTest, getRadioCapability) {
serial = GetRandomSerialNumber();
radio->getRadioCapability(serial);
@@ -664,7 +664,7 @@
/*
* Test IRadio.setRadioCapability() for the response returned.
*/
-TEST_F(RadioHidlTest, setRadioCapability) {
+TEST_P(RadioHidlTest, setRadioCapability) {
serial = GetRandomSerialNumber();
RadioCapability rc;
memset(&rc, 0, sizeof(rc));
@@ -685,7 +685,7 @@
/*
* Test IRadio.startLceService() for the response returned.
*/
-TEST_F(RadioHidlTest, startLceService) {
+TEST_P(RadioHidlTest, startLceService) {
serial = GetRandomSerialNumber();
radio->startLceService(serial, 5, true);
@@ -704,7 +704,7 @@
/*
* Test IRadio.stopLceService() for the response returned.
*/
-TEST_F(RadioHidlTest, stopLceService) {
+TEST_P(RadioHidlTest, stopLceService) {
serial = GetRandomSerialNumber();
radio->stopLceService(serial);
@@ -722,7 +722,7 @@
/*
* Test IRadio.pullLceData() for the response returned.
*/
-TEST_F(RadioHidlTest, pullLceData) {
+TEST_P(RadioHidlTest, pullLceData) {
serial = GetRandomSerialNumber();
radio->pullLceData(serial);
@@ -741,7 +741,7 @@
/*
* Test IRadio.getModemActivityInfo() for the response returned.
*/
-TEST_F(RadioHidlTest, getModemActivityInfo) {
+TEST_P(RadioHidlTest, getModemActivityInfo) {
serial = GetRandomSerialNumber();
radio->getModemActivityInfo(serial);
@@ -758,7 +758,7 @@
/*
* Test IRadio.setAllowedCarriers() for the response returned.
*/
-TEST_F(RadioHidlTest, setAllowedCarriers) {
+TEST_P(RadioHidlTest, setAllowedCarriers) {
serial = GetRandomSerialNumber();
CarrierRestrictions carriers;
memset(&carriers, 0, sizeof(carriers));
@@ -835,7 +835,7 @@
/*
* Test IRadio.getAllowedCarriers() for the response returned.
*/
-TEST_F(RadioHidlTest, getAllowedCarriers) {
+TEST_P(RadioHidlTest, getAllowedCarriers) {
serial = GetRandomSerialNumber();
radio->getAllowedCarriers(serial);
@@ -852,7 +852,7 @@
/*
* Test IRadio.sendDeviceState() for the response returned.
*/
-TEST_F(RadioHidlTest, sendDeviceState) {
+TEST_P(RadioHidlTest, sendDeviceState) {
serial = GetRandomSerialNumber();
radio->sendDeviceState(serial, DeviceStateType::POWER_SAVE_MODE, true);
@@ -871,7 +871,7 @@
/*
* Test IRadio.setIndicationFilter() for the response returned.
*/
-TEST_F(RadioHidlTest, setIndicationFilter) {
+TEST_P(RadioHidlTest, setIndicationFilter) {
serial = GetRandomSerialNumber();
radio->setIndicationFilter(serial, 1);
@@ -890,7 +890,7 @@
/*
* Test IRadio.setSimCardPower() for the response returned.
*/
-TEST_F(RadioHidlTest, setSimCardPower) {
+TEST_P(RadioHidlTest, setSimCardPower) {
serial = GetRandomSerialNumber();
radio->setSimCardPower(serial, true);
diff --git a/radio/1.0/vts/functional/radio_hidl_hal_sms.cpp b/radio/1.0/vts/functional/radio_hidl_hal_sms.cpp
index 9e41429..58c3bbd 100644
--- a/radio/1.0/vts/functional/radio_hidl_hal_sms.cpp
+++ b/radio/1.0/vts/functional/radio_hidl_hal_sms.cpp
@@ -21,7 +21,7 @@
/*
* Test IRadio.sendSms() for the response returned.
*/
-TEST_F(RadioHidlTest, sendSms) {
+TEST_P(RadioHidlTest, sendSms) {
serial = GetRandomSerialNumber();
GsmSmsMessage msg;
msg.smscPdu = "";
@@ -45,7 +45,7 @@
/*
* Test IRadio.sendSMSExpectMore() for the response returned.
*/
-TEST_F(RadioHidlTest, sendSMSExpectMore) {
+TEST_P(RadioHidlTest, sendSMSExpectMore) {
serial = GetRandomSerialNumber();
GsmSmsMessage msg;
msg.smscPdu = "";
@@ -71,7 +71,7 @@
/*
* Test IRadio.acknowledgeLastIncomingGsmSms() for the response returned.
*/
-TEST_F(RadioHidlTest, acknowledgeLastIncomingGsmSms) {
+TEST_P(RadioHidlTest, acknowledgeLastIncomingGsmSms) {
serial = GetRandomSerialNumber();
bool success = true;
@@ -92,7 +92,7 @@
/*
* Test IRadio.acknowledgeIncomingGsmSmsWithPdu() for the response returned.
*/
-TEST_F(RadioHidlTest, acknowledgeIncomingGsmSmsWithPdu) {
+TEST_P(RadioHidlTest, acknowledgeIncomingGsmSmsWithPdu) {
serial = GetRandomSerialNumber();
bool success = true;
std::string ackPdu = "";
@@ -111,7 +111,7 @@
/*
* Test IRadio.sendCdmaSms() for the response returned.
*/
-TEST_F(RadioHidlTest, sendCdmaSms) {
+TEST_P(RadioHidlTest, sendCdmaSms) {
serial = GetRandomSerialNumber();
// Create a CdmaSmsAddress
@@ -155,7 +155,7 @@
/*
* Test IRadio.acknowledgeLastIncomingCdmaSms() for the response returned.
*/
-TEST_F(RadioHidlTest, acknowledgeLastIncomingCdmaSms) {
+TEST_P(RadioHidlTest, acknowledgeLastIncomingCdmaSms) {
serial = GetRandomSerialNumber();
// Create a CdmaSmsAck
@@ -179,7 +179,7 @@
/*
* Test IRadio.sendImsSms() for the response returned.
*/
-TEST_F(RadioHidlTest, sendImsSms) {
+TEST_P(RadioHidlTest, sendImsSms) {
serial = GetRandomSerialNumber();
// Create a CdmaSmsAddress
@@ -229,7 +229,7 @@
/*
* Test IRadio.getSmscAddress() for the response returned.
*/
-TEST_F(RadioHidlTest, getSmscAddress) {
+TEST_P(RadioHidlTest, getSmscAddress) {
serial = GetRandomSerialNumber();
radio->getSmscAddress(serial);
@@ -249,7 +249,7 @@
/*
* Test IRadio.setSmscAddress() for the response returned.
*/
-TEST_F(RadioHidlTest, setSmscAddress) {
+TEST_P(RadioHidlTest, setSmscAddress) {
serial = GetRandomSerialNumber();
hidl_string address = hidl_string("smscAddress");
@@ -270,7 +270,7 @@
/*
* Test IRadio.writeSmsToSim() for the response returned.
*/
-TEST_F(RadioHidlTest, writeSmsToSim) {
+TEST_P(RadioHidlTest, writeSmsToSim) {
serial = GetRandomSerialNumber();
SmsWriteArgs smsWriteArgs;
smsWriteArgs.status = SmsWriteArgsStatus::REC_UNREAD;
@@ -296,7 +296,7 @@
/*
* Test IRadio.deleteSmsOnSim() for the response returned.
*/
-TEST_F(RadioHidlTest, deleteSmsOnSim) {
+TEST_P(RadioHidlTest, deleteSmsOnSim) {
serial = GetRandomSerialNumber();
int index = 1;
@@ -319,7 +319,7 @@
/*
* Test IRadio.writeSmsToRuim() for the response returned.
*/
-TEST_F(RadioHidlTest, writeSmsToRuim) {
+TEST_P(RadioHidlTest, writeSmsToRuim) {
serial = GetRandomSerialNumber();
// Create a CdmaSmsAddress
@@ -370,7 +370,7 @@
/*
* Test IRadio.deleteSmsOnRuim() for the response returned.
*/
-TEST_F(RadioHidlTest, deleteSmsOnRuim) {
+TEST_P(RadioHidlTest, deleteSmsOnRuim) {
serial = GetRandomSerialNumber();
int index = 1;
@@ -421,7 +421,7 @@
/*
* Test IRadio.reportSmsMemoryStatus() for the response returned.
*/
-TEST_F(RadioHidlTest, reportSmsMemoryStatus) {
+TEST_P(RadioHidlTest, reportSmsMemoryStatus) {
serial = GetRandomSerialNumber();
bool available = true;
diff --git a/radio/1.0/vts/functional/radio_hidl_hal_stk.cpp b/radio/1.0/vts/functional/radio_hidl_hal_stk.cpp
index a3b5029..1170111 100644
--- a/radio/1.0/vts/functional/radio_hidl_hal_stk.cpp
+++ b/radio/1.0/vts/functional/radio_hidl_hal_stk.cpp
@@ -21,7 +21,7 @@
/*
* Test IRadio.sendEnvelope() for the response returned.
*/
-TEST_F(RadioHidlTest, sendEnvelope) {
+TEST_P(RadioHidlTest, sendEnvelope) {
serial = GetRandomSerialNumber();
// Test with sending empty string
@@ -44,7 +44,7 @@
/*
* Test IRadio.sendTerminalResponseToSim() for the response returned.
*/
-TEST_F(RadioHidlTest, sendTerminalResponseToSim) {
+TEST_P(RadioHidlTest, sendTerminalResponseToSim) {
serial = GetRandomSerialNumber();
// Test with sending empty string
@@ -67,7 +67,7 @@
/*
* Test IRadio.handleStkCallSetupRequestFromSim() for the response returned.
*/
-TEST_F(RadioHidlTest, handleStkCallSetupRequestFromSim) {
+TEST_P(RadioHidlTest, handleStkCallSetupRequestFromSim) {
serial = GetRandomSerialNumber();
bool accept = false;
@@ -88,7 +88,7 @@
/*
* Test IRadio.reportStkServiceIsRunning() for the response returned.
*/
-TEST_F(RadioHidlTest, reportStkServiceIsRunning) {
+TEST_P(RadioHidlTest, reportStkServiceIsRunning) {
serial = GetRandomSerialNumber();
radio->reportStkServiceIsRunning(serial);
@@ -107,7 +107,7 @@
* Test IRadio.sendEnvelopeWithStatus() for the response returned with empty
* string.
*/
-TEST_F(RadioHidlTest, sendEnvelopeWithStatus) {
+TEST_P(RadioHidlTest, sendEnvelopeWithStatus) {
serial = GetRandomSerialNumber();
// Test with sending empty string
diff --git a/radio/1.0/vts/functional/radio_hidl_hal_test.cpp b/radio/1.0/vts/functional/radio_hidl_hal_test.cpp
index 96719d6..3c833c0 100644
--- a/radio/1.0/vts/functional/radio_hidl_hal_test.cpp
+++ b/radio/1.0/vts/functional/radio_hidl_hal_test.cpp
@@ -17,13 +17,10 @@
#include <radio_hidl_hal_utils_v1_0.h>
void RadioHidlTest::SetUp() {
- radio = ::testing::VtsHalHidlTargetTestBase::getService<IRadio>(
- RadioHidlEnvironment::Instance()->getServiceName<IRadio>(hidl_string(RADIO_SERVICE_NAME)));
+ radio = IRadio::getService(GetParam());
if (radio == NULL) {
sleep(60);
- radio = ::testing::VtsHalHidlTargetTestBase::getService<IRadio>(
- RadioHidlEnvironment::Instance()->getServiceName<IRadio>(
- hidl_string(RADIO_SERVICE_NAME)));
+ radio = IRadio::getService(GetParam());
}
ASSERT_NE(nullptr, radio.get());
diff --git a/radio/1.0/vts/functional/radio_hidl_hal_utils_v1_0.h b/radio/1.0/vts/functional/radio_hidl_hal_utils_v1_0.h
index 23bc434..8a551f7 100644
--- a/radio/1.0/vts/functional/radio_hidl_hal_utils_v1_0.h
+++ b/radio/1.0/vts/functional/radio_hidl_hal_utils_v1_0.h
@@ -16,8 +16,6 @@
#include <android-base/logging.h>
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
#include <chrono>
#include <condition_variable>
#include <mutex>
@@ -26,6 +24,7 @@
#include <android/hardware/radio/1.0/IRadioIndication.h>
#include <android/hardware/radio/1.0/IRadioResponse.h>
#include <android/hardware/radio/1.0/types.h>
+#include <gtest/gtest.h>
#include "vts_test_util.h"
@@ -515,23 +514,9 @@
const ::android::hardware::hidl_string& reason);
};
-// Test environment for Radio HIDL HAL.
-class RadioHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static RadioHidlEnvironment* Instance() {
- static RadioHidlEnvironment* instance = new RadioHidlEnvironment;
- return instance;
- }
- virtual void registerTestServices() override { registerTestService<IRadio>(); }
-
- private:
- RadioHidlEnvironment() {}
-};
-
// The main test class for Radio HIDL.
-class RadioHidlTest : public ::testing::VtsHalHidlTargetTestBase {
- protected:
+class RadioHidlTest : public ::testing::TestWithParam<std::string> {
+ protected:
std::mutex mtx;
std::condition_variable cv;
int count;
diff --git a/radio/1.0/vts/functional/radio_hidl_hal_voice.cpp b/radio/1.0/vts/functional/radio_hidl_hal_voice.cpp
index 1fce470..a192a33 100644
--- a/radio/1.0/vts/functional/radio_hidl_hal_voice.cpp
+++ b/radio/1.0/vts/functional/radio_hidl_hal_voice.cpp
@@ -19,7 +19,7 @@
/*
* Test IRadio.getCurrentCalls() for the response returned.
*/
-TEST_F(RadioHidlTest, getCurrentCalls) {
+TEST_P(RadioHidlTest, getCurrentCalls) {
serial = GetRandomSerialNumber();
radio->getCurrentCalls(serial);
@@ -35,7 +35,7 @@
/*
* Test IRadio.dial() for the response returned.
*/
-TEST_F(RadioHidlTest, dial) {
+TEST_P(RadioHidlTest, dial) {
serial = GetRandomSerialNumber();
Dial dialInfo;
@@ -62,7 +62,7 @@
/*
* Test IRadio.hangup() for the response returned.
*/
-TEST_F(RadioHidlTest, hangup) {
+TEST_P(RadioHidlTest, hangup) {
serial = GetRandomSerialNumber();
radio->hangup(serial, 1);
@@ -81,7 +81,7 @@
/*
* Test IRadio.hangupWaitingOrBackground() for the response returned.
*/
-TEST_F(RadioHidlTest, hangupWaitingOrBackground) {
+TEST_P(RadioHidlTest, hangupWaitingOrBackground) {
serial = GetRandomSerialNumber();
radio->hangupWaitingOrBackground(serial);
@@ -99,7 +99,7 @@
/*
* Test IRadio.hangupForegroundResumeBackground() for the response returned.
*/
-TEST_F(RadioHidlTest, hangupForegroundResumeBackground) {
+TEST_P(RadioHidlTest, hangupForegroundResumeBackground) {
serial = GetRandomSerialNumber();
radio->hangupForegroundResumeBackground(serial);
@@ -117,7 +117,7 @@
/*
* Test IRadio.switchWaitingOrHoldingAndActive() for the response returned.
*/
-TEST_F(RadioHidlTest, switchWaitingOrHoldingAndActive) {
+TEST_P(RadioHidlTest, switchWaitingOrHoldingAndActive) {
serial = GetRandomSerialNumber();
radio->switchWaitingOrHoldingAndActive(serial);
@@ -135,7 +135,7 @@
/*
* Test IRadio.conference() for the response returned.
*/
-TEST_F(RadioHidlTest, conference) {
+TEST_P(RadioHidlTest, conference) {
serial = GetRandomSerialNumber();
radio->conference(serial);
@@ -153,7 +153,7 @@
/*
* Test IRadio.rejectCall() for the response returned.
*/
-TEST_F(RadioHidlTest, rejectCall) {
+TEST_P(RadioHidlTest, rejectCall) {
serial = GetRandomSerialNumber();
radio->rejectCall(serial);
@@ -171,7 +171,7 @@
/*
* Test IRadio.getLastCallFailCause() for the response returned.
*/
-TEST_F(RadioHidlTest, getLastCallFailCause) {
+TEST_P(RadioHidlTest, getLastCallFailCause) {
serial = GetRandomSerialNumber();
radio->getLastCallFailCause(serial);
@@ -188,7 +188,7 @@
/*
* Test IRadio.sendUssd() for the response returned.
*/
-TEST_F(RadioHidlTest, sendUssd) {
+TEST_P(RadioHidlTest, sendUssd) {
serial = GetRandomSerialNumber();
radio->sendUssd(serial, hidl_string("test"));
EXPECT_EQ(std::cv_status::no_timeout, wait());
@@ -206,7 +206,7 @@
/*
* Test IRadio.cancelPendingUssd() for the response returned.
*/
-TEST_F(RadioHidlTest, cancelPendingUssd) {
+TEST_P(RadioHidlTest, cancelPendingUssd) {
serial = GetRandomSerialNumber();
radio->cancelPendingUssd(serial);
@@ -225,7 +225,7 @@
/*
* Test IRadio.getCallForwardStatus() for the response returned.
*/
-TEST_F(RadioHidlTest, getCallForwardStatus) {
+TEST_P(RadioHidlTest, getCallForwardStatus) {
serial = GetRandomSerialNumber();
CallForwardInfo callInfo;
memset(&callInfo, 0, sizeof(callInfo));
@@ -247,7 +247,7 @@
/*
* Test IRadio.setCallForward() for the response returned.
*/
-TEST_F(RadioHidlTest, setCallForward) {
+TEST_P(RadioHidlTest, setCallForward) {
serial = GetRandomSerialNumber();
CallForwardInfo callInfo;
memset(&callInfo, 0, sizeof(callInfo));
@@ -269,7 +269,7 @@
/*
* Test IRadio.getCallWaiting() for the response returned.
*/
-TEST_F(RadioHidlTest, getCallWaiting) {
+TEST_P(RadioHidlTest, getCallWaiting) {
serial = GetRandomSerialNumber();
radio->getCallWaiting(serial, 1);
@@ -288,7 +288,7 @@
/*
* Test IRadio.setCallWaiting() for the response returned.
*/
-TEST_F(RadioHidlTest, setCallWaiting) {
+TEST_P(RadioHidlTest, setCallWaiting) {
serial = GetRandomSerialNumber();
radio->setCallWaiting(serial, true, 1);
@@ -307,7 +307,7 @@
/*
* Test IRadio.acceptCall() for the response returned.
*/
-TEST_F(RadioHidlTest, acceptCall) {
+TEST_P(RadioHidlTest, acceptCall) {
serial = GetRandomSerialNumber();
radio->acceptCall(serial);
@@ -325,7 +325,7 @@
/*
* Test IRadio.separateConnection() for the response returned.
*/
-TEST_F(RadioHidlTest, separateConnection) {
+TEST_P(RadioHidlTest, separateConnection) {
serial = GetRandomSerialNumber();
radio->separateConnection(serial, 1);
@@ -344,7 +344,7 @@
/*
* Test IRadio.explicitCallTransfer() for the response returned.
*/
-TEST_F(RadioHidlTest, explicitCallTransfer) {
+TEST_P(RadioHidlTest, explicitCallTransfer) {
serial = GetRandomSerialNumber();
radio->explicitCallTransfer(serial);
@@ -362,7 +362,7 @@
/*
* Test IRadio.sendCDMAFeatureCode() for the response returned.
*/
-TEST_F(RadioHidlTest, sendCDMAFeatureCode) {
+TEST_P(RadioHidlTest, sendCDMAFeatureCode) {
serial = GetRandomSerialNumber();
radio->sendCDMAFeatureCode(serial, hidl_string());
@@ -382,7 +382,7 @@
/*
* Test IRadio.sendDtmf() for the response returned.
*/
-TEST_F(RadioHidlTest, sendDtmf) {
+TEST_P(RadioHidlTest, sendDtmf) {
serial = GetRandomSerialNumber();
radio->sendDtmf(serial, "1");
@@ -402,7 +402,7 @@
/*
* Test IRadio.startDtmf() for the response returned.
*/
-TEST_F(RadioHidlTest, startDtmf) {
+TEST_P(RadioHidlTest, startDtmf) {
serial = GetRandomSerialNumber();
radio->startDtmf(serial, "1");
@@ -422,7 +422,7 @@
/*
* Test IRadio.stopDtmf() for the response returned.
*/
-TEST_F(RadioHidlTest, stopDtmf) {
+TEST_P(RadioHidlTest, stopDtmf) {
serial = GetRandomSerialNumber();
radio->stopDtmf(serial);
@@ -441,7 +441,7 @@
/*
* Test IRadio.setMute() for the response returned.
*/
-TEST_F(RadioHidlTest, setMute) {
+TEST_P(RadioHidlTest, setMute) {
serial = GetRandomSerialNumber();
radio->setMute(serial, true);
@@ -459,7 +459,7 @@
/*
* Test IRadio.getMute() for the response returned.
*/
-TEST_F(RadioHidlTest, getMute) {
+TEST_P(RadioHidlTest, getMute) {
serial = GetRandomSerialNumber();
radio->getMute(serial);
@@ -475,7 +475,7 @@
/*
* Test IRadio.sendBurstDtmf() for the response returned.
*/
-TEST_F(RadioHidlTest, sendBurstDtmf) {
+TEST_P(RadioHidlTest, sendBurstDtmf) {
serial = GetRandomSerialNumber();
radio->sendBurstDtmf(serial, "1", 0, 0);
diff --git a/radio/1.0/vts/functional/sap_hidl_hal_api.cpp b/radio/1.0/vts/functional/sap_hidl_hal_api.cpp
index 1d79ff6..6bd2c88 100644
--- a/radio/1.0/vts/functional/sap_hidl_hal_api.cpp
+++ b/radio/1.0/vts/functional/sap_hidl_hal_api.cpp
@@ -19,7 +19,7 @@
/*
* Test ISap.connectReq() for the response returned.
*/
-TEST_F(SapHidlTest, connectReq) {
+TEST_P(SapHidlTest, connectReq) {
token = GetRandomSerialNumber();
int32_t maxMsgSize = 100;
@@ -35,7 +35,7 @@
/*
* Test IRadio.disconnectReq() for the response returned
*/
-TEST_F(SapHidlTest, disconnectReq) {
+TEST_P(SapHidlTest, disconnectReq) {
token = GetRandomSerialNumber();
sap->disconnectReq(token);
@@ -46,7 +46,7 @@
/*
* Test IRadio.apduReq() for the response returned.
*/
-TEST_F(SapHidlTest, apduReq) {
+TEST_P(SapHidlTest, apduReq) {
token = GetRandomSerialNumber();
SapApduType sapApduType = SapApduType::APDU;
android::hardware::hidl_vec<uint8_t> command = {};
@@ -64,7 +64,7 @@
/*
* Test IRadio.transferAtrReq() for the response returned.
*/
-TEST_F(SapHidlTest, transferAtrReq) {
+TEST_P(SapHidlTest, transferAtrReq) {
token = GetRandomSerialNumber();
sap->transferAtrReq(token);
@@ -80,7 +80,7 @@
/*
* Test IRadio.powerReq() for the response returned.
*/
-TEST_F(SapHidlTest, powerReq) {
+TEST_P(SapHidlTest, powerReq) {
token = GetRandomSerialNumber();
bool state = true;
@@ -97,7 +97,7 @@
/*
* Test IRadio.resetSimReq() for the response returned.
*/
-TEST_F(SapHidlTest, resetSimReq) {
+TEST_P(SapHidlTest, resetSimReq) {
token = GetRandomSerialNumber();
sap->resetSimReq(token);
@@ -113,7 +113,7 @@
/*
* Test IRadio.transferCardReaderStatusReq() for the response returned.
*/
-TEST_F(SapHidlTest, transferCardReaderStatusReq) {
+TEST_P(SapHidlTest, transferCardReaderStatusReq) {
token = GetRandomSerialNumber();
sap->transferCardReaderStatusReq(token);
@@ -127,7 +127,7 @@
/*
* Test IRadio.setTransferProtocolReq() for the response returned.
*/
-TEST_F(SapHidlTest, setTransferProtocolReq) {
+TEST_P(SapHidlTest, setTransferProtocolReq) {
token = GetRandomSerialNumber();
SapTransferProtocol sapTransferProtocol = SapTransferProtocol::T0;
diff --git a/radio/1.0/vts/functional/sap_hidl_hal_test.cpp b/radio/1.0/vts/functional/sap_hidl_hal_test.cpp
index 65b344b..fe10587 100644
--- a/radio/1.0/vts/functional/sap_hidl_hal_test.cpp
+++ b/radio/1.0/vts/functional/sap_hidl_hal_test.cpp
@@ -17,8 +17,7 @@
#include <sap_hidl_hal_utils.h>
void SapHidlTest::SetUp() {
- sap = ::testing::VtsHalHidlTargetTestBase::getService<ISap>(
- SapHidlEnvironment::Instance()->getServiceName<ISap>(hidl_string(SAP_SERVICE_NAME)));
+ sap = ISap::getService(GetParam());
ASSERT_NE(sap, nullptr);
sapCb = new SapCallback(*this);
diff --git a/radio/1.0/vts/functional/sap_hidl_hal_utils.h b/radio/1.0/vts/functional/sap_hidl_hal_utils.h
index f432932..2fc9ae3 100644
--- a/radio/1.0/vts/functional/sap_hidl_hal_utils.h
+++ b/radio/1.0/vts/functional/sap_hidl_hal_utils.h
@@ -16,8 +16,6 @@
#include <android-base/logging.h>
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
#include <chrono>
#include <condition_variable>
#include <mutex>
@@ -25,6 +23,7 @@
#include <android/hardware/radio/1.0/ISap.h>
#include <android/hardware/radio/1.0/ISapCallback.h>
#include <android/hardware/radio/1.0/types.h>
+#include <gtest/gtest.h>
#include "vts_test_util.h"
@@ -80,23 +79,9 @@
Return<void> transferProtocolResponse(int32_t token, SapResultCode resultCode);
};
-// Test environment for Sap HIDL HAL.
-class SapHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static SapHidlEnvironment* Instance() {
- static SapHidlEnvironment* instance = new SapHidlEnvironment;
- return instance;
- }
- virtual void registerTestServices() override { registerTestService<ISap>(); }
-
- private:
- SapHidlEnvironment() {}
-};
-
// The main test class for Sap HIDL.
-class SapHidlTest : public ::testing::VtsHalHidlTargetTestBase {
- private:
+class SapHidlTest : public ::testing::TestWithParam<std::string> {
+ private:
std::mutex mtx;
std::condition_variable cv;
int count;
diff --git a/radio/1.0/vts/functional/vts_hal_radio_target_test.xml b/radio/1.0/vts/functional/vts_hal_radio_target_test.xml
new file mode 100644
index 0000000..5e4a1cd
--- /dev/null
+++ b/radio/1.0/vts/functional/vts_hal_radio_target_test.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 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.
+-->
+<configuration description="Runs VtsHalRadioV1_0TargetTest.">
+ <option name="test-suite-tag" value="apct" />
+ <option name="test-suite-tag" value="apct-native" />
+
+ <target_preparer class="com.android.tradefed.targetprep.MultiSimPreparer" />
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
+ </target_preparer>
+
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="cleanup" value="true" />
+ <option name="push" value="VtsHalRadioV1_0TargetTest->/data/local/tmp/VtsHalRadioV1_0TargetTest" />
+ </target_preparer>
+
+ <test class="com.android.tradefed.testtype.GTest" >
+ <option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="module-name" value="VtsHalRadioV1_0TargetTest" />
+ </test>
+</configuration>
diff --git a/radio/1.0/vts/functional/vts_hal_sap_target_test.xml b/radio/1.0/vts/functional/vts_hal_sap_target_test.xml
new file mode 100644
index 0000000..457d700
--- /dev/null
+++ b/radio/1.0/vts/functional/vts_hal_sap_target_test.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 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.
+-->
+<configuration description="Runs VtsHalSapV1_0TargetTest.">
+ <option name="test-suite-tag" value="apct" />
+ <option name="test-suite-tag" value="apct-native" />
+
+ <target_preparer class="com.android.tradefed.targetprep.MultiSimPreparer" />
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
+ </target_preparer>
+
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="cleanup" value="true" />
+ <option name="push" value="VtsHalSapV1_0TargetTest->/data/local/tmp/VtsHalSapV1_0TargetTest" />
+ </target_preparer>
+
+ <test class="com.android.tradefed.testtype.GTest" >
+ <option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="module-name" value="VtsHalSapV1_0TargetTest" />
+ </test>
+</configuration>
diff --git a/radio/1.0/vts/functional/vts_test_util.h b/radio/1.0/vts/functional/vts_test_util.h
index 826f0de..05b47c9 100644
--- a/radio/1.0/vts/functional/vts_test_util.h
+++ b/radio/1.0/vts/functional/vts_test_util.h
@@ -16,9 +16,8 @@
#include <android-base/logging.h>
-#include <VtsHalHidlTargetTestBase.h>
-
#include <android/hardware/radio/1.0/types.h>
+#include <gtest/gtest.h>
using ::android::hardware::radio::V1_0::RadioError;
using ::android::hardware::radio::V1_0::SapResultCode;
diff --git a/radio/1.1/vts/functional/Android.bp b/radio/1.1/vts/functional/Android.bp
index 5695c6b..58aa67e 100644
--- a/radio/1.1/vts/functional/Android.bp
+++ b/radio/1.1/vts/functional/Android.bp
@@ -30,5 +30,5 @@
header_libs: [
"radio.util.header@1.0",
],
- test_suites: ["general-tests"],
+ test_suites: ["general-tests", "vts-core"],
}
diff --git a/radio/1.1/vts/functional/AndroidTest.xml b/radio/1.1/vts/functional/AndroidTest.xml
new file mode 100644
index 0000000..5badadd
--- /dev/null
+++ b/radio/1.1/vts/functional/AndroidTest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 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.
+-->
+<configuration description="Runs VtsHalRadioV1_1TargetTest.">
+ <option name="test-suite-tag" value="apct" />
+ <option name="test-suite-tag" value="apct-native" />
+
+ <target_preparer class="com.android.tradefed.targetprep.MultiSimPreparer" />
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
+ </target_preparer>
+
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="cleanup" value="true" />
+ <option name="push" value="VtsHalRadioV1_1TargetTest->/data/local/tmp/VtsHalRadioV1_1TargetTest" />
+ </target_preparer>
+
+ <test class="com.android.tradefed.testtype.GTest" >
+ <option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="module-name" value="VtsHalRadioV1_1TargetTest" />
+ </test>
+</configuration>
diff --git a/radio/1.1/vts/functional/VtsHalRadioV1_1TargetTest.cpp b/radio/1.1/vts/functional/VtsHalRadioV1_1TargetTest.cpp
index 83564ee..98dbf62 100644
--- a/radio/1.1/vts/functional/VtsHalRadioV1_1TargetTest.cpp
+++ b/radio/1.1/vts/functional/VtsHalRadioV1_1TargetTest.cpp
@@ -14,13 +14,12 @@
* limitations under the License.
*/
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include <radio_hidl_hal_utils_v1_1.h>
-int main(int argc, char** argv) {
- ::testing::AddGlobalTestEnvironment(RadioHidlEnvironment::Instance());
- ::testing::InitGoogleTest(&argc, argv);
- RadioHidlEnvironment::Instance()->init(&argc, argv);
- int status = RUN_ALL_TESTS();
- LOG(INFO) << "Test result = " << status;
- return status;
-}
+INSTANTIATE_TEST_SUITE_P(PerInstance, RadioHidlTest_v1_1,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(
+ ::android::hardware::radio::V1_1::IRadio::descriptor)),
+ android::hardware::PrintInstanceNameToString);
diff --git a/radio/1.1/vts/functional/radio_hidl_hal_api.cpp b/radio/1.1/vts/functional/radio_hidl_hal_api.cpp
index 33347c5..75abbbf 100644
--- a/radio/1.1/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.1/vts/functional/radio_hidl_hal_api.cpp
@@ -20,7 +20,7 @@
/*
* Test IRadio.setSimCardPower() for the response returned.
*/
-TEST_F(RadioHidlTest_v1_1, setSimCardPower_1_1) {
+TEST_P(RadioHidlTest_v1_1, setSimCardPower_1_1) {
/* Record the sim card state for the testing environment */
CardState cardStateForTest = cardStatus.cardState;
@@ -81,7 +81,7 @@
/*
* Test IRadio.startNetworkScan() for the response returned.
*/
-TEST_F(RadioHidlTest_v1_1, startNetworkScan) {
+TEST_P(RadioHidlTest_v1_1, startNetworkScan) {
serial = GetRandomSerialNumber();
NetworkScanRequest request;
@@ -115,7 +115,7 @@
/*
* Test IRadio.startNetworkScan() for the response returned.
*/
-TEST_F(RadioHidlTest_v1_1, startNetworkScan_InvalidArgument) {
+TEST_P(RadioHidlTest_v1_1, startNetworkScan_InvalidArgument) {
serial = GetRandomSerialNumber();
NetworkScanRequest request;
@@ -139,7 +139,7 @@
/*
* Test IRadio.stopNetworkScan() for the response returned.
*/
-TEST_F(RadioHidlTest_v1_1, stopNetworkScan) {
+TEST_P(RadioHidlTest_v1_1, stopNetworkScan) {
serial = GetRandomSerialNumber();
radio_v1_1->stopNetworkScan(serial);
@@ -158,7 +158,7 @@
/*
* Test IRadio.setCarrierInfoForImsiEncryption() for the response returned.
*/
-TEST_F(RadioHidlTest_v1_1, setCarrierInfoForImsiEncryption) {
+TEST_P(RadioHidlTest_v1_1, setCarrierInfoForImsiEncryption) {
serial = GetRandomSerialNumber();
ImsiEncryptionInfo imsiInfo;
imsiInfo.mcc = "310";
@@ -181,7 +181,7 @@
/*
* Test IRadio.startKeepalive() for the response returned.
*/
-TEST_F(RadioHidlTest_v1_1, startKeepalive) {
+TEST_P(RadioHidlTest_v1_1, startKeepalive) {
std::vector<KeepaliveRequest> requests = {
{
// Invalid IPv4 source address
@@ -279,7 +279,7 @@
/*
* Test IRadio.stopKeepalive() for the response returned.
*/
-TEST_F(RadioHidlTest_v1_1, stopKeepalive) {
+TEST_P(RadioHidlTest_v1_1, stopKeepalive) {
serial = GetRandomSerialNumber();
radio_v1_1->stopKeepalive(serial, 0xBAD);
diff --git a/radio/1.1/vts/functional/radio_hidl_hal_test.cpp b/radio/1.1/vts/functional/radio_hidl_hal_test.cpp
index 2f657b4..020168e 100644
--- a/radio/1.1/vts/functional/radio_hidl_hal_test.cpp
+++ b/radio/1.1/vts/functional/radio_hidl_hal_test.cpp
@@ -17,18 +17,10 @@
#include <radio_hidl_hal_utils_v1_1.h>
void RadioHidlTest_v1_1::SetUp() {
- radio_v1_1 =
- ::testing::VtsHalHidlTargetTestBase::getService<::android::hardware::radio::V1_1::IRadio>(
- RadioHidlEnvironment::Instance()
- ->getServiceName<::android::hardware::radio::V1_1::IRadio>(
- hidl_string(RADIO_SERVICE_NAME)));
+ radio_v1_1 = ::android::hardware::radio::V1_1::IRadio::getService(GetParam());
if (radio_v1_1 == NULL) {
sleep(60);
- radio_v1_1 = ::testing::VtsHalHidlTargetTestBase::getService<
- ::android::hardware::radio::V1_1::IRadio>(
- RadioHidlEnvironment::Instance()
- ->getServiceName<::android::hardware::radio::V1_1::IRadio>(
- hidl_string(RADIO_SERVICE_NAME)));
+ radio_v1_1 = ::android::hardware::radio::V1_1::IRadio::getService(GetParam());
}
ASSERT_NE(nullptr, radio_v1_1.get());
diff --git a/radio/1.1/vts/functional/radio_hidl_hal_utils_v1_1.h b/radio/1.1/vts/functional/radio_hidl_hal_utils_v1_1.h
index 925f4fc..b81ee13 100644
--- a/radio/1.1/vts/functional/radio_hidl_hal_utils_v1_1.h
+++ b/radio/1.1/vts/functional/radio_hidl_hal_utils_v1_1.h
@@ -16,8 +16,7 @@
#include <android-base/logging.h>
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
+#include <log/log.h>
#include <chrono>
#include <condition_variable>
#include <mutex>
@@ -26,6 +25,7 @@
#include <android/hardware/radio/1.1/IRadioIndication.h>
#include <android/hardware/radio/1.1/IRadioResponse.h>
#include <android/hardware/radio/1.1/types.h>
+#include <gtest/gtest.h>
#include "vts_test_util.h"
@@ -535,25 +535,9 @@
const ::android::hardware::hidl_string& reason);
};
-// Test environment for Radio HIDL HAL.
-class RadioHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static RadioHidlEnvironment* Instance() {
- static RadioHidlEnvironment* instance = new RadioHidlEnvironment;
- return instance;
- }
- virtual void registerTestServices() override {
- registerTestService<::android::hardware::radio::V1_1::IRadio>();
- }
-
- private:
- RadioHidlEnvironment() {}
-};
-
// The main test class for Radio HIDL.
-class RadioHidlTest_v1_1 : public ::testing::VtsHalHidlTargetTestBase {
- protected:
+class RadioHidlTest_v1_1 : public ::testing::TestWithParam<std::string> {
+ protected:
std::mutex mtx;
std::condition_variable cv;
int count;
diff --git a/radio/1.2/vts/functional/Android.bp b/radio/1.2/vts/functional/Android.bp
index c5838a8..f7189a8 100644
--- a/radio/1.2/vts/functional/Android.bp
+++ b/radio/1.2/vts/functional/Android.bp
@@ -34,5 +34,5 @@
"android.hardware.radio.config@1.1",
],
header_libs: ["radio.util.header@1.0"],
- test_suites: ["general-tests"],
+ test_suites: ["general-tests", "vts-core"],
}
diff --git a/radio/1.2/vts/functional/AndroidTest.xml b/radio/1.2/vts/functional/AndroidTest.xml
new file mode 100644
index 0000000..5d92248
--- /dev/null
+++ b/radio/1.2/vts/functional/AndroidTest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 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.
+-->
+<configuration description="Runs VtsHalRadioV1_2TargetTest.">
+ <option name="test-suite-tag" value="apct" />
+ <option name="test-suite-tag" value="apct-native" />
+
+ <target_preparer class="com.android.tradefed.targetprep.MultiSimPreparer" />
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
+ </target_preparer>
+
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="cleanup" value="true" />
+ <option name="push" value="VtsHalRadioV1_2TargetTest->/data/local/tmp/VtsHalRadioV1_2TargetTest" />
+ </target_preparer>
+
+ <test class="com.android.tradefed.testtype.GTest" >
+ <option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="module-name" value="VtsHalRadioV1_2TargetTest" />
+ </test>
+</configuration>
diff --git a/radio/1.2/vts/functional/VtsHalRadioV1_2TargetTest.cpp b/radio/1.2/vts/functional/VtsHalRadioV1_2TargetTest.cpp
index c1a2f3d..400e394 100644
--- a/radio/1.2/vts/functional/VtsHalRadioV1_2TargetTest.cpp
+++ b/radio/1.2/vts/functional/VtsHalRadioV1_2TargetTest.cpp
@@ -14,13 +14,12 @@
* limitations under the License.
*/
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include <radio_hidl_hal_utils_v1_2.h>
-int main(int argc, char** argv) {
- ::testing::AddGlobalTestEnvironment(RadioHidlEnvironment::Instance());
- ::testing::InitGoogleTest(&argc, argv);
- RadioHidlEnvironment::Instance()->init(&argc, argv);
- int status = RUN_ALL_TESTS();
- LOG(INFO) << "Test result = " << status;
- return status;
-}
+INSTANTIATE_TEST_SUITE_P(PerInstance, RadioHidlTest_v1_2,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(
+ ::android::hardware::radio::V1_2::IRadio::descriptor)),
+ android::hardware::PrintInstanceNameToString);
diff --git a/radio/1.2/vts/functional/radio_hidl_hal_api.cpp b/radio/1.2/vts/functional/radio_hidl_hal_api.cpp
index a98f22a..7464307 100644
--- a/radio/1.2/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.2/vts/functional/radio_hidl_hal_api.cpp
@@ -31,7 +31,7 @@
/*
* Test IRadio.startNetworkScan() for the response returned.
*/
-TEST_F(RadioHidlTest_v1_2, startNetworkScan) {
+TEST_P(RadioHidlTest_v1_2, startNetworkScan) {
serial = GetRandomSerialNumber();
if (radioConfig != NULL && DDS_LOGICAL_SLOT_INDEX != logicalSlotId) {
@@ -82,7 +82,7 @@
/*
* Test IRadio.startNetworkScan() with invalid specifier.
*/
-TEST_F(RadioHidlTest_v1_2, startNetworkScan_InvalidArgument) {
+TEST_P(RadioHidlTest_v1_2, startNetworkScan_InvalidArgument) {
serial = GetRandomSerialNumber();
::android::hardware::radio::V1_2::NetworkScanRequest request = {.type = ScanType::ONE_SHOT,
@@ -109,7 +109,7 @@
/*
* Test IRadio.startNetworkScan() with invalid interval (lower boundary).
*/
-TEST_F(RadioHidlTest_v1_2, startNetworkScan_InvalidInterval1) {
+TEST_P(RadioHidlTest_v1_2, startNetworkScan_InvalidInterval1) {
serial = GetRandomSerialNumber();
::android::hardware::radio::V1_2::NetworkScanRequest request = {
@@ -141,7 +141,7 @@
/*
* Test IRadio.startNetworkScan() with invalid interval (upper boundary).
*/
-TEST_F(RadioHidlTest_v1_2, startNetworkScan_InvalidInterval2) {
+TEST_P(RadioHidlTest_v1_2, startNetworkScan_InvalidInterval2) {
serial = GetRandomSerialNumber();
::android::hardware::radio::V1_2::NetworkScanRequest request = {
@@ -173,7 +173,7 @@
/*
* Test IRadio.startNetworkScan() with invalid max search time (lower boundary).
*/
-TEST_F(RadioHidlTest_v1_2, startNetworkScan_InvalidMaxSearchTime1) {
+TEST_P(RadioHidlTest_v1_2, startNetworkScan_InvalidMaxSearchTime1) {
serial = GetRandomSerialNumber();
::android::hardware::radio::V1_2::NetworkScanRequest request = {
@@ -205,7 +205,7 @@
/*
* Test IRadio.startNetworkScan() with invalid max search time (upper boundary).
*/
-TEST_F(RadioHidlTest_v1_2, startNetworkScan_InvalidMaxSearchTime2) {
+TEST_P(RadioHidlTest_v1_2, startNetworkScan_InvalidMaxSearchTime2) {
serial = GetRandomSerialNumber();
::android::hardware::radio::V1_2::NetworkScanRequest request = {
@@ -237,7 +237,7 @@
/*
* Test IRadio.startNetworkScan() with invalid periodicity (lower boundary).
*/
-TEST_F(RadioHidlTest_v1_2, startNetworkScan_InvalidPeriodicity1) {
+TEST_P(RadioHidlTest_v1_2, startNetworkScan_InvalidPeriodicity1) {
serial = GetRandomSerialNumber();
::android::hardware::radio::V1_2::NetworkScanRequest request = {
@@ -269,7 +269,7 @@
/*
* Test IRadio.startNetworkScan() with invalid periodicity (upper boundary).
*/
-TEST_F(RadioHidlTest_v1_2, startNetworkScan_InvalidPeriodicity2) {
+TEST_P(RadioHidlTest_v1_2, startNetworkScan_InvalidPeriodicity2) {
serial = GetRandomSerialNumber();
::android::hardware::radio::V1_2::NetworkScanRequest request = {
@@ -301,7 +301,7 @@
/*
* Test IRadio.startNetworkScan() with valid periodicity
*/
-TEST_F(RadioHidlTest_v1_2, startNetworkScan_GoodRequest1) {
+TEST_P(RadioHidlTest_v1_2, startNetworkScan_GoodRequest1) {
serial = GetRandomSerialNumber();
::android::hardware::radio::V1_2::NetworkScanRequest request = {
@@ -335,7 +335,7 @@
/*
* Test IRadio.startNetworkScan() with valid periodicity and plmns
*/
-TEST_F(RadioHidlTest_v1_2, startNetworkScan_GoodRequest2) {
+TEST_P(RadioHidlTest_v1_2, startNetworkScan_GoodRequest2) {
serial = GetRandomSerialNumber();
::android::hardware::radio::V1_2::NetworkScanRequest request = {
@@ -370,7 +370,7 @@
/*
* Test IRadio.setIndicationFilter_1_2()
*/
-TEST_F(RadioHidlTest_v1_2, setIndicationFilter_1_2) {
+TEST_P(RadioHidlTest_v1_2, setIndicationFilter_1_2) {
serial = GetRandomSerialNumber();
Return<void> res = radio_v1_2->setIndicationFilter_1_2(
@@ -388,7 +388,7 @@
/*
* Test IRadio.setSignalStrengthReportingCriteria() with invalid hysteresisDb
*/
-TEST_F(RadioHidlTest_v1_2, setSignalStrengthReportingCriteria_invalidHysteresisDb) {
+TEST_P(RadioHidlTest_v1_2, setSignalStrengthReportingCriteria_invalidHysteresisDb) {
serial = GetRandomSerialNumber();
Return<void> res = radio_v1_2->setSignalStrengthReportingCriteria(
@@ -408,7 +408,7 @@
/*
* Test IRadio.setSignalStrengthReportingCriteria() with empty parameters
*/
-TEST_F(RadioHidlTest_v1_2, setSignalStrengthReportingCriteria_EmptyParams) {
+TEST_P(RadioHidlTest_v1_2, setSignalStrengthReportingCriteria_EmptyParams) {
serial = GetRandomSerialNumber();
Return<void> res = radio_v1_2->setSignalStrengthReportingCriteria(
@@ -426,7 +426,7 @@
/*
* Test IRadio.setSignalStrengthReportingCriteria() for GERAN
*/
-TEST_F(RadioHidlTest_v1_2, setSignalStrengthReportingCriteria_Geran) {
+TEST_P(RadioHidlTest_v1_2, setSignalStrengthReportingCriteria_Geran) {
serial = GetRandomSerialNumber();
Return<void> res = radio_v1_2->setSignalStrengthReportingCriteria(
@@ -445,7 +445,7 @@
/*
* Test IRadio.setSignalStrengthReportingCriteria() for UTRAN
*/
-TEST_F(RadioHidlTest_v1_2, setSignalStrengthReportingCriteria_Utran) {
+TEST_P(RadioHidlTest_v1_2, setSignalStrengthReportingCriteria_Utran) {
serial = GetRandomSerialNumber();
Return<void> res = radio_v1_2->setSignalStrengthReportingCriteria(
@@ -464,7 +464,7 @@
/*
* Test IRadio.setSignalStrengthReportingCriteria() for EUTRAN
*/
-TEST_F(RadioHidlTest_v1_2, setSignalStrengthReportingCriteria_Eutran) {
+TEST_P(RadioHidlTest_v1_2, setSignalStrengthReportingCriteria_Eutran) {
serial = GetRandomSerialNumber();
Return<void> res = radio_v1_2->setSignalStrengthReportingCriteria(
@@ -483,7 +483,7 @@
/*
* Test IRadio.setSignalStrengthReportingCriteria() for CDMA2000
*/
-TEST_F(RadioHidlTest_v1_2, setSignalStrengthReportingCriteria_Cdma2000) {
+TEST_P(RadioHidlTest_v1_2, setSignalStrengthReportingCriteria_Cdma2000) {
serial = GetRandomSerialNumber();
Return<void> res = radio_v1_2->setSignalStrengthReportingCriteria(
@@ -502,7 +502,7 @@
/*
* Test IRadio.setLinkCapacityReportingCriteria() invalid hysteresisDlKbps
*/
-TEST_F(RadioHidlTest_v1_2, setLinkCapacityReportingCriteria_invalidHysteresisDlKbps) {
+TEST_P(RadioHidlTest_v1_2, setLinkCapacityReportingCriteria_invalidHysteresisDlKbps) {
serial = GetRandomSerialNumber();
Return<void> res = radio_v1_2->setLinkCapacityReportingCriteria(
@@ -527,7 +527,7 @@
/*
* Test IRadio.setLinkCapacityReportingCriteria() invalid hysteresisUlKbps
*/
-TEST_F(RadioHidlTest_v1_2, setLinkCapacityReportingCriteria_invalidHysteresisUlKbps) {
+TEST_P(RadioHidlTest_v1_2, setLinkCapacityReportingCriteria_invalidHysteresisUlKbps) {
serial = GetRandomSerialNumber();
Return<void> res = radio_v1_2->setLinkCapacityReportingCriteria(
@@ -552,7 +552,7 @@
/*
* Test IRadio.setLinkCapacityReportingCriteria() empty params
*/
-TEST_F(RadioHidlTest_v1_2, setLinkCapacityReportingCriteria_emptyParams) {
+TEST_P(RadioHidlTest_v1_2, setLinkCapacityReportingCriteria_emptyParams) {
serial = GetRandomSerialNumber();
Return<void> res = radio_v1_2->setLinkCapacityReportingCriteria(
@@ -573,7 +573,7 @@
/*
* Test IRadio.setLinkCapacityReportingCriteria() GERAN
*/
-TEST_F(RadioHidlTest_v1_2, setLinkCapacityReportingCriteria_Geran) {
+TEST_P(RadioHidlTest_v1_2, setLinkCapacityReportingCriteria_Geran) {
serial = GetRandomSerialNumber();
Return<void> res = radio_v1_2->setLinkCapacityReportingCriteria(
@@ -595,7 +595,7 @@
/*
* Test IRadio.setupDataCall_1_2() for the response returned.
*/
-TEST_F(RadioHidlTest_v1_2, setupDataCall_1_2) {
+TEST_P(RadioHidlTest_v1_2, setupDataCall_1_2) {
serial = GetRandomSerialNumber();
::android::hardware::radio::V1_2::AccessNetwork accessNetwork =
@@ -655,7 +655,7 @@
/*
* Test IRadio.deactivateDataCall_1_2() for the response returned.
*/
-TEST_F(RadioHidlTest_v1_2, deactivateDataCall_1_2) {
+TEST_P(RadioHidlTest_v1_2, deactivateDataCall_1_2) {
serial = GetRandomSerialNumber();
int cid = 1;
::android::hardware::radio::V1_2::DataRequestReason reason =
@@ -686,7 +686,7 @@
/*
* Test IRadio.getCellInfoList() for the response returned.
*/
-TEST_F(RadioHidlTest_v1_2, getCellInfoList_1_2) {
+TEST_P(RadioHidlTest_v1_2, getCellInfoList_1_2) {
serial = GetRandomSerialNumber();
Return<void> res = radio_v1_2->getCellInfoList(serial);
@@ -704,7 +704,7 @@
/*
* Test IRadio.getVoiceRegistrationState() for the response returned.
*/
-TEST_F(RadioHidlTest_v1_2, getVoiceRegistrationState) {
+TEST_P(RadioHidlTest_v1_2, getVoiceRegistrationState) {
serial = GetRandomSerialNumber();
Return<void> res = radio_v1_2->getVoiceRegistrationState(serial);
@@ -722,7 +722,7 @@
/*
* Test IRadio.getDataRegistrationState() for the response returned.
*/
-TEST_F(RadioHidlTest_v1_2, getDataRegistrationState) {
+TEST_P(RadioHidlTest_v1_2, getDataRegistrationState) {
serial = GetRandomSerialNumber();
Return<void> res = radio_v1_2->getDataRegistrationState(serial);
@@ -797,7 +797,7 @@
/*
* Test IRadio.getAvailableBandModes() for the response returned.
*/
-TEST_F(RadioHidlTest_v1_2, getAvailableBandModes) {
+TEST_P(RadioHidlTest_v1_2, getAvailableBandModes) {
serial = GetRandomSerialNumber();
Return<void> res = radio_v1_2->getAvailableBandModes(serial);
diff --git a/radio/1.2/vts/functional/radio_hidl_hal_test.cpp b/radio/1.2/vts/functional/radio_hidl_hal_test.cpp
index 21caddb..4845c7f 100644
--- a/radio/1.2/vts/functional/radio_hidl_hal_test.cpp
+++ b/radio/1.2/vts/functional/radio_hidl_hal_test.cpp
@@ -17,18 +17,10 @@
#include <radio_hidl_hal_utils_v1_2.h>
void RadioHidlTest_v1_2::SetUp() {
- radio_v1_2 =
- ::testing::VtsHalHidlTargetTestBase::getService<::android::hardware::radio::V1_2::IRadio>(
- RadioHidlEnvironment::Instance()
- ->getServiceName<::android::hardware::radio::V1_2::IRadio>(
- hidl_string(RADIO_SERVICE_NAME)));
+ radio_v1_2 = ::android::hardware::radio::V1_2::IRadio::getService(GetParam());
if (radio_v1_2 == NULL) {
sleep(60);
- radio_v1_2 = ::testing::VtsHalHidlTargetTestBase::getService<
- ::android::hardware::radio::V1_2::IRadio>(
- RadioHidlEnvironment::Instance()
- ->getServiceName<::android::hardware::radio::V1_2::IRadio>(
- hidl_string(RADIO_SERVICE_NAME)));
+ radio_v1_2 = ::android::hardware::radio::V1_2::IRadio::getService(GetParam());
}
ASSERT_NE(nullptr, radio_v1_2.get());
@@ -51,8 +43,7 @@
/* Enforce Vts Testing with Sim Status Present only. */
EXPECT_EQ(CardState::PRESENT, cardStatus.base.cardState);
- radioConfig = ::testing::VtsHalHidlTargetTestBase::getService<
- ::android::hardware::radio::config::V1_1::IRadioConfig>();
+ radioConfig = ::android::hardware::radio::config::V1_1::IRadioConfig::getService();
/* Enforce Vts tesing with RadioConfig for network scan excemption. */
// Some devices can only perform network scan on logical modem that currently used for packet
diff --git a/radio/1.2/vts/functional/radio_hidl_hal_utils_v1_2.h b/radio/1.2/vts/functional/radio_hidl_hal_utils_v1_2.h
index 2db1cac..479340c 100644
--- a/radio/1.2/vts/functional/radio_hidl_hal_utils_v1_2.h
+++ b/radio/1.2/vts/functional/radio_hidl_hal_utils_v1_2.h
@@ -16,8 +16,7 @@
#include <android-base/logging.h>
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
+#include <log/log.h>
#include <chrono>
#include <condition_variable>
#include <mutex>
@@ -30,6 +29,7 @@
#include <android/hardware/radio/1.2/IRadioIndication.h>
#include <android/hardware/radio/1.2/IRadioResponse.h>
#include <android/hardware/radio/1.2/types.h>
+#include <gtest/gtest.h>
#include "vts_test_util.h"
@@ -631,25 +631,9 @@
const ::android::hardware::hidl_string& reason);
};
-// Test environment for Radio HIDL HAL.
-class RadioHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static RadioHidlEnvironment* Instance() {
- static RadioHidlEnvironment* instance = new RadioHidlEnvironment;
- return instance;
- }
- virtual void registerTestServices() override {
- registerTestService<::android::hardware::radio::V1_2::IRadio>();
- }
-
- private:
- RadioHidlEnvironment() {}
-};
-
// The main test class for Radio HIDL.
-class RadioHidlTest_v1_2 : public ::testing::VtsHalHidlTargetTestBase {
- protected:
+class RadioHidlTest_v1_2 : public ::testing::TestWithParam<std::string> {
+ protected:
std::mutex mtx_;
std::condition_variable cv_;
int count_;
diff --git a/radio/1.3/vts/functional/Android.bp b/radio/1.3/vts/functional/Android.bp
index 67aff6e..2301732 100644
--- a/radio/1.3/vts/functional/Android.bp
+++ b/radio/1.3/vts/functional/Android.bp
@@ -32,5 +32,5 @@
"android.hardware.radio@1.0",
],
header_libs: ["radio.util.header@1.0"],
- test_suites: ["general-tests"],
+ test_suites: ["general-tests", "vts-core"],
}
diff --git a/radio/1.3/vts/functional/AndroidTest.xml b/radio/1.3/vts/functional/AndroidTest.xml
new file mode 100644
index 0000000..c910047
--- /dev/null
+++ b/radio/1.3/vts/functional/AndroidTest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 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.
+-->
+<configuration description="Runs VtsHalRadioV1_3TargetTest.">
+ <option name="test-suite-tag" value="apct" />
+ <option name="test-suite-tag" value="apct-native" />
+
+ <target_preparer class="com.android.tradefed.targetprep.MultiSimPreparer" />
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
+ </target_preparer>
+
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="cleanup" value="true" />
+ <option name="push" value="VtsHalRadioV1_3TargetTest->/data/local/tmp/VtsHalRadioV1_3TargetTest" />
+ </target_preparer>
+
+ <test class="com.android.tradefed.testtype.GTest" >
+ <option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="module-name" value="VtsHalRadioV1_3TargetTest" />
+ </test>
+</configuration>
diff --git a/radio/1.3/vts/functional/VtsHalRadioV1_3TargetTest.cpp b/radio/1.3/vts/functional/VtsHalRadioV1_3TargetTest.cpp
index 7d2623e..2622bbc 100644
--- a/radio/1.3/vts/functional/VtsHalRadioV1_3TargetTest.cpp
+++ b/radio/1.3/vts/functional/VtsHalRadioV1_3TargetTest.cpp
@@ -14,13 +14,12 @@
* limitations under the License.
*/
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include <radio_hidl_hal_utils_v1_3.h>
-int main(int argc, char** argv) {
- ::testing::AddGlobalTestEnvironment(RadioHidlEnvironment::Instance());
- ::testing::InitGoogleTest(&argc, argv);
- RadioHidlEnvironment::Instance()->init(&argc, argv);
- int status = RUN_ALL_TESTS();
- LOG(INFO) << "Test result = " << status;
- return status;
-}
+INSTANTIATE_TEST_SUITE_P(PerInstance, RadioHidlTest_v1_3,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(
+ ::android::hardware::radio::V1_3::IRadio::descriptor)),
+ android::hardware::PrintInstanceNameToString);
\ No newline at end of file
diff --git a/radio/1.3/vts/functional/radio_hidl_hal_api.cpp b/radio/1.3/vts/functional/radio_hidl_hal_api.cpp
index 813dd13..4e48141 100644
--- a/radio/1.3/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.3/vts/functional/radio_hidl_hal_api.cpp
@@ -22,7 +22,7 @@
/*
* Test IRadio.enableMddem() for the response returned.
*/
-TEST_F(RadioHidlTest_v1_3, enableModem) {
+TEST_P(RadioHidlTest_v1_3, enableModem) {
serial = GetRandomSerialNumber();
bool responseToggle = radioRsp_v1_3->enableModemResponseToggle;
@@ -61,7 +61,7 @@
/*
* Test IRadio.getModemStackStatus() for the response returned.
*/
-TEST_F(RadioHidlTest_v1_3, getModemStackStatus) {
+TEST_P(RadioHidlTest_v1_3, getModemStackStatus) {
serial = GetRandomSerialNumber();
Return<void> res = radio_v1_3->getModemStackStatus(serial);
@@ -81,7 +81,7 @@
*
* This test is excluded from manifest, due to non-implementation in Q. Tracked by b/130254624.
*/
-TEST_F(RadioHidlTest_v1_3, setSystemSelectionChannels) {
+TEST_P(RadioHidlTest_v1_3, setSystemSelectionChannels) {
serial = GetRandomSerialNumber();
RadioAccessSpecifier specifier = {.radioAccessNetwork = RadioAccessNetworks::GERAN,
diff --git a/radio/1.3/vts/functional/radio_hidl_hal_test.cpp b/radio/1.3/vts/functional/radio_hidl_hal_test.cpp
index a876b1a..4581350 100644
--- a/radio/1.3/vts/functional/radio_hidl_hal_test.cpp
+++ b/radio/1.3/vts/functional/radio_hidl_hal_test.cpp
@@ -17,18 +17,10 @@
#include <radio_hidl_hal_utils_v1_3.h>
void RadioHidlTest_v1_3::SetUp() {
- radio_v1_3 = ::testing::VtsHalHidlTargetTestBase::getService<
- ::android::hardware::radio::V1_3::IRadio>(
- RadioHidlEnvironment::Instance()
- ->getServiceName<::android::hardware::radio::V1_3::IRadio>(
- hidl_string(RADIO_SERVICE_NAME)));
+ radio_v1_3 = ::android::hardware::radio::V1_3::IRadio::getService(GetParam());
if (radio_v1_3 == NULL) {
sleep(60);
- radio_v1_3 = ::testing::VtsHalHidlTargetTestBase::getService<
- ::android::hardware::radio::V1_3::IRadio>(
- RadioHidlEnvironment::Instance()
- ->getServiceName<::android::hardware::radio::V1_3::IRadio>(
- hidl_string(RADIO_SERVICE_NAME)));
+ radio_v1_3 = ::android::hardware::radio::V1_3::IRadio::getService(GetParam());
}
ASSERT_NE(nullptr, radio_v1_3.get());
diff --git a/radio/1.3/vts/functional/radio_hidl_hal_utils_v1_3.h b/radio/1.3/vts/functional/radio_hidl_hal_utils_v1_3.h
index 1d03a99..893eac5 100644
--- a/radio/1.3/vts/functional/radio_hidl_hal_utils_v1_3.h
+++ b/radio/1.3/vts/functional/radio_hidl_hal_utils_v1_3.h
@@ -16,8 +16,7 @@
#include <android-base/logging.h>
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
+#include <log/log.h>
#include <chrono>
#include <condition_variable>
#include <mutex>
@@ -609,25 +608,9 @@
const ::android::hardware::hidl_string& reason);
};
-// Test environment for Radio HIDL HAL.
-class RadioHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static RadioHidlEnvironment* Instance() {
- static RadioHidlEnvironment* instance = new RadioHidlEnvironment;
- return instance;
- }
- virtual void registerTestServices() override {
- registerTestService<::android::hardware::radio::V1_3::IRadio>();
- }
-
- private:
- RadioHidlEnvironment() {}
-};
-
// The main test class for Radio HIDL.
-class RadioHidlTest_v1_3 : public ::testing::VtsHalHidlTargetTestBase {
- protected:
+class RadioHidlTest_v1_3 : public ::testing::TestWithParam<std::string> {
+ protected:
std::mutex mtx_;
std::condition_variable cv_;
int count_;
diff --git a/radio/1.4/vts/functional/Android.bp b/radio/1.4/vts/functional/Android.bp
index 6827132..8284404 100644
--- a/radio/1.4/vts/functional/Android.bp
+++ b/radio/1.4/vts/functional/Android.bp
@@ -35,5 +35,5 @@
"android.hardware.radio.config@1.1",
],
header_libs: ["radio.util.header@1.0"],
- test_suites: ["general-tests"]
+ test_suites: ["general-tests", "vts-core"]
}
diff --git a/radio/1.4/vts/functional/AndroidTest.xml b/radio/1.4/vts/functional/AndroidTest.xml
new file mode 100644
index 0000000..c910047
--- /dev/null
+++ b/radio/1.4/vts/functional/AndroidTest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 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.
+-->
+<configuration description="Runs VtsHalRadioV1_3TargetTest.">
+ <option name="test-suite-tag" value="apct" />
+ <option name="test-suite-tag" value="apct-native" />
+
+ <target_preparer class="com.android.tradefed.targetprep.MultiSimPreparer" />
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
+ </target_preparer>
+
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="cleanup" value="true" />
+ <option name="push" value="VtsHalRadioV1_3TargetTest->/data/local/tmp/VtsHalRadioV1_3TargetTest" />
+ </target_preparer>
+
+ <test class="com.android.tradefed.testtype.GTest" >
+ <option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="module-name" value="VtsHalRadioV1_3TargetTest" />
+ </test>
+</configuration>
diff --git a/radio/1.4/vts/functional/VtsHalRadioV1_4TargetTest.cpp b/radio/1.4/vts/functional/VtsHalRadioV1_4TargetTest.cpp
index d6330e6..23ec011 100644
--- a/radio/1.4/vts/functional/VtsHalRadioV1_4TargetTest.cpp
+++ b/radio/1.4/vts/functional/VtsHalRadioV1_4TargetTest.cpp
@@ -14,13 +14,12 @@
* limitations under the License.
*/
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include <radio_hidl_hal_utils_v1_4.h>
-int main(int argc, char** argv) {
- ::testing::AddGlobalTestEnvironment(RadioHidlEnvironment::Instance());
- ::testing::InitGoogleTest(&argc, argv);
- RadioHidlEnvironment::Instance()->init(&argc, argv);
- int status = RUN_ALL_TESTS();
- LOG(INFO) << "Test result = " << status;
- return status;
-}
\ No newline at end of file
+INSTANTIATE_TEST_SUITE_P(PerInstance, RadioHidlTest_v1_4,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(
+ ::android::hardware::radio::V1_4::IRadio::descriptor)),
+ android::hardware::PrintInstanceNameToString);
\ No newline at end of file
diff --git a/radio/1.4/vts/functional/radio_hidl_hal_api.cpp b/radio/1.4/vts/functional/radio_hidl_hal_api.cpp
index a4953d7..95136bb 100644
--- a/radio/1.4/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.4/vts/functional/radio_hidl_hal_api.cpp
@@ -21,7 +21,7 @@
/*
* Test IRadio.emergencyDial() for the response returned.
*/
-TEST_F(RadioHidlTest_v1_4, emergencyDial) {
+TEST_P(RadioHidlTest_v1_4, emergencyDial) {
serial = GetRandomSerialNumber();
::android::hardware::radio::V1_0::Dial dialInfo;
@@ -52,7 +52,7 @@
/*
* Test IRadio.emergencyDial() with specified service and its response returned.
*/
-TEST_F(RadioHidlTest_v1_4, emergencyDial_withServices) {
+TEST_P(RadioHidlTest_v1_4, emergencyDial_withServices) {
serial = GetRandomSerialNumber();
::android::hardware::radio::V1_0::Dial dialInfo;
@@ -84,7 +84,7 @@
/*
* Test IRadio.emergencyDial() with known emergency call routing and its response returned.
*/
-TEST_F(RadioHidlTest_v1_4, emergencyDial_withEmergencyRouting) {
+TEST_P(RadioHidlTest_v1_4, emergencyDial_withEmergencyRouting) {
serial = GetRandomSerialNumber();
::android::hardware::radio::V1_0::Dial dialInfo;
@@ -116,7 +116,7 @@
/*
* Test IRadio.getPreferredNetworkTypeBitmap() for the response returned.
*/
-TEST_F(RadioHidlTest_v1_4, getPreferredNetworkTypeBitmap) {
+TEST_P(RadioHidlTest_v1_4, getPreferredNetworkTypeBitmap) {
serial = GetRandomSerialNumber();
Return<void> res = radio_v1_4->getPreferredNetworkTypeBitmap(serial);
@@ -130,7 +130,7 @@
EXPECT_EQ(RadioError::NONE, radioRsp_v1_4->rspInfo.error);
}
-TEST_F(RadioHidlTest_v1_4, setPreferredNetworkTypeBitmap) {
+TEST_P(RadioHidlTest_v1_4, setPreferredNetworkTypeBitmap) {
serial = GetRandomSerialNumber();
::android::hardware::hidl_bitfield<::android::hardware::radio::V1_4::RadioAccessFamily>
network_type_bitmap{};
@@ -175,7 +175,7 @@
* REQUEST_NOT_SUPPORTED will be disallowed for all tests. Modems have "GSM" rat scan need to
* support scanning requests combined with some parameters.
*/
-TEST_F(RadioHidlTest_v1_4, startNetworkScan) {
+TEST_P(RadioHidlTest_v1_4, startNetworkScan) {
serial = GetRandomSerialNumber();
RadioAccessSpecifier specifier = {.radioAccessNetwork = RadioAccessNetworks::GERAN,
@@ -218,7 +218,7 @@
/*
* Test IRadio.startNetworkScan() with invalid specifier.
*/
-TEST_F(RadioHidlTest_v1_4, startNetworkScan_InvalidArgument) {
+TEST_P(RadioHidlTest_v1_4, startNetworkScan_InvalidArgument) {
serial = GetRandomSerialNumber();
::android::hardware::radio::V1_2::NetworkScanRequest request = {.type = ScanType::ONE_SHOT,
@@ -246,7 +246,7 @@
/*
* Test IRadio.startNetworkScan() with invalid interval (lower boundary).
*/
-TEST_F(RadioHidlTest_v1_4, startNetworkScan_InvalidInterval1) {
+TEST_P(RadioHidlTest_v1_4, startNetworkScan_InvalidInterval1) {
serial = GetRandomSerialNumber();
RadioAccessSpecifier specifier = {.radioAccessNetwork = RadioAccessNetworks::GERAN,
@@ -283,7 +283,7 @@
/*
* Test IRadio.startNetworkScan() with invalid interval (upper boundary).
*/
-TEST_F(RadioHidlTest_v1_4, startNetworkScan_InvalidInterval2) {
+TEST_P(RadioHidlTest_v1_4, startNetworkScan_InvalidInterval2) {
serial = GetRandomSerialNumber();
RadioAccessSpecifier specifier = {.radioAccessNetwork = RadioAccessNetworks::GERAN,
@@ -319,7 +319,7 @@
/*
* Test IRadio.startNetworkScan() with invalid max search time (lower boundary).
*/
-TEST_F(RadioHidlTest_v1_4, startNetworkScan_InvalidMaxSearchTime1) {
+TEST_P(RadioHidlTest_v1_4, startNetworkScan_InvalidMaxSearchTime1) {
serial = GetRandomSerialNumber();
RadioAccessSpecifier specifier = {.radioAccessNetwork = RadioAccessNetworks::GERAN,
@@ -355,7 +355,7 @@
/*
* Test IRadio.startNetworkScan() with invalid max search time (upper boundary).
*/
-TEST_F(RadioHidlTest_v1_4, startNetworkScan_InvalidMaxSearchTime2) {
+TEST_P(RadioHidlTest_v1_4, startNetworkScan_InvalidMaxSearchTime2) {
serial = GetRandomSerialNumber();
RadioAccessSpecifier specifier = {.radioAccessNetwork = RadioAccessNetworks::GERAN,
@@ -391,7 +391,7 @@
/*
* Test IRadio.startNetworkScan() with invalid periodicity (lower boundary).
*/
-TEST_F(RadioHidlTest_v1_4, startNetworkScan_InvalidPeriodicity1) {
+TEST_P(RadioHidlTest_v1_4, startNetworkScan_InvalidPeriodicity1) {
serial = GetRandomSerialNumber();
RadioAccessSpecifier specifier = {.radioAccessNetwork = RadioAccessNetworks::GERAN,
@@ -427,7 +427,7 @@
/*
* Test IRadio.startNetworkScan() with invalid periodicity (upper boundary).
*/
-TEST_F(RadioHidlTest_v1_4, startNetworkScan_InvalidPeriodicity2) {
+TEST_P(RadioHidlTest_v1_4, startNetworkScan_InvalidPeriodicity2) {
serial = GetRandomSerialNumber();
RadioAccessSpecifier specifier = {.radioAccessNetwork = RadioAccessNetworks::GERAN,
@@ -463,7 +463,7 @@
/*
* Test IRadio.startNetworkScan() with valid periodicity
*/
-TEST_F(RadioHidlTest_v1_4, startNetworkScan_GoodRequest1) {
+TEST_P(RadioHidlTest_v1_4, startNetworkScan_GoodRequest1) {
serial = GetRandomSerialNumber();
RadioAccessSpecifier specifier = {.radioAccessNetwork = RadioAccessNetworks::GERAN,
@@ -502,7 +502,7 @@
/*
* Test IRadio.startNetworkScan() with valid periodicity and plmns
*/
-TEST_F(RadioHidlTest_v1_4, startNetworkScan_GoodRequest2) {
+TEST_P(RadioHidlTest_v1_4, startNetworkScan_GoodRequest2) {
serial = GetRandomSerialNumber();
RadioAccessSpecifier specifier = {.radioAccessNetwork = RadioAccessNetworks::GERAN,
@@ -543,7 +543,7 @@
/*
* Test IRadio.getSignalStrength_1_4() for the response returned.
*/
-TEST_F(RadioHidlTest_v1_4, getSignalStrength_1_4) {
+TEST_P(RadioHidlTest_v1_4, getSignalStrength_1_4) {
serial = GetRandomSerialNumber();
radio_v1_4->getSignalStrength_1_4(serial);
@@ -562,7 +562,7 @@
/*
* Test IRadio.setupDataCall_1_4() for the response returned.
*/
-TEST_F(RadioHidlTest_v1_4, setupDataCall_1_4) {
+TEST_P(RadioHidlTest_v1_4, setupDataCall_1_4) {
serial = GetRandomSerialNumber();
::android::hardware::radio::V1_4::AccessNetwork accessNetwork =
@@ -617,7 +617,7 @@
/*
* Test IRadio.getAllowedCarriers_1_4() for the response returned.
*/
-TEST_F(RadioHidlTest_v1_4, getAllowedCarriers_1_4) {
+TEST_P(RadioHidlTest_v1_4, getAllowedCarriers_1_4) {
serial = GetRandomSerialNumber();
radio_v1_4->getAllowedCarriers_1_4(serial);
@@ -632,7 +632,7 @@
/**
* Test IRadio.setAllowedCarriers_1_4() for the response returned.
*/
-TEST_F(RadioHidlTest_v1_4, setAllowedCarriers_1_4) {
+TEST_P(RadioHidlTest_v1_4, setAllowedCarriers_1_4) {
serial = GetRandomSerialNumber();
CarrierRestrictionsWithPriority carrierRestrictions;
memset(&carrierRestrictions, 0, sizeof(carrierRestrictions));
@@ -727,7 +727,7 @@
}
}
-TEST_F(RadioHidlTest_v1_4, setDataProfile_1_4) {
+TEST_P(RadioHidlTest_v1_4, setDataProfile_1_4) {
serial = GetRandomSerialNumber();
// Create a dataProfileInfo
@@ -770,7 +770,7 @@
}
}
-TEST_F(RadioHidlTest_v1_4, setInitialAttachApn_1_4) {
+TEST_P(RadioHidlTest_v1_4, setInitialAttachApn_1_4) {
serial = GetRandomSerialNumber();
// Create a dataProfileInfo
@@ -812,7 +812,7 @@
/*
* Test IRadio.getDataRegistrationStateResponse_1_4() for the response returned.
*/
-TEST_F(RadioHidlTest_v1_4, getDataRegistrationState_1_4) {
+TEST_P(RadioHidlTest_v1_4, getDataRegistrationState_1_4) {
int rat;
serial = GetRandomSerialNumber();
diff --git a/radio/1.4/vts/functional/radio_hidl_hal_test.cpp b/radio/1.4/vts/functional/radio_hidl_hal_test.cpp
index f27749b..15a0b24 100644
--- a/radio/1.4/vts/functional/radio_hidl_hal_test.cpp
+++ b/radio/1.4/vts/functional/radio_hidl_hal_test.cpp
@@ -17,18 +17,11 @@
#include <radio_hidl_hal_utils_v1_4.h>
void RadioHidlTest_v1_4::SetUp() {
- radio_v1_4 = ::testing::VtsHalHidlTargetTestBase::getService<
- ::android::hardware::radio::V1_4::IRadio>(
- RadioHidlEnvironment::Instance()
- ->getServiceName<::android::hardware::radio::V1_4::IRadio>(
- hidl_string(RADIO_SERVICE_NAME)));
+ radio_v1_4 = ::android::hardware::radio::V1_4::IRadio::getService(GetParam());
+
if (radio_v1_4 == NULL) {
sleep(60);
- radio_v1_4 = ::testing::VtsHalHidlTargetTestBase::getService<
- ::android::hardware::radio::V1_4::IRadio>(
- RadioHidlEnvironment::Instance()
- ->getServiceName<::android::hardware::radio::V1_4::IRadio>(
- hidl_string(RADIO_SERVICE_NAME)));
+ radio_v1_4 = ::android::hardware::radio::V1_4::IRadio::getService(GetParam());
}
ASSERT_NE(nullptr, radio_v1_4.get());
@@ -48,8 +41,7 @@
EXPECT_EQ(RadioError::NONE, radioRsp_v1_4->rspInfo.error);
sp<::android::hardware::radio::config::V1_1::IRadioConfig> radioConfig =
- ::testing::VtsHalHidlTargetTestBase::getService<
- ::android::hardware::radio::config::V1_1::IRadioConfig>();
+ ::android::hardware::radio::config::V1_1::IRadioConfig::getService();
/* Enforce Vts tesing with RadioConfig is existed. */
ASSERT_NE(nullptr, radioConfig.get());
diff --git a/radio/1.4/vts/functional/radio_hidl_hal_utils_v1_4.h b/radio/1.4/vts/functional/radio_hidl_hal_utils_v1_4.h
index b07f9c3..31b7e13 100644
--- a/radio/1.4/vts/functional/radio_hidl_hal_utils_v1_4.h
+++ b/radio/1.4/vts/functional/radio_hidl_hal_utils_v1_4.h
@@ -16,8 +16,7 @@
#include <android-base/logging.h>
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
+#include <log/log.h>
#include <chrono>
#include <condition_variable>
#include <mutex>
@@ -28,6 +27,7 @@
#include <android/hardware/radio/1.4/IRadioIndication.h>
#include <android/hardware/radio/1.4/IRadioResponse.h>
#include <android/hardware/radio/1.4/types.h>
+#include <gtest/gtest.h>
#include "vts_test_util.h"
@@ -705,25 +705,9 @@
const ::android::hardware::hidl_string& reason);
};
-// Test environment for Radio HIDL HAL.
-class RadioHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static RadioHidlEnvironment* Instance() {
- static RadioHidlEnvironment* instance = new RadioHidlEnvironment;
- return instance;
- }
- virtual void registerTestServices() override {
- registerTestService<::android::hardware::radio::V1_4::IRadio>();
- }
-
- private:
- RadioHidlEnvironment() {}
-};
-
// The main test class for Radio HIDL.
-class RadioHidlTest_v1_4 : public ::testing::VtsHalHidlTargetTestBase {
- protected:
+class RadioHidlTest_v1_4 : public ::testing::TestWithParam<std::string> {
+ protected:
std::mutex mtx_;
std::condition_variable cv_;
int count_;
diff --git a/radio/1.5/Android.bp b/radio/1.5/Android.bp
index de9ec6e..06a2a6e 100644
--- a/radio/1.5/Android.bp
+++ b/radio/1.5/Android.bp
@@ -19,6 +19,7 @@
"android.hardware.radio@1.3",
"android.hardware.radio@1.4",
"android.hidl.base@1.0",
+ "android.hidl.safe_union@1.0",
],
gen_java: true,
}
diff --git a/radio/1.5/IRadio.hal b/radio/1.5/IRadio.hal
index 74ec56d..62a2c61 100644
--- a/radio/1.5/IRadio.hal
+++ b/radio/1.5/IRadio.hal
@@ -16,8 +16,12 @@
package android.hardware.radio@1.5;
+import @1.2::DataRequestReason;
import @1.4::IRadio;
import @1.5::AccessNetwork;
+import @1.5::DataProfileInfo;
+import @1.5::NetworkScanRequest;
+import @1.5::RadioAccessSpecifier;
import @1.5::SignalThresholdInfo;
/**
@@ -29,7 +33,6 @@
* setResponseFunctions must work with @1.5::IRadioResponse and @1.5::IRadioIndication.
*/
interface IRadio extends @1.4::IRadio {
-
/**
* Sets the signal strength reporting criteria.
*
@@ -41,18 +44,181 @@
* -EUTRAN - RSRP/RSRQ/RSSNR
* -NGRAN - SSRSRP/SSRSRQ/SSSINR
*
- * Note: Reporting criteria must be individually set for each RAN. For any unset reporting
- * criteria, the value is implementation-defined.
+ * Note: Reporting criteria must be individually set for each RAN. For each RAN, if none of
+ * reporting criteria of any measurement is set enabled
+ * (see @1.5::SignalThresholdInfo.isEnabled), the reporting criteria for this RAN is
+ * implementation-defined. For each RAN, if any of reporting criteria of any measure is set
+ * enabled, the reporting criteria of the other measures in this RAN are set disabled
+ * (see @1.5::SignalThresholdInfo.isEnabled) until they are set enabled.
*
* Response callback is
* IRadioResponse.setSignalStrengthReportingCriteriaResponse_1_5()
*
* @param serial Serial number of request.
* @param signalThresholdInfo Signal threshold info including the threshold values,
- * hysteresisDb, and hysteresisMs. See @1.5::SignalThresholdInfo
- * for details.
+ * hysteresisDb, hysteresisMs and isEnabled.
+ * See @1.5::SignalThresholdInfo for details.
* @param accessNetwork The type of network for which to apply these thresholds.
*/
oneway setSignalStrengthReportingCriteria_1_5(int32_t serial,
SignalThresholdInfo signalThresholdInfo, AccessNetwork accessNetwork);
+
+ /**
+ * Enable or disable UiccApplications on the SIM. If disabled:
+ * - Modem will not register on any network.
+ * - SIM must be PRESENT, and the IccId of the SIM must still be accessible.
+ * - The corresponding modem stack is still functional, e.g. able to make emergency calls or
+ * do network scan.
+ * By default if this API is not called, the uiccApplications must be enabled automatically.
+ * It must work for both single SIM and DSDS cases for UX consistency.
+ * The preference is per SIM, and must be remembered over power cycle, modem reboot, or SIM
+ * insertion / unplug.
+ *
+ * @param serial Serial number of request.
+ * @param enable true if to enable uiccApplications, false to disable.
+
+ * Response callback is IRadioResponse.enableUiccApplicationsResponse()
+ */
+ oneway enableUiccApplications(int32_t serial, bool enable);
+
+ /**
+ * Whether uiccApplications are enabled, or disabled.
+ *
+ * By default uiccApplications must be enabled, unless enableUiccApplications() with enable
+ * being false is called.
+ *
+ * @param serial Serial number of request.
+ *
+ * Response callback is IRadioResponse.areUiccApplicationsEnabledResponse()
+ */
+ oneway areUiccApplicationsEnabled(int32_t serial);
+
+ /**
+ * Specify which bands modem's background scan must act on.
+ * If specifyChannels is true, it only scans bands specified in specifiers.
+ * If specifyChannels is false, it scans all bands.
+ *
+ * For example, CBRS is only on LTE band 48. By specifying this band,
+ * modem saves more power.
+ *
+ * @param serial Serial number of request.
+ * @param specifyChannels whether to scan bands defined in specifiers.
+ * @param specifiers which bands to scan. Only used if specifyChannels is true.
+ *
+ * Response callback is IRadioResponse.setSystemSelectionChannelsResponse()
+ */
+ oneway setSystemSelectionChannels_1_5(int32_t serial, bool specifyChannels,
+ vec<RadioAccessSpecifier> specifiers);
+
+ /**
+ * Starts a network scan
+ *
+ * @param serial Serial number of request.
+ * @param request Defines the radio networks/bands/channels which need to be scanned.
+ *
+ * Same API as @1.4::IRadio.startNetworkScan_1_4, except using
+ * 1.5 version of NetworkScanRequest
+ */
+ oneway startNetworkScan_1_5(int32_t serial, NetworkScanRequest request);
+
+ /**
+ * Setup a packet data connection. If DataCallResponse.status returns DataCallFailCause:NONE,
+ * the data connection must be added to data calls and a unsolDataCallListChanged() must be
+ * sent. The call remains until removed by subsequent unsolDataCallIstChanged(). It may be
+ * lost due to many factors, including deactivateDataCall() being issued, the radio powered
+ * off, reception lost or even transient factors like congestion. This data call list is
+ * returned by getDataCallList() and dataCallListChanged().
+ *
+ * The Radio is expected to:
+ * - Create one data call context.
+ * - Create and configure a dedicated interface for the context.
+ * - The interface must be point to point.
+ * - The interface is configured with one or more addresses and is capable of sending and
+ * receiving packets. The prefix length of the addresses must be /32 for IPv4 and /128
+ * for IPv6.
+ * - Must not modify routing configuration related to this interface; routing management is
+ * exclusively within the purview of the Android OS.
+ * - Support simultaneous data call contexts up to DataRegStateResult.maxDataCalls specified
+ * in the response of getDataRegistrationState.
+ *
+ * @param serial Serial number of request.
+ * @param accessNetwork The access network to setup the data call. If the data connection cannot
+ * be established on the specified access network, the setup request must be failed.
+ * @param dataProfileInfo Data profile info.
+ * @param roamingAllowed Indicates whether or not data roaming is allowed by the user.
+ * @param reason The request reason. Must be DataRequestReason.NORMAL or
+ * DataRequestReason.HANDOVER.
+ * @param addresses If the reason is DataRequestReason.HANDOVER, this indicates the list of link
+ * addresses of the existing data connection. The format is IP address with optional "/"
+ * prefix length (The format is defined in RFC-4291 section 2.3). For example, "192.0.1.3",
+ * "192.0.1.11/16", or "2001:db8::1/64". Typically one IPv4 or one IPv6 or one of each. If
+ * the prefix length is absent, then the addresses are assumed to be point to point with
+ * IPv4 with prefix length 32 or IPv6 with prefix length 128. This parameter must be ignored
+ * unless reason is DataRequestReason.HANDOVER.
+ * @param dnses If the reason is DataRequestReason.HANDOVER, this indicates the list of DNS
+ * addresses of the existing data connection. The format is defined in RFC-4291 section
+ * 2.2. For example, "192.0.1.3" or "2001:db8::1". This parameter must be ignored unless
+ * reason is DataRequestReason.HANDOVER.
+ *
+ * Response function is IRadioResponse.setupDataCallResponse_1_5()
+ *
+ * Note this API is the same as the 1.4 version except using the
+ * 1.5 AccessNetwork and DataProfileInto as the input param.
+ */
+ oneway setupDataCall_1_5(int32_t serial, AccessNetwork accessNetwork,
+ DataProfileInfo dataProfileInfo, bool roamingAllowed,
+ DataRequestReason reason, vec<string> addresses, vec<string> dnses);
+
+ /**
+ * Set an apn to initial attach network
+ *
+ * @param serial Serial number of request.
+ * @param dataProfileInfo data profile containing APN settings
+ *
+ * Response callback is IRadioResponse.setInitialAttachApnResponse_1_5()
+ *
+ * Note this API is the same as the 1.4 version except using the 1.5 DataProfileInfo
+ * as the input param.
+ */
+ oneway setInitialAttachApn_1_5(int32_t serial, DataProfileInfo dataProfileInfo);
+
+ /**
+ * Send data profiles of the current carrier to the modem.
+ *
+ * @param serial Serial number of request.
+ * @param profiles Array of DataProfile to set.
+ *
+ * Response callback is IRadioResponse.setDataProfileResponse_1_5()
+ *
+ * Note this API is the same as the 1.4 version except using the 1.5 DataProfileInfo
+ * as the input param.
+ */
+ oneway setDataProfile_1_5(int32_t serial, vec<DataProfileInfo> profiles);
+
+ /**
+ * Toggle radio on and off (for "airplane" mode)
+ * If the radio is turned off/on the radio modem subsystem
+ * is expected return to an initialized state. For instance,
+ * any voice and data calls must be terminated and all associated
+ * lists emptied.
+ *
+ * When setting radio power on to exit from airplane mode to place an emergency call on this
+ * logical modem, powerOn, forEmergencyCall and preferredForEmergencyCall must be true. In
+ * this case, this modem is optimized to scan only emergency call bands, until:
+ * 1) Emergency call is completed; or
+ * 2) Another setRadioPower_1_5 is issued with forEmergencyCall being false or
+ * preferredForEmergencyCall being false; or
+ * 3) Timeout after a long period of time.
+ *
+ * @param serial Serial number of request.
+ * @param powerOn To turn on radio -> on = true, to turn off radio -> on = false.
+ * @param forEmergencyCall To indication to radio if this request is due to emergency call.
+ * No effect if powerOn is false.
+ * @param preferredForEmergencyCall indicate whether the following emergency call will be sent
+ * on this modem or not. No effect if forEmergencyCall is false, or powerOn is false.
+ *
+ * Response callback is IRadioConfigResponse. setRadioPowerResponse_1_5.
+ */
+ oneway setRadioPower_1_5(int32_t serial, bool powerOn, bool forEmergencyCall,
+ bool preferredForEmergencyCall);
};
diff --git a/radio/1.5/IRadioIndication.hal b/radio/1.5/IRadioIndication.hal
index d488404..81452ab 100644
--- a/radio/1.5/IRadioIndication.hal
+++ b/radio/1.5/IRadioIndication.hal
@@ -23,4 +23,11 @@
* Interface declaring unsolicited radio indications.
*/
interface IRadioIndication extends @1.4::IRadioIndication {
+ /**
+ * Report change of whether uiccApplications are enabled, or disabled.
+ *
+ * @param type Type of radio indication
+ * @param enabled whether uiccApplications are enabled, or disabled
+ */
+ oneway uiccApplicationsEnablementChanged(RadioIndicationType type, bool enabled);
};
diff --git a/radio/1.5/IRadioResponse.hal b/radio/1.5/IRadioResponse.hal
index 91dc1e0..7a0bc57 100644
--- a/radio/1.5/IRadioResponse.hal
+++ b/radio/1.5/IRadioResponse.hal
@@ -18,6 +18,7 @@
import @1.0::RadioResponseInfo;
import @1.4::IRadioResponse;
+import @1.4::SetupDataCallResult;
/**
* Interface declaring response functions to solicited radio requests.
@@ -32,4 +33,116 @@
* RadioError:RADIO_NOT_AVAILABLE
*/
oneway setSignalStrengthReportingCriteriaResponse_1_5(RadioResponseInfo info);
+
+ /**
+ * @param info Response info struct containing response type, serial no. and error
+ *
+ * Valid errors returned:
+ * RadioError:NONE
+ * RadioError:SIM_ABSENT
+ * RadioError:RADIO_NOT_AVAILABLE
+ * RadioError:INTERNAL_ERR
+ * RadioError:BUSY
+ */
+ oneway enableUiccApplicationsResponse(RadioResponseInfo info);
+
+ /**
+ * @param info Response info struct containing response type, serial no. and error
+ * @param enabled whether Uicc applications are enabled.
+ *
+ * Valid errors returned:
+ * RadioError:NONE
+ * RadioError:SIM_ABSENT
+ * RadioError:RADIO_NOT_AVAILABLE
+ * RadioError:INTERNAL_ERR
+ */
+ oneway areUiccApplicationsEnabledResponse(RadioResponseInfo info, bool enabled);
+
+ /**
+ * @param info Response info struct containing response type, serial no. and error
+ *
+ * Valid errors returned:
+ * RadioError:NONE
+ * RadioError:RADIO_NOT_AVAILABLE
+ * RadioError:INTERNAL_ERR
+ * RadioError:INVALID_ARGUMENTS
+ */
+ oneway setSystemSelectionChannelsResponse_1_5(RadioResponseInfo info);
+
+ /**
+ * @param info Response info struct containing response type, serial no. and error
+ *
+ * Valid errors returned:
+ * RadioError:NONE
+ * RadioError:RADIO_NOT_AVAILABLE
+ * RadioError:DEVICE_IN_USE
+ * RadioError:INTERNAL_ERR
+ * RadioError:MODEM_ERR
+ * RadioError:INVALID_ARGUMENTS
+ */
+ oneway startNetworkScanResponse_1_5(RadioResponseInfo info);
+
+ /**
+ * @param info Response info struct containing response type, serial no. and error
+ * @param dcResponse SetupDataCallResult defined in types.hal
+ *
+ * Valid errors returned:
+ * RadioError:NONE must be returned on both success and failure of setup with the
+ * DataCallResponse.status containing the actual status
+ * For all other errors the DataCallResponse is ignored.
+ * RadioError:RADIO_NOT_AVAILABLE
+ * RadioError:OP_NOT_ALLOWED_BEFORE_REG_TO_NW
+ * RadioError:OP_NOT_ALLOWED_DURING_VOICE_CALL
+ * RadioError:REQUEST_NOT_SUPPORTED
+ * RadioError:INVALID_ARGUMENTS
+ * RadioError:INTERNAL_ERR
+ * RadioError:NO_RESOURCES
+ * RadioError:SIM_ABSENT
+ */
+ oneway setupDataCallResponse_1_5(RadioResponseInfo info, SetupDataCallResult dcResponse);
+
+ /**
+ * @param info Response info struct containing response type, serial no. and error
+ *
+ * Valid errors returned:
+ * RadioError:NONE
+ * RadioError:RADIO_NOT_AVAILABLE
+ * RadioError:SUBSCRIPTION_NOT_AVAILABLE
+ * RadioError:NO_MEMORY
+ * RadioError:INTERNAL_ERR
+ * RadioError:SYSTEM_ERR
+ * RadioError:MODEM_ERR
+ * RadioError:INVALID_ARGUMENTS
+ * RadioError:NOT_PROVISIONED
+ * RadioError:REQUEST_NOT_SUPPORTED
+ * RadioError:NO_RESOURCES
+ * RadioError:CANCELLED
+ */
+ oneway setInitialAttachApnResponse_1_5(RadioResponseInfo info);
+
+ /**
+ * @param info Response info struct containing response type, serial no. and error
+ *
+ * Valid errors returned:
+ * RadioError:NONE
+ * RadioError:RADIO_NOT_AVAILABLE
+ * RadioError:SUBSCRIPTION_NOT_AVAILABLE
+ * RadioError:INTERNAL_ERR
+ * RadioError:NO_MEMORY
+ * RadioError:NO_RESOURCES
+ * RadioError:CANCELLED
+ * RadioError:REQUEST_NOT_SUPPORTED
+ * RadioError:SIM_ABSENT
+ */
+ oneway setDataProfileResponse_1_5(RadioResponseInfo info);
+
+ /**
+ * @param info Response info struct containing response type, serial no. and error
+ *
+ * Valid errors returned:
+ * RadioError:NONE
+ * RadioError:INTERNAL_ERR
+ * RadioError:INVALID_ARGUMENTS
+ */
+ oneway setRadioPowerResponse_1_5(RadioResponseInfo info);
};
diff --git a/radio/1.5/types.hal b/radio/1.5/types.hal
index 2441b65..5795f7b 100644
--- a/radio/1.5/types.hal
+++ b/radio/1.5/types.hal
@@ -16,7 +16,16 @@
package android.hardware.radio@1.5;
+import @1.1::EutranBands;
+import @1.1::GeranBands;
+import @1.1::RadioAccessNetworks;
+import @1.1::RadioAccessSpecifier;
+import @1.1::ScanType;
+import @1.1::UtranBands;
+import @1.2::NetworkScanRequest;
import @1.4::AccessNetwork;
+import @1.4::ApnTypes;
+import @1.4::DataProfileInfo;
/**
* Defining signal strength type.
@@ -106,6 +115,15 @@
* A vector size of 0 disables the use of thresholds for reporting.
*/
vec<int32_t> thresholds;
+
+ /**
+ * Indicates whether the reporting criteria of the corresponding measurement is enabled
+ * (isEnabled==true) or disabled (isEnabled==false).
+ *
+ * If enabled, modem must trigger the report based on the criteria.
+ * If disabled, modem must not trigger the report based on the criteria.
+ */
+ bool isEnabled;
};
enum AccessNetwork : @1.4::AccessNetwork {
@@ -114,3 +132,160 @@
*/
NGRAN = 6,
};
+
+enum RadioAccessNetworks : @1.1::RadioAccessNetworks {
+ NGRAN = 4,
+};
+
+/**
+ * Overwritten from @1.1::RadioAccessSpecifier to add NGRAN and NgranBands
+ */
+struct RadioAccessSpecifier {
+ /**
+ * The type of network to scan.
+ */
+ RadioAccessNetworks radioAccessNetwork;
+
+ /**
+ * The frequency bands to scan.
+ * Maximum length of the vector is 8.
+ */
+ safe_union Bands {
+ /** Valid only if radioAccessNetwork = GERAN. */
+ vec<GeranBands> geranBands;
+ /** Valid only if radioAccessNetwork = UTRAN. */
+ vec<UtranBands> utranBands;
+ /** Valid only if radioAccessNetwork = EUTRAN. */
+ vec<EutranBands> eutranBands;
+ /** Valid only if radioAccessNetwork = NGRAN. */
+ vec<NgranBands> ngranBands;
+ } bands;
+
+ /**
+ * The radio channels to scan as defined in 3GPP TS 25.101 and 36.101.
+ * Maximum length of the vector is 32.
+ */
+ vec<int32_t> channels;
+};
+
+enum NgranBands : int32_t {
+ /** 3GPP TS 38.101-1, Table 5.2-1: FR1 bands */
+ BAND_1 = 1,
+ BAND_2 = 2,
+ BAND_3 = 3,
+ BAND_5 = 5,
+ BAND_7 = 7,
+ BAND_8 = 8,
+ BAND_12 = 12,
+ BAND_14 = 14,
+ BAND_18 = 18,
+ BAND_20 = 20,
+ BAND_25 = 25,
+ BAND_28 = 28,
+ BAND_29 = 29,
+ BAND_30 = 30,
+ BAND_34 = 34,
+ BAND_38 = 38,
+ BAND_39 = 39,
+ BAND_40 = 40,
+ BAND_41 = 41,
+ BAND_48 = 48,
+ BAND_50 = 50,
+ BAND_51 = 51,
+ BAND_65 = 65,
+ BAND_66 = 66,
+ BAND_70 = 70,
+ BAND_71 = 71,
+ BAND_74 = 74,
+ BAND_75 = 75,
+ BAND_76 = 76,
+ BAND_77 = 77,
+ BAND_78 = 78,
+ BAND_79 = 79,
+ BAND_80 = 80,
+ BAND_81 = 81,
+ BAND_82 = 82,
+ BAND_83 = 83,
+ BAND_84 = 84,
+ BAND_86 = 86,
+ BAND_90 = 90,
+ /** 3GPP TS 38.101-2, Table 5.2-1: FR2 bands */
+ BAND_257 = 257,
+ BAND_258 = 258,
+ BAND_260 = 260,
+ BAND_261 = 261,
+};
+
+/**
+ * Overwritten from @1.2::NetworkScanRequest to update
+ * RadioAccessSpecifier to 1.5 version
+ */
+struct NetworkScanRequest {
+ ScanType type;
+
+ /**
+ * Time interval in seconds between the completion of one scan and the start of
+ * a subsequent scan.
+ * Implementations may ignore this field unless the 'type' is 'PERIODIC'.
+ * Range: ScanIntervalRange:MIN to ScanIntervalRange:MAX
+ */
+ int32_t interval;
+
+ /**
+ * Networks with bands/channels to scan
+ * Maximum length of the vector is RadioConst:RADIO_ACCESS_SPECIFIER_MAX_SIZE
+ */
+ vec<RadioAccessSpecifier> specifiers;
+
+ /**
+ * Maximum duration of the periodic search (in seconds).
+ * If the search lasts maxSearchTime, it must be terminated.
+ * Range: MaxSearchTimeRange:MIN to MaxSearchTimeRange:MAX
+ */
+ int32_t maxSearchTime;
+
+ /**
+ * Indicates whether the modem must report incremental results of the network scan
+ * to the client.
+ * FALSE – Incremental results must not be reported.
+ * TRUE – Incremental must be reported.
+ */
+ bool incrementalResults;
+
+ /**
+ * Indicates the periodicity with which the modem must report incremental results to
+ * the client (in seconds).
+ * Implementations may ignore this value if the incremental results are not requested.
+ * This value must be less than or equal to maxSearchTime.
+ * Range: IncrementalResultsPeriodicityRange:MIN to IncrementalResultsPeriodicityRange:MAX
+ */
+ int32_t incrementalResultsPeriodicity;
+
+ /**
+ * Describes the List of PLMN ids (MCC-MNC)
+ * If any PLMN of this list is found, search must end at that point and results with all
+ * PLMN found until that point should be sent as response.
+ * If the list is not sent, search to be completed until end and all PLMNs found to be
+ * reported.
+ */
+ vec<string> mccMncs;
+};
+
+enum ApnTypes : @1.4::ApnTypes {
+ /**
+ * APN type for XCAP
+ * NOTE: Due to the addition of this new value, the value ALL defined in
+ * 1.0::ApnTypes is deprecated and should not be used.
+ */
+ XCAP = 1 << 11,
+};
+
+/**
+ * Extended from @1.4::DataProfileInfo to update ApnTypes to 1.5 version
+ */
+struct DataProfileInfo {
+ @1.4::DataProfileInfo base;
+
+ /** Supported APN types bitmap. See ApnTypes for the value of each bit. */
+ bitfield<ApnTypes> supportedApnTypesBitmap;
+};
diff --git a/radio/1.5/vts/functional/VtsHalRadioV1_5TargetTest.cpp b/radio/1.5/vts/functional/VtsHalRadioV1_5TargetTest.cpp
index b72febd..5f11d19 100644
--- a/radio/1.5/vts/functional/VtsHalRadioV1_5TargetTest.cpp
+++ b/radio/1.5/vts/functional/VtsHalRadioV1_5TargetTest.cpp
@@ -23,4 +23,4 @@
int status = RUN_ALL_TESTS();
LOG(INFO) << "Test result = " << status;
return status;
-}
\ No newline at end of file
+}
diff --git a/radio/1.5/vts/functional/radio_hidl_hal_api.cpp b/radio/1.5/vts/functional/radio_hidl_hal_api.cpp
index d173411..d05d2cb 100644
--- a/radio/1.5/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.5/vts/functional/radio_hidl_hal_api.cpp
@@ -29,6 +29,7 @@
signalThresholdInfo.hysteresisMs = 5000;
signalThresholdInfo.hysteresisDb = 10; // hysteresisDb too large given threshold list deltas
signalThresholdInfo.thresholds = {-109, -103, -97, -89};
+ signalThresholdInfo.isEnabled = true;
Return<void> res = radio_v1_5->setSignalStrengthReportingCriteria_1_5(
serial, signalThresholdInfo, ::android::hardware::radio::V1_5::AccessNetwork::GERAN);
@@ -52,6 +53,7 @@
signalThresholdInfo.signalMeasurement = SignalMeasurementType::RSSI;
signalThresholdInfo.hysteresisMs = 0;
signalThresholdInfo.hysteresisDb = 0;
+ signalThresholdInfo.isEnabled = true;
Return<void> res = radio_v1_5->setSignalStrengthReportingCriteria_1_5(
serial, signalThresholdInfo, ::android::hardware::radio::V1_5::AccessNetwork::GERAN);
@@ -76,6 +78,7 @@
signalThresholdInfo.hysteresisMs = 5000;
signalThresholdInfo.hysteresisDb = 2;
signalThresholdInfo.thresholds = {-109, -103, -97, -89};
+ signalThresholdInfo.isEnabled = true;
Return<void> res = radio_v1_5->setSignalStrengthReportingCriteria_1_5(
serial, signalThresholdInfo, ::android::hardware::radio::V1_5::AccessNetwork::GERAN);
@@ -100,6 +103,7 @@
signalThresholdInfo.hysteresisMs = 5000;
signalThresholdInfo.hysteresisDb = 2;
signalThresholdInfo.thresholds = {-110, -97, -73, -49, -25};
+ signalThresholdInfo.isEnabled = true;
Return<void> res = radio_v1_5->setSignalStrengthReportingCriteria_1_5(
serial, signalThresholdInfo, ::android::hardware::radio::V1_5::AccessNetwork::UTRAN);
@@ -124,6 +128,7 @@
signalThresholdInfo.hysteresisMs = 5000;
signalThresholdInfo.hysteresisDb = 2;
signalThresholdInfo.thresholds = {-128, -108, -88, -68};
+ signalThresholdInfo.isEnabled = true;
Return<void> res = radio_v1_5->setSignalStrengthReportingCriteria_1_5(
serial, signalThresholdInfo, ::android::hardware::radio::V1_5::AccessNetwork::EUTRAN);
@@ -148,6 +153,7 @@
signalThresholdInfo.hysteresisMs = 5000;
signalThresholdInfo.hysteresisDb = 2;
signalThresholdInfo.thresholds = {-27, -20, -13, -6};
+ signalThresholdInfo.isEnabled = true;
Return<void> res = radio_v1_5->setSignalStrengthReportingCriteria_1_5(
serial, signalThresholdInfo, ::android::hardware::radio::V1_5::AccessNetwork::EUTRAN);
@@ -172,6 +178,7 @@
signalThresholdInfo.hysteresisMs = 5000;
signalThresholdInfo.hysteresisDb = 2;
signalThresholdInfo.thresholds = {-10, 0, 10, 20};
+ signalThresholdInfo.isEnabled = true;
Return<void> res = radio_v1_5->setSignalStrengthReportingCriteria_1_5(
serial, signalThresholdInfo, ::android::hardware::radio::V1_5::AccessNetwork::EUTRAN);
@@ -192,6 +199,7 @@
signalThresholdInfo.hysteresisMs = 5000;
signalThresholdInfo.hysteresisDb = 2;
signalThresholdInfo.thresholds = {-105, -90, -75, -65};
+ signalThresholdInfo.isEnabled = true;
Return<void> res = radio_v1_5->setSignalStrengthReportingCriteria_1_5(
serial, signalThresholdInfo, ::android::hardware::radio::V1_5::AccessNetwork::CDMA2000);
@@ -216,6 +224,7 @@
signalThresholdInfo.hysteresisMs = 5000;
signalThresholdInfo.hysteresisDb = 0;
signalThresholdInfo.thresholds = {-105, -90, -75, -65};
+ signalThresholdInfo.isEnabled = true;
Return<void> res = radio_v1_5->setSignalStrengthReportingCriteria_1_5(
serial, signalThresholdInfo, ::android::hardware::radio::V1_5::AccessNetwork::NGRAN);
@@ -240,6 +249,7 @@
signalThresholdInfo.hysteresisMs = 5000;
signalThresholdInfo.hysteresisDb = 0;
signalThresholdInfo.thresholds = {-15, -10, -5, -4};
+ signalThresholdInfo.isEnabled = true;
Return<void> res = radio_v1_5->setSignalStrengthReportingCriteria_1_5(
serial, signalThresholdInfo, ::android::hardware::radio::V1_5::AccessNetwork::NGRAN);
@@ -254,6 +264,27 @@
}
/*
+ * Test IRadio.setSignalStrengthReportingCriteria_1_5() for EUTRAN
+ */
+TEST_F(RadioHidlTest_v1_5, setSignalStrengthReportingCriteria_1_5_Disable_RSSNR) {
+ serial = GetRandomSerialNumber();
+
+ ::android::hardware::radio::V1_5::SignalThresholdInfo signalThresholdInfo;
+ signalThresholdInfo.signalMeasurement = SignalMeasurementType::RSSNR;
+ signalThresholdInfo.hysteresisMs = 5000;
+ signalThresholdInfo.hysteresisDb = 2;
+ signalThresholdInfo.thresholds = {-10, 0, 10, 20};
+ signalThresholdInfo.isEnabled = false;
+
+ Return<void> res = radio_v1_5->setSignalStrengthReportingCriteria_1_5(
+ serial, signalThresholdInfo, ::android::hardware::radio::V1_5::AccessNetwork::EUTRAN);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
+}
+
+/*
* Test IRadio.setSignalStrengthReportingCriteria_1_5() for NGRAN_SSSINR
*/
TEST_F(RadioHidlTest_v1_5, setSignalStrengthReportingCriteria_1_5_NGRAN_SSSINR) {
@@ -264,6 +295,7 @@
signalThresholdInfo.hysteresisMs = 5000;
signalThresholdInfo.hysteresisDb = 0;
signalThresholdInfo.thresholds = {-10, 3, 16, 18};
+ signalThresholdInfo.isEnabled = true;
Return<void> res = radio_v1_5->setSignalStrengthReportingCriteria_1_5(
serial, signalThresholdInfo, ::android::hardware::radio::V1_5::AccessNetwork::NGRAN);
@@ -276,3 +308,681 @@
toString(radioRsp_v1_5->rspInfo.error).c_str());
ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_5->rspInfo.error, {RadioError::NONE}));
}
+
+/*
+ * Test IRadio.enableUiccApplications() for the response returned.
+ * For SIM ABSENT case.
+ */
+TEST_F(RadioHidlTest_v1_5, togglingUiccApplicationsSimAbsent) {
+ // This test case only test SIM ABSENT case.
+ if (cardStatus.base.base.cardState != CardState::ABSENT) return;
+
+ // Disable Uicc applications.
+ serial = GetRandomSerialNumber();
+ radio_v1_5->enableUiccApplications(serial, false);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
+ // As SIM is absent, RadioError::SIM_ABSENT should be thrown.
+ EXPECT_EQ(RadioError::SIM_ABSENT, radioRsp_v1_5->rspInfo.error);
+
+ // Query Uicc application enablement.
+ serial = GetRandomSerialNumber();
+ radio_v1_5->areUiccApplicationsEnabled(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
+ // As SIM is absent, RadioError::SIM_ABSENT should be thrown.
+ EXPECT_EQ(RadioError::SIM_ABSENT, radioRsp_v1_5->rspInfo.error);
+}
+
+/*
+ * Test IRadio.enableUiccApplications() for the response returned.
+ * For SIM PRESENT case.
+ */
+TEST_F(RadioHidlTest_v1_5, togglingUiccApplicationsSimPresent) {
+ // This test case only test SIM ABSENT case.
+ if (cardStatus.base.base.cardState != CardState::PRESENT) return;
+
+ // Disable Uicc applications.
+ serial = GetRandomSerialNumber();
+ radio_v1_5->enableUiccApplications(serial, false);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
+ // As SIM is present, there shouldn't be error.
+ EXPECT_EQ(RadioError::NONE, radioRsp_v1_5->rspInfo.error);
+
+ // Query Uicc application enablement.
+ serial = GetRandomSerialNumber();
+ radio_v1_5->areUiccApplicationsEnabled(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
+ // As SIM is present, there shouldn't be error.
+ EXPECT_EQ(RadioError::NONE, radioRsp_v1_5->rspInfo.error);
+ ASSERT_FALSE(radioRsp_v1_5->areUiccApplicationsEnabled);
+
+ // Enable Uicc applications.
+ serial = GetRandomSerialNumber();
+ radio_v1_5->enableUiccApplications(serial, true);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
+ // As SIM is present, there shouldn't be error.
+ EXPECT_EQ(RadioError::NONE, radioRsp_v1_5->rspInfo.error);
+
+ // Query Uicc application enablement.
+ serial = GetRandomSerialNumber();
+ radio_v1_5->areUiccApplicationsEnabled(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
+ // As SIM is present, there shouldn't be error.
+ EXPECT_EQ(RadioError::NONE, radioRsp_v1_5->rspInfo.error);
+ ASSERT_TRUE(radioRsp_v1_5->areUiccApplicationsEnabled);
+}
+
+/*
+ * Test IRadio.areUiccApplicationsEnabled() for the response returned.
+ */
+TEST_F(RadioHidlTest_v1_5, areUiccApplicationsEnabled) {
+ // Disable Uicc applications.
+ serial = GetRandomSerialNumber();
+ radio_v1_5->areUiccApplicationsEnabled(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
+
+ // If SIM is absent, RadioError::SIM_ABSENT should be thrown. Otherwise there shouldn't be any
+ // error.
+ if (cardStatus.base.base.cardState == CardState::ABSENT) {
+ EXPECT_EQ(RadioError::SIM_ABSENT, radioRsp_v1_5->rspInfo.error);
+ } else if (cardStatus.base.base.cardState == CardState::PRESENT) {
+ EXPECT_EQ(RadioError::NONE, radioRsp_v1_5->rspInfo.error);
+ }
+}
+
+/*
+ * Test IRadio.setSystemSelectionChannels_1_5() for the response returned.
+ */
+TEST_F(RadioHidlTest_v1_5, setSystemSelectionChannels_1_5) {
+ serial = GetRandomSerialNumber();
+
+ ::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands rasBands;
+ rasBands.geranBands() = {GeranBands::BAND_450, GeranBands::BAND_480};
+
+ ::android::hardware::radio::V1_5::RadioAccessSpecifier specifier = {
+ .radioAccessNetwork = ::android::hardware::radio::V1_5::RadioAccessNetworks::GERAN,
+ .bands = rasBands,
+ .channels = {1, 2}};
+
+ Return<void> res = radio_v1_5->setSystemSelectionChannels_1_5(serial, true, {specifier});
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
+ ALOGI("setSystemSelectionChannels, rspInfo.error = %s\n",
+ toString(radioRsp_v1_5->rspInfo.error).c_str());
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_v1_5->rspInfo.error,
+ {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, RadioError::INTERNAL_ERR}));
+
+ if (radioRsp_v1_5->rspInfo.error == RadioError::NONE) {
+ serial = GetRandomSerialNumber();
+ Return<void> res = radio_v1_5->setSystemSelectionChannels_1_5(serial, false, {specifier});
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
+ ALOGI("setSystemSelectionChannels, rspInfo.error = %s\n",
+ toString(radioRsp_v1_5->rspInfo.error).c_str());
+ EXPECT_EQ(RadioError::NONE, radioRsp_v1_5->rspInfo.error);
+ }
+}
+
+/*
+ * Test IRadio.startNetworkScan_1_5() for the response returned.
+ */
+TEST_F(RadioHidlTest_v1_5, startNetworkScan) {
+ serial = GetRandomSerialNumber();
+
+ ::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands rasBands;
+ rasBands.geranBands() = {GeranBands::BAND_450, GeranBands::BAND_480};
+
+ ::android::hardware::radio::V1_5::RadioAccessSpecifier specifier = {
+ .radioAccessNetwork = ::android::hardware::radio::V1_5::RadioAccessNetworks::GERAN,
+ .bands = rasBands,
+ .channels = {1, 2}};
+
+ ::android::hardware::radio::V1_5::NetworkScanRequest request = {
+ .type = ScanType::ONE_SHOT,
+ .interval = 60,
+ .specifiers = {specifier},
+ .maxSearchTime = 60,
+ .incrementalResults = false,
+ .incrementalResultsPeriodicity = 1};
+
+ Return<void> res = radio_v1_5->startNetworkScan_1_5(serial, request);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
+ ALOGI("startNetworkScan, rspInfo.error = %s\n", toString(radioRsp_v1_5->rspInfo.error).c_str());
+
+ if (cardStatus.base.base.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_5->rspInfo.error, {RadioError::SIM_ABSENT}));
+ } else if (cardStatus.base.base.cardState == CardState::PRESENT) {
+ // OPERATION_NOT_ALLOWED should not be allowed; however, some vendors do
+ // not support the required manual GSM search functionality. This is
+ // tracked in b/112206766. Modems have "GSM" rat scan need to
+ // support scanning requests combined with some parameters.
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_5->rspInfo.error,
+ {RadioError::NONE, RadioError::OPERATION_NOT_ALLOWED}));
+ }
+}
+
+/*
+ * Test IRadio.startNetworkScan_1_5() with invalid specifier.
+ */
+TEST_F(RadioHidlTest_v1_5, startNetworkScan_InvalidArgument) {
+ serial = GetRandomSerialNumber();
+
+ ::android::hardware::radio::V1_5::NetworkScanRequest request = {.type = ScanType::ONE_SHOT,
+ .interval = 60};
+
+ Return<void> res = radio_v1_5->startNetworkScan_1_5(serial, request);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
+ ALOGI("startNetworkScan_InvalidArgument, rspInfo.error = %s\n",
+ toString(radioRsp_v1_5->rspInfo.error).c_str());
+
+ if (cardStatus.base.base.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_5->rspInfo.error,
+ {RadioError::SIM_ABSENT, RadioError::INVALID_ARGUMENTS}));
+ } else if (cardStatus.base.base.cardState == CardState::PRESENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_v1_5->rspInfo.error,
+ {RadioError::INVALID_ARGUMENTS, RadioError::REQUEST_NOT_SUPPORTED}));
+ }
+}
+
+/*
+ * Test IRadio.startNetworkScan_1_5() with invalid interval (lower boundary).
+ */
+TEST_F(RadioHidlTest_v1_5, startNetworkScan_InvalidInterval1) {
+ serial = GetRandomSerialNumber();
+
+ ::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands rasBands;
+ rasBands.geranBands() = {GeranBands::BAND_450, GeranBands::BAND_480};
+
+ ::android::hardware::radio::V1_5::RadioAccessSpecifier specifier = {
+ .radioAccessNetwork = ::android::hardware::radio::V1_5::RadioAccessNetworks::GERAN,
+ .bands = rasBands,
+ .channels = {1, 2}};
+
+ ::android::hardware::radio::V1_5::NetworkScanRequest request = {
+ .type = ScanType::ONE_SHOT,
+ .interval = 4,
+ .specifiers = {specifier},
+ .maxSearchTime = 60,
+ .incrementalResults = false,
+ .incrementalResultsPeriodicity = 1};
+
+ Return<void> res = radio_v1_5->startNetworkScan_1_5(serial, request);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
+ ALOGI("startNetworkScan_InvalidInterval1, rspInfo.error = %s\n",
+ toString(radioRsp_v1_5->rspInfo.error).c_str());
+ if (cardStatus.base.base.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_5->rspInfo.error,
+ {RadioError::SIM_ABSENT, RadioError::INVALID_ARGUMENTS}));
+ } else if (cardStatus.base.base.cardState == CardState::PRESENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_v1_5->rspInfo.error,
+ {RadioError::INVALID_ARGUMENTS, RadioError::REQUEST_NOT_SUPPORTED}));
+ }
+}
+
+/*
+ * Test IRadio.startNetworkScan_1_5() with invalid interval (upper boundary).
+ */
+TEST_F(RadioHidlTest_v1_5, startNetworkScan_InvalidInterval2) {
+ serial = GetRandomSerialNumber();
+
+ ::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands rasBands;
+ rasBands.geranBands() = {GeranBands::BAND_450, GeranBands::BAND_480};
+
+ ::android::hardware::radio::V1_5::RadioAccessSpecifier specifier = {
+ .radioAccessNetwork = ::android::hardware::radio::V1_5::RadioAccessNetworks::GERAN,
+ .bands = rasBands,
+ .channels = {1, 2}};
+
+ ::android::hardware::radio::V1_5::NetworkScanRequest request = {
+ .type = ScanType::ONE_SHOT,
+ .interval = 301,
+ .specifiers = {specifier},
+ .maxSearchTime = 60,
+ .incrementalResults = false,
+ .incrementalResultsPeriodicity = 1};
+
+ Return<void> res = radio_v1_5->startNetworkScan_1_5(serial, request);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
+ ALOGI("startNetworkScan_InvalidInterval2, rspInfo.error = %s\n",
+ toString(radioRsp_v1_5->rspInfo.error).c_str());
+ if (cardStatus.base.base.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_5->rspInfo.error,
+ {RadioError::SIM_ABSENT, RadioError::INVALID_ARGUMENTS}));
+ } else if (cardStatus.base.base.cardState == CardState::PRESENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_v1_5->rspInfo.error,
+ {RadioError::INVALID_ARGUMENTS, RadioError::REQUEST_NOT_SUPPORTED}));
+ }
+}
+
+/*
+ * Test IRadio.startNetworkScan_1_5() with invalid max search time (lower boundary).
+ */
+TEST_F(RadioHidlTest_v1_5, startNetworkScan_InvalidMaxSearchTime1) {
+ serial = GetRandomSerialNumber();
+
+ ::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands rasBands;
+ rasBands.geranBands() = {GeranBands::BAND_450, GeranBands::BAND_480};
+
+ ::android::hardware::radio::V1_5::RadioAccessSpecifier specifier = {
+ .radioAccessNetwork = ::android::hardware::radio::V1_5::RadioAccessNetworks::GERAN,
+ .bands = rasBands,
+ .channels = {1, 2}};
+
+ ::android::hardware::radio::V1_5::NetworkScanRequest request = {
+ .type = ScanType::ONE_SHOT,
+ .interval = 60,
+ .specifiers = {specifier},
+ .maxSearchTime = 59,
+ .incrementalResults = false,
+ .incrementalResultsPeriodicity = 1};
+
+ Return<void> res = radio_v1_5->startNetworkScan_1_5(serial, request);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
+ ALOGI("startNetworkScan_InvalidMaxSearchTime1, rspInfo.error = %s\n",
+ toString(radioRsp_v1_5->rspInfo.error).c_str());
+ if (cardStatus.base.base.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_5->rspInfo.error,
+ {RadioError::SIM_ABSENT, RadioError::INVALID_ARGUMENTS}));
+ } else if (cardStatus.base.base.cardState == CardState::PRESENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_v1_5->rspInfo.error,
+ {RadioError::INVALID_ARGUMENTS, RadioError::REQUEST_NOT_SUPPORTED}));
+ }
+}
+
+/*
+ * Test IRadio.startNetworkScan_1_5() with invalid max search time (upper boundary).
+ */
+TEST_F(RadioHidlTest_v1_5, startNetworkScan_InvalidMaxSearchTime2) {
+ serial = GetRandomSerialNumber();
+
+ ::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands rasBands;
+ rasBands.geranBands() = {GeranBands::BAND_450, GeranBands::BAND_480};
+
+ ::android::hardware::radio::V1_5::RadioAccessSpecifier specifier = {
+ .radioAccessNetwork = ::android::hardware::radio::V1_5::RadioAccessNetworks::GERAN,
+ .bands = rasBands,
+ .channels = {1, 2}};
+
+ ::android::hardware::radio::V1_5::NetworkScanRequest request = {
+ .type = ScanType::ONE_SHOT,
+ .interval = 60,
+ .specifiers = {specifier},
+ .maxSearchTime = 3601,
+ .incrementalResults = false,
+ .incrementalResultsPeriodicity = 1};
+
+ Return<void> res = radio_v1_5->startNetworkScan_1_5(serial, request);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
+ ALOGI("startNetworkScan_InvalidMaxSearchTime2, rspInfo.error = %s\n",
+ toString(radioRsp_v1_5->rspInfo.error).c_str());
+ if (cardStatus.base.base.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_5->rspInfo.error,
+ {RadioError::SIM_ABSENT, RadioError::INVALID_ARGUMENTS}));
+ } else if (cardStatus.base.base.cardState == CardState::PRESENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_v1_5->rspInfo.error,
+ {RadioError::INVALID_ARGUMENTS, RadioError::REQUEST_NOT_SUPPORTED}));
+ }
+}
+
+/*
+ * Test IRadio.startNetworkScan_1_5() with invalid periodicity (lower boundary).
+ */
+TEST_F(RadioHidlTest_v1_5, startNetworkScan_InvalidPeriodicity1) {
+ serial = GetRandomSerialNumber();
+
+ ::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands rasBands;
+ rasBands.geranBands() = {GeranBands::BAND_450, GeranBands::BAND_480};
+
+ ::android::hardware::radio::V1_5::RadioAccessSpecifier specifier = {
+ .radioAccessNetwork = ::android::hardware::radio::V1_5::RadioAccessNetworks::GERAN,
+ .bands = rasBands,
+ .channels = {1, 2}};
+
+ ::android::hardware::radio::V1_5::NetworkScanRequest request = {
+ .type = ScanType::ONE_SHOT,
+ .interval = 60,
+ .specifiers = {specifier},
+ .maxSearchTime = 600,
+ .incrementalResults = true,
+ .incrementalResultsPeriodicity = 0};
+
+ Return<void> res = radio_v1_5->startNetworkScan_1_5(serial, request);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
+ ALOGI("startNetworkScan_InvalidPeriodicity1, rspInfo.error = %s\n",
+ toString(radioRsp_v1_5->rspInfo.error).c_str());
+ if (cardStatus.base.base.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_5->rspInfo.error,
+ {RadioError::SIM_ABSENT, RadioError::INVALID_ARGUMENTS}));
+ } else if (cardStatus.base.base.cardState == CardState::PRESENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_v1_5->rspInfo.error,
+ {RadioError::INVALID_ARGUMENTS, RadioError::REQUEST_NOT_SUPPORTED}));
+ }
+}
+
+/*
+ * Test IRadio.startNetworkScan_1_5() with invalid periodicity (upper boundary).
+ */
+TEST_F(RadioHidlTest_v1_5, startNetworkScan_InvalidPeriodicity2) {
+ serial = GetRandomSerialNumber();
+
+ ::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands rasBands;
+ rasBands.geranBands() = {GeranBands::BAND_450, GeranBands::BAND_480};
+
+ ::android::hardware::radio::V1_5::RadioAccessSpecifier specifier = {
+ .radioAccessNetwork = ::android::hardware::radio::V1_5::RadioAccessNetworks::GERAN,
+ .bands = rasBands,
+ .channels = {1, 2}};
+
+ ::android::hardware::radio::V1_5::NetworkScanRequest request = {
+ .type = ScanType::ONE_SHOT,
+ .interval = 60,
+ .specifiers = {specifier},
+ .maxSearchTime = 600,
+ .incrementalResults = true,
+ .incrementalResultsPeriodicity = 11};
+
+ Return<void> res = radio_v1_5->startNetworkScan_1_5(serial, request);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
+ ALOGI("startNetworkScan_InvalidPeriodicity2, rspInfo.error = %s\n",
+ toString(radioRsp_v1_5->rspInfo.error).c_str());
+ if (cardStatus.base.base.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_5->rspInfo.error,
+ {RadioError::SIM_ABSENT, RadioError::INVALID_ARGUMENTS}));
+ } else if (cardStatus.base.base.cardState == CardState::PRESENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_v1_5->rspInfo.error,
+ {RadioError::INVALID_ARGUMENTS, RadioError::REQUEST_NOT_SUPPORTED}));
+ }
+}
+
+/*
+ * Test IRadio.startNetworkScan_1_5() with valid periodicity
+ */
+TEST_F(RadioHidlTest_v1_5, startNetworkScan_GoodRequest1) {
+ serial = GetRandomSerialNumber();
+
+ ::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands rasBands;
+ rasBands.geranBands() = {GeranBands::BAND_450, GeranBands::BAND_480};
+
+ ::android::hardware::radio::V1_5::RadioAccessSpecifier specifier = {
+ .radioAccessNetwork = ::android::hardware::radio::V1_5::RadioAccessNetworks::GERAN,
+ .bands = rasBands,
+ .channels = {1, 2}};
+
+ ::android::hardware::radio::V1_5::NetworkScanRequest request = {
+ .type = ScanType::ONE_SHOT,
+ .interval = 60,
+ .specifiers = {specifier},
+ .maxSearchTime = 360,
+ .incrementalResults = false,
+ .incrementalResultsPeriodicity = 10};
+
+ Return<void> res = radio_v1_5->startNetworkScan_1_5(serial, request);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
+ ALOGI("startNetworkScan_GoodRequest1, rspInfo.error = %s\n",
+ toString(radioRsp_v1_5->rspInfo.error).c_str());
+ if (cardStatus.base.base.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_5->rspInfo.error,
+ {RadioError::NONE, RadioError::SIM_ABSENT}));
+ } else if (cardStatus.base.base.cardState == CardState::PRESENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_5->rspInfo.error,
+ {RadioError::NONE, RadioError::INVALID_ARGUMENTS,
+ RadioError::REQUEST_NOT_SUPPORTED}));
+ }
+}
+
+/*
+ * Test IRadio.startNetworkScan_1_5() with valid periodicity and plmns
+ */
+TEST_F(RadioHidlTest_v1_5, startNetworkScan_GoodRequest2) {
+ serial = GetRandomSerialNumber();
+
+ ::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands rasBands;
+ rasBands.geranBands() = {GeranBands::BAND_450, GeranBands::BAND_480};
+
+ ::android::hardware::radio::V1_5::RadioAccessSpecifier specifier = {
+ .radioAccessNetwork = ::android::hardware::radio::V1_5::RadioAccessNetworks::GERAN,
+ .bands = rasBands,
+ .channels = {1, 2}};
+
+ ::android::hardware::radio::V1_5::NetworkScanRequest request = {
+ .type = ScanType::ONE_SHOT,
+ .interval = 60,
+ .specifiers = {specifier},
+ .maxSearchTime = 360,
+ .incrementalResults = false,
+ .incrementalResultsPeriodicity = 10,
+ .mccMncs = {"310410"}};
+
+ Return<void> res = radio_v1_5->startNetworkScan_1_5(serial, request);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
+ ALOGI("startNetworkScan_GoodRequest2, rspInfo.error = %s\n",
+ toString(radioRsp_v1_5->rspInfo.error).c_str());
+ if (cardStatus.base.base.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_5->rspInfo.error,
+ {RadioError::NONE, RadioError::SIM_ABSENT}));
+ } else if (cardStatus.base.base.cardState == CardState::PRESENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_5->rspInfo.error,
+ {RadioError::NONE, RadioError::INVALID_ARGUMENTS,
+ RadioError::REQUEST_NOT_SUPPORTED}));
+ }
+}
+
+/*
+ * Test IRadio.setupDataCall_1_5() for the response returned.
+ */
+TEST_F(RadioHidlTest_v1_5, setupDataCall_1_5) {
+ serial = GetRandomSerialNumber();
+
+ ::android::hardware::radio::V1_5::AccessNetwork accessNetwork =
+ ::android::hardware::radio::V1_5::AccessNetwork::EUTRAN;
+
+ android::hardware::radio::V1_5::DataProfileInfo dataProfileInfo;
+ memset(&dataProfileInfo, 0, sizeof(dataProfileInfo));
+ dataProfileInfo.base.profileId = DataProfileId::DEFAULT;
+ dataProfileInfo.base.apn = hidl_string("internet");
+ dataProfileInfo.base.protocol = PdpProtocolType::IP;
+ dataProfileInfo.base.roamingProtocol = PdpProtocolType::IP;
+ dataProfileInfo.base.authType = ApnAuthType::NO_PAP_NO_CHAP;
+ dataProfileInfo.base.user = hidl_string("username");
+ dataProfileInfo.base.password = hidl_string("password");
+ dataProfileInfo.base.type = DataProfileInfoType::THREE_GPP;
+ dataProfileInfo.base.maxConnsTime = 300;
+ dataProfileInfo.base.maxConns = 20;
+ dataProfileInfo.base.waitTime = 0;
+ dataProfileInfo.base.enabled = true;
+ dataProfileInfo.supportedApnTypesBitmap = 320;
+ dataProfileInfo.base.bearerBitmap = 161543;
+ dataProfileInfo.base.mtu = 0;
+ dataProfileInfo.base.preferred = true;
+ dataProfileInfo.base.persistent = false;
+
+ bool roamingAllowed = false;
+
+ ::android::hardware::radio::V1_2::DataRequestReason reason =
+ ::android::hardware::radio::V1_2::DataRequestReason::NORMAL;
+ std::vector<hidl_string> addresses = {""};
+ std::vector<hidl_string> dnses = {""};
+
+ Return<void> res = radio_v1_5->setupDataCall_1_5(serial, accessNetwork, dataProfileInfo,
+ roamingAllowed, reason, addresses, dnses);
+ ASSERT_OK(res);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
+
+ if (cardStatus.base.base.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_5->rspInfo.error,
+ {RadioError::SIM_ABSENT, RadioError::RADIO_NOT_AVAILABLE,
+ RadioError::OP_NOT_ALLOWED_BEFORE_REG_TO_NW}));
+ } else if (cardStatus.base.base.cardState == CardState::PRESENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_5->rspInfo.error,
+ {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE,
+ RadioError::OP_NOT_ALLOWED_BEFORE_REG_TO_NW}));
+ }
+}
+
+TEST_F(RadioHidlTest_v1_5, setInitialAttachApn_1_5) {
+ serial = GetRandomSerialNumber();
+
+ // Create a dataProfileInfo
+ android::hardware::radio::V1_5::DataProfileInfo dataProfileInfo;
+ memset(&dataProfileInfo, 0, sizeof(dataProfileInfo));
+ dataProfileInfo.base.profileId = DataProfileId::DEFAULT;
+ dataProfileInfo.base.apn = hidl_string("internet");
+ dataProfileInfo.base.protocol = PdpProtocolType::IPV4V6;
+ dataProfileInfo.base.roamingProtocol = PdpProtocolType::IPV4V6;
+ dataProfileInfo.base.authType = ApnAuthType::NO_PAP_NO_CHAP;
+ dataProfileInfo.base.user = hidl_string("username");
+ dataProfileInfo.base.password = hidl_string("password");
+ dataProfileInfo.base.type = DataProfileInfoType::THREE_GPP;
+ dataProfileInfo.base.maxConnsTime = 300;
+ dataProfileInfo.base.maxConns = 20;
+ dataProfileInfo.base.waitTime = 0;
+ dataProfileInfo.base.enabled = true;
+ dataProfileInfo.supportedApnTypesBitmap = 320;
+ dataProfileInfo.base.bearerBitmap = 161543;
+ dataProfileInfo.base.mtu = 0;
+ dataProfileInfo.base.preferred = true;
+ dataProfileInfo.base.persistent = false;
+
+ radio_v1_5->setInitialAttachApn_1_5(serial, dataProfileInfo);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
+
+ if (cardStatus.base.base.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_5->rspInfo.error,
+ {RadioError::SIM_ABSENT, RadioError::RADIO_NOT_AVAILABLE}));
+ } else if (cardStatus.base.base.cardState == CardState::PRESENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_5->rspInfo.error,
+ {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE}));
+ }
+}
+
+TEST_F(RadioHidlTest_v1_5, setDataProfile_1_5) {
+ serial = GetRandomSerialNumber();
+
+ // Create a dataProfileInfo
+ android::hardware::radio::V1_5::DataProfileInfo dataProfileInfo;
+ memset(&dataProfileInfo, 0, sizeof(dataProfileInfo));
+ dataProfileInfo.base.profileId = DataProfileId::DEFAULT;
+ dataProfileInfo.base.apn = hidl_string("internet");
+ dataProfileInfo.base.protocol = PdpProtocolType::IPV4V6;
+ dataProfileInfo.base.roamingProtocol = PdpProtocolType::IPV4V6;
+ dataProfileInfo.base.authType = ApnAuthType::NO_PAP_NO_CHAP;
+ dataProfileInfo.base.user = hidl_string("username");
+ dataProfileInfo.base.password = hidl_string("password");
+ dataProfileInfo.base.type = DataProfileInfoType::THREE_GPP;
+ dataProfileInfo.base.maxConnsTime = 300;
+ dataProfileInfo.base.maxConns = 20;
+ dataProfileInfo.base.waitTime = 0;
+ dataProfileInfo.base.enabled = true;
+ dataProfileInfo.supportedApnTypesBitmap = 320;
+ dataProfileInfo.base.bearerBitmap = 161543;
+ dataProfileInfo.base.mtu = 0;
+ dataProfileInfo.base.preferred = true;
+ dataProfileInfo.base.persistent = true;
+
+ // Create a dataProfileInfoList
+ android::hardware::hidl_vec<android::hardware::radio::V1_5::DataProfileInfo>
+ dataProfileInfoList = {dataProfileInfo};
+
+ radio_v1_5->setDataProfile_1_5(serial, dataProfileInfoList);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
+
+ if (cardStatus.base.base.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_5->rspInfo.error,
+ {RadioError::SIM_ABSENT, RadioError::RADIO_NOT_AVAILABLE}));
+ } else if (cardStatus.base.base.cardState == CardState::PRESENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_5->rspInfo.error,
+ {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE}));
+ }
+}
+
+TEST_F(RadioHidlTest_v1_5, setRadioPower_1_5_emergencyCall_cancalled) {
+ // Set radio power to off.
+ serial = GetRandomSerialNumber();
+ radio_v1_5->setRadioPower_1_5(serial, false, false, false);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
+ EXPECT_EQ(RadioError::NONE, radioRsp_v1_5->rspInfo.error);
+
+ // Set radio power to on with forEmergencyCall being true. This should put modem to only scan
+ // emergency call bands.
+ serial = GetRandomSerialNumber();
+ radio_v1_5->setRadioPower_1_5(serial, true, true, true);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
+ EXPECT_EQ(RadioError::NONE, radioRsp_v1_5->rspInfo.error);
+
+ // Set radio power to on with forEmergencyCall being false. This should put modem in regular
+ // operation modem.
+ serial = GetRandomSerialNumber();
+ radio_v1_5->setRadioPower_1_5(serial, true, false, false);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
+ EXPECT_EQ(RadioError::NONE, radioRsp_v1_5->rspInfo.error);
+}
\ No newline at end of file
diff --git a/radio/1.5/vts/functional/radio_hidl_hal_utils_v1_5.h b/radio/1.5/vts/functional/radio_hidl_hal_utils_v1_5.h
index 683fdfc..c2ee94e 100644
--- a/radio/1.5/vts/functional/radio_hidl_hal_utils_v1_5.h
+++ b/radio/1.5/vts/functional/radio_hidl_hal_utils_v1_5.h
@@ -53,7 +53,7 @@
class RadioHidlTest_v1_5;
extern ::android::hardware::radio::V1_4::CardStatus cardStatus;
-/* Callback class for radio respons v1_5 */
+/* Callback class for radio response v1_5 */
class RadioResponse_v1_5 : public ::android::hardware::radio::V1_5::IRadioResponse {
protected:
RadioHidlTest_v1_5& parent_v1_5;
@@ -80,6 +80,12 @@
::android::hardware::radio::V1_4::CarrierRestrictionsWithPriority carrierRestrictionsResp;
::android::hardware::radio::V1_4::SimLockMultiSimPolicy multiSimPolicyResp;
+ // Whether toggling uicc applications operation is supported.
+ bool canToggleUiccApplicationsEnablement;
+
+ // Whether Uicc applications are enabled or not.
+ bool areUiccApplicationsEnabled;
+
RadioResponse_v1_5(RadioHidlTest_v1_5& parent_v1_5);
virtual ~RadioResponse_v1_5() = default;
@@ -524,6 +530,27 @@
/* 1.5 Api */
Return<void> setSignalStrengthReportingCriteriaResponse_1_5(const RadioResponseInfo& info);
+
+ Return<void> enableUiccApplicationsResponse(const RadioResponseInfo& info);
+
+ Return<void> areUiccApplicationsEnabledResponse(const RadioResponseInfo& info, bool enabled);
+
+ Return<void> canToggleUiccApplicationsEnablementResponse(const RadioResponseInfo& info,
+ bool canToggle);
+
+ Return<void> setSystemSelectionChannelsResponse_1_5(const RadioResponseInfo& info);
+
+ Return<void> startNetworkScanResponse_1_5(const RadioResponseInfo& info);
+
+ Return<void> setupDataCallResponse_1_5(
+ const RadioResponseInfo& info,
+ const android::hardware::radio::V1_4::SetupDataCallResult& dcResponse);
+
+ Return<void> setInitialAttachApnResponse_1_5(const RadioResponseInfo& info);
+
+ Return<void> setDataProfileResponse_1_5(const RadioResponseInfo& info);
+
+ Return<void> setRadioPowerResponse_1_5(const RadioResponseInfo& info);
};
/* Callback class for radio indication */
@@ -535,6 +562,9 @@
RadioIndication_v1_5(RadioHidlTest_v1_5& parent_v1_5);
virtual ~RadioIndication_v1_5() = default;
+ /* 1.5 Api */
+ Return<void> uiccApplicationsEnablementChanged(RadioIndicationType type, bool enabled);
+
/* 1.4 Api */
Return<void> currentEmergencyNumberList(
RadioIndicationType type,
diff --git a/radio/1.5/vts/functional/radio_indication.cpp b/radio/1.5/vts/functional/radio_indication.cpp
index b63b745..acffbbe 100644
--- a/radio/1.5/vts/functional/radio_indication.cpp
+++ b/radio/1.5/vts/functional/radio_indication.cpp
@@ -328,3 +328,8 @@
const ::android::hardware::hidl_string& /*reason*/) {
return Void();
}
+
+Return<void> RadioIndication_v1_5::uiccApplicationsEnablementChanged(RadioIndicationType /*type*/,
+ bool /*enabled*/) {
+ return Void();
+}
diff --git a/radio/1.5/vts/functional/radio_response.cpp b/radio/1.5/vts/functional/radio_response.cpp
index 29a9250..8932a64 100644
--- a/radio/1.5/vts/functional/radio_response.cpp
+++ b/radio/1.5/vts/functional/radio_response.cpp
@@ -892,4 +892,65 @@
rspInfo = info;
parent_v1_5.notify(info.serial);
return Void();
+}
+
+Return<void> RadioResponse_v1_5::enableUiccApplicationsResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_v1_5.notify(info.serial);
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::areUiccApplicationsEnabledResponse(const RadioResponseInfo& info,
+ bool enabled) {
+ rspInfo = info;
+ areUiccApplicationsEnabled = enabled;
+ parent_v1_5.notify(info.serial);
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::canToggleUiccApplicationsEnablementResponse(
+ const RadioResponseInfo& info, bool canToggle) {
+ rspInfo = info;
+ canToggleUiccApplicationsEnablement = canToggle;
+ parent_v1_5.notify(info.serial);
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::setSystemSelectionChannelsResponse_1_5(
+ const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_v1_5.notify(info.serial);
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::startNetworkScanResponse_1_5(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_v1_5.notify(info.serial);
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::setupDataCallResponse_1_5(
+ const RadioResponseInfo& info,
+ const android::hardware::radio::V1_4::SetupDataCallResult& /* dcResponse */) {
+ rspInfo = info;
+ parent_v1_5.notify(info.serial);
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::setInitialAttachApnResponse_1_5(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_v1_5.notify(info.serial);
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::setDataProfileResponse_1_5(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_v1_5.notify(info.serial);
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::setRadioPowerResponse_1_5(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_v1_5.notify(info.serial);
+ return Void();
}
\ No newline at end of file
diff --git a/radio/config/1.3/Android.bp b/radio/config/1.3/Android.bp
new file mode 100644
index 0000000..88de666
--- /dev/null
+++ b/radio/config/1.3/Android.bp
@@ -0,0 +1,23 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+hidl_interface {
+ name: "android.hardware.radio.config@1.3",
+ root: "android.hardware",
+ vndk: {
+ enabled: true,
+ },
+ srcs: [
+ "types.hal",
+ "IRadioConfig.hal",
+ "IRadioConfigIndication.hal",
+ "IRadioConfigResponse.hal",
+ ],
+ interfaces: [
+ "android.hardware.radio.config@1.0",
+ "android.hardware.radio.config@1.1",
+ "android.hardware.radio.config@1.2",
+ "android.hardware.radio@1.0",
+ "android.hidl.base@1.0",
+ ],
+ gen_java: true,
+}
diff --git a/radio/config/1.3/IRadioConfig.hal b/radio/config/1.3/IRadioConfig.hal
new file mode 100644
index 0000000..a0ce6e0
--- /dev/null
+++ b/radio/config/1.3/IRadioConfig.hal
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2019 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.radio.config@1.3;
+
+import @1.1::IRadioConfig;
+
+/**
+ * This interface is used by telephony and telecom to talk to cellular radio for the purpose of
+ * radio configuration, and it is not associated with any specific modem or slot.
+ * All the functions have minimum one parameter:
+ * serial: which corresponds to serial no. of request. Serial numbers must only be memorized for the
+ * duration of a method call. If clients provide colliding serials (including passing the same
+ * serial to different methods), multiple responses (one for each method call) must still be served.
+ */
+interface IRadioConfig extends @1.1::IRadioConfig {
+
+};
diff --git a/radio/config/1.3/IRadioConfigIndication.hal b/radio/config/1.3/IRadioConfigIndication.hal
new file mode 100644
index 0000000..9ef496c
--- /dev/null
+++ b/radio/config/1.3/IRadioConfigIndication.hal
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2019 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.radio.config@1.3;
+
+import @1.2::IRadioConfigIndication;
+
+/**
+ * Interface declaring unsolicited radio config indications.
+ */
+interface IRadioConfigIndication extends @1.2::IRadioConfigIndication {
+
+};
diff --git a/radio/config/1.3/IRadioConfigResponse.hal b/radio/config/1.3/IRadioConfigResponse.hal
new file mode 100644
index 0000000..9c4c971
--- /dev/null
+++ b/radio/config/1.3/IRadioConfigResponse.hal
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2019 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.radio.config@1.3;
+
+import @1.2::IRadioConfigResponse;
+
+/**
+ * Interface declaring response functions to solicited radio config requests.
+ */
+interface IRadioConfigResponse extends @1.2::IRadioConfigResponse {
+
+};
diff --git a/radio/config/1.3/default/Android.bp b/radio/config/1.3/default/Android.bp
new file mode 100644
index 0000000..163c5c5
--- /dev/null
+++ b/radio/config/1.3/default/Android.bp
@@ -0,0 +1,28 @@
+cc_binary {
+ name: "android.hardware.radio.config@1.3-service",
+ init_rc: ["android.hardware.radio.config@1.3-service.rc"],
+ relative_install_path: "hw",
+ vintf_fragments: ["radio-config-default.xml"],
+ vendor: true,
+ srcs: [
+ "RadioConfig.cpp",
+ "RadioConfigIndication.cpp",
+ "RadioConfigResponse.cpp",
+ "service.cpp",
+ ],
+ shared_libs: [
+ "libhidlbase",
+ "liblog",
+ "libutils",
+ "android.hardware.radio.config@1.0",
+ "android.hardware.radio.config@1.1",
+ "android.hardware.radio.config@1.2",
+ "android.hardware.radio.config@1.3",
+ "android.hardware.radio@1.0",
+ "android.hardware.radio@1.1",
+ "android.hardware.radio@1.2",
+ "android.hardware.radio@1.3",
+ "android.hardware.radio@1.4",
+ "android.hardware.radio@1.5",
+ ],
+}
diff --git a/radio/config/1.3/default/RadioConfig.cpp b/radio/config/1.3/default/RadioConfig.cpp
new file mode 100644
index 0000000..c28119c
--- /dev/null
+++ b/radio/config/1.3/default/RadioConfig.cpp
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.1 (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.1
+ *
+ * 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.
+ */
+
+#include "RadioConfig.h"
+
+namespace android {
+namespace hardware {
+namespace radio {
+namespace config {
+namespace V1_3 {
+namespace implementation {
+
+using namespace ::android::hardware::radio::V1_0;
+using namespace ::android::hardware::radio::config;
+
+// Methods from ::android::hardware::radio::config::V1_0::IRadioConfig follow.
+Return<void> RadioConfig::setResponseFunctions(
+ const sp<V1_0::IRadioConfigResponse>& radioConfigResponse,
+ const sp<V1_0::IRadioConfigIndication>& radioConfigIndication) {
+ mRadioConfigResponse = radioConfigResponse;
+ mRadioConfigIndication = radioConfigIndication;
+
+ mRadioConfigResponseV1_3 =
+ V1_3::IRadioConfigResponse::castFrom(mRadioConfigResponse).withDefault(nullptr);
+ mRadioConfigIndicationV1_3 =
+ V1_3::IRadioConfigIndication::castFrom(mRadioConfigIndication).withDefault(nullptr);
+ if (mRadioConfigResponseV1_3 == nullptr || mRadioConfigIndicationV1_3 == nullptr) {
+ mRadioConfigResponseV1_3 = nullptr;
+ mRadioConfigIndicationV1_3 = nullptr;
+ }
+
+ mRadioConfigResponseV1_2 =
+ V1_2::IRadioConfigResponse::castFrom(mRadioConfigResponse).withDefault(nullptr);
+ mRadioConfigIndicationV1_2 =
+ V1_2::IRadioConfigIndication::castFrom(mRadioConfigIndication).withDefault(nullptr);
+ if (mRadioConfigResponseV1_2 == nullptr || mRadioConfigIndicationV1_2 == nullptr) {
+ mRadioConfigResponseV1_2 = nullptr;
+ mRadioConfigIndicationV1_2 = nullptr;
+ }
+
+ mRadioConfigResponseV1_1 =
+ V1_1::IRadioConfigResponse::castFrom(mRadioConfigResponse).withDefault(nullptr);
+ mRadioConfigIndicationV1_1 =
+ V1_1::IRadioConfigIndication::castFrom(mRadioConfigIndication).withDefault(nullptr);
+ if (mRadioConfigResponseV1_1 == nullptr || mRadioConfigIndicationV1_1 == nullptr) {
+ mRadioConfigResponseV1_1 = nullptr;
+ mRadioConfigIndicationV1_1 = nullptr;
+ }
+
+ return Void();
+}
+
+Return<void> RadioConfig::getSimSlotsStatus(int32_t /* serial */) {
+ hidl_vec<V1_0::SimSlotStatus> slotStatus;
+ RadioResponseInfo info;
+ mRadioConfigResponse->getSimSlotsStatusResponse(info, slotStatus);
+ return Void();
+}
+
+Return<void> RadioConfig::setSimSlotsMapping(int32_t /* serial */,
+ const hidl_vec<uint32_t>& /* slotMap */) {
+ RadioResponseInfo info;
+ mRadioConfigResponse->setSimSlotsMappingResponse(info);
+ return Void();
+}
+
+// Methods from ::android::hardware::radio::config::V1_1::IRadioConfig follow.
+Return<void> RadioConfig::getPhoneCapability(int32_t /* serial */) {
+ V1_1::PhoneCapability phoneCapability;
+ RadioResponseInfo info;
+ mRadioConfigResponseV1_1->getPhoneCapabilityResponse(info, phoneCapability);
+ return Void();
+}
+
+Return<void> RadioConfig::setPreferredDataModem(int32_t /* serial */, uint8_t /* modemId */) {
+ RadioResponseInfo info;
+ mRadioConfigResponseV1_1->setPreferredDataModemResponse(info);
+ return Void();
+}
+
+Return<void> RadioConfig::setModemsConfig(int32_t /* serial */,
+ const V1_1::ModemsConfig& /* modemsConfig */) {
+ RadioResponseInfo info;
+ mRadioConfigResponseV1_1->setModemsConfigResponse(info);
+ return Void();
+}
+
+Return<void> RadioConfig::getModemsConfig(int32_t /* serial */) {
+ V1_1::ModemsConfig modemsConfig;
+ RadioResponseInfo info;
+ mRadioConfigResponseV1_1->getModemsConfigResponse(info, modemsConfig);
+ return Void();
+}
+
+} // namespace implementation
+} // namespace V1_3
+} // namespace config
+} // namespace radio
+} // namespace hardware
+} // namespace android
diff --git a/radio/config/1.3/default/RadioConfig.h b/radio/config/1.3/default/RadioConfig.h
new file mode 100644
index 0000000..00585e6
--- /dev/null
+++ b/radio/config/1.3/default/RadioConfig.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.1 (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.1
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_RADIO_CONFIG_V1_3_RADIOCONFIG_H
+#define ANDROID_HARDWARE_RADIO_CONFIG_V1_3_RADIOCONFIG_H
+
+#include <android/hardware/radio/config/1.3/IRadioConfig.h>
+#include <android/hardware/radio/config/1.3/IRadioConfigIndication.h>
+#include <android/hardware/radio/config/1.3/IRadioConfigResponse.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace radio {
+namespace config {
+namespace V1_3 {
+namespace implementation {
+
+using namespace ::android::hardware::radio::config;
+
+using ::android::sp;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+
+struct RadioConfig : public V1_3::IRadioConfig {
+ sp<V1_0::IRadioConfigResponse> mRadioConfigResponse;
+ sp<V1_0::IRadioConfigIndication> mRadioConfigIndication;
+ sp<V1_1::IRadioConfigResponse> mRadioConfigResponseV1_1;
+ sp<V1_1::IRadioConfigIndication> mRadioConfigIndicationV1_1;
+ sp<V1_2::IRadioConfigResponse> mRadioConfigResponseV1_2;
+ sp<V1_2::IRadioConfigIndication> mRadioConfigIndicationV1_2;
+ sp<V1_3::IRadioConfigResponse> mRadioConfigResponseV1_3;
+ sp<V1_3::IRadioConfigIndication> mRadioConfigIndicationV1_3;
+
+ // Methods from ::android::hardware::radio::config::V1_0::IRadioConfig follow.
+ Return<void> setResponseFunctions(
+ const sp<V1_0::IRadioConfigResponse>& radioConfigResponse,
+ const sp<V1_0::IRadioConfigIndication>& radioConfigIndication);
+ Return<void> getSimSlotsStatus(int32_t serial);
+ Return<void> setSimSlotsMapping(int32_t serial, const hidl_vec<uint32_t>& slotMap);
+
+ // Methods from ::android::hardware::radio::config::V1_1::IRadioConfig follow.
+ Return<void> getPhoneCapability(int32_t serial);
+ Return<void> setPreferredDataModem(int32_t serial, uint8_t modemId);
+ Return<void> setModemsConfig(int32_t serial, const V1_1::ModemsConfig& modemsConfig);
+ Return<void> getModemsConfig(int32_t serial);
+};
+
+} // namespace implementation
+} // namespace V1_3
+} // namespace config
+} // namespace radio
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_RADIO_CONFIG_V1_3_RADIOCONFIG_H
diff --git a/radio/config/1.3/default/RadioConfigIndication.cpp b/radio/config/1.3/default/RadioConfigIndication.cpp
new file mode 100644
index 0000000..eb77a48
--- /dev/null
+++ b/radio/config/1.3/default/RadioConfigIndication.cpp
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.1 (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.1
+ *
+ * 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.
+ */
+
+#include "RadioConfigIndication.h"
+
+namespace android {
+namespace hardware {
+namespace radio {
+namespace config {
+namespace V1_3 {
+namespace implementation {
+
+using namespace ::android::hardware::radio::V1_0;
+using namespace ::android::hardware::radio::config::V1_0;
+using namespace ::android::hardware::radio::config::V1_2;
+
+// Methods from ::android::hardware::radio::config::V1_0::IRadioConfigIndication follow.
+Return<void> RadioConfigIndication::simSlotsStatusChanged(
+ RadioIndicationType /* type */, const hidl_vec<V1_0::SimSlotStatus>& /* slotStatus */) {
+ // TODO implement
+ return Void();
+}
+
+// Methods from ::android::hardware::radio::config::V1_2::IRadioConfigIndication follow.
+Return<void> RadioConfigIndication::simSlotsStatusChanged_1_2(
+ RadioIndicationType /* type */, const hidl_vec<V1_2::SimSlotStatus>& /* slotStatus */) {
+ // TODO implement
+ return Void();
+}
+
+} // namespace implementation
+} // namespace V1_3
+} // namespace config
+} // namespace radio
+} // namespace hardware
+} // namespace android
diff --git a/radio/config/1.3/default/RadioConfigIndication.h b/radio/config/1.3/default/RadioConfigIndication.h
new file mode 100644
index 0000000..3697492
--- /dev/null
+++ b/radio/config/1.3/default/RadioConfigIndication.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.1 (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.1
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_RADIO_CONFIG_V1_3_RADIOCONFIGINDICATION_H
+#define ANDROID_HARDWARE_RADIO_CONFIG_V1_3_RADIOCONFIGINDICATION_H
+
+#include <android/hardware/radio/config/1.3/IRadioConfigIndication.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace radio {
+namespace config {
+namespace V1_3 {
+namespace implementation {
+
+using namespace ::android::hardware::radio::V1_0;
+using namespace ::android::hardware::radio::config;
+
+using ::android::sp;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+
+struct RadioConfigIndication : public IRadioConfigIndication {
+ // Methods from ::android::hardware::radio::config::V1_0::IRadioConfigIndication follow.
+ Return<void> simSlotsStatusChanged(RadioIndicationType type,
+ const hidl_vec<V1_0::SimSlotStatus>& slotStatus) override;
+
+ // Methods from ::android::hardware::radio::config::V1_2::IRadioConfigIndication follow.
+ Return<void> simSlotsStatusChanged_1_2(
+ RadioIndicationType type, const hidl_vec<V1_2::SimSlotStatus>& slotStatus) override;
+};
+
+} // namespace implementation
+} // namespace V1_3
+} // namespace config
+} // namespace radio
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_RADIO_CONFIG_V1_3_RADIOCONFIGINDICATION_H
diff --git a/radio/config/1.3/default/RadioConfigResponse.cpp b/radio/config/1.3/default/RadioConfigResponse.cpp
new file mode 100644
index 0000000..48e81da
--- /dev/null
+++ b/radio/config/1.3/default/RadioConfigResponse.cpp
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.1 (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.1
+ *
+ * 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.
+ */
+
+#include "RadioConfigResponse.h"
+
+namespace android {
+namespace hardware {
+namespace radio {
+namespace config {
+namespace V1_3 {
+namespace implementation {
+
+using namespace ::android::hardware::radio::V1_0;
+using namespace ::android::hardware::radio::config::V1_0;
+using namespace ::android::hardware::radio::config::V1_1;
+using namespace ::android::hardware::radio::config::V1_2;
+
+// Methods from ::android::hardware::radio::config::V1_0::IRadioConfigResponse follow.
+Return<void> RadioConfigResponse::getSimSlotsStatusResponse(
+ const RadioResponseInfo& /* info */,
+ const hidl_vec<V1_0::SimSlotStatus>& /* slotStatus */) {
+ // TODO implement
+ return Void();
+}
+
+Return<void> RadioConfigResponse::setSimSlotsMappingResponse(const RadioResponseInfo& /* info */) {
+ // TODO implement
+ return Void();
+}
+
+// Methods from ::android::hardware::radio::config::V1_1::IRadioConfigResponse follow.
+Return<void> RadioConfigResponse::getPhoneCapabilityResponse(
+ const RadioResponseInfo& /* info */, const V1_1::PhoneCapability& /* phoneCapability */) {
+ // TODO implement
+ return Void();
+}
+
+Return<void> RadioConfigResponse::setPreferredDataModemResponse(
+ const RadioResponseInfo& /* info */) {
+ // TODO implement
+ return Void();
+}
+
+Return<void> RadioConfigResponse::setModemsConfigResponse(const RadioResponseInfo& /* info */) {
+ // TODO implement
+ return Void();
+}
+
+Return<void> RadioConfigResponse::getModemsConfigResponse(
+ const RadioResponseInfo& /* info */, const V1_1::ModemsConfig& /* modemsConfig */) {
+ // TODO implement
+ return Void();
+}
+
+// Methods from ::android::hardware::radio::config::V1_2::IRadioConfigResponse follow.
+Return<void> RadioConfigResponse::getSimSlotsStatusResponse_1_2(
+ const RadioResponseInfo& /* info */,
+ const hidl_vec<V1_2::SimSlotStatus>& /* slotStatus */) {
+ // TODO implement
+ return Void();
+}
+
+} // namespace implementation
+} // namespace V1_3
+} // namespace config
+} // namespace radio
+} // namespace hardware
+} // namespace android
diff --git a/radio/config/1.3/default/RadioConfigResponse.h b/radio/config/1.3/default/RadioConfigResponse.h
new file mode 100644
index 0000000..0f0033f
--- /dev/null
+++ b/radio/config/1.3/default/RadioConfigResponse.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.1 (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.1
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_RADIO_CONFIG_V1_3_RADIOCONFIGRESPONSE_H
+#define ANDROID_HARDWARE_RADIO_CONFIG_V1_3_RADIOCONFIGRESPONSE_H
+
+#include <android/hardware/radio/config/1.3/IRadioConfigResponse.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace radio {
+namespace config {
+namespace V1_3 {
+namespace implementation {
+
+using ::android::sp;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+
+struct RadioConfigResponse : public IRadioConfigResponse {
+ // Methods from ::android::hardware::radio::config::V1_0::IRadioConfigResponse follow.
+ Return<void> getSimSlotsStatusResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
+ const hidl_vec<::android::hardware::radio::config::V1_0::SimSlotStatus>& slotStatus)
+ override;
+ Return<void> setSimSlotsMappingResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info) override;
+
+ // Methods from ::android::hardware::radio::config::V1_1::IRadioConfigResponse follow.
+ Return<void> getPhoneCapabilityResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
+ const ::android::hardware::radio::config::V1_1::PhoneCapability& phoneCapability)
+ override;
+ Return<void> setPreferredDataModemResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info) override;
+ Return<void> setModemsConfigResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info) override;
+ Return<void> getModemsConfigResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
+ const ::android::hardware::radio::config::V1_1::ModemsConfig& modemsConfig) override;
+
+ // Methods from ::android::hardware::radio::config::V1_2::IRadioConfigResponse follow.
+ Return<void> getSimSlotsStatusResponse_1_2(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
+ const hidl_vec<::android::hardware::radio::config::V1_2::SimSlotStatus>& slotStatus)
+ override;
+
+ // Methods from ::android::hidl::base::V1_0::IBase follow.
+};
+
+} // namespace implementation
+} // namespace V1_3
+} // namespace config
+} // namespace radio
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_RADIO_CONFIG_V1_3_RADIOCONFIGRESPONSE_H
diff --git a/radio/config/1.3/default/android.hardware.radio.config@1.3-service.rc b/radio/config/1.3/default/android.hardware.radio.config@1.3-service.rc
new file mode 100644
index 0000000..6df9b52
--- /dev/null
+++ b/radio/config/1.3/default/android.hardware.radio.config@1.3-service.rc
@@ -0,0 +1,7 @@
+service vendor.radio-config-hal-1-3 /vendor/bin/hw/android.hardware.radio.config@1.3-service
+ interface android.hardware.radio.config@1.0::IRadioConfig default
+ interface android.hardware.radio.config@1.1::IRadioConfig default
+ interface android.hardware.radio.config@1.3::IRadioConfig default
+ class hal
+ user system
+ group system
diff --git a/radio/config/1.3/default/radio-config-default.xml b/radio/config/1.3/default/radio-config-default.xml
new file mode 100644
index 0000000..72f363e
--- /dev/null
+++ b/radio/config/1.3/default/radio-config-default.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2019, 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.
+*/
+-->
+<manifest version="1.0" type="device">
+ <hal format="hidl">
+ <name>android.hardware.radio.config</name>
+ <transport>hwbinder</transport>
+ <version>1.3</version>
+ <interface>
+ <name>IRadioConfig</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+</manifest>
diff --git a/radio/config/1.3/default/service.cpp b/radio/config/1.3/default/service.cpp
new file mode 100644
index 0000000..b1e6736
--- /dev/null
+++ b/radio/config/1.3/default/service.cpp
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.1 (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.1
+ *
+ * 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 "android.hardware.radio.config@1.3-service"
+
+#include <android/hardware/radio/config/1.3/IRadioConfig.h>
+#include <hidl/HidlTransportSupport.h>
+
+#include "RadioConfig.h"
+
+using android::OK;
+using android::sp;
+using android::status_t;
+using android::hardware::configureRpcThreadpool;
+using android::hardware::joinRpcThreadpool;
+using android::hardware::radio::config::V1_3::IRadioConfig;
+using android::hardware::radio::config::V1_3::implementation::RadioConfig;
+
+int main() {
+ configureRpcThreadpool(1, true);
+ sp<IRadioConfig> radioConfig = new RadioConfig;
+ const status_t status = radioConfig->registerAsService();
+ ALOGW_IF(status != OK, "Could not register IRadioConfig 1.3");
+ ALOGD("Default service is ready.");
+
+ joinRpcThreadpool();
+ return 1;
+}
diff --git a/radio/config/1.3/types.hal b/radio/config/1.3/types.hal
new file mode 100644
index 0000000..866002a
--- /dev/null
+++ b/radio/config/1.3/types.hal
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2019 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.radio.config@1.3;
diff --git a/radio/config/1.3/vts/functional/Android.bp b/radio/config/1.3/vts/functional/Android.bp
new file mode 100644
index 0000000..6b28faf
--- /dev/null
+++ b/radio/config/1.3/vts/functional/Android.bp
@@ -0,0 +1,35 @@
+//
+// Copyright (C) 2019 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.
+//
+
+cc_test {
+ name: "VtsHalRadioConfigV1_3TargetTest",
+ defaults: ["VtsHalTargetTestDefaults"],
+ srcs: [
+ "radio_config_hidl_hal_api.cpp",
+ "radio_config_hidl_hal_test.cpp",
+ "radio_config_response.cpp",
+ "VtsHalRadioConfigV1_3TargetTest.cpp",
+ ],
+ static_libs: [
+ "RadioVtsTestUtilBase",
+ "android.hardware.radio.config@1.0",
+ "android.hardware.radio.config@1.1",
+ "android.hardware.radio.config@1.2",
+ "android.hardware.radio.config@1.3",
+ ],
+ header_libs: ["radio.util.header@1.0"],
+ test_suites: ["general-tests", "vts-core"],
+}
diff --git a/radio/config/1.3/vts/functional/VtsHalRadioConfigV1_3TargetTest.cpp b/radio/config/1.3/vts/functional/VtsHalRadioConfigV1_3TargetTest.cpp
new file mode 100644
index 0000000..3bacacf
--- /dev/null
+++ b/radio/config/1.3/vts/functional/VtsHalRadioConfigV1_3TargetTest.cpp
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#include <radio_config_hidl_hal_utils.h>
+
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, RadioConfigHidlTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(
+ ::android::hardware::radio::config::V1_3::IRadioConfig::descriptor)),
+ android::hardware::PrintInstanceNameToString);
diff --git a/radio/config/1.3/vts/functional/radio_config_hidl_hal_api.cpp b/radio/config/1.3/vts/functional/radio_config_hidl_hal_api.cpp
new file mode 100644
index 0000000..07e9ede
--- /dev/null
+++ b/radio/config/1.3/vts/functional/radio_config_hidl_hal_api.cpp
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#include <radio_config_hidl_hal_utils.h>
+
+#define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk())
diff --git a/radio/config/1.3/vts/functional/radio_config_hidl_hal_test.cpp b/radio/config/1.3/vts/functional/radio_config_hidl_hal_test.cpp
new file mode 100644
index 0000000..dbb4bf4
--- /dev/null
+++ b/radio/config/1.3/vts/functional/radio_config_hidl_hal_test.cpp
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#include <radio_config_hidl_hal_utils.h>
+
+void RadioConfigHidlTest::SetUp() {
+ radioConfig = ::android::hardware::radio::config::V1_3::IRadioConfig::getService(GetParam());
+ ASSERT_NE(nullptr, radioConfig.get());
+
+ radioConfigRsp = new (std::nothrow) RadioConfigResponse(*this);
+ ASSERT_NE(nullptr, radioConfigRsp.get());
+
+ count_ = 0;
+
+ radioConfig->setResponseFunctions(radioConfigRsp, nullptr);
+}
+
+/*
+ * Notify that the response message is received.
+ */
+void RadioConfigHidlTest::notify(int receivedSerial) {
+ std::unique_lock<std::mutex> lock(mtx_);
+ if (serial == receivedSerial) {
+ count_++;
+ cv_.notify_one();
+ }
+}
+
+/*
+ * Wait till the response message is notified or till TIMEOUT_PERIOD.
+ */
+std::cv_status RadioConfigHidlTest::wait() {
+ std::unique_lock<std::mutex> lock(mtx_);
+
+ std::cv_status status = std::cv_status::no_timeout;
+ auto now = std::chrono::system_clock::now();
+ while (count_ == 0) {
+ status = cv_.wait_until(lock, now + std::chrono::seconds(TIMEOUT_PERIOD));
+ if (status == std::cv_status::timeout) {
+ return status;
+ }
+ }
+ count_--;
+ return status;
+}
diff --git a/radio/config/1.3/vts/functional/radio_config_hidl_hal_utils.h b/radio/config/1.3/vts/functional/radio_config_hidl_hal_utils.h
new file mode 100644
index 0000000..9b78c04
--- /dev/null
+++ b/radio/config/1.3/vts/functional/radio_config_hidl_hal_utils.h
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#include <android-base/logging.h>
+
+#include <chrono>
+#include <condition_variable>
+#include <mutex>
+
+#include <android/hardware/radio/config/1.3/IRadioConfig.h>
+#include <android/hardware/radio/config/1.3/IRadioConfigIndication.h>
+#include <android/hardware/radio/config/1.3/IRadioConfigResponse.h>
+#include <android/hardware/radio/config/1.3/types.h>
+
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
+
+#include "vts_test_util.h"
+
+using namespace ::android::hardware::radio::config::V1_1;
+using namespace ::android::hardware::radio::config::V1_2;
+using namespace ::android::hardware::radio::config::V1_3;
+
+using ::android::sp;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+
+using ::android::hardware::radio::V1_0::RadioResponseInfo;
+using ::android::hardware::radio::V1_0::RadioResponseType;
+
+#define TIMEOUT_PERIOD 75
+
+class RadioConfigHidlTest;
+
+/* Callback class for radio config response */
+class RadioConfigResponse : public ::android::hardware::radio::config::V1_3::IRadioConfigResponse {
+ protected:
+ RadioConfigHidlTest& parent;
+
+ public:
+ RadioResponseInfo rspInfo;
+ PhoneCapability phoneCap;
+
+ RadioConfigResponse(RadioConfigHidlTest& parent);
+ virtual ~RadioConfigResponse() = default;
+
+ /* 1.0 Api */
+ Return<void> getSimSlotsStatusResponse(
+ const RadioResponseInfo& info,
+ const hidl_vec<::android::hardware::radio::config::V1_0::SimSlotStatus>& slotStatus);
+
+ Return<void> setSimSlotsMappingResponse(const RadioResponseInfo& info);
+
+ /* 1.1 Api */
+ Return<void> getPhoneCapabilityResponse(const RadioResponseInfo& info,
+ const PhoneCapability& phoneCapability);
+
+ Return<void> setPreferredDataModemResponse(const RadioResponseInfo& info);
+
+ Return<void> getModemsConfigResponse(const RadioResponseInfo& info,
+ const ModemsConfig& mConfig);
+
+ Return<void> setModemsConfigResponse(const RadioResponseInfo& info);
+
+ /* 1.2 Api */
+ Return<void> getSimSlotsStatusResponse_1_2(const RadioResponseInfo& info,
+ const hidl_vec<SimSlotStatus>& slotStatus);
+};
+
+/* Callback class for radio config indication */
+class RadioConfigIndication
+ : public ::android::hardware::radio::config::V1_3::IRadioConfigIndication {
+ protected:
+ RadioConfigHidlTest& parent;
+
+ public:
+ RadioConfigIndication(RadioConfigHidlTest& parent);
+ virtual ~RadioConfigIndication() = default;
+
+ /* 1.2 Api */
+ Return<void> simSlotsStatusChanged_1_2(
+ ::android::hardware::radio::V1_0::RadioIndicationType type,
+ const hidl_vec<SimSlotStatus>& slotStatus);
+};
+
+// The main test class for Radio config HIDL.
+class RadioConfigHidlTest : public ::testing::TestWithParam<std::string> {
+ protected:
+ std::mutex mtx_;
+ std::condition_variable cv_;
+ int count_;
+
+ public:
+ virtual void SetUp() override;
+
+ /* Used as a mechanism to inform the test about data/event callback */
+ void notify(int receivedSerial);
+
+ /* Test code calls this function to wait for response */
+ std::cv_status wait();
+
+ void updateSimCardStatus();
+
+ /* Serial number for radio request */
+ int serial;
+
+ /* radio config service handle */
+ sp<::android::hardware::radio::config::V1_3::IRadioConfig> radioConfig;
+
+ /* radio config response handle */
+ sp<RadioConfigResponse> radioConfigRsp;
+};
diff --git a/radio/config/1.3/vts/functional/radio_config_response.cpp b/radio/config/1.3/vts/functional/radio_config_response.cpp
new file mode 100644
index 0000000..1ca960e
--- /dev/null
+++ b/radio/config/1.3/vts/functional/radio_config_response.cpp
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#include <radio_config_hidl_hal_utils.h>
+
+using ::android::hardware::radio::V1_0::RadioResponseInfo;
+
+// SimSlotStatus slotStatus;
+
+RadioConfigResponse::RadioConfigResponse(RadioConfigHidlTest& parent) : parent(parent) {}
+
+/* 1.0 Apis */
+Return<void> RadioConfigResponse::getSimSlotsStatusResponse(
+ const RadioResponseInfo& /* info */,
+ const ::android::hardware::hidl_vec<
+ ::android::hardware::radio::config::V1_0::SimSlotStatus>& /* slotStatus */) {
+ return Void();
+}
+
+Return<void> RadioConfigResponse::setSimSlotsMappingResponse(const RadioResponseInfo& /* info */) {
+ return Void();
+}
+
+/* 1.1 Apis */
+Return<void> RadioConfigResponse::getPhoneCapabilityResponse(
+ const RadioResponseInfo& info, const PhoneCapability& phoneCapability) {
+ rspInfo = info;
+ phoneCap = phoneCapability;
+ parent.notify(info.serial);
+ return Void();
+}
+
+Return<void> RadioConfigResponse::setPreferredDataModemResponse(
+ const RadioResponseInfo& /* info */) {
+ return Void();
+}
+
+Return<void> RadioConfigResponse::getModemsConfigResponse(const RadioResponseInfo& /* info */,
+ const ModemsConfig& /* mConfig */) {
+ return Void();
+}
+
+Return<void> RadioConfigResponse::setModemsConfigResponse(const RadioResponseInfo& /* info */) {
+ return Void();
+}
+
+/* 1.2 Apis */
+Return<void> RadioConfigResponse::getSimSlotsStatusResponse_1_2(
+ const RadioResponseInfo& /* info */,
+ const ::android::hardware::hidl_vec<SimSlotStatus>& /* slotStatus */) {
+ return Void();
+}
\ No newline at end of file
diff --git a/rebootescrow/aidl/Android.bp b/rebootescrow/aidl/Android.bp
new file mode 100644
index 0000000..7bc8d6f
--- /dev/null
+++ b/rebootescrow/aidl/Android.bp
@@ -0,0 +1,18 @@
+aidl_interface {
+ name: "vintf-rebootescrow",
+ vendor_available: true,
+ srcs: [
+ "android/hardware/rebootescrow/IRebootEscrow.aidl",
+ ],
+ stability: "vintf",
+ backend: {
+ java: {
+ platform_apis: true,
+ },
+ ndk: {
+ vndk: {
+ enabled: true,
+ },
+ },
+ },
+}
diff --git a/rebootescrow/aidl/android/hardware/rebootescrow/IRebootEscrow.aidl b/rebootescrow/aidl/android/hardware/rebootescrow/IRebootEscrow.aidl
new file mode 100644
index 0000000..edc695d
--- /dev/null
+++ b/rebootescrow/aidl/android/hardware/rebootescrow/IRebootEscrow.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2019 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.rebootescrow;
+
+/**
+ * This HAL defines the interface to the device-specific implementation
+ * of retaining a secret to unlock the Synthetic Password stored during
+ * a reboot to perform an OTA update. The implementation of this interface
+ * should never store the key on any non-volatile medium. The key should be
+ * overwritten with zeroes when destroyKey() is called. All care should be given
+ * to provide the shortest lifetime for the storage of the key in volatile and
+ * erasable storage.
+ *
+ * This HAL is optional so does not require an implementation on device.
+ */
+@VintfStability
+interface IRebootEscrow {
+ /**
+ * Store the key for reboot.
+ */
+ void storeKey(in byte[] kek);
+
+ /**
+ * Retrieve the possible keys. If the implementation is probabalistic, it
+ * should return the keys in order from most-probable to least-probable.
+ * There is not a hard limit to the number of keys, but it is suggested to
+ * keep the number of key possibilities less than 32.
+ */
+ byte[] retrieveKey();
+}
diff --git a/rebootescrow/aidl/default/Android.bp b/rebootescrow/aidl/default/Android.bp
new file mode 100644
index 0000000..eb228ad
--- /dev/null
+++ b/rebootescrow/aidl/default/Android.bp
@@ -0,0 +1,47 @@
+//
+// Copyright (C) 2019 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.
+//
+
+cc_library_static {
+ name: "libhadamardutils",
+ vendor_available: true,
+ host_supported: true,
+ shared_libs: [
+ "libbase",
+ ],
+ srcs: [
+ "HadamardUtils.cpp",
+ ],
+ visibility: [
+ ":__subpackages__",
+ ],
+}
+
+cc_test {
+ name: "HadamardUtilsTest",
+ host_supported: true,
+ srcs: [
+ "HadamardUtilsTest.cpp",
+ ],
+ static_libs: [
+ "libhadamardutils",
+ "libgtest_prod",
+ ],
+ shared_libs: [
+ "liblog",
+ "libbase",
+ ],
+ test_suites: ["device-tests"],
+}
diff --git a/rebootescrow/aidl/default/HadamardUtils.cpp b/rebootescrow/aidl/default/HadamardUtils.cpp
new file mode 100644
index 0000000..5853d2d
--- /dev/null
+++ b/rebootescrow/aidl/default/HadamardUtils.cpp
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#include <HadamardUtils.h>
+
+#include <android-base/logging.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace rebootescrow {
+namespace hadamard {
+
+constexpr auto BYTE_LENGTH = 8u;
+
+std::vector<uint8_t> BitsetToBytes(const std::bitset<ENCODE_LENGTH>& encoded_bits) {
+ CHECK_EQ(0, (encoded_bits.size() % BYTE_LENGTH));
+ std::vector<uint8_t> result;
+ for (size_t i = 0; i < encoded_bits.size(); i += 8) {
+ uint8_t current = 0;
+ // Set each byte starting from the LSB.
+ for (size_t j = 0; j < BYTE_LENGTH; j++) {
+ CHECK_LE(i + j, encoded_bits.size());
+ if (encoded_bits[i + j]) {
+ current |= (1u << j);
+ }
+ }
+ result.push_back(current);
+ }
+ return result;
+}
+
+std::bitset<ENCODE_LENGTH> BytesToBitset(const std::vector<uint8_t>& encoded) {
+ CHECK_EQ(ENCODE_LENGTH, encoded.size() * BYTE_LENGTH);
+
+ std::bitset<ENCODE_LENGTH> result;
+ size_t offset = 0;
+ for (const auto& byte : encoded) {
+ // Set each byte starting from the LSB.
+ for (size_t j = 0; j < BYTE_LENGTH; j++) {
+ result[offset + j] = byte & (1u << j);
+ }
+ offset += BYTE_LENGTH;
+ }
+ return result;
+}
+
+// The encoding is equivalent to multiply the word with the generator matrix (and take the module
+// of 2). Here is an example of encoding a number with 3 bits. The encoded length is thus
+// 2^(3-1) = 4 bits.
+// |1 1 1 1| |0|
+// |0 1 1| * |0 0 1 1| = |1|
+// |0 1 0 1| |1|
+// |0|
+std::bitset<ENCODE_LENGTH> EncodeWord(uint16_t word) {
+ std::bitset<ENCODE_LENGTH> result;
+ for (uint64_t i = ENCODE_LENGTH; i < 2 * ENCODE_LENGTH; i++) {
+ uint32_t wi = word & i;
+ // Sum all the bits in the word and check its parity.
+ wi ^= wi >> 8u;
+ wi ^= wi >> 4u;
+ wi ^= wi >> 2u;
+ wi ^= wi >> 1u;
+ result[i - ENCODE_LENGTH] = wi & 1u;
+ }
+ return result;
+}
+
+std::vector<uint8_t> EncodeKey(const std::vector<uint8_t>& key) {
+ CHECK_EQ(KEY_SIZE_IN_BYTES, key.size());
+
+ std::vector<uint8_t> result;
+ for (size_t i = 0; i < key.size(); i += 2) {
+ uint16_t word = static_cast<uint16_t>(key[i + 1]) << BYTE_LENGTH | key[i];
+ auto encoded_bits = EncodeWord(word);
+ auto byte_array = BitsetToBytes(encoded_bits);
+ std::move(byte_array.begin(), byte_array.end(), std::back_inserter(result));
+ }
+ return result;
+}
+
+std::vector<uint8_t> DecodeKey(const std::vector<uint8_t>& encoded) {
+ CHECK_EQ(0, (encoded.size() * 8) % ENCODE_LENGTH);
+ std::vector<uint8_t> result;
+ for (size_t i = 0; i < encoded.size(); i += ENCODE_LENGTH / 8) {
+ auto current =
+ std::vector<uint8_t>{encoded.begin() + i, encoded.begin() + i + ENCODE_LENGTH / 8};
+ auto bits = BytesToBitset(current);
+ auto candidates = DecodeWord(bits);
+ CHECK(!candidates.empty());
+ // TODO(xunchang) Do we want to try other candidates?
+ uint16_t val = candidates.top().second;
+ result.push_back(val & 0xffu);
+ result.push_back(val >> BYTE_LENGTH);
+ }
+
+ return result;
+}
+
+std::priority_queue<std::pair<int32_t, uint16_t>> DecodeWord(
+ const std::bitset<ENCODE_LENGTH>& encoded) {
+ std::vector<int32_t> scores;
+ scores.reserve(ENCODE_LENGTH);
+ // Convert 0 -> -1 in the encoded bits. e.g [0, 1, 1, 0] -> [-1, 1, 1, -1]
+ for (uint32_t i = 0; i < ENCODE_LENGTH; i++) {
+ scores.push_back(2 * encoded[i] - 1);
+ }
+
+ // Multiply the hadamard matrix by the transformed input.
+ // |1 1 1 1| |-1| | 0|
+ // |1 -1 1 -1| * | 1| = | 0|
+ // |1 1 -1 -1| | 1| | 0|
+ // |1 -1 -1 1| |-1| |-4|
+ for (uint32_t i = 0; i < CODE_K; i++) {
+ uint16_t step = 1u << i;
+ for (uint32_t j = 0; j < ENCODE_LENGTH; j += 2 * step) {
+ for (uint32_t k = j; k < j + step; k++) {
+ auto a0 = scores[k];
+ auto a1 = scores[k + step];
+ scores[k] = a0 + a1;
+ scores[k + step] = a0 - a1;
+ }
+ }
+ }
+
+ // Assign the corresponding score to each index; larger score indicates higher probability. e.g.
+ // value 3, encoding [0, 1, 1, 0] -> score: 4
+ // value 7, encoding [1, 0, 0, 1] (3's complement) -> score: -4
+ std::priority_queue<std::pair<int32_t, uint16_t>> candidates;
+ // TODO(xunchang) limit the candidate size since we don't need all of them?
+ for (uint32_t i = 0; i < scores.size(); i++) {
+ candidates.emplace(-scores[i], i);
+ candidates.emplace(scores[i], (1u << CODE_K) | i);
+ }
+
+ CHECK_EQ(2 * ENCODE_LENGTH, candidates.size());
+ return candidates;
+}
+
+} // namespace hadamard
+} // namespace rebootescrow
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/rebootescrow/aidl/default/HadamardUtils.h b/rebootescrow/aidl/default/HadamardUtils.h
new file mode 100644
index 0000000..21cfc78
--- /dev/null
+++ b/rebootescrow/aidl/default/HadamardUtils.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#pragma once
+
+#include <stdint.h>
+
+#include <bitset>
+#include <queue>
+#include <utility>
+#include <vector>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace rebootescrow {
+namespace hadamard {
+
+constexpr uint32_t CODE_K = 15;
+constexpr uint32_t ENCODE_LENGTH = 1u << CODE_K;
+constexpr auto KEY_SIZE_IN_BYTES = 32u;
+
+// Encodes a 2 bytes word with hadamard code. The encoding expands a word of k+1 bits to a 2^k
+// bitset. Returns the encoded bitset.
+std::bitset<ENCODE_LENGTH> EncodeWord(uint16_t word);
+
+// Decodes the input bitset, and returns a sorted list of pair with (score, value). The value with
+// a higher score indicates a greater likehood.
+std::priority_queue<std::pair<int32_t, uint16_t>> DecodeWord(
+ const std::bitset<ENCODE_LENGTH>& encoded);
+
+// Encodes a key that has a size of KEY_SIZE_IN_BYTES. Returns a byte array representation of the
+// encoded bitset. So a 32 bytes key will expand to 16*(2^15) bits = 64KiB.
+std::vector<uint8_t> EncodeKey(const std::vector<uint8_t>& input);
+
+// Given a byte array representation of the encoded keys, decodes it and return the result.
+std::vector<uint8_t> DecodeKey(const std::vector<uint8_t>& encoded);
+
+// Converts a bitset of length |ENCODE_LENGTH| to a byte array.
+std::vector<uint8_t> BitsetToBytes(const std::bitset<ENCODE_LENGTH>& encoded_bits);
+
+// Converts a byte array of encoded words back to the bitset.
+std::bitset<ENCODE_LENGTH> BytesToBitset(const std::vector<uint8_t>& encoded);
+
+} // namespace hadamard
+} // namespace rebootescrow
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/rebootescrow/aidl/default/HadamardUtilsTest.cpp b/rebootescrow/aidl/default/HadamardUtilsTest.cpp
new file mode 100644
index 0000000..e397e76
--- /dev/null
+++ b/rebootescrow/aidl/default/HadamardUtilsTest.cpp
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#include <stdint.h>
+#include <random>
+
+#include <bitset>
+#include <utility>
+#include <vector>
+
+#include <gtest/gtest.h>
+
+#include <HadamardUtils.h>
+
+using namespace aidl::android::hardware::rebootescrow::hadamard;
+
+class HadamardTest : public testing::Test {
+ protected:
+ void SetUp() override {
+ auto ones = std::bitset<ENCODE_LENGTH>{}.set();
+ // Expects 0x4000 to encode as top half as ones, and lower half as zeros. i.e.
+ // [1, 1 .. 1, 0, 0 .. 0]
+ expected_half_size_ = ones << half_size_;
+
+ // Expects 0x1 to encode as interleaved 1 and 0s i.e. [1, 0, 1, 0 ..]
+ expected_one_ = ones;
+ for (uint32_t i = ENCODE_LENGTH / 2; i >= 1; i /= 2) {
+ expected_one_ ^= (expected_one_ >> i);
+ }
+ }
+
+ uint16_t half_size_ = ENCODE_LENGTH / 2;
+ std::bitset<ENCODE_LENGTH> expected_one_;
+ std::bitset<ENCODE_LENGTH> expected_half_size_;
+};
+
+static void AddError(std::bitset<ENCODE_LENGTH>* corrupted_bits) {
+ // The hadamard code has a hamming distance of ENCODE_LENGTH/2. So we should always be able to
+ // correct the data if less than a quarter of the encoded bits are corrupted.
+ auto corrupted_max = 0.24f * corrupted_bits->size();
+ auto corrupted_num = 0;
+ for (size_t i = 0; i < corrupted_bits->size() && corrupted_num < corrupted_max; i++) {
+ if (random() % 2 == 0) {
+ (*corrupted_bits)[i] = !(*corrupted_bits)[i];
+ corrupted_num += 1;
+ }
+ }
+}
+
+static void EncodeAndDecodeKeys(const std::vector<uint8_t>& key) {
+ auto encoded = EncodeKey(key);
+ ASSERT_EQ(64 * 1024, encoded.size());
+ auto decoded = DecodeKey(encoded);
+ ASSERT_EQ(key, std::vector<uint8_t>(decoded.begin(), decoded.begin() + key.size()));
+}
+
+TEST_F(HadamardTest, Encode_smoke) {
+ ASSERT_EQ(expected_half_size_, EncodeWord(half_size_));
+ ASSERT_EQ(expected_one_, EncodeWord(1));
+ // Check the complement of 1.
+ ASSERT_EQ(~expected_one_, EncodeWord(1u << CODE_K | 1u));
+}
+
+TEST_F(HadamardTest, Decode_smoke) {
+ auto candidate = DecodeWord(expected_half_size_);
+ auto expected = std::pair<int32_t, uint16_t>{ENCODE_LENGTH, half_size_};
+ ASSERT_EQ(expected, candidate.top());
+
+ candidate = DecodeWord(expected_one_);
+ expected = std::pair<int32_t, uint16_t>{ENCODE_LENGTH, 1};
+ ASSERT_EQ(expected, candidate.top());
+}
+
+TEST_F(HadamardTest, Decode_error_correction) {
+ constexpr auto iteration = 10;
+ for (int i = 0; i < iteration; i++) {
+ uint16_t word = random() % (ENCODE_LENGTH * 2);
+ auto corrupted_bits = EncodeWord(word);
+ AddError(&corrupted_bits);
+
+ auto candidate = DecodeWord(corrupted_bits);
+ ASSERT_EQ(word, candidate.top().second);
+ }
+}
+
+TEST_F(HadamardTest, BytesToBitset_smoke) {
+ auto bytes = BitsetToBytes(expected_one_);
+
+ auto read_back = BytesToBitset(bytes);
+ ASSERT_EQ(expected_one_, read_back);
+}
+
+TEST_F(HadamardTest, EncodeAndDecodeKey) {
+ std::vector<uint8_t> KEY_1{
+ 0xA5, 0x00, 0xFF, 0x01, 0xA5, 0x5a, 0xAA, 0x55, 0x00, 0xD3, 0x2A,
+ 0x8C, 0x2E, 0x83, 0x0E, 0x65, 0x9E, 0x8D, 0xC6, 0xAC, 0x1E, 0x83,
+ 0x21, 0xB3, 0x95, 0x02, 0x89, 0x64, 0x64, 0x92, 0x12, 0x1F,
+ };
+ std::vector<uint8_t> KEY_2{
+ 0xFF, 0x00, 0x00, 0xAA, 0x5A, 0x19, 0x20, 0x71, 0x9F, 0xFB, 0xDA,
+ 0xB6, 0x2D, 0x06, 0xD5, 0x49, 0x7E, 0xEF, 0x63, 0xAC, 0x18, 0xFF,
+ 0x5A, 0xA3, 0x40, 0xBB, 0x64, 0xFA, 0x67, 0xC1, 0x10, 0x18,
+ };
+
+ EncodeAndDecodeKeys(KEY_1);
+ EncodeAndDecodeKeys(KEY_2);
+
+ std::vector<uint8_t> key;
+ for (uint8_t i = 0; i < KEY_SIZE_IN_BYTES; i++) {
+ key.push_back(i);
+ };
+ EncodeAndDecodeKeys(key);
+}
diff --git a/rebootescrow/aidl/vts/functional/Android.bp b/rebootescrow/aidl/vts/functional/Android.bp
new file mode 100644
index 0000000..dadf250
--- /dev/null
+++ b/rebootescrow/aidl/vts/functional/Android.bp
@@ -0,0 +1,34 @@
+//
+// Copyright (C) 2019 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.
+//
+
+cc_test {
+ name: "VtsHalRebootEscrowTargetTest",
+ defaults: [
+ "VtsHalTargetTestDefaults",
+ "use_libaidlvintf_gtest_helper_static",
+ ],
+ srcs: ["VtsHalRebootEscrowTargetTest.cpp"],
+ shared_libs: [
+ "libbinder",
+ ],
+ static_libs: [
+ "vintf-rebootescrow-cpp",
+ ],
+ test_suites: [
+ "vts-core",
+ ],
+ require_root: true,
+}
diff --git a/rebootescrow/aidl/vts/functional/VtsHalRebootEscrowTargetTest.cpp b/rebootescrow/aidl/vts/functional/VtsHalRebootEscrowTargetTest.cpp
new file mode 100644
index 0000000..f69cf87
--- /dev/null
+++ b/rebootescrow/aidl/vts/functional/VtsHalRebootEscrowTargetTest.cpp
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+
+#include <android/hardware/rebootescrow/BnRebootEscrow.h>
+
+#include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+
+using android::sp;
+using android::String16;
+using android::hardware::rebootescrow::IRebootEscrow;
+
+/**
+ * This tests that the key can be written, read, and removed. It does not test
+ * that the key survives a reboot. That needs a host-based test.
+ *
+ * atest VtsHalRebootEscrowV1_0TargetTest
+ */
+class RebootEscrowAidlTest : public testing::TestWithParam<std::string> {
+ public:
+ virtual void SetUp() override {
+ rebootescrow = android::waitForDeclaredService<IRebootEscrow>(String16(GetParam().c_str()));
+ ASSERT_NE(rebootescrow, nullptr);
+ }
+
+ sp<IRebootEscrow> rebootescrow;
+
+ std::vector<uint8_t> KEY_1{
+ 0xA5, 0x00, 0xFF, 0x01, 0xA5, 0x5a, 0xAA, 0x55, 0x00, 0xD3, 0x2A,
+ 0x8C, 0x2E, 0x83, 0x0E, 0x65, 0x9E, 0x8D, 0xC6, 0xAC, 0x1E, 0x83,
+ 0x21, 0xB3, 0x95, 0x02, 0x89, 0x64, 0x64, 0x92, 0x12, 0x1F,
+ };
+ std::vector<uint8_t> KEY_2{
+ 0xFF, 0x00, 0x00, 0xAA, 0x5A, 0x19, 0x20, 0x71, 0x9F, 0xFB, 0xDA,
+ 0xB6, 0x2D, 0x06, 0xD5, 0x49, 0x7E, 0xEF, 0x63, 0xAC, 0x18, 0xFF,
+ 0x5A, 0xA3, 0x40, 0xBB, 0x64, 0xFA, 0x67, 0xC1, 0x10, 0x18,
+ };
+ std::vector<uint8_t> EMPTY_KEY{
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ };
+};
+
+TEST_P(RebootEscrowAidlTest, StoreAndRetrieve_Success) {
+ ASSERT_TRUE(rebootescrow->storeKey(KEY_1).isOk());
+
+ std::vector<uint8_t> actualKey;
+ ASSERT_TRUE(rebootescrow->retrieveKey(&actualKey).isOk());
+ EXPECT_EQ(actualKey, KEY_1);
+}
+
+TEST_P(RebootEscrowAidlTest, StoreAndRetrieve_SecondRetrieveSucceeds) {
+ ASSERT_TRUE(rebootescrow->storeKey(KEY_1).isOk());
+
+ std::vector<uint8_t> actualKey;
+ ASSERT_TRUE(rebootescrow->retrieveKey(&actualKey).isOk());
+ EXPECT_EQ(actualKey, KEY_1);
+
+ ASSERT_TRUE(rebootescrow->retrieveKey(&actualKey).isOk());
+ EXPECT_EQ(actualKey, KEY_1);
+}
+
+TEST_P(RebootEscrowAidlTest, StoreTwiceOverwrites_Success) {
+ ASSERT_TRUE(rebootescrow->storeKey(KEY_1).isOk());
+ ASSERT_TRUE(rebootescrow->storeKey(KEY_2).isOk());
+
+ std::vector<uint8_t> actualKey;
+ ASSERT_TRUE(rebootescrow->retrieveKey(&actualKey).isOk());
+ EXPECT_EQ(actualKey, KEY_2);
+}
+
+TEST_P(RebootEscrowAidlTest, StoreEmpty_AfterGetEmptyKey_Success) {
+ rebootescrow->storeKey(KEY_1);
+ rebootescrow->storeKey(EMPTY_KEY);
+
+ std::vector<uint8_t> actualKey;
+ ASSERT_TRUE(rebootescrow->retrieveKey(&actualKey).isOk());
+ EXPECT_EQ(actualKey, EMPTY_KEY);
+}
+
+INSTANTIATE_TEST_SUITE_P(
+ RebootEscrow, RebootEscrowAidlTest,
+ testing::ValuesIn(android::getAidlHalInstanceNames(IRebootEscrow::descriptor)),
+ android::PrintInstanceNameToString);
diff --git a/renderscript/1.0/vts/functional/Android.bp b/renderscript/1.0/vts/functional/Android.bp
index 87e62f1..e3716e0 100644
--- a/renderscript/1.0/vts/functional/Android.bp
+++ b/renderscript/1.0/vts/functional/Android.bp
@@ -28,5 +28,5 @@
"android.hardware.renderscript@1.0",
"libnativewindow",
],
- test_suites: ["general-tests"],
+ test_suites: ["general-tests", "vts-core"],
}
diff --git a/renderscript/1.0/vts/functional/VtsCopyTests.cpp b/renderscript/1.0/vts/functional/VtsCopyTests.cpp
index f47253f..3040cbf 100644
--- a/renderscript/1.0/vts/functional/VtsCopyTests.cpp
+++ b/renderscript/1.0/vts/functional/VtsCopyTests.cpp
@@ -27,7 +27,7 @@
*
* Expect: dataIn & dataOut are the same.
*/
-TEST_F(RenderscriptHidlTest, Simple1DCopyTest) {
+TEST_P(RenderscriptHidlTest, Simple1DCopyTest) {
// float1
Element element = context->elementCreate(DataType::FLOAT_32, DataKind::USER, false, 1);
ASSERT_NE(Element(0), element);
@@ -63,7 +63,7 @@
*
* Expect: dataIn & dataOut are the same.
*/
-TEST_F(RenderscriptHidlTest, Simple2DCopyTest) {
+TEST_P(RenderscriptHidlTest, Simple2DCopyTest) {
// float1
Element element = context->elementCreate(DataType::FLOAT_32, DataKind::USER, false, 1);
ASSERT_NE(Element(0), element);
@@ -100,7 +100,7 @@
*
* Expect: dataIn & dataOut are the same.
*/
-TEST_F(RenderscriptHidlTest, Simple3DCopyTest) {
+TEST_P(RenderscriptHidlTest, Simple3DCopyTest) {
// float1
Element element = context->elementCreate(DataType::FLOAT_32, DataKind::USER, false, 1);
ASSERT_NE(Element(0), element);
@@ -137,7 +137,7 @@
*
* Expect: dataIn & dataOut are the same.
*/
-TEST_F(RenderscriptHidlTest, SimpleBitmapTest) {
+TEST_P(RenderscriptHidlTest, SimpleBitmapTest) {
// float1
Element element = context->elementCreate(DataType::FLOAT_32, DataKind::USER, false, 1);
ASSERT_NE(Element(0), element);
@@ -177,7 +177,7 @@
*
* Expect: dataIn & dataOut are the same.
*/
-TEST_F(RenderscriptHidlTest, AllocationCopy2DRangeTest) {
+TEST_P(RenderscriptHidlTest, AllocationCopy2DRangeTest) {
// float1
Element element = context->elementCreate(DataType::FLOAT_32, DataKind::USER, false, 1);
ASSERT_NE(Element(0), element);
@@ -229,7 +229,7 @@
*
* Expect: dataIn & dataOut are the same.
*/
-TEST_F(RenderscriptHidlTest, AllocationCopy3DRangeTest) {
+TEST_P(RenderscriptHidlTest, AllocationCopy3DRangeTest) {
// float1
Element element = context->elementCreate(DataType::FLOAT_32, DataKind::USER, false, 1);
ASSERT_NE(Element(0), element);
@@ -282,7 +282,7 @@
*
* Expect: dataIn & dataOut are the same.
*/
-TEST_F(RenderscriptHidlTest, SimpleAdapterTest) {
+TEST_P(RenderscriptHidlTest, SimpleAdapterTest) {
// float1
Element element = context->elementCreate(DataType::FLOAT_32, DataKind::USER, false, 1);
ASSERT_NE(Element(0), element);
@@ -339,7 +339,7 @@
*
* Expect: dataIn & dataOut are the same.
*/
-TEST_F(RenderscriptHidlTest, SimpleMipmapTest) {
+TEST_P(RenderscriptHidlTest, SimpleMipmapTest) {
// uint8_t
Element element = context->elementCreate(DataType::UNSIGNED_8, DataKind::USER, false, 1);
ASSERT_NE(Element(0), element);
@@ -386,7 +386,7 @@
*
* Expect: dataIn & dataOut are the same.
*/
-TEST_F(RenderscriptHidlTest, SimpleCubemapTest) {
+TEST_P(RenderscriptHidlTest, SimpleCubemapTest) {
// float1
Element element = context->elementCreate(DataType::FLOAT_32, DataKind::USER, false, 1);
ASSERT_NE(Element(0), element);
@@ -425,7 +425,7 @@
* typeCreate, allocationCreateTyped, allocationElementWrite,
* allocationElementRead
*/
-TEST_F(RenderscriptHidlTest, ComplexElementTest) {
+TEST_P(RenderscriptHidlTest, ComplexElementTest) {
Element element1 = context->elementCreate(DataType::UNSIGNED_8, DataKind::USER, false, 1);
ASSERT_NE(Element(0), element1);
diff --git a/renderscript/1.0/vts/functional/VtsHalRenderscriptV1_0TargetTest.cpp b/renderscript/1.0/vts/functional/VtsHalRenderscriptV1_0TargetTest.cpp
index 0636cf9..5e5776c 100644
--- a/renderscript/1.0/vts/functional/VtsHalRenderscriptV1_0TargetTest.cpp
+++ b/renderscript/1.0/vts/functional/VtsHalRenderscriptV1_0TargetTest.cpp
@@ -18,8 +18,7 @@
// The main test class for RENDERSCRIPT HIDL HAL.
void RenderscriptHidlTest::SetUp() {
- device = ::testing::VtsHalHidlTargetTestBase::getService<IDevice>(
- RenderscriptHidlEnvironment::Instance()->getServiceName<IDevice>());
+ device = IDevice::getService(GetParam());
ASSERT_NE(nullptr, device.get());
uint32_t version = 0;
@@ -35,11 +34,7 @@
}
}
-int main(int argc, char** argv) {
- ::testing::AddGlobalTestEnvironment(RenderscriptHidlEnvironment::Instance());
- ::testing::InitGoogleTest(&argc, argv);
- RenderscriptHidlEnvironment::Instance()->init(&argc, argv);
- int status = RUN_ALL_TESTS();
- LOG(INFO) << "Test result = " << status;
- return status;
-}
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, RenderscriptHidlTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(IDevice::descriptor)),
+ android::hardware::PrintInstanceNameToString);
diff --git a/renderscript/1.0/vts/functional/VtsHalRenderscriptV1_0TargetTest.h b/renderscript/1.0/vts/functional/VtsHalRenderscriptV1_0TargetTest.h
index e11ab92..b7dbed4 100644
--- a/renderscript/1.0/vts/functional/VtsHalRenderscriptV1_0TargetTest.h
+++ b/renderscript/1.0/vts/functional/VtsHalRenderscriptV1_0TargetTest.h
@@ -14,8 +14,7 @@
* limitations under the License.
*/
-#ifndef VTS_HAL_RENDERSCRIPT_V1_0_TARGET_TESTS_H
-#define VTS_HAL_RENDERSCRIPT_V1_0_TARGET_TESTS_H
+#pragma once
#define LOG_TAG "renderscript_hidl_hal_test"
#include <android-base/logging.h>
@@ -24,9 +23,9 @@
#include <android/hardware/renderscript/1.0/IDevice.h>
#include <android/hardware/renderscript/1.0/types.h>
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
using ::android::hardware::renderscript::V1_0::Allocation;
using ::android::hardware::renderscript::V1_0::AllocationAdapter;
@@ -89,8 +88,8 @@
extern const int bitCodeLength;
// The main test class for RENDERSCRIPT HIDL HAL.
-class RenderscriptHidlTest : public ::testing::VtsHalHidlTargetTestBase {
-public:
+class RenderscriptHidlTest : public ::testing::TestWithParam<std::string> {
+ public:
virtual void SetUp() override;
virtual void TearDown() override;
@@ -99,17 +98,3 @@
private:
sp<IDevice> device;
};
-
-// Test environment for RENDERSCRIPT HIDL HAL.
-class RenderscriptHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static RenderscriptHidlEnvironment* Instance() {
- static RenderscriptHidlEnvironment* instance = new RenderscriptHidlEnvironment;
- return instance;
- }
-
- virtual void registerTestServices() override { registerTestService<IDevice>(); }
-};
-
-#endif // VTS_HAL_RENDERSCRIPT_V1_0_TARGET_TESTS_H
diff --git a/renderscript/1.0/vts/functional/VtsMiscellaneousTests.cpp b/renderscript/1.0/vts/functional/VtsMiscellaneousTests.cpp
index 278dbf3..c66ddea 100644
--- a/renderscript/1.0/vts/functional/VtsMiscellaneousTests.cpp
+++ b/renderscript/1.0/vts/functional/VtsMiscellaneousTests.cpp
@@ -25,14 +25,14 @@
*
* Calls: getService<IDevice>, contextCreate, contextDestroy
*/
-TEST_F(RenderscriptHidlTest, ContextCreateAndDestroy) {}
+TEST_P(RenderscriptHidlTest, ContextCreateAndDestroy) {}
/*
* Create an Element and verify the return value is valid.
*
* Calls: elementCreate
*/
-TEST_F(RenderscriptHidlTest, ElementCreate) {
+TEST_P(RenderscriptHidlTest, ElementCreate) {
Element element = context->elementCreate(DataType::FLOAT_32, DataKind::USER, false, 1);
EXPECT_NE(Element(0), element);
}
@@ -43,7 +43,7 @@
*
* Calls: elementCreate, typeCreate, allocationCreateTyped, allocationGetType
*/
-TEST_F(RenderscriptHidlTest, ElementTypeAllocationCreate) {
+TEST_P(RenderscriptHidlTest, ElementTypeAllocationCreate) {
// Element create test
Element element = context->elementCreate(DataType::FLOAT_32, DataKind::USER, false, 1);
ASSERT_NE(Element(0), element);
@@ -71,7 +71,7 @@
* Calls: elementCreate, typeCreate, elementGetNativeMetadata,
* typeGetNativeMetadata
*/
-TEST_F(RenderscriptHidlTest, MetadataTest) {
+TEST_P(RenderscriptHidlTest, MetadataTest) {
// float1
Element element = context->elementCreate(DataType::FLOAT_32, DataKind::USER, false, 1);
ASSERT_NE(Element(0), element);
@@ -107,7 +107,7 @@
* Calls: elementCreate, typeCreate, allocationCreateTyped,
* allocationGetPointer, allocationResize1D
*/
-TEST_F(RenderscriptHidlTest, ResizeTest) {
+TEST_P(RenderscriptHidlTest, ResizeTest) {
// float1
Element element = context->elementCreate(DataType::FLOAT_32, DataKind::USER, false, 1);
ASSERT_NE(Element(0), element);
@@ -145,7 +145,7 @@
* allocationGetNativeWindow, allocationSetNativeWindow, allocationIoSend,
* allocationIoReceive, allocation2DRead
*/
-TEST_F(RenderscriptHidlTest, NativeWindowIoTest) {
+TEST_P(RenderscriptHidlTest, NativeWindowIoTest) {
// uint8x4
Element element = context->elementCreate(DataType::UNSIGNED_8, DataKind::USER, false, 4);
ASSERT_NE(Element(0), element);
@@ -198,7 +198,7 @@
* allocation2DWrite, allocation2DRead, allocationIoSend,
* allocationIoReceive
*/
-TEST_F(RenderscriptHidlTest, BufferQueueTest) {
+TEST_P(RenderscriptHidlTest, BufferQueueTest) {
// uint8x4
Element element = context->elementCreate(DataType::UNSIGNED_8, DataKind::USER, false, 4);
ASSERT_NE(Element(0), element);
@@ -269,7 +269,7 @@
* Calls: contextInitToClient, contextSendMessage, contextPeekMessage,
* contextGetMessage, contextDeinitToClient, contextLog
*/
-TEST_F(RenderscriptHidlTest, ContextMessageTest) {
+TEST_P(RenderscriptHidlTest, ContextMessageTest) {
context->contextInitToClient();
const char * message = "correct";
@@ -299,7 +299,7 @@
* Calls: contextSetPriority, contextSetCacheDir, elementCreate, assignName,
* contextFinish, getName, objDestroy, samplerCreate
*/
-TEST_F(RenderscriptHidlTest, MiscellaneousTests) {
+TEST_P(RenderscriptHidlTest, MiscellaneousTests) {
context->contextSetPriority(ThreadPriorities::NORMAL);
context->contextSetCacheDir("/data/local/tmp/temp/");
diff --git a/renderscript/1.0/vts/functional/VtsScriptTests.cpp b/renderscript/1.0/vts/functional/VtsScriptTests.cpp
index 8d24cfa..9607267 100644
--- a/renderscript/1.0/vts/functional/VtsScriptTests.cpp
+++ b/renderscript/1.0/vts/functional/VtsScriptTests.cpp
@@ -22,7 +22,7 @@
*
* Calls: elementCreate, scriptIntrinsicCreate, scriptSetTimeZone
*/
-TEST_F(RenderscriptHidlTest, IntrinsicTest) {
+TEST_P(RenderscriptHidlTest, IntrinsicTest) {
// uint8
Element element = context->elementCreate(DataType::UNSIGNED_8, DataKind::USER, false, 1);
EXPECT_NE(Element(0), element);
@@ -41,7 +41,7 @@
* scriptSetVarF, scriptSetVarD, elementCreate, typeCreate,
* allocationCreateTyped, scriptSetVarObj, scriptSetVarV, scriptSetVarVE
*/
-TEST_F(RenderscriptHidlTest, ScriptVarTest) {
+TEST_P(RenderscriptHidlTest, ScriptVarTest) {
hidl_vec<uint8_t> bitcode;
bitcode.setToExternal((uint8_t*)bitCode, bitCodeLength);
Script script = context->scriptCCreate("struct_test", "/data/local/tmp/", bitcode);
@@ -132,7 +132,7 @@
*
* Calls: scriptCCreate, scriptInvoke, scriptGetVarV, scriptInvokeV
*/
-TEST_F(RenderscriptHidlTest, ScriptInvokeTest) {
+TEST_P(RenderscriptHidlTest, ScriptInvokeTest) {
hidl_vec<uint8_t> bitcode;
bitcode.setToExternal((uint8_t*)bitCode, bitCodeLength);
Script script = context->scriptCCreate("struct_test", "/data/local/tmp/", bitcode);
@@ -191,7 +191,7 @@
* Calls: scriptCCreate, elementCreate, typeCreate, allocationCreateTyped,
* allocation1DWrite, scriptForEach, allocationRead
*/
-TEST_F(RenderscriptHidlTest, ScriptForEachTest) {
+TEST_P(RenderscriptHidlTest, ScriptForEachTest) {
hidl_vec<uint8_t> bitcode;
bitcode.setToExternal((uint8_t*)bitCode, bitCodeLength);
Script script = context->scriptCCreate("struct_test", "/data/local/tmp/", bitcode);
@@ -237,7 +237,7 @@
* Calls: scriptCCreate, elementCreate, typeCreate, allocationCreateTyped,
* allocation1DWrite, scriptReduce, contextFinish, allocationRead
*/
-TEST_F(RenderscriptHidlTest, ScriptReduceTest) {
+TEST_P(RenderscriptHidlTest, ScriptReduceTest) {
hidl_vec<uint8_t> bitcode;
bitcode.setToExternal((uint8_t*)bitCode, bitCodeLength);
Script script = context->scriptCCreate("struct_test", "/data/local/tmp/", bitcode);
@@ -288,7 +288,7 @@
* allocation1DWrite, scriptBindAllocation, scriptSetVarV, scriptBindAllocation,
* allocationRead, scriptInvokeV, allocationRead
*/
-TEST_F(RenderscriptHidlTest, ScriptBindTest) {
+TEST_P(RenderscriptHidlTest, ScriptBindTest) {
hidl_vec<uint8_t> bitcode;
bitcode.setToExternal((uint8_t*)bitCode, bitCodeLength);
Script script = context->scriptCCreate("struct_test", "/data/local/tmp/", bitcode);
@@ -333,7 +333,7 @@
* scriptGroupCreate, scriptGroupSetInput, scriptGroupSetOutput,
* scriptGroupExecute, contextFinish, allocation2DRead
*/
-TEST_F(RenderscriptHidlTest, ScriptGroupTest) {
+TEST_P(RenderscriptHidlTest, ScriptGroupTest) {
std::vector<uint8_t> dataIn(256 * 256 * 4, 128), dataOut(256 * 256 * 4, 0),
zeros(256 * 256 * 4, 0);
hidl_vec<uint8_t> _dataIn, _dataOut;
@@ -418,7 +418,7 @@
* invokeClosureCreate, closureCreate, closureSetGlobal, scriptGroup2Create,
* scriptGroupExecute, allocationRead
*/
-TEST_F(RenderscriptHidlTest, ScriptGroup2Test) {
+TEST_P(RenderscriptHidlTest, ScriptGroup2Test) {
hidl_vec<uint8_t> bitcode;
bitcode.setToExternal((uint8_t*)bitCode, bitCodeLength);
Script script = context->scriptCCreate("struct_test", "/data/local/tmp/", bitcode);
@@ -495,7 +495,7 @@
* allocation1DWrite, scriptKernelIDCreate, closureCreate, closureSetArg,
* scriptGroup2Create, scriptGroupExecute, allocationRead
*/
-TEST_F(RenderscriptHidlTest, ScriptGroup2KernelTest) {
+TEST_P(RenderscriptHidlTest, ScriptGroup2KernelTest) {
hidl_vec<uint8_t> bitcode;
bitcode.setToExternal((uint8_t*)bitCode, bitCodeLength);
Script script = context->scriptCCreate("struct_test", "/data/local/tmp/", bitcode);
diff --git a/secure_element/1.0/vts/functional/Android.bp b/secure_element/1.0/vts/functional/Android.bp
index 2b2b73e..6dbd027 100644
--- a/secure_element/1.0/vts/functional/Android.bp
+++ b/secure_element/1.0/vts/functional/Android.bp
@@ -21,5 +21,5 @@
static_libs: [
"android.hardware.secure_element@1.0",
],
- test_suites: ["general-tests"],
+ test_suites: ["general-tests", "vts-core"],
}
diff --git a/secure_element/1.0/vts/functional/VtsHalSecureElementV1_0TargetTest.cpp b/secure_element/1.0/vts/functional/VtsHalSecureElementV1_0TargetTest.cpp
index 671923a..93ffd05 100644
--- a/secure_element/1.0/vts/functional/VtsHalSecureElementV1_0TargetTest.cpp
+++ b/secure_element/1.0/vts/functional/VtsHalSecureElementV1_0TargetTest.cpp
@@ -20,10 +20,11 @@
#include <android/hardware/secure_element/1.0/ISecureElement.h>
#include <android/hardware/secure_element/1.0/ISecureElementHalCallback.h>
#include <android/hardware/secure_element/1.0/types.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include <VtsHalHidlTargetCallbackBase.h>
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
using ::android::hardware::secure_element::V1_0::ISecureElement;
using ::android::hardware::secure_element::V1_0::ISecureElementHalCallback;
@@ -32,7 +33,6 @@
using ::android::hardware::Return;
using ::android::hardware::Void;
using ::android::sp;
-using ::testing::VtsHalHidlTargetTestEnvBase;
#define DATA_APDU \
{ 0x00, 0x08, 0x00, 0x00, 0x00 }
@@ -63,30 +63,11 @@
};
};
-class SecureElementHidlEnvironment : public VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static SecureElementHidlEnvironment* Instance() {
- static SecureElementHidlEnvironment* instance = new SecureElementHidlEnvironment;
- return instance;
- }
-
- virtual void registerTestServices() override { registerTestService<ISecureElement>(); }
-
- private:
- SecureElementHidlEnvironment() {}
-
- GTEST_DISALLOW_COPY_AND_ASSIGN_(SecureElementHidlEnvironment);
-};
-
-class SecureElementHidlTest : public ::testing::VtsHalHidlTargetTestBase {
- public:
+class SecureElementHidlTest : public ::testing::TestWithParam<std::string> {
+ public:
virtual void SetUp() override {
- std::string serviceName =
- SecureElementHidlEnvironment::Instance()->getServiceName<ISecureElement>("eSE1");
- LOG(INFO) << "get service with name:" << serviceName;
- ASSERT_FALSE(serviceName.empty());
- se_ = ::testing::VtsHalHidlTargetTestBase::getService<ISecureElement>(serviceName);
+ LOG(INFO) << "get service with name:" << GetParam();
+ se_ = ISecureElement::getService(GetParam());
ASSERT_NE(se_, nullptr);
se_cb_ = new SecureElementHalCallback();
@@ -105,7 +86,7 @@
* isCardPresent:
* Expects the card to be present
*/
-TEST_F(SecureElementHidlTest, isCardPresent) {
+TEST_P(SecureElementHidlTest, isCardPresent) {
EXPECT_TRUE(se_->isCardPresent());
}
@@ -113,7 +94,7 @@
* transmit:
* Check status word in the response
*/
-TEST_F(SecureElementHidlTest, transmit) {
+TEST_P(SecureElementHidlTest, transmit) {
std::vector<uint8_t> aid = ANDROID_TEST_AID;
SecureElementStatus statusReturned;
LogicalChannelResponse response;
@@ -153,7 +134,7 @@
* If the secure element allows opening of basic channel:
* open channel, check the length of selectResponse and close the channel
*/
-TEST_F(SecureElementHidlTest, openBasicChannel) {
+TEST_P(SecureElementHidlTest, openBasicChannel) {
std::vector<uint8_t> aid = ANDROID_TEST_AID;
SecureElementStatus statusReturned;
std::vector<uint8_t> response;
@@ -179,7 +160,7 @@
/*
* GetATR
*/
-TEST_F(SecureElementHidlTest, getAtr) {
+TEST_P(SecureElementHidlTest, getAtr) {
std::vector<uint8_t> atr;
se_->getAtr([&atr](std::vector<uint8_t> atrReturned) {
atr.resize(atrReturned.size());
@@ -200,7 +181,7 @@
* Check status
* Close Channel
*/
-TEST_F(SecureElementHidlTest, openCloseLogicalChannel) {
+TEST_P(SecureElementHidlTest, openCloseLogicalChannel) {
std::vector<uint8_t> aid = ANDROID_TEST_AID;
SecureElementStatus statusReturned;
LogicalChannelResponse response;
@@ -223,10 +204,7 @@
EXPECT_EQ(SecureElementStatus::SUCCESS, se_->closeChannel(response.channelNumber));
}
-int main(int argc, char** argv) {
- ::testing::AddGlobalTestEnvironment(SecureElementHidlEnvironment::Instance());
- ::testing::InitGoogleTest(&argc, argv);
- SecureElementHidlEnvironment::Instance()->init(&argc, argv);
- int status = RUN_ALL_TESTS();
- return status;
-}
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, SecureElementHidlTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(ISecureElement::descriptor)),
+ android::hardware::PrintInstanceNameToString);
\ No newline at end of file
diff --git a/secure_element/1.1/vts/functional/Android.bp b/secure_element/1.1/vts/functional/Android.bp
index 51410bd..a2c39dc 100644
--- a/secure_element/1.1/vts/functional/Android.bp
+++ b/secure_element/1.1/vts/functional/Android.bp
@@ -22,5 +22,5 @@
"android.hardware.secure_element@1.0",
"android.hardware.secure_element@1.1",
],
- test_suites: ["general-tests"],
+ test_suites: ["general-tests", "vts-core"],
}
diff --git a/secure_element/1.1/vts/functional/VtsHalSecureElementV1_1TargetTest.cpp b/secure_element/1.1/vts/functional/VtsHalSecureElementV1_1TargetTest.cpp
index f8765ca..66fc47c 100644
--- a/secure_element/1.1/vts/functional/VtsHalSecureElementV1_1TargetTest.cpp
+++ b/secure_element/1.1/vts/functional/VtsHalSecureElementV1_1TargetTest.cpp
@@ -22,10 +22,11 @@
#include <android/hardware/secure_element/1.0/types.h>
#include <android/hardware/secure_element/1.1/ISecureElement.h>
#include <android/hardware/secure_element/1.1/ISecureElementHalCallback.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include <VtsHalHidlTargetCallbackBase.h>
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
using ::android::sp;
using ::android::hardware::hidl_string;
@@ -33,7 +34,6 @@
using ::android::hardware::Void;
using ::android::hardware::secure_element::V1_1::ISecureElement;
using ::android::hardware::secure_element::V1_1::ISecureElementHalCallback;
-using ::testing::VtsHalHidlTargetTestEnvBase;
constexpr char kCallbackNameOnStateChange[] = "onStateChange";
@@ -60,30 +60,11 @@
Return<void> onStateChange(__attribute__((unused)) bool state) override { return Void(); }
};
-class SecureElementHidlEnvironment : public VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static SecureElementHidlEnvironment* Instance() {
- static SecureElementHidlEnvironment* instance = new SecureElementHidlEnvironment;
- return instance;
- }
-
- virtual void registerTestServices() override { registerTestService<ISecureElement>(); }
-
- private:
- SecureElementHidlEnvironment() {}
-
- GTEST_DISALLOW_COPY_AND_ASSIGN_(SecureElementHidlEnvironment);
-};
-
-class SecureElementHidlTest : public ::testing::VtsHalHidlTargetTestBase {
- public:
+class SecureElementHidlTest : public ::testing::TestWithParam<std::string> {
+ public:
virtual void SetUp() override {
- std::string serviceName =
- SecureElementHidlEnvironment::Instance()->getServiceName<ISecureElement>("eSE1");
- LOG(INFO) << "get service with name:" << serviceName;
- ASSERT_FALSE(serviceName.empty());
- se_ = ::testing::VtsHalHidlTargetTestBase::getService<ISecureElement>(serviceName);
+ LOG(INFO) << "get service with name:" << GetParam();
+ se_ = ISecureElement::getService(GetParam());
ASSERT_NE(se_, nullptr);
se_cb_ = new SecureElementHalCallback();
@@ -103,14 +84,11 @@
* isCardPresent:
* Expects the card to be present
*/
-TEST_F(SecureElementHidlTest, isCardPresent) {
+TEST_P(SecureElementHidlTest, isCardPresent) {
EXPECT_TRUE(se_->isCardPresent());
}
-int main(int argc, char** argv) {
- ::testing::AddGlobalTestEnvironment(SecureElementHidlEnvironment::Instance());
- ::testing::InitGoogleTest(&argc, argv);
- SecureElementHidlEnvironment::Instance()->init(&argc, argv);
- int status = RUN_ALL_TESTS();
- return status;
-}
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, SecureElementHidlTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(ISecureElement::descriptor)),
+ android::hardware::PrintInstanceNameToString);
diff --git a/sensors/1.0/vts/functional/Android.bp b/sensors/1.0/vts/functional/Android.bp
index 7bb992b..1167fd4 100644
--- a/sensors/1.0/vts/functional/Android.bp
+++ b/sensors/1.0/vts/functional/Android.bp
@@ -31,6 +31,6 @@
"android.hardware.sensors@1.0",
"VtsHalSensorsTargetTestUtils",
],
- test_suites: ["general-tests"],
+ test_suites: ["general-tests", "vts-core"],
}
diff --git a/sensors/1.0/vts/functional/AndroidTest.xml b/sensors/1.0/vts/functional/AndroidTest.xml
new file mode 100644
index 0000000..fb0d64c
--- /dev/null
+++ b/sensors/1.0/vts/functional/AndroidTest.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 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.
+-->
+<configuration description="Runs VtsHalSensorsV1_0TargetTest.">
+ <option name="test-suite-tag" value="apct" />
+ <option name="test-suite-tag" value="apct-native" />
+
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
+ </target_preparer>
+
+ <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+ <option name="run-command" value="stop"/>
+ <option name="teardown-command" value="start"/>
+ </target_preparer>
+
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="cleanup" value="true" />
+ <option name="push" value="VtsHalSensorsV1_0TargetTest->/data/local/tmp/VtsHalSensorsV1_0TargetTest" />
+ </target_preparer>
+
+ <test class="com.android.tradefed.testtype.GTest" >
+ <option name="native-test-timeout" value="900000" />
+ <option name="runtime-hint" value="300000"/>
+ <option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="module-name" value="VtsHalSensorsV1_0TargetTest" />
+ </test>
+</configuration>
\ No newline at end of file
diff --git a/sensors/1.0/vts/functional/SensorsHidlEnvironmentV1_0.cpp b/sensors/1.0/vts/functional/SensorsHidlEnvironmentV1_0.cpp
index 00207b1..1e5e886 100644
--- a/sensors/1.0/vts/functional/SensorsHidlEnvironmentV1_0.cpp
+++ b/sensors/1.0/vts/functional/SensorsHidlEnvironmentV1_0.cpp
@@ -35,8 +35,7 @@
// this do ... while is for easy error handling
do {
step = "getService()";
- sensors = ISensors::getService(
- SensorsHidlEnvironmentV1_0::Instance()->getServiceName<ISensors>());
+ sensors = ISensors::getService(mServiceName);
if (sensors == nullptr) {
break;
}
diff --git a/sensors/1.0/vts/functional/SensorsHidlEnvironmentV1_0.h b/sensors/1.0/vts/functional/SensorsHidlEnvironmentV1_0.h
index 0a9e59f..29bfa50 100644
--- a/sensors/1.0/vts/functional/SensorsHidlEnvironmentV1_0.h
+++ b/sensors/1.0/vts/functional/SensorsHidlEnvironmentV1_0.h
@@ -32,23 +32,14 @@
class SensorsHidlEnvironmentV1_0 : public SensorsHidlEnvironmentBase {
public:
using Event = ::android::hardware::sensors::V1_0::Event;
- // get the test environment singleton
- static SensorsHidlEnvironmentV1_0* Instance() {
- static SensorsHidlEnvironmentV1_0* instance = new SensorsHidlEnvironmentV1_0();
- return instance;
- }
+ SensorsHidlEnvironmentV1_0(const std::string& service_name)
+ : SensorsHidlEnvironmentBase(service_name) {}
- virtual void registerTestServices() override {
- registerTestService<android::hardware::sensors::V1_0::ISensors>();
- }
-
- private:
+ private:
friend SensorsHidlTest;
// sensors hidl service
sp<android::hardware::sensors::V1_0::ISensors> sensors;
- SensorsHidlEnvironmentV1_0() {}
-
bool resetHal() override;
void startPollingThread() override;
static void pollingThread(SensorsHidlEnvironmentV1_0* env, std::atomic_bool& stop);
diff --git a/sensors/1.0/vts/functional/VtsHalSensorsV1_0TargetTest.cpp b/sensors/1.0/vts/functional/VtsHalSensorsV1_0TargetTest.cpp
index 5453ef6..2cad54d 100644
--- a/sensors/1.0/vts/functional/VtsHalSensorsV1_0TargetTest.cpp
+++ b/sensors/1.0/vts/functional/VtsHalSensorsV1_0TargetTest.cpp
@@ -19,6 +19,8 @@
#include <android/hardware/sensors/1.0/ISensors.h>
#include <android/hardware/sensors/1.0/types.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include <log/log.h>
#include <utils/SystemClock.h>
@@ -33,7 +35,17 @@
// The main test class for SENSORS HIDL HAL.
class SensorsHidlTest : public SensorsHidlTestBase {
- protected:
+ public:
+ virtual void SetUp() override {
+ mEnvironment = new SensorsHidlEnvironmentV1_0(GetParam());
+ mEnvironment->HidlSetUp();
+ // Ensure that we have a valid environment before performing tests
+ ASSERT_NE(S(), nullptr);
+ }
+
+ virtual void TearDown() override { mEnvironment->HidlTearDown(); }
+
+ protected:
SensorInfo defaultSensorByType(SensorType type) override;
std::vector<SensorInfo> getSensorsList();
// implementation wrapper
@@ -66,11 +78,13 @@
return S()->configDirectReport(sensorHandle, channelHandle, rate, _hidl_cb);
}
- inline sp<ISensors>& S() { return SensorsHidlEnvironmentV1_0::Instance()->sensors; }
+ inline sp<ISensors>& S() { return mEnvironment->sensors; }
- SensorsHidlEnvironmentBase* getEnvironment() override {
- return SensorsHidlEnvironmentV1_0::Instance();
- }
+ SensorsHidlEnvironmentBase* getEnvironment() override { return mEnvironment; }
+
+ private:
+ // Test environment for sensors HAL.
+ SensorsHidlEnvironmentV1_0* mEnvironment;
};
Return<Result> SensorsHidlTest::activate(int32_t sensorHandle, bool enabled) {
@@ -133,55 +147,52 @@
}
// Test if sensor list returned is valid
-TEST_F(SensorsHidlTest, SensorListValid) {
- S()->getSensorsList(
- [&] (const auto &list) {
+TEST_P(SensorsHidlTest, SensorListValid) {
+ S()->getSensorsList([&](const auto& list) {
const size_t count = list.size();
for (size_t i = 0; i < count; ++i) {
- const auto &s = list[i];
- SCOPED_TRACE(::testing::Message() << i << "/" << count << ": "
- << " handle=0x" << std::hex << std::setw(8) << std::setfill('0')
- << s.sensorHandle << std::dec
- << " type=" << static_cast<int>(s.type)
- << " name=" << s.name);
+ const auto& s = list[i];
+ SCOPED_TRACE(::testing::Message()
+ << i << "/" << count << ": "
+ << " handle=0x" << std::hex << std::setw(8) << std::setfill('0')
+ << s.sensorHandle << std::dec << " type=" << static_cast<int>(s.type)
+ << " name=" << s.name);
- // Test non-empty type string
- EXPECT_FALSE(s.typeAsString.empty());
+ // Test non-empty type string
+ EXPECT_FALSE(s.typeAsString.empty());
- // Test defined type matches defined string type
- EXPECT_NO_FATAL_FAILURE(assertTypeMatchStringType(s.type, s.typeAsString));
+ // Test defined type matches defined string type
+ EXPECT_NO_FATAL_FAILURE(assertTypeMatchStringType(s.type, s.typeAsString));
- // Test if all sensor has name and vendor
- EXPECT_FALSE(s.name.empty());
- EXPECT_FALSE(s.vendor.empty());
+ // Test if all sensor has name and vendor
+ EXPECT_FALSE(s.name.empty());
+ EXPECT_FALSE(s.vendor.empty());
- // Test power > 0, maxRange > 0
- EXPECT_LE(0, s.power);
- EXPECT_LT(0, s.maxRange);
+ // Test power > 0, maxRange > 0
+ EXPECT_LE(0, s.power);
+ EXPECT_LT(0, s.maxRange);
- // Info type, should have no sensor
- EXPECT_FALSE(
- s.type == SensorType::ADDITIONAL_INFO
- || s.type == SensorType::META_DATA);
+ // Info type, should have no sensor
+ EXPECT_FALSE(s.type == SensorType::ADDITIONAL_INFO || s.type == SensorType::META_DATA);
- // Test fifoMax >= fifoReserved
- EXPECT_GE(s.fifoMaxEventCount, s.fifoReservedEventCount)
- << "max=" << s.fifoMaxEventCount << " reserved=" << s.fifoReservedEventCount;
+ // Test fifoMax >= fifoReserved
+ EXPECT_GE(s.fifoMaxEventCount, s.fifoReservedEventCount)
+ << "max=" << s.fifoMaxEventCount << " reserved=" << s.fifoReservedEventCount;
- // Test Reporting mode valid
- EXPECT_NO_FATAL_FAILURE(assertTypeMatchReportMode(s.type, extractReportMode(s.flags)));
+ // Test Reporting mode valid
+ EXPECT_NO_FATAL_FAILURE(assertTypeMatchReportMode(s.type, extractReportMode(s.flags)));
- // Test min max are in the right order
- EXPECT_LE(s.minDelay, s.maxDelay);
- // Test min/max delay matches reporting mode
- EXPECT_NO_FATAL_FAILURE(
- assertDelayMatchReportMode(s.minDelay, s.maxDelay, extractReportMode(s.flags)));
+ // Test min max are in the right order
+ EXPECT_LE(s.minDelay, s.maxDelay);
+ // Test min/max delay matches reporting mode
+ EXPECT_NO_FATAL_FAILURE(
+ assertDelayMatchReportMode(s.minDelay, s.maxDelay, extractReportMode(s.flags)));
}
- });
+ });
}
// Test if sensor list returned is valid
-TEST_F(SensorsHidlTest, SetOperationMode) {
+TEST_P(SensorsHidlTest, SetOperationMode) {
std::vector<SensorInfo> sensorList = getSensorsList();
bool needOperationModeSupport =
@@ -199,7 +210,7 @@
}
// Test if sensor list returned is valid
-TEST_F(SensorsHidlTest, InjectSensorEventData) {
+TEST_P(SensorsHidlTest, InjectSensorEventData) {
std::vector<SensorInfo> sensorList = getSensorsList();
std::vector<SensorInfo> sensorSupportInjection;
@@ -244,224 +255,202 @@
}
// Test if sensor hal can do UI speed accelerometer streaming properly
-TEST_F(SensorsHidlTest, AccelerometerStreamingOperationSlow) {
- testStreamingOperation(SensorType::ACCELEROMETER,
- std::chrono::milliseconds(200),
- std::chrono::seconds(5),
- sAccelNormChecker);
+TEST_P(SensorsHidlTest, AccelerometerStreamingOperationSlow) {
+ testStreamingOperation(SensorType::ACCELEROMETER, std::chrono::milliseconds(200),
+ std::chrono::seconds(5), sAccelNormChecker);
}
// Test if sensor hal can do normal speed accelerometer streaming properly
-TEST_F(SensorsHidlTest, AccelerometerStreamingOperationNormal) {
- testStreamingOperation(SensorType::ACCELEROMETER,
- std::chrono::milliseconds(20),
- std::chrono::seconds(5),
- sAccelNormChecker);
+TEST_P(SensorsHidlTest, AccelerometerStreamingOperationNormal) {
+ testStreamingOperation(SensorType::ACCELEROMETER, std::chrono::milliseconds(20),
+ std::chrono::seconds(5), sAccelNormChecker);
}
// Test if sensor hal can do game speed accelerometer streaming properly
-TEST_F(SensorsHidlTest, AccelerometerStreamingOperationFast) {
- testStreamingOperation(SensorType::ACCELEROMETER,
- std::chrono::milliseconds(5),
- std::chrono::seconds(5),
- sAccelNormChecker);
+TEST_P(SensorsHidlTest, AccelerometerStreamingOperationFast) {
+ testStreamingOperation(SensorType::ACCELEROMETER, std::chrono::milliseconds(5),
+ std::chrono::seconds(5), sAccelNormChecker);
}
// Test if sensor hal can do UI speed gyroscope streaming properly
-TEST_F(SensorsHidlTest, GyroscopeStreamingOperationSlow) {
- testStreamingOperation(SensorType::GYROSCOPE,
- std::chrono::milliseconds(200),
- std::chrono::seconds(5),
- sGyroNormChecker);
+TEST_P(SensorsHidlTest, GyroscopeStreamingOperationSlow) {
+ testStreamingOperation(SensorType::GYROSCOPE, std::chrono::milliseconds(200),
+ std::chrono::seconds(5), sGyroNormChecker);
}
// Test if sensor hal can do normal speed gyroscope streaming properly
-TEST_F(SensorsHidlTest, GyroscopeStreamingOperationNormal) {
- testStreamingOperation(SensorType::GYROSCOPE,
- std::chrono::milliseconds(20),
- std::chrono::seconds(5),
- sGyroNormChecker);
+TEST_P(SensorsHidlTest, GyroscopeStreamingOperationNormal) {
+ testStreamingOperation(SensorType::GYROSCOPE, std::chrono::milliseconds(20),
+ std::chrono::seconds(5), sGyroNormChecker);
}
// Test if sensor hal can do game speed gyroscope streaming properly
-TEST_F(SensorsHidlTest, GyroscopeStreamingOperationFast) {
- testStreamingOperation(SensorType::GYROSCOPE,
- std::chrono::milliseconds(5),
- std::chrono::seconds(5),
- sGyroNormChecker);
+TEST_P(SensorsHidlTest, GyroscopeStreamingOperationFast) {
+ testStreamingOperation(SensorType::GYROSCOPE, std::chrono::milliseconds(5),
+ std::chrono::seconds(5), sGyroNormChecker);
}
// Test if sensor hal can do UI speed magnetometer streaming properly
-TEST_F(SensorsHidlTest, MagnetometerStreamingOperationSlow) {
- testStreamingOperation(SensorType::MAGNETIC_FIELD,
- std::chrono::milliseconds(200),
- std::chrono::seconds(5),
- NullChecker());
+TEST_P(SensorsHidlTest, MagnetometerStreamingOperationSlow) {
+ testStreamingOperation(SensorType::MAGNETIC_FIELD, std::chrono::milliseconds(200),
+ std::chrono::seconds(5), NullChecker());
}
// Test if sensor hal can do normal speed magnetometer streaming properly
-TEST_F(SensorsHidlTest, MagnetometerStreamingOperationNormal) {
- testStreamingOperation(SensorType::MAGNETIC_FIELD,
- std::chrono::milliseconds(20),
- std::chrono::seconds(5),
- NullChecker());
+TEST_P(SensorsHidlTest, MagnetometerStreamingOperationNormal) {
+ testStreamingOperation(SensorType::MAGNETIC_FIELD, std::chrono::milliseconds(20),
+ std::chrono::seconds(5), NullChecker());
}
// Test if sensor hal can do game speed magnetometer streaming properly
-TEST_F(SensorsHidlTest, MagnetometerStreamingOperationFast) {
- testStreamingOperation(SensorType::MAGNETIC_FIELD,
- std::chrono::milliseconds(5),
- std::chrono::seconds(5),
- NullChecker());
+TEST_P(SensorsHidlTest, MagnetometerStreamingOperationFast) {
+ testStreamingOperation(SensorType::MAGNETIC_FIELD, std::chrono::milliseconds(5),
+ std::chrono::seconds(5), NullChecker());
}
// Test if sensor hal can do accelerometer sampling rate switch properly when sensor is active
-TEST_F(SensorsHidlTest, AccelerometerSamplingPeriodHotSwitchOperation) {
- testSamplingRateHotSwitchOperation(SensorType::ACCELEROMETER);
- testSamplingRateHotSwitchOperation(SensorType::ACCELEROMETER, false /*fastToSlow*/);
+TEST_P(SensorsHidlTest, AccelerometerSamplingPeriodHotSwitchOperation) {
+ testSamplingRateHotSwitchOperation(SensorType::ACCELEROMETER);
+ testSamplingRateHotSwitchOperation(SensorType::ACCELEROMETER, false /*fastToSlow*/);
}
// Test if sensor hal can do gyroscope sampling rate switch properly when sensor is active
-TEST_F(SensorsHidlTest, GyroscopeSamplingPeriodHotSwitchOperation) {
- testSamplingRateHotSwitchOperation(SensorType::GYROSCOPE);
- testSamplingRateHotSwitchOperation(SensorType::GYROSCOPE, false /*fastToSlow*/);
+TEST_P(SensorsHidlTest, GyroscopeSamplingPeriodHotSwitchOperation) {
+ testSamplingRateHotSwitchOperation(SensorType::GYROSCOPE);
+ testSamplingRateHotSwitchOperation(SensorType::GYROSCOPE, false /*fastToSlow*/);
}
// Test if sensor hal can do magnetometer sampling rate switch properly when sensor is active
-TEST_F(SensorsHidlTest, MagnetometerSamplingPeriodHotSwitchOperation) {
- testSamplingRateHotSwitchOperation(SensorType::MAGNETIC_FIELD);
- testSamplingRateHotSwitchOperation(SensorType::MAGNETIC_FIELD, false /*fastToSlow*/);
+TEST_P(SensorsHidlTest, MagnetometerSamplingPeriodHotSwitchOperation) {
+ testSamplingRateHotSwitchOperation(SensorType::MAGNETIC_FIELD);
+ testSamplingRateHotSwitchOperation(SensorType::MAGNETIC_FIELD, false /*fastToSlow*/);
}
// Test if sensor hal can do accelerometer batching properly
-TEST_F(SensorsHidlTest, AccelerometerBatchingOperation) {
- testBatchingOperation(SensorType::ACCELEROMETER);
+TEST_P(SensorsHidlTest, AccelerometerBatchingOperation) {
+ testBatchingOperation(SensorType::ACCELEROMETER);
}
// Test if sensor hal can do gyroscope batching properly
-TEST_F(SensorsHidlTest, GyroscopeBatchingOperation) {
- testBatchingOperation(SensorType::GYROSCOPE);
+TEST_P(SensorsHidlTest, GyroscopeBatchingOperation) {
+ testBatchingOperation(SensorType::GYROSCOPE);
}
// Test if sensor hal can do magnetometer batching properly
-TEST_F(SensorsHidlTest, MagnetometerBatchingOperation) {
- testBatchingOperation(SensorType::MAGNETIC_FIELD);
+TEST_P(SensorsHidlTest, MagnetometerBatchingOperation) {
+ testBatchingOperation(SensorType::MAGNETIC_FIELD);
}
// Test sensor event direct report with ashmem for accel sensor at normal rate
-TEST_F(SensorsHidlTest, AccelerometerAshmemDirectReportOperationNormal) {
- testDirectReportOperation(SensorType::ACCELEROMETER, SharedMemType::ASHMEM, RateLevel::NORMAL,
- sAccelNormChecker);
+TEST_P(SensorsHidlTest, AccelerometerAshmemDirectReportOperationNormal) {
+ testDirectReportOperation(SensorType::ACCELEROMETER, SharedMemType::ASHMEM, RateLevel::NORMAL,
+ sAccelNormChecker);
}
// Test sensor event direct report with ashmem for accel sensor at fast rate
-TEST_F(SensorsHidlTest, AccelerometerAshmemDirectReportOperationFast) {
- testDirectReportOperation(SensorType::ACCELEROMETER, SharedMemType::ASHMEM, RateLevel::FAST,
- sAccelNormChecker);
+TEST_P(SensorsHidlTest, AccelerometerAshmemDirectReportOperationFast) {
+ testDirectReportOperation(SensorType::ACCELEROMETER, SharedMemType::ASHMEM, RateLevel::FAST,
+ sAccelNormChecker);
}
// Test sensor event direct report with ashmem for accel sensor at very fast rate
-TEST_F(SensorsHidlTest, AccelerometerAshmemDirectReportOperationVeryFast) {
- testDirectReportOperation(SensorType::ACCELEROMETER, SharedMemType::ASHMEM, RateLevel::VERY_FAST,
- sAccelNormChecker);
+TEST_P(SensorsHidlTest, AccelerometerAshmemDirectReportOperationVeryFast) {
+ testDirectReportOperation(SensorType::ACCELEROMETER, SharedMemType::ASHMEM,
+ RateLevel::VERY_FAST, sAccelNormChecker);
}
// Test sensor event direct report with ashmem for gyro sensor at normal rate
-TEST_F(SensorsHidlTest, GyroscopeAshmemDirectReportOperationNormal) {
- testDirectReportOperation(SensorType::GYROSCOPE, SharedMemType::ASHMEM, RateLevel::NORMAL,
- sGyroNormChecker);
+TEST_P(SensorsHidlTest, GyroscopeAshmemDirectReportOperationNormal) {
+ testDirectReportOperation(SensorType::GYROSCOPE, SharedMemType::ASHMEM, RateLevel::NORMAL,
+ sGyroNormChecker);
}
// Test sensor event direct report with ashmem for gyro sensor at fast rate
-TEST_F(SensorsHidlTest, GyroscopeAshmemDirectReportOperationFast) {
- testDirectReportOperation(SensorType::GYROSCOPE, SharedMemType::ASHMEM, RateLevel::FAST,
- sGyroNormChecker);
+TEST_P(SensorsHidlTest, GyroscopeAshmemDirectReportOperationFast) {
+ testDirectReportOperation(SensorType::GYROSCOPE, SharedMemType::ASHMEM, RateLevel::FAST,
+ sGyroNormChecker);
}
// Test sensor event direct report with ashmem for gyro sensor at very fast rate
-TEST_F(SensorsHidlTest, GyroscopeAshmemDirectReportOperationVeryFast) {
- testDirectReportOperation(SensorType::GYROSCOPE, SharedMemType::ASHMEM, RateLevel::VERY_FAST,
- sGyroNormChecker);
+TEST_P(SensorsHidlTest, GyroscopeAshmemDirectReportOperationVeryFast) {
+ testDirectReportOperation(SensorType::GYROSCOPE, SharedMemType::ASHMEM, RateLevel::VERY_FAST,
+ sGyroNormChecker);
}
// Test sensor event direct report with ashmem for mag sensor at normal rate
-TEST_F(SensorsHidlTest, MagnetometerAshmemDirectReportOperationNormal) {
- testDirectReportOperation(SensorType::MAGNETIC_FIELD, SharedMemType::ASHMEM, RateLevel::NORMAL,
- NullChecker());
+TEST_P(SensorsHidlTest, MagnetometerAshmemDirectReportOperationNormal) {
+ testDirectReportOperation(SensorType::MAGNETIC_FIELD, SharedMemType::ASHMEM, RateLevel::NORMAL,
+ NullChecker());
}
// Test sensor event direct report with ashmem for mag sensor at fast rate
-TEST_F(SensorsHidlTest, MagnetometerAshmemDirectReportOperationFast) {
- testDirectReportOperation(SensorType::MAGNETIC_FIELD, SharedMemType::ASHMEM, RateLevel::FAST,
- NullChecker());
+TEST_P(SensorsHidlTest, MagnetometerAshmemDirectReportOperationFast) {
+ testDirectReportOperation(SensorType::MAGNETIC_FIELD, SharedMemType::ASHMEM, RateLevel::FAST,
+ NullChecker());
}
// Test sensor event direct report with ashmem for mag sensor at very fast rate
-TEST_F(SensorsHidlTest, MagnetometerAshmemDirectReportOperationVeryFast) {
- testDirectReportOperation(
- SensorType::MAGNETIC_FIELD, SharedMemType::ASHMEM, RateLevel::VERY_FAST, NullChecker());
+TEST_P(SensorsHidlTest, MagnetometerAshmemDirectReportOperationVeryFast) {
+ testDirectReportOperation(SensorType::MAGNETIC_FIELD, SharedMemType::ASHMEM,
+ RateLevel::VERY_FAST, NullChecker());
}
// Test sensor event direct report with gralloc for accel sensor at normal rate
-TEST_F(SensorsHidlTest, AccelerometerGrallocDirectReportOperationNormal) {
- testDirectReportOperation(SensorType::ACCELEROMETER, SharedMemType::GRALLOC, RateLevel::NORMAL,
- sAccelNormChecker);
+TEST_P(SensorsHidlTest, AccelerometerGrallocDirectReportOperationNormal) {
+ testDirectReportOperation(SensorType::ACCELEROMETER, SharedMemType::GRALLOC, RateLevel::NORMAL,
+ sAccelNormChecker);
}
// Test sensor event direct report with gralloc for accel sensor at fast rate
-TEST_F(SensorsHidlTest, AccelerometerGrallocDirectReportOperationFast) {
- testDirectReportOperation(SensorType::ACCELEROMETER, SharedMemType::GRALLOC, RateLevel::FAST,
- sAccelNormChecker);
+TEST_P(SensorsHidlTest, AccelerometerGrallocDirectReportOperationFast) {
+ testDirectReportOperation(SensorType::ACCELEROMETER, SharedMemType::GRALLOC, RateLevel::FAST,
+ sAccelNormChecker);
}
// Test sensor event direct report with gralloc for accel sensor at very fast rate
-TEST_F(SensorsHidlTest, AccelerometerGrallocDirectReportOperationVeryFast) {
- testDirectReportOperation(SensorType::ACCELEROMETER, SharedMemType::GRALLOC, RateLevel::VERY_FAST,
- sAccelNormChecker);
+TEST_P(SensorsHidlTest, AccelerometerGrallocDirectReportOperationVeryFast) {
+ testDirectReportOperation(SensorType::ACCELEROMETER, SharedMemType::GRALLOC,
+ RateLevel::VERY_FAST, sAccelNormChecker);
}
// Test sensor event direct report with gralloc for gyro sensor at normal rate
-TEST_F(SensorsHidlTest, GyroscopeGrallocDirectReportOperationNormal) {
- testDirectReportOperation(SensorType::GYROSCOPE, SharedMemType::GRALLOC, RateLevel::NORMAL,
- sGyroNormChecker);
+TEST_P(SensorsHidlTest, GyroscopeGrallocDirectReportOperationNormal) {
+ testDirectReportOperation(SensorType::GYROSCOPE, SharedMemType::GRALLOC, RateLevel::NORMAL,
+ sGyroNormChecker);
}
// Test sensor event direct report with gralloc for gyro sensor at fast rate
-TEST_F(SensorsHidlTest, GyroscopeGrallocDirectReportOperationFast) {
- testDirectReportOperation(SensorType::GYROSCOPE, SharedMemType::GRALLOC, RateLevel::FAST,
- sGyroNormChecker);
+TEST_P(SensorsHidlTest, GyroscopeGrallocDirectReportOperationFast) {
+ testDirectReportOperation(SensorType::GYROSCOPE, SharedMemType::GRALLOC, RateLevel::FAST,
+ sGyroNormChecker);
}
// Test sensor event direct report with gralloc for gyro sensor at very fast rate
-TEST_F(SensorsHidlTest, GyroscopeGrallocDirectReportOperationVeryFast) {
- testDirectReportOperation(SensorType::GYROSCOPE, SharedMemType::GRALLOC, RateLevel::VERY_FAST,
- sGyroNormChecker);
+TEST_P(SensorsHidlTest, GyroscopeGrallocDirectReportOperationVeryFast) {
+ testDirectReportOperation(SensorType::GYROSCOPE, SharedMemType::GRALLOC, RateLevel::VERY_FAST,
+ sGyroNormChecker);
}
// Test sensor event direct report with gralloc for mag sensor at normal rate
-TEST_F(SensorsHidlTest, MagnetometerGrallocDirectReportOperationNormal) {
- testDirectReportOperation(SensorType::MAGNETIC_FIELD, SharedMemType::GRALLOC, RateLevel::NORMAL,
- NullChecker());
+TEST_P(SensorsHidlTest, MagnetometerGrallocDirectReportOperationNormal) {
+ testDirectReportOperation(SensorType::MAGNETIC_FIELD, SharedMemType::GRALLOC, RateLevel::NORMAL,
+ NullChecker());
}
// Test sensor event direct report with gralloc for mag sensor at fast rate
-TEST_F(SensorsHidlTest, MagnetometerGrallocDirectReportOperationFast) {
- testDirectReportOperation(SensorType::MAGNETIC_FIELD, SharedMemType::GRALLOC, RateLevel::FAST,
- NullChecker());
+TEST_P(SensorsHidlTest, MagnetometerGrallocDirectReportOperationFast) {
+ testDirectReportOperation(SensorType::MAGNETIC_FIELD, SharedMemType::GRALLOC, RateLevel::FAST,
+ NullChecker());
}
// Test sensor event direct report with gralloc for mag sensor at very fast rate
-TEST_F(SensorsHidlTest, MagnetometerGrallocDirectReportOperationVeryFast) {
- testDirectReportOperation(
- SensorType::MAGNETIC_FIELD, SharedMemType::GRALLOC, RateLevel::VERY_FAST, NullChecker());
+TEST_P(SensorsHidlTest, MagnetometerGrallocDirectReportOperationVeryFast) {
+ testDirectReportOperation(SensorType::MAGNETIC_FIELD, SharedMemType::GRALLOC,
+ RateLevel::VERY_FAST, NullChecker());
}
-int main(int argc, char **argv) {
- ::testing::AddGlobalTestEnvironment(SensorsHidlEnvironmentV1_0::Instance());
- ::testing::InitGoogleTest(&argc, argv);
- SensorsHidlEnvironmentV1_0::Instance()->init(&argc, argv);
- int status = RUN_ALL_TESTS();
- ALOGI("Test result = %d", status);
- return status;
-}
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, SensorsHidlTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(ISensors::descriptor)),
+ android::hardware::PrintInstanceNameToString);
// vim: set ts=2 sw=2
diff --git a/sensors/2.0/multihal/Android.bp b/sensors/2.0/multihal/Android.bp
index c13eaf2..811c455 100644
--- a/sensors/2.0/multihal/Android.bp
+++ b/sensors/2.0/multihal/Android.bp
@@ -43,10 +43,10 @@
srcs: [
"service.cpp",
"HalProxy.cpp",
- "ScopedWakelock.cpp",
],
init_rc: ["android.hardware.sensors@2.0-service-multihal.rc"],
vintf_fragments: ["android.hardware.sensors@2.0-multihal.xml"],
+ shared_libs: ["android.hardware.sensors@2.0-ScopedWakelock"]
}
cc_library_headers {
@@ -55,19 +55,40 @@
export_include_dirs: ["include"],
}
+cc_library_shared {
+ name: "android.hardware.sensors@2.0-ScopedWakelock",
+ defaults: [
+ "hidl_defaults",
+ "android.hardware.sensors@2.0-multihal-defaults",
+ ],
+ srcs: [
+ "ScopedWakelock.cpp",
+ ],
+ vendor_available: true,
+ export_header_lib_headers: [
+ "android.hardware.sensors@2.0-multihal.header"
+ ]
+}
+
// The below targets should only be used for testing.
cc_test_library {
name: "android.hardware.sensors@2.0-HalProxy",
- defaults: ["android.hardware.sensors@2.0-multihal-defaults"],
+ defaults: [
+ "hidl_defaults",
+ "android.hardware.sensors@2.0-multihal-defaults",
+ ],
vendor_available: true,
srcs: [
"HalProxy.cpp",
- "ScopedWakelock.cpp",
],
export_header_lib_headers: [
"android.hardware.sensors@2.0-multihal.header",
],
+ export_shared_lib_headers: [
+ "android.hardware.sensors@2.0-ScopedWakelock",
+ ],
shared_libs: [
"libutils",
+ "android.hardware.sensors@2.0-ScopedWakelock",
],
}
diff --git a/sensors/2.0/multihal/tests/Android.bp b/sensors/2.0/multihal/tests/Android.bp
index e7f9499..1637312 100644
--- a/sensors/2.0/multihal/tests/Android.bp
+++ b/sensors/2.0/multihal/tests/Android.bp
@@ -25,6 +25,7 @@
shared_libs: [
"android.hardware.sensors@1.0",
"android.hardware.sensors@2.0",
+ "android.hardware.sensors@2.0-ScopedWakelock",
"libcutils",
"libfmq",
"libhardware",
@@ -83,6 +84,7 @@
shared_libs: [
"android.hardware.sensors@1.0",
"android.hardware.sensors@2.0",
+ "android.hardware.sensors@2.0-ScopedWakelock",
"libbase",
"libcutils",
"libfmq",
diff --git a/sensors/2.0/vts/functional/AndroidTest.xml b/sensors/2.0/vts/functional/AndroidTest.xml
new file mode 100644
index 0000000..b710ed0
--- /dev/null
+++ b/sensors/2.0/vts/functional/AndroidTest.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 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.
+-->
+<configuration description="Runs VtsHalSensorsV2_0TargetTest.">
+ <option name="test-suite-tag" value="apct" />
+ <option name="test-suite-tag" value="apct-native" />
+
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
+ </target_preparer>
+
+ <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+ <option name="run-command" value="stop"/>
+ <option name="teardown-command" value="start"/>
+ </target_preparer>
+
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="cleanup" value="true" />
+ <option name="push" value="VtsHalSensorsV2_0TargetTest->/data/local/tmp/VtsHalSensorsV2_0TargetTest" />
+ </target_preparer>
+
+ <test class="com.android.tradefed.testtype.GTest" >
+ <option name="native-test-timeout" value="900000" />
+ <option name="runtime-hint" value="300000"/>
+ <option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="module-name" value="VtsHalSensorsV2_0TargetTest" />
+ </test>
+</configuration>
diff --git a/sensors/2.0/vts/functional/SensorsHidlEnvironmentV2_0.cpp b/sensors/2.0/vts/functional/SensorsHidlEnvironmentV2_0.cpp
index dc54f27..81db5a0 100644
--- a/sensors/2.0/vts/functional/SensorsHidlEnvironmentV2_0.cpp
+++ b/sensors/2.0/vts/functional/SensorsHidlEnvironmentV2_0.cpp
@@ -58,8 +58,7 @@
bool SensorsHidlEnvironmentV2_0::resetHal() {
bool succeed = false;
do {
- mSensors = ISensors::getService(
- SensorsHidlEnvironmentV2_0::Instance()->getServiceName<ISensors>());
+ mSensors = ISensors::getService(mServiceName);
if (mSensors == nullptr) {
break;
}
diff --git a/sensors/2.0/vts/functional/SensorsHidlEnvironmentV2_0.h b/sensors/2.0/vts/functional/SensorsHidlEnvironmentV2_0.h
index b0dbd90..819cdd4 100644
--- a/sensors/2.0/vts/functional/SensorsHidlEnvironmentV2_0.h
+++ b/sensors/2.0/vts/functional/SensorsHidlEnvironmentV2_0.h
@@ -42,22 +42,12 @@
class SensorsHidlEnvironmentV2_0 : public SensorsHidlEnvironmentBase {
public:
using Event = ::android::hardware::sensors::V1_0::Event;
- // get the test environment singleton
- static SensorsHidlEnvironmentV2_0* Instance() {
- static SensorsHidlEnvironmentV2_0* instance = new SensorsHidlEnvironmentV2_0();
- return instance;
- }
-
- virtual void registerTestServices() override {
- registerTestService<android::hardware::sensors::V2_0::ISensors>();
- }
-
virtual void HidlTearDown() override;
protected:
friend SensorsHidlTest;
-
- SensorsHidlEnvironmentV2_0() : mEventQueueFlag(nullptr) {}
+ SensorsHidlEnvironmentV2_0(const std::string& service_name)
+ : SensorsHidlEnvironmentBase(service_name), mEventQueueFlag(nullptr) {}
/**
* Resets the HAL with new FMQs and a new Event Flag
diff --git a/sensors/2.0/vts/functional/VtsHalSensorsV2_0TargetTest.cpp b/sensors/2.0/vts/functional/VtsHalSensorsV2_0TargetTest.cpp
index 8364ba9..c5eb442 100644
--- a/sensors/2.0/vts/functional/VtsHalSensorsV2_0TargetTest.cpp
+++ b/sensors/2.0/vts/functional/VtsHalSensorsV2_0TargetTest.cpp
@@ -20,6 +20,8 @@
#include <android/hardware/sensors/2.0/ISensors.h>
#include <android/hardware/sensors/2.0/types.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include <log/log.h>
#include <utils/SystemClock.h>
@@ -120,10 +122,14 @@
class SensorsHidlTest : public SensorsHidlTestBase {
public:
virtual void SetUp() override {
+ mEnvironment = new SensorsHidlEnvironmentV2_0(GetParam());
+ mEnvironment->HidlSetUp();
// Ensure that we have a valid environment before performing tests
ASSERT_NE(getSensors(), nullptr);
}
+ virtual void TearDown() override { mEnvironment->HidlTearDown(); }
+
protected:
SensorInfo defaultSensorByType(SensorType type) override;
std::vector<SensorInfo> getSensorsList();
@@ -160,12 +166,10 @@
}
inline sp<::android::hardware::sensors::V2_0::ISensors>& getSensors() {
- return SensorsHidlEnvironmentV2_0::Instance()->mSensors;
+ return mEnvironment->mSensors;
}
- SensorsHidlEnvironmentBase* getEnvironment() override {
- return SensorsHidlEnvironmentV2_0::Instance();
- }
+ SensorsHidlEnvironmentBase* getEnvironment() override { return mEnvironment; }
// Test helpers
void runSingleFlushTest(const std::vector<SensorInfo>& sensors, bool activateSensor,
@@ -191,6 +195,10 @@
void checkRateLevel(const SensorInfo& sensor, int32_t directChannelHandle, RateLevel rateLevel);
void queryDirectChannelSupport(SharedMemType memType, bool* supportsSharedMemType,
bool* supportsAnyDirectChannel);
+
+ private:
+ // Test environment for sensors HAL.
+ SensorsHidlEnvironmentV2_0* mEnvironment;
};
Return<Result> SensorsHidlTest::activate(int32_t sensorHandle, bool enabled) {
@@ -301,7 +309,7 @@
}
// Test if sensor list returned is valid
-TEST_F(SensorsHidlTest, SensorListValid) {
+TEST_P(SensorsHidlTest, SensorListValid) {
getSensors()->getSensorsList([&](const auto& list) {
const size_t count = list.size();
for (size_t i = 0; i < count; ++i) {
@@ -346,7 +354,7 @@
}
// Test that SetOperationMode returns the expected value
-TEST_F(SensorsHidlTest, SetOperationMode) {
+TEST_P(SensorsHidlTest, SetOperationMode) {
std::vector<SensorInfo> sensors = getInjectEventSensors();
if (getInjectEventSensors().size() > 0) {
ASSERT_EQ(Result::OK, getSensors()->setOperationMode(OperationMode::NORMAL));
@@ -358,7 +366,7 @@
}
// Test that an injected event is written back to the Event FMQ
-TEST_F(SensorsHidlTest, InjectSensorEventData) {
+TEST_P(SensorsHidlTest, InjectSensorEventData) {
std::vector<SensorInfo> sensors = getInjectEventSensors();
if (sensors.size() == 0) {
return;
@@ -414,196 +422,196 @@
}
// Test if sensor hal can do UI speed accelerometer streaming properly
-TEST_F(SensorsHidlTest, AccelerometerStreamingOperationSlow) {
+TEST_P(SensorsHidlTest, AccelerometerStreamingOperationSlow) {
testStreamingOperation(SensorType::ACCELEROMETER, std::chrono::milliseconds(200),
std::chrono::seconds(5), sAccelNormChecker);
}
// Test if sensor hal can do normal speed accelerometer streaming properly
-TEST_F(SensorsHidlTest, AccelerometerStreamingOperationNormal) {
+TEST_P(SensorsHidlTest, AccelerometerStreamingOperationNormal) {
testStreamingOperation(SensorType::ACCELEROMETER, std::chrono::milliseconds(20),
std::chrono::seconds(5), sAccelNormChecker);
}
// Test if sensor hal can do game speed accelerometer streaming properly
-TEST_F(SensorsHidlTest, AccelerometerStreamingOperationFast) {
+TEST_P(SensorsHidlTest, AccelerometerStreamingOperationFast) {
testStreamingOperation(SensorType::ACCELEROMETER, std::chrono::milliseconds(5),
std::chrono::seconds(5), sAccelNormChecker);
}
// Test if sensor hal can do UI speed gyroscope streaming properly
-TEST_F(SensorsHidlTest, GyroscopeStreamingOperationSlow) {
+TEST_P(SensorsHidlTest, GyroscopeStreamingOperationSlow) {
testStreamingOperation(SensorType::GYROSCOPE, std::chrono::milliseconds(200),
std::chrono::seconds(5), sGyroNormChecker);
}
// Test if sensor hal can do normal speed gyroscope streaming properly
-TEST_F(SensorsHidlTest, GyroscopeStreamingOperationNormal) {
+TEST_P(SensorsHidlTest, GyroscopeStreamingOperationNormal) {
testStreamingOperation(SensorType::GYROSCOPE, std::chrono::milliseconds(20),
std::chrono::seconds(5), sGyroNormChecker);
}
// Test if sensor hal can do game speed gyroscope streaming properly
-TEST_F(SensorsHidlTest, GyroscopeStreamingOperationFast) {
+TEST_P(SensorsHidlTest, GyroscopeStreamingOperationFast) {
testStreamingOperation(SensorType::GYROSCOPE, std::chrono::milliseconds(5),
std::chrono::seconds(5), sGyroNormChecker);
}
// Test if sensor hal can do UI speed magnetometer streaming properly
-TEST_F(SensorsHidlTest, MagnetometerStreamingOperationSlow) {
+TEST_P(SensorsHidlTest, MagnetometerStreamingOperationSlow) {
testStreamingOperation(SensorType::MAGNETIC_FIELD, std::chrono::milliseconds(200),
std::chrono::seconds(5), NullChecker());
}
// Test if sensor hal can do normal speed magnetometer streaming properly
-TEST_F(SensorsHidlTest, MagnetometerStreamingOperationNormal) {
+TEST_P(SensorsHidlTest, MagnetometerStreamingOperationNormal) {
testStreamingOperation(SensorType::MAGNETIC_FIELD, std::chrono::milliseconds(20),
std::chrono::seconds(5), NullChecker());
}
// Test if sensor hal can do game speed magnetometer streaming properly
-TEST_F(SensorsHidlTest, MagnetometerStreamingOperationFast) {
+TEST_P(SensorsHidlTest, MagnetometerStreamingOperationFast) {
testStreamingOperation(SensorType::MAGNETIC_FIELD, std::chrono::milliseconds(5),
std::chrono::seconds(5), NullChecker());
}
// Test if sensor hal can do accelerometer sampling rate switch properly when sensor is active
-TEST_F(SensorsHidlTest, AccelerometerSamplingPeriodHotSwitchOperation) {
+TEST_P(SensorsHidlTest, AccelerometerSamplingPeriodHotSwitchOperation) {
testSamplingRateHotSwitchOperation(SensorType::ACCELEROMETER);
testSamplingRateHotSwitchOperation(SensorType::ACCELEROMETER, false /*fastToSlow*/);
}
// Test if sensor hal can do gyroscope sampling rate switch properly when sensor is active
-TEST_F(SensorsHidlTest, GyroscopeSamplingPeriodHotSwitchOperation) {
+TEST_P(SensorsHidlTest, GyroscopeSamplingPeriodHotSwitchOperation) {
testSamplingRateHotSwitchOperation(SensorType::GYROSCOPE);
testSamplingRateHotSwitchOperation(SensorType::GYROSCOPE, false /*fastToSlow*/);
}
// Test if sensor hal can do magnetometer sampling rate switch properly when sensor is active
-TEST_F(SensorsHidlTest, MagnetometerSamplingPeriodHotSwitchOperation) {
+TEST_P(SensorsHidlTest, MagnetometerSamplingPeriodHotSwitchOperation) {
testSamplingRateHotSwitchOperation(SensorType::MAGNETIC_FIELD);
testSamplingRateHotSwitchOperation(SensorType::MAGNETIC_FIELD, false /*fastToSlow*/);
}
// Test if sensor hal can do accelerometer batching properly
-TEST_F(SensorsHidlTest, AccelerometerBatchingOperation) {
+TEST_P(SensorsHidlTest, AccelerometerBatchingOperation) {
testBatchingOperation(SensorType::ACCELEROMETER);
}
// Test if sensor hal can do gyroscope batching properly
-TEST_F(SensorsHidlTest, GyroscopeBatchingOperation) {
+TEST_P(SensorsHidlTest, GyroscopeBatchingOperation) {
testBatchingOperation(SensorType::GYROSCOPE);
}
// Test if sensor hal can do magnetometer batching properly
-TEST_F(SensorsHidlTest, MagnetometerBatchingOperation) {
+TEST_P(SensorsHidlTest, MagnetometerBatchingOperation) {
testBatchingOperation(SensorType::MAGNETIC_FIELD);
}
// Test sensor event direct report with ashmem for accel sensor at normal rate
-TEST_F(SensorsHidlTest, AccelerometerAshmemDirectReportOperationNormal) {
+TEST_P(SensorsHidlTest, AccelerometerAshmemDirectReportOperationNormal) {
testDirectReportOperation(SensorType::ACCELEROMETER, SharedMemType::ASHMEM, RateLevel::NORMAL,
sAccelNormChecker);
}
// Test sensor event direct report with ashmem for accel sensor at fast rate
-TEST_F(SensorsHidlTest, AccelerometerAshmemDirectReportOperationFast) {
+TEST_P(SensorsHidlTest, AccelerometerAshmemDirectReportOperationFast) {
testDirectReportOperation(SensorType::ACCELEROMETER, SharedMemType::ASHMEM, RateLevel::FAST,
sAccelNormChecker);
}
// Test sensor event direct report with ashmem for accel sensor at very fast rate
-TEST_F(SensorsHidlTest, AccelerometerAshmemDirectReportOperationVeryFast) {
+TEST_P(SensorsHidlTest, AccelerometerAshmemDirectReportOperationVeryFast) {
testDirectReportOperation(SensorType::ACCELEROMETER, SharedMemType::ASHMEM,
RateLevel::VERY_FAST, sAccelNormChecker);
}
// Test sensor event direct report with ashmem for gyro sensor at normal rate
-TEST_F(SensorsHidlTest, GyroscopeAshmemDirectReportOperationNormal) {
+TEST_P(SensorsHidlTest, GyroscopeAshmemDirectReportOperationNormal) {
testDirectReportOperation(SensorType::GYROSCOPE, SharedMemType::ASHMEM, RateLevel::NORMAL,
sGyroNormChecker);
}
// Test sensor event direct report with ashmem for gyro sensor at fast rate
-TEST_F(SensorsHidlTest, GyroscopeAshmemDirectReportOperationFast) {
+TEST_P(SensorsHidlTest, GyroscopeAshmemDirectReportOperationFast) {
testDirectReportOperation(SensorType::GYROSCOPE, SharedMemType::ASHMEM, RateLevel::FAST,
sGyroNormChecker);
}
// Test sensor event direct report with ashmem for gyro sensor at very fast rate
-TEST_F(SensorsHidlTest, GyroscopeAshmemDirectReportOperationVeryFast) {
+TEST_P(SensorsHidlTest, GyroscopeAshmemDirectReportOperationVeryFast) {
testDirectReportOperation(SensorType::GYROSCOPE, SharedMemType::ASHMEM, RateLevel::VERY_FAST,
sGyroNormChecker);
}
// Test sensor event direct report with ashmem for mag sensor at normal rate
-TEST_F(SensorsHidlTest, MagnetometerAshmemDirectReportOperationNormal) {
+TEST_P(SensorsHidlTest, MagnetometerAshmemDirectReportOperationNormal) {
testDirectReportOperation(SensorType::MAGNETIC_FIELD, SharedMemType::ASHMEM, RateLevel::NORMAL,
NullChecker());
}
// Test sensor event direct report with ashmem for mag sensor at fast rate
-TEST_F(SensorsHidlTest, MagnetometerAshmemDirectReportOperationFast) {
+TEST_P(SensorsHidlTest, MagnetometerAshmemDirectReportOperationFast) {
testDirectReportOperation(SensorType::MAGNETIC_FIELD, SharedMemType::ASHMEM, RateLevel::FAST,
NullChecker());
}
// Test sensor event direct report with ashmem for mag sensor at very fast rate
-TEST_F(SensorsHidlTest, MagnetometerAshmemDirectReportOperationVeryFast) {
+TEST_P(SensorsHidlTest, MagnetometerAshmemDirectReportOperationVeryFast) {
testDirectReportOperation(SensorType::MAGNETIC_FIELD, SharedMemType::ASHMEM,
RateLevel::VERY_FAST, NullChecker());
}
// Test sensor event direct report with gralloc for accel sensor at normal rate
-TEST_F(SensorsHidlTest, AccelerometerGrallocDirectReportOperationNormal) {
+TEST_P(SensorsHidlTest, AccelerometerGrallocDirectReportOperationNormal) {
testDirectReportOperation(SensorType::ACCELEROMETER, SharedMemType::GRALLOC, RateLevel::NORMAL,
sAccelNormChecker);
}
// Test sensor event direct report with gralloc for accel sensor at fast rate
-TEST_F(SensorsHidlTest, AccelerometerGrallocDirectReportOperationFast) {
+TEST_P(SensorsHidlTest, AccelerometerGrallocDirectReportOperationFast) {
testDirectReportOperation(SensorType::ACCELEROMETER, SharedMemType::GRALLOC, RateLevel::FAST,
sAccelNormChecker);
}
// Test sensor event direct report with gralloc for accel sensor at very fast rate
-TEST_F(SensorsHidlTest, AccelerometerGrallocDirectReportOperationVeryFast) {
+TEST_P(SensorsHidlTest, AccelerometerGrallocDirectReportOperationVeryFast) {
testDirectReportOperation(SensorType::ACCELEROMETER, SharedMemType::GRALLOC,
RateLevel::VERY_FAST, sAccelNormChecker);
}
// Test sensor event direct report with gralloc for gyro sensor at normal rate
-TEST_F(SensorsHidlTest, GyroscopeGrallocDirectReportOperationNormal) {
+TEST_P(SensorsHidlTest, GyroscopeGrallocDirectReportOperationNormal) {
testDirectReportOperation(SensorType::GYROSCOPE, SharedMemType::GRALLOC, RateLevel::NORMAL,
sGyroNormChecker);
}
// Test sensor event direct report with gralloc for gyro sensor at fast rate
-TEST_F(SensorsHidlTest, GyroscopeGrallocDirectReportOperationFast) {
+TEST_P(SensorsHidlTest, GyroscopeGrallocDirectReportOperationFast) {
testDirectReportOperation(SensorType::GYROSCOPE, SharedMemType::GRALLOC, RateLevel::FAST,
sGyroNormChecker);
}
// Test sensor event direct report with gralloc for gyro sensor at very fast rate
-TEST_F(SensorsHidlTest, GyroscopeGrallocDirectReportOperationVeryFast) {
+TEST_P(SensorsHidlTest, GyroscopeGrallocDirectReportOperationVeryFast) {
testDirectReportOperation(SensorType::GYROSCOPE, SharedMemType::GRALLOC, RateLevel::VERY_FAST,
sGyroNormChecker);
}
// Test sensor event direct report with gralloc for mag sensor at normal rate
-TEST_F(SensorsHidlTest, MagnetometerGrallocDirectReportOperationNormal) {
+TEST_P(SensorsHidlTest, MagnetometerGrallocDirectReportOperationNormal) {
testDirectReportOperation(SensorType::MAGNETIC_FIELD, SharedMemType::GRALLOC, RateLevel::NORMAL,
NullChecker());
}
// Test sensor event direct report with gralloc for mag sensor at fast rate
-TEST_F(SensorsHidlTest, MagnetometerGrallocDirectReportOperationFast) {
+TEST_P(SensorsHidlTest, MagnetometerGrallocDirectReportOperationFast) {
testDirectReportOperation(SensorType::MAGNETIC_FIELD, SharedMemType::GRALLOC, RateLevel::FAST,
NullChecker());
}
// Test sensor event direct report with gralloc for mag sensor at very fast rate
-TEST_F(SensorsHidlTest, MagnetometerGrallocDirectReportOperationVeryFast) {
+TEST_P(SensorsHidlTest, MagnetometerGrallocDirectReportOperationVeryFast) {
testDirectReportOperation(SensorType::MAGNETIC_FIELD, SharedMemType::GRALLOC,
RateLevel::VERY_FAST, NullChecker());
}
@@ -619,9 +627,13 @@
// Test that if initialize is called twice, then the HAL writes events to the FMQs from the second
// call to the function.
-TEST_F(SensorsHidlTest, CallInitializeTwice) {
+TEST_P(SensorsHidlTest, CallInitializeTwice) {
// Create a helper class so that a second environment is able to be instantiated
- class SensorsHidlEnvironmentTest : public SensorsHidlEnvironmentV2_0 {};
+ class SensorsHidlEnvironmentTest : public SensorsHidlEnvironmentV2_0 {
+ public:
+ SensorsHidlEnvironmentTest(const std::string& service_name)
+ : SensorsHidlEnvironmentV2_0(service_name) {}
+ };
if (getSensorsList().size() == 0) {
// No sensors
@@ -633,7 +645,7 @@
// Create a new environment that calls initialize()
std::unique_ptr<SensorsHidlEnvironmentTest> newEnv =
- std::make_unique<SensorsHidlEnvironmentTest>();
+ std::make_unique<SensorsHidlEnvironmentTest>(GetParam());
newEnv->HidlSetUp();
if (HasFatalFailure()) {
return; // Exit early if setting up the new environment failed
@@ -662,7 +674,7 @@
activateAllSensors(false);
}
-TEST_F(SensorsHidlTest, CleanupConnectionsOnInitialize) {
+TEST_P(SensorsHidlTest, CleanupConnectionsOnInitialize) {
activateAllSensors(true);
// Verify that events are received
@@ -731,7 +743,7 @@
}
}
-TEST_F(SensorsHidlTest, FlushSensor) {
+TEST_P(SensorsHidlTest, FlushSensor) {
// Find a sensor that is not a one-shot sensor
std::vector<SensorInfo> sensors = getNonOneShotSensors();
if (sensors.size() == 0) {
@@ -743,7 +755,7 @@
runFlushTest(sensors, true /* activateSensor */, kFlushes, kFlushes, Result::OK);
}
-TEST_F(SensorsHidlTest, FlushOneShotSensor) {
+TEST_P(SensorsHidlTest, FlushOneShotSensor) {
// Find a sensor that is a one-shot sensor
std::vector<SensorInfo> sensors = getOneShotSensors();
if (sensors.size() == 0) {
@@ -754,7 +766,7 @@
Result::BAD_VALUE);
}
-TEST_F(SensorsHidlTest, FlushInactiveSensor) {
+TEST_P(SensorsHidlTest, FlushInactiveSensor) {
// Attempt to find a non-one shot sensor, then a one-shot sensor if necessary
std::vector<SensorInfo> sensors = getNonOneShotSensors();
if (sensors.size() == 0) {
@@ -768,7 +780,7 @@
Result::BAD_VALUE);
}
-TEST_F(SensorsHidlTest, FlushNonexistentSensor) {
+TEST_P(SensorsHidlTest, FlushNonexistentSensor) {
SensorInfo sensor;
std::vector<SensorInfo> sensors = getNonOneShotSensors();
if (sensors.size() == 0) {
@@ -783,7 +795,7 @@
0 /* expectedFlushCount */, Result::BAD_VALUE);
}
-TEST_F(SensorsHidlTest, Batch) {
+TEST_P(SensorsHidlTest, Batch) {
if (getSensorsList().size() == 0) {
return;
}
@@ -815,7 +827,7 @@
Result::BAD_VALUE);
}
-TEST_F(SensorsHidlTest, Activate) {
+TEST_P(SensorsHidlTest, Activate) {
if (getSensorsList().size() == 0) {
return;
}
@@ -841,7 +853,7 @@
ASSERT_EQ(activate(invalidHandle, false), Result::BAD_VALUE);
}
-TEST_F(SensorsHidlTest, NoStaleEvents) {
+TEST_P(SensorsHidlTest, NoStaleEvents) {
constexpr milliseconds kFiveHundredMs(500);
constexpr milliseconds kOneSecond(1000);
@@ -1021,11 +1033,11 @@
}
}
-TEST_F(SensorsHidlTest, DirectChannelAshmem) {
+TEST_P(SensorsHidlTest, DirectChannelAshmem) {
verifyDirectChannel(SharedMemType::ASHMEM);
}
-TEST_F(SensorsHidlTest, DirectChannelGralloc) {
+TEST_P(SensorsHidlTest, DirectChannelGralloc) {
verifyDirectChannel(SharedMemType::GRALLOC);
}
@@ -1064,7 +1076,7 @@
return found;
}
-TEST_F(SensorsHidlTest, ConfigureDirectChannelWithInvalidHandle) {
+TEST_P(SensorsHidlTest, ConfigureDirectChannelWithInvalidHandle) {
SensorInfo sensor;
SharedMemType memType;
RateLevel rate;
@@ -1078,7 +1090,7 @@
});
}
-TEST_F(SensorsHidlTest, CleanupDirectConnectionOnInitialize) {
+TEST_P(SensorsHidlTest, CleanupDirectConnectionOnInitialize) {
constexpr size_t kNumEvents = 1;
constexpr size_t kMemSize = kNumEvents * kEventSize;
@@ -1124,12 +1136,8 @@
mDirectChannelHandles = handles;
}
-int main(int argc, char** argv) {
- ::testing::AddGlobalTestEnvironment(SensorsHidlEnvironmentV2_0::Instance());
- ::testing::InitGoogleTest(&argc, argv);
- SensorsHidlEnvironmentV2_0::Instance()->init(&argc, argv);
- int status = RUN_ALL_TESTS();
- ALOGI("Test result = %d", status);
- return status;
-}
+INSTANTIATE_TEST_SUITE_P(PerInstance, SensorsHidlTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(
+ android::hardware::sensors::V2_0::ISensors::descriptor)),
+ android::hardware::PrintInstanceNameToString);
// vim: set ts=2 sw=2
diff --git a/sensors/common/vts/utils/Android.bp b/sensors/common/vts/utils/Android.bp
index 02dc608..bb4d329 100644
--- a/sensors/common/vts/utils/Android.bp
+++ b/sensors/common/vts/utils/Android.bp
@@ -16,6 +16,7 @@
cc_library_static {
name: "VtsHalSensorsTargetTestUtils",
+ defaults: ["VtsHalTargetTestDefaults"],
cflags: ["-DLOG_TAG=\"sensors_hidl_hal_test\""],
srcs: [
"GrallocWrapper.cpp",
@@ -36,6 +37,5 @@
"android.hardware.graphics.mapper@2.1",
"android.hardware.graphics.mapper@3.0",
"android.hardware.sensors@1.0",
- "VtsHalHidlTargetTestBase",
],
}
diff --git a/sensors/common/vts/utils/include/sensors-vts-utils/SensorsHidlEnvironmentBase.h b/sensors/common/vts/utils/include/sensors-vts-utils/SensorsHidlEnvironmentBase.h
index 6499fba..dbc9392 100644
--- a/sensors/common/vts/utils/include/sensors-vts-utils/SensorsHidlEnvironmentBase.h
+++ b/sensors/common/vts/utils/include/sensors-vts-utils/SensorsHidlEnvironmentBase.h
@@ -17,9 +17,8 @@
#ifndef ANDROID_SENSORS_HIDL_ENVIRONMENT_BASE_H
#define ANDROID_SENSORS_HIDL_ENVIRONMENT_BASE_H
-#include <VtsHalHidlTargetTestEnvBase.h>
-
#include <android/hardware/sensors/1.0/types.h>
+#include <gtest/gtest.h>
#include <atomic>
#include <memory>
@@ -33,11 +32,11 @@
virtual void onEvent(const ::android::hardware::sensors::V1_0::Event& event) = 0;
};
-class SensorsHidlEnvironmentBase : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
+class SensorsHidlEnvironmentBase {
+ public:
using Event = ::android::hardware::sensors::V1_0::Event;
- virtual void HidlSetUp() override;
- virtual void HidlTearDown() override;
+ virtual void HidlSetUp();
+ virtual void HidlTearDown();
// Get and clear all events collected so far (like "cat" shell command).
// If output is nullptr, it clears all collected events.
@@ -50,22 +49,27 @@
void unregisterCallback();
protected:
- SensorsHidlEnvironmentBase() : mCollectionEnabled(false), mCallback(nullptr) {}
+ SensorsHidlEnvironmentBase(const std::string& service_name)
+ : mCollectionEnabled(false), mCallback(nullptr) {
+ mServiceName = service_name;
+ }
+ virtual ~SensorsHidlEnvironmentBase(){};
- void addEvent(const Event& ev);
+ void addEvent(const Event& ev);
- virtual void startPollingThread() = 0;
- virtual bool resetHal() = 0;
+ virtual void startPollingThread() = 0;
+ virtual bool resetHal() = 0;
- bool mCollectionEnabled;
- std::atomic_bool mStopThread;
- std::thread mPollThread;
- std::vector<Event> mEvents;
- std::mutex mEventsMutex;
+ std::string mServiceName;
+ bool mCollectionEnabled;
+ std::atomic_bool mStopThread;
+ std::thread mPollThread;
+ std::vector<Event> mEvents;
+ std::mutex mEventsMutex;
- IEventCallback* mCallback;
+ IEventCallback* mCallback;
- GTEST_DISALLOW_COPY_AND_ASSIGN_(SensorsHidlEnvironmentBase);
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(SensorsHidlEnvironmentBase);
};
#endif // ANDROID_SENSORS_HIDL_ENVIRONMENT_BASE_H
\ No newline at end of file
diff --git a/sensors/common/vts/utils/include/sensors-vts-utils/SensorsHidlTestBase.h b/sensors/common/vts/utils/include/sensors-vts-utils/SensorsHidlTestBase.h
index 6fd9a2b..5fb6c5c 100644
--- a/sensors/common/vts/utils/include/sensors-vts-utils/SensorsHidlTestBase.h
+++ b/sensors/common/vts/utils/include/sensors-vts-utils/SensorsHidlTestBase.h
@@ -23,6 +23,7 @@
#include <VtsHalHidlTargetTestBase.h>
#include <android/hardware/sensors/1.0/ISensors.h>
#include <android/hardware/sensors/1.0/types.h>
+#include <gtest/gtest.h>
#include <unordered_set>
#include <vector>
@@ -44,8 +45,8 @@
using ::android::hardware::sensors::V1_0::SharedMemInfo;
using ::android::hardware::sensors::V1_0::SharedMemType;
-class SensorsHidlTestBase : public ::testing::VtsHalHidlTargetTestBase {
- public:
+class SensorsHidlTestBase : public testing::TestWithParam<std::string> {
+ public:
virtual SensorsHidlEnvironmentBase* getEnvironment() = 0;
virtual void SetUp() override {}
diff --git a/soundtrigger/2.1/Android.bp b/soundtrigger/2.1/Android.bp
index 68e425b..30173cb 100644
--- a/soundtrigger/2.1/Android.bp
+++ b/soundtrigger/2.1/Android.bp
@@ -15,5 +15,5 @@
"android.hardware.soundtrigger@2.0",
"android.hidl.base@1.0",
],
- gen_java: false,
+ gen_java: true,
}
diff --git a/soundtrigger/2.2/Android.bp b/soundtrigger/2.2/Android.bp
index 43898c7..7556aa4 100644
--- a/soundtrigger/2.2/Android.bp
+++ b/soundtrigger/2.2/Android.bp
@@ -15,5 +15,5 @@
"android.hardware.soundtrigger@2.1",
"android.hidl.base@1.0",
],
- gen_java: false,
+ gen_java: true,
}
diff --git a/soundtrigger/2.3/Android.bp b/soundtrigger/2.3/Android.bp
new file mode 100644
index 0000000..3253a86
--- /dev/null
+++ b/soundtrigger/2.3/Android.bp
@@ -0,0 +1,22 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+hidl_interface {
+ name: "android.hardware.soundtrigger@2.3",
+ root: "android.hardware",
+ vndk: {
+ enabled: true,
+ },
+ srcs: [
+ "types.hal",
+ "ISoundTriggerHw.hal",
+ ],
+ interfaces: [
+ "android.hardware.audio.common@2.0",
+ "android.hardware.soundtrigger@2.0",
+ "android.hardware.soundtrigger@2.1",
+ "android.hardware.soundtrigger@2.2",
+ "android.hidl.base@1.0",
+ "android.hidl.safe_union@1.0",
+ ],
+ gen_java: true,
+}
diff --git a/soundtrigger/2.3/ISoundTriggerHw.hal b/soundtrigger/2.3/ISoundTriggerHw.hal
new file mode 100644
index 0000000..207b9b7
--- /dev/null
+++ b/soundtrigger/2.3/ISoundTriggerHw.hal
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2019 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.soundtrigger@2.3;
+
+import @2.0::SoundModelHandle;
+import @2.2::ISoundTriggerHw;
+
+/**
+ * SoundTrigger HAL interface. Used for hardware recognition of hotwords
+ * and other sounds.
+ */
+interface ISoundTriggerHw extends @2.2::ISoundTriggerHw {
+
+ /**
+ * Set a model specific parameter with the given value. This parameter
+ * will keep its value for the duration the model is loaded regardless of starting and stopping
+ * recognition. Once the model is unloaded, the value will be lost.
+ * It is expected to check if the handle supports the parameter via the queryParameter
+ * API prior to calling this method.
+ *
+ * @param modelHandle The sound model handle indicating which model to modify parameters
+ * @param modelParam Parameter to set which will be validated against the
+ * ModelParameter type. Not putting ModelParameter type
+ * directly in the definition and validating internally
+ * allows for forward compatibility.
+ * @param value The value to set for the given model parameter
+ * @return status Operation completion status: 0 in case of success,
+ * -ENODEV if the native service cannot be reached
+ * -EINVAL invalid input parameter
+ */
+ setParameter(SoundModelHandle modelHandle, ModelParameter modelParam, int32_t value)
+ generates (int32_t status);
+
+ /**
+ * Get a model specific parameter. This parameter will keep its value
+ * for the duration the model is loaded regardless of starting and stopping recognition.
+ * Once the model is unloaded, the value will be lost. If the value is not set, a default
+ * value is returned. See ModelParameter for parameter default values.
+ * It is expected to check if the handle supports the parameter via the queryParameter
+ * API prior to calling this method.
+ *
+ * @param modelHandle The sound model associated with given modelParam
+ * @param modelParam Parameter to set which will be validated against the
+ * ModelParameter type. Not putting ModelParameter type
+ * directly in the definition and validating internally
+ * allows for forward compatibility.
+ * @return status Operation completion status: 0 in case of success,
+ * -ENODEV if the native service cannot be reached
+ * -EINVAL invalid input parameter
+ * @return value Value set to the requested parameter. Value is only set when status
+ * indicates success.
+ */
+ getParameter(SoundModelHandle modelHandle, ModelParameter modelParam)
+ generates (int32_t status, int32_t value);
+
+ /**
+ * Get supported parameter attributes with respect to the provided model
+ * handle. Along with determining the valid range, this API is also used
+ * to determine if a given parameter ID is supported at all by the
+ * modelHandle for use with getParameter and setParameter APIs.
+ *
+ * @param modelHandle The sound model handle indicating which model to query
+ * @param modelParam Parameter to set which will be validated against the
+ * ModelParameter type
+ * @return status Operation completion status: 0 in case of success
+ * -ENODEV if the native service cannot be reached
+ * -EINVAL invalid input parameter
+ * @return retval ModelParameter structure indicating supported attributes
+ * of the parameter for the given model handle
+ */
+ queryParameter(SoundModelHandle modelHandle, ModelParameter modelParam)
+ generates (int32_t status, OptionalModelParameterRange retval);
+};
diff --git a/soundtrigger/2.3/default/Android.bp b/soundtrigger/2.3/default/Android.bp
new file mode 100644
index 0000000..be2c8b0
--- /dev/null
+++ b/soundtrigger/2.3/default/Android.bp
@@ -0,0 +1,37 @@
+//
+// Copyright (C) 2019 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.
+
+cc_library_shared {
+ name: "android.hardware.soundtrigger@2.3-impl",
+ relative_install_path: "hw",
+ vendor: true,
+ srcs: [
+ "SoundTriggerHw.cpp",
+ ],
+ shared_libs: [
+ "libhidlbase",
+ "liblog",
+ "libhidlmemory",
+ "libutils",
+ "libhardware",
+ "android.hardware.soundtrigger@2.0",
+ "android.hardware.soundtrigger@2.0-core",
+ "android.hardware.soundtrigger@2.1",
+ "android.hardware.soundtrigger@2.2",
+ "android.hardware.soundtrigger@2.3",
+ "android.hidl.allocator@1.0",
+ "android.hidl.memory@1.0",
+ ],
+}
diff --git a/soundtrigger/2.3/default/SoundTriggerHw.cpp b/soundtrigger/2.3/default/SoundTriggerHw.cpp
new file mode 100644
index 0000000..4a39ab5
--- /dev/null
+++ b/soundtrigger/2.3/default/SoundTriggerHw.cpp
@@ -0,0 +1,804 @@
+/*
+ * Copyright (C) 2019 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 "SoundTriggerHw"
+
+#include "SoundTriggerHw.h"
+
+#include <android/hidl/allocator/1.0/IAllocator.h>
+#include <android/log.h>
+#include <hidlmemory/mapping.h>
+#include <utility>
+
+using android::hardware::hidl_memory;
+using android::hidl::allocator::V1_0::IAllocator;
+using android::hidl::memory::V1_0::IMemory;
+
+namespace android {
+namespace hardware {
+namespace soundtrigger {
+namespace V2_3 {
+namespace implementation {
+
+/**
+ * According to the HIDL C++ Users Guide: client and server implementations
+ * should never directly refer to anything other than the interface header
+ * generated from the HIDL definition file (ie. ISoundTriggerHw.hal), so
+ * this V2_3 implementation copies the previous implementations and
+ * then adds the new implementation.
+ */
+
+// Begin V2_0 implementation, copied from
+// hardware/interfaces/soundtrigger/2.0/default/SoundTriggerHalImpl.cpp
+
+// static
+void soundModelCallback_(struct sound_trigger_model_event* halEvent, void* cookie) {
+ if (halEvent == NULL) {
+ ALOGW("soundModelCallback called with NULL event");
+ return;
+ }
+ sp<SoundTriggerHw::SoundModelClient> client =
+ wp<SoundTriggerHw::SoundModelClient>(
+ static_cast<SoundTriggerHw::SoundModelClient*>(cookie))
+ .promote();
+ if (client == 0) {
+ ALOGW("soundModelCallback called on stale client");
+ return;
+ }
+ if (halEvent->model != client->getHalHandle()) {
+ ALOGW("soundModelCallback call with wrong handle %d on client with handle %d",
+ (int)halEvent->model, (int)client->getHalHandle());
+ return;
+ }
+
+ client->soundModelCallback(halEvent);
+}
+
+// static
+void recognitionCallback_(struct sound_trigger_recognition_event* halEvent, void* cookie) {
+ if (halEvent == NULL) {
+ ALOGW("recognitionCallback call NULL event");
+ return;
+ }
+ sp<SoundTriggerHw::SoundModelClient> client =
+ wp<SoundTriggerHw::SoundModelClient>(
+ static_cast<SoundTriggerHw::SoundModelClient*>(cookie))
+ .promote();
+ if (client == 0) {
+ ALOGW("recognitionCallback called on stale client");
+ return;
+ }
+
+ client->recognitionCallback(halEvent);
+}
+
+Return<void> SoundTriggerHw::getProperties(ISoundTriggerHw::getProperties_cb _hidl_cb) {
+ ALOGV("getProperties() mHwDevice %p", mHwDevice);
+ int ret;
+ struct sound_trigger_properties halProperties;
+ ISoundTriggerHw::Properties properties;
+
+ if (mHwDevice == NULL) {
+ ret = -ENODEV;
+ goto exit;
+ }
+
+ ret = mHwDevice->get_properties(mHwDevice, &halProperties);
+
+ convertPropertiesFromHal(&properties, &halProperties);
+
+ ALOGV("getProperties implementor %s recognitionModes %08x", properties.implementor.c_str(),
+ properties.recognitionModes);
+
+exit:
+ _hidl_cb(ret, properties);
+ return Void();
+}
+
+int SoundTriggerHw::doLoadSoundModel(const V2_0::ISoundTriggerHw::SoundModel& soundModel,
+ sp<SoundTriggerHw::SoundModelClient> client) {
+ int32_t ret = 0;
+ struct sound_trigger_sound_model* halSoundModel;
+
+ ALOGV("doLoadSoundModel() data size %zu", soundModel.data.size());
+
+ if (mHwDevice == NULL) {
+ ret = -ENODEV;
+ goto exit;
+ }
+
+ halSoundModel = convertSoundModelToHal(&soundModel);
+ if (halSoundModel == NULL) {
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ sound_model_handle_t halHandle;
+ ret = mHwDevice->load_sound_model(mHwDevice, halSoundModel, soundModelCallback_, client.get(),
+ &halHandle);
+
+ free(halSoundModel);
+
+ if (ret != 0) {
+ goto exit;
+ }
+
+ client->setHalHandle(halHandle);
+ {
+ AutoMutex lock(mLock);
+ mClients.add(client->getId(), client);
+ }
+
+exit:
+ return ret;
+}
+
+Return<void> SoundTriggerHw::loadSoundModel(const V2_0::ISoundTriggerHw::SoundModel& soundModel,
+ const sp<V2_0::ISoundTriggerHwCallback>& callback,
+ V2_0::ISoundTriggerHwCallback::CallbackCookie cookie,
+ ISoundTriggerHw::loadSoundModel_cb _hidl_cb) {
+ sp<SoundTriggerHw::SoundModelClient> client =
+ new SoundModelClient_2_0(nextUniqueModelId(), cookie, callback);
+ _hidl_cb(doLoadSoundModel(soundModel, client), client->getId());
+ return Void();
+}
+
+Return<void> SoundTriggerHw::loadPhraseSoundModel(
+ const V2_0::ISoundTriggerHw::PhraseSoundModel& soundModel,
+ const sp<V2_0::ISoundTriggerHwCallback>& callback,
+ V2_0::ISoundTriggerHwCallback::CallbackCookie cookie,
+ ISoundTriggerHw::loadPhraseSoundModel_cb _hidl_cb) {
+ sp<SoundTriggerHw::SoundModelClient> client =
+ new SoundModelClient_2_0(nextUniqueModelId(), cookie, callback);
+ _hidl_cb(doLoadSoundModel((const V2_0::ISoundTriggerHw::SoundModel&)soundModel, client),
+ client->getId());
+ return Void();
+}
+
+Return<int32_t> SoundTriggerHw::unloadSoundModel(int32_t modelHandle) {
+ int32_t ret;
+ sp<SoundTriggerHw::SoundModelClient> client;
+
+ if (mHwDevice == NULL) {
+ ret = -ENODEV;
+ goto exit;
+ }
+
+ {
+ AutoMutex lock(mLock);
+ client = mClients.valueFor(modelHandle);
+ if (client == 0) {
+ ret = -ENOSYS;
+ goto exit;
+ }
+ }
+
+ ret = mHwDevice->unload_sound_model(mHwDevice, client->getHalHandle());
+
+ mClients.removeItem(modelHandle);
+
+exit:
+ return ret;
+}
+
+Return<int32_t> SoundTriggerHw::startRecognition(
+ int32_t modelHandle, const V2_0::ISoundTriggerHw::RecognitionConfig& config,
+ const sp<V2_0::ISoundTriggerHwCallback>& /* callback */, int32_t /* cookie */) {
+ int32_t ret;
+ sp<SoundTriggerHw::SoundModelClient> client;
+ struct sound_trigger_recognition_config* halConfig;
+
+ if (mHwDevice == NULL) {
+ ret = -ENODEV;
+ goto exit;
+ }
+
+ {
+ AutoMutex lock(mLock);
+ client = mClients.valueFor(modelHandle);
+ if (client == 0) {
+ ret = -ENOSYS;
+ goto exit;
+ }
+ }
+
+ halConfig =
+ convertRecognitionConfigToHal((const V2_0::ISoundTriggerHw::RecognitionConfig*)&config);
+
+ if (halConfig == NULL) {
+ ret = -EINVAL;
+ goto exit;
+ }
+ ret = mHwDevice->start_recognition(mHwDevice, client->getHalHandle(), halConfig,
+ recognitionCallback_, client.get());
+
+ free(halConfig);
+
+exit:
+ return ret;
+}
+
+Return<int32_t> SoundTriggerHw::stopRecognition(int32_t modelHandle) {
+ int32_t ret;
+ sp<SoundTriggerHw::SoundModelClient> client;
+ if (mHwDevice == NULL) {
+ ret = -ENODEV;
+ goto exit;
+ }
+
+ {
+ AutoMutex lock(mLock);
+ client = mClients.valueFor(modelHandle);
+ if (client == 0) {
+ ret = -ENOSYS;
+ goto exit;
+ }
+ }
+
+ ret = mHwDevice->stop_recognition(mHwDevice, client->getHalHandle());
+
+exit:
+ return ret;
+}
+
+Return<int32_t> SoundTriggerHw::stopAllRecognitions() {
+ int32_t ret;
+ if (mHwDevice == NULL) {
+ ret = -ENODEV;
+ goto exit;
+ }
+
+ ret = mHwDevice->stop_all_recognitions(mHwDevice);
+
+exit:
+ return ret;
+}
+
+SoundTriggerHw::SoundTriggerHw() : mModuleName("primary"), mHwDevice(NULL), mNextModelId(1) {}
+
+void SoundTriggerHw::onFirstRef() {
+ const hw_module_t* mod;
+ int rc;
+
+ rc = hw_get_module_by_class(SOUND_TRIGGER_HARDWARE_MODULE_ID, mModuleName, &mod);
+ if (rc != 0) {
+ ALOGE("couldn't load sound trigger module %s.%s (%s)", SOUND_TRIGGER_HARDWARE_MODULE_ID,
+ mModuleName, strerror(-rc));
+ return;
+ }
+ rc = sound_trigger_hw_device_open(mod, &mHwDevice);
+ if (rc != 0) {
+ ALOGE("couldn't open sound trigger hw device in %s.%s (%s)",
+ SOUND_TRIGGER_HARDWARE_MODULE_ID, mModuleName, strerror(-rc));
+ mHwDevice = NULL;
+ return;
+ }
+ if (mHwDevice->common.version != SOUND_TRIGGER_DEVICE_API_VERSION_1_3) {
+ ALOGE("wrong sound trigger hw device version %04x", mHwDevice->common.version);
+ sound_trigger_hw_device_close(mHwDevice);
+ mHwDevice = NULL;
+ return;
+ }
+
+ ALOGI("onFirstRef() mModuleName %s mHwDevice %p", mModuleName, mHwDevice);
+}
+
+SoundTriggerHw::~SoundTriggerHw() {
+ if (mHwDevice != NULL) {
+ sound_trigger_hw_device_close(mHwDevice);
+ }
+}
+
+uint32_t SoundTriggerHw::nextUniqueModelId() {
+ uint32_t modelId = 0;
+ {
+ AutoMutex lock(mLock);
+ do {
+ modelId = atomic_fetch_add_explicit(&mNextModelId, (uint_fast32_t)1,
+ memory_order_acq_rel);
+ } while (mClients.valueFor(modelId) != 0 && modelId != 0);
+ }
+ LOG_ALWAYS_FATAL_IF(modelId == 0, "wrap around in sound model IDs, num loaded models %zu",
+ mClients.size());
+ return modelId;
+}
+
+void SoundTriggerHw::convertUuidFromHal(Uuid* uuid, const sound_trigger_uuid_t* halUuid) {
+ uuid->timeLow = halUuid->timeLow;
+ uuid->timeMid = halUuid->timeMid;
+ uuid->versionAndTimeHigh = halUuid->timeHiAndVersion;
+ uuid->variantAndClockSeqHigh = halUuid->clockSeq;
+ memcpy(&uuid->node[0], &halUuid->node[0], 6);
+}
+
+void SoundTriggerHw::convertUuidToHal(sound_trigger_uuid_t* halUuid, const Uuid* uuid) {
+ halUuid->timeLow = uuid->timeLow;
+ halUuid->timeMid = uuid->timeMid;
+ halUuid->timeHiAndVersion = uuid->versionAndTimeHigh;
+ halUuid->clockSeq = uuid->variantAndClockSeqHigh;
+ memcpy(&halUuid->node[0], &uuid->node[0], 6);
+}
+
+void SoundTriggerHw::convertPropertiesFromHal(
+ ISoundTriggerHw::Properties* properties,
+ const struct sound_trigger_properties* halProperties) {
+ properties->implementor = halProperties->implementor;
+ properties->description = halProperties->description;
+ properties->version = halProperties->version;
+ convertUuidFromHal(&properties->uuid, &halProperties->uuid);
+ properties->maxSoundModels = halProperties->max_sound_models;
+ properties->maxKeyPhrases = halProperties->max_key_phrases;
+ properties->maxUsers = halProperties->max_users;
+ properties->recognitionModes = halProperties->recognition_modes;
+ properties->captureTransition = halProperties->capture_transition;
+ properties->maxBufferMs = halProperties->max_buffer_ms;
+ properties->concurrentCapture = halProperties->concurrent_capture;
+ properties->triggerInEvent = halProperties->trigger_in_event;
+ properties->powerConsumptionMw = halProperties->power_consumption_mw;
+}
+
+void SoundTriggerHw::convertTriggerPhraseToHal(struct sound_trigger_phrase* halTriggerPhrase,
+ const ISoundTriggerHw::Phrase* triggerPhrase) {
+ halTriggerPhrase->id = triggerPhrase->id;
+ halTriggerPhrase->recognition_mode = triggerPhrase->recognitionModes;
+ unsigned int i;
+
+ halTriggerPhrase->num_users =
+ std::min((int)triggerPhrase->users.size(), SOUND_TRIGGER_MAX_USERS);
+ for (i = 0; i < halTriggerPhrase->num_users; i++) {
+ halTriggerPhrase->users[i] = triggerPhrase->users[i];
+ }
+
+ strlcpy(halTriggerPhrase->locale, triggerPhrase->locale.c_str(), SOUND_TRIGGER_MAX_LOCALE_LEN);
+ strlcpy(halTriggerPhrase->text, triggerPhrase->text.c_str(), SOUND_TRIGGER_MAX_STRING_LEN);
+}
+
+struct sound_trigger_sound_model* SoundTriggerHw::convertSoundModelToHal(
+ const V2_0::ISoundTriggerHw::SoundModel* soundModel) {
+ struct sound_trigger_sound_model* halModel = NULL;
+ if (soundModel->type == V2_0::SoundModelType::KEYPHRASE) {
+ size_t allocSize =
+ sizeof(struct sound_trigger_phrase_sound_model) + soundModel->data.size();
+ struct sound_trigger_phrase_sound_model* halKeyPhraseModel =
+ static_cast<struct sound_trigger_phrase_sound_model*>(malloc(allocSize));
+ LOG_ALWAYS_FATAL_IF(halKeyPhraseModel == NULL,
+ "malloc failed for size %zu in convertSoundModelToHal PHRASE",
+ allocSize);
+
+ const V2_0::ISoundTriggerHw::PhraseSoundModel* keyPhraseModel =
+ reinterpret_cast<const V2_0::ISoundTriggerHw::PhraseSoundModel*>(soundModel);
+
+ size_t i;
+ for (i = 0; i < keyPhraseModel->phrases.size() && i < SOUND_TRIGGER_MAX_PHRASES; i++) {
+ convertTriggerPhraseToHal(&halKeyPhraseModel->phrases[i], &keyPhraseModel->phrases[i]);
+ }
+ halKeyPhraseModel->num_phrases = (unsigned int)i;
+ halModel = reinterpret_cast<struct sound_trigger_sound_model*>(halKeyPhraseModel);
+ halModel->data_offset = sizeof(struct sound_trigger_phrase_sound_model);
+ } else {
+ size_t allocSize = sizeof(struct sound_trigger_sound_model) + soundModel->data.size();
+ halModel = static_cast<struct sound_trigger_sound_model*>(malloc(allocSize));
+ LOG_ALWAYS_FATAL_IF(halModel == NULL,
+ "malloc failed for size %zu in convertSoundModelToHal GENERIC",
+ allocSize);
+
+ halModel->data_offset = sizeof(struct sound_trigger_sound_model);
+ }
+ halModel->type = (sound_trigger_sound_model_type_t)soundModel->type;
+ convertUuidToHal(&halModel->uuid, &soundModel->uuid);
+ convertUuidToHal(&halModel->vendor_uuid, &soundModel->vendorUuid);
+ halModel->data_size = soundModel->data.size();
+ uint8_t* dst = reinterpret_cast<uint8_t*>(halModel) + halModel->data_offset;
+ const uint8_t* src = reinterpret_cast<const uint8_t*>(&soundModel->data[0]);
+ memcpy(dst, src, soundModel->data.size());
+
+ return halModel;
+}
+
+void SoundTriggerHw::convertPhraseRecognitionExtraToHal(
+ struct sound_trigger_phrase_recognition_extra* halExtra,
+ const V2_0::PhraseRecognitionExtra* extra) {
+ halExtra->id = extra->id;
+ halExtra->recognition_modes = extra->recognitionModes;
+ halExtra->confidence_level = extra->confidenceLevel;
+
+ unsigned int i;
+ for (i = 0; i < extra->levels.size() && i < SOUND_TRIGGER_MAX_USERS; i++) {
+ halExtra->levels[i].user_id = extra->levels[i].userId;
+ halExtra->levels[i].level = extra->levels[i].levelPercent;
+ }
+ halExtra->num_levels = i;
+}
+
+struct sound_trigger_recognition_config* SoundTriggerHw::convertRecognitionConfigToHal(
+ const V2_0::ISoundTriggerHw::RecognitionConfig* config) {
+ size_t allocSize = sizeof(struct sound_trigger_recognition_config) + config->data.size();
+ struct sound_trigger_recognition_config* halConfig =
+ static_cast<struct sound_trigger_recognition_config*>(malloc(allocSize));
+
+ LOG_ALWAYS_FATAL_IF(halConfig == NULL,
+ "malloc failed for size %zu in convertRecognitionConfigToHal", allocSize);
+
+ halConfig->capture_handle = (audio_io_handle_t)config->captureHandle;
+ halConfig->capture_device = (audio_devices_t)config->captureDevice;
+ halConfig->capture_requested = config->captureRequested;
+
+ unsigned int i;
+ for (i = 0; i < config->phrases.size() && i < SOUND_TRIGGER_MAX_PHRASES; i++) {
+ convertPhraseRecognitionExtraToHal(&halConfig->phrases[i], &config->phrases[i]);
+ }
+ halConfig->num_phrases = i;
+
+ halConfig->data_offset = sizeof(struct sound_trigger_recognition_config);
+ halConfig->data_size = config->data.size();
+ uint8_t* dst = reinterpret_cast<uint8_t*>(halConfig) + halConfig->data_offset;
+ const uint8_t* src = reinterpret_cast<const uint8_t*>(&config->data[0]);
+ memcpy(dst, src, config->data.size());
+ return halConfig;
+}
+
+// static
+void SoundTriggerHw::convertSoundModelEventFromHal(
+ V2_0::ISoundTriggerHwCallback::ModelEvent* event,
+ const struct sound_trigger_model_event* halEvent) {
+ event->status = (V2_0::ISoundTriggerHwCallback::SoundModelStatus)halEvent->status;
+ // event->model to be remapped by called
+ event->data.setToExternal(const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(halEvent)) +
+ halEvent->data_offset,
+ halEvent->data_size);
+}
+
+// static
+void SoundTriggerHw::convertPhaseRecognitionEventFromHal(
+ V2_0::ISoundTriggerHwCallback::PhraseRecognitionEvent* event,
+ const struct sound_trigger_phrase_recognition_event* halEvent) {
+ event->phraseExtras.resize(halEvent->num_phrases);
+ for (unsigned int i = 0; i < halEvent->num_phrases; i++) {
+ convertPhraseRecognitionExtraFromHal(&event->phraseExtras[i], &halEvent->phrase_extras[i]);
+ }
+ convertRecognitionEventFromHal(&event->common, &halEvent->common);
+}
+
+// static
+void SoundTriggerHw::convertRecognitionEventFromHal(
+ V2_0::ISoundTriggerHwCallback::RecognitionEvent* event,
+ const struct sound_trigger_recognition_event* halEvent) {
+ event->status = static_cast<V2_0::ISoundTriggerHwCallback::RecognitionStatus>(halEvent->status);
+ event->type = static_cast<V2_0::SoundModelType>(halEvent->type);
+ // event->model to be remapped by called
+ event->captureAvailable = halEvent->capture_available;
+ event->captureSession = halEvent->capture_session;
+ event->captureDelayMs = halEvent->capture_delay_ms;
+ event->capturePreambleMs = halEvent->capture_preamble_ms;
+ event->triggerInData = halEvent->trigger_in_data;
+ event->audioConfig.sampleRateHz = halEvent->audio_config.sample_rate;
+ event->audioConfig.channelMask =
+ (audio::common::V2_0::AudioChannelMask)halEvent->audio_config.channel_mask;
+ event->audioConfig.format = (audio::common::V2_0::AudioFormat)halEvent->audio_config.format;
+ event->data.setToExternal(const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(halEvent)) +
+ halEvent->data_offset,
+ halEvent->data_size);
+}
+
+// static
+void SoundTriggerHw::convertPhraseRecognitionExtraFromHal(
+ V2_0::PhraseRecognitionExtra* extra,
+ const struct sound_trigger_phrase_recognition_extra* halExtra) {
+ extra->id = halExtra->id;
+ extra->recognitionModes = halExtra->recognition_modes;
+ extra->confidenceLevel = halExtra->confidence_level;
+
+ extra->levels.resize(halExtra->num_levels);
+ for (unsigned int i = 0; i < halExtra->num_levels; i++) {
+ extra->levels[i].userId = halExtra->levels[i].user_id;
+ extra->levels[i].levelPercent = halExtra->levels[i].level;
+ }
+}
+
+void SoundTriggerHw::SoundModelClient_2_0::recognitionCallback(
+ struct sound_trigger_recognition_event* halEvent) {
+ if (halEvent->type == SOUND_MODEL_TYPE_KEYPHRASE) {
+ V2_0::ISoundTriggerHwCallback::PhraseRecognitionEvent event;
+ convertPhaseRecognitionEventFromHal(
+ &event, reinterpret_cast<sound_trigger_phrase_recognition_event*>(halEvent));
+ event.common.model = mId;
+ mCallback->phraseRecognitionCallback(event, mCookie);
+ } else {
+ V2_0::ISoundTriggerHwCallback::RecognitionEvent event;
+ convertRecognitionEventFromHal(&event, halEvent);
+ event.model = mId;
+ mCallback->recognitionCallback(event, mCookie);
+ }
+}
+
+void SoundTriggerHw::SoundModelClient_2_0::soundModelCallback(
+ struct sound_trigger_model_event* halEvent) {
+ V2_0::ISoundTriggerHwCallback::ModelEvent event;
+ convertSoundModelEventFromHal(&event, halEvent);
+ event.model = mId;
+ mCallback->soundModelCallback(event, mCookie);
+}
+
+// Begin V2_1 implementation, copied from
+// hardware/interfaces/soundtrigger/2.1/default/SoundTriggerHw.cpp
+
+namespace {
+
+// Backs up by the vector with the contents of shared memory.
+// It is assumed that the passed hidl_vector is empty, so it's
+// not cleared if the memory is a null object.
+// The caller needs to keep the returned sp<IMemory> as long as
+// the data is needed.
+std::pair<bool, sp<IMemory>> memoryAsVector(const hidl_memory& m, hidl_vec<uint8_t>* vec) {
+ sp<IMemory> memory;
+ if (m.size() == 0) {
+ return std::make_pair(true, memory);
+ }
+ memory = mapMemory(m);
+ if (memory != nullptr) {
+ memory->read();
+ vec->setToExternal(static_cast<uint8_t*>(static_cast<void*>(memory->getPointer())),
+ memory->getSize());
+ return std::make_pair(true, memory);
+ }
+ ALOGE("%s: Could not map HIDL memory to IMemory", __func__);
+ return std::make_pair(false, memory);
+}
+
+// Moves the data from the vector into allocated shared memory,
+// emptying the vector.
+// It is assumed that the passed hidl_memory is a null object, so it's
+// not reset if the vector is empty.
+// The caller needs to keep the returned sp<IMemory> as long as
+// the data is needed.
+std::pair<bool, sp<IMemory>> moveVectorToMemory(hidl_vec<uint8_t>* v, hidl_memory* mem) {
+ sp<IMemory> memory;
+ if (v->size() == 0) {
+ return std::make_pair(true, memory);
+ }
+ sp<IAllocator> ashmem = IAllocator::getService("ashmem");
+ if (ashmem == 0) {
+ ALOGE("Failed to retrieve ashmem allocator service");
+ return std::make_pair(false, memory);
+ }
+ bool success = false;
+ Return<void> r = ashmem->allocate(v->size(), [&](bool s, const hidl_memory& m) {
+ success = s;
+ if (success) *mem = m;
+ });
+ if (r.isOk() && success) {
+ memory = hardware::mapMemory(*mem);
+ if (memory != 0) {
+ memory->update();
+ memcpy(memory->getPointer(), v->data(), v->size());
+ memory->commit();
+ v->resize(0);
+ return std::make_pair(true, memory);
+ } else {
+ ALOGE("Failed to map allocated ashmem");
+ }
+ } else {
+ ALOGE("Failed to allocate %llu bytes from ashmem", (unsigned long long)v->size());
+ }
+ return std::make_pair(false, memory);
+}
+
+} // namespace
+
+Return<void> SoundTriggerHw::loadSoundModel_2_1(
+ const V2_1::ISoundTriggerHw::SoundModel& soundModel,
+ const sp<V2_1::ISoundTriggerHwCallback>& callback, int32_t cookie,
+ V2_1::ISoundTriggerHw::loadSoundModel_2_1_cb _hidl_cb) {
+ // It is assumed that legacy data vector is empty, thus making copy is cheap.
+ V2_0::ISoundTriggerHw::SoundModel soundModel_2_0(soundModel.header);
+ auto result = memoryAsVector(soundModel.data, &soundModel_2_0.data);
+ if (result.first) {
+ sp<SoundModelClient> client =
+ new SoundModelClient_2_1(nextUniqueModelId(), cookie, callback);
+ _hidl_cb(doLoadSoundModel(soundModel_2_0, client), client->getId());
+ return Void();
+ }
+ _hidl_cb(-ENOMEM, 0);
+ return Void();
+}
+
+Return<void> SoundTriggerHw::loadPhraseSoundModel_2_1(
+ const V2_1::ISoundTriggerHw::PhraseSoundModel& soundModel,
+ const sp<V2_1::ISoundTriggerHwCallback>& callback, int32_t cookie,
+ V2_1::ISoundTriggerHw::loadPhraseSoundModel_2_1_cb _hidl_cb) {
+ V2_0::ISoundTriggerHw::PhraseSoundModel soundModel_2_0;
+ // It is assumed that legacy data vector is empty, thus making copy is cheap.
+ soundModel_2_0.common = soundModel.common.header;
+ // Avoid copying phrases data.
+ soundModel_2_0.phrases.setToExternal(
+ const_cast<V2_0::ISoundTriggerHw::Phrase*>(soundModel.phrases.data()),
+ soundModel.phrases.size());
+ auto result = memoryAsVector(soundModel.common.data, &soundModel_2_0.common.data);
+ if (result.first) {
+ sp<SoundModelClient> client =
+ new SoundModelClient_2_1(nextUniqueModelId(), cookie, callback);
+ _hidl_cb(doLoadSoundModel((const V2_0::ISoundTriggerHw::SoundModel&)soundModel_2_0, client),
+ client->getId());
+ return Void();
+ }
+ _hidl_cb(-ENOMEM, 0);
+ return Void();
+}
+
+Return<int32_t> SoundTriggerHw::startRecognition_2_1(
+ int32_t modelHandle, const V2_1::ISoundTriggerHw::RecognitionConfig& config,
+ const sp<V2_1::ISoundTriggerHwCallback>& callback, int32_t cookie) {
+ // It is assumed that legacy data vector is empty, thus making copy is cheap.
+ V2_0::ISoundTriggerHw::RecognitionConfig config_2_0(config.header);
+ auto result = memoryAsVector(config.data, &config_2_0.data);
+ return result.first ? startRecognition(modelHandle, config_2_0, callback, cookie)
+ : Return<int32_t>(-ENOMEM);
+}
+
+void SoundTriggerHw::SoundModelClient_2_1::recognitionCallback(
+ struct sound_trigger_recognition_event* halEvent) {
+ if (halEvent->type == SOUND_MODEL_TYPE_KEYPHRASE) {
+ V2_0::ISoundTriggerHwCallback::PhraseRecognitionEvent event_2_0;
+ convertPhaseRecognitionEventFromHal(
+ &event_2_0, reinterpret_cast<sound_trigger_phrase_recognition_event*>(halEvent));
+ event_2_0.common.model = mId;
+ V2_1::ISoundTriggerHwCallback::PhraseRecognitionEvent event;
+ event.phraseExtras.setToExternal(event_2_0.phraseExtras.data(),
+ event_2_0.phraseExtras.size());
+ auto result = moveVectorToMemory(&event_2_0.common.data, &event.common.data);
+ if (result.first) {
+ // The data vector is now empty, thus copying is cheap.
+ event.common.header = event_2_0.common;
+ mCallback->phraseRecognitionCallback_2_1(event, mCookie);
+ }
+ } else {
+ V2_1::ISoundTriggerHwCallback::RecognitionEvent event;
+ convertRecognitionEventFromHal(&event.header, halEvent);
+ event.header.model = mId;
+ auto result = moveVectorToMemory(&event.header.data, &event.data);
+ if (result.first) {
+ mCallback->recognitionCallback_2_1(event, mCookie);
+ }
+ }
+}
+
+void SoundTriggerHw::SoundModelClient_2_1::soundModelCallback(
+ struct sound_trigger_model_event* halEvent) {
+ V2_1::ISoundTriggerHwCallback::ModelEvent event;
+ convertSoundModelEventFromHal(&event.header, halEvent);
+ event.header.model = mId;
+ auto result = moveVectorToMemory(&event.header.data, &event.data);
+ if (result.first) {
+ mCallback->soundModelCallback_2_1(event, mCookie);
+ }
+}
+
+// Begin V2_2 implementation, copied from
+// hardware/interfaces/soundtrigger/2.2/default/SoundTriggerHw.cpp
+
+Return<int32_t> SoundTriggerHw::getModelState(int32_t modelHandle) {
+ sp<SoundModelClient> client;
+ if (mHwDevice == NULL) {
+ return -ENODEV;
+ }
+
+ {
+ AutoMutex lock(mLock);
+ client = mClients.valueFor(modelHandle);
+ if (client == 0) {
+ return -ENOSYS;
+ }
+ }
+
+ return mHwDevice->get_model_state(mHwDevice, client->getHalHandle());
+}
+
+// Begin V2_3 implementation
+
+Return<int32_t> SoundTriggerHw::setParameter(V2_0::SoundModelHandle modelHandle,
+ ModelParameter modelParam, int32_t value) {
+ sp<SoundModelClient> client;
+ if (mHwDevice == NULL) {
+ return -ENODEV;
+ }
+
+ {
+ AutoMutex lock(mLock);
+ client = mClients.valueFor(modelHandle);
+ if (client == 0) {
+ return -EINVAL;
+ }
+ }
+
+ return mHwDevice->set_parameter(mHwDevice, client->getHalHandle(),
+ convertModelParameterToHal(modelParam), value);
+}
+
+Return<void> SoundTriggerHw::getParameter(V2_0::SoundModelHandle modelHandle,
+ ModelParameter modelParam, getParameter_cb _hidl_cb) {
+ sp<SoundModelClient> client;
+ if (mHwDevice == NULL) {
+ _hidl_cb(-ENODEV, 0);
+ return Void();
+ }
+
+ {
+ AutoMutex lock(mLock);
+ client = mClients.valueFor(modelHandle);
+ if (client == 0) {
+ _hidl_cb(-EINVAL, 0);
+ return Void();
+ }
+ }
+
+ int32_t value;
+ int32_t status = mHwDevice->get_parameter(mHwDevice, client->getHalHandle(),
+ convertModelParameterToHal(modelParam), &value);
+ _hidl_cb(status, value);
+ return Void();
+}
+
+Return<void> SoundTriggerHw::queryParameter(V2_0::SoundModelHandle modelHandle,
+ ModelParameter modelParam, queryParameter_cb _hidl_cb) {
+ OptionalModelParameterRange optionalParamRange;
+ sp<SoundModelClient> client;
+ if (mHwDevice == NULL) {
+ _hidl_cb(-ENODEV, optionalParamRange);
+ return Void();
+ }
+
+ {
+ AutoMutex lock(mLock);
+ client = mClients.valueFor(modelHandle);
+ if (client == 0) {
+ _hidl_cb(-EINVAL, optionalParamRange);
+ return Void();
+ }
+ }
+
+ sound_trigger_model_parameter_range_t paramRange;
+ int32_t status = mHwDevice->query_parameter(
+ mHwDevice, client->getHalHandle(), convertModelParameterToHal(modelParam), ¶mRange);
+
+ if (status == 0) {
+ optionalParamRange.range({.start = paramRange.start, .end = paramRange.end});
+ }
+ _hidl_cb(status, optionalParamRange);
+ return Void();
+}
+
+// static
+sound_trigger_model_parameter_t SoundTriggerHw::convertModelParameterToHal(ModelParameter param) {
+ switch (param) {
+ case ModelParameter::THRESHOLD_FACTOR:
+ return MODEL_PARAMETER_THRESHOLD_FACTOR;
+ case ModelParameter::INVALID:
+ default:
+ return MODEL_PARAMETER_INVALID;
+ }
+}
+
+// Methods from ::android::hidl::base::V1_0::IBase follow.
+
+ISoundTriggerHw* HIDL_FETCH_ISoundTriggerHw(const char* /* name */) {
+ return new SoundTriggerHw();
+}
+
+} // namespace implementation
+} // namespace V2_3
+} // namespace soundtrigger
+} // namespace hardware
+} // namespace android
diff --git a/soundtrigger/2.3/default/SoundTriggerHw.h b/soundtrigger/2.3/default/SoundTriggerHw.h
new file mode 100644
index 0000000..c82c9ea
--- /dev/null
+++ b/soundtrigger/2.3/default/SoundTriggerHw.h
@@ -0,0 +1,207 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_SOUNDTRIGGER_V2_3_SOUNDTRIGGERHW_H
+#define ANDROID_HARDWARE_SOUNDTRIGGER_V2_3_SOUNDTRIGGERHW_H
+
+#include <android/hardware/soundtrigger/2.0/ISoundTriggerHw.h>
+#include <android/hardware/soundtrigger/2.0/ISoundTriggerHwCallback.h>
+#include <android/hardware/soundtrigger/2.3/ISoundTriggerHw.h>
+#include <android/hardware/soundtrigger/2.3/types.h>
+#include <hardware/sound_trigger.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+#include <stdatomic.h>
+#include <system/sound_trigger.h>
+#include <utils/KeyedVector.h>
+#include <utils/threads.h>
+
+namespace android {
+namespace hardware {
+namespace soundtrigger {
+namespace V2_3 {
+namespace implementation {
+
+using ::android::sp;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::audio::common::V2_0::Uuid;
+
+/**
+ * According to the HIDL C++ Users Guide: client and server implementations
+ * should never directly refer to anything other than the interface header
+ * generated from the HIDL definition file (ie. ISoundTriggerHw.hal), so
+ * this V2_3 implementation copies the previous implementations and
+ * then adds the new implementation.
+ */
+struct SoundTriggerHw : public ISoundTriggerHw {
+ // Methods from V2_0::ISoundTriggerHw follow.
+ Return<void> getProperties(getProperties_cb _hidl_cb) override;
+ Return<void> loadSoundModel(const V2_0::ISoundTriggerHw::SoundModel& soundModel,
+ const sp<V2_0::ISoundTriggerHwCallback>& callback, int32_t cookie,
+ loadSoundModel_cb _hidl_cb) override;
+ Return<void> loadPhraseSoundModel(const V2_0::ISoundTriggerHw::PhraseSoundModel& soundModel,
+ const sp<V2_0::ISoundTriggerHwCallback>& callback,
+ int32_t cookie, loadPhraseSoundModel_cb _hidl_cb) override;
+ Return<int32_t> unloadSoundModel(int32_t modelHandle) override;
+ Return<int32_t> startRecognition(int32_t modelHandle,
+ const V2_0::ISoundTriggerHw::RecognitionConfig& config,
+ const sp<V2_0::ISoundTriggerHwCallback>& callback,
+ int32_t cookie) override;
+ Return<int32_t> stopRecognition(int32_t modelHandle) override;
+ Return<int32_t> stopAllRecognitions() override;
+
+ // Methods from V2_1::ISoundTriggerHw follow.
+ Return<void> loadSoundModel_2_1(const V2_1::ISoundTriggerHw::SoundModel& soundModel,
+ const sp<V2_1::ISoundTriggerHwCallback>& callback,
+ int32_t cookie, loadSoundModel_2_1_cb _hidl_cb) override;
+ Return<void> loadPhraseSoundModel_2_1(const V2_1::ISoundTriggerHw::PhraseSoundModel& soundModel,
+ const sp<V2_1::ISoundTriggerHwCallback>& callback,
+ int32_t cookie,
+ loadPhraseSoundModel_2_1_cb _hidl_cb) override;
+ Return<int32_t> startRecognition_2_1(int32_t modelHandle,
+ const V2_1::ISoundTriggerHw::RecognitionConfig& config,
+ const sp<V2_1::ISoundTriggerHwCallback>& callback,
+ int32_t cookie) override;
+
+ // Methods from V2_2::ISoundTriggerHw follow.
+ Return<int32_t> getModelState(int32_t modelHandle) override;
+
+ // Methods from V2_3::ISoundTriggerHw follow.
+ Return<int32_t> setParameter(V2_0::SoundModelHandle modelHandle, ModelParameter modelParam,
+ int32_t value) override;
+ Return<void> getParameter(V2_0::SoundModelHandle modelHandle, ModelParameter modelParam,
+ ISoundTriggerHw::getParameter_cb _hidl_cb) override;
+ Return<void> queryParameter(V2_0::SoundModelHandle modelHandle, ModelParameter modelParam,
+ ISoundTriggerHw::queryParameter_cb _hidl_cb) override;
+
+ SoundTriggerHw();
+
+ // Copied from hardware/interfaces/soundtrigger/2.0/default/SoundTriggerHalImpl.h
+
+ /**
+ * Client object holding active handles and callback sctructures. Used for referencing
+ * which models map to which client of the HAL. SoundModelClients are stored in the
+ * mClients object while the model is active.
+ */
+ class SoundModelClient : public RefBase {
+ public:
+ SoundModelClient(uint32_t id, V2_0::ISoundTriggerHwCallback::CallbackCookie cookie)
+ : mId(id), mCookie(cookie) {}
+ virtual ~SoundModelClient() {}
+
+ uint32_t getId() const { return mId; }
+ sound_model_handle_t getHalHandle() const { return mHalHandle; }
+ void setHalHandle(sound_model_handle_t handle) { mHalHandle = handle; }
+
+ virtual void recognitionCallback(struct sound_trigger_recognition_event* halEvent) = 0;
+ virtual void soundModelCallback(struct sound_trigger_model_event* halEvent) = 0;
+
+ protected:
+ const uint32_t mId;
+ sound_model_handle_t mHalHandle;
+ V2_0::ISoundTriggerHwCallback::CallbackCookie mCookie;
+ };
+
+ private:
+ static void convertPhaseRecognitionEventFromHal(
+ V2_0::ISoundTriggerHwCallback::PhraseRecognitionEvent* event,
+ const struct sound_trigger_phrase_recognition_event* halEvent);
+ static void convertRecognitionEventFromHal(
+ V2_0::ISoundTriggerHwCallback::RecognitionEvent* event,
+ const struct sound_trigger_recognition_event* halEvent);
+ static void convertSoundModelEventFromHal(V2_0::ISoundTriggerHwCallback::ModelEvent* event,
+ const struct sound_trigger_model_event* halEvent);
+
+ virtual ~SoundTriggerHw();
+
+ uint32_t nextUniqueModelId();
+ int doLoadSoundModel(const V2_0::ISoundTriggerHw::SoundModel& soundModel,
+ sp<SoundModelClient> client);
+
+ // RefBase
+ void onFirstRef() override;
+
+ class SoundModelClient_2_0 : public SoundModelClient {
+ public:
+ SoundModelClient_2_0(uint32_t id, V2_0::ISoundTriggerHwCallback::CallbackCookie cookie,
+ sp<V2_0::ISoundTriggerHwCallback> callback)
+ : SoundModelClient(id, cookie), mCallback(callback) {}
+
+ void recognitionCallback(struct sound_trigger_recognition_event* halEvent) override;
+ void soundModelCallback(struct sound_trigger_model_event* halEvent) override;
+
+ private:
+ sp<V2_0::ISoundTriggerHwCallback> mCallback;
+ };
+
+ void convertUuidFromHal(Uuid* uuid, const sound_trigger_uuid_t* halUuid);
+ void convertUuidToHal(sound_trigger_uuid_t* halUuid, const Uuid* uuid);
+ void convertPropertiesFromHal(V2_0::ISoundTriggerHw::Properties* properties,
+ const struct sound_trigger_properties* halProperties);
+ static sound_trigger_model_parameter_t convertModelParameterToHal(ModelParameter param);
+ void convertTriggerPhraseToHal(struct sound_trigger_phrase* halTriggerPhrase,
+ const V2_0::ISoundTriggerHw::Phrase* triggerPhrase);
+ // returned HAL sound model must be freed by caller
+ struct sound_trigger_sound_model* convertSoundModelToHal(
+ const V2_0::ISoundTriggerHw::SoundModel* soundModel);
+ void convertPhraseRecognitionExtraToHal(struct sound_trigger_phrase_recognition_extra* halExtra,
+ const V2_0::PhraseRecognitionExtra* extra);
+ // returned recognition config must be freed by caller
+ struct sound_trigger_recognition_config* convertRecognitionConfigToHal(
+ const V2_0::ISoundTriggerHw::RecognitionConfig* config);
+
+ static void convertPhraseRecognitionExtraFromHal(
+ V2_0::PhraseRecognitionExtra* extra,
+ const struct sound_trigger_phrase_recognition_extra* halExtra);
+
+ static void soundModelCallback(struct sound_trigger_model_event* halEvent, void* cookie);
+ static void recognitionCallback(struct sound_trigger_recognition_event* halEvent, void* cookie);
+
+ const char* mModuleName;
+ struct sound_trigger_hw_device* mHwDevice;
+ volatile atomic_uint_fast32_t mNextModelId;
+ DefaultKeyedVector<int32_t, sp<SoundModelClient>> mClients;
+ Mutex mLock;
+
+ // Copied from hardware/interfaces/soundtrigger/2.1/default/SoundTriggerHw.h
+ class SoundModelClient_2_1 : public SoundModelClient {
+ public:
+ SoundModelClient_2_1(uint32_t id, V2_1::ISoundTriggerHwCallback::CallbackCookie cookie,
+ sp<V2_1::ISoundTriggerHwCallback> callback)
+ : SoundModelClient(id, cookie), mCallback(callback) {}
+
+ void recognitionCallback(struct sound_trigger_recognition_event* halEvent) override;
+ void soundModelCallback(struct sound_trigger_model_event* halEvent) override;
+
+ private:
+ sp<V2_1::ISoundTriggerHwCallback> mCallback;
+ };
+};
+
+extern "C" ISoundTriggerHw* HIDL_FETCH_ISoundTriggerHw(const char* name);
+
+} // namespace implementation
+} // namespace V2_3
+} // namespace soundtrigger
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_SOUNDTRIGGER_V2_2_SOUNDTRIGGERHW_H
diff --git a/soundtrigger/2.3/types.hal b/soundtrigger/2.3/types.hal
new file mode 100644
index 0000000..c3a522b
--- /dev/null
+++ b/soundtrigger/2.3/types.hal
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2019 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.soundtrigger@2.3;
+
+import android.hidl.safe_union@1.0::Monostate;
+
+/**
+ * Model specific parameters to be used with parameter set and get APIs
+ */
+enum ModelParameter : int32_t {
+ /**
+ * Placeholder for invalid model parameter used for returning error or
+ * passing an invalid value.
+ */
+ INVALID = -1,
+
+ /**
+ * Controls the sensitivity threshold adjustment factor for a given model.
+ * Negative value corresponds to less sensitive model (high threshold) and
+ * a positive value corresponds to a more sensitive model (low threshold).
+ * Default value is 0.
+ */
+ THRESHOLD_FACTOR = 0
+};
+
+/**
+ * Safe union wrapping ModelParameterRange.
+ * Monostate is used to indicate there is no valid range
+ */
+safe_union OptionalModelParameterRange {
+ Monostate noinit;
+ ModelParameterRange range;
+};
+
+/**
+ * Model specific range support for a given parameter
+ */
+struct ModelParameterRange {
+ /**
+ * start of supported value range inclusive
+ */
+ int32_t start;
+ /**
+ * end of supported value range inclusive
+ */
+ int32_t end;
+};
diff --git a/soundtrigger/2.3/vts/functional/Android.bp b/soundtrigger/2.3/vts/functional/Android.bp
new file mode 100644
index 0000000..e3855fc
--- /dev/null
+++ b/soundtrigger/2.3/vts/functional/Android.bp
@@ -0,0 +1,31 @@
+//
+// Copyright (C) 2019 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.
+//
+
+cc_test {
+ name: "VtsHalSoundtriggerV2_3TargetTest",
+ defaults: ["VtsHalTargetTestDefaults"],
+ srcs: ["VtsHalSoundtriggerV2_3TargetTest.cpp"],
+ static_libs: [
+ "android.hardware.soundtrigger@2.0",
+ "android.hardware.soundtrigger@2.1",
+ "android.hardware.soundtrigger@2.2",
+ "android.hardware.soundtrigger@2.3",
+ ],
+ test_suites: [
+ "general-tests",
+ "vts-core",
+ ],
+}
diff --git a/soundtrigger/2.3/vts/functional/VtsHalSoundtriggerV2_3TargetTest.cpp b/soundtrigger/2.3/vts/functional/VtsHalSoundtriggerV2_3TargetTest.cpp
new file mode 100644
index 0000000..202eb6c
--- /dev/null
+++ b/soundtrigger/2.3/vts/functional/VtsHalSoundtriggerV2_3TargetTest.cpp
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2019 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 "SoundTriggerHidlHalTest"
+
+#include <android-base/logging.h>
+#include <android/hardware/audio/common/2.0/types.h>
+#include <android/hardware/soundtrigger/2.3/ISoundTriggerHw.h>
+#include <android/hardware/soundtrigger/2.3/types.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
+
+using ::android::sp;
+using ::android::hardware::Return;
+using ::android::hardware::soundtrigger::V2_3::ISoundTriggerHw;
+
+/**
+ * Test class holding the instance of the SoundTriggerHW service to test.
+ * The passed parameter is the registered name of the implementing service
+ * supplied by INSTANTIATE_TEST_SUITE_P() call.
+ */
+class SoundTriggerHidlTest : public testing::TestWithParam<std::string> {
+ public:
+ void SetUp() override {
+ soundtrigger = ISoundTriggerHw::getService(GetParam());
+
+ ASSERT_NE(soundtrigger, nullptr);
+ LOG(INFO) << "Test is remote " << soundtrigger->isRemote();
+ }
+
+ sp<ISoundTriggerHw> soundtrigger;
+};
+
+/**
+ * Empty test is in place to ensure service is initalized.
+ * Due to the nature of SoundTrigger HAL providing an interface for
+ * proprietary or vendor specific implementations, limited testing on
+ * individual APIs is possible.
+ */
+TEST_P(SoundTriggerHidlTest, ServiceIsInstantiated) {}
+
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, SoundTriggerHidlTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(ISoundTriggerHw::descriptor)),
+ android::hardware::PrintInstanceNameToString);
diff --git a/tests/extension/vibrator/aidl/client/test-cpp-client.cpp b/tests/extension/vibrator/aidl/client/test-cpp-client.cpp
index f6f5537..015a345 100644
--- a/tests/extension/vibrator/aidl/client/test-cpp-client.cpp
+++ b/tests/extension/vibrator/aidl/client/test-cpp-client.cpp
@@ -20,9 +20,9 @@
#include <binder/IServiceManager.h>
#include <gtest/gtest.h>
+using android::checked_interface_cast;
using android::IBinder;
using android::IInterface;
-using android::interface_cast;
using android::OK;
using android::sp;
using android::waitForVintfService;
@@ -44,7 +44,7 @@
// getting the extension
sp<IBinder> ext;
ASSERT_EQ(OK, IInterface::asBinder(vib)->getExtension(&ext));
- sp<ICustomVibrator> cvib = interface_cast<ICustomVibrator>(ext);
+ sp<ICustomVibrator> cvib = checked_interface_cast<ICustomVibrator>(ext);
ASSERT_NE(nullptr, cvib.get());
// calling extension method
diff --git a/tests/memory/1.0/Android.bp b/tests/memory/1.0/Android.bp
index 29f6be7..6612e31 100644
--- a/tests/memory/1.0/Android.bp
+++ b/tests/memory/1.0/Android.bp
@@ -11,5 +11,5 @@
"android.hidl.memory.block@1.0",
"android.hidl.memory.token@1.0",
],
- gen_java: false,
+ gen_java: true,
}
diff --git a/tests/memory/2.0/.hidl_for_test b/tests/memory/2.0/.hidl_for_test
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/memory/2.0/.hidl_for_test
diff --git a/tests/memory/2.0/Android.bp b/tests/memory/2.0/Android.bp
index 5166652..d24bd21 100644
--- a/tests/memory/2.0/Android.bp
+++ b/tests/memory/2.0/Android.bp
@@ -1,9 +1,11 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
hidl_interface {
name: "android.hardware.tests.memory@2.0",
root: "android.hardware",
srcs: [
- "IMemoryInterface.hal",
"types.hal",
+ "IMemoryInterface.hal",
],
interfaces: [
"android.hidl.base@1.0",
diff --git a/tetheroffload/control/1.0/vts/functional/Android.bp b/tetheroffload/control/1.0/vts/functional/Android.bp
index e8e1414..4af59b6 100644
--- a/tetheroffload/control/1.0/vts/functional/Android.bp
+++ b/tetheroffload/control/1.0/vts/functional/Android.bp
@@ -20,5 +20,5 @@
"android.hardware.tetheroffload.config@1.0",
"android.hardware.tetheroffload.control@1.0",
],
- test_suites: ["general-tests"],
+ test_suites: ["general-tests", "vts-core"],
}
diff --git a/tetheroffload/control/1.0/vts/functional/VtsHalTetheroffloadControlV1_0TargetTest.cpp b/tetheroffload/control/1.0/vts/functional/VtsHalTetheroffloadControlV1_0TargetTest.cpp
index 03b6406..b422b2f 100644
--- a/tetheroffload/control/1.0/vts/functional/VtsHalTetheroffloadControlV1_0TargetTest.cpp
+++ b/tetheroffload/control/1.0/vts/functional/VtsHalTetheroffloadControlV1_0TargetTest.cpp
@@ -17,15 +17,17 @@
#define LOG_TAG "VtsOffloadControlV1_0TargetTest"
#include <VtsHalHidlTargetCallbackBase.h>
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
#include <android-base/stringprintf.h>
#include <android-base/unique_fd.h>
#include <android/hardware/tetheroffload/config/1.0/IOffloadConfig.h>
#include <android/hardware/tetheroffload/control/1.0/IOffloadControl.h>
#include <android/hardware/tetheroffload/control/1.0/types.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include <linux/netfilter/nfnetlink.h>
#include <linux/netlink.h>
+#include <log/log.h>
#include <net/if.h>
#include <sys/socket.h>
#include <unistd.h>
@@ -110,24 +112,8 @@
NatTimeoutUpdate last_params;
};
-// Test environment for OffloadControl HIDL HAL.
-class OffloadControlHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static OffloadControlHidlEnvironment* Instance() {
- static OffloadControlHidlEnvironment* instance = new OffloadControlHidlEnvironment;
- return instance;
- }
-
- virtual void registerTestServices() override {
- registerTestService<IOffloadConfig>();
- registerTestService<IOffloadControl>();
- }
- private:
- OffloadControlHidlEnvironment() {}
-};
-
-class OffloadControlHidlTestBase : public testing::VtsHalHidlTargetTestBase {
+class OffloadControlHidlTestBase
+ : public testing::TestWithParam<std::tuple<std::string, std::string>> {
public:
virtual void SetUp() override {
setupConfigHal();
@@ -144,8 +130,7 @@
// The IOffloadConfig HAL is tested more thoroughly elsewhere. He we just
// setup everything correctly and verify basic readiness.
void setupConfigHal() {
- config = testing::VtsHalHidlTargetTestBase::getService<IOffloadConfig>(
- OffloadControlHidlEnvironment::Instance()->getServiceName<IOffloadConfig>());
+ config = IOffloadConfig::getService(std::get<0>(GetParam()));
ASSERT_NE(nullptr, config.get()) << "Could not get HIDL instance";
unique_fd fd1(conntrackSocket(NF_NETLINK_CONNTRACK_NEW | NF_NETLINK_CONNTRACK_DESTROY));
@@ -173,8 +158,7 @@
}
void prepareControlHal() {
- control = testing::VtsHalHidlTargetTestBase::getService<IOffloadControl>(
- OffloadControlHidlEnvironment::Instance()->getServiceName<IOffloadControl>());
+ control = IOffloadControl::getService(std::get<1>(GetParam()));
ASSERT_NE(nullptr, control.get()) << "Could not get HIDL instance";
control_cb = new TetheringOffloadCallback();
@@ -240,7 +224,7 @@
};
// Call initOffload() multiple times. Check that non-first initOffload() calls return false.
-TEST_F(OffloadControlHidlTestBase, AdditionalInitsWithoutStopReturnFalse) {
+TEST_P(OffloadControlHidlTestBase, AdditionalInitsWithoutStopReturnFalse) {
initOffload(true);
initOffload(false);
initOffload(false);
@@ -248,7 +232,7 @@
}
// Check that calling stopOffload() without first having called initOffload() returns false.
-TEST_F(OffloadControlHidlTestBase, MultipleStopsWithoutInitReturnFalse) {
+TEST_P(OffloadControlHidlTestBase, MultipleStopsWithoutInitReturnFalse) {
stopOffload(ExpectBoolean::False);
stopOffload(ExpectBoolean::False);
stopOffload(ExpectBoolean::False);
@@ -267,7 +251,7 @@
}
// Check that calling stopOffload() after a complete init/stop cycle returns false.
-TEST_F(OffloadControlHidlTestBase, AdditionalStopsWithInitReturnFalse) {
+TEST_P(OffloadControlHidlTestBase, AdditionalStopsWithInitReturnFalse) {
initOffload(true);
// Call setUpstreamParameters() so that "offload" can be reasonably said
// to be both requested and operational.
@@ -289,7 +273,7 @@
}
// Check that calling setLocalPrefixes() without first having called initOffload() returns false.
-TEST_F(OffloadControlHidlTestBase, SetLocalPrefixesWithoutInitReturnsFalse) {
+TEST_P(OffloadControlHidlTestBase, SetLocalPrefixesWithoutInitReturnsFalse) {
const vector<hidl_string> prefixes{hidl_string("2001:db8::/64")};
const Return<void> ret = control->setLocalPrefixes(prefixes, ASSERT_FALSE_CALLBACK);
EXPECT_TRUE(ret.isOk());
@@ -297,14 +281,14 @@
// Check that calling getForwardedStats() without first having called initOffload()
// returns zero bytes statistics.
-TEST_F(OffloadControlHidlTestBase, GetForwardedStatsWithoutInitReturnsZeroValues) {
+TEST_P(OffloadControlHidlTestBase, GetForwardedStatsWithoutInitReturnsZeroValues) {
const hidl_string upstream(TEST_IFACE);
const Return<void> ret = control->getForwardedStats(upstream, ASSERT_ZERO_BYTES_CALLBACK);
EXPECT_TRUE(ret.isOk());
}
// Check that calling setDataLimit() without first having called initOffload() returns false.
-TEST_F(OffloadControlHidlTestBase, SetDataLimitWithoutInitReturnsFalse) {
+TEST_P(OffloadControlHidlTestBase, SetDataLimitWithoutInitReturnsFalse) {
const hidl_string upstream(TEST_IFACE);
const uint64_t limit = 5000ULL;
const Return<void> ret = control->setDataLimit(upstream, limit, ASSERT_FALSE_CALLBACK);
@@ -313,7 +297,7 @@
// Check that calling setUpstreamParameters() without first having called initOffload()
// returns false.
-TEST_F(OffloadControlHidlTestBase, SetUpstreamParametersWithoutInitReturnsFalse) {
+TEST_P(OffloadControlHidlTestBase, SetUpstreamParametersWithoutInitReturnsFalse) {
const hidl_string iface(TEST_IFACE);
const hidl_string v4Addr("192.0.2.0/24");
const hidl_string v4Gw("192.0.2.1");
@@ -325,7 +309,7 @@
// Check that calling addDownstream() with an IPv4 prefix without first having called
// initOffload() returns false.
-TEST_F(OffloadControlHidlTestBase, AddIPv4DownstreamWithoutInitReturnsFalse) {
+TEST_P(OffloadControlHidlTestBase, AddIPv4DownstreamWithoutInitReturnsFalse) {
const hidl_string iface(TEST_IFACE);
const hidl_string prefix("192.0.2.0/24");
const Return<void> ret = control->addDownstream(iface, prefix, ASSERT_FALSE_CALLBACK);
@@ -334,7 +318,7 @@
// Check that calling addDownstream() with an IPv6 prefix without first having called
// initOffload() returns false.
-TEST_F(OffloadControlHidlTestBase, AddIPv6DownstreamWithoutInitReturnsFalse) {
+TEST_P(OffloadControlHidlTestBase, AddIPv6DownstreamWithoutInitReturnsFalse) {
const hidl_string iface(TEST_IFACE);
const hidl_string prefix("2001:db8::/64");
const Return<void> ret = control->addDownstream(iface, prefix, ASSERT_FALSE_CALLBACK);
@@ -343,7 +327,7 @@
// Check that calling removeDownstream() with an IPv4 prefix without first having called
// initOffload() returns false.
-TEST_F(OffloadControlHidlTestBase, RemoveIPv4DownstreamWithoutInitReturnsFalse) {
+TEST_P(OffloadControlHidlTestBase, RemoveIPv4DownstreamWithoutInitReturnsFalse) {
const hidl_string iface(TEST_IFACE);
const hidl_string prefix("192.0.2.0/24");
const Return<void> ret = control->removeDownstream(iface, prefix, ASSERT_FALSE_CALLBACK);
@@ -352,7 +336,7 @@
// Check that calling removeDownstream() with an IPv6 prefix without first having called
// initOffload() returns false.
-TEST_F(OffloadControlHidlTestBase, RemoveIPv6DownstreamWithoutInitReturnsFalse) {
+TEST_P(OffloadControlHidlTestBase, RemoveIPv6DownstreamWithoutInitReturnsFalse) {
const hidl_string iface(TEST_IFACE);
const hidl_string prefix("2001:db8::/64");
const Return<void> ret = control->removeDownstream(iface, prefix, ASSERT_FALSE_CALLBACK);
@@ -379,21 +363,21 @@
*/
// Test setLocalPrefixes() accepts an IPv4 address.
-TEST_F(OffloadControlHidlTest, SetLocalPrefixesIPv4AddressOk) {
+TEST_P(OffloadControlHidlTest, SetLocalPrefixesIPv4AddressOk) {
const vector<hidl_string> prefixes{hidl_string("192.0.2.1")};
const Return<void> ret = control->setLocalPrefixes(prefixes, ASSERT_TRUE_CALLBACK);
EXPECT_TRUE(ret.isOk());
}
// Test setLocalPrefixes() accepts an IPv6 address.
-TEST_F(OffloadControlHidlTest, SetLocalPrefixesIPv6AddressOk) {
+TEST_P(OffloadControlHidlTest, SetLocalPrefixesIPv6AddressOk) {
const vector<hidl_string> prefixes{hidl_string("fe80::1")};
const Return<void> ret = control->setLocalPrefixes(prefixes, ASSERT_TRUE_CALLBACK);
EXPECT_TRUE(ret.isOk());
}
// Test setLocalPrefixes() accepts both IPv4 and IPv6 prefixes.
-TEST_F(OffloadControlHidlTest, SetLocalPrefixesIPv4v6PrefixesOk) {
+TEST_P(OffloadControlHidlTest, SetLocalPrefixesIPv4v6PrefixesOk) {
const vector<hidl_string> prefixes{hidl_string("192.0.2.0/24"), hidl_string("fe80::/64")};
const Return<void> ret = control->setLocalPrefixes(prefixes, ASSERT_TRUE_CALLBACK);
EXPECT_TRUE(ret.isOk());
@@ -402,14 +386,14 @@
// Test that setLocalPrefixes() fails given empty input. There is always
// a non-empty set of local prefixes; when all networking interfaces are down
// we still apply {127.0.0.0/8, ::1/128, fe80::/64} here.
-TEST_F(OffloadControlHidlTest, SetLocalPrefixesEmptyFails) {
+TEST_P(OffloadControlHidlTest, SetLocalPrefixesEmptyFails) {
const vector<hidl_string> prefixes{};
const Return<void> ret = control->setLocalPrefixes(prefixes, ASSERT_FALSE_CALLBACK);
EXPECT_TRUE(ret.isOk());
}
// Test setLocalPrefixes() fails on incorrectly formed input strings.
-TEST_F(OffloadControlHidlTest, SetLocalPrefixesInvalidFails) {
+TEST_P(OffloadControlHidlTest, SetLocalPrefixesInvalidFails) {
const vector<hidl_string> prefixes{hidl_string("192.0.2.0/24"), hidl_string("invalid")};
const Return<void> ret = control->setLocalPrefixes(prefixes, ASSERT_FALSE_CALLBACK);
EXPECT_TRUE(ret.isOk());
@@ -420,7 +404,7 @@
*/
// Test that getForwardedStats() for a non-existent upstream yields zero bytes statistics.
-TEST_F(OffloadControlHidlTest, GetForwardedStatsInvalidUpstreamIface) {
+TEST_P(OffloadControlHidlTest, GetForwardedStatsInvalidUpstreamIface) {
const hidl_string upstream("invalid");
const Return<void> ret = control->getForwardedStats(upstream, ASSERT_ZERO_BYTES_CALLBACK);
EXPECT_TRUE(ret.isOk());
@@ -428,7 +412,7 @@
// TEST_IFACE is presumed to exist on the device and be up. No packets
// are ever actually caused to be forwarded.
-TEST_F(OffloadControlHidlTest, GetForwardedStatsDummyIface) {
+TEST_P(OffloadControlHidlTest, GetForwardedStatsDummyIface) {
const hidl_string upstream(TEST_IFACE);
const Return<void> ret = control->getForwardedStats(upstream, ASSERT_ZERO_BYTES_CALLBACK);
EXPECT_TRUE(ret.isOk());
@@ -439,7 +423,7 @@
*/
// Test that setDataLimit() for an empty interface name fails.
-TEST_F(OffloadControlHidlTest, SetDataLimitEmptyUpstreamIfaceFails) {
+TEST_P(OffloadControlHidlTest, SetDataLimitEmptyUpstreamIfaceFails) {
const hidl_string upstream("");
const uint64_t limit = 5000ULL;
const Return<void> ret = control->setDataLimit(upstream, limit, ASSERT_FALSE_CALLBACK);
@@ -448,7 +432,7 @@
// TEST_IFACE is presumed to exist on the device and be up. No packets
// are ever actually caused to be forwarded.
-TEST_F(OffloadControlHidlTest, SetDataLimitNonZeroOk) {
+TEST_P(OffloadControlHidlTest, SetDataLimitNonZeroOk) {
const hidl_string upstream(TEST_IFACE);
const uint64_t limit = 5000ULL;
const Return<void> ret = control->setDataLimit(upstream, limit, ASSERT_TRUE_CALLBACK);
@@ -457,7 +441,7 @@
// TEST_IFACE is presumed to exist on the device and be up. No packets
// are ever actually caused to be forwarded.
-TEST_F(OffloadControlHidlTest, SetDataLimitZeroOk) {
+TEST_P(OffloadControlHidlTest, SetDataLimitZeroOk) {
const hidl_string upstream(TEST_IFACE);
const uint64_t limit = 0ULL;
const Return<void> ret = control->setDataLimit(upstream, limit, ASSERT_TRUE_CALLBACK);
@@ -470,7 +454,7 @@
// TEST_IFACE is presumed to exist on the device and be up. No packets
// are ever actually caused to be forwarded.
-TEST_F(OffloadControlHidlTest, SetUpstreamParametersIPv6OnlyOk) {
+TEST_P(OffloadControlHidlTest, SetUpstreamParametersIPv6OnlyOk) {
const hidl_string iface(TEST_IFACE);
const hidl_string v4Addr("");
const hidl_string v4Gw("");
@@ -482,7 +466,7 @@
// TEST_IFACE is presumed to exist on the device and be up. No packets
// are ever actually caused to be forwarded.
-TEST_F(OffloadControlHidlTest, SetUpstreamParametersAlternateIPv6OnlyOk) {
+TEST_P(OffloadControlHidlTest, SetUpstreamParametersAlternateIPv6OnlyOk) {
const hidl_string iface(TEST_IFACE);
const hidl_string v4Addr;
const hidl_string v4Gw;
@@ -494,7 +478,7 @@
// TEST_IFACE is presumed to exist on the device and be up. No packets
// are ever actually caused to be forwarded.
-TEST_F(OffloadControlHidlTest, SetUpstreamParametersIPv4OnlyOk) {
+TEST_P(OffloadControlHidlTest, SetUpstreamParametersIPv4OnlyOk) {
const hidl_string iface(TEST_IFACE);
const hidl_string v4Addr("192.0.2.2");
const hidl_string v4Gw("192.0.2.1");
@@ -506,7 +490,7 @@
// TEST_IFACE is presumed to exist on the device and be up. No packets
// are ever actually caused to be forwarded.
-TEST_F(OffloadControlHidlTest, SetUpstreamParametersIPv4v6Ok) {
+TEST_P(OffloadControlHidlTest, SetUpstreamParametersIPv4v6Ok) {
const hidl_string iface(TEST_IFACE);
const hidl_string v4Addr("192.0.2.2");
const hidl_string v4Gw("192.0.2.1");
@@ -517,7 +501,7 @@
}
// Test that setUpstreamParameters() fails when all parameters are empty.
-TEST_F(OffloadControlHidlTest, SetUpstreamParametersEmptyFails) {
+TEST_P(OffloadControlHidlTest, SetUpstreamParametersEmptyFails) {
const hidl_string iface("");
const hidl_string v4Addr("");
const hidl_string v4Gw("");
@@ -528,7 +512,7 @@
}
// Test that setUpstreamParameters() fails when given empty or non-existent interface names.
-TEST_F(OffloadControlHidlTest, SetUpstreamParametersBogusIfaceFails) {
+TEST_P(OffloadControlHidlTest, SetUpstreamParametersBogusIfaceFails) {
const hidl_string v4Addr("192.0.2.2");
const hidl_string v4Gw("192.0.2.1");
const vector<hidl_string> v6Gws{hidl_string("fe80::db8:1")};
@@ -542,7 +526,7 @@
}
// Test that setUpstreamParameters() fails when given unparseable IPv4 addresses.
-TEST_F(OffloadControlHidlTest, SetUpstreamParametersInvalidIPv4AddrFails) {
+TEST_P(OffloadControlHidlTest, SetUpstreamParametersInvalidIPv4AddrFails) {
const hidl_string iface(TEST_IFACE);
const hidl_string v4Gw("192.0.2.1");
const vector<hidl_string> v6Gws{hidl_string("fe80::db8:1")};
@@ -556,7 +540,7 @@
}
// Test that setUpstreamParameters() fails when given unparseable IPv4 gateways.
-TEST_F(OffloadControlHidlTest, SetUpstreamParametersInvalidIPv4GatewayFails) {
+TEST_P(OffloadControlHidlTest, SetUpstreamParametersInvalidIPv4GatewayFails) {
const hidl_string iface(TEST_IFACE);
const hidl_string v4Addr("192.0.2.2");
const vector<hidl_string> v6Gws{hidl_string("fe80::db8:1")};
@@ -570,7 +554,7 @@
}
// Test that setUpstreamParameters() fails when given unparseable IPv6 gateways.
-TEST_F(OffloadControlHidlTest, SetUpstreamParametersBadIPv6GatewaysFail) {
+TEST_P(OffloadControlHidlTest, SetUpstreamParametersBadIPv6GatewaysFail) {
const hidl_string iface(TEST_IFACE);
const hidl_string v4Addr("192.0.2.2");
const hidl_string v4Gw("192.0.2.1");
@@ -588,7 +572,7 @@
*/
// Test addDownstream() works given an IPv4 prefix.
-TEST_F(OffloadControlHidlTest, AddDownstreamIPv4) {
+TEST_P(OffloadControlHidlTest, AddDownstreamIPv4) {
const hidl_string iface("dummy0");
const hidl_string prefix("192.0.2.0/24");
const Return<void> ret = control->addDownstream(iface, prefix, ASSERT_TRUE_CALLBACK);
@@ -596,7 +580,7 @@
}
// Test addDownstream() works given an IPv6 prefix.
-TEST_F(OffloadControlHidlTest, AddDownstreamIPv6) {
+TEST_P(OffloadControlHidlTest, AddDownstreamIPv6) {
const hidl_string iface("dummy0");
const hidl_string prefix("2001:db8::/64");
const Return<void> ret = control->addDownstream(iface, prefix, ASSERT_TRUE_CALLBACK);
@@ -604,7 +588,7 @@
}
// Test addDownstream() fails given all empty parameters.
-TEST_F(OffloadControlHidlTest, AddDownstreamEmptyFails) {
+TEST_P(OffloadControlHidlTest, AddDownstreamEmptyFails) {
const hidl_string iface("");
const hidl_string prefix("");
const Return<void> ret = control->addDownstream(iface, prefix, ASSERT_FALSE_CALLBACK);
@@ -612,7 +596,7 @@
}
// Test addDownstream() fails given empty or non-existent interface names.
-TEST_F(OffloadControlHidlTest, AddDownstreamInvalidIfaceFails) {
+TEST_P(OffloadControlHidlTest, AddDownstreamInvalidIfaceFails) {
const hidl_string prefix("192.0.2.0/24");
for (const auto& bogus : {"", "invalid"}) {
SCOPED_TRACE(StringPrintf("iface='%s'", bogus));
@@ -623,7 +607,7 @@
}
// Test addDownstream() fails given unparseable prefix arguments.
-TEST_F(OffloadControlHidlTest, AddDownstreamBogusPrefixFails) {
+TEST_P(OffloadControlHidlTest, AddDownstreamBogusPrefixFails) {
const hidl_string iface("dummy0");
for (const auto& bogus : {"", "192.0.2/24", "2001:db8/64"}) {
SCOPED_TRACE(StringPrintf("prefix='%s'", bogus));
@@ -638,7 +622,7 @@
*/
// Test removeDownstream() works given an IPv4 prefix.
-TEST_F(OffloadControlHidlTest, RemoveDownstreamIPv4) {
+TEST_P(OffloadControlHidlTest, RemoveDownstreamIPv4) {
const hidl_string iface("dummy0");
const hidl_string prefix("192.0.2.0/24");
// First add the downstream, otherwise removeDownstream logic can reasonably
@@ -650,7 +634,7 @@
}
// Test removeDownstream() works given an IPv6 prefix.
-TEST_F(OffloadControlHidlTest, RemoveDownstreamIPv6) {
+TEST_P(OffloadControlHidlTest, RemoveDownstreamIPv6) {
const hidl_string iface("dummy0");
const hidl_string prefix("2001:db8::/64");
// First add the downstream, otherwise removeDownstream logic can reasonably
@@ -662,7 +646,7 @@
}
// Test removeDownstream() fails given all empty parameters.
-TEST_F(OffloadControlHidlTest, RemoveDownstreamEmptyFails) {
+TEST_P(OffloadControlHidlTest, RemoveDownstreamEmptyFails) {
const hidl_string iface("");
const hidl_string prefix("");
const Return<void> ret = control->removeDownstream(iface, prefix, ASSERT_FALSE_CALLBACK);
@@ -670,7 +654,7 @@
}
// Test removeDownstream() fails given empty or non-existent interface names.
-TEST_F(OffloadControlHidlTest, RemoveDownstreamBogusIfaceFails) {
+TEST_P(OffloadControlHidlTest, RemoveDownstreamBogusIfaceFails) {
const hidl_string prefix("192.0.2.0/24");
for (const auto& bogus : {"", "invalid"}) {
SCOPED_TRACE(StringPrintf("iface='%s'", bogus));
@@ -681,7 +665,7 @@
}
// Test removeDownstream() fails given unparseable prefix arguments.
-TEST_F(OffloadControlHidlTest, RemoveDownstreamBogusPrefixFails) {
+TEST_P(OffloadControlHidlTest, RemoveDownstreamBogusPrefixFails) {
const hidl_string iface("dummy0");
for (const auto& bogus : {"", "192.0.2/24", "2001:db8/64"}) {
SCOPED_TRACE(StringPrintf("prefix='%s'", bogus));
@@ -691,11 +675,21 @@
}
}
-int main(int argc, char** argv) {
- ::testing::AddGlobalTestEnvironment(OffloadControlHidlEnvironment::Instance());
- ::testing::InitGoogleTest(&argc, argv);
- OffloadControlHidlEnvironment::Instance()->init(&argc, argv);
- int status = RUN_ALL_TESTS();
- ALOGE("Test result with status=%d", status);
- return status;
-}
+INSTANTIATE_TEST_CASE_P(
+ PerInstance, OffloadControlHidlTestBase,
+ testing::Combine(
+ testing::ValuesIn(
+ android::hardware::getAllHalInstanceNames(IOffloadConfig::descriptor)),
+ testing::ValuesIn(
+ android::hardware::getAllHalInstanceNames(IOffloadControl::descriptor))),
+ android::hardware::PrintInstanceTupleNameToString<>);
+
+INSTANTIATE_TEST_CASE_P(
+ PerInstance, OffloadControlHidlTest,
+ testing::Combine(
+ testing::ValuesIn(
+ android::hardware::getAllHalInstanceNames(IOffloadConfig::descriptor)),
+ testing::ValuesIn(
+ android::hardware::getAllHalInstanceNames(IOffloadControl::descriptor))),
+ android::hardware::PrintInstanceTupleNameToString<>);
+
diff --git a/tv/tuner/1.0/IDemux.hal b/tv/tuner/1.0/IDemux.hal
index 9e799b4..16fc392 100644
--- a/tv/tuner/1.0/IDemux.hal
+++ b/tv/tuner/1.0/IDemux.hal
@@ -25,7 +25,6 @@
/**
* Demultiplexer(Demux) takes a single multiplexed input and splits it into
* one or more output.
- *
*/
interface IDemux {
/**
@@ -134,4 +133,30 @@
*/
openDvr(DvrType type, uint32_t bufferSize, IDvrCallback cb)
generates (Result result, IDvr dvr);
+
+ /**
+ * Connect Conditional Access Modules (CAM) through Common Interface (CI)
+ *
+ * It is used by the client to connect CI-CAM. The demux uses the output
+ * from the frontend as the input by default, and must change to use the
+ * output from CI-CAM as the input after this call take place.
+ *
+ * @param ciCamId specify CI-CAM Id to connect.
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * UNKNOWN_ERROR if failed for other reasons.
+ */
+ connectCiCam(uint32_t ciCamId) generates (Result result);
+
+ /**
+ * Disconnect Conditional Access Modules (CAM)
+ *
+ * It is used by the client to disconnect CI-CAM. The demux will use the
+ * output from the frontend as the input after this call take place.
+ *
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * UNKNOWN_ERROR if failed for other reasons.
+ */
+ disconnectCiCam() generates (Result result);
};
diff --git a/tv/tuner/1.0/IFilter.hal b/tv/tuner/1.0/IFilter.hal
index deaf3d4..94e3c0c 100644
--- a/tv/tuner/1.0/IFilter.hal
+++ b/tv/tuner/1.0/IFilter.hal
@@ -104,15 +104,30 @@
*
* It is used by the client to ask the hardware resource id for the filter.
*
- * @param filterId the hardware resource Id for the filter.
* @return result Result status of the operation.
* SUCCESS if successful,
* INVALID_STATE if failed for wrong state.
* UNKNOWN_ERROR if failed for other reasons.
+ * @return filterId the hardware resource Id for the filter.
*/
getId() generates (Result result, uint32_t filterId);
/**
+ * Release the handle reported by the HAL for AV memory.
+ *
+ * It is used by the client to notify the HAL that the AV handle won't be
+ * used any more in client side, so that the HAL can mark the memory
+ * presented by file descripor in the handle as released.
+ *
+ * @param avMemory A handle associated to the memory for audio or video.
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * INVALID_ARGUMENT if failed for wrong parameter.
+ * UNKNOWN_ERROR if failed for other reasons.
+ */
+ releaseAvHandle(handle avMemory) generates (Result result);
+
+ /**
* Set the filter's data source.
*
* A filter uses demux as data source by default. If the data was packetized
diff --git a/tv/tuner/1.0/default/Demux.cpp b/tv/tuner/1.0/default/Demux.cpp
index c5921f7..43c4e3a 100644
--- a/tv/tuner/1.0/default/Demux.cpp
+++ b/tv/tuner/1.0/default/Demux.cpp
@@ -51,7 +51,8 @@
mFrontendSourceFile = mFrontend->getSourceFile();
mTunerService->setFrontendAsDemuxSource(frontendId, mDemuxId);
- return startBroadcastInputLoop();
+
+ return startFrontendInputLoop();
}
Return<void> Demux::openFilter(const DemuxFilterType& type, uint32_t bufferSize,
@@ -136,29 +137,44 @@
return Void();
}
- sp<Dvr> dvr = new Dvr(type, bufferSize, cb, this);
+ mDvr = new Dvr(type, bufferSize, cb, this);
- if (!dvr->createDvrMQ()) {
- _hidl_cb(Result::UNKNOWN_ERROR, dvr);
+ if (!mDvr->createDvrMQ()) {
+ _hidl_cb(Result::UNKNOWN_ERROR, mDvr);
return Void();
}
- _hidl_cb(Result::SUCCESS, dvr);
+ _hidl_cb(Result::SUCCESS, mDvr);
return Void();
}
+Return<Result> Demux::connectCiCam(uint32_t ciCamId) {
+ ALOGV("%s", __FUNCTION__);
+
+ mCiCamId = ciCamId;
+
+ return Result::SUCCESS;
+}
+
+Return<Result> Demux::disconnectCiCam() {
+ ALOGV("%s", __FUNCTION__);
+
+ return Result::SUCCESS;
+}
+
Result Demux::removeFilter(uint32_t filterId) {
ALOGV("%s", __FUNCTION__);
// resetFilterRecords(filterId);
mUsedFilterIds.erase(filterId);
+ mRecordFilterIds.erase(filterId);
mUnusedFilterIds.insert(filterId);
mFilters.erase(filterId);
return Result::SUCCESS;
}
-void Demux::startTsFilter(vector<uint8_t> data) {
+void Demux::startBroadcastTsFilter(vector<uint8_t> data) {
set<uint32_t>::iterator it;
for (it = mUsedFilterIds.begin(); it != mUsedFilterIds.end(); it++) {
uint16_t pid = ((data[1] & 0x1f) << 8) | ((data[2] & 0xff));
@@ -171,7 +187,17 @@
}
}
-bool Demux::startFilterDispatcher() {
+void Demux::sendFrontendInputToRecord(vector<uint8_t> data) {
+ set<uint32_t>::iterator it;
+ for (it = mRecordFilterIds.begin(); it != mRecordFilterIds.end(); it++) {
+ if (DEBUG_FILTER) {
+ ALOGW("update record filter output");
+ }
+ mFilters[*it]->updateRecordOutput(data);
+ }
+}
+
+bool Demux::startBroadcastFilterDispatcher() {
set<uint32_t>::iterator it;
// Handle the output data per filter type
@@ -184,6 +210,18 @@
return true;
}
+bool Demux::startRecordFilterDispatcher() {
+ set<uint32_t>::iterator it;
+
+ for (it = mRecordFilterIds.begin(); it != mRecordFilterIds.end(); it++) {
+ if (mFilters[*it]->startRecordFilterHandler() != Result::SUCCESS) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
Result Demux::startFilterHandler(uint32_t filterId) {
return mFilters[filterId]->startFilterHandler();
}
@@ -196,22 +234,22 @@
return mFilters[filterId]->getTpid();
}
-Result Demux::startBroadcastInputLoop() {
- pthread_create(&mBroadcastInputThread, NULL, __threadLoopBroadcast, this);
- pthread_setname_np(mBroadcastInputThread, "broadcast_input_thread");
+Result Demux::startFrontendInputLoop() {
+ pthread_create(&mFrontendInputThread, NULL, __threadLoopFrontend, this);
+ pthread_setname_np(mFrontendInputThread, "frontend_input_thread");
return Result::SUCCESS;
}
-void* Demux::__threadLoopBroadcast(void* user) {
+void* Demux::__threadLoopFrontend(void* user) {
Demux* const self = static_cast<Demux*>(user);
- self->broadcastInputThreadLoop();
+ self->frontendInputThreadLoop();
return 0;
}
-void Demux::broadcastInputThreadLoop() {
- std::lock_guard<std::mutex> lock(mBroadcastInputThreadLock);
- mBroadcastInputThreadRunning = true;
+void Demux::frontendInputThreadLoop() {
+ std::lock_guard<std::mutex> lock(mFrontendInputThreadLock);
+ mFrontendInputThreadRunning = true;
mKeepFetchingDataFromFrontend = true;
// open the stream and get its length
@@ -220,20 +258,20 @@
int packetSize = 188;
int writePacketAmount = 6;
char* buffer = new char[packetSize];
- ALOGW("[Demux] broadcast input thread loop start %s", mFrontendSourceFile.c_str());
+ ALOGW("[Demux] Frontend input thread loop start %s", mFrontendSourceFile.c_str());
if (!inputData.is_open()) {
- mBroadcastInputThreadRunning = false;
+ mFrontendInputThreadRunning = false;
ALOGW("[Demux] Error %s", strerror(errno));
}
- while (mBroadcastInputThreadRunning) {
+ while (mFrontendInputThreadRunning) {
// move the stream pointer for packet size * 6 every read until the end
while (mKeepFetchingDataFromFrontend) {
for (int i = 0; i < writePacketAmount; i++) {
inputData.read(buffer, packetSize);
if (!inputData) {
mKeepFetchingDataFromFrontend = false;
- mBroadcastInputThreadRunning = false;
+ mFrontendInputThreadRunning = false;
break;
}
// filter and dispatch filter output
@@ -242,23 +280,61 @@
for (int index = 0; index < byteBuffer.size(); index++) {
byteBuffer[index] = static_cast<uint8_t>(buffer[index]);
}
- startTsFilter(byteBuffer);
+ if (mIsRecording) {
+ // Feed the data into the Dvr recording input
+ sendFrontendInputToRecord(byteBuffer);
+ } else {
+ // Feed the data into the broadcast demux filter
+ startBroadcastTsFilter(byteBuffer);
+ }
}
- startFilterDispatcher();
+ if (mIsRecording) {
+ // Dispatch the data into the broadcasting filters.
+ startRecordFilterDispatcher();
+ } else {
+ // Dispatch the data into the broadcasting filters.
+ startBroadcastFilterDispatcher();
+ }
usleep(100);
}
}
- ALOGW("[Demux] Broadcast Input thread end.");
+ ALOGW("[Demux] Frontend Input thread end.");
delete[] buffer;
inputData.close();
}
-void Demux::stopBroadcastInput() {
+void Demux::stopFrontendInput() {
ALOGD("[Demux] stop frontend on demux");
mKeepFetchingDataFromFrontend = false;
- mBroadcastInputThreadRunning = false;
- std::lock_guard<std::mutex> lock(mBroadcastInputThreadLock);
+ mFrontendInputThreadRunning = false;
+ std::lock_guard<std::mutex> lock(mFrontendInputThreadLock);
+}
+
+void Demux::setIsRecording(bool isRecording) {
+ mIsRecording = isRecording;
+}
+
+bool Demux::attachRecordFilter(int filterId) {
+ if (mFilters[filterId] == nullptr || mDvr == nullptr) {
+ return false;
+ }
+
+ mRecordFilterIds.insert(filterId);
+ mFilters[filterId]->attachFilterToRecord(mDvr);
+
+ return true;
+}
+
+bool Demux::detachRecordFilter(int filterId) {
+ if (mFilters[filterId] == nullptr || mDvr == nullptr) {
+ return false;
+ }
+
+ mRecordFilterIds.erase(filterId);
+ mFilters[filterId]->detachFilterFromRecord();
+
+ return true;
}
} // namespace implementation
diff --git a/tv/tuner/1.0/default/Demux.h b/tv/tuner/1.0/default/Demux.h
index a9756cc..1405d0c 100644
--- a/tv/tuner/1.0/default/Demux.h
+++ b/tv/tuner/1.0/default/Demux.h
@@ -76,12 +76,19 @@
virtual Return<void> openDvr(DvrType type, uint32_t bufferSize, const sp<IDvrCallback>& cb,
openDvr_cb _hidl_cb) override;
+ virtual Return<Result> connectCiCam(uint32_t ciCamId) override;
+
+ virtual Return<Result> disconnectCiCam() override;
+
// Functions interacts with Tuner Service
- void stopBroadcastInput();
+ void stopFrontendInput();
Result removeFilter(uint32_t filterId);
+ bool attachRecordFilter(int filterId);
+ bool detachRecordFilter(int filterId);
Result startFilterHandler(uint32_t filterId);
void updateFilterOutput(uint16_t filterId, vector<uint8_t> data);
uint16_t getFilterTpid(uint32_t filterId);
+ void setIsRecording(bool isRecording);
private:
// Tuner service
@@ -97,9 +104,9 @@
uint32_t filterId;
};
- Result startBroadcastInputLoop();
- static void* __threadLoopBroadcast(void* user);
- void broadcastInputThreadLoop();
+ Result startFrontendInputLoop();
+ static void* __threadLoopFrontend(void* user);
+ void frontendInputThreadLoop();
/**
* To create a FilterMQ with the the next available Filter ID.
@@ -113,11 +120,16 @@
/**
* A dispatcher to read and dispatch input data to all the started filters.
* Each filter handler handles the data filtering/output writing/filterEvent updating.
+ * Note that recording filters are not included.
*/
- bool startFilterDispatcher();
- void startTsFilter(vector<uint8_t> data);
+ bool startBroadcastFilterDispatcher();
+ void startBroadcastTsFilter(vector<uint8_t> data);
+
+ void sendFrontendInputToRecord(vector<uint8_t> data);
+ bool startRecordFilterDispatcher();
uint32_t mDemuxId;
+ uint32_t mCiCamId;
/**
* Record the last used filter id. Initial value is -1.
* Filter Id starts with 0.
@@ -136,26 +148,40 @@
*/
set<uint32_t> mUnusedFilterIds;
/**
+ * Record all the attached record filter Ids.
+ * Any removed filter id should be removed from this set.
+ */
+ set<uint32_t> mRecordFilterIds;
+ /**
* A list of created FilterMQ ptrs.
* The array number is the filter ID.
*/
std::map<uint32_t, sp<Filter>> mFilters;
+ /**
+ * Local reference to the opened DVR object.
+ */
+ sp<Dvr> mDvr;
+
// Thread handlers
- pthread_t mBroadcastInputThread;
+ pthread_t mFrontendInputThread;
/**
* If a specific filter's writing loop is still running
*/
- bool mBroadcastInputThreadRunning;
+ bool mFrontendInputThreadRunning;
bool mKeepFetchingDataFromFrontend;
/**
+ * If the dvr recording is running.
+ */
+ bool mIsRecording = false;
+ /**
* Lock to protect writes to the FMQs
*/
std::mutex mWriteLock;
/**
* Lock to protect writes to the input status
*/
- std::mutex mBroadcastInputThreadLock;
+ std::mutex mFrontendInputThreadLock;
// temp handle single PES filter
// TODO handle mulptiple Pes filters
diff --git a/tv/tuner/1.0/default/Dvr.cpp b/tv/tuner/1.0/default/Dvr.cpp
index eb38f90..3088a9d 100644
--- a/tv/tuner/1.0/default/Dvr.cpp
+++ b/tv/tuner/1.0/default/Dvr.cpp
@@ -70,7 +70,14 @@
return status;
}
+ // check if the attached filter is a record filter
+
mFilters[filterId] = filter;
+ mIsRecordFilterAttached = true;
+ if (!mDemux->attachRecordFilter(filterId)) {
+ return Result::INVALID_ARGUMENT;
+ }
+ mDemux->setIsRecording(mIsRecordStarted | mIsRecordFilterAttached);
return Result::SUCCESS;
}
@@ -95,6 +102,15 @@
it = mFilters.find(filterId);
if (it != mFilters.end()) {
mFilters.erase(filterId);
+ if (!mDemux->detachRecordFilter(filterId)) {
+ return Result::INVALID_ARGUMENT;
+ }
+ }
+
+ // If all the filters are detached, record can't be started
+ if (mFilters.empty()) {
+ mIsRecordFilterAttached = false;
+ mDemux->setIsRecording(mIsRecordStarted | mIsRecordFilterAttached);
}
return Result::SUCCESS;
@@ -115,8 +131,9 @@
pthread_create(&mDvrThread, NULL, __threadLoopPlayback, this);
pthread_setname_np(mDvrThread, "playback_waiting_loop");
} else if (mType == DvrType::RECORD) {
- /*pthread_create(&mInputThread, NULL, __threadLoopInput, this);
- pthread_setname_np(mInputThread, "playback_waiting_loop");*/
+ mRecordStatus = RecordStatus::DATA_READY;
+ mIsRecordStarted = true;
+ mDemux->setIsRecording(mIsRecordStarted | mIsRecordFilterAttached);
}
// TODO start another thread to send filter status callback to the framework
@@ -131,12 +148,17 @@
std::lock_guard<std::mutex> lock(mDvrThreadLock);
+ mIsRecordStarted = false;
+ mDemux->setIsRecording(mIsRecordStarted | mIsRecordFilterAttached);
+
return Result::SUCCESS;
}
Return<Result> Dvr::flush() {
ALOGV("%s", __FUNCTION__);
+ mRecordStatus = RecordStatus::DATA_READY;
+
return Result::SUCCESS;
}
@@ -272,6 +294,45 @@
return true;
}
+bool Dvr::writeRecordFMQ(const std::vector<uint8_t>& data) {
+ std::lock_guard<std::mutex> lock(mWriteLock);
+ ALOGW("[Dvr] write record FMQ");
+ if (mDvrMQ->write(data.data(), data.size())) {
+ mDvrEventFlag->wake(static_cast<uint32_t>(DemuxQueueNotifyBits::DATA_READY));
+ maySendRecordStatusCallback();
+ return true;
+ }
+
+ maySendRecordStatusCallback();
+ return false;
+}
+
+void Dvr::maySendRecordStatusCallback() {
+ std::lock_guard<std::mutex> lock(mRecordStatusLock);
+ int availableToRead = mDvrMQ->availableToRead();
+ int availableToWrite = mDvrMQ->availableToWrite();
+
+ RecordStatus newStatus = checkRecordStatusChange(availableToWrite, availableToRead,
+ mDvrSettings.record().highThreshold,
+ mDvrSettings.record().lowThreshold);
+ if (mRecordStatus != newStatus) {
+ mCallback->onRecordStatus(newStatus);
+ mRecordStatus = newStatus;
+ }
+}
+
+RecordStatus Dvr::checkRecordStatusChange(uint32_t availableToWrite, uint32_t availableToRead,
+ uint32_t highThreshold, uint32_t lowThreshold) {
+ if (availableToWrite == 0) {
+ return DemuxFilterStatus::OVERFLOW;
+ } else if (availableToRead > highThreshold) {
+ return DemuxFilterStatus::HIGH_WATER;
+ } else if (availableToRead < lowThreshold) {
+ return DemuxFilterStatus::LOW_WATER;
+ }
+ return mRecordStatus;
+}
+
} // namespace implementation
} // namespace V1_0
} // namespace tuner
diff --git a/tv/tuner/1.0/default/Dvr.h b/tv/tuner/1.0/default/Dvr.h
index fbb778c..f39d8db 100644
--- a/tv/tuner/1.0/default/Dvr.h
+++ b/tv/tuner/1.0/default/Dvr.h
@@ -79,6 +79,8 @@
* Return false is any of the above processes fails.
*/
bool createDvrMQ();
+ void sendBroadcastInputToDvrRecord(vector<uint8_t> byteBuffer);
+ bool writeRecordFMQ(const std::vector<uint8_t>& data);
private:
// Demux service
@@ -95,6 +97,8 @@
void maySendRecordStatusCallback();
PlaybackStatus checkPlaybackStatusChange(uint32_t availableToWrite, uint32_t availableToRead,
uint32_t highThreshold, uint32_t lowThreshold);
+ RecordStatus checkRecordStatusChange(uint32_t availableToWrite, uint32_t availableToRead,
+ uint32_t highThreshold, uint32_t lowThreshold);
/**
* A dispatcher to read and dispatch input data to all the started filters.
* Each filter handler handles the data filtering/output writing/filterEvent updating.
@@ -103,9 +107,9 @@
void startTpidFilter(vector<uint8_t> data);
bool startFilterDispatcher();
static void* __threadLoopPlayback(void* user);
- static void* __threadLoopBroadcast(void* user);
+ static void* __threadLoopRecord(void* user);
void playbackThreadLoop();
- void broadcastInputThreadLoop();
+ void recordThreadLoop();
unique_ptr<DvrMQ> mDvrMQ;
EventFlag* mDvrEventFlag;
@@ -121,6 +125,7 @@
// FMQ status local records
PlaybackStatus mPlaybackStatus;
+ RecordStatus mRecordStatus;
/**
* If a specific filter's writing loop is still running
*/
@@ -135,10 +140,16 @@
* Lock to protect writes to the input status
*/
std::mutex mPlaybackStatusLock;
+ std::mutex mRecordStatusLock;
std::mutex mBroadcastInputThreadLock;
std::mutex mDvrThreadLock;
const bool DEBUG_DVR = false;
+
+ // Booleans to check if recording is running.
+ // Recording is ready when both of the following are set to true.
+ bool mIsRecordStarted = false;
+ bool mIsRecordFilterAttached = false;
};
} // namespace implementation
diff --git a/tv/tuner/1.0/default/Filter.cpp b/tv/tuner/1.0/default/Filter.cpp
index 3d8a977..b3160fc 100644
--- a/tv/tuner/1.0/default/Filter.cpp
+++ b/tv/tuner/1.0/default/Filter.cpp
@@ -120,6 +120,12 @@
return Result::SUCCESS;
}
+Return<Result> Filter::releaseAvHandle(const hidl_handle& /*avMemory*/) {
+ ALOGV("%s", __FUNCTION__);
+
+ return Result::SUCCESS;
+}
+
Return<Result> Filter::close() {
ALOGV("%s", __FUNCTION__);
@@ -259,10 +265,16 @@
void Filter::updateFilterOutput(vector<uint8_t> data) {
std::lock_guard<std::mutex> lock(mFilterOutputLock);
- ALOGD("[Filter] handler output updated");
+ ALOGD("[Filter] filter output updated");
mFilterOutput.insert(mFilterOutput.end(), data.begin(), data.end());
}
+void Filter::updateRecordOutput(vector<uint8_t> data) {
+ std::lock_guard<std::mutex> lock(mRecordFilterOutputLock);
+ ALOGD("[Filter] record filter output updated");
+ mRecordFilterOutput.insert(mRecordFilterOutput.end(), data.begin(), data.end());
+}
+
Result Filter::startFilterHandler() {
std::lock_guard<std::mutex> lock(mFilterOutputLock);
switch (mType.mainType) {
@@ -286,8 +298,10 @@
case DemuxTsFilterType::PCR:
startPcrFilterHandler();
break;
- case DemuxTsFilterType::RECORD:
- startRecordFilterHandler();
+ case DemuxTsFilterType::TEMI:
+ startTemiFilterHandler();
+ break;
+ default:
break;
}
break;
@@ -333,12 +347,16 @@
if (mPesSizeLeft == 0) {
uint32_t prefix = (mFilterOutput[i + 4] << 16) | (mFilterOutput[i + 5] << 8) |
mFilterOutput[i + 6];
- ALOGD("[Filter] prefix %d", prefix);
+ if (DEBUG_FILTER) {
+ ALOGD("[Filter] prefix %d", prefix);
+ }
if (prefix == 0x000001) {
// TODO handle mulptiple Pes filters
mPesSizeLeft = (mFilterOutput[i + 8] << 8) | mFilterOutput[i + 9];
mPesSizeLeft += 6;
- ALOGD("[Filter] pes data length %d", mPesSizeLeft);
+ if (DEBUG_FILTER) {
+ ALOGD("[Filter] pes data length %d", mPesSizeLeft);
+ }
} else {
continue;
}
@@ -351,7 +369,9 @@
mPesOutput.insert(mPesOutput.end(), first, last);
// size does not match then continue
mPesSizeLeft -= endPoint;
- ALOGD("[Filter] pes data left %d", mPesSizeLeft);
+ if (DEBUG_FILTER) {
+ ALOGD("[Filter] pes data left %d", mPesSizeLeft);
+ }
if (mPesSizeLeft > 0) {
continue;
}
@@ -368,7 +388,9 @@
.streamId = mPesOutput[3],
.dataLength = static_cast<uint16_t>(mPesOutput.size()),
};
- ALOGD("[Filter] assembled pes data length %d", pesEvent.dataLength);
+ if (DEBUG_FILTER) {
+ ALOGD("[Filter] assembled pes data length %d", pesEvent.dataLength);
+ }
int size = mFilterEvent.events.size();
mFilterEvent.events.resize(size + 1);
@@ -404,13 +426,23 @@
}
Result Filter::startRecordFilterHandler() {
- DemuxFilterTsRecordEvent tsRecordEvent;
+ /*DemuxFilterTsRecordEvent tsRecordEvent;
tsRecordEvent.pid.tPid(0);
tsRecordEvent.indexMask.tsIndexMask(0x01);
mFilterEvent.events.resize(1);
mFilterEvent.events[0].tsRecord(tsRecordEvent);
+*/
+ std::lock_guard<std::mutex> lock(mRecordFilterOutputLock);
+ if (mRecordFilterOutput.empty()) {
+ return Result::SUCCESS;
+ }
- mFilterOutput.clear();
+ if (mDvr == nullptr || !mDvr->writeRecordFMQ(mRecordFilterOutput)) {
+ ALOGD("[Filter] dvr fails to write into record FMQ.");
+ return Result::UNKNOWN_ERROR;
+ }
+
+ mRecordFilterOutput.clear();
return Result::SUCCESS;
}
@@ -419,6 +451,11 @@
return Result::SUCCESS;
}
+Result Filter::startTemiFilterHandler() {
+ // TODO handle starting TEMI filter
+ return Result::SUCCESS;
+}
+
bool Filter::writeSectionsAndCreateEvent(vector<uint8_t> data) {
// TODO check how many sections has been read
ALOGD("[Filter] section hander");
@@ -448,9 +485,17 @@
return false;
}
+void Filter::attachFilterToRecord(const sp<Dvr> dvr) {
+ mDvr = dvr;
+}
+
+void Filter::detachFilterFromRecord() {
+ mDvr = nullptr;
+}
+
} // namespace implementation
} // namespace V1_0
} // namespace tuner
} // namespace tv
} // namespace hardware
-} // namespace android
\ No newline at end of file
+} // namespace android
diff --git a/tv/tuner/1.0/default/Filter.h b/tv/tuner/1.0/default/Filter.h
index 21d4297..d397f73 100644
--- a/tv/tuner/1.0/default/Filter.h
+++ b/tv/tuner/1.0/default/Filter.h
@@ -22,6 +22,7 @@
#include <math.h>
#include <set>
#include "Demux.h"
+#include "Dvr.h"
#include "Frontend.h"
using namespace std;
@@ -44,6 +45,7 @@
using FilterMQ = MessageQueue<uint8_t, kSynchronizedReadWrite>;
class Demux;
+class Dvr;
class Filter : public IFilter {
public:
@@ -68,6 +70,8 @@
virtual Return<Result> flush() override;
+ virtual Return<Result> releaseAvHandle(const hidl_handle& avMemory) override;
+
virtual Return<Result> close() override;
/**
@@ -78,11 +82,17 @@
bool createFilterMQ();
uint16_t getTpid();
void updateFilterOutput(vector<uint8_t> data);
+ void updateRecordOutput(vector<uint8_t> data);
Result startFilterHandler();
+ Result startRecordFilterHandler();
+ void attachFilterToRecord(const sp<Dvr> dvr);
+ void detachFilterFromRecord();
private:
// Tuner service
sp<Demux> mDemux;
+ // Dvr reference once the filter is attached to any
+ sp<Dvr> mDvr = nullptr;
/**
* Filter callbacks used on filter events or FMQ status
*/
@@ -97,6 +107,7 @@
sp<IFilter> mDataSource;
bool mIsDataSourceDemux = true;
vector<uint8_t> mFilterOutput;
+ vector<uint8_t> mRecordFilterOutput;
unique_ptr<FilterMQ> mFilterMQ;
EventFlag* mFilterEventFlag;
DemuxFilterEvent mFilterEvent;
@@ -118,6 +129,8 @@
*/
const uint16_t SECTION_WRITE_COUNT = 10;
+ bool DEBUG_FILTER = false;
+
/**
* Filter handlers to handle the data filtering.
* They are also responsible to write the filtered output into the filter FMQ
@@ -127,8 +140,8 @@
Result startPesFilterHandler();
Result startTsFilterHandler();
Result startMediaFilterHandler();
- Result startRecordFilterHandler();
Result startPcrFilterHandler();
+ Result startTemiFilterHandler();
Result startFilterLoop();
void deleteEventFlag();
@@ -162,6 +175,7 @@
std::mutex mFilterStatusLock;
std::mutex mFilterThreadLock;
std::mutex mFilterOutputLock;
+ std::mutex mRecordFilterOutputLock;
// temp handle single PES filter
// TODO handle mulptiple Pes filters
@@ -176,4 +190,4 @@
} // namespace hardware
} // namespace android
-#endif // ANDROID_HARDWARE_TV_TUNER_V1_0_FILTER_H_
\ No newline at end of file
+#endif // ANDROID_HARDWARE_TV_TUNER_V1_0_FILTER_H_
diff --git a/tv/tuner/1.0/default/Tuner.cpp b/tv/tuner/1.0/default/Tuner.cpp
index f86b28d..c143d61 100644
--- a/tv/tuner/1.0/default/Tuner.cpp
+++ b/tv/tuner/1.0/default/Tuner.cpp
@@ -148,7 +148,7 @@
uint32_t demuxId;
if (it != mFrontendToDemux.end()) {
demuxId = it->second;
- mDemuxes[demuxId]->stopBroadcastInput();
+ mDemuxes[demuxId]->stopFrontendInput();
}
}
diff --git a/tv/tuner/1.0/types.hal b/tv/tuner/1.0/types.hal
index fa00a6e..1dea04e 100644
--- a/tv/tuner/1.0/types.hal
+++ b/tv/tuner/1.0/types.hal
@@ -1759,6 +1759,12 @@
* buffer of the record.
*/
RECORD,
+ /**
+ * A filter to filter out Timed External Media Information (TEMI) according
+ * to ISO/IEC 13818-1:2013/ DAM 6 from input stream, and send TEMI event to
+ * client through onFilterEvent.
+ */
+ TEMI,
};
/**
@@ -2170,7 +2176,8 @@
safe_union FilterSettings {
/**
- * Not additional parameters. it's used by PCR, TS subtype filters.
+ * Not additional parameters. it's used by PCR, TS, TEMI subtype
+ * filters.
*/
Monostate noinit;
@@ -2223,8 +2230,6 @@
DemuxFilterSectionSettings section;
- DemuxFilterPesDataSettings pesData;
-
/**
* true if the data from IP subtype go to next filter directly
*/
@@ -2241,7 +2246,7 @@
/**
* true if the filtered data is commpressed ip packet
*/
- bool bIsCompressedIpPacket;
+ bool isCompressedIpPacket;
safe_union FilterSettings {
/**
@@ -2461,6 +2466,27 @@
};
/**
+ * Filter Event for Timed External Media Information (TEMI) data.
+ */
+struct DemuxFilterTemiEvent {
+ /**
+ * Presentation Time Stamp for audio or video frame. It based on 90KHz has
+ * the same format as PTS (Presentation Time Stamp) in ISO/IEC 13818-1.
+ */
+ uint64_t pts;
+
+ /**
+ * TEMI Descriptor Tag
+ */
+ uint8_t descrTag;
+
+ /**
+ * TEMI Descriptor
+ */
+ vec<uint8_t> descrData;
+};
+
+/**
* Filter Event for MMTP Record data.
*/
struct DemuxFilterMmtpRecordEvent {
@@ -2521,6 +2547,8 @@
DemuxFilterDownloadEvent download;
DemuxFilterIpPayloadEvent ipPayload;
+
+ DemuxFilterTemiEvent temi;
};
/**
diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp
index c666226..7977f25 100644
--- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp
+++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp
@@ -65,6 +65,7 @@
using android::hardware::tv::tuner::V1_0::DemuxFilterMainType;
using android::hardware::tv::tuner::V1_0::DemuxFilterPesDataSettings;
using android::hardware::tv::tuner::V1_0::DemuxFilterPesEvent;
+using android::hardware::tv::tuner::V1_0::DemuxFilterRecordSettings;
using android::hardware::tv::tuner::V1_0::DemuxFilterSectionEvent;
using android::hardware::tv::tuner::V1_0::DemuxFilterSectionSettings;
using android::hardware::tv::tuner::V1_0::DemuxFilterSettings;
@@ -95,6 +96,7 @@
using android::hardware::tv::tuner::V1_0::ITuner;
using android::hardware::tv::tuner::V1_0::PlaybackSettings;
using android::hardware::tv::tuner::V1_0::PlaybackStatus;
+using android::hardware::tv::tuner::V1_0::RecordSettings;
using android::hardware::tv::tuner::V1_0::RecordStatus;
using android::hardware::tv::tuner::V1_0::Result;
@@ -159,6 +161,7 @@
RECORD,
MMTPRECORD,
DOWNLOAD,
+ TEMI,
};
struct PlaybackConf {
@@ -378,7 +381,20 @@
class DvrCallback : public IDvrCallback {
public:
- virtual Return<void> onRecordStatus(RecordStatus /*status*/) override { return Void(); }
+ virtual Return<void> onRecordStatus(DemuxFilterStatus status) override {
+ ALOGW("[vts] record status %hhu", status);
+ switch (status) {
+ case DemuxFilterStatus::DATA_READY:
+ break;
+ case DemuxFilterStatus::LOW_WATER:
+ break;
+ case DemuxFilterStatus::HIGH_WATER:
+ case DemuxFilterStatus::OVERFLOW:
+ ALOGW("[vts] record overflow. Flushing");
+ break;
+ }
+ return Void();
+ }
virtual Return<void> onPlaybackStatus(PlaybackStatus status) override {
// android::Mutex::Autolock autoLock(mMsgLock);
@@ -400,10 +416,17 @@
void testFilterDataOutput();
void stopPlaybackThread();
+ void testRecordOutput();
+ void stopRecordThread();
void startPlaybackInputThread(PlaybackConf playbackConf, MQDesc& playbackMQDescriptor);
+ void startRecordOutputThread(RecordSettings recordSetting, MQDesc& recordMQDescriptor);
static void* __threadLoopPlayback(void* threadArgs);
+ static void* __threadLoopRecord(void* threadArgs);
void playbackThreadLoop(PlaybackConf* playbackConf, bool* keepWritingPlaybackFMQ);
+ void recordThreadLoop(RecordSettings* recordSetting, bool* keepWritingPlaybackFMQ);
+
+ bool readRecordFMQ();
private:
struct PlaybackThreadArgs {
@@ -411,22 +434,31 @@
PlaybackConf* playbackConf;
bool* keepWritingPlaybackFMQ;
};
+ struct RecordThreadArgs {
+ DvrCallback* user;
+ RecordSettings* recordSetting;
+ bool* keepReadingRecordFMQ;
+ };
uint16_t mDataLength = 0;
std::vector<uint8_t> mDataOutputBuffer;
std::map<uint32_t, std::unique_ptr<FilterMQ>> mFilterIdToMQ;
std::unique_ptr<FilterMQ> mPlaybackMQ;
+ std::unique_ptr<FilterMQ> mRecordMQ;
std::map<uint32_t, EventFlag*> mFilterIdToMQEventFlag;
std::map<uint32_t, DemuxFilterEvent> mFilterIdToEvent;
- EventFlag* mPlaybackMQEventFlag;
android::Mutex mMsgLock;
android::Mutex mPlaybackThreadLock;
+ android::Mutex mRecordThreadLock;
android::Condition mMsgCondition;
bool mKeepWritingPlaybackFMQ = true;
+ bool mKeepReadingRecordFMQ = true;
bool mPlaybackThreadRunning;
+ bool mRecordThreadRunning;
pthread_t mPlaybackThread;
+ pthread_t mRecordThread;
int mPidFilterOutputCount = 0;
};
@@ -515,6 +547,92 @@
inputData.close();
}
+void DvrCallback::testRecordOutput() {
+ android::Mutex::Autolock autoLock(mMsgLock);
+ while (mDataOutputBuffer.empty()) {
+ if (-ETIMEDOUT == mMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) {
+ EXPECT_TRUE(false) << "record output matching pid does not output within timeout";
+ return;
+ }
+ }
+ stopRecordThread();
+ ALOGW("[vts] record pass and stop");
+}
+
+void DvrCallback::startRecordOutputThread(RecordSettings recordSetting,
+ MQDesc& recordMQDescriptor) {
+ mRecordMQ = std::make_unique<FilterMQ>(recordMQDescriptor, true /* resetPointers */);
+ EXPECT_TRUE(mRecordMQ);
+ struct RecordThreadArgs* threadArgs =
+ (struct RecordThreadArgs*)malloc(sizeof(struct RecordThreadArgs));
+ threadArgs->user = this;
+ threadArgs->recordSetting = &recordSetting;
+ threadArgs->keepReadingRecordFMQ = &mKeepReadingRecordFMQ;
+
+ pthread_create(&mRecordThread, NULL, __threadLoopRecord, (void*)threadArgs);
+ pthread_setname_np(mRecordThread, "test_record_input_loop");
+}
+
+void* DvrCallback::__threadLoopRecord(void* threadArgs) {
+ DvrCallback* const self =
+ static_cast<DvrCallback*>(((struct RecordThreadArgs*)threadArgs)->user);
+ self->recordThreadLoop(((struct RecordThreadArgs*)threadArgs)->recordSetting,
+ ((struct RecordThreadArgs*)threadArgs)->keepReadingRecordFMQ);
+ return 0;
+}
+
+void DvrCallback::recordThreadLoop(RecordSettings* /*recordSetting*/, bool* keepReadingRecordFMQ) {
+ ALOGD("[vts] DvrCallback record threadLoop start.");
+ android::Mutex::Autolock autoLock(mRecordThreadLock);
+ mRecordThreadRunning = true;
+
+ // Create the EventFlag that is used to signal the HAL impl that data have been
+ // read from the Record FMQ
+ EventFlag* recordMQEventFlag;
+ EXPECT_TRUE(EventFlag::createEventFlag(mRecordMQ->getEventFlagWord(), &recordMQEventFlag) ==
+ android::OK);
+
+ while (mRecordThreadRunning) {
+ while (*keepReadingRecordFMQ) {
+ uint32_t efState = 0;
+ android::status_t status = recordMQEventFlag->wait(
+ static_cast<uint32_t>(DemuxQueueNotifyBits::DATA_READY), &efState, WAIT_TIMEOUT,
+ true /* retry on spurious wake */);
+ if (status != android::OK) {
+ ALOGD("[vts] wait for data ready on the record FMQ");
+ continue;
+ }
+ // Our current implementation filter the data and write it into the filter FMQ
+ // immediately after the DATA_READY from the VTS/framework
+ if (!readRecordFMQ()) {
+ ALOGD("[vts] record data failed to be filtered. Ending thread");
+ mRecordThreadRunning = false;
+ break;
+ }
+ }
+ }
+
+ mRecordThreadRunning = false;
+ ALOGD("[vts] record thread ended.");
+}
+
+bool DvrCallback::readRecordFMQ() {
+ android::Mutex::Autolock autoLock(mMsgLock);
+ bool result = false;
+ mDataOutputBuffer.clear();
+ mDataOutputBuffer.resize(mRecordMQ->availableToRead());
+ result = mRecordMQ->read(mDataOutputBuffer.data(), mRecordMQ->availableToRead());
+ EXPECT_TRUE(result) << "can't read from Record MQ";
+ mMsgCondition.signal();
+ return result;
+}
+
+void DvrCallback::stopRecordThread() {
+ mKeepReadingRecordFMQ = false;
+ mRecordThreadRunning = false;
+ android::Mutex::Autolock autoLock(mRecordThreadLock);
+}
+
// Test environment for Tuner HIDL HAL.
class TunerHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
public:
@@ -554,6 +672,7 @@
sp<DvrCallback> mDvrCallback;
MQDesc mFilterMQDescriptor;
MQDesc mPlaybackMQDescriptor;
+ MQDesc mRecordMQDescriptor;
vector<uint32_t> mUsedFilterIds;
uint32_t mDemuxId;
@@ -571,6 +690,8 @@
FrontendSettings settings);
::testing::AssertionResult getPlaybackMQDescriptor();
::testing::AssertionResult addPlaybackToDemux(PlaybackSettings setting);
+ ::testing::AssertionResult getRecordMQDescriptor();
+ ::testing::AssertionResult addRecordToDemux(RecordSettings setting);
::testing::AssertionResult addFilterToDemux(DemuxFilterType type, DemuxFilterSettings setting);
::testing::AssertionResult getFilterMQDescriptor();
::testing::AssertionResult closeDemux();
@@ -580,6 +701,9 @@
::testing::AssertionResult playbackDataFlowTest(vector<FilterConf> filterConf,
PlaybackConf playbackConf,
vector<string> goldenOutputFiles);
+ ::testing::AssertionResult recordDataFlowTest(vector<FilterConf> filterConf,
+ RecordSettings recordSetting,
+ vector<string> goldenOutputFiles);
::testing::AssertionResult broadcastDataFlowTest(vector<FilterConf> filterConf,
vector<string> goldenOutputFiles);
};
@@ -765,6 +889,49 @@
return ::testing::AssertionResult(status == Result::SUCCESS);
}
+::testing::AssertionResult TunerHidlTest::addRecordToDemux(RecordSettings setting) {
+ Result status;
+
+ if (!mDemux && createDemux() == ::testing::AssertionFailure()) {
+ return ::testing::AssertionFailure();
+ }
+
+ // Create dvr callback
+ mDvrCallback = new DvrCallback();
+
+ // Add playback input to the local demux
+ mDemux->openDvr(DvrType::RECORD, FMQ_SIZE_1M, mDvrCallback,
+ [&](Result result, const sp<IDvr>& dvr) {
+ mDvr = dvr;
+ status = result;
+ });
+
+ if (status != Result::SUCCESS) {
+ return ::testing::AssertionFailure();
+ }
+
+ DvrSettings dvrSetting;
+ dvrSetting.record(setting);
+ status = mDvr->configure(dvrSetting);
+
+ return ::testing::AssertionResult(status == Result::SUCCESS);
+}
+
+::testing::AssertionResult TunerHidlTest::getRecordMQDescriptor() {
+ Result status;
+
+ if ((!mDemux && createDemux() == ::testing::AssertionFailure()) || !mDvr) {
+ return ::testing::AssertionFailure();
+ }
+
+ mDvr->getQueueDesc([&](Result result, const MQDesc& dvrMQDesc) {
+ mRecordMQDescriptor = dvrMQDesc;
+ status = result;
+ });
+
+ return ::testing::AssertionResult(status == Result::SUCCESS);
+}
+
::testing::AssertionResult TunerHidlTest::addFilterToDemux(DemuxFilterType type,
DemuxFilterSettings setting) {
Result status;
@@ -821,6 +988,9 @@
case DemuxTsFilterType::RECORD:
eventType = FilterEventType::RECORD;
break;
+ case DemuxTsFilterType::TEMI:
+ eventType = FilterEventType::TEMI;
+ break;
}
break;
case DemuxFilterMainType::MMTP:
@@ -993,6 +1163,82 @@
return closeDemux();
}
+::testing::AssertionResult TunerHidlTest::recordDataFlowTest(vector<FilterConf> filterConf,
+ RecordSettings recordSetting,
+ vector<string> /*goldenOutputFiles*/) {
+ Result status;
+ hidl_vec<FrontendId> feIds;
+
+ mService->getFrontendIds([&](Result result, const hidl_vec<FrontendId>& frontendIds) {
+ status = result;
+ feIds = frontendIds;
+ });
+
+ if (feIds.size() == 0) {
+ ALOGW("[ WARN ] Frontend isn't available");
+ return ::testing::AssertionFailure();
+ }
+
+ FrontendDvbtSettings dvbt{
+ .frequency = 1000,
+ };
+ FrontendSettings settings;
+ settings.dvbt(dvbt);
+
+ int filterIdsSize;
+ // Filter Configuration Module
+ for (int i = 0; i < filterConf.size(); i++) {
+ if (addFilterToDemux(filterConf[i].type, filterConf[i].setting) ==
+ ::testing::AssertionFailure() ||
+ // TODO use a map to save the FMQs/EvenFlags and pass to callback
+ getFilterMQDescriptor() == ::testing::AssertionFailure()) {
+ return ::testing::AssertionFailure();
+ }
+ filterIdsSize = mUsedFilterIds.size();
+ mUsedFilterIds.resize(filterIdsSize + 1);
+ mUsedFilterIds[filterIdsSize] = mFilterId;
+ mFilters[mFilterId] = mFilter;
+ }
+
+ // Record Config Module
+ if (addRecordToDemux(recordSetting) == ::testing::AssertionFailure() ||
+ getRecordMQDescriptor() == ::testing::AssertionFailure()) {
+ return ::testing::AssertionFailure();
+ }
+ for (int i = 0; i <= filterIdsSize; i++) {
+ if (mDvr->attachFilter(mFilters[mUsedFilterIds[i]]) != Result::SUCCESS) {
+ return ::testing::AssertionFailure();
+ }
+ }
+
+ mDvrCallback->startRecordOutputThread(recordSetting, mRecordMQDescriptor);
+ status = mDvr->start();
+ if (status != Result::SUCCESS) {
+ return ::testing::AssertionFailure();
+ }
+
+ if (createDemuxWithFrontend(feIds[0], settings) != ::testing::AssertionSuccess()) {
+ return ::testing::AssertionFailure();
+ }
+
+ // Data Verify Module
+ mDvrCallback->testRecordOutput();
+
+ // Clean Up Module
+ for (int i = 0; i <= filterIdsSize; i++) {
+ if (mFilters[mUsedFilterIds[i]]->stop() != Result::SUCCESS) {
+ return ::testing::AssertionFailure();
+ }
+ }
+ if (mFrontend->stopTune() != Result::SUCCESS) {
+ return ::testing::AssertionFailure();
+ }
+ mUsedFilterIds.clear();
+ mFilterCallbacks.clear();
+ mFilters.clear();
+ return closeDemux();
+}
+
/*
* API STATUS TESTS
*/
@@ -1199,6 +1445,44 @@
ASSERT_TRUE(broadcastDataFlowTest(filterConf, goldenOutputFiles));
}
+TEST_F(TunerHidlTest, RecordDataFlowWithTsRecordFilterTest) {
+ description("Feed ts data from frontend to recording and test with ts record filter");
+
+ // todo modulize the filter conf parser
+ vector<FilterConf> filterConf;
+ filterConf.resize(1);
+
+ DemuxFilterSettings filterSetting;
+ DemuxTsFilterSettings tsFilterSetting{
+ .tpid = 119,
+ };
+ DemuxFilterRecordSettings recordFilterSetting;
+ tsFilterSetting.filterSettings.record(recordFilterSetting);
+ filterSetting.ts(tsFilterSetting);
+
+ DemuxFilterType type{
+ .mainType = DemuxFilterMainType::TS,
+ };
+ type.subType.tsFilterType(DemuxTsFilterType::RECORD);
+ FilterConf recordFilterConf{
+ .type = type,
+ .setting = filterSetting,
+ };
+ filterConf[0] = recordFilterConf;
+
+ RecordSettings recordSetting{
+ .statusMask = 0xf,
+ .lowThreshold = 0x1000,
+ .highThreshold = 0x07fff,
+ .dataFormat = DataFormat::TS,
+ .packetSize = 188,
+ };
+
+ vector<string> goldenOutputFiles;
+
+ ASSERT_TRUE(recordDataFlowTest(filterConf, recordSetting, goldenOutputFiles));
+}
+
} // namespace
int main(int argc, char** argv) {
diff --git a/usb/1.0/vts/functional/Android.bp b/usb/1.0/vts/functional/Android.bp
index 683ee17..1a3b56b 100644
--- a/usb/1.0/vts/functional/Android.bp
+++ b/usb/1.0/vts/functional/Android.bp
@@ -19,5 +19,5 @@
defaults: ["VtsHalTargetTestDefaults"],
srcs: ["VtsHalUsbV1_0TargetTest.cpp"],
static_libs: ["android.hardware.usb@1.0"],
- test_suites: ["general-tests"],
+ test_suites: ["general-tests", "vts-core"],
}
diff --git a/usb/1.0/vts/functional/VtsHalUsbV1_0TargetTest.cpp b/usb/1.0/vts/functional/VtsHalUsbV1_0TargetTest.cpp
index ee7ef1b..bba75c8 100644
--- a/usb/1.0/vts/functional/VtsHalUsbV1_0TargetTest.cpp
+++ b/usb/1.0/vts/functional/VtsHalUsbV1_0TargetTest.cpp
@@ -20,9 +20,10 @@
#include <android/hardware/usb/1.0/IUsb.h>
#include <android/hardware/usb/1.0/IUsbCallback.h>
#include <android/hardware/usb/1.0/types.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
#include <log/log.h>
#include <stdlib.h>
#include <chrono>
@@ -49,20 +50,8 @@
using ::android::hardware::Void;
using ::android::sp;
-// Test environment for Usb HIDL HAL.
-class UsbHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static UsbHidlEnvironment* Instance() {
- static UsbHidlEnvironment* instance = new UsbHidlEnvironment;
- return instance;
- }
-
- virtual void registerTestServices() override { registerTestService<IUsb>(); }
-};
-
// The main test class for the USB hidl HAL
-class UsbHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+class UsbHidlTest : public testing::TestWithParam<std::string> {
public:
// Callback class for the USB HIDL hal.
// Usb Hal will call this object upon role switch or port query.
@@ -109,8 +98,7 @@
virtual void SetUp() override {
ALOGI("Setup");
- usb = ::testing::VtsHalHidlTargetTestBase::getService<IUsb>(
- UsbHidlEnvironment::Instance()->getServiceName<IUsb>());
+ usb = IUsb::getService(GetParam());
ASSERT_NE(usb, nullptr);
usb_cb_2 = new UsbCallback(*this, 2);
@@ -182,7 +170,7 @@
* Callback oject is created and registered.
* Check to see if the hidl transaction succeeded.
*/
-TEST_F(UsbHidlTest, setCallback) {
+TEST_P(UsbHidlTest, setCallback) {
usb_cb_1 = new UsbCallback(*this, 1);
ASSERT_NE(usb_cb_1, nullptr);
Return<void> ret = usb->setCallback(usb_cb_1);
@@ -193,7 +181,7 @@
* Check to see if querying type-c
* port status succeeds.
*/
-TEST_F(UsbHidlTest, queryPortStatus) {
+TEST_P(UsbHidlTest, queryPortStatus) {
Return<void> ret = usb->queryPortStatus();
ASSERT_TRUE(ret.isOk());
EXPECT_EQ(std::cv_status::no_timeout, wait());
@@ -206,7 +194,7 @@
* This test case tried to switch the port with empty
* name which is expected to fail.
*/
-TEST_F(UsbHidlTest, switchEmptyPort) {
+TEST_P(UsbHidlTest, switchEmptyPort) {
struct PortRole role;
role.type = PortRoleType::DATA_ROLE;
@@ -218,52 +206,6 @@
}
/*
- * Test switching the mode of usb port.
- * Test case queries the usb ports present in device.
- * If there is atleast one usb port, a mode switch
- * to DFP is attempted for the port.
- * The callback parametes are checked to see if the mode
- * switch was successfull. Upon success, Status::SUCCESS
- * is expected to be returned.
- */
-TEST_F(UsbHidlTest, switchModetoDFP) {
- struct PortRole role;
- role.type = PortRoleType::MODE;
- role.role = static_cast<uint32_t>(PortMode::DFP);
-
- Return<void> ret = usb->queryPortStatus();
- ASSERT_TRUE(ret.isOk());
- EXPECT_EQ(std::cv_status::no_timeout, wait());
- EXPECT_EQ(2, usb_last_cookie);
-
- if (!usb_last_port_status.portName.empty()) {
- hidl_string portBeingSwitched = usb_last_port_status.portName;
- ALOGI("mode portname:%s", portBeingSwitched.c_str());
- usb_role_switch_done = false;
- Return<void> ret = usb->switchRole(portBeingSwitched.c_str(), role);
- ASSERT_TRUE(ret.isOk());
-
- std::cv_status waitStatus = wait();
- while (waitStatus == std::cv_status::no_timeout &&
- usb_role_switch_done == false)
- waitStatus = wait();
-
- EXPECT_EQ(std::cv_status::no_timeout, waitStatus);
- EXPECT_EQ(2, usb_last_cookie);
-
- EXPECT_EQ(static_cast<uint32_t>(PortRoleType::MODE),
- static_cast<uint32_t>(usb_last_port_role.type));
- if (usb_last_status == Status::SUCCESS) {
- EXPECT_EQ(static_cast<uint32_t>(PortMode::DFP),
- static_cast<uint32_t>(usb_last_port_role.role));
- } else {
- EXPECT_NE(static_cast<uint32_t>(PortMode::UFP),
- static_cast<uint32_t>(usb_last_port_role.role));
- }
- }
-}
-
-/*
* Test switching the power role of usb port.
* Test case queries the usb ports present in device.
* If there is atleast one usb port, a power role switch
@@ -273,7 +215,7 @@
* is expected to be returned.
*/
-TEST_F(UsbHidlTest, switchPowerRole) {
+TEST_P(UsbHidlTest, switchPowerRole) {
struct PortRole role;
role.type = PortRoleType::POWER_ROLE;
role.role = static_cast<uint32_t>(PortPowerRole::SOURCE);
@@ -319,7 +261,7 @@
* switch was successfull. Upon success, Status::SUCCESS
* is expected to be returned.
*/
-TEST_F(UsbHidlTest, switchDataRole) {
+TEST_P(UsbHidlTest, switchDataRole) {
struct PortRole role;
role.type = PortRoleType::DATA_ROLE;
role.role = static_cast<uint32_t>(PortDataRole::HOST);
@@ -356,11 +298,7 @@
}
}
-int main(int argc, char** argv) {
- ::testing::AddGlobalTestEnvironment(UsbHidlEnvironment::Instance());
- ::testing::InitGoogleTest(&argc, argv);
- UsbHidlEnvironment::Instance()->init(&argc, argv);
- int status = RUN_ALL_TESTS();
- ALOGI("Test result = %d", status);
- return status;
-}
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, UsbHidlTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(IUsb::descriptor)),
+ android::hardware::PrintInstanceNameToString);
diff --git a/usb/1.1/vts/functional/Android.bp b/usb/1.1/vts/functional/Android.bp
index 1f0972f..32c470b 100644
--- a/usb/1.1/vts/functional/Android.bp
+++ b/usb/1.1/vts/functional/Android.bp
@@ -22,6 +22,6 @@
"android.hardware.usb@1.0",
"android.hardware.usb@1.1",
],
- test_suites: ["general-tests"],
+ test_suites: ["general-tests", "vts-core"],
}
diff --git a/usb/1.1/vts/functional/VtsHalUsbV1_1TargetTest.cpp b/usb/1.1/vts/functional/VtsHalUsbV1_1TargetTest.cpp
index caf9c69..d4b2ffd 100644
--- a/usb/1.1/vts/functional/VtsHalUsbV1_1TargetTest.cpp
+++ b/usb/1.1/vts/functional/VtsHalUsbV1_1TargetTest.cpp
@@ -23,8 +23,9 @@
#include <android/hardware/usb/1.1/types.h>
#include <VtsHalHidlTargetCallbackBase.h>
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include <log/log.h>
#include <stdlib.h>
#include <chrono>
@@ -114,25 +115,12 @@
};
};
-// Test environment for Usb HIDL HAL.
-class UsbHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static UsbHidlEnvironment* Instance() {
- static UsbHidlEnvironment* instance = new UsbHidlEnvironment;
- return instance;
- }
-
- virtual void registerTestServices() override { registerTestService<IUsb>(); }
-};
-
// The main test class for the USB hidl HAL
-class UsbHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+class UsbHidlTest : public ::testing::TestWithParam<std::string> {
public:
virtual void SetUp() override {
ALOGI(__FUNCTION__);
- usb = ::testing::VtsHalHidlTargetTestBase::getService<IUsb>(
- UsbHidlEnvironment::Instance()->getServiceName<IUsb>());
+ usb = IUsb::getService(GetParam());
ASSERT_NE(usb, nullptr);
usb_cb_2 = new UsbCallback(2);
@@ -158,7 +146,7 @@
* Callback oject is created and registered.
* Check to see if the hidl transaction succeeded.
*/
-TEST_F(UsbHidlTest, setCallback) {
+TEST_P(UsbHidlTest, setCallback) {
usb_cb_1 = new UsbCallback(1);
ASSERT_NE(usb_cb_1, nullptr);
Return<void> ret = usb->setCallback(usb_cb_1);
@@ -171,7 +159,7 @@
* HAL service should call notifyPortStatusChange_1_1
* instead of notifyPortStatusChange of V1_0 interface
*/
-TEST_F(UsbHidlTest, queryPortStatus) {
+TEST_P(UsbHidlTest, queryPortStatus) {
Return<void> ret = usb->queryPortStatus();
ASSERT_TRUE(ret.isOk());
auto res = usb_cb_2->WaitForCallback(kCallbackNameNotifyPortStatusChange_1_1);
@@ -181,12 +169,7 @@
EXPECT_EQ(PortMode::NONE, res.args->usb_last_port_status.status.supportedModes);
EXPECT_EQ(Status::SUCCESS, res.args->usb_last_status);
}
-
-int main(int argc, char** argv) {
- ::testing::AddGlobalTestEnvironment(UsbHidlEnvironment::Instance());
- ::testing::InitGoogleTest(&argc, argv);
- UsbHidlEnvironment::Instance()->init(&argc, argv);
- int status = RUN_ALL_TESTS();
- ALOGI("Test result = %d", status);
- return status;
-}
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, UsbHidlTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(IUsb::descriptor)),
+ android::hardware::PrintInstanceNameToString);
diff --git a/vibrator/aidl/Android.bp b/vibrator/aidl/Android.bp
index cd5439f..1eec1da 100644
--- a/vibrator/aidl/Android.bp
+++ b/vibrator/aidl/Android.bp
@@ -5,5 +5,14 @@
"android/hardware/vibrator/*.aidl",
],
stability: "vintf",
+ backend: {
+ java: {
+ platform_apis: true,
+ },
+ ndk: {
+ vndk: {
+ enabled: true,
+ },
+ },
+ },
}
-
diff --git a/vibrator/aidl/android/hardware/vibrator/CompositeEffect.aidl b/vibrator/aidl/android/hardware/vibrator/CompositeEffect.aidl
new file mode 100644
index 0000000..84556b5
--- /dev/null
+++ b/vibrator/aidl/android/hardware/vibrator/CompositeEffect.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2019 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.vibrator;
+
+import android.hardware.vibrator.CompositePrimitive;
+
+@VintfStability
+parcelable CompositeEffect {
+ /* Period of silence preceding primitive. */
+ int delayMs;
+ CompositePrimitive primitive;
+ /* 0.0 (exclusive) - 1.0 (inclusive) */
+ float scale;
+}
diff --git a/vibrator/aidl/android/hardware/vibrator/CompositePrimitive.aidl b/vibrator/aidl/android/hardware/vibrator/CompositePrimitive.aidl
new file mode 100644
index 0000000..b9a80ec
--- /dev/null
+++ b/vibrator/aidl/android/hardware/vibrator/CompositePrimitive.aidl
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2019 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.vibrator;
+
+@VintfStability
+@Backing(type="int")
+enum CompositePrimitive {
+ /**
+ * No haptic effect. Used to generate extended delays between primitives.
+ */
+ NOOP,
+ /**
+ * This effect should produce a sharp, crisp click sensation.
+ */
+ CLICK,
+ /**
+ * A haptic effect that simulates downwards movement with gravity. Often
+ * followed by extra energy of hitting and reverberation to augment
+ * physicality.
+ */
+ THUD,
+ /**
+ * A haptic effect that simulates spinning momentum.
+ */
+ SPIN,
+ /**
+ * A haptic effect that simulates quick upward movement against gravity.
+ */
+ QUICK_RISE,
+ /**
+ * A haptic effect that simulates slow upward movement against gravity.
+ */
+ SLOW_RISE,
+ /**
+ * A haptic effect that simulates quick downwards movement with gravity.
+ */
+ QUICK_FALL,
+}
diff --git a/vibrator/aidl/android/hardware/vibrator/IVibrator.aidl b/vibrator/aidl/android/hardware/vibrator/IVibrator.aidl
index 8c4fd05..f553664 100644
--- a/vibrator/aidl/android/hardware/vibrator/IVibrator.aidl
+++ b/vibrator/aidl/android/hardware/vibrator/IVibrator.aidl
@@ -19,6 +19,8 @@
import android.hardware.vibrator.IVibratorCallback;
import android.hardware.vibrator.Effect;
import android.hardware.vibrator.EffectStrength;
+import android.hardware.vibrator.CompositeEffect;
+import android.hardware.vibrator.CompositePrimitive;
@VintfStability
interface IVibrator {
@@ -42,6 +44,14 @@
* Whether setAmplitude is supported (when external control is enabled)
*/
const int CAP_EXTERNAL_AMPLITUDE_CONTROL = 1 << 4;
+ /**
+ * Whether compose is supported.
+ */
+ const int CAP_COMPOSE_EFFECTS = 1 << 5;
+ /**
+ * Whether alwaysOnEnable/alwaysOnDisable is supported.
+ */
+ const int CAP_ALWAYS_ON_CONTROL = 1 << 6;
/**
* Determine capabilities of the vibrator HAL (CAP_* mask)
@@ -107,11 +117,10 @@
* CAP_EXTERNAL_AMPLITUDE_CONTROL.
*
* @param amplitude The unitless force setting. Note that this number must
- * be between 1 and 255, inclusive. If the motor does not
- * have exactly 255 steps, it must do it's best to map it
- * onto the number of steps it does have.
+ * be between 0.0 (exclusive) and 1.0 (inclusive). It must
+ * do it's best to map it onto the number of steps it does have.
*/
- void setAmplitude(in int amplitude);
+ void setAmplitude(in float amplitude);
/**
* Enables/disables control override of vibrator to audio.
@@ -128,4 +137,63 @@
* @param enabled Whether external control should be enabled or disabled.
*/
void setExternalControl(in boolean enabled);
+
+ /**
+ * Retrieve composition delay limit.
+ *
+ * Support is reflected in getCapabilities (CAP_COMPOSE_EFFECTS).
+ *
+ * @return Maximum delay for a single CompositeEffect[] entry.
+ */
+ int getCompositionDelayMax();
+
+ /**
+ * Retrieve composition size limit.
+ *
+ * Support is reflected in getCapabilities (CAP_COMPOSE_EFFECTS).
+ *
+ * @return Maximum number of entries in CompositeEffect[].
+ * @param maxDelayMs Maximum delay for a single CompositeEffect[] entry.
+ */
+ int getCompositionSizeMax();
+
+ /**
+ * Fire off a string of effect primitives, combined to perform richer effects.
+ *
+ * Support is reflected in getCapabilities (CAP_COMPOSE_EFFECTS).
+ *
+ * Doing this operation while the vibrator is already on is undefined behavior. Clients should
+ * explicitly call off.
+ *
+ * @param composite Array of composition parameters.
+ */
+ void compose(in CompositeEffect[] composite, in IVibratorCallback callback);
+
+ /**
+ * List of supported always-on effects.
+ *
+ * Return the effects which are supported by the alwaysOnEnable (an effect
+ * is expected to be supported at every strength level.
+ */
+ Effect[] getSupportedAlwaysOnEffects();
+
+ /**
+ * Enable an always-on haptic source, assigning a specific effect. An
+ * always-on haptic source is a source that can be triggered externally
+ * once enabled and assigned an effect to play. This may not be supported
+ * and this support is reflected in getCapabilities (CAP_ALWAYS_ON_CONTROL).
+ *
+ * @param id The device-specific always-on source ID to enable.
+ * @param effect The type of haptic event to trigger.
+ * @param strength The intensity of haptic event to trigger.
+ */
+ void alwaysOnEnable(in int id, in Effect effect, in EffectStrength strength);
+
+ /**
+ * Disable an always-on haptic source. This may not be supported and this
+ * support is reflected in getCapabilities (CAP_ALWAYS_ON_CONTROL).
+ *
+ * @param id The device-specific always-on source ID to disable.
+ */
+ void alwaysOnDisable(in int id);
}
diff --git a/vibrator/aidl/default/Vibrator.cpp b/vibrator/aidl/default/Vibrator.cpp
index 09cd234..cedd9cb 100644
--- a/vibrator/aidl/default/Vibrator.cpp
+++ b/vibrator/aidl/default/Vibrator.cpp
@@ -24,11 +24,15 @@
namespace hardware {
namespace vibrator {
+static constexpr int32_t kComposeDelayMaxMs = 1000;
+static constexpr int32_t kComposeSizeMax = 256;
+
ndk::ScopedAStatus Vibrator::getCapabilities(int32_t* _aidl_return) {
LOG(INFO) << "Vibrator reporting capabilities";
*_aidl_return = IVibrator::CAP_ON_CALLBACK | IVibrator::CAP_PERFORM_CALLBACK |
IVibrator::CAP_AMPLITUDE_CONTROL | IVibrator::CAP_EXTERNAL_CONTROL |
- IVibrator::CAP_EXTERNAL_AMPLITUDE_CONTROL;
+ IVibrator::CAP_EXTERNAL_AMPLITUDE_CONTROL | IVibrator::CAP_COMPOSE_EFFECTS |
+ IVibrator::CAP_ALWAYS_ON_CONTROL;
return ndk::ScopedAStatus::ok();
}
@@ -45,7 +49,9 @@
LOG(INFO) << "Starting on on another thread";
usleep(timeoutMs * 1000);
LOG(INFO) << "Notifying on complete";
- callback->onComplete();
+ if (!callback->onComplete().isOk()) {
+ LOG(ERROR) << "Failed to call onComplete";
+ }
}).detach();
}
return ndk::ScopedAStatus::ok();
@@ -84,9 +90,9 @@
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus Vibrator::setAmplitude(int32_t amplitude) {
+ndk::ScopedAStatus Vibrator::setAmplitude(float amplitude) {
LOG(INFO) << "Vibrator set amplitude: " << amplitude;
- if (amplitude <= 0 || amplitude > 255) {
+ if (amplitude <= 0.0f || amplitude > 1.0f) {
return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_ARGUMENT));
}
return ndk::ScopedAStatus::ok();
@@ -97,6 +103,77 @@
return ndk::ScopedAStatus::ok();
}
+ndk::ScopedAStatus Vibrator::getCompositionDelayMax(int32_t* maxDelayMs) {
+ *maxDelayMs = kComposeDelayMaxMs;
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Vibrator::getCompositionSizeMax(int32_t* maxSize) {
+ *maxSize = kComposeSizeMax;
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Vibrator::compose(const std::vector<CompositeEffect>& composite,
+ const std::shared_ptr<IVibratorCallback>& callback) {
+ if (composite.size() > kComposeSizeMax) {
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+
+ for (auto& e : composite) {
+ if (e.delayMs > kComposeDelayMaxMs) {
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+ if (e.scale <= 0.0f || e.scale > 1.0f) {
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+ if (e.primitive < CompositePrimitive::NOOP ||
+ e.primitive > CompositePrimitive::QUICK_FALL) {
+ return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+ }
+ }
+
+ std::thread([=] {
+ LOG(INFO) << "Starting compose on another thread";
+
+ for (auto& e : composite) {
+ if (e.delayMs) {
+ usleep(e.delayMs * 1000);
+ }
+ LOG(INFO) << "triggering primitive " << static_cast<int>(e.primitive) << " @ scale "
+ << e.scale;
+ }
+
+ if (callback != nullptr) {
+ LOG(INFO) << "Notifying perform complete";
+ callback->onComplete();
+ }
+ }).detach();
+
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Vibrator::getSupportedAlwaysOnEffects(std::vector<Effect>* _aidl_return) {
+ return getSupportedEffects(_aidl_return);
+}
+
+ndk::ScopedAStatus Vibrator::alwaysOnEnable(int32_t id, Effect effect, EffectStrength strength) {
+ std::vector<Effect> effects;
+ getSupportedAlwaysOnEffects(&effects);
+
+ if (std::find(effects.begin(), effects.end(), effect) == effects.end()) {
+ return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+ } else {
+ LOG(INFO) << "Enabling always-on ID " << id << " with " << toString(effect) << "/"
+ << toString(strength);
+ return ndk::ScopedAStatus::ok();
+ }
+}
+
+ndk::ScopedAStatus Vibrator::alwaysOnDisable(int32_t id) {
+ LOG(INFO) << "Disabling always-on ID " << id;
+ return ndk::ScopedAStatus::ok();
+}
+
} // namespace vibrator
} // namespace hardware
} // namespace android
diff --git a/vibrator/aidl/default/include/vibrator-impl/Vibrator.h b/vibrator/aidl/default/include/vibrator-impl/Vibrator.h
index 14e7292..0eb957d 100644
--- a/vibrator/aidl/default/include/vibrator-impl/Vibrator.h
+++ b/vibrator/aidl/default/include/vibrator-impl/Vibrator.h
@@ -32,8 +32,15 @@
const std::shared_ptr<IVibratorCallback>& callback,
int32_t* _aidl_return) override;
ndk::ScopedAStatus getSupportedEffects(std::vector<Effect>* _aidl_return) override;
- ndk::ScopedAStatus setAmplitude(int32_t amplitude) override;
+ ndk::ScopedAStatus setAmplitude(float amplitude) override;
ndk::ScopedAStatus setExternalControl(bool enabled) override;
+ ndk::ScopedAStatus getCompositionDelayMax(int32_t* maxDelayMs);
+ ndk::ScopedAStatus getCompositionSizeMax(int32_t* maxSize);
+ ndk::ScopedAStatus compose(const std::vector<CompositeEffect>& composite,
+ const std::shared_ptr<IVibratorCallback>& callback) override;
+ ndk::ScopedAStatus getSupportedAlwaysOnEffects(std::vector<Effect>* _aidl_return) override;
+ ndk::ScopedAStatus alwaysOnEnable(int32_t id, Effect effect, EffectStrength strength) override;
+ ndk::ScopedAStatus alwaysOnDisable(int32_t id) override;
};
} // namespace vibrator
diff --git a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
index b6aa9e2..0e2b3e1 100644
--- a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
+++ b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
@@ -28,22 +28,16 @@
using android::String16;
using android::binder::Status;
using android::hardware::vibrator::BnVibratorCallback;
+using android::hardware::vibrator::CompositeEffect;
+using android::hardware::vibrator::CompositePrimitive;
using android::hardware::vibrator::Effect;
using android::hardware::vibrator::EffectStrength;
using android::hardware::vibrator::IVibrator;
-// TODO(b/143992652): autogenerate
-const std::vector<Effect> kEffects = {
- Effect::CLICK, Effect::DOUBLE_CLICK, Effect::TICK, Effect::THUD,
- Effect::POP, Effect::HEAVY_CLICK, Effect::RINGTONE_1, Effect::RINGTONE_2,
- Effect::RINGTONE_3, Effect::RINGTONE_4, Effect::RINGTONE_5, Effect::RINGTONE_6,
- Effect::RINGTONE_7, Effect::RINGTONE_8, Effect::RINGTONE_9, Effect::RINGTONE_10,
- Effect::RINGTONE_11, Effect::RINGTONE_12, Effect::RINGTONE_13, Effect::RINGTONE_14,
- Effect::RINGTONE_15, Effect::TEXTURE_TICK};
-
-// TODO(b/143992652): autogenerate
-const std::vector<EffectStrength> kEffectStrengths = {EffectStrength::LIGHT, EffectStrength::MEDIUM,
- EffectStrength::STRONG};
+const std::vector<Effect> kEffects{android::enum_range<Effect>().begin(),
+ android::enum_range<Effect>().end()};
+const std::vector<EffectStrength> kEffectStrengths{android::enum_range<EffectStrength>().begin(),
+ android::enum_range<EffectStrength>().end()};
const std::vector<Effect> kInvalidEffects = {
static_cast<Effect>(static_cast<int32_t>(kEffects.front()) - 1),
@@ -55,6 +49,20 @@
static_cast<EffectStrength>(static_cast<int8_t>(kEffectStrengths.back()) + 1),
};
+// TODO(b/143992652): autogenerate
+const std::vector<CompositePrimitive> kCompositePrimitives = {
+ CompositePrimitive::NOOP, CompositePrimitive::CLICK,
+ CompositePrimitive::THUD, CompositePrimitive::SPIN,
+ CompositePrimitive::QUICK_RISE, CompositePrimitive::SLOW_RISE,
+ CompositePrimitive::QUICK_FALL,
+};
+// TODO(b/143992652): autogenerate
+
+const std::vector<CompositePrimitive> kInvalidPrimitives = {
+ static_cast<CompositePrimitive>(static_cast<int32_t>(kCompositePrimitives.front()) - 1),
+ static_cast<CompositePrimitive>(static_cast<int32_t>(kCompositePrimitives.back()) + 1),
+};
+
class CompletionCallback : public BnVibratorCallback {
public:
CompletionCallback(const std::function<void()>& callback) : mCallback(callback) {}
@@ -119,13 +127,12 @@
Status status = vibrator->perform(effect, strength, nullptr /*callback*/, &lengthMs);
if (isEffectSupported) {
- EXPECT_TRUE(status.isOk())
- << static_cast<int>(effect) << " " << static_cast<int>(strength);
+ EXPECT_TRUE(status.isOk()) << toString(effect) << " " << toString(strength);
EXPECT_GT(lengthMs, 0);
usleep(lengthMs * 1000);
} else {
EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION)
- << static_cast<int>(effect) << " " << static_cast<int>(strength);
+ << toString(effect) << " " << toString(strength);
EXPECT_EQ(lengthMs, 0);
}
}
@@ -186,7 +193,7 @@
int32_t lengthMs;
Status status = vibrator->perform(effect, strength, nullptr /*callback*/, &lengthMs);
EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION)
- << static_cast<int>(effect) << " " << static_cast<int>(strength);
+ << toString(effect) << " " << toString(strength);
}
}
for (Effect effect : kEffects) {
@@ -194,18 +201,18 @@
int32_t lengthMs;
Status status = vibrator->perform(effect, strength, nullptr /*callback*/, &lengthMs);
EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION)
- << static_cast<int>(effect) << " " << static_cast<int>(strength);
+ << toString(effect) << " " << toString(strength);
}
}
}
TEST_P(VibratorAidl, ChangeVibrationAmplitude) {
if (capabilities & IVibrator::CAP_AMPLITUDE_CONTROL) {
- EXPECT_TRUE(vibrator->setAmplitude(1).isOk());
+ EXPECT_EQ(Status::EX_NONE, vibrator->setAmplitude(0.1f).exceptionCode());
EXPECT_TRUE(vibrator->on(2000, nullptr /*callback*/).isOk());
- EXPECT_TRUE(vibrator->setAmplitude(128).isOk());
+ EXPECT_EQ(Status::EX_NONE, vibrator->setAmplitude(0.5f).exceptionCode());
sleep(1);
- EXPECT_TRUE(vibrator->setAmplitude(255).isOk());
+ EXPECT_EQ(Status::EX_NONE, vibrator->setAmplitude(1.0f).exceptionCode());
sleep(1);
}
}
@@ -214,7 +221,7 @@
if (capabilities & IVibrator::CAP_AMPLITUDE_CONTROL) {
EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, vibrator->setAmplitude(-1).exceptionCode());
EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, vibrator->setAmplitude(0).exceptionCode());
- EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, vibrator->setAmplitude(256).exceptionCode());
+ EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, vibrator->setAmplitude(1.1).exceptionCode());
}
}
@@ -240,7 +247,7 @@
if (capabilities & IVibrator::CAP_EXTERNAL_CONTROL) {
EXPECT_TRUE(vibrator->setExternalControl(true).isOk());
- Status amplitudeStatus = vibrator->setAmplitude(128);
+ Status amplitudeStatus = vibrator->setAmplitude(0.5);
if (supportsExternalAmplitudeControl) {
EXPECT_TRUE(amplitudeStatus.isOk());
} else {
@@ -259,6 +266,128 @@
}
}
+TEST_P(VibratorAidl, ComposeValidPrimitives) {
+ if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
+ int32_t maxDelay, maxSize;
+
+ EXPECT_EQ(Status::EX_NONE, vibrator->getCompositionDelayMax(&maxDelay).exceptionCode());
+ EXPECT_EQ(Status::EX_NONE, vibrator->getCompositionSizeMax(&maxSize).exceptionCode());
+
+ std::vector<CompositeEffect> composite;
+
+ for (auto primitive : kCompositePrimitives) {
+ CompositeEffect effect;
+
+ effect.delayMs = std::rand() % (maxDelay + 1);
+ effect.primitive = primitive;
+ effect.scale = static_cast<float>(std::rand()) / RAND_MAX ?: 1.0f;
+ composite.emplace_back(effect);
+
+ if (composite.size() == maxSize) {
+ EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
+ composite.clear();
+ vibrator->off();
+ }
+ }
+
+ if (composite.size() != 0) {
+ EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
+ vibrator->off();
+ }
+ }
+}
+
+TEST_P(VibratorAidl, ComposeUnsupportedPrimitives) {
+ if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
+ for (auto primitive : kInvalidPrimitives) {
+ std::vector<CompositeEffect> composite(1);
+
+ for (auto& effect : composite) {
+ effect.delayMs = 0;
+ effect.primitive = primitive;
+ effect.scale = 1.0f;
+ }
+ EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION,
+ vibrator->compose(composite, nullptr).exceptionCode());
+ vibrator->off();
+ }
+ }
+}
+
+TEST_P(VibratorAidl, CompseDelayBoundary) {
+ if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
+ int32_t maxDelay;
+
+ EXPECT_EQ(Status::EX_NONE, vibrator->getCompositionDelayMax(&maxDelay).exceptionCode());
+
+ std::vector<CompositeEffect> composite(1);
+ CompositeEffect effect;
+
+ effect.delayMs = 1;
+ effect.primitive = CompositePrimitive::CLICK;
+ effect.scale = 1.0f;
+
+ std::fill(composite.begin(), composite.end(), effect);
+ EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
+
+ effect.delayMs = maxDelay + 1;
+
+ std::fill(composite.begin(), composite.end(), effect);
+ EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT,
+ vibrator->compose(composite, nullptr).exceptionCode());
+ vibrator->off();
+ }
+}
+
+TEST_P(VibratorAidl, CompseSizeBoundary) {
+ if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
+ int32_t maxSize;
+
+ EXPECT_EQ(Status::EX_NONE, vibrator->getCompositionSizeMax(&maxSize).exceptionCode());
+
+ std::vector<CompositeEffect> composite(maxSize);
+ CompositeEffect effect;
+
+ effect.delayMs = 1;
+ effect.primitive = CompositePrimitive::CLICK;
+ effect.scale = 1.0f;
+
+ std::fill(composite.begin(), composite.end(), effect);
+ EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
+
+ composite.emplace_back(effect);
+ EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT,
+ vibrator->compose(composite, nullptr).exceptionCode());
+ vibrator->off();
+ }
+}
+
+TEST_P(VibratorAidl, AlwaysOn) {
+ if (capabilities & IVibrator::CAP_ALWAYS_ON_CONTROL) {
+ std::vector<Effect> supported;
+ ASSERT_TRUE(vibrator->getSupportedAlwaysOnEffects(&supported).isOk());
+
+ for (Effect effect : kEffects) {
+ bool isEffectSupported =
+ std::find(supported.begin(), supported.end(), effect) != supported.end();
+
+ for (EffectStrength strength : kEffectStrengths) {
+ Status status = vibrator->alwaysOnEnable(0, effect, strength);
+
+ if (isEffectSupported) {
+ EXPECT_EQ(Status::EX_NONE, status.exceptionCode())
+ << toString(effect) << " " << toString(strength);
+ } else {
+ EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION, status.exceptionCode())
+ << toString(effect) << " " << toString(strength);
+ }
+ }
+ }
+
+ EXPECT_EQ(Status::EX_NONE, vibrator->alwaysOnDisable(0).exceptionCode());
+ }
+}
+
INSTANTIATE_TEST_SUITE_P(Vibrator, VibratorAidl,
testing::ValuesIn(android::getAidlHalInstanceNames(IVibrator::descriptor)),
android::PrintInstanceNameToString);
diff --git a/wifi/1.4/Android.bp b/wifi/1.4/Android.bp
index 5750e42..3b94619 100644
--- a/wifi/1.4/Android.bp
+++ b/wifi/1.4/Android.bp
@@ -11,9 +11,10 @@
"IWifi.hal",
"IWifiApIface.hal",
"IWifiChip.hal",
+ "IWifiChipEventCallback.hal",
+ "IWifiNanIface.hal",
"IWifiRttController.hal",
"IWifiRttControllerEventCallback.hal",
- "IWifiStaIface.hal",
],
interfaces: [
"android.hardware.wifi@1.0",
diff --git a/wifi/1.4/IWifiChip.hal b/wifi/1.4/IWifiChip.hal
index d269427..07f4a65 100644
--- a/wifi/1.4/IWifiChip.hal
+++ b/wifi/1.4/IWifiChip.hal
@@ -19,6 +19,7 @@
import @1.0::WifiStatus;
import @1.0::IWifiIface;
import @1.3::IWifiChip;
+import IWifiChipEventCallback;
import IWifiRttController;
/**
@@ -26,6 +27,21 @@
*/
interface IWifiChip extends @1.3::IWifiChip {
/**
+ * Requests notifications of significant events on this chip. Multiple calls
+ * to this must register multiple callbacks each of which must receive all
+ * events.
+ *
+ * @param callback An instance of the |IWifiChipEventCallback| HIDL interface
+ * object.
+ * @return status WifiStatus of the operation.
+ * Possible status codes:
+ * |WifiStatusCode.SUCCESS|,
+ * |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+ * |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|
+ */
+ registerEventCallback_1_4(IWifiChipEventCallback callback) generates (WifiStatus status);
+
+ /**
* Create a RTTController instance.
*
* RTT controller can be either:
diff --git a/wifi/1.4/IWifiChipEventCallback.hal b/wifi/1.4/IWifiChipEventCallback.hal
new file mode 100644
index 0000000..9ead344
--- /dev/null
+++ b/wifi/1.4/IWifiChipEventCallback.hal
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2019 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.wifi@1.4;
+
+import @1.2::IWifiChipEventCallback;
+import WifiBand;
+
+/**
+ * Wifi chip event callbacks.
+ */
+interface IWifiChipEventCallback extends @1.2::IWifiChipEventCallback {
+ /**
+ * Struct describing the state of each hardware radio chain (hardware MAC)
+ * on the device.
+ */
+ struct RadioModeInfo {
+ /**
+ * Identifier for this radio chain. This is vendor dependent & used
+ * only for debugging purposes.
+ */
+ uint32_t radioId;
+
+ /**
+ * List of bands on which this radio chain is operating.
+ * Can be one of:
+ * a) WifiBand.BAND_24GHZ => 2.4Ghz.
+ * b) WifiBand.BAND_5GHZ => 5Ghz.
+ * c) WifiBand.BAND_24GHZ_5GHZ = 2.4Ghz + 5Ghz (Radio is time sharing
+ * across the 2 bands).
+ * d) WifiBand.BAND_6GHZ => 6Ghz.
+ * e) WifiBand.BAND_5GHZ_6GHZ => 5Ghz + 6Ghz (Radio is time sharing
+ * across the 2 bands).
+ * f) WifiBand.BAND_24GHZ_5GHZ_6GHZ => 2.4Ghz + 5Ghz + 6Ghz (Radio is
+ * time sharing across the 3 bands).
+ */
+ WifiBand bandInfo;
+
+ /**
+ * List of interfaces on this radio chain (hardware MAC).
+ */
+ vec<IfaceInfo> ifaceInfos;
+ };
+
+ /**
+ * Asynchronous callback indicating a radio mode change.
+ * Radio mode change could be a result of:
+ * a) Bringing up concurrent interfaces (For ex: STA + AP).
+ * b) Change in operating band of one of the concurrent interfaces (For ex:
+ * STA connection moved from 2.4G to 5G)
+ *
+ * @param radioModeInfos List of RadioModeInfo structures for each
+ * radio chain (hardware MAC) on the device.
+ */
+ oneway onRadioModeChange_1_4(vec<RadioModeInfo> radioModeInfos);
+};
diff --git a/wifi/1.4/IWifiNanIface.hal b/wifi/1.4/IWifiNanIface.hal
new file mode 100644
index 0000000..881d06c
--- /dev/null
+++ b/wifi/1.4/IWifiNanIface.hal
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2019 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.wifi@1.4;
+
+import @1.0::CommandIdShort;
+import @1.0::WifiStatus;
+import @1.2::IWifiNanIface;
+import @1.2::NanConfigRequestSupplemental;
+import NanConfigRequest;
+import NanEnableRequest;
+
+/**
+ * Interface used to represent a single NAN (Neighbour Aware Network) iface.
+ *
+ * References to "NAN Spec" are to the Wi-Fi Alliance "Wi-Fi Neighbor Awareness
+ * Networking (NAN) Technical Specification".
+ */
+interface IWifiNanIface extends @1.2::IWifiNanIface {
+ /**
+ * Enable NAN: configures and activates NAN clustering (does not start
+ * a discovery session or set up data-interfaces or data-paths). Use the
+ * |IWifiNanIface.configureRequest| method to change the configuration of an already enabled
+ * NAN interface.
+ * Asynchronous response is with |IWifiNanIfaceEventCallback.notifyEnableResponse|.
+ *
+ * Note: supersedes the @1.2::IWifiNanIface.enableRequest() method which is deprecated as of
+ * HAL version 1.4.
+ *
+ * @param cmdId command Id to use for this invocation.
+ * @param msg1 Instance of |NanEnableRequest|.
+ * @param msg2 Instance of |NanConfigRequestSupplemental|.
+ * @return status WifiStatus of the operation.
+ * Possible status codes:
+ * |WifiStatusCode.SUCCESS|,
+ * |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+ * |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+ * |WifiStatusCode.ERROR_INVALID_ARGS|,
+ * |WifiStatusCode.ERROR_UNKNOWN|
+ */
+ enableRequest_1_4(CommandIdShort cmdId, NanEnableRequest msg1,
+ NanConfigRequestSupplemental msg2) generates (WifiStatus status);
+
+ /**
+ * Configure NAN: configures an existing NAN functionality (i.e. assumes
+ * |IWifiNanIface.enableRequest| already submitted and succeeded).
+ * Asynchronous response is with |IWifiNanIfaceEventCallback.notifyConfigResponse|.
+ *
+ * Note: supersedes the @1.2::IWifiNanIface.configRequest() method which is deprecated as of
+ * HAL version 1.4.
+ *
+ * @param cmdId command Id to use for this invocation.
+ * @param msg1 Instance of |NanConfigRequest|.
+ * @param msg1 Instance of |NanConfigRequestSupplemental|.
+ * @return status WifiStatus of the operation.
+ * Possible status codes:
+ * |WifiStatusCode.SUCCESS|,
+ * |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+ * |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+ * |WifiStatusCode.ERROR_INVALID_ARGS|,
+ * |WifiStatusCode.ERROR_UNKNOWN|
+ */
+ configRequest_1_4(CommandIdShort cmdId, NanConfigRequest msg1,
+ NanConfigRequestSupplemental msg2) generates (WifiStatus status);
+};
diff --git a/wifi/1.4/IWifiStaIface.hal b/wifi/1.4/IWifiStaIface.hal
deleted file mode 100644
index fb658cd..0000000
--- a/wifi/1.4/IWifiStaIface.hal
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright 2019 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.wifi@1.4;
-
-import @1.0::WifiStatus;
-import @1.0::MacAddress;
-import @1.0::IWifiStaIface;
-import @1.3::IWifiStaIface;
-
-/**
- * Interface used to represent a single STA iface.
- *
- * IWifiChip.createStaIface() may return a @1.4::IWifiStaIface when supported.
- */
-interface IWifiStaIface extends @1.3::IWifiStaIface {
-
- enum StaIfaceCapabilityMask : @1.0::IWifiStaIface.StaIfaceCapabilityMask {
- STA_6G = 1 << 15
- };
-
- /**
- * Get the capabilities supported by this STA iface.
- *
- * @return status WifiStatus of the operation.
- * Possible status codes:
- * |WifiStatusCode.SUCCESS|,
- * |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
- * |WifiStatusCode.ERROR_NOT_AVAILABLE|,
- * |WifiStatusCode.ERROR_NOT_SUPPORTED|,
- * |WifiStatusCode.ERROR_UNKNOWN|
- * @return capabilities Bitset of |StaIfaceCapabilityMask| values.
- */
- getCapabilities_1_4()
- generates (WifiStatus status,
- bitfield<StaIfaceCapabilityMask> capabilities);
-};
diff --git a/wifi/1.4/default/hidl_struct_util.cpp b/wifi/1.4/default/hidl_struct_util.cpp
index 13a09f3..4996e35 100644
--- a/wifi/1.4/default/hidl_struct_util.cpp
+++ b/wifi/1.4/default/hidl_struct_util.cpp
@@ -120,8 +120,6 @@
return HidlStaIfaceCaps::ND_OFFLOAD;
case WIFI_FEATURE_MKEEP_ALIVE:
return HidlStaIfaceCaps::KEEP_ALIVE;
- case WIFI_FEATURE_INFRA_6G:
- return HidlStaIfaceCaps::STA_6G;
};
CHECK(false) << "Unknown legacy feature: " << feature;
return {};
@@ -316,7 +314,7 @@
bool convertLegacyWifiMacInfoToHidl(
const legacy_hal::WifiMacInfo& legacy_mac_info,
- V1_2::IWifiChipEventCallback::RadioModeInfo* hidl_radio_mode_info) {
+ IWifiChipEventCallback::RadioModeInfo* hidl_radio_mode_info) {
if (!hidl_radio_mode_info) {
return false;
}
@@ -325,8 +323,17 @@
hidl_radio_mode_info->radioId = legacy_mac_info.wlan_mac_id;
// Convert from bitmask of bands in the legacy HAL to enum value in
// the HIDL interface.
- if (legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_2_4_BAND &&
- legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_5_0_BAND) {
+ if (legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_6_0_BAND &&
+ legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_5_0_BAND &&
+ legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_2_4_BAND) {
+ hidl_radio_mode_info->bandInfo = WifiBand::BAND_24GHZ_5GHZ_6GHZ;
+ } else if (legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_6_0_BAND &&
+ legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_5_0_BAND) {
+ hidl_radio_mode_info->bandInfo = WifiBand::BAND_5GHZ_6GHZ;
+ } else if (legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_6_0_BAND) {
+ hidl_radio_mode_info->bandInfo = WifiBand::BAND_6GHZ;
+ } else if (legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_2_4_BAND &&
+ legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_5_0_BAND) {
hidl_radio_mode_info->bandInfo = WifiBand::BAND_24GHZ_5GHZ;
} else if (legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_2_4_BAND) {
hidl_radio_mode_info->bandInfo = WifiBand::BAND_24GHZ;
@@ -348,15 +355,14 @@
bool convertLegacyWifiMacInfosToHidl(
const std::vector<legacy_hal::WifiMacInfo>& legacy_mac_infos,
- std::vector<V1_2::IWifiChipEventCallback::RadioModeInfo>*
- hidl_radio_mode_infos) {
+ std::vector<IWifiChipEventCallback::RadioModeInfo>* hidl_radio_mode_infos) {
if (!hidl_radio_mode_infos) {
return false;
}
*hidl_radio_mode_infos = {};
for (const auto& legacy_mac_info : legacy_mac_infos) {
- V1_2::IWifiChipEventCallback::RadioModeInfo hidl_radio_mode_info;
+ IWifiChipEventCallback::RadioModeInfo hidl_radio_mode_info;
if (!convertLegacyWifiMacInfoToHidl(legacy_mac_info,
&hidl_radio_mode_info)) {
return false;
@@ -386,8 +392,7 @@
WIFI_FEATURE_IE_WHITELIST, WIFI_FEATURE_SCAN_RAND,
WIFI_FEATURE_INFRA_5G, WIFI_FEATURE_HOTSPOT, WIFI_FEATURE_PNO,
WIFI_FEATURE_TDLS, WIFI_FEATURE_TDLS_OFFCHANNEL,
- WIFI_FEATURE_CONFIG_NDO, WIFI_FEATURE_MKEEP_ALIVE,
- WIFI_FEATURE_INFRA_6G}) {
+ WIFI_FEATURE_CONFIG_NDO, WIFI_FEATURE_MKEEP_ALIVE}) {
if (feature & legacy_feature_set) {
*hidl_caps |= convertLegacyFeatureToHidlStaIfaceCapability(feature);
}
@@ -449,21 +454,21 @@
return true;
}
-legacy_hal::wifi_band convertHidlWifiBandToLegacy(WifiBand band) {
+legacy_hal::wifi_band convertHidlWifiBandToLegacy(V1_0::WifiBand band) {
switch (band) {
- case WifiBand::BAND_UNSPECIFIED:
+ case V1_0::WifiBand::BAND_UNSPECIFIED:
return legacy_hal::WIFI_BAND_UNSPECIFIED;
- case WifiBand::BAND_24GHZ:
+ case V1_0::WifiBand::BAND_24GHZ:
return legacy_hal::WIFI_BAND_BG;
- case WifiBand::BAND_5GHZ:
+ case V1_0::WifiBand::BAND_5GHZ:
return legacy_hal::WIFI_BAND_A;
- case WifiBand::BAND_5GHZ_DFS:
+ case V1_0::WifiBand::BAND_5GHZ_DFS:
return legacy_hal::WIFI_BAND_A_DFS;
- case WifiBand::BAND_5GHZ_WITH_DFS:
+ case V1_0::WifiBand::BAND_5GHZ_WITH_DFS:
return legacy_hal::WIFI_BAND_A_WITH_DFS;
- case WifiBand::BAND_24GHZ_5GHZ:
+ case V1_0::WifiBand::BAND_24GHZ_5GHZ:
return legacy_hal::WIFI_BAND_ABG;
- case WifiBand::BAND_24GHZ_5GHZ_WITH_DFS:
+ case V1_0::WifiBand::BAND_24GHZ_5GHZ_WITH_DFS:
return legacy_hal::WIFI_BAND_ABG_WITH_DFS;
};
CHECK(false);
@@ -1127,9 +1132,9 @@
legacy_request->disc_mac_addr_rand_interval_sec =
hidl_request.configParams.macAddressRandomizationIntervalSec;
legacy_request->config_2dot4g_rssi_close = 1;
- if (hidl_request.configParams.bandSpecificConfig.size() != 2) {
+ if (hidl_request.configParams.bandSpecificConfig.size() != 3) {
LOG(ERROR) << "convertHidlNanEnableRequestToLegacy: "
- "bandSpecificConfig.size() != 2";
+ "bandSpecificConfig.size() != 3";
return false;
}
legacy_request->rssi_close_2dot4g_val =
@@ -1262,16 +1267,20 @@
hidl_request.debugConfigs
.useSdfInBandVal[(size_t)NanBandIndex::NAN_BAND_5GHZ];
+ /* TODO: b/145609058
+ * Missing updates needed to legacy_hal::NanEnableRequest and conversion to
+ * it for 6GHz band */
+
return true;
}
-bool convertHidlNanEnableRequest_1_2ToLegacy(
+bool convertHidlNanEnableRequest_1_4ToLegacy(
const NanEnableRequest& hidl_request1,
const V1_2::NanConfigRequestSupplemental& hidl_request2,
legacy_hal::NanEnableRequest* legacy_request) {
if (!legacy_request) {
LOG(ERROR)
- << "convertHidlNanEnableRequest_1_2ToLegacy: null legacy_request";
+ << "convertHidlNanEnableRequest_1_4ToLegacy: null legacy_request";
return false;
}
@@ -1772,16 +1781,19 @@
legacy_request->config_dw.dw_5g_interval_val =
hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
.discoveryWindowIntervalVal;
+ /* TODO: b/145609058
+ * Missing updates needed to legacy_hal::NanConfigRequest and conversion to
+ * it for 6GHz band */
return true;
}
-bool convertHidlNanConfigRequest_1_2ToLegacy(
+bool convertHidlNanConfigRequest_1_4ToLegacy(
const NanConfigRequest& hidl_request1,
const V1_2::NanConfigRequestSupplemental& hidl_request2,
legacy_hal::NanConfigRequest* legacy_request) {
if (!legacy_request) {
- LOG(ERROR) << "convertHidlNanConfigRequest_1_2ToLegacy: legacy_request "
+ LOG(ERROR) << "convertHidlNanConfigRequest_1_4ToLegacy: legacy_request "
"is null";
return false;
}
@@ -1822,7 +1834,13 @@
convertHidlNanDataPathChannelCfgToLegacy(
hidl_request.channelRequestType);
legacy_request->channel = hidl_request.channel;
- strcpy(legacy_request->ndp_iface, hidl_request.ifaceName.c_str());
+ if (strnlen(hidl_request.ifaceName.c_str(), IFNAMSIZ + 1) == IFNAMSIZ + 1) {
+ LOG(ERROR) << "convertHidlNanDataPathInitiatorRequestToLegacy: "
+ "ifaceName too long";
+ return false;
+ }
+ strncpy(legacy_request->ndp_iface, hidl_request.ifaceName.c_str(),
+ IFNAMSIZ + 1);
legacy_request->ndp_cfg.security_cfg =
(hidl_request.securityConfig.securityType !=
NanDataPathSecurityType::OPEN)
@@ -1903,7 +1921,13 @@
? legacy_hal::NAN_DP_REQUEST_ACCEPT
: legacy_hal::NAN_DP_REQUEST_REJECT;
legacy_request->ndp_instance_id = hidl_request.ndpInstanceId;
- strcpy(legacy_request->ndp_iface, hidl_request.ifaceName.c_str());
+ if (strnlen(hidl_request.ifaceName.c_str(), IFNAMSIZ + 1) == IFNAMSIZ + 1) {
+ LOG(ERROR) << "convertHidlNanDataPathIndicationResponseToLegacy: "
+ "ifaceName too long";
+ return false;
+ }
+ strncpy(legacy_request->ndp_iface, hidl_request.ifaceName.c_str(),
+ IFNAMSIZ + 1);
legacy_request->ndp_cfg.security_cfg =
(hidl_request.securityConfig.securityType !=
NanDataPathSecurityType::OPEN)
diff --git a/wifi/1.4/default/hidl_struct_util.h b/wifi/1.4/default/hidl_struct_util.h
index cfaa4ad..d040c1f 100644
--- a/wifi/1.4/default/hidl_struct_util.h
+++ b/wifi/1.4/default/hidl_struct_util.h
@@ -21,11 +21,10 @@
#include <android/hardware/wifi/1.0/IWifiChip.h>
#include <android/hardware/wifi/1.0/types.h>
-#include <android/hardware/wifi/1.2/IWifiChipEventCallback.h>
#include <android/hardware/wifi/1.2/types.h>
#include <android/hardware/wifi/1.3/IWifiChip.h>
#include <android/hardware/wifi/1.3/types.h>
-#include <android/hardware/wifi/1.4/IWifiStaIface.h>
+#include <android/hardware/wifi/1.4/IWifiChipEventCallback.h>
#include <android/hardware/wifi/1.4/types.h>
#include "wifi_legacy_hal.h"
@@ -65,8 +64,7 @@
V1_2::IWifiChip::TxPowerScenario hidl_scenario);
bool convertLegacyWifiMacInfosToHidl(
const std::vector<legacy_hal::WifiMacInfo>& legacy_mac_infos,
- std::vector<V1_2::IWifiChipEventCallback::RadioModeInfo>*
- hidl_radio_mode_infos);
+ std::vector<IWifiChipEventCallback::RadioModeInfo>* hidl_radio_mode_infos);
// STA iface conversion methods.
bool convertLegacyFeaturesToHidlStaCapabilities(
@@ -78,7 +76,7 @@
bool convertLegacyGscanCapabilitiesToHidl(
const legacy_hal::wifi_gscan_capabilities& legacy_caps,
StaBackgroundScanCapabilities* hidl_caps);
-legacy_hal::wifi_band convertHidlWifiBandToLegacy(WifiBand band);
+legacy_hal::wifi_band convertHidlWifiBandToLegacy(V1_0::WifiBand band);
bool convertHidlGscanParamsToLegacy(
const StaBackgroundScanParameters& hidl_scan_params,
legacy_hal::wifi_scan_cmd_params* legacy_scan_params);
@@ -119,11 +117,11 @@
bool convertHidlNanConfigRequestToLegacy(
const NanConfigRequest& hidl_request,
legacy_hal::NanConfigRequest* legacy_request);
-bool convertHidlNanEnableRequest_1_2ToLegacy(
+bool convertHidlNanEnableRequest_1_4ToLegacy(
const NanEnableRequest& hidl_request1,
const V1_2::NanConfigRequestSupplemental& hidl_request2,
legacy_hal::NanEnableRequest* legacy_request);
-bool convertHidlNanConfigRequest_1_2ToLegacy(
+bool convertHidlNanConfigRequest_1_4ToLegacy(
const NanConfigRequest& hidl_request1,
const V1_2::NanConfigRequestSupplemental& hidl_request2,
legacy_hal::NanConfigRequest* legacy_request);
diff --git a/wifi/1.4/default/tests/hidl_struct_util_unit_tests.cpp b/wifi/1.4/default/tests/hidl_struct_util_unit_tests.cpp
index 14a1504..b71d549 100644
--- a/wifi/1.4/default/tests/hidl_struct_util_unit_tests.cpp
+++ b/wifi/1.4/default/tests/hidl_struct_util_unit_tests.cpp
@@ -55,8 +55,7 @@
legacy_mac_info1.iface_infos.push_back(legacy_iface_info2);
legacy_mac_infos.push_back(legacy_mac_info1);
- std::vector<V1_2::IWifiChipEventCallback::RadioModeInfo>
- hidl_radio_mode_infos;
+ std::vector<IWifiChipEventCallback::RadioModeInfo> hidl_radio_mode_infos;
ASSERT_TRUE(hidl_struct_util::convertLegacyWifiMacInfosToHidl(
legacy_mac_infos, &hidl_radio_mode_infos));
@@ -90,20 +89,18 @@
legacy_mac_info2.iface_infos.push_back(legacy_iface_info2);
legacy_mac_infos.push_back(legacy_mac_info2);
- std::vector<V1_2::IWifiChipEventCallback::RadioModeInfo>
- hidl_radio_mode_infos;
+ std::vector<IWifiChipEventCallback::RadioModeInfo> hidl_radio_mode_infos;
ASSERT_TRUE(hidl_struct_util::convertLegacyWifiMacInfosToHidl(
legacy_mac_infos, &hidl_radio_mode_infos));
ASSERT_EQ(2u, hidl_radio_mode_infos.size());
// Find mac info 1.
- const auto hidl_radio_mode_info1 =
- std::find_if(hidl_radio_mode_infos.begin(), hidl_radio_mode_infos.end(),
- [&legacy_mac_info1](
- const V1_2::IWifiChipEventCallback::RadioModeInfo& x) {
- return x.radioId == legacy_mac_info1.wlan_mac_id;
- });
+ const auto hidl_radio_mode_info1 = std::find_if(
+ hidl_radio_mode_infos.begin(), hidl_radio_mode_infos.end(),
+ [&legacy_mac_info1](const IWifiChipEventCallback::RadioModeInfo& x) {
+ return x.radioId == legacy_mac_info1.wlan_mac_id;
+ });
ASSERT_NE(hidl_radio_mode_infos.end(), hidl_radio_mode_info1);
EXPECT_EQ(WifiBand::BAND_5GHZ, hidl_radio_mode_info1->bandInfo);
ASSERT_EQ(1u, hidl_radio_mode_info1->ifaceInfos.size());
@@ -113,12 +110,11 @@
hidl_iface_info1.channel);
// Find mac info 2.
- const auto hidl_radio_mode_info2 =
- std::find_if(hidl_radio_mode_infos.begin(), hidl_radio_mode_infos.end(),
- [&legacy_mac_info2](
- const V1_2::IWifiChipEventCallback::RadioModeInfo& x) {
- return x.radioId == legacy_mac_info2.wlan_mac_id;
- });
+ const auto hidl_radio_mode_info2 = std::find_if(
+ hidl_radio_mode_infos.begin(), hidl_radio_mode_infos.end(),
+ [&legacy_mac_info2](const IWifiChipEventCallback::RadioModeInfo& x) {
+ return x.radioId == legacy_mac_info2.wlan_mac_id;
+ });
ASSERT_NE(hidl_radio_mode_infos.end(), hidl_radio_mode_info2);
EXPECT_EQ(WifiBand::BAND_24GHZ, hidl_radio_mode_info2->bandInfo);
ASSERT_EQ(1u, hidl_radio_mode_info2->ifaceInfos.size());
diff --git a/wifi/1.4/default/tests/wifi_chip_unit_tests.cpp b/wifi/1.4/default/tests/wifi_chip_unit_tests.cpp
index 90e81e1..d35adbc 100644
--- a/wifi/1.4/default/tests/wifi_chip_unit_tests.cpp
+++ b/wifi/1.4/default/tests/wifi_chip_unit_tests.cpp
@@ -720,13 +720,16 @@
ASSERT_EQ(iface_names[0], "wlan0");
});
// Retrieve the exact iface object.
- sp<IWifiNanIface> nan_iface;
- chip_->getNanIface("wlan0", [&nan_iface](const WifiStatus& status,
- const sp<IWifiNanIface>& iface) {
- ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
- ASSERT_NE(iface.get(), nullptr);
- nan_iface = iface;
- });
+ sp<android::hardware::wifi::V1_0::IWifiNanIface> nan_iface;
+ chip_->getNanIface(
+ "wlan0",
+ [&nan_iface](
+ const WifiStatus& status,
+ const sp<android::hardware::wifi::V1_0::IWifiNanIface>& iface) {
+ ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
+ ASSERT_NE(iface.get(), nullptr);
+ nan_iface = iface;
+ });
// Remove the STA iface.
removeIface(IfaceType::STA, "wlan0");
diff --git a/wifi/1.4/default/tests/wifi_nan_iface_unit_tests.cpp b/wifi/1.4/default/tests/wifi_nan_iface_unit_tests.cpp
index 8aefa92..9022792 100644
--- a/wifi/1.4/default/tests/wifi_nan_iface_unit_tests.cpp
+++ b/wifi/1.4/default/tests/wifi_nan_iface_unit_tests.cpp
@@ -41,6 +41,9 @@
namespace V1_4 {
namespace implementation {
+using android::hardware::wifi::V1_2::IWifiNanIfaceEventCallback;
+using android::hardware::wifi::V1_2::NanDataPathConfirmInd;
+
bool CaptureIfaceEventHandlers(
const std::string& /* iface_name*/,
iface_util::IfaceEventHandlers in_iface_event_handlers,
@@ -96,9 +99,15 @@
Return<void>(uint16_t, const WifiNanStatus&));
MOCK_METHOD1(eventDataPathRequest,
Return<void>(const NanDataPathRequestInd&));
- MOCK_METHOD1(eventDataPathConfirm,
- Return<void>(const NanDataPathConfirmInd&));
+ MOCK_METHOD1(
+ eventDataPathConfirm,
+ Return<void>(
+ const android::hardware::wifi::V1_0::NanDataPathConfirmInd&));
MOCK_METHOD1(eventDataPathTerminated, Return<void>(uint32_t));
+ MOCK_METHOD1(eventDataPathConfirm_1_2,
+ Return<void>(const NanDataPathConfirmInd&));
+ MOCK_METHOD1(eventDataPathScheduleUpdate,
+ Return<void>(const NanDataPathScheduleUpdateInd&));
};
class WifiNanIfaceTest : public Test {
diff --git a/wifi/1.4/default/wifi_ap_iface.cpp b/wifi/1.4/default/wifi_ap_iface.cpp
index e677f19..8777a4c 100644
--- a/wifi/1.4/default/wifi_ap_iface.cpp
+++ b/wifi/1.4/default/wifi_ap_iface.cpp
@@ -64,7 +64,7 @@
}
Return<void> WifiApIface::getValidFrequenciesForBand(
- WifiBand band, getValidFrequenciesForBand_cb hidl_status_cb) {
+ V1_0::WifiBand band, getValidFrequenciesForBand_cb hidl_status_cb) {
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
&WifiApIface::getValidFrequenciesForBandInternal,
hidl_status_cb, band);
@@ -100,7 +100,7 @@
}
std::pair<WifiStatus, std::vector<WifiChannelInMhz>>
-WifiApIface::getValidFrequenciesForBandInternal(WifiBand band) {
+WifiApIface::getValidFrequenciesForBandInternal(V1_0::WifiBand band) {
static_assert(sizeof(WifiChannelInMhz) == sizeof(uint32_t),
"Size mismatch");
legacy_hal::wifi_error legacy_status;
diff --git a/wifi/1.4/default/wifi_ap_iface.h b/wifi/1.4/default/wifi_ap_iface.h
index 4f3438c..bf16d5e 100644
--- a/wifi/1.4/default/wifi_ap_iface.h
+++ b/wifi/1.4/default/wifi_ap_iface.h
@@ -49,7 +49,8 @@
Return<void> setCountryCode(const hidl_array<int8_t, 2>& code,
setCountryCode_cb hidl_status_cb) override;
Return<void> getValidFrequenciesForBand(
- WifiBand band, getValidFrequenciesForBand_cb hidl_status_cb) override;
+ V1_0::WifiBand band,
+ getValidFrequenciesForBand_cb hidl_status_cb) override;
Return<void> setMacAddress(const hidl_array<uint8_t, 6>& mac,
setMacAddress_cb hidl_status_cb) override;
Return<void> getFactoryMacAddress(
@@ -61,7 +62,7 @@
std::pair<WifiStatus, IfaceType> getTypeInternal();
WifiStatus setCountryCodeInternal(const std::array<int8_t, 2>& code);
std::pair<WifiStatus, std::vector<WifiChannelInMhz>>
- getValidFrequenciesForBandInternal(WifiBand band);
+ getValidFrequenciesForBandInternal(V1_0::WifiBand band);
WifiStatus setMacAddressInternal(const std::array<uint8_t, 6>& mac);
std::pair<WifiStatus, std::array<uint8_t, 6>>
getFactoryMacAddressInternal();
diff --git a/wifi/1.4/default/wifi_chip.cpp b/wifi/1.4/default/wifi_chip.cpp
index 7685ac6..a70457b 100644
--- a/wifi/1.4/default/wifi_chip.cpp
+++ b/wifi/1.4/default/wifi_chip.cpp
@@ -341,7 +341,7 @@
bool WifiChip::isValid() { return is_valid_; }
-std::set<sp<V1_2::IWifiChipEventCallback>> WifiChip::getEventCallbacks() {
+std::set<sp<IWifiChipEventCallback>> WifiChip::getEventCallbacks() {
return event_cb_handler_.getCallbacks();
}
@@ -628,6 +628,14 @@
hidl_status_cb, bound_iface);
}
+Return<void> WifiChip::registerEventCallback_1_4(
+ const sp<IWifiChipEventCallback>& event_callback,
+ registerEventCallback_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::registerEventCallbackInternal_1_4,
+ hidl_status_cb, event_callback);
+}
+
void WifiChip::invalidateAndRemoveAllIfaces() {
invalidateAndClearAll(ap_ifaces_);
invalidateAndClearAll(nan_ifaces_);
@@ -930,7 +938,8 @@
return createWifiStatus(WifiStatusCode::SUCCESS);
}
-std::pair<WifiStatus, sp<IWifiStaIface>> WifiChip::createStaIfaceInternal() {
+std::pair<WifiStatus, sp<V1_3::IWifiStaIface>>
+WifiChip::createStaIfaceInternal() {
if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::STA)) {
return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
}
@@ -954,7 +963,7 @@
return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(sta_ifaces_)};
}
-std::pair<WifiStatus, sp<IWifiStaIface>> WifiChip::getStaIfaceInternal(
+std::pair<WifiStatus, sp<V1_3::IWifiStaIface>> WifiChip::getStaIfaceInternal(
const std::string& ifname) {
const auto iface = findUsingName(sta_ifaces_, ifname);
if (!iface.get()) {
@@ -1021,6 +1030,12 @@
max_interval_in_sec, min_data_size_in_bytes);
ringbuffer_map_.insert(std::pair<std::string, Ringbuffer>(
ring_name, Ringbuffer(kMaxBufferSizeBytes)));
+ // if verbose logging enabled, turn up HAL daemon logging as well.
+ if (verbose_level < WifiDebugRingBufferVerboseLevel::VERBOSE) {
+ android::base::SetMinimumLogSeverity(android::base::DEBUG);
+ } else {
+ android::base::SetMinimumLogSeverity(android::base::VERBOSE);
+ }
return createWifiStatusFromLegacyError(legacy_status);
}
@@ -1119,11 +1134,9 @@
}
WifiStatus WifiChip::registerEventCallbackInternal_1_2(
- const sp<V1_2::IWifiChipEventCallback>& event_callback) {
- if (!event_cb_handler_.addCallback(event_callback)) {
- return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
- }
- return createWifiStatus(WifiStatusCode::SUCCESS);
+ const sp<V1_2::IWifiChipEventCallback>& /* event_callback */) {
+ // Deprecated support for this callback.
+ return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
}
WifiStatus WifiChip::selectTxPowerScenarioInternal_1_2(
@@ -1173,6 +1186,14 @@
return {createWifiStatus(WifiStatusCode::SUCCESS), rtt};
}
+WifiStatus WifiChip::registerEventCallbackInternal_1_4(
+ const sp<IWifiChipEventCallback>& event_callback) {
+ if (!event_cb_handler_.addCallback(event_callback)) {
+ return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+ }
+ return createWifiStatus(WifiStatusCode::SUCCESS);
+}
+
WifiStatus WifiChip::handleChipConfiguration(
/* NONNULL */ std::unique_lock<std::recursive_mutex>* lock,
ChipModeId mode_id) {
@@ -1275,7 +1296,7 @@
LOG(ERROR) << "Callback invoked on an invalid object";
return;
}
- std::vector<V1_2::IWifiChipEventCallback::RadioModeInfo>
+ std::vector<IWifiChipEventCallback::RadioModeInfo>
hidl_radio_mode_infos;
if (!hidl_struct_util::convertLegacyWifiMacInfosToHidl(
mac_infos, &hidl_radio_mode_infos)) {
@@ -1283,9 +1304,9 @@
return;
}
for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
- if (!callback->onRadioModeChange(hidl_radio_mode_infos)
+ if (!callback->onRadioModeChange_1_4(hidl_radio_mode_infos)
.isOk()) {
- LOG(ERROR) << "Failed to invoke onRadioModeChange"
+ LOG(ERROR) << "Failed to invoke onRadioModeChange_1_4"
<< " callback on: " << toString(callback);
}
}
diff --git a/wifi/1.4/default/wifi_chip.h b/wifi/1.4/default/wifi_chip.h
index 3bf1847..3323ade 100644
--- a/wifi/1.4/default/wifi_chip.h
+++ b/wifi/1.4/default/wifi_chip.h
@@ -71,7 +71,7 @@
// marked valid before processing them.
void invalidate();
bool isValid();
- std::set<sp<V1_2::IWifiChipEventCallback>> getEventCallbacks();
+ std::set<sp<IWifiChipEventCallback>> getEventCallbacks();
// HIDL methods exposed.
Return<void> getId(getId_cb hidl_status_cb) override;
@@ -156,6 +156,9 @@
Return<void> createRttController_1_4(
const sp<IWifiIface>& bound_iface,
createRttController_1_4_cb hidl_status_cb) override;
+ Return<void> registerEventCallback_1_4(
+ const sp<IWifiChipEventCallback>& event_callback,
+ registerEventCallback_1_4_cb hidl_status_cb) override;
private:
void invalidateAndRemoveAllIfaces();
@@ -194,9 +197,9 @@
std::pair<WifiStatus, sp<IWifiP2pIface>> getP2pIfaceInternal(
const std::string& ifname);
WifiStatus removeP2pIfaceInternal(const std::string& ifname);
- std::pair<WifiStatus, sp<IWifiStaIface>> createStaIfaceInternal();
+ std::pair<WifiStatus, sp<V1_3::IWifiStaIface>> createStaIfaceInternal();
std::pair<WifiStatus, std::vector<hidl_string>> getStaIfaceNamesInternal();
- std::pair<WifiStatus, sp<IWifiStaIface>> getStaIfaceInternal(
+ std::pair<WifiStatus, sp<V1_3::IWifiStaIface>> getStaIfaceInternal(
const std::string& ifname);
WifiStatus removeStaIfaceInternal(const std::string& ifname);
std::pair<WifiStatus, sp<V1_0::IWifiRttController>>
@@ -223,6 +226,9 @@
std::pair<WifiStatus, uint32_t> getCapabilitiesInternal_1_3();
std::pair<WifiStatus, sp<IWifiRttController>>
createRttControllerInternal_1_4(const sp<IWifiIface>& bound_iface);
+ WifiStatus registerEventCallbackInternal_1_4(
+ const sp<IWifiChipEventCallback>& event_callback);
+
WifiStatus handleChipConfiguration(
std::unique_lock<std::recursive_mutex>* lock, ChipModeId mode_id);
WifiStatus registerDebugRingBufferCallback();
@@ -271,7 +277,7 @@
// registration mechanism. Use this to check if we have already
// registered a callback.
bool debug_ring_buffer_cb_registered_;
- hidl_callback_util::HidlCallbackHandler<V1_2::IWifiChipEventCallback>
+ hidl_callback_util::HidlCallbackHandler<IWifiChipEventCallback>
event_cb_handler_;
DISALLOW_COPY_AND_ASSIGN(WifiChip);
diff --git a/wifi/1.4/default/wifi_nan_iface.cpp b/wifi/1.4/default/wifi_nan_iface.cpp
index 981acb2..073101c 100644
--- a/wifi/1.4/default/wifi_nan_iface.cpp
+++ b/wifi/1.4/default/wifi_nan_iface.cpp
@@ -576,7 +576,7 @@
}
Return<void> WifiNanIface::enableRequest(uint16_t cmd_id,
- const NanEnableRequest& msg,
+ const V1_0::NanEnableRequest& msg,
enableRequest_cb hidl_status_cb) {
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
&WifiNanIface::enableRequestInternal, hidl_status_cb,
@@ -584,7 +584,7 @@
}
Return<void> WifiNanIface::configRequest(uint16_t cmd_id,
- const NanConfigRequest& msg,
+ const V1_0::NanConfigRequest& msg,
configRequest_cb hidl_status_cb) {
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
&WifiNanIface::configRequestInternal, hidl_status_cb,
@@ -687,7 +687,7 @@
}
Return<void> WifiNanIface::enableRequest_1_2(
- uint16_t cmd_id, const NanEnableRequest& msg1,
+ uint16_t cmd_id, const V1_0::NanEnableRequest& msg1,
const V1_2::NanConfigRequestSupplemental& msg2,
enableRequest_1_2_cb hidl_status_cb) {
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
@@ -696,7 +696,7 @@
}
Return<void> WifiNanIface::configRequest_1_2(
- uint16_t cmd_id, const NanConfigRequest& msg1,
+ uint16_t cmd_id, const V1_0::NanConfigRequest& msg1,
const V1_2::NanConfigRequestSupplemental& msg2,
configRequest_1_2_cb hidl_status_cb) {
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
@@ -704,6 +704,24 @@
hidl_status_cb, cmd_id, msg1, msg2);
}
+Return<void> WifiNanIface::enableRequest_1_4(
+ uint16_t cmd_id, const NanEnableRequest& msg1,
+ const V1_2::NanConfigRequestSupplemental& msg2,
+ enableRequest_1_4_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiNanIface::enableRequest_1_4Internal,
+ hidl_status_cb, cmd_id, msg1, msg2);
+}
+
+Return<void> WifiNanIface::configRequest_1_4(
+ uint16_t cmd_id, const NanConfigRequest& msg1,
+ const V1_2::NanConfigRequestSupplemental& msg2,
+ configRequest_1_4_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiNanIface::configRequest_1_4Internal,
+ hidl_status_cb, cmd_id, msg1, msg2);
+}
+
std::pair<WifiStatus, std::string> WifiNanIface::getNameInternal() {
return {createWifiStatus(WifiStatusCode::SUCCESS), ifname_};
}
@@ -727,12 +745,12 @@
}
WifiStatus WifiNanIface::enableRequestInternal(
- uint16_t /* cmd_id */, const NanEnableRequest& /* msg */) {
+ uint16_t /* cmd_id */, const V1_0::NanEnableRequest& /* msg */) {
return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
}
WifiStatus WifiNanIface::configRequestInternal(
- uint16_t /* cmd_id */, const NanConfigRequest& /* msg */) {
+ uint16_t /* cmd_id */, const V1_0::NanConfigRequest& /* msg */) {
return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
}
@@ -855,10 +873,22 @@
}
WifiStatus WifiNanIface::enableRequest_1_2Internal(
+ uint16_t /* cmd_id */, const V1_0::NanEnableRequest& /* msg1 */,
+ const V1_2::NanConfigRequestSupplemental& /*msg2 */) {
+ return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
+}
+
+WifiStatus WifiNanIface::configRequest_1_2Internal(
+ uint16_t /* cmd_id */, const V1_0::NanConfigRequest& /* msg1 */,
+ const V1_2::NanConfigRequestSupplemental& /* msg2 */) {
+ return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
+}
+
+WifiStatus WifiNanIface::enableRequest_1_4Internal(
uint16_t cmd_id, const NanEnableRequest& msg1,
const V1_2::NanConfigRequestSupplemental& msg2) {
legacy_hal::NanEnableRequest legacy_msg;
- if (!hidl_struct_util::convertHidlNanEnableRequest_1_2ToLegacy(
+ if (!hidl_struct_util::convertHidlNanEnableRequest_1_4ToLegacy(
msg1, msg2, &legacy_msg)) {
return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
}
@@ -867,11 +897,11 @@
return createWifiStatusFromLegacyError(legacy_status);
}
-WifiStatus WifiNanIface::configRequest_1_2Internal(
+WifiStatus WifiNanIface::configRequest_1_4Internal(
uint16_t cmd_id, const NanConfigRequest& msg1,
const V1_2::NanConfigRequestSupplemental& msg2) {
legacy_hal::NanConfigRequest legacy_msg;
- if (!hidl_struct_util::convertHidlNanConfigRequest_1_2ToLegacy(
+ if (!hidl_struct_util::convertHidlNanConfigRequest_1_4ToLegacy(
msg1, msg2, &legacy_msg)) {
return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
}
diff --git a/wifi/1.4/default/wifi_nan_iface.h b/wifi/1.4/default/wifi_nan_iface.h
index e3a5c34..c16628b 100644
--- a/wifi/1.4/default/wifi_nan_iface.h
+++ b/wifi/1.4/default/wifi_nan_iface.h
@@ -19,7 +19,7 @@
#include <android-base/macros.h>
#include <android/hardware/wifi/1.0/IWifiNanIfaceEventCallback.h>
-#include <android/hardware/wifi/1.2/IWifiNanIface.h>
+#include <android/hardware/wifi/1.4/IWifiNanIface.h>
#include "hidl_callback_util.h"
#include "wifi_iface_util.h"
@@ -31,11 +31,12 @@
namespace V1_4 {
namespace implementation {
using namespace android::hardware::wifi::V1_0;
+using namespace android::hardware::wifi::V1_2;
/**
* HIDL interface object used to control a NAN Iface instance.
*/
-class WifiNanIface : public V1_2::IWifiNanIface {
+class WifiNanIface : public V1_4::IWifiNanIface {
public:
WifiNanIface(const std::string& ifname,
const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
@@ -53,9 +54,11 @@
registerEventCallback_cb hidl_status_cb) override;
Return<void> getCapabilitiesRequest(
uint16_t cmd_id, getCapabilitiesRequest_cb hidl_status_cb) override;
- Return<void> enableRequest(uint16_t cmd_id, const NanEnableRequest& msg,
+ Return<void> enableRequest(uint16_t cmd_id,
+ const V1_0::NanEnableRequest& msg,
enableRequest_cb hidl_status_cb) override;
- Return<void> configRequest(uint16_t cmd_id, const NanConfigRequest& msg,
+ Return<void> configRequest(uint16_t cmd_id,
+ const V1_0::NanConfigRequest& msg,
configRequest_cb hidl_status_cb) override;
Return<void> disableRequest(uint16_t cmd_id,
disableRequest_cb hidl_status_cb) override;
@@ -94,10 +97,18 @@
const sp<V1_2::IWifiNanIfaceEventCallback>& callback,
registerEventCallback_1_2_cb hidl_status_cb) override;
Return<void> enableRequest_1_2(
- uint16_t cmd_id, const NanEnableRequest& msg1,
+ uint16_t cmd_id, const V1_0::NanEnableRequest& msg1,
const V1_2::NanConfigRequestSupplemental& msg2,
enableRequest_1_2_cb hidl_status_cb) override;
Return<void> configRequest_1_2(
+ uint16_t cmd_id, const V1_0::NanConfigRequest& msg1,
+ const V1_2::NanConfigRequestSupplemental& msg2,
+ configRequest_1_2_cb hidl_status_cb) override;
+ Return<void> enableRequest_1_4(
+ uint16_t cmd_id, const NanEnableRequest& msg1,
+ const V1_2::NanConfigRequestSupplemental& msg2,
+ enableRequest_1_2_cb hidl_status_cb) override;
+ Return<void> configRequest_1_4(
uint16_t cmd_id, const NanConfigRequest& msg1,
const V1_2::NanConfigRequestSupplemental& msg2,
configRequest_1_2_cb hidl_status_cb) override;
@@ -110,9 +121,9 @@
const sp<V1_0::IWifiNanIfaceEventCallback>& callback);
WifiStatus getCapabilitiesRequestInternal(uint16_t cmd_id);
WifiStatus enableRequestInternal(uint16_t cmd_id,
- const NanEnableRequest& msg);
+ const V1_0::NanEnableRequest& msg);
WifiStatus configRequestInternal(uint16_t cmd_id,
- const NanConfigRequest& msg);
+ const V1_0::NanConfigRequest& msg);
WifiStatus disableRequestInternal(uint16_t cmd_id);
WifiStatus startPublishRequestInternal(uint16_t cmd_id,
const NanPublishRequest& msg);
@@ -136,9 +147,15 @@
WifiStatus registerEventCallback_1_2Internal(
const sp<V1_2::IWifiNanIfaceEventCallback>& callback);
WifiStatus enableRequest_1_2Internal(
- uint16_t cmd_id, const NanEnableRequest& msg1,
+ uint16_t cmd_id, const V1_0::NanEnableRequest& msg1,
const V1_2::NanConfigRequestSupplemental& msg2);
WifiStatus configRequest_1_2Internal(
+ uint16_t cmd_id, const V1_0::NanConfigRequest& msg,
+ const V1_2::NanConfigRequestSupplemental& msg2);
+ WifiStatus enableRequest_1_4Internal(
+ uint16_t cmd_id, const NanEnableRequest& msg1,
+ const V1_2::NanConfigRequestSupplemental& msg2);
+ WifiStatus configRequest_1_4Internal(
uint16_t cmd_id, const NanConfigRequest& msg,
const V1_2::NanConfigRequestSupplemental& msg2);
diff --git a/wifi/1.4/default/wifi_sta_iface.cpp b/wifi/1.4/default/wifi_sta_iface.cpp
index 8e1ada1..e2ea6e4 100644
--- a/wifi/1.4/default/wifi_sta_iface.cpp
+++ b/wifi/1.4/default/wifi_sta_iface.cpp
@@ -113,7 +113,7 @@
}
Return<void> WifiStaIface::getValidFrequenciesForBand(
- WifiBand band, getValidFrequenciesForBand_cb hidl_status_cb) {
+ V1_0::WifiBand band, getValidFrequenciesForBand_cb hidl_status_cb) {
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
&WifiStaIface::getValidFrequenciesForBandInternal,
hidl_status_cb, band);
@@ -266,13 +266,6 @@
hidl_status_cb);
}
-Return<void> WifiStaIface::getCapabilities_1_4(
- getCapabilities_cb hidl_status_cb) {
- return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
- &WifiStaIface::getCapabilitiesInternal_1_4,
- hidl_status_cb);
-}
-
std::pair<WifiStatus, std::string> WifiStaIface::getNameInternal() {
return {createWifiStatus(WifiStatusCode::SUCCESS), ifname_};
}
@@ -290,7 +283,26 @@
}
std::pair<WifiStatus, uint32_t> WifiStaIface::getCapabilitiesInternal() {
- return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), 0};
+ legacy_hal::wifi_error legacy_status;
+ uint64_t legacy_feature_set;
+ std::tie(legacy_status, legacy_feature_set) =
+ legacy_hal_.lock()->getSupportedFeatureSet(ifname_);
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ return {createWifiStatusFromLegacyError(legacy_status), 0};
+ }
+ uint32_t legacy_logger_feature_set;
+ std::tie(legacy_status, legacy_logger_feature_set) =
+ legacy_hal_.lock()->getLoggerSupportedFeatureSet(ifname_);
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ // some devices don't support querying logger feature set
+ legacy_logger_feature_set = 0;
+ }
+ uint32_t hidl_caps;
+ if (!hidl_struct_util::convertLegacyFeaturesToHidlStaCapabilities(
+ legacy_feature_set, legacy_logger_feature_set, &hidl_caps)) {
+ return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), 0};
+ }
+ return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps};
}
std::pair<WifiStatus, StaApfPacketFilterCapabilities>
@@ -344,7 +356,7 @@
}
std::pair<WifiStatus, std::vector<WifiChannelInMhz>>
-WifiStaIface::getValidFrequenciesForBandInternal(WifiBand band) {
+WifiStaIface::getValidFrequenciesForBandInternal(V1_0::WifiBand band) {
static_assert(sizeof(WifiChannelInMhz) == sizeof(uint32_t),
"Size mismatch");
legacy_hal::wifi_error legacy_status;
@@ -628,29 +640,6 @@
return {createWifiStatus(WifiStatusCode::SUCCESS), mac};
}
-std::pair<WifiStatus, uint32_t> WifiStaIface::getCapabilitiesInternal_1_4() {
- legacy_hal::wifi_error legacy_status;
- uint64_t legacy_feature_set;
- std::tie(legacy_status, legacy_feature_set) =
- legacy_hal_.lock()->getSupportedFeatureSet(ifname_);
- if (legacy_status != legacy_hal::WIFI_SUCCESS) {
- return {createWifiStatusFromLegacyError(legacy_status), 0};
- }
- uint32_t legacy_logger_feature_set;
- std::tie(legacy_status, legacy_logger_feature_set) =
- legacy_hal_.lock()->getLoggerSupportedFeatureSet(ifname_);
- if (legacy_status != legacy_hal::WIFI_SUCCESS) {
- // some devices don't support querying logger feature set
- legacy_logger_feature_set = 0;
- }
- uint32_t hidl_caps;
- if (!hidl_struct_util::convertLegacyFeaturesToHidlStaCapabilities(
- legacy_feature_set, legacy_logger_feature_set, &hidl_caps)) {
- return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), 0};
- }
- return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps};
-}
-
} // namespace implementation
} // namespace V1_4
} // namespace wifi
diff --git a/wifi/1.4/default/wifi_sta_iface.h b/wifi/1.4/default/wifi_sta_iface.h
index ccf234f..dee04f2 100644
--- a/wifi/1.4/default/wifi_sta_iface.h
+++ b/wifi/1.4/default/wifi_sta_iface.h
@@ -19,7 +19,7 @@
#include <android-base/macros.h>
#include <android/hardware/wifi/1.0/IWifiStaIfaceEventCallback.h>
-#include <android/hardware/wifi/1.4/IWifiStaIface.h>
+#include <android/hardware/wifi/1.3/IWifiStaIface.h>
#include "hidl_callback_util.h"
#include "wifi_iface_util.h"
@@ -35,7 +35,7 @@
/**
* HIDL interface object used to control a STA Iface instance.
*/
-class WifiStaIface : public V1_4::IWifiStaIface {
+class WifiStaIface : public V1_3::IWifiStaIface {
public:
WifiStaIface(const std::string& ifname,
const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
@@ -63,7 +63,8 @@
Return<void> getBackgroundScanCapabilities(
getBackgroundScanCapabilities_cb hidl_status_cb) override;
Return<void> getValidFrequenciesForBand(
- WifiBand band, getValidFrequenciesForBand_cb hidl_status_cb) override;
+ V1_0::WifiBand band,
+ getValidFrequenciesForBand_cb hidl_status_cb) override;
Return<void> startBackgroundScan(
uint32_t cmd_id, const StaBackgroundScanParameters& params,
startBackgroundScan_cb hidl_status_cb) override;
@@ -111,8 +112,6 @@
setMacAddress_cb hidl_status_cb) override;
Return<void> getFactoryMacAddress(
getFactoryMacAddress_cb hidl_status_cb) override;
- Return<void> getCapabilities_1_4(
- getCapabilities_1_4_cb hidl_status_cb) override;
private:
// Corresponding worker functions for the HIDL methods.
@@ -130,7 +129,7 @@
std::pair<WifiStatus, StaBackgroundScanCapabilities>
getBackgroundScanCapabilitiesInternal();
std::pair<WifiStatus, std::vector<WifiChannelInMhz>>
- getValidFrequenciesForBandInternal(WifiBand band);
+ getValidFrequenciesForBandInternal(V1_0::WifiBand band);
WifiStatus startBackgroundScanInternal(
uint32_t cmd_id, const StaBackgroundScanParameters& params);
WifiStatus stopBackgroundScanInternal(uint32_t cmd_id);
@@ -161,7 +160,6 @@
WifiStatus setMacAddressInternal(const std::array<uint8_t, 6>& mac);
std::pair<WifiStatus, std::array<uint8_t, 6>>
getFactoryMacAddressInternal();
- std::pair<WifiStatus, uint32_t> getCapabilitiesInternal_1_4();
std::string ifname_;
std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
diff --git a/wifi/1.4/types.hal b/wifi/1.4/types.hal
index 232e26f..4f1d22e 100644
--- a/wifi/1.4/types.hal
+++ b/wifi/1.4/types.hal
@@ -17,6 +17,8 @@
package android.hardware.wifi@1.4;
import @1.0::MacAddress;
+import @1.0::NanBandIndex;
+import @1.0::NanBandSpecificConfig;
import @1.0::Rssi;
import @1.0::RttBw;
import @1.0::RttConfig;
@@ -26,13 +28,47 @@
import @1.0::RttType;
import @1.0::TimeSpanInPs;
import @1.0::TimeStampInUs;
+import @1.0::WifiBand;
import @1.0::WifiChannelInfo;
+import @1.0::WifiChannelInMhz;
import @1.0::WifiChannelWidthInMhz;
import @1.0::WifiInformationElement;
import @1.0::WifiRateNss;
import @1.0::WifiRatePreamble;
/**
+ * Wifi bands defined in 80211 spec.
+ */
+enum WifiBand : @1.0::WifiBand {
+ /**
+ * 6 GHz.
+ */
+ BAND_6GHZ = 8,
+ /**
+ * 5 GHz no DFS + 6 GHz.
+ */
+ BAND_5GHZ_6GHZ = 10,
+ /**
+ * 2.4 GHz + 5 GHz no DFS + 6 GHz.
+ */
+ BAND_24GHZ_5GHZ_6GHZ = 11,
+ /**
+ * 2.4 GHz + 5 GHz with DFS + 6 GHz.
+ */
+ BAND_24GHZ_5GHZ_WITH_DFS_6GHZ = 15,
+};
+
+/**
+ * The discovery bands supported by NAN.
+ */
+enum NanBandIndex : @1.0::NanBandIndex {
+ /**
+ * Index for 6 GHz band.
+ */
+ NAN_BAND_6GHZ = 2,
+};
+
+/**
* Wifi Rate Preamble
*/
enum WifiRatePreamble : @1.0::WifiRatePreamble {
@@ -53,6 +89,183 @@
};
/**
+ * Debug configuration parameters. Many of these allow non-standard-compliant operation and are
+ * not intended for normal operational mode.
+ */
+struct NanDebugConfig {
+ /**
+ * Specification of the lower 2 bytes of the cluster ID. The cluster ID is 50-60-9a-01-00-00 to
+ * 50-60-9a-01-FF-FF. Configuration of the bottom and top values of the range (which defaults to
+ * 0x0000 and 0xFFFF respectively).
+ * Configuration is only used if |validClusterIdVals| is set to true.
+ */
+ bool validClusterIdVals;
+
+ uint16_t clusterIdBottomRangeVal;
+
+ uint16_t clusterIdTopRangeVal;
+
+ /**
+ * NAN management interface address, if specified (|validIntfAddrVal| is true) then overrides any
+ * other configuration (specifically the default randomization configured by
+ * |NanConfigRequest.macAddressRandomizationIntervalSec|).
+ */
+ bool validIntfAddrVal;
+
+ MacAddress intfAddrVal;
+
+ /**
+ * Combination of the 24 bit Organizationally Unique ID (OUI) and the 8 bit OUI Type.
+ * Used if |validOuiVal| is set to true.
+ */
+ bool validOuiVal;
+
+ uint32_t ouiVal;
+
+ /**
+ * Force the Random Factor to the specified value for all transmitted Sync/Discovery beacons.
+ * Used if |validRandomFactorForceVal| is set to true.
+ * NAN Spec: Master Indication Attribute / Random Factor
+ */
+ bool validRandomFactorForceVal;
+
+ uint8_t randomFactorForceVal;
+
+ /**
+ * Forces the hop-count for all transmitted Sync and Discovery Beacons NO matter the real
+ * hop-count being received over the air. Used if the |validHopCountForceVal}| flag is set to
+ * true.
+ * NAN Spec: Cluster Attribute / Anchor Master Information / Hop Count to Anchor Master
+ */
+ bool validHopCountForceVal;
+
+ uint8_t hopCountForceVal;
+
+ /**
+ * Frequency in MHz to of the discovery channel in the specified band. Indexed by |NanBandIndex|.
+ * Used if the |validDiscoveryChannelVal| is set to true.
+ */
+ bool validDiscoveryChannelVal;
+
+ WifiChannelInMhz[3] discoveryChannelMhzVal;
+
+ /**
+ * Specifies whether sync/discovery beacons are transmitted in the specified band. Indexed by
+ * |NanBandIndex|. Used if the |validUseBeaconsInBandVal| is set to true.
+ */
+ bool validUseBeaconsInBandVal;
+
+ bool[3] useBeaconsInBandVal;
+
+ /**
+ * Specifies whether SDF (service discovery frames) are transmitted in the specified band. Indexed
+ * by |NanBandIndex|. Used if the |validUseSdfInBandVal| is set to true.
+ */
+ bool validUseSdfInBandVal;
+
+ bool[3] useSdfInBandVal;
+};
+
+/**
+ * Configuration parameters of NAN: used when enabling and re-configuring a NAN cluster.
+ */
+struct NanConfigRequest {
+ /**
+ * Master preference of this device.
+ * NAN Spec: Master Indication Attribute / Master Preference
+ */
+ uint8_t masterPref;
+
+ /**
+ * Controls whether or not the |IWifiNanIfaceEventCallback.eventClusterEvent| will be delivered
+ * for |NanClusterEventType.DISCOVERY_MAC_ADDRESS_CHANGED|.
+ */
+ bool disableDiscoveryAddressChangeIndication;
+
+ /**
+ * Controls whether or not the |IWifiNanIfaceEventCallback.eventClusterEvent| will be delivered
+ * for |NanClusterEventType.STARTED_CLUSTER|.
+ */
+ bool disableStartedClusterIndication;
+
+ /**
+ * Controls whether or not the |IWifiNanIfaceEventCallback.eventClusterEvent| will be delivered
+ * for |NanClusterEventType.JOINED_CLUSTER|.
+ */
+ bool disableJoinedClusterIndication;
+
+ /**
+ * Control whether publish service IDs are included in Sync/Discovery beacons.
+ * NAN Spec: Service ID List Attribute
+ */
+ bool includePublishServiceIdsInBeacon;
+
+ /**
+ * If |includePublishServiceIdsInBeacon| is true then specifies the number of publish service IDs
+ * to include in the Sync/Discovery beacons:
+ * Value = 0: include as many service IDs as will fit into the maximum allowed beacon frame size.
+ * Value must fit within 7 bits - i.e. <= 127.
+ */
+ uint8_t numberOfPublishServiceIdsInBeacon;
+
+ /**
+ * Control whether subscribe service IDs are included in Sync/Discovery beacons.
+ * Spec: Subscribe Service ID List Attribute
+ */
+ bool includeSubscribeServiceIdsInBeacon;
+
+ /**
+ * If |includeSubscribeServiceIdsInBeacon| is true then specifies the number of subscribe service
+ * IDs to include in the Sync/Discovery beacons:
+ * Value = 0: include as many service IDs as will fit into the maximum allowed beacon frame size.
+ * Value must fit within 7 bits - i.e. <= 127.
+ */
+ uint8_t numberOfSubscribeServiceIdsInBeacon;
+
+ /**
+ * Number of samples used to calculate RSSI.
+ */
+ uint16_t rssiWindowSize;
+
+ /**
+ * Specifies the interval in seconds that the NAN management interface MAC address is randomized.
+ * A value of 0 is used to disable the MAC address randomization
+ */
+ uint32_t macAddressRandomizationIntervalSec;
+
+ /**
+ * Additional configuration provided per band: indexed by |NanBandIndex|.
+ */
+ NanBandSpecificConfig[3] bandSpecificConfig;
+};
+
+/**
+ * Enable requests for NAN: start-up configuration |IWifiNanIface.enableRequest|.
+ */
+struct NanEnableRequest {
+ /**
+ * Enable operation in a specific band: indexed by |NanBandIndex|.
+ */
+ bool[3] operateInBand;
+
+ /**
+ * Specify extent of cluster by specifying the max hop count.
+ */
+ uint8_t hopCountMax;
+
+ /**
+ * Configurations of NAN cluster operation. Can also be modified at run-time using
+ * |IWifiNanIface.configRequest|.
+ */
+ NanConfigRequest configParams;
+
+ /**
+ * Non-standard configurations of NAN cluster operation - useful for debugging operations.
+ */
+ NanDebugConfig debugConfigs;
+};
+
+/**
* RTT configuration.
*/
struct RttConfig {
diff --git a/wifi/1.4/vts/functional/Android.bp b/wifi/1.4/vts/functional/Android.bp
index c71b319..46ac3ee 100644
--- a/wifi/1.4/vts/functional/Android.bp
+++ b/wifi/1.4/vts/functional/Android.bp
@@ -21,6 +21,8 @@
srcs: [
"VtsHalWifiV1_4TargetTest.cpp",
"wifi_ap_iface_hidl_test.cpp",
+ "wifi_chip_hidl_test.cpp",
+ "wifi_nan_iface_hidl_test.cpp"
],
static_libs: [
"VtsHalWifiV1_0TargetTestUtil",
diff --git a/wifi/1.4/vts/functional/wifi_chip_hidl_test.cpp b/wifi/1.4/vts/functional/wifi_chip_hidl_test.cpp
new file mode 100644
index 0000000..8ca5214
--- /dev/null
+++ b/wifi/1.4/vts/functional/wifi_chip_hidl_test.cpp
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#include <VtsHalHidlTargetCallbackBase.h>
+#include <android-base/logging.h>
+
+#undef NAN // NAN is defined in bionic/libc/include/math.h:38
+
+#include <android/hardware/wifi/1.4/IWifi.h>
+#include <android/hardware/wifi/1.4/IWifiChip.h>
+#include <android/hardware/wifi/1.4/IWifiChipEventCallback.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
+
+#include "wifi_hidl_call_util.h"
+#include "wifi_hidl_test_utils.h"
+
+using ::android::sp;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::wifi::V1_0::IfaceType;
+using ::android::hardware::wifi::V1_0::WifiDebugRingBufferStatus;
+using ::android::hardware::wifi::V1_0::WifiStatus;
+using ::android::hardware::wifi::V1_0::WifiStatusCode;
+using ::android::hardware::wifi::V1_4::IWifiChip;
+using ::android::hardware::wifi::V1_4::IWifiChipEventCallback;
+
+/**
+ * Fixture to use for all Wifi chip HIDL interface tests.
+ */
+class WifiChipHidlTest : public ::testing::TestWithParam<std::string> {
+ public:
+ virtual void SetUp() override {
+ wifi_chip_ = IWifiChip::castFrom(getWifiChip(GetInstanceName()));
+ ASSERT_NE(nullptr, wifi_chip_.get());
+ }
+
+ virtual void TearDown() override { stopWifi(GetInstanceName()); }
+
+ // A simple test implementation of WifiChipEventCallback.
+ class WifiChipEventCallback
+ : public ::testing::VtsHalHidlTargetCallbackBase<WifiChipHidlTest>,
+ public IWifiChipEventCallback {
+ public:
+ WifiChipEventCallback(){};
+
+ virtual ~WifiChipEventCallback() = default;
+
+ Return<void> onChipReconfigured(uint32_t modeId __unused) {
+ return Void();
+ };
+
+ Return<void> onChipReconfigureFailure(
+ const WifiStatus& status __unused) {
+ return Void();
+ };
+
+ Return<void> onIfaceAdded(IfaceType type __unused,
+ const hidl_string& name __unused) {
+ return Void();
+ };
+
+ Return<void> onIfaceRemoved(IfaceType type __unused,
+ const hidl_string& name __unused) {
+ return Void();
+ };
+
+ Return<void> onDebugRingBufferDataAvailable(
+ const WifiDebugRingBufferStatus& status __unused,
+ const hidl_vec<uint8_t>& data __unused) {
+ return Void();
+ };
+
+ Return<void> onDebugErrorAlert(int32_t errorCode __unused,
+ const hidl_vec<uint8_t>& debugData
+ __unused) {
+ return Void();
+ };
+
+ Return<void> onRadioModeChange(
+ const hidl_vec<::android::hardware::wifi::V1_2::
+ IWifiChipEventCallback::RadioModeInfo>&
+ radioModeInfos __unused) {
+ return Void();
+ };
+
+ Return<void> onRadioModeChange_1_4(
+ const hidl_vec<RadioModeInfo>& radioModeInfos __unused) {
+ return Void();
+ };
+ };
+
+ protected:
+ sp<IWifiChip> wifi_chip_;
+
+ private:
+ std::string GetInstanceName() { return GetParam(); }
+};
+
+/*
+ * registerEventCallback_1_4
+ * This test case tests the registerEventCallback_1_4() API which registers
+ * a call back function with the hal implementation
+ *
+ * Note: it is not feasible to test the invocation of the call back function
+ * since event is triggered internally in the HAL implementation, and can not be
+ * triggered from the test case
+ */
+TEST_P(WifiChipHidlTest, registerEventCallback_1_4) {
+ sp<WifiChipEventCallback> wifiChipEventCallback =
+ new WifiChipEventCallback();
+ const auto& status = HIDL_INVOKE(wifi_chip_, registerEventCallback_1_4,
+ wifiChipEventCallback);
+
+ if (status.code != WifiStatusCode::SUCCESS) {
+ EXPECT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED, status.code);
+ return;
+ }
+}
diff --git a/wifi/1.4/vts/functional/wifi_nan_iface_hidl_test.cpp b/wifi/1.4/vts/functional/wifi_nan_iface_hidl_test.cpp
new file mode 100644
index 0000000..245e906
--- /dev/null
+++ b/wifi/1.4/vts/functional/wifi_nan_iface_hidl_test.cpp
@@ -0,0 +1,544 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Nanache 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.
+ */
+
+#include <android-base/logging.h>
+
+#include <android/hardware/wifi/1.2/IWifiNanIfaceEventCallback.h>
+#include <android/hardware/wifi/1.4/IWifi.h>
+#include <android/hardware/wifi/1.4/IWifiNanIface.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
+#include <chrono>
+#include <condition_variable>
+#include <mutex>
+
+#include "wifi_hidl_call_util.h"
+#include "wifi_hidl_test_utils.h"
+
+using namespace ::android::hardware::wifi::V1_0;
+using namespace ::android::hardware::wifi::V1_2;
+using namespace ::android::hardware::wifi::V1_4;
+
+using ::android::sp;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+
+#define TIMEOUT_PERIOD 10
+
+android::sp<android::hardware::wifi::V1_4::IWifiNanIface> getWifiNanIface_1_4(
+ const std::string& instance_name) {
+ return android::hardware::wifi::V1_4::IWifiNanIface::castFrom(
+ getWifiNanIface(instance_name));
+}
+
+/**
+ * Fixture to use for all NAN Iface HIDL interface tests.
+ */
+class WifiNanIfaceHidlTest : public ::testing::TestWithParam<std::string> {
+ public:
+ virtual void SetUp() override {
+ iwifiNanIface = getWifiNanIface_1_4(GetInstanceName());
+ ASSERT_NE(nullptr, iwifiNanIface.get());
+ ASSERT_EQ(WifiStatusCode::SUCCESS,
+ HIDL_INVOKE(iwifiNanIface, registerEventCallback_1_2,
+ new WifiNanIfaceEventCallback(*this))
+ .code);
+ }
+
+ virtual void TearDown() override { stopWifi(GetInstanceName()); }
+
+ /* Used as a mechanism to inform the test about data/event callback */
+ inline void notify() {
+ std::unique_lock<std::mutex> lock(mtx_);
+ count_++;
+ cv_.notify_one();
+ }
+
+ enum CallbackType {
+ INVALID = -2,
+ ANY_CALLBACK = -1,
+
+ NOTIFY_CAPABILITIES_RESPONSE = 0,
+ NOTIFY_ENABLE_RESPONSE,
+ NOTIFY_CONFIG_RESPONSE,
+ NOTIFY_DISABLE_RESPONSE,
+ NOTIFY_START_PUBLISH_RESPONSE,
+ NOTIFY_STOP_PUBLISH_RESPONSE,
+ NOTIFY_START_SUBSCRIBE_RESPONSE,
+ NOTIFY_STOP_SUBSCRIBE_RESPONSE,
+ NOTIFY_TRANSMIT_FOLLOWUP_RESPONSE,
+ NOTIFY_CREATE_DATA_INTERFACE_RESPONSE,
+ NOTIFY_DELETE_DATA_INTERFACE_RESPONSE,
+ NOTIFY_INITIATE_DATA_PATH_RESPONSE,
+ NOTIFY_RESPOND_TO_DATA_PATH_INDICATION_RESPONSE,
+ NOTIFY_TERMINATE_DATA_PATH_RESPONSE,
+
+ EVENT_CLUSTER_EVENT,
+ EVENT_DISABLED,
+ EVENT_PUBLISH_TERMINATED,
+ EVENT_SUBSCRIBE_TERMINATED,
+ EVENT_MATCH,
+ EVENT_MATCH_EXPIRED,
+ EVENT_FOLLOWUP_RECEIVED,
+ EVENT_TRANSMIT_FOLLOWUP,
+ EVENT_DATA_PATH_REQUEST,
+ EVENT_DATA_PATH_CONFIRM,
+ EVENT_DATA_PATH_TERMINATED,
+ EVENT_DATA_PATH_CONFIRM_1_2,
+ EVENT_DATA_PATH_SCHEDULE_UPDATE
+ };
+
+ /* Test code calls this function to wait for data/event callback */
+ /* Must set callbackType = INVALID before call this function */
+ inline std::cv_status wait(CallbackType waitForCallbackType) {
+ std::unique_lock<std::mutex> lock(mtx_);
+
+ EXPECT_NE(INVALID, waitForCallbackType); // can't ASSERT in a
+ // non-void-returning method
+
+ std::cv_status status = std::cv_status::no_timeout;
+ auto now = std::chrono::system_clock::now();
+ while (count_ == 0) {
+ status = cv_.wait_until(lock,
+ now + std::chrono::seconds(TIMEOUT_PERIOD));
+ if (status == std::cv_status::timeout) return status;
+ if (waitForCallbackType != ANY_CALLBACK &&
+ callbackType != INVALID &&
+ callbackType != waitForCallbackType) {
+ count_--;
+ }
+ }
+ count_--;
+ return status;
+ }
+
+ class WifiNanIfaceEventCallback
+ : public ::android::hardware::wifi::V1_2::IWifiNanIfaceEventCallback {
+ WifiNanIfaceHidlTest& parent_;
+
+ public:
+ WifiNanIfaceEventCallback(WifiNanIfaceHidlTest& parent)
+ : parent_(parent){};
+
+ virtual ~WifiNanIfaceEventCallback() = default;
+
+ Return<void> notifyCapabilitiesResponse(
+ uint16_t id, const WifiNanStatus& status,
+ const NanCapabilities& capabilities) override {
+ parent_.callbackType = NOTIFY_CAPABILITIES_RESPONSE;
+
+ parent_.id = id;
+ parent_.status = status;
+ parent_.capabilities = capabilities;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> notifyEnableResponse(
+ uint16_t id, const WifiNanStatus& status) override {
+ parent_.callbackType = NOTIFY_ENABLE_RESPONSE;
+
+ parent_.id = id;
+ parent_.status = status;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> notifyConfigResponse(
+ uint16_t id, const WifiNanStatus& status) override {
+ parent_.callbackType = NOTIFY_CONFIG_RESPONSE;
+
+ parent_.id = id;
+ parent_.status = status;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> notifyDisableResponse(
+ uint16_t id, const WifiNanStatus& status) override {
+ parent_.callbackType = NOTIFY_DISABLE_RESPONSE;
+
+ parent_.id = id;
+ parent_.status = status;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> notifyStartPublishResponse(uint16_t id,
+ const WifiNanStatus& status,
+ uint8_t sessionId) override {
+ parent_.callbackType = NOTIFY_START_PUBLISH_RESPONSE;
+
+ parent_.id = id;
+ parent_.status = status;
+ parent_.sessionId = sessionId;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> notifyStopPublishResponse(
+ uint16_t id, const WifiNanStatus& status) override {
+ parent_.callbackType = NOTIFY_STOP_PUBLISH_RESPONSE;
+
+ parent_.id = id;
+ parent_.status = status;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> notifyStartSubscribeResponse(uint16_t id,
+ const WifiNanStatus& status,
+ uint8_t sessionId) override {
+ parent_.callbackType = NOTIFY_START_SUBSCRIBE_RESPONSE;
+
+ parent_.id = id;
+ parent_.status = status;
+ parent_.sessionId = sessionId;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> notifyStopSubscribeResponse(
+ uint16_t id, const WifiNanStatus& status) override {
+ parent_.callbackType = NOTIFY_STOP_SUBSCRIBE_RESPONSE;
+
+ parent_.id = id;
+ parent_.status = status;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> notifyTransmitFollowupResponse(
+ uint16_t id, const WifiNanStatus& status) override {
+ parent_.callbackType = NOTIFY_TRANSMIT_FOLLOWUP_RESPONSE;
+
+ parent_.id = id;
+ parent_.status = status;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> notifyCreateDataInterfaceResponse(
+ uint16_t id, const WifiNanStatus& status) override {
+ parent_.callbackType = NOTIFY_CREATE_DATA_INTERFACE_RESPONSE;
+
+ parent_.id = id;
+ parent_.status = status;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> notifyDeleteDataInterfaceResponse(
+ uint16_t id, const WifiNanStatus& status) override {
+ parent_.callbackType = NOTIFY_DELETE_DATA_INTERFACE_RESPONSE;
+
+ parent_.id = id;
+ parent_.status = status;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> notifyInitiateDataPathResponse(
+ uint16_t id, const WifiNanStatus& status,
+ uint32_t ndpInstanceId) override {
+ parent_.callbackType = NOTIFY_INITIATE_DATA_PATH_RESPONSE;
+
+ parent_.id = id;
+ parent_.status = status;
+ parent_.ndpInstanceId = ndpInstanceId;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> notifyRespondToDataPathIndicationResponse(
+ uint16_t id, const WifiNanStatus& status) override {
+ parent_.callbackType =
+ NOTIFY_RESPOND_TO_DATA_PATH_INDICATION_RESPONSE;
+
+ parent_.id = id;
+ parent_.status = status;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> notifyTerminateDataPathResponse(
+ uint16_t id, const WifiNanStatus& status) override {
+ parent_.callbackType = NOTIFY_TERMINATE_DATA_PATH_RESPONSE;
+
+ parent_.id = id;
+ parent_.status = status;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> eventClusterEvent(
+ const NanClusterEventInd& event) override {
+ parent_.callbackType = EVENT_CLUSTER_EVENT;
+
+ parent_.nanClusterEventInd = event;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> eventDisabled(const WifiNanStatus& status) override {
+ parent_.callbackType = EVENT_DISABLED;
+
+ parent_.status = status;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> eventPublishTerminated(
+ uint8_t sessionId, const WifiNanStatus& status) override {
+ parent_.callbackType = EVENT_PUBLISH_TERMINATED;
+
+ parent_.sessionId = sessionId;
+ parent_.status = status;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> eventSubscribeTerminated(
+ uint8_t sessionId, const WifiNanStatus& status) override {
+ parent_.callbackType = EVENT_SUBSCRIBE_TERMINATED;
+
+ parent_.sessionId = sessionId;
+ parent_.status = status;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> eventMatch(const NanMatchInd& event) override {
+ parent_.callbackType = EVENT_MATCH;
+
+ parent_.nanMatchInd = event;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> eventMatchExpired(uint8_t discoverySessionId,
+ uint32_t peerId) override {
+ parent_.callbackType = EVENT_MATCH_EXPIRED;
+
+ parent_.sessionId = discoverySessionId;
+ parent_.peerId = peerId;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> eventFollowupReceived(
+ const NanFollowupReceivedInd& event) override {
+ parent_.callbackType = EVENT_FOLLOWUP_RECEIVED;
+
+ parent_.nanFollowupReceivedInd = event;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> eventTransmitFollowup(
+ uint16_t id, const WifiNanStatus& status) override {
+ parent_.callbackType = EVENT_TRANSMIT_FOLLOWUP;
+
+ parent_.id = id;
+ parent_.status = status;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> eventDataPathRequest(
+ const NanDataPathRequestInd& event) override {
+ parent_.callbackType = EVENT_DATA_PATH_REQUEST;
+
+ parent_.nanDataPathRequestInd = event;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> eventDataPathConfirm(
+ const ::android::hardware::wifi::V1_0::NanDataPathConfirmInd& event)
+ override {
+ parent_.callbackType = EVENT_DATA_PATH_CONFIRM;
+
+ parent_.nanDataPathConfirmInd = event;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> eventDataPathTerminated(uint32_t ndpInstanceId) override {
+ parent_.callbackType = EVENT_DATA_PATH_TERMINATED;
+
+ parent_.ndpInstanceId = ndpInstanceId;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> eventDataPathConfirm_1_2(
+ const ::android::hardware::wifi::V1_2::NanDataPathConfirmInd& event)
+ override {
+ parent_.callbackType = EVENT_DATA_PATH_CONFIRM_1_2;
+
+ parent_.nanDataPathConfirmInd_1_2 = event;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> eventDataPathScheduleUpdate(
+ const NanDataPathScheduleUpdateInd& event) override {
+ parent_.callbackType = EVENT_DATA_PATH_SCHEDULE_UPDATE;
+
+ parent_.nanDataPathScheduleUpdateInd = event;
+
+ parent_.notify();
+ return Void();
+ }
+ };
+
+ private:
+ // synchronization objects
+ std::mutex mtx_;
+ std::condition_variable cv_;
+ int count_;
+
+ protected:
+ android::sp<::android::hardware::wifi::V1_4::IWifiNanIface> iwifiNanIface;
+
+ // Data from IWifiNanIfaceEventCallback callbacks: this is the collection of
+ // all arguments to all callbacks. They are set by the callback
+ // (notifications or events) and can be retrieved by tests.
+ CallbackType callbackType;
+ uint16_t id;
+ WifiNanStatus status;
+ NanCapabilities capabilities;
+ uint8_t sessionId;
+ uint32_t ndpInstanceId;
+ NanClusterEventInd nanClusterEventInd;
+ NanMatchInd nanMatchInd;
+ uint32_t peerId;
+ NanFollowupReceivedInd nanFollowupReceivedInd;
+ NanDataPathRequestInd nanDataPathRequestInd;
+ ::android::hardware::wifi::V1_0::NanDataPathConfirmInd
+ nanDataPathConfirmInd;
+ ::android::hardware::wifi::V1_2::NanDataPathConfirmInd
+ nanDataPathConfirmInd_1_2;
+ NanDataPathScheduleUpdateInd nanDataPathScheduleUpdateInd;
+
+ std::string GetInstanceName() { return GetParam(); }
+};
+
+/*
+ * Create:
+ * Ensures that an instance of the IWifiNanIface proxy object is
+ * successfully created.
+ */
+TEST_P(WifiNanIfaceHidlTest, Create) {
+ // The creation of a proxy object is tested as part of SetUp method.
+}
+
+/*
+ * enableRequest_1_4InvalidArgs: validate that fails with invalid arguments
+ */
+TEST_P(WifiNanIfaceHidlTest, enableRequest_1_4InvalidArgs) {
+ uint16_t inputCmdId = 10;
+ callbackType = INVALID;
+ ::android::hardware::wifi::V1_4::NanEnableRequest nanEnableRequest = {};
+ NanConfigRequestSupplemental nanConfigRequestSupp = {};
+ ASSERT_EQ(WifiStatusCode::SUCCESS,
+ HIDL_INVOKE(iwifiNanIface, enableRequest_1_4, inputCmdId,
+ nanEnableRequest, nanConfigRequestSupp)
+ .code);
+ // wait for a callback
+ ASSERT_EQ(std::cv_status::no_timeout, wait(NOTIFY_ENABLE_RESPONSE));
+ ASSERT_EQ(NOTIFY_ENABLE_RESPONSE, callbackType);
+ ASSERT_EQ(id, inputCmdId);
+ ASSERT_EQ(status.status, NanStatusType::INVALID_ARGS);
+}
+
+/*
+ * enableRequest_1_4ShimInvalidArgs: validate that fails with invalid arguments
+ * to the shim
+ */
+TEST_P(WifiNanIfaceHidlTest, enableRequest_1_4ShimInvalidArgs) {
+ uint16_t inputCmdId = 10;
+ ::android::hardware::wifi::V1_4::NanEnableRequest nanEnableRequest = {};
+ nanEnableRequest.configParams.numberOfPublishServiceIdsInBeacon =
+ 128; // must be <= 127
+ NanConfigRequestSupplemental nanConfigRequestSupp = {};
+ ASSERT_EQ(WifiStatusCode::ERROR_INVALID_ARGS,
+ HIDL_INVOKE(iwifiNanIface, enableRequest_1_4, inputCmdId,
+ nanEnableRequest, nanConfigRequestSupp)
+ .code);
+}
+
+/*
+ * configRequest_1_4InvalidArgs: validate that fails with invalid arguments
+ */
+TEST_P(WifiNanIfaceHidlTest, configRequest_1_4InvalidArgs) {
+ uint16_t inputCmdId = 10;
+ callbackType = INVALID;
+ ::android::hardware::wifi::V1_4::NanConfigRequest nanConfigRequest = {};
+ NanConfigRequestSupplemental nanConfigRequestSupp = {};
+ ASSERT_EQ(WifiStatusCode::SUCCESS,
+ HIDL_INVOKE(iwifiNanIface, configRequest_1_4, inputCmdId,
+ nanConfigRequest, nanConfigRequestSupp)
+ .code);
+ // wait for a callback
+ ASSERT_EQ(std::cv_status::no_timeout, wait(NOTIFY_CONFIG_RESPONSE));
+ ASSERT_EQ(NOTIFY_CONFIG_RESPONSE, callbackType);
+ ASSERT_EQ(id, inputCmdId);
+ ASSERT_EQ(status.status, NanStatusType::INVALID_ARGS);
+}
+
+/*
+ * configRequest_1_4ShimInvalidArgs: validate that fails with invalid arguments
+ * to the shim
+ */
+TEST_P(WifiNanIfaceHidlTest, configRequest_1_4ShimInvalidArgs) {
+ uint16_t inputCmdId = 10;
+ ::android::hardware::wifi::V1_4::NanConfigRequest nanConfigRequest = {};
+ nanConfigRequest.numberOfPublishServiceIdsInBeacon = 128; // must be <= 127
+ NanConfigRequestSupplemental nanConfigRequestSupp = {};
+ ASSERT_EQ(WifiStatusCode::ERROR_INVALID_ARGS,
+ HIDL_INVOKE(iwifiNanIface, configRequest_1_4, inputCmdId,
+ nanConfigRequest, nanConfigRequestSupp)
+ .code);
+}
diff --git a/wifi/1.4/vts/functional/wifi_sta_iface_hidl_test.cpp b/wifi/1.4/vts/functional/wifi_sta_iface_hidl_test.cpp
deleted file mode 100644
index ec4b2c9..0000000
--- a/wifi/1.4/vts/functional/wifi_sta_iface_hidl_test.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Staache 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.
- */
-
-#include <android-base/logging.h>
-
-#include <android/hardware/wifi/1.4/IWifiStaIface.h>
-
-#include <VtsHalHidlTargetTestBase.h>
-
-#include "wifi_hidl_call_util.h"
-#include "wifi_hidl_test_utils.h"
-
-using ::android::sp;
-using ::android::hardware::hidl_array;
-using ::android::hardware::wifi::V1_0::WifiStatus;
-using ::android::hardware::wifi::V1_0::WifiStatusCode;
-using ::android::hardware::wifi::V1_4::IWifiStaIface;
-
-/**
- * Fixture to use for all STA Iface HIDL interface tests.
- */
-class WifiStaIfaceHidlTest : public ::testing::VtsHalHidlTargetTestBase {
- public:
- virtual void SetUp() override {
- wifi_sta_iface_ = IWifiStaIface::castFrom(getWifiStaIface());
- ASSERT_NE(nullptr, wifi_sta_iface_.get());
- }
-
- virtual void TearDown() override { stopWifi(); }
-
- protected:
- sp<IWifiStaIface> wifi_sta_iface_;
-};
-
-/*
- * GetCapabilities_1_4
- */
-TEST_F(WifiStaIfaceHidlTest, GetCapabilities_1_4) {
- configureChipForIfaceType(IfaceType::STA, true);
-
- const auto& status_and_caps =
- HIDL_INVOKE(wifi_sta_iface_, getCapabilities_1_4);
- if (status_and_caps.first.code != WifiStatusCode::SUCCESS) {
- EXPECT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED,
- status_and_caps.first.code);
- return;
- }
- EXPECT_NE(0u, status_and_caps.second);
-}
diff --git a/wifi/hostapd/1.2/Android.bp b/wifi/hostapd/1.2/Android.bp
new file mode 100644
index 0000000..3dcad71
--- /dev/null
+++ b/wifi/hostapd/1.2/Android.bp
@@ -0,0 +1,20 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+hidl_interface {
+ name: "android.hardware.wifi.hostapd@1.2",
+ root: "android.hardware",
+ vndk: {
+ enabled: true,
+ },
+ srcs: [
+ "types.hal",
+ "IHostapd.hal",
+ ],
+ interfaces: [
+ "android.hardware.wifi.hostapd@1.0",
+ "android.hardware.wifi.hostapd@1.1",
+ "android.hardware.wifi.supplicant@1.0",
+ "android.hidl.base@1.0",
+ ],
+ gen_java: true,
+}
diff --git a/wifi/hostapd/1.2/IHostapd.hal b/wifi/hostapd/1.2/IHostapd.hal
new file mode 100644
index 0000000..1bac1e7
--- /dev/null
+++ b/wifi/hostapd/1.2/IHostapd.hal
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2019 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.wifi.hostapd@1.2;
+
+import @1.0::IHostapd.NetworkParams;
+import @1.1::IHostapd;
+import HostapdStatus;
+import MacAddress;
+import Ieee80211ReasonCode;
+
+/**
+ * Top-level object for managing SoftAPs.
+ */
+interface IHostapd extends @1.1::IHostapd {
+ /**
+ * Band bitmMask to use for the SoftAp operations.
+ * A combinatoin of these bits are used to identify the allowed bands
+ * to start the softAp
+ */
+ enum BandMask : uint32_t {
+ /**
+ * 2.4 GHz band.
+ */
+ BAND_2_GHZ = 1 << 0,
+ /**
+ * 5 GHz band.
+ */
+ BAND_5_GHZ = 1 << 1,
+ /**
+ * 6 GHz band.
+ */
+ BAND_6_GHZ = 1 << 2,
+ };
+
+ /**
+ * Parameters to control the HW mode for the interface.
+ */
+ struct HwModeParams {
+ /**
+ * Whether IEEE 802.11ax (HE) is enabled or not.
+ * Note: hw_mode=a is used to specify that 5 GHz band or 6 GHz band is
+ * used with HE.
+ */
+ bool enable80211AX;
+ /**
+ * Whether 6GHz band enabled or not on softAp.
+ * Note: hw_mode=a is used to specify that 5 GHz band or 6 GHz band is
+ * used.
+ */
+ bool enable6GhzBand;
+ };
+
+ /**
+ * Parameters to control the channel selection for the interface.
+ */
+ struct ChannelParams {
+ /**
+ * Band to use for the SoftAp operations.
+ */
+ bitfield<BandMask> bandMask;
+ };
+
+ /**
+ * Parameters to use for setting up the access point interface.
+ */
+ struct IfaceParams {
+ /**
+ * Baseline information as defined in HAL 1.1.
+ */
+ @1.1::IHostapd.IfaceParams V1_1;
+ /** Additional Hw mode params for the interface */
+ HwModeParams hwModeParams;
+ /** Additional Channel params for the interface */
+ ChannelParams channelParams;
+ };
+
+ /**
+ * Adds a new access point for hostapd to control.
+ *
+ * This should trigger the setup of an access point with the specified
+ * interface and network params.
+ *
+ * @param ifaceParams AccessPoint Params for the access point.
+ * @param nwParams Network Params for the access point.
+ * @return status Status of the operation.
+ * Possible status codes:
+ * |HostapdStatusCode.SUCCESS|,
+ * |HostapdStatusCode.FAILURE_ARGS_INVALID|,
+ * |HostapdStatusCode.FAILURE_UNKNOWN|,
+ * |HostapdStatusCode.FAILURE_IFACE_EXISTS|
+ */
+ addAccessPoint_1_2(IfaceParams ifaceParams, NetworkParams nwParams)
+ generates(HostapdStatus status);
+
+ /**
+ * force one of the hotspot clients disconnect..
+ *
+ * @param ifaceName Name of the interface.
+ * @param clientAddress Mac Address of the hotspot client.
+ * @param reasonCode One of disconnect reason code which defined by 802.11.
+ * @return status Status of the operation.
+ * Possible status codes:
+ * |HostapdStatusCode.SUCCESS|,
+ * |HostapdStatusCode.FAILURE_IFACE_UNKNOWN|
+ * |HostapdStatusCode.FAILURE_CLIENT_UNKNOWN|
+ */
+ forceClientDisconnect(string ifaceName, MacAddress clientAddress,
+ Ieee80211ReasonCode reasonCode) generates (HostapdStatus status);
+};
diff --git a/wifi/hostapd/1.2/types.hal b/wifi/hostapd/1.2/types.hal
new file mode 100644
index 0000000..06e890b
--- /dev/null
+++ b/wifi/hostapd/1.2/types.hal
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2019 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.wifi.hostapd@1.2;
+
+import @1.0::HostapdStatusCode;
+
+/**
+ * Enum values indicating the status of any hostapd operation.
+ */
+enum HostapdStatusCode : @1.0::HostapdStatusCode {
+ /**
+ * Failure because unknown the client.
+ */
+ FAILURE_CLIENT_UNKNOWN,
+};
+
+/**
+ * Enum values indicating the reason code for disconnect packet.
+ * Reason codes (IEEE Std 802.11-2016, 9.4.1.7, Table 9-45).
+ */
+enum Ieee80211ReasonCode : uint16_t {
+ WLAN_REASON_UNSPECIFIED = 1,
+ WLAN_REASON_PREV_AUTH_NOT_VALID = 2,
+ WLAN_REASON_DISASSOC_AP_BUSY = 5,
+};
+
+typedef uint8_t[6] MacAddress;
+
+/**
+ * Generic structure to return the status of any hostapd operation.
+ */
+struct HostapdStatus {
+ HostapdStatusCode code;
+
+ /**
+ * A vendor-specific error message to provide more information beyond the
+ * status code.
+ * This must be used for debugging purposes only.
+ */
+ string debugMessage;
+};
diff --git a/wifi/hostapd/1.2/vts/OWNERS b/wifi/hostapd/1.2/vts/OWNERS
new file mode 100644
index 0000000..8bfb148
--- /dev/null
+++ b/wifi/hostapd/1.2/vts/OWNERS
@@ -0,0 +1,2 @@
+rpius@google.com
+etancohen@google.com
diff --git a/wifi/hostapd/1.2/vts/functional/Android.bp b/wifi/hostapd/1.2/vts/functional/Android.bp
new file mode 100644
index 0000000..50cfdee
--- /dev/null
+++ b/wifi/hostapd/1.2/vts/functional/Android.bp
@@ -0,0 +1,37 @@
+//
+// Copyright (C) 2019 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.
+//
+
+cc_test {
+ name: "VtsHalWifiHostapdV1_2TargetTest",
+ defaults: ["VtsHalTargetTestDefaults"],
+ srcs: [
+ "VtsHalWifiHostapdV1_2TargetTest.cpp",
+ "hostapd_hidl_test.cpp",
+ ],
+ static_libs: [
+ "VtsHalWifiV1_0TargetTestUtil",
+ "VtsHalWifiHostapdV1_0TargetTestUtil",
+ "android.hardware.wifi.hostapd@1.0",
+ "android.hardware.wifi.hostapd@1.1",
+ "android.hardware.wifi.hostapd@1.2",
+ "android.hardware.wifi@1.0",
+ "libgmock",
+ "libwifi-system",
+ "libwifi-system-iface",
+ ],
+ test_suites: ["general-tests", "vts-core"],
+}
+
diff --git a/wifi/hostapd/1.2/vts/functional/VtsHalWifiHostapdV1_2TargetTest.cpp b/wifi/hostapd/1.2/vts/functional/VtsHalWifiHostapdV1_2TargetTest.cpp
new file mode 100644
index 0000000..7e0f3cd
--- /dev/null
+++ b/wifi/hostapd/1.2/vts/functional/VtsHalWifiHostapdV1_2TargetTest.cpp
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#include <VtsHalHidlTargetTestEnvBase.h>
+
+// TODO(b/143892896): Remove this file after wifi_hidl_test_utils.cpp is
+// updated.
+::testing::VtsHalHidlTargetTestEnvBase* gEnv = nullptr;
\ No newline at end of file
diff --git a/wifi/hostapd/1.2/vts/functional/hostapd_hidl_test.cpp b/wifi/hostapd/1.2/vts/functional/hostapd_hidl_test.cpp
new file mode 100644
index 0000000..b092d00
--- /dev/null
+++ b/wifi/hostapd/1.2/vts/functional/hostapd_hidl_test.cpp
@@ -0,0 +1,329 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#include <android-base/logging.h>
+#include <cutils/properties.h>
+
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
+
+#include <android/hardware/wifi/1.0/IWifi.h>
+#include <android/hardware/wifi/hostapd/1.2/IHostapd.h>
+
+#include "hostapd_hidl_call_util.h"
+#include "hostapd_hidl_test_utils.h"
+
+using ::android::sp;
+using ::android::hardware::hidl_string;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::wifi::hostapd::V1_2::HostapdStatusCode;
+using ::android::hardware::wifi::hostapd::V1_2::Ieee80211ReasonCode;
+using ::android::hardware::wifi::hostapd::V1_2::IHostapd;
+using ::android::hardware::wifi::V1_0::IWifi;
+
+namespace {
+constexpr unsigned char kNwSsid[] = {'t', 'e', 's', 't', '1',
+ '2', '3', '4', '5'};
+constexpr char kNwPassphrase[] = "test12345";
+constexpr int kIfaceChannel = 6;
+constexpr int kIfaceInvalidChannel = 567;
+constexpr uint8_t kTestZeroMacAddr[] = {[0 ... 5] = 0x0};
+constexpr Ieee80211ReasonCode kTestDisconnectReasonCode =
+ Ieee80211ReasonCode::WLAN_REASON_UNSPECIFIED;
+} // namespace
+
+class HostapdHidlTest
+ : public ::testing::TestWithParam<std::tuple<std::string, std::string>> {
+ public:
+ virtual void SetUp() override {
+ wifi_instance_name_ = std::get<0>(GetParam());
+ hostapd_instance_name_ = std::get<1>(GetParam());
+ stopSupplicantIfNeeded(wifi_instance_name_);
+ startHostapdAndWaitForHidlService(wifi_instance_name_,
+ hostapd_instance_name_);
+ hostapd_ = IHostapd::getService(hostapd_instance_name_);
+ ASSERT_NE(hostapd_.get(), nullptr);
+ }
+
+ virtual void TearDown() override { stopHostapd(wifi_instance_name_); }
+
+ protected:
+ std::string getPrimaryWlanIfaceName() {
+ std::array<char, PROPERTY_VALUE_MAX> buffer;
+ auto res = property_get("ro.vendor.wifi.sap.interface", buffer.data(),
+ nullptr);
+ if (res > 0) return buffer.data();
+ property_get("wifi.interface", buffer.data(), "wlan0");
+ return buffer.data();
+ }
+
+ IHostapd::IfaceParams getIfaceParamsWithoutAcs() {
+ ::android::hardware::wifi::hostapd::V1_0::IHostapd::IfaceParams
+ iface_params;
+ ::android::hardware::wifi::hostapd::V1_1::IHostapd::IfaceParams
+ iface_params_1_1;
+ IHostapd::IfaceParams iface_params_1_2;
+
+ iface_params.ifaceName = getPrimaryWlanIfaceName();
+ iface_params.hwModeParams.enable80211N = true;
+ iface_params.hwModeParams.enable80211AC = false;
+ iface_params.channelParams.enableAcs = false;
+ iface_params.channelParams.acsShouldExcludeDfs = false;
+ iface_params.channelParams.channel = kIfaceChannel;
+ iface_params_1_1.V1_0 = iface_params;
+ iface_params_1_2.V1_1 = iface_params_1_1;
+ // Newly added attributes in V1_2
+ iface_params_1_2.hwModeParams.enable80211AX = false;
+ iface_params_1_2.hwModeParams.enable6GhzBand = false;
+ iface_params_1_2.channelParams.bandMask = 0;
+ iface_params_1_2.channelParams.bandMask |=
+ IHostapd::BandMask::BAND_2_GHZ;
+ return iface_params_1_2;
+ }
+
+ IHostapd::IfaceParams getIfaceParamsWithAcs() {
+ // First get the settings for WithoutAcs and then make changes
+ IHostapd::IfaceParams iface_params_1_2 = getIfaceParamsWithoutAcs();
+ iface_params_1_2.V1_1.V1_0.channelParams.enableAcs = true;
+ iface_params_1_2.V1_1.V1_0.channelParams.acsShouldExcludeDfs = true;
+ iface_params_1_2.V1_1.V1_0.channelParams.channel = 0;
+ iface_params_1_2.channelParams.bandMask |=
+ IHostapd::BandMask::BAND_5_GHZ;
+
+ return iface_params_1_2;
+ }
+
+ IHostapd::IfaceParams getIfaceParamsWithAcsAndChannelRange() {
+ IHostapd::IfaceParams iface_params_1_2 = getIfaceParamsWithAcs();
+ ::android::hardware::wifi::hostapd::V1_1::IHostapd::ChannelParams
+ channelParams;
+ ::android::hardware::wifi::hostapd::V1_1::IHostapd::AcsChannelRange
+ acsChannelRange;
+ acsChannelRange.start = 1;
+ acsChannelRange.end = 11;
+ std::vector<
+ ::android::hardware::wifi::hostapd::V1_1::IHostapd::AcsChannelRange>
+ vec_acsChannelRange;
+ vec_acsChannelRange.push_back(acsChannelRange);
+ channelParams.acsChannelRanges = vec_acsChannelRange;
+ iface_params_1_2.V1_1.channelParams = channelParams;
+ return iface_params_1_2;
+ }
+
+ IHostapd::IfaceParams getIfaceParamsWithAcsAndInvalidChannelRange() {
+ IHostapd::IfaceParams iface_params_1_2 =
+ getIfaceParamsWithAcsAndChannelRange();
+ iface_params_1_2.V1_1.channelParams.acsChannelRanges[0].start = 222;
+ iface_params_1_2.V1_1.channelParams.acsChannelRanges[0].end = 999;
+ return iface_params_1_2;
+ }
+
+ IHostapd::NetworkParams getOpenNwParams() {
+ IHostapd::NetworkParams nw_params;
+ nw_params.ssid =
+ std::vector<uint8_t>(kNwSsid, kNwSsid + sizeof(kNwSsid));
+ nw_params.isHidden = false;
+ nw_params.encryptionType = IHostapd::EncryptionType::NONE;
+ return nw_params;
+ }
+
+ IHostapd::NetworkParams getPskNwParams() {
+ IHostapd::NetworkParams nw_params;
+ nw_params.ssid =
+ std::vector<uint8_t>(kNwSsid, kNwSsid + sizeof(kNwSsid));
+ nw_params.isHidden = false;
+ nw_params.encryptionType = IHostapd::EncryptionType::WPA2;
+ nw_params.pskPassphrase = kNwPassphrase;
+ return nw_params;
+ }
+
+ IHostapd::NetworkParams getInvalidPskNwParams() {
+ IHostapd::NetworkParams nw_params;
+ nw_params.ssid =
+ std::vector<uint8_t>(kNwSsid, kNwSsid + sizeof(kNwSsid));
+ nw_params.isHidden = false;
+ nw_params.encryptionType = IHostapd::EncryptionType::WPA2;
+ return nw_params;
+ }
+
+ IHostapd::IfaceParams getIfaceParamsWithInvalidChannel() {
+ IHostapd::IfaceParams iface_params_1_2 = getIfaceParamsWithoutAcs();
+ iface_params_1_2.V1_1.V1_0.channelParams.channel = kIfaceInvalidChannel;
+ return iface_params_1_2;
+ }
+
+ // IHostapd object used for all tests in this fixture.
+ sp<IHostapd> hostapd_;
+ std::string wifi_instance_name_;
+ std::string hostapd_instance_name_;
+};
+
+/**
+ * Adds an access point with PSK network config & ACS enabled.
+ * Access point creation should pass.
+ */
+TEST_P(HostapdHidlTest, AddPskAccessPointWithAcs) {
+ auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
+ getIfaceParamsWithAcs(), getPskNwParams());
+ // TODO: b/140172237, fix this in R.
+ // EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
+}
+
+/**
+ * Adds an access point with PSK network config, ACS enabled & channel Range.
+ * Access point creation should pass.
+ */
+TEST_P(HostapdHidlTest, AddPskAccessPointWithAcsAndChannelRange) {
+ auto status =
+ HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
+ getIfaceParamsWithAcsAndChannelRange(), getPskNwParams());
+ // TODO: b/140172237, fix this in R
+ // EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
+}
+
+/**
+ * Adds an access point with invalid channel range.
+ * Access point creation should fail.
+ */
+TEST_P(HostapdHidlTest, AddPskAccessPointWithAcsAndInvalidChannelRange) {
+ auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
+ getIfaceParamsWithAcsAndInvalidChannelRange(),
+ getPskNwParams());
+ // TODO: b/140172237, fix this in R
+ // EXPECT_NE(HostapdStatusCode::SUCCESS, status.code);
+}
+
+/**
+ * Adds an access point with Open network config & ACS enabled.
+ * Access point creation should pass.
+ */
+TEST_P(HostapdHidlTest, AddOpenAccessPointWithAcs) {
+ auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
+ getIfaceParamsWithAcs(), getOpenNwParams());
+ // TODO: b/140172237, fix this in R
+ // EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
+}
+
+/**
+ * Adds an access point with PSK network config & ACS disabled.
+ * Access point creation should pass.
+ */
+TEST_P(HostapdHidlTest, AddPskAccessPointWithoutAcs) {
+ auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
+ getIfaceParamsWithoutAcs(), getPskNwParams());
+ EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
+}
+
+/**
+ * Adds an access point with Open network config & ACS disabled.
+ * Access point creation should pass.
+ */
+TEST_P(HostapdHidlTest, AddOpenAccessPointWithoutAcs) {
+ auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
+ getIfaceParamsWithoutAcs(), getOpenNwParams());
+ EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
+}
+
+/**
+ * Adds & then removes an access point with PSK network config & ACS enabled.
+ * Access point creation & removal should pass.
+ */
+TEST_P(HostapdHidlTest, RemoveAccessPointWithAcs) {
+ auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
+ getIfaceParamsWithAcs(), getPskNwParams());
+ // TODO: b/140172237, fix this in R
+ /*
+ EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
+ status =
+ HIDL_INVOKE(hostapd_, removeAccessPoint, getPrimaryWlanIfaceName());
+ EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
+ */
+}
+
+/**
+ * Adds & then removes an access point with PSK network config & ACS disabled.
+ * Access point creation & removal should pass.
+ */
+TEST_P(HostapdHidlTest, RemoveAccessPointWithoutAcs) {
+ auto status_1_2 = HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
+ getIfaceParamsWithoutAcs(), getPskNwParams());
+ EXPECT_EQ(HostapdStatusCode::SUCCESS, status_1_2.code);
+ auto status =
+ HIDL_INVOKE(hostapd_, removeAccessPoint, getPrimaryWlanIfaceName());
+ EXPECT_EQ(
+ android::hardware::wifi::hostapd::V1_0::HostapdStatusCode::SUCCESS,
+ status.code);
+}
+
+/**
+ * Adds an access point with invalid channel.
+ * Access point creation should fail.
+ */
+TEST_P(HostapdHidlTest, AddPskAccessPointWithInvalidChannel) {
+ auto status =
+ HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
+ getIfaceParamsWithInvalidChannel(), getPskNwParams());
+ EXPECT_NE(HostapdStatusCode::SUCCESS, status.code);
+}
+
+/**
+ * Adds an access point with invalid PSK network config.
+ * Access point creation should fail.
+ */
+TEST_P(HostapdHidlTest, AddInvalidPskAccessPointWithoutAcs) {
+ auto status =
+ HIDL_INVOKE(hostapd_, addAccessPoint_1_2, getIfaceParamsWithoutAcs(),
+ getInvalidPskNwParams());
+ EXPECT_NE(HostapdStatusCode::SUCCESS, status.code);
+}
+
+/**
+ * forceClientDisconnect should return FAILURE_IFACE_UNKNOWN
+ * when hotspot interface doesn't init..
+ */
+TEST_P(HostapdHidlTest, DisconnectClientWhenIfaceNotAvailable) {
+ auto status =
+ HIDL_INVOKE(hostapd_, forceClientDisconnect, getPrimaryWlanIfaceName(),
+ kTestZeroMacAddr, kTestDisconnectReasonCode);
+ EXPECT_EQ(HostapdStatusCode::FAILURE_IFACE_UNKNOWN, status.code);
+}
+
+/**
+ * forceClientDisconnect should return FAILURE_CLIENT_UNKNOWN
+ * when hotspot interface available.
+ */
+TEST_P(HostapdHidlTest, DisconnectClientWhenIfacAvailable) {
+ auto status_1_2 =
+ HIDL_INVOKE(hostapd_, addAccessPoint_1_2, getIfaceParamsWithoutAcs(),
+ getOpenNwParams());
+ EXPECT_EQ(HostapdStatusCode::SUCCESS, status_1_2.code);
+
+ status_1_2 =
+ HIDL_INVOKE(hostapd_, forceClientDisconnect, getPrimaryWlanIfaceName(),
+ kTestZeroMacAddr, kTestDisconnectReasonCode);
+ EXPECT_EQ(HostapdStatusCode::FAILURE_CLIENT_UNKNOWN, status_1_2.code);
+}
+
+INSTANTIATE_TEST_CASE_P(
+ PerInstance, HostapdHidlTest,
+ testing::Combine(
+ testing::ValuesIn(
+ android::hardware::getAllHalInstanceNames(IWifi::descriptor)),
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(
+ android::hardware::wifi::hostapd::V1_2::IHostapd::descriptor))),
+ android::hardware::PrintInstanceTupleNameToString<>);
diff --git a/wifi/supplicant/1.0/vts/functional/Android.bp b/wifi/supplicant/1.0/vts/functional/Android.bp
index 15525bb..332ee4a 100644
--- a/wifi/supplicant/1.0/vts/functional/Android.bp
+++ b/wifi/supplicant/1.0/vts/functional/Android.bp
@@ -19,7 +19,7 @@
defaults: ["VtsHalTargetTestDefaults"],
srcs: ["supplicant_hidl_test_utils.cpp"],
export_include_dirs: [
- "."
+ ".",
],
static_libs: [
"VtsHalWifiV1_0TargetTestUtil",
@@ -51,14 +51,17 @@
"libwifi-system",
"libwifi-system-iface",
],
- test_suites: ["general-tests", "vts-core"],
+ test_suites: [
+ "general-tests",
+ "vts-core",
+ ],
}
cc_test {
name: "VtsHalWifiSupplicantP2pV1_0TargetTest",
defaults: ["VtsHalTargetTestDefaults"],
srcs: [
- "VtsHalWifiSupplicantV1_0TargetTest.cpp",
+ "VtsHalWifiSupplicantP2pV1_0TargetTest.cpp",
"supplicant_p2p_iface_hidl_test.cpp",
],
static_libs: [
@@ -71,5 +74,8 @@
"libwifi-system",
"libwifi-system-iface",
],
- test_suites: ["general-tests", "vts-core"],
+ test_suites: [
+ "general-tests",
+ "vts-core",
+ ],
}
diff --git a/wifi/supplicant/1.0/vts/functional/VtsHalWifiSupplicantP2pV1_0TargetTest.cpp b/wifi/supplicant/1.0/vts/functional/VtsHalWifiSupplicantP2pV1_0TargetTest.cpp
new file mode 100644
index 0000000..a132707
--- /dev/null
+++ b/wifi/supplicant/1.0/vts/functional/VtsHalWifiSupplicantP2pV1_0TargetTest.cpp
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#include <VtsCoreUtil.h>
+#include "supplicant_hidl_test_utils.h"
+
+// TODO(b/143892896): Remove this line after wifi_hidl_test_utils.cpp is
+// updated.
+WifiSupplicantHidlEnvironment* gEnv = nullptr;
+
+int main(int argc, char** argv) {
+ if (!::testing::deviceSupportsFeature("android.hardware.wifi.direct"))
+ return 0;
+
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
diff --git a/wifi/supplicant/1.3/ISupplicantStaIface.hal b/wifi/supplicant/1.3/ISupplicantStaIface.hal
index bfd8946..fa88b91 100644
--- a/wifi/supplicant/1.3/ISupplicantStaIface.hal
+++ b/wifi/supplicant/1.3/ISupplicantStaIface.hal
@@ -18,6 +18,7 @@
import @1.0::SupplicantStatus;
import @1.2::ISupplicantStaIface;
+import @1.3::ISupplicantStaNetwork;
import ISupplicantStaIfaceCallback;
/**
@@ -76,4 +77,17 @@
* |SupplicantStatusCode.FAILURE_UNKNOWN|
*/
setMboCellularDataStatus(bool available) generates (SupplicantStatus status);
+
+ /**
+ * Get Key management capabilities of the device
+ *
+ * @return status Status of the operation, and a bitmap of key management mask.
+ * Possible status codes:
+ * |SupplicantStatusCode.SUCCESS|,
+ * |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+ * |SupplicantStatusCode.FAILURE_NETWORK_INVALID|,
+ * |SupplicantStatusCode.FAILURE_UNKNOWN|
+ */
+ getKeyMgmtCapabilities_1_3()
+ generates (SupplicantStatus status, bitfield<KeyMgmtMask> keyMgmtMask);
};
diff --git a/wifi/supplicant/1.3/ISupplicantStaNetwork.hal b/wifi/supplicant/1.3/ISupplicantStaNetwork.hal
index ab08cff..1bcf7bc 100644
--- a/wifi/supplicant/1.3/ISupplicantStaNetwork.hal
+++ b/wifi/supplicant/1.3/ISupplicantStaNetwork.hal
@@ -16,6 +16,7 @@
package android.hardware.wifi.supplicant@1.3;
+import @1.0::ISupplicantStaNetwork;
import @1.0::SupplicantStatus;
import @1.2::ISupplicantStaNetwork;
@@ -24,6 +25,32 @@
* configuration it controls.
*/
interface ISupplicantStaNetwork extends @1.2::ISupplicantStaNetwork {
+ /** Possble mask of values for Proto param. */
+ enum ProtoMask : @1.0::ISupplicantStaNetwork.ProtoMask {
+ WAPI = 1 << 2,
+ };
+
+ /** Possble mask of values for KeyMgmt param. */
+ enum KeyMgmtMask : @1.2::ISupplicantStaNetwork.KeyMgmtMask {
+ /* WAPI Psk */
+ WAPI_PSK = 1 << 12,
+
+ /** WAPI Cert */
+ WAPI_CERT = 1 << 13,
+ };
+
+ /** Possble mask of values for PairwiseCipher param. */
+ enum PairwiseCipherMask : @1.2::ISupplicantStaNetwork.PairwiseCipherMask {
+ /** SMS4 Pairwise Cipher */
+ SMS4 = 1 << 7,
+ };
+
+ /** Possble mask of values for GroupCipher param. */
+ enum GroupCipherMask : @1.2::ISupplicantStaNetwork.GroupCipherMask {
+ /** SMS4 Group Cipher */
+ SMS4 = 1 << 7,
+ };
+
/**
* Set OCSP (Online Certificate Status Protocol) type for this network.
*
@@ -49,6 +76,142 @@
getOcsp() generates (SupplicantStatus status, OcspType ocspType);
/**
+ * Set key management mask for the network.
+ *
+ * @param keyMgmtMask value to set.
+ * Combination of |KeyMgmtMask| values.
+ * @return status Status of the operation.
+ * Possible status codes:
+ * |SupplicantStatusCode.SUCCESS|,
+ * |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+ * |SupplicantStatusCode.FAILURE_NETWORK_INVALID|,
+ * |SupplicantStatusCode.FAILURE_UNKNOWN|
+ */
+ setKeyMgmt_1_3(bitfield<KeyMgmtMask> keyMgmtMask) generates (SupplicantStatus status);
+
+ /**
+ * Get the key mgmt mask set for the network.
+ *
+ * @return status Status of the operation.
+ * Possible status codes:
+ * |SupplicantStatusCode.SUCCESS|,
+ * |SupplicantStatusCode.FAILURE_NETWORK_INVALID|,
+ * |SupplicantStatusCode.FAILURE_UNKNOWN|
+ * @return keyMgmtMask Combination of |KeyMgmtMask| values.
+ */
+ getKeyMgmt_1_3()
+ generates (SupplicantStatus status, bitfield<KeyMgmtMask> keyMgmtMask);
+
+ /**
+ * Set proto mask for the network.
+ *
+ * @param protoMask value to set.
+ * Combination of |ProtoMask| values.
+ * @return status Status of the operation.
+ * Possible status codes:
+ * |SupplicantStatusCode.SUCCESS|,
+ * |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+ * |SupplicantStatusCode.FAILURE_NETWORK_INVALID|,
+ * |SupplicantStatusCode.FAILURE_UNKNOWN|
+ */
+ setProto_1_3(bitfield<ProtoMask> protoMask) generates (SupplicantStatus status);
+
+ /**
+ * Get the proto mask set for the network.
+ *
+ * @return status Status of the operation.
+ * Possible status codes:
+ * |SupplicantStatusCode.SUCCESS|,
+ * |SupplicantStatusCode.FAILURE_NETWORK_INVALID|,
+ * |SupplicantStatusCode.FAILURE_UNKNOWN|
+ * @return protoMask Combination of |ProtoMask| values.
+ */
+ getProto_1_3() generates (SupplicantStatus status, bitfield<ProtoMask> protoMask);
+
+ /**
+ * Set group cipher mask for the network.
+ *
+ * @param groupCipherMask value to set.
+ * Combination of |ProtoMask| values.
+ * @return status Status of the operation.
+ * Possible status codes:
+ * |SupplicantStatusCode.SUCCESS|,
+ * |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+ * |SupplicantStatusCode.FAILURE_NETWORK_INVALID|,
+ * |SupplicantStatusCode.FAILURE_UNKNOWN|
+ */
+ setGroupCipher_1_3(bitfield<GroupCipherMask> groupCipherMask)
+ generates (SupplicantStatus status);
+
+ /**
+ * Get the pairwise cipher mask set for the network.
+ *
+ * @return status Status of the operation.
+ * Possible status codes:
+ * |SupplicantStatusCode.SUCCESS|,
+ * |SupplicantStatusCode.FAILURE_NETWORK_INVALID|,
+ * |SupplicantStatusCode.FAILURE_UNKNOWN|
+ * @return pairwiseCipherMask Combination of |PairwiseCipherMask| values.
+ */
+ getPairwiseCipher_1_3()
+ generates (SupplicantStatus status,
+ bitfield<PairwiseCipherMask> pairwiseCipherMask);
+
+ /**
+ * Set pairwise cipher mask for the network.
+ *
+ * @param pairwiseCipherMask value to set.
+ * Combination of |ProtoMask| values.
+ * @return status Status of the operation.
+ * Possible status codes:
+ * |SupplicantStatusCode.SUCCESS|,
+ * |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+ * |SupplicantStatusCode.FAILURE_NETWORK_INVALID|,
+ * |SupplicantStatusCode.FAILURE_UNKNOWN|
+ */
+ setPairwiseCipher_1_3(bitfield<PairwiseCipherMask> pairwiseCipherMask)
+ generates (SupplicantStatus status);
+
+ /**
+ * Get the group cipher mask set for the network.
+ *
+ * @return status Status of the operation.
+ * Possible status codes:
+ * |SupplicantStatusCode.SUCCESS|,
+ * |SupplicantStatusCode.FAILURE_NETWORK_INVALID|,
+ * |SupplicantStatusCode.FAILURE_UNKNOWN|
+ * @return groupCipherMask Combination of |GroupCipherMask| values.
+ */
+ getGroupCipher_1_3()
+ generates (SupplicantStatus status,
+ bitfield<GroupCipherMask> groupCipherMask);
+
+ /**
+ * Set WAPI certificate suite for this network.
+ *
+ * @param suite value to set.
+ * @return status Status of the operation.
+ * Possible status codes:
+ * |SupplicantStatusCode.SUCCESS|,
+ * |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+ * |SupplicantStatusCode.FAILURE_NETWORK_INVALID|,
+ * |SupplicantStatusCode.FAILURE_UNKNOWN|
+ */
+ setWapiCertSuite(string suite) generates (SupplicantStatus status);
+
+ /**
+ * Get WAPI certificate suite set for this network.
+ *
+ * @return status Status of the operation.
+ * Possible status codes:
+ * |SupplicantStatusCode.SUCCESS|,
+ * |SupplicantStatusCode.FAILURE_NETWORK_INVALID|,
+ * |SupplicantStatusCode.FAILURE_UNKNOWN|
+ * @return suite The name of a suite.
+ */
+ getWapiCertSuite() generates (SupplicantStatus status, string suite);
+
+ /**
* Add a PMK into supplicant PMK cache.
*
* @param serializedEntry is serialized PMK cache entry, the content is
diff --git a/wifi/supplicant/1.3/vts/functional/supplicant_sta_iface_hidl_test.cpp b/wifi/supplicant/1.3/vts/functional/supplicant_sta_iface_hidl_test.cpp
index 2cf5881..ca3265e 100644
--- a/wifi/supplicant/1.3/vts/functional/supplicant_sta_iface_hidl_test.cpp
+++ b/wifi/supplicant/1.3/vts/functional/supplicant_sta_iface_hidl_test.cpp
@@ -227,3 +227,22 @@
EXPECT_EQ(expectedStatusCode, status.code);
});
}
+
+/*
+ * GetKeyMgmtCapabilities_1_3
+ */
+TEST_F(SupplicantStaIfaceHidlTest, GetKeyMgmtCapabilities_1_3) {
+ sta_iface_->getKeyMgmtCapabilities_1_3([&](const SupplicantStatus& status,
+ uint32_t keyMgmtMask) {
+ if (SupplicantStatusCode::SUCCESS != status.code) {
+ // for unsupport case
+ EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code);
+ } else {
+ // Even though capabilities vary, these two are always set in HAL
+ // v1.3
+ EXPECT_TRUE(keyMgmtMask & ISupplicantStaNetwork::KeyMgmtMask::NONE);
+ EXPECT_TRUE(keyMgmtMask &
+ ISupplicantStaNetwork::KeyMgmtMask::IEEE8021X);
+ }
+ });
+}
diff --git a/wifi/supplicant/1.3/vts/functional/supplicant_sta_network_hidl_test.cpp b/wifi/supplicant/1.3/vts/functional/supplicant_sta_network_hidl_test.cpp
index 07bc9d8..d6f55f5 100644
--- a/wifi/supplicant/1.3/vts/functional/supplicant_sta_network_hidl_test.cpp
+++ b/wifi/supplicant/1.3/vts/functional/supplicant_sta_network_hidl_test.cpp
@@ -17,15 +17,18 @@
#include <android-base/logging.h>
#include <VtsHalHidlTargetTestBase.h>
+#include <android/hardware/wifi/supplicant/1.3/ISupplicantStaIface.h>
#include <android/hardware/wifi/supplicant/1.3/ISupplicantStaNetwork.h>
#include "supplicant_hidl_test_utils.h"
#include "supplicant_hidl_test_utils_1_3.h"
using ::android::sp;
+using ::android::hardware::hidl_string;
using ::android::hardware::hidl_vec;
using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatus;
using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatusCode;
+using ::android::hardware::wifi::supplicant::V1_3::ISupplicantStaIface;
using ::android::hardware::wifi::supplicant::V1_3::ISupplicantStaNetwork;
using ::android::hardware::wifi::supplicant::V1_3::OcspType;
namespace {
@@ -39,15 +42,37 @@
virtual void SetUp() override {
startSupplicantAndWaitForHidlService();
EXPECT_TRUE(turnOnExcessiveLogging());
+ sta_iface_ = getSupplicantStaIface_1_3();
+ ASSERT_NE(nullptr, sta_iface_.get());
sta_network_ = createSupplicantStaNetwork_1_3();
- ASSERT_NE(sta_network_.get(), nullptr);
+ ASSERT_NE(nullptr, sta_network_.get());
}
virtual void TearDown() override { stopSupplicant(); }
protected:
+ sp<ISupplicantStaIface> sta_iface_;
// ISupplicantStaNetwork object used for all tests in this fixture.
sp<ISupplicantStaNetwork> sta_network_;
+
+ bool isWapiSupported() {
+ uint32_t keyMgmtMask = 0;
+
+ // We need to first get the key management capabilities from the device.
+ // If WAPI is not supported, we just pass the test.
+ sta_iface_->getKeyMgmtCapabilities_1_3(
+ [&](const SupplicantStatus &status, uint32_t keyMgmtMaskInternal) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ keyMgmtMask = keyMgmtMaskInternal;
+ });
+
+ if (!(keyMgmtMask & ISupplicantStaNetwork::KeyMgmtMask::WAPI_PSK)) {
+ // WAPI not supported
+ return false;
+ }
+
+ return true;
+ }
};
/*
@@ -84,3 +109,160 @@
EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
});
}
+
+/*
+ * SetGetKeyMgmt_1_3, check new WAPI proto support
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SetGetKeyMgmt_1_3) {
+ uint32_t keyMgmt = (uint32_t)ISupplicantStaNetwork::KeyMgmtMask::WAPI_PSK;
+
+ sta_network_->setKeyMgmt_1_3(keyMgmt, [](const SupplicantStatus &status) {
+ if (SupplicantStatusCode::SUCCESS != status.code) {
+ // for unsupport case
+ EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code);
+ }
+ });
+
+ sta_network_->getKeyMgmt_1_3(
+ [&keyMgmt](const SupplicantStatus &status, uint32_t keyMgmtOut) {
+ if (SupplicantStatusCode::SUCCESS != status.code) {
+ // for unsupport case
+ EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code);
+ } else {
+ EXPECT_EQ(keyMgmtOut, keyMgmt);
+ }
+ });
+
+ keyMgmt = (uint32_t)ISupplicantStaNetwork::KeyMgmtMask::WAPI_CERT;
+ sta_network_->setKeyMgmt_1_3(keyMgmt, [](const SupplicantStatus &status) {
+ if (SupplicantStatusCode::SUCCESS != status.code) {
+ // for unsupport case
+ EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code);
+ }
+ });
+
+ sta_network_->getKeyMgmt_1_3(
+ [&keyMgmt](const SupplicantStatus &status, uint32_t keyMgmtOut) {
+ if (SupplicantStatusCode::SUCCESS != status.code) {
+ // for unsupport case
+ EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code);
+ } else {
+ EXPECT_EQ(keyMgmtOut, keyMgmt);
+ }
+ });
+}
+
+/*
+ * SetGetProto_1_3, check new WAPI proto support
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SetGetProto_1_3) {
+ uint32_t wapiProto = (uint32_t)ISupplicantStaNetwork::ProtoMask::WAPI;
+ sta_network_->setProto(wapiProto, [](const SupplicantStatus &status) {
+ if (SupplicantStatusCode::SUCCESS != status.code) {
+ // for unsupport case
+ EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code);
+ }
+ });
+ sta_network_->getProto([&](const SupplicantStatus &status, uint32_t proto) {
+ if (SupplicantStatusCode::SUCCESS != status.code) {
+ // for unsupport case
+ EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code);
+ } else {
+ EXPECT_EQ(proto, wapiProto);
+ }
+ });
+}
+
+/*
+ * SetGetGroupCipher_1_3, check new WAPI support
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SetGetGroupCipher_1_3) {
+ uint32_t groupCipher =
+ (uint32_t)ISupplicantStaNetwork::GroupCipherMask::SMS4;
+
+ sta_network_->setGroupCipher_1_3(
+ groupCipher, [](const SupplicantStatus &status) {
+ if (SupplicantStatusCode::SUCCESS != status.code) {
+ // for unsupport case
+ EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code);
+ }
+ });
+
+ sta_network_->getGroupCipher_1_3(
+ [&groupCipher](const SupplicantStatus &status,
+ uint32_t groupCipherOut) {
+ if (SupplicantStatusCode::SUCCESS != status.code) {
+ // for unsupport case
+ EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code);
+ } else {
+ EXPECT_EQ(groupCipherOut, groupCipher);
+ }
+ });
+}
+
+/*
+ * SetGetPairwiseCipher_1_3, check new WAPI support
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SetGetPairwiseCipher_1_3) {
+ uint32_t pairwiseCipher =
+ (uint32_t)ISupplicantStaNetwork::PairwiseCipherMask::SMS4;
+
+ sta_network_->setPairwiseCipher_1_3(
+ pairwiseCipher, [](const SupplicantStatus &status) {
+ if (SupplicantStatusCode::SUCCESS != status.code) {
+ // for unsupport case
+ EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code);
+ }
+ });
+
+ sta_network_->getPairwiseCipher_1_3(
+ [&pairwiseCipher](const SupplicantStatus &status,
+ uint32_t pairwiseCipherOut) {
+ if (SupplicantStatusCode::SUCCESS != status.code) {
+ // for unsupport case
+ EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code);
+ } else {
+ EXPECT_EQ(pairwiseCipherOut, pairwiseCipher);
+ }
+ });
+}
+
+/*
+ * SetGetWapiCertSuite
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SetGetWapiCertSuite) {
+ hidl_string testWapiCertSuite = "suite";
+
+ if (isWapiSupported()) {
+ sta_network_->setWapiCertSuite(
+ testWapiCertSuite, [](const SupplicantStatus &status) {
+ if (SupplicantStatusCode::SUCCESS != status.code) {
+ // for unsupport case
+ EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN,
+ status.code);
+ }
+ });
+
+ sta_network_->getWapiCertSuite([testWapiCertSuite](
+ const SupplicantStatus &status,
+ const hidl_string &wapiCertSuite) {
+ if (SupplicantStatusCode::SUCCESS != status.code) {
+ // for unsupport case
+ EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code);
+ } else {
+ EXPECT_EQ(testWapiCertSuite, wapiCertSuite);
+ }
+ });
+ } else {
+ sta_network_->setWapiCertSuite(
+ testWapiCertSuite, [](const SupplicantStatus &status) {
+ EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code);
+ });
+
+ sta_network_->getWapiCertSuite(
+ [testWapiCertSuite](const SupplicantStatus &status,
+ const hidl_string &wapiCertSuite __unused) {
+ EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code);
+ });
+ }
+}