安卓车机系统adb shell cmd 源码原理分析

news2024/11/18 17:43:37

hi,粉丝朋友们大家好!
上一次视频分享了input专题课中input命令在android 12的更新,因为原来课程是基于android 10 (可以加我扣:2102309716 优惠购买)
https://ke.qq.com/course/package/77595?tuin=7d4eb354
https://www.bilibili.com/video/BV1aK41117mw/
具体input命令的更新大家看以上视频既可以,顺便补充一下视频中流程图:
在这里插入图片描述

本文主要来补充一下视频中没有详细讲解的cmd命令
一般cmd命令使用格式一般是:
adb shell cmd xxxx
这里xxx其实一般是我们的系统服务名字,其跨进程课中servicemanager列表中保存的所有服务名字

然后他就会触发对应服务的onShellCommand方法,这个时候相当于和dumpsys命令非常类似,dumpsys命令是会触发到对应的服务的dump方法
https://blog.csdn.net/learnframework/article/details/122596598
那么下面来源码级别分析一下cmd命令,因为上面都是大概的讲解,没有拿出源码来证明。

代码路径:
frameworks/native/cmds/cmd/main.cpp

#include <unistd.h>

#include "cmd.h"

int main(int argc, char* const argv[]) {
    signal(SIGPIPE, SIG_IGN);

    std::vector<std::string_view> arguments;
    arguments.reserve(argc - 1);
    // 0th argument is a program name, skipping.
    for (int i = 1; i < argc; ++i) {
        arguments.emplace_back(argv[i]);
    }

    return cmdMain(arguments, android::aout, android::aerr, STDIN_FILENO, STDOUT_FILENO,
                   STDERR_FILENO, RunMode::kStandalone);
}

这里可以看出主要执行的是cmdMain方法

int cmdMain(const std::vector<std::string_view>& argv, TextOutput& outputLog, TextOutput& errorLog,
            int in, int out, int err, RunMode runMode) {
    sp<ProcessState> proc = ProcessState::self();
    proc->startThreadPool();

#if DEBUG
    ALOGD("cmd: starting");
#endif
    sp<IServiceManager> sm = defaultServiceManager();
    //ignoe
    if ((argc == 1) && (argv[0] == "-l")) {
        Vector<String16> services = sm->listServices();
        services.sort(sort_func);
        outputLog << "Currently running services:" << endl;

        for (size_t i=0; i<services.size(); i++) {
            sp<IBinder> service = sm->checkService(services[i]);
            if (service != nullptr) {
                outputLog << "  " << services[i] << endl;
            }
        }
        return 0;
    }

    bool waitForService = ((argc > 1) && (argv[0] == "-w"));
    int serviceIdx = (waitForService) ? 1 : 0;
    const auto cmd = argv[serviceIdx];

    Vector<String16> args;
    String16 serviceName = String16(cmd.data(), cmd.size());
    for (int i = serviceIdx + 1; i < argc; i++) {
        args.add(String16(argv[i].data(), argv[i].size()));
    }
    sp<IBinder> service;
    if(waitForService) {
        service = sm->waitForService(serviceName);
    } else {
        service = sm->checkService(serviceName);
    }

    //ignoe
    sp<MyShellCallback> cb = new MyShellCallback(errorLog);
    sp<MyResultReceiver> result = new MyResultReceiver();
    // TODO: block until a result is returned to MyResultReceiver.
    status_t error = IBinder::shellCommand(service, in, out, err, args, cb, result);
     //ignoe
    cb->mActive = false;
    status_t res = result->waitForResult();
#if DEBUG
    ALOGD("result=%d", (int)res);
#endif
    return res;
}

cmdMain的代码其实也简单,主要做了以下几步工作:
1、解析出cmd命令后面的服务字符,根据这个服务字符去servicemanager寻找对应service,返回对应的BpBinder
2、获取了BpBinder后调用IBinder::shellCommand方法,这个方法是最为关键,它会调用到服务端的onShellCommand方法
3、等带服务返回结果

这里继续看看IBinder::shellCommand怎么调用的到服务端的:

status_t IBinder::shellCommand(const sp<IBinder>& target, int in, int out, int err,
    Vector<String16>& args, const sp<IShellCallback>& callback,
    const sp<IResultReceiver>& resultReceiver)
{
    Parcel send;
    Parcel reply;
    send.writeFileDescriptor(in);
    send.writeFileDescriptor(out);
    send.writeFileDescriptor(err);
    const size_t numArgs = args.size();
    send.writeInt32(numArgs);
    for (size_t i = 0; i < numArgs; i++) {
        send.writeString16(args[i]);
    }
    send.writeStrongBinder(callback != nullptr ? IInterface::asBinder(callback) : nullptr);
    send.writeStrongBinder(resultReceiver != nullptr ? IInterface::asBinder(resultReceiver) : nullptr);
    return target->transact(SHELL_COMMAND_TRANSACTION, send, &reply);
}

这里大家如果学习过跨进程专题应该非常熟悉这个,可以看到最后其实是构造了一个Parcel调用了transact方法进行传递,当transact调用完成后就会到服务端的transact再调用到onShellCommand

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

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

相关文章

联合证券|金融部门开年推出新方案 改善优质房企资产负债状况

当时&#xff0c;努力促进房地产与金融正常循环是金融部门的工作要点之一。记者日前了解到&#xff0c;为遵循落实中心经济工作会议布置&#xff0c;有用防范化解优质头部房企危险&#xff0c;改进财物负债情况&#xff0c;有关部门起草了《改进优质房企财物负债表计划举动计划…

【计算机体系结构基础】流水线异常处理和提高流水线效率的技术(一)

流水线中的异常 异常的来源 外部事件指令执行中的错误数据完整性的问题地址转换异常系统调用陷入需要软件修正的运算 异常可以分为&#xff1a;可恢复异常和不可恢复异常 不可恢复异常&#xff1a;系统硬件出现严重故障&#xff0c;异常处理后系统面临重启。 解决办法&#x…

Spring Boot Apollo监听namespace并更新配置Bean(附源码)

这里是weihubeats,觉得文章不错可以关注公众号小奏技术&#xff0c;文章首发。拒绝营销号&#xff0c;拒绝标题党 背景 如果我们使用的配置中心是apollo的话我们经常会遇到这样的问题&#xff0c;就是动态更新配置Bean 动态更新配置bean 动态更新配置bean其实是很简单的&…

Python学习笔记-PyQt6消息窗

对话框是界面编程中重要的窗体&#xff0c;一般用于提示或者一些其他特定操作。一、使用QDialog显示通用消息框直接使用QDialog类&#xff0c;可以及通过对话框进行通用对话框显示&#xff0c;亦可以通过自定义设置自己需要的对话框。# _*_ coding:utf-8 _*_import sysfrom PyQ…

MySQL主从复制的原理是什么?

主从复制是指将主数据库的 DDL 和 DML 操作通过二进制日志传到从库服务器中&#xff0c;然后在从库上对这些日志重新执行(也叫重做)&#xff0c;从而使得从库和主库的数据保持同步。 MySQL支持一台主库同时向多台从库进行复制&#xff0c; 从库同时也可以作为其他从服务器的主…

Python批量下载某网站贵得要shi文档 并保存为PDF

人生苦短&#xff0c;我用Python 基本开发环境&#x1f4a8; Python 3.6Pycharm 相关模块的使用&#x1f4a8; import requests import parsel import re import os import pdfkit需要使用到一个软件 wkhtmltopdf 这个软件的作用就是把html文件转成PDF 想要把文档内容保存…

人工智能轨道交通行业周刊-第30期(2023.1.9-1.15)

本期关键词&#xff1a;贵阳智慧车站、城轨智能化汇总、隧道巡检、信创厂商、手语数字人 1 整理涉及公众号名单 1.1 行业类 RT轨道交通中关村轨道交通产业服务平台人民铁道世界轨道交通资讯网铁路信号技术交流北京铁路轨道交通网上榜铁路视点ITS World轨道交通联盟VSTR铁路与…

煤矿人员工服着装智能识别监测系统 yolov5架构

煤矿人员工服着装智能识别监测系统通过pythonyolov5深度学习网络架构&#xff0c;对画面中人员是否正确着装实时分析&#xff0c;发现违规着装立即抓拍存档告警。我们选择当下YOLO最新的卷积神经网络YOLOv5来进行识别检测。按照官方给出的数目&#xff0c;现版本的YOLOv5每个图…

数据库概述杂谈之章节回顾

数据与数据之间联系的模型表示 网状模型用“图”结构来表示数据及数据之间的联系层次模型用“树”结构来表示数据及数据之间的联系关系模型用“关系&#xff08;二维表&#xff09;”结构来表示数据及数据之间的联系对象模型用“对象”数据结构来表示数据及数据之间的联系 数…

SPI协议与GPIO模拟SPI的实现

SPI定义 SPI&#xff08;Serial Peripheral Interface, 串口外设接口&#xff09;&#xff0c;它用于MCU与各种外围设备以串行方式进行通信&#xff0c;速度最高可达25MHz以上。 SPI接口主要应用在EEPROM、 FLASH、实时时钟、网络控制器、 OLED显示驱动器、 AD转换器&#xf…

ArcGIS10.6保姆式安装教程,超详细;附安装包

安装前请关闭杀毒软件&#xff0c;系统防火墙&#xff0c;断开网络连接 参考链接&#xff1a;请点击 下载链接&#xff1a; 通过百度网盘分享的文件&#xff1a;ArcGIS10.6zip 链接:https://pan.baidu.com/s/1tCsOQ_-WP-usEHmJo9SfcA 提取码:hn15 复制这段内容打开「百度网盘A…

Java环境安装、python环境安装、Burpsuite安装

数据来源 Java环境安装 Windows安装JDK8&#xff08;安装过程&#xff1a;一路下一步&#xff09; 下载JDK8&#xff1a;https://www.oracle.com/java/technologies/javase-jdk8-downloads.html 百度网盘&#xff1a;windows64、84位 配置PATH环境变量&#xff1a; 变量名…

RT-Thread系列--双链表分析

一、目的学习过C语言的同学应该都知道几种常用的数据结构&#xff0c;例如数组、单链表、双链表等。每种数据结构都有其特点和应用场景&#xff0c;本篇就结合RT-Thread源码分析一下其双链表实现细节和特点。那什么是双链表呢&#xff0c;这边简单解释一下帮助大家理解。通过双…

KubeSphere 开源社区 2022 年度回顾与致谢

2022 年&#xff0c;国内的云原生技术生态日趋完善&#xff0c;细分技术项目也不断涌现&#xff0c;形成了完整的支撑应用云原生化的全生命周期技术体系。基础设施即代码、微服务、Serverless 等技术&#xff0c;促使基础设施资源向更加灵活弹性、自动化方向发展。而开源生态也…

重装系统如何设置u盘启动为第一启动项

如何设置u盘启动为第一启动项呢?将U盘设为第一启动项&#xff0c;是使用U盘装机工具重装系统的重要步骤之一&#xff0c;很多网友不清楚怎么操作&#xff0c;下面小编就分享下设置u盘启动为第一启动项的方法。 工具/原料&#xff1a; 系统版本&#xff1a;win7家庭版 品牌型…

【openGauss实战4】数据类型解读

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 哈喽&#xff01;大家好&#xff0c;我是【IT邦德】&#xff0c;江湖人称jeames007&#xff0c;10余年DBA工作经验 一位上进心十足的【大数据领域博主】&#xff01;&#x1f61c;&#x1f61…

一文教会你巧用设计模式重构项目

文章目录一、设计模式总览二、模板方法模式案例三、策略模式案例四、支付改造4.1 思路分析4.2 实现图解&#xff1a;4.3 代码实现&#xff1a;4.4 效果演示4.5 如何扩展本文参考自12.29日尚硅谷雷神的 巧妙使用设计模式重构项目 一、设计模式总览 总体分类 不同时期选择不同的…

Python批量检索论文被引用数量源码,利用百度学术网页版来批量检索论文的被引用数量源码

论文被引用数搜索 利用百度学术网页版来检索一个文件夹中的所有论文的被引用数量。 完整代码下载地址&#xff1a;Python批量检索论文被引用数量源码 依赖有beautifulsoup库、regex正则表达式库。 使用方法 主程序为fileWalk.py。 修改程序中workPath值为文件夹绝对路径&am…

基于碰撞传感器的自动导航车系统设计

1、内容简介略635-可以交流、咨询、答疑2、内容说明略随着世界各国对科学技术的重视&#xff0c;各类高科技技术突飞猛进&#xff0c;人类逐步进入人工智能时代。而在这些高科技技术的背后&#xff0c;自动导航小车作为无人驾驶小车的一种类型备受关注。它的主要优点是不需要人…

冰冰学习笔记:智能指针

欢迎各位大佬光临本文章&#xff01;&#xff01;&#xff01; 还请各位大佬提出宝贵的意见&#xff0c;如发现文章错误请联系冰冰&#xff0c;冰冰一定会虚心接受&#xff0c;及时改正。 本系列文章为冰冰学习编程的学习笔记&#xff0c;如果对您也有帮助&#xff0c;还请各位…