当前位置: 首页 > news >正文

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可以通过多种方式来完成&#xff0c;以下是四种常见的方法&#xff1a; 方法一&#xff1a;使用Node.js官方安装程序 访问Node.js的官方网站&#xff0c;下载对应你操作系统的最新版本安装程序。通常&#xff0c;你可以 https://nodejs.org/en/download 找到你需…...

Excel---一个工作簿中的多个sheet合并成一个PDF

0 Preface/Foreword 1 操作方法 1.1 方法一 文件》 导出 》创建PDF/XPS 》 选项 》发布内容 》“整个工作簿” 1.2 方法二 文件》 打印》 打印机选项中&#xff0c;选择一种PDF阅读器 》设置选项中&#xff0c;选择打印整个工作簿。...

结合文本的目标检测:Open-GroundingDino训练自己的数据集

1、简单介绍 Open-GroundingDino是GroundingDino的第三方实现训练流程的代码&#xff0c;因为官方GroundingDino没有提供训练代码&#xff0c;只提供了demo推理代码。 关于GroundingDino的介绍可以看论文&#xff1a;https://arxiv.org/pdf/2303.05499.pdf GroundingDino的G…...

分布式锁-redission锁的MutiLock原理

5.5 分布式锁-redission锁的MutiLock原理 为了提高redis的可用性&#xff0c;我们会搭建集群或者主从&#xff0c;现在以主从为例 此时我们去写命令&#xff0c;写在主机上&#xff0c; 主机会将数据同步给从机&#xff0c;但是假设在主机还没有来得及把数据写入到从机去的时…...

MySQL索引、B+树相关知识汇总

MySQL索引、B树相关知识汇总 一、有一个查询需求&#xff0c;MySQL中有两个表&#xff0c;一个表1000W数据&#xff0c;另一个表只有几千数据&#xff0c;要做一个关联查询&#xff0c;如何优化&#xff1f;1、为关联字段建立索引二、小表驱动大表 二、b树和b树的区别1、更高的…...

相机模型浅析

相机模型 文章目录 相机模型四个坐标系针孔相机模型世界坐标系到相机坐标系相机坐标系到图像坐标系图像坐标到像素坐标 四个坐标系 ①世界坐标系&#xff1a;是客观三维世界的绝对坐标系&#xff0c;也称客观坐标系。因为数码相机安放在三维空间中&#xff0c;我们需要世界坐标…...

国芯科技(C*Core)双芯片汽车安全气囊解决方案

汽车安全气囊是20世纪汽车上的十大发明之一&#xff0c;是目前汽车的法定标准配置&#xff0c;成为汽车驾乘人员生命安全的保护神。随着人们对汽车安全性要求的进一步提高&#xff0c;已形成前排驾驶员气囊、前排副驾驶员气囊、前排侧气囊、后排侧气囊、膝部气囊、安全气帘等等…...

牛客周赛 Round 39(A,B,C,D,E,F,G)

比赛链接 官方题解&#xff08;视频&#xff09; B题是个贪心。CD用同余最短路&#xff0c;预处理的完全背包&#xff0c;多重背包都能做&#xff0c;比较典型。E是个诈骗&#xff0c;暴力就完事了。F是个线段树。G是个分类大讨论&#xff0c;出题人钦定的本年度最佳最粪 题目…...

解锁区块链技术的潜力:实现智能合约与DApps

在数字时代&#xff0c;区块链技术正迅速成为重塑多个行业的革命性力量。从金融服务到供应链管理&#xff0c;再到数字身份验证&#xff0c;区块链提供了一种去中心化、安全和透明的数据处理方式。在本文中&#xff0c;我们将深入探讨区块链技术&#xff0c;特别是智能合约和去…...

MAC OS关闭SIP(navicat 无法保存密码)

最近安装navicat&#xff08;16.3.7&#xff09;时,安装后无法保存密码,保存密码会报错如下&#xff1a; 因为用的破解版&#xff0c;一开始是打不开的&#xff0c;用自带的修复软件修复后就可以打开了&#xff0c;但是保存密码就会报错&#xff0c;按照网上的一些操作 1、卸载…...

阿里云服务器带宽价格全解析,附报价单

阿里云服务器公网带宽怎么收费&#xff1f;北京地域服务器按固定带宽计费一个月23元/M&#xff0c;按使用流量计费0.8元/GB&#xff0c;云服务器地域不同实际带宽价格也不同&#xff0c;阿里云服务器网aliyunfuwuqi.com分享不同带宽计费模式下带宽收费价格表&#xff1a; 公网…...

Day36|贪心算法part05:435. 无重叠区间、763.划分字母区间、56. 合并区间

435. 无重叠区间 有了上题射气球的因子&#xff0c;这题也就有思路了&#xff0c;反正无脑排序就行了&#xff1a; 首先将所有区间按照end的大小从小到大排序&#xff1b;选取最早end为起始x_end遍历所有区间&#xff0c;如果该区间的start比end大&#xff08;可重叠&#xf…...

棋牌室计时吧台计费收费灯控管理系统软件操作流程

棋牌室计时吧台计费收费灯控管理系统软件操作流程 一、前言 以下软件操作教程以&#xff0c;佳易王棋牌桌球计时计费管理系统软件灯控版V17.87为例说明 软件文件下载可以点击最下方官网卡片——软件下载——试用版软件下载 该计时计费软件可以是棋牌和桌球混合同时计时计费 …...

【实践篇】RabbitMQ实现队列延迟功能汇总

前言 记录下RabbitMQ实现延迟队列功能的所有实践内容。 前期准备&#xff0c;需要安装好docker、docker-compose的运行环境。 一、安装RabbitMQ 开启RabbitMQ的WEB管理功能。-CSDN博客 二、实现延迟队列的两种方式 RabbitMQ实现延迟队列的两种方式。-CSDN博客 三、实践文…...

EditPlus来啦(免费使用!)

hello&#xff0c;我是小索奇 今天推荐一款编辑器&#xff0c;是索奇学习JavaSE时入手滴&#xff0c;非常好用哈&#xff0c;小索奇还是通过老杜-杜老师入手滴&#xff0c;相信很多人也是通过老杜认识嘞&#xff0c;来寻找破解版或者准备入手这个间接使用的编辑器~ EditPlus是…...

蓝桥杯22年第十三届省赛-数组切分|线性DP

题目链接&#xff1a; 蓝桥杯2022年第十三届省赛真题-数组切分 - C语言网 (dotcpp.com) 1.数组切分 - 蓝桥云课 (lanqiao.cn) 这道题C语言网数据会强一些。 说明&#xff1a; 对于一个切分的子数组&#xff0c;由于数组是1-N的一个排列&#xff0c;所以每个数唯一 可以用子…...

小米汽车:搅动市场的鲶鱼or价格战砧板上的鱼肉?

3月28日晚&#xff0c;备受关注的小米汽车上市发布会召开&#xff0c;小米集团董事长雷军宣布小米SU7正式发布。小米汽车在带飞股价的同时&#xff0c;二轮订购迅速售尽。 图一&#xff1a;小米集团股价 雷军口中“小米汽车迈出的第一步&#xff0c;也是人生最后一战的开篇”&a…...

Docker 学习笔记(五):梳理 Docker 镜像知识,附带 Commit 方式提交镜像副本,安装可视化面板 portainer

一、前言 记录时间 [2024-4-10] 前置文章&#xff1a; Docker学习笔记&#xff08;一&#xff09;&#xff1a;入门篇&#xff0c;Docker概述、基本组成等&#xff0c;对Docker有一个初步的认识 Docker学习笔记&#xff08;二&#xff09;&#xff1a;在Linux中部署Docker&…...

K8S node节点执行kubectl get pods报错

第一个问题是由第二个问题产生的&#xff0c;第二个问题也是最常见的 网上找的都是从master节点把文件复制过来&#xff0c;这样确实可以解决&#xff0c;但是麻烦&#xff0c;有一个node节点还好&#xff0c;如果有多个呢&#xff1f;每个都复制吗&#xff1f;下面是我从外网…...

Appium+python自动化(十六)- ADB命令

简介 Android 调试桥(adb)是多种用途的工具&#xff0c;该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具&#xff0c;其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利&#xff0c;如安装和调试…...

【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密

在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...

Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务

通过akshare库&#xff0c;获取股票数据&#xff0c;并生成TabPFN这个模型 可以识别、处理的格式&#xff0c;写一个完整的预处理示例&#xff0c;并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务&#xff0c;进行预测并输…...

前端开发面试题总结-JavaScript篇(一)

文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包&#xff08;Closure&#xff09;&#xff1f;闭包有什么应用场景和潜在问题&#xff1f;2.解释 JavaScript 的作用域链&#xff08;Scope Chain&#xff09; 二、原型与继承3.原型链是什么&#xff1f;如何实现继承&a…...

智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制

在数字化浪潮席卷全球的今天&#xff0c;数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具&#xff0c;在大规模数据获取中发挥着关键作用。然而&#xff0c;传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时&#xff0c;常出现数据质…...

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)

上一章用到了V2 的概念&#xff0c;其实 Fiori当中还有 V4&#xff0c;咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务)&#xff0c;代理中间件&#xff08;ui5-middleware-simpleproxy&#xff09;-CSDN博客…...

C#中的CLR属性、依赖属性与附加属性

CLR属性的主要特征 封装性&#xff1a; 隐藏字段的实现细节 提供对字段的受控访问 访问控制&#xff1a; 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性&#xff1a; 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑&#xff1a; 可以…...

【前端异常】JavaScript错误处理:分析 Uncaught (in promise) error

在前端开发中&#xff0c;JavaScript 异常是不可避免的。随着现代前端应用越来越多地使用异步操作&#xff08;如 Promise、async/await 等&#xff09;&#xff0c;开发者常常会遇到 Uncaught (in promise) error 错误。这个错误是由于未正确处理 Promise 的拒绝&#xff08;r…...

什么是VR全景技术

VR全景技术&#xff0c;全称为虚拟现实全景技术&#xff0c;是通过计算机图像模拟生成三维空间中的虚拟世界&#xff0c;使用户能够在该虚拟世界中进行全方位、无死角的观察和交互的技术。VR全景技术模拟人在真实空间中的视觉体验&#xff0c;结合图文、3D、音视频等多媒体元素…...

Kubernetes 网络模型深度解析:Pod IP 与 Service 的负载均衡机制,Service到底是什么?

Pod IP 的本质与特性 Pod IP 的定位 纯端点地址&#xff1a;Pod IP 是分配给 Pod 网络命名空间的真实 IP 地址&#xff08;如 10.244.1.2&#xff09;无特殊名称&#xff1a;在 Kubernetes 中&#xff0c;它通常被称为 “Pod IP” 或 “容器 IP”生命周期&#xff1a;与 Pod …...