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

Commit 15dcd133 authored by Biswarup Pal's avatar Biswarup Pal
Browse files

Support non-numerical id (with prefix) for virtual camera

This will ensure that virtual camera id's don't clash
with camera id's provided by any other HAL's. Also, this
should be fine as we currently don't expose virtual camera
id's to apps.

Test: atest CtsVirtualDevicesCameraTestCases
Test: atest virtual_camera_tests
Test: atest CtsVirtualDevicesCameraCtsTestCases
Flag: android.companion.virtual.flags.virtual_camera
Bug: 343404629
Change-Id: I304161eee08b144b82d31e8e9b8a9fcc2b9fc45c
parent ff1e5ee6
Loading
Loading
Loading
Loading
+7 −7
Original line number Diff line number Diff line
@@ -68,7 +68,7 @@ namespace {

using namespace std::chrono_literals;

// Prefix of camera name - "device@1.1/virtual/{numerical_id}"
// Prefix of camera name - "device@1.1/virtual/{camera_id}"
const char* kDevicePathPrefix = "device@1.1/virtual/";

constexpr int32_t kMaxJpegSize = 3 * 1024 * 1024 /*3MiB*/;
@@ -404,8 +404,8 @@ std::optional<CameraMetadata> initCameraCharacteristics(
}  // namespace

VirtualCameraDevice::VirtualCameraDevice(
    const uint32_t cameraId, const VirtualCameraConfiguration& configuration,
    int32_t deviceId)
    const std::string& cameraId,
    const VirtualCameraConfiguration& configuration, int32_t deviceId)
    : mCameraId(cameraId),
      mVirtualCameraClientCallback(configuration.virtualCameraCallback),
      mSupportedInputConfigurations(configuration.supportedStreamConfigs) {
@@ -582,11 +582,11 @@ ndk::ScopedAStatus VirtualCameraDevice::getTorchStrengthLevel(
}

binder_status_t VirtualCameraDevice::dump(int fd, const char**, uint32_t) {
  ALOGD("Dumping virtual camera %d", mCameraId);
  ALOGD("Dumping virtual camera %s", mCameraId.c_str());
  const char* indent = "  ";
  const char* doubleIndent = "    ";
  dprintf(fd, "%svirtual_camera %d belongs to virtual device %d\n", indent,
          mCameraId,
  dprintf(fd, "%svirtual_camera %s belongs to virtual device %d\n", indent,
          mCameraId.c_str(),
          getDeviceId(mCameraCharacteristics)
              .value_or(VirtualCameraService::kDefaultDeviceId));
  dprintf(fd, "%sSupportedStreamConfiguration:\n", indent);
@@ -597,7 +597,7 @@ binder_status_t VirtualCameraDevice::dump(int fd, const char**, uint32_t) {
}

std::string VirtualCameraDevice::getCameraName() const {
  return std::string(kDevicePathPrefix) + std::to_string(mCameraId);
  return std::string(kDevicePathPrefix) + mCameraId;
}

const std::vector<SupportedStreamConfiguration>&
+6 −4
Original line number Diff line number Diff line
@@ -37,7 +37,7 @@ class VirtualCameraDevice
    : public ::aidl::android::hardware::camera::device::BnCameraDevice {
 public:
  explicit VirtualCameraDevice(
      uint32_t cameraId,
      const std::string& cameraId,
      const aidl::android::companion::virtualcamera::VirtualCameraConfiguration&
          configuration,
      int32_t deviceId);
@@ -92,10 +92,12 @@ class VirtualCameraDevice
  binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;

  // Returns unique virtual camera name in form
  // "device@{major}.{minor}/virtual/{numerical_id}"
  // "device@{major}.{minor}/virtual/{camera_id}"
  std::string getCameraName() const;

  uint32_t getCameraId() const { return mCameraId; }
  const std::string& getCameraId() const {
    return mCameraId;
  }

  const std::vector<
      aidl::android::companion::virtualcamera::SupportedStreamConfiguration>&
@@ -138,7 +140,7 @@ class VirtualCameraDevice
 private:
  std::shared_ptr<VirtualCameraDevice> sharedFromThis();

  const uint32_t mCameraId;
  const std::string mCameraId;
  const std::shared_ptr<
      ::aidl::android::companion::virtualcamera::IVirtualCameraCallback>
      mVirtualCameraClientCallback;
+4 −5
Original line number Diff line number Diff line
@@ -150,11 +150,10 @@ ndk::ScopedAStatus VirtualCameraProvider::isConcurrentStreamCombinationSupported
}

std::shared_ptr<VirtualCameraDevice> VirtualCameraProvider::createCamera(
    const VirtualCameraConfiguration& configuration, const int cameraId,
    const int32_t deviceId) {
  if (cameraId < 0) {
    ALOGE("%s: Cannot create camera with negative id. cameraId: %d", __func__,
          cameraId);
    const VirtualCameraConfiguration& configuration,
    const std::string& cameraId, const int32_t deviceId) {
  if (cameraId.empty()) {
    ALOGE("%s: Cannot create camera with empty cameraId", __func__);
    return nullptr;
  }

+1 −1
Original line number Diff line number Diff line
@@ -77,7 +77,7 @@ class VirtualCameraProvider
  std::shared_ptr<VirtualCameraDevice> createCamera(
      const aidl::android::companion::virtualcamera::VirtualCameraConfiguration&
          configuration,
      int cameraId, int32_t deviceId);
      const std::string& cameraId, int32_t deviceId);

  std::shared_ptr<VirtualCameraDevice> getCamera(const std::string& name);

+20 −14
Original line number Diff line number Diff line
@@ -57,12 +57,9 @@ using ::aidl::android::companion::virtualcamera::SensorOrientation;
using ::aidl::android::companion::virtualcamera::SupportedStreamConfiguration;
using ::aidl::android::companion::virtualcamera::VirtualCameraConfiguration;

// TODO(b/301023410) Make camera id range configurable / dynamic
// based on already registered devices.
std::atomic_int VirtualCameraService::sNextId{1000};

namespace {

constexpr char kCameraIdPrefix[] = "v";
constexpr int kVgaWidth = 640;
constexpr int kVgaHeight = 480;
constexpr int kMaxFps = 60;
@@ -90,6 +87,9 @@ constexpr std::array<const char*, 3> kRequiredEglExtensions = {
    "GL_EXT_YUV_target",
};

// Numerical portion for id to assign to next created camera.
static std::atomic_int sNextIdNumericalPortion{1000};

ndk::ScopedAStatus validateConfiguration(
    const VirtualCameraConfiguration& configuration) {
  if (configuration.supportedStreamConfigs.empty()) {
@@ -192,7 +192,7 @@ std::variant<CommandWithOptions, std::string> parseCommand(
  }

  return cmd;
};
}

ndk::ScopedAStatus verifyRequiredEglExtensions() {
  EglDisplayContext context;
@@ -211,6 +211,11 @@ ndk::ScopedAStatus verifyRequiredEglExtensions() {
  return ndk::ScopedAStatus::ok();
}

std::string createCameraId(const int32_t deviceId) {
  return kCameraIdPrefix + std::to_string(deviceId) + "_" +
         std::to_string(sNextIdNumericalPortion++);
}

}  // namespace

VirtualCameraService::VirtualCameraService(
@@ -224,13 +229,14 @@ ndk::ScopedAStatus VirtualCameraService::registerCamera(
    const ::ndk::SpAIBinder& token,
    const VirtualCameraConfiguration& configuration, const int32_t deviceId,
    bool* _aidl_return) {
  return registerCamera(token, configuration, sNextId++, deviceId, _aidl_return);
  return registerCamera(token, configuration, createCameraId(deviceId),
                        deviceId, _aidl_return);
}

ndk::ScopedAStatus VirtualCameraService::registerCamera(
    const ::ndk::SpAIBinder& token,
    const VirtualCameraConfiguration& configuration, const int cameraId,
    const int32_t deviceId, bool* _aidl_return) {
    const VirtualCameraConfiguration& configuration,
    const std::string& cameraId, const int32_t deviceId, bool* _aidl_return) {
  if (!mPermissionProxy.checkCallingPermission(kCreateVirtualDevicePermission)) {
    ALOGE("%s: caller (pid %d, uid %d) doesn't hold %s permission", __func__,
          getpid(), getuid(), kCreateVirtualDevicePermission);
@@ -308,7 +314,7 @@ ndk::ScopedAStatus VirtualCameraService::unregisterCamera(
}

ndk::ScopedAStatus VirtualCameraService::getCameraId(
    const ::ndk::SpAIBinder& token, int32_t* _aidl_return) {
    const ::ndk::SpAIBinder& token, std::string* _aidl_return) {
  if (!mPermissionProxy.checkCallingPermission(kCreateVirtualDevicePermission)) {
    ALOGE("%s: caller (pid %d, uid %d) doesn't hold %s permission", __func__,
          getpid(), getuid(), kCreateVirtualDevicePermission);
@@ -400,13 +406,12 @@ binder_status_t VirtualCameraService::enableTestCameraCmd(
    return STATUS_OK;
  }

  std::optional<int> cameraId;
  std::optional<std::string> cameraId;
  auto it = options.find("camera_id");
  if (it != options.end()) {
    cameraId = parseInt(it->second);
    cameraId = it->second;
    if (!cameraId.has_value()) {
      dprintf(err, "Invalid camera_id: %s\n, must be number > 0",
              it->second.c_str());
      dprintf(err, "Invalid camera_id: %s", it->second.c_str());
      return STATUS_BAD_VALUE;
    }
  }
@@ -447,7 +452,8 @@ binder_status_t VirtualCameraService::enableTestCameraCmd(
  configuration.virtualCameraCallback =
      ndk::SharedRefBase::make<VirtualCameraTestInstance>(
          inputFps.value_or(kTestCameraDefaultInputFps));
  registerCamera(mTestCameraToken, configuration, cameraId.value_or(sNextId++),
  registerCamera(mTestCameraToken, configuration,
                 cameraId.value_or(std::to_string(sNextIdNumericalPortion++)),
                 kDefaultDeviceId, &ret);
  if (ret) {
    dprintf(out, "Successfully registered test camera %s\n",
Loading