第14讲 cameraserver进程启动之logicaldevicestatuschange详解 -凯发k8旗舰厅

本讲是android camera native framework专题的第14讲,我们介绍cameraserver进程启动之logicaldevicestatuschange。

更多资源:

资源 描述
在线课程
知识星球 星球名称:深入浅出android camera 星球id: 17296815
wechat 极客笔记圈

process cache status callbacks

本讲我们介绍logical cameradevice的status callback是逻辑。

process cache status callbacks

cameradevicestatuschangelocked

cameradevicestatuschangelocked

上述流程图来自android 13:

status_t cameraprovidermanager::providerinfo::cameradevicestatuschangelocked(
        std::string* id, const std::string& cameradevicename,
        cameradevicestatus newstatus) {
    bool known = false;
    std::string cameraid;
    for (auto& deviceinfo : mdevices) {
        if (deviceinfo->mname == cameradevicename) {
            mutex::autolock l(deviceinfo->mdeviceavailablelock);
            alogi("camera device %s status is now %s, was %s", cameradevicename.c_str(),
                    frameworkdevicestatustostring(newstatus),
                    frameworkdevicestatustostring(deviceinfo->mstatus));
            deviceinfo->mstatus = newstatus;
            // todo: handle device removal (not_present)
            cameraid = deviceinfo->mid;
            known = true;
            deviceinfo->misdeviceavailable =
                (newstatus == cameradevicestatus::present);
            deviceinfo->mdeviceavailablesignal.signal();
            break;
        }
    }
    // previously unseen device; status must not be not_present
    if (!known) {
        if (newstatus == cameradevicestatus::not_present) {
            alogw("camera provider %s says an unknown camera device %s is not present. curious.",
                mprovidername.c_str(), cameradevicename.c_str());
            return bad_value;
        }
        adddevice(cameradevicename, newstatus, &cameraid);
    } else if (newstatus == cameradevicestatus::not_present) {
        removedevice(cameraid);
    } else if (isexternallazyhal()) {
        // do not notify cameraservice for present->present (lazy hal restart)
        // because not_available is set on cameraservice::connect and a present
        // notif. would overwrite it
        return bad_value;
    }
    if (recacheconcurrentstreamingcameraidslocked() != ok) {
        aloge("%s: cameraprovider %s could not re-cache concurrent streaming camera id list ",
                  __function__, mprovidername.c_str());
    }
    *id = cameraid;
    return ok;
}

logical oncameradevicechanged

logical oncameradevicechanged

上述流程图来自android 13:

void cameraservice::ondevicestatuschanged(const string8& id,
        cameradevicestatus newhalstatus) {
    alogi("%s: status changed for cameraid=%s, newstatus=%d", __function__,
            id.string(), newhalstatus);
    statusinternal newstatus = maptointernal(newhalstatus);
    std::shared_ptr state = getcamerastate(id);
    if (state == nullptr) {
        if (newstatus == statusinternal::present) {
            alogi("%s: unknown camera id %s, a new camera is added",
                    __function__, id.string());
            // first add as absent to make sure clients are notified below
            addstates(id);
            updatestatus(newstatus, id);
        } else {
            aloge("%s: bad camera id %s", __function__, id.string());
        }
        return;
    }
    statusinternal oldstatus = state->getstatus();
    if (oldstatus == newstatus) {
        aloge("%s: state transition to the same status %#x not allowed", __function__, newstatus);
        return;
    }
    if (newstatus == statusinternal::not_present) {
        logdeviceremoved(id, string8::format("device status changed from %d to %d", oldstatus,
                newstatus));
        // set the device status to not_present, clients will no longer be able to connect
        // to this device until the status changes
        updatestatus(statusinternal::not_present, id);
        sp clienttodisconnectonline, clienttodisconnectoffline;
        {
            // don't do this in updatestatus to avoid deadlock over mservicelock
            mutex::autolock lock(mservicelock);
            // remove cached shim parameters
            state->setshimparams(cameraparameters());
            // remove online as well as offline client from the list of active clients,
            // if they are present
            clienttodisconnectonline = removeclientlocked(id);
            clienttodisconnectoffline = removeclientlocked(kofflinedevice   id);
        }
        disconnectclient(id, clienttodisconnectonline);
        disconnectclient(kofflinedevice   id, clienttodisconnectoffline);
        removestates(id);
    } else {
        if (oldstatus == statusinternal::not_present) {
            logdeviceadded(id, string8::format("device status changed from %d to %d", oldstatus,
                    newstatus));
        }
        updatestatus(newstatus, id);
    }
}

cameraservice::updatestatus

cameraservice::updatestatus

上述流程图来自android 13:

void cameraservice::updatestatus(statusinternal status, const string8& cameraid,
        std::initializer_list rejectsourcestates) {
    // do not lock mservicelock here or can get into a deadlock from
    // connect() -> disconnect -> updatestatus
    auto state = getcamerastate(cameraid);
    if (state == nullptr) {
        alogw("%s: could not update the status for %s, no such device exists", __function__,
                cameraid.string());
        return;
    }
    // avoid calling getsystemcamerakind() with mstatuslistenerlock held (b/141756275)
    systemcamerakind devicekind = systemcamerakind::public;
    if (getsystemcamerakind(cameraid, &devicekind) != ok) {
        aloge("%s: invalid camera id %s, skipping", __function__, cameraid.string());
        return;
    }
    // collect the logical cameras without holding mstatuslock in updatestatus
    // as that can lead to a deadlock(b/162192331).
    auto logicalcameraids = getlogicalcameras(cameraid);
    // update the status for this camera state, then send the onstatuschangedcallbacks to each
    // of the listeners with both the mstatuslock and mstatuslistenerlock held
    state->updatestatus(status, cameraid, rejectsourcestates, [this, &devicekind,
                        &logicalcameraids]
            (const string8& cameraid, statusinternal status) {
            if (status != statusinternal::enumerating) {
                // update torch status if it has a flash unit.
                mutex::autolock al(mtorchstatusmutex);
                torchmodestatus torchstatus;
                if (gettorchstatuslocked(cameraid, &torchstatus) !=
                        name_not_found) {
                    torchmodestatus newtorchstatus =
                            status == statusinternal::present ?
                            torchmodestatus::available_off :
                            torchmodestatus::not_available;
                    if (torchstatus != newtorchstatus) {
                        ontorchstatuschangedlocked(cameraid, newtorchstatus, devicekind);
                    }
                }
            }
            mutex::autolock lock(mstatuslistenerlock);
            notifyphysicalcamerastatuslocked(maptointerface(status), string16(cameraid),
                    logicalcameraids, devicekind);
            for (auto& listener : mlistenerlist) {
                bool isvendorlistener = listener->isvendorlistener();
                if (shouldskipstatusupdates(devicekind, isvendorlistener,
                        listener->getlistenerpid(), listener->getlisteneruid()) ||
                        isvendorlistener) {
                    alogv("skipping discovery callback for system-only camera device %s",
                            cameraid.c_str());
                    continue;
                }
                listener->getlistener()->onstatuschanged(maptointerface(status),
                        string16(cameraid));
            }
        });
}

cameraservice::addstates

cameraservice::addstates

上述流程图来自android 13:

void cameraservice::addstates(const string8 id) {
    std::string cameraid(id.c_str());
    cameraresourcecost cost;
    status_t res = mcameraprovidermanager->getresourcecost(cameraid, &cost);
    if (res != ok) {
        aloge("failed to query device resource cost: %s (%d)", strerror(-res), res);
        return;
    }
    systemcamerakind devicekind = systemcamerakind::public;
    res = mcameraprovidermanager->getsystemcamerakind(cameraid, &devicekind);
    if (res != ok) {
        aloge("failed to query device kind: %s (%d)", strerror(-res), res);
        return;
    }
    std::vector physicalcameraids;
    mcameraprovidermanager->islogicalcamera(cameraid, &physicalcameraids);
    std::set conflicting;
    for (size_t i = 0; i < cost.conflictingdevices.size(); i  ) {
        conflicting.emplace(string8(cost.conflictingdevices[i].c_str()));
    }
    {
        mutex::autolock lock(mcamerastateslock);
        mcamerastates.emplace(id, std::make_shared(id, cost.resourcecost,
                conflicting, devicekind, physicalcameraids));
    }
    if (mflashlight->hasflashunit(id)) {
        mutex::autolock al(mtorchstatusmutex);
        mtorchstatusmap.add(id, torchmodestatus::available_off);
        broadcasttorchmodestatus(id, torchmodestatus::available_off, devicekind);
    }
    updatecameranumandids();
    logdeviceadded(id, "device added");
}

cameraservice::removestates

cameraservice::removestates

上述流程图来自android 13:

void cameraservice::removestates(const string8 id) {
    updatecameranumandids();
    if (mflashlight->hasflashunit(id)) {
        mutex::autolock al(mtorchstatusmutex);
        mtorchstatusmap.removeitem(id);
    }
    {
        mutex::autolock lock(mcamerastateslock);
        mcamerastates.erase(id);
    }
}

camera课程

python教程

java教程

web教程

数据库教程

图形图像教程

办公软件教程

linux教程

计算机教程

大数据教程

开发工具教程

网站地图