Merge "Set the property ID before writing freeze frames"
diff --git a/audio/2.0/Android.mk b/audio/2.0/Android.mk
index e989364..d5e840f 100644
--- a/audio/2.0/Android.mk
+++ b/audio/2.0/Android.mk
@@ -5,7 +5,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.audio@2.0-java-constants
+LOCAL_MODULE := android.hardware.audio-V2.0-java-constants
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
diff --git a/audio/2.0/default/Android.mk b/audio/2.0/default/Android.mk
index 93f7ad0..621853c 100644
--- a/audio/2.0/default/Android.mk
+++ b/audio/2.0/default/Android.mk
@@ -43,6 +43,12 @@
android.hardware.audio.common@2.0 \
android.hardware.audio.common@2.0-util \
+LOCAL_HEADER_LIBRARIES := \
+ libaudioclient_headers \
+ libaudio_system_headers \
+ libhardware_headers \
+ libmedia_headers \
+
LOCAL_WHOLE_STATIC_LIBRARIES := libmedia_helper
include $(BUILD_SHARED_LIBRARY)
diff --git a/audio/2.0/default/StreamIn.cpp b/audio/2.0/default/StreamIn.cpp
index 2745607..e5a1a55 100644
--- a/audio/2.0/default/StreamIn.cpp
+++ b/audio/2.0/default/StreamIn.cpp
@@ -20,6 +20,7 @@
#include <android/log.h>
#include <hardware/audio.h>
+#include <memory>
#include <utils/Trace.h>
#include "StreamIn.h"
@@ -52,7 +53,11 @@
mDataMQ(dataMQ),
mStatusMQ(statusMQ),
mEfGroup(efGroup),
- mBuffer(new uint8_t[dataMQ->getQuantumCount()]) {
+ mBuffer(nullptr) {
+ }
+ bool init() {
+ mBuffer.reset(new(std::nothrow) uint8_t[mDataMQ->getQuantumCount()]);
+ return mBuffer != nullptr;
}
virtual ~ReadThread() {}
@@ -308,8 +313,14 @@
return Void();
}
std::unique_ptr<CommandMQ> tempCommandMQ(new CommandMQ(1));
- std::unique_ptr<DataMQ> tempDataMQ(
- new DataMQ(frameSize * framesCount, true /* EventFlag */));
+ if (frameSize > std::numeric_limits<size_t>::max() / framesCount) {
+ ALOGE("Requested buffer is too big, %d*%d can not fit in size_t", frameSize, framesCount);
+ _hidl_cb(Result::INVALID_ARGUMENTS,
+ CommandMQ::Descriptor(), DataMQ::Descriptor(), StatusMQ::Descriptor(), threadInfo);
+ return Void();
+ }
+ std::unique_ptr<DataMQ> tempDataMQ(new DataMQ(frameSize * framesCount, true /* EventFlag */));
+
std::unique_ptr<StatusMQ> tempStatusMQ(new StatusMQ(1));
if (!tempCommandMQ->isValid() || !tempDataMQ->isValid() || !tempStatusMQ->isValid()) {
ALOGE_IF(!tempCommandMQ->isValid(), "command MQ is invalid");
@@ -319,8 +330,11 @@
CommandMQ::Descriptor(), DataMQ::Descriptor(), StatusMQ::Descriptor(), threadInfo);
return Void();
}
- status = EventFlag::createEventFlag(tempDataMQ->getEventFlagWord(), &mEfGroup);
- if (status != OK || !mEfGroup) {
+ EventFlag* tempRawEfGroup{};
+ status = EventFlag::createEventFlag(tempDataMQ->getEventFlagWord(), &tempRawEfGroup);
+ std::unique_ptr<EventFlag, void(*)(EventFlag*)> tempElfGroup(tempRawEfGroup, [](auto *ef) {
+ EventFlag::deleteEventFlag(&ef); });
+ if (status != OK || !tempElfGroup) {
ALOGE("failed creating event flag for data MQ: %s", strerror(-status));
_hidl_cb(Result::INVALID_ARGUMENTS,
CommandMQ::Descriptor(), DataMQ::Descriptor(), StatusMQ::Descriptor(), threadInfo);
@@ -328,14 +342,19 @@
}
// Create and launch the thread.
- mReadThread = new ReadThread(
+ auto tempReadThread = std::make_unique<ReadThread>(
&mStopReadThread,
mStream,
tempCommandMQ.get(),
tempDataMQ.get(),
tempStatusMQ.get(),
- mEfGroup);
- status = mReadThread->run("reader", PRIORITY_URGENT_AUDIO);
+ tempElfGroup.get());
+ if (!tempReadThread->init()) {
+ _hidl_cb(Result::INVALID_ARGUMENTS,
+ CommandMQ::Descriptor(), DataMQ::Descriptor(), StatusMQ::Descriptor(), threadInfo);
+ return Void();
+ }
+ status = tempReadThread->run("reader", PRIORITY_URGENT_AUDIO);
if (status != OK) {
ALOGW("failed to start reader thread: %s", strerror(-status));
_hidl_cb(Result::INVALID_ARGUMENTS,
@@ -346,6 +365,8 @@
mCommandMQ = std::move(tempCommandMQ);
mDataMQ = std::move(tempDataMQ);
mStatusMQ = std::move(tempStatusMQ);
+ mReadThread = tempReadThread.release();
+ mEfGroup = tempElfGroup.release();
threadInfo.pid = getpid();
threadInfo.tid = mReadThread->getTid();
_hidl_cb(Result::OK,
diff --git a/audio/2.0/default/StreamOut.cpp b/audio/2.0/default/StreamOut.cpp
index 88045a0..3339b63 100644
--- a/audio/2.0/default/StreamOut.cpp
+++ b/audio/2.0/default/StreamOut.cpp
@@ -18,6 +18,8 @@
//#define LOG_NDEBUG 0
#define ATRACE_TAG ATRACE_TAG_AUDIO
+#include <memory>
+
#include <android/log.h>
#include <hardware/audio.h>
#include <utils/Trace.h>
@@ -50,7 +52,11 @@
mDataMQ(dataMQ),
mStatusMQ(statusMQ),
mEfGroup(efGroup),
- mBuffer(new uint8_t[dataMQ->getQuantumCount()]) {
+ mBuffer(nullptr) {
+ }
+ bool init() {
+ mBuffer.reset(new(std::nothrow) uint8_t[mDataMQ->getQuantumCount()]);
+ return mBuffer != nullptr;
}
virtual ~WriteThread() {}
@@ -291,8 +297,15 @@
return Void();
}
std::unique_ptr<CommandMQ> tempCommandMQ(new CommandMQ(1));
- std::unique_ptr<DataMQ> tempDataMQ(
- new DataMQ(frameSize * framesCount, true /* EventFlag */));
+
+ if (frameSize > std::numeric_limits<size_t>::max() / framesCount) {
+ ALOGE("Requested buffer is too big, %d*%d can not fit in size_t", frameSize, framesCount);
+ _hidl_cb(Result::INVALID_ARGUMENTS,
+ CommandMQ::Descriptor(), DataMQ::Descriptor(), StatusMQ::Descriptor(), threadInfo);
+ return Void();
+ }
+ std::unique_ptr<DataMQ> tempDataMQ(new DataMQ(frameSize * framesCount, true /* EventFlag */));
+
std::unique_ptr<StatusMQ> tempStatusMQ(new StatusMQ(1));
if (!tempCommandMQ->isValid() || !tempDataMQ->isValid() || !tempStatusMQ->isValid()) {
ALOGE_IF(!tempCommandMQ->isValid(), "command MQ is invalid");
@@ -302,8 +315,11 @@
CommandMQ::Descriptor(), DataMQ::Descriptor(), StatusMQ::Descriptor(), threadInfo);
return Void();
}
- status = EventFlag::createEventFlag(tempDataMQ->getEventFlagWord(), &mEfGroup);
- if (status != OK || !mEfGroup) {
+ EventFlag* tempRawEfGroup{};
+ status = EventFlag::createEventFlag(tempDataMQ->getEventFlagWord(), &tempRawEfGroup);
+ std::unique_ptr<EventFlag, void(*)(EventFlag*)> tempElfGroup(tempRawEfGroup,[](auto *ef) {
+ EventFlag::deleteEventFlag(&ef); });
+ if (status != OK || !tempElfGroup) {
ALOGE("failed creating event flag for data MQ: %s", strerror(-status));
_hidl_cb(Result::INVALID_ARGUMENTS,
CommandMQ::Descriptor(), DataMQ::Descriptor(), StatusMQ::Descriptor(), threadInfo);
@@ -311,14 +327,19 @@
}
// Create and launch the thread.
- mWriteThread = new WriteThread(
+ auto tempWriteThread = std::make_unique<WriteThread>(
&mStopWriteThread,
mStream,
tempCommandMQ.get(),
tempDataMQ.get(),
tempStatusMQ.get(),
- mEfGroup);
- status = mWriteThread->run("writer", PRIORITY_URGENT_AUDIO);
+ tempElfGroup.get());
+ if (!tempWriteThread->init()) {
+ _hidl_cb(Result::INVALID_ARGUMENTS,
+ CommandMQ::Descriptor(), DataMQ::Descriptor(), StatusMQ::Descriptor(), threadInfo);
+ return Void();
+ }
+ status = tempWriteThread->run("writer", PRIORITY_URGENT_AUDIO);
if (status != OK) {
ALOGW("failed to start writer thread: %s", strerror(-status));
_hidl_cb(Result::INVALID_ARGUMENTS,
@@ -329,6 +350,8 @@
mCommandMQ = std::move(tempCommandMQ);
mDataMQ = std::move(tempDataMQ);
mStatusMQ = std::move(tempStatusMQ);
+ mWriteThread = tempWriteThread.release();
+ mEfGroup = tempElfGroup.release();
threadInfo.pid = getpid();
threadInfo.tid = mWriteThread->getTid();
_hidl_cb(Result::OK,
diff --git a/audio/2.0/default/service.cpp b/audio/2.0/default/service.cpp
index f3a858a..7f28d7d 100644
--- a/audio/2.0/default/service.cpp
+++ b/audio/2.0/default/service.cpp
@@ -50,7 +50,7 @@
status = registerPassthroughServiceImplementation<IEffectsFactory>();
LOG_ALWAYS_FATAL_IF(status != OK, "Error while registering audio effects service: %d", status);
// Soundtrigger and FM radio might be not present.
- status = registerPassthroughServiceImplementation<ISoundTriggerHw>("sound_trigger.primary");
+ status = registerPassthroughServiceImplementation<ISoundTriggerHw>();
ALOGE_IF(status != OK, "Error while registering soundtrigger service: %d", status);
if (useBroadcastRadioFutureFeatures) {
status = registerPassthroughServiceImplementation<
diff --git a/audio/2.0/vts/functional/AudioPrimaryHidlHalTest.cpp b/audio/2.0/vts/functional/AudioPrimaryHidlHalTest.cpp
index 1021569..4b00f35 100644
--- a/audio/2.0/vts/functional/AudioPrimaryHidlHalTest.cpp
+++ b/audio/2.0/vts/functional/AudioPrimaryHidlHalTest.cpp
@@ -171,6 +171,7 @@
sp<IDevice> baseDevice;
ASSERT_OK(devicesFactory->openDevice(IDevicesFactory::Device::PRIMARY,
returnIn(result, baseDevice)));
+ ASSERT_OK(result);
ASSERT_TRUE(baseDevice != nullptr);
environment->registerTearDown([]{ device.clear(); });
@@ -990,10 +991,12 @@
};
TEST_P(OutputStreamTest, SupportsPauseAndResumeAndDrain) {
+ doc::test("Implementation must expose pause, resume and drain capabilities");
Capability(stream.get());
}
TEST_P(OutputStreamTest, GetRenderPosition) {
+ doc::test("The render position should be 0 on a not started");
uint32_t dspFrames;
ASSERT_OK(stream->getRenderPosition(returnIn(res, dspFrames)));
if (res == Result::NOT_SUPPORTED) {
@@ -1005,6 +1008,7 @@
}
TEST_P(OutputStreamTest, GetNextWriteTimestamp) {
+ doc::test("The render position of a stream just created should be 0");
uint64_t timestampUs;
ASSERT_OK(stream->getNextWriteTimestamp(returnIn(res, timestampUs)));
if (res == Result::NOT_SUPPORTED) {
@@ -1030,6 +1034,7 @@
}
TEST_P(OutputStreamTest, SetCallback) {
+ doc::test("If supported, registering callback for async operation should never fail");
if (!isAsyncModeSupported(stream.get())) {
doc::partialTest("The stream does not support async operations");
return;
@@ -1039,6 +1044,7 @@
}
TEST_P(OutputStreamTest, clearCallback) {
+ doc::test("If supported, clearing a callback to go back to sync operation should not fail");
if (!isAsyncModeSupported(stream.get())) {
doc::partialTest("The stream does not support async operations");
return;
@@ -1049,6 +1055,7 @@
}
TEST_P(OutputStreamTest, Resume) {
+ doc::test("If supported, a stream should fail to resume if not previously paused");
if (!Capability(stream.get()).resume) {
doc::partialTest("The output stream does not support resume");
return;
@@ -1057,6 +1064,7 @@
}
TEST_P(OutputStreamTest, Pause) {
+ doc::test("If supported, a stream should fail to pause if not previously started");
if (!Capability(stream.get()).pause) {
doc::partialTest("The output stream does not support pause");
return;
@@ -1066,21 +1074,24 @@
static void testDrain(IStreamOut *stream, AudioDrain type) {
if (!Capability(stream).drain) {
- doc::partialTest("The output stream does not support pause");
+ doc::partialTest("The output stream does not support drain");
return;
}
ASSERT_RESULT(Result::OK, stream->drain(type));
}
TEST_P(OutputStreamTest, DrainAll) {
+ doc::test("If supported, a stream should always succeed to drain");
testDrain(stream.get(), AudioDrain::ALL);
}
TEST_P(OutputStreamTest, DrainEarlyNotify) {
+ doc::test("If supported, a stream should always succeed to drain");
testDrain(stream.get(), AudioDrain::EARLY_NOTIFY);
}
TEST_P(OutputStreamTest, FlushStop) {
+ doc::test("If supported, a stream should always succeed to flush");
auto ret = stream->flush();
ASSERT_TRUE(ret.isOk());
if (ret == Result::NOT_SUPPORTED) {
@@ -1091,6 +1102,7 @@
}
TEST_P(OutputStreamTest, GetPresentationPositionStop) {
+ doc::test("If supported, a stream should always succeed to retrieve the presentation position");
uint64_t frames;
TimeSpec mesureTS;
ASSERT_OK(stream->getPresentationPosition(returnIn(res, frames, mesureTS)));
diff --git a/audio/Android.bp b/audio/Android.bp
index 8a1e892..c3c2be1 100644
--- a/audio/Android.bp
+++ b/audio/Android.bp
@@ -3,6 +3,7 @@
"2.0",
"2.0/vts/functional",
"common/2.0",
+ "common/2.0/default",
"effect/2.0",
"effect/2.0/vts/functional",
]
diff --git a/audio/common/2.0/Android.mk b/audio/common/2.0/Android.mk
index 7d62779..a78a395 100644
--- a/audio/common/2.0/Android.mk
+++ b/audio/common/2.0/Android.mk
@@ -5,7 +5,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.audio.common@2.0-java-constants
+LOCAL_MODULE := android.hardware.audio.common-V2.0-java-constants
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
diff --git a/audio/common/2.0/default/Android.bp b/audio/common/2.0/default/Android.bp
new file mode 100644
index 0000000..0486a5c
--- /dev/null
+++ b/audio/common/2.0/default/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_library_shared {
+ name: "android.hardware.audio.common@2.0-util",
+ vendor_available: true,
+ srcs: [
+ "EffectMap.cpp",
+ "HidlUtils.cpp",
+ ],
+
+ export_include_dirs: ["."],
+
+ shared_libs: [
+ "liblog",
+ "libutils",
+ "libhidlbase",
+ "android.hardware.audio.common@2.0",
+ ],
+
+ header_libs: [
+ "libaudio_system_headers",
+ "libhardware_headers",
+ ],
+}
diff --git a/audio/common/2.0/default/Android.mk b/audio/common/2.0/default/Android.mk
deleted file mode 100644
index 8e2fed4..0000000
--- a/audio/common/2.0/default/Android.mk
+++ /dev/null
@@ -1,32 +0,0 @@
-#
-# 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.
-
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.audio.common@2.0-util
-LOCAL_SRC_FILES := \
- EffectMap.cpp \
- HidlUtils.cpp \
-
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
-
-LOCAL_SHARED_LIBRARIES := \
- libutils \
- libhidlbase \
- android.hardware.audio.common@2.0 \
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/audio/effect/2.0/Android.mk b/audio/effect/2.0/Android.mk
index d71255e..a426763 100644
--- a/audio/effect/2.0/Android.mk
+++ b/audio/effect/2.0/Android.mk
@@ -5,7 +5,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.audio.effect@2.0-java-constants
+LOCAL_MODULE := android.hardware.audio.effect-V2.0-java-constants
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
diff --git a/audio/effect/2.0/default/Android.mk b/audio/effect/2.0/default/Android.mk
index bbcf298..f89d4f7 100644
--- a/audio/effect/2.0/default/Android.mk
+++ b/audio/effect/2.0/default/Android.mk
@@ -36,4 +36,11 @@
android.hardware.audio.effect@2.0 \
android.hidl.memory@1.0 \
+LOCAL_HEADER_LIBRARIES := \
+ libaudio_system_headers \
+ libaudioclient_headers \
+ libeffects_headers \
+ libhardware_headers \
+ libmedia_headers \
+
include $(BUILD_SHARED_LIBRARY)
diff --git a/automotive/vehicle/2.0/Android.mk b/automotive/vehicle/2.0/Android.mk
index d093017..eb05f35 100644
--- a/automotive/vehicle/2.0/Android.mk
+++ b/automotive/vehicle/2.0/Android.mk
@@ -5,7 +5,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.automotive.vehicle@2.0-java
+LOCAL_MODULE := android.hardware.automotive.vehicle-V2.0-java
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -13,7 +13,7 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_JAVA_LIBRARIES := \
- android.hidl.base@1.0-java \
+ android.hidl.base-V1.0-java \
#
@@ -977,7 +977,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.automotive.vehicle@2.0-java-static
+LOCAL_MODULE := android.hardware.automotive.vehicle-V2.0-java-static
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -985,7 +985,7 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_STATIC_JAVA_LIBRARIES := \
- android.hidl.base@1.0-java-static \
+ android.hidl.base-V1.0-java-static \
#
diff --git a/automotive/vehicle/2.0/default/common/include/vhal_v2_0/SubscriptionManager.h b/automotive/vehicle/2.0/default/common/include/vhal_v2_0/SubscriptionManager.h
index fd59802..8e9089d 100644
--- a/automotive/vehicle/2.0/default/common/include/vhal_v2_0/SubscriptionManager.h
+++ b/automotive/vehicle/2.0/default/common/include/vhal_v2_0/SubscriptionManager.h
@@ -78,6 +78,8 @@
std::list<VehiclePropValue *> values;
};
+using ClientId = uint64_t;
+
class SubscriptionManager {
public:
using OnPropertyUnsubscribed = std::function<void(int32_t)>;
@@ -100,7 +102,8 @@
* Updates subscription. Returns the vector of properties subscription that
* needs to be updated in VehicleHAL.
*/
- StatusCode addOrUpdateSubscription(const sp<IVehicleCallback>& callback,
+ StatusCode addOrUpdateSubscription(ClientId clientId,
+ const sp<IVehicleCallback>& callback,
const hidl_vec<SubscribeOptions>& optionList,
std::list<SubscribeOptions>* outUpdatedOptions);
@@ -119,7 +122,7 @@
* If there are no clients subscribed to given properties than callback function provided
* in the constructor will be called.
*/
- void unsubscribe(const sp<IVehicleCallback>& callback, int32_t propId);
+ void unsubscribe(ClientId clientId, int32_t propId);
private:
std::list<sp<HalClient>> getSubscribedClientsLocked(int32_t propId,
int32_t area,
@@ -131,7 +134,8 @@
sp<HalClientVector> getClientsForPropertyLocked(int32_t propId) const;
- sp<HalClient> getOrCreateHalClientLocked(const sp<IVehicleCallback> &callback);
+ sp<HalClient> getOrCreateHalClientLocked(ClientId callingPid,
+ const sp<IVehicleCallback>& callback);
void onCallbackDead(uint64_t cookie);
@@ -160,7 +164,7 @@
mutable std::mutex mLock;
- std::map<sp<IVehicleCallback>, sp<HalClient>> mClients;
+ std::map<ClientId, sp<HalClient>> mClients;
std::map<int32_t, sp<HalClientVector>> mPropToClients;
std::map<int32_t, SubscribeOptions> mHalEventSubscribeOptions;
diff --git a/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleHalManager.h b/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleHalManager.h
index 1d45f4b..c1e9e88 100644
--- a/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleHalManager.h
+++ b/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleHalManager.h
@@ -101,6 +101,7 @@
static bool isSampleRateFixed(VehiclePropertyChangeMode mode);
static float checkSampleRate(const VehiclePropConfig& config,
float sampleRate);
+ static ClientId getClientId(const sp<IVehicleCallback>& callback);
private:
VehicleHal* mHal;
std::unique_ptr<VehiclePropConfigIndex> mConfigIndex;
diff --git a/automotive/vehicle/2.0/default/common/src/SubscriptionManager.cpp b/automotive/vehicle/2.0/default/common/src/SubscriptionManager.cpp
index e0f3f31..74f0a5f 100644
--- a/automotive/vehicle/2.0/default/common/src/SubscriptionManager.cpp
+++ b/automotive/vehicle/2.0/default/common/src/SubscriptionManager.cpp
@@ -97,6 +97,7 @@
}
StatusCode SubscriptionManager::addOrUpdateSubscription(
+ ClientId clientId,
const sp<IVehicleCallback> &callback,
const hidl_vec<SubscribeOptions> &optionList,
std::list<SubscribeOptions>* outUpdatedSubscriptions) {
@@ -106,7 +107,7 @@
ALOGI("SubscriptionManager::addOrUpdateSubscription, callback: %p", callback.get());
- const sp<HalClient>& client = getOrCreateHalClientLocked(callback);
+ const sp<HalClient>& client = getOrCreateHalClientLocked(clientId, callback);
if (client.get() == nullptr) {
return StatusCode::INTERNAL_ERROR;
}
@@ -221,10 +222,11 @@
}
sp<HalClient> SubscriptionManager::getOrCreateHalClientLocked(
- const sp<IVehicleCallback>& callback) {
- auto it = mClients.find(callback);
+ ClientId clientId, const sp<IVehicleCallback>& callback) {
+ auto it = mClients.find(clientId);
+
if (it == mClients.end()) {
- uint64_t cookie = reinterpret_cast<uint64_t>(callback.get());
+ uint64_t cookie = reinterpret_cast<uint64_t>(clientId);
ALOGI("Creating new client and linking to death recipient, cookie: 0x%" PRIx64, cookie);
auto res = callback->linkToDeath(mCallbackDeathRecipient, cookie);
if (!res.isOk()) { // Client is already dead?
@@ -234,18 +236,18 @@
}
sp<HalClient> client = new HalClient(callback);
- mClients.emplace(callback, client);
+ mClients.insert({clientId, client});
return client;
} else {
return it->second;
}
}
-void SubscriptionManager::unsubscribe(const sp<IVehicleCallback>& callback,
+void SubscriptionManager::unsubscribe(ClientId clientId,
int32_t propId) {
MuxGuard g(mLock);
auto propertyClients = getClientsForPropertyLocked(propId);
- auto clientIter = mClients.find(callback);
+ auto clientIter = mClients.find(clientId);
if (clientIter == mClients.end()) {
ALOGW("Unable to unsubscribe: no callback found, propId: 0x%x", propId);
} else {
@@ -285,12 +287,12 @@
void SubscriptionManager::onCallbackDead(uint64_t cookie) {
ALOGI("%s, cookie: 0x%" PRIx64, __func__, cookie);
- IVehicleCallback* callback = reinterpret_cast<IVehicleCallback*>(cookie);
+ ClientId clientId = cookie;
std::vector<int32_t> props;
{
MuxGuard g(mLock);
- const auto& it = mClients.find(callback);
+ const auto& it = mClients.find(clientId);
if (it == mClients.end()) {
return; // Nothing to do here, client wasn't subscribed to any properties.
}
@@ -299,7 +301,7 @@
}
for (int32_t propId : props) {
- unsubscribe(callback, propId);
+ unsubscribe(clientId, propId);
}
}
diff --git a/automotive/vehicle/2.0/default/common/src/VehicleHalManager.cpp b/automotive/vehicle/2.0/default/common/src/VehicleHalManager.cpp
index f452be8..ae543bb 100644
--- a/automotive/vehicle/2.0/default/common/src/VehicleHalManager.cpp
+++ b/automotive/vehicle/2.0/default/common/src/VehicleHalManager.cpp
@@ -22,6 +22,7 @@
#include <fstream>
#include <android/log.h>
+#include <android/hardware/automotive/vehicle/2.0/BpHwVehicleCallback.h>
#include "VehicleUtils.h"
@@ -154,7 +155,8 @@
}
std::list<SubscribeOptions> updatedOptions;
- auto res = mSubscriptionManager.addOrUpdateSubscription(callback, verifiedOptions,
+ auto res = mSubscriptionManager.addOrUpdateSubscription(getClientId(callback),
+ callback, verifiedOptions,
&updatedOptions);
if (StatusCode::OK != res) {
ALOGW("%s failed to subscribe, error code: %d", __func__, res);
@@ -170,7 +172,7 @@
Return<StatusCode> VehicleHalManager::unsubscribe(const sp<IVehicleCallback>& callback,
int32_t propId) {
- mSubscriptionManager.unsubscribe(callback, propId);
+ mSubscriptionManager.unsubscribe(getClientId(callback), propId);
return StatusCode::OK;
}
@@ -341,6 +343,18 @@
mHal->unsubscribe(propertyId);
}
+ClientId VehicleHalManager::getClientId(const sp<IVehicleCallback>& callback) {
+ //TODO(b/32172906): rework this to get some kind of unique id for callback interface when this
+ // feature is ready in HIDL.
+
+ if (callback->isRemote()) {
+ BpHwVehicleCallback* hwCallback = static_cast<BpHwVehicleCallback*>(callback.get());
+ return static_cast<ClientId>(reinterpret_cast<intptr_t>(hwCallback->onAsBinder()));
+ } else {
+ return static_cast<ClientId>(reinterpret_cast<intptr_t>(callback.get()));
+ }
+}
+
} // namespace V2_0
} // namespace vehicle
} // namespace automotive
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
index bf16a9b..c4f935b 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
@@ -28,6 +28,25 @@
namespace impl {
+/*
+ * This property is used for test purpose to generate fake events.
+ *
+ * It has the following format:
+ *
+ * int32Values[0] - command (1 - start fake data generation, 0 - stop)
+ * int32Values[1] - VehicleProperty to which command applies
+ *
+ * For start command, additional data should be provided:
+ * int64Values[0] - periodic interval in nanoseconds
+ * floatValues[0] - initial value
+ * floatValues[1] - dispersion defines min and max range relative to initial value
+ * floatValues[2] - increment, with every timer tick the value will be incremented by this amount
+ */
+const int32_t kGenerateFakeDataControllingProperty = 0x0666
+ | VehiclePropertyGroup::VENDOR
+ | VehicleArea::GLOBAL
+ | VehiclePropertyType::COMPLEX;
+
const int32_t kHvacPowerProperties[] = {
toInt(VehicleProperty::HVAC_FAN_SPEED),
toInt(VehicleProperty::HVAC_FAN_DIRECTION),
@@ -64,6 +83,24 @@
{
.config = {
+ .prop = toInt(VehicleProperty::PERF_ODOMETER),
+ .access = VehiclePropertyAccess::READ,
+ .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+ },
+ .initialValue = { .floatValues = {0.0f} }
+ },
+
+ {
+ .config = {
+ .prop = toInt(VehicleProperty::ENGINE_RPM),
+ .access = VehiclePropertyAccess::READ,
+ .changeMode = VehiclePropertyChangeMode::CONTINUOUS,
+ },
+ .initialValue = { .floatValues = {0.0f} }
+ },
+
+ {
+ .config = {
.prop = toInt(VehicleProperty::CURRENT_GEAR),
.access = VehiclePropertyAccess::READ,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
@@ -284,6 +321,14 @@
.maxSampleRate = 10, // 10 Hz, every 100 ms
},
.initialValue = { .floatValues = {101.0f} }
+ },
+
+ {
+ .config = {
+ .prop = kGenerateFakeDataControllingProperty,
+ .access = VehiclePropertyAccess::WRITE,
+ .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+ },
}
};
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp
index 0ac6ada..ea40cc5 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp
@@ -27,11 +27,18 @@
namespace impl {
+enum class FakeDataCommand : int32_t {
+ Stop = 0,
+ Start = 1,
+};
+
EmulatedVehicleHal::EmulatedVehicleHal(VehiclePropertyStore* propStore)
: mPropStore(propStore),
mHvacPowerProps(std::begin(kHvacPowerProperties), std::end(kHvacPowerProperties)),
mRecurrentTimer(std::bind(&EmulatedVehicleHal::onContinuousPropertyTimer,
- this, std::placeholders::_1)) {
+ this, std::placeholders::_1)),
+ mFakeValueGenerator(std::bind(&EmulatedVehicleHal::onFakeValueGenerated,
+ this, std::placeholders::_1, std::placeholders::_2)) {
for (size_t i = 0; i < arraysize(kVehicleProperties); i++) {
mPropStore->registerProperty(kVehicleProperties[i].config);
@@ -52,6 +59,10 @@
}
StatusCode EmulatedVehicleHal::set(const VehiclePropValue& propValue) {
+ if (propValue.prop == kGenerateFakeDataControllingProperty) {
+ return handleGenerateFakeDataRequest(propValue);
+ };
+
if (mHvacPowerProps.count(propValue.prop)) {
auto hvacPowerOn = mPropStore->readValueOrNull(toInt(VehicleProperty::HVAC_POWER_ON),
toInt(VehicleAreaZone::ROW_1));
@@ -176,6 +187,81 @@
return mPropStore->readAllValues();
}
+StatusCode EmulatedVehicleHal::handleGenerateFakeDataRequest(const VehiclePropValue& request) {
+ ALOGI("%s", __func__);
+ const auto& v = request.value;
+ if (v.int32Values.size() < 2) {
+ ALOGE("%s: expected at least 2 elements in int32Values, got: %zu", __func__,
+ v.int32Values.size());
+ return StatusCode::INVALID_ARG;
+ }
+
+ FakeDataCommand command = static_cast<FakeDataCommand>(v.int32Values[0]);
+ int32_t propId = v.int32Values[1];
+
+ switch (command) {
+ case FakeDataCommand::Start: {
+ if (!v.int64Values.size()) {
+ ALOGE("%s: interval is not provided in int64Values", __func__);
+ return StatusCode::INVALID_ARG;
+ }
+ auto interval = std::chrono::nanoseconds(v.int64Values[0]);
+
+ if (v.floatValues.size() < 3) {
+ ALOGE("%s: expected at least 3 element sin floatValues, got: %zu", __func__,
+ v.floatValues.size());
+ return StatusCode::INVALID_ARG;
+ }
+ float initialValue = v.floatValues[0];
+ float dispersion = v.floatValues[1];
+ float increment = v.floatValues[2];
+
+ ALOGI("%s, propId: %d, initalValue: %f", __func__, propId, initialValue);
+ mFakeValueGenerator.startGeneratingHalEvents(
+ interval, propId, initialValue, dispersion, increment);
+
+ break;
+ }
+ case FakeDataCommand::Stop: {
+ ALOGI("%s, FakeDataCommandStop", __func__);
+ mFakeValueGenerator.stopGeneratingHalEvents(propId);
+ break;
+ }
+ default: {
+ ALOGE("%s: unexpected command: %d", __func__, command);
+ return StatusCode::INVALID_ARG;
+ }
+ }
+ return StatusCode::OK;
+}
+
+void EmulatedVehicleHal::onFakeValueGenerated(int32_t propId, float value) {
+ VehiclePropValuePtr updatedPropValue {};
+ switch (getPropType(propId)) {
+ case VehiclePropertyType::FLOAT:
+ updatedPropValue = getValuePool()->obtainFloat(value);
+ break;
+ case VehiclePropertyType::INT32:
+ updatedPropValue = getValuePool()->obtainInt32(static_cast<int32_t>(value));
+ break;
+ default:
+ ALOGE("%s: data type for property: 0x%x not supported", __func__, propId);
+ return;
+
+ }
+
+ if (updatedPropValue) {
+ updatedPropValue->prop = propId;
+ updatedPropValue->areaId = 0; // Add area support if necessary.
+ updatedPropValue->timestamp = elapsedRealtimeNano();
+ mPropStore->writeValue(*updatedPropValue);
+ auto changeMode = mPropStore->getConfigOrDie(propId)->changeMode;
+ if (VehiclePropertyChangeMode::ON_CHANGE == changeMode) {
+ doHalEvent(move(updatedPropValue));
+ }
+ }
+}
+
} // impl
} // namespace V2_0
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h
index e0874e2..009485d 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h
@@ -34,6 +34,7 @@
#include "DefaultConfig.h"
#include "VehicleHalProto.pb.h"
#include "VehicleEmulator.h"
+#include "FakeValueGenerator.h"
namespace android {
namespace hardware {
@@ -67,6 +68,9 @@
return std::chrono::nanoseconds(static_cast<int64_t>(1000000000L / hz));
}
+ StatusCode handleGenerateFakeDataRequest(const VehiclePropValue& request);
+ void onFakeValueGenerated(int32_t propId, float value);
+
void onContinuousPropertyTimer(const std::vector<int32_t>& properties);
bool isContinuousProperty(int32_t propId) const;
@@ -74,6 +78,7 @@
VehiclePropertyStore* mPropStore;
std::unordered_set<int32_t> mHvacPowerProps;
RecurrentTimer mRecurrentTimer;
+ FakeValueGenerator mFakeValueGenerator;
};
} // impl
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/FakeValueGenerator.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/FakeValueGenerator.h
new file mode 100644
index 0000000..7bbbb08
--- /dev/null
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/FakeValueGenerator.h
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef android_hardware_automotive_vehicle_V2_0_impl_FakeHalEventGenerator_H_
+#define android_hardware_automotive_vehicle_V2_0_impl_FakeHalEventGenerator_H_
+
+#include <chrono>
+
+#include <android/hardware/automotive/vehicle/2.0/types.h>
+
+#include <vhal_v2_0/RecurrentTimer.h>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+namespace V2_0 {
+
+namespace impl {
+
+class FakeValueGenerator {
+private:
+ // In every timer tick we may want to generate new value based on initial value for debug
+ // purpose. It's better to have sequential values to see if events gets delivered in order
+ // to the client.
+
+ struct GeneratorCfg {
+ float initialValue; //
+ float currentValue; // Should be in range (initialValue +/- dispersion).
+ float dispersion; // Defines minimum and maximum value based on initial value.
+ float increment; // Value that we will be added to currentValue with each timer tick.
+ };
+
+public:
+ using OnHalEvent = std::function<void(int32_t propId, float value)>;
+
+ FakeValueGenerator(const OnHalEvent& onHalEvent) :
+ mOnHalEvent(onHalEvent),
+ mRecurrentTimer(std::bind(&FakeValueGenerator::onTimer, this,
+ std::placeholders::_1))
+ {}
+
+ ~FakeValueGenerator() = default;
+
+
+ void startGeneratingHalEvents(std::chrono::nanoseconds interval, int propId, float initialValue,
+ float dispersion, float increment) {
+ MuxGuard g(mLock);
+
+ removeLocked(propId);
+
+ mGenCfg.insert({propId, GeneratorCfg {
+ .initialValue = initialValue,
+ .currentValue = initialValue,
+ .dispersion = dispersion,
+ .increment = increment,
+ }});
+
+ mRecurrentTimer.registerRecurrentEvent(interval, propId);
+ }
+
+ void stopGeneratingHalEvents(int propId) {
+ MuxGuard g(mLock);
+ if (propId == 0) {
+ // Remove all.
+ for (auto&& it : mGenCfg) {
+ removeLocked(it.first);
+ }
+ } else {
+ removeLocked(propId);
+ }
+ }
+
+private:
+ void removeLocked(int propId) {
+ if (mGenCfg.erase(propId)) {
+ mRecurrentTimer.unregisterRecurrentEvent(propId);
+ }
+ }
+
+ void onTimer(const std::vector<int32_t>& properties) {
+ MuxGuard g(mLock);
+
+ for (int32_t propId : properties) {
+ auto& cfg = mGenCfg[propId];
+ cfg.currentValue += cfg.increment;
+ if (cfg.currentValue > cfg.initialValue + cfg.dispersion) {
+ cfg.currentValue = cfg.initialValue - cfg.dispersion;
+ }
+ mOnHalEvent(propId, cfg.currentValue);
+ }
+ }
+
+private:
+ using MuxGuard = std::lock_guard<std::mutex>;
+
+ mutable std::mutex mLock;
+ OnHalEvent mOnHalEvent;
+ RecurrentTimer mRecurrentTimer;
+ std::unordered_map<int32_t, GeneratorCfg> mGenCfg;
+};
+
+
+} // impl
+
+} // namespace V2_0
+} // namespace vehicle
+} // namespace automotive
+} // namespace hardware
+} // namespace android
+
+
+
+#endif //android_hardware_automotive_vehicle_V2_0_impl_FakeHalEventGenerator_H_
diff --git a/automotive/vehicle/2.0/default/tests/SubscriptionManager_test.cpp b/automotive/vehicle/2.0/default/tests/SubscriptionManager_test.cpp
index 7ec9b79..5688dd6 100644
--- a/automotive/vehicle/2.0/default/tests/SubscriptionManager_test.cpp
+++ b/automotive/vehicle/2.0/default/tests/SubscriptionManager_test.cpp
@@ -119,8 +119,10 @@
TEST_F(SubscriptionManagerTest, multipleClients) {
std::list<SubscribeOptions> updatedOptions;
- ASSERT_EQ(StatusCode::OK, manager.addOrUpdateSubscription(cb1, subscrToProp1, &updatedOptions));
- ASSERT_EQ(StatusCode::OK, manager.addOrUpdateSubscription(cb2, subscrToProp1, &updatedOptions));
+ ASSERT_EQ(StatusCode::OK,
+ manager.addOrUpdateSubscription(1, cb1, subscrToProp1, &updatedOptions));
+ ASSERT_EQ(StatusCode::OK,
+ manager.addOrUpdateSubscription(2, cb2, subscrToProp1, &updatedOptions));
auto clients = manager.getSubscribedClients(
PROP1,
@@ -132,7 +134,8 @@
TEST_F(SubscriptionManagerTest, negativeCases) {
std::list<SubscribeOptions> updatedOptions;
- ASSERT_EQ(StatusCode::OK, manager.addOrUpdateSubscription(cb1, subscrToProp1, &updatedOptions));
+ ASSERT_EQ(StatusCode::OK,
+ manager.addOrUpdateSubscription(1, cb1, subscrToProp1, &updatedOptions));
// Wrong zone
auto clients = manager.getSubscribedClients(
@@ -158,7 +161,8 @@
TEST_F(SubscriptionManagerTest, mulipleSubscriptions) {
std::list<SubscribeOptions> updatedOptions;
- ASSERT_EQ(StatusCode::OK, manager.addOrUpdateSubscription(cb1, subscrToProp1, &updatedOptions));
+ ASSERT_EQ(StatusCode::OK, manager.addOrUpdateSubscription(1, cb1, subscrToProp1,
+ &updatedOptions));
auto clients = manager.getSubscribedClients(
PROP1,
@@ -169,7 +173,7 @@
// Same property, but different zone, to make sure we didn't unsubscribe
// from previous zone.
- ASSERT_EQ(StatusCode::OK, manager.addOrUpdateSubscription(cb1, {
+ ASSERT_EQ(StatusCode::OK, manager.addOrUpdateSubscription(1, cb1, {
SubscribeOptions {
.propId = PROP1,
.vehicleAreas = toInt(VehicleAreaZone::ROW_2),
@@ -190,15 +194,17 @@
TEST_F(SubscriptionManagerTest, unsubscribe) {
std::list<SubscribeOptions> updatedOptions;
- ASSERT_EQ(StatusCode::OK, manager.addOrUpdateSubscription(cb1, subscrToProp1, &updatedOptions));
- ASSERT_EQ(StatusCode::OK, manager.addOrUpdateSubscription(cb2, subscrToProp2, &updatedOptions));
- ASSERT_EQ(StatusCode::OK, manager.addOrUpdateSubscription(cb3, subscrToProp1and2,
- &updatedOptions));
+ ASSERT_EQ(StatusCode::OK,
+ manager.addOrUpdateSubscription(1, cb1, subscrToProp1, &updatedOptions));
+ ASSERT_EQ(StatusCode::OK,
+ manager.addOrUpdateSubscription(2, cb2, subscrToProp2, &updatedOptions));
+ ASSERT_EQ(StatusCode::OK,
+ manager.addOrUpdateSubscription(3, cb3, subscrToProp1and2, &updatedOptions));
- ASSERT_ALL_EXISTS({cb1, cb3}, extractCallbacks(clientsToProp1()));
+ ASSERT_ALL_EXISTS({ cb1, cb3 }, extractCallbacks(clientsToProp1()));
ASSERT_ALL_EXISTS({cb2, cb3}, extractCallbacks(clientsToProp2()));
- manager.unsubscribe(cb1, PROP1);
+ manager.unsubscribe(1, PROP1);
assertOnPropertyUnsubscribedNotCalled();
ASSERT_ALL_EXISTS({cb3}, extractCallbacks(clientsToProp1()));
@@ -206,20 +212,20 @@
ASSERT_ALL_EXISTS({cb2, cb3}, extractCallbacks(clientsToProp2()));
// No one subscribed to PROP1, subscription for PROP2 is not affected.
- manager.unsubscribe(cb3, PROP1);
+ manager.unsubscribe(3, PROP1);
assertLastUnsubscribedProperty(PROP1);
ASSERT_ALL_EXISTS({cb2, cb3}, extractCallbacks(clientsToProp2()));
- manager.unsubscribe(cb3, PROP2);
+ manager.unsubscribe(3, PROP2);
assertOnPropertyUnsubscribedNotCalled();
ASSERT_ALL_EXISTS({cb2}, extractCallbacks(clientsToProp2()));
// The last client unsubscribed from this property.
- manager.unsubscribe(cb2, PROP2);
+ manager.unsubscribe(2, PROP2);
assertLastUnsubscribedProperty(PROP2);
// No one subscribed anymore
- manager.unsubscribe(cb1, PROP1);
+ manager.unsubscribe(1, PROP1);
assertLastUnsubscribedProperty(PROP1);
}
diff --git a/automotive/vehicle/2.1/Android.mk b/automotive/vehicle/2.1/Android.mk
index a421c86..8e1c0dd 100644
--- a/automotive/vehicle/2.1/Android.mk
+++ b/automotive/vehicle/2.1/Android.mk
@@ -5,7 +5,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.automotive.vehicle@2.1-java
+LOCAL_MODULE := android.hardware.automotive.vehicle-V2.1-java
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -13,8 +13,8 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_JAVA_LIBRARIES := \
- android.hardware.automotive.vehicle@2.0-java \
- android.hidl.base@1.0-java \
+ android.hardware.automotive.vehicle-V2.0-java \
+ android.hidl.base-V1.0-java \
#
@@ -326,7 +326,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.automotive.vehicle@2.1-java-static
+LOCAL_MODULE := android.hardware.automotive.vehicle-V2.1-java-static
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -334,8 +334,8 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_STATIC_JAVA_LIBRARIES := \
- android.hardware.automotive.vehicle@2.0-java-static \
- android.hidl.base@1.0-java-static \
+ android.hardware.automotive.vehicle-V2.0-java-static \
+ android.hidl.base-V1.0-java-static \
#
diff --git a/biometrics/fingerprint/2.1/Android.mk b/biometrics/fingerprint/2.1/Android.mk
index 567b38a..2f32371 100644
--- a/biometrics/fingerprint/2.1/Android.mk
+++ b/biometrics/fingerprint/2.1/Android.mk
@@ -5,7 +5,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.biometrics.fingerprint@2.1-java
+LOCAL_MODULE := android.hardware.biometrics.fingerprint-V2.1-java
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -13,7 +13,7 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_JAVA_LIBRARIES := \
- android.hidl.base@1.0-java \
+ android.hidl.base-V1.0-java \
#
@@ -236,7 +236,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.biometrics.fingerprint@2.1-java-static
+LOCAL_MODULE := android.hardware.biometrics.fingerprint-V2.1-java-static
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -244,7 +244,7 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_STATIC_JAVA_LIBRARIES := \
- android.hidl.base@1.0-java-static \
+ android.hidl.base-V1.0-java-static \
#
diff --git a/biometrics/fingerprint/2.1/default/Android.mk b/biometrics/fingerprint/2.1/default/Android.mk
index 3d06397..f02db94 100644
--- a/biometrics/fingerprint/2.1/default/Android.mk
+++ b/biometrics/fingerprint/2.1/default/Android.mk
@@ -10,12 +10,11 @@
service.cpp \
LOCAL_SHARED_LIBRARIES := \
- libbinder \
+ libcutils \
liblog \
libhidlbase \
libhidltransport \
libhardware \
- libkeystore_binder \
libutils \
android.hardware.biometrics.fingerprint@2.1 \
diff --git a/biometrics/fingerprint/2.1/default/BiometricsFingerprint.cpp b/biometrics/fingerprint/2.1/default/BiometricsFingerprint.cpp
index 4f5aaf9..16197d7 100644
--- a/biometrics/fingerprint/2.1/default/BiometricsFingerprint.cpp
+++ b/biometrics/fingerprint/2.1/default/BiometricsFingerprint.cpp
@@ -16,8 +16,6 @@
#define LOG_TAG "android.hardware.biometrics.fingerprint@2.1-service"
#define LOG_VERBOSE "android.hardware.biometrics.fingerprint@2.1-service"
-// For communication with Keystore binder interface
-#include <keystore/keystore.h> // for error codes
#include <hardware/hw_auth_token.h>
#include <hardware/hardware.h>
@@ -25,6 +23,7 @@
#include "BiometricsFingerprint.h"
#include <inttypes.h>
+#include <unistd.h>
namespace android {
namespace hardware {
@@ -189,7 +188,12 @@
const hidl_string& storePath) {
if (storePath.size() >= PATH_MAX || storePath.size() <= 0) {
ALOGE("Bad path length: %zd", storePath.size());
+ return RequestStatus::SYS_EINVAL;
}
+ if (access(storePath.c_str(), W_OK)) {
+ return RequestStatus::SYS_EINVAL;
+ }
+
return ErrorFilter(mDevice->set_active_group(mDevice, gid,
storePath.c_str()));
}
diff --git a/biometrics/fingerprint/2.1/vts/functional/VtsHalBiometricsFingerprintV2_1TargetTest.cpp b/biometrics/fingerprint/2.1/vts/functional/VtsHalBiometricsFingerprintV2_1TargetTest.cpp
index d3f6612..29776b4 100644
--- a/biometrics/fingerprint/2.1/vts/functional/VtsHalBiometricsFingerprintV2_1TargetTest.cpp
+++ b/biometrics/fingerprint/2.1/vts/functional/VtsHalBiometricsFingerprintV2_1TargetTest.cpp
@@ -43,7 +43,7 @@
static const uint32_t kTimeout = 3;
static const std::chrono::seconds kTimeoutInSeconds = std::chrono::seconds(kTimeout);
static const uint32_t kGroupId = 99;
-static const std::string kTmpDir = "/data/local/tmp/";
+static const std::string kTmpDir = "/data/system/";
static const uint32_t kIterations = 1000;
// Wait for a callback to occur (signaled by the given future) up to the
@@ -186,6 +186,8 @@
ASSERT_FALSE(mService == nullptr);
// Create an active group
+ // FP service can only write to /data/system due to
+ // SELinux Policy and Linux Dir Permissions
Return<RequestStatus> res = mService->setActiveGroup(kGroupId, kTmpDir);
ASSERT_EQ(RequestStatus::SYS_OK, static_cast<RequestStatus>(res));
}
diff --git a/bluetooth/1.0/Android.mk b/bluetooth/1.0/Android.mk
index d824d5d..f8cd96e 100644
--- a/bluetooth/1.0/Android.mk
+++ b/bluetooth/1.0/Android.mk
@@ -5,7 +5,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.bluetooth@1.0-java
+LOCAL_MODULE := android.hardware.bluetooth-V1.0-java
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -13,7 +13,7 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_JAVA_LIBRARIES := \
- android.hidl.base@1.0-java \
+ android.hidl.base-V1.0-java \
#
@@ -84,7 +84,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.bluetooth@1.0-java-static
+LOCAL_MODULE := android.hardware.bluetooth-V1.0-java-static
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -92,7 +92,7 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_STATIC_JAVA_LIBRARIES := \
- android.hidl.base@1.0-java-static \
+ android.hidl.base-V1.0-java-static \
#
diff --git a/bluetooth/1.0/default/Android.bp b/bluetooth/1.0/default/Android.bp
index c77f0e6..fec2264 100644
--- a/bluetooth/1.0/default/Android.bp
+++ b/bluetooth/1.0/default/Android.bp
@@ -16,7 +16,7 @@
cc_library_shared {
name: "android.hardware.bluetooth@1.0-impl",
defaults: ["hidl_defaults"],
- proprietary: true,
+ vendor: true,
relative_install_path: "hw",
srcs: [
"bluetooth_hci.cc",
@@ -41,7 +41,7 @@
cc_library_static {
name: "android.hardware.bluetooth-async",
- proprietary: true,
+ vendor: true,
defaults: ["hidl_defaults"],
srcs: [
"async_fd_watcher.cc",
@@ -54,7 +54,7 @@
cc_library_static {
name: "android.hardware.bluetooth-hci",
- proprietary: true,
+ vendor: true,
defaults: ["hidl_defaults"],
srcs: [
"hci_packetizer.cc",
@@ -73,6 +73,7 @@
cc_test {
name: "bluetooth-vendor-interface-unit-tests",
+ vendor: true,
defaults: ["hidl_defaults"],
srcs: [
"test/async_fd_watcher_unittest.cc",
diff --git a/bluetooth/1.0/default/Android.mk b/bluetooth/1.0/default/Android.mk
index 7530925..38294c7 100644
--- a/bluetooth/1.0/default/Android.mk
+++ b/bluetooth/1.0/default/Android.mk
@@ -29,7 +29,6 @@
libdl \
libbase \
libutils \
- libhardware_legacy \
libhardware \
LOCAL_SHARED_LIBRARIES += \
diff --git a/boot/1.0/Android.mk b/boot/1.0/Android.mk
index b188acb..efd5759 100644
--- a/boot/1.0/Android.mk
+++ b/boot/1.0/Android.mk
@@ -5,7 +5,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.boot@1.0-java
+LOCAL_MODULE := android.hardware.boot-V1.0-java
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -13,7 +13,7 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_JAVA_LIBRARIES := \
- android.hidl.base@1.0-java \
+ android.hidl.base-V1.0-java \
#
@@ -80,7 +80,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.boot@1.0-java-static
+LOCAL_MODULE := android.hardware.boot-V1.0-java-static
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -88,7 +88,7 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_STATIC_JAVA_LIBRARIES := \
- android.hidl.base@1.0-java-static \
+ android.hidl.base-V1.0-java-static \
#
diff --git a/camera/common/1.0/Android.mk b/camera/common/1.0/Android.mk
index 9e05172..47bfb31 100644
--- a/camera/common/1.0/Android.mk
+++ b/camera/common/1.0/Android.mk
@@ -5,7 +5,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.camera.common@1.0-java
+LOCAL_MODULE := android.hardware.camera.common-V1.0-java
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -188,7 +188,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.camera.common@1.0-java-static
+LOCAL_MODULE := android.hardware.camera.common-V1.0-java-static
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
diff --git a/camera/device/3.2/ICameraDevice.hal b/camera/device/3.2/ICameraDevice.hal
index 6e66bf3..1f523e4 100644
--- a/camera/device/3.2/ICameraDevice.hal
+++ b/camera/device/3.2/ICameraDevice.hal
@@ -167,7 +167,7 @@
* longer available. This interface is now stale, and a new instance
* must be acquired if the device is reconnected. All subsequent
* calls on this interface must return CAMERA_DISCONNECTED.
- * @return cameraDevice The interface to the newly-opened camera session,
+ * @return session The interface to the newly-opened camera session,
* or null if status is not OK.
*/
open(ICameraDeviceCallback callback) generates
diff --git a/camera/device/3.2/ICameraDeviceCallback.hal b/camera/device/3.2/ICameraDeviceCallback.hal
index bf51da2..69715de 100644
--- a/camera/device/3.2/ICameraDeviceCallback.hal
+++ b/camera/device/3.2/ICameraDeviceCallback.hal
@@ -42,7 +42,9 @@
* metadata and low-resolution buffers to be returned in one call, and
* post-processed JPEG buffers in a later call, once it is available. Each
* call must include the frame number of the request it is returning
- * metadata or buffers for.
+ * metadata or buffers for. Only one call to processCaptureResult
+ * may be made at a time by the HAL although the calls may come from
+ * different threads in the HAL.
*
* A component (buffer or metadata) of the complete result may only be
* included in one process_capture_result call. A buffer for each stream,
diff --git a/camera/device/3.2/ICameraDeviceSession.hal b/camera/device/3.2/ICameraDeviceSession.hal
index 731fc76..477a3cc 100644
--- a/camera/device/3.2/ICameraDeviceSession.hal
+++ b/camera/device/3.2/ICameraDeviceSession.hal
@@ -248,6 +248,39 @@
generates (Status status, uint32_t numRequestProcessed);
/**
+ * getCaptureRequestMetadataQueue:
+ *
+ * Retrieves the queue used along with processCaptureRequest. If
+ * client decides to use fast message queue to pass request metadata,
+ * it must:
+ * - Call getCaptureRequestMetadataQueue to retrieve the fast message queue;
+ * - In each of the requests sent in processCaptureRequest, set
+ * fmqSettingsSize field of CaptureRequest to be the size to read from the
+ * fast message queue; leave settings field of CaptureRequest empty.
+ *
+ * @return queue the queue that client writes request metadata to.
+ */
+ getCaptureRequestMetadataQueue() generates (fmq_sync<uint8_t> queue);
+
+ /**
+ * getCaptureResultMetadataQueue:
+ *
+ * Retrieves the queue used along with
+ * ICameraDeviceCallback.processCaptureResult.
+ *
+ * Clients to ICameraDeviceSession 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);
+
+ /**
* flush:
*
* Flush all currently in-process captures and all buffers in the pipeline
diff --git a/camera/device/3.2/default/Android.bp b/camera/device/3.2/default/Android.bp
index e0dc5ff..d95f8f4 100644
--- a/camera/device/3.2/default/Android.bp
+++ b/camera/device/3.2/default/Android.bp
@@ -14,10 +14,14 @@
"android.hardware.camera.provider@2.4",
"liblog",
"libhardware",
- "libcamera_metadata"
+ "libcamera_metadata",
+ "libfmq"
],
static_libs: [
"android.hardware.camera.common@1.0-helper"
],
- export_include_dirs: ["."]
+ export_include_dirs: ["."],
+ export_shared_lib_headers: [
+ "libfmq",
+ ]
}
diff --git a/camera/device/3.2/default/CameraDeviceSession.cpp b/camera/device/3.2/default/CameraDeviceSession.cpp
index 5bb53c7..2499b1a 100644
--- a/camera/device/3.2/default/CameraDeviceSession.cpp
+++ b/camera/device/3.2/default/CameraDeviceSession.cpp
@@ -30,6 +30,11 @@
namespace V3_2 {
namespace implementation {
+// Size of request metadata fast message queue. Change to 0 to always use hwbinder buffer.
+static constexpr size_t CAMERA_REQUEST_METADATA_QUEUE_SIZE = 1 << 20 /* 1MB */;
+// Size of result metadata fast message queue. Change to 0 to always use hwbinder buffer.
+static constexpr size_t CAMERA_RESULT_METADATA_QUEUE_SIZE = 1 << 20 /* 1MB */;
+
HandleImporter& CameraDeviceSession::sHandleImporter = HandleImporter::getInstance();
const int CameraDeviceSession::ResultBatcher::NOT_BATCHED;
@@ -66,6 +71,21 @@
mClosed = true;
return true;
}
+
+ mRequestMetadataQueue = std::make_unique<RequestMetadataQueue>(
+ CAMERA_REQUEST_METADATA_QUEUE_SIZE, false /* non blocking */);
+ if (!mRequestMetadataQueue->isValid()) {
+ ALOGE("%s: invalid request fmq", __FUNCTION__);
+ return true;
+ }
+ mResultMetadataQueue = std::make_shared<RequestMetadataQueue>(
+ CAMERA_RESULT_METADATA_QUEUE_SIZE, false /* non blocking */);
+ if (!mResultMetadataQueue->isValid()) {
+ ALOGE("%s: invalid result fmq", __FUNCTION__);
+ return true;
+ }
+ mResultBatcher.setResultMetadataQueue(mResultMetadataQueue);
+
return false;
}
@@ -220,6 +240,11 @@
mStreamsToBatch = streamsToBatch;
}
+void CameraDeviceSession::ResultBatcher::setResultMetadataQueue(std::shared_ptr<ResultMetadataQueue> q) {
+ Mutex::Autolock _l(mLock);
+ mResultMetadataQueue = q;
+}
+
void CameraDeviceSession::ResultBatcher::registerBatch(
const hidl_vec<CaptureRequest>& requests) {
auto batch = std::make_shared<InflightBatch>();
@@ -339,6 +364,7 @@
results.resize(batchSize);
for (size_t i = 0; i < batchSize; i++) {
results[i].frameNumber = batch->mFirstFrame + i;
+ results[i].fmqResultSize = 0;
results[i].partialResult = 0; // 0 for buffer only results
results[i].inputBuffer.streamId = -1;
results[i].inputBuffer.bufferId = 0;
@@ -355,7 +381,7 @@
}
results[i].outputBuffers = outBufs;
}
- mCallback->processCaptureResult(results);
+ invokeProcessCaptureResultCallback(results, /* tryWriteFmq */false);
freeReleaseFences(results);
for (int streamId : streams) {
InflightBatch::BufferBatch& bb = batch->mBatchBufs[streamId];
@@ -385,6 +411,7 @@
CaptureResult result;
result.frameNumber = p.first;
result.result = std::move(p.second);
+ result.fmqResultSize = 0;
result.inputBuffer.streamId = -1;
result.inputBuffer.bufferId = 0;
result.inputBuffer.buffer = nullptr;
@@ -393,7 +420,9 @@
}
mb.mMds.clear();
}
- mCallback->processCaptureResult(results);
+ hidl_vec<CaptureResult> hResults;
+ hResults.setToExternal(results.data(), results.size());
+ invokeProcessCaptureResultCallback(hResults, /* tryWriteFmq */true);
batch->mPartialResultProgress = lastPartialResultIdx;
for (uint32_t partialIdx : toBeRemovedIdxes) {
batch->mResultMds.erase(partialIdx);
@@ -466,9 +495,37 @@
}
}
+void CameraDeviceSession::ResultBatcher::invokeProcessCaptureResultCallback(
+ hidl_vec<CaptureResult> &results, bool tryWriteFmq) {
+ if (mProcessCaptureResultLock.tryLock() != OK) {
+ ALOGW("%s: previous call is not finished! waiting 1s...",
+ __FUNCTION__);
+ if (mProcessCaptureResultLock.timedLock(1000000000 /* 1s */) != OK) {
+ ALOGE("%s: cannot acquire lock in 1s, cannot proceed",
+ __FUNCTION__);
+ return;
+ }
+ }
+ if (tryWriteFmq && mResultMetadataQueue->availableToWrite() > 0) {
+ for (CaptureResult &result : results) {
+ if (result.result.size() > 0) {
+ if (mResultMetadataQueue->write(result.result.data(), result.result.size())) {
+ result.fmqResultSize = result.result.size();
+ result.result.resize(0);
+ } else {
+ ALOGW("%s: couldn't utilize fmq, fall back to hwbinder", __FUNCTION__);
+ result.fmqResultSize = 0;
+ }
+ }
+ }
+ }
+ mCallback->processCaptureResult(results);
+ mProcessCaptureResultLock.unlock();
+}
+
void CameraDeviceSession::ResultBatcher::processOneCaptureResult(CaptureResult& result) {
hidl_vec<CaptureResult> results = {result};
- mCallback->processCaptureResult(results);
+ invokeProcessCaptureResultCallback(results, /* tryWriteFmq */true);
freeReleaseFences(results);
return;
}
@@ -515,6 +572,7 @@
if (nonBatchedBuffers.size() > 0 || result.inputBuffer.streamId != -1) {
CaptureResult nonBatchedResult;
nonBatchedResult.frameNumber = result.frameNumber;
+ nonBatchedResult.fmqResultSize = 0;
nonBatchedResult.outputBuffers = nonBatchedBuffers;
nonBatchedResult.inputBuffer = result.inputBuffer;
nonBatchedResult.partialResult = 0; // 0 for buffer only results
@@ -699,6 +757,18 @@
}
}
+Return<void> CameraDeviceSession::getCaptureRequestMetadataQueue(
+ getCaptureRequestMetadataQueue_cb _hidl_cb) {
+ _hidl_cb(*mRequestMetadataQueue->getDesc());
+ return Void();
+}
+
+Return<void> CameraDeviceSession::getCaptureResultMetadataQueue(
+ getCaptureResultMetadataQueue_cb _hidl_cb) {
+ _hidl_cb(*mResultMetadataQueue->getDesc());
+ return Void();
+}
+
Return<void> CameraDeviceSession::processCaptureRequest(
const hidl_vec<CaptureRequest>& requests,
const hidl_vec<BufferCache>& cachesToRemove,
@@ -731,7 +801,24 @@
camera3_capture_request_t halRequest;
halRequest.frame_number = request.frameNumber;
- bool converted = convertFromHidl(request.settings, &halRequest.settings);
+
+ bool converted = true;
+ CameraMetadata settingsFmq; // settings from FMQ
+ if (request.fmqSettingsSize > 0) {
+ // non-blocking read; client must write metadata before calling
+ // processOneCaptureRequest
+ settingsFmq.resize(request.fmqSettingsSize);
+ bool read = mRequestMetadataQueue->read(settingsFmq.data(), request.fmqSettingsSize);
+ if (read) {
+ converted = convertFromHidl(settingsFmq, &halRequest.settings);
+ } else {
+ ALOGE("%s: capture request settings metadata couldn't be read from fmq!", __FUNCTION__);
+ converted = false;
+ }
+ } else {
+ converted = convertFromHidl(request.settings, &halRequest.settings);
+ }
+
if (!converted) {
ALOGE("%s: capture request settings metadata is corrupt!", __FUNCTION__);
return Status::INTERNAL_ERROR;
@@ -881,6 +968,7 @@
// within the scope of this function
CaptureResult result;
result.frameNumber = frameNumber;
+ result.fmqResultSize = 0;
result.partialResult = hal_result->partial_result;
convertToHidl(hal_result->result, &result.result);
if (hasInputBuf) {
diff --git a/camera/device/3.2/default/CameraDeviceSession.h b/camera/device/3.2/default/CameraDeviceSession.h
index 781056e..7682165 100644
--- a/camera/device/3.2/default/CameraDeviceSession.h
+++ b/camera/device/3.2/default/CameraDeviceSession.h
@@ -17,19 +17,20 @@
#ifndef ANDROID_HARDWARE_CAMERA_DEVICE_V3_2_CAMERADEVICE3SESSION_H
#define ANDROID_HARDWARE_CAMERA_DEVICE_V3_2_CAMERADEVICE3SESSION_H
+#include <android/hardware/camera/device/3.2/ICameraDevice.h>
+#include <android/hardware/camera/device/3.2/ICameraDeviceSession.h>
+#include <fmq/MessageQueue.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+#include <include/convert.h>
#include <deque>
#include <map>
#include <unordered_map>
-#include "hardware/camera_common.h"
-#include "hardware/camera3.h"
-#include "utils/Mutex.h"
-#include <android/hardware/camera/device/3.2/ICameraDevice.h>
-#include <android/hardware/camera/device/3.2/ICameraDeviceSession.h>
-#include <hidl/Status.h>
-#include <hidl/MQDescriptor.h>
-#include <include/convert.h>
-#include "HandleImporter.h"
#include "CameraMetadata.h"
+#include "HandleImporter.h"
+#include "hardware/camera3.h"
+#include "hardware/camera_common.h"
+#include "utils/Mutex.h"
namespace android {
namespace hardware {
@@ -44,6 +45,9 @@
using ::android::hardware::camera::device::V3_2::ICameraDeviceSession;
using ::android::hardware::camera::common::V1_0::Status;
using ::android::hardware::camera::common::V1_0::helper::HandleImporter;
+using ::android::hardware::kSynchronizedReadWrite;
+using ::android::hardware::MessageQueue;
+using ::android::hardware::MQDescriptorSync;
using ::android::hardware::Return;
using ::android::hardware::Void;
using ::android::hardware::hidl_vec;
@@ -84,6 +88,10 @@
RequestTemplate type, constructDefaultRequestSettings_cb _hidl_cb) override;
Return<void> configureStreams(
const StreamConfiguration& requestedConfiguration, configureStreams_cb _hidl_cb) override;
+ Return<void> getCaptureRequestMetadataQueue(
+ getCaptureRequestMetadataQueue_cb _hidl_cb) override;
+ Return<void> getCaptureResultMetadataQueue(
+ getCaptureResultMetadataQueue_cb _hidl_cb) override;
Return<void> processCaptureRequest(
const hidl_vec<CaptureRequest>& requests,
const hidl_vec<BufferCache>& cachesToRemove,
@@ -126,11 +134,17 @@
common::V1_0::helper::CameraMetadata mDeviceInfo;
+ using RequestMetadataQueue = MessageQueue<uint8_t, kSynchronizedReadWrite>;
+ std::unique_ptr<RequestMetadataQueue> mRequestMetadataQueue;
+ using ResultMetadataQueue = MessageQueue<uint8_t, kSynchronizedReadWrite>;
+ std::shared_ptr<ResultMetadataQueue> mResultMetadataQueue;
+
class ResultBatcher {
public:
ResultBatcher(const sp<ICameraDeviceCallback>& callback);
void setNumPartialResults(uint32_t n);
void setBatchedStreams(const std::vector<int>& streamsToBatch);
+ void setResultMetadataQueue(std::shared_ptr<ResultMetadataQueue> q);
void registerBatch(const hidl_vec<CaptureRequest>& requests);
void notify(NotifyMsg& msg);
@@ -208,6 +222,7 @@
void freeReleaseFences(hidl_vec<CaptureResult>&);
void notifySingleMsg(NotifyMsg& msg);
void processOneCaptureResult(CaptureResult& result);
+ void invokeProcessCaptureResultCallback(hidl_vec<CaptureResult> &results, bool tryWriteFmq);
// Protect access to mInflightBatches, mNumPartialResults and mStreamsToBatch
// processCaptureRequest, processCaptureResult, notify will compete for this lock
@@ -217,6 +232,11 @@
uint32_t mNumPartialResults;
std::vector<int> mStreamsToBatch;
const sp<ICameraDeviceCallback> mCallback;
+ std::shared_ptr<ResultMetadataQueue> mResultMetadataQueue;
+
+ // Protect against invokeProcessCaptureResultCallback()
+ Mutex mProcessCaptureResultLock;
+
} mResultBatcher;
std::vector<int> mVideoStreamIds;
diff --git a/camera/device/3.2/types.hal b/camera/device/3.2/types.hal
index 1632570..276e92a 100644
--- a/camera/device/3.2/types.hal
+++ b/camera/device/3.2/types.hal
@@ -753,11 +753,22 @@
uint32_t frameNumber;
/**
- * The settings buffer contains the capture and processing parameters for
+ * If non-zero, read settings from request queue instead
+ * (see ICameraDeviceSession.getCaptureRequestMetadataQueue).
+ * If zero, read settings from .settings field.
+ */
+ uint64_t fmqSettingsSize;
+
+ /**
+ * If fmqSettingsSize is zero,
+ * the settings buffer contains the capture and processing parameters for
* the request. As a special case, an empty settings buffer indicates that
* the settings are identical to the most-recently submitted capture
* request. A empty buffer cannot be used as the first submitted request
* after a configureStreams() call.
+ *
+ * This field must be used if fmqSettingsSize is zero. It must not be used
+ * if fmqSettingsSize is non-zero.
*/
CameraMetadata settings;
@@ -842,6 +853,13 @@
uint32_t frameNumber;
/**
+ * If non-zero, read result from result queue instead
+ * (see ICameraDeviceSession.getCaptureResultMetadataQueue).
+ * If zero, read result from .result field.
+ */
+ uint64_t fmqResultSize;
+
+ /**
* The result metadata for this capture. This contains information about the
* final capture parameters, the state of the capture and post-processing
* hardware, the state of the 3A algorithms, if enabled, and the output of
diff --git a/camera/metadata/3.2/Android.mk b/camera/metadata/3.2/Android.mk
index 86cee91..935c37c 100644
--- a/camera/metadata/3.2/Android.mk
+++ b/camera/metadata/3.2/Android.mk
@@ -5,7 +5,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.camera.metadata@3.2-java
+LOCAL_MODULE := android.hardware.camera.metadata-V3.2-java
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -1233,7 +1233,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.camera.metadata@3.2-java-static
+LOCAL_MODULE := android.hardware.camera.metadata-V3.2-java-static
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
diff --git a/camera/provider/2.4/default/Android.bp b/camera/provider/2.4/default/Android.bp
index 8e8df62..9506827 100644
--- a/camera/provider/2.4/default/Android.bp
+++ b/camera/provider/2.4/default/Android.bp
@@ -37,7 +37,6 @@
shared_libs: [
"libhidlbase",
"libhidltransport",
- "libbinder",
"liblog",
"libutils",
"android.hardware.camera.device@1.0",
diff --git a/camera/provider/2.4/default/service.cpp b/camera/provider/2.4/default/service.cpp
index 7eeb637..df2602e 100644
--- a/camera/provider/2.4/default/service.cpp
+++ b/camera/provider/2.4/default/service.cpp
@@ -19,16 +19,11 @@
#include <android/hardware/camera/provider/2.4/ICameraProvider.h>
#include <hidl/LegacySupport.h>
-#include <binder/ProcessState.h>
-
using android::hardware::camera::provider::V2_4::ICameraProvider;
using android::hardware::defaultPassthroughServiceImplementation;
int main()
{
ALOGI("Camera provider Service is starting.");
- // The camera HAL may communicate to other vendor components via
- // /dev/vndbinder
- android::ProcessState::initWithDriver("/dev/vndbinder");
return defaultPassthroughServiceImplementation<ICameraProvider>("legacy/0", /*maxThreads*/ 6);
}
diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
index e37f989..b7ce858 100644
--- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
+++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
@@ -2493,7 +2493,7 @@
outputBuffer};
StreamBuffer emptyInputBuffer = {-1, 0, nullptr,
BufferStatus::ERROR, nullptr, nullptr};
- CaptureRequest request = {frameNumber, settings,
+ CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings,
emptyInputBuffer, outputBuffers};
{
@@ -2599,7 +2599,7 @@
outputBuffer};
StreamBuffer emptyInputBuffer = {-1, 0, nullptr,
BufferStatus::ERROR, nullptr, nullptr};
- CaptureRequest request = {frameNumber, settings,
+ CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings,
emptyInputBuffer, outputBuffers};
//Settings were not correctly initialized, we should fail here
@@ -2654,7 +2654,7 @@
::android::hardware::hidl_vec<StreamBuffer> emptyOutputBuffers;
StreamBuffer emptyInputBuffer = {-1, 0, nullptr,
BufferStatus::ERROR, nullptr, nullptr};
- CaptureRequest request = {frameNumber, settings,
+ CaptureRequest request = {frameNumber, 0/* fmqSettingsSize */, settings,
emptyInputBuffer, emptyOutputBuffers};
//Output buffers are missing, we should fail here
@@ -2719,7 +2719,7 @@
outputBuffer};
const StreamBuffer emptyInputBuffer = {-1, 0, nullptr,
BufferStatus::ERROR, nullptr, nullptr};
- CaptureRequest request = {frameNumber, settings,
+ CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings,
emptyInputBuffer, outputBuffers};
{
diff --git a/configstore/1.0/Android.mk b/configstore/1.0/Android.mk
index 010d509..6be99db 100644
--- a/configstore/1.0/Android.mk
+++ b/configstore/1.0/Android.mk
@@ -5,7 +5,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.configstore@1.0-java
+LOCAL_MODULE := android.hardware.configstore-V1.0-java
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -13,7 +13,7 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_JAVA_LIBRARIES := \
- android.hidl.base@1.0-java \
+ android.hidl.base-V1.0-java \
#
@@ -156,7 +156,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.configstore@1.0-java-static
+LOCAL_MODULE := android.hardware.configstore-V1.0-java-static
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -164,7 +164,7 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_STATIC_JAVA_LIBRARIES := \
- android.hidl.base@1.0-java-static \
+ android.hidl.base-V1.0-java-static \
#
diff --git a/configstore/1.0/vts/functional/Android.bp b/configstore/1.0/vts/functional/Android.bp
new file mode 100644
index 0000000..1775538
--- /dev/null
+++ b/configstore/1.0/vts/functional/Android.bp
@@ -0,0 +1,34 @@
+//
+// Copyright (C) 2017 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: "VtsHalConfigstoreV1_0TargetTest",
+ defaults: ["hidl_defaults"],
+ srcs: ["VtsHalConfigstoreV1_0TargetTest.cpp"],
+ shared_libs: [
+ "libbase",
+ "libhidlbase",
+ "liblog",
+ "libutils",
+ "android.hardware.configstore@1.0",
+ ],
+ static_libs: ["VtsHalHidlTargetTestBase"],
+ cflags: [
+ "-O0",
+ "-g",
+ ]
+}
+
diff --git a/configstore/1.0/vts/functional/VtsHalConfigstoreV1_0TargetTest.cpp b/configstore/1.0/vts/functional/VtsHalConfigstoreV1_0TargetTest.cpp
new file mode 100644
index 0000000..95cd30b
--- /dev/null
+++ b/configstore/1.0/vts/functional/VtsHalConfigstoreV1_0TargetTest.cpp
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2017 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 "ConfigstoreHidlHalTest"
+
+#include <VtsHalHidlTargetTestBase.h>
+#include <android-base/logging.h>
+#include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
+#include <android/hardware/configstore/1.0/types.h>
+#include <unistd.h>
+
+using ::android::hardware::configstore::V1_0::ISurfaceFlingerConfigs;
+using ::android::hardware::configstore::V1_0::OptionalBool;
+using ::android::hardware::configstore::V1_0::OptionalInt64;
+using ::android::hardware::configstore::V1_0::OptionalUInt64;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+#define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk())
+#define EXPECT_OK(ret) EXPECT_TRUE(ret.isOk())
+
+class ConfigstoreHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+ public:
+ sp<ISurfaceFlingerConfigs> sfConfigs;
+
+ virtual void SetUp() override {
+ sfConfigs = ::testing::VtsHalHidlTargetTestBase::getService<
+ ISurfaceFlingerConfigs>();
+ }
+
+ virtual void TearDown() override {}
+};
+
+/**
+ * Ensure all ISurfaceFlingerConfigs.hal function calls are successful.
+ */
+TEST_F(ConfigstoreHidlTest, TestFunctionCalls) {
+ bool tmp;
+
+ Return<void> status = sfConfigs->vsyncEventPhaseOffsetNs(
+ [&tmp](OptionalInt64 arg) { tmp = arg.specified; });
+ EXPECT_OK(status);
+
+ status = sfConfigs->vsyncSfEventPhaseOffsetNs(
+ [&tmp](OptionalInt64 arg) { tmp = arg.specified; });
+ EXPECT_OK(status);
+
+ status = sfConfigs->useContextPriority(
+ [&tmp](OptionalBool arg) { tmp = arg.specified; });
+ EXPECT_OK(status);
+
+ status = sfConfigs->hasWideColorDisplay(
+ [&tmp](OptionalBool arg) { tmp = arg.specified; });
+ EXPECT_OK(status);
+
+ status = sfConfigs->hasHDRDisplay(
+ [&tmp](OptionalBool arg) { tmp = arg.specified; });
+ EXPECT_OK(status);
+
+ status = sfConfigs->presentTimeOffsetFromVSyncNs(
+ [&tmp](OptionalInt64 arg) { tmp = arg.specified; });
+ EXPECT_OK(status);
+
+ status = sfConfigs->useHwcForRGBtoYUV(
+ [&tmp](OptionalBool arg) { tmp = arg.specified; });
+ EXPECT_OK(status);
+
+ status = sfConfigs->maxVirtualDisplaySize(
+ [&tmp](OptionalUInt64 arg) { tmp = arg.specified; });
+ EXPECT_OK(status);
+
+ status = sfConfigs->hasSyncFramework(
+ [&tmp](OptionalBool arg) { tmp = arg.specified; });
+ EXPECT_OK(status);
+
+ status = sfConfigs->useVrFlinger(
+ [&tmp](OptionalBool arg) { tmp = arg.specified; });
+ EXPECT_OK(status);
+
+ status = sfConfigs->maxFrameBufferAcquiredBuffers(
+ [&tmp](OptionalInt64 arg) { tmp = arg.specified; });
+ EXPECT_OK(status);
+
+ status = sfConfigs->startGraphicsAllocatorService(
+ [&tmp](OptionalBool arg) { tmp = arg.specified; });
+ EXPECT_OK(status);
+}
+
+/**
+ * Ensure repeated call to the same function returns the same result.
+ */
+TEST_F(ConfigstoreHidlTest, TestSameReturnValue) {
+ int64_t original_ret;
+ Return<void> status = sfConfigs->vsyncEventPhaseOffsetNs(
+ [&original_ret](OptionalInt64 arg) { original_ret = arg.value; });
+
+ int64_t next_ret;
+ for (int cnt = 0; cnt < 10; cnt++) {
+ status = sfConfigs->vsyncEventPhaseOffsetNs(
+ [&next_ret](OptionalInt64 arg) { next_ret = arg.value; });
+ EXPECT_EQ(original_ret, next_ret);
+ }
+}
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ int status = RUN_ALL_TESTS();
+ LOG(INFO) << "Test result = " << status;
+ return status;
+}
diff --git a/configstore/Android.bp b/configstore/Android.bp
index 79b63f6..ba3e62e 100644
--- a/configstore/Android.bp
+++ b/configstore/Android.bp
@@ -1,5 +1,6 @@
// This is an autogenerated file, do not edit.
subdirs = [
"1.0",
+ "1.0/vts/functional",
"utils",
]
diff --git a/contexthub/1.0/Android.mk b/contexthub/1.0/Android.mk
index a053986..d161e3b 100644
--- a/contexthub/1.0/Android.mk
+++ b/contexthub/1.0/Android.mk
@@ -5,7 +5,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.contexthub@1.0-java
+LOCAL_MODULE := android.hardware.contexthub-V1.0-java
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -13,7 +13,7 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_JAVA_LIBRARIES := \
- android.hidl.base@1.0-java \
+ android.hidl.base-V1.0-java \
#
@@ -331,7 +331,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.contexthub@1.0-java-static
+LOCAL_MODULE := android.hardware.contexthub-V1.0-java-static
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -339,7 +339,7 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_STATIC_JAVA_LIBRARIES := \
- android.hidl.base@1.0-java-static \
+ android.hidl.base-V1.0-java-static \
#
diff --git a/contexthub/1.0/default/Android.mk b/contexthub/1.0/default/Android.mk
index 538a6b2..917bfe0 100644
--- a/contexthub/1.0/default/Android.mk
+++ b/contexthub/1.0/default/Android.mk
@@ -13,7 +13,6 @@
libcutils \
libdl \
libhardware \
- libhardware_legacy \
libhidlbase \
libhidltransport \
liblog \
diff --git a/drm/1.0/default/Android.mk b/drm/1.0/default/Android.mk
index 23a4506..7602399 100644
--- a/drm/1.0/default/Android.mk
+++ b/drm/1.0/default/Android.mk
@@ -34,6 +34,7 @@
libhardware \
liblog \
libutils \
+ libbinder \
LOCAL_C_INCLUDES := \
hardware/interfaces/drm
diff --git a/drm/1.0/default/service.cpp b/drm/1.0/default/service.cpp
index 823f39e..1a44ce2 100644
--- a/drm/1.0/default/service.cpp
+++ b/drm/1.0/default/service.cpp
@@ -21,6 +21,8 @@
#include <hidl/HidlTransportSupport.h>
#include <hidl/LegacySupport.h>
+#include <binder/ProcessState.h>
+
using android::hardware::configureRpcThreadpool;
using android::hardware::joinRpcThreadpool;
using android::hardware::registerPassthroughServiceImplementation;
@@ -30,6 +32,11 @@
int main() {
ALOGD("android.hardware.drm@1.0-service starting...");
+
+ // The DRM HAL may communicate to other vendor components via
+ // /dev/vndbinder
+ android::ProcessState::initWithDriver("/dev/vndbinder");
+
configureRpcThreadpool(8, true /* callerWillJoin */);
android::status_t status =
registerPassthroughServiceImplementation<IDrmFactory>();
diff --git a/drm/1.0/vts/functional/drm_hal_clearkey_test.cpp b/drm/1.0/vts/functional/drm_hal_clearkey_test.cpp
index 7955813..2947d2e 100644
--- a/drm/1.0/vts/functional/drm_hal_clearkey_test.cpp
+++ b/drm/1.0/vts/functional/drm_hal_clearkey_test.cpp
@@ -244,6 +244,7 @@
SessionId openSession();
void closeSession(const SessionId& sessionId);
+ hidl_vec<uint8_t> loadKeys(const SessionId& sessionId, const KeyType& type);
sp<IMemory> getDecryptMemory(size_t size, size_t index);
protected:
@@ -312,6 +313,70 @@
}
/**
+ * Helper method to load keys for subsequent decrypt tests.
+ * These tests use predetermined key request/response to
+ * avoid requiring a round trip to a license server.
+ */
+hidl_vec<uint8_t> DrmHalClearkeyPluginTest::loadKeys(
+ const SessionId& sessionId, const KeyType& type = KeyType::STREAMING) {
+ hidl_vec<uint8_t> initData = {
+ // BMFF box header (4 bytes size + 'pssh')
+ 0x00, 0x00, 0x00, 0x34, 0x70, 0x73, 0x73, 0x68,
+ // full box header (version = 1 flags = 0)
+ 0x01, 0x00, 0x00, 0x00,
+ // system id
+ 0x10, 0x77, 0xef, 0xec, 0xc0, 0xb2, 0x4d, 0x02, 0xac, 0xe3, 0x3c, 0x1e,
+ 0x52, 0xe2, 0xfb, 0x4b,
+ // number of key ids
+ 0x00, 0x00, 0x00, 0x01,
+ // key id
+ 0x60, 0x06, 0x1e, 0x01, 0x7e, 0x47, 0x7e, 0x87, 0x7e, 0x57, 0xd0, 0x0d,
+ 0x1e, 0xd0, 0x0d, 0x1e,
+ // size of data, must be zero
+ 0x00, 0x00, 0x00, 0x00};
+
+ hidl_vec<uint8_t> expectedKeyRequest = {
+ 0x7b, 0x22, 0x6b, 0x69, 0x64, 0x73, 0x22, 0x3a, 0x5b, 0x22, 0x59,
+ 0x41, 0x59, 0x65, 0x41, 0x58, 0x35, 0x48, 0x66, 0x6f, 0x64, 0x2b,
+ 0x56, 0x39, 0x41, 0x4e, 0x48, 0x74, 0x41, 0x4e, 0x48, 0x67, 0x22,
+ 0x5d, 0x2c, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x22, 0x74,
+ 0x65, 0x6d, 0x70, 0x6f, 0x72, 0x61, 0x72, 0x79, 0x22, 0x7d};
+
+ hidl_vec<uint8_t> knownKeyResponse = {
+ 0x7b, 0x22, 0x6b, 0x65, 0x79, 0x73, 0x22, 0x3a, 0x5b, 0x7b, 0x22,
+ 0x6b, 0x74, 0x79, 0x22, 0x3a, 0x22, 0x6f, 0x63, 0x74, 0x22, 0x2c,
+ 0x22, 0x6b, 0x69, 0x64, 0x22, 0x3a, 0x22, 0x59, 0x41, 0x59, 0x65,
+ 0x41, 0x58, 0x35, 0x48, 0x66, 0x6f, 0x64, 0x2b, 0x56, 0x39, 0x41,
+ 0x4e, 0x48, 0x74, 0x41, 0x4e, 0x48, 0x67, 0x22, 0x2c, 0x22, 0x6b,
+ 0x22, 0x3a, 0x22, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x54, 0x65,
+ 0x73, 0x74, 0x4b, 0x65, 0x79, 0x42, 0x61, 0x73, 0x65, 0x36, 0x34,
+ 0x67, 0x67, 0x67, 0x22, 0x7d, 0x5d, 0x7d, 0x0a};
+
+ hidl_string mimeType = "video/mp4";
+ KeyedVector optionalParameters;
+ auto res = drmPlugin->getKeyRequest(
+ sessionId, initData, mimeType, type, optionalParameters,
+ [&](Status status, const hidl_vec<uint8_t>& request,
+ KeyRequestType requestType, const hidl_string&) {
+ EXPECT_EQ(Status::OK, status);
+ EXPECT_EQ(KeyRequestType::INITIAL, requestType);
+ EXPECT_EQ(request, expectedKeyRequest);
+ });
+ EXPECT_OK(res);
+
+ hidl_vec<uint8_t> keySetId;
+ res = drmPlugin->provideKeyResponse(
+ sessionId, knownKeyResponse,
+ [&](Status status, const hidl_vec<uint8_t>& myKeySetId) {
+ EXPECT_EQ(Status::OK, status);
+ EXPECT_EQ(0u, myKeySetId.size());
+ keySetId = myKeySetId;
+ });
+ EXPECT_OK(res);
+ return keySetId;
+}
+
+/**
* Test that a session can be opened and closed
*/
TEST_F(DrmHalClearkeyPluginTest, OpenCloseSession) {
@@ -470,6 +535,30 @@
}
/**
+ * Test that ClearKey cannot handle key restoring.
+ * Expected message is Status::ERROR_DRM_CANNOT_HANDLE.
+ */
+TEST_F(DrmHalClearkeyPluginTest, RestoreKeysCannotHandle) {
+ hidl_vec<uint8_t> keySetId = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
+ SessionId sessionId = openSession();
+ Status status = drmPlugin->restoreKeys(sessionId, keySetId);
+ EXPECT_EQ(Status::ERROR_DRM_CANNOT_HANDLE, status);
+ closeSession(sessionId);
+}
+
+/**
+ * Test that restoreKeys fails with a null key set ID.
+ * Error message is expected to be Status::BAD_VALUE.
+ */
+TEST_F(DrmHalClearkeyPluginTest, RestoreKeysNull) {
+ SessionId sessionId = openSession();
+ hidl_vec<uint8_t> nullKeySetId;
+ Status status = drmPlugin->restoreKeys(sessionId, nullKeySetId);
+ EXPECT_EQ(Status::BAD_VALUE, status);
+ closeSession(sessionId);
+}
+
+/**
* Test that the clearkey plugin doesn't support getting
* secure stops.
*/
@@ -830,7 +919,6 @@
class DrmHalClearkeyDecryptTest : public DrmHalClearkeyPluginTest {
public:
- void loadKeys(const SessionId& sessionId);
void fillRandom(const sp<IMemory>& memory);
hidl_array<uint8_t, 16> toHidlArray(const vector<uint8_t>& vec) {
EXPECT_EQ(16u, vec.size());
@@ -844,67 +932,6 @@
const hidl_vec<SubSample>& subSamples, const vector<uint8_t>& key);
};
-/**
- * Helper method to load keys for subsequent decrypt tests.
- * These tests use predetermined key request/response to
- * avoid requiring a round trip to a license server.
- */
-void DrmHalClearkeyDecryptTest::loadKeys(const SessionId& sessionId) {
- hidl_vec<uint8_t> initData = {
- // BMFF box header (4 bytes size + 'pssh')
- 0x00, 0x00, 0x00, 0x34, 0x70, 0x73, 0x73, 0x68,
- // full box header (version = 1 flags = 0)
- 0x01, 0x00, 0x00, 0x00,
- // system id
- 0x10, 0x77, 0xef, 0xec, 0xc0, 0xb2, 0x4d, 0x02, 0xac, 0xe3, 0x3c,
- 0x1e, 0x52, 0xe2, 0xfb, 0x4b,
- // number of key ids
- 0x00, 0x00, 0x00, 0x01,
- // key id
- 0x60, 0x06, 0x1e, 0x01, 0x7e, 0x47, 0x7e, 0x87, 0x7e, 0x57, 0xd0,
- 0x0d, 0x1e, 0xd0, 0x0d, 0x1e,
- // size of data, must be zero
- 0x00, 0x00, 0x00, 0x00};
-
- hidl_vec<uint8_t> expectedKeyRequest = {
- 0x7b, 0x22, 0x6b, 0x69, 0x64, 0x73, 0x22, 0x3a, 0x5b, 0x22, 0x59,
- 0x41, 0x59, 0x65, 0x41, 0x58, 0x35, 0x48, 0x66, 0x6f, 0x64, 0x2b,
- 0x56, 0x39, 0x41, 0x4e, 0x48, 0x74, 0x41, 0x4e, 0x48, 0x67, 0x22,
- 0x5d, 0x2c, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x22, 0x74,
- 0x65, 0x6d, 0x70, 0x6f, 0x72, 0x61, 0x72, 0x79, 0x22, 0x7d};
-
- hidl_vec<uint8_t> knownKeyResponse = {
- 0x7b, 0x22, 0x6b, 0x65, 0x79, 0x73, 0x22, 0x3a, 0x5b, 0x7b, 0x22,
- 0x6b, 0x74, 0x79, 0x22, 0x3a, 0x22, 0x6f, 0x63, 0x74, 0x22, 0x2c,
- 0x22, 0x6b, 0x69, 0x64, 0x22, 0x3a, 0x22, 0x59, 0x41, 0x59, 0x65,
- 0x41, 0x58, 0x35, 0x48, 0x66, 0x6f, 0x64, 0x2b, 0x56, 0x39, 0x41,
- 0x4e, 0x48, 0x74, 0x41, 0x4e, 0x48, 0x67, 0x22, 0x2c, 0x22, 0x6b,
- 0x22, 0x3a, 0x22, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x54, 0x65,
- 0x73, 0x74, 0x4b, 0x65, 0x79, 0x42, 0x61, 0x73, 0x65, 0x36, 0x34,
- 0x67, 0x67, 0x67, 0x22, 0x7d, 0x5d, 0x7d, 0x0a};
-
- hidl_string mimeType = "video/mp4";
- KeyedVector optionalParameters;
- auto res = drmPlugin->getKeyRequest(
- sessionId, initData, mimeType, KeyType::STREAMING,
- optionalParameters,
- [&](Status status, const hidl_vec<uint8_t>& request,
- KeyRequestType requestType, const hidl_string&) {
- EXPECT_EQ(Status::OK, status);
- EXPECT_EQ(KeyRequestType::INITIAL, requestType);
- EXPECT_EQ(request, expectedKeyRequest);
- });
- EXPECT_OK(res);
-
- res = drmPlugin->provideKeyResponse(
- sessionId, knownKeyResponse,
- [&](Status status, const hidl_vec<uint8_t>& keySetId) {
- EXPECT_EQ(Status::OK, status);
- EXPECT_EQ(0u, keySetId.size());
- });
- EXPECT_OK(res);
-}
-
void DrmHalClearkeyDecryptTest::fillRandom(const sp<IMemory>& memory) {
random_device rd;
mt19937 rand(rd());
diff --git a/drm/1.0/vts/functional/drm_hal_vendor_module_api.h b/drm/1.0/vts/functional/drm_hal_vendor_module_api.h
index 73e0cfe..b8b2052 100644
--- a/drm/1.0/vts/functional/drm_hal_vendor_module_api.h
+++ b/drm/1.0/vts/functional/drm_hal_vendor_module_api.h
@@ -65,7 +65,7 @@
class DrmHalVTSVendorModule {
public:
- DrmHalVTSVendorModule() {}
+ DrmHalVTSVendorModule() : installed(true) {}
virtual ~DrmHalVTSVendorModule() {}
/**
@@ -89,7 +89,15 @@
*/
virtual std::string getServiceName() const = 0;
+ /**
+ * Set a flag in the vendor module to indicate whether or not the drm
+ * scheme corresponding to this module is installed on the device.
+ */
+ void setInstalled(bool flag) {installed = flag;}
+ bool isInstalled() const {return installed;}
+
private:
+ bool installed;
DrmHalVTSVendorModule(const DrmHalVTSVendorModule&) = delete;
void operator=(const DrmHalVTSVendorModule&) = delete;
};
@@ -158,17 +166,30 @@
const std::map<std::string, std::string> optionalParameters;
/**
+ * Define license policy attributes for the content configuration.
+ * These attributes can affect which tests are able to be applied.
+ */
+ struct Policy {
+ /**
+ * Indicate if the license policy allows offline playback.
+ * Content configurated with this policy supports KeyType::OFFLINE
+ * key requests/responses. A vendor module should provide at least
+ * one content configuration where allowOffline is true if the drm
+ * scheme supports offline content.
+ */
+ bool allowOffline;
+ } policy;
+
+ /**
* The keys that will be available once the keys are loaded
*/
struct Key {
/**
* Indicate if the key content is configured to require secure
- * buffers,
- * where the output buffers are protected and cannot be accessed.
- * A vendor module should provide some content configurations where
- * isSecure is false, to allow decrypt result verification tests to
- * be
- * run.
+ * buffers, where the output buffers are protected and cannot be
+ * accessed by the non-secure cpu. A vendor module should provide
+ * at least one content configurations where isSecure is false, to
+ * allow decrypt result verification tests to be run.
*/
bool isSecure;
diff --git a/drm/1.0/vts/functional/drm_hal_vendor_test.cpp b/drm/1.0/vts/functional/drm_hal_vendor_test.cpp
index 4d9e1fc..2290df1 100644
--- a/drm/1.0/vts/functional/drm_hal_vendor_test.cpp
+++ b/drm/1.0/vts/functional/drm_hal_vendor_test.cpp
@@ -82,6 +82,14 @@
#define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk())
#define EXPECT_OK(ret) EXPECT_TRUE(ret.isOk())
+#define RETURN_IF_SKIPPED \
+ if (!vendorModule->isInstalled()) { \
+ std::cout << "[ SKIPPED ] This drm scheme not supported." << \
+ " library:" << GetParam() << " service-name:" << \
+ vendorModule->getServiceName() << std::endl; \
+ return; \
+ }
+
static const uint8_t kInvalidUUID[16] = {
0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80,
0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80,
@@ -123,6 +131,12 @@
VtsTestBase::getService<ICryptoFactory>();
}
ASSERT_NE(cryptoFactory, nullptr);
+
+ // If drm scheme not installed skip subsequent tests
+ if (!drmFactory->isCryptoSchemeSupported(getVendorUUID())) {
+ vendorModule->setInstalled(false);
+ return;
+ }
}
virtual void TearDown() override {}
@@ -141,6 +155,7 @@
TEST_P(DrmHalVendorFactoryTest, ValidateConfigurations) {
const char* kVendorStr = "Vendor module ";
+ size_t count = 0;
for (auto config : contentConfigurations) {
ASSERT_TRUE(config.name.size() > 0) << kVendorStr << "has no name";
ASSERT_TRUE(config.serverUrl.size() > 0) << kVendorStr
@@ -156,7 +171,9 @@
ASSERT_TRUE(key.keyId.size() > 0) << kVendorStr
<< " has zero length key value";
}
+ count++;
}
+ EXPECT_NE(0u, count);
}
/**
@@ -177,9 +194,10 @@
}
/**
- * Ensure the factory supports the scheme uuid in the config
+ * Check if the factory supports the scheme uuid in the config.
*/
-TEST_P(DrmHalVendorFactoryTest, EmptyPluginConfigUUIDSupported) {
+TEST_P(DrmHalVendorFactoryTest, PluginConfigUUIDSupported) {
+ RETURN_IF_SKIPPED;
EXPECT_TRUE(drmFactory->isCryptoSchemeSupported(getVendorUUID()));
EXPECT_TRUE(cryptoFactory->isCryptoSchemeSupported(getVendorUUID()));
}
@@ -204,6 +222,7 @@
* Ensure valid content types in the configs are supported
*/
TEST_P(DrmHalVendorFactoryTest, ValidContentTypeSupported) {
+ RETURN_IF_SKIPPED;
for (auto config : contentConfigurations) {
EXPECT_TRUE(drmFactory->isContentTypeSupported(config.mimeType));
}
@@ -213,6 +232,7 @@
* Ensure vendor drm plugin can be created
*/
TEST_P(DrmHalVendorFactoryTest, CreateVendorDrmPlugin) {
+ RETURN_IF_SKIPPED;
hidl_string packageName("android.hardware.drm.test");
auto res = drmFactory->createPlugin(
getVendorUUID(), packageName,
@@ -227,6 +247,7 @@
* Ensure vendor crypto plugin can be created
*/
TEST_P(DrmHalVendorFactoryTest, CreateVendorCryptoPlugin) {
+ RETURN_IF_SKIPPED;
hidl_vec<uint8_t> initVec;
auto res = cryptoFactory->createPlugin(
getVendorUUID(), initVec,
@@ -241,6 +262,7 @@
* Ensure invalid drm plugin can't be created
*/
TEST_P(DrmHalVendorFactoryTest, CreateInvalidDrmPlugin) {
+ RETURN_IF_SKIPPED;
hidl_string packageName("android.hardware.drm.test");
auto res = drmFactory->createPlugin(
kInvalidUUID, packageName,
@@ -255,6 +277,7 @@
* Ensure invalid crypto plugin can't be created
*/
TEST_P(DrmHalVendorFactoryTest, CreateInvalidCryptoPlugin) {
+ RETURN_IF_SKIPPED;
hidl_vec<uint8_t> initVec;
auto res = cryptoFactory->createPlugin(
kInvalidUUID, initVec,
@@ -271,6 +294,7 @@
virtual void SetUp() override {
// Create factories
DrmHalVendorFactoryTest::SetUp();
+ RETURN_IF_SKIPPED;
hidl_string packageName("android.hardware.drm.test");
auto res = drmFactory->createPlugin(
@@ -298,6 +322,10 @@
SessionId openSession();
void closeSession(const SessionId& sessionId);
sp<IMemory> getDecryptMemory(size_t size, size_t index);
+ KeyedVector toHidlKeyedVector(const map<string, string>& params);
+ hidl_vec<uint8_t> loadKeys(const SessionId& sessionId,
+ const ContentConfiguration& configuration,
+ const KeyType& type);
protected:
sp<IDrmPlugin> drmPlugin;
@@ -318,6 +346,7 @@
*/
TEST_P(DrmHalVendorPluginTest, DoProvisioning) {
+ RETURN_IF_SKIPPED;
hidl_string certificateType;
hidl_string certificateAuthority;
hidl_vec<uint8_t> provisionRequest;
@@ -355,6 +384,7 @@
* response is provided.
*/
TEST_P(DrmHalVendorPluginTest, ProvideEmptyProvisionResponse) {
+ RETURN_IF_SKIPPED;
hidl_vec<uint8_t> response;
auto res = drmPlugin->provideProvisionResponse(
response, [&](Status status, const hidl_vec<uint8_t>&,
@@ -388,10 +418,69 @@
EXPECT_EQ(Status::OK, status);
}
+KeyedVector DrmHalVendorPluginTest::toHidlKeyedVector(
+ const map<string, string>& params) {
+ std::vector<KeyValue> stdKeyedVector;
+ for (auto it = params.begin(); it != params.end(); ++it) {
+ KeyValue keyValue;
+ keyValue.key = it->first;
+ keyValue.value = it->second;
+ stdKeyedVector.push_back(keyValue);
+ }
+ return KeyedVector(stdKeyedVector);
+}
+
+/**
+ * Helper method to load keys for subsequent decrypt tests.
+ * These tests use predetermined key request/response to
+ * avoid requiring a round trip to a license server.
+ */
+hidl_vec<uint8_t> DrmHalVendorPluginTest::loadKeys(
+ const SessionId& sessionId, const ContentConfiguration& configuration,
+ const KeyType& type = KeyType::STREAMING) {
+ hidl_vec<uint8_t> keyRequest;
+ auto res = drmPlugin->getKeyRequest(
+ sessionId, configuration.initData, configuration.mimeType, type,
+ toHidlKeyedVector(configuration.optionalParameters),
+ [&](Status status, const hidl_vec<uint8_t>& request,
+ KeyRequestType type, const hidl_string&) {
+ EXPECT_EQ(Status::OK, status) << "Failed to get "
+ "key request for configuration "
+ << configuration.name;
+ EXPECT_EQ(type, KeyRequestType::INITIAL);
+ EXPECT_NE(request.size(), 0u) << "Expected key request size"
+ " to have length > 0 bytes";
+ keyRequest = request;
+ });
+ EXPECT_OK(res);
+
+ /**
+ * Get key response from vendor module
+ */
+ hidl_vec<uint8_t> keyResponse =
+ vendorModule->handleKeyRequest(keyRequest, configuration.serverUrl);
+
+ EXPECT_NE(keyResponse.size(), 0u) << "Expected key response size "
+ "to have length > 0 bytes";
+
+ hidl_vec<uint8_t> keySetId;
+ res = drmPlugin->provideKeyResponse(
+ sessionId, keyResponse,
+ [&](Status status, const hidl_vec<uint8_t>& myKeySetId) {
+ EXPECT_EQ(Status::OK, status) << "Failure providing "
+ "key response for configuration "
+ << configuration.name;
+ keySetId = myKeySetId;
+ });
+ EXPECT_OK(res);
+ return keySetId;
+}
+
/**
* Test that a session can be opened and closed
*/
TEST_P(DrmHalVendorPluginTest, OpenCloseSession) {
+ RETURN_IF_SKIPPED;
auto sessionId = openSession();
closeSession(sessionId);
}
@@ -401,6 +490,7 @@
* is prohibited with the documented error code.
*/
TEST_P(DrmHalVendorPluginTest, CloseInvalidSession) {
+ RETURN_IF_SKIPPED;
SessionId invalidSessionId;
Status status = drmPlugin->closeSession(invalidSessionId);
EXPECT_EQ(Status::BAD_VALUE, status);
@@ -411,6 +501,7 @@
* is prohibited with the documented error code.
*/
TEST_P(DrmHalVendorPluginTest, CloseClosedSession) {
+ RETURN_IF_SKIPPED;
auto sessionId = openSession();
closeSession(sessionId);
Status status = drmPlugin->closeSession(sessionId);
@@ -421,6 +512,7 @@
* A get key request should fail if no sessionId is provided
*/
TEST_P(DrmHalVendorPluginTest, GetKeyRequestNoSession) {
+ RETURN_IF_SKIPPED;
SessionId invalidSessionId;
hidl_vec<uint8_t> initData;
hidl_string mimeType = "video/mp4";
@@ -437,6 +529,7 @@
* Test that an empty sessionID returns BAD_VALUE
*/
TEST_P(DrmHalVendorPluginTest, ProvideKeyResponseEmptySessionId) {
+ RETURN_IF_SKIPPED;
SessionId session;
hidl_vec<uint8_t> keyResponse = {0x7b, 0x22, 0x6b, 0x65,
@@ -454,6 +547,7 @@
* Test that an empty key response returns BAD_VALUE
*/
TEST_P(DrmHalVendorPluginTest, ProvideKeyResponseEmptyResponse) {
+ RETURN_IF_SKIPPED;
SessionId session = openSession();
hidl_vec<uint8_t> emptyResponse;
auto res = drmPlugin->provideKeyResponse(
@@ -470,6 +564,7 @@
* Test that a removeKeys on an empty sessionID returns BAD_VALUE
*/
TEST_P(DrmHalVendorPluginTest, RemoveKeysEmptySessionId) {
+ RETURN_IF_SKIPPED;
SessionId sessionId;
Status status = drmPlugin->removeKeys(sessionId);
EXPECT_TRUE(status == Status::BAD_VALUE);
@@ -480,6 +575,7 @@
* that has no keys.
*/
TEST_P(DrmHalVendorPluginTest, RemoveKeysNewSession) {
+ RETURN_IF_SKIPPED;
SessionId sessionId = openSession();
Status status = drmPlugin->removeKeys(sessionId);
EXPECT_TRUE(status == Status::OK);
@@ -487,11 +583,68 @@
}
/**
+ * Test that keys are successfully restored to a new session
+ * for all content having a policy that allows offline use.
+ */
+TEST_P(DrmHalVendorPluginTest, RestoreKeys) {
+ RETURN_IF_SKIPPED;
+ for (auto config : contentConfigurations) {
+ if (config.policy.allowOffline) {
+ auto sessionId = openSession();
+ hidl_vec<uint8_t> keySetId =
+ loadKeys(sessionId, config, KeyType::OFFLINE);
+ closeSession(sessionId);
+ sessionId = openSession();
+ EXPECT_NE(0u, keySetId.size());
+ Status status = drmPlugin->restoreKeys(sessionId, keySetId);
+ EXPECT_EQ(Status::OK, status);
+ closeSession(sessionId);
+ }
+ }
+}
+
+/**
+ * Test that restoreKeys fails with a null key set ID.
+ * Error message is expected to be Status::BAD_VALUE.
+ */
+TEST_P(DrmHalVendorPluginTest, RestoreKeysNull) {
+ RETURN_IF_SKIPPED;
+ SessionId sessionId = openSession();
+ hidl_vec<uint8_t> nullKeySetId;
+ Status status = drmPlugin->restoreKeys(sessionId, nullKeySetId);
+ EXPECT_EQ(Status::BAD_VALUE, status);
+ closeSession(sessionId);
+}
+
+/**
+ * Test that restoreKeys fails to restore keys to a closed
+ * session. Error message is expected to be
+ * Status::ERROR_DRM_SESSION_NOT_OPENED.
+ */
+TEST_P(DrmHalVendorPluginTest, RestoreKeysClosedSession) {
+ RETURN_IF_SKIPPED;
+ for (auto config : contentConfigurations) {
+ if (config.policy.allowOffline) {
+ auto sessionId = openSession();
+ hidl_vec<uint8_t> keySetId =
+ loadKeys(sessionId, config, KeyType::OFFLINE);
+ EXPECT_NE(0u, keySetId.size());
+ closeSession(sessionId);
+ sessionId = openSession();
+ closeSession(sessionId);
+ Status status = drmPlugin->restoreKeys(sessionId, keySetId);
+ EXPECT_EQ(Status::ERROR_DRM_SESSION_NOT_OPENED, status);
+ }
+ }
+}
+
+/**
* Test that the plugin either doesn't support getting
* secure stops, or has no secure stops available after
* clearing them.
*/
TEST_P(DrmHalVendorPluginTest, GetSecureStops) {
+ RETURN_IF_SKIPPED;
// There may be secure stops, depending on if there were keys
// loaded and unloaded previously. Clear them to get to a known
// state, then make sure there are none.
@@ -519,6 +672,7 @@
* an empty ssid is provided.
*/
TEST_P(DrmHalVendorPluginTest, GetSecureStopEmptySSID) {
+ RETURN_IF_SKIPPED;
SecureStopId ssid;
auto res = drmPlugin->getSecureStop(
ssid, [&](Status status, const SecureStop&) {
@@ -532,6 +686,7 @@
* or is completed successfully
*/
TEST_P(DrmHalVendorPluginTest, ReleaseAllSecureStops) {
+ RETURN_IF_SKIPPED;
Status status = drmPlugin->releaseAllSecureStops();
EXPECT_TRUE(status == Status::OK ||
status == Status::ERROR_DRM_CANNOT_HANDLE);
@@ -543,6 +698,7 @@
* This is an optional API so it can also return CANNOT_HANDLE.
*/
TEST_P(DrmHalVendorPluginTest, ReleaseSecureStopSequenceError) {
+ RETURN_IF_SKIPPED;
SecureStopId ssid = {1, 2, 3, 4};
Status status = drmPlugin->releaseSecureStop(ssid);
EXPECT_TRUE(status == Status::ERROR_DRM_INVALID_STATE ||
@@ -555,6 +711,7 @@
* CANNOT_HANDLE.
*/
TEST_P(DrmHalVendorPluginTest, ReleaseSecureStopEmptySSID) {
+ RETURN_IF_SKIPPED;
SecureStopId ssid;
Status status = drmPlugin->releaseSecureStop(ssid);
EXPECT_TRUE(status == Status::BAD_VALUE ||
@@ -567,6 +724,7 @@
* the plugin.
*/
TEST_P(DrmHalVendorPluginTest, GetVendorProperty) {
+ RETURN_IF_SKIPPED;
auto res = drmPlugin->getPropertyString(
"vendor", [&](Status status, const hidl_string& value) {
EXPECT_EQ(Status::OK, status);
@@ -576,6 +734,7 @@
}
TEST_P(DrmHalVendorPluginTest, GetVersionProperty) {
+ RETURN_IF_SKIPPED;
auto res = drmPlugin->getPropertyString(
"version", [&](Status status, const hidl_string& value) {
EXPECT_EQ(Status::OK, status);
@@ -585,6 +744,7 @@
}
TEST_P(DrmHalVendorPluginTest, GetDescriptionProperty) {
+ RETURN_IF_SKIPPED;
auto res = drmPlugin->getPropertyString(
"description", [&](Status status, const hidl_string& value) {
EXPECT_EQ(Status::OK, status);
@@ -594,6 +754,7 @@
}
TEST_P(DrmHalVendorPluginTest, GetAlgorithmsProperty) {
+ RETURN_IF_SKIPPED;
auto res = drmPlugin->getPropertyString(
"algorithms", [&](Status status, const hidl_string& value) {
if (status == Status::OK) {
@@ -606,6 +767,7 @@
}
TEST_P(DrmHalVendorPluginTest, GetPropertyUniqueDeviceID) {
+ RETURN_IF_SKIPPED;
auto res = drmPlugin->getPropertyByteArray(
"deviceUniqueId",
[&](Status status, const hidl_vec<uint8_t>& value) {
@@ -623,6 +785,7 @@
* properties returns the documented error code.
*/
TEST_P(DrmHalVendorPluginTest, GetInvalidStringProperty) {
+ RETURN_IF_SKIPPED;
auto res = drmPlugin->getPropertyString(
"invalid", [&](Status status, const hidl_string&) {
EXPECT_EQ(Status::ERROR_DRM_CANNOT_HANDLE, status);
@@ -631,6 +794,7 @@
}
TEST_P(DrmHalVendorPluginTest, GetInvalidByteArrayProperty) {
+ RETURN_IF_SKIPPED;
auto res = drmPlugin->getPropertyByteArray(
"invalid", [&](Status status, const hidl_vec<uint8_t>&) {
EXPECT_EQ(Status::ERROR_DRM_CANNOT_HANDLE, status);
@@ -643,11 +807,13 @@
* the expected status value.
*/
TEST_P(DrmHalVendorPluginTest, SetStringPropertyNotSupported) {
+ RETURN_IF_SKIPPED;
EXPECT_EQ(drmPlugin->setPropertyString("awefijaeflijwef", "value"),
Status::ERROR_DRM_CANNOT_HANDLE);
}
TEST_P(DrmHalVendorPluginTest, SetByteArrayPropertyNotSupported) {
+ RETURN_IF_SKIPPED;
hidl_vec<uint8_t> value;
EXPECT_EQ(drmPlugin->setPropertyByteArray("awefijaeflijwef", value),
Status::ERROR_DRM_CANNOT_HANDLE);
@@ -658,6 +824,7 @@
* the expected status value.
*/
TEST_P(DrmHalVendorPluginTest, SetCipherInvalidAlgorithm) {
+ RETURN_IF_SKIPPED;
SessionId session = openSession();
hidl_string algorithm;
Status status = drmPlugin->setCipherAlgorithm(session, algorithm);
@@ -670,6 +837,7 @@
* the expected status value.
*/
TEST_P(DrmHalVendorPluginTest, SetCipherAlgorithmNoSession) {
+ RETURN_IF_SKIPPED;
SessionId session;
hidl_string algorithm = "AES/CBC/NoPadding";
Status status = drmPlugin->setCipherAlgorithm(session, algorithm);
@@ -683,6 +851,7 @@
* either accept it or return ERROR_DRM_CANNOT_HANDLE
*/
TEST_P(DrmHalVendorPluginTest, SetCipherAlgorithm) {
+ RETURN_IF_SKIPPED;
SessionId session = openSession();
;
hidl_string algorithm = "AES/CBC/NoPadding";
@@ -697,6 +866,7 @@
* the expected status value.
*/
TEST_P(DrmHalVendorPluginTest, SetMacInvalidAlgorithm) {
+ RETURN_IF_SKIPPED;
SessionId session = openSession();
hidl_string algorithm;
Status status = drmPlugin->setMacAlgorithm(session, algorithm);
@@ -709,6 +879,7 @@
* the expected status value.
*/
TEST_P(DrmHalVendorPluginTest, SetMacNullAlgorithmNoSession) {
+ RETURN_IF_SKIPPED;
SessionId session;
hidl_string algorithm = "HmacSHA256";
Status status = drmPlugin->setMacAlgorithm(session, algorithm);
@@ -722,6 +893,7 @@
* either accept it or return ERROR_DRM_CANNOT_HANDLE
*/
TEST_P(DrmHalVendorPluginTest, SetMacAlgorithm) {
+ RETURN_IF_SKIPPED;
SessionId session = openSession();
hidl_string algorithm = "HmacSHA256";
Status status = drmPlugin->setMacAlgorithm(session, algorithm);
@@ -742,6 +914,7 @@
* inputs, e.g. empty sessionId
*/
TEST_P(DrmHalVendorPluginTest, GenericEncryptNoSession) {
+ RETURN_IF_SKIPPED;
SessionId session;
hidl_vec<uint8_t> keyId, input, iv;
auto res = drmPlugin->encrypt(
@@ -753,6 +926,7 @@
}
TEST_P(DrmHalVendorPluginTest, GenericDecryptNoSession) {
+ RETURN_IF_SKIPPED;
SessionId session;
hidl_vec<uint8_t> keyId, input, iv;
auto res = drmPlugin->decrypt(
@@ -764,6 +938,7 @@
}
TEST_P(DrmHalVendorPluginTest, GenericSignNoSession) {
+ RETURN_IF_SKIPPED;
SessionId session;
hidl_vec<uint8_t> keyId, message;
auto res = drmPlugin->sign(
@@ -775,6 +950,7 @@
}
TEST_P(DrmHalVendorPluginTest, GenericVerifyNoSession) {
+ RETURN_IF_SKIPPED;
SessionId session;
hidl_vec<uint8_t> keyId, message, signature;
auto res = drmPlugin->verify(
@@ -785,6 +961,7 @@
}
TEST_P(DrmHalVendorPluginTest, GenericSignRSANoSession) {
+ RETURN_IF_SKIPPED;
SessionId session;
hidl_string algorithm;
hidl_vec<uint8_t> message, wrappedKey;
@@ -805,6 +982,7 @@
* Verify that requiresSecureDecoderComponent handles empty mimetype.
*/
TEST_P(DrmHalVendorPluginTest, RequiresSecureDecoderEmptyMimeType) {
+ RETURN_IF_SKIPPED;
EXPECT_FALSE(cryptoPlugin->requiresSecureDecoderComponent(""));
}
@@ -812,6 +990,7 @@
* Verify that requiresSecureDecoderComponent handles invalid mimetype.
*/
TEST_P(DrmHalVendorPluginTest, RequiresSecureDecoderInvalidMimeType) {
+ RETURN_IF_SKIPPED;
EXPECT_FALSE(cryptoPlugin->requiresSecureDecoderComponent("bad"));
}
@@ -820,7 +999,7 @@
* configurations
*/
TEST_P(DrmHalVendorPluginTest, RequiresSecureDecoderConfig) {
- const char* kVendorStr = "Vendor module ";
+ RETURN_IF_SKIPPED;
for (auto config : contentConfigurations) {
for (auto key : config.keys) {
if (key.isSecure) {
@@ -892,6 +1071,7 @@
* gets them.
*/
TEST_P(DrmHalVendorPluginTest, ListenerEvents) {
+ RETURN_IF_SKIPPED;
sp<TestDrmPluginListener> listener = new TestDrmPluginListener();
drmPlugin->setListener(listener);
auto sessionId = openSession();
@@ -918,6 +1098,7 @@
* the listener gets them.
*/
TEST_P(DrmHalVendorPluginTest, ListenerExpirationUpdate) {
+ RETURN_IF_SKIPPED;
sp<TestDrmPluginListener> listener = new TestDrmPluginListener();
drmPlugin->setListener(listener);
auto sessionId = openSession();
@@ -935,6 +1116,7 @@
* the listener gets them.
*/
TEST_P(DrmHalVendorPluginTest, ListenerKeysChange) {
+ RETURN_IF_SKIPPED;
sp<TestDrmPluginListener> listener = new TestDrmPluginListener();
drmPlugin->setListener(listener);
auto sessionId = openSession();
@@ -952,6 +1134,7 @@
EXPECT_TRUE(result.args);
EXPECT_EQ(sessionId, result.args->sessionId);
EXPECT_EQ(keyStatusList, result.args->keyStatusList);
+ closeSession(sessionId);
}
/**
@@ -959,6 +1142,7 @@
* listener set.
*/
TEST_P(DrmHalVendorPluginTest, NotListening) {
+ RETURN_IF_SKIPPED;
sp<TestDrmPluginListener> listener = new TestDrmPluginListener();
drmPlugin->setListener(listener);
drmPlugin->setListener(nullptr);
@@ -984,6 +1168,7 @@
* just call the method for coverage.
*/
TEST_P(DrmHalVendorPluginTest, NotifyResolution) {
+ RETURN_IF_SKIPPED;
cryptoPlugin->notifyResolution(1920, 1080);
}
@@ -1023,6 +1208,7 @@
* is used to associate a drm session with a crypto session.
*/
TEST_P(DrmHalVendorPluginTest, SetMediaDrmSession) {
+ RETURN_IF_SKIPPED;
auto sessionId = openSession();
Status status = cryptoPlugin->setMediaDrmSession(sessionId);
EXPECT_EQ(Status::OK, status);
@@ -1033,6 +1219,7 @@
* setMediaDrmSession with a closed session id
*/
TEST_P(DrmHalVendorPluginTest, SetMediaDrmSessionClosedSession) {
+ RETURN_IF_SKIPPED;
auto sessionId = openSession();
closeSession(sessionId);
Status status = cryptoPlugin->setMediaDrmSession(sessionId);
@@ -1043,6 +1230,7 @@
* setMediaDrmSession with a empty session id: BAD_VALUE
*/
TEST_P(DrmHalVendorPluginTest, SetMediaDrmSessionEmptySession) {
+ RETURN_IF_SKIPPED;
SessionId sessionId;
Status status = cryptoPlugin->setMediaDrmSession(sessionId);
EXPECT_EQ(Status::BAD_VALUE, status);
@@ -1058,10 +1246,7 @@
virtual ~DrmHalVendorDecryptTest() {}
protected:
- void loadKeys(const SessionId& sessionId,
- const ContentConfiguration& configuration);
void fillRandom(const sp<IMemory>& memory);
- KeyedVector toHidlKeyedVector(const map<string, string>& params);
hidl_array<uint8_t, 16> toHidlArray(const vector<uint8_t>& vec) {
EXPECT_EQ(vec.size(), 16u);
return hidl_array<uint8_t, 16>(&vec[0]);
@@ -1078,63 +1263,6 @@
const hidl_vec<SubSample>& subSamples, const vector<uint8_t>& key);
};
-KeyedVector DrmHalVendorDecryptTest::toHidlKeyedVector(
- const map<string, string>& params) {
- std::vector<KeyValue> stdKeyedVector;
- for (auto it = params.begin(); it != params.end(); ++it) {
- KeyValue keyValue;
- keyValue.key = it->first;
- keyValue.value = it->second;
- stdKeyedVector.push_back(keyValue);
- }
- return KeyedVector(stdKeyedVector);
-}
-
-/**
- * Helper method to load keys for subsequent decrypt tests.
- * These tests use predetermined key request/response to
- * avoid requiring a round trip to a license server.
- */
-void DrmHalVendorDecryptTest::loadKeys(const SessionId& sessionId,
- const ContentConfiguration& configuration) {
- hidl_vec<uint8_t> keyRequest;
- auto res = drmPlugin->getKeyRequest(
- sessionId, configuration.initData, configuration.mimeType,
- KeyType::STREAMING,
- toHidlKeyedVector(configuration.optionalParameters),
- [&](Status status, const hidl_vec<uint8_t>& request,
- KeyRequestType type, const hidl_string&) {
- EXPECT_EQ(Status::OK, status)
- << "Failed to get "
- "key request for configuration "
- << configuration.name;
- EXPECT_EQ(type, KeyRequestType::INITIAL);
- EXPECT_NE(request.size(), 0u) << "Expected key request size"
- " to have length > 0 bytes";
- keyRequest = request;
- });
- EXPECT_OK(res);
-
- /**
- * Get key response from vendor module
- */
- hidl_vec<uint8_t> keyResponse =
- vendorModule->handleKeyRequest(keyRequest, configuration.serverUrl);
-
- EXPECT_NE(keyResponse.size(), 0u) << "Expected key response size "
- "to have length > 0 bytes";
-
- res = drmPlugin->provideKeyResponse(
- sessionId, keyResponse,
- [&](Status status, const hidl_vec<uint8_t>&) {
- EXPECT_EQ(Status::OK, status)
- << "Failure providing "
- "key response for configuration "
- << configuration.name;
- });
- EXPECT_OK(res);
-}
-
void DrmHalVendorDecryptTest::fillRandom(const sp<IMemory>& memory) {
random_device rd;
mt19937 rand(rd());
@@ -1296,6 +1424,7 @@
* Test key status with empty session id, should return BAD_VALUE
*/
TEST_P(DrmHalVendorDecryptTest, QueryKeyStatusInvalidSession) {
+ RETURN_IF_SKIPPED;
SessionId sessionId;
auto res = drmPlugin->queryKeyStatus(sessionId,
[&](Status status, KeyedVector /* info */) {
@@ -1309,6 +1438,7 @@
* Test key status. There should be no key status prior to loading keys
*/
TEST_P(DrmHalVendorDecryptTest, QueryKeyStatusWithNoKeys) {
+ RETURN_IF_SKIPPED;
auto sessionId = openSession();
auto keyStatus = queryKeyStatus(sessionId);
EXPECT_EQ(0u, keyStatus.size());
@@ -1320,6 +1450,7 @@
* Test key status. There should be key status after loading keys.
*/
TEST_P(DrmHalVendorDecryptTest, QueryKeyStatus) {
+ RETURN_IF_SKIPPED;
for (auto config : contentConfigurations) {
auto sessionId = openSession();
loadKeys(sessionId, config);
@@ -1333,6 +1464,7 @@
* Positive decrypt test. "Decrypt" a single clear segment and verify.
*/
TEST_P(DrmHalVendorDecryptTest, ClearSegmentTest) {
+ RETURN_IF_SKIPPED;
for (auto config : contentConfigurations) {
for (auto key : config.keys) {
const size_t kSegmentSize = 1024;
@@ -1360,6 +1492,7 @@
* Verify data matches.
*/
TEST_P(DrmHalVendorDecryptTest, EncryptedAesCtrSegmentTest) {
+ RETURN_IF_SKIPPED;
for (auto config : contentConfigurations) {
for (auto key : config.keys) {
const size_t kSegmentSize = 1024;
@@ -1386,6 +1519,7 @@
* Negative decrypt test. Decrypt without loading keys.
*/
TEST_P(DrmHalVendorDecryptTest, EncryptedAesCtrSegmentTestNoKeys) {
+ RETURN_IF_SKIPPED;
for (auto config : contentConfigurations) {
for (auto key : config.keys) {
vector<uint8_t> iv(AES_BLOCK_SIZE, 0);
@@ -1412,6 +1546,7 @@
* decryption can't be performed.
*/
TEST_P(DrmHalVendorDecryptTest, AttemptDecryptWithKeysRemoved) {
+ RETURN_IF_SKIPPED;
for (auto config : contentConfigurations) {
for (auto key : config.keys) {
vector<uint8_t> iv(AES_BLOCK_SIZE, 0);
@@ -1428,7 +1563,7 @@
uint32_t byteCount = decrypt(Mode::AES_CTR, key.isSecure,
toHidlArray(key.keyId), &iv[0], subSamples, noPattern,
- key.clearContentKey, Status::ERROR_DRM_DECRYPT);
+ key.clearContentKey, Status::ERROR_DRM_NO_LICENSE);
EXPECT_EQ(0u, byteCount);
closeSession(sessionId);
diff --git a/dumpstate/1.0/default/DumpstateDevice.cpp b/dumpstate/1.0/default/DumpstateDevice.cpp
index 8000d85..213fc62 100644
--- a/dumpstate/1.0/default/DumpstateDevice.cpp
+++ b/dumpstate/1.0/default/DumpstateDevice.cpp
@@ -52,7 +52,7 @@
dprintf(fd, "Dumpstate HIDL not provided by device; providing bogus data.\n");
// Shows some examples on how to use the libdumpstateutil API.
- RunCommandToFd(fd, "DATE", {"/system/bin/date"});
+ RunCommandToFd(fd, "DATE", {"/vendor/bin/date"});
DumpFileToFd(fd, "HOSTS", "/system/etc/hosts");
return Void();
diff --git a/gatekeeper/1.0/Android.mk b/gatekeeper/1.0/Android.mk
index 70206ff..576f729 100644
--- a/gatekeeper/1.0/Android.mk
+++ b/gatekeeper/1.0/Android.mk
@@ -5,7 +5,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.gatekeeper@1.0-java
+LOCAL_MODULE := android.hardware.gatekeeper-V1.0-java
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -13,7 +13,7 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_JAVA_LIBRARIES := \
- android.hidl.base@1.0-java \
+ android.hidl.base-V1.0-java \
#
@@ -80,7 +80,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.gatekeeper@1.0-java-static
+LOCAL_MODULE := android.hardware.gatekeeper-V1.0-java-static
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -88,7 +88,7 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_STATIC_JAVA_LIBRARIES := \
- android.hidl.base@1.0-java-static \
+ android.hidl.base-V1.0-java-static \
#
diff --git a/gnss/1.0/Android.mk b/gnss/1.0/Android.mk
index 5985c87..bb1b765 100644
--- a/gnss/1.0/Android.mk
+++ b/gnss/1.0/Android.mk
@@ -5,7 +5,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.gnss@1.0-java
+LOCAL_MODULE := android.hardware.gnss-V1.0-java
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -13,7 +13,7 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_JAVA_LIBRARIES := \
- android.hidl.base@1.0-java \
+ android.hidl.base-V1.0-java \
#
@@ -527,7 +527,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.gnss@1.0-java-static
+LOCAL_MODULE := android.hardware.gnss-V1.0-java-static
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -535,7 +535,7 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_STATIC_JAVA_LIBRARIES := \
- android.hidl.base@1.0-java-static \
+ android.hidl.base-V1.0-java-static \
#
@@ -1049,7 +1049,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.gnss@1.0-java-constants
+LOCAL_MODULE := android.hardware.gnss-V1.0-java-constants
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
diff --git a/gnss/1.0/default/Android.mk b/gnss/1.0/default/Android.mk
index 5ad5e50..34da64e 100644
--- a/gnss/1.0/default/Android.mk
+++ b/gnss/1.0/default/Android.mk
@@ -45,8 +45,8 @@
libdl \
libbase \
libutils \
- libhardware_legacy \
libhardware \
+ libbinder \
LOCAL_SHARED_LIBRARIES += \
libhidlbase \
diff --git a/gnss/1.0/default/android.hardware.gnss@1.0-service.rc b/gnss/1.0/default/android.hardware.gnss@1.0-service.rc
index f1116f4..96638a3 100644
--- a/gnss/1.0/default/android.hardware.gnss@1.0-service.rc
+++ b/gnss/1.0/default/android.hardware.gnss@1.0-service.rc
@@ -1,7 +1,4 @@
service gnss_service /vendor/bin/hw/android.hardware.gnss@1.0-service
class main
user system
-#
-# TODO:(b/35757613) - STOPSHIP - HAL cannot have direct inet access
-#
- group system inet
+ group system gps
diff --git a/gnss/1.0/default/service.cpp b/gnss/1.0/default/service.cpp
index 5a8acc1..0704e7f 100644
--- a/gnss/1.0/default/service.cpp
+++ b/gnss/1.0/default/service.cpp
@@ -4,9 +4,14 @@
#include <hidl/LegacySupport.h>
+#include <binder/ProcessState.h>
+
using android::hardware::gnss::V1_0::IGnss;
using android::hardware::defaultPassthroughServiceImplementation;
int main() {
+ // The GNSS HAL may communicate to other vendor components via
+ // /dev/vndbinder
+ android::ProcessState::initWithDriver("/dev/vndbinder");
return defaultPassthroughServiceImplementation<IGnss>();
}
diff --git a/graphics/common/1.0/Android.mk b/graphics/common/1.0/Android.mk
index ae80c6a..569a5f4 100644
--- a/graphics/common/1.0/Android.mk
+++ b/graphics/common/1.0/Android.mk
@@ -5,7 +5,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.graphics.common@1.0-java
+LOCAL_MODULE := android.hardware.graphics.common-V1.0-java
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -150,7 +150,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.graphics.common@1.0-java-static
+LOCAL_MODULE := android.hardware.graphics.common-V1.0-java-static
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -295,7 +295,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.graphics.common@1.0-java-constants
+LOCAL_MODULE := android.hardware.graphics.common-V1.0-java-constants
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
diff --git a/graphics/composer/2.1/default/service.cpp b/graphics/composer/2.1/default/service.cpp
index aa0604a..712dac1 100644
--- a/graphics/composer/2.1/default/service.cpp
+++ b/graphics/composer/2.1/default/service.cpp
@@ -28,7 +28,6 @@
int main() {
// the conventional HAL might start binder services
- android::ProcessState::initWithDriver("/dev/vndbinder");
android::ProcessState::self()->setThreadPoolMaxThreadCount(4);
android::ProcessState::self()->startThreadPool();
diff --git a/health/1.0/Android.mk b/health/1.0/Android.mk
index ebb89a7..b03b868 100644
--- a/health/1.0/Android.mk
+++ b/health/1.0/Android.mk
@@ -5,7 +5,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.health@1.0-java
+LOCAL_MODULE := android.hardware.health-V1.0-java
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -13,7 +13,7 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_JAVA_LIBRARIES := \
- android.hidl.base@1.0-java \
+ android.hidl.base-V1.0-java \
#
@@ -137,7 +137,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.health@1.0-java-static
+LOCAL_MODULE := android.hardware.health-V1.0-java-static
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -145,7 +145,7 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_STATIC_JAVA_LIBRARIES := \
- android.hidl.base@1.0-java-static \
+ android.hidl.base-V1.0-java-static \
#
@@ -269,7 +269,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.health@1.0-java-constants
+LOCAL_MODULE := android.hardware.health-V1.0-java-constants
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
diff --git a/ir/1.0/Android.mk b/ir/1.0/Android.mk
index d43286c..bdb3b29 100644
--- a/ir/1.0/Android.mk
+++ b/ir/1.0/Android.mk
@@ -5,7 +5,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.ir@1.0-java
+LOCAL_MODULE := android.hardware.ir-V1.0-java
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -13,7 +13,7 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_JAVA_LIBRARIES := \
- android.hidl.base@1.0-java \
+ android.hidl.base-V1.0-java \
#
@@ -61,7 +61,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.ir@1.0-java-static
+LOCAL_MODULE := android.hardware.ir-V1.0-java-static
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -69,7 +69,7 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_STATIC_JAVA_LIBRARIES := \
- android.hidl.base@1.0-java-static \
+ android.hidl.base-V1.0-java-static \
#
diff --git a/keymaster/3.0/default/Android.mk b/keymaster/3.0/default/Android.mk
index c537346..9df5bf8 100644
--- a/keymaster/3.0/default/Android.mk
+++ b/keymaster/3.0/default/Android.mk
@@ -34,7 +34,6 @@
libdl \
libbase \
libutils \
- libhardware_legacy \
libhardware \
libhidlbase \
libhidltransport \
diff --git a/keymaster/3.0/default/KeymasterDevice.cpp b/keymaster/3.0/default/KeymasterDevice.cpp
index 6b4524b..58102bb 100644
--- a/keymaster/3.0/default/KeymasterDevice.cpp
+++ b/keymaster/3.0/default/KeymasterDevice.cpp
@@ -519,6 +519,7 @@
hidl_vec<hidl_vec<uint8_t>> resultCertChain;
+ bool foundAttestationApplicationId = false;
for (size_t i = 0; i < attestParams.size(); ++i) {
switch (attestParams[i].tag) {
case Tag::ATTESTATION_ID_BRAND:
@@ -532,11 +533,22 @@
// never perform any device id attestation.
_hidl_cb(ErrorCode::CANNOT_ATTEST_IDS, resultCertChain);
return Void();
+
+ case Tag::ATTESTATION_APPLICATION_ID:
+ foundAttestationApplicationId = true;
+ break;
+
default:
break;
}
}
+ // KM3 devices reject missing attest application IDs. KM2 devices do not.
+ if (!foundAttestationApplicationId) {
+ _hidl_cb(ErrorCode::ATTESTATION_APPLICATION_ID_MISSING,
+ resultCertChain);
+ }
+
keymaster_cert_chain_t cert_chain{nullptr, 0};
auto kmKeyToAttest = hidlVec2KmKeyBlob(keyToAttest);
diff --git a/keymaster/3.0/vts/functional/attestation_record.cpp b/keymaster/3.0/vts/functional/attestation_record.cpp
index 6cdd44c..5d96fff 100644
--- a/keymaster/3.0/vts/functional/attestation_record.cpp
+++ b/keymaster/3.0/vts/functional/attestation_record.cpp
@@ -244,6 +244,8 @@
copyAuthTag(record->rsa_public_exponent, TAG_RSA_PUBLIC_EXPONENT, auth_list);
copyAuthTag(record->usage_expire_date_time, TAG_USAGE_EXPIRE_DATETIME, auth_list);
copyAuthTag(record->user_auth_type, TAG_USER_AUTH_TYPE, auth_list);
+ copyAuthTag(record->attestation_application_id,
+ TAG_ATTESTATION_APPLICATION_ID, auth_list);
return ErrorCode::OK;
}
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 edb1cd1..3448398 100644
--- a/keymaster/3.0/vts/functional/keymaster_hidl_hal_test.cpp
+++ b/keymaster/3.0/vts/functional/keymaster_hidl_hal_test.cpp
@@ -892,19 +892,10 @@
static hidl_string author_;
};
-uint32_t expected_keymaster_version() {
- if (!KeymasterHidlTest::IsSecure()) return 2; // SW is KM2
-
- uint32_t keymaster_version = 0;
- if (KeymasterHidlTest::SupportsSymmetric()) keymaster_version = 1;
- if (KeymasterHidlTest::SupportsAttestation()) keymaster_version = 2;
- return keymaster_version;
-}
-
-bool verify_attestation_record(const string& challenge, AuthorizationSet expected_sw_enforced,
+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;
@@ -921,6 +912,7 @@
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, //
@@ -933,8 +925,28 @@
&att_tee_enforced, //
&att_unique_id));
- EXPECT_EQ(1U, att_attestation_version);
- EXPECT_EQ(expected_keymaster_version(), att_keymaster_version);
+ if (att_keymaster_version == 3) {
+ EXPECT_EQ(2U, att_attestation_version);
+ } else {
+ EXPECT_EQ(1U, att_attestation_version);
+ }
+
+ expected_sw_enforced.push_back(TAG_ATTESTATION_APPLICATION_ID,
+ HidlBuf(app_id));
+
+ if (!KeymasterHidlTest::IsSecure()) {
+ // SW is KM2
+ EXPECT_EQ(att_keymaster_version, 2U);
+ }
+
+ 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);
@@ -3827,15 +3839,41 @@
.Authorization(TAG_INCLUDE_UNIQUE_ID)));
hidl_vec<hidl_vec<uint8_t>> cert_chain;
- EXPECT_EQ(ErrorCode::OK, AttestKey(AuthorizationSetBuilder().Authorization(
- TAG_ATTESTATION_CHALLENGE, HidlBuf("challenge")),
- &cert_chain));
+ EXPECT_EQ(
+ ErrorCode::OK,
+ AttestKey(
+ AuthorizationSetBuilder()
+ .Authorization(TAG_ATTESTATION_CHALLENGE, HidlBuf("challenge"))
+ .Authorization(TAG_ATTESTATION_APPLICATION_ID, HidlBuf("foo")),
+ &cert_chain));
EXPECT_GE(cert_chain.size(), 2U);
EXPECT_TRUE(verify_chain(cert_chain));
- EXPECT_TRUE(verify_attestation_record("challenge", //
- key_characteristics_.softwareEnforced, //
- key_characteristics_.teeEnforced, //
- cert_chain[0]));
+ EXPECT_TRUE(
+ verify_attestation_record("challenge", "foo", //
+ key_characteristics_.softwareEnforced, //
+ key_characteristics_.teeEnforced, //
+ cert_chain[0]));
+}
+
+/*
+ * AttestationTest.RsaAttestationRequiresAppId
+ *
+ * Verifies that attesting to RSA requires app ID.
+ */
+TEST_F(AttestationTest, RsaAttestationRequiresAppId) {
+ ASSERT_EQ(ErrorCode::OK,
+ GenerateKey(AuthorizationSetBuilder()
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .RsaSigningKey(1024, 3)
+ .Digest(Digest::NONE)
+ .Padding(PaddingMode::NONE)
+ .Authorization(TAG_INCLUDE_UNIQUE_ID)));
+
+ hidl_vec<hidl_vec<uint8_t>> cert_chain;
+ EXPECT_EQ(ErrorCode::ATTESTATION_APPLICATION_ID_MISSING,
+ AttestKey(AuthorizationSetBuilder().Authorization(
+ TAG_ATTESTATION_CHALLENGE, HidlBuf("challenge")),
+ &cert_chain));
}
/*
@@ -3851,16 +3889,41 @@
.Authorization(TAG_INCLUDE_UNIQUE_ID)));
hidl_vec<hidl_vec<uint8_t>> cert_chain;
- EXPECT_EQ(ErrorCode::OK, AttestKey(AuthorizationSetBuilder().Authorization(
- TAG_ATTESTATION_CHALLENGE, HidlBuf("challenge")),
- &cert_chain));
+ EXPECT_EQ(
+ ErrorCode::OK,
+ AttestKey(
+ AuthorizationSetBuilder()
+ .Authorization(TAG_ATTESTATION_CHALLENGE, HidlBuf("challenge"))
+ .Authorization(TAG_ATTESTATION_APPLICATION_ID, HidlBuf("foo")),
+ &cert_chain));
EXPECT_GE(cert_chain.size(), 2U);
EXPECT_TRUE(verify_chain(cert_chain));
- EXPECT_TRUE(verify_attestation_record("challenge", //
- key_characteristics_.softwareEnforced, //
- key_characteristics_.teeEnforced, //
- cert_chain[0]));
+ EXPECT_TRUE(
+ verify_attestation_record("challenge", "foo", //
+ key_characteristics_.softwareEnforced, //
+ key_characteristics_.teeEnforced, //
+ cert_chain[0]));
+}
+
+/*
+ * AttestationTest.EcAttestationRequiresAttestationAppId
+ *
+ * Verifies that attesting to EC keys requires app ID
+ */
+TEST_F(AttestationTest, EcAttestationRequiresAttestationAppId) {
+ ASSERT_EQ(ErrorCode::OK,
+ GenerateKey(AuthorizationSetBuilder()
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .EcdsaSigningKey(EcCurve::P_256)
+ .Digest(Digest::SHA_2_256)
+ .Authorization(TAG_INCLUDE_UNIQUE_ID)));
+
+ hidl_vec<hidl_vec<uint8_t>> cert_chain;
+ EXPECT_EQ(ErrorCode::ATTESTATION_APPLICATION_ID_MISSING,
+ AttestKey(AuthorizationSetBuilder().Authorization(
+ TAG_ATTESTATION_CHALLENGE, HidlBuf("challenge")),
+ &cert_chain));
}
/*
@@ -3932,15 +3995,18 @@
AuthorizationSet begin_out_params;
if (rollback_protected) {
- EXPECT_EQ(ErrorCode::INVALID_KEY_BLOB,
- Begin(KeyPurpose::SIGN, key_blob_,
- AuthorizationSetBuilder().Digest(Digest::NONE).Padding(PaddingMode::NONE),
- &begin_out_params, &op_handle_));
+ EXPECT_EQ(
+ ErrorCode::INVALID_KEY_BLOB,
+ Begin(KeyPurpose::SIGN, key_blob_, AuthorizationSetBuilder()
+ .Digest(Digest::NONE)
+ .Padding(PaddingMode::NONE),
+ &begin_out_params, &op_handle_));
} else {
- EXPECT_EQ(ErrorCode::OK,
- Begin(KeyPurpose::SIGN, key_blob_,
- AuthorizationSetBuilder().Digest(Digest::NONE).Padding(PaddingMode::NONE),
- &begin_out_params, &op_handle_));
+ EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::SIGN, key_blob_,
+ AuthorizationSetBuilder()
+ .Digest(Digest::NONE)
+ .Padding(PaddingMode::NONE),
+ &begin_out_params, &op_handle_));
}
AbortIfNeeded();
key_blob_ = HidlBuf();
@@ -4006,15 +4072,18 @@
AuthorizationSet begin_out_params;
if (rollback_protected) {
- EXPECT_EQ(ErrorCode::INVALID_KEY_BLOB,
- Begin(KeyPurpose::SIGN, key_blob_,
- AuthorizationSetBuilder().Digest(Digest::NONE).Padding(PaddingMode::NONE),
- &begin_out_params, &op_handle_));
+ EXPECT_EQ(
+ ErrorCode::INVALID_KEY_BLOB,
+ Begin(KeyPurpose::SIGN, key_blob_, AuthorizationSetBuilder()
+ .Digest(Digest::NONE)
+ .Padding(PaddingMode::NONE),
+ &begin_out_params, &op_handle_));
} else {
- EXPECT_EQ(ErrorCode::OK,
- Begin(KeyPurpose::SIGN, key_blob_,
- AuthorizationSetBuilder().Digest(Digest::NONE).Padding(PaddingMode::NONE),
- &begin_out_params, &op_handle_));
+ EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::SIGN, key_blob_,
+ AuthorizationSetBuilder()
+ .Digest(Digest::NONE)
+ .Padding(PaddingMode::NONE),
+ &begin_out_params, &op_handle_));
}
AbortIfNeeded();
key_blob_ = HidlBuf();
diff --git a/light/2.0/Android.mk b/light/2.0/Android.mk
index 7bb4293..24d7ab1 100644
--- a/light/2.0/Android.mk
+++ b/light/2.0/Android.mk
@@ -5,7 +5,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.light@2.0-java
+LOCAL_MODULE := android.hardware.light-V2.0-java
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -13,7 +13,7 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_JAVA_LIBRARIES := \
- android.hidl.base@1.0-java \
+ android.hidl.base-V1.0-java \
#
@@ -137,7 +137,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.light@2.0-java-static
+LOCAL_MODULE := android.hardware.light-V2.0-java-static
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -145,7 +145,7 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_STATIC_JAVA_LIBRARIES := \
- android.hidl.base@1.0-java-static \
+ android.hidl.base-V1.0-java-static \
#
diff --git a/light/2.0/default/Android.mk b/light/2.0/default/Android.mk
index 3439c9b..1f44e66 100644
--- a/light/2.0/default/Android.mk
+++ b/light/2.0/default/Android.mk
@@ -34,7 +34,6 @@
libdl \
libbase \
libutils \
- libhardware_legacy \
libhardware \
LOCAL_SHARED_LIBRARIES += \
diff --git a/media/Android.bp b/media/Android.bp
old mode 100644
new mode 100755
index f2abc67..2c12fb8
--- a/media/Android.bp
+++ b/media/Android.bp
@@ -2,4 +2,7 @@
subdirs = [
"1.0",
"omx/1.0",
+ "omx/1.0/vts/functional/audio",
+ "omx/1.0/vts/functional/component",
+ "omx/1.0/vts/functional/master",
]
diff --git a/media/omx/1.0/vts/functional/audio/Android.bp b/media/omx/1.0/vts/functional/audio/Android.bp
new file mode 100644
index 0000000..d6c73ce
--- /dev/null
+++ b/media/omx/1.0/vts/functional/audio/Android.bp
@@ -0,0 +1,79 @@
+//
+// Copyright (C) 2017 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: "VtsHalMediaOmxV1_0TargetAudioEncTest",
+ defaults: ["hidl_defaults"],
+ srcs: ["VtsHalMediaOmxV1_0TargetAudioEncTest.cpp",
+ "media_audio_hidl_test_common.cpp"],
+ shared_libs: [
+ "libbase",
+ "liblog",
+ "libcutils",
+ "libhidlbase",
+ "libhidlmemory",
+ "libhidltransport",
+ "libhwbinder",
+ "libnativehelper",
+ "libutils",
+ "libstagefright_foundation",
+ "android.hidl.allocator@1.0",
+ "android.hidl.memory@1.0",
+ "android.hardware.media.omx@1.0",
+ ],
+ static_libs: ["VtsHalHidlTargetTestBase"],
+ cflags: [
+ "-O0",
+ "-g",
+ ],
+ include_dirs: [
+ "frameworks/native/include/media/openmax/",
+ "hardware/interfaces/media/omx/1.0/vts/functional/common",
+ ],
+}
+
+cc_test {
+ name: "VtsHalMediaOmxV1_0TargetAudioDecTest",
+ defaults: ["hidl_defaults"],
+ srcs: ["VtsHalMediaOmxV1_0TargetAudioDecTest.cpp",
+ "media_audio_hidl_test_common.cpp"],
+ shared_libs: [
+ "libbase",
+ "liblog",
+ "libcutils",
+ "libhidlbase",
+ "libhidlmemory",
+ "libhidltransport",
+ "libhwbinder",
+ "libnativehelper",
+ "libutils",
+ "libstagefright_foundation",
+ "android.hidl.allocator@1.0",
+ "android.hidl.memory@1.0",
+ "android.hardware.media.omx@1.0",
+ ],
+ static_libs: ["VtsHalHidlTargetTestBase"],
+ cflags: [
+ "-O0",
+ "-g",
+ ],
+ include_dirs: [
+ "frameworks/native/include/media/openmax/",
+ "hardware/interfaces/media/omx/1.0/vts/functional/common",
+ ],
+}
+
+
diff --git a/media/omx/1.0/vts/functional/audio/VtsHalMediaOmxV1_0TargetAudioDecTest.cpp b/media/omx/1.0/vts/functional/audio/VtsHalMediaOmxV1_0TargetAudioDecTest.cpp
new file mode 100644
index 0000000..7c21753
--- /dev/null
+++ b/media/omx/1.0/vts/functional/audio/VtsHalMediaOmxV1_0TargetAudioDecTest.cpp
@@ -0,0 +1,687 @@
+/*
+ * Copyright (C) 2017 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 "media_omx_hidl_audio_dec_test"
+#include <android-base/logging.h>
+
+#include <android/hardware/media/omx/1.0/IOmx.h>
+#include <android/hardware/media/omx/1.0/IOmxNode.h>
+#include <android/hardware/media/omx/1.0/IOmxObserver.h>
+#include <android/hardware/media/omx/1.0/types.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>
+
+using ::android::hardware::media::omx::V1_0::IOmx;
+using ::android::hardware::media::omx::V1_0::IOmxObserver;
+using ::android::hardware::media::omx::V1_0::IOmxNode;
+using ::android::hardware::media::omx::V1_0::Message;
+using ::android::hardware::media::omx::V1_0::CodecBuffer;
+using ::android::hidl::allocator::V1_0::IAllocator;
+using ::android::hidl::memory::V1_0::IMemory;
+using ::android::hidl::memory::V1_0::IMapper;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+#include <VtsHalHidlTargetTestBase.h>
+#include <getopt.h>
+#include <media_audio_hidl_test_common.h>
+#include <media_hidl_test_common.h>
+#include <fstream>
+
+// A class for test environment setup
+class ComponentTestEnvironment : public ::testing::Environment {
+ public:
+ virtual void SetUp() {}
+ virtual void TearDown() {}
+
+ ComponentTestEnvironment() : instance("default") {}
+
+ void setInstance(const char* _instance) { instance = _instance; }
+
+ void setComponent(const char* _component) { component = _component; }
+
+ void setRole(const char* _role) { role = _role; }
+
+ void setQuirks(int _quirks) { quirks = _quirks; }
+
+ const hidl_string getInstance() const { return instance; }
+
+ const hidl_string getComponent() const { return component; }
+
+ const hidl_string getRole() const { return role; }
+
+ int getQuirks() const { return quirks; }
+
+ int initFromOptions(int argc, char** argv) {
+ static struct option options[] = {
+ {"instance", required_argument, 0, 'I'},
+ {"component", required_argument, 0, 'C'},
+ {"role", required_argument, 0, 'R'},
+ {"quirks", required_argument, 0, 'Q'},
+ {0, 0, 0, 0}};
+
+ while (true) {
+ int index = 0;
+ int c = getopt_long(argc, argv, "I:C:Q:R:", options, &index);
+ if (c == -1) {
+ break;
+ }
+
+ switch (c) {
+ case 'I':
+ setInstance(optarg);
+ break;
+ case 'C':
+ setComponent(optarg);
+ break;
+ case 'Q':
+ setQuirks(atoi(optarg));
+ break;
+ case 'R':
+ setRole(optarg);
+ break;
+ case '?':
+ break;
+ }
+ }
+
+ if (optind < argc) {
+ fprintf(stderr,
+ "unrecognized option: %s\n\n"
+ "usage: %s <gtest options> <test options>\n\n"
+ "test options are:\n\n"
+ "-I, --instance: HAL instance to test\n"
+ "-C, --component: OMX component to test\n"
+ "-R, --Role: OMX component Role\n"
+ "-Q, --quirks: Component quirks\n",
+ argv[optind ?: 1], argv[0]);
+ return 2;
+ }
+ return 0;
+ }
+
+ private:
+ hidl_string instance;
+ hidl_string component;
+ hidl_string role;
+ // to be removed when IOmxNode::setQuirks is removed
+ int quirks;
+};
+
+static ComponentTestEnvironment* gEnv = nullptr;
+
+class AudioDecHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+ public:
+ virtual void SetUp() override {
+ android::hardware::media::omx::V1_0::Status status;
+ omx = ::testing::VtsHalHidlTargetTestBase::getService<IOmx>(
+ gEnv->getInstance());
+ ASSERT_NE(omx, nullptr);
+ observer = new CodecObserver();
+ ASSERT_NE(observer, nullptr);
+ ASSERT_EQ(strncmp(gEnv->getComponent().c_str(), "OMX.", 4), 0)
+ << "Invalid Component Name";
+ EXPECT_TRUE(omx->allocateNode(
+ gEnv->getComponent(), observer,
+ [&](android::hardware::media::omx::V1_0::Status _s,
+ sp<IOmxNode> const& _nl) {
+ status = _s;
+ this->omxNode = _nl;
+ })
+ .isOk());
+ ASSERT_NE(omxNode, nullptr);
+ ASSERT_NE(gEnv->getRole().empty(), true) << "Invalid Component Role";
+ struct StringToName {
+ const char* Name;
+ standardComp CompName;
+ };
+ const StringToName kStringToName[] = {
+ {"mp3", mp3}, {"amrnb", amrnb}, {"amrwb", amrwb},
+ {"aac", aac}, {"vorbis", vorbis}, {"opus", opus},
+ {"pcm", pcm}, {"flac", flac},
+ };
+ const size_t kNumStringToName =
+ sizeof(kStringToName) / sizeof(kStringToName[0]);
+ const char* pch;
+ char substring[OMX_MAX_STRINGNAME_SIZE];
+ strcpy(substring, gEnv->getRole().c_str());
+ pch = strchr(substring, '.');
+ ASSERT_NE(pch, nullptr);
+ compName = unknown_comp;
+ for (size_t i = 0; i < kNumStringToName; ++i) {
+ if (!strcasecmp(pch + 1, kStringToName[i].Name)) {
+ compName = kStringToName[i].CompName;
+ break;
+ }
+ }
+ ASSERT_NE(compName, unknown_comp);
+ struct CompToCoding {
+ standardComp CompName;
+ OMX_AUDIO_CODINGTYPE eEncoding;
+ };
+ static const CompToCoding kCompToCoding[] = {
+ {mp3, OMX_AUDIO_CodingMP3},
+ {amrnb, OMX_AUDIO_CodingAMR},
+ {amrwb, OMX_AUDIO_CodingAMR},
+ {aac, OMX_AUDIO_CodingAAC},
+ {vorbis, OMX_AUDIO_CodingVORBIS},
+ {pcm, OMX_AUDIO_CodingPCM},
+ {opus, (OMX_AUDIO_CODINGTYPE)OMX_AUDIO_CodingAndroidOPUS},
+ {flac, OMX_AUDIO_CodingFLAC},
+ };
+ static const size_t kNumCompToCoding =
+ sizeof(kCompToCoding) / sizeof(kCompToCoding[0]);
+ size_t i;
+ for (i = 0; i < kNumCompToCoding; ++i) {
+ if (kCompToCoding[i].CompName == compName) {
+ eEncoding = kCompToCoding[i].eEncoding;
+ break;
+ }
+ }
+ ASSERT_NE(i, kNumCompToCoding);
+ }
+
+ virtual void TearDown() override {
+ if (omxNode != nullptr) {
+ EXPECT_TRUE((omxNode->freeNode()).isOk());
+ omxNode = nullptr;
+ }
+ }
+
+ enum standardComp {
+ mp3,
+ amrnb,
+ amrwb,
+ aac,
+ vorbis,
+ opus,
+ pcm,
+ flac,
+ unknown_comp,
+ };
+
+ sp<IOmx> omx;
+ sp<CodecObserver> observer;
+ sp<IOmxNode> omxNode;
+ standardComp compName;
+ OMX_AUDIO_CODINGTYPE eEncoding;
+};
+
+void setDefaultPortParam(
+ sp<IOmxNode> omxNode, OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE eEncoding,
+ int32_t nChannels = 2, int32_t nSampleRate = 44100,
+ OMX_NUMERICALDATATYPE eNumData = OMX_NumericalDataSigned,
+ int32_t nBitPerSample = 16) {
+ android::hardware::media::omx::V1_0::Status status;
+ OMX_PARAM_PORTDEFINITIONTYPE portDef;
+ status = getPortParam(omxNode, OMX_IndexParamPortDefinition, portIndex,
+ &portDef);
+ EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+
+ portDef.format.audio.bFlagErrorConcealment = OMX_TRUE;
+ portDef.format.audio.eEncoding = eEncoding;
+ status = setPortParam(omxNode, OMX_IndexParamPortDefinition, portIndex,
+ &portDef);
+ EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+
+ switch ((int)eEncoding) {
+ case OMX_AUDIO_CodingPCM:
+ setupPCMPort(omxNode, portIndex, nChannels, eNumData, nBitPerSample,
+ nSampleRate);
+ break;
+ default:
+ ASSERT_TRUE(false);
+ break;
+ }
+}
+
+void getInputChannelInfo(sp<IOmxNode> omxNode, OMX_U32 kPortIndexInput,
+ OMX_AUDIO_CODINGTYPE eEncoding, int32_t* nChannels,
+ int32_t* nSampleRate) {
+ *nChannels = 0;
+ *nSampleRate = 0;
+ android::hardware::media::omx::V1_0::Status status;
+
+ switch ((int)eEncoding) {
+ case OMX_AUDIO_CodingPCM: {
+ OMX_AUDIO_PARAM_PCMMODETYPE param;
+ status = getPortParam(omxNode, OMX_IndexParamAudioPcm,
+ kPortIndexInput, ¶m);
+ ASSERT_EQ(status,
+ ::android::hardware::media::omx::V1_0::Status::OK);
+ *nChannels = param.nChannels;
+ *nSampleRate = param.nSamplingRate;
+ break;
+ }
+ case OMX_AUDIO_CodingMP3: {
+ OMX_AUDIO_PARAM_MP3TYPE param;
+ status = getPortParam(omxNode, OMX_IndexParamAudioMp3,
+ kPortIndexInput, ¶m);
+ ASSERT_EQ(status,
+ ::android::hardware::media::omx::V1_0::Status::OK);
+ *nChannels = param.nChannels;
+ *nSampleRate = param.nSampleRate;
+ break;
+ }
+ case OMX_AUDIO_CodingFLAC: {
+ OMX_AUDIO_PARAM_FLACTYPE param;
+ status = getPortParam(omxNode, OMX_IndexParamAudioFlac,
+ kPortIndexInput, ¶m);
+ ASSERT_EQ(status,
+ ::android::hardware::media::omx::V1_0::Status::OK);
+ *nChannels = param.nChannels;
+ *nSampleRate = param.nSampleRate;
+ break;
+ }
+ case OMX_AUDIO_CodingAndroidOPUS: {
+ OMX_AUDIO_PARAM_ANDROID_OPUSTYPE param;
+ status = getPortParam(omxNode,
+ (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus,
+ kPortIndexInput, ¶m);
+ ASSERT_EQ(status,
+ ::android::hardware::media::omx::V1_0::Status::OK);
+ *nChannels = param.nChannels;
+ *nSampleRate = param.nSampleRate;
+ break;
+ }
+ case OMX_AUDIO_CodingVORBIS: {
+ OMX_AUDIO_PARAM_VORBISTYPE param;
+ status = getPortParam(omxNode, OMX_IndexParamAudioVorbis,
+ kPortIndexInput, ¶m);
+ ASSERT_EQ(status,
+ ::android::hardware::media::omx::V1_0::Status::OK);
+ *nChannels = param.nChannels;
+ *nSampleRate = param.nSampleRate;
+ break;
+ }
+ case OMX_AUDIO_CodingAMR: {
+ OMX_AUDIO_PARAM_AMRTYPE param;
+ status = getPortParam(omxNode, OMX_IndexParamAudioAmr,
+ kPortIndexInput, ¶m);
+ ASSERT_EQ(status,
+ ::android::hardware::media::omx::V1_0::Status::OK);
+ *nChannels = param.nChannels;
+ *nSampleRate = 8000;
+ break;
+ }
+ case OMX_AUDIO_CodingAAC: {
+ OMX_AUDIO_PARAM_AACPROFILETYPE param;
+ status = getPortParam(omxNode, OMX_IndexParamAudioAac,
+ kPortIndexInput, ¶m);
+ ASSERT_EQ(status,
+ ::android::hardware::media::omx::V1_0::Status::OK);
+ *nChannels = param.nChannels;
+ *nSampleRate = param.nSampleRate;
+ break;
+ }
+ default:
+ ASSERT_TRUE(false);
+ break;
+ }
+}
+
+void GetURLForComponent(AudioDecHidlTest::standardComp comp, const char** mURL,
+ const char** info) {
+ struct CompToURL {
+ AudioDecHidlTest::standardComp comp;
+ const char* mURL;
+ const char* info;
+ };
+ static const CompToURL kCompToURL[] = {
+ {AudioDecHidlTest::standardComp::mp3,
+ "/sdcard/raw/MP3_48KHz_128kbps_s_1_17_CBR.audio.mp3",
+ "/sdcard/raw/MP3_48KHz_128kbps_s_1_17_CBR.audio.info"},
+ {AudioDecHidlTest::standardComp::aac,
+ "/sdcard/raw/H264_500_AAC_128.audio.aac",
+ "/sdcard/raw/H264_500_AAC_128.audio.info"},
+ {AudioDecHidlTest::standardComp::amrnb,
+ "/sdcard/raw/H264_320_AMRNB_6.audio.amr",
+ "/sdcard/raw/H264_320_AMRNB_6.audio.info"},
+ {AudioDecHidlTest::standardComp::amrwb, "", ""},
+ {AudioDecHidlTest::standardComp::vorbis, "", ""},
+ {AudioDecHidlTest::standardComp::opus, "", ""},
+ {AudioDecHidlTest::standardComp::flac, "", ""},
+ };
+
+ for (size_t i = 0; i < sizeof(kCompToURL) / sizeof(kCompToURL[0]); ++i) {
+ if (kCompToURL[i].comp == comp) {
+ *mURL = kCompToURL[i].mURL;
+ *info = kCompToURL[i].info;
+ return;
+ }
+ }
+}
+
+void flushAllPorts(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
+ android::Vector<BufferInfo>* iBuffer,
+ android::Vector<BufferInfo>* oBuffer,
+ OMX_U32 kPortIndexInput, OMX_U32 kPortIndexOutput) {
+ android::hardware::media::omx::V1_0::Status status;
+ Message msg;
+ // Flush
+ status = omxNode->sendCommand(toRawCommandType(OMX_CommandFlush),
+ kPortIndexInput);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+ status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer, oBuffer);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+ ASSERT_EQ(msg.type, Message::Type::EVENT);
+ ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
+ ASSERT_EQ(msg.data.eventData.data1, OMX_CommandFlush);
+ ASSERT_EQ(msg.data.eventData.data2, kPortIndexInput);
+ // test if client got all its buffers back
+ for (size_t i = 0; i < iBuffer->size(); ++i) {
+ EXPECT_EQ((*iBuffer)[i].owner, client);
+ }
+
+ status = omxNode->sendCommand(toRawCommandType(OMX_CommandFlush),
+ kPortIndexOutput);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+ status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer, oBuffer);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+ ASSERT_EQ(msg.type, Message::Type::EVENT);
+ ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
+ ASSERT_EQ(msg.data.eventData.data1, OMX_CommandFlush);
+ ASSERT_EQ(msg.data.eventData.data2, kPortIndexOutput);
+ // test if client got all its buffers back
+ for (size_t i = 0; i < oBuffer->size(); ++i) {
+ EXPECT_EQ((*oBuffer)[i].owner, client);
+ }
+}
+
+void decodeNFrames(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
+ android::Vector<BufferInfo>* iBuffer,
+ android::Vector<BufferInfo>* oBuffer,
+ OMX_AUDIO_CODINGTYPE eEncoding, OMX_U32 kPortIndexInput,
+ OMX_U32 kPortIndexOutput, uint32_t nFrames,
+ std::ifstream& eleStream, std::ifstream& eleInfo) {
+ android::hardware::media::omx::V1_0::Status status;
+ Message msg;
+
+ // dispatch output buffers
+ for (size_t i = 0; i < oBuffer->size(); i++) {
+ dispatchOutputBuffer(omxNode, oBuffer, i);
+ }
+ // dispatch input buffers
+ int bytesCount = 0;
+ for (size_t i = 0; i < iBuffer->size(); i++) {
+ char* ipBuffer = static_cast<char*>(
+ static_cast<void*>((*iBuffer)[i].mMemory->getPointer()));
+ if (!(eleInfo >> bytesCount)) break;
+ eleStream.read(ipBuffer, bytesCount);
+ ASSERT_EQ(eleStream.gcount(), bytesCount);
+ dispatchInputBuffer(omxNode, iBuffer, i, bytesCount, 0, 0);
+ }
+
+ while (nFrames != 0) {
+ status =
+ observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer, oBuffer);
+ if (status == android::hardware::media::omx::V1_0::Status::OK &&
+ msg.type == Message::Type::EVENT &&
+ msg.data.eventData.event == OMX_EventPortSettingsChanged) {
+ ASSERT_EQ(msg.data.eventData.data1, kPortIndexOutput);
+
+ status = omxNode->sendCommand(
+ toRawCommandType(OMX_CommandPortDisable), kPortIndexOutput);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+
+ status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer,
+ oBuffer);
+ if (status ==
+ android::hardware::media::omx::V1_0::Status::TIMED_OUT) {
+ for (size_t i = 0; i < oBuffer->size(); ++i) {
+ // test if client got all its buffers back
+ EXPECT_EQ((*oBuffer)[i].owner, client);
+ // free the buffers
+ status =
+ omxNode->freeBuffer(kPortIndexOutput, (*oBuffer)[i].id);
+ ASSERT_EQ(status,
+ android::hardware::media::omx::V1_0::Status::OK);
+ }
+ status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT,
+ iBuffer, oBuffer);
+ ASSERT_EQ(status,
+ android::hardware::media::omx::V1_0::Status::OK);
+ ASSERT_EQ(msg.type, Message::Type::EVENT);
+ ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
+ ASSERT_EQ(msg.data.eventData.data1, OMX_CommandPortDisable);
+ ASSERT_EQ(msg.data.eventData.data2, kPortIndexOutput);
+
+ // Port Reconfigurations
+ int32_t nChannels;
+ int32_t nSampleRate;
+ getInputChannelInfo(omxNode, kPortIndexInput, eEncoding,
+ &nChannels, &nSampleRate);
+ setDefaultPortParam(omxNode, kPortIndexOutput,
+ OMX_AUDIO_CodingPCM, nChannels,
+ nSampleRate);
+
+ // If you can disable a port, then you should be able to enable
+ // it as well
+ status = omxNode->sendCommand(
+ toRawCommandType(OMX_CommandPortEnable), kPortIndexOutput);
+ ASSERT_EQ(status,
+ android::hardware::media::omx::V1_0::Status::OK);
+
+ // do not enable the port until all the buffers are supplied
+ status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT,
+ iBuffer, oBuffer);
+ ASSERT_EQ(
+ status,
+ android::hardware::media::omx::V1_0::Status::TIMED_OUT);
+
+ allocatePortBuffers(omxNode, oBuffer, kPortIndexOutput);
+ status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT,
+ iBuffer, oBuffer);
+ ASSERT_EQ(status,
+ android::hardware::media::omx::V1_0::Status::OK);
+ ASSERT_EQ(msg.type, Message::Type::EVENT);
+ ASSERT_EQ(msg.data.eventData.data1, OMX_CommandPortEnable);
+ ASSERT_EQ(msg.data.eventData.data2, kPortIndexOutput);
+
+ // dispatch output buffers
+ for (size_t i = 0; i < oBuffer->size(); i++) {
+ dispatchOutputBuffer(omxNode, oBuffer, i);
+ }
+ } else {
+ ASSERT_TRUE(false);
+ }
+ continue;
+ }
+ size_t index = 0;
+ if ((index = getEmptyBufferID(iBuffer)) < iBuffer->size()) {
+ char* ipBuffer = static_cast<char*>(
+ static_cast<void*>((*iBuffer)[index].mMemory->getPointer()));
+ if (!(eleInfo >> bytesCount)) break;
+ eleStream.read(ipBuffer, bytesCount);
+ ASSERT_EQ(eleStream.gcount(), bytesCount);
+ dispatchInputBuffer(omxNode, iBuffer, index, bytesCount, 0, 0);
+ }
+ if ((index = getEmptyBufferID(oBuffer)) < oBuffer->size()) {
+ dispatchOutputBuffer(omxNode, oBuffer, index);
+ }
+ nFrames--;
+ }
+}
+
+// Set Component Role
+TEST_F(AudioDecHidlTest, SetRole) {
+ android::hardware::media::omx::V1_0::Status status;
+ status = setRole(omxNode, gEnv->getRole().c_str());
+ ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+}
+
+// Enumerate Port Format
+TEST_F(AudioDecHidlTest, EnumeratePortFormat) {
+ android::hardware::media::omx::V1_0::Status status;
+ uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
+ status = setRole(omxNode, gEnv->getRole().c_str());
+ ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+ OMX_PORT_PARAM_TYPE params;
+ status = getParam(omxNode, OMX_IndexParamAudioInit, ¶ms);
+ if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
+ ASSERT_EQ(params.nPorts, 2U);
+ kPortIndexInput = params.nStartPortNumber;
+ kPortIndexOutput = kPortIndexInput + 1;
+ }
+ status = setAudioPortFormat(omxNode, kPortIndexInput, eEncoding);
+ EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+ status = setAudioPortFormat(omxNode, kPortIndexOutput, OMX_AUDIO_CodingPCM);
+ EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+}
+
+// Decode Test
+TEST_F(AudioDecHidlTest, DecodeTest) {
+ android::hardware::media::omx::V1_0::Status status;
+ uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
+ status = setRole(omxNode, gEnv->getRole().c_str());
+ ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+ OMX_PORT_PARAM_TYPE params;
+ status = getParam(omxNode, OMX_IndexParamAudioInit, ¶ms);
+ if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
+ ASSERT_EQ(params.nPorts, 2U);
+ kPortIndexInput = params.nStartPortNumber;
+ kPortIndexOutput = kPortIndexInput + 1;
+ }
+ const char *mURL = nullptr, *info = nullptr;
+ GetURLForComponent(compName, &mURL, &info);
+ EXPECT_NE(mURL, nullptr);
+ EXPECT_NE(info, nullptr);
+
+ std::ifstream eleStream, eleInfo;
+ eleStream.open(mURL, std::ifstream::binary);
+ ASSERT_EQ(eleStream.is_open(), true);
+ eleInfo.open(info);
+ ASSERT_EQ(eleInfo.is_open(), true);
+
+ if (eEncoding == OMX_AUDIO_CodingPCM)
+ setDefaultPortParam(omxNode, kPortIndexInput, eEncoding);
+ int32_t nChannels;
+ int32_t nSampleRate;
+ getInputChannelInfo(omxNode, kPortIndexInput, eEncoding, &nChannels,
+ &nSampleRate);
+ setDefaultPortParam(omxNode, kPortIndexOutput, OMX_AUDIO_CodingPCM,
+ nChannels, nSampleRate);
+
+ Message msg;
+ android::Vector<BufferInfo> iBuffer, oBuffer;
+
+ status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
+ OMX_StateIdle);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+
+ status =
+ observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &iBuffer, &oBuffer);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::TIMED_OUT);
+
+ allocatePortBuffers(omxNode, &iBuffer, kPortIndexInput);
+ status =
+ observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &iBuffer, &oBuffer);
+
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::TIMED_OUT);
+ allocatePortBuffers(omxNode, &oBuffer, kPortIndexOutput);
+
+ status =
+ observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &iBuffer, &oBuffer);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+ ASSERT_EQ(msg.type, Message::Type::EVENT);
+ ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
+ ASSERT_EQ(msg.data.eventData.data1, OMX_CommandStateSet);
+ ASSERT_EQ(msg.data.eventData.data2, OMX_StateIdle);
+
+ status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
+ OMX_StateExecuting);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+ status =
+ observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &iBuffer, &oBuffer);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+ ASSERT_EQ(msg.type, Message::Type::EVENT);
+ ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
+ ASSERT_EQ(msg.data.eventData.data1, OMX_CommandStateSet);
+ ASSERT_EQ(msg.data.eventData.data2, OMX_StateExecuting);
+
+ // Port Reconfiguration
+ decodeNFrames(omxNode, observer, &iBuffer, &oBuffer, eEncoding,
+ kPortIndexInput, kPortIndexOutput, (1 << 12), eleStream,
+ eleInfo);
+
+ // flush
+ flushAllPorts(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
+ kPortIndexOutput);
+
+ // set state to Idle
+ status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
+ OMX_StateIdle);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+ status =
+ observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &iBuffer, &oBuffer);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+ ASSERT_EQ(msg.type, Message::Type::EVENT);
+ ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
+ ASSERT_EQ(msg.data.eventData.data1, OMX_CommandStateSet);
+ ASSERT_EQ(msg.data.eventData.data2, OMX_StateIdle);
+
+ // set state to Loaded
+ status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
+ OMX_StateLoaded);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+
+ // dont change state until all buffers are freed
+ status =
+ observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &iBuffer, &oBuffer);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::TIMED_OUT);
+
+ for (size_t i = 0; i < iBuffer.size(); ++i) {
+ status = omxNode->freeBuffer(kPortIndexInput, iBuffer[i].id);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+ }
+
+ // dont change state until all buffers are freed
+ status =
+ observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &iBuffer, &oBuffer);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::TIMED_OUT);
+
+ for (size_t i = 0; i < oBuffer.size(); ++i) {
+ status = omxNode->freeBuffer(kPortIndexOutput, oBuffer[i].id);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+ }
+
+ status =
+ observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &iBuffer, &oBuffer);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+ ASSERT_EQ(msg.type, Message::Type::EVENT);
+ ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
+ ASSERT_EQ(msg.data.eventData.data1, OMX_CommandStateSet);
+ ASSERT_EQ(msg.data.eventData.data2, OMX_StateLoaded);
+
+ eleInfo.close();
+ eleStream.close();
+}
+
+int main(int argc, char** argv) {
+ gEnv = new ComponentTestEnvironment();
+ ::testing::AddGlobalTestEnvironment(gEnv);
+ ::testing::InitGoogleTest(&argc, argv);
+ int status = gEnv->initFromOptions(argc, argv);
+ if (status == 0) {
+ status = RUN_ALL_TESTS();
+ ALOGI("Test result = %d", status);
+ }
+ return status;
+}
diff --git a/media/omx/1.0/vts/functional/audio/VtsHalMediaOmxV1_0TargetAudioEncTest.cpp b/media/omx/1.0/vts/functional/audio/VtsHalMediaOmxV1_0TargetAudioEncTest.cpp
new file mode 100644
index 0000000..6a88b1a
--- /dev/null
+++ b/media/omx/1.0/vts/functional/audio/VtsHalMediaOmxV1_0TargetAudioEncTest.cpp
@@ -0,0 +1,263 @@
+/*
+ * Copyright (C) 2017 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 "media_omx_hidl_audio_enc_test"
+#include <android-base/logging.h>
+
+#include <android/hardware/media/omx/1.0/IOmx.h>
+#include <android/hardware/media/omx/1.0/IOmxNode.h>
+#include <android/hardware/media/omx/1.0/IOmxObserver.h>
+#include <android/hardware/media/omx/1.0/types.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>
+
+using ::android::hardware::media::omx::V1_0::IOmx;
+using ::android::hardware::media::omx::V1_0::IOmxObserver;
+using ::android::hardware::media::omx::V1_0::IOmxNode;
+using ::android::hardware::media::omx::V1_0::Message;
+using ::android::hardware::media::omx::V1_0::CodecBuffer;
+using ::android::hidl::allocator::V1_0::IAllocator;
+using ::android::hidl::memory::V1_0::IMemory;
+using ::android::hidl::memory::V1_0::IMapper;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+#include <VtsHalHidlTargetTestBase.h>
+#include <getopt.h>
+#include <media_audio_hidl_test_common.h>
+#include <media_hidl_test_common.h>
+#include <fstream>
+
+// A class for test environment setup
+class ComponentTestEnvironment : public ::testing::Environment {
+ public:
+ virtual void SetUp() {}
+ virtual void TearDown() {}
+
+ ComponentTestEnvironment() : instance("default") {}
+
+ void setInstance(const char* _instance) { instance = _instance; }
+
+ void setComponent(const char* _component) { component = _component; }
+
+ void setRole(const char* _role) { role = _role; }
+
+ void setQuirks(int _quirks) { quirks = _quirks; }
+
+ const hidl_string getInstance() const { return instance; }
+
+ const hidl_string getComponent() const { return component; }
+
+ const hidl_string getRole() const { return role; }
+
+ int getQuirks() const { return quirks; }
+
+ int initFromOptions(int argc, char** argv) {
+ static struct option options[] = {
+ {"instance", required_argument, 0, 'I'},
+ {"component", required_argument, 0, 'C'},
+ {"role", required_argument, 0, 'R'},
+ {"quirks", required_argument, 0, 'Q'},
+ {0, 0, 0, 0}};
+
+ while (true) {
+ int index = 0;
+ int c = getopt_long(argc, argv, "I:C:Q:R:", options, &index);
+ if (c == -1) {
+ break;
+ }
+
+ switch (c) {
+ case 'I':
+ setInstance(optarg);
+ break;
+ case 'C':
+ setComponent(optarg);
+ break;
+ case 'Q':
+ setQuirks(atoi(optarg));
+ break;
+ case 'R':
+ setRole(optarg);
+ break;
+ case '?':
+ break;
+ }
+ }
+
+ if (optind < argc) {
+ fprintf(stderr,
+ "unrecognized option: %s\n\n"
+ "usage: %s <gtest options> <test options>\n\n"
+ "test options are:\n\n"
+ "-I, --instance: HAL instance to test\n"
+ "-C, --component: OMX component to test\n"
+ "-R, --Role: OMX component Role\n"
+ "-Q, --quirks: Component quirks\n",
+ argv[optind ?: 1], argv[0]);
+ return 2;
+ }
+ return 0;
+ }
+
+ private:
+ hidl_string instance;
+ hidl_string component;
+ hidl_string role;
+ // to be removed when IOmxNode::setQuirks is removed
+ int quirks;
+};
+
+static ComponentTestEnvironment* gEnv = nullptr;
+
+class AudioEncHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+ public:
+ virtual void SetUp() override {
+ android::hardware::media::omx::V1_0::Status status;
+ omx = ::testing::VtsHalHidlTargetTestBase::getService<IOmx>(
+ gEnv->getInstance());
+ ASSERT_NE(omx, nullptr);
+ observer = new CodecObserver();
+ ASSERT_NE(observer, nullptr);
+ ASSERT_EQ(strncmp(gEnv->getComponent().c_str(), "OMX.", 4), 0)
+ << "Invalid Component Name";
+ EXPECT_TRUE(omx->allocateNode(
+ gEnv->getComponent(), observer,
+ [&](android::hardware::media::omx::V1_0::Status _s,
+ sp<IOmxNode> const& _nl) {
+ status = _s;
+ this->omxNode = _nl;
+ })
+ .isOk());
+ ASSERT_NE(omxNode, nullptr);
+ ASSERT_NE(gEnv->getRole().empty(), true) << "Invalid Component Role";
+ struct StringToName {
+ const char* Name;
+ standardComp CompName;
+ };
+ const StringToName kStringToName[] = {
+ {"mp3", mp3}, {"amrnb", amrnb}, {"amrwb", amrwb},
+ {"aac", aac}, {"vorbis", vorbis}, {"opus", opus},
+ {"pcm", pcm}, {"flac", flac},
+ };
+ const size_t kNumStringToName =
+ sizeof(kStringToName) / sizeof(kStringToName[0]);
+ const char* pch;
+ char substring[OMX_MAX_STRINGNAME_SIZE];
+ strcpy(substring, gEnv->getRole().c_str());
+ pch = strchr(substring, '.');
+ ASSERT_NE(pch, nullptr);
+ compName = unknown_comp;
+ for (size_t i = 0; i < kNumStringToName; ++i) {
+ if (!strcasecmp(pch + 1, kStringToName[i].Name)) {
+ compName = kStringToName[i].CompName;
+ break;
+ }
+ }
+ ASSERT_NE(compName, unknown_comp);
+ struct CompToCoding {
+ standardComp CompName;
+ OMX_AUDIO_CODINGTYPE eEncoding;
+ };
+ static const CompToCoding kCompToCoding[] = {
+ {mp3, OMX_AUDIO_CodingMP3},
+ {amrnb, OMX_AUDIO_CodingAMR},
+ {amrwb, OMX_AUDIO_CodingAMR},
+ {aac, OMX_AUDIO_CodingAAC},
+ {vorbis, OMX_AUDIO_CodingVORBIS},
+ {pcm, OMX_AUDIO_CodingPCM},
+ {opus, (OMX_AUDIO_CODINGTYPE)OMX_AUDIO_CodingAndroidOPUS},
+ {flac, OMX_AUDIO_CodingFLAC},
+ };
+ static const size_t kNumCompToCoding =
+ sizeof(kCompToCoding) / sizeof(kCompToCoding[0]);
+ size_t i;
+ for (i = 0; i < kNumCompToCoding; ++i) {
+ if (kCompToCoding[i].CompName == compName) {
+ eEncoding = kCompToCoding[i].eEncoding;
+ break;
+ }
+ }
+ ASSERT_NE(i, kNumCompToCoding);
+ }
+
+ virtual void TearDown() override {
+ if (omxNode != nullptr) {
+ EXPECT_TRUE((omxNode->freeNode()).isOk());
+ omxNode = nullptr;
+ }
+ }
+
+ enum standardComp {
+ mp3,
+ amrnb,
+ amrwb,
+ aac,
+ vorbis,
+ opus,
+ pcm,
+ flac,
+ unknown_comp,
+ };
+
+ sp<IOmx> omx;
+ sp<CodecObserver> observer;
+ sp<IOmxNode> omxNode;
+ standardComp compName;
+ OMX_AUDIO_CODINGTYPE eEncoding;
+};
+
+// Set Component Role
+TEST_F(AudioEncHidlTest, SetRole) {
+ android::hardware::media::omx::V1_0::Status status;
+ status = setRole(omxNode, gEnv->getRole().c_str());
+ ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+}
+
+// Enumerate Port Format
+TEST_F(AudioEncHidlTest, EnumeratePortFormat) {
+ android::hardware::media::omx::V1_0::Status status;
+ uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
+ status = setRole(omxNode, gEnv->getRole().c_str());
+ ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+ OMX_PORT_PARAM_TYPE params;
+ status = getParam(omxNode, OMX_IndexParamAudioInit, ¶ms);
+ if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
+ ASSERT_EQ(params.nPorts, 2U);
+ kPortIndexInput = params.nStartPortNumber;
+ kPortIndexOutput = kPortIndexInput + 1;
+ }
+ status = setAudioPortFormat(omxNode, kPortIndexInput, OMX_AUDIO_CodingPCM);
+ EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+ status = setAudioPortFormat(omxNode, kPortIndexOutput, eEncoding);
+ EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+}
+
+int main(int argc, char** argv) {
+ gEnv = new ComponentTestEnvironment();
+ ::testing::AddGlobalTestEnvironment(gEnv);
+ ::testing::InitGoogleTest(&argc, argv);
+ int status = gEnv->initFromOptions(argc, argv);
+ if (status == 0) {
+ status = RUN_ALL_TESTS();
+ ALOGI("Test result = %d", status);
+ }
+ return status;
+}
diff --git a/media/omx/1.0/vts/functional/audio/media_audio_hidl_test_common.cpp b/media/omx/1.0/vts/functional/audio/media_audio_hidl_test_common.cpp
new file mode 100644
index 0000000..e01e9aa
--- /dev/null
+++ b/media/omx/1.0/vts/functional/audio/media_audio_hidl_test_common.cpp
@@ -0,0 +1,316 @@
+/*
+ * Copyright (C) 2017 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 "media_omx_hidl_audio_test_common"
+#include <android-base/logging.h>
+
+#include <android/hardware/media/omx/1.0/IOmx.h>
+#include <android/hardware/media/omx/1.0/IOmxNode.h>
+#include <android/hardware/media/omx/1.0/IOmxObserver.h>
+#include <android/hardware/media/omx/1.0/types.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>
+
+using ::android::hardware::media::omx::V1_0::IOmx;
+using ::android::hardware::media::omx::V1_0::IOmxObserver;
+using ::android::hardware::media::omx::V1_0::IOmxNode;
+using ::android::hardware::media::omx::V1_0::Message;
+using ::android::hardware::media::omx::V1_0::CodecBuffer;
+using ::android::hidl::allocator::V1_0::IAllocator;
+using ::android::hidl::memory::V1_0::IMemory;
+using ::android::hidl::memory::V1_0::IMapper;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+#include <VtsHalHidlTargetTestBase.h>
+#include <hidlmemory/mapping.h>
+#include <media_audio_hidl_test_common.h>
+#include <media_hidl_test_common.h>
+#include <memory>
+
+void allocatePortBuffers(sp<IOmxNode> omxNode,
+ android::Vector<BufferInfo>* buffArray,
+ OMX_U32 portIndex) {
+ android::hardware::media::omx::V1_0::Status status;
+ OMX_PARAM_PORTDEFINITIONTYPE portDef;
+
+ buffArray->clear();
+
+ sp<IAllocator> allocator = IAllocator::getService("ashmem");
+ EXPECT_NE(allocator, nullptr);
+
+ status = getPortParam(omxNode, OMX_IndexParamPortDefinition, portIndex,
+ &portDef);
+ ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+ for (size_t i = 0; i < portDef.nBufferCountActual; i++) {
+ BufferInfo buffer;
+ buffer.owner = client;
+ buffer.omxBuffer.type = CodecBuffer::Type::SHARED_MEM;
+ buffer.omxBuffer.attr.preset.rangeOffset = 0;
+ buffer.omxBuffer.attr.preset.rangeLength = 0;
+ bool success;
+ allocator->allocate(
+ portDef.nBufferSize,
+ [&success, &buffer](bool _s,
+ ::android::hardware::hidl_memory const& mem) {
+ success = _s;
+ buffer.omxBuffer.sharedMemory = mem;
+ });
+ ASSERT_EQ(success, true);
+ buffer.mMemory = mapMemory(buffer.omxBuffer.sharedMemory);
+ ASSERT_NE(buffer.mMemory, nullptr);
+ omxNode->useBuffer(
+ portIndex, buffer.omxBuffer,
+ [&status, &buffer](android::hardware::media::omx::V1_0::Status _s,
+ uint32_t id) {
+ status = _s;
+ buffer.id = id;
+ });
+ buffArray->push(buffer);
+ ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+ }
+}
+
+size_t getEmptyBufferID(android::Vector<BufferInfo>* buffArray) {
+ for (size_t i = 0; i < buffArray->size(); i++) {
+ if ((*buffArray)[i].owner == client) return i;
+ }
+ return buffArray->size();
+}
+
+void dispatchInputBuffer(sp<IOmxNode> omxNode,
+ android::Vector<BufferInfo>* buffArray,
+ size_t bufferIndex, int bytesCount, uint32_t flags,
+ uint64_t timestamp) {
+ android::hardware::media::omx::V1_0::Status status;
+ CodecBuffer t;
+ t.sharedMemory = android::hardware::hidl_memory();
+ t.nativeHandle = android::hardware::hidl_handle();
+ t.type = CodecBuffer::Type::PRESET;
+ t.attr.preset.rangeOffset = 0;
+ t.attr.preset.rangeLength = bytesCount;
+ native_handle_t* fenceNh = native_handle_create(0, 0);
+ ASSERT_NE(fenceNh, nullptr);
+ status = omxNode->emptyBuffer((*buffArray)[bufferIndex].id, t, flags,
+ timestamp, fenceNh);
+ native_handle_close(fenceNh);
+ native_handle_delete(fenceNh);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+ buffArray->editItemAt(bufferIndex).owner = component;
+}
+
+void dispatchOutputBuffer(sp<IOmxNode> omxNode,
+ android::Vector<BufferInfo>* buffArray,
+ size_t bufferIndex) {
+ android::hardware::media::omx::V1_0::Status status;
+ CodecBuffer t;
+ t.sharedMemory = android::hardware::hidl_memory();
+ t.nativeHandle = android::hardware::hidl_handle();
+ t.type = CodecBuffer::Type::PRESET;
+ t.attr.preset.rangeOffset = 0;
+ t.attr.preset.rangeLength = 0;
+ native_handle_t* fenceNh = native_handle_create(0, 0);
+ ASSERT_NE(fenceNh, nullptr);
+ status = omxNode->fillBuffer((*buffArray)[bufferIndex].id, t, fenceNh);
+ native_handle_close(fenceNh);
+ native_handle_delete(fenceNh);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+ buffArray->editItemAt(bufferIndex).owner = component;
+}
+
+Return<android::hardware::media::omx::V1_0::Status> setAudioPortFormat(
+ sp<IOmxNode> omxNode, OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE encoding) {
+ OMX_U32 index = 0;
+ OMX_AUDIO_PARAM_PORTFORMATTYPE portFormat;
+ std::vector<OMX_AUDIO_CODINGTYPE> eEncoding;
+ android::hardware::media::omx::V1_0::Status status;
+
+ while (1) {
+ portFormat.nIndex = index;
+ status = getPortParam(omxNode, OMX_IndexParamAudioPortFormat, portIndex,
+ &portFormat);
+ if (status != ::android::hardware::media::omx::V1_0::Status::OK) break;
+ eEncoding.push_back(portFormat.eEncoding);
+ index++;
+ if (index == 512) {
+ EXPECT_LE(index, 512U)
+ << "Expecting OMX_ErrorNoMore but not received";
+ break;
+ }
+ }
+ if (!index) return status;
+ for (index = 0; index < eEncoding.size(); index++) {
+ if (eEncoding[index] == encoding) {
+ portFormat.eEncoding = eEncoding[index];
+ break;
+ }
+ }
+ if (index == eEncoding.size()) {
+ ALOGI("setting default Port format");
+ portFormat.eEncoding = eEncoding[0];
+ }
+ // In setParam call nIndex shall be ignored as per omx-il specification.
+ // see how this holds up by corrupting nIndex
+ portFormat.nIndex = RANDOM_INDEX;
+ status = setPortParam(omxNode, OMX_IndexParamAudioPortFormat, portIndex,
+ &portFormat);
+ return status;
+}
+
+Return<android::hardware::media::omx::V1_0::Status> setRole(
+ sp<IOmxNode> omxNode, const char* role) {
+ OMX_PARAM_COMPONENTROLETYPE params;
+ strcpy((char*)params.cRole, role);
+ return setParam(omxNode, OMX_IndexParamStandardComponentRole, ¶ms);
+}
+
+void setupPCMPort(sp<IOmxNode> omxNode, OMX_U32 portIndex, int32_t nChannels,
+ OMX_NUMERICALDATATYPE eNumData, int32_t nBitPerSample,
+ int32_t nSamplingRate) {
+ OMX_AUDIO_PARAM_PCMMODETYPE param;
+ android::hardware::media::omx::V1_0::Status status;
+ status = getPortParam(omxNode, OMX_IndexParamAudioPcm, portIndex, ¶m);
+ EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+ param.nChannels = nChannels;
+ param.eNumData = eNumData;
+ param.eEndian = OMX_EndianBig;
+ param.bInterleaved = OMX_TRUE;
+ param.nBitPerSample = nBitPerSample;
+ param.nSamplingRate = nSamplingRate;
+ param.ePCMMode = OMX_AUDIO_PCMModeLinear;
+ switch (nChannels) {
+ case 1:
+ param.eChannelMapping[0] = OMX_AUDIO_ChannelCF;
+ break;
+ case 2:
+ param.eChannelMapping[0] = OMX_AUDIO_ChannelLF;
+ param.eChannelMapping[1] = OMX_AUDIO_ChannelRF;
+ break;
+ default:
+ EXPECT_TRUE(false);
+ }
+ status = setPortParam(omxNode, OMX_IndexParamAudioPcm, portIndex, ¶m);
+ ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+}
+
+void setupMP3Port(sp<IOmxNode> omxNode, OMX_U32 portIndex,
+ OMX_AUDIO_MP3STREAMFORMATTYPE eFormat, int32_t nChannels,
+ int32_t nBitRate, int32_t nSampleRate, bool isEncoder) {
+ if (isEncoder == false) return;
+ OMX_AUDIO_PARAM_MP3TYPE param;
+ android::hardware::media::omx::V1_0::Status status;
+ status = getPortParam(omxNode, OMX_IndexParamAudioMp3, portIndex, ¶m);
+ EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+ param.nChannels = nChannels;
+ param.nBitRate = nBitRate;
+ param.nSampleRate = nSampleRate;
+ param.nAudioBandWidth = 0;
+ param.eChannelMode = (nChannels == 1) ? OMX_AUDIO_ChannelModeMono
+ : OMX_AUDIO_ChannelModeStereo;
+ param.eFormat = eFormat;
+ status = setPortParam(omxNode, OMX_IndexParamAudioMp3, portIndex, ¶m);
+ ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+}
+
+void setupFLACPort(sp<IOmxNode> omxNode, OMX_U32 portIndex, int32_t nChannels,
+ int32_t nSampleRate, int32_t nCompressionLevel,
+ bool isEncoder) {
+ if (isEncoder == false) return;
+ android::hardware::media::omx::V1_0::Status status;
+ OMX_AUDIO_PARAM_FLACTYPE param;
+ status = getPortParam(omxNode, OMX_IndexParamAudioFlac, portIndex, ¶m);
+ EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+ param.nChannels = nChannels;
+ param.nSampleRate = nSampleRate;
+ param.nCompressionLevel = nCompressionLevel;
+ status = setPortParam(omxNode, OMX_IndexParamAudioFlac, portIndex, ¶m);
+ ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+}
+
+void setupOPUSPort(sp<IOmxNode> omxNode, OMX_U32 portIndex, int32_t nChannels,
+ int32_t nBitRate, int32_t nSampleRate, bool isEncoder) {
+ if (isEncoder == false) return;
+ android::hardware::media::omx::V1_0::Status status;
+ OMX_AUDIO_PARAM_ANDROID_OPUSTYPE param;
+ status =
+ getPortParam(omxNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus,
+ portIndex, ¶m);
+ EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+ param.nChannels = nChannels;
+ param.nBitRate = nBitRate;
+ param.nSampleRate = nSampleRate;
+ status =
+ setPortParam(omxNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus,
+ portIndex, ¶m);
+ ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+}
+
+void setupAMRPort(sp<IOmxNode> omxNode, OMX_U32 portIndex, int32_t nBitRate,
+ OMX_AUDIO_AMRBANDMODETYPE eAMRBandMode, bool isEncoder) {
+ if (isEncoder == false) return;
+ android::hardware::media::omx::V1_0::Status status;
+ OMX_AUDIO_PARAM_AMRTYPE param;
+ status = getPortParam(omxNode, OMX_IndexParamAudioAmr, portIndex, ¶m);
+ EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+ param.nChannels = 1;
+ param.nBitRate = nBitRate;
+ param.eAMRBandMode = eAMRBandMode;
+ status = setPortParam(omxNode, OMX_IndexParamAudioAmr, portIndex, ¶m);
+ ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+}
+
+void setupVORBISPort(sp<IOmxNode> omxNode, OMX_U32 portIndex, int32_t nChannels,
+ int32_t nBitRate, int32_t nSampleRate, int32_t nQuality,
+ bool isEncoder) {
+ if (isEncoder == false) return;
+ android::hardware::media::omx::V1_0::Status status;
+ OMX_AUDIO_PARAM_VORBISTYPE param;
+ status =
+ getPortParam(omxNode, OMX_IndexParamAudioVorbis, portIndex, ¶m);
+ EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+ param.nChannels = nChannels;
+ param.nBitRate = nBitRate;
+ param.nSampleRate = nSampleRate;
+ param.nQuality = nQuality;
+ status =
+ setPortParam(omxNode, OMX_IndexParamAudioVorbis, portIndex, ¶m);
+ ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+}
+
+void setupAACPort(sp<IOmxNode> omxNode, OMX_U32 portIndex,
+ OMX_AUDIO_AACPROFILETYPE eAACProfile,
+ OMX_AUDIO_AACSTREAMFORMATTYPE eAACStreamFormat,
+ int32_t nChannels, int32_t nBitRate, int32_t nSampleRate,
+ bool isEncoder) {
+ if (isEncoder == false) return;
+ android::hardware::media::omx::V1_0::Status status;
+ OMX_AUDIO_PARAM_AACPROFILETYPE param;
+ status = getPortParam(omxNode, OMX_IndexParamAudioAac, portIndex, ¶m);
+ EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+ param.nChannels = nChannels;
+ param.nSampleRate = nSampleRate;
+ param.nBitRate = nBitRate;
+ param.eAACProfile = eAACProfile;
+ param.eAACStreamFormat = eAACStreamFormat;
+ param.eChannelMode = (nChannels == 1) ? OMX_AUDIO_ChannelModeMono
+ : OMX_AUDIO_ChannelModeStereo;
+ status = setPortParam(omxNode, OMX_IndexParamAudioAac, portIndex, ¶m);
+ ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+}
diff --git a/media/omx/1.0/vts/functional/audio/media_audio_hidl_test_common.h b/media/omx/1.0/vts/functional/audio/media_audio_hidl_test_common.h
new file mode 100644
index 0000000..bdf5d52
--- /dev/null
+++ b/media/omx/1.0/vts/functional/audio/media_audio_hidl_test_common.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright 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 MEDIA_AUDIO_HIDL_TEST_COMMON_H
+#define MEDIA_AUDIO_HIDL_TEST_COMMON_H
+
+#include <media_hidl_test_common.h>
+/*
+ * Random Index used for monkey testing while get/set parameters
+ */
+#define RANDOM_INDEX 1729
+
+/*
+ * Common audio utils
+ */
+void allocatePortBuffers(sp<IOmxNode> omxNode,
+ android::Vector<BufferInfo>* buffArray,
+ OMX_U32 portIndex);
+
+size_t getEmptyBufferID(android::Vector<BufferInfo>* buffArray);
+
+void dispatchInputBuffer(sp<IOmxNode> omxNode,
+ android::Vector<BufferInfo>* buffArray,
+ size_t bufferIndex, int bytesCount, uint32_t flags,
+ uint64_t timestamp);
+
+void dispatchOutputBuffer(sp<IOmxNode> omxNode,
+ android::Vector<BufferInfo>* buffArray,
+ size_t bufferIndex);
+
+Return<android::hardware::media::omx::V1_0::Status> setAudioPortFormat(
+ sp<IOmxNode> omxNode, OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE encoding);
+
+Return<android::hardware::media::omx::V1_0::Status> setRole(
+ sp<IOmxNode> omxNode, const char* role);
+
+void setupPCMPort(sp<IOmxNode> omxNode, OMX_U32 portIndex, int32_t nChannels,
+ OMX_NUMERICALDATATYPE eNumData, int32_t nBitPerSample,
+ int32_t nSamplingRate);
+
+void setupMP3Port(sp<IOmxNode> omxNode, OMX_U32 portIndex,
+ OMX_AUDIO_MP3STREAMFORMATTYPE eFormat, int32_t nChannels,
+ int32_t nBitRate, int32_t nSampleRate, bool isEncoder);
+
+void setupFLACPort(sp<IOmxNode> omxNode, OMX_U32 portIndex, int32_t nChannels,
+ int32_t nSampleRate, int32_t nCompressionLevel,
+ bool isEncoder);
+
+void setupOPUSPort(sp<IOmxNode> omxNode, OMX_U32 portIndex, int32_t nChannels,
+ int32_t nBitRate, int32_t nSampleRate, bool isEncoder);
+
+void setupAMRPort(sp<IOmxNode> omxNode, OMX_U32 portIndex, int32_t nBitRate,
+ OMX_AUDIO_AMRBANDMODETYPE eAMRBandMode, bool isEncoder);
+
+void setupVORBISPort(sp<IOmxNode> omxNode, OMX_U32 portIndex, int32_t nChannels,
+ int32_t nBitRate, int32_t nSampleRate, int32_t nQuality,
+ bool isEncoder);
+
+void setupAACPort(sp<IOmxNode> omxNode, OMX_U32 portIndex,
+ OMX_AUDIO_AACPROFILETYPE eAACProfile,
+ OMX_AUDIO_AACSTREAMFORMATTYPE eAACStreamFormat,
+ int32_t nChannels, int32_t nBitRate, int32_t nSampleRate,
+ bool isEncoder);
+
+#endif // MEDIA_AUDIO_HIDL_TEST_COMMON_H
diff --git a/media/omx/1.0/vts/functional/common/media_hidl_test_common.h b/media/omx/1.0/vts/functional/common/media_hidl_test_common.h
new file mode 100644
index 0000000..9421463
--- /dev/null
+++ b/media/omx/1.0/vts/functional/common/media_hidl_test_common.h
@@ -0,0 +1,206 @@
+/*
+ * Copyright 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 MEDIA_HIDL_TEST_COMMON_H
+#define MEDIA_HIDL_TEST_COMMON_H
+
+#include <media/stagefright/foundation/ALooper.h>
+#include <utils/Condition.h>
+#include <utils/List.h>
+#include <utils/Mutex.h>
+
+#include <media/openmax/OMX_Index.h>
+#include <media/openmax/OMX_Core.h>
+#include <media/openmax/OMX_Component.h>
+#include <media/openmax/OMX_IndexExt.h>
+#include <media/openmax/OMX_AudioExt.h>
+
+/*
+ * TODO: Borrowed from Conversion.h. This is not the ideal way to do it.
+ * Loose these definitions once you include Conversion.h
+ */
+inline uint32_t toRawIndexType(OMX_INDEXTYPE l) {
+ return static_cast<uint32_t>(l);
+}
+
+inline android::hardware::media::omx::V1_0::Status toStatus(
+ android::status_t l) {
+ return static_cast<android::hardware::media::omx::V1_0::Status>(l);
+}
+
+inline hidl_vec<uint8_t> inHidlBytes(void const* l, size_t size) {
+ hidl_vec<uint8_t> t;
+ t.setToExternal(static_cast<uint8_t*>(const_cast<void*>(l)), size, false);
+ return t;
+}
+
+inline uint32_t toRawCommandType(OMX_COMMANDTYPE l) {
+ return static_cast<uint32_t>(l);
+}
+
+/*
+ * Handle Callback functions EmptythisBuffer(), FillthisBuffer(),
+ * EventHandler()
+ */
+#define DEFAULT_TIMEOUT 40000
+
+enum bufferOwner {
+ client,
+ component,
+ unknown,
+};
+
+struct BufferInfo {
+ uint32_t id;
+ bufferOwner owner;
+ android::hardware::media::omx::V1_0::CodecBuffer omxBuffer;
+ ::android::sp<IMemory> mMemory;
+};
+
+struct CodecObserver : public IOmxObserver {
+ public:
+ Return<void> onMessages(const hidl_vec<Message>& messages) override {
+ android::Mutex::Autolock autoLock(msgLock);
+ for (hidl_vec<Message>::const_iterator it = messages.begin();
+ it != messages.end(); ++it) {
+ msgQueue.push_back(*it);
+ }
+ msgCondition.signal();
+ return Void();
+ }
+ android::hardware::media::omx::V1_0::Status dequeueMessage(
+ Message* msg, int64_t timeoutUs,
+ android::Vector<BufferInfo>* iBuffers = nullptr,
+ android::Vector<BufferInfo>* oBuffers = nullptr) {
+ int64_t finishBy = android::ALooper::GetNowUs() + timeoutUs;
+ for (;;) {
+ android::Mutex::Autolock autoLock(msgLock);
+ android::List<Message>::iterator it = msgQueue.begin();
+ while (it != msgQueue.end()) {
+ if (it->type ==
+ android::hardware::media::omx::V1_0::Message::Type::EVENT) {
+ *msg = *it;
+ msgQueue.erase(it);
+ return ::android::hardware::media::omx::V1_0::Status::OK;
+ } else if (it->type == android::hardware::media::omx::V1_0::
+ Message::Type::FILL_BUFFER_DONE) {
+ if (oBuffers) {
+ size_t i;
+ for (i = 0; i < oBuffers->size(); ++i) {
+ if ((*oBuffers)[i].id ==
+ it->data.bufferData.buffer) {
+ oBuffers->editItemAt(i).owner = client;
+ msgQueue.erase(it);
+ break;
+ }
+ }
+ EXPECT_LE(i, oBuffers->size());
+ }
+ } else if (it->type == android::hardware::media::omx::V1_0::
+ Message::Type::EMPTY_BUFFER_DONE) {
+ if (iBuffers) {
+ size_t i;
+ for (i = 0; i < iBuffers->size(); ++i) {
+ if ((*iBuffers)[i].id ==
+ it->data.bufferData.buffer) {
+ iBuffers->editItemAt(i).owner = client;
+ msgQueue.erase(it);
+ break;
+ }
+ }
+ EXPECT_LE(i, iBuffers->size());
+ }
+ }
+ ++it;
+ }
+ android::status_t err =
+ (timeoutUs < 0)
+ ? msgCondition.wait(msgLock)
+ : msgCondition.waitRelative(
+ msgLock,
+ (finishBy - android::ALooper::GetNowUs()) * 1000);
+ if (err == android::TIMED_OUT) return toStatus(err);
+ }
+ }
+
+ android::List<Message> msgQueue;
+ android::Mutex msgLock;
+ android::Condition msgCondition;
+};
+
+/*
+ * Useful Wrapper utilities
+ */
+template <class T>
+void InitOMXParams(T* params) {
+ params->nSize = sizeof(T);
+ params->nVersion.s.nVersionMajor = 1;
+ params->nVersion.s.nVersionMinor = 0;
+ params->nVersion.s.nRevision = 0;
+ params->nVersion.s.nStep = 0;
+}
+
+template <class T>
+Return<android::hardware::media::omx::V1_0::Status> getParam(
+ sp<IOmxNode> omxNode, OMX_INDEXTYPE omxIdx, T* params) {
+ android::hardware::media::omx::V1_0::Status status;
+ InitOMXParams(params);
+ omxNode->getParameter(
+ toRawIndexType(omxIdx), inHidlBytes(params, sizeof(*params)),
+ [&status, ¶ms](android::hardware::media::omx::V1_0::Status _s,
+ hidl_vec<uint8_t> const& outParams) {
+ status = _s;
+ std::copy(outParams.data(), outParams.data() + outParams.size(),
+ static_cast<uint8_t*>(static_cast<void*>(params)));
+ });
+ return status;
+}
+
+template <class T>
+Return<android::hardware::media::omx::V1_0::Status> setParam(
+ sp<IOmxNode> omxNode, OMX_INDEXTYPE omxIdx, T* params) {
+ InitOMXParams(params);
+ return omxNode->setParameter(toRawIndexType(omxIdx),
+ inHidlBytes(params, sizeof(*params)));
+}
+
+template <class T>
+Return<android::hardware::media::omx::V1_0::Status> getPortParam(
+ sp<IOmxNode> omxNode, OMX_INDEXTYPE omxIdx, OMX_U32 nPortIndex, T* params) {
+ android::hardware::media::omx::V1_0::Status status;
+ InitOMXParams(params);
+ params->nPortIndex = nPortIndex;
+ omxNode->getParameter(
+ toRawIndexType(omxIdx), inHidlBytes(params, sizeof(*params)),
+ [&status, ¶ms](android::hardware::media::omx::V1_0::Status _s,
+ hidl_vec<uint8_t> const& outParams) {
+ status = _s;
+ std::copy(outParams.data(), outParams.data() + outParams.size(),
+ static_cast<uint8_t*>(static_cast<void*>(params)));
+ });
+ return status;
+}
+
+template <class T>
+Return<android::hardware::media::omx::V1_0::Status> setPortParam(
+ sp<IOmxNode> omxNode, OMX_INDEXTYPE omxIdx, OMX_U32 nPortIndex, T* params) {
+ InitOMXParams(params);
+ params->nPortIndex = nPortIndex;
+ return omxNode->setParameter(toRawIndexType(omxIdx),
+ inHidlBytes(params, sizeof(*params)));
+}
+
+#endif // MEDIA_HIDL_TEST_COMMON_H
diff --git a/media/omx/1.0/vts/functional/component/Android.bp b/media/omx/1.0/vts/functional/component/Android.bp
new file mode 100644
index 0000000..02fe182
--- /dev/null
+++ b/media/omx/1.0/vts/functional/component/Android.bp
@@ -0,0 +1,45 @@
+//
+// Copyright (C) 2017 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: "VtsHalMediaOmxV1_0TargetComponentTest",
+ defaults: ["hidl_defaults"],
+ srcs: ["VtsHalMediaOmxV1_0TargetComponentTest.cpp"],
+ shared_libs: [
+ "libbase",
+ "liblog",
+ "libcutils",
+ "libhidlbase",
+ "libhidltransport",
+ "libhwbinder",
+ "libnativehelper",
+ "libutils",
+ "libstagefright_foundation",
+ "android.hidl.allocator@1.0",
+ "android.hidl.memory@1.0",
+ "android.hardware.media.omx@1.0",
+ ],
+ static_libs: ["VtsHalHidlTargetTestBase"],
+ cflags: [
+ "-O0",
+ "-g",
+ ],
+ include_dirs: [
+ "frameworks/native/include/media/openmax/",
+ "hardware/interfaces/media/omx/1.0/vts/functional/common",
+ ],
+}
+
diff --git a/media/omx/1.0/vts/functional/component/VtsHalMediaOmxV1_0TargetComponentTest.cpp b/media/omx/1.0/vts/functional/component/VtsHalMediaOmxV1_0TargetComponentTest.cpp
new file mode 100644
index 0000000..fdffd66
--- /dev/null
+++ b/media/omx/1.0/vts/functional/component/VtsHalMediaOmxV1_0TargetComponentTest.cpp
@@ -0,0 +1,1213 @@
+/*
+ * Copyright (C) 2017 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 "media_omx_hidl_component_test"
+#include <android-base/logging.h>
+
+#include <android/hardware/media/omx/1.0/IOmx.h>
+#include <android/hardware/media/omx/1.0/IOmxNode.h>
+#include <android/hardware/media/omx/1.0/IOmxObserver.h>
+#include <android/hardware/media/omx/1.0/types.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>
+
+using ::android::hardware::media::omx::V1_0::IOmx;
+using ::android::hardware::media::omx::V1_0::IOmxObserver;
+using ::android::hardware::media::omx::V1_0::IOmxNode;
+using ::android::hardware::media::omx::V1_0::Message;
+using ::android::hardware::media::omx::V1_0::CodecBuffer;
+using ::android::hidl::allocator::V1_0::IAllocator;
+using ::android::hidl::memory::V1_0::IMemory;
+using ::android::hidl::memory::V1_0::IMapper;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+#include <VtsHalHidlTargetTestBase.h>
+#include <getopt.h>
+#include <media_hidl_test_common.h>
+
+// A class for test environment setup
+class ComponentTestEnvironment : public ::testing::Environment {
+ public:
+ virtual void SetUp() {}
+ virtual void TearDown() {}
+
+ ComponentTestEnvironment() : instance("default") {}
+
+ void setInstance(const char* _instance) { instance = _instance; }
+
+ void setComponent(const char* _component) { component = _component; }
+
+ void setRole(const char* _role) { role = _role; }
+
+ void setQuirks(int _quirks) { quirks = _quirks; }
+
+ const hidl_string getInstance() const { return instance; }
+
+ const hidl_string getComponent() const { return component; }
+
+ const hidl_string getRole() const { return role; }
+
+ int getQuirks() const { return quirks; }
+
+ int initFromOptions(int argc, char** argv) {
+ static struct option options[] = {
+ {"instance", required_argument, 0, 'I'},
+ {"component", required_argument, 0, 'C'},
+ {"role", required_argument, 0, 'R'},
+ {"quirks", required_argument, 0, 'Q'},
+ {0, 0, 0, 0}};
+
+ while (true) {
+ int index = 0;
+ int c = getopt_long(argc, argv, "I:C:Q:R:", options, &index);
+ if (c == -1) {
+ break;
+ }
+
+ switch (c) {
+ case 'I':
+ setInstance(optarg);
+ break;
+ case 'C':
+ setComponent(optarg);
+ break;
+ case 'Q':
+ setQuirks(atoi(optarg));
+ break;
+ case 'R':
+ setRole(optarg);
+ break;
+ case '?':
+ break;
+ }
+ }
+
+ if (optind < argc) {
+ fprintf(stderr,
+ "unrecognized option: %s\n\n"
+ "usage: %s <gtest options> <test options>\n\n"
+ "test options are:\n\n"
+ "-I, --instance: HAL instance to test\n"
+ "-C, --component: OMX component to test\n"
+ "-R, --Role: OMX component Role\n"
+ "-Q, --quirks: Component quirks\n",
+ argv[optind ?: 1], argv[0]);
+ return 2;
+ }
+ return 0;
+ }
+
+ private:
+ hidl_string instance;
+ hidl_string component;
+ hidl_string role;
+ // to be removed when IOmxNode::setQuirks is removed
+ int quirks;
+};
+
+static ComponentTestEnvironment* gEnv = nullptr;
+
+class ComponentHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+ public:
+ virtual void SetUp() override {
+ android::hardware::media::omx::V1_0::Status status;
+ omx = ::testing::VtsHalHidlTargetTestBase::getService<IOmx>(
+ gEnv->getInstance());
+ ASSERT_NE(omx, nullptr);
+ observer = new CodecObserver();
+ ASSERT_NE(observer, nullptr);
+ ASSERT_EQ(strncmp(gEnv->getComponent().c_str(), "OMX.", 4), 0)
+ << "Invalid Component Name";
+ EXPECT_TRUE(omx->allocateNode(
+ gEnv->getComponent(), observer,
+ [&](android::hardware::media::omx::V1_0::Status _s,
+ sp<IOmxNode> const& _nl) {
+ status = _s;
+ this->omxNode = _nl;
+ })
+ .isOk());
+ ASSERT_NE(omxNode, nullptr);
+ ASSERT_NE(gEnv->getRole().empty(), true) << "Invalid Component Role";
+ struct StringToClass {
+ const char* Class;
+ standardCompClass CompClass;
+ };
+ const StringToClass kStringToClass[] = {
+ {"audio_decoder", audio_decoder},
+ {"audio_encoder", audio_encoder},
+ {"video_decoder", video_decoder},
+ {"video_encoder", video_encoder},
+ };
+ const size_t kNumStringToClass =
+ sizeof(kStringToClass) / sizeof(kStringToClass[0]);
+ const char* pch;
+ char substring[OMX_MAX_STRINGNAME_SIZE];
+ strcpy(substring, gEnv->getRole().c_str());
+ pch = strchr(substring, '.');
+ ASSERT_NE(pch, nullptr) << "Invalid Component Role";
+ substring[pch - substring] = '\0';
+ compClass = unknown_class;
+ for (size_t i = 0; i < kNumStringToClass; ++i) {
+ if (!strcasecmp(substring, kStringToClass[i].Class)) {
+ compClass = kStringToClass[i].CompClass;
+ break;
+ }
+ }
+ ASSERT_NE(compClass, unknown_class) << "Invalid Component Class";
+
+ allocator = ::testing::VtsHalHidlTargetTestBase::getService<IAllocator>(
+ "ashmem");
+ ASSERT_NE(allocator, nullptr);
+ }
+
+ virtual void TearDown() override {
+ if (omxNode != nullptr) {
+ EXPECT_TRUE((omxNode->freeNode()).isOk());
+ omxNode = nullptr;
+ }
+ }
+
+ enum standardCompClass {
+ audio_decoder,
+ audio_encoder,
+ video_decoder,
+ video_encoder,
+ unknown_class,
+ };
+
+ sp<IOmx> omx;
+ sp<CodecObserver> observer;
+ sp<IOmxNode> omxNode;
+ sp<IAllocator> allocator;
+ standardCompClass compClass;
+};
+
+#define RANDOM_INDEX 1729
+
+void allocatePortBuffers(sp<IOmxNode> omxNode, sp<IAllocator> allocator,
+ android::Vector<BufferInfo>* buffArray,
+ OMX_U32 portIndex) {
+ android::hardware::media::omx::V1_0::Status status;
+ OMX_PARAM_PORTDEFINITIONTYPE portDef;
+
+ buffArray->clear();
+
+ status = getPortParam(omxNode, OMX_IndexParamPortDefinition, portIndex,
+ &portDef);
+ ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+ for (size_t i = 0; i < portDef.nBufferCountActual; i++) {
+ BufferInfo buffer;
+ buffer.owner = client;
+ buffer.omxBuffer.type = CodecBuffer::Type::SHARED_MEM;
+ buffer.omxBuffer.attr.preset.rangeOffset = 0;
+ buffer.omxBuffer.attr.preset.rangeLength = 0;
+ bool success;
+ allocator->allocate(
+ portDef.nBufferSize,
+ [&success, &buffer](bool _s,
+ ::android::hardware::hidl_memory const& mem) {
+ success = _s;
+ buffer.omxBuffer.sharedMemory = mem;
+ });
+ ASSERT_EQ(success, true);
+
+ omxNode->useBuffer(
+ portIndex, buffer.omxBuffer,
+ [&status, &buffer](android::hardware::media::omx::V1_0::Status _s,
+ uint32_t id) {
+ status = _s;
+ buffer.id = id;
+ });
+ buffArray->push(buffer);
+ ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+ }
+}
+
+Return<android::hardware::media::omx::V1_0::Status> setVideoPortFormat(
+ sp<IOmxNode> omxNode, OMX_U32 portIndex,
+ OMX_VIDEO_CODINGTYPE compressionFormat, OMX_COLOR_FORMATTYPE colorFormat,
+ OMX_U32 frameRate) {
+ OMX_U32 index = 0;
+ OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat;
+ std::vector<OMX_COLOR_FORMATTYPE> eColorFormat;
+ std::vector<OMX_VIDEO_CODINGTYPE> eCompressionFormat;
+ android::hardware::media::omx::V1_0::Status status;
+
+ while (1) {
+ portFormat.nIndex = index;
+ status = getPortParam(omxNode, OMX_IndexParamVideoPortFormat, portIndex,
+ &portFormat);
+ if (status != ::android::hardware::media::omx::V1_0::Status::OK) break;
+ if (compressionFormat == OMX_VIDEO_CodingUnused)
+ eColorFormat.push_back(portFormat.eColorFormat);
+ else
+ eCompressionFormat.push_back(portFormat.eCompressionFormat);
+ index++;
+ if (index == 512) {
+ EXPECT_LE(index, 512U)
+ << "Expecting OMX_ErrorNoMore but not received";
+ break;
+ }
+ }
+ if (!index) return status;
+ if (compressionFormat == OMX_VIDEO_CodingUnused) {
+ for (index = 0; index < eColorFormat.size(); index++) {
+ if (eColorFormat[index] == colorFormat) {
+ portFormat.eColorFormat = eColorFormat[index];
+ break;
+ }
+ }
+ if (index == eColorFormat.size()) {
+ ALOGI("setting default color format");
+ portFormat.eColorFormat = eColorFormat[0];
+ }
+ portFormat.eCompressionFormat = OMX_VIDEO_CodingUnused;
+ } else {
+ for (index = 0; index < eCompressionFormat.size(); index++) {
+ if (eCompressionFormat[index] == compressionFormat) {
+ portFormat.eCompressionFormat = eCompressionFormat[index];
+ break;
+ }
+ }
+ if (index == eCompressionFormat.size()) {
+ ALOGI("setting default compression format");
+ portFormat.eCompressionFormat = eCompressionFormat[0];
+ }
+ portFormat.eColorFormat = OMX_COLOR_FormatUnused;
+ }
+ // In setParam call nIndex shall be ignored as per omx-il specification.
+ // see how this holds up by corrupting nIndex
+ portFormat.nIndex = RANDOM_INDEX;
+ portFormat.xFramerate = frameRate;
+ status = setPortParam(omxNode, OMX_IndexParamVideoPortFormat, portIndex,
+ &portFormat);
+ return status;
+}
+
+Return<android::hardware::media::omx::V1_0::Status> setAudioPortFormat(
+ sp<IOmxNode> omxNode, OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE encoding) {
+ OMX_U32 index = 0;
+ OMX_AUDIO_PARAM_PORTFORMATTYPE portFormat;
+ std::vector<OMX_AUDIO_CODINGTYPE> eEncoding;
+ android::hardware::media::omx::V1_0::Status status;
+
+ while (1) {
+ portFormat.nIndex = index;
+ status = getPortParam(omxNode, OMX_IndexParamAudioPortFormat, portIndex,
+ &portFormat);
+ if (status != ::android::hardware::media::omx::V1_0::Status::OK) break;
+ eEncoding.push_back(portFormat.eEncoding);
+ index++;
+ if (index == 512) {
+ EXPECT_LE(index, 512U)
+ << "Expecting OMX_ErrorNoMore but not received";
+ break;
+ }
+ }
+ if (!index) return status;
+ for (index = 0; index < eEncoding.size(); index++) {
+ if (eEncoding[index] == encoding) {
+ portFormat.eEncoding = eEncoding[index];
+ break;
+ }
+ }
+ if (index == eEncoding.size()) {
+ ALOGI("setting default Port format");
+ portFormat.eEncoding = eEncoding[0];
+ }
+ // In setParam call nIndex shall be ignored as per omx-il specification.
+ // see how this holds up by corrupting nIndex
+ portFormat.nIndex = RANDOM_INDEX;
+ status = setPortParam(omxNode, OMX_IndexParamAudioPortFormat, portIndex,
+ &portFormat);
+ return status;
+}
+
+Return<android::hardware::media::omx::V1_0::Status> setRole(
+ sp<IOmxNode> omxNode, const char* role) {
+ OMX_PARAM_COMPONENTROLETYPE params;
+ strcpy((char*)params.cRole, role);
+ return setParam(omxNode, OMX_IndexParamStandardComponentRole, ¶ms);
+}
+
+// Set Component Role
+TEST_F(ComponentHidlTest, SetRole) {
+ android::hardware::media::omx::V1_0::Status status;
+ status = setRole(omxNode, gEnv->getRole().c_str());
+ EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+}
+
+// Get Number of Ports and their Indices for all Domains
+// (Audio/Video/Image/Other)
+TEST_F(ComponentHidlTest, GetPortIndices) {
+ android::hardware::media::omx::V1_0::Status status;
+ OMX_PORT_PARAM_TYPE params;
+
+ status = setRole(omxNode, gEnv->getRole().c_str());
+ ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+
+ // All standard OMX components shall support following OMX Index types
+ status = getParam(omxNode, OMX_IndexParamAudioInit, ¶ms);
+ EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+ status = getParam(omxNode, OMX_IndexParamVideoInit, ¶ms);
+ EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+ status = getParam(omxNode, OMX_IndexParamImageInit, ¶ms);
+ EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+ status = getParam(omxNode, OMX_IndexParamOtherInit, ¶ms);
+ EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+}
+
+// Enumerate Port Format
+TEST_F(ComponentHidlTest, EnumeratePortFormat) {
+ android::hardware::media::omx::V1_0::Status status;
+ uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
+
+ status = setRole(omxNode, gEnv->getRole().c_str());
+ ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+ OMX_PORT_PARAM_TYPE params;
+ if (compClass == audio_decoder || compClass == audio_encoder) {
+ status = getParam(omxNode, OMX_IndexParamAudioInit, ¶ms);
+ } else {
+ status = getParam(omxNode, OMX_IndexParamVideoInit, ¶ms);
+ }
+ if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
+ ASSERT_EQ(params.nPorts, 2U);
+ kPortIndexInput = params.nStartPortNumber;
+ kPortIndexOutput = kPortIndexInput + 1;
+ }
+
+ OMX_COLOR_FORMATTYPE colorFormat = OMX_COLOR_FormatYUV420Planar;
+ OMX_U32 frameRate = 24 << 16;
+
+ if (compClass == audio_encoder) {
+ status =
+ setAudioPortFormat(omxNode, kPortIndexInput, OMX_AUDIO_CodingPCM);
+ EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+ status = setAudioPortFormat(omxNode, kPortIndexOutput,
+ OMX_AUDIO_CodingAutoDetect);
+ EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+ } else if (compClass == audio_decoder) {
+ status = setAudioPortFormat(omxNode, kPortIndexInput,
+ OMX_AUDIO_CodingAutoDetect);
+ EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+ status =
+ setAudioPortFormat(omxNode, kPortIndexOutput, OMX_AUDIO_CodingPCM);
+ EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+ } else if (compClass == video_encoder) {
+ status =
+ setVideoPortFormat(omxNode, kPortIndexInput, OMX_VIDEO_CodingUnused,
+ colorFormat, frameRate);
+ EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+ status = setVideoPortFormat(omxNode, kPortIndexOutput,
+ OMX_VIDEO_CodingAutoDetect,
+ OMX_COLOR_FormatUnused, 0U);
+ EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+ } else {
+ status = setVideoPortFormat(omxNode, kPortIndexInput,
+ OMX_VIDEO_CodingAutoDetect,
+ OMX_COLOR_FormatUnused, 0U);
+ EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+ status =
+ setVideoPortFormat(omxNode, kPortIndexOutput,
+ OMX_VIDEO_CodingUnused, colorFormat, frameRate);
+ EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+ }
+}
+
+// r/w default i/o port parameters
+TEST_F(ComponentHidlTest, SetDefaultPortParams) {
+ android::hardware::media::omx::V1_0::Status status;
+ uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
+
+ status = setRole(omxNode, gEnv->getRole().c_str());
+ ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+ OMX_PORT_PARAM_TYPE params;
+ if (compClass == audio_decoder || compClass == audio_encoder) {
+ status = getParam(omxNode, OMX_IndexParamAudioInit, ¶ms);
+ } else {
+ status = getParam(omxNode, OMX_IndexParamVideoInit, ¶ms);
+ }
+ if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
+ ASSERT_EQ(params.nPorts, 2U);
+ kPortIndexInput = params.nStartPortNumber;
+ kPortIndexOutput = kPortIndexInput + 1;
+ }
+
+ OMX_PARAM_PORTDEFINITIONTYPE iPortDef;
+ status = getPortParam(omxNode, OMX_IndexParamPortDefinition,
+ kPortIndexInput, &iPortDef);
+ EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+
+ if (status == android::hardware::media::omx::V1_0::Status::OK) {
+ EXPECT_EQ(iPortDef.eDir, OMX_DirInput);
+ EXPECT_EQ(iPortDef.bEnabled, OMX_TRUE);
+ EXPECT_EQ(iPortDef.bPopulated, 0);
+ EXPECT_GE(iPortDef.nBufferCountMin, 1U);
+ EXPECT_GE(iPortDef.nBufferCountActual, iPortDef.nBufferCountMin);
+ if (compClass == audio_encoder || compClass == audio_decoder) {
+ EXPECT_EQ(iPortDef.eDomain, OMX_PortDomainAudio);
+ if (compClass == audio_decoder) {
+ iPortDef.format.audio.bFlagErrorConcealment = OMX_TRUE;
+ status = setPortParam(omxNode, OMX_IndexParamPortDefinition,
+ kPortIndexInput, &iPortDef);
+ }
+ EXPECT_EQ(status,
+ ::android::hardware::media::omx::V1_0::Status::OK);
+ } else if (compClass == video_encoder || compClass == video_decoder) {
+ EXPECT_EQ(iPortDef.eDomain, OMX_PortDomainVideo);
+ }
+ OMX_PARAM_PORTDEFINITIONTYPE dummy = iPortDef;
+ iPortDef.nBufferCountActual = iPortDef.nBufferCountMin - 1;
+ status = setPortParam(omxNode, OMX_IndexParamPortDefinition,
+ kPortIndexInput, &iPortDef);
+ EXPECT_NE(status, ::android::hardware::media::omx::V1_0::Status::OK);
+ // Edit Read-Only fields.
+ iPortDef.eDir = OMX_DirOutput; // Read Only field
+ iPortDef.nBufferCountActual = dummy.nBufferCountActual << 1;
+ iPortDef.nBufferCountMin = dummy.nBufferCountMin
+ << 1; // Read Only field
+ iPortDef.nBufferSize = dummy.nBufferSize << 1; // Read Only field
+ status = setPortParam(omxNode, OMX_IndexParamPortDefinition,
+ kPortIndexInput, &iPortDef);
+ EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+ status = getPortParam(omxNode, OMX_IndexParamPortDefinition,
+ kPortIndexInput, &iPortDef);
+ EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+ EXPECT_EQ(iPortDef.nBufferCountActual, dummy.nBufferCountActual << 1);
+ if ((iPortDef.eDir != OMX_DirInput) ||
+ (iPortDef.nBufferCountMin != dummy.nBufferCountMin) ||
+ (iPortDef.nBufferSize != dummy.nBufferSize)) {
+ ALOGI(
+ "Warning, Component does not seem to preserve Read-Only "
+ "fields");
+ printf(
+ "Warning, Component does not seem to preserve Read-Only fields "
+ "\n");
+ }
+ }
+
+ OMX_PARAM_PORTDEFINITIONTYPE oPortDef;
+ status = getPortParam(omxNode, OMX_IndexParamPortDefinition,
+ kPortIndexOutput, &oPortDef);
+ EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+ if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
+ EXPECT_EQ(oPortDef.eDir, OMX_DirOutput);
+ EXPECT_EQ(oPortDef.bEnabled, OMX_TRUE);
+ EXPECT_EQ(oPortDef.bPopulated, 0);
+ EXPECT_GE(oPortDef.nBufferCountMin, 1U);
+ EXPECT_GE(oPortDef.nBufferCountActual, oPortDef.nBufferCountMin);
+ if (compClass == audio_encoder || compClass == audio_decoder) {
+ EXPECT_EQ(oPortDef.eDomain, OMX_PortDomainAudio);
+ if (compClass == audio_encoder) {
+ oPortDef.format.audio.bFlagErrorConcealment = OMX_TRUE;
+ status = setPortParam(omxNode, OMX_IndexParamPortDefinition,
+ kPortIndexOutput, &oPortDef);
+ }
+ EXPECT_EQ(status,
+ ::android::hardware::media::omx::V1_0::Status::OK);
+ } else if (compClass == video_encoder || compClass == video_decoder) {
+ EXPECT_EQ(oPortDef.eDomain, OMX_PortDomainVideo);
+ }
+ OMX_PARAM_PORTDEFINITIONTYPE dummy = oPortDef;
+ oPortDef.nBufferCountActual = oPortDef.nBufferCountMin - 1;
+ status = setPortParam(omxNode, OMX_IndexParamPortDefinition,
+ kPortIndexOutput, &oPortDef);
+ EXPECT_NE(status, ::android::hardware::media::omx::V1_0::Status::OK);
+ // Edit Read-Only fields.
+ oPortDef.eDir = OMX_DirInput; // Read Only field
+ oPortDef.nBufferCountActual = dummy.nBufferCountActual << 1;
+ oPortDef.nBufferCountMin = dummy.nBufferCountMin
+ << 1; // Read Only field
+ oPortDef.nBufferSize = dummy.nBufferSize << 1; // Read Only field
+ status = setPortParam(omxNode, OMX_IndexParamPortDefinition,
+ kPortIndexOutput, &oPortDef);
+ EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+ status = getPortParam(omxNode, OMX_IndexParamPortDefinition,
+ kPortIndexOutput, &oPortDef);
+ EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+ EXPECT_EQ(oPortDef.nBufferCountActual, dummy.nBufferCountActual << 1);
+ if ((oPortDef.eDir != OMX_DirOutput) ||
+ (oPortDef.nBufferCountMin != dummy.nBufferCountMin) ||
+ (oPortDef.nBufferSize != dummy.nBufferSize)) {
+ ALOGI(
+ "Warning, Component does not seem to preserve Read-Only "
+ "fields");
+ printf(
+ "Warning, Component does not seem to preserve Read-Only fields "
+ "\n");
+ }
+ }
+}
+
+// Test State Transitions & Flush
+TEST_F(ComponentHidlTest, StateTransitions_Flush) {
+ android::hardware::media::omx::V1_0::Status status;
+ uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
+ Message msg;
+
+ status = setRole(omxNode, gEnv->getRole().c_str());
+ ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+ OMX_PORT_PARAM_TYPE params;
+ if (compClass == audio_decoder || compClass == audio_encoder) {
+ status = getParam(omxNode, OMX_IndexParamAudioInit, ¶ms);
+ } else {
+ status = getParam(omxNode, OMX_IndexParamVideoInit, ¶ms);
+ }
+ if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
+ ASSERT_EQ(params.nPorts, 2U);
+ kPortIndexInput = params.nStartPortNumber;
+ kPortIndexOutput = kPortIndexInput + 1;
+ }
+
+ android::Vector<BufferInfo> iBuffer, oBuffer;
+
+ // set state to idle
+ status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
+ OMX_StateIdle);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+
+ // Dont switch states until the ports got their buffers
+ status =
+ observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &iBuffer, &oBuffer);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::TIMED_OUT);
+
+ // allocate buffers on input port
+ allocatePortBuffers(omxNode, allocator, &iBuffer, kPortIndexInput);
+
+ // Dont switch states until the ports got their buffers
+ status =
+ observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &iBuffer, &oBuffer);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::TIMED_OUT);
+
+ // allocate buffers on output port
+ allocatePortBuffers(omxNode, allocator, &oBuffer, kPortIndexOutput);
+
+ status =
+ observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &iBuffer, &oBuffer);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+ ASSERT_EQ(msg.type, Message::Type::EVENT);
+ ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
+ ASSERT_EQ(msg.data.eventData.data1, OMX_CommandStateSet);
+ ASSERT_EQ(msg.data.eventData.data2, OMX_StateIdle);
+
+ // set state to executing
+ status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
+ OMX_StateExecuting);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+ status =
+ observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &iBuffer, &oBuffer);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+ ASSERT_EQ(msg.type, Message::Type::EVENT);
+ ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
+ ASSERT_EQ(msg.data.eventData.data1, OMX_CommandStateSet);
+ ASSERT_EQ(msg.data.eventData.data2, OMX_StateExecuting);
+
+ CodecBuffer t;
+ t.sharedMemory = android::hardware::hidl_memory();
+ t.nativeHandle = android::hardware::hidl_handle();
+ t.type = CodecBuffer::Type::PRESET;
+ t.attr.preset.rangeOffset = 0;
+ t.attr.preset.rangeLength = 0;
+ for (size_t i = 0; i < oBuffer.size(); ++i) {
+ native_handle_t* fenceNh = native_handle_create(0, 0);
+ status = omxNode->fillBuffer(oBuffer[i].id, t, fenceNh);
+ native_handle_close(fenceNh);
+ native_handle_delete(fenceNh);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+ oBuffer.editItemAt(i).owner = component;
+ }
+
+ // set state to Idle
+ status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
+ OMX_StateIdle);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+ status =
+ observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &iBuffer, &oBuffer);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+ ASSERT_EQ(msg.type, Message::Type::EVENT);
+ ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
+ ASSERT_EQ(msg.data.eventData.data1, OMX_CommandStateSet);
+ ASSERT_EQ(msg.data.eventData.data2, OMX_StateIdle);
+
+ // test if client got all its buffers back
+ for (size_t i = 0; i < oBuffer.size(); ++i) {
+ EXPECT_EQ(oBuffer[i].owner, client);
+ }
+
+ // set state to executing
+ status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
+ OMX_StateExecuting);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+ status =
+ observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &iBuffer, &oBuffer);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+ ASSERT_EQ(msg.type, Message::Type::EVENT);
+ ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
+ ASSERT_EQ(msg.data.eventData.data1, OMX_CommandStateSet);
+ ASSERT_EQ(msg.data.eventData.data2, OMX_StateExecuting);
+
+ for (size_t i = 0; i < oBuffer.size(); i += 2) {
+ native_handle_t* fenceNh = native_handle_create(0, 0);
+ status = omxNode->fillBuffer(oBuffer[i].id, t, fenceNh);
+ native_handle_close(fenceNh);
+ native_handle_delete(fenceNh);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+ oBuffer.editItemAt(i).owner = component;
+ }
+
+ status = omxNode->sendCommand(toRawCommandType(OMX_CommandFlush),
+ kPortIndexOutput);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+ status =
+ observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &iBuffer, &oBuffer);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+ ASSERT_EQ(msg.type, Message::Type::EVENT);
+ ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
+ ASSERT_EQ(msg.data.eventData.data1, OMX_CommandFlush);
+ ASSERT_EQ(msg.data.eventData.data2, kPortIndexOutput);
+
+ // test if client got all its buffers back
+ for (size_t i = 0; i < oBuffer.size(); ++i) {
+ EXPECT_EQ(oBuffer[i].owner, client);
+ }
+
+ // set state to Idle
+ status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
+ OMX_StateIdle);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+ status =
+ observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &iBuffer, &oBuffer);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+ ASSERT_EQ(msg.type, Message::Type::EVENT);
+ ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
+ ASSERT_EQ(msg.data.eventData.data1, OMX_CommandStateSet);
+ ASSERT_EQ(msg.data.eventData.data2, OMX_StateIdle);
+
+ // set state to Loaded
+ status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
+ OMX_StateLoaded);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+
+ // dont change state until all buffers are freed
+ status =
+ observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &iBuffer, &oBuffer);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::TIMED_OUT);
+
+ for (size_t i = 0; i < iBuffer.size(); ++i) {
+ status = omxNode->freeBuffer(kPortIndexInput, iBuffer[i].id);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+ }
+
+ // dont change state until all buffers are freed
+ status =
+ observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &iBuffer, &oBuffer);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::TIMED_OUT);
+
+ for (size_t i = 0; i < oBuffer.size(); ++i) {
+ status = omxNode->freeBuffer(kPortIndexOutput, oBuffer[i].id);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+ }
+
+ status =
+ observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &iBuffer, &oBuffer);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+ ASSERT_EQ(msg.type, Message::Type::EVENT);
+ ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
+ ASSERT_EQ(msg.data.eventData.data1, OMX_CommandStateSet);
+ ASSERT_EQ(msg.data.eventData.data2, OMX_StateLoaded);
+}
+
+// Test State Transitions
+TEST_F(ComponentHidlTest, StateTransitions_M) {
+ android::hardware::media::omx::V1_0::Status status;
+ uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
+ Message msg;
+
+ status = setRole(omxNode, gEnv->getRole().c_str());
+ ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+ OMX_PORT_PARAM_TYPE params;
+ if (compClass == audio_decoder || compClass == audio_encoder) {
+ status = getParam(omxNode, OMX_IndexParamAudioInit, ¶ms);
+ } else {
+ status = getParam(omxNode, OMX_IndexParamVideoInit, ¶ms);
+ }
+ if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
+ ASSERT_EQ(params.nPorts, 2U);
+ kPortIndexInput = params.nStartPortNumber;
+ kPortIndexOutput = kPortIndexInput + 1;
+ }
+
+ android::Vector<BufferInfo> iBuffer, oBuffer;
+
+ // set state to loaded ; receive error OMX_ErrorSameState
+ status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
+ OMX_StateLoaded);
+ EXPECT_NE(status, android::hardware::media::omx::V1_0::Status::OK);
+
+ // set state to executing ; receive error OMX_ErrorIncorrectStateTransition
+ status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
+ OMX_StateExecuting);
+ EXPECT_NE(status, android::hardware::media::omx::V1_0::Status::OK);
+
+ // set state to idle
+ status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
+ OMX_StateIdle);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+
+ // allocate buffers on i/o port
+ allocatePortBuffers(omxNode, allocator, &iBuffer, kPortIndexInput);
+ allocatePortBuffers(omxNode, allocator, &oBuffer, kPortIndexOutput);
+
+ status =
+ observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &iBuffer, &oBuffer);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+ ASSERT_EQ(msg.type, Message::Type::EVENT);
+ ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
+ ASSERT_EQ(msg.data.eventData.data1, OMX_CommandStateSet);
+ ASSERT_EQ(msg.data.eventData.data2, OMX_StateIdle);
+
+ // set state to idle ; receive error OMX_ErrorSameState
+ status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
+ OMX_StateIdle);
+ EXPECT_NE(status, android::hardware::media::omx::V1_0::Status::OK);
+
+ // set state to executing
+ status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
+ OMX_StateExecuting);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+ status =
+ observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &iBuffer, &oBuffer);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+ ASSERT_EQ(msg.type, Message::Type::EVENT);
+ ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
+ ASSERT_EQ(msg.data.eventData.data1, OMX_CommandStateSet);
+ ASSERT_EQ(msg.data.eventData.data2, OMX_StateExecuting);
+
+ // set state to executing ; receive error OMX_ErrorSameState
+ status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
+ OMX_StateExecuting);
+ EXPECT_NE(status, android::hardware::media::omx::V1_0::Status::OK);
+
+ // set state to Loaded ; receive error OMX_ErrorIncorrectStateTransition
+ status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
+ OMX_StateLoaded);
+ EXPECT_NE(status, android::hardware::media::omx::V1_0::Status::OK);
+
+ // set state to Idle
+ status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
+ OMX_StateIdle);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+ status =
+ observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &iBuffer, &oBuffer);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+ ASSERT_EQ(msg.type, Message::Type::EVENT);
+ ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
+ ASSERT_EQ(msg.data.eventData.data1, OMX_CommandStateSet);
+ ASSERT_EQ(msg.data.eventData.data2, OMX_StateIdle);
+
+ // set state to Loaded
+ status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
+ OMX_StateLoaded);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+
+ for (size_t i = 0; i < iBuffer.size(); ++i) {
+ status = omxNode->freeBuffer(kPortIndexInput, iBuffer[i].id);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+ }
+ for (size_t i = 0; i < oBuffer.size(); ++i) {
+ status = omxNode->freeBuffer(kPortIndexOutput, oBuffer[i].id);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+ }
+
+ status =
+ observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &iBuffer, &oBuffer);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+ ASSERT_EQ(msg.type, Message::Type::EVENT);
+ ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
+ ASSERT_EQ(msg.data.eventData.data1, OMX_CommandStateSet);
+ ASSERT_EQ(msg.data.eventData.data2, OMX_StateLoaded);
+}
+
+// Enable and Disable Input and Output ports when the component is in Loaded
+// State
+TEST_F(ComponentHidlTest, PortEnableDisable_Loaded) {
+ android::hardware::media::omx::V1_0::Status status;
+ OMX_U32 portBase = 0;
+ Message msg;
+ status = setRole(omxNode, gEnv->getRole().c_str());
+ ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+ OMX_PORT_PARAM_TYPE params;
+ if (compClass == audio_decoder || compClass == audio_encoder) {
+ status = getParam(omxNode, OMX_IndexParamAudioInit, ¶ms);
+ } else {
+ status = getParam(omxNode, OMX_IndexParamVideoInit, ¶ms);
+ }
+ if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
+ ASSERT_EQ(params.nPorts, 2U);
+ portBase = params.nStartPortNumber;
+ }
+
+ for (size_t i = portBase; i < portBase + 2; i++) {
+ status =
+ omxNode->sendCommand(toRawCommandType(OMX_CommandPortDisable), i);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+ status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+ ASSERT_EQ(msg.type, Message::Type::EVENT);
+ if (msg.data.eventData.event == OMX_EventCmdComplete) {
+ ASSERT_EQ(msg.data.eventData.data1, OMX_CommandPortDisable);
+ ASSERT_EQ(msg.data.eventData.data2, i);
+ // If you can disable a port, then you should be able to enable it
+ // as well
+ status = omxNode->sendCommand(
+ toRawCommandType(OMX_CommandPortEnable), i);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+ status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+ ASSERT_EQ(msg.type, Message::Type::EVENT);
+ ASSERT_EQ(msg.data.eventData.data1, OMX_CommandPortEnable);
+ ASSERT_EQ(msg.data.eventData.data2, i);
+ } else if (msg.data.eventData.event == OMX_EventError) {
+ ALOGI("Port %d Disabling failed with error %d", (int)i,
+ (int)msg.data.eventData.event);
+ } else {
+ // something unexpected happened
+ ASSERT_TRUE(false);
+ }
+ }
+}
+
+// Enable and Disable Input and Output ports when the component is in Idle State
+TEST_F(ComponentHidlTest, PortEnableDisable_Idle) {
+ android::hardware::media::omx::V1_0::Status status;
+ uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
+ OMX_U32 portBase = 0;
+ Message msg;
+ status = setRole(omxNode, gEnv->getRole().c_str());
+ ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+ OMX_PORT_PARAM_TYPE params;
+ if (compClass == audio_decoder || compClass == audio_encoder) {
+ status = getParam(omxNode, OMX_IndexParamAudioInit, ¶ms);
+ } else {
+ status = getParam(omxNode, OMX_IndexParamVideoInit, ¶ms);
+ }
+ if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
+ ASSERT_EQ(params.nPorts, 2U);
+ portBase = params.nStartPortNumber;
+ }
+ kPortIndexInput = portBase;
+ kPortIndexOutput = portBase + 1;
+
+ // Component State :: Idle
+ android::Vector<BufferInfo> pBuffer[2];
+ // set state to idle
+ status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
+ OMX_StateIdle);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+
+ // allocate buffers on input port
+ allocatePortBuffers(omxNode, allocator, &pBuffer[0], kPortIndexInput);
+ allocatePortBuffers(omxNode, allocator, &pBuffer[1], kPortIndexOutput);
+
+ status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &pBuffer[0],
+ &pBuffer[1]);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+ ASSERT_EQ(msg.type, Message::Type::EVENT);
+ ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
+ ASSERT_EQ(msg.data.eventData.data1, OMX_CommandStateSet);
+ ASSERT_EQ(msg.data.eventData.data2, OMX_StateIdle);
+
+ for (size_t i = portBase; i < portBase + 2; i++) {
+ status =
+ omxNode->sendCommand(toRawCommandType(OMX_CommandPortDisable), i);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+
+ status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &pBuffer[0],
+ &pBuffer[1]);
+ if (status == android::hardware::media::omx::V1_0::Status::OK) {
+ ASSERT_EQ(msg.type, Message::Type::EVENT);
+ if (msg.data.eventData.event == OMX_EventCmdComplete) {
+ // do not disable the port until all the buffers are freed
+ ASSERT_TRUE(false);
+ } else if (msg.data.eventData.event == OMX_EventError) {
+ ALOGI("Port %d Disabling failed with error %d", (int)i,
+ (int)msg.data.eventData.event);
+ } else {
+ // something unexpected happened
+ ASSERT_TRUE(false);
+ }
+ } else if (status ==
+ android::hardware::media::omx::V1_0::Status::TIMED_OUT) {
+ for (size_t j = 0; j < pBuffer[i - portBase].size(); ++j) {
+ status = omxNode->freeBuffer(i, pBuffer[i - portBase][j].id);
+ ASSERT_EQ(status,
+ android::hardware::media::omx::V1_0::Status::OK);
+ }
+
+ status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT,
+ &pBuffer[0], &pBuffer[1]);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+ ASSERT_EQ(msg.type, Message::Type::EVENT);
+ ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
+ ASSERT_EQ(msg.data.eventData.data1, OMX_CommandPortDisable);
+ ASSERT_EQ(msg.data.eventData.data2, i);
+
+ // If you can disable a port, then you should be able to enable it
+ // as well
+ status = omxNode->sendCommand(
+ toRawCommandType(OMX_CommandPortEnable), i);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+
+ // do not enable the port until all the buffers are supplied
+ status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT,
+ &pBuffer[0], &pBuffer[1]);
+ ASSERT_EQ(status,
+ android::hardware::media::omx::V1_0::Status::TIMED_OUT);
+
+ allocatePortBuffers(omxNode, allocator, &pBuffer[i - portBase], i);
+ status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT,
+ &pBuffer[0], &pBuffer[1]);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+ ASSERT_EQ(msg.type, Message::Type::EVENT);
+ ASSERT_EQ(msg.data.eventData.data1, OMX_CommandPortEnable);
+ ASSERT_EQ(msg.data.eventData.data2, i);
+ } else {
+ // something unexpected happened
+ ASSERT_TRUE(false);
+ }
+ }
+}
+
+// Enable and Disable Input and Output ports when the component is in execute
+TEST_F(ComponentHidlTest, PortEnableDisable_Execute) {
+ android::hardware::media::omx::V1_0::Status status;
+ uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
+ OMX_U32 portBase = 0;
+ Message msg;
+ status = setRole(omxNode, gEnv->getRole().c_str());
+ ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+ OMX_PORT_PARAM_TYPE params;
+ if (compClass == audio_decoder || compClass == audio_encoder) {
+ status = getParam(omxNode, OMX_IndexParamAudioInit, ¶ms);
+ } else {
+ status = getParam(omxNode, OMX_IndexParamVideoInit, ¶ms);
+ }
+ if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
+ ASSERT_EQ(params.nPorts, 2U);
+ portBase = params.nStartPortNumber;
+ }
+ kPortIndexInput = portBase;
+ kPortIndexOutput = portBase + 1;
+
+ // Component State :: Idle
+ android::Vector<BufferInfo> pBuffer[2];
+ // set state to idle
+ status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
+ OMX_StateIdle);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+
+ // allocate buffers on input port
+ allocatePortBuffers(omxNode, allocator, &pBuffer[0], kPortIndexInput);
+ allocatePortBuffers(omxNode, allocator, &pBuffer[1], kPortIndexOutput);
+
+ status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &pBuffer[0],
+ &pBuffer[1]);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+ ASSERT_EQ(msg.type, Message::Type::EVENT);
+ ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
+ ASSERT_EQ(msg.data.eventData.data1, OMX_CommandStateSet);
+ ASSERT_EQ(msg.data.eventData.data2, OMX_StateIdle);
+
+ // Component State :: Execute
+ status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
+ OMX_StateExecuting);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+ status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &pBuffer[0],
+ &pBuffer[1]);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+ ASSERT_EQ(msg.type, Message::Type::EVENT);
+ ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
+ ASSERT_EQ(msg.data.eventData.data1, OMX_CommandStateSet);
+ ASSERT_EQ(msg.data.eventData.data2, OMX_StateExecuting);
+
+ CodecBuffer t;
+ t.sharedMemory = android::hardware::hidl_memory();
+ t.nativeHandle = android::hardware::hidl_handle();
+ t.type = CodecBuffer::Type::PRESET;
+ t.attr.preset.rangeOffset = 0;
+ t.attr.preset.rangeLength = 0;
+ for (size_t i = 0; i < pBuffer[1].size(); ++i) {
+ native_handle_t* fenceNh = native_handle_create(0, 0);
+ status = omxNode->fillBuffer(pBuffer[1][i].id, t, fenceNh);
+ native_handle_close(fenceNh);
+ native_handle_delete(fenceNh);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+ pBuffer[1].editItemAt(i).owner = component;
+ }
+
+ for (size_t i = portBase; i < portBase + 2; i++) {
+ status =
+ omxNode->sendCommand(toRawCommandType(OMX_CommandPortDisable), i);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+
+ status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &pBuffer[0],
+ &pBuffer[1]);
+ if (status == android::hardware::media::omx::V1_0::Status::OK) {
+ ASSERT_EQ(msg.type, Message::Type::EVENT);
+ if (msg.data.eventData.event == OMX_EventCmdComplete) {
+ // do not disable the port until all the buffers are freed
+ ASSERT_TRUE(false);
+ } else if (msg.data.eventData.event == OMX_EventError) {
+ ALOGI("Port %d Disabling failed with error %d", (int)i,
+ (int)msg.data.eventData.event);
+ } else {
+ // something unexpected happened
+ ASSERT_TRUE(false);
+ }
+ } else if (status ==
+ android::hardware::media::omx::V1_0::Status::TIMED_OUT) {
+ for (size_t j = 0; j < pBuffer[i - portBase].size(); ++j) {
+ // test if client got all its buffers back
+ EXPECT_EQ(pBuffer[i - portBase][j].owner, client);
+ // free the buffers
+ status = omxNode->freeBuffer(i, pBuffer[i - portBase][j].id);
+ ASSERT_EQ(status,
+ android::hardware::media::omx::V1_0::Status::OK);
+ }
+
+ status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT,
+ &pBuffer[0], &pBuffer[1]);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+ ASSERT_EQ(msg.type, Message::Type::EVENT);
+ ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
+ ASSERT_EQ(msg.data.eventData.data1, OMX_CommandPortDisable);
+ ASSERT_EQ(msg.data.eventData.data2, i);
+
+ // If you can disable a port, then you should be able to enable it
+ // as well
+ status = omxNode->sendCommand(
+ toRawCommandType(OMX_CommandPortEnable), i);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+
+ // do not enable the port until all the buffers are supplied
+ status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT,
+ &pBuffer[0], &pBuffer[1]);
+ ASSERT_EQ(status,
+ android::hardware::media::omx::V1_0::Status::TIMED_OUT);
+
+ allocatePortBuffers(omxNode, allocator, &pBuffer[i - portBase], i);
+ status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT,
+ &pBuffer[0], &pBuffer[1]);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+ ASSERT_EQ(msg.type, Message::Type::EVENT);
+ ASSERT_EQ(msg.data.eventData.data1, OMX_CommandPortEnable);
+ ASSERT_EQ(msg.data.eventData.data2, i);
+ } else {
+ // something unexpected happened
+ ASSERT_TRUE(false);
+ }
+ }
+}
+
+// Enable and Disable Input and Output ports, (in loaded state)
+TEST_F(ComponentHidlTest, PortEnableDisable_M) {
+ android::hardware::media::omx::V1_0::Status status;
+ OMX_U32 portBase = 0;
+ Message msg;
+ status = setRole(omxNode, gEnv->getRole().c_str());
+ ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+ OMX_PORT_PARAM_TYPE params;
+ if (compClass == audio_decoder || compClass == audio_encoder) {
+ status = getParam(omxNode, OMX_IndexParamAudioInit, ¶ms);
+ } else {
+ status = getParam(omxNode, OMX_IndexParamVideoInit, ¶ms);
+ }
+ if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
+ ASSERT_EQ(params.nPorts, 2U);
+ portBase = params.nStartPortNumber;
+ }
+
+ // disable invalid port, expecting OMX_ErrorBadPortIndex
+ status = omxNode->sendCommand(toRawCommandType(OMX_CommandPortDisable),
+ RANDOM_INDEX);
+ ASSERT_NE(status, android::hardware::media::omx::V1_0::Status::OK);
+
+ // enable invalid port, expecting OMX_ErrorBadPortIndex
+ status = omxNode->sendCommand(toRawCommandType(OMX_CommandPortEnable),
+ RANDOM_INDEX);
+ ASSERT_NE(status, android::hardware::media::omx::V1_0::Status::OK);
+
+ // disable all ports
+ status =
+ omxNode->sendCommand(toRawCommandType(OMX_CommandPortDisable), OMX_ALL);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+ for (size_t i = 0; i < 2; i++) {
+ status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+ ASSERT_EQ(msg.type, Message::Type::EVENT);
+ if (msg.data.eventData.event == OMX_EventCmdComplete) {
+ ASSERT_EQ(msg.data.eventData.data1, OMX_CommandPortDisable);
+ if (msg.data.eventData.data2 != portBase ||
+ msg.data.eventData.data2 != portBase + 1)
+ EXPECT_TRUE(false);
+ } else if (msg.data.eventData.event == OMX_EventError) {
+ ALOGI("Port %d Disabling failed with error %d", (int)i,
+ (int)msg.data.eventData.event);
+ } else {
+ // something unexpected happened
+ ASSERT_TRUE(false);
+ }
+ }
+
+ // enable all ports
+ status =
+ omxNode->sendCommand(toRawCommandType(OMX_CommandPortEnable), OMX_ALL);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+ for (size_t i = 0; i < 2; i++) {
+ status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+ ASSERT_EQ(msg.type, Message::Type::EVENT);
+ if (msg.data.eventData.event == OMX_EventCmdComplete) {
+ ASSERT_EQ(msg.data.eventData.data1, OMX_CommandPortEnable);
+ if (msg.data.eventData.data2 != portBase ||
+ msg.data.eventData.data2 != portBase + 1)
+ EXPECT_TRUE(false);
+ } else if (msg.data.eventData.event == OMX_EventError) {
+ ALOGI("Port %d Enabling failed with error %d", (int)i,
+ (int)msg.data.eventData.event);
+ } else {
+ // something unexpected happened
+ ASSERT_TRUE(false);
+ }
+ }
+}
+
+int main(int argc, char** argv) {
+ gEnv = new ComponentTestEnvironment();
+ ::testing::AddGlobalTestEnvironment(gEnv);
+ ::testing::InitGoogleTest(&argc, argv);
+ int status = gEnv->initFromOptions(argc, argv);
+ if (status == 0) {
+ status = RUN_ALL_TESTS();
+ ALOGI("Test result = %d", status);
+ }
+ return status;
+}
diff --git a/media/omx/1.0/vts/functional/master/Android.bp b/media/omx/1.0/vts/functional/master/Android.bp
new file mode 100644
index 0000000..6edbf4a
--- /dev/null
+++ b/media/omx/1.0/vts/functional/master/Android.bp
@@ -0,0 +1,38 @@
+//
+// Copyright (C) 2017 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: "VtsHalMediaOmxV1_0TargetMasterTest",
+ defaults: ["hidl_defaults"],
+ srcs: ["VtsHalMediaOmxV1_0TargetMasterTest.cpp"],
+ shared_libs: [
+ "libbase",
+ "liblog",
+ "libcutils",
+ "libhidlbase",
+ "libhidltransport",
+ "libhwbinder",
+ "libnativehelper",
+ "libutils",
+ "android.hardware.media.omx@1.0",
+ ],
+ static_libs: ["VtsHalHidlTargetTestBase"],
+ cflags: [
+ "-O0",
+ "-g",
+ ],
+}
+
diff --git a/media/omx/1.0/vts/functional/master/VtsHalMediaOmxV1_0TargetMasterTest.cpp b/media/omx/1.0/vts/functional/master/VtsHalMediaOmxV1_0TargetMasterTest.cpp
new file mode 100644
index 0000000..65b999e
--- /dev/null
+++ b/media/omx/1.0/vts/functional/master/VtsHalMediaOmxV1_0TargetMasterTest.cpp
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2017 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 "media_omx_hidl_master_test"
+#include <android-base/logging.h>
+
+#include <android/hardware/media/omx/1.0/IOmx.h>
+#include <android/hardware/media/omx/1.0/types.h>
+#include <getopt.h>
+#include <log/log.h>
+#include <VtsHalHidlTargetTestBase.h>
+
+using ::android::hardware::media::omx::V1_0::IOmx;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+// A class for test environment setup
+class ComponentTestEnvironment : public ::testing::Environment {
+ public:
+ virtual void SetUp() {}
+ virtual void TearDown() {}
+
+ ComponentTestEnvironment() : instance("default") {}
+
+ void setInstance(const char* _instance) { instance = _instance; }
+
+ const hidl_string getInstance() const { return instance; }
+
+ int initFromOptions(int argc, char** argv) {
+ static struct option options[] = {
+ {"instance", required_argument, 0, 'I'}, {0, 0, 0, 0}};
+
+ while (true) {
+ int index = 0;
+ int c = getopt_long(argc, argv, "I:", options, &index);
+ if (c == -1) {
+ break;
+ }
+
+ switch (c) {
+ case 'I':
+ setInstance(optarg);
+ break;
+ case '?':
+ break;
+ }
+ }
+
+ if (optind < argc) {
+ fprintf(stderr,
+ "unrecognized option: %s\n\n"
+ "usage: %s <gtest options> <test options>\n\n"
+ "test options are:\n\n"
+ "-I, --instance: HAL instance to test\n",
+ argv[optind ?: 1], argv[0]);
+ return 2;
+ }
+ return 0;
+ }
+
+ private:
+ hidl_string instance;
+};
+
+static ComponentTestEnvironment* gEnv = nullptr;
+
+class MasterHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+ public:
+ virtual void SetUp() override {
+ omx = ::testing::VtsHalHidlTargetTestBase::getService<IOmx>(
+ gEnv->getInstance());
+ ASSERT_NE(omx, nullptr);
+ }
+
+ virtual void TearDown() override {}
+
+ sp<IOmx> omx;
+};
+
+// enumerate list of components and roles
+TEST_F(MasterHidlTest, ListNodes) {
+ android::hardware::media::omx::V1_0::Status status;
+ hidl_vec<IOmx::ComponentInfo> nodeList;
+ EXPECT_TRUE(
+ omx->listNodes([&status, &nodeList](
+ android::hardware::media::omx::V1_0::Status _s,
+ hidl_vec<IOmx::ComponentInfo> const& _nl) {
+ status = _s;
+ nodeList = _nl;
+ })
+ .isOk());
+}
+
+int main(int argc, char** argv) {
+ gEnv = new ComponentTestEnvironment();
+ ::testing::AddGlobalTestEnvironment(gEnv);
+ ::testing::InitGoogleTest(&argc, argv);
+ int status = gEnv->initFromOptions(argc, argv);
+ if (status == 0) {
+ status = RUN_ALL_TESTS();
+ ALOGI("Test result = %d", status);
+ }
+ return status;
+}
diff --git a/memtrack/1.0/Android.mk b/memtrack/1.0/Android.mk
index 62bee97..8583b0a 100644
--- a/memtrack/1.0/Android.mk
+++ b/memtrack/1.0/Android.mk
@@ -5,7 +5,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.memtrack@1.0-java
+LOCAL_MODULE := android.hardware.memtrack-V1.0-java
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -13,7 +13,7 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_JAVA_LIBRARIES := \
- android.hidl.base@1.0-java \
+ android.hidl.base-V1.0-java \
#
@@ -118,7 +118,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.memtrack@1.0-java-static
+LOCAL_MODULE := android.hardware.memtrack-V1.0-java-static
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -126,7 +126,7 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_STATIC_JAVA_LIBRARIES := \
- android.hidl.base@1.0-java-static \
+ android.hidl.base-V1.0-java-static \
#
diff --git a/nfc/1.0/Android.mk b/nfc/1.0/Android.mk
index 6f09764..3ea7707 100644
--- a/nfc/1.0/Android.mk
+++ b/nfc/1.0/Android.mk
@@ -5,7 +5,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.nfc@1.0-java
+LOCAL_MODULE := android.hardware.nfc-V1.0-java
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -13,7 +13,7 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_JAVA_LIBRARIES := \
- android.hidl.base@1.0-java \
+ android.hidl.base-V1.0-java \
#
@@ -103,7 +103,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.nfc@1.0-java-static
+LOCAL_MODULE := android.hardware.nfc-V1.0-java-static
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -111,7 +111,7 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_STATIC_JAVA_LIBRARIES := \
- android.hidl.base@1.0-java-static \
+ android.hidl.base-V1.0-java-static \
#
@@ -201,7 +201,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.nfc@1.0-java-constants
+LOCAL_MODULE := android.hardware.nfc-V1.0-java-constants
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
diff --git a/nfc/1.0/default/Android.mk b/nfc/1.0/default/Android.mk
index 2e1f17f..4afad74 100644
--- a/nfc/1.0/default/Android.mk
+++ b/nfc/1.0/default/Android.mk
@@ -14,7 +14,6 @@
libdl \
libbase \
libutils \
- libhardware_legacy \
libhardware \
LOCAL_SHARED_LIBRARIES += \
diff --git a/oemlock/1.0/Android.bp b/oemlock/1.0/Android.bp
index 33096c3..6d471e9 100644
--- a/oemlock/1.0/Android.bp
+++ b/oemlock/1.0/Android.bp
@@ -44,6 +44,7 @@
generated_sources: ["android.hardware.oemlock@1.0_genc++"],
generated_headers: ["android.hardware.oemlock@1.0_genc++_headers"],
export_generated_headers: ["android.hardware.oemlock@1.0_genc++_headers"],
+ vendor_available: true,
shared_libs: [
"libhidlbase",
"libhidltransport",
diff --git a/oemlock/1.0/Android.mk b/oemlock/1.0/Android.mk
index e50c288..d986441 100644
--- a/oemlock/1.0/Android.mk
+++ b/oemlock/1.0/Android.mk
@@ -5,7 +5,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.oemlock@1.0-java
+LOCAL_MODULE := android.hardware.oemlock-V1.0-java
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -13,7 +13,7 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_JAVA_LIBRARIES := \
- android.hidl.base@1.0-java \
+ android.hidl.base-V1.0-java \
#
@@ -80,7 +80,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.oemlock@1.0-java-static
+LOCAL_MODULE := android.hardware.oemlock-V1.0-java-static
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -88,7 +88,7 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_STATIC_JAVA_LIBRARIES := \
- android.hidl.base@1.0-java-static \
+ android.hidl.base-V1.0-java-static \
#
diff --git a/power/1.0/Android.mk b/power/1.0/Android.mk
index 98d95a8..8a89a45 100644
--- a/power/1.0/Android.mk
+++ b/power/1.0/Android.mk
@@ -5,7 +5,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.power@1.0-java
+LOCAL_MODULE := android.hardware.power-V1.0-java
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -13,7 +13,7 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_JAVA_LIBRARIES := \
- android.hidl.base@1.0-java \
+ android.hidl.base-V1.0-java \
#
@@ -137,7 +137,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.power@1.0-java-static
+LOCAL_MODULE := android.hardware.power-V1.0-java-static
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -145,7 +145,7 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_STATIC_JAVA_LIBRARIES := \
- android.hidl.base@1.0-java-static \
+ android.hidl.base-V1.0-java-static \
#
diff --git a/radio/1.0/Android.mk b/radio/1.0/Android.mk
index 94072fb..a71e672 100644
--- a/radio/1.0/Android.mk
+++ b/radio/1.0/Android.mk
@@ -5,7 +5,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.radio@1.0-java
+LOCAL_MODULE := android.hardware.radio-V1.0-java
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -13,7 +13,7 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_JAVA_LIBRARIES := \
- android.hidl.base@1.0-java \
+ android.hidl.base-V1.0-java \
#
@@ -1841,6 +1841,25 @@
LOCAL_GENERATED_SOURCES += $(GEN)
#
+# Build types.hal (P2Constant)
+#
+GEN := $(intermediates)/android/hardware/radio/V1_0/P2Constant.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+ $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+ -Ljava \
+ -randroid.hardware:hardware/interfaces \
+ -randroid.hidl:system/libhidl/transport \
+ android.hardware.radio@1.0::types.P2Constant
+
+$(GEN): $(LOCAL_PATH)/types.hal
+ $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
# Build types.hal (PcoDataInfo)
#
GEN := $(intermediates)/android/hardware/radio/V1_0/PcoDataInfo.java
@@ -3039,7 +3058,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.radio@1.0-java-static
+LOCAL_MODULE := android.hardware.radio-V1.0-java-static
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -3047,7 +3066,7 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_STATIC_JAVA_LIBRARIES := \
- android.hidl.base@1.0-java-static \
+ android.hidl.base-V1.0-java-static \
#
@@ -4875,6 +4894,25 @@
LOCAL_GENERATED_SOURCES += $(GEN)
#
+# Build types.hal (P2Constant)
+#
+GEN := $(intermediates)/android/hardware/radio/V1_0/P2Constant.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+ $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+ -Ljava \
+ -randroid.hardware:hardware/interfaces \
+ -randroid.hidl:system/libhidl/transport \
+ android.hardware.radio@1.0::types.P2Constant
+
+$(GEN): $(LOCAL_PATH)/types.hal
+ $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
# Build types.hal (PcoDataInfo)
#
GEN := $(intermediates)/android/hardware/radio/V1_0/PcoDataInfo.java
diff --git a/radio/1.0/IRadioResponse.hal b/radio/1.0/IRadioResponse.hal
index 2ba210b..fdb5c4e 100644
--- a/radio/1.0/IRadioResponse.hal
+++ b/radio/1.0/IRadioResponse.hal
@@ -1811,7 +1811,6 @@
* RadioError:NONE
* RadioError:RADIO_NOT_AVAILABLE
* RadioError:REQUEST_NOT_SUPPORTED
- * RadioError:SIM_ABSENT
* RadioError:INVALID_ARGUMENTS
*/
oneway setSimCardPowerResponse(RadioResponseInfo info);
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 2e0a10f..825585d 100644
--- a/radio/1.0/vts/functional/radio_hidl_hal_misc.cpp
+++ b/radio/1.0/vts/functional/radio_hidl_hal_misc.cpp
@@ -787,6 +787,7 @@
EXPECT_EQ(serial, radioRsp->rspInfo.serial);
if (cardStatus.cardState == CardState::ABSENT) {
- ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::SIM_ABSENT);
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE
+ || radioRsp->rspInfo.error == RadioError::REQUEST_NOT_SUPPORTED);
}
}
\ No newline at end of file
diff --git a/radio/deprecated/1.0/Android.mk b/radio/deprecated/1.0/Android.mk
index 4cce633..11377d8 100644
--- a/radio/deprecated/1.0/Android.mk
+++ b/radio/deprecated/1.0/Android.mk
@@ -5,7 +5,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.radio.deprecated@1.0-java
+LOCAL_MODULE := android.hardware.radio.deprecated-V1.0-java
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -13,8 +13,8 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_JAVA_LIBRARIES := \
- android.hardware.radio@1.0-java \
- android.hidl.base@1.0-java \
+ android.hardware.radio-V1.0-java \
+ android.hidl.base-V1.0-java \
#
@@ -83,7 +83,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.radio.deprecated@1.0-java-static
+LOCAL_MODULE := android.hardware.radio.deprecated-V1.0-java-static
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -91,8 +91,8 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_STATIC_JAVA_LIBRARIES := \
- android.hardware.radio@1.0-java-static \
- android.hidl.base@1.0-java-static \
+ android.hardware.radio-V1.0-java-static \
+ android.hidl.base-V1.0-java-static \
#
diff --git a/renderscript/1.0/Android.mk b/renderscript/1.0/Android.mk
index 5c3a37d..cdd580a 100644
--- a/renderscript/1.0/Android.mk
+++ b/renderscript/1.0/Android.mk
@@ -5,7 +5,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.renderscript@1.0-java-constants
+LOCAL_MODULE := android.hardware.renderscript-V1.0-java-constants
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
diff --git a/renderscript/1.0/vts/functional/VtsScriptTests.cpp b/renderscript/1.0/vts/functional/VtsScriptTests.cpp
index fed7c6e..8268dcc 100644
--- a/renderscript/1.0/vts/functional/VtsScriptTests.cpp
+++ b/renderscript/1.0/vts/functional/VtsScriptTests.cpp
@@ -323,27 +323,30 @@
/*
* This test groups together two RenderScript intrinsic kernels to run one after
- * the other asynchronously with respect to the client. The test configures YuvToRGB(A) and Blur,
- * and links them together such that Blur will execute after YuvToRGB(A) and use its result. The
- * test checks the data returned to make sure it was changed after passing through the entire
- * ScriptGroup.
+ * the other asynchronously with respect to the client. The test configures
+ * Blend and Blur, and links them together such that Blur will execute after
+ * Blend and use its result. The test checks the data returned to make sure it
+ * was changed after passing through the entire ScriptGroup.
*
* Calls: elementCreate, typeCreate, allocationCreateTyped, allocation2DWrite,
* scriptIntrinsicCreate, scriptKernelIDCreate, scriptFieldIDCreate,
- * scriptGroupCreate, scriptSetVarObj, scriptGroupSetOutput, scriptGroupExecute,
- * contextFinish, allocation2DRead
+ * scriptGroupCreate, scriptGroupSetInput, scriptGroupSetOutput,
+ * scriptGroupExecute, contextFinish, allocation2DRead
*/
TEST_F(RenderscriptHidlTest, ScriptGroupTest) {
- std::vector<uint8_t> dataIn(256*256*1, 128), dataOut(256*256*4, 0), zeros(256*256*4, 0);
+ 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;
_dataIn.setToExternal(dataIn.data(), dataIn.size());
_dataOut.setToExternal(dataOut.data(), dataOut.size());
// 256 x 256 YUV pixels
- Element element1 = context->elementCreate(DataType::UNSIGNED_8, DataKind::PIXEL_YUV, true, 1);
+ Element element1 = context->elementCreate(DataType::UNSIGNED_8,
+ DataKind::PIXEL_RGBA, true, 4);
ASSERT_NE(Element(0), element1);
- Type type1 = context->typeCreate(element1, 256, 256, 0, false, false, YuvFormat::YUV_420_888);
+ Type type1 = context->typeCreate(element1, 256, 256, 0, false, false,
+ YuvFormat::YUV_NONE);
ASSERT_NE(Type(0), type1);
Allocation allocation1 = context->allocationCreateTyped(type1, AllocationMipmapControl::NONE,
@@ -370,11 +373,12 @@
_dataOut, 0);
// create scripts
- Script yuv2rgb = context->scriptIntrinsicCreate(ScriptIntrinsicID::ID_YUV_TO_RGB, element1);
- ASSERT_NE(Script(0), yuv2rgb);
+ Script blend =
+ context->scriptIntrinsicCreate(ScriptIntrinsicID::ID_BLEND, element1);
+ ASSERT_NE(Script(0), blend);
- ScriptKernelID yuv2rgbKID = context->scriptKernelIDCreate(yuv2rgb, 0, 2);
- ASSERT_NE(ScriptKernelID(0), yuv2rgbKID);
+ ScriptKernelID blendKID = context->scriptKernelIDCreate(blend, 1, 3);
+ ASSERT_NE(ScriptKernelID(0), blendKID);
Script blur = context->scriptIntrinsicCreate(ScriptIntrinsicID::ID_BLUR, element2);
ASSERT_NE(Script(0), blur);
@@ -386,15 +390,15 @@
ASSERT_NE(ScriptFieldID(0), blurFID);
// ScriptGroup
- hidl_vec<ScriptKernelID> kernels = {yuv2rgbKID, blurKID};
- hidl_vec<ScriptKernelID> srcK = {yuv2rgbKID};
+ hidl_vec<ScriptKernelID> kernels = {blendKID, blurKID};
+ hidl_vec<ScriptKernelID> srcK = {blendKID};
hidl_vec<ScriptKernelID> dstK = {ScriptKernelID(0)};
hidl_vec<ScriptFieldID> dstF = {blurFID};
hidl_vec<Type> types = {type2};
ScriptGroup scriptGroup = context->scriptGroupCreate(kernels, srcK, dstK, dstF, types);
ASSERT_NE(ScriptGroup(0), scriptGroup);
- context->scriptSetVarObj(yuv2rgb, 0, (ObjectBase)allocation1);
+ context->scriptGroupSetInput(scriptGroup, blendKID, allocation1);
context->scriptGroupSetOutput(scriptGroup, blurKID, allocation2);
context->scriptGroupExecute(scriptGroup);
context->contextFinish();
diff --git a/sensors/1.0/Android.mk b/sensors/1.0/Android.mk
index 29f7c7e..18528a9 100644
--- a/sensors/1.0/Android.mk
+++ b/sensors/1.0/Android.mk
@@ -5,7 +5,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.sensors@1.0-java-constants
+LOCAL_MODULE := android.hardware.sensors-V1.0-java-constants
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
diff --git a/sensors/1.0/default/Android.mk b/sensors/1.0/default/Android.mk
index bc1cfbd..d114542 100644
--- a/sensors/1.0/default/Android.mk
+++ b/sensors/1.0/default/Android.mk
@@ -14,8 +14,6 @@
libdl \
libbase \
libutils \
- libhardware_legacy \
- libhardware \
LOCAL_SHARED_LIBRARIES += \
libhidlbase \
diff --git a/soundtrigger/2.0/default/SoundTriggerHalImpl.cpp b/soundtrigger/2.0/default/SoundTriggerHalImpl.cpp
index b0aef4b..996519b 100644
--- a/soundtrigger/2.0/default/SoundTriggerHalImpl.cpp
+++ b/soundtrigger/2.0/default/SoundTriggerHalImpl.cpp
@@ -294,8 +294,8 @@
return ret;
}
-SoundTriggerHalImpl::SoundTriggerHalImpl(const char *moduleName)
- : mModuleName(moduleName), mHwDevice(NULL), mNextModelId(1)
+SoundTriggerHalImpl::SoundTriggerHalImpl()
+ : mModuleName("primary"), mHwDevice(NULL), mNextModelId(1)
{
}
@@ -304,9 +304,6 @@
const hw_module_t *mod;
int rc;
- if (mModuleName == NULL || strlen(mModuleName) == 0) {
- mModuleName = "primary";
- }
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)",
@@ -570,20 +567,9 @@
delete[] levels;
}
-ISoundTriggerHw *HIDL_FETCH_ISoundTriggerHw(const char *name)
+ISoundTriggerHw *HIDL_FETCH_ISoundTriggerHw(const char* /* name */)
{
- if (name != NULL) {
- if (strncmp(SOUND_TRIGGER_HARDWARE_MODULE_ID, name,
- strlen(SOUND_TRIGGER_HARDWARE_MODULE_ID)) != 0) {
- return NULL;
- }
- name = strchr(name, '.');
- if (name == NULL) {
- return NULL;
- }
- name++;
- }
- return new SoundTriggerHalImpl(name);
+ return new SoundTriggerHalImpl();
}
} // namespace implementation
} // namespace V2_0
diff --git a/soundtrigger/2.0/default/SoundTriggerHalImpl.h b/soundtrigger/2.0/default/SoundTriggerHalImpl.h
index 8aa9285..4769590 100644
--- a/soundtrigger/2.0/default/SoundTriggerHalImpl.h
+++ b/soundtrigger/2.0/default/SoundTriggerHalImpl.h
@@ -38,7 +38,7 @@
class SoundTriggerHalImpl : public ISoundTriggerHw {
public:
- explicit SoundTriggerHalImpl(const char *moduleName = NULL);
+ SoundTriggerHalImpl();
// Methods from ::android::hardware::soundtrigger::V2_0::ISoundTriggerHw follow.
Return<void> getProperties(getProperties_cb _hidl_cb) override;
diff --git a/tests/baz/1.0/Android.mk b/tests/baz/1.0/Android.mk
index 9d4d6b6..29874da 100644
--- a/tests/baz/1.0/Android.mk
+++ b/tests/baz/1.0/Android.mk
@@ -5,7 +5,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.tests.baz@1.0-java
+LOCAL_MODULE := android.hardware.tests.baz-V1.0-java
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -13,7 +13,7 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_JAVA_LIBRARIES := \
- android.hidl.base@1.0-java \
+ android.hidl.base-V1.0-java \
#
@@ -101,7 +101,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.tests.baz@1.0-java-static
+LOCAL_MODULE := android.hardware.tests.baz-V1.0-java-static
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -109,7 +109,7 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_STATIC_JAVA_LIBRARIES := \
- android.hidl.base@1.0-java-static \
+ android.hidl.base-V1.0-java-static \
#
diff --git a/tests/expression/1.0/Android.mk b/tests/expression/1.0/Android.mk
index 6bc9390..1a32ef5 100644
--- a/tests/expression/1.0/Android.mk
+++ b/tests/expression/1.0/Android.mk
@@ -5,7 +5,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.tests.expression@1.0-java
+LOCAL_MODULE := android.hardware.tests.expression-V1.0-java
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -13,7 +13,7 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_JAVA_LIBRARIES := \
- android.hidl.base@1.0-java \
+ android.hidl.base-V1.0-java \
#
@@ -61,7 +61,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.tests.expression@1.0-java-static
+LOCAL_MODULE := android.hardware.tests.expression-V1.0-java-static
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -69,7 +69,7 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_STATIC_JAVA_LIBRARIES := \
- android.hidl.base@1.0-java-static \
+ android.hidl.base-V1.0-java-static \
#
diff --git a/tests/extension/light/2.0/Android.mk b/tests/extension/light/2.0/Android.mk
index 16424a3..f1e10e4 100644
--- a/tests/extension/light/2.0/Android.mk
+++ b/tests/extension/light/2.0/Android.mk
@@ -5,7 +5,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.tests.extension.light@2.0-java
+LOCAL_MODULE := android.hardware.tests.extension.light-V2.0-java
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -13,8 +13,8 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_JAVA_LIBRARIES := \
- android.hardware.light@2.0-java \
- android.hidl.base@1.0-java \
+ android.hardware.light-V2.0-java \
+ android.hidl.base-V1.0-java \
#
@@ -100,7 +100,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.tests.extension.light@2.0-java-static
+LOCAL_MODULE := android.hardware.tests.extension.light-V2.0-java-static
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -108,8 +108,8 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_STATIC_JAVA_LIBRARIES := \
- android.hardware.light@2.0-java-static \
- android.hidl.base@1.0-java-static \
+ android.hardware.light-V2.0-java-static \
+ android.hidl.base-V1.0-java-static \
#
diff --git a/tests/hash/1.0/Android.mk b/tests/hash/1.0/Android.mk
index 15428b4..586df6e 100644
--- a/tests/hash/1.0/Android.mk
+++ b/tests/hash/1.0/Android.mk
@@ -5,7 +5,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.tests.hash@1.0-java
+LOCAL_MODULE := android.hardware.tests.hash-V1.0-java
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -13,7 +13,7 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_JAVA_LIBRARIES := \
- android.hidl.base@1.0-java \
+ android.hidl.base-V1.0-java \
#
@@ -40,7 +40,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.tests.hash@1.0-java-static
+LOCAL_MODULE := android.hardware.tests.hash-V1.0-java-static
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -48,7 +48,7 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_STATIC_JAVA_LIBRARIES := \
- android.hidl.base@1.0-java-static \
+ android.hidl.base-V1.0-java-static \
#
diff --git a/tests/inheritance/1.0/Android.mk b/tests/inheritance/1.0/Android.mk
index 21aac00..0ff9abc 100644
--- a/tests/inheritance/1.0/Android.mk
+++ b/tests/inheritance/1.0/Android.mk
@@ -5,7 +5,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.tests.inheritance@1.0-java
+LOCAL_MODULE := android.hardware.tests.inheritance-V1.0-java
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -13,7 +13,7 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_JAVA_LIBRARIES := \
- android.hidl.base@1.0-java \
+ android.hidl.base-V1.0-java \
#
@@ -107,7 +107,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.tests.inheritance@1.0-java-static
+LOCAL_MODULE := android.hardware.tests.inheritance-V1.0-java-static
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -115,7 +115,7 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_STATIC_JAVA_LIBRARIES := \
- android.hidl.base@1.0-java-static \
+ android.hidl.base-V1.0-java-static \
#
diff --git a/tests/libhwbinder/1.0/Android.bp b/tests/libhwbinder/1.0/Android.bp
index 9c0fe45..e8d28a3 100644
--- a/tests/libhwbinder/1.0/Android.bp
+++ b/tests/libhwbinder/1.0/Android.bp
@@ -4,6 +4,7 @@
name: "android.hardware.tests.libhwbinder@1.0_hal",
srcs: [
"IBenchmark.hal",
+ "IScheduleTest.hal",
],
}
@@ -16,6 +17,7 @@
],
out: [
"android/hardware/tests/libhwbinder/1.0/BenchmarkAll.cpp",
+ "android/hardware/tests/libhwbinder/1.0/ScheduleTestAll.cpp",
],
}
@@ -32,6 +34,11 @@
"android/hardware/tests/libhwbinder/1.0/BnHwBenchmark.h",
"android/hardware/tests/libhwbinder/1.0/BpHwBenchmark.h",
"android/hardware/tests/libhwbinder/1.0/BsBenchmark.h",
+ "android/hardware/tests/libhwbinder/1.0/IScheduleTest.h",
+ "android/hardware/tests/libhwbinder/1.0/IHwScheduleTest.h",
+ "android/hardware/tests/libhwbinder/1.0/BnHwScheduleTest.h",
+ "android/hardware/tests/libhwbinder/1.0/BpHwScheduleTest.h",
+ "android/hardware/tests/libhwbinder/1.0/BsScheduleTest.h",
],
}
diff --git a/tests/libhwbinder/1.0/Android.mk b/tests/libhwbinder/1.0/Android.mk
index 2ee26d6..bb430fb 100644
--- a/tests/libhwbinder/1.0/Android.mk
+++ b/tests/libhwbinder/1.0/Android.mk
@@ -5,7 +5,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.tests.libhwbinder@1.0-java
+LOCAL_MODULE := android.hardware.tests.libhwbinder-V1.0-java
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -13,7 +13,7 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_JAVA_LIBRARIES := \
- android.hidl.base@1.0-java \
+ android.hidl.base-V1.0-java \
#
@@ -34,13 +34,32 @@
$(GEN): $(LOCAL_PATH)/IBenchmark.hal
$(transform-generated-source)
LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build IScheduleTest.hal
+#
+GEN := $(intermediates)/android/hardware/tests/libhwbinder/V1_0/IScheduleTest.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/IScheduleTest.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+ $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+ -Ljava \
+ -randroid.hardware:hardware/interfaces \
+ -randroid.hidl:system/libhidl/transport \
+ android.hardware.tests.libhwbinder@1.0::IScheduleTest
+
+$(GEN): $(LOCAL_PATH)/IScheduleTest.hal
+ $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
include $(BUILD_JAVA_LIBRARY)
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.tests.libhwbinder@1.0-java-static
+LOCAL_MODULE := android.hardware.tests.libhwbinder-V1.0-java-static
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -48,7 +67,7 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_STATIC_JAVA_LIBRARIES := \
- android.hidl.base@1.0-java-static \
+ android.hidl.base-V1.0-java-static \
#
@@ -69,6 +88,25 @@
$(GEN): $(LOCAL_PATH)/IBenchmark.hal
$(transform-generated-source)
LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build IScheduleTest.hal
+#
+GEN := $(intermediates)/android/hardware/tests/libhwbinder/V1_0/IScheduleTest.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/IScheduleTest.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+ $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+ -Ljava \
+ -randroid.hardware:hardware/interfaces \
+ -randroid.hidl:system/libhidl/transport \
+ android.hardware.tests.libhwbinder@1.0::IScheduleTest
+
+$(GEN): $(LOCAL_PATH)/IScheduleTest.hal
+ $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/tests/libhwbinder/1.0/IBenchmark.hal b/tests/libhwbinder/1.0/IBenchmark.hal
index 6b266e2..b3aa320 100644
--- a/tests/libhwbinder/1.0/IBenchmark.hal
+++ b/tests/libhwbinder/1.0/IBenchmark.hal
@@ -17,5 +17,5 @@
package android.hardware.tests.libhwbinder@1.0;
interface IBenchmark {
- sendVec(vec<uint8_t> data) generates (vec<uint8_t> return_data);
+ sendVec(vec<uint8_t> data) generates (vec<uint8_t> data);
};
diff --git a/tests/libhwbinder/1.0/IScheduleTest.hal b/tests/libhwbinder/1.0/IScheduleTest.hal
new file mode 100644
index 0000000..b3f57c5
--- /dev/null
+++ b/tests/libhwbinder/1.0/IScheduleTest.hal
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+package android.hardware.tests.libhwbinder@1.0;
+
+interface IScheduleTest {
+ send(uint32_t cfg, uint32_t callerSta) generates (uint32_t data);
+};
diff --git a/tests/libhwbinder/1.0/default/Android.bp b/tests/libhwbinder/1.0/default/Android.bp
index e690ca5..fa1b2b3 100644
--- a/tests/libhwbinder/1.0/default/Android.bp
+++ b/tests/libhwbinder/1.0/default/Android.bp
@@ -1,18 +1,16 @@
cc_library_shared {
name: "android.hardware.tests.libhwbinder@1.0-impl",
- defaults: ["hidl_defaults"],
relative_install_path: "hw",
proprietary: true,
srcs: [
"Benchmark.cpp",
+ "ScheduleTest.cpp",
],
-
shared_libs: [
- "libbase",
"libhidlbase",
"libhidltransport",
- "liblog",
"libutils",
"android.hardware.tests.libhwbinder@1.0",
+ "android.hidl.base@1.0",
],
}
diff --git a/tests/libhwbinder/1.0/default/ScheduleTest.cpp b/tests/libhwbinder/1.0/default/ScheduleTest.cpp
new file mode 100644
index 0000000..6356953
--- /dev/null
+++ b/tests/libhwbinder/1.0/default/ScheduleTest.cpp
@@ -0,0 +1,84 @@
+#include "ScheduleTest.h"
+#include <pthread.h>
+#include <iomanip>
+#include <iostream>
+
+using namespace std;
+
+#define ASSERT(cond) \
+ do { \
+ if (!(cond)) { \
+ cerr << __func__ << ":" << __LINE__ << " condition:" << #cond \
+ << " failed\n" \
+ << endl; \
+ exit(EXIT_FAILURE); \
+ } \
+ } while (0)
+
+static int threadPri() {
+ struct sched_param param;
+ int policy;
+ ASSERT(!pthread_getschedparam(pthread_self(), &policy, ¶m));
+ return param.sched_priority;
+}
+
+static void threadDump(const char* prefix, int verbose) {
+ struct sched_param param;
+ int policy;
+ if (!verbose) return;
+ cout << "--------------------------------------------------" << endl;
+ cout << setw(12) << left << prefix << " pid: " << getpid()
+ << " tid: " << gettid() << " cpu: " << sched_getcpu() << endl;
+ ASSERT(!pthread_getschedparam(pthread_self(), &policy, ¶m));
+ string s = (policy == SCHED_OTHER)
+ ? "SCHED_OTHER"
+ : (policy == SCHED_FIFO)
+ ? "SCHED_FIFO"
+ : (policy == SCHED_RR) ? "SCHED_RR" : "???";
+ cout << setw(12) << left << s << param.sched_priority << endl;
+ return;
+}
+
+namespace android {
+namespace hardware {
+namespace tests {
+namespace libhwbinder {
+namespace V1_0 {
+namespace implementation {
+
+// Methods from ::android::hardware::tests::libhwbinder::V1_0::IScheduleTest
+// follow.
+Return<uint32_t> ScheduleTest::send(uint32_t cfg, uint32_t callerSta) {
+ // TODO implement
+ int priority = threadPri();
+ int priority_caller = (callerSta >> 16) & 0xffff;
+ int verbose = cfg & 1;
+ threadDump("hwbinder", verbose);
+ uint32_t h = 0, s = 0;
+ if (priority_caller != priority) {
+ h++;
+ if (verbose) {
+ cout << "err priority_caller:" << priority_caller
+ << ", priority:" << priority << endl;
+ }
+ }
+ int cpu = sched_getcpu();
+ int cpu_caller = (callerSta)&0xffff;
+ if (cpu != cpu_caller) {
+ s++;
+ }
+ return (h << 16) | (s & 0xffff);
+}
+
+// Methods from ::android::hidl::base::V1_0::IBase follow.
+
+IScheduleTest* HIDL_FETCH_IScheduleTest(const char* /* name */) {
+ return new ScheduleTest();
+}
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace libhwbinder
+} // namespace tests
+} // namespace hardware
+} // namespace android
diff --git a/tests/libhwbinder/1.0/default/ScheduleTest.h b/tests/libhwbinder/1.0/default/ScheduleTest.h
new file mode 100644
index 0000000..ad6dd9d
--- /dev/null
+++ b/tests/libhwbinder/1.0/default/ScheduleTest.h
@@ -0,0 +1,41 @@
+#ifndef ANDROID_HARDWARE_TESTS_LIBHWBINDER_V1_0_SCHEDULETEST_H
+#define ANDROID_HARDWARE_TESTS_LIBHWBINDER_V1_0_SCHEDULETEST_H
+
+#include <android/hardware/tests/libhwbinder/1.0/IScheduleTest.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace tests {
+namespace libhwbinder {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::tests::libhwbinder::V1_0::IScheduleTest;
+using ::android::hidl::base::V1_0::DebugInfo;
+using ::android::hidl::base::V1_0::IBase;
+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::sp;
+
+struct ScheduleTest : public IScheduleTest {
+ // Methods from ::android::hardware::tests::libhwbinder::V1_0::IScheduleTest
+ // follow.
+ Return<uint32_t> send(uint32_t cfg, uint32_t callerSta) override;
+
+ // Methods from ::android::hidl::base::V1_0::IBase follow.
+};
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace libhwbinder
+} // namespace tests
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_TESTS_LIBHWBINDER_V1_0_SCHEDULETEST_H
diff --git a/tests/versioning/1.0/Android.mk b/tests/versioning/1.0/Android.mk
index ba18384..81ffd08 100644
--- a/tests/versioning/1.0/Android.mk
+++ b/tests/versioning/1.0/Android.mk
@@ -5,7 +5,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.tests.versioning@1.0-java
+LOCAL_MODULE := android.hardware.tests.versioning-V1.0-java
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -13,7 +13,7 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_JAVA_LIBRARIES := \
- android.hidl.base@1.0-java \
+ android.hidl.base-V1.0-java \
#
@@ -40,7 +40,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.tests.versioning@1.0-java-static
+LOCAL_MODULE := android.hardware.tests.versioning-V1.0-java-static
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -48,7 +48,7 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_STATIC_JAVA_LIBRARIES := \
- android.hidl.base@1.0-java-static \
+ android.hidl.base-V1.0-java-static \
#
diff --git a/tests/versioning/2.2/Android.mk b/tests/versioning/2.2/Android.mk
index e2a2ff7..4fccce6 100644
--- a/tests/versioning/2.2/Android.mk
+++ b/tests/versioning/2.2/Android.mk
@@ -5,7 +5,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.tests.versioning@2.2-java
+LOCAL_MODULE := android.hardware.tests.versioning-V2.2-java
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -13,7 +13,7 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_JAVA_LIBRARIES := \
- android.hidl.base@1.0-java \
+ android.hidl.base-V1.0-java \
#
@@ -59,7 +59,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.tests.versioning@2.2-java-static
+LOCAL_MODULE := android.hardware.tests.versioning-V2.2-java-static
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -67,7 +67,7 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_STATIC_JAVA_LIBRARIES := \
- android.hidl.base@1.0-java-static \
+ android.hidl.base-V1.0-java-static \
#
diff --git a/tests/versioning/2.3/Android.mk b/tests/versioning/2.3/Android.mk
index 68e6be4..36326d6 100644
--- a/tests/versioning/2.3/Android.mk
+++ b/tests/versioning/2.3/Android.mk
@@ -5,7 +5,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.tests.versioning@2.3-java
+LOCAL_MODULE := android.hardware.tests.versioning-V2.3-java
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -13,9 +13,9 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_JAVA_LIBRARIES := \
- android.hardware.tests.versioning@1.0-java \
- android.hardware.tests.versioning@2.2-java \
- android.hidl.base@1.0-java \
+ android.hardware.tests.versioning-V1.0-java \
+ android.hardware.tests.versioning-V2.2-java \
+ android.hidl.base-V1.0-java \
#
@@ -80,7 +80,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.tests.versioning@2.3-java-static
+LOCAL_MODULE := android.hardware.tests.versioning-V2.3-java-static
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -88,9 +88,9 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_STATIC_JAVA_LIBRARIES := \
- android.hardware.tests.versioning@1.0-java-static \
- android.hardware.tests.versioning@2.2-java-static \
- android.hidl.base@1.0-java-static \
+ android.hardware.tests.versioning-V1.0-java-static \
+ android.hardware.tests.versioning-V2.2-java-static \
+ android.hidl.base-V1.0-java-static \
#
diff --git a/tests/versioning/2.4/Android.mk b/tests/versioning/2.4/Android.mk
index e41397f..c716172 100644
--- a/tests/versioning/2.4/Android.mk
+++ b/tests/versioning/2.4/Android.mk
@@ -5,7 +5,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.tests.versioning@2.4-java
+LOCAL_MODULE := android.hardware.tests.versioning-V2.4-java
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -13,9 +13,9 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_JAVA_LIBRARIES := \
- android.hardware.tests.versioning@2.2-java \
- android.hardware.tests.versioning@2.3-java \
- android.hidl.base@1.0-java \
+ android.hardware.tests.versioning-V2.2-java \
+ android.hardware.tests.versioning-V2.3-java \
+ android.hidl.base-V1.0-java \
#
@@ -42,7 +42,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.tests.versioning@2.4-java-static
+LOCAL_MODULE := android.hardware.tests.versioning-V2.4-java-static
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -50,9 +50,9 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_STATIC_JAVA_LIBRARIES := \
- android.hardware.tests.versioning@2.2-java-static \
- android.hardware.tests.versioning@2.3-java-static \
- android.hidl.base@1.0-java-static \
+ android.hardware.tests.versioning-V2.2-java-static \
+ android.hardware.tests.versioning-V2.3-java-static \
+ android.hidl.base-V1.0-java-static \
#
diff --git a/thermal/1.0/Android.mk b/thermal/1.0/Android.mk
index 7748b9e..5a0a9a0 100644
--- a/thermal/1.0/Android.mk
+++ b/thermal/1.0/Android.mk
@@ -5,7 +5,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.thermal@1.0-java
+LOCAL_MODULE := android.hardware.thermal-V1.0-java
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -13,7 +13,7 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_JAVA_LIBRARIES := \
- android.hidl.base@1.0-java \
+ android.hidl.base-V1.0-java \
#
@@ -175,7 +175,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.thermal@1.0-java-static
+LOCAL_MODULE := android.hardware.thermal-V1.0-java-static
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -183,7 +183,7 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_STATIC_JAVA_LIBRARIES := \
- android.hidl.base@1.0-java-static \
+ android.hidl.base-V1.0-java-static \
#
@@ -345,7 +345,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.thermal@1.0-java-constants
+LOCAL_MODULE := android.hardware.thermal-V1.0-java-constants
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
diff --git a/thermal/1.0/default/Android.mk b/thermal/1.0/default/Android.mk
index 2d25dc3..113020a 100644
--- a/thermal/1.0/default/Android.mk
+++ b/thermal/1.0/default/Android.mk
@@ -29,7 +29,6 @@
libdl \
libbase \
libutils \
- libhardware_legacy \
libhardware \
LOCAL_SHARED_LIBRARIES += \
diff --git a/tv/cec/1.0/Android.mk b/tv/cec/1.0/Android.mk
index b08099e..1e3853d 100644
--- a/tv/cec/1.0/Android.mk
+++ b/tv/cec/1.0/Android.mk
@@ -5,7 +5,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.tv.cec@1.0-java
+LOCAL_MODULE := android.hardware.tv.cec-V1.0-java
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -13,7 +13,7 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_JAVA_LIBRARIES := \
- android.hidl.base@1.0-java \
+ android.hidl.base-V1.0-java \
#
@@ -293,7 +293,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.tv.cec@1.0-java-static
+LOCAL_MODULE := android.hardware.tv.cec-V1.0-java-static
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -301,7 +301,7 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_STATIC_JAVA_LIBRARIES := \
- android.hidl.base@1.0-java-static \
+ android.hidl.base-V1.0-java-static \
#
diff --git a/tv/input/1.0/Android.mk b/tv/input/1.0/Android.mk
index 87654da..aa1cf70 100644
--- a/tv/input/1.0/Android.mk
+++ b/tv/input/1.0/Android.mk
@@ -5,7 +5,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.tv.input@1.0-java-constants
+LOCAL_MODULE := android.hardware.tv.input-V1.0-java-constants
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
diff --git a/usb/1.0/Android.mk b/usb/1.0/Android.mk
index 7be7147..62f6935 100644
--- a/usb/1.0/Android.mk
+++ b/usb/1.0/Android.mk
@@ -5,7 +5,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.usb@1.0-java
+LOCAL_MODULE := android.hardware.usb-V1.0-java
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -13,7 +13,7 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_JAVA_LIBRARIES := \
- android.hidl.base@1.0-java \
+ android.hidl.base-V1.0-java \
#
@@ -198,7 +198,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.usb@1.0-java-static
+LOCAL_MODULE := android.hardware.usb-V1.0-java-static
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -206,7 +206,7 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_STATIC_JAVA_LIBRARIES := \
- android.hidl.base@1.0-java-static \
+ android.hidl.base-V1.0-java-static \
#
@@ -391,7 +391,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.usb@1.0-java-constants
+LOCAL_MODULE := android.hardware.usb-V1.0-java-constants
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
diff --git a/vibrator/1.0/Android.mk b/vibrator/1.0/Android.mk
index 8de1ac3..c54b655 100644
--- a/vibrator/1.0/Android.mk
+++ b/vibrator/1.0/Android.mk
@@ -5,7 +5,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.vibrator@1.0-java
+LOCAL_MODULE := android.hardware.vibrator-V1.0-java
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -13,7 +13,7 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_JAVA_LIBRARIES := \
- android.hidl.base@1.0-java \
+ android.hidl.base-V1.0-java \
#
@@ -99,7 +99,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.vibrator@1.0-java-static
+LOCAL_MODULE := android.hardware.vibrator-V1.0-java-static
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -107,7 +107,7 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_STATIC_JAVA_LIBRARIES := \
- android.hidl.base@1.0-java-static \
+ android.hidl.base-V1.0-java-static \
#
@@ -193,7 +193,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.vibrator@1.0-java-constants
+LOCAL_MODULE := android.hardware.vibrator-V1.0-java-constants
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
diff --git a/vr/1.0/Android.mk b/vr/1.0/Android.mk
index 0fbdaf7..fc5c675d 100644
--- a/vr/1.0/Android.mk
+++ b/vr/1.0/Android.mk
@@ -5,7 +5,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.vr@1.0-java
+LOCAL_MODULE := android.hardware.vr-V1.0-java
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -13,7 +13,7 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_JAVA_LIBRARIES := \
- android.hidl.base@1.0-java \
+ android.hidl.base-V1.0-java \
#
@@ -40,7 +40,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.vr@1.0-java-static
+LOCAL_MODULE := android.hardware.vr-V1.0-java-static
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -48,7 +48,7 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_STATIC_JAVA_LIBRARIES := \
- android.hidl.base@1.0-java-static \
+ android.hidl.base-V1.0-java-static \
#
diff --git a/weaver/1.0/Android.bp b/weaver/1.0/Android.bp
index 738da4f..2a7b128 100644
--- a/weaver/1.0/Android.bp
+++ b/weaver/1.0/Android.bp
@@ -44,6 +44,7 @@
generated_sources: ["android.hardware.weaver@1.0_genc++"],
generated_headers: ["android.hardware.weaver@1.0_genc++_headers"],
export_generated_headers: ["android.hardware.weaver@1.0_genc++_headers"],
+ vendor_available: true,
shared_libs: [
"libhidlbase",
"libhidltransport",
diff --git a/weaver/1.0/Android.mk b/weaver/1.0/Android.mk
index f8b08ac..7f35b4e 100644
--- a/weaver/1.0/Android.mk
+++ b/weaver/1.0/Android.mk
@@ -5,7 +5,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.weaver@1.0-java
+LOCAL_MODULE := android.hardware.weaver-V1.0-java
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -13,7 +13,7 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_JAVA_LIBRARIES := \
- android.hidl.base@1.0-java \
+ android.hidl.base-V1.0-java \
#
@@ -118,7 +118,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.weaver@1.0-java-static
+LOCAL_MODULE := android.hardware.weaver-V1.0-java-static
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -126,7 +126,7 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_STATIC_JAVA_LIBRARIES := \
- android.hidl.base@1.0-java-static \
+ android.hidl.base-V1.0-java-static \
#
diff --git a/wifi/1.0/Android.mk b/wifi/1.0/Android.mk
index 82409de..08cdcfa 100644
--- a/wifi/1.0/Android.mk
+++ b/wifi/1.0/Android.mk
@@ -5,7 +5,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.wifi@1.0-java
+LOCAL_MODULE := android.hardware.wifi-V1.0-java
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -13,7 +13,7 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_JAVA_LIBRARIES := \
- android.hidl.base@1.0-java \
+ android.hidl.base-V1.0-java \
#
@@ -1884,7 +1884,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.wifi@1.0-java-static
+LOCAL_MODULE := android.hardware.wifi-V1.0-java-static
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -1892,7 +1892,7 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_STATIC_JAVA_LIBRARIES := \
- android.hidl.base@1.0-java-static \
+ android.hidl.base-V1.0-java-static \
#
diff --git a/wifi/1.0/IWifiStaIface.hal b/wifi/1.0/IWifiStaIface.hal
index 43c3126..644e78a 100644
--- a/wifi/1.0/IWifiStaIface.hal
+++ b/wifi/1.0/IWifiStaIface.hal
@@ -145,6 +145,31 @@
* program if present.
* Must fail if |StaIfaceCapabilityMask.APF| is not set.
*
+ * APF docs
+ * ==========================================================================
+ * APF functionality, instructions and bytecode/binary format is described in:
+ * http://android.googlesource.com/platform/hardware/google/apf/
+ * +/b75c9f3714cfae3dad3d976958e063150781437e/apf.h
+ *
+ * The interpreter API is described here:
+ * http://android.googlesource.com/platform/hardware/google/apf/+/
+ * b75c9f3714cfae3dad3d976958e063150781437e/apf_interpreter.h#32
+ *
+ * The assembler/generator API is described in javadocs here:
+ * http://android.googlesource.com/platform/frameworks/base/+/
+ * 4456f33a958a7f09e608399da83c4d12b2e7d191/services/net/java/android/net/
+ * apf/ApfGenerator.java
+ *
+ * Disassembler usage is described here:
+ * http://android.googlesource.com/platform/hardware/google/apf/+/
+ * b75c9f3714cfae3dad3d976958e063150781437e/apf_disassembler.c#65
+ *
+ * The BPF to APF translator usage is described here:
+ * http://android.googlesource.com/platform/frameworks/base/+/
+ * 4456f33a958a7f09e608399da83c4d12b2e7d191/tests/net/java/android/net/
+ * apf/Bpf2Apf.java
+ * ==========================================================================
+ *
* @param cmdId command Id to use for this invocation.
* @param APF Program to be set.
* @return status WifiStatus of the operation.
diff --git a/wifi/offload/1.0/Android.bp b/wifi/offload/1.0/Android.bp
index 5e89ceb..7ea8deb 100644
--- a/wifi/offload/1.0/Android.bp
+++ b/wifi/offload/1.0/Android.bp
@@ -32,6 +32,7 @@
],
out: [
"android/hardware/wifi/offload/1.0/types.h",
+ "android/hardware/wifi/offload/1.0/hwtypes.h",
"android/hardware/wifi/offload/1.0/IOffload.h",
"android/hardware/wifi/offload/1.0/IHwOffload.h",
"android/hardware/wifi/offload/1.0/BnHwOffload.h",
@@ -50,6 +51,7 @@
generated_sources: ["android.hardware.wifi.offload@1.0_genc++"],
generated_headers: ["android.hardware.wifi.offload@1.0_genc++_headers"],
export_generated_headers: ["android.hardware.wifi.offload@1.0_genc++_headers"],
+ vendor_available: true,
shared_libs: [
"libhidlbase",
"libhidltransport",
diff --git a/wifi/offload/1.0/IOffloadCallback.hal b/wifi/offload/1.0/IOffloadCallback.hal
index 4599370..4888125 100644
--- a/wifi/offload/1.0/IOffloadCallback.hal
+++ b/wifi/offload/1.0/IOffloadCallback.hal
@@ -22,4 +22,11 @@
* @param scanResult a vector of scan result objects
*/
oneway onScanResult(vec<ScanResult> scanResult);
+ /**
+ * Interface for the Offload HAL to inform the client of error conditions
+ * see OffloadStatus for the error conditions to be reported
+ *
+ * @param status OffloadStatus
+ */
+ oneway onError(OffloadStatus status);
};
diff --git a/wifi/offload/1.0/types.hal b/wifi/offload/1.0/types.hal
index 870d2d3..38d5eda 100644
--- a/wifi/offload/1.0/types.hal
+++ b/wifi/offload/1.0/types.hal
@@ -199,6 +199,20 @@
vec<LogRecord> logRecord;
};
+/**
+ * Defines a list of return codes to indicate status of Offload HAL
+ */
+enum OffloadStatus : uint32_t {
+ /* No error */
+ OFFLOAD_STATUS_OK,
+ /* No Connection to underlying implementation */
+ OFFLOAD_STATUS_NO_CONNECTION,
+ /* Operation timeout */
+ OFFLOAD_STATUS_TIMEOUT,
+ /* Other errors */
+ OFFLOAD_STATUS_ERROR
+};
+
diff --git a/wifi/offload/1.0/vts/functional/VtsHalWifiOffloadV1_0TargetTest.cpp b/wifi/offload/1.0/vts/functional/VtsHalWifiOffloadV1_0TargetTest.cpp
index 630922a..3020542 100644
--- a/wifi/offload/1.0/vts/functional/VtsHalWifiOffloadV1_0TargetTest.cpp
+++ b/wifi/offload/1.0/vts/functional/VtsHalWifiOffloadV1_0TargetTest.cpp
@@ -21,6 +21,7 @@
#include <android/hardware/wifi/offload/1.0/IOffloadCallback.h>
#include <android/hardware/wifi/offload/1.0/types.h>
+#include <VtsHalHidlTargetCallbackBase.h>
#include <VtsHalHidlTargetTestBase.h>
#include <vector>
@@ -31,13 +32,31 @@
using ::android::hardware::wifi::offload::V1_0::ScanParam;
using ::android::hardware::wifi::offload::V1_0::ScanFilter;
using ::android::hardware::wifi::offload::V1_0::ScanStats;
+using ::android::hardware::wifi::offload::V1_0::OffloadStatus;
using ::android::hardware::Return;
using ::android::hardware::Void;
using ::android::hardware::hidl_vec;
using ::android::sp;
-typedef std::function<void(const std::vector<ScanResult>& scanResult)>
- OnOffloadScanResultsReadyHandler;
+constexpr char kOffloadCallbackSendScanResult[] = "onScanResult";
+constexpr char kOffloadCallbackSendError[] = "onError";
+
+namespace {
+const uint8_t kSsid[] = {'G', 'o', 'o', 'g', 'l', 'e'};
+const uint8_t kBssid[6] = {0x12, 0xef, 0xa1, 0x2c, 0x97, 0x8b};
+const int16_t kRssi = -60;
+const uint32_t kFrequency = 2412;
+const uint8_t kBssidSize = 6;
+const uint64_t kTsf = 0;
+const uint16_t kCapability = 0;
+const uint8_t kNetworkFlags = 0;
+}
+
+class OffloadCallbackArgs {
+ public:
+ hidl_vec<ScanResult> scan_results_;
+ OffloadStatus error_code_;
+};
// The main test class for WifiOffload HIDL HAL.
class WifiOffloadHidlTest : public ::testing::VtsHalHidlTargetTestBase {
@@ -47,43 +66,39 @@
::testing::VtsHalHidlTargetTestBase::getService<IOffload>();
ASSERT_NE(wifi_offload_, nullptr);
- wifi_offload_cb_ = new OffloadCallback(
- [this](std::vector<ScanResult> scanResult) -> void {
- this->reportScanResults(scanResult);
- });
+ wifi_offload_cb_ = new OffloadCallback();
ASSERT_NE(wifi_offload_cb_, nullptr);
-
- defaultSize = 0;
}
virtual void TearDown() override {}
- void reportScanResults(std::vector<ScanResult> scanResult) {
- defaultSize = scanResult.size();
- }
-
- /* Callback class for scanResult. */
- class OffloadCallback : public IOffloadCallback {
+ /* Callback class for Offload HAL. */
+ class OffloadCallback
+ : public ::testing::VtsHalHidlTargetCallbackBase<OffloadCallbackArgs>,
+ public IOffloadCallback {
public:
- OffloadCallback(OnOffloadScanResultsReadyHandler handler)
- : handler_(handler){};
+ OffloadCallback(){};
virtual ~OffloadCallback() = default;
Return<void> onScanResult(
- const hidl_vec<ScanResult>& scanResult) override {
- const std::vector<ScanResult> scanResult_(scanResult);
- handler_(scanResult_);
+ const hidl_vec<ScanResult>& scan_result) override {
+ OffloadCallbackArgs args;
+ args.scan_results_ = scan_result;
+ NotifyFromCallback(kOffloadCallbackSendScanResult, args);
return Void();
};
- private:
- OnOffloadScanResultsReadyHandler handler_;
+ Return<void> onError(OffloadStatus status) {
+ OffloadCallbackArgs args;
+ args.error_code_ = status;
+ NotifyFromCallback(kOffloadCallbackSendError, args);
+ return Void();
+ }
};
sp<IOffload> wifi_offload_;
- sp<IOffloadCallback> wifi_offload_cb_;
- int defaultSize = 0;
+ sp<OffloadCallback> wifi_offload_cb_;
};
/*
@@ -133,6 +148,38 @@
ASSERT_EQ(returnObject.isOk(), true);
}
+/*
+ * Verify that onScanResult callback is invoked
+ */
+TEST_F(WifiOffloadHidlTest, getScanResults) {
+ wifi_offload_->setEventCallback(wifi_offload_cb_);
+ std::vector<ScanResult> scan_results;
+ std::vector<uint8_t> ssid(kSsid, kSsid + sizeof(kSsid));
+ ScanResult scan_result;
+ scan_result.tsf = kTsf;
+ scan_result.rssi = kRssi;
+ scan_result.frequency = kFrequency;
+ scan_result.capability = kCapability;
+ memcpy(&scan_result.bssid[0], &kBssid[0], kBssidSize);
+ scan_result.networkInfo.ssid = ssid;
+ scan_result.networkInfo.flags = kNetworkFlags;
+ scan_results.push_back(scan_result);
+ wifi_offload_cb_->onScanResult(scan_results);
+ auto res =
+ wifi_offload_cb_->WaitForCallback(kOffloadCallbackSendScanResult);
+ ASSERT_EQ(res.no_timeout, true);
+}
+
+/*
+ * Verify that onError callback is invoked
+ */
+TEST_F(WifiOffloadHidlTest, getError) {
+ wifi_offload_->setEventCallback(wifi_offload_cb_);
+ wifi_offload_cb_->onError(OffloadStatus::OFFLOAD_STATUS_ERROR);
+ auto res = wifi_offload_cb_->WaitForCallback(kOffloadCallbackSendError);
+ ASSERT_EQ(res.no_timeout, true);
+}
+
// A class for test environment setup
class WifiOffloadHalHidlEnvironment : public ::testing::Environment {
public:
diff --git a/wifi/supplicant/1.0/Android.mk b/wifi/supplicant/1.0/Android.mk
index dd210d0..18c7833 100644
--- a/wifi/supplicant/1.0/Android.mk
+++ b/wifi/supplicant/1.0/Android.mk
@@ -5,7 +5,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.wifi.supplicant@1.0-java
+LOCAL_MODULE := android.hardware.wifi.supplicant-V1.0-java
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -13,7 +13,7 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_JAVA_LIBRARIES := \
- android.hidl.base@1.0-java \
+ android.hidl.base-V1.0-java \
#
@@ -384,7 +384,7 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.wifi.supplicant@1.0-java-static
+LOCAL_MODULE := android.hardware.wifi.supplicant-V1.0-java-static
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
@@ -392,7 +392,7 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_STATIC_JAVA_LIBRARIES := \
- android.hidl.base@1.0-java-static \
+ android.hidl.base-V1.0-java-static \
#
diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_p2p_iface_hidl_test.cpp b/wifi/supplicant/1.0/vts/functional/supplicant_p2p_iface_hidl_test.cpp
index 5a210d6..0181f7b 100644
--- a/wifi/supplicant/1.0/vts/functional/supplicant_p2p_iface_hidl_test.cpp
+++ b/wifi/supplicant/1.0/vts/functional/supplicant_p2p_iface_hidl_test.cpp
@@ -40,17 +40,30 @@
constexpr uint8_t kTestSsidPostfix[] = {'t', 'e', 's', 't'};
constexpr uint8_t kTestMacAddr[] = {0x56, 0x67, 0x67, 0xf4, 0x56, 0x92};
constexpr uint8_t kTestPeerMacAddr[] = {0x56, 0x67, 0x55, 0xf4, 0x56, 0x92};
+constexpr uint8_t kTestBonjourServiceQuery[] = {'t', 'e', 's', 't', 'q',
+ 'u', 'e', 'r', 'y'};
+constexpr uint8_t kTestBonjourServiceResponse[] = {
+ 't', 'e', 's', 't', 'r', 'e', 's', 'p', 'o', 'n', 's', 'e'};
+constexpr uint8_t kTestWfdDeviceInfo[] = {[0 ... 5] = 0x01};
constexpr char kTestConnectPin[] = "34556665";
constexpr char kTestGroupIfName[] = "TestGroup";
+constexpr char kTestWpsDeviceName[] = "TestWpsDeviceName";
+constexpr char kTestWpsManufacturer[] = "TestManufacturer";
+constexpr char kTestWpsModelName[] = "TestModelName";
+constexpr char kTestWpsModelNumber[] = "TestModelNumber";
+constexpr char kTestWpsSerialNumber[] = "TestSerialNumber";
+constexpr char kTestUpnpServiceName[] = "TestServiceName";
+constexpr uint8_t kTestWpsDeviceType[] = {[0 ... 7] = 0x01};
+constexpr uint16_t kTestWpsConfigMethods = 0xffff;
constexpr uint32_t kTestConnectGoIntent = 6;
constexpr uint32_t kTestFindTimeout = 5;
constexpr uint32_t kTestSetGroupIdleTimeout = 6;
-constexpr SupplicantNetworkId kTestNetworkId = 5;
constexpr uint32_t kTestChannel = 1;
constexpr uint32_t kTestOperatingClass = 81;
constexpr uint32_t kTestFreqRange[] = {2412, 2432};
constexpr uint32_t kTestExtListenPeriod = 400;
constexpr uint32_t kTestExtListenInterval = 400;
+constexpr SupplicantNetworkId kTestNetworkId = 5;
} // namespace
class SupplicantP2pIfaceHidlTest : public ::testing::VtsHalHidlTargetTestBase {
@@ -309,6 +322,15 @@
}
/*
+ * RemoveGroup
+ */
+TEST_F(SupplicantP2pIfaceHidlTest, RemoveGroup) {
+ // This is not going to work with fake values.
+ EXPECT_NE(SupplicantStatusCode::SUCCESS,
+ HIDL_INVOKE(p2p_iface_, removeGroup, kTestGroupIfName).code);
+}
+
+/*
* Reject
*/
TEST_F(SupplicantP2pIfaceHidlTest, Reject) {
@@ -455,3 +477,145 @@
SupplicantStatusCode::SUCCESS,
HIDL_INVOKE(p2p_iface_, setPowerSave, kTestGroupIfName, false).code);
}
+
+/*
+ * SetWpsDeviceName
+ */
+TEST_F(SupplicantP2pIfaceHidlTest, SetWpsDeviceName) {
+ EXPECT_EQ(
+ SupplicantStatusCode::SUCCESS,
+ HIDL_INVOKE(p2p_iface_, setWpsDeviceName, kTestWpsDeviceName).code);
+}
+
+/*
+ * SetWpsDeviceType
+ */
+TEST_F(SupplicantP2pIfaceHidlTest, SetWpsDeviceType) {
+ EXPECT_EQ(
+ SupplicantStatusCode::SUCCESS,
+ HIDL_INVOKE(p2p_iface_, setWpsDeviceType, kTestWpsDeviceType).code);
+}
+
+/*
+ * SetWpsManufacturer
+ */
+TEST_F(SupplicantP2pIfaceHidlTest, SetWpsManufacturer) {
+ EXPECT_EQ(
+ SupplicantStatusCode::SUCCESS,
+ HIDL_INVOKE(p2p_iface_, setWpsManufacturer, kTestWpsManufacturer).code);
+}
+
+/*
+ * SetWpsModelName
+ */
+TEST_F(SupplicantP2pIfaceHidlTest, SetWpsModelName) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS,
+ HIDL_INVOKE(p2p_iface_, setWpsModelName, kTestWpsModelName).code);
+}
+
+/*
+ * SetWpsModelNumber
+ */
+TEST_F(SupplicantP2pIfaceHidlTest, SetWpsModelNumber) {
+ EXPECT_EQ(
+ SupplicantStatusCode::SUCCESS,
+ HIDL_INVOKE(p2p_iface_, setWpsModelNumber, kTestWpsModelNumber).code);
+}
+
+/*
+ * SetWpsSerialNumber
+ */
+TEST_F(SupplicantP2pIfaceHidlTest, SetWpsSerialNumber) {
+ EXPECT_EQ(
+ SupplicantStatusCode::SUCCESS,
+ HIDL_INVOKE(p2p_iface_, setWpsSerialNumber, kTestWpsSerialNumber).code);
+}
+
+/*
+ * SetWpsConfigMethods
+ */
+TEST_F(SupplicantP2pIfaceHidlTest, SetWpsConfigMethods) {
+ EXPECT_EQ(
+ SupplicantStatusCode::SUCCESS,
+ HIDL_INVOKE(p2p_iface_, setWpsConfigMethods, kTestWpsConfigMethods)
+ .code);
+}
+
+/*
+ * AddAndRemoveBonjourService
+ * This tests that we are able to add a bonjour service, and we can remove it
+ * by using the same query data.
+ * This also tests that removeBonjourSerive() returns error when there is no
+ * existing bonjour service with the same query data.
+ */
+TEST_F(SupplicantP2pIfaceHidlTest, AddAndRemoveBonjourService) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS,
+ HIDL_INVOKE(
+ p2p_iface_, addBonjourService,
+ std::vector<uint8_t>(kTestBonjourServiceQuery,
+ kTestBonjourServiceQuery +
+ sizeof(kTestBonjourServiceQuery)),
+ std::vector<uint8_t>(kTestBonjourServiceResponse,
+ kTestBonjourServiceResponse +
+ sizeof(kTestBonjourServiceResponse)))
+ .code);
+ EXPECT_EQ(
+ SupplicantStatusCode::SUCCESS,
+ HIDL_INVOKE(p2p_iface_, removeBonjourService,
+ std::vector<uint8_t>(kTestBonjourServiceQuery,
+ kTestBonjourServiceQuery +
+ sizeof(kTestBonjourServiceQuery)))
+ .code);
+ // This will fail because boujour service with kTestBonjourServiceQuery was
+ // already removed.
+ EXPECT_NE(
+ SupplicantStatusCode::SUCCESS,
+ HIDL_INVOKE(p2p_iface_, removeBonjourService,
+ std::vector<uint8_t>(kTestBonjourServiceQuery,
+ kTestBonjourServiceQuery +
+ sizeof(kTestBonjourServiceQuery)))
+ .code);
+}
+
+/*
+ * AddAndRemoveUpnpService
+ * This tests that we are able to add a upnp service, and we can remove it
+ * by using the same service name.
+ * This also tests that removeUpnpService() returns error when there is no
+ * exsiting upnp service with the same service name.
+ */
+TEST_F(SupplicantP2pIfaceHidlTest, AddAndRemoveUpnpService) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS,
+ HIDL_INVOKE(p2p_iface_, addUpnpService, 0 /* version */,
+ kTestUpnpServiceName)
+ .code);
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS,
+ HIDL_INVOKE(p2p_iface_, removeUpnpService, 0 /* version */,
+ kTestUpnpServiceName)
+ .code);
+ // This will fail because Upnp service with kTestUpnpServiceName was
+ // already removed.
+ EXPECT_NE(SupplicantStatusCode::SUCCESS,
+ HIDL_INVOKE(p2p_iface_, removeUpnpService, 0 /* version */,
+ kTestUpnpServiceName)
+ .code);
+}
+
+/*
+ * EnableWfd
+ */
+TEST_F(SupplicantP2pIfaceHidlTest, EnableWfd) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS,
+ HIDL_INVOKE(p2p_iface_, enableWfd, true).code);
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS,
+ HIDL_INVOKE(p2p_iface_, enableWfd, false).code);
+}
+
+/*
+ * SetWfdDeviceInfo
+ */
+TEST_F(SupplicantP2pIfaceHidlTest, SetWfdDeviceInfo) {
+ EXPECT_EQ(
+ SupplicantStatusCode::SUCCESS,
+ HIDL_INVOKE(p2p_iface_, setWfdDeviceInfo, kTestWfdDeviceInfo).code);
+}
diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_sta_iface_hidl_test.cpp b/wifi/supplicant/1.0/vts/functional/supplicant_sta_iface_hidl_test.cpp
index 3670321..c0e62d1 100644
--- a/wifi/supplicant/1.0/vts/functional/supplicant_sta_iface_hidl_test.cpp
+++ b/wifi/supplicant/1.0/vts/functional/supplicant_sta_iface_hidl_test.cpp
@@ -47,7 +47,18 @@
ISupplicantStaIface::Hs20AnqpSubtypes::WAN_METRICS,
ISupplicantStaIface::Hs20AnqpSubtypes::OPERATOR_FRIENDLY_NAME};
constexpr char kTestHs20IconFile[] = "TestFile";
+constexpr char kTestWpsDeviceName[] = "TestWpsDeviceName";
+constexpr char kTestWpsManufacturer[] = "TestManufacturer";
+constexpr char kTestWpsModelName[] = "TestModelName";
+constexpr char kTestWpsModelNumber[] = "TestModelNumber";
+constexpr char kTestWpsSerialNumber[] = "TestSerialNumber";
+constexpr char kTestRadioWorkName[] = "TestRadioWork";
+constexpr uint32_t kTestRadioWorkFrequency = 2412;
+constexpr uint32_t kTestRadioWorkTimeout = 8;
+constexpr uint32_t kTestRadioWorkId = 16;
constexpr int8_t kTestCountryCode[] = {'U', 'S'};
+constexpr uint8_t kTestWpsDeviceType[] = {[0 ... 7] = 0x01};
+constexpr uint16_t kTestWpsConfigMethods = 0xffff;
} // namespace
class SupplicantStaIfaceHidlTest : public ::testing::VtsHalHidlTargetTestBase {
@@ -427,3 +438,101 @@
EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
});
}
+
+/*
+ * SetWpsDeviceName
+ */
+TEST_F(SupplicantStaIfaceHidlTest, SetWpsDeviceName) {
+ EXPECT_EQ(
+ SupplicantStatusCode::SUCCESS,
+ HIDL_INVOKE(sta_iface_, setWpsDeviceName, kTestWpsDeviceName).code);
+}
+
+/*
+ * SetWpsDeviceType
+ */
+TEST_F(SupplicantStaIfaceHidlTest, SetWpsDeviceType) {
+ EXPECT_EQ(
+ SupplicantStatusCode::SUCCESS,
+ HIDL_INVOKE(sta_iface_, setWpsDeviceType, kTestWpsDeviceType).code);
+}
+
+/*
+ * SetWpsManufacturer
+ */
+TEST_F(SupplicantStaIfaceHidlTest, SetWpsManufacturer) {
+ EXPECT_EQ(
+ SupplicantStatusCode::SUCCESS,
+ HIDL_INVOKE(sta_iface_, setWpsManufacturer, kTestWpsManufacturer).code);
+}
+
+/*
+ * SetWpsModelName
+ */
+TEST_F(SupplicantStaIfaceHidlTest, SetWpsModelName) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS,
+ HIDL_INVOKE(sta_iface_, setWpsModelName, kTestWpsModelName).code);
+}
+
+/*
+ * SetWpsModelNumber
+ */
+TEST_F(SupplicantStaIfaceHidlTest, SetWpsModelNumber) {
+ EXPECT_EQ(
+ SupplicantStatusCode::SUCCESS,
+ HIDL_INVOKE(sta_iface_, setWpsModelNumber, kTestWpsModelNumber).code);
+}
+
+/*
+ * SetWpsSerialNumber
+ */
+TEST_F(SupplicantStaIfaceHidlTest, SetWpsSerialNumber) {
+ EXPECT_EQ(
+ SupplicantStatusCode::SUCCESS,
+ HIDL_INVOKE(sta_iface_, setWpsSerialNumber, kTestWpsSerialNumber).code);
+}
+
+/*
+ * SetWpsConfigMethods
+ */
+TEST_F(SupplicantStaIfaceHidlTest, SetWpsConfigMethods) {
+ EXPECT_EQ(
+ SupplicantStatusCode::SUCCESS,
+ HIDL_INVOKE(sta_iface_, setWpsConfigMethods, kTestWpsConfigMethods)
+ .code);
+}
+
+/*
+ * SetExternalSim
+ */
+TEST_F(SupplicantStaIfaceHidlTest, SetExternalSim) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS,
+ HIDL_INVOKE(sta_iface_, setExternalSim, true).code);
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS,
+ HIDL_INVOKE(sta_iface_, setExternalSim, false).code);
+}
+
+/*
+ * AddExtRadioWork
+ */
+TEST_F(SupplicantStaIfaceHidlTest, AddExtRadioWork) {
+ const auto& status_and_radio_work_id =
+ HIDL_INVOKE(sta_iface_, addExtRadioWork, kTestRadioWorkName,
+ kTestRadioWorkFrequency, kTestRadioWorkTimeout);
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS,
+ status_and_radio_work_id.first.code);
+ // removeExtRadio only succeeds if the added radio work hasn't started yet.
+ // So there this no guaranteed result from calling removeExtRadioWork here.
+ // That being said, currently we are not able to test addExtRadioWork and
+ // removeExtRadioWork in a row.
+}
+
+/*
+ * RemoveExtRadioWork
+ */
+TEST_F(SupplicantStaIfaceHidlTest, RemoveExtRadioWork) {
+ // This fails because there is no on going radio work with kTestRadioWorkId.
+ EXPECT_NE(
+ SupplicantStatusCode::SUCCESS,
+ HIDL_INVOKE(sta_iface_, removeExtRadioWork, kTestRadioWorkId).code);
+}