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 DEBUG
    ALOGD("cmd: starting");
#endif
    sp<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 DEBUG
    ALOGD("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 DEBUG
    ALOGD("result=%d", (int)res);
#endif
    return 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/sh

if [ "$1" != "instrument" ] ; then
    cmd activity "$@"
else
    base=/system
    export CLASSPATH=$base/framework/am.jar
    exec 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.mfbz.cn/a/107134.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux 系统调用IO口,利用光标偏移实现文件复制

用系统调用IO函数实现从一个文件读取最后2KB数据并复制到另一个文件中&#xff0c;源文件以只读方式打开&#xff0c;目标文件以只写的方式打开&#xff0c;若目标文件不存在&#xff0c;可以创建并设置初始值为0664&#xff0c;写出相应代码&#xff0c;要对出错情况有一定的处…

Peter算法小课堂—归并排序

位运算 << 这个符号相当于将一个数二进制往左移动几位&#xff0c;如(100110)2<<1(001100)2。相当于乘以2的k次方 >> 这个符号相当于将一个数二进制往右移动几位&#xff0c;如(100110)2<<1(0100110)2。相当于除以2的k次方 归并排序 先看一个视频…

macOS Sonoma 14.1正式版(23B74)发布(可下载黑白苹果镜像)

系统介绍 黑果魏叔苹果今天为 macOS Sonoma 推出了 14.1 版本更新&#xff0c;魏叔发现&#xff0c;本更新主要改善了 Apple Music 界面&#xff0c;设置中新增保修状态&#xff0c;并修复了多项错误内容。 根据苹果的新说明&#xff0c;这次的 Mac 更新不仅提供了一系列的改善…

asp.net教务管理信息系统VS开发sqlserver数据库web结构c#编程Microsoft Visual Studio计算机毕业设计

一、源码特点 asp.net 教务管理信息系统是一套完善的web设计管理系统&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为vs2010&#xff0c;数据库为sqlserver2008&#xff0c;使用c#语言 开发 asp.net教务管理系统 应用技术&a…

数据链路层和DNS之间的那些事~

数据链路层&#xff0c;考虑的是两个节点之间的传输。这里面的典型协议也很多&#xff0c;最知名的就是“以太网”。我们本篇主要介绍的就是以太网协议。这个协议规定了数据链路层&#xff0c;也规定了物理层的内容。 目录 以太网帧格式 帧头 载荷 帧尾 DNS 从输入URL到…

(c语言进阶)字符串函数、字符分类函数和字符转换函数

一.求字符串长度 1.strlen() (1)基本概念 头文件&#xff1a;<string.h> (2)易错点&#xff1a;strlen()的返回值为无符号整形 #include<stdio.h> #include<string.h> int main() {const char* str1 "abcdef";const char* str2 "bbb&q…

Linux常见问题解决操作(yum被占用、lsb无此命令、Linux开机进入命令界面等)

Linux常见问题解决操作&#xff08;yum被占用、lsb无此命令、Linux开机进入命令界面等&#xff09; 问题一、新安装的Linux使用命令lsb_release提示无此命令&#xff0c;需先安装再使用 Linux安装lsb命令 lsb是Linux Standard Base的缩写&#xff08;Linux基本标准&#xff…

Centos7 安装和配置 Redis 5 教程

在Centos上安装Redis 5&#xff0c;如果是 Centos8&#xff0c;那么 yum 仓库中默认的 redis 版本就是 5&#xff0c;直接 yum install 即可。但如果是 Centos7&#xff0c;yum 仓库中默认的 redis 版本是 3 系列&#xff0c;比较老&#xff1a; 通过 yum list | grep redis 命…

Constellation 介绍:Chainlink 黑客马拉松

在 2020 年&#xff0c;Chainlink 举办了其第一次线上黑客马拉松。当时&#xff0c;DeFi 作为一个类别刚刚开始蓬勃发展&#xff0c;而 NFT 也只是刚刚起步。这次黑客马拉松吸引了来自 45 个国家的 1,000 多名注册参与者&#xff0c;并收到了来自 70 个项目提交。 从那时起&am…

【C++初探:简单易懂的入门指南】一

【C初探&#xff1a;简单易懂的入门指南】一 1. 命名空间1.1 命名空间的定义1.2 命名空间的使用方法 2. C的输入、输出2.1 为什么使用输入、输出要引用一个<iostream>的头文件&#xff1f;2.2 为什么代码里面开放了一个叫std的命名空间2.3 代码中出现的<<和>>…

基于SSM的航班订票管理系统的设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

SpringBoot使用WebSocket收发实时离线消息

引入maven依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency> WebScoket配置处理器 import org.springframework.boot.web.servlet.ServletContextI…

JVM面试知识点整理

文章目录 (一) JVM组成JVM组成部分和运行流程从图中可以看出 JVM 的主要组成部分运行流程&#xff1a;程序计数器Java堆虚拟机栈方法区堆栈的区别是什么&#xff1f; (二) 类加载器双亲委派模型类装载的执行过程 (三) 垃圾回收对象什么时候可以被垃圾回收哪些可以作为根对象 垃…

浅谈安科瑞EMS能源管控平台建设的意义-安科瑞 蒋静

摘 要&#xff1a;能源消耗量大、能源运输供给不足、环境压力日趋增加、能耗双控等一系列问题一直困扰着钢铁冶金行业&#xff0c;制约着企业快速稳定健康发展。本文介绍的安科瑞EMS能源管控平台&#xff0c;采用自动化、信息化技术&#xff0c;实现从能源数据采集、过程监控、…

Spring Boot简介

Spring Boot帮助你创建可以运行的独立的、基于Spring的生产级应用程序。 我们对Spring平台和第三方库采取了有主见的观点&#xff0c;这样你就能以最少的麻烦开始工作。 大多数Spring Boot应用程序只需要很少的Spring配置。 你可以使用Spring Boot来创建Java应用程序&#xff…

【Python3】【力扣题】202. 快乐数

【力扣题】题目描述&#xff1a; 【Python3】代码&#xff1a; 1、解题思路&#xff1a;用哈希集合检测循环。设置集合记录每次结果&#xff0c;判断结果是否为1。若计算结果已在集合中则进入循环&#xff0c;结果一定不为1。 &#xff08;1-1&#xff09;知识点&#xff1a;…

基于SSM和VUE的留守儿童信息管理系统

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 目录…

关键词搜索1688商品数据接口(标题|主图|SKU|价格|优惠价|掌柜昵称|店铺链接|店铺所在地)

1688商品列表接口是一个用于获取1688网站上商品列表信息的接口。通过该接口&#xff0c;您可以获取到1688网站上不同类别的商品列表&#xff0c;包括商品的名称、价格、图片等信息。 要使用1688商品列表接口&#xff0c;您需要按照以下步骤进行操作&#xff1a; 登录1688网站…

听力检测为什么要在标准化的隔声屏蔽系统中进行?

作者兰明&#xff0c;医学硕士&#xff0c;听力学博士&#xff0c;听觉健康门诊主任 美国国家研究委员会;;行为、认知和感官科学委员会联合出版的听力损失确定社会保障福利的资格一书中关于测试环境的要求如下&#xff1a; 行动建议4-4 测试环境 听力学评估是在受控的声学环境中…

接口返回响应,统一封装(ResponseBodyAdvice + Result)(SpringBoot)

需求 接口的返回响应&#xff0c;封装成统一的数据格式&#xff0c;再返回给前端。 依赖 对于SpringBoot项目&#xff0c;接口层基于 SpringWeb&#xff0c;也就是 SpringMVC。 <dependency><groupId>org.springframework.boot</groupId><artifactId&g…
最新文章