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

Commit 11f409a8 authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 8035399 from c40bae7d to tm-release

Change-Id: I2d203a83dabb0040981c833d05708913ce9fe237
parents 4b75d5c8 c40bae7d
Loading
Loading
Loading
Loading
+265 −10
Original line number Diff line number Diff line
@@ -907,7 +907,7 @@ public:

    static Status getMandatoryConcurrentStreams(const camera_metadata_t* staticMeta,
                                                std::vector<AvailableStream>* outputStreams);

    static bool supportsPreviewStabilization(const std::string& name, sp<ICameraProvider> provider);
    static Status getJpegBufferSize(camera_metadata_t *staticMeta,
            uint32_t* outBufSize);
    static Status isConstrainedModeAvailable(camera_metadata_t *staticMeta);
@@ -955,6 +955,9 @@ public:

    void processCaptureRequestInternal(uint64_t bufferusage, RequestTemplate reqTemplate,
                                       bool useSecureOnlyCameras);
    void processPreviewStabilizationCaptureRequestInternal(
            bool previewStabilizationOn,
            /*inout*/ std::unordered_map<std::string, nsecs_t>& cameraDeviceToTimeLag);

    // Used by switchToOffline where a new result queue is created for offline reqs
    void updateInflightResultQueue(std::shared_ptr<ResultMetadataQueue> resultQueue);
@@ -1008,7 +1011,11 @@ protected:

        // Buffers are added by process_capture_result when output buffers
        // return from HAL but framework.
        ::android::Vector<StreamBuffer> resultOutputBuffers;
        struct StreamBufferAndTimestamp {
            StreamBuffer buffer;
            nsecs_t timeStamp;
        };
        ::android::Vector<StreamBufferAndTimestamp> resultOutputBuffers;

        std::unordered_set<std::string> expectedPhysicalResults;

@@ -1423,8 +1430,25 @@ bool CameraHidlTest::DeviceCb::processCaptureResultLocked(const CaptureResult& r
        return notify;
    }

    request->resultOutputBuffers.appendArray(results.outputBuffers.data(),
            results.outputBuffers.size());
    for (const auto& buffer : results.outputBuffers) {
        // wait for the fence timestamp and store it along with the buffer
        // TODO: Check if we really need the dup here
        sp<android::Fence> releaseFence = nullptr;
        if (buffer.releaseFence && (buffer.releaseFence->numFds == 1) &&
            buffer.releaseFence->data[0] >= 0) {
            releaseFence = new android::Fence(dup(buffer.releaseFence->data[0]));
        }
        InFlightRequest::StreamBufferAndTimestamp streamBufferAndTimestamp;
        streamBufferAndTimestamp.buffer = buffer;
        streamBufferAndTimestamp.timeStamp = systemTime();
        if (releaseFence && releaseFence->isValid()) {
            releaseFence->wait(/*ms*/ 300);
            nsecs_t releaseTime = releaseFence->getSignalTime();
            if (streamBufferAndTimestamp.timeStamp < releaseTime)
                streamBufferAndTimestamp.timeStamp = releaseTime;
        }
        request->resultOutputBuffers.push_back(streamBufferAndTimestamp);
    }
    // If shutter event is received notify the pending threads.
    if (request->shutterTimestamp != 0) {
        notify = true;
@@ -4926,7 +4950,7 @@ void CameraHidlTest::processCaptureRequestInternal(uint64_t bufferUsage,

            ASSERT_FALSE(inflightReq.errorCodeValid);
            ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u);
            ASSERT_EQ(testStream.id, inflightReq.resultOutputBuffers[0].streamId);
            ASSERT_EQ(testStream.id, inflightReq.resultOutputBuffers[0].buffer.streamId);

            // For camera device 3.8 or newer, shutterReadoutTimestamp must be
            // available, and it must be >= shutterTimestamp + exposureTime, and
@@ -4986,7 +5010,197 @@ void CameraHidlTest::processCaptureRequestInternal(uint64_t bufferUsage,

            ASSERT_FALSE(inflightReq.errorCodeValid);
            ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u);
            ASSERT_EQ(testStream.id, inflightReq.resultOutputBuffers[0].streamId);
            ASSERT_EQ(testStream.id, inflightReq.resultOutputBuffers[0].buffer.streamId);
        }

        if (useHalBufManager) {
            verifyBuffersReturned(session, deviceVersion, testStream.id, cb);
        }

        ret = session->close();
        ASSERT_TRUE(ret.isOk());
    }
}

TEST_P(CameraHidlTest, processCaptureRequestPreviewStabilization) {
    std::unordered_map<std::string, nsecs_t> cameraDeviceToTimeLag;
    processPreviewStabilizationCaptureRequestInternal(/*previewStabilizationOn*/ false,
                                                      cameraDeviceToTimeLag);
    processPreviewStabilizationCaptureRequestInternal(/*previewStabilizationOn*/ true,
                                                      cameraDeviceToTimeLag);
}

void CameraHidlTest::processPreviewStabilizationCaptureRequestInternal(
        bool previewStabilizationOn,
        // Used as output when preview stabilization is off, as output when its
        // on.
        std::unordered_map<std::string, nsecs_t>& cameraDeviceToTimeLag) {
    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
    AvailableStream streamThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
                                       static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
    uint64_t bufferId = 1;
    uint32_t frameNumber = 1;
    ::android::hardware::hidl_vec<uint8_t> settings;

    for (const auto& name : cameraDeviceNames) {
        int deviceVersion = getCameraDeviceVersion(name, mProviderType);
        if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) {
            continue;
        } else if (deviceVersion <= 0) {
            ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
            ADD_FAILURE();
            return;
        }

        if (!supportsPreviewStabilization(name, mProvider)) {
            ALOGI(" %s Camera device %s doesn't support preview stabilization, skipping", __func__,
                  name.c_str());
            continue;
        }

        if (deviceVersion < CAMERA_DEVICE_API_VERSION_3_8) {
            ALOGE("%s: device version < 3.8 must not advertise preview stabilization,"
                  " camera metadata validation will fail",
                  __func__);
            ADD_FAILURE();
        }

        V3_2::Stream testStream;
        HalStreamConfiguration halStreamConfig;
        sp<ICameraDeviceSession> session;
        sp<DeviceCb> cb;
        bool supportsPartialResults = false;
        bool useHalBufManager = false;
        uint32_t partialResultCount = 0;
        configureSingleStream(name, deviceVersion, mProvider, &streamThreshold,
                              GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, RequestTemplate::PREVIEW,
                              &session /*out*/, &testStream /*out*/, &halStreamConfig /*out*/,
                              &supportsPartialResults /*out*/, &partialResultCount /*out*/,
                              &useHalBufManager /*out*/, &cb /*out*/);

        std::shared_ptr<ResultMetadataQueue> resultQueue;
        auto resultQueueRet =
                session->getCaptureResultMetadataQueue([&resultQueue](const auto& descriptor) {
                    resultQueue = std::make_shared<ResultMetadataQueue>(descriptor);
                    if (!resultQueue->isValid() || resultQueue->availableToWrite() <= 0) {
                        ALOGE("%s: HAL returns empty result metadata fmq,"
                              " not use it",
                              __func__);
                        resultQueue = nullptr;
                        // Don't use the queue onwards.
                    }
                });
        ASSERT_TRUE(resultQueueRet.isOk());

        InFlightRequest inflightReq = {1, false, supportsPartialResults, partialResultCount,
                                       resultQueue};

        Return<void> ret;
        android::hardware::camera::common::V1_0::helper::CameraMetadata defaultSettings;
        ret = session->constructDefaultRequestSettings(
                RequestTemplate::PREVIEW, [&](auto status, const auto& req) {
                    ASSERT_EQ(Status::OK, status);
                    const camera_metadata_t* metadata =
                            reinterpret_cast<const camera_metadata_t*>(req.data());
                    defaultSettings = metadata;
                    settings = req;
                });
        ASSERT_TRUE(ret.isOk());
        android::status_t metadataRet = ::android::OK;
        uint8_t videoStabilizationMode = ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF;
        if (previewStabilizationOn) {
            videoStabilizationMode = ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_PREVIEW_STABILIZATION;
            metadataRet = defaultSettings.update(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
                                                 &videoStabilizationMode, 1);
        } else {
            metadataRet = defaultSettings.update(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
                                                 &videoStabilizationMode, 1);
        }
        ASSERT_EQ(metadataRet, ::android::OK);
        hidl_handle buffer_handle;
        StreamBuffer outputBuffer;
        if (useHalBufManager) {
            outputBuffer = {halStreamConfig.streams[0].id,
                            /*bufferId*/ 0,
                            buffer_handle,
                            BufferStatus::OK,
                            nullptr,
                            nullptr};
        } else {
            allocateGraphicBuffer(
                    testStream.width, testStream.height,
                    /* We don't look at halStreamConfig.streams[0].consumerUsage
                     * since that is 0 for output streams
                     */
                    android_convertGralloc1To0Usage(halStreamConfig.streams[0].producerUsage,
                                                    GRALLOC1_CONSUMER_USAGE_HWCOMPOSER),
                    halStreamConfig.streams[0].overrideFormat, &buffer_handle);
            outputBuffer = {halStreamConfig.streams[0].id,
                            bufferId,
                            buffer_handle,
                            BufferStatus::OK,
                            nullptr,
                            nullptr};
        }
        ::android::hardware::hidl_vec<StreamBuffer> outputBuffers = {outputBuffer};
        StreamBuffer emptyInputBuffer = {-1, 0, nullptr, BufferStatus::ERROR, nullptr, nullptr};
        CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings, emptyInputBuffer,
                                  outputBuffers};

        {
            std::unique_lock<std::mutex> l(mLock);
            mInflightMap.clear();
            mInflightMap.add(frameNumber, &inflightReq);
        }

        Status status = Status::INTERNAL_ERROR;
        uint32_t numRequestProcessed = 0;
        hidl_vec<BufferCache> cachesToRemove;
        Return<void> returnStatus = session->processCaptureRequest(
                {request}, cachesToRemove, [&status, &numRequestProcessed](auto s, uint32_t n) {
                    status = s;
                    numRequestProcessed = n;
                });
        ASSERT_TRUE(returnStatus.isOk());
        ASSERT_EQ(Status::OK, status);
        ASSERT_EQ(numRequestProcessed, 1u);

        {
            std::unique_lock<std::mutex> l(mLock);
            while (!inflightReq.errorCodeValid &&
                   ((0 < inflightReq.numBuffersLeft) || (!inflightReq.haveResultMetadata))) {
                auto timeout = std::chrono::system_clock::now() +
                               std::chrono::seconds(kStreamBufferTimeoutSec);
                ASSERT_NE(std::cv_status::timeout, mResultCondition.wait_until(l, timeout));
            }

            ASSERT_FALSE(inflightReq.errorCodeValid);
            ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u);
            ASSERT_EQ(testStream.id, inflightReq.resultOutputBuffers[0].buffer.streamId);
            ASSERT_TRUE(inflightReq.shutterReadoutTimestampValid);
            nsecs_t readoutTimestamp = inflightReq.shutterReadoutTimestamp;

            if (previewStabilizationOn) {
                // Here we collect the time difference between the buffer ready
                // timestamp - notify readout timestamp.
                // timeLag = buffer ready timestamp - notify readout timestamp.
                // timeLag(previewStabilization) must be <=
                //        timeLag(stabilization off) + 1 frame duration.
                auto it = cameraDeviceToTimeLag.find(name.c_str());
                camera_metadata_entry e;
                e = inflightReq.collectedResult.find(ANDROID_SENSOR_FRAME_DURATION);
                ASSERT_TRUE(e.count > 0);
                nsecs_t frameDuration = e.data.i64[0];
                ASSERT_TRUE(it != cameraDeviceToTimeLag.end());

                nsecs_t previewStabOnLagTime =
                        inflightReq.resultOutputBuffers[0].timeStamp - readoutTimestamp;
                ASSERT_TRUE(previewStabOnLagTime <= (it->second + frameDuration));
            } else {
                // Fill in the buffer ready timestamp - notify timestamp;
                cameraDeviceToTimeLag[std::string(name.c_str())] =
                        inflightReq.resultOutputBuffers[0].timeStamp - readoutTimestamp;
            }
        }

        if (useHalBufManager) {
@@ -5567,7 +5781,7 @@ TEST_P(CameraHidlTest, processCaptureRequestBurstISO) {

            ASSERT_FALSE(inflightReqs[i].errorCodeValid);
            ASSERT_NE(inflightReqs[i].resultOutputBuffers.size(), 0u);
            ASSERT_EQ(previewStream.id, inflightReqs[i].resultOutputBuffers[0].streamId);
            ASSERT_EQ(previewStream.id, inflightReqs[i].resultOutputBuffers[0].buffer.streamId);
            ASSERT_FALSE(inflightReqs[i].collectedResult.isEmpty());
            ASSERT_TRUE(inflightReqs[i].collectedResult.exists(ANDROID_SENSOR_SENSITIVITY));
            camera_metadata_entry_t isoResult = inflightReqs[i].collectedResult.find(
@@ -5851,7 +6065,7 @@ TEST_P(CameraHidlTest, switchToOffline) {

            ASSERT_FALSE(inflightReqs[i].errorCodeValid);
            ASSERT_NE(inflightReqs[i].resultOutputBuffers.size(), 0u);
            ASSERT_EQ(stream.id, inflightReqs[i].resultOutputBuffers[0].streamId);
            ASSERT_EQ(stream.id, inflightReqs[i].resultOutputBuffers[0].buffer.streamId);
            ASSERT_FALSE(inflightReqs[i].collectedResult.isEmpty());
        }

@@ -6047,7 +6261,7 @@ TEST_P(CameraHidlTest, flushPreviewRequest) {

            if (!inflightReq.errorCodeValid) {
                ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u);
                ASSERT_EQ(previewStream.id, inflightReq.resultOutputBuffers[0].streamId);
                ASSERT_EQ(previewStream.id, inflightReq.resultOutputBuffers[0].buffer.streamId);
            } else {
                switch (inflightReq.errorCode) {
                    case ErrorCode::ERROR_REQUEST:
@@ -7685,6 +7899,47 @@ void CameraHidlTest::configurePreviewStream(const std::string &name, int32_t dev
                          previewStream, halStreamConfig, supportsPartialResults,
                          partialResultCount, useHalBufManager, outCb, streamConfigCounter);
}

bool CameraHidlTest::supportsPreviewStabilization(const std::string& name,
                                                  sp<ICameraProvider> provider) {
    Return<void> ret;
    sp<ICameraDevice> device3_x = nullptr;
    ret = provider->getCameraDeviceInterface_V3_x(name, [&](auto status, const auto& device) {
        ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
        ASSERT_EQ(Status::OK, status);
        ASSERT_NE(device, nullptr);
        device3_x = device;
    });
    if (!(ret.isOk())) {
        ADD_FAILURE() << "Failed to get camera device interface for " << name;
    }

    camera_metadata_t* staticMeta = nullptr;
    ret = device3_x->getCameraCharacteristics([&](Status s, CameraMetadata metadata) {
        ASSERT_EQ(Status::OK, s);
        staticMeta =
                clone_camera_metadata(reinterpret_cast<const camera_metadata_t*>(metadata.data()));
    });
    if (!(ret.isOk())) {
        ADD_FAILURE() << "Failed to get camera characteristics for " << name;
    }
    // Go through the characteristics and see if video stabilization modes have
    // preview stabilization
    camera_metadata_ro_entry entry;

    int retcode = find_camera_metadata_ro_entry(
            staticMeta, ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES, &entry);
    if ((0 == retcode) && (entry.count > 0)) {
        for (auto i = 0; i < entry.count; i++) {
            if (entry.data.u8[i] ==
                ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_PREVIEW_STABILIZATION) {
                return true;
            }
        }
    }
    return false;
}

// Open a device session and configure a preview stream.
void CameraHidlTest::configureSingleStream(
        const std::string& name, int32_t deviceVersion, sp<ICameraProvider> provider,
+7 −6
Original line number Diff line number Diff line
@@ -74,16 +74,17 @@ enum Composition {
     */
    SIDEBAND = 5,
    /**
     * A display decoration layer contains a buffer which is an 8 bit
     * alpha mask. Pixels in the mask with an alpha of 0 (transparent) will
     * show the content underneath, and pixels with an alpha of 255 will be
     * be rendered in black. An alpha in between will show the content
     * blended with black. This is useful, for example, to provide
     * A display decoration layer contains a buffer which is used to provide
     * anti-aliasing on the cutout region/rounded corners on the top and
     * bottom of a display.
     *
     * Pixels in the buffer with an alpha of 0 (transparent) will show the
     * content underneath, and pixels with a max alpha value will be rendered in
     * black. An alpha in between will show the underlying content blended with
     * black.
     *
     * Upon validateDisplay, the device may request a change from this type
     * to CLIENT.
     * to either DEVICE or CLIENT.
     */
    DISPLAY_DECORATION = 6,
}
+4 −1
Original line number Diff line number Diff line
@@ -30,7 +30,10 @@ cc_test {
        ":inputconstants_aidl",
        "VtsHalInputClassifierV1_0TargetTest.cpp",
    ],
    header_libs: ["jni_headers"],
    header_libs: [
        "jni_headers",
        "libbinder_headers",
    ],
    static_libs: [
        "android.hardware.input.classifier@1.0",
        "android.hardware.input.common@1.0",
+1 −0
Original line number Diff line number Diff line
@@ -81,6 +81,7 @@ static void publishRadioConfig() {
}

static void main() {
    base::InitLogging(nullptr, base::LogdLogger(base::RADIO));
    base::SetDefaultTag("radiocompat");
    base::SetMinimumLogSeverity(base::VERBOSE);
    LOG(DEBUG) << "Radio HAL compat service starting...";