Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9543c7f1 authored by Biswarup Pal's avatar Biswarup Pal
Browse files

Check hardware buffer support for virtual camera creation

Bug: 382230255
Flag: EXEMPT minor fix
Test: atest virtual_camera_tests
Test: atest CtsVirtualDevicesCameraCtsTestCases
Change-Id: I46aee1c33dd805286a80bc2469b980219af3163d
parent 2177359d
Loading
Loading
Loading
Loading
+7 −9
Original line number Diff line number Diff line
@@ -139,13 +139,11 @@ NotifyMsg createRequestErrorNotifyMsg(int frameNumber) {

std::shared_ptr<EglFrameBuffer> allocateTemporaryFramebuffer(
    EGLDisplay eglDisplay, const uint width, const int height) {
  const AHardwareBuffer_Desc desc{
      .width = static_cast<uint32_t>(width),
  const AHardwareBuffer_Desc desc{.width = static_cast<uint32_t>(width),
                                  .height = static_cast<uint32_t>(height),
                                  .layers = 1,
      .format = AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420,
      .usage = AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER |
               AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN,
                                  .format = kHardwareBufferFormat,
                                  .usage = kHardwareBufferUsage,
                                  .rfu0 = 0,
                                  .rfu1 = 0};

+31 −2
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@
#include "android/binder_interface_utils.h"
#include "android/binder_libbinder.h"
#include "android/binder_status.h"
#include "android/hardware_buffer.h"
#include "binder/Status.h"
#include "fmt/format.h"
#include "util/EglDisplayContext.h"
@@ -213,6 +214,27 @@ ndk::ScopedAStatus verifyRequiredEglExtensions() {
  return ndk::ScopedAStatus::ok();
}

ndk::ScopedAStatus verifyHardwareBufferSupport() {
  static constexpr AHardwareBuffer_Desc desc{
      .width = static_cast<uint32_t>(kVgaWidth),
      .height = static_cast<uint32_t>(kVgaHeight),
      .layers = 1,
      .format = kHardwareBufferFormat,
      .usage = kHardwareBufferUsage,
      .rfu0 = 0,
      .rfu1 = 0};
  if (AHardwareBuffer_isSupported(&desc)) {
    return ndk::ScopedAStatus::ok();
  }
  ALOGE("%s: Hardware buffer allocation is unsupported for required formats",
        __func__);
  return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
      EX_UNSUPPORTED_OPERATION,
      fmt::format("Cannot create virtual camera, because hardware buffer "
                  "allocation is unsupported")
          .c_str());
}

std::string createCameraId(const int32_t deviceId) {
  return kCameraIdPrefix + std::to_string(deviceId) + "_" +
         std::to_string(sNextIdNumericalPortion++);
@@ -255,12 +277,18 @@ ndk::ScopedAStatus VirtualCameraService::registerCameraNoCheck(
        Status::EX_ILLEGAL_ARGUMENT);
  }

  if (mVerifyEglExtensions) {
  if (mCheckHardwareRequirements) {
    auto status = verifyRequiredEglExtensions();
    if (!status.isOk()) {
      *_aidl_return = false;
      return status;
    }

    status = verifyHardwareBufferSupport();
    if (!status.isOk()) {
      *_aidl_return = false;
      return status;
    }
  }

  auto status = validateConfiguration(configuration);
@@ -492,7 +520,8 @@ binder_status_t VirtualCameraService::enableTestCameraCmd(
      kDefaultDeviceId, &ret);
  if (!ret) {
    dprintf(err, "Failed to create test camera (error %d)\n", ret);
    return ret;
    mTestCameraToken.set(nullptr);
    return STATUS_UNKNOWN_ERROR;
  }

  dprintf(out, "Successfully registered test camera %s\n",
+5 −5
Original line number Diff line number Diff line
@@ -71,10 +71,10 @@ class VirtualCameraService
  binder_status_t handleShellCommand(int in, int out, int err, const char** args,
                                     uint32_t numArgs) override;

  // Do not verify presence on required EGL extensions when registering virtual
  // camera. Only to be used by unit tests.
  void disableEglVerificationForTest() {
    mVerifyEglExtensions = false;
  // Do not check hardware requirements when registering virtual camera.
  // Only to be used by unit tests.
  void disableHardwareRequirementsCheck() {
    mCheckHardwareRequirements = false;
  }

  // Default virtual device id (the host device id)
@@ -97,7 +97,7 @@ class VirtualCameraService
      EXCLUDES(mLock);

  std::shared_ptr<VirtualCameraProvider> mVirtualCameraProvider;
  bool mVerifyEglExtensions = true;
  bool mCheckHardwareRequirements = true;
  const PermissionsProxy& mPermissionProxy;

  std::mutex mLock;
+1 −1
Original line number Diff line number Diff line
@@ -133,7 +133,7 @@ class VirtualCameraServiceTest : public ::testing::Test {
    mCameraProvider->setCallback(mMockCameraProviderCallback);
    mCameraService = ndk::SharedRefBase::make<VirtualCameraService>(
        mCameraProvider, mMockPermissionsProxy);
    mCameraService->disableEglVerificationForTest();
    mCameraService->disableHardwareRequirementsCheck();

    ON_CALL(mMockPermissionsProxy, checkCallingPermission)
        .WillByDefault(Return(true));
+4 −0
Original line number Diff line number Diff line
@@ -35,6 +35,10 @@ namespace android {
namespace companion {
namespace virtualcamera {

constexpr int kHardwareBufferUsage = AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER |
                                     AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN;
constexpr int kHardwareBufferFormat = AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420;

// RAII utility class to safely lock AHardwareBuffer and obtain android_ycbcr
// structure describing YUV plane layout.
//