Android13 CameraServer启动流程

代码入口

frameworks/av/camera/cameraserver

里面包含了四个文件

我们先来看看Android.bp的内容

复制代码
package {
    // See: http://go/android-license-faq
    // A large-scale-change added 'default_applicable_licenses' to import
    // all of the 'license_kinds' from "frameworks_av_camera_license"
    // to get the below license kinds:
    //   SPDX-license-identifier-Apache-2.0
    default_applicable_licenses: ["frameworks_av_camera_license"],
}

cc_binary {
    name: "cameraserver",

    srcs: ["main_cameraserver.cpp"],

    header_libs: [
        "libmedia_headers",
    ],

    shared_libs: [
        "libcameraservice",
        "liblog",
        "libutils",
        "libui",
        "libgui",
        "libbinder",
        "libhidlbase",
        "android.hardware.camera.common@1.0",
        "android.hardware.camera.provider@2.4",
        "android.hardware.camera.provider@2.5",
        "android.hardware.camera.provider@2.6",
        "android.hardware.camera.provider@2.7",
        "android.hardware.camera.provider-V1-ndk",
        "android.hardware.camera.device@1.0",
        "android.hardware.camera.device@3.2",
        "android.hardware.camera.device@3.4",
    ],
    compile_multilib: "first",
    cflags: [
        "-Wall",
        "-Wextra",
        "-Werror",
        "-Wno-unused-parameter",
    ],

    init_rc: ["cameraserver.rc"],

    vintf_fragments: [
        "manifest_android.frameworks.cameraservice.service@2.2.xml",
    ],
}

我们注意到

init_rc: ["cameraserver.rc"],

由此可知系统在编译时会将cameraserver.rc放到system/etc/init目录下,

init进程启动的时候会解析这个目录下的所有.rc文件。

solid/android13/amdroid13_ntls/out/target/product/hpg2_24/system/etc/init$ ll cameraserver.rc

-rw-rw-r-- 1 wancg wancg 214 3月 7 14:59 cameraserver.rc

接下来我们来探探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

开机时/system/bin/cameraserver启动一个名称为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)
{
    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.
    hardware::configureRpcThreadpool(5, /*willjoin*/ false);

    sp<ProcessState> proc(ProcessState::self());
    sp<IServiceManager> sm = defaultServiceManager();
    ALOGI("ServiceManager: %p", sm.get());
    CameraService::instantiate();
    //下面我们就从CameraService继续分析。
    ALOGI("ServiceManager: %p done instantiate", sm.get());
    ProcessState::self()->startThreadPool();
    IPCThreadState::self()->joinThreadPool();
}

CarmeraServer.cpp

CameraService继承了BinderService.h.这个:instantiate()调用到了BinderService.h里的代码

复制代码
frameworks/native/libs/binder/include/binder/BinderService.h
class BinderService
{
public:
    static status_t publish(bool allowIsolated = false,
                            int dumpFlags = IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT) {
        sp<IServiceManager> sm(defaultServiceManager());
        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();
    }
};

在回过头来看看上面提到的CameraService方法

复制代码
// frameworks/av/services/camera/libcameraservice/CameraService.h
class CameraService :
    // 继承BinderService指定泛型类型为CameraService
    public BinderService<CameraService>,
    public virtual ::android::hardware::BnCameraService,
    public virtual IBinder::DeathRecipient,
    public virtual CameraProviderManager::StatusListener
{
    ...
public:
    ...
    // 注册的binder服务名称为"media.camera"
    static char const* getServiceName() { 
      return "media.camera"; 
    }
    ...
}

接下来我们看下frameworks/native/libs/binder/include/binder/BinderService.h 中提到addService方法

复制代码
// frameworks/native/libs/binder/include/binder/IServiceManager.h
// 第一个参数是字符串media.camera
// 第二个参数是new的CameraService对象
// 这里相当于const sp<IBinder>& service = new CameraService()
virtual status_t addService(const String16& name, const sp<IBinder>& service,
                            bool allowIsolated = false,
                            int dumpsysFlags = DUMP_FLAG_PRIORITY_DEFAULT) = 0;

我们看下class sp的实现

复制代码
// system/core/libutils/include/utils/StrongPointer.h
// 下面的T就是CameraService*
template <typename T>
sp<T>& sp<T>::operator=(T* other) {
    T* oldPtr(*const_cast<T* volatile*>(&m_ptr));
    if (other) {
        check_not_on_stack(other);
        // 可以看到如果指针不为空的话
        // 会调用自身的incStrong方法
        other->incStrong(this);
    }
    if (oldPtr) oldPtr->decStrong(this);
    if (oldPtr != *const_cast<T* volatile*>(&m_ptr)) sp_report_race();
    m_ptr = other;
    return *this;
}

但是我们发现CameraService里并没有incStrong方法,那么一定

是它的父类的方法,由此引出了一个非常重要的类RefBase。

RefBase是Android中所有C++对象的基类。

从这个文件可以看出,instantiate最终还是调用到了IServiceManager里的addService, 将我们的cameraService注册到了系统的服务管理器里去了.

这里调用到CameraService后, 因为是开机第一次调用,它的引用计数为1,所以会调用到CameraService::onFirstRef()这个函数. 这个函数是从CameraService的父类RefBase里继承过来的.该函数在强引用sp新增引用计数时调用,什么意思?就是当 有sp包装的类初始化的时候调用.我们再看看cameraService::onFirstRef()

复制代码
frameworks\av\services\camera\libcameraservice\CameraService.cpp
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;

    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(),这里就到了列出所有cameraProvider.

复制代码
status_t CameraService::enumerateProviders() {
    status_t res;

    std::vector<std::string> deviceIds;
    std::unordered_map<std::string, std::set<std::string>> unavailPhysicalIds;
    {
        Mutex::Autolock l(mServiceLock);

        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);
                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(&unavailPhysicalIds);
    }


    for (auto& cameraId : deviceIds) {
        String8 id8 = String8(cameraId.c_str());
        if (getCameraState(id8) == nullptr) {
            onDeviceStatusChanged(id8, CameraDeviceStatus::PRESENT);
        }
        if (unavailPhysicalIds.count(cameraId) > 0) {
            for (const auto& physicalId : unavailPhysicalIds[cameraId]) {
                String8 physicalId8 = String8(physicalId.c_str());
                onDeviceStatusChanged(id8, physicalId8, CameraDeviceStatus::NOT_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;
}

这个函数里,创建了一个CameraProviderManager对象,并调进行了初始化.具体如下:

相关推荐
alexhilton2 小时前
在Jetpack Compose中创建CRT屏幕效果
android·kotlin·android jetpack
2501_940094024 小时前
emu系列模拟器最新汉化版 安卓版 怀旧游戏模拟器全集附可运行游戏ROM
android·游戏·安卓·模拟器
下位子4 小时前
『OpenGL学习滤镜相机』- Day9: CameraX 基础集成
android·opengl
参宿四南河三6 小时前
Android Compose SideEffect(副作用)实例加倍详解
android·app
火柴就是我7 小时前
mmkv的 mmap 的理解
android
没有了遇见7 小时前
Android之直播宽高比和相机宽高比不支持后动态获取所支持的宽高比
android
shenshizhong7 小时前
揭开 kotlin 中协程的神秘面纱
android·kotlin
vivo高启强8 小时前
如何简单 hack agp 执行过程中的某个类
android
沐怡旸8 小时前
【底层机制】 Android ION内存分配器深度解析
android·面试
你听得到119 小时前
肝了半个月,我用 Flutter 写了个功能强大的图片编辑器,告别image_cropper
android·前端·flutter