diff options
Diffstat (limited to 'services/camera/libcameraservice/CameraService.h')
-rw-r--r-- | services/camera/libcameraservice/CameraService.h | 256 |
1 files changed, 225 insertions, 31 deletions
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h index 4dab340..710f164 100644 --- a/services/camera/libcameraservice/CameraService.h +++ b/services/camera/libcameraservice/CameraService.h @@ -18,10 +18,20 @@ #ifndef ANDROID_SERVERS_CAMERA_CAMERASERVICE_H #define ANDROID_SERVERS_CAMERA_CAMERASERVICE_H +#include <utils/Vector.h> +#include <binder/AppOpsManager.h> #include <binder/BinderService.h> +#include <binder/IAppOpsCallback.h> #include <camera/ICameraService.h> #include <hardware/camera.h> +#include <camera/ICamera.h> +#include <camera/ICameraClient.h> +#include <camera/IProCameraUser.h> +#include <camera/IProCameraCallbacks.h> + +#include <camera/ICameraServiceListener.h> + /* This needs to be increased if we can have more cameras */ #define MAX_CAMERAS 2 @@ -35,32 +45,49 @@ class MediaPlayer; class CameraService : public BinderService<CameraService>, public BnCameraService, - public IBinder::DeathRecipient + public IBinder::DeathRecipient, + public camera_module_callbacks_t { friend class BinderService<CameraService>; public: class Client; + class BasicClient; + + // Implementation of BinderService<T> static char const* getServiceName() { return "media.camera"; } CameraService(); virtual ~CameraService(); + ///////////////////////////////////////////////////////////////////// + // HAL Callbacks + virtual void onDeviceStatusChanged(int cameraId, + int newStatus); + + ///////////////////////////////////////////////////////////////////// + // ICameraService virtual int32_t getNumberOfCameras(); virtual status_t getCameraInfo(int cameraId, struct CameraInfo* cameraInfo); - virtual sp<ICamera> connect(const sp<ICameraClient>& cameraClient, int cameraId); - virtual void removeClient(const sp<ICameraClient>& cameraClient); - // returns plain pointer of client. Note that mClientLock should be acquired to - // prevent the client from destruction. The result can be NULL. - virtual Client* getClientByIdUnsafe(int cameraId); - virtual Mutex* getClientLockById(int cameraId); - virtual sp<Client> getClientByRemote(const wp<IBinder>& cameraClient); + virtual sp<ICamera> connect(const sp<ICameraClient>& cameraClient, int cameraId, + const String16& clientPackageName, int clientUid); + virtual sp<IProCameraUser> connect(const sp<IProCameraCallbacks>& cameraCb, + int cameraId, const String16& clientPackageName, int clientUid); - virtual status_t dump(int fd, const Vector<String16>& args); + virtual status_t addListener(const sp<ICameraServiceListener>& listener); + virtual status_t removeListener( + const sp<ICameraServiceListener>& listener); + + // Extra permissions checks virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags); - virtual void onFirstRef(); + + virtual status_t dump(int fd, const Vector<String16>& args); + + ///////////////////////////////////////////////////////////////////// + // Client functionality + virtual void removeClientByRemote(const wp<IBinder>& remoteBinder); enum sound_kind { SOUND_SHUTTER = 0, @@ -72,16 +99,96 @@ public: void playSound(sound_kind kind); void releaseSound(); - class Client : public BnCamera + + ///////////////////////////////////////////////////////////////////// + // CameraClient functionality + + // returns plain pointer of client. Note that mClientLock should be acquired to + // prevent the client from destruction. The result can be NULL. + virtual Client* getClientByIdUnsafe(int cameraId); + virtual Mutex* getClientLockById(int cameraId); + + class BasicClient : public virtual RefBase { + public: + virtual status_t initialize(camera_module_t *module) = 0; + + virtual void disconnect() = 0; + + // Return the remote callback binder object (e.g. IProCameraCallbacks) + wp<IBinder> getRemote() { + return mRemoteBinder; + } + + protected: + BasicClient(const sp<CameraService>& cameraService, + const sp<IBinder>& remoteCallback, + const String16& clientPackageName, + int cameraId, + int cameraFacing, + int clientPid, + uid_t clientUid, + int servicePid); + + virtual ~BasicClient(); + + // the instance is in the middle of destruction. When this is set, + // the instance should not be accessed from callback. + // CameraService's mClientLock should be acquired to access this. + // - subclasses should set this to true in their destructors. + bool mDestructionStarted; + + // these are initialized in the constructor. + sp<CameraService> mCameraService; // immutable after constructor + int mCameraId; // immutable after constructor + int mCameraFacing; // immutable after constructor + const String16 mClientPackageName; + pid_t mClientPid; + uid_t mClientUid; // immutable after constructor + pid_t mServicePid; // immutable after constructor + + // - The app-side Binder interface to receive callbacks from us + wp<IBinder> mRemoteBinder; // immutable after constructor + + // permissions management + status_t startCameraOps(); + status_t finishCameraOps(); + + // Notify client about a fatal error + virtual void notifyError() = 0; + private: + AppOpsManager mAppOpsManager; + + class OpsCallback : public BnAppOpsCallback { + public: + OpsCallback(wp<BasicClient> client); + virtual void opChanged(int32_t op, const String16& packageName); + + private: + wp<BasicClient> mClient; + + }; // class OpsCallback + + sp<OpsCallback> mOpsCallback; + // Track whether startCameraOps was called successfully, to avoid + // finishing what we didn't start. + bool mOpsActive; + + // IAppOpsCallback interface, indirected through opListener + virtual void opChanged(int32_t op, const String16& packageName); + }; // class BasicClient + + class Client : public BnCamera, public BasicClient { public: + typedef ICameraClient TCamCallbacks; + // ICamera interface (see ICamera for details) virtual void disconnect(); virtual status_t connect(const sp<ICameraClient>& client) = 0; virtual status_t lock() = 0; virtual status_t unlock() = 0; virtual status_t setPreviewDisplay(const sp<Surface>& surface) = 0; - virtual status_t setPreviewTexture(const sp<ISurfaceTexture>& surfaceTexture) = 0; + virtual status_t setPreviewTexture(const sp<IGraphicBufferProducer>& bufferProducer)=0; virtual void setPreviewCallbackFlag(int flag) = 0; virtual status_t startPreview() = 0; virtual void stopPreview() = 0; @@ -101,49 +208,112 @@ public: // Interface used by CameraService Client(const sp<CameraService>& cameraService, const sp<ICameraClient>& cameraClient, + const String16& clientPackageName, int cameraId, int cameraFacing, int clientPid, + uid_t clientUid, int servicePid); ~Client(); // return our camera client - const sp<ICameraClient>& getCameraClient() { - return mCameraClient; + const sp<ICameraClient>& getRemoteCallback() { + return mRemoteCallback; } - virtual status_t initialize(camera_module_t *module) = 0; - - virtual status_t dump(int fd, const Vector<String16>& args) = 0; - protected: static Mutex* getClientLockFromCookie(void* user); // convert client from cookie. Client lock should be acquired before getting Client. static Client* getClientFromCookie(void* user); - // the instance is in the middle of destruction. When this is set, - // the instance should not be accessed from callback. - // CameraService's mClientLock should be acquired to access this. - bool mDestructionStarted; + virtual void notifyError(); - // these are initialized in the constructor. - sp<CameraService> mCameraService; // immutable after constructor - sp<ICameraClient> mCameraClient; - int mCameraId; // immutable after constructor - int mCameraFacing; // immutable after constructor - pid_t mClientPid; - pid_t mServicePid; // immutable after constructor + // Initialized in constructor - }; + // - The app-side Binder interface to receive callbacks from us + sp<ICameraClient> mRemoteCallback; + + }; // class Client + + class ProClient : public BnProCameraUser, public BasicClient { + public: + typedef IProCameraCallbacks TCamCallbacks; + + ProClient(const sp<CameraService>& cameraService, + const sp<IProCameraCallbacks>& remoteCallback, + const String16& clientPackageName, + int cameraId, + int cameraFacing, + int clientPid, + uid_t clientUid, + int servicePid); + + virtual ~ProClient(); + + const sp<IProCameraCallbacks>& getRemoteCallback() { + return mRemoteCallback; + } + + /*** + IProCamera implementation + ***/ + virtual status_t connect(const sp<IProCameraCallbacks>& callbacks) + = 0; + virtual status_t exclusiveTryLock() = 0; + virtual status_t exclusiveLock() = 0; + virtual status_t exclusiveUnlock() = 0; + + virtual bool hasExclusiveLock() = 0; + + // Note that the callee gets a copy of the metadata. + virtual int submitRequest(camera_metadata_t* metadata, + bool streaming = false) = 0; + virtual status_t cancelRequest(int requestId) = 0; + + // Callbacks from camera service + virtual void onExclusiveLockStolen() = 0; + + protected: + virtual void notifyError(); + + sp<IProCameraCallbacks> mRemoteCallback; + }; // class ProClient private: + + // Delay-load the Camera HAL module + virtual void onFirstRef(); + + // Step 1. Check if we can connect, before we acquire the service lock. + bool validateConnect(int cameraId, + /*inout*/ + int& clientUid) const; + + // Step 2. Check if we can connect, after we acquire the service lock. + bool canConnectUnsafe(int cameraId, + const String16& clientPackageName, + const sp<IBinder>& remoteCallback, + /*out*/ + sp<Client> &client); + + // When connection is successful, initialize client and track its death + bool connectFinishUnsafe(const sp<BasicClient>& client, + const sp<IBinder>& clientBinder); + + virtual sp<BasicClient> getClientByRemote(const wp<IBinder>& cameraClient); + Mutex mServiceLock; wp<Client> mClient[MAX_CAMERAS]; // protected by mServiceLock Mutex mClientLock[MAX_CAMERAS]; // prevent Client destruction inside callbacks int mNumberOfCameras; + typedef wp<ProClient> weak_pro_client_ptr; + Vector<weak_pro_client_ptr> mProClientList[MAX_CAMERAS]; + // needs to be called with mServiceLock held sp<Client> findClientUnsafe(const wp<IBinder>& cameraClient, int& outIndex); + sp<ProClient> findProClientUnsafe( + const wp<IBinder>& cameraCallbacksRemote); // atomics to record whether the hardware is allocated to some client. volatile int32_t mBusy[MAX_CAMERAS]; @@ -159,8 +329,32 @@ private: camera_module_t *mModule; + Vector<sp<ICameraServiceListener> > + mListenerList; + + // guard only mStatusList and the broadcasting of ICameraServiceListener + mutable Mutex mStatusMutex; + ICameraServiceListener::Status + mStatusList[MAX_CAMERAS]; + + // Read the current status (locks mStatusMutex) + ICameraServiceListener::Status + getStatus(int cameraId) const; + + typedef Vector<ICameraServiceListener::Status> StatusVector; + // Broadcast the new status if it changed (locks the service mutex) + void updateStatus( + ICameraServiceListener::Status status, + int32_t cameraId, + const StatusVector *rejectSourceStates = NULL); + // IBinder::DeathRecipient implementation - virtual void binderDied(const wp<IBinder> &who); + virtual void binderDied(const wp<IBinder> &who); + + // Helpers + int getDeviceVersion(int cameraId, int* facing); + + bool isValidCameraId(int cameraId); }; } // namespace android |