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

news2024/9/24 4:33:01

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.coloradmin.cn/o/1143435.html

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

相关文章

【Leetcode】【每日一题】【简单】2558. 从数量最多的堆取走礼物

力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台备战技术面试&#xff1f;力扣提供海量技术面试资源&#xff0c;帮助你高效提升编程技能&#xff0c;轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problems/take-gifts-from-the-richest-pi…

NodeJS爬取墨刀上的设计图片

背景 设计人员分享了一个墨刀的原型图&#xff0c;但是给的是只读权限&#xff0c;无法下载其中的素材&#xff1b;开发时想下载里面的一张动图&#xff0c;通过浏览器的F12工具在页面结构找到了图片地址。 但是浏览器直接访问后发现没权限&#xff1a; Nginx 的 403 页面。。…

VistaSoftware.vTask Studio 7.913 Crack

VistaTask 是一款支持包括互联网活动&#xff0c;数据库查询&#xff0c;文件操作&#xff0c;窗口控制&#xff0c;鼠标活动&#xff0c;键盘输入以及其它活动在内的160多种不同活动的全功能自动控制工具。你可以通过简单的拖拽想要的活动的方式来指定新的自动控制任务&#x…

HDFS 短路读的实现(全网最全面深入讲解)

文章目录 前言1. 知识准备1.1 关于域套接字(Domain Socket)什么是Domain SocketDomain Socket 通信在ShortCircuit Read中做了什么DomainSocket 在Hadoop上的基本实现 1.2 关于内存映射(MMAP)什么是MMAPMMAP在ShortCircuit中的作用是什么 1.3 关于共享内存(Shared Memory)什么是…

USB学习(3):USB描述符和USB类设备

文章目录 1 USB描述符(Descriptors)1.1 设备描述符(Device Descriptor)1.2 配置描述符(Configuration Descriptor)1.3 接口关联描述符(Interface Association Descriptor)1.4 接口描述符(Interface Descriptor)1.5 端点描述符(Endpoint Descriptor)1.6 字符串描述符(String Des…

CS224W2.1——传统基于特征的方法(节点层级特征)

CS224W1.1——图机器学习介绍CS224W1.2——图机器学习应用CS224W1.3——图表示的选择 前面几篇介绍了图机器学习的基础一些背景知识&#xff0c;我们知道图机器学习任务分为多个层级&#xff1a; 节点层级任务边层级任务子图层级任务图层级任务 这篇主要讲传统的基于特征方法…

基于MFC的串口通信

1、串口通信的概述&#xff1a; 串口是一种重要的通信资源&#xff0c;例如鼠标口、USB接口都是串口。串行端口是CPU和串行设备间的编码转换器。当数据从CPU经过端口发送出去的时候&#xff0c;字节数据会被转为串行的位&#xff0c;在接收数据时&#xff0c;串行的位被转换为…

无线WIFI接入FreeRadius进行认证——筑梦之路

环境说明 硬件设备&#xff1a; ASUS RT-AC88U路由器 服务器系统&#xff1a;Ubuntu 16.04 软件版本&#xff1a;FreeRADIUS 2.2.8 服务安装搭建 1. 安装freeradius apt-get install freeradius freeradius-mysql 2. 配置用户 vim /etc/freeradius/userssteve Cleart…

数据结构绪论,基本概念

目录 1.什么是数据结构&#xff1f; 2.三种数据结构&#xff1a; 3.第一章绪论 了解概念 1.几个概念 2.数据存储方式&#xff1a; 3.算法的五个重要特性: 4.算法设计的要求: 1.什么是数据结构&#xff1f; 数据 数据&#xff0c;是对客观事物的符号表示&#xff0c;在计…

操作系统——内存扩容:覆盖技术、交换技术(王道视频p44)

1.对于覆盖技术 和 交换技术&#xff1a;&#xff08;并不是重点&#xff09;

LaTeX:在标题section中添加脚注footnote

命令讲解 先导包&#xff1a; \usepackage{footmisc} 设原标题为&#xff1a; \section{标题内容} 更改为&#xff1a; \section[标题内容]{标题内容\protect\footnote{脚注内容}} 语法讲解&#xff1a; \section[]{} []内为短标题&#xff0c;作为目录和页眉中的标题。…

redis6.0源码分析:字典扩容与渐进式rehash

文章目录 字典数据结构结构设计dictType字典类型为什么字典有两个哈希表&#xff1f;哈希算法 扩容机制扩容前置知识字典存在几种状态&#xff1f;容量相关的关键字段定义字典的容量都是2的幂次方 扩容机制字典什么时候会扩容&#xff1f;扩容的阈值 & 扩容的倍数哪些方法会…

Android平台GB28181执法记录仪技术方案

技术背景 我们在做Android平台GB28181设备接入模块的时候&#xff0c;对接过好多开发者&#xff0c;他们都是用于执法记录仪场景&#xff0c;执法记录仪是一种便携式设备&#xff0c;用于记录执法人员的行动和接触情况&#xff0c;通过实时回传音视频数据和实时位置信息给指挥…

2023 MathorCup(妈妈杯) 数学建模挑战赛B题完整解题思路+模型+代码

2023妈妈杯数学建模B题完整版思路、模型代码已出&#xff01;&#xff01;&#xff01; 云顶数模最新完整版解题思路、模型代码&#xff0c;供大家参考~~ B题目 解题思路 详细模型解析&#xff1a;

RGB-T Salient Object Detection via Fusing Multi-Level CNN Features

ADFC means ‘adjacent-depth feature combination’&#xff0c;MGF means ‘multi-branch group fusion’&#xff0c;JCSA means ‘joint channel-spatial attention’&#xff0c;JABMP means ‘joint attention guided bi-directional message passing’ 作者未提供代…

Sprint Cloud Stream整合RocketMq和websocket实现消息发布订阅

1.引入RocketMQ依赖&#xff1a;首先&#xff0c;在pom.xml文件中添加RocketMQ的依赖&#xff1a; <dependency><groupId>org.apache.rocketmq</groupId><artifactId>rocketmq-spring-boot-starter</artifactId><version>2.2.0</versi…

JVM虚拟机:运行时数据区详解

本文重点 我们前面已经将类的加载过程进行了全面的了解和学习,按照如下所示的JVM架架构图,接下来我们应该学习运行时数据区了。 运行时数据区 如上图所示,灰色的标识线程私有,基本不存在垃圾回收。而非灰色的是线程共享的,存在垃圾回收。 PC计数器 每个线程都有一个程序…

【java】建筑施工一体化智慧工地信息管理系统源码

智慧工地系统是一种利用人工智能和物联网技术来监测和管理建筑工地的系统。它可以通过感知设备、数据处理和分析、智能控制等技术手段&#xff0c;实现对工地施工、设备状态、人员安全等方面的实时监控和管理。 一、智慧工地让工程施工智能化 1、内容全面&#xff0c;多维度数…

简化geojson策略

1、删除无用的属性&#xff0c;也就是字段&#xff0c;在shp的时候就给删了 用arcgis等等软件都可以做到 2、简化坐标的小数位数 &#xff08;1&#xff09;网上推荐的办法&#xff0c;俺不会Python… github.com/perrygeo/geojson-precision &#xff08;2&#xff09;曲线…

【C++项目】高并发内存池第五讲内存回收释放过程介绍

内存回收 1.ThreadCache2.CentralCache3.PageCache 1.ThreadCache void ThreadCache::Deallocate(void* ptr, size_t size) {assert(ptr);assert(size < MAX_BYTES);//计算在哪号桶中&#xff0c;然后插入进去size_t index SizeClass::Index(size);_freeLists[index].Push…