Merge "light: add additional vts tests."
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/Android.bp b/boot/1.0/Android.bp
index d67972f..266ef4d 100644
--- a/boot/1.0/Android.bp
+++ b/boot/1.0/Android.bp
@@ -54,3 +54,106 @@
"android.hidl.base@1.0",
],
}
+
+genrule {
+ name: "android.hardware.boot.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.boot@1.0 && $(location vtsc) -mDRIVER -tSOURCE -b$(genDir) android/hardware/boot/1.0/ $(genDir)/android/hardware/boot/1.0/",
+ srcs: [
+ "types.hal",
+ "IBootControl.hal",
+ ],
+ out: [
+ "android/hardware/boot/1.0/types.vts.cpp",
+ "android/hardware/boot/1.0/BootControl.vts.cpp",
+ ],
+}
+
+genrule {
+ name: "android.hardware.boot.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.boot@1.0 && $(location vtsc) -mDRIVER -tHEADER -b$(genDir) android/hardware/boot/1.0/ $(genDir)/android/hardware/boot/1.0/",
+ srcs: [
+ "types.hal",
+ "IBootControl.hal",
+ ],
+ out: [
+ "android/hardware/boot/1.0/types.vts.h",
+ "android/hardware/boot/1.0/BootControl.vts.h",
+ ],
+}
+
+cc_library_shared {
+ name: "android.hardware.boot.vts.driver@1.0",
+ generated_sources: ["android.hardware.boot.vts.driver@1.0_genc++"],
+ generated_headers: ["android.hardware.boot.vts.driver@1.0_genc++_headers"],
+ export_generated_headers: ["android.hardware.boot.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.boot@1.0",
+ ],
+ export_shared_lib_headers: [
+ "libhidlbase",
+ "libhidltransport",
+ "libhwbinder",
+ "libutils",
+ "android.hidl.base@1.0",
+ ],
+}
+
+genrule {
+ name: "android.hardware.boot@1.0-IBootControl-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.boot@1.0 && $(location vtsc) -mPROFILER -tSOURCE -b$(genDir) android/hardware/boot/1.0/ $(genDir)/android/hardware/boot/1.0/",
+ srcs: [
+ "IBootControl.hal",
+ "types.hal",
+ ],
+ out: [
+ "android/hardware/boot/1.0/BootControl.vts.cpp",
+ "android/hardware/boot/1.0/types.vts.cpp",
+ ],
+}
+
+genrule {
+ name: "android.hardware.boot@1.0-IBootControl-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.boot@1.0 && $(location vtsc) -mPROFILER -tHEADER -b$(genDir) android/hardware/boot/1.0/ $(genDir)/android/hardware/boot/1.0/",
+ srcs: [
+ "IBootControl.hal",
+ "types.hal",
+ ],
+ out: [
+ "android/hardware/boot/1.0/BootControl.vts.h",
+ "android/hardware/boot/1.0/types.vts.h",
+ ],
+}
+
+cc_library_shared {
+ name: "android.hardware.boot@1.0-IBootControl-vts.profiler",
+ generated_sources: ["android.hardware.boot@1.0-IBootControl-vts.profiler_genc++"],
+ generated_headers: ["android.hardware.boot@1.0-IBootControl-vts.profiler_genc++_headers"],
+ export_generated_headers: ["android.hardware.boot@1.0-IBootControl-vts.profiler_genc++_headers"],
+ shared_libs: [
+ "libbase",
+ "libhidlbase",
+ "libhidltransport",
+ "libvts_profiling",
+ "libvts_multidevice_proto",
+ "libprotobuf-cpp-full",
+ "android.hidl.base@1.0",
+ "android.hardware.boot@1.0",
+ ],
+}
diff --git a/boot/1.0/vts/Android.mk b/boot/1.0/vts/Android.mk
index 9b30ef1..df5dac8 100644
--- a/boot/1.0/vts/Android.mk
+++ b/boot/1.0/vts/Android.mk
@@ -16,66 +16,4 @@
LOCAL_PATH := $(call my-dir)
-# build VTS driver for Boot Control v1.0.
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libvts_driver_hidl_boot@1.0
-
-LOCAL_SRC_FILES := \
- BootControl.vts \
- types.vts \
-
-LOCAL_SHARED_LIBRARIES += \
- android.hardware.boot@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 boot.
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libvts_profiler_hidl_boot@1.0
-
-LOCAL_SRC_FILES := \
- BootControl.vts \
- types.vts \
-
-LOCAL_C_INCLUDES += \
- test/vts/drivers/libprofiling \
-
-LOCAL_VTS_MODE := PROFILER
-
-LOCAL_SHARED_LIBRARIES := \
- android.hardware.boot@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)
\ No newline at end of file
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/allocator/2.0/default/Gralloc.cpp b/graphics/allocator/2.0/default/Gralloc.cpp
index e3d2703..3a102d1 100644
--- a/graphics/allocator/2.0/default/Gralloc.cpp
+++ b/graphics/allocator/2.0/default/Gralloc.cpp
@@ -47,21 +47,21 @@
Error createDescriptor(
const IAllocatorClient::BufferDescriptorInfo& descriptorInfo,
- BufferDescriptor& outDescriptor);
+ BufferDescriptor* outDescriptor);
Error destroyDescriptor(BufferDescriptor descriptor);
Error testAllocate(const hidl_vec<BufferDescriptor>& descriptors);
Error allocate(const hidl_vec<BufferDescriptor>& descriptors,
- hidl_vec<Buffer>& outBuffers);
+ hidl_vec<Buffer>* outBuffers);
Error free(Buffer buffer);
- Error exportHandle(Buffer buffer, const native_handle_t*& outHandle);
+ Error exportHandle(Buffer buffer, const native_handle_t** outHandle);
private:
void initCapabilities();
template<typename T>
- void initDispatch(T& func, gralloc1_function_descriptor_t desc);
+ void initDispatch(gralloc1_function_descriptor_t desc, T* outPfn);
void initDispatch();
bool hasCapability(Capability capability) const;
@@ -143,35 +143,35 @@
}
template<typename T>
-void GrallocHal::initDispatch(T& func, gralloc1_function_descriptor_t desc)
+void GrallocHal::initDispatch(gralloc1_function_descriptor_t desc, T* outPfn)
{
auto pfn = mDevice->getFunction(mDevice, desc);
if (!pfn) {
LOG_ALWAYS_FATAL("failed to get gralloc1 function %d", desc);
}
- func = reinterpret_cast<T>(pfn);
+ *outPfn = reinterpret_cast<T>(pfn);
}
void GrallocHal::initDispatch()
{
- initDispatch(mDispatch.dump, GRALLOC1_FUNCTION_DUMP);
- initDispatch(mDispatch.createDescriptor,
- GRALLOC1_FUNCTION_CREATE_DESCRIPTOR);
- initDispatch(mDispatch.destroyDescriptor,
- GRALLOC1_FUNCTION_DESTROY_DESCRIPTOR);
- initDispatch(mDispatch.setDimensions, GRALLOC1_FUNCTION_SET_DIMENSIONS);
- initDispatch(mDispatch.setFormat, GRALLOC1_FUNCTION_SET_FORMAT);
+ initDispatch(GRALLOC1_FUNCTION_DUMP, &mDispatch.dump);
+ initDispatch(GRALLOC1_FUNCTION_CREATE_DESCRIPTOR,
+ &mDispatch.createDescriptor);
+ initDispatch(GRALLOC1_FUNCTION_DESTROY_DESCRIPTOR,
+ &mDispatch.destroyDescriptor);
+ initDispatch(GRALLOC1_FUNCTION_SET_DIMENSIONS, &mDispatch.setDimensions);
+ initDispatch(GRALLOC1_FUNCTION_SET_FORMAT, &mDispatch.setFormat);
if (hasCapability(Capability::LAYERED_BUFFERS)) {
- initDispatch(
- mDispatch.setLayerCount, GRALLOC1_FUNCTION_SET_LAYER_COUNT);
+ initDispatch(GRALLOC1_FUNCTION_SET_LAYER_COUNT,
+ &mDispatch.setLayerCount);
}
- initDispatch(mDispatch.setConsumerUsage,
- GRALLOC1_FUNCTION_SET_CONSUMER_USAGE);
- initDispatch(mDispatch.setProducerUsage,
- GRALLOC1_FUNCTION_SET_PRODUCER_USAGE);
- initDispatch(mDispatch.allocate, GRALLOC1_FUNCTION_ALLOCATE);
- initDispatch(mDispatch.release, GRALLOC1_FUNCTION_RELEASE);
+ initDispatch(GRALLOC1_FUNCTION_SET_CONSUMER_USAGE,
+ &mDispatch.setConsumerUsage);
+ initDispatch(GRALLOC1_FUNCTION_SET_PRODUCER_USAGE,
+ &mDispatch.setProducerUsage);
+ initDispatch(GRALLOC1_FUNCTION_ALLOCATE, &mDispatch.allocate);
+ initDispatch(GRALLOC1_FUNCTION_RELEASE, &mDispatch.release);
}
bool GrallocHal::hasCapability(Capability capability) const
@@ -218,7 +218,7 @@
Error GrallocHal::createDescriptor(
const IAllocatorClient::BufferDescriptorInfo& descriptorInfo,
- BufferDescriptor& outDescriptor)
+ BufferDescriptor* outDescriptor)
{
gralloc1_buffer_descriptor_t descriptor;
int32_t err = mDispatch.createDescriptor(mDevice, &descriptor);
@@ -261,7 +261,7 @@
}
if (err == GRALLOC1_ERROR_NONE) {
- outDescriptor = descriptor;
+ *outDescriptor = descriptor;
} else {
mDispatch.destroyDescriptor(mDevice, descriptor);
}
@@ -287,15 +287,15 @@
}
Error GrallocHal::allocate(const hidl_vec<BufferDescriptor>& descriptors,
- hidl_vec<Buffer>& outBuffers)
+ hidl_vec<Buffer>* outBuffers)
{
std::vector<buffer_handle_t> buffers(descriptors.size());
int32_t err = mDispatch.allocate(mDevice, descriptors.size(),
descriptors.data(), buffers.data());
if (err == GRALLOC1_ERROR_NONE || err == GRALLOC1_ERROR_NOT_SHARED) {
- outBuffers.resize(buffers.size());
- for (size_t i = 0; i < outBuffers.size(); i++) {
- outBuffers[i] = static_cast<Buffer>(
+ outBuffers->resize(buffers.size());
+ for (size_t i = 0; i < outBuffers->size(); i++) {
+ (*outBuffers)[i] = static_cast<Buffer>(
reinterpret_cast<uintptr_t>(buffers[i]));
}
}
@@ -313,10 +313,10 @@
}
Error GrallocHal::exportHandle(Buffer buffer,
- const native_handle_t*& outHandle)
+ const native_handle_t** outHandle)
{
// we rely on the caller to validate buffer here
- outHandle = reinterpret_cast<buffer_handle_t>(
+ *outHandle = reinterpret_cast<buffer_handle_t>(
static_cast<uintptr_t>(buffer));
return Error::NONE;
}
@@ -347,8 +347,8 @@
const BufferDescriptorInfo& descriptorInfo,
createDescriptor_cb hidl_cb)
{
- BufferDescriptor descriptor;
- Error err = mHal.createDescriptor(descriptorInfo, descriptor);
+ BufferDescriptor descriptor = 0;
+ Error err = mHal.createDescriptor(descriptorInfo, &descriptor);
if (err == Error::NONE) {
std::lock_guard<std::mutex> lock(mMutex);
@@ -387,7 +387,7 @@
const hidl_vec<BufferDescriptor>& descriptors,
allocate_cb hidl_cb) {
hidl_vec<Buffer> buffers;
- Error err = mHal.allocate(descriptors, buffers);
+ Error err = mHal.allocate(descriptors, &buffers);
if (err == Error::NONE || err == Error::NOT_SHARED) {
std::lock_guard<std::mutex> lock(mMutex);
@@ -440,14 +440,14 @@
}
}
- Error err = mHal.exportHandle(buffer, handle);
+ Error err = mHal.exportHandle(buffer, &handle);
hidl_cb(err, handle);
return Void();
}
IAllocator* HIDL_FETCH_IAllocator(const char* /* name */) {
- const hw_module_t* module;
+ const hw_module_t* module = nullptr;
int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
if (err) {
ALOGE("failed to get gralloc module");
diff --git a/graphics/common/1.0/types.hal b/graphics/common/1.0/types.hal
index 67ff353..e20fedc 100644
--- a/graphics/common/1.0/types.hal
+++ b/graphics/common/1.0/types.hal
@@ -39,9 +39,11 @@
/*
* The following formats use a 16bit float per color component.
+ *
+ * When used with ANativeWindow, the dataSpace field describes the color
+ * space of the buffer.
*/
RGBA_FP16 = 0x16,
- RGBX_FP16 = 0x17,
/*
* 0x101 - 0x1FF
diff --git a/graphics/composer/2.1/Android.bp b/graphics/composer/2.1/Android.bp
index 2bc8e93..26c7739 100644
--- a/graphics/composer/2.1/Android.bp
+++ b/graphics/composer/2.1/Android.bp
@@ -8,11 +8,13 @@
"types.hal",
"IComposer.hal",
"IComposerCallback.hal",
+ "IComposerClient.hal",
],
out: [
"android/hardware/graphics/composer/2.1/types.cpp",
"android/hardware/graphics/composer/2.1/ComposerAll.cpp",
"android/hardware/graphics/composer/2.1/ComposerCallbackAll.cpp",
+ "android/hardware/graphics/composer/2.1/ComposerClientAll.cpp",
],
}
@@ -24,6 +26,7 @@
"types.hal",
"IComposer.hal",
"IComposerCallback.hal",
+ "IComposerClient.hal",
],
out: [
"android/hardware/graphics/composer/2.1/types.h",
@@ -37,6 +40,11 @@
"android/hardware/graphics/composer/2.1/BnComposerCallback.h",
"android/hardware/graphics/composer/2.1/BpComposerCallback.h",
"android/hardware/graphics/composer/2.1/BsComposerCallback.h",
+ "android/hardware/graphics/composer/2.1/IComposerClient.h",
+ "android/hardware/graphics/composer/2.1/IHwComposerClient.h",
+ "android/hardware/graphics/composer/2.1/BnComposerClient.h",
+ "android/hardware/graphics/composer/2.1/BpComposerClient.h",
+ "android/hardware/graphics/composer/2.1/BsComposerClient.h",
],
}
diff --git a/graphics/composer/2.1/IComposer.hal b/graphics/composer/2.1/IComposer.hal
index dd61c11..771fc7d 100644
--- a/graphics/composer/2.1/IComposer.hal
+++ b/graphics/composer/2.1/IComposer.hal
@@ -16,8 +16,7 @@
package android.hardware.graphics.composer@2.1;
-import android.hardware.graphics.common@1.0;
-import IComposerCallback;
+import IComposerClient;
interface IComposer {
/*
@@ -47,210 +46,6 @@
SKIP_CLIENT_COLOR_TRANSFORM = 2,
};
- /* Display attributes queryable through getDisplayAttribute. */
- enum Attribute : int32_t {
- INVALID = 0,
-
- /* Dimensions in pixels */
- WIDTH = 1,
- HEIGHT = 2,
-
- /* Vsync period in nanoseconds */
- VSYNC_PERIOD = 3,
-
- /*
- * Dots per thousand inches (DPI * 1000). Scaling by 1000 allows these
- * numbers to be stored in an int32_t without losing too much
- * precision. If the DPI for a configuration is unavailable or is
- * considered unreliable, the device may return UNSUPPORTED instead.
- */
- DPI_X = 4,
- DPI_Y = 5,
- };
-
- /* Display requests returned by getDisplayRequests. */
- enum DisplayRequest : uint32_t {
- /*
- * Instructs the client to provide a new client target buffer, even if
- * no layers are marked for client composition.
- */
- FLIP_CLIENT_TARGET = 1 << 0,
-
- /*
- * Instructs the client to write the result of client composition
- * directly into the virtual display output buffer. If any of the
- * layers are not marked as Composition::CLIENT or the given display
- * is not a virtual display, this request has no effect.
- */
- WRITE_CLIENT_TARGET_TO_OUTPUT = 1 << 1,
- };
-
- /* Layer requests returned from getDisplayRequests. */
- enum LayerRequest : uint32_t {
- /*
- * The client should clear its target with transparent pixels where
- * this layer would be. The client may ignore this request if the
- * layer must be blended.
- */
- CLEAR_CLIENT_TARGET = 1 << 0,
- };
-
- /* Power modes for use with setPowerMode. */
- enum PowerMode : int32_t {
- /* The display is fully off (blanked). */
- OFF = 0,
-
- /*
- * These are optional low power modes. getDozeSupport may be called to
- * determine whether a given display supports these modes.
- */
-
- /*
- * The display is turned on and configured in a low power state that
- * is suitable for presenting ambient information to the user,
- * possibly with lower fidelity than ON, but with greater efficiency.
- */
- DOZE = 1,
-
- /*
- * The display is configured as in DOZE but may stop applying display
- * updates from the client. This is effectively a hint to the device
- * that drawing to the display has been suspended and that the the
- * device should remain on in a low power state and continue
- * displaying its current contents indefinitely until the power mode
- * changes.
- *
- * This mode may also be used as a signal to enable hardware-based
- * doze functionality. In this case, the device is free to take over
- * the display and manage it autonomously to implement a low power
- * always-on display.
- */
- DOZE_SUSPEND = 3,
-
- /* The display is fully on. */
- ON = 2,
- };
-
- /* Vsync values passed to setVsyncEnabled. */
- enum Vsync : int32_t {
- INVALID = 0,
-
- /* Enable vsync. */
- ENABLE = 1,
-
- /* Disable vsync. */
- DISABLE = 2,
- };
-
- /* Blend modes, settable per layer. */
- enum BlendMode : int32_t {
- INVALID = 0,
-
- /* colorOut = colorSrc */
- NONE = 1,
-
- /* colorOut = colorSrc + colorDst * (1 - alphaSrc) */
- PREMULTIPLIED = 2,
-
- /* colorOut = colorSrc * alphaSrc + colorDst * (1 - alphaSrc) */
- COVERAGE = 3,
- };
-
- /* Possible composition types for a given layer. */
- enum Composition : int32_t {
- INVALID = 0,
-
- /*
- * The client will composite this layer into the client target buffer
- * (provided to the device through setClientTarget).
- *
- * The device must not request any composition type changes for layers
- * of this type.
- */
- CLIENT = 1,
-
- /*
- * The device will handle the composition of this layer through a
- * hardware overlay or other similar means.
- *
- * Upon validateDisplay, the device may request a change from this
- * type to CLIENT.
- */
- DEVICE = 2,
-
- /*
- * The device will render this layer using the color set through
- * setLayerColor. If this functionality is not supported on a layer
- * that the client sets to SOLID_COLOR, the device must request that
- * the composition type of that layer is changed to CLIENT upon the
- * next call to validateDisplay.
- *
- * Upon validateDisplay, the device may request a change from this
- * type to CLIENT.
- */
- SOLID_COLOR = 3,
-
- /*
- * Similar to DEVICE, but the position of this layer may also be set
- * asynchronously through setCursorPosition. If this functionality is
- * not supported on a layer that the client sets to CURSOR, the device
- * must request that the composition type of that layer is changed to
- * CLIENT upon the next call to validateDisplay.
- *
- * Upon validateDisplay, the device may request a change from this
- * type to either DEVICE or CLIENT. Changing to DEVICE will prevent
- * the use of setCursorPosition but still permit the device to
- * composite the layer.
- */
- CURSOR = 4,
-
- /*
- * The device will handle the composition of this layer, as well as
- * its buffer updates and content synchronization. Only supported on
- * devices which provide Capability::SIDEBAND_STREAM.
- *
- * Upon validateDisplay, the device may request a change from this
- * type to either DEVICE or CLIENT, but it is unlikely that content
- * will display correctly in these cases.
- */
- SIDEBAND = 5,
- };
-
- /* Display types returned by getDisplayType. */
- enum DisplayType : int32_t {
- INVALID = 0,
-
- /*
- * All physical displays, including both internal displays and
- * hotpluggable external displays.
- */
- PHYSICAL = 1,
-
- /* Virtual displays created by createVirtualDisplay. */
- VIRTUAL = 2,
- };
-
- struct Rect {
- int32_t left;
- int32_t top;
- int32_t right;
- int32_t bottom;
- };
-
- struct FRect {
- float left;
- float top;
- float right;
- float bottom;
- };
-
- struct Color {
- uint8_t r;
- uint8_t g;
- uint8_t b;
- uint8_t a;
- };
-
/*
* Provides a list of supported capabilities (as described in the
* definition of Capability above). This list must not change after
@@ -269,898 +64,14 @@
dumpDebugInfo() generates (string debugInfo);
/*
- * Provides a IComposerCallback object for the device to call.
+ * Creates a client of the composer. All resources created by the client
+ * are owned by the client and are only visible to the client.
*
- * @param callback is the IComposerCallback object.
- */
- registerCallback(IComposerCallback callback);
-
- /*
- * Returns the maximum number of virtual displays supported by this device
- * (which may be 0). The client will not attempt to create more than this
- * many virtual displays on this device. This number must not change for
- * the lifetime of the device.
- */
- getMaxVirtualDisplayCount() generates (uint32_t count);
-
- /*
- * Creates a new virtual display with the given width and height. The
- * format passed into this function is the default format requested by the
- * consumer of the virtual display output buffers.
- *
- * The display will be assumed to be on from the time the first frame is
- * presented until the display is destroyed.
- *
- * @param width is the width in pixels.
- * @param height is the height in pixels.
- * @param formatHint is the default output buffer format selected by
- * the consumer.
- * @return error is NONE upon success. Otherwise,
- * UNSUPPORTED when the width or height is too large for the
- * device to be able to create a virtual display.
- * NO_RESOURCES when the device is unable to create a new virtual
- * display at this time.
- * @return display is the newly-created virtual display.
- * @return format is the format of the buffer the device will produce.
- */
- createVirtualDisplay(uint32_t width,
- uint32_t height,
- PixelFormat formatHint)
- generates (Error error,
- Display display,
- PixelFormat format);
-
- /*
- * Destroys a virtual display. After this call all resources consumed by
- * this display may be freed by the device and any operations performed on
- * this display should fail.
- *
- * @param display is the virtual display to destroy.
- * @return error is NONE upon success. Otherwise,
- * BAD_DISPLAY when an invalid display handle was passed in.
- * BAD_PARAMETER when the display handle which was passed in does
- * not refer to a virtual display.
- */
- destroyVirtualDisplay(Display display) generates (Error error);
-
- /*
- * Accepts the changes required by the device from the previous
- * validateDisplay call (which may be queried using
- * getChangedCompositionTypes) and revalidates the display. This function
- * is equivalent to requesting the changed types from
- * getChangedCompositionTypes, setting those types on the corresponding
- * layers, and then calling validateDisplay again.
- *
- * After this call it must be valid to present this display. Calling this
- * after validateDisplay returns 0 changes must succeed with NONE, but
- * should have no other effect.
+ * There can only be one client at any time.
*
* @return error is NONE upon success. Otherwise,
- * BAD_DISPLAY when an invalid display handle was passed in.
- * NOT_VALIDATED when validateDisplay has not been called.
+ * NO_RESOURCES when no more client can be created currently.
+ * @return client is the newly created client.
*/
- acceptDisplayChanges(Display display) generates (Error error);
-
- /*
- * Creates a new layer on the given display.
- *
- * @param display is the display on which to create the layer.
- * @return error is NONE upon success. Otherwise,
- * BAD_DISPLAY when an invalid display handle was passed in.
- * NO_RESOURCES when the device was unable to create a layer this
- * time.
- * @return layer is the handle of the new layer.
- */
- createLayer(Display display) generates (Error error, Layer layer);
-
- /*
- * Destroys the given layer.
- *
- * @param display is the display on which the layer was created.
- * @param layer is the layer to destroy.
- * @return error is NONE upon success. Otherwise,
- * BAD_DISPLAY when an invalid display handle was passed in.
- * BAD_LAYER when an invalid layer handle was passed in.
- */
- destroyLayer(Display display, Layer layer) generates (Error error);
-
- /*
- * Retrieves which display configuration is currently active.
- *
- * If no display configuration is currently active, this function must
- * return BAD_CONFIG. It is the responsibility of the client to call
- * setActiveConfig with a valid configuration before attempting to present
- * anything on the display.
- *
- * @param display is the display to which the active config is queried.
- * @return error is NONE upon success. Otherwise,
- * BAD_DISPLAY when an invalid display handle was passed in.
- * BAD_CONFIG when no configuration is currently active.
- * @return config is the currently active display configuration.
- */
- getActiveConfig(Display display) generates (Error error, Config config);
-
- /*
- * Retrieves the layers for which the device requires a different
- * composition type than had been set prior to the last call to
- * validateDisplay. The client will either update its state with these
- * types and call acceptDisplayChanges, or will set new types and attempt
- * to validate the display again.
- *
- * The number of changed layers must be the same as the value returned in
- * numTypes from the last call to validateDisplay.
- *
- * @param display is the display to query.
- * @return error is NONE upon success. Otherwise,
- * BAD_DISPLAY when an invalid display handle was passed in.
- * NOT_VALIDATED when validateDisplay has not been called.
- * @return layers is an array of layer handles.
- * @return types is an array of composition types, each corresponding to
- * an element of layers.
- */
- getChangedCompositionTypes(Display display)
- generates (Error error,
- vec<Layer> layers,
- vec<Composition> types);
-
- /*
- * Returns whether a client target with the given properties can be
- * handled by the device.
- *
- * This function must return true for a client target with width and
- * height equal to the active display configuration dimensions,
- * PixelFormat::RGBA_8888, and Dataspace::UNKNOWN. It is not required to
- * return true for any other configuration.
- *
- * @param display is the display to query.
- * @param width is the client target width in pixels.
- * @param height is the client target height in pixels.
- * @param format is the client target format.
- * @param dataspace is the client target dataspace, as described in
- * setLayerDataspace.
- * @return error is NONE upon success. Otherwise,
- * BAD_DISPLAY when an invalid display handle was passed in.
- * UNSUPPORTED when the given configuration is not supported.
- */
- getClientTargetSupport(Display display,
- uint32_t width,
- uint32_t height,
- PixelFormat format,
- Dataspace dataspace)
- generates (Error error);
-
- /*
- * Returns the color modes supported on this display.
- *
- * All devices must support at least ColorMode::NATIVE.
- *
- * @param display is the display to query.
- * @return error is NONE upon success. Otherwise,
- * BAD_DISPLAY when an invalid display handle was passed in.
- * @return modes is an array of color modes.
- */
- getColorModes(Display display)
- generates (Error error,
- vec<ColorMode> modes);
-
- /*
- * Returns a display attribute value for a particular display
- * configuration.
- *
- * @param display is the display to query.
- * @param config is the display configuration for which to return
- * attribute values.
- * @return error is NONE upon success. Otherwise,
- * BAD_DISPLAY when an invalid display handle was passed in.
- * BAD_CONFIG when config does not name a valid configuration for
- * this display.
- * BAD_PARAMETER when attribute is unrecognized.
- * UNSUPPORTED when attribute cannot be queried for the config.
- * @return value is the value of the attribute.
- */
- getDisplayAttribute(Display display,
- Config config,
- Attribute attribute)
- generates (Error error,
- int32_t value);
-
- /*
- * Returns handles for all of the valid display configurations on this
- * display.
- *
- * @param display is the display to query.
- * @return error is NONE upon success. Otherwise,
- * BAD_DISPLAY when an invalid display handle was passed in.
- * @return configs is an array of configuration handles.
- */
- getDisplayConfigs(Display display)
- generates (Error error,
- vec<Config> configs);
-
- /*
- * Returns a human-readable version of the display's name.
- *
- * @return error is NONE upon success. Otherwise,
- * BAD_DISPLAY when an invalid display handle was passed in.
- * @return name is the name of the display.
- */
- getDisplayName(Display display) generates (Error error, string name);
-
- /*
- * Returns the display requests and the layer requests required for the
- * last validated configuration.
- *
- * Display requests provide information about how the client should handle
- * the client target. Layer requests provide information about how the
- * client should handle an individual layer.
- *
- * The number of layer requests must be equal to the value returned in
- * numRequests from the last call to validateDisplay.
- *
- * @param display is the display to query.
- * @return error is NONE upon success. Otherwise,
- * BAD_DISPLAY when an invalid display handle was passed in.
- * NOT_VALIDATED when validateDisplay has not been called.
- * @return displayRequestMask is the display requests for the current
- * validated state.
- * @return layers is an array of layers which all have at least one
- * request.
- * @return layerRequestMasks is the requests corresponding to each element
- * of layers.
- */
- getDisplayRequests(Display display)
- generates (Error error,
- uint32_t displayRequestMask,
- vec<Layer> layers,
- vec<uint32_t> layerRequestMasks);
-
- /*
- * Returns whether the given display is a physical or virtual display.
- *
- * @param display is the display to query.
- * @return error is NONE upon success. Otherwise,
- * BAD_DISPLAY when an invalid display handle was passed in.
- * @return type is the type of the display.
- */
- getDisplayType(Display display) generates (Error error, DisplayType type);
-
- /*
- * Returns whether the given display supports PowerMode::DOZE and
- * PowerMode::DOZE_SUSPEND. DOZE_SUSPEND may not provide any benefit over
- * DOZE (see the definition of PowerMode for more information), but if
- * both DOZE and DOZE_SUSPEND are no different from PowerMode::ON, the
- * device should not claim support.
- *
- * @param display is the display to query.
- * @return error is NONE upon success. Otherwise,
- * BAD_DISPLAY when an invalid display handle was passed in.
- * @return support is true only when the display supports doze modes.
- */
- getDozeSupport(Display display) generates (Error error, bool support);
-
- /*
- * Returns the high dynamic range (HDR) capabilities of the given display,
- * which are invariant with regard to the active configuration.
- *
- * Displays which are not HDR-capable must return no types.
- *
- * @param display is the display to query.
- * @return error is NONE upon success. Otherwise,
- * BAD_DISPLAY when an invalid display handle was passed in.
- * @return types is an array of HDR types, may have 0 elements if the
- * display is not HDR-capable.
- * @return maxLuminance is the desired content maximum luminance for this
- * display in cd/m^2.
- * @return maxAverageLuminance - the desired content maximum frame-average
- * luminance for this display in cd/m^2.
- * @return minLuminance is the desired content minimum luminance for this
- * display in cd/m^2.
- */
- getHdrCapabilities(Display display)
- generates (Error error,
- vec<Hdr> types,
- float maxLuminance,
- float maxAverageLuminance,
- float minLuminance);
-
- /*
- * Retrieves the release fences for device layers on this display which
- * will receive new buffer contents this frame.
- *
- * A release fence is a file descriptor referring to a sync fence object
- * which will be signaled after the device has finished reading from the
- * buffer presented in the prior frame. This indicates that it is safe to
- * start writing to the buffer again. If a given layer's fence is not
- * returned from this function, it will be assumed that the buffer
- * presented on the previous frame is ready to be written.
- *
- * The fences returned by this function should be unique for each layer
- * (even if they point to the same underlying sync object).
- *
- * @param display is the display to query.
- * @return error is NONE upon success. Otherwise,
- * BAD_DISPLAY when an invalid display handle was passed in.
- * @return layers is an array of layer handles.
- * @return fences is handle that contains an array of sync fence file
- * descriptors as described above, each corresponding to an
- * element of layers.
- */
- getReleaseFences(Display display)
- generates (Error error,
- vec<Layer> layers,
- handle releaseFences);
-
- /*
- * Presents the current display contents on the screen (or in the case of
- * virtual displays, into the output buffer).
- *
- * Prior to calling this function, the display must be successfully
- * validated with validateDisplay. Note that setLayerBuffer and
- * setLayerSurfaceDamage specifically do not count as layer state, so if
- * there are no other changes to the layer state (or to the buffer's
- * properties as described in setLayerBuffer), then it is safe to call
- * this function without first validating the display.
- *
- * If this call succeeds, presentFence will be populated with a file
- * descriptor referring to a present sync fence object. For physical
- * displays, this fence will be signaled at the vsync when the result of
- * composition of this frame starts to appear (for video-mode panels) or
- * starts to transfer to panel memory (for command-mode panels). For
- * virtual displays, this fence will be signaled when writes to the output
- * buffer have completed and it is safe to read from it.
- *
- * @param display is the display to present.
- * @return error is NONE upon success. Otherwise,
- * BAD_DISPLAY when an invalid display handle was passed in.
- * NO_RESOURCES when no valid output buffer has been set for a
- * virtual display.
- * NOT_VALIDATED when validateDisplay has not successfully been
- * called for this display.
- * @return presentFence is a sync fence file descriptor as described
- * above.
- */
- presentDisplay(Display display)
- generates (Error error,
- handle presentFence);
-
- /*
- * Sets the active configuration for this display. Upon returning, the
- * given display configuration should be active and remain so until either
- * this function is called again or the display is disconnected.
- *
- * @param display is the display to which the active config is set.
- * @param config is the new display configuration.
- * @return error is NONE upon success. Otherwise,
- * BAD_DISPLAY when an invalid display handle was passed in.
- * BAD_CONFIG when the configuration handle passed in is not valid
- * for this display.
- */
- setActiveConfig(Display display, Config config) generates (Error error);
-
- /*
- * Sets the buffer handle which will receive the output of client
- * composition. Layers marked as Composition::CLIENT will be composited
- * into this buffer prior to the call to presentDisplay, and layers not
- * marked as Composition::CLIENT should be composited with this buffer by
- * the device.
- *
- * The buffer handle provided may be empty if no layers are being
- * composited by the client. This must not result in an error (unless an
- * invalid display handle is also provided).
- *
- * Also provides a file descriptor referring to an acquire sync fence
- * object, which will be signaled when it is safe to read from the client
- * target buffer. If it is already safe to read from this buffer, an
- * empty handle may be passed instead.
- *
- * For more about dataspaces, see setLayerDataspace.
- *
- * The damage parameter describes a surface damage region as defined in
- * the description of setLayerSurfaceDamage.
- *
- * Will be called before presentDisplay if any of the layers are marked as
- * Composition::CLIENT. If no layers are so marked, then it is not
- * necessary to call this function. It is not necessary to call
- * validateDisplay after changing the target through this function.
- *
- * @param display is the display to which the client target is set.
- * @param target is the new target buffer.
- * @param acquireFence is a sync fence file descriptor as described above.
- * @param dataspace is the dataspace of the buffer, as described in
- * setLayerDataspace.
- * @param damage is the surface damage region.
- * @return error is NONE upon success. Otherwise,
- * BAD_DISPLAY when an invalid display handle was passed in.
- * BAD_PARAMETER when the new target handle was invalid.
- */
- setClientTarget(Display display,
- handle target,
- handle acquireFence,
- Dataspace dataspace,
- vec<Rect> damage)
- generates (Error error);
-
- /*
- * Sets the color mode of the given display.
- *
- * Upon returning from this function, the color mode change must have
- * fully taken effect.
- *
- * All devices must support at least ColorMode::NATIVE, and displays are
- * assumed to be in this mode upon hotplug.
- *
- * @param display is the display to which the color mode is set.
- * @param mode is the mode to set to.
- * @return error is NONE upon success. Otherwise,
- * BAD_DISPLAY when an invalid display handle was passed in.
- * BAD_PARAMETER when mode is not a valid color mode.
- * UNSUPPORTED when mode is not supported on this display.
- */
- setColorMode(Display display, ColorMode mode) generates (Error error);
-
- /*
- * Sets a color transform which will be applied after composition.
- *
- * If hint is not ColorTransform::ARBITRARY, then the device may use the
- * hint to apply the desired color transform instead of using the color
- * matrix directly.
- *
- * If the device is not capable of either using the hint or the matrix to
- * apply the desired color transform, it should force all layers to client
- * composition during validateDisplay.
- *
- * If Capability::SKIP_CLIENT_COLOR_TRANSFORM is present, then the client
- * will never apply the color transform during client composition, even if
- * all layers are being composed by the client.
- *
- * The matrix provided is an affine color transformation of the following
- * form:
- *
- * |r.r r.g r.b 0|
- * |g.r g.g g.b 0|
- * |b.r b.g b.b 0|
- * |Tr Tg Tb 1|
- *
- * This matrix will be provided in row-major form:
- *
- * {r.r, r.g, r.b, 0, g.r, ...}.
- *
- * Given a matrix of this form and an input color [R_in, G_in, B_in], the
- * output color [R_out, G_out, B_out] will be:
- *
- * R_out = R_in * r.r + G_in * g.r + B_in * b.r + Tr
- * G_out = R_in * r.g + G_in * g.g + B_in * b.g + Tg
- * B_out = R_in * r.b + G_in * g.b + B_in * b.b + Tb
- *
- * @param display is the display to which the color transform is set.
- * @param matrix is a 4x4 transform matrix (16 floats) as described above.
- * @param hint is a hint value which may be used instead of the given
- * matrix unless it is ColorTransform::ARBITRARY.
- * @return error is NONE upon success. Otherwise,
- * BAD_DISPLAY when an invalid display handle was passed in.
- * BAD_PARAMETER when hint is not a valid color transform hint.
- */
- setColorTransform(Display display,
- vec<float> matrix,
- ColorTransform hint)
- generates (Error error);
-
- /*
- * Sets the output buffer for a virtual display. That is, the buffer to
- * which the composition result will be written.
- *
- * Also provides a file descriptor referring to a release sync fence
- * object, which will be signaled when it is safe to write to the output
- * buffer. If it is already safe to write to the output buffer, an empty
- * handle may be passed instead.
- *
- * Must be called at least once before presentDisplay, but does not have
- * any interaction with layer state or display validation.
- *
- * @param display is the virtual display to which the output buffer is
- * set.
- * @param buffer is the new output buffer.
- * @param releaseFence is a sync fence file descriptor as described above.
- * @return error is NONE upon success. Otherwise,
- * BAD_DISPLAY when an invalid display handle was passed in.
- * BAD_PARAMETER when the new output buffer handle was invalid.
- * UNSUPPORTED when display does not refer to a virtual display.
- */
- setOutputBuffer(Display display,
- handle buffer,
- handle releaseFence)
- generates (Error error);
-
- /*
- * Sets the power mode of the given display. The transition must be
- * complete when this function returns. It is valid to call this function
- * multiple times with the same power mode.
- *
- * All displays must support PowerMode::ON and PowerMode::OFF. Whether a
- * display supports PowerMode::DOZE or PowerMode::DOZE_SUSPEND may be
- * queried using getDozeSupport.
- *
- * @param display is the display to which the power mode is set.
- * @param mode is the new power mode.
- * @return error is NONE upon success. Otherwise,
- * BAD_DISPLAY when an invalid display handle was passed in.
- * BAD_PARAMETER when mode was not a valid power mode.
- * UNSUPPORTED when mode is not supported on this display.
- */
- setPowerMode(Display display, PowerMode mode) generates (Error error);
-
- /*
- * Enables or disables the vsync signal for the given display. Virtual
- * displays never generate vsync callbacks, and any attempt to enable
- * vsync for a virtual display though this function must succeed and have
- * no other effect.
- *
- * @param display is the display to which the vsync mode is set.
- * @param enabled indicates whether to enable or disable vsync
- * @return error is NONE upon success. Otherwise,
- * BAD_DISPLAY when an invalid display handle was passed in.
- * BAD_PARAMETER when enabled was an invalid value.
- */
- setVsyncEnabled(Display display, Vsync enabled) generates (Error error);
-
- /*
- * Instructs the device to inspect all of the layer state and determine if
- * there are any composition type changes necessary before presenting the
- * display. Permitted changes are described in the definition of
- * Composition above.
- *
- * Also returns the number of layer requests required by the given layer
- * configuration.
- *
- * @param display is the display to validate.
- * @return error is NONE or HAS_CHANGES upon success.
- * NONE when no changes are necessary and it is safe to present
- * the display using the current layer state.
- * HAS_CHANGES when composition type changes are needed.
- * Otherwise,
- * BAD_DISPLAY when an invalid display handle was passed in.
- * @return numTypes is the number of composition type changes required by
- * the device; if greater than 0, the client must either set and
- * validate new types, or call acceptDisplayChanges to accept the
- * changes returned by getChangedCompositionTypes. It must be the
- * same as the number of changes returned by
- * getChangedCompositionTypes (see the declaration of that
- * function for more information).
- * @return numRequests is the number of layer requests required by this
- * layer configuration. It must be equal to the number of layer
- * requests returned by getDisplayRequests (see the declaration of
- * that function for more information).
- */
- validateDisplay(Display display)
- generates (Error error,
- uint32_t numTypes,
- uint32_t numRequests);
-
- /*
- * Layer Functions
- *
- * These are functions which operate on layers, but which do not modify
- * state that must be validated before use. See also 'Layer State
- * Functions' below.
- */
-
- /*
- * Asynchronously sets the position of a cursor layer.
- *
- * Prior to validateDisplay, a layer may be marked as Composition::CURSOR.
- * If validation succeeds (i.e., the device does not request a composition
- * change for that layer), then once a buffer has been set for the layer
- * and it has been presented, its position may be set by this function at
- * any time between presentDisplay and any subsequent validateDisplay
- * calls for this display.
- *
- * Once validateDisplay is called, this function will not be called again
- * until the validate/present sequence is completed.
- *
- * May be called from any thread so long as it is not interleaved with the
- * validate/present sequence as described above.
- *
- * @param display is the display on which the layer was created.
- * @param layer is the layer to which the position is set.
- * @param x is the new x coordinate (in pixels from the left of the
- * screen).
- * @param y is the new y coordinate (in pixels from the top of the
- * screen).
- * @return error is NONE upon success. Otherwise,
- * BAD_DISPLAY when an invalid display handle was passed in.
- * BAD_LAYER when the layer is invalid or is not currently marked
- * as Composition::CURSOR.
- * NOT_VALIDATED when the device is currently in the middle of the
- * validate/present sequence.
- */
- setCursorPosition(Display display,
- Layer layer,
- int32_t x,
- int32_t y)
- generates (Error error);
-
- /*
- * Sets the buffer handle to be displayed for this layer. If the buffer
- * properties set at allocation time (width, height, format, and usage)
- * have not changed since the previous frame, it is not necessary to call
- * validateDisplay before calling presentDisplay unless new state needs to
- * be validated in the interim.
- *
- * Also provides a file descriptor referring to an acquire sync fence
- * object, which will be signaled when it is safe to read from the given
- * buffer. If it is already safe to read from the buffer, an empty handle
- * may be passed instead.
- *
- * This function must return NONE and have no other effect if called for a
- * layer with a composition type of Composition::SOLID_COLOR (because it
- * has no buffer) or Composition::SIDEBAND or Composition::CLIENT (because
- * synchronization and buffer updates for these layers are handled
- * elsewhere).
- *
- * @param display is the display on which the layer was created.
- * @param layer is the layer to which the buffer is set.
- * @param buffer is the buffer handle to set.
- * @param acquireFence is a sync fence file descriptor as described above.
- * @return error is NONE upon success. Otherwise,
- * BAD_DISPLAY when an invalid display handle was passed in.
- * BAD_LAYER when an invalid layer handle was passed in.
- * BAD_PARAMETER when the buffer handle passed in was invalid.
- */
- setLayerBuffer(Display display,
- Layer layer,
- handle buffer,
- handle acquireFence)
- generates (Error error);
-
- /*
- * Provides the region of the source buffer which has been modified since
- * the last frame. This region does not need to be validated before
- * calling presentDisplay.
- *
- * Once set through this function, the damage region remains the same
- * until a subsequent call to this function.
- *
- * If damage is non-empty, then it may be assumed that any portion of the
- * source buffer not covered by one of the rects has not been modified
- * this frame. If damage is empty, then the whole source buffer must be
- * treated as if it has been modified.
- *
- * If the layer's contents are not modified relative to the prior frame,
- * damage will contain exactly one empty rect([0, 0, 0, 0]).
- *
- * The damage rects are relative to the pre-transformed buffer, and their
- * origin is the top-left corner. They will not exceed the dimensions of
- * the latched buffer.
- *
- * @param display is the display on which the layer was created.
- * @param layer is the layer to which the damage region is set.
- * @param damage is the new surface damage region.
- * @return error is NONE upon success. Otherwise,
- * BAD_DISPLAY when an invalid display handle was passed in.
- * BAD_LAYER when an invalid layer handle was passed in.
- */
- setLayerSurfaceDamage(Display display,
- Layer layer,
- vec<Rect> damage)
- generates (Error error);
-
- /*
- * Layer State Functions
- *
- * These functions modify the state of a given layer. They do not take
- * effect until the display configuration is successfully validated with
- * validateDisplay and the display contents are presented with
- * presentDisplay.
- */
-
- /*
- * Sets the blend mode of the given layer.
- *
- * @param display is the display on which the layer was created.
- * @param layer is the layer to which the blend mode is set.
- * @param mode is the new blend mode.
- * @return error is NONE upon success. Otherwise,
- * BAD_DISPLAY when an invalid display handle was passed in.
- * BAD_LAYER when an invalid layer handle was passed in.
- * BAD_PARAMETER when an invalid blend mode was passed in.
- */
- setLayerBlendMode(Display display,
- Layer layer,
- BlendMode mode)
- generates (Error error);
-
- /*
- * Sets the color of the given layer. If the composition type of the layer
- * is not Composition::SOLID_COLOR, this call must succeed and have no
- * other effect.
- *
- * @param display is the display on which the layer was created.
- * @param layer is the layer to which the blend mode is set.
- * @param color is the new color.
- * @return error is NONE upon success. Otherwise,
- * BAD_DISPLAY when an invalid display handle was passed in.
- * BAD_LAYER when an invalid layer handle was passed in.
- */
- setLayerColor(Display display,
- Layer layer,
- Color color)
- generates (Error error);
-
- /*
- * Sets the desired composition type of the given layer. During
- * validateDisplay, the device may request changes to the composition
- * types of any of the layers as described in the definition of
- * Composition above.
- *
- * @param display is the display on which the layer was created.
- * @param layer is the layer to which the blend mode is set.
- * @param type is the new composition type.
- * @return error is NONE upon success. Otherwise,
- * BAD_DISPLAY when an invalid display handle was passed in.
- * BAD_LAYER when an invalid layer handle was passed in.
- * BAD_PARAMETER when an invalid composition type was passed in.
- * UNSUPPORTED when a valid composition type was passed in, but it
- * is not supported by this device.
- */
- setLayerCompositionType(Display display,
- Layer layer,
- Composition type)
- generates (Error error);
-
- /*
- * Sets the dataspace that the current buffer on this layer is in.
- *
- * The dataspace provides more information about how to interpret the
- * buffer contents, such as the encoding standard and color transform.
- *
- * See the values of Dataspace for more information.
- *
- * @param display is the display on which the layer was created.
- * @param layer is the layer to which the dataspace is set.
- * @param dataspace is the new dataspace.
- * @return error is NONE upon success. Otherwise,
- * BAD_DISPLAY when an invalid display handle was passed in.
- * BAD_LAYER when an invalid layer handle was passed in.
- */
- setLayerDataspace(Display display,
- Layer layer,
- Dataspace dataspace)
- generates (Error error);
-
- /*
- * Sets the display frame (the portion of the display covered by a layer)
- * of the given layer. This frame will not exceed the display dimensions.
- *
- * @param display is the display on which the layer was created.
- * @param layer is the layer to which the frame is set.
- * @param frame is the new display frame.
- * @return error is NONE upon success. Otherwise,
- * BAD_DISPLAY when an invalid display handle was passed in.
- * BAD_LAYER when an invalid layer handle was passed in.
- */
- setLayerDisplayFrame(Display display,
- Layer layer,
- Rect frame)
- generates (Error error);
-
- /*
- * Sets an alpha value (a floating point value in the range [0.0, 1.0])
- * which will be applied to the whole layer. It can be conceptualized as a
- * preprocessing step which applies the following function:
- * if (blendMode == BlendMode::PREMULTIPLIED)
- * out.rgb = in.rgb * planeAlpha
- * out.a = in.a * planeAlpha
- *
- * If the device does not support this operation on a layer which is
- * marked Composition::DEVICE, it must request a composition type change
- * to Composition::CLIENT upon the next validateDisplay call.
- *
- * @param display is the display on which the layer was created.
- * @param layer is the layer to which the plane alpha is set.
- * @param alpha is the plane alpha value to apply.
- * @return error is NONE upon success. Otherwise,
- * BAD_DISPLAY when an invalid display handle was passed in.
- * BAD_LAYER when an invalid layer handle was passed in.
- */
- setLayerPlaneAlpha(Display display,
- Layer layer,
- float alpha)
- generates (Error error);
-
- /*
- * Sets the sideband stream for this layer. If the composition type of the
- * given layer is not Composition::SIDEBAND, this call must succeed and
- * have no other effect.
- *
- * @param display is the display on which the layer was created.
- * @param layer is the layer to which the sideband stream is set.
- * @param stream is the new sideband stream.
- * @return error is NONE upon success. Otherwise,
- * BAD_DISPLAY when an invalid display handle was passed in.
- * BAD_LAYER when an invalid layer handle was passed in.
- * BAD_PARAMETER when an invalid sideband stream was passed in.
- */
- setLayerSidebandStream(Display display,
- Layer layer,
- handle stream)
- generates (Error error);
-
- /*
- * Sets the source crop (the portion of the source buffer which will fill
- * the display frame) of the given layer. This crop rectangle will not
- * exceed the dimensions of the latched buffer.
- *
- * If the device is not capable of supporting a true float source crop
- * (i.e., it will truncate or round the floats to integers), it should set
- * this layer to Composition::CLIENT when crop is non-integral for the
- * most accurate rendering.
- *
- * If the device cannot support float source crops, but still wants to
- * handle the layer, it should use the following code (or similar) to
- * convert to an integer crop:
- * intCrop.left = (int) ceilf(crop.left);
- * intCrop.top = (int) ceilf(crop.top);
- * intCrop.right = (int) floorf(crop.right);
- * intCrop.bottom = (int) floorf(crop.bottom);
- *
- * @param display is the display on which the layer was created.
- * @param layer is the layer to which the source crop is set.
- * @param crop is the new source crop.
- * @return error is NONE upon success. Otherwise,
- * BAD_DISPLAY when an invalid display handle was passed in.
- * BAD_LAYER when an invalid layer handle was passed in.
- */
- setLayerSourceCrop(Display display,
- Layer layer,
- FRect crop)
- generates (Error error);
-
- /*
- * Sets the transform (rotation/flip) of the given layer.
- *
- * @param display is the display on which the layer was created.
- * @param layer is the layer to which the transform is set.
- * @param transform is the new transform.
- * @return error is NONE upon success. Otherwise,
- * BAD_DISPLAY when an invalid display handle was passed in.
- * BAD_LAYER when an invalid layer handle was passed in.
- * BAD_PARAMETER when an invalid transform was passed in.
- */
- setLayerTransform(Display display,
- Layer layer,
- Transform transform)
- generates (Error error);
-
- /*
- * Specifies the portion of the layer that is visible, including portions
- * under translucent areas of other layers. The region is in screen space,
- * and will not exceed the dimensions of the screen.
- *
- * @param display is the display on which the layer was created.
- * @param layer is the layer to which the visible region is set.
- * @param visible is the new visible region, in screen space.
- * @return error is NONE upon success. Otherwise,
- * BAD_DISPLAY when an invalid display handle was passed in.
- * BAD_LAYER when an invalid layer handle was passed in.
- */
- setLayerVisibleRegion(Display display,
- Layer layer,
- vec<Rect> visible)
- generates (Error error);
-
- /*
- * Sets the desired Z order (height) of the given layer. A layer with a
- * greater Z value occludes a layer with a lesser Z value.
- *
- * @param display is the display on which the layer was created.
- * @param layer is the layer to which the Z order is set.
- * @param z is the new Z order.
- * @return error is NONE upon success. Otherwise,
- * BAD_DISPLAY when an invalid display handle was passed in.
- * BAD_LAYER when an invalid layer handle was passed in.
- */
- setLayerZOrder(Display display,
- Layer layer,
- uint32_t z)
- generates (Error error);
+ createClient() generates (Error error, IComposerClient client);
};
diff --git a/graphics/composer/2.1/IComposerClient.hal b/graphics/composer/2.1/IComposerClient.hal
new file mode 100644
index 0000000..1a82215
--- /dev/null
+++ b/graphics/composer/2.1/IComposerClient.hal
@@ -0,0 +1,1118 @@
+/*
+ * 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.graphics.composer@2.1;
+
+import android.hardware.graphics.common@1.0;
+import IComposerCallback;
+
+interface IComposerClient {
+ /* Display attributes queryable through getDisplayAttribute. */
+ enum Attribute : int32_t {
+ INVALID = 0,
+
+ /* Dimensions in pixels */
+ WIDTH = 1,
+ HEIGHT = 2,
+
+ /* Vsync period in nanoseconds */
+ VSYNC_PERIOD = 3,
+
+ /*
+ * Dots per thousand inches (DPI * 1000). Scaling by 1000 allows these
+ * numbers to be stored in an int32_t without losing too much
+ * precision. If the DPI for a configuration is unavailable or is
+ * considered unreliable, the device may return UNSUPPORTED instead.
+ */
+ DPI_X = 4,
+ DPI_Y = 5,
+ };
+
+ /* Display requests returned by getDisplayRequests. */
+ enum DisplayRequest : uint32_t {
+ /*
+ * Instructs the client to provide a new client target buffer, even if
+ * no layers are marked for client composition.
+ */
+ FLIP_CLIENT_TARGET = 1 << 0,
+
+ /*
+ * Instructs the client to write the result of client composition
+ * directly into the virtual display output buffer. If any of the
+ * layers are not marked as Composition::CLIENT or the given display
+ * is not a virtual display, this request has no effect.
+ */
+ WRITE_CLIENT_TARGET_TO_OUTPUT = 1 << 1,
+ };
+
+ /* Layer requests returned from getDisplayRequests. */
+ enum LayerRequest : uint32_t {
+ /*
+ * The client must clear its target with transparent pixels where
+ * this layer would be. The client may ignore this request if the
+ * layer must be blended.
+ */
+ CLEAR_CLIENT_TARGET = 1 << 0,
+ };
+
+ /* Power modes for use with setPowerMode. */
+ enum PowerMode : int32_t {
+ /* The display is fully off (blanked). */
+ OFF = 0,
+
+ /*
+ * These are optional low power modes. getDozeSupport may be called to
+ * determine whether a given display supports these modes.
+ */
+
+ /*
+ * The display is turned on and configured in a low power state that
+ * is suitable for presenting ambient information to the user,
+ * possibly with lower fidelity than ON, but with greater efficiency.
+ */
+ DOZE = 1,
+
+ /*
+ * The display is configured as in DOZE but may stop applying display
+ * updates from the client. This is effectively a hint to the device
+ * that drawing to the display has been suspended and that the the
+ * device must remain on in a low power state and continue
+ * displaying its current contents indefinitely until the power mode
+ * changes.
+ *
+ * This mode may also be used as a signal to enable hardware-based
+ * doze functionality. In this case, the device is free to take over
+ * the display and manage it autonomously to implement a low power
+ * always-on display.
+ */
+ DOZE_SUSPEND = 3,
+
+ /* The display is fully on. */
+ ON = 2,
+ };
+
+ /* Vsync values passed to setVsyncEnabled. */
+ enum Vsync : int32_t {
+ INVALID = 0,
+
+ /* Enable vsync. */
+ ENABLE = 1,
+
+ /* Disable vsync. */
+ DISABLE = 2,
+ };
+
+ /* Blend modes, settable per layer. */
+ enum BlendMode : int32_t {
+ INVALID = 0,
+
+ /* colorOut = colorSrc */
+ NONE = 1,
+
+ /* colorOut = colorSrc + colorDst * (1 - alphaSrc) */
+ PREMULTIPLIED = 2,
+
+ /* colorOut = colorSrc * alphaSrc + colorDst * (1 - alphaSrc) */
+ COVERAGE = 3,
+ };
+
+ /* Possible composition types for a given layer. */
+ enum Composition : int32_t {
+ INVALID = 0,
+
+ /*
+ * The client must composite this layer into the client target buffer
+ * (provided to the device through setClientTarget).
+ *
+ * The device must not request any composition type changes for layers
+ * of this type.
+ */
+ CLIENT = 1,
+
+ /*
+ * The device must handle the composition of this layer through a
+ * hardware overlay or other similar means.
+ *
+ * Upon validateDisplay, the device may request a change from this
+ * type to CLIENT.
+ */
+ DEVICE = 2,
+
+ /*
+ * The device must render this layer using the color set through
+ * setLayerColor. If this functionality is not supported on a layer
+ * that the client sets to SOLID_COLOR, the device must request that
+ * the composition type of that layer is changed to CLIENT upon the
+ * next call to validateDisplay.
+ *
+ * Upon validateDisplay, the device may request a change from this
+ * type to CLIENT.
+ */
+ SOLID_COLOR = 3,
+
+ /*
+ * Similar to DEVICE, but the position of this layer may also be set
+ * asynchronously through setCursorPosition. If this functionality is
+ * not supported on a layer that the client sets to CURSOR, the device
+ * must request that the composition type of that layer is changed to
+ * CLIENT upon the next call to validateDisplay.
+ *
+ * Upon validateDisplay, the device may request a change from this
+ * type to either DEVICE or CLIENT. Changing to DEVICE will prevent
+ * the use of setCursorPosition but still permit the device to
+ * composite the layer.
+ */
+ CURSOR = 4,
+
+ /*
+ * The device must handle the composition of this layer, as well as
+ * its buffer updates and content synchronization. Only supported on
+ * devices which provide Capability::SIDEBAND_STREAM.
+ *
+ * Upon validateDisplay, the device may request a change from this
+ * type to either DEVICE or CLIENT, but it is unlikely that content
+ * will display correctly in these cases.
+ */
+ SIDEBAND = 5,
+ };
+
+ /* Display types returned by getDisplayType. */
+ enum DisplayType : int32_t {
+ INVALID = 0,
+
+ /*
+ * All physical displays, including both internal displays and
+ * hotpluggable external displays.
+ */
+ PHYSICAL = 1,
+
+ /* Virtual displays created by createVirtualDisplay. */
+ VIRTUAL = 2,
+ };
+
+ /* Special index values (always negative) for command queue commands. */
+ enum HandleIndex : int32_t {
+ /* No handle */
+ EMPTY = -1,
+
+ /* Use cached handle */
+ CACHED = -2,
+ };
+
+ struct Rect {
+ int32_t left;
+ int32_t top;
+ int32_t right;
+ int32_t bottom;
+ };
+
+ struct FRect {
+ float left;
+ float top;
+ float right;
+ float bottom;
+ };
+
+ struct Color {
+ uint8_t r;
+ uint8_t g;
+ uint8_t b;
+ uint8_t a;
+ };
+
+ /*
+ * Provides a IComposerCallback object for the device to call.
+ *
+ * This function must be called only once.
+ *
+ * @param callback is the IComposerCallback object.
+ */
+ registerCallback(IComposerCallback callback);
+
+ /*
+ * Returns the maximum number of virtual displays supported by this device
+ * (which may be 0). The client must not attempt to create more than this
+ * many virtual displays on this device. This number must not change for
+ * the lifetime of the device.
+ *
+ * @return count is the maximum number of virtual displays supported.
+ */
+ getMaxVirtualDisplayCount() generates (uint32_t count);
+
+ /*
+ * Creates a new virtual display with the given width and height. The
+ * format passed into this function is the default format requested by the
+ * consumer of the virtual display output buffers.
+ *
+ * The display must be assumed to be on from the time the first frame is
+ * presented until the display is destroyed.
+ *
+ * @param width is the width in pixels.
+ * @param height is the height in pixels.
+ * @param formatHint is the default output buffer format selected by
+ * the consumer.
+ * @param outputBufferSlotCount is the number of output buffer slots to be
+ * reserved.
+ * @return error is NONE upon success. Otherwise,
+ * UNSUPPORTED when the width or height is too large for the
+ * device to be able to create a virtual display.
+ * NO_RESOURCES when the device is unable to create a new virtual
+ * display at this time.
+ * @return display is the newly-created virtual display.
+ * @return format is the format of the buffer the device will produce.
+ */
+ createVirtualDisplay(uint32_t width,
+ uint32_t height,
+ PixelFormat formatHint,
+ uint32_t outputBufferSlotCount)
+ generates (Error error,
+ Display display,
+ PixelFormat format);
+
+ /*
+ * Destroys a virtual display. After this call all resources consumed by
+ * this display may be freed by the device and any operations performed on
+ * this display must fail.
+ *
+ * @param display is the virtual display to destroy.
+ * @return error is NONE upon success. Otherwise,
+ * BAD_DISPLAY when an invalid display handle was passed in.
+ * BAD_PARAMETER when the display handle which was passed in does
+ * not refer to a virtual display.
+ */
+ destroyVirtualDisplay(Display display) generates (Error error);
+
+ /*
+ * Creates a new layer on the given display.
+ *
+ * @param display is the display on which to create the layer.
+ * @param bufferSlotCount is the number of buffer slot to be reserved.
+ * @return error is NONE upon success. Otherwise,
+ * BAD_DISPLAY when an invalid display handle was passed in.
+ * NO_RESOURCES when the device was unable to create a layer this
+ * time.
+ * @return layer is the handle of the new layer.
+ */
+ createLayer(Display display,
+ uint32_t bufferSlotCount)
+ generates (Error error,
+ Layer layer);
+
+ /*
+ * Destroys the given layer.
+ *
+ * @param display is the display on which the layer was created.
+ * @param layer is the layer to destroy.
+ * @return error is NONE upon success. Otherwise,
+ * BAD_DISPLAY when an invalid display handle was passed in.
+ * BAD_LAYER when an invalid layer handle was passed in.
+ */
+ destroyLayer(Display display, Layer layer) generates (Error error);
+
+ /*
+ * Retrieves which display configuration is currently active.
+ *
+ * If no display configuration is currently active, this function must
+ * return BAD_CONFIG. It is the responsibility of the client to call
+ * setActiveConfig with a valid configuration before attempting to present
+ * anything on the display.
+ *
+ * @param display is the display to which the active config is queried.
+ * @return error is NONE upon success. Otherwise,
+ * BAD_DISPLAY when an invalid display handle was passed in.
+ * BAD_CONFIG when no configuration is currently active.
+ * @return config is the currently active display configuration.
+ */
+ getActiveConfig(Display display) generates (Error error, Config config);
+
+ /*
+ * Returns whether a client target with the given properties can be
+ * handled by the device.
+ *
+ * This function must return true for a client target with width and
+ * height equal to the active display configuration dimensions,
+ * PixelFormat::RGBA_8888, and Dataspace::UNKNOWN. It is not required to
+ * return true for any other configuration.
+ *
+ * @param display is the display to query.
+ * @param width is the client target width in pixels.
+ * @param height is the client target height in pixels.
+ * @param format is the client target format.
+ * @param dataspace is the client target dataspace, as described in
+ * setLayerDataspace.
+ * @return error is NONE upon success. Otherwise,
+ * BAD_DISPLAY when an invalid display handle was passed in.
+ * UNSUPPORTED when the given configuration is not supported.
+ */
+ getClientTargetSupport(Display display,
+ uint32_t width,
+ uint32_t height,
+ PixelFormat format,
+ Dataspace dataspace)
+ generates (Error error);
+
+ /*
+ * Returns the color modes supported on this display.
+ *
+ * All devices must support at least ColorMode::NATIVE.
+ *
+ * @param display is the display to query.
+ * @return error is NONE upon success. Otherwise,
+ * BAD_DISPLAY when an invalid display handle was passed in.
+ * @return modes is an array of color modes.
+ */
+ getColorModes(Display display)
+ generates (Error error,
+ vec<ColorMode> modes);
+
+ /*
+ * Returns a display attribute value for a particular display
+ * configuration.
+ *
+ * @param display is the display to query.
+ * @param config is the display configuration for which to return
+ * attribute values.
+ * @return error is NONE upon success. Otherwise,
+ * BAD_DISPLAY when an invalid display handle was passed in.
+ * BAD_CONFIG when config does not name a valid configuration for
+ * this display.
+ * BAD_PARAMETER when attribute is unrecognized.
+ * UNSUPPORTED when attribute cannot be queried for the config.
+ * @return value is the value of the attribute.
+ */
+ getDisplayAttribute(Display display,
+ Config config,
+ Attribute attribute)
+ generates (Error error,
+ int32_t value);
+
+ /*
+ * Returns handles for all of the valid display configurations on this
+ * display.
+ *
+ * @param display is the display to query.
+ * @return error is NONE upon success. Otherwise,
+ * BAD_DISPLAY when an invalid display handle was passed in.
+ * @return configs is an array of configuration handles.
+ */
+ getDisplayConfigs(Display display)
+ generates (Error error,
+ vec<Config> configs);
+
+ /*
+ * Returns a human-readable version of the display's name.
+ *
+ * @return error is NONE upon success. Otherwise,
+ * BAD_DISPLAY when an invalid display handle was passed in.
+ * @return name is the name of the display.
+ */
+ getDisplayName(Display display) generates (Error error, string name);
+
+ /*
+ * Returns whether the given display is a physical or virtual display.
+ *
+ * @param display is the display to query.
+ * @return error is NONE upon success. Otherwise,
+ * BAD_DISPLAY when an invalid display handle was passed in.
+ * @return type is the type of the display.
+ */
+ getDisplayType(Display display) generates (Error error, DisplayType type);
+
+ /*
+ * Returns whether the given display supports PowerMode::DOZE and
+ * PowerMode::DOZE_SUSPEND. DOZE_SUSPEND may not provide any benefit over
+ * DOZE (see the definition of PowerMode for more information), but if
+ * both DOZE and DOZE_SUSPEND are no different from PowerMode::ON, the
+ * device must not claim support.
+ *
+ * @param display is the display to query.
+ * @return error is NONE upon success. Otherwise,
+ * BAD_DISPLAY when an invalid display handle was passed in.
+ * @return support is true only when the display supports doze modes.
+ */
+ getDozeSupport(Display display) generates (Error error, bool support);
+
+ /*
+ * Returns the high dynamic range (HDR) capabilities of the given display,
+ * which are invariant with regard to the active configuration.
+ *
+ * Displays which are not HDR-capable must return no types.
+ *
+ * @param display is the display to query.
+ * @return error is NONE upon success. Otherwise,
+ * BAD_DISPLAY when an invalid display handle was passed in.
+ * @return types is an array of HDR types, may have 0 elements if the
+ * display is not HDR-capable.
+ * @return maxLuminance is the desired content maximum luminance for this
+ * display in cd/m^2.
+ * @return maxAverageLuminance - the desired content maximum frame-average
+ * luminance for this display in cd/m^2.
+ * @return minLuminance is the desired content minimum luminance for this
+ * display in cd/m^2.
+ */
+ getHdrCapabilities(Display display)
+ generates (Error error,
+ vec<Hdr> types,
+ float maxLuminance,
+ float maxAverageLuminance,
+ float minLuminance);
+
+ /*
+ * Set the number of client target slots to be reserved.
+ *
+ * @param display is the display to which the slots are reserved.
+ * @param clientTargetSlotCount is the slot count for client targets.
+ * @return error is NONE upon success. Otherwise,
+ * BAD_DISPLAY when an invalid display handle was passed in.
+ * NO_RESOURCES when unable to reserve the slots.
+ */
+ setClientTargetSlotCount(Display display,
+ uint32_t clientTargetSlotCount)
+ generates (Error error);
+
+ /*
+ * Sets the active configuration for this display. Upon returning, the
+ * given display configuration must be active and remain so until either
+ * this function is called again or the display is disconnected.
+ *
+ * @param display is the display to which the active config is set.
+ * @param config is the new display configuration.
+ * @return error is NONE upon success. Otherwise,
+ * BAD_DISPLAY when an invalid display handle was passed in.
+ * BAD_CONFIG when the configuration handle passed in is not valid
+ * for this display.
+ */
+ setActiveConfig(Display display, Config config) generates (Error error);
+
+ /*
+ * Sets the color mode of the given display.
+ *
+ * Upon returning from this function, the color mode change must have
+ * fully taken effect.
+ *
+ * All devices must support at least ColorMode::NATIVE, and displays are
+ * assumed to be in this mode upon hotplug.
+ *
+ * @param display is the display to which the color mode is set.
+ * @param mode is the mode to set to.
+ * @return error is NONE upon success. Otherwise,
+ * BAD_DISPLAY when an invalid display handle was passed in.
+ * BAD_PARAMETER when mode is not a valid color mode.
+ * UNSUPPORTED when mode is not supported on this display.
+ */
+ setColorMode(Display display, ColorMode mode) generates (Error error);
+
+ /*
+ * Sets the power mode of the given display. The transition must be
+ * complete when this function returns. It is valid to call this function
+ * multiple times with the same power mode.
+ *
+ * All displays must support PowerMode::ON and PowerMode::OFF. Whether a
+ * display supports PowerMode::DOZE or PowerMode::DOZE_SUSPEND may be
+ * queried using getDozeSupport.
+ *
+ * @param display is the display to which the power mode is set.
+ * @param mode is the new power mode.
+ * @return error is NONE upon success. Otherwise,
+ * BAD_DISPLAY when an invalid display handle was passed in.
+ * BAD_PARAMETER when mode was not a valid power mode.
+ * UNSUPPORTED when mode is not supported on this display.
+ */
+ setPowerMode(Display display, PowerMode mode) generates (Error error);
+
+ /*
+ * Enables or disables the vsync signal for the given display. Virtual
+ * displays never generate vsync callbacks, and any attempt to enable
+ * vsync for a virtual display though this function must succeed and have
+ * no other effect.
+ *
+ * @param display is the display to which the vsync mode is set.
+ * @param enabled indicates whether to enable or disable vsync
+ * @return error is NONE upon success. Otherwise,
+ * BAD_DISPLAY when an invalid display handle was passed in.
+ * BAD_PARAMETER when enabled was an invalid value.
+ */
+ setVsyncEnabled(Display display, Vsync enabled) generates (Error error);
+
+ /*
+ * Sets the input command message queue.
+ *
+ * @param descriptor is the descriptor of the input command message queue.
+ * @return error is NONE upon success. Otherwise,
+ * NO_RESOURCES when failed to set the queue temporarily.
+ */
+ setInputCommandQueue(MQDescriptorSync descriptor)
+ generates (Error error);
+
+ /*
+ * Gets the output command message queue.
+ *
+ * This function must only be called inside executeCommands closure.
+ *
+ * @return error is NONE upon success. Otherwise,
+ * NO_RESOURCES when failed to get the queue temporarily.
+ * @return descriptor is the descriptor of the output command queue.
+ */
+ getOutputCommandQueue()
+ generates (Error error,
+ MQDescriptorSync descriptor);
+
+ /*
+ * Executes commands from the input command message queue. Return values
+ * generated by the input commands are written to the output command
+ * message queue in the form of value commands.
+ *
+ * @param inLength is the length of input commands.
+ * @param inHandles is an array of handles referenced by the input
+ * commands.
+ * @return error is NONE upon success. Otherwise,
+ * BAD_PARAMETER when inLength is not equal to the length of
+ * commands in the input command message queue.
+ * NO_RESOURCES when the output command message queue was not
+ * properly drained.
+ * @param outQueueChanged indicates whether the output command message
+ * queue has changed.
+ * @param outLength is the length of output commands.
+ * @param outHandles is an array of handles referenced by the output
+ * commands.
+ */
+ executeCommands(uint32_t inLength,
+ vec<handle> inHandles)
+ generates (Error error,
+ bool outQueueChanged,
+ uint32_t outLength,
+ vec<handle> outHandles);
+
+ /*
+ * SELECT_DISPLAY has this pseudo prototype
+ *
+ * selectDisplay(Display display);
+ *
+ * Selects the current display implied by all other commands.
+ *
+ * @param display is the newly selected display.
+ *
+ *
+ * SELECT_LAYER has this pseudo prototype
+ *
+ * selectLayer(Layer layer);
+ *
+ * Selects the current layer implied by all implicit layer commands.
+ *
+ * @param layer is the newly selected layer.
+ *
+ *
+ * SET_ERROR has this pseudo prototype
+ *
+ * setError(uint32_t location, Error error);
+ *
+ * Indicates an error generated by a command.
+ *
+ * @param location is the offset of the command in the input command
+ * message queue.
+ * @param error is the error generated by the command.
+ *
+ *
+ * SET_CHANGED_COMPOSITION_TYPES has this pseudo prototype
+ *
+ * setChangedCompositionTypes(vec<Layer> layers,
+ * vec<Composition> types);
+ *
+ * Sets the layers for which the device requires a different composition
+ * type than had been set prior to the last call to VALIDATE_DISPLAY. The
+ * client must either update its state with these types and call
+ * ACCEPT_DISPLAY_CHANGES, or must set new types and attempt to validate
+ * the display again.
+ *
+ * @param layers is an array of layer handles.
+ * @param types is an array of composition types, each corresponding to
+ * an element of layers.
+ *
+ *
+ * SET_DISPLAY_REQUESTS has this pseudo prototype
+ *
+ * setDisplayRequests(uint32_t displayRequestMask,
+ * vec<Layer> layers,
+ * vec<uint32_t> layerRequestMasks);
+ *
+ * Sets the display requests and the layer requests required for the last
+ * validated configuration.
+ *
+ * Display requests provide information about how the client must handle
+ * the client target. Layer requests provide information about how the
+ * client must handle an individual layer.
+ *
+ * @param displayRequestMask is the display requests for the current
+ * validated state.
+ * @param layers is an array of layers which all have at least one
+ * request.
+ * @param layerRequestMasks is the requests corresponding to each element
+ * of layers.
+ *
+ *
+ * SET_PRESENT_FENCE has this pseudo prototype
+ *
+ * setPresentFence(int32_t presentFenceIndex);
+ *
+ * Sets the present fence as a result of PRESENT_DISPLAY. For physical
+ * displays, this fence must be signaled at the vsync when the result
+ * of composition of this frame starts to appear (for video-mode panels)
+ * or starts to transfer to panel memory (for command-mode panels). For
+ * virtual displays, this fence must be signaled when writes to the output
+ * buffer have completed and it is safe to read from it.
+ *
+ * @param presentFenceIndex is an index into outHandles array.
+ *
+ *
+ * SET_RELEASE_FENCES has this pseudo prototype
+ *
+ * setReleaseFences(vec<Layer> layers,
+ * vec<int32_t> releaseFenceIndices);
+ *
+ * Sets the release fences for device layers on this display which will
+ * receive new buffer contents this frame.
+ *
+ * A release fence is a file descriptor referring to a sync fence object
+ * which must be signaled after the device has finished reading from the
+ * buffer presented in the prior frame. This indicates that it is safe to
+ * start writing to the buffer again. If a given layer's fence is not
+ * returned from this function, it must be assumed that the buffer
+ * presented on the previous frame is ready to be written.
+ *
+ * The fences returned by this function must be unique for each layer
+ * (even if they point to the same underlying sync object).
+ *
+ * @param layers is an array of layer handles.
+ * @param releaseFenceIndices are indices into outHandles array, each
+ * corresponding to an element of layers.
+ *
+ *
+ * SET_COLOR_TRANSFORM has this pseudo prototype
+ *
+ * setColorTransform(float[16] matrix,
+ * ColorTransform hint);
+ *
+ * Sets a color transform which will be applied after composition.
+ *
+ * If hint is not ColorTransform::ARBITRARY, then the device may use the
+ * hint to apply the desired color transform instead of using the color
+ * matrix directly.
+ *
+ * If the device is not capable of either using the hint or the matrix to
+ * apply the desired color transform, it must force all layers to client
+ * composition during VALIDATE_DISPLAY.
+ *
+ * If IComposer::Capability::SKIP_CLIENT_COLOR_TRANSFORM is present, then
+ * the client must never apply the color transform during client
+ * composition, even if all layers are being composed by the client.
+ *
+ * The matrix provided is an affine color transformation of the following
+ * form:
+ *
+ * |r.r r.g r.b 0|
+ * |g.r g.g g.b 0|
+ * |b.r b.g b.b 0|
+ * |Tr Tg Tb 1|
+ *
+ * This matrix must be provided in row-major form:
+ *
+ * {r.r, r.g, r.b, 0, g.r, ...}.
+ *
+ * Given a matrix of this form and an input color [R_in, G_in, B_in], the
+ * output color [R_out, G_out, B_out] will be:
+ *
+ * R_out = R_in * r.r + G_in * g.r + B_in * b.r + Tr
+ * G_out = R_in * r.g + G_in * g.g + B_in * b.g + Tg
+ * B_out = R_in * r.b + G_in * g.b + B_in * b.b + Tb
+ *
+ * @param matrix is a 4x4 transform matrix (16 floats) as described above.
+ * @param hint is a hint value which may be used instead of the given
+ * matrix unless it is ColorTransform::ARBITRARY.
+ *
+ *
+ * SET_CLIENT_TARGET has this pseudo prototype
+ *
+ * setClientTarget(uint32_t targetSlot,
+ * int32_t targetIndex,
+ * int32_t acquireFenceIndex,
+ * Dataspace dataspace,
+ * vec<Rect> damage);
+ *
+ * Sets the buffer handle which will receive the output of client
+ * composition. Layers marked as Composition::CLIENT must be composited
+ * into this buffer prior to the call to PRESENT_DISPLAY, and layers not
+ * marked as Composition::CLIENT must be composited with this buffer by
+ * the device.
+ *
+ * The buffer handle provided may be empty if no layers are being
+ * composited by the client. This must not result in an error (unless an
+ * invalid display handle is also provided).
+ *
+ * Also provides a file descriptor referring to an acquire sync fence
+ * object, which must be signaled when it is safe to read from the client
+ * target buffer. If it is already safe to read from this buffer, an
+ * empty handle may be passed instead.
+ *
+ * For more about dataspaces, see SET_LAYER_DATASPACE.
+ *
+ * The damage parameter describes a surface damage region as defined in
+ * the description of SET_LAYER_SURFACE_DAMAGE.
+ *
+ * Will be called before PRESENT_DISPLAY if any of the layers are marked
+ * as Composition::CLIENT. If no layers are so marked, then it is not
+ * necessary to call this function. It is not necessary to call
+ * validateDisplay after changing the target through this function.
+ *
+ * @param targetSlot is the client target buffer slot to use.
+ * @param targetIndex is an index into inHandles for the new target
+ * buffer.
+ * @param acquireFenceIndex is an index into inHandles for a sync fence
+ * file descriptor as described above.
+ * @param dataspace is the dataspace of the buffer, as described in
+ * setLayerDataspace.
+ * @param damage is the surface damage region.
+ *
+ *
+ * SET_OUTPUT_BUFFER has this pseudo prototype
+ *
+ * setOutputBuffer(uint32_t bufferSlot,
+ * int32_t bufferIndex,
+ * int32_t releaseFenceIndex);
+ *
+ * Sets the output buffer for a virtual display. That is, the buffer to
+ * which the composition result will be written.
+ *
+ * Also provides a file descriptor referring to a release sync fence
+ * object, which must be signaled when it is safe to write to the output
+ * buffer. If it is already safe to write to the output buffer, an empty
+ * handle may be passed instead.
+ *
+ * Must be called at least once before PRESENT_DISPLAY, but does not have
+ * any interaction with layer state or display validation.
+ *
+ * @param bufferSlot is the new output buffer.
+ * @param bufferIndex is the new output buffer.
+ * @param releaseFenceIndex is a sync fence file descriptor as described
+ * above.
+ *
+ *
+ * VALIDATE_DISPLAY has this pseudo prototype
+ *
+ * validateDisplay();
+ *
+ * Instructs the device to inspect all of the layer state and determine if
+ * there are any composition type changes necessary before presenting the
+ * display. Permitted changes are described in the definition of
+ * Composition above.
+ *
+ *
+ * ACCEPT_DISPLAY_CHANGES has this pseudo prototype
+ *
+ * acceptDisplayChanges();
+ *
+ * Accepts the changes required by the device from the previous
+ * validateDisplay call (which may be queried using
+ * getChangedCompositionTypes) and revalidates the display. This function
+ * is equivalent to requesting the changed types from
+ * getChangedCompositionTypes, setting those types on the corresponding
+ * layers, and then calling validateDisplay again.
+ *
+ * After this call it must be valid to present this display. Calling this
+ * after validateDisplay returns 0 changes must succeed with NONE, but
+ * must have no other effect.
+ *
+ *
+ * PRESENT_DISPLAY has this pseudo prototype
+ *
+ * presentDisplay();
+ *
+ * Presents the current display contents on the screen (or in the case of
+ * virtual displays, into the output buffer).
+ *
+ * Prior to calling this function, the display must be successfully
+ * validated with validateDisplay. Note that setLayerBuffer and
+ * setLayerSurfaceDamage specifically do not count as layer state, so if
+ * there are no other changes to the layer state (or to the buffer's
+ * properties as described in setLayerBuffer), then it is safe to call
+ * this function without first validating the display.
+ *
+ *
+ * SET_LAYER_CURSOR_POSITION has this pseudo prototype
+ *
+ * setLayerCursorPosition(int32_t x, int32_t y);
+ *
+ * Asynchronously sets the position of a cursor layer.
+ *
+ * Prior to validateDisplay, a layer may be marked as Composition::CURSOR.
+ * If validation succeeds (i.e., the device does not request a composition
+ * change for that layer), then once a buffer has been set for the layer
+ * and it has been presented, its position may be set by this function at
+ * any time between presentDisplay and any subsequent validateDisplay
+ * calls for this display.
+ *
+ * Once validateDisplay is called, this function must not be called again
+ * until the validate/present sequence is completed.
+ *
+ * May be called from any thread so long as it is not interleaved with the
+ * validate/present sequence as described above.
+ *
+ * @param layer is the layer to which the position is set.
+ * @param x is the new x coordinate (in pixels from the left of the
+ * screen).
+ * @param y is the new y coordinate (in pixels from the top of the
+ * screen).
+ *
+ *
+ * SET_LAYER_BUFFER has this pseudo prototype
+ *
+ * setLayerBuffer(uint32_t bufferSlot,
+ * int32_t bufferIndex,
+ * int32_t acquireFenceIndex);
+ *
+ * Sets the buffer handle to be displayed for this layer. If the buffer
+ * properties set at allocation time (width, height, format, and usage)
+ * have not changed since the previous frame, it is not necessary to call
+ * validateDisplay before calling presentDisplay unless new state needs to
+ * be validated in the interim.
+ *
+ * Also provides a file descriptor referring to an acquire sync fence
+ * object, which must be signaled when it is safe to read from the given
+ * buffer. If it is already safe to read from the buffer, an empty handle
+ * may be passed instead.
+ *
+ * This function must return NONE and have no other effect if called for a
+ * layer with a composition type of Composition::SOLID_COLOR (because it
+ * has no buffer) or Composition::SIDEBAND or Composition::CLIENT (because
+ * synchronization and buffer updates for these layers are handled
+ * elsewhere).
+ *
+ * @param layer is the layer to which the buffer is set.
+ * @param bufferSlot is the buffer slot to use.
+ * @param bufferIndex is the buffer handle to set.
+ * @param acquireFenceIndex is a sync fence file descriptor as described above.
+ *
+ *
+ * SET_LAYER_SURFACE_DAMAGE has this pseudo prototype
+ *
+ * setLayerSurfaceDamage(vec<Rect> damage);
+ *
+ * Provides the region of the source buffer which has been modified since
+ * the last frame. This region does not need to be validated before
+ * calling presentDisplay.
+ *
+ * Once set through this function, the damage region remains the same
+ * until a subsequent call to this function.
+ *
+ * If damage is non-empty, then it may be assumed that any portion of the
+ * source buffer not covered by one of the rects has not been modified
+ * this frame. If damage is empty, then the whole source buffer must be
+ * treated as if it has been modified.
+ *
+ * If the layer's contents are not modified relative to the prior frame,
+ * damage must contain exactly one empty rect([0, 0, 0, 0]).
+ *
+ * The damage rects are relative to the pre-transformed buffer, and their
+ * origin is the top-left corner. They must not exceed the dimensions of
+ * the latched buffer.
+ *
+ * @param layer is the layer to which the damage region is set.
+ * @param damage is the new surface damage region.
+ *
+ *
+ * SET_LAYER_BLEND_MODE has this pseudo prototype
+ *
+ * setLayerBlendMode(BlendMode mode)
+ *
+ * Sets the blend mode of the given layer.
+ *
+ * @param mode is the new blend mode.
+ *
+ *
+ * SET_LAYER_COLOR has this pseudo prototype
+ *
+ * setLayerColor(Color color);
+ *
+ * Sets the color of the given layer. If the composition type of the layer
+ * is not Composition::SOLID_COLOR, this call must succeed and have no
+ * other effect.
+ *
+ * @param color is the new color.
+ *
+ *
+ * SET_LAYER_COMPOSITION_TYPE has this pseudo prototype
+ *
+ * setLayerCompositionType(Composition type);
+ *
+ * Sets the desired composition type of the given layer. During
+ * validateDisplay, the device may request changes to the composition
+ * types of any of the layers as described in the definition of
+ * Composition above.
+ *
+ * @param type is the new composition type.
+ *
+ *
+ * SET_LAYER_DATASPACE has this pseudo prototype
+ *
+ * setLayerDataspace(Dataspace dataspace);
+ *
+ * Sets the dataspace that the current buffer on this layer is in.
+ *
+ * The dataspace provides more information about how to interpret the
+ * buffer contents, such as the encoding standard and color transform.
+ *
+ * See the values of Dataspace for more information.
+ *
+ * @param dataspace is the new dataspace.
+ *
+ *
+ * SET_LAYER_DISPLAY_FRAME has this pseudo prototype
+ *
+ * setLayerDisplayFrame(Rect frame);
+ *
+ * Sets the display frame (the portion of the display covered by a layer)
+ * of the given layer. This frame must not exceed the display dimensions.
+ *
+ * @param frame is the new display frame.
+ *
+ *
+ * SET_LAYER_PLANE_ALPHA has this pseudo prototype
+ *
+ * setLayerPlaneAlpha(float alpha);
+ *
+ * Sets an alpha value (a floating point value in the range [0.0, 1.0])
+ * which will be applied to the whole layer. It can be conceptualized as a
+ * preprocessing step which applies the following function:
+ * if (blendMode == BlendMode::PREMULTIPLIED)
+ * out.rgb = in.rgb * planeAlpha
+ * out.a = in.a * planeAlpha
+ *
+ * If the device does not support this operation on a layer which is
+ * marked Composition::DEVICE, it must request a composition type change
+ * to Composition::CLIENT upon the next validateDisplay call.
+ *
+ * @param alpha is the plane alpha value to apply.
+ *
+ *
+ * SET_LAYER_SIDEBAND_STREAM has this pseudo prototype
+ *
+ * setLayerSidebandStream(int32_t streamIndex)
+ *
+ * Sets the sideband stream for this layer. If the composition type of the
+ * given layer is not Composition::SIDEBAND, this call must succeed and
+ * have no other effect.
+ *
+ * @param streamIndex is the new sideband stream.
+ *
+ *
+ * SET_LAYER_SOURCE_CROP has this pseudo prototype
+ *
+ * setLayerSourceCrop(FRect crop);
+ *
+ * Sets the source crop (the portion of the source buffer which will fill
+ * the display frame) of the given layer. This crop rectangle must not
+ * exceed the dimensions of the latched buffer.
+ *
+ * If the device is not capable of supporting a true float source crop
+ * (i.e., it will truncate or round the floats to integers), it must set
+ * this layer to Composition::CLIENT when crop is non-integral for the
+ * most accurate rendering.
+ *
+ * If the device cannot support float source crops, but still wants to
+ * handle the layer, it must use the following code (or similar) to
+ * convert to an integer crop:
+ * intCrop.left = (int) ceilf(crop.left);
+ * intCrop.top = (int) ceilf(crop.top);
+ * intCrop.right = (int) floorf(crop.right);
+ * intCrop.bottom = (int) floorf(crop.bottom);
+ *
+ * @param crop is the new source crop.
+ *
+ *
+ * SET_LAYER_TRANSFORM has this pseudo prototype
+ *
+ * Sets the transform (rotation/flip) of the given layer.
+ *
+ * setLayerTransform(Transform transform);
+ *
+ * @param transform is the new transform.
+ *
+ *
+ * SET_LAYER_VISIBLE_REGION has this pseudo prototype
+ *
+ * setLayerVisibleRegion(vec<Rect> visible);
+ *
+ * Specifies the portion of the layer that is visible, including portions
+ * under translucent areas of other layers. The region is in screen space,
+ * and must not exceed the dimensions of the screen.
+ *
+ * @param visible is the new visible region, in screen space.
+ *
+ *
+ * SET_LAYER_Z_ORDER has this pseudo prototype
+ *
+ * setLayerZOrder(uint32_t z);
+ *
+ * Sets the desired Z order (height) of the given layer. A layer with a
+ * greater Z value occludes a layer with a lesser Z value.
+ *
+ * @param z is the new Z order.
+ */
+ enum Command : int32_t {
+ LENGTH_MASK = 0xffff,
+ OPCODE_SHIFT = 16,
+ OPCODE_MASK = 0xffff << OPCODE_SHIFT,
+
+ /* special commands */
+ SELECT_DISPLAY = 0x000 << OPCODE_SHIFT,
+ SELECT_LAYER = 0x001 << OPCODE_SHIFT,
+
+ /* value commands (for return values) */
+ SET_ERROR = 0x100 << OPCODE_SHIFT,
+ SET_CHANGED_COMPOSITION_TYPES = 0x101 << OPCODE_SHIFT,
+ SET_DISPLAY_REQUESTS = 0x102 << OPCODE_SHIFT,
+ SET_PRESENT_FENCE = 0x103 << OPCODE_SHIFT,
+ SET_RELEASE_FENCES = 0x104 << OPCODE_SHIFT,
+
+ /* display commands */
+ SET_COLOR_TRANSFORM = 0x200 << OPCODE_SHIFT,
+ SET_CLIENT_TARGET = 0x201 << OPCODE_SHIFT,
+ SET_OUTPUT_BUFFER = 0x202 << OPCODE_SHIFT,
+ VALIDATE_DISPLAY = 0x203 << OPCODE_SHIFT,
+ ACCEPT_DISPLAY_CHANGES = 0x204 << OPCODE_SHIFT,
+ PRESENT_DISPLAY = 0x205 << OPCODE_SHIFT,
+
+ /* layer commands (VALIDATE_DISPLAY not required) */
+ SET_LAYER_CURSOR_POSITION = 0x300 << OPCODE_SHIFT,
+ SET_LAYER_BUFFER = 0x301 << OPCODE_SHIFT,
+ SET_LAYER_SURFACE_DAMAGE = 0x302 << OPCODE_SHIFT,
+
+ /* layer state commands (VALIDATE_DISPLAY required) */
+ SET_LAYER_BLEND_MODE = 0x400 << OPCODE_SHIFT,
+ SET_LAYER_COLOR = 0x401 << OPCODE_SHIFT,
+ SET_LAYER_COMPOSITION_TYPE = 0x402 << OPCODE_SHIFT,
+ SET_LAYER_DATASPACE = 0x403 << OPCODE_SHIFT,
+ SET_LAYER_DISPLAY_FRAME = 0x404 << OPCODE_SHIFT,
+ SET_LAYER_PLANE_ALPHA = 0x405 << OPCODE_SHIFT,
+ SET_LAYER_SIDEBAND_STREAM = 0x406 << OPCODE_SHIFT,
+ SET_LAYER_SOURCE_CROP = 0x407 << OPCODE_SHIFT,
+ SET_LAYER_TRANSFORM = 0x408 << OPCODE_SHIFT,
+ SET_LAYER_VISIBLE_REGION = 0x409 << OPCODE_SHIFT,
+ SET_LAYER_Z_ORDER = 0x40a << OPCODE_SHIFT,
+
+ /* 0x800 - 0xfff are reserved for vendor extensions */
+ /* 0x1000 - 0xffff are reserved */
+ };
+};
diff --git a/graphics/composer/2.1/default/Android.bp b/graphics/composer/2.1/default/Android.bp
index 22f4906..0d63c3c 100644
--- a/graphics/composer/2.1/default/Android.bp
+++ b/graphics/composer/2.1/default/Android.bp
@@ -1,17 +1,19 @@
cc_library_shared {
name: "android.hardware.graphics.composer@2.1-impl",
relative_install_path: "hw",
- srcs: ["Hwc.cpp"],
+ srcs: ["Hwc.cpp", "HwcClient.cpp"],
shared_libs: [
"android.hardware.graphics.allocator@2.0",
"android.hardware.graphics.composer@2.1",
"libbase",
"libcutils",
+ "libfmq",
"libhardware",
"libhidlbase",
"libhidltransport",
"libhwbinder",
"liblog",
+ "libsync",
"libutils",
],
}
@@ -19,7 +21,7 @@
cc_binary {
name: "android.hardware.graphics.composer@2.1-service",
relative_install_path: "hw",
- srcs: ["service.cpp", "Hwc.cpp"],
+ srcs: ["service.cpp", "Hwc.cpp", "HwcClient.cpp"],
cppflags: ["-DBINDERIZED"],
init_rc: ["android.hardware.graphics.composer@2.1-service.rc"],
@@ -29,11 +31,19 @@
"libbase",
"libbinder",
"libcutils",
+ "libfmq",
"libhardware",
"libhidlbase",
"libhidltransport",
"libhwbinder",
"liblog",
+ "libsync",
"libutils",
],
}
+
+cc_library_static {
+ name: "libhwcomposer-command-buffer",
+ shared_libs: ["android.hardware.graphics.composer@2.1"],
+ export_include_dirs: ["."],
+}
diff --git a/graphics/composer/2.1/default/Hwc.cpp b/graphics/composer/2.1/default/Hwc.cpp
index 36c6e54..4efb12b 100644
--- a/graphics/composer/2.1/default/Hwc.cpp
+++ b/graphics/composer/2.1/default/Hwc.cpp
@@ -16,19 +16,12 @@
#define LOG_TAG "HwcPassthrough"
-#include <mutex>
#include <type_traits>
-#include <unordered_map>
-#include <unordered_set>
-#include <utility>
-#include <vector>
-#include <hardware/gralloc.h>
-#include <hardware/gralloc1.h>
-#include <hardware/hwcomposer2.h>
#include <log/log.h>
#include "Hwc.h"
+#include "HwcClient.h"
namespace android {
namespace hardware {
@@ -37,419 +30,9 @@
namespace V2_1 {
namespace implementation {
-using android::hardware::graphics::common::V1_0::PixelFormat;
-using android::hardware::graphics::common::V1_0::Transform;
-using android::hardware::graphics::common::V1_0::Dataspace;
-using android::hardware::graphics::common::V1_0::ColorMode;
-using android::hardware::graphics::common::V1_0::ColorTransform;
-using android::hardware::graphics::common::V1_0::Hdr;
-
-namespace {
-
-class HandleImporter {
-public:
- HandleImporter() : mInitialized(false) {}
-
- bool initialize()
- {
- // allow only one client
- if (mInitialized) {
- return false;
- }
-
- if (!openGralloc()) {
- return false;
- }
-
- mInitialized = true;
- return true;
- }
-
- void cleanup()
- {
- if (!mInitialized) {
- return;
- }
-
- closeGralloc();
- mInitialized = false;
- }
-
- // In IComposer, any buffer_handle_t is owned by the caller and we need to
- // make a clone for hwcomposer2. We also need to translate empty handle
- // to nullptr. This function does that, in-place.
- bool importBuffer(buffer_handle_t& handle)
- {
- if (!handle->numFds && !handle->numInts) {
- handle = nullptr;
- return true;
- }
-
- buffer_handle_t clone = cloneBuffer(handle);
- if (!clone) {
- return false;
- }
-
- handle = clone;
- return true;
- }
-
- void freeBuffer(buffer_handle_t handle)
- {
- if (!handle) {
- return;
- }
-
- releaseBuffer(handle);
- }
-
- bool importFence(const native_handle_t* handle, int& fd)
- {
- if (handle->numFds == 0) {
- fd = -1;
- } else if (handle->numFds == 1) {
- fd = dup(handle->data[0]);
- if (fd < 0) {
- ALOGE("failed to dup fence fd %d", handle->data[0]);
- return false;
- }
- } else {
- ALOGE("invalid fence handle with %d file descriptors",
- handle->numFds);
- return false;
- }
-
- return true;
- }
-
- void closeFence(int fd)
- {
- if (fd >= 0) {
- close(fd);
- }
- }
-
-private:
- bool mInitialized;
-
- // Some existing gralloc drivers do not support retaining more than once,
- // when we are in passthrough mode.
-#ifdef BINDERIZED
- bool openGralloc()
- {
- const hw_module_t* module;
- int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
- if (err) {
- ALOGE("failed to get gralloc module");
- return false;
- }
-
- uint8_t major = (module->module_api_version >> 8) & 0xff;
- if (major > 1) {
- ALOGE("unknown gralloc module major version %d", major);
- return false;
- }
-
- if (major == 1) {
- err = gralloc1_open(module, &mDevice);
- if (err) {
- ALOGE("failed to open gralloc1 device");
- return false;
- }
-
- mRetain = reinterpret_cast<GRALLOC1_PFN_RETAIN>(
- mDevice->getFunction(mDevice, GRALLOC1_FUNCTION_RETAIN));
- mRelease = reinterpret_cast<GRALLOC1_PFN_RELEASE>(
- mDevice->getFunction(mDevice, GRALLOC1_FUNCTION_RELEASE));
- if (!mRetain || !mRelease) {
- ALOGE("invalid gralloc1 device");
- gralloc1_close(mDevice);
- return false;
- }
- } else {
- mModule = reinterpret_cast<const gralloc_module_t*>(module);
- }
-
- return true;
- }
-
- void closeGralloc()
- {
- if (mDevice) {
- gralloc1_close(mDevice);
- }
- }
-
- buffer_handle_t cloneBuffer(buffer_handle_t handle)
- {
- native_handle_t* clone = native_handle_clone(handle);
- if (!clone) {
- ALOGE("failed to clone buffer %p", handle);
- return nullptr;
- }
-
- bool err;
- if (mDevice) {
- err = (mRetain(mDevice, clone) != GRALLOC1_ERROR_NONE);
- } else {
- err = (mModule->registerBuffer(mModule, clone) != 0);
- }
-
- if (err) {
- ALOGE("failed to retain/register buffer %p", clone);
- native_handle_close(clone);
- native_handle_delete(clone);
- return nullptr;
- }
-
- return clone;
- }
-
- void releaseBuffer(buffer_handle_t handle)
- {
- if (mDevice) {
- mRelease(mDevice, handle);
- } else {
- mModule->unregisterBuffer(mModule, handle);
- native_handle_close(handle);
- native_handle_delete(const_cast<native_handle_t*>(handle));
- }
- }
-
- // gralloc1
- gralloc1_device_t* mDevice;
- GRALLOC1_PFN_RETAIN mRetain;
- GRALLOC1_PFN_RELEASE mRelease;
-
- // gralloc0
- const gralloc_module_t* mModule;
-#else
- bool openGralloc() { return true; }
- void closeGralloc() {}
- buffer_handle_t cloneBuffer(buffer_handle_t handle) { return handle; }
- void releaseBuffer(buffer_handle_t) {}
-#endif
-};
-
-HandleImporter sHandleImporter;
-
-class BufferClone {
-public:
- BufferClone() : mHandle(nullptr) {}
-
- BufferClone(BufferClone&& other)
- {
- mHandle = other.mHandle;
- other.mHandle = nullptr;
- }
-
- BufferClone(const BufferClone& other) = delete;
- BufferClone& operator=(const BufferClone& other) = delete;
-
- BufferClone& operator=(buffer_handle_t handle)
- {
- clear();
- mHandle = handle;
- return *this;
- }
-
- ~BufferClone()
- {
- clear();
- }
-
-private:
- void clear()
- {
- if (mHandle) {
- sHandleImporter.freeBuffer(mHandle);
- }
- }
-
- buffer_handle_t mHandle;
-};
-
-} // anonymous namespace
-
-class HwcHal : public IComposer {
-public:
- HwcHal(const hw_module_t* module);
- virtual ~HwcHal();
-
- // IComposer interface
- Return<void> getCapabilities(getCapabilities_cb hidl_cb) override;
- Return<void> dumpDebugInfo(dumpDebugInfo_cb hidl_cb) override;
- Return<void> registerCallback(const sp<IComposerCallback>& callback) override;
- Return<uint32_t> getMaxVirtualDisplayCount() override;
- Return<void> createVirtualDisplay(uint32_t width, uint32_t height,
- PixelFormat formatHint, createVirtualDisplay_cb hidl_cb) override;
- Return<Error> destroyVirtualDisplay(Display display) override;
- Return<Error> acceptDisplayChanges(Display display) override;
- Return<void> createLayer(Display display,
- createLayer_cb hidl_cb) override;
- Return<Error> destroyLayer(Display display, Layer layer) override;
- Return<void> getActiveConfig(Display display,
- getActiveConfig_cb hidl_cb) override;
- Return<void> getChangedCompositionTypes(Display display,
- getChangedCompositionTypes_cb hidl_cb) override;
- Return<Error> getClientTargetSupport(Display display,
- uint32_t width, uint32_t height,
- PixelFormat format, Dataspace dataspace) override;
- Return<void> getColorModes(Display display,
- getColorModes_cb hidl_cb) override;
- Return<void> getDisplayAttribute(Display display,
- Config config, Attribute attribute,
- getDisplayAttribute_cb hidl_cb) override;
- Return<void> getDisplayConfigs(Display display,
- getDisplayConfigs_cb hidl_cb) override;
- Return<void> getDisplayName(Display display,
- getDisplayName_cb hidl_cb) override;
- Return<void> getDisplayRequests(Display display,
- getDisplayRequests_cb hidl_cb) override;
- Return<void> getDisplayType(Display display,
- getDisplayType_cb hidl_cb) override;
- Return<void> getDozeSupport(Display display,
- getDozeSupport_cb hidl_cb) override;
- Return<void> getHdrCapabilities(Display display,
- getHdrCapabilities_cb hidl_cb) override;
- Return<void> getReleaseFences(Display display,
- getReleaseFences_cb hidl_cb) override;
- Return<void> presentDisplay(Display display,
- presentDisplay_cb hidl_cb) override;
- Return<Error> setActiveConfig(Display display, Config config) override;
- Return<Error> setClientTarget(Display display,
- const hidl_handle& target,
- const hidl_handle& acquireFence,
- Dataspace dataspace, const hidl_vec<Rect>& damage) override;
- Return<Error> setColorMode(Display display, ColorMode mode) override;
- Return<Error> setColorTransform(Display display,
- const hidl_vec<float>& matrix, ColorTransform hint) override;
- Return<Error> setOutputBuffer(Display display,
- const hidl_handle& buffer,
- const hidl_handle& releaseFence) override;
- Return<Error> setPowerMode(Display display, PowerMode mode) override;
- Return<Error> setVsyncEnabled(Display display, Vsync enabled) override;
- Return<void> validateDisplay(Display display,
- validateDisplay_cb hidl_cb) override;
- Return<Error> setCursorPosition(Display display,
- Layer layer, int32_t x, int32_t y) override;
- Return<Error> setLayerBuffer(Display display,
- Layer layer, const hidl_handle& buffer,
- const hidl_handle& acquireFence) override;
- Return<Error> setLayerSurfaceDamage(Display display,
- Layer layer, const hidl_vec<Rect>& damage) override;
- Return<Error> setLayerBlendMode(Display display,
- Layer layer, BlendMode mode) override;
- Return<Error> setLayerColor(Display display,
- Layer layer, const Color& color) override;
- Return<Error> setLayerCompositionType(Display display,
- Layer layer, Composition type) override;
- Return<Error> setLayerDataspace(Display display,
- Layer layer, Dataspace dataspace) override;
- Return<Error> setLayerDisplayFrame(Display display,
- Layer layer, const Rect& frame) override;
- Return<Error> setLayerPlaneAlpha(Display display,
- Layer layer, float alpha) override;
- Return<Error> setLayerSidebandStream(Display display,
- Layer layer, const hidl_handle& stream) override;
- Return<Error> setLayerSourceCrop(Display display,
- Layer layer, const FRect& crop) override;
- Return<Error> setLayerTransform(Display display,
- Layer layer, Transform transform) override;
- Return<Error> setLayerVisibleRegion(Display display,
- Layer layer, const hidl_vec<Rect>& visible) override;
- Return<Error> setLayerZOrder(Display display,
- Layer layer, uint32_t z) override;
-
-private:
- void initCapabilities();
-
- template<typename T>
- void initDispatch(T& func, hwc2_function_descriptor_t desc);
- void initDispatch();
-
- bool hasCapability(Capability capability) const;
-
- static void hotplugHook(hwc2_callback_data_t callbackData,
- hwc2_display_t display, int32_t connected);
- static void refreshHook(hwc2_callback_data_t callbackData,
- hwc2_display_t display);
- static void vsyncHook(hwc2_callback_data_t callbackData,
- hwc2_display_t display, int64_t timestamp);
-
- hwc2_device_t* mDevice;
-
- std::unordered_set<Capability> mCapabilities;
-
- struct {
- HWC2_PFN_ACCEPT_DISPLAY_CHANGES acceptDisplayChanges;
- HWC2_PFN_CREATE_LAYER createLayer;
- HWC2_PFN_CREATE_VIRTUAL_DISPLAY createVirtualDisplay;
- HWC2_PFN_DESTROY_LAYER destroyLayer;
- HWC2_PFN_DESTROY_VIRTUAL_DISPLAY destroyVirtualDisplay;
- HWC2_PFN_DUMP dump;
- HWC2_PFN_GET_ACTIVE_CONFIG getActiveConfig;
- HWC2_PFN_GET_CHANGED_COMPOSITION_TYPES getChangedCompositionTypes;
- HWC2_PFN_GET_CLIENT_TARGET_SUPPORT getClientTargetSupport;
- HWC2_PFN_GET_COLOR_MODES getColorModes;
- HWC2_PFN_GET_DISPLAY_ATTRIBUTE getDisplayAttribute;
- HWC2_PFN_GET_DISPLAY_CONFIGS getDisplayConfigs;
- HWC2_PFN_GET_DISPLAY_NAME getDisplayName;
- HWC2_PFN_GET_DISPLAY_REQUESTS getDisplayRequests;
- HWC2_PFN_GET_DISPLAY_TYPE getDisplayType;
- HWC2_PFN_GET_DOZE_SUPPORT getDozeSupport;
- HWC2_PFN_GET_HDR_CAPABILITIES getHdrCapabilities;
- HWC2_PFN_GET_MAX_VIRTUAL_DISPLAY_COUNT getMaxVirtualDisplayCount;
- HWC2_PFN_GET_RELEASE_FENCES getReleaseFences;
- HWC2_PFN_PRESENT_DISPLAY presentDisplay;
- HWC2_PFN_REGISTER_CALLBACK registerCallback;
- HWC2_PFN_SET_ACTIVE_CONFIG setActiveConfig;
- HWC2_PFN_SET_CLIENT_TARGET setClientTarget;
- HWC2_PFN_SET_COLOR_MODE setColorMode;
- HWC2_PFN_SET_COLOR_TRANSFORM setColorTransform;
- HWC2_PFN_SET_CURSOR_POSITION setCursorPosition;
- HWC2_PFN_SET_LAYER_BLEND_MODE setLayerBlendMode;
- HWC2_PFN_SET_LAYER_BUFFER setLayerBuffer;
- HWC2_PFN_SET_LAYER_COLOR setLayerColor;
- HWC2_PFN_SET_LAYER_COMPOSITION_TYPE setLayerCompositionType;
- HWC2_PFN_SET_LAYER_DATASPACE setLayerDataspace;
- HWC2_PFN_SET_LAYER_DISPLAY_FRAME setLayerDisplayFrame;
- HWC2_PFN_SET_LAYER_PLANE_ALPHA setLayerPlaneAlpha;
- HWC2_PFN_SET_LAYER_SIDEBAND_STREAM setLayerSidebandStream;
- HWC2_PFN_SET_LAYER_SOURCE_CROP setLayerSourceCrop;
- HWC2_PFN_SET_LAYER_SURFACE_DAMAGE setLayerSurfaceDamage;
- HWC2_PFN_SET_LAYER_TRANSFORM setLayerTransform;
- HWC2_PFN_SET_LAYER_VISIBLE_REGION setLayerVisibleRegion;
- HWC2_PFN_SET_LAYER_Z_ORDER setLayerZOrder;
- HWC2_PFN_SET_OUTPUT_BUFFER setOutputBuffer;
- HWC2_PFN_SET_POWER_MODE setPowerMode;
- HWC2_PFN_SET_VSYNC_ENABLED setVsyncEnabled;
- HWC2_PFN_VALIDATE_DISPLAY validateDisplay;
- } mDispatch;
-
- // cloned buffers for a display
- struct DisplayBuffers {
- BufferClone ClientTarget;
- BufferClone OutputBuffer;
-
- std::unordered_map<Layer, BufferClone> LayerBuffers;
- std::unordered_map<Layer, BufferClone> LayerSidebandStreams;
- };
-
- std::mutex mCallbackMutex;
- sp<IComposerCallback> mCallback;
-
- std::mutex mDisplayMutex;
- std::unordered_map<Display, DisplayBuffers> mDisplays;
-};
-
HwcHal::HwcHal(const hw_module_t* module)
: mDevice(nullptr), mDispatch()
{
- if (!sHandleImporter.initialize()) {
- LOG_ALWAYS_FATAL("failed to initialize handle importer");
- }
-
int status = hwc2_open(module, &mDevice);
if (status) {
LOG_ALWAYS_FATAL("failed to open hwcomposer2 device: %s",
@@ -463,8 +46,6 @@
HwcHal::~HwcHal()
{
hwc2_close(mDevice);
- mDisplays.clear();
- sHandleImporter.cleanup();
}
void HwcHal::initCapabilities()
@@ -481,88 +62,89 @@
}
template<typename T>
-void HwcHal::initDispatch(T& func, hwc2_function_descriptor_t desc)
+void HwcHal::initDispatch(hwc2_function_descriptor_t desc, T* outPfn)
{
auto pfn = mDevice->getFunction(mDevice, desc);
if (!pfn) {
LOG_ALWAYS_FATAL("failed to get hwcomposer2 function %d", desc);
}
- func = reinterpret_cast<T>(pfn);
+ *outPfn = reinterpret_cast<T>(pfn);
}
void HwcHal::initDispatch()
{
- initDispatch(mDispatch.acceptDisplayChanges,
- HWC2_FUNCTION_ACCEPT_DISPLAY_CHANGES);
- initDispatch(mDispatch.createLayer, HWC2_FUNCTION_CREATE_LAYER);
- initDispatch(mDispatch.createVirtualDisplay,
- HWC2_FUNCTION_CREATE_VIRTUAL_DISPLAY);
- initDispatch(mDispatch.destroyLayer, HWC2_FUNCTION_DESTROY_LAYER);
- initDispatch(mDispatch.destroyVirtualDisplay,
- HWC2_FUNCTION_DESTROY_VIRTUAL_DISPLAY);
- initDispatch(mDispatch.dump, HWC2_FUNCTION_DUMP);
- initDispatch(mDispatch.getActiveConfig, HWC2_FUNCTION_GET_ACTIVE_CONFIG);
- initDispatch(mDispatch.getChangedCompositionTypes,
- HWC2_FUNCTION_GET_CHANGED_COMPOSITION_TYPES);
- initDispatch(mDispatch.getClientTargetSupport,
- HWC2_FUNCTION_GET_CLIENT_TARGET_SUPPORT);
- initDispatch(mDispatch.getColorModes, HWC2_FUNCTION_GET_COLOR_MODES);
- initDispatch(mDispatch.getDisplayAttribute,
- HWC2_FUNCTION_GET_DISPLAY_ATTRIBUTE);
- initDispatch(mDispatch.getDisplayConfigs,
- HWC2_FUNCTION_GET_DISPLAY_CONFIGS);
- initDispatch(mDispatch.getDisplayName, HWC2_FUNCTION_GET_DISPLAY_NAME);
- initDispatch(mDispatch.getDisplayRequests,
- HWC2_FUNCTION_GET_DISPLAY_REQUESTS);
- initDispatch(mDispatch.getDisplayType, HWC2_FUNCTION_GET_DISPLAY_TYPE);
- initDispatch(mDispatch.getDozeSupport, HWC2_FUNCTION_GET_DOZE_SUPPORT);
- initDispatch(mDispatch.getHdrCapabilities,
- HWC2_FUNCTION_GET_HDR_CAPABILITIES);
- initDispatch(mDispatch.getMaxVirtualDisplayCount,
- HWC2_FUNCTION_GET_MAX_VIRTUAL_DISPLAY_COUNT);
- initDispatch(mDispatch.getReleaseFences,
- HWC2_FUNCTION_GET_RELEASE_FENCES);
- initDispatch(mDispatch.presentDisplay, HWC2_FUNCTION_PRESENT_DISPLAY);
- initDispatch(mDispatch.registerCallback, HWC2_FUNCTION_REGISTER_CALLBACK);
- initDispatch(mDispatch.setActiveConfig, HWC2_FUNCTION_SET_ACTIVE_CONFIG);
- initDispatch(mDispatch.setClientTarget, HWC2_FUNCTION_SET_CLIENT_TARGET);
- initDispatch(mDispatch.setColorMode, HWC2_FUNCTION_SET_COLOR_MODE);
- initDispatch(mDispatch.setColorTransform,
- HWC2_FUNCTION_SET_COLOR_TRANSFORM);
- initDispatch(mDispatch.setCursorPosition,
- HWC2_FUNCTION_SET_CURSOR_POSITION);
- initDispatch(mDispatch.setLayerBlendMode,
- HWC2_FUNCTION_SET_LAYER_BLEND_MODE);
- initDispatch(mDispatch.setLayerBuffer, HWC2_FUNCTION_SET_LAYER_BUFFER);
- initDispatch(mDispatch.setLayerColor, HWC2_FUNCTION_SET_LAYER_COLOR);
- initDispatch(mDispatch.setLayerCompositionType,
- HWC2_FUNCTION_SET_LAYER_COMPOSITION_TYPE);
- initDispatch(mDispatch.setLayerDataspace,
- HWC2_FUNCTION_SET_LAYER_DATASPACE);
- initDispatch(mDispatch.setLayerDisplayFrame,
- HWC2_FUNCTION_SET_LAYER_DISPLAY_FRAME);
- initDispatch(mDispatch.setLayerPlaneAlpha,
- HWC2_FUNCTION_SET_LAYER_PLANE_ALPHA);
+ initDispatch(HWC2_FUNCTION_ACCEPT_DISPLAY_CHANGES,
+ &mDispatch.acceptDisplayChanges);
+ initDispatch(HWC2_FUNCTION_CREATE_LAYER, &mDispatch.createLayer);
+ initDispatch(HWC2_FUNCTION_CREATE_VIRTUAL_DISPLAY,
+ &mDispatch.createVirtualDisplay);
+ initDispatch(HWC2_FUNCTION_DESTROY_LAYER, &mDispatch.destroyLayer);
+ initDispatch(HWC2_FUNCTION_DESTROY_VIRTUAL_DISPLAY,
+ &mDispatch.destroyVirtualDisplay);
+ initDispatch(HWC2_FUNCTION_DUMP, &mDispatch.dump);
+ initDispatch(HWC2_FUNCTION_GET_ACTIVE_CONFIG, &mDispatch.getActiveConfig);
+ initDispatch(HWC2_FUNCTION_GET_CHANGED_COMPOSITION_TYPES,
+ &mDispatch.getChangedCompositionTypes);
+ initDispatch(HWC2_FUNCTION_GET_CLIENT_TARGET_SUPPORT,
+ &mDispatch.getClientTargetSupport);
+ initDispatch(HWC2_FUNCTION_GET_COLOR_MODES, &mDispatch.getColorModes);
+ initDispatch(HWC2_FUNCTION_GET_DISPLAY_ATTRIBUTE,
+ &mDispatch.getDisplayAttribute);
+ initDispatch(HWC2_FUNCTION_GET_DISPLAY_CONFIGS,
+ &mDispatch.getDisplayConfigs);
+ initDispatch(HWC2_FUNCTION_GET_DISPLAY_NAME, &mDispatch.getDisplayName);
+ initDispatch(HWC2_FUNCTION_GET_DISPLAY_REQUESTS,
+ &mDispatch.getDisplayRequests);
+ initDispatch(HWC2_FUNCTION_GET_DISPLAY_TYPE, &mDispatch.getDisplayType);
+ initDispatch(HWC2_FUNCTION_GET_DOZE_SUPPORT, &mDispatch.getDozeSupport);
+ initDispatch(HWC2_FUNCTION_GET_HDR_CAPABILITIES,
+ &mDispatch.getHdrCapabilities);
+ initDispatch(HWC2_FUNCTION_GET_MAX_VIRTUAL_DISPLAY_COUNT,
+ &mDispatch.getMaxVirtualDisplayCount);
+ initDispatch(HWC2_FUNCTION_GET_RELEASE_FENCES,
+ &mDispatch.getReleaseFences);
+ initDispatch(HWC2_FUNCTION_PRESENT_DISPLAY, &mDispatch.presentDisplay);
+ initDispatch(HWC2_FUNCTION_REGISTER_CALLBACK,
+ &mDispatch.registerCallback);
+ initDispatch(HWC2_FUNCTION_SET_ACTIVE_CONFIG, &mDispatch.setActiveConfig);
+ initDispatch(HWC2_FUNCTION_SET_CLIENT_TARGET, &mDispatch.setClientTarget);
+ initDispatch(HWC2_FUNCTION_SET_COLOR_MODE, &mDispatch.setColorMode);
+ initDispatch(HWC2_FUNCTION_SET_COLOR_TRANSFORM,
+ &mDispatch.setColorTransform);
+ initDispatch(HWC2_FUNCTION_SET_CURSOR_POSITION,
+ &mDispatch.setCursorPosition);
+ initDispatch(HWC2_FUNCTION_SET_LAYER_BLEND_MODE,
+ &mDispatch.setLayerBlendMode);
+ initDispatch(HWC2_FUNCTION_SET_LAYER_BUFFER, &mDispatch.setLayerBuffer);
+ initDispatch(HWC2_FUNCTION_SET_LAYER_COLOR, &mDispatch.setLayerColor);
+ initDispatch(HWC2_FUNCTION_SET_LAYER_COMPOSITION_TYPE,
+ &mDispatch.setLayerCompositionType);
+ initDispatch(HWC2_FUNCTION_SET_LAYER_DATASPACE,
+ &mDispatch.setLayerDataspace);
+ initDispatch(HWC2_FUNCTION_SET_LAYER_DISPLAY_FRAME,
+ &mDispatch.setLayerDisplayFrame);
+ initDispatch(HWC2_FUNCTION_SET_LAYER_PLANE_ALPHA,
+ &mDispatch.setLayerPlaneAlpha);
if (hasCapability(Capability::SIDEBAND_STREAM)) {
- initDispatch(mDispatch.setLayerSidebandStream,
- HWC2_FUNCTION_SET_LAYER_SIDEBAND_STREAM);
+ initDispatch(HWC2_FUNCTION_SET_LAYER_SIDEBAND_STREAM,
+ &mDispatch.setLayerSidebandStream);
}
- initDispatch(mDispatch.setLayerSourceCrop,
- HWC2_FUNCTION_SET_LAYER_SOURCE_CROP);
- initDispatch(mDispatch.setLayerSurfaceDamage,
- HWC2_FUNCTION_SET_LAYER_SURFACE_DAMAGE);
- initDispatch(mDispatch.setLayerTransform,
- HWC2_FUNCTION_SET_LAYER_TRANSFORM);
- initDispatch(mDispatch.setLayerVisibleRegion,
- HWC2_FUNCTION_SET_LAYER_VISIBLE_REGION);
- initDispatch(mDispatch.setLayerZOrder, HWC2_FUNCTION_SET_LAYER_Z_ORDER);
- initDispatch(mDispatch.setOutputBuffer, HWC2_FUNCTION_SET_OUTPUT_BUFFER);
- initDispatch(mDispatch.setPowerMode, HWC2_FUNCTION_SET_POWER_MODE);
- initDispatch(mDispatch.setVsyncEnabled, HWC2_FUNCTION_SET_VSYNC_ENABLED);
- initDispatch(mDispatch.validateDisplay, HWC2_FUNCTION_VALIDATE_DISPLAY);
+ initDispatch(HWC2_FUNCTION_SET_LAYER_SOURCE_CROP,
+ &mDispatch.setLayerSourceCrop);
+ initDispatch(HWC2_FUNCTION_SET_LAYER_SURFACE_DAMAGE,
+ &mDispatch.setLayerSurfaceDamage);
+ initDispatch(HWC2_FUNCTION_SET_LAYER_TRANSFORM,
+ &mDispatch.setLayerTransform);
+ initDispatch(HWC2_FUNCTION_SET_LAYER_VISIBLE_REGION,
+ &mDispatch.setLayerVisibleRegion);
+ initDispatch(HWC2_FUNCTION_SET_LAYER_Z_ORDER, &mDispatch.setLayerZOrder);
+ initDispatch(HWC2_FUNCTION_SET_OUTPUT_BUFFER, &mDispatch.setOutputBuffer);
+ initDispatch(HWC2_FUNCTION_SET_POWER_MODE, &mDispatch.setPowerMode);
+ initDispatch(HWC2_FUNCTION_SET_VSYNC_ENABLED, &mDispatch.setVsyncEnabled);
+ initDispatch(HWC2_FUNCTION_VALIDATE_DISPLAY, &mDispatch.validateDisplay);
}
bool HwcHal::hasCapability(Capability capability) const
@@ -584,7 +166,7 @@
Return<void> HwcHal::dumpDebugInfo(dumpDebugInfo_cb hidl_cb)
{
- uint32_t len;
+ uint32_t len = 0;
mDispatch.dump(mDevice, &len, nullptr);
std::vector<char> buf(len + 1);
@@ -599,699 +181,519 @@
return Void();
}
+Return<void> HwcHal::createClient(createClient_cb hidl_cb)
+{
+ Error err = Error::NONE;
+ sp<HwcClient> client;
+
+ {
+ std::lock_guard<std::mutex> lock(mClientMutex);
+
+ // only one client is allowed
+ if (mClient == nullptr) {
+ client = new HwcClient(*this);
+ mClient = client;
+ } else {
+ err = Error::NO_RESOURCES;
+ }
+ }
+
+ hidl_cb(err, client);
+
+ return Void();
+}
+
+sp<HwcClient> HwcHal::getClient()
+{
+ std::lock_guard<std::mutex> lock(mClientMutex);
+ return (mClient != nullptr) ? mClient.promote() : nullptr;
+}
+
+void HwcHal::removeClient()
+{
+ std::lock_guard<std::mutex> lock(mClientMutex);
+ mClient = nullptr;
+}
+
void HwcHal::hotplugHook(hwc2_callback_data_t callbackData,
hwc2_display_t display, int32_t connected)
{
auto hal = reinterpret_cast<HwcHal*>(callbackData);
-
- {
- std::lock_guard<std::mutex> lock(hal->mDisplayMutex);
-
- if (connected == HWC2_CONNECTION_CONNECTED) {
- hal->mDisplays.emplace(display, DisplayBuffers());
- } else if (connected == HWC2_CONNECTION_DISCONNECTED) {
- hal->mDisplays.erase(display);
- }
+ auto client = hal->getClient();
+ if (client != nullptr) {
+ client->onHotplug(display,
+ static_cast<IComposerCallback::Connection>(connected));
}
-
- hal->mCallback->onHotplug(display,
- static_cast<IComposerCallback::Connection>(connected));
}
void HwcHal::refreshHook(hwc2_callback_data_t callbackData,
hwc2_display_t display)
{
auto hal = reinterpret_cast<HwcHal*>(callbackData);
- hal->mCallback->onRefresh(display);
+ auto client = hal->getClient();
+ if (client != nullptr) {
+ client->onRefresh(display);
+ }
}
void HwcHal::vsyncHook(hwc2_callback_data_t callbackData,
hwc2_display_t display, int64_t timestamp)
{
auto hal = reinterpret_cast<HwcHal*>(callbackData);
- hal->mCallback->onVsync(display, timestamp);
+ auto client = hal->getClient();
+ if (client != nullptr) {
+ client->onVsync(display, timestamp);
+ }
}
-Return<void> HwcHal::registerCallback(const sp<IComposerCallback>& callback)
+void HwcHal::enableCallback(bool enable)
{
- std::lock_guard<std::mutex> lock(mCallbackMutex);
-
- mCallback = callback;
-
- mDispatch.registerCallback(mDevice, HWC2_CALLBACK_HOTPLUG, this,
- reinterpret_cast<hwc2_function_pointer_t>(hotplugHook));
- mDispatch.registerCallback(mDevice, HWC2_CALLBACK_REFRESH, this,
- reinterpret_cast<hwc2_function_pointer_t>(refreshHook));
- mDispatch.registerCallback(mDevice, HWC2_CALLBACK_VSYNC, this,
- reinterpret_cast<hwc2_function_pointer_t>(vsyncHook));
-
- return Void();
+ if (enable) {
+ mDispatch.registerCallback(mDevice, HWC2_CALLBACK_HOTPLUG, this,
+ reinterpret_cast<hwc2_function_pointer_t>(hotplugHook));
+ mDispatch.registerCallback(mDevice, HWC2_CALLBACK_REFRESH, this,
+ reinterpret_cast<hwc2_function_pointer_t>(refreshHook));
+ mDispatch.registerCallback(mDevice, HWC2_CALLBACK_VSYNC, this,
+ reinterpret_cast<hwc2_function_pointer_t>(vsyncHook));
+ } else {
+ mDispatch.registerCallback(mDevice, HWC2_CALLBACK_HOTPLUG, this,
+ nullptr);
+ mDispatch.registerCallback(mDevice, HWC2_CALLBACK_REFRESH, this,
+ nullptr);
+ mDispatch.registerCallback(mDevice, HWC2_CALLBACK_VSYNC, this,
+ nullptr);
+ }
}
-Return<uint32_t> HwcHal::getMaxVirtualDisplayCount()
+uint32_t HwcHal::getMaxVirtualDisplayCount()
{
return mDispatch.getMaxVirtualDisplayCount(mDevice);
}
-Return<void> HwcHal::createVirtualDisplay(uint32_t width, uint32_t height,
- PixelFormat formatHint, createVirtualDisplay_cb hidl_cb)
+Error HwcHal::createVirtualDisplay(uint32_t width, uint32_t height,
+ PixelFormat* format, Display* outDisplay)
{
- int32_t format = static_cast<int32_t>(formatHint);
- hwc2_display_t display;
- auto error = mDispatch.createVirtualDisplay(mDevice, width, height,
- &format, &display);
- if (error == HWC2_ERROR_NONE) {
- std::lock_guard<std::mutex> lock(mDisplayMutex);
+ int32_t hwc_format = static_cast<int32_t>(*format);
+ int32_t err = mDispatch.createVirtualDisplay(mDevice, width, height,
+ &hwc_format, outDisplay);
+ *format = static_cast<PixelFormat>(hwc_format);
- mDisplays.emplace(display, DisplayBuffers());
- }
-
- hidl_cb(static_cast<Error>(error), display,
- static_cast<PixelFormat>(format));
-
- return Void();
+ return static_cast<Error>(err);
}
-Return<Error> HwcHal::destroyVirtualDisplay(Display display)
+Error HwcHal::destroyVirtualDisplay(Display display)
{
- auto error = mDispatch.destroyVirtualDisplay(mDevice, display);
- if (error == HWC2_ERROR_NONE) {
- std::lock_guard<std::mutex> lock(mDisplayMutex);
-
- mDisplays.erase(display);
- }
-
- return static_cast<Error>(error);
+ int32_t err = mDispatch.destroyVirtualDisplay(mDevice, display);
+ return static_cast<Error>(err);
}
-Return<Error> HwcHal::acceptDisplayChanges(Display display)
+Error HwcHal::createLayer(Display display, Layer* outLayer)
{
- auto error = mDispatch.acceptDisplayChanges(mDevice, display);
- return static_cast<Error>(error);
+ int32_t err = mDispatch.createLayer(mDevice, display, outLayer);
+ return static_cast<Error>(err);
}
-Return<void> HwcHal::createLayer(Display display, createLayer_cb hidl_cb)
+Error HwcHal::destroyLayer(Display display, Layer layer)
{
- hwc2_layer_t layer;
- auto error = mDispatch.createLayer(mDevice, display, &layer);
-
- hidl_cb(static_cast<Error>(error), layer);
-
- return Void();
+ int32_t err = mDispatch.destroyLayer(mDevice, display, layer);
+ return static_cast<Error>(err);
}
-Return<Error> HwcHal::destroyLayer(Display display, Layer layer)
+Error HwcHal::getActiveConfig(Display display, Config* outConfig)
{
- auto error = mDispatch.destroyLayer(mDevice, display, layer);
- if (error == HWC2_ERROR_NONE) {
- std::lock_guard<std::mutex> lock(mDisplayMutex);
-
- auto dpy = mDisplays.find(display);
- dpy->second.LayerBuffers.erase(layer);
- dpy->second.LayerSidebandStreams.erase(layer);
- }
-
- return static_cast<Error>(error);
+ int32_t err = mDispatch.getActiveConfig(mDevice, display, outConfig);
+ return static_cast<Error>(err);
}
-Return<void> HwcHal::getActiveConfig(Display display,
- getActiveConfig_cb hidl_cb)
-{
- hwc2_config_t config;
- auto error = mDispatch.getActiveConfig(mDevice, display, &config);
-
- hidl_cb(static_cast<Error>(error), config);
-
- return Void();
-}
-
-Return<void> HwcHal::getChangedCompositionTypes(Display display,
- getChangedCompositionTypes_cb hidl_cb)
-{
- uint32_t count = 0;
- auto error = mDispatch.getChangedCompositionTypes(mDevice, display,
- &count, nullptr, nullptr);
- if (error != HWC2_ERROR_NONE) {
- count = 0;
- }
-
- std::vector<hwc2_layer_t> layers(count);
- std::vector<Composition> types(count);
- error = mDispatch.getChangedCompositionTypes(mDevice, display,
- &count, layers.data(),
- reinterpret_cast<std::underlying_type<Composition>::type*>(
- types.data()));
- if (error != HWC2_ERROR_NONE) {
- count = 0;
- }
- layers.resize(count);
- types.resize(count);
-
- hidl_vec<Layer> layers_reply;
- layers_reply.setToExternal(layers.data(), layers.size());
-
- hidl_vec<Composition> types_reply;
- types_reply.setToExternal(types.data(), types.size());
-
- hidl_cb(static_cast<Error>(error), layers_reply, types_reply);
-
- return Void();
-}
-
-Return<Error> HwcHal::getClientTargetSupport(Display display,
+Error HwcHal::getClientTargetSupport(Display display,
uint32_t width, uint32_t height,
PixelFormat format, Dataspace dataspace)
{
- auto error = mDispatch.getClientTargetSupport(mDevice, display,
+ int32_t err = mDispatch.getClientTargetSupport(mDevice, display,
width, height, static_cast<int32_t>(format),
static_cast<int32_t>(dataspace));
- return static_cast<Error>(error);
+ return static_cast<Error>(err);
}
-Return<void> HwcHal::getColorModes(Display display, getColorModes_cb hidl_cb)
+Error HwcHal::getColorModes(Display display, hidl_vec<ColorMode>* outModes)
{
uint32_t count = 0;
- auto error = mDispatch.getColorModes(mDevice, display, &count, nullptr);
- if (error != HWC2_ERROR_NONE) {
- count = 0;
+ int32_t err = mDispatch.getColorModes(mDevice, display, &count, nullptr);
+ if (err != HWC2_ERROR_NONE) {
+ return static_cast<Error>(err);
}
- std::vector<ColorMode> modes(count);
- error = mDispatch.getColorModes(mDevice, display, &count,
+ outModes->resize(count);
+ err = mDispatch.getColorModes(mDevice, display, &count,
reinterpret_cast<std::underlying_type<ColorMode>::type*>(
- modes.data()));
- if (error != HWC2_ERROR_NONE) {
- count = 0;
+ outModes->data()));
+ if (err != HWC2_ERROR_NONE) {
+ *outModes = hidl_vec<ColorMode>();
+ return static_cast<Error>(err);
}
- modes.resize(count);
- hidl_vec<ColorMode> modes_reply;
- modes_reply.setToExternal(modes.data(), modes.size());
- hidl_cb(static_cast<Error>(error), modes_reply);
-
- return Void();
+ return Error::NONE;
}
-Return<void> HwcHal::getDisplayAttribute(Display display,
- Config config, Attribute attribute,
- getDisplayAttribute_cb hidl_cb)
+Error HwcHal::getDisplayAttribute(Display display, Config config,
+ IComposerClient::Attribute attribute, int32_t* outValue)
{
- int32_t value;
- auto error = mDispatch.getDisplayAttribute(mDevice, display, config,
- static_cast<int32_t>(attribute), &value);
-
- hidl_cb(static_cast<Error>(error), value);
-
- return Void();
+ int32_t err = mDispatch.getDisplayAttribute(mDevice, display, config,
+ static_cast<int32_t>(attribute), outValue);
+ return static_cast<Error>(err);
}
-Return<void> HwcHal::getDisplayConfigs(Display display,
- getDisplayConfigs_cb hidl_cb)
+Error HwcHal::getDisplayConfigs(Display display, hidl_vec<Config>* outConfigs)
{
uint32_t count = 0;
- auto error = mDispatch.getDisplayConfigs(mDevice, display,
+ int32_t err = mDispatch.getDisplayConfigs(mDevice, display,
&count, nullptr);
- if (error != HWC2_ERROR_NONE) {
- count = 0;
+ if (err != HWC2_ERROR_NONE) {
+ return static_cast<Error>(err);
}
- std::vector<hwc2_config_t> configs(count);
- error = mDispatch.getDisplayConfigs(mDevice, display,
- &count, configs.data());
- if (error != HWC2_ERROR_NONE) {
- count = 0;
+ outConfigs->resize(count);
+ err = mDispatch.getDisplayConfigs(mDevice, display,
+ &count, outConfigs->data());
+ if (err != HWC2_ERROR_NONE) {
+ *outConfigs = hidl_vec<Config>();
+ return static_cast<Error>(err);
}
- configs.resize(count);
- hidl_vec<Config> configs_reply;
- configs_reply.setToExternal(configs.data(), configs.size());
- hidl_cb(static_cast<Error>(error), configs_reply);
-
- return Void();
+ return Error::NONE;
}
-Return<void> HwcHal::getDisplayName(Display display,
- getDisplayName_cb hidl_cb)
+Error HwcHal::getDisplayName(Display display, hidl_string* outName)
{
uint32_t count = 0;
- auto error = mDispatch.getDisplayName(mDevice, display, &count, nullptr);
- if (error != HWC2_ERROR_NONE) {
- count = 0;
+ int32_t err = mDispatch.getDisplayName(mDevice, display, &count, nullptr);
+ if (err != HWC2_ERROR_NONE) {
+ return static_cast<Error>(err);
}
- std::vector<char> name(count + 1);
- error = mDispatch.getDisplayName(mDevice, display, &count, name.data());
- if (error != HWC2_ERROR_NONE) {
- count = 0;
+ std::vector<char> buf(count + 1);
+ err = mDispatch.getDisplayName(mDevice, display, &count, buf.data());
+ if (err != HWC2_ERROR_NONE) {
+ return static_cast<Error>(err);
}
- name.resize(count + 1);
- name[count] = '\0';
+ buf.resize(count + 1);
+ buf[count] = '\0';
- hidl_string name_reply;
- name_reply.setToExternal(name.data(), count);
- hidl_cb(static_cast<Error>(error), name_reply);
+ *outName = buf.data();
- return Void();
+ return Error::NONE;
}
-Return<void> HwcHal::getDisplayRequests(Display display,
- getDisplayRequests_cb hidl_cb)
+Error HwcHal::getDisplayType(Display display,
+ IComposerClient::DisplayType* outType)
{
- int32_t display_reqs;
- uint32_t count = 0;
- auto error = mDispatch.getDisplayRequests(mDevice, display,
- &display_reqs, &count, nullptr, nullptr);
- if (error != HWC2_ERROR_NONE) {
- count = 0;
- }
+ int32_t hwc_type = HWC2_DISPLAY_TYPE_INVALID;
+ int32_t err = mDispatch.getDisplayType(mDevice, display, &hwc_type);
+ *outType = static_cast<IComposerClient::DisplayType>(hwc_type);
- std::vector<hwc2_layer_t> layers(count);
- std::vector<int32_t> layer_reqs(count);
- error = mDispatch.getDisplayRequests(mDevice, display,
- &display_reqs, &count, layers.data(), layer_reqs.data());
- if (error != HWC2_ERROR_NONE) {
- count = 0;
- }
- layers.resize(count);
- layer_reqs.resize(count);
-
- hidl_vec<Layer> layers_reply;
- layers_reply.setToExternal(layers.data(), layers.size());
-
- hidl_vec<uint32_t> layer_reqs_reply;
- layer_reqs_reply.setToExternal(
- reinterpret_cast<uint32_t*>(layer_reqs.data()),
- layer_reqs.size());
-
- hidl_cb(static_cast<Error>(error), display_reqs,
- layers_reply, layer_reqs_reply);
-
- return Void();
+ return static_cast<Error>(err);
}
-Return<void> HwcHal::getDisplayType(Display display,
- getDisplayType_cb hidl_cb)
+Error HwcHal::getDozeSupport(Display display, bool* outSupport)
{
- int32_t type;
- auto error = mDispatch.getDisplayType(mDevice, display, &type);
+ int32_t hwc_support = 0;
+ int32_t err = mDispatch.getDozeSupport(mDevice, display, &hwc_support);
+ *outSupport = hwc_support;
- hidl_cb(static_cast<Error>(error), static_cast<DisplayType>(type));
-
- return Void();
+ return static_cast<Error>(err);
}
-Return<void> HwcHal::getDozeSupport(Display display,
- getDozeSupport_cb hidl_cb)
-{
- int32_t support;
- auto error = mDispatch.getDozeSupport(mDevice, display, &support);
-
- hidl_cb(static_cast<Error>(error), support);
-
- return Void();
-}
-
-Return<void> HwcHal::getHdrCapabilities(Display display,
- getHdrCapabilities_cb hidl_cb)
-{
- float max_lumi, max_avg_lumi, min_lumi;
- uint32_t count = 0;
- auto error = mDispatch.getHdrCapabilities(mDevice, display,
- &count, nullptr, &max_lumi, &max_avg_lumi, &min_lumi);
- if (error != HWC2_ERROR_NONE) {
- count = 0;
- }
-
- std::vector<Hdr> types(count);
- error = mDispatch.getHdrCapabilities(mDevice, display, &count,
- reinterpret_cast<std::underlying_type<Hdr>::type*>(types.data()),
- &max_lumi, &max_avg_lumi, &min_lumi);
- if (error != HWC2_ERROR_NONE) {
- count = 0;
- }
- types.resize(count);
-
- hidl_vec<Hdr> types_reply;
- types_reply.setToExternal(types.data(), types.size());
- hidl_cb(static_cast<Error>(error), types_reply,
- max_lumi, max_avg_lumi, min_lumi);
-
- return Void();
-}
-
-Return<void> HwcHal::getReleaseFences(Display display,
- getReleaseFences_cb hidl_cb)
+Error HwcHal::getHdrCapabilities(Display display, hidl_vec<Hdr>* outTypes,
+ float* outMaxLuminance, float* outMaxAverageLuminance,
+ float* outMinLuminance)
{
uint32_t count = 0;
- auto error = mDispatch.getReleaseFences(mDevice, display,
- &count, nullptr, nullptr);
- if (error != HWC2_ERROR_NONE) {
- count = 0;
+ int32_t err = mDispatch.getHdrCapabilities(mDevice, display, &count,
+ nullptr, outMaxLuminance, outMaxAverageLuminance,
+ outMinLuminance);
+ if (err != HWC2_ERROR_NONE) {
+ return static_cast<Error>(err);
}
- std::vector<hwc2_layer_t> layers(count);
- std::vector<int32_t> fences(count);
- error = mDispatch.getReleaseFences(mDevice, display,
- &count, layers.data(), fences.data());
- if (error != HWC2_ERROR_NONE) {
- count = 0;
- }
- layers.resize(count);
- fences.resize(count);
-
- // filter out layers with release fence -1
- std::vector<hwc2_layer_t> filtered_layers;
- std::vector<int> filtered_fences;
- for (size_t i = 0; i < layers.size(); i++) {
- if (fences[i] >= 0) {
- filtered_layers.push_back(layers[i]);
- filtered_fences.push_back(fences[i]);
- }
+ outTypes->resize(count);
+ err = mDispatch.getHdrCapabilities(mDevice, display, &count,
+ reinterpret_cast<std::underlying_type<Hdr>::type*>(
+ outTypes->data()), outMaxLuminance,
+ outMaxAverageLuminance, outMinLuminance);
+ if (err != HWC2_ERROR_NONE) {
+ *outTypes = hidl_vec<Hdr>();
+ return static_cast<Error>(err);
}
- hidl_vec<Layer> layers_reply;
- native_handle_t* fences_reply =
- native_handle_create(filtered_fences.size(), 0);
- if (fences_reply) {
- layers_reply.setToExternal(filtered_layers.data(),
- filtered_layers.size());
- memcpy(fences_reply->data, filtered_fences.data(),
- sizeof(int) * filtered_fences.size());
-
- hidl_cb(static_cast<Error>(error), layers_reply, fences_reply);
-
- native_handle_close(fences_reply);
- native_handle_delete(fences_reply);
- } else {
- NATIVE_HANDLE_DECLARE_STORAGE(fences_storage, 0, 0);
- fences_reply = native_handle_init(fences_storage, 0, 0);
-
- hidl_cb(Error::NO_RESOURCES, layers_reply, fences_reply);
-
- for (auto fence : filtered_fences) {
- close(fence);
- }
- }
-
- return Void();
+ return Error::NONE;
}
-Return<void> HwcHal::presentDisplay(Display display,
- presentDisplay_cb hidl_cb)
+Error HwcHal::setActiveConfig(Display display, Config config)
{
- int32_t fence = -1;
- auto error = mDispatch.presentDisplay(mDevice, display, &fence);
-
- NATIVE_HANDLE_DECLARE_STORAGE(fence_storage, 1, 0);
- native_handle_t* fence_reply;
- if (fence >= 0) {
- fence_reply = native_handle_init(fence_storage, 1, 0);
- fence_reply->data[0] = fence;
- } else {
- fence_reply = native_handle_init(fence_storage, 0, 0);
- }
-
- hidl_cb(static_cast<Error>(error), fence_reply);
-
- if (fence >= 0) {
- close(fence);
- }
-
- return Void();
+ int32_t err = mDispatch.setActiveConfig(mDevice, display, config);
+ return static_cast<Error>(err);
}
-Return<Error> HwcHal::setActiveConfig(Display display, Config config)
+Error HwcHal::setColorMode(Display display, ColorMode mode)
{
- auto error = mDispatch.setActiveConfig(mDevice, display, config);
- return static_cast<Error>(error);
-}
-
-Return<Error> HwcHal::setClientTarget(Display display,
- const hidl_handle& target,
- const hidl_handle& acquireFence,
- Dataspace dataspace, const hidl_vec<Rect>& damage)
-{
- const native_handle_t* targetHandle = target.getNativeHandle();
- if (!sHandleImporter.importBuffer(targetHandle)) {
- return Error::NO_RESOURCES;
- }
-
- int32_t fence;
- if (!sHandleImporter.importFence(acquireFence, fence)) {
- sHandleImporter.freeBuffer(targetHandle);
- return Error::NO_RESOURCES;
- }
-
- hwc_region_t damage_region = { damage.size(),
- reinterpret_cast<const hwc_rect_t*>(&damage[0]) };
-
- int32_t error = mDispatch.setClientTarget(mDevice, display,
- targetHandle, fence, static_cast<int32_t>(dataspace),
- damage_region);
- if (error == HWC2_ERROR_NONE) {
- std::lock_guard<std::mutex> lock(mDisplayMutex);
-
- auto dpy = mDisplays.find(display);
- dpy->second.ClientTarget = targetHandle;
- } else {
- sHandleImporter.freeBuffer(target);
- sHandleImporter.closeFence(fence);
- }
-
- return static_cast<Error>(error);
-}
-
-Return<Error> HwcHal::setColorMode(Display display, ColorMode mode)
-{
- auto error = mDispatch.setColorMode(mDevice, display,
+ int32_t err = mDispatch.setColorMode(mDevice, display,
static_cast<int32_t>(mode));
- return static_cast<Error>(error);
+ return static_cast<Error>(err);
}
-Return<Error> HwcHal::setColorTransform(Display display,
- const hidl_vec<float>& matrix, ColorTransform hint)
+Error HwcHal::setPowerMode(Display display, IComposerClient::PowerMode mode)
{
- auto error = mDispatch.setColorTransform(mDevice, display,
- &matrix[0], static_cast<int32_t>(hint));
- return static_cast<Error>(error);
-}
-
-Return<Error> HwcHal::setOutputBuffer(Display display,
- const hidl_handle& buffer,
- const hidl_handle& releaseFence)
-{
- const native_handle_t* bufferHandle = buffer.getNativeHandle();
- if (!sHandleImporter.importBuffer(bufferHandle)) {
- return Error::NO_RESOURCES;
- }
-
- int32_t fence;
- if (!sHandleImporter.importFence(releaseFence, fence)) {
- sHandleImporter.freeBuffer(bufferHandle);
- return Error::NO_RESOURCES;
- }
-
- int32_t error = mDispatch.setOutputBuffer(mDevice,
- display, bufferHandle, fence);
- if (error == HWC2_ERROR_NONE) {
- std::lock_guard<std::mutex> lock(mDisplayMutex);
-
- auto dpy = mDisplays.find(display);
- dpy->second.OutputBuffer = bufferHandle;
- } else {
- sHandleImporter.freeBuffer(bufferHandle);
- }
-
- // unlike in setClientTarget, fence is owned by us and is always closed
- sHandleImporter.closeFence(fence);
-
- return static_cast<Error>(error);
-}
-
-Return<Error> HwcHal::setPowerMode(Display display, PowerMode mode)
-{
- auto error = mDispatch.setPowerMode(mDevice, display,
+ int32_t err = mDispatch.setPowerMode(mDevice, display,
static_cast<int32_t>(mode));
- return static_cast<Error>(error);
+ return static_cast<Error>(err);
}
-Return<Error> HwcHal::setVsyncEnabled(Display display,
- Vsync enabled)
+Error HwcHal::setVsyncEnabled(Display display, IComposerClient::Vsync enabled)
{
- auto error = mDispatch.setVsyncEnabled(mDevice, display,
+ int32_t err = mDispatch.setVsyncEnabled(mDevice, display,
static_cast<int32_t>(enabled));
- return static_cast<Error>(error);
+ return static_cast<Error>(err);
}
-Return<void> HwcHal::validateDisplay(Display display,
- validateDisplay_cb hidl_cb)
+Error HwcHal::setColorTransform(Display display, const float* matrix,
+ int32_t hint)
+{
+ int32_t err = mDispatch.setColorTransform(mDevice, display, matrix, hint);
+ return static_cast<Error>(err);
+}
+
+Error HwcHal::setClientTarget(Display display, buffer_handle_t target,
+ int32_t acquireFence, int32_t dataspace,
+ const std::vector<hwc_rect_t>& damage)
+{
+ hwc_region region = { damage.size(), damage.data() };
+ int32_t err = mDispatch.setClientTarget(mDevice, display, target,
+ acquireFence, dataspace, region);
+ return static_cast<Error>(err);
+}
+
+Error HwcHal::setOutputBuffer(Display display, buffer_handle_t buffer,
+ int32_t releaseFence)
+{
+ int32_t err = mDispatch.setOutputBuffer(mDevice, display, buffer,
+ releaseFence);
+ // unlike in setClientTarget, releaseFence is owned by us
+ if (err == HWC2_ERROR_NONE && releaseFence >= 0) {
+ close(releaseFence);
+ }
+
+ return static_cast<Error>(err);
+}
+
+Error HwcHal::validateDisplay(Display display,
+ std::vector<Layer>* outChangedLayers,
+ std::vector<IComposerClient::Composition>* outCompositionTypes,
+ uint32_t* outDisplayRequestMask,
+ std::vector<Layer>* outRequestedLayers,
+ std::vector<uint32_t>* outRequestMasks)
{
uint32_t types_count = 0;
uint32_t reqs_count = 0;
- auto error = mDispatch.validateDisplay(mDevice, display,
+ int32_t err = mDispatch.validateDisplay(mDevice, display,
&types_count, &reqs_count);
-
- hidl_cb(static_cast<Error>(error), types_count, reqs_count);
-
- return Void();
-}
-
-Return<Error> HwcHal::setCursorPosition(Display display,
- Layer layer, int32_t x, int32_t y)
-{
- auto error = mDispatch.setCursorPosition(mDevice, display, layer, x, y);
- return static_cast<Error>(error);
-}
-
-Return<Error> HwcHal::setLayerBuffer(Display display,
- Layer layer, const hidl_handle& buffer,
- const hidl_handle& acquireFence)
-{
- const native_handle_t* bufferHandle = buffer.getNativeHandle();
- if (!sHandleImporter.importBuffer(bufferHandle)) {
- return Error::NO_RESOURCES;
+ if (err != HWC2_ERROR_NONE && err != HWC2_ERROR_HAS_CHANGES) {
+ return static_cast<Error>(err);
}
- int32_t fence;
- if (!sHandleImporter.importFence(acquireFence, fence)) {
- sHandleImporter.freeBuffer(bufferHandle);
- return Error::NO_RESOURCES;
+ err = mDispatch.getChangedCompositionTypes(mDevice, display,
+ &types_count, nullptr, nullptr);
+ if (err != HWC2_ERROR_NONE) {
+ return static_cast<Error>(err);
}
- int32_t error = mDispatch.setLayerBuffer(mDevice,
- display, layer, bufferHandle, fence);
- if (error == HWC2_ERROR_NONE) {
- std::lock_guard<std::mutex> lock(mDisplayMutex);
-
- auto dpy = mDisplays.find(display);
- dpy->second.LayerBuffers[layer] = bufferHandle;
- } else {
- sHandleImporter.freeBuffer(bufferHandle);
- sHandleImporter.closeFence(fence);
+ outChangedLayers->resize(types_count);
+ outCompositionTypes->resize(types_count);
+ err = mDispatch.getChangedCompositionTypes(mDevice, display,
+ &types_count, outChangedLayers->data(),
+ reinterpret_cast<
+ std::underlying_type<IComposerClient::Composition>::type*>(
+ outCompositionTypes->data()));
+ if (err != HWC2_ERROR_NONE) {
+ outChangedLayers->clear();
+ outCompositionTypes->clear();
+ return static_cast<Error>(err);
}
- return static_cast<Error>(error);
+ int32_t display_reqs = 0;
+ err = mDispatch.getDisplayRequests(mDevice, display, &display_reqs,
+ &reqs_count, nullptr, nullptr);
+ if (err != HWC2_ERROR_NONE) {
+ outChangedLayers->clear();
+ outCompositionTypes->clear();
+ return static_cast<Error>(err);
+ }
+
+ outRequestedLayers->resize(reqs_count);
+ outRequestMasks->resize(reqs_count);
+ err = mDispatch.getDisplayRequests(mDevice, display, &display_reqs,
+ &reqs_count, outRequestedLayers->data(),
+ reinterpret_cast<int32_t*>(outRequestMasks->data()));
+ if (err != HWC2_ERROR_NONE) {
+ outChangedLayers->clear();
+ outCompositionTypes->clear();
+
+ outRequestedLayers->clear();
+ outRequestMasks->clear();
+ return static_cast<Error>(err);
+ }
+
+ *outDisplayRequestMask = display_reqs;
+
+ return static_cast<Error>(err);
}
-Return<Error> HwcHal::setLayerSurfaceDamage(Display display,
- Layer layer, const hidl_vec<Rect>& damage)
+Error HwcHal::acceptDisplayChanges(Display display)
{
- hwc_region_t damage_region = { damage.size(),
- reinterpret_cast<const hwc_rect_t*>(&damage[0]) };
-
- auto error = mDispatch.setLayerSurfaceDamage(mDevice, display, layer,
- damage_region);
- return static_cast<Error>(error);
+ int32_t err = mDispatch.acceptDisplayChanges(mDevice, display);
+ return static_cast<Error>(err);
}
-Return<Error> HwcHal::setLayerBlendMode(Display display,
- Layer layer, BlendMode mode)
+Error HwcHal::presentDisplay(Display display, int32_t* outPresentFence,
+ std::vector<Layer>* outLayers, std::vector<int32_t>* outReleaseFences)
{
- auto error = mDispatch.setLayerBlendMode(mDevice, display, layer,
- static_cast<int32_t>(mode));
- return static_cast<Error>(error);
+ *outPresentFence = -1;
+ int32_t err = mDispatch.presentDisplay(mDevice, display, outPresentFence);
+ if (err != HWC2_ERROR_NONE) {
+ return static_cast<Error>(err);
+ }
+
+ uint32_t count = 0;
+ err = mDispatch.getReleaseFences(mDevice, display, &count,
+ nullptr, nullptr);
+ if (err != HWC2_ERROR_NONE) {
+ ALOGW("failed to get release fences");
+ return Error::NONE;
+ }
+
+ outLayers->resize(count);
+ outReleaseFences->resize(count);
+ err = mDispatch.getReleaseFences(mDevice, display, &count,
+ outLayers->data(), outReleaseFences->data());
+ if (err != HWC2_ERROR_NONE) {
+ ALOGW("failed to get release fences");
+ outLayers->clear();
+ outReleaseFences->clear();
+ return Error::NONE;
+ }
+
+ return static_cast<Error>(err);
}
-Return<Error> HwcHal::setLayerColor(Display display,
- Layer layer, const Color& color)
+Error HwcHal::setLayerCursorPosition(Display display, Layer layer,
+ int32_t x, int32_t y)
+{
+ int32_t err = mDispatch.setCursorPosition(mDevice, display, layer, x, y);
+ return static_cast<Error>(err);
+}
+
+Error HwcHal::setLayerBuffer(Display display, Layer layer,
+ buffer_handle_t buffer, int32_t acquireFence)
+{
+ int32_t err = mDispatch.setLayerBuffer(mDevice, display, layer,
+ buffer, acquireFence);
+ return static_cast<Error>(err);
+}
+
+Error HwcHal::setLayerSurfaceDamage(Display display, Layer layer,
+ const std::vector<hwc_rect_t>& damage)
+{
+ hwc_region region = { damage.size(), damage.data() };
+ int32_t err = mDispatch.setLayerSurfaceDamage(mDevice, display, layer,
+ region);
+ return static_cast<Error>(err);
+}
+
+Error HwcHal::setLayerBlendMode(Display display, Layer layer, int32_t mode)
+{
+ int32_t err = mDispatch.setLayerBlendMode(mDevice, display, layer, mode);
+ return static_cast<Error>(err);
+}
+
+Error HwcHal::setLayerColor(Display display, Layer layer,
+ IComposerClient::Color color)
{
hwc_color_t hwc_color{color.r, color.g, color.b, color.a};
- auto error = mDispatch.setLayerColor(mDevice, display, layer, hwc_color);
- return static_cast<Error>(error);
+ int32_t err = mDispatch.setLayerColor(mDevice, display, layer, hwc_color);
+ return static_cast<Error>(err);
}
-Return<Error> HwcHal::setLayerCompositionType(Display display,
- Layer layer, Composition type)
+Error HwcHal::setLayerCompositionType(Display display, Layer layer,
+ int32_t type)
{
- auto error = mDispatch.setLayerCompositionType(mDevice, display, layer,
- static_cast<int32_t>(type));
- return static_cast<Error>(error);
+ int32_t err = mDispatch.setLayerCompositionType(mDevice, display, layer,
+ type);
+ return static_cast<Error>(err);
}
-Return<Error> HwcHal::setLayerDataspace(Display display,
- Layer layer, Dataspace dataspace)
+Error HwcHal::setLayerDataspace(Display display, Layer layer,
+ int32_t dataspace)
{
- auto error = mDispatch.setLayerDataspace(mDevice, display, layer,
- static_cast<int32_t>(dataspace));
- return static_cast<Error>(error);
+ int32_t err = mDispatch.setLayerDataspace(mDevice, display, layer,
+ dataspace);
+ return static_cast<Error>(err);
}
-Return<Error> HwcHal::setLayerDisplayFrame(Display display,
- Layer layer, const Rect& frame)
+Error HwcHal::setLayerDisplayFrame(Display display, Layer layer,
+ const hwc_rect_t& frame)
{
- hwc_rect_t hwc_frame{frame.left, frame.top, frame.right, frame.bottom};
- auto error = mDispatch.setLayerDisplayFrame(mDevice, display, layer,
- hwc_frame);
- return static_cast<Error>(error);
+ int32_t err = mDispatch.setLayerDisplayFrame(mDevice, display, layer,
+ frame);
+ return static_cast<Error>(err);
}
-Return<Error> HwcHal::setLayerPlaneAlpha(Display display,
- Layer layer, float alpha)
+Error HwcHal::setLayerPlaneAlpha(Display display, Layer layer, float alpha)
{
- auto error = mDispatch.setLayerPlaneAlpha(mDevice, display, layer, alpha);
- return static_cast<Error>(error);
+ int32_t err = mDispatch.setLayerPlaneAlpha(mDevice, display, layer,
+ alpha);
+ return static_cast<Error>(err);
}
-Return<Error> HwcHal::setLayerSidebandStream(Display display,
- Layer layer, const hidl_handle& stream)
+Error HwcHal::setLayerSidebandStream(Display display, Layer layer,
+ buffer_handle_t stream)
{
- const native_handle_t* streamHandle = stream.getNativeHandle();
- if (!sHandleImporter.importBuffer(streamHandle)) {
- return Error::NO_RESOURCES;
- }
-
- int32_t error = mDispatch.setLayerSidebandStream(mDevice,
- display, layer, streamHandle);
- if (error == HWC2_ERROR_NONE) {
- std::lock_guard<std::mutex> lock(mDisplayMutex);
-
- auto dpy = mDisplays.find(display);
- dpy->second.LayerSidebandStreams[layer] = streamHandle;
- } else {
- sHandleImporter.freeBuffer(streamHandle);
- }
-
- return static_cast<Error>(error);
+ int32_t err = mDispatch.setLayerSidebandStream(mDevice, display, layer,
+ stream);
+ return static_cast<Error>(err);
}
-Return<Error> HwcHal::setLayerSourceCrop(Display display,
- Layer layer, const FRect& crop)
+Error HwcHal::setLayerSourceCrop(Display display, Layer layer,
+ const hwc_frect_t& crop)
{
- hwc_frect_t hwc_crop{crop.left, crop.top, crop.right, crop.bottom};
- auto error = mDispatch.setLayerSourceCrop(mDevice, display, layer,
- hwc_crop);
- return static_cast<Error>(error);
+ int32_t err = mDispatch.setLayerSourceCrop(mDevice, display, layer, crop);
+ return static_cast<Error>(err);
}
-Return<Error> HwcHal::setLayerTransform(Display display,
- Layer layer, Transform transform)
+Error HwcHal::setLayerTransform(Display display, Layer layer,
+ int32_t transform)
{
- auto error = mDispatch.setLayerTransform(mDevice, display, layer,
- static_cast<int32_t>(transform));
- return static_cast<Error>(error);
+ int32_t err = mDispatch.setLayerTransform(mDevice, display, layer,
+ transform);
+ return static_cast<Error>(err);
}
-Return<Error> HwcHal::setLayerVisibleRegion(Display display,
- Layer layer, const hidl_vec<Rect>& visible)
+Error HwcHal::setLayerVisibleRegion(Display display, Layer layer,
+ const std::vector<hwc_rect_t>& visible)
{
- hwc_region_t visible_region = { visible.size(),
- reinterpret_cast<const hwc_rect_t*>(&visible[0]) };
-
- auto error = mDispatch.setLayerVisibleRegion(mDevice, display, layer,
- visible_region);
- return static_cast<Error>(error);
+ hwc_region_t region = { visible.size(), visible.data() };
+ int32_t err = mDispatch.setLayerVisibleRegion(mDevice, display, layer,
+ region);
+ return static_cast<Error>(err);
}
-Return<Error> HwcHal::setLayerZOrder(Display display,
- Layer layer, uint32_t z)
+Error HwcHal::setLayerZOrder(Display display, Layer layer, uint32_t z)
{
- auto error = mDispatch.setLayerZOrder(mDevice, display, layer, z);
- return static_cast<Error>(error);
+ int32_t err = mDispatch.setLayerZOrder(mDevice, display, layer, z);
+ return static_cast<Error>(err);
}
IComposer* HIDL_FETCH_IComposer(const char*)
{
- const hw_module_t* module;
+ const hw_module_t* module = nullptr;
int err = hw_get_module(HWC_HARDWARE_MODULE_ID, &module);
if (err) {
ALOGE("failed to get hwcomposer module");
diff --git a/graphics/composer/2.1/default/Hwc.h b/graphics/composer/2.1/default/Hwc.h
index de69417..6420b31 100644
--- a/graphics/composer/2.1/default/Hwc.h
+++ b/graphics/composer/2.1/default/Hwc.h
@@ -17,7 +17,12 @@
#ifndef ANDROID_HARDWARE_GRAPHICS_COMPOSER_V2_1_HWC_H
#define ANDROID_HARDWARE_GRAPHICS_COMPOSER_V2_1_HWC_H
+#include <mutex>
+#include <unordered_set>
+#include <vector>
+
#include <android/hardware/graphics/composer/2.1/IComposer.h>
+#include <hardware/hwcomposer2.h>
namespace android {
namespace hardware {
@@ -26,6 +31,174 @@
namespace V2_1 {
namespace implementation {
+using android::hardware::graphics::common::V1_0::PixelFormat;
+using android::hardware::graphics::common::V1_0::Transform;
+using android::hardware::graphics::common::V1_0::Dataspace;
+using android::hardware::graphics::common::V1_0::ColorMode;
+using android::hardware::graphics::common::V1_0::ColorTransform;
+using android::hardware::graphics::common::V1_0::Hdr;
+
+class HwcClient;
+
+class HwcHal : public IComposer {
+public:
+ HwcHal(const hw_module_t* module);
+ virtual ~HwcHal();
+
+ // IComposer interface
+ Return<void> getCapabilities(getCapabilities_cb hidl_cb) override;
+ Return<void> dumpDebugInfo(dumpDebugInfo_cb hidl_cb) override;
+ Return<void> createClient(createClient_cb hidl_cb) override;
+
+ bool hasCapability(Capability capability) const;
+
+ void removeClient();
+
+ void enableCallback(bool enable);
+
+ uint32_t getMaxVirtualDisplayCount();
+ Error createVirtualDisplay(uint32_t width, uint32_t height,
+ PixelFormat* format, Display* outDisplay);
+ Error destroyVirtualDisplay(Display display);
+
+ Error createLayer(Display display, Layer* outLayer);
+ Error destroyLayer(Display display, Layer layer);
+
+ Error getActiveConfig(Display display, Config* outConfig);
+ Error getClientTargetSupport(Display display,
+ uint32_t width, uint32_t height,
+ PixelFormat format, Dataspace dataspace);
+ Error getColorModes(Display display, hidl_vec<ColorMode>* outModes);
+ Error getDisplayAttribute(Display display, Config config,
+ IComposerClient::Attribute attribute, int32_t* outValue);
+ Error getDisplayConfigs(Display display, hidl_vec<Config>* outConfigs);
+ Error getDisplayName(Display display, hidl_string* outName);
+ Error getDisplayType(Display display,
+ IComposerClient::DisplayType* outType);
+ Error getDozeSupport(Display display, bool* outSupport);
+ Error getHdrCapabilities(Display display, hidl_vec<Hdr>* outTypes,
+ float* outMaxLuminance, float* outMaxAverageLuminance,
+ float* outMinLuminance);
+
+ Error setActiveConfig(Display display, Config config);
+ Error setColorMode(Display display, ColorMode mode);
+ Error setPowerMode(Display display, IComposerClient::PowerMode mode);
+ Error setVsyncEnabled(Display display, IComposerClient::Vsync enabled);
+
+ Error setColorTransform(Display display, const float* matrix,
+ int32_t hint);
+ Error setClientTarget(Display display, buffer_handle_t target,
+ int32_t acquireFence, int32_t dataspace,
+ const std::vector<hwc_rect_t>& damage);
+ Error setOutputBuffer(Display display, buffer_handle_t buffer,
+ int32_t releaseFence);
+ Error validateDisplay(Display display,
+ std::vector<Layer>* outChangedLayers,
+ std::vector<IComposerClient::Composition>* outCompositionTypes,
+ uint32_t* outDisplayRequestMask,
+ std::vector<Layer>* outRequestedLayers,
+ std::vector<uint32_t>* outRequestMasks);
+ Error acceptDisplayChanges(Display display);
+ Error presentDisplay(Display display, int32_t* outPresentFence,
+ std::vector<Layer>* outLayers,
+ std::vector<int32_t>* outReleaseFences);
+
+ Error setLayerCursorPosition(Display display, Layer layer,
+ int32_t x, int32_t y);
+ Error setLayerBuffer(Display display, Layer layer,
+ buffer_handle_t buffer, int32_t acquireFence);
+ Error setLayerSurfaceDamage(Display display, Layer layer,
+ const std::vector<hwc_rect_t>& damage);
+ Error setLayerBlendMode(Display display, Layer layer, int32_t mode);
+ Error setLayerColor(Display display, Layer layer,
+ IComposerClient::Color color);
+ Error setLayerCompositionType(Display display, Layer layer,
+ int32_t type);
+ Error setLayerDataspace(Display display, Layer layer,
+ int32_t dataspace);
+ Error setLayerDisplayFrame(Display display, Layer layer,
+ const hwc_rect_t& frame);
+ Error setLayerPlaneAlpha(Display display, Layer layer, float alpha);
+ Error setLayerSidebandStream(Display display, Layer layer,
+ buffer_handle_t stream);
+ Error setLayerSourceCrop(Display display, Layer layer,
+ const hwc_frect_t& crop);
+ Error setLayerTransform(Display display, Layer layer,
+ int32_t transform);
+ Error setLayerVisibleRegion(Display display, Layer layer,
+ const std::vector<hwc_rect_t>& visible);
+ Error setLayerZOrder(Display display, Layer layer, uint32_t z);
+
+private:
+ void initCapabilities();
+
+ template<typename T>
+ void initDispatch(hwc2_function_descriptor_t desc, T* outPfn);
+ void initDispatch();
+
+ sp<HwcClient> getClient();
+
+ static void hotplugHook(hwc2_callback_data_t callbackData,
+ hwc2_display_t display, int32_t connected);
+ static void refreshHook(hwc2_callback_data_t callbackData,
+ hwc2_display_t display);
+ static void vsyncHook(hwc2_callback_data_t callbackData,
+ hwc2_display_t display, int64_t timestamp);
+
+ hwc2_device_t* mDevice;
+
+ std::unordered_set<Capability> mCapabilities;
+
+ struct {
+ HWC2_PFN_ACCEPT_DISPLAY_CHANGES acceptDisplayChanges;
+ HWC2_PFN_CREATE_LAYER createLayer;
+ HWC2_PFN_CREATE_VIRTUAL_DISPLAY createVirtualDisplay;
+ HWC2_PFN_DESTROY_LAYER destroyLayer;
+ HWC2_PFN_DESTROY_VIRTUAL_DISPLAY destroyVirtualDisplay;
+ HWC2_PFN_DUMP dump;
+ HWC2_PFN_GET_ACTIVE_CONFIG getActiveConfig;
+ HWC2_PFN_GET_CHANGED_COMPOSITION_TYPES getChangedCompositionTypes;
+ HWC2_PFN_GET_CLIENT_TARGET_SUPPORT getClientTargetSupport;
+ HWC2_PFN_GET_COLOR_MODES getColorModes;
+ HWC2_PFN_GET_DISPLAY_ATTRIBUTE getDisplayAttribute;
+ HWC2_PFN_GET_DISPLAY_CONFIGS getDisplayConfigs;
+ HWC2_PFN_GET_DISPLAY_NAME getDisplayName;
+ HWC2_PFN_GET_DISPLAY_REQUESTS getDisplayRequests;
+ HWC2_PFN_GET_DISPLAY_TYPE getDisplayType;
+ HWC2_PFN_GET_DOZE_SUPPORT getDozeSupport;
+ HWC2_PFN_GET_HDR_CAPABILITIES getHdrCapabilities;
+ HWC2_PFN_GET_MAX_VIRTUAL_DISPLAY_COUNT getMaxVirtualDisplayCount;
+ HWC2_PFN_GET_RELEASE_FENCES getReleaseFences;
+ HWC2_PFN_PRESENT_DISPLAY presentDisplay;
+ HWC2_PFN_REGISTER_CALLBACK registerCallback;
+ HWC2_PFN_SET_ACTIVE_CONFIG setActiveConfig;
+ HWC2_PFN_SET_CLIENT_TARGET setClientTarget;
+ HWC2_PFN_SET_COLOR_MODE setColorMode;
+ HWC2_PFN_SET_COLOR_TRANSFORM setColorTransform;
+ HWC2_PFN_SET_CURSOR_POSITION setCursorPosition;
+ HWC2_PFN_SET_LAYER_BLEND_MODE setLayerBlendMode;
+ HWC2_PFN_SET_LAYER_BUFFER setLayerBuffer;
+ HWC2_PFN_SET_LAYER_COLOR setLayerColor;
+ HWC2_PFN_SET_LAYER_COMPOSITION_TYPE setLayerCompositionType;
+ HWC2_PFN_SET_LAYER_DATASPACE setLayerDataspace;
+ HWC2_PFN_SET_LAYER_DISPLAY_FRAME setLayerDisplayFrame;
+ HWC2_PFN_SET_LAYER_PLANE_ALPHA setLayerPlaneAlpha;
+ HWC2_PFN_SET_LAYER_SIDEBAND_STREAM setLayerSidebandStream;
+ HWC2_PFN_SET_LAYER_SOURCE_CROP setLayerSourceCrop;
+ HWC2_PFN_SET_LAYER_SURFACE_DAMAGE setLayerSurfaceDamage;
+ HWC2_PFN_SET_LAYER_TRANSFORM setLayerTransform;
+ HWC2_PFN_SET_LAYER_VISIBLE_REGION setLayerVisibleRegion;
+ HWC2_PFN_SET_LAYER_Z_ORDER setLayerZOrder;
+ HWC2_PFN_SET_OUTPUT_BUFFER setOutputBuffer;
+ HWC2_PFN_SET_POWER_MODE setPowerMode;
+ HWC2_PFN_SET_VSYNC_ENABLED setVsyncEnabled;
+ HWC2_PFN_VALIDATE_DISPLAY validateDisplay;
+ } mDispatch;
+
+ std::mutex mClientMutex;
+ wp<HwcClient> mClient;
+};
+
extern "C" IComposer* HIDL_FETCH_IComposer(const char* name);
} // namespace implementation
diff --git a/graphics/composer/2.1/default/HwcClient.cpp b/graphics/composer/2.1/default/HwcClient.cpp
new file mode 100644
index 0000000..ce6c480
--- /dev/null
+++ b/graphics/composer/2.1/default/HwcClient.cpp
@@ -0,0 +1,1128 @@
+/*
+ * 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 "HwcPassthrough"
+
+#include <hardware/gralloc.h>
+#include <hardware/gralloc1.h>
+#include <log/log.h>
+
+#include "Hwc.h"
+#include "HwcClient.h"
+#include "IComposerCommandBuffer.h"
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace composer {
+namespace V2_1 {
+namespace implementation {
+
+namespace {
+
+class HandleImporter {
+public:
+ HandleImporter() : mInitialized(false) {}
+
+ bool initialize()
+ {
+ // allow only one client
+ if (mInitialized) {
+ return false;
+ }
+
+ if (!openGralloc()) {
+ return false;
+ }
+
+ mInitialized = true;
+ return true;
+ }
+
+ void cleanup()
+ {
+ if (!mInitialized) {
+ return;
+ }
+
+ closeGralloc();
+ mInitialized = false;
+ }
+
+ // In IComposer, any buffer_handle_t is owned by the caller and we need to
+ // make a clone for hwcomposer2. We also need to translate empty handle
+ // to nullptr. This function does that, in-place.
+ bool importBuffer(buffer_handle_t& handle)
+ {
+ if (!handle) {
+ return true;
+ }
+
+ if (!handle->numFds && !handle->numInts) {
+ handle = nullptr;
+ return true;
+ }
+
+ buffer_handle_t clone = cloneBuffer(handle);
+ if (!clone) {
+ return false;
+ }
+
+ handle = clone;
+ return true;
+ }
+
+ void freeBuffer(buffer_handle_t handle)
+ {
+ if (!handle) {
+ return;
+ }
+
+ releaseBuffer(handle);
+ }
+
+private:
+ bool mInitialized;
+
+ // Some existing gralloc drivers do not support retaining more than once,
+ // when we are in passthrough mode.
+#ifdef BINDERIZED
+ bool openGralloc()
+ {
+ const hw_module_t* module = nullptr;
+ int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
+ if (err) {
+ ALOGE("failed to get gralloc module");
+ return false;
+ }
+
+ uint8_t major = (module->module_api_version >> 8) & 0xff;
+ if (major > 1) {
+ ALOGE("unknown gralloc module major version %d", major);
+ return false;
+ }
+
+ if (major == 1) {
+ err = gralloc1_open(module, &mDevice);
+ if (err) {
+ ALOGE("failed to open gralloc1 device");
+ return false;
+ }
+
+ mRetain = reinterpret_cast<GRALLOC1_PFN_RETAIN>(
+ mDevice->getFunction(mDevice, GRALLOC1_FUNCTION_RETAIN));
+ mRelease = reinterpret_cast<GRALLOC1_PFN_RELEASE>(
+ mDevice->getFunction(mDevice, GRALLOC1_FUNCTION_RELEASE));
+ if (!mRetain || !mRelease) {
+ ALOGE("invalid gralloc1 device");
+ gralloc1_close(mDevice);
+ return false;
+ }
+ } else {
+ mModule = reinterpret_cast<const gralloc_module_t*>(module);
+ }
+
+ return true;
+ }
+
+ void closeGralloc()
+ {
+ if (mDevice) {
+ gralloc1_close(mDevice);
+ }
+ }
+
+ buffer_handle_t cloneBuffer(buffer_handle_t handle)
+ {
+ native_handle_t* clone = native_handle_clone(handle);
+ if (!clone) {
+ ALOGE("failed to clone buffer %p", handle);
+ return nullptr;
+ }
+
+ bool err;
+ if (mDevice) {
+ err = (mRetain(mDevice, clone) != GRALLOC1_ERROR_NONE);
+ } else {
+ err = (mModule->registerBuffer(mModule, clone) != 0);
+ }
+
+ if (err) {
+ ALOGE("failed to retain/register buffer %p", clone);
+ native_handle_close(clone);
+ native_handle_delete(clone);
+ return nullptr;
+ }
+
+ return clone;
+ }
+
+ void releaseBuffer(buffer_handle_t handle)
+ {
+ if (mDevice) {
+ mRelease(mDevice, handle);
+ } else {
+ mModule->unregisterBuffer(mModule, handle);
+ native_handle_close(handle);
+ native_handle_delete(const_cast<native_handle_t*>(handle));
+ }
+ }
+
+ // gralloc1
+ gralloc1_device_t* mDevice;
+ GRALLOC1_PFN_RETAIN mRetain;
+ GRALLOC1_PFN_RELEASE mRelease;
+
+ // gralloc0
+ const gralloc_module_t* mModule;
+#else
+ bool openGralloc() { return true; }
+ void closeGralloc() {}
+ buffer_handle_t cloneBuffer(buffer_handle_t handle) { return handle; }
+ void releaseBuffer(buffer_handle_t) {}
+#endif
+};
+
+HandleImporter sHandleImporter;
+
+} // anonymous namespace
+
+BufferClone::BufferClone()
+ : mHandle(nullptr)
+{
+}
+
+BufferClone::BufferClone(BufferClone&& other)
+{
+ mHandle = other.mHandle;
+ other.mHandle = nullptr;
+}
+
+BufferClone& BufferClone::operator=(buffer_handle_t handle)
+{
+ clear();
+ mHandle = handle;
+ return *this;
+}
+
+BufferClone::~BufferClone()
+{
+ clear();
+}
+
+void BufferClone::clear()
+{
+ if (mHandle) {
+ sHandleImporter.freeBuffer(mHandle);
+ }
+}
+
+HwcClient::HwcClient(HwcHal& hal)
+ : mHal(hal), mReader(*this), mWriter(kWriterInitialSize)
+{
+ if (!sHandleImporter.initialize()) {
+ LOG_ALWAYS_FATAL("failed to initialize handle importer");
+ }
+}
+
+HwcClient::~HwcClient()
+{
+ mHal.enableCallback(false);
+ mHal.removeClient();
+
+ // no need to grab the mutex as any in-flight hwbinder call should keep
+ // the client alive
+ for (const auto& dpy : mDisplayData) {
+ if (!dpy.second.Layers.empty()) {
+ ALOGW("client destroyed with valid layers");
+ }
+ for (const auto& ly : dpy.second.Layers) {
+ mHal.destroyLayer(dpy.first, ly.first);
+ }
+
+ if (dpy.second.IsVirtual) {
+ ALOGW("client destroyed with valid virtual display");
+ mHal.destroyVirtualDisplay(dpy.first);
+ }
+ }
+
+ mDisplayData.clear();
+
+ sHandleImporter.cleanup();
+}
+
+void HwcClient::onHotplug(Display display,
+ IComposerCallback::Connection connected)
+{
+ {
+ std::lock_guard<std::mutex> lock(mDisplayDataMutex);
+
+ if (connected == IComposerCallback::Connection::CONNECTED) {
+ mDisplayData.emplace(display, DisplayData(false));
+ } else if (connected == IComposerCallback::Connection::DISCONNECTED) {
+ mDisplayData.erase(display);
+ }
+ }
+
+ mCallback->onHotplug(display, connected);
+}
+
+void HwcClient::onRefresh(Display display)
+{
+ mCallback->onRefresh(display);
+}
+
+void HwcClient::onVsync(Display display, int64_t timestamp)
+{
+ mCallback->onVsync(display, timestamp);
+}
+
+Return<void> HwcClient::registerCallback(const sp<IComposerCallback>& callback)
+{
+ // no locking as we require this function to be called only once
+ mCallback = callback;
+ mHal.enableCallback(callback != nullptr);
+
+ return Void();
+}
+
+Return<uint32_t> HwcClient::getMaxVirtualDisplayCount()
+{
+ return mHal.getMaxVirtualDisplayCount();
+}
+
+Return<void> HwcClient::createVirtualDisplay(uint32_t width, uint32_t height,
+ PixelFormat formatHint, uint32_t outputBufferSlotCount,
+ createVirtualDisplay_cb hidl_cb)
+{
+ Display display = 0;
+ Error err = mHal.createVirtualDisplay(width, height,
+ &formatHint, &display);
+ if (err == Error::NONE) {
+ std::lock_guard<std::mutex> lock(mDisplayDataMutex);
+
+ auto dpy = mDisplayData.emplace(display, DisplayData(true)).first;
+ dpy->second.OutputBuffers.resize(outputBufferSlotCount);
+ }
+
+ hidl_cb(err, display, formatHint);
+ return Void();
+}
+
+Return<Error> HwcClient::destroyVirtualDisplay(Display display)
+{
+ Error err = mHal.destroyVirtualDisplay(display);
+ if (err == Error::NONE) {
+ std::lock_guard<std::mutex> lock(mDisplayDataMutex);
+
+ mDisplayData.erase(display);
+ }
+
+ return err;
+}
+
+Return<void> HwcClient::createLayer(Display display, uint32_t bufferSlotCount,
+ createLayer_cb hidl_cb)
+{
+ Layer layer = 0;
+ Error err = mHal.createLayer(display, &layer);
+ if (err == Error::NONE) {
+ std::lock_guard<std::mutex> lock(mDisplayDataMutex);
+
+ auto dpy = mDisplayData.find(display);
+ auto ly = dpy->second.Layers.emplace(layer, LayerBuffers()).first;
+ ly->second.Buffers.resize(bufferSlotCount);
+ }
+
+ hidl_cb(err, layer);
+ return Void();
+}
+
+Return<Error> HwcClient::destroyLayer(Display display, Layer layer)
+{
+ Error err = mHal.destroyLayer(display, layer);
+ if (err == Error::NONE) {
+ std::lock_guard<std::mutex> lock(mDisplayDataMutex);
+
+ auto dpy = mDisplayData.find(display);
+ dpy->second.Layers.erase(layer);
+ }
+
+ return err;
+}
+
+Return<void> HwcClient::getActiveConfig(Display display,
+ getActiveConfig_cb hidl_cb)
+{
+ Config config = 0;
+ Error err = mHal.getActiveConfig(display, &config);
+
+ hidl_cb(err, config);
+ return Void();
+}
+
+Return<Error> HwcClient::getClientTargetSupport(Display display,
+ uint32_t width, uint32_t height,
+ PixelFormat format, Dataspace dataspace)
+{
+ Error err = mHal.getClientTargetSupport(display,
+ width, height, format, dataspace);
+ return err;
+}
+
+Return<void> HwcClient::getColorModes(Display display, getColorModes_cb hidl_cb)
+{
+ hidl_vec<ColorMode> modes;
+ Error err = mHal.getColorModes(display, &modes);
+
+ hidl_cb(err, modes);
+ return Void();
+}
+
+Return<void> HwcClient::getDisplayAttribute(Display display,
+ Config config, Attribute attribute,
+ getDisplayAttribute_cb hidl_cb)
+{
+ int32_t value = 0;
+ Error err = mHal.getDisplayAttribute(display, config, attribute, &value);
+
+ hidl_cb(err, value);
+ return Void();
+}
+
+Return<void> HwcClient::getDisplayConfigs(Display display,
+ getDisplayConfigs_cb hidl_cb)
+{
+ hidl_vec<Config> configs;
+ Error err = mHal.getDisplayConfigs(display, &configs);
+
+ hidl_cb(err, configs);
+ return Void();
+}
+
+Return<void> HwcClient::getDisplayName(Display display,
+ getDisplayName_cb hidl_cb)
+{
+ hidl_string name;
+ Error err = mHal.getDisplayName(display, &name);
+
+ hidl_cb(err, name);
+ return Void();
+}
+
+Return<void> HwcClient::getDisplayType(Display display,
+ getDisplayType_cb hidl_cb)
+{
+ DisplayType type = DisplayType::INVALID;
+ Error err = mHal.getDisplayType(display, &type);
+
+ hidl_cb(err, type);
+ return Void();
+}
+
+Return<void> HwcClient::getDozeSupport(Display display,
+ getDozeSupport_cb hidl_cb)
+{
+ bool support = false;
+ Error err = mHal.getDozeSupport(display, &support);
+
+ hidl_cb(err, support);
+ return Void();
+}
+
+Return<void> HwcClient::getHdrCapabilities(Display display,
+ getHdrCapabilities_cb hidl_cb)
+{
+ hidl_vec<Hdr> types;
+ float max_lumi = 0.0f;
+ float max_avg_lumi = 0.0f;
+ float min_lumi = 0.0f;
+ Error err = mHal.getHdrCapabilities(display, &types,
+ &max_lumi, &max_avg_lumi, &min_lumi);
+
+ hidl_cb(err, types, max_lumi, max_avg_lumi, min_lumi);
+ return Void();
+}
+
+Return<Error> HwcClient::setClientTargetSlotCount(Display display,
+ uint32_t clientTargetSlotCount)
+{
+ std::lock_guard<std::mutex> lock(mDisplayDataMutex);
+
+ auto dpy = mDisplayData.find(display);
+ if (dpy == mDisplayData.end()) {
+ return Error::BAD_DISPLAY;
+ }
+
+ dpy->second.ClientTargets.resize(clientTargetSlotCount);
+
+ return Error::NONE;
+}
+
+Return<Error> HwcClient::setActiveConfig(Display display, Config config)
+{
+ Error err = mHal.setActiveConfig(display, config);
+ return err;
+}
+
+Return<Error> HwcClient::setColorMode(Display display, ColorMode mode)
+{
+ Error err = mHal.setColorMode(display, mode);
+ return err;
+}
+
+Return<Error> HwcClient::setPowerMode(Display display, PowerMode mode)
+{
+ Error err = mHal.setPowerMode(display, mode);
+ return err;
+}
+
+Return<Error> HwcClient::setVsyncEnabled(Display display, Vsync enabled)
+{
+ Error err = mHal.setVsyncEnabled(display, enabled);
+ return err;
+}
+
+Return<Error> HwcClient::setInputCommandQueue(
+ const MQDescriptorSync& descriptor)
+{
+ std::lock_guard<std::mutex> lock(mCommandMutex);
+ return mReader.setMQDescriptor(descriptor) ?
+ Error::NONE : Error::NO_RESOURCES;
+}
+
+Return<void> HwcClient::getOutputCommandQueue(
+ getOutputCommandQueue_cb hidl_cb)
+{
+ // no locking as we require this function to be called inside
+ // executeCommands_cb
+
+ auto outDescriptor = mWriter.getMQDescriptor();
+ if (outDescriptor) {
+ hidl_cb(Error::NONE, *outDescriptor);
+ } else {
+ hidl_cb(Error::NO_RESOURCES, MQDescriptorSync(0, nullptr, 0));
+ }
+
+ return Void();
+}
+
+Return<void> HwcClient::executeCommands(uint32_t inLength,
+ const hidl_vec<hidl_handle>& inHandles,
+ executeCommands_cb hidl_cb)
+{
+ std::lock_guard<std::mutex> lock(mCommandMutex);
+
+ bool outChanged = false;
+ uint32_t outLength = 0;
+ hidl_vec<hidl_handle> outHandles;
+
+ if (!mReader.readQueue(inLength, inHandles)) {
+ hidl_cb(Error::BAD_PARAMETER, outChanged, outLength, outHandles);
+ return Void();
+ }
+
+ Error err = mReader.parse();
+ if (err == Error::NONE &&
+ !mWriter.writeQueue(&outChanged, &outLength, &outHandles)) {
+ err = Error::NO_RESOURCES;
+ }
+
+ hidl_cb(err, outChanged, outLength, outHandles);
+
+ mReader.reset();
+ mWriter.reset();
+
+ return Void();
+}
+
+HwcClient::CommandReader::CommandReader(HwcClient& client)
+ : mClient(client), mHal(client.mHal), mWriter(client.mWriter)
+{
+}
+
+Error HwcClient::CommandReader::parse()
+{
+ IComposerClient::Command command;
+ uint16_t length = 0;
+
+ while (!isEmpty()) {
+ if (!beginCommand(&command, &length)) {
+ break;
+ }
+
+ bool parsed = false;
+ switch (command) {
+ case IComposerClient::Command::SELECT_DISPLAY:
+ parsed = parseSelectDisplay(length);
+ break;
+ case IComposerClient::Command::SELECT_LAYER:
+ parsed = parseSelectLayer(length);
+ break;
+ case IComposerClient::Command::SET_COLOR_TRANSFORM:
+ parsed = parseSetColorTransform(length);
+ break;
+ case IComposerClient::Command::SET_CLIENT_TARGET:
+ parsed = parseSetClientTarget(length);
+ break;
+ case IComposerClient::Command::SET_OUTPUT_BUFFER:
+ parsed = parseSetOutputBuffer(length);
+ break;
+ case IComposerClient::Command::VALIDATE_DISPLAY:
+ parsed = parseValidateDisplay(length);
+ break;
+ case IComposerClient::Command::ACCEPT_DISPLAY_CHANGES:
+ parsed = parseAcceptDisplayChanges(length);
+ break;
+ case IComposerClient::Command::PRESENT_DISPLAY:
+ parsed = parsePresentDisplay(length);
+ break;
+ case IComposerClient::Command::SET_LAYER_CURSOR_POSITION:
+ parsed = parseSetLayerCursorPosition(length);
+ break;
+ case IComposerClient::Command::SET_LAYER_BUFFER:
+ parsed = parseSetLayerBuffer(length);
+ break;
+ case IComposerClient::Command::SET_LAYER_SURFACE_DAMAGE:
+ parsed = parseSetLayerSurfaceDamage(length);
+ break;
+ case IComposerClient::Command::SET_LAYER_BLEND_MODE:
+ parsed = parseSetLayerBlendMode(length);
+ break;
+ case IComposerClient::Command::SET_LAYER_COLOR:
+ parsed = parseSetLayerColor(length);
+ break;
+ case IComposerClient::Command::SET_LAYER_COMPOSITION_TYPE:
+ parsed = parseSetLayerCompositionType(length);
+ break;
+ case IComposerClient::Command::SET_LAYER_DATASPACE:
+ parsed = parseSetLayerDataspace(length);
+ break;
+ case IComposerClient::Command::SET_LAYER_DISPLAY_FRAME:
+ parsed = parseSetLayerDisplayFrame(length);
+ break;
+ case IComposerClient::Command::SET_LAYER_PLANE_ALPHA:
+ parsed = parseSetLayerPlaneAlpha(length);
+ break;
+ case IComposerClient::Command::SET_LAYER_SIDEBAND_STREAM:
+ parsed = parseSetLayerSidebandStream(length);
+ break;
+ case IComposerClient::Command::SET_LAYER_SOURCE_CROP:
+ parsed = parseSetLayerSourceCrop(length);
+ break;
+ case IComposerClient::Command::SET_LAYER_TRANSFORM:
+ parsed = parseSetLayerTransform(length);
+ break;
+ case IComposerClient::Command::SET_LAYER_VISIBLE_REGION:
+ parsed = parseSetLayerVisibleRegion(length);
+ break;
+ case IComposerClient::Command::SET_LAYER_Z_ORDER:
+ parsed = parseSetLayerZOrder(length);
+ break;
+ default:
+ parsed = false;
+ break;
+ }
+
+ endCommand();
+
+ if (!parsed) {
+ ALOGE("failed to parse command 0x%x, length %" PRIu16,
+ command, length);
+ break;
+ }
+ }
+
+ return (isEmpty()) ? Error::NONE : Error::BAD_PARAMETER;
+}
+
+bool HwcClient::CommandReader::parseSelectDisplay(uint16_t length)
+{
+ if (length != CommandWriter::kSelectDisplayLength) {
+ return false;
+ }
+
+ mDisplay = read64();
+ mWriter.selectDisplay(mDisplay);
+
+ return true;
+}
+
+bool HwcClient::CommandReader::parseSelectLayer(uint16_t length)
+{
+ if (length != CommandWriter::kSelectLayerLength) {
+ return false;
+ }
+
+ mLayer = read64();
+
+ return true;
+}
+
+bool HwcClient::CommandReader::parseSetColorTransform(uint16_t length)
+{
+ if (length != CommandWriter::kSetColorTransformLength) {
+ return false;
+ }
+
+ float matrix[16];
+ for (int i = 0; i < 16; i++) {
+ matrix[i] = readFloat();
+ }
+ auto transform = readSigned();
+
+ auto err = mHal.setColorTransform(mDisplay, matrix, transform);
+ if (err != Error::NONE) {
+ mWriter.setError(getCommandLoc(), err);
+ }
+
+ return true;
+}
+
+bool HwcClient::CommandReader::parseSetClientTarget(uint16_t length)
+{
+ // 4 parameters followed by N rectangles
+ if ((length - 4) % 4 != 0) {
+ return false;
+ }
+
+ bool useCache = false;
+ auto slot = read();
+ auto clientTarget = readHandle(&useCache);
+ auto fence = readFence();
+ auto dataspace = readSigned();
+ auto damage = readRegion((length - 4) / 4);
+
+ auto err = lookupBuffer(BufferCache::CLIENT_TARGETS,
+ slot, useCache, clientTarget);
+ if (err == Error::NONE) {
+ err = mHal.setClientTarget(mDisplay, clientTarget, fence,
+ dataspace, damage);
+ }
+ if (err != Error::NONE) {
+ close(fence);
+ mWriter.setError(getCommandLoc(), err);
+ }
+
+ return true;
+}
+
+bool HwcClient::CommandReader::parseSetOutputBuffer(uint16_t length)
+{
+ if (length != CommandWriter::kSetOutputBufferLength) {
+ return false;
+ }
+
+ bool useCache = false;
+ auto slot = read();
+ auto outputBuffer = readHandle(&useCache);
+ auto fence = readFence();
+
+ auto err = lookupBuffer(BufferCache::OUTPUT_BUFFERS,
+ slot, useCache, outputBuffer);
+ if (err == Error::NONE) {
+ err = mHal.setOutputBuffer(mDisplay, outputBuffer, fence);
+ }
+ if (err != Error::NONE) {
+ close(fence);
+ mWriter.setError(getCommandLoc(), err);
+ }
+
+ return true;
+}
+
+bool HwcClient::CommandReader::parseValidateDisplay(uint16_t length)
+{
+ if (length != CommandWriter::kValidateDisplayLength) {
+ return false;
+ }
+
+ std::vector<Layer> changedLayers;
+ std::vector<IComposerClient::Composition> compositionTypes;
+ uint32_t displayRequestMask = 0x0;
+ std::vector<Layer> requestedLayers;
+ std::vector<uint32_t> requestMasks;
+
+ auto err = mHal.validateDisplay(mDisplay, &changedLayers,
+ &compositionTypes, &displayRequestMask,
+ &requestedLayers, &requestMasks);
+ if (err == Error::NONE) {
+ mWriter.setChangedCompositionTypes(changedLayers,
+ compositionTypes);
+ mWriter.setDisplayRequests(displayRequestMask,
+ requestedLayers, requestMasks);
+ } else {
+ mWriter.setError(getCommandLoc(), err);
+ }
+
+ return true;
+}
+
+bool HwcClient::CommandReader::parseAcceptDisplayChanges(uint16_t length)
+{
+ if (length != CommandWriter::kAcceptDisplayChangesLength) {
+ return false;
+ }
+
+ auto err = mHal.acceptDisplayChanges(mDisplay);
+ if (err != Error::NONE) {
+ mWriter.setError(getCommandLoc(), err);
+ }
+
+ return true;
+}
+
+bool HwcClient::CommandReader::parsePresentDisplay(uint16_t length)
+{
+ if (length != CommandWriter::kPresentDisplayLength) {
+ return false;
+ }
+
+ int presentFence = -1;
+ std::vector<Layer> layers;
+ std::vector<int> fences;
+ auto err = mHal.presentDisplay(mDisplay, &presentFence, &layers, &fences);
+ if (err == Error::NONE) {
+ mWriter.setPresentFence(presentFence);
+ mWriter.setReleaseFences(layers, fences);
+ } else {
+ mWriter.setError(getCommandLoc(), err);
+ }
+
+ return true;
+}
+
+bool HwcClient::CommandReader::parseSetLayerCursorPosition(uint16_t length)
+{
+ if (length != CommandWriter::kSetLayerCursorPositionLength) {
+ return false;
+ }
+
+ auto err = mHal.setLayerCursorPosition(mDisplay, mLayer,
+ readSigned(), readSigned());
+ if (err != Error::NONE) {
+ mWriter.setError(getCommandLoc(), err);
+ }
+
+ return true;
+}
+
+bool HwcClient::CommandReader::parseSetLayerBuffer(uint16_t length)
+{
+ if (length != CommandWriter::kSetLayerBufferLength) {
+ return false;
+ }
+
+ bool useCache = false;
+ auto slot = read();
+ auto buffer = readHandle(&useCache);
+ auto fence = readFence();
+
+ auto err = lookupBuffer(BufferCache::LAYER_BUFFERS,
+ slot, useCache, buffer);
+ if (err == Error::NONE) {
+ err = mHal.setLayerBuffer(mDisplay, mLayer, buffer, fence);
+ }
+ if (err != Error::NONE) {
+ close(fence);
+ mWriter.setError(getCommandLoc(), err);
+ }
+
+ return true;
+}
+
+bool HwcClient::CommandReader::parseSetLayerSurfaceDamage(uint16_t length)
+{
+ // N rectangles
+ if (length % 4 != 0) {
+ return false;
+ }
+
+ auto damage = readRegion(length / 4);
+ auto err = mHal.setLayerSurfaceDamage(mDisplay, mLayer, damage);
+ if (err != Error::NONE) {
+ mWriter.setError(getCommandLoc(), err);
+ }
+
+ return true;
+}
+
+bool HwcClient::CommandReader::parseSetLayerBlendMode(uint16_t length)
+{
+ if (length != CommandWriter::kSetLayerBlendModeLength) {
+ return false;
+ }
+
+ auto err = mHal.setLayerBlendMode(mDisplay, mLayer, readSigned());
+ if (err != Error::NONE) {
+ mWriter.setError(getCommandLoc(), err);
+ }
+
+ return true;
+}
+
+bool HwcClient::CommandReader::parseSetLayerColor(uint16_t length)
+{
+ if (length != CommandWriter::kSetLayerColorLength) {
+ return false;
+ }
+
+ auto err = mHal.setLayerColor(mDisplay, mLayer, readColor());
+ if (err != Error::NONE) {
+ mWriter.setError(getCommandLoc(), err);
+ }
+
+ return true;
+}
+
+bool HwcClient::CommandReader::parseSetLayerCompositionType(uint16_t length)
+{
+ if (length != CommandWriter::kSetLayerCompositionTypeLength) {
+ return false;
+ }
+
+ auto err = mHal.setLayerCompositionType(mDisplay, mLayer, readSigned());
+ if (err != Error::NONE) {
+ mWriter.setError(getCommandLoc(), err);
+ }
+
+ return true;
+}
+
+bool HwcClient::CommandReader::parseSetLayerDataspace(uint16_t length)
+{
+ if (length != CommandWriter::kSetLayerDataspaceLength) {
+ return false;
+ }
+
+ auto err = mHal.setLayerDataspace(mDisplay, mLayer, readSigned());
+ if (err != Error::NONE) {
+ mWriter.setError(getCommandLoc(), err);
+ }
+
+ return true;
+}
+
+bool HwcClient::CommandReader::parseSetLayerDisplayFrame(uint16_t length)
+{
+ if (length != CommandWriter::kSetLayerDisplayFrameLength) {
+ return false;
+ }
+
+ auto err = mHal.setLayerDisplayFrame(mDisplay, mLayer, readRect());
+ if (err != Error::NONE) {
+ mWriter.setError(getCommandLoc(), err);
+ }
+
+ return true;
+}
+
+bool HwcClient::CommandReader::parseSetLayerPlaneAlpha(uint16_t length)
+{
+ if (length != CommandWriter::kSetLayerPlaneAlphaLength) {
+ return false;
+ }
+
+ auto err = mHal.setLayerPlaneAlpha(mDisplay, mLayer, readFloat());
+ if (err != Error::NONE) {
+ mWriter.setError(getCommandLoc(), err);
+ }
+
+ return true;
+}
+
+bool HwcClient::CommandReader::parseSetLayerSidebandStream(uint16_t length)
+{
+ if (length != CommandWriter::kSetLayerSidebandStreamLength) {
+ return false;
+ }
+
+ auto stream = readHandle();
+
+ auto err = lookupLayerSidebandStream(stream);
+ if (err == Error::NONE) {
+ err = mHal.setLayerSidebandStream(mDisplay, mLayer, stream);
+ }
+ if (err != Error::NONE) {
+ mWriter.setError(getCommandLoc(), err);
+ }
+
+ return true;
+}
+
+bool HwcClient::CommandReader::parseSetLayerSourceCrop(uint16_t length)
+{
+ if (length != CommandWriter::kSetLayerSourceCropLength) {
+ return false;
+ }
+
+ auto err = mHal.setLayerSourceCrop(mDisplay, mLayer, readFRect());
+ if (err != Error::NONE) {
+ mWriter.setError(getCommandLoc(), err);
+ }
+
+ return true;
+}
+
+bool HwcClient::CommandReader::parseSetLayerTransform(uint16_t length)
+{
+ if (length != CommandWriter::kSetLayerTransformLength) {
+ return false;
+ }
+
+ auto err = mHal.setLayerTransform(mDisplay, mLayer, readSigned());
+ if (err != Error::NONE) {
+ mWriter.setError(getCommandLoc(), err);
+ }
+
+ return true;
+}
+
+bool HwcClient::CommandReader::parseSetLayerVisibleRegion(uint16_t length)
+{
+ // N rectangles
+ if (length % 4 != 0) {
+ return false;
+ }
+
+ auto region = readRegion(length / 4);
+ auto err = mHal.setLayerVisibleRegion(mDisplay, mLayer, region);
+ if (err != Error::NONE) {
+ mWriter.setError(getCommandLoc(), err);
+ }
+
+ return true;
+}
+
+bool HwcClient::CommandReader::parseSetLayerZOrder(uint16_t length)
+{
+ if (length != CommandWriter::kSetLayerZOrderLength) {
+ return false;
+ }
+
+ auto err = mHal.setLayerZOrder(mDisplay, mLayer, read());
+ if (err != Error::NONE) {
+ mWriter.setError(getCommandLoc(), err);
+ }
+
+ return true;
+}
+
+hwc_rect_t HwcClient::CommandReader::readRect()
+{
+ return hwc_rect_t{
+ readSigned(),
+ readSigned(),
+ readSigned(),
+ readSigned(),
+ };
+}
+
+std::vector<hwc_rect_t> HwcClient::CommandReader::readRegion(size_t count)
+{
+ std::vector<hwc_rect_t> region;
+ region.reserve(count);
+ while (count > 0) {
+ region.emplace_back(readRect());
+ count--;
+ }
+
+ return region;
+}
+
+hwc_frect_t HwcClient::CommandReader::readFRect()
+{
+ return hwc_frect_t{
+ readFloat(),
+ readFloat(),
+ readFloat(),
+ readFloat(),
+ };
+}
+
+Error HwcClient::CommandReader::lookupBuffer(BufferCache cache, uint32_t slot,
+ bool useCache, buffer_handle_t& handle)
+{
+ std::lock_guard<std::mutex> lock(mClient.mDisplayDataMutex);
+
+ auto dpy = mClient.mDisplayData.find(mDisplay);
+ if (dpy == mClient.mDisplayData.end()) {
+ return Error::BAD_DISPLAY;
+ }
+
+ BufferClone* clone = nullptr;
+ switch (cache) {
+ case BufferCache::CLIENT_TARGETS:
+ if (slot < dpy->second.ClientTargets.size()) {
+ clone = &dpy->second.ClientTargets[slot];
+ }
+ break;
+ case BufferCache::OUTPUT_BUFFERS:
+ if (slot < dpy->second.OutputBuffers.size()) {
+ clone = &dpy->second.OutputBuffers[slot];
+ }
+ break;
+ case BufferCache::LAYER_BUFFERS:
+ {
+ auto ly = dpy->second.Layers.find(mLayer);
+ if (ly == dpy->second.Layers.end()) {
+ return Error::BAD_LAYER;
+ }
+ if (slot < ly->second.Buffers.size()) {
+ clone = &ly->second.Buffers[slot];
+ }
+ }
+ break;
+ case BufferCache::LAYER_SIDEBAND_STREAMS:
+ {
+ auto ly = dpy->second.Layers.find(mLayer);
+ if (ly == dpy->second.Layers.end()) {
+ return Error::BAD_LAYER;
+ }
+ if (slot == 0) {
+ clone = &ly->second.SidebandStream;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (!clone) {
+ ALOGW("invalid buffer slot");
+ return Error::BAD_PARAMETER;
+ }
+
+ // use or update cache
+ if (useCache) {
+ handle = *clone;
+ } else {
+ if (!sHandleImporter.importBuffer(handle)) {
+ return Error::NO_RESOURCES;
+ }
+
+ *clone = handle;
+ }
+
+ return Error::NONE;
+}
+
+} // namespace implementation
+} // namespace V2_1
+} // namespace composer
+} // namespace graphics
+} // namespace hardware
+} // namespace android
diff --git a/graphics/composer/2.1/default/HwcClient.h b/graphics/composer/2.1/default/HwcClient.h
new file mode 100644
index 0000000..a9bc4cd
--- /dev/null
+++ b/graphics/composer/2.1/default/HwcClient.h
@@ -0,0 +1,202 @@
+/*
+ * 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 ANDROID_HARDWARE_GRAPHICS_COMPOSER_V2_1_HWC_CLIENT_H
+#define ANDROID_HARDWARE_GRAPHICS_COMPOSER_V2_1_HWC_CLIENT_H
+
+#include <mutex>
+#include <unordered_map>
+#include <vector>
+
+#include "Hwc.h"
+#include "IComposerCommandBuffer.h"
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace composer {
+namespace V2_1 {
+namespace implementation {
+
+class BufferClone {
+public:
+ BufferClone();
+ BufferClone(BufferClone&& other);
+
+ BufferClone(const BufferClone& other) = delete;
+ BufferClone& operator=(const BufferClone& other) = delete;
+
+ BufferClone& operator=(buffer_handle_t handle);
+ ~BufferClone();
+
+ operator buffer_handle_t() const { return mHandle; }
+
+private:
+ void clear();
+
+ buffer_handle_t mHandle;
+};
+
+class HwcClient : public IComposerClient {
+public:
+ HwcClient(HwcHal& hal);
+ virtual ~HwcClient();
+
+ void onHotplug(Display display, IComposerCallback::Connection connected);
+ void onRefresh(Display display);
+ void onVsync(Display display, int64_t timestamp);
+
+ // IComposerClient interface
+ Return<void> registerCallback(
+ const sp<IComposerCallback>& callback) override;
+ Return<uint32_t> getMaxVirtualDisplayCount() override;
+ Return<void> createVirtualDisplay(uint32_t width, uint32_t height,
+ PixelFormat formatHint, uint32_t outputBufferSlotCount,
+ createVirtualDisplay_cb hidl_cb) override;
+ Return<Error> destroyVirtualDisplay(Display display) override;
+ Return<void> createLayer(Display display, uint32_t bufferSlotCount,
+ createLayer_cb hidl_cb) override;
+ Return<Error> destroyLayer(Display display, Layer layer) override;
+ Return<void> getActiveConfig(Display display,
+ getActiveConfig_cb hidl_cb) override;
+ Return<Error> getClientTargetSupport(Display display,
+ uint32_t width, uint32_t height,
+ PixelFormat format, Dataspace dataspace) override;
+ Return<void> getColorModes(Display display,
+ getColorModes_cb hidl_cb) override;
+ Return<void> getDisplayAttribute(Display display,
+ Config config, Attribute attribute,
+ getDisplayAttribute_cb hidl_cb) override;
+ Return<void> getDisplayConfigs(Display display,
+ getDisplayConfigs_cb hidl_cb) override;
+ Return<void> getDisplayName(Display display,
+ getDisplayName_cb hidl_cb) override;
+ Return<void> getDisplayType(Display display,
+ getDisplayType_cb hidl_cb) override;
+ Return<void> getDozeSupport(Display display,
+ getDozeSupport_cb hidl_cb) override;
+ Return<void> getHdrCapabilities(Display display,
+ getHdrCapabilities_cb hidl_cb) override;
+ Return<Error> setActiveConfig(Display display, Config config) override;
+ Return<Error> setColorMode(Display display, ColorMode mode) override;
+ Return<Error> setPowerMode(Display display, PowerMode mode) override;
+ Return<Error> setVsyncEnabled(Display display, Vsync enabled) override;
+ Return<Error> setClientTargetSlotCount(Display display,
+ uint32_t clientTargetSlotCount) override;
+ Return<Error> setInputCommandQueue(
+ const MQDescriptorSync& descriptor) override;
+ Return<void> getOutputCommandQueue(
+ getOutputCommandQueue_cb hidl_cb) override;
+ Return<void> executeCommands(uint32_t inLength,
+ const hidl_vec<hidl_handle>& inHandles,
+ executeCommands_cb hidl_cb) override;
+
+private:
+ struct LayerBuffers {
+ std::vector<BufferClone> Buffers;
+ BufferClone SidebandStream;
+ };
+
+ struct DisplayData {
+ bool IsVirtual;
+
+ std::vector<BufferClone> ClientTargets;
+ std::vector<BufferClone> OutputBuffers;
+
+ std::unordered_map<Layer, LayerBuffers> Layers;
+
+ DisplayData(bool isVirtual) : IsVirtual(isVirtual) {}
+ };
+
+ class CommandReader : public CommandReaderBase {
+ public:
+ CommandReader(HwcClient& client);
+ Error parse();
+
+ private:
+ bool parseSelectDisplay(uint16_t length);
+ bool parseSelectLayer(uint16_t length);
+ bool parseSetColorTransform(uint16_t length);
+ bool parseSetClientTarget(uint16_t length);
+ bool parseSetOutputBuffer(uint16_t length);
+ bool parseValidateDisplay(uint16_t length);
+ bool parseAcceptDisplayChanges(uint16_t length);
+ bool parsePresentDisplay(uint16_t length);
+ bool parseSetLayerCursorPosition(uint16_t length);
+ bool parseSetLayerBuffer(uint16_t length);
+ bool parseSetLayerSurfaceDamage(uint16_t length);
+ bool parseSetLayerBlendMode(uint16_t length);
+ bool parseSetLayerColor(uint16_t length);
+ bool parseSetLayerCompositionType(uint16_t length);
+ bool parseSetLayerDataspace(uint16_t length);
+ bool parseSetLayerDisplayFrame(uint16_t length);
+ bool parseSetLayerPlaneAlpha(uint16_t length);
+ bool parseSetLayerSidebandStream(uint16_t length);
+ bool parseSetLayerSourceCrop(uint16_t length);
+ bool parseSetLayerTransform(uint16_t length);
+ bool parseSetLayerVisibleRegion(uint16_t length);
+ bool parseSetLayerZOrder(uint16_t length);
+
+ hwc_rect_t readRect();
+ std::vector<hwc_rect_t> readRegion(size_t count);
+ hwc_frect_t readFRect();
+
+ enum class BufferCache {
+ CLIENT_TARGETS,
+ OUTPUT_BUFFERS,
+ LAYER_BUFFERS,
+ LAYER_SIDEBAND_STREAMS,
+ };
+ Error lookupBuffer(BufferCache cache, uint32_t slot,
+ bool useCache, buffer_handle_t& handle);
+
+ Error lookupLayerSidebandStream(buffer_handle_t& handle)
+ {
+ return lookupBuffer(BufferCache::LAYER_SIDEBAND_STREAMS,
+ 0, false, handle);
+ }
+
+ HwcClient& mClient;
+ HwcHal& mHal;
+ CommandWriter& mWriter;
+
+ Display mDisplay;
+ Layer mLayer;
+ };
+
+ HwcHal& mHal;
+
+ // 64KiB minus a small space for metadata such as read/write pointers
+ static constexpr size_t kWriterInitialSize =
+ 64 * 1024 / sizeof(uint32_t) - 16;
+ std::mutex mCommandMutex;
+ CommandReader mReader;
+ CommandWriter mWriter;
+
+ sp<IComposerCallback> mCallback;
+
+ std::mutex mDisplayDataMutex;
+ std::unordered_map<Display, DisplayData> mDisplayData;
+};
+
+} // namespace implementation
+} // namespace V2_1
+} // namespace composer
+} // namespace graphics
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GRAPHICS_COMPOSER_V2_1_HWC_CLIENT_H
diff --git a/graphics/composer/2.1/default/IComposerCommandBuffer.h b/graphics/composer/2.1/default/IComposerCommandBuffer.h
new file mode 100644
index 0000000..8f133fe
--- /dev/null
+++ b/graphics/composer/2.1/default/IComposerCommandBuffer.h
@@ -0,0 +1,850 @@
+/*
+ * 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 ANDROID_HARDWARE_GRAPHICS_COMPOSER_COMMAND_BUFFER_H
+#define ANDROID_HARDWARE_GRAPHICS_COMPOSER_COMMAND_BUFFER_H
+
+#ifndef LOG_TAG
+#warn "IComposerCommandBuffer.h included without LOG_TAG"
+#endif
+
+#undef LOG_NDEBUG
+#define LOG_NDEBUG 0
+
+#include <algorithm>
+#include <limits>
+#include <memory>
+#include <vector>
+
+#include <inttypes.h>
+#include <string.h>
+
+#include <android/hardware/graphics/composer/2.1/IComposer.h>
+#include <log/log.h>
+#include <sync/sync.h>
+#include <fmq/MessageQueue.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace composer {
+namespace V2_1 {
+
+using android::hardware::graphics::common::V1_0::ColorTransform;
+using android::hardware::graphics::common::V1_0::Dataspace;
+using android::hardware::graphics::common::V1_0::Transform;
+using android::hardware::MessageQueue;
+
+using CommandQueueType = MessageQueue<uint32_t, kSynchronizedReadWrite>;
+
+// This class helps build a command queue. Note that all sizes/lengths are in
+// units of uint32_t's.
+class CommandWriter {
+public:
+ CommandWriter(uint32_t initialMaxSize)
+ : mDataMaxSize(initialMaxSize)
+ {
+ mData = std::make_unique<uint32_t[]>(mDataMaxSize);
+ reset();
+ }
+
+ ~CommandWriter()
+ {
+ reset();
+ }
+
+ void reset()
+ {
+ mDataWritten = 0;
+ mCommandEnd = 0;
+
+ // handles in mDataHandles are owned by the caller
+ mDataHandles.clear();
+
+ // handles in mTemporaryHandles are owned by the writer
+ for (auto handle : mTemporaryHandles) {
+ native_handle_close(handle);
+ native_handle_delete(handle);
+ }
+ mTemporaryHandles.clear();
+ }
+
+ IComposerClient::Command getCommand(uint32_t offset)
+ {
+ uint32_t val = (offset < mDataWritten) ? mData[offset] : 0;
+ return static_cast<IComposerClient::Command>(val &
+ static_cast<uint32_t>(IComposerClient::Command::OPCODE_MASK));
+ }
+
+ bool writeQueue(bool* outQueueChanged, uint32_t* outCommandLength,
+ hidl_vec<hidl_handle>* outCommandHandles)
+ {
+ // write data to queue, optionally resizing it
+ if (mQueue && (mDataMaxSize <= mQueue->getQuantumCount())) {
+ if (!mQueue->write(mData.get(), mDataWritten)) {
+ ALOGE("failed to write commands to message queue");
+ return false;
+ }
+
+ *outQueueChanged = false;
+ } else {
+ auto newQueue = std::make_unique<CommandQueueType>(mDataMaxSize);
+ if (!newQueue->isValid() ||
+ !newQueue->write(mData.get(), mDataWritten)) {
+ ALOGE("failed to prepare a new message queue ");
+ return false;
+ }
+
+ mQueue = std::move(newQueue);
+ *outQueueChanged = true;
+ }
+
+ *outCommandLength = mDataWritten;
+ outCommandHandles->setToExternal(
+ const_cast<hidl_handle*>(mDataHandles.data()),
+ mDataHandles.size());
+
+ return true;
+ }
+
+ const MQDescriptorSync* getMQDescriptor() const
+ {
+ return (mQueue) ? mQueue->getDesc() : nullptr;
+ }
+
+ static constexpr uint16_t kSelectDisplayLength = 2;
+ void selectDisplay(Display display)
+ {
+ beginCommand(IComposerClient::Command::SELECT_DISPLAY,
+ kSelectDisplayLength);
+ write64(display);
+ endCommand();
+ }
+
+ static constexpr uint16_t kSelectLayerLength = 2;
+ void selectLayer(Layer layer)
+ {
+ beginCommand(IComposerClient::Command::SELECT_LAYER,
+ kSelectLayerLength);
+ write64(layer);
+ endCommand();
+ }
+
+ static constexpr uint16_t kSetErrorLength = 2;
+ void setError(uint32_t location, Error error)
+ {
+ beginCommand(IComposerClient::Command::SET_ERROR, kSetErrorLength);
+ write(location);
+ writeSigned(static_cast<int32_t>(error));
+ endCommand();
+ }
+
+ void setChangedCompositionTypes(const std::vector<Layer>& layers,
+ const std::vector<IComposerClient::Composition>& types)
+ {
+ size_t totalLayers = std::min(layers.size(), types.size());
+ size_t currentLayer = 0;
+
+ while (currentLayer < totalLayers) {
+ size_t count = std::min(totalLayers - currentLayer,
+ static_cast<size_t>(kMaxLength) / 3);
+
+ beginCommand(
+ IComposerClient::Command::SET_CHANGED_COMPOSITION_TYPES,
+ count * 3);
+ for (size_t i = 0; i < count; i++) {
+ write64(layers[currentLayer + i]);
+ writeSigned(static_cast<int32_t>(types[currentLayer + i]));
+ }
+ endCommand();
+
+ currentLayer += count;
+ }
+ }
+
+ void setDisplayRequests(uint32_t displayRequestMask,
+ const std::vector<Layer>& layers,
+ const std::vector<uint32_t>& layerRequestMasks)
+ {
+ size_t totalLayers = std::min(layers.size(),
+ layerRequestMasks.size());
+ size_t currentLayer = 0;
+
+ while (currentLayer < totalLayers) {
+ size_t count = std::min(totalLayers - currentLayer,
+ static_cast<size_t>(kMaxLength - 1) / 3);
+
+ beginCommand(IComposerClient::Command::SET_DISPLAY_REQUESTS,
+ 1 + count * 3);
+ write(displayRequestMask);
+ for (size_t i = 0; i < count; i++) {
+ write64(layers[currentLayer + i]);
+ write(static_cast<int32_t>(layerRequestMasks[currentLayer + i]));
+ }
+ endCommand();
+
+ currentLayer += count;
+ }
+ }
+
+ static constexpr uint16_t kSetPresentFenceLength = 1;
+ void setPresentFence(int presentFence)
+ {
+ beginCommand(IComposerClient::Command::SET_PRESENT_FENCE,
+ kSetPresentFenceLength);
+ writeFence(presentFence);
+ endCommand();
+ }
+
+ void setReleaseFences(const std::vector<Layer>& layers,
+ const std::vector<int>& releaseFences)
+ {
+ size_t totalLayers = std::min(layers.size(), releaseFences.size());
+ size_t currentLayer = 0;
+
+ while (currentLayer < totalLayers) {
+ size_t count = std::min(totalLayers - currentLayer,
+ static_cast<size_t>(kMaxLength) / 3);
+
+ beginCommand(IComposerClient::Command::SET_RELEASE_FENCES,
+ count * 3);
+ for (size_t i = 0; i < count; i++) {
+ write64(layers[currentLayer + i]);
+ writeFence(releaseFences[currentLayer + i]);
+ }
+ endCommand();
+
+ currentLayer += count;
+ }
+ }
+
+ static constexpr uint16_t kSetColorTransformLength = 17;
+ void setColorTransform(const float* matrix, ColorTransform hint)
+ {
+ beginCommand(IComposerClient::Command::SET_COLOR_TRANSFORM,
+ kSetColorTransformLength);
+ for (int i = 0; i < 16; i++) {
+ writeFloat(matrix[i]);
+ }
+ writeSigned(static_cast<int32_t>(hint));
+ endCommand();
+ }
+
+ void setClientTarget(uint32_t slot, const native_handle_t* target,
+ int acquireFence, Dataspace dataspace,
+ const std::vector<IComposerClient::Rect>& damage)
+ {
+ bool doWrite = (damage.size() <= (kMaxLength - 4) / 4);
+ size_t length = 4 + ((doWrite) ? damage.size() * 4 : 0);
+
+ beginCommand(IComposerClient::Command::SET_CLIENT_TARGET, length);
+ write(slot);
+ writeHandle(target, true);
+ writeFence(acquireFence);
+ writeSigned(static_cast<int32_t>(dataspace));
+ // When there are too many rectangles in the damage region and doWrite
+ // is false, we write no rectangle at all which means the entire
+ // client target is damaged.
+ if (doWrite) {
+ writeRegion(damage);
+ }
+ endCommand();
+ }
+
+ static constexpr uint16_t kSetOutputBufferLength = 3;
+ void setOutputBuffer(uint32_t slot, const native_handle_t* buffer,
+ int releaseFence)
+ {
+ beginCommand(IComposerClient::Command::SET_OUTPUT_BUFFER,
+ kSetOutputBufferLength);
+ write(slot);
+ writeHandle(buffer, true);
+ writeFence(releaseFence);
+ endCommand();
+ }
+
+ static constexpr uint16_t kValidateDisplayLength = 0;
+ void validateDisplay()
+ {
+ beginCommand(IComposerClient::Command::VALIDATE_DISPLAY,
+ kValidateDisplayLength);
+ endCommand();
+ }
+
+ static constexpr uint16_t kAcceptDisplayChangesLength = 0;
+ void acceptDisplayChanges()
+ {
+ beginCommand(IComposerClient::Command::ACCEPT_DISPLAY_CHANGES,
+ kAcceptDisplayChangesLength);
+ endCommand();
+ }
+
+ static constexpr uint16_t kPresentDisplayLength = 0;
+ void presentDisplay()
+ {
+ beginCommand(IComposerClient::Command::PRESENT_DISPLAY,
+ kPresentDisplayLength);
+ endCommand();
+ }
+
+ static constexpr uint16_t kSetLayerCursorPositionLength = 2;
+ void setLayerCursorPosition(int32_t x, int32_t y)
+ {
+ beginCommand(IComposerClient::Command::SET_LAYER_CURSOR_POSITION,
+ kSetLayerCursorPositionLength);
+ writeSigned(x);
+ writeSigned(y);
+ endCommand();
+ }
+
+ static constexpr uint16_t kSetLayerBufferLength = 3;
+ void setLayerBuffer(uint32_t slot, const native_handle_t* buffer,
+ int acquireFence)
+ {
+ beginCommand(IComposerClient::Command::SET_LAYER_BUFFER,
+ kSetLayerBufferLength);
+ write(slot);
+ writeHandle(buffer, true);
+ writeFence(acquireFence);
+ endCommand();
+ }
+
+ void setLayerSurfaceDamage(
+ const std::vector<IComposerClient::Rect>& damage)
+ {
+ bool doWrite = (damage.size() <= kMaxLength / 4);
+ size_t length = (doWrite) ? damage.size() * 4 : 0;
+
+ beginCommand(IComposerClient::Command::SET_LAYER_SURFACE_DAMAGE,
+ length);
+ // When there are too many rectangles in the damage region and doWrite
+ // is false, we write no rectangle at all which means the entire
+ // layer is damaged.
+ if (doWrite) {
+ writeRegion(damage);
+ }
+ endCommand();
+ }
+
+ static constexpr uint16_t kSetLayerBlendModeLength = 1;
+ void setLayerBlendMode(IComposerClient::BlendMode mode)
+ {
+ beginCommand(IComposerClient::Command::SET_LAYER_BLEND_MODE,
+ kSetLayerBlendModeLength);
+ writeSigned(static_cast<int32_t>(mode));
+ endCommand();
+ }
+
+ static constexpr uint16_t kSetLayerColorLength = 1;
+ void setLayerColor(IComposerClient::Color color)
+ {
+ beginCommand(IComposerClient::Command::SET_LAYER_COLOR,
+ kSetLayerColorLength);
+ writeColor(color);
+ endCommand();
+ }
+
+ static constexpr uint16_t kSetLayerCompositionTypeLength = 1;
+ void setLayerCompositionType(IComposerClient::Composition type)
+ {
+ beginCommand(IComposerClient::Command::SET_LAYER_COMPOSITION_TYPE,
+ kSetLayerCompositionTypeLength);
+ writeSigned(static_cast<int32_t>(type));
+ endCommand();
+ }
+
+ static constexpr uint16_t kSetLayerDataspaceLength = 1;
+ void setLayerDataspace(Dataspace dataspace)
+ {
+ beginCommand(IComposerClient::Command::SET_LAYER_DATASPACE,
+ kSetLayerDataspaceLength);
+ writeSigned(static_cast<int32_t>(dataspace));
+ endCommand();
+ }
+
+ static constexpr uint16_t kSetLayerDisplayFrameLength = 4;
+ void setLayerDisplayFrame(const IComposerClient::Rect& frame)
+ {
+ beginCommand(IComposerClient::Command::SET_LAYER_DISPLAY_FRAME,
+ kSetLayerDisplayFrameLength);
+ writeRect(frame);
+ endCommand();
+ }
+
+ static constexpr uint16_t kSetLayerPlaneAlphaLength = 1;
+ void setLayerPlaneAlpha(float alpha)
+ {
+ beginCommand(IComposerClient::Command::SET_LAYER_PLANE_ALPHA,
+ kSetLayerPlaneAlphaLength);
+ writeFloat(alpha);
+ endCommand();
+ }
+
+ static constexpr uint16_t kSetLayerSidebandStreamLength = 1;
+ void setLayerSidebandStream(const native_handle_t* stream)
+ {
+ beginCommand(IComposerClient::Command::SET_LAYER_SIDEBAND_STREAM,
+ kSetLayerSidebandStreamLength);
+ writeHandle(stream);
+ endCommand();
+ }
+
+ static constexpr uint16_t kSetLayerSourceCropLength = 4;
+ void setLayerSourceCrop(const IComposerClient::FRect& crop)
+ {
+ beginCommand(IComposerClient::Command::SET_LAYER_SOURCE_CROP,
+ kSetLayerSourceCropLength);
+ writeFRect(crop);
+ endCommand();
+ }
+
+ static constexpr uint16_t kSetLayerTransformLength = 1;
+ void setLayerTransform(Transform transform)
+ {
+ beginCommand(IComposerClient::Command::SET_LAYER_TRANSFORM,
+ kSetLayerTransformLength);
+ writeSigned(static_cast<int32_t>(transform));
+ endCommand();
+ }
+
+ void setLayerVisibleRegion(
+ const std::vector<IComposerClient::Rect>& visible)
+ {
+ bool doWrite = (visible.size() <= kMaxLength / 4);
+ size_t length = (doWrite) ? visible.size() * 4 : 0;
+
+ beginCommand(IComposerClient::Command::SET_LAYER_VISIBLE_REGION,
+ length);
+ // When there are too many rectangles in the visible region and
+ // doWrite is false, we write no rectangle at all which means the
+ // entire layer is visible.
+ if (doWrite) {
+ writeRegion(visible);
+ }
+ endCommand();
+ }
+
+ static constexpr uint16_t kSetLayerZOrderLength = 1;
+ void setLayerZOrder(uint32_t z)
+ {
+ beginCommand(IComposerClient::Command::SET_LAYER_Z_ORDER,
+ kSetLayerZOrderLength);
+ write(z);
+ endCommand();
+ }
+
+protected:
+ void beginCommand(IComposerClient::Command command, uint16_t length)
+ {
+ if (mCommandEnd) {
+ LOG_FATAL("endCommand was not called before command 0x%x",
+ command);
+ }
+
+ growData(1 + length);
+ write(static_cast<uint32_t>(command) | length);
+
+ mCommandEnd = mDataWritten + length;
+ }
+
+ void endCommand()
+ {
+ if (!mCommandEnd) {
+ LOG_FATAL("beginCommand was not called");
+ } else if (mDataWritten > mCommandEnd) {
+ LOG_FATAL("too much data written");
+ mDataWritten = mCommandEnd;
+ } else if (mDataWritten < mCommandEnd) {
+ LOG_FATAL("too little data written");
+ while (mDataWritten < mCommandEnd) {
+ write(0);
+ }
+ }
+
+ mCommandEnd = 0;
+ }
+
+ void write(uint32_t val)
+ {
+ mData[mDataWritten++] = val;
+ }
+
+ void writeSigned(int32_t val)
+ {
+ memcpy(&mData[mDataWritten++], &val, sizeof(val));
+ }
+
+ void writeFloat(float val)
+ {
+ memcpy(&mData[mDataWritten++], &val, sizeof(val));
+ }
+
+ void write64(uint64_t val)
+ {
+ uint32_t lo = static_cast<uint32_t>(val & 0xffffffff);
+ uint32_t hi = static_cast<uint32_t>(val >> 32);
+ write(lo);
+ write(hi);
+ }
+
+ void writeRect(const IComposerClient::Rect& rect)
+ {
+ writeSigned(rect.left);
+ writeSigned(rect.top);
+ writeSigned(rect.right);
+ writeSigned(rect.bottom);
+ }
+
+ void writeRegion(const std::vector<IComposerClient::Rect>& region)
+ {
+ for (const auto& rect : region) {
+ writeRect(rect);
+ }
+ }
+
+ void writeFRect(const IComposerClient::FRect& rect)
+ {
+ writeFloat(rect.left);
+ writeFloat(rect.top);
+ writeFloat(rect.right);
+ writeFloat(rect.bottom);
+ }
+
+ void writeColor(const IComposerClient::Color& color)
+ {
+ write((color.r << 0) |
+ (color.g << 8) |
+ (color.b << 16) |
+ (color.a << 24));
+ }
+
+ // ownership of handle is not transferred
+ void writeHandle(const native_handle_t* handle, bool useCache)
+ {
+ if (!handle) {
+ writeSigned(static_cast<int32_t>((useCache) ?
+ IComposerClient::HandleIndex::CACHED :
+ IComposerClient::HandleIndex::EMPTY));
+ return;
+ }
+
+ mDataHandles.push_back(handle);
+ writeSigned(mDataHandles.size() - 1);
+ }
+
+ void writeHandle(const native_handle_t* handle)
+ {
+ writeHandle(handle, false);
+ }
+
+ // ownership of fence is transferred
+ void writeFence(int fence)
+ {
+ native_handle_t* handle = nullptr;
+ if (fence >= 0) {
+ handle = getTemporaryHandle(1, 0);
+ if (handle) {
+ handle->data[0] = fence;
+ } else {
+ ALOGW("failed to get temporary handle for fence %d", fence);
+ sync_wait(fence, -1);
+ close(fence);
+ }
+ }
+
+ writeHandle(handle);
+ }
+
+ native_handle_t* getTemporaryHandle(int numFds, int numInts)
+ {
+ native_handle_t* handle = native_handle_create(numFds, numInts);
+ if (handle) {
+ mTemporaryHandles.push_back(handle);
+ }
+ return handle;
+ }
+
+ static constexpr uint16_t kMaxLength =
+ std::numeric_limits<uint16_t>::max();
+
+private:
+ void growData(uint32_t grow)
+ {
+ uint32_t newWritten = mDataWritten + grow;
+ if (newWritten < mDataWritten) {
+ LOG_ALWAYS_FATAL("buffer overflowed; data written %" PRIu32
+ ", growing by %" PRIu32, mDataWritten, grow);
+ }
+
+ if (newWritten <= mDataMaxSize) {
+ return;
+ }
+
+ uint32_t newMaxSize = mDataMaxSize << 1;
+ if (newMaxSize < newWritten) {
+ newMaxSize = newWritten;
+ }
+
+ auto newData = std::make_unique<uint32_t[]>(newMaxSize);
+ std::copy_n(mData.get(), mDataWritten, newData.get());
+ mDataMaxSize = newMaxSize;
+ mData = std::move(newData);
+ }
+
+ uint32_t mDataMaxSize;
+ std::unique_ptr<uint32_t[]> mData;
+
+ uint32_t mDataWritten;
+ // end offset of the current command
+ uint32_t mCommandEnd;
+
+ std::vector<hidl_handle> mDataHandles;
+ std::vector<native_handle_t *> mTemporaryHandles;
+
+ std::unique_ptr<CommandQueueType> mQueue;
+};
+
+// This class helps parse a command queue. Note that all sizes/lengths are in
+// units of uint32_t's.
+class CommandReaderBase {
+public:
+ CommandReaderBase() : mDataMaxSize(0)
+ {
+ reset();
+ }
+
+ bool setMQDescriptor(const MQDescriptorSync& descriptor)
+ {
+ mQueue = std::make_unique<CommandQueueType>(descriptor, false);
+ if (mQueue->isValid()) {
+ return true;
+ } else {
+ mQueue = nullptr;
+ return false;
+ }
+ }
+
+ bool readQueue(uint32_t commandLength,
+ const hidl_vec<hidl_handle>& commandHandles)
+ {
+ if (!mQueue) {
+ return false;
+ }
+
+ auto quantumCount = mQueue->getQuantumCount();
+ if (mDataMaxSize < quantumCount) {
+ mDataMaxSize = quantumCount;
+ mData = std::make_unique<uint32_t[]>(mDataMaxSize);
+ }
+
+ if (commandLength > mDataMaxSize ||
+ !mQueue->read(mData.get(), commandLength)) {
+ ALOGE("failed to read commands from message queue");
+ return false;
+ }
+
+ mDataSize = commandLength;
+ mDataRead = 0;
+ mCommandBegin = 0;
+ mCommandEnd = 0;
+ mDataHandles.setToExternal(
+ const_cast<hidl_handle*>(commandHandles.data()),
+ commandHandles.size());
+
+ return true;
+ }
+
+ void reset()
+ {
+ mDataSize = 0;
+ mDataRead = 0;
+ mCommandBegin = 0;
+ mCommandEnd = 0;
+ mDataHandles.setToExternal(nullptr, 0);
+ }
+
+protected:
+ bool isEmpty() const
+ {
+ return (mDataRead >= mDataSize);
+ }
+
+ bool beginCommand(IComposerClient::Command* outCommand,
+ uint16_t* outLength)
+ {
+ if (mCommandEnd) {
+ LOG_FATAL("endCommand was not called before command 0x%x",
+ command);
+ }
+
+ constexpr uint32_t opcode_mask =
+ static_cast<uint32_t>(IComposerClient::Command::OPCODE_MASK);
+ constexpr uint32_t length_mask =
+ static_cast<uint32_t>(IComposerClient::Command::LENGTH_MASK);
+
+ uint32_t val = read();
+ *outCommand = static_cast<IComposerClient::Command>(
+ val & opcode_mask);
+ *outLength = static_cast<uint16_t>(val & length_mask);
+
+ if (mDataRead + *outLength > mDataSize) {
+ ALOGE("command 0x%x has invalid command length %" PRIu16,
+ *outCommand, *outLength);
+ // undo the read() above
+ mDataRead--;
+ return false;
+ }
+
+ mCommandEnd = mDataRead + *outLength;
+
+ return true;
+ }
+
+ void endCommand()
+ {
+ if (!mCommandEnd) {
+ LOG_FATAL("beginCommand was not called");
+ } else if (mDataRead > mCommandEnd) {
+ LOG_FATAL("too much data read");
+ mDataRead = mCommandEnd;
+ } else if (mDataRead < mCommandEnd) {
+ LOG_FATAL("too little data read");
+ mDataRead = mCommandEnd;
+ }
+
+ mCommandBegin = mCommandEnd;
+ mCommandEnd = 0;
+ }
+
+ uint32_t getCommandLoc() const
+ {
+ return mCommandBegin;
+ }
+
+ uint32_t read()
+ {
+ return mData[mDataRead++];
+ }
+
+ int32_t readSigned()
+ {
+ int32_t val;
+ memcpy(&val, &mData[mDataRead++], sizeof(val));
+ return val;
+ }
+
+ float readFloat()
+ {
+ float val;
+ memcpy(&val, &mData[mDataRead++], sizeof(val));
+ return val;
+ }
+
+ uint64_t read64()
+ {
+ uint32_t lo = read();
+ uint32_t hi = read();
+ return (static_cast<uint64_t>(hi) << 32) | lo;
+ }
+
+ IComposerClient::Color readColor()
+ {
+ uint32_t val = read();
+ return IComposerClient::Color{
+ static_cast<uint8_t>((val >> 0) & 0xff),
+ static_cast<uint8_t>((val >> 8) & 0xff),
+ static_cast<uint8_t>((val >> 16) & 0xff),
+ static_cast<uint8_t>((val >> 24) & 0xff),
+ };
+ }
+
+ // ownership of handle is not transferred
+ const native_handle_t* readHandle(bool* outUseCache)
+ {
+ const native_handle_t* handle = nullptr;
+
+ int32_t index = readSigned();
+ switch (index) {
+ case static_cast<int32_t>(IComposerClient::HandleIndex::EMPTY):
+ *outUseCache = false;
+ break;
+ case static_cast<int32_t>(IComposerClient::HandleIndex::CACHED):
+ *outUseCache = true;
+ break;
+ default:
+ if (static_cast<size_t>(index) < mDataHandles.size()) {
+ handle = mDataHandles[index].getNativeHandle();
+ } else {
+ ALOGE("invalid handle index %zu", static_cast<size_t>(index));
+ }
+ *outUseCache = false;
+ break;
+ }
+
+ return handle;
+ }
+
+ const native_handle_t* readHandle()
+ {
+ bool useCache;
+ return readHandle(&useCache);
+ }
+
+ // ownership of fence is transferred
+ int readFence()
+ {
+ auto handle = readHandle();
+ if (!handle || handle->numFds == 0) {
+ return -1;
+ }
+
+ if (handle->numFds != 1) {
+ ALOGE("invalid fence handle with %d fds", handle->numFds);
+ return -1;
+ }
+
+ int fd = dup(handle->data[0]);
+ if (fd < 0) {
+ ALOGW("failed to dup fence %d", handle->data[0]);
+ sync_wait(handle->data[0], -1);
+ fd = -1;
+ }
+
+ return fd;
+ }
+
+private:
+ std::unique_ptr<CommandQueueType> mQueue;
+ uint32_t mDataMaxSize;
+ std::unique_ptr<uint32_t[]> mData;
+
+ uint32_t mDataSize;
+ uint32_t mDataRead;
+
+ // begin/end offsets of the current command
+ uint32_t mCommandBegin;
+ uint32_t mCommandEnd;
+
+ hidl_vec<hidl_handle> mDataHandles;
+};
+
+} // namespace V2_1
+} // namespace composer
+} // namespace graphics
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GRAPHICS_COMPOSER_COMMAND_BUFFER_H
diff --git a/graphics/composer/2.1/types.hal b/graphics/composer/2.1/types.hal
index 9c2e1d7..e54031e 100644
--- a/graphics/composer/2.1/types.hal
+++ b/graphics/composer/2.1/types.hal
@@ -23,7 +23,7 @@
BAD_DISPLAY = 2, /* invalid Display */
BAD_LAYER = 3, /* invalid Layer */
BAD_PARAMETER = 4, /* invalid width, height, etc. */
- HAS_CHANGES = 5,
+ /* 5 is reserved */
NO_RESOURCES = 6, /* temporary failure due to resource contention */
NOT_VALIDATED = 7, /* validateDisplay has not been called */
UNSUPPORTED = 8, /* permanent failure */
diff --git a/graphics/mapper/2.0/Android.bp b/graphics/mapper/2.0/Android.bp
index 19b1388..9ac6d50 100644
--- a/graphics/mapper/2.0/Android.bp
+++ b/graphics/mapper/2.0/Android.bp
@@ -1,4 +1,60 @@
-cc_library_static {
+// This file is autogenerated by hidl-gen. Do not edit manually.
+
+genrule {
+ name: "android.hardware.graphics.mapper@2.0_genc++",
+ tools: ["hidl-gen"],
+ cmd: "$(location hidl-gen) -o $(genDir) -Lc++ -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.graphics.mapper@2.0",
+ srcs: [
+ "types.hal",
+ "IMapper.hal",
+ ],
+ out: [
+ "android/hardware/graphics/mapper/2.0/types.cpp",
+ "android/hardware/graphics/mapper/2.0/MapperAll.cpp",
+ ],
+}
+
+genrule {
+ name: "android.hardware.graphics.mapper@2.0_genc++_headers",
+ tools: ["hidl-gen"],
+ cmd: "$(location hidl-gen) -o $(genDir) -Lc++ -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.graphics.mapper@2.0",
+ srcs: [
+ "types.hal",
+ "IMapper.hal",
+ ],
+ out: [
+ "android/hardware/graphics/mapper/2.0/types.h",
+ "android/hardware/graphics/mapper/2.0/IMapper.h",
+ "android/hardware/graphics/mapper/2.0/IHwMapper.h",
+ "android/hardware/graphics/mapper/2.0/BnMapper.h",
+ "android/hardware/graphics/mapper/2.0/BpMapper.h",
+ "android/hardware/graphics/mapper/2.0/BsMapper.h",
+ ],
+}
+
+cc_library_shared {
name: "android.hardware.graphics.mapper@2.0",
- export_include_dirs: ["include"],
+ generated_sources: ["android.hardware.graphics.mapper@2.0_genc++"],
+ generated_headers: ["android.hardware.graphics.mapper@2.0_genc++_headers"],
+ export_generated_headers: ["android.hardware.graphics.mapper@2.0_genc++_headers"],
+ shared_libs: [
+ "libhidlbase",
+ "libhidltransport",
+ "libhwbinder",
+ "liblog",
+ "libutils",
+ "libcutils",
+ "android.hardware.graphics.allocator@2.0",
+ "android.hardware.graphics.common@1.0",
+ "android.hidl.base@1.0",
+ ],
+ export_shared_lib_headers: [
+ "libhidlbase",
+ "libhidltransport",
+ "libhwbinder",
+ "libutils",
+ "android.hardware.graphics.allocator@2.0",
+ "android.hardware.graphics.common@1.0",
+ "android.hidl.base@1.0",
+ ],
}
diff --git a/graphics/mapper/2.0/include/android/hardware/graphics/mapper/2.0/IMapper.h b/graphics/mapper/2.0/IMapper.hal
similarity index 62%
rename from graphics/mapper/2.0/include/android/hardware/graphics/mapper/2.0/IMapper.h
rename to graphics/mapper/2.0/IMapper.hal
index ac8ec45..21a6dfa 100644
--- a/graphics/mapper/2.0/include/android/hardware/graphics/mapper/2.0/IMapper.h
+++ b/graphics/mapper/2.0/IMapper.hal
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 The Android Open Source Project
+ * 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.
@@ -14,165 +14,135 @@
* limitations under the License.
*/
-#ifndef ANDROID_HARDWARE_GRAPHICS_MAPPER_V2_0_IMAPPER_H
-#define ANDROID_HARDWARE_GRAPHICS_MAPPER_V2_0_IMAPPER_H
+package android.hardware.graphics.mapper@2.0;
-#include <type_traits>
+import android.hardware.graphics.common@1.0::PixelFormat;
+import android.hardware.graphics.allocator@2.0;
-#include <android/hardware/graphics/mapper/2.0/types.h>
-
-extern "C" {
-
-namespace android {
-namespace hardware {
-namespace graphics {
-namespace mapper {
-namespace V2_0 {
-
-struct Device {
+interface IMapper {
struct Rect {
int32_t left;
int32_t top;
int32_t width;
int32_t height;
};
- static_assert(std::is_pod<Rect>::value, "Device::Rect is not POD");
-
- /*
- * Create a mapper device.
- *
- * @return error is NONE upon success. Otherwise,
- * NOT_SUPPORTED when creation will never succeed.
- * BAD_RESOURCES when creation failed at this time.
- * @return device is the newly created mapper device.
- */
- typedef Error (*createDevice)(Device** outDevice);
-
- /*
- * Destroy a mapper device.
- *
- * @return error is always NONE.
- * @param device is the mapper device to destroy.
- */
- typedef Error (*destroyDevice)(Device* device);
/*
* Adds a reference to the given buffer handle.
*
* A buffer handle received from a remote process or exported by
- * IAllocator::exportHandle is unknown to this client-side library. There
- * is also no guarantee that the buffer's backing store will stay alive.
- * This function must be called at least once in both cases to intrdouce
- * the buffer handle to this client-side library and to secure the backing
- * store. It may also be called more than once to increase the reference
- * count if two components in the same process want to interact with the
- * buffer independently.
+ * IAllocator::exportHandle is unknown to the mapper. There is also no
+ * guarantee that the buffer's backing store will stay alive. This
+ * function must be called at least once in both cases to intrdouce the
+ * buffer handle to the mapper and to secure the backing store. It may
+ * also be called more than once to increase the reference count if two
+ * components in the same process want to interact with the buffer
+ * independently.
*
- * @param device is the mapper device.
* @param bufferHandle is the buffer to which a reference must be added.
* @return error is NONE upon success. Otherwise,
* BAD_BUFFER when the buffer handle is invalid
* NO_RESOURCES when it is not possible to add a
* reference to this buffer at this time
*/
- typedef Error (*retain)(Device* device,
- const native_handle_t* bufferHandle);
+ @entry
+ @callflow(next="*")
+ retain(handle bufferHandle) generates (Error error);
/*
* Removes a reference from the given buffer buffer.
*
- * If no references remain, the buffer handle should be freed with
- * native_handle_close/native_handle_delete. When the last buffer handle
- * referring to a particular backing store is freed, that backing store
- * should also be freed.
+ * If no references remain, the buffer handle must be freed with
+ * native_handle_close/native_handle_delete by the mapper. When the last
+ * buffer handle referring to a particular backing store is freed, that
+ * backing store must also be freed.
*
- * @param device is the mapper device.
* @param bufferHandle is the buffer from which a reference must be
* removed.
* @return error is NONE upon success. Otherwise,
* BAD_BUFFER when the buffer handle is invalid.
*/
- typedef Error (*release)(Device* device,
- const native_handle_t* bufferHandle);
+ @exit
+ release(handle bufferHandle) generates (Error error);
/*
* Gets the width and height of the buffer in pixels.
*
* See IAllocator::BufferDescriptorInfo for more information.
*
- * @param device is the mapper device.
* @param bufferHandle is the buffer from which to get the dimensions.
* @return error is NONE upon success. Otherwise,
* BAD_BUFFER when the buffer handle is invalid.
* @return width is the width of the buffer in pixels.
* @return height is the height of the buffer in pixels.
*/
- typedef Error (*getDimensions)(Device* device,
- const native_handle_t* bufferHandle,
- uint32_t* outWidth,
- uint32_t* outHeight);
+ @callflow(next="*")
+ getDimensions(handle bufferHandle)
+ generates (Error error,
+ uint32_t width,
+ uint32_t height);
/*
* Gets the format of the buffer.
*
* See IAllocator::BufferDescriptorInfo for more information.
*
- * @param device is the mapper device.
* @param bufferHandle is the buffer from which to get format.
* @return error is NONE upon success. Otherwise,
* BAD_BUFFER when the buffer handle is invalid.
* @return format is the format of the buffer.
*/
- typedef Error (*getFormat)(Device* device,
- const native_handle_t* bufferHandle,
- PixelFormat* outFormat);
+ @callflow(next="*")
+ getFormat(handle bufferHandle)
+ generates (Error error,
+ PixelFormat format);
/*
* Gets the number of layers of the buffer.
*
* See IAllocator::BufferDescriptorInfo for more information.
*
- * @param device is the mapper device.
* @param bufferHandle is the buffer from which to get format.
* @return error is NONE upon success. Otherwise,
* BAD_BUFFER when the buffer handle is invalid.
* @return layerCount is the number of layers of the buffer.
*/
- typedef Error (*getLayerCount)(Device* device,
- const native_handle_t* bufferHandle,
- uint32_t* outLayerCount);
+ @callflow(next="*")
+ getLayerCount(handle bufferHandle)
+ generates (Error error,
+ uint32_t layerCount);
/*
* Gets the producer usage flags which were used to allocate this buffer.
*
* See IAllocator::BufferDescriptorInfo for more information.
*
- * @param device is the mapper device.
* @param bufferHandle is the buffer from which to get the producer usage
* flags.
* @return error is NONE upon success. Otherwise,
* BAD_BUFFER when the buffer handle is invalid.
* @return usageMask contains the producer usage flags of the buffer.
*/
- typedef Error (*getProducerUsageMask)(Device* device,
- const native_handle_t* bufferHandle,
- uint64_t* outUsageMask);
+ @callflow(next="*")
+ getProducerUsageMask(handle bufferHandle)
+ generates (Error error,
+ uint64_t usageMask);
/*
* Gets the consumer usage flags which were used to allocate this buffer.
*
* See IAllocator::BufferDescriptorInfo for more information.
*
- * @param device is the mapper device.
* @param bufferHandle is the buffer from which to get the consumer usage
* flags.
* @return error is NONE upon success. Otherwise,
* BAD_BUFFER when the buffer handle is invalid.
* @return usageMask contains the consumer usage flags of the buffer.
*/
- typedef Error (*getConsumerUsageMask)(Device* device,
- const native_handle_t* bufferHandle,
- uint64_t* outUsageMask);
+ @callflow(next="*")
+ getConsumerUsageMask(handle bufferHandle)
+ generates (Error error,
+ uint64_t usageMask);
/*
* Gets a value that uniquely identifies the backing store of the given
@@ -190,9 +160,10 @@
* BAD_BUFFER when the buffer handle is invalid.
* @return store is the backing store identifier for this buffer.
*/
- typedef Error (*getBackingStore)(Device* device,
- const native_handle_t* bufferHandle,
- BackingStore* outStore);
+ @callflow(next="*")
+ getBackingStore(handle bufferHandle)
+ generates (Error error,
+ BackingStore store);
/*
* Gets the stride of the buffer in pixels.
@@ -209,31 +180,10 @@
* meaningful for the buffer format.
* @return store is the stride in pixels.
*/
- typedef Error (*getStride)(Device* device,
- const native_handle_t* bufferHandle,
- uint32_t* outStride);
-
- /*
- * Returns the number of flex layout planes which are needed to represent
- * the given buffer. This may be used to efficiently allocate only as many
- * plane structures as necessary before calling into lockFlex.
- *
- * If the given buffer cannot be locked as a flex format, this function
- * may return UNSUPPORTED (as lockFlex would).
- *
- * @param device is the mapper device.
- * @param bufferHandle is the buffer for which the number of planes should
- * be queried.
- * @return error is NONE upon success. Otherwise,
- * BAD_BUFFER when the buffer handle is invalid.
- * UNSUPPORTED when the buffer's format cannot be
- * represented in a flex layout.
- * @return numPlanes is the number of flex planes required to describe the
- * given buffer.
- */
- typedef Error (*getNumFlexPlanes)(Device* device,
- const native_handle_t* bufferHandle,
- uint32_t* outNumPlanes);
+ @callflow(next="*")
+ getStride(handle bufferHandle)
+ generates (Error error,
+ uint32_t stride);
/*
* Locks the given buffer for the specified CPU usage.
@@ -264,7 +214,6 @@
* the contents of the buffer (prior to locking). If it is already safe to
* access the buffer contents, -1 may be passed instead.
*
- * @param device is the mapper device.
* @param bufferHandle is the buffer to lock.
* @param producerUsageMask contains the producer usage flags to request;
* either this or consumerUsagemask must be 0, and the other must
@@ -289,13 +238,14 @@
* @return data will be filled with a CPU-accessible pointer to the buffer
* data.
*/
- typedef Error (*lock)(Device* device,
- const native_handle_t* bufferHandle,
- uint64_t producerUsageMask,
- uint64_t consumerUsageMask,
- const Rect* accessRegion,
- int32_t acquireFence,
- void** outData);
+ @callflow(next="unlock")
+ lock(handle bufferHandle,
+ uint64_t producerUsageMask,
+ uint64_t consumerUsageMask,
+ Rect accessRegion,
+ handle acquireFence)
+ generates (Error error,
+ pointer data);
/*
* This is largely the same as lock(), except that instead of returning a
@@ -337,13 +287,14 @@
* @return flexLayout will be filled with the description of the planes in
* the buffer.
*/
- typedef Error (*lockFlex)(Device* device,
- const native_handle_t* bufferHandle,
- uint64_t producerUsageMask,
- uint64_t consumerUsageMask,
- const Rect* accessRegion,
- int32_t acquireFence,
- FlexLayout* outFlexLayout);
+ @callflow(next="unlock")
+ lockFlex(handle bufferHandle,
+ uint64_t producerUsageMask,
+ uint64_t consumerUsageMask,
+ Rect accessRegion,
+ handle acquireFence)
+ generates (Error error,
+ FlexLayout layout);
/*
* This function indicates to the device that the client will be done with
@@ -365,40 +316,8 @@
* @return releaseFence is a sync fence file descriptor as described
* above.
*/
- typedef Error (*unlock)(Device* device,
- const native_handle_t* bufferHandle,
- int32_t* outReleaseFence);
+ @callflow(next="*")
+ unlock(handle bufferHandle)
+ generates (Error error,
+ handle releaseFence);
};
-static_assert(std::is_pod<Device>::value, "Device is not POD");
-
-struct IMapper {
- Device::createDevice createDevice;
- Device::destroyDevice destroyDevice;
-
- Device::retain retain;
- Device::release release;
- Device::getDimensions getDimensions;
- Device::getFormat getFormat;
- Device::getLayerCount getLayerCount;
- Device::getProducerUsageMask getProducerUsageMask;
- Device::getConsumerUsageMask getConsumerUsageMask;
- Device::getBackingStore getBackingStore;
- Device::getStride getStride;
- Device::getNumFlexPlanes getNumFlexPlanes;
- Device::lock lock;
- Device::lockFlex lockFlex;
- Device::unlock unlock;
-};
-static_assert(std::is_pod<IMapper>::value, "IMapper is not POD");
-
-} // namespace V2_0
-} // namespace mapper
-} // namespace graphics
-} // namespace hardware
-} // namespace android
-
-const void* HALLIB_FETCH_Interface(const char* name);
-
-} // extern "C"
-
-#endif /* ANDROID_HARDWARE_GRAPHICS_MAPPER_V2_0_IMAPPER_H */
diff --git a/graphics/mapper/2.0/default/Android.bp b/graphics/mapper/2.0/default/Android.bp
index 7da6eb1..02ed877 100644
--- a/graphics/mapper/2.0/default/Android.bp
+++ b/graphics/mapper/2.0/default/Android.bp
@@ -1,3 +1,4 @@
+//
// Copyright (C) 2016 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
@@ -13,17 +14,19 @@
// limitations under the License.
cc_library_shared {
- name: "android.hardware.graphics.mapper.hallib",
+ name: "android.hardware.graphics.mapper@2.0-impl",
relative_install_path: "hw",
srcs: ["GrallocMapper.cpp"],
cppflags: ["-Wall", "-Wextra"],
- static_libs: ["android.hardware.graphics.mapper@2.0"],
shared_libs: [
- "android.hardware.graphics.allocator@2.0",
+ "android.hardware.graphics.mapper@2.0",
+ "libbase",
+ "libcutils",
"libhardware",
"libhidlbase",
"libhidltransport",
"libhwbinder",
"liblog",
+ "libutils",
],
}
diff --git a/graphics/mapper/2.0/default/GrallocMapper.cpp b/graphics/mapper/2.0/default/GrallocMapper.cpp
index 2af1d2c..cd9db38 100644
--- a/graphics/mapper/2.0/default/GrallocMapper.cpp
+++ b/graphics/mapper/2.0/default/GrallocMapper.cpp
@@ -15,13 +15,15 @@
#define LOG_TAG "GrallocMapperPassthrough"
-#include <android/hardware/graphics/allocator/2.0/IAllocator.h>
-#include <android/hardware/graphics/mapper/2.0/IMapper.h>
+#include "GrallocMapper.h"
+
+#include <vector>
+
+#include <string.h>
+
#include <hardware/gralloc1.h>
#include <log/log.h>
-#include <unordered_set>
-
namespace android {
namespace hardware {
namespace graphics {
@@ -29,50 +31,59 @@
namespace V2_0 {
namespace implementation {
-using Capability = allocator::V2_0::IAllocator::Capability;
+namespace {
-class GrallocDevice : public Device {
+using android::hardware::graphics::allocator::V2_0::Error;
+using android::hardware::graphics::common::V1_0::PixelFormat;
+
+class GrallocMapperHal : public IMapper {
public:
- GrallocDevice();
- ~GrallocDevice();
+ GrallocMapperHal(const hw_module_t* module);
+ ~GrallocMapperHal();
// IMapper interface
- Error retain(const native_handle_t* bufferHandle);
- Error release(const native_handle_t* bufferHandle);
- Error getDimensions(const native_handle_t* bufferHandle,
- uint32_t* outWidth, uint32_t* outHeight);
- Error getFormat(const native_handle_t* bufferHandle,
- PixelFormat* outFormat);
- Error getLayerCount(const native_handle_t* bufferHandle,
- uint32_t* outLayerCount);
- Error getProducerUsageMask(const native_handle_t* bufferHandle,
- uint64_t* outUsageMask);
- Error getConsumerUsageMask(const native_handle_t* bufferHandle,
- uint64_t* outUsageMask);
- Error getBackingStore(const native_handle_t* bufferHandle,
- BackingStore* outStore);
- Error getStride(const native_handle_t* bufferHandle, uint32_t* outStride);
- Error getNumFlexPlanes(const native_handle_t* bufferHandle,
- uint32_t* outNumPlanes);
- Error lock(const native_handle_t* bufferHandle,
+ Return<Error> retain(const hidl_handle& bufferHandle) override;
+ Return<Error> release(const hidl_handle& bufferHandle) override;
+ Return<void> getDimensions(const hidl_handle& bufferHandle,
+ getDimensions_cb hidl_cb) override;
+ Return<void> getFormat(const hidl_handle& bufferHandle,
+ getFormat_cb hidl_cb) override;
+ Return<void> getLayerCount(const hidl_handle& bufferHandle,
+ getLayerCount_cb hidl_cb) override;
+ Return<void> getProducerUsageMask(const hidl_handle& bufferHandle,
+ getProducerUsageMask_cb hidl_cb) override;
+ Return<void> getConsumerUsageMask(const hidl_handle& bufferHandle,
+ getConsumerUsageMask_cb hidl_cb) override;
+ Return<void> getBackingStore(const hidl_handle& bufferHandle,
+ getBackingStore_cb hidl_cb) override;
+ Return<void> getStride(const hidl_handle& bufferHandle,
+ getStride_cb hidl_cb) override;
+ Return<void> lock(const hidl_handle& bufferHandle,
uint64_t producerUsageMask, uint64_t consumerUsageMask,
- const Rect* accessRegion, int32_t acquireFence, void** outData);
- Error lockFlex(const native_handle_t* bufferHandle,
+ const IMapper::Rect& accessRegion, const hidl_handle& acquireFence,
+ lock_cb hidl_cb) override;
+ Return<void> lockFlex(const hidl_handle& bufferHandle,
uint64_t producerUsageMask, uint64_t consumerUsageMask,
- const Rect* accessRegion, int32_t acquireFence,
- FlexLayout* outFlexLayout);
- Error unlock(const native_handle_t* bufferHandle,
- int32_t* outReleaseFence);
+ const IMapper::Rect& accessRegion, const hidl_handle& acquireFence,
+ lockFlex_cb hidl_cb) override;
+ Return<void> unlock(const hidl_handle& bufferHandle,
+ unlock_cb hidl_cb) override;
private:
void initCapabilities();
+ template<typename T>
+ void initDispatch(gralloc1_function_descriptor_t desc, T* outPfn);
void initDispatch();
- bool hasCapability(Capability capability) const;
+
+ static gralloc1_rect_t asGralloc1Rect(const IMapper::Rect& rect);
+ static bool dupFence(const hidl_handle& fenceHandle, int* outFd);
gralloc1_device_t* mDevice;
- std::unordered_set<Capability> mCapabilities;
+ struct {
+ bool layeredBuffers;
+ } mCapabilities;
struct {
GRALLOC1_PFN_RETAIN retain;
@@ -91,333 +102,293 @@
} mDispatch;
};
-GrallocDevice::GrallocDevice()
+GrallocMapperHal::GrallocMapperHal(const hw_module_t* module)
+ : mDevice(nullptr), mCapabilities(), mDispatch()
{
- const hw_module_t* module;
- int status = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
+ int status = gralloc1_open(module, &mDevice);
if (status) {
- LOG_ALWAYS_FATAL("failed to get gralloc module");
- }
-
- uint8_t major = (module->module_api_version >> 8) & 0xff;
- if (major != 1) {
- LOG_ALWAYS_FATAL("unknown gralloc module major version %d", major);
- }
-
- status = gralloc1_open(module, &mDevice);
- if (status) {
- LOG_ALWAYS_FATAL("failed to open gralloc1 device");
+ LOG_ALWAYS_FATAL("failed to open gralloc1 device: %s",
+ strerror(-status));
}
initCapabilities();
initDispatch();
}
-GrallocDevice::~GrallocDevice()
+GrallocMapperHal::~GrallocMapperHal()
{
gralloc1_close(mDevice);
}
-void GrallocDevice::initCapabilities()
+void GrallocMapperHal::initCapabilities()
{
uint32_t count;
mDevice->getCapabilities(mDevice, &count, nullptr);
- std::vector<Capability> caps(count);
- mDevice->getCapabilities(mDevice, &count, reinterpret_cast<
- std::underlying_type<Capability>::type*>(caps.data()));
+ std::vector<int32_t> caps(count);
+ mDevice->getCapabilities(mDevice, &count, caps.data());
caps.resize(count);
- mCapabilities.insert(caps.cbegin(), caps.cend());
-}
-
-void GrallocDevice::initDispatch()
-{
-#define CHECK_FUNC(func, desc) do { \
- mDispatch.func = reinterpret_cast<decltype(mDispatch.func)>( \
- mDevice->getFunction(mDevice, desc)); \
- if (!mDispatch.func) { \
- LOG_ALWAYS_FATAL("failed to get gralloc1 function %d", desc); \
- } \
-} while (0)
-
- CHECK_FUNC(retain, GRALLOC1_FUNCTION_RETAIN);
- CHECK_FUNC(release, GRALLOC1_FUNCTION_RELEASE);
- CHECK_FUNC(getDimensions, GRALLOC1_FUNCTION_GET_DIMENSIONS);
- CHECK_FUNC(getFormat, GRALLOC1_FUNCTION_GET_FORMAT);
- if (hasCapability(Capability::LAYERED_BUFFERS)) {
- CHECK_FUNC(getLayerCount, GRALLOC1_FUNCTION_GET_LAYER_COUNT);
+ for (auto cap : caps) {
+ switch (cap) {
+ case GRALLOC1_CAPABILITY_LAYERED_BUFFERS:
+ mCapabilities.layeredBuffers = true;
+ break;
+ default:
+ break;
+ }
}
- CHECK_FUNC(getProducerUsage, GRALLOC1_FUNCTION_GET_PRODUCER_USAGE);
- CHECK_FUNC(getConsumerUsage, GRALLOC1_FUNCTION_GET_CONSUMER_USAGE);
- CHECK_FUNC(getBackingStore, GRALLOC1_FUNCTION_GET_BACKING_STORE);
- CHECK_FUNC(getStride, GRALLOC1_FUNCTION_GET_STRIDE);
- CHECK_FUNC(getNumFlexPlanes, GRALLOC1_FUNCTION_GET_NUM_FLEX_PLANES);
- CHECK_FUNC(lock, GRALLOC1_FUNCTION_LOCK);
- CHECK_FUNC(lockFlex, GRALLOC1_FUNCTION_LOCK_FLEX);
- CHECK_FUNC(unlock, GRALLOC1_FUNCTION_UNLOCK);
-
-#undef CHECK_FUNC
}
-bool GrallocDevice::hasCapability(Capability capability) const
+template<typename T>
+void GrallocMapperHal::initDispatch(gralloc1_function_descriptor_t desc,
+ T* outPfn)
{
- return (mCapabilities.count(capability) > 0);
+ auto pfn = mDevice->getFunction(mDevice, desc);
+ if (!pfn) {
+ LOG_ALWAYS_FATAL("failed to get gralloc1 function %d", desc);
+ }
+
+ *outPfn = reinterpret_cast<T>(pfn);
}
-Error GrallocDevice::retain(const native_handle_t* bufferHandle)
+void GrallocMapperHal::initDispatch()
{
- int32_t error = mDispatch.retain(mDevice, bufferHandle);
- return static_cast<Error>(error);
+ initDispatch(GRALLOC1_FUNCTION_RETAIN, &mDispatch.retain);
+ initDispatch(GRALLOC1_FUNCTION_RELEASE, &mDispatch.release);
+ initDispatch(GRALLOC1_FUNCTION_GET_DIMENSIONS, &mDispatch.getDimensions);
+ initDispatch(GRALLOC1_FUNCTION_GET_FORMAT, &mDispatch.getFormat);
+ if (mCapabilities.layeredBuffers) {
+ initDispatch(GRALLOC1_FUNCTION_GET_LAYER_COUNT,
+ &mDispatch.getLayerCount);
+ }
+ initDispatch(GRALLOC1_FUNCTION_GET_PRODUCER_USAGE,
+ &mDispatch.getProducerUsage);
+ initDispatch(GRALLOC1_FUNCTION_GET_CONSUMER_USAGE,
+ &mDispatch.getConsumerUsage);
+ initDispatch(GRALLOC1_FUNCTION_GET_BACKING_STORE,
+ &mDispatch.getBackingStore);
+ initDispatch(GRALLOC1_FUNCTION_GET_STRIDE, &mDispatch.getStride);
+ initDispatch(GRALLOC1_FUNCTION_GET_NUM_FLEX_PLANES,
+ &mDispatch.getNumFlexPlanes);
+ initDispatch(GRALLOC1_FUNCTION_LOCK, &mDispatch.lock);
+ initDispatch(GRALLOC1_FUNCTION_LOCK_FLEX, &mDispatch.lockFlex);
+ initDispatch(GRALLOC1_FUNCTION_UNLOCK, &mDispatch.unlock);
}
-Error GrallocDevice::release(const native_handle_t* bufferHandle)
+gralloc1_rect_t GrallocMapperHal::asGralloc1Rect(const IMapper::Rect& rect)
{
- int32_t error = mDispatch.release(mDevice, bufferHandle);
- return static_cast<Error>(error);
+ return gralloc1_rect_t{rect.left, rect.top, rect.width, rect.height};
}
-Error GrallocDevice::getDimensions(const native_handle_t* bufferHandle,
- uint32_t* outWidth, uint32_t* outHeight)
+bool GrallocMapperHal::dupFence(const hidl_handle& fenceHandle, int* outFd)
{
- int32_t error = mDispatch.getDimensions(mDevice, bufferHandle,
- outWidth, outHeight);
- return static_cast<Error>(error);
+ auto handle = fenceHandle.getNativeHandle();
+ if (!handle || handle->numFds == 0) {
+ *outFd = -1;
+ return true;
+ }
+
+ if (handle->numFds > 1) {
+ ALOGE("invalid fence handle with %d fds", handle->numFds);
+ return false;
+ }
+
+ *outFd = dup(handle->data[0]);
+ return (*outFd >= 0);
}
-Error GrallocDevice::getFormat(const native_handle_t* bufferHandle,
- PixelFormat* outFormat)
+Return<Error> GrallocMapperHal::retain(const hidl_handle& bufferHandle)
{
- int32_t error = mDispatch.getFormat(mDevice, bufferHandle,
- reinterpret_cast<int32_t*>(outFormat));
- return static_cast<Error>(error);
+ int32_t err = mDispatch.retain(mDevice, bufferHandle);
+ return static_cast<Error>(err);
}
-Error GrallocDevice::getLayerCount(const native_handle_t* bufferHandle,
- uint32_t* outLayerCount)
+Return<Error> GrallocMapperHal::release(const hidl_handle& bufferHandle)
{
- if (hasCapability(Capability::LAYERED_BUFFERS)) {
- int32_t error = mDispatch.getLayerCount(mDevice, bufferHandle,
- outLayerCount);
- return static_cast<Error>(error);
+ int32_t err = mDispatch.release(mDevice, bufferHandle);
+ return static_cast<Error>(err);
+}
+
+Return<void> GrallocMapperHal::getDimensions(const hidl_handle& bufferHandle,
+ getDimensions_cb hidl_cb)
+{
+ uint32_t width = 0;
+ uint32_t height = 0;
+ int32_t err = mDispatch.getDimensions(mDevice, bufferHandle,
+ &width, &height);
+
+ hidl_cb(static_cast<Error>(err), width, height);
+ return Void();
+}
+
+Return<void> GrallocMapperHal::getFormat(const hidl_handle& bufferHandle,
+ getFormat_cb hidl_cb)
+{
+ int32_t format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
+ int32_t err = mDispatch.getFormat(mDevice, bufferHandle, &format);
+
+ hidl_cb(static_cast<Error>(err), static_cast<PixelFormat>(format));
+ return Void();
+}
+
+Return<void> GrallocMapperHal::getLayerCount(const hidl_handle& bufferHandle,
+ getLayerCount_cb hidl_cb)
+{
+ int32_t err = GRALLOC1_ERROR_NONE;
+ uint32_t count = 1;
+ if (mCapabilities.layeredBuffers) {
+ err = mDispatch.getLayerCount(mDevice, bufferHandle, &count);
+ }
+
+ hidl_cb(static_cast<Error>(err), count);
+ return Void();
+}
+
+Return<void> GrallocMapperHal::getProducerUsageMask(
+ const hidl_handle& bufferHandle, getProducerUsageMask_cb hidl_cb)
+{
+ uint64_t mask = 0x0;
+ int32_t err = mDispatch.getProducerUsage(mDevice, bufferHandle, &mask);
+
+ hidl_cb(static_cast<Error>(err), mask);
+ return Void();
+}
+
+Return<void> GrallocMapperHal::getConsumerUsageMask(
+ const hidl_handle& bufferHandle, getConsumerUsageMask_cb hidl_cb)
+{
+ uint64_t mask = 0x0;
+ int32_t err = mDispatch.getConsumerUsage(mDevice, bufferHandle, &mask);
+
+ hidl_cb(static_cast<Error>(err), mask);
+ return Void();
+}
+
+Return<void> GrallocMapperHal::getBackingStore(
+ const hidl_handle& bufferHandle, getBackingStore_cb hidl_cb)
+{
+ uint64_t store = 0;
+ int32_t err = mDispatch.getBackingStore(mDevice, bufferHandle, &store);
+
+ hidl_cb(static_cast<Error>(err), store);
+ return Void();
+}
+
+Return<void> GrallocMapperHal::getStride(const hidl_handle& bufferHandle,
+ getStride_cb hidl_cb)
+{
+ uint32_t stride = 0;
+ int32_t err = mDispatch.getStride(mDevice, bufferHandle, &stride);
+
+ hidl_cb(static_cast<Error>(err), stride);
+ return Void();
+}
+
+Return<void> GrallocMapperHal::lock(const hidl_handle& bufferHandle,
+ uint64_t producerUsageMask, uint64_t consumerUsageMask,
+ const IMapper::Rect& accessRegion, const hidl_handle& acquireFence,
+ lock_cb hidl_cb)
+{
+ gralloc1_rect_t rect = asGralloc1Rect(accessRegion);
+
+ int fence = -1;
+ if (!dupFence(acquireFence, &fence)) {
+ hidl_cb(Error::NO_RESOURCES, nullptr);
+ return Void();
+ }
+
+ void* data = nullptr;
+ int32_t err = mDispatch.lock(mDevice, bufferHandle, producerUsageMask,
+ consumerUsageMask, &rect, &data, fence);
+ if (err != GRALLOC1_ERROR_NONE) {
+ close(fence);
+ }
+
+ hidl_cb(static_cast<Error>(err), data);
+ return Void();
+}
+
+Return<void> GrallocMapperHal::lockFlex(const hidl_handle& bufferHandle,
+ uint64_t producerUsageMask, uint64_t consumerUsageMask,
+ const IMapper::Rect& accessRegion, const hidl_handle& acquireFence,
+ lockFlex_cb hidl_cb)
+{
+ FlexLayout layout_reply{};
+
+ uint32_t planeCount = 0;
+ int32_t err = mDispatch.getNumFlexPlanes(mDevice, bufferHandle,
+ &planeCount);
+ if (err != GRALLOC1_ERROR_NONE) {
+ hidl_cb(static_cast<Error>(err), layout_reply);
+ return Void();
+ }
+
+ gralloc1_rect_t rect = asGralloc1Rect(accessRegion);
+
+ int fence = -1;
+ if (!dupFence(acquireFence, &fence)) {
+ hidl_cb(Error::NO_RESOURCES, layout_reply);
+ return Void();
+ }
+
+ std::vector<android_flex_plane_t> planes(planeCount);
+ android_flex_layout_t layout{};
+ layout.num_planes = planes.size();
+ layout.planes = planes.data();
+
+ err = mDispatch.lockFlex(mDevice, bufferHandle, producerUsageMask,
+ consumerUsageMask, &rect, &layout, fence);
+ if (err == GRALLOC1_ERROR_NONE) {
+ layout_reply.format = static_cast<FlexFormat>(layout.format);
+
+ planes.resize(layout.num_planes);
+ layout_reply.planes.setToExternal(
+ reinterpret_cast<FlexPlane*>(planes.data()), planes.size());
} else {
- *outLayerCount = 1;
- return Error::NONE;
+ close(fence);
}
+
+ hidl_cb(static_cast<Error>(err), layout_reply);
+ return Void();
}
-Error GrallocDevice::getProducerUsageMask(const native_handle_t* bufferHandle,
- uint64_t* outUsageMask)
+Return<void> GrallocMapperHal::unlock(const hidl_handle& bufferHandle,
+ unlock_cb hidl_cb)
{
- int32_t error = mDispatch.getProducerUsage(mDevice, bufferHandle,
- outUsageMask);
- return static_cast<Error>(error);
+ int32_t fence = -1;
+ int32_t err = mDispatch.unlock(mDevice, bufferHandle, &fence);
+
+ NATIVE_HANDLE_DECLARE_STORAGE(fenceStorage, 1, 0);
+ hidl_handle fenceHandle;
+ if (err == GRALLOC1_ERROR_NONE && fence >= 0) {
+ auto nativeHandle = native_handle_init(fenceStorage, 1, 0);
+ nativeHandle->data[0] = fence;
+
+ fenceHandle = nativeHandle;
+ }
+
+ hidl_cb(static_cast<Error>(err), fenceHandle);
+ return Void();
}
-Error GrallocDevice::getConsumerUsageMask(const native_handle_t* bufferHandle,
- uint64_t* outUsageMask)
-{
- int32_t error = mDispatch.getConsumerUsage(mDevice, bufferHandle,
- outUsageMask);
- return static_cast<Error>(error);
-}
+} // anonymous namespace
-Error GrallocDevice::getBackingStore(const native_handle_t* bufferHandle,
- BackingStore* outStore)
-{
- int32_t error = mDispatch.getBackingStore(mDevice, bufferHandle,
- outStore);
- return static_cast<Error>(error);
-}
-
-Error GrallocDevice::getStride(const native_handle_t* bufferHandle,
- uint32_t* outStride)
-{
- int32_t error = mDispatch.getStride(mDevice, bufferHandle, outStride);
- return static_cast<Error>(error);
-}
-
-Error GrallocDevice::getNumFlexPlanes(const native_handle_t* bufferHandle,
- uint32_t* outNumPlanes)
-{
- int32_t error = mDispatch.getNumFlexPlanes(mDevice, bufferHandle,
- outNumPlanes);
- return static_cast<Error>(error);
-}
-
-Error GrallocDevice::lock(const native_handle_t* bufferHandle,
- uint64_t producerUsageMask, uint64_t consumerUsageMask,
- const Rect* accessRegion, int32_t acquireFence,
- void** outData)
-{
- int32_t error = mDispatch.lock(mDevice, bufferHandle,
- producerUsageMask, consumerUsageMask,
- reinterpret_cast<const gralloc1_rect_t*>(accessRegion),
- outData, acquireFence);
- return static_cast<Error>(error);
-}
-
-Error GrallocDevice::lockFlex(const native_handle_t* bufferHandle,
- uint64_t producerUsageMask, uint64_t consumerUsageMask,
- const Rect* accessRegion, int32_t acquireFence,
- FlexLayout* outFlexLayout)
-{
- int32_t error = mDispatch.lockFlex(mDevice, bufferHandle,
- producerUsageMask, consumerUsageMask,
- reinterpret_cast<const gralloc1_rect_t*>(accessRegion),
- reinterpret_cast<android_flex_layout_t*>(outFlexLayout),
- acquireFence);
- return static_cast<Error>(error);
-}
-
-Error GrallocDevice::unlock(const native_handle_t* bufferHandle,
- int32_t* outReleaseFence)
-{
- int32_t error = mDispatch.unlock(mDevice, bufferHandle, outReleaseFence);
- return static_cast<Error>(error);
-}
-
-class GrallocMapper : public IMapper {
-public:
- GrallocMapper() : IMapper{
- .createDevice = createDevice,
- .destroyDevice = destroyDevice,
- .retain = retain,
- .release = release,
- .getDimensions = getDimensions,
- .getFormat = getFormat,
- .getLayerCount = getLayerCount,
- .getProducerUsageMask = getProducerUsageMask,
- .getConsumerUsageMask = getConsumerUsageMask,
- .getBackingStore = getBackingStore,
- .getStride = getStride,
- .getNumFlexPlanes = getNumFlexPlanes,
- .lock = lock,
- .lockFlex = lockFlex,
- .unlock = unlock,
- } {}
-
- const IMapper* getInterface() const
- {
- return static_cast<const IMapper*>(this);
+IMapper* HIDL_FETCH_IMapper(const char* /* name */) {
+ const hw_module_t* module = nullptr;
+ int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
+ if (err) {
+ ALOGE("failed to get gralloc module");
+ return nullptr;
}
-private:
- static GrallocDevice* cast(Device* device)
- {
- return reinterpret_cast<GrallocDevice*>(device);
+ uint8_t major = (module->module_api_version >> 8) & 0xff;
+ if (major != 1) {
+ ALOGE("unknown gralloc module major version %d", major);
+ return nullptr;
}
- static Error createDevice(Device** outDevice)
- {
- *outDevice = new GrallocDevice;
- return Error::NONE;
- }
-
- static Error destroyDevice(Device* device)
- {
- delete cast(device);
- return Error::NONE;
- }
-
- static Error retain(Device* device,
- const native_handle_t* bufferHandle)
- {
- return cast(device)->retain(bufferHandle);
- }
-
- static Error release(Device* device,
- const native_handle_t* bufferHandle)
- {
- return cast(device)->release(bufferHandle);
- }
-
- static Error getDimensions(Device* device,
- const native_handle_t* bufferHandle,
- uint32_t* outWidth, uint32_t* outHeight)
- {
- return cast(device)->getDimensions(bufferHandle, outWidth, outHeight);
- }
-
- static Error getFormat(Device* device,
- const native_handle_t* bufferHandle, PixelFormat* outFormat)
- {
- return cast(device)->getFormat(bufferHandle, outFormat);
- }
-
- static Error getLayerCount(Device* device,
- const native_handle_t* bufferHandle, uint32_t* outLayerCount)
- {
- return cast(device)->getLayerCount(bufferHandle, outLayerCount);
- }
-
- static Error getProducerUsageMask(Device* device,
- const native_handle_t* bufferHandle, uint64_t* outUsageMask)
- {
- return cast(device)->getProducerUsageMask(bufferHandle, outUsageMask);
- }
-
- static Error getConsumerUsageMask(Device* device,
- const native_handle_t* bufferHandle, uint64_t* outUsageMask)
- {
- return cast(device)->getConsumerUsageMask(bufferHandle, outUsageMask);
- }
-
- static Error getBackingStore(Device* device,
- const native_handle_t* bufferHandle, BackingStore* outStore)
- {
- return cast(device)->getBackingStore(bufferHandle, outStore);
- }
-
- static Error getStride(Device* device,
- const native_handle_t* bufferHandle, uint32_t* outStride)
- {
- return cast(device)->getStride(bufferHandle, outStride);
- }
-
- static Error getNumFlexPlanes(Device* device,
- const native_handle_t* bufferHandle, uint32_t* outNumPlanes)
- {
- return cast(device)->getNumFlexPlanes(bufferHandle, outNumPlanes);
- }
-
- static Error lock(Device* device,
- const native_handle_t* bufferHandle,
- uint64_t producerUsageMask, uint64_t consumerUsageMask,
- const Device::Rect* accessRegion, int32_t acquireFence,
- void** outData)
- {
- return cast(device)->lock(bufferHandle,
- producerUsageMask, consumerUsageMask,
- accessRegion, acquireFence, outData);
- }
-
- static Error lockFlex(Device* device,
- const native_handle_t* bufferHandle,
- uint64_t producerUsageMask, uint64_t consumerUsageMask,
- const Device::Rect* accessRegion, int32_t acquireFence,
- FlexLayout* outFlexLayout)
- {
- return cast(device)->lockFlex(bufferHandle,
- producerUsageMask, consumerUsageMask,
- accessRegion, acquireFence, outFlexLayout);
- }
-
- static Error unlock(Device* device,
- const native_handle_t* bufferHandle, int32_t* outReleaseFence)
- {
- return cast(device)->unlock(bufferHandle, outReleaseFence);
- }
-};
-
-extern "C" const void* HALLIB_FETCH_Interface(const char* name)
-{
- if (strcmp(name, "android.hardware.graphics.mapper@2.0::IMapper") == 0) {
- static GrallocMapper sGrallocMapper;
- return sGrallocMapper.getInterface();
- }
-
- return nullptr;
+ return new GrallocMapperHal(module);
}
} // namespace implementation
diff --git a/graphics/mapper/2.0/default/GrallocMapper.h b/graphics/mapper/2.0/default/GrallocMapper.h
new file mode 100644
index 0000000..a2f89d1
--- /dev/null
+++ b/graphics/mapper/2.0/default/GrallocMapper.h
@@ -0,0 +1,38 @@
+/*
+ * 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 ANDROID_HARDWARE_GRAPHICS_MAPPER_V2_0_GRALLOC_MAPPER_H
+#define ANDROID_HARDWARE_GRAPHICS_MAPPER_V2_0_GRALLOC_MAPPER_H
+
+#include <android/hardware/graphics/mapper/2.0/IMapper.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace mapper {
+namespace V2_0 {
+namespace implementation {
+
+extern "C" IMapper* HIDL_FETCH_IMapper(const char* name);
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace mapper
+} // namespace graphics
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GRAPHICS_MAPPER_V2_0_GRALLOC_MAPPER_H
diff --git a/graphics/mapper/2.0/include/android/hardware/graphics/mapper/2.0/types.h b/graphics/mapper/2.0/include/android/hardware/graphics/mapper/2.0/types.h
deleted file mode 100644
index 4054b82..0000000
--- a/graphics/mapper/2.0/include/android/hardware/graphics/mapper/2.0/types.h
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * 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 ANDROID_HARDWARE_GRAPHICS_MAPPER_V2_0_TYPES_H
-#define ANDROID_HARDWARE_GRAPHICS_MAPPER_V2_0_TYPES_H
-
-#include <type_traits>
-
-#include <android/hardware/graphics/allocator/2.0/types.h>
-#include <android/hardware/graphics/common/1.0/types.h>
-
-namespace android {
-namespace hardware {
-namespace graphics {
-namespace mapper {
-namespace V2_0 {
-
-using android::hardware::graphics::allocator::V2_0::Error;
-using android::hardware::graphics::allocator::V2_0::ProducerUsage;
-using android::hardware::graphics::allocator::V2_0::ConsumerUsage;
-using android::hardware::graphics::common::V1_0::PixelFormat;
-
-/*
- * Structures for describing flexible YUVA/RGBA formats for consumption by
- * applications. Such flexible formats contain a plane for each component
- * (e.g. red, green, blue), where each plane is laid out in a grid-like
- * pattern occupying unique byte addresses and with consistent byte offsets
- * between neighboring pixels.
- *
- * The FlexLayout structure is used with any pixel format that can be
- * represented by it, such as:
- *
- * - PixelFormat::YCbCr_*_888
- * - PixelFormat::FLEX_RGB*_888
- * - PixelFormat::RGB[AX]_888[8],BGRA_8888,RGB_888
- * - PixelFormat::YV12,Y8,Y16,YCbCr_422_SP/I,YCrCb_420_SP
- * - even implementation defined formats that can be represented by the
- * structures
- *
- * Vertical increment (aka. row increment or stride) describes the distance in
- * bytes from the first pixel of one row to the first pixel of the next row
- * (below) for the component plane. This can be negative.
- *
- * Horizontal increment (aka. column or pixel increment) describes the
- * distance in bytes from one pixel to the next pixel (to the right) on the
- * same row for the component plane. This can be negative.
- *
- * Each plane can be subsampled either vertically or horizontally by a
- * power-of-two factor.
- *
- * The bit-depth of each component can be arbitrary, as long as the pixels are
- * laid out on whole bytes, in native byte-order, using the most significant
- * bits of each unit.
- */
-
-enum class FlexComponent : int32_t {
- Y = 1 << 0, /* luma */
- Cb = 1 << 1, /* chroma blue */
- Cr = 1 << 2, /* chroma red */
-
- R = 1 << 10, /* red */
- G = 1 << 11, /* green */
- B = 1 << 12, /* blue */
-
- A = 1 << 30, /* alpha */
-};
-
-inline FlexComponent operator|(FlexComponent lhs, FlexComponent rhs)
-{
- return static_cast<FlexComponent>(static_cast<int32_t>(lhs) |
- static_cast<int32_t>(rhs));
-}
-
-inline FlexComponent& operator|=(FlexComponent &lhs, FlexComponent rhs)
-{
- lhs = static_cast<FlexComponent>(static_cast<int32_t>(lhs) |
- static_cast<int32_t>(rhs));
- return lhs;
-}
-
-enum class FlexFormat : int32_t {
- /* not a flexible format */
- INVALID = 0x0,
-
- Y = static_cast<int32_t>(FlexComponent::Y),
- YCbCr = static_cast<int32_t>(FlexComponent::Y) |
- static_cast<int32_t>(FlexComponent::Cb) |
- static_cast<int32_t>(FlexComponent::Cr),
- YCbCrA = static_cast<int32_t>(YCbCr) |
- static_cast<int32_t>(FlexComponent::A),
- RGB = static_cast<int32_t>(FlexComponent::R) |
- static_cast<int32_t>(FlexComponent::G) |
- static_cast<int32_t>(FlexComponent::B),
- RGBA = static_cast<int32_t>(RGB) |
- static_cast<int32_t>(FlexComponent::A),
-};
-
-struct FlexPlane {
- /* pointer to the first byte of the top-left pixel of the plane. */
- uint8_t *topLeft;
-
- FlexComponent component;
-
- /*
- * bits allocated for the component in each pixel. Must be a positive
- * multiple of 8.
- */
- int32_t bitsPerComponent;
-
- /*
- * number of the most significant bits used in the format for this
- * component. Must be between 1 and bits_per_component, inclusive.
- */
- int32_t bitsUsed;
-
- /* horizontal increment */
- int32_t hIncrement;
- /* vertical increment */
- int32_t vIncrement;
-
- /* horizontal subsampling. Must be a positive power of 2. */
- int32_t hSubsampling;
- /* vertical subsampling. Must be a positive power of 2. */
- int32_t vSubsampling;
-};
-static_assert(std::is_pod<FlexPlane>::value, "FlexPlane is not POD");
-
-struct FlexLayout {
- /* the kind of flexible format */
- FlexFormat format;
-
- /* number of planes; 0 for FLEX_FORMAT_INVALID */
- uint32_t numPlanes;
-
- /*
- * a plane for each component; ordered in increasing component value order.
- * E.g. FLEX_FORMAT_RGBA maps 0 -> R, 1 -> G, etc.
- * Can be NULL for FLEX_FORMAT_INVALID
- */
- FlexPlane* planes;
-};
-static_assert(std::is_pod<FlexLayout>::value, "FlexLayout is not POD");
-
-typedef uint64_t BackingStore;
-
-} // namespace V2_0
-} // namespace mapper
-} // namespace graphics
-} // namespace hardware
-} // namespace android
-
-#endif /* ANDROID_HARDWARE_GRAPHICS_MAPPER_V2_0_TYPES_H */
diff --git a/graphics/mapper/2.0/types.hal b/graphics/mapper/2.0/types.hal
new file mode 100644
index 0000000..aa33141
--- /dev/null
+++ b/graphics/mapper/2.0/types.hal
@@ -0,0 +1,116 @@
+/*
+ * 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.graphics.mapper@2.0;
+
+/*
+ * Structures for describing flexible YUVA/RGBA formats for consumption by
+ * applications. Such flexible formats contain a plane for each component (e.g.
+ * red, green, blue), where each plane is laid out in a grid-like pattern
+ * occupying unique byte addresses and with consistent byte offsets between
+ * neighboring pixels.
+ *
+ * The FlexLayout structure is used with any pixel format that can be
+ * represented by it, such as:
+ * - PixelFormat::YCBCR_*_888
+ * - PixelFormat::FLEX_RGB*_888
+ * - PixelFormat::RGB[AX]_888[8],BGRA_8888,RGB_888
+ * - PixelFormat::YV12,Y8,Y16,YCBCR_422_SP/I,YCRCB_420_SP
+ * - even implementation defined formats that can be represented by
+ * the structures
+ *
+ * Vertical increment (aka. row increment or stride) describes the distance in
+ * bytes from the first pixel of one row to the first pixel of the next row
+ * (below) for the component plane. This can be negative.
+ *
+ * Horizontal increment (aka. column or pixel increment) describes the distance
+ * in bytes from one pixel to the next pixel (to the right) on the same row for
+ * the component plane. This can be negative.
+ *
+ * Each plane can be subsampled either vertically or horizontally by
+ * a power-of-two factor.
+ *
+ * The bit-depth of each component can be arbitrary, as long as the pixels are
+ * laid out on whole bytes, in native byte-order, using the most significant
+ * bits of each unit.
+ */
+
+enum FlexComponent : int32_t {
+ Y = 1 << 0, /* luma */
+ CB = 1 << 1, /* chroma blue */
+ CR = 1 << 2, /* chroma red */
+
+ R = 1 << 10, /* red */
+ G = 1 << 11, /* green */
+ B = 1 << 12, /* blue */
+
+ A = 1 << 30, /* alpha */
+};
+
+enum FlexFormat : int32_t {
+ /* not a flexible format */
+ INVALID = 0x0,
+
+ Y = FlexComponent:Y,
+ YCBCR = Y | FlexComponent:CB | FlexComponent:CR,
+ YCBCRA = YCBCR | FlexComponent:A,
+
+ RGB = FlexComponent:R | FlexComponent:G | FlexComponent:B,
+ RGBA = RGB | FlexComponent:A,
+};
+
+struct FlexPlane {
+ /* Pointer to the first byte of the top-left pixel of the plane. */
+ pointer topLeft;
+
+ FlexComponent component;
+
+ /*
+ * Bits allocated for the component in each pixel. Must be a positive
+ * multiple of 8.
+ */
+ int32_t bitsPerComponent;
+
+ /*
+ * Number of the most significant bits used in the format for this
+ * component. Must be between 1 and bitsPerComponent, inclusive.
+ */
+ int32_t bitsUsed;
+
+ /* Horizontal increment. */
+ int32_t hIncrement;
+ /* Vertical increment. */
+ int32_t vIncrement;
+ /* Horizontal subsampling. Must be a positive power of 2. */
+ int32_t hSubsampling;
+ /* Vertical subsampling. Must be a positive power of 2. */
+ int32_t vSubsampling;
+};
+
+struct FlexLayout {
+ /* The kind of flexible format. */
+ FlexFormat format;
+
+ /*
+ * A plane for each component; ordered in increasing component value
+ * order. E.g. FlexFormat::RGBA maps 0 -> R, 1 -> G, etc. Can have size 0
+ * for FlexFormat::INVALID.
+ */
+ vec<FlexPlane> planes;
+};
+
+/* Backing store ID of a buffer. See IMapper::getBackingStore. */
+typedef uint64_t BackingStore;
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/light/2.0/Android.bp b/light/2.0/Android.bp
index 60e8f8e..0ad131c 100644
--- a/light/2.0/Android.bp
+++ b/light/2.0/Android.bp
@@ -54,3 +54,106 @@
"android.hidl.base@1.0",
],
}
+
+genrule {
+ name: "android.hardware.light.vts.driver@2.0_genc++",
+ tools: ["hidl-gen", "vtsc"],
+ cmd: "$(location hidl-gen) -o $(genDir) -Lvts -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.light@2.0 && $(location vtsc) -mDRIVER -tSOURCE -b$(genDir) android/hardware/light/2.0/ $(genDir)/android/hardware/light/2.0/",
+ srcs: [
+ "types.hal",
+ "ILight.hal",
+ ],
+ out: [
+ "android/hardware/light/2.0/types.vts.cpp",
+ "android/hardware/light/2.0/Light.vts.cpp",
+ ],
+}
+
+genrule {
+ name: "android.hardware.light.vts.driver@2.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.light@2.0 && $(location vtsc) -mDRIVER -tHEADER -b$(genDir) android/hardware/light/2.0/ $(genDir)/android/hardware/light/2.0/",
+ srcs: [
+ "types.hal",
+ "ILight.hal",
+ ],
+ out: [
+ "android/hardware/light/2.0/types.vts.h",
+ "android/hardware/light/2.0/Light.vts.h",
+ ],
+}
+
+cc_library_shared {
+ name: "android.hardware.light.vts.driver@2.0",
+ generated_sources: ["android.hardware.light.vts.driver@2.0_genc++"],
+ generated_headers: ["android.hardware.light.vts.driver@2.0_genc++_headers"],
+ export_generated_headers: ["android.hardware.light.vts.driver@2.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.light@2.0",
+ ],
+ export_shared_lib_headers: [
+ "libhidlbase",
+ "libhidltransport",
+ "libhwbinder",
+ "libutils",
+ "android.hidl.base@1.0",
+ ],
+}
+
+genrule {
+ name: "android.hardware.light@2.0-ILight-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.light@2.0 && $(location vtsc) -mPROFILER -tSOURCE -b$(genDir) android/hardware/light/2.0/ $(genDir)/android/hardware/light/2.0/",
+ srcs: [
+ "ILight.hal",
+ "types.hal",
+ ],
+ out: [
+ "android/hardware/light/2.0/Light.vts.cpp",
+ "android/hardware/light/2.0/types.vts.cpp",
+ ],
+}
+
+genrule {
+ name: "android.hardware.light@2.0-ILight-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.light@2.0 && $(location vtsc) -mPROFILER -tHEADER -b$(genDir) android/hardware/light/2.0/ $(genDir)/android/hardware/light/2.0/",
+ srcs: [
+ "ILight.hal",
+ "types.hal",
+ ],
+ out: [
+ "android/hardware/light/2.0/Light.vts.h",
+ "android/hardware/light/2.0/types.vts.h",
+ ],
+}
+
+cc_library_shared {
+ name: "android.hardware.light@2.0-ILight-vts.profiler",
+ generated_sources: ["android.hardware.light@2.0-ILight-vts.profiler_genc++"],
+ generated_headers: ["android.hardware.light@2.0-ILight-vts.profiler_genc++_headers"],
+ export_generated_headers: ["android.hardware.light@2.0-ILight-vts.profiler_genc++_headers"],
+ shared_libs: [
+ "libbase",
+ "libhidlbase",
+ "libhidltransport",
+ "libvts_profiling",
+ "libvts_multidevice_proto",
+ "libprotobuf-cpp-full",
+ "android.hidl.base@1.0",
+ "android.hardware.light@2.0",
+ ],
+}
diff --git a/light/2.0/vts/Android.mk b/light/2.0/vts/Android.mk
index 0df4772..089503b 100644
--- a/light/2.0/vts/Android.mk
+++ b/light/2.0/vts/Android.mk
@@ -16,34 +16,4 @@
LOCAL_PATH := $(call my-dir)
-# build VTS driver for Light v2.0.
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libvts_driver_hidl_light@2.0
-
-LOCAL_SRC_FILES := \
- Light.vts \
- types.vts \
-
-LOCAL_SHARED_LIBRARIES += \
- android.hardware.light@2.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)
-
include $(call all-makefiles-under,$(LOCAL_PATH))
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/Android.bp b/memtrack/1.0/Android.bp
index b56ffeb..87342ef 100644
--- a/memtrack/1.0/Android.bp
+++ b/memtrack/1.0/Android.bp
@@ -54,3 +54,106 @@
"android.hidl.base@1.0",
],
}
+
+genrule {
+ name: "android.hardware.memtrack.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.memtrack@1.0 && $(location vtsc) -mDRIVER -tSOURCE -b$(genDir) android/hardware/memtrack/1.0/ $(genDir)/android/hardware/memtrack/1.0/",
+ srcs: [
+ "types.hal",
+ "IMemtrack.hal",
+ ],
+ out: [
+ "android/hardware/memtrack/1.0/types.vts.cpp",
+ "android/hardware/memtrack/1.0/Memtrack.vts.cpp",
+ ],
+}
+
+genrule {
+ name: "android.hardware.memtrack.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.memtrack@1.0 && $(location vtsc) -mDRIVER -tHEADER -b$(genDir) android/hardware/memtrack/1.0/ $(genDir)/android/hardware/memtrack/1.0/",
+ srcs: [
+ "types.hal",
+ "IMemtrack.hal",
+ ],
+ out: [
+ "android/hardware/memtrack/1.0/types.vts.h",
+ "android/hardware/memtrack/1.0/Memtrack.vts.h",
+ ],
+}
+
+cc_library_shared {
+ name: "android.hardware.memtrack.vts.driver@1.0",
+ generated_sources: ["android.hardware.memtrack.vts.driver@1.0_genc++"],
+ generated_headers: ["android.hardware.memtrack.vts.driver@1.0_genc++_headers"],
+ export_generated_headers: ["android.hardware.memtrack.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.memtrack@1.0",
+ ],
+ export_shared_lib_headers: [
+ "libhidlbase",
+ "libhidltransport",
+ "libhwbinder",
+ "libutils",
+ "android.hidl.base@1.0",
+ ],
+}
+
+genrule {
+ name: "android.hardware.memtrack@1.0-IMemtrack-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.memtrack@1.0 && $(location vtsc) -mPROFILER -tSOURCE -b$(genDir) android/hardware/memtrack/1.0/ $(genDir)/android/hardware/memtrack/1.0/",
+ srcs: [
+ "IMemtrack.hal",
+ "types.hal",
+ ],
+ out: [
+ "android/hardware/memtrack/1.0/Memtrack.vts.cpp",
+ "android/hardware/memtrack/1.0/types.vts.cpp",
+ ],
+}
+
+genrule {
+ name: "android.hardware.memtrack@1.0-IMemtrack-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.memtrack@1.0 && $(location vtsc) -mPROFILER -tHEADER -b$(genDir) android/hardware/memtrack/1.0/ $(genDir)/android/hardware/memtrack/1.0/",
+ srcs: [
+ "IMemtrack.hal",
+ "types.hal",
+ ],
+ out: [
+ "android/hardware/memtrack/1.0/Memtrack.vts.h",
+ "android/hardware/memtrack/1.0/types.vts.h",
+ ],
+}
+
+cc_library_shared {
+ name: "android.hardware.memtrack@1.0-IMemtrack-vts.profiler",
+ generated_sources: ["android.hardware.memtrack@1.0-IMemtrack-vts.profiler_genc++"],
+ generated_headers: ["android.hardware.memtrack@1.0-IMemtrack-vts.profiler_genc++_headers"],
+ export_generated_headers: ["android.hardware.memtrack@1.0-IMemtrack-vts.profiler_genc++_headers"],
+ shared_libs: [
+ "libbase",
+ "libhidlbase",
+ "libhidltransport",
+ "libvts_profiling",
+ "libvts_multidevice_proto",
+ "libprotobuf-cpp-full",
+ "android.hidl.base@1.0",
+ "android.hardware.memtrack@1.0",
+ ],
+}
diff --git a/memtrack/1.0/vts/Android.mk b/memtrack/1.0/vts/Android.mk
index 8a5ceb1..397f946 100644
--- a/memtrack/1.0/vts/Android.mk
+++ b/memtrack/1.0/vts/Android.mk
@@ -16,65 +16,6 @@
LOCAL_PATH := $(call my-dir)
-# build VTS driver for memtrack v1.0.
-include $(CLEAR_VARS)
+include $(call all-subdir-makefiles)
-LOCAL_MODULE := libvts_driver_hidl_memtrack@1.0
-
-LOCAL_SRC_FILES := \
- Memtrack.vts \
- types.vts \
-
-LOCAL_SHARED_LIBRARIES += \
- android.hardware.memtrack@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 memtrack.
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libvts_profiler_hidl_memtrack@1.0
-
-LOCAL_SRC_FILES := \
- Memtrack.vts \
- types.vts \
-
-LOCAL_C_INCLUDES += \
- test/vts/drivers/libprofiling \
-
-LOCAL_VTS_MODE := PROFILER
-
-LOCAL_SHARED_LIBRARIES := \
- android.hardware.memtrack@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 $(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 0c70f10..af571f3 100644
--- a/nfc/1.0/Android.bp
+++ b/nfc/1.0/Android.bp
@@ -66,7 +66,7 @@
genrule {
name: "android.hardware.nfc.vts.driver@1.0_genc++",
tools: ["hidl-gen", "vtsc"],
- cmd: "$(location hidl-gen) -o $(genDir) -L vts -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.nfc@1.0 && $(location vtsc) -mDRIVER -tSOURCE -b$(genDir) android/hardware/nfc/1.0/ $(genDir)/android/hardware/nfc/1.0/",
+ cmd: "$(location hidl-gen) -o $(genDir) -Lvts -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.nfc@1.0 && $(location vtsc) -mDRIVER -tSOURCE -b$(genDir) android/hardware/nfc/1.0/ $(genDir)/android/hardware/nfc/1.0/",
srcs: [
"types.hal",
"INfc.hal",
@@ -82,7 +82,7 @@
genrule {
name: "android.hardware.nfc.vts.driver@1.0_genc++_headers",
tools: ["hidl-gen", "vtsc"],
- cmd: "$(location hidl-gen) -o $(genDir) -L vts -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.nfc@1.0 && $(location vtsc) -mDRIVER -tHEADER -b$(genDir) android/hardware/nfc/1.0/ $(genDir)/android/hardware/nfc/1.0/",
+ cmd: "$(location hidl-gen) -o $(genDir) -Lvts -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.nfc@1.0 && $(location vtsc) -mDRIVER -tHEADER -b$(genDir) android/hardware/nfc/1.0/ $(genDir)/android/hardware/nfc/1.0/",
srcs: [
"types.hal",
"INfc.hal",
@@ -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/Android.bp b/power/1.0/Android.bp
index 3503f0e..8643139 100644
--- a/power/1.0/Android.bp
+++ b/power/1.0/Android.bp
@@ -54,3 +54,106 @@
"android.hidl.base@1.0",
],
}
+
+genrule {
+ name: "android.hardware.power.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.power@1.0 && $(location vtsc) -mDRIVER -tSOURCE -b$(genDir) android/hardware/power/1.0/ $(genDir)/android/hardware/power/1.0/",
+ srcs: [
+ "types.hal",
+ "IPower.hal",
+ ],
+ out: [
+ "android/hardware/power/1.0/types.vts.cpp",
+ "android/hardware/power/1.0/Power.vts.cpp",
+ ],
+}
+
+genrule {
+ name: "android.hardware.power.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.power@1.0 && $(location vtsc) -mDRIVER -tHEADER -b$(genDir) android/hardware/power/1.0/ $(genDir)/android/hardware/power/1.0/",
+ srcs: [
+ "types.hal",
+ "IPower.hal",
+ ],
+ out: [
+ "android/hardware/power/1.0/types.vts.h",
+ "android/hardware/power/1.0/Power.vts.h",
+ ],
+}
+
+cc_library_shared {
+ name: "android.hardware.power.vts.driver@1.0",
+ generated_sources: ["android.hardware.power.vts.driver@1.0_genc++"],
+ generated_headers: ["android.hardware.power.vts.driver@1.0_genc++_headers"],
+ export_generated_headers: ["android.hardware.power.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.power@1.0",
+ ],
+ export_shared_lib_headers: [
+ "libhidlbase",
+ "libhidltransport",
+ "libhwbinder",
+ "libutils",
+ "android.hidl.base@1.0",
+ ],
+}
+
+genrule {
+ name: "android.hardware.power@1.0-IPower-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.power@1.0 && $(location vtsc) -mPROFILER -tSOURCE -b$(genDir) android/hardware/power/1.0/ $(genDir)/android/hardware/power/1.0/",
+ srcs: [
+ "IPower.hal",
+ "types.hal",
+ ],
+ out: [
+ "android/hardware/power/1.0/Power.vts.cpp",
+ "android/hardware/power/1.0/types.vts.cpp",
+ ],
+}
+
+genrule {
+ name: "android.hardware.power@1.0-IPower-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.power@1.0 && $(location vtsc) -mPROFILER -tHEADER -b$(genDir) android/hardware/power/1.0/ $(genDir)/android/hardware/power/1.0/",
+ srcs: [
+ "IPower.hal",
+ "types.hal",
+ ],
+ out: [
+ "android/hardware/power/1.0/Power.vts.h",
+ "android/hardware/power/1.0/types.vts.h",
+ ],
+}
+
+cc_library_shared {
+ name: "android.hardware.power@1.0-IPower-vts.profiler",
+ generated_sources: ["android.hardware.power@1.0-IPower-vts.profiler_genc++"],
+ generated_headers: ["android.hardware.power@1.0-IPower-vts.profiler_genc++_headers"],
+ export_generated_headers: ["android.hardware.power@1.0-IPower-vts.profiler_genc++_headers"],
+ shared_libs: [
+ "libbase",
+ "libhidlbase",
+ "libhidltransport",
+ "libvts_profiling",
+ "libvts_multidevice_proto",
+ "libprotobuf-cpp-full",
+ "android.hidl.base@1.0",
+ "android.hardware.power@1.0",
+ ],
+}
diff --git a/power/1.0/vts/Android.mk b/power/1.0/vts/Android.mk
index 4164baf..df5dac8 100644
--- a/power/1.0/vts/Android.mk
+++ b/power/1.0/vts/Android.mk
@@ -16,66 +16,4 @@
LOCAL_PATH := $(call my-dir)
-# build VTS driver for Power v1.0.
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libvts_driver_hidl_power@1.0
-
-LOCAL_SRC_FILES := \
- Power.vts \
- types.vts \
-
-LOCAL_SHARED_LIBRARIES += \
- android.hardware.power@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 power.
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libvts_profiler_hidl_power@1.0
-
-LOCAL_SRC_FILES := \
- Power.vts \
- types.vts \
-
-LOCAL_C_INCLUDES += \
- test/vts/drivers/libprofiling \
-
-LOCAL_VTS_MODE := PROFILER
-
-LOCAL_SHARED_LIBRARIES := \
- android.hardware.power@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)
\ No newline at end of file
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/radio/1.0/ISapCallback.hal b/radio/1.0/ISapCallback.hal
index 5129648..6d80d6c 100644
--- a/radio/1.0/ISapCallback.hal
+++ b/radio/1.0/ISapCallback.hal
@@ -46,7 +46,6 @@
* TRANSFER_APDU_RESP from SAP 1.1 spec 5.1.7
*
* @param token Id to match req-resp. Value must match the one in req.
- * @param type APDU command type
* @param resultCode ResultCode to indicate if command was processed correctly
* Possible values:
* SapResultCode:SUCCESS,
@@ -58,7 +57,6 @@
* occurred.
*/
oneway apduResponse(int32_t token,
- SapApduType type,
SapResultCode resultCode,
vec<uint8_t> apduRsp);
@@ -123,7 +121,7 @@
* Possible values:
* SapResultCode:SUCCESS,
* SapResultCode:GENERIC_FAILURE
- * SapResultCode:CARD_ALREADY_POWERED_ON
+ * SapResultCode:DATA_NOT_AVAILABLE
* @param cardReaderStatus Card Reader Status coded as described in 3GPP TS 11.14 Section 12.33
* and TS 31.111 Section 8.33
*/
diff --git a/sensors/1.0/Android.bp b/sensors/1.0/Android.bp
index ed65265..b5ee36a 100644
--- a/sensors/1.0/Android.bp
+++ b/sensors/1.0/Android.bp
@@ -54,3 +54,106 @@
"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",
+ ],
+}
+
+genrule {
+ name: "android.hardware.sensors@1.0-ISensors-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.sensors@1.0 && $(location vtsc) -mPROFILER -tSOURCE -b$(genDir) android/hardware/sensors/1.0/ $(genDir)/android/hardware/sensors/1.0/",
+ srcs: [
+ "ISensors.hal",
+ "types.hal",
+ ],
+ out: [
+ "android/hardware/sensors/1.0/Sensors.vts.cpp",
+ "android/hardware/sensors/1.0/types.vts.cpp",
+ ],
+}
+
+genrule {
+ name: "android.hardware.sensors@1.0-ISensors-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.sensors@1.0 && $(location vtsc) -mPROFILER -tHEADER -b$(genDir) android/hardware/sensors/1.0/ $(genDir)/android/hardware/sensors/1.0/",
+ srcs: [
+ "ISensors.hal",
+ "types.hal",
+ ],
+ out: [
+ "android/hardware/sensors/1.0/Sensors.vts.h",
+ "android/hardware/sensors/1.0/types.vts.h",
+ ],
+}
+
+cc_library_shared {
+ name: "android.hardware.sensors@1.0-ISensors-vts.profiler",
+ generated_sources: ["android.hardware.sensors@1.0-ISensors-vts.profiler_genc++"],
+ generated_headers: ["android.hardware.sensors@1.0-ISensors-vts.profiler_genc++_headers"],
+ export_generated_headers: ["android.hardware.sensors@1.0-ISensors-vts.profiler_genc++_headers"],
+ shared_libs: [
+ "libbase",
+ "libhidlbase",
+ "libhidltransport",
+ "libvts_profiling",
+ "libvts_multidevice_proto",
+ "libprotobuf-cpp-full",
+ "android.hidl.base@1.0",
+ "android.hardware.sensors@1.0",
+ ],
+}
diff --git a/sensors/1.0/vts/Android.mk b/sensors/1.0/vts/Android.mk
index df8d66f..e22fba7 100644
--- a/sensors/1.0/vts/Android.mk
+++ b/sensors/1.0/vts/Android.mk
@@ -16,68 +16,5 @@
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)
-
-LOCAL_MODULE := libvts_profiler_hidl_sensors@1.0
-
-LOCAL_SRC_FILES := \
- Sensors.vts \
- types.vts \
-
-LOCAL_C_INCLUDES += \
- test/vts/drivers/libprofiling \
-
-LOCAL_VTS_MODE := PROFILER
-
-LOCAL_SHARED_LIBRARIES := \
- android.hardware.sensors@1.0 \
- libbase \
- libutils \
- libcutils \
- liblog \
- libhidlbase \
- libhidltransport \
- libhwbinder \
- libprotobuf-cpp-full \
- libvts_common \
- libvts_multidevice_proto \
- libvts_profiling \
-
-LOCAL_PROTOC_OPTIMIZE_TYPE := full
-
-include $(BUILD_SHARED_LIBRARY)
-
# include hidl test makefiles
include $(LOCAL_PATH)/functional/vts/testcases/hal/sensors/hidl/Android.mk
-
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/Android.bp b/thermal/1.0/Android.bp
index b887f16..f2c60da 100644
--- a/thermal/1.0/Android.bp
+++ b/thermal/1.0/Android.bp
@@ -54,3 +54,106 @@
"android.hidl.base@1.0",
],
}
+
+genrule {
+ name: "android.hardware.thermal.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.thermal@1.0 && $(location vtsc) -mDRIVER -tSOURCE -b$(genDir) android/hardware/thermal/1.0/ $(genDir)/android/hardware/thermal/1.0/",
+ srcs: [
+ "types.hal",
+ "IThermal.hal",
+ ],
+ out: [
+ "android/hardware/thermal/1.0/types.vts.cpp",
+ "android/hardware/thermal/1.0/Thermal.vts.cpp",
+ ],
+}
+
+genrule {
+ name: "android.hardware.thermal.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.thermal@1.0 && $(location vtsc) -mDRIVER -tHEADER -b$(genDir) android/hardware/thermal/1.0/ $(genDir)/android/hardware/thermal/1.0/",
+ srcs: [
+ "types.hal",
+ "IThermal.hal",
+ ],
+ out: [
+ "android/hardware/thermal/1.0/types.vts.h",
+ "android/hardware/thermal/1.0/Thermal.vts.h",
+ ],
+}
+
+cc_library_shared {
+ name: "android.hardware.thermal.vts.driver@1.0",
+ generated_sources: ["android.hardware.thermal.vts.driver@1.0_genc++"],
+ generated_headers: ["android.hardware.thermal.vts.driver@1.0_genc++_headers"],
+ export_generated_headers: ["android.hardware.thermal.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.thermal@1.0",
+ ],
+ export_shared_lib_headers: [
+ "libhidlbase",
+ "libhidltransport",
+ "libhwbinder",
+ "libutils",
+ "android.hidl.base@1.0",
+ ],
+}
+
+genrule {
+ name: "android.hardware.thermal@1.0-IThermal-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.thermal@1.0 && $(location vtsc) -mPROFILER -tSOURCE -b$(genDir) android/hardware/thermal/1.0/ $(genDir)/android/hardware/thermal/1.0/",
+ srcs: [
+ "IThermal.hal",
+ "types.hal",
+ ],
+ out: [
+ "android/hardware/thermal/1.0/Thermal.vts.cpp",
+ "android/hardware/thermal/1.0/types.vts.cpp",
+ ],
+}
+
+genrule {
+ name: "android.hardware.thermal@1.0-IThermal-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.thermal@1.0 && $(location vtsc) -mPROFILER -tHEADER -b$(genDir) android/hardware/thermal/1.0/ $(genDir)/android/hardware/thermal/1.0/",
+ srcs: [
+ "IThermal.hal",
+ "types.hal",
+ ],
+ out: [
+ "android/hardware/thermal/1.0/Thermal.vts.h",
+ "android/hardware/thermal/1.0/types.vts.h",
+ ],
+}
+
+cc_library_shared {
+ name: "android.hardware.thermal@1.0-IThermal-vts.profiler",
+ generated_sources: ["android.hardware.thermal@1.0-IThermal-vts.profiler_genc++"],
+ generated_headers: ["android.hardware.thermal@1.0-IThermal-vts.profiler_genc++_headers"],
+ export_generated_headers: ["android.hardware.thermal@1.0-IThermal-vts.profiler_genc++_headers"],
+ shared_libs: [
+ "libbase",
+ "libhidlbase",
+ "libhidltransport",
+ "libvts_profiling",
+ "libvts_multidevice_proto",
+ "libprotobuf-cpp-full",
+ "android.hidl.base@1.0",
+ "android.hardware.thermal@1.0",
+ ],
+}
diff --git a/thermal/1.0/vts/Android.mk b/thermal/1.0/vts/Android.mk
index ef926fe..60cc723 100644
--- a/thermal/1.0/vts/Android.mk
+++ b/thermal/1.0/vts/Android.mk
@@ -16,73 +16,4 @@
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)
-
-LOCAL_MODULE := libvts_profiler_hidl_thermal@1.0
-
-LOCAL_SRC_FILES := \
- Thermal.vts \
- types.vts \
-
-LOCAL_C_INCLUDES += \
- test/vts/drivers/libprofiling \
-
-LOCAL_VTS_MODE := PROFILER
-
-LOCAL_SHARED_LIBRARIES := \
- android.hardware.thermal@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/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/Android.bp b/tv/cec/1.0/Android.bp
index 53b1ce8..4c98cb9 100644
--- a/tv/cec/1.0/Android.bp
+++ b/tv/cec/1.0/Android.bp
@@ -62,3 +62,155 @@
"android.hidl.base@1.0",
],
}
+
+genrule {
+ name: "android.hardware.tv.cec.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.tv.cec@1.0 && $(location vtsc) -mDRIVER -tSOURCE -b$(genDir) android/hardware/tv/cec/1.0/ $(genDir)/android/hardware/tv/cec/1.0/",
+ srcs: [
+ "types.hal",
+ "IHdmiCec.hal",
+ "IHdmiCecCallback.hal",
+ ],
+ out: [
+ "android/hardware/tv/cec/1.0/types.vts.cpp",
+ "android/hardware/tv/cec/1.0/HdmiCec.vts.cpp",
+ "android/hardware/tv/cec/1.0/HdmiCecCallback.vts.cpp",
+ ],
+}
+
+genrule {
+ name: "android.hardware.tv.cec.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.tv.cec@1.0 && $(location vtsc) -mDRIVER -tHEADER -b$(genDir) android/hardware/tv/cec/1.0/ $(genDir)/android/hardware/tv/cec/1.0/",
+ srcs: [
+ "types.hal",
+ "IHdmiCec.hal",
+ "IHdmiCecCallback.hal",
+ ],
+ out: [
+ "android/hardware/tv/cec/1.0/types.vts.h",
+ "android/hardware/tv/cec/1.0/HdmiCec.vts.h",
+ "android/hardware/tv/cec/1.0/HdmiCecCallback.vts.h",
+ ],
+}
+
+cc_library_shared {
+ name: "android.hardware.tv.cec.vts.driver@1.0",
+ generated_sources: ["android.hardware.tv.cec.vts.driver@1.0_genc++"],
+ generated_headers: ["android.hardware.tv.cec.vts.driver@1.0_genc++_headers"],
+ export_generated_headers: ["android.hardware.tv.cec.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.tv.cec@1.0",
+ ],
+ export_shared_lib_headers: [
+ "libhidlbase",
+ "libhidltransport",
+ "libhwbinder",
+ "libutils",
+ "android.hidl.base@1.0",
+ ],
+}
+
+genrule {
+ name: "android.hardware.tv.cec@1.0-IHdmiCec-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.tv.cec@1.0 && $(location vtsc) -mPROFILER -tSOURCE -b$(genDir) android/hardware/tv/cec/1.0/ $(genDir)/android/hardware/tv/cec/1.0/",
+ srcs: [
+ "IHdmiCec.hal",
+ "types.hal",
+ ],
+ out: [
+ "android/hardware/tv/cec/1.0/HdmiCec.vts.cpp",
+ "android/hardware/tv/cec/1.0/types.vts.cpp",
+ ],
+}
+
+genrule {
+ name: "android.hardware.tv.cec@1.0-IHdmiCec-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.tv.cec@1.0 && $(location vtsc) -mPROFILER -tHEADER -b$(genDir) android/hardware/tv/cec/1.0/ $(genDir)/android/hardware/tv/cec/1.0/",
+ srcs: [
+ "IHdmiCec.hal",
+ "types.hal",
+ ],
+ out: [
+ "android/hardware/tv/cec/1.0/HdmiCec.vts.h",
+ "android/hardware/tv/cec/1.0/types.vts.h",
+ ],
+}
+
+cc_library_shared {
+ name: "android.hardware.tv.cec@1.0-IHdmiCec-vts.profiler",
+ generated_sources: ["android.hardware.tv.cec@1.0-IHdmiCec-vts.profiler_genc++"],
+ generated_headers: ["android.hardware.tv.cec@1.0-IHdmiCec-vts.profiler_genc++_headers"],
+ export_generated_headers: ["android.hardware.tv.cec@1.0-IHdmiCec-vts.profiler_genc++_headers"],
+ shared_libs: [
+ "libbase",
+ "libhidlbase",
+ "libhidltransport",
+ "libvts_profiling",
+ "libvts_multidevice_proto",
+ "libprotobuf-cpp-full",
+ "android.hidl.base@1.0",
+ "android.hardware.tv.cec@1.0",
+ ],
+}
+
+genrule {
+ name: "android.hardware.tv.cec@1.0-IHdmiCecCallback-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.tv.cec@1.0 && $(location vtsc) -mPROFILER -tSOURCE -b$(genDir) android/hardware/tv/cec/1.0/ $(genDir)/android/hardware/tv/cec/1.0/",
+ srcs: [
+ "IHdmiCecCallback.hal",
+ "types.hal",
+ ],
+ out: [
+ "android/hardware/tv/cec/1.0/HdmiCecCallback.vts.cpp",
+ "android/hardware/tv/cec/1.0/types.vts.cpp",
+ ],
+}
+
+genrule {
+ name: "android.hardware.tv.cec@1.0-IHdmiCecCallback-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.tv.cec@1.0 && $(location vtsc) -mPROFILER -tHEADER -b$(genDir) android/hardware/tv/cec/1.0/ $(genDir)/android/hardware/tv/cec/1.0/",
+ srcs: [
+ "IHdmiCecCallback.hal",
+ "types.hal",
+ ],
+ out: [
+ "android/hardware/tv/cec/1.0/HdmiCecCallback.vts.h",
+ "android/hardware/tv/cec/1.0/types.vts.h",
+ ],
+}
+
+cc_library_shared {
+ name: "android.hardware.tv.cec@1.0-IHdmiCecCallback-vts.profiler",
+ generated_sources: ["android.hardware.tv.cec@1.0-IHdmiCecCallback-vts.profiler_genc++"],
+ generated_headers: ["android.hardware.tv.cec@1.0-IHdmiCecCallback-vts.profiler_genc++_headers"],
+ export_generated_headers: ["android.hardware.tv.cec@1.0-IHdmiCecCallback-vts.profiler_genc++_headers"],
+ shared_libs: [
+ "libbase",
+ "libhidlbase",
+ "libhidltransport",
+ "libvts_profiling",
+ "libvts_multidevice_proto",
+ "libprotobuf-cpp-full",
+ "android.hidl.base@1.0",
+ "android.hardware.tv.cec@1.0",
+ ],
+}
diff --git a/tv/cec/1.0/vts/Android.mk b/tv/cec/1.0/vts/Android.mk
index d25fb31..60cc723 100644
--- a/tv/cec/1.0/vts/Android.mk
+++ b/tv/cec/1.0/vts/Android.mk
@@ -16,105 +16,4 @@
LOCAL_PATH := $(call my-dir)
-# build VTS driver for TvCec v1.0.
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libvts_driver_hidl_tv_cec@1.0
-
-LOCAL_SRC_FILES := \
- HdmiCec.vts \
- HdmiCecCallback.vts \
- types.vts \
-
-LOCAL_SHARED_LIBRARIES += \
- android.hardware.tv.cec@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 HdmiCec
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libvts_profiler_hidl_tv_cec@1.0
-
-LOCAL_SRC_FILES := \
- HdmiCec.vts \
- types.vts \
-
-LOCAL_C_INCLUDES += \
- test/vts/drivers/libprofiling \
-
-LOCAL_VTS_MODE := PROFILER
-
-LOCAL_SHARED_LIBRARIES += \
- android.hardware.tv.cec@1.0 \
- libbase \
- libcutils \
- liblog \
- libhidlbase \
- libhidltransport \
- libhwbinder \
- libprotobuf-cpp-full \
- libvts_common \
- libvts_multidevice_proto \
- libvts_profiling \
- libutils \
-
-LOCAL_PROTOC_OPTIMIZE_TYPE := full
-
-LOCAL_MULTILIB := both
-
-include $(BUILD_SHARED_LIBRARY)
-
-
-# build VTS profiler for HdmiCecCallback
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libvts_profiler_hidl_tv_cec_callback_@1.0
-
-LOCAL_SRC_FILES := \
- HdmiCecCallback.vts \
- types.vts \
-
-LOCAL_C_INCLUDES += \
- test/vts/drivers/libprofiling \
-
-LOCAL_VTS_MODE := PROFILER
-
-LOCAL_SHARED_LIBRARIES += \
- android.hardware.tv.cec@1.0 \
- libbase \
- libcutils \
- liblog \
- libhidlbase \
- libhidltransport \
- libhwbinder \
- libprotobuf-cpp-full \
- libvts_common \
- libvts_multidevice_proto \
- libvts_profiling \
- libutils \
-
-LOCAL_PROTOC_OPTIMIZE_TYPE := full
-
-LOCAL_MULTILIB := both
-
-include $(BUILD_SHARED_LIBRARY)
-
-include $(call all-makefiles-under,$(LOCAL_PATH))
\ No newline at end of file
+include $(call all-subdir-makefiles)
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.bp b/vehicle/2.0/Android.bp
index 6c96d3f..04dfd5a 100644
--- a/vehicle/2.0/Android.bp
+++ b/vehicle/2.0/Android.bp
@@ -62,3 +62,155 @@
"android.hidl.base@1.0",
],
}
+
+genrule {
+ name: "android.hardware.vehicle.vts.driver@2.0_genc++",
+ tools: ["hidl-gen", "vtsc"],
+ cmd: "$(location hidl-gen) -o $(genDir) -Lvts -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.vehicle@2.0 && $(location vtsc) -mDRIVER -tSOURCE -b$(genDir) android/hardware/vehicle/2.0/ $(genDir)/android/hardware/vehicle/2.0/",
+ srcs: [
+ "types.hal",
+ "IVehicle.hal",
+ "IVehicleCallback.hal",
+ ],
+ out: [
+ "android/hardware/vehicle/2.0/types.vts.cpp",
+ "android/hardware/vehicle/2.0/Vehicle.vts.cpp",
+ "android/hardware/vehicle/2.0/VehicleCallback.vts.cpp",
+ ],
+}
+
+genrule {
+ name: "android.hardware.vehicle.vts.driver@2.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.vehicle@2.0 && $(location vtsc) -mDRIVER -tHEADER -b$(genDir) android/hardware/vehicle/2.0/ $(genDir)/android/hardware/vehicle/2.0/",
+ srcs: [
+ "types.hal",
+ "IVehicle.hal",
+ "IVehicleCallback.hal",
+ ],
+ out: [
+ "android/hardware/vehicle/2.0/types.vts.h",
+ "android/hardware/vehicle/2.0/Vehicle.vts.h",
+ "android/hardware/vehicle/2.0/VehicleCallback.vts.h",
+ ],
+}
+
+cc_library_shared {
+ name: "android.hardware.vehicle.vts.driver@2.0",
+ generated_sources: ["android.hardware.vehicle.vts.driver@2.0_genc++"],
+ generated_headers: ["android.hardware.vehicle.vts.driver@2.0_genc++_headers"],
+ export_generated_headers: ["android.hardware.vehicle.vts.driver@2.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.vehicle@2.0",
+ ],
+ export_shared_lib_headers: [
+ "libhidlbase",
+ "libhidltransport",
+ "libhwbinder",
+ "libutils",
+ "android.hidl.base@1.0",
+ ],
+}
+
+genrule {
+ name: "android.hardware.vehicle@2.0-IVehicle-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.vehicle@2.0 && $(location vtsc) -mPROFILER -tSOURCE -b$(genDir) android/hardware/vehicle/2.0/ $(genDir)/android/hardware/vehicle/2.0/",
+ srcs: [
+ "IVehicle.hal",
+ "types.hal",
+ ],
+ out: [
+ "android/hardware/vehicle/2.0/Vehicle.vts.cpp",
+ "android/hardware/vehicle/2.0/types.vts.cpp",
+ ],
+}
+
+genrule {
+ name: "android.hardware.vehicle@2.0-IVehicle-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.vehicle@2.0 && $(location vtsc) -mPROFILER -tHEADER -b$(genDir) android/hardware/vehicle/2.0/ $(genDir)/android/hardware/vehicle/2.0/",
+ srcs: [
+ "IVehicle.hal",
+ "types.hal",
+ ],
+ out: [
+ "android/hardware/vehicle/2.0/Vehicle.vts.h",
+ "android/hardware/vehicle/2.0/types.vts.h",
+ ],
+}
+
+cc_library_shared {
+ name: "android.hardware.vehicle@2.0-IVehicle-vts.profiler",
+ generated_sources: ["android.hardware.vehicle@2.0-IVehicle-vts.profiler_genc++"],
+ generated_headers: ["android.hardware.vehicle@2.0-IVehicle-vts.profiler_genc++_headers"],
+ export_generated_headers: ["android.hardware.vehicle@2.0-IVehicle-vts.profiler_genc++_headers"],
+ shared_libs: [
+ "libbase",
+ "libhidlbase",
+ "libhidltransport",
+ "libvts_profiling",
+ "libvts_multidevice_proto",
+ "libprotobuf-cpp-full",
+ "android.hidl.base@1.0",
+ "android.hardware.vehicle@2.0",
+ ],
+}
+
+genrule {
+ name: "android.hardware.vehicle@2.0-IVehicleCallback-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.vehicle@2.0 && $(location vtsc) -mPROFILER -tSOURCE -b$(genDir) android/hardware/vehicle/2.0/ $(genDir)/android/hardware/vehicle/2.0/",
+ srcs: [
+ "IVehicleCallback.hal",
+ "types.hal",
+ ],
+ out: [
+ "android/hardware/vehicle/2.0/VehicleCallback.vts.cpp",
+ "android/hardware/vehicle/2.0/types.vts.cpp",
+ ],
+}
+
+genrule {
+ name: "android.hardware.vehicle@2.0-IVehicleCallback-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.vehicle@2.0 && $(location vtsc) -mPROFILER -tHEADER -b$(genDir) android/hardware/vehicle/2.0/ $(genDir)/android/hardware/vehicle/2.0/",
+ srcs: [
+ "IVehicleCallback.hal",
+ "types.hal",
+ ],
+ out: [
+ "android/hardware/vehicle/2.0/VehicleCallback.vts.h",
+ "android/hardware/vehicle/2.0/types.vts.h",
+ ],
+}
+
+cc_library_shared {
+ name: "android.hardware.vehicle@2.0-IVehicleCallback-vts.profiler",
+ generated_sources: ["android.hardware.vehicle@2.0-IVehicleCallback-vts.profiler_genc++"],
+ generated_headers: ["android.hardware.vehicle@2.0-IVehicleCallback-vts.profiler_genc++_headers"],
+ export_generated_headers: ["android.hardware.vehicle@2.0-IVehicleCallback-vts.profiler_genc++_headers"],
+ shared_libs: [
+ "libbase",
+ "libhidlbase",
+ "libhidltransport",
+ "libvts_profiling",
+ "libvts_multidevice_proto",
+ "libprotobuf-cpp-full",
+ "android.hidl.base@1.0",
+ "android.hardware.vehicle@2.0",
+ ],
+}
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/Android.mk b/vehicle/2.0/vts/Android.mk
index 8370067..df5dac8 100644
--- a/vehicle/2.0/vts/Android.mk
+++ b/vehicle/2.0/vts/Android.mk
@@ -16,105 +16,4 @@
LOCAL_PATH := $(call my-dir)
-# build VTS driver for Vehicle v2.0.
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libvts_driver_hidl_vehicle@2.0
-
-LOCAL_SRC_FILES := \
- Vehicle.vts \
- VehicleCallback.vts \
- types.vts \
-
-LOCAL_SHARED_LIBRARIES += \
- android.hardware.vehicle@2.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 Vehicle.
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libvts_profiler_hidl_vehicle@2.0
-
-LOCAL_SRC_FILES := \
- Vehicle.vts \
- types.vts \
-
-LOCAL_C_INCLUDES += \
- test/vts/drivers/libprofiling \
-
-LOCAL_VTS_MODE := PROFILER
-
-LOCAL_SHARED_LIBRARIES := \
- android.hardware.vehicle@2.0 \
- libbase \
- libcutils \
- liblog \
- libhidlbase \
- libhidltransport \
- libhwbinder \
- libprotobuf-cpp-full \
- libvts_common \
- libvts_multidevice_proto \
- libvts_profiling \
- libutils \
-
-LOCAL_PROTOC_OPTIMIZE_TYPE := full
-
-LOCAL_MULTILIB := both
-
-include $(BUILD_SHARED_LIBRARY)
-
-
-# build profiler for VehicleCallback.
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libvts_profiler_hidl_vehicle_callback_@2.0
-
-LOCAL_SRC_FILES := \
- Vehicle.vts \
- types.vts \
-
-LOCAL_C_INCLUDES += \
- test/vts/drivers/libprofiling \
-
-LOCAL_VTS_MODE := PROFILER
-
-LOCAL_SHARED_LIBRARIES := \
- android.hardware.vehicle@2.0 \
- libbase \
- libcutils \
- liblog \
- libhidlbase \
- libhidltransport \
- libhwbinder \
- libprotobuf-cpp-full \
- libvts_common \
- libvts_multidevice_proto \
- libvts_profiling \
- libutils \
-
-LOCAL_PROTOC_OPTIMIZE_TYPE := full
-
-LOCAL_MULTILIB := both
-
-include $(BUILD_SHARED_LIBRARY)
-
-include $(call all-makefiles-under,$(LOCAL_PATH))
\ No newline at end of file
+include $(call all-subdir-makefiles)
\ No newline at end of file
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/Android.bp b/vibrator/1.0/Android.bp
index 75a3bfa..cea74bb 100644
--- a/vibrator/1.0/Android.bp
+++ b/vibrator/1.0/Android.bp
@@ -54,3 +54,106 @@
"android.hidl.base@1.0",
],
}
+
+genrule {
+ name: "android.hardware.vibrator.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.vibrator@1.0 && $(location vtsc) -mDRIVER -tSOURCE -b$(genDir) android/hardware/vibrator/1.0/ $(genDir)/android/hardware/vibrator/1.0/",
+ srcs: [
+ "types.hal",
+ "IVibrator.hal",
+ ],
+ out: [
+ "android/hardware/vibrator/1.0/types.vts.cpp",
+ "android/hardware/vibrator/1.0/Vibrator.vts.cpp",
+ ],
+}
+
+genrule {
+ name: "android.hardware.vibrator.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.vibrator@1.0 && $(location vtsc) -mDRIVER -tHEADER -b$(genDir) android/hardware/vibrator/1.0/ $(genDir)/android/hardware/vibrator/1.0/",
+ srcs: [
+ "types.hal",
+ "IVibrator.hal",
+ ],
+ out: [
+ "android/hardware/vibrator/1.0/types.vts.h",
+ "android/hardware/vibrator/1.0/Vibrator.vts.h",
+ ],
+}
+
+cc_library_shared {
+ name: "android.hardware.vibrator.vts.driver@1.0",
+ generated_sources: ["android.hardware.vibrator.vts.driver@1.0_genc++"],
+ generated_headers: ["android.hardware.vibrator.vts.driver@1.0_genc++_headers"],
+ export_generated_headers: ["android.hardware.vibrator.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.vibrator@1.0",
+ ],
+ export_shared_lib_headers: [
+ "libhidlbase",
+ "libhidltransport",
+ "libhwbinder",
+ "libutils",
+ "android.hidl.base@1.0",
+ ],
+}
+
+genrule {
+ name: "android.hardware.vibrator@1.0-IVibrator-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.vibrator@1.0 && $(location vtsc) -mPROFILER -tSOURCE -b$(genDir) android/hardware/vibrator/1.0/ $(genDir)/android/hardware/vibrator/1.0/",
+ srcs: [
+ "IVibrator.hal",
+ "types.hal",
+ ],
+ out: [
+ "android/hardware/vibrator/1.0/Vibrator.vts.cpp",
+ "android/hardware/vibrator/1.0/types.vts.cpp",
+ ],
+}
+
+genrule {
+ name: "android.hardware.vibrator@1.0-IVibrator-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.vibrator@1.0 && $(location vtsc) -mPROFILER -tHEADER -b$(genDir) android/hardware/vibrator/1.0/ $(genDir)/android/hardware/vibrator/1.0/",
+ srcs: [
+ "IVibrator.hal",
+ "types.hal",
+ ],
+ out: [
+ "android/hardware/vibrator/1.0/Vibrator.vts.h",
+ "android/hardware/vibrator/1.0/types.vts.h",
+ ],
+}
+
+cc_library_shared {
+ name: "android.hardware.vibrator@1.0-IVibrator-vts.profiler",
+ generated_sources: ["android.hardware.vibrator@1.0-IVibrator-vts.profiler_genc++"],
+ generated_headers: ["android.hardware.vibrator@1.0-IVibrator-vts.profiler_genc++_headers"],
+ export_generated_headers: ["android.hardware.vibrator@1.0-IVibrator-vts.profiler_genc++_headers"],
+ shared_libs: [
+ "libbase",
+ "libhidlbase",
+ "libhidltransport",
+ "libvts_profiling",
+ "libvts_multidevice_proto",
+ "libprotobuf-cpp-full",
+ "android.hidl.base@1.0",
+ "android.hardware.vibrator@1.0",
+ ],
+}
diff --git a/vibrator/1.0/vts/Android.mk b/vibrator/1.0/vts/Android.mk
index 080eb88..df5dac8 100644
--- a/vibrator/1.0/vts/Android.mk
+++ b/vibrator/1.0/vts/Android.mk
@@ -16,66 +16,4 @@
LOCAL_PATH := $(call my-dir)
-# build VTS driver for Vibrator v1.0.
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libvts_driver_hidl_vibrator@1.0
-
-LOCAL_SRC_FILES := \
- Vibrator.vts \
- types.vts \
-
-LOCAL_SHARED_LIBRARIES += \
- android.hardware.vibrator@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 vibrator.
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libvts_profiler_hidl_vibrator@1.0
-
-LOCAL_SRC_FILES := \
- Vibrator.vts \
- types.vts \
-
-LOCAL_C_INCLUDES += \
- test/vts/drivers/libprofiling \
-
-LOCAL_VTS_MODE := PROFILER
-
-LOCAL_SHARED_LIBRARIES := \
- android.hardware.vibrator@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)
\ No newline at end of file
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/vr/1.0/Android.bp b/vr/1.0/Android.bp
index 57c9257..3397bff 100644
--- a/vr/1.0/Android.bp
+++ b/vr/1.0/Android.bp
@@ -50,3 +50,98 @@
"android.hidl.base@1.0",
],
}
+
+genrule {
+ name: "android.hardware.vr.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.vr@1.0 && $(location vtsc) -mDRIVER -tSOURCE -b$(genDir) android/hardware/vr/1.0/ $(genDir)/android/hardware/vr/1.0/",
+ srcs: [
+ "IVr.hal",
+ ],
+ out: [
+ "android/hardware/vr/1.0/Vr.vts.cpp",
+ ],
+}
+
+genrule {
+ name: "android.hardware.vr.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.vr@1.0 && $(location vtsc) -mDRIVER -tHEADER -b$(genDir) android/hardware/vr/1.0/ $(genDir)/android/hardware/vr/1.0/",
+ srcs: [
+ "IVr.hal",
+ ],
+ out: [
+ "android/hardware/vr/1.0/Vr.vts.h",
+ ],
+}
+
+cc_library_shared {
+ name: "android.hardware.vr.vts.driver@1.0",
+ generated_sources: ["android.hardware.vr.vts.driver@1.0_genc++"],
+ generated_headers: ["android.hardware.vr.vts.driver@1.0_genc++_headers"],
+ export_generated_headers: ["android.hardware.vr.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.vr@1.0",
+ ],
+ export_shared_lib_headers: [
+ "libhidlbase",
+ "libhidltransport",
+ "libhwbinder",
+ "libutils",
+ "android.hidl.base@1.0",
+ ],
+}
+
+genrule {
+ name: "android.hardware.vr@1.0-IVr-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.vr@1.0 && $(location vtsc) -mPROFILER -tSOURCE -b$(genDir) android/hardware/vr/1.0/ $(genDir)/android/hardware/vr/1.0/",
+ srcs: [
+ "IVr.hal",
+ ],
+ out: [
+ "android/hardware/vr/1.0/Vr.vts.cpp",
+ ],
+}
+
+genrule {
+ name: "android.hardware.vr@1.0-IVr-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.vr@1.0 && $(location vtsc) -mPROFILER -tHEADER -b$(genDir) android/hardware/vr/1.0/ $(genDir)/android/hardware/vr/1.0/",
+ srcs: [
+ "IVr.hal",
+ ],
+ out: [
+ "android/hardware/vr/1.0/Vr.vts.h",
+ ],
+}
+
+cc_library_shared {
+ name: "android.hardware.vr@1.0-IVr-vts.profiler",
+ generated_sources: ["android.hardware.vr@1.0-IVr-vts.profiler_genc++"],
+ generated_headers: ["android.hardware.vr@1.0-IVr-vts.profiler_genc++_headers"],
+ export_generated_headers: ["android.hardware.vr@1.0-IVr-vts.profiler_genc++_headers"],
+ shared_libs: [
+ "libbase",
+ "libhidlbase",
+ "libhidltransport",
+ "libvts_profiling",
+ "libvts_multidevice_proto",
+ "libprotobuf-cpp-full",
+ "android.hidl.base@1.0",
+ "android.hardware.vr@1.0",
+ ],
+}
diff --git a/vr/1.0/vts/Android.mk b/vr/1.0/vts/Android.mk
index 8a1312d..e8afa86 100644
--- a/vr/1.0/vts/Android.mk
+++ b/vr/1.0/vts/Android.mk
@@ -16,65 +16,5 @@
LOCAL_PATH := $(call my-dir)
-# build VTS driver for Vr v1.0.
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libvts_driver_hidl_vr@1.0
-
-LOCAL_SRC_FILES := \
- Vr.vts \
-
-LOCAL_SHARED_LIBRARIES += \
- android.hardware.vr@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 Vr.
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libvts_profiler_hidl_vr@1.0
-
-LOCAL_SRC_FILES := \
- Vr.vts \
-
-LOCAL_C_INCLUDES += \
- test/vts/drivers/libprofiling \
-
-LOCAL_VTS_MODE := PROFILER
-
-LOCAL_SHARED_LIBRARIES := \
- android.hardware.vr@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 hidl test makefiles
include $(LOCAL_PATH)/functional/vts/testcases/hal/vr/hidl/Android.mk
diff --git a/wifi/1.0/Android.mk b/wifi/1.0/Android.mk
index 26f782e..bb8d144 100644
--- a/wifi/1.0/Android.mk
+++ b/wifi/1.0/Android.mk
@@ -1879,177 +1879,6 @@
LOCAL_GENERATED_SOURCES += $(GEN)
#
-# Build types.hal (WifiDebugRingEntryConnectivityEvent)
-#
-GEN := $(intermediates)/android/hardware/wifi/V1_0/WifiDebugRingEntryConnectivityEvent.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.wifi@1.0::types.WifiDebugRingEntryConnectivityEvent
-
-$(GEN): $(LOCAL_PATH)/types.hal
- $(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN)
-
-#
-# Build types.hal (WifiDebugRingEntryEventTlv)
-#
-GEN := $(intermediates)/android/hardware/wifi/V1_0/WifiDebugRingEntryEventTlv.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.wifi@1.0::types.WifiDebugRingEntryEventTlv
-
-$(GEN): $(LOCAL_PATH)/types.hal
- $(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN)
-
-#
-# Build types.hal (WifiDebugRingEntryEventTlvType)
-#
-GEN := $(intermediates)/android/hardware/wifi/V1_0/WifiDebugRingEntryEventTlvType.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.wifi@1.0::types.WifiDebugRingEntryEventTlvType
-
-$(GEN): $(LOCAL_PATH)/types.hal
- $(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN)
-
-#
-# Build types.hal (WifiDebugRingEntryEventType)
-#
-GEN := $(intermediates)/android/hardware/wifi/V1_0/WifiDebugRingEntryEventType.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.wifi@1.0::types.WifiDebugRingEntryEventType
-
-$(GEN): $(LOCAL_PATH)/types.hal
- $(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN)
-
-#
-# Build types.hal (WifiDebugRingEntryFlags)
-#
-GEN := $(intermediates)/android/hardware/wifi/V1_0/WifiDebugRingEntryFlags.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.wifi@1.0::types.WifiDebugRingEntryFlags
-
-$(GEN): $(LOCAL_PATH)/types.hal
- $(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN)
-
-#
-# Build types.hal (WifiDebugRingEntryHeader)
-#
-GEN := $(intermediates)/android/hardware/wifi/V1_0/WifiDebugRingEntryHeader.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.wifi@1.0::types.WifiDebugRingEntryHeader
-
-$(GEN): $(LOCAL_PATH)/types.hal
- $(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN)
-
-#
-# Build types.hal (WifiDebugRingEntryPowerEvent)
-#
-GEN := $(intermediates)/android/hardware/wifi/V1_0/WifiDebugRingEntryPowerEvent.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.wifi@1.0::types.WifiDebugRingEntryPowerEvent
-
-$(GEN): $(LOCAL_PATH)/types.hal
- $(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN)
-
-#
-# Build types.hal (WifiDebugRingEntryVendorData)
-#
-GEN := $(intermediates)/android/hardware/wifi/V1_0/WifiDebugRingEntryVendorData.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.wifi@1.0::types.WifiDebugRingEntryVendorData
-
-$(GEN): $(LOCAL_PATH)/types.hal
- $(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN)
-
-#
-# Build types.hal (WifiDebugRingEntryWakelockEvent)
-#
-GEN := $(intermediates)/android/hardware/wifi/V1_0/WifiDebugRingEntryWakelockEvent.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.wifi@1.0::types.WifiDebugRingEntryWakelockEvent
-
-$(GEN): $(LOCAL_PATH)/types.hal
- $(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN)
-
-#
# Build types.hal (WifiDebugRxPacketFate)
#
GEN := $(intermediates)/android/hardware/wifi/V1_0/WifiDebugRxPacketFate.java
@@ -4421,177 +4250,6 @@
LOCAL_GENERATED_SOURCES += $(GEN)
#
-# Build types.hal (WifiDebugRingEntryConnectivityEvent)
-#
-GEN := $(intermediates)/android/hardware/wifi/V1_0/WifiDebugRingEntryConnectivityEvent.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.wifi@1.0::types.WifiDebugRingEntryConnectivityEvent
-
-$(GEN): $(LOCAL_PATH)/types.hal
- $(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN)
-
-#
-# Build types.hal (WifiDebugRingEntryEventTlv)
-#
-GEN := $(intermediates)/android/hardware/wifi/V1_0/WifiDebugRingEntryEventTlv.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.wifi@1.0::types.WifiDebugRingEntryEventTlv
-
-$(GEN): $(LOCAL_PATH)/types.hal
- $(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN)
-
-#
-# Build types.hal (WifiDebugRingEntryEventTlvType)
-#
-GEN := $(intermediates)/android/hardware/wifi/V1_0/WifiDebugRingEntryEventTlvType.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.wifi@1.0::types.WifiDebugRingEntryEventTlvType
-
-$(GEN): $(LOCAL_PATH)/types.hal
- $(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN)
-
-#
-# Build types.hal (WifiDebugRingEntryEventType)
-#
-GEN := $(intermediates)/android/hardware/wifi/V1_0/WifiDebugRingEntryEventType.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.wifi@1.0::types.WifiDebugRingEntryEventType
-
-$(GEN): $(LOCAL_PATH)/types.hal
- $(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN)
-
-#
-# Build types.hal (WifiDebugRingEntryFlags)
-#
-GEN := $(intermediates)/android/hardware/wifi/V1_0/WifiDebugRingEntryFlags.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.wifi@1.0::types.WifiDebugRingEntryFlags
-
-$(GEN): $(LOCAL_PATH)/types.hal
- $(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN)
-
-#
-# Build types.hal (WifiDebugRingEntryHeader)
-#
-GEN := $(intermediates)/android/hardware/wifi/V1_0/WifiDebugRingEntryHeader.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.wifi@1.0::types.WifiDebugRingEntryHeader
-
-$(GEN): $(LOCAL_PATH)/types.hal
- $(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN)
-
-#
-# Build types.hal (WifiDebugRingEntryPowerEvent)
-#
-GEN := $(intermediates)/android/hardware/wifi/V1_0/WifiDebugRingEntryPowerEvent.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.wifi@1.0::types.WifiDebugRingEntryPowerEvent
-
-$(GEN): $(LOCAL_PATH)/types.hal
- $(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN)
-
-#
-# Build types.hal (WifiDebugRingEntryVendorData)
-#
-GEN := $(intermediates)/android/hardware/wifi/V1_0/WifiDebugRingEntryVendorData.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.wifi@1.0::types.WifiDebugRingEntryVendorData
-
-$(GEN): $(LOCAL_PATH)/types.hal
- $(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN)
-
-#
-# Build types.hal (WifiDebugRingEntryWakelockEvent)
-#
-GEN := $(intermediates)/android/hardware/wifi/V1_0/WifiDebugRingEntryWakelockEvent.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.wifi@1.0::types.WifiDebugRingEntryWakelockEvent
-
-$(GEN): $(LOCAL_PATH)/types.hal
- $(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN)
-
-#
# Build types.hal (WifiDebugRxPacketFate)
#
GEN := $(intermediates)/android/hardware/wifi/V1_0/WifiDebugRxPacketFate.java
diff --git a/wifi/1.0/IWifiChip.hal b/wifi/1.0/IWifiChip.hal
index e903ced..d790404 100644
--- a/wifi/1.0/IWifiChip.hal
+++ b/wifi/1.0/IWifiChip.hal
@@ -137,28 +137,28 @@
/**
* Memory dump of Firmware.
*/
- DEBUG_MEMORY_FIRMWARE_DUMP_SUPPORTED = 1 << 0,
+ DEBUG_MEMORY_FIRMWARE_DUMP = 1 << 0,
/**
* Memory dump of Driver.
*/
- DEBUG_MEMORY_DRIVER_DUMP_SUPPORTED = 1 << 1,
+ DEBUG_MEMORY_DRIVER_DUMP = 1 << 1,
/**
* Connectivity events reported via debug ring buffer.
*/
- DEBUG_RING_BUFFER_CONNECT_EVENT_SUPPORTED = 1 << 2,
+ DEBUG_RING_BUFFER_CONNECT_EVENT = 1 << 2,
/**
* Power events reported via debug ring buffer.
*/
- DEBUG_RING_BUFFER_POWER_EVENT_SUPPORTED = 1 << 3,
+ DEBUG_RING_BUFFER_POWER_EVENT = 1 << 3,
/**
* Wakelock events reported via debug ring buffer.
*/
- DEBUG_RING_BUFFER_WAKELOCK_EVENT_SUPPORTED = 1 << 4,
+ DEBUG_RING_BUFFER_WAKELOCK_EVENT = 1 << 4,
/**
* Vendor data reported via debug ring buffer.
* This mostly contains firmware event logs.
*/
- DEBUG_RING_BUFFER_VENDOR_DATA_SUPPORTED = 1 << 5,
+ DEBUG_RING_BUFFER_VENDOR_DATA = 1 << 5,
/**
* Host wake reasons stats collection.
*/
@@ -292,7 +292,7 @@
* Create an AP iface on the chip.
*
* Depending on the mode the chip is configured in, the interface creation
- * may fail (code: |ERROR_NOT_SUPPORTED|) if we've already reached the maximum
+ * may fail (code: |ERROR_NOT_AVAILABLE|) if we've already reached the maximum
* allowed (specified in |ChipIfaceCombination|) number of ifaces of the AP
* type.
*
@@ -352,7 +352,7 @@
* Create a NAN iface on the chip.
*
* Depending on the mode the chip is configured in, the interface creation
- * may fail (code: |ERROR_NOT_SUPPORTED|) if we've already reached the maximum
+ * may fail (code: |ERROR_NOT_AVAILABLE|) if we've already reached the maximum
* allowed (specified in |ChipIfaceCombination|) number of ifaces of the NAN
* type.
*
@@ -412,7 +412,7 @@
* Create a P2P iface on the chip.
*
* Depending on the mode the chip is configured in, the interface creation
- * may fail (code: |ERROR_NOT_SUPPORTED|) if we've already reached the maximum
+ * may fail (code: |ERROR_NOT_AVAILABLE|) if we've already reached the maximum
* allowed (specified in |ChipIfaceCombination|) number of ifaces of the P2P
* type.
*
@@ -472,7 +472,7 @@
* Create an STA iface on the chip.
*
* Depending on the mode the chip is configured in, the interface creation
- * may fail (code: |ERROR_NOT_SUPPORTED|) if we've already reached the maximum
+ * may fail (code: |ERROR_NOT_AVAILABLE|) if we've already reached the maximum
* allowed (specified in |ChipIfaceCombination|) number of ifaces of the STA
* type.
*
@@ -558,7 +558,7 @@
* ring. The vebose level for each ring buffer can be specified in this API.
* - During wifi operations, driver must periodically report per ring data to
* framework by invoking the
- * |IWifiChipEventCallback.onDebugRingBuffer<Type>EntriesAvailable| callback.
+ * |IWifiChipEventCallback.onDebugRingBufferDataAvailable| callback.
* - When capturing a bug report, framework must indicate to driver that all
* the data has to be uploaded urgently by calling
* |forceDumpToDebugRingBuffer|.
diff --git a/wifi/1.0/IWifiChipEventCallback.hal b/wifi/1.0/IWifiChipEventCallback.hal
index aff1e43..0d9e329 100644
--- a/wifi/1.0/IWifiChipEventCallback.hal
+++ b/wifi/1.0/IWifiChipEventCallback.hal
@@ -74,28 +74,11 @@
* @return status Status of the corresponding ring buffer. This should
* contain the name of the ring buffer on which the data is
* available.
- * @return entries Vector of debug ring buffer data entries. These
- * should be parsed based on the type of entry.
+ * @return data Raw bytes of data sent by the driver. Must be dumped
+ * out to a bugreport and post processed.
*/
- /** Connectivity event data callback */
- oneway onDebugRingBufferConnectivityEventEntriesAvailable(
- WifiDebugRingBufferStatus status,
- vec<WifiDebugRingEntryConnectivityEvent> entries);
-
- /** Power event data callback */
- oneway onDebugRingBufferPowerEventEntriesAvailable(
- WifiDebugRingBufferStatus status,
- vec<WifiDebugRingEntryPowerEvent> entries);
-
- /** Wakelock event data callback */
- oneway onDebugRingBufferWakelockEventEntriesAvailable(
- WifiDebugRingBufferStatus status,
- vec<WifiDebugRingEntryWakelockEvent> entries);
-
- /** Vendor data event data callback */
- oneway onDebugRingBufferVendorDataEntriesAvailable(
- WifiDebugRingBufferStatus status,
- vec<WifiDebugRingEntryVendorData> entries);
+ oneway onDebugRingBufferDataAvailable(
+ WifiDebugRingBufferStatus status, vec<uint8_t> data);
/**
* Callback indicating that the chip has encountered a fatal error.
diff --git a/wifi/1.0/IWifiStaIface.hal b/wifi/1.0/IWifiStaIface.hal
index 8c7ac4a..98af043 100644
--- a/wifi/1.0/IWifiStaIface.hal
+++ b/wifi/1.0/IWifiStaIface.hal
@@ -61,9 +61,29 @@
*/
SCAN_RAND = 1 << 6,
/**
- * Tracks connection packets' fate.
+ * Support for 5 GHz Band.
*/
- DEBUG_PACKET_FATE_SUPPORTED = 1 << 7
+ STA_5G = 1 << 7,
+ /**
+ * Support for GAS/ANQP queries.
+ */
+ HOTSPOT = 1 << 8,
+ /**
+ * Support for Preferred Network Offload.
+ */
+ PNO = 1 << 9,
+ /**
+ * Support for Tunneled Direct Link Setup.
+ */
+ TDLS = 1 << 10,
+ /**
+ * Support for Tunneled Direct Link Setup off channel.
+ */
+ TDLS_OFFCHANNEL = 1 << 11,
+ /**
+ * Support for tracking connection packets' fate.
+ */
+ DEBUG_PACKET_FATE = 1 << 12
};
/**
diff --git a/wifi/1.0/default/hidl_struct_util.cpp b/wifi/1.0/default/hidl_struct_util.cpp
index 0aee372..a94d812 100644
--- a/wifi/1.0/default/hidl_struct_util.cpp
+++ b/wifi/1.0/default/hidl_struct_util.cpp
@@ -31,15 +31,15 @@
using HidlChipCaps = IWifiChip::ChipCapabilityMask;
switch (feature) {
case legacy_hal::WIFI_LOGGER_MEMORY_DUMP_SUPPORTED:
- return HidlChipCaps::DEBUG_MEMORY_FIRMWARE_DUMP_SUPPORTED;
+ return HidlChipCaps::DEBUG_MEMORY_FIRMWARE_DUMP;
case legacy_hal::WIFI_LOGGER_DRIVER_DUMP_SUPPORTED:
- return HidlChipCaps::DEBUG_MEMORY_DRIVER_DUMP_SUPPORTED;
+ return HidlChipCaps::DEBUG_MEMORY_DRIVER_DUMP;
case legacy_hal::WIFI_LOGGER_CONNECT_EVENT_SUPPORTED:
- return HidlChipCaps::DEBUG_RING_BUFFER_CONNECT_EVENT_SUPPORTED;
+ return HidlChipCaps::DEBUG_RING_BUFFER_CONNECT_EVENT;
case legacy_hal::WIFI_LOGGER_POWER_EVENT_SUPPORTED:
- return HidlChipCaps::DEBUG_RING_BUFFER_POWER_EVENT_SUPPORTED;
+ return HidlChipCaps::DEBUG_RING_BUFFER_POWER_EVENT;
case legacy_hal::WIFI_LOGGER_WAKE_LOCK_SUPPORTED:
- return HidlChipCaps::DEBUG_RING_BUFFER_WAKELOCK_EVENT_SUPPORTED;
+ return HidlChipCaps::DEBUG_RING_BUFFER_WAKELOCK_EVENT;
};
CHECK(false) << "Unknown legacy feature: " << feature;
return {};
@@ -50,7 +50,7 @@
using HidlStaIfaceCaps = IWifiStaIface::StaIfaceCapabilityMask;
switch (feature) {
case legacy_hal::WIFI_LOGGER_PACKET_FATE_SUPPORTED:
- return HidlStaIfaceCaps::DEBUG_PACKET_FATE_SUPPORTED;
+ return HidlStaIfaceCaps::DEBUG_PACKET_FATE;
};
CHECK(false) << "Unknown legacy feature: " << feature;
return {};
@@ -72,6 +72,16 @@
return HidlStaIfaceCaps::PROBE_IE_WHITELIST;
case WIFI_FEATURE_SCAN_RAND:
return HidlStaIfaceCaps::SCAN_RAND;
+ case WIFI_FEATURE_INFRA_5G:
+ return HidlStaIfaceCaps::STA_5G;
+ case WIFI_FEATURE_HOTSPOT:
+ return HidlStaIfaceCaps::HOTSPOT;
+ case WIFI_FEATURE_PNO:
+ return HidlStaIfaceCaps::PNO;
+ case WIFI_FEATURE_TDLS:
+ return HidlStaIfaceCaps::TDLS;
+ case WIFI_FEATURE_TDLS_OFFCHANNEL:
+ return HidlStaIfaceCaps::TDLS_OFFCHANNEL;
};
CHECK(false) << "Unknown legacy feature: " << feature;
return {};
@@ -95,7 +105,7 @@
}
// There are no flags for these 3 in the legacy feature set. Adding them to
// the set because all the current devices support it.
- *hidl_caps |= HidlChipCaps::DEBUG_RING_BUFFER_VENDOR_DATA_SUPPORTED;
+ *hidl_caps |= HidlChipCaps::DEBUG_RING_BUFFER_VENDOR_DATA;
*hidl_caps |= HidlChipCaps::DEBUG_HOST_WAKE_REASON_STATS;
*hidl_caps |= HidlChipCaps::DEBUG_ERROR_ALERTS;
return true;
@@ -224,7 +234,12 @@
WIFI_FEATURE_RSSI_MONITOR,
WIFI_FEATURE_CONTROL_ROAMING,
WIFI_FEATURE_IE_WHITELIST,
- WIFI_FEATURE_SCAN_RAND}) {
+ WIFI_FEATURE_SCAN_RAND,
+ WIFI_FEATURE_INFRA_5G,
+ WIFI_FEATURE_HOTSPOT,
+ WIFI_FEATURE_PNO,
+ WIFI_FEATURE_TDLS,
+ WIFI_FEATURE_TDLS_OFFCHANNEL}) {
if (feature & legacy_feature_set) {
*hidl_caps |= convertLegacyFeatureToHidlStaIfaceCapability(feature);
}
diff --git a/wifi/1.0/default/hidl_struct_util.h b/wifi/1.0/default/hidl_struct_util.h
index e4104e2..9086666 100644
--- a/wifi/1.0/default/hidl_struct_util.h
+++ b/wifi/1.0/default/hidl_struct_util.h
@@ -39,6 +39,9 @@
// Chip conversion methods.
bool convertLegacyFeaturesToHidlChipCapabilities(
uint32_t legacy_logger_feature_set, uint32_t* hidl_caps);
+bool convertLegacyDebugRingBufferStatusToHidl(
+ const legacy_hal::wifi_ring_buffer_status& legacy_status,
+ WifiDebugRingBufferStatus* hidl_status);
bool convertLegacyVectorOfDebugRingBufferStatusToHidl(
const std::vector<legacy_hal::wifi_ring_buffer_status>& legacy_status_vec,
std::vector<WifiDebugRingBufferStatus>* hidl_status_vec);
diff --git a/wifi/1.0/default/wifi_chip.cpp b/wifi/1.0/default/wifi_chip.cpp
index 87b47cb..e15178d 100644
--- a/wifi/1.0/default/wifi_chip.cpp
+++ b/wifi/1.0/default/wifi_chip.cpp
@@ -57,7 +57,8 @@
legacy_hal_(legacy_hal),
mode_controller_(mode_controller),
is_valid_(true),
- current_mode_id_(kInvalidModeId) {}
+ current_mode_id_(kInvalidModeId),
+ debug_ring_buffer_cb_registered_(false) {}
void WifiChip::invalidate() {
invalidateAndRemoveAllIfaces();
@@ -687,6 +688,10 @@
WifiDebugRingBufferVerboseLevel verbose_level,
uint32_t max_interval_in_sec,
uint32_t min_data_size_in_bytes) {
+ WifiStatus status = registerDebugRingBufferCallback();
+ if (status.code != WifiStatusCode::SUCCESS) {
+ return status;
+ }
legacy_hal::wifi_error legacy_status =
legacy_hal_.lock()->startRingBufferLogging(
ring_name,
@@ -700,6 +705,10 @@
WifiStatus WifiChip::forceDumpToDebugRingBufferInternal(
const hidl_string& ring_name) {
+ WifiStatus status = registerDebugRingBufferCallback();
+ if (status.code != WifiStatusCode::SUCCESS) {
+ return status;
+ }
legacy_hal::wifi_error legacy_status =
legacy_hal_.lock()->getRingBufferData(ring_name);
return createWifiStatusFromLegacyError(legacy_status);
@@ -774,6 +783,42 @@
}
return createWifiStatus(WifiStatusCode::SUCCESS);
}
+
+WifiStatus WifiChip::registerDebugRingBufferCallback() {
+ if (debug_ring_buffer_cb_registered_) {
+ return createWifiStatus(WifiStatusCode::SUCCESS);
+ }
+
+ android::wp<WifiChip> weak_ptr_this(this);
+ const auto& on_ring_buffer_data_callback = [weak_ptr_this](
+ const std::string& /* name */,
+ const std::vector<uint8_t>& data,
+ const legacy_hal::wifi_ring_buffer_status& status) {
+ const auto shared_ptr_this = weak_ptr_this.promote();
+ if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+ LOG(ERROR) << "Callback invoked on an invalid object";
+ return;
+ }
+ WifiDebugRingBufferStatus hidl_status;
+ if (!hidl_struct_util::convertLegacyDebugRingBufferStatusToHidl(
+ status, &hidl_status)) {
+ LOG(ERROR) << "Error converting ring buffer status";
+ return;
+ }
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ callback->onDebugRingBufferDataAvailable(hidl_status, data);
+ }
+ };
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->registerRingBufferCallbackHandler(
+ on_ring_buffer_data_callback);
+
+ if (legacy_status == legacy_hal::WIFI_SUCCESS) {
+ debug_ring_buffer_cb_registered_ = true;
+ }
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
} // namespace implementation
} // namespace V1_0
} // namespace wifi
diff --git a/wifi/1.0/default/wifi_chip.h b/wifi/1.0/default/wifi_chip.h
index 373712c..938b180 100644
--- a/wifi/1.0/default/wifi_chip.h
+++ b/wifi/1.0/default/wifi_chip.h
@@ -174,6 +174,7 @@
WifiStatus enableDebugErrorAlertsInternal(bool enable);
WifiStatus handleChipConfiguration(ChipModeId mode_id);
+ WifiStatus registerDebugRingBufferCallback();
ChipId chip_id_;
std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
@@ -186,6 +187,10 @@
std::vector<sp<WifiRttController>> rtt_controllers_;
bool is_valid_;
uint32_t current_mode_id_;
+ // The legacy ring buffer callback API has only a global callback
+ // registration mechanism. Use this to check if we have already
+ // registered a callback.
+ bool debug_ring_buffer_cb_registered_;
DISALLOW_COPY_AND_ASSIGN(WifiChip);
};
diff --git a/wifi/1.0/default/wifi_legacy_hal.cpp b/wifi/1.0/default/wifi_legacy_hal.cpp
index d65052e..3b99e60 100644
--- a/wifi/1.0/default/wifi_legacy_hal.cpp
+++ b/wifi/1.0/default/wifi_legacy_hal.cpp
@@ -761,7 +761,7 @@
WifiLegacyHal::getRingBuffersStatus() {
std::vector<wifi_ring_buffer_status> ring_buffers_status;
ring_buffers_status.resize(kMaxRingBuffers);
- uint32_t num_rings = 0;
+ uint32_t num_rings = kMaxRingBuffers;
wifi_error status = global_func_table_.wifi_get_ring_buffers_status(
wlan_interface_handle_, &num_rings, ring_buffers_status.data());
CHECK(num_rings <= kMaxRingBuffers);
diff --git a/wifi/1.0/types.hal b/wifi/1.0/types.hal
index 2da4d84..76c89e3 100644
--- a/wifi/1.0/types.hal
+++ b/wifi/1.0/types.hal
@@ -2359,468 +2359,6 @@
typedef uint32_t WifiRingBufferId;
/**
- * Mask of flags present in |WifiDebugRingEntryHeader.flags| field.
- */
-enum WifiDebugRingEntryFlags : uint8_t {
- /**
- * Set for binary entries
- */
- HAS_BINARY = 1 << 0,
- /**
- * Set if 64 bits timestamp is present
- */
- HAS_TIMESTAMP = 1 << 1,
-};
-
-/**
- * This structure represent an entry within a debug ring buffer.
- * Wifi driver are responsible to manage the debug ring buffer and write the
- * debug information into those buffer.
- *
- * In general, the debug entries can be used to store meaningful 802.11
- * information (SME, MLME, connection and packet statistics) as well as vendor
- * proprietary data that is specific to a specific driver or chipset.
- * Binary entries can be used so as to store packet data or vendor specific
- * information and will be treated as blobs of data by android framework.
- *
- * A user land process will be started by framework so as to periodically
- * retrieve the data logged by drivers into their debug ring buffer, store the
- * data into log files and include the logs into android bugreports.
- */
-struct WifiDebugRingEntryHeader {
- /**
- * The size of |payload| excluding the header.
- */
- uint16_t sizeInBytes;
- /**
- * Combination of |WifiDebugRingEntryFlags| values.
- */
- uint8_t flags;
- /**
- * Present if |HAS_TIMESTAMP| bit is set.
- */
- TimeStampInUs timestamp;
-};
-
-/**
- * Below event types are used for both the connect and power event
- * ring entries.
- */
-enum WifiDebugRingEntryEventType : uint16_t {
- /**
- * Driver receives association command from kernel.
- */
- ASSOCIATION_REQUESTED = 0,
- AUTH_COMPLETE = 1,
- ASSOC_COMPLETE = 2,
- /**
- * Firmware event indicating auth frames are sent.
- */
- FW_AUTH_STARTED = 3,
- /**
- * Firmware event indicating assoc frames are sent.
- */
- FW_ASSOC_STARTED = 4,
- /**
- * Firmware event indicating reassoc frames are sent.
- */
- FW_RE_ASSOC_STARTED = 5,
- DRIVER_SCAN_REQUESTED = 6,
- DRIVER_SCAN_RESULT_FOUND = 7,
- DRIVER_SCAN_COMPLETE = 8,
- BACKGROUND_SCAN_STARTED = 9,
- BACKGROUND_SCAN_COMPLETE = 10,
- DISASSOCIATION_REQUESTED = 11,
- RE_ASSOCIATION_REQUESTED = 12,
- ROAM_REQUESTED = 13,
- /**
- * Received beacon from AP (event enabled only in verbose mode).
- */
- BEACON_RECEIVED = 14,
- /**
- * Firmware has triggered a roam scan (not g-scan).
- */
- ROAM_SCAN_STARTED = 15,
- /**
- * Firmware has completed a roam scan (not g-scan).
- */
- ROAM_SCAN_COMPLETE = 16,
- /**
- * Firmware has started searching for roam candidates (with reason =xx).
- */
- ROAM_SEARCH_STARTED = 17,
- /**
- * Firmware has stopped searching for roam candidates (with reason =xx).
- */
- ROAM_SEARCH_STOPPED = 18,
- /**
- * Received channel switch anouncement from AP.
- */
- CHANNEL_SWITCH_ANOUNCEMENT = 20,
- /**
- * Firmware start transmit eapol frame, with EAPOL index 1-4.
- */
- FW_EAPOL_FRAME_TRANSMIT_START = 21,
- /**
- * Firmware gives up eapol frame, with rate, success/failure and number
- * retries.
- */
- FW_EAPOL_FRAME_TRANSMIT_STOP = 22,
- /**
- * Kernel queue EAPOL for transmission in driver with EAPOL index 1-4.
- */
- DRIVER_EAPOL_FRAME_TRANSMIT_REQUESTED = 23,
- /**
- * With rate, regardless of the fact that EAPOL frame is accepted or
- * rejected by firmware.
- */
- FW_EAPOL_FRAME_RECEIVED = 24,
- /**
- * With rate, and eapol index, driver has received EAPOL frame and will
- * queue it up to wpa_supplicant.
- */
- DRIVER_EAPOL_FRAME_RECEIVED = 26,
- /**
- * With success/failure, parameters
- */
- BLOCK_ACK_NEGOTIATION_COMPLETE = 27,
- BT_COEX_BT_SCO_START = 28,
- BT_COEX_BT_SCO_STOP = 29,
- /**
- * For paging/scan etc., when BT starts transmiting twice per BT slot.
- */
- BT_COEX_BT_SCAN_START = 30,
- BT_COEX_BT_SCAN_STOP = 31,
- BT_COEX_BT_HID_START = 32,
- BT_COEX_BT_HID_STOP = 33,
- /**
- * Firmware sends auth frame in roaming to next candidate.
- */
- ROAM_AUTH_STARTED = 34,
- /**
- * Firmware receive auth confirm from ap
- */
- ROAM_AUTH_COMPLETE = 35,
- /**
- * Firmware sends assoc/reassoc frame in roaming to next candidate.
- */
- ROAM_ASSOC_STARTED = 36,
- /**
- * Firmware receive assoc/reassoc confirm from ap.
- */
- ROAM_ASSOC_COMPLETE = 37,
- /**
- * Firmware sends stop BACKGROUND_SCAN
- */
- BACKGROUND_SCAN_STOP = 38,
- /**
- * Firmware indicates BACKGROUND_SCAN scan cycle started.
- */
- BACKGROUND_SCAN_CYCLE_STARTED = 39,
- /**
- * Firmware indicates BACKGROUND_SCAN scan cycle completed.
- */
- BACKGROUND_SCAN_CYCLE_COMPLETED = 40,
- /**
- * Firmware indicates BACKGROUND_SCAN scan start for a particular bucket.
- */
- BACKGROUND_SCAN_BUCKET_STARTED = 41,
- /**
- * Firmware indicates BACKGROUND_SCAN scan completed for for a particular bucket.
- */
- BACKGROUND_SCAN_BUCKET_COMPLETED = 42,
- /**
- * Event received from firmware about BACKGROUND_SCAN scan results being available.
- */
- BACKGROUND_SCAN_RESULTS_AVAILABLE = 43,
- /**
- * Event received from firmware with BACKGROUND_SCAN capabilities.
- */
- BACKGROUND_SCAN_CAPABILITIES = 44,
- /**
- * Event received from firmware when eligible candidate is found.
- */
- ROAM_CANDIDATE_FOUND = 45,
- /**
- * Event received from firmware when roam scan configuration gets
- * enabled or disabled.
- */
- ROAM_SCAN_CONFIG = 46,
- /**
- * Firmware/driver timed out authentication.
- */
- AUTH_TIMEOUT = 47,
- /**
- * Firmware/driver timed out association.
- */
- ASSOC_TIMEOUT = 48,
- /**
- * Firmware/driver encountered allocation failure.
- */
- MEM_ALLOC_FAILURE = 49,
- /**
- * Driver added a PNO network in firmware.
- */
- DRIVER_PNO_ADD = 50,
- /**
- * Driver removed a PNO network in firmware.
- */
- DRIVER_PNO_REMOVE = 51,
- /**
- * Driver received PNO networks found indication from firmware.
- */
- DRIVER_PNO_NETWORK_FOUND = 52,
- /**
- * Driver triggered a scan for PNO networks.
- */
- DRIVER_PNO_SCAN_REQUESTED = 53,
- /**
- * Driver received scan results of PNO networks.
- */
- DRIVER_PNO_SCAN_RESULT_FOUND = 54,
- /**
- * Driver updated scan results from PNO networks to cfg80211.
- */
- DRIVER_PNO_SCAN_COMPLETE = 55,
-};
-
-/**
- * Parameters of the various events are a sequence of TLVs
- * (type, length, value). The types for different TLV's are defined below.
- */
-enum WifiDebugRingEntryEventTlvType : uint16_t {
- /**
- * Take a byte stream as parameter.
- */
- VENDOR_SPECIFIC = 0,
- /**
- * Takes a MAC address as parameter.
- */
- BSSID = 1,
- /**
- * Takes a MAC address as parameter.
- */
- ADDR = 2,
- /**
- * Takes an SSID as parameter.
- */
- SSID = 3,
- /**
- * Takes an integer as parameter.
- */
- STATUS = 4,
- /**
- * Takes a |WifiChannelInfo| struct as parameter.
- */
- CHANNEL_SPEC = 5,
- /**
- * Takes a MAC address as parameter.
- */
- ADDR_1 = 6,
- /**
- * Takes a MAC address as parameter.
- */
- ADDR_2 = 7,
- /**
- * Takes a MAC address as parameter.
- */
- ADDR_3 = 8,
- /**
- * Takes a MAC address as parameter.
- */
- ADDR_4 = 9,
- /**
- * Takes a TSF value as parameter.
- */
- TSF = 10,
- /**
- * Takes one or more specific 802.11 IEs parameter IEs are in turn
- * indicated in TLV format as per 802.11, spec.
- */
- IE = 11,
- /**
- * Takes a string interface name as parameter.
- */
- IFACE_NAME = 12,
- /**
- * Takes a integer reason code as per 802.11 as parameter.
- */
- REASON_CODE = 13,
- /**
- * Takes an integer representing wifi rate in 1 mbps as parameter.
- */
- RATE_MBPS = 14,
- /**
- * Takes an integer as parameter.
- */
- REQUEST_ID = 15,
- /**
- * Takes an integer as parameter.
- */
- BUCKET_ID = 16,
- /**
- * Takes a |BackgroundScanParameters| struct as parameter.
- */
- BACKGROUND_SCAN_PARAMS = 17,
- /**
- * Takes a |BackgroundScanCapabilities| struct as parameter.
- */
- BACKGROUND_SCAN_CAPABILITIES = 18,
- /**
- * Takes an integer as parameter.
- */
- SCAN_ID = 19,
- /**
- * Takes an integer as parameter.
- */
- RSSI = 20,
- /**
- * Takes a |WifiChannelInMhz| as parameter.
- */
- CHANNEL = 21,
- /**
- * Takes an integer as parameter.
- */
- LINK_ID = 22,
- /**
- * Takes an integer as parameter.
- */
- LINK_ROLE = 23,
- /**
- * Takes an integer as parameter.
- */
- LINK_STATE = 24,
- /**
- * Takes an integer as parameter.
- */
- LINK_TYPE = 25,
- /**
- * Takes an integer as parameter.
- */
- TSCO = 26,
- /**
- * Takes an integer as parameter.
- */
- RSCO = 27,
- /**
- * Takes an integer as parameter.
- * M1=1, M2=2, M3=3, M=4,
- */
- EAPOL_MESSAGE_TYPE = 28,
-};
-
-/**
- * Used to describe a specific TLV in an event entry.
- */
-struct WifiDebugRingEntryEventTlv {
- WifiDebugRingEntryEventTlvType type;
- /**
- * All possible types of values that can be held in the TLV.
- * Note: This should ideally be a union. But, since this HIDL package
- * is going to be used by a java client, we cannot have unions in this
- * package.
- */
- /* TODO(b/32207606): This can be moved to vendor extension. */
- vec<uint8_t> vendorSpecific;
- Bssid bssid;
- MacAddress addr;
- Ssid ssid;
- WifiChannelInfo channelSpec;
- uint64_t tsf;
- vec<WifiInformationElement> ie;
- string ifaceName;
- StaBackgroundScanParameters bgScanParams;
- StaBackgroundScanCapabilities bgScanCapabilities;
- Rssi rssi;
- WifiChannelInMhz channel;
- uint32_t integerVal;
-};
-
-/**
- * Used to describe a connect event ring entry.
- */
-struct WifiDebugRingEntryConnectivityEvent {
- /**
- * Ring entry header.
- */
- WifiDebugRingEntryHeader header;
- /**
- * Type of connection event.
- */
- WifiDebugRingEntryEventType event;
- /**
- * Separate parameter structure per event to be provided and optional data.
- * The event data is expected to include an official android part, with some
- * parameter as transmit rate, num retries, num scan result found, etc.
- * event data can include a vendor proprietary part which is understood by
- * the vendor only.
- */
- vec<WifiDebugRingEntryEventTlv> tlvs;
-};
-
-/**
- * Used to describe a power event ring entry.
- */
-struct WifiDebugRingEntryPowerEvent {
- /**
- * Ring entry header.
- */
- WifiDebugRingEntryHeader header;
- /**
- * Type of power event.
- */
- WifiDebugRingEntryEventType event;
- /**
- * Separate parameter structure per event to be provided and optional data.
- * The event data is expected to include an official android part, with some
- * parameter as transmit rate, num retries, num scan result found, etc.
- * event data can include a vendor proprietary part which is understood by
- * the vendor only.
- */
- vec<WifiDebugRingEntryEventTlv> tlvs;
-};
-
-/**
- * Used to describe a wakelock event ring entry.
- */
-struct WifiDebugRingEntryWakelockEvent {
- /**
- * Ring entry header.
- */
- WifiDebugRingEntryHeader header;
- /**
- * true = wake lock acquired.
- * false = wake lock released.
- */
- bool wasAcquired;
- /**
- * Reason why this wake lock is taken.
- * This is a vendor defined reason and can only be understood by the
- * vendor.
- */
- uint32_t vendorSpecificReason;
- /**
- * Wake lock name.
- */
- string wakelockName;
-};
-
-/**
- * Used to describe a vendor specific data ring entry.
- */
-struct WifiDebugRingEntryVendorData {
- /**
- * Ring entry header.
- */
- WifiDebugRingEntryHeader header;
- /**
- * This is a blob that will only be understood by the
- * vendor.
- */
- vec<uint8_t> vendorData;
-};
-
-/**
* Flags describing each debug ring buffer.
*/
enum WifiDebugRingBufferFlags : uint32_t {
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",
]
diff --git a/wifi/supplicant/1.0/ISupplicantP2pIface.hal b/wifi/supplicant/1.0/ISupplicantP2pIface.hal
index cd5a7c5..0fa19c8 100644
--- a/wifi/supplicant/1.0/ISupplicantP2pIface.hal
+++ b/wifi/supplicant/1.0/ISupplicantP2pIface.hal
@@ -357,8 +357,7 @@
* |SupplicantStatusCode.FAILURE_UNKNOWN|,
* |SupplicantStatusCode.FAILURE_IFACE_INVALID|
*/
- configureExtListen(bool enable,
- uint32_t periodInMillis,
+ configureExtListen(uint32_t periodInMillis,
uint32_t intervalInMillis)
generates (SupplicantStatus status);
@@ -492,8 +491,7 @@
* |SupplicantStatusCode.FAILURE_UNKNOWN|,
* |SupplicantStatusCode.FAILURE_IFACE_INVALID|
*/
- flushServices(uint32_t version, string serviceName)
- generates (SupplicantStatus status);
+ flushServices() generates (SupplicantStatus status);
/**
* Schedule a P2P service discovery request. The parameters for this command