安卓如何实现双击触摸唤醒点亮屏幕功能-源码分析linage os高通平台

news2024/10/9 5:07:48

背景:

前面文章已经有讲解过双击亮屏在一些方案调研情况,刚好linage os手机本身也有这个功能,刚好也有整体开源源码,所以今天带大家来对双击亮屏的源码部分进行剖析,本篇文章会一直分析到hal操作驱动节点。

设置作为切入点分析

根据字符tap to wake尝试grep相关字符在Settings这个代码中

nx563j_aosp14/packages/apps/Settings$ grep "tap_to_wake" ./ -rn
./src/com/android/settings/display/TapToWakePreferenceController.java:28:    private static final String KEY_TAP_TO_WAKE = "tap_to_wake";

看看相关代码


    @Override
    public boolean onPreferenceChange(Preference preference, Object newValue) {
        boolean value = (Boolean) newValue;
        Settings.Secure.putInt(
                mContext.getContentResolver(), Settings.Secure.DOUBLE_TAP_TO_WAKE, value ? 1 : 0);
        return true;
    }

这里PowerManagerService会监听settings值的变化然后进行设置
frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java

  private final class SettingsObserver extends ContentObserver {
        public SettingsObserver(Handler handler) {
            super(handler);
        }

        @Override
        public void onChange(boolean selfChange, Uri uri) {
            synchronized (mLock) {
                handleSettingsChangedLocked();
            }
        }
    }

具体对DOUBLE_TAP_TO_WAKE的处理

if (mSupportsDoubleTapWakeConfig) {
    boolean doubleTapWakeEnabled = Settings.Secure.getIntForUser(resolver,
            Settings.Secure.DOUBLE_TAP_TO_WAKE, DEFAULT_DOUBLE_TAP_TO_WAKE,
                    UserHandle.USER_CURRENT) != 0;
    if (doubleTapWakeEnabled != mDoubleTapWakeEnabled) {
        mDoubleTapWakeEnabled = doubleTapWakeEnabled;
        mNativeWrapper.nativeSetPowerMode(Mode.DOUBLE_TAP_TO_WAKE, mDoubleTapWakeEnabled);
    }
}

    /** Wrapper for PowerManager.nativeSetPowerMode */
        public boolean nativeSetPowerMode(int mode, boolean enabled) {
            return PowerManagerService.nativeSetPowerMode(mode, enabled);
        }

java代码就最后调用到了nativeSetPowerMode

native层面分析

frameworks/base/services/core/jni/com_android_server_power_PowerManagerService.cpp

static jboolean nativeSetPowerMode(JNIEnv* /* env */, jclass /* clazz */, jint mode,
                                   jboolean enabled) {
    return setPowerMode(static_cast<Mode>(mode), enabled);
}

static bool setPowerMode(Mode mode, bool enabled) {
    android::base::Timer t;
    auto result = gPowerHalController.setMode(mode, enabled);
    if (mode == Mode::INTERACTIVE && t.duration() > 20ms) {
        ALOGD("Excessive delay in setting interactive mode to %s while turning screen %s",
              enabled ? "true" : "false", enabled ? "on" : "off");
    }
    return result.isOk();
}

这里在native代码最后调用到了setPowerMode再接下来调用到PowerHalController的setMode

frameworks/native/services/powermanager/PowerHalController.cpp

HalResult<void> PowerHalController::setMode(Mode mode, bool enabled) {
    std::shared_ptr<HalWrapper> handle = initHal();
    auto result = handle->setMode(mode, enabled);
    return processHalResult(result, "setMode");
}

这里的initHal明显可以看出其实是返回一个hal的接口来进行后面的setMode调用

std::shared_ptr<HalWrapper> PowerHalController::initHal() {
    std::lock_guard<std::mutex> lock(mConnectedHalMutex);
    if (mConnectedHal == nullptr) {
        mConnectedHal = mHalConnector->connect();
    }
    return mConnectedHal;
}

这里进行了connect调用返回hal接口

std::unique_ptr<HalWrapper> HalConnector::connect() {
    sp<IPower> halAidl = PowerHalLoader::loadAidl();
    if (halAidl) {
        return std::make_unique<AidlHalWrapper>(halAidl);
    }
    sp<V1_0::IPower> halHidlV1_0 = PowerHalLoader::loadHidlV1_0();
    sp<V1_1::IPower> halHidlV1_1 = PowerHalLoader::loadHidlV1_1();
    if (halHidlV1_1) {
        return std::make_unique<HidlHalWrapperV1_1>(halHidlV1_0, halHidlV1_1);
    }
    if (halHidlV1_0) {
        return std::make_unique<HidlHalWrapperV1_0>(halHidlV1_0);
    }
    return nullptr;
}

可以看出这里会依次加载aidl,hidl等接口,正常有aidl就会直接返回,没有就再加载hidl接口,这里的就需要结合具体设备上power hal的提供情况

power的aidl hal分析

我的机器设备是aidl的hal类型,hal代码是lineage os开源的,属于高通的通用一套8998代码
具体路径:
vendor/qcom/opensource/power

大家注意哈,这个hal代码路径大家自己根据情况确定,这种方式适合lineage os自带了高通开源代码
那么知道了路径后,继续分析上面提到的handle->setMode方法最后调用到了如下方法
hal实现代码路径:vendor/qcom/opensource/power/Power.cpp


ndk::ScopedAStatus Power::setMode(Mode type, bool enabled) {
    LOG(ERROR) << "Power setMode: " << static_cast<int32_t>(type) << " to: " << enabled;
#ifdef MODE_EXT
    if (setDeviceSpecificMode(type, enabled)) {
        return ndk::ScopedAStatus::ok();
    }
#endif
    switch (type) {
#ifdef TAP_TO_WAKE_NODE//可以看到这里有一个宏,而且是根据mk中变量确定编译宏
        case Mode::DOUBLE_TAP_TO_WAKE:
        			//直接把enabled的值写入到TAP_TO_WAKE_NODE这个路径
            ::android::base::WriteStringToFile(enabled ? "1" : "0", TAP_TO_WAKE_NODE, true);
            break;
#else
        case Mode::DOUBLE_TAP_TO_WAKE:
#endif
        case Mode::LOW_POWER:
        case Mode::DEVICE_IDLE:
        case Mode::DISPLAY_INACTIVE:
        case Mode::AUDIO_STREAMING_LOW_LATENCY:
        case Mode::CAMERA_STREAMING_SECURE:
        case Mode::CAMERA_STREAMING_LOW:
        case Mode::CAMERA_STREAMING_MID:
        case Mode::CAMERA_STREAMING_HIGH:
        case Mode::VR:
  //省略
    }
    return ndk::ScopedAStatus::ok();
}

上面的#ifdef TAP_TO_WAKE_NODE这个宏已经在前面文章给大家剖析过,所以很容易知道这里的TAP_TO_WAKE_NODE值

TARGET_TAP_TO_WAKE_NODE := "/sys/class/touch/tpnode/synaptics/wake_gesture"

实际上到这里就很清楚hal中干的事情,就是对/sys/class/touch/tpnode/synaptics/wake_gesture写入对应的值0或1,具体也可以通过设置中开关,然后验证/sys/class/touch/tpnode/synaptics/wake_gesture的值

在这里插入图片描述

adb shell cat /sys/class/touch/tpnode/synaptics/wake_gesture
1

在这里插入图片描述

 adb shell cat /sys/class/touch/tpnode/synaptics/wake_gesture
0

那么剩下的事就是驱动层面实现的事情,本篇文章就不对驱动部分进行深入剖析了。

更多framework详细代码和资料参考如下链接
投屏专题部分:

https://mp.weixin.qq.com/s/IGm6VHMiAOPejC_H3N_SNg

hal+perfetto+surfaceflinger

https://mp.weixin.qq.com/s/LbVLnu1udqExHVKxd74ILg
其他课程七件套专题:在这里插入图片描述
点击这里
https://mp.weixin.qq.com/s/Qv8zjgQ0CkalKmvi8tMGaw

视频试看:
https://www.bilibili.com/video/BV1wc41117L4/

参考相关链接:
https://blog.csdn.net/zhimokf/article/details/137958615

更多framework假威风耗:androidframework007

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

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

相关文章

有点晕,inline, crossinline,noinline小计

inline 主要用于展开铺平函数&#xff0c;用于高频访问但是代码不是很多的方法&#xff0c;减少函数对象的定义 fun <T> List<T>.normalForeach(action:(T)->Unit){for(item in this){action(item)} }inline fun <T> List<T>.inlinedForeach(action…

易图讯军用VR三维电子沙盘系统

深圳易图讯军用VR三维电子沙盘系统是一种集成了虚拟现实&#xff08;VR&#xff09;技术、三维建模技术、大数据分析、实时动态更新以及高度安全可靠的综合性军事指挥平台。该系统通过高精度三维模型真实再现战场环境&#xff0c;为指挥员提供沉浸式体验和交互操作的可能性&…

使用CANFD路由实现CAN与CANFD互通

随着科技的发展&#xff0c;汽车电子和工业领域中CAN通信需要承载数据量也越来越大&#xff0c;传统CAN通信有了向CANFD通信过渡的倾向。在实现过渡的过程中可能会出现自己设备是CAN通信&#xff0c;客户设备是CANFD通信的情况&#xff0c;或者自己设备是CANFD通信&#xff0c;…

react项目引入ant-design

当前react版本为&#xff1a; 1、安装antd npm install antd --save不需要安装babel-plugin-import&#xff0c;否则会报各种问题 2、引入Ant Design 样式 为了确保 Ant Design 样式在页面中生效&#xff0c;你需要在 _app.js 文件中全局引入样式。 当前项目用的Next.js。Ne…

vscode创建flutter项目,运行flutter项目

打开View&#xff08;查看&#xff09; > Command Palette...&#xff08;命令面板&#xff09;。 可以按下 Ctrl / Cmd Shift P 输入 flutter 选择Flutter: New Project 命令 按下 Enter 。选择Application 选择项目地址 输入项目名称 。按下 Enter 等待项目初始化完成 …

【HarmonyOS开发笔记 1】 -- 开发环境的搭建

DevEco Studio 的下载与安装 下载 下载路径&#xff1a; https://developer.huawei.com/consumer/cn/download/ 安装 解压后双击 deveco-studio-5.0.3.814.exe 指定安装目录&#xff0c;或者默认&#xff0c;然后下一步 一直“下一步”&#xff0c; 直到最后安装完成 新…

主机加固的关键要素:服务器防病毒

在数字化浪潮中&#xff0c;网络安全已成为企业不可忽视的一环。尤其是安全运维人员&#xff0c;他们肩负着保护企业数据不受侵害的重任。MCK主机加固解决方案&#xff0c;正是为了应对这一挑战而生。 网络安全的严峻现实 不久前&#xff0c;一家知名企业因勒索病毒攻击而被迫…

MVC、MVP和MVVM之间的区别

MVC&#xff08;Model-View-Controller&#xff09; 角色划分&#xff1a; Model&#xff1a;负责处理数据和业务逻辑&#xff0c;通常包括数据的存储、检索和更新等操作。 View&#xff1a;负责展示用户界面&#xff0c;接收用户输入&#xff0c;并将用户操作传递给 Controll…

如何在Visual Studio 2019中创建.Net Core WPF工程

如何在Visual Studio 2019中创建.Net Core WPF工程 打开Visual Studio 2019&#xff0c;选择Create a new project 选择WPF App(.Net Core) 输入项目名称和位置&#xff0c;单击Create 这样我们就创建好了一个WPF工程 工程文件说明 Dependencies 当前项目所使用的依赖库&…

java面向对之象类的继承与多态

目录 1.类的继承 图解 案例:创建一个动物类和一个猫类 1.代码 1)动物类 2)猫类 3.测试类 2.效果 2.父类方法的重写 案例:如何重写父类的方法 1.代码 1&#xff09;Animal类 2&#xff09;Dog类 3&#xff09;测试类 2.效果 3.super关键字 案例:如何在子类中调用父类的方…

如何使用 Puppeteer 和 Browserless 运行自动化测试?

Puppeteer&#xff1a;什么是 Puppeteer 及其功能 Puppeteer 是一个 Node.js 库。使用 Puppeteer&#xff0c;您可以在所有基于 Chromium 的浏览器上测试您的网站&#xff0c;包括 Chrome、Microsoft Edge Chrome 和 Chromium。此外&#xff0c;Puppeteer 可用于网页抓取、自动…

PDF处理技巧:Windows电脑如何选择合适的 PDF 编辑器

您可以阅读本文以了解用于在 PC 上编辑 PDF 的顶级免费软件&#xff0c;而无需花费任何费用即可轻松进行快速编辑、拆分、合并、注释、转换和共享您的 PDF。 PDF 或可移植文档文件是由 Adobe 创建的一种多功能文件格式。它可以帮助您轻松可靠地交换文档&#xff0c;无论相关方…

电脑端视频通过PCIE到FPGA端转UDP网络视频输出,基于XDMA+PHY芯片架构,提供3套工程源码和技术支持

目录 1、前言工程概述免责声明 2、相关方案推荐我已有的PCIE方案我这里已有的以太网方案 3、PCIE基础知识扫描4、工程详细设计方案工程设计原理框图电脑端视频PCIE视频采集QT上位机XDMA配置及使用XDMA中断模块FDMA图像缓存UDP视频组包发送UDP协议栈MAC数据缓冲FIFO组Tri Mode E…

基于php+uniapp微信小程序的电子书阅读系统snxr5

目录 项目介绍技术栈和环境说明具体实现截图php技术介绍文件解析微信开发者工具HBuilderXuniapp开发技术简介解决的思路性能/安全/负载方面数据访问方式PHP核心代码部分展示代码目录结构解析系统测试详细视频演示源码获取 项目介绍 &#xff08;1&#xff09;用户在安卓APP页面…

微信小程序启动不起来,报错凡是以~/包名/*.js路径的文件,都找不到,试过网上一切方法,最终居然这么解决的,【避坑】命运的齿轮开始转动

app.json "resolveAlias": {"~/*": "/*"},文件代码也没有问题&#xff0c;网上的方法试过来了&#xff0c;大模型AI也问过遍&#xff0c;熬夜到凌晨2点半&#xff0c;最不可思议的是居然是因为微信开发者工具版本的问题&#xff0c;我真的是笑死…

深入了解Oracle OCP认证,开启数据库专业之旅

使用Oracle数据库的公司内部&#xff0c;经常有员工们在讨论OCP认证(Oracle Certified Professional&#xff0c;Oracle认证专家)&#xff0c;这是甲骨文Oracle公司提供的一种专业认证&#xff0c;认证用于使用者在Oracle技术领域的专业知识和技能。 在这里&#xff0c;有一点…

Qt小bug — LINK : fatal error LNK1158: 无法运行“rc.exe“

Qt小bug —— LINK &#xff1a;fatal error LNK1158&#xff1a;无法运行"rc.exe" 环境 Qt 5.14.2 MSVC 2015 x64 现象 解决 在电脑上找到rc.exe 和rcdll.dll &#xff08;一般在C:\Program Files(x86)\Windows Kits*\bin\x64下面&#xff09;拷贝到 C:\Qt\Qt5…

高并发 - 1.进程和线程

1.进程 1.基本概念 1.进程&#xff08;Process&#xff09;&#xff1a;程序的一次启动执行(程序在执行过程中分配和管理资源的基本单位&#xff0c;操作系统资源分配的最小单位)2.程序&#xff1a;存放在硬盘中的可执行文件&#xff0c;主要包括代码指令和数据3.一个进程是一个…

常见的负载均衡

1.常见的负载均衡服务 负载均衡服务是分布式系统中用于分配网络流量和请求的关键组件&#xff0c;它可以帮助提高应用程序的可用性、可扩展性和响应速度。以下是一些常用的负载均衡服务&#xff1a; Nginx&#xff1a;一个高性能的Web服务器和反向代理&#xff0c;广泛用于实现…

【基于YOLOv5的反光衣检测预警系统】可检测图片、视频、摄像头,支持GPU加速检测以及语音播报预警

文章目录 演示视频系统界面项目环境系统界面功能项目框架介绍项目代码获取 ➷点击跳转至文末完整项目代码下载处☇ 演示视频 【基于YOLOv5的反光衣检测预警系统】可检测图片、视频、摄像头&#xff0c;支持GPU加速检测以及语音播报预警 系统界面 项目环境 项目运行所需环境为…