Merge "move VTS HIDL HAL tests to the corresponding interface directories"
diff --git a/audio/2.0/default/Android.mk b/audio/2.0/default/Android.mk
index 5108448..2b1aa4f 100644
--- a/audio/2.0/default/Android.mk
+++ b/audio/2.0/default/Android.mk
@@ -66,6 +66,7 @@
android.hardware.audio.common@2.0 \
android.hardware.audio.effect@2.0 \
android.hardware.soundtrigger@2.0 \
+ android.hardware.broadcastradio@1.0
ifeq ($(strip $(AUDIOSERVER_MULTILIB)),)
LOCAL_MULTILIB := 32
diff --git a/audio/2.0/default/Device.cpp b/audio/2.0/default/Device.cpp
index 05824c7..339f371 100644
--- a/audio/2.0/default/Device.cpp
+++ b/audio/2.0/default/Device.cpp
@@ -520,7 +520,7 @@
return setParametersImpl(parameters);
}
-Return<void> Device::debugDump(const native_handle_t* fd) {
+Return<void> Device::debugDump(const hidl_handle& fd) {
if (fd->numFds == 1) {
analyzeStatus("dump", mDevice->dump(mDevice, fd->data[0]));
}
diff --git a/audio/2.0/default/Device.h b/audio/2.0/default/Device.h
index d7b3128..3fd67e3 100644
--- a/audio/2.0/default/Device.h
+++ b/audio/2.0/default/Device.h
@@ -102,7 +102,7 @@
Return<void> getParameters(
const hidl_vec<hidl_string>& keys, getParameters_cb _hidl_cb) override;
Return<Result> setParameters(const hidl_vec<ParameterValue>& parameters) override;
- Return<void> debugDump(const native_handle_t* fd) override;
+ Return<void> debugDump(const hidl_handle& fd) override;
// Utility methods for extending interfaces.
Result analyzeStatus(const char* funcName, int status);
diff --git a/audio/2.0/default/PrimaryDevice.cpp b/audio/2.0/default/PrimaryDevice.cpp
index 9f5180c..a8aa5ec 100644
--- a/audio/2.0/default/PrimaryDevice.cpp
+++ b/audio/2.0/default/PrimaryDevice.cpp
@@ -119,7 +119,7 @@
return mDevice->setParameters(parameters);
}
-Return<void> PrimaryDevice::debugDump(const native_handle_t* fd) {
+Return<void> PrimaryDevice::debugDump(const hidl_handle& fd) {
return mDevice->debugDump(fd);
}
diff --git a/audio/2.0/default/PrimaryDevice.h b/audio/2.0/default/PrimaryDevice.h
index 4c5b590..968c208 100644
--- a/audio/2.0/default/PrimaryDevice.h
+++ b/audio/2.0/default/PrimaryDevice.h
@@ -88,7 +88,7 @@
Return<void> getParameters(
const hidl_vec<hidl_string>& keys, getParameters_cb _hidl_cb) override;
Return<Result> setParameters(const hidl_vec<ParameterValue>& parameters) override;
- Return<void> debugDump(const native_handle_t* fd) override;
+ Return<void> debugDump(const hidl_handle& fd) override;
// Methods from ::android::hardware::audio::V2_0::IPrimaryDevice follow.
Return<Result> setVoiceVolume(float volume) override;
diff --git a/audio/2.0/default/Stream.cpp b/audio/2.0/default/Stream.cpp
index 7616bec..6d68f55 100644
--- a/audio/2.0/default/Stream.cpp
+++ b/audio/2.0/default/Stream.cpp
@@ -222,7 +222,7 @@
return setParametersImpl(parameters);
}
-Return<void> Stream::debugDump(const native_handle_t* fd) {
+Return<void> Stream::debugDump(const hidl_handle& fd) {
if (fd->numFds == 1) {
analyzeStatus("dump", mStream->dump(mStream, fd->data[0]));
}
diff --git a/audio/2.0/default/Stream.h b/audio/2.0/default/Stream.h
index f28fbff..3893af4 100644
--- a/audio/2.0/default/Stream.h
+++ b/audio/2.0/default/Stream.h
@@ -70,7 +70,7 @@
Return<void> getParameters(
const hidl_vec<hidl_string>& keys, getParameters_cb _hidl_cb) override;
Return<Result> setParameters(const hidl_vec<ParameterValue>& parameters) override;
- Return<void> debugDump(const native_handle_t* fd) override;
+ Return<void> debugDump(const hidl_handle& fd) override;
// Utility methods for extending interfaces.
Result analyzeStatus(const char* funcName, int status);
diff --git a/audio/2.0/default/StreamIn.cpp b/audio/2.0/default/StreamIn.cpp
index b590d1a..791e519 100644
--- a/audio/2.0/default/StreamIn.cpp
+++ b/audio/2.0/default/StreamIn.cpp
@@ -126,7 +126,7 @@
return mStreamCommon->setParameters(parameters);
}
-Return<void> StreamIn::debugDump(const native_handle_t* fd) {
+Return<void> StreamIn::debugDump(const hidl_handle& fd) {
return mStreamCommon->debugDump(fd);
}
diff --git a/audio/2.0/default/StreamIn.h b/audio/2.0/default/StreamIn.h
index 83f620c..c2a7ea2 100644
--- a/audio/2.0/default/StreamIn.h
+++ b/audio/2.0/default/StreamIn.h
@@ -72,7 +72,7 @@
Return<void> getParameters(
const hidl_vec<hidl_string>& keys, getParameters_cb _hidl_cb) override;
Return<Result> setParameters(const hidl_vec<ParameterValue>& parameters) override;
- Return<void> debugDump(const native_handle_t* fd) override;
+ Return<void> debugDump(const hidl_handle& fd) override;
// Methods from ::android::hardware::audio::V2_0::IStreamIn follow.
Return<void> getAudioSource(getAudioSource_cb _hidl_cb) override;
diff --git a/audio/2.0/default/StreamOut.cpp b/audio/2.0/default/StreamOut.cpp
index 34bae29..2106256 100644
--- a/audio/2.0/default/StreamOut.cpp
+++ b/audio/2.0/default/StreamOut.cpp
@@ -128,7 +128,7 @@
return mStreamCommon->setParameters(parameters);
}
-Return<void> StreamOut::debugDump(const native_handle_t* fd) {
+Return<void> StreamOut::debugDump(const hidl_handle& fd) {
return mStreamCommon->debugDump(fd);
}
diff --git a/audio/2.0/default/StreamOut.h b/audio/2.0/default/StreamOut.h
index 51b7df8..ca33b2d 100644
--- a/audio/2.0/default/StreamOut.h
+++ b/audio/2.0/default/StreamOut.h
@@ -74,7 +74,7 @@
Return<void> getParameters(
const hidl_vec<hidl_string>& keys, getParameters_cb _hidl_cb) override;
Return<Result> setParameters(const hidl_vec<ParameterValue>& parameters) override;
- Return<void> debugDump(const native_handle_t* fd) override;
+ Return<void> debugDump(const hidl_handle& fd) override;
// Methods from ::android::hardware::audio::V2_0::IStreamOut follow.
Return<uint32_t> getLatency() override;
diff --git a/audio/2.0/default/service.cpp b/audio/2.0/default/service.cpp
index 147f7b9..28ef660 100644
--- a/audio/2.0/default/service.cpp
+++ b/audio/2.0/default/service.cpp
@@ -20,6 +20,7 @@
#include <android/hardware/audio/2.0/IDevicesFactory.h>
#include <android/hardware/audio/effect/2.0/IEffectsFactory.h>
#include <android/hardware/soundtrigger/2.0/ISoundTriggerHw.h>
+#include <android/hardware/broadcastradio/1.0/IBroadcastRadioFactory.h>
using android::hardware::IPCThreadState;
using android::hardware::ProcessState;
@@ -27,10 +28,12 @@
using android::hardware::audio::V2_0::IDevicesFactory;
using android::hardware::soundtrigger::V2_0::ISoundTriggerHw;
using android::hardware::registerPassthroughServiceImplementation;
+using android::hardware::broadcastradio::V1_0::IBroadcastRadioFactory;
int main(int /* argc */, char* /* argv */ []) {
registerPassthroughServiceImplementation<IDevicesFactory>("audio_devices_factory");
registerPassthroughServiceImplementation<IEffectsFactory>("audio_effects_factory");
registerPassthroughServiceImplementation<ISoundTriggerHw>("sound_trigger.primary");
+ registerPassthroughServiceImplementation<IBroadcastRadioFactory>("broadcastradio");
return android::hardware::launchRpcServer(16);
}
diff --git a/audio/effect/2.0/default/EffectsFactory.cpp b/audio/effect/2.0/default/EffectsFactory.cpp
index 30fcb26..2b5d70b 100644
--- a/audio/effect/2.0/default/EffectsFactory.cpp
+++ b/audio/effect/2.0/default/EffectsFactory.cpp
@@ -182,7 +182,7 @@
return Void();
}
-Return<void> EffectsFactory::debugDump(const native_handle_t* fd) {
+Return<void> EffectsFactory::debugDump(const hidl_handle& fd) {
if (fd->numFds == 1) {
EffectDumpEffects(fd->data[0]);
}
diff --git a/audio/effect/2.0/default/EffectsFactory.h b/audio/effect/2.0/default/EffectsFactory.h
index 229356f..d934c93 100644
--- a/audio/effect/2.0/default/EffectsFactory.h
+++ b/audio/effect/2.0/default/EffectsFactory.h
@@ -47,7 +47,7 @@
Return<void> getDescriptor(const Uuid& uid, getDescriptor_cb _hidl_cb) override;
Return<void> createEffect(
const Uuid& uid, int32_t session, int32_t ioHandle, createEffect_cb _hidl_cb) override;
- Return<void> debugDump(const native_handle_t* fd) override;
+ Return<void> debugDump(const hidl_handle& fd) override;
private:
static sp<IEffect> dispatchEffectInstanceCreation(
diff --git a/broadcastradio/1.0/ITunerCallback.hal b/broadcastradio/1.0/ITunerCallback.hal
index f805472..a7e1260 100644
--- a/broadcastradio/1.0/ITunerCallback.hal
+++ b/broadcastradio/1.0/ITunerCallback.hal
@@ -72,7 +72,9 @@
/*
* Method called by the HAL when metadata for current station
* are updated.
- * @param metadatas A list of all updated metada.
+ * @param channel The channel the metadata is associated with.
+ * @param subChannel The sub channel the metadata is associated with.
+ * @param metadata A list of all updated metada.
*/
- oneway newMetadata(vec<MetaData> metadatas);
+ oneway newMetadata(uint32_t channel, uint32_t subChannel, vec<MetaData> metadata);
};
\ No newline at end of file
diff --git a/broadcastradio/1.0/default/Android.mk b/broadcastradio/1.0/default/Android.mk
new file mode 100644
index 0000000..734a0e1
--- /dev/null
+++ b/broadcastradio/1.0/default/Android.mk
@@ -0,0 +1,28 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hardware.broadcastradio@1.0-impl
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_SRC_FILES := \
+ BroadcastRadio.cpp \
+ BroadcastRadioFactory.cpp \
+ Tuner.cpp \
+ Utils.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+ libhidlbase \
+ libhidltransport \
+ libhwbinder \
+ libutils \
+ liblog \
+ libhardware \
+ android.hardware.broadcastradio@1.0 \
+ libradio_metadata
+
+ifeq ($(strip $(AUDIOSERVER_MULTILIB)),)
+LOCAL_MULTILIB := 32
+else
+LOCAL_MULTILIB := $(AUDIOSERVER_MULTILIB)
+endif
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/broadcastradio/1.0/default/BroadcastRadio.cpp b/broadcastradio/1.0/default/BroadcastRadio.cpp
new file mode 100644
index 0000000..b97b609
--- /dev/null
+++ b/broadcastradio/1.0/default/BroadcastRadio.cpp
@@ -0,0 +1,141 @@
+/*
+ * 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 "BroadcastRadio"
+//#define LOG_NDEBUG 0
+
+#include <utils/Log.h>
+#include <hardware/radio.h>
+
+#include "BroadcastRadio.h"
+#include "Tuner.h"
+#include "Utils.h"
+
+namespace android {
+namespace hardware {
+namespace broadcastradio {
+namespace V1_0 {
+namespace implementation {
+
+BroadcastRadio::BroadcastRadio(Class classId)
+ : mStatus(Result::NOT_INITIALIZED), mClassId(classId), mHwDevice(NULL)
+{
+}
+
+BroadcastRadio::~BroadcastRadio()
+{
+ if (mHwDevice != NULL) {
+ radio_hw_device_close(mHwDevice);
+ }
+}
+
+void BroadcastRadio::onFirstRef()
+{
+ const hw_module_t *mod;
+ int rc;
+ ALOGI("%s mClassId %d", __FUNCTION__, mClassId);
+
+ mHwDevice = NULL;
+ const char *classString = Utils::getClassString(mClassId);
+ if (classString == NULL) {
+ ALOGE("invalid class ID %d", mClassId);
+ mStatus = Result::INVALID_ARGUMENTS;
+ return;
+ }
+
+ ALOGI("%s RADIO_HARDWARE_MODULE_ID %s %s",
+ __FUNCTION__, RADIO_HARDWARE_MODULE_ID, classString);
+
+ rc = hw_get_module_by_class(RADIO_HARDWARE_MODULE_ID, classString, &mod);
+ if (rc != 0) {
+ ALOGE("couldn't load radio module %s.%s (%s)",
+ RADIO_HARDWARE_MODULE_ID, classString, strerror(-rc));
+ return;
+ }
+ rc = radio_hw_device_open(mod, &mHwDevice);
+ if (rc != 0) {
+ ALOGE("couldn't open radio hw device in %s.%s (%s)",
+ RADIO_HARDWARE_MODULE_ID, "primary", strerror(-rc));
+ mHwDevice = NULL;
+ return;
+ }
+ if (mHwDevice->common.version != RADIO_DEVICE_API_VERSION_CURRENT) {
+ ALOGE("wrong radio hw device version %04x", mHwDevice->common.version);
+ radio_hw_device_close(mHwDevice);
+ mHwDevice = NULL;
+ } else {
+ mStatus = Result::OK;
+ }
+}
+
+int BroadcastRadio::closeHalTuner(const struct radio_tuner *halTuner)
+{
+ ALOGV("%s", __FUNCTION__);
+ if (mHwDevice == NULL) {
+ return -ENODEV;
+ }
+ if (halTuner == 0) {
+ return -EINVAL;
+ }
+ return mHwDevice->close_tuner(mHwDevice, halTuner);
+}
+
+
+// Methods from ::android::hardware::broadcastradio::V1_0::IBroadcastRadio follow.
+Return<void> BroadcastRadio::getProperties(getProperties_cb _hidl_cb)
+{
+ int rc;
+ radio_hal_properties_t halProperties;
+ Properties properties;
+
+ if (mHwDevice == NULL) {
+ rc = -ENODEV;
+ goto exit;
+ }
+ rc = mHwDevice->get_properties(mHwDevice, &halProperties);
+ if (rc == 0) {
+ Utils::convertPropertiesFromHal(&properties, &halProperties);
+ }
+
+exit:
+ _hidl_cb(Utils::convertHalResult(rc), properties);
+ return Void();
+}
+
+Return<void> BroadcastRadio::openTuner(const BandConfig& config, bool audio,
+ const sp<ITunerCallback>& callback, openTuner_cb _hidl_cb)
+{
+ sp<Tuner> tunerImpl = new Tuner(callback, this);
+
+ radio_hal_band_config_t halConfig;
+ const struct radio_tuner *halTuner;
+ Utils::convertBandConfigToHal(&halConfig, &config);
+ int rc = mHwDevice->open_tuner(mHwDevice, &halConfig, audio,
+ Tuner::callback, tunerImpl.get(),
+ &halTuner);
+ if (rc == 0) {
+ tunerImpl->setHalTuner(halTuner);
+ }
+
+ _hidl_cb(Utils::convertHalResult(rc), tunerImpl);
+ return Void();
+}
+
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace broadcastradio
+} // namespace hardware
+} // namespace android
diff --git a/broadcastradio/1.0/default/BroadcastRadio.h b/broadcastradio/1.0/default/BroadcastRadio.h
new file mode 100644
index 0000000..dbd6e07
--- /dev/null
+++ b/broadcastradio/1.0/default/BroadcastRadio.h
@@ -0,0 +1,71 @@
+/*
+ * 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.
+ */
+#ifndef HIDL_GENERATED_android_hardware_broadcastradio_V1_0_BroadcastRadio_H_
+#define HIDL_GENERATED_android_hardware_broadcastradio_V1_0_BroadcastRadio_H_
+
+#include <android/hardware/broadcastradio/1.0/IBroadcastRadio.h>
+#include <hidl/Status.h>
+#include <hardware/radio.h>
+
+#include <hidl/MQDescriptor.h>
+namespace android {
+namespace hardware {
+namespace broadcastradio {
+namespace V1_0 {
+namespace implementation {
+
+struct BroadcastRadio : public IBroadcastRadio {
+
+ BroadcastRadio(Class classId);
+
+ // Methods from ::android::hardware::broadcastradio::V1_0::IBroadcastRadio follow.
+ Return<void> getProperties(getProperties_cb _hidl_cb) override;
+ Return<void> openTuner(const BandConfig& config, bool audio,
+ const sp<ITunerCallback>& callback,
+ openTuner_cb _hidl_cb) override;
+
+
+ // RefBase
+ virtual void onFirstRef();
+
+ Result initCheck() { return mStatus; }
+ int closeHalTuner(const struct radio_tuner *halTuner);
+
+private:
+ virtual ~BroadcastRadio();
+
+ static const char * sClassModuleNames[];
+
+ Result convertHalResult(int rc);
+ void convertBandConfigFromHal(BandConfig *config,
+ const radio_hal_band_config_t *halConfig);
+ void convertPropertiesFromHal(Properties *properties,
+ const radio_hal_properties_t *halProperties);
+ void convertBandConfigToHal(radio_hal_band_config_t *halConfig,
+ const BandConfig *config);
+
+ Result mStatus;
+ Class mClassId;
+ struct radio_hw_device *mHwDevice;
+};
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace broadcastradio
+} // namespace hardware
+} // namespace android
+
+#endif // HIDL_GENERATED_android_hardware_broadcastradio_V1_0_BroadcastRadio_H_
diff --git a/broadcastradio/1.0/default/BroadcastRadioFactory.cpp b/broadcastradio/1.0/default/BroadcastRadioFactory.cpp
new file mode 100644
index 0000000..d5d214c
--- /dev/null
+++ b/broadcastradio/1.0/default/BroadcastRadioFactory.cpp
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+#include "BroadcastRadioFactory.h"
+#include "BroadcastRadio.h"
+
+namespace android {
+namespace hardware {
+namespace broadcastradio {
+namespace V1_0 {
+namespace implementation {
+
+// Methods from ::android::hardware::broadcastradio::V1_0::IBroadcastRadioFactory follow.
+Return<void> BroadcastRadioFactory::connectModule(Class classId, connectModule_cb _hidl_cb) {
+ sp<BroadcastRadio> impl = new BroadcastRadio(classId);
+ Result retval = Result::NOT_INITIALIZED;
+ if (impl != 0) {
+ retval = impl->initCheck();
+ }
+ _hidl_cb(retval, impl);
+ return Void();
+}
+
+
+IBroadcastRadioFactory* HIDL_FETCH_IBroadcastRadioFactory(const char* /* name */) {
+ return new BroadcastRadioFactory();
+}
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace broadcastradio
+} // namespace hardware
+} // namespace android
diff --git a/broadcastradio/1.0/default/BroadcastRadioFactory.h b/broadcastradio/1.0/default/BroadcastRadioFactory.h
new file mode 100644
index 0000000..9b2ca17
--- /dev/null
+++ b/broadcastradio/1.0/default/BroadcastRadioFactory.h
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+#ifndef HIDL_GENERATED_android_hardware_broadcastradio_V1_0_BroadcastRadioFactory_H_
+#define HIDL_GENERATED_android_hardware_broadcastradio_V1_0_BroadcastRadioFactory_H_
+
+#include <android/hardware/broadcastradio/1.0/IBroadcastRadioFactory.h>
+#include <hidl/Status.h>
+
+#include <hidl/MQDescriptor.h>
+namespace android {
+namespace hardware {
+namespace broadcastradio {
+namespace V1_0 {
+namespace implementation {
+
+struct BroadcastRadioFactory : public IBroadcastRadioFactory {
+ // Methods from ::android::hardware::broadcastradio::V1_0::IBroadcastRadioFactory follow.
+ Return<void> connectModule(Class classId, connectModule_cb _hidl_cb) override;
+
+};
+
+extern "C" IBroadcastRadioFactory* HIDL_FETCH_IBroadcastRadioFactory(const char* name);
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace broadcastradio
+} // namespace hardware
+} // namespace android
+
+#endif // HIDL_GENERATED_android_hardware_broadcastradio_V1_0_BroadcastRadioFactory_H_
diff --git a/broadcastradio/1.0/default/Tuner.cpp b/broadcastradio/1.0/default/Tuner.cpp
new file mode 100644
index 0000000..0c1d8ab
--- /dev/null
+++ b/broadcastradio/1.0/default/Tuner.cpp
@@ -0,0 +1,199 @@
+/*
+ * 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 "Tuner"
+//#define LOG_NDEBUG 0
+
+#include <utils/Log.h>
+
+#include "BroadcastRadio.h"
+#include "Tuner.h"
+#include "Utils.h"
+#include <system/radio_metadata.h>
+
+namespace android {
+namespace hardware {
+namespace broadcastradio {
+namespace V1_0 {
+namespace implementation {
+
+void Tuner::onCallback(radio_hal_event_t *halEvent)
+{
+ BandConfig config;
+ ProgramInfo info;
+ hidl_vec<MetaData> metadata;
+
+ if (mCallback != 0) {
+ switch(halEvent->type) {
+ case RADIO_EVENT_CONFIG:
+ Utils::convertBandConfigFromHal(&config, &halEvent->config);
+ mCallback->configChange(Utils::convertHalResult(halEvent->status), config);
+ break;
+ case RADIO_EVENT_ANTENNA:
+ mCallback->antennaStateChange(halEvent->on);
+ break;
+ case RADIO_EVENT_TUNED:
+ Utils::convertProgramInfoFromHal(&info, &halEvent->info, true);
+ mCallback->tuneComplete(Utils::convertHalResult(halEvent->status), info);
+ break;
+ case RADIO_EVENT_METADATA: {
+ uint32_t channel;
+ uint32_t sub_channel;
+ if (radio_metadata_get_channel(halEvent->metadata, &channel, &sub_channel) == 0) {
+ Utils::convertMetaDataFromHal(metadata, halEvent->metadata);
+ mCallback->newMetadata(channel, sub_channel, metadata);
+ }
+ } break;
+ case RADIO_EVENT_TA:
+ mCallback->trafficAnnouncement(halEvent->on);
+ break;
+ case RADIO_EVENT_AF_SWITCH:
+ Utils::convertProgramInfoFromHal(&info, &halEvent->info, true);
+ mCallback->afSwitch(info);
+ break;
+ case RADIO_EVENT_EA:
+ mCallback->emergencyAnnouncement(halEvent->on);
+ break;
+ case RADIO_EVENT_HW_FAILURE:
+ default:
+ mCallback->hardwareFailure();
+ break;
+ }
+ }
+}
+
+//static
+void Tuner::callback(radio_hal_event_t *halEvent, void *cookie)
+{
+ wp<Tuner> weak(reinterpret_cast<Tuner*>(cookie));
+ sp<Tuner> tuner = weak.promote();
+ if (tuner == 0) return;
+ tuner->onCallback(halEvent);
+}
+
+Tuner::Tuner(const sp<ITunerCallback>& callback, const wp<BroadcastRadio>& parentDevice)
+ : mHalTuner(NULL), mCallback(callback), mParentDevice(parentDevice)
+{
+ ALOGV("%s", __FUNCTION__);
+}
+
+
+Tuner::~Tuner()
+{
+ ALOGV("%s", __FUNCTION__);
+ const sp<BroadcastRadio> parentDevice = mParentDevice.promote();
+ if (parentDevice != 0) {
+ parentDevice->closeHalTuner(mHalTuner);
+ }
+}
+
+// Methods from ::android::hardware::broadcastradio::V1_0::ITuner follow.
+Return<Result> Tuner::setConfiguration(const BandConfig& config) {
+ ALOGV("%s", __FUNCTION__);
+ if (mHalTuner == NULL) {
+ return Utils::convertHalResult(-ENODEV);
+ }
+ radio_hal_band_config_t halConfig;
+ Utils::convertBandConfigToHal(&halConfig, &config);
+ int rc = mHalTuner->set_configuration(mHalTuner, &halConfig);
+ return Utils::convertHalResult(rc);
+}
+
+Return<void> Tuner::getConfiguration(getConfiguration_cb _hidl_cb) {
+ int rc;
+ radio_hal_band_config_t halConfig;
+ BandConfig config;
+
+ ALOGV("%s", __FUNCTION__);
+ if (mHalTuner == NULL) {
+ rc = -ENODEV;
+ goto exit;
+ }
+ rc = mHalTuner->get_configuration(mHalTuner, &halConfig);
+ if (rc == 0) {
+ Utils::convertBandConfigFromHal(&config, &halConfig);
+ }
+
+exit:
+ _hidl_cb(Utils::convertHalResult(rc), config);
+ return Void();
+}
+
+Return<Result> Tuner::scan(Direction direction, bool skipSubChannel) {
+ if (mHalTuner == NULL) {
+ return Utils::convertHalResult(-ENODEV);
+ }
+ int rc = mHalTuner->scan(mHalTuner, static_cast<radio_direction_t>(direction), skipSubChannel);
+ return Utils::convertHalResult(rc);
+}
+
+Return<Result> Tuner::step(Direction direction, bool skipSubChannel) {
+ if (mHalTuner == NULL) {
+ return Utils::convertHalResult(-ENODEV);
+ }
+ int rc = mHalTuner->step(mHalTuner, static_cast<radio_direction_t>(direction), skipSubChannel);
+ return Utils::convertHalResult(rc);
+}
+
+Return<Result> Tuner::tune(uint32_t channel, uint32_t subChannel) {
+ if (mHalTuner == NULL) {
+ return Utils::convertHalResult(-ENODEV);
+ }
+ int rc = mHalTuner->tune(mHalTuner, channel, subChannel);
+ return Utils::convertHalResult(rc);
+}
+
+Return<Result> Tuner::cancel() {
+ if (mHalTuner == NULL) {
+ return Utils::convertHalResult(-ENODEV);
+ }
+ int rc = mHalTuner->cancel(mHalTuner);
+ return Utils::convertHalResult(rc);
+}
+
+Return<void> Tuner::getProgramInformation(bool withMetadata, getProgramInformation_cb _hidl_cb) {
+ int rc;
+ radio_program_info_t halInfo;
+ ProgramInfo info;
+
+ ALOGV("%s", __FUNCTION__);
+ if (mHalTuner == NULL) {
+ rc = -ENODEV;
+ goto exit;
+ }
+ if (withMetadata) {
+ radio_metadata_allocate(&halInfo.metadata, 0, 0);
+ } else {
+ halInfo.metadata = NULL;
+ }
+ rc = mHalTuner->get_program_information(mHalTuner, &halInfo);
+ if (rc == 0) {
+ Utils::convertProgramInfoFromHal(&info, &halInfo, withMetadata);
+ }
+ if (withMetadata) {
+ radio_metadata_deallocate(halInfo.metadata);
+ }
+
+exit:
+ _hidl_cb(Utils::convertHalResult(rc), info);
+ return Void();
+}
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace broadcastradio
+} // namespace hardware
+} // namespace android
diff --git a/broadcastradio/1.0/default/Tuner.h b/broadcastradio/1.0/default/Tuner.h
new file mode 100644
index 0000000..94e216e
--- /dev/null
+++ b/broadcastradio/1.0/default/Tuner.h
@@ -0,0 +1,67 @@
+/*
+ * 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.
+ */
+#ifndef HIDL_GENERATED_android_hardware_broadcastradio_V1_0_Tuner_H_
+#define HIDL_GENERATED_android_hardware_broadcastradio_V1_0_Tuner_H_
+
+#include <android/hardware/broadcastradio/1.0/ITuner.h>
+#include <android/hardware/broadcastradio/1.0/ITunerCallback.h>
+#include <hidl/Status.h>
+#include <hardware/radio.h>
+
+namespace android {
+namespace hardware {
+namespace broadcastradio {
+namespace V1_0 {
+namespace implementation {
+
+struct BroadcastRadio;
+
+struct Tuner : public ITuner {
+
+ Tuner(const sp<ITunerCallback>& callback, const wp<BroadcastRadio>& mParentDevice);
+
+ // Methods from ::android::hardware::broadcastradio::V1_0::ITuner follow.
+ Return<Result> setConfiguration(const BandConfig& config) override;
+ Return<void> getConfiguration(getConfiguration_cb _hidl_cb) override;
+ Return<Result> scan(Direction direction, bool skipSubChannel) override;
+ Return<Result> step(Direction direction, bool skipSubChannel) override;
+ Return<Result> tune(uint32_t channel, uint32_t subChannel) override;
+ Return<Result> cancel() override;
+ Return<void> getProgramInformation(bool withMetadata,
+ getProgramInformation_cb _hidl_cb) override;
+
+ static void callback(radio_hal_event_t *halEvent, void *cookie);
+ void onCallback(radio_hal_event_t *halEvent);
+
+ void setHalTuner(const struct radio_tuner *halTuner) { mHalTuner = halTuner; }
+ const struct radio_tuner *getHalTuner() { return mHalTuner; }
+
+ private:
+ ~Tuner();
+
+ const struct radio_tuner *mHalTuner;
+ const sp<ITunerCallback> mCallback;
+ const wp<BroadcastRadio> mParentDevice;
+};
+
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace broadcastradio
+} // namespace hardware
+} // namespace android
+
+#endif // HIDL_GENERATED_android_hardware_broadcastradio_V1_0_Tuner_H_
diff --git a/broadcastradio/1.0/default/Utils.cpp b/broadcastradio/1.0/default/Utils.cpp
new file mode 100644
index 0000000..bdaae00
--- /dev/null
+++ b/broadcastradio/1.0/default/Utils.cpp
@@ -0,0 +1,297 @@
+/*
+ * 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 "BroadcastRadioHalUtils"
+//#define LOG_NDEBUG 0
+
+#include <utils/Log.h>
+#include <utils/misc.h>
+#include <system/radio_metadata.h>
+
+#include "Utils.h"
+
+namespace android {
+namespace hardware {
+namespace broadcastradio {
+namespace V1_0 {
+namespace implementation {
+
+const char *Utils::sClassModuleNames[] = {
+ RADIO_HARDWARE_MODULE_ID_FM, /* corresponds to RADIO_CLASS_AM_FM */
+ RADIO_HARDWARE_MODULE_ID_SAT, /* corresponds to RADIO_CLASS_SAT */
+ RADIO_HARDWARE_MODULE_ID_DT, /* corresponds to RADIO_CLASS_DT */
+};
+
+// make sure HIDL enum values are aligned with legacy values
+static_assert(RADIO_CLASS_AM_FM == static_cast<int>(Class::AM_FM),
+ "AM/FM class mismatch with legacy");
+static_assert(RADIO_CLASS_SAT == static_cast<int>(Class::SAT),
+ "SAT class mismatch with legacy");
+static_assert(RADIO_CLASS_DT == static_cast<int>(Class::DT),
+ "DT class mismatch with legacy");
+
+static_assert(RADIO_BAND_AM == static_cast<int>(Band::AM),
+ "AM band mismatch with legacy");
+static_assert(RADIO_BAND_FM == static_cast<int>(Band::FM),
+ "FM band mismatch with legacy");
+static_assert(RADIO_BAND_AM_HD == static_cast<int>(Band::AM_HD),
+ "AM HD band mismatch with legacy");
+static_assert(RADIO_BAND_FM_HD == static_cast<int>(Band::FM_HD),
+ "FM HD band mismatch with legacy");
+
+static_assert(RADIO_RDS_NONE == static_cast<int>(Rds::NONE),
+ "RDS NONE mismatch with legacy");
+static_assert(RADIO_RDS_WORLD == static_cast<int>(Rds::WORLD),
+ "RDS WORLD mismatch with legacy");
+static_assert(RADIO_RDS_US == static_cast<int>(Rds::US),
+ "RDS US mismatch with legacy");
+
+static_assert(RADIO_DEEMPHASIS_50 == static_cast<int>(Deemphasis::D50),
+ "De-emphasis 50 mismatch with legacy");
+static_assert(RADIO_DEEMPHASIS_75 == static_cast<int>(Deemphasis::D75),
+ "De-emphasis 75 mismatch with legacy");
+
+static_assert(RADIO_DIRECTION_UP == static_cast<int>(Direction::UP),
+ "Direction Up mismatch with legacy");
+static_assert(RADIO_DIRECTION_DOWN == static_cast<int>(Direction::DOWN),
+ "Direction Up mismatch with legacy");
+
+static_assert(RADIO_METADATA_TYPE_INVALID == static_cast<int>(MetadataType::INVALID),
+ "Metadata type INVALID mismatch with legacy");
+static_assert(RADIO_METADATA_TYPE_INT == static_cast<int>(MetadataType::INT),
+ "Metadata type INT mismatch with legacy");
+static_assert(RADIO_METADATA_TYPE_TEXT == static_cast<int>(MetadataType::TEXT),
+ "Metadata type TEXT mismatch with legacy");
+static_assert(RADIO_METADATA_TYPE_RAW == static_cast<int>(MetadataType::RAW),
+ "Metadata type RAW mismatch with legacy");
+static_assert(RADIO_METADATA_TYPE_CLOCK == static_cast<int>(MetadataType::CLOCK),
+ "Metadata type CLOCK mismatch with legacy");
+
+static_assert(RADIO_METADATA_KEY_INVALID == static_cast<int>(MetadataKey::INVALID),
+ "Metadata key INVALID mismatch with legacy");
+static_assert(RADIO_METADATA_KEY_RDS_PI == static_cast<int>(MetadataKey::RDS_PI),
+ "Metadata key RDS_PI mismatch with legacy");
+static_assert(RADIO_METADATA_KEY_RDS_PS == static_cast<int>(MetadataKey::RDS_PS),
+ "Metadata key RDS_PS mismatch with legacy");
+static_assert(RADIO_METADATA_KEY_RDS_PTY == static_cast<int>(MetadataKey::RDS_PTY),
+ "Metadata key RDS_PTY mismatch with legacy");
+static_assert(RADIO_METADATA_KEY_RBDS_PTY == static_cast<int>(MetadataKey::RBDS_PTY),
+ "Metadata key RBDS_PTY mismatch with legacy");
+static_assert(RADIO_METADATA_KEY_RDS_RT == static_cast<int>(MetadataKey::RDS_RT),
+ "Metadata key RDS_RT mismatch with legacy");
+static_assert(RADIO_METADATA_KEY_TITLE == static_cast<int>(MetadataKey::TITLE),
+ "Metadata key TITLE mismatch with legacy");
+static_assert(RADIO_METADATA_KEY_ARTIST == static_cast<int>(MetadataKey::ARTIST),
+ "Metadata key ARTIST mismatch with legacy");
+static_assert(RADIO_METADATA_KEY_ALBUM == static_cast<int>(MetadataKey::ALBUM),
+ "Metadata key ALBUM mismatch with legacy");
+static_assert(RADIO_METADATA_KEY_GENRE == static_cast<int>(MetadataKey::GENRE),
+ "Metadata key GENRE mismatch with legacy");
+static_assert(RADIO_METADATA_KEY_ICON == static_cast<int>(MetadataKey::ICON),
+ "Metadata key ICON mismatch with legacy");
+static_assert(RADIO_METADATA_KEY_ART == static_cast<int>(MetadataKey::ART),
+ "Metadata key ART mismatch with legacy");
+static_assert(RADIO_METADATA_KEY_CLOCK == static_cast<int>(MetadataKey::CLOCK),
+ "Metadata key CLOCK mismatch with legacy");
+
+
+//static
+const char * Utils::getClassString(Class ClassId)
+{
+ int id = static_cast<int>(ClassId);
+
+ if ((id < 0) ||
+ (id >= NELEM(sClassModuleNames))) {
+ ALOGE("invalid class ID %d", id);
+ return NULL;
+ }
+ return sClassModuleNames[id];
+}
+
+//static
+Result Utils::convertHalResult(int rc)
+{
+ switch (rc) {
+ case 0:
+ return Result::OK;
+ case -EINVAL:
+ return Result::INVALID_ARGUMENTS;
+ case -ENOSYS:
+ return Result::INVALID_STATE;
+ case -ETIMEDOUT:
+ return Result::TIMEOUT;
+ case -ENODEV:
+ default:
+ return Result::NOT_INITIALIZED;
+ }
+}
+
+//static
+void Utils::convertBandConfigFromHal(
+ BandConfig *config,
+ const radio_hal_band_config_t *halConfig)
+{
+
+ config->type = static_cast<Band>(halConfig->type);
+ config->antennaConnected = halConfig->antenna_connected;
+ config->lowerLimit = halConfig->lower_limit;
+ config->upperLimit = halConfig->upper_limit;
+ config->spacings.setToExternal(const_cast<unsigned int *>(&halConfig->spacings[0]),
+ halConfig->num_spacings * sizeof(uint32_t));
+ // FIXME: transfer buffer ownership. should have a method for that in hidl_vec
+ config->spacings.resize(halConfig->num_spacings);
+
+ if (config->type == Band::FM) {
+ config->ext.fm.deemphasis = static_cast<Deemphasis>(halConfig->fm.deemphasis);
+ config->ext.fm.stereo = halConfig->fm.stereo;
+ config->ext.fm.rds = static_cast<Rds>(halConfig->fm.rds);
+ config->ext.fm.ta = halConfig->fm.ta;
+ config->ext.fm.af = halConfig->fm.af;
+ config->ext.fm.ea = halConfig->fm.ea;
+ } else {
+ config->ext.am.stereo = halConfig->am.stereo;
+ }
+}
+
+//static
+void Utils::convertPropertiesFromHal(
+ Properties *properties,
+ const radio_hal_properties_t *halProperties)
+{
+ properties->classId = static_cast<Class>(halProperties->class_id);
+ properties->implementor.setToExternal(halProperties->implementor, strlen(halProperties->implementor));
+ properties->product.setToExternal(halProperties->product, strlen(halProperties->product));
+ properties->version.setToExternal(halProperties->version, strlen(halProperties->version));
+ properties->serial.setToExternal(halProperties->serial, strlen(halProperties->serial));
+ properties->numTuners = halProperties->num_tuners;
+ properties->numAudioSources = halProperties->num_audio_sources;
+ properties->supportsCapture = halProperties->supports_capture;
+
+ BandConfig *bands =
+ new BandConfig[halProperties->num_bands];
+ for (size_t i = 0; i < halProperties->num_bands; i++) {
+ convertBandConfigFromHal(&bands[i], &halProperties->bands[i]);
+ }
+ properties->bands.setToExternal(bands, halProperties->num_bands);
+ // FIXME: transfer buffer ownership. should have a method for that in hidl_vec
+ properties->bands.resize(halProperties->num_bands);
+ delete[] bands;
+}
+
+//static
+void Utils::convertBandConfigToHal(
+ radio_hal_band_config_t *halConfig,
+ const BandConfig *config)
+{
+
+ halConfig->type = static_cast<radio_band_t>(config->type);
+ halConfig->antenna_connected = config->antennaConnected;
+ halConfig->lower_limit = config->lowerLimit;
+ halConfig->upper_limit = config->upperLimit;
+ halConfig->num_spacings = config->spacings.size();
+ if (halConfig->num_spacings > RADIO_NUM_SPACINGS_MAX) {
+ halConfig->num_spacings = RADIO_NUM_SPACINGS_MAX;
+ }
+ memcpy(halConfig->spacings, config->spacings.data(),
+ sizeof(uint32_t) * halConfig->num_spacings);
+
+ if (config->type == Band::FM) {
+ halConfig->fm.deemphasis = static_cast<radio_deemphasis_t>(config->ext.fm.deemphasis);
+ halConfig->fm.stereo = config->ext.fm.stereo;
+ halConfig->fm.rds = static_cast<radio_rds_t>(config->ext.fm.rds);
+ halConfig->fm.ta = config->ext.fm.ta;
+ halConfig->fm.af = config->ext.fm.af;
+ halConfig->fm.ea = config->ext.fm.ea;
+ } else {
+ halConfig->am.stereo = config->ext.am.stereo;
+ }
+}
+
+
+//static
+void Utils::convertProgramInfoFromHal(ProgramInfo *info,
+ radio_program_info_t *halInfo,
+ bool withMetadata)
+{
+ info->channel = halInfo->channel;
+ info->subChannel = halInfo->sub_channel;
+ info->tuned = halInfo->tuned;
+ info->stereo = halInfo->stereo;
+ info->digital = halInfo->digital;
+ info->signalStrength = halInfo->signal_strength;
+ if (withMetadata && halInfo->metadata != NULL) {
+ convertMetaDataFromHal(info->metadata, halInfo->metadata);
+ }
+}
+
+//static
+int Utils::convertMetaDataFromHal(hidl_vec<MetaData>& metadata,
+ radio_metadata_t *halMetadata)
+{
+ if (halMetadata == NULL) {
+ return 0;
+ }
+
+ int count = radio_metadata_get_count(halMetadata);
+ if (count <= 0) {
+ return count;
+ }
+ MetaData *newMetadata =
+ new MetaData[count];
+ int outCount = 0;
+ for (int i = 0; i < count; i++) {
+ radio_metadata_key_t key;
+ radio_metadata_type_t type;
+ void *value;
+ size_t size;
+ if (radio_metadata_get_at_index(halMetadata, i , &key, &type, &value, &size) != 0 ||
+ size == 0) {
+ continue;
+ }
+ switch (type) {
+ case RADIO_METADATA_TYPE_INT: {
+ newMetadata[outCount].intValue = *(static_cast<int32_t *>(value));
+ } break;
+ case RADIO_METADATA_TYPE_TEXT: {
+ newMetadata[outCount].stringValue = static_cast<char *>(value);
+ } break;
+ case RADIO_METADATA_TYPE_RAW: {
+ newMetadata[outCount].rawValue.setToExternal(static_cast<uint8_t *>(value), size);
+ // FIXME: transfer buffer ownership. should have a method for that in hidl_vec
+ newMetadata[outCount].rawValue.resize(size);
+ } break;
+ case RADIO_METADATA_TYPE_CLOCK: {
+ radio_metadata_clock_t *clock = static_cast<radio_metadata_clock_t *>(value);
+ newMetadata[outCount].clockValue.utcSecondsSinceEpoch =
+ clock->utc_seconds_since_epoch;
+ newMetadata[outCount].clockValue.timezoneOffsetInMinutes =
+ clock->timezone_offset_in_minutes;
+ } break;
+ }
+ newMetadata[outCount].type = static_cast<MetadataType>(type);
+ newMetadata[outCount].key = static_cast<MetadataKey>(key);
+ outCount++;
+ }
+ metadata.setToExternal(newMetadata, outCount);
+ // FIXME: transfer buffer ownership. should have a method for that in hidl_vec
+ metadata.resize(outCount);
+ return outCount;
+}
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace broadcastradio
+} // namespace hardware
+} // namespace android
diff --git a/broadcastradio/1.0/default/Utils.h b/broadcastradio/1.0/default/Utils.h
new file mode 100644
index 0000000..25eb6ee
--- /dev/null
+++ b/broadcastradio/1.0/default/Utils.h
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+#ifndef ANDROID_HARDWARE_BROADCASTRADIO_V1_0_UTILS_H
+#define ANDROID_HARDWARE_BROADCASTRADIO_V1_0_UTILS_H
+
+#include <android/hardware/broadcastradio/1.0/types.h>
+#include <hardware/radio.h>
+
+namespace android {
+namespace hardware {
+namespace broadcastradio {
+namespace V1_0 {
+namespace implementation {
+
+class Utils {
+public:
+ static const char * getClassString(Class ClassId);
+ static Result convertHalResult(int rc);
+ static void convertBandConfigFromHal(BandConfig *config,
+ const radio_hal_band_config_t *halConfig);
+ static void convertPropertiesFromHal(Properties *properties,
+ const radio_hal_properties_t *halProperties);
+ static void convertBandConfigToHal(radio_hal_band_config_t *halConfig,
+ const BandConfig *config);
+ static void convertProgramInfoFromHal(ProgramInfo *info,
+ radio_program_info_t *halInfo,
+ bool withMetadata);
+ static int convertMetaDataFromHal(hidl_vec<MetaData>& metadata,
+ radio_metadata_t *halMetadata);
+private:
+ static const char * sClassModuleNames[];
+
+};
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace broadcastradio
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_BROADCASTRADIO_V1_0_UTILS_H
diff --git a/broadcastradio/1.0/types.hal b/broadcastradio/1.0/types.hal
index c5b4411..d04359c 100644
--- a/broadcastradio/1.0/types.hal
+++ b/broadcastradio/1.0/types.hal
@@ -54,7 +54,7 @@
enum Rds : uint32_t {
NONE = 0,
WORLD = (1<<0),
- RDS_US = (1<<1),
+ US = (1<<1),
};
@@ -111,7 +111,7 @@
union Ext {
FmBandConfig fm;
AmBandConfig am;
- };
+ } ext;
};
/* Exposes properties of a given hardware radio module.
diff --git a/graphics/Android.bp b/graphics/Android.bp
index 4ac7766..796ef41 100644
--- a/graphics/Android.bp
+++ b/graphics/Android.bp
@@ -2,6 +2,7 @@
subdirs = [
"allocator/2.0",
"allocator/2.0/default",
+ "allocator/2.0/vts/functional",
"common/1.0",
"composer/2.1",
"composer/2.1/default",
diff --git a/graphics/allocator/2.0/IAllocator.hal b/graphics/allocator/2.0/IAllocator.hal
index 0464bcd..9a45444 100644
--- a/graphics/allocator/2.0/IAllocator.hal
+++ b/graphics/allocator/2.0/IAllocator.hal
@@ -78,6 +78,9 @@
*
* @return capabilities is a list of supported capabilities.
*/
+ @entry
+ @exit
+ @callflow(next="*")
getCapabilities() generates (vec<Capability> capabilities);
/*
@@ -86,6 +89,9 @@
*
* @return debugInfo is a string of debug information.
*/
+ @entry
+ @exit
+ @callflow(next="*")
dumpDebugInfo() generates (string debugInfo);
/*
@@ -98,6 +104,8 @@
* NO_RESOURCES when no more descriptors can currently be created.
* @return descriptor is the newly created buffer descriptor.
*/
+ @entry
+ @callflow(next="*")
createDescriptor(BufferDescriptorInfo descriptorInfo)
generates (Error error,
BufferDescriptor descriptor);
@@ -108,6 +116,8 @@
* @param descriptor is the descriptor to destroy.
* @return error is either NONE or BAD_DESCRIPTOR.
*/
+ @exit
+ @callflow(next="*")
destroyDescriptor(BufferDescriptor descriptor) generates (Error error);
/*
@@ -124,6 +134,7 @@
* UNSUPPORTED when any of the descriptors can never be satisfied.
* UNDEFINED when TEST_ALLOCATE is not listed in getCapabilities.
*/
+ @callflow(next="allocate")
testAllocate(vec<BufferDescriptor> descriptors) generates (Error error);
/*
@@ -147,6 +158,7 @@
* time.
* @return buffers is the allocated buffers.
*/
+ @callflow(next="exportHandle")
allocate(vec<BufferDescriptor> descriptors)
generates (Error error,
vec<Buffer> buffers);
@@ -158,6 +170,8 @@
* @return error is NONE upon success. Otherwise,
* BAD_BUFFER when the buffer is invalid.
*/
+ @exit
+ @callflow(next="*")
free(Buffer buffer) generates (Error error);
/*
@@ -182,6 +196,7 @@
* NO_RESOURCES when the buffer cannot be exported at this time.
* @return bufferHandle is the exported handle.
*/
+ @callflow(next="free")
exportHandle(BufferDescriptor descriptor,
Buffer buffer)
generates (Error error,
diff --git a/graphics/allocator/2.0/vts/Allocator.vts b/graphics/allocator/2.0/vts/Allocator.vts
new file mode 100644
index 0000000..04d4314
--- /dev/null
+++ b/graphics/allocator/2.0/vts/Allocator.vts
@@ -0,0 +1,215 @@
+component_class: HAL_HIDL
+component_type_version: 2.0
+component_name: "IAllocator"
+
+package: "android.hardware.graphics.allocator"
+
+import: "android.hardware.graphics.allocator@2.0::types"
+
+interface: {
+ attribute: {
+ name: "::android::hardware::graphics::allocator::V2_0::IAllocator::Capability"
+ type: TYPE_ENUM
+ enum_value: {
+ scalar_type: "int32_t"
+
+ enumerator: "INVALID"
+ scalar_value: {
+ int32_t: 0
+ }
+ enumerator: "TEST_ALLOCATE"
+ scalar_value: {
+ int32_t: 1
+ }
+ }
+ }
+
+ attribute: {
+ name: "::android::hardware::graphics::allocator::V2_0::IAllocator::BufferDescriptorInfo"
+ type: TYPE_STRUCT
+ struct_value: {
+ name: "width"
+ type: TYPE_SCALAR
+ scalar_type: "uint32_t"
+ }
+ struct_value: {
+ name: "height"
+ type: TYPE_SCALAR
+ scalar_type: "uint32_t"
+ }
+ struct_value: {
+ name: "format"
+ type: TYPE_ENUM
+ predefined_type: "::android::hardware::graphics::allocator::V2_0::PixelFormat"
+ }
+ struct_value: {
+ name: "producerUsageMask"
+ type: TYPE_SCALAR
+ scalar_type: "uint64_t"
+ }
+ struct_value: {
+ name: "consumerUsageMask"
+ type: TYPE_SCALAR
+ scalar_type: "uint64_t"
+ }
+ }
+
+ api: {
+ name: "getCapabilities"
+ return_type_hidl: {
+ type: TYPE_VECTOR
+ vector_value: {
+ type: TYPE_ENUM
+ predefined_type: "::android::hardware::graphics::allocator::V2_0::IAllocator::Capability"
+ }
+ }
+ callflow: {
+ entry: true
+ }
+ callflow: {
+ exit: true
+ }
+ callflow: {
+ next: "*"
+ }
+ }
+
+ api: {
+ name: "dumpDebugInfo"
+ return_type_hidl: {
+ type: TYPE_STRING
+ }
+ callflow: {
+ entry: true
+ }
+ callflow: {
+ exit: true
+ }
+ callflow: {
+ next: "*"
+ }
+ }
+
+ api: {
+ name: "createDescriptor"
+ return_type_hidl: {
+ type: TYPE_ENUM
+ predefined_type: "::android::hardware::graphics::allocator::V2_0::Error"
+ }
+ return_type_hidl: {
+ type: TYPE_SCALAR
+ scalar_type: "uint64_t"
+ }
+ arg: {
+ type: TYPE_STRUCT
+ predefined_type: "::android::hardware::graphics::allocator::V2_0::IAllocator::BufferDescriptorInfo"
+ }
+ callflow: {
+ entry: true
+ }
+ callflow: {
+ next: "*"
+ }
+ }
+
+ api: {
+ name: "destroyDescriptor"
+ return_type_hidl: {
+ type: TYPE_ENUM
+ predefined_type: "::android::hardware::graphics::allocator::V2_0::Error"
+ }
+ arg: {
+ type: TYPE_SCALAR
+ scalar_type: "uint64_t"
+ }
+ callflow: {
+ exit: true
+ }
+ callflow: {
+ next: "*"
+ }
+ }
+
+ api: {
+ name: "testAllocate"
+ return_type_hidl: {
+ type: TYPE_ENUM
+ predefined_type: "::android::hardware::graphics::allocator::V2_0::Error"
+ }
+ arg: {
+ type: TYPE_VECTOR
+ vector_value: {
+ type: TYPE_SCALAR
+ scalar_type: "uint64_t"
+ }
+ }
+ callflow: {
+ next: "allocate"
+ }
+ }
+
+ api: {
+ name: "allocate"
+ return_type_hidl: {
+ type: TYPE_ENUM
+ predefined_type: "::android::hardware::graphics::allocator::V2_0::Error"
+ }
+ return_type_hidl: {
+ type: TYPE_VECTOR
+ vector_value: {
+ type: TYPE_SCALAR
+ scalar_type: "uint64_t"
+ }
+ }
+ arg: {
+ type: TYPE_VECTOR
+ vector_value: {
+ type: TYPE_SCALAR
+ scalar_type: "uint64_t"
+ }
+ }
+ callflow: {
+ next: "exportHandle"
+ }
+ }
+
+ api: {
+ name: "free"
+ return_type_hidl: {
+ type: TYPE_ENUM
+ predefined_type: "::android::hardware::graphics::allocator::V2_0::Error"
+ }
+ arg: {
+ type: TYPE_SCALAR
+ scalar_type: "uint64_t"
+ }
+ callflow: {
+ exit: true
+ }
+ callflow: {
+ next: "*"
+ }
+ }
+
+ api: {
+ name: "exportHandle"
+ return_type_hidl: {
+ type: TYPE_ENUM
+ predefined_type: "::android::hardware::graphics::allocator::V2_0::Error"
+ }
+ return_type_hidl: {
+ }
+ arg: {
+ type: TYPE_SCALAR
+ scalar_type: "uint64_t"
+ }
+ arg: {
+ type: TYPE_SCALAR
+ scalar_type: "uint64_t"
+ }
+ callflow: {
+ next: "free"
+ }
+ }
+
+}
diff --git a/graphics/allocator/2.0/vts/functional/Android.bp b/graphics/allocator/2.0/vts/functional/Android.bp
new file mode 100644
index 0000000..e1966dc
--- /dev/null
+++ b/graphics/allocator/2.0/vts/functional/Android.bp
@@ -0,0 +1,37 @@
+//
+// 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.
+//
+
+cc_test {
+ name: "graphics_allocator_hidl_hal_test",
+ gtest: true,
+ srcs: ["graphics_allocator_hidl_hal_test.cpp"],
+ shared_libs: [
+ "libbase",
+ "liblog",
+ "libcutils",
+ "libhidlbase",
+ "libhidltransport",
+ "libhwbinder",
+ "libnativehelper",
+ "libutils",
+ "android.hardware.graphics.allocator@2.0",
+ ],
+ static_libs: ["libgtest"],
+ cflags: [
+ "-O0",
+ "-g",
+ ],
+}
diff --git a/graphics/allocator/2.0/vts/functional/graphics_allocator_hidl_hal_test.cpp b/graphics/allocator/2.0/vts/functional/graphics_allocator_hidl_hal_test.cpp
new file mode 100644
index 0000000..54369a4
--- /dev/null
+++ b/graphics/allocator/2.0/vts/functional/graphics_allocator_hidl_hal_test.cpp
@@ -0,0 +1,304 @@
+/*
+ * 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 "graphics_allocator_hidl_hal_test"
+
+#include <unordered_set>
+
+#include <android-base/logging.h>
+#include <android/hardware/graphics/allocator/2.0/IAllocator.h>
+#include <gtest/gtest.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace allocator {
+namespace V2_0 {
+namespace tests {
+namespace {
+
+using android::hardware::graphics::common::V1_0::PixelFormat;
+
+#define CHECK_FEATURE_OR_SKIP(FEATURE_NAME) \
+ do { \
+ if (!hasCapability(FEATURE_NAME)) { \
+ std::cout << "[ SKIPPED ] Feature " << #FEATURE_NAME \
+ << " not supported" << std::endl; \
+ return; \
+ } \
+ } while (0)
+
+class TempDescriptor {
+ public:
+ TempDescriptor(const sp<IAllocator>& allocator,
+ const IAllocator::BufferDescriptorInfo& info)
+ : mAllocator(allocator), mError(Error::NO_RESOURCES) {
+ mAllocator->createDescriptor(
+ info, [&](const auto& tmpError, const auto& tmpDescriptor) {
+ mError = tmpError;
+ mDescriptor = tmpDescriptor;
+ });
+ }
+
+ ~TempDescriptor() {
+ if (mError == Error::NONE) {
+ mAllocator->destroyDescriptor(mDescriptor);
+ }
+ }
+
+ bool isValid() const { return (mError == Error::NONE); }
+
+ operator BufferDescriptor() const { return mDescriptor; }
+
+ private:
+ sp<IAllocator> mAllocator;
+ Error mError;
+ BufferDescriptor mDescriptor;
+};
+
+class GraphicsAllocatorHidlTest : public ::testing::Test {
+ protected:
+ void SetUp() override {
+ mAllocator = IAllocator::getService("gralloc");
+ ASSERT_NE(mAllocator, nullptr);
+
+ initCapabilities();
+
+ mDummyDescriptorInfo.width = 64;
+ mDummyDescriptorInfo.height = 64;
+ mDummyDescriptorInfo.format = PixelFormat::RGBA_8888;
+ mDummyDescriptorInfo.producerUsageMask =
+ static_cast<uint64_t>(ProducerUsage::CPU_WRITE);
+ mDummyDescriptorInfo.consumerUsageMask =
+ static_cast<uint64_t>(ConsumerUsage::CPU_READ);
+ }
+
+ void TearDown() override {}
+
+ /**
+ * Initialize the set of supported capabilities.
+ */
+ void initCapabilities() {
+ mAllocator->getCapabilities([this](const auto& capabilities) {
+ std::vector<IAllocator::Capability> caps = capabilities;
+ mCapabilities.insert(caps.cbegin(), caps.cend());
+ });
+ }
+
+ /**
+ * Test whether a capability is supported.
+ */
+ bool hasCapability(IAllocator::Capability capability) const {
+ return (mCapabilities.count(capability) > 0);
+ }
+
+ sp<IAllocator> mAllocator;
+ IAllocator::BufferDescriptorInfo mDummyDescriptorInfo{};
+
+ private:
+ std::unordered_set<IAllocator::Capability> mCapabilities;
+};
+
+TEST_F(GraphicsAllocatorHidlTest, GetCapabilities) {
+ auto ret = mAllocator->getCapabilities([](const auto& capabilities) {
+ std::vector<IAllocator::Capability> caps = capabilities;
+ for (auto cap : caps) {
+ EXPECT_NE(IAllocator::Capability::INVALID, cap);
+ }
+ });
+
+ ASSERT_TRUE(ret.getStatus().isOk());
+}
+
+TEST_F(GraphicsAllocatorHidlTest, DumpDebugInfo) {
+ auto ret = mAllocator->dumpDebugInfo([](const auto&) {
+ // nothing to do
+ });
+
+ ASSERT_TRUE(ret.getStatus().isOk());
+}
+
+TEST_F(GraphicsAllocatorHidlTest, CreateDestroyDescriptor) {
+ Error error;
+ BufferDescriptor descriptor;
+ auto ret = mAllocator->createDescriptor(
+ mDummyDescriptorInfo,
+ [&](const auto& tmpError, const auto& tmpDescriptor) {
+ error = tmpError;
+ descriptor = tmpDescriptor;
+ });
+
+ ASSERT_TRUE(ret.getStatus().isOk());
+ ASSERT_EQ(Error::NONE, error);
+
+ auto err_ret = mAllocator->destroyDescriptor(descriptor);
+ ASSERT_TRUE(err_ret.getStatus().isOk());
+ ASSERT_EQ(Error::NONE, static_cast<Error>(err_ret));
+}
+
+/**
+ * Test testAllocate with a single buffer descriptor.
+ */
+TEST_F(GraphicsAllocatorHidlTest, TestAllocateBasic) {
+ CHECK_FEATURE_OR_SKIP(IAllocator::Capability::TEST_ALLOCATE);
+
+ TempDescriptor descriptor(mAllocator, mDummyDescriptorInfo);
+ ASSERT_TRUE(descriptor.isValid());
+
+ hidl_vec<BufferDescriptor> descriptors;
+ descriptors.resize(1);
+ descriptors[0] = descriptor;
+
+ auto ret = mAllocator->testAllocate(descriptors);
+ ASSERT_TRUE(ret.getStatus().isOk());
+
+ auto error = static_cast<Error>(ret);
+ ASSERT_TRUE(error == Error::NONE || error == Error::NOT_SHARED);
+}
+
+/**
+ * Test testAllocate with two buffer descriptors.
+ */
+TEST_F(GraphicsAllocatorHidlTest, TestAllocateArray) {
+ CHECK_FEATURE_OR_SKIP(IAllocator::Capability::TEST_ALLOCATE);
+
+ TempDescriptor descriptor(mAllocator, mDummyDescriptorInfo);
+ ASSERT_TRUE(descriptor.isValid());
+
+ hidl_vec<BufferDescriptor> descriptors;
+ descriptors.resize(2);
+ descriptors[0] = descriptor;
+ descriptors[1] = descriptor;
+
+ auto ret = mAllocator->testAllocate(descriptors);
+ ASSERT_TRUE(ret.getStatus().isOk());
+
+ auto error = static_cast<Error>(ret);
+ ASSERT_TRUE(error == Error::NONE || error == Error::NOT_SHARED);
+}
+
+/**
+ * Test allocate/free with a single buffer descriptor.
+ */
+TEST_F(GraphicsAllocatorHidlTest, AllocateFreeBasic) {
+ TempDescriptor descriptor(mAllocator, mDummyDescriptorInfo);
+ ASSERT_TRUE(descriptor.isValid());
+
+ hidl_vec<BufferDescriptor> descriptors;
+ descriptors.resize(1);
+ descriptors[0] = descriptor;
+
+ Error error;
+ std::vector<Buffer> buffers;
+ auto ret = mAllocator->allocate(
+ descriptors, [&](const auto& tmpError, const auto& tmpBuffers) {
+ error = tmpError;
+ buffers = tmpBuffers;
+ });
+
+ ASSERT_TRUE(ret.getStatus().isOk());
+ ASSERT_TRUE(error == Error::NONE || error == Error::NOT_SHARED);
+ EXPECT_EQ(1u, buffers.size());
+
+ if (!buffers.empty()) {
+ auto err_ret = mAllocator->free(buffers[0]);
+ EXPECT_TRUE(err_ret.getStatus().isOk());
+ EXPECT_EQ(Error::NONE, static_cast<Error>(err_ret));
+ }
+}
+
+/**
+ * Test allocate/free with an array of buffer descriptors.
+ */
+TEST_F(GraphicsAllocatorHidlTest, AllocateFreeArray) {
+ TempDescriptor descriptor1(mAllocator, mDummyDescriptorInfo);
+ ASSERT_TRUE(descriptor1.isValid());
+
+ TempDescriptor descriptor2(mAllocator, mDummyDescriptorInfo);
+ ASSERT_TRUE(descriptor2.isValid());
+
+ hidl_vec<BufferDescriptor> descriptors;
+ descriptors.resize(3);
+ descriptors[0] = descriptor1;
+ descriptors[1] = descriptor1;
+ descriptors[2] = descriptor2;
+
+ Error error;
+ std::vector<Buffer> buffers;
+ auto ret = mAllocator->allocate(
+ descriptors, [&](const auto& tmpError, const auto& tmpBuffers) {
+ error = tmpError;
+ buffers = tmpBuffers;
+ });
+
+ ASSERT_TRUE(ret.getStatus().isOk());
+ ASSERT_TRUE(error == Error::NONE || error == Error::NOT_SHARED);
+ EXPECT_EQ(descriptors.size(), buffers.size());
+
+ for (auto buf : buffers) {
+ auto err_ret = mAllocator->free(buf);
+ EXPECT_TRUE(err_ret.getStatus().isOk());
+ EXPECT_EQ(Error::NONE, static_cast<Error>(err_ret));
+ }
+}
+
+TEST_F(GraphicsAllocatorHidlTest, ExportHandle) {
+ TempDescriptor descriptor(mAllocator, mDummyDescriptorInfo);
+ ASSERT_TRUE(descriptor.isValid());
+
+ hidl_vec<BufferDescriptor> descriptors;
+ descriptors.resize(1);
+ descriptors[0] = descriptor;
+
+ Error error;
+ std::vector<Buffer> buffers;
+ auto ret = mAllocator->allocate(
+ descriptors, [&](const auto& tmpError, const auto& tmpBuffers) {
+ error = tmpError;
+ buffers = tmpBuffers;
+ });
+
+ ASSERT_TRUE(ret.getStatus().isOk());
+ ASSERT_TRUE(error == Error::NONE || error == Error::NOT_SHARED);
+ ASSERT_EQ(1u, buffers.size());
+
+ ret = mAllocator->exportHandle(
+ descriptors[0], buffers[0],
+ [&](const auto& tmpError, const auto&) { error = tmpError; });
+ EXPECT_TRUE(ret.getStatus().isOk());
+ EXPECT_EQ(Error::NONE, error);
+
+ auto err_ret = mAllocator->free(buffers[0]);
+ EXPECT_TRUE(err_ret.getStatus().isOk());
+ EXPECT_EQ(Error::NONE, static_cast<Error>(err_ret));
+}
+
+} // namespace anonymous
+} // namespace tests
+} // namespace V2_0
+} // namespace allocator
+} // namespace graphics
+} // namespace hardware
+} // namespace android
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+
+ int status = RUN_ALL_TESTS();
+ ALOGI("Test result = %d", status);
+
+ return status;
+}
diff --git a/graphics/allocator/2.0/vts/types.vts b/graphics/allocator/2.0/vts/types.vts
new file mode 100644
index 0000000..ac1bf3f
--- /dev/null
+++ b/graphics/allocator/2.0/vts/types.vts
@@ -0,0 +1,231 @@
+component_class: HAL_HIDL
+component_type_version: 2.0
+component_name: "types"
+
+package: "android.hardware.graphics.allocator"
+
+
+attribute: {
+ name: "::android::hardware::graphics::allocator::V2_0::Error"
+ type: TYPE_ENUM
+ enum_value: {
+ scalar_type: "int32_t"
+
+ enumerator: "NONE"
+ scalar_value: {
+ int32_t: 0
+ }
+ enumerator: "BAD_DESCRIPTOR"
+ scalar_value: {
+ int32_t: 1
+ }
+ enumerator: "BAD_BUFFER"
+ scalar_value: {
+ int32_t: 2
+ }
+ enumerator: "BAD_VALUE"
+ scalar_value: {
+ int32_t: 3
+ }
+ enumerator: "NOT_SHARED"
+ scalar_value: {
+ int32_t: 4
+ }
+ enumerator: "NO_RESOURCES"
+ scalar_value: {
+ int32_t: 5
+ }
+ enumerator: "UNDEFINED"
+ scalar_value: {
+ int32_t: 6
+ }
+ enumerator: "UNSUPPORTED"
+ scalar_value: {
+ int32_t: 7
+ }
+ }
+}
+
+attribute: {
+ name: "::android::hardware::graphics::allocator::V2_0::ProducerUsage"
+ type: TYPE_ENUM
+ enum_value: {
+ scalar_type: "uint64_t"
+
+ enumerator: "CPU_READ"
+ scalar_value: {
+ uint64_t: 2
+ }
+ enumerator: "CPU_READ_OFTEN"
+ scalar_value: {
+ uint64_t: 4
+ }
+ enumerator: "CPU_WRITE"
+ scalar_value: {
+ uint64_t: 32
+ }
+ enumerator: "CPU_WRITE_OFTEN"
+ scalar_value: {
+ uint64_t: 64
+ }
+ enumerator: "GPU_RENDER_TARGET"
+ scalar_value: {
+ uint64_t: 512
+ }
+ enumerator: "PROTECTED"
+ scalar_value: {
+ uint64_t: 16384
+ }
+ enumerator: "CAMERA"
+ scalar_value: {
+ uint64_t: 131072
+ }
+ enumerator: "VIDEO_DECODER"
+ scalar_value: {
+ uint64_t: 4194304
+ }
+ }
+}
+
+attribute: {
+ name: "::android::hardware::graphics::allocator::V2_0::ConsumerUsage"
+ type: TYPE_ENUM
+ enum_value: {
+ scalar_type: "uint64_t"
+
+ enumerator: "CPU_READ"
+ scalar_value: {
+ uint64_t: 2
+ }
+ enumerator: "CPU_READ_OFTEN"
+ scalar_value: {
+ uint64_t: 4
+ }
+ enumerator: "GPU_TEXTURE"
+ scalar_value: {
+ uint64_t: 256
+ }
+ enumerator: "HWCOMPOSER"
+ scalar_value: {
+ uint64_t: 2048
+ }
+ enumerator: "CLIENT_TARGET"
+ scalar_value: {
+ uint64_t: 4096
+ }
+ enumerator: "CURSOR"
+ scalar_value: {
+ uint64_t: 32768
+ }
+ enumerator: "VIDEO_ENCODER"
+ scalar_value: {
+ uint64_t: 65536
+ }
+ enumerator: "CAMERA"
+ scalar_value: {
+ uint64_t: 262144
+ }
+ enumerator: "RENDERSCRIPT"
+ scalar_value: {
+ uint64_t: 1048576
+ }
+ }
+}
+
+attribute: {
+ name: "::android::hardware::graphics::allocator::V2_0::PixelFormat"
+ type: TYPE_ENUM
+ enum_value: {
+ scalar_type: "int32_t"
+
+ enumerator: "RGBA_8888"
+ scalar_value: {
+ int32_t: 1
+ }
+ enumerator: "RGBX_8888"
+ scalar_value: {
+ int32_t: 2
+ }
+ enumerator: "RGB_888"
+ scalar_value: {
+ int32_t: 3
+ }
+ enumerator: "RGB_565"
+ scalar_value: {
+ int32_t: 4
+ }
+ enumerator: "BGRA_8888"
+ scalar_value: {
+ int32_t: 5
+ }
+ enumerator: "YV12"
+ scalar_value: {
+ int32_t: 842094169
+ }
+ enumerator: "Y8"
+ scalar_value: {
+ int32_t: 538982489
+ }
+ enumerator: "Y16"
+ scalar_value: {
+ int32_t: 540422489
+ }
+ enumerator: "RAW16"
+ scalar_value: {
+ int32_t: 32
+ }
+ enumerator: "RAW10"
+ scalar_value: {
+ int32_t: 37
+ }
+ enumerator: "RAW12"
+ scalar_value: {
+ int32_t: 38
+ }
+ enumerator: "RAW_OPAQUE"
+ scalar_value: {
+ int32_t: 36
+ }
+ enumerator: "BLOB"
+ scalar_value: {
+ int32_t: 33
+ }
+ enumerator: "IMPLEMENTATION_DEFINED"
+ scalar_value: {
+ int32_t: 34
+ }
+ enumerator: "YCbCr_420_888"
+ scalar_value: {
+ int32_t: 35
+ }
+ enumerator: "YCbCr_422_888"
+ scalar_value: {
+ int32_t: 39
+ }
+ enumerator: "YCbCr_444_888"
+ scalar_value: {
+ int32_t: 40
+ }
+ enumerator: "FLEX_RGB_888"
+ scalar_value: {
+ int32_t: 41
+ }
+ enumerator: "FLEX_RGBA_8888"
+ scalar_value: {
+ int32_t: 42
+ }
+ enumerator: "YCbCr_422_SP"
+ scalar_value: {
+ int32_t: 16
+ }
+ enumerator: "YCrCb_420_SP"
+ scalar_value: {
+ int32_t: 17
+ }
+ enumerator: "YCbCr_422_I"
+ scalar_value: {
+ int32_t: 20
+ }
+ }
+}
+
diff --git a/graphics/composer/2.1/default/Hwc.cpp b/graphics/composer/2.1/default/Hwc.cpp
index 7fa5119..36c6e54 100644
--- a/graphics/composer/2.1/default/Hwc.cpp
+++ b/graphics/composer/2.1/default/Hwc.cpp
@@ -318,15 +318,15 @@
presentDisplay_cb hidl_cb) override;
Return<Error> setActiveConfig(Display display, Config config) override;
Return<Error> setClientTarget(Display display,
- const native_handle_t* target,
- const native_handle_t* acquireFence,
+ const hidl_handle& target,
+ const hidl_handle& acquireFence,
Dataspace dataspace, const hidl_vec<Rect>& damage) override;
Return<Error> setColorMode(Display display, ColorMode mode) override;
Return<Error> setColorTransform(Display display,
const hidl_vec<float>& matrix, ColorTransform hint) override;
Return<Error> setOutputBuffer(Display display,
- const native_handle_t* buffer,
- const native_handle_t* releaseFence) override;
+ const hidl_handle& buffer,
+ const hidl_handle& releaseFence) override;
Return<Error> setPowerMode(Display display, PowerMode mode) override;
Return<Error> setVsyncEnabled(Display display, Vsync enabled) override;
Return<void> validateDisplay(Display display,
@@ -334,8 +334,8 @@
Return<Error> setCursorPosition(Display display,
Layer layer, int32_t x, int32_t y) override;
Return<Error> setLayerBuffer(Display display,
- Layer layer, const native_handle_t* buffer,
- const native_handle_t* acquireFence) override;
+ Layer layer, const hidl_handle& buffer,
+ const hidl_handle& acquireFence) override;
Return<Error> setLayerSurfaceDamage(Display display,
Layer layer, const hidl_vec<Rect>& damage) override;
Return<Error> setLayerBlendMode(Display display,
@@ -351,7 +351,7 @@
Return<Error> setLayerPlaneAlpha(Display display,
Layer layer, float alpha) override;
Return<Error> setLayerSidebandStream(Display display,
- Layer layer, const native_handle_t* stream) override;
+ Layer layer, const hidl_handle& stream) override;
Return<Error> setLayerSourceCrop(Display display,
Layer layer, const FRect& crop) override;
Return<Error> setLayerTransform(Display display,
@@ -1027,17 +1027,18 @@
}
Return<Error> HwcHal::setClientTarget(Display display,
- const native_handle_t* target,
- const native_handle_t* acquireFence,
+ const hidl_handle& target,
+ const hidl_handle& acquireFence,
Dataspace dataspace, const hidl_vec<Rect>& damage)
{
- if (!sHandleImporter.importBuffer(target)) {
+ const native_handle_t* targetHandle = target.getNativeHandle();
+ if (!sHandleImporter.importBuffer(targetHandle)) {
return Error::NO_RESOURCES;
}
int32_t fence;
if (!sHandleImporter.importFence(acquireFence, fence)) {
- sHandleImporter.freeBuffer(target);
+ sHandleImporter.freeBuffer(targetHandle);
return Error::NO_RESOURCES;
}
@@ -1045,13 +1046,13 @@
reinterpret_cast<const hwc_rect_t*>(&damage[0]) };
int32_t error = mDispatch.setClientTarget(mDevice, display,
- target, fence, static_cast<int32_t>(dataspace),
+ targetHandle, fence, static_cast<int32_t>(dataspace),
damage_region);
if (error == HWC2_ERROR_NONE) {
std::lock_guard<std::mutex> lock(mDisplayMutex);
auto dpy = mDisplays.find(display);
- dpy->second.ClientTarget = target;
+ dpy->second.ClientTarget = targetHandle;
} else {
sHandleImporter.freeBuffer(target);
sHandleImporter.closeFence(fence);
@@ -1076,28 +1077,29 @@
}
Return<Error> HwcHal::setOutputBuffer(Display display,
- const native_handle_t* buffer,
- const native_handle_t* releaseFence)
+ const hidl_handle& buffer,
+ const hidl_handle& releaseFence)
{
- if (!sHandleImporter.importBuffer(buffer)) {
+ const native_handle_t* bufferHandle = buffer.getNativeHandle();
+ if (!sHandleImporter.importBuffer(bufferHandle)) {
return Error::NO_RESOURCES;
}
int32_t fence;
if (!sHandleImporter.importFence(releaseFence, fence)) {
- sHandleImporter.freeBuffer(buffer);
+ sHandleImporter.freeBuffer(bufferHandle);
return Error::NO_RESOURCES;
}
int32_t error = mDispatch.setOutputBuffer(mDevice,
- display, buffer, fence);
+ display, bufferHandle, fence);
if (error == HWC2_ERROR_NONE) {
std::lock_guard<std::mutex> lock(mDisplayMutex);
auto dpy = mDisplays.find(display);
- dpy->second.OutputBuffer = buffer;
+ dpy->second.OutputBuffer = bufferHandle;
} else {
- sHandleImporter.freeBuffer(buffer);
+ sHandleImporter.freeBuffer(bufferHandle);
}
// unlike in setClientTarget, fence is owned by us and is always closed
@@ -1142,28 +1144,29 @@
}
Return<Error> HwcHal::setLayerBuffer(Display display,
- Layer layer, const native_handle_t* buffer,
- const native_handle_t* acquireFence)
+ Layer layer, const hidl_handle& buffer,
+ const hidl_handle& acquireFence)
{
- if (!sHandleImporter.importBuffer(buffer)) {
+ const native_handle_t* bufferHandle = buffer.getNativeHandle();
+ if (!sHandleImporter.importBuffer(bufferHandle)) {
return Error::NO_RESOURCES;
}
int32_t fence;
if (!sHandleImporter.importFence(acquireFence, fence)) {
- sHandleImporter.freeBuffer(buffer);
+ sHandleImporter.freeBuffer(bufferHandle);
return Error::NO_RESOURCES;
}
int32_t error = mDispatch.setLayerBuffer(mDevice,
- display, layer, buffer, fence);
+ display, layer, bufferHandle, fence);
if (error == HWC2_ERROR_NONE) {
std::lock_guard<std::mutex> lock(mDisplayMutex);
auto dpy = mDisplays.find(display);
- dpy->second.LayerBuffers[layer] = buffer;
+ dpy->second.LayerBuffers[layer] = bufferHandle;
} else {
- sHandleImporter.freeBuffer(buffer);
+ sHandleImporter.freeBuffer(bufferHandle);
sHandleImporter.closeFence(fence);
}
@@ -1230,21 +1233,22 @@
}
Return<Error> HwcHal::setLayerSidebandStream(Display display,
- Layer layer, const native_handle_t* stream)
+ Layer layer, const hidl_handle& stream)
{
- if (!sHandleImporter.importBuffer(stream)) {
+ const native_handle_t* streamHandle = stream.getNativeHandle();
+ if (!sHandleImporter.importBuffer(streamHandle)) {
return Error::NO_RESOURCES;
}
int32_t error = mDispatch.setLayerSidebandStream(mDevice,
- display, layer, stream);
+ display, layer, streamHandle);
if (error == HWC2_ERROR_NONE) {
std::lock_guard<std::mutex> lock(mDisplayMutex);
auto dpy = mDisplays.find(display);
- dpy->second.LayerSidebandStreams[layer] = stream;
+ dpy->second.LayerSidebandStreams[layer] = streamHandle;
} else {
- sHandleImporter.freeBuffer(stream);
+ sHandleImporter.freeBuffer(streamHandle);
}
return static_cast<Error>(error);
diff --git a/nfc/1.0/INfc.hal b/nfc/1.0/INfc.hal
index f003b2c..1c952db 100644
--- a/nfc/1.0/INfc.hal
+++ b/nfc/1.0/INfc.hal
@@ -33,6 +33,8 @@
* If open() returns any other value, the NCI stack will stop.
*
*/
+ @entry
+ @callflow(next={"write", "coreInitialized", "prediscover", "powerCycle", "controlGranted"})
open(INfcClientCallback clientCallback) generates (int32_t retval);
/*
@@ -41,6 +43,8 @@
* This method may queue writes and return immediately. The only
* requirement is that the writes are executed in order.
*/
+ @callflow(next={"write", "prediscover", "coreInitialized", "close", "powerCycle",
+ "controlGranted"})
write(NfcData data) generates (int32_t retval);
/*
@@ -53,6 +57,7 @@
* If coreInitialized() returns any other value, the NCI stack will continue
* immediately.
*/
+ @callflow(next={"write", "prediscover", "close"})
coreInitialized(NfcData data) generates (int32_t retval);
/*
@@ -66,11 +71,13 @@
* If prediscover() returns any other value, the NCI stack will start
* RF discovery immediately.
*/
+ @callflow(next={"write", "close", "coreInitialized", "powerCycle", "controlGranted"})
prediscover() generates (int32_t retval);
/*
* Close the NFC controller. Should free all resources.
*/
+ @exit
close() generates (int32_t retval);
/*
@@ -79,11 +86,13 @@
* Must only be called when there are no NCI commands pending.
* NfcEvent.RELEASE_CONTROL will notify when HAL no longer needs exclusive control.
*/
+ @callflow(next={"write", "close", "prediscover", "coreInitialized", "powerCycle"})
controlGranted() generates (int32_t retval);
/*
* Restart controller by power cyle;
* NfcEvent.OPEN_CPLT will notify when operation is complete.
*/
+ @callflow(next={"write", "coreInitialized", "prediscover", "controlGranted", "close"})
powerCycle() generates (int32_t retval);
};
diff --git a/tests/bar/1.0/default/Bar.cpp b/tests/bar/1.0/default/Bar.cpp
index 2158cd8..c07e2fa 100644
--- a/tests/bar/1.0/default/Bar.cpp
+++ b/tests/bar/1.0/default/Bar.cpp
@@ -153,8 +153,8 @@
return Void();
}
-Return<void> Bar::expectNullHandle(const native_handle_t* h, const Abc& xyz, expectNullHandle_cb _hidl_cb) {
- ALOGI("SERVER(Bar) h = %p, xyz.z = %p", h, static_cast<void*>(xyz.z));
+Return<void> Bar::expectNullHandle(const hidl_handle& h, const Abc& xyz, expectNullHandle_cb _hidl_cb) {
+ ALOGI("SERVER(Bar) h = %p, xyz.z = %p", h.getNativeHandle(), xyz.z.getNativeHandle());
_hidl_cb(h == nullptr, xyz.z == nullptr);
return Void();
}
diff --git a/tests/bar/1.0/default/Bar.h b/tests/bar/1.0/default/Bar.h
index 4e22b61..29eedec 100644
--- a/tests/bar/1.0/default/Bar.h
+++ b/tests/bar/1.0/default/Bar.h
@@ -64,7 +64,7 @@
// Methods from ::android::hardware::tests::bar::V1_0::IBar follow.
Return<void> thisIsNew() override;
- Return<void> expectNullHandle(const native_handle_t* h, const Abc& xyz, expectNullHandle_cb _hidl_cb) override;
+ Return<void> expectNullHandle(const hidl_handle& h, const Abc& xyz, expectNullHandle_cb _hidl_cb) override;
private:
sp<IFoo> mFoo;
diff --git a/tests/foo/1.0/default/Foo.cpp b/tests/foo/1.0/default/Foo.cpp
index f7cc7c0..a1df3b2 100644
--- a/tests/foo/1.0/default/Foo.cpp
+++ b/tests/foo/1.0/default/Foo.cpp
@@ -309,7 +309,7 @@
}
Return<void> Foo::createHandles(uint32_t size, createHandles_cb _hidl_cb) {
- hidl_vec<const native_handle_t*> handles;
+ hidl_vec<hidl_handle> handles;
handles.resize(size);
for(uint32_t i = 0; i < size; ++i) {
createMyHandle([&](const MyHandle& h) {
diff --git a/wifi/1.0/default/wifi_legacy_hal.cpp b/wifi/1.0/default/wifi_legacy_hal.cpp
index 28b7f9a..15b6bfc 100644
--- a/wifi/1.0/default/wifi_legacy_hal.cpp
+++ b/wifi/1.0/default/wifi_legacy_hal.cpp
@@ -28,8 +28,14 @@
namespace V1_0 {
namespace implementation {
namespace legacy_hal {
-// Constants used in the class.
+// Constants ported over from the legacy HAL calling code
+// (com_android_server_wifi_WifiNative.cpp). This will all be thrown
+// away when this shim layer is replaced by the real vendor
+// implementation.
static constexpr uint32_t kMaxVersionStringLength = 256;
+static constexpr uint32_t kMaxCachedGscanResults = 64;
+static constexpr uint32_t kMaxGscanFrequenciesForBand = 64;
+static constexpr uint32_t kLinkLayerStatsDataMpduSizeThreshold = 128;
// Legacy HAL functions accept "C" style function pointers, so use global
// functions to pass to the legacy HAL function and store the corresponding
@@ -57,6 +63,40 @@
on_firmware_memory_dump_internal_callback(buffer, buffer_size);
}
}
+
+// Callback to be invoked for Gscan events.
+std::function<void(wifi_request_id, wifi_scan_event)>
+ on_gscan_event_internal_callback;
+void onGscanEvent(wifi_request_id id, wifi_scan_event event) {
+ if (on_gscan_event_internal_callback) {
+ on_gscan_event_internal_callback(id, event);
+ }
+}
+
+// Callback to be invoked for Gscan full results.
+std::function<void(wifi_request_id, wifi_scan_result*, uint32_t)>
+ on_gscan_full_result_internal_callback;
+void onGscanFullResult(wifi_request_id id,
+ wifi_scan_result* result,
+ uint32_t buckets_scanned) {
+ if (on_gscan_full_result_internal_callback) {
+ on_gscan_full_result_internal_callback(id, result, buckets_scanned);
+ }
+}
+
+// Callback to be invoked for link layer stats results.
+std::function<void((wifi_request_id, wifi_iface_stat*, int, wifi_radio_stat*))>
+ on_link_layer_stats_result_internal_callback;
+void onLinkLayerStatsDataResult(wifi_request_id id,
+ wifi_iface_stat* iface_stat,
+ int num_radios,
+ wifi_radio_stat* radio_stat) {
+ if (on_link_layer_stats_result_internal_callback) {
+ on_link_layer_stats_result_internal_callback(
+ id, iface_stat, num_radios, radio_stat);
+ }
+}
+
// End of the free-standing "C" style callbacks.
WifiLegacyHal::WifiLegacyHal()
@@ -206,6 +246,162 @@
wlan_interface_handle_, program.data(), program.size());
}
+std::pair<wifi_error, wifi_gscan_capabilities>
+WifiLegacyHal::getGscanCapabilities() {
+ wifi_gscan_capabilities caps;
+ wifi_error status = global_func_table_.wifi_get_gscan_capabilities(
+ wlan_interface_handle_, &caps);
+ return {status, caps};
+}
+
+wifi_error WifiLegacyHal::startGscan(
+ wifi_request_id id,
+ const wifi_scan_cmd_params& params,
+ const std::function<void(wifi_request_id)>& on_failure_user_callback,
+ const on_gscan_results_callback& on_results_user_callback,
+ const on_gscan_full_result_callback& on_full_result_user_callback) {
+ // If there is already an ongoing background scan, reject new scan requests.
+ if (on_gscan_event_internal_callback ||
+ on_gscan_full_result_internal_callback) {
+ return WIFI_ERROR_NOT_AVAILABLE;
+ }
+
+ // This callback will be used to either trigger |on_results_user_callback| or
+ // |on_failure_user_callback|.
+ on_gscan_event_internal_callback =
+ [on_failure_user_callback, on_results_user_callback, this](
+ wifi_request_id id, wifi_scan_event event) {
+ switch (event) {
+ case WIFI_SCAN_RESULTS_AVAILABLE:
+ case WIFI_SCAN_THRESHOLD_NUM_SCANS:
+ case WIFI_SCAN_THRESHOLD_PERCENT: {
+ wifi_error status;
+ std::vector<wifi_cached_scan_results> cached_scan_results;
+ std::tie(status, cached_scan_results) = getGscanCachedResults();
+ if (status == WIFI_SUCCESS) {
+ on_results_user_callback(id, cached_scan_results);
+ return;
+ }
+ }
+ // Fall through if failed. Failure to retrieve cached scan results
+ // should trigger a background scan failure.
+ case WIFI_SCAN_FAILED:
+ on_failure_user_callback(id);
+ on_gscan_event_internal_callback = nullptr;
+ on_gscan_full_result_internal_callback = nullptr;
+ return;
+ }
+ LOG(FATAL) << "Unexpected gscan event received: " << event;
+ };
+
+ on_gscan_full_result_internal_callback = [on_full_result_user_callback](
+ wifi_request_id id, wifi_scan_result* result, uint32_t buckets_scanned) {
+ if (result) {
+ on_full_result_user_callback(id, result, buckets_scanned);
+ }
+ };
+
+ wifi_scan_result_handler handler = {onGscanFullResult, onGscanEvent};
+ wifi_error status = global_func_table_.wifi_start_gscan(
+ id, wlan_interface_handle_, params, handler);
+ if (status != WIFI_SUCCESS) {
+ on_gscan_event_internal_callback = nullptr;
+ on_gscan_full_result_internal_callback = nullptr;
+ }
+ return status;
+}
+
+wifi_error WifiLegacyHal::stopGscan(wifi_request_id id) {
+ // If there is no an ongoing background scan, reject stop requests.
+ // TODO(b/32337212): This needs to be handled by the HIDL object because we
+ // need to return the NOT_STARTED error code.
+ if (!on_gscan_event_internal_callback &&
+ !on_gscan_full_result_internal_callback) {
+ return WIFI_ERROR_NOT_AVAILABLE;
+ }
+ wifi_error status =
+ global_func_table_.wifi_stop_gscan(id, wlan_interface_handle_);
+ // If the request Id is wrong, don't stop the ongoing background scan. Any
+ // other error should be treated as the end of background scan.
+ if (status != WIFI_ERROR_INVALID_REQUEST_ID) {
+ on_gscan_event_internal_callback = nullptr;
+ on_gscan_full_result_internal_callback = nullptr;
+ }
+ return status;
+}
+
+std::pair<wifi_error, std::vector<uint32_t>>
+WifiLegacyHal::getValidFrequenciesForGscan(wifi_band band) {
+ static_assert(sizeof(uint32_t) >= sizeof(wifi_channel),
+ "Wifi Channel cannot be represented in output");
+ std::vector<uint32_t> freqs;
+ freqs.resize(kMaxGscanFrequenciesForBand);
+ int32_t num_freqs = 0;
+ wifi_error status = global_func_table_.wifi_get_valid_channels(
+ wlan_interface_handle_,
+ band,
+ freqs.size(),
+ reinterpret_cast<wifi_channel*>(freqs.data()),
+ &num_freqs);
+ CHECK(num_freqs >= 0 &&
+ static_cast<uint32_t>(num_freqs) <= kMaxGscanFrequenciesForBand);
+ freqs.resize(num_freqs);
+ return {status, std::move(freqs)};
+}
+
+wifi_error WifiLegacyHal::enableLinkLayerStats(bool debug) {
+ wifi_link_layer_params params;
+ params.mpdu_size_threshold = kLinkLayerStatsDataMpduSizeThreshold;
+ params.aggressive_statistics_gathering = debug;
+ return global_func_table_.wifi_set_link_stats(wlan_interface_handle_, params);
+}
+
+wifi_error WifiLegacyHal::disableLinkLayerStats() {
+ // TODO: Do we care about these responses?
+ uint32_t clear_mask_rsp;
+ uint8_t stop_rsp;
+ return global_func_table_.wifi_clear_link_stats(
+ wlan_interface_handle_, 0xFFFFFFFF, &clear_mask_rsp, 1, &stop_rsp);
+}
+
+std::pair<wifi_error, LinkLayerStats> WifiLegacyHal::getLinkLayerStats() {
+ LinkLayerStats link_stats{};
+ LinkLayerStats* link_stats_ptr = &link_stats;
+
+ on_link_layer_stats_result_internal_callback = [&link_stats_ptr](
+ wifi_request_id /* id */,
+ wifi_iface_stat* iface_stats_ptr,
+ int num_radios,
+ wifi_radio_stat* radio_stats_ptr) {
+ if (iface_stats_ptr != nullptr) {
+ link_stats_ptr->iface = *iface_stats_ptr;
+ link_stats_ptr->iface.num_peers = 0;
+ } else {
+ LOG(ERROR) << "Invalid iface stats in link layer stats";
+ }
+ if (num_radios == 1 && radio_stats_ptr != nullptr) {
+ link_stats_ptr->radio = *radio_stats_ptr;
+ // Copy over the tx level array to the separate vector.
+ if (radio_stats_ptr->num_tx_levels > 0 &&
+ radio_stats_ptr->tx_time_per_levels != nullptr) {
+ link_stats_ptr->radio_tx_time_per_levels.assign(
+ radio_stats_ptr->tx_time_per_levels,
+ radio_stats_ptr->tx_time_per_levels +
+ radio_stats_ptr->num_tx_levels);
+ }
+ link_stats_ptr->radio.num_tx_levels = 0;
+ link_stats_ptr->radio.tx_time_per_levels = nullptr;
+ } else {
+ LOG(ERROR) << "Invalid radio stats in link layer stats";
+ }
+ };
+
+ wifi_error status = global_func_table_.wifi_get_link_stats(
+ 0, wlan_interface_handle_, {onLinkLayerStatsDataResult});
+ on_link_layer_stats_result_internal_callback = nullptr;
+ return {status, link_stats};
+}
+
wifi_error WifiLegacyHal::retrieveWlanInterfaceHandle() {
const std::string& ifname_to_find = getStaIfaceName();
wifi_interface_handle* iface_handles = nullptr;
@@ -245,12 +441,44 @@
if_tool.SetWifiUpState(false);
}
+std::pair<wifi_error, std::vector<wifi_cached_scan_results>>
+WifiLegacyHal::getGscanCachedResults() {
+ std::vector<wifi_cached_scan_results> cached_scan_results;
+ cached_scan_results.resize(kMaxCachedGscanResults);
+ int32_t num_results = 0;
+ wifi_error status = global_func_table_.wifi_get_cached_gscan_results(
+ wlan_interface_handle_,
+ true /* always flush */,
+ cached_scan_results.size(),
+ cached_scan_results.data(),
+ &num_results);
+ CHECK(num_results >= 0 &&
+ static_cast<uint32_t>(num_results) <= kMaxCachedGscanResults);
+ cached_scan_results.resize(num_results);
+ // Check for invalid IE lengths in these cached scan results and correct it.
+ for (auto& cached_scan_result : cached_scan_results) {
+ int num_scan_results = cached_scan_result.num_results;
+ for (int i = 0; i < num_scan_results; i++) {
+ auto& scan_result = cached_scan_result.results[i];
+ if (scan_result.ie_length > 0) {
+ LOG(ERROR) << "Cached scan result has non-zero IE length "
+ << scan_result.ie_length;
+ scan_result.ie_length = 0;
+ }
+ }
+ }
+ return {status, std::move(cached_scan_results)};
+}
+
void WifiLegacyHal::invalidate() {
global_handle_ = nullptr;
wlan_interface_handle_ = nullptr;
on_stop_complete_internal_callback = nullptr;
on_driver_memory_dump_internal_callback = nullptr;
on_firmware_memory_dump_internal_callback = nullptr;
+ on_gscan_event_internal_callback = nullptr;
+ on_gscan_full_result_internal_callback = nullptr;
+ on_link_layer_stats_result_internal_callback = nullptr;
}
} // namespace legacy_hal
diff --git a/wifi/1.0/default/wifi_legacy_hal.h b/wifi/1.0/default/wifi_legacy_hal.h
index 8bd146a..df1c3d6 100644
--- a/wifi/1.0/default/wifi_legacy_hal.h
+++ b/wifi/1.0/default/wifi_legacy_hal.h
@@ -39,6 +39,31 @@
uint32_t max_len;
};
+// WARNING: We don't care about the variable sized members of either
+// |wifi_iface_stat|, |wifi_radio_stat| structures. So, using the pragma
+// to escape the compiler warnings regarding this.
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wgnu-variable-sized-type-not-at-end"
+// The |wifi_radio_stat.tx_time_per_levels| stats is provided as a pointer in
+// |wifi_radio_stat| structure in the legacy HAL API. Separate that out
+// into a separate return element to avoid passing pointers around.
+struct LinkLayerStats {
+ wifi_iface_stat iface;
+ wifi_radio_stat radio;
+ std::vector<uint32_t> radio_tx_time_per_levels;
+};
+#pragma GCC diagnostic pop
+
+// Full scan results contain IE info and are hence passed by reference, to
+// preserve the variable length array member |ie_data|. Callee must not retain
+// the pointer.
+using on_gscan_full_result_callback =
+ std::function<void(wifi_request_id, const wifi_scan_result*, uint32_t)>;
+// These scan results don't contain any IE info, so no need to pass by
+// reference.
+using on_gscan_results_callback = std::function<void(
+ wifi_request_id, const std::vector<wifi_cached_scan_results>&)>;
+
/**
* Class that encapsulates all legacy HAL interactions.
* This class manages the lifetime of the event loop thread used by legacy HAL.
@@ -65,12 +90,41 @@
// APF functions.
std::pair<wifi_error, PacketFilterCapabilities> getPacketFilterCapabilities();
wifi_error setPacketFilter(const std::vector<uint8_t>& program);
+ // Gscan functions.
+ std::pair<wifi_error, wifi_gscan_capabilities> getGscanCapabilities();
+ // These API's provides a simplified interface over the legacy Gscan API's:
+ // a) All scan events from the legacy HAL API other than the
+ // |WIFI_SCAN_FAILED| are treated as notification of results.
+ // This method then retrieves the cached scan results from the legacy
+ // HAL API and triggers the externally provided |on_results_user_callback|
+ // on success.
+ // b) |WIFI_SCAN_FAILED| scan event or failure to retrieve cached scan results
+ // triggers the externally provided |on_failure_user_callback|.
+ // c) Full scan result event triggers the externally provided
+ // |on_full_result_user_callback|.
+ wifi_error startGscan(
+ wifi_request_id id,
+ const wifi_scan_cmd_params& params,
+ const std::function<void(wifi_request_id)>& on_failure_callback,
+ const on_gscan_results_callback& on_results_callback,
+ const on_gscan_full_result_callback& on_full_result_callback);
+ wifi_error stopGscan(wifi_request_id id);
+ std::pair<wifi_error, std::vector<uint32_t>> getValidFrequenciesForGscan(
+ wifi_band band);
+ // Link layer stats functions.
+ wifi_error enableLinkLayerStats(bool debug);
+ wifi_error disableLinkLayerStats();
+ std::pair<wifi_error, LinkLayerStats> getLinkLayerStats();
private:
// Retrieve the interface handle to be used for the "wlan" interface.
wifi_error retrieveWlanInterfaceHandle();
// Run the legacy HAL event loop thread.
void runEventLoop();
+ // Retrieve the cached gscan results to pass the results back to the external
+ // callbacks.
+ std::pair<wifi_error, std::vector<wifi_cached_scan_results>>
+ getGscanCachedResults();
void invalidate();
// Event loop thread used by legacy HAL.