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

Commit 22f9fcae authored by Biswarup Pal's avatar Biswarup Pal
Browse files

Do not add fake output stream for virtual camera

... and enable virtual camera to support the configuration
of zero streams.

Test: atest CtsVirtualDevicesCameraTestCases
Test: atest CtsVirtualDevicesCameraCtsTestCases
Test: atest CtsCameraTestCases
Test: atest virtual_camera_tests
Fixes: 375029101
Flag: EXEMPT bugfix
Change-Id: I747ea03a182c7d35e73e3f4dafd1b5757a41e49a
parent 6b2624ab
Loading
Loading
Loading
Loading
+1 −10
Original line number Diff line number Diff line
@@ -97,16 +97,7 @@ namespace {
    const char* kVirtualDeviceFrontCameraId = "1";
    const char* kUnknownPackageName = "<unknown>";

    int32_t getDeviceId(const android::CameraMetadata& cameraInfo) {
        if (!cameraInfo.exists(ANDROID_INFO_DEVICE_ID)) {
            return android::kDefaultDeviceId;
        }

        const auto &deviceIdEntry = cameraInfo.find(ANDROID_INFO_DEVICE_ID);
        return deviceIdEntry.data.i32[0];
    }

    static android::PermissionChecker::PermissionResult appOpModeToPermissionResult(int32_t res) {
    android::PermissionChecker::PermissionResult appOpModeToPermissionResult(int32_t res) {
        switch (res) {
            case android::AppOpsManager::MODE_ERRORED:
                return android::PermissionChecker::PERMISSION_HARD_DENIED;
+18 −6
Original line number Diff line number Diff line
@@ -89,6 +89,16 @@ namespace wm_flags = com::android::window::flags;

namespace android {

namespace {

bool shouldInjectFakeStream(const CameraMetadata& info) {
    // Do not inject fake stream for a virtual camera (i.e., camera belonging to virtual devices),
    // as it can handle zero streams properly.
    return getDeviceId(info) == kDefaultDeviceId;
}

} // namespace

Camera3Device::Camera3Device(std::shared_ptr<CameraServiceProxyWrapper>& cameraServiceProxyWrapper,
        std::shared_ptr<AttributionAndPermissionUtils> attributionAndPermissionUtils,
        const std::string &id, bool overrideForPerfClass, int rotationOverride,
@@ -2502,12 +2512,14 @@ status_t Camera3Device::configureStreamsLocked(int operatingMode,

    // Workaround for device HALv3.2 or older spec bug - zero streams requires
    // adding a fake stream instead.
    // TODO: Bug: 17321404 for fixing the HAL spec and removing this workaround.
    // TODO(b/17321404): Fix the HAL spec and remove this workaround.
    if (shouldInjectFakeStream(mDeviceInfo)) {
        if (mOutputStreams.size() == 0) {
            addFakeStreamLocked();
        } else {
            tryRemoveFakeStreamLocked();
        }
    }

    // Override stream use case based on "adb shell command"
    overrideStreamUseCaseLocked();
@@ -5914,4 +5926,4 @@ status_t Camera3Device::deriveAndSetTransformLocked(
    return OK;
}

}; // namespace android
} // namespace android
+11 −0
Original line number Diff line number Diff line
@@ -23,6 +23,8 @@
#include <utils/Log.h>
#include <vendorsupport/api_level.h>

#include <camera/CameraUtils.h>

namespace android {

int getVNDKVersionFromProp(int defaultVersion) {
@@ -38,6 +40,15 @@ int getVNDKVersionFromProp(int defaultVersion) {
    return AVendorSupport_getSdkApiLevelOf(vendorApiLevel);
}

int32_t getDeviceId(const CameraMetadata& cameraInfo) {
    if (!cameraInfo.exists(ANDROID_INFO_DEVICE_ID)) {
        return kDefaultDeviceId;
    }

    const auto &deviceIdEntry = cameraInfo.find(ANDROID_INFO_DEVICE_ID);
    return deviceIdEntry.data.i32[0];
}

RunThreadWithRealtimePriority::RunThreadWithRealtimePriority(int tid)
    : mTid(tid), mPreviousPolicy(sched_getscheduler(tid)) {
    auto res = sched_getparam(mTid, &mPreviousParams);
+8 −0
Original line number Diff line number Diff line
@@ -21,6 +21,8 @@
#include <unistd.h>
#include <type_traits>

#include <camera/CameraMetadata.h>

namespace android {

/**
@@ -42,6 +44,12 @@ constexpr std::underlying_type_t<Enum> eToI(Enum val) {
 */
int getVNDKVersionFromProp(int defaultVersion);

/**
 * Returns the deviceId for the given camera metadata. For any virtual camera, this is the id
 * of the virtual device owning the camera. For any real camera, this is kDefaultDeviceId.
 */
int32_t getDeviceId(const CameraMetadata& cameraInfo);

/**
 * An instance of this class will raise the scheduling policy of a given
 * given thread to real time and keep it this way throughout the lifetime
+15 −14
Original line number Diff line number Diff line
@@ -94,9 +94,6 @@ using ::android::base::unique_fd;

namespace {

using metadata_ptr =
    std::unique_ptr<camera_metadata_t, void (*)(camera_metadata_t*)>;

using namespace std::chrono_literals;

// Size of request/result metadata fast message queue.
@@ -106,8 +103,7 @@ constexpr size_t kMetadataMsgQueueSize = 0;
// Maximum number of buffers to use per single stream.
constexpr size_t kMaxStreamBuffers = 2;

// Thumbnail size (0,0) correspods to disabling thumbnail.
const Resolution kDefaultJpegThumbnailSize(0, 0);
constexpr int kInvalidStreamId = -1;

camera_metadata_enum_android_control_capture_intent_t requestTemplateToIntent(
    const RequestTemplate type) {
@@ -291,7 +287,7 @@ RequestSettings createSettingsFromMetadata(const CameraMetadata& metadata) {
      .aePrecaptureTrigger = getPrecaptureTrigger(metadata)};
}

}  // namespace
};  // namespace

VirtualCameraSession::VirtualCameraSession(
    std::shared_ptr<VirtualCameraDevice> cameraDevice,
@@ -299,7 +295,8 @@ VirtualCameraSession::VirtualCameraSession(
    std::shared_ptr<IVirtualCameraCallback> virtualCameraClientCallback)
    : mCameraDevice(cameraDevice),
      mCameraDeviceCallback(cameraDeviceCallback),
      mVirtualCameraClientCallback(virtualCameraClientCallback) {
      mVirtualCameraClientCallback(virtualCameraClientCallback),
      mCurrentInputStreamId(kInvalidStreamId) {
  mRequestMetadataQueue = std::make_unique<RequestMetadataQueue>(
      kMetadataMsgQueueSize, false /* non blocking */);
  if (!mRequestMetadataQueue->isValid()) {
@@ -318,13 +315,15 @@ ndk::ScopedAStatus VirtualCameraSession::close() {
  {
    std::lock_guard<std::mutex> lock(mLock);

    if (mVirtualCameraClientCallback != nullptr) {
      mVirtualCameraClientCallback->onStreamClosed(mCurrentInputStreamId);
    }

    if (mRenderThread != nullptr) {
      mRenderThread->flush();
      mRenderThread->stop();
      mRenderThread = nullptr;

      if (mVirtualCameraClientCallback != nullptr) {
        mVirtualCameraClientCallback->onStreamClosed(mCurrentInputStreamId);
      }
      mCurrentInputStreamId = kInvalidStreamId;
    }
  }

@@ -357,7 +356,11 @@ ndk::ScopedAStatus VirtualCameraSession::configureStreams(
  halStreams.resize(in_requestedConfiguration.streams.size());

  if (!virtualCamera->isStreamCombinationSupported(in_requestedConfiguration)) {
    ALOGE("%s: Requested stream configuration is not supported", __func__);
    ALOGE(
        "%s: Requested stream configuration is not supported, closing existing "
        "session",
        __func__);
    close();
    return cameraStatus(Status::ILLEGAL_ARGUMENT);
  }

@@ -466,13 +469,11 @@ ndk::ScopedAStatus VirtualCameraSession::constructDefaultRequestSettings(
      // Don't support VIDEO_SNAPSHOT, MANUAL, ZSL templates
      return ndk::ScopedAStatus::fromServiceSpecificError(
          static_cast<int32_t>(Status::ILLEGAL_ARGUMENT));
      ;
    default:
      ALOGE("%s: unknown request template type %d", __FUNCTION__,
            static_cast<int>(in_type));
      return ndk::ScopedAStatus::fromServiceSpecificError(
          static_cast<int32_t>(Status::ILLEGAL_ARGUMENT));
      ;
  }
}

Loading