/* * Copyright (C) 2008 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ANDROID_SERVERS_CAMERA_CAMERASERVICE_H #define ANDROID_SERVERS_CAMERA_CAMERASERVICE_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* This needs to be increased if we can have more cameras */ #define MAX_CAMERAS 2 namespace android { extern volatile int32_t gLogLevel; class MemoryHeapBase; class MediaPlayer; class CameraService : public BinderService, public BnCameraService, public IBinder::DeathRecipient, public camera_module_callbacks_t { friend class BinderService; public: class Client; class BasicClient; // Implementation of BinderService 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 status_t getCameraCharacteristics(int cameraId, CameraMetadata* cameraInfo); virtual status_t getCameraVendorTagDescriptor(/*out*/ sp& desc); virtual status_t connect(const sp& cameraClient, int cameraId, const String16& clientPackageName, int clientUid, /*out*/ sp& device); virtual status_t connectPro(const sp& cameraCb, int cameraId, const String16& clientPackageName, int clientUid, /*out*/ sp& device); virtual status_t connectDevice( const sp& cameraCb, int cameraId, const String16& clientPackageName, int clientUid, /*out*/ sp& device); virtual status_t addListener(const sp& listener); virtual status_t removeListener( const sp& listener); // Extra permissions checks virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags); virtual status_t dump(int fd, const Vector& args); ///////////////////////////////////////////////////////////////////// // Client functionality virtual void removeClientByRemote(const wp& remoteBinder); enum sound_kind { SOUND_SHUTTER = 0, SOUND_RECORDING = 1, NUM_SOUNDS }; void loadSound(); void playSound(sound_kind kind); void releaseSound(); ///////////////////////////////////////////////////////////////////// // CameraDeviceFactory functionality int getDeviceVersion(int cameraId, int* facing = NULL); ///////////////////////////////////////////////////////////////////// // 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 BasicClient* 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; // because we can't virtually inherit IInterface, which breaks // virtual inheritance virtual sp asBinderWrapper() = 0; // Return the remote callback binder object (e.g. IProCameraCallbacks) sp getRemote() { return mRemoteBinder; } virtual status_t dump(int fd, const Vector& args) = 0; protected: BasicClient(const sp& cameraService, const sp& 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 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 sp mRemoteBinder; // immutable after constructor // permissions management status_t startCameraOps(); status_t finishCameraOps(); // Notify client about a fatal error virtual void notifyError( ICameraDeviceCallbacks::CameraErrorCode errorCode, const CaptureResultExtras& resultExtras) = 0; private: AppOpsManager mAppOpsManager; class OpsCallback : public BnAppOpsCallback { public: OpsCallback(wp client); virtual void opChanged(int32_t op, const String16& packageName); private: wp mClient; }; // class OpsCallback sp 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& client) = 0; virtual status_t lock() = 0; virtual status_t unlock() = 0; virtual status_t setPreviewTarget(const sp& bufferProducer)=0; virtual void setPreviewCallbackFlag(int flag) = 0; virtual status_t setPreviewCallbackTarget( const sp& callbackProducer) = 0; virtual status_t startPreview() = 0; virtual void stopPreview() = 0; virtual bool previewEnabled() = 0; virtual status_t storeMetaDataInBuffers(bool enabled) = 0; virtual status_t startRecording() = 0; virtual void stopRecording() = 0; virtual bool recordingEnabled() = 0; virtual void releaseRecordingFrame(const sp& mem) = 0; virtual status_t autoFocus() = 0; virtual status_t cancelAutoFocus() = 0; virtual status_t takePicture(int msgType) = 0; virtual status_t setParameters(const String8& params) = 0; virtual String8 getParameters() const = 0; virtual status_t sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) = 0; // Interface used by CameraService Client(const sp& cameraService, const sp& cameraClient, const String16& clientPackageName, int cameraId, int cameraFacing, int clientPid, uid_t clientUid, int servicePid); ~Client(); // return our camera client const sp& getRemoteCallback() { return mRemoteCallback; } virtual sp asBinderWrapper() { return asBinder(); } protected: static Mutex* getClientLockFromCookie(void* user); // convert client from cookie. Client lock should be acquired before getting Client. static Client* getClientFromCookie(void* user); virtual void notifyError(ICameraDeviceCallbacks::CameraErrorCode errorCode, const CaptureResultExtras& resultExtras); // Initialized in constructor // - The app-side Binder interface to receive callbacks from us sp mRemoteCallback; }; // class Client class ProClient : public BnProCameraUser, public BasicClient { public: typedef IProCameraCallbacks TCamCallbacks; ProClient(const sp& cameraService, const sp& remoteCallback, const String16& clientPackageName, int cameraId, int cameraFacing, int clientPid, uid_t clientUid, int servicePid); virtual ~ProClient(); const sp& getRemoteCallback() { return mRemoteCallback; } /*** IProCamera implementation ***/ virtual status_t connect(const sp& 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(ICameraDeviceCallbacks::CameraErrorCode errorCode, const CaptureResultExtras& resultExtras); sp 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. status_t 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& remoteCallback, /*out*/ sp &client); // When connection is successful, initialize client and track its death status_t connectFinishUnsafe(const sp& client, const sp& remoteCallback); virtual sp getClientByRemote(const wp& cameraClient); Mutex mServiceLock; // either a Client or CameraDeviceClient wp mClient[MAX_CAMERAS]; // protected by mServiceLock Mutex mClientLock[MAX_CAMERAS]; // prevent Client destruction inside callbacks int mNumberOfCameras; typedef wp weak_pro_client_ptr; Vector mProClientList[MAX_CAMERAS]; // needs to be called with mServiceLock held sp findClientUnsafe(const wp& cameraClient, int& outIndex); sp findProClientUnsafe( const wp& cameraCallbacksRemote); // atomics to record whether the hardware is allocated to some client. volatile int32_t mBusy[MAX_CAMERAS]; void setCameraBusy(int cameraId); void setCameraFree(int cameraId); // sounds MediaPlayer* newMediaPlayer(const char *file); Mutex mSoundLock; sp mSoundPlayer[NUM_SOUNDS]; int mSoundRef; // reference count (release all MediaPlayer when 0) camera_module_t *mModule; Vector > 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 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 &who); // Helpers bool isValidCameraId(int cameraId); bool setUpVendorTags(); }; } // namespace android #endif