Android Camera Subsystem - Open - 01

 

 

 

sm(BpServiceManager(BpBinder(handle= 0))) = defaultServiceManager()

binder =sm->getServcie(String16(kCameraServiceName))

cs =(BpCameraService(BpBinder))

c->mCamera =cs->connect(…);   // 返回 BpCamera(BpBinder)

最后c->mCamera指向一个BpCamera(BpBinder)

 

1.  frameworks/base/core/java/android/hardware/camera.java

1.1  Open

  public static Camera open(int cameraId) {

       return new Camera(cameraId);

    }

   /**

    * Creates a new Camera object to access the first back-facing camera onthe

    * device. If the device does not have a back-facing camera, this returns

    * null.

    * @see #open(int)

    */

   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;

}

1.2 Camera Constructor

   Camera(int cameraId) {

       mShutterCallback = null;

       mRawImageCallback = null;

       mJpegCallback = null;

       mPreviewCallback = null;

       mPostviewCallback = null;

       mZoomListener = null;

 

       Looper looper;

       if ((looper = Looper.myLooper()) != null) {

           mEventHandler = new EventHandler(this, looper);

       } else if ((looper = Looper.getMainLooper()) != null) {

            mEventHandler = new EventHandler(this,looper);

       } else {

           mEventHandler = null;

       }

 

       String packageName = ActivityThread.currentPackageName();

 

       native_setup(newWeakReference<Camera>(this), cameraId, packageName);

}

2.   frameworks/base/core/jni/android_hardware_Camera.cpp

// connect tocamera service

static voidandroid_hardware_Camera_native_setup(JNIEnv *env, jobject thiz,

    jobject weak_this, jint cameraId, jstringclientPackageName)

{

    // 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);

 

   // 这儿模板实例是Camera

   // Camera::connect()返回一个Camera对象

   // 因此camera是一个Camera对象

 

    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 Cameraobject can be garbage collected.

    // The reference is only used as a proxyfor callbacks.

  // camera(本地Camera对象)保存在Java上下文

 

 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());

}

 

 

 

 

3.   frameworks/av/camera/Camera.cpp

sp<Camera>Camera::connect(int cameraId, const String16& clientPackageName,

        int clientUid)

{

   // 这儿模板实例是Camera

    returnCameraBaseT::connect(cameraId, clientPackageName, clientUid);

}

Notes:

Inframeworks/av/include/camera/CameraBase.cpp

template<typename TCam, typename TCamTraits = CameraTraits<TCam> >

class CameraBase: public IBinder::DeathRecipient

{

typedef CameraBase<TCam>        CameraBaseT;

};

4.   frameworks/av/camera/CameraBase.cpp

4.1  connect

template<typename TCam, typename TCamTraits>

sp<TCam>CameraBase<TCam, TCamTraits>::connect(int cameraId,

                                         constString16& clientPackageName,

                                              int clientUid)

{

   // 上层模板实例是Camera,因此这儿TCam就是 Camera

    ALOGV("%s: connect",__FUNCTION__);

 

//模板实例是一个Camera,因此c是一个Camera对象

 

    sp<TCam> c = new TCam(cameraId);

 

    sp<TCamCallbacks> cl = c;

 

    constsp<ICameraService>& cs = getCameraService();

 

  //这儿getCameraService 返回的是一个BpCameraService对象,并将一个BpBinder

    // 对象赋值给BpCameraService对象的成员变量mRemote,

     //这些是通过getCameraService调用defaultServiceManager()interface_cast函数来实现的

 

    if (cs != 0) {  // mCamera定义在 CameraBase类中

 

       c->mCamera =cs->connect(cl, cameraId, clientPackageName, clientUid);

 

// 这里 cs->connect返回的是一个BpCamera对象,因此 c->mCamera保存的是一个BpCamera对象。

//  BpCamera也有一个mRemote对象,也指向一个BpBinder对象(看下面BpCameraService::connect

//  这个BpBinder就是依据reply中得到的BnBinderBnCameraService)生成的对应的本地接口BpBinder),

//  也就是说在这儿得到Serviceresponse.

 

    }

    if (c->mCamera != 0) {

       c->mCamera->asBinder()->linkToDeath(c);

        c->mStatus = NO_ERROR;

    } else {

        c.clear();

    }

    return c;

}

4.2getCameraService

// establishbinder interface to camera service

template<typename TCam, typename TCamTraits>

constsp<ICameraService>& CameraBase<TCam,TCamTraits>::getCameraService()

{

    Mutex::Autolock _l(gLock);

    if (gCameraService.get() == 0) {

       sp<IServiceManager>sm = defaultServiceManager();

// sm是一个BpServiceManager, 并且BpServiceManagermRemote成员变量

// 将指向一个BpBinder(handle = 0), 0代表 ServiceManager.

        sp<IBinder> binder;

        do {

//这儿从getService()返回的binder是一个BpBinder对象.服务端返回的

//是一个BnCameraService之类的BnBinder对象,客户端在checkService

//将通过readStrongBinder来依据这个BnBinder对象来生成本地接口BpBinder对象。

 

           binder =sm->getService(String16(kCameraServiceName));

            if (binder != 0) {

                break;

            }

            ALOGW("CameraService notpublished, waiting...");

            usleep(kCameraServicePollDelay);

        } while(true);

        if (gDeathNotifier == NULL) {

            gDeathNotifier = newDeathNotifier();

        }

        binder->linkToDeath(gDeathNotifier);

// interface_cast函数将生成一个BpCameraService对象,并把binder(BpBinder对象)

//赋值给mRemote成员变量,gCameraService是一个BpCameraService对象。

       gCameraService= interface_cast<ICameraService>(binder);

    }

    ALOGE_IF(gCameraService == 0, "noCameraService!?");

    return gCameraService;

}

 

首先取得跨进程的IServiceManager,然后取得camera service(这个servicemediaserver启动时注册)。最重要的,把这个返回的binder对象经过interface_cast<ICameraService>处理,生成一个BpCameraService对象,并将binder对象赋值给BpCameraService的成员变量mRemote. Interface_cast frameworks/native/include/binder/IInterface.h中实现。

 

namespaceandroid {

 

//----------------------------------------------------------------------

 

class IInterface: public virtual RefBase

{

public:

            IInterface();

            sp<IBinder>         asBinder();

            sp<const IBinder>   asBinder() const;

           

protected:

    virtual                     ~IInterface();

    virtual IBinder*            onAsBinder() = 0;

};

 

//----------------------------------------------------------------------

 

template<typenameINTERFACE>

inlinesp<INTERFACE> interface_cast(const sp<IBinder>& obj)

{

    return INTERFACE::asInterface(obj);

}

 

//----------------------------------------------------------------------

 

template<typenameINTERFACE>

classBnInterface : public INTERFACE, public BBinder

{

public:

    virtual sp<IInterface>      queryLocalInterface(const String16&_descriptor);

    virtual const String16&     getInterfaceDescriptor() const;

 

protected:

    virtual IBinder*            onAsBinder();

};

 

//----------------------------------------------------------------------

 

template<typenameINTERFACE>

classBpInterface : public INTERFACE, public BpRefBase

{

public:

                               BpInterface(const sp<IBinder>& remote);

 

protected:

    virtual IBinder*            onAsBinder();

};

 

//----------------------------------------------------------------------

 

#defineDECLARE_META_INTERFACE(INTERFACE)                               \

    static const android::String16descriptor;                          \

    static android::sp<I##INTERFACE>asInterface(                       \

            constandroid::sp<android::IBinder>& obj);                  \

    virtual const android::String16&getInterfaceDescriptor() const;    \

    I##INTERFACE();                                                    \

    virtual ~I##INTERFACE();                                            \

 

 

#defineIMPLEMENT_META_INTERFACE(INTERFACE, NAME)                       \

    const android::String16 I##INTERFACE::descriptor(NAME);             \

    const android::String16&                                            \

           I##INTERFACE::getInterfaceDescriptor() const {              \

        return I##INTERFACE::descriptor;                                \

    }                                                                  \

    android::sp<I##INTERFACE>I##INTERFACE::asInterface(               \

            constandroid::sp<android::IBinder>& obj)                   \

    {                                                                   \

        android::sp<I##INTERFACE>intr;                                 \

        if (obj != NULL) {                                              \

           intr =static_cast<I##INTERFACE*>(                          \

               obj->queryLocalInterface(                               \

                       I##INTERFACE::descriptor).get());               \

            if (intr == NULL) {                                         \

               intr =new Bp##INTERFACE(obj);                         \

            }                                                          \

        }                                                              \

        return intr;                                                    \

    }                                                                  \

    I##INTERFACE::I##INTERFACE() { }                                    \

    I##INTERFACE::~I##INTERFACE() { }                                   \

 

 

#define CHECK_INTERFACE(interface,data, reply)                         \

    if (!data.checkInterface(this)) { returnPERMISSION_DENIED; }       \

 

 

//----------------------------------------------------------------------

// Nouser-serviceable parts after this...

 

template<typenameINTERFACE>

inlinesp<IInterface> BnInterface<INTERFACE>::queryLocalInterface(

        const String16& _descriptor)

{

    if (_descriptor == INTERFACE::descriptor)return this;

    return NULL;

}

 

template<typenameINTERFACE>

inline const String16&BnInterface<INTERFACE>::getInterfaceDescriptor() const

{

    return INTERFACE::getInterfaceDescriptor();

}

 

template<typenameINTERFACE>

IBinder*BnInterface<INTERFACE>::onAsBinder()

{

    return this;

}

 

template<typenameINTERFACE>

inlineBpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote)

    : BpRefBase(remote)

{

}

 

template<typenameINTERFACE>

inline IBinder*BpInterface<INTERFACE>::onAsBinder()

{

    return remote();

}

   

//----------------------------------------------------------------------

 

}; // namespaceandroid

 

5.   frameworks/av/camera/ICameraService.cpp

5.1  BpCameraService::connect

c->mCamera = cs->connect(cl, cameraId,clientPackageName, clientUid);

由于cs是经过interace_cast得到的BpCameraService,因此实际调用 BpCameraService::connect.

 

    // connect to camera service

    virtual sp<ICamera> BpCameraService::connect(constsp<ICameraClient>& cameraClient, int cameraId,

                                const String16&clientPackageName, int clientUid)

    {

        Parcel data, reply;

       data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());

       data.writeStrongBinder(cameraClient->asBinder());

        data.writeInt32(cameraId);

        data.writeString16(clientPackageName);

        data.writeInt32(clientUid);

       remote()->transact(BnCameraService::CONNECT, data, &reply);

       returninterface_cast<ICamera>(reply.readStrongBinder());

 

       // 这里又一次用到了interface_cast,interface_cast里,

// 将生成一个newBpCamera(binder object)

// 客户端将从reply中得到的服务端CameraClient对象,

// readStrongBinder()生成的相应的本地接口BpBinder对象。

       // in BpCamera构造函数里,实际上是通过其基类BpRefBase的构造函数,

//(CameraClient继承自BnCameraClientBnCameraClient继承自BBinder)

// 将这个本地接口(BpBinder)赋值给mRemote成员变量,也就是说BpCamera对象的mRemote

// 员变量实际上指向从服务器端返回的CameraClient对象向对应的BpBinder本地接口对象

// 这样在BpCamera BnCamera之间建立了一一对应的关系。Camera后面的操作,

// startPreview等就基于这个对应关系进行binder通讯

 

// BpRefBase::BpRefBase(const sp<IBinder>& o)
//     : mRemote(o.get()), mRefs(NULL), mState(0)
// {
//     extendObjectLifetime(OBJECT_LIFETIME_WEAK);

//    if (mRemote) {
//       mRemote->incStrong(this);          // Removed on first IncStrong().
//        mRefs =mRemote->createWeak(this);  // Held for our entire lifetime.
//    }
//}

 

 

    }

这里remote()函数返回的是mRemote成员变量,它指向一个BpBinder对象。

因此remote()->transact()实际上调用的是BpBinder::transact()

 

 

6.   frameworks/native/libs/binder/BpBinder.cpp

6.1  BpBinder::transact

 

status_tBpBinder::transact(

    uint32_t code, const Parcel& data,Parcel* reply, uint32_t flags)

{

    // Once a binder has died, it will nevercome 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;

}

 

7.   frameworks/native/libs/binder/IPCThreadState.cpp

7.1 IPCThreadState::transact

写数据到binderdriver

status_tIPCThreadState::transact(int32_t handle,

                                  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(">>>> SENDfrom pid %d uid %d %s", getpid(), getuid(),

            (flags & TF_ONE_WAY) == 0 ?"READ REPLY" : "ONE WAY");

       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 << "(nonerequested)" << endl;

        }

    } else {

        err = waitForResponse(NULL, NULL);

    }

   

    return err;

}

 

7.2  IPCThreadState::writeTransactionData

 

status_tIPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags,

    int32_t handle, uint32_t code, const Parcel&data, status_t* statusBuffer)

{

    binder_transaction_data tr;

 

   tr.target.handle =handle;  // handle 标识目的端,其中0标识ServiceManager

    tr.code = code;

    tr.flags = binderFlags;

    tr.cookie = 0;

    tr.sender_pid = 0;

    tr.sender_euid = 0;

   

    const status_t err = data.errorCheck();

    if (err == NO_ERROR) {

        tr.data_size = data.ipcDataSize();

        tr.data.ptr.buffer = data.ipcData();

        tr.offsets_size =data.ipcObjectsCount()*sizeof(size_t);

        tr.data.ptr.offsets = data.ipcObjects();

    } else if (statusBuffer) {

        tr.flags |= TF_STATUS_CODE;

        *statusBuffer = err;

        tr.data_size = sizeof(status_t);

        tr.data.ptr.buffer = statusBuffer;

        tr.offsets_size = 0;

        tr.data.ptr.offsets = NULL;

    } else {

        return (mLastError = err);

    }

 

   // mIn, mOut是连个Parcel对象,发送和接收命令缓冲区。

   // 每个IPCThreadState都有一个mIn, mOutmIn是用来接收从binder设备

//来的数据,而mOut是用来存储发往binder设备的数据。

//写命令到缓冲区

    mOut.writeInt32(cmd);

    mOut.write(&tr, sizeof(tr));

   

    return NO_ERROR;

}

 

 

 

 

7.3  IPCThreadState:: waitForResponse

 

发送请求与接收响应

status_tIPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)

{

    int32_t cmd;

    int32_t err;

 

    while (1) {

       if((err=talkWithDriver()) < NO_ERROR) break;

        err = mIn.errorCheck();

        if (err < NO_ERROR) break;

        if (mIn.dataAvail() == 0) continue;

       

        cmd = mIn.readInt32();

       

        IF_LOG_COMMANDS() {

            alog << "ProcessingwaitForResponse Command: "

                << getReturnString(cmd)<< endl;

        }

 

        switch (cmd) {

        case BR_TRANSACTION_COMPLETE:

            if (!reply &&!acquireResult) goto finish;

            break;

       

        case BR_DEAD_REPLY:

            err = DEAD_OBJECT;

            goto finish;

 

        case BR_FAILED_REPLY:

            err = FAILED_TRANSACTION;

            goto finish;

       

        case BR_ACQUIRE_RESULT:

            {

                ALOG_ASSERT(acquireResult !=NULL, "Unexpected brACQUIRE_RESULT");

                const int32_t result =mIn.readInt32();

                if (!acquireResult) continue;

                *acquireResult = result ?NO_ERROR : INVALID_OPERATION;

            }

            goto finish;

       

        case BR_REPLY:

            {

                binder_transaction_data tr;

                err = mIn.read(&tr,sizeof(tr));

                ALOG_ASSERT(err == NO_ERROR,"Not enough command data for brREPLY");

                if (err != NO_ERROR) gotofinish;

 

                if (reply) {

                    if ((tr.flags &TF_STATUS_CODE) == 0) {

                       reply->ipcSetDataReference(

                           reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),

                            tr.data_size,

                           reinterpret_cast<const size_t*>(tr.data.ptr.offsets),

                           tr.offsets_size/sizeof(size_t),

                            freeBuffer, this);

                    } else {

                        err =*static_cast<const status_t*>(tr.data.ptr.buffer);

                        freeBuffer(NULL,

                           reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),

                            tr.data_size,

                            reinterpret_cast<constsize_t*>(tr.data.ptr.offsets),

                           tr.offsets_size/sizeof(size_t), this);

                    }

                } else {

                    freeBuffer(NULL,

                        reinterpret_cast<constuint8_t*>(tr.data.ptr.buffer),

                        tr.data_size,

                       reinterpret_cast<const size_t*>(tr.data.ptr.offsets),

                       tr.offsets_size/sizeof(size_t), this);

                    continue;

                }

            }

            goto finish;

 

        default:

           err =executeCommand(cmd);

            if (err != NO_ERROR) goto finish;

            break;

        }

    }

 

finish:

    if (err != NO_ERROR) {

        if (acquireResult) *acquireResult =err;

        if (reply) reply->setError(err);

        mLastError = err;

    }

   

    return err;

}

 

7.4  IPCThreadState:: talkWithDriver

 

IPCThreadState:: talkWithDriver

status_tIPCThreadState::talkWithDriver(bool doReceive)

{

    if (mProcess->mDriverFD <= 0) {

        return -EBADF;

    }

   

    binder_write_read bwr;

   

    // Is the read buffer empty?

    const bool needRead = mIn.dataPosition()>= mIn.dataSize();

   

    // We don't want to write anything if weare still reading

    // from data left in the input buffer andthe caller

    // has requested to read the next data.

    const size_t outAvail = (!doReceive ||needRead) ? mOut.dataSize() : 0;

   

    bwr.write_size = outAvail;

    bwr.write_buffer = (long unsignedint)mOut.data();

 

    // This is what we'll read.

    if (doReceive && needRead) {

        bwr.read_size = mIn.dataCapacity();

        bwr.read_buffer = (long unsignedint)mIn.data();

    } else {

        bwr.read_size = 0;

        bwr.read_buffer = 0;

    }

 

    IF_LOG_COMMANDS() {

        TextOutput::Bundle _b(alog);

        if (outAvail != 0) {

            alog << "Sendingcommands to driver: " << indent;

            const void* cmds = (constvoid*)bwr.write_buffer;

            const void* end = ((constuint8_t*)cmds)+bwr.write_size;

            alog << HexDump(cmds,bwr.write_size) << endl;

            while (cmds < end) cmds =printCommand(alog, cmds);

            alog << dedent;

        }

        alog << "Size of receivebuffer: " << bwr.read_size

            << ", needRead: "<< needRead << ", doReceive: " << doReceive<< endl;

    }

   

    // Return immediately if there is nothingto do.

    if ((bwr.write_size == 0) &&(bwr.read_size == 0)) return NO_ERROR;

 

    bwr.write_consumed = 0;

    bwr.read_consumed = 0;

    status_t err;

    do {

        IF_LOG_COMMANDS() {

            alog << "About toread/write, write size = " << mOut.dataSize() << endl;

        }

#if defined(HAVE_ANDROID_OS)

       if(ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)

            err = NO_ERROR;

        else

            err = -errno;

#else

        err = INVALID_OPERATION;

#endif

        if (mProcess->mDriverFD <= 0) {

            err = -EBADF;

        }

        IF_LOG_COMMANDS() {

            alog << "Finishedread/write, write size = " << mOut.dataSize() << endl;

        }

    } while (err == -EINTR);

 

    IF_LOG_COMMANDS() {

        alog << "Our err: "<< (void*)err << ", write consumed: "

            << bwr.write_consumed<< " (of " << mOut.dataSize()

                           << "),read consumed: " << bwr.read_consumed << endl;

    }

 

    if (err >= NO_ERROR) {

        if (bwr.write_consumed > 0) {

            if (bwr.write_consumed <(ssize_t)mOut.dataSize())

                mOut.remove(0,bwr.write_consumed);

            else

                mOut.setDataSize(0);

        }

        if (bwr.read_consumed > 0) {

            mIn.setDataSize(bwr.read_consumed);

            mIn.setDataPosition(0);

        }

        IF_LOG_COMMANDS() {

            TextOutput::Bundle _b(alog);

            alog << "Remaining datasize: " << mOut.dataSize() << endl;

            alog << "Receivedcommands from driver: " << indent;

            const void* cmds = mIn.data();

            const void* end = mIn.data() +mIn.dataSize();

            alog << HexDump(cmds,mIn.dataSize()) << endl;

            while (cmds < end) cmds =printReturnCommand(alog, cmds);

            alog << dedent;

        }

        return NO_ERROR;

    }

   

    return err;

}

 

7.5  IPCThreadState:: executeCommand

现在假设请求后得到回复响应

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_OK:

        break;

       

    case BR_ACQUIRE:

        refs =(RefBase::weakref_type*)mIn.readInt32();

        obj = (BBinder*)mIn.readInt32();

        ALOG_ASSERT(refs->refBase() == obj,

                   "BR_ACQUIRE: object %pdoes not match cookie %p (expected %p)",

                   refs, obj,refs->refBase());

        obj->incStrong(mProcess.get());

        IF_LOG_REMOTEREFS() {

            LOG_REMOTEREFS("BR_ACQUIREfrom driver on %p", obj);

            obj->printRefs();

        }

        mOut.writeInt32(BC_ACQUIRE_DONE);

        mOut.writeInt32((int32_t)refs);

        mOut.writeInt32((int32_t)obj);

        break;

       

    case BR_RELEASE:

        refs = (RefBase::weakref_type*)mIn.readInt32();

        obj = (BBinder*)mIn.readInt32();

        ALOG_ASSERT(refs->refBase() == obj,

                   "BR_RELEASE: object %pdoes not match cookie %p (expected %p)",

                   refs, obj,refs->refBase());

        IF_LOG_REMOTEREFS() {

            LOG_REMOTEREFS("BR_RELEASEfrom driver on %p", obj);

            obj->printRefs();

        }

        mPendingStrongDerefs.push(obj);

        break;

       

    case BR_INCREFS:

        refs =(RefBase::weakref_type*)mIn.readInt32();

        obj = (BBinder*)mIn.readInt32();

        refs->incWeak(mProcess.get());

        mOut.writeInt32(BC_INCREFS_DONE);

        mOut.writeInt32((int32_t)refs);

        mOut.writeInt32((int32_t)obj);

        break;

       

    case BR_DECREFS:

        refs =(RefBase::weakref_type*)mIn.readInt32();

        obj = (BBinder*)mIn.readInt32();

        // NOTE: This assertion is not valid,because the object may no

        // longer exist (thus the(BBinder*)cast above resulting in a different

        // memory address).

        //ALOG_ASSERT(refs->refBase() ==obj,

        //           "BR_DECREFS: object %p does notmatch cookie %p (expected %p)",

        //           refs, obj, refs->refBase());

        mPendingWeakDerefs.push(refs);

        break;

       

    case BR_ATTEMPT_ACQUIRE:

        refs =(RefBase::weakref_type*)mIn.readInt32();

        obj = (BBinder*)mIn.readInt32();

        

        {

            const bool success =refs->attemptIncStrong(mProcess.get());

            ALOG_ASSERT(success &&refs->refBase() == obj,

                      "BR_ATTEMPT_ACQUIRE: object %p does not match cookie %p (expected%p)",

                       refs, obj,refs->refBase());

           

            mOut.writeInt32(BC_ACQUIRE_RESULT);

            mOut.writeInt32((int32_t)success);

        }

        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_TRANSACTIONthr " << (void*)pthread_self()

                    << " / obj" << tr.target.ptr << " / code "

                    << TypeCode(tr.code)<< ": " << indent << buffer

                    << dedent <<endl

                    << "Data addr ="

                    << reinterpret_cast<constuint8_t*>(tr.data.ptr.buffer)

                    << ", offsetsaddr="

                    <<reinterpret_cast<const size_t*>(tr.data.ptr.offsets) << endl;

            }

            if (tr.target.ptr) {

// registered CameraService object, CameraServiceinherit from BBinder

               sp<BBinder> b((BBinder*)tr.cookie);

               conststatus_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_REPLY thr" << (void*)pthread_self() << " / obj "

                    << tr.target.ptr<< ": " << indent << reply << dedent <<endl;

            }

           

        }

        break;

   

    case BR_DEAD_BINDER:

        {

            BpBinder *proxy =(BpBinder*)mIn.readInt32();

            proxy->sendObituary();

           mOut.writeInt32(BC_DEAD_BINDER_DONE);

            mOut.writeInt32((int32_t)proxy);

        } break;

       

    case BR_CLEAR_DEATH_NOTIFICATION_DONE:

        {

            BpBinder *proxy =(BpBinder*)mIn.readInt32();

           proxy->getWeakRefs()->decWeak(proxy);

        } break;

       

    case BR_FINISHED:

        result = TIMED_OUT;

        break;

       

    case BR_NOOP:

        break;

        

    case BR_SPAWN_LOOPER:

        mProcess->spawnPooledThread(false);

        break;

       

    default:

        printf("*** BAD COMMAND %dreceived from Binder driver\n", cmd);

        result = UNKNOWN_ERROR;

        break;

    }

 

    if (result != NO_ERROR) {

        mLastError = result;

    }

   

    return result;

}

 

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值