CameraDeviceClient.cpp revision 28c9b6f298134624cb52b1af4ed8716dddb983d3
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() { 257b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk // TODO: Implement this. 258b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk ALOGE("%s: Not implemented yet.", __FUNCTION__); 259b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk return OK; 260b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk} 261b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk 262e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkinstatus_t CameraDeviceClient::deleteStream(int streamId) { 263e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin ATRACE_CALL(); 264e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin ALOGV("%s (streamId = 0x%x)", __FUNCTION__, streamId); 265e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin 266e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin status_t res; 267e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin if ( (res = checkPid(__FUNCTION__) ) != OK) return res; 268e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin 269e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin Mutex::Autolock icl(mBinderSerializationLock); 270e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin 271e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin if (!mDevice.get()) return DEAD_OBJECT; 272e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin 273e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin // Guard against trying to delete non-created streams 274e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin ssize_t index = NAME_NOT_FOUND; 275e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin for (size_t i = 0; i < mStreamMap.size(); ++i) { 276e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin if (streamId == mStreamMap.valueAt(i)) { 277e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin index = i; 278e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin break; 279e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin } 280e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin } 281e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin 282e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin if (index == NAME_NOT_FOUND) { 283e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin ALOGW("%s: Camera %d: Invalid stream ID (%d) specified, no stream " 284e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin "created yet", __FUNCTION__, mCameraId, streamId); 285e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin return BAD_VALUE; 286e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin } 287e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin 288e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin // Also returns BAD_VALUE if stream ID was not valid 289e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin res = mDevice->deleteStream(streamId); 290e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin 291e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin if (res == BAD_VALUE) { 292e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin ALOGE("%s: Camera %d: Unexpected BAD_VALUE when deleting stream, but we" 293e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin " already checked and the stream ID (%d) should be valid.", 294e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin __FUNCTION__, mCameraId, streamId); 295e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin } else if (res == OK) { 296e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin mStreamMap.removeItemsAt(index); 297e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin 298e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin } 299e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin 300e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin return res; 301e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin} 302e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin 303e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkinstatus_t CameraDeviceClient::createStream(int width, int height, int format, 304e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin const sp<IGraphicBufferProducer>& bufferProducer) 305e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin{ 306e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin ATRACE_CALL(); 307e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin ALOGV("%s (w = %d, h = %d, f = 0x%x)", __FUNCTION__, width, height, format); 308e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin 309e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin status_t res; 310e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin if ( (res = checkPid(__FUNCTION__) ) != OK) return res; 311e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin 312e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin Mutex::Autolock icl(mBinderSerializationLock); 313e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin 31489f14dacfadea1b14149510d4dfbc75dc79b23bbYin-Chia Yeh if (bufferProducer == NULL) { 31589f14dacfadea1b14149510d4dfbc75dc79b23bbYin-Chia Yeh ALOGE("%s: bufferProducer must not be null", __FUNCTION__); 31689f14dacfadea1b14149510d4dfbc75dc79b23bbYin-Chia Yeh return BAD_VALUE; 31789f14dacfadea1b14149510d4dfbc75dc79b23bbYin-Chia Yeh } 318e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin if (!mDevice.get()) return DEAD_OBJECT; 319e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin 320e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin // Don't create multiple streams for the same target surface 321e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin { 322e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin ssize_t index = mStreamMap.indexOfKey(bufferProducer->asBinder()); 323e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin if (index != NAME_NOT_FOUND) { 324e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin ALOGW("%s: Camera %d: Buffer producer already has a stream for it " 325e5729fac81c8a984e984fefc90afc64135817d4fColin Cross "(ID %zd)", 326e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin __FUNCTION__, mCameraId, index); 327e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin return ALREADY_EXISTS; 328e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin } 329e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin } 330e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin 3311da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala // HACK b/10949105 3321da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala // Query consumer usage bits to set async operation mode for 3331da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala // GLConsumer using controlledByApp parameter. 3341da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala bool useAsync = false; 3351da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala int32_t consumerUsage; 3361da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala if ((res = bufferProducer->query(NATIVE_WINDOW_CONSUMER_USAGE_BITS, 3371da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala &consumerUsage)) != OK) { 3381da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala ALOGE("%s: Camera %d: Failed to query consumer usage", __FUNCTION__, 3391da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala mCameraId); 3401da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala return res; 3411da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala } 3421da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala if (consumerUsage & GraphicBuffer::USAGE_HW_TEXTURE) { 3431da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala ALOGW("%s: Camera %d: Forcing asynchronous mode for stream", 3441da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala __FUNCTION__, mCameraId); 3451da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala useAsync = true; 3461da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala } 3471da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala 348e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin sp<IBinder> binder; 349e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin sp<ANativeWindow> anw; 350e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin if (bufferProducer != 0) { 351e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin binder = bufferProducer->asBinder(); 3521da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala anw = new Surface(bufferProducer, useAsync); 353e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin } 354e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin 355e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin // TODO: remove w,h,f since we are ignoring them 356e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin 357e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin if ((res = anw->query(anw.get(), NATIVE_WINDOW_WIDTH, &width)) != OK) { 358e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin ALOGE("%s: Camera %d: Failed to query Surface width", __FUNCTION__, 359e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin mCameraId); 360e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin return res; 361e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin } 362e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin if ((res = anw->query(anw.get(), NATIVE_WINDOW_HEIGHT, &height)) != OK) { 363e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin ALOGE("%s: Camera %d: Failed to query Surface height", __FUNCTION__, 364e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin mCameraId); 365e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin return res; 366e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin } 367e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin if ((res = anw->query(anw.get(), NATIVE_WINDOW_FORMAT, &format)) != OK) { 368e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin ALOGE("%s: Camera %d: Failed to query Surface format", __FUNCTION__, 369e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin mCameraId); 370e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin return res; 371e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin } 372e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin 373e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin // FIXME: remove this override since the default format should be 374e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin // IMPLEMENTATION_DEFINED. b/9487482 3751581101ce2a8c1b8d0b07b643ad891595221d781Igor Murashkin if (format >= HAL_PIXEL_FORMAT_RGBA_8888 && 3761581101ce2a8c1b8d0b07b643ad891595221d781Igor Murashkin format <= HAL_PIXEL_FORMAT_BGRA_8888) { 377e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin ALOGW("%s: Camera %d: Overriding format 0x%x to IMPLEMENTATION_DEFINED", 378e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin __FUNCTION__, mCameraId, format); 379e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED; 380e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin } 381e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin 382e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin // TODO: add startConfigure/stopConfigure call to CameraDeviceBase 383e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin // this will make it so Camera3Device doesn't call configure_streams 384e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin // after each call, but only once we are done with all. 385e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin 386e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin int streamId = -1; 38728c9b6f298134624cb52b1af4ed8716dddb983d3Zhijun He res = mDevice->createStream(anw, width, height, format, &streamId); 388e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin 389e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin if (res == OK) { 390e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin mStreamMap.add(bufferProducer->asBinder(), streamId); 391e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin 392e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin ALOGV("%s: Camera %d: Successfully created a new stream ID %d", 393e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin __FUNCTION__, mCameraId, streamId); 394f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin 395f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin /** 396f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin * Set the stream transform flags to automatically 397f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin * rotate the camera stream for preview use cases. 398f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin */ 399f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin int32_t transform = 0; 400f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin res = getRotationTransformLocked(&transform); 401f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin 402f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin if (res != OK) { 403f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin // Error logged by getRotationTransformLocked. 404f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin return res; 405f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin } 406f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin 407f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin res = mDevice->setStreamTransform(streamId, transform); 408f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin if (res != OK) { 409f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin ALOGE("%s: Failed to set stream transform (stream id %d)", 410f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin __FUNCTION__, streamId); 411f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin return res; 412f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin } 413f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin 414e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin return streamId; 415e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin } 416e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin 417e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin return res; 418e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin} 419e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin 420e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin// Create a request object from a template. 421e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkinstatus_t CameraDeviceClient::createDefaultRequest(int templateId, 422e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin /*out*/ 423e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin CameraMetadata* request) 424e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin{ 425e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin ATRACE_CALL(); 426e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin ALOGV("%s (templateId = 0x%x)", __FUNCTION__, templateId); 427e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin 428e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin status_t res; 429e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin if ( (res = checkPid(__FUNCTION__) ) != OK) return res; 430e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin 431e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin Mutex::Autolock icl(mBinderSerializationLock); 432e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin 433e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin if (!mDevice.get()) return DEAD_OBJECT; 434e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin 435e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin CameraMetadata metadata; 436e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin if ( (res = mDevice->createDefaultRequest(templateId, &metadata) ) == OK && 437e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin request != NULL) { 438e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin 439e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin request->swap(metadata); 440e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin } 441e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin 442e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin return res; 443e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin} 444e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin 445099b457f3203fa51387e21bd450495abb973ab31Igor Murashkinstatus_t CameraDeviceClient::getCameraInfo(/*out*/CameraMetadata* info) 446e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin{ 447e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin ATRACE_CALL(); 448e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin ALOGV("%s", __FUNCTION__); 449e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin 450e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin status_t res = OK; 451e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin 452e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin if ( (res = checkPid(__FUNCTION__) ) != OK) return res; 453e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin 454e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin Mutex::Autolock icl(mBinderSerializationLock); 455e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin 456e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin if (!mDevice.get()) return DEAD_OBJECT; 457e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin 458099b457f3203fa51387e21bd450495abb973ab31Igor Murashkin if (info != NULL) { 459099b457f3203fa51387e21bd450495abb973ab31Igor Murashkin *info = mDevice->info(); // static camera metadata 460099b457f3203fa51387e21bd450495abb973ab31Igor Murashkin // TODO: merge with device-specific camera metadata 461099b457f3203fa51387e21bd450495abb973ab31Igor Murashkin } 462e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin 463e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin return res; 464e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin} 465e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin 4662ab500c632569e2f131a1a2288459933da70c4eeZhijun Hestatus_t CameraDeviceClient::waitUntilIdle() 4672ab500c632569e2f131a1a2288459933da70c4eeZhijun He{ 4682ab500c632569e2f131a1a2288459933da70c4eeZhijun He ATRACE_CALL(); 4692ab500c632569e2f131a1a2288459933da70c4eeZhijun He ALOGV("%s", __FUNCTION__); 4702ab500c632569e2f131a1a2288459933da70c4eeZhijun He 4712ab500c632569e2f131a1a2288459933da70c4eeZhijun He status_t res = OK; 4722ab500c632569e2f131a1a2288459933da70c4eeZhijun He if ( (res = checkPid(__FUNCTION__) ) != OK) return res; 4732ab500c632569e2f131a1a2288459933da70c4eeZhijun He 4742ab500c632569e2f131a1a2288459933da70c4eeZhijun He Mutex::Autolock icl(mBinderSerializationLock); 4752ab500c632569e2f131a1a2288459933da70c4eeZhijun He 4762ab500c632569e2f131a1a2288459933da70c4eeZhijun He if (!mDevice.get()) return DEAD_OBJECT; 4772ab500c632569e2f131a1a2288459933da70c4eeZhijun He 4782ab500c632569e2f131a1a2288459933da70c4eeZhijun He // FIXME: Also need check repeating burst. 4792ab500c632569e2f131a1a2288459933da70c4eeZhijun He if (!mStreamingRequestList.isEmpty()) { 4802ab500c632569e2f131a1a2288459933da70c4eeZhijun He ALOGE("%s: Camera %d: Try to waitUntilIdle when there are active streaming requests", 4812ab500c632569e2f131a1a2288459933da70c4eeZhijun He __FUNCTION__, mCameraId); 4822ab500c632569e2f131a1a2288459933da70c4eeZhijun He return INVALID_OPERATION; 4832ab500c632569e2f131a1a2288459933da70c4eeZhijun He } 4842ab500c632569e2f131a1a2288459933da70c4eeZhijun He res = mDevice->waitUntilDrained(); 4852ab500c632569e2f131a1a2288459933da70c4eeZhijun He ALOGV("%s Done", __FUNCTION__); 4862ab500c632569e2f131a1a2288459933da70c4eeZhijun He 4872ab500c632569e2f131a1a2288459933da70c4eeZhijun He return res; 4882ab500c632569e2f131a1a2288459933da70c4eeZhijun He} 4892ab500c632569e2f131a1a2288459933da70c4eeZhijun He 490cb0652e5a850b2fcd919e977247e87239efaf70eJianing Weistatus_t CameraDeviceClient::flush(int64_t* lastFrameNumber) { 491abaa51d3ca31f0eda99e1d271e6dc64c877dbf58Eino-Ville Talvala ATRACE_CALL(); 492abaa51d3ca31f0eda99e1d271e6dc64c877dbf58Eino-Ville Talvala ALOGV("%s", __FUNCTION__); 493abaa51d3ca31f0eda99e1d271e6dc64c877dbf58Eino-Ville Talvala 494abaa51d3ca31f0eda99e1d271e6dc64c877dbf58Eino-Ville Talvala status_t res = OK; 495abaa51d3ca31f0eda99e1d271e6dc64c877dbf58Eino-Ville Talvala if ( (res = checkPid(__FUNCTION__) ) != OK) return res; 496abaa51d3ca31f0eda99e1d271e6dc64c877dbf58Eino-Ville Talvala 497abaa51d3ca31f0eda99e1d271e6dc64c877dbf58Eino-Ville Talvala Mutex::Autolock icl(mBinderSerializationLock); 498abaa51d3ca31f0eda99e1d271e6dc64c877dbf58Eino-Ville Talvala 499abaa51d3ca31f0eda99e1d271e6dc64c877dbf58Eino-Ville Talvala if (!mDevice.get()) return DEAD_OBJECT; 500abaa51d3ca31f0eda99e1d271e6dc64c877dbf58Eino-Ville Talvala 5013c76fa3e73374dfe7bb93e1b03fed30749e1e4b9Jianing Wei mStreamingRequestList.clear(); 502cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei return mDevice->flush(lastFrameNumber); 503abaa51d3ca31f0eda99e1d271e6dc64c877dbf58Eino-Ville Talvala} 504abaa51d3ca31f0eda99e1d271e6dc64c877dbf58Eino-Ville Talvala 505e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkinstatus_t CameraDeviceClient::dump(int fd, const Vector<String16>& args) { 506e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin String8 result; 507e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin result.appendFormat("CameraDeviceClient[%d] (%p) PID: %d, dump:\n", 508e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin mCameraId, 509e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin getRemoteCallback()->asBinder().get(), 510e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin mClientPid); 511e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin result.append(" State: "); 512e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin 513e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin // TODO: print dynamic/request section from most recent requests 514e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin mFrameProcessor->dump(fd, args); 515e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin 516e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin return dumpDevice(fd, args); 517e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin} 518e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin 519cb0652e5a850b2fcd919e977247e87239efaf70eJianing Weivoid CameraDeviceClient::notifyError(ICameraDeviceCallbacks::CameraErrorCode errorCode, 520cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei const CaptureResultExtras& resultExtras) { 521f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala // Thread safe. Don't bother locking. 522f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala sp<ICameraDeviceCallbacks> remoteCb = getRemoteCallback(); 523f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala 524f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala if (remoteCb != 0) { 525cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei remoteCb->onDeviceError(errorCode, resultExtras); 526f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala } 527f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala} 528f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala 529f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvalavoid CameraDeviceClient::notifyIdle() { 530f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala // Thread safe. Don't bother locking. 531f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala sp<ICameraDeviceCallbacks> remoteCb = getRemoteCallback(); 532f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala 533f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala if (remoteCb != 0) { 534f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala remoteCb->onDeviceIdle(); 535f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala } 536f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala} 537f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala 538cb0652e5a850b2fcd919e977247e87239efaf70eJianing Weivoid CameraDeviceClient::notifyShutter(const CaptureResultExtras& resultExtras, 539f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala nsecs_t timestamp) { 540f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala // Thread safe. Don't bother locking. 541f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala sp<ICameraDeviceCallbacks> remoteCb = getRemoteCallback(); 542f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala if (remoteCb != 0) { 543cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei remoteCb->onCaptureStarted(resultExtras, timestamp); 544f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala } 545f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala} 546f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala 547e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin// TODO: refactor the code below this with IProCameraUser. 548e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin// it's 100% copy-pasted, so lets not change it right now to make it easier. 549e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin 550e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkinvoid CameraDeviceClient::detachDevice() { 551e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin if (mDevice == 0) return; 552e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin 553e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin ALOGV("Camera %d: Stopping processors", mCameraId); 554e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin 555e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin mFrameProcessor->removeListener(FRAME_PROCESSOR_LISTENER_MIN_ID, 556e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin FRAME_PROCESSOR_LISTENER_MAX_ID, 557e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin /*listener*/this); 558e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin mFrameProcessor->requestExit(); 559e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin ALOGV("Camera %d: Waiting for threads", mCameraId); 560e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin mFrameProcessor->join(); 561e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin ALOGV("Camera %d: Disconnecting device", mCameraId); 562e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin 563e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin // WORKAROUND: HAL refuses to disconnect while there's streams in flight 564e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin { 565e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin mDevice->clearStreamingRequest(); 566e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin 567e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin status_t code; 568e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin if ((code = mDevice->waitUntilDrained()) != OK) { 569e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin ALOGE("%s: waitUntilDrained failed with code 0x%x", __FUNCTION__, 570e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin code); 571e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin } 572e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin } 573e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin 574e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin Camera2ClientBase::detachDevice(); 575e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin} 576e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin 577e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin/** Device-related methods */ 578cb0652e5a850b2fcd919e977247e87239efaf70eJianing Weivoid CameraDeviceClient::onResultAvailable(const CaptureResult& result) { 579e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin ATRACE_CALL(); 580e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin ALOGV("%s", __FUNCTION__); 581e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin 5824fb55c15da1a563ab925914a0f493a3dc80495a3Igor Murashkin // Thread-safe. No lock necessary. 5834fb55c15da1a563ab925914a0f493a3dc80495a3Igor Murashkin sp<ICameraDeviceCallbacks> remoteCb = mRemoteCallback; 5844fb55c15da1a563ab925914a0f493a3dc80495a3Igor Murashkin if (remoteCb != NULL) { 585cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei remoteCb->onResultReceived(result.mMetadata, result.mResultExtras); 586e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin } 587e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin} 588e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin 589e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin// TODO: move to Camera2ClientBase 590e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkinbool CameraDeviceClient::enforceRequestPermissions(CameraMetadata& metadata) { 591e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin 592e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin const int pid = IPCThreadState::self()->getCallingPid(); 593e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin const int selfPid = getpid(); 594e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin camera_metadata_entry_t entry; 595e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin 596e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin /** 597e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin * Mixin default important security values 598e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin * - android.led.transmit = defaulted ON 599e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin */ 600e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin CameraMetadata staticInfo = mDevice->info(); 601e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin entry = staticInfo.find(ANDROID_LED_AVAILABLE_LEDS); 602e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin for(size_t i = 0; i < entry.count; ++i) { 603e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin uint8_t led = entry.data.u8[i]; 604e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin 605e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin switch(led) { 606e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin case ANDROID_LED_AVAILABLE_LEDS_TRANSMIT: { 607e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin uint8_t transmitDefault = ANDROID_LED_TRANSMIT_ON; 608e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin if (!metadata.exists(ANDROID_LED_TRANSMIT)) { 609e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin metadata.update(ANDROID_LED_TRANSMIT, 610e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin &transmitDefault, 1); 611e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin } 612e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin break; 613e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin } 614e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin } 615e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin } 616e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin 617e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin // We can do anything! 618e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin if (pid == selfPid) { 619e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin return true; 620e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin } 621e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin 622e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin /** 623e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin * Permission check special fields in the request 624e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin * - android.led.transmit = android.permission.CAMERA_DISABLE_TRANSMIT 625e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin */ 626e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin entry = metadata.find(ANDROID_LED_TRANSMIT); 627e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin if (entry.count > 0 && entry.data.u8[0] != ANDROID_LED_TRANSMIT_ON) { 628e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin String16 permissionString = 629e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin String16("android.permission.CAMERA_DISABLE_TRANSMIT_LED"); 630e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin if (!checkCallingPermission(permissionString)) { 631e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin const int uid = IPCThreadState::self()->getCallingUid(); 632e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin ALOGE("Permission Denial: " 633e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin "can't disable transmit LED pid=%d, uid=%d", pid, uid); 634e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin return false; 635e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin } 636e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin } 637e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin 638e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin return true; 639e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin} 640e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin 641f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkinstatus_t CameraDeviceClient::getRotationTransformLocked(int32_t* transform) { 642f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin ALOGV("%s: begin", __FUNCTION__); 643f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin 644f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin const CameraMetadata& staticInfo = mDevice->info(); 6455698d4461a260dbf208484383f692b03c6473e74Ruben Brunk return CameraUtils::getRotationTransform(staticInfo, transform); 646f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin} 647f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin 648e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin} // namespace android 649