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
317b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvala
32e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
33e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkinnamespace android {
34e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkinusing namespace camera2;
35e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
36e7ee7637747371635a85fedd24d2190bb1f38651Igor MurashkinCameraDeviceClientBase::CameraDeviceClientBase(
37e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        const sp<CameraService>& cameraService,
38e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        const sp<ICameraDeviceCallbacks>& remoteCallback,
39e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        const String16& clientPackageName,
40e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        int cameraId,
41e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        int cameraFacing,
42e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        int clientPid,
43e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        uid_t clientUid,
44e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        int servicePid) :
45e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    BasicClient(cameraService, remoteCallback->asBinder(), clientPackageName,
46e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                cameraId, cameraFacing, clientPid, clientUid, servicePid),
47e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    mRemoteCallback(remoteCallback) {
48e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin}
49e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
50e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin// Interface used by CameraService
51e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
52e7ee7637747371635a85fedd24d2190bb1f38651Igor MurashkinCameraDeviceClient::CameraDeviceClient(const sp<CameraService>& cameraService,
53e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                                   const sp<ICameraDeviceCallbacks>& remoteCallback,
54e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                                   const String16& clientPackageName,
55e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                                   int cameraId,
56e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                                   int cameraFacing,
57e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                                   int clientPid,
58e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                                   uid_t clientUid,
59e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                                   int servicePid) :
60e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    Camera2ClientBase(cameraService, remoteCallback, clientPackageName,
61e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                cameraId, cameraFacing, clientPid, clientUid, servicePid),
62e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    mRequestIdCounter(0) {
63e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
64e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    ATRACE_CALL();
65e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    ALOGI("CameraDeviceClient %d: Opened", cameraId);
66e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin}
67e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
68e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkinstatus_t CameraDeviceClient::initialize(camera_module_t *module)
69e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin{
70e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    ATRACE_CALL();
71e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    status_t res;
72e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
73e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    res = Camera2ClientBase::initialize(module);
74e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if (res != OK) {
75e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        return res;
76e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
77e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
78e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    String8 threadName;
797b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvala    mFrameProcessor = new FrameProcessorBase(mDevice);
80e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    threadName = String8::format("CDU-%d-FrameProc", mCameraId);
81e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    mFrameProcessor->run(threadName.string());
82e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
83e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    mFrameProcessor->registerListener(FRAME_PROCESSOR_LISTENER_MIN_ID,
84e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                                      FRAME_PROCESSOR_LISTENER_MAX_ID,
85184dfe4ea5e2ba33951bed2b1366007aee0ce3daEino-Ville Talvala                                      /*listener*/this,
8625a0aef19e170d2695f64b4c48296e7914155a88Zhijun He                                      /*sendPartials*/true);
87e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
88e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    return OK;
89e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin}
90e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
91e7ee7637747371635a85fedd24d2190bb1f38651Igor MurashkinCameraDeviceClient::~CameraDeviceClient() {
92e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin}
93e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
94e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkinstatus_t CameraDeviceClient::submitRequest(sp<CaptureRequest> request,
95cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei                                         bool streaming,
96cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei                                         /*out*/
97cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei                                         int64_t* lastFrameNumber) {
98cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei    List<sp<CaptureRequest> > requestList;
99cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei    requestList.push_back(request);
100cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei    return submitRequestList(requestList, streaming, lastFrameNumber);
10190e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei}
10290e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei
10390e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Weistatus_t CameraDeviceClient::submitRequestList(List<sp<CaptureRequest> > requests,
104cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei                                               bool streaming, int64_t* lastFrameNumber) {
10590e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei    ATRACE_CALL();
10650468413251bd92a1cdf9de8275a994dab8648d1Mark Salyzyn    ALOGV("%s-start of function. Request list size %zu", __FUNCTION__, requests.size());
10790e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei
10890e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei    status_t res;
10990e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
11090e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei
11190e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei    Mutex::Autolock icl(mBinderSerializationLock);
11290e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei
11390e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei    if (!mDevice.get()) return DEAD_OBJECT;
11490e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei
11590e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei    if (requests.empty()) {
11690e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei        ALOGE("%s: Camera %d: Sent null request. Rejecting request.",
11790e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei              __FUNCTION__, mCameraId);
11890e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei        return BAD_VALUE;
11990e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei    }
12090e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei
12190e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei    List<const CameraMetadata> metadataRequestList;
12290e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei    int32_t requestId = mRequestIdCounter;
12390e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei    uint32_t loopCounter = 0;
12490e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei
12590e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei    for (List<sp<CaptureRequest> >::iterator it = requests.begin(); it != requests.end(); ++it) {
12690e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei        sp<CaptureRequest> request = *it;
12790e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei        if (request == 0) {
12890e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei            ALOGE("%s: Camera %d: Sent null request.",
12990e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei                    __FUNCTION__, mCameraId);
13090e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei            return BAD_VALUE;
13190e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei        }
13290e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei
13390e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei        CameraMetadata metadata(request->mMetadata);
13490e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei        if (metadata.isEmpty()) {
13590e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei            ALOGE("%s: Camera %d: Sent empty metadata packet. Rejecting request.",
13690e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei                   __FUNCTION__, mCameraId);
13790e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei            return BAD_VALUE;
13890e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei        } else if (request->mSurfaceList.isEmpty()) {
13990e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei            ALOGE("%s: Camera %d: Requests must have at least one surface target. "
14090e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei                  "Rejecting request.", __FUNCTION__, mCameraId);
14190e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei            return BAD_VALUE;
14290e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei        }
14390e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei
14490e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei        if (!enforceRequestPermissions(metadata)) {
14590e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei            // Callee logs
14690e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei            return PERMISSION_DENIED;
14790e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei        }
14890e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei
14990e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei        /**
15090e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei         * Write in the output stream IDs which we calculate from
15190e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei         * the capture request's list of surface targets
15290e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei         */
15390e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei        Vector<int32_t> outputStreamIds;
15490e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei        outputStreamIds.setCapacity(request->mSurfaceList.size());
155cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei        for (size_t i = 0; i < request->mSurfaceList.size(); ++i) {
156cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei            sp<Surface> surface = request->mSurfaceList[i];
15790e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei            if (surface == 0) continue;
15890e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei
15990e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei            sp<IGraphicBufferProducer> gbp = surface->getIGraphicBufferProducer();
16090e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei            int idx = mStreamMap.indexOfKey(gbp->asBinder());
16190e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei
16290e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei            // Trying to submit request with surface that wasn't created
16390e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei            if (idx == NAME_NOT_FOUND) {
16490e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei                ALOGE("%s: Camera %d: Tried to submit a request with a surface that"
16590e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei                      " we have not called createStream on",
16690e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei                      __FUNCTION__, mCameraId);
16790e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei                return BAD_VALUE;
16890e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei            }
16990e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei
17090e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei            int streamId = mStreamMap.valueAt(idx);
17190e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei            outputStreamIds.push_back(streamId);
17290e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei            ALOGV("%s: Camera %d: Appending output stream %d to request",
17390e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei                  __FUNCTION__, mCameraId, streamId);
17490e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei        }
17590e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei
17690e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei        metadata.update(ANDROID_REQUEST_OUTPUT_STREAMS, &outputStreamIds[0],
17790e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei                        outputStreamIds.size());
17890e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei
17990e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei        metadata.update(ANDROID_REQUEST_ID, &requestId, /*size*/1);
18090e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei        loopCounter++; // loopCounter starts from 1
18150468413251bd92a1cdf9de8275a994dab8648d1Mark Salyzyn        ALOGV("%s: Camera %d: Creating request with ID %d (%d of %zu)",
18290e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei              __FUNCTION__, mCameraId, requestId, loopCounter, requests.size());
18390e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei
18490e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei        metadataRequestList.push_back(metadata);
18590e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei    }
18690e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei    mRequestIdCounter++;
18790e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei
18890e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei    if (streaming) {
189cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei        res = mDevice->setStreamingRequestList(metadataRequestList, lastFrameNumber);
19090e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei        if (res != OK) {
19190e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei            ALOGE("%s: Camera %d:  Got error %d after trying to set streaming "
19290e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei                  "request", __FUNCTION__, mCameraId, res);
19390e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei        } else {
19490e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei            mStreamingRequestList.push_back(requestId);
19590e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei        }
19690e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei    } else {
197cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei        res = mDevice->captureList(metadataRequestList, lastFrameNumber);
19890e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei        if (res != OK) {
19990e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei            ALOGE("%s: Camera %d: Got error %d after trying to set capture",
20090e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei                __FUNCTION__, mCameraId, res);
20190e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei        }
202cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei        ALOGV("%s: requestId = %d ", __FUNCTION__, requestId);
20390e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei    }
20490e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei
20590e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei    ALOGV("%s: Camera %d: End of function", __FUNCTION__, mCameraId);
20690e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei    if (res == OK) {
20790e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei        return requestId;
20890e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei    }
209e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
210e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    return res;
211e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin}
212e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
213cb0652e5a850b2fcd919e977247e87239efaf70eJianing Weistatus_t CameraDeviceClient::cancelRequest(int requestId, int64_t* lastFrameNumber) {
214e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    ATRACE_CALL();
215e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    ALOGV("%s, requestId = %d", __FUNCTION__, requestId);
216e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
217e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    status_t res;
218e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
219e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
220e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
221e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    Mutex::Autolock icl(mBinderSerializationLock);
222e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
223e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if (!mDevice.get()) return DEAD_OBJECT;
224e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
225e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    Vector<int>::iterator it, end;
226e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    for (it = mStreamingRequestList.begin(), end = mStreamingRequestList.end();
227e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin         it != end; ++it) {
228e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        if (*it == requestId) {
229e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin            break;
230e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        }
231e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
232e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
233e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if (it == end) {
234e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        ALOGE("%s: Camera%d: Did not find request id %d in list of streaming "
235e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin              "requests", __FUNCTION__, mCameraId, requestId);
236e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        return BAD_VALUE;
237e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
238e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
239cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei    res = mDevice->clearStreamingRequest(lastFrameNumber);
240e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
241e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if (res == OK) {
242e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        ALOGV("%s: Camera %d: Successfully cleared streaming request",
243e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin              __FUNCTION__, mCameraId);
244e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        mStreamingRequestList.erase(it);
245e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
246e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
247e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    return res;
248e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin}
249e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
250b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunkstatus_t CameraDeviceClient::beginConfigure() {
251b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk    // TODO: Implement this.
252b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk    ALOGE("%s: Not implemented yet.", __FUNCTION__);
253b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk    return OK;
254b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk}
255b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk
256b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunkstatus_t CameraDeviceClient::endConfigure() {
257e2d167eb689d7a536805f950c31f11b9e9c578aeIgor Murashkin    ALOGV("%s: ending configure (%zu streams)",
258e2d167eb689d7a536805f950c31f11b9e9c578aeIgor Murashkin            __FUNCTION__, mStreamMap.size());
259e2d167eb689d7a536805f950c31f11b9e9c578aeIgor Murashkin
260e2d167eb689d7a536805f950c31f11b9e9c578aeIgor Murashkin    status_t res;
261e2d167eb689d7a536805f950c31f11b9e9c578aeIgor Murashkin    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
262e2d167eb689d7a536805f950c31f11b9e9c578aeIgor Murashkin
263e2d167eb689d7a536805f950c31f11b9e9c578aeIgor Murashkin    Mutex::Autolock icl(mBinderSerializationLock);
264e2d167eb689d7a536805f950c31f11b9e9c578aeIgor Murashkin
265e2d167eb689d7a536805f950c31f11b9e9c578aeIgor Murashkin    if (!mDevice.get()) return DEAD_OBJECT;
266e2d167eb689d7a536805f950c31f11b9e9c578aeIgor Murashkin
267e2d167eb689d7a536805f950c31f11b9e9c578aeIgor Murashkin    return mDevice->configureStreams();
268b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk}
269b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk
270e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkinstatus_t CameraDeviceClient::deleteStream(int streamId) {
271e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    ATRACE_CALL();
272e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    ALOGV("%s (streamId = 0x%x)", __FUNCTION__, streamId);
273e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
274e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    status_t res;
275e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
276e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
277e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    Mutex::Autolock icl(mBinderSerializationLock);
278e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
279e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if (!mDevice.get()) return DEAD_OBJECT;
280e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
281e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    // Guard against trying to delete non-created streams
282e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    ssize_t index = NAME_NOT_FOUND;
283e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    for (size_t i = 0; i < mStreamMap.size(); ++i) {
284e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        if (streamId == mStreamMap.valueAt(i)) {
285e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin            index = i;
286e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin            break;
287e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        }
288e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
289e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
290e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if (index == NAME_NOT_FOUND) {
291e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        ALOGW("%s: Camera %d: Invalid stream ID (%d) specified, no stream "
292e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin              "created yet", __FUNCTION__, mCameraId, streamId);
293e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        return BAD_VALUE;
294e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
295e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
296e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    // Also returns BAD_VALUE if stream ID was not valid
297e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    res = mDevice->deleteStream(streamId);
298e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
299e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if (res == BAD_VALUE) {
300e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        ALOGE("%s: Camera %d: Unexpected BAD_VALUE when deleting stream, but we"
301e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin              " already checked and the stream ID (%d) should be valid.",
302e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin              __FUNCTION__, mCameraId, streamId);
303e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    } else if (res == OK) {
304e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        mStreamMap.removeItemsAt(index);
305e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
306e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
307e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
308e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    return res;
309e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin}
310e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
311e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkinstatus_t CameraDeviceClient::createStream(int width, int height, int format,
312e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                      const sp<IGraphicBufferProducer>& bufferProducer)
313e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin{
314e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    ATRACE_CALL();
315e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    ALOGV("%s (w = %d, h = %d, f = 0x%x)", __FUNCTION__, width, height, format);
316e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
317e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    status_t res;
318e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
319e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
320e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    Mutex::Autolock icl(mBinderSerializationLock);
321e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
32289f14dacfadea1b14149510d4dfbc75dc79b23bbYin-Chia Yeh    if (bufferProducer == NULL) {
32389f14dacfadea1b14149510d4dfbc75dc79b23bbYin-Chia Yeh        ALOGE("%s: bufferProducer must not be null", __FUNCTION__);
32489f14dacfadea1b14149510d4dfbc75dc79b23bbYin-Chia Yeh        return BAD_VALUE;
32589f14dacfadea1b14149510d4dfbc75dc79b23bbYin-Chia Yeh    }
326e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if (!mDevice.get()) return DEAD_OBJECT;
327e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
328e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    // Don't create multiple streams for the same target surface
329e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    {
330e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        ssize_t index = mStreamMap.indexOfKey(bufferProducer->asBinder());
331e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        if (index != NAME_NOT_FOUND) {
332e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin            ALOGW("%s: Camera %d: Buffer producer already has a stream for it "
333e5729fac81c8a984e984fefc90afc64135817d4fColin Cross                  "(ID %zd)",
334e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                  __FUNCTION__, mCameraId, index);
335e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin            return ALREADY_EXISTS;
336e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        }
337e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
338e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
3391da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala    // HACK b/10949105
3401da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala    // Query consumer usage bits to set async operation mode for
3411da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala    // GLConsumer using controlledByApp parameter.
3421da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala    bool useAsync = false;
3431da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala    int32_t consumerUsage;
3441da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala    if ((res = bufferProducer->query(NATIVE_WINDOW_CONSUMER_USAGE_BITS,
3451da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala            &consumerUsage)) != OK) {
3461da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala        ALOGE("%s: Camera %d: Failed to query consumer usage", __FUNCTION__,
3471da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala              mCameraId);
3481da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala        return res;
3491da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala    }
3501da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala    if (consumerUsage & GraphicBuffer::USAGE_HW_TEXTURE) {
3511da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala        ALOGW("%s: Camera %d: Forcing asynchronous mode for stream",
3521da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala                __FUNCTION__, mCameraId);
3531da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala        useAsync = true;
3541da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala    }
3551da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala
356bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk    int32_t disallowedFlags = GraphicBuffer::USAGE_HW_VIDEO_ENCODER |
357bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk                              GRALLOC_USAGE_RENDERSCRIPT;
358bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk    int32_t allowedFlags = GraphicBuffer::USAGE_SW_READ_MASK |
359bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk                           GraphicBuffer::USAGE_HW_TEXTURE |
360bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk                           GraphicBuffer::USAGE_HW_COMPOSER;
361bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk    bool flexibleConsumer = (consumerUsage & disallowedFlags) == 0 &&
362bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk            (consumerUsage & allowedFlags) != 0;
363bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk
364e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    sp<IBinder> binder;
365e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    sp<ANativeWindow> anw;
366e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if (bufferProducer != 0) {
367e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        binder = bufferProducer->asBinder();
3681da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala        anw = new Surface(bufferProducer, useAsync);
369e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
370e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
371e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    // TODO: remove w,h,f since we are ignoring them
372e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
373e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if ((res = anw->query(anw.get(), NATIVE_WINDOW_WIDTH, &width)) != OK) {
374e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        ALOGE("%s: Camera %d: Failed to query Surface width", __FUNCTION__,
375e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin              mCameraId);
376e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        return res;
377e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
378e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if ((res = anw->query(anw.get(), NATIVE_WINDOW_HEIGHT, &height)) != OK) {
379e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        ALOGE("%s: Camera %d: Failed to query Surface height", __FUNCTION__,
380e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin              mCameraId);
381e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        return res;
382e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
383e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if ((res = anw->query(anw.get(), NATIVE_WINDOW_FORMAT, &format)) != OK) {
384e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        ALOGE("%s: Camera %d: Failed to query Surface format", __FUNCTION__,
385e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin              mCameraId);
386e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        return res;
387e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
388e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
389e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    // FIXME: remove this override since the default format should be
390e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    //       IMPLEMENTATION_DEFINED. b/9487482
3911581101ce2a8c1b8d0b07b643ad891595221d781Igor Murashkin    if (format >= HAL_PIXEL_FORMAT_RGBA_8888 &&
3921581101ce2a8c1b8d0b07b643ad891595221d781Igor Murashkin        format <= HAL_PIXEL_FORMAT_BGRA_8888) {
393bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk        ALOGW("%s: Camera %d: Overriding format %#x to IMPLEMENTATION_DEFINED",
394e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin              __FUNCTION__, mCameraId, format);
395e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
396e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
397e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
398bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk    // Round dimensions to the nearest dimensions available for this format
399bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk    if (flexibleConsumer && !CameraDeviceClient::roundBufferDimensionNearest(width, height,
400bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk            format, mDevice->info(), /*out*/&width, /*out*/&height)) {
401bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk        ALOGE("%s: No stream configurations with the format %#x defined, failed to create stream.",
402bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk                __FUNCTION__, format);
403bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk        return BAD_VALUE;
404bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk    }
405e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
406e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    int streamId = -1;
40728c9b6f298134624cb52b1af4ed8716dddb983d3Zhijun He    res = mDevice->createStream(anw, width, height, format, &streamId);
408e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
409e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if (res == OK) {
410e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        mStreamMap.add(bufferProducer->asBinder(), streamId);
411e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
412e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        ALOGV("%s: Camera %d: Successfully created a new stream ID %d",
413e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin              __FUNCTION__, mCameraId, streamId);
414f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin
415f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin        /**
416f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin         * Set the stream transform flags to automatically
417f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin         * rotate the camera stream for preview use cases.
418f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin         */
419f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin        int32_t transform = 0;
420f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin        res = getRotationTransformLocked(&transform);
421f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin
422f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin        if (res != OK) {
423f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin            // Error logged by getRotationTransformLocked.
424f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin            return res;
425f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin        }
426f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin
427f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin        res = mDevice->setStreamTransform(streamId, transform);
428f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin        if (res != OK) {
429f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin            ALOGE("%s: Failed to set stream transform (stream id %d)",
430f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin                  __FUNCTION__, streamId);
431f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin            return res;
432f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin        }
433f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin
434e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        return streamId;
435e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
436e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
437e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    return res;
438e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin}
439e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
440bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk
441bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunkbool CameraDeviceClient::roundBufferDimensionNearest(int32_t width, int32_t height,
442bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk        int32_t format, const CameraMetadata& info,
443bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk        /*out*/int32_t* outWidth, /*out*/int32_t* outHeight) {
444bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk
445bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk    camera_metadata_ro_entry streamConfigs =
446bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk            info.find(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS);
447bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk
448bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk    int32_t bestWidth = -1;
449bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk    int32_t bestHeight = -1;
450bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk
451bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk    // Iterate through listed stream configurations and find the one with the smallest euclidean
452bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk    // distance from the given dimensions for the given format.
453bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk    for (size_t i = 0; i < streamConfigs.count; i += 4) {
454bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk        int32_t fmt = streamConfigs.data.i32[i];
455bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk        int32_t w = streamConfigs.data.i32[i + 1];
456bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk        int32_t h = streamConfigs.data.i32[i + 2];
457bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk
458bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk        // Ignore input/output type for now
459bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk        if (fmt == format) {
460bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk            if (w == width && h == height) {
461bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk                bestWidth = width;
462bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk                bestHeight = height;
463bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk                break;
464bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk            } else if (w <= ROUNDING_WIDTH_CAP && (bestWidth == -1 ||
465bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk                    CameraDeviceClient::euclidDistSquare(w, h, width, height) <
466bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk                    CameraDeviceClient::euclidDistSquare(bestWidth, bestHeight, width, height))) {
467bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk                bestWidth = w;
468bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk                bestHeight = h;
469bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk            }
470bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk        }
471bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk    }
472bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk
473bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk    if (bestWidth == -1) {
474bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk        // Return false if no configurations for this format were listed
475bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk        return false;
476bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk    }
477bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk
478bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk    // Set the outputs to the closet width/height
479bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk    if (outWidth != NULL) {
480bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk        *outWidth = bestWidth;
481bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk    }
482bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk    if (outHeight != NULL) {
483bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk        *outHeight = bestHeight;
484bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk    }
485bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk
486bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk    // Return true if at least one configuration for this format was listed
487bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk    return true;
488bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk}
489bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk
490bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunkint64_t CameraDeviceClient::euclidDistSquare(int32_t x0, int32_t y0, int32_t x1, int32_t y1) {
491bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk    int64_t d0 = x0 - x1;
492bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk    int64_t d1 = y0 - y1;
493bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk    return d0 * d0 + d1 * d1;
494bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk}
495bba75576c3bc5a90cd8e14bd053ab2d74a6c7e9dRuben Brunk
496e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin// Create a request object from a template.
497e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkinstatus_t CameraDeviceClient::createDefaultRequest(int templateId,
498e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                                                  /*out*/
499e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                                                  CameraMetadata* request)
500e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin{
501e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    ATRACE_CALL();
502e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    ALOGV("%s (templateId = 0x%x)", __FUNCTION__, templateId);
503e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
504e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    status_t res;
505e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
506e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
507e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    Mutex::Autolock icl(mBinderSerializationLock);
508e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
509e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if (!mDevice.get()) return DEAD_OBJECT;
510e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
511e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    CameraMetadata metadata;
512e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if ( (res = mDevice->createDefaultRequest(templateId, &metadata) ) == OK &&
513e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        request != NULL) {
514e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
515e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        request->swap(metadata);
516e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
517e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
518e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    return res;
519e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin}
520e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
521099b457f3203fa51387e21bd450495abb973ab31Igor Murashkinstatus_t CameraDeviceClient::getCameraInfo(/*out*/CameraMetadata* info)
522e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin{
523e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    ATRACE_CALL();
524e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    ALOGV("%s", __FUNCTION__);
525e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
526e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    status_t res = OK;
527e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
528e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
529e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
530e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    Mutex::Autolock icl(mBinderSerializationLock);
531e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
532e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if (!mDevice.get()) return DEAD_OBJECT;
533e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
534099b457f3203fa51387e21bd450495abb973ab31Igor Murashkin    if (info != NULL) {
535099b457f3203fa51387e21bd450495abb973ab31Igor Murashkin        *info = mDevice->info(); // static camera metadata
536099b457f3203fa51387e21bd450495abb973ab31Igor Murashkin        // TODO: merge with device-specific camera metadata
537099b457f3203fa51387e21bd450495abb973ab31Igor Murashkin    }
538e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
539e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    return res;
540e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin}
541e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
5422ab500c632569e2f131a1a2288459933da70c4eeZhijun Hestatus_t CameraDeviceClient::waitUntilIdle()
5432ab500c632569e2f131a1a2288459933da70c4eeZhijun He{
5442ab500c632569e2f131a1a2288459933da70c4eeZhijun He    ATRACE_CALL();
5452ab500c632569e2f131a1a2288459933da70c4eeZhijun He    ALOGV("%s", __FUNCTION__);
5462ab500c632569e2f131a1a2288459933da70c4eeZhijun He
5472ab500c632569e2f131a1a2288459933da70c4eeZhijun He    status_t res = OK;
5482ab500c632569e2f131a1a2288459933da70c4eeZhijun He    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
5492ab500c632569e2f131a1a2288459933da70c4eeZhijun He
5502ab500c632569e2f131a1a2288459933da70c4eeZhijun He    Mutex::Autolock icl(mBinderSerializationLock);
5512ab500c632569e2f131a1a2288459933da70c4eeZhijun He
5522ab500c632569e2f131a1a2288459933da70c4eeZhijun He    if (!mDevice.get()) return DEAD_OBJECT;
5532ab500c632569e2f131a1a2288459933da70c4eeZhijun He
5542ab500c632569e2f131a1a2288459933da70c4eeZhijun He    // FIXME: Also need check repeating burst.
5552ab500c632569e2f131a1a2288459933da70c4eeZhijun He    if (!mStreamingRequestList.isEmpty()) {
5562ab500c632569e2f131a1a2288459933da70c4eeZhijun He        ALOGE("%s: Camera %d: Try to waitUntilIdle when there are active streaming requests",
5572ab500c632569e2f131a1a2288459933da70c4eeZhijun He              __FUNCTION__, mCameraId);
5582ab500c632569e2f131a1a2288459933da70c4eeZhijun He        return INVALID_OPERATION;
5592ab500c632569e2f131a1a2288459933da70c4eeZhijun He    }
5602ab500c632569e2f131a1a2288459933da70c4eeZhijun He    res = mDevice->waitUntilDrained();
5612ab500c632569e2f131a1a2288459933da70c4eeZhijun He    ALOGV("%s Done", __FUNCTION__);
5622ab500c632569e2f131a1a2288459933da70c4eeZhijun He
5632ab500c632569e2f131a1a2288459933da70c4eeZhijun He    return res;
5642ab500c632569e2f131a1a2288459933da70c4eeZhijun He}
5652ab500c632569e2f131a1a2288459933da70c4eeZhijun He
566cb0652e5a850b2fcd919e977247e87239efaf70eJianing Weistatus_t CameraDeviceClient::flush(int64_t* lastFrameNumber) {
567abaa51d3ca31f0eda99e1d271e6dc64c877dbf58Eino-Ville Talvala    ATRACE_CALL();
568abaa51d3ca31f0eda99e1d271e6dc64c877dbf58Eino-Ville Talvala    ALOGV("%s", __FUNCTION__);
569abaa51d3ca31f0eda99e1d271e6dc64c877dbf58Eino-Ville Talvala
570abaa51d3ca31f0eda99e1d271e6dc64c877dbf58Eino-Ville Talvala    status_t res = OK;
571abaa51d3ca31f0eda99e1d271e6dc64c877dbf58Eino-Ville Talvala    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
572abaa51d3ca31f0eda99e1d271e6dc64c877dbf58Eino-Ville Talvala
573abaa51d3ca31f0eda99e1d271e6dc64c877dbf58Eino-Ville Talvala    Mutex::Autolock icl(mBinderSerializationLock);
574abaa51d3ca31f0eda99e1d271e6dc64c877dbf58Eino-Ville Talvala
575abaa51d3ca31f0eda99e1d271e6dc64c877dbf58Eino-Ville Talvala    if (!mDevice.get()) return DEAD_OBJECT;
576abaa51d3ca31f0eda99e1d271e6dc64c877dbf58Eino-Ville Talvala
5773c76fa3e73374dfe7bb93e1b03fed30749e1e4b9Jianing Wei    mStreamingRequestList.clear();
578cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei    return mDevice->flush(lastFrameNumber);
579abaa51d3ca31f0eda99e1d271e6dc64c877dbf58Eino-Ville Talvala}
580abaa51d3ca31f0eda99e1d271e6dc64c877dbf58Eino-Ville Talvala
581e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkinstatus_t CameraDeviceClient::dump(int fd, const Vector<String16>& args) {
582e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    String8 result;
58367489d2f5668441a36cb1f1157e80ec8684023bfEino-Ville Talvala    result.appendFormat("CameraDeviceClient[%d] (%p) dump:\n",
584e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin            mCameraId,
58567489d2f5668441a36cb1f1157e80ec8684023bfEino-Ville Talvala            getRemoteCallback()->asBinder().get());
58667489d2f5668441a36cb1f1157e80ec8684023bfEino-Ville Talvala    result.appendFormat("  Current client: %s (PID %d, UID %u)\n",
58767489d2f5668441a36cb1f1157e80ec8684023bfEino-Ville Talvala            String8(mClientPackageName).string(),
58867489d2f5668441a36cb1f1157e80ec8684023bfEino-Ville Talvala            mClientPid, mClientUid);
58967489d2f5668441a36cb1f1157e80ec8684023bfEino-Ville Talvala
59067489d2f5668441a36cb1f1157e80ec8684023bfEino-Ville Talvala    result.append("  State:\n");
59167489d2f5668441a36cb1f1157e80ec8684023bfEino-Ville Talvala    result.appendFormat("    Request ID counter: %d\n", mRequestIdCounter);
59267489d2f5668441a36cb1f1157e80ec8684023bfEino-Ville Talvala    if (!mStreamMap.isEmpty()) {
59367489d2f5668441a36cb1f1157e80ec8684023bfEino-Ville Talvala        result.append("    Current stream IDs:\n");
59467489d2f5668441a36cb1f1157e80ec8684023bfEino-Ville Talvala        for (size_t i = 0; i < mStreamMap.size(); i++) {
59567489d2f5668441a36cb1f1157e80ec8684023bfEino-Ville Talvala            result.appendFormat("      Stream %d\n", mStreamMap.valueAt(i));
59667489d2f5668441a36cb1f1157e80ec8684023bfEino-Ville Talvala        }
59767489d2f5668441a36cb1f1157e80ec8684023bfEino-Ville Talvala    } else {
59867489d2f5668441a36cb1f1157e80ec8684023bfEino-Ville Talvala        result.append("    No streams configured.\n");
59967489d2f5668441a36cb1f1157e80ec8684023bfEino-Ville Talvala    }
60067489d2f5668441a36cb1f1157e80ec8684023bfEino-Ville Talvala    write(fd, result.string(), result.size());
601e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    // TODO: print dynamic/request section from most recent requests
602e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    mFrameProcessor->dump(fd, args);
603e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
604e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    return dumpDevice(fd, args);
605e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin}
606e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
607cb0652e5a850b2fcd919e977247e87239efaf70eJianing Weivoid CameraDeviceClient::notifyError(ICameraDeviceCallbacks::CameraErrorCode errorCode,
608cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei                                     const CaptureResultExtras& resultExtras) {
609f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    // Thread safe. Don't bother locking.
610f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    sp<ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
611f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
612f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    if (remoteCb != 0) {
613cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei        remoteCb->onDeviceError(errorCode, resultExtras);
614f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    }
615f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala}
616f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
617f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvalavoid CameraDeviceClient::notifyIdle() {
618f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    // Thread safe. Don't bother locking.
619f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    sp<ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
620f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
621f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    if (remoteCb != 0) {
622f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        remoteCb->onDeviceIdle();
623f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    }
624f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala}
625f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
626cb0652e5a850b2fcd919e977247e87239efaf70eJianing Weivoid CameraDeviceClient::notifyShutter(const CaptureResultExtras& resultExtras,
627f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        nsecs_t timestamp) {
628f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    // Thread safe. Don't bother locking.
629f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    sp<ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
630f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    if (remoteCb != 0) {
631cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei        remoteCb->onCaptureStarted(resultExtras, timestamp);
632f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    }
633f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala}
634f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
635e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin// TODO: refactor the code below this with IProCameraUser.
636e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin// it's 100% copy-pasted, so lets not change it right now to make it easier.
637e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
638e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkinvoid CameraDeviceClient::detachDevice() {
639e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if (mDevice == 0) return;
640e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
641e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    ALOGV("Camera %d: Stopping processors", mCameraId);
642e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
643e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    mFrameProcessor->removeListener(FRAME_PROCESSOR_LISTENER_MIN_ID,
644e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                                    FRAME_PROCESSOR_LISTENER_MAX_ID,
645e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                                    /*listener*/this);
646e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    mFrameProcessor->requestExit();
647e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    ALOGV("Camera %d: Waiting for threads", mCameraId);
648e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    mFrameProcessor->join();
649e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    ALOGV("Camera %d: Disconnecting device", mCameraId);
650e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
651e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    // WORKAROUND: HAL refuses to disconnect while there's streams in flight
652e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    {
653e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        mDevice->clearStreamingRequest();
654e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
655e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        status_t code;
656e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        if ((code = mDevice->waitUntilDrained()) != OK) {
657e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin            ALOGE("%s: waitUntilDrained failed with code 0x%x", __FUNCTION__,
658e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                  code);
659e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        }
660e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
661e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
662e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    Camera2ClientBase::detachDevice();
663e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin}
664e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
665e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin/** Device-related methods */
666cb0652e5a850b2fcd919e977247e87239efaf70eJianing Weivoid CameraDeviceClient::onResultAvailable(const CaptureResult& result) {
667e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    ATRACE_CALL();
668e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    ALOGV("%s", __FUNCTION__);
669e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
6704fb55c15da1a563ab925914a0f493a3dc80495a3Igor Murashkin    // Thread-safe. No lock necessary.
6714fb55c15da1a563ab925914a0f493a3dc80495a3Igor Murashkin    sp<ICameraDeviceCallbacks> remoteCb = mRemoteCallback;
6724fb55c15da1a563ab925914a0f493a3dc80495a3Igor Murashkin    if (remoteCb != NULL) {
673cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei        remoteCb->onResultReceived(result.mMetadata, result.mResultExtras);
674e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
675e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin}
676e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
677e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin// TODO: move to Camera2ClientBase
678e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkinbool CameraDeviceClient::enforceRequestPermissions(CameraMetadata& metadata) {
679e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
680e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    const int pid = IPCThreadState::self()->getCallingPid();
681e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    const int selfPid = getpid();
682e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    camera_metadata_entry_t entry;
683e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
684e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    /**
685e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin     * Mixin default important security values
686e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin     * - android.led.transmit = defaulted ON
687e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin     */
688e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    CameraMetadata staticInfo = mDevice->info();
689e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    entry = staticInfo.find(ANDROID_LED_AVAILABLE_LEDS);
690e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    for(size_t i = 0; i < entry.count; ++i) {
691e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        uint8_t led = entry.data.u8[i];
692e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
693e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        switch(led) {
694e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin            case ANDROID_LED_AVAILABLE_LEDS_TRANSMIT: {
695e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                uint8_t transmitDefault = ANDROID_LED_TRANSMIT_ON;
696e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                if (!metadata.exists(ANDROID_LED_TRANSMIT)) {
697e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                    metadata.update(ANDROID_LED_TRANSMIT,
698e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                                    &transmitDefault, 1);
699e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                }
700e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                break;
701e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin            }
702e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        }
703e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
704e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
705e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    // We can do anything!
706e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if (pid == selfPid) {
707e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        return true;
708e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
709e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
710e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    /**
711e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin     * Permission check special fields in the request
712e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin     * - android.led.transmit = android.permission.CAMERA_DISABLE_TRANSMIT
713e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin     */
714e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    entry = metadata.find(ANDROID_LED_TRANSMIT);
715e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if (entry.count > 0 && entry.data.u8[0] != ANDROID_LED_TRANSMIT_ON) {
716e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        String16 permissionString =
717e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin            String16("android.permission.CAMERA_DISABLE_TRANSMIT_LED");
718e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        if (!checkCallingPermission(permissionString)) {
719e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin            const int uid = IPCThreadState::self()->getCallingUid();
720e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin            ALOGE("Permission Denial: "
721e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                  "can't disable transmit LED pid=%d, uid=%d", pid, uid);
722e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin            return false;
723e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        }
724e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
725e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
726e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    return true;
727e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin}
728e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
729f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkinstatus_t CameraDeviceClient::getRotationTransformLocked(int32_t* transform) {
730f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin    ALOGV("%s: begin", __FUNCTION__);
731f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin
732f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin    const CameraMetadata& staticInfo = mDevice->info();
7335698d4461a260dbf208484383f692b03c6473e74Ruben Brunk    return CameraUtils::getRotationTransform(staticInfo, transform);
734f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin}
735f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin
736e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin} // namespace android
737