Home | History | Annotate | Download | only in libcameraservice
      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 #include "camera2/Parameters.h"
     28 #include "ProCamera2Client.h"
     29 #include "camera2/ProFrameProcessor.h"
     30 #include "CameraDeviceBase.h"
     31 
     32 namespace android {
     33 using namespace camera2;
     34 
     35 // Interface used by CameraService
     36 
     37 ProCamera2Client::ProCamera2Client(const sp<CameraService>& cameraService,
     38                                    const sp<IProCameraCallbacks>& remoteCallback,
     39                                    const String16& clientPackageName,
     40                                    int cameraId,
     41                                    int cameraFacing,
     42                                    int clientPid,
     43                                    uid_t clientUid,
     44                                    int servicePid) :
     45     Camera2ClientBase(cameraService, remoteCallback, clientPackageName,
     46                 cameraId, cameraFacing, clientPid, clientUid, servicePid)
     47 {
     48     ATRACE_CALL();
     49     ALOGI("ProCamera %d: Opened", cameraId);
     50 
     51     mExclusiveLock = false;
     52 }
     53 
     54 status_t ProCamera2Client::initialize(camera_module_t *module)
     55 {
     56     ATRACE_CALL();
     57     status_t res;
     58 
     59     res = Camera2ClientBase::initialize(module);
     60     if (res != OK) {
     61         return res;
     62     }
     63 
     64     String8 threadName;
     65     mFrameProcessor = new ProFrameProcessor(mDevice);
     66     threadName = String8::format("PC2-%d-FrameProc", mCameraId);
     67     mFrameProcessor->run(threadName.string());
     68 
     69     mFrameProcessor->registerListener(FRAME_PROCESSOR_LISTENER_MIN_ID,
     70                                       FRAME_PROCESSOR_LISTENER_MAX_ID,
     71                                       /*listener*/this);
     72 
     73     return OK;
     74 }
     75 
     76 ProCamera2Client::~ProCamera2Client() {
     77 }
     78 
     79 status_t ProCamera2Client::exclusiveTryLock() {
     80     ATRACE_CALL();
     81     ALOGV("%s", __FUNCTION__);
     82 
     83     Mutex::Autolock icl(mBinderSerializationLock);
     84     SharedCameraCallbacks::Lock l(mSharedCameraCallbacks);
     85 
     86     if (!mDevice.get()) return PERMISSION_DENIED;
     87 
     88     if (!mExclusiveLock) {
     89         mExclusiveLock = true;
     90 
     91         if (mRemoteCallback != NULL) {
     92             mRemoteCallback->onLockStatusChanged(
     93                               IProCameraCallbacks::LOCK_ACQUIRED);
     94         }
     95 
     96         ALOGV("%s: exclusive lock acquired", __FUNCTION__);
     97 
     98         return OK;
     99     }
    100 
    101     // TODO: have a PERMISSION_DENIED case for when someone else owns the lock
    102 
    103     // don't allow recursive locking
    104     ALOGW("%s: exclusive lock already exists - recursive locking is not"
    105           "allowed", __FUNCTION__);
    106 
    107     return ALREADY_EXISTS;
    108 }
    109 
    110 status_t ProCamera2Client::exclusiveLock() {
    111     ATRACE_CALL();
    112     ALOGV("%s", __FUNCTION__);
    113 
    114     Mutex::Autolock icl(mBinderSerializationLock);
    115     SharedCameraCallbacks::Lock l(mSharedCameraCallbacks);
    116 
    117     if (!mDevice.get()) return PERMISSION_DENIED;
    118 
    119     /**
    120      * TODO: this should asynchronously 'wait' until the lock becomes available
    121      * if another client already has an exclusive lock.
    122      *
    123      * once we have proper sharing support this will need to do
    124      * more than just return immediately
    125      */
    126     if (!mExclusiveLock) {
    127         mExclusiveLock = true;
    128 
    129         if (mRemoteCallback != NULL) {
    130             mRemoteCallback->onLockStatusChanged(IProCameraCallbacks::LOCK_ACQUIRED);
    131         }
    132 
    133         ALOGV("%s: exclusive lock acquired", __FUNCTION__);
    134 
    135         return OK;
    136     }
    137 
    138     // don't allow recursive locking
    139     ALOGW("%s: exclusive lock already exists - recursive locking is not allowed"
    140                                                                 , __FUNCTION__);
    141     return ALREADY_EXISTS;
    142 }
    143 
    144 status_t ProCamera2Client::exclusiveUnlock() {
    145     ATRACE_CALL();
    146     ALOGV("%s", __FUNCTION__);
    147 
    148     Mutex::Autolock icl(mBinderSerializationLock);
    149     SharedCameraCallbacks::Lock l(mSharedCameraCallbacks);
    150 
    151     // don't allow unlocking if we have no lock
    152     if (!mExclusiveLock) {
    153         ALOGW("%s: cannot unlock, no lock was held in the first place",
    154               __FUNCTION__);
    155         return BAD_VALUE;
    156     }
    157 
    158     mExclusiveLock = false;
    159     if (mRemoteCallback != NULL ) {
    160         mRemoteCallback->onLockStatusChanged(
    161                                        IProCameraCallbacks::LOCK_RELEASED);
    162     }
    163     ALOGV("%s: exclusive lock released", __FUNCTION__);
    164 
    165     return OK;
    166 }
    167 
    168 bool ProCamera2Client::hasExclusiveLock() {
    169     Mutex::Autolock icl(mBinderSerializationLock);
    170     return mExclusiveLock;
    171 }
    172 
    173 void ProCamera2Client::onExclusiveLockStolen() {
    174     ALOGV("%s: ProClient lost exclusivity (id %d)",
    175           __FUNCTION__, mCameraId);
    176 
    177     Mutex::Autolock icl(mBinderSerializationLock);
    178     SharedCameraCallbacks::Lock l(mSharedCameraCallbacks);
    179 
    180     if (mExclusiveLock && mRemoteCallback.get() != NULL) {
    181         mRemoteCallback->onLockStatusChanged(
    182                                        IProCameraCallbacks::LOCK_STOLEN);
    183     }
    184 
    185     mExclusiveLock = false;
    186 
    187     //TODO: we should not need to detach the device, merely reset it.
    188     detachDevice();
    189 }
    190 
    191 status_t ProCamera2Client::submitRequest(camera_metadata_t* request,
    192                                          bool streaming) {
    193     ATRACE_CALL();
    194     ALOGV("%s", __FUNCTION__);
    195 
    196     Mutex::Autolock icl(mBinderSerializationLock);
    197 
    198     if (!mDevice.get()) return DEAD_OBJECT;
    199 
    200     if (!mExclusiveLock) {
    201         return PERMISSION_DENIED;
    202     }
    203 
    204     CameraMetadata metadata(request);
    205 
    206     if (!enforceRequestPermissions(metadata)) {
    207         return PERMISSION_DENIED;
    208     }
    209 
    210     if (streaming) {
    211         return mDevice->setStreamingRequest(metadata);
    212     } else {
    213         return mDevice->capture(metadata);
    214     }
    215 
    216     // unreachable. thx gcc for a useless warning
    217     return OK;
    218 }
    219 
    220 status_t ProCamera2Client::cancelRequest(int 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, /*size*/1,
    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: ");
    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 
    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 /** Device-related methods */
    377 void 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 
    395 bool 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