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