Home | History | Annotate | Download | only in common
      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 "Camera2ClientBase"
     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 "common/Camera2ClientBase.h"
     29 
     30 #include "api2/CameraDeviceClient.h"
     31 
     32 #include "CameraDeviceFactory.h"
     33 
     34 namespace android {
     35 using namespace camera2;
     36 
     37 static int getCallingPid() {
     38     return IPCThreadState::self()->getCallingPid();
     39 }
     40 
     41 // Interface used by CameraService
     42 
     43 template <typename TClientBase>
     44 Camera2ClientBase<TClientBase>::Camera2ClientBase(
     45         const sp<CameraService>& cameraService,
     46         const sp<TCamCallbacks>& remoteCallback,
     47         const String16& clientPackageName,
     48         int cameraId,
     49         int cameraFacing,
     50         int clientPid,
     51         uid_t clientUid,
     52         int servicePid):
     53         TClientBase(cameraService, remoteCallback, clientPackageName,
     54                 cameraId, cameraFacing, clientPid, clientUid, servicePid),
     55         mSharedCameraCallbacks(remoteCallback)
     56 {
     57     ALOGI("Camera %d: Opened", cameraId);
     58 
     59     mDevice = CameraDeviceFactory::createDevice(cameraId);
     60     LOG_ALWAYS_FATAL_IF(mDevice == 0, "Device should never be NULL here.");
     61 }
     62 
     63 template <typename TClientBase>
     64 status_t Camera2ClientBase<TClientBase>::checkPid(const char* checkLocation)
     65         const {
     66 
     67     int callingPid = getCallingPid();
     68     if (callingPid == TClientBase::mClientPid) return NO_ERROR;
     69 
     70     ALOGE("%s: attempt to use a locked camera from a different process"
     71             " (old pid %d, new pid %d)", checkLocation, TClientBase::mClientPid, callingPid);
     72     return PERMISSION_DENIED;
     73 }
     74 
     75 template <typename TClientBase>
     76 status_t Camera2ClientBase<TClientBase>::initialize(camera_module_t *module) {
     77     ATRACE_CALL();
     78     ALOGV("%s: Initializing client for camera %d", __FUNCTION__,
     79           TClientBase::mCameraId);
     80     status_t res;
     81 
     82     // Verify ops permissions
     83     res = TClientBase::startCameraOps();
     84     if (res != OK) {
     85         return res;
     86     }
     87 
     88     if (mDevice == NULL) {
     89         ALOGE("%s: Camera %d: No device connected",
     90                 __FUNCTION__, TClientBase::mCameraId);
     91         return NO_INIT;
     92     }
     93 
     94     res = mDevice->initialize(module);
     95     if (res != OK) {
     96         ALOGE("%s: Camera %d: unable to initialize device: %s (%d)",
     97                 __FUNCTION__, TClientBase::mCameraId, strerror(-res), res);
     98         return res;
     99     }
    100 
    101     res = mDevice->setNotifyCallback(this);
    102 
    103     return OK;
    104 }
    105 
    106 template <typename TClientBase>
    107 Camera2ClientBase<TClientBase>::~Camera2ClientBase() {
    108     ATRACE_CALL();
    109 
    110     TClientBase::mDestructionStarted = true;
    111 
    112     TClientBase::finishCameraOps();
    113 
    114     disconnect();
    115 
    116     ALOGI("Closed Camera %d", TClientBase::mCameraId);
    117 }
    118 
    119 template <typename TClientBase>
    120 status_t Camera2ClientBase<TClientBase>::dump(int fd,
    121                                               const Vector<String16>& args) {
    122     String8 result;
    123     result.appendFormat("Camera2ClientBase[%d] (%p) PID: %d, dump:\n",
    124             TClientBase::mCameraId,
    125             TClientBase::getRemoteCallback()->asBinder().get(),
    126             TClientBase::mClientPid);
    127     result.append("  State: ");
    128 
    129     write(fd, result.string(), result.size());
    130     // TODO: print dynamic/request section from most recent requests
    131 
    132     return dumpDevice(fd, args);
    133 }
    134 
    135 template <typename TClientBase>
    136 status_t Camera2ClientBase<TClientBase>::dumpDevice(
    137                                                 int fd,
    138                                                 const Vector<String16>& args) {
    139     String8 result;
    140 
    141     result = "  Device dump:\n";
    142     write(fd, result.string(), result.size());
    143 
    144     if (!mDevice.get()) {
    145         result = "  *** Device is detached\n";
    146         write(fd, result.string(), result.size());
    147         return NO_ERROR;
    148     }
    149 
    150     status_t res = mDevice->dump(fd, args);
    151     if (res != OK) {
    152         result = String8::format("   Error dumping device: %s (%d)",
    153                 strerror(-res), res);
    154         write(fd, result.string(), result.size());
    155     }
    156 
    157     return NO_ERROR;
    158 }
    159 
    160 // ICameraClient2BaseUser interface
    161 
    162 
    163 template <typename TClientBase>
    164 void Camera2ClientBase<TClientBase>::disconnect() {
    165     ATRACE_CALL();
    166     Mutex::Autolock icl(mBinderSerializationLock);
    167 
    168     // Allow both client and the media server to disconnect at all times
    169     int callingPid = getCallingPid();
    170     if (callingPid != TClientBase::mClientPid &&
    171         callingPid != TClientBase::mServicePid) return;
    172 
    173     ALOGV("Camera %d: Shutting down", TClientBase::mCameraId);
    174 
    175     detachDevice();
    176 
    177     CameraService::BasicClient::disconnect();
    178 
    179     ALOGV("Camera %d: Shut down complete complete", TClientBase::mCameraId);
    180 }
    181 
    182 template <typename TClientBase>
    183 void Camera2ClientBase<TClientBase>::detachDevice() {
    184     if (mDevice == 0) return;
    185     mDevice->disconnect();
    186 
    187     mDevice.clear();
    188 
    189     ALOGV("Camera %d: Detach complete", TClientBase::mCameraId);
    190 }
    191 
    192 template <typename TClientBase>
    193 status_t Camera2ClientBase<TClientBase>::connect(
    194         const sp<TCamCallbacks>& client) {
    195     ATRACE_CALL();
    196     ALOGV("%s: E", __FUNCTION__);
    197     Mutex::Autolock icl(mBinderSerializationLock);
    198 
    199     if (TClientBase::mClientPid != 0 &&
    200         getCallingPid() != TClientBase::mClientPid) {
    201 
    202         ALOGE("%s: Camera %d: Connection attempt from pid %d; "
    203                 "current locked to pid %d",
    204                 __FUNCTION__,
    205                 TClientBase::mCameraId,
    206                 getCallingPid(),
    207                 TClientBase::mClientPid);
    208         return BAD_VALUE;
    209     }
    210 
    211     TClientBase::mClientPid = getCallingPid();
    212 
    213     TClientBase::mRemoteCallback = client;
    214     mSharedCameraCallbacks = client;
    215 
    216     return OK;
    217 }
    218 
    219 /** Device-related methods */
    220 
    221 template <typename TClientBase>
    222 void Camera2ClientBase<TClientBase>::notifyError(int errorCode, int arg1,
    223                                                  int arg2) {
    224     ALOGE("Error condition %d reported by HAL, arguments %d, %d", errorCode,
    225           arg1, arg2);
    226 }
    227 
    228 template <typename TClientBase>
    229 void Camera2ClientBase<TClientBase>::notifyIdle() {
    230     ALOGV("Camera device is now idle");
    231 }
    232 
    233 template <typename TClientBase>
    234 void Camera2ClientBase<TClientBase>::notifyShutter(int requestId,
    235                                                    nsecs_t timestamp) {
    236     (void)requestId;
    237     (void)timestamp;
    238 
    239     ALOGV("%s: Shutter notification for request id %d at time %lld",
    240             __FUNCTION__, requestId, timestamp);
    241 }
    242 
    243 template <typename TClientBase>
    244 void Camera2ClientBase<TClientBase>::notifyAutoFocus(uint8_t newState,
    245                                                      int triggerId) {
    246     (void)newState;
    247     (void)triggerId;
    248 
    249     ALOGV("%s: Autofocus state now %d, last trigger %d",
    250           __FUNCTION__, newState, triggerId);
    251 
    252 }
    253 
    254 template <typename TClientBase>
    255 void Camera2ClientBase<TClientBase>::notifyAutoExposure(uint8_t newState,
    256                                                         int triggerId) {
    257     (void)newState;
    258     (void)triggerId;
    259 
    260     ALOGV("%s: Autoexposure state now %d, last trigger %d",
    261             __FUNCTION__, newState, triggerId);
    262 }
    263 
    264 template <typename TClientBase>
    265 void Camera2ClientBase<TClientBase>::notifyAutoWhitebalance(uint8_t newState,
    266                                                             int triggerId) {
    267     (void)newState;
    268     (void)triggerId;
    269 
    270     ALOGV("%s: Auto-whitebalance state now %d, last trigger %d",
    271             __FUNCTION__, newState, triggerId);
    272 }
    273 
    274 template <typename TClientBase>
    275 int Camera2ClientBase<TClientBase>::getCameraId() const {
    276     return TClientBase::mCameraId;
    277 }
    278 
    279 template <typename TClientBase>
    280 const sp<CameraDeviceBase>& Camera2ClientBase<TClientBase>::getCameraDevice() {
    281     return mDevice;
    282 }
    283 
    284 template <typename TClientBase>
    285 const sp<CameraService>& Camera2ClientBase<TClientBase>::getCameraService() {
    286     return TClientBase::mCameraService;
    287 }
    288 
    289 template <typename TClientBase>
    290 Camera2ClientBase<TClientBase>::SharedCameraCallbacks::Lock::Lock(
    291         SharedCameraCallbacks &client) :
    292 
    293         mRemoteCallback(client.mRemoteCallback),
    294         mSharedClient(client) {
    295 
    296     mSharedClient.mRemoteCallbackLock.lock();
    297 }
    298 
    299 template <typename TClientBase>
    300 Camera2ClientBase<TClientBase>::SharedCameraCallbacks::Lock::~Lock() {
    301     mSharedClient.mRemoteCallbackLock.unlock();
    302 }
    303 
    304 template <typename TClientBase>
    305 Camera2ClientBase<TClientBase>::SharedCameraCallbacks::SharedCameraCallbacks(
    306         const sp<TCamCallbacks>&client) :
    307 
    308         mRemoteCallback(client) {
    309 }
    310 
    311 template <typename TClientBase>
    312 typename Camera2ClientBase<TClientBase>::SharedCameraCallbacks&
    313 Camera2ClientBase<TClientBase>::SharedCameraCallbacks::operator=(
    314         const sp<TCamCallbacks>&client) {
    315 
    316     Mutex::Autolock l(mRemoteCallbackLock);
    317     mRemoteCallback = client;
    318     return *this;
    319 }
    320 
    321 template <typename TClientBase>
    322 void Camera2ClientBase<TClientBase>::SharedCameraCallbacks::clear() {
    323     Mutex::Autolock l(mRemoteCallbackLock);
    324     mRemoteCallback.clear();
    325 }
    326 
    327 template class Camera2ClientBase<CameraService::ProClient>;
    328 template class Camera2ClientBase<CameraService::Client>;
    329 template class Camera2ClientBase<CameraDeviceClientBase>;
    330 
    331 } // namespace android
    332