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