ProCamera2Client.cpp revision 7b82efe7a376c882f8f938e1c41b8311a8cdda4a
1edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/* 2edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Copyright (C) 2013 The Android Open Source Project 3edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * 4edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * you may not use this file except in compliance with the License. 6edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * You may obtain a copy of the License at 7edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * 8edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * 10edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * See the License for the specific language governing permissions and 14edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * limitations under the License. 15edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 16edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 17edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define LOG_TAG "ProCamera2Client" 18edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define ATRACE_TAG ATRACE_TAG_CAMERA 19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project//#define LOG_NDEBUG 0 20edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Log.h> 22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Trace.h> 23edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 24edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/properties.h> 25edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <gui/Surface.h> 26edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <gui/Surface.h> 27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 28edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "api_pro/ProCamera2Client.h" 29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "common/CameraDeviceBase.h" 30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android { 32edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectusing namespace camera2; 33edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 34edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// Interface used by CameraService 35edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 36edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectProCamera2Client::ProCamera2Client(const sp<CameraService>& cameraService, 37edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const sp<IProCameraCallbacks>& remoteCallback, 38edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const String16& clientPackageName, 39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int cameraId, 40edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int cameraFacing, 41edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int clientPid, 42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uid_t clientUid, 43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int servicePid) : 4420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Camera2ClientBase(cameraService, remoteCallback, clientPackageName, 4520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian cameraId, cameraFacing, clientPid, clientUid, servicePid) 46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 4717b2ad027b4b72b96dfb663c0ea001972da7ef58Mathias Agopian ATRACE_CALL(); 4817b2ad027b4b72b96dfb663c0ea001972da7ef58Mathias Agopian ALOGI("ProCamera %d: Opened", cameraId); 49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 509f96145725ff3f265712d607d19078fb91a5c8ecMathias Agopian mExclusiveLock = false; 519f96145725ff3f265712d607d19078fb91a5c8ecMathias Agopian} 529f96145725ff3f265712d607d19078fb91a5c8ecMathias Agopian 53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t ProCamera2Client::initialize(camera_module_t *module) 54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 550926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian ATRACE_CALL(); 56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project status_t res; 57edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 58b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain Guy res = Camera2ClientBase::initialize(module); 59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (res != OK) { 6020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return res; 61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 62edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String8 threadName; 64b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain Guy mFrameProcessor = new FrameProcessorBase(mDevice); 65edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project threadName = String8::format("PC2-%d-FrameProc", mCameraId); 66edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFrameProcessor->run(threadName.string()); 67edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 6820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian mFrameProcessor->registerListener(FRAME_PROCESSOR_LISTENER_MIN_ID, 69bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopian FRAME_PROCESSOR_LISTENER_MAX_ID, 70b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain Guy /*listener*/this); 71bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopian 72bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopian return OK; 73edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 74edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 75bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias AgopianProCamera2Client::~ProCamera2Client() { 76b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain Guy} 77bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopian 78bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopianstatus_t ProCamera2Client::exclusiveTryLock() { 79edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ATRACE_CALL(); 80edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ALOGV("%s", __FUNCTION__); 8120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 8220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Mutex::Autolock icl(mBinderSerializationLock); 83b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain Guy SharedCameraCallbacks::Lock l(mSharedCameraCallbacks); 8420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 8520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (!mDevice.get()) return PERMISSION_DENIED; 8620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 8720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (!mExclusiveLock) { 88bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopian mExclusiveLock = true; 89bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopian 90b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain Guy if (mRemoteCallback != NULL) { 91bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopian mRemoteCallback->onLockStatusChanged( 92bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopian IProCameraCallbacks::LOCK_ACQUIRED); 93edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 94edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 95bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopian ALOGV("%s: exclusive lock acquired", __FUNCTION__); 96b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain Guy 97bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopian return OK; 98bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopian } 99bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopian 100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // TODO: have a PERMISSION_DENIED case for when someone else owns the lock 101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 102b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain Guy // don't allow recursive locking 103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ALOGW("%s: exclusive lock already exists - recursive locking is not" 104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "allowed", __FUNCTION__); 105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return ALREADY_EXISTS; 10720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 10820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 10920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopianstatus_t ProCamera2Client::exclusiveLock() { 11020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian ATRACE_CALL(); 11120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian ALOGV("%s", __FUNCTION__); 11220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 11320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Mutex::Autolock icl(mBinderSerializationLock); 11420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian SharedCameraCallbacks::Lock l(mSharedCameraCallbacks); 11520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 11620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (!mDevice.get()) return PERMISSION_DENIED; 11720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 11820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian /** 119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * TODO: this should asynchronously 'wait' until the lock becomes available 12020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian * if another client already has an exclusive lock. 12120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian * 12220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian * once we have proper sharing support this will need to do 12320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian * more than just return immediately 124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (!mExclusiveLock) { 126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mExclusiveLock = true; 127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mRemoteCallback != NULL) { 129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mRemoteCallback->onLockStatusChanged(IProCameraCallbacks::LOCK_ACQUIRED); 130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ALOGV("%s: exclusive lock acquired", __FUNCTION__); 133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return OK; 135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 13620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 13720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian // don't allow recursive locking 13820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian ALOGW("%s: exclusive lock already exists - recursive locking is not allowed" 13920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian , __FUNCTION__); 14020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return ALREADY_EXISTS; 14120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 142bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopian 143bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopianstatus_t ProCamera2Client::exclusiveUnlock() { 144bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopian ATRACE_CALL(); 14520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian ALOGV("%s", __FUNCTION__); 14620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 14720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Mutex::Autolock icl(mBinderSerializationLock); 14820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian SharedCameraCallbacks::Lock l(mSharedCameraCallbacks); 14920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 15020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian // don't allow unlocking if we have no lock 15120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (!mExclusiveLock) { 15220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian ALOGW("%s: cannot unlock, no lock was held in the first place", 15320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian __FUNCTION__); 15420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return BAD_VALUE; 15520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 15620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 15720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian mExclusiveLock = false; 15820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (mRemoteCallback != NULL ) { 15920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian mRemoteCallback->onLockStatusChanged( 16020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian IProCameraCallbacks::LOCK_RELEASED); 16120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 16220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian ALOGV("%s: exclusive lock released", __FUNCTION__); 163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return OK; 165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 166bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopian 167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool ProCamera2Client::hasExclusiveLock() { 168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock icl(mBinderSerializationLock); 169b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain Guy return mExclusiveLock; 170b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain Guy} 171b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain Guy 172bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopianvoid ProCamera2Client::onExclusiveLockStolen() { 173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ALOGV("%s: ProClient lost exclusivity (id %d)", 174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project __FUNCTION__, mCameraId); 175bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopian 176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock icl(mBinderSerializationLock); 177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project SharedCameraCallbacks::Lock l(mSharedCameraCallbacks); 178bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopian 179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mExclusiveLock && mRemoteCallback.get() != NULL) { 180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mRemoteCallback->onLockStatusChanged( 181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IProCameraCallbacks::LOCK_STOLEN); 182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mExclusiveLock = false; 185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 186b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain Guy //TODO: we should not need to detach the device, merely reset it. 187b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain Guy detachDevice(); 188b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain Guy} 189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t ProCamera2Client::submitRequest(camera_metadata_t* request, 191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project bool streaming) { 192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ATRACE_CALL(); 193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ALOGV("%s", __FUNCTION__); 194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock icl(mBinderSerializationLock); 196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (!mDevice.get()) return DEAD_OBJECT; 198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (!mExclusiveLock) { 200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return PERMISSION_DENIED; 201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 203 CameraMetadata metadata(request); 204 205 if (!enforceRequestPermissions(metadata)) { 206 return PERMISSION_DENIED; 207 } 208 209 if (streaming) { 210 return mDevice->setStreamingRequest(metadata); 211 } else { 212 return mDevice->capture(metadata); 213 } 214 215 // unreachable. thx gcc for a useless warning 216 return OK; 217} 218 219status_t ProCamera2Client::cancelRequest(int requestId) { 220 (void)requestId; 221 ATRACE_CALL(); 222 ALOGV("%s", __FUNCTION__); 223 224 Mutex::Autolock icl(mBinderSerializationLock); 225 226 if (!mDevice.get()) return DEAD_OBJECT; 227 228 if (!mExclusiveLock) { 229 return PERMISSION_DENIED; 230 } 231 232 // TODO: implement 233 ALOGE("%s: not fully implemented yet", __FUNCTION__); 234 return INVALID_OPERATION; 235} 236 237status_t ProCamera2Client::deleteStream(int streamId) { 238 ATRACE_CALL(); 239 ALOGV("%s (streamId = 0x%x)", __FUNCTION__, streamId); 240 241 status_t res; 242 if ( (res = checkPid(__FUNCTION__) ) != OK) return res; 243 244 Mutex::Autolock icl(mBinderSerializationLock); 245 246 if (!mDevice.get()) return DEAD_OBJECT; 247 mDevice->clearStreamingRequest(); 248 249 status_t code; 250 if ((code = mDevice->waitUntilDrained()) != OK) { 251 ALOGE("%s: waitUntilDrained failed with code 0x%x", __FUNCTION__, code); 252 } 253 254 return mDevice->deleteStream(streamId); 255} 256 257status_t ProCamera2Client::createStream(int width, int height, int format, 258 const sp<IGraphicBufferProducer>& bufferProducer, 259 /*out*/ 260 int* streamId) 261{ 262 if (streamId) { 263 *streamId = -1; 264 } 265 266 ATRACE_CALL(); 267 ALOGV("%s (w = %d, h = %d, f = 0x%x)", __FUNCTION__, width, height, format); 268 269 status_t res; 270 if ( (res = checkPid(__FUNCTION__) ) != OK) return res; 271 272 Mutex::Autolock icl(mBinderSerializationLock); 273 274 if (!mDevice.get()) return DEAD_OBJECT; 275 276 sp<IBinder> binder; 277 sp<ANativeWindow> window; 278 if (bufferProducer != 0) { 279 binder = bufferProducer->asBinder(); 280 window = new Surface(bufferProducer); 281 } 282 283 return mDevice->createStream(window, width, height, format, /*size*/1, 284 streamId); 285} 286 287// Create a request object from a template. 288// -- Caller owns the newly allocated metadata 289status_t ProCamera2Client::createDefaultRequest(int templateId, 290 /*out*/ 291 camera_metadata** request) 292{ 293 ATRACE_CALL(); 294 ALOGV("%s (templateId = 0x%x)", __FUNCTION__, templateId); 295 296 if (request) { 297 *request = NULL; 298 } 299 300 status_t res; 301 if ( (res = checkPid(__FUNCTION__) ) != OK) return res; 302 303 Mutex::Autolock icl(mBinderSerializationLock); 304 305 if (!mDevice.get()) return DEAD_OBJECT; 306 307 CameraMetadata metadata; 308 if ( (res = mDevice->createDefaultRequest(templateId, &metadata) ) == OK) { 309 *request = metadata.release(); 310 } 311 312 return res; 313} 314 315status_t ProCamera2Client::getCameraInfo(int cameraId, 316 /*out*/ 317 camera_metadata** info) 318{ 319 if (cameraId != mCameraId) { 320 return INVALID_OPERATION; 321 } 322 323 Mutex::Autolock icl(mBinderSerializationLock); 324 325 if (!mDevice.get()) return DEAD_OBJECT; 326 327 CameraMetadata deviceInfo = mDevice->info(); 328 *info = deviceInfo.release(); 329 330 return OK; 331} 332 333status_t ProCamera2Client::dump(int fd, const Vector<String16>& args) { 334 String8 result; 335 result.appendFormat("ProCamera2Client[%d] (%p) PID: %d, dump:\n", 336 mCameraId, 337 getRemoteCallback()->asBinder().get(), 338 mClientPid); 339 result.append(" State: "); 340 341 // TODO: print dynamic/request section from most recent requests 342 mFrameProcessor->dump(fd, args); 343 344 return dumpDevice(fd, args); 345} 346 347// IProCameraUser interface 348 349void ProCamera2Client::detachDevice() { 350 if (mDevice == 0) return; 351 352 ALOGV("Camera %d: Stopping processors", mCameraId); 353 354 mFrameProcessor->removeListener(FRAME_PROCESSOR_LISTENER_MIN_ID, 355 FRAME_PROCESSOR_LISTENER_MAX_ID, 356 /*listener*/this); 357 mFrameProcessor->requestExit(); 358 ALOGV("Camera %d: Waiting for threads", mCameraId); 359 mFrameProcessor->join(); 360 ALOGV("Camera %d: Disconnecting device", mCameraId); 361 362 // WORKAROUND: HAL refuses to disconnect while there's streams in flight 363 { 364 mDevice->clearStreamingRequest(); 365 366 status_t code; 367 if ((code = mDevice->waitUntilDrained()) != OK) { 368 ALOGE("%s: waitUntilDrained failed with code 0x%x", __FUNCTION__, 369 code); 370 } 371 } 372 373 Camera2ClientBase::detachDevice(); 374} 375 376/** Device-related methods */ 377void ProCamera2Client::onFrameAvailable(int32_t frameId, 378 const CameraMetadata& frame) { 379 ATRACE_CALL(); 380 ALOGV("%s", __FUNCTION__); 381 382 Mutex::Autolock icl(mBinderSerializationLock); 383 SharedCameraCallbacks::Lock l(mSharedCameraCallbacks); 384 385 if (mRemoteCallback != NULL) { 386 CameraMetadata tmp(frame); 387 camera_metadata_t* meta = tmp.release(); 388 ALOGV("%s: meta = %p ", __FUNCTION__, meta); 389 mRemoteCallback->onResultReceived(frameId, meta); 390 tmp.acquire(meta); 391 } 392 393} 394 395bool ProCamera2Client::enforceRequestPermissions(CameraMetadata& metadata) { 396 397 const int pid = IPCThreadState::self()->getCallingPid(); 398 const int selfPid = getpid(); 399 camera_metadata_entry_t entry; 400 401 /** 402 * Mixin default important security values 403 * - android.led.transmit = defaulted ON 404 */ 405 CameraMetadata staticInfo = mDevice->info(); 406 entry = staticInfo.find(ANDROID_LED_AVAILABLE_LEDS); 407 for(size_t i = 0; i < entry.count; ++i) { 408 uint8_t led = entry.data.u8[i]; 409 410 switch(led) { 411 case ANDROID_LED_AVAILABLE_LEDS_TRANSMIT: { 412 uint8_t transmitDefault = ANDROID_LED_TRANSMIT_ON; 413 if (!metadata.exists(ANDROID_LED_TRANSMIT)) { 414 metadata.update(ANDROID_LED_TRANSMIT, 415 &transmitDefault, 1); 416 } 417 break; 418 } 419 } 420 } 421 422 // We can do anything! 423 if (pid == selfPid) { 424 return true; 425 } 426 427 /** 428 * Permission check special fields in the request 429 * - android.led.transmit = android.permission.CAMERA_DISABLE_TRANSMIT 430 */ 431 entry = metadata.find(ANDROID_LED_TRANSMIT); 432 if (entry.count > 0 && entry.data.u8[0] != ANDROID_LED_TRANSMIT_ON) { 433 String16 permissionString = 434 String16("android.permission.CAMERA_DISABLE_TRANSMIT_LED"); 435 if (!checkCallingPermission(permissionString)) { 436 const int uid = IPCThreadState::self()->getCallingUid(); 437 ALOGE("Permission Denial: " 438 "can't disable transmit LED pid=%d, uid=%d", pid, uid); 439 return false; 440 } 441 } 442 443 return true; 444} 445 446} // namespace android 447