startPreview
1. Camera::startPreview()
frameworks/base/core/java/android/hardware/Camera.java
public native final voidstartPreview();
2. android_hardware_Camera_startPreview()
frameworks/base/core/jni/android_hardware_Camera.cpp
static voidandroid_hardware_Camera_startPreview(JNIEnv *env, jobject thiz)
{
ALOGV("startPreview");
//得到本地Camera对象
sp<Camera> camera =get_native_camera(env, thiz, NULL);
if (camera == 0) return;
//调用本地Camera::startPreview方法
if (camera->startPreview() != NO_ERROR){
jniThrowRuntimeException(env, "startPreview failed");
return;
}
}
3. Camera::startPreview()
frameworks/av/camera/Camera.cpp
// start preview mode
status_t Camera::startPreview()
{
ALOGV("startPreview");
sp<ICamera> c = mCamera;
// mCamera是CameraBase中的成员变量,它指向的是一个BpCamera对象。
//在Camera open的过程中, mCamera从cs->connect()返回中
//得到的是 BpCamera对象,因此c将为BpCamera对象。
if (c == 0) return NO_INIT;
return c->startPreview();
}
4. BpCamera::startPreview()
frameworks/av/camera/ICamera.cpp
class BpCamera: publicBpInterface<ICamera>
{
// start preview mode, must call setPreviewDisplay first
status_t startPreview()
{
ALOGV("startPreview");
Parcel data, reply;
data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
remote()->transact(START_PREVIEW,data, &reply);
return reply.readInt32();
}
};
在 camera open过程中, cs->connect()时从service回复reply中得到的一个binder对象(实际上是一个CameraClient或Camera2Client对象),在interfaca_cast时,会从依据这个对象查询其对应的本地接口(BpBinder对象),在创建BpCamera对象时将这个BpBinder本地接口对象传入BpCamera的构造函数,最终这个BpBinder对象赋值给BpCamera的mRemote成员变量。而remote()函数就是返回mRemote成员变量。
因此remote()->transact()实际上调用的是BpBinder::transact()
5. BpBinder::transact()
Frameworks/native/libs/binder/BpBinder.cpp
status_t BpBinder::transact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
// Once a binder has died, it will never come back to life.
if (mAlive) {
status_t status = IPCThreadState::self()->transact(
mHandle, code, data, reply, flags);
if (status == DEAD_OBJECT) mAlive = 0;
return status;
}
return DEAD_OBJECT;
}
6. IPCThreadState::transact()
Frameworks/native/libs/binder/IPCThreadState.cpp
status_t IPCThreadState::transact(int32_thandle,
uint32_tcode, const Parcel& data,
Parcel*reply, uint32_t flags)
{
status_t err = data.errorCheck();
flags |= TF_ACCEPT_FDS;
IF_LOG_TRANSACTIONS() {
TextOutput::Bundle _b(alog);
alog << "BC_TRANSACTION thr " <<(void*)pthread_self() << " / hand "
<< handle << " / code " << TypeCode(code)<< ": "
<< indent << data << dedent << endl;
}
if (err == NO_ERROR) {
LOG_ONEWAY(">>>> SEND from pid %d uid %d %s",getpid(), getuid(),
(flags & TF_ONE_WAY) == 0 ? "READ REPLY" : "ONEWAY");
err =writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);
}
if (err != NO_ERROR) {
if (reply) reply->setError(err);
return (mLastError = err);
}
if ((flags & TF_ONE_WAY) == 0) {
#if 0
if (code == 4) { // relayout
ALOGI(">>>>>> CALLING transaction 4");
} else {
ALOGI(">>>>>> CALLING transaction %d",code);
}
#endif
if (reply) {
err = waitForResponse(reply);
} else {
Parcel fakeReply;
err = waitForResponse(&fakeReply);
}
#if 0
if (code == 4) { // relayout
ALOGI("<<<<<< RETURNING transaction 4");
} else {
ALOGI("<<<<<< RETURNING transaction %d",code);
}
#endif
IF_LOG_TRANSACTIONS() {
TextOutput::Bundle _b(alog);
alog << "BR_REPLY thr " << (void*)pthread_self()<< " / hand "
<< handle <<": ";
if (reply) alog << indent << *reply << dedent <<endl;
else alog <<"(none requested)" << endl;
}
}else {
err = waitForResponse(NULL, NULL);
}
return err;
}
IPCThreadState::writeTransactionData()
IPCThreadState:: waitForResponse ()
7. status_tIPCThreadState::executeCommand(int32_t cmd)
Frameworks/native/libs/binder/IPCThreadState.cpp
status_tIPCThreadState::executeCommand(int32_t cmd)
{
BBinder* obj;
RefBase::weakref_type* refs;
status_t result = NO_ERROR;
switch (cmd) {
case BR_ERROR:
result = mIn.readInt32();
break;
……………………………………………………………..
case BR_TRANSACTION:
{
binder_transaction_data tr;
result = mIn.read(&tr, sizeof(tr));
ALOG_ASSERT(result == NO_ERROR,
"Not enough command datafor brTRANSACTION");
if (result != NO_ERROR) break;
Parcel buffer;
buffer.ipcSetDataReference(
reinterpret_cast<constuint8_t*>(tr.data.ptr.buffer),
tr.data_size,
reinterpret_cast<constsize_t*>(tr.data.ptr.offsets),
tr.offsets_size/sizeof(size_t),freeBuffer, this);
const pid_t origPid = mCallingPid;
const uid_t origUid = mCallingUid;
mCallingPid = tr.sender_pid;
mCallingUid = tr.sender_euid;
int curPrio = getpriority(PRIO_PROCESS, mMyThreadId);
if (gDisableBackgroundScheduling) {
if (curPrio >ANDROID_PRIORITY_NORMAL) {
// We have inherited areduced priority from the caller, but do not
// want to run in thatstate in this process. The driver setour
// priority already (thoughnot our scheduling class), so bounce
// it back to the defaultbefore invoking the transaction.
setpriority(PRIO_PROCESS,mMyThreadId, ANDROID_PRIORITY_NORMAL);
}
} else {
if (curPrio >=ANDROID_PRIORITY_BACKGROUND) {
// We want to use theinherited priority from the caller.
// Ensure this thread is inthe background scheduling class,
// since the driver won'tmodify scheduling classes for us.
// The scheduling group isreset to default by the caller
// once this method returnsafter the transaction is complete.
set_sched_policy(mMyThreadId, SP_BACKGROUND);
}
}
//ALOGI(">>>> TRANSACT from pid %d uid %d\n",mCallingPid, mCallingUid);
Parcel reply;
IF_LOG_TRANSACTIONS() {
TextOutput::Bundle _b(alog);
alog <<"BR_TRANSACTION thr " << (void*)pthread_self()
<< " / obj" << tr.target.ptr << " / code "
<< TypeCode(tr.code)<< ": " << indent << buffer
<< dedent <<endl
<< "Data addr = "
<<reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer)
<< ", offsetsaddr="
<<reinterpret_cast<const size_t*>(tr.data.ptr.offsets) << endl;
}
if (tr.target.ptr) {
//这儿的b应该就是 Camera::open()调用过程中,在服务端生成的CameraClient
//或 Camera2Client对象
// class CameraClient : public CameraService::Client
// clas CameraService::Client : public BnCamera, publicBasicClient
// class BnCamera: public BnInterface<ICamera>
// class BnInterface : public INTERFACE, public BBinder
// class BBinder : public IBinder
sp<BBinder>b((BBinder*)tr.cookie);
const status_t error =b->transact(tr.code, buffer, &reply, tr.flags);
if (error < NO_ERROR)reply.setError(error);
} else {
const status_t error =the_context_object->transact(tr.code, buffer, &reply, tr.flags);
if (error < NO_ERROR)reply.setError(error);
}
//ALOGI("<<<< TRANSACT from pid %d restore pid %d uid%d\n",
// mCallingPid, origPid,origUid);
if ((tr.flags & TF_ONE_WAY) == 0) {
LOG_ONEWAY("Sending replyto %d!", mCallingPid);
sendReply(reply, 0);
} else {
LOG_ONEWAY("NOT sendingreply to %d!", mCallingPid);
}
mCallingPid = origPid;
mCallingUid = origUid;
IF_LOG_TRANSACTIONS() {
TextOutput::Bundle _b(alog);
alog << "BC_REPLYthr " << (void*)pthread_self() << " / obj "
<< tr.target.ptr<< ": " << indent << reply << dedent <<endl;
}
}
break;
…………………………………………………………….
}
8. BBinder::transact()
Frameworks/native/libs/binder/binder.cpp
// class CameraClient : public CameraService::Client
// clas CameraService::Client : public BnCamera, publicBasicClient
// class BnCamera: public BnInterface<ICamera>
// class BnInterface : public INTERFACE, public BBinder
// class BBinder : public IBinder
由于CameraClient没有改写BBinder的transact(),因此上述b->transact()
实际上就是调用BBinder的transact() .
status_t BBinder::transact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
data.setDataPosition(0);
status_t err = NO_ERROR;
switch (code) {
case PING_TRANSACTION:
reply->writeInt32(pingBinder());
break;
default:
err = onTransact(code, data, reply,flags);
break;
}
if (reply != NULL) {
reply->setDataPosition(0);
}
return err;
}
9. BnCamera::onTransact ()
Frameworks/av/camera/ICamera.cpp
status_t BnCamera::onTransact(
uint32_tcode, const Parcel& data, Parcel* reply, uint32_t flags)
{
switch(code) {
case DISCONNECT: {
ALOGV("DISCONNECT");
CHECK_INTERFACE(ICamera, data, reply);
disconnect();
return NO_ERROR;
} break;
case SET_PREVIEW_TEXTURE: {
ALOGV("SET_PREVIEW_TEXTURE");
CHECK_INTERFACE(ICamera, data, reply);
sp<IGraphicBufferProducer> st =
interface_cast<IGraphicBufferProducer>(data.readStrongBinder());
reply->writeInt32(setPreviewTexture(st));
return NO_ERROR;
} break;
case SET_PREVIEW_CALLBACK_FLAG: {
ALOGV("SET_PREVIEW_CALLBACK_TYPE");
CHECK_INTERFACE(ICamera, data, reply);
int callback_flag = data.readInt32();
setPreviewCallbackFlag(callback_flag);
return NO_ERROR;
} break;
case START_PREVIEW: {
ALOGV("START_PREVIEW");
CHECK_INTERFACE(ICamera, data, reply);
reply->writeInt32(startPreview());
return NO_ERROR;
} break;
case START_RECORDING: {
ALOGV("START_RECORDING");
CHECK_INTERFACE(ICamera, data, reply);
reply->writeInt32(startRecording());
return NO_ERROR;
} break;
case STOP_PREVIEW: {
ALOGV("STOP_PREVIEW");
CHECK_INTERFACE(ICamera, data, reply);
stopPreview();
return NO_ERROR;
} break;
case STOP_RECORDING: {
ALOGV("STOP_RECORDING");
CHECK_INTERFACE(ICamera, data, reply);
stopRecording();
return NO_ERROR;
} break;
case RELEASE_RECORDING_FRAME: {
ALOGV("RELEASE_RECORDING_FRAME");
CHECK_INTERFACE(ICamera, data, reply);
sp<IMemory> mem =interface_cast<IMemory>(data.readStrongBinder());
releaseRecordingFrame(mem);
return NO_ERROR;
} break;
case STORE_META_DATA_IN_BUFFERS: {
ALOGV("STORE_META_DATA_IN_BUFFERS");
CHECK_INTERFACE(ICamera, data, reply);
bool enabled = data.readInt32();
reply->writeInt32(storeMetaDataInBuffers(enabled));
return NO_ERROR;
} break;
case PREVIEW_ENABLED: {
ALOGV("PREVIEW_ENABLED");
CHECK_INTERFACE(ICamera, data, reply);
reply->writeInt32(previewEnabled());
return NO_ERROR;
} break;
case RECORDING_ENABLED: {
ALOGV("RECORDING_ENABLED");
CHECK_INTERFACE(ICamera, data, reply);
reply->writeInt32(recordingEnabled());
return NO_ERROR;
} break;
case AUTO_FOCUS: {
ALOGV("AUTO_FOCUS");
CHECK_INTERFACE(ICamera, data, reply);
reply->writeInt32(autoFocus());
return NO_ERROR;
} break;
case CANCEL_AUTO_FOCUS: {
ALOGV("CANCEL_AUTO_FOCUS");
CHECK_INTERFACE(ICamera, data, reply);
reply->writeInt32(cancelAutoFocus());
return NO_ERROR;
} break;
case TAKE_PICTURE: {
ALOGV("TAKE_PICTURE");
CHECK_INTERFACE(ICamera, data, reply);
int msgType = data.readInt32();
reply->writeInt32(takePicture(msgType));
return NO_ERROR;
} break;
case SET_PARAMETERS: {
ALOGV("SET_PARAMETERS");
CHECK_INTERFACE(ICamera, data, reply);
String8 params(data.readString8());
reply->writeInt32(setParameters(params));
return NO_ERROR;
} break;
case GET_PARAMETERS: {
ALOGV("GET_PARAMETERS");
CHECK_INTERFACE(ICamera, data, reply);
reply->writeString8(getParameters());
return NO_ERROR;
} break;
case SEND_COMMAND: {
ALOGV("SEND_COMMAND");
CHECK_INTERFACE(ICamera, data, reply);
int command = data.readInt32();
int arg1 = data.readInt32();
int arg2 = data.readInt32();
reply->writeInt32(sendCommand(command, arg1, arg2));
return NO_ERROR;
} break;
case CONNECT: {
CHECK_INTERFACE(ICamera, data, reply);
sp<ICameraClient> cameraClient =interface_cast<ICameraClient>(data.readStrongBinder());
reply->writeInt32(connect(cameraClient));
return NO_ERROR;
} break;
case LOCK: {
CHECK_INTERFACE(ICamera, data, reply);
reply->writeInt32(lock());
return NO_ERROR;
} break;
case UNLOCK: {
CHECK_INTERFACE(ICamera, data, reply);
reply->writeInt32(unlock());
return NO_ERROR;
} break;
default:
return BBinder::onTransact(code, data, reply, flags);
}
}
10. CameraClient::startPreview()
Frameworks/av/services/camera/libcameraservice/CameraClient.cpp
上述case语句中startPreview()实际上调用的是CameraClient::startPreview()
case START_PREVIEW: {
ALOGV("START_PREVIEW");
CHECK_INTERFACE(ICamera, data, reply);
reply->writeInt32(startPreview());
return NO_ERROR;
} break;
// start preview mode
status_t CameraClient::startPreview() {
LOG1("startPreview (pid %d)", getCallingPid());
returnstartCameraMode(CAMERA_PREVIEW_MODE);
}
// start preview or recording
status_tCameraClient::startCameraMode(camera_mode mode) {
LOG1("startCameraMode(%d)", mode);
Mutex::Autolock lock(mLock);
status_t result = checkPidAndHardware();
if (result != NO_ERROR) return result;
switch(mode) {
case CAMERA_PREVIEW_MODE:
if (mSurface == 0 && mPreviewWindow == 0) {
LOG1("mSurface is not setyet.");
// still able to start previewin this case.
}
return startPreviewMode();
case CAMERA_RECORDING_MODE:
if (mSurface == 0 && mPreviewWindow == 0) {
ALOGE("mSurface ormPreviewWindow must be set before startRecordingMode.");
return INVALID_OPERATION;
}
return startRecordingMode();
default:
return UNKNOWN_ERROR;
}
}
status_t CameraClient::startPreviewMode() {
LOG1("startPreviewMode");
status_t result = NO_ERROR;
// if preview has been enabled, nothing needs to be done
if (mHardware->previewEnabled()) {
return NO_ERROR;
}
if (mPreviewWindow != 0) {
native_window_set_scaling_mode(mPreviewWindow.get(),
NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
native_window_set_buffers_transform(mPreviewWindow.get(),
mOrientation);
}
mHardware->setPreviewWindow(mPreviewWindow);
result = mHardware->startPreview();
return result;
}
11. CameraClient::startPreview()
Frameworks/av/services/camera/libcameraservice/CameraHardwareInterface.h
//调用设备驱动例程
status_t startPreview()
{
ALOGV("%s(%s)", __FUNCTION__, mName.string());
if (mDevice->ops->start_preview)
returnmDevice->ops->start_preview(mDevice);
return INVALID_OPERATION;
}