Android13源码添加系统服务

本文基于Android 13的framework层添加系统接口,为应用层提供读写函数、以及执行命令!

添加接口

frameworks/base/core/java/android/app/IDevices.aidl

package android.app;
interface IDevices
{//读取文件String readFile(String path);//写入文件void writeFile(String path,String data);//执行shell命令String shellExec(String cmd);
}

添加系统服务的Manager

frameworks/base/core/java/android/app/DevicesManager.java

package android.app;import android.annotation.SystemService;
import android.content.Context;
import android.os.RemoteException;
import android.util.Slog;@SystemService(Context.DEVICES_SERVICE)
public class DevicesManager {Context mContext;IDevices mService;public DevicesManager(Context context,IDevices service){if(service==null){Slog.e("DevicesManager","Construct service is null");}mContext = context;mService = service;}public String shellExec(String cmd){if(mService != null){try{Slog.e("DevicesManager","shellExec");return mService.shellExec(cmd);}catch(RemoteException e){Slog.e("DevicesManager","RemoteException "+e);}}else{Slog.e("DevicesManager","mService is null");}return "";}public String readFile(String path){if(mService != null){try{Slog.e("DevicesManager","readFile");return mService.readFile(path);}catch(RemoteException e){Slog.e("DevicesManager","RemoteException "+e);}}else{Slog.e("DevicesManager","mService is null");}return "";}public void writeFile(String path,String data){if(mService != null){try{Slog.e("DevicesManager","writeFile");mService.writeFile(path,data);}catch(RemoteException e){Slog.e("DevicesManager","RemoteException "+e);}}else{Slog.e("DevicesManager","mService is null");}}}

添加系统服务,实现aidl文件的接口

frameworks/base/services/core/java/com/android/server/DevicesService.java

package com.android.server; import android.app.IDevices;
import android.content.Context;
import android.os.Build;
import android.util.Log;
import android.util.Slog;import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;import libcore.io.IoUtils;import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.RandomAccessFile;import android.util.Base64;public class DevicesService extends IDevices.Stub {private Context mContext;private String TAG="DevicesService";public DevicesService(Context context){super();mContext = context;Slog.d(TAG,"Construct");}@Overridepublic String shellExec(String cmd){Runtime mRuntime = Runtime.getRuntime();try {//Process中封装了返回的结果和执行错误的结果Slog.d(TAG,"shellExec data:"+cmd);Process mProcess = mRuntime.exec(cmd);BufferedReader mReader = new BufferedReader(new InputStreamReader(mProcess.getInputStream()));StringBuffer mRespBuff = new StringBuffer();char[] buff = new char[1024];int ch = 0;while ((ch = mReader.read(buff)) != -1) {mRespBuff.append(buff, 0, ch);}mReader.close();return mRespBuff.toString();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();Slog.d(TAG,"shellExec err:"+e.getMessage());}return "";}public static void writeTxtToFile(String strcontent, String filePath) {String strFilePath = filePath;String strContent = strcontent + "\n";  // \r\n 结尾会变成 ^Mtry {File file = new File(strFilePath);makeFilePath(file.getParent(),file.getName());if (!file.exists()) {file.getParentFile().mkdirs();file.createNewFile();}RandomAccessFile raf = new RandomAccessFile(file, "rwd");raf.setLength(0);// 写文件的位置标记,从文件开头开始,后续读取文件内容从该标记开始long writePosition = raf.getFilePointer();raf.seek(writePosition);raf.write(strContent.getBytes());raf.close();//} catch (Exception e) {Log.d("DevicesService","Error on write File:" + e);}}// 生成文件public static File makeFilePath(String filePath, String fileName) {File file = null;makeRootDirectory(filePath);try {file = new File(filePath +"/"+ fileName);if (!file.exists()) {file.createNewFile();}} catch (Exception e) {e.printStackTrace();}return file;}// 生成文件夹public static void makeRootDirectory(String filePath) {File file = null;try {Log.d("FileHelper", "makeRootDirectory "+filePath);file = new File(filePath);if (!file.exists()) {boolean isok= file.mkdir();Log.d("FileHelper", "makeRootDirectory "+filePath+" "+isok);}} catch (Exception e) {Log.d("DevicesService", e+"");}}public static String readFileAll(String path) {File file = new File(path);StringBuilder sb=new StringBuilder();if (file != null && file.exists()) {InputStream inputStream = null;BufferedReader bufferedReader = null;try {inputStream = new FileInputStream(file);bufferedReader = new BufferedReader(new InputStreamReader(inputStream));String outData;while((outData=bufferedReader.readLine())!=null){sb.append(outData+"\n");}} catch (Throwable t) {} finally {try {if (bufferedReader != null) {bufferedReader.close();}} catch (Exception e) {e.printStackTrace();}try {if (inputStream != null) {inputStream.close();}} catch (Exception e) {e.printStackTrace();}}}return sb.toString();}@Overridepublic String readFile(String path){return readFileAll(path);}@Overridepublic void writeFile(String path,String data){writeTxtToFile(data,path);}}

添加服务名称

frameworks/base/core/java/android/content/Context.java

        @StringDef(suffix = { "_SERVICE" }, value = {POWER_SERVICE,
/*add_longzhiye*/++    DEVICES_SERVICE,//@hide: POWER_STATS_SERVICE,WINDOW_SERVICE,LAYOUT_INFLATER_SERVICE,ACCOUNT_SERVICE,ACTIVITY_SERVICE,ALARM_SERVICE,public static final String POWER_SERVICE = "power";
++public static final String DEVICES_SERVICE = "devices";

将实现的服务注册到系统中去

frameworks/base/core/java/android/app/SystemServiceRegistry.java

registerService(Context.SEARCH_SERVICE, SearchManager.class,new CachedServiceFetcher<SearchManager>() {@Overridepublic SearchManager createService(ContextImpl ctx) throws ServiceNotFoundException {return new SearchManager(ctx.getOuterContext(),ctx.mMainThread.getHandler());}});
//add longzhiye
registerService(Context.DEVICES_SERVICE,DevicesManager.class,new CachedServiceFetcher<DevicesManager>(){@Overridepublic DevicesManager createService(ContextImpl ctx){IBinder b = ServiceManager.getService(Context.DEVICES_SERVICE);return new DevicesManager(ctx,IDevices.Stub.asInterface(b));} });   
//add end       
registerService(Context.SENSOR_SERVICE, SensorManager.class,new CachedServiceFetcher<SensorManager>() {@Overridepublic SensorManager createService(ContextImpl ctx) {return new SystemSensorManager(ctx.getOuterContext(),ctx.mMainThread.getHandler().getLooper());}});

将注册的服务设置成开机启动服务

frameworks/base/services/java/com/android/server/SystemServer.java

t.traceBegin("StartTelephonyRegistry");
telephonyRegistry = new TelephonyRegistry(context, new TelephonyRegistry.ConfigurationProvider());
ServiceManager.addService("telephony.registry", telephonyRegistry);
t.traceEnd();
//add longzhiye
t.traceBegin("StartDevicesService");
try{ServiceManager.addService(Context.DEVICES_SERVICE,new DevicesService(context));
} catch(Throwable e){Slog.e("DevicesService","Failed to start DevicesService Service "+e);
}
t.traceEnd();
//add end

让lint检查忽略掉自己的模块

注(Android 11 以后谷歌强制开启lint检查,lint检查不过编译会报错)

frameworks/base/Android.bp

// TODO(b/145644363): move this to under StubLibraries.bp or ApiDocs.bp
metalava_framework_docs_args = "" +"--api-lint-ignore-prefix android.app. " +     //add_longzhiye"--api-lint-ignore-prefix android.icu. " +"--api-lint-ignore-prefix java. " +"--api-lint-ignore-prefix junit. " +"--api-lint-ignore-prefix org. " +"--error NoSettingsProvider " +"--error UnhiddenSystemApi " +"--force-convert-to-warning-nullability-annotations +*:-android.*:+android.icu.*:-dalvik.* " +"--hide BroadcastBehavior " +"--hide CallbackInterface " +"--hide DeprecationMismatch " +"--hide HiddenSuperclass " +"--hide HiddenTypeParameter " +"--hide MissingPermission " +"--hide-package android.audio.policy.configuration.V7_0 " +"--hide-package com.android.server " +"--hide RequiresPermission " +"--hide SdkConstant " +"--hide Todo " +"--hide Typo " +"--hide UnavailableSymbol " +"--manifest $(location core/res/AndroidManifest.xml) "

编译源码 更新api接口

make update-api

检查服务是否开启

将编译好的rom 刷入手机,查看sevice list
这里可以看到我们的服务 已经启动了:
服务名称:79 devices: [android.app.IDevices]

longzhiye@longzhiye-laptop:~$ adb shell
coral:/ # service list |grep Device
60    companiondevice: [android.companion.ICompanionDeviceManager]
75    device_identifiers: [android.os.IDeviceIdentifiersPolicyService]
76    device_policy: [android.app.admin.IDevicePolicyManager]
77    device_state: [android.hardware.devicestate.IDeviceStateManager]
78    deviceidle: [android.os.IDeviceIdleController]
79    devices: [android.app.IDevices]
251    virtualdevice: [android.companion.virtual.IVirtualDeviceManager]
coral:/ #

调用测试

应用层项目中引入aidl

// IDevices.aidl
package android.app;// Declare any non-default types here with import statementsinterface IDevices {String shellExec(String cmd);String readFile(String path);void writeFile(String path,String data);
}


调用测试:

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

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

相关文章

华为数通方向HCIP-DataCom H12-831题库(多选题:61-80)

第61题 在MPLS VPN中,为了区分使用相同地址空间的IPV4前缀,将IPV4的地址增加了RD值,下列选项描述正确的是: A、在PE设备上,每一个VPN实例都对应一个RD值,同一PE设备上,必须保证RD值唯一 B、RD可用于来控制VPN路由信息的发布 C、RD在传递过程中作为BGP的扩展团体性封装在…

易基因: Nature Biotech:番茄细菌性青枯病的噬菌体联合治疗|国人佳作

大家好&#xff0c;这里是专注表观组学十余年&#xff0c;领跑多组学科研服务的易基因。 生物防治是利用细菌接种剂来改变植物根际微生物群落的组成&#xff0c;但在以往研究中存在有接种的细菌在根际建立不良&#xff0c;与本地微生物组争夺资源&#xff0c;干扰本地微生物的…

单元测试,集成测试,系统测试的区别是什么?

实际的测试工作当中&#xff0c;我们会从不同的角度对软件测试的活动进行分类&#xff0c;题主说的“单元测试&#xff0c;集成测试&#xff0c;系统测试”&#xff0c;是按照开发阶段进行测试活动的划分。这种划分完整的分类&#xff0c;其实是分为四种“单元测试&#xff0c;…

存储器概述

一、存储系统基本概念

重庆开放大学学子们的好帮手

作为一名电大学员&#xff0c;我有幸目睹了一个令人惊叹的学习工具的诞生——电大搜题微信公众号。这个创新应用为重庆开放大学&#xff08;广播电视大学&#xff09;的学子们提供了便捷、高效的学习资源&#xff0c;成为他们的得力助手。 重庆开放大学是一所为全日制在职人员提…

OpenLayers.js 入门教程:打造互动地图的入门指南

本文简介 戴尬猴&#xff0c;我是德育处主任 本文介绍如何使用 OpenLayers.js &#xff08;后面简称 ol&#xff09;。ol 是一个开源 JavaScript 库&#xff0c;可用于在Web页面上创建交互式地图。 ol能帮助我们在浏览器轻松地使用地图功能&#xff0c;例如地图缩放、地图拖动…

文件权限详解

一、文件类型 ll指令查看文件详细信息中&#xff0c;第一列就是文件类型。 常见的文件类型有&#xff1a; 1、 - &#xff1a;普通文件 &#xff08;文本、源代码、图片、视频、可执行&#xff09; 2、 d &#xff1a;目录文件 3、b &#xff1a;块设备 4、c &#xff1…

【软件教程】如何用C++检查TCP或UDP端口是否被占用

一、检查步骤 使用socket函数创建socket_fd套接字。使用sockaddr_in结构体配置协议和端口号。使用bind函数尝试与端口进行绑定&#xff0c;成功返回0表示未被占用&#xff0c;失败返回-1表示已被占用。 二、CODE 其中port需要修改为想要检测的端口号&#xff0c;也可以将代码…

网络架构学习1

文章目录 网络架构学习11. 传统CNN卷积神经网络1.1 基本思想1.2 VCG16(经典CNN网络架构之一) 2. 两种经典的网络架构2.1 FCN网络2.2 U-Net网络 3. FCNVMB(基于U-Net架构)3.1 FCNVMB 主要思想3.2 FCNVMB 提供的其他思想 网络架构学习1 1. 传统CNN卷积神经网络 1.1 基本思想 C…

【Acwing167】木棒(dfs+剪枝)超级详细题解!

题目描述 统一说明 本题思路来源于acwing算法提高课 木棍指题目输入数据所指的东西 木棒指最后由木棍拼接而成的最长的东西 看本文需要准备的知识 1.dfs基本思想 2.对“剪枝”这个词汇有一个基本的认识即可 整体分析 这个题目最终是求木棒的最短长度&#xff0c;所以我…

shell脚本的基础知识

目录 1.什么是shell 2.shell脚本的意义 3.如何创建shell脚本 4.如何执行shell脚本 5.如何对脚本进行测试 脚本练习 1.什么是shell Shell是一种命令行解释器&#xff0c;是用户与操作系统内核之间的接口&#xff0c;允许用户编辑和执行命令。它是用户输入命令并将其传递给操…

万能鼠标设置 SteerMouse v5.6.8

鼠标可谓是用户们在使用电脑时候的必备外接设备呢&#xff01;适合你自己的鼠标设置也绝对能够优化你的Mac使用体验&#xff01;想要更好的Mac体验就试试用Steermouse Mac版吧。它通过软件来自由设置你的鼠标操作&#xff01;在这款万能鼠标设置工具中&#xff0c;用户可以在偏…

Tuxera NTFS2024破解版本下载

当您获得一台新 Mac 时&#xff0c;它只能读取 Windows NTFS 格式的 USB 驱动器。要将文件添加、保存或写入您的 Mac&#xff0c;您需要一个附加的 NTFS 驱动程序。Tuxera 的 Microsoft NTFS for Mac 是一款易于使用的软件&#xff0c;可以在 Mac 上打开、编辑、复制、移动或删…

hdlbits系列verilog解答(模块按名字)-22

文章目录 一、问题描述二、verilog源码三、仿真结果 一、问题描述 此问题类似于模块。您将获得一个名为的 mod_a 模块&#xff0c;该模块按某种顺序具有 2 个输出和 4 个输入。您必须按名称将 6 个端口连接到顶级模块的端口&#xff1a; module mod_a ( output out1, output …

FPGA从入门到精通(二十)SignalTapII

这一篇将介绍SignalTapII。 之前的工程我们是做仿真&#xff0c;设置激励&#xff0c;观察输出波形去判断代码没有问题&#xff0c;但事实上我们真实的需求是综合后的代码下载到FPGA芯片中能够符合预期。 其中可能出现问题的原因有&#xff1a; 1、我们是写testbench设置激励…

五、W5100S/W5500+RP2040树莓派Pico<UDP Client数据回环测试>

文章目录 1. 前言2. 协议简介2.1 简述2.2 优点2.3 应用 3. WIZnet以太网芯片4. UDP Client回环测试4.1 程序流程图4.2 测试准备4.3 连接方式4.4 相关代码4.5 测试现象 5. 注意事项6. 相关链接 1. 前言 UDP是一种无连接的网络协议&#xff0c;它提供了一种简单的、不可靠的方式来…

软考高级系统架构师冲关预测

[ – 2023年10月27日 – ] 去年11月通过了软考高级系统架构师的考试&#xff0c;原本想立即分享下过关的总结回顾&#xff0c;但是随着软考新版大纲及教程的发布&#xff0c;也意味着题目及内容的复盘总结经验便不那么适用。在即将迎来今年的软考高架的时候&#xff0c;想着透…

构建客户门户的痛点及低代码工具解决方案

企业如何做好数字化转型呢&#xff1f; 如果笼统地说起“数字化转型”&#xff0c;这个概念太大了&#xff0c;它涉及到了企业管理中的方方面面。数字化转型是一个持续不断的过程&#xff0c;既要在整体上进行数字规划&#xff0c;也需要从细节入手&#xff0c;将每一个步骤进…

学习笔记:tarjan

tarjan 引入 Robert Tarjan&#xff0c;计算机科学家&#xff0c;以 LCA、强连通分量等算法而闻名。Tarjan 设计了求解的应用领域的广泛有效的算法和数据结构。他以在数据结构和图论上的开创性工作而闻名&#xff0c;他的一些著名的算法有 Tarjan 最近公共祖先离线算法&#…

一、高效构建Java应用:Maven入门和进阶

一、高效构建Java应用&#xff1a;Maven入门和进阶 目录 一、Maven简介和快速入门 1.1 Maven介绍1.2 Maven主要作用理解1.3 Maven安装和配置 二、基于IDEA的Maven工程创建 2.1梳理Maven工程GAVP属性2.2 Idea构建Maven JavaSE工程2.3 Idea构建Maven JavaEE工程2.4 Maven工程项…