1/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <vector>
18#include <inttypes.h>
19#include "ACameraDevice.h"
20#include "ACameraMetadata.h"
21#include "ACaptureRequest.h"
22#include "ACameraCaptureSession.h"
23
24namespace android {
25namespace acam {
26
27template<class T>
28camera_status_t
29CameraDevice::captureLocked(
30        sp<ACameraCaptureSession> session,
31        /*optional*/T* cbs,
32        int numRequests, ACaptureRequest** requests,
33        /*optional*/int* captureSequenceId) {
34    return submitRequestsLocked(
35            session, cbs, numRequests, requests, captureSequenceId, /*isRepeating*/false);
36}
37
38template<class T>
39camera_status_t
40CameraDevice::setRepeatingRequestsLocked(
41        sp<ACameraCaptureSession> session,
42        /*optional*/T* cbs,
43        int numRequests, ACaptureRequest** requests,
44        /*optional*/int* captureSequenceId) {
45    return submitRequestsLocked(
46            session, cbs, numRequests, requests, captureSequenceId, /*isRepeating*/true);
47}
48
49template<class T>
50camera_status_t CameraDevice::submitRequestsLocked(
51        sp<ACameraCaptureSession> session,
52        /*optional*/T* cbs,
53        int numRequests, ACaptureRequest** requests,
54        /*optional*/int* captureSequenceId,
55        bool isRepeating) {
56    camera_status_t ret = checkCameraClosedOrErrorLocked();
57    if (ret != ACAMERA_OK) {
58        ALOGE("Camera %s submit capture request failed! ret %d", getId(), ret);
59        return ret;
60    }
61
62    // Form two vectors of capture request, one for internal tracking
63    std::vector<hardware::camera2::CaptureRequest> requestList;
64    Vector<sp<CaptureRequest> > requestsV;
65    requestsV.setCapacity(numRequests);
66    for (int i = 0; i < numRequests; i++) {
67        sp<CaptureRequest> req;
68        ret = allocateCaptureRequest(requests[i], req);
69        if (ret != ACAMERA_OK) {
70            ALOGE("Convert capture request to internal format failure! ret %d", ret);
71            return ret;
72        }
73        if (req->mSurfaceList.empty()) {
74            ALOGE("Capture request without output target cannot be submitted!");
75            return ACAMERA_ERROR_INVALID_PARAMETER;
76        }
77        requestList.push_back(*(req.get()));
78        requestsV.push_back(req);
79    }
80
81    if (isRepeating) {
82        ret = stopRepeatingLocked();
83        if (ret != ACAMERA_OK) {
84            ALOGE("Camera %s stop repeating failed! ret %d", getId(), ret);
85            return ret;
86        }
87    }
88
89    binder::Status remoteRet;
90    hardware::camera2::utils::SubmitInfo info;
91    remoteRet = mRemote->submitRequestList(requestList, isRepeating, &info);
92    int sequenceId = info.mRequestId;
93    int64_t lastFrameNumber = info.mLastFrameNumber;
94    if (sequenceId < 0) {
95        ALOGE("Camera %s submit request remote failure: ret %d", getId(), sequenceId);
96        return ACAMERA_ERROR_UNKNOWN;
97    }
98
99    CallbackHolder cbHolder(session, requestsV, isRepeating, cbs);
100    mSequenceCallbackMap.insert(std::make_pair(sequenceId, cbHolder));
101
102    if (isRepeating) {
103        // stopRepeating above should have cleanup repeating sequence id
104        if (mRepeatingSequenceId != REQUEST_ID_NONE) {
105            setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
106            return ACAMERA_ERROR_CAMERA_DEVICE;
107        }
108        mRepeatingSequenceId = sequenceId;
109    } else {
110        mSequenceLastFrameNumberMap.insert(std::make_pair(sequenceId, lastFrameNumber));
111    }
112
113    if (mIdle) {
114        sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
115        msg->setPointer(kContextKey, session->mUserSessionCallback.context);
116        msg->setObject(kSessionSpKey, session);
117        msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onActive);
118        postSessionMsgAndCleanup(msg);
119    }
120    mIdle = false;
121    mBusySession = session;
122
123    if (captureSequenceId) {
124        *captureSequenceId = sequenceId;
125    }
126    return ACAMERA_OK;
127}
128
129} // namespace acam
130} // namespace android
131