参考
官方文档
Camera架构
https://source.android.google.cn/devices/camera
Camera API
https://developer.android.google.cn/training/camera
博客
Android源码笔记——Camera系统架构
Android Camera 四 Camera HAL 分析
概述
Camera框架(旧)
Android系统架构
CameraServicq启动
/system/core/rootdir/init.rc
service media /system/bin/mediaserver
class main
user media
group audio camera inet net_bt net_bt_admin net_bw_acct drmrpc mediadrm
ioprio rt 4
启动mediaserver服务
frameworks/av/media/mediaserver/main_mediaserver.cpp
int main(int argc, char** argv)
{
......
} else {
// all other services
if (doLog) {
prctl(PR_SET_PDEATHSIG, SIGKILL); // if parent media.log dies before me, kill me also
setpgid(0, 0); // but if I die first, don't kill my parent
}
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm = defaultServiceManager();
ALOGI("ServiceManager: %p", sm.get());
AudioFlinger::instantiate();
MediaPlayerService::instantiate();
CameraService::instantiate();
AudioPolicyService::instantiate();
registerExtensions();
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
}
启动CameraService服务
Camera 层次结构
Camera代码流程主要文件
open()
frameworks/base/core/java/android/hardware/Camera.java
public static Camera open() {
int numberOfCameras = getNumberOfCameras();
CameraInfo cameraInfo = new CameraInfo();
for (int i = 0; i < numberOfCameras; i++) {
getCameraInfo(i, cameraInfo);
if (cameraInfo.facing == CameraInfo.CAMERA_FACING_BACK) {
return new Camera(i);
}
}
return null;
}
构造Camera对象,默认是后置摄像头
Camera(int cameraId) {
...
native_setup(new WeakReference<Camera>(this), cameraId, packageName);
}
调用native方法进行设置
private native final void native_setup(Object camera_this, int cameraId,
String packageName);
JNI方法实现
frameworks/base/core/jni/android_hardware_Camera.cpp
// connect to camera service
static void android_hardware_Camera_native_setup(JNIEnv *env, jobject thiz,
jobject weak_this, jint cameraId, jstring clientPackageName)
{
// Convert jstring to String16
const char16_t *rawClientName = env->GetStringChars(clientPackageName, NULL);
jsize rawClientNameLen = env->GetStringLength(clientPackageName);
String16 clientName(rawClientName, rawClientNameLen);
env->ReleaseStringChars(clientPackageName, rawClientName);
sp<Camera> camera = Camera::connect(cameraId, clientName,
Camera::USE_CALLING_UID);
if (camera == NULL) {
jniThrowRuntimeException(env, "Fail to connect to camera service");
return;
}
// make sure camera hardware is alive
if (camera->getStatus() != NO_ERROR) {
jniThrowRuntimeException(env, "Camera initialization failed");
return;
}
jclass clazz = env->GetObjectClass(thiz);
if (clazz == NULL) {
jniThrowRuntimeException(env, "Can't find android/hardware/Camera");
return;
}
// We use a weak reference so the Camera object can be garbage collected.
// The reference is only used as a proxy for callbacks.
sp<JNICameraContext> context = new JNICameraContext(env, weak_this, clazz, camera);
context->incStrong((void*)android_hardware_Camera_native_setup);
camera->setListener(context);
// save context in opaque field
env->SetIntField(thiz, fields.context, (int)context.get());
}
连接到camera service
frameworks/av/camera/Camera.cpp
sp<Camera> Camera::connect(int cameraId, const String16& clientPackageName,
int clientUid)
{
return CameraBaseT::connect(cameraId, clientPackageName, clientUid);
}
Camera基础CameraBase
Camera::Camera(int cameraId)
: CameraBase(cameraId)
{
}
查看CameraBase的connect方法
frameworks/av/camera/CameraBase.cpp
template <typename TCam, typename TCamTraits>
sp<TCam> CameraBase<TCam, TCamTraits>::connect(int cameraId,
const String16& clientPackageName,
int clientUid)
{
ALOGV("%s: connect", __FUNCTION__);
sp<TCam> c = new TCam(cameraId);
sp<TCamCallbacks> cl = c;
status_t status = NO_ERROR;
const sp<ICameraService>& cs = getCameraService();
if (cs != 0) {
TCamConnectService fnConnectService = TCamTraits::fnConnectService;
status = (cs.get()->*fnConnectService)(cl, cameraId, clientPackageName, clientUid,
/*out*/ c->mCamera);
}
if (status == OK && c->mCamera != 0) {
c->mCamera->asBinder()->linkToDeath(c);
c->mStatus = NO_ERROR;
} else {
ALOGW("An error occurred while connecting to camera: %d", cameraId);
c.clear();
}
return c;
}
Binder调用
getCameraService返回服务的Ibinder
调用service的connect函数
status_t CameraService::connect(
const sp<ICameraClient>& cameraClient,
int cameraId,
const String16& clientPackageName,
int clientUid,
/*out*/
sp<ICamera>& device) {
String8 clientName8(clientPackageName);
int callingPid = getCallingPid();
LOG1("CameraService::connect E (pid %d \"%s\", id %d)", callingPid,
clientName8.string(), cameraId);
status_t status = validateConnect(cameraId, /*inout*/clientUid);
if (status != OK) {
return status;
}
sp<Client> client;
{
Mutex::Autolock lock(mServiceLock);
sp<BasicClient> clientTmp;
if (!canConnectUnsafe(cameraId, clientPackageName,
cameraClient->asBinder(),
/*out*/clientTmp)) {
return -EBUSY;
} else if (client.get() != NULL) {
device = static_cast<Client*>(clientTmp.get());
return OK;
}
int facing = -1;
int deviceVersion = getDeviceVersion(cameraId, &facing);
// If there are other non-exclusive users of the camera,
// this will tear them down before we can reuse the camera
if (isValidCameraId(cameraId)) {
// transition from PRESENT -> NOT_AVAILABLE
updateStatus(ICameraServiceListener::STATUS_NOT_AVAILABLE,
cameraId);
}
switch(deviceVersion) {
case CAMERA_DEVICE_API_VERSION_1_0:
client = new CameraClient(this, cameraClient,
clientPackageName, cameraId,
facing, callingPid, clientUid, getpid());
break;
case CAMERA_DEVICE_API_VERSION_2_0:
case CAMERA_DEVICE_API_VERSION_2_1:
case CAMERA_DEVICE_API_VERSION_3_0:
client = new Camera2Client(this, cameraClient,
clientPackageName, cameraId,
facing, callingPid, clientUid, getpid(),
deviceVersion);
break;
case -1:
ALOGE("Invalid camera id %d", cameraId);
return BAD_VALUE;
default