Merge "graphics: replace non-const references by pointers"
diff --git a/audio/2.0/IStream.hal b/audio/2.0/IStream.hal
index dc43346..5c88a69 100644
--- a/audio/2.0/IStream.hal
+++ b/audio/2.0/IStream.hal
@@ -227,4 +227,56 @@
* @param fd dump file descriptor.
*/
debugDump(handle fd);
+
+ /*
+ * Called by the framework to start a stream operating in mmap mode.
+ * createMmapBuffer() must be called before calling start().
+ * Function only implemented by streams operating in mmap mode.
+ *
+ * @return retval OK in case the success.
+ * NOT_SUPPORTED on non mmap mode streams
+ * INVALID_STATE if called out of sequence
+ */
+ start() generates (Result retval);
+
+ /**
+ * Called by the framework to stop a stream operating in mmap mode.
+ * Function only implemented by streams operating in mmap mode.
+ *
+ * @return retval OK in case the succes.
+ * NOT_SUPPORTED on non mmap mode streams
+ * INVALID_STATE if called out of sequence
+ */
+ stop() generates (Result retval) ;
+
+ /*
+ * Called by the framework to retrieve information on the mmap buffer used for audio
+ * samples transfer.
+ * Function only implemented by streams operating in mmap mode.
+ *
+ * @param minSizeFrames minimum buffer size requested. The actual buffer
+ * size returned in struct MmapBufferInfo can be larger.
+ * @return retval OK in case the success.
+ * NOT_SUPPORTED on non mmap mode streams
+ * NOT_INITIALIZED in case of memory allocation error
+ * INVALID_ARGUMENTS if the requested buffer size is too large
+ * INVALID_STATE if called out of sequence
+ * @return info a MmapBufferInfo struct containing information on the MMMAP buffer created.
+ */
+ createMmapBuffer(int32_t minSizeFrames)
+ generates (Result retval, MmapBufferInfo info);
+
+ /*
+ * Called by the framework to read current read/write position in the mmap buffer
+ * with associated time stamp.
+ * Function only implemented by streams operating in mmap mode.
+ *
+ * @return retval OK in case the success.
+ * NOT_SUPPORTED on non mmap mode streams
+ * INVALID_STATE if called out of sequence
+ * @return position a MmapPosition struct containing current HW read/write position in frames
+ * with associated time stamp.
+ */
+ getMmapPosition()
+ generates (Result retval, MmapPosition position);
};
diff --git a/audio/2.0/IStreamOutCallback.hal b/audio/2.0/IStreamOutCallback.hal
index 267c46d..cdb38de 100644
--- a/audio/2.0/IStreamOutCallback.hal
+++ b/audio/2.0/IStreamOutCallback.hal
@@ -23,15 +23,15 @@
/*
* Non blocking write completed.
*/
- onWriteReady();
+ oneway onWriteReady();
/*
* Drain completed.
*/
- onDrainReady();
+ oneway onDrainReady();
/*
* Stream hit an error.
*/
- onError();
+ oneway onError();
};
diff --git a/audio/2.0/default/Android.mk b/audio/2.0/default/Android.mk
index 2b1aa4f..c3cfd69 100644
--- a/audio/2.0/default/Android.mk
+++ b/audio/2.0/default/Android.mk
@@ -33,6 +33,7 @@
libhidlbase \
libhidltransport \
libhwbinder \
+ libcutils \
libutils \
libhardware \
liblog \
diff --git a/audio/2.0/default/Stream.cpp b/audio/2.0/default/Stream.cpp
index 40f67f0..f214eed 100644
--- a/audio/2.0/default/Stream.cpp
+++ b/audio/2.0/default/Stream.cpp
@@ -43,9 +43,10 @@
mStream = nullptr;
}
+// static
Result Stream::analyzeStatus(const char* funcName, int status, int ignoreError) {
if (status != 0 && status != -ignoreError) {
- ALOGW("Stream %p %s: %s", mStream, funcName, strerror(-status));
+ ALOGW("Error from HAL stream in function %s: %s", funcName, strerror(-status));
}
switch (status) {
case 0: return Result::OK;
@@ -229,6 +230,29 @@
return Void();
}
+Return<Result> Stream::start() {
+ return Result::NOT_SUPPORTED;
+}
+
+Return<Result> Stream::stop() {
+ return Result::NOT_SUPPORTED;
+}
+
+Return<void> Stream::createMmapBuffer(int32_t minSizeFrames __unused,
+ createMmapBuffer_cb _hidl_cb) {
+ Result retval(Result::NOT_SUPPORTED);
+ MmapBufferInfo info;
+ _hidl_cb(retval, info);
+ return Void();
+}
+
+Return<void> Stream::getMmapPosition(getMmapPosition_cb _hidl_cb) {
+ Result retval(Result::NOT_SUPPORTED);
+ MmapPosition position;
+ _hidl_cb(retval, position);
+ return Void();
+}
+
} // namespace implementation
} // namespace V2_0
} // namespace audio
diff --git a/audio/2.0/default/Stream.h b/audio/2.0/default/Stream.h
index 0ebd723..819bbf7 100644
--- a/audio/2.0/default/Stream.h
+++ b/audio/2.0/default/Stream.h
@@ -18,6 +18,7 @@
#define ANDROID_HARDWARE_AUDIO_V2_0_STREAM_H
#include <android/hardware/audio/2.0/IStream.h>
+#include <hardware/audio.h>
#include <hidl/Status.h>
#include <hidl/MQDescriptor.h>
@@ -71,9 +72,13 @@
const hidl_vec<hidl_string>& keys, getParameters_cb _hidl_cb) override;
Return<Result> setParameters(const hidl_vec<ParameterValue>& parameters) override;
Return<void> debugDump(const hidl_handle& fd) override;
+ Return<Result> start() override;
+ Return<Result> stop() override;
+ Return<void> createMmapBuffer(int32_t minSizeFrames, createMmapBuffer_cb _hidl_cb) override;
+ Return<void> getMmapPosition(getMmapPosition_cb _hidl_cb) override;
// Utility methods for extending interfaces.
- Result analyzeStatus(const char* funcName, int status, int ignoreError = OK);
+ static Result analyzeStatus(const char* funcName, int status, int ignoreError = OK);
private:
audio_stream_t *mStream;
@@ -85,6 +90,80 @@
int halSetParameters(const char* keysAndValues) override;
};
+
+template <typename T>
+struct StreamMmap : public RefBase {
+ explicit StreamMmap(T* stream) : mStream(stream) {}
+
+ Return<Result> start();
+ Return<Result> stop();
+ Return<void> createMmapBuffer(
+ int32_t minSizeFrames, size_t frameSize, IStream::createMmapBuffer_cb _hidl_cb);
+ Return<void> getMmapPosition(IStream::getMmapPosition_cb _hidl_cb);
+
+ private:
+ StreamMmap() {}
+
+ T *mStream;
+};
+
+template <typename T>
+Return<Result> StreamMmap<T>::start() {
+ if (mStream->start == NULL) return Result::NOT_SUPPORTED;
+ int result = mStream->start(mStream);
+ return Stream::analyzeStatus("start", result);
+}
+
+template <typename T>
+Return<Result> StreamMmap<T>::stop() {
+ if (mStream->stop == NULL) return Result::NOT_SUPPORTED;
+ int result = mStream->stop(mStream);
+ return Stream::analyzeStatus("stop", result);
+}
+
+template <typename T>
+Return<void> StreamMmap<T>::createMmapBuffer(int32_t minSizeFrames, size_t frameSize,
+ IStream::createMmapBuffer_cb _hidl_cb) {
+ Result retval(Result::NOT_SUPPORTED);
+ MmapBufferInfo info;
+
+ if (mStream->create_mmap_buffer != NULL) {
+ struct audio_mmap_buffer_info halInfo;
+ retval = Stream::analyzeStatus(
+ "create_mmap_buffer",
+ mStream->create_mmap_buffer(mStream, minSizeFrames, &halInfo));
+ if (retval == Result::OK) {
+ native_handle_t* hidlHandle = native_handle_create(1, 0);
+ hidlHandle->data[0] = halInfo.shared_memory_fd;
+ info.sharedMemory = hidl_memory("audio_buffer", hidlHandle,
+ frameSize *halInfo.buffer_size_frames);
+ info.bufferSizeFrames = halInfo.buffer_size_frames;
+ info.burstSizeFrames = halInfo.burst_size_frames;
+ }
+ }
+ _hidl_cb(retval, info);
+ return Void();
+}
+
+template <typename T>
+Return<void> StreamMmap<T>::getMmapPosition(IStream::getMmapPosition_cb _hidl_cb) {
+ Result retval(Result::NOT_SUPPORTED);
+ MmapPosition position;
+
+ if (mStream->get_mmap_position != NULL) {
+ struct audio_mmap_position halPosition;
+ retval = Stream::analyzeStatus(
+ "get_mmap_position",
+ mStream->get_mmap_position(mStream, &halPosition));
+ if (retval == Result::OK) {
+ position.timeNanoseconds = halPosition.time_nanoseconds;
+ position.positionFrames = halPosition.position_frames;
+ }
+ }
+ _hidl_cb(retval, position);
+ return Void();
+}
+
} // namespace implementation
} // namespace V2_0
} // namespace audio
diff --git a/audio/2.0/default/StreamIn.cpp b/audio/2.0/default/StreamIn.cpp
index 1bc9dfb..1441e74 100644
--- a/audio/2.0/default/StreamIn.cpp
+++ b/audio/2.0/default/StreamIn.cpp
@@ -28,7 +28,9 @@
namespace implementation {
StreamIn::StreamIn(audio_hw_device_t* device, audio_stream_in_t* stream)
- : mDevice(device), mStream(stream), mStreamCommon(new Stream(&stream->common)) {
+ : mDevice(device), mStream(stream),
+ mStreamCommon(new Stream(&stream->common)),
+ mStreamMmap(new StreamMmap<audio_stream_in_t>(stream)) {
}
StreamIn::~StreamIn() {
@@ -130,6 +132,22 @@
return mStreamCommon->debugDump(fd);
}
+Return<Result> StreamIn::start() {
+ return mStreamMmap->start();
+}
+
+Return<Result> StreamIn::stop() {
+ return mStreamMmap->stop();
+}
+
+Return<void> StreamIn::createMmapBuffer(int32_t minSizeFrames, createMmapBuffer_cb _hidl_cb) {
+ return mStreamMmap->createMmapBuffer(
+ minSizeFrames, audio_stream_in_frame_size(mStream), _hidl_cb);
+}
+
+Return<void> StreamIn::getMmapPosition(getMmapPosition_cb _hidl_cb) {
+ return mStreamMmap->getMmapPosition(_hidl_cb);
+}
// Methods from ::android::hardware::audio::V2_0::IStreamIn follow.
Return<void> StreamIn::getAudioSource(getAudioSource_cb _hidl_cb) {
@@ -144,7 +162,7 @@
}
Return<Result> StreamIn::setGain(float gain) {
- return mStreamCommon->analyzeStatus("set_gain", mStream->set_gain(mStream, gain));
+ return Stream::analyzeStatus("set_gain", mStream->set_gain(mStream, gain));
}
Return<void> StreamIn::read(uint64_t size, read_cb _hidl_cb) {
@@ -157,7 +175,7 @@
data.resize(readResult);
} else if (readResult < 0) {
data.resize(0);
- retval = mStreamCommon->analyzeStatus("read", readResult);
+ retval = Stream::analyzeStatus("read", readResult);
}
_hidl_cb(retval, data);
return Void();
@@ -172,7 +190,7 @@
uint64_t frames = 0, time = 0;
if (mStream->get_capture_position != NULL) {
int64_t halFrames, halTime;
- retval = mStreamCommon->analyzeStatus(
+ retval = Stream::analyzeStatus(
"get_capture_position",
mStream->get_capture_position(mStream, &halFrames, &halTime));
if (retval == Result::OK) {
diff --git a/audio/2.0/default/StreamIn.h b/audio/2.0/default/StreamIn.h
index f7c17b7..65e94bb 100644
--- a/audio/2.0/default/StreamIn.h
+++ b/audio/2.0/default/StreamIn.h
@@ -80,11 +80,17 @@
Return<void> read(uint64_t size, read_cb _hidl_cb) override;
Return<uint32_t> getInputFramesLost() override;
Return<void> getCapturePosition(getCapturePosition_cb _hidl_cb) override;
+ Return<Result> start() override;
+ Return<Result> stop() override;
+ Return<void> createMmapBuffer(int32_t minSizeFrames, createMmapBuffer_cb _hidl_cb) override;
+ Return<void> getMmapPosition(getMmapPosition_cb _hidl_cb) override;
private:
audio_hw_device_t *mDevice;
audio_stream_in_t *mStream;
sp<Stream> mStreamCommon;
+ sp<StreamMmap<audio_stream_in_t>> mStreamMmap;
+
virtual ~StreamIn();
};
diff --git a/audio/2.0/default/StreamOut.cpp b/audio/2.0/default/StreamOut.cpp
index 913b6ae..3d20d11 100644
--- a/audio/2.0/default/StreamOut.cpp
+++ b/audio/2.0/default/StreamOut.cpp
@@ -15,6 +15,7 @@
*/
#define LOG_TAG "StreamOutHAL"
+//#define LOG_NDEBUG 0
#include <hardware/audio.h>
#include <android/log.h>
@@ -28,7 +29,9 @@
namespace implementation {
StreamOut::StreamOut(audio_hw_device_t* device, audio_stream_out_t* stream)
- : mDevice(device), mStream(stream), mStreamCommon(new Stream(&stream->common)) {
+ : mDevice(device), mStream(stream),
+ mStreamCommon(new Stream(&stream->common)),
+ mStreamMmap(new StreamMmap<audio_stream_out_t>(stream)) {
}
StreamOut::~StreamOut() {
@@ -132,7 +135,6 @@
return mStreamCommon->debugDump(fd);
}
-
// Methods from ::android::hardware::audio::V2_0::IStreamOut follow.
Return<uint32_t> StreamOut::getLatency() {
return mStream->get_latency(mStream);
@@ -141,7 +143,7 @@
Return<Result> StreamOut::setVolume(float left, float right) {
Result retval(Result::NOT_SUPPORTED);
if (mStream->set_volume != NULL) {
- retval = mStreamCommon->analyzeStatus(
+ retval = Stream::analyzeStatus(
"set_volume", mStream->set_volume(mStream, left, right));
}
return retval;
@@ -155,7 +157,7 @@
if (writeResult >= 0) {
written = writeResult;
} else {
- retval = mStreamCommon->analyzeStatus("write", writeResult);
+ retval = Stream::analyzeStatus("write", writeResult);
written = 0;
}
_hidl_cb(retval, written);
@@ -164,7 +166,7 @@
Return<void> StreamOut::getRenderPosition(getRenderPosition_cb _hidl_cb) {
uint32_t halDspFrames;
- Result retval = mStreamCommon->analyzeStatus(
+ Result retval = Stream::analyzeStatus(
"get_render_position", mStream->get_render_position(mStream, &halDspFrames));
_hidl_cb(retval, halDspFrames);
return Void();
@@ -174,7 +176,7 @@
Result retval(Result::NOT_SUPPORTED);
int64_t timestampUs = 0;
if (mStream->get_next_write_timestamp != NULL) {
- retval = mStreamCommon->analyzeStatus(
+ retval = Stream::analyzeStatus(
"get_next_write_timestamp",
mStream->get_next_write_timestamp(mStream, ×tampUs));
}
@@ -188,7 +190,7 @@
if (result == 0) {
mCallback = callback;
}
- return mStreamCommon->analyzeStatus("set_callback", result);
+ return Stream::analyzeStatus("set_callback", result);
}
Return<Result> StreamOut::clearCallback() {
@@ -227,13 +229,13 @@
Return<Result> StreamOut::pause() {
return mStream->pause != NULL ?
- mStreamCommon->analyzeStatus("pause", mStream->pause(mStream)) :
+ Stream::analyzeStatus("pause", mStream->pause(mStream)) :
Result::NOT_SUPPORTED;
}
Return<Result> StreamOut::resume() {
return mStream->resume != NULL ?
- mStreamCommon->analyzeStatus("resume", mStream->resume(mStream)) :
+ Stream::analyzeStatus("resume", mStream->resume(mStream)) :
Result::NOT_SUPPORTED;
}
@@ -243,14 +245,14 @@
Return<Result> StreamOut::drain(AudioDrain type) {
return mStream->drain != NULL ?
- mStreamCommon->analyzeStatus(
+ Stream::analyzeStatus(
"drain", mStream->drain(mStream, static_cast<audio_drain_type_t>(type))) :
Result::NOT_SUPPORTED;
}
Return<Result> StreamOut::flush() {
return mStream->flush != NULL ?
- mStreamCommon->analyzeStatus("flush", mStream->flush(mStream)) :
+ Stream::analyzeStatus("flush", mStream->flush(mStream)) :
Result::NOT_SUPPORTED;
}
@@ -260,7 +262,7 @@
TimeSpec timeStamp = { 0, 0 };
if (mStream->get_presentation_position != NULL) {
struct timespec halTimeStamp;
- retval = mStreamCommon->analyzeStatus(
+ retval = Stream::analyzeStatus(
"get_presentation_position",
mStream->get_presentation_position(mStream, &frames, &halTimeStamp),
// Don't logspam on EINVAL--it's normal for get_presentation_position
@@ -275,6 +277,23 @@
return Void();
}
+Return<Result> StreamOut::start() {
+ return mStreamMmap->start();
+}
+
+Return<Result> StreamOut::stop() {
+ return mStreamMmap->stop();
+}
+
+Return<void> StreamOut::createMmapBuffer(int32_t minSizeFrames, createMmapBuffer_cb _hidl_cb) {
+ return mStreamMmap->createMmapBuffer(
+ minSizeFrames, audio_stream_out_frame_size(mStream), _hidl_cb);
+}
+
+Return<void> StreamOut::getMmapPosition(getMmapPosition_cb _hidl_cb) {
+ return mStreamMmap->getMmapPosition(_hidl_cb);
+}
+
} // namespace implementation
} // namespace V2_0
} // namespace audio
diff --git a/audio/2.0/default/StreamOut.h b/audio/2.0/default/StreamOut.h
index dc9a604..9b7f9f8 100644
--- a/audio/2.0/default/StreamOut.h
+++ b/audio/2.0/default/StreamOut.h
@@ -91,11 +91,16 @@
Return<Result> drain(AudioDrain type) override;
Return<Result> flush() override;
Return<void> getPresentationPosition(getPresentationPosition_cb _hidl_cb) override;
+ Return<Result> start() override;
+ Return<Result> stop() override;
+ Return<void> createMmapBuffer(int32_t minSizeFrames, createMmapBuffer_cb _hidl_cb) override;
+ Return<void> getMmapPosition(getMmapPosition_cb _hidl_cb) override;
private:
audio_hw_device_t *mDevice;
audio_stream_out_t *mStream;
sp<Stream> mStreamCommon;
+ sp<StreamMmap<audio_stream_out_t>> mStreamMmap;
sp<IStreamOutCallback> mCallback;
virtual ~StreamOut();
diff --git a/audio/2.0/types.hal b/audio/2.0/types.hal
index 7002f38..37c39e4 100644
--- a/audio/2.0/types.hal
+++ b/audio/2.0/types.hal
@@ -70,3 +70,22 @@
string busAddress; // used for BUS
string rSubmixAddress; // used for REMOTE_SUBMIX
};
+
+/*
+ * Mmap buffer descriptor returned by IStream.createMmapBuffer().
+ * Used by streams opened in mmap mode.
+ */
+struct MmapBufferInfo {
+ memory sharedMemory; // mmap memory buffer
+ int32_t bufferSizeFrames; // total buffer size in frames
+ int32_t burstSizeFrames; // transfer size granularity in frames
+};
+
+/*
+ * Mmap buffer read/write position returned by IStream.getMmapPosition().
+ * Used by streams opened in mmap mode.
+ */
+struct MmapPosition {
+ int64_t timeNanoseconds; // time stamp in ns, CLOCK_MONOTONIC
+ int32_t positionFrames; // increasing 32 bit frame count reset when IStream.stop() is called
+};
diff --git a/audio/common/2.0/default/HidlUtils.cpp b/audio/common/2.0/default/HidlUtils.cpp
index b1bff00..241ca90 100644
--- a/audio/common/2.0/default/HidlUtils.cpp
+++ b/audio/common/2.0/default/HidlUtils.cpp
@@ -97,6 +97,7 @@
const audio_offload_info_t& halOffload, AudioOffloadInfo* offload) {
offload->sampleRateHz = halOffload.sample_rate;
offload->channelMask = AudioChannelMask(halOffload.channel_mask);
+ offload->format = AudioFormat(halOffload.format);
offload->streamType = AudioStreamType(halOffload.stream_type);
offload->bitRatePerSecond = halOffload.bit_rate;
offload->durationMicroseconds = halOffload.duration_us;
@@ -109,6 +110,7 @@
*halOffload = AUDIO_INFO_INITIALIZER;
halOffload->sample_rate = offload.sampleRateHz;
halOffload->channel_mask = static_cast<audio_channel_mask_t>(offload.channelMask);
+ halOffload->format = static_cast<audio_format_t>(offload.format);
halOffload->stream_type = static_cast<audio_stream_type_t>(offload.streamType);
halOffload->bit_rate = offload.bitRatePerSecond;
halOffload->duration_us = offload.durationMicroseconds;
diff --git a/audio/effect/2.0/vts/functional/audio_effect_hidl_hal_test.cpp b/audio/effect/2.0/vts/functional/audio_effect_hidl_hal_test.cpp
index ef70215..1e0ab32 100644
--- a/audio/effect/2.0/vts/functional/audio_effect_hidl_hal_test.cpp
+++ b/audio/effect/2.0/vts/functional/audio_effect_hidl_hal_test.cpp
@@ -97,49 +97,6 @@
EXPECT_NE(effect, nullptr);
}
-// See b/32834072 -- we should have those operator== generated by hidl-gen.
-
-namespace android {
-namespace hardware {
-namespace audio {
-namespace common {
-namespace V2_0 {
-
-static bool operator==(const Uuid& lhs, const Uuid& rhs) {
- return lhs.timeLow == rhs.timeLow && lhs.timeMid == rhs.timeMid &&
- lhs.versionAndTimeHigh == rhs.versionAndTimeHigh &&
- lhs.variantAndClockSeqHigh == rhs.variantAndClockSeqHigh &&
- memcmp(lhs.node.data(), rhs.node.data(), lhs.node.size()) == 0;
-}
-
-} // namespace V2_0
-} // namespace common
-} // namespace audio
-} // namespace hardware
-} // namespace android
-
-namespace android {
-namespace hardware {
-namespace audio {
-namespace effect {
-namespace V2_0 {
-
-static bool operator==(const EffectDescriptor& lhs,
- const EffectDescriptor& rhs) {
- return lhs.type == rhs.type && lhs.uuid == rhs.uuid &&
- lhs.flags == rhs.flags && lhs.cpuLoad == rhs.cpuLoad &&
- lhs.memoryUsage == rhs.memoryUsage &&
- memcmp(lhs.name.data(), rhs.name.data(), lhs.name.size()) == 0 &&
- memcmp(lhs.implementor.data(), rhs.implementor.data(),
- lhs.implementor.size()) == 0;
-}
-
-} // namespace V2_0
-} // namespace effect
-} // namespace audio
-} // namespace hardware
-} // namespace android
-
TEST_F(AudioEffectHidlTest, GetDescriptor) {
hidl_vec<EffectDescriptor> allDescriptors;
Return<void> ret = effectsFactory->getAllDescriptors(
diff --git a/boot/1.0/vts/functional/vts/testcases/hal/boot/hidl/target/AndroidTest.xml b/boot/1.0/vts/functional/vts/testcases/hal/boot/hidl/target/AndroidTest.xml
index 6c7809c..bc759bf 100644
--- a/boot/1.0/vts/functional/vts/testcases/hal/boot/hidl/target/AndroidTest.xml
+++ b/boot/1.0/vts/functional/vts/testcases/hal/boot/hidl/target/AndroidTest.xml
@@ -24,6 +24,7 @@
_32bit::DATA/nativetest/boot_hidl_hal_test/boot_hidl_hal_test,
_64bit::DATA/nativetest64/boot_hidl_hal_test/boot_hidl_hal_test,
"/>
+ <option name="test-config-path" value="vts/testcases/hal/boot/hidl/target/HalBootHidlTargetTest.config" />
<option name="binary-test-type" value="gtest" />
<option name="test-timeout" value="1m" />
</test>
diff --git a/boot/1.0/vts/functional/vts/testcases/hal/boot/hidl/target/HalBootHidlTargetTest.config b/boot/1.0/vts/functional/vts/testcases/hal/boot/hidl/target/HalBootHidlTargetTest.config
new file mode 100644
index 0000000..ebb4d1b
--- /dev/null
+++ b/boot/1.0/vts/functional/vts/testcases/hal/boot/hidl/target/HalBootHidlTargetTest.config
@@ -0,0 +1,20 @@
+{
+ "use_gae_db": true,
+ "coverage": true,
+ "modules": [
+ {
+ "module_name": "system/lib64/hw/bootctrl.msm8996",
+ "git_project": {
+ "name": "platform/hardware/qcom/bootctrl",
+ "path": "hardware/qcom/bootctrl"
+ }
+ },
+ {
+ "module_name": "system/lib64/hw/android.hardware.boot@1.0-impl",
+ "git_project": {
+ "name": "platform/hardware/interfaces",
+ "path": "hardware/interfaces"
+ }
+ }
+ ]
+}
diff --git a/camera/device/3.2/types.hal b/camera/device/3.2/types.hal
index 3ce5037..ed6ef7d 100644
--- a/camera/device/3.2/types.hal
+++ b/camera/device/3.2/types.hal
@@ -20,6 +20,9 @@
import android.hardware.graphics.common@1.0::types;
typedef vec<uint8_t> CameraMetadata;
+typedef bitfield<ProducerUsage> ProducerUsageFlags;
+typedef bitfield<ConsumerUsage> ConsumerUsageFlags;
+typedef bitfield<Dataspace> DataspaceFlags;
/**
* StreamType:
@@ -221,24 +224,12 @@
* together and then passed to the platform gralloc HAL module for
* allocating the gralloc buffers for each stream.
*
- * For streamType OUTPUT, when passed via
- * configureStreams(), the initial value of this is the consumer's usage
- * flags. The HAL may use these consumer flags to decide stream
- * configuration. For streamType INPUT, when passed via
- * configureStreams(), the initial value of this is 0. For all streams
- * passed via configureStreams(), the HAL must set its desired producer
- * usage flags in the final stream configuration.
+ * The HAL may use these consumer flags to decide stream configuration. For
+ * streamType INPUT, the value of this field is always 0. For all streams
+ * passed via configureStreams(), the HAL must set its own
+ * additional usage flags in its output HalStreamConfiguration.
*/
- ConsumerUsage usage;
-
- /**
- * The maximum number of buffers the HAL device may need to have dequeued at
- * the same time. The HAL device may not have more buffers in-flight from
- * this stream than this value. For all streams passed via
- * configureStreams(), the HAL must set its desired max buffer count in the
- * final stream configuration.
- */
- uint32_t maxBuffers;
+ ConsumerUsageFlags usage;
/**
* A field that describes the contents of the buffer. The format and buffer
@@ -256,7 +247,7 @@
* supported. The dataspace values are set using the V0 dataspace
* definitions.
*/
- Dataspace dataSpace;
+ DataspaceFlags dataSpace;
/**
* The required output rotation of the stream.
@@ -328,18 +319,18 @@
int32_t id;
/**
- * The pixel format for the buffers in this stream.
- *
- * If HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED is used, then the platform
- * gralloc module must select a format based on the usage flags provided by
- * the camera device and the other endpoint of the stream.
+ * An override pixel format for the buffers in this stream.
*
* The HAL must respect the requested format in Stream unless it is
* IMPLEMENTATION_DEFINED, in which case the override format here must be
- * used instead. This allows cross-platform HALs to use a standard format
- * since IMPLEMENTATION_DEFINED formats often require device-specific
- * information. In all other cases, the overrideFormat must match the
- * requested format.
+ * used by the client instead, for this stream. This allows cross-platform
+ * HALs to use a standard format since IMPLEMENTATION_DEFINED formats often
+ * require device-specific information. In all other cases, the
+ * overrideFormat must match the requested format.
+ *
+ * When HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED is used, then the platform
+ * gralloc module must select a format based on the usage flags provided by
+ * the camera device and the other endpoint of the stream.
*/
android.hardware.graphics.common@1.0::PixelFormat overrideFormat;
@@ -356,8 +347,8 @@
* consumerUsage must be set. For other types, producerUsage must be set,
* and consumerUsage must be 0.
*/
- ProducerUsage producerUsage;
- ConsumerUsage consumerUsage;
+ ProducerUsageFlags producerUsage;
+ ConsumerUsageFlags consumerUsage;
/**
* The maximum number of buffers the HAL device may need to have dequeued at
@@ -635,7 +626,7 @@
* Shutter message contents. Valid if type is MsgType::SHUTTER
*/
ShutterMsg shutter;
- };
+ } msg;
};
diff --git a/contexthub/1.0/IContexthub.hal b/contexthub/1.0/IContexthub.hal
index 8d19aeb..8c792fd 100644
--- a/contexthub/1.0/IContexthub.hal
+++ b/contexthub/1.0/IContexthub.hal
@@ -60,9 +60,11 @@
* After the init method for nanoApp returns success, this must be indicated
* to the service by an asynchronous call to handleTxnResult.
*
+ * Loading a nanoapp must not take more than 30 seconds.
+ *
* @param hubId identifer of the contextHub
- * appBinary binary for the nanoApp
- * msg message to be sent
+ * appBinary serialized NanoApppBinary for the nanoApp
+ * transactionId transactionId for this call
*
* @return result OK if transation started
* BAD_VALUE if parameters are not sane
@@ -71,7 +73,9 @@
* TRANSACTION_FAILED if load failed synchronously
*
*/
- loadNanoApp(uint32_t hubId, NanoAppBinary appBinary, uint32_t transactionId)
+ loadNanoApp(uint32_t hubId,
+ vec<uint8_t> appBinary,
+ uint32_t transactionId)
generates (Result result);
/**
@@ -79,6 +83,8 @@
* After this, success must be indicated to the service through an
* asynchronous call to handleTxnResult.
*
+ * Unloading a nanoapp must not take more than 5 seconds.
+ *
* @param hubId identifer of the contextHub
* appId appIdentifier returned by the HAL
* msg message to be sent
@@ -98,6 +104,8 @@
* After this, success must be indicated to the service through an
* asynchronous message.
*
+ * Enabling a nanoapp must not take more than 5 seconds.
+ *
* @param hubId identifer of the contextHub
* appId appIdentifier returned by the HAL
* msg message to be sent
@@ -117,6 +125,8 @@
* After this, success must be indicated to the service through an
* asynchronous message.
*
+ * Disabling a nanoapp must not take more than 5 seconds.
+ *
* @param hubId identifer of the contextHub
* appId appIdentifier returned by the HAL
* msg message to be sent
@@ -136,7 +146,11 @@
*
* @param hubId identifer of the contextHub
*
- * @return apps all nanoApps on the hub
+ * @return apps all nanoApps on the hub.
+ * All nanoApps that can be modified by the service must
+ * be returned. A non-modifiable nanoapps must not be
+ * returned. A modifiable nanoApp is one that can be
+ * unloaded/disabled/enabled by the service.
*
*/
queryApps(uint32_t hubId) generates (Result result);
diff --git a/contexthub/1.0/IContexthubCallback.hal b/contexthub/1.0/IContexthubCallback.hal
index 29c41ce..9e9cf27 100644
--- a/contexthub/1.0/IContexthubCallback.hal
+++ b/contexthub/1.0/IContexthubCallback.hal
@@ -22,41 +22,44 @@
* implementation to allow the HAL to send asynchronous messages back
* to the service and registered clients of the ContextHub service.
*
- * @params hubId : identifier of the hub calling callback
- * msg : message
+ * @params msg : message
*
*/
- handleClientMsg(uint32_t hubId, ContextHubMsg msg);
+ handleClientMsg(ContextHubMsg msg);
/*
* This callback is passed by the Contexthub service to the HAL
* implementation to allow the HAL to send the response for a
* transaction.
*
- * @params hubId : identifier of the hub calling callback
- * txnId : transaction id whose result is being sent
+ * @params txnId : transaction id whose result is being sent
* passed in by the service at start of transacation.
* result: result of transaction.
*
*/
- handleTxnResult(uint32_t hubId, uint32_t txnId,
- TransactionResult result);
+ handleTxnResult(uint32_t txnId, TransactionResult result);
/*
* This callback is passed by the Contexthub service to the HAL
* implementation to allow the HAL to send an asynchronous event
* to the ContextHub service.
*
- * @params hubId : identifier of the hub calling callback
- * msg : message
+ * @params msg : message
*
*/
- handleHubEvent(uint32_t hubId, AsyncEventType evt);
+ handleHubEvent(AsyncEventType evt);
/*
* This callback is passed by the Contexthub service to the HAL
* implementation to allow the HAL to send information about the
* currently loaded and active nanoapps on the hub.
+ *
+ * @params appInfo : vector of HubAppinfo structure for each nanoApp
+ * on the hub that can be enabled, disabled and
+ * unloaded by the service. Any nanoApps that cannot
+ * be controlled by the service must not be reported.
+ * All nanoApps that can be controlled by the service
+ * must be reported.
*/
- handleAppsInfo(uint32_t hubId, vec<HubAppInfo> appInfo);
+ handleAppsInfo(vec<HubAppInfo> appInfo);
};
diff --git a/contexthub/1.0/default/Android.bp b/contexthub/1.0/default/Android.bp
new file mode 100644
index 0000000..7c5f79d
--- /dev/null
+++ b/contexthub/1.0/default/Android.bp
@@ -0,0 +1,33 @@
+/*
+ * 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.contexthub@1.0-impl",
+ relative_install_path: "hw",
+ srcs: ["Contexthub.cpp"],
+ shared_libs: [
+ "liblog",
+ "libcutils",
+ "libhardware",
+ "libhwbinder",
+ "libbase",
+ "libcutils",
+ "libutils",
+ "libhidlbase",
+ "libhidltransport",
+ "android.hardware.contexthub@1.0",
+ ],
+}
diff --git a/contexthub/1.0/default/Android.mk b/contexthub/1.0/default/Android.mk
new file mode 100644
index 0000000..ad40878
--- /dev/null
+++ b/contexthub/1.0/default/Android.mk
@@ -0,0 +1,23 @@
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_MODULE := android.hardware.contexthub@1.0-service
+LOCAL_INIT_RC := android.hardware.contexthub@1.0-service.rc
+LOCAL_SRC_FILES := \
+ service.cpp \
+
+LOCAL_SHARED_LIBRARIES := \
+ libbase \
+ libcutils \
+ libdl \
+ libhardware \
+ libhardware_legacy \
+ libhidlbase \
+ libhidltransport \
+ libhwbinder \
+ liblog \
+ libutils \
+ android.hardware.contexthub@1.0 \
+
+include $(BUILD_EXECUTABLE)
diff --git a/contexthub/1.0/default/Contexthub.cpp b/contexthub/1.0/default/Contexthub.cpp
new file mode 100644
index 0000000..d530a87
--- /dev/null
+++ b/contexthub/1.0/default/Contexthub.cpp
@@ -0,0 +1,528 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "Contexthub.h"
+
+#include <inttypes.h>
+
+#include <android/log.h>
+#include <android/hardware/contexthub/1.0/IContexthub.h>
+#include <hardware/context_hub.h>
+
+#undef LOG_TAG
+#define LOG_TAG "ContextHubHalAdapter"
+
+namespace android {
+namespace hardware {
+namespace contexthub {
+namespace V1_0 {
+namespace implementation {
+
+static constexpr uint64_t ALL_APPS = UINT64_C(0xFFFFFFFFFFFFFFFF);
+
+Contexthub::Contexthub()
+ : mInitCheck(NO_INIT),
+ mContextHubModule(nullptr),
+ mIsTransactionPending(false) {
+ const hw_module_t *module;
+
+ mInitCheck = hw_get_module(CONTEXT_HUB_MODULE_ID, &module);
+
+ if (mInitCheck != OK) {
+ ALOGE("Could not load %s module: %s", CONTEXT_HUB_MODULE_ID, strerror(-mInitCheck));
+ } else if (module == nullptr) {
+ ALOGE("hal returned succes but a null module!");
+ // Assign an error, this should not really happen...
+ mInitCheck = UNKNOWN_ERROR;
+ } else {
+ ALOGI("Loaded Context Hub module");
+ mContextHubModule = reinterpret_cast<const context_hub_module_t *>(module);
+ }
+}
+
+bool Contexthub::setOsAppAsDestination(hub_message_t *msg, int hubId) {
+ if (!isValidHubId(hubId)) {
+ ALOGW("%s: Hub information is null for hubHandle %d",
+ __FUNCTION__,
+ hubId);
+ return false;
+ } else {
+ msg->app_name = mCachedHubInfo[hubId].osAppName;
+ return true;
+ }
+}
+
+Return<void> Contexthub::getHubs(getHubs_cb _hidl_cb) {
+ std::vector<ContextHub> hubs;
+ if (isInitialized()) {
+ const context_hub_t *hubArray = nullptr;
+ size_t numHubs;
+
+ // Explicitly discarding const. HAL method discards it.
+ numHubs = mContextHubModule->get_hubs(const_cast<context_hub_module_t *>(mContextHubModule),
+ &hubArray);
+ ALOGI("Context Hub Hal Adapter reports %zu hubs", numHubs);
+
+ mCachedHubInfo.clear();
+
+ for (size_t i = 0; i < numHubs; i++) {
+ CachedHubInformation info;
+ ContextHub c;
+
+ c.hubId = hubArray[i].hub_id;
+ c.name = hubArray[i].name;
+ c.vendor = hubArray[i].vendor;
+ c.toolchain = hubArray[i].toolchain;
+ c.toolchainVersion = hubArray[i].toolchain_version;
+ c.platformVersion = hubArray[i].platform_version;
+ c.maxSupportedMsgLen = hubArray[i].max_supported_msg_len;
+ c.peakMips = hubArray[i].peak_mips;
+ c.peakPowerDrawMw = hubArray[i].peak_power_draw_mw;
+ c.stoppedPowerDrawMw = hubArray[i].stopped_power_draw_mw;
+ c.sleepPowerDrawMw = hubArray[i].sleep_power_draw_mw;
+
+ info.callBack = nullptr;
+ info.osAppName = hubArray[i].os_app_name;
+ mCachedHubInfo[hubArray[i].hub_id] = info;
+
+ hubs.push_back(c);
+ }
+ } else {
+ ALOGW("Context Hub Hal Adapter not initialized");
+ }
+
+ _hidl_cb(hubs);
+ return Void();
+}
+
+bool Contexthub::isValidHubId(uint32_t hubId) {
+ if (!mCachedHubInfo.count(hubId)) {
+ ALOGW("Hub information not found for hubId %" PRIu32, hubId);
+ return false;
+ } else {
+ return true;
+ }
+}
+
+sp<IContexthubCallback> Contexthub::getCallBackForHubId(uint32_t hubId) {
+ if (!isValidHubId(hubId)) {
+ return nullptr;
+ } else {
+ return mCachedHubInfo[hubId].callBack;
+ }
+}
+
+Return<Result> Contexthub::sendMessageToHub(uint32_t hubId,
+ const ContextHubMsg &msg) {
+ if (!isInitialized()) {
+ return Result::NOT_INIT;
+ }
+
+ if (!isValidHubId(hubId) || msg.msg.size() > UINT32_MAX) {
+ return Result::BAD_PARAMS;
+ }
+
+ hub_message_t txMsg = {
+ .app_name.id = msg.appName,
+ .message_type = msg.msgType,
+ .message_len = static_cast<uint32_t>(msg.msg.size()), // Note the check above
+ .message = static_cast<const uint8_t *>(msg.msg.data()),
+ };
+
+ ALOGI("Sending msg of type %" PRIu32 ", size %" PRIu32 " to app 0x%" PRIx64,
+ txMsg.message_type,
+ txMsg.message_len,
+ txMsg.app_name.id);
+
+ if(mContextHubModule->send_message(hubId, &txMsg) != 0) {
+ return Result::TRANSACTION_FAILED;
+ }
+
+ return Result::OK;
+}
+
+Return<Result> Contexthub::reboot(uint32_t hubId) {
+ if (!isInitialized()) {
+ return Result::NOT_INIT;
+ }
+
+ hub_message_t msg;
+
+ if (setOsAppAsDestination(&msg, hubId) == false) {
+ return Result::BAD_PARAMS;
+ }
+
+ msg.message_type = CONTEXT_HUB_OS_REBOOT;
+ msg.message_len = 0;
+ msg.message = nullptr;
+
+ if(mContextHubModule->send_message(hubId, &msg) != 0) {
+ return Result::TRANSACTION_FAILED;
+ } else {
+ return Result::OK;
+ }
+}
+
+Return<Result> Contexthub::registerCallback(uint32_t hubId,
+ const sp<IContexthubCallback> &cb) {
+ Return<Result> retVal = Result::BAD_PARAMS;
+
+ if (!isInitialized()) {
+ // Not initilalized
+ ALOGW("Context hub not initialized successfully");
+ retVal = Result::NOT_INIT;
+ } else if (!isValidHubId(hubId)) {
+ // Initialized, but hubId is not valid
+ retVal = Result::BAD_PARAMS;
+ } else if (mContextHubModule->subscribe_messages(hubId,
+ contextHubCb,
+ this) == 0) {
+ // Initialized && valid hub && subscription successful
+ retVal = Result::OK;
+ mCachedHubInfo[hubId].callBack = cb;
+ } else {
+ // Initalized && valid hubId - but subscription unsuccessful
+ // This is likely an internal error in the HAL implementation, but we
+ // cannot add more information.
+ ALOGW("Could not subscribe to the hub for callback");
+ retVal = Result::UNKNOWN_FAILURE;
+ }
+
+ return retVal;
+}
+
+static bool isValidOsStatus(const uint8_t *msg,
+ size_t msgLen,
+ status_response_t *rsp) {
+ // Workaround a bug in some HALs
+ if (msgLen == 1) {
+ rsp->result = msg[0];
+ return true;
+ }
+
+ if (msg == nullptr || msgLen != sizeof(*rsp)) {
+ ALOGI("Received invalid response (is null : %d, size %zu)",
+ msg == nullptr ? 1 : 0,
+ msgLen);
+ return false;
+ }
+
+ memcpy(rsp, msg, sizeof(*rsp));
+
+ // No sanity checks on return values
+ return true;
+}
+
+int Contexthub::handleOsMessage(sp<IContexthubCallback> cb,
+ uint32_t msgType,
+ const uint8_t *msg,
+ int msgLen) {
+ int retVal = -1;
+
+
+ switch(msgType) {
+ case CONTEXT_HUB_APPS_ENABLE:
+ case CONTEXT_HUB_APPS_DISABLE:
+ case CONTEXT_HUB_LOAD_APP:
+ case CONTEXT_HUB_UNLOAD_APP:
+ {
+ struct status_response_t rsp;
+ TransactionResult result;
+ if (isValidOsStatus(msg, msgLen, &rsp) && rsp.result == 0) {
+ retVal = 0;
+ result = TransactionResult::SUCCESS;
+ } else {
+ result = TransactionResult::FAILURE;
+ }
+
+ if (cb != nullptr) {
+ cb->handleTxnResult(mTransactionId, result);
+ }
+ retVal = 0;
+ mIsTransactionPending = false;
+ break;
+ }
+
+ case CONTEXT_HUB_QUERY_APPS:
+ {
+ std::vector<HubAppInfo> apps;
+ int numApps = msgLen / sizeof(hub_app_info);
+ const hub_app_info *unalignedInfoAddr = reinterpret_cast<const hub_app_info *>(msg);
+
+ for (int i = 0; i < numApps; i++) {
+ hub_app_info query_info;
+ memcpy(&query_info, &unalignedInfoAddr[i], sizeof(query_info));
+ HubAppInfo app;
+ app.appId = query_info.app_name.id;
+ app.version = query_info.version;
+ // TODO :: Add memory ranges
+
+ apps.push_back(app);
+ }
+
+ if (cb != nullptr) {
+ cb->handleAppsInfo(apps);
+ }
+ retVal = 0;
+ break;
+ }
+
+ case CONTEXT_HUB_QUERY_MEMORY:
+ {
+ // Deferring this use
+ retVal = 0;
+ break;
+ }
+
+ case CONTEXT_HUB_OS_REBOOT:
+ {
+ mIsTransactionPending = false;
+ if (cb != nullptr) {
+ cb->handleHubEvent(AsyncEventType::RESTARTED);
+ }
+ retVal = 0;
+ break;
+ }
+
+ default:
+ {
+ retVal = -1;
+ break;
+ }
+ }
+
+ return retVal;
+}
+
+int Contexthub::contextHubCb(uint32_t hubId,
+ const struct hub_message_t *rxMsg,
+ void *cookie) {
+ Contexthub *obj = static_cast<Contexthub *>(cookie);
+
+ if (rxMsg == nullptr) {
+ ALOGW("Ignoring NULL message");
+ return -1;
+ }
+
+ if (!obj->isValidHubId(hubId)) {
+ ALOGW("Invalid hub Id %" PRIu32, hubId);
+ return -1;
+ }
+
+ sp<IContexthubCallback> cb = obj->getCallBackForHubId(hubId);
+
+ if (cb == nullptr) {
+ // This should not ever happen
+ ALOGW("No callback registered, returning");
+ return -1;
+ }
+
+ if (rxMsg->message_type < CONTEXT_HUB_TYPE_PRIVATE_MSG_BASE) {
+ obj->handleOsMessage(cb,
+ rxMsg->message_type,
+ static_cast<const uint8_t *>(rxMsg->message),
+ rxMsg->message_len);
+ } else {
+ ContextHubMsg msg;
+
+ msg.appName = rxMsg->app_name.id;
+ msg.msgType = rxMsg->message_type;
+ msg.msg = std::vector<uint8_t>(static_cast<const uint8_t *>(rxMsg->message),
+ static_cast<const uint8_t *>(rxMsg->message) +
+ rxMsg->message_len);
+
+ cb->handleClientMsg(msg);
+ }
+
+ return 0;
+}
+
+Return<Result> Contexthub::unloadNanoApp(uint32_t hubId,
+ uint64_t appId,
+ uint32_t transactionId) {
+ if (!isInitialized()) {
+ return Result::NOT_INIT;
+ }
+
+ if (mIsTransactionPending) {
+ return Result::TRANSACTION_PENDING;
+ }
+
+ hub_message_t msg;
+
+ if (setOsAppAsDestination(&msg, hubId) == false) {
+ return Result::BAD_PARAMS;
+ }
+
+ struct apps_disable_request_t req;
+
+ msg.message_type = CONTEXT_HUB_UNLOAD_APP;
+ msg.message_len = sizeof(req);
+ msg.message = &req;
+ req.app_name.id = appId;
+
+ if(mContextHubModule->send_message(hubId, &msg) != 0) {
+ return Result::TRANSACTION_FAILED;
+ } else {
+ mTransactionId = transactionId;
+ mIsTransactionPending = true;
+ return Result::OK;
+ }
+}
+
+Return<Result> Contexthub::loadNanoApp(uint32_t hubId,
+ const ::android::hardware::hidl_vec<uint8_t>& appBinary,
+ uint32_t transactionId) {
+ if (!isInitialized()) {
+ return Result::NOT_INIT;
+ }
+
+ if (mIsTransactionPending) {
+ return Result::TRANSACTION_PENDING;
+ }
+
+ hub_message_t hubMsg;
+
+ if (setOsAppAsDestination(&hubMsg, hubId) == false) {
+ return Result::BAD_PARAMS;
+ }
+
+ hubMsg.message_type = CONTEXT_HUB_LOAD_APP;
+ hubMsg.message_len = appBinary.size();
+ hubMsg.message = appBinary.data();
+
+ if(mContextHubModule->send_message(hubId, &hubMsg) != 0) {
+ return Result::TRANSACTION_FAILED;
+ } else {
+ mTransactionId = transactionId;
+ mIsTransactionPending = true;
+ return Result::OK;
+ }
+}
+
+Return<Result> Contexthub::enableNanoApp(uint32_t hubId,
+ uint64_t appId,
+ uint32_t transactionId) {
+ if (!isInitialized()) {
+ return Result::NOT_INIT;
+ }
+
+ if (mIsTransactionPending) {
+ return Result::TRANSACTION_PENDING;
+ }
+
+ hub_message_t msg;
+
+ if (setOsAppAsDestination(&msg, hubId) == false) {
+ return Result::BAD_PARAMS;
+ }
+
+ struct apps_enable_request_t req;
+
+ msg.message_type = CONTEXT_HUB_APPS_ENABLE;
+ msg.message_len = sizeof(req);
+ req.app_name.id = appId;
+ msg.message = &req;
+
+ if(mContextHubModule->send_message(hubId, &msg) != 0) {
+ return Result::TRANSACTION_FAILED;
+ } else {
+ mTransactionId = transactionId;
+ mIsTransactionPending = true;
+ return Result::OK;
+ }
+}
+
+Return<Result> Contexthub::disableNanoApp(uint32_t hubId,
+ uint64_t appId,
+ uint32_t transactionId) {
+ if (!isInitialized()) {
+ return Result::NOT_INIT;
+ }
+
+ if (mIsTransactionPending) {
+ return Result::TRANSACTION_PENDING;
+ }
+
+ hub_message_t msg;
+
+ if (setOsAppAsDestination(&msg, hubId) == false) {
+ return Result::BAD_PARAMS;
+ }
+
+ struct apps_disable_request_t req;
+
+ msg.message_type = CONTEXT_HUB_APPS_DISABLE;
+ msg.message_len = sizeof(req);
+ req.app_name.id = appId;
+ msg.message = &req;
+
+ if(mContextHubModule->send_message(hubId, &msg) != 0) {
+ return Result::TRANSACTION_FAILED;
+ } else {
+ mTransactionId = transactionId;
+ mIsTransactionPending = true;
+ return Result::OK;
+ }
+}
+
+Return<Result> Contexthub::queryApps(uint32_t hubId) {
+ if (!isInitialized()) {
+ return Result::NOT_INIT;
+ }
+
+ hub_message_t msg;
+
+ if (setOsAppAsDestination(&msg, hubId) == false) {
+ ALOGW("Could not find hubId %" PRIu32, hubId);
+ return Result::BAD_PARAMS;
+ }
+
+ query_apps_request_t payload;
+ payload.app_name.id = ALL_APPS; // TODO : Pass this in as a parameter
+ msg.message = &payload;
+ msg.message_len = sizeof(payload);
+ msg.message_type = CONTEXT_HUB_QUERY_APPS;
+
+ if(mContextHubModule->send_message(hubId, &msg) != 0) {
+ ALOGW("Query Apps sendMessage failed");
+ return Result::TRANSACTION_FAILED;
+ }
+
+ return Result::OK;
+}
+
+bool Contexthub::isInitialized() {
+ return (mInitCheck == OK && mContextHubModule != nullptr);
+}
+
+IContexthub *HIDL_FETCH_IContexthub(const char * halName) {
+ ALOGI("%s Called for %s", __FUNCTION__, halName);
+ Contexthub *contexthub = new Contexthub;
+
+ if (!contexthub->isInitialized()) {
+ delete contexthub;
+ contexthub = nullptr;
+ }
+
+ return contexthub;
+}
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace contexthub
+} // namespace hardware
+} // namespace android
diff --git a/contexthub/1.0/default/Contexthub.h b/contexthub/1.0/default/Contexthub.h
new file mode 100644
index 0000000..0883ce8
--- /dev/null
+++ b/contexthub/1.0/default/Contexthub.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_CONTEXTHUB_V1_0_CONTEXTHUB_H_
+#define ANDROID_HARDWARE_CONTEXTHUB_V1_0_CONTEXTHUB_H_
+
+#include <unordered_map>
+
+#include <android/hardware/contexthub/1.0/IContexthub.h>
+#include <hardware/context_hub.h>
+
+namespace android {
+namespace hardware {
+namespace contexthub {
+namespace V1_0 {
+namespace implementation {
+
+struct Contexthub : public ::android::hardware::contexthub::V1_0::IContexthub {
+ Contexthub();
+
+ Return<void> getHubs(getHubs_cb _hidl_cb) override;
+
+ Return<Result> registerCallback(uint32_t hubId,
+ const sp<IContexthubCallback> &cb) override;
+
+ Return<Result> sendMessageToHub(uint32_t hubId,
+ const ContextHubMsg &msg) override;
+
+ Return<Result> loadNanoApp(uint32_t hubId,
+ const ::android::hardware::hidl_vec<uint8_t>& appBinary,
+ uint32_t transactionId) override;
+
+ Return<Result> unloadNanoApp(uint32_t hubId,
+ uint64_t appId,
+ uint32_t transactionId) override;
+
+ Return<Result> enableNanoApp(uint32_t hubId,
+ uint64_t appId,
+ uint32_t transactionId) override;
+
+ Return<Result> disableNanoApp(uint32_t hubId,
+ uint64_t appId,
+ uint32_t transactionId) override;
+
+ Return<Result> queryApps(uint32_t hubId) override;
+
+ Return<Result> reboot(uint32_t hubId);
+
+ bool isInitialized();
+
+private:
+
+ struct CachedHubInformation{
+ struct hub_app_name_t osAppName;
+ sp<IContexthubCallback> callBack;
+ };
+
+ status_t mInitCheck;
+ const struct context_hub_module_t *mContextHubModule;
+ std::unordered_map<uint32_t, CachedHubInformation> mCachedHubInfo;
+
+ sp<IContexthubCallback> mCb;
+ bool mIsTransactionPending;
+ uint32_t mTransactionId;
+
+ bool isValidHubId(uint32_t hubId);
+
+ sp<IContexthubCallback> getCallBackForHubId(uint32_t hubId);
+
+ int handleOsMessage(sp<IContexthubCallback> cb,
+ uint32_t msgType,
+ const uint8_t *msg,
+ int msgLen);
+
+ static int contextHubCb(uint32_t hubId,
+ const struct hub_message_t *rxMsg,
+ void *cookie);
+
+ bool setOsAppAsDestination(hub_message_t *msg, int hubId);
+
+ DISALLOW_COPY_AND_ASSIGN(Contexthub);
+};
+
+extern "C" IContexthub *HIDL_FETCH_IContexthub(const char *name);
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace contexthub
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_CONTEXTHUB_V1_0_CONTEXTHUB_H_
diff --git a/contexthub/1.0/default/android.hardware.contexthub@1.0-service.rc b/contexthub/1.0/default/android.hardware.contexthub@1.0-service.rc
new file mode 100644
index 0000000..8dba85f
--- /dev/null
+++ b/contexthub/1.0/default/android.hardware.contexthub@1.0-service.rc
@@ -0,0 +1,4 @@
+service contexthub-hal-1-0 /system/bin/hw/android.hardware.contexthub@1.0-service
+ class hal
+ user system
+ group system
diff --git a/contexthub/1.0/default/service.cpp b/contexthub/1.0/default/service.cpp
new file mode 100644
index 0000000..db9a4e7
--- /dev/null
+++ b/contexthub/1.0/default/service.cpp
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "android.hardware.contexthub@1.0-service"
+
+#include <android/hardware/contexthub/1.0/IContexthub.h>
+#include <hidl/LegacySupport.h>
+
+using android::hardware::contexthub::V1_0::IContexthub;
+using android::hardware::defaultPassthroughServiceImplementation;
+
+int main() {
+ return defaultPassthroughServiceImplementation<IContexthub>("context_hub");
+}
diff --git a/contexthub/1.0/types.hal b/contexthub/1.0/types.hal
index b9f014b..043bb39 100644
--- a/contexthub/1.0/types.hal
+++ b/contexthub/1.0/types.hal
@@ -18,6 +18,7 @@
enum Result : uint32_t {
OK, // Success
+ UNKNOWN_FAILURE, // Failure, unknown reason
BAD_PARAMS, // Parameters not sane
NOT_INIT, // not initialized
TRANSACTION_FAILED, // transaction failed
diff --git a/contexthub/Android.bp b/contexthub/Android.bp
index bbb3e4b..ba90f2c 100644
--- a/contexthub/Android.bp
+++ b/contexthub/Android.bp
@@ -1,4 +1,5 @@
// This is an autogenerated file, do not edit.
subdirs = [
"1.0",
+ "1.0/default",
]
diff --git a/drm/crypto/1.0/ICryptoFactory.hal b/drm/crypto/1.0/ICryptoFactory.hal
index 58f86df..0ac7828 100644
--- a/drm/crypto/1.0/ICryptoFactory.hal
+++ b/drm/crypto/1.0/ICryptoFactory.hal
@@ -25,7 +25,7 @@
* which are used by a codec to decrypt protected video content.
*/
interface ICryptoFactory {
- /*
+ /**
* Determine if a crypto scheme is supported by this HAL
*
* @param uuid identifies the crypto scheme in question
@@ -33,23 +33,17 @@
*/
isCryptoSchemeSupported(uint8_t[16] uuid) generates(bool isSupported);
- /*
+ /**
* Create a crypto plugin for the specified uuid and scheme-specific
* initialization data.
*
* @param uuid uniquely identifies the drm scheme. See
* http://dashif.org/identifiers/protection for uuid assignments
* @param initData scheme-specific init data.
- * @return the status of the call
- * @return the created ICryptoPlugin
- */
+ * @return status the status of the call. If the plugin can't
+ * be created, the HAL implementation must return ERROR_DRM_CANNOT_HANDLE.
+ * @return cryptoPlugin the created ICryptoPlugin
+ */
createPlugin(uint8_t[16] uuid, vec<uint8_t> initData)
generates (Status status, ICryptoPlugin cryptoPlugin);
-
- /*
- * Destroy a previously created crypto plugin
- *
- * @return status the status of the call
- */
- destroyPlugin() generates(Status status);
};
diff --git a/drm/crypto/1.0/ICryptoPlugin.hal b/drm/crypto/1.0/ICryptoPlugin.hal
index 1255fdb..e86c9f2 100644
--- a/drm/crypto/1.0/ICryptoPlugin.hal
+++ b/drm/crypto/1.0/ICryptoPlugin.hal
@@ -25,7 +25,7 @@
* load crypto keys for a codec to decrypt protected video content.
*/
interface ICryptoPlugin {
- /*
+ /**
* Check if the specified mime-type requires a secure decoder
* component.
*
@@ -36,7 +36,7 @@
requiresSecureDecoderComponent(string mime)
generates(bool secureRequired);
- /*
+ /**
* Notify a plugin of the currently configured resolution
*
* @param width - the display resolutions's width
@@ -44,16 +44,19 @@
*/
notifyResolution(uint32_t width, uint32_t height);
- /*
+ /**
* Associate a mediadrm session with this crypto session
*
* @param sessionId the MediaDrm session ID to associate with this crypto
* session
- * @return the status of the call
+ * @return status the status of the call, status must be
+ * ERROR_DRM_SESSION_NOT_OPENED if the session is not opened, or
+ * ERROR_DRM_CANNOT_HANDLE if the operation is not supported by the drm
+ * scheme.
*/
setMediaDrmSession(vec<uint8_t> sessionId) generates(Status status);
- /*
+ /**
* Decrypt an array of subsamples from the source memory buffer to the
* destination memory buffer.
*
@@ -71,7 +74,14 @@
* call to operate on a range of subsamples in a single call
* @param source the input buffer for the decryption
* @param destination the output buffer for the decryption
- * @return status the status of the call
+ * @return status the status of the call. The status must be one of
+ * the following: ERROR_DRM_NO_LICENSE if no license keys have been
+ * loaded, ERROR_DRM_LICENSE_EXPIRED if the license keys have expired,
+ * ERROR_DRM_RESOURCE_BUSY if the resources required to perform the
+ * decryption are not available, ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION
+ * if required output protections are not active,
+ * ERROR_DRM_SESSION_NOT_OPENED if the decrypt session is not opened, or
+ * ERROR_DRM_CANNOT_HANDLE in other failure cases.
* @return bytesWritten the number of bytes output from the decryption
* @return detailedError if the error is a vendor-specific error, the
* vendor's crypto HAL may provide a detailed error string to help
diff --git a/drm/crypto/1.0/default/Android.mk b/drm/crypto/1.0/default/Android.mk
new file mode 100644
index 0000000..83794ac
--- /dev/null
+++ b/drm/crypto/1.0/default/Android.mk
@@ -0,0 +1,41 @@
+# 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.drm.crypto@1.0-impl
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_SRC_FILES := \
+ CryptoFactory.cpp \
+ CryptoPlugin.cpp \
+ TypeConvert.cpp \
+
+LOCAL_SHARED_LIBRARIES := \
+ libhidlbase \
+ libhidltransport \
+ libhwbinder \
+ libhidlmemory \
+ libutils \
+ liblog \
+ libmediadrm \
+ libstagefright_foundation \
+ android.hardware.drm.crypto@1.0 \
+ android.hidl.memory@1.0
+
+LOCAL_C_INCLUDES := \
+ frameworks/native/include \
+ frameworks/av/include
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/drm/crypto/1.0/default/CryptoFactory.cpp b/drm/crypto/1.0/default/CryptoFactory.cpp
new file mode 100644
index 0000000..e67a990
--- /dev/null
+++ b/drm/crypto/1.0/default/CryptoFactory.cpp
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "CryptoFactory.h"
+#include "CryptoPlugin.h"
+#include "TypeConvert.h"
+#include <utils/Log.h>
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace crypto {
+namespace V1_0 {
+namespace implementation {
+
+ CryptoFactory::CryptoFactory() :
+ loader("/vendor/lib/mediadrm", "createCryptoFactory", "crypto") {}
+
+ // Methods from ::android::hardware::drm::crypto::V1_0::ICryptoFactory follow.
+ Return<bool> CryptoFactory::isCryptoSchemeSupported(
+ const hidl_array<uint8_t, 16>& uuid) {
+ for (size_t i = 0; i < loader.factoryCount(); i++) {
+ if (loader.getFactory(i)->isCryptoSchemeSupported(uuid.data())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ Return<void> CryptoFactory::createPlugin(const hidl_array<uint8_t, 16>& uuid,
+ const hidl_vec<uint8_t>& initData, createPlugin_cb _hidl_cb) {
+
+ for (size_t i = 0; i < loader.factoryCount(); i++) {
+ if (loader.getFactory(i)->isCryptoSchemeSupported(uuid.data())) {
+ android::CryptoPlugin *legacyPlugin = NULL;
+ status_t status = loader.getFactory(i)->createPlugin(uuid.data(),
+ initData.data(), initData.size(), &legacyPlugin);
+ CryptoPlugin *newPlugin = NULL;
+ if (legacyPlugin == NULL) {
+ ALOGE("Crypto legacy HAL: failed to create crypto plugin");
+ } else {
+ newPlugin = new CryptoPlugin(legacyPlugin);
+ }
+ _hidl_cb(toStatus(status), newPlugin);
+ return Void();
+ }
+ }
+ _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, NULL);
+ return Void();
+ }
+
+ ICryptoFactory* HIDL_FETCH_ICryptoFactory(const char /* *name */) {
+ return new CryptoFactory();
+ }
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace crypto
+} // namespace drm
+} // namespace hardware
+} // namespace android
diff --git a/drm/crypto/1.0/default/CryptoFactory.h b/drm/crypto/1.0/default/CryptoFactory.h
new file mode 100644
index 0000000..0855996
--- /dev/null
+++ b/drm/crypto/1.0/default/CryptoFactory.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef ANDROID_HARDWARE_DRM_CRYPTO_V1_0__CRYPTOFACTORY_H
+#define ANDROID_HARDWARE_DRM_CRYPTO_V1_0__CRYPTOFACTORY_H
+
+#include <android/hardware/drm/crypto/1.0/ICryptoFactory.h>
+#include <hidl/Status.h>
+#include <media/hardware/CryptoAPI.h>
+#include <media/PluginLoader.h>
+#include <media/SharedLibrary.h>
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace crypto {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::drm::crypto::V1_0::ICryptoFactory;
+using ::android::hardware::drm::crypto::V1_0::ICryptoPlugin;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+struct CryptoFactory : public ICryptoFactory {
+ CryptoFactory();
+ virtual ~CryptoFactory() {}
+
+ // Methods from ::android::hardware::drm::crypto::V1_0::ICryptoFactory follow.
+
+ Return<bool> isCryptoSchemeSupported(const hidl_array<uint8_t, 16>& uuid)
+ override;
+
+ Return<void> createPlugin(const hidl_array<uint8_t, 16>& uuid,
+ const hidl_vec<uint8_t>& initData, createPlugin_cb _hidl_cb)
+ override;
+
+private:
+ android::PluginLoader<android::CryptoFactory> loader;
+
+ CryptoFactory(const CryptoFactory &) = delete;
+ void operator=(const CryptoFactory &) = delete;
+};
+
+extern "C" ICryptoFactory* HIDL_FETCH_ICryptoFactory(const char* name);
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace crypto
+} // namespace drm
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_DRM_CRYPTO_V1_0__CRYPTOFACTORY_H
diff --git a/drm/crypto/1.0/default/CryptoPlugin.cpp b/drm/crypto/1.0/default/CryptoPlugin.cpp
new file mode 100644
index 0000000..9173d5b
--- /dev/null
+++ b/drm/crypto/1.0/default/CryptoPlugin.cpp
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "CryptoPlugin.h"
+#include "TypeConvert.h"
+
+#include <media/stagefright/foundation/AString.h>
+
+#include <hidlmemory/mapping.h>
+#include <android/hidl/memory/1.0/IMemory.h>
+
+using android::hidl::memory::V1_0::IMemory;
+
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace crypto {
+namespace V1_0 {
+namespace implementation {
+
+ // Methods from ::android::hardware::drm::crypto::V1_0::ICryptoPlugin follow
+ Return<bool> CryptoPlugin::requiresSecureDecoderComponent(
+ const hidl_string& mime) {
+ return mLegacyPlugin->requiresSecureDecoderComponent(mime);
+ }
+
+ Return<void> CryptoPlugin::notifyResolution(uint32_t width,
+ uint32_t height) {
+ mLegacyPlugin->notifyResolution(width, height);
+ return Void();
+ }
+
+ Return<Status> CryptoPlugin::setMediaDrmSession(
+ const hidl_vec<uint8_t>& sessionId) {
+ return toStatus(mLegacyPlugin->setMediaDrmSession(toVector(sessionId)));
+ }
+
+ Return<void> CryptoPlugin::decrypt(bool secure,
+ const hidl_array<uint8_t, 16>& keyId,
+ const hidl_array<uint8_t, 16>& iv, Mode mode,
+ const Pattern& pattern, const hidl_vec<SubSample>& subSamples,
+ const hidl_memory &source, const DestinationBuffer& destination,
+ decrypt_cb _hidl_cb) {
+
+ android::CryptoPlugin::Mode legacyMode;
+ switch(mode) {
+ case Mode::UNENCRYPTED:
+ legacyMode = android::CryptoPlugin::kMode_Unencrypted;
+ break;
+ case Mode::AES_CTR:
+ legacyMode = android::CryptoPlugin::kMode_AES_CTR;
+ break;
+ case Mode::AES_CBC_CTS:
+ legacyMode = android::CryptoPlugin::kMode_AES_WV;
+ break;
+ case Mode::AES_CBC:
+ legacyMode = android::CryptoPlugin::kMode_AES_CBC;
+ break;
+ }
+ android::CryptoPlugin::Pattern legacyPattern;
+ legacyPattern.mEncryptBlocks = pattern.encryptBlocks;
+ legacyPattern.mSkipBlocks = pattern.skipBlocks;
+
+ android::CryptoPlugin::SubSample *legacySubSamples =
+ new android::CryptoPlugin::SubSample[subSamples.size()];
+
+ for (size_t i = 0; i < subSamples.size(); i++) {
+ legacySubSamples[i].mNumBytesOfClearData
+ = subSamples[i].numBytesOfClearData;
+ legacySubSamples[i].mNumBytesOfEncryptedData
+ = subSamples[i].numBytesOfEncryptedData;
+ }
+
+ AString detailMessage;
+
+ void *destPtr = NULL;
+ sp<IMemory> sharedMemory;
+
+ if (destination.type == BufferType::SHARED_MEMORY) {
+ sharedMemory = mapMemory(source);
+ destPtr = sharedMemory->getPointer();
+ sharedMemory->update();
+ } else if (destination.type == BufferType::NATIVE_HANDLE) {
+ native_handle_t *handle = const_cast<native_handle_t *>(
+ destination.secureMemory.getNativeHandle());
+ destPtr = static_cast<void *>(handle);
+ }
+ ssize_t result = mLegacyPlugin->decrypt(secure, keyId.data(), iv.data(),
+ legacyMode, legacyPattern, sharedMemory->getPointer(),
+ legacySubSamples, subSamples.size(), destPtr, &detailMessage);
+
+ if (destination.type == BufferType::SHARED_MEMORY) {
+ sharedMemory->commit();
+ }
+ delete[] legacySubSamples;
+
+ uint32_t status;
+ uint32_t bytesWritten;
+
+ if (result >= 0) {
+ status = android::OK;
+ bytesWritten = result;
+ } else {
+ status = -result;
+ bytesWritten = 0;
+ }
+
+ _hidl_cb(toStatus(status), bytesWritten, detailMessage.c_str());
+ return Void();
+ }
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace crypto
+} // namespace drm
+} // namespace hardware
+} // namespace android
diff --git a/drm/crypto/1.0/default/CryptoPlugin.h b/drm/crypto/1.0/default/CryptoPlugin.h
new file mode 100644
index 0000000..b17dade
--- /dev/null
+++ b/drm/crypto/1.0/default/CryptoPlugin.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_DRM_CRYPTO_V1_0__CRYPTOPLUGIN_H
+#define ANDROID_HARDWARE_DRM_CRYPTO_V1_0__CRYPTOPLUGIN_H
+
+#include <media/hardware/CryptoAPI.h>
+#include <android/hardware/drm/crypto/1.0/ICryptoPlugin.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace crypto {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::drm::crypto::V1_0::DestinationBuffer;
+using ::android::hardware::drm::crypto::V1_0::ICryptoPlugin;
+using ::android::hardware::drm::crypto::V1_0::Mode;
+using ::android::hardware::drm::crypto::V1_0::Pattern;
+using ::android::hardware::drm::crypto::V1_0::SubSample;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+struct CryptoPlugin : public ICryptoPlugin {
+ CryptoPlugin(android::CryptoPlugin *plugin) : mLegacyPlugin(plugin) {}
+ ~CryptoPlugin() {delete mLegacyPlugin;}
+
+ // Methods from ::android::hardware::drm::crypto::V1_0::ICryptoPlugin
+ // follow.
+
+ Return<bool> requiresSecureDecoderComponent(const hidl_string& mime)
+ override;
+
+ Return<void> notifyResolution(uint32_t width, uint32_t height) override;
+
+ Return<Status> setMediaDrmSession(const hidl_vec<uint8_t>& sessionId)
+ override;
+
+ Return<void> decrypt(bool secure, const hidl_array<uint8_t, 16>& keyId,
+ const hidl_array<uint8_t, 16>& iv, Mode mode, const Pattern& pattern,
+ const hidl_vec<SubSample>& subSamples, const hidl_memory& source,
+ const DestinationBuffer& destination, decrypt_cb _hidl_cb) override;
+
+private:
+ android::CryptoPlugin *mLegacyPlugin;
+
+ CryptoPlugin() = delete;
+ CryptoPlugin(const CryptoPlugin &) = delete;
+ void operator=(const CryptoPlugin &) = delete;
+};
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace crypto
+} // namespace drm
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_DRM_CRYPTO_V1_0__CRYPTOPLUGIN_H
diff --git a/drm/crypto/1.0/default/TypeConvert.cpp b/drm/crypto/1.0/default/TypeConvert.cpp
new file mode 100644
index 0000000..d9cca6b
--- /dev/null
+++ b/drm/crypto/1.0/default/TypeConvert.cpp
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "TypeConvert.h"
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace crypto {
+namespace V1_0 {
+namespace implementation {
+
+Status toStatus(status_t legacyStatus) {
+ Status status;
+ switch(legacyStatus) {
+ case android::ERROR_DRM_NO_LICENSE:
+ status = Status::ERROR_DRM_NO_LICENSE;
+ break;
+ case android::ERROR_DRM_LICENSE_EXPIRED:
+ status = Status::ERROR_DRM_LICENSE_EXPIRED;
+ break;
+ case android::ERROR_DRM_RESOURCE_BUSY:
+ status = Status::ERROR_DRM_RESOURCE_BUSY;
+ break;
+ case android::ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION:
+ status = Status::ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION;
+ break;
+ case android::ERROR_DRM_SESSION_NOT_OPENED:
+ status = Status::ERROR_DRM_SESSION_NOT_OPENED;
+ break;
+ case android::ERROR_DRM_CANNOT_HANDLE:
+ case android::BAD_VALUE:
+ status = Status::ERROR_DRM_CANNOT_HANDLE;
+ break;
+ default:
+ ALOGW("Unable to convert legacy status: %d, defaulting to UNKNOWN",
+ legacyStatus);
+ status = Status::ERROR_UNKNOWN_CRYPTO_EXCEPTION;
+ break;
+ }
+ return status;
+}
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace crypto
+} // namespace drm
+} // namespace hardware
+} // namespace android
diff --git a/drm/crypto/1.0/default/TypeConvert.h b/drm/crypto/1.0/default/TypeConvert.h
new file mode 100644
index 0000000..1655bab
--- /dev/null
+++ b/drm/crypto/1.0/default/TypeConvert.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_DRM_CRYPTO_V1_0_TYPECONVERT
+#define ANDROID_HARDWARE_DRM_CRYPTO_V1_0_TYPECONVERT
+
+#include <utils/Vector.h>
+#include <media/stagefright/MediaErrors.h>
+#include <media/hardware/CryptoAPI.h>
+
+#include <hidl/MQDescriptor.h>
+#include <android/hardware/drm/crypto/1.0/types.h>
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace crypto {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::hidl_vec;
+
+template<typename T> const hidl_vec<T> toHidlVec(const Vector<T> &Vector) {
+ hidl_vec<T> vec;
+ vec.setToExternal(const_cast<T *>(Vector.array()), Vector.size());
+ return vec;
+}
+
+template<typename T> hidl_vec<T> toHidlVec(Vector<T> &Vector) {
+ hidl_vec<T> vec;
+ vec.setToExternal(Vector.editArray(), Vector.size());
+ return vec;
+}
+
+template<typename T> const Vector<T> toVector(const hidl_vec<T> &vec) {
+ Vector<T> vector;
+ vector.appendArray(vec.data(), vec.size());
+ return *const_cast<const Vector<T> *>(&vector);
+}
+
+template<typename T> Vector<T> toVector(hidl_vec<T> &vec) {
+ Vector<T> vector;
+ vector.appendArray(vec.data(), vec.size());
+ return vector;
+}
+
+template<typename T, size_t SIZE> const Vector<T> toVector(
+ const hidl_array<T, SIZE> &array) {
+ Vector<T> vector;
+ vector.appendArray(array.data(), array.size());
+ return vector;
+}
+
+template<typename T, size_t SIZE> Vector<T> toVector(
+ hidl_array<T, SIZE> &array) {
+ Vector<T> vector;
+ vector.appendArray(array.data(), array.size());
+ return vector;
+}
+
+Status toStatus(status_t legacyStatus);
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace crypto
+} // namespace drm
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_DRM_CRYPTO_V1_0_TYPECONVERT
diff --git a/drm/drm/1.0/IDrmFactory.hal b/drm/drm/1.0/IDrmFactory.hal
index a4ee0f1..a58bcaa 100644
--- a/drm/drm/1.0/IDrmFactory.hal
+++ b/drm/drm/1.0/IDrmFactory.hal
@@ -27,7 +27,7 @@
*/
interface IDrmFactory {
- /*
+ /**
* Determine if a crypto scheme is supported by this HAL
*
* @param uuid identifies the crypto scheme in question
@@ -35,22 +35,16 @@
*/
isCryptoSchemeSupported(uint8_t[16] uuid) generates(bool isSupported);
- /*
+ /**
* Create a drm plugin instance for the specified uuid and scheme-specific
* initialization data.
*
* @param uuid uniquely identifies the drm scheme. See
* http://dashif.org/identifiers/protection for uuid assignments
- * @param initData scheme-specific init data.
- * @return the status of the call
- * @return the created IDrmPlugin
+ * @return status the status of the call. If the plugin can't be created,
+ * the HAL implementation must return ERROR_DRM_CANNOT_HANDLE.
+ * @return drmPlugin the created IDrmPlugin
*/
- createPlugin(uint8_t[16] uuid, vec<uint8_t> initData)
- generates (Status status, IDrmPlugin drmPlugin);
-
- /*
- * Destroy a previously created drm plugin
- * @return status the status of the call
- */
- destroyPlugin() generates(Status status);
+ createPlugin(uint8_t[16] uuid) generates (Status status,
+ IDrmPlugin drmPlugin);
};
diff --git a/drm/drm/1.0/IDrmPlugin.hal b/drm/drm/1.0/IDrmPlugin.hal
index 7f396d9..e847805 100644
--- a/drm/drm/1.0/IDrmPlugin.hal
+++ b/drm/drm/1.0/IDrmPlugin.hal
@@ -30,15 +30,25 @@
/**
* Open a new session with the DrmPlugin object. A session ID is returned
* in the sessionId parameter.
- * @return status the status of the call
+ * @return status the status of the call. The status must be one of
+ * ERROR_DRM_NOT_PROVISIONED if the device requires provisioning before
+ * it can open a session, ERROR_DRM_RESOURCE_BUSY if there are insufficent
+ * resources available to open a session, ERROR_DRM_CANNOT_HANDLE,
+ * if openSession is not supported at the time of the call or
+ * ERROR_DRM_INVALID_STATE if the HAL is in a state where a session cannot
+ * be opened.
+ * @return sessionId the session ID for the newly opened session
*/
- openSession() generates (SessionId sessionId, Status status);
+ openSession() generates (Status status, SessionId sessionId);
/**
* Close a session on the DrmPlugin object
*
* @param sessionId the session id the call applies to
- * @return status the status of the call
+ * @return status the status of the call. The status must be one of
+ * ERROR_DRM_SESSION_NOT_OPENED if the session is not opened,
+ * BAD_VALUE if the sessionId is invalid or ERROR_DRM_INVALID_STATE
+ * if the HAL is in a state where the session cannot be closed.
*/
closeSession(SessionId sessionId) generates (Status status);
@@ -65,6 +75,13 @@
* allow a client application to provide additional message parameters to
* the server.
*
+ * @return status the status of the call. The status must be one of
+ * ERROR_DRM_SESSION_NOT_OPENED if the session is not opened,
+ * ERROR_DRM_NOT_PROVISIONED if the device requires provisioning before
+ * it can generate a key request, ERROR_DRM_CANNOT_HANDLE if keyKeyRequest
+ * is not supported at the time of the call, BAD_VALUE if any parameters
+ * are invalid or ERROR_DRM_INVALID_STATE if the HAL is in a state where
+ * a key request cannot be generated.
* @return request if successful, the opaque key request blob is returned
* @return requestType indicates type information about the returned
* request. The type may be one of INITIAL, RENEWAL or RELEASE. An
@@ -72,15 +89,14 @@
* subsequent key request used to refresh the keys in a license. RELEASE
* corresponds to a keyType of RELEASE, which indicates keys are being
* released.
- * @return status the status of the call
* @return defaultUrl the URL that the request may be sent to, if
* provided by the drm HAL. The app may choose to override this
* URL.
*/
getKeyRequest(vec<uint8_t> scope, vec<uint8_t> initData,
- string mimeType, KeyType keyType, KeyedVector optionalParameters)
- generates (vec<uint8_t> request, KeyRequestType requestType,
- Status status, string defaultUrl);
+ string mimeType, KeyType keyType, KeyedVector optionalParameters)
+ generates (Status status, vec<uint8_t> request,
+ KeyRequestType requestType, string defaultUrl);
/**
* After a key response is received by the app, it is provided to the
@@ -93,22 +109,31 @@
* @param response the response from the key server that is being
* provided to the drm HAL.
*
+ * @return status the status of the call. The status must be one of
+ * ERROR_DRM_SESSION_NOT_OPENED if the session is not opened,
+ * ERROR_DRM_NOT_PROVISIONED if the device requires provisioning before
+ * it can handle the key response, ERROR_DRM_DEVICE_REVOKED if the device
+ * has been disabled by the license policy, ERROR_DRM_CANNOT_HANDLE if
+ * provideKeyResponse is not supported at the time of the call, BAD_VALUE
+ * if any parameters are invalid or ERROR_DRM_INVALID_STATE if the HAL is
+ * in a state where a key response cannot be handled.
* @return keySetId when the response is for an offline key request, a
* keySetId is returned in the keySetId vector parameter that can be used
* to later restore the keys to a new session with the method restoreKeys.
* When the response is for a streaming or release request, no keySetId is
* returned.
- *
- * @return status the status of the call
*/
- provideKeyResponse(vec<uint8_t> scope,
- vec<uint8_t> response) generates (vec<uint8_t> keySetId, Status status);
+ provideKeyResponse(vec<uint8_t> scope, vec<uint8_t> response)
+ generates (Status status, vec<uint8_t> keySetId);
/**
* Remove the current keys from a session
*
* @param sessionId the session id the call applies to
- * @return status the status of the call
+ * @return status the status of the call. The status must be one of
+ * ERROR_DRM_SESSION_NOT_OPENED if the session is not opened,
+ * BAD_VALUE if the sessionId is invalid or ERROR_DRM_INVALID_STATE
+ * if the HAL is in a state where the keys cannot be removed.
*/
removeKeys(SessionId sessionId) generates (Status status);
@@ -118,12 +143,15 @@
* @param sessionId the session id the call applies to
* @param keySetId identifies the keys to load, obtained from a prior
* call to provideKeyResponse().
- * @return status the status of the call
+ * @return status the status of the call. The status must be one of
+ * ERROR_DRM_SESSION_NOT_OPENED if the session is not opened,
+ * BAD_VALUE if any parameters are invalid or ERROR_DRM_INVALID_STATE
+ * if the HAL is in a state where keys cannot be restored.
*/
restoreKeys(SessionId sessionId,
- vec<uint8_t> keySetId) generates (Status status);
+ vec<uint8_t> keySetId) generates (Status status);
- /*
+ /**
* Request an informative description of the license for the session. The
* status is in the form of {name, value} pairs. Since DRM license policies
* vary by vendor, the specific status field names are determined by each
@@ -131,45 +159,61 @@
* the field names for a particular drm scheme.
*
* @param sessionId the session id the call applies to
+ * @return status the status of the call. The status must be one of
+ * ERROR_DRM_SESSION_NOT_OPENED if the session is not opened,
+ * BAD_VALUE if the sessionId is invalid or ERROR_DRM_INVALID_STATE
+ * if the HAL is in a state where key status cannot be queried.
* @return infoList a list of name value pairs describing the license
- * @return status the status of the call
*/
queryKeyStatus(SessionId sessionId)
- generates (KeyedVector infoList, Status status);
+ generates (Status status, KeyedVector infoList);
/**
* A provision request/response exchange occurs between the app and a
* provisioning server to retrieve a device certificate. getProvisionRequest
- * is used to obtain an opaque key request blob that is delivered to the
- * provisioning server.
+ * is used to obtain an opaque provisioning request blob that is delivered
+ * to the provisioning server.
*
* @param certificateType the type of certificate requested, e.g. "X.509"
* @param certificateAuthority identifies the certificate authority. A
* certificate authority (CA) is an entity which issues digital certificates
- * for use by other parties. It is an example of a trusted third party
- * @return if successful the opaque certirequest blob is returned
- * @return status the status of the call
+ * for use by other parties. It is an example of a trusted third party.
+ * @return status the status of the call. The status must be one of
+ * BAD_VALUE if the sessionId is invalid or ERROR_DRM_INVALID_STATE
+ * if the HAL is in a state where the provision request cannot be
+ * generated.
+ * @return request if successful the opaque certificate request blob
+ * is returned
+ * @return defaultUrl URL that the provisioning request should be
+ * sent to, if known by the HAL implementation. If the HAL implementation
+ * does not provide a defaultUrl, the returned string must be empty.
*/
getProvisionRequest(string certificateType, string certificateAuthority)
- generates (vec<uint8_t> request, string defaultUrl, Status status);
+ generates (Status status, vec<uint8_t> request, string defaultUrl);
/**
* After a provision response is received by the app from a provisioning
- * server, it can be provided to the Drm HAL using provideProvisionResponse.
+ * server, it is provided to the Drm HAL using provideProvisionResponse.
+ * The HAL implementation must receive the provision request and
+ * store the provisioned credentials.
*
* @param response the opaque provisioning response received by the
- * app from a provisioning server
+ * app from a provisioning server.
+
+ * @return status the status of the call. The status must be one of
+ * ERROR_DRM_DEVICE_REVOKED if the device has been disabled by the license
+ * policy, BAD_VALUE if any parameters are invalid or ERROR_DRM_INVALID_STATE
+ * if the HAL is in a state where the provision response cannot be
+ * handled.
* @return certificate the public certificate resulting from the provisioning
* operation, if any. An empty vector indicates that no certificate was
* returned.
* @return wrappedKey an opaque object containing encrypted private key
* material to be used by signRSA when computing an RSA signature on a
* message, see the signRSA method.
- * @return status the status of the call
*/
- provideProvisionResponse(vec<uint8_t> response)
- generates (vec<uint8_t> certificate, vec<uint8_t> wrappedKey,
- Status status);
+ provideProvisionResponse(vec<uint8_t> response) generates (Status status,
+ vec<uint8_t> certificate, vec<uint8_t> wrappedKey);
/**
* SecureStop is a way of enforcing the concurrent stream limit per
@@ -193,41 +237,50 @@
/**
* Get all secure stops on the device
*
+ * @return status the status of the call. The status must be
+ * ERROR_DRM_INVALID_STATE if the HAL is in a state where the secure stops
+ * cannot be returned.
* @return secureStops a list of the secure stop opaque objects
- * @return status the status of the call
*/
getSecureStops() generates
- (vec<SecureStop> secureStops, Status status);
+ (Status status, vec<SecureStop> secureStops);
/**
- * Get all secure stops by secure stop ID
- *
- * @param secureStopId the ID of the secure stop to return. The
- * secure stop ID is delivered by the key server as part of the key
- * response and must also be known by the app.
- *
- * @return the secure stop opaque object
- * @return status the status of the call
- */
+ * Get all secure stops by secure stop ID
+ *
+ * @param secureStopId the ID of the secure stop to return. The
+ * secure stop ID is delivered by the key server as part of the key
+ * response and must also be known by the app.
+ *
+ * @return status the status of the call. The status must be one of
+ * BAD_VALUE if the secureStopId is invalid or ERROR_DRM_INVALID_STATE
+ * if the HAL is in a state where the secure stop cannot be returned.
+ * @return secureStop the secure stop opaque object
+ */
+
getSecureStop(SecureStopId secureStopId)
- generates (SecureStop secureStop, Status status);
+ generates (Status status, SecureStop secureStop);
/**
* Release all secure stops on the device
*
- * @return status the status of the call
+ * @return status the status of the call. The status must be one of
+ * ERROR_DRM_INVALID_STATE if the HAL is in a state where the secure
+ * stops cannot be released.
*/
releaseAllSecureStops() generates (Status status);
/**
- * Release a secure stop by secure stop ID
- *
- * @param secureStopId the ID of the secure stop to release. The
- * secure stop ID is delivered by the key server as part of the key
- * response and must also be known by the app.
- *
- * @return status the status of the call
- */
+ * Release a secure stop by secure stop ID
+ *
+ * @param secureStopId the ID of the secure stop to release. The
+ * secure stop ID is delivered by the key server as part of the key
+ * response and must also be known by the app.
+ *
+ * @return status the status of the call. The status must be one of
+ * BAD_VALUE if the secureStopId is invalid or ERROR_DRM_INVALID_STATE
+ * if the HAL is in a state where the secure stop cannot be released.
+ */
releaseSecureStop(vec<uint8_t> secureStopId) generates (Status status);
/**
@@ -252,30 +305,39 @@
* Read a string property value given the property name.
*
* @param propertyName the name of the property
- * @return the property value string
- * @return status the status of the call
+ * @return status the status of the call. The status must be one of
+ * BAD_VALUE if the property name is invalid, ERROR_DRM_CANNOT_HANDLE
+ * if the property is not supported, or ERROR_DRM_INVALID_STATE if the
+ * HAL is in a state where the property cannot be obtained.
+ * @return value the property value string
*/
getPropertyString(string propertyName)
- generates (string value, Status status);
+ generates (Status status, string value);
/**
* Read a byte array property value given the property name.
*
* @param propertyName the name of the property
- * @return the property value byte array
- * @return status the status of the call
+ * @return status the status of the call. The status must be one of
+ * BAD_VALUE if the property name is invalid, ERROR_DRM_CANNOT_HANDLE
+ * if the property is not supported, or ERROR_DRM_INVALID_STATE if the
+ * HAL is in a state where the property cannot be obtained.
+ * @return value the property value byte array
*/
getPropertyByteArray(string propertyName)
- generates (vec<uint8_t> value, Status status);
+ generates (Status status, vec<uint8_t> value);
/**
* Write a property string value given the property name
*
* @param propertyName the name of the property
* @param value the value to write
- * @return status the status of the call
+ * @return status the status of the call. The status must be one of
+ * BAD_VALUE if the property name is invalid, ERROR_DRM_CANNOT_HANDLE
+ * if the property is not supported, or ERROR_DRM_INVALID_STATE if the
+ * HAL is in a state where the property cannot be set.
*/
- setPropertyString(string propertyName, string value )
+ setPropertyString(string propertyName, string value)
generates (Status status);
/**
@@ -283,7 +345,10 @@
*
* @param propertyName the name of the property
* @param value the value to write
- * @return status the status of the call
+ * @return status the status of the call. The status must be one of
+ * BAD_VALUE if the property name is invalid, ERROR_DRM_CANNOT_HANDLE
+ * if the property is not supported, or ERROR_DRM_INVALID_STATE if the
+ * HAL is in a state where the property cannot be set.
*/
setPropertyByteArray(string propertyName, vec<uint8_t> value )
generates (Status status);
@@ -301,7 +366,10 @@
* @param algorithm the algorithm to use. The string conforms to JCA
* Standard Names for Cipher Transforms and is case insensitive. An
* example algorithm is "AES/CBC/PKCS5Padding".
- * @return status the status of the call
+ * @return status the status of the call. The status must be one of
+ * ERROR_DRM_SESSION_NOT_OPENED if the session is not opened,
+ * BAD_VALUE if any parameters are invalid or ERROR_DRM_INVALID_STATE
+ * if the HAL is in a state where the algorithm cannot be set.
*/
setCipherAlgorithm(SessionId sessionId, string algorithm)
generates (Status status);
@@ -313,7 +381,10 @@
* @param algorithm the algorithm to use. The string conforms to JCA
* Standard Names for Mac Algorithms and is case insensitive. An example MAC
* algorithm string is "HmacSHA256".
- * @return status the status of the call
+ * @return status the status of the call. The status must be one of
+ * ERROR_DRM_SESSION_NOT_OPENED if the session is not opened,
+ * BAD_VALUE if any parameters are invalid or ERROR_DRM_INVALID_STATE
+ * if the HAL is in a state where the algorithm cannot be set.
*/
setMacAlgorithm(SessionId sessionId, string algorithm)
generates (Status status);
@@ -327,12 +398,15 @@
* @param keyId the ID of the key to use for encryption
* @param input the input data to encrypt
* @param iv the initialization vector to use for encryption
+ * @return status the status of the call. The status must be one of
+ * ERROR_DRM_SESSION_NOT_OPENED if the session is not opened,
+ * BAD_VALUE if any parameters are invalid or ERROR_DRM_INVALID_STATE
+ * if the HAL is in a state where the encrypt operation cannot be
+ * performed.
* @return output the decrypted data
- * @return status the status of the call
*/
encrypt(SessionId sessionId, vec<uint8_t> keyId, vec<uint8_t> input,
- vec<uint8_t> iv)
- generates (vec<uint8_t> output, Status status);
+ vec<uint8_t> iv) generates (Status status, vec<uint8_t> output);
/**
* Decrypt the provided input buffer with the cipher algorithm
@@ -343,11 +417,15 @@
* @param keyId the ID of the key to use for decryption
* @param input the input data to decrypt
* @param iv the initialization vector to use for decryption
+ * @return status the status of the call. The status must be one of
+ * ERROR_DRM_SESSION_NOT_OPENED if the session is not opened,
+ * BAD_VALUE if any parameters are invalid or ERROR_DRM_INVALID_STATE
+ * if the HAL is in a state where the decrypt operation cannot be
+ * performed.
* @return output the decrypted data
- * @return status the status of the call
*/
decrypt(SessionId sessionId, vec<uint8_t> keyId, vec<uint8_t> input,
- vec<uint8_t> iv) generates (vec<uint8_t> output, Status status);
+ vec<uint8_t> iv) generates (Status status, vec<uint8_t> output);
/**
* Compute a signature over the provided message using the mac algorithm
@@ -357,11 +435,15 @@
* @param sessionId the session id the call applies to
* @param keyId the ID of the key to use for decryption
* @param message the message to compute a signature over
- * @return the computed signature
- * @return status the status of the call
+ * @return status the status of the call. The status must be one of
+ * ERROR_DRM_SESSION_NOT_OPENED if the session is not opened,
+ * BAD_VALUE if any parameters are invalid or ERROR_DRM_INVALID_STATE
+ * if the HAL is in a state where the sign operation cannot be
+ * performed.
+ * @return signature the computed signature
*/
sign(SessionId sessionId, vec<uint8_t> keyId, vec<uint8_t> message)
- generates (vec<uint8_t> signature, Status status);
+ generates (Status status, vec<uint8_t> signature);
/**
* Compute a hash of the provided message using the mac algorithm specified
@@ -371,26 +453,43 @@
* @param sessionId the session id the call applies to
* @param keyId the ID of the key to use for decryption
* @param message the message to compute a hash of
- * @return status the status of the call
+ * @param signature the signature to verify
+ * @return status the status of the call. The status must be one of
+ * ERROR_DRM_SESSION_NOT_OPENED if the session is not opened,
+ * BAD_VALUE if any parameters are invalid or ERROR_DRM_INVALID_STATE
+ * if the HAL is in a state where the verify operation cannot be
+ * performed.
+ * @return match true if the signature is verified positively,
+ * false otherwise.
*/
verify(SessionId sessionId, vec<uint8_t> keyId, vec<uint8_t> message,
- vec<uint8_t> signature) generates (bool match, Status status);
+ vec<uint8_t> signature) generates (Status status, bool match);
/**
* Compute an RSA signature on the provided message using the specified
* algorithm.
*
+ * @param sessionId the session id the call applies to
* @param algorithm the signing algorithm, such as "RSASSA-PSS-SHA1"
* or "PKCS1-BlockType1"
- * @param sessionId the session id the call applies to
- * @param wrappedKey the private key returned during provisioning
- * as returned by provideProvisionResponse.
+ * @param message the message to compute the signature on
+ * @param wrappedKey the private key returned during provisioning as
+ * returned by provideProvisionResponse.
+ * @return status the status of the call. The status must be one of
+ * ERROR_DRM_SESSION_NOT_OPENED if the session is not opened,
+ * BAD_VALUE if any parameters are invalid or ERROR_DRM_INVALID_STATE
+ * if the HAL is in a state where the signRSA operation cannot be
+ * performed.
* @return signature the RSA signature computed over the message
- * @return status the status of the call
*/
signRSA(SessionId sessionId, string algorithm, vec<uint8_t> message,
vec<uint8_t> wrappedkey)
- generates (vec<uint8_t> signature, Status status);
+ generates (Status status, vec<uint8_t> signature);
+
+ /**
+ * Plugins call the following methods to deliver events to the
+ * java app.
+ */
/**
* Set a listener for a drm session. This allows the drm HAL to
@@ -401,11 +500,6 @@
setListener(IDrmPluginListener listener);
/**
- * HAL implementations call the following methods to deliver events to the
- * listener
- */
-
- /**
* Legacy event sending method, it sends events of various types using a
* single overloaded set of parameters. This form is deprecated.
*
@@ -413,24 +507,23 @@
* @param sessionId identifies the session the event originated from
* @param data event-specific data blob
*/
- oneway sendEvent(EventType eventType, SessionId sessionId,
- vec<uint8_t> data);
+ sendEvent(EventType eventType, SessionId sessionId, vec<uint8_t> data);
/**
* Send a license expiration update to the listener. The expiration
- * update indicates how long the current keys are valid before they
- * need to be renewed.
+ * update indicates how long the current license is valid before it
+ * needs to be renewed.
*
* @param sessionId identifies the session the event originated from
* @param expiryTimeInMS the time when the keys need to be renewed.
* The time is in milliseconds, relative to the Unix epoch. A time of 0
* indicates that the keys never expire.
*/
- oneway sendExpirationUpdate(SessionId sessionId, int64_t expiryTimeInMS);
+ sendExpirationUpdate(SessionId sessionId, int64_t expiryTimeInMS);
/**
* Send a keys change event to the listener. The keys change event
- * indicates the status of each key in the session. `Keys can be
+ * indicates the status of each key in the session. Keys can be
* indicated as being usable, expired, outputnotallowed or statuspending.
*
* @param sessionId identifies the session the event originated from
@@ -439,6 +532,6 @@
* @param hasNewUsableKey indicates if the event includes at least one
* key that has become usable.
*/
- oneway sendKeysChange(SessionId sessionId, vec<KeyStatus> keyStatusList,
- bool hasNewUsableKey);
+ sendKeysChange(SessionId sessionId, vec<KeyStatus> keyStatusList,
+ bool hasNewUsableKey);
};
diff --git a/drm/drm/1.0/IDrmPluginListener.hal b/drm/drm/1.0/IDrmPluginListener.hal
index fe2d998..92010a1 100644
--- a/drm/drm/1.0/IDrmPluginListener.hal
+++ b/drm/drm/1.0/IDrmPluginListener.hal
@@ -36,7 +36,8 @@
* @param sessionId identifies the session the event originated from
* @param data event-specific data blob
*/
- sendEvent(EventType eventType, SessionId sessionId, vec<uint8_t> data);
+ oneway sendEvent(EventType eventType, SessionId sessionId,
+ vec<uint8_t> data);
/**
* Send a license expiration update to the listener. The expiration
@@ -48,7 +49,7 @@
* The time is in milliseconds, relative to the Unix epoch. A time
* of 0 indicates that the keys never expire.
*/
- sendExpirationUpdate(SessionId sessionId, int64_t expiryTimeInMS);
+ oneway sendExpirationUpdate(SessionId sessionId, int64_t expiryTimeInMS);
/**
* Send a keys change event to the listener. The keys change event
@@ -61,6 +62,6 @@
* @param hasNewUsableKey indicates if the event includes at least one
* key that has become usable.
*/
- sendKeysChange(SessionId sessionId, vec<KeyStatus> keyStatusList,
+ oneway sendKeysChange(SessionId sessionId, vec<KeyStatus> keyStatusList,
bool hasNewUsableKey);
};
diff --git a/drm/drm/1.0/default/Android.mk b/drm/drm/1.0/default/Android.mk
new file mode 100644
index 0000000..952957c
--- /dev/null
+++ b/drm/drm/1.0/default/Android.mk
@@ -0,0 +1,39 @@
+# 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.drm.drm@1.0-impl
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_SRC_FILES := \
+ DrmFactory.cpp \
+ DrmPlugin.cpp \
+ TypeConvert.cpp \
+
+LOCAL_SHARED_LIBRARIES := \
+ libhidlbase \
+ libhidltransport \
+ libhwbinder \
+ libutils \
+ liblog \
+ libmediadrm \
+ libstagefright_foundation \
+ android.hardware.drm.drm@1.0 \
+
+LOCAL_C_INCLUDES := \
+ frameworks/native/include \
+ frameworks/av/include
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/drm/drm/1.0/default/DrmFactory.cpp b/drm/drm/1.0/default/DrmFactory.cpp
new file mode 100644
index 0000000..494ca53
--- /dev/null
+++ b/drm/drm/1.0/default/DrmFactory.cpp
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "DrmFactory.h"
+#include "DrmPlugin.h"
+#include "TypeConvert.h"
+#include <utils/Log.h>
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace drm {
+namespace V1_0 {
+namespace implementation {
+
+ DrmFactory::DrmFactory() :
+ loader("/vendor/lib/mediadrm", "createDrmFactory", "drm") {}
+
+ // Methods from ::android::hardware::drm::drm::V1_0::IDrmFactory follow.
+ Return<bool> DrmFactory::isCryptoSchemeSupported (
+ const hidl_array<uint8_t, 16>& uuid) {
+ for (size_t i = 0; i < loader.factoryCount(); i++) {
+ if (loader.getFactory(i)->isCryptoSchemeSupported(uuid.data())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ Return<void> DrmFactory::createPlugin(const hidl_array<uint8_t, 16>& uuid,
+ createPlugin_cb _hidl_cb) {
+
+ for (size_t i = 0; i < loader.factoryCount(); i++) {
+ if (loader.getFactory(i)->isCryptoSchemeSupported(uuid.data())) {
+ android::DrmPlugin *legacyPlugin = NULL;
+ status_t status = loader.getFactory(i)->createDrmPlugin(
+ uuid.data(), &legacyPlugin);
+ DrmPlugin *newPlugin = NULL;
+ if (legacyPlugin == NULL) {
+ ALOGE("Drm legacy HAL: failed to create drm plugin");
+ } else {
+ newPlugin = new DrmPlugin(legacyPlugin);
+ }
+ _hidl_cb(toStatus(status), newPlugin);
+ return Void();
+ }
+ }
+ _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, NULL);
+ return Void();
+ }
+
+ IDrmFactory* HIDL_FETCH_IDrmFactory(const char* /* name */) {
+ return new DrmFactory();
+ }
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace drm
+} // namespace drm
+} // namespace hardware
+} // namespace android
diff --git a/drm/drm/1.0/default/DrmFactory.h b/drm/drm/1.0/default/DrmFactory.h
new file mode 100644
index 0000000..4dd9ac0
--- /dev/null
+++ b/drm/drm/1.0/default/DrmFactory.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef ANDROID_HARDWARE_DRM_DRM_V1_0__DRMFACTORY_H
+#define ANDROID_HARDWARE_DRM_DRM_V1_0__DRMFACTORY_H
+
+#include <android/hardware/drm/drm/1.0/IDrmFactory.h>
+#include <hidl/Status.h>
+#include <media/drm/DrmAPI.h>
+#include <media/PluginLoader.h>
+#include <media/SharedLibrary.h>
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace drm {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::drm::drm::V1_0::IDrmFactory;
+using ::android::hardware::drm::drm::V1_0::IDrmPlugin;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+struct DrmFactory : public IDrmFactory {
+ DrmFactory();
+ virtual ~DrmFactory() {}
+
+ // Methods from ::android::hardware::drm::drm::V1_0::IDrmFactory follow.
+
+ Return<bool> isCryptoSchemeSupported(const hidl_array<uint8_t, 16>& uuid)
+ override;
+
+ Return<void> createPlugin(const hidl_array<uint8_t, 16>& uuid,
+ createPlugin_cb _hidl_cb) override;
+
+private:
+ android::PluginLoader<android::DrmFactory> loader;
+
+ DrmFactory(const DrmFactory &) = delete;
+ void operator=(const DrmFactory &) = delete;
+};
+
+extern "C" IDrmFactory* HIDL_FETCH_IDrmFactory(const char* name);
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace drm
+} // namespace drm
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_DRM_DRM_V1_0__DRMFACTORY_H
diff --git a/drm/drm/1.0/default/DrmPlugin.cpp b/drm/drm/1.0/default/DrmPlugin.cpp
new file mode 100644
index 0000000..5c8f426
--- /dev/null
+++ b/drm/drm/1.0/default/DrmPlugin.cpp
@@ -0,0 +1,428 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <utils/KeyedVector.h>
+#include <utils/String8.h>
+
+#include "DrmPlugin.h"
+#include "TypeConvert.h"
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace drm {
+namespace V1_0 {
+namespace implementation {
+
+ // Methods from ::android::hardware::drm::drm::V1_0::IDrmPlugin follow.
+
+ Return<void> DrmPlugin::openSession(openSession_cb _hidl_cb) {
+
+ Vector<uint8_t> legacySessionId;
+ status_t status = mLegacyPlugin->openSession(legacySessionId);
+ _hidl_cb(toStatus(status), toHidlVec(legacySessionId));
+ return Void();
+ }
+
+ Return<Status> DrmPlugin::closeSession(const hidl_vec<uint8_t>& sessionId) {
+ return toStatus(mLegacyPlugin->closeSession(toVector(sessionId)));
+ }
+
+ Return<void> DrmPlugin::getKeyRequest(const hidl_vec<uint8_t>& scope,
+ const hidl_vec<uint8_t>& initData, const hidl_string& mimeType,
+ KeyType keyType, const hidl_vec<KeyValue>& optionalParameters,
+ getKeyRequest_cb _hidl_cb) {
+
+ status_t status = android::OK;
+
+ android::DrmPlugin::KeyType legacyKeyType;
+ switch(keyType) {
+ case KeyType::OFFLINE:
+ legacyKeyType = android::DrmPlugin::kKeyType_Offline;
+ break;
+ case KeyType::STREAMING:
+ legacyKeyType = android::DrmPlugin::kKeyType_Streaming;
+ break;
+ case KeyType::RELEASE:
+ legacyKeyType = android::DrmPlugin::kKeyType_Release;
+ break;
+ default:
+ status = android::BAD_VALUE;
+ break;
+ }
+
+ Vector<uint8_t> legacyRequest;
+ KeyRequestType requestType = KeyRequestType::UNKNOWN;
+ String8 defaultUrl;
+
+ if (status == android::OK) {
+ android::KeyedVector<String8, String8> legacyOptionalParameters;
+ for (size_t i = 0; i < optionalParameters.size(); i++) {
+ legacyOptionalParameters.add(String8(optionalParameters[i].key),
+ String8(optionalParameters[i].value));
+ }
+
+ android::DrmPlugin::KeyRequestType legacyRequestType =
+ android::DrmPlugin::kKeyRequestType_Unknown;
+
+ status_t status = mLegacyPlugin->getKeyRequest(toVector(scope),
+ toVector(initData), String8(mimeType), legacyKeyType,
+ legacyOptionalParameters, legacyRequest, defaultUrl,
+ &legacyRequestType);
+
+ switch(legacyRequestType) {
+ case android::DrmPlugin::kKeyRequestType_Initial:
+ requestType = KeyRequestType::INITIAL;
+ break;
+ case android::DrmPlugin::kKeyRequestType_Renewal:
+ requestType = KeyRequestType::RENEWAL;
+ break;
+ case android::DrmPlugin::kKeyRequestType_Release:
+ requestType = KeyRequestType::RELEASE;
+ break;
+ case android::DrmPlugin::kKeyRequestType_Unknown:
+ status = android::BAD_VALUE;
+ break;
+ }
+ }
+ _hidl_cb(toStatus(status), toHidlVec(legacyRequest), requestType,
+ defaultUrl.string());
+ return Void();
+ }
+
+ Return<void> DrmPlugin::provideKeyResponse(const hidl_vec<uint8_t>& scope,
+ const hidl_vec<uint8_t>& response, provideKeyResponse_cb _hidl_cb) {
+
+ Vector<uint8_t> keySetId;
+ status_t status = mLegacyPlugin->provideKeyResponse(toVector(scope),
+ toVector(response), keySetId);
+ _hidl_cb(toStatus(status), toHidlVec(keySetId));
+ return Void();
+ }
+
+ Return<Status> DrmPlugin::removeKeys(const hidl_vec<uint8_t>& sessionId) {
+ return toStatus(mLegacyPlugin->removeKeys(toVector(sessionId)));
+ }
+
+ Return<Status> DrmPlugin::restoreKeys(const hidl_vec<uint8_t>& sessionId,
+ const hidl_vec<uint8_t>& keySetId) {
+ status_t legacyStatus = mLegacyPlugin->restoreKeys(toVector(sessionId),
+ toVector(keySetId));
+ return toStatus(legacyStatus);
+ }
+
+ Return<void> DrmPlugin::queryKeyStatus(const hidl_vec<uint8_t>& sessionId,
+ queryKeyStatus_cb _hidl_cb) {
+
+ android::KeyedVector<String8, String8> legacyInfoMap;
+ status_t status = mLegacyPlugin->queryKeyStatus(toVector(sessionId),
+ legacyInfoMap);
+
+ Vector<KeyValue> infoMapVec;
+ for (size_t i = 0; i < legacyInfoMap.size(); i++) {
+ KeyValue keyValuePair;
+ keyValuePair.key = String8(legacyInfoMap.keyAt(i));
+ keyValuePair.value = String8(legacyInfoMap.valueAt(i));
+ infoMapVec.push_back(keyValuePair);
+ }
+ _hidl_cb(toStatus(status), toHidlVec(infoMapVec));
+ return Void();
+ }
+
+ Return<void> DrmPlugin::getProvisionRequest(
+ const hidl_string& certificateType,
+ const hidl_string& certificateAuthority,
+ getProvisionRequest_cb _hidl_cb) {
+
+ Vector<uint8_t> legacyRequest;
+ String8 legacyDefaultUrl;
+ status_t status = mLegacyPlugin->getProvisionRequest(
+ String8(certificateType), String8(certificateAuthority),
+ legacyRequest, legacyDefaultUrl);
+
+ _hidl_cb(toStatus(status), toHidlVec(legacyRequest),
+ hidl_string(legacyDefaultUrl));
+ return Void();
+ }
+
+ Return<void> DrmPlugin::provideProvisionResponse(
+ const hidl_vec<uint8_t>& response,
+ provideProvisionResponse_cb _hidl_cb) {
+
+ Vector<uint8_t> certificate;
+ Vector<uint8_t> wrappedKey;
+
+ status_t legacyStatus = mLegacyPlugin->provideProvisionResponse(
+ toVector(response), certificate, wrappedKey);
+
+ _hidl_cb(toStatus(legacyStatus), toHidlVec(certificate),
+ toHidlVec(wrappedKey));
+ return Void();
+ }
+
+ Return<void> DrmPlugin::getSecureStops(getSecureStops_cb _hidl_cb) {
+ List<Vector<uint8_t> > legacySecureStops;
+ status_t status = mLegacyPlugin->getSecureStops(legacySecureStops);
+
+ Vector<SecureStop> secureStopsVec;
+ List<Vector<uint8_t> >::iterator iter = legacySecureStops.begin();
+
+ while (iter != legacySecureStops.end()) {
+ SecureStop secureStop;
+ secureStop.opaqueData = toHidlVec(*iter++);
+ secureStopsVec.push_back(secureStop);
+ }
+
+ _hidl_cb(toStatus(status), toHidlVec(secureStopsVec));
+ return Void();
+ }
+
+ Return<void> DrmPlugin::getSecureStop(const hidl_vec<uint8_t>& secureStopId,
+ getSecureStop_cb _hidl_cb) {
+
+ Vector<uint8_t> legacySecureStop;
+ status_t status = mLegacyPlugin->getSecureStop(toVector(secureStopId),
+ legacySecureStop);
+
+ SecureStop secureStop;
+ secureStop.opaqueData = toHidlVec(legacySecureStop);
+ _hidl_cb(toStatus(status), secureStop);
+ return Void();
+ }
+
+ Return<Status> DrmPlugin::releaseAllSecureStops() {
+ return toStatus(mLegacyPlugin->releaseAllSecureStops());
+ }
+
+ Return<Status> DrmPlugin::releaseSecureStop(
+ const hidl_vec<uint8_t>& secureStopId) {
+ status_t legacyStatus =
+ mLegacyPlugin->releaseSecureStops(toVector(secureStopId));
+ return toStatus(legacyStatus);
+ }
+
+ Return<void> DrmPlugin::getPropertyString(const hidl_string& propertyName,
+ getPropertyString_cb _hidl_cb) {
+ String8 legacyValue;
+ status_t status = mLegacyPlugin->getPropertyString(
+ String8(propertyName), legacyValue);
+ _hidl_cb(toStatus(status), legacyValue.string());
+ return Void();
+ }
+
+ Return<void> DrmPlugin::getPropertyByteArray(const hidl_string& propertyName,
+ getPropertyByteArray_cb _hidl_cb) {
+ Vector<uint8_t> legacyValue;
+ status_t status = mLegacyPlugin->getPropertyByteArray(
+ String8(propertyName), legacyValue);
+ _hidl_cb(toStatus(status), toHidlVec(legacyValue));
+ return Void();
+ }
+
+ Return<Status> DrmPlugin::setPropertyString(const hidl_string& propertyName,
+ const hidl_string& value) {
+ status_t legacyStatus =
+ mLegacyPlugin->setPropertyString(String8(propertyName),
+ String8(value));
+ return toStatus(legacyStatus);
+ }
+
+ Return<Status> DrmPlugin::setPropertyByteArray(
+ const hidl_string& propertyName, const hidl_vec<uint8_t>& value) {
+ status_t legacyStatus =
+ mLegacyPlugin->setPropertyByteArray(String8(propertyName),
+ toVector(value));
+ return toStatus(legacyStatus);
+ }
+
+ Return<Status> DrmPlugin::setCipherAlgorithm(
+ const hidl_vec<uint8_t>& sessionId, const hidl_string& algorithm) {
+ status_t legacyStatus =
+ mLegacyPlugin->setCipherAlgorithm(toVector(sessionId),
+ String8(algorithm));
+ return toStatus(legacyStatus);
+ }
+
+ Return<Status> DrmPlugin::setMacAlgorithm(
+ const hidl_vec<uint8_t>& sessionId, const hidl_string& algorithm) {
+ status_t legacyStatus =
+ mLegacyPlugin->setMacAlgorithm(toVector(sessionId),
+ String8(algorithm));
+ return toStatus(legacyStatus);
+ }
+
+ Return<void> DrmPlugin::encrypt(const hidl_vec<uint8_t>& sessionId,
+ const hidl_vec<uint8_t>& keyId, const hidl_vec<uint8_t>& input,
+ const hidl_vec<uint8_t>& iv, encrypt_cb _hidl_cb) {
+
+ Vector<uint8_t> legacyOutput;
+ status_t status = mLegacyPlugin->encrypt(toVector(sessionId),
+ toVector(keyId), toVector(input), toVector(iv), legacyOutput);
+ _hidl_cb(toStatus(status), toHidlVec(legacyOutput));
+ return Void();
+ }
+
+ Return<void> DrmPlugin::decrypt(const hidl_vec<uint8_t>& sessionId,
+ const hidl_vec<uint8_t>& keyId, const hidl_vec<uint8_t>& input,
+ const hidl_vec<uint8_t>& iv, decrypt_cb _hidl_cb) {
+
+ Vector<uint8_t> legacyOutput;
+ status_t status = mLegacyPlugin->decrypt(toVector(sessionId),
+ toVector(keyId), toVector(input), toVector(iv), legacyOutput);
+ _hidl_cb(toStatus(status), toHidlVec(legacyOutput));
+ return Void();
+ }
+
+ Return<void> DrmPlugin::sign(const hidl_vec<uint8_t>& sessionId,
+ const hidl_vec<uint8_t>& keyId, const hidl_vec<uint8_t>& message,
+ sign_cb _hidl_cb) {
+ Vector<uint8_t> legacySignature;
+ status_t status = mLegacyPlugin->sign(toVector(sessionId),
+ toVector(keyId), toVector(message), legacySignature);
+ _hidl_cb(toStatus(status), toHidlVec(legacySignature));
+ return Void();
+ }
+
+ Return<void> DrmPlugin::verify(const hidl_vec<uint8_t>& sessionId,
+ const hidl_vec<uint8_t>& keyId, const hidl_vec<uint8_t>& message,
+ const hidl_vec<uint8_t>& signature, verify_cb _hidl_cb) {
+
+ bool match;
+ status_t status = mLegacyPlugin->verify(toVector(sessionId),
+ toVector(keyId), toVector(message), toVector(signature),
+ match);
+ _hidl_cb(toStatus(status), match);
+ return Void();
+ }
+
+ Return<void> DrmPlugin::signRSA(const hidl_vec<uint8_t>& sessionId,
+ const hidl_string& algorithm, const hidl_vec<uint8_t>& message,
+ const hidl_vec<uint8_t>& wrappedKey, signRSA_cb _hidl_cb) {
+
+ Vector<uint8_t> legacySignature;
+ status_t status = mLegacyPlugin->signRSA(toVector(sessionId),
+ String8(algorithm), toVector(message), toVector(wrappedKey),
+ legacySignature);
+ _hidl_cb(toStatus(status), toHidlVec(legacySignature));
+ return Void();
+ }
+
+ Return<void> DrmPlugin::setListener(const sp<IDrmPluginListener>& listener) {
+ mListener = listener;
+ return Void();
+ }
+
+ Return<void> DrmPlugin::sendEvent(EventType eventType,
+ const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& data) {
+ mListener->sendEvent(eventType, sessionId, data);
+ return Void();
+ }
+
+ Return<void> DrmPlugin::sendExpirationUpdate(
+ const hidl_vec<uint8_t>& sessionId, int64_t expiryTimeInMS) {
+ mListener->sendExpirationUpdate(sessionId, expiryTimeInMS);
+ return Void();
+ }
+
+ Return<void> DrmPlugin::sendKeysChange(const hidl_vec<uint8_t>& sessionId,
+ const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey) {
+ mListener->sendKeysChange(sessionId, keyStatusList, hasNewUsableKey);
+ return Void();
+ }
+
+
+ // Methods from android::DrmPluginListener
+
+ void DrmPlugin::sendEvent(android::DrmPlugin::EventType legacyEventType,
+ int /*unused*/, Vector<uint8_t> const *sessionId,
+ Vector<uint8_t> const *data) {
+
+ EventType eventType;
+ bool sendEvent = true;
+ switch(legacyEventType) {
+ case android::DrmPlugin::kDrmPluginEventProvisionRequired:
+ eventType = EventType::PROVISION_REQUIRED;
+ break;
+ case android::DrmPlugin::kDrmPluginEventKeyNeeded:
+ eventType = EventType::KEY_NEEDED;
+ break;
+ case android::DrmPlugin::kDrmPluginEventKeyExpired:
+ eventType = EventType::KEY_EXPIRED;
+ break;
+ case android::DrmPlugin::kDrmPluginEventVendorDefined:
+ eventType = EventType::VENDOR_DEFINED;
+ break;
+ case android::DrmPlugin::kDrmPluginEventSessionReclaimed:
+ eventType = EventType::SESSION_RECLAIMED;
+ break;
+ default:
+ sendEvent = false;
+ break;
+ }
+ if (sendEvent) {
+ mListener->sendEvent(eventType, toHidlVec(*sessionId),
+ toHidlVec(*data));
+ }
+ }
+
+ void DrmPlugin::sendExpirationUpdate(Vector<uint8_t> const *sessionId,
+ int64_t expiryTimeInMS) {
+ mListener->sendExpirationUpdate(toHidlVec(*sessionId), expiryTimeInMS);
+ }
+
+ void DrmPlugin::sendKeysChange(Vector<uint8_t> const *sessionId,
+ Vector<android::DrmPlugin::KeyStatus> const *legacyKeyStatusList,
+ bool hasNewUsableKey) {
+
+ Vector<KeyStatus> keyStatusVec;
+ for (size_t i = 0; i < legacyKeyStatusList->size(); i++) {
+ const android::DrmPlugin::KeyStatus &legacyKeyStatus =
+ legacyKeyStatusList->itemAt(i);
+
+ KeyStatus keyStatus;
+
+ switch(legacyKeyStatus.mType) {
+ case android::DrmPlugin::kKeyStatusType_Usable:
+ keyStatus.type = KeyStatusType::USABLE;
+ break;
+ case android::DrmPlugin::kKeyStatusType_Expired:
+ keyStatus.type = KeyStatusType::EXPIRED;
+ break;
+ case android::DrmPlugin::kKeyStatusType_OutputNotAllowed:
+ keyStatus.type = KeyStatusType::OUTPUTNOTALLOWED;
+ break;
+ case android::DrmPlugin::kKeyStatusType_StatusPending:
+ keyStatus.type = KeyStatusType::STATUSPENDING;
+ break;
+ case android::DrmPlugin::kKeyStatusType_InternalError:
+ default:
+ keyStatus.type = KeyStatusType::INTERNALERROR;
+ break;
+ }
+
+ keyStatus.keyId = toHidlVec(legacyKeyStatus.mKeyId);
+ keyStatusVec.push_back(keyStatus);
+ }
+ mListener->sendKeysChange(toHidlVec(*sessionId),
+ toHidlVec(keyStatusVec), hasNewUsableKey);
+ }
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace drm
+} // namespace drm
+} // namespace hardware
+} // namespace android
diff --git a/drm/drm/1.0/default/DrmPlugin.h b/drm/drm/1.0/default/DrmPlugin.h
new file mode 100644
index 0000000..2bf3b5e
--- /dev/null
+++ b/drm/drm/1.0/default/DrmPlugin.h
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_DRM_DRM_V1_0__DRMPLUGIN_H
+#define ANDROID_HARDWARE_DRM_DRM_V1_0__DRMPLUGIN_H
+
+#include <media/drm/DrmAPI.h>
+#include <android/hardware/drm/drm/1.0/IDrmPlugin.h>
+#include <android/hardware/drm/drm/1.0/IDrmPluginListener.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace drm {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::drm::drm::V1_0::EventType;
+using ::android::hardware::drm::drm::V1_0::IDrmPlugin;
+using ::android::hardware::drm::drm::V1_0::IDrmPluginListener;
+using ::android::hardware::drm::drm::V1_0::KeyRequestType;
+using ::android::hardware::drm::drm::V1_0::KeyStatus;
+using ::android::hardware::drm::drm::V1_0::KeyType;
+using ::android::hardware::drm::drm::V1_0::KeyValue;
+using ::android::hardware::drm::drm::V1_0::SecureStop;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+struct DrmPlugin : public IDrmPlugin, android::DrmPluginListener {
+
+ DrmPlugin(android::DrmPlugin *plugin) : mLegacyPlugin(plugin) {}
+ ~DrmPlugin() {delete mLegacyPlugin;}
+
+ // Methods from ::android::hardware::drm::drm::V1_0::IDrmPlugin follow.
+
+ Return<void> openSession(openSession_cb _hidl_cb) override;
+
+ Return<Status> closeSession(const hidl_vec<uint8_t>& sessionId) override;
+
+ Return<void> getKeyRequest(const hidl_vec<uint8_t>& scope,
+ const hidl_vec<uint8_t>& initData, const hidl_string& mimeType,
+ KeyType keyType, const hidl_vec<KeyValue>& optionalParameters,
+ getKeyRequest_cb _hidl_cb) override;
+
+ Return<void> provideKeyResponse(const hidl_vec<uint8_t>& scope,
+ const hidl_vec<uint8_t>& response, provideKeyResponse_cb _hidl_cb)
+ override;
+
+ Return<Status> removeKeys(const hidl_vec<uint8_t>& sessionId) override;
+
+ Return<Status> restoreKeys(const hidl_vec<uint8_t>& sessionId,
+ const hidl_vec<uint8_t>& keySetId) override;
+
+ Return<void> queryKeyStatus(const hidl_vec<uint8_t>& sessionId,
+ queryKeyStatus_cb _hidl_cb) override;
+
+ Return<void> getProvisionRequest(const hidl_string& certificateType,
+ const hidl_string& certificateAuthority,
+ getProvisionRequest_cb _hidl_cb) override;
+
+ Return<void> provideProvisionResponse(const hidl_vec<uint8_t>& response,
+ provideProvisionResponse_cb _hidl_cb) override;
+
+ Return<void> getSecureStops(getSecureStops_cb _hidl_cb) override;
+
+ Return<void> getSecureStop(const hidl_vec<uint8_t>& secureStopId,
+ getSecureStop_cb _hidl_cb) override;
+
+ Return<Status> releaseAllSecureStops() override;
+
+ Return<Status> releaseSecureStop(const hidl_vec<uint8_t>& secureStopId)
+ override;
+
+ Return<void> getPropertyString(const hidl_string& propertyName,
+ getPropertyString_cb _hidl_cb) override;
+
+ Return<void> getPropertyByteArray(const hidl_string& propertyName,
+ getPropertyByteArray_cb _hidl_cb) override;
+
+ Return<Status> setPropertyString(const hidl_string& propertyName,
+ const hidl_string& value) override;
+
+ Return<Status> setPropertyByteArray(const hidl_string& propertyName,
+ const hidl_vec<uint8_t>& value) override;
+
+ Return<Status> setCipherAlgorithm(const hidl_vec<uint8_t>& sessionId,
+ const hidl_string& algorithm) override;
+
+ Return<Status> setMacAlgorithm(const hidl_vec<uint8_t>& sessionId,
+ const hidl_string& algorithm) override;
+
+ Return<void> encrypt(const hidl_vec<uint8_t>& sessionId,
+ const hidl_vec<uint8_t>& keyId, const hidl_vec<uint8_t>& input,
+ const hidl_vec<uint8_t>& iv, encrypt_cb _hidl_cb) override;
+
+ Return<void> decrypt(const hidl_vec<uint8_t>& sessionId,
+ const hidl_vec<uint8_t>& keyId, const hidl_vec<uint8_t>& input,
+ const hidl_vec<uint8_t>& iv, decrypt_cb _hidl_cb) override;
+
+ Return<void> sign(const hidl_vec<uint8_t>& sessionId,
+ const hidl_vec<uint8_t>& keyId, const hidl_vec<uint8_t>& message,
+ sign_cb _hidl_cb) override;
+
+ Return<void> verify(const hidl_vec<uint8_t>& sessionId,
+ const hidl_vec<uint8_t>& keyId, const hidl_vec<uint8_t>& message,
+ const hidl_vec<uint8_t>& signature, verify_cb _hidl_cb) override;
+
+ Return<void> signRSA(const hidl_vec<uint8_t>& sessionId,
+ const hidl_string& algorithm, const hidl_vec<uint8_t>& message,
+ const hidl_vec<uint8_t>& wrappedkey, signRSA_cb _hidl_cb) override;
+
+ Return<void> setListener(const sp<IDrmPluginListener>& listener) override;
+
+ Return<void> sendEvent(EventType eventType,
+ const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& data)
+ override;
+
+ Return<void> sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId,
+ int64_t expiryTimeInMS) override;
+
+ Return<void> sendKeysChange(const hidl_vec<uint8_t>& sessionId,
+ const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey)
+ override;
+
+ // Methods from android::DrmPluginListener follow
+
+ virtual void sendEvent(android::DrmPlugin::EventType eventType, int extra,
+ Vector<uint8_t> const *sessionId, Vector<uint8_t> const *data);
+
+ virtual void sendExpirationUpdate(Vector<uint8_t> const *sessionId,
+ int64_t expiryTimeInMS);
+
+ virtual void sendKeysChange(Vector<uint8_t> const *sessionId,
+ Vector<android::DrmPlugin::KeyStatus> const *keyStatusList,
+ bool hasNewUsableKey);
+
+private:
+ android::DrmPlugin *mLegacyPlugin;
+ sp<IDrmPluginListener> mListener;
+
+ DrmPlugin() = delete;
+ DrmPlugin(const DrmPlugin &) = delete;
+ void operator=(const DrmPlugin &) = delete;
+};
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace drm
+} // namespace drm
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_DRM_DRM_V1_0__DRMPLUGIN_H
diff --git a/drm/drm/1.0/default/TypeConvert.cpp b/drm/drm/1.0/default/TypeConvert.cpp
new file mode 100644
index 0000000..2b4e2a2
--- /dev/null
+++ b/drm/drm/1.0/default/TypeConvert.cpp
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "TypeConvert.h"
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace drm {
+namespace V1_0 {
+namespace implementation {
+
+Status toStatus(status_t legacyStatus) {
+ Status status;
+ switch(legacyStatus) {
+ case android::ERROR_DRM_NO_LICENSE:
+ status = Status::ERROR_DRM_NO_LICENSE;
+ break;
+ case android::ERROR_DRM_LICENSE_EXPIRED:
+ status = Status::ERROR_DRM_LICENSE_EXPIRED;
+ break;
+ case android::ERROR_DRM_SESSION_NOT_OPENED:
+ status = Status::ERROR_DRM_SESSION_NOT_OPENED;
+ break;
+ case android::ERROR_DRM_CANNOT_HANDLE:
+ status = Status::ERROR_DRM_CANNOT_HANDLE;
+ break;
+ case android::ERROR_DRM_TAMPER_DETECTED:
+ status = Status::ERROR_DRM_INVALID_STATE;
+ break;
+ case android::BAD_VALUE:
+ status = Status::BAD_VALUE;
+ break;
+ case android::ERROR_DRM_NOT_PROVISIONED:
+ status = Status::ERROR_DRM_NOT_PROVISIONED;
+ break;
+ case android::ERROR_DRM_RESOURCE_BUSY:
+ status = Status::ERROR_DRM_RESOURCE_BUSY;
+ break;
+ case android::ERROR_DRM_DEVICE_REVOKED:
+ status = Status::ERROR_DRM_DEVICE_REVOKED;
+ break;
+ default:
+ ALOGW("Unable to convert legacy status: %d, defaulting to UNKNOWN",
+ legacyStatus);
+ status = Status::ERROR_DRM_UNKNOWN;
+ break;
+ }
+ return status;
+}
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace drm
+} // namespace drm
+} // namespace hardware
+} // namespace android
diff --git a/drm/drm/1.0/default/TypeConvert.h b/drm/drm/1.0/default/TypeConvert.h
new file mode 100644
index 0000000..2f7875e
--- /dev/null
+++ b/drm/drm/1.0/default/TypeConvert.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_DRM_DRM_V1_0_TYPECONVERT
+#define ANDROID_HARDWARE_DRM_DRM_V1_0_TYPECONVERT
+
+#include <utils/Vector.h>
+#include <media/stagefright/MediaErrors.h>
+#include <media/drm/DrmAPI.h>
+
+#include <hidl/MQDescriptor.h>
+#include <android/hardware/drm/drm/1.0/types.h>
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace drm {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::hidl_vec;
+
+template<typename T> const hidl_vec<T> toHidlVec(const Vector<T> &Vector) {
+ hidl_vec<T> vec;
+ vec.setToExternal(const_cast<T *>(Vector.array()), Vector.size());
+ return vec;
+}
+
+template<typename T> hidl_vec<T> toHidlVec(Vector<T> &Vector) {
+ hidl_vec<T> vec;
+ vec.setToExternal(Vector.editArray(), Vector.size());
+ return vec;
+}
+
+template<typename T> const Vector<T> toVector(const hidl_vec<T> & vec) {
+ Vector<T> vector;
+ vector.appendArray(vec.data(), vec.size());
+ return *const_cast<const Vector<T> *>(&vector);
+}
+
+template<typename T> Vector<T> toVector(hidl_vec<T> &vec) {
+ Vector<T> vector;
+ vector.appendArray(vec.data(), vec.size());
+ return vector;
+}
+
+Status toStatus(status_t legacyStatus);
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace drm
+} // namespace drm
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_DRM_DRM_V1_0_TYPECONVERT
diff --git a/drm/drm/1.0/types.hal b/drm/drm/1.0/types.hal
index 05101c9..3d77911 100644
--- a/drm/drm/1.0/types.hal
+++ b/drm/drm/1.0/types.hal
@@ -161,6 +161,11 @@
* to become available for streaming.
*/
RELEASE,
+
+ /**
+ * Key request type is unknown due to some error condition.
+ */
+ UNKNOWN,
};
/**
diff --git a/graphics/composer/2.1/default/HwcClient.cpp b/graphics/composer/2.1/default/HwcClient.cpp
index 89945da..ce6c480 100644
--- a/graphics/composer/2.1/default/HwcClient.cpp
+++ b/graphics/composer/2.1/default/HwcClient.cpp
@@ -936,7 +936,7 @@
return false;
}
- auto err = mHal.setLayerPlaneAlpha(mDisplay, mLayer, read());
+ auto err = mHal.setLayerPlaneAlpha(mDisplay, mLayer, readFloat());
if (err != Error::NONE) {
mWriter.setError(getCommandLoc(), err);
}
diff --git a/graphics/composer/2.1/default/IComposerCommandBuffer.h b/graphics/composer/2.1/default/IComposerCommandBuffer.h
index 36654d0..8f133fe 100644
--- a/graphics/composer/2.1/default/IComposerCommandBuffer.h
+++ b/graphics/composer/2.1/default/IComposerCommandBuffer.h
@@ -35,7 +35,7 @@
#include <android/hardware/graphics/composer/2.1/IComposer.h>
#include <log/log.h>
#include <sync/sync.h>
-#include <MessageQueue.h>
+#include <fmq/MessageQueue.h>
namespace android {
namespace hardware {
diff --git a/ir/1.0/IConsumerIr.hal b/ir/1.0/IConsumerIr.hal
index f928c0e..f9e6316 100644
--- a/ir/1.0/IConsumerIr.hal
+++ b/ir/1.0/IConsumerIr.hal
@@ -28,7 +28,7 @@
*
* returns: true on success, false on error.
*/
- transmit(int32_t carrierFreq, vec<int32_t> pattern, int32_t patternLen) generates (bool success);
+ transmit(int32_t carrierFreq, vec<int32_t> pattern) generates (bool success);
/*
* getCarrierFreqs() enumerates which frequencies the IR transmitter supports.
diff --git a/ir/1.0/default/ConsumerIr.cpp b/ir/1.0/default/ConsumerIr.cpp
index 763e09a..8cfb2e8 100644
--- a/ir/1.0/default/ConsumerIr.cpp
+++ b/ir/1.0/default/ConsumerIr.cpp
@@ -32,8 +32,8 @@
}
// Methods from ::android::hardware::consumerir::V1_0::IConsumerIr follow.
-Return<bool> ConsumerIr::transmit(int32_t carrierFreq, const hidl_vec<int32_t>& pattern, int32_t patternLen) {
- return mDevice->transmit(mDevice, carrierFreq, pattern.data(), patternLen) == 0;
+Return<bool> ConsumerIr::transmit(int32_t carrierFreq, const hidl_vec<int32_t>& pattern) {
+ return mDevice->transmit(mDevice, carrierFreq, pattern.data(), pattern.size()) == 0;
}
Return<void> ConsumerIr::getCarrierFreqs(getCarrierFreqs_cb _hidl_cb) {
diff --git a/ir/1.0/default/ConsumerIr.h b/ir/1.0/default/ConsumerIr.h
index 527c577..1532183 100644
--- a/ir/1.0/default/ConsumerIr.h
+++ b/ir/1.0/default/ConsumerIr.h
@@ -40,7 +40,7 @@
struct ConsumerIr : public IConsumerIr {
ConsumerIr(consumerir_device_t *device);
// Methods from ::android::hardware::ir::V1_0::IConsumerIr follow.
- Return<bool> transmit(int32_t carrierFreq, const hidl_vec<int32_t>& pattern, int32_t patternLen) override;
+ Return<bool> transmit(int32_t carrierFreq, const hidl_vec<int32_t>& pattern) override;
Return<void> getCarrierFreqs(getCarrierFreqs_cb _hidl_cb) override;
private:
consumerir_device_t *mDevice;
diff --git a/keymaster/3.0/Android.bp b/keymaster/3.0/Android.bp
new file mode 100644
index 0000000..3c2034b
--- /dev/null
+++ b/keymaster/3.0/Android.bp
@@ -0,0 +1,56 @@
+// This file is autogenerated by hidl-gen. Do not edit manually.
+
+genrule {
+ name: "android.hardware.keymaster@3.0_genc++",
+ tools: ["hidl-gen"],
+ cmd: "$(location hidl-gen) -o $(genDir) -Lc++ -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.keymaster@3.0",
+ srcs: [
+ "types.hal",
+ "IKeymasterDevice.hal",
+ ],
+ out: [
+ "android/hardware/keymaster/3.0/types.cpp",
+ "android/hardware/keymaster/3.0/KeymasterDeviceAll.cpp",
+ ],
+}
+
+genrule {
+ name: "android.hardware.keymaster@3.0_genc++_headers",
+ tools: ["hidl-gen"],
+ cmd: "$(location hidl-gen) -o $(genDir) -Lc++ -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.keymaster@3.0",
+ srcs: [
+ "types.hal",
+ "IKeymasterDevice.hal",
+ ],
+ out: [
+ "android/hardware/keymaster/3.0/types.h",
+ "android/hardware/keymaster/3.0/IKeymasterDevice.h",
+ "android/hardware/keymaster/3.0/IHwKeymasterDevice.h",
+ "android/hardware/keymaster/3.0/BnKeymasterDevice.h",
+ "android/hardware/keymaster/3.0/BpKeymasterDevice.h",
+ "android/hardware/keymaster/3.0/BsKeymasterDevice.h",
+ ],
+}
+
+cc_library_shared {
+ name: "android.hardware.keymaster@3.0",
+ generated_sources: ["android.hardware.keymaster@3.0_genc++"],
+ generated_headers: ["android.hardware.keymaster@3.0_genc++_headers"],
+ export_generated_headers: ["android.hardware.keymaster@3.0_genc++_headers"],
+ shared_libs: [
+ "libhidlbase",
+ "libhidltransport",
+ "libhwbinder",
+ "liblog",
+ "libutils",
+ "libcutils",
+ "android.hidl.base@1.0",
+ ],
+ export_shared_lib_headers: [
+ "libhidlbase",
+ "libhidltransport",
+ "libhwbinder",
+ "libutils",
+ "android.hidl.base@1.0",
+ ],
+}
diff --git a/keymaster/3.0/IKeymasterDevice.hal b/keymaster/3.0/IKeymasterDevice.hal
new file mode 100644
index 0000000..19669c8
--- /dev/null
+++ b/keymaster/3.0/IKeymasterDevice.hal
@@ -0,0 +1,324 @@
+/*
+ * 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.keymaster@3.0;
+
+/**
+ * Keymaster device definition. For thorough documentation see the implementer's reference, at
+ * https://source.android.com/security/keystore/implementer-ref.html
+ */
+interface IKeymasterDevice {
+
+ /**
+ * Returns information about the underlying keymaster hardware.
+ *
+ * @return isSecure is true if keys are stored and never leave secure hardware (Trusted
+ * Execution Environment or similar). CDD requires that all devices initially
+ * launched with Marshmallow or later must have secure hardware.
+ *
+ * @return supportsEllipticCurve is true if the hardware supports Elliptic Curve cryptography
+ * with the NIST curves (P-224, P-256, P-384, and P-521). CDD requires that all
+ * devices initially launched with Nougat or later must support Elliptic Curve
+ * cryptography.
+ *
+ * @return supportsSymmetricCryptography is true if the hardware supports symmetric
+ * cryptography, including AES and HMAC. CDD requires that all devices initially
+ * launched with Nougat or later must support hardware enforcement of Keymaster
+ * authorizations.
+ *
+ * @return supportsAttestation is true if the hardware supports generation of Keymaster public
+ * key attestation certificates, signed with a key injected in a secure
+ * environment. CDD requires that all devices initially launched with Android O or
+ * later must support hardware attestation.
+ */
+ getHardwareFeatures()
+ generates(bool isSecure, bool supportsEllipticCurve,
+ bool supportsSymmetricCryptography, bool supportsAttestation);
+
+ /**
+ * Adds entropy to the RNG used by keymaster. Entropy added through this method is guaranteed
+ * not to be the only source of entropy used, and the mixing function is required to be secure,
+ * in the sense that if the RNG is seeded (from any source) with any data the attacker cannot
+ * predict (or control), then the RNG output is indistinguishable from random. Thus, if the
+ * entropy from any source is good, the output must be good.
+ *
+ * @param data Bytes to be mixed into the RNG.
+ *
+ * @return error See the ErrorCode enum in types.hal.
+ */
+ addRngEntropy(vec<uint8_t> data) generates(ErrorCode error);
+
+ /**
+ * Generates a key, or key pair, returning a key blob and/or a description of the key.
+ *
+ * @param keyParams Key generation parameters are defined as keymaster tag/value pairs, provided
+ * in params. See Tag in types.hal for the full list.
+ *
+ * @return error See the ErrorCode enum in types.hal.
+ *
+ * @return keyBlob Opaque, encrypted descriptor of the generated key, which generally contains a
+ * copy of the key material, wrapped in a key unavailable outside secure hardware.
+ *
+ * @return keyCharacteristics Description of the generated key. See KeyCharacteristis in
+ * types.hal.
+ */
+ generateKey(vec<KeyParameter> keyParams)
+ generates(ErrorCode error, vec<uint8_t> keyBlob, KeyCharacteristics keyCharacteristics);
+
+ /**
+ * Imports a key, or key pair, returning a key blob and/or a description of the key.
+ *
+ * @param keyParams Key generation parameters are defined as keymaster tag/value pairs, provided
+ * in params. See Tag for the full list.
+ *
+ * @param keyFormat The format of the key material to import. See KeyFormat in types.hal.
+ *
+ * @pram keyData The key material to import, in the format specifed in keyFormat.
+ *
+ * @return error See the ErrorCode enum.
+ *
+ * @return keyBlob Opaque, encrypted descriptor of the generated key, which will generally
+ * contain a copy of the key material, wrapped in a key unavailable outside secure
+ * hardware.
+ *
+ * @return keyCharacteristics Decription of the generated key. See KeyCharacteristis.
+ *
+ * @return error See the ErrorCode enum.
+ */
+ importKey(vec<KeyParameter> params, KeyFormat keyFormat, vec<uint8_t> keyData)
+ generates(ErrorCode error, vec<uint8_t> keyBlob, KeyCharacteristics keyCharacteristics);
+
+ /**
+ * Returns the characteristics of the specified key, if the keyBlob is valid (implementations
+ * must fully validate the integrity of the key).
+ *
+ * @param keyBlob The opaque descriptor returned by generateKey() or importKey();
+ *
+ * @param clientId An opaque byte string identifying the client. This value must match the
+ * Tag::APPLICATION_ID data provided during key generation/import. Without the
+ * correct value it must be cryptographically impossible for the secure hardware to
+ * obtain the key material.
+ *
+ * @param appData An opaque byte string provided by the application. This value must match the
+ * Tag::APPLICATION_DATA data provided during key generation/import. Without the
+ * correct value it must be cryptographically impossible for the secure hardware to
+ * obtain the key material.
+ *
+ * @return error See the ErrorCode enum in types.hal.
+ *
+ * @return keyCharacteristics Decription of the generated key. See KeyCharacteristis in
+ * types.hal.
+ */
+ getKeyCharacteristics(vec<uint8_t> keyBlob, vec<uint8_t> clientId, vec<uint8_t> appData)
+ generates(ErrorCode error, KeyCharacteristics keyCharacteristics);
+
+ /**
+ * Exports a public key, returning the key in the specified format.
+ *
+ * @parm keyFormat The format used for export. See KeyFormat in types.hal.
+ *
+ * @param keyBlob The opaque descriptor returned by generateKey() or importKey(). The
+ * referenced key must be asymmetric.
+ *
+ * @param clientId An opaque byte string identifying the client. This value must match the
+ * Tag::APPLICATION_ID data provided during key generation/import. Without the
+ * correct value it must be cryptographically impossible for the secure hardware to
+ * obtain the key material.
+ *
+ * @param appData An opaque byte string provided by the application. This value must match the
+ * Tag::APPLICATION_DATA data provided during key generation/import. Without the
+ * correct value it must be cryptographically impossible for the secure hardware to
+ * obtain the key material.
+ *
+ * @return error See the ErrorCode enum in types.hal.
+ *
+ * @return keyMaterial The public key material in PKCS#8 format.
+ */
+ exportKey(KeyFormat keyFormat, vec<uint8_t> keyBlob, vec<uint8_t> clientId,
+ vec<uint8_t> appData) generates(ErrorCode error, vec<uint8_t> keyMaterial);
+
+ /**
+ * Generates a signed X.509 certificate chain attesting to the presence of keyToAttest in
+ * keymaster. The certificate will contain an extension with OID 1.3.6.1.4.1.11129.2.1.17 and
+ * value defined in:
+ *
+ * https://developer.android.com/training/articles/security-key-attestation.html.
+ *
+ * @param keyToAttest The opaque descriptor returned by generateKey() or importKey(). The
+ * referenced key must be asymmetric.
+ *
+ * @param attestParams Parameters for the attestation, notably Tag::ATTESTATION_CHALLENGE.
+ *
+ * @return error See the ErrorCode enum in types.hal.
+ */
+ attestKey(vec<uint8_t> keyToAttest, vec<KeyParameter> attestParams)
+ generates(ErrorCode error, vec<vec<uint8_t>> certChain);
+
+ /**
+ * Upgrades an old key. Keys can become "old" in two ways: Keymaster can be upgraded to a new
+ * version, or the system can be updated to invalidate the OS version and/or patch level. In
+ * either case, attempts to use an old key with getKeyCharacteristics(), exportKey(),
+ * attestKey() or begin() will result in keymaster returning
+ * ErrorCode::KEY_REQUIRES_UPGRADE. This method must then be called to upgrade the key.
+ *
+ * @param keyBlobToUpgrade The opaque descriptor returned by generateKey() or importKey();
+ *
+ * @param upgradeParams A parameter list containing any parameters needed to complete the
+ * upgrade, including Tag::APPLICATION_ID and Tag::APPLICATION_DATA.
+ *
+ * @return error See the ErrorCode enum.
+ */
+ upgradeKey(vec<uint8_t> keyBlobToUpgrade, vec<KeyParameter> upgradeParams)
+ generates(ErrorCode error, vec<uint8_t> upgradedKeyBlob);
+
+ /**
+ * Deletes the key, or key pair, associated with the key blob. After calling this function it
+ * will be impossible to use the key for any other operations. May be applied to keys from
+ * foreign roots of trust (keys not usable under the current root of trust).
+ *
+ * This is a NOP for keys that don't have rollback protection.
+ *
+ * @param keyBlobToUpgrade The opaque descriptor returned by generateKey() or importKey();
+ *
+ * @return error See the ErrorCode enum.
+ */
+ deleteKey(vec<uint8_t> keyBlob) generates(ErrorCode error);
+
+ /**
+ * Deletes all keys in the hardware keystore. Used when keystore is reset completely. After
+ * calling this function it will be impossible to use any previously generated or imported key
+ * blobs for any operations.
+ *
+ * This is a NOP if keys don't have rollback protection.
+ *
+ * @return error See the ErrorCode enum.
+ */
+ deleteAllKeys() generates(ErrorCode error);
+
+ /**
+ * Begins a cryptographic operation using the specified key. If all is well, begin() will return
+ * ErrorCode::OK and create an operation handle which must be passed to subsequent calls to
+ * update(), finish() or abort().
+ *
+ * It is critical that each call to begin() be paired with a subsequent call to finish() or
+ * abort(), to allow the keymaster implementation to clean up any internal operation state.
+ * Failure to do this may leak internal state space or other internal resources and may
+ * eventually cause begin() to return ErrorCode::TOO_MANY_OPERATIONS when it runs out of space
+ * for operations. Any result other than ErrorCode::OK from begin(), update() or finish()
+ * implicitly aborts the operation, in which case abort() need not be called (and will return
+ * ErrorCode::INVALID_OPERATION_HANDLE if called).
+ *
+ * @param purpose The purpose of the operation, one of KeyPurpose::ENCRYPT, KeyPurpose::DECRYPT,
+ * KeyPurpose::SIGN or KeyPurpose::VERIFY. Note that for AEAD modes, encryption and
+ * decryption imply signing and verification, respectively, but must be specified as
+ * KeyPurpose::ENCRYPT and KeyPurpose::DECRYPT.
+ *
+ * @param keyBlob The opaque key descriptor returned by generateKey() or importKey(). The key
+ * must have a purpose compatible with purpose and all of its usage requirements
+ * must be satisfied, or begin() will return an appropriate error code.
+ *
+ * @param inParams Additional parameters for the operation. This is typically used to provide
+ * authentication data, with Tag::AUTH_TOKEN. If Tag::APPLICATION_ID or
+ * Tag::APPLICATION_DATA were provided during generation, they must be provided
+ * here, or the operation will fail with ErrorCode::INVALID_KEY_BLOB. For operations
+ * that require a nonce or IV, on keys that were generated with Tag::CALLER_NONCE,
+ * inParams may contain a tag Tag::NONCE.
+ *
+ * @return error See the ErrorCode enum in types.hal.
+ *
+ * @return outParams Output parameters. Used to return additional data from the operation
+ * initialization, notably to return the IV or nonce from operations that generate
+ * an IV or nonce.
+ *
+ * @return operationHandle The newly-created operation handle which must be passed to update(),
+ * finish() or abort().
+ */
+ begin(KeyPurpose purpose, vec<uint8_t> key, vec<KeyParameter> inParams)
+ generates(ErrorCode error, vec<KeyParameter> outParams, OperationHandle operationHandle);
+
+ /**
+ * Provides data to, and possibly receives output from, an ongoing cryptographic operation begun
+ * with begin().
+ *
+ * If operationHandle is invalid, update() will return ErrorCode::INVALID_OPERATION_HANDLE.
+ *
+ * update() may not consume all of the data provided in the data buffer. update() will return
+ * the amount consumed in inputConsumed. The caller may provide the unconsumed data in a
+ * subsequent call.
+ *
+ * @param operationHandle The operation handle returned by begin().
+ *
+ * @param inParams Additional parameters for the operation. For AEAD modes, this is used to
+ * specify Tag::ADDITIONAL_DATA. Note that additional data may be provided in
+ * multiple calls to update(), but only until input data has been provided.
+ *
+ * @param input Data to be processed, per the parameters established in the call to begin().
+ * Note that update() may or may not consume all of the data provided. See
+ * inputConsumed.
+ *
+ * @return error See the ErrorCode enum in types.hal.
+ *
+ * @return inputConsumed Amount of data that was consumed by update(). If this is less than the
+ * amount provided, the caller may provide the remainder in a subsequent call to
+ * update() or finish().
+ *
+ * @return outParams Output parameters, used to return additional data from the operation The
+ * caller takes ownership of the output parameters array and must free it with
+ * keymaster_free_param_set().
+ *
+ * @return output The output data, if any.
+ */
+ update(OperationHandle operationHandle, vec<KeyParameter> inParams, vec<uint8_t> input)
+ generates(ErrorCode error, uint32_t inputConsumed, vec<KeyParameter> outParams,
+ vec<uint8_t> output);
+
+ /**
+ * Finalizes a cryptographic operation begun with begin() and invalidates operationHandle.
+ *
+ * @param operationHandle The operation handle returned by begin(). This handle will be
+ * invalid when finish() returns.
+ *
+ * @param inParams Additional parameters for the operation. For AEAD modes, this is used to
+ * specify Tag::ADDITIONAL_DATA, but only if no input data was provided to update().
+ *
+ * @param input Data to be processed, per the parameters established in the call to
+ * begin(). finish() must consume all provided data or return
+ * ErrorCode::INVALID_INPUT_LENGTH.
+ *
+ * @param signature The signature to be verified if the purpose specified in the begin() call
+ * was KeyPurpose::VERIFY.
+ *
+ * @return error See the ErrorCode enum in types.hal.
+ *
+ * @return outParams Any output parameters generated by finish().
+ *
+ * @return output The output data, if any.
+ */
+ finish(OperationHandle operationHandle, vec<KeyParameter> inParams, vec<uint8_t> input,
+ vec<uint8_t> signature)
+ generates(ErrorCode error, vec<KeyParameter> outParams, vec<uint8_t> output);
+
+ /**
+ * Aborts a cryptographic operation begun with begin(), freeing all internal resources and
+ * invalidating operationHandle.
+ *
+ * @param operationHandle The operation handle returned by begin(). This handle will be
+ * invalid when abort() returns.
+ *
+ * @return error See the ErrorCode enum in types.hal.
+ */
+ abort(OperationHandle operationHandle) generates(ErrorCode error);
+};
diff --git a/keymaster/3.0/default/Android.mk b/keymaster/3.0/default/Android.mk
new file mode 100644
index 0000000..36d8890
--- /dev/null
+++ b/keymaster/3.0/default/Android.mk
@@ -0,0 +1,43 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hardware.keymaster@3.0-impl
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_SRC_FILES := \
+ KeymasterDevice.cpp \
+
+LOCAL_SHARED_LIBRARIES := \
+ liblog \
+ libsoftkeymasterdevice \
+ libcrypto \
+ libkeymaster1 \
+ libhidlbase \
+ libhidltransport \
+ libhwbinder \
+ libutils \
+ libhardware \
+ android.hardware.keymaster@3.0
+
+include $(BUILD_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_MODULE := android.hardware.keymaster@3.0-service
+LOCAL_INIT_RC := android.hardware.keymaster@3.0-service.rc
+LOCAL_SRC_FILES := \
+ service.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+ liblog \
+ libcutils \
+ libdl \
+ libbase \
+ libutils \
+ libhardware_legacy \
+ libhardware \
+ libhwbinder \
+ libhidlbase \
+ libhidltransport \
+ android.hardware.keymaster@3.0
+
+include $(BUILD_EXECUTABLE)
diff --git a/keymaster/3.0/default/KeymasterDevice.cpp b/keymaster/3.0/default/KeymasterDevice.cpp
new file mode 100644
index 0000000..1208b8d
--- /dev/null
+++ b/keymaster/3.0/default/KeymasterDevice.cpp
@@ -0,0 +1,691 @@
+/*
+ **
+ ** 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.
+ */
+
+#define LOG_TAG "android.hardware.keymaster@3.0-impl"
+
+#include "KeymasterDevice.h"
+
+#include <cutils/log.h>
+
+#include <hardware/keymaster_defs.h>
+#include <keymaster/keymaster_configuration.h>
+#include <keymaster/soft_keymaster_device.h>
+
+namespace android {
+namespace hardware {
+namespace keymaster {
+namespace V3_0 {
+namespace implementation {
+
+using ::keymaster::SoftKeymasterDevice;
+
+class SoftwareOnlyHidlKeymasterEnforcement : public ::keymaster::KeymasterEnforcement {
+ public:
+ SoftwareOnlyHidlKeymasterEnforcement() : KeymasterEnforcement(64, 64) {}
+
+ uint32_t get_current_time() const override {
+ struct timespec tp;
+ int err = clock_gettime(CLOCK_MONOTONIC, &tp);
+ if (err || tp.tv_sec < 0) return 0;
+ return static_cast<uint32_t>(tp.tv_sec);
+ }
+
+ bool activation_date_valid(uint64_t) const override { return true; }
+ bool expiration_date_passed(uint64_t) const override { return false; }
+ bool auth_token_timed_out(const hw_auth_token_t&, uint32_t) const override { return false; }
+ bool ValidateTokenSignature(const hw_auth_token_t&) const override { return true; }
+};
+
+class SoftwareOnlyHidlKeymasterContext : public ::keymaster::SoftKeymasterContext {
+ public:
+ SoftwareOnlyHidlKeymasterContext() : enforcement_(new SoftwareOnlyHidlKeymasterEnforcement) {}
+
+ ::keymaster::KeymasterEnforcement* enforcement_policy() override { return enforcement_.get(); }
+
+ private:
+ std::unique_ptr<::keymaster::KeymasterEnforcement> enforcement_;
+};
+
+static int keymaster0_device_initialize(const hw_module_t* mod, keymaster2_device_t** dev) {
+ assert(mod->module_api_version < KEYMASTER_MODULE_API_VERSION_1_0);
+ ALOGI("Found keymaster0 module %s, version %x", mod->name, mod->module_api_version);
+
+ UniquePtr<SoftKeymasterDevice> soft_keymaster(new SoftKeymasterDevice);
+ keymaster0_device_t* km0_device = NULL;
+ keymaster_error_t error = KM_ERROR_OK;
+
+ int rc = keymaster0_open(mod, &km0_device);
+ if (rc) {
+ ALOGE("Error opening keystore keymaster0 device.");
+ goto err;
+ }
+
+ if (km0_device->flags & KEYMASTER_SOFTWARE_ONLY) {
+ ALOGI("Keymaster0 module is software-only. Using SoftKeymasterDevice instead.");
+ km0_device->common.close(&km0_device->common);
+ km0_device = NULL;
+ // SoftKeymasterDevice will be deleted by keymaster_device_release()
+ *dev = soft_keymaster.release()->keymaster2_device();
+ return 0;
+ }
+
+ ALOGD("Wrapping keymaster0 module %s with SoftKeymasterDevice", mod->name);
+ error = soft_keymaster->SetHardwareDevice(km0_device);
+ km0_device = NULL; // SoftKeymasterDevice has taken ownership.
+ if (error != KM_ERROR_OK) {
+ ALOGE("Got error %d from SetHardwareDevice", error);
+ rc = error;
+ goto err;
+ }
+
+ // SoftKeymasterDevice will be deleted by keymaster_device_release()
+ *dev = soft_keymaster.release()->keymaster2_device();
+ return 0;
+
+err:
+ if (km0_device) km0_device->common.close(&km0_device->common);
+ *dev = NULL;
+ return rc;
+}
+
+static int keymaster1_device_initialize(const hw_module_t* mod, keymaster2_device_t** dev) {
+ assert(mod->module_api_version >= KEYMASTER_MODULE_API_VERSION_1_0);
+ ALOGI("Found keymaster1 module %s, version %x", mod->name, mod->module_api_version);
+
+ UniquePtr<SoftKeymasterDevice> soft_keymaster(new SoftKeymasterDevice);
+ keymaster1_device_t* km1_device = nullptr;
+ keymaster_error_t error = KM_ERROR_OK;
+
+ int rc = keymaster1_open(mod, &km1_device);
+ if (rc) {
+ ALOGE("Error %d opening keystore keymaster1 device", rc);
+ goto err;
+ }
+
+ ALOGD("Wrapping keymaster1 module %s with SofKeymasterDevice", mod->name);
+ error = soft_keymaster->SetHardwareDevice(km1_device);
+ km1_device = nullptr; // SoftKeymasterDevice has taken ownership.
+ if (error != KM_ERROR_OK) {
+ ALOGE("Got error %d from SetHardwareDevice", error);
+ rc = error;
+ goto err;
+ }
+
+ // SoftKeymasterDevice will be deleted by keymaster_device_release()
+ *dev = soft_keymaster.release()->keymaster2_device();
+ return 0;
+
+err:
+ if (km1_device) km1_device->common.close(&km1_device->common);
+ *dev = NULL;
+ return rc;
+}
+
+static int keymaster2_device_initialize(const hw_module_t* mod, keymaster2_device_t** dev) {
+ assert(mod->module_api_version >= KEYMASTER_MODULE_API_VERSION_2_0);
+ ALOGI("Found keymaster2 module %s, version %x", mod->name, mod->module_api_version);
+
+ keymaster2_device_t* km2_device = nullptr;
+
+ int rc = keymaster2_open(mod, &km2_device);
+ if (rc) {
+ ALOGE("Error %d opening keystore keymaster2 device", rc);
+ goto err;
+ }
+
+ *dev = km2_device;
+ return 0;
+
+err:
+ if (km2_device) km2_device->common.close(&km2_device->common);
+ *dev = nullptr;
+ return rc;
+}
+
+static int keymaster_device_initialize(keymaster2_device_t** dev, uint32_t* version,
+ bool* supports_ec) {
+ const hw_module_t* mod;
+
+ *supports_ec = true;
+
+ int rc = hw_get_module_by_class(KEYSTORE_HARDWARE_MODULE_ID, NULL, &mod);
+ if (rc) {
+ ALOGI("Could not find any keystore module, using software-only implementation.");
+ // SoftKeymasterDevice will be deleted by keymaster_device_release()
+ *dev = (new SoftKeymasterDevice(new SoftwareOnlyHidlKeymasterContext))->keymaster2_device();
+ *version = -1;
+ return 0;
+ }
+
+ if (mod->module_api_version < KEYMASTER_MODULE_API_VERSION_1_0) {
+ *version = 0;
+ int rc = keymaster0_device_initialize(mod, dev);
+ if (rc == 0 && ((*dev)->flags & KEYMASTER_SUPPORTS_EC) == 0) {
+ *supports_ec = false;
+ }
+ return rc;
+ } else if (mod->module_api_version == KEYMASTER_MODULE_API_VERSION_1_0) {
+ *version = 1;
+ return keymaster1_device_initialize(mod, dev);
+ } else {
+ *version = 2;
+ return keymaster2_device_initialize(mod, dev);
+ }
+}
+
+KeymasterDevice::~KeymasterDevice() {
+ if (keymaster_device_) keymaster_device_->common.close(&keymaster_device_->common);
+}
+
+static inline keymaster_tag_type_t typeFromTag(const keymaster_tag_t tag) {
+ return keymaster_tag_get_type(tag);
+}
+
+/**
+ * legacy_enum_conversion converts enums from hidl to keymaster and back. Currently, this is just a
+ * cast to make the compiler happy. One of two thigs should happen though:
+ * TODO The keymaster enums should become aliases for the hidl generated enums so that we have a
+ * single point of truth. Then this cast function can go away.
+ */
+inline static keymaster_tag_t legacy_enum_conversion(const Tag value) {
+ return keymaster_tag_t(value);
+}
+inline static Tag legacy_enum_conversion(const keymaster_tag_t value) {
+ return Tag(value);
+}
+inline static keymaster_purpose_t legacy_enum_conversion(const KeyPurpose value) {
+ return keymaster_purpose_t(value);
+}
+inline static keymaster_key_format_t legacy_enum_conversion(const KeyFormat value) {
+ return keymaster_key_format_t(value);
+}
+inline static ErrorCode legacy_enum_conversion(const keymaster_error_t value) {
+ return ErrorCode(value);
+}
+
+class KmParamSet : public keymaster_key_param_set_t {
+ public:
+ KmParamSet(const hidl_vec<KeyParameter>& keyParams) {
+ params = new keymaster_key_param_t[keyParams.size()];
+ length = keyParams.size();
+ for (size_t i = 0; i < keyParams.size(); ++i) {
+ auto tag = legacy_enum_conversion(keyParams[i].tag);
+ switch (typeFromTag(tag)) {
+ case KM_ENUM:
+ case KM_ENUM_REP:
+ params[i] = keymaster_param_enum(tag, keyParams[i].f.integer);
+ break;
+ case KM_UINT:
+ case KM_UINT_REP:
+ params[i] = keymaster_param_int(tag, keyParams[i].f.integer);
+ break;
+ case KM_ULONG:
+ case KM_ULONG_REP:
+ params[i] = keymaster_param_long(tag, keyParams[i].f.longInteger);
+ break;
+ case KM_DATE:
+ params[i] = keymaster_param_date(tag, keyParams[i].f.dateTime);
+ break;
+ case KM_BOOL:
+ if (keyParams[i].f.boolValue)
+ params[i] = keymaster_param_bool(tag);
+ else
+ params[i].tag = KM_TAG_INVALID;
+ break;
+ case KM_BIGNUM:
+ case KM_BYTES:
+ params[i] =
+ keymaster_param_blob(tag, &keyParams[i].blob[0], keyParams[i].blob.size());
+ break;
+ case KM_INVALID:
+ default:
+ params[i].tag = KM_TAG_INVALID;
+ /* just skip */
+ break;
+ }
+ }
+ }
+ KmParamSet(KmParamSet&& other) : keymaster_key_param_set_t{other.params, other.length} {
+ other.length = 0;
+ other.params = nullptr;
+ }
+ KmParamSet(const KmParamSet&) = delete;
+ ~KmParamSet() { delete[] params; }
+};
+
+inline static KmParamSet hidlParams2KmParamSet(const hidl_vec<KeyParameter>& params) {
+ return KmParamSet(params);
+}
+
+inline static keymaster_blob_t hidlVec2KmBlob(const hidl_vec<uint8_t>& blob) {
+ /* hidl unmarshals funny pointers if the the blob is empty */
+ if (blob.size()) return {&blob[0], blob.size()};
+ return {nullptr, 0};
+}
+
+inline static keymaster_key_blob_t hidlVec2KmKeyBlob(const hidl_vec<uint8_t>& blob) {
+ /* hidl unmarshals funny pointers if the the blob is empty */
+ if (blob.size()) return {&blob[0], blob.size()};
+ return {nullptr, 0};
+}
+
+inline static hidl_vec<uint8_t> kmBlob2hidlVec(const keymaster_key_blob_t& blob) {
+ hidl_vec<uint8_t> result;
+ result.setToExternal(const_cast<unsigned char*>(blob.key_material), blob.key_material_size);
+ return result;
+}
+inline static hidl_vec<uint8_t> kmBlob2hidlVec(const keymaster_blob_t& blob) {
+ hidl_vec<uint8_t> result;
+ result.setToExternal(const_cast<unsigned char*>(blob.data), blob.data_length);
+ return result;
+}
+
+inline static hidl_vec<hidl_vec<uint8_t>>
+kmCertChain2Hidl(const keymaster_cert_chain_t* cert_chain) {
+ hidl_vec<hidl_vec<uint8_t>> result;
+ if (!cert_chain || cert_chain->entry_count == 0 || !cert_chain->entries) return result;
+
+ result.resize(cert_chain->entry_count);
+ for (size_t i = 0; i < cert_chain->entry_count; ++i) {
+ auto& entry = cert_chain->entries[i];
+ result[i] = kmBlob2hidlVec(entry);
+ }
+
+ return result;
+}
+
+static inline hidl_vec<KeyParameter> kmParamSet2Hidl(const keymaster_key_param_set_t& set) {
+ hidl_vec<KeyParameter> result;
+ if (set.length == 0 || set.params == nullptr) return result;
+
+ result.resize(set.length);
+ keymaster_key_param_t* params = set.params;
+ for (size_t i = 0; i < set.length; ++i) {
+ auto tag = params[i].tag;
+ result[i].tag = legacy_enum_conversion(tag);
+ switch (typeFromTag(tag)) {
+ case KM_ENUM:
+ case KM_ENUM_REP:
+ result[i].f.integer = params[i].enumerated;
+ break;
+ case KM_UINT:
+ case KM_UINT_REP:
+ result[i].f.integer = params[i].integer;
+ break;
+ case KM_ULONG:
+ case KM_ULONG_REP:
+ result[i].f.longInteger = params[i].long_integer;
+ break;
+ case KM_DATE:
+ result[i].f.dateTime = params[i].date_time;
+ break;
+ case KM_BOOL:
+ result[i].f.boolValue = params[i].boolean;
+ break;
+ case KM_BIGNUM:
+ case KM_BYTES:
+ result[i].blob.setToExternal(const_cast<unsigned char*>(params[i].blob.data),
+ params[i].blob.data_length);
+ break;
+ case KM_INVALID:
+ default:
+ params[i].tag = KM_TAG_INVALID;
+ /* just skip */
+ break;
+ }
+ }
+ return result;
+}
+
+// Methods from ::android::hardware::keymaster::V3_0::IKeymasterDevice follow.
+Return<void> KeymasterDevice::getHardwareFeatures(getHardwareFeatures_cb _hidl_cb) {
+ bool is_secure = false;
+ bool supports_symmetric_cryptography = false;
+ bool supports_attestation = false;
+
+ switch (hardware_version_) {
+ case 2:
+ supports_attestation = true;
+ /* Falls through */
+ case 1:
+ supports_symmetric_cryptography = true;
+ /* Falls through */
+ case 0:
+ is_secure = true;
+ break;
+ };
+
+ _hidl_cb(is_secure, hardware_supports_ec_, supports_symmetric_cryptography,
+ supports_attestation);
+ return Void();
+}
+
+Return<ErrorCode> KeymasterDevice::addRngEntropy(const hidl_vec<uint8_t>& data) {
+ return legacy_enum_conversion(
+ keymaster_device_->add_rng_entropy(keymaster_device_, &data[0], data.size()));
+}
+
+Return<void> KeymasterDevice::generateKey(const hidl_vec<KeyParameter>& keyParams,
+ generateKey_cb _hidl_cb) {
+ // result variables for the wire
+ KeyCharacteristics resultCharacteristics;
+ hidl_vec<uint8_t> resultKeyBlob;
+
+ // result variables the backend understands
+ keymaster_key_blob_t key_blob{nullptr, 0};
+ keymaster_key_characteristics_t key_characteristics{{nullptr, 0}, {nullptr, 0}};
+
+ // convert the parameter set to something our backend understands
+ auto kmParams = hidlParams2KmParamSet(keyParams);
+
+ auto rc = keymaster_device_->generate_key(keymaster_device_, &kmParams, &key_blob,
+ &key_characteristics);
+
+ if (rc == KM_ERROR_OK) {
+ // on success convert the result to wire format
+ resultKeyBlob = kmBlob2hidlVec(key_blob);
+ resultCharacteristics.softwareEnforced = kmParamSet2Hidl(key_characteristics.sw_enforced);
+ resultCharacteristics.teeEnforced = kmParamSet2Hidl(key_characteristics.hw_enforced);
+ }
+
+ // send results off to the client
+ _hidl_cb(legacy_enum_conversion(rc), resultKeyBlob, resultCharacteristics);
+
+ // free buffers that we are responsible for
+ if (key_blob.key_material) free(const_cast<uint8_t*>(key_blob.key_material));
+ keymaster_free_characteristics(&key_characteristics);
+
+ return Void();
+}
+
+Return<void> KeymasterDevice::getKeyCharacteristics(const hidl_vec<uint8_t>& keyBlob,
+ const hidl_vec<uint8_t>& clientId,
+ const hidl_vec<uint8_t>& appData,
+ getKeyCharacteristics_cb _hidl_cb) {
+ // result variables for the wire
+ KeyCharacteristics resultCharacteristics;
+
+ // result variables the backend understands
+ keymaster_key_characteristics_t key_characteristics{{nullptr, 0}, {nullptr, 0}};
+
+ auto kmKeyBlob = hidlVec2KmKeyBlob(keyBlob);
+ auto kmClientId = hidlVec2KmBlob(clientId);
+ auto kmAppData = hidlVec2KmBlob(appData);
+
+ auto rc = keymaster_device_->get_key_characteristics(
+ keymaster_device_, keyBlob.size() ? &kmKeyBlob : nullptr,
+ clientId.size() ? &kmClientId : nullptr, appData.size() ? &kmAppData : nullptr,
+ &key_characteristics);
+
+ if (rc == KM_ERROR_OK) {
+ resultCharacteristics.softwareEnforced = kmParamSet2Hidl(key_characteristics.sw_enforced);
+ resultCharacteristics.teeEnforced = kmParamSet2Hidl(key_characteristics.hw_enforced);
+ }
+
+ _hidl_cb(legacy_enum_conversion(rc), resultCharacteristics);
+
+ keymaster_free_characteristics(&key_characteristics);
+
+ return Void();
+}
+
+Return<void> KeymasterDevice::importKey(const hidl_vec<KeyParameter>& params, KeyFormat keyFormat,
+ const hidl_vec<uint8_t>& keyData, importKey_cb _hidl_cb) {
+ // result variables for the wire
+ KeyCharacteristics resultCharacteristics;
+ hidl_vec<uint8_t> resultKeyBlob;
+
+ // result variables the backend understands
+ keymaster_key_blob_t key_blob{nullptr, 0};
+ keymaster_key_characteristics_t key_characteristics{{nullptr, 0}, {nullptr, 0}};
+
+ auto kmParams = hidlParams2KmParamSet(params);
+ auto kmKeyData = hidlVec2KmBlob(keyData);
+
+ auto rc = keymaster_device_->import_key(keymaster_device_, &kmParams,
+ legacy_enum_conversion(keyFormat), &kmKeyData,
+ &key_blob, &key_characteristics);
+
+ if (rc == KM_ERROR_OK) {
+ // on success convert the result to wire format
+ // (Can we assume that key_blob is {nullptr, 0} or a valid buffer description?)
+ resultKeyBlob = kmBlob2hidlVec(key_blob);
+ resultCharacteristics.softwareEnforced = kmParamSet2Hidl(key_characteristics.sw_enforced);
+ resultCharacteristics.teeEnforced = kmParamSet2Hidl(key_characteristics.hw_enforced);
+ }
+
+ _hidl_cb(legacy_enum_conversion(rc), resultKeyBlob, resultCharacteristics);
+
+ // free buffers that we are responsible for
+ if (key_blob.key_material) free(const_cast<uint8_t*>(key_blob.key_material));
+ keymaster_free_characteristics(&key_characteristics);
+
+ return Void();
+}
+
+Return<void> KeymasterDevice::exportKey(KeyFormat exportFormat, const hidl_vec<uint8_t>& keyBlob,
+ const hidl_vec<uint8_t>& clientId,
+ const hidl_vec<uint8_t>& appData, exportKey_cb _hidl_cb) {
+
+ // result variables for the wire
+ hidl_vec<uint8_t> resultKeyBlob;
+
+ // result variables the backend understands
+ keymaster_blob_t out_blob{nullptr, 0};
+
+ auto kmKeyBlob = hidlVec2KmKeyBlob(keyBlob);
+ auto kmClientId = hidlVec2KmBlob(clientId);
+ auto kmAppData = hidlVec2KmBlob(appData);
+
+ auto rc = keymaster_device_->export_key(keymaster_device_, legacy_enum_conversion(exportFormat),
+ keyBlob.size() ? &kmKeyBlob : nullptr,
+ clientId.size() ? &kmClientId : nullptr,
+ appData.size() ? &kmAppData : nullptr, &out_blob);
+
+ if (rc == KM_ERROR_OK) {
+ // on success convert the result to wire format
+ // (Can we assume that key_blob is {nullptr, 0} or a valid buffer description?)
+ resultKeyBlob = kmBlob2hidlVec(out_blob);
+ }
+
+ _hidl_cb(legacy_enum_conversion(rc), resultKeyBlob);
+
+ // free buffers that we are responsible for
+ if (out_blob.data) free(const_cast<uint8_t*>(out_blob.data));
+
+ return Void();
+}
+
+Return<void> KeymasterDevice::attestKey(const hidl_vec<uint8_t>& keyToAttest,
+ const hidl_vec<KeyParameter>& attestParams,
+ attestKey_cb _hidl_cb) {
+
+ hidl_vec<hidl_vec<uint8_t>> resultCertChain;
+
+ keymaster_cert_chain_t cert_chain{nullptr, 0};
+
+ auto kmKeyToAttest = hidlVec2KmKeyBlob(keyToAttest);
+ auto kmAttestParams = hidlParams2KmParamSet(attestParams);
+
+ auto rc = keymaster_device_->attest_key(keymaster_device_, &kmKeyToAttest, &kmAttestParams,
+ &cert_chain);
+
+ if (rc == KM_ERROR_OK) {
+ resultCertChain = kmCertChain2Hidl(&cert_chain);
+ }
+
+ _hidl_cb(legacy_enum_conversion(rc), resultCertChain);
+
+ keymaster_free_cert_chain(&cert_chain);
+
+ return Void();
+}
+
+Return<void> KeymasterDevice::upgradeKey(const hidl_vec<uint8_t>& keyBlobToUpgrade,
+ const hidl_vec<KeyParameter>& upgradeParams,
+ upgradeKey_cb _hidl_cb) {
+
+ // result variables for the wire
+ hidl_vec<uint8_t> resultKeyBlob;
+
+ // result variables the backend understands
+ keymaster_key_blob_t key_blob{nullptr, 0};
+
+ auto kmKeyBlobToUpgrade = hidlVec2KmKeyBlob(keyBlobToUpgrade);
+ auto kmUpgradeParams = hidlParams2KmParamSet(upgradeParams);
+
+ auto rc = keymaster_device_->upgrade_key(keymaster_device_, &kmKeyBlobToUpgrade,
+ &kmUpgradeParams, &key_blob);
+
+ if (rc == KM_ERROR_OK) {
+ // on success convert the result to wire format
+ resultKeyBlob = kmBlob2hidlVec(key_blob);
+ }
+
+ _hidl_cb(legacy_enum_conversion(rc), resultKeyBlob);
+
+ if (key_blob.key_material) free(const_cast<uint8_t*>(key_blob.key_material));
+
+ return Void();
+}
+
+Return<ErrorCode> KeymasterDevice::deleteKey(const hidl_vec<uint8_t>& keyBlob) {
+ auto kmKeyBlob = hidlVec2KmKeyBlob(keyBlob);
+ return legacy_enum_conversion(keymaster_device_->delete_key(keymaster_device_, &kmKeyBlob));
+}
+
+Return<ErrorCode> KeymasterDevice::deleteAllKeys() {
+ return legacy_enum_conversion(keymaster_device_->delete_all_keys(keymaster_device_));
+}
+
+Return<void> KeymasterDevice::begin(KeyPurpose purpose, const hidl_vec<uint8_t>& key,
+ const hidl_vec<KeyParameter>& inParams, begin_cb _hidl_cb) {
+
+ // result variables for the wire
+ hidl_vec<KeyParameter> resultParams;
+ uint64_t resultOpHandle = 0;
+
+ // result variables the backend understands
+ keymaster_key_param_set_t out_params{nullptr, 0};
+ keymaster_operation_handle_t& operation_handle = resultOpHandle;
+
+ auto kmKey = hidlVec2KmKeyBlob(key);
+ auto kmInParams = hidlParams2KmParamSet(inParams);
+
+ auto rc = keymaster_device_->begin(keymaster_device_, legacy_enum_conversion(purpose), &kmKey,
+ &kmInParams, &out_params, &operation_handle);
+
+ if (rc == KM_ERROR_OK) resultParams = kmParamSet2Hidl(out_params);
+
+ _hidl_cb(legacy_enum_conversion(rc), resultParams, resultOpHandle);
+
+ keymaster_free_param_set(&out_params);
+
+ return Void();
+}
+
+Return<void> KeymasterDevice::update(uint64_t operationHandle,
+ const hidl_vec<KeyParameter>& inParams,
+ const hidl_vec<uint8_t>& input, update_cb _hidl_cb) {
+ // result variables for the wire
+ uint32_t resultConsumed = 0;
+ hidl_vec<KeyParameter> resultParams;
+ hidl_vec<uint8_t> resultBlob;
+
+ // result variables the backend understands
+ size_t consumed = 0;
+ keymaster_key_param_set_t out_params{nullptr, 0};
+ keymaster_blob_t out_blob{nullptr, 0};
+
+ auto kmInParams = hidlParams2KmParamSet(inParams);
+ auto kmInput = hidlVec2KmBlob(input);
+
+ auto rc = keymaster_device_->update(keymaster_device_, operationHandle, &kmInParams, &kmInput,
+ &consumed, &out_params, &out_blob);
+
+ if (rc == KM_ERROR_OK) {
+ resultConsumed = consumed;
+ resultParams = kmParamSet2Hidl(out_params);
+ resultBlob = kmBlob2hidlVec(out_blob);
+ }
+
+ _hidl_cb(legacy_enum_conversion(rc), resultConsumed, resultParams, resultBlob);
+
+ keymaster_free_param_set(&out_params);
+ if (out_blob.data) free(const_cast<uint8_t*>(out_blob.data));
+
+ return Void();
+}
+
+Return<void> KeymasterDevice::finish(uint64_t operationHandle,
+ const hidl_vec<KeyParameter>& inParams,
+ const hidl_vec<uint8_t>& input,
+ const hidl_vec<uint8_t>& signature, finish_cb _hidl_cb) {
+ // result variables for the wire
+ hidl_vec<KeyParameter> resultParams;
+ hidl_vec<uint8_t> resultBlob;
+
+ // result variables the backend understands
+ keymaster_key_param_set_t out_params{nullptr, 0};
+ keymaster_blob_t out_blob{nullptr, 0};
+
+ auto kmInParams = hidlParams2KmParamSet(inParams);
+ auto kmInput = hidlVec2KmBlob(input);
+ auto kmSignature = hidlVec2KmBlob(signature);
+
+ auto rc = keymaster_device_->finish(keymaster_device_, operationHandle, &kmInParams, &kmInput,
+ &kmSignature, &out_params, &out_blob);
+
+ if (rc == KM_ERROR_OK) {
+ resultParams = kmParamSet2Hidl(out_params);
+ resultBlob = kmBlob2hidlVec(out_blob);
+ }
+
+ _hidl_cb(legacy_enum_conversion(rc), resultParams, resultBlob);
+
+ keymaster_free_param_set(&out_params);
+ if (out_blob.data) free(const_cast<uint8_t*>(out_blob.data));
+
+ return Void();
+}
+
+Return<ErrorCode> KeymasterDevice::abort(uint64_t operationHandle) {
+ return legacy_enum_conversion(keymaster_device_->abort(keymaster_device_, operationHandle));
+}
+
+IKeymasterDevice* HIDL_FETCH_IKeymasterDevice(const char* /* name */) {
+ keymaster2_device_t* dev = nullptr;
+
+ uint32_t version;
+ bool supports_ec;
+ auto rc = keymaster_device_initialize(&dev, &version, &supports_ec);
+ if (rc) return nullptr;
+
+ auto kmrc = ::keymaster::ConfigureDevice(dev);
+ if (kmrc != KM_ERROR_OK) {
+ dev->common.close(&dev->common);
+ return nullptr;
+ }
+
+ return new KeymasterDevice(dev, version, supports_ec);
+}
+
+} // namespace implementation
+} // namespace V3_0
+} // namespace keymaster
+} // namespace hardware
+} // namespace android
diff --git a/keymaster/3.0/default/KeymasterDevice.h b/keymaster/3.0/default/KeymasterDevice.h
new file mode 100644
index 0000000..23767ef
--- /dev/null
+++ b/keymaster/3.0/default/KeymasterDevice.h
@@ -0,0 +1,97 @@
+/*
+ **
+ ** 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 HIDL_GENERATED_android_hardware_keymaster_V3_0_KeymasterDevice_H_
+#define HIDL_GENERATED_android_hardware_keymaster_V3_0_KeymasterDevice_H_
+
+#include <hardware/keymaster2.h>
+
+#include <android/hardware/keymaster/3.0/IKeymasterDevice.h>
+#include <hidl/Status.h>
+
+#include <hidl/MQDescriptor.h>
+namespace android {
+namespace hardware {
+namespace keymaster {
+namespace V3_0 {
+namespace implementation {
+
+using ::android::hardware::keymaster::V3_0::ErrorCode;
+using ::android::hardware::keymaster::V3_0::IKeymasterDevice;
+using ::android::hardware::keymaster::V3_0::KeyCharacteristics;
+using ::android::hardware::keymaster::V3_0::KeyFormat;
+using ::android::hardware::keymaster::V3_0::KeyParameter;
+using ::android::hardware::keymaster::V3_0::KeyPurpose;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+class KeymasterDevice : public IKeymasterDevice {
+ public:
+ KeymasterDevice(keymaster2_device_t* dev, uint32_t hardware_version, bool hardware_supports_ec)
+ : keymaster_device_(dev), hardware_version_(hardware_version),
+ hardware_supports_ec_(hardware_supports_ec) {}
+ virtual ~KeymasterDevice();
+
+ // Methods from ::android::hardware::keymaster::V3_0::IKeymasterDevice follow.
+ Return<void> getHardwareFeatures(getHardwareFeatures_cb _hidl_cb);
+ Return<ErrorCode> addRngEntropy(const hidl_vec<uint8_t>& data) override;
+ Return<void> generateKey(const hidl_vec<KeyParameter>& keyParams,
+ generateKey_cb _hidl_cb) override;
+ Return<void> getKeyCharacteristics(const hidl_vec<uint8_t>& keyBlob,
+ const hidl_vec<uint8_t>& clientId,
+ const hidl_vec<uint8_t>& appData,
+ getKeyCharacteristics_cb _hidl_cb) override;
+ Return<void> importKey(const hidl_vec<KeyParameter>& params, KeyFormat keyFormat,
+ const hidl_vec<uint8_t>& keyData, importKey_cb _hidl_cb) override;
+ Return<void> exportKey(KeyFormat exportFormat, const hidl_vec<uint8_t>& keyBlob,
+ const hidl_vec<uint8_t>& clientId, const hidl_vec<uint8_t>& appData,
+ exportKey_cb _hidl_cb) override;
+ Return<void> attestKey(const hidl_vec<uint8_t>& keyToAttest,
+ const hidl_vec<KeyParameter>& attestParams,
+ attestKey_cb _hidl_cb) override;
+ Return<void> upgradeKey(const hidl_vec<uint8_t>& keyBlobToUpgrade,
+ const hidl_vec<KeyParameter>& upgradeParams,
+ upgradeKey_cb _hidl_cb) override;
+ Return<ErrorCode> deleteKey(const hidl_vec<uint8_t>& keyBlob) override;
+ Return<ErrorCode> deleteAllKeys() override;
+ Return<void> begin(KeyPurpose purpose, const hidl_vec<uint8_t>& key,
+ const hidl_vec<KeyParameter>& inParams, begin_cb _hidl_cb) override;
+ Return<void> update(uint64_t operationHandle, const hidl_vec<KeyParameter>& inParams,
+ const hidl_vec<uint8_t>& input, update_cb _hidl_cb) override;
+ Return<void> finish(uint64_t operationHandle, const hidl_vec<KeyParameter>& inParams,
+ const hidl_vec<uint8_t>& input, const hidl_vec<uint8_t>& signature,
+ finish_cb _hidl_cb) override;
+ Return<ErrorCode> abort(uint64_t operationHandle) override;
+
+ private:
+ keymaster2_device_t* keymaster_device_;
+ uint32_t hardware_version_;
+ bool hardware_supports_ec_;
+};
+
+extern "C" IKeymasterDevice* HIDL_FETCH_IKeymasterDevice(const char* name);
+
+} // namespace implementation
+} // namespace V3_0
+} // namespace keymaster
+} // namespace hardware
+} // namespace android
+
+#endif // HIDL_GENERATED_android_hardware_keymaster_V3_0_KeymasterDevice_H_
diff --git a/keymaster/3.0/default/android.hardware.keymaster@3.0-service.rc b/keymaster/3.0/default/android.hardware.keymaster@3.0-service.rc
new file mode 100644
index 0000000..86ed1e7
--- /dev/null
+++ b/keymaster/3.0/default/android.hardware.keymaster@3.0-service.rc
@@ -0,0 +1,4 @@
+service keymaster-3-0 /system/bin/hw/android.hardware.keymaster@3.0-service
+ class hal
+ user system
+ group system drmrpc
diff --git a/keymaster/3.0/default/service.cpp b/keymaster/3.0/default/service.cpp
new file mode 100644
index 0000000..038bf31
--- /dev/null
+++ b/keymaster/3.0/default/service.cpp
@@ -0,0 +1,33 @@
+/*
+**
+** 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.
+*/
+
+#define LOG_TAG "android.hardware.keymaster@3.0-service"
+
+#include <android/hardware/keymaster/3.0/IKeymasterDevice.h>
+
+#include <hidl/LegacySupport.h>
+
+using android::sp;
+
+using android::hardware::keymaster::V3_0::IKeymasterDevice;
+using android::hardware::registerPassthroughServiceImplementation;
+using android::hardware::launchRpcServer;
+
+int main() {
+ registerPassthroughServiceImplementation<IKeymasterDevice>("keymaster");
+ return launchRpcServer(1);
+}
diff --git a/keymaster/3.0/types.hal b/keymaster/3.0/types.hal
new file mode 100644
index 0000000..e99e9c8
--- /dev/null
+++ b/keymaster/3.0/types.hal
@@ -0,0 +1,414 @@
+/*
+ * 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.keymaster@3.0;
+
+enum TagType : uint32_t {
+ INVALID = 0 << 28, /* Invalid type, used to designate a tag as uninitialized */
+ ENUM = 1 << 28,
+ ENUM_REP = 2 << 28, /* Repeatable enumeration value. */
+ UINT = 3 << 28,
+ UINT_REP = 4 << 28, /* Repeatable integer value */
+ ULONG = 5 << 28,
+ DATE = 6 << 28,
+ BOOL = 7 << 28,
+ BIGNUM = 8 << 28,
+ BYTES = 9 << 28,
+ ULONG_REP = 10 << 28, /* Repeatable long value */
+};
+
+enum Tag : uint32_t {
+ INVALID = TagType:INVALID | 0,
+
+ /*
+ * Tags that must be semantically enforced by hardware and software implementations.
+ */
+
+ /* Crypto parameters */
+ PURPOSE = TagType:ENUM_REP | 1, /* KeyPurpose. */
+ ALGORITHM = TagType:ENUM | 2, /* Algorithm. */
+ KEY_SIZE = TagType:UINT | 3, /* Key size in bits. */
+ BLOCK_MODE = TagType:ENUM_REP | 4, /* BlockMode. */
+ DIGEST = TagType:ENUM_REP | 5, /* Digest. */
+ PADDING = TagType:ENUM_REP | 6, /* PaddingMode. */
+ CALLER_NONCE = TagType:BOOL | 7, /* Allow caller to specify nonce or IV. */
+ MIN_MAC_LENGTH = TagType:UINT | 8, /* Minimum length of MAC or AEAD authentication tag in
+ * bits. */
+ KDF = TagType:ENUM_REP | 9, /* KeyDerivationFunction. */
+ EC_CURVE = TagType:ENUM | 10, /* EcCurve. */
+
+ /* Algorithm-specific. */
+ RSA_PUBLIC_EXPONENT = TagType:ULONG | 200,
+ ECIES_SINGLE_HASH_MODE = TagType:BOOL | 201, /* Whether the ephemeral public key is fed into the
+ * KDF. */
+ INCLUDE_UNIQUE_ID = TagType:BOOL | 202, /* If true, attestation certificates for this key
+ * will contain an application-scoped and
+ * time-bounded device-unique ID.*/
+
+ /* Other hardware-enforced. */
+ BLOB_USAGE_REQUIREMENTS = TagType:ENUM | 301, /* KeyBlobUsageRequirements. */
+ BOOTLOADER_ONLY = TagType:BOOL | 302, /* Usable only by bootloader. */
+
+ /*
+ * Tags that should be semantically enforced by hardware if possible and will otherwise be
+ * enforced by software (keystore).
+ */
+
+ /* Key validity period */
+ ACTIVE_DATETIME = TagType:DATE | 400, /* Start of validity. */
+ ORIGINATION_EXPIRE_DATETIME = TagType:DATE | 401, /* Date when new "messages" should no longer
+ * be created. */
+ USAGE_EXPIRE_DATETIME = TagType:DATE | 402, /* Date when existing "messages" should no
+ * longer be trusted. */
+ MIN_SECONDS_BETWEEN_OPS = TagType:UINT | 403, /* Minimum elapsed time between
+ * cryptographic operations with the key. */
+ MAX_USES_PER_BOOT = TagType:UINT | 404, /* Number of times the key can be used per
+ * boot. */
+
+ /* User authentication */
+ ALL_USERS = TagType:BOOL | 500, /* Reserved for future use -- ignore. */
+ USER_ID = TagType:UINT | 501, /* Reserved for future use -- ignore. */
+ USER_SECURE_ID = TagType:ULONG_REP | 502, /* Secure ID of authorized user or authenticator(s).
+ * Disallowed if ALL_USERS or NO_AUTH_REQUIRED is
+ * present. */
+ NO_AUTH_REQUIRED = TagType:BOOL | 503, /* If key is usable without authentication. */
+ USER_AUTH_TYPE = TagType:ENUM | 504, /* Bitmask of authenticator types allowed when
+ * USER_SECURE_ID contains a secure user ID, rather
+ * than a secure authenticator ID. Defined in
+ * HardwareAuthenticatorType. */
+ AUTH_TIMEOUT = TagType:UINT | 505, /* Required freshness of user authentication for
+ * private/secret key operations, in seconds. Public
+ * key operations require no authentication. If
+ * absent, authentication is required for every use.
+ * Authentication state is lost when the device is
+ * powered off. */
+ ALLOW_WHILE_ON_BODY = TagType:BOOL | 506, /* Allow key to be used after authentication timeout
+ * if device is still on-body (requires secure on-body
+ * sensor. */
+
+ /* Application access control */
+ ALL_APPLICATIONS = TagType:BOOL | 600, /* Specified to indicate key is usable by all
+ * applications. */
+ APPLICATION_ID = TagType:BYTES | 601, /* Byte string identifying the authorized application. */
+ EXPORTABLE = TagType:BOOL | 602, /* If true, private/secret key can be exported, but only
+ * if all access control requirements for use are
+ * met. (keymaster2) */
+
+ /*
+ * Semantically unenforceable tags, either because they have no specific meaning or because
+ * they're informational only.
+ */
+ APPLICATION_DATA = TagType:BYTES | 700, /* Data provided by authorized application. */
+ CREATION_DATETIME = TagType:DATE | 701, /* Key creation time */
+ ORIGIN = TagType:ENUM | 702, /* keymaster_key_origin_t. */
+ ROLLBACK_RESISTANT = TagType:BOOL | 703, /* Whether key is rollback-resistant. */
+ ROOT_OF_TRUST = TagType:BYTES | 704, /* Root of trust ID. */
+ OS_VERSION = TagType:UINT | 705, /* Version of system (keymaster2) */
+ OS_PATCHLEVEL = TagType:UINT | 706, /* Patch level of system (keymaster2) */
+ UNIQUE_ID = TagType:BYTES | 707, /* Used to provide unique ID in attestation */
+ ATTESTATION_CHALLENGE = TagType:BYTES | 708, /* Used to provide challenge in attestation */
+ ATTESTATION_APPLICATION_ID = TagType:BYTES | 709, /* Used to identify the set of possible
+ * applications of which one has initiated a
+ * key attestation */
+
+ /* Tags used only to provide data to or receive data from operations */
+ ASSOCIATED_DATA = TagType:BYTES | 1000, /* Used to provide associated data for AEAD modes. */
+ NONCE = TagType:BYTES | 1001, /* Nonce or Initialization Vector */
+ AUTH_TOKEN = TagType:BYTES | 1002, /* Authentication token that proves secure user
+ * authentication has been performed. Structure defined
+ * in hw_auth_token_t in hw_auth_token.h. */
+ MAC_LENGTH = TagType:UINT | 1003, /* MAC or AEAD authentication tag length in bits. */
+
+ RESET_SINCE_ID_ROTATION = TagType:BOOL | 1004, /* Whether the device has beeen factory reset
+ * since the last unique ID rotation. Used for
+ * key attestation. */
+};
+
+enum Algorithm : uint32_t {
+ /* Asymmetric algorithms. */
+ RSA = 1,
+ // DSA = 2, -- Removed, do not re-use value 2.
+ EC = 3,
+
+ /* Block ciphers algorithms */
+ AES = 32,
+
+ /* MAC algorithms */
+ HMAC = 128,
+};
+
+/**
+ * Symmetric block cipher modes provided by keymaster implementations.
+ */
+enum BlockMode : uint32_t {
+ /* Unauthenticated modes, usable only for encryption/decryption and not generally recommended
+ * except for compatibility with existing other protocols. */
+ ECB = 1,
+ CBC = 2,
+ CTR = 3,
+
+ /* Authenticated modes, usable for encryption/decryption and signing/verification. Recommended
+ * over unauthenticated modes for all purposes. */
+ GCM = 32,
+};
+
+/**
+ * Padding modes that may be applied to plaintext for encryption operations. This list includes
+ * padding modes for both symmetric and asymmetric algorithms. Note that implementations should not
+ * provide all possible combinations of algorithm and padding, only the
+ * cryptographically-appropriate pairs.
+ */
+enum PaddingMode : uint32_t {
+ NONE = 1, /* deprecated */
+ RSA_OAEP = 2,
+ RSA_PSS = 3,
+ RSA_PKCS1_1_5_ENCRYPT = 4,
+ RSA_PKCS1_1_5_SIGN = 5,
+ PKCS7 = 64,
+};
+
+/**
+ * Digests provided by keymaster implementations.
+ */
+enum Digest : uint32_t {
+ NONE = 0,
+ MD5 = 1, /* Optional, may not be implemented in hardware, will be handled in software if
+ * needed. */
+ SHA1 = 2,
+ SHA_2_224 = 3,
+ SHA_2_256 = 4,
+ SHA_2_384 = 5,
+ SHA_2_512 = 6,
+};
+
+/**
+ * Supported EC curves, used in ECDSA
+ */
+enum EcCurve : uint32_t {
+ P_224 = 0,
+ P_256 = 1,
+ P_384 = 2,
+ P_521 = 3,
+};
+
+/**
+ * The origin of a key (or pair), i.e. where it was generated. Note that ORIGIN can be found in
+ * either the hardware-enforced or software-enforced list for a key, indicating whether the key is
+ * hardware or software-based. Specifically, a key with GENERATED in the hardware-enforced list is
+ * guaranteed never to have existed outide the secure hardware.
+ */
+enum KeyOrigin : uint32_t {
+ GENERATED = 0, /* Generated in keymaster. Should not exist outside the TEE. */
+ DERIVED = 1, /* Derived inside keymaster. Likely exists off-device. */
+ IMPORTED = 2, /* Imported into keymaster. Existed as cleartext in Android. */
+ UNKNOWN = 3, /* Keymaster did not record origin. This value can only be seen on keys in a
+ * keymaster0 implementation. The keymaster0 adapter uses this value to document
+ * the fact that it is unkown whether the key was generated inside or imported
+ * into keymaster. */
+};
+
+/**
+ * Usability requirements of key blobs. This defines what system functionality must be available
+ * for the key to function. For example, key "blobs" which are actually handles referencing
+ * encrypted key material stored in the file system cannot be used until the file system is
+ * available, and should have BLOB_REQUIRES_FILE_SYSTEM. Other requirements entries will be added
+ * as needed for implementations.
+ */
+enum KeyBlobUsageRequirements : uint32_t {
+ STANDALONE = 0,
+ REQUIRES_FILE_SYSTEM = 1,
+};
+
+/**
+ * Possible purposes of a key (or pair).
+ */
+enum KeyPurpose : uint32_t {
+ ENCRYPT = 0, /* Usable with RSA, EC and AES keys. */
+ DECRYPT = 1, /* Usable with RSA, EC and AES keys. */
+ SIGN = 2, /* Usable with RSA, EC and HMAC keys. */
+ VERIFY = 3, /* Usable with RSA, EC and HMAC keys. */
+ DERIVE_KEY = 4, /* Usable with EC keys. */
+};
+
+/**
+ * Keymaster error codes.
+ */
+enum ErrorCode : uint32_t {
+ OK = 0,
+ ROOT_OF_TRUST_ALREADY_SET = -1,
+ UNSUPPORTED_PURPOSE = -2,
+ INCOMPATIBLE_PURPOSE = -3,
+ UNSUPPORTED_ALGORITHM = -4,
+ INCOMPATIBLE_ALGORITHM = -5,
+ UNSUPPORTED_KEY_SIZE = -6,
+ UNSUPPORTED_BLOCK_MODE = -7,
+ INCOMPATIBLE_BLOCK_MODE = -8,
+ UNSUPPORTED_MAC_LENGTH = -9,
+ UNSUPPORTED_PADDING_MODE = -10,
+ INCOMPATIBLE_PADDING_MODE = -11,
+ UNSUPPORTED_DIGEST = -12,
+ INCOMPATIBLE_DIGEST = -13,
+ INVALID_EXPIRATION_TIME = -14,
+ INVALID_USER_ID = -15,
+ INVALID_AUTHORIZATION_TIMEOUT = -16,
+ UNSUPPORTED_KEY_FORMAT = -17,
+ INCOMPATIBLE_KEY_FORMAT = -18,
+ UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM = -19, /* For PKCS8 & PKCS12 */
+ UNSUPPORTED_KEY_VERIFICATION_ALGORITHM = -20, /* For PKCS8 & PKCS12 */
+ INVALID_INPUT_LENGTH = -21,
+ KEY_EXPORT_OPTIONS_INVALID = -22,
+ DELEGATION_NOT_ALLOWED = -23,
+ KEY_NOT_YET_VALID = -24,
+ KEY_EXPIRED = -25,
+ KEY_USER_NOT_AUTHENTICATED = -26,
+ OUTPUT_PARAMETER_NULL = -27,
+ INVALID_OPERATION_HANDLE = -28,
+ INSUFFICIENT_BUFFER_SPACE = -29,
+ VERIFICATION_FAILED = -30,
+ TOO_MANY_OPERATIONS = -31,
+ UNEXPECTED_NULL_POINTER = -32,
+ INVALID_KEY_BLOB = -33,
+ IMPORTED_KEY_NOT_ENCRYPTED = -34,
+ IMPORTED_KEY_DECRYPTION_FAILED = -35,
+ IMPORTED_KEY_NOT_SIGNED = -36,
+ IMPORTED_KEY_VERIFICATION_FAILED = -37,
+ INVALID_ARGUMENT = -38,
+ UNSUPPORTED_TAG = -39,
+ INVALID_TAG = -40,
+ MEMORY_ALLOCATION_FAILED = -41,
+ IMPORT_PARAMETER_MISMATCH = -44,
+ SECURE_HW_ACCESS_DENIED = -45,
+ OPERATION_CANCELLED = -46,
+ CONCURRENT_ACCESS_CONFLICT = -47,
+ SECURE_HW_BUSY = -48,
+ SECURE_HW_COMMUNICATION_FAILED = -49,
+ UNSUPPORTED_EC_FIELD = -50,
+ MISSING_NONCE = -51,
+ INVALID_NONCE = -52,
+ MISSING_MAC_LENGTH = -53,
+ KEY_RATE_LIMIT_EXCEEDED = -54,
+ CALLER_NONCE_PROHIBITED = -55,
+ KEY_MAX_OPS_EXCEEDED = -56,
+ INVALID_MAC_LENGTH = -57,
+ MISSING_MIN_MAC_LENGTH = -58,
+ UNSUPPORTED_MIN_MAC_LENGTH = -59,
+ UNSUPPORTED_KDF = -60,
+ UNSUPPORTED_EC_CURVE = -61,
+ KEY_REQUIRES_UPGRADE = -62,
+ ATTESTATION_CHALLENGE_MISSING = -63,
+ KEYMASTER_NOT_CONFIGURED = -64,
+ ATTESTATION_APPLICATION_ID_MISSING = -65,
+
+ UNIMPLEMENTED = -100,
+ VERSION_MISMATCH = -101,
+
+ UNKNOWN_ERROR = -1000,
+};
+
+/**
+ * Key derivation functions, mostly used in ECIES.
+ */
+enum KeyDerivationFunction : uint32_t {
+ /* Do not apply a key derivation function; use the raw agreed key */
+ NONE = 0,
+ /* HKDF defined in RFC 5869 with SHA256 */
+ RFC5869_SHA256 = 1,
+ /* KDF1 defined in ISO 18033-2 with SHA1 */
+ ISO18033_2_KDF1_SHA1 = 2,
+ /* KDF1 defined in ISO 18033-2 with SHA256 */
+ ISO18033_2_KDF1_SHA256 = 3,
+ /* KDF2 defined in ISO 18033-2 with SHA1 */
+ ISO18033_2_KDF2_SHA1 = 4,
+ /* KDF2 defined in ISO 18033-2 with SHA256 */
+ ISO18033_2_KDF2_SHA256 = 5,
+};
+
+/**
+ * Hardware authentication type, used by HardwareAuthTokens to specify the mechanism used to
+ * authentiate the user, and in KeyCharacteristics to specify the allowable mechanisms for
+ * authenticating to activate a key.
+ */
+enum HardwareAuthenticatorType : uint32_t {
+ NONE = 0,
+ PASSWORD = 1 << 0,
+ FINGERPRINT = 1 << 1,
+ // Additional entries must be powers of 2.
+ ANY = 0xFFFFFFFF,
+};
+
+struct KeyParameter {
+ /* Discriminates the uinon/blob field used. The blob cannot be coincided with the union, but
+ * only one of "f" and "blob" is ever used at a time. */
+ Tag tag;
+ union IntegerParams {
+ /* Enum types */
+ Algorithm algorithm;
+ BlockMode blockMode;
+ PaddingMode paddingMode;
+ Digest digest;
+ EcCurve ecCurve;
+ KeyOrigin origin;
+ KeyBlobUsageRequirements keyBlobUsageRequirements;
+ KeyPurpose purpose;
+ KeyDerivationFunction keyDerivationFunction;
+ HardwareAuthenticatorType hardwareAuthenticatorType;
+
+ /* Other types */
+ bool boolValue; // Always true, if a boolean tag is present.
+ uint32_t integer;
+ uint64_t longInteger;
+ uint64_t dateTime;
+ };
+ IntegerParams f; // Hidl does not support anonymous unions, so we have to name it.
+ vec<uint8_t> blob;
+};
+
+struct KeyCharacteristics {
+ vec<KeyParameter> softwareEnforced;
+ vec<KeyParameter> teeEnforced;
+};
+
+/**
+ * Data used to prove successful authentication.
+ */
+struct HardwareAuthToken {
+ uint64_t challenge;
+ uint64_t userId; // Secure User ID, not Android user ID.
+ uint64_t authenticatorId; // Secure authenticator ID.
+ uint32_t authenticatorType; // HardwareAuthenticatorType, in network order.
+ uint64_t timestamp; // In network order.
+ uint8_t[32] hmac; // HMAC is computed over 0 || challenge || user_id ||
+ // authenticator_id || authenticator_type || timestamp, with a
+ // prefixed 0 byte (which was a version field in Keymaster1 and
+ // Keymaster2) and the fields packed (no padding; so you probably
+ // can't just compute over the bytes of the struct).
+};
+
+enum SecurityLevel : uint32_t {
+ SOFTWARE = 0,
+ TRUSTED_ENVIRONMENT = 1,
+};
+
+/**
+ * Formats for key import and export.
+ */
+enum KeyFormat : uint32_t {
+ X509 = 0, /* for public key export */
+ PKCS8 = 1, /* for asymmetric key pair import */
+ RAW = 3, /* for symmetric key import and export*/
+};
+
+typedef uint64_t OperationHandle;
diff --git a/keymaster/Android.bp b/keymaster/Android.bp
new file mode 100644
index 0000000..09b8cb2
--- /dev/null
+++ b/keymaster/Android.bp
@@ -0,0 +1,4 @@
+// This is an autogenerated file, do not edit.
+subdirs = [
+ "3.0",
+]
diff --git a/media/1.0/types.hal b/media/1.0/types.hal
index 98dfe14..89b7fa2 100644
--- a/media/1.0/types.hal
+++ b/media/1.0/types.hal
@@ -27,28 +27,28 @@
/**
* Ref: frameworks/native/include/ui/GraphicBuffer.h
- * Ref: system/core/include/system/window.h
+ * Ref: system/core/include/system/window.h: ANativeWindowBuffer
*/
/**
* This struct contains attributes for a gralloc buffer that can be put into a
* union.
*/
-struct GraphicBufferAttributes {
+struct AnwBufferAttributes {
uint32_t width;
uint32_t height;
uint32_t stride;
PixelFormat format;
uint32_t usage; // TODO: convert to an enum
- uint32_t generationNumber;
+ uint64_t layerCount;
};
/**
- * A GraphicBuffer is simply GraphicBufferAttributes plus a native handle.
+ * An AnwBuffer is simply AnwBufferAttributes plus a native handle.
*/
-struct GraphicBuffer {
+struct AnwBuffer {
handle nativeHandle;
- GraphicBufferAttributes attr;
+ AnwBufferAttributes attr;
};
/**
diff --git a/media/omx/1.0/IGraphicBufferSource.hal b/media/omx/1.0/IGraphicBufferSource.hal
index a5b5813..9b3ab0c 100644
--- a/media/omx/1.0/IGraphicBufferSource.hal
+++ b/media/omx/1.0/IGraphicBufferSource.hal
@@ -29,32 +29,23 @@
*/
interface IGraphicBufferSource {
- configure(IOmxNode omxNode, Dataspace dataspace)
- generates (Status status);
+ configure(IOmxNode omxNode, Dataspace dataspace);
- setSuspend(bool suspend)
- generates (Status status);
+ setSuspend(bool suspend);
- setRepeatPreviousFrameDelayUs(int64_t repeatAfterUs)
- generates (Status status);
+ setRepeatPreviousFrameDelayUs(int64_t repeatAfterUs);
- setMaxFps(float maxFps)
- generates (Status status);
+ setMaxFps(float maxFps);
- setTimeLapseConfig(int64_t timePerFrameUs, int64_t timePerCaptureUs)
- generates (Status status);
+ setTimeLapseConfig(int64_t timePerFrameUs, int64_t timePerCaptureUs);
- setStartTimeUs(int64_t startTimeUs)
- generates (Status status);
+ setStartTimeUs(int64_t startTimeUs);
- setColorAspects(ColorAspects aspects)
- generates (Status status);
+ setColorAspects(ColorAspects aspects);
- setTimeOffsetUs(int64_t timeOffsetUs)
- generates (Status status);
+ setTimeOffsetUs(int64_t timeOffsetUs);
- signalEndOfInputStream()
- generates (Status status);
+ signalEndOfInputStream();
};
diff --git a/media/omx/1.0/IOmxNode.hal b/media/omx/1.0/IOmxNode.hal
index 9483be4..5945b44 100644
--- a/media/omx/1.0/IOmxNode.hal
+++ b/media/omx/1.0/IOmxNode.hal
@@ -46,14 +46,14 @@
* Invoke a command on the node.
*
* @param[in] cmd indicates the type of the command.
- * @param[in] info holds information about the command.
+ * @param[in] param is a parameter for the command.
* @param[out] status will be the status of the call.
*
* @see OMX_SendCommand() in the OpenMax IL standard.
*/
sendCommand(
uint32_t cmd,
- Bytes info // TODO: describe structure better or point at standard
+ int32_t param
) generates (
Status status
);
diff --git a/media/omx/1.0/types.hal b/media/omx/1.0/types.hal
index 79c3a44..ccb2ddf 100644
--- a/media/omx/1.0/types.hal
+++ b/media/omx/1.0/types.hal
@@ -34,6 +34,7 @@
NAME_NOT_FOUND = -2,
NO_MEMORY = -12,
+ BAD_VALUE = -22,
ERROR_UNSUPPORTED = -1010,
UNKNOWN_ERROR = -2147483648,
};
@@ -149,7 +150,7 @@
SharedMemoryAttributes sharedMem;
// if bufferType == ANW_BUFFER
- GraphicBufferAttributes anwBuffer;
+ AnwBufferAttributes anwBuffer;
// if bufferType == NATIVE_HANDLE
// No additional attributes.
diff --git a/memtrack/1.0/vts/Android.mk b/memtrack/1.0/vts/Android.mk
index 4a5ca4f..7b2400f 100644
--- a/memtrack/1.0/vts/Android.mk
+++ b/memtrack/1.0/vts/Android.mk
@@ -48,3 +48,4 @@
include $(BUILD_SHARED_LIBRARY)
+include $(LOCAL_PATH)/functional/vts/testcases/hal/memtrack/hidl/target/Android.mk
diff --git a/memtrack/1.0/vts/functional/Android.bp b/memtrack/1.0/vts/functional/Android.bp
new file mode 100644
index 0000000..b3e560a
--- /dev/null
+++ b/memtrack/1.0/vts/functional/Android.bp
@@ -0,0 +1,40 @@
+//
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+cc_test {
+ name: "memtrack_hidl_hal_test",
+ gtest: true,
+ srcs: ["memtrack_hidl_hal_test.cpp"],
+ shared_libs: [
+ "libbase",
+ "liblog",
+ "libcutils",
+ "libhardware",
+ "libhidlbase",
+ "libhwbinder",
+ "libutils",
+ "android.hardware.memtrack@1.0",
+ ],
+ static_libs: ["libgtest"],
+ cflags: [
+ "--coverage",
+ "-O0",
+ "-g",
+ ],
+ ldflags: [
+ "--coverage"
+ ]
+}
diff --git a/memtrack/1.0/vts/functional/memtrack_hidl_hal_test.cpp b/memtrack/1.0/vts/functional/memtrack_hidl_hal_test.cpp
new file mode 100644
index 0000000..597b5da
--- /dev/null
+++ b/memtrack/1.0/vts/functional/memtrack_hidl_hal_test.cpp
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "memtrack_hidl_hal_test"
+#include <android-base/logging.h>
+#include <android/hardware/memtrack/1.0/IMemtrack.h>
+
+#include <gtest/gtest.h>
+
+#include <algorithm>
+#include <vector>
+
+using ::android::hardware::memtrack::V1_0::IMemtrack;
+using ::android::hardware::memtrack::V1_0::MemtrackRecord;
+using ::android::hardware::memtrack::V1_0::MemtrackFlag;
+using ::android::hardware::memtrack::V1_0::MemtrackType;
+using ::android::hardware::memtrack::V1_0::MemtrackStatus;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::sp;
+using std::vector;
+using std::count_if;
+
+class MemtrackHidlTest : public ::testing::Test {
+ public:
+ virtual void SetUp() override {
+ memtrack = IMemtrack::getService("memtrack");
+ ASSERT_NE(memtrack, nullptr);
+ }
+
+ virtual void TearDown() override {}
+
+ sp<IMemtrack> memtrack;
+};
+
+/* Returns true if flags contains at least min, and no more than max,
+ * of the flags in flagSet. Returns false otherwise.
+ */
+bool rightFlagCount(uint32_t flags, vector<MemtrackFlag> flagSet, uint32_t min,
+ uint32_t max) {
+ uint32_t count =
+ count_if(flagSet.begin(), flagSet.end(),
+ [&](MemtrackFlag f) { return flags & (uint32_t)f; });
+ return (min <= count && count <= max);
+}
+
+/* Returns true when passed a valid, defined status, false otherwise.
+ */
+bool validStatus(MemtrackStatus s) {
+ vector<MemtrackStatus> statusVec = {
+ MemtrackStatus::SUCCESS, MemtrackStatus::MEMORY_TRACKING_NOT_SUPPORTED,
+ MemtrackStatus::TYPE_NOT_SUPPORTED};
+ return std::find(statusVec.begin(), statusVec.end(), s) != statusVec.end();
+}
+
+/* Returns a pid found in /proc for which the string read from
+ * /proc/[pid]/cmdline matches cmd, or -1 if no such pid exists.
+ */
+pid_t getPidFromCmd(const char cmd[], uint32_t len) {
+ const char procs[] = "/proc/";
+ DIR *dir = opendir(procs);
+ if (!dir) {
+ return -1;
+ }
+
+ struct dirent *proc;
+ while ((proc = readdir(dir)) != NULL) {
+ if (!isdigit(proc->d_name[0])) {
+ continue;
+ }
+ char line[len];
+ char fname[PATH_MAX];
+ snprintf(fname, PATH_MAX, "/proc/%s/cmdline", proc->d_name);
+
+ FILE *file = fopen(fname, "r");
+ if (!file) {
+ continue;
+ }
+ char *str = fgets(line, len, file);
+ fclose(file);
+ if (!str || strcmp(str, cmd)) {
+ continue;
+ } else {
+ closedir(dir);
+ return atoi(proc->d_name);
+ }
+ }
+ closedir(dir);
+ return -1;
+}
+
+auto generate_cb(MemtrackStatus *s, hidl_vec<MemtrackRecord> *v) {
+ return [=](MemtrackStatus status, hidl_vec<MemtrackRecord> vec) {
+ *s = status;
+ *v = vec;
+ };
+}
+
+/* Sanity check results when getMemory() is passed a negative PID
+ */
+TEST_F(MemtrackHidlTest, BadPidTest) {
+ MemtrackStatus s;
+ hidl_vec<MemtrackRecord> v;
+ auto cb = generate_cb(&s, &v);
+ for (uint32_t i = 0; i < static_cast<uint32_t>(MemtrackType::NUM_TYPES);
+ i++) {
+ Return<void> ret =
+ memtrack->getMemory(-1, static_cast<MemtrackType>(i), cb);
+ ASSERT_TRUE(ret.isOk());
+ ASSERT_TRUE(validStatus(s));
+ }
+}
+
+/* Sanity check results when getMemory() is passed a bad memory usage type
+ */
+TEST_F(MemtrackHidlTest, BadTypeTest) {
+ MemtrackStatus s;
+ hidl_vec<MemtrackRecord> v;
+ auto cb = generate_cb(&s, &v);
+ Return<void> ret = memtrack->getMemory(getpid(), MemtrackType::NUM_TYPES, cb);
+ ASSERT_TRUE(ret.isOk());
+ ASSERT_TRUE(validStatus(s));
+}
+
+/* Call memtrack on the surfaceflinger process and check that the results are
+ * reasonable for all memory types, including valid flag combinations for
+ * every MemtrackRecord returned.
+ */
+TEST_F(MemtrackHidlTest, SurfaceflingerTest) {
+ const char cmd[] = "/system/bin/surfaceflinger";
+ const uint32_t len = sizeof(cmd);
+ pid_t pid = getPidFromCmd(cmd, len);
+ ASSERT_LE(0, pid) << "Surfaceflinger process not found";
+
+ MemtrackStatus s;
+ hidl_vec<MemtrackRecord> v;
+ auto cb = generate_cb(&s, &v);
+ uint32_t unsupportedCount = 0;
+ for (uint32_t i = 0; i < static_cast<uint32_t>(MemtrackType::NUM_TYPES);
+ i++) {
+ Return<void> ret =
+ memtrack->getMemory(pid, static_cast<MemtrackType>(i), cb);
+ ASSERT_TRUE(ret.isOk());
+
+ switch (s) {
+ case MemtrackStatus::MEMORY_TRACKING_NOT_SUPPORTED:
+ unsupportedCount++;
+ break;
+ case MemtrackStatus::TYPE_NOT_SUPPORTED:
+ break;
+ case MemtrackStatus::SUCCESS: {
+ for (uint32_t j = 0; j < v.size(); j++) {
+ // Enforce flag constraints
+ vector<MemtrackFlag> smapFlags = {MemtrackFlag::SMAPS_ACCOUNTED,
+ MemtrackFlag::SMAPS_UNACCOUNTED};
+ EXPECT_TRUE(rightFlagCount(v[j].flags, smapFlags, 1, 1));
+ vector<MemtrackFlag> shareFlags = {MemtrackFlag::SHARED,
+ MemtrackFlag::SHARED_PSS,
+ MemtrackFlag::PRIVATE};
+ EXPECT_TRUE(rightFlagCount(v[j].flags, shareFlags, 0, 1));
+ vector<MemtrackFlag> systemFlags = {MemtrackFlag::SYSTEM,
+ MemtrackFlag::DEDICATED};
+ EXPECT_TRUE(rightFlagCount(v[j].flags, systemFlags, 0, 1));
+ vector<MemtrackFlag> secureFlags = {MemtrackFlag::SECURE,
+ MemtrackFlag::NONSECURE};
+ EXPECT_TRUE(rightFlagCount(v[j].flags, secureFlags, 0, 1));
+ }
+ break;
+ }
+ default:
+ FAIL();
+ }
+ }
+ // If tracking is not supported this should be returned for all types.
+ ASSERT_TRUE(unsupportedCount == 0 ||
+ unsupportedCount ==
+ static_cast<uint32_t>(MemtrackType::NUM_TYPES));
+}
+
+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/memtrack/1.0/vts/functional/vts/testcases/hal/memtrack/hidl/target/Android.mk b/memtrack/1.0/vts/functional/vts/testcases/hal/memtrack/hidl/target/Android.mk
new file mode 100644
index 0000000..8dcaabb
--- /dev/null
+++ b/memtrack/1.0/vts/functional/vts/testcases/hal/memtrack/hidl/target/Android.mk
@@ -0,0 +1,25 @@
+#
+# 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 $(call all-subdir-makefiles)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := HalMemtrackHidlTargetTest
+VTS_CONFIG_SRC_DIR := testcases/hal/memtrack/hidl/target
+include test/vts/tools/build/Android.host_config.mk
diff --git a/memtrack/1.0/vts/functional/vts/testcases/hal/memtrack/hidl/target/AndroidTest.xml b/memtrack/1.0/vts/functional/vts/testcases/hal/memtrack/hidl/target/AndroidTest.xml
new file mode 100644
index 0000000..7fb286b
--- /dev/null
+++ b/memtrack/1.0/vts/functional/vts/testcases/hal/memtrack/hidl/target/AndroidTest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<configuration description="Config for VTS Memtrack HIDL HAL's target-side test cases">
+ <target_preparer class="com.android.compatibility.common.tradefed.targetprep.VtsFilePusher">
+ <option name="push-group" value="HidlHalTest.push" />
+ </target_preparer>
+ <target_preparer class="com.android.tradefed.targetprep.VtsPythonVirtualenvPreparer" />
+ <test class="com.android.tradefed.testtype.VtsMultiDeviceTest">
+ <option name="test-module-name" value="HalMemtrackHidlTargetTest"/>
+ <option name="binary-test-sources" value="
+ _32bit::DATA/nativetest/memtrack_hidl_hal_test/memtrack_hidl_hal_test,
+ _64bit::DATA/nativetest64/memtrack_hidl_hal_test/memtrack_hidl_hal_test,
+ "/>
+ <option name="test-config-path" value="vts/testcases/hal/memtrack/hidl/target/HalMemtrackHidlTargetTest.config" />
+ <option name="binary-test-type" value="gtest" />
+ <option name="test-timeout" value="5m" />
+ </test>
+</configuration>
diff --git a/memtrack/1.0/vts/functional/vts/testcases/hal/memtrack/hidl/target/HalMemtrackHidlTargetTest.config b/memtrack/1.0/vts/functional/vts/testcases/hal/memtrack/hidl/target/HalMemtrackHidlTargetTest.config
new file mode 100644
index 0000000..d2597a2
--- /dev/null
+++ b/memtrack/1.0/vts/functional/vts/testcases/hal/memtrack/hidl/target/HalMemtrackHidlTargetTest.config
@@ -0,0 +1,20 @@
+{
+ "use_gae_db": true,
+ "coverage": true,
+ "modules": [
+ {
+ "module_name": "system/lib64/hw/memtrack.msm8992",
+ "git_project": {
+ "name": "platform/hardware/qcom/display",
+ "path": "hardware/qcom/display"
+ }
+ },
+ {
+ "module_name": "system/lib64/hw/android.hardware.memtrack@1.0-impl",
+ "git_project": {
+ "name": "platform/hardware/interfaces",
+ "path": "hardware/interfaces"
+ }
+ }
+ ]
+}
diff --git a/memtrack/Android.bp b/memtrack/Android.bp
index ba90f2c..ed19a37 100644
--- a/memtrack/Android.bp
+++ b/memtrack/Android.bp
@@ -2,4 +2,5 @@
subdirs = [
"1.0",
"1.0/default",
+ "1.0/vts/functional",
]
diff --git a/nfc/1.0/Android.bp b/nfc/1.0/Android.bp
index 930fb14..af571f3 100644
--- a/nfc/1.0/Android.bp
+++ b/nfc/1.0/Android.bp
@@ -124,3 +124,93 @@
"android.hidl.base@1.0",
],
}
+
+genrule {
+ name: "android.hardware.nfc@1.0-INfc-vts.profiler_genc++",
+ tools: ["hidl-gen", "vtsc"],
+ cmd: "$(location hidl-gen) -o $(genDir) -Lvts -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.nfc@1.0 && $(location vtsc) -mPROFILER -tSOURCE -b$(genDir) android/hardware/nfc/1.0/ $(genDir)/android/hardware/nfc/1.0/",
+ srcs: [
+ "INfc.hal",
+ "types.hal",
+ ],
+ out: [
+ "android/hardware/nfc/1.0/Nfc.vts.cpp",
+ "android/hardware/nfc/1.0/types.vts.cpp",
+ ],
+}
+
+genrule {
+ name: "android.hardware.nfc@1.0-INfc-vts.profiler_genc++_headers",
+ tools: ["hidl-gen", "vtsc"],
+ cmd: "$(location hidl-gen) -o $(genDir) -Lvts -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.nfc@1.0 && $(location vtsc) -mPROFILER -tHEADER -b$(genDir) android/hardware/nfc/1.0/ $(genDir)/android/hardware/nfc/1.0/",
+ srcs: [
+ "INfc.hal",
+ "types.hal",
+ ],
+ out: [
+ "android/hardware/nfc/1.0/Nfc.vts.h",
+ "android/hardware/nfc/1.0/types.vts.h",
+ ],
+}
+
+cc_library_shared {
+ name: "android.hardware.nfc@1.0-INfc-vts.profiler",
+ generated_sources: ["android.hardware.nfc@1.0-INfc-vts.profiler_genc++"],
+ generated_headers: ["android.hardware.nfc@1.0-INfc-vts.profiler_genc++_headers"],
+ export_generated_headers: ["android.hardware.nfc@1.0-INfc-vts.profiler_genc++_headers"],
+ shared_libs: [
+ "libbase",
+ "libhidlbase",
+ "libhidltransport",
+ "libvts_profiling",
+ "libvts_multidevice_proto",
+ "libprotobuf-cpp-full",
+ "android.hidl.base@1.0",
+ "android.hardware.nfc@1.0",
+ ],
+}
+
+genrule {
+ name: "android.hardware.nfc@1.0-INfcClientCallback-vts.profiler_genc++",
+ tools: ["hidl-gen", "vtsc"],
+ cmd: "$(location hidl-gen) -o $(genDir) -Lvts -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.nfc@1.0 && $(location vtsc) -mPROFILER -tSOURCE -b$(genDir) android/hardware/nfc/1.0/ $(genDir)/android/hardware/nfc/1.0/",
+ srcs: [
+ "INfcClientCallback.hal",
+ "types.hal",
+ ],
+ out: [
+ "android/hardware/nfc/1.0/NfcClientCallback.vts.cpp",
+ "android/hardware/nfc/1.0/types.vts.cpp",
+ ],
+}
+
+genrule {
+ name: "android.hardware.nfc@1.0-INfcClientCallback-vts.profiler_genc++_headers",
+ tools: ["hidl-gen", "vtsc"],
+ cmd: "$(location hidl-gen) -o $(genDir) -Lvts -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.nfc@1.0 && $(location vtsc) -mPROFILER -tHEADER -b$(genDir) android/hardware/nfc/1.0/ $(genDir)/android/hardware/nfc/1.0/",
+ srcs: [
+ "INfcClientCallback.hal",
+ "types.hal",
+ ],
+ out: [
+ "android/hardware/nfc/1.0/NfcClientCallback.vts.h",
+ "android/hardware/nfc/1.0/types.vts.h",
+ ],
+}
+
+cc_library_shared {
+ name: "android.hardware.nfc@1.0-INfcClientCallback-vts.profiler",
+ generated_sources: ["android.hardware.nfc@1.0-INfcClientCallback-vts.profiler_genc++"],
+ generated_headers: ["android.hardware.nfc@1.0-INfcClientCallback-vts.profiler_genc++_headers"],
+ export_generated_headers: ["android.hardware.nfc@1.0-INfcClientCallback-vts.profiler_genc++_headers"],
+ shared_libs: [
+ "libbase",
+ "libhidlbase",
+ "libhidltransport",
+ "libvts_profiling",
+ "libvts_multidevice_proto",
+ "libprotobuf-cpp-full",
+ "android.hidl.base@1.0",
+ "android.hardware.nfc@1.0",
+ ],
+}
diff --git a/nfc/1.0/vts/Android.mk b/nfc/1.0/vts/Android.mk
index e7dec14..f9e3276 100644
--- a/nfc/1.0/vts/Android.mk
+++ b/nfc/1.0/vts/Android.mk
@@ -16,68 +16,4 @@
LOCAL_PATH := $(call my-dir)
-# build profiler for Nfc.
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libvts_profiler_hidl_nfc@1.0
-
-LOCAL_SRC_FILES := \
- Nfc.vts \
- types.vts \
-
-LOCAL_C_INCLUDES += \
- test/vts/drivers/libprofiling \
-
-LOCAL_VTS_MODE := PROFILER
-
-LOCAL_SHARED_LIBRARIES := \
- android.hardware.nfc@1.0 \
- libbase \
- libcutils \
- liblog \
- libhidlbase \
- libhidltransport \
- libhwbinder \
- libprotobuf-cpp-full \
- libvts_common \
- libvts_multidevice_proto \
- libvts_profiling \
- libutils \
-
-LOCAL_PROTOC_OPTIMIZE_TYPE := full
-
-include $(BUILD_SHARED_LIBRARY)
-
-# build profiler for NfcClientCallback.
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libvts_profiler_hidl_nfc_client_callback_@1.0
-
-LOCAL_SRC_FILES := \
- NfcClientCallback.vts \
- types.vts \
-
-LOCAL_C_INCLUDES += \
- test/vts/drivers/libprofiling \
-
-LOCAL_VTS_MODE := PROFILER
-
-LOCAL_SHARED_LIBRARIES := \
- android.hardware.nfc@1.0 \
- libbase \
- libcutils \
- liblog \
- libhidlbase \
- libhidltransport \
- libhwbinder \
- libprotobuf-cpp-full \
- libvts_common \
- libvts_multidevice_proto \
- libvts_profiling \
- libutils \
-
-LOCAL_PROTOC_OPTIMIZE_TYPE := full
-
-include $(BUILD_SHARED_LIBRARY)
-
-include $(call all-makefiles-under,$(LOCAL_PATH))
+include $(call all-subdir-makefiles)
diff --git a/nfc/1.0/vts/functional/vts/testcases/hal/nfc/hidl/host/NfcHidlBasicTest.py b/nfc/1.0/vts/functional/vts/testcases/hal/nfc/hidl/host/NfcHidlBasicTest.py
index ede7897..136704a 100644
--- a/nfc/1.0/vts/functional/vts/testcases/hal/nfc/hidl/host/NfcHidlBasicTest.py
+++ b/nfc/1.0/vts/functional/vts/testcases/hal/nfc/hidl/host/NfcHidlBasicTest.py
@@ -52,6 +52,7 @@
target_version=1.0,
target_package="android.hardware.nfc",
target_component_name="INfc",
+ hw_binder_service_name="nfc_nci",
bits=64)
def tearDownClass(self):
diff --git a/power/1.0/vts/functional/power_hidl_hal_test.cpp b/power/1.0/vts/functional/power_hidl_hal_test.cpp
index 8833c04..045a34b 100644
--- a/power/1.0/vts/functional/power_hidl_hal_test.cpp
+++ b/power/1.0/vts/functional/power_hidl_hal_test.cpp
@@ -35,18 +35,8 @@
class PowerHidlTest : public ::testing::Test {
public:
virtual void SetUp() override {
- // TODO(b/33385836) Delete copied code
- bool getStub = false;
- char getSubProperty[PROPERTY_VALUE_MAX];
- if (property_get("vts.hidl.get_stub", getSubProperty, "") > 0) {
- if (!strcmp(getSubProperty, "true") || !strcmp(getSubProperty, "True") ||
- !strcmp(getSubProperty, "1")) {
- getStub = true;
- }
- }
- power = IPower::getService("power", getStub);
+ power = IPower::getService("power");
ASSERT_NE(power, nullptr);
- ASSERT_EQ(!getStub, power->isRemote());
}
virtual void TearDown() override {}
diff --git a/power/1.0/vts/functional/vts/testcases/hal/power/hidl/target/AndroidTest.xml b/power/1.0/vts/functional/vts/testcases/hal/power/hidl/target/AndroidTest.xml
index bb80de2..0eb2142 100644
--- a/power/1.0/vts/functional/vts/testcases/hal/power/hidl/target/AndroidTest.xml
+++ b/power/1.0/vts/functional/vts/testcases/hal/power/hidl/target/AndroidTest.xml
@@ -24,6 +24,7 @@
_32bit::DATA/nativetest/power_hidl_hal_test/power_hidl_hal_test,
_64bit::DATA/nativetest64/power_hidl_hal_test/power_hidl_hal_test,
"/>
+ <option name="test-config-path" value="vts/testcases/hal/power/hidl/target/HalPowerHidlTargetTest.config" />
<option name="binary-test-type" value="gtest" />
<option name="test-timeout" value="1m" />
</test>
diff --git a/power/1.0/vts/functional/vts/testcases/hal/power/hidl/target/HalPowerHidlTargetTest.config b/power/1.0/vts/functional/vts/testcases/hal/power/hidl/target/HalPowerHidlTargetTest.config
new file mode 100644
index 0000000..54c0175
--- /dev/null
+++ b/power/1.0/vts/functional/vts/testcases/hal/power/hidl/target/HalPowerHidlTargetTest.config
@@ -0,0 +1,34 @@
+{
+ "use_gae_db": true,
+ "coverage": true,
+ "modules": [
+ {
+ "module_name": "system/lib64/hw/power.bullhead",
+ "git_project": {
+ "name": "device/lge/bullhead",
+ "path": "device/lge/bullhead"
+ }
+ },
+ {
+ "module_name": "system/lib64/hw/power.marlin",
+ "git_project": {
+ "name": "device/google/marlin",
+ "path": "device/google/marlin"
+ }
+ },
+ {
+ "module_name": "system/lib64/hw/power.sailfish",
+ "git_project": {
+ "name": "device/google/marlin",
+ "path": "device/google/marlin"
+ }
+ },
+ {
+ "module_name": "system/lib64/hw/android.hardware.power@1.0-impl",
+ "git_project": {
+ "name": "platform/hardware/interfaces",
+ "path": "hardware/interfaces"
+ }
+ }
+ ]
+}
diff --git a/sensors/1.0/Android.bp b/sensors/1.0/Android.bp
index ed65265..437b545 100644
--- a/sensors/1.0/Android.bp
+++ b/sensors/1.0/Android.bp
@@ -54,3 +54,61 @@
"android.hidl.base@1.0",
],
}
+
+genrule {
+ name: "android.hardware.sensors.vts.driver@1.0_genc++",
+ tools: ["hidl-gen", "vtsc"],
+ cmd: "$(location hidl-gen) -o $(genDir) -Lvts -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.sensors@1.0 && $(location vtsc) -mDRIVER -tSOURCE -b$(genDir) android/hardware/sensors/1.0/ $(genDir)/android/hardware/sensors/1.0/",
+ srcs: [
+ "types.hal",
+ "ISensors.hal",
+ ],
+ out: [
+ "android/hardware/sensors/1.0/types.vts.cpp",
+ "android/hardware/sensors/1.0/Sensors.vts.cpp",
+ ],
+}
+
+genrule {
+ name: "android.hardware.sensors.vts.driver@1.0_genc++_headers",
+ tools: ["hidl-gen", "vtsc"],
+ cmd: "$(location hidl-gen) -o $(genDir) -Lvts -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.sensors@1.0 && $(location vtsc) -mDRIVER -tHEADER -b$(genDir) android/hardware/sensors/1.0/ $(genDir)/android/hardware/sensors/1.0/",
+ srcs: [
+ "types.hal",
+ "ISensors.hal",
+ ],
+ out: [
+ "android/hardware/sensors/1.0/types.vts.h",
+ "android/hardware/sensors/1.0/Sensors.vts.h",
+ ],
+}
+
+cc_library_shared {
+ name: "android.hardware.sensors.vts.driver@1.0",
+ generated_sources: ["android.hardware.sensors.vts.driver@1.0_genc++"],
+ generated_headers: ["android.hardware.sensors.vts.driver@1.0_genc++_headers"],
+ export_generated_headers: ["android.hardware.sensors.vts.driver@1.0_genc++_headers"],
+ shared_libs: [
+ "libhidlbase",
+ "libhidltransport",
+ "libhwbinder",
+ "liblog",
+ "libutils",
+ "libcutils",
+ "libvts_common",
+ "libvts_datatype",
+ "libvts_measurement",
+ "libvts_multidevice_proto",
+ "libcamera_metadata",
+ "libprotobuf-cpp-full",
+ "android.hidl.base@1.0",
+ "android.hardware.sensors@1.0",
+ ],
+ export_shared_lib_headers: [
+ "libhidlbase",
+ "libhidltransport",
+ "libhwbinder",
+ "libutils",
+ "android.hidl.base@1.0",
+ ],
+}
diff --git a/sensors/1.0/vts/Android.mk b/sensors/1.0/vts/Android.mk
index df8d66f..93bbd96 100644
--- a/sensors/1.0/vts/Android.mk
+++ b/sensors/1.0/vts/Android.mk
@@ -16,36 +16,6 @@
LOCAL_PATH := $(call my-dir)
-# build VTS driver for Sensors v1.0.
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libvts_driver_hidl_sensors@1.0
-
-LOCAL_SRC_FILES := \
- Sensors.vts \
- types.vts \
-
-LOCAL_SHARED_LIBRARIES += \
- android.hardware.sensors@1.0 \
- libbase \
- libutils \
- libcutils \
- liblog \
- libhidlbase \
- libhidltransport \
- libhwbinder \
- libprotobuf-cpp-full \
- libvts_common \
- libvts_datatype \
- libvts_measurement \
- libvts_multidevice_proto \
-
-LOCAL_PROTOC_OPTIMIZE_TYPE := full
-
-LOCAL_MULTILIB := both
-
-include $(BUILD_SHARED_LIBRARY)
-
# build profiler for sensors.
include $(CLEAR_VARS)
diff --git a/tests/bar/1.0/Android.bp b/tests/bar/1.0/Android.bp
index 6ef8ac2..e4c79fa 100644
--- a/tests/bar/1.0/Android.bp
+++ b/tests/bar/1.0/Android.bp
@@ -6,10 +6,12 @@
cmd: "$(location hidl-gen) -o $(genDir) -Lc++ -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.tests.bar@1.0",
srcs: [
"IBar.hal",
+ "IComplicated.hal",
"IImportTypes.hal",
],
out: [
"android/hardware/tests/bar/1.0/BarAll.cpp",
+ "android/hardware/tests/bar/1.0/ComplicatedAll.cpp",
"android/hardware/tests/bar/1.0/ImportTypesAll.cpp",
],
}
@@ -20,6 +22,7 @@
cmd: "$(location hidl-gen) -o $(genDir) -Lc++ -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.tests.bar@1.0",
srcs: [
"IBar.hal",
+ "IComplicated.hal",
"IImportTypes.hal",
],
out: [
@@ -28,6 +31,11 @@
"android/hardware/tests/bar/1.0/BnBar.h",
"android/hardware/tests/bar/1.0/BpBar.h",
"android/hardware/tests/bar/1.0/BsBar.h",
+ "android/hardware/tests/bar/1.0/IComplicated.h",
+ "android/hardware/tests/bar/1.0/IHwComplicated.h",
+ "android/hardware/tests/bar/1.0/BnComplicated.h",
+ "android/hardware/tests/bar/1.0/BpComplicated.h",
+ "android/hardware/tests/bar/1.0/BsComplicated.h",
"android/hardware/tests/bar/1.0/IImportTypes.h",
"android/hardware/tests/bar/1.0/IHwImportTypes.h",
"android/hardware/tests/bar/1.0/BnImportTypes.h",
diff --git a/tests/bar/1.0/IBar.hal b/tests/bar/1.0/IBar.hal
index 21c3473..5f94d07 100644
--- a/tests/bar/1.0/IBar.hal
+++ b/tests/bar/1.0/IBar.hal
@@ -17,9 +17,12 @@
package android.hardware.tests.bar@1.0;
import android.hardware.tests.foo@1.0::IFoo;
+import android.hardware.tests.foo@1.0::ISimple;
import android.hardware.tests.foo@1.0::Abc;
import android.hardware.tests.foo@1.0::Unrelated;
+import IComplicated;
+
interface IBar extends android.hardware.tests.foo@1.0::IFoo {
typedef android.hardware.tests.foo@1.0::IFoo FunkyAlias;
@@ -33,4 +36,6 @@
expectNullHandle(handle h, Abc xyz) generates (bool hIsNull, bool xyzHasNull);
takeAMask(BitField bf, bitfield<BitField> first, MyMask second, Mask third)
generates (BitField bf, uint8_t first, uint8_t second, uint8_t third);
+
+ haveAInterface(ISimple i) generates (ISimple i);
};
diff --git a/tests/bar/1.0/IComplicated.hal b/tests/bar/1.0/IComplicated.hal
new file mode 100644
index 0000000..deaef8d
--- /dev/null
+++ b/tests/bar/1.0/IComplicated.hal
@@ -0,0 +1,22 @@
+/*
+ * 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.bar@1.0;
+
+import android.hardware.tests.foo@1.0::ISimple;
+
+interface IComplicated extends ISimple {
+};
diff --git a/tests/bar/1.0/default/Bar.cpp b/tests/bar/1.0/default/Bar.cpp
index a750fe4..4152bb9 100644
--- a/tests/bar/1.0/default/Bar.cpp
+++ b/tests/bar/1.0/default/Bar.cpp
@@ -165,6 +165,13 @@
return Void();
}
+Return<void> Bar::haveAInterface(const sp<ISimple> &in,
+ haveAInterface_cb _hidl_cb) {
+ _hidl_cb(in);
+ return Void();
+}
+
+
IBar* HIDL_FETCH_IBar(const char* /* name */) {
return new Bar();
}
diff --git a/tests/bar/1.0/default/Bar.h b/tests/bar/1.0/default/Bar.h
index 71737fe..70bffe7 100644
--- a/tests/bar/1.0/default/Bar.h
+++ b/tests/bar/1.0/default/Bar.h
@@ -71,6 +71,8 @@
Return<void> takeAMask(BitField bf, uint8_t first, const MyMask& second, uint8_t third,
takeAMask_cb _hidl_cb) override;
+ Return<void> haveAInterface(const sp<ISimple> &in,
+ haveAInterface_cb _hidl_cb) override;
private:
sp<IFoo> mFoo;
diff --git a/tests/baz/1.0/IBaz.hal b/tests/baz/1.0/IBaz.hal
index 3e1e2b9..7c5d63a 100644
--- a/tests/baz/1.0/IBaz.hal
+++ b/tests/baz/1.0/IBaz.hal
@@ -49,6 +49,10 @@
doStuffAndReturnAString() generates (string something);
mapThisVector(vec<int32_t> param) generates (vec<int32_t> something);
callMe(IBazCallback cb);
+
+ callMeLater(IBazCallback cb);
+ iAmFreeNow();
+
useAnEnum(SomeEnum zzz) generates (SomeEnum kkk);
haveSomeStrings(string[3] array) generates (string[2] result);
diff --git a/tests/baz/1.0/IBazCallback.hal b/tests/baz/1.0/IBazCallback.hal
index b59a107..503b970 100644
--- a/tests/baz/1.0/IBazCallback.hal
+++ b/tests/baz/1.0/IBazCallback.hal
@@ -18,4 +18,5 @@
interface IBazCallback {
heyItsMe(IBazCallback cb);
+ hey();
};
diff --git a/tests/foo/1.0/ISimple.hal b/tests/foo/1.0/ISimple.hal
index 92e9d95..0d45835 100644
--- a/tests/foo/1.0/ISimple.hal
+++ b/tests/foo/1.0/ISimple.hal
@@ -18,4 +18,8 @@
interface ISimple {
getCookie() generates (int32_t cookie);
+ customVecInt() generates (vec<int32_t> chain);
+ customVecStr() generates (vec<string> chain);
+ mystr() generates (string str);
+ myhandle() generates (handle str);
};
diff --git a/tests/msgq/1.0/ITestMsgQ.hal b/tests/msgq/1.0/ITestMsgQ.hal
index dcdc74a..b23f48f 100644
--- a/tests/msgq/1.0/ITestMsgQ.hal
+++ b/tests/msgq/1.0/ITestMsgQ.hal
@@ -17,6 +17,11 @@
package android.hardware.tests.msgq@1.0;
interface ITestMsgQ {
+ enum EventFlagBits : uint32_t {
+ FMQ_NOT_EMPTY = 1 << 0,
+ FMQ_NOT_FULL = 1 << 1,
+ };
+
/*
* This method requests the service to set up a synchronous read/write
* wait-free FMQ with the client as reader.
@@ -79,4 +84,11 @@
*/
requestReadFmqUnsync(int32_t count) generates(bool ret);
+ /*
+ * This method requests the service to trigger a blocking read.
+ *
+ * @param count Number of messages to read.
+ *
+ */
+ oneway requestBlockingRead(int32_t count);
};
diff --git a/thermal/1.0/vts/Android.mk b/thermal/1.0/vts/Android.mk
index ef926fe..644b2ed 100644
--- a/thermal/1.0/vts/Android.mk
+++ b/thermal/1.0/vts/Android.mk
@@ -16,43 +16,6 @@
LOCAL_PATH := $(call my-dir)
-# build VTS driver for Thermal v1.0.
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libvts_driver_hidl_thermal@1.0
-
-LOCAL_SRC_FILES := \
- Thermal.vts \
- types.vts \
-
-LOCAL_C_INCLUDES := \
- android.hardware.thermal@1.0 \
- system/core/base/include \
- system/core/include \
-
-LOCAL_SHARED_LIBRARIES += \
- android.hardware.thermal@1.0 \
- libbase \
- libutils \
- libcutils \
- liblog \
- libhidlbase \
- libhidltransport \
- libhwbinder \
- libprotobuf-cpp-full \
- libvts_common \
- libvts_datatype \
- libvts_measurement \
- libvts_multidevice_proto \
-
-LOCAL_STATIC_LIBRARIES := \
-
-LOCAL_PROTOC_OPTIMIZE_TYPE := full
-
-LOCAL_MULTILIB := both
-
-include $(BUILD_SHARED_LIBRARY)
-
# build profiler for thermal.
include $(CLEAR_VARS)
diff --git a/thermal/1.0/vts/functional/Android.bp b/thermal/1.0/vts/functional/Android.bp
index fedb760..bef7bc2 100644
--- a/thermal/1.0/vts/functional/Android.bp
+++ b/thermal/1.0/vts/functional/Android.bp
@@ -31,8 +31,12 @@
],
static_libs: ["libgtest"],
cflags: [
+ "--coverage",
"-O0",
"-g",
],
+ ldflags: [
+ "--coverage"
+ ]
}
diff --git a/thermal/1.0/vts/functional/vts/testcases/hal/thermal/hidl/target/AndroidTest.xml b/thermal/1.0/vts/functional/vts/testcases/hal/thermal/hidl/target/AndroidTest.xml
index 169264d..3594745 100644
--- a/thermal/1.0/vts/functional/vts/testcases/hal/thermal/hidl/target/AndroidTest.xml
+++ b/thermal/1.0/vts/functional/vts/testcases/hal/thermal/hidl/target/AndroidTest.xml
@@ -26,6 +26,8 @@
"/>
<option name="binary-test-type" value="gtest" />
<option name="test-timeout" value="5m" />
+ <option name="test-config-path"
+ value="vts/testcases/hal/thermal/hidl/target/ThermalHidlBasicTest.config" />
</test>
</configuration>
diff --git a/thermal/1.0/vts/functional/vts/testcases/hal/thermal/hidl/target/ThermalHidlBasicTest.config b/thermal/1.0/vts/functional/vts/testcases/hal/thermal/hidl/target/ThermalHidlBasicTest.config
new file mode 100644
index 0000000..0d19619
--- /dev/null
+++ b/thermal/1.0/vts/functional/vts/testcases/hal/thermal/hidl/target/ThermalHidlBasicTest.config
@@ -0,0 +1,25 @@
+{
+ "use_gae_db": true,
+ "coverage": true,
+ "modules": [{
+ "module_name": "system/lib64/hw/thermal.bullhead",
+ "git_project": {
+ "name": "device/lge/bullhead",
+ "path": "device/lge/bullhead"
+ }
+ },
+ {
+ "module_name": "system/lib64/hw/thermal.marlin",
+ "git_project": {
+ "name": "device/google/marlin",
+ "path": "device/google/marlin"
+ }
+ },
+ {
+ "module_name": "system/lib64/hw/android.hardware.thermal@1.0-impl",
+ "git_project": {
+ "name": "platform/hardware/interfaces",
+ "path": "hardware/interfaces"
+ }
+ }]
+}
diff --git a/tv/cec/1.0/vts/functional/vts/testcases/hal/tv_cec/hidl/host/TvCecHidlTest.py b/tv/cec/1.0/vts/functional/vts/testcases/hal/tv_cec/hidl/host/TvCecHidlTest.py
index ba062d9..cd2374a 100644
--- a/tv/cec/1.0/vts/functional/vts/testcases/hal/tv_cec/hidl/host/TvCecHidlTest.py
+++ b/tv/cec/1.0/vts/functional/vts/testcases/hal/tv_cec/hidl/host/TvCecHidlTest.py
@@ -34,11 +34,15 @@
self.dut.shell.InvokeTerminal("one")
self.dut.shell.one.Execute("setenforce 0") # SELinux permissive mode
+ self.dut.shell.one.Execute(
+ "setprop vts.hal.vts.hidl.get_stub true")
+
self.dut.hal.InitHidlHal(target_type="tv_cec",
target_basepaths=["/system/lib64"],
target_version=1.0,
target_package="android.hardware.tv.cec",
target_component_name="IHdmiCec",
+ hw_binder_service_name="tv.cec",
bits=64)
def testGetCecVersion1(self):
diff --git a/tv/input/1.0/vts/Android.mk b/tv/input/1.0/vts/Android.mk
index f8610dd..5a60edc 100644
--- a/tv/input/1.0/vts/Android.mk
+++ b/tv/input/1.0/vts/Android.mk
@@ -16,39 +16,6 @@
LOCAL_PATH := $(call my-dir)
-# build VTS driver for TvInput v1.0.
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libvts_driver_hidl_tv_input@1.0
-
-LOCAL_SRC_FILES := \
- TvInput.vts \
- TvInputCallback.vts \
- types.vts \
- ../../../../audio/common/2.0/vts/types.vts \
-
-LOCAL_SHARED_LIBRARIES += \
- android.hardware.tv.input@1.0 \
- libbase \
- libutils \
- libcutils \
- liblog \
- libhidlbase \
- libhidltransport \
- libhwbinder \
- libprotobuf-cpp-full \
- libvts_common \
- libvts_datatype \
- libvts_measurement \
- libvts_multidevice_proto \
-
-LOCAL_PROTOC_OPTIMIZE_TYPE := full
-
-LOCAL_MULTILIB := both
-
-include $(BUILD_SHARED_LIBRARY)
-
-
# build VTS profiler for TvInput
include $(CLEAR_VARS)
diff --git a/vehicle/2.0/Android.mk b/vehicle/2.0/Android.mk
index dc4d25c..71b587b 100644
--- a/vehicle/2.0/Android.mk
+++ b/vehicle/2.0/Android.mk
@@ -663,6 +663,25 @@
LOCAL_GENERATED_SOURCES += $(GEN)
#
+# Build types.hal (VehicleIgnitionState)
+#
+GEN := $(intermediates)/android/hardware/vehicle/V2_0/VehicleIgnitionState.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.vehicle@2.0::types.VehicleIgnitionState
+
+$(GEN): $(LOCAL_PATH)/types.hal
+ $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
# Build types.hal (VehicleInstrumentClusterType)
#
GEN := $(intermediates)/android/hardware/vehicle/V2_0/VehicleInstrumentClusterType.java
@@ -682,25 +701,6 @@
LOCAL_GENERATED_SOURCES += $(GEN)
#
-# Build types.hal (VehiclePermissionModel)
-#
-GEN := $(intermediates)/android/hardware/vehicle/V2_0/VehiclePermissionModel.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.vehicle@2.0::types.VehiclePermissionModel
-
-$(GEN): $(LOCAL_PATH)/types.hal
- $(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN)
-
-#
# Build types.hal (VehiclePropConfig)
#
GEN := $(intermediates)/android/hardware/vehicle/V2_0/VehiclePropConfig.java
@@ -1616,6 +1616,25 @@
LOCAL_GENERATED_SOURCES += $(GEN)
#
+# Build types.hal (VehicleIgnitionState)
+#
+GEN := $(intermediates)/android/hardware/vehicle/V2_0/VehicleIgnitionState.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.vehicle@2.0::types.VehicleIgnitionState
+
+$(GEN): $(LOCAL_PATH)/types.hal
+ $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
# Build types.hal (VehicleInstrumentClusterType)
#
GEN := $(intermediates)/android/hardware/vehicle/V2_0/VehicleInstrumentClusterType.java
@@ -1635,25 +1654,6 @@
LOCAL_GENERATED_SOURCES += $(GEN)
#
-# Build types.hal (VehiclePermissionModel)
-#
-GEN := $(intermediates)/android/hardware/vehicle/V2_0/VehiclePermissionModel.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.vehicle@2.0::types.VehiclePermissionModel
-
-$(GEN): $(LOCAL_PATH)/types.hal
- $(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN)
-
-#
# Build types.hal (VehiclePropConfig)
#
GEN := $(intermediates)/android/hardware/vehicle/V2_0/VehiclePropConfig.java
diff --git a/vehicle/2.0/default/impl/DefaultConfig.h b/vehicle/2.0/default/impl/DefaultConfig.h
index e4ca5ca..77ee9d4 100644
--- a/vehicle/2.0/default/impl/DefaultConfig.h
+++ b/vehicle/2.0/default/impl/DefaultConfig.h
@@ -32,14 +32,12 @@
.prop = VehicleProperty::INFO_MAKE,
.access = VehiclePropertyAccess::READ,
.changeMode = VehiclePropertyChangeMode::STATIC,
- .permissionModel = VehiclePermissionModel::OEM_ONLY,
},
{
.prop = VehicleProperty::HVAC_POWER_ON,
.access = VehiclePropertyAccess::READ_WRITE,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .permissionModel = VehiclePermissionModel::NO_RESTRICTION,
.supportedAreas = toInt(VehicleAreaZone::ROW_1)
},
@@ -47,7 +45,6 @@
.prop = VehicleProperty::HVAC_DEFROSTER,
.access = VehiclePropertyAccess::READ_WRITE,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .permissionModel = VehiclePermissionModel::NO_RESTRICTION,
.supportedAreas =
VehicleAreaWindow::FRONT_WINDSHIELD
| VehicleAreaWindow::REAR_WINDSHIELD
@@ -57,7 +54,6 @@
.prop = VehicleProperty::HVAC_RECIRC_ON,
.access = VehiclePropertyAccess::READ_WRITE,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .permissionModel = VehiclePermissionModel::NO_RESTRICTION,
.supportedAreas = toInt(VehicleAreaZone::ROW_1)
},
@@ -65,7 +61,6 @@
.prop = VehicleProperty::HVAC_AC_ON,
.access = VehiclePropertyAccess::READ_WRITE,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .permissionModel = VehiclePermissionModel::NO_RESTRICTION,
.supportedAreas = toInt(VehicleAreaZone::ROW_1)
},
@@ -73,7 +68,6 @@
.prop = VehicleProperty::HVAC_AUTO_ON,
.access = VehiclePropertyAccess::READ_WRITE,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .permissionModel = VehiclePermissionModel::NO_RESTRICTION,
.supportedAreas = toInt(VehicleAreaZone::ROW_1)
},
@@ -81,7 +75,6 @@
.prop = VehicleProperty::HVAC_FAN_SPEED,
.access = VehiclePropertyAccess::READ_WRITE,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .permissionModel = VehiclePermissionModel::NO_RESTRICTION,
.supportedAreas = toInt(VehicleAreaZone::ROW_1),
.areaConfigs = {
VehicleAreaConfig {
@@ -96,7 +89,6 @@
.prop = VehicleProperty::HVAC_FAN_DIRECTION,
.access = VehiclePropertyAccess::READ_WRITE,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .permissionModel = VehiclePermissionModel::NO_RESTRICTION,
.supportedAreas = toInt(VehicleAreaZone::ROW_1),
},
@@ -104,7 +96,6 @@
.prop = VehicleProperty::HVAC_TEMPERATURE_SET,
.access = VehiclePropertyAccess::READ_WRITE,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .permissionModel = VehiclePermissionModel::NO_RESTRICTION,
.supportedAreas =
VehicleAreaZone::ROW_1_LEFT
| VehicleAreaZone::ROW_1_RIGHT,
@@ -126,28 +117,24 @@
.prop = VehicleProperty::NIGHT_MODE,
.access = VehiclePropertyAccess::READ,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .permissionModel = VehiclePermissionModel::NO_RESTRICTION,
},
{
.prop = VehicleProperty::DRIVING_STATUS,
.access = VehiclePropertyAccess::READ,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .permissionModel = VehiclePermissionModel::NO_RESTRICTION,
},
{
.prop = VehicleProperty::GEAR_SELECTION,
.access = VehiclePropertyAccess::READ,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .permissionModel = VehiclePermissionModel::NO_RESTRICTION,
},
{
.prop = VehicleProperty::INFO_FUEL_CAPACITY,
.access = VehiclePropertyAccess::READ,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .permissionModel = VehiclePermissionModel::OEM_ONLY,
.areaConfigs = {
VehicleAreaConfig {
.minFloatValue = 0,
@@ -160,13 +147,18 @@
.prop = VehicleProperty::DISPLAY_BRIGHTNESS,
.access = VehiclePropertyAccess::READ_WRITE,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .permissionModel = VehiclePermissionModel::OEM_ONLY,
.areaConfigs = {
VehicleAreaConfig {
.minInt32Value = 0,
.maxInt32Value = 10
}
}
+ },
+
+ {
+ .prop = VehicleProperty::IGNITION_STATE,
+ .access = VehiclePropertyAccess::READ,
+ .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
}
};
diff --git a/vehicle/2.0/default/impl/DefaultVehicleHal.cpp b/vehicle/2.0/default/impl/DefaultVehicleHal.cpp
index 4e27bdc..6cbcfe3 100644
--- a/vehicle/2.0/default/impl/DefaultVehicleHal.cpp
+++ b/vehicle/2.0/default/impl/DefaultVehicleHal.cpp
@@ -87,6 +87,9 @@
case VehicleProperty::DRIVING_STATUS:
v = pool.obtainInt32(toInt(VehicleDrivingStatus::UNRESTRICTED));
break;
+ case VehicleProperty::IGNITION_STATE:
+ v = pool.obtainInt32(toInt(VehicleIgnitionState::ACC));
+ break;
default:
*outStatus = StatusCode::INVALID_ARG;
}
diff --git a/vehicle/2.0/default/tests/VehicleHalManager_test.cpp b/vehicle/2.0/default/tests/VehicleHalManager_test.cpp
index 964c7c8..dffcfbb 100644
--- a/vehicle/2.0/default/tests/VehicleHalManager_test.cpp
+++ b/vehicle/2.0/default/tests/VehicleHalManager_test.cpp
@@ -67,6 +67,14 @@
pValue = getValuePool()->obtainFloat(42.42);
}
break;
+ case VehicleProperty::VEHICLE_MAPS_DATA_SERVICE:
+ pValue = getValuePool()->obtainComplex();
+ pValue->value.int32Values = hidl_vec<int32_t> { 10, 20 };
+ pValue->value.int64Values = hidl_vec<int64_t> { 30, 40 };
+ pValue->value.floatValues = hidl_vec<float_t> { 1.1, 2.2 };
+ pValue->value.bytes = hidl_vec<uint8_t> { 1, 2, 3 };
+ pValue->value.stringValue = kCarMake;
+ break;
default:
auto key = makeKey(property, areaId);
if (mValues.count(key) == 0) {
@@ -308,6 +316,32 @@
ASSERT_EQ(StatusCode::OK, res);
}
+TEST_F(VehicleHalManagerTest, get_Complex) {
+ invokeGet(VehicleProperty::VEHICLE_MAPS_DATA_SERVICE, 0);
+
+ ASSERT_EQ(StatusCode::OK, actualStatusCode);
+ ASSERT_EQ(VehicleProperty::VEHICLE_MAPS_DATA_SERVICE, actualValue.prop);
+
+ ASSERT_EQ(3, actualValue.value.bytes.size());
+ ASSERT_EQ(1, actualValue.value.bytes[0]);
+ ASSERT_EQ(2, actualValue.value.bytes[1]);
+ ASSERT_EQ(3, actualValue.value.bytes[2]);
+
+ ASSERT_EQ(2, actualValue.value.int32Values.size());
+ ASSERT_EQ(10, actualValue.value.int32Values[0]);
+ ASSERT_EQ(20, actualValue.value.int32Values[1]);
+
+ ASSERT_EQ(2, actualValue.value.floatValues.size());
+ ASSERT_FLOAT_EQ(1.1, actualValue.value.floatValues[0]);
+ ASSERT_FLOAT_EQ(2.2, actualValue.value.floatValues[1]);
+
+ ASSERT_EQ(2, actualValue.value.int64Values.size());
+ ASSERT_FLOAT_EQ(30, actualValue.value.int64Values[0]);
+ ASSERT_FLOAT_EQ(40, actualValue.value.int64Values[1]);
+
+ ASSERT_STREQ(kCarMake, actualValue.value.stringValue.c_str());
+}
+
TEST_F(VehicleHalManagerTest, get_StaticString) {
invokeGet(VehicleProperty::INFO_MAKE, 0);
diff --git a/vehicle/2.0/default/tests/VehicleHalTestUtils.h b/vehicle/2.0/default/tests/VehicleHalTestUtils.h
index 586b5ab..e1e355e 100644
--- a/vehicle/2.0/default/tests/VehicleHalTestUtils.h
+++ b/vehicle/2.0/default/tests/VehicleHalTestUtils.h
@@ -32,7 +32,6 @@
.prop = VehicleProperty::INFO_MAKE,
.access = VehiclePropertyAccess::READ,
.changeMode = VehiclePropertyChangeMode::STATIC,
- .permissionModel = VehiclePermissionModel::OEM_ONLY,
.configString = "Some=config,options=if,you=have_any",
},
@@ -40,7 +39,6 @@
.prop = VehicleProperty::HVAC_FAN_SPEED,
.access = VehiclePropertyAccess::READ_WRITE,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .permissionModel = VehiclePermissionModel::NO_RESTRICTION,
.supportedAreas = static_cast<int32_t>(
VehicleAreaZone::ROW_1_LEFT | VehicleAreaZone::ROW_1_RIGHT),
.areaConfigs = {
@@ -61,7 +59,6 @@
.prop = VehicleProperty::HVAC_SEAT_TEMPERATURE,
.access = VehiclePropertyAccess::WRITE,
.changeMode = VehiclePropertyChangeMode::ON_SET,
- .permissionModel = VehiclePermissionModel::NO_RESTRICTION,
.supportedAreas = static_cast<int32_t>(
VehicleAreaZone::ROW_1_LEFT | VehicleAreaZone::ROW_1_RIGHT),
.areaConfigs = {
@@ -81,7 +78,6 @@
.prop = VehicleProperty::INFO_FUEL_CAPACITY,
.access = VehiclePropertyAccess::READ,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .permissionModel = VehiclePermissionModel::OEM_ONLY,
.areaConfigs = {
VehicleAreaConfig {
.minFloatValue = 0,
@@ -94,7 +90,6 @@
.prop = VehicleProperty::DISPLAY_BRIGHTNESS,
.access = VehiclePropertyAccess::READ_WRITE,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .permissionModel = VehiclePermissionModel::OEM_ONLY,
.areaConfigs = {
VehicleAreaConfig {
.minInt32Value = 0,
@@ -107,8 +102,14 @@
.prop = VehicleProperty::MIRROR_FOLD,
.access = VehiclePropertyAccess::READ_WRITE,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .permissionModel = VehiclePermissionModel::OEM_ONLY,
+ },
+
+ // Complex data type.
+ {
+ .prop = VehicleProperty::VEHICLE_MAPS_DATA_SERVICE,
+ .access = VehiclePropertyAccess::READ_WRITE,
+ .changeMode = VehiclePropertyChangeMode::ON_CHANGE
}
};
@@ -238,7 +239,6 @@
<< " prop: " << enumToHexString(config.prop) << ",\n"
<< " supportedAreas: " << hexString(config.supportedAreas) << ",\n"
<< " access: " << enumToHexString(config.access) << ",\n"
- << " permissionModel: " << enumToHexString(config.permissionModel) << ",\n"
<< " changeMode: " << enumToHexString(config.changeMode) << ",\n"
<< " configFlags: " << hexString(config.configFlags) << ",\n"
<< " minSampleRate: " << config.minSampleRate << ",\n"
diff --git a/vehicle/2.0/default/vehicle_hal_manager/VehicleObjectPool.cpp b/vehicle/2.0/default/vehicle_hal_manager/VehicleObjectPool.cpp
index 70b93e7..463b333 100644
--- a/vehicle/2.0/default/vehicle_hal_manager/VehicleObjectPool.cpp
+++ b/vehicle/2.0/default/vehicle_hal_manager/VehicleObjectPool.cpp
@@ -80,6 +80,10 @@
return val;
}
+VehiclePropValuePool::RecyclableType VehiclePropValuePool::obtainComplex() {
+ return obtain(VehiclePropertyType::COMPLEX);
+}
+
VehiclePropValuePool::RecyclableType VehiclePropValuePool::obtainRecylable(
VehiclePropertyType type, size_t vecSize) {
// VehiclePropertyType is not overlapping with vectorSize.
diff --git a/vehicle/2.0/default/vehicle_hal_manager/VehicleObjectPool.h b/vehicle/2.0/default/vehicle_hal_manager/VehicleObjectPool.h
index 1ca9211..d9231c3 100644
--- a/vehicle/2.0/default/vehicle_hal_manager/VehicleObjectPool.h
+++ b/vehicle/2.0/default/vehicle_hal_manager/VehicleObjectPool.h
@@ -184,13 +184,15 @@
RecyclableType obtainInt64(int64_t value);
RecyclableType obtainFloat(float value);
RecyclableType obtainString(const char* cstr);
+ RecyclableType obtainComplex();
VehiclePropValuePool(VehiclePropValuePool& ) = delete;
VehiclePropValuePool& operator=(VehiclePropValuePool&) = delete;
private:
bool isDisposable(VehiclePropertyType type, size_t vecSize) const {
return vecSize > mMaxRecyclableVectorSize ||
- VehiclePropertyType::STRING == type;
+ VehiclePropertyType::STRING == type ||
+ VehiclePropertyType::COMPLEX == type;
}
RecyclableType obtainDisposable(VehiclePropertyType valueType,
diff --git a/vehicle/2.0/default/vehicle_hal_manager/VehicleUtils.cpp b/vehicle/2.0/default/vehicle_hal_manager/VehicleUtils.cpp
index c461833..ab1d908 100644
--- a/vehicle/2.0/default/vehicle_hal_manager/VehicleUtils.cpp
+++ b/vehicle/2.0/default/vehicle_hal_manager/VehicleUtils.cpp
@@ -47,6 +47,7 @@
val->value.bytes.resize(vecSize);
break;
case VehiclePropertyType::STRING:
+ case VehiclePropertyType::COMPLEX:
break; // Valid, but nothing to do.
default:
ALOGE("createVehiclePropValue: unknown type: %d", type);
diff --git a/vehicle/2.0/types.hal b/vehicle/2.0/types.hal
index 72fa554..28ccb78 100644
--- a/vehicle/2.0/types.hal
+++ b/vehicle/2.0/types.hal
@@ -31,6 +31,12 @@
FLOAT_VEC = 0x00610000,
BYTES = 0x00700000,
+ /*
+ * Any combination of scalar or vector types. The exact format must be
+ * provided in the description of the property.
+ */
+ COMPLEX = 0x00e00000,
+
MASK = 0x00ff0000
};
@@ -310,6 +316,18 @@
| VehicleArea:GLOBAL),
/*
+ * Represents ignition state
+ *
+ * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+ * @access VehiclePropertyAccess:READ
+ */
+ IGNITION_STATE = (
+ 0x0409
+ | VehiclePropertyGroup:SYSTEM
+ | VehiclePropertyType:INT32
+ | VehicleArea:GLOBAL),
+
+ /*
* Fan speed setting
*
* @change_mode VehiclePropertyChangeMode:ON_CHANGE
@@ -1614,6 +1632,18 @@
| VehiclePropertyGroup:SYSTEM
| VehiclePropertyType:BOOLEAN
| VehicleArea:GLOBAL),
+
+ /*
+ * Vehicle Maps Data Service (VMDS) message
+ *
+ * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+ * @access VehiclePropertyAccess:READ_WRITE
+ */
+ VEHICLE_MAPS_DATA_SERVICE = (
+ 0x0C00
+ | VehiclePropertyGroup:SYSTEM
+ | VehiclePropertyType:COMPLEX
+ | VehicleArea:GLOBAL),
};
/*
@@ -2144,30 +2174,6 @@
};
/*
- * These permissions define how the OEMs want to distribute their information
- * and security they want to apply. On top of these restrictions, android will
- * have additional 'app-level' permissions that the apps will need to ask the
- * user before the apps have the information.
- * This information must be kept in VehiclePropConfig#permissionModel.
- */
-enum VehiclePermissionModel : int32_t {
- /*
- * No special restriction, but each property can still require specific
- * android app-level permission.
- */
- NO_RESTRICTION = 0,
-
- /* Signature only. Only APKs signed with OEM keys are allowed. */
- OEM_ONLY = 0x1,
-
- /* System only. APKs built-in to system can access the property. */
- SYSTEM_APP_ONLY = 0x2,
-
- /* Equivalent to “system|signature” */
- OEM_OR_SYSTEM_APP = 0x3,
-};
-
-/*
* Car states.
*
* The driving states determine what features of the UI will be accessible.
@@ -2311,11 +2317,6 @@
VehiclePropertyChangeMode changeMode;
/*
- * Defines permission model to access the data.
- */
- VehiclePermissionModel permissionModel;
-
- /*
* Some of the properties may have associated areas (for example, some hvac
* properties are associated with VehicleAreaZone), in these
* cases the config may contain an ORed value for the associated areas.
@@ -2405,6 +2406,35 @@
RawValue value;
};
+enum VehicleIgnitionState : int32_t {
+ UNDEFINED = 0,
+
+ /* Steering wheel is locked */
+ LOCK = 1,
+
+ /*
+ * Steering wheel is not locked, engine and all accessories are OFF. If
+ * car can be in LOCK and OFF state at the same time than HAL must report
+ * LOCK state.
+ */
+ OFF,
+
+ /*
+ * Typically in this state accessories become available (e.g. radio).
+ * Instrument cluster and engine are turned off
+ */
+ ACC,
+
+ /*
+ * Ignition is in state ON. Accessories and instrument cluster available,
+ * engine might be running or ready to be started.
+ */
+ ON,
+
+ /* Typically in this state engine is starting (cranking). */
+ START
+};
+
/*
* Represent the operation where the current error has happened.
diff --git a/vehicle/2.0/vts/functional/vts/testcases/hal/vehicle/hidl/host/VehicleHidlTest.py b/vehicle/2.0/vts/functional/vts/testcases/hal/vehicle/hidl/host/VehicleHidlTest.py
index bc37e59..8da36d1 100644
--- a/vehicle/2.0/vts/functional/vts/testcases/hal/vehicle/hidl/host/VehicleHidlTest.py
+++ b/vehicle/2.0/vts/functional/vts/testcases/hal/vehicle/hidl/host/VehicleHidlTest.py
@@ -33,6 +33,7 @@
self.dut = self.registerController(android_device)[0]
self.dut.shell.InvokeTerminal("one")
+ self.dut.shell.one.Execute("setenforce 0") # SELinux permissive mode
if self.enable_profiling:
profiling_utils.EnableVTSProfiling(self.dut.shell.one)
@@ -55,25 +56,13 @@
self.ProcessAndUploadTraceData(self.dut, profiling_trace_path)
profiling_utils.DisableVTSProfiling(self.dut.shell.one)
- def testEcho1(self):
- """A simple testcase which sends a command."""
- self.dut.shell.InvokeTerminal("my_shell1") # creates a remote shell instance.
- results = self.dut.shell.my_shell1.Execute("echo hello_world") # runs a shell command.
- logging.info(str(results[const.STDOUT])) # prints the stdout
- asserts.assertEqual(results[const.STDOUT][0].strip(), "hello_world") # checks the stdout
- asserts.assertEqual(results[const.EXIT_CODE][0], 0) # checks the exit code
+ def testListProperties(self):
+ logging.info("vehicle_types")
+ vehicle_types = self.dut.hal.vehicle.GetHidlTypeInterface("types")
+ logging.info("vehicle_types: %s", vehicle_types)
- def testEcho2(self):
- """A simple testcase which sends two commands."""
- self.dut.shell.InvokeTerminal("my_shell2")
- my_shell = getattr(self.dut.shell, "my_shell2")
- results = my_shell.Execute(["echo hello", "echo world"])
- logging.info(str(results[const.STDOUT]))
- asserts.assertEqual(len(results[const.STDOUT]), 2) # check the number of processed commands
- asserts.assertEqual(results[const.STDOUT][0].strip(), "hello")
- asserts.assertEqual(results[const.STDOUT][1].strip(), "world")
- asserts.assertEqual(results[const.EXIT_CODE][0], 0)
- asserts.assertEqual(results[const.EXIT_CODE][1], 0)
+ allConfigs = self.dut.hal.vehicle.getAllPropConfigs()
+ logging.info("all supported properties: %s", allConfigs)
if __name__ == "__main__":
test_runner.main()
diff --git a/vehicle/2.0/vts/types.vts b/vehicle/2.0/vts/types.vts
index fc63add..99fa6e7 100644
--- a/vehicle/2.0/vts/types.vts
+++ b/vehicle/2.0/vts/types.vts
@@ -1149,6 +1149,10 @@
enum_value: {
scalar_type: "int32_t"
+ enumerator: "NONE"
+ scalar_value: {
+ int32_t: 0
+ }
enumerator: "READ"
scalar_value: {
int32_t: 1
@@ -1165,31 +1169,6 @@
}
attribute: {
- name: "::android::hardware::vehicle::V2_0::VehiclePermissionModel"
- type: TYPE_ENUM
- enum_value: {
- scalar_type: "int32_t"
-
- enumerator: "NO_RESTRICTION"
- scalar_value: {
- int32_t: 0
- }
- enumerator: "OEM_ONLY"
- scalar_value: {
- int32_t: 1
- }
- enumerator: "SYSTEM_APP_ONLY"
- scalar_value: {
- int32_t: 2
- }
- enumerator: "OEM_OR_SYSTEM_APP"
- scalar_value: {
- int32_t: 3
- }
- }
-}
-
-attribute: {
name: "::android::hardware::vehicle::V2_0::VehicleDrivingStatus"
type: TYPE_ENUM
enum_value: {
@@ -1600,11 +1579,6 @@
predefined_type: "::android::hardware::vehicle::V2_0::VehiclePropertyChangeMode"
}
struct_value: {
- name: "permissionModel"
- type: TYPE_ENUM
- predefined_type: "::android::hardware::vehicle::V2_0::VehiclePermissionModel"
- }
- struct_value: {
name: "supportedAreas"
type: TYPE_SCALAR
scalar_type: "int32_t"
diff --git a/vibrator/1.0/vts/functional/vts/testcases/hal/vibrator/hidl/host/VibratorHidlTest.py b/vibrator/1.0/vts/functional/vts/testcases/hal/vibrator/hidl/host/VibratorHidlTest.py
index e8fae30..b36f47a 100644
--- a/vibrator/1.0/vts/functional/vts/testcases/hal/vibrator/hidl/host/VibratorHidlTest.py
+++ b/vibrator/1.0/vts/functional/vts/testcases/hal/vibrator/hidl/host/VibratorHidlTest.py
@@ -48,6 +48,7 @@
target_version=1.0,
target_package="android.hardware.vibrator",
target_component_name="IVibrator",
+ hw_binder_service_name="vibrator",
bits=64)
def tearDownClass(self):
diff --git a/wifi/1.0/vts/functional/Android.bp b/wifi/1.0/vts/functional/Android.bp
new file mode 100644
index 0000000..422eec5
--- /dev/null
+++ b/wifi/1.0/vts/functional/Android.bp
@@ -0,0 +1,50 @@
+//
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+cc_test {
+ name: "wifi_hidl_test",
+ gtest: true,
+ srcs: [
+ "main.cpp",
+ "wifi_ap_iface_hidl_test.cpp",
+ "wifi_chip_hidl_test.cpp",
+ "wifi_hidl_test.cpp",
+ "wifi_hidl_test_utils.cpp",
+ "wifi_nan_iface_hidl_test.cpp",
+ "wifi_p2p_iface_hidl_test.cpp",
+ "wifi_rtt_controller_hidl_test.cpp",
+ "wifi_sta_iface_hidl_test.cpp"],
+ shared_libs: [
+ "libbase",
+ "liblog",
+ "libcutils",
+ "libhidlbase",
+ "libhidltransport",
+ "libhwbinder",
+ "libnativehelper",
+ "libutils",
+ "android.hardware.wifi@1.0",
+ ],
+ static_libs: ["libgtest"],
+ cflags: [
+ "--coverage",
+ "-O0",
+ "-g",
+ ],
+ ldflags: [
+ "--coverage"
+ ]
+}
diff --git a/wifi/1.0/vts/functional/Android.mk b/wifi/1.0/vts/functional/Android.mk
new file mode 100644
index 0000000..f9e3276
--- /dev/null
+++ b/wifi/1.0/vts/functional/Android.mk
@@ -0,0 +1,19 @@
+#
+# 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 $(call all-subdir-makefiles)
diff --git a/wifi/1.0/vts/functional/main.cpp b/wifi/1.0/vts/functional/main.cpp
new file mode 100644
index 0000000..b33b5eb
--- /dev/null
+++ b/wifi/1.0/vts/functional/main.cpp
@@ -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.
+ */
+
+#include <android-base/logging.h>
+
+#include <gtest/gtest.h>
+
+#include "wifi_hidl_test_utils.h"
+
+class WifiHidlEnvironment : public ::testing::Environment {
+ public:
+ virtual void SetUp() override { stopFramework(); }
+ virtual void TearDown() override { startFramework(); }
+
+ private:
+};
+
+int main(int argc, char** argv) {
+ ::testing::AddGlobalTestEnvironment(new WifiHidlEnvironment);
+ ::testing::InitGoogleTest(&argc, argv);
+ int status = RUN_ALL_TESTS();
+ LOG(INFO) << "Test result = " << status;
+ return status;
+}
diff --git a/wifi/1.0/vts/functional/wifi_ap_iface_hidl_test.cpp b/wifi/1.0/vts/functional/wifi_ap_iface_hidl_test.cpp
new file mode 100644
index 0000000..dc7b0b9
--- /dev/null
+++ b/wifi/1.0/vts/functional/wifi_ap_iface_hidl_test.cpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+
+#include <android/hardware/wifi/1.0/IWifiApIface.h>
+
+#include <gtest/gtest.h>
+
+#include "wifi_hidl_test_utils.h"
+
+using ::android::hardware::wifi::V1_0::IWifiApIface;
+using ::android::sp;
+
+/**
+ * Fixture to use for all AP Iface HIDL interface tests.
+ */
+class WifiApIfaceHidlTest : public ::testing::Test {
+ public:
+ virtual void SetUp() override {}
+
+ virtual void TearDown() override { stopWifi(); }
+
+ protected:
+};
+
+/*
+ * Create:
+ * Ensures that an instance of the IWifiApIface proxy object is
+ * successfully created.
+ */
+TEST(WifiApIfaceHidlTestNoFixture, Create) {
+ EXPECT_NE(nullptr, getWifiApIface().get());
+ stopWifi();
+}
diff --git a/wifi/1.0/vts/functional/wifi_chip_hidl_test.cpp b/wifi/1.0/vts/functional/wifi_chip_hidl_test.cpp
new file mode 100644
index 0000000..b6ecd8b
--- /dev/null
+++ b/wifi/1.0/vts/functional/wifi_chip_hidl_test.cpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+
+#include <android/hardware/wifi/1.0/IWifiChip.h>
+
+#include <gtest/gtest.h>
+
+#include "wifi_hidl_test_utils.h"
+
+using ::android::hardware::wifi::V1_0::IWifiChip;
+using ::android::sp;
+
+/**
+ * Fixture to use for all Wifi chip HIDL interface tests.
+ */
+class WifiChipHidlTest : public ::testing::Test {
+ public:
+ virtual void SetUp() override {}
+
+ virtual void TearDown() override { stopWifi(); }
+
+ protected:
+};
+
+/*
+ * Create:
+ * Ensures that an instance of the IWifiChip proxy object is
+ * successfully created.
+ */
+TEST(WifiChipHidlTestNoFixture, Create) {
+ EXPECT_NE(nullptr, getWifiChip().get());
+ stopWifi();
+}
diff --git a/wifi/1.0/vts/functional/wifi_hidl_test.cpp b/wifi/1.0/vts/functional/wifi_hidl_test.cpp
new file mode 100644
index 0000000..3e350e5
--- /dev/null
+++ b/wifi/1.0/vts/functional/wifi_hidl_test.cpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+
+#include <android/hardware/wifi/1.0/IWifi.h>
+
+#include <gtest/gtest.h>
+
+#include "wifi_hidl_test_utils.h"
+
+using ::android::hardware::wifi::V1_0::IWifi;
+using ::android::sp;
+
+/**
+ * Fixture to use for all root Wifi HIDL interface tests.
+ */
+class WifiHidlTest : public ::testing::Test {
+ public:
+ virtual void SetUp() override {}
+
+ virtual void TearDown() override { stopWifi(); }
+
+ protected:
+};
+
+/*
+ * Create:
+ * Ensures that an instance of the IWifi proxy object is
+ * successfully created.
+ */
+TEST(WifiHidlTestNoFixture, Create) {
+ EXPECT_NE(nullptr, getWifi().get());
+ stopWifi();
+}
diff --git a/wifi/1.0/vts/functional/wifi_hidl_test_utils.cpp b/wifi/1.0/vts/functional/wifi_hidl_test_utils.cpp
new file mode 100644
index 0000000..f88b866
--- /dev/null
+++ b/wifi/1.0/vts/functional/wifi_hidl_test_utils.cpp
@@ -0,0 +1,278 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+
+#include "wifi_hidl_test_utils.h"
+
+using ::android::hardware::wifi::V1_0::IWifi;
+using ::android::hardware::wifi::V1_0::IWifiApIface;
+using ::android::hardware::wifi::V1_0::IWifiChip;
+using ::android::hardware::wifi::V1_0::IWifiNanIface;
+using ::android::hardware::wifi::V1_0::IWifiP2pIface;
+using ::android::hardware::wifi::V1_0::IWifiRttController;
+using ::android::hardware::wifi::V1_0::IWifiStaIface;
+using ::android::hardware::wifi::V1_0::ChipModeId;
+using ::android::hardware::wifi::V1_0::ChipId;
+using ::android::hardware::wifi::V1_0::IfaceType;
+using ::android::hardware::wifi::V1_0::WifiStatus;
+using ::android::hardware::wifi::V1_0::WifiStatusCode;
+using ::android::sp;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+
+const char kWifiServiceName[] = "wifi";
+
+void stopFramework() {
+ ASSERT_EQ(std::system("svc wifi disable"), 0);
+ sleep(5);
+}
+
+void startFramework() { ASSERT_EQ(std::system("svc wifi enable"), 0); }
+
+sp<IWifi> getWifi() {
+ sp<IWifi> wifi = IWifi::getService(kWifiServiceName);
+ return wifi;
+}
+
+sp<IWifiChip> getWifiChip() {
+ sp<IWifi> wifi = getWifi();
+ if (!wifi.get()) {
+ return nullptr;
+ }
+
+ bool operation_failed = false;
+ wifi->start([&](WifiStatus status) {
+ if (status.code != WifiStatusCode::SUCCESS) {
+ operation_failed = true;
+ }
+ });
+ if (operation_failed) {
+ return nullptr;
+ }
+
+ std::vector<ChipId> wifi_chip_ids;
+ wifi->getChipIds(
+ [&](const WifiStatus& status, const hidl_vec<ChipId>& chip_ids) {
+ if (status.code != WifiStatusCode::SUCCESS) {
+ operation_failed = true;
+ }
+ wifi_chip_ids = chip_ids;
+ });
+ // We don't expect more than 1 chip currently.
+ if (operation_failed || wifi_chip_ids.size() != 1) {
+ return nullptr;
+ }
+
+ sp<IWifiChip> wifi_chip;
+ wifi->getChip(wifi_chip_ids[0],
+ [&](const WifiStatus& status, const sp<IWifiChip>& chip) {
+ if (status.code != WifiStatusCode::SUCCESS) {
+ operation_failed = true;
+ }
+ wifi_chip = chip;
+ });
+ if (operation_failed) {
+ return nullptr;
+ }
+ return wifi_chip;
+}
+
+// Since we currently only support one iface of each type. Just iterate thru the
+// modes of operation and find the mode ID to use for that iface type.
+bool findModeToSupportIfaceType(IfaceType type,
+ const std::vector<IWifiChip::ChipMode>& modes,
+ ChipModeId* mode_id) {
+ for (const auto& mode : modes) {
+ std::vector<IWifiChip::ChipIfaceCombination> combinations =
+ mode.availableCombinations;
+ for (const auto& combination : combinations) {
+ std::vector<IWifiChip::ChipIfaceCombinationLimit> iface_limits =
+ combination.limits;
+ for (const auto& iface_limit : iface_limits) {
+ std::vector<IfaceType> iface_types = iface_limit.types;
+ for (const auto& iface_type : iface_types) {
+ if (iface_type == type) {
+ *mode_id = mode.id;
+ return true;
+ }
+ }
+ }
+ }
+ }
+ return false;
+}
+
+bool configureChipToSupportIfaceType(const sp<IWifiChip>& wifi_chip,
+ IfaceType type) {
+ bool operation_failed = false;
+ std::vector<IWifiChip::ChipMode> chip_modes;
+ wifi_chip->getAvailableModes(
+ [&](WifiStatus status, const hidl_vec<IWifiChip::ChipMode>& modes) {
+ if (status.code != WifiStatusCode::SUCCESS) {
+ operation_failed = true;
+ }
+ chip_modes = modes;
+ });
+ if (operation_failed) {
+ return false;
+ }
+
+ ChipModeId mode_id;
+ if (!findModeToSupportIfaceType(type, chip_modes, &mode_id)) {
+ return false;
+ }
+
+ wifi_chip->configureChip(mode_id, [&](WifiStatus status) {
+ if (status.code != WifiStatusCode::SUCCESS) {
+ operation_failed = true;
+ }
+ });
+ if (operation_failed) {
+ return false;
+ }
+ return true;
+}
+
+sp<IWifiApIface> getWifiApIface() {
+ sp<IWifiChip> wifi_chip = getWifiChip();
+ if (!wifi_chip.get()) {
+ return nullptr;
+ }
+ if (!configureChipToSupportIfaceType(wifi_chip, IfaceType::AP)) {
+ return nullptr;
+ }
+
+ bool operation_failed = false;
+ sp<IWifiApIface> wifi_ap_iface;
+ wifi_chip->createApIface(
+ [&](const WifiStatus& status, const sp<IWifiApIface>& iface) {
+ if (status.code != WifiStatusCode::SUCCESS) {
+ operation_failed = true;
+ }
+ wifi_ap_iface = iface;
+ });
+ if (operation_failed) {
+ return nullptr;
+ }
+ return wifi_ap_iface;
+}
+
+sp<IWifiNanIface> getWifiNanIface() {
+ sp<IWifiChip> wifi_chip = getWifiChip();
+ if (!wifi_chip.get()) {
+ return nullptr;
+ }
+ if (!configureChipToSupportIfaceType(wifi_chip, IfaceType::NAN)) {
+ return nullptr;
+ }
+
+ bool operation_failed = false;
+ sp<IWifiNanIface> wifi_nan_iface;
+ wifi_chip->createNanIface(
+ [&](const WifiStatus& status, const sp<IWifiNanIface>& iface) {
+ if (status.code != WifiStatusCode::SUCCESS) {
+ operation_failed = true;
+ }
+ wifi_nan_iface = iface;
+ });
+ if (operation_failed) {
+ return nullptr;
+ }
+ return wifi_nan_iface;
+}
+
+sp<IWifiP2pIface> getWifiP2pIface() {
+ sp<IWifiChip> wifi_chip = getWifiChip();
+ if (!wifi_chip.get()) {
+ return nullptr;
+ }
+ if (!configureChipToSupportIfaceType(wifi_chip, IfaceType::P2P)) {
+ return nullptr;
+ }
+
+ bool operation_failed = false;
+ sp<IWifiP2pIface> wifi_p2p_iface;
+ wifi_chip->createP2pIface(
+ [&](const WifiStatus& status, const sp<IWifiP2pIface>& iface) {
+ if (status.code != WifiStatusCode::SUCCESS) {
+ operation_failed = true;
+ }
+ wifi_p2p_iface = iface;
+ });
+ if (operation_failed) {
+ return nullptr;
+ }
+ return wifi_p2p_iface;
+}
+
+sp<IWifiStaIface> getWifiStaIface() {
+ sp<IWifiChip> wifi_chip = getWifiChip();
+ if (!wifi_chip.get()) {
+ return nullptr;
+ }
+ if (!configureChipToSupportIfaceType(wifi_chip, IfaceType::STA)) {
+ return nullptr;
+ }
+
+ bool operation_failed = false;
+ sp<IWifiStaIface> wifi_sta_iface;
+ wifi_chip->createStaIface(
+ [&](const WifiStatus& status, const sp<IWifiStaIface>& iface) {
+ if (status.code != WifiStatusCode::SUCCESS) {
+ operation_failed = true;
+ }
+ wifi_sta_iface = iface;
+ });
+ if (operation_failed) {
+ return nullptr;
+ }
+ return wifi_sta_iface;
+}
+
+sp<IWifiRttController> getWifiRttController() {
+ sp<IWifiChip> wifi_chip = getWifiChip();
+ if (!wifi_chip.get()) {
+ return nullptr;
+ }
+ sp<IWifiStaIface> wifi_sta_iface = getWifiStaIface();
+ if (!wifi_sta_iface.get()) {
+ return nullptr;
+ }
+
+ bool operation_failed = false;
+ sp<IWifiRttController> wifi_rtt_controller;
+ wifi_chip->createRttController(
+ wifi_sta_iface, [&](const WifiStatus& status,
+ const sp<IWifiRttController>& controller) {
+ if (status.code != WifiStatusCode::SUCCESS) {
+ operation_failed = true;
+ }
+ wifi_rtt_controller = controller;
+ });
+ if (operation_failed) {
+ return nullptr;
+ }
+ return wifi_rtt_controller;
+}
+
+void stopWifi() {
+ sp<IWifi> wifi = getWifi();
+ ASSERT_NE(wifi, nullptr);
+ wifi->stop([](const WifiStatus& status) {
+ ASSERT_EQ(status.code, WifiStatusCode::SUCCESS);
+ });
+}
diff --git a/wifi/1.0/vts/functional/wifi_hidl_test_utils.h b/wifi/1.0/vts/functional/wifi_hidl_test_utils.h
new file mode 100644
index 0000000..08933d9
--- /dev/null
+++ b/wifi/1.0/vts/functional/wifi_hidl_test_utils.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android/hardware/wifi/1.0/IWifi.h>
+#include <android/hardware/wifi/1.0/IWifiApIface.h>
+#include <android/hardware/wifi/1.0/IWifiChip.h>
+#include <android/hardware/wifi/1.0/IWifiNanIface.h>
+#include <android/hardware/wifi/1.0/IWifiP2pIface.h>
+#include <android/hardware/wifi/1.0/IWifiRttController.h>
+#include <android/hardware/wifi/1.0/IWifiStaIface.h>
+
+// Used to stop the android framework (wifi service) before every
+// test.
+void stopFramework();
+void startFramework();
+
+// Helper functions to obtain references to the various HIDL interface objects.
+// Note: We only have a single instance of each of these objects currently.
+// These helper functions should be modified to return vectors if we support
+// multiple instances.
+android::sp<android::hardware::wifi::V1_0::IWifi> getWifi();
+android::sp<android::hardware::wifi::V1_0::IWifiChip> getWifiChip();
+android::sp<android::hardware::wifi::V1_0::IWifiApIface> getWifiApIface();
+android::sp<android::hardware::wifi::V1_0::IWifiNanIface> getWifiNanIface();
+android::sp<android::hardware::wifi::V1_0::IWifiP2pIface> getWifiP2pIface();
+android::sp<android::hardware::wifi::V1_0::IWifiStaIface> getWifiStaIface();
+android::sp<android::hardware::wifi::V1_0::IWifiRttController>
+getWifiRttController();
+// Used to trigger IWifi.stop() at the end of every test.
+void stopWifi();
diff --git a/wifi/1.0/vts/functional/wifi_nan_iface_hidl_test.cpp b/wifi/1.0/vts/functional/wifi_nan_iface_hidl_test.cpp
new file mode 100644
index 0000000..a8be48c
--- /dev/null
+++ b/wifi/1.0/vts/functional/wifi_nan_iface_hidl_test.cpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Nanache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+
+#include <android/hardware/wifi/1.0/IWifiNanIface.h>
+
+#include <gtest/gtest.h>
+
+#include "wifi_hidl_test_utils.h"
+
+using ::android::hardware::wifi::V1_0::IWifiNanIface;
+using ::android::sp;
+
+/**
+ * Fixture to use for all NAN Iface HIDL interface tests.
+ */
+class WifiNanIfaceHidlTest : public ::testing::Test {
+ public:
+ virtual void SetUp() override {}
+
+ virtual void TearDown() override { stopWifi(); }
+
+ protected:
+};
+
+/*
+ * Create:
+ * Ensures that an instance of the IWifiNanIface proxy object is
+ * successfully created.
+ */
+TEST(WifiNanIfaceHidlTestNoFixture, Create) {
+ EXPECT_NE(nullptr, getWifiNanIface().get());
+ stopWifi();
+}
diff --git a/wifi/1.0/vts/functional/wifi_p2p_iface_hidl_test.cpp b/wifi/1.0/vts/functional/wifi_p2p_iface_hidl_test.cpp
new file mode 100644
index 0000000..e29226d
--- /dev/null
+++ b/wifi/1.0/vts/functional/wifi_p2p_iface_hidl_test.cpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the P2pache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+
+#include <android/hardware/wifi/1.0/IWifiP2pIface.h>
+
+#include <gtest/gtest.h>
+
+#include "wifi_hidl_test_utils.h"
+
+using ::android::hardware::wifi::V1_0::IWifiP2pIface;
+using ::android::sp;
+
+/**
+ * Fixture to use for all P2P Iface HIDL interface tests.
+ */
+class WifiP2pIfaceHidlTest : public ::testing::Test {
+ public:
+ virtual void SetUp() override {}
+
+ virtual void TearDown() override { stopWifi(); }
+
+ protected:
+};
+
+/*
+ * Create:
+ * Ensures that an instance of the IWifiP2pIface proxy object is
+ * successfully created.
+ */
+TEST(WifiP2pIfaceHidlTestNoFixture, Create) {
+ EXPECT_NE(nullptr, getWifiP2pIface().get());
+ stopWifi();
+}
diff --git a/wifi/1.0/vts/functional/wifi_rtt_controller_hidl_test.cpp b/wifi/1.0/vts/functional/wifi_rtt_controller_hidl_test.cpp
new file mode 100644
index 0000000..7aee761
--- /dev/null
+++ b/wifi/1.0/vts/functional/wifi_rtt_controller_hidl_test.cpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+
+#include <android/hardware/wifi/1.0/IWifiRttController.h>
+
+#include <gtest/gtest.h>
+
+#include "wifi_hidl_test_utils.h"
+
+using ::android::hardware::wifi::V1_0::IWifiRttController;
+using ::android::sp;
+
+/**
+ * Fixture to use for all RTT controller HIDL interface tests.
+ */
+class WifiRttControllerHidlTest : public ::testing::Test {
+ public:
+ virtual void SetUp() override {}
+
+ virtual void TearDown() override { stopWifi(); }
+
+ protected:
+};
+
+/*
+ * Create:
+ * Ensures that an instance of the IWifiRttController proxy object is
+ * successfully created.
+ */
+TEST(WifiRttControllerHidlTestNoFixture, Create) {
+ EXPECT_NE(nullptr, getWifiRttController().get());
+ stopWifi();
+}
diff --git a/wifi/1.0/vts/functional/wifi_sta_iface_hidl_test.cpp b/wifi/1.0/vts/functional/wifi_sta_iface_hidl_test.cpp
new file mode 100644
index 0000000..770763c
--- /dev/null
+++ b/wifi/1.0/vts/functional/wifi_sta_iface_hidl_test.cpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Staache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+
+#include <android/hardware/wifi/1.0/IWifiStaIface.h>
+
+#include <gtest/gtest.h>
+
+#include "wifi_hidl_test_utils.h"
+
+using ::android::hardware::wifi::V1_0::IWifiStaIface;
+using ::android::sp;
+
+/**
+ * Fixture to use for all STA Iface HIDL interface tests.
+ */
+class WifiStaIfaceHidlTest : public ::testing::Test {
+ public:
+ virtual void SetUp() override {}
+
+ virtual void TearDown() override { stopWifi(); }
+
+ protected:
+};
+
+/*
+ * Create:
+ * Ensures that an instance of the IWifiStaIface proxy object is
+ * successfully created.
+ */
+TEST(WifiStaIfaceHidlTestNoFixture, Create) {
+ EXPECT_NE(nullptr, getWifiStaIface().get());
+ stopWifi();
+}
diff --git a/wifi/Android.bp b/wifi/Android.bp
index ea43db4..d4e0fda 100644
--- a/wifi/Android.bp
+++ b/wifi/Android.bp
@@ -1,5 +1,6 @@
// This is an autogenerated file, do not edit.
subdirs = [
"1.0",
+ "1.0/vts/functional",
"supplicant/1.0",
]