基于Android Camera2 CameraServer启动流程分析

基于Android P版本分析

CameraServer启动模块图:

CameraServer启动时序图:

Android系统启动过程可以简单概括为两大步骤:

  1. Linux内核启动;
  2. Android架构启动;

Linux内核启动:

主要是bootLoader的启动和初始化驱动,安装文件系统等。在Linux内核启动的最后,会启动第一个用于进程init进程,它是所有用户进程的父进程,由此进入了Android架构的启动阶段;

Android架构启动:

init进程启动后会自动加载init.rc(/system/core/rootdir/init.rc)脚本,当执行mount_all指令挂在分区时,会加载包括system、vendor、odm等目录下的xxx/etc/init目录下的所有rc脚本;

cameraserver.rc

通过分析代码,我们发现在/frameworks/av/camera/目录下有一个cameraserver文件夹,里面有一个cameraserver.rc文件:

less 复制代码
// 通过init进程启动cameraserver进程,启动路径为/system/bin/cameraserver
service cameraserver /system/bin/cameraserver
    // 启动入口
    class main
    // 用户名
    user cameraserver
    // 分组
    group audio camera input drmrpc
    ioprio rt 4
    writepid /dev/cpuset/camera-daemon/tasks /dev/stune/top-app/tasks
    rlimit rtprio 10 10

在该文件中首先先定义了cameraserver的加载路径,然后定义启动入口、用户名以及分组等信息;

因为init进程会加载包括system、vendor、odm等目录下的xxx/etc/init目录下的所有rc脚本,所以cameraserver.rc也会被init进程加载,加载方式是通过在Android.mk文件中定义加载路径:

makefile 复制代码
LOCAL_PATH:= $(call my-dir)
​
include $(CLEAR_VARS)
​
LOCAL_SRC_FILES:= \
    main_cameraserver.cpp
​
LOCAL_SHARED_LIBRARIES := \
    libcameraservice \
    liblog \
    libutils \
    libui \
    libgui \
    libbinder \
    libhidltransport \
    android.hardware.camera.common@1.0 \
    android.hardware.camera.provider@2.4 \
    android.hardware.camera.device@1.0 \
    android.hardware.camera.device@3.2
​
LOCAL_MODULE:= cameraserver
LOCAL_32_BIT_ONLY := true
​
LOCAL_CFLAGS += -Wall -Wextra -Werror -Wno-unused-parameter
​
LOCAL_INIT_RC := cameraserver.rc
​
include $(BUILD_EXECUTABLE)

其中LOCAL_INIT_RC := cameraserver.rc将cameraserver.rc挂载到/system/etc/init目录中,这样init.rc就可以调用cameraserver.rc;

Android.mk中还指明了具体执行的源文件为main_cameraserver.cpp,该文件和cameraserver.rc在同一目录中。

所以init进程加载cameraserver.rc文件,会调用rc文件中指定的入口函数main()初始化cameraserver;

所以我们需要看一下main_cameraserver.cpp文件的定义。

main_cameraserver.cpp

arduino 复制代码
#define LOG_TAG "cameraserver"
//#define LOG_NDEBUG 0
​
#include "CameraService.h"
#include <hidl/HidlTransportSupport.h>
​
using namespace android;
​
int main(int argc __unused, char** argv __unused)
{
    signal(SIGPIPE, SIG_IGN);
​
    // Set 3 threads for HIDL calls
    // 设置了3个HIDL线程数量,数量不固定与特定机型有关,有的机型设置5个
    hardware::configureRpcThreadpool(3, /*willjoin*/ false);
​
    sp<ProcessState> proc(ProcessState::self());
    sp<IServiceManager> sm = defaultServiceManager();
    ALOGI("ServiceManager: %p", sm.get());
    CameraService::instantiate();
    ProcessState::self()->startThreadPool();
    IPCThreadState::self()->joinThreadPool();
}

首先会调用hardware::configureRpcThreadpool(3, /* willjoin */ false)方法,用于设置HIDL线程个数;

然后调用instantiate()方法,但是在CameraSevice.cpp中找不到对应的方法,该方法是CameraService类所继承的模板父类BinderService中的静态方法;

这个继承关系定义在CameraService.h中:

arduino 复制代码
............
​
namespace android {
​
extern volatile int32_t gLogLevel;
​
class MemoryHeapBase;
class MediaPlayer;
​
class CameraService :
    // 模板类 主要是封装了将Binder 添加到ServiceManager进程中
    public BinderService<CameraService>,
    // ICameraService的服务端需要继承BnCameraService(native binder的写法)
    public virtual ::android::hardware::BnCameraService,
    // Binder死亡监听  监听客户端进程的死亡情况
    public virtual IBinder::DeathRecipient,
    public virtual CameraProviderManager::StatusListener
{
    friend class BinderService<CameraService>;
    friend class CameraClient;
public:
    class Client;
    class BasicClient;
    ............

紧接着查看BinderService.h文件:

frameworks/native/libs/binder/include/binder/BinderService.h

arduino 复制代码
#ifndef ANDROID_BINDER_SERVICE_H
#define ANDROID_BINDER_SERVICE_H
​
#include <stdint.h>
​
#include <utils/Errors.h>
#include <utils/String16.h>
​
#include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
​
// ---------------------------------------------------------------------------
namespace android {
​
template<typename SERVICE>
class BinderService
{
public:
    static status_t publish(bool allowIsolated = false,
                            int dumpFlags = IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT) {
        sp<IServiceManager> sm(defaultServiceManager());
        // getServiceName()返回值为:media.camera,在CameraService.h中定义
        // SERVICE:在BinderService.h中定义的 -- template<typename SERVICE>
        return sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated,
                              dumpFlags);
    }
​
    static void publishAndJoinThreadPool(
            bool allowIsolated = false,
            int dumpFlags = IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT) {
        publish(allowIsolated, dumpFlags);
        joinThreadPool();
    }
​
    static void instantiate() { publish(); }
​
    static status_t shutdown() { return NO_ERROR; }
​
private:
    static void joinThreadPool() {
        sp<ProcessState> ps(ProcessState::self());
        ps->startThreadPool();
        ps->giveThreadPoolName();
        IPCThreadState::self()->joinThreadPool();
    }
};
​
​
}; // namespace android
// ---------------------------------------------------------------------------
#endif // ANDROID_BINDER_SERVICE_H

看到instantiate()方法中调用了publish()方法,而在publish()方法中,主要是获取了ServiceManager服务,然后将new好的service注册到ServiceManager中;

这一步,完成了CameraService的启动和初始化工作,并将CameraService注册到了ServiceManager,那么其他地方,就可以通过ServiceManager去获取这个服务。

CameraService.cpp

scss 复制代码
CameraService::CameraService() :
        mEventLog(DEFAULT_EVENT_LOG_LENGTH),  // 初始化用来打印Log的圆形Buffer的长度-100
        mNumberOfCameras(0),  // 初始化Camera的数量为0
        mSoundRef(0),
        mInitialized(false)  // 标识CameraService 是否被初始化了
{
    ALOGI("CameraService started (pid=%d)", getpid());
    mServiceLockWrapper = std::make_shared<WaitableMutexWrapper>(&mServiceLock);
}
​
// onFirstRef()属于其父类RefBase,当有sp包装的类初始化的时候调用
void CameraService::onFirstRef()
{
    ALOGI("CameraService process starting");
​
    BnCameraService::onFirstRef();
​
    // Update battery life tracking if service is restarting
    BatteryNotifier& notifier(BatteryNotifier::getInstance());
    notifier.noteResetCamera();
    notifier.noteResetFlashlight();
​
    status_t res = INVALID_OPERATION;
​
    // 主要是调用 enumerateProviders() 函数获取CameraProvider信息
    res = enumerateProviders();
    if (res == OK) {
        mInitialized = true;
    }
​
    // 连接CameraServiceProxy服务,也就是"media.camera.proxy"服务,此服务由SystemServer注册到ServiceManager中
    CameraService::pingCameraServiceProxy();
​
    mUidPolicy = new UidPolicy(this);
    mUidPolicy->registerSelf();
}

CameraService在初始化的过程中,会先初始化一些成员变量的值;

需要注意一下onFirstRef()方法,这个函数继承自类RefBase,会在CameraService第一次被引用时调用;在该函数中注册了BatteryNotifier、enumerateProviders,注册UID的Policy,最后检查CameraServiceProxy;

CameraService::enumerateProviders

scss 复制代码
status_t CameraService::enumerateProviders() {
    status_t res;
​
    std::vector<std::string> deviceIds;
    {
        Mutex::Autolock l(mServiceLock);
​
        // 初始化CameraProviderManager
        if (nullptr == mCameraProviderManager.get()) {
            mCameraProviderManager = new CameraProviderManager();
            res = mCameraProviderManager->initialize(this);
            if (res != OK) {
                ALOGE("%s: Unable to initialize camera provider manager: %s (%d)",
                        __FUNCTION__, strerror(-res), res);
                return res;
            }
        }
​
​
        // Setup vendor tags before we call get_camera_info the first time
        // because HAL might need to setup static vendor keys in get_camera_info
        // TODO: maybe put this into CameraProviderManager::initialize()?
        // 设置供应商标签
        mCameraProviderManager->setUpVendorTags();
​
        // 初始化闪光灯
        if (nullptr == mFlashlight.get()) {
            mFlashlight = new CameraFlashlight(mCameraProviderManager, this);
        }
​
        // 查找闪光灯资源
        res = mFlashlight->findFlashUnits();
        if (res != OK) {
            ALOGE("Failed to enumerate flash units: %s (%d)", strerror(-res), res);
        }
​
        // 保存所有的cameraIds,每个cameraId对应一个CameraDevice
        deviceIds = mCameraProviderManager->getCameraDeviceIds();
    }
​
​
    for (auto& cameraId : deviceIds) {
        String8 id8 = String8(cameraId.c_str());
        onDeviceStatusChanged(id8, CameraDeviceStatus::PRESENT);
    }
​
    return OK;
}

在这个方法中主要做了如下几件事:

  • 初始化CameraProviderManager并设置供应商标签;

通过new创建了CameraProviderManager实例之后,通过mCameraProviderManager->initialize(this)初始化;

c 复制代码
..................
​
const std::string kLegacyProviderName("legacy/0");
const std::string kExternalProviderName("external/0");
​
..................
​
// 第二个参数就是远程代理类。这个参数已经是默认赋值了,实际类HardwareServiceInteractionProxy
status_t CameraProviderManager::initialize(wp<CameraProviderManager::StatusListener> listener,
        ServiceInteractionProxy* proxy) {
    std::lock_guard<std::mutex> lock(mInterfaceMutex);
    if (proxy == nullptr) {
        ALOGE("%s: No valid service interaction proxy provided", __FUNCTION__);
        return BAD_VALUE;
    }
    // 将listener赋值给mListener,即CameraService赋值给Listener,CameraService可以接收CameraProvider的回调
    mListener = listener;
    mServiceProxy = proxy;
​
    // Registering will trigger notifications for all already-known providers
    bool success = mServiceProxy->registerForNotifications(
        /* instance name, empty means no filter */ "",
        this);
    if (!success) {
        ALOGE("%s: Unable to register with hardware service manager for notifications "
                "about camera providers", __FUNCTION__);
        return INVALID_OPERATION;
    }
​
    // See if there's a passthrough HAL, but let's not complain if there's not
    addProviderLocked(kLegacyProviderName, /*expected*/ false);
    addProviderLocked(kExternalProviderName, /*expected*/ false);
​
    return OK;
}

参数类型为StatusListener回调接口,在CameraProviderManager.h中定义:

csharp 复制代码
/**
 * Listener interface for device/torch status changes
 */
struct StatusListener : virtual public RefBase {
    ~StatusListener() {}
​
    // camera device状态发生变化
    virtual void onDeviceStatusChanged(const String8 &cameraId,
            hardware::camera::common::V1_0::CameraDeviceStatus newStatus) = 0;
    // 手电筒状态发生变化
    virtual void onTorchStatusChanged(const String8 &cameraId,
            hardware::camera::common::V1_0::TorchModeStatus newStatus) = 0;
    virtual void onNewProviderRegistered() = 0;
};

CameraProviderManager::initialize的核心逻辑为:

arduino 复制代码
addProviderLocked(kLegacyProviderName, /*expected*/ false);
addProviderLocked(kExternalProviderName, /*expected*/ false);

这里主要是和CameraProvider和ExternalCameraProvider建立联系,并把对应的代理(Interface)保存到ProviderInfo中,所以这两个方法执行完成之后这里有两个ProviderInfo对象,保存在mProviders中;

addProviderLocked(providerName, /* expected */ false)

kotlin 复制代码
status_t CameraProviderManager::addProviderLocked(const std::string& newProvider, bool expected) {
    for (const auto& providerInfo : mProviders) {
        if (providerInfo->mProviderName == newProvider) {
            ALOGW("%s: Camera provider HAL with name '%s' already registered", __FUNCTION__,
                    newProvider.c_str());
            return ALREADY_EXISTS;
        }
    }
​
    // 这里是通过服务端Binder的名字来获取hal的ICameraProvider对象
    sp<provider::V2_4::ICameraProvider> interface;  // HIDL的服务端对象
    // 这里的mServiceProxy就是HardwareServiceInteractionProxy
    interface = mServiceProxy->getService(newProvider);
​
    if (interface == nullptr) {
        if (expected) {
            ALOGE("%s: Camera provider HAL '%s' is not actually available", __FUNCTION__,
                    newProvider.c_str());
            return BAD_VALUE;
        } else {
            return OK;
        }
    }
​
    // 通过ProviderInfo保存得到的CameraHal进程的代理对象ICameraProvider以及对应的string key还有CameraProviderManager对象
    sp<ProviderInfo> providerInfo =
            new ProviderInfo(newProvider, interface, this);
    status_t res = providerInfo->initialize();
    if (res != OK) {
        return res;
    }
​
    // 将providerInfo添加到一个内部容器进行管理
    mProviders.push_back(providerInfo);
​
    return OK;
}

首先通过mServiceProxy->getService方法获取ICameraProvider代理,随后实例化了一个ProviderInfo对象,之后调用其initialize方法进行初始化,最后将ProviderInfo加入到一个内部容器中进行管理;

new ProviderInfo(newProvider, interface, this)和providerInfo->initialize()将CameraProviderManager、ProviderInfo、CameraProvider这三者关联起来的;

所以需要重点关注一下这一块的逻辑处理;

mProviders的定义在CameraProviderManager.h中:

arduino 复制代码
std::vector<sp<ProviderInfo>> mProviders;
css 复制代码
CameraProviderManager::ProviderInfo::ProviderInfo(
        const std::string &providerName,
        sp<provider::V2_4::ICameraProvider>& interface,
        CameraProviderManager *manager) :
        mProviderName(providerName),
        mInterface(interface),
        mProviderTagid(generateVendorTagId(providerName)),
        mUniqueDeviceCount(0),
        mManager(manager) {
    (void) mManager;
}

可以看一下CameraProviderManager::ProviderInfo::initialize():

scss 复制代码
status_t CameraProviderManager::ProviderInfo::initialize() {
    status_t res = parseProviderName(mProviderName, &mType, &mId);
    if (res != OK) {
        ALOGE("%s: Invalid provider name, ignoring", __FUNCTION__);
        return BAD_VALUE;
    }
    ALOGI("Connecting to new camera provider: %s, isRemote? %d",
            mProviderName.c_str(), mInterface->isRemote());
​
    // cameraDeviceStatusChange callbacks may be called (and causing new devices added)
    // before setCallback returns
    // mInterface是在ProviderInfo的构造函数中赋值的,也就是上面获取到的BpHwCameraProvider
    // ProviderInfo实现了ICameraProviderCallback接口,所以紧接着调用了ICameraProvider的setCallback将自身注册到Camera Provider中,接收来自CameraProvider进程的事件回调
    hardware::Return<Status> status = mInterface->setCallback(this);
    if (!status.isOk()) {
        ALOGE("%s: Transaction error setting up callbacks with camera provider '%s': %s",
                __FUNCTION__, mProviderName.c_str(), status.description().c_str());
        return DEAD_OBJECT;
    }
    if (status != Status::OK) {
        ALOGE("%s: Unable to register callbacks with camera provider '%s'",
                __FUNCTION__, mProviderName.c_str());
        return mapToStatusT(status);
    }
​
    // 死亡代理
    hardware::Return<bool> linked = mInterface->linkToDeath(this, /*cookie*/ mId);
    if (!linked.isOk()) {
        ALOGE("%s: Transaction error in linking to camera provider '%s' death: %s",
                __FUNCTION__, mProviderName.c_str(), linked.description().c_str());
        return DEAD_OBJECT;
    } else if (!linked) {
        ALOGW("%s: Unable to link to provider '%s' death notifications",
                __FUNCTION__, mProviderName.c_str());
    }
​
    // Get initial list of camera devices, if any
    // 可用摄像头列表  里面存放的是CameraId
    std::vector<std::string> devices;
    // getCameraIdList()参数是一个回调函数,等着Provider进程回调过来准备用于接收数据
    // 主要是将状态OK的摄像的id存取到devices列表里面
    // 其实该方法对应的就是camera application中使用的CameraManager.getCameraIdList()方法
    hardware::Return<void> ret = mInterface->getCameraIdList([&status, &devices](
            Status idStatus,
            const hardware::hidl_vec<hardware::hidl_string>& cameraDeviceNames) {
        status = idStatus;
        if (status == Status::OK) {
            for (size_t i = 0; i < cameraDeviceNames.size(); i++) {
                devices.push_back(cameraDeviceNames[i]);
            }
        } });
    if (!ret.isOk()) {
        ALOGE("%s: Transaction error in getting camera ID list from provider '%s': %s",
                __FUNCTION__, mProviderName.c_str(), linked.description().c_str());
        return DEAD_OBJECT;
    }
    if (status != Status::OK) {
        ALOGE("%s: Unable to query for camera devices from provider '%s'",
                __FUNCTION__, mProviderName.c_str());
        return mapToStatusT(status);
    }
​
    sp<StatusListener> listener = mManager->getStatusListener();
    for (auto& device : devices) {
        std::string id;
        // 将设备名和状态(在这里初始成PRESENT状态)保存起来
        status_t res = addDevice(device,
                hardware::camera::common::V1_0::CameraDeviceStatus::PRESENT, &id);
        if (res != OK) {
            ALOGE("%s: Unable to enumerate camera device '%s': %s (%d)",
                    __FUNCTION__, device.c_str(), strerror(-res), res);
            continue;
        }
    }
​
    ALOGI("Camera provider %s ready with %zu camera devices",
            mProviderName.c_str(), mDevices.size());
​
    mInitialized = true;
    return OK;
}

mInterface->setCallback(this) 这个会调用到CameraProvider里面去,然后这里的this是因为ProviderInfo继承了ICameraProviderCallback(这里ProviderInfo是ICameraProviderCallback的匿名Binder的服务端)CameraProvider可以通过ICameraProviderCallback传递消息到CameraService进程的ProviderInfo中。

mInterface->getCameraIdList()这是主动调用获取摄像头列表,这里是通过函数回调形式传递数据。得到摄像头名称的列表之后,就对这个列表进行遍历,根据摄像头的name属性获取摄像头的基本信息并保存到ProviderInfo的DeviceInfo中;

上面的代码会继续走到addDevice()函数:

c 复制代码
status_t CameraProviderManager::ProviderInfo::addDevice(const std::string& name,
        CameraDeviceStatus initialStatus, /*out*/ std::string* parsedId) {
​
    ALOGI("Enumerating new camera device: %s", name.c_str());
​
    uint16_t major, minor;
    std::string type, id;
​
    // 将传递过来的name(设备名)解析,得到major、minor、type、id等值
    status_t res = parseDeviceName(name, &major, &minor, &type, &id);
    if (res != OK) {
        return res;
    }
    if (type != mType) {
        ALOGE("%s: Device type %s does not match provider type %s", __FUNCTION__,
                type.c_str(), mType.c_str());
        return BAD_VALUE;
    }
    // 检查摄像头设备是否已经添加了ProviderInfo->mDevices中
    if (mManager->isValidDeviceLocked(id, major)) {
        ALOGE("%s: Device %s: ID %s is already in use for device major version %d", __FUNCTION__,
                name.c_str(), id.c_str(), major);
        return BAD_VALUE;
    }
​
    std::unique_ptr<DeviceInfo> deviceInfo;
    // 这里我们分析的是Camera2的API,所以是3这个分支
    switch (major) {
        case 1:
            deviceInfo = initializeDeviceInfo<DeviceInfo1>(name, mProviderTagid,
                    id, minor);
            break;
        case 3:
            // 根据上面的信息去创建一个DeviceInfo3的对象
            deviceInfo = initializeDeviceInfo<DeviceInfo3>(name, mProviderTagid,
                    id, minor);
            break;
        default:
            ALOGE("%s: Device %s: Unknown HIDL device HAL major version %d:", __FUNCTION__,
                    name.c_str(), major);
            return BAD_VALUE;
    }
    if (deviceInfo == nullptr) return BAD_VALUE;
    // 将传递过来的CameraDeviceStatus::PRESENT状态赋值给创建的DeviceInfo对象
    deviceInfo->mStatus = initialStatus;
    bool isAPI1Compatible = deviceInfo->isAPI1Compatible();
​
    // 将创建的DeviceInfo对象保存到ProviderInfo的mDevices中
    mDevices.push_back(std::move(deviceInfo));
​
    // 将CameraId存放到mUniqueCameraIds
    mUniqueCameraIds.insert(id);
    // 这个表明该摄像头设备支持camera api1
    if (isAPI1Compatible) {
        mUniqueAPI1CompatibleCameraIds.push_back(id);
    }
​
    if (parsedId != nullptr) {
        *parsedId = id;
    }
    return OK;
}

根据摄像头的设备名称信息获取到摄像头的major、minor、type、id等值后做了一些基本的校验,然后根据这些信息调用initializeDeviceInfo(name, mProviderTagid, id, minor) 创建一个DeviceInfo3对象;

  • 初始化闪光灯并查找闪光灯资源;
ini 复制代码
if (nullptr == mFlashlight.get()) {
    mFlashlight = new CameraFlashlight(mCameraProviderManager, this);
}
​
// 查找闪光灯资源
res = mFlashlight->findFlashUnits();
ini 复制代码
CameraFlashlight::CameraFlashlight(sp<CameraProviderManager> providerManager,
        CameraProviderManager::StatusListener* callbacks) :
        mProviderManager(providerManager),
        mCallbacks(callbacks),
        mFlashlightMapInitialized(false) {
}
..................
​
status_t CameraFlashlight::findFlashUnits() {
    Mutex::Autolock l(mLock);
    status_t res;
​
    std::vector<String8> cameraIds;
    std::vector<std::string> ids = mProviderManager->getAPI1CompatibleCameraDeviceIds();
    int numberOfCameras = static_cast<int>(ids.size());
    cameraIds.resize(numberOfCameras);
    // No module, must be provider
    for (size_t i = 0; i < cameraIds.size(); i++) {
        cameraIds[i] = String8(ids[i].c_str());
    }
​
    mFlashControl.clear();
​
    for (auto &id : cameraIds) {
        ssize_t index = mHasFlashlightMap.indexOfKey(id);
        if (0 <= index) {
            continue;
        }
​
        bool hasFlash = false;
        res = createFlashlightControl(id);
        if (res) {
            ALOGE("%s: failed to create flash control for %s", __FUNCTION__,
                    id.string());
        } else {
            res = mFlashControl->hasFlashUnit(id, &hasFlash);
            if (res == -EUSERS || res == -EBUSY) {
                ALOGE("%s: failed to check if camera %s has a flash unit. Some "
                        "camera devices may be opened", __FUNCTION__,
                        id.string());
                return res;
            } else if (res) {
                ALOGE("%s: failed to check if camera %s has a flash unit. %s"
                        " (%d)", __FUNCTION__, id.string(), strerror(-res),
                        res);
            }
​
            mFlashControl.clear();
        }
        mHasFlashlightMap.add(id, hasFlash);
    }
​
    mFlashlightMapInitialized = true;
    return OK;
}

通过getAPI1CompatibleCameraDeviceIds()方法获取所有的闪光灯设备,然后关闭释放所有的FlashController,然后根据获取的闪光灯设备号创建对应的FlashController,然后保证新创建的FlashController是close状态,然后将flash id和flash state对应的保存到mFlashlightMapInitialized中;

  • 获取CameraDeviceIds并遍历所有Ids的状态更新通知;
ini 复制代码
..................
    deviceIds = mCameraProviderManager->getCameraDeviceIds();
}
​
for (auto& cameraId : deviceIds) {
    String8 id8 = String8(cameraId.c_str());
    onDeviceStatusChanged(id8, CameraDeviceStatus::PRESENT);
}
..................

首先分析getCameraDeviceIds():

c 复制代码
std::vector<std::string> CameraProviderManager::getCameraDeviceIds() const {
    std::lock_guard<std::mutex> lock(mInterfaceMutex);
    std::vector<std::string> deviceIds;
    for (auto& provider : mProviders) {
        // CameraProviderManager::ProviderInfo::addDevice
        for (auto& id : provider->mUniqueCameraIds) {
            deviceIds.push_back(id);
        }
    }
    return deviceIds;
}

遍历mProviders,获取provider->mUniqueCameraIds,其实mUniqueCameraIds就是对应CameraProviderManager::ProviderInfo::addDevice方法中的mUniqueCameraIds.insert(id)逻辑,而其中的id就是对应getCameraIdList()获取到的cameraIds,即将所有的provider中的全部cameraId保存到deviceIds中;

获取完CameraDeviceIds之后,遍历cameraIds更新通知;

scss 复制代码
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);
​
    // 获取对应当前id的CameraDevice state
    std::shared_ptr<CameraState> state = getCameraState(id);
​
    // 如果为空,判断新状态是不是PRESENT
    if (state == nullptr) {
        // 如果是的话添加这个CameraDevice,并通知所有client
        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;
    }
​
    // 如果不为空,则获取旧的状态。如果新状态与状态相等,则没有必要发出通知,直接return
    StatusInternal oldStatus = state->getStatus();
​
    if (oldStatus == newStatus) {
        ALOGE("%s: State transition to the same status %#x not allowed", __FUNCTION__, newStatus);
        return;
    }
​
    // 如果新状态为NOT_PRESENT,则更新对应的状态,然后根据id查找需要移除的client,通知,然后断开连接。最后,移除该id
    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<BasicClient> clientToDisconnect;
        {
            // Don't do this in updateStatus to avoid deadlock over mServiceLock
            Mutex::Autolock lock(mServiceLock);
​
            // Remove cached shim parameters
            state->setShimParams(CameraParameters());
​
            // Remove the client from the list of active clients, if there is one
            clientToDisconnect = removeClientLocked(id);
        }
​
        // Disconnect client
        if (clientToDisconnect.get() != nullptr) {
            ALOGI("%s: Client for camera ID %s evicted due to device status change from HAL",
                    __FUNCTION__, id.string());
            // Notify the client of disconnection
            clientToDisconnect->notifyError(
                    hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISCONNECTED,
                    CaptureResultExtras{});
            // Ensure not in binder RPC so client disconnect PID checks work correctly
            LOG_ALWAYS_FATAL_IF(getCallingPid() != getpid(),
                    "onDeviceStatusChanged must be called from the camera service process!");
            clientToDisconnect->disconnect();
        }
​
        removeStates(id);
    } else {  // 如果新状态不为NOT_PRESENT,则打印一条log作提示,然后更新CameraDevice的状态
        if (oldStatus == StatusInternal::NOT_PRESENT) {
            logDeviceAdded(id, String8::format("Device status changed from %d to %d", oldStatus,
                    newStatus));
        }
        updateStatus(newStatus, id);
    }
​
}

在onDeviceStatusChanged()方法中,首先获取对应当前id的CameraDevice状态:

  • 如果为空,判断新状态是不是PRESENT。如果是的话添加这个CameraDevice,并通知所有client;
  • 如果不为空,则获取旧的状态。如果新状态与状态相等,则没有必要发出通知,直接return;
  • 如果新状态为NOT_PRESENT,则更新对应的状态,然后根据id查找需要移除的client,通知,然后断开连接。最后,移除该id;
  • 如果新状态不为NOT_PRESENT,则打印一条log作提示,然后更新CameraDevice的状态;

至此,enumerateProviders()函数分析完成;

CameraService::pingCameraServiceProxy

enumerateProviders()函数执行结束之后,紧接着就是该函数的执行;

ini 复制代码
void CameraService::pingCameraServiceProxy() {
    sp<ICameraServiceProxy> proxyBinder = getCameraServiceProxy();
    if (proxyBinder == nullptr) return;
    proxyBinder->pingForUserUpdate();
}

在这个时候,CameraServiceProxy服务应该还没有addService到ServiceManager中;

因为cameraserver进程是在init进程中启动的,而CameraServiceProxy进程是在SystemServer中startService的,而addService则是在startService中通过publish的方式添加的;

arduino 复制代码
sp<ICameraServiceProxy> CameraService::getCameraServiceProxy() {
    sp<ICameraServiceProxy> proxyBinder = nullptr;
#ifndef __BRILLO__
    sp<IServiceManager> sm = defaultServiceManager();
    // Use checkService because cameraserver normally starts before the
    // system server and the proxy service. So the long timeout that getService
    // has before giving up is inappropriate.
    // 使用checkService是因为cameraserver通常在系统服务器和代理服务之前启动
    sp<IBinder> binder = sm->checkService(String16("media.camera.proxy"));
    if (binder != nullptr) {
        proxyBinder = interface_cast<ICameraServiceProxy>(binder);
    }
#endif
    return proxyBinder;
}

理论上来说,获取到的binder应该为null???

综上,CameraServer进程的启动流程就分析完了;

相关推荐
weixin_482565531 小时前
Android IC读写器安卓小程序 3
android·小程序
峰子20121 小时前
Go语言实现守护进程的挑战
开发语言·后端·面试·架构·golang·go
hvinsion2 小时前
Python PDF批量加密工具
android·python·pdf
m0_748230442 小时前
【MySQL】数据库开发技术:内外连接与表的索引穿透深度解析
android·mysql·数据库开发
绝无仅有2 小时前
gozero项目日志Prometheus的配置与实战
后端·面试·架构
marui19822 小时前
hadoop sql 执行log
android·ide·android studio
绝无仅有3 小时前
gozero项目日志收集与配置实战
后端·面试·架构
uhakadotcom4 小时前
2025年,最新的AI发展趋势是什么?
后端·面试·架构
liangmou21214 小时前
解释小部分分WPI函数(由贪吃蛇游戏拓展)
android·游戏·c#
你听得到114 小时前
《Flutter性能优化全攻略:从首屏渲染到性能监测,附案例代码详解》
android·flutter