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.0default_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/cameraserverclass mainuser cameraservergroup audio camera input drmrpcioprio rt 4task_profiles CameraServiceCapacity MaxPerformancerlimit 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指定泛型类型为CameraServicepublic 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 restartingBatteryNotifier& 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对象,并调进行了初始化.具体如下:
相关文章:
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_a…...
如何升级node.js版本
升级Node.js可以通过多种方式来完成,以下是四种常见的方法: 方法一:使用Node.js官方安装程序 访问Node.js的官方网站,下载对应你操作系统的最新版本安装程序。通常,你可以 https://nodejs.org/en/download 找到你需…...
Excel---一个工作簿中的多个sheet合并成一个PDF
0 Preface/Foreword 1 操作方法 1.1 方法一 文件》 导出 》创建PDF/XPS 》 选项 》发布内容 》“整个工作簿” 1.2 方法二 文件》 打印》 打印机选项中,选择一种PDF阅读器 》设置选项中,选择打印整个工作簿。...
结合文本的目标检测:Open-GroundingDino训练自己的数据集
1、简单介绍 Open-GroundingDino是GroundingDino的第三方实现训练流程的代码,因为官方GroundingDino没有提供训练代码,只提供了demo推理代码。 关于GroundingDino的介绍可以看论文:https://arxiv.org/pdf/2303.05499.pdf GroundingDino的G…...
分布式锁-redission锁的MutiLock原理
5.5 分布式锁-redission锁的MutiLock原理 为了提高redis的可用性,我们会搭建集群或者主从,现在以主从为例 此时我们去写命令,写在主机上, 主机会将数据同步给从机,但是假设在主机还没有来得及把数据写入到从机去的时…...
MySQL索引、B+树相关知识汇总
MySQL索引、B树相关知识汇总 一、有一个查询需求,MySQL中有两个表,一个表1000W数据,另一个表只有几千数据,要做一个关联查询,如何优化?1、为关联字段建立索引二、小表驱动大表 二、b树和b树的区别1、更高的…...
相机模型浅析
相机模型 文章目录 相机模型四个坐标系针孔相机模型世界坐标系到相机坐标系相机坐标系到图像坐标系图像坐标到像素坐标 四个坐标系 ①世界坐标系:是客观三维世界的绝对坐标系,也称客观坐标系。因为数码相机安放在三维空间中,我们需要世界坐标…...
国芯科技(C*Core)双芯片汽车安全气囊解决方案
汽车安全气囊是20世纪汽车上的十大发明之一,是目前汽车的法定标准配置,成为汽车驾乘人员生命安全的保护神。随着人们对汽车安全性要求的进一步提高,已形成前排驾驶员气囊、前排副驾驶员气囊、前排侧气囊、后排侧气囊、膝部气囊、安全气帘等等…...
牛客周赛 Round 39(A,B,C,D,E,F,G)
比赛链接 官方题解(视频) B题是个贪心。CD用同余最短路,预处理的完全背包,多重背包都能做,比较典型。E是个诈骗,暴力就完事了。F是个线段树。G是个分类大讨论,出题人钦定的本年度最佳最粪 题目…...
解锁区块链技术的潜力:实现智能合约与DApps
在数字时代,区块链技术正迅速成为重塑多个行业的革命性力量。从金融服务到供应链管理,再到数字身份验证,区块链提供了一种去中心化、安全和透明的数据处理方式。在本文中,我们将深入探讨区块链技术,特别是智能合约和去…...
MAC OS关闭SIP(navicat 无法保存密码)
最近安装navicat(16.3.7)时,安装后无法保存密码,保存密码会报错如下: 因为用的破解版,一开始是打不开的,用自带的修复软件修复后就可以打开了,但是保存密码就会报错,按照网上的一些操作 1、卸载…...
阿里云服务器带宽价格全解析,附报价单
阿里云服务器公网带宽怎么收费?北京地域服务器按固定带宽计费一个月23元/M,按使用流量计费0.8元/GB,云服务器地域不同实际带宽价格也不同,阿里云服务器网aliyunfuwuqi.com分享不同带宽计费模式下带宽收费价格表: 公网…...
Day36|贪心算法part05:435. 无重叠区间、763.划分字母区间、56. 合并区间
435. 无重叠区间 有了上题射气球的因子,这题也就有思路了,反正无脑排序就行了: 首先将所有区间按照end的大小从小到大排序;选取最早end为起始x_end遍历所有区间,如果该区间的start比end大(可重叠…...
棋牌室计时吧台计费收费灯控管理系统软件操作流程
棋牌室计时吧台计费收费灯控管理系统软件操作流程 一、前言 以下软件操作教程以,佳易王棋牌桌球计时计费管理系统软件灯控版V17.87为例说明 软件文件下载可以点击最下方官网卡片——软件下载——试用版软件下载 该计时计费软件可以是棋牌和桌球混合同时计时计费 …...
【实践篇】RabbitMQ实现队列延迟功能汇总
前言 记录下RabbitMQ实现延迟队列功能的所有实践内容。 前期准备,需要安装好docker、docker-compose的运行环境。 一、安装RabbitMQ 开启RabbitMQ的WEB管理功能。-CSDN博客 二、实现延迟队列的两种方式 RabbitMQ实现延迟队列的两种方式。-CSDN博客 三、实践文…...
EditPlus来啦(免费使用!)
hello,我是小索奇 今天推荐一款编辑器,是索奇学习JavaSE时入手滴,非常好用哈,小索奇还是通过老杜-杜老师入手滴,相信很多人也是通过老杜认识嘞,来寻找破解版或者准备入手这个间接使用的编辑器~ EditPlus是…...
蓝桥杯22年第十三届省赛-数组切分|线性DP
题目链接: 蓝桥杯2022年第十三届省赛真题-数组切分 - C语言网 (dotcpp.com) 1.数组切分 - 蓝桥云课 (lanqiao.cn) 这道题C语言网数据会强一些。 说明: 对于一个切分的子数组,由于数组是1-N的一个排列,所以每个数唯一 可以用子…...
小米汽车:搅动市场的鲶鱼or价格战砧板上的鱼肉?
3月28日晚,备受关注的小米汽车上市发布会召开,小米集团董事长雷军宣布小米SU7正式发布。小米汽车在带飞股价的同时,二轮订购迅速售尽。 图一:小米集团股价 雷军口中“小米汽车迈出的第一步,也是人生最后一战的开篇”&a…...
Docker 学习笔记(五):梳理 Docker 镜像知识,附带 Commit 方式提交镜像副本,安装可视化面板 portainer
一、前言 记录时间 [2024-4-10] 前置文章: Docker学习笔记(一):入门篇,Docker概述、基本组成等,对Docker有一个初步的认识 Docker学习笔记(二):在Linux中部署Docker&…...
K8S node节点执行kubectl get pods报错
第一个问题是由第二个问题产生的,第二个问题也是最常见的 网上找的都是从master节点把文件复制过来,这样确实可以解决,但是麻烦,有一个node节点还好,如果有多个呢?每个都复制吗?下面是我从外网…...
为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?
在建筑行业,项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升,传统的管理模式已经难以满足现代工程的需求。过去,许多企业依赖手工记录、口头沟通和分散的信息管理,导致效率低下、成本失控、风险频发。例如&#…...
最新SpringBoot+SpringCloud+Nacos微服务框架分享
文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的,根据Excel列的需求预估的工时直接打骨折,不要问我为什么,主要…...
江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命
在华东塑料包装行业面临限塑令深度调整的背景下,江苏艾立泰以一场跨国资源接力的创新实践,重新定义了绿色供应链的边界。 跨国回收网络:废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点,将海外废弃包装箱通过标准…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
Golang——6、指针和结构体
指针和结构体 1、指针1.1、指针地址和指针类型1.2、指针取值1.3、new和make 2、结构体2.1、type关键字的使用2.2、结构体的定义和初始化2.3、结构体方法和接收者2.4、给任意类型添加方法2.5、结构体的匿名字段2.6、嵌套结构体2.7、嵌套匿名结构体2.8、结构体的继承 3、结构体与…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现企业微信功能
1. 开发环境准备 安装DevEco Studio 3.1: 从华为开发者官网下载最新版DevEco Studio安装HarmonyOS 5.0 SDK 项目配置: // module.json5 {"module": {"requestPermissions": [{"name": "ohos.permis…...
渗透实战PortSwigger Labs指南:自定义标签XSS和SVG XSS利用
阻止除自定义标签之外的所有标签 先输入一些标签测试,说是全部标签都被禁了 除了自定义的 自定义<my-tag onmouseoveralert(xss)> <my-tag idx onfocusalert(document.cookie) tabindex1> onfocus 当元素获得焦点时(如通过点击或键盘导航&…...
作为点的对象CenterNet论文阅读
摘要 检测器将图像中的物体表示为轴对齐的边界框。大多数成功的目标检测方法都会枚举几乎完整的潜在目标位置列表,并对每一个位置进行分类。这种做法既浪费又低效,并且需要额外的后处理。在本文中,我们采取了不同的方法。我们将物体建模为单…...
DL00871-基于深度学习YOLOv11的盲人障碍物目标检测含完整数据集
基于深度学习YOLOv11的盲人障碍物目标检测:开启盲人出行新纪元 在全球范围内,盲人及视觉障碍者的出行问题一直是社会关注的重点。尽管技术不断进步,许多城市的无障碍设施依然未能满足盲人出行的实际需求。尤其是在复杂的城市环境中ÿ…...
5. TypeScript 类型缩小
在 TypeScript 中,类型缩小(Narrowing)是指根据特定条件将变量的类型细化为更具体的过程。它帮助开发者编写更精确、更准确的代码,确保变量在运行时只以符合其类型的方式进行处理。 一、instanceof 缩小类型 TypeScript 中的 in…...
