Sensor direct report test - gralloc support

Bug: 37794556
Test: sensor vts passes on 2016 and 2017 devices
Change-Id: Ibe1d076c24dc2cfe61dfd19aa5055c9075aa9e14
diff --git a/sensors/1.0/vts/functional/GrallocWrapper.cpp b/sensors/1.0/vts/functional/GrallocWrapper.cpp
new file mode 100644
index 0000000..e422d62
--- /dev/null
+++ b/sensors/1.0/vts/functional/GrallocWrapper.cpp
@@ -0,0 +1,232 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "GrallocWrapper"
+
+#include "GrallocWrapper.h"
+
+#include <utils/Log.h>
+
+namespace android {
+
+GrallocWrapper::GrallocWrapper() { init(); }
+
+void GrallocWrapper::init() {
+  mAllocator = allocator2::IAllocator::getService();
+  if (mAllocator == nullptr) {
+    ALOGE("Failed to get allocator service");
+  }
+
+  mMapper = mapper2::IMapper::getService();
+  if (mMapper == nullptr) {
+    ALOGE("Failed to get mapper service");
+  }
+  if (mMapper->isRemote()) {
+    ALOGE("Mapper is not in passthrough mode");
+  }
+}
+
+GrallocWrapper::~GrallocWrapper() {
+  for (auto bufferHandle : mClonedBuffers) {
+    auto buffer = const_cast<native_handle_t*>(bufferHandle);
+    native_handle_close(buffer);
+    native_handle_delete(buffer);
+  }
+  mClonedBuffers.clear();
+
+  for (auto bufferHandle : mImportedBuffers) {
+    auto buffer = const_cast<native_handle_t*>(bufferHandle);
+    if (mMapper->freeBuffer(buffer) != mapper2::Error::NONE) {
+      ALOGE("Failed to free buffer %p", buffer);
+    }
+  }
+  mImportedBuffers.clear();
+}
+
+sp<allocator2::IAllocator> GrallocWrapper::getAllocator() const {
+  return mAllocator;
+}
+
+std::string GrallocWrapper::dumpDebugInfo() {
+  std::string debugInfo;
+  mAllocator->dumpDebugInfo(
+      [&](const auto& tmpDebugInfo) { debugInfo = tmpDebugInfo.c_str(); });
+
+  return debugInfo;
+}
+
+const native_handle_t* GrallocWrapper::cloneBuffer(
+    const hardware::hidl_handle& rawHandle) {
+  const native_handle_t* bufferHandle =
+      native_handle_clone(rawHandle.getNativeHandle());
+
+  if (bufferHandle) {
+    mClonedBuffers.insert(bufferHandle);
+  }
+  return bufferHandle;
+}
+
+std::vector<const native_handle_t*> GrallocWrapper::allocate(
+    const mapper2::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) {
+        if (mapper2::Error::NONE != tmpError) {
+          ALOGE("Failed to allocate buffers");
+        }
+        if (count != tmpBuffers.size()) {
+          ALOGE("Invalid buffer array");
+        }
+
+        for (uint32_t i = 0; i < count; i++) {
+          if (import) {
+            bufferHandles.push_back(importBuffer(tmpBuffers[i]));
+          } else {
+            bufferHandles.push_back(cloneBuffer(tmpBuffers[i]));
+          }
+        }
+
+        if (outStride) {
+          *outStride = tmpStride;
+        }
+      });
+
+  return bufferHandles;
+}
+
+const native_handle_t* GrallocWrapper::allocate(
+    const mapper2::IMapper::BufferDescriptorInfo& descriptorInfo, bool import,
+    uint32_t* outStride) {
+  mapper2::BufferDescriptor descriptor = createDescriptor(descriptorInfo);
+  ALOGE("QQ");
+  auto buffers = allocate(descriptor, 1, import, outStride);
+  return buffers[0];
+}
+
+sp<mapper2::IMapper> GrallocWrapper::getMapper() const { return mMapper; }
+
+mapper2::BufferDescriptor GrallocWrapper::createDescriptor(
+    const mapper2::IMapper::BufferDescriptorInfo& descriptorInfo) {
+  mapper2::BufferDescriptor descriptor;
+  mMapper->createDescriptor(
+      descriptorInfo, [&](const auto& tmpError, const auto& tmpDescriptor) {
+        if (tmpError != mapper2::Error::NONE) {
+          ALOGE("Failed to create descriptor");
+        }
+        descriptor = tmpDescriptor;
+      });
+
+  return descriptor;
+}
+
+const native_handle_t* GrallocWrapper::importBuffer(
+    const hardware::hidl_handle& rawHandle) {
+  const native_handle_t* bufferHandle = nullptr;
+  mMapper->importBuffer(
+      rawHandle, [&](const auto& tmpError, const auto& tmpBuffer) {
+        if (tmpError != mapper2::Error::NONE) {
+          ALOGE("Failed to import buffer %p", rawHandle.getNativeHandle());
+        }
+        bufferHandle = static_cast<const native_handle_t*>(tmpBuffer);
+      });
+
+  if (bufferHandle) {
+    mImportedBuffers.insert(bufferHandle);
+  }
+
+  return bufferHandle;
+}
+
+void GrallocWrapper::freeBuffer(const native_handle_t* bufferHandle) {
+  auto buffer = const_cast<native_handle_t*>(bufferHandle);
+
+  if (mImportedBuffers.erase(bufferHandle)) {
+    mapper2::Error error = mMapper->freeBuffer(buffer);
+    if (error != mapper2::Error::NONE) {
+      ALOGE("Failed to free %p", buffer);
+    }
+  } else {
+    mClonedBuffers.erase(bufferHandle);
+    native_handle_close(buffer);
+    native_handle_delete(buffer);
+  }
+}
+
+void* GrallocWrapper::lock(const native_handle_t* bufferHandle,
+                           uint64_t cpuUsage,
+                           const mapper2::IMapper::Rect& accessRegion,
+                           int acquireFence) {
+  auto buffer = const_cast<native_handle_t*>(bufferHandle);
+
+  NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
+  hardware::hidl_handle acquireFenceHandle;
+  if (acquireFence >= 0) {
+    auto h = native_handle_init(acquireFenceStorage, 1, 0);
+    h->data[0] = acquireFence;
+    acquireFenceHandle = h;
+  }
+
+  void* data = nullptr;
+  mMapper->lock(buffer, cpuUsage, accessRegion, acquireFenceHandle,
+                [&](const auto& tmpError, const auto& tmpData) {
+                  if (tmpError != mapper2::Error::NONE) {
+                    ALOGE("Failed to lock buffer %p", buffer);
+                  }
+                  data = tmpData;
+                });
+
+  if (acquireFence >= 0) {
+    close(acquireFence);
+  }
+
+  return data;
+}
+
+int GrallocWrapper::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) {
+    if (tmpError != mapper2::Error::NONE) {
+      ALOGE("Failed to unlock buffer %p", buffer);
+    }
+
+    auto fenceHandle = tmpReleaseFence.getNativeHandle();
+    if (fenceHandle) {
+      if (fenceHandle->numInts != 0) {
+        ALOGE("Invalid fence handle %p", fenceHandle);
+      }
+      if (fenceHandle->numFds == 1) {
+        releaseFence = dup(fenceHandle->data[0]);
+        if (releaseFence < 0){
+          ALOGE("Failed to dup fence fd");
+        }
+      } else {
+        if (fenceHandle->numFds != 0) {
+          ALOGE("Invalid fence handle %p", fenceHandle);
+        }
+      }
+    }
+  });
+
+  return releaseFence;
+}
+
+}  // namespace android