Home | History | Annotate | Download | only in api_pro
      1 /*
      2  * Copyright (C) 2013 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #define LOG_TAG "ProCamera2Client"
     18 #define ATRACE_TAG ATRACE_TAG_CAMERA
     19 //#define LOG_NDEBUG 0
     20 
     21 #include <utils/Log.h>
     22 #include <utils/Trace.h>
     23 
     24 #include <cutils/properties.h>
     25 #include <gui/Surface.h>
     26 #include <gui/Surface.h>
     27 
     28 #include "api_pro/ProCamera2Client.h"
     29 #include "common/CameraDeviceBase.h"
     30 
     31 namespace android {
     32 using namespace camera2;
     33 
     34 // Interface used by CameraService
     35 
     36 ProCamera2Client::ProCamera2Client(const sp<CameraService>& cameraService,
     37                                    const sp<IProCameraCallbacks>& remoteCallback,
     38                                    const String16& clientPackageName,
     39                                    int cameraId,
     40                                    int cameraFacing,
     41                                    int clientPid,
     42                                    uid_t clientUid,
     43                                    int servicePid) :
     44     Camera2ClientBase(cameraService, remoteCallback, clientPackageName,
     45                 cameraId, cameraFacing, clientPid, clientUid, servicePid)
     46 {
     47     ATRACE_CALL();
     48     ALOGI("ProCamera %d: Opened", cameraId);
     49 
     50     mExclusiveLock = false;
     51 }
     52 
     53 status_t ProCamera2Client::initialize(camera_module_t *module)
     54 {
     55     ATRACE_CALL();
     56     status_t res;
     57 
     58     res = Camera2ClientBase::initialize(module);
     59     if (res != OK) {
     60         return res;
     61     }
     62 
     63     String8 threadName;
     64     mFrameProcessor = new FrameProcessorBase(mDevice);
     65     threadName = String8::format("PC2-%d-FrameProc", mCameraId);
     66     mFrameProcessor->run(threadName.string());
     67 
     68     mFrameProcessor->registerListener(FRAME_PROCESSOR_LISTENER_MIN_ID,
     69                                       FRAME_PROCESSOR_LISTENER_MAX_ID,
     70                                       /*listener*/this);
     71 
     72     return OK;
     73 }
     74 
     75 ProCamera2Client::~ProCamera2Client() {
     76 }
     77 
     78 status_t ProCamera2Client::exclusiveTryLock() {
     79     ATRACE_CALL();
     80     ALOGV("%s", __FUNCTION__);
     81 
     82     Mutex::Autolock icl(mBinderSerializationLock);
     83     SharedCameraCallbacks::Lock l(mSharedCameraCallbacks);
     84 
     85     if (!mDevice.get()) return PERMISSION_DENIED;
     86 
     87     if (!mExclusiveLock) {
     88         mExclusiveLock = true;
     89 
     90         if (mRemoteCallback != NULL) {
     91             mRemoteCallback->onLockStatusChanged(
     92                               IProCameraCallbacks::LOCK_ACQUIRED);
     93         }
     94 
     95         ALOGV("%s: exclusive lock acquired", __FUNCTION__);
     96 
     97         return OK;
     98     }
     99 
    100     // TODO: have a PERMISSION_DENIED case for when someone else owns the lock
    101 
    102     // don't allow recursive locking
    103     ALOGW("%s: exclusive lock already exists - recursive locking is not"
    104           "allowed", __FUNCTION__);
    105 
    106     return ALREADY_EXISTS;
    107 }
    108 
    109 status_t ProCamera2Client::exclusiveLock() {
    110     ATRACE_CALL();
    111     ALOGV("%s", __FUNCTION__);
    112 
    113     Mutex::Autolock icl(mBinderSerializationLock);
    114     SharedCameraCallbacks::Lock l(mSharedCameraCallbacks);
    115 
    116     if (!mDevice.get()) return PERMISSION_DENIED;
    117 
    118     /**
    119      * TODO: this should asynchronously 'wait' until the lock becomes available
    120      * if another client already has an exclusive lock.
    121      *
    122      * once we have proper sharing support this will need to do
    123      * more than just return immediately
    124      */
    125     if (!mExclusiveLock) {
    126         mExclusiveLock = true;
    127 
    128         if (mRemoteCallback != NULL) {
    129             mRemoteCallback->onLockStatusChanged(IProCameraCallbacks::LOCK_ACQUIRED);
    130         }
    131 
    132         ALOGV("%s: exclusive lock acquired", __FUNCTION__);
    133 
    134         return OK;
    135     }
    136 
    137     // don't allow recursive locking
    138     ALOGW("%s: exclusive lock already exists - recursive locking is not allowed"
    139                                                                 , __FUNCTION__);
    140     return ALREADY_EXISTS;
    141 }
    142 
    143 status_t ProCamera2Client::exclusiveUnlock() {
    144     ATRACE_CALL();
    145     ALOGV("%s", __FUNCTION__);
    146 
    147     Mutex::Autolock icl(mBinderSerializationLock);
    148     SharedCameraCallbacks::Lock l(mSharedCameraCallbacks);
    149 
    150     // don't allow unlocking if we have no lock
    151     if (!mExclusiveLock) {
    152         ALOGW("%s: cannot unlock, no lock was held in the first place",
    153               __FUNCTION__);
    154         return BAD_VALUE;
    155     }
    156 
    157     mExclusiveLock = false;
    158     if (mRemoteCallback != NULL ) {
    159         mRemoteCallback->onLockStatusChanged(
    160                                        IProCameraCallbacks::LOCK_RELEASED);
    161     }
    162     ALOGV("%s: exclusive lock released", __FUNCTION__);
    163 
    164     return OK;
    165 }
    166 
    167 bool ProCamera2Client::hasExclusiveLock() {
    168     Mutex::Autolock icl(mBinderSerializationLock);
    169     return mExclusiveLock;
    170 }
    171 
    172 void ProCamera2Client::onExclusiveLockStolen() {
    173     ALOGV("%s: ProClient lost exclusivity (id %d)",
    174           __FUNCTION__, mCameraId);
    175 
    176     Mutex::Autolock icl(mBinderSerializationLock);
    177     SharedCameraCallbacks::Lock l(mSharedCameraCallbacks);
    178 
    179     if (mExclusiveLock && mRemoteCallback.get() != NULL) {
    180         mRemoteCallback->onLockStatusChanged(
    181                                        IProCameraCallbacks::LOCK_STOLEN);
    182     }
    183 
    184     mExclusiveLock = false;
    185 
    186     //TODO: we should not need to detach the device, merely reset it.
    187     detachDevice();
    188 }
    189 
    190 status_t ProCamera2Client::submitRequest(camera_metadata_t* request,
    191                                          bool streaming) {
    192     ATRACE_CALL();
    193     ALOGV("%s", __FUNCTION__);
    194 
    195     Mutex::Autolock icl(mBinderSerializationLock);
    196 
    197     if (!mDevice.get()) return DEAD_OBJECT;
    198 
    199     if (!mExclusiveLock) {
    200         return PERMISSION_DENIED;
    201     }
    202 
    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 
    219 status_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 
    237 status_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 
    257 status_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,
    284                                  streamId);
    285 }
    286 
    287 // Create a request object from a template.
    288 // -- Caller owns the newly allocated metadata
    289 status_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 
    315 status_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 
    333 status_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:\n");
    340     write(fd, result.string(), result.size());
    341 
    342     // TODO: print dynamic/request section from most recent requests
    343     mFrameProcessor->dump(fd, args);
    344     return dumpDevice(fd, args);
    345 }
    346 
    347 // IProCameraUser interface
    348 
    349 void 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 void ProCamera2Client::onResultAvailable(const CaptureResult& result) {
    377     ATRACE_CALL();
    378     ALOGV("%s", __FUNCTION__);
    379 
    380     Mutex::Autolock icl(mBinderSerializationLock);
    381     SharedCameraCallbacks::Lock l(mSharedCameraCallbacks);
    382 
    383     if (mRemoteCallback != NULL) {
    384         CameraMetadata tmp(result.mMetadata);
    385         camera_metadata_t* meta = tmp.release();
    386         ALOGV("%s: meta = %p ", __FUNCTION__, meta);
    387         mRemoteCallback->onResultReceived(result.mResultExtras.requestId, meta);
    388         tmp.acquire(meta);
    389     }
    390 }
    391 
    392 bool ProCamera2Client::enforceRequestPermissions(CameraMetadata& metadata) {
    393 
    394     const int pid = IPCThreadState::self()->getCallingPid();
    395     const int selfPid = getpid();
    396     camera_metadata_entry_t entry;
    397 
    398     /**
    399      * Mixin default important security values
    400      * - android.led.transmit = defaulted ON
    401      */
    402     CameraMetadata staticInfo = mDevice->info();
    403     entry = staticInfo.find(ANDROID_LED_AVAILABLE_LEDS);
    404     for(size_t i = 0; i < entry.count; ++i) {
    405         uint8_t led = entry.data.u8[i];
    406 
    407         switch(led) {
    408             case ANDROID_LED_AVAILABLE_LEDS_TRANSMIT: {
    409                 uint8_t transmitDefault = ANDROID_LED_TRANSMIT_ON;
    410                 if (!metadata.exists(ANDROID_LED_TRANSMIT)) {
    411                     metadata.update(ANDROID_LED_TRANSMIT,
    412                                     &transmitDefault, 1);
    413                 }
    414                 break;
    415             }
    416         }
    417     }
    418 
    419     // We can do anything!
    420     if (pid == selfPid) {
    421         return true;
    422     }
    423 
    424     /**
    425      * Permission check special fields in the request
    426      * - android.led.transmit = android.permission.CAMERA_DISABLE_TRANSMIT
    427      */
    428     entry = metadata.find(ANDROID_LED_TRANSMIT);
    429     if (entry.count > 0 && entry.data.u8[0] != ANDROID_LED_TRANSMIT_ON) {
    430         String16 permissionString =
    431             String16("android.permission.CAMERA_DISABLE_TRANSMIT_LED");
    432         if (!checkCallingPermission(permissionString)) {
    433             const int uid = IPCThreadState::self()->getCallingUid();
    434             ALOGE("Permission Denial: "
    435                   "can't disable transmit LED pid=%d, uid=%d", pid, uid);
    436             return false;
    437         }
    438     }
    439 
    440     return true;
    441 }
    442 
    443 } // namespace android
    444