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

Android学习14--charger

1 概述

最近正好在做关机充电这个,就详细看看吧。还是本着保密的原则,项目里的代码也不能直接用,这里就用的Github的。https://github.com/aosp-mirror

具体位置是:https://github.com/aosp-mirror/platform_system_core/tree/main/healthd

核心代码压缩包只有3M,比起AOSP整包的极度臃肿真是对比强烈。 

2 代码框架

首先还是看BP,编译的产物是charger,但是在新版AOSP中服务却不是这个名字。新的是android.hardware.health-service.qti,此外后面带一个--charger的参数。

cc_binary {name: "charger",defaults: ["charger_defaults"],recovery_available: true,srcs: ["charger.cpp","charger_utils.cpp",],shared_libs: ["android.hardware.health@2.0","android.hardware.health@2.1",],target: {recovery: {// No UI and libsuspend for recovery charger.cflags: ["-DCHARGER_FORCE_NO_UI=1",],exclude_shared_libs: ["libpng",],exclude_static_libs: ["libhealthd_draw","libhealthd_charger","libhealthd_charger_ui","libminui","libsuspend",],}}
}

 模块里面有个测试程序,可以看看整个模块的用法。

int main(int /*argc*/, char** /*argv*/) {const char* dumpFile = "/data/local/tmp/dump.txt";auto config = std::make_unique<healthd_config>();InitHealthdConfig(config.get());healthd_board_init(config.get());sp<IHealth> passthrough = new TestHealth(std::move(config));std::thread bgThread([=] {android::ChargerHidl charger(passthrough);charger.StartLoop();});// wait for healthd_init to finishif (!getUpdateNotifier().waitFor(1000 /* wait ms */, true /* updated */)) {LOG_THIS("Time out.");exit(1);}passthrough->debug(createHidlHandle(dumpFile), {} /* options */);std::string content = openToString(dumpFile);int status = expectContains(content, {"status: 4","health: 6","present: 1","level: 47","voltage: 45","temp: 987","current now: 99000","current avg: 98000","charge counter: 600","current now: 99","cycle count: 77","Full charge: 3515547"});if (status == 0) {LOG_THIS("Test success.");} else {LOG_THIS("Actual dump:\n%s", content.c_str());}exit(status);  // force bgThread to exit
}

可以看到,就是

android::ChargerHidl charger(passthrough);

charger.StartLoop();

在Android的HIDL(HAL Interface Definition Language)框架中,StartLoop是一个用于启动HIDL服务端线程循环的方法。它允许HIDL服务端在一个独立的线程中运行,以便可以接收和处理来自客户端的请求。具体来说,StartLoop方法会创建一个线程池,并在这个线程池中运行,使得服务端可以异步处理多个客户端请求

3 重点流程

整个其实是一个提供Hidl接口的服务。提供的接口如下:

AIDL implementationHIDL implementation
Health::getChargeCounterUahHealth::getChargeCounter
Health::getCurrentNowMicroampsHealth::getCurrentNow
Health::getCurrentAverageMicroampsHealth::getCurrentAverage
Health::getCapacityHealth::getCapacity
Health::getChargeStatusHealth::getChargeStatus
Health::getEnergyCounterNwhHealth::getEnergyCounter
Health::getDiskStatsHealth::getDiskStats
Health::getStorageInfoHealth::getStorageInfo
Health::BinderEventBinderHealth::BinderEvent
Health::dumpHealth::debug
Health::ShouldKeepScreenOnHealth::shouldKeepScreenOn
Health::UpdateHealthInfoHealth::UpdateHealthInfo

类的定义如下:

namespace android {// An implementation of Charger backed by HIDL implementation. Uses HIDL health
// HAL's HalHealthLoop.
class ChargerHidl : public ::android::ChargerConfigurationInterface,public ::android::hardware::health::V2_1::implementation::HalHealthLoop {using HalHealthLoop = ::android::hardware::health::V2_1::implementation::HalHealthLoop;using HealthInfo_2_1 = android::hardware::health::V2_1::HealthInfo;public:explicit ChargerHidl(const sp<android::hardware::health::V2_1::IHealth>& service);std::optional<bool> ChargerShouldKeepScreenOn() override;bool ChargerIsOnline() override { return HalHealthLoop::charger_online(); }void ChargerInitConfig(healthd_config* config) override { return HalHealthLoop::Init(config); }int ChargerRegisterEvent(int fd, BoundFunction func, EventWakeup wakeup) override {return HalHealthLoop::RegisterEvent(fd, func, wakeup);}bool ChargerEnableSuspend() override;// HealthLoop overridesvoid Heartbeat() override { charger_->OnHeartbeat(); }int PrepareToWait() override { return charger_->OnPrepareToWait(); }void Init(struct healthd_config* config) override { charger_->OnInit(config); }// HalHealthLoop overridesvoid OnHealthInfoChanged(const HealthInfo_2_1& health_info) override;private:sp<android::hardware::health::V2_1::IHealth> service_;std::unique_ptr<Charger> charger_;
};

这里面有个私有变量是std::unique_ptr<Charger> charger_;,在init的时候会同时初始化charger类。ChargerHidl类很多实现还是直接调用的Charger类方法。主要的定义还是在Charger类中。

这部分主要的功能也是在Charger::OnInit里面启动的。这里有一个epoll。之前写过这部分,可以参考:小试epoll-CSDN博客

不过charger好像不是epoll,里面有一个Charger::OnHeartbeat(),在每次的心跳中处理状态和事件。包括插拔充电器和按下电源键。

大概就是这些吧,只是粗略的过了一遍,看的也不是太仔细。。。

4 题外话

对了, 从代码中可以看出,对于C++的高级应用还是很熟的。这点挺厉害的。

template <typename T>
class Atomic {public:Atomic(T&& init) : mValue(std::move(init)) {}void set(T&& newVal) {{std::lock_guard<std::mutex> lock(mMutex);mValue = std::move(newVal);}mChanged.notify_all();}bool waitFor(long ms, const T& expectVal) {std::unique_lock<std::mutex> lock(mMutex);return mChanged.wait_for(lock, std::chrono::milliseconds(ms),[this, &expectVal] { return mValue == expectVal; });}private:std::mutex mMutex;std::condition_variable mChanged;T mValue;
};Atomic<bool>& getUpdateNotifier() {static Atomic<bool> val(false);return val;
}

5 参考

https://source.android.com/docs/core/perf/health?hl=zh-cn

相关文章:

Android学习14--charger

1 概述 最近正好在做关机充电这个&#xff0c;就详细看看吧。还是本着保密的原则&#xff0c;项目里的代码也不能直接用&#xff0c;这里就用的Github的。https://github.com/aosp-mirror 具体位置是&#xff1a;https://github.com/aosp-mirror/platform_system_core/tree/mai…...

页面开发样式和布局入门:Vite + Vue 3 + Less

页面开发样式和布局入门&#xff1a;Vite Vue 3 Less 引言 在现代前端开发中&#xff0c;样式和布局是页面开发的核心部分。随着技术的不断发展&#xff0c;Vite、Vue 3和Less等工具和框架的出现&#xff0c;使得前端开发变得更加高效和灵活。然而&#xff0c;尽管这些工具…...

瑞芯微RK3566/RK3568开发板安卓11固件ROOT教程,Purple Pi OH演示

本文介绍RK3566/RK3568开发板Android11系统&#xff0c;编译ROOT权限固件的方法。触觉智能Purple Pi OH鸿蒙开发板演示&#xff0c;搭载了瑞芯微RK3566四核处理器&#xff0c;Laval鸿蒙社区推荐开发板&#xff0c;已适配全新OpenHarmony5.0 Release系统&#xff0c;SDK源码全开…...

Netty 入门应用:结合 Redis 实现服务器通信

在上篇博客中&#xff0c;我们了解了 Netty 的基本概念和架构。本篇文章将带你深入实践&#xff0c;构建一个简单的 Netty 服务端&#xff0c;并结合 Redis 实现一个数据存取的示例。在这个场景中&#xff0c;Redis 作为缓存存储&#xff0c;Netty 作为服务端处理客户端请求。通…...

试题转excel;pdf转excel;试卷转Excel,word试题转excel

一、问题描述 一名教师朋友&#xff0c;偶尔会需要整理一些高质量的题目到excel中 以往都是手动复制搬运&#xff0c;几百道题几乎需要一个下午的时间 关键这些事&#xff0c;枯燥无聊费眼睛&#xff0c;实在是看起来就很蠢的工作 就想着做一个工具&#xff0c;可以自动处理…...

查看网卡设备Bus号

在Linux系统中&#xff0c;通过ip命令能够看到网卡设备的名称&#xff0c;那么怎么看这个网卡设备对应的硬件设备以及Bus号&#xff1f; 例如在下面的虚拟机中能够看到有一个网口名为enp1s0 如何查看这个设备对应的Bus编号&#xff0c;可以在/sys中找到对应的设备 ll /sys/cl…...

鸿蒙Next星河版高级用例之网络请求和自适应布局以及响应式布局

目录&#xff1a; 1、发起网络请求的两种方式第一种使用httpRequest发送http的请求&#xff1a;1.1、在进行网络请求前&#xff0c;您需要在module.json5文件中申明网络访问权限1.2、GET 请求1.3、POST请求1.4、处理响应的结果第二种使用axios发送http的请求&#xff1a;1.1、在…...

鸿蒙技术分享:敲鸿蒙木鱼,积____功德——鸿蒙元服务开发:从入门到放弃(3)...

本文是系列文章&#xff0c;其他文章见&#xff1a;敲鸿蒙木鱼&#xff0c;积____功德&#x1f436;&#x1f436;&#x1f436;——鸿蒙元服务开发&#xff1a;从入门到放弃(1)敲鸿蒙木鱼&#xff0c;积____功德&#x1f436;&#x1f436;&#x1f436;——鸿蒙元服务开发&am…...

Hadoop生态圈框架部署 伪集群版(六)- MySQL安装配置

文章目录 前言一、MySQL安装与配置1. 安装MySQL2. 安装MySQL服务器3. 启动MySQL服务并设置开机自启动4. 修改MySQL初始密码登录5. 设置允许MySQL远程登录6. 登录MySQL 卸载1. 停止MySQL服务2. 卸载MySQL软件包3. 删除MySQL配置文件及数据目录 前言 在本文中&#xff0c;我们将…...

【Docker】创建Docker并部署Web站点

要在服务器上创建Docker容器&#xff0c;并在其中部署站点&#xff0c;你可以按照以下步骤操作。我们将以Flask应用为例来说明如何完成这一过程。 1. 准备工作 确保你的服务器已经安装了Docker。如果没有&#xff0c;请根据官方文档安装&#xff1a; Docker 安装指南 2. 创…...

实验七 用 MATLAB 设计 FIR 数字滤波器

实验目的 加深对窗函数法设计 FIR 数字滤波器的基本原理的理解。 学习用 Matlab 语言的窗函数法编写设计 FIR 数字滤波器的程序。 了解 Matlab 语言有关窗函数法设计 FIR 数字滤波器的常用函数用法。 掌握 FIR 滤波器的快速卷积实现原理。 不同滤波器的设计方法具有不同的优…...

学习ESP32开发板安装鸿蒙操作系统(新板子esp32c3不支持)

鸿蒙LiteOS网址&#xff1a;LiteOS: Huawei LiteOS开源代码官方主仓库.LiteOS Studio 开发工具请访问https://gitee.com/LiteOS/LiteOS_Studio 失败的实践记录见&#xff1a;完全按照手册win10里装Ubuntu 虚拟机然后编译ESP32&#xff08;主要是想针对ESP32C3和S3&#xff09;…...

asp.net core过滤器应用

筛选器类型 授权筛选器 授权过滤器是过滤器管道的第一个被执行的过滤器&#xff0c;用于系统授权。一般不会编写自定义的授权过滤器&#xff0c;而是配置授权策略或编写自定义授权策略。简单举个例子。 using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCo…...

力扣面试题 31 - 特定深度节点链表 C语言解法

题目&#xff1a; 给定一棵二叉树&#xff0c;设计一个算法&#xff0c;创建含有某一深度上所有节点的链表&#xff08;比如&#xff0c;若一棵树的深度为 D&#xff0c;则会创建出 D 个链表&#xff09;。返回一个包含所有深度的链表的数组。 示例&#xff1a; 输入&#xf…...

WordPress阅读文章显示太慢的处理

有两种方式&#xff0c; 1. 完全静态化。 动态都变成html&#xff0c;不再查数据库就快了。 但尝试了几个插件&#xff0c;都未成功。算了后面再研究。 2. cache缓存 用了WP Super Cache测试了一下&#xff0c;打开过一次后&#xff0c;文章秒开&#xff0c;也算达到了要求…...

关于多个线程共享一个实例对象

在多线程环境中&#xff0c;多个线程可能同时调用同一个对象的实例方法&#xff0c;这时候需要考虑如何保证线程安全。理解不同场景下的线程安全性是至关重要的&#xff0c;特别是当方法涉及共享状态时。 1. 共享实例与方法执行 共享实例&#xff1a;多个线程共享同一个实例对…...

【C++】printf 函数详解与格式化输出控制

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 &#x1f4af;前言&#x1f4af;printf 基础用法1.1 printf 的常见占位符1.2 占位符与参数的对应关系1.3 换行控制示例&#xff1a; &#x1f4af;格式化输出控制2.1 输出宽度控制2.1.1 指定最小宽度 2.2 …...

HDFS 操作命令

在现代的企业环境中&#xff0c;单机容量往往无法存储大量数据&#xff0c;需要跨机器存储。统一管理分布在 集群上的文件系统称为 分布式文件系统 。 HDFS &#xff08; Hadoop Distributed File System &#xff09;是 Apache Hadoop 项目的一个子项目&#xff0c; Hadoo…...

html ul li 首页渲染多条数据 但只展示八条,其余的数据全部隐藏,通过icon图标 进行展示

<div style"float: left;" id"showMore"> 展开 </div> <div style"float: left;“id"hideLess"> 收起 </div> var data document.querySelectorAll(.allbox .item h3 a); const list document.querySelectorAl…...

Facebook:筑牢隐私安全堡垒,守护社交净土

在全球社交媒体平台中&#xff0c;Facebook一直是风靡全球的佼佼者。然而&#xff0c;随着数字化信息的迅速膨胀&#xff0c;用户隐私保护的重要性日益凸显。面对用户对数据安全性的高度重视&#xff0c;Facebook致力于通过一系列措施来确保隐私保护&#xff0c;守护每位用户的…...

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...

生成xcframework

打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式&#xff0c;可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...

利用ngx_stream_return_module构建简易 TCP/UDP 响应网关

一、模块概述 ngx_stream_return_module 提供了一个极简的指令&#xff1a; return <value>;在收到客户端连接后&#xff0c;立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量&#xff08;如 $time_iso8601、$remote_addr 等&#xff09;&a…...

智能在线客服平台:数字化时代企业连接用户的 AI 中枢

随着互联网技术的飞速发展&#xff0c;消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁&#xff0c;不仅优化了客户体验&#xff0c;还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用&#xff0c;并…...

C++ 基础特性深度解析

目录 引言 一、命名空间&#xff08;namespace&#xff09; C 中的命名空间​ 与 C 语言的对比​ 二、缺省参数​ C 中的缺省参数​ 与 C 语言的对比​ 三、引用&#xff08;reference&#xff09;​ C 中的引用​ 与 C 语言的对比​ 四、inline&#xff08;内联函数…...

C# 类和继承(抽象类)

抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...

ios苹果系统,js 滑动屏幕、锚定无效

现象&#xff1a;window.addEventListener监听touch无效&#xff0c;划不动屏幕&#xff0c;但是代码逻辑都有执行到。 scrollIntoView也无效。 原因&#xff1a;这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作&#xff0c;从而会影响…...

Pinocchio 库详解及其在足式机器人上的应用

Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库&#xff0c;专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性&#xff0c;并提供了一个通用的框架&…...

排序算法总结(C++)

目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指&#xff1a;同样大小的样本 **&#xff08;同样大小的数据&#xff09;**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...

为什么要创建 Vue 实例

核心原因:Vue 需要一个「控制中心」来驱动整个应用 你可以把 Vue 实例想象成你应用的**「大脑」或「引擎」。它负责协调模板、数据、逻辑和行为,将它们变成一个活的、可交互的应用**。没有这个实例,你的代码只是一堆静态的 HTML、JavaScript 变量和函数,无法「活」起来。 …...