Android 13 cameraserver启动流程

文章目录


欢迎关注微信公众号 无限无羡

前面的两篇文章我们已经介绍了CameraProvider进程(Camera HAL)的启动流程,今天我们开始讲cameraserver进程的启动流程。
cameraserver进程是一个system进程,也是通过init.rc启动的。

// frameworks/av/camera/cameraserver/cameraserver.rc
service cameraserver /system/bin/cameraserver
    class main
    user cameraserver
    group audio camera input drmrpc
    ioprio rt 4
    task_profiles CameraServiceCapacity MaxPerformance
    rlimit rtprio 10 10

它的入口函数为

// frameworks/av/camera/cameraserver/main_cameraserver.cpp
#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)
{
	// 忽略SIGPIPE信号,这个信号是服务端关闭后client继续向服务端发送数据的时候会收到,
	// 如果不忽略的话client进程就会退出。
    signal(SIGPIPE, SIG_IGN);

    // Set 5 threads for HIDL calls. Now cameraserver will serve HIDL calls in
    // addition to consuming them from the Camera HAL as well.
    // 使用/dev/hwbinder也就是跟HAL进程通信的最大线程数为5
    hardware::configureRpcThreadpool(5, /*willjoin*/ false);

	// 创建ProcessState对象,这是一个单利,每个进程只有一个对象。
	// 在其构造函数中会打开binder节点,并且通过mmap拿到binderq驱动内存的虚拟地址的fd
    sp<ProcessState> proc(ProcessState::self());
    sp<IServiceManager> sm = defaultServiceManager();
    ALOGI("ServiceManager: %p", sm.get());
    CameraService::instantiate();
    ALOGI("ServiceManager: %p done instantiate", sm.get());
    // 创建binder线程池
    ProcessState::self()->startThreadPool();
    // 将当前线程加入binder线程池
    IPCThreadState::self()->joinThreadPool();
}

binder相关的我们这里就不详细介绍了,主要介绍Camera相关的业务流程。我们主要看下CameraService::instantiate()的实现。

// frameworks/av/services/camera/libcameraservice/CameraService.h
class CameraService :
	// 这里BinderService是一个泛型类,后面在其实现中会用到CameraService
    public BinderService<CameraService>,

我们会发现CameraService里没有instantiate函数,但是它继承了BinderService,而BinderService里是有instantiate函数实现的

// frameworks/native/libs/binder/include/binder/BinderService.h
// 我们可以看到instantiate()调用了publish()方法,而publish()方法里则调用了ServiceManager的addService方法,将CameraService
// 添加到了ServiceManager中
static void instantiate() { publish(); }
static status_t publish(bool allowIsolated = false,
                        int dumpFlags = IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT) {
    sp<IServiceManager> sm(defaultServiceManager());
    // 这里的SERVICE是CameraService,这里调用CameraService::getServiceName()获取服务名称
    // 然后new一个CameraService
    return sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated,
                          dumpFlags);
}

// frameworks/native/cmds/servicemanager/ServiceManager.h
// 这个是addService的函数声明,我们可以看到,第二个参数使用了智能指针,
// 而被sp引用的对象在创建时会执行onFirstRef函数,所以我们下面分析完CameraService
// 的构造函数后,还要看其onFirstRef函数实现。
binder::Status addService(const std::string& name, const sp<IBinder>& binder,
                          bool allowIsolated, int32_t dumpPriority) override;
// frameworks/av/services/camera/libcameraservice/CameraService.h
// CameraService注册的名字为media.camera
static char const* getServiceName() { return "media.camera"; }

接下来看下CameraService的构造函数,因为上面addService的时候执行了new操作

// frameworks/av/services/camera/libcameraservice/CameraService.cpp
// 构造函数比较简单,进行了一些初始化操作
CameraService::CameraService() :
        mEventLog(DEFAULT_EVENT_LOG_LENGTH),
        mNumberOfCameras(0),
        mNumberOfCamerasWithoutSystemCamera(0),
        mSoundRef(0), mInitialized(false),
        mAudioRestriction(hardware::camera2::ICameraDeviceUser::AUDIO_RESTRICTION_NONE) {
    ALOGI("CameraService started (pid=%d)", getpid());
    mServiceLockWrapper = std::make_shared<WaitableMutexWrapper>(&mServiceLock);
    mMemFd = memfd_create(sFileName, MFD_ALLOW_SEALING);
    if (mMemFd == -1) {
        ALOGE("%s: Error while creating the file: %s", __FUNCTION__, sFileName);
    }
}

// 如前所述,由于CameraService被智能指针sp引用,所以会执行其onFirstRef函数,这个函数也是关键
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;
	// 这里是关键实现,用于跟CameraProvider建立连接,我们接下来重点分析这个函数的实现
    res = enumerateProviders();
    if (res == OK) {
        mInitialized = true;
    }

    mUidPolicy = new UidPolicy(this);
    mUidPolicy->registerSelf();
    mSensorPrivacyPolicy = new SensorPrivacyPolicy(this);
    mSensorPrivacyPolicy->registerSelf();
    mInjectionStatusListener = new InjectionStatusListener(this);
    mAppOps.setCameraAudioRestriction(mAudioRestriction);
    sp<HidlCameraService> hcs = HidlCameraService::getInstance(this);
    if (hcs->registerAsService() != android::OK) {
        ALOGE("%s: Failed to register default android.frameworks.cameraservice.service@1.0",
              __FUNCTION__);
    }

    // This needs to be last call in this function, so that it's as close to
    // ServiceManager::addService() as possible.
    CameraServiceProxyWrapper::pingCameraServiceProxy();
    ALOGI("CameraService pinged cameraservice proxy");
}

enumerateProviders实现分析:

// frameworks/av/services/camera/libcameraservice/CameraService.cpp
status_t CameraService::enumerateProviders() {
    status_t res;

    std::vector<std::string> deviceIds;
    {
        Mutex::Autolock l(mServiceLock);

        if (nullptr == mCameraProviderManager.get()) {
        	// 创建CameraProviderManager对象并执行其initialize函数
            mCameraProviderManager = new CameraProviderManager();
            res = mCameraProviderManager->initialize(this);
            if (res != OK) {
                ALOGE("%s: Unable to initialize camera provider manager: %s (%d)",
                        __FUNCTION__, strerror(-res), res);
                logServiceError(String8::format("Unable to initialize camera provider manager"),
                ERROR_DISCONNECTED);
                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);
        }

        deviceIds = mCameraProviderManager->getCameraDeviceIds();
    }


    for (auto& cameraId : deviceIds) {
        String8 id8 = String8(cameraId.c_str());
        if (getCameraState(id8) == nullptr) {
            onDeviceStatusChanged(id8, CameraDeviceStatus::PRESENT);
        }
    }

    // Derive primary rear/front cameras, and filter their charactierstics.
    // This needs to be done after all cameras are enumerated and camera ids are sorted.
    if (SessionConfigurationUtils::IS_PERF_CLASS) {
        // Assume internal cameras are advertised from the same
        // provider. If multiple providers are registered at different time,
        // and each provider contains multiple internal color cameras, the current
        // logic may filter the characteristics of more than one front/rear color
        // cameras.
        Mutex::Autolock l(mServiceLock);
        filterSPerfClassCharacteristicsLocked();
    }

    return OK;
}

我们重点分析mCameraProviderManager->initialize

// frameworks/av/services/camera/libcameraservice/common/CameraProviderManager.cpp
// 其没有显示构造函数,所以我们直接看它的initialize函数
// 这里的第二个参数是HIDL CameraProvider服务的代理
// 这个函数主要是查询系统中的HIDL方式实现的CameraProvider和AIDL方式实现的CameraProvider,拿到其服务名称,
// 分别构建HidlProviderInfo对象和AidlProviderInfo对象并添加到ProviderInfo的数组mProviders中
// HidlProviderInfo和AidlProviderInfo继承自ProviderInfo,构造函数中会传入CameraProviderManager对象
status_t CameraProviderManager::initialize(wp<CameraProviderManager::StatusListener> listener,
        HidlServiceInteractionProxy* hidlProxy) {
    std::lock_guard<std::mutex> lock(mInterfaceMutex);
    if (hidlProxy == nullptr) {
        ALOGE("%s: No valid service interaction proxy provided", __FUNCTION__);
        return BAD_VALUE;
    }
    mListener = listener;
    mDeviceState = 0;
    // 查询系统中的HIDL方式实现的CameraProvider,拿到其服务名称,构建HidlProviderInfo对象
    // 并添加到ProviderInfo的数组mProviders中,在构建HidlProviderInfo对象后会进行一些初始化操作然后再构建一个
    // HidlDeviceInfo3对象用来保存一些基本信息
    auto res = tryToInitAndAddHidlProvidersLocked(hidlProxy);
    if (res != OK) {
        // Logging done in called function;
        return res;
    }
    // 查询系统中的AIDL方式实现的CameraProvider,拿到其服务名称,构建AidlProviderInfo对象
    // 并添加到ProviderInfo的数组mProviders中,在构建AidlProviderInfo对象后会进行一些初始化操作然后再构建一个
    // AidlDeviceInfo3对象用来保存一些基本信息
    res = tryToAddAidlProvidersLocked();

    IPCThreadState::self()->flushCommands();

    return res;
}

如上可以看出,CameraServer启动的过程中主要干了三件事:

  1. 将自身服务添加到ServiceManager中,使得Client可以通过binder调用
  2. 创建CameraProviderManager对象,这个对象是CameraServer跟CameraProvider进程通信的桥梁
  3. 创建ProviderInfo对象和DeviceInfo对象,用来保存一些Camera设备的基本信息(此部分代码比较繁琐,有兴趣的可以自己跟读,后面再将重要流程时涉及到的会再具体说明)
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ZZH的Android

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值