blob: 8a3db08a132ea4ecde1d4f3554c014a14f0656a9 [file] [log] [blame]
/*
* 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 <utils/KeyedVector.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/camera2/ICameraDeviceUser.h>
#include <camera/camera2/ICameraDeviceCallbacks.h>
#include <camera/VendorTagDescriptor.h>
#include <camera/CaptureResult.h>
#include <camera/CameraParameters.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;
// Event log ID
static const int SN_EVENT_LOG_ID = 0x534e4554;
// 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 status_t getCameraCharacteristics(int cameraId,
CameraMetadata* cameraInfo);
virtual status_t getCameraVendorTagDescriptor(/*out*/ sp<VendorTagDescriptor>& desc);
virtual status_t connect(const sp<ICameraClient>& cameraClient, int cameraId,
const String16& clientPackageName, int clientUid,
/*out*/
sp<ICamera>& device);
virtual status_t connectLegacy(const sp<ICameraClient>& cameraClient, int cameraId,
int halVersion, const String16& clientPackageName, int clientUid,
/*out*/
sp<ICamera>& device);
virtual status_t connectPro(const sp<IProCameraCallbacks>& cameraCb,
int cameraId, const String16& clientPackageName, int clientUid,
/*out*/
sp<IProCameraUser>& device);
virtual status_t connectDevice(
const sp<ICameraDeviceCallbacks>& cameraCb,
int cameraId,
const String16& clientPackageName,
int clientUid,
/*out*/
sp<ICameraDeviceUser>& device);
virtual status_t addListener(const sp<ICameraServiceListener>& listener);
virtual status_t removeListener(
const sp<ICameraServiceListener>& listener);
virtual status_t getLegacyParameters(
int cameraId,
/*out*/
String16* parameters);
// OK = supports api of that version, -EOPNOTSUPP = does not support
virtual status_t supportsCameraApi(
int cameraId, int apiVersion);
// 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();
/////////////////////////////////////////////////////////////////////
// CameraDeviceFactory functionality
int getDeviceVersion(int cameraId, int* facing = NULL);
/////////////////////////////////////////////////////////////////////
// Shared utilities
static status_t filterOpenErrorCode(status_t err);
static status_t filterGetInfoErrorCode(status_t err);
/////////////////////////////////////////////////////////////////////
// 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();
// because we can't virtually inherit IInterface, which breaks
// virtual inheritance
virtual sp<IBinder> asBinderWrapper() = 0;
// Return the remote callback binder object (e.g. IProCameraCallbacks)
sp<IBinder> getRemote() {
return mRemoteBinder;
}
// Disallows dumping over binder interface
virtual status_t dump(int fd, const Vector<String16>& args);
// Internal dump method to be called by CameraService
virtual status_t dumpClient(int fd, const Vector<String16>& args) = 0;
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
sp<IBinder> 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<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 setPreviewTarget(const sp<IGraphicBufferProducer>& bufferProducer)=0;
virtual void setPreviewCallbackFlag(int flag) = 0;
virtual status_t setPreviewCallbackTarget(
const sp<IGraphicBufferProducer>& 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<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;
}
virtual sp<IBinder> 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<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(ICameraDeviceCallbacks::CameraErrorCode errorCode,
const CaptureResultExtras& resultExtras);
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.
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<IBinder>& remoteCallback,
/*out*/
sp<BasicClient> &client);
// When connection is successful, initialize client and track its death
status_t connectFinishUnsafe(const sp<BasicClient>& client,
const sp<IBinder>& remoteCallback);
virtual sp<BasicClient> getClientByRemote(const wp<IBinder>& cameraClient);
Mutex mServiceLock;
// either a Client or CameraDeviceClient
wp<BasicClient> 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<BasicClient> 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
bool isValidCameraId(int cameraId);
bool setUpVendorTags();
/**
* A mapping of camera ids to CameraParameters returned by that camera device.
*
* This cache is used to generate CameraCharacteristic metadata when using
* the HAL1 shim.
*/
KeyedVector<int, CameraParameters> mShimParams;
/**
* Initialize and cache the metadata used by the HAL1 shim for a given cameraId.
*
* Returns OK on success, or a negative error code.
*/
status_t initializeShimMetadata(int cameraId);
/**
* Get the cached CameraParameters for the camera. If they haven't been
* cached yet, then initialize them for the first time.
*
* Returns OK on success, or a negative error code.
*/
status_t getLegacyParametersLazy(int cameraId, /*out*/CameraParameters* parameters);
/**
* Generate the CameraCharacteristics metadata required by the Camera2 API
* from the available HAL1 CameraParameters and CameraInfo.
*
* Returns OK on success, or a negative error code.
*/
status_t generateShimMetadata(int cameraId, /*out*/CameraMetadata* cameraInfo);
/**
* Connect a new camera client. This should only be used while holding the
* mutex for mServiceLock.
*
* Returns OK on success, or a negative error code.
*/
status_t connectHelperLocked(
/*out*/
sp<Client>& client,
/*in*/
const sp<ICameraClient>& cameraClient,
int cameraId,
const String16& clientPackageName,
int clientUid,
int callingPid,
int halVersion = CAMERA_HAL_API_VERSION_UNSPECIFIED,
bool legacyMode = false);
};
} // namespace android
#endif