1e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin/*
2e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin * Copyright (C) 2013 The Android Open Source Project
3e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin *
4e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin * Licensed under the Apache License, Version 2.0 (the "License");
5e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin * you may not use this file except in compliance with the License.
6e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin * You may obtain a copy of the License at
7e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin *
8e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin *      http://www.apache.org/licenses/LICENSE-2.0
9e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin *
10e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin * Unless required by applicable law or agreed to in writing, software
11e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin * distributed under the License is distributed on an "AS IS" BASIS,
12e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin * See the License for the specific language governing permissions and
14e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin * limitations under the License.
15e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin */
16e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
17e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin#define LOG_TAG "CameraDeviceClient"
18e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin#define ATRACE_TAG ATRACE_TAG_CAMERA
19cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei//#define LOG_NDEBUG 0
20e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
217b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvala#include <cutils/properties.h>
22e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin#include <utils/Log.h>
23e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin#include <utils/Trace.h>
24e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin#include <gui/Surface.h>
257b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvala#include <camera/camera2/CaptureRequest.h>
265698d4461a260dbf208484383f692b03c6473e74Ruben Brunk#include <camera/CameraUtils.h>
277b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvala
287b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvala#include "common/CameraDeviceBase.h"
297b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvala#include "api2/CameraDeviceClient.h"
307b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvala
31d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala// Convenience methods for constructing binder::Status objects for error returns
327b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvala
33d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala#define STATUS_ERROR(errorCode, errorString) \
34d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    binder::Status::fromServiceSpecificError(errorCode, \
3502bf03287652923b5bb5316667b065423565d6b4Eino-Ville Talvala            String8::format("%s:%d: %s", __FUNCTION__, __LINE__, errorString))
36d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala
37d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala#define STATUS_ERROR_FMT(errorCode, errorString, ...) \
38d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    binder::Status::fromServiceSpecificError(errorCode, \
3902bf03287652923b5bb5316667b065423565d6b4Eino-Ville Talvala            String8::format("%s:%d: " errorString, __FUNCTION__, __LINE__, \
40d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    __VA_ARGS__))
41e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
42e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkinnamespace android {
43e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkinusing namespace camera2;
44e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
45e7ee7637747371635a85fedd24d2190bb1f38651Igor MurashkinCameraDeviceClientBase::CameraDeviceClientBase(
46e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        const sp<CameraService>& cameraService,
47d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        const sp<hardware::camera2::ICameraDeviceCallbacks>& remoteCallback,
48e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        const String16& clientPackageName,
49e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        int cameraId,
50e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        int cameraFacing,
51e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        int clientPid,
52e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        uid_t clientUid,
53e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        int servicePid) :
54e992e75053e98e3699af6e344c11b787e30411adEino-Ville Talvala    BasicClient(cameraService,
55f888020c6e2735624f2b2a30e72aca24e17b8b4dMarco Nelissen            IInterface::asBinder(remoteCallback),
56e992e75053e98e3699af6e344c11b787e30411adEino-Ville Talvala            clientPackageName,
57e992e75053e98e3699af6e344c11b787e30411adEino-Ville Talvala            cameraId,
58e992e75053e98e3699af6e344c11b787e30411adEino-Ville Talvala            cameraFacing,
59e992e75053e98e3699af6e344c11b787e30411adEino-Ville Talvala            clientPid,
60e992e75053e98e3699af6e344c11b787e30411adEino-Ville Talvala            clientUid,
61e992e75053e98e3699af6e344c11b787e30411adEino-Ville Talvala            servicePid),
62e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    mRemoteCallback(remoteCallback) {
63e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin}
64e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
65e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin// Interface used by CameraService
66e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
67e7ee7637747371635a85fedd24d2190bb1f38651Igor MurashkinCameraDeviceClient::CameraDeviceClient(const sp<CameraService>& cameraService,
68d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        const sp<hardware::camera2::ICameraDeviceCallbacks>& remoteCallback,
69d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        const String16& clientPackageName,
70d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        int cameraId,
71d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        int cameraFacing,
72d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        int clientPid,
73d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        uid_t clientUid,
74d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        int servicePid) :
75e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    Camera2ClientBase(cameraService, remoteCallback, clientPackageName,
76e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                cameraId, cameraFacing, clientPid, clientUid, servicePid),
77618ff8a48a0c895a78f91f5692510c2a809425c3Chien-Yu Chen    mInputStream(),
78e8c535e833ed135895e99ca81aa3b85d80d7cf3cChien-Yu Chen    mStreamingRequestId(REQUEST_ID_NONE),
79e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    mRequestIdCounter(0) {
80e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
81e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    ATRACE_CALL();
82e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    ALOGI("CameraDeviceClient %d: Opened", cameraId);
83e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin}
84e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
85e074a93046ebe5cea0b55c3a479e082a426e1e07Yin-Chia Yehstatus_t CameraDeviceClient::initialize(CameraModule *module)
86e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin{
87e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    ATRACE_CALL();
88e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    status_t res;
89e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
90e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    res = Camera2ClientBase::initialize(module);
91e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if (res != OK) {
92e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        return res;
93e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
94e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
95e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    String8 threadName;
967b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvala    mFrameProcessor = new FrameProcessorBase(mDevice);
97e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    threadName = String8::format("CDU-%d-FrameProc", mCameraId);
98e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    mFrameProcessor->run(threadName.string());
99e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
100e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    mFrameProcessor->registerListener(FRAME_PROCESSOR_LISTENER_MIN_ID,
101e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                                      FRAME_PROCESSOR_LISTENER_MAX_ID,
102184dfe4ea5e2ba33951bed2b1366007aee0ce3daEino-Ville Talvala                                      /*listener*/this,
10325a0aef19e170d2695f64b4c48296e7914155a88Zhijun He                                      /*sendPartials*/true);
104e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
105e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    return OK;
106e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin}
107e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
108e7ee7637747371635a85fedd24d2190bb1f38651Igor MurashkinCameraDeviceClient::~CameraDeviceClient() {
109e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin}
110e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
111d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvalabinder::Status CameraDeviceClient::submitRequest(
112d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        const hardware::camera2::CaptureRequest& request,
113d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        bool streaming,
114d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        /*out*/
115d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        hardware::camera2::utils::SubmitInfo *submitInfo) {
116d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    std::vector<hardware::camera2::CaptureRequest> requestList = { request };
117d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return submitRequestList(requestList, streaming, submitInfo);
11890e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei}
11990e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei
120d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvalabinder::Status CameraDeviceClient::submitRequestList(
121d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        const std::vector<hardware::camera2::CaptureRequest>& requests,
122d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        bool streaming,
123d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        /*out*/
124d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        hardware::camera2::utils::SubmitInfo *submitInfo) {
12590e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei    ATRACE_CALL();
12650468413251bd92a1cdf9de8275a994dab8648d1Mark Salyzyn    ALOGV("%s-start of function. Request list size %zu", __FUNCTION__, requests.size());
12790e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei
128d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    binder::Status res = binder::Status::ok();
129d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    status_t err;
130d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if ( !(res = checkPidStatus(__FUNCTION__) ).isOk()) {
131d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return res;
132d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    }
13390e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei
13490e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei    Mutex::Autolock icl(mBinderSerializationLock);
13590e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei
136d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if (!mDevice.get()) {
137d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
138d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    }
13990e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei
14090e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei    if (requests.empty()) {
14190e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei        ALOGE("%s: Camera %d: Sent null request. Rejecting request.",
14290e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei              __FUNCTION__, mCameraId);
143d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "Empty request list");
14490e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei    }
14590e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei
14690e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei    List<const CameraMetadata> metadataRequestList;
147d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    submitInfo->mRequestId = mRequestIdCounter;
14890e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei    uint32_t loopCounter = 0;
14990e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei
150d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    for (auto&& request: requests) {
151d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        if (request.mIsReprocess) {
152ed0412ed78321bf9d35537626e33115862f7c805Chien-Yu Chen            if (!mInputStream.configured) {
153ed0412ed78321bf9d35537626e33115862f7c805Chien-Yu Chen                ALOGE("%s: Camera %d: no input stream is configured.", __FUNCTION__, mCameraId);
154d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                return STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
155d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                        "No input configured for camera %d but request is for reprocessing",
156d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                        mCameraId);
157ed0412ed78321bf9d35537626e33115862f7c805Chien-Yu Chen            } else if (streaming) {
158ed0412ed78321bf9d35537626e33115862f7c805Chien-Yu Chen                ALOGE("%s: Camera %d: streaming reprocess requests not supported.", __FUNCTION__,
159ed0412ed78321bf9d35537626e33115862f7c805Chien-Yu Chen                        mCameraId);
160d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
161d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                        "Repeating reprocess requests not supported");
162618ff8a48a0c895a78f91f5692510c2a809425c3Chien-Yu Chen            }
16390e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei        }
16490e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei
165d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        CameraMetadata metadata(request.mMetadata);
16690e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei        if (metadata.isEmpty()) {
16790e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei            ALOGE("%s: Camera %d: Sent empty metadata packet. Rejecting request.",
16890e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei                   __FUNCTION__, mCameraId);
169d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
170d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    "Request settings are empty");
171d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        } else if (request.mSurfaceList.isEmpty()) {
17290e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei            ALOGE("%s: Camera %d: Requests must have at least one surface target. "
173d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    "Rejecting request.", __FUNCTION__, mCameraId);
174d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
175d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    "Request has no output targets");
17690e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei        }
17790e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei
17890e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei        if (!enforceRequestPermissions(metadata)) {
17990e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei            // Callee logs
180d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            return STATUS_ERROR(CameraService::ERROR_PERMISSION_DENIED,
181d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    "Caller does not have permission to change restricted controls");
18290e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei        }
18390e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei
18490e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei        /**
18590e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei         * Write in the output stream IDs which we calculate from
18690e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei         * the capture request's list of surface targets
18790e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei         */
18890e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei        Vector<int32_t> outputStreamIds;
189d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        outputStreamIds.setCapacity(request.mSurfaceList.size());
190d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        for (sp<Surface> surface : request.mSurfaceList) {
19190e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei            if (surface == 0) continue;
19290e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei
19390e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei            sp<IGraphicBufferProducer> gbp = surface->getIGraphicBufferProducer();
194f888020c6e2735624f2b2a30e72aca24e17b8b4dMarco Nelissen            int idx = mStreamMap.indexOfKey(IInterface::asBinder(gbp));
19590e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei
19690e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei            // Trying to submit request with surface that wasn't created
19790e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei            if (idx == NAME_NOT_FOUND) {
19890e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei                ALOGE("%s: Camera %d: Tried to submit a request with a surface that"
199d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                        " we have not called createStream on",
200d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                        __FUNCTION__, mCameraId);
201d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
202d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                        "Request targets Surface that is not part of current capture session");
20390e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei            }
20490e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei
20590e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei            int streamId = mStreamMap.valueAt(idx);
20690e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei            outputStreamIds.push_back(streamId);
20790e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei            ALOGV("%s: Camera %d: Appending output stream %d to request",
208d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    __FUNCTION__, mCameraId, streamId);
20990e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei        }
21090e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei
21190e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei        metadata.update(ANDROID_REQUEST_OUTPUT_STREAMS, &outputStreamIds[0],
21290e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei                        outputStreamIds.size());
21390e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei
214d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        if (request.mIsReprocess) {
215618ff8a48a0c895a78f91f5692510c2a809425c3Chien-Yu Chen            metadata.update(ANDROID_REQUEST_INPUT_STREAMS, &mInputStream.id, 1);
216618ff8a48a0c895a78f91f5692510c2a809425c3Chien-Yu Chen        }
217618ff8a48a0c895a78f91f5692510c2a809425c3Chien-Yu Chen
218d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        metadata.update(ANDROID_REQUEST_ID, &(submitInfo->mRequestId), /*size*/1);
21990e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei        loopCounter++; // loopCounter starts from 1
22050468413251bd92a1cdf9de8275a994dab8648d1Mark Salyzyn        ALOGV("%s: Camera %d: Creating request with ID %d (%d of %zu)",
221d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala              __FUNCTION__, mCameraId, submitInfo->mRequestId, loopCounter, requests.size());
22290e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei
22390e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei        metadataRequestList.push_back(metadata);
22490e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei    }
22590e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei    mRequestIdCounter++;
22690e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei
22790e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei    if (streaming) {
228d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        err = mDevice->setStreamingRequestList(metadataRequestList, &(submitInfo->mLastFrameNumber));
229d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        if (err != OK) {
230d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            String8 msg = String8::format(
231d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                "Camera %d:  Got error %s (%d) after trying to set streaming request",
232d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                mCameraId, strerror(-err), err);
233d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            ALOGE("%s: %s", __FUNCTION__, msg.string());
234d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION,
235d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    msg.string());
23690e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei        } else {
237c9ca6788c65ed3f578d1a1ed0ba7c268254dcb4bShuzhen Wang            Mutex::Autolock idLock(mStreamingRequestIdLock);
238e8c535e833ed135895e99ca81aa3b85d80d7cf3cChien-Yu Chen            mStreamingRequestId = submitInfo->mRequestId;
23990e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei        }
24090e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei    } else {
241d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        err = mDevice->captureList(metadataRequestList, &(submitInfo->mLastFrameNumber));
242d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        if (err != OK) {
243d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            String8 msg = String8::format(
244d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                "Camera %d: Got error %s (%d) after trying to submit capture request",
245d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                mCameraId, strerror(-err), err);
246d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            ALOGE("%s: %s", __FUNCTION__, msg.string());
247d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION,
248d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    msg.string());
24990e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei        }
250d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        ALOGV("%s: requestId = %d ", __FUNCTION__, submitInfo->mRequestId);
25190e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei    }
25290e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei
25390e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei    ALOGV("%s: Camera %d: End of function", __FUNCTION__, mCameraId);
254e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    return res;
255e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin}
256e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
257d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvalabinder::Status CameraDeviceClient::cancelRequest(
258d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        int requestId,
259d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        /*out*/
260d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        int64_t* lastFrameNumber) {
261e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    ATRACE_CALL();
262e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    ALOGV("%s, requestId = %d", __FUNCTION__, requestId);
263e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
264d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    status_t err;
265d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    binder::Status res;
266e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
267d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
268e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
269e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    Mutex::Autolock icl(mBinderSerializationLock);
270e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
271d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if (!mDevice.get()) {
272d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
273d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    }
274e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
275c9ca6788c65ed3f578d1a1ed0ba7c268254dcb4bShuzhen Wang    Mutex::Autolock idLock(mStreamingRequestIdLock);
276e8c535e833ed135895e99ca81aa3b85d80d7cf3cChien-Yu Chen    if (mStreamingRequestId != requestId) {
277e8c535e833ed135895e99ca81aa3b85d80d7cf3cChien-Yu Chen        String8 msg = String8::format("Camera %d: Canceling request ID %d doesn't match "
278e8c535e833ed135895e99ca81aa3b85d80d7cf3cChien-Yu Chen                "current request ID %d", mCameraId, requestId, mStreamingRequestId);
279d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        ALOGE("%s: %s", __FUNCTION__, msg.string());
280d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
281e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
282e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
283d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    err = mDevice->clearStreamingRequest(lastFrameNumber);
284e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
285d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if (err == OK) {
286e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        ALOGV("%s: Camera %d: Successfully cleared streaming request",
287e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin              __FUNCTION__, mCameraId);
288e8c535e833ed135895e99ca81aa3b85d80d7cf3cChien-Yu Chen        mStreamingRequestId = REQUEST_ID_NONE;
289d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    } else {
290d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
291d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                "Camera %d: Error clearing streaming request: %s (%d)",
292d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                mCameraId, strerror(-err), err);
293e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
294e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
295e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    return res;
296e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin}
297e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
298d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvalabinder::Status CameraDeviceClient::beginConfigure() {
299b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk    // TODO: Implement this.
3001fa8999c91d5df81949aa723000058380cd3faa2Zhijun He    ALOGV("%s: Not implemented yet.", __FUNCTION__);
301d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return binder::Status::ok();
302b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk}
303b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk
304d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvalabinder::Status CameraDeviceClient::endConfigure(bool isConstrainedHighSpeed) {
305618ff8a48a0c895a78f91f5692510c2a809425c3Chien-Yu Chen    ALOGV("%s: ending configure (%d input stream, %zu output streams)",
306618ff8a48a0c895a78f91f5692510c2a809425c3Chien-Yu Chen            __FUNCTION__, mInputStream.configured ? 1 : 0, mStreamMap.size());
307e2d167eb689d7a536805f950c31f11b9e9c578aeIgor Murashkin
3080effd5277058b1fa6067875ca86d74452c4491c3Zhijun He    binder::Status res;
3090effd5277058b1fa6067875ca86d74452c4491c3Zhijun He    if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
3100effd5277058b1fa6067875ca86d74452c4491c3Zhijun He
3110effd5277058b1fa6067875ca86d74452c4491c3Zhijun He    Mutex::Autolock icl(mBinderSerializationLock);
3120effd5277058b1fa6067875ca86d74452c4491c3Zhijun He
3130effd5277058b1fa6067875ca86d74452c4491c3Zhijun He    if (!mDevice.get()) {
3140effd5277058b1fa6067875ca86d74452c4491c3Zhijun He        return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
3150effd5277058b1fa6067875ca86d74452c4491c3Zhijun He    }
3160effd5277058b1fa6067875ca86d74452c4491c3Zhijun He
3171fa8999c91d5df81949aa723000058380cd3faa2Zhijun He    // Sanitize the high speed session against necessary capability bit.
3181fa8999c91d5df81949aa723000058380cd3faa2Zhijun He    if (isConstrainedHighSpeed) {
3191fa8999c91d5df81949aa723000058380cd3faa2Zhijun He        CameraMetadata staticInfo = mDevice->info();
3201fa8999c91d5df81949aa723000058380cd3faa2Zhijun He        camera_metadata_entry_t entry = staticInfo.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
3211fa8999c91d5df81949aa723000058380cd3faa2Zhijun He        bool isConstrainedHighSpeedSupported = false;
3221fa8999c91d5df81949aa723000058380cd3faa2Zhijun He        for(size_t i = 0; i < entry.count; ++i) {
3231fa8999c91d5df81949aa723000058380cd3faa2Zhijun He            uint8_t capability = entry.data.u8[i];
3241fa8999c91d5df81949aa723000058380cd3faa2Zhijun He            if (capability == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO) {
3251fa8999c91d5df81949aa723000058380cd3faa2Zhijun He                isConstrainedHighSpeedSupported = true;
3261fa8999c91d5df81949aa723000058380cd3faa2Zhijun He                break;
3271fa8999c91d5df81949aa723000058380cd3faa2Zhijun He            }
3281fa8999c91d5df81949aa723000058380cd3faa2Zhijun He        }
3291fa8999c91d5df81949aa723000058380cd3faa2Zhijun He        if (!isConstrainedHighSpeedSupported) {
330d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            String8 msg = String8::format(
331d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                "Camera %d: Try to create a constrained high speed configuration on a device"
332d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                " that doesn't support it.", mCameraId);
333d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            ALOGE("%s: %s", __FUNCTION__, msg.string());
334d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
335d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    msg.string());
3361fa8999c91d5df81949aa723000058380cd3faa2Zhijun He        }
3371fa8999c91d5df81949aa723000058380cd3faa2Zhijun He    }
3381fa8999c91d5df81949aa723000058380cd3faa2Zhijun He
339d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    status_t err = mDevice->configureStreams(isConstrainedHighSpeed);
340ace805805313827c7edde3bc6eb6624ab9f62dcbEino-Ville Talvala    if (err == BAD_VALUE) {
3415d677d1f0879d5101e38df480a38228a64d63959Zhijun He        String8 msg = String8::format("Camera %d: Unsupported set of inputs/outputs provided",
342ace805805313827c7edde3bc6eb6624ab9f62dcbEino-Ville Talvala                mCameraId);
3435d677d1f0879d5101e38df480a38228a64d63959Zhijun He        ALOGE("%s: %s", __FUNCTION__, msg.string());
3445d677d1f0879d5101e38df480a38228a64d63959Zhijun He        res = STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
345ace805805313827c7edde3bc6eb6624ab9f62dcbEino-Ville Talvala    } else if (err != OK) {
3465d677d1f0879d5101e38df480a38228a64d63959Zhijun He        String8 msg = String8::format("Camera %d: Error configuring streams: %s (%d)",
347d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                mCameraId, strerror(-err), err);
3485d677d1f0879d5101e38df480a38228a64d63959Zhijun He        ALOGE("%s: %s", __FUNCTION__, msg.string());
3495d677d1f0879d5101e38df480a38228a64d63959Zhijun He        res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
350d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    }
351e2d167eb689d7a536805f950c31f11b9e9c578aeIgor Murashkin
352d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return res;
353b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk}
354b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk
355d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvalabinder::Status CameraDeviceClient::deleteStream(int streamId) {
356e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    ATRACE_CALL();
357e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    ALOGV("%s (streamId = 0x%x)", __FUNCTION__, streamId);
358e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
359d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    binder::Status res;
360d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
361e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
362e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    Mutex::Autolock icl(mBinderSerializationLock);
363e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
364d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if (!mDevice.get()) {
365d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
366d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    }
367e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
368618ff8a48a0c895a78f91f5692510c2a809425c3Chien-Yu Chen    bool isInput = false;
369e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    ssize_t index = NAME_NOT_FOUND;
3705d677d1f0879d5101e38df480a38228a64d63959Zhijun He    ssize_t dIndex = NAME_NOT_FOUND;
371618ff8a48a0c895a78f91f5692510c2a809425c3Chien-Yu Chen
372618ff8a48a0c895a78f91f5692510c2a809425c3Chien-Yu Chen    if (mInputStream.configured && mInputStream.id == streamId) {
373618ff8a48a0c895a78f91f5692510c2a809425c3Chien-Yu Chen        isInput = true;
374618ff8a48a0c895a78f91f5692510c2a809425c3Chien-Yu Chen    } else {
375618ff8a48a0c895a78f91f5692510c2a809425c3Chien-Yu Chen        // Guard against trying to delete non-created streams
376618ff8a48a0c895a78f91f5692510c2a809425c3Chien-Yu Chen        for (size_t i = 0; i < mStreamMap.size(); ++i) {
377618ff8a48a0c895a78f91f5692510c2a809425c3Chien-Yu Chen            if (streamId == mStreamMap.valueAt(i)) {
378618ff8a48a0c895a78f91f5692510c2a809425c3Chien-Yu Chen                index = i;
379618ff8a48a0c895a78f91f5692510c2a809425c3Chien-Yu Chen                break;
380618ff8a48a0c895a78f91f5692510c2a809425c3Chien-Yu Chen            }
381e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        }
382e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
383618ff8a48a0c895a78f91f5692510c2a809425c3Chien-Yu Chen        if (index == NAME_NOT_FOUND) {
3845d677d1f0879d5101e38df480a38228a64d63959Zhijun He            // See if this stream is one of the deferred streams.
3855d677d1f0879d5101e38df480a38228a64d63959Zhijun He            for (size_t i = 0; i < mDeferredStreams.size(); ++i) {
3865d677d1f0879d5101e38df480a38228a64d63959Zhijun He                if (streamId == mDeferredStreams[i]) {
3875d677d1f0879d5101e38df480a38228a64d63959Zhijun He                    dIndex = i;
3885d677d1f0879d5101e38df480a38228a64d63959Zhijun He                    break;
3895d677d1f0879d5101e38df480a38228a64d63959Zhijun He                }
3905d677d1f0879d5101e38df480a38228a64d63959Zhijun He            }
3915d677d1f0879d5101e38df480a38228a64d63959Zhijun He            if (dIndex == NAME_NOT_FOUND) {
3925d677d1f0879d5101e38df480a38228a64d63959Zhijun He                String8 msg = String8::format("Camera %d: Invalid stream ID (%d) specified, no such"
3935d677d1f0879d5101e38df480a38228a64d63959Zhijun He                        " stream created yet", mCameraId, streamId);
3945d677d1f0879d5101e38df480a38228a64d63959Zhijun He                ALOGW("%s: %s", __FUNCTION__, msg.string());
3955d677d1f0879d5101e38df480a38228a64d63959Zhijun He                return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
3965d677d1f0879d5101e38df480a38228a64d63959Zhijun He            }
397618ff8a48a0c895a78f91f5692510c2a809425c3Chien-Yu Chen        }
398e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
399e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
400e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    // Also returns BAD_VALUE if stream ID was not valid
401d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    status_t err = mDevice->deleteStream(streamId);
402e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
403d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if (err != OK) {
404d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        String8 msg = String8::format("Camera %d: Unexpected error %s (%d) when deleting stream %d",
405d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                mCameraId, strerror(-err), err, streamId);
406d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        ALOGE("%s: %s", __FUNCTION__, msg.string());
407d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
408d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    } else {
409618ff8a48a0c895a78f91f5692510c2a809425c3Chien-Yu Chen        if (isInput) {
410618ff8a48a0c895a78f91f5692510c2a809425c3Chien-Yu Chen            mInputStream.configured = false;
4115d677d1f0879d5101e38df480a38228a64d63959Zhijun He        } else if (index != NAME_NOT_FOUND) {
412618ff8a48a0c895a78f91f5692510c2a809425c3Chien-Yu Chen            mStreamMap.removeItemsAt(index);
4135d677d1f0879d5101e38df480a38228a64d63959Zhijun He        } else {
4145d677d1f0879d5101e38df480a38228a64d63959Zhijun He            mDeferredStreams.removeItemsAt(dIndex);
415618ff8a48a0c895a78f91f5692510c2a809425c3Chien-Yu Chen        }
416e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
417e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
418e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    return res;
419e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin}
420e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
421d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvalabinder::Status CameraDeviceClient::createStream(
422d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        const hardware::camera2::params::OutputConfiguration &outputConfiguration,
423d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        /*out*/
424d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        int32_t* newStreamId) {
425e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    ATRACE_CALL();
426e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
427d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    binder::Status res;
428d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
429e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
430e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    Mutex::Autolock icl(mBinderSerializationLock);
431e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
432b97babb8c08969b55af3b6456d15f764c8873d3fYin-Chia Yeh    sp<IGraphicBufferProducer> bufferProducer = outputConfiguration.getGraphicBufferProducer();
4335d677d1f0879d5101e38df480a38228a64d63959Zhijun He    bool deferredConsumer = bufferProducer == NULL;
4345d677d1f0879d5101e38df480a38228a64d63959Zhijun He    int surfaceType = outputConfiguration.getSurfaceType();
4355d677d1f0879d5101e38df480a38228a64d63959Zhijun He    bool validSurfaceType = ((surfaceType == OutputConfiguration::SURFACE_TYPE_SURFACE_VIEW) ||
4365d677d1f0879d5101e38df480a38228a64d63959Zhijun He            (surfaceType == OutputConfiguration::SURFACE_TYPE_SURFACE_TEXTURE));
4375d677d1f0879d5101e38df480a38228a64d63959Zhijun He    if (deferredConsumer && !validSurfaceType) {
4385d677d1f0879d5101e38df480a38228a64d63959Zhijun He        ALOGE("%s: Target surface is invalid: bufferProducer = %p, surfaceType = %d.",
4395d677d1f0879d5101e38df480a38228a64d63959Zhijun He                __FUNCTION__, bufferProducer.get(), surfaceType);
440d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "Target Surface is invalid");
441d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    }
4425d677d1f0879d5101e38df480a38228a64d63959Zhijun He
443d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if (!mDevice.get()) {
444d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
44589f14dacfadea1b14149510d4dfbc75dc79b23bbYin-Chia Yeh    }
446e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
4475d677d1f0879d5101e38df480a38228a64d63959Zhijun He    int width, height, format;
4485d677d1f0879d5101e38df480a38228a64d63959Zhijun He    int32_t consumerUsage;
4495d677d1f0879d5101e38df480a38228a64d63959Zhijun He    android_dataspace dataSpace;
4505d677d1f0879d5101e38df480a38228a64d63959Zhijun He    status_t err;
4515d677d1f0879d5101e38df480a38228a64d63959Zhijun He
4525d677d1f0879d5101e38df480a38228a64d63959Zhijun He    // Create stream for deferred surface case.
4535d677d1f0879d5101e38df480a38228a64d63959Zhijun He    if (deferredConsumer) {
4545d677d1f0879d5101e38df480a38228a64d63959Zhijun He        return createDeferredSurfaceStreamLocked(outputConfiguration, newStreamId);
4555d677d1f0879d5101e38df480a38228a64d63959Zhijun He    }
4565d677d1f0879d5101e38df480a38228a64d63959Zhijun He
457e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    // Don't create multiple streams for the same target surface
458e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    {
459f888020c6e2735624f2b2a30e72aca24e17b8b4dMarco Nelissen        ssize_t index = mStreamMap.indexOfKey(IInterface::asBinder(bufferProducer));
460e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        if (index != NAME_NOT_FOUND) {
461d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            String8 msg = String8::format("Camera %d: Surface already has a stream created for it "
462d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    "(ID %zd)", mCameraId, index);
463d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            ALOGW("%s: %s", __FUNCTION__, msg.string());
464d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            return STATUS_ERROR(CameraService::ERROR_ALREADY_EXISTS, msg.string());
465e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        }
466e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
467e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
4681da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala    // HACK b/10949105
4691da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala    // Query consumer usage bits to set async operation mode for
4701da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala    // GLConsumer using controlledByApp parameter.
4711da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala    bool useAsync = false;
472d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if ((err = bufferProducer->query(NATIVE_WINDOW_CONSUMER_USAGE_BITS,
4731da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala            &consumerUsage)) != OK) {
474d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        String8 msg = String8::format("Camera %d: Failed to query Surface consumer usage: %s (%d)",
475d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                mCameraId, strerror(-err), err);
476d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        ALOGE("%s: %s", __FUNCTION__, msg.string());
477d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
4781da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala    }
4791da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala    if (consumerUsage & GraphicBuffer::USAGE_HW_TEXTURE) {
4805d677d1f0879d5101e38df480a38228a64d63959Zhijun He        ALOGW("%s: Camera %d with consumer usage flag: 0x%x: Forcing asynchronous mode for stream",
4815d677d1f0879d5101e38df480a38228a64d63959Zhijun He                __FUNCTION__, mCameraId, consumerUsage);
4821da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala        useAsync = true;
4831da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala    }
4841da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala
485bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk    int32_t disallowedFlags = GraphicBuffer::USAGE_HW_VIDEO_ENCODER |
486bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk                              GRALLOC_USAGE_RENDERSCRIPT;
487bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk    int32_t allowedFlags = GraphicBuffer::USAGE_SW_READ_MASK |
488bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk                           GraphicBuffer::USAGE_HW_TEXTURE |
489bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk                           GraphicBuffer::USAGE_HW_COMPOSER;
490bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk    bool flexibleConsumer = (consumerUsage & disallowedFlags) == 0 &&
491bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk            (consumerUsage & allowedFlags) != 0;
492bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk
493f888020c6e2735624f2b2a30e72aca24e17b8b4dMarco Nelissen    sp<IBinder> binder = IInterface::asBinder(bufferProducer);
494727d172137b4f32681c098de8e2623c0b65a6406Eino-Ville Talvala    sp<Surface> surface = new Surface(bufferProducer, useAsync);
495727d172137b4f32681c098de8e2623c0b65a6406Eino-Ville Talvala    ANativeWindow *anw = surface.get();
496e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
497d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if ((err = anw->query(anw, NATIVE_WINDOW_WIDTH, &width)) != OK) {
498d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        String8 msg = String8::format("Camera %d: Failed to query Surface width: %s (%d)",
499d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                mCameraId, strerror(-err), err);
500d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        ALOGE("%s: %s", __FUNCTION__, msg.string());
501d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
502e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
503d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if ((err = anw->query(anw, NATIVE_WINDOW_HEIGHT, &height)) != OK) {
504d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        String8 msg = String8::format("Camera %d: Failed to query Surface height: %s (%d)",
505d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                mCameraId, strerror(-err), err);
506d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        ALOGE("%s: %s", __FUNCTION__, msg.string());
507d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
508e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
509d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if ((err = anw->query(anw, NATIVE_WINDOW_FORMAT, &format)) != OK) {
510d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        String8 msg = String8::format("Camera %d: Failed to query Surface format: %s (%d)",
511d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                mCameraId, strerror(-err), err);
512d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        ALOGE("%s: %s", __FUNCTION__, msg.string());
513d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
514e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
515d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if ((err = anw->query(anw, NATIVE_WINDOW_DEFAULT_DATASPACE,
5163d82c0d9ed2b3e956ad699a9ca2c8a70c9d24678Eino-Ville Talvala                            reinterpret_cast<int*>(&dataSpace))) != OK) {
517d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        String8 msg = String8::format("Camera %d: Failed to query Surface dataspace: %s (%d)",
518d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                mCameraId, strerror(-err), err);
519d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        ALOGE("%s: %s", __FUNCTION__, msg.string());
520d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
5213d82c0d9ed2b3e956ad699a9ca2c8a70c9d24678Eino-Ville Talvala    }
522e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
523e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    // FIXME: remove this override since the default format should be
524e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    //       IMPLEMENTATION_DEFINED. b/9487482
5251581101ce2a8c1b8d0b07b643ad891595221d781Igor Murashkin    if (format >= HAL_PIXEL_FORMAT_RGBA_8888 &&
5261581101ce2a8c1b8d0b07b643ad891595221d781Igor Murashkin        format <= HAL_PIXEL_FORMAT_BGRA_8888) {
527bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk        ALOGW("%s: Camera %d: Overriding format %#x to IMPLEMENTATION_DEFINED",
528e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin              __FUNCTION__, mCameraId, format);
529e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
530e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
531e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
532bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk    // Round dimensions to the nearest dimensions available for this format
533bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk    if (flexibleConsumer && !CameraDeviceClient::roundBufferDimensionNearest(width, height,
5343d82c0d9ed2b3e956ad699a9ca2c8a70c9d24678Eino-Ville Talvala            format, dataSpace, mDevice->info(), /*out*/&width, /*out*/&height)) {
535d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        String8 msg = String8::format("Camera %d: No supported stream configurations with "
536d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                "format %#x defined, failed to create output stream", mCameraId, format);
537d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        ALOGE("%s: %s", __FUNCTION__, msg.string());
538d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
539bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk    }
540e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
541125684aba1a11b7adbf5f9d607ee2bcc9449081cZhijun He    int streamId = camera3::CAMERA3_STREAM_ID_INVALID;
542d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    err = mDevice->createStream(surface, width, height, format, dataSpace,
543d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            static_cast<camera3_stream_rotation_t>(outputConfiguration.getRotation()),
544d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            &streamId, outputConfiguration.getSurfaceSetID());
545d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala
546d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if (err != OK) {
547d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
548d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                "Camera %d: Error creating output stream (%d x %d, fmt %x, dataSpace %x): %s (%d)",
549d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                mCameraId, width, height, format, dataSpace, strerror(-err), err);
550d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    } else {
551e992e75053e98e3699af6e344c11b787e30411adEino-Ville Talvala        mStreamMap.add(binder, streamId);
552e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
5535d677d1f0879d5101e38df480a38228a64d63959Zhijun He        ALOGV("%s: Camera %d: Successfully created a new stream ID %d for output surface"
5545d677d1f0879d5101e38df480a38228a64d63959Zhijun He                " (%d x %d) with format 0x%x.",
5555d677d1f0879d5101e38df480a38228a64d63959Zhijun He              __FUNCTION__, mCameraId, streamId, width, height, format);
556f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin
5575d677d1f0879d5101e38df480a38228a64d63959Zhijun He        // Set transform flags to ensure preview to be rotated correctly.
5585d677d1f0879d5101e38df480a38228a64d63959Zhijun He        res = setStreamTransformLocked(streamId);
559f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin
5605d677d1f0879d5101e38df480a38228a64d63959Zhijun He        *newStreamId = streamId;
5615d677d1f0879d5101e38df480a38228a64d63959Zhijun He    }
562f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin
5635d677d1f0879d5101e38df480a38228a64d63959Zhijun He    return res;
5645d677d1f0879d5101e38df480a38228a64d63959Zhijun He}
565f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin
5665d677d1f0879d5101e38df480a38228a64d63959Zhijun Hebinder::Status CameraDeviceClient::createDeferredSurfaceStreamLocked(
5675d677d1f0879d5101e38df480a38228a64d63959Zhijun He        const hardware::camera2::params::OutputConfiguration &outputConfiguration,
5685d677d1f0879d5101e38df480a38228a64d63959Zhijun He        /*out*/
5695d677d1f0879d5101e38df480a38228a64d63959Zhijun He        int* newStreamId) {
5705d677d1f0879d5101e38df480a38228a64d63959Zhijun He    int width, height, format, surfaceType;
5715d677d1f0879d5101e38df480a38228a64d63959Zhijun He    int32_t consumerUsage;
5725d677d1f0879d5101e38df480a38228a64d63959Zhijun He    android_dataspace dataSpace;
5735d677d1f0879d5101e38df480a38228a64d63959Zhijun He    status_t err;
5745d677d1f0879d5101e38df480a38228a64d63959Zhijun He    binder::Status res;
5755d677d1f0879d5101e38df480a38228a64d63959Zhijun He
5765d677d1f0879d5101e38df480a38228a64d63959Zhijun He    if (!mDevice.get()) {
5775d677d1f0879d5101e38df480a38228a64d63959Zhijun He        return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
5785d677d1f0879d5101e38df480a38228a64d63959Zhijun He    }
5795d677d1f0879d5101e38df480a38228a64d63959Zhijun He
5805d677d1f0879d5101e38df480a38228a64d63959Zhijun He    // Infer the surface info for deferred surface stream creation.
5815d677d1f0879d5101e38df480a38228a64d63959Zhijun He    width = outputConfiguration.getWidth();
5825d677d1f0879d5101e38df480a38228a64d63959Zhijun He    height = outputConfiguration.getHeight();
5835d677d1f0879d5101e38df480a38228a64d63959Zhijun He    surfaceType = outputConfiguration.getSurfaceType();
5845d677d1f0879d5101e38df480a38228a64d63959Zhijun He    format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
5855d677d1f0879d5101e38df480a38228a64d63959Zhijun He    dataSpace = android_dataspace_t::HAL_DATASPACE_UNKNOWN;
5865d677d1f0879d5101e38df480a38228a64d63959Zhijun He    // Hardcode consumer usage flags: SurfaceView--0x900, SurfaceTexture--0x100.
5875d677d1f0879d5101e38df480a38228a64d63959Zhijun He    consumerUsage = GraphicBuffer::USAGE_HW_TEXTURE;
5885d677d1f0879d5101e38df480a38228a64d63959Zhijun He    if (surfaceType == OutputConfiguration::SURFACE_TYPE_SURFACE_VIEW) {
5895d677d1f0879d5101e38df480a38228a64d63959Zhijun He        consumerUsage |= GraphicBuffer::USAGE_HW_COMPOSER;
590e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
5915d677d1f0879d5101e38df480a38228a64d63959Zhijun He    int streamId = camera3::CAMERA3_STREAM_ID_INVALID;
5925d677d1f0879d5101e38df480a38228a64d63959Zhijun He    err = mDevice->createStream(/*surface*/nullptr, width, height, format, dataSpace,
5935d677d1f0879d5101e38df480a38228a64d63959Zhijun He            static_cast<camera3_stream_rotation_t>(outputConfiguration.getRotation()),
5945d677d1f0879d5101e38df480a38228a64d63959Zhijun He            &streamId, outputConfiguration.getSurfaceSetID(), consumerUsage);
5955d677d1f0879d5101e38df480a38228a64d63959Zhijun He
5965d677d1f0879d5101e38df480a38228a64d63959Zhijun He    if (err != OK) {
5975d677d1f0879d5101e38df480a38228a64d63959Zhijun He        res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
5985d677d1f0879d5101e38df480a38228a64d63959Zhijun He                "Camera %d: Error creating output stream (%d x %d, fmt %x, dataSpace %x): %s (%d)",
5995d677d1f0879d5101e38df480a38228a64d63959Zhijun He                mCameraId, width, height, format, dataSpace, strerror(-err), err);
6005d677d1f0879d5101e38df480a38228a64d63959Zhijun He    } else {
6015d677d1f0879d5101e38df480a38228a64d63959Zhijun He        // Can not add streamId to mStreamMap here, as the surface is deferred. Add it to
6025d677d1f0879d5101e38df480a38228a64d63959Zhijun He        // a separate list to track. Once the deferred surface is set, this id will be
6035d677d1f0879d5101e38df480a38228a64d63959Zhijun He        // relocated to mStreamMap.
6045d677d1f0879d5101e38df480a38228a64d63959Zhijun He        mDeferredStreams.push_back(streamId);
605e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
6065d677d1f0879d5101e38df480a38228a64d63959Zhijun He        ALOGV("%s: Camera %d: Successfully created a new stream ID %d for a deferred surface"
6075d677d1f0879d5101e38df480a38228a64d63959Zhijun He                " (%d x %d) stream with format 0x%x.",
6085d677d1f0879d5101e38df480a38228a64d63959Zhijun He              __FUNCTION__, mCameraId, streamId, width, height, format);
6095d677d1f0879d5101e38df480a38228a64d63959Zhijun He
6105d677d1f0879d5101e38df480a38228a64d63959Zhijun He        // Set transform flags to ensure preview to be rotated correctly.
6115d677d1f0879d5101e38df480a38228a64d63959Zhijun He        res = setStreamTransformLocked(streamId);
6125d677d1f0879d5101e38df480a38228a64d63959Zhijun He
6135d677d1f0879d5101e38df480a38228a64d63959Zhijun He        *newStreamId = streamId;
6145d677d1f0879d5101e38df480a38228a64d63959Zhijun He    }
615e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    return res;
616e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin}
617e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
6185d677d1f0879d5101e38df480a38228a64d63959Zhijun Hebinder::Status CameraDeviceClient::setStreamTransformLocked(int streamId) {
6195d677d1f0879d5101e38df480a38228a64d63959Zhijun He    int32_t transform = 0;
6205d677d1f0879d5101e38df480a38228a64d63959Zhijun He    status_t err;
6215d677d1f0879d5101e38df480a38228a64d63959Zhijun He    binder::Status res;
6225d677d1f0879d5101e38df480a38228a64d63959Zhijun He
6235d677d1f0879d5101e38df480a38228a64d63959Zhijun He    if (!mDevice.get()) {
6245d677d1f0879d5101e38df480a38228a64d63959Zhijun He        return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
6255d677d1f0879d5101e38df480a38228a64d63959Zhijun He    }
6265d677d1f0879d5101e38df480a38228a64d63959Zhijun He
6275d677d1f0879d5101e38df480a38228a64d63959Zhijun He    err = getRotationTransformLocked(&transform);
6285d677d1f0879d5101e38df480a38228a64d63959Zhijun He    if (err != OK) {
6295d677d1f0879d5101e38df480a38228a64d63959Zhijun He        // Error logged by getRotationTransformLocked.
6305d677d1f0879d5101e38df480a38228a64d63959Zhijun He        return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION,
6315d677d1f0879d5101e38df480a38228a64d63959Zhijun He                "Unable to calculate rotation transform for new stream");
6325d677d1f0879d5101e38df480a38228a64d63959Zhijun He    }
6335d677d1f0879d5101e38df480a38228a64d63959Zhijun He
6345d677d1f0879d5101e38df480a38228a64d63959Zhijun He    err = mDevice->setStreamTransform(streamId, transform);
6355d677d1f0879d5101e38df480a38228a64d63959Zhijun He    if (err != OK) {
6365d677d1f0879d5101e38df480a38228a64d63959Zhijun He        String8 msg = String8::format("Failed to set stream transform (stream id %d)",
6375d677d1f0879d5101e38df480a38228a64d63959Zhijun He                streamId);
6385d677d1f0879d5101e38df480a38228a64d63959Zhijun He        ALOGE("%s: %s", __FUNCTION__, msg.string());
6395d677d1f0879d5101e38df480a38228a64d63959Zhijun He        return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
6405d677d1f0879d5101e38df480a38228a64d63959Zhijun He    }
6415d677d1f0879d5101e38df480a38228a64d63959Zhijun He
6425d677d1f0879d5101e38df480a38228a64d63959Zhijun He    return res;
6435d677d1f0879d5101e38df480a38228a64d63959Zhijun He}
644bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk
645d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvalabinder::Status CameraDeviceClient::createInputStream(
646d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        int width, int height, int format,
647d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        /*out*/
648d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        int32_t* newStreamId) {
649618ff8a48a0c895a78f91f5692510c2a809425c3Chien-Yu Chen
650618ff8a48a0c895a78f91f5692510c2a809425c3Chien-Yu Chen    ATRACE_CALL();
651618ff8a48a0c895a78f91f5692510c2a809425c3Chien-Yu Chen    ALOGV("%s (w = %d, h = %d, f = 0x%x)", __FUNCTION__, width, height, format);
652618ff8a48a0c895a78f91f5692510c2a809425c3Chien-Yu Chen
653d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    binder::Status res;
654d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
655618ff8a48a0c895a78f91f5692510c2a809425c3Chien-Yu Chen
656618ff8a48a0c895a78f91f5692510c2a809425c3Chien-Yu Chen    Mutex::Autolock icl(mBinderSerializationLock);
657d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala
658d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if (!mDevice.get()) {
659d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
660d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    }
661618ff8a48a0c895a78f91f5692510c2a809425c3Chien-Yu Chen
662618ff8a48a0c895a78f91f5692510c2a809425c3Chien-Yu Chen    if (mInputStream.configured) {
663d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        String8 msg = String8::format("Camera %d: Already has an input stream "
664d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                "configured (ID %zd)", mCameraId, mInputStream.id);
665d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        ALOGE("%s: %s", __FUNCTION__, msg.string() );
666d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(CameraService::ERROR_ALREADY_EXISTS, msg.string());
667618ff8a48a0c895a78f91f5692510c2a809425c3Chien-Yu Chen    }
668618ff8a48a0c895a78f91f5692510c2a809425c3Chien-Yu Chen
669618ff8a48a0c895a78f91f5692510c2a809425c3Chien-Yu Chen    int streamId = -1;
670d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    status_t err = mDevice->createInputStream(width, height, format, &streamId);
671d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if (err == OK) {
672618ff8a48a0c895a78f91f5692510c2a809425c3Chien-Yu Chen        mInputStream.configured = true;
673618ff8a48a0c895a78f91f5692510c2a809425c3Chien-Yu Chen        mInputStream.width = width;
674618ff8a48a0c895a78f91f5692510c2a809425c3Chien-Yu Chen        mInputStream.height = height;
675618ff8a48a0c895a78f91f5692510c2a809425c3Chien-Yu Chen        mInputStream.format = format;
676618ff8a48a0c895a78f91f5692510c2a809425c3Chien-Yu Chen        mInputStream.id = streamId;
677618ff8a48a0c895a78f91f5692510c2a809425c3Chien-Yu Chen
678618ff8a48a0c895a78f91f5692510c2a809425c3Chien-Yu Chen        ALOGV("%s: Camera %d: Successfully created a new input stream ID %d",
679d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                __FUNCTION__, mCameraId, streamId);
680618ff8a48a0c895a78f91f5692510c2a809425c3Chien-Yu Chen
681d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        *newStreamId = streamId;
682d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    } else {
683d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
684d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                "Camera %d: Error creating new input stream: %s (%d)", mCameraId,
685d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                strerror(-err), err);
686618ff8a48a0c895a78f91f5692510c2a809425c3Chien-Yu Chen    }
687618ff8a48a0c895a78f91f5692510c2a809425c3Chien-Yu Chen
688618ff8a48a0c895a78f91f5692510c2a809425c3Chien-Yu Chen    return res;
689618ff8a48a0c895a78f91f5692510c2a809425c3Chien-Yu Chen}
690618ff8a48a0c895a78f91f5692510c2a809425c3Chien-Yu Chen
691d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvalabinder::Status CameraDeviceClient::getInputSurface(/*out*/ view::Surface *inputSurface) {
692d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala
693d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    binder::Status res;
694d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
695618ff8a48a0c895a78f91f5692510c2a809425c3Chien-Yu Chen
696d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if (inputSurface == NULL) {
697d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "Null input surface");
698618ff8a48a0c895a78f91f5692510c2a809425c3Chien-Yu Chen    }
699618ff8a48a0c895a78f91f5692510c2a809425c3Chien-Yu Chen
700618ff8a48a0c895a78f91f5692510c2a809425c3Chien-Yu Chen    Mutex::Autolock icl(mBinderSerializationLock);
701d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if (!mDevice.get()) {
702d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
703d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    }
704d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    sp<IGraphicBufferProducer> producer;
705d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    status_t err = mDevice->getInputBufferProducer(&producer);
706d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if (err != OK) {
707d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
708d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                "Camera %d: Error getting input Surface: %s (%d)",
709d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                mCameraId, strerror(-err), err);
710d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    } else {
711d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        inputSurface->name = String16("CameraInput");
712d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        inputSurface->graphicBufferProducer = producer;
713d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    }
714d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return res;
715618ff8a48a0c895a78f91f5692510c2a809425c3Chien-Yu Chen}
716618ff8a48a0c895a78f91f5692510c2a809425c3Chien-Yu Chen
717bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunkbool CameraDeviceClient::roundBufferDimensionNearest(int32_t width, int32_t height,
7183d82c0d9ed2b3e956ad699a9ca2c8a70c9d24678Eino-Ville Talvala        int32_t format, android_dataspace dataSpace, const CameraMetadata& info,
719bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk        /*out*/int32_t* outWidth, /*out*/int32_t* outHeight) {
720bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk
721bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk    camera_metadata_ro_entry streamConfigs =
7223d82c0d9ed2b3e956ad699a9ca2c8a70c9d24678Eino-Ville Talvala            (dataSpace == HAL_DATASPACE_DEPTH) ?
7233d82c0d9ed2b3e956ad699a9ca2c8a70c9d24678Eino-Ville Talvala            info.find(ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS) :
724bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk            info.find(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS);
725bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk
726bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk    int32_t bestWidth = -1;
727bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk    int32_t bestHeight = -1;
728bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk
729bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk    // Iterate through listed stream configurations and find the one with the smallest euclidean
730bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk    // distance from the given dimensions for the given format.
731bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk    for (size_t i = 0; i < streamConfigs.count; i += 4) {
732bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk        int32_t fmt = streamConfigs.data.i32[i];
733bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk        int32_t w = streamConfigs.data.i32[i + 1];
734bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk        int32_t h = streamConfigs.data.i32[i + 2];
735bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk
736bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk        // Ignore input/output type for now
737bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk        if (fmt == format) {
738bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk            if (w == width && h == height) {
739bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk                bestWidth = width;
740bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk                bestHeight = height;
741bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk                break;
742bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk            } else if (w <= ROUNDING_WIDTH_CAP && (bestWidth == -1 ||
743bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk                    CameraDeviceClient::euclidDistSquare(w, h, width, height) <
744bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk                    CameraDeviceClient::euclidDistSquare(bestWidth, bestHeight, width, height))) {
745bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk                bestWidth = w;
746bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk                bestHeight = h;
747bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk            }
748bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk        }
749bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk    }
750bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk
751bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk    if (bestWidth == -1) {
752bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk        // Return false if no configurations for this format were listed
753bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk        return false;
754bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk    }
755bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk
756bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk    // Set the outputs to the closet width/height
757bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk    if (outWidth != NULL) {
758bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk        *outWidth = bestWidth;
759bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk    }
760bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk    if (outHeight != NULL) {
761bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk        *outHeight = bestHeight;
762bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk    }
763bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk
764bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk    // Return true if at least one configuration for this format was listed
765bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk    return true;
766bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk}
767bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk
768bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunkint64_t CameraDeviceClient::euclidDistSquare(int32_t x0, int32_t y0, int32_t x1, int32_t y1) {
769bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk    int64_t d0 = x0 - x1;
770bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk    int64_t d1 = y0 - y1;
771bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk    return d0 * d0 + d1 * d1;
772bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk}
773bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk
774e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin// Create a request object from a template.
775d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvalabinder::Status CameraDeviceClient::createDefaultRequest(int templateId,
776d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        /*out*/
777d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        hardware::camera2::impl::CameraMetadataNative* request)
778e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin{
779e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    ATRACE_CALL();
780e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    ALOGV("%s (templateId = 0x%x)", __FUNCTION__, templateId);
781e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
782d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    binder::Status res;
783d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
784e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
785e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    Mutex::Autolock icl(mBinderSerializationLock);
786e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
787d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if (!mDevice.get()) {
788d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
789d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    }
790e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
791e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    CameraMetadata metadata;
792d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    status_t err;
793d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if ( (err = mDevice->createDefaultRequest(templateId, &metadata) ) == OK &&
794e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        request != NULL) {
795e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
796e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        request->swap(metadata);
7979cd140240c84789d00349c33e9c0b7a74d1543edChien-Yu Chen    } else if (err == BAD_VALUE) {
7989cd140240c84789d00349c33e9c0b7a74d1543edChien-Yu Chen        res = STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
7999cd140240c84789d00349c33e9c0b7a74d1543edChien-Yu Chen                "Camera %d: Template ID %d is invalid or not supported: %s (%d)",
8009cd140240c84789d00349c33e9c0b7a74d1543edChien-Yu Chen                mCameraId, templateId, strerror(-err), err);
8019cd140240c84789d00349c33e9c0b7a74d1543edChien-Yu Chen
802d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    } else {
803d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
804d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                "Camera %d: Error creating default request for template %d: %s (%d)",
805d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                mCameraId, templateId, strerror(-err), err);
806e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
807e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    return res;
808e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin}
809e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
810d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvalabinder::Status CameraDeviceClient::getCameraInfo(
811d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        /*out*/
812d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        hardware::camera2::impl::CameraMetadataNative* info)
813e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin{
814e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    ATRACE_CALL();
815e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    ALOGV("%s", __FUNCTION__);
816e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
817d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    binder::Status res;
818e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
819d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
820e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
821e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    Mutex::Autolock icl(mBinderSerializationLock);
822e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
823d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if (!mDevice.get()) {
824d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
825d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    }
826e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
827099b457f3203fa51387e21bd450495abb973ab31Igor Murashkin    if (info != NULL) {
828099b457f3203fa51387e21bd450495abb973ab31Igor Murashkin        *info = mDevice->info(); // static camera metadata
829099b457f3203fa51387e21bd450495abb973ab31Igor Murashkin        // TODO: merge with device-specific camera metadata
830099b457f3203fa51387e21bd450495abb973ab31Igor Murashkin    }
831e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
832e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    return res;
833e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin}
834e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
835d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvalabinder::Status CameraDeviceClient::waitUntilIdle()
8362ab500c632569e2f131a1a2288459933da70c4eeZhijun He{
8372ab500c632569e2f131a1a2288459933da70c4eeZhijun He    ATRACE_CALL();
8382ab500c632569e2f131a1a2288459933da70c4eeZhijun He    ALOGV("%s", __FUNCTION__);
8392ab500c632569e2f131a1a2288459933da70c4eeZhijun He
840d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    binder::Status res;
841d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
8422ab500c632569e2f131a1a2288459933da70c4eeZhijun He
8432ab500c632569e2f131a1a2288459933da70c4eeZhijun He    Mutex::Autolock icl(mBinderSerializationLock);
8442ab500c632569e2f131a1a2288459933da70c4eeZhijun He
845d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if (!mDevice.get()) {
846d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
847d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    }
8482ab500c632569e2f131a1a2288459933da70c4eeZhijun He
8492ab500c632569e2f131a1a2288459933da70c4eeZhijun He    // FIXME: Also need check repeating burst.
850c9ca6788c65ed3f578d1a1ed0ba7c268254dcb4bShuzhen Wang    Mutex::Autolock idLock(mStreamingRequestIdLock);
851e8c535e833ed135895e99ca81aa3b85d80d7cf3cChien-Yu Chen    if (mStreamingRequestId != REQUEST_ID_NONE) {
852d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        String8 msg = String8::format(
853d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            "Camera %d: Try to waitUntilIdle when there are active streaming requests",
854d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            mCameraId);
855d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        ALOGE("%s: %s", __FUNCTION__, msg.string());
856d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
857d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    }
858d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    status_t err = mDevice->waitUntilDrained();
859d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if (err != OK) {
860d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
861d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                "Camera %d: Error waiting to drain: %s (%d)",
862d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                mCameraId, strerror(-err), err);
8632ab500c632569e2f131a1a2288459933da70c4eeZhijun He    }
8642ab500c632569e2f131a1a2288459933da70c4eeZhijun He    ALOGV("%s Done", __FUNCTION__);
8652ab500c632569e2f131a1a2288459933da70c4eeZhijun He    return res;
8662ab500c632569e2f131a1a2288459933da70c4eeZhijun He}
8672ab500c632569e2f131a1a2288459933da70c4eeZhijun He
868d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvalabinder::Status CameraDeviceClient::flush(
869d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        /*out*/
870d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        int64_t* lastFrameNumber) {
871abaa51d3ca31f0eda99e1d271e6dc64c877dbf58Eino-Ville Talvala    ATRACE_CALL();
872abaa51d3ca31f0eda99e1d271e6dc64c877dbf58Eino-Ville Talvala    ALOGV("%s", __FUNCTION__);
873abaa51d3ca31f0eda99e1d271e6dc64c877dbf58Eino-Ville Talvala
874d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    binder::Status res;
875d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
876abaa51d3ca31f0eda99e1d271e6dc64c877dbf58Eino-Ville Talvala
877abaa51d3ca31f0eda99e1d271e6dc64c877dbf58Eino-Ville Talvala    Mutex::Autolock icl(mBinderSerializationLock);
878abaa51d3ca31f0eda99e1d271e6dc64c877dbf58Eino-Ville Talvala
879d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if (!mDevice.get()) {
880d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
881d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    }
882abaa51d3ca31f0eda99e1d271e6dc64c877dbf58Eino-Ville Talvala
883c9ca6788c65ed3f578d1a1ed0ba7c268254dcb4bShuzhen Wang    Mutex::Autolock idLock(mStreamingRequestIdLock);
884e8c535e833ed135895e99ca81aa3b85d80d7cf3cChien-Yu Chen    mStreamingRequestId = REQUEST_ID_NONE;
885d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    status_t err = mDevice->flush(lastFrameNumber);
886d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if (err != OK) {
887d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
888d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                "Camera %d: Error flushing device: %s (%d)", mCameraId, strerror(-err), err);
889d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    }
890d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return res;
891abaa51d3ca31f0eda99e1d271e6dc64c877dbf58Eino-Ville Talvala}
892abaa51d3ca31f0eda99e1d271e6dc64c877dbf58Eino-Ville Talvala
893d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvalabinder::Status CameraDeviceClient::prepare(int streamId) {
8944d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala    ATRACE_CALL();
8954d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala    ALOGV("%s", __FUNCTION__);
8964d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala
897d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    binder::Status res;
898d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
8994d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala
9004d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala    Mutex::Autolock icl(mBinderSerializationLock);
9014d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala
9024d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala    // Guard against trying to prepare non-created streams
9034d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala    ssize_t index = NAME_NOT_FOUND;
9044d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala    for (size_t i = 0; i < mStreamMap.size(); ++i) {
9054d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala        if (streamId == mStreamMap.valueAt(i)) {
9064d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala            index = i;
9074d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala            break;
9084d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala        }
9094d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala    }
9104d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala
9114d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala    if (index == NAME_NOT_FOUND) {
912d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        String8 msg = String8::format("Camera %d: Invalid stream ID (%d) specified, no stream "
913d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala              "with that ID exists", mCameraId, streamId);
914d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        ALOGW("%s: %s", __FUNCTION__, msg.string());
915d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
9164d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala    }
9174d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala
918261394e3edbe10f4f145f543187dcfbabf702c11Eino-Ville Talvala    // Also returns BAD_VALUE if stream ID was not valid, or stream already
919261394e3edbe10f4f145f543187dcfbabf702c11Eino-Ville Talvala    // has been used
920d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    status_t err = mDevice->prepare(streamId);
921d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if (err == BAD_VALUE) {
922d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        res = STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
923d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                "Camera %d: Stream %d has already been used, and cannot be prepared",
924d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                mCameraId, streamId);
925d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    } else if (err != OK) {
926d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
927d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                "Camera %d: Error preparing stream %d: %s (%d)", mCameraId, streamId,
928d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                strerror(-err), err);
929d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    }
9304d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala    return res;
9314d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala}
9324d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala
933d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvalabinder::Status CameraDeviceClient::prepare2(int maxCount, int streamId) {
934c78ac26e3a65328fc0118f16ee76a800d0687eb7Ruben Brunk    ATRACE_CALL();
935c78ac26e3a65328fc0118f16ee76a800d0687eb7Ruben Brunk    ALOGV("%s", __FUNCTION__);
936c78ac26e3a65328fc0118f16ee76a800d0687eb7Ruben Brunk
937d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    binder::Status res;
938d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
939c78ac26e3a65328fc0118f16ee76a800d0687eb7Ruben Brunk
940c78ac26e3a65328fc0118f16ee76a800d0687eb7Ruben Brunk    Mutex::Autolock icl(mBinderSerializationLock);
941c78ac26e3a65328fc0118f16ee76a800d0687eb7Ruben Brunk
942c78ac26e3a65328fc0118f16ee76a800d0687eb7Ruben Brunk    // Guard against trying to prepare non-created streams
943c78ac26e3a65328fc0118f16ee76a800d0687eb7Ruben Brunk    ssize_t index = NAME_NOT_FOUND;
944c78ac26e3a65328fc0118f16ee76a800d0687eb7Ruben Brunk    for (size_t i = 0; i < mStreamMap.size(); ++i) {
945c78ac26e3a65328fc0118f16ee76a800d0687eb7Ruben Brunk        if (streamId == mStreamMap.valueAt(i)) {
946c78ac26e3a65328fc0118f16ee76a800d0687eb7Ruben Brunk            index = i;
947c78ac26e3a65328fc0118f16ee76a800d0687eb7Ruben Brunk            break;
948c78ac26e3a65328fc0118f16ee76a800d0687eb7Ruben Brunk        }
949c78ac26e3a65328fc0118f16ee76a800d0687eb7Ruben Brunk    }
950c78ac26e3a65328fc0118f16ee76a800d0687eb7Ruben Brunk
951c78ac26e3a65328fc0118f16ee76a800d0687eb7Ruben Brunk    if (index == NAME_NOT_FOUND) {
952d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        String8 msg = String8::format("Camera %d: Invalid stream ID (%d) specified, no stream "
953d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala              "with that ID exists", mCameraId, streamId);
954d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        ALOGW("%s: %s", __FUNCTION__, msg.string());
955d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
956c78ac26e3a65328fc0118f16ee76a800d0687eb7Ruben Brunk    }
957c78ac26e3a65328fc0118f16ee76a800d0687eb7Ruben Brunk
958c78ac26e3a65328fc0118f16ee76a800d0687eb7Ruben Brunk    if (maxCount <= 0) {
959d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        String8 msg = String8::format("Camera %d: maxCount (%d) must be greater than 0",
960d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                mCameraId, maxCount);
961d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        ALOGE("%s: %s", __FUNCTION__, msg.string());
962d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
963c78ac26e3a65328fc0118f16ee76a800d0687eb7Ruben Brunk    }
964c78ac26e3a65328fc0118f16ee76a800d0687eb7Ruben Brunk
965c78ac26e3a65328fc0118f16ee76a800d0687eb7Ruben Brunk    // Also returns BAD_VALUE if stream ID was not valid, or stream already
966c78ac26e3a65328fc0118f16ee76a800d0687eb7Ruben Brunk    // has been used
967d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    status_t err = mDevice->prepare(maxCount, streamId);
968d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if (err == BAD_VALUE) {
969d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        res = STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
970d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                "Camera %d: Stream %d has already been used, and cannot be prepared",
971d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                mCameraId, streamId);
972d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    } else if (err != OK) {
973d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
974d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                "Camera %d: Error preparing stream %d: %s (%d)", mCameraId, streamId,
975d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                strerror(-err), err);
976d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    }
977c78ac26e3a65328fc0118f16ee76a800d0687eb7Ruben Brunk
978c78ac26e3a65328fc0118f16ee76a800d0687eb7Ruben Brunk    return res;
979c78ac26e3a65328fc0118f16ee76a800d0687eb7Ruben Brunk}
980c78ac26e3a65328fc0118f16ee76a800d0687eb7Ruben Brunk
981d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvalabinder::Status CameraDeviceClient::tearDown(int streamId) {
982b25e3c87724b6147ed1da7c1d6617c39bfce2fbfEino-Ville Talvala    ATRACE_CALL();
983b25e3c87724b6147ed1da7c1d6617c39bfce2fbfEino-Ville Talvala    ALOGV("%s", __FUNCTION__);
984b25e3c87724b6147ed1da7c1d6617c39bfce2fbfEino-Ville Talvala
985d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    binder::Status res;
986d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
987b25e3c87724b6147ed1da7c1d6617c39bfce2fbfEino-Ville Talvala
988b25e3c87724b6147ed1da7c1d6617c39bfce2fbfEino-Ville Talvala    Mutex::Autolock icl(mBinderSerializationLock);
989b25e3c87724b6147ed1da7c1d6617c39bfce2fbfEino-Ville Talvala
990b25e3c87724b6147ed1da7c1d6617c39bfce2fbfEino-Ville Talvala    // Guard against trying to prepare non-created streams
991b25e3c87724b6147ed1da7c1d6617c39bfce2fbfEino-Ville Talvala    ssize_t index = NAME_NOT_FOUND;
992b25e3c87724b6147ed1da7c1d6617c39bfce2fbfEino-Ville Talvala    for (size_t i = 0; i < mStreamMap.size(); ++i) {
993b25e3c87724b6147ed1da7c1d6617c39bfce2fbfEino-Ville Talvala        if (streamId == mStreamMap.valueAt(i)) {
994b25e3c87724b6147ed1da7c1d6617c39bfce2fbfEino-Ville Talvala            index = i;
995b25e3c87724b6147ed1da7c1d6617c39bfce2fbfEino-Ville Talvala            break;
996b25e3c87724b6147ed1da7c1d6617c39bfce2fbfEino-Ville Talvala        }
997b25e3c87724b6147ed1da7c1d6617c39bfce2fbfEino-Ville Talvala    }
998b25e3c87724b6147ed1da7c1d6617c39bfce2fbfEino-Ville Talvala
999b25e3c87724b6147ed1da7c1d6617c39bfce2fbfEino-Ville Talvala    if (index == NAME_NOT_FOUND) {
1000d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        String8 msg = String8::format("Camera %d: Invalid stream ID (%d) specified, no stream "
1001d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala              "with that ID exists", mCameraId, streamId);
1002d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        ALOGW("%s: %s", __FUNCTION__, msg.string());
1003d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
1004b25e3c87724b6147ed1da7c1d6617c39bfce2fbfEino-Ville Talvala    }
1005b25e3c87724b6147ed1da7c1d6617c39bfce2fbfEino-Ville Talvala
1006b25e3c87724b6147ed1da7c1d6617c39bfce2fbfEino-Ville Talvala    // Also returns BAD_VALUE if stream ID was not valid or if the stream is in
1007b25e3c87724b6147ed1da7c1d6617c39bfce2fbfEino-Ville Talvala    // use
1008d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    status_t err = mDevice->tearDown(streamId);
1009d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if (err == BAD_VALUE) {
1010d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        res = STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
1011d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                "Camera %d: Stream %d is still in use, cannot be torn down",
1012d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                mCameraId, streamId);
1013d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    } else if (err != OK) {
1014d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
1015d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                "Camera %d: Error tearing down stream %d: %s (%d)", mCameraId, streamId,
1016d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                strerror(-err), err);
1017d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    }
1018b25e3c87724b6147ed1da7c1d6617c39bfce2fbfEino-Ville Talvala
1019b25e3c87724b6147ed1da7c1d6617c39bfce2fbfEino-Ville Talvala    return res;
1020b25e3c87724b6147ed1da7c1d6617c39bfce2fbfEino-Ville Talvala}
1021b25e3c87724b6147ed1da7c1d6617c39bfce2fbfEino-Ville Talvala
10225d677d1f0879d5101e38df480a38228a64d63959Zhijun Hebinder::Status CameraDeviceClient::setDeferredConfiguration(int32_t streamId,
10235d677d1f0879d5101e38df480a38228a64d63959Zhijun He        const hardware::camera2::params::OutputConfiguration &outputConfiguration) {
10245d677d1f0879d5101e38df480a38228a64d63959Zhijun He    ATRACE_CALL();
10255d677d1f0879d5101e38df480a38228a64d63959Zhijun He
10265d677d1f0879d5101e38df480a38228a64d63959Zhijun He    binder::Status res;
10275d677d1f0879d5101e38df480a38228a64d63959Zhijun He    if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
10285d677d1f0879d5101e38df480a38228a64d63959Zhijun He
10295d677d1f0879d5101e38df480a38228a64d63959Zhijun He    Mutex::Autolock icl(mBinderSerializationLock);
10305d677d1f0879d5101e38df480a38228a64d63959Zhijun He
10315d677d1f0879d5101e38df480a38228a64d63959Zhijun He    sp<IGraphicBufferProducer> bufferProducer = outputConfiguration.getGraphicBufferProducer();
10325d677d1f0879d5101e38df480a38228a64d63959Zhijun He
10335d677d1f0879d5101e38df480a38228a64d63959Zhijun He    // Client code should guarantee that the surface is from SurfaceView or SurfaceTexture.
10345d677d1f0879d5101e38df480a38228a64d63959Zhijun He    if (bufferProducer == NULL) {
10355d677d1f0879d5101e38df480a38228a64d63959Zhijun He        ALOGE("%s: bufferProducer must not be null", __FUNCTION__);
10365d677d1f0879d5101e38df480a38228a64d63959Zhijun He        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "Target Surface is invalid");
10375d677d1f0879d5101e38df480a38228a64d63959Zhijun He    }
10385d677d1f0879d5101e38df480a38228a64d63959Zhijun He    // Check if this stram id is one of the deferred streams
10395d677d1f0879d5101e38df480a38228a64d63959Zhijun He    ssize_t index = NAME_NOT_FOUND;
10405d677d1f0879d5101e38df480a38228a64d63959Zhijun He    for (size_t i = 0; i < mDeferredStreams.size(); i++) {
10415d677d1f0879d5101e38df480a38228a64d63959Zhijun He        if (streamId == mDeferredStreams[i]) {
10425d677d1f0879d5101e38df480a38228a64d63959Zhijun He            index = i;
10435d677d1f0879d5101e38df480a38228a64d63959Zhijun He            break;
10445d677d1f0879d5101e38df480a38228a64d63959Zhijun He        }
10455d677d1f0879d5101e38df480a38228a64d63959Zhijun He    }
10465d677d1f0879d5101e38df480a38228a64d63959Zhijun He    if (index == NAME_NOT_FOUND) {
10475d677d1f0879d5101e38df480a38228a64d63959Zhijun He        String8 msg = String8::format("Camera %d: deferred surface is set to a unknown stream"
10485d677d1f0879d5101e38df480a38228a64d63959Zhijun He                "(ID %d)", mCameraId, streamId);
10495d677d1f0879d5101e38df480a38228a64d63959Zhijun He        ALOGW("%s: %s", __FUNCTION__, msg.string());
10505d677d1f0879d5101e38df480a38228a64d63959Zhijun He        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
10515d677d1f0879d5101e38df480a38228a64d63959Zhijun He    }
10525d677d1f0879d5101e38df480a38228a64d63959Zhijun He
10535d677d1f0879d5101e38df480a38228a64d63959Zhijun He    if (!mDevice.get()) {
10545d677d1f0879d5101e38df480a38228a64d63959Zhijun He        return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
10555d677d1f0879d5101e38df480a38228a64d63959Zhijun He    }
10565d677d1f0879d5101e38df480a38228a64d63959Zhijun He
10575d677d1f0879d5101e38df480a38228a64d63959Zhijun He    // Don't create multiple streams for the same target surface
10585d677d1f0879d5101e38df480a38228a64d63959Zhijun He    {
10595d677d1f0879d5101e38df480a38228a64d63959Zhijun He        ssize_t index = mStreamMap.indexOfKey(IInterface::asBinder(bufferProducer));
10605d677d1f0879d5101e38df480a38228a64d63959Zhijun He        if (index != NAME_NOT_FOUND) {
10615d677d1f0879d5101e38df480a38228a64d63959Zhijun He            String8 msg = String8::format("Camera %d: Surface already has a stream created "
10625d677d1f0879d5101e38df480a38228a64d63959Zhijun He                    " for it (ID %zd)", mCameraId, index);
10635d677d1f0879d5101e38df480a38228a64d63959Zhijun He            ALOGW("%s: %s", __FUNCTION__, msg.string());
10645d677d1f0879d5101e38df480a38228a64d63959Zhijun He            return STATUS_ERROR(CameraService::ERROR_ALREADY_EXISTS, msg.string());
10655d677d1f0879d5101e38df480a38228a64d63959Zhijun He        }
10665d677d1f0879d5101e38df480a38228a64d63959Zhijun He    }
10675d677d1f0879d5101e38df480a38228a64d63959Zhijun He
10685d677d1f0879d5101e38df480a38228a64d63959Zhijun He    status_t err;
10695d677d1f0879d5101e38df480a38228a64d63959Zhijun He
10705d677d1f0879d5101e38df480a38228a64d63959Zhijun He    // Always set to async, as we know the deferred surface is for preview streaming.
10715d677d1f0879d5101e38df480a38228a64d63959Zhijun He    sp<Surface> consumerSurface = new Surface(bufferProducer, /*useAsync*/true);
10725d677d1f0879d5101e38df480a38228a64d63959Zhijun He
10735d677d1f0879d5101e38df480a38228a64d63959Zhijun He    // Finish the deferred stream configuration with the surface.
10745d677d1f0879d5101e38df480a38228a64d63959Zhijun He    err = mDevice->setConsumerSurface(streamId, consumerSurface);
10755d677d1f0879d5101e38df480a38228a64d63959Zhijun He    if (err == OK) {
10765d677d1f0879d5101e38df480a38228a64d63959Zhijun He        sp<IBinder> binder = IInterface::asBinder(bufferProducer);
10775d677d1f0879d5101e38df480a38228a64d63959Zhijun He        mStreamMap.add(binder, streamId);
10785d677d1f0879d5101e38df480a38228a64d63959Zhijun He        mDeferredStreams.removeItemsAt(index);
10795d677d1f0879d5101e38df480a38228a64d63959Zhijun He    } else if (err == NO_INIT) {
10805d677d1f0879d5101e38df480a38228a64d63959Zhijun He        res = STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
10815d677d1f0879d5101e38df480a38228a64d63959Zhijun He                "Camera %d: Deferred surface is invalid: %s (%d)",
10825d677d1f0879d5101e38df480a38228a64d63959Zhijun He                mCameraId, strerror(-err), err);
10835d677d1f0879d5101e38df480a38228a64d63959Zhijun He    } else {
10845d677d1f0879d5101e38df480a38228a64d63959Zhijun He        res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
10855d677d1f0879d5101e38df480a38228a64d63959Zhijun He                "Camera %d: Error setting output stream deferred surface: %s (%d)",
10865d677d1f0879d5101e38df480a38228a64d63959Zhijun He                mCameraId, strerror(-err), err);
10875d677d1f0879d5101e38df480a38228a64d63959Zhijun He    }
10885d677d1f0879d5101e38df480a38228a64d63959Zhijun He
10895d677d1f0879d5101e38df480a38228a64d63959Zhijun He    return res;
10905d677d1f0879d5101e38df480a38228a64d63959Zhijun He}
10915d677d1f0879d5101e38df480a38228a64d63959Zhijun He
1092e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkinstatus_t CameraDeviceClient::dump(int fd, const Vector<String16>& args) {
1093c4003965258404a19b99280ac0f475e2f290bf27Eino-Ville Talvala    return BasicClient::dump(fd, args);
1094c4003965258404a19b99280ac0f475e2f290bf27Eino-Ville Talvala}
1095c4003965258404a19b99280ac0f475e2f290bf27Eino-Ville Talvala
1096c4003965258404a19b99280ac0f475e2f290bf27Eino-Ville Talvalastatus_t CameraDeviceClient::dumpClient(int fd, const Vector<String16>& args) {
1097e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    String8 result;
109867489d2f5668441a36cb1f1157e80ec8684023bfEino-Ville Talvala    result.appendFormat("CameraDeviceClient[%d] (%p) dump:\n",
1099e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin            mCameraId,
1100e992e75053e98e3699af6e344c11b787e30411adEino-Ville Talvala            (getRemoteCallback() != NULL ?
1101f888020c6e2735624f2b2a30e72aca24e17b8b4dMarco Nelissen                    IInterface::asBinder(getRemoteCallback()).get() : NULL) );
1102cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    result.appendFormat("  Current client UID %u\n", mClientUid);
110367489d2f5668441a36cb1f1157e80ec8684023bfEino-Ville Talvala
110467489d2f5668441a36cb1f1157e80ec8684023bfEino-Ville Talvala    result.append("  State:\n");
110567489d2f5668441a36cb1f1157e80ec8684023bfEino-Ville Talvala    result.appendFormat("    Request ID counter: %d\n", mRequestIdCounter);
1106618ff8a48a0c895a78f91f5692510c2a809425c3Chien-Yu Chen    if (mInputStream.configured) {
1107618ff8a48a0c895a78f91f5692510c2a809425c3Chien-Yu Chen        result.appendFormat("    Current input stream ID: %d\n",
1108618ff8a48a0c895a78f91f5692510c2a809425c3Chien-Yu Chen                    mInputStream.id);
1109618ff8a48a0c895a78f91f5692510c2a809425c3Chien-Yu Chen    } else {
1110618ff8a48a0c895a78f91f5692510c2a809425c3Chien-Yu Chen        result.append("    No input stream configured.\n");
1111618ff8a48a0c895a78f91f5692510c2a809425c3Chien-Yu Chen    }
111267489d2f5668441a36cb1f1157e80ec8684023bfEino-Ville Talvala    if (!mStreamMap.isEmpty()) {
1113618ff8a48a0c895a78f91f5692510c2a809425c3Chien-Yu Chen        result.append("    Current output stream IDs:\n");
111467489d2f5668441a36cb1f1157e80ec8684023bfEino-Ville Talvala        for (size_t i = 0; i < mStreamMap.size(); i++) {
111567489d2f5668441a36cb1f1157e80ec8684023bfEino-Ville Talvala            result.appendFormat("      Stream %d\n", mStreamMap.valueAt(i));
111667489d2f5668441a36cb1f1157e80ec8684023bfEino-Ville Talvala        }
11175d677d1f0879d5101e38df480a38228a64d63959Zhijun He    } else if (!mDeferredStreams.isEmpty()) {
11185d677d1f0879d5101e38df480a38228a64d63959Zhijun He        result.append("    Current deferred surface output stream IDs:\n");
11195d677d1f0879d5101e38df480a38228a64d63959Zhijun He        for (auto& streamId : mDeferredStreams) {
11205d677d1f0879d5101e38df480a38228a64d63959Zhijun He            result.appendFormat("      Stream %d\n", streamId);
11215d677d1f0879d5101e38df480a38228a64d63959Zhijun He        }
112267489d2f5668441a36cb1f1157e80ec8684023bfEino-Ville Talvala    } else {
1123618ff8a48a0c895a78f91f5692510c2a809425c3Chien-Yu Chen        result.append("    No output streams configured.\n");
112467489d2f5668441a36cb1f1157e80ec8684023bfEino-Ville Talvala    }
112567489d2f5668441a36cb1f1157e80ec8684023bfEino-Ville Talvala    write(fd, result.string(), result.size());
1126e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    // TODO: print dynamic/request section from most recent requests
1127e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    mFrameProcessor->dump(fd, args);
1128e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
1129e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    return dumpDevice(fd, args);
1130e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin}
1131e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
1132d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvalavoid CameraDeviceClient::notifyError(int32_t errorCode,
1133cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei                                     const CaptureResultExtras& resultExtras) {
1134f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    // Thread safe. Don't bother locking.
1135d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    sp<hardware::camera2::ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
1136f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
1137f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    if (remoteCb != 0) {
1138cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei        remoteCb->onDeviceError(errorCode, resultExtras);
1139f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    }
1140f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala}
1141f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
1142e8c535e833ed135895e99ca81aa3b85d80d7cf3cChien-Yu Chenvoid CameraDeviceClient::notifyRepeatingRequestError(long lastFrameNumber) {
1143e8c535e833ed135895e99ca81aa3b85d80d7cf3cChien-Yu Chen    sp<hardware::camera2::ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
1144e8c535e833ed135895e99ca81aa3b85d80d7cf3cChien-Yu Chen
1145e8c535e833ed135895e99ca81aa3b85d80d7cf3cChien-Yu Chen    if (remoteCb != 0) {
1146e8c535e833ed135895e99ca81aa3b85d80d7cf3cChien-Yu Chen        remoteCb->onRepeatingRequestError(lastFrameNumber);
1147e8c535e833ed135895e99ca81aa3b85d80d7cf3cChien-Yu Chen    }
1148e8c535e833ed135895e99ca81aa3b85d80d7cf3cChien-Yu Chen
1149c9ca6788c65ed3f578d1a1ed0ba7c268254dcb4bShuzhen Wang    Mutex::Autolock idLock(mStreamingRequestIdLock);
1150e8c535e833ed135895e99ca81aa3b85d80d7cf3cChien-Yu Chen    mStreamingRequestId = REQUEST_ID_NONE;
1151e8c535e833ed135895e99ca81aa3b85d80d7cf3cChien-Yu Chen}
1152e8c535e833ed135895e99ca81aa3b85d80d7cf3cChien-Yu Chen
1153f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvalavoid CameraDeviceClient::notifyIdle() {
1154f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    // Thread safe. Don't bother locking.
1155d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    sp<hardware::camera2::ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
1156f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
1157f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    if (remoteCb != 0) {
1158f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        remoteCb->onDeviceIdle();
1159f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    }
1160412fe56cd7cf7d73bc5d2bcc3f635bc650d18de9Eino-Ville Talvala    Camera2ClientBase::notifyIdle();
1161f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala}
1162f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
1163cb0652e5a850b2fcd919e977247e87239efaf70eJianing Weivoid CameraDeviceClient::notifyShutter(const CaptureResultExtras& resultExtras,
1164f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        nsecs_t timestamp) {
1165f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    // Thread safe. Don't bother locking.
1166d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    sp<hardware::camera2::ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
1167f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    if (remoteCb != 0) {
1168cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei        remoteCb->onCaptureStarted(resultExtras, timestamp);
1169f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    }
1170412fe56cd7cf7d73bc5d2bcc3f635bc650d18de9Eino-Ville Talvala    Camera2ClientBase::notifyShutter(resultExtras, timestamp);
1171f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala}
1172f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
11734d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvalavoid CameraDeviceClient::notifyPrepared(int streamId) {
11744d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala    // Thread safe. Don't bother locking.
1175d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    sp<hardware::camera2::ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
11764d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala    if (remoteCb != 0) {
11774d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala        remoteCb->onPrepared(streamId);
11784d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala    }
11794d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala}
11804d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala
1181e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkinvoid CameraDeviceClient::detachDevice() {
1182e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if (mDevice == 0) return;
1183e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
1184e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    ALOGV("Camera %d: Stopping processors", mCameraId);
1185e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
1186e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    mFrameProcessor->removeListener(FRAME_PROCESSOR_LISTENER_MIN_ID,
1187e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                                    FRAME_PROCESSOR_LISTENER_MAX_ID,
1188e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                                    /*listener*/this);
1189e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    mFrameProcessor->requestExit();
1190e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    ALOGV("Camera %d: Waiting for threads", mCameraId);
1191e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    mFrameProcessor->join();
1192e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    ALOGV("Camera %d: Disconnecting device", mCameraId);
1193e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
1194e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    // WORKAROUND: HAL refuses to disconnect while there's streams in flight
1195e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    {
1196e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        mDevice->clearStreamingRequest();
1197e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
1198e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        status_t code;
1199e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        if ((code = mDevice->waitUntilDrained()) != OK) {
1200e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin            ALOGE("%s: waitUntilDrained failed with code 0x%x", __FUNCTION__,
1201e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                  code);
1202e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        }
1203e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
1204e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
1205e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    Camera2ClientBase::detachDevice();
1206e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin}
1207e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
1208e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin/** Device-related methods */
1209cb0652e5a850b2fcd919e977247e87239efaf70eJianing Weivoid CameraDeviceClient::onResultAvailable(const CaptureResult& result) {
1210e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    ATRACE_CALL();
1211e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    ALOGV("%s", __FUNCTION__);
1212e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
12134fb55c15da1a563ab925914a0f493a3dc80495a3Igor Murashkin    // Thread-safe. No lock necessary.
1214d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    sp<hardware::camera2::ICameraDeviceCallbacks> remoteCb = mRemoteCallback;
12154fb55c15da1a563ab925914a0f493a3dc80495a3Igor Murashkin    if (remoteCb != NULL) {
1216cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei        remoteCb->onResultReceived(result.mMetadata, result.mResultExtras);
1217e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
1218e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin}
1219e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
1220d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvalabinder::Status CameraDeviceClient::checkPidStatus(const char* checkLocation) {
12216192b89257c5ae8834faa25b801d561043675d3bEino-Ville Talvala    if (mDisconnected) {
12226192b89257c5ae8834faa25b801d561043675d3bEino-Ville Talvala        return STATUS_ERROR(CameraService::ERROR_DISCONNECTED,
12236192b89257c5ae8834faa25b801d561043675d3bEino-Ville Talvala                "The camera device has been disconnected");
12246192b89257c5ae8834faa25b801d561043675d3bEino-Ville Talvala    }
1225d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    status_t res = checkPid(checkLocation);
1226d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return (res == OK) ? binder::Status::ok() :
1227d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            STATUS_ERROR(CameraService::ERROR_PERMISSION_DENIED,
1228d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    "Attempt to use camera from a different process than original client");
1229d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala}
1230d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala
1231e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin// TODO: move to Camera2ClientBase
1232e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkinbool CameraDeviceClient::enforceRequestPermissions(CameraMetadata& metadata) {
1233e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
1234e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    const int pid = IPCThreadState::self()->getCallingPid();
1235e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    const int selfPid = getpid();
1236e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    camera_metadata_entry_t entry;
1237e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
1238e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    /**
1239e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin     * Mixin default important security values
1240e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin     * - android.led.transmit = defaulted ON
1241e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin     */
1242e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    CameraMetadata staticInfo = mDevice->info();
1243e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    entry = staticInfo.find(ANDROID_LED_AVAILABLE_LEDS);
1244e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    for(size_t i = 0; i < entry.count; ++i) {
1245e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        uint8_t led = entry.data.u8[i];
1246e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
1247e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        switch(led) {
1248e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin            case ANDROID_LED_AVAILABLE_LEDS_TRANSMIT: {
1249e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                uint8_t transmitDefault = ANDROID_LED_TRANSMIT_ON;
1250e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                if (!metadata.exists(ANDROID_LED_TRANSMIT)) {
1251e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                    metadata.update(ANDROID_LED_TRANSMIT,
1252e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                                    &transmitDefault, 1);
1253e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                }
1254e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                break;
1255e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin            }
1256e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        }
1257e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
1258e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
1259e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    // We can do anything!
1260e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if (pid == selfPid) {
1261e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        return true;
1262e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
1263e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
1264e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    /**
1265e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin     * Permission check special fields in the request
1266e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin     * - android.led.transmit = android.permission.CAMERA_DISABLE_TRANSMIT
1267e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin     */
1268e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    entry = metadata.find(ANDROID_LED_TRANSMIT);
1269e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if (entry.count > 0 && entry.data.u8[0] != ANDROID_LED_TRANSMIT_ON) {
1270e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        String16 permissionString =
1271e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin            String16("android.permission.CAMERA_DISABLE_TRANSMIT_LED");
1272e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        if (!checkCallingPermission(permissionString)) {
1273e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin            const int uid = IPCThreadState::self()->getCallingUid();
1274e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin            ALOGE("Permission Denial: "
1275e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                  "can't disable transmit LED pid=%d, uid=%d", pid, uid);
1276e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin            return false;
1277e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        }
1278e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
1279e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
1280e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    return true;
1281e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin}
1282e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
1283f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkinstatus_t CameraDeviceClient::getRotationTransformLocked(int32_t* transform) {
1284f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin    ALOGV("%s: begin", __FUNCTION__);
1285f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin
1286f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin    const CameraMetadata& staticInfo = mDevice->info();
12875698d4461a260dbf208484383f692b03c6473e74Ruben Brunk    return CameraUtils::getRotationTransform(staticInfo, transform);
1288f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin}
1289f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin
1290e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin} // namespace android
1291