Merge "Add p2 option in OpenLogicalChannel" into oc-dev
diff --git a/audio/common/2.0/default/HidlUtils.cpp b/audio/common/2.0/default/HidlUtils.cpp
index 241ca90..79cb37c 100644
--- a/audio/common/2.0/default/HidlUtils.cpp
+++ b/audio/common/2.0/default/HidlUtils.cpp
@@ -28,6 +28,7 @@
using ::android::hardware::audio::common::V2_0::AudioPortType;
using ::android::hardware::audio::common::V2_0::AudioSource;
using ::android::hardware::audio::common::V2_0::AudioStreamType;
+using ::android::hardware::audio::common::V2_0::AudioUsage;
namespace android {
@@ -103,6 +104,9 @@
offload->durationMicroseconds = halOffload.duration_us;
offload->hasVideo = halOffload.has_video;
offload->isStreaming = halOffload.is_streaming;
+ offload->bitWidth = halOffload.bit_width;
+ offload->bufferSize = halOffload.offload_buffer_size;
+ offload->usage = static_cast<AudioUsage>(halOffload.usage);
}
void HidlUtils::audioOffloadInfoToHal(
diff --git a/automotive/evs/1.0/vts/functional/FrameHandler.cpp b/automotive/evs/1.0/vts/functional/FrameHandler.cpp
index 01d9a0e..58c2f26 100644
--- a/automotive/evs/1.0/vts/functional/FrameHandler.cpp
+++ b/automotive/evs/1.0/vts/functional/FrameHandler.cpp
@@ -23,7 +23,6 @@
#include <android/log.h>
#include <cutils/native_handle.h>
-#include <ui/GraphicBufferMapper.h>
#include <ui/GraphicBuffer.h>
#include <algorithm> // std::min
@@ -135,11 +134,7 @@
// Local flag we use to keep track of when the stream is stopping
bool timeToStop = false;
- // TODO: Why do we get a gralloc crash if we don't clone the buffer here?
- BufferDesc buffer(bufferArg);
- ALOGD("Clone the received frame as %p", buffer.memHandle.getNativeHandle());
-
- if (buffer.memHandle.getNativeHandle() == nullptr) {
+ if (bufferArg.memHandle.getNativeHandle() == nullptr) {
// Signal that the last frame has been received and the stream is stopped
timeToStop = true;
} else {
@@ -157,13 +152,8 @@
printf("Didn't get target buffer - frame lost\n");
ALOGE("Didn't get requested output buffer -- skipping this frame.");
} else {
- // In order for the handles passed through HIDL and stored in the BufferDesc to
- // be lockable, we must register them with GraphicBufferMapper
- registerBufferHelper(tgtBuffer);
- registerBufferHelper(buffer);
-
// Copy the contents of the of buffer.memHandle into tgtBuffer
- copyBufferContents(tgtBuffer, buffer);
+ copyBufferContents(tgtBuffer, bufferArg);
// Send the target buffer back for display
Return <EvsResult> result = mDisplay->returnTargetBufferForDisplay(tgtBuffer);
@@ -183,10 +173,6 @@
mFramesDisplayed++;
mLock.unlock();
}
-
- // Now tell GraphicBufferMapper we won't be using these handles anymore
- unregisterBufferHelper(tgtBuffer);
- unregisterBufferHelper(buffer);
}
}
@@ -233,24 +219,22 @@
const unsigned height = std::min(tgtBuffer.height,
srcBuffer.height);
- android::GraphicBufferMapper &mapper = android::GraphicBufferMapper::get();
-
+ sp<android::GraphicBuffer> tgt = new android::GraphicBuffer(
+ tgtBuffer.memHandle, android::GraphicBuffer::CLONE_HANDLE,
+ tgtBuffer.width, tgtBuffer.height, tgtBuffer.format, 1, tgtBuffer.usage,
+ tgtBuffer.stride);
+ sp<android::GraphicBuffer> src = new android::GraphicBuffer(
+ srcBuffer.memHandle, android::GraphicBuffer::CLONE_HANDLE,
+ srcBuffer.width, srcBuffer.height, srcBuffer.format, 1, srcBuffer.usage,
+ srcBuffer.stride);
// Lock our source buffer for reading
unsigned char* srcPixels = nullptr;
- mapper.registerBuffer(srcBuffer.memHandle);
- mapper.lock(srcBuffer.memHandle,
- GRALLOC_USAGE_SW_READ_OFTEN,
- android::Rect(width, height),
- (void **) &srcPixels);
+ src->lock(GRALLOC_USAGE_SW_READ_OFTEN, (void**)&srcPixels);
// Lock our target buffer for writing
unsigned char* tgtPixels = nullptr;
- mapper.registerBuffer(tgtBuffer.memHandle);
- mapper.lock(tgtBuffer.memHandle,
- GRALLOC_USAGE_SW_WRITE_OFTEN,
- android::Rect(width, height),
- (void **) &tgtPixels);
+ tgt->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)&tgtPixels);
if (srcPixels && tgtPixels) {
for (unsigned row = 0; row < height; row++) {
@@ -267,45 +251,11 @@
}
if (srcPixels) {
- mapper.unlock(srcBuffer.memHandle);
+ src->unlock();
}
if (tgtPixels) {
- mapper.unlock(tgtBuffer.memHandle);
+ tgt->unlock();
}
- mapper.unregisterBuffer(srcBuffer.memHandle);
- mapper.unregisterBuffer(tgtBuffer.memHandle);
return success;
}
-
-
-void FrameHandler::registerBufferHelper(const BufferDesc& buffer)
-{
- // In order for the handles passed through HIDL and stored in the BufferDesc to
- // be lockable, we must register them with GraphicBufferMapper.
- // If the device upon which we're running supports gralloc1, we could just call
- // registerBuffer directly with the handle. But that call is broken for gralloc0 devices
- // (which we care about, at least for now). As a result, we have to synthesize a GraphicBuffer
- // object around the buffer handle in order to make a call to the overloaded alternate
- // version of the registerBuffer call that does happen to work on gralloc0 devices.
-#if REGISTER_BUFFER_ALWAYS_WORKS
- android::GraphicBufferMapper::get().registerBuffer(buffer.memHandle);
-#else
- android::sp<android::GraphicBuffer> pGfxBuff = new android::GraphicBuffer(
- buffer.width, buffer.height, buffer.format,
- 1, /* we always use exactly one layer */
- buffer.usage, buffer.stride,
- const_cast<native_handle_t*>(buffer.memHandle.getNativeHandle()),
- false /* GraphicBuffer should not try to free the handle */
- );
-
- android::GraphicBufferMapper::get().registerBuffer(pGfxBuff.get());
-#endif
-}
-
-
-void FrameHandler::unregisterBufferHelper(const BufferDesc& buffer)
-{
- // Now tell GraphicBufferMapper we won't be using these handles anymore
- android::GraphicBufferMapper::get().unregisterBuffer(buffer.memHandle);
-}
diff --git a/automotive/evs/1.0/vts/functional/FrameHandler.h b/automotive/evs/1.0/vts/functional/FrameHandler.h
index d5c3f6b..17a3980 100644
--- a/automotive/evs/1.0/vts/functional/FrameHandler.h
+++ b/automotive/evs/1.0/vts/functional/FrameHandler.h
@@ -68,8 +68,6 @@
// Local implementation details
bool copyBufferContents(const BufferDesc& tgtBuffer, const BufferDesc& srcBuffer);
- void registerBufferHelper(const BufferDesc& buffer);
- void unregisterBufferHelper(const BufferDesc& buffer);
// Values initialized as startup
android::sp <IEvsCamera> mCamera;
diff --git a/camera/device/1.0/Android.bp b/camera/device/1.0/Android.bp
index 44a108c..81e41aa 100644
--- a/camera/device/1.0/Android.bp
+++ b/camera/device/1.0/Android.bp
@@ -66,7 +66,6 @@
"libutils",
"libcutils",
"android.hardware.camera.common@1.0",
- "android.hardware.graphics.allocator@2.0",
"android.hardware.graphics.common@1.0",
"android.hidl.base@1.0",
],
@@ -76,7 +75,6 @@
"libhwbinder",
"libutils",
"android.hardware.camera.common@1.0",
- "android.hardware.graphics.allocator@2.0",
"android.hardware.graphics.common@1.0",
"android.hidl.base@1.0",
],
diff --git a/camera/device/1.0/ICameraDevicePreviewCallback.hal b/camera/device/1.0/ICameraDevicePreviewCallback.hal
index 4c9b517..5421981 100644
--- a/camera/device/1.0/ICameraDevicePreviewCallback.hal
+++ b/camera/device/1.0/ICameraDevicePreviewCallback.hal
@@ -17,7 +17,6 @@
package android.hardware.camera.device@1.0;
import android.hardware.camera.common@1.0::types;
-import android.hardware.graphics.allocator@2.0::types;
import android.hardware.graphics.common@1.0::types;
/**
@@ -89,7 +88,7 @@
*
* @return Status The status code for this operation.
*/
- setUsage(ProducerUsage usage) generates (Status status);
+ setUsage(BufferUsage usage) generates (Status status);
/**
* Set the expected buffering mode for the preview output.
diff --git a/camera/device/1.0/default/CameraDevice.cpp b/camera/device/1.0/default/CameraDevice.cpp
index 6495f30..cb20fec 100644
--- a/camera/device/1.0/default/CameraDevice.cpp
+++ b/camera/device/1.0/default/CameraDevice.cpp
@@ -30,7 +30,7 @@
namespace V1_0 {
namespace implementation {
-using ::android::hardware::graphics::allocator::V2_0::ProducerUsage;
+using ::android::hardware::graphics::common::V1_0::BufferUsage;
using ::android::hardware::graphics::common::V1_0::PixelFormat;
HandleImporter& CameraDevice::sHandleImporter = HandleImporter::getInstance();
@@ -259,7 +259,7 @@
}
object->cleanUpCirculatingBuffers();
- return getStatusT(object->mPreviewCallback->setUsage((ProducerUsage) usage));
+ return getStatusT(object->mPreviewCallback->setUsage((BufferUsage)usage));
}
int CameraDevice::sSetSwapInterval(struct preview_stream_ops *w, int interval) {
diff --git a/camera/device/3.2/Android.bp b/camera/device/3.2/Android.bp
index fd7276f..7807a85 100644
--- a/camera/device/3.2/Android.bp
+++ b/camera/device/3.2/Android.bp
@@ -66,7 +66,6 @@
"libutils",
"libcutils",
"android.hardware.camera.common@1.0",
- "android.hardware.graphics.allocator@2.0",
"android.hardware.graphics.common@1.0",
"android.hidl.base@1.0",
],
@@ -76,7 +75,6 @@
"libhwbinder",
"libutils",
"android.hardware.camera.common@1.0",
- "android.hardware.graphics.allocator@2.0",
"android.hardware.graphics.common@1.0",
"android.hidl.base@1.0",
],
diff --git a/camera/device/3.2/default/CameraDeviceSession.cpp b/camera/device/3.2/default/CameraDeviceSession.cpp
index 5b3024b..5bb53c7 100644
--- a/camera/device/3.2/default/CameraDeviceSession.cpp
+++ b/camera/device/3.2/default/CameraDeviceSession.cpp
@@ -650,7 +650,8 @@
mVideoStreamIds.clear();
for (const auto& stream : requestedConfiguration.streams) {
if (stream.streamType == StreamType::OUTPUT &&
- stream.usage & graphics::allocator::V2_0::ConsumerUsage::VIDEO_ENCODER) {
+ stream.usage &
+ graphics::common::V1_0::BufferUsage::VIDEO_ENCODER) {
mVideoStreamIds.push_back(stream.id);
}
}
diff --git a/camera/device/3.2/default/convert.cpp b/camera/device/3.2/default/convert.cpp
index c7cc75a..d878deb 100644
--- a/camera/device/3.2/default/convert.cpp
+++ b/camera/device/3.2/default/convert.cpp
@@ -28,8 +28,7 @@
using ::android::hardware::graphics::common::V1_0::Dataspace;
using ::android::hardware::graphics::common::V1_0::PixelFormat;
-using ::android::hardware::camera::device::V3_2::ConsumerUsageFlags;
-using ::android::hardware::camera::device::V3_2::ProducerUsageFlags;
+using ::android::hardware::camera::device::V3_2::BufferUsageFlags;
bool convertFromHidl(const CameraMetadata &src, const camera_metadata_t** dst) {
if (src.size() == 0) {
@@ -78,11 +77,11 @@
dst->overrideFormat = (PixelFormat) src->format;
dst->maxBuffers = src->max_buffers;
if (src->stream_type == CAMERA3_STREAM_OUTPUT) {
- dst->consumerUsage = (ConsumerUsageFlags) 0;
- dst->producerUsage = (ProducerUsageFlags) src->usage;
+ dst->consumerUsage = (BufferUsageFlags)0;
+ dst->producerUsage = (BufferUsageFlags)src->usage;
} else if (src->stream_type == CAMERA3_STREAM_INPUT) {
- dst->producerUsage = (ProducerUsageFlags) 0;
- dst->consumerUsage = (ConsumerUsageFlags) src->usage;
+ dst->producerUsage = (BufferUsageFlags)0;
+ dst->consumerUsage = (BufferUsageFlags)src->usage;
} else {
//Should not reach here per current HIDL spec, but we might end up adding
// bi-directional stream to HIDL.
diff --git a/camera/device/3.2/types.hal b/camera/device/3.2/types.hal
index 5ae7a18..1632570 100644
--- a/camera/device/3.2/types.hal
+++ b/camera/device/3.2/types.hal
@@ -16,12 +16,10 @@
package android.hardware.camera.device@3.2;
-import android.hardware.graphics.allocator@2.0::types;
import android.hardware.graphics.common@1.0::types;
typedef vec<uint8_t> CameraMetadata;
-typedef bitfield<ProducerUsage> ProducerUsageFlags;
-typedef bitfield<ConsumerUsage> ConsumerUsageFlags;
+typedef bitfield<BufferUsage> BufferUsageFlags;
typedef bitfield<Dataspace> DataspaceFlags;
/**
@@ -255,7 +253,7 @@
* with ILLEGAL_ARGUMENT if the combined flags cannot be supported due to
* imcompatible buffer format, dataSpace, or other hardware limitations.
*/
- ConsumerUsageFlags usage;
+ BufferUsageFlags usage;
/**
* A field that describes the contents of the buffer. The format and buffer
@@ -373,8 +371,8 @@
* consumerUsage must be set. For other types, producerUsage must be set,
* and consumerUsage must be 0.
*/
- ProducerUsageFlags producerUsage;
- ConsumerUsageFlags consumerUsage;
+ BufferUsageFlags producerUsage;
+ BufferUsageFlags consumerUsage;
/**
* The maximum number of buffers the HAL device may need to have dequeued at
diff --git a/camera/provider/2.4/Android.bp b/camera/provider/2.4/Android.bp
index 1656325..d295f3e 100644
--- a/camera/provider/2.4/Android.bp
+++ b/camera/provider/2.4/Android.bp
@@ -57,7 +57,6 @@
"android.hardware.camera.common@1.0",
"android.hardware.camera.device@1.0",
"android.hardware.camera.device@3.2",
- "android.hardware.graphics.allocator@2.0",
"android.hardware.graphics.common@1.0",
"android.hidl.base@1.0",
],
@@ -69,7 +68,6 @@
"android.hardware.camera.common@1.0",
"android.hardware.camera.device@1.0",
"android.hardware.camera.device@3.2",
- "android.hardware.graphics.allocator@2.0",
"android.hardware.graphics.common@1.0",
"android.hidl.base@1.0",
],
diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
index 74e6efe..e37f989 100644
--- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
+++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
@@ -52,8 +52,8 @@
using ::android::BufferItemConsumer;
using ::android::Surface;
using ::android::CameraParameters;
+using ::android::hardware::graphics::common::V1_0::BufferUsage;
using ::android::hardware::graphics::common::V1_0::PixelFormat;
-using ::android::hardware::graphics::allocator::V2_0::ProducerUsage;
using ::android::hardware::camera::common::V1_0::Status;
using ::android::hardware::camera::common::V1_0::CameraDeviceStatus;
using ::android::hardware::camera::common::V1_0::TorchMode;
@@ -233,7 +233,7 @@
Return<Status> setCrop(int32_t left, int32_t top,
int32_t right, int32_t bottom) override;
- Return<Status> setUsage(ProducerUsage usage) override;
+ Return<Status> setUsage(BufferUsage usage) override;
Return<Status> setSwapInterval(int32_t interval) override;
@@ -408,7 +408,7 @@
return mapToStatus(rc);
}
-Return<Status> PreviewWindowCb::setUsage(ProducerUsage usage) {
+Return<Status> PreviewWindowCb::setUsage(BufferUsage usage) {
auto rc = native_window_set_usage(mAnw.get(), static_cast<int>(usage));
if (rc == ::android::OK) {
mPreviewUsage = static_cast<int>(usage);
diff --git a/drm/1.0/vts/functional/drm_hal_vendor_test.cpp b/drm/1.0/vts/functional/drm_hal_vendor_test.cpp
index 44675dc..5945c05 100644
--- a/drm/1.0/vts/functional/drm_hal_vendor_test.cpp
+++ b/drm/1.0/vts/functional/drm_hal_vendor_test.cpp
@@ -33,7 +33,8 @@
#include "drm_hal_vendor_module_api.h"
#include "vendor_modules.h"
-#include "VtsHalHidlTargetTestBase.h"
+#include <VtsHalHidlTargetCallbackBase.h>
+#include <VtsHalHidlTargetTestBase.h>
using ::android::hardware::drm::V1_0::BufferType;
using ::android::hardware::drm::V1_0::DestinationBuffer;
@@ -77,6 +78,7 @@
using ContentConfiguration = ::DrmHalVTSVendorModule_V1::ContentConfiguration;
using Key = ::DrmHalVTSVendorModule_V1::ContentConfiguration::Key;
+using VtsTestBase = ::testing::VtsHalHidlTargetTestBase;
#define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk())
#define EXPECT_OK(ret) EXPECT_TRUE(ret.isOk())
@@ -105,14 +107,22 @@
GetParam().c_str());
ASSERT_NE(vendorModule, nullptr);
+
+ // First try the binderized service name provided by the vendor module.
+ // If that fails, which it can on non-binderized devices, try the default
+ // service.
string name = vendorModule->getServiceName();
- drmFactory =
- ::testing::VtsHalHidlTargetTestBase::getService<IDrmFactory>(
- name != "default" ? name : "drm");
+ drmFactory = VtsTestBase::getService<IDrmFactory>(name);
+ if (drmFactory == nullptr) {
+ drmFactory = VtsTestBase::getService<IDrmFactory>("drm");
+ }
ASSERT_NE(drmFactory, nullptr);
- cryptoFactory =
- ::testing::VtsHalHidlTargetTestBase::getService<ICryptoFactory>(
- name != "default" ? name : "crypto");
+
+ // Dot the same for the crypto factory
+ cryptoFactory = VtsTestBase::getService<ICryptoFactory>(name);
+ if (cryptoFactory == nullptr) {
+ VtsTestBase::getService<ICryptoFactory>("crypto");
+ }
ASSERT_NE(cryptoFactory, nullptr);
}
@@ -825,71 +835,59 @@
/**
* Event Handling tests
*/
+struct ListenerEventArgs {
+ EventType eventType;
+ SessionId sessionId;
+ hidl_vec<uint8_t> data;
+ int64_t expiryTimeInMS;
+ hidl_vec<KeyStatus> keyStatusList;
+ bool hasNewUsableKey;
+};
-class TestDrmPluginListener : public IDrmPluginListener {
+const char *kCallbackEvent = "SendEvent";
+const char *kCallbackExpirationUpdate = "SendExpirationUpdate";
+const char *kCallbackKeysChange = "SendKeysChange";
+
+class TestDrmPluginListener
+ : public ::testing::VtsHalHidlTargetCallbackBase<ListenerEventArgs>,
+ public IDrmPluginListener {
public:
- TestDrmPluginListener() {reset();}
+ TestDrmPluginListener() {
+ SetWaitTimeoutDefault(std::chrono::milliseconds(500));
+ }
virtual ~TestDrmPluginListener() {}
virtual Return<void> sendEvent(EventType eventType, const hidl_vec<uint8_t>& sessionId,
const hidl_vec<uint8_t>& data) override {
- eventType_ = eventType;
- sessionId_ = sessionId;
- data_ = data;
- gotEvent_ = true;
+ ListenerEventArgs args;
+ args.eventType = eventType;
+ args.sessionId = sessionId;
+ args.data = data;
+ NotifyFromCallback(kCallbackEvent, args);
return Void();
}
virtual Return<void> sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId,
int64_t expiryTimeInMS) override {
- sessionId_ = sessionId;
- expiryTimeInMS_ = expiryTimeInMS;
- gotExpirationUpdate_ = true;
+ ListenerEventArgs args;
+ args.sessionId = sessionId;
+ args.expiryTimeInMS = expiryTimeInMS;
+ NotifyFromCallback(kCallbackExpirationUpdate, args);
return Void();
}
virtual Return<void> sendKeysChange(const hidl_vec<uint8_t>& sessionId,
const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey) override {
- sessionId_ = sessionId;
- keyStatusList_ = keyStatusList;
- hasNewUsableKey_ = hasNewUsableKey;
- gotKeysChange_ = true;
+ ListenerEventArgs args;
+ args.sessionId = sessionId;
+ args.keyStatusList = keyStatusList;
+ args.hasNewUsableKey = hasNewUsableKey;
+ NotifyFromCallback(kCallbackKeysChange, args);
return Void();
}
-
- EventType getEventType() const {return eventType_;}
- SessionId getSessionId() const {return sessionId_;}
- vector<uint8_t> getData() const {return data_;}
- int64_t getExpiryTimeInMS() const {return expiryTimeInMS_;}
- hidl_vec<KeyStatus> getKeyStatusList() const {return keyStatusList_;}
- bool hasNewUsableKey() {return hasNewUsableKey_;}
- bool gotEvent() {return gotEvent_;}
- bool gotExpirationUpdate() {return gotExpirationUpdate_;}
- bool gotKeysChange() {return gotKeysChange_;}
-
- void reset() {
- gotEvent_ = gotExpirationUpdate_ = gotKeysChange_ = false;
- eventType_ = EventType::PROVISION_REQUIRED;
- sessionId_ = SessionId();
- data_ = hidl_vec<uint8_t>();
- expiryTimeInMS_ = 0;
- keyStatusList_ = hidl_vec<KeyStatus>();
- hasNewUsableKey_ = false;
- }
-
-private:
- bool gotEvent_;
- bool gotExpirationUpdate_;
- bool gotKeysChange_;
-
- EventType eventType_;
- SessionId sessionId_;
- hidl_vec<uint8_t> data_;
- int64_t expiryTimeInMS_;
- hidl_vec<KeyStatus> keyStatusList_;
- bool hasNewUsableKey_;
};
+
/**
* Simulate the plugin sending events. Make sure the listener
* gets them.
@@ -898,19 +896,20 @@
sp<TestDrmPluginListener> listener = new TestDrmPluginListener();
drmPlugin->setListener(listener);
auto sessionId = openSession();
- vector<uint8_t> data = {0, 1, 2};
+ hidl_vec<uint8_t> data = {0, 1, 2};
EventType eventTypes[] = {EventType::PROVISION_REQUIRED,
EventType::KEY_NEEDED,
EventType::KEY_EXPIRED,
EventType::VENDOR_DEFINED,
EventType::SESSION_RECLAIMED};
for (auto eventType : eventTypes) {
- listener->reset();
drmPlugin->sendEvent(eventType, sessionId, data);
- while (!listener->gotEvent()) {usleep(100);}
- EXPECT_EQ(eventType, listener->getEventType());
- EXPECT_EQ(sessionId, listener->getSessionId());
- EXPECT_EQ(data, listener->getData());
+ auto result = listener->WaitForCallback(kCallbackEvent);
+ EXPECT_TRUE(result.no_timeout);
+ EXPECT_TRUE(result.args);
+ EXPECT_EQ(eventType, result.args->eventType);
+ EXPECT_EQ(sessionId, result.args->sessionId);
+ EXPECT_EQ(data, result.args->data);
}
closeSession(sessionId);
}
@@ -924,9 +923,11 @@
drmPlugin->setListener(listener);
auto sessionId = openSession();
drmPlugin->sendExpirationUpdate(sessionId, 100);
- while (!listener->gotExpirationUpdate()) {usleep(100);}
- EXPECT_EQ(sessionId, listener->getSessionId());
- EXPECT_EQ(100, listener->getExpiryTimeInMS());
+ auto result = listener->WaitForCallback(kCallbackExpirationUpdate);
+ EXPECT_TRUE(result.no_timeout);
+ EXPECT_TRUE(result.args);
+ EXPECT_EQ(sessionId, result.args->sessionId);
+ EXPECT_EQ(100, result.args->expiryTimeInMS);
closeSession(sessionId);
}
@@ -947,10 +948,11 @@
};
drmPlugin->sendKeysChange(sessionId, keyStatusList, true);
- while (!listener->gotKeysChange()) {usleep(100);}
- EXPECT_EQ(sessionId, listener->getSessionId());
- EXPECT_EQ(keyStatusList, listener->getKeyStatusList());
- EXPECT_EQ(true, listener->hasNewUsableKey());
+ auto result = listener->WaitForCallback(kCallbackKeysChange);
+ EXPECT_TRUE(result.no_timeout);
+ EXPECT_TRUE(result.args);
+ EXPECT_EQ(sessionId, result.args->sessionId);
+ EXPECT_EQ(keyStatusList, result.args->keyStatusList);
}
/**
@@ -963,15 +965,14 @@
drmPlugin->setListener(nullptr);
SessionId sessionId;
- vector<uint8_t> data;
+ hidl_vec<uint8_t> data;
hidl_vec<KeyStatus> keyStatusList;
drmPlugin->sendEvent(EventType::PROVISION_REQUIRED, sessionId, data);
drmPlugin->sendExpirationUpdate(sessionId, 100);
drmPlugin->sendKeysChange(sessionId, keyStatusList, true);
- usleep(1000); // can't wait for the event to be recieved, just wait a long time
- EXPECT_EQ(false, listener->gotEvent());
- EXPECT_EQ(false, listener->gotExpirationUpdate());
- EXPECT_EQ(false, listener->gotKeysChange());
+ auto result = listener->WaitForCallbackAny(
+ {kCallbackEvent, kCallbackExpirationUpdate, kCallbackKeysChange});
+ EXPECT_FALSE(result.no_timeout);
}
diff --git a/graphics/Android.bp b/graphics/Android.bp
index f4f7db4..9aea85f 100644
--- a/graphics/Android.bp
+++ b/graphics/Android.bp
@@ -2,7 +2,6 @@
subdirs = [
"allocator/2.0",
"allocator/2.0/default",
- "allocator/2.0/vts/functional",
"bufferqueue/1.0",
"common/1.0",
"composer/2.1",
diff --git a/graphics/allocator/2.0/Android.bp b/graphics/allocator/2.0/Android.bp
index 271f2ce..f707468 100644
--- a/graphics/allocator/2.0/Android.bp
+++ b/graphics/allocator/2.0/Android.bp
@@ -3,9 +3,7 @@
filegroup {
name: "android.hardware.graphics.allocator@2.0_hal",
srcs: [
- "types.hal",
"IAllocator.hal",
- "IAllocatorClient.hal",
],
}
@@ -17,9 +15,7 @@
":android.hardware.graphics.allocator@2.0_hal",
],
out: [
- "android/hardware/graphics/allocator/2.0/types.cpp",
"android/hardware/graphics/allocator/2.0/AllocatorAll.cpp",
- "android/hardware/graphics/allocator/2.0/AllocatorClientAll.cpp",
],
}
@@ -31,18 +27,11 @@
":android.hardware.graphics.allocator@2.0_hal",
],
out: [
- "android/hardware/graphics/allocator/2.0/types.h",
- "android/hardware/graphics/allocator/2.0/hwtypes.h",
"android/hardware/graphics/allocator/2.0/IAllocator.h",
"android/hardware/graphics/allocator/2.0/IHwAllocator.h",
"android/hardware/graphics/allocator/2.0/BnHwAllocator.h",
"android/hardware/graphics/allocator/2.0/BpHwAllocator.h",
"android/hardware/graphics/allocator/2.0/BsAllocator.h",
- "android/hardware/graphics/allocator/2.0/IAllocatorClient.h",
- "android/hardware/graphics/allocator/2.0/IHwAllocatorClient.h",
- "android/hardware/graphics/allocator/2.0/BnHwAllocatorClient.h",
- "android/hardware/graphics/allocator/2.0/BpHwAllocatorClient.h",
- "android/hardware/graphics/allocator/2.0/BsAllocatorClient.h",
],
}
@@ -59,6 +48,7 @@
"libutils",
"libcutils",
"android.hardware.graphics.common@1.0",
+ "android.hardware.graphics.mapper@2.0",
"android.hidl.base@1.0",
],
export_shared_lib_headers: [
@@ -67,6 +57,7 @@
"libhwbinder",
"libutils",
"android.hardware.graphics.common@1.0",
+ "android.hardware.graphics.mapper@2.0",
"android.hidl.base@1.0",
],
}
diff --git a/graphics/allocator/2.0/IAllocator.hal b/graphics/allocator/2.0/IAllocator.hal
index bf0e141..43a3916 100644
--- a/graphics/allocator/2.0/IAllocator.hal
+++ b/graphics/allocator/2.0/IAllocator.hal
@@ -16,38 +16,9 @@
package android.hardware.graphics.allocator@2.0;
-import IAllocatorClient;
+import android.hardware.graphics.mapper@2.0;
interface IAllocator {
- enum Capability : int32_t {
- /** reserved */
- INVALID = 0,
-
- /**
- * IAllocatorClient::testAllocate must always return UNDEFINED unless
- * this capability is supported.
- */
- TEST_ALLOCATE = 1,
-
- /**
- * IAllocatorClient::BufferDescriptorInfo::layerCount must be 1 unless
- * this capability is supported.
- */
- LAYERED_BUFFERS = 2,
- };
-
- /**
- * Provides a list of supported capabilities (as described in the
- * definition of Capability above). This list must not change after
- * initialization.
- *
- * @return capabilities is a list of supported capabilities.
- */
- @entry
- @exit
- @callflow(next="*")
- getCapabilities() generates (vec<Capability> capabilities);
-
/**
* Retrieves implementation-defined debug information, which will be
* displayed during, for example, `dumpsys SurfaceFlinger`.
@@ -60,15 +31,27 @@
dumpDebugInfo() generates (string debugInfo);
/**
- * Creates a client of the allocator. All resources created by the client
- * are owned by the client and are only visible to the client, unless they
- * are exported by exportHandle.
+ * Allocates buffers with the properties specified by the descriptor.
*
+ * @param descriptor specifies the properties of the buffers to allocate.
+ * @param count is the number of buffers to allocate.
* @return error is NONE upon success. Otherwise,
- * NO_RESOURCES when no more client can currently be created.
- * @return client is the newly created client.
+ * BAD_DESCRIPTOR when the descriptor is invalid.
+ * NO_RESOURCES when the allocation cannot be fulfilled at this
+ * time.
+ * UNSUPPORTED when any of the property encoded in the descriptor
+ * is not supported.
+ * @return stride is the number of pixels between two consecutive rows of
+ * the buffers, when the concept of consecutive rows is defined.
+ * Otherwise, it has no meaning.
+ * @return buffers is an array of raw handles to the newly allocated
+ * buffers.
*/
@entry
+ @exit
@callflow(next="*")
- createClient() generates (Error error, IAllocatorClient client);
+ allocate(BufferDescriptor descriptor, uint32_t count)
+ generates (Error error,
+ uint32_t stride,
+ vec<handle> buffers);
};
diff --git a/graphics/allocator/2.0/IAllocatorClient.hal b/graphics/allocator/2.0/IAllocatorClient.hal
deleted file mode 100644
index 8ca568f..0000000
--- a/graphics/allocator/2.0/IAllocatorClient.hal
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.graphics.allocator@2.0;
-
-import android.hardware.graphics.common@1.0::PixelFormat;
-
-interface IAllocatorClient {
- struct BufferDescriptorInfo {
- /**
- * The width specifies how many columns of pixels must be in the
- * allocated buffer, but does not necessarily represent the offset in
- * columns between the same column in adjacent rows. The rows may be
- * padded.
- */
- uint32_t width;
-
- /**
- * The height specifies how many rows of pixels must be in the
- * allocated buffer.
- */
- uint32_t height;
-
- /**
- * The number of image layers that must be in the allocated buffer.
- */
- uint32_t layerCount;
-
- /** Buffer pixel format. */
- PixelFormat format;
-
- /**
- * Buffer producer usage mask; valid flags can be found in the
- * definition of ProducerUsage.
- */
- uint64_t producerUsageMask;
-
- /**
- * Buffer consumer usage mask; valid flags can be found in the
- * definition of ConsumerUsage.
- */
- uint64_t consumerUsageMask;
- };
-
- /**
- * Creates a new, opaque buffer descriptor.
- *
- * @param descriptorInfo specifies the attributes of the buffer
- * descriptor.
- * @return error is NONE upon success. Otherwise,
- * BAD_VALUE when any attribute in descriptorInfo is invalid.
- * NO_RESOURCES when no more descriptors can currently be created.
- * @return descriptor is the newly created buffer descriptor.
- */
- @entry
- @callflow(next="*")
- createDescriptor(BufferDescriptorInfo descriptorInfo)
- generates (Error error,
- BufferDescriptor descriptor);
-
- /**
- * Destroys an existing buffer descriptor.
- *
- * @param descriptor is the descriptor to destroy.
- * @return error is either NONE or BAD_DESCRIPTOR.
- */
- @exit
- @callflow(next="*")
- destroyDescriptor(BufferDescriptor descriptor) generates (Error error);
-
- /**
- * Tests whether a buffer allocation can succeed, ignoring potential
- * resource contention which might lead to a NO_RESOURCES error.
- *
- * @param descriptors is a list of buffer descriptors.
- * @return error is NONE or NOT_SHARED upon success;
- * NONE when buffers can be created and share a backing store.
- * NOT_SHARED when buffers can be created but require more than a
- * backing store.
- * Otherwise,
- * BAD_DESCRIPTOR when any of the descriptors is invalid.
- * UNSUPPORTED when any of the descriptors can never be satisfied.
- * UNDEFINED when TEST_ALLOCATE is not listed in getCapabilities.
- */
- @callflow(next="allocate")
- testAllocate(vec<BufferDescriptor> descriptors) generates (Error error);
-
- /**
- * Attempts to allocate a list of buffers sharing a backing store.
- *
- * Each buffer must correspond to one of the descriptors passed into the
- * function and must hold a reference to its backing store. If the device
- * is unable to share the backing store between the buffers, it must
- * attempt to allocate the buffers with different backing stores and
- * return NOT_SHARED if it is successful.
- *
- * @param descriptors is the buffer descriptors to attempt to allocate.
- * @return error is NONE or NOT_SHARED upon success;
- * NONE when buffers can be created and share a backing store.
- * NOT_SHARED when buffers can be created but require more than a
- * backing store.
- * Otherwise,
- * BAD_DESCRIPTOR when any of the descriptors is invalid.
- * UNSUPPORTED when any of the descriptors can never be satisfied.
- * NO_RESOURCES when any of the buffers cannot be created at this
- * time.
- * @return buffers is the allocated buffers.
- */
- @callflow(next="exportHandle")
- allocate(vec<BufferDescriptor> descriptors)
- generates (Error error,
- vec<Buffer> buffers);
-
- /**
- * Frees a buffer.
- *
- * @param buffer is the buffer to be freed.
- * @return error is NONE upon success. Otherwise,
- * BAD_BUFFER when the buffer is invalid.
- */
- @exit
- @callflow(next="*")
- free(Buffer buffer) generates (Error error);
-
- /**
- * Exports a buffer for use in other client libraries or for cross-process
- * sharing.
- *
- * The exported handle is a handle to the backing store of the buffer, not
- * to the buffer itself. It however may not hold any reference to the
- * backing store and may be considered invalid by client libraries. To use
- * it and, in most cases, to save it for later use, a client must make a
- * clone of the handle and have the cloned handle hold a reference to the
- * backing store. Such a cloned handle will stay valid even after the
- * original buffer is freed. Refer to native_handle_clone and IMapper for
- * how a handle is cloned and how a reference is added.
- *
- * @param descriptor is the descriptor used to allocate the buffer.
- * @param buffer is the buffer to be exported.
- * @return error is NONE upon success. Otherwise,
- * BAD_DESCRIPTOR when the descriptor is invalid.
- * BAD_BUFFER when the buffer is invalid.
- * BAD_VALUE when descriptor and buffer do not match.
- * NO_RESOURCES when the buffer cannot be exported at this time.
- * @return bufferHandle is the exported handle.
- */
- @callflow(next="free")
- exportHandle(BufferDescriptor descriptor,
- Buffer buffer)
- generates (Error error,
- handle bufferHandle);
-};
diff --git a/graphics/allocator/2.0/default/Android.bp b/graphics/allocator/2.0/default/Android.bp
index 0baef89..4a7cfe0 100644
--- a/graphics/allocator/2.0/default/Android.bp
+++ b/graphics/allocator/2.0/default/Android.bp
@@ -3,7 +3,7 @@
defaults: ["hidl_defaults"],
proprietary: true,
relative_install_path: "hw",
- srcs: ["Gralloc.cpp"],
+ srcs: ["Gralloc.cpp", "Gralloc0Allocator.cpp", "Gralloc1Allocator.cpp"],
cppflags: ["-Wall", "-Wextra"],
shared_libs: [
"android.hardware.graphics.allocator@2.0",
@@ -15,6 +15,9 @@
"liblog",
"libutils",
],
+ header_libs: [
+ "libgrallocmapperincludes",
+ ],
}
cc_binary {
diff --git a/graphics/allocator/2.0/default/Gralloc.cpp b/graphics/allocator/2.0/default/Gralloc.cpp
index 0b9e863..273d3f5 100644
--- a/graphics/allocator/2.0/default/Gralloc.cpp
+++ b/graphics/allocator/2.0/default/Gralloc.cpp
@@ -16,17 +16,11 @@
#define LOG_TAG "GrallocPassthrough"
-#include <mutex>
-#include <type_traits>
-#include <unordered_set>
-#include <vector>
-
-#include <string.h>
-
-#include <hardware/gralloc1.h>
-#include <log/log.h>
-
#include "Gralloc.h"
+#include "Gralloc0Allocator.h"
+#include "Gralloc1Allocator.h"
+
+#include <log/log.h>
namespace android {
namespace hardware {
@@ -35,417 +29,6 @@
namespace V2_0 {
namespace implementation {
-class GrallocHal : public IAllocator {
-public:
- GrallocHal(const hw_module_t* module);
- virtual ~GrallocHal();
-
- // IAllocator 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;
-
- Error createDescriptor(
- const IAllocatorClient::BufferDescriptorInfo& descriptorInfo,
- BufferDescriptor* outDescriptor);
- Error destroyDescriptor(BufferDescriptor descriptor);
-
- Error testAllocate(const hidl_vec<BufferDescriptor>& descriptors);
- Error allocate(const hidl_vec<BufferDescriptor>& descriptors,
- hidl_vec<Buffer>* outBuffers);
- Error free(Buffer buffer);
-
- Error exportHandle(Buffer buffer, const native_handle_t** outHandle);
-
-private:
- void initCapabilities();
-
- template<typename T>
- void initDispatch(gralloc1_function_descriptor_t desc, T* outPfn);
- void initDispatch();
-
- bool hasCapability(Capability capability) const;
-
- gralloc1_device_t* mDevice;
-
- std::unordered_set<Capability> mCapabilities;
-
- struct {
- GRALLOC1_PFN_DUMP dump;
- GRALLOC1_PFN_CREATE_DESCRIPTOR createDescriptor;
- GRALLOC1_PFN_DESTROY_DESCRIPTOR destroyDescriptor;
- GRALLOC1_PFN_SET_DIMENSIONS setDimensions;
- GRALLOC1_PFN_SET_FORMAT setFormat;
- GRALLOC1_PFN_SET_LAYER_COUNT setLayerCount;
- GRALLOC1_PFN_SET_CONSUMER_USAGE setConsumerUsage;
- GRALLOC1_PFN_SET_PRODUCER_USAGE setProducerUsage;
- GRALLOC1_PFN_ALLOCATE allocate;
- GRALLOC1_PFN_RELEASE release;
- } mDispatch;
-};
-
-class GrallocClient : public IAllocatorClient {
-public:
- GrallocClient(GrallocHal& hal);
- virtual ~GrallocClient();
-
- // IAllocatorClient interface
- Return<void> createDescriptor(const BufferDescriptorInfo& descriptorInfo,
- createDescriptor_cb hidl_cb) override;
- Return<Error> destroyDescriptor(BufferDescriptor descriptor) override;
-
- Return<Error> testAllocate(
- const hidl_vec<BufferDescriptor>& descriptors) override;
- Return<void> allocate(const hidl_vec<BufferDescriptor>& descriptors,
- allocate_cb hidl_cb) override;
- Return<Error> free(Buffer buffer) override;
-
- Return<void> exportHandle(BufferDescriptor descriptor,
- Buffer buffer, exportHandle_cb hidl_cb) override;
-
-private:
- GrallocHal& mHal;
-
- std::mutex mMutex;
- std::unordered_set<BufferDescriptor> mDescriptors;
- std::unordered_set<Buffer> mBuffers;
-};
-
-GrallocHal::GrallocHal(const hw_module_t* module)
- : mDevice(nullptr), mDispatch()
-{
- int status = gralloc1_open(module, &mDevice);
- if (status) {
- LOG_ALWAYS_FATAL("failed to open gralloc1 device: %s",
- strerror(-status));
- }
-
- initCapabilities();
- initDispatch();
-}
-
-GrallocHal::~GrallocHal()
-{
- gralloc1_close(mDevice);
-}
-
-void GrallocHal::initCapabilities()
-{
- uint32_t count = 0;
- mDevice->getCapabilities(mDevice, &count, nullptr);
-
- std::vector<Capability> caps(count);
- mDevice->getCapabilities(mDevice, &count, reinterpret_cast<
- std::underlying_type<Capability>::type*>(caps.data()));
- caps.resize(count);
-
- mCapabilities.insert(caps.cbegin(), caps.cend());
-}
-
-template<typename T>
-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);
- }
-
- *outPfn = reinterpret_cast<T>(pfn);
-}
-
-void GrallocHal::initDispatch()
-{
- 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(GRALLOC1_FUNCTION_SET_LAYER_COUNT,
- &mDispatch.setLayerCount);
- }
- 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
-{
- return (mCapabilities.count(capability) > 0);
-}
-
-Return<void> GrallocHal::getCapabilities(getCapabilities_cb hidl_cb)
-{
- std::vector<Capability> caps(
- mCapabilities.cbegin(), mCapabilities.cend());
-
- hidl_vec<Capability> reply;
- reply.setToExternal(caps.data(), caps.size());
- hidl_cb(reply);
-
- return Void();
-}
-
-Return<void> GrallocHal::dumpDebugInfo(dumpDebugInfo_cb hidl_cb)
-{
- uint32_t len = 0;
- mDispatch.dump(mDevice, &len, nullptr);
-
- std::vector<char> buf(len + 1);
- mDispatch.dump(mDevice, &len, buf.data());
- buf.resize(len + 1);
- buf[len] = '\0';
-
- hidl_string reply;
- reply.setToExternal(buf.data(), len);
- hidl_cb(reply);
-
- return Void();
-}
-
-Return<void> GrallocHal::createClient(createClient_cb hidl_cb)
-{
- sp<IAllocatorClient> client = new GrallocClient(*this);
- hidl_cb(Error::NONE, client);
-
- return Void();
-}
-
-Error GrallocHal::createDescriptor(
- const IAllocatorClient::BufferDescriptorInfo& descriptorInfo,
- BufferDescriptor* outDescriptor)
-{
- gralloc1_buffer_descriptor_t descriptor;
- int32_t err = mDispatch.createDescriptor(mDevice, &descriptor);
- if (err != GRALLOC1_ERROR_NONE) {
- return static_cast<Error>(err);
- }
-
- err = mDispatch.setDimensions(mDevice, descriptor,
- descriptorInfo.width, descriptorInfo.height);
- if (err == GRALLOC1_ERROR_NONE) {
- err = mDispatch.setFormat(mDevice, descriptor,
- static_cast<int32_t>(descriptorInfo.format));
- }
- if (err == GRALLOC1_ERROR_NONE) {
- if (hasCapability(Capability::LAYERED_BUFFERS)) {
- err = mDispatch.setLayerCount(mDevice, descriptor,
- descriptorInfo.layerCount);
- } else if (descriptorInfo.layerCount != 1) {
- err = GRALLOC1_ERROR_BAD_VALUE;
- }
- }
- if (err == GRALLOC1_ERROR_NONE) {
- uint64_t producerUsageMask = descriptorInfo.producerUsageMask;
- if (producerUsageMask & GRALLOC1_PRODUCER_USAGE_CPU_READ_OFTEN) {
- producerUsageMask |= GRALLOC1_PRODUCER_USAGE_CPU_READ;
- }
- if (producerUsageMask & GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN) {
- producerUsageMask |= GRALLOC1_PRODUCER_USAGE_CPU_WRITE;
- }
- err = mDispatch.setProducerUsage(mDevice, descriptor,
- descriptorInfo.producerUsageMask);
- }
- if (err == GRALLOC1_ERROR_NONE) {
- uint64_t consumerUsageMask = descriptorInfo.consumerUsageMask;
- if (consumerUsageMask & GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN) {
- consumerUsageMask |= GRALLOC1_CONSUMER_USAGE_CPU_READ;
- }
- err = mDispatch.setConsumerUsage(mDevice, descriptor,
- consumerUsageMask);
- }
-
- if (err == GRALLOC1_ERROR_NONE) {
- *outDescriptor = descriptor;
- } else {
- mDispatch.destroyDescriptor(mDevice, descriptor);
- }
-
- return static_cast<Error>(err);
-}
-
-Error GrallocHal::destroyDescriptor(BufferDescriptor descriptor)
-{
- int32_t err = mDispatch.destroyDescriptor(mDevice, descriptor);
- return static_cast<Error>(err);
-}
-
-Error GrallocHal::testAllocate(const hidl_vec<BufferDescriptor>& descriptors)
-{
- if (!hasCapability(Capability::TEST_ALLOCATE)) {
- return Error::UNDEFINED;
- }
-
- int32_t err = mDispatch.allocate(mDevice, descriptors.size(),
- descriptors.data(), nullptr);
- return static_cast<Error>(err);
-}
-
-Error GrallocHal::allocate(const hidl_vec<BufferDescriptor>& descriptors,
- 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>(
- reinterpret_cast<uintptr_t>(buffers[i]));
- }
- }
-
- return static_cast<Error>(err);
-}
-
-Error GrallocHal::free(Buffer buffer)
-{
- buffer_handle_t handle = reinterpret_cast<buffer_handle_t>(
- static_cast<uintptr_t>(buffer));
-
- int32_t err = mDispatch.release(mDevice, handle);
- return static_cast<Error>(err);
-}
-
-Error GrallocHal::exportHandle(Buffer buffer,
- const native_handle_t** outHandle)
-{
- // we rely on the caller to validate buffer here
- *outHandle = reinterpret_cast<buffer_handle_t>(
- static_cast<uintptr_t>(buffer));
- return Error::NONE;
-}
-
-GrallocClient::GrallocClient(GrallocHal& hal)
- : mHal(hal)
-{
-}
-
-GrallocClient::~GrallocClient()
-{
- if (!mBuffers.empty()) {
- ALOGW("client destroyed with valid buffers");
- for (auto buf : mBuffers) {
- mHal.free(buf);
- }
- }
-
- if (!mDescriptors.empty()) {
- ALOGW("client destroyed with valid buffer descriptors");
- for (auto desc : mDescriptors) {
- mHal.destroyDescriptor(desc);
- }
- }
-}
-
-Return<void> GrallocClient::createDescriptor(
- const BufferDescriptorInfo& descriptorInfo,
- createDescriptor_cb hidl_cb)
-{
- BufferDescriptor descriptor = 0;
- Error err = mHal.createDescriptor(descriptorInfo, &descriptor);
-
- if (err == Error::NONE) {
- std::lock_guard<std::mutex> lock(mMutex);
-
- auto result = mDescriptors.insert(descriptor);
- if (!result.second) {
- ALOGW("duplicated buffer descriptor id returned");
- mHal.destroyDescriptor(descriptor);
- err = Error::NO_RESOURCES;
- }
- }
-
- hidl_cb(err, descriptor);
- return Void();
-}
-
-Return<Error> GrallocClient::destroyDescriptor(BufferDescriptor descriptor)
-{
- {
- std::lock_guard<std::mutex> lock(mMutex);
- if (!mDescriptors.erase(descriptor)) {
- return Error::BAD_DESCRIPTOR;
- }
- }
-
- return mHal.destroyDescriptor(descriptor);
-}
-
-Return<Error> GrallocClient::testAllocate(
- const hidl_vec<BufferDescriptor>& descriptors)
-{
- return mHal.testAllocate(descriptors);
-}
-
-Return<void> GrallocClient::allocate(
- const hidl_vec<BufferDescriptor>& descriptors,
- allocate_cb hidl_cb) {
- hidl_vec<Buffer> buffers;
- Error err = mHal.allocate(descriptors, &buffers);
-
- if (err == Error::NONE || err == Error::NOT_SHARED) {
- std::lock_guard<std::mutex> lock(mMutex);
-
- for (size_t i = 0; i < buffers.size(); i++) {
- auto result = mBuffers.insert(buffers[i]);
- if (!result.second) {
- ALOGW("duplicated buffer id returned");
-
- for (size_t j = 0; j < buffers.size(); j++) {
- if (j < i) {
- mBuffers.erase(buffers[i]);
- }
- mHal.free(buffers[i]);
- }
-
- buffers = hidl_vec<Buffer>();
- err = Error::NO_RESOURCES;
- break;
- }
- }
- }
-
- hidl_cb(err, buffers);
- return Void();
-}
-
-Return<Error> GrallocClient::free(Buffer buffer)
-{
- {
- std::lock_guard<std::mutex> lock(mMutex);
- if (!mBuffers.erase(buffer)) {
- return Error::BAD_BUFFER;
- }
- }
-
- return mHal.free(buffer);
-}
-
-Return<void> GrallocClient::exportHandle(BufferDescriptor /*descriptor*/,
- Buffer buffer, exportHandle_cb hidl_cb)
-{
- const native_handle_t* handle = nullptr;
-
- {
- std::lock_guard<std::mutex> lock(mMutex);
- if (mBuffers.count(buffer) == 0) {
- hidl_cb(Error::BAD_BUFFER, handle);
- return Void();
- }
- }
-
- Error err = mHal.exportHandle(buffer, &handle);
-
- hidl_cb(err, handle);
- return Void();
-}
-
IAllocator* HIDL_FETCH_IAllocator(const char* /* name */) {
const hw_module_t* module = nullptr;
int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
@@ -455,12 +38,15 @@
}
uint8_t major = (module->module_api_version >> 8) & 0xff;
- if (major != 1) {
- ALOGE("unknown gralloc module major version %d", major);
- return nullptr;
+ switch (major) {
+ case 1:
+ return new Gralloc1Allocator(module);
+ case 0:
+ return new Gralloc0Allocator(module);
+ default:
+ ALOGE("unknown gralloc module major version %d", major);
+ return nullptr;
}
-
- return new GrallocHal(module);
}
} // namespace implementation
diff --git a/graphics/allocator/2.0/default/Gralloc0Allocator.cpp b/graphics/allocator/2.0/default/Gralloc0Allocator.cpp
new file mode 100644
index 0000000..3b62bb3
--- /dev/null
+++ b/graphics/allocator/2.0/default/Gralloc0Allocator.cpp
@@ -0,0 +1,144 @@
+/*
+ * 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 "Gralloc0Allocator"
+
+#include "Gralloc0Allocator.h"
+#include "GrallocBufferDescriptor.h"
+
+#include <vector>
+
+#include <string.h>
+
+#include <log/log.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace allocator {
+namespace V2_0 {
+namespace implementation {
+
+using android::hardware::graphics::mapper::V2_0::implementation::
+ grallocDecodeBufferDescriptor;
+
+Gralloc0Allocator::Gralloc0Allocator(const hw_module_t* module) {
+ int result = gralloc_open(module, &mDevice);
+ if (result) {
+ LOG_ALWAYS_FATAL("failed to open gralloc0 device: %s",
+ strerror(-result));
+ }
+}
+
+Gralloc0Allocator::~Gralloc0Allocator() {
+ gralloc_close(mDevice);
+}
+
+Return<void> Gralloc0Allocator::dumpDebugInfo(dumpDebugInfo_cb hidl_cb) {
+ char buf[4096] = {};
+ if (mDevice->dump) {
+ mDevice->dump(mDevice, buf, sizeof(buf));
+ buf[sizeof(buf) - 1] = '\0';
+ }
+
+ hidl_cb(hidl_string(buf));
+
+ return Void();
+}
+
+Return<void> Gralloc0Allocator::allocate(const BufferDescriptor& descriptor,
+ uint32_t count, allocate_cb hidl_cb) {
+ IMapper::BufferDescriptorInfo descriptorInfo;
+ if (!grallocDecodeBufferDescriptor(descriptor, &descriptorInfo)) {
+ hidl_cb(Error::BAD_DESCRIPTOR, 0, hidl_vec<hidl_handle>());
+ return Void();
+ }
+
+ Error error = Error::NONE;
+ uint32_t stride = 0;
+ std::vector<hidl_handle> buffers;
+ buffers.reserve(count);
+
+ // allocate the buffers
+ for (uint32_t i = 0; i < count; i++) {
+ buffer_handle_t tmpBuffer;
+ uint32_t tmpStride;
+ error = allocateOne(descriptorInfo, &tmpBuffer, &tmpStride);
+ if (error != Error::NONE) {
+ break;
+ }
+
+ if (stride == 0) {
+ stride = tmpStride;
+ } else if (stride != tmpStride) {
+ // non-uniform strides
+ mDevice->free(mDevice, tmpBuffer);
+ stride = 0;
+ error = Error::UNSUPPORTED;
+ break;
+ }
+
+ buffers.emplace_back(hidl_handle(tmpBuffer));
+ }
+
+ // return the buffers
+ hidl_vec<hidl_handle> hidl_buffers;
+ if (error == Error::NONE) {
+ hidl_buffers.setToExternal(buffers.data(), buffers.size());
+ }
+ hidl_cb(error, stride, hidl_buffers);
+
+ // free the buffers
+ for (const auto& buffer : buffers) {
+ mDevice->free(mDevice, buffer.getNativeHandle());
+ }
+
+ return Void();
+}
+
+Error Gralloc0Allocator::allocateOne(const IMapper::BufferDescriptorInfo& info,
+ buffer_handle_t* outBuffer,
+ uint32_t* outStride) {
+ if (info.layerCount > 1 || (info.usage >> 32) != 0) {
+ return Error::BAD_VALUE;
+ }
+
+ buffer_handle_t buffer = nullptr;
+ int stride = 0;
+ int result = mDevice->alloc(mDevice, info.width, info.height,
+ static_cast<int>(info.format), info.usage,
+ &buffer, &stride);
+ if (result) {
+ switch (result) {
+ case -EINVAL:
+ return Error::BAD_VALUE;
+ default:
+ return Error::NO_RESOURCES;
+ }
+ }
+
+ *outBuffer = buffer;
+ *outStride = stride;
+
+ return Error::NONE;
+}
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace allocator
+} // namespace graphics
+} // namespace hardware
+} // namespace android
diff --git a/graphics/allocator/2.0/default/Gralloc0Allocator.h b/graphics/allocator/2.0/default/Gralloc0Allocator.h
new file mode 100644
index 0000000..0e90527
--- /dev/null
+++ b/graphics/allocator/2.0/default/Gralloc0Allocator.h
@@ -0,0 +1,59 @@
+/*
+ * 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_ALLOCATOR_V2_0_GRALLOC0ALLOCATOR_H
+#define ANDROID_HARDWARE_GRAPHICS_ALLOCATOR_V2_0_GRALLOC0ALLOCATOR_H
+
+#include <android/hardware/graphics/allocator/2.0/IAllocator.h>
+#include <android/hardware/graphics/mapper/2.0/IMapper.h>
+#include <hardware/gralloc.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace allocator {
+namespace V2_0 {
+namespace implementation {
+
+using android::hardware::graphics::mapper::V2_0::IMapper;
+using android::hardware::graphics::mapper::V2_0::BufferDescriptor;
+using android::hardware::graphics::mapper::V2_0::Error;
+
+class Gralloc0Allocator : public IAllocator {
+ public:
+ Gralloc0Allocator(const hw_module_t* module);
+ virtual ~Gralloc0Allocator();
+
+ // IAllocator interface
+ Return<void> dumpDebugInfo(dumpDebugInfo_cb hidl_cb) override;
+ Return<void> allocate(const BufferDescriptor& descriptor, uint32_t count,
+ allocate_cb hidl_cb) override;
+
+ private:
+ Error allocateOne(const IMapper::BufferDescriptorInfo& info,
+ buffer_handle_t* outBuffer, uint32_t* outStride);
+
+ alloc_device_t* mDevice;
+};
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace allocator
+} // namespace graphics
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GRAPHICS_ALLOCATOR_V2_0_GRALLOC0ALLOCATOR_H
diff --git a/graphics/allocator/2.0/default/Gralloc1Allocator.cpp b/graphics/allocator/2.0/default/Gralloc1Allocator.cpp
new file mode 100644
index 0000000..c0a5e1e
--- /dev/null
+++ b/graphics/allocator/2.0/default/Gralloc1Allocator.cpp
@@ -0,0 +1,321 @@
+/*
+ * 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 "Gralloc1Allocator"
+
+#include "Gralloc1Allocator.h"
+#include "GrallocBufferDescriptor.h"
+
+#include <vector>
+
+#include <string.h>
+
+#include <log/log.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace allocator {
+namespace V2_0 {
+namespace implementation {
+
+using android::hardware::graphics::common::V1_0::BufferUsage;
+using android::hardware::graphics::mapper::V2_0::implementation::
+ grallocDecodeBufferDescriptor;
+
+Gralloc1Allocator::Gralloc1Allocator(const hw_module_t* module)
+ : mDevice(nullptr), mCapabilities(), mDispatch() {
+ int result = gralloc1_open(module, &mDevice);
+ if (result) {
+ LOG_ALWAYS_FATAL("failed to open gralloc1 device: %s",
+ strerror(-result));
+ }
+
+ initCapabilities();
+ initDispatch();
+}
+
+Gralloc1Allocator::~Gralloc1Allocator() {
+ gralloc1_close(mDevice);
+}
+
+void Gralloc1Allocator::initCapabilities() {
+ uint32_t count = 0;
+ mDevice->getCapabilities(mDevice, &count, nullptr);
+
+ std::vector<int32_t> capabilities(count);
+ mDevice->getCapabilities(mDevice, &count, capabilities.data());
+ capabilities.resize(count);
+
+ for (auto capability : capabilities) {
+ if (capability == GRALLOC1_CAPABILITY_LAYERED_BUFFERS) {
+ mCapabilities.layeredBuffers = true;
+ break;
+ }
+ }
+}
+
+template <typename T>
+void Gralloc1Allocator::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);
+ }
+
+ *outPfn = reinterpret_cast<T>(pfn);
+}
+
+void Gralloc1Allocator::initDispatch() {
+ 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 (mCapabilities.layeredBuffers) {
+ initDispatch(GRALLOC1_FUNCTION_SET_LAYER_COUNT,
+ &mDispatch.setLayerCount);
+ }
+ initDispatch(GRALLOC1_FUNCTION_SET_CONSUMER_USAGE,
+ &mDispatch.setConsumerUsage);
+ initDispatch(GRALLOC1_FUNCTION_SET_PRODUCER_USAGE,
+ &mDispatch.setProducerUsage);
+ initDispatch(GRALLOC1_FUNCTION_GET_STRIDE, &mDispatch.getStride);
+ initDispatch(GRALLOC1_FUNCTION_ALLOCATE, &mDispatch.allocate);
+ initDispatch(GRALLOC1_FUNCTION_RELEASE, &mDispatch.release);
+}
+
+Return<void> Gralloc1Allocator::dumpDebugInfo(dumpDebugInfo_cb hidl_cb) {
+ uint32_t len = 0;
+ mDispatch.dump(mDevice, &len, nullptr);
+
+ std::vector<char> buf(len + 1);
+ mDispatch.dump(mDevice, &len, buf.data());
+ buf.resize(len + 1);
+ buf[len] = '\0';
+
+ hidl_string reply;
+ reply.setToExternal(buf.data(), len);
+ hidl_cb(reply);
+
+ return Void();
+}
+
+Return<void> Gralloc1Allocator::allocate(const BufferDescriptor& descriptor,
+ uint32_t count, allocate_cb hidl_cb) {
+ IMapper::BufferDescriptorInfo descriptorInfo;
+ if (!grallocDecodeBufferDescriptor(descriptor, &descriptorInfo)) {
+ hidl_cb(Error::BAD_DESCRIPTOR, 0, hidl_vec<hidl_handle>());
+ return Void();
+ }
+
+ gralloc1_buffer_descriptor_t desc;
+ Error error = createDescriptor(descriptorInfo, &desc);
+ if (error != Error::NONE) {
+ hidl_cb(error, 0, hidl_vec<hidl_handle>());
+ return Void();
+ }
+
+ uint32_t stride = 0;
+ std::vector<hidl_handle> buffers;
+ buffers.reserve(count);
+
+ // allocate the buffers
+ for (uint32_t i = 0; i < count; i++) {
+ buffer_handle_t tmpBuffer;
+ uint32_t tmpStride;
+ error = allocateOne(desc, &tmpBuffer, &tmpStride);
+ if (error != Error::NONE) {
+ break;
+ }
+
+ if (stride == 0) {
+ stride = tmpStride;
+ } else if (stride != tmpStride) {
+ // non-uniform strides
+ mDispatch.release(mDevice, tmpBuffer);
+ stride = 0;
+ error = Error::UNSUPPORTED;
+ break;
+ }
+
+ buffers.emplace_back(hidl_handle(tmpBuffer));
+ }
+
+ mDispatch.destroyDescriptor(mDevice, desc);
+
+ // return the buffers
+ hidl_vec<hidl_handle> hidl_buffers;
+ if (error == Error::NONE) {
+ hidl_buffers.setToExternal(buffers.data(), buffers.size());
+ }
+ hidl_cb(error, stride, hidl_buffers);
+
+ // free the buffers
+ for (const auto& buffer : buffers) {
+ mDispatch.release(mDevice, buffer.getNativeHandle());
+ }
+
+ return Void();
+}
+
+Error Gralloc1Allocator::toError(int32_t error) {
+ switch (error) {
+ case GRALLOC1_ERROR_NONE:
+ return Error::NONE;
+ case GRALLOC1_ERROR_BAD_DESCRIPTOR:
+ return Error::BAD_DESCRIPTOR;
+ case GRALLOC1_ERROR_BAD_HANDLE:
+ return Error::BAD_BUFFER;
+ case GRALLOC1_ERROR_BAD_VALUE:
+ return Error::BAD_VALUE;
+ case GRALLOC1_ERROR_NOT_SHARED:
+ return Error::NONE; // this is fine
+ case GRALLOC1_ERROR_NO_RESOURCES:
+ return Error::NO_RESOURCES;
+ case GRALLOC1_ERROR_UNDEFINED:
+ case GRALLOC1_ERROR_UNSUPPORTED:
+ default:
+ return Error::UNSUPPORTED;
+ }
+}
+
+uint64_t Gralloc1Allocator::toProducerUsage(uint64_t usage) {
+ // this is potentially broken as we have no idea which private flags
+ // should be filtered out
+ uint64_t producerUsage =
+ usage &
+ ~static_cast<uint64_t>(BufferUsage::CPU_READ_MASK |
+ BufferUsage::CPU_WRITE_MASK);
+
+ switch (usage & BufferUsage::CPU_WRITE_MASK) {
+ case static_cast<uint64_t>(BufferUsage::CPU_WRITE_RARELY):
+ producerUsage |= GRALLOC1_PRODUCER_USAGE_CPU_WRITE;
+ break;
+ case static_cast<uint64_t>(BufferUsage::CPU_WRITE_OFTEN):
+ producerUsage |= GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN;
+ break;
+ default:
+ break;
+ }
+
+ switch (usage & BufferUsage::CPU_READ_MASK) {
+ case static_cast<uint64_t>(BufferUsage::CPU_READ_RARELY):
+ producerUsage |= GRALLOC1_PRODUCER_USAGE_CPU_READ;
+ break;
+ case static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN):
+ producerUsage |= GRALLOC1_PRODUCER_USAGE_CPU_READ_OFTEN;
+ break;
+ default:
+ break;
+ }
+
+ return producerUsage;
+}
+
+uint64_t Gralloc1Allocator::toConsumerUsage(uint64_t usage) {
+ // this is potentially broken as we have no idea which private flags
+ // should be filtered out
+ uint64_t consumerUsage =
+ usage &
+ ~static_cast<uint64_t>(BufferUsage::CPU_READ_MASK |
+ BufferUsage::CPU_WRITE_MASK);
+
+ switch (usage & BufferUsage::CPU_READ_MASK) {
+ case static_cast<uint64_t>(BufferUsage::CPU_READ_RARELY):
+ consumerUsage |= GRALLOC1_CONSUMER_USAGE_CPU_READ;
+ break;
+ case static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN):
+ consumerUsage |= GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN;
+ break;
+ default:
+ break;
+ }
+
+ return consumerUsage;
+}
+
+Error Gralloc1Allocator::createDescriptor(
+ const IMapper::BufferDescriptorInfo& info,
+ gralloc1_buffer_descriptor_t* outDescriptor) {
+ gralloc1_buffer_descriptor_t descriptor;
+
+ int32_t error = mDispatch.createDescriptor(mDevice, &descriptor);
+
+ if (error == GRALLOC1_ERROR_NONE) {
+ error = mDispatch.setDimensions(mDevice, descriptor, info.width,
+ info.height);
+ }
+ if (error == GRALLOC1_ERROR_NONE) {
+ error = mDispatch.setFormat(mDevice, descriptor,
+ static_cast<int32_t>(info.format));
+ }
+ if (error == GRALLOC1_ERROR_NONE) {
+ if (mCapabilities.layeredBuffers) {
+ error =
+ mDispatch.setLayerCount(mDevice, descriptor, info.layerCount);
+ } else if (info.layerCount > 1) {
+ error = GRALLOC1_ERROR_UNSUPPORTED;
+ }
+ }
+ if (error == GRALLOC1_ERROR_NONE) {
+ error = mDispatch.setProducerUsage(mDevice, descriptor,
+ toProducerUsage(info.usage));
+ }
+ if (error == GRALLOC1_ERROR_NONE) {
+ error = mDispatch.setConsumerUsage(mDevice, descriptor,
+ toConsumerUsage(info.usage));
+ }
+
+ if (error == GRALLOC1_ERROR_NONE) {
+ *outDescriptor = descriptor;
+ } else {
+ mDispatch.destroyDescriptor(mDevice, descriptor);
+ }
+
+ return toError(error);
+}
+
+Error Gralloc1Allocator::allocateOne(gralloc1_buffer_descriptor_t descriptor,
+ buffer_handle_t* outBuffer,
+ uint32_t* outStride) {
+ buffer_handle_t buffer = nullptr;
+ int32_t error = mDispatch.allocate(mDevice, 1, &descriptor, &buffer);
+ if (error != GRALLOC1_ERROR_NONE && error != GRALLOC1_ERROR_NOT_SHARED) {
+ return toError(error);
+ }
+
+ uint32_t stride = 0;
+ error = mDispatch.getStride(mDevice, buffer, &stride);
+ if (error != GRALLOC1_ERROR_NONE && error != GRALLOC1_ERROR_UNDEFINED) {
+ mDispatch.release(mDevice, buffer);
+ return toError(error);
+ }
+
+ *outBuffer = buffer;
+ *outStride = stride;
+
+ return Error::NONE;
+}
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace allocator
+} // namespace graphics
+} // namespace hardware
+} // namespace android
diff --git a/graphics/allocator/2.0/default/Gralloc1Allocator.h b/graphics/allocator/2.0/default/Gralloc1Allocator.h
new file mode 100644
index 0000000..7b5a966
--- /dev/null
+++ b/graphics/allocator/2.0/default/Gralloc1Allocator.h
@@ -0,0 +1,89 @@
+/*
+ * 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_ALLOCATOR_V2_0_GRALLOC1ALLOCATOR_H
+#define ANDROID_HARDWARE_GRAPHICS_ALLOCATOR_V2_0_GRALLOC1ALLOCATOR_H
+
+#include <android/hardware/graphics/allocator/2.0/IAllocator.h>
+#include <android/hardware/graphics/mapper/2.0/IMapper.h>
+#include <hardware/gralloc1.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace allocator {
+namespace V2_0 {
+namespace implementation {
+
+using android::hardware::graphics::mapper::V2_0::IMapper;
+using android::hardware::graphics::mapper::V2_0::BufferDescriptor;
+using android::hardware::graphics::mapper::V2_0::Error;
+
+class Gralloc1Allocator : public IAllocator {
+ public:
+ Gralloc1Allocator(const hw_module_t* module);
+ virtual ~Gralloc1Allocator();
+
+ // IAllocator interface
+ Return<void> dumpDebugInfo(dumpDebugInfo_cb hidl_cb) override;
+ Return<void> allocate(const BufferDescriptor& descriptor, uint32_t count,
+ allocate_cb hidl_cb) override;
+
+ private:
+ void initCapabilities();
+
+ template <typename T>
+ void initDispatch(gralloc1_function_descriptor_t desc, T* outPfn);
+ void initDispatch();
+
+ static Error toError(int32_t error);
+ static uint64_t toProducerUsage(uint64_t usage);
+ static uint64_t toConsumerUsage(uint64_t usage);
+
+ Error createDescriptor(const IMapper::BufferDescriptorInfo& info,
+ gralloc1_buffer_descriptor_t* outDescriptor);
+ Error allocateOne(gralloc1_buffer_descriptor_t descriptor,
+ buffer_handle_t* outBuffer, uint32_t* outStride);
+
+ gralloc1_device_t* mDevice;
+
+ struct {
+ bool layeredBuffers;
+ } mCapabilities;
+
+ struct {
+ GRALLOC1_PFN_DUMP dump;
+ GRALLOC1_PFN_CREATE_DESCRIPTOR createDescriptor;
+ GRALLOC1_PFN_DESTROY_DESCRIPTOR destroyDescriptor;
+ GRALLOC1_PFN_SET_DIMENSIONS setDimensions;
+ GRALLOC1_PFN_SET_FORMAT setFormat;
+ GRALLOC1_PFN_SET_LAYER_COUNT setLayerCount;
+ GRALLOC1_PFN_SET_CONSUMER_USAGE setConsumerUsage;
+ GRALLOC1_PFN_SET_PRODUCER_USAGE setProducerUsage;
+ GRALLOC1_PFN_GET_STRIDE getStride;
+ GRALLOC1_PFN_ALLOCATE allocate;
+ GRALLOC1_PFN_RELEASE release;
+ } mDispatch;
+};
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace allocator
+} // namespace graphics
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GRAPHICS_ALLOCATOR_V2_0_GRALLOC1ALLOCATOR_H
diff --git a/graphics/allocator/2.0/types.hal b/graphics/allocator/2.0/types.hal
deleted file mode 100644
index d9b184b..0000000
--- a/graphics/allocator/2.0/types.hal
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.graphics.allocator@2.0;
-
-enum Error : int32_t {
- NONE = 0, /** no error */
- BAD_DESCRIPTOR = 1, /** invalid BufferDescriptor */
- BAD_BUFFER = 2, /** invalid Buffer */
- BAD_VALUE = 3, /** invalid width, height, etc. */
- NOT_SHARED = 4, /** buffers not sharing backing store */
- NO_RESOURCES = 5, /** temporary failure due to resource contention */
- UNDEFINED = 6, /** an operation has no defined meaning */
- UNSUPPORTED = 7, /** permanent failure */
-};
-
-enum ProducerUsage : uint64_t {
- /** bit 0 is reserved */
-
- /** buffer is read by CPU occasionally */
- CPU_READ = 1ULL << 1,
- /** buffer is read by CPU frequently */
- CPU_READ_OFTEN = 1ULL << 2,
-
- /** bit 3 is reserved */
- /** bit 4 is reserved */
-
- /** buffer is written by CPU occasionally */
- CPU_WRITE = 1ULL << 5,
- /** buffer is written by CPU frequently */
- CPU_WRITE_OFTEN = 1ULL << 6,
-
- /** bit 7 is reserved */
- /** bit 8 is reserved */
-
- /** buffer is used as a GPU render target */
- GPU_RENDER_TARGET = 1ULL << 9,
-
- /** bit 10 is reserved */
- /** bit 11 is reserved */
- /** bit 12 is reserved */
- /** bit 13 is reserved */
-
- /**
- * Buffer is allocated with hardware-level protection against copying the
- * contents (or information derived from the contents) into unprotected
- * memory.
- */
- PROTECTED = 1ULL << 14,
-
- /** bit 15 is reserved */
- /** bit 16 is reserved */
-
- /** buffer is used as a camera HAL output */
- CAMERA = 1ULL << 17,
-
- /** bit 18 is reserved */
- /** bit 19 is reserved */
- /** bit 20 is reserved */
- /** bit 21 is reserved */
-
- /** buffer is used as a video decoder output */
- VIDEO_DECODER = 1ULL << 22,
-
- /** buffer is used as a sensor direct report output */
- SENSOR_DIRECT_DATA = 1ULL << 23,
-
- /** bits 24-27 are reserved for future versions */
- /** bits 28-31 are reserved for vendor extensions */
-
- /** bits 32-47 are reserved for future versions */
- /** bits 48-63 are reserved for vendor extensions */
-};
-
-enum ConsumerUsage : uint64_t {
- /** bit 0 is reserved */
-
- /** buffer is read by CPU occasionally */
- CPU_READ = 1ULL << 1,
- /** buffer is read by CPU frequently */
- CPU_READ_OFTEN = 1ULL << 2,
-
- /** bit 3 is reserved */
- /** bit 4 is reserved */
- /** bit 5 is reserved */
- /** bit 6 is reserved */
- /** bit 7 is reserved */
-
- /** buffer is used as a GPU texture */
- GPU_TEXTURE = 1ULL << 8,
-
- /** bit 9 is reserved */
- /** bit 10 is reserved */
-
- /** buffer is used by hwcomposer HAL */
- HWCOMPOSER = 1ULL << 11,
- /** buffer is a hwcomposer HAL client target */
- CLIENT_TARGET = 1ULL << 12,
-
- /** bit 13 is reserved */
- /** bit 14 is reserved */
-
- /** buffer is used as a hwcomposer HAL cursor */
- CURSOR = 1ULL << 15,
-
- /** buffer is used as a video encoder input */
- VIDEO_ENCODER = 1ULL << 16,
-
- /** bit 17 is reserved */
-
- /** buffer is used as a camera HAL input */
- CAMERA = 1ULL << 18,
-
- /** bit 19 is reserved */
-
- /** buffer is used as a renderscript allocation */
- RENDERSCRIPT = 1ULL << 20,
-
- /** bit 21 is reserved */
- /** bit 22 is reserved */
-
- /**
- * buffer is used as as an OpenGL shader storage or uniform
- buffer object */
- GPU_DATA_BUFFER = 1ULL << 23,
-
- /** bits 24-27 are reserved for future versions */
- /** bits 28-31 are reserved for vendor extensions */
-
- /** bits 32-47 are reserved for future versions */
- /** bits 48-63 are reserved for vendor extensions */
-};
-
-typedef uint64_t BufferDescriptor;
-typedef uint64_t Buffer;
diff --git a/graphics/allocator/2.0/vts/functional/Android.bp b/graphics/allocator/2.0/vts/functional/Android.bp
deleted file mode 100644
index fb77ab3..0000000
--- a/graphics/allocator/2.0/vts/functional/Android.bp
+++ /dev/null
@@ -1,62 +0,0 @@
-//
-// Copyright (C) 2016 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-cc_library_static {
- name: "libVtsHalGraphicsAllocatorTestUtils",
- defaults: ["hidl_defaults"],
- srcs: ["VtsHalGraphicsAllocatorTestUtils.cpp"],
- shared_libs: [
- "android.hardware.graphics.allocator@2.0",
- ],
- static_libs: [
- "VtsHalHidlTargetTestBase",
- ],
- cflags: [
- "-Wall",
- "-Wextra",
- "-Werror",
- "-O0",
- "-g",
- ],
- export_include_dirs: ["."],
-}
-
-cc_test {
- name: "VtsHalGraphicsAllocatorV2_0TargetTest",
- defaults: ["hidl_defaults"],
- srcs: ["VtsHalGraphicsAllocatorV2_0TargetTest.cpp"],
- shared_libs: [
- "libbase",
- "liblog",
- "libcutils",
- "libhidlbase",
- "libhidltransport",
- "libnativehelper",
- "libutils",
- "android.hardware.graphics.allocator@2.0",
- ],
- static_libs: [
- "libVtsHalGraphicsAllocatorTestUtils",
- "VtsHalHidlTargetTestBase",
- ],
- cflags: [
- "-Wall",
- "-Wextra",
- "-Werror",
- "-O0",
- "-g",
- ]
-}
diff --git a/graphics/allocator/2.0/vts/functional/VtsHalGraphicsAllocatorTestUtils.cpp b/graphics/allocator/2.0/vts/functional/VtsHalGraphicsAllocatorTestUtils.cpp
deleted file mode 100644
index 0dc43be..0000000
--- a/graphics/allocator/2.0/vts/functional/VtsHalGraphicsAllocatorTestUtils.cpp
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <VtsHalHidlTargetTestBase.h>
-
-#include "VtsHalGraphicsAllocatorTestUtils.h"
-
-namespace android {
-namespace hardware {
-namespace graphics {
-namespace allocator {
-namespace V2_0 {
-namespace tests {
-
-Allocator::Allocator() { init(); }
-
-void Allocator::init() {
- mAllocator = ::testing::VtsHalHidlTargetTestBase::getService<IAllocator>();
- ASSERT_NE(nullptr, mAllocator.get()) << "failed to get allocator service";
-
- std::vector<IAllocator::Capability> capabilities = getCapabilities();
- mCapabilities.insert(capabilities.begin(), capabilities.end());
-}
-
-sp<IAllocator> Allocator::getRaw() const { return mAllocator; }
-
-bool Allocator::hasCapability(IAllocator::Capability capability) const {
- return mCapabilities.count(capability) > 0;
-}
-
-std::vector<IAllocator::Capability> Allocator::getCapabilities() {
- std::vector<IAllocator::Capability> capabilities;
- mAllocator->getCapabilities(
- [&](const auto& tmpCapabilities) { capabilities = tmpCapabilities; });
-
- return capabilities;
-}
-
-std::string Allocator::dumpDebugInfo() {
- std::string debugInfo;
- mAllocator->dumpDebugInfo(
- [&](const auto& tmpDebugInfo) { debugInfo = tmpDebugInfo.c_str(); });
-
- return debugInfo;
-}
-
-std::unique_ptr<AllocatorClient> Allocator::createClient() {
- std::unique_ptr<AllocatorClient> client;
- mAllocator->createClient([&](const auto& tmpError, const auto& tmpClient) {
- ASSERT_EQ(Error::NONE, tmpError) << "failed to create client";
- client = std::make_unique<AllocatorClient>(tmpClient);
- });
-
- return client;
-}
-
-AllocatorClient::AllocatorClient(const sp<IAllocatorClient>& client)
- : mClient(client) {}
-
-AllocatorClient::~AllocatorClient() {
- for (auto buffer : mBuffers) {
- EXPECT_EQ(Error::NONE, mClient->free(buffer))
- << "failed to free buffer " << buffer;
- }
- mBuffers.clear();
-
- for (auto descriptor : mDescriptors) {
- EXPECT_EQ(Error::NONE, mClient->destroyDescriptor(descriptor))
- << "failed to destroy descriptor " << descriptor;
- }
- mDescriptors.clear();
-}
-
-sp<IAllocatorClient> AllocatorClient::getRaw() const { return mClient; }
-
-BufferDescriptor AllocatorClient::createDescriptor(
- const IAllocatorClient::BufferDescriptorInfo& info) {
- BufferDescriptor descriptor = 0;
- mClient->createDescriptor(
- info, [&](const auto& tmpError, const auto& tmpDescriptor) {
- ASSERT_EQ(Error::NONE, tmpError) << "failed to create descriptor";
- descriptor = tmpDescriptor;
-
- EXPECT_TRUE(mDescriptors.insert(descriptor).second)
- << "duplicated descriptor id " << descriptor;
- });
-
- return descriptor;
-}
-
-void AllocatorClient::destroyDescriptor(BufferDescriptor descriptor) {
- ASSERT_EQ(Error::NONE, mClient->destroyDescriptor(descriptor))
- << "failed to destroy descriptor " << descriptor;
-
- mDescriptors.erase(descriptor);
-}
-
-Error AllocatorClient::testAllocate(
- const std::vector<BufferDescriptor>& descriptors) {
- return mClient->testAllocate(descriptors);
-}
-
-bool AllocatorClient::testAllocate(BufferDescriptor descriptor) {
- std::vector<BufferDescriptor> descriptors(1, descriptor);
- Error error = testAllocate(descriptors);
- return (error == Error::NONE || error == Error::NOT_SHARED);
-}
-
-Error AllocatorClient::allocate(
- const std::vector<BufferDescriptor>& descriptors,
- std::vector<Buffer>& buffers) {
- Error error = Error::NO_RESOURCES;
- mClient->allocate(descriptors, [&](const auto& tmpError,
- const auto& tmpBuffers) {
- ASSERT_TRUE(tmpError == Error::NONE || tmpError == Error::NOT_SHARED)
- << "failed to allocate buffer";
- ASSERT_EQ(descriptors.size(), tmpBuffers.size()) << "invalid buffer count";
-
- error = tmpError;
- buffers = tmpBuffers;
-
- for (auto buffer : buffers) {
- EXPECT_TRUE(mBuffers.insert(buffer).second)
- << "duplicated buffer id " << buffer;
- }
- });
-
- return error;
-}
-
-Buffer AllocatorClient::allocate(BufferDescriptor descriptor) {
- std::vector<BufferDescriptor> descriptors(1, descriptor);
- std::vector<Buffer> buffers;
- allocate(descriptors, buffers);
- if (::testing::Test::HasFatalFailure()) {
- return 0;
- }
-
- return buffers[0];
-}
-
-void AllocatorClient::free(Buffer buffer) {
- ASSERT_EQ(Error::NONE, mClient->free(buffer))
- << "failed to free buffer " << buffer;
-
- mBuffers.erase(buffer);
-}
-
-native_handle_t* AllocatorClient::exportHandle(BufferDescriptor descriptor,
- Buffer buffer) {
- native_handle_t* handle;
- mClient->exportHandle(
- descriptor, buffer, [&](const auto& tmpError, const auto& tmpHandle) {
- ASSERT_EQ(Error::NONE, tmpError) << "failed to export buffer handle";
- ASSERT_NE(nullptr, tmpHandle.getNativeHandle())
- << "invalid buffer handle";
-
- handle = native_handle_clone(tmpHandle.getNativeHandle());
- ASSERT_NE(nullptr, handle) << "failed to clone handle";
- });
-
- return handle;
-}
-
-} // namespace tests
-} // namespace V2_0
-} // namespace allocator
-} // namespace graphics
-} // namespace hardware
-} // namespace android
diff --git a/graphics/allocator/2.0/vts/functional/VtsHalGraphicsAllocatorTestUtils.h b/graphics/allocator/2.0/vts/functional/VtsHalGraphicsAllocatorTestUtils.h
deleted file mode 100644
index c9bfe8f..0000000
--- a/graphics/allocator/2.0/vts/functional/VtsHalGraphicsAllocatorTestUtils.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef VTS_HAL_GRAPHICS_ALLOCATOR_UTILS
-#define VTS_HAL_GRAPHICS_ALLOCATOR_UTILS
-
-#include <memory>
-#include <string>
-#include <unordered_set>
-#include <vector>
-
-#include <android/hardware/graphics/allocator/2.0/IAllocator.h>
-#include <utils/StrongPointer.h>
-
-namespace android {
-namespace hardware {
-namespace graphics {
-namespace allocator {
-namespace V2_0 {
-namespace tests {
-
-class AllocatorClient;
-
-// A wrapper to IAllocator.
-class Allocator {
- public:
- Allocator();
-
- sp<IAllocator> getRaw() const;
-
- // Returns true when the allocator supports the specified capability.
- bool hasCapability(IAllocator::Capability capability) const;
-
- std::vector<IAllocator::Capability> getCapabilities();
- std::string dumpDebugInfo();
- std::unique_ptr<AllocatorClient> createClient();
-
- private:
- void init();
-
- sp<IAllocator> mAllocator;
- std::unordered_set<IAllocator::Capability> mCapabilities;
-};
-
-// A wrapper to IAllocatorClient.
-class AllocatorClient {
- public:
- AllocatorClient(const sp<IAllocatorClient>& client);
- ~AllocatorClient();
-
- sp<IAllocatorClient> getRaw() const;
-
- BufferDescriptor createDescriptor(
- const IAllocatorClient::BufferDescriptorInfo& info);
- void destroyDescriptor(BufferDescriptor descriptor);
-
- Error testAllocate(const std::vector<BufferDescriptor>& descriptors);
- bool testAllocate(BufferDescriptor descriptor);
-
- Error allocate(const std::vector<BufferDescriptor>& descriptors,
- std::vector<Buffer>& buffers);
- Buffer allocate(BufferDescriptor descriptor);
- void free(Buffer buffer);
-
- // Returns a handle to the buffer. The ownership of the handle is
- // transferred to the caller.
- native_handle_t* exportHandle(BufferDescriptor descriptor, Buffer buffer);
-
- private:
- sp<IAllocatorClient> mClient;
-
- // Keep track of all descriptors and buffers. When a test fails with
- // ASSERT_*, the destructor will clean up the resources for the test.
- std::unordered_set<BufferDescriptor> mDescriptors;
- std::unordered_set<Buffer> mBuffers;
-};
-
-} // namespace tests
-} // namespace V2_0
-} // namespace allocator
-} // namespace graphics
-} // namespace hardware
-} // namespace android
-
-#endif // VTS_HAL_GRAPHICS_ALLOCATOR_UTILS
diff --git a/graphics/allocator/2.0/vts/functional/VtsHalGraphicsAllocatorV2_0TargetTest.cpp b/graphics/allocator/2.0/vts/functional/VtsHalGraphicsAllocatorV2_0TargetTest.cpp
deleted file mode 100644
index b1c764f..0000000
--- a/graphics/allocator/2.0/vts/functional/VtsHalGraphicsAllocatorV2_0TargetTest.cpp
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "graphics_allocator_hidl_hal_test"
-
-#include <android-base/logging.h>
-#include <VtsHalHidlTargetTestBase.h>
-
-#include "VtsHalGraphicsAllocatorTestUtils.h"
-
-namespace android {
-namespace hardware {
-namespace graphics {
-namespace allocator {
-namespace V2_0 {
-namespace tests {
-namespace {
-
-using android::hardware::graphics::common::V1_0::PixelFormat;
-
-#define CHECK_FEATURE_OR_SKIP(FEATURE_NAME) \
- do { \
- if (!mAllocator->hasCapability(FEATURE_NAME)) { \
- std::cout << "[ SKIPPED ] Feature " << #FEATURE_NAME \
- << " not supported" << std::endl; \
- return; \
- } \
- } while (0)
-
-class GraphicsAllocatorHidlTest : public ::testing::VtsHalHidlTargetTestBase {
- protected:
- void SetUp() override {
- ASSERT_NO_FATAL_FAILURE(mAllocator = std::make_unique<Allocator>());
- ASSERT_NO_FATAL_FAILURE(mClient = mAllocator->createClient());
-
- mDummyDescriptorInfo.width = 64;
- mDummyDescriptorInfo.height = 64;
- mDummyDescriptorInfo.layerCount = 1;
- mDummyDescriptorInfo.format = PixelFormat::RGBA_8888;
- mDummyDescriptorInfo.producerUsageMask =
- static_cast<uint64_t>(ProducerUsage::CPU_WRITE);
- mDummyDescriptorInfo.consumerUsageMask =
- static_cast<uint64_t>(ConsumerUsage::CPU_READ);
- }
-
- void TearDown() override {}
-
- std::unique_ptr<Allocator> mAllocator;
- std::unique_ptr<AllocatorClient> mClient;
- IAllocatorClient::BufferDescriptorInfo mDummyDescriptorInfo{};
-};
-
-TEST_F(GraphicsAllocatorHidlTest, GetCapabilities) {
- auto capabilities = mAllocator->getCapabilities();
- for (auto cap : capabilities) {
- EXPECT_NE(IAllocator::Capability::INVALID, cap);
- }
-}
-
-TEST_F(GraphicsAllocatorHidlTest, DumpDebugInfo) {
- mAllocator->dumpDebugInfo();
-}
-
-TEST_F(GraphicsAllocatorHidlTest, CreateDestroyDescriptor) {
- BufferDescriptor descriptor;
- ASSERT_NO_FATAL_FAILURE(descriptor =
- mClient->createDescriptor(mDummyDescriptorInfo));
- mClient->destroyDescriptor(descriptor);
-}
-
-/**
- * Test testAllocate with a single buffer descriptor.
- */
-TEST_F(GraphicsAllocatorHidlTest, TestAllocateBasic) {
- CHECK_FEATURE_OR_SKIP(IAllocator::Capability::TEST_ALLOCATE);
-
- BufferDescriptor descriptor;
- ASSERT_NO_FATAL_FAILURE(descriptor =
- mClient->createDescriptor(mDummyDescriptorInfo));
-
- ASSERT_TRUE(mClient->testAllocate(descriptor));
-}
-
-/**
- * Test testAllocate with two buffer descriptors.
- */
-TEST_F(GraphicsAllocatorHidlTest, TestAllocateArray) {
- CHECK_FEATURE_OR_SKIP(IAllocator::Capability::TEST_ALLOCATE);
-
- BufferDescriptor descriptor;
- ASSERT_NO_FATAL_FAILURE(descriptor =
- mClient->createDescriptor(mDummyDescriptorInfo));
-
- hidl_vec<BufferDescriptor> descriptors;
- descriptors.resize(2);
- descriptors[0] = descriptor;
- descriptors[1] = descriptor;
-
- auto error = mClient->testAllocate(descriptors);
- ASSERT_TRUE(error == Error::NONE || error == Error::NOT_SHARED);
-}
-
-/**
- * Test allocate/free with a single buffer descriptor.
- */
-TEST_F(GraphicsAllocatorHidlTest, AllocateFreeBasic) {
- BufferDescriptor descriptor;
- ASSERT_NO_FATAL_FAILURE(descriptor =
- mClient->createDescriptor(mDummyDescriptorInfo));
-
- Buffer buffer;
- ASSERT_NO_FATAL_FAILURE(buffer = mClient->allocate(descriptor));
-
- mClient->free(buffer);
-}
-
-/**
- * Test allocate/free with an array of buffer descriptors.
- */
-TEST_F(GraphicsAllocatorHidlTest, AllocateFreeArray) {
- BufferDescriptor descriptor1;
- ASSERT_NO_FATAL_FAILURE(descriptor1 =
- mClient->createDescriptor(mDummyDescriptorInfo));
-
- BufferDescriptor descriptor2;
- ASSERT_NO_FATAL_FAILURE(descriptor2 =
- mClient->createDescriptor(mDummyDescriptorInfo));
-
- hidl_vec<BufferDescriptor> descriptors;
- descriptors.resize(3);
- descriptors[0] = descriptor1;
- descriptors[1] = descriptor1;
- descriptors[2] = descriptor2;
-
- std::vector<Buffer> buffers;
- ASSERT_NO_FATAL_FAILURE(mClient->allocate(descriptors, buffers));
-
- for (auto buf : buffers) {
- mClient->free(buf);
- }
-}
-
-TEST_F(GraphicsAllocatorHidlTest, ExportHandle) {
- BufferDescriptor descriptor;
- ASSERT_NO_FATAL_FAILURE(descriptor =
- mClient->createDescriptor(mDummyDescriptorInfo));
-
- Buffer buffer;
- ASSERT_NO_FATAL_FAILURE(buffer = mClient->allocate(descriptor));
-
- native_handle_t* handle;
- ASSERT_NO_FATAL_FAILURE(handle = mClient->exportHandle(descriptor, buffer));
-
- native_handle_close(handle);
- native_handle_delete(handle);
-}
-
-} // namespace anonymous
-} // namespace tests
-} // namespace V2_0
-} // namespace allocator
-} // namespace graphics
-} // namespace hardware
-} // namespace android
-
-int main(int argc, char** argv) {
- ::testing::InitGoogleTest(&argc, argv);
-
- int status = RUN_ALL_TESTS();
- LOG(INFO) << "Test result = " << status;
-
- return status;
-}
diff --git a/graphics/common/1.0/Android.mk b/graphics/common/1.0/Android.mk
index c08053d..ae80c6a 100644
--- a/graphics/common/1.0/Android.mk
+++ b/graphics/common/1.0/Android.mk
@@ -13,6 +13,25 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
#
+# Build types.hal (BufferUsage)
+#
+GEN := $(intermediates)/android/hardware/graphics/common/V1_0/BufferUsage.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.graphics.common@1.0::types.BufferUsage
+
+$(GEN): $(LOCAL_PATH)/types.hal
+ $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
# Build types.hal (ColorMode)
#
GEN := $(intermediates)/android/hardware/graphics/common/V1_0/ColorMode.java
@@ -139,6 +158,25 @@
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
#
+# Build types.hal (BufferUsage)
+#
+GEN := $(intermediates)/android/hardware/graphics/common/V1_0/BufferUsage.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.graphics.common@1.0::types.BufferUsage
+
+$(GEN): $(LOCAL_PATH)/types.hal
+ $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
# Build types.hal (ColorMode)
#
GEN := $(intermediates)/android/hardware/graphics/common/V1_0/ColorMode.java
diff --git a/graphics/common/1.0/types.hal b/graphics/common/1.0/types.hal
index 8aa0779..3bd1ec1 100644
--- a/graphics/common/1.0/types.hal
+++ b/graphics/common/1.0/types.hal
@@ -450,6 +450,90 @@
};
/**
+ * Buffer usage definitions.
+ */
+enum BufferUsage : uint64_t {
+ /** bit 0-3 is an enum */
+ CPU_READ_MASK = 0xfULL,
+ /** buffer is never read by CPU */
+ CPU_READ_NEVER = 0,
+ /** buffer is rarely read by CPU */
+ CPU_READ_RARELY = 2,
+ /** buffer is often read by CPU */
+ CPU_READ_OFTEN = 3,
+
+ /** bit 4-7 is an enum */
+ CPU_WRITE_MASK = 0xfULL << 4,
+ /** buffer is never written by CPU */
+ CPU_WRITE_NEVER = 0 << 4,
+ /** buffer is rarely written by CPU */
+ CPU_WRITE_RARELY = 2 << 4,
+ /** buffer is often written by CPU */
+ CPU_WRITE_OFTEN = 3 << 4,
+
+ /** buffer is used as a GPU texture */
+ GPU_TEXTURE = 1ULL << 8,
+
+ /** buffer is used as a GPU render target */
+ GPU_RENDER_TARGET = 1ULL << 9,
+
+ /** bit 10 must be zero */
+
+ /** buffer is used as a composer HAL overlay layer */
+ COMPOSER_OVERLAY = 1ULL << 11,
+ /** buffer is used as a composer HAL client target */
+ COMPOSER_CLIENT_TARGET = 1ULL << 12,
+
+ /** bit 13 must be zero */
+
+ /**
+ * Buffer is allocated with hardware-level protection against copying the
+ * contents (or information derived from the contents) into unprotected
+ * memory.
+ */
+ PROTECTED = 1ULL << 14,
+
+ /** buffer is used as a hwcomposer HAL cursor layer */
+ COMPOSER_CURSOR = 1ULL << 15,
+
+ /** buffer is used as a video encoder input */
+ VIDEO_ENCODER = 1ULL << 16,
+
+ /** buffer is used as a camera HAL output */
+ CAMERA_OUTPUT = 1ULL << 17,
+
+ /** buffer is used as a camera HAL input */
+ CAMERA_INPUT = 1ULL << 18,
+
+ /** bit 19 must be zero */
+
+ /** buffer is used as a renderscript allocation */
+ RENDERSCRIPT = 1ULL << 20,
+
+ /** bit 21 must be zero */
+
+ /** buffer is used as a video decoder output */
+ VIDEO_DECODER = 1ULL << 22,
+
+ /** buffer is used as a sensor direct report output */
+ SENSOR_DIRECT_DATA = 1ULL << 23,
+
+ /**
+ * buffer is used as as an OpenGL shader storage or uniform
+ * buffer object
+ */
+ GPU_DATA_BUFFER = 1ULL << 24,
+
+ /** bits 25-27 must be zero and are reserved for future versions */
+ /** bits 28-31 are reserved for vendor extensions */
+ VENDOR_MASK = 0xfULL << 28,
+
+ /** bits 32-47 must be zero and are reserved for future versions */
+ /** bits 48-63 are reserved for vendor extensions */
+ VENDOR_MASK_HI = 0xffffULL << 48,
+};
+
+/**
* Transformation definitions
*
* IMPORTANT NOTE:
diff --git a/graphics/composer/2.1/IComposer.hal b/graphics/composer/2.1/IComposer.hal
index b3ac761..e2aa5cd 100644
--- a/graphics/composer/2.1/IComposer.hal
+++ b/graphics/composer/2.1/IComposer.hal
@@ -44,6 +44,12 @@
* applying the color transform during its composition step.
*/
SKIP_CLIENT_COLOR_TRANSFORM = 2,
+
+ /**
+ * Specifies that the present fence must not be used as an accurate
+ * representation of the actual present time of a frame.
+ */
+ PRESENT_FENCE_IS_NOT_RELIABLE = 3,
};
/**
diff --git a/graphics/composer/2.1/default/Hwc.cpp b/graphics/composer/2.1/default/Hwc.cpp
index 1497065..8ca0eb3 100644
--- a/graphics/composer/2.1/default/Hwc.cpp
+++ b/graphics/composer/2.1/default/Hwc.cpp
@@ -65,6 +65,12 @@
}
initCapabilities();
+ if (majorVersion >= 2 &&
+ hasCapability(Capability::PRESENT_FENCE_IS_NOT_RELIABLE)) {
+ ALOGE("Present fence must be reliable from HWC2 on.");
+ abort();
+ }
+
initDispatch();
}
diff --git a/graphics/composer/2.1/vts/functional/Android.bp b/graphics/composer/2.1/vts/functional/Android.bp
index 8e1f925..66323d4 100644
--- a/graphics/composer/2.1/vts/functional/Android.bp
+++ b/graphics/composer/2.1/vts/functional/Android.bp
@@ -52,7 +52,6 @@
],
static_libs: [
"libhwcomposer-command-buffer",
- "libVtsHalGraphicsAllocatorTestUtils",
"libVtsHalGraphicsComposerTestUtils",
"libVtsHalGraphicsMapperTestUtils",
"VtsHalHidlTargetTestBase",
diff --git a/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp b/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp
index 0da3a33..387222f 100644
--- a/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp
+++ b/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp
@@ -18,7 +18,6 @@
#include <IComposerCommandBuffer.h>
#include <android-base/logging.h>
-#include "VtsHalGraphicsAllocatorTestUtils.h"
#include "VtsHalGraphicsComposerTestUtils.h"
#include "VtsHalGraphicsMapperTestUtils.h"
@@ -40,22 +39,15 @@
namespace tests {
namespace {
-using android::hardware::graphics::allocator::V2_0::Buffer;
-using android::hardware::graphics::allocator::V2_0::BufferDescriptor;
-using android::hardware::graphics::allocator::V2_0::ConsumerUsage;
-using android::hardware::graphics::allocator::V2_0::IAllocator;
-using android::hardware::graphics::allocator::V2_0::IAllocatorClient;
-using android::hardware::graphics::allocator::V2_0::ProducerUsage;
-using android::hardware::graphics::allocator::V2_0::tests::Allocator;
-using android::hardware::graphics::allocator::V2_0::tests::AllocatorClient;
+using android::hardware::graphics::common::V1_0::BufferUsage;
using android::hardware::graphics::common::V1_0::ColorMode;
using android::hardware::graphics::common::V1_0::ColorTransform;
using android::hardware::graphics::common::V1_0::Dataspace;
using android::hardware::graphics::common::V1_0::PixelFormat;
using android::hardware::graphics::common::V1_0::Transform;
using android::hardware::graphics::mapper::V2_0::IMapper;
-using android::hardware::graphics::mapper::V2_0::tests::Mapper;
-using GrallocError = android::hardware::graphics::allocator::V2_0::Error;
+using android::hardware::graphics::mapper::V2_0::tests::Gralloc;
+using GrallocError = android::hardware::graphics::mapper::V2_0::Error;
// IComposerCallback to be installed with IComposerClient::registerCallback.
class GraphicsComposerCallback : public IComposerCallback {
@@ -409,9 +401,7 @@
void SetUp() override {
ASSERT_NO_FATAL_FAILURE(GraphicsComposerHidlTest::SetUp());
- ASSERT_NO_FATAL_FAILURE(mAllocator = std::make_unique<Allocator>());
- ASSERT_NO_FATAL_FAILURE(mAllocatorClient = mAllocator->createClient());
- ASSERT_NO_FATAL_FAILURE(mMapper = std::make_unique<Mapper>());
+ ASSERT_NO_FATAL_FAILURE(mGralloc = std::make_unique<Gralloc>());
mWriter = std::make_unique<CommandWriterBase>(1024);
mReader = std::make_unique<CommandReader>();
@@ -422,15 +412,15 @@
}
const native_handle_t* allocate() {
- IAllocatorClient::BufferDescriptorInfo info{};
- info.width = 64;
- info.height = 64;
- info.layerCount = 1;
- info.format = PixelFormat::RGBA_8888;
- info.producerUsageMask = static_cast<uint64_t>(ProducerUsage::CPU_WRITE);
- info.consumerUsageMask = static_cast<uint64_t>(ConsumerUsage::CPU_READ);
+ IMapper::BufferDescriptorInfo info{};
+ info.width = 64;
+ info.height = 64;
+ info.layerCount = 1;
+ info.format = PixelFormat::RGBA_8888;
+ info.usage = static_cast<uint64_t>(BufferUsage::CPU_WRITE_OFTEN |
+ BufferUsage::CPU_READ_OFTEN);
- return mMapper->allocate(mAllocatorClient, info);
+ return mGralloc->allocate(info);
}
void execute() {
@@ -507,9 +497,7 @@
std::unique_ptr<CommandReader> mReader;
private:
- std::unique_ptr<Allocator> mAllocator;
- std::unique_ptr<AllocatorClient> mAllocatorClient;
- std::unique_ptr<Mapper> mMapper;
+ std::unique_ptr<Gralloc> mGralloc;
};
/**
diff --git a/graphics/mapper/2.0/Android.bp b/graphics/mapper/2.0/Android.bp
index 98a509b..cc2bd73 100644
--- a/graphics/mapper/2.0/Android.bp
+++ b/graphics/mapper/2.0/Android.bp
@@ -51,7 +51,6 @@
"liblog",
"libutils",
"libcutils",
- "android.hardware.graphics.allocator@2.0",
"android.hardware.graphics.common@1.0",
"android.hidl.base@1.0",
],
@@ -60,7 +59,6 @@
"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/IMapper.hal b/graphics/mapper/2.0/IMapper.hal
index 573dcd0..246be24 100644
--- a/graphics/mapper/2.0/IMapper.hal
+++ b/graphics/mapper/2.0/IMapper.hal
@@ -16,10 +16,39 @@
package android.hardware.graphics.mapper@2.0;
-import android.hardware.graphics.common@1.0::PixelFormat;
-import android.hardware.graphics.allocator@2.0;
+import android.hardware.graphics.common@1.0;
interface IMapper {
+ struct BufferDescriptorInfo {
+ /**
+ * The width specifies how many columns of pixels must be in the
+ * allocated buffer, but does not necessarily represent the offset in
+ * columns between the same column in adjacent rows. The rows may be
+ * padded.
+ */
+ uint32_t width;
+
+ /**
+ * The height specifies how many rows of pixels must be in the
+ * allocated buffer.
+ */
+ uint32_t height;
+
+ /**
+ * The number of image layers that must be in the allocated buffer.
+ */
+ uint32_t layerCount;
+
+ /** Buffer pixel format. */
+ PixelFormat format;
+
+ /**
+ * Buffer usage mask; valid flags can be found in the definition of
+ * BufferUsage.
+ */
+ bitfield<BufferUsage> usage;
+ };
+
struct Rect {
int32_t left;
int32_t top;
@@ -28,170 +57,76 @@
};
/**
- * Adds a reference to the given buffer handle.
+ * Creates a buffer descriptor. The descriptor can be used with IAllocator
+ * to allocate buffers.
*
- * A buffer handle received from a remote process or exported by
- * 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.
+ * Since the buffer descriptor fully describes a buffer, any device
+ * dependent or device independent checks must be performed here whenever
+ * possible. Specifically, when layered buffers are not supported, this
+ * function must return UNSUPPORTED if layerCount is great than 1.
*
- * @param bufferHandle is the buffer to which a reference must be added.
+ * @param descriptorInfo specifies the attributes of the descriptor.
* @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
+ * BAD_VALUE when any of the specified attributes is
+ * invalid or conflicting.
+ * NO_RESOURCES when the creation cannot be fullfilled at
+ * this time.
+ * UNSUPPORTED when any of the specified attributes is
+ * not supported.
+ * @return descriptor is the newly created buffer descriptor.
*/
@entry
@callflow(next="*")
- retain(handle bufferHandle) generates (Error error);
+ createDescriptor(BufferDescriptorInfo descriptorInfo)
+ generates (Error error,
+ BufferDescriptor descriptor);
/**
- * Removes a reference from the given buffer buffer.
+ * Imports a raw buffer handle to create an imported buffer handle for use
+ * with the rest of the mapper or with other in-process libraries.
*
- * 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.
+ * A buffer handle is considered raw when it is cloned or when it is
+ * received from another HAL or another process. A raw buffer handle must
+ * not be used to access the underlying graphics buffer. It must be
+ * imported to create an imported handle first.
*
- * @param bufferHandle is the buffer from which a reference must be
- * removed.
+ * This function must at least validate the raw handle before creating the
+ * imported handle. It must also support importing the same raw handle
+ * multiple times to create multiple imported handles. The imported handle
+ * must be considered valid everywhere in the process, including in
+ * another instance of the mapper.
+ *
+ * @param rawHandle is the raw buffer handle to import.
* @return error is NONE upon success. Otherwise,
- * BAD_BUFFER when the buffer handle is invalid.
+ * BAD_BUFFER when the raw handle is invalid.
+ * NO_RESOURCES when the raw handle cannot be imported at
+ * this time.
+ * @return buffer is the imported buffer handle and has the type
+ * buffer_handle_t.
+ */
+ @entry
+ @callflow(next="*")
+ importBuffer(handle rawHandle) generates (Error error, pointer buffer);
+
+ /**
+ * Frees a buffer handle. Buffer handles returned by importBuffer must be
+ * freed with this function when no longer needed.
+ *
+ * This function must free up all resources allocated by importBuffer for
+ * the imported handle. For example, if the imported handle was created
+ * with native_handle_create, this function must call native_handle_close
+ * and native_handle_delete.
+ *
+ * @return error is NONE upon success. Otherwise,
+ * BAD_BUFFER when the buffer is invalid.
*/
@exit
- release(handle bufferHandle) generates (Error error);
-
- /**
- * Gets the width and height of the buffer in pixels.
- *
- * See IAllocator::BufferDescriptorInfo for more information.
- *
- * @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.
- */
@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 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.
- */
- @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 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.
- */
- @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 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.
- */
- @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 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.
- */
- @callflow(next="*")
- getConsumerUsageMask(handle bufferHandle)
- generates (Error error,
- uint64_t usageMask);
-
- /**
- * Gets a value that uniquely identifies the backing store of the given
- * buffer.
- *
- * Buffers which share a backing store should return the same value from
- * this function. If the buffer is present in more than one process, the
- * backing store value for that buffer is not required to be the same in
- * every process.
- *
- * @param device is the mapper device.
- * @param bufferHandle is the buffer from which to get the backing store
- * identifier.
- * @return error is NONE upon success. Otherwise,
- * BAD_BUFFER when the buffer handle is invalid.
- * @return store is the backing store identifier for this buffer.
- */
- @callflow(next="*")
- getBackingStore(handle bufferHandle)
- generates (Error error,
- BackingStore store);
-
- /**
- * Gets the stride of the buffer in pixels.
- *
- * The stride is the offset in pixel-sized elements between the same
- * column in two adjacent rows of pixels. This may not be equal to the
- * width of the buffer.
- *
- * @param device is the mapper device.
- * @param bufferHandle is the buffer from which to get the stride.
- * @return error is NONE upon success. Otherwise,
- * BAD_BUFFER when the buffer handle is invalid.
- * UNDEFINED when the notion of a stride is not
- * meaningful for the buffer format.
- * @return store is the stride in pixels.
- */
- @callflow(next="*")
- getStride(handle bufferHandle)
- generates (Error error,
- uint32_t stride);
+ freeBuffer(pointer buffer) generates (Error error);
/**
* Locks the given buffer for the specified CPU usage.
*
- * Exactly one of producerUsageMask and consumerUsageMask must be 0. The
- * usage which is not 0 must be one of the *Usage::CPU* values, as
- * applicable. Locking a buffer for a non-CPU usage is not supported.
- *
* Locking the same buffer simultaneously from multiple threads is
* permitted, but if any of the threads attempt to lock the buffer for
* writing, the behavior is undefined, except that it must not cause
@@ -209,39 +144,27 @@
* address will represent the top-left corner of the entire buffer, even
* if accessRegion does not begin at the top-left corner.
*
- * acquireFence is a file descriptor referring to a acquire sync fence
- * object, which will be signaled when it is safe for the device to access
- * the contents of the buffer (prior to locking). If it is already safe to
- * access the buffer contents, -1 may be passed instead.
- *
- * @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
- * be a CPU usage.
- * @param consumerUsageMask contains the consumer usage flags to request;
- * either this or producerUsageMask must be 0, and the other must
- * be a CPU usage.
+ * @param buffer is the buffer to lock.
+ * @param cpuUsage specifies one or more CPU usage flags to request.
* @param accessRegion is the portion of the buffer that the client
* intends to access.
- * @param acquireFence is a sync fence file descriptor as described above.
+ * @param acquireFence, when non-empty, is a handle containing a file
+ * descriptor referring to a sync fence object, which will be
+ * signaled when it is safe for the mapper to lock the buffer. If
+ * it is already safe to lock, acquireFence is empty.
* @return error is NONE upon success. Otherwise,
- * BAD_BUFFER when the buffer handle is invalid.
- * BAD_VALUE when neither or both of producerUsageMask
- * and consumerUsageMask were 0, or the usage
- * which was not 0 was not a CPU usage.
+ * BAD_BUFFER when the buffer is invalid or is
+ * incompatible with this function.
+ * BAD_VALUE when cpuUsage is 0, contains non-CPU usage
+ * flags, or is incompatible with the buffer.
* NO_RESOURCES when the buffer cannot be locked at this
* time, but locking may succeed at a future
* time.
- * UNSUPPORTED when the buffer cannot be locked with the
- * given usage, and any future attempts at
- * locking will also fail.
- * @return data will be filled with a CPU-accessible pointer to the buffer
- * data.
+ * @return data is a CPU-accessible pointer to the buffer data.
*/
@callflow(next="unlock")
- lock(handle bufferHandle,
- uint64_t producerUsageMask,
- uint64_t consumerUsageMask,
+ lock(pointer buffer,
+ bitfield<BufferUsage> cpuUsage,
Rect accessRegion,
handle acquireFence)
generates (Error error,
@@ -249,7 +172,7 @@
/**
* This is largely the same as lock(), except that instead of returning a
- * pointer directly to the buffer data, it returns an FlexLayout struct
+ * pointer directly to the buffer data, it returns an YCbCrLayout struct
* describing how to access the data planes.
*
* This function must work on buffers with PixelFormat::YCbCr_*_888 if
@@ -257,67 +180,46 @@
* multimedia codecs when they are configured with a
* flexible-YUV-compatible color format.
*
- * This function may also be called on buffers of other formats, including
- * non-YUV formats, but if the buffer format is not compatible with a
- * flexible representation, it may return UNSUPPORTED.
- *
- * @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
- * be a CPU usage.
- * @param consumerUsageMask contains the consumer usage flags to request;
- * either this or producerUsageMask must be 0, and the other must
- * be a CPU usage.
+ * @param buffer is the buffer to lock.
+ * @param cpuUsage specifies one or more CPU usage flags to request.
* @param accessRegion is the portion of the buffer that the client
* intends to access.
- * @param acquireFence is a sync fence file descriptor as described in
- * lock().
+ * @param acquireFence, when non-empty, is a handle containing a file
+ * descriptor referring to a sync fence object, which will be
+ * signaled when it is safe for the mapper to lock the buffer. If
+ * it is already safe to lock, acquireFence is empty.
* @return error is NONE upon success. Otherwise,
- * BAD_BUFFER when the buffer handle is invalid.
- * BAD_VALUE when neither or both of producerUsageMask
- * and consumerUsageMask were 0, or the usage
- * which was not 0 was not a CPU usage.
+ * BAD_BUFFER when the buffer is invalid or is
+ * incompatible with this function.
+ * BAD_VALUE when cpuUsage is 0, contains non-CPU usage
+ * flags, or is incompatible with the buffer.
* NO_RESOURCES when the buffer cannot be locked at this
* time, but locking may succeed at a future
* time.
- * UNSUPPORTED when the buffer cannot be locked with the
- * given usage, and any future attempts at
- * locking will also fail.
- * @return flexLayout will be filled with the description of the planes in
- * the buffer.
+ * @return layout is the data layout of the buffer.
*/
@callflow(next="unlock")
- lockFlex(handle bufferHandle,
- uint64_t producerUsageMask,
- uint64_t consumerUsageMask,
- Rect accessRegion,
- handle acquireFence)
+ lockYCbCr(pointer buffer,
+ bitfield<BufferUsage> cpuUsage,
+ Rect accessRegion,
+ handle acquireFence)
generates (Error error,
- FlexLayout layout);
+ YCbCrLayout layout);
/**
- * This function indicates to the device that the client will be done with
- * the buffer when releaseFence signals.
+ * Unlocks a buffer to indicate all CPU accesses to the buffer have
+ * completed.
*
- * releaseFence will be filled with a file descriptor referring to a
- * release sync fence object, which will be signaled when it is safe to
- * access the contents of the buffer (after the buffer has been unlocked).
- * If it is already safe to access the buffer contents, then -1 may be
- * returned instead.
- *
- * This function is used to unlock both buffers locked by lock() and those
- * locked by lockFlex().
- *
- * @param device is the mapper device.
- * @param bufferHandle is the buffer to unlock.
+ * @param buffer is the buffer to unlock.
* @return error is NONE upon success. Otherwise,
- * BAD_BUFFER when the buffer handle is invalid.
- * @return releaseFence is a sync fence file descriptor as described
- * above.
+ * BAD_BUFFER when the buffer is invalid or not locked.
+ * @return releaseFence, when non-empty, is a handle containing a file
+ * descriptor referring to a sync fence object. The sync fence
+ * object will be signaled when the mapper has completed any
+ * pending work.
*/
@callflow(next="*")
- unlock(handle bufferHandle)
+ unlock(pointer buffer)
generates (Error error,
handle releaseFence);
};
diff --git a/graphics/mapper/2.0/default/Android.bp b/graphics/mapper/2.0/default/Android.bp
index 1dc5aea..677d966 100644
--- a/graphics/mapper/2.0/default/Android.bp
+++ b/graphics/mapper/2.0/default/Android.bp
@@ -16,12 +16,11 @@
cc_library_shared {
name: "android.hardware.graphics.mapper@2.0-impl",
defaults: ["hidl_defaults"],
- proprietary: true,
+ vendor: true,
relative_install_path: "hw",
- srcs: ["GrallocMapper.cpp"],
+ srcs: ["GrallocMapper.cpp", "Gralloc0Mapper.cpp", "Gralloc1Mapper.cpp"],
cppflags: ["-Wall", "-Wextra"],
shared_libs: [
- "android.hardware.graphics.allocator@2.0",
"android.hardware.graphics.mapper@2.0",
"libbase",
"libcutils",
@@ -29,6 +28,13 @@
"libhidlbase",
"libhidltransport",
"liblog",
+ "libsync",
"libutils",
],
}
+
+cc_library_headers {
+ name: "libgrallocmapperincludes",
+ vendor: true,
+ export_include_dirs: ["."],
+}
diff --git a/graphics/mapper/2.0/default/Gralloc0Mapper.cpp b/graphics/mapper/2.0/default/Gralloc0Mapper.cpp
new file mode 100644
index 0000000..28f5016
--- /dev/null
+++ b/graphics/mapper/2.0/default/Gralloc0Mapper.cpp
@@ -0,0 +1,156 @@
+/*
+ * 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 "Gralloc0Mapper"
+
+#include "Gralloc0Mapper.h"
+
+#include <log/log.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace mapper {
+namespace V2_0 {
+namespace implementation {
+
+Gralloc0Mapper::Gralloc0Mapper(const hw_module_t* module)
+ : mModule(reinterpret_cast<const gralloc_module_t*>(module)),
+ mMinor(module->module_api_version & 0xff) {
+ mCapabilities.highUsageBits = false;
+ mCapabilities.layeredBuffers = false;
+ mCapabilities.unregisterImplyDelete = false;
+}
+
+Error Gralloc0Mapper::registerBuffer(buffer_handle_t bufferHandle) {
+ int result = mModule->registerBuffer(mModule, bufferHandle);
+ return result ? Error::BAD_BUFFER : Error::NONE;
+}
+
+void Gralloc0Mapper::unregisterBuffer(buffer_handle_t bufferHandle) {
+ mModule->unregisterBuffer(mModule, bufferHandle);
+}
+
+Error Gralloc0Mapper::lockBuffer(buffer_handle_t bufferHandle,
+ uint64_t cpuUsage,
+ const IMapper::Rect& accessRegion, int fenceFd,
+ void** outData) {
+ int result;
+ void* data = nullptr;
+ if (mMinor >= 3 && mModule->lockAsync) {
+ // Dup fenceFd as it is going to be owned by gralloc. Note that it is
+ // gralloc's responsibility to close it, even on locking errors.
+ if (fenceFd >= 0) {
+ fenceFd = dup(fenceFd);
+ if (fenceFd < 0) {
+ return Error::NO_RESOURCES;
+ }
+ }
+
+ result = mModule->lockAsync(mModule, bufferHandle, cpuUsage,
+ accessRegion.left, accessRegion.top,
+ accessRegion.width, accessRegion.height,
+ &data, fenceFd);
+ } else {
+ waitFenceFd(fenceFd, "Gralloc0Mapper::lock");
+
+ result = mModule->lock(mModule, bufferHandle, cpuUsage,
+ accessRegion.left, accessRegion.top,
+ accessRegion.width, accessRegion.height, &data);
+ }
+
+ if (result) {
+ return Error::BAD_VALUE;
+ } else {
+ *outData = data;
+ return Error::NONE;
+ }
+}
+
+Error Gralloc0Mapper::lockBuffer(buffer_handle_t bufferHandle,
+ uint64_t cpuUsage,
+ const IMapper::Rect& accessRegion, int fenceFd,
+ YCbCrLayout* outLayout) {
+ int result;
+ android_ycbcr ycbcr = {};
+ if (mMinor >= 3 && mModule->lockAsync_ycbcr) {
+ // Dup fenceFd as it is going to be owned by gralloc. Note that it is
+ // gralloc's responsibility to close it, even on locking errors.
+ if (fenceFd >= 0) {
+ fenceFd = dup(fenceFd);
+ if (fenceFd < 0) {
+ return Error::NO_RESOURCES;
+ }
+ }
+
+ result = mModule->lockAsync_ycbcr(mModule, bufferHandle, cpuUsage,
+ accessRegion.left, accessRegion.top,
+ accessRegion.width,
+ accessRegion.height, &ycbcr, fenceFd);
+ } else {
+ waitFenceFd(fenceFd, "Gralloc0Mapper::lockYCbCr");
+
+ if (mModule->lock_ycbcr) {
+ result = mModule->lock_ycbcr(mModule, bufferHandle, cpuUsage,
+ accessRegion.left, accessRegion.top,
+ accessRegion.width,
+ accessRegion.height, &ycbcr);
+ } else {
+ result = -EINVAL;
+ }
+ }
+
+ if (result) {
+ return Error::BAD_VALUE;
+ } else {
+ outLayout->y = ycbcr.y;
+ outLayout->cb = ycbcr.cb;
+ outLayout->cr = ycbcr.cr;
+ outLayout->yStride = ycbcr.ystride;
+ outLayout->cStride = ycbcr.cstride;
+ outLayout->chromaStep = ycbcr.chroma_step;
+ return Error::NONE;
+ }
+}
+
+Error Gralloc0Mapper::unlockBuffer(buffer_handle_t bufferHandle,
+ int* outFenceFd) {
+ int result;
+ int fenceFd = -1;
+ if (mMinor >= 3 && mModule->unlockAsync) {
+ result = mModule->unlockAsync(mModule, bufferHandle, &fenceFd);
+ } else {
+ result = mModule->unlock(mModule, bufferHandle);
+ }
+
+ if (result) {
+ // we always own the fenceFd even when unlock failed
+ if (fenceFd >= 0) {
+ close(fenceFd);
+ }
+
+ return Error::BAD_VALUE;
+ } else {
+ *outFenceFd = fenceFd;
+ return Error::NONE;
+ }
+}
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace mapper
+} // namespace graphics
+} // namespace hardware
+} // namespace android
diff --git a/graphics/mapper/2.0/default/Gralloc0Mapper.h b/graphics/mapper/2.0/default/Gralloc0Mapper.h
new file mode 100644
index 0000000..e792a69
--- /dev/null
+++ b/graphics/mapper/2.0/default/Gralloc0Mapper.h
@@ -0,0 +1,56 @@
+/*
+ * 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_GRALLOC0MAPPER_H
+#define ANDROID_HARDWARE_GRAPHICS_MAPPER_V2_0_GRALLOC0MAPPER_H
+
+#include "GrallocMapper.h"
+
+#include <hardware/gralloc.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace mapper {
+namespace V2_0 {
+namespace implementation {
+
+class Gralloc0Mapper : public GrallocMapper {
+ public:
+ Gralloc0Mapper(const hw_module_t* module);
+
+ private:
+ Error registerBuffer(buffer_handle_t bufferHandle) override;
+ void unregisterBuffer(buffer_handle_t bufferHandle) override;
+ Error lockBuffer(buffer_handle_t bufferHandle, uint64_t cpuUsage,
+ const IMapper::Rect& accessRegion, int fenceFd,
+ void** outData) override;
+ Error lockBuffer(buffer_handle_t bufferHandle, uint64_t cpuUsage,
+ const IMapper::Rect& accessRegion, int fenceFd,
+ YCbCrLayout* outLayout) override;
+ Error unlockBuffer(buffer_handle_t bufferHandle, int* outFenceFd) override;
+
+ const gralloc_module_t* mModule;
+ uint8_t mMinor;
+};
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace mapper
+} // namespace graphics
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GRAPHICS_MAPPER_V2_0_GRALLOC0MAPPER_H
diff --git a/graphics/mapper/2.0/default/Gralloc1Mapper.cpp b/graphics/mapper/2.0/default/Gralloc1Mapper.cpp
new file mode 100644
index 0000000..c1e5adc
--- /dev/null
+++ b/graphics/mapper/2.0/default/Gralloc1Mapper.cpp
@@ -0,0 +1,273 @@
+/*
+ * 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 "Gralloc1Mapper"
+
+#include "Gralloc1Mapper.h"
+
+#include <vector>
+
+#include <log/log.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace mapper {
+namespace V2_0 {
+namespace implementation {
+
+using android::hardware::graphics::common::V1_0::BufferUsage;
+
+Gralloc1Mapper::Gralloc1Mapper(const hw_module_t* module)
+ : mDevice(nullptr), mDispatch() {
+ int result = gralloc1_open(module, &mDevice);
+ if (result) {
+ LOG_ALWAYS_FATAL("failed to open gralloc1 device: %s",
+ strerror(-result));
+ }
+
+ initCapabilities();
+ initDispatch();
+}
+
+Gralloc1Mapper::~Gralloc1Mapper() {
+ gralloc1_close(mDevice);
+}
+
+void Gralloc1Mapper::initCapabilities() {
+ mCapabilities.highUsageBits = true;
+ mCapabilities.layeredBuffers = false;
+ mCapabilities.unregisterImplyDelete = false;
+
+ uint32_t count = 0;
+ mDevice->getCapabilities(mDevice, &count, nullptr);
+
+ std::vector<int32_t> capabilities(count);
+ mDevice->getCapabilities(mDevice, &count, capabilities.data());
+ capabilities.resize(count);
+
+ for (auto capability : capabilities) {
+ switch (capability) {
+ case GRALLOC1_CAPABILITY_LAYERED_BUFFERS:
+ mCapabilities.layeredBuffers = true;
+ break;
+ case GRALLOC1_CAPABILITY_RELEASE_IMPLY_DELETE:
+ mCapabilities.unregisterImplyDelete = true;
+ break;
+ }
+ }
+}
+
+template <typename T>
+void Gralloc1Mapper::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);
+ }
+
+ *outPfn = reinterpret_cast<T>(pfn);
+}
+
+void Gralloc1Mapper::initDispatch() {
+ initDispatch(GRALLOC1_FUNCTION_RETAIN, &mDispatch.retain);
+ initDispatch(GRALLOC1_FUNCTION_RELEASE, &mDispatch.release);
+ 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 Gralloc1Mapper::toError(int32_t error) {
+ switch (error) {
+ case GRALLOC1_ERROR_NONE:
+ return Error::NONE;
+ case GRALLOC1_ERROR_BAD_DESCRIPTOR:
+ return Error::BAD_DESCRIPTOR;
+ case GRALLOC1_ERROR_BAD_HANDLE:
+ return Error::BAD_BUFFER;
+ case GRALLOC1_ERROR_BAD_VALUE:
+ return Error::BAD_VALUE;
+ case GRALLOC1_ERROR_NOT_SHARED:
+ return Error::NONE; // this is fine
+ case GRALLOC1_ERROR_NO_RESOURCES:
+ return Error::NO_RESOURCES;
+ case GRALLOC1_ERROR_UNDEFINED:
+ case GRALLOC1_ERROR_UNSUPPORTED:
+ default:
+ return Error::UNSUPPORTED;
+ }
+}
+
+bool Gralloc1Mapper::toYCbCrLayout(const android_flex_layout& flex,
+ YCbCrLayout* outLayout) {
+ // must be YCbCr
+ if (flex.format != FLEX_FORMAT_YCbCr || flex.num_planes < 3) {
+ return false;
+ }
+
+ for (int i = 0; i < 3; i++) {
+ const auto& plane = flex.planes[i];
+ // must have 8-bit depth
+ if (plane.bits_per_component != 8 || plane.bits_used != 8) {
+ return false;
+ }
+
+ if (plane.component == FLEX_COMPONENT_Y) {
+ // Y must not be interleaved
+ if (plane.h_increment != 1) {
+ return false;
+ }
+ } else {
+ // Cb and Cr can be interleaved
+ if (plane.h_increment != 1 && plane.h_increment != 2) {
+ return false;
+ }
+ }
+
+ if (!plane.v_increment) {
+ return false;
+ }
+ }
+
+ if (flex.planes[0].component != FLEX_COMPONENT_Y ||
+ flex.planes[1].component != FLEX_COMPONENT_Cb ||
+ flex.planes[2].component != FLEX_COMPONENT_Cr) {
+ return false;
+ }
+
+ const auto& y = flex.planes[0];
+ const auto& cb = flex.planes[1];
+ const auto& cr = flex.planes[2];
+
+ if (cb.h_increment != cr.h_increment || cb.v_increment != cr.v_increment) {
+ return false;
+ }
+
+ outLayout->y = y.top_left;
+ outLayout->cb = cb.top_left;
+ outLayout->cr = cr.top_left;
+ outLayout->yStride = y.v_increment;
+ outLayout->cStride = cb.v_increment;
+ outLayout->chromaStep = cb.h_increment;
+
+ return true;
+}
+
+gralloc1_rect_t Gralloc1Mapper::asGralloc1Rect(const IMapper::Rect& rect) {
+ return gralloc1_rect_t{rect.left, rect.top, rect.width, rect.height};
+}
+
+Error Gralloc1Mapper::registerBuffer(buffer_handle_t bufferHandle) {
+ return toError(mDispatch.retain(mDevice, bufferHandle));
+}
+
+void Gralloc1Mapper::unregisterBuffer(buffer_handle_t bufferHandle) {
+ mDispatch.release(mDevice, bufferHandle);
+}
+
+Error Gralloc1Mapper::lockBuffer(buffer_handle_t bufferHandle,
+ uint64_t cpuUsage,
+ const IMapper::Rect& accessRegion, int fenceFd,
+ void** outData) {
+ // Dup fenceFd as it is going to be owned by gralloc. Note that it is
+ // gralloc's responsibility to close it, even on locking errors.
+ if (fenceFd >= 0) {
+ fenceFd = dup(fenceFd);
+ if (fenceFd < 0) {
+ return Error::NO_RESOURCES;
+ }
+ }
+
+ const uint64_t consumerUsage =
+ cpuUsage & ~static_cast<uint64_t>(BufferUsage::CPU_WRITE_MASK);
+ const auto accessRect = asGralloc1Rect(accessRegion);
+ void* data = nullptr;
+ int32_t error = mDispatch.lock(mDevice, bufferHandle, cpuUsage,
+ consumerUsage, &accessRect, &data, fenceFd);
+
+ if (error == GRALLOC1_ERROR_NONE) {
+ *outData = data;
+ }
+
+ return toError(error);
+}
+
+Error Gralloc1Mapper::lockBuffer(buffer_handle_t bufferHandle,
+ uint64_t cpuUsage,
+ const IMapper::Rect& accessRegion, int fenceFd,
+ YCbCrLayout* outLayout) {
+ // prepare flex layout
+ android_flex_layout flex = {};
+ int32_t error =
+ mDispatch.getNumFlexPlanes(mDevice, bufferHandle, &flex.num_planes);
+ if (error != GRALLOC1_ERROR_NONE) {
+ return toError(error);
+ }
+ std::vector<android_flex_plane_t> flexPlanes(flex.num_planes);
+ flex.planes = flexPlanes.data();
+
+ // Dup fenceFd as it is going to be owned by gralloc. Note that it is
+ // gralloc's responsibility to close it, even on locking errors.
+ if (fenceFd >= 0) {
+ fenceFd = dup(fenceFd);
+ if (fenceFd < 0) {
+ return Error::NO_RESOURCES;
+ }
+ }
+
+ const uint64_t consumerUsage =
+ cpuUsage & ~static_cast<uint64_t>(BufferUsage::CPU_WRITE_MASK);
+ const auto accessRect = asGralloc1Rect(accessRegion);
+ error = mDispatch.lockFlex(mDevice, bufferHandle, cpuUsage, consumerUsage,
+ &accessRect, &flex, fenceFd);
+ if (error == GRALLOC1_ERROR_NONE && !toYCbCrLayout(flex, outLayout)) {
+ ALOGD("unable to convert android_flex_layout to YCbCrLayout");
+
+ // undo the lock
+ fenceFd = -1;
+ mDispatch.unlock(mDevice, bufferHandle, &fenceFd);
+ if (fenceFd >= 0) {
+ close(fenceFd);
+ }
+
+ error = GRALLOC1_ERROR_BAD_HANDLE;
+ }
+
+ return toError(error);
+}
+
+Error Gralloc1Mapper::unlockBuffer(buffer_handle_t bufferHandle,
+ int* outFenceFd) {
+ int fenceFd = -1;
+ int32_t error = mDispatch.unlock(mDevice, bufferHandle, &fenceFd);
+
+ if (error == GRALLOC1_ERROR_NONE) {
+ *outFenceFd = fenceFd;
+ } else if (fenceFd >= 0) {
+ // we always own the fenceFd even when unlock failed
+ close(fenceFd);
+ }
+
+ return toError(error);
+}
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace mapper
+} // namespace graphics
+} // namespace hardware
+} // namespace android
diff --git a/graphics/mapper/2.0/default/Gralloc1Mapper.h b/graphics/mapper/2.0/default/Gralloc1Mapper.h
new file mode 100644
index 0000000..452afdf
--- /dev/null
+++ b/graphics/mapper/2.0/default/Gralloc1Mapper.h
@@ -0,0 +1,76 @@
+/*
+ * 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_GRALLOC1MAPPER_H
+#define ANDROID_HARDWARE_GRAPHICS_MAPPER_V2_0_GRALLOC1MAPPER_H
+
+#include "GrallocMapper.h"
+
+#include <hardware/gralloc1.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace mapper {
+namespace V2_0 {
+namespace implementation {
+
+class Gralloc1Mapper : public GrallocMapper {
+ public:
+ Gralloc1Mapper(const hw_module_t* module);
+ ~Gralloc1Mapper();
+
+ private:
+ void initCapabilities();
+
+ template <typename T>
+ void initDispatch(gralloc1_function_descriptor_t desc, T* outPfn);
+ void initDispatch();
+
+ static Error toError(int32_t error);
+ static bool toYCbCrLayout(const android_flex_layout& flex,
+ YCbCrLayout* outLayout);
+ static gralloc1_rect_t asGralloc1Rect(const IMapper::Rect& rect);
+
+ Error registerBuffer(buffer_handle_t bufferHandle) override;
+ void unregisterBuffer(buffer_handle_t bufferHandle) override;
+ Error lockBuffer(buffer_handle_t bufferHandle, uint64_t cpuUsage,
+ const IMapper::Rect& accessRegion, int fenceFd,
+ void** outData) override;
+ Error lockBuffer(buffer_handle_t bufferHandle, uint64_t cpuUsage,
+ const IMapper::Rect& accessRegion, int fenceFd,
+ YCbCrLayout* outLayout) override;
+ Error unlockBuffer(buffer_handle_t bufferHandle, int* outFenceFd) override;
+
+ gralloc1_device_t* mDevice;
+
+ struct {
+ GRALLOC1_PFN_RETAIN retain;
+ GRALLOC1_PFN_RELEASE release;
+ GRALLOC1_PFN_GET_NUM_FLEX_PLANES getNumFlexPlanes;
+ GRALLOC1_PFN_LOCK lock;
+ GRALLOC1_PFN_LOCK_FLEX lockFlex;
+ GRALLOC1_PFN_UNLOCK unlock;
+ } mDispatch;
+};
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace mapper
+} // namespace graphics
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GRAPHICS_MAPPER_V2_0_GRALLOC1MAPPER_H
diff --git a/graphics/mapper/2.0/default/GrallocBufferDescriptor.h b/graphics/mapper/2.0/default/GrallocBufferDescriptor.h
new file mode 100644
index 0000000..9b5ab04
--- /dev/null
+++ b/graphics/mapper/2.0/default/GrallocBufferDescriptor.h
@@ -0,0 +1,79 @@
+/*
+ * 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_GRALLOCBUFFERDESCRIPTOR_H
+#define ANDROID_HARDWARE_GRAPHICS_MAPPER_V2_0_GRALLOCBUFFERDESCRIPTOR_H
+
+#include <android/hardware/graphics/mapper/2.0/IMapper.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace mapper {
+namespace V2_0 {
+namespace implementation {
+
+using android::hardware::graphics::common::V1_0::PixelFormat;
+
+/**
+ * BufferDescriptor is created by IMapper and consumed by IAllocator. It is
+ * versioned so that IMapper and IAllocator can be updated independently.
+ */
+constexpr uint32_t grallocBufferDescriptorSize = 7;
+constexpr uint32_t grallocBufferDescriptorMagicVersion = ((0x9487 << 16) | 0);
+
+inline BufferDescriptor grallocEncodeBufferDescriptor(
+ const IMapper::BufferDescriptorInfo& descriptorInfo) {
+ BufferDescriptor descriptor;
+ descriptor.resize(grallocBufferDescriptorSize);
+ descriptor[0] = grallocBufferDescriptorMagicVersion;
+ descriptor[1] = descriptorInfo.width;
+ descriptor[2] = descriptorInfo.height;
+ descriptor[3] = descriptorInfo.layerCount;
+ descriptor[4] = static_cast<uint32_t>(descriptorInfo.format);
+ descriptor[5] = static_cast<uint32_t>(descriptorInfo.usage);
+ descriptor[6] = static_cast<uint32_t>(descriptorInfo.usage >> 32);
+
+ return descriptor;
+}
+
+inline bool grallocDecodeBufferDescriptor(
+ const BufferDescriptor& descriptor,
+ IMapper::BufferDescriptorInfo* outDescriptorInfo) {
+ if (descriptor.size() != grallocBufferDescriptorSize ||
+ descriptor[0] != grallocBufferDescriptorMagicVersion) {
+ return false;
+ }
+
+ *outDescriptorInfo = IMapper::BufferDescriptorInfo{
+ descriptor[1],
+ descriptor[2],
+ descriptor[3],
+ static_cast<PixelFormat>(descriptor[4]),
+ (static_cast<uint64_t>(descriptor[6]) << 32) | descriptor[5],
+ };
+
+ return true;
+}
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace mapper
+} // namespace graphics
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GRAPHICS_MAPPER_V2_0_GRALLOCBUFFERDESCRIPTOR_H
diff --git a/graphics/mapper/2.0/default/GrallocMapper.cpp b/graphics/mapper/2.0/default/GrallocMapper.cpp
index 526aca2..339317a 100644
--- a/graphics/mapper/2.0/default/GrallocMapper.cpp
+++ b/graphics/mapper/2.0/default/GrallocMapper.cpp
@@ -17,14 +17,14 @@
#include "GrallocMapper.h"
-#include <mutex>
-#include <vector>
-#include <unordered_map>
+#include "Gralloc0Mapper.h"
+#include "Gralloc1Mapper.h"
+#include "GrallocBufferDescriptor.h"
-#include <string.h>
+#include <inttypes.h>
-#include <hardware/gralloc1.h>
#include <log/log.h>
+#include <sync/sync.h>
namespace android {
namespace hardware {
@@ -33,374 +33,251 @@
namespace V2_0 {
namespace implementation {
-namespace {
-
-using android::hardware::graphics::allocator::V2_0::Error;
+using android::hardware::graphics::common::V1_0::BufferUsage;
using android::hardware::graphics::common::V1_0::PixelFormat;
-class GrallocMapperHal : public IMapper {
-public:
- GrallocMapperHal(const hw_module_t* module);
- ~GrallocMapperHal();
+std::mutex GrallocMapper::mMutex;
+std::unordered_set<buffer_handle_t> GrallocMapper::mRegisteredHandles;
- // IMapper interface
- 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 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 IMapper::Rect& accessRegion, const hidl_handle& acquireFence,
- lockFlex_cb hidl_cb) override;
- Return<void> unlock(const hidl_handle& bufferHandle,
- unlock_cb hidl_cb) override;
+bool GrallocMapper::validateDescriptorInfo(
+ const BufferDescriptorInfo& descriptorInfo) const {
+ const uint64_t validUsageBits =
+ BufferUsage::CPU_READ_MASK | BufferUsage::CPU_WRITE_MASK |
+ BufferUsage::GPU_TEXTURE | BufferUsage::GPU_RENDER_TARGET |
+ BufferUsage::COMPOSER_OVERLAY | BufferUsage::COMPOSER_CLIENT_TARGET |
+ BufferUsage::PROTECTED | BufferUsage::COMPOSER_CURSOR |
+ BufferUsage::VIDEO_ENCODER | BufferUsage::CAMERA_OUTPUT |
+ BufferUsage::CAMERA_INPUT | BufferUsage::RENDERSCRIPT |
+ BufferUsage::VIDEO_DECODER | BufferUsage::SENSOR_DIRECT_DATA |
+ BufferUsage::GPU_DATA_BUFFER | BufferUsage::VENDOR_MASK |
+ (mCapabilities.highUsageBits ? BufferUsage::VENDOR_MASK_HI
+ : static_cast<BufferUsage>(0));
-private:
- void initCapabilities();
-
- template<typename T>
- void initDispatch(gralloc1_function_descriptor_t desc, T* outPfn);
- void initDispatch();
-
- static gralloc1_rect_t asGralloc1Rect(const IMapper::Rect& rect);
- static bool dupFence(const hidl_handle& fenceHandle, int* outFd);
-
- gralloc1_device_t* mDevice;
-
- struct {
- bool layeredBuffers;
- } mCapabilities;
-
- struct {
- GRALLOC1_PFN_RETAIN retain;
- GRALLOC1_PFN_RELEASE release;
- GRALLOC1_PFN_GET_DIMENSIONS getDimensions;
- GRALLOC1_PFN_GET_FORMAT getFormat;
- GRALLOC1_PFN_GET_LAYER_COUNT getLayerCount;
- GRALLOC1_PFN_GET_PRODUCER_USAGE getProducerUsage;
- GRALLOC1_PFN_GET_CONSUMER_USAGE getConsumerUsage;
- GRALLOC1_PFN_GET_BACKING_STORE getBackingStore;
- GRALLOC1_PFN_GET_STRIDE getStride;
- GRALLOC1_PFN_GET_NUM_FLEX_PLANES getNumFlexPlanes;
- GRALLOC1_PFN_LOCK lock;
- GRALLOC1_PFN_LOCK_FLEX lockFlex;
- GRALLOC1_PFN_UNLOCK unlock;
- } mDispatch;
-
- std::mutex mMutex;
- std::unordered_map<buffer_handle_t, size_t> mBufferReferenceCounts;
-};
-
-GrallocMapperHal::GrallocMapperHal(const hw_module_t* module)
- : mDevice(nullptr), mCapabilities(), mDispatch()
-{
- int status = gralloc1_open(module, &mDevice);
- if (status) {
- LOG_ALWAYS_FATAL("failed to open gralloc1 device: %s",
- strerror(-status));
- }
-
- initCapabilities();
- initDispatch();
-}
-
-GrallocMapperHal::~GrallocMapperHal()
-{
- gralloc1_close(mDevice);
-}
-
-void GrallocMapperHal::initCapabilities()
-{
- uint32_t count = 0;
- mDevice->getCapabilities(mDevice, &count, nullptr);
-
- std::vector<int32_t> caps(count);
- mDevice->getCapabilities(mDevice, &count, caps.data());
- caps.resize(count);
-
- for (auto cap : caps) {
- switch (cap) {
- case GRALLOC1_CAPABILITY_LAYERED_BUFFERS:
- mCapabilities.layeredBuffers = true;
- break;
- default:
- break;
- }
- }
-}
-
-template<typename T>
-void GrallocMapperHal::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);
- }
-
- *outPfn = reinterpret_cast<T>(pfn);
-}
-
-void GrallocMapperHal::initDispatch()
-{
- 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);
-}
-
-gralloc1_rect_t GrallocMapperHal::asGralloc1Rect(const IMapper::Rect& rect)
-{
- return gralloc1_rect_t{rect.left, rect.top, rect.width, rect.height};
-}
-
-bool GrallocMapperHal::dupFence(const hidl_handle& fenceHandle, int* outFd)
-{
- 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);
+ if (!descriptorInfo.width || !descriptorInfo.height ||
+ !descriptorInfo.layerCount) {
return false;
}
- *outFd = dup(handle->data[0]);
- return (*outFd >= 0);
-}
-
-Return<Error> GrallocMapperHal::retain(const hidl_handle& bufferHandle)
-{
- int32_t err = mDispatch.retain(mDevice, bufferHandle);
- if (err == GRALLOC1_ERROR_NONE) {
- auto nativeHandle = bufferHandle.getNativeHandle();
- std::lock_guard<std::mutex> lock(mMutex);
-
- ++mBufferReferenceCounts[nativeHandle];
- }
- return static_cast<Error>(err);
-}
-
-Return<Error> GrallocMapperHal::release(const hidl_handle& bufferHandle)
-{
- int32_t err = mDispatch.release(mDevice, bufferHandle);
- if (err == GRALLOC1_ERROR_NONE) {
- auto nativeHandle = bufferHandle.getNativeHandle();
- std::lock_guard<std::mutex> lock(mMutex);
-
- auto iter = mBufferReferenceCounts.find(bufferHandle);
- if (iter == mBufferReferenceCounts.end()) {
- // this should never happen
- err = GRALLOC1_ERROR_BAD_HANDLE;
- } else if (--iter->second == 0) {
- native_handle_close(nativeHandle);
- native_handle_delete(const_cast<native_handle_t*>(nativeHandle));
-
- mBufferReferenceCounts.erase(iter);
- }
+ if (!mCapabilities.layeredBuffers && descriptorInfo.layerCount > 1) {
+ return false;
}
- 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);
+ if (descriptorInfo.format == static_cast<PixelFormat>(0)) {
+ return false;
}
- hidl_cb(static_cast<Error>(err), count);
+ if (descriptorInfo.usage & ~validUsageBits) {
+ // could not fail as gralloc may use the reserved bits...
+ ALOGW("buffer descriptor with invalid usage bits 0x%" PRIx64,
+ descriptorInfo.usage & ~validUsageBits);
+ }
+
+ return true;
+}
+
+Return<void> GrallocMapper::createDescriptor(
+ const BufferDescriptorInfo& descriptorInfo, createDescriptor_cb hidl_cb) {
+ if (validateDescriptorInfo(descriptorInfo)) {
+ hidl_cb(Error::NONE, grallocEncodeBufferDescriptor(descriptorInfo));
+ } else {
+ hidl_cb(Error::BAD_VALUE, BufferDescriptor());
+ }
+
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();
+bool GrallocMapper::addRegisteredHandle(buffer_handle_t bufferHandle) {
+ std::lock_guard<std::mutex> lock(mMutex);
+ return mRegisteredHandles.insert(bufferHandle).second;
}
-Return<void> GrallocMapperHal::getConsumerUsageMask(
- const hidl_handle& bufferHandle, getConsumerUsageMask_cb hidl_cb)
-{
- uint64_t mask = 0x0;
- int32_t err = mDispatch.getConsumerUsage(mDevice, bufferHandle, &mask);
+native_handle_t* GrallocMapper::popRegisteredHandle(void* buffer) {
+ auto bufferHandle = static_cast<native_handle_t*>(buffer);
- hidl_cb(static_cast<Error>(err), mask);
- return Void();
+ std::lock_guard<std::mutex> lock(mMutex);
+ return mRegisteredHandles.erase(bufferHandle) == 1 ? bufferHandle : nullptr;
}
-Return<void> GrallocMapperHal::getBackingStore(
- const hidl_handle& bufferHandle, getBackingStore_cb hidl_cb)
-{
- uint64_t store = 0;
- int32_t err = mDispatch.getBackingStore(mDevice, bufferHandle, &store);
+buffer_handle_t GrallocMapper::getRegisteredHandle(const void* buffer) {
+ auto bufferHandle = static_cast<buffer_handle_t>(buffer);
- hidl_cb(static_cast<Error>(err), store);
- return Void();
+ std::lock_guard<std::mutex> lock(mMutex);
+ return mRegisteredHandles.count(bufferHandle) == 1 ? bufferHandle : nullptr;
}
-Return<void> GrallocMapperHal::getStride(const hidl_handle& bufferHandle,
- getStride_cb hidl_cb)
-{
- uint32_t stride = 0;
- int32_t err = mDispatch.getStride(mDevice, bufferHandle, &stride);
+Return<void> GrallocMapper::importBuffer(const hidl_handle& rawHandle,
+ importBuffer_cb hidl_cb) {
+ // importing an already imported handle rather than a raw handle
+ if (getRegisteredHandle(rawHandle.getNativeHandle())) {
+ hidl_cb(Error::BAD_BUFFER, nullptr);
+ return Void();
+ }
- hidl_cb(static_cast<Error>(err), stride);
- return Void();
-}
+ if (!rawHandle.getNativeHandle()) {
+ hidl_cb(Error::BAD_BUFFER, nullptr);
+ 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)) {
+ native_handle_t* bufferHandle =
+ native_handle_clone(rawHandle.getNativeHandle());
+ if (!bufferHandle) {
hidl_cb(Error::NO_RESOURCES, nullptr);
return Void();
}
+ Error error = registerBuffer(bufferHandle);
+ if (error != Error::NONE) {
+ native_handle_close(bufferHandle);
+ native_handle_delete(bufferHandle);
+
+ hidl_cb(error, nullptr);
+ return Void();
+ }
+
+ // The newly cloned handle is already registered? This can only happen
+ // when a handle previously registered was native_handle_delete'd instead
+ // of freeBuffer'd.
+ if (!addRegisteredHandle(bufferHandle)) {
+ ALOGE("handle %p has already been imported; potential fd leaking",
+ bufferHandle);
+ unregisterBuffer(bufferHandle);
+ if (!mCapabilities.unregisterImplyDelete) {
+ native_handle_close(bufferHandle);
+ native_handle_delete(bufferHandle);
+ }
+
+ hidl_cb(Error::NO_RESOURCES, nullptr);
+ return Void();
+ }
+
+ hidl_cb(Error::NONE, bufferHandle);
+ return Void();
+}
+
+Return<Error> GrallocMapper::freeBuffer(void* buffer) {
+ native_handle_t* bufferHandle = popRegisteredHandle(buffer);
+ if (!bufferHandle) {
+ return Error::BAD_BUFFER;
+ }
+
+ unregisterBuffer(bufferHandle);
+ if (!mCapabilities.unregisterImplyDelete) {
+ native_handle_close(bufferHandle);
+ native_handle_delete(bufferHandle);
+ }
+
+ return Error::NONE;
+}
+
+void GrallocMapper::waitFenceFd(int fenceFd, const char* logname) {
+ if (fenceFd < 0) {
+ return;
+ }
+
+ const int warningTimeout = 3500;
+ const int error = sync_wait(fenceFd, warningTimeout);
+ if (error < 0 && errno == ETIME) {
+ ALOGE("%s: fence %d didn't signal in %u ms", logname, fenceFd,
+ warningTimeout);
+ sync_wait(fenceFd, -1);
+ }
+}
+
+bool GrallocMapper::getFenceFd(const hidl_handle& fenceHandle,
+ int* outFenceFd) {
+ auto handle = fenceHandle.getNativeHandle();
+ if (handle && handle->numFds > 1) {
+ ALOGE("invalid fence handle with %d fds", handle->numFds);
+ return false;
+ }
+
+ *outFenceFd = (handle && handle->numFds == 1) ? handle->data[0] : -1;
+ return true;
+}
+
+hidl_handle GrallocMapper::getFenceHandle(int fenceFd, char* handleStorage) {
+ native_handle_t* handle = nullptr;
+ if (fenceFd >= 0) {
+ handle = native_handle_init(handleStorage, 1, 0);
+ handle->data[0] = fenceFd;
+ }
+
+ return hidl_handle(handle);
+}
+
+Return<void> GrallocMapper::lock(void* buffer, uint64_t cpuUsage,
+ const IMapper::Rect& accessRegion,
+ const hidl_handle& acquireFence,
+ lock_cb hidl_cb) {
+ buffer_handle_t bufferHandle = getRegisteredHandle(buffer);
+ if (!bufferHandle) {
+ hidl_cb(Error::BAD_BUFFER, nullptr);
+ return Void();
+ }
+
+ int fenceFd;
+ if (!getFenceFd(acquireFence, &fenceFd)) {
+ hidl_cb(Error::BAD_VALUE, 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);
- }
+ Error error =
+ lockBuffer(bufferHandle, cpuUsage, accessRegion, fenceFd, &data);
- hidl_cb(static_cast<Error>(err), data);
+ hidl_cb(error, 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{};
+Return<void> GrallocMapper::lockYCbCr(void* buffer, uint64_t cpuUsage,
+ const IMapper::Rect& accessRegion,
+ const hidl_handle& acquireFence,
+ lockYCbCr_cb hidl_cb) {
+ YCbCrLayout layout = {};
- 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);
+ buffer_handle_t bufferHandle = getRegisteredHandle(buffer);
+ if (!bufferHandle) {
+ hidl_cb(Error::BAD_BUFFER, layout);
return Void();
}
- gralloc1_rect_t rect = asGralloc1Rect(accessRegion);
-
- int fence = -1;
- if (!dupFence(acquireFence, &fence)) {
- hidl_cb(Error::NO_RESOURCES, layout_reply);
+ int fenceFd;
+ if (!getFenceFd(acquireFence, &fenceFd)) {
+ hidl_cb(Error::BAD_VALUE, layout);
return Void();
}
- std::vector<android_flex_plane_t> planes(planeCount);
- android_flex_layout_t layout{};
- layout.num_planes = planes.size();
- layout.planes = planes.data();
+ Error error =
+ lockBuffer(bufferHandle, cpuUsage, accessRegion, fenceFd, &layout);
- err = mDispatch.lockFlex(mDevice, bufferHandle, producerUsageMask,
- consumerUsageMask, &rect, &layout, fence);
- if (err == GRALLOC1_ERROR_NONE) {
- layout_reply.format = static_cast<FlexFormat>(layout.format);
+ hidl_cb(error, layout);
+ return Void();
+}
- planes.resize(layout.num_planes);
- layout_reply.planes.setToExternal(
- reinterpret_cast<FlexPlane*>(planes.data()), planes.size());
+Return<void> GrallocMapper::unlock(void* buffer, unlock_cb hidl_cb) {
+ buffer_handle_t bufferHandle = getRegisteredHandle(buffer);
+ if (!bufferHandle) {
+ hidl_cb(Error::BAD_BUFFER, nullptr);
+ return Void();
+ }
+
+ int fenceFd;
+ Error error = unlockBuffer(bufferHandle, &fenceFd);
+ if (error == Error::NONE) {
+ NATIVE_HANDLE_DECLARE_STORAGE(fenceStorage, 1, 0);
+
+ hidl_cb(error, getFenceHandle(fenceFd, fenceStorage));
+
+ if (fenceFd >= 0) {
+ close(fenceFd);
+ }
} else {
- close(fence);
+ hidl_cb(error, nullptr);
}
- hidl_cb(static_cast<Error>(err), layout_reply);
return Void();
}
-Return<void> GrallocMapperHal::unlock(const hidl_handle& bufferHandle,
- unlock_cb hidl_cb)
-{
- 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();
-}
-
-} // anonymous namespace
-
IMapper* HIDL_FETCH_IMapper(const char* /* name */) {
const hw_module_t* module = nullptr;
int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
@@ -410,12 +287,15 @@
}
uint8_t major = (module->module_api_version >> 8) & 0xff;
- if (major != 1) {
- ALOGE("unknown gralloc module major version %d", major);
- return nullptr;
+ switch (major) {
+ case 1:
+ return new Gralloc1Mapper(module);
+ case 0:
+ return new Gralloc0Mapper(module);
+ default:
+ ALOGE("unknown gralloc module major version %d", major);
+ 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
index a2f89d1..c9c6d8a 100644
--- a/graphics/mapper/2.0/default/GrallocMapper.h
+++ b/graphics/mapper/2.0/default/GrallocMapper.h
@@ -18,6 +18,10 @@
#define ANDROID_HARDWARE_GRAPHICS_MAPPER_V2_0_GRALLOC_MAPPER_H
#include <android/hardware/graphics/mapper/2.0/IMapper.h>
+#include <system/window.h>
+
+#include <mutex>
+#include <unordered_set>
namespace android {
namespace hardware {
@@ -26,6 +30,68 @@
namespace V2_0 {
namespace implementation {
+class GrallocMapper : public IMapper {
+ public:
+ // IMapper interface
+ Return<void> createDescriptor(const BufferDescriptorInfo& descriptorInfo,
+ createDescriptor_cb hidl_cb) override;
+ Return<void> importBuffer(const hidl_handle& rawHandle,
+ importBuffer_cb hidl_cb) override;
+ Return<Error> freeBuffer(void* buffer) override;
+ Return<void> lock(void* buffer, uint64_t cpuUsage,
+ const IMapper::Rect& accessRegion,
+ const hidl_handle& acquireFence,
+ lock_cb hidl_cb) override;
+ Return<void> lockYCbCr(void* buffer, uint64_t cpuUsage,
+ const IMapper::Rect& accessRegion,
+ const hidl_handle& acquireFence,
+ lockYCbCr_cb hidl_cb) override;
+ Return<void> unlock(void* buffer, unlock_cb hidl_cb) override;
+
+ protected:
+ static void waitFenceFd(int fenceFd, const char* logname);
+
+ struct {
+ bool highUsageBits;
+ bool layeredBuffers;
+ bool unregisterImplyDelete;
+ } mCapabilities = {};
+
+ private:
+ virtual bool validateDescriptorInfo(
+ const BufferDescriptorInfo& descriptorInfo) const;
+
+ // Register a buffer. The handle is already cloned by the caller.
+ virtual Error registerBuffer(buffer_handle_t bufferHandle) = 0;
+
+ // Unregister a buffer. The handle is closed and deleted by the
+ // callee if and only if mCapabilities.unregisterImplyDelete is set.
+ virtual void unregisterBuffer(buffer_handle_t bufferHandle) = 0;
+
+ // Lock a buffer. The fence is owned by the caller.
+ virtual Error lockBuffer(buffer_handle_t bufferHandle, uint64_t cpuUsage,
+ const IMapper::Rect& accessRegion, int fenceFd,
+ void** outData) = 0;
+ virtual Error lockBuffer(buffer_handle_t bufferHandle, uint64_t cpuUsage,
+ const IMapper::Rect& accessRegion, int fenceFd,
+ YCbCrLayout* outLayout) = 0;
+
+ // Unlock a buffer. The returned fence is owned by the caller.
+ virtual Error unlockBuffer(buffer_handle_t bufferHandle,
+ int* outFenceFd) = 0;
+
+ static bool addRegisteredHandle(buffer_handle_t bufferHandle);
+ static buffer_handle_t getRegisteredHandle(const void* buffer);
+ static native_handle_t* popRegisteredHandle(void* buffer);
+
+ static bool getFenceFd(const hidl_handle& fenceHandle, int* outFenceFd);
+ static hidl_handle getFenceHandle(int fenceFd, char* handleStorage);
+
+ // these are static and shared by all mappers
+ static std::mutex mMutex;
+ static std::unordered_set<buffer_handle_t> mRegisteredHandles;
+};
+
extern "C" IMapper* HIDL_FETCH_IMapper(const char* name);
} // namespace implementation
diff --git a/graphics/mapper/2.0/types.hal b/graphics/mapper/2.0/types.hal
index 2946e85..e9b2f3a 100644
--- a/graphics/mapper/2.0/types.hal
+++ b/graphics/mapper/2.0/types.hal
@@ -16,101 +16,50 @@
package android.hardware.graphics.mapper@2.0;
+enum Error : int32_t {
+ NONE = 0, /** no error */
+ BAD_DESCRIPTOR = 1, /** invalid BufferDescriptor */
+ BAD_BUFFER = 2, /** invalid buffer handle */
+ BAD_VALUE = 3, /** invalid width, height, etc. */
+ /* 4 is reserved */
+ NO_RESOURCES = 5, /** temporary failure due to resource contention */
+ /* 6 is reserved */
+ UNSUPPORTED = 7, /** permanent failure */
+};
+
/**
- * 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.
+ * A buffer descriptor is an implementation-defined opaque data returned by
+ * createDescriptor. It describes the properties of a buffer and is consumed
+ * by the allocator.
*/
+typedef vec<uint32_t> BufferDescriptor;
-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 */
+/**
+ * Structure for describing YCbCr formats for consumption by applications.
+ * This is used with PixelFormat::YCBCR_*_888.
+ *
+ * Buffer chroma subsampling is defined in the format.
+ * e.g. PixelFormat::YCBCR_420_888 has subsampling 4:2:0.
+ *
+ * Buffers must have a 8 bit depth.
+ *
+ * y, cb, and cr point to the first byte of their respective planes.
+ *
+ * Stride describes the distance in bytes from the first value of one row of
+ * the image to the first value of the next row. It includes the width of the
+ * image plus padding.
+ * yStride is the stride of the luma plane.
+ * cStride is the stride of the chroma planes.
+ *
+ * chromaStep is the distance in bytes from one chroma pixel value to the
+ * next. This is 2 bytes for semiplanar (because chroma values are interleaved
+ * and each chroma value is one byte) and 1 for planar.
+ */
+struct YCbCrLayout {
+ pointer y;
+ pointer cb;
+ pointer cr;
+ uint32_t yStride;
+ uint32_t cStride;
+ uint32_t chromaStep;
};
-
-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/graphics/mapper/2.0/vts/functional/Android.bp b/graphics/mapper/2.0/vts/functional/Android.bp
index e26f087..1c0e4c5 100644
--- a/graphics/mapper/2.0/vts/functional/Android.bp
+++ b/graphics/mapper/2.0/vts/functional/Android.bp
@@ -24,7 +24,6 @@
],
static_libs: [
"VtsHalHidlTargetTestBase",
- "libVtsHalGraphicsAllocatorTestUtils",
],
cflags: [
"-Wall",
@@ -54,7 +53,6 @@
"android.hardware.graphics.common@1.0",
],
static_libs: [
- "libVtsHalGraphicsAllocatorTestUtils",
"libVtsHalGraphicsMapperTestUtils",
"VtsHalHidlTargetTestBase",
],
diff --git a/graphics/mapper/2.0/vts/functional/VtsHalGraphicsMapperTestUtils.cpp b/graphics/mapper/2.0/vts/functional/VtsHalGraphicsMapperTestUtils.cpp
index f6a26ac..c534889 100644
--- a/graphics/mapper/2.0/vts/functional/VtsHalGraphicsMapperTestUtils.cpp
+++ b/graphics/mapper/2.0/vts/functional/VtsHalGraphicsMapperTestUtils.cpp
@@ -25,228 +25,233 @@
namespace V2_0 {
namespace tests {
-using android::hardware::graphics::allocator::V2_0::Buffer;
-using android::hardware::graphics::allocator::V2_0::BufferDescriptor;
-using android::hardware::graphics::allocator::V2_0::Error;
-
-Mapper::Mapper() { init(); }
-
-void Mapper::init() {
- mMapper = ::testing::VtsHalHidlTargetTestBase::getService<IMapper>();
- ASSERT_NE(nullptr, mMapper.get()) << "failed to get mapper service";
- ASSERT_FALSE(mMapper->isRemote()) << "mapper is not in passthrough mode";
+Gralloc::Gralloc() {
+ init();
}
-Mapper::~Mapper() {
- for (auto it : mHandles) {
- while (it.second) {
- EXPECT_EQ(Error::NONE, mMapper->release(it.first))
- << "failed to release handle " << it.first;
- it.second--;
+void Gralloc::init() {
+ mAllocator = ::testing::VtsHalHidlTargetTestBase::getService<IAllocator>();
+ ASSERT_NE(nullptr, mAllocator.get()) << "failed to get allocator service";
+
+ mMapper = ::testing::VtsHalHidlTargetTestBase::getService<IMapper>();
+ ASSERT_NE(nullptr, mMapper.get()) << "failed to get mapper service";
+ ASSERT_FALSE(mMapper->isRemote()) << "mapper is not in passthrough mode";
+}
+
+Gralloc::~Gralloc() {
+ for (auto bufferHandle : mClonedBuffers) {
+ auto buffer = const_cast<native_handle_t*>(bufferHandle);
+ native_handle_close(buffer);
+ native_handle_delete(buffer);
}
- }
- mHandles.clear();
+ mClonedBuffers.clear();
+
+ for (auto bufferHandle : mImportedBuffers) {
+ auto buffer = const_cast<native_handle_t*>(bufferHandle);
+ EXPECT_EQ(Error::NONE, mMapper->freeBuffer(buffer))
+ << "failed to free buffer " << buffer;
+ }
+ mImportedBuffers.clear();
}
-sp<IMapper> Mapper::getRaw() const { return mMapper; }
-
-void Mapper::retain(const native_handle_t* handle) {
- Error error = mMapper->retain(handle);
- ASSERT_EQ(Error::NONE, error) << "failed to retain handle " << handle;
-
- mHandles[handle]++;
+sp<IAllocator> Gralloc::getAllocator() const {
+ return mAllocator;
}
-void Mapper::release(const native_handle_t* handle) {
- Error error = mMapper->release(handle);
- ASSERT_EQ(Error::NONE, error) << "failed to release handle " << handle;
+std::string Gralloc::dumpDebugInfo() {
+ std::string debugInfo;
+ mAllocator->dumpDebugInfo(
+ [&](const auto& tmpDebugInfo) { debugInfo = tmpDebugInfo.c_str(); });
- if (--mHandles[handle] == 0) {
- mHandles.erase(handle);
- }
+ return debugInfo;
}
-Mapper::Dimensions Mapper::getDimensions(const native_handle_t* handle) {
- Dimensions dimensions = {};
- mMapper->getDimensions(handle, [&](const auto& tmpError, const auto& tmpWidth,
- const auto& tmpHeight) {
- ASSERT_EQ(Error::NONE, tmpError)
- << "failed to get dimensions for handle " << handle;
- dimensions.width = tmpWidth;
- dimensions.height = tmpHeight;
- });
+const native_handle_t* Gralloc::cloneBuffer(const hidl_handle& rawHandle) {
+ const native_handle_t* bufferHandle =
+ native_handle_clone(rawHandle.getNativeHandle());
+ EXPECT_NE(nullptr, bufferHandle);
- return dimensions;
+ if (bufferHandle) {
+ mClonedBuffers.insert(bufferHandle);
+ }
+
+ return bufferHandle;
}
-PixelFormat Mapper::getFormat(const native_handle_t* handle) {
- PixelFormat format = static_cast<PixelFormat>(0);
- mMapper->getFormat(handle, [&](const auto& tmpError, const auto& tmpFormat) {
- ASSERT_EQ(Error::NONE, tmpError)
- << "failed to get format for handle " << handle;
- format = tmpFormat;
- });
+std::vector<const native_handle_t*> Gralloc::allocate(
+ const BufferDescriptor& descriptor, uint32_t count, bool import,
+ uint32_t* outStride) {
+ std::vector<const native_handle_t*> bufferHandles;
+ bufferHandles.reserve(count);
+ mAllocator->allocate(
+ descriptor, count, [&](const auto& tmpError, const auto& tmpStride,
+ const auto& tmpBuffers) {
+ ASSERT_EQ(Error::NONE, tmpError) << "failed to allocate buffers";
+ ASSERT_EQ(count, tmpBuffers.size()) << "invalid buffer array";
- return format;
+ for (uint32_t i = 0; i < count; i++) {
+ if (import) {
+ ASSERT_NO_FATAL_FAILURE(
+ bufferHandles.push_back(importBuffer(tmpBuffers[i])));
+ } else {
+ ASSERT_NO_FATAL_FAILURE(
+ bufferHandles.push_back(cloneBuffer(tmpBuffers[i])));
+ }
+ }
+
+ if (outStride) {
+ *outStride = tmpStride;
+ }
+ });
+
+ if (::testing::Test::HasFatalFailure()) {
+ bufferHandles.clear();
+ }
+
+ return bufferHandles;
}
-uint32_t Mapper::getLayerCount(const native_handle_t* handle) {
- uint32_t count = 0;
- mMapper->getLayerCount(
- handle, [&](const auto& tmpError, const auto& tmpCount) {
- ASSERT_EQ(Error::NONE, tmpError)
- << "failed to get layer count for handle " << handle;
- count = tmpCount;
- });
+const native_handle_t* Gralloc::allocate(
+ const IMapper::BufferDescriptorInfo& descriptorInfo, bool import,
+ uint32_t* outStride) {
+ BufferDescriptor descriptor = createDescriptor(descriptorInfo);
+ if (::testing::Test::HasFatalFailure()) {
+ return nullptr;
+ }
- return count;
+ auto buffers = allocate(descriptor, 1, import, outStride);
+ if (::testing::Test::HasFatalFailure()) {
+ return nullptr;
+ }
+
+ return buffers[0];
}
-uint64_t Mapper::getProducerUsageMask(const native_handle_t* handle) {
- uint64_t usageMask = 0;
- mMapper->getProducerUsageMask(
- handle, [&](const auto& tmpError, const auto& tmpUsageMask) {
- ASSERT_EQ(Error::NONE, tmpError)
- << "failed to get producer usage mask for handle " << handle;
- usageMask = tmpUsageMask;
- });
-
- return usageMask;
+sp<IMapper> Gralloc::getMapper() const {
+ return mMapper;
}
-uint64_t Mapper::getConsumerUsageMask(const native_handle_t* handle) {
- uint64_t usageMask = 0;
- mMapper->getConsumerUsageMask(
- handle, [&](const auto& tmpError, const auto& tmpUsageMask) {
- ASSERT_EQ(Error::NONE, tmpError)
- << "failed to get consumer usage mask for handle " << handle;
- usageMask = tmpUsageMask;
- });
+BufferDescriptor Gralloc::createDescriptor(
+ const IMapper::BufferDescriptorInfo& descriptorInfo) {
+ BufferDescriptor descriptor;
+ mMapper->createDescriptor(
+ descriptorInfo, [&](const auto& tmpError, const auto& tmpDescriptor) {
+ ASSERT_EQ(Error::NONE, tmpError) << "failed to create descriptor";
+ descriptor = tmpDescriptor;
+ });
- return usageMask;
+ return descriptor;
}
-BackingStore Mapper::getBackingStore(const native_handle_t* handle) {
- BackingStore backingStore = 0;
- mMapper->getBackingStore(
- handle, [&](const auto& tmpError, const auto& tmpBackingStore) {
- ASSERT_EQ(Error::NONE, tmpError)
- << "failed to get backing store for handle " << handle;
- backingStore = tmpBackingStore;
- });
+const native_handle_t* Gralloc::importBuffer(const hidl_handle& rawHandle) {
+ const native_handle_t* bufferHandle = nullptr;
+ mMapper->importBuffer(
+ rawHandle, [&](const auto& tmpError, const auto& tmpBuffer) {
+ ASSERT_EQ(Error::NONE, tmpError) << "failed to import buffer %p"
+ << rawHandle.getNativeHandle();
+ bufferHandle = static_cast<const native_handle_t*>(tmpBuffer);
+ });
- return backingStore;
+ if (bufferHandle) {
+ mImportedBuffers.insert(bufferHandle);
+ }
+
+ return bufferHandle;
}
-uint32_t Mapper::getStride(const native_handle_t* handle) {
- uint32_t stride = 0;
- mMapper->getStride(handle, [&](const auto& tmpError, const auto& tmpStride) {
- ASSERT_EQ(Error::NONE, tmpError)
- << "failed to get stride for handle " << handle;
- stride = tmpStride;
- });
+void Gralloc::freeBuffer(const native_handle_t* bufferHandle) {
+ auto buffer = const_cast<native_handle_t*>(bufferHandle);
- return stride;
+ if (mImportedBuffers.erase(bufferHandle)) {
+ Error error = mMapper->freeBuffer(buffer);
+ ASSERT_EQ(Error::NONE, error) << "failed to free buffer " << buffer;
+ } else {
+ mClonedBuffers.erase(bufferHandle);
+ native_handle_close(buffer);
+ native_handle_delete(buffer);
+ }
}
-void* Mapper::lock(const native_handle_t* handle, uint64_t producerUsageMask,
- uint64_t consumerUsageMask,
- const IMapper::Rect& accessRegion, int acquireFence) {
- NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 0, 1);
- native_handle_t* acquireFenceHandle = nullptr;
- if (acquireFence >= 0) {
- acquireFenceHandle = native_handle_init(acquireFenceStorage, 0, 1);
- acquireFenceHandle->data[0] = acquireFence;
- }
+void* Gralloc::lock(const native_handle_t* bufferHandle, uint64_t cpuUsage,
+ const IMapper::Rect& accessRegion, int acquireFence) {
+ auto buffer = const_cast<native_handle_t*>(bufferHandle);
- void* data = nullptr;
- mMapper->lock(
- handle, producerUsageMask, consumerUsageMask, accessRegion,
- acquireFenceHandle, [&](const auto& tmpError, const auto& tmpData) {
- ASSERT_EQ(Error::NONE, tmpError) << "failed to lock handle " << handle;
- data = tmpData;
- });
+ NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
+ hidl_handle acquireFenceHandle;
+ if (acquireFence >= 0) {
+ auto h = native_handle_init(acquireFenceStorage, 1, 0);
+ h->data[0] = acquireFence;
+ acquireFenceHandle = h;
+ }
- if (acquireFence >= 0) {
- close(acquireFence);
- }
-
- return data;
-}
-
-FlexLayout Mapper::lockFlex(const native_handle_t* handle,
- uint64_t producerUsageMask,
- uint64_t consumerUsageMask,
- const IMapper::Rect& accessRegion,
- int acquireFence) {
- NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 0, 1);
- native_handle_t* acquireFenceHandle = nullptr;
- if (acquireFence >= 0) {
- acquireFenceHandle = native_handle_init(acquireFenceStorage, 0, 1);
- acquireFenceHandle->data[0] = acquireFence;
- }
-
- FlexLayout layout = {};
- mMapper->lockFlex(handle, producerUsageMask, consumerUsageMask, accessRegion,
- acquireFenceHandle,
- [&](const auto& tmpError, const auto& tmpLayout) {
+ void* data = nullptr;
+ mMapper->lock(buffer, cpuUsage, accessRegion, acquireFenceHandle,
+ [&](const auto& tmpError, const auto& tmpData) {
ASSERT_EQ(Error::NONE, tmpError)
- << "failed to lockFlex handle " << handle;
- layout = tmpLayout;
- });
+ << "failed to lock buffer " << buffer;
+ data = tmpData;
+ });
- if (acquireFence >= 0) {
- close(acquireFence);
- }
-
- return layout;
-}
-
-int Mapper::unlock(const native_handle_t* handle) {
- int releaseFence = -1;
- mMapper->unlock(handle, [&](const auto& tmpError,
- const auto& tmpReleaseFence) {
- ASSERT_EQ(Error::NONE, tmpError) << "failed to unlock handle " << handle;
-
- auto handle = tmpReleaseFence.getNativeHandle();
- if (handle) {
- ASSERT_EQ(0, handle->numInts) << "invalid fence handle " << handle;
- if (handle->numFds == 1) {
- releaseFence = dup(handle->data[0]);
- ASSERT_LT(0, releaseFence) << "failed to dup fence fd";
- } else {
- ASSERT_EQ(0, handle->numFds) << " invalid fence handle " << handle;
- }
+ if (acquireFence >= 0) {
+ close(acquireFence);
}
- });
- return releaseFence;
+ return data;
}
-const native_handle_t* Mapper::allocate(
- std::unique_ptr<AllocatorClient>& allocatorClient,
- const IAllocatorClient::BufferDescriptorInfo& info) {
- BufferDescriptor descriptor = allocatorClient->createDescriptor(info);
- if (::testing::Test::HasFatalFailure()) {
- return nullptr;
- }
+YCbCrLayout Gralloc::lockYCbCr(const native_handle_t* bufferHandle,
+ uint64_t cpuUsage,
+ const IMapper::Rect& accessRegion,
+ int acquireFence) {
+ auto buffer = const_cast<native_handle_t*>(bufferHandle);
- Buffer buffer = allocatorClient->allocate(descriptor);
- if (::testing::Test::HasFatalFailure()) {
- allocatorClient->destroyDescriptor(descriptor);
- return nullptr;
- }
+ NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
+ hidl_handle acquireFenceHandle;
+ if (acquireFence >= 0) {
+ auto h = native_handle_init(acquireFenceStorage, 1, 0);
+ h->data[0] = acquireFence;
+ acquireFenceHandle = h;
+ }
- const native_handle_t* handle =
- allocatorClient->exportHandle(descriptor, buffer);
- if (handle) {
- retain(handle);
- }
+ YCbCrLayout layout = {};
+ mMapper->lockYCbCr(buffer, cpuUsage, accessRegion, acquireFenceHandle,
+ [&](const auto& tmpError, const auto& tmpLayout) {
+ ASSERT_EQ(Error::NONE, tmpError)
+ << "failed to lockYCbCr buffer " << buffer;
+ layout = tmpLayout;
+ });
- allocatorClient->free(buffer);
- allocatorClient->destroyDescriptor(descriptor);
+ if (acquireFence >= 0) {
+ close(acquireFence);
+ }
- return handle;
+ return layout;
+}
+
+int Gralloc::unlock(const native_handle_t* bufferHandle) {
+ auto buffer = const_cast<native_handle_t*>(bufferHandle);
+
+ int releaseFence = -1;
+ mMapper->unlock(
+ buffer, [&](const auto& tmpError, const auto& tmpReleaseFence) {
+ ASSERT_EQ(Error::NONE, tmpError) << "failed to unlock buffer "
+ << buffer;
+
+ auto fenceHandle = tmpReleaseFence.getNativeHandle();
+ if (fenceHandle) {
+ ASSERT_EQ(0, fenceHandle->numInts) << "invalid fence handle "
+ << fenceHandle;
+ if (fenceHandle->numFds == 1) {
+ releaseFence = dup(fenceHandle->data[0]);
+ ASSERT_LT(0, releaseFence) << "failed to dup fence fd";
+ } else {
+ ASSERT_EQ(0, fenceHandle->numFds)
+ << " invalid fence handle " << fenceHandle;
+ }
+ }
+ });
+
+ return releaseFence;
}
} // namespace tests
diff --git a/graphics/mapper/2.0/vts/functional/VtsHalGraphicsMapperTestUtils.h b/graphics/mapper/2.0/vts/functional/VtsHalGraphicsMapperTestUtils.h
index c186b00..757f20b 100644
--- a/graphics/mapper/2.0/vts/functional/VtsHalGraphicsMapperTestUtils.h
+++ b/graphics/mapper/2.0/vts/functional/VtsHalGraphicsMapperTestUtils.h
@@ -17,14 +17,12 @@
#ifndef VTS_HAL_GRAPHICS_MAPPER_UTILS
#define VTS_HAL_GRAPHICS_MAPPER_UTILS
-#include <memory>
-#include <unordered_map>
+#include <unordered_set>
+#include <android/hardware/graphics/allocator/2.0/IAllocator.h>
#include <android/hardware/graphics/mapper/2.0/IMapper.h>
#include <utils/StrongPointer.h>
-#include "VtsHalGraphicsAllocatorTestUtils.h"
-
namespace android {
namespace hardware {
namespace graphics {
@@ -32,59 +30,62 @@
namespace V2_0 {
namespace tests {
-using android::hardware::graphics::common::V1_0::PixelFormat;
-using android::hardware::graphics::allocator::V2_0::IAllocatorClient;
-using android::hardware::graphics::allocator::V2_0::tests::AllocatorClient;
+using android::hardware::graphics::allocator::V2_0::IAllocator;
-// A wrapper to IMapper.
-class Mapper {
- public:
- Mapper();
- ~Mapper();
+// A wrapper to IAllocator and IMapper.
+class Gralloc {
+ public:
+ Gralloc();
+ ~Gralloc();
- sp<IMapper> getRaw() const;
+ // IAllocator methods
- void retain(const native_handle_t* handle);
- void release(const native_handle_t* handle);
+ sp<IAllocator> getAllocator() const;
- struct Dimensions {
- uint32_t width;
- uint32_t height;
- };
- Dimensions getDimensions(const native_handle_t* handle);
+ std::string dumpDebugInfo();
- PixelFormat getFormat(const native_handle_t* handle);
- uint32_t getLayerCount(const native_handle_t* handle);
- uint64_t getProducerUsageMask(const native_handle_t* handle);
- uint64_t getConsumerUsageMask(const native_handle_t* handle);
- BackingStore getBackingStore(const native_handle_t* handle);
- uint32_t getStride(const native_handle_t* handle);
+ // When import is false, this simply calls IAllocator::allocate. When import
+ // is true, the returned buffers are also imported into the mapper.
+ //
+ // Either case, the returned buffers must be freed with freeBuffer.
+ std::vector<const native_handle_t*> allocate(
+ const BufferDescriptor& descriptor, uint32_t count, bool import = true,
+ uint32_t* outStride = nullptr);
+ const native_handle_t* allocate(
+ const IMapper::BufferDescriptorInfo& descriptorInfo, bool import = true,
+ uint32_t* outStride = nullptr);
- // We use fd instead of hidl_handle in these functions to pass fences
- // in and out of the mapper. The ownership of the fd is always transferred
- // with each of these functions.
- void* lock(const native_handle_t* handle, uint64_t producerUsageMask,
- uint64_t consumerUsageMask, const IMapper::Rect& accessRegion,
- int acquireFence);
- FlexLayout lockFlex(const native_handle_t* handle, uint64_t producerUsageMask,
- uint64_t consumerUsageMask,
- const IMapper::Rect& accessRegion, int acquireFence);
- int unlock(const native_handle_t* handle);
+ // IMapper methods
- // Requests AllocatorClient to allocate a buffer, export the handle, and
- // register the handle with mapper.
- const native_handle_t* allocate(
- std::unique_ptr<AllocatorClient>& allocatorClient,
- const IAllocatorClient::BufferDescriptorInfo& info);
+ sp<IMapper> getMapper() const;
- private:
- void init();
+ BufferDescriptor createDescriptor(
+ const IMapper::BufferDescriptorInfo& descriptorInfo);
- sp<IMapper> mMapper;
+ const native_handle_t* importBuffer(const hidl_handle& rawHandle);
+ void freeBuffer(const native_handle_t* bufferHandle);
- // Keep track of all registered (retained) handles. When a test fails with
- // ASSERT_*, the destructor will release the handles for the test.
- std::unordered_map<const native_handle_t*, uint64_t> mHandles;
+ // We use fd instead of hidl_handle in these functions to pass fences
+ // in and out of the mapper. The ownership of the fd is always transferred
+ // with each of these functions.
+ void* lock(const native_handle_t* bufferHandle, uint64_t cpuUsage,
+ const IMapper::Rect& accessRegion, int acquireFence);
+ YCbCrLayout lockYCbCr(const native_handle_t* bufferHandle,
+ uint64_t cpuUsage, const IMapper::Rect& accessRegion,
+ int acquireFence);
+ int unlock(const native_handle_t* bufferHandle);
+
+ private:
+ void init();
+ const native_handle_t* cloneBuffer(const hidl_handle& rawHandle);
+
+ sp<IAllocator> mAllocator;
+ sp<IMapper> mMapper;
+
+ // Keep track of all cloned and imported handles. When a test fails with
+ // ASSERT_*, the destructor will free the handles for the test.
+ std::unordered_set<const native_handle_t*> mClonedBuffers;
+ std::unordered_set<const native_handle_t*> mImportedBuffers;
};
} // namespace tests
diff --git a/graphics/mapper/2.0/vts/functional/VtsHalGraphicsMapperV2_0TargetTest.cpp b/graphics/mapper/2.0/vts/functional/VtsHalGraphicsMapperV2_0TargetTest.cpp
index 92d74d5..f066a1e 100644
--- a/graphics/mapper/2.0/vts/functional/VtsHalGraphicsMapperV2_0TargetTest.cpp
+++ b/graphics/mapper/2.0/vts/functional/VtsHalGraphicsMapperV2_0TargetTest.cpp
@@ -14,10 +14,10 @@
* limitations under the License.
*/
-#define LOG_TAG "graphics_mapper_hidl_hal_test"
+#define LOG_TAG "VtsHalGraphicsMapperV2_0TargetTest"
-#include <android-base/logging.h>
#include <VtsHalHidlTargetTestBase.h>
+#include <android-base/logging.h>
#include <sync/sync.h>
#include "VtsHalGraphicsMapperTestUtils.h"
@@ -29,202 +29,384 @@
namespace tests {
namespace {
-using namespace android::hardware::graphics::allocator::V2_0;
-using namespace android::hardware::graphics::allocator::V2_0::tests;
+using android::hardware::graphics::common::V1_0::BufferUsage;
+using android::hardware::graphics::common::V1_0::PixelFormat;
class GraphicsMapperHidlTest : public ::testing::VtsHalHidlTargetTestBase {
protected:
void SetUp() override {
- ASSERT_NO_FATAL_FAILURE(mAllocator = std::make_unique<Allocator>());
- ASSERT_NO_FATAL_FAILURE(mAllocatorClient = mAllocator->createClient());
- ASSERT_NO_FATAL_FAILURE(mMapper = std::make_unique<Mapper>());
+ ASSERT_NO_FATAL_FAILURE(mGralloc = std::make_unique<Gralloc>());
- mDummyDescriptorInfo.width = 64;
- mDummyDescriptorInfo.height = 64;
- mDummyDescriptorInfo.layerCount = 1;
- mDummyDescriptorInfo.format = PixelFormat::RGBA_8888;
- mDummyDescriptorInfo.producerUsageMask =
- static_cast<uint64_t>(ProducerUsage::CPU_WRITE);
- mDummyDescriptorInfo.consumerUsageMask =
- static_cast<uint64_t>(ConsumerUsage::CPU_READ);
+ mDummyDescriptorInfo.width = 64;
+ mDummyDescriptorInfo.height = 64;
+ mDummyDescriptorInfo.layerCount = 1;
+ mDummyDescriptorInfo.format = PixelFormat::RGBA_8888;
+ mDummyDescriptorInfo.usage = static_cast<uint64_t>(
+ BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN);
}
void TearDown() override {}
- std::unique_ptr<Allocator> mAllocator;
- std::unique_ptr<AllocatorClient> mAllocatorClient;
- std::unique_ptr<Mapper> mMapper;
- IAllocatorClient::BufferDescriptorInfo mDummyDescriptorInfo{};
+ std::unique_ptr<Gralloc> mGralloc;
+ IMapper::BufferDescriptorInfo mDummyDescriptorInfo{};
};
/**
- * Test IMapper::retain and IMapper::release.
+ * Test IAllocator::dumpDebugInfo by calling it.
*/
-TEST_F(GraphicsMapperHidlTest, RetainRelease) {
- const native_handle_t* buffer;
- ASSERT_NO_FATAL_FAILURE(
- buffer = mMapper->allocate(mAllocatorClient, mDummyDescriptorInfo));
-
- const int maxRefs = 10;
- for (int i = 0; i < maxRefs; i++) {
- ASSERT_NO_FATAL_FAILURE(mMapper->retain(buffer));
- }
- for (int i = 0; i < maxRefs; i++) {
- ASSERT_NO_FATAL_FAILURE(mMapper->release(buffer));
- }
-
- ASSERT_NO_FATAL_FAILURE(mMapper->release(buffer));
+TEST_F(GraphicsMapperHidlTest, AllocatorDumpDebugInfo) {
+ mGralloc->dumpDebugInfo();
}
/**
- * Test IMapper::get* getters.
+ * Test IAllocator::allocate with valid buffer descriptors.
*/
-TEST_F(GraphicsMapperHidlTest, Getters) {
- const native_handle_t* buffer;
- ASSERT_NO_FATAL_FAILURE(
- buffer = mMapper->allocate(mAllocatorClient, mDummyDescriptorInfo));
+TEST_F(GraphicsMapperHidlTest, AllocatorAllocate) {
+ BufferDescriptor descriptor;
+ ASSERT_NO_FATAL_FAILURE(
+ descriptor = mGralloc->createDescriptor(mDummyDescriptorInfo));
- IAllocatorClient::BufferDescriptorInfo info = {};
+ for (uint32_t count = 0; count < 5; count++) {
+ std::vector<const native_handle_t*> bufferHandles;
+ uint32_t stride;
+ ASSERT_NO_FATAL_FAILURE(bufferHandles = mGralloc->allocate(
+ descriptor, count, false, &stride));
- Mapper::Dimensions dimensions;
- ASSERT_NO_FATAL_FAILURE(dimensions = mMapper->getDimensions(buffer));
- info.width = dimensions.width;
- info.height = dimensions.height;
+ if (count >= 1) {
+ EXPECT_LE(mDummyDescriptorInfo.width, stride)
+ << "invalid buffer stride";
+ }
- ASSERT_NO_FATAL_FAILURE(info.format = mMapper->getFormat(buffer));
- ASSERT_NO_FATAL_FAILURE(info.producerUsageMask =
- mMapper->getProducerUsageMask(buffer));
- ASSERT_NO_FATAL_FAILURE(info.consumerUsageMask =
- mMapper->getConsumerUsageMask(buffer));
+ for (auto bufferHandle : bufferHandles) {
+ mGralloc->freeBuffer(bufferHandle);
+ }
+ }
+}
- EXPECT_EQ(mDummyDescriptorInfo.width, info.width);
- EXPECT_EQ(mDummyDescriptorInfo.height, info.height);
- EXPECT_EQ(mDummyDescriptorInfo.format, info.format);
- EXPECT_EQ(mDummyDescriptorInfo.producerUsageMask, info.producerUsageMask);
- EXPECT_EQ(mDummyDescriptorInfo.consumerUsageMask, info.consumerUsageMask);
+/**
+ * Test IAllocator::allocate with invalid buffer descriptors.
+ */
+TEST_F(GraphicsMapperHidlTest, AllocatorAllocateNegative) {
+ // this assumes any valid descriptor is non-empty
+ BufferDescriptor descriptor;
+ mGralloc->getAllocator()->allocate(
+ descriptor, 1, [&](const auto& tmpError, const auto&, const auto&) {
+ EXPECT_EQ(Error::BAD_DESCRIPTOR, tmpError);
+ });
+}
- ASSERT_NO_FATAL_FAILURE(mMapper->getBackingStore(buffer));
+/**
+ * Test IAllocator::allocate does not leak.
+ */
+TEST_F(GraphicsMapperHidlTest, AllocatorAllocateNoLeak) {
+ auto info = mDummyDescriptorInfo;
+ info.width = 1024;
+ info.height = 1024;
- uint32_t stride;
- ASSERT_NO_FATAL_FAILURE(stride = mMapper->getStride(buffer));
- EXPECT_LE(info.width, stride);
+ for (int i = 0; i < 2048; i++) {
+ auto bufferHandle = mGralloc->allocate(info, false);
+ mGralloc->freeBuffer(bufferHandle);
+ }
+}
+
+/**
+ * Test IMapper::createDescriptor with valid descriptor info.
+ */
+TEST_F(GraphicsMapperHidlTest, CreateDescriptorBasic) {
+ ASSERT_NO_FATAL_FAILURE(mGralloc->createDescriptor(mDummyDescriptorInfo));
+}
+
+/**
+ * Test IMapper::createDescriptor with invalid descriptor info.
+ */
+TEST_F(GraphicsMapperHidlTest, CreateDescriptorNegative) {
+ auto info = mDummyDescriptorInfo;
+ info.width = 0;
+ mGralloc->getMapper()->createDescriptor(
+ info, [&](const auto& tmpError, const auto&) {
+ EXPECT_EQ(Error::BAD_VALUE, tmpError)
+ << "createDescriptor did not fail with BAD_VALUE";
+ });
+}
+
+/**
+ * Test IMapper::importBuffer and IMapper::freeBuffer with allocated buffers.
+ */
+TEST_F(GraphicsMapperHidlTest, ImportFreeBufferBasic) {
+ const native_handle_t* bufferHandle;
+ ASSERT_NO_FATAL_FAILURE(bufferHandle =
+ mGralloc->allocate(mDummyDescriptorInfo, true));
+ ASSERT_NO_FATAL_FAILURE(mGralloc->freeBuffer(bufferHandle));
+}
+
+/**
+ * Test IMapper::importBuffer and IMapper::freeBuffer with cloned buffers.
+ */
+TEST_F(GraphicsMapperHidlTest, ImportFreeBufferClone) {
+ const native_handle_t* clonedBufferHandle;
+ ASSERT_NO_FATAL_FAILURE(
+ clonedBufferHandle = mGralloc->allocate(mDummyDescriptorInfo, false));
+
+ // A cloned handle is a raw handle. Check that we can import it multiple
+ // times.
+ const native_handle_t* importedBufferHandles[2];
+ ASSERT_NO_FATAL_FAILURE(importedBufferHandles[0] =
+ mGralloc->importBuffer(clonedBufferHandle));
+ ASSERT_NO_FATAL_FAILURE(importedBufferHandles[1] =
+ mGralloc->importBuffer(clonedBufferHandle));
+ ASSERT_NO_FATAL_FAILURE(mGralloc->freeBuffer(importedBufferHandles[0]));
+ ASSERT_NO_FATAL_FAILURE(mGralloc->freeBuffer(importedBufferHandles[1]));
+
+ ASSERT_NO_FATAL_FAILURE(mGralloc->freeBuffer(clonedBufferHandle));
+}
+
+/**
+ * Test IMapper::importBuffer and IMapper::freeBuffer cross mapper instances.
+ */
+TEST_F(GraphicsMapperHidlTest, ImportFreeBufferSingleton) {
+ const native_handle_t* rawHandle;
+ ASSERT_NO_FATAL_FAILURE(
+ rawHandle = mGralloc->allocate(mDummyDescriptorInfo, false));
+
+ native_handle_t* importedHandle = nullptr;
+ mGralloc->getMapper()->importBuffer(
+ rawHandle, [&](const auto& tmpError, const auto& buffer) {
+ ASSERT_EQ(Error::NONE, tmpError);
+ importedHandle = static_cast<native_handle_t*>(buffer);
+ });
+
+ // free the imported handle with another mapper
+ std::unique_ptr<Gralloc> anotherGralloc;
+ ASSERT_NO_FATAL_FAILURE(anotherGralloc = std::make_unique<Gralloc>());
+ Error error = mGralloc->getMapper()->freeBuffer(importedHandle);
+ ASSERT_EQ(Error::NONE, error);
+
+ ASSERT_NO_FATAL_FAILURE(mGralloc->freeBuffer(rawHandle));
+}
+
+/**
+ * Test IMapper::importBuffer and IMapper::freeBuffer do not leak.
+ */
+TEST_F(GraphicsMapperHidlTest, ImportFreeBufferNoLeak) {
+ auto info = mDummyDescriptorInfo;
+ info.width = 1024;
+ info.height = 1024;
+
+ for (int i = 0; i < 2048; i++) {
+ auto bufferHandle = mGralloc->allocate(info, true);
+ mGralloc->freeBuffer(bufferHandle);
+ }
+}
+
+/**
+ * Test IMapper::importBuffer with invalid buffers.
+ */
+TEST_F(GraphicsMapperHidlTest, ImportBufferNegative) {
+ native_handle_t* invalidHandle = nullptr;
+ mGralloc->getMapper()->importBuffer(
+ invalidHandle, [&](const auto& tmpError, const auto&) {
+ EXPECT_EQ(Error::BAD_BUFFER, tmpError)
+ << "importBuffer with nullptr did not fail with BAD_BUFFER";
+ });
+
+ invalidHandle = native_handle_create(0, 0);
+ mGralloc->getMapper()->importBuffer(invalidHandle, [&](const auto& tmpError,
+ const auto&) {
+ EXPECT_EQ(Error::BAD_BUFFER, tmpError)
+ << "importBuffer with invalid handle did not fail with BAD_BUFFER";
+ });
+ native_handle_delete(invalidHandle);
+
+ const native_handle_t* importedHandle;
+ ASSERT_NO_FATAL_FAILURE(importedHandle =
+ mGralloc->allocate(mDummyDescriptorInfo, true));
+ mGralloc->getMapper()->importBuffer(
+ importedHandle, [&](const auto& tmpError, const auto&) {
+ EXPECT_EQ(Error::BAD_BUFFER, tmpError)
+ << "importBuffer with an "
+ "already imported handle did "
+ "not fail with BAD_BUFFER";
+ });
+ mGralloc->freeBuffer(importedHandle);
+}
+
+/**
+ * Test IMapper::freeBuffer with invalid buffers.
+ */
+TEST_F(GraphicsMapperHidlTest, FreeBufferNegative) {
+ native_handle_t* invalidHandle = nullptr;
+ Error error = mGralloc->getMapper()->freeBuffer(invalidHandle);
+ EXPECT_EQ(Error::BAD_BUFFER, error)
+ << "freeBuffer with nullptr did not fail with BAD_BUFFER";
+
+ invalidHandle = native_handle_create(0, 0);
+ error = mGralloc->getMapper()->freeBuffer(invalidHandle);
+ EXPECT_EQ(Error::BAD_BUFFER, error)
+ << "freeBuffer with invalid handle did not fail with BAD_BUFFER";
+ native_handle_delete(invalidHandle);
+
+ const native_handle_t* clonedBufferHandle;
+ ASSERT_NO_FATAL_FAILURE(
+ clonedBufferHandle = mGralloc->allocate(mDummyDescriptorInfo, false));
+ error = mGralloc->getMapper()->freeBuffer(invalidHandle);
+ EXPECT_EQ(Error::BAD_BUFFER, error)
+ << "freeBuffer with un-imported handle did not fail with BAD_BUFFER";
+
+ mGralloc->freeBuffer(clonedBufferHandle);
}
/**
* Test IMapper::lock and IMapper::unlock.
*/
-TEST_F(GraphicsMapperHidlTest, LockBasic) {
- const auto& info = mDummyDescriptorInfo;
+TEST_F(GraphicsMapperHidlTest, LockUnlockBasic) {
+ const auto& info = mDummyDescriptorInfo;
- const native_handle_t* buffer;
- ASSERT_NO_FATAL_FAILURE(
- buffer = mMapper->allocate(mAllocatorClient, mDummyDescriptorInfo));
+ const native_handle_t* bufferHandle;
+ uint32_t stride;
+ ASSERT_NO_FATAL_FAILURE(bufferHandle =
+ mGralloc->allocate(info, true, &stride));
- uint32_t stride;
- ASSERT_NO_FATAL_FAILURE(stride = mMapper->getStride(buffer));
+ // lock buffer for writing
+ const IMapper::Rect region{0, 0, static_cast<int32_t>(info.width),
+ static_cast<int32_t>(info.height)};
+ int fence = -1;
+ uint8_t* data;
+ ASSERT_NO_FATAL_FAILURE(data = static_cast<uint8_t*>(mGralloc->lock(
+ bufferHandle, info.usage, region, fence)));
- // lock buffer for writing
- const IMapper::Rect region{0, 0, static_cast<int32_t>(info.width),
- static_cast<int32_t>(info.height)};
- int fence = -1;
- uint32_t* data;
- ASSERT_NO_FATAL_FAILURE(
- data = static_cast<uint32_t*>(
- mMapper->lock(buffer, info.producerUsageMask, 0, region, fence)));
+ // RGBA_8888
+ size_t strideInBytes = stride * 4;
+ size_t writeInBytes = info.width * 4;
- for (uint32_t y = 0; y < info.height; y++) {
- for (uint32_t x = 0; x < info.width; x++) {
- data[stride * y + x] = info.height * y + x;
+ for (uint32_t y = 0; y < info.height; y++) {
+ memset(data, y, writeInBytes);
+ data += strideInBytes;
}
- }
- ASSERT_NO_FATAL_FAILURE(fence = mMapper->unlock(buffer));
+ ASSERT_NO_FATAL_FAILURE(fence = mGralloc->unlock(bufferHandle));
- // lock buffer for reading
- ASSERT_NO_FATAL_FAILURE(
- data = static_cast<uint32_t*>(
- mMapper->lock(buffer, 0, info.consumerUsageMask, region, fence)));
- for (uint32_t y = 0; y < info.height; y++) {
- for (uint32_t x = 0; x < info.width; x++) {
- EXPECT_EQ(info.height * y + x, data[stride * y + x]);
+ // lock again for reading
+ ASSERT_NO_FATAL_FAILURE(data = static_cast<uint8_t*>(mGralloc->lock(
+ bufferHandle, info.usage, region, fence)));
+ for (uint32_t y = 0; y < info.height; y++) {
+ for (size_t i = 0; i < writeInBytes; i++) {
+ EXPECT_EQ(static_cast<uint8_t>(y), data[i]);
+ }
+ data += strideInBytes;
}
- }
- ASSERT_NO_FATAL_FAILURE(fence = mMapper->unlock(buffer));
- if (fence >= 0) {
- close(fence);
- }
+ ASSERT_NO_FATAL_FAILURE(fence = mGralloc->unlock(bufferHandle));
+ if (fence >= 0) {
+ close(fence);
+ }
}
/**
- * Test IMapper::lockFlex. This locks a YV12 buffer, and makes sure we can
+ * Test IMapper::lockYCbCr. This locks a YV12 buffer, and makes sure we can
* write to and read from it.
*/
-TEST_F(GraphicsMapperHidlTest, LockFlexBasic) {
- auto info = mDummyDescriptorInfo;
- info.format = PixelFormat::YV12;
+TEST_F(GraphicsMapperHidlTest, LockYCbCrBasic) {
+ auto info = mDummyDescriptorInfo;
+ info.format = PixelFormat::YV12;
- const native_handle_t* buffer;
- ASSERT_NO_FATAL_FAILURE(buffer = mMapper->allocate(mAllocatorClient, info));
+ const native_handle_t* bufferHandle;
+ uint32_t stride;
+ ASSERT_NO_FATAL_FAILURE(bufferHandle =
+ mGralloc->allocate(info, true, &stride));
- // lock buffer for writing
- const IMapper::Rect region{0, 0, static_cast<int32_t>(info.width),
- static_cast<int32_t>(info.height)};
- int fence = -1;
- FlexLayout layout;
- ASSERT_NO_FATAL_FAILURE(
- layout =
- mMapper->lockFlex(buffer, info.producerUsageMask, 0, region, fence));
- ASSERT_EQ(FlexFormat::YCBCR, layout.format);
- ASSERT_EQ(3u, layout.planes.size());
+ // lock buffer for writing
+ const IMapper::Rect region{0, 0, static_cast<int32_t>(info.width),
+ static_cast<int32_t>(info.height)};
+ int fence = -1;
+ YCbCrLayout layout;
+ ASSERT_NO_FATAL_FAILURE(
+ layout = mGralloc->lockYCbCr(bufferHandle, info.usage, region, fence));
- const auto y_stride = layout.planes[0].vIncrement;
- const auto c_stride = layout.planes[1].vIncrement;
- auto y_data = static_cast<uint8_t*>(layout.planes[0].topLeft);
- auto cb_data = static_cast<uint8_t*>(layout.planes[1].topLeft);
- auto cr_data = static_cast<uint8_t*>(layout.planes[2].topLeft);
+ auto yData = static_cast<uint8_t*>(layout.y);
+ auto cbData = static_cast<uint8_t*>(layout.cb);
+ auto crData = static_cast<uint8_t*>(layout.cr);
+ for (uint32_t y = 0; y < info.height; y++) {
+ for (uint32_t x = 0; x < info.width; x++) {
+ auto val = static_cast<uint8_t>(info.height * y + x);
- for (uint32_t y = 0; y < info.height; y++) {
- for (uint32_t x = 0; x < info.width; x++) {
- auto val = static_cast<uint8_t>(info.height * y + x);
-
- y_data[y_stride * y + x] = val;
- if (y % 2 == 0 && x % 2 == 0) {
- cb_data[c_stride * y / 2 + x / 2] = val;
- cr_data[c_stride * y / 2 + x / 2] = val;
- }
+ yData[layout.yStride * y + x] = val;
+ if (y % 2 == 0 && x % 2 == 0) {
+ cbData[layout.cStride * y / 2 + x / 2] = val;
+ crData[layout.cStride * y / 2 + x / 2] = val;
+ }
+ }
}
- }
- ASSERT_NO_FATAL_FAILURE(fence = mMapper->unlock(buffer));
+ ASSERT_NO_FATAL_FAILURE(fence = mGralloc->unlock(bufferHandle));
- // lock buffer for reading
- ASSERT_NO_FATAL_FAILURE(
- layout =
- mMapper->lockFlex(buffer, 0, info.consumerUsageMask, region, fence));
+ // lock again for reading
+ ASSERT_NO_FATAL_FAILURE(
+ layout = mGralloc->lockYCbCr(bufferHandle, info.usage, region, fence));
- y_data = static_cast<uint8_t*>(layout.planes[0].topLeft);
- cb_data = static_cast<uint8_t*>(layout.planes[1].topLeft);
- cr_data = static_cast<uint8_t*>(layout.planes[2].topLeft);
- for (uint32_t y = 0; y < info.height; y++) {
- for (uint32_t x = 0; x < info.width; x++) {
- auto val = static_cast<uint8_t>(info.height * y + x);
+ yData = static_cast<uint8_t*>(layout.y);
+ cbData = static_cast<uint8_t*>(layout.cb);
+ crData = static_cast<uint8_t*>(layout.cr);
+ for (uint32_t y = 0; y < info.height; y++) {
+ for (uint32_t x = 0; x < info.width; x++) {
+ auto val = static_cast<uint8_t>(info.height * y + x);
- EXPECT_EQ(val, y_data[y_stride * y + x]);
- if (y % 2 == 0 && x % 2 == 0) {
- EXPECT_EQ(val, cb_data[c_stride * y / 2 + x / 2]);
- EXPECT_EQ(val, cr_data[c_stride * y / 2 + x / 2]);
- }
+ EXPECT_EQ(val, yData[layout.yStride * y + x]);
+ if (y % 2 == 0 && x % 2 == 0) {
+ EXPECT_EQ(val, cbData[layout.cStride * y / 2 + x / 2]);
+ EXPECT_EQ(val, crData[layout.cStride * y / 2 + x / 2]);
+ }
+ }
}
- }
- ASSERT_NO_FATAL_FAILURE(fence = mMapper->unlock(buffer));
- if (fence >= 0) {
- close(fence);
- }
+ ASSERT_NO_FATAL_FAILURE(fence = mGralloc->unlock(bufferHandle));
+ if (fence >= 0) {
+ close(fence);
+ }
}
-} // namespace anonymous
+/**
+ * Test IMapper::unlock with invalid buffers.
+ */
+TEST_F(GraphicsMapperHidlTest, UnlockNegative) {
+ native_handle_t* invalidHandle = nullptr;
+ mGralloc->getMapper()->unlock(
+ invalidHandle, [&](const auto& tmpError, const auto&) {
+ EXPECT_EQ(Error::BAD_BUFFER, tmpError)
+ << "unlock with nullptr did not fail with BAD_BUFFER";
+ });
+
+ invalidHandle = native_handle_create(0, 0);
+ mGralloc->getMapper()->unlock(
+ invalidHandle, [&](const auto& tmpError, const auto&) {
+ EXPECT_EQ(Error::BAD_BUFFER, tmpError)
+ << "unlock with invalid handle did not fail with BAD_BUFFER";
+ });
+ native_handle_delete(invalidHandle);
+
+ ASSERT_NO_FATAL_FAILURE(invalidHandle =
+ const_cast<native_handle_t*>(mGralloc->allocate(
+ mDummyDescriptorInfo, false)));
+ mGralloc->getMapper()->unlock(invalidHandle, [&](const auto& tmpError,
+ const auto&) {
+ EXPECT_EQ(Error::BAD_BUFFER, tmpError)
+ << "unlock with un-imported handle did not fail with BAD_BUFFER";
+ });
+ mGralloc->freeBuffer(invalidHandle);
+
+// disabled as it fails on many existing drivers
+#if 0
+ ASSERT_NO_FATAL_FAILURE(invalidHandle = const_cast<native_handle_t*>(
+ mGralloc->allocate(mDummyDescriptorInfo, true)));
+ mGralloc->getMapper()->unlock(
+ invalidHandle, [&](const auto& tmpError, const auto&) {
+ EXPECT_EQ(Error::BAD_BUFFER, tmpError)
+ << "unlock with unlocked handle did not fail with BAD_BUFFER";
+ });
+ mGralloc->freeBuffer(invalidHandle);
+#endif
+}
+
+} // namespace
} // namespace tests
} // namespace V2_0
} // namespace mapper
diff --git a/media/1.0/types.hal b/media/1.0/types.hal
index 1f9c4dc..bb1a73b 100644
--- a/media/1.0/types.hal
+++ b/media/1.0/types.hal
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016 The Android Open Source Project
+ * Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/media/omx/1.0/Android.bp b/media/omx/1.0/Android.bp
index c6e0389..bfd46c2 100644
--- a/media/omx/1.0/Android.bp
+++ b/media/omx/1.0/Android.bp
@@ -9,6 +9,7 @@
"IOmxBufferSource.hal",
"IOmxNode.hal",
"IOmxObserver.hal",
+ "IOmxStore.hal",
],
}
@@ -26,6 +27,7 @@
"android/hardware/media/omx/1.0/OmxBufferSourceAll.cpp",
"android/hardware/media/omx/1.0/OmxNodeAll.cpp",
"android/hardware/media/omx/1.0/OmxObserverAll.cpp",
+ "android/hardware/media/omx/1.0/OmxStoreAll.cpp",
],
}
@@ -64,6 +66,11 @@
"android/hardware/media/omx/1.0/BnHwOmxObserver.h",
"android/hardware/media/omx/1.0/BpHwOmxObserver.h",
"android/hardware/media/omx/1.0/BsOmxObserver.h",
+ "android/hardware/media/omx/1.0/IOmxStore.h",
+ "android/hardware/media/omx/1.0/IHwOmxStore.h",
+ "android/hardware/media/omx/1.0/BnHwOmxStore.h",
+ "android/hardware/media/omx/1.0/BpHwOmxStore.h",
+ "android/hardware/media/omx/1.0/BsOmxStore.h",
],
}
diff --git a/media/omx/1.0/IOmx.hal b/media/omx/1.0/IOmx.hal
index 78d4b32..f5fc449 100644
--- a/media/omx/1.0/IOmx.hal
+++ b/media/omx/1.0/IOmx.hal
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016 The Android Open Source Project
+ * Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,7 +26,7 @@
/**
* Ref: frameworks/av/include/media/IOMX.h: IOMX
*
- * IOmx is the main entry point for communicating with OMX components.
+ * IOmx has the ability to create OMX nodes.
*/
interface IOmx {
@@ -41,8 +41,8 @@
/**
* List available components.
*
- * @param[out] status The status of the call.
- * @param[out] nodeList The list of ComponentInfo.
+ * @return status The status of the call.
+ * @return nodeList The list of ComponentInfo.
*/
listNodes(
) generates (
@@ -50,14 +50,15 @@
vec<ComponentInfo> nodeList
);
+
/**
- * Allocate an IOmxNode instance with the specified component name.
+ * Allocate an IOmxNode instance with the specified node name.
*
- * @param[in] name The name of the component to create.
- * @param[in] observer An observer object that will receive messages from
+ * @param name The name of the node to create.
+ * @param observer An observer object that will receive messages from
* the created instance.
- * @param[out] status The status of the call.
- * @param[out] omxNode The allocated instance of IOmxNode.
+ * @return status The status of the call.
+ * @return omxNode The allocated instance of `IOmxNode`.
*/
allocateNode(
string name,
@@ -70,8 +71,9 @@
/**
* Create an input surface for recording.
*
- * @param[out] producer The associated producer end of the buffer queue.
- * @param[out] source The associated `IGraphicBufferSource`.
+ * @return status The status of the call.
+ * @return producer The associated producer end of the buffer queue.
+ * @return source The associated `IGraphicBufferSource`.
*/
createInputSurface(
) generates (
diff --git a/media/omx/1.0/IOmxNode.hal b/media/omx/1.0/IOmxNode.hal
index 8729637..71c0da3 100644
--- a/media/omx/1.0/IOmxNode.hal
+++ b/media/omx/1.0/IOmxNode.hal
@@ -35,7 +35,7 @@
/**
* Free the node.
*
- * @param[out] status Status of the call.
+ * @return status Status of the call.
*/
freeNode(
) generates (
@@ -45,9 +45,9 @@
/**
* Invoke a command on the node.
*
- * @param[in] cmd Type of the command.
- * @param[in] param Parameter for the command.
- * @param[out] status Status of the call.
+ * @param cmd Type of the command.
+ * @param param Parameter for the command.
+ * @return status Status of the call.
*
* @see OMX_SendCommand() in the OpenMax IL standard.
*/
@@ -61,10 +61,10 @@
/**
* Retrieve a parameter setting from the node.
*
- * @param[in] index Type of the parameter to retrieve.
- * @param[in] inParams Information about the retrieval.
- * @param[out] status Status of the call.
- * @param[out] outParams Current parameter setting.
+ * @param index Type of the parameter to retrieve.
+ * @param inParams Information about the retrieval.
+ * @return status Status of the call.
+ * @return outParams Current parameter setting.
*
* @see OMX_GetParameter() in the OpenMax IL standard.
*/
@@ -79,9 +79,9 @@
/**
* Change a parameter setting of the node.
*
- * @param[in] index Type of the parameter to change.
- * @param[in] params New parameter setting.
- * @param[out] status Status of the call.
+ * @param index Type of the parameter to change.
+ * @param params New parameter setting.
+ * @return status Status of the call.
*
* @see OMX_SetParameter() in the OpenMax IL standard.
*/
@@ -95,10 +95,10 @@
/**
* Retrieve a configuration from the node.
*
- * @param[in] index Type of the configuration to retrieve.
- * @param[in] inConfig Information about the retrieval.
- * @param[out] status Status of the call.
- * @param[out] outConfig Current configuration.
+ * @param index Type of the configuration to retrieve.
+ * @param inConfig Information about the retrieval.
+ * @return status Status of the call.
+ * @return outConfig Current configuration.
*
* @see OMX_GetConfig() in the OpenMax IL standard.
*/
@@ -113,9 +113,9 @@
/**
* Change a configuration of the node.
*
- * @param[in] index Type of the configuration to change.
- * @param[in] config New configuration.
- * @param[out] status Status of the call.
+ * @param index Type of the configuration to change.
+ * @param config New configuration.
+ * @return status Status of the call.
*
* @see OMX_SetConfig() in the OpenMax IL standard.
*/
@@ -129,9 +129,9 @@
/**
* Set the mode of a port on the node.
*
- * @param[in] portIndex Index of the port.
- * @param[in] mode Target mode on the specified port.
- * @param[out] status Status of the call.
+ * @param portIndex Index of the port.
+ * @param mode Target mode on the specified port.
+ * @return status Status of the call.
*/
setPortMode(
uint32_t portIndex,
@@ -144,11 +144,11 @@
* Prepare a port for adaptive playback. This is based on the extension
* "OMX.google.android.index.prepareForAdaptivePlayback".
*
- * @param[in] portIndex Index of the port.
- * @param[in] enable Whether the adaptive playback is enabled or not.
- * @param[in] maxFrameWidth Maximum frame width.
- * @param[in] maxFrameHeight Maximum frame height.
- * @param[out] status Status of the call.
+ * @param portIndex Index of the port.
+ * @param enable Whether the adaptive playback is enabled or not.
+ * @param maxFrameWidth Maximum frame width.
+ * @param maxFrameHeight Maximum frame height.
+ * @return status Status of the call.
*/
prepareForAdaptivePlayback(
uint32_t portIndex,
@@ -163,12 +163,12 @@
* Configure a port for a tunneled playback mode. This is based on the
* extension "OMX.google.android.index.configureVideoTunnelMode".
*
- * @param[in] portIndex Index of the port.
- * @param[in] tunneled Whether the tunneled mode is used or not.
- * @param[in] audioHwSync HW SYNC ID of the audio HAL output stream to sync
+ * @param portIndex Index of the port.
+ * @param tunneled Whether the tunneled mode is used or not.
+ * @param audioHwSync HW SYNC ID of the audio HAL output stream to sync
* the video with.
- * @param[out] status Status of the call.
- * @param[out] sidebandHandle Codec-allocated sideband window handle.
+ * @return status Status of the call.
+ * @return sidebandHandle Codec-allocated sideband window handle.
*/
configureVideoTunnelMode(
uint32_t portIndex,
@@ -183,9 +183,9 @@
* Retrieve the buffer usage on a port. This is based on the extension
* "OMX.google.android.index.getAndroidNativeBufferUsage".
*
- * @param[in] portIndex Index of the port.
- * @param[out] status Status of the call.
- * @param[out] usage Current graphic buffer usage.
+ * @param portIndex Index of the port.
+ * @return status Status of the call.
+ * @return usage Current graphic buffer usage.
*/
getGraphicBufferUsage(
uint32_t portIndex
@@ -197,9 +197,9 @@
/**
* Set up a listener to events related to the input surface.
*
- * @param[in] bufferSource Listener object that implements
+ * @param bufferSource Listener object that implements
* IOmxBufferSource.
- * @param[out] status Status of the call.
+ * @return status Status of the call.
*
* @see IOmxBufferSource.
*/
@@ -212,12 +212,12 @@
/**
* Allocate an opaque buffer on a port as a native handle.
*
- * @param[in] portIndex Index of the port.
- * @param[in] size Desired size of the buffer.
- * @param[out] status Status of the call.
- * @param[out] buffer Id of the allocated buffer, which will be needed in
+ * @param portIndex Index of the port.
+ * @param size Desired size of the buffer.
+ * @return status Status of the call.
+ * @return buffer Id of the allocated buffer, which will be needed in
* other buffer-related functions.
- * @param[out] nativeHandle Native handle of the allocated buffer.
+ * @return nativeHandle Native handle of the allocated buffer.
*
* @see OMX_AllocateBuffer() in the OpenMax IL standard.
*/
@@ -233,10 +233,10 @@
/**
* Assign a buffer to a port.
*
- * @param[in] portIndex Index of the port.
- * @param[in] omxBuffer Buffer to be assigned to the port.
- * @param[out] status Status of the call.
- * @param[out] buffer Id of the assigned buffer, which will be needed in
+ * @param portIndex Index of the port.
+ * @param omxBuffer Buffer to be assigned to the port.
+ * @return status Status of the call.
+ * @return buffer Id of the assigned buffer, which will be needed in
* other buffer-related functions.
*
* @see OMX_UseBuffer() in the OpenMax IL standard.
@@ -253,9 +253,9 @@
* Free a buffer previously assigned to a port by allocateSecureBuffer() or
* useBuffer().
*
- * @param[in] portIndex Index of the port.
- * @param[in] buffer Id of the buffer to be freed.
- * @param[out] status Status of the call.
+ * @param portIndex Index of the port.
+ * @param buffer Id of the buffer to be freed.
+ * @return status Status of the call.
*
* @see OMX_FreeBuffer() in the OpenMax IL standard.
*/
@@ -275,10 +275,10 @@
* the new buffer passed in via \p omxBuffer before OMX_FillThisBuffer() is
* called. Otherwise, \p omxBuffer is not used.
*
- * @param[in] buffer Id of the buffer to fill.
- * @param[in] omxBuffer New buffer information (in metadata mode).
- * @param[in] fence Fence to wait for (if not null).
- * @param[out] status Status of the call.
+ * @param buffer Id of the buffer to fill.
+ * @param omxBuffer New buffer information (in metadata mode).
+ * @param fence Fence to wait for (if not null).
+ * @return status Status of the call.
*
* @see OMX_FillThisBuffer() in the OpenMax IL standard.
*/
@@ -299,12 +299,12 @@
* the new buffer passed in via \p omxBuffer before OMX_EmptyThisBuffer() is
* called. Otherwise, \p omxBuffer is not used.
*
- * @param[in] buffer Id of the buffer to fill.
- * @param[in] omxBuffer New buffer information (in metadata mode).
- * @param[in] flags Flags to be passed to OMX_EmptyBuffer().
- * @param[in] timestampUs Timestamp OMX_EmptyBuffer().
- * @param[in] fence Fence to wait for (if not null).
- * @param[out] status Status of the call.
+ * @param buffer Id of the buffer to fill.
+ * @param omxBuffer New buffer information (in metadata mode).
+ * @param flags Flags to be passed to OMX_EmptyBuffer().
+ * @param timestampUs Timestamp OMX_EmptyBuffer().
+ * @param fence Fence to wait for (if not null).
+ * @return status Status of the call.
*
* @see OMX_EmptyThisBuffer() in the OpenMax IL standard.
*/
@@ -321,9 +321,9 @@
/**
* Request the node to translate an extension string to an index.
*
- * @param[in] parameterName Requested extension string.
- * @param[out] status Status of the call.
- * @param[out] index Translated index.
+ * @param parameterName Requested extension string.
+ * @return status Status of the call.
+ * @return index Translated index.
*
* @see OMX_GetExtensionIndex() in the OpenMax IL standard.
*/
@@ -340,8 +340,8 @@
* receive the message in batches by the callback
* IOmxObserver::onMessages().
*
- * @param[in] msg Message to send.
- * @param[out] status Status of the call.
+ * @param msg Message to send.
+ * @return status Status of the call.
*
* @see IOmxObserver::onMessages().
*/
@@ -350,16 +350,5 @@
) generates (
Status status
);
-
- /**
- * Set quirks.
- *
- * @param[in] quirks Quirks for the component, generally obtained from
- * MediaCodecList::getQuirksFor().
- */
- oneway setQuirks(
- uint32_t quirks
- );
-
};
diff --git a/media/omx/1.0/IOmxStore.hal b/media/omx/1.0/IOmxStore.hal
new file mode 100644
index 0000000..a224b0e
--- /dev/null
+++ b/media/omx/1.0/IOmxStore.hal
@@ -0,0 +1,215 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.omx@1.0;
+
+import IOmx;
+
+/**
+ * Ref: frameworks/av/include/media/IOMX.h: IOMX
+ *
+ * There will be two instances of IOmxStore: "platform" and "vendor".
+ *
+ * The IOmxStore service provided by the platform must present "platform" as the
+ * interface name.
+ *
+ * The IOmxStore service provided by the vendor must present "vendor" as the
+ * instance name.
+ */
+interface IOmxStore {
+
+ /**
+ * Attribute is a key-value pair of strings. The `value` member is generally
+ * a stringified value of the following:
+ * enum<v1,v2,...,vn>: v1 | v2 | ... | vn
+ * num: 0 | [1-9][0-9]*
+ * string: arbitrary string
+ * size: <num>x<num>
+ * ratio: <num>:<num>
+ * range<type>: <type>-<type>
+ * list<type>: <type> | <type>,<list<type>>
+ */
+ struct Attribute {
+ string key;
+ string value;
+ };
+
+ /**
+ * Service attribute
+ *
+ * Optional service attributes:
+ * key: 'max-video-encoder-input-buffers', value-type: num
+ * key: 'supports-multiple-secure-codecs', value-type: enum<0,1>
+ * key: 'supports-secure-with-non-secure-codec', value-type: enum<0,1>
+ *
+ * For keys with prefix 'supports-', the value of 0 means "no" (not
+ * supported) while the value of 1 means "yes" (supported).
+ */
+ typedef Attribute ServiceAttribute;
+
+ /**
+ * List attributes that are service-specific (not node-specific).
+ *
+ * @return attributes The list of `Attribute`s that are specific to this
+ * service.
+ */
+ listServiceAttributes(
+ ) generates (
+ Status status,
+ vec<ServiceAttribute> attributes
+ );
+
+ /**
+ * Node attribute
+ *
+ * Optional node attributes to describe supported values:
+ * key: 'bitrate-range', value-type: range<num>
+ * key: 'max-concurrent-instances', value-type: num
+ * key: 'max-supported-instances', value-type: num
+ *
+ * Optional node attributes for audio nodes to describe supported values:
+ * key: 'max-channel-count', value-type: num
+ * key: 'sample-rate-ranges', value-type: list<range<num>>
+ *
+ * Optional node attributes for video nodes to describe supported values:
+ * key: 'alignment', value-type: size
+ * key: 'block-aspect-ratio-range', value-type: range<ratio>
+ * key: 'block-count-range', value-type: range<num>
+ * key: 'block-size', value-type: size
+ * key: 'blocks-per-second-range', value-type: range<num>
+ * key: 'feature-can-swap-width-height', value-type: enum<0,1>
+ * key: 'frame-rate-range', value-type: range<num>
+ * key: 'pixel-aspect-ratio-range', value-type: range<ratio>
+ * key: 'size-range', value-type: range<size>
+ *
+ * Required node attributes for video nodes that are required by Android to
+ * describe measured values for this device:
+ * key: 'measured-frame-rate-<width>-<height>-range',
+ * value-type: range<num>; where width: num, height: num
+ *
+ * Optional node attributes for decoders to describe supported values:
+ * key: 'feature-adaptive-playback', value: enum<0,1>
+ * key: 'feature-secure-playback', value: enum<0,1>
+ * key: 'feature-tunneled-playback', value: enum<0,1>
+ *
+ * Optional node attributes for video decoders to describe supported values:
+ * key: 'feature-partial-frame', value: enum<0,1>
+ *
+ * Optional node attributes for encoders to describe supported values:
+ * key: 'complexity-default', value-type: num
+ * key: 'complexity-range', value-type: range<num>
+ * key: 'feature-bitrate-control', value-type: list<enum<VBR,CBR,CQ>>
+ * key: 'feature-intra-refresh', value-type: enum<0,1>
+ * key: 'quality-default', value-type: num
+ * key: 'quality-range', value-type: range<num>
+ * key: 'quality-scale', value-type: string
+ *
+ * For keys with prefix 'feature-' and value type enum<0,1>, the value of 0
+ * means "optional", while the value of 1 means "required".
+ */
+ typedef Attribute NodeAttribute;
+
+ /**
+ * Information for an IOmxNode node.
+ */
+ struct NodeInfo {
+ /**
+ * Name of this node.
+ *
+ * `name` can be supplied to `IOmx::allocateNode` of a
+ * corresponding `IOmx` instance to create the node.
+ */
+ string name;
+ /**
+ * Name of the `IOmx` instance that can create this node.
+ *
+ * To obtain the `IOmx` instance, call `getOmx(owner)`.
+ */
+ string owner;
+ /**
+ * List of node attributes.
+ */
+ vec<NodeAttribute> attributes;
+ };
+
+ /**
+ * Information about nodes provided for a supported node role
+ */
+ struct RoleInfo {
+ /**
+ * Standard OMX node role.
+ */
+ string role;
+ /**
+ * Corresponding media type (as defined in MediaFormat.MIMETYPE_*
+ * constants for types required by Android).
+ */
+ string type;
+ /**
+ * Whether this role is for an encoder or a decoder.
+ */
+ bool isEncoder;
+ /**
+ * Whether to prefer platform nodes for this role.
+ */
+ bool preferPlatformNodes;
+ /**
+ * List of nodes that support this role, ordered by preference.
+ */
+ vec<NodeInfo> nodes;
+ };
+
+ /**
+ * Return the prefix of names of supported nodes.
+ *
+ * @return prefix The prefix of the names of all nodes supported by this
+ * service.
+ */
+ getNodePrefix(
+ ) generates (
+ string prefix
+ );
+
+ /**
+ * List roles of supported nodes.
+ *
+ * The name of each node inside `NodeInfo` must start with the prefix
+ * returned by `getNodePrefix()`.
+ *
+ * @return roleList The list of `RoleInfo`s.
+ *
+ * @see RoleInfo
+ */
+ listRoles(
+ ) generates (
+ vec<RoleInfo> roleList
+ );
+
+ /**
+ * Obtain an `IOmx` instance with a specified name.
+ *
+ * @param name The name of the instance.
+ * @return omx The `IOmx` interface associated with `name`. This must be
+ * null if the name is not found.
+ */
+ getOmx(
+ string name
+ ) generates (
+ IOmx omx
+ );
+
+};
+
diff --git a/media/omx/1.0/types.hal b/media/omx/1.0/types.hal
index 5413344..76a6007 100644
--- a/media/omx/1.0/types.hal
+++ b/media/omx/1.0/types.hal
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016 The Android Open Source Project
+ * Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -35,6 +35,7 @@
NAME_NOT_FOUND = -2,
WOULD_BLOCK = -11,
NO_MEMORY = -12,
+ ALREADY_EXISTS = -17,
NO_INIT = -19,
BAD_VALUE = -22,
DEAD_OBJECT = -32,
diff --git a/power/1.0/default/Power.cpp b/power/1.0/default/Power.cpp
index 6ea9167..51f87f5 100644
--- a/power/1.0/default/Power.cpp
+++ b/power/1.0/default/Power.cpp
@@ -145,25 +145,27 @@
}
IPower* HIDL_FETCH_IPower(const char* /* name */) {
- int ret = 0;
- const hw_module_t* hw_module = NULL;
- power_module_t *power_module;
- ret = hw_get_module(POWER_HARDWARE_MODULE_ID, &hw_module);
- if (ret == 0 && hw_module->methods->open) {
- ret = hw_module->methods->open(hw_module, POWER_HARDWARE_MODULE_ID,
- reinterpret_cast<hw_device_t**>(&power_module));
- if (ret == 0) {
- return new Power(power_module);
- }
- else {
- ALOGE("Passthrough failed to load legacy power HAL.");
+ const hw_module_t* hw_module = nullptr;
+ power_module_t* power_module = nullptr;
+ int err = hw_get_module(POWER_HARDWARE_MODULE_ID, &hw_module);
+ if (err) {
+ ALOGE("hw_get_module %s failed: %d", POWER_HARDWARE_MODULE_ID, err);
+ return nullptr;
+ }
+
+ if (!hw_module->methods || !hw_module->methods->open) {
+ power_module = reinterpret_cast<power_module_t*>(
+ const_cast<hw_module_t*>(hw_module));
+ } else {
+ err = hw_module->methods->open(
+ hw_module, POWER_HARDWARE_MODULE_ID,
+ reinterpret_cast<hw_device_t**>(&power_module));
+ if (err) {
+ ALOGE("Passthrough failed to load legacy HAL.");
return nullptr;
}
}
- else {
- ALOGE ("hw_get_module %s failed: %d", POWER_HARDWARE_MODULE_ID, ret);
- return nullptr;
- }
+ return new Power(power_module);
}
} // namespace implementation
diff --git a/radio/1.0/vts/functional/radio_hidl_hal_test.cpp b/radio/1.0/vts/functional/radio_hidl_hal_test.cpp
index 9094f39..d40f15a 100644
--- a/radio/1.0/vts/functional/radio_hidl_hal_test.cpp
+++ b/radio/1.0/vts/functional/radio_hidl_hal_test.cpp
@@ -18,7 +18,7 @@
void RadioHidlTest::SetUp() {
radio = ::testing::VtsHalHidlTargetTestBase::getService<IRadio>(
- hidl_string("rild"));
+ hidl_string(RADIO_SERVICE_NAME));
ASSERT_NE(radio, nullptr);
radioRsp = new RadioResponse(*this);
diff --git a/radio/1.0/vts/functional/radio_hidl_hal_utils.h b/radio/1.0/vts/functional/radio_hidl_hal_utils.h
index 6826238..51db87b 100644
--- a/radio/1.0/vts/functional/radio_hidl_hal_utils.h
+++ b/radio/1.0/vts/functional/radio_hidl_hal_utils.h
@@ -81,6 +81,7 @@
using ::android::sp;
#define TIMEOUT_PERIOD 40
+#define RADIO_SERVICE_NAME "slot1"
class RadioHidlTest;
extern CardStatus cardStatus;
diff --git a/radio/1.0/vts/functional/sap_hidl_hal_test.cpp b/radio/1.0/vts/functional/sap_hidl_hal_test.cpp
index 88274cd..02accef 100644
--- a/radio/1.0/vts/functional/sap_hidl_hal_test.cpp
+++ b/radio/1.0/vts/functional/sap_hidl_hal_test.cpp
@@ -18,7 +18,7 @@
void SapHidlTest::SetUp() {
sap = ::testing::VtsHalHidlTargetTestBase::getService<ISap>(
- hidl_string("sap_uim_socket1"));
+ hidl_string(SAP_SERVICE_NAME));
ASSERT_NE(sap, nullptr);
sapCb = new SapCallback(*this);
diff --git a/radio/1.0/vts/functional/sap_hidl_hal_utils.h b/radio/1.0/vts/functional/sap_hidl_hal_utils.h
index 2ee3c96..38fb003 100644
--- a/radio/1.0/vts/functional/sap_hidl_hal_utils.h
+++ b/radio/1.0/vts/functional/sap_hidl_hal_utils.h
@@ -34,6 +34,7 @@
using ::android::sp;
#define TIMEOUT_PERIOD 40
+#define SAP_SERVICE_NAME "slot1"
class SapHidlTest;
diff --git a/renderscript/1.0/vts/functional/VtsCopyTests.cpp b/renderscript/1.0/vts/functional/VtsCopyTests.cpp
index 168e681..f47253f 100644
--- a/renderscript/1.0/vts/functional/VtsCopyTests.cpp
+++ b/renderscript/1.0/vts/functional/VtsCopyTests.cpp
@@ -30,12 +30,18 @@
TEST_F(RenderscriptHidlTest, Simple1DCopyTest) {
// float1
Element element = context->elementCreate(DataType::FLOAT_32, DataKind::USER, false, 1);
+ ASSERT_NE(Element(0), element);
+
// 128 x float1
Type type = context->typeCreate(element, 128, 0, 0, false, false, YuvFormat::YUV_NONE);
+ ASSERT_NE(Type(0), type);
+
// 128 x float1
Allocation allocation = context->allocationCreateTyped(type, AllocationMipmapControl::NONE,
(int)AllocationUsageType::SCRIPT,
(Ptr)nullptr);
+ ASSERT_NE(Allocation(0), allocation);
+
std::vector<float> dataIn(128), dataOut(128);
std::generate(dataIn.begin(), dataIn.end(), [](){ static int val = 0; return (float)val++; });
hidl_vec<uint8_t> _data;
@@ -60,12 +66,18 @@
TEST_F(RenderscriptHidlTest, Simple2DCopyTest) {
// float1
Element element = context->elementCreate(DataType::FLOAT_32, DataKind::USER, false, 1);
+ ASSERT_NE(Element(0), element);
+
// 128 x 128 x float1
Type type = context->typeCreate(element, 128, 128, 0, false, false, YuvFormat::YUV_NONE);
+ ASSERT_NE(Type(0), type);
+
// 128 x 128 x float1
Allocation allocation = context->allocationCreateTyped(type, AllocationMipmapControl::NONE,
(int)AllocationUsageType::SCRIPT,
(Ptr)nullptr);
+ ASSERT_NE(Allocation(0), allocation);
+
std::vector<float> dataIn(128*128), dataOut(128*128);
std::generate(dataIn.begin(), dataIn.end(), [](){ static int val = 0; return (float)val++; });
hidl_vec<uint8_t> _data;
@@ -91,12 +103,18 @@
TEST_F(RenderscriptHidlTest, Simple3DCopyTest) {
// float1
Element element = context->elementCreate(DataType::FLOAT_32, DataKind::USER, false, 1);
+ ASSERT_NE(Element(0), element);
+
// 32 x 32 x 32 x float1
Type type = context->typeCreate(element, 32, 32, 32, false, false, YuvFormat::YUV_NONE);
+ ASSERT_NE(Type(0), type);
+
// 32 x 32 x 32 x float1
Allocation allocation = context->allocationCreateTyped(type, AllocationMipmapControl::NONE,
(int)AllocationUsageType::SCRIPT,
(Ptr)nullptr);
+ ASSERT_NE(Allocation(0), allocation);
+
std::vector<float> dataIn(32*32*32), dataOut(32*32*32);
std::generate(dataIn.begin(), dataIn.end(), [](){ static int val = 0; return (float)val++; });
hidl_vec<uint8_t> _data;
@@ -122,8 +140,12 @@
TEST_F(RenderscriptHidlTest, SimpleBitmapTest) {
// float1
Element element = context->elementCreate(DataType::FLOAT_32, DataKind::USER, false, 1);
+ ASSERT_NE(Element(0), element);
+
// 512 x 512 x float1
Type type = context->typeCreate(element, 512, 512, 0, false, false, YuvFormat::YUV_NONE);
+ ASSERT_NE(Type(0), type);
+
std::vector<float> dataIn(512*512), dataOut1(512*512), dataOut2(512*512);
std::generate(dataIn.begin(), dataIn.end(), [](){ static int val = 0; return (float)val++; });
hidl_vec<uint8_t> _data;
@@ -133,7 +155,7 @@
AllocationMipmapControl::NONE,
_data,
(int)AllocationUsageType::SCRIPT);
- EXPECT_NE(Allocation(0), allocation);
+ ASSERT_NE(Allocation(0), allocation);
context->allocationCopyToBitmap(allocation, (Ptr)dataOut1.data(),
(Size)dataOut1.size()*sizeof(float));
@@ -158,10 +180,16 @@
TEST_F(RenderscriptHidlTest, AllocationCopy2DRangeTest) {
// float1
Element element = context->elementCreate(DataType::FLOAT_32, DataKind::USER, false, 1);
+ ASSERT_NE(Element(0), element);
+
// 512 x 512 x float1
Type typeSrc = context->typeCreate(element, 512, 512, 0, false, false, YuvFormat::YUV_NONE);
+ ASSERT_NE(Type(0), typeSrc);
+
// 256 x 256 x float1
Type typeDst = context->typeCreate(element, 256, 256, 0, false, false, YuvFormat::YUV_NONE);
+ ASSERT_NE(Type(0), typeDst);
+
std::vector<float> dataIn(512*512), dataOut(256*256), expected(256*256);
std::generate(dataIn.begin(), dataIn.end(), [](){ static int val = 0; return (float)val++; });
hidl_vec<uint8_t> _data;
@@ -170,10 +198,14 @@
Allocation allocSrc = context->allocationCreateFromBitmap(typeSrc,
AllocationMipmapControl::NONE, _data,
(int)AllocationUsageType::SCRIPT);
+ ASSERT_NE(Allocation(0), allocSrc);
+
// 256 x 256 x float1
Allocation allocDst = context->allocationCreateTyped(typeDst, AllocationMipmapControl::NONE,
(int)AllocationUsageType::SCRIPT,
(Ptr)nullptr);
+ ASSERT_NE(Allocation(0), allocDst);
+
context->allocationCopy2DRange(allocDst, 0, 0, 0, AllocationCubemapFace::POSITIVE_X, 256, 256,
allocSrc, 128, 128, 0, AllocationCubemapFace::POSITIVE_X);
context->allocationRead(allocDst, (Ptr)dataOut.data(), (Size)dataOut.size()*sizeof(float));
@@ -200,10 +232,16 @@
TEST_F(RenderscriptHidlTest, AllocationCopy3DRangeTest) {
// float1
Element element = context->elementCreate(DataType::FLOAT_32, DataKind::USER, false, 1);
+ ASSERT_NE(Element(0), element);
+
// 128 x 128 x 128 x float1
Type typeSrc = context->typeCreate(element, 128, 128, 128, false, false, YuvFormat::YUV_NONE);
+ ASSERT_NE(Type(0), typeSrc);
+
// 64 x 64 x 64 x float1
Type typeDst = context->typeCreate(element, 64, 64, 64, false, false, YuvFormat::YUV_NONE);
+ ASSERT_NE(Type(0), typeDst);
+
std::vector<float> dataIn(128*128*128), dataOut(64*64*64), expected(64*64*64);
std::generate(dataIn.begin(), dataIn.end(), [](){ static int val = 0; return (float)val++; });
hidl_vec<uint8_t> _data;
@@ -212,10 +250,14 @@
Allocation allocSrc = context->allocationCreateTyped(typeSrc, AllocationMipmapControl::NONE,
(int)AllocationUsageType::SCRIPT,
(Ptr)nullptr);
+ ASSERT_NE(Allocation(0), allocSrc);
+
// 256 x 256 x float1
Allocation allocDst = context->allocationCreateTyped(typeDst, AllocationMipmapControl::NONE,
(int)AllocationUsageType::SCRIPT,
(Ptr)nullptr);
+ ASSERT_NE(Allocation(0), allocDst);
+
context->allocation3DWrite(allocSrc, 0, 0, 0, 0, 128, 128, 128, _data, 128*sizeof(float));
context->allocationCopy3DRange(allocDst, 0, 0, 0, 0, 64, 64, 64, allocSrc, 32, 32, 32, 0);
context->allocationRead(allocDst, (Ptr)dataOut.data(), (Size)dataOut.size()*sizeof(float));
@@ -243,8 +285,12 @@
TEST_F(RenderscriptHidlTest, SimpleAdapterTest) {
// float1
Element element = context->elementCreate(DataType::FLOAT_32, DataKind::USER, false, 1);
+ ASSERT_NE(Element(0), element);
+
// 512 x 512 x float1
Type type = context->typeCreate(element, 512, 512, 0, false, false, YuvFormat::YUV_NONE);
+ ASSERT_NE(Type(0), type);
+
std::vector<float> dataIn(512*512), dataOut(256*256), expected;
std::generate(dataIn.begin(), dataIn.end(), [](){ static int val = 0; return (float)val++; });
hidl_vec<uint8_t> _data;
@@ -254,11 +300,15 @@
AllocationMipmapControl::NONE,
_data,
(int)AllocationUsageType::SCRIPT);
+ ASSERT_NE(Allocation(0), allocation);
+
// 256 x 256 x float1
Type subType = context->typeCreate(element, 256, 256, 0, false, false, YuvFormat::YUV_NONE);
+ ASSERT_NE(Type(0), subType);
+
// 256 x 256 x float1
AllocationAdapter allocationAdapter = context->allocationAdapterCreate(subType, allocation);
- EXPECT_NE(AllocationAdapter(0), allocationAdapter);
+ ASSERT_NE(AllocationAdapter(0), allocationAdapter);
std::vector<uint32_t> offsets(9, 0);
offsets[0] = 128;
@@ -292,8 +342,12 @@
TEST_F(RenderscriptHidlTest, SimpleMipmapTest) {
// uint8_t
Element element = context->elementCreate(DataType::UNSIGNED_8, DataKind::USER, false, 1);
+ ASSERT_NE(Element(0), element);
+
// 64 x 64 x uint8_t
Type type = context->typeCreate(element, 64, 64, 0, true, false, YuvFormat::YUV_NONE);
+ ASSERT_NE(Type(0), type);
+
std::vector<uint8_t> dataIn(64*64), dataOut(32*32), expected(32*32);
std::generate(dataIn.begin(), dataIn.end(),
[](){ static int val = 0; return (uint8_t)(0xFF & val++); });
@@ -303,6 +357,8 @@
Allocation allocation = context->allocationCreateTyped(type, AllocationMipmapControl::FULL,
(int)AllocationUsageType::SCRIPT,
(Ptr)nullptr);
+ ASSERT_NE(Allocation(0), allocation);
+
context->allocation2DWrite(allocation, 0, 0, 0, AllocationCubemapFace::POSITIVE_X, 64, 64,
_data, 64*sizeof(uint8_t));
context->allocationGenerateMipmaps(allocation);
@@ -333,8 +389,12 @@
TEST_F(RenderscriptHidlTest, SimpleCubemapTest) {
// float1
Element element = context->elementCreate(DataType::FLOAT_32, DataKind::USER, false, 1);
+ ASSERT_NE(Element(0), element);
+
// 128 x 128 x float1
Type type = context->typeCreate(element, 128, 128, 0, false, true, YuvFormat::YUV_NONE);
+ ASSERT_NE(Type(0), type);
+
std::vector<float> dataIn(128*128*6), dataOut(128*128), expected(128*128);
std::generate(dataIn.begin(), dataIn.end(), [](){ static int val = 0; return (float)val++; });
hidl_vec<uint8_t> _data;
@@ -342,7 +402,7 @@
// 128 x 128 x float1 x 6
Allocation allocation = context->allocationCubeCreateFromBitmap(
type, AllocationMipmapControl::NONE, _data, (int)AllocationUsageType::SCRIPT);
- EXPECT_NE(Allocation(0), allocation);
+ ASSERT_NE(Allocation(0), allocation);
context->allocation2DRead(allocation, 0, 0, 0, AllocationCubemapFace::NEGATIVE_Z, 128,
128, (Ptr)dataOut.data(), (Size)dataOut.size()*sizeof(float),
@@ -367,13 +427,16 @@
*/
TEST_F(RenderscriptHidlTest, ComplexElementTest) {
Element element1 = context->elementCreate(DataType::UNSIGNED_8, DataKind::USER, false, 1);
+ ASSERT_NE(Element(0), element1);
+
Element element2 = context->elementCreate(DataType::UNSIGNED_32, DataKind::USER, false, 1);
+ ASSERT_NE(Element(0), element2);
hidl_vec<Element> eins = {element1, element2};
hidl_vec<hidl_string> names = {hidl_string("first"), hidl_string("second")};
hidl_vec<Size> arraySizesPtr = {1, 1};
Element element3 = context->elementComplexCreate(eins, names, arraySizesPtr);
- EXPECT_NE(Element(0), element3);
+ ASSERT_NE(Element(0), element3);
std::vector<Element> ids;
std::vector<std::string> namesOut;
@@ -395,10 +458,14 @@
// 1 x (uint8_t, uint32_t)
Type type = context->typeCreate(element3, 1, 0, 0, false, false, YuvFormat::YUV_NONE);
+ ASSERT_NE(Type(0), type);
+
// 1 x (uint8_t, uint32_t)
Allocation allocation = context->allocationCreateTyped(type, AllocationMipmapControl::NONE,
(int)AllocationUsageType::SCRIPT,
(Ptr)nullptr);
+ ASSERT_NE(Allocation(0), allocation);
+
std::vector<uint32_t> dataIn(1), dataOut(1);
std::generate(dataIn.begin(), dataIn.end(), [](){ static uint32_t val = 0; return val++; });
hidl_vec<uint8_t> _data;
diff --git a/renderscript/1.0/vts/functional/VtsMiscellaneousTests.cpp b/renderscript/1.0/vts/functional/VtsMiscellaneousTests.cpp
index 39d63ca..23b09ac 100644
--- a/renderscript/1.0/vts/functional/VtsMiscellaneousTests.cpp
+++ b/renderscript/1.0/vts/functional/VtsMiscellaneousTests.cpp
@@ -46,18 +46,18 @@
TEST_F(RenderscriptHidlTest, ElementTypeAllocationCreate) {
// Element create test
Element element = context->elementCreate(DataType::FLOAT_32, DataKind::USER, false, 1);
- EXPECT_NE(Element(0), element);
+ ASSERT_NE(Element(0), element);
// Type create test
Type type = context->typeCreate(element, 1, 0, 0, false, false, YuvFormat::YUV_NONE);
- EXPECT_NE(Type(0), type);
+ ASSERT_NE(Type(0), type);
// Allocation create test
Allocation allocation = context->allocationCreateTyped(type, AllocationMipmapControl::NONE,
(int)((uint32_t)AllocationUsageType::ALL
& ~(uint32_t)AllocationUsageType::OEM),
(Ptr)nullptr);
- EXPECT_NE(Allocation(0), allocation);
+ ASSERT_NE(Allocation(0), allocation);
// Allocation type test
Type type2 = context->allocationGetType(allocation);
@@ -74,8 +74,11 @@
TEST_F(RenderscriptHidlTest, MetadataTest) {
// float1
Element element = context->elementCreate(DataType::FLOAT_32, DataKind::USER, false, 1);
+ ASSERT_NE(Element(0), element);
+
// 128 x float1
Type type = context->typeCreate(element, 128, 0, 0, false, false, YuvFormat::YUV_NONE);
+ ASSERT_NE(Type(0), type);
std::vector<uint32_t> elementMetadata(5);
context->elementGetNativeMetadata(element, [&](const hidl_vec<uint32_t>& _metadata){
@@ -107,24 +110,30 @@
TEST_F(RenderscriptHidlTest, ResizeTest) {
// float1
Element element = context->elementCreate(DataType::FLOAT_32, DataKind::USER, false, 1);
+ ASSERT_NE(Element(0), element);
+
// 128 x float1
Type type = context->typeCreate(element, 128, 0, 0, false, false, YuvFormat::YUV_NONE);
+ ASSERT_NE(Type(0), type);
+
// 128 x float1
Allocation allocation = context->allocationCreateTyped(type, AllocationMipmapControl::NONE,
(int)AllocationUsageType::SCRIPT,
(Ptr)nullptr);
+ ASSERT_NE(Allocation(0), allocation);
+
Ptr dataPtr1, dataPtr2;
Size stride;
context->allocationGetPointer(allocation, 0, AllocationCubemapFace::POSITIVE_X, 0,
[&](Ptr _dataPtr, Size _stride){
dataPtr1 = _dataPtr; stride = _stride; });
- EXPECT_EQ(0ul, stride);
+ EXPECT_EQ(Size(0), stride);
context->allocationResize1D(allocation, 1024*1024);
context->allocationGetPointer(allocation, 0, AllocationCubemapFace::POSITIVE_X, 0,
[&](Ptr _dataPtr, Size _stride){
dataPtr2 = _dataPtr; stride = _stride; });
- EXPECT_EQ(0ul, stride);
+ EXPECT_EQ(Size(0), stride);
EXPECT_NE(dataPtr1, dataPtr2);
}
@@ -139,8 +148,12 @@
TEST_F(RenderscriptHidlTest, NativeWindowIoTest) {
// uint8x4
Element element = context->elementCreate(DataType::UNSIGNED_8, DataKind::USER, false, 4);
+ ASSERT_NE(Element(0), element);
+
// 512 x 512 x uint8x4
Type type = context->typeCreate(element, 512, 512, 0, false, false, YuvFormat::YUV_NONE);
+ ASSERT_NE(Type(0), type);
+
std::vector<uint32_t> dataIn(512*512), dataOut(512*512);
std::generate(dataIn.begin(), dataIn.end(), [](){ static uint32_t val = 0; return val++; });
hidl_vec<uint8_t> _data;
@@ -150,12 +163,16 @@
(int)(AllocationUsageType::SCRIPT
| AllocationUsageType::IO_INPUT),
(Ptr)nullptr);
+ ASSERT_NE(Allocation(0), allocationRecv);
+
Allocation allocationSend = context->allocationCreateTyped(type, AllocationMipmapControl::NONE,
(int)(AllocationUsageType::SCRIPT
| AllocationUsageType::IO_OUTPUT),
(Ptr)nullptr);
+ ASSERT_NE(Allocation(0), allocationSend);
+
NativeWindow nativeWindow = context->allocationGetNativeWindow(allocationRecv);
- EXPECT_NE(NativeWindow(0), nativeWindow);
+ ASSERT_NE(NativeWindow(0), nativeWindow);
((ANativeWindow *)nativeWindow)->incStrong(nullptr);
@@ -174,14 +191,20 @@
* two allocations with IO_INPUT are made to share the same BufferQueue.
*
* Calls: elementCreate, typeCreate, allocationCreateTyped,
- * allocationCreateFromBitmap, allocationSetupBufferQueue,
- * allocationShareBufferQueue
+ * allocationSetupBufferQueue, allocationShareBufferQueue,
+ * allocationGetNativeWindow, allocationSetNativeWindow,
+ * allocation2DWrite, allocation2DRead, allocationIoSend,
+ * allocationIoReceive
*/
TEST_F(RenderscriptHidlTest, BufferQueueTest) {
// uint8x4
Element element = context->elementCreate(DataType::UNSIGNED_8, DataKind::USER, false, 4);
+ ASSERT_NE(Element(0), element);
+
// 512 x 512 x uint8x4
Type type = context->typeCreate(element, 512, 512, 0, false, false, YuvFormat::YUV_NONE);
+ ASSERT_NE(Type(0), type);
+
std::vector<uint32_t> dataIn(512*512), dataOut1(512*512), dataOut2(512*512);
std::generate(dataIn.begin(), dataIn.end(), [](){ static uint32_t val = 0; return val++; });
hidl_vec<uint8_t> _data;
@@ -191,20 +214,28 @@
(int)(AllocationUsageType::SCRIPT
| AllocationUsageType::IO_INPUT),
(Ptr)nullptr);
+ ASSERT_NE(Allocation(0), allocationRecv1);
+
Allocation allocationRecv2 = context->allocationCreateTyped(type, AllocationMipmapControl::NONE,
(int)(AllocationUsageType::SCRIPT
| AllocationUsageType::IO_INPUT),
(Ptr)nullptr);
+ ASSERT_NE(Allocation(0), allocationRecv2);
+
Allocation allocationSend = context->allocationCreateTyped(type, AllocationMipmapControl::NONE,
(int)(AllocationUsageType::SCRIPT
| AllocationUsageType::IO_INPUT),
(Ptr)nullptr);
+ ASSERT_NE(Allocation(0), allocationSend);
+
context->allocationSetupBufferQueue(allocationRecv1, 2);
context->allocationShareBufferQueue(allocationRecv2, allocationRecv1);
NativeWindow nativeWindow1 = context->allocationGetNativeWindow(allocationRecv1);
- EXPECT_NE(NativeWindow(0), nativeWindow1);
+ ASSERT_NE(NativeWindow(0), nativeWindow1);
+
NativeWindow nativeWindow2 = context->allocationGetNativeWindow(allocationRecv2);
+ ASSERT_NE(NativeWindow(0), nativeWindow2);
EXPECT_EQ(nativeWindow2, nativeWindow1);
((ANativeWindow *)nativeWindow1)->incStrong(nullptr);
@@ -269,6 +300,8 @@
context->contextSetCacheDir("/data/local/tmp/temp/");
Element element = context->elementCreate(DataType::UNSIGNED_8, DataKind::USER, false, 1);
+ ASSERT_NE(Element(0), element);
+
std::string nameIn = "element_test_name";
std::string nameOut = "not_name";
hidl_string _nameIn;
diff --git a/renderscript/1.0/vts/functional/VtsScriptTests.cpp b/renderscript/1.0/vts/functional/VtsScriptTests.cpp
index 6bb375a..fed7c6e 100644
--- a/renderscript/1.0/vts/functional/VtsScriptTests.cpp
+++ b/renderscript/1.0/vts/functional/VtsScriptTests.cpp
@@ -25,6 +25,8 @@
TEST_F(RenderscriptHidlTest, IntrinsicTest) {
// uint8
Element element = context->elementCreate(DataType::UNSIGNED_8, DataKind::USER, false, 1);
+ EXPECT_NE(Element(0), element);
+
Script script = context->scriptIntrinsicCreate(ScriptIntrinsicID::ID_BLUR, element);
EXPECT_NE(Script(0), script);
@@ -43,7 +45,7 @@
hidl_vec<uint8_t> bitcode;
bitcode.setToExternal((uint8_t*)bitCode, bitCodeLength);
Script script = context->scriptCCreate("struct_test", "/data/local/tmp/", bitcode);
- EXPECT_NE(Script(0), script);
+ ASSERT_NE(Script(0), script);
// arg tests
context->scriptSetVarI(script, mExportVarIdx_var_int, 100);
@@ -75,12 +77,18 @@
// float1
Element element = context->elementCreate(DataType::FLOAT_32, DataKind::USER, false, 1);
+ ASSERT_NE(Element(0), element);
+
// 128 x float1
Type type = context->typeCreate(element, 128, 0, 0, false, false, YuvFormat::YUV_NONE);
+ ASSERT_NE(Type(0), type);
+
// 128 x float1
Allocation allocationIn = context->allocationCreateTyped(type, AllocationMipmapControl::NONE,
(int)AllocationUsageType::SCRIPT,
(Ptr)nullptr);
+ ASSERT_NE(Allocation(0), allocationIn);
+
Allocation allocationOut = Allocation(0);
context->scriptSetVarObj(script, mExportVarIdx_var_allocation, (ObjectBase)allocationIn);
context->scriptGetVarV(script, mExportVarIdx_var_allocation, sizeof(ObjectBase),
@@ -107,6 +115,8 @@
_dimsVE.setToExternal((uint32_t*)dimsVE.data(), dimsVE.size());
// intx2 to represent point2 which is {int, int}
Element elementVE = context->elementCreate(DataType::SIGNED_32, DataKind::USER, false, 2);
+ ASSERT_NE(Element(0), elementVE);
+
context->scriptSetVarVE(script, mExportVarIdx_var_point2, _dataVE, elementVE, _dimsVE);
context->scriptGetVarV(script, mExportVarIdx_var_point2, 2*sizeof(int),
[&](const hidl_vec<uint8_t>& _data){
@@ -126,7 +136,7 @@
hidl_vec<uint8_t> bitcode;
bitcode.setToExternal((uint8_t*)bitCode, bitCodeLength);
Script script = context->scriptCCreate("struct_test", "/data/local/tmp/", bitcode);
- EXPECT_NE(Script(0), script);
+ ASSERT_NE(Script(0), script);
// invoke test
int resultI = 0;
@@ -185,12 +195,16 @@
hidl_vec<uint8_t> bitcode;
bitcode.setToExternal((uint8_t*)bitCode, bitCodeLength);
Script script = context->scriptCCreate("struct_test", "/data/local/tmp/", bitcode);
- EXPECT_NE(Script(0), script);
+ ASSERT_NE(Script(0), script);
// uint8_t
Element element = context->elementCreate(DataType::UNSIGNED_8, DataKind::USER, false, 1);
+ ASSERT_NE(Element(0), element);
+
// 64 x uint8_t
Type type = context->typeCreate(element, 64, 0, 0, false, false, YuvFormat::YUV_NONE);
+ ASSERT_NE(Type(0), type);
+
std::vector<uint8_t> dataIn(64), dataOut(64), expected(64);
std::generate(dataIn.begin(), dataIn.end(), [](){ static uint8_t val = 0; return val++; });
std::generate(expected.begin(), expected.end(), [](){ static uint8_t val = 1; return val++; });
@@ -200,9 +214,13 @@
Allocation allocation = context->allocationCreateTyped(type, AllocationMipmapControl::NONE,
(int)AllocationUsageType::SCRIPT,
(Ptr)nullptr);
+ ASSERT_NE(Allocation(0), allocation);
+
Allocation vout = context->allocationCreateTyped(type, AllocationMipmapControl::NONE,
(int)AllocationUsageType::SCRIPT,
(Ptr)nullptr);
+ ASSERT_NE(Allocation(0), vout);
+
context->allocation1DWrite(allocation, 0, 0, (Size)dataIn.size(), _data);
hidl_vec<Allocation> vains;
vains.setToExternal(&allocation, 1);
@@ -223,13 +241,19 @@
hidl_vec<uint8_t> bitcode;
bitcode.setToExternal((uint8_t*)bitCode, bitCodeLength);
Script script = context->scriptCCreate("struct_test", "/data/local/tmp/", bitcode);
- EXPECT_NE(Script(0), script);
+ ASSERT_NE(Script(0), script);
// uint8_t
Element element = context->elementCreate(DataType::SIGNED_32, DataKind::USER, false, 1);
+ ASSERT_NE(Element(0), element);
+
// 64 x uint8_t
Type type = context->typeCreate(element, 64, 0, 0, false, false, YuvFormat::YUV_NONE);
+ ASSERT_NE(Type(0), type);
+
Type type2 = context->typeCreate(element, 1, 0, 0, false, false, YuvFormat::YUV_NONE);
+ ASSERT_NE(Type(0), type2);
+
std::vector<int> dataIn(64), dataOut(1);
std::generate(dataIn.begin(), dataIn.end(), [](){ static int val = 0; return val++; });
hidl_vec<uint8_t> _data;
@@ -238,9 +262,13 @@
Allocation allocation = context->allocationCreateTyped(type, AllocationMipmapControl::NONE,
(int)AllocationUsageType::SCRIPT,
(Ptr)nullptr);
+ ASSERT_NE(Allocation(0), allocation);
+
Allocation vaout = context->allocationCreateTyped(type2, AllocationMipmapControl::NONE,
(int)AllocationUsageType::SCRIPT,
(Ptr)nullptr);
+ ASSERT_NE(Allocation(0), vaout);
+
context->allocation1DWrite(allocation, 0, 0, (Size)dataIn.size(), _data);
hidl_vec<Allocation> vains;
vains.setToExternal(&allocation, 1);
@@ -257,22 +285,29 @@
* RenderScript script, represented in the bitcode.
*
* Calls: scriptCCreate, elementCreate, typeCreate, allocationCreateTyped,
- * scriptSetVarV, scriptBindAllocation, allocationRead
+ * allocation1DWrite, scriptBindAllocation, scriptSetVarV, scriptBindAllocation,
+ * allocationRead, scriptInvokeV, allocationRead
*/
TEST_F(RenderscriptHidlTest, ScriptBindTest) {
hidl_vec<uint8_t> bitcode;
bitcode.setToExternal((uint8_t*)bitCode, bitCodeLength);
Script script = context->scriptCCreate("struct_test", "/data/local/tmp/", bitcode);
- EXPECT_NE(Script(0), script);
+ ASSERT_NE(Script(0), script);
// in32
Element element = context->elementCreate(DataType::SIGNED_32, DataKind::USER, false, 1);
+ ASSERT_NE(Element(0), element);
+
// 64 x int32
Type type = context->typeCreate(element, 64, 0, 0, false, false, YuvFormat::YUV_NONE);
+ ASSERT_NE(Type(0), type);
+
// 64 x int32
Allocation allocation = context->allocationCreateTyped(type, AllocationMipmapControl::NONE,
(int)AllocationUsageType::SCRIPT,
(Ptr)nullptr);
+ ASSERT_NE(Allocation(0), allocation);
+
std::vector<int> dataIn(64), dataOut(64), expected(64, 5);
hidl_vec<uint8_t> _data;
_data.setToExternal((uint8_t*)dataIn.data(), dataIn.size()*sizeof(int));
@@ -295,7 +330,8 @@
*
* Calls: elementCreate, typeCreate, allocationCreateTyped, allocation2DWrite,
* scriptIntrinsicCreate, scriptKernelIDCreate, scriptFieldIDCreate,
- * scriptGroupCreate, scriptGroupSetOutput, scriptGroupExecute, allocation2DRead
+ * scriptGroupCreate, scriptSetVarObj, scriptGroupSetOutput, scriptGroupExecute,
+ * contextFinish, allocation2DRead
*/
TEST_F(RenderscriptHidlTest, ScriptGroupTest) {
std::vector<uint8_t> dataIn(256*256*1, 128), dataOut(256*256*4, 0), zeros(256*256*4, 0);
@@ -305,36 +341,49 @@
// 256 x 256 YUV pixels
Element element1 = context->elementCreate(DataType::UNSIGNED_8, DataKind::PIXEL_YUV, true, 1);
+ ASSERT_NE(Element(0), element1);
+
Type type1 = context->typeCreate(element1, 256, 256, 0, false, false, YuvFormat::YUV_420_888);
+ ASSERT_NE(Type(0), type1);
+
Allocation allocation1 = context->allocationCreateTyped(type1, AllocationMipmapControl::NONE,
(int)AllocationUsageType::SCRIPT,
(Ptr)nullptr);
+ ASSERT_NE(Allocation(0), allocation1);
+
context->allocation2DWrite(allocation1, 0, 0, 0, AllocationCubemapFace::POSITIVE_X, 256, 256,
_dataIn, 0);
// 256 x 256 RGBA pixels
Element element2 = context->elementCreate(DataType::UNSIGNED_8, DataKind::PIXEL_RGBA, true, 4);
+ ASSERT_NE(Element(0), element2);
+
Type type2 = context->typeCreate(element2, 256, 256, 0, false, false, YuvFormat::YUV_NONE);
+ ASSERT_NE(Type(0), type2);
+
Allocation allocation2 = context->allocationCreateTyped(type2, AllocationMipmapControl::NONE,
(int)AllocationUsageType::SCRIPT,
(Ptr)nullptr);
+ ASSERT_NE(Allocation(0), allocation2);
+
context->allocation2DWrite(allocation2, 0, 0, 0, AllocationCubemapFace::POSITIVE_X, 256, 256,
_dataOut, 0);
// create scripts
Script yuv2rgb = context->scriptIntrinsicCreate(ScriptIntrinsicID::ID_YUV_TO_RGB, element1);
- EXPECT_NE(Script(0), yuv2rgb);
+ ASSERT_NE(Script(0), yuv2rgb);
ScriptKernelID yuv2rgbKID = context->scriptKernelIDCreate(yuv2rgb, 0, 2);
- EXPECT_NE(ScriptKernelID(0), yuv2rgbKID);
+ ASSERT_NE(ScriptKernelID(0), yuv2rgbKID);
Script blur = context->scriptIntrinsicCreate(ScriptIntrinsicID::ID_BLUR, element2);
- EXPECT_NE(Script(0), blur);
+ ASSERT_NE(Script(0), blur);
ScriptKernelID blurKID = context->scriptKernelIDCreate(blur, 0, 2);
- EXPECT_NE(ScriptKernelID(0), blurKID);
+ ASSERT_NE(ScriptKernelID(0), blurKID);
+
ScriptFieldID blurFID = context->scriptFieldIDCreate(blur, 1);
- EXPECT_NE(ScriptFieldID(0), blurFID);
+ ASSERT_NE(ScriptFieldID(0), blurFID);
// ScriptGroup
hidl_vec<ScriptKernelID> kernels = {yuv2rgbKID, blurKID};
@@ -343,7 +392,7 @@
hidl_vec<ScriptFieldID> dstF = {blurFID};
hidl_vec<Type> types = {type2};
ScriptGroup scriptGroup = context->scriptGroupCreate(kernels, srcK, dstK, dstF, types);
- EXPECT_NE(ScriptGroup(0), scriptGroup);
+ ASSERT_NE(ScriptGroup(0), scriptGroup);
context->scriptSetVarObj(yuv2rgb, 0, (ObjectBase)allocation1);
context->scriptGroupSetOutput(scriptGroup, blurKID, allocation2);
@@ -360,14 +409,16 @@
* Similar to the ScriptGroup test, this test verifies the execution flow of
* RenderScript kernels and invokables.
*
- * Calls: scriptFieldIDCreate, closureCreate, scriptInvokeIDCreate,
- * invokeClosureCreate, closureSetGlobal, scriptGroup2Create, scriptGroupExecute
+ * Calls: scriptCCreate, elementCreate, typeCreate, allocationCreateTyped,
+ * allocation1DWrite, scriptFieldIDCreate, scriptInvokeIDCreate,
+ * invokeClosureCreate, closureCreate, closureSetGlobal, scriptGroup2Create,
+ * scriptGroupExecute, allocationRead
*/
TEST_F(RenderscriptHidlTest, ScriptGroup2Test) {
hidl_vec<uint8_t> bitcode;
bitcode.setToExternal((uint8_t*)bitCode, bitCodeLength);
Script script = context->scriptCCreate("struct_test", "/data/local/tmp/", bitcode);
- EXPECT_NE(Script(0), script);
+ ASSERT_NE(Script(0), script);
std::vector<uint8_t> dataIn(128, 128), dataOut(128, 0), expected(128, 7+1);
hidl_vec<uint8_t> _dataIn, _dataOut;
@@ -375,19 +426,23 @@
// 256 x 256 YUV pixels
Element element = context->elementCreate(DataType::UNSIGNED_8, DataKind::USER, false, 1);
+ ASSERT_NE(Element(0), element);
+
Type type = context->typeCreate(element, 128, 0, 0, false, false, YuvFormat::YUV_NONE);
+ ASSERT_NE(Type(0), type);
+
Allocation allocation = context->allocationCreateTyped(type, AllocationMipmapControl::NONE,
(int)AllocationUsageType::SCRIPT,
(Ptr)nullptr);
+ ASSERT_NE(Allocation(0), allocation);
+
context->allocation1DWrite(allocation, 0, 0, (Size)_dataIn.size(), _dataIn);
ScriptFieldID fieldID = context->scriptFieldIDCreate(script, mExportVarIdx_var_allocation);
- EXPECT_NE(ScriptFieldID(0), fieldID);
ASSERT_NE(ScriptFieldID(0), fieldID);
// invoke
ScriptInvokeID invokeID = context->scriptInvokeIDCreate(script, mExportFuncIdx_setAllocation);
- EXPECT_NE(ScriptInvokeID(0), invokeID);
ASSERT_NE(ScriptInvokeID(0), invokeID);
int dim = 128;
@@ -397,12 +452,10 @@
hidl_vec<int64_t> values1 = {int64_t(0)};
hidl_vec<int32_t> sizes1 = {int32_t(0)};
Closure closure1 = context->invokeClosureCreate(invokeID, params, fieldIDS1, values1, sizes1);
- EXPECT_NE(Closure(0), closure1);
ASSERT_NE(Closure(0), closure1);
// kernel
ScriptKernelID kernelID = context->scriptKernelIDCreate(script, mExportForEachIdx_increment, 3);
- EXPECT_NE(ScriptKernelID(0), kernelID);
ASSERT_NE(ScriptKernelID(0), kernelID);
hidl_vec<ScriptFieldID> fieldIDS2 = {ScriptFieldID(0)};
@@ -412,7 +465,6 @@
hidl_vec<ScriptFieldID> depFieldIDS2 = {fieldID};
Closure closure2 = context->closureCreate(kernelID, allocation /* returnValue */, fieldIDS2,
values2, sizes2, depClosures2, depFieldIDS2);
- EXPECT_NE(Closure(0), closure2);
ASSERT_NE(Closure(0), closure2);
// set argument
@@ -424,7 +476,6 @@
hidl_string cacheDir = "/data/local/tmp";
hidl_vec<Closure> closures = {closure1, closure2};
ScriptGroup2 scriptGroup2 = context->scriptGroup2Create(name, cacheDir, closures);
- EXPECT_NE(ScriptGroup2(0), scriptGroup2);
ASSERT_NE(ScriptGroup2(0), scriptGroup2);
context->scriptGroupExecute(scriptGroup2);
@@ -436,14 +487,15 @@
* Similar to the ScriptGroup test, this test verifies a single kernel can be
* called by ScriptGroup with an unbound allocation specified before launch
*
- * Calls: scriptFieldIDCreate, closureCreate, scriptInvokeIDCreate,
- * invokeClosureCreate, closureSetArg, scriptGroup2Create, scriptGroupExecute
+ * Calls: scriptCCreate, elementCreate, typeCreate, allocationCreateTyped,
+ * allocation1DWrite, scriptKernelIDCreate, closureCreate, closureSetArg,
+ * scriptGroup2Create, scriptGroupExecute, allocationRead
*/
TEST_F(RenderscriptHidlTest, ScriptGroup2KernelTest) {
hidl_vec<uint8_t> bitcode;
bitcode.setToExternal((uint8_t*)bitCode, bitCodeLength);
Script script = context->scriptCCreate("struct_test", "/data/local/tmp/", bitcode);
- EXPECT_NE(Script(0), script);
+ ASSERT_NE(Script(0), script);
std::vector<uint8_t> dataIn(128, 128), dataOut(128, 0), expected(128, 128 + 1);
hidl_vec<uint8_t> _dataIn, _dataOut;
@@ -451,15 +503,20 @@
// 256 x 256 YUV pixels
Element element = context->elementCreate(DataType::UNSIGNED_8, DataKind::USER, false, 1);
+ ASSERT_NE(Element(0), element);
+
Type type = context->typeCreate(element, 128, 0, 0, false, false, YuvFormat::YUV_NONE);
+ ASSERT_NE(Type(0), type);
+
Allocation allocation = context->allocationCreateTyped(type, AllocationMipmapControl::NONE,
(int)AllocationUsageType::SCRIPT,
(Ptr)nullptr);
+ ASSERT_NE(Allocation(0), allocation);
+
context->allocation1DWrite(allocation, 0, 0, (Size)_dataIn.size(), _dataIn);
// kernel
ScriptKernelID kernelID = context->scriptKernelIDCreate(script, mExportForEachIdx_increment, 3);
- EXPECT_NE(ScriptKernelID(0), kernelID);
ASSERT_NE(ScriptKernelID(0), kernelID);
hidl_vec<ScriptFieldID> fieldIDS = {ScriptFieldID(0)};
@@ -469,7 +526,6 @@
hidl_vec<ScriptFieldID> depFieldIDS = {ScriptFieldID(0)};
Closure closure = context->closureCreate(kernelID, allocation /* returnValue */, fieldIDS,
values, sizes, depClosures, depFieldIDS);
- EXPECT_NE(Closure(0), closure);
ASSERT_NE(Closure(0), closure);
// set argument
@@ -480,7 +536,6 @@
hidl_string cacheDir = "/data/local/tmp";
hidl_vec<Closure> closures = {closure};
ScriptGroup2 scriptGroup2 = context->scriptGroup2Create(name, cacheDir, closures);
- EXPECT_NE(ScriptGroup2(0), scriptGroup2);
ASSERT_NE(ScriptGroup2(0), scriptGroup2);
context->scriptGroupExecute(scriptGroup2);
diff --git a/soundtrigger/2.0/types.hal b/soundtrigger/2.0/types.hal
index fc7d019..99bbd56 100644
--- a/soundtrigger/2.0/types.hal
+++ b/soundtrigger/2.0/types.hal
@@ -75,8 +75,3 @@
vec<ConfidenceLevel> levels;
};
-/** TODO(elaurent) remove when Java build problem is fixed */
-union Dummy {
- uint32_t dummy1;
- int32_t dummy2;
-};
diff --git a/tests/foo/1.0/default/lib/Android.bp b/tests/foo/1.0/default/lib/Android.bp
index 895582c..b512311 100644
--- a/tests/foo/1.0/default/lib/Android.bp
+++ b/tests/foo/1.0/default/lib/Android.bp
@@ -1,5 +1,6 @@
cc_library_shared {
name: "libfootest",
+ vendor: true,
defaults: ["hidl_defaults"],
srcs: [
"FooHelper.cpp"
diff --git a/tests/pointer/1.0/default/lib/Android.bp b/tests/pointer/1.0/default/lib/Android.bp
index ae07b04..1fe0896 100644
--- a/tests/pointer/1.0/default/lib/Android.bp
+++ b/tests/pointer/1.0/default/lib/Android.bp
@@ -1,5 +1,6 @@
cc_library_shared {
name: "libpointertest",
+ vendor: true,
defaults: ["hidl_defaults"],
srcs: [
"PointerHelper.cpp"
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
index 42d9a96..c0af30b 100644
--- a/wifi/1.0/vts/functional/wifi_ap_iface_hidl_test.cpp
+++ b/wifi/1.0/vts/functional/wifi_ap_iface_hidl_test.cpp
@@ -20,9 +20,13 @@
#include <VtsHalHidlTargetTestBase.h>
+#include "wifi_hidl_call_util.h"
#include "wifi_hidl_test_utils.h"
+using ::android::hardware::wifi::V1_0::IfaceType;
using ::android::hardware::wifi::V1_0::IWifiApIface;
+using ::android::hardware::wifi::V1_0::WifiBand;
+using ::android::hardware::wifi::V1_0::WifiStatusCode;
using ::android::sp;
/**
@@ -30,11 +34,15 @@
*/
class WifiApIfaceHidlTest : public ::testing::VtsHalHidlTargetTestBase {
public:
- virtual void SetUp() override {}
+ virtual void SetUp() override {
+ wifi_ap_iface_ = getWifiApIface();
+ ASSERT_NE(nullptr, wifi_ap_iface_.get());
+ }
virtual void TearDown() override { stopWifi(); }
protected:
+ sp<IWifiApIface> wifi_ap_iface_;
};
/*
@@ -46,3 +54,36 @@
EXPECT_NE(nullptr, getWifiApIface().get());
stopWifi();
}
+
+/*
+ * GetType:
+ * Ensures that the correct interface type is returned for AP interface.
+ */
+TEST_F(WifiApIfaceHidlTest, GetType) {
+ const auto& status_and_type = HIDL_INVOKE(wifi_ap_iface_, getType);
+ EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_type.first.code);
+ EXPECT_EQ(IfaceType::AP, status_and_type.second);
+}
+
+/*
+ * SetCountryCode:
+ * Ensures that a call to set the country code will return with a success
+ * status code.
+ */
+TEST_F(WifiApIfaceHidlTest, SetCountryCode) {
+ const android::hardware::hidl_array<int8_t, 2> kCountryCode{
+ std::array<int8_t, 2>{{0x55, 0x53}}};
+ EXPECT_EQ(WifiStatusCode::SUCCESS,
+ HIDL_INVOKE(wifi_ap_iface_, setCountryCode, kCountryCode).code);
+}
+
+/*
+ * GetValidFrequenciesForBand:
+ * Ensures that we can retrieve valid frequencies for 2.4 GHz band.
+ */
+TEST_F(WifiApIfaceHidlTest, GetValidFrequenciesForBand) {
+ const auto& status_and_freqs = HIDL_INVOKE(
+ wifi_ap_iface_, getValidFrequenciesForBand, WifiBand::BAND_24GHZ);
+ EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_freqs.first.code);
+ EXPECT_GT(status_and_freqs.second.size(), 0u);
+}
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
index 95add61..83f83b6 100644
--- a/wifi/1.0/vts/functional/wifi_sta_iface_hidl_test.cpp
+++ b/wifi/1.0/vts/functional/wifi_sta_iface_hidl_test.cpp
@@ -24,7 +24,16 @@
#include "wifi_hidl_test_utils.h"
using ::android::sp;
+using ::android::hardware::wifi::V1_0::Bssid;
+using ::android::hardware::wifi::V1_0::CommandId;
+using ::android::hardware::wifi::V1_0::IfaceType;
using ::android::hardware::wifi::V1_0::IWifiStaIface;
+using ::android::hardware::wifi::V1_0::Rssi;
+using ::android::hardware::wifi::V1_0::Ssid;
+using ::android::hardware::wifi::V1_0::StaApfPacketFilterCapabilities;
+using ::android::hardware::wifi::V1_0::StaRoamingConfig;
+using ::android::hardware::wifi::V1_0::StaRoamingState;
+using ::android::hardware::wifi::V1_0::WifiBand;
using ::android::hardware::wifi::V1_0::WifiStatus;
using ::android::hardware::wifi::V1_0::WifiStatusCode;
@@ -41,6 +50,13 @@
virtual void TearDown() override { stopWifi(); }
protected:
+ bool isCapabilitySupported(IWifiStaIface::StaIfaceCapabilityMask cap_mask) {
+ const auto& status_and_caps =
+ HIDL_INVOKE(wifi_sta_iface_, getCapabilities);
+ EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_caps.first.code);
+ return (status_and_caps.second & cap_mask) != 0;
+ }
+
sp<IWifiStaIface> wifi_sta_iface_;
};
@@ -60,5 +76,190 @@
TEST_F(WifiStaIfaceHidlTest, GetCapabilities) {
const auto& status_and_caps = HIDL_INVOKE(wifi_sta_iface_, getCapabilities);
EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_caps.first.code);
- EXPECT_NE(0u, status_and_caps.second);
+ EXPECT_GT(status_and_caps.second, 0u);
+}
+
+/*
+ * GetType:
+ * Ensures that the correct interface type is returned for station interface.
+ */
+TEST_F(WifiStaIfaceHidlTest, GetType) {
+ const auto& status_and_type = HIDL_INVOKE(wifi_sta_iface_, getType);
+ EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_type.first.code);
+ EXPECT_EQ(IfaceType::STA, status_and_type.second);
+}
+
+/*
+ * GetApfPacketFilterCapabilities:
+ * Ensures that we can retrieve APF packet filter capabilites.
+ */
+TEST_F(WifiStaIfaceHidlTest, GetApfPacketFilterCapabilities) {
+ if (!isCapabilitySupported(IWifiStaIface::StaIfaceCapabilityMask::APF)) {
+ // No-op if APF packet filer is not supported.
+ return;
+ }
+
+ const auto& status_and_caps =
+ HIDL_INVOKE(wifi_sta_iface_, getApfPacketFilterCapabilities);
+ EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_caps.first.code);
+}
+
+/*
+ * GetBackgroundScanCapabilities:
+ * Ensures that we can retrieve background scan capabilities.
+ */
+TEST_F(WifiStaIfaceHidlTest, GetBackgroundScanCapabilities) {
+ if (!isCapabilitySupported(
+ IWifiStaIface::StaIfaceCapabilityMask::BACKGROUND_SCAN)) {
+ // No-op if background scan is not supported.
+ return;
+ }
+
+ const auto& status_and_caps =
+ HIDL_INVOKE(wifi_sta_iface_, getBackgroundScanCapabilities);
+ EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_caps.first.code);
+}
+
+/*
+ * GetValidFrequenciesForBand:
+ * Ensures that we can retrieve valid frequencies for 2.4 GHz band.
+ */
+TEST_F(WifiStaIfaceHidlTest, GetValidFrequenciesForBand) {
+ const auto& status_and_freqs = HIDL_INVOKE(
+ wifi_sta_iface_, getValidFrequenciesForBand, WifiBand::BAND_24GHZ);
+ EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_freqs.first.code);
+ EXPECT_GT(status_and_freqs.second.size(), 0u);
+}
+
+/*
+ * LinkLayerStatsCollection:
+ * Ensures that calls to enable, disable, and retrieve link layer stats
+ * will return a success status code.
+ */
+TEST_F(WifiStaIfaceHidlTest, LinkLayerStatsCollection) {
+ if (!isCapabilitySupported(
+ IWifiStaIface::StaIfaceCapabilityMask::LINK_LAYER_STATS)) {
+ // No-op if link layer stats is not supported.
+ return;
+ }
+
+ // Enable link layer stats collection.
+ EXPECT_EQ(WifiStatusCode::SUCCESS,
+ HIDL_INVOKE(wifi_sta_iface_, enableLinkLayerStatsCollection, true)
+ .code);
+ // Retrieve link layer stats.
+ EXPECT_EQ(WifiStatusCode::SUCCESS,
+ HIDL_INVOKE(wifi_sta_iface_, getLinkLayerStats).first.code);
+ // Disable link layer stats collection.
+ EXPECT_EQ(
+ WifiStatusCode::SUCCESS,
+ HIDL_INVOKE(wifi_sta_iface_, disableLinkLayerStatsCollection).code);
+}
+
+/*
+ * RSSIMonitoring:
+ * Ensures that calls to enable and disable RSSI monitoring will return
+ * a success status code.
+ */
+TEST_F(WifiStaIfaceHidlTest, RSSIMonitoring) {
+ if (!isCapabilitySupported(
+ IWifiStaIface::StaIfaceCapabilityMask::RSSI_MONITOR)) {
+ // No-op if RSSI monitor is not supported.
+ return;
+ }
+
+ const CommandId kCmd = 1;
+ const Rssi kMaxRssi = -50;
+ const Rssi kMinRssi = -90;
+ EXPECT_EQ(WifiStatusCode::SUCCESS,
+ HIDL_INVOKE(wifi_sta_iface_, startRssiMonitoring, kCmd, kMaxRssi,
+ kMinRssi)
+ .code);
+ EXPECT_EQ(WifiStatusCode::SUCCESS,
+ HIDL_INVOKE(wifi_sta_iface_, stopRssiMonitoring, kCmd).code);
+}
+
+/*
+ * RoamingControl:
+ * Ensures that calls to configure and enable roaming will return a success
+ * status code.
+ */
+TEST_F(WifiStaIfaceHidlTest, RoamingControl) {
+ if (!isCapabilitySupported(
+ IWifiStaIface::StaIfaceCapabilityMask::CONTROL_ROAMING)) {
+ // No-op if roaming control is not supported.
+ return;
+ }
+
+ // Retrieve roaming capabilities.
+ const auto& status_and_cap =
+ HIDL_INVOKE(wifi_sta_iface_, getRoamingCapabilities);
+ EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_cap.first.code);
+
+ // Setup roaming configuration based on roaming capabilities.
+ const auto& cap = status_and_cap.second;
+ StaRoamingConfig roaming_config;
+ if (cap.maxBlacklistSize > 0) {
+ Bssid black_list_bssid{
+ std::array<uint8_t, 6>{{0x11, 0x22, 0x33, 0x44, 0x55, 0x66}}};
+ roaming_config.bssidBlacklist =
+ android::hardware::hidl_vec<Bssid>{black_list_bssid};
+ }
+ if (cap.maxWhitelistSize > 0) {
+ Ssid white_list_ssid{
+ std::array<uint8_t, 32>{{0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC}}};
+ roaming_config.ssidWhitelist =
+ android::hardware::hidl_vec<Ssid>{white_list_ssid};
+ }
+
+ // Configure roaming.
+ EXPECT_EQ(
+ WifiStatusCode::SUCCESS,
+ HIDL_INVOKE(wifi_sta_iface_, configureRoaming, roaming_config).code);
+
+ // Enable roaming.
+ EXPECT_EQ(
+ WifiStatusCode::SUCCESS,
+ HIDL_INVOKE(wifi_sta_iface_, setRoamingState, StaRoamingState::ENABLED)
+ .code);
+}
+
+/*
+ * EnableNDOffload:
+ * Ensures that calls to enable neighbor discovery offload will return a success
+ * status code.
+ */
+TEST_F(WifiStaIfaceHidlTest, EnableNDOffload) {
+ EXPECT_EQ(WifiStatusCode::SUCCESS,
+ HIDL_INVOKE(wifi_sta_iface_, enableNdOffload, true).code);
+}
+
+/*
+ * SetScanningMacOui:
+ * Ensures that calls to set scanning MAC OUI will return a success status
+ * code.
+ */
+TEST_F(WifiStaIfaceHidlTest, SetScanningMacOui) {
+ const android::hardware::hidl_array<uint8_t, 3> kOui{
+ std::array<uint8_t, 3>{{0x10, 0x22, 0x33}}};
+ EXPECT_EQ(WifiStatusCode::SUCCESS,
+ HIDL_INVOKE(wifi_sta_iface_, setScanningMacOui, kOui).code);
+}
+
+/*
+ * PacketFateMonitoring:
+ * Ensures that calls to start packet fate monitoring and retrieve TX/RX
+ * packets will return a success status code.
+ */
+TEST_F(WifiStaIfaceHidlTest, PacketFateMonitoring) {
+ // Start packet fate monitoring.
+ EXPECT_EQ(
+ WifiStatusCode::SUCCESS,
+ HIDL_INVOKE(wifi_sta_iface_, startDebugPacketFateMonitoring).code);
+
+ // Retrieve packets.
+ EXPECT_EQ(WifiStatusCode::SUCCESS,
+ HIDL_INVOKE(wifi_sta_iface_, getDebugTxPacketFates).first.code);
+ EXPECT_EQ(WifiStatusCode::SUCCESS,
+ HIDL_INVOKE(wifi_sta_iface_, getDebugRxPacketFates).first.code);
}
diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_call_util.h b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_call_util.h
new file mode 100644
index 0000000..1c0fcec
--- /dev/null
+++ b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_call_util.h
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// This file is copied from
+// hardware/interfaces/wifi/1.0/vts/functional/wifi_hidl_call_util.h
+// Please make sure these two file are consistent.
+
+#pragma once
+
+#include <functional>
+#include <tuple>
+#include <type_traits>
+#include <utility>
+
+#include <VtsHalHidlTargetTestBase.h>
+
+namespace {
+namespace detail {
+template <typename>
+struct functionArgSaver;
+
+// Provides a std::function that takes one argument, and a buffer
+// wherein the function will store its argument. The buffer has
+// the same type as the argument, but with const and reference
+// modifiers removed.
+template <typename ArgT>
+struct functionArgSaver<std::function<void(ArgT)>> final {
+ using StorageT = typename std::remove_const<
+ typename std::remove_reference<ArgT>::type>::type;
+
+ std::function<void(ArgT)> saveArgs = [this](ArgT arg) {
+ this->saved_values = arg;
+ };
+
+ StorageT saved_values;
+};
+
+// Provides a std::function that takes two arguments, and a buffer
+// wherein the function will store its arguments. The buffer is a
+// std::pair, whose elements have the same types as the arguments
+// (but with const and reference modifiers removed).
+template <typename Arg1T, typename Arg2T>
+struct functionArgSaver<std::function<void(Arg1T, Arg2T)>> final {
+ using StorageT =
+ std::pair<typename std::remove_const<
+ typename std::remove_reference<Arg1T>::type>::type,
+ typename std::remove_const<
+ typename std::remove_reference<Arg2T>::type>::type>;
+
+ std::function<void(Arg1T, Arg2T)> saveArgs = [this](Arg1T arg1,
+ Arg2T arg2) {
+ this->saved_values = {arg1, arg2};
+ };
+
+ StorageT saved_values;
+};
+
+// Provides a std::function that takes three or more arguments, and a
+// buffer wherein the function will store its arguments. The buffer is a
+// std::tuple whose elements have the same types as the arguments (but
+// with const and reference modifiers removed).
+template <typename... ArgT>
+struct functionArgSaver<std::function<void(ArgT...)>> final {
+ using StorageT = std::tuple<typename std::remove_const<
+ typename std::remove_reference<ArgT>::type>::type...>;
+
+ std::function<void(ArgT...)> saveArgs = [this](ArgT... arg) {
+ this->saved_values = {arg...};
+ };
+
+ StorageT saved_values;
+};
+
+// Invokes |method| on |object|, providing |method| a CallbackT as the
+// final argument. Returns a copy of the parameters that |method| provided
+// to CallbackT. (The parameters are returned by value.)
+template <typename CallbackT, typename MethodT, typename ObjectT,
+ typename... ArgT>
+typename functionArgSaver<CallbackT>::StorageT invokeMethod(
+ MethodT method, ObjectT object, ArgT&&... methodArg) {
+ functionArgSaver<CallbackT> result_buffer;
+ const auto& res = ((*object).*method)(std::forward<ArgT>(methodArg)...,
+ result_buffer.saveArgs);
+ EXPECT_TRUE(res.isOk());
+ return result_buffer.saved_values;
+}
+} // namespace detail
+} // namespace
+
+// Invokes |method| on |strong_pointer|, passing provided arguments through to
+// |method|.
+//
+// Returns either:
+// - A copy of the result callback parameter (for callbacks with a single
+// parameter), OR
+// - A pair containing a copy of the result callback parameters (for callbacks
+// with two parameters), OR
+// - A tuple containing a copy of the result callback paramters (for callbacks
+// with three or more parameters).
+//
+// Example usage:
+// EXPECT_EQ(WifiStatusCode::SUCCESS,
+// HIDL_INVOKE(strong_pointer, methodReturningWifiStatus).code);
+// EXPECT_EQ(WifiStatusCode::SUCCESS,
+// HIDL_INVOKE(strong_pointer, methodReturningWifiStatusAndOneMore)
+// .first.code);
+// EXPECT_EQ(WifiStatusCode::SUCCESS, std::get<0>(
+// HIDL_INVOKE(strong_pointer, methodReturningWifiStatusAndTwoMore))
+// .code);
+#define HIDL_INVOKE(strong_pointer, method, ...) \
+ (detail::invokeMethod< \
+ std::remove_reference<decltype(*strong_pointer)>::type::method##_cb>( \
+ &std::remove_reference<decltype(*strong_pointer)>::type::method, \
+ strong_pointer, ##__VA_ARGS__))
diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_p2p_iface_hidl_test.cpp b/wifi/supplicant/1.0/vts/functional/supplicant_p2p_iface_hidl_test.cpp
index 72a3c42..5a210d6 100644
--- a/wifi/supplicant/1.0/vts/functional/supplicant_p2p_iface_hidl_test.cpp
+++ b/wifi/supplicant/1.0/vts/functional/supplicant_p2p_iface_hidl_test.cpp
@@ -20,6 +20,7 @@
#include <android/hardware/wifi/supplicant/1.0/ISupplicantP2pIface.h>
+#include "supplicant_hidl_call_util.h"
#include "supplicant_hidl_test_utils.h"
using ::android::sp;
@@ -28,6 +29,7 @@
using ::android::hardware::hidl_vec;
using ::android::hardware::Return;
using ::android::hardware::Void;
+using ::android::hardware::wifi::supplicant::V1_0::IfaceType;
using ::android::hardware::wifi::supplicant::V1_0::ISupplicantP2pIface;
using ::android::hardware::wifi::supplicant::V1_0::ISupplicantP2pIfaceCallback;
using ::android::hardware::wifi::supplicant::V1_0::SupplicantNetworkId;
@@ -42,6 +44,7 @@
constexpr char kTestGroupIfName[] = "TestGroup";
constexpr uint32_t kTestConnectGoIntent = 6;
constexpr uint32_t kTestFindTimeout = 5;
+constexpr uint32_t kTestSetGroupIdleTimeout = 6;
constexpr SupplicantNetworkId kTestNetworkId = 5;
constexpr uint32_t kTestChannel = 1;
constexpr uint32_t kTestOperatingClass = 81;
@@ -178,6 +181,26 @@
}
/*
+ * GetName
+ */
+TEST_F(SupplicantP2pIfaceHidlTest, GetName) {
+ const auto& status_and_interface_name = HIDL_INVOKE(p2p_iface_, getName);
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS,
+ status_and_interface_name.first.code);
+ EXPECT_FALSE(std::string(status_and_interface_name.second).empty());
+}
+
+/*
+ * GetType
+ */
+TEST_F(SupplicantP2pIfaceHidlTest, GetType) {
+ const auto& status_and_interface_type = HIDL_INVOKE(p2p_iface_, getType);
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS,
+ status_and_interface_type.first.code);
+ EXPECT_EQ(status_and_interface_type.second, IfaceType::P2P);
+}
+
+/*
* GetDeviceAddress
*/
TEST_F(SupplicantP2pIfaceHidlTest, GetDeviceAddress) {
@@ -219,10 +242,6 @@
p2p_iface_->stopFind([](const SupplicantStatus& status) {
EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
});
-
- p2p_iface_->stopFind([](const SupplicantStatus& status) {
- EXPECT_NE(SupplicantStatusCode::SUCCESS, status.code);
- });
}
/*
@@ -411,3 +430,28 @@
status.code);
});
}
+
+/*
+ * SetGroupIdle
+ */
+TEST_F(SupplicantP2pIfaceHidlTest, SetGroupIdle) {
+ // This is not going to work with fake values.
+ EXPECT_NE(SupplicantStatusCode::SUCCESS,
+ HIDL_INVOKE(p2p_iface_, setGroupIdle, kTestGroupIfName,
+ kTestSetGroupIdleTimeout)
+ .code);
+}
+
+/*
+ * SetPowerSave
+ */
+TEST_F(SupplicantP2pIfaceHidlTest, SetPowerSave) {
+ // This is not going to work with fake values.
+ EXPECT_NE(
+ SupplicantStatusCode::SUCCESS,
+ HIDL_INVOKE(p2p_iface_, setPowerSave, kTestGroupIfName, true).code);
+ // This is not going to work with fake values.
+ EXPECT_NE(
+ SupplicantStatusCode::SUCCESS,
+ HIDL_INVOKE(p2p_iface_, setPowerSave, kTestGroupIfName, false).code);
+}
diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_sta_iface_hidl_test.cpp b/wifi/supplicant/1.0/vts/functional/supplicant_sta_iface_hidl_test.cpp
index 5abf4e0..3670321 100644
--- a/wifi/supplicant/1.0/vts/functional/supplicant_sta_iface_hidl_test.cpp
+++ b/wifi/supplicant/1.0/vts/functional/supplicant_sta_iface_hidl_test.cpp
@@ -20,6 +20,7 @@
#include <android/hardware/wifi/supplicant/1.0/ISupplicantStaIface.h>
+#include "supplicant_hidl_call_util.h"
#include "supplicant_hidl_test_utils.h"
using ::android::sp;
@@ -28,6 +29,7 @@
using ::android::hardware::hidl_vec;
using ::android::hardware::Return;
using ::android::hardware::Void;
+using ::android::hardware::wifi::supplicant::V1_0::IfaceType;
using ::android::hardware::wifi::supplicant::V1_0::ISupplicantStaIface;
using ::android::hardware::wifi::supplicant::V1_0::ISupplicantStaIfaceCallback;
using ::android::hardware::wifi::supplicant::V1_0::ISupplicantStaNetwork;
@@ -163,6 +165,26 @@
}
/*
+ * GetName
+ */
+TEST_F(SupplicantStaIfaceHidlTest, GetName) {
+ const auto& status_and_interface_name = HIDL_INVOKE(sta_iface_, getName);
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS,
+ status_and_interface_name.first.code);
+ EXPECT_FALSE(std::string(status_and_interface_name.second).empty());
+}
+
+/*
+ * GetType
+ */
+TEST_F(SupplicantStaIfaceHidlTest, GetType) {
+ const auto& status_and_interface_type = HIDL_INVOKE(sta_iface_, getType);
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS,
+ status_and_interface_type.first.code);
+ EXPECT_EQ(status_and_interface_type.second, IfaceType::STA);
+}
+
+/*
* listNetworks.
*/
TEST_F(SupplicantStaIfaceHidlTest, listNetworks) {
diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_sta_network_hidl_test.cpp b/wifi/supplicant/1.0/vts/functional/supplicant_sta_network_hidl_test.cpp
index aa84e9a..832dd41 100644
--- a/wifi/supplicant/1.0/vts/functional/supplicant_sta_network_hidl_test.cpp
+++ b/wifi/supplicant/1.0/vts/functional/supplicant_sta_network_hidl_test.cpp
@@ -22,6 +22,7 @@
#include <android/hardware/wifi/supplicant/1.0/ISupplicantStaNetwork.h>
+#include "supplicant_hidl_call_util.h"
#include "supplicant_hidl_test_utils.h"
using ::android::sp;
@@ -30,6 +31,7 @@
using ::android::hardware::hidl_vec;
using ::android::hardware::Return;
using ::android::hardware::Void;
+using ::android::hardware::wifi::supplicant::V1_0::IfaceType;
using ::android::hardware::wifi::supplicant::V1_0::ISupplicantStaIface;
using ::android::hardware::wifi::supplicant::V1_0::ISupplicantStaNetwork;
using ::android::hardware::wifi::supplicant::V1_0::
@@ -39,7 +41,7 @@
namespace {
constexpr char kTestSsidStr[] = "TestSsid1234";
-constexpr char kTestPsk[] = "TestPsk123";
+constexpr char kTestPskPassphrase[] = "TestPsk123";
constexpr char kTestIdStr[] = "TestIdstr";
constexpr char kTestEapPasswdStr[] = "TestEapPasswd1234";
constexpr char kTestEapCert[] = "keystore://CERT";
@@ -54,7 +56,10 @@
constexpr uint8_t kTestIk[] = {[0 ... 15] = 0x65};
constexpr uint8_t kTestCk[] = {[0 ... 15] = 0x45};
constexpr uint8_t kTestIdentity[] = {0x45, 0x67, 0x98, 0x67, 0x56};
+constexpr uint8_t kTestPsk[] = {[0 ... 31] = 0x12};
+constexpr uint8_t kTestAutParam[] = {[0 ... 13] = 0xe1};
constexpr uint32_t kTestWepTxKeyIdx = 2;
+constexpr uint32_t kTestUpdateIdentifier = 21;
constexpr uint32_t kTestKeyMgmt = (ISupplicantStaNetwork::KeyMgmtMask::WPA_PSK |
ISupplicantStaNetwork::KeyMgmtMask::WPA_EAP);
constexpr uint32_t kTestProto = (ISupplicantStaNetwork::ProtoMask::OSEN |
@@ -137,6 +142,27 @@
});
}
+/*
+ * GetInterfaceName
+ */
+TEST_F(SupplicantStaNetworkHidlTest, GetInterfaceName) {
+ const auto& status_and_interface_name =
+ HIDL_INVOKE(sta_network_, getInterfaceName);
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS,
+ status_and_interface_name.first.code);
+ EXPECT_FALSE(std::string(status_and_interface_name.second).empty());
+}
+
+/*
+ * GetType
+ */
+TEST_F(SupplicantStaNetworkHidlTest, GetType) {
+ const auto& status_and_interface_type = HIDL_INVOKE(sta_network_, getType);
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS,
+ status_and_interface_type.first.code);
+ EXPECT_EQ(status_and_interface_type.second, IfaceType::STA);
+}
+
/* Tests out the various setter/getter methods. */
/*
* SetGetSsid
@@ -246,17 +272,29 @@
*/
TEST_F(SupplicantStaNetworkHidlTest, SetGetPskPassphrase) {
sta_network_->setPskPassphrase(
- kTestPsk, [](const SupplicantStatus& status) {
+ kTestPskPassphrase, [](const SupplicantStatus& status) {
EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
});
sta_network_->getPskPassphrase(
[&](const SupplicantStatus& status, const hidl_string& psk) {
EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
- EXPECT_EQ(kTestPsk, std::string(psk.c_str()));
+ EXPECT_EQ(kTestPskPassphrase, std::string(psk.c_str()));
});
}
/*
+ * SetGetPsk
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SetGetPsk) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS,
+ HIDL_INVOKE(sta_network_, setPsk, kTestPsk).code);
+ const auto& status_and_psk = HIDL_INVOKE(sta_network_, getPsk);
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status_and_psk.first.code);
+ hidl_array<uint8_t, 32> expected_psk(kTestPsk);
+ EXPECT_EQ(expected_psk, status_and_psk.second);
+}
+
+/*
* SetGetWepKeys
*/
TEST_F(SupplicantStaNetworkHidlTest, SetGetWepTxKeyIdx) {
@@ -361,6 +399,12 @@
* SetGetEapPhase2Method
*/
TEST_F(SupplicantStaNetworkHidlTest, SetGetEapPhase2Method) {
+ ISupplicantStaNetwork::EapMethod set_eap_method =
+ ISupplicantStaNetwork::EapMethod::PEAP;
+ sta_network_->setEapMethod(
+ set_eap_method, [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
ISupplicantStaNetwork::EapPhase2Method set_eap_phase2_method =
ISupplicantStaNetwork::EapPhase2Method::NONE;
sta_network_->setEapPhase2Method(
@@ -500,6 +544,21 @@
}
/*
+ * SetGetEapSubjectMatch
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SetGetEapSubjectMatch) {
+ EXPECT_EQ(
+ SupplicantStatusCode::SUCCESS,
+ HIDL_INVOKE(sta_network_, setEapSubjectMatch, kTestEapMatch).code);
+ const auto& status_and_subject_match =
+ HIDL_INVOKE(sta_network_, getEapSubjectMatch);
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS,
+ status_and_subject_match.first.code);
+ EXPECT_EQ(kTestEapMatch,
+ std::string(status_and_subject_match.second.c_str()));
+}
+
+/*
* SetGetEapDomainSuffixMatch
*/
TEST_F(SupplicantStaNetworkHidlTest, SetGetEapDomainSuffixMatch) {
@@ -634,6 +693,14 @@
}
/*
+ * SendNetworkEapSimGsmAuthFailure
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SendNetworkEapSimGsmAuthFailure) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS,
+ HIDL_INVOKE(sta_network_, sendNetworkEapSimGsmAuthFailure).code);
+}
+
+/*
* SendNetworkEapSimUmtsAuthResponse
*/
TEST_F(SupplicantStaNetworkHidlTest, SendNetworkEapSimUmtsAuthResponse) {
@@ -648,6 +715,24 @@
}
/*
+ * SendNetworkEapSimUmtsAuthFailure
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SendNetworkEapSimUmtsAuthFailure) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS,
+ HIDL_INVOKE(sta_network_, sendNetworkEapSimUmtsAuthFailure).code);
+}
+
+/*
+ * SendNetworkEapSimUmtsAutsResponse
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SendNetworkEapSimUmtsAutsResponse) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS,
+ HIDL_INVOKE(sta_network_, sendNetworkEapSimUmtsAutsResponse,
+ kTestAutParam)
+ .code);
+}
+
+/*
* SendNetworkEapIdentityResponse
*/
TEST_F(SupplicantStaNetworkHidlTest, SendNetworkEapIdentityResponse) {
@@ -658,3 +743,40 @@
EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
});
}
+
+/*
+ * SetUpdateIdentifier
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SetUpdateIdentifier) {
+ EXPECT_EQ(
+ SupplicantStatusCode::SUCCESS,
+ HIDL_INVOKE(sta_network_, setUpdateIdentifier, kTestUpdateIdentifier)
+ .code);
+}
+
+/*
+ * SetProactiveKeyCaching
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SetProactiveKeyCaching) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS,
+ HIDL_INVOKE(sta_network_, setProactiveKeyCaching, true).code);
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS,
+ HIDL_INVOKE(sta_network_, setProactiveKeyCaching, false).code);
+}
+
+/*
+ * GetWpsNfcConfigurationToken
+ */
+TEST_F(SupplicantStaNetworkHidlTest, GetWpsNfcConfigurationToken) {
+ ASSERT_EQ(SupplicantStatusCode::SUCCESS,
+ HIDL_INVOKE(sta_network_, setSsid, ssid_).code);
+ ASSERT_EQ(SupplicantStatusCode::SUCCESS,
+ HIDL_INVOKE(sta_network_, setKeyMgmt, kTestKeyMgmt).code);
+ ASSERT_EQ(
+ SupplicantStatusCode::SUCCESS,
+ HIDL_INVOKE(sta_network_, setPskPassphrase, kTestPskPassphrase).code);
+ const auto& status_and_token =
+ HIDL_INVOKE(sta_network_, getWpsNfcConfigurationToken);
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status_and_token.first.code);
+ EXPECT_FALSE(0 == status_and_token.second.size());
+}