相机可用性变化监听AvailabilityCallback流程分析

相机可用性变化监听及流程分析

一、接口说明

​ 相机可用性变化监听可以通过CameraManager中的接口registerAvailabilityCallback()来设置回调,接口如下:

/**
*注册一个回调以获得有关相机设备可用性的通知。
*
*<p>再次注册相同的回调将用提供的新回调替换处理程序</p>
*
*<p>第一次注册回调时,会立即调用回调,并显示当前已知的所有相机设备的可用性状态</p>
*
*任何相机API客户端打开相机设备时,都会调用<p>{@linkAvailabilityCallback#onCameraUnavailable(String)}。从API级别23开始,其他相机API客户端可能仍然能够打开这样的相机设备,如果它们的优先级高于相机设备的现有客户端,则会逐出现有客户端。有关详细信息,请参阅open()</p>
*
*<p>由于此回调将在相机服务中注册,请记住在不再需要时注销它;否则,回调将无限期地继续接收事件,并可能阻止其他资源被释放。具体来说,回调将调用各个CameraManager实例的状态</p>
*
*@param callback 向发送相机可用性通知的新回调。
*@param handler 应该调用回调的handler,或者为{@code null}的话使用当前线程的{@linkandroid.os.Looper Looper}。
*
*如果handler为{@code null},但当前线程没有Looper,则@throws IllegalArgumentException。
*/
public void registerAvailabilityCallback(@NonNull AvailabilityCallback callback, @Nullable Handler handler)

AvailabilityCallback主要api如下:

    /***摄像机设备变为可用或不可用的回调。**<p>当不再使用相机或连接新的可移动相机时,相机将可用。当某些应用程序或服务开始使用相机时,或者当可移动相机断开连接时,它们将不可用</p>**<p>扩展此回调,并将子类的一个实例传递给{@link CameraManager#registerAvailabilityCallback},以便收到此类可用性更改的通知</p>**@参见#registerAvailabilityCallback*/public static abstract class AvailabilityCallback {/***一台新相机已经可以使用了。**<p>此方法的默认实现不执行任何操作</p>**@param cameraId新相机的唯一标识符。*/public void onCameraAvailable(@NonNull String cameraId) {// default empty implementation}/***以前可用的相机已无法使用。**<p>*如果一个应用程序有一个活动的CameraDevice实例用于现在断开连接的相机,该应用程序将收到{@link CameraDevice.StateCallback#onDisconnected disconnection error}*</p>**<p>此方法的默认实现不执行任何操作</p>**@param cameraId断开连接的摄像机的唯一标识符。*/public void onCameraUnavailable(@NonNull String cameraId) {// default empty implementation}/***每当摄像机访问优先级更改时调用。**<p>通知相机访问优先级已更改,相机现在可以打开。先前由于较高优先级的用户已经在使用相机而被拒绝访问相机的应用程序,或者由于较高优先级用户试图打开相机而与活动相机会话断开连接的应用程序如果仍想使用相机,则应尝试再次打开相机。请注意,多个应用程序可能同时接收此回调,并且在实践中,根据确切的访问优先级和时间,只有其中一个应用程序能够成功打开相机。如果多个应用程序可能同时处于恢复状态,并且用户在它们之间切换焦点,或者使用应用程序的当前相机在全屏和画中画(PiP)状态之间移动,则此方法非常有用。在这种情况下,摄像机可用/不可用回调将不会被调用,但另一个应用程序现在可能比当前使用摄像机的应用程序具有更高的摄像机访问优先级</p>**<p>此方法的默认实现不执行任何操作</p>*/public void onCameraAccessPrioritiesChanged() {// default empty implementation}/***一台物理相机已可再次使用。**<p>默认情况下,逻辑多摄像机的所有物理摄像机都可用,因此当调用逻辑多摄像机用的{@link#onCameraAvailable}时,不会为逻辑多摄像机中的任何物理摄像机调用{@link#onPhysicalCameraAvailable}。但是,如果某些特定的物理摄影机一开始就不可用,则可以在{@link#onCameraAvailable}之后调用{@link#onPhysicalCameraUnavailable}</p>**<p>此方法的默认实现不执行任何操作</p>**@param cameraId逻辑多摄像机的唯一标识符。*@param physicalCameraId物理相机的唯一标识符。**@请参阅#onCameraAvailable*@请参阅#onPhysicalCamera不可用*/public void onPhysicalCameraAvailable(@NonNull String cameraId,@NonNull String physicalCameraId) {// default empty implementation}/***以前可用的物理相机已无法使用。**<p>默认情况下,逻辑多摄像机的所有物理摄像机都可用,因此当调用逻辑多摄像机用的{@link#onCameraAvailable}时,不会为逻辑多摄像机中的任何物理摄像机调用{@link#onPhysicalCameraAvailable}。如果某些特定的物理相机一开始就不可用,则可以在{@link#onCameraAvailable}之后调用{@link#onPhysicalCameraUnavailable}</p>**<p>此方法的默认实现不执行任何操作</p>**@param cameraId逻辑多摄像机的唯一标识符。*@param physicalCameraId物理相机的唯一标识符。**@请参阅#onCameraAvailable*@请参阅#onPhysicalCameraAvailable*/public void onPhysicalCameraUnavailable(@NonNull String cameraId,@NonNull String physicalCameraId) {// default empty implementation}}

注意这里physical cameralogical multi-camera的区别:

  • physical camera:物理摄像头,对应实际的物理硬件。

  • logical multi-camera:是在某些支持的 Android 设备上引入的一项功能,它允许开发者同时使用多个摄像头来进行更高级的图像处理和功能。在逻辑多摄像头系统中,多个物理摄像头可以捆绑在一起,并被视为单个逻辑摄像头设备。这些物理摄像头可以包括不同的焦距、不同的传感器类型(例如彩色相机和红外相机)等。由于这些物理摄像头协同工作,它们可以为开发者提供更丰富的功能和更灵活的图像处理能力。

二、源码调用链分析

1.回调设置的过程

\frameworks\base\core\java\android\hardware\camera2\CameraManager.java

public void registerAvailabilityCallback(@NonNull AvailabilityCallback callback, @Nullable Handler handler) {CameraManagerGlobal.get().registerAvailabilityCallback(callback,                   CameraDeviceImpl.checkAndWrapHandler(handler));
}

调用到CameraManager的内部类CameraManagerGlobal的方法registerAvailabilityCallback:

\frameworks\base\core\java\android\hardware\camera2\CameraManager.java

public void registerAvailabilityCallback(AvailabilityCallback callback,Executor executor) {synchronized (mLock) {/*1.连接到CameraService,如果已经连接,不执行任何操作。*/connectCameraServiceLocked();/*2.将设置的callback存入mCallbackMap中。mCallbackMap专门用于存储可用性回调以及执行它们的Executor。*/Executor oldExecutor = mCallbackMap.put(callback, executor);// For new callbacks, provide initial availability informationif (oldExecutor == null) {/*3.如果oldExecutor为空,说明是第一次设置该可用性回调。将当前已知的所有相机的状态触发设置的callback回调,以便使监听者了解当前所有相机状态。*/updateCallbackLocked(callback, executor);}// If not connected to camera service, schedule a reconnect to camera service.if (mCameraService == null) {/*4.如果mCameraService为空说明连接CameraService失败,计划一次新的重连尝试。*/scheduleCameraServiceReconnectionLocked();}}
}

​ 到这里设置的可用性回调已经被存储到mCallbackMap当中,设置回调的流程完毕,后续相机状态变化触发回调时,将遍历mCallbackMap取出callback并执行相应的回调方法。

2.回调触发的过程

​ 这里主要关注回调AvailabilityCallback中的onCameraAvailable和onCameraUnavailable方法的触发。我将从这两个方法最终被调用的地方开始往前梳理调用链。

​ 发现方法最终被调用的地方只有一个,即为CameraManager的内部类CameraManagerGlobal的内部类中的private方法postSingleUpdate:

\frameworks\base\core\java\android\hardware\camera2\CameraManager.java

private void postSingleUpdate(final AvailabilityCallback callback,final Executor executor,final String id, final String physicalId, final int status) {/*略*/}

继续分析,发现调用postSingleUpdate的方法的地方为CameraManager的内部类CameraManagerGlobal中的另外3个private方法:

\frameworks\base\core\java\android\hardware\camera2\CameraManager.java

private void updateCallbackLocked(AvailabilityCallback callback,Executor executor) {/*略*/}
private void onStatusChangedLocked(int status, String id) {/*略*/}
private void onPhysicalCameraStatusChangedLocked(int status, String id, String physicalId) {/*略*/}

updateCallbackLocked方法只在注册回调时调用,忽略。关注onStatusChangedLocked和onPhysicalCameraStatusChangedLocked两个方法,从名称上可以看出这两个方法的用意,这里我们主要关注onStatusChangedLocked方法的调用。

发现调用onStatusChangedLocked方法的均为CameraManager的内部类CameraManagerGlobal中方法,包括以下4个方法:

\frameworks\base\core\java\android\hardware\camera2\CameraManager.java

private void connectCameraServiceLocked() {/*略*/}
public String[] getCameraIdListNoLazy() {/*略*/}
@Override
public void onStatusChanged(int status, String cameraId) throws RemoteException {/*略*/}
public void binderDied() {/*略*/}

其中onStatusChanged方法重写自CameraManagerGlobal实现的ICameraServiceListener.Stub接口,即该方法为相机框架中4个关键AIDL文件之一的CameraServiceListener.aidl中定义的方法,通过CameraServiceListener.aidl,CameraService可以调用CameraManager中的方法。(相机框架4个关键AIDL文件包括:ICameraService.aidl、ICameraDeviceCallback.aidl、ICameraDeviceUser.aidl、ICameraServiceListener.aidl)

所以现在直接追溯到CameraService中通过AIDL调用onStatusChanged的地方:

void CameraService::updateStatus(StatusInternal status, const String8& cameraId,std::initializer_list<StatusInternal>rejectSourceStates) {/*……略……*/for (auto& listener : mListenerList) {/*……略……*/listener->getListener()->onStatusChanged(mapToInterface(status),String16(cameraId));/*……略……*/}/*……略……*/
}

未完待续……

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/12796.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Nginx性能优化配置

一、全局优化 # 工作进程数 worker_processes auto; # 建议 CPU核心数|CPU线程数# 最大支持的连接(open-file)数量&#xff1b;最大值受限于 Linux open files (ulimit -n) # 建议公式&#xff1a;worker_rlimit_nofile > worker_processes * worker_connections…

vue指令-v-for

vue指令-v-for 1、目标2、语法语法 1、目标 列表渲染&#xff0c;所在标签结构&#xff0c;按照数据数量&#xff0c;循环生成 2、语法 v-for "(值变量&#xff0c;索引变量) in 目标结构"示例&#xff1a; <template><div id"app"><di…

安装Anaconda3和MiniConda3

MiniConda3官方版是一款优秀的Python环境管理软件。MiniConda3最新版只包含conda及其依赖项如果您更愿意拥有conda以及超过720个开源软件包&#xff0c;请安装Anaconda。MiniConda3官方版还是一个开源的软件包管理系统和环境管理系统&#xff0c;能够帮助用户安装多个版本的软件…

ChatGPT漫谈(三)

AIGC(AI Generated Content)指的是使用人工智能技术生成的内容,包括文字、图像、视频等多种形式。通过机器学习、深度学习等技术,AI系统可以学习和模仿人类的创作风格和思维模式,自动生成大量高质量的内容。AIGC被视为继用户生成内容(UGC)和专业生成内容(PGC)之后的下…

上传图片到腾讯云对象存储桶cos 【腾讯云对象存储桶】【cos】【el-upload】【vue3】【上传头像】【删除】

1、首先登录腾讯云官网控制台 进入对象存储页面 2、找到跨越访问CIRS设置 配置规则 点击添加规则 填写信息 3、书写代码 这里用VUE3书写 第一种用按钮出发事件形式 <template><div><input type="file" @change="handleFileChange" /&…

数值线性代数:奇异值分解SVD

本文记录计算矩阵奇异值分解SVD的原理与流程。 注1&#xff1a;限于研究水平&#xff0c;分析难免不当&#xff0c;欢迎批评指正。 零、预修 0.1 矩阵的奇异值 设列满秩矩阵&#xff0c;若的特征值为&#xff0c;则称为矩阵的奇异值。 0.2 SVD(分解)定理 设&#xff0c;则…

神经网络简单介绍

人工神经网络(artififial neural network) 简称神经网络&#xff0c;它是一种模仿生物神经网络结构和功能的非线性数学模型。 神经网络通过输入层接受原始特征信息&#xff0c;再通过隐藏层进行特征信息的加工和提取&#xff0c;最后通过输出层输出结果。 根据需要神经网络可以…

RTPSv2.2(中文版)

实时发布订阅协议 &#xff08;RTPS&#xff09; DDS互操作性 有线协议规范 V2.2 &#xff08;2014-09-01正式发布&#xff09; https://www.omg.org/spec/DDSI-RTPS/2.2/PDF 目 录 1 范围Scope 9 2 一致性Conformance 9 3 参考文献References 9 4 术语和定义Terms a…

centos(linux)手动配置ip地址

查看系统 查看ip 进入网卡配置的目录 [root178-119-30-16 ~]# cd /etc/sysconfig/network-scripts/ [root178-119-30-16 network-scripts]# ls ifcfg-ens192 ifdown ifdown-ippp ifdown-post ifdown-sit ifdown-tunnel ifup-bnep ifup-ipv6 ifup-plus…

【Mysql】万字长文带你快速掌握数据库基础概念及SQL基本操作

文章目录 前言一、数据库相关概念1. 什么是数据库2. 数据库的种类3. Mysql 简介4. SQL简介5. 数据库中常见的数据类型 二、SQL基础1. SQL通用语法2. SQL的主要分类3. DDL&#xff08;数据库&#xff0c;表&#xff0c;索引&#xff0c;视图&#xff09;4. DML&#xff08;数据的…

14:00面试,14:06就出来了,问的问题有点变态。。。

从小厂出来&#xff0c;没想到在另一家公司又寄了。 到这家公司开始上班&#xff0c;加班是每天必不可少的&#xff0c;看在钱给的比较多的份上&#xff0c;就不太计较了。没想到5月一纸通知&#xff0c;所有人不准加班&#xff0c;加班费不仅没有了&#xff0c;薪资还要降40%,…

【每日一题】—— A - 1-2-4 Test (AtCoder Beginner Contest 270)

&#x1f30f;博客主页&#xff1a;PH_modest的博客主页 &#x1f6a9;当前专栏&#xff1a;每日一题 &#x1f48c;其他专栏&#xff1a; &#x1f534; 每日反刍 &#x1f7e1; C跬步积累 &#x1f7e2; C语言跬步积累 &#x1f308;座右铭&#xff1a;广积粮&#xff0c;缓称…

HiveSQL SparkSQL中常用知识点记录

目录 0. 相关文章链接 1. hive中多表full join主键重复问题 2. Hive中选出最新一个分区中新增和变化的数据 3. Hive中使用sort_array函数解决collet_list列表排序混乱问题 4. SQL中对小数位数很多的数值转换成文本的时候不使用科学计数法 5. HiveSQL & SparkSQL中炸裂…

c#[WebMethod]方法接收前端传入的JsonArray的方法

一、第一种方法&#xff1a;可以这样接收前端传入的jsonArray字符串到一个类的数组中&#xff0c;然后遍历该数组取值 这种方法需要创建PointConfig类 class PointConfig{public string ptcrossing { get; set; }public string ptcrossingId { get; set; }public string camId …

小程序动态隐藏分享按钮

// 禁用分享 wx.hideShareMenu({menus: [shareAppMessage, shareTimeline] })// 显示分享 wx.showShareMenu({withShareTicket: true,menus: [shareAppMessage, shareTimeline] })//私密消息 wx.updateShareMenu({isPrivateMessage: true, })

驱动开发day3 7.25

ioctl控制LED、蜂鸣器、风扇、马达 (为每一个硬件注册一个驱动) 头文件 #ifndef __HEAD_H__ #define __HEAD_H__typedef struct{volatile unsigned int MODER;volatile unsigned int OTYPER;volatile unsigned int OSPEEDR;volatile unsigned int PUPDR;volatile unsigned in…

list与erase()

运行代码&#xff1a; //list与erase() #include"std_lib_facilities.h" //声明Item类 struct Item {string name;int iid;double value;Item():name(" "),iid(0),value(0.0){}Item(string ss,int ii,double vv):name(ss),iid(ii),value(vv){}friend istr…

JMM是如何保证原子性呢?

3.3.1加锁 锁是一种通用技术&#xff0c;比如Java提供的Synchronized关键字就是锁的一种实现&#xff0c;Synchronized是排他锁/独占锁&#xff0c;就是有你没我的意思&#xff0c;只要其他线程到来访问&#xff0c;发现锁还未释放&#xff0c;就要在外面等待&#xff0c;因为S…

Redis—相关背景

Redis—相关背景 &#x1f50e;Redis—特性In-memory data structures—在内存中存储数据Programmability—可编程性Extensibility—可扩展性Persistence—持久化Clustering—集群High availability—高可用 &#x1f50e;Redis 为什么快&#x1f50e;Redis 的使用场景Real-tim…

【TiDB理论知识06】PD架构与作用

目录 一 PD的架构与功能 PD架构 PD作用 名词解释 路由功能 二 TSO的分配 概念 分配过程 性能问题 高可用问题 三 PD的调度原理 总流程 1 信息收集 2 生成调度 3 执行调度 四 Label的作用 Label的配置 给TiKV打标签 PD配置 一 PD的架构与功能 PD架构 PD集群…