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

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

更多资源:

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

initializeproviderinfocommon

initializeproviderinfocommon主要完成2件事情:

  1. 调用adddevice将cameradevice保持在mdevices中
  2. 处理cached status回调

前面的课程已经介绍了adddevice的逻辑,本讲介绍处理cached status回调

initializeproviderinfocommon

什么时候会有cache status

  • 在cameraserver初始化provider过程中,hal通知发生了physicalcameradevicestatuschange 或 cameradevicestatuschange

process cache status callbacks

process cache status callbacks

上面流程的逻辑来自android 13:

// process cached status callbacks
std::unique_ptr> cachedstatus =
        std::make_unique>();
{
    std::lock_guard lock(minitlock);
    for (auto& statusinfo : mcachedstatus) {
        std::string id, physicalid;
        status_t res = ok;
        if (statusinfo.isphysicalcamerastatus) {
            res = physicalcameradevicestatuschangelocked(&id, &physicalid,
                statusinfo.cameraid, statusinfo.physicalcameraid, statusinfo.status);
        } else {
            res = cameradevicestatuschangelocked(&id, statusinfo.cameraid, statusinfo.status);
        }
        if (res == ok) {
            cachedstatus->emplace_back(statusinfo.isphysicalcamerastatus,
                    id.c_str(), physicalid.c_str(), statusinfo.status);
        }
    }
    mcachedstatus.clear();
    minitialized = true;
}
// the cached status change callbacks cannot be fired directly from this
// function, due to same-thread deadlock trying to acquire minterfacemutex
// twice.
if (listener != nullptr) {
    minitialstatuscallbackfuture = std::async(std::launch::async,
            &cameraprovidermanager::providerinfo::notifyinitialstatuschange, this,
            listener, std::move(cachedstatus));
}

physicalcameradevicestatuschangelocked

physicalcameradevicestatuschangelocked

上面流程的逻辑来自android 13:

status_t cameraprovidermanager::providerinfo::physicalcameradevicestatuschangelocked(
            std::string* id, std::string* physicalid,
            const std::string& cameradevicename,
            const std::string& physicalcameradevicename,
            cameradevicestatus newstatus) {
    bool known = false;
    std::string cameraid;
    for (auto& deviceinfo : mdevices) {
        if (deviceinfo->mname == cameradevicename) {
            cameraid = deviceinfo->mid;
            if (!deviceinfo->mislogicalcamera) {
                aloge("%s: invalid combination of camera id %s, physical id %s",
                        __function__, cameraid.c_str(), physicalcameradevicename.c_str());
                return bad_value;
            }
            if (std::find(deviceinfo->mphysicalids.begin(), deviceinfo->mphysicalids.end(),
                    physicalcameradevicename) == deviceinfo->mphysicalids.end()) {
                aloge("%s: invalid combination of camera id %s, physical id %s",
                        __function__, cameraid.c_str(), physicalcameradevicename.c_str());
                return bad_value;
            }
            alogi("camera device %s physical device %s status is now %s",
                    cameradevicename.c_str(), physicalcameradevicename.c_str(),
                    frameworkdevicestatustostring(newstatus));
            known = true;
            break;
        }
    }
    // previously unseen device; status must not be not_present
    if (!known) {
        alogw("camera provider %s says an unknown camera device %s-%s is not present. curious.",
                mprovidername.c_str(), cameradevicename.c_str(),
                physicalcameradevicename.c_str());
        return bad_value;
    }
    *id = cameraid;
    *physicalid = physicalcameradevicename.c_str();
    return ok;
}

physical ondevicestatuschanged

关于systemcamerakind的说明如下:

systemcamerakind description
public 所有拥有camera权限的进程可使用
system_only_camera 三方app不可用,且必须有system_camera权限
hidden_secure_camera 只给vendor client(hal进程)使用

physical ondevicestatuschanged

上面流程的逻辑来自android 13:

void cameraservice::ondevicestatuschanged(const string8& id,
        const string8& physicalid,
        cameradevicestatus newhalstatus) {
    alogi("%s: status changed for cameraid=%s, physicalcameraid=%s, newstatus=%d",
            __function__, id.string(), physicalid.string(), newhalstatus);
    statusinternal newstatus = maptointernal(newhalstatus);
    std::shared_ptr state = getcamerastate(id);
    if (state == nullptr) {
        aloge("%s: physical camera id %s status change on a non-present id %s",
                __function__, id.string(), physicalid.string());
        return;
    }
    statusinternal logicalcamerastatus = state->getstatus();
    if (logicalcamerastatus != statusinternal::present &&
            logicalcamerastatus != statusinternal::not_available) {
        aloge("%s: physical camera id %s status %d change for an invalid logical camera state %d",
                __function__, physicalid.string(), newhalstatus, logicalcamerastatus);
        return;
    }
    bool updated = false;
    if (newstatus == statusinternal::present) {
        updated = state->removeunavailablephysicalid(physicalid);
    } else {
        updated = state->addunavailablephysicalid(physicalid);
    }
    if (updated) {
        string8 idcombo = id   " : "   physicalid;
        if (newstatus == statusinternal::present) {
            logdeviceadded(idcombo,
                    string8::format("device status changed to %d", newstatus));
        } else {
            logdeviceremoved(idcombo,
                    string8::format("device status changed to %d", newstatus));
        }
        // avoid calling getsystemcamerakind() with mstatuslistenerlock held (b/141756275)
        systemcamerakind devicekind = systemcamerakind::public;
        if (getsystemcamerakind(id, &devicekind) != ok) {
            aloge("%s: invalid camera id %s, skipping", __function__, id.string());
            return;
        }
        string16 id16(id), physicalid16(physicalid);
        mutex::autolock lock(mstatuslistenerlock);
        for (auto& listener : mlistenerlist) {
            if (shouldskipstatusupdates(devicekind, listener->isvendorlistener(),
                    listener->getlistenerpid(), listener->getlisteneruid())) {
                alogv("skipping discovery callback for system-only camera device %s",
                        id.c_str());
                continue;
            }
            listener->getlistener()->onphysicalcamerastatuschanged(maptointerface(newstatus),
                    id16, physicalid16);
        }
    }
}

camera课程

python教程

java教程

web教程

数据库教程

图形图像教程

办公软件教程

linux教程

计算机教程

大数据教程

开发工具教程

网站地图