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     res = mDevice->setNotifyCallback(this);
    108 
    109     return OK;
    110 }
    111 
    112 template <typename TClientBase>
    113 Camera2ClientBase<TClientBase>::~Camera2ClientBase() {
    114     ATRACE_CALL();
    115 
    116     TClientBase::mDestructionStarted = true;
    117 
    118     disconnect();
    119 
    120     ALOGI("Closed Camera %d. Client was: %s (PID %d, UID %u)",
    121             TClientBase::mCameraId,
    122             String8(TClientBase::mClientPackageName).string(),
    123             mInitialClientPid, TClientBase::mClientUid);
    124 }
    125 
    126 template <typename TClientBase>
    127 status_t Camera2ClientBase<TClientBase>::dumpClient(int fd,
    128                                               const Vector<String16>& args) {
    129     String8 result;
    130     result.appendFormat("Camera2ClientBase[%d] (%p) PID: %d, dump:\n",
    131             TClientBase::mCameraId,
    132             (TClientBase::getRemoteCallback() != NULL ?
    133                     IInterface::asBinder(TClientBase::getRemoteCallback()).get() : NULL),
    134             TClientBase::mClientPid);
    135     result.append("  State: ");
    136 
    137     write(fd, result.string(), result.size());
    138     // TODO: print dynamic/request section from most recent requests
    139 
    140     return dumpDevice(fd, args);
    141 }
    142 
    143 template <typename TClientBase>
    144 status_t Camera2ClientBase<TClientBase>::dumpDevice(
    145                                                 int fd,
    146                                                 const Vector<String16>& args) {
    147     String8 result;
    148 
    149     result = "  Device dump:\n";
    150     write(fd, result.string(), result.size());
    151 
    152     if (!mDevice.get()) {
    153         result = "  *** Device is detached\n";
    154         write(fd, result.string(), result.size());
    155         return NO_ERROR;
    156     }
    157 
    158     status_t res = mDevice->dump(fd, args);
    159     if (res != OK) {
    160         result = String8::format("   Error dumping device: %s (%d)",
    161                 strerror(-res), res);
    162         write(fd, result.string(), result.size());
    163     }
    164 
    165     return NO_ERROR;
    166 }
    167 
    168 // ICameraClient2BaseUser interface
    169 
    170 
    171 template <typename TClientBase>
    172 binder::Status Camera2ClientBase<TClientBase>::disconnect() {
    173     ATRACE_CALL();
    174     Mutex::Autolock icl(mBinderSerializationLock);
    175 
    176     binder::Status res = binder::Status::ok();
    177     // Allow both client and the media server to disconnect at all times
    178     int callingPid = getCallingPid();
    179     if (callingPid != TClientBase::mClientPid &&
    180         callingPid != TClientBase::mServicePid) return res;
    181 
    182     ALOGV("Camera %d: Shutting down", TClientBase::mCameraId);
    183 
    184     detachDevice();
    185 
    186     CameraService::BasicClient::disconnect();
    187 
    188     ALOGV("Camera %d: Shut down complete complete", TClientBase::mCameraId);
    189 
    190     return res;
    191 }
    192 
    193 template <typename TClientBase>
    194 void Camera2ClientBase<TClientBase>::detachDevice() {
    195     if (mDevice == 0) return;
    196     mDevice->disconnect();
    197 
    198     mDevice.clear();
    199 
    200     ALOGV("Camera %d: Detach complete", TClientBase::mCameraId);
    201 }
    202 
    203 template <typename TClientBase>
    204 status_t Camera2ClientBase<TClientBase>::connect(
    205         const sp<TCamCallbacks>& client) {
    206     ATRACE_CALL();
    207     ALOGV("%s: E", __FUNCTION__);
    208     Mutex::Autolock icl(mBinderSerializationLock);
    209 
    210     if (TClientBase::mClientPid != 0 &&
    211         getCallingPid() != TClientBase::mClientPid) {
    212 
    213         ALOGE("%s: Camera %d: Connection attempt from pid %d; "
    214                 "current locked to pid %d",
    215                 __FUNCTION__,
    216                 TClientBase::mCameraId,
    217                 getCallingPid(),
    218                 TClientBase::mClientPid);
    219         return BAD_VALUE;
    220     }
    221 
    222     TClientBase::mClientPid = getCallingPid();
    223 
    224     TClientBase::mRemoteCallback = client;
    225     mSharedCameraCallbacks = client;
    226 
    227     return OK;
    228 }
    229 
    230 /** Device-related methods */
    231 
    232 template <typename TClientBase>
    233 void Camera2ClientBase<TClientBase>::notifyError(
    234         int32_t errorCode,
    235         const CaptureResultExtras& resultExtras) {
    236     ALOGE("Error condition %d reported by HAL, requestId %" PRId32, errorCode,
    237           resultExtras.requestId);
    238 }
    239 
    240 template <typename TClientBase>
    241 void Camera2ClientBase<TClientBase>::notifyIdle() {
    242     if (mDeviceActive) {
    243         getCameraService()->updateProxyDeviceState(
    244             ICameraServiceProxy::CAMERA_STATE_IDLE,
    245             String8::format("%d", TClientBase::mCameraId));
    246     }
    247     mDeviceActive = false;
    248 
    249     ALOGV("Camera device is now idle");
    250 }
    251 
    252 template <typename TClientBase>
    253 void Camera2ClientBase<TClientBase>::notifyShutter(const CaptureResultExtras& resultExtras,
    254                                                    nsecs_t timestamp) {
    255     (void)resultExtras;
    256     (void)timestamp;
    257 
    258     if (!mDeviceActive) {
    259         getCameraService()->updateProxyDeviceState(
    260             ICameraServiceProxy::CAMERA_STATE_ACTIVE,
    261             String8::format("%d", TClientBase::mCameraId));
    262     }
    263     mDeviceActive = true;
    264 
    265     ALOGV("%s: Shutter notification for request id %" PRId32 " at time %" PRId64,
    266             __FUNCTION__, resultExtras.requestId, timestamp);
    267 }
    268 
    269 template <typename TClientBase>
    270 void Camera2ClientBase<TClientBase>::notifyAutoFocus(uint8_t newState,
    271                                                      int triggerId) {
    272     (void)newState;
    273     (void)triggerId;
    274 
    275     ALOGV("%s: Autofocus state now %d, last trigger %d",
    276           __FUNCTION__, newState, triggerId);
    277 
    278 }
    279 
    280 template <typename TClientBase>
    281 void Camera2ClientBase<TClientBase>::notifyAutoExposure(uint8_t newState,
    282                                                         int triggerId) {
    283     (void)newState;
    284     (void)triggerId;
    285 
    286     ALOGV("%s: Autoexposure state now %d, last trigger %d",
    287             __FUNCTION__, newState, triggerId);
    288 }
    289 
    290 template <typename TClientBase>
    291 void Camera2ClientBase<TClientBase>::notifyAutoWhitebalance(uint8_t newState,
    292                                                             int triggerId) {
    293     (void)newState;
    294     (void)triggerId;
    295 
    296     ALOGV("%s: Auto-whitebalance state now %d, last trigger %d",
    297             __FUNCTION__, newState, triggerId);
    298 }
    299 
    300 template <typename TClientBase>
    301 void Camera2ClientBase<TClientBase>::notifyPrepared(int streamId) {
    302     (void)streamId;
    303 
    304     ALOGV("%s: Stream %d now prepared",
    305             __FUNCTION__, streamId);
    306 }
    307 
    308 template <typename TClientBase>
    309 void Camera2ClientBase<TClientBase>::notifyRepeatingRequestError(long lastFrameNumber) {
    310     (void)lastFrameNumber;
    311 
    312     ALOGV("%s: Repeating request was stopped. Last frame number is %ld",
    313             __FUNCTION__, lastFrameNumber);
    314 }
    315 
    316 template <typename TClientBase>
    317 int Camera2ClientBase<TClientBase>::getCameraId() const {
    318     return TClientBase::mCameraId;
    319 }
    320 
    321 template <typename TClientBase>
    322 int Camera2ClientBase<TClientBase>::getCameraDeviceVersion() const {
    323     return mDeviceVersion;
    324 }
    325 
    326 template <typename TClientBase>
    327 const sp<CameraDeviceBase>& Camera2ClientBase<TClientBase>::getCameraDevice() {
    328     return mDevice;
    329 }
    330 
    331 template <typename TClientBase>
    332 const sp<CameraService>& Camera2ClientBase<TClientBase>::getCameraService() {
    333     return TClientBase::mCameraService;
    334 }
    335 
    336 template <typename TClientBase>
    337 Camera2ClientBase<TClientBase>::SharedCameraCallbacks::Lock::Lock(
    338         SharedCameraCallbacks &client) :
    339 
    340         mRemoteCallback(client.mRemoteCallback),
    341         mSharedClient(client) {
    342 
    343     mSharedClient.mRemoteCallbackLock.lock();
    344 }
    345 
    346 template <typename TClientBase>
    347 Camera2ClientBase<TClientBase>::SharedCameraCallbacks::Lock::~Lock() {
    348     mSharedClient.mRemoteCallbackLock.unlock();
    349 }
    350 
    351 template <typename TClientBase>
    352 Camera2ClientBase<TClientBase>::SharedCameraCallbacks::SharedCameraCallbacks(
    353         const sp<TCamCallbacks>&client) :
    354 
    355         mRemoteCallback(client) {
    356 }
    357 
    358 template <typename TClientBase>
    359 typename Camera2ClientBase<TClientBase>::SharedCameraCallbacks&
    360 Camera2ClientBase<TClientBase>::SharedCameraCallbacks::operator=(
    361         const sp<TCamCallbacks>&client) {
    362 
    363     Mutex::Autolock l(mRemoteCallbackLock);
    364     mRemoteCallback = client;
    365     return *this;
    366 }
    367 
    368 template <typename TClientBase>
    369 void Camera2ClientBase<TClientBase>::SharedCameraCallbacks::clear() {
    370     Mutex::Autolock l(mRemoteCallbackLock);
    371     mRemoteCallback.clear();
    372 }
    373 
    374 template class Camera2ClientBase<CameraService::Client>;
    375 template class Camera2ClientBase<CameraDeviceClientBase>;
    376 
    377 } // namespace android
    378