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;

// mCameraCameraBase成员变量,它指向的是一个BpCamera对象。

//Camera open的过程中, mCameracs->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对象(实际上是一个CameraClientCamera2Client对象),在interfaca_cast时,会从依据这个对象查询其对应的本地接口(BpBinder对象),在创建BpCamera对象时将这个BpBinder本地接口对象传入BpCamera的构造函数,最终这个BpBinder对象赋值给BpCameramRemote成员变量。而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没有改写BBindertransact(),因此上述b->transact()

实际上就是调用BBindertransact() .

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;

}

更多相关文章

  1. 服务器向Android写一个对象
  2. Android及Robotium学习总结【环境变量,真机调试及根据id模拟按键
  3. Android中使用static变量
  4. Android的跨进程通信介绍----------------aidl,传递复杂对象以及S
  5. Android环境变量作用--命令行操作(ADB、AVD等)
  6. listView显示对象以及access any RESTFull service that uses JS
  7. android 面向对象数据库 db40使用demo

随机推荐

  1. 40个常用Linux命令
  2. Python 炫技操作:连接列表的八种方法
  3. 太酷炫了!我会 8 种 Python 导包的方式,你
  4. json 数据类型、时间与时间戳
  5. Linux 内核的五大创新
  6. PHP变量声明及数据类型
  7. 怎样快速调试Linux内核
  8. 27个Linux文档编辑命令
  9. Linux常用命令大全(最完整)
  10. 精通 Linux 的 ls 命令