基于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进程的启动流程就分析完了;

相关推荐
私人珍藏库1 小时前
[Android] APK提取器(1.3.7)版本
android
m0_748232641 小时前
mysql的主从配置
android·mysql·adb
秋长愁1 小时前
Android监听应用前台的实现方案解析
android
BlueBirdssh2 小时前
ARM SOC 架构系统M系、R系、A系
arm开发·架构
胖虎12 小时前
2025 新版Android Studio创建Java语言项目
android·java·android studio·创建java项目
JabamiLight4 小时前
Lineageos 22.1(Android 15)Launcer简单调整初始化配置
android·android 15·lineageos 22.1·launcer
CodeJourney.4 小时前
WPS携手DeepSeek:开启智能办公新时代
数据库·人工智能·算法·架构
敲代码的鱼哇5 小时前
设备唯一ID获取,支持安卓/iOS/鸿蒙Next(uni-device-id)UTS插件
android·ios·uniapp·harmonyos
uhakadotcom6 小时前
Next.js中生成sitemap的简单方法
前端·面试·架构
太空漫步117 小时前
android滑动看新闻
android