Android Camera Subsystem - Open - 02

来源:互联网 发布:动作片 知乎 编辑:程序博客网 时间:2024/06/04 17:47

 

 

 

8.   frameworks/native/libs/binder/Binder.cpp

由于上述b->transact()b的实际对象是CameraServiceCameraService inherit from BBinder,因此调用 BBinder::transact() ===CameraService::onTransact()

因为CameraService没有重写BBinder::transact,所以b->transact()实际调用的就是BBinder::transact

status_tBBinder::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);

           //因为CameraService重写了onTransact,

//因此调用CameraService::onTransact()

            break;

    }

 

    if (reply != NULL) {

        reply->setDataPosition(0);

    }

 

    return err;

}

 

 

9.   frameworks/av/services/camera/libcameraservice/CameraService.cpp

status_tCameraService::onTransact(

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

    // Permission checks

    switch (code) {

        case BnCameraService::CONNECT:

        case BnCameraService::CONNECT_PRO:

            const int pid = getCallingPid();

            const int self_pid = getpid();

            if (pid != self_pid) {

                // we're called from adifferent process, do the real check

                if (!checkCallingPermission(

                        String16("android.permission.CAMERA"))){

                    const int uid =getCallingUid();

                    ALOGE("PermissionDenial: "

                         "can't use thecamera pid=%d, uid=%d", pid, uid);

                    return PERMISSION_DENIED;

                }

            }

            break;

    }

 

   returnBnCameraService::onTransact(code, data, reply, flags);

}

 

 

 

 

 

10.  frameworks/av/ camera/ICameraService.cpp

10.1  BnCameraService::onTransact

status_tBnCameraService::onTransact(

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

{

    switch(code) {

        case GET_NUMBER_OF_CAMERAS: {

            CHECK_INTERFACE(ICameraService,data, reply);

           reply->writeInt32(getNumberOfCameras());

            return NO_ERROR;

        } break;

        case GET_CAMERA_INFO: {

            CHECK_INTERFACE(ICameraService,data, reply);

            CameraInfo cameraInfo;

            memset(&cameraInfo, 0,sizeof(cameraInfo));

            status_t result = getCameraInfo(data.readInt32(),&cameraInfo);

           reply->writeInt32(cameraInfo.facing);

           reply->writeInt32(cameraInfo.orientation);

            reply->writeInt32(result);

            return NO_ERROR;

        } break;

        case CONNECT: {

            CHECK_INTERFACE(ICameraService, data,reply);

            sp<ICameraClient>cameraClient =

                   interface_cast<ICameraClient>(data.readStrongBinder());

            int32_t cameraId =data.readInt32();

            const String16 clientName =data.readString16();

            int32_t clientUid =data.readInt32();

           sp<ICamera> camera = connect(cameraClient, cameraId,

                   clientName, clientUid);  //真正的处理函数

 

// connect返回一个CameraClient对象,也就是camera是一个CameraClient对象,

//并作为replybinder对象返回给客户端

 

           reply->writeStrongBinder(camera->asBinder());

            return NO_ERROR;

        } break;

        case CONNECT_PRO: {

            CHECK_INTERFACE(ICameraService,data, reply);

            sp<IProCameraCallbacks>cameraClient = interface_cast<IProCameraCallbacks>(data.readStrongBinder());

            int32_t cameraId =data.readInt32();

            const String16 clientName =data.readString16();

            int32_t clientUid =data.readInt32();

            sp<IProCameraUser> camera =connect(cameraClient, cameraId,

                                               clientName, clientUid);

           reply->writeStrongBinder(camera->asBinder());

            return NO_ERROR;

        } break;

        case ADD_LISTENER: {

            CHECK_INTERFACE(ICameraService,data, reply);

            sp<ICameraServiceListener>listener =

               interface_cast<ICameraServiceListener>(data.readStrongBinder());

           reply->writeInt32(addListener(listener));

            return NO_ERROR;

        } break;

        case REMOVE_LISTENER: {

            CHECK_INTERFACE(ICameraService,data, reply);

            sp<ICameraServiceListener>listener =

               interface_cast<ICameraServiceListener>(data.readStrongBinder());

           reply->writeInt32(removeListener(listener));

            return NO_ERROR;

        } break;

        default:

            return BBinder::onTransact(code,data, reply, flags);

    }

}

 

11.  frameworks/av/ services/camera/libcameraservice/CameraService.cpp

仍然由于b->transact()b的实际对象是CameraService,connect虚拟方法已经被CameraService改写,因此上述sp<ICamera> camera = connect(cameraClient,cameraId,

clientName, clientUid); //真正的处理函数 实际调用的是CameraServiceconnect函数

11.1  CameraService::connect

sp<ICamera>CameraService::connect(

        const sp<ICameraClient>&cameraClient,

        int cameraId,

        const String16& clientPackageName,

        int clientUid) {

 

    String8 clientName8(clientPackageName);

    int callingPid = getCallingPid();

 

    LOG1("CameraService::connect E (pid %d\"%s\", id %d)", callingPid,

            clientName8.string(), cameraId);

 

    if (!validateConnect(cameraId,/*inout*/clientUid)) {

        return NULL;

    }

 

//这里由于是在CameraService内部,ClientCameraService的一个内部内

//因此这儿 sp<Client>client等价于sp<CameraService::Client> client;

    sp<Client> client;

 

    {

        Mutex::Autolock lock(mServiceLock);

        if (!canConnectUnsafe(cameraId,clientPackageName,

                             cameraClient->asBinder(),

                              /*out*/client)) {

            return NULL;

        } else if (client.get() != NULL) {

            return client;

        }

 

        int facing = -1;

        int deviceVersion =getDeviceVersion(cameraId, &facing);

 

        // If there are other non-exclusiveusers 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);

        }

 

// class CameraClient : public CameraService::Client

// clas CameraService::Client : public BnCamera, publicBasicClient

// class BnCamera: public BnInterface<ICamera>

// class BnInterface : public INTERFACE, public BBinder

        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 NULL;

          default:

            ALOGE("Unknown camera deviceHAL version: %d", deviceVersion);

            return NULL;

        }

 

        if (!connectFinishUnsafe(client,client->asBinder())) {

            // this is probably notrecoverable.. maybe the client can try again

            // OK: we can only get here if wewere originally in PRESENT state

            updateStatus(ICameraServiceListener::STATUS_PRESENT,cameraId);

 

            return NULL;

        }

 

        mClient[cameraId] = client;

        LOG1("CameraService::connect X (id%d, this pid is %d)", cameraId,

             getpid());

    }

    // important: release the mutex here so theclient can call back

    //   into the service from its destructor (can be at the end of the call)

 

    return client;  // 返回一个CameraClient 或 Camera2Client对象

}

 

 

 

 

 

IPCThreadState::joinThreadPool

从设备中读出数据并执行相应命令

voidIPCThreadState::joinThreadPool(bool isMain)

{

    LOG_THREADPOOL("**** THREAD %p (PID%d) IS JOINING THE THREAD POOL\n", (void*)pthread_self(), getpid());

 

    mOut.writeInt32(isMain ? BC_ENTER_LOOPER :BC_REGISTER_LOOPER);

   

    // This thread may have been spawned by athread that was in the background

    //scheduling group, so first we will make sure it is in the foreground

    // one to avoid performing an initialtransaction in the background.

    set_sched_policy(mMyThreadId,SP_FOREGROUND);

       

    status_t result;

    do {

        int32_t cmd;

       

        // When we've cleared the incomingcommand queue, process any pending derefs

        if (mIn.dataPosition() >=mIn.dataSize()) {

            size_t numPending =mPendingWeakDerefs.size();

            if (numPending > 0) {

                for (size_t i = 0; i < numPending; i++) {

                    RefBase::weakref_type* refs= mPendingWeakDerefs[i];

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

                }

                mPendingWeakDerefs.clear();

            }

 

            numPending =mPendingStrongDerefs.size();

            if (numPending > 0) {

                for (size_t i = 0; i <numPending; i++) {

                    BBinder* obj =mPendingStrongDerefs[i];

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

                }

                mPendingStrongDerefs.clear();

            }

        }

 

        // now get the next command to beprocessed, waiting if necessary

       result =talkWithDriver();  //读出写入的数据包

        if (result >= NO_ERROR) {

            size_t IN = mIn.dataAvail();

            if (IN < sizeof(int32_t))continue;

           cmd =mIn.readInt32();

            IF_LOG_COMMANDS() {

                alog << "Processingtop-level Command: "

                    <<getReturnString(cmd) << endl;

            }

 

 

            result = executeCommand(cmd);  // 执行命令

        } else if (result != TIMED_OUT&& result != -ECONNREFUSED && result != -EBADF) {

            ALOGE("talkWithDriver(fd=%d)returned unexpected error %d, aborting",

                  mProcess->mDriverFD,result);

            abort();

        }

       

        // After executing the command, ensurethat the thread is returned to the

        // foreground cgroup before rejoiningthe pool.  The driver takes care of

        // restoring the priority, but doesn'tdo anything with cgroups so we

        // need to take care of that here inuserspace.  Note that we do make

        // sure to go in the foreground afterexecuting a transaction, but

        // there are other callbacks into usercode that could have changed

        // our group so we want to makeabsolutely sure it is put back.

        set_sched_policy(mMyThreadId,SP_FOREGROUND);

 

        // Let this thread exit the thread poolif it is no longer

        // needed and it is not the mainprocess thread.

        if(result == TIMED_OUT &&!isMain) {

            break;

        }

    } while (result != -ECONNREFUSED &&result != -EBADF);

 

    LOG_THREADPOOL("**** THREAD %p (PID%d) IS LEAVING THE THREAD POOL err=%p\n",

        (void*)pthread_self(), getpid(),(void*)result);

   

    mOut.writeInt32(BC_EXIT_LOOPER);

    talkWithDriver(false);

}

 

 

 

 

原创粉丝点击