<commit_before>/*
 * Copyright 2021 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.
 */

package androidx.camera.camera2.pipe.compat

import android.hardware.camera2.CameraCaptureSession
import android.hardware.camera2.CaptureFailure
import android.hardware.camera2.CaptureRequest
import android.hardware.camera2.CaptureResult
import android.hardware.camera2.TotalCaptureResult
import android.view.Surface
import androidx.camera.camera2.pipe.CameraId
import androidx.camera.camera2.pipe.CameraTimestamp
import androidx.camera.camera2.pipe.FrameNumber
import androidx.camera.camera2.pipe.Request
import androidx.camera.camera2.pipe.RequestMetadata
import androidx.camera.camera2.pipe.RequestNumber
import androidx.camera.camera2.pipe.StreamId

/**
 * This class responds to events from a set of one or more requests. It uses the tag field on
 * a [CaptureRequest] object to lookup and invoke per-request listeners so that a listener can be
 * defined on a specific request within a burst.
 */
internal class Camera2CaptureSequence(
    private val internalListeners: List<Request.Listener>,
    private val requests: Map<RequestNumber, RequestInfo>,
    private val captureRequests: List<CaptureRequest>,
    private val surfaceMap: Map<Surface, StreamId>,
    private val inFlightRequests: MutableList<Camera2CaptureSequence>,
    private val camera: CameraId
) : CameraCaptureSession.CaptureCallback() {
    private val debugId = requestSequenceDebugIds.incrementAndGet()

    @Volatile
    private var _sequenceNumber: Int? = null
    var sequenceNumber: Int
        get() {
            if (_sequenceNumber == null) {
                // If the sequence id has not been submitted, it means the call to capture or
                // setRepeating has not yet returned. The callback methods should never be synchronously
                // invoked, so the only case this should happen is if a second thread attempted to
                // invoke one of the callbacks before the initial call completed. By locking against the
                // captureSequence object here and in the capture call, we can block the callback thread
                // until the sequenceId is available.
                synchronized(this) {
                    return checkNotNull(_sequenceNumber) {
                        "SequenceNumber has not been set for $this!"
                    }
                }
            }
            return checkNotNull(_sequenceNumber) {
                "SequenceNumber has not been set for $this!"
            }
        }
        set(value) {
            _sequenceNumber = value
        }

    override fun onCaptureStarted(
        captureSession: CameraCaptureSession,
        captureRequest: CaptureRequest,
        captureTimestamp: Long,
        captureFrameNumber: Long
    ) {
        val requestNumber = readRequestNumber(captureRequest)
        val timestamp = CameraTimestamp(captureTimestamp)
        val frameNumber = FrameNumber(captureFrameNumber)

        // Load the request and throw if we are not able to find an associated request. Under
        // normal circumstances this should never happen.
        val request = readRequest(requestNumber)

        invokeOnRequest(request) {
            it.onStarted(
                request,
                frameNumber,
                timestamp
            )
        }
    }

    override fun onCaptureProgressed(
        captureSession: CameraCaptureSession,
        captureRequest: CaptureRequest,
        partialCaptureResult: CaptureResult
    ) {
        val requestNumber = readRequestNumber(captureRequest)
        val frameNumber = FrameNumber(partialCaptureResult.frameNumber)
        val frameMetadata = AndroidFrameMetadata(partialCaptureResult, camera)

        // Load the request and throw if we are not able to find an associated request. Under
        // normal circumstances this should never happen.
        val request = readRequest(requestNumber)

        invokeOnRequest(request) {
            it.onPartialCaptureResult(
                request,
                frameNumber,
                frameMetadata
            )
        }
    }

    override fun onCaptureCompleted(
        captureSession: CameraCaptureSession,
        captureRequest: CaptureRequest,
        captureResult: TotalCaptureResult
    ) {
        // Remove this request from the set of requests that are currently tracked.
        synchronized(inFlightRequests) {
            inFlightRequests.remove(this)
        }

        val requestNumber = readRequestNumber(captureRequest)
        val frameNumber = FrameNumber(captureResult.frameNumber)

        // Load the request and throw if we are not able to find an associated request. Under
        // normal circumstances this should never happen.
        val request = readRequest(requestNumber)

        val frameInfo = AndroidFrameInfo(
            captureResult,
            camera,
            request
        )

        invokeOnRequest(request) {
            it.onTotalCaptureResult(
                request,
                frameNumber,
                frameInfo
            )
        }<commit_msg>Fire onComplete() right after onTotalCaptureResult()<commit_after>/*
 * Copyright 2021 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.
 */

package androidx.camera.camera2.pipe.compat

import android.hardware.camera2.CameraCaptureSession
import android.hardware.camera2.CaptureFailure
import android.hardware.camera2.CaptureRequest
import android.hardware.camera2.CaptureResult
import android.hardware.camera2.TotalCaptureResult
import android.view.Surface
import androidx.camera.camera2.pipe.CameraId
import androidx.camera.camera2.pipe.CameraTimestamp
import androidx.camera.camera2.pipe.FrameNumber
import androidx.camera.camera2.pipe.Request
import androidx.camera.camera2.pipe.RequestMetadata
import androidx.camera.camera2.pipe.RequestNumber
import androidx.camera.camera2.pipe.StreamId

/**
 * This class responds to events from a set of one or more requests. It uses the tag field on
 * a [CaptureRequest] object to lookup and invoke per-request listeners so that a listener can be
 * defined on a specific request within a burst.
 */
internal class Camera2CaptureSequence(
    private val internalListeners: List<Request.Listener>,
    private val requests: Map<RequestNumber, RequestInfo>,
    private val captureRequests: List<CaptureRequest>,
    private val surfaceMap: Map<Surface, StreamId>,
    private val inFlightRequests: MutableList<Camera2CaptureSequence>,
    private val camera: CameraId
) : CameraCaptureSession.CaptureCallback() {
    private val debugId = requestSequenceDebugIds.incrementAndGet()

    @Volatile
    private var _sequenceNumber: Int? = null
    var sequenceNumber: Int
        get() {
            if (_sequenceNumber == null) {
                // If the sequence id has not been submitted, it means the call to capture or
                // setRepeating has not yet returned. The callback methods should never be synchronously
                // invoked, so the only case this should happen is if a second thread attempted to
                // invoke one of the callbacks before the initial call completed. By locking against the
                // captureSequence object here and in the capture call, we can block the callback thread
                // until the sequenceId is available.
                synchronized(this) {
                    return checkNotNull(_sequenceNumber) {
                        "SequenceNumber has not been set for $this!"
                    }
                }
            }
            return checkNotNull(_sequenceNumber) {
                "SequenceNumber has not been set for $this!"
            }
        }
        set(value) {
            _sequenceNumber = value
        }

    override fun onCaptureStarted(
        captureSession: CameraCaptureSession,
        captureRequest: CaptureRequest,
        captureTimestamp: Long,
        captureFrameNumber: Long
    ) {
        val requestNumber = readRequestNumber(captureRequest)
        val timestamp = CameraTimestamp(captureTimestamp)
        val frameNumber = FrameNumber(captureFrameNumber)

        // Load the request and throw if we are not able to find an associated request. Under
        // normal circumstances this should never happen.
        val request = readRequest(requestNumber)

        invokeOnRequest(request) {
            it.onStarted(
                request,
                frameNumber,
                timestamp
            )
        }
    }

    override fun onCaptureProgressed(
        captureSession: CameraCaptureSession,
        captureRequest: CaptureRequest,
        partialCaptureResult: CaptureResult
    ) {
        val requestNumber = readRequestNumber(captureRequest)
        val frameNumber = FrameNumber(partialCaptureResult.frameNumber)
        val frameMetadata = AndroidFrameMetadata(partialCaptureResult, camera)

        // Load the request and throw if we are not able to find an associated request. Under
        // normal circumstances this should never happen.
        val request = readRequest(requestNumber)

        invokeOnRequest(request) {
            it.onPartialCaptureResult(
                request,
                frameNumber,
                frameMetadata
            )
        }
    }

    override fun onCaptureCompleted(
        captureSession: CameraCaptureSession,
        captureRequest: CaptureRequest,
        captureResult: TotalCaptureResult
    ) {
        // Remove this request from the set of requests that are currently tracked.
        synchronized(inFlightRequests) {
            inFlightRequests.remove(this)
        }

        val requestNumber = readRequestNumber(captureRequest)
        val frameNumber = FrameNumber(captureResult.frameNumber)

        // Load the request and throw if we are not able to find an associated request. Under
        // normal circumstances this should never happen.
        val request = readRequest(requestNumber)

        val frameInfo = AndroidFrameInfo(
            captureResult,
            camera,
            request
        )

        invokeOnRequest(request) {
            it.onTotalCaptureResult(
                request,
                frameNumber,
                frameInfo
            )
        }

        // TODO: Implement a proper mechanism to delay the firing of onComplete(). See
        // androidx.camera.camera2.pipe.Request.Listener for context.
        invokeOnRequest(request) {
            it.onComplete(
                request,
                frameNumber,
                frameInfo
            )
        }
{'fraction_non_alphanumeric': 0.057565648789667266, 'fraction_numerical': 0.0040201864682234195, 'mean_word_length': 2.4177141186787487, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5112370', 'n_tokens_mistral': 2715, 'n_tokens_neox': 2648, 'n_words': 952}