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