CameraBase.cpp revision 9efdf956cc2eef63fef609375901d6c8df6351b6
1/* 2** 3** Copyright (C) 2013, The Android Open Source Project 4** 5** Licensed under the Apache License, Version 2.0 (the "License"); 6** you may not use this file except in compliance with the License. 7** You may obtain a copy of the License at 8** 9** http://www.apache.org/licenses/LICENSE-2.0 10** 11** Unless required by applicable law or agreed to in writing, software 12** distributed under the License is distributed on an "AS IS" BASIS, 13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14** See the License for the specific language governing permissions and 15** limitations under the License. 16*/ 17 18//#define LOG_NDEBUG 0 19#define LOG_TAG "CameraBase" 20#include <utils/Log.h> 21#include <utils/threads.h> 22#include <utils/Mutex.h> 23 24#include <binder/IPCThreadState.h> 25#include <binder/IServiceManager.h> 26#include <binder/IMemory.h> 27 28#include <camera/CameraBase.h> 29#include <camera/ICameraService.h> 30 31// needed to instantiate 32#include <camera/Camera.h> 33 34#include <system/camera_metadata.h> 35 36namespace android { 37 38namespace { 39 sp<ICameraService> gCameraService; 40 const int kCameraServicePollDelay = 500000; // 0.5s 41 const char* kCameraServiceName = "media.camera"; 42 43 Mutex gLock; 44 45 class DeathNotifier : public IBinder::DeathRecipient 46 { 47 public: 48 DeathNotifier() { 49 } 50 51 virtual void binderDied(const wp<IBinder>& /*who*/) { 52 ALOGV("binderDied"); 53 Mutex::Autolock _l(gLock); 54 gCameraService.clear(); 55 ALOGW("Camera service died!"); 56 } 57 }; 58 59 sp<DeathNotifier> gDeathNotifier; 60}; // namespace anonymous 61 62/////////////////////////////////////////////////////////// 63// CameraBase definition 64/////////////////////////////////////////////////////////// 65 66// establish binder interface to camera service 67template <typename TCam, typename TCamTraits> 68const sp<ICameraService>& CameraBase<TCam, TCamTraits>::getCameraService() 69{ 70 Mutex::Autolock _l(gLock); 71 if (gCameraService.get() == 0) { 72 sp<IServiceManager> sm = defaultServiceManager(); 73 sp<IBinder> binder; 74 do { 75 binder = sm->getService(String16(kCameraServiceName)); 76 if (binder != 0) { 77 break; 78 } 79 ALOGW("CameraService not published, waiting..."); 80 usleep(kCameraServicePollDelay); 81 } while(true); 82 if (gDeathNotifier == NULL) { 83 gDeathNotifier = new DeathNotifier(); 84 } 85 binder->linkToDeath(gDeathNotifier); 86 gCameraService = interface_cast<ICameraService>(binder); 87 } 88 ALOGE_IF(gCameraService == 0, "no CameraService!?"); 89 return gCameraService; 90} 91 92template <typename TCam, typename TCamTraits> 93sp<TCam> CameraBase<TCam, TCamTraits>::connect(int cameraId, 94 const String16& clientPackageName, 95 int clientUid) 96{ 97 ALOGV("%s: connect", __FUNCTION__); 98 sp<TCam> c = new TCam(cameraId); 99 sp<TCamCallbacks> cl = c; 100 status_t status = NO_ERROR; 101 const sp<ICameraService>& cs = getCameraService(); 102 103 if (cs != 0) { 104 TCamConnectService fnConnectService = TCamTraits::fnConnectService; 105 status = (cs.get()->*fnConnectService)(cl, cameraId, clientPackageName, clientUid, 106 /*out*/ c->mCamera); 107 } 108 if (status == OK && c->mCamera != 0) { 109 IInterface::asBinder(c->mCamera)->linkToDeath(c); 110 c->mStatus = NO_ERROR; 111 } else { 112 ALOGW("An error occurred while connecting to camera: %d", cameraId); 113 c.clear(); 114 } 115 return c; 116} 117 118template <typename TCam, typename TCamTraits> 119void CameraBase<TCam, TCamTraits>::disconnect() 120{ 121 ALOGV("%s: disconnect", __FUNCTION__); 122 if (mCamera != 0) { 123 mCamera->disconnect(); 124 IInterface::asBinder(mCamera)->unlinkToDeath(this); 125 mCamera = 0; 126 } 127 ALOGV("%s: disconnect (done)", __FUNCTION__); 128} 129 130template <typename TCam, typename TCamTraits> 131CameraBase<TCam, TCamTraits>::CameraBase(int cameraId) : 132 mStatus(UNKNOWN_ERROR), 133 mCameraId(cameraId) 134{ 135} 136 137template <typename TCam, typename TCamTraits> 138CameraBase<TCam, TCamTraits>::~CameraBase() 139{ 140} 141 142template <typename TCam, typename TCamTraits> 143sp<typename TCamTraits::TCamUser> CameraBase<TCam, TCamTraits>::remote() 144{ 145 return mCamera; 146} 147 148template <typename TCam, typename TCamTraits> 149status_t CameraBase<TCam, TCamTraits>::getStatus() 150{ 151 return mStatus; 152} 153 154template <typename TCam, typename TCamTraits> 155void CameraBase<TCam, TCamTraits>::binderDied(const wp<IBinder>& /*who*/) { 156 ALOGW("mediaserver's remote binder Camera object died"); 157 notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_SERVER_DIED, /*ext2*/0); 158} 159 160template <typename TCam, typename TCamTraits> 161void CameraBase<TCam, TCamTraits>::setListener(const sp<TCamListener>& listener) 162{ 163 Mutex::Autolock _l(mLock); 164 mListener = listener; 165} 166 167// callback from camera service 168template <typename TCam, typename TCamTraits> 169void CameraBase<TCam, TCamTraits>::notifyCallback(int32_t msgType, 170 int32_t ext1, 171 int32_t ext2) 172{ 173 sp<TCamListener> listener; 174 { 175 Mutex::Autolock _l(mLock); 176 listener = mListener; 177 } 178 if (listener != NULL) { 179 listener->notify(msgType, ext1, ext2); 180 } 181} 182 183template <typename TCam, typename TCamTraits> 184int CameraBase<TCam, TCamTraits>::getNumberOfCameras() { 185 const sp<ICameraService> cs = getCameraService(); 186 187 if (!cs.get()) { 188 // as required by the public Java APIs 189 return 0; 190 } 191 return cs->getNumberOfCameras(); 192} 193 194// this can be in BaseCamera but it should be an instance method 195template <typename TCam, typename TCamTraits> 196status_t CameraBase<TCam, TCamTraits>::getCameraInfo(int cameraId, 197 struct CameraInfo* cameraInfo) { 198 const sp<ICameraService>& cs = getCameraService(); 199 if (cs == 0) return UNKNOWN_ERROR; 200 return cs->getCameraInfo(cameraId, cameraInfo); 201} 202 203template <typename TCam, typename TCamTraits> 204status_t CameraBase<TCam, TCamTraits>::addServiceListener( 205 const sp<ICameraServiceListener>& listener) { 206 const sp<ICameraService>& cs = getCameraService(); 207 if (cs == 0) return UNKNOWN_ERROR; 208 return cs->addListener(listener); 209} 210 211template <typename TCam, typename TCamTraits> 212status_t CameraBase<TCam, TCamTraits>::removeServiceListener( 213 const sp<ICameraServiceListener>& listener) { 214 const sp<ICameraService>& cs = getCameraService(); 215 if (cs == 0) return UNKNOWN_ERROR; 216 return cs->removeListener(listener); 217} 218 219template class CameraBase<Camera>; 220 221} // namespace android 222