Android framework服务命令行工具框架 - Android13

Android framework服务命令行工具框架 - Android13

  • 1、framework服务命令行工具简介
  • 2、cmd 执行程序
    • 2.1 目录和Android.bp
    • 2.2 cmdMain 执行入口
    • 2.3 cmd命令
  • 3、am命令工具,实质脚本执行cmd activity
    • 3.1 sh脚本
    • 3.2 activity服务注册
    • 3.3 onShellCommand执行
  • 4、简易时序图

1、framework服务命令行工具简介

这里强调 “framework服务” ,主要就是bin命令模拟 framework服务 相关的查询和功能,如am\pm\input等;其实质就是 Android 提供了大多数常见的 Unix 命令行工具,说白了就是bin执行程序 。而 framework服务 命令行工具现在一般就是cmdbin执行程序Binder获取对应服务,通过IBinder::shellCommand调用对应服务的onShellCommand

在这里插入图片描述 在这里插入图片描述

2、cmd 执行程序

2.1 目录和Android.bp

frameworks/native/cmds/cmd/Android.bp
frameworks/native/cmds/cmd/cmd.cpp
在这里插入图片描述

2.2 cmdMain 执行入口

  • DEBUG:默认关闭#define DEBUG 0
  • serviceName:SM中注册的binder服务对应的名称,如ACTIVITY_SERVICE = "activity"(ActivityManagerService)
  • IBinder::shellCommand(service, in, out, err, args, cb, result):执行到对应服务onShellCommand

frameworks/native/cmds/cmd/cmd.cpp

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 DEBUGALOGD("cmd: starting");
#endifsp<IServiceManager> sm = defaultServiceManager();if (runMode == RunMode::kStandalone) {fflush(stdout);}if (sm == nullptr) {ALOGW("Unable to get default service manager!");errorLog << "cmd: Unable to get default service manager!" << endl;return 20;}int argc = argv.size();if (argc == 0) {errorLog << "cmd: No service specified; use -l to list all running services. Use -w to start and wait for a service." << endl;return 20;}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);}if (service == nullptr) {if (runMode == RunMode::kStandalone) {ALOGW("Can't find service %.*s", static_cast<int>(cmd.size()), cmd.data());}errorLog << "cmd: Can't find service: " << cmd << endl;return 20;}sp<MyShellCallback> cb = new MyShellCallback(errorLog);sp<MyResultReceiver> result = new MyResultReceiver();#if DEBUGALOGD("cmd: Invoking %.*s in=%d, out=%d, err=%d",static_cast<int>(cmd.size()), cmd.data(), in, out, err);
#endif// TODO: block until a result is returned to MyResultReceiver.status_t error = IBinder::shellCommand(service, in, out, err, args, cb, result);if (error < 0) {const char* errstr;switch (error) {case BAD_TYPE: errstr = "Bad type"; break;case FAILED_TRANSACTION: errstr = "Failed transaction"; break;case FDS_NOT_ALLOWED: errstr = "File descriptors not allowed"; break;case UNEXPECTED_NULL: errstr = "Unexpected null"; break;default: errstr = strerror(-error); break;}if (runMode == RunMode::kStandalone) {ALOGW("Failure calling service %.*s: %s (%d)", static_cast<int>(cmd.size()), cmd.data(),errstr, -error);}outputLog << "cmd: Failure calling service " << cmd << ": " << errstr << " (" << (-error)<< ")" << endl;return error;}cb->mActive = false;status_t res = result->waitForResult();
#if DEBUGALOGD("result=%d", (int)res);
#endifreturn res;
}

2.3 cmd命令

  1. cmd
    在这里插入图片描述

  2. cmd -l 列出SM中注册的服务
    在这里插入图片描述

  3. cmd activity
    在这里插入图片描述

3、am命令工具,实质脚本执行cmd activity

3.1 sh脚本

这里am工具为例。Android 提供了大多数常见的 Unix 命令行工具,查看可用工具的列表:adb shell ls /system/bin

frameworks/base/cmds/am/am

#!/system/bin/shif [ "$1" != "instrument" ] ; thencmd activity "$@"
elsebase=/systemexport CLASSPATH=$base/framework/am.jarexec app_process $base/bin com.android.commands.am.Am "$@"
fi

3.2 activity服务注册

activity服务就是ActivityManagerService注册的Context.ACTIVITY_SERVICE

frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

public void setSystemProcess() {try {ServiceManager.addService(Context.ACTIVITY_SERVICE, this, /* allowIsolated= */ true,DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO);ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);ServiceManager.addService("meminfo", new MemBinder(this), /* allowIsolated= */ false,DUMP_FLAG_PRIORITY_HIGH);ServiceManager.addService("gfxinfo", new GraphicsBinder(this));ServiceManager.addService("dbinfo", new DbBinder(this));mAppProfiler.setCpuInfoService();ServiceManager.addService("permission", new PermissionController(this));ServiceManager.addService("processinfo", new ProcessInfoService(this));ServiceManager.addService("cacheinfo", new CacheBinder(this));//... ... ... ...
}

3.3 onShellCommand执行

ActivityManagerShellCommand专门处理am相关命令,这里具体功能不展开细说。

frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

@Override
public void onShellCommand(FileDescriptor in, FileDescriptor out,FileDescriptor err, String[] args, ShellCallback callback,ResultReceiver resultReceiver) {(new ActivityManagerShellCommand(this, false)).exec(this, in, out, err, args, callback, resultReceiver);
}

frameworks/base/services/core/java/com/android/server/am/ActivityManagerShellCommand.java

@Override
public int onCommand(String cmd) {if (cmd == null) {return handleDefaultCommands(cmd);}final PrintWriter pw = getOutPrintWriter();try {switch (cmd) {case "start":case "start-activity":return runStartActivity(pw);case "startservice":case "start-service":return runStartService(pw, false);case "startforegroundservice":case "startfgservice":case "start-foreground-service":case "start-fg-service":return runStartService(pw, true);case "stopservice":case "stop-service":return runStopService(pw);case "broadcast":return runSendBroadcast(pw);case "compact":return runCompact(pw);case "instrument":getOutPrintWriter().println("Error: must be invoked through 'am instrument'.");return -1;case "trace-ipc":return runTraceIpc(pw);case "profile":return runProfile(pw);case "dumpheap":return runDumpHeap(pw);case "set-debug-app":return runSetDebugApp(pw);case "set-agent-app":return runSetAgentApp(pw);case "clear-debug-app":return runClearDebugApp(pw);case "set-watch-heap":return runSetWatchHeap(pw);case "clear-watch-heap":return runClearWatchHeap(pw);case "clear-exit-info":return runClearExitInfo(pw);case "bug-report":return runBugReport(pw);case "force-stop":return runForceStop(pw);case "stop-app":return runStopApp(pw);case "fgs-notification-rate-limit":return runFgsNotificationRateLimit(pw);case "crash":return runCrash(pw);case "kill":return runKill(pw);case "kill-all":return runKillAll(pw);case "make-uid-idle":return runMakeIdle(pw);case "monitor":return runMonitor(pw);case "watch-uids":return runWatchUids(pw);case "hang":return runHang(pw);case "restart":return runRestart(pw);case "idle-maintenance":return runIdleMaintenance(pw);case "screen-compat":return runScreenCompat(pw);case "package-importance":return runPackageImportance(pw);case "to-uri":return runToUri(pw, 0);case "to-intent-uri":return runToUri(pw, Intent.URI_INTENT_SCHEME);case "to-app-uri":return runToUri(pw, Intent.URI_ANDROID_APP_SCHEME);case "switch-user":return runSwitchUser(pw);case "get-current-user":return runGetCurrentUser(pw);case "start-user":return runStartUser(pw);case "unlock-user":return runUnlockUser(pw);case "stop-user":return runStopUser(pw);case "is-user-stopped":return runIsUserStopped(pw);case "get-started-user-state":return runGetStartedUserState(pw);case "track-associations":return runTrackAssociations(pw);case "untrack-associations":return runUntrackAssociations(pw);case "get-uid-state":return getUidState(pw);case "get-config":return runGetConfig(pw);case "suppress-resize-config-changes":return runSuppressResizeConfigChanges(pw);case "set-inactive":return runSetInactive(pw);case "get-inactive":return runGetInactive(pw);case "set-standby-bucket":return runSetStandbyBucket(pw);case "get-standby-bucket":return runGetStandbyBucket(pw);case "send-trim-memory":return runSendTrimMemory(pw);case "display":return runDisplay(pw);case "stack":return runStack(pw);case "task":return runTask(pw);case "write":return runWrite(pw);case "attach-agent":return runAttachAgent(pw);case "supports-multiwindow":return runSupportsMultiwindow(pw);case "supports-split-screen-multi-window":return runSupportsSplitScreenMultiwindow(pw);case "update-appinfo":return runUpdateApplicationInfo(pw);case "no-home-screen":return runNoHomeScreen(pw);case "wait-for-broadcast-idle":return runWaitForBroadcastIdle(pw);case "compat":return runCompat(pw);case "refresh-settings-cache":return runRefreshSettingsCache();case "memory-factor":return runMemoryFactor(pw);case "service-restart-backoff":return runServiceRestartBackoff(pw);case "get-isolated-pids":return runGetIsolatedProcesses(pw);case "set-stop-user-on-switch":return runSetStopUserOnSwitch(pw);case "set-bg-abusive-uids":return runSetBgAbusiveUids(pw);case "list-bg-exemptions-config":return runListBgExemptionsConfig(pw);default:return handleDefaultCommands(cmd);}} catch (RemoteException e) {pw.println("Remote exception: " + e);}return -1;
}

4、简易时序图

在这里插入图片描述

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

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

相关文章

javaEE -9(7000字详解TCP/IP协议)

一&#xff1a; IP 地址 IP地址&#xff08;Internet Protocol Address&#xff09;是指互联网协议地址&#xff0c;又译为网际协议地址。 IP地址是IP协议提供的一种统一的地址格式&#xff0c;它为互联网上的每一个网络和每一台主机分配一个逻辑地址&#xff0c;以此来屏蔽物…

使用pycharm远程连接到Linux服务器进行开发

预计达到的效果 本地的 PyCharm 能达到和远程服务器之间的文件同步&#xff1b;本地的 PyCharm 能够使用远程服务器的开发环境&#xff1b; 环境配置 PyCharm&#xff1a;PyCharm 2021.3 (Professional Edition)Linux服务器&#xff1a;Ubuntu20.04 步骤 1.进入配置项 配…

Python 算法高级篇:桶排序与基数排序

Python 算法高级篇&#xff1a;桶排序与基数排序 引言什么是桶排序&#xff1f;桶排序的基本步骤桶排序的示例 什么是基数排序&#xff1f;基数排序的基本步骤基数排序的示例 桶排序与基数排序的应用桶排序的应用基数排序的应用 Python 示例代码总结 引言 在算法高级篇的课程中…

从设计、制造到封测,XSKY 智能存储助力半导体行业数字化转型

近日&#xff0c;ECS2023 第五届中国电子通信与半导体 CIO 峰会在深圳召开&#xff0c;峰会以“数字科技与业务重塑”为主题&#xff0c;汇聚了 300来自电子通信与半导体行业知名企业高管、CIO、信息化与数字化负责人&#xff0c;交流电子通信与半导体行业的创新的产品和解决方…

【排序】js简单实现前端数组排序,多字段数组对象排序,字符串排序,数字排序等

数组对象排序&#xff08;多字段排序&#xff09; 排序前&#xff1a; 排序后&#xff1a; data() {return {list: [{ks: 外科,child_ks: 泌尿外科,xz: 外科一组,doctor: 小明,num: 18,num2: 19,num3: 20},{ks: 中医科,child_ks: 中医男科,xz: 外科一组,doctor: 小红,num: …

Hadoop、Hive安装

一、 工具 Linux系统&#xff1a;Centos&#xff0c;版本7.0及以上 JDK&#xff1a;jdk1.8 Hadoop&#xff1a;3.1.3 Hive&#xff1a;3.1.2 虚拟机&#xff1a;VMware mysql&#xff1a;5.7.11 工具下载地址: https://pan.baidu.com/s/1JYtUVf2aYl5–i7xO6LOAQ 提取码: xavd…

ORACLE-递归查询、树操作

1. 数据准备 -- 测试数据准备 DROP TABLE untifa_test;CREATE TABLE untifa_test(child_id NUMBER(10) NOT NULL, --子idtitle VARCHAR2(50), --标题relation_type VARCHAR(10) --关系,parent_id NUMBER(10) --父id );insert into untifa_test (CHILD_ID, TITLE, RELATION_TYP…

SpringBoot整合Gateway 的Demo(附源码)

源码&#xff0c;可直接下载 Gateway模块 Gateway 的父pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:sc…

vue核心面试题汇总【查缺补漏】

给大家推荐一个实用面试题库 1、前端面试题库 &#xff08;面试必备&#xff09; 推荐&#xff1a;★★★★★ 地址&#xff1a;web前端面试题库 很喜欢‘万变不离其宗’这句话&#xff0c;希望在不断的思考和总结中找到Vue中的宗&#xff0c;来解答面试官抛出的…

2023MathorCup(妈妈杯) 数学建模挑战赛 解题思路

云顶数模最新解题思路免费分享~~ 2023妈妈杯数学建模A题B题思路&#xff0c;供大家参考~~ A题 B题

对mysql的联合索引的深刻理解

背景 对mysql的联合索引的考察是Java程序员面试高频考点&#xff01;必须深刻理解掌握否则容易丢分非常可惜。 技术难点 考察对最左侧匹配原理理解。 原理 暂且不表。网上讲这非常多。我理解就是&#xff0c;B树每个非叶子节点的值都是有序存放索引的值。 比如对A、B、C …

物联网和互联网医院小程序:如何实现医疗设备的远程监测和管理?

物联网&#xff08;IoT&#xff09;技术的发展为医疗设备的远程监测和管理提供了巨大的机会。结合互联网医院小程序&#xff0c;我们可以实现对医疗设备的远程访问、监控和管理&#xff0c;从而提高医疗服务的质量和效率。本文将介绍如何实现医疗设备的远程监测和管理&#xff…

appium操控微信小程序的坑

appium操控微信小程序的坑 打不开启动页面driver的context只有NATIVE_APP小程序上元素找不到 我打算使用appium操控微信小程序&#xff0c;只要能够获取到小程序的页面元素就算成功。下面都是我遇到的问题。 打不开启动页面 以下是我的appium的配置参数和代码&#xff1a; de…

Hyperledger Fabric搭建测试网络

本文使用的Fabric版本&#xff1a;V2.5.4 Ubuntu系统&#xff1a;16.04LTS 前序文章已经详细介绍了如何安装部署Hyperledger Fabric系统&#xff0c;这里不再赘述。本篇文章主要介绍如何使用Fabric的测试网络。在正式开始之前&#xff0c;有一点需要说明&#xff1a; Hyperled…

24 行为型模式-访问者模式

1 访问者模式介绍 访问者模式在实际开发中使用的非常少,因为它比较难以实现并且应用该模式肯能会导致代码的可读性变差,可维护性变差,在没有特别必要的情况下,不建议使用访问者模式。 2 访问者模式原理 3 访问者模式实现 我们以超市购物为例,假设超市中的三类商品: 水果,糖…

JVM(二)

一,运行时数据区 Java虚拟机在运行Java程序过程中管理的内存区域,称之为运行时数据区。 1.1 程序计数器 程序计数器(Program Counter Register)也叫PC寄存器,每个线程会通过程序计数器记录当前要执行的的字节码指令的地址。 在加载阶段,虚拟机将字节码文件中的指令读取…

多线程面试相关知识点

文章目录 (一) 进程线程和协程的区别创建线程的4种方式1. 继承Thread类2. 实现runnable接口3. 实现Callable接口4. 线程池创建 runnable 和 callable 有什么区别线程的 run()和 start()有什么区别&#xff1f;线程之间的状态变化notify()和 notifyAll()有什么区别&#xff1f;j…

HPV感染的风险:闫会宁主任分析酒店环境中的常见因素

人类乳头瘤病毒(HPV)是一种普遍存在的病毒&#xff0c;其存在和传播方式多种多样。近年来&#xff0c;人们对于HPV的认识不断深入&#xff0c;知道其在酒店环境中的传播风险。本文将探讨哪些情况下在酒店可能感染HPV。 一、HPV的传播方式 HPV主要通过直接接触传播&#xff0c…

数据湖Iceberg介绍和使用(集成Hive、SparkSQL、FlinkSQL)

文章目录 简介概述作用特性数据存储、计算引擎插件化实时流批一体数据表演化&#xff08;Table Evolution&#xff09;模式演化&#xff08;Schema Evolution&#xff09;分区演化&#xff08;Partition Evolution&#xff09;列顺序演化&#xff08;Sort Order Evolution&…

python:使用Scikit-image对遥感影像进行梯度特征提取(gradient)

作者:CSDN @ _养乐多_ 在本博客中,我们将介绍如何使用Scikit-Image来进行梯度特征提取(gradient),并且提供一个示例代码,演示了如何在单波段遥感图像上应用这些方法。 梯度特征是指用于表示图像中亮度或颜色变化的特征。它包括两个关键成分:梯度幅值和梯度方向。梯度幅…