/*
**
** 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 <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
namespace android {
extern volatile int32_t gLogLevel;
class MemoryHeapBase;
class MediaPlayer;
class CameraService :
public BinderService<CameraService>,
public BnCameraService,
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,
const String16& clientPackageName, int clientUid);
virtual sp<IProCameraUser> connect(const sp<IProCameraCallbacks>& cameraCb,
int cameraId, const String16& clientPackageName, int clientUid);
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 status_t dump(int fd, const Vector<String16>& args);
/////////////////////////////////////////////////////////////////////
// Client functionality
virtual void removeClientByRemote(const wp<IBinder>& remoteBinder);
enum sound_kind {
SOUND_SHUTTER = 0,
SOUND_RECORDING = 1,
NUM_SOUNDS
};
void loadSound();
void playSound(sound_kind kind);
void releaseSound();
/////////////////////////////////////////////////////////////////////
// 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<IGraphicBufferProducer>& bufferProducer)=0;
virtual void setPreviewCallbackFlag(int flag) = 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<IMemory>& 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>& 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>& getRemoteCallback() {
return mRemoteCallback;
}
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();
// 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];
void setCameraBusy(int cameraId);
void setCameraFree(int cameraId);
// sounds
MediaPlayer* newMediaPlayer(const char *file);
Mutex mSoundLock;
sp<MediaPlayer> mSoundPlayer[NUM_SOUNDS];
int mSoundRef; // reference count (release all MediaPlayer when 0)
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);
// Helpers
int getDeviceVersion(int cameraId, int* facing);
bool isValidCameraId(int cameraId);
};
} // namespace android
#endif