【二】车载FrameWork添加系统服务

自定义系统服务

常见的AMS、PWS、WMS等等都是系统服务,运行于system_server进程,并且向servicemanager进程注册其Binder以便其他进程获取binder与对应的服务进行通信。为了新增自定义系统服务,我们可以参考AMS等原生系统服务编写如下文件:

1、AIDL文件:生成Binder类,其中Stub即为Binder的服务端;

2、XXManagerService:系统服务类,继承自Stub;

3、XXManager:封装了AIDL接口方法的类,相当于Binder客户端(Proxy),其他进程通过此类完成与系统服务的通信。

增加系统服务

1、AIDL

在frameworks/base/core/java/com/enjoy/service中编写IEnjoyManager.aidl

// IEnjoyManager.aidl
package com.enjoy.service;// Declare any non-default types here with import statementsinterface IEnjoyManager {void sendMessage(String msg);
}

在frameworks/base/Android.mk中声明AIDL文件:

LOCAL_SRC_FILES += ....core/java/android/app/IActivityManager.aidl \core/java/com/enjoy/service/IEnjoyManager.aidl \....

2、系统服务

在frameworks/base/services/core/java/com/enjoy/service中编写EnjoyManagerService.java

package com.enjoy.service;import android.os.RemoteException;
import android.util.Log;public class EnjoyManagerService extends IEnjoyManager.Stub {private static final String TAG = "Enjoy";@Overridepublic void sendMessage(String msg) throws RemoteException {Log.i(TAG, "sendMessage: " + msg);}
}

3、客户端代理

在frameworks/base/core/java/com/enjoy/service下编写EnjoyManager.java

package com.enjoy.service;import android.os.RemoteException;
import android.util.Log;public class EnjoyManager {private static final String TAG = "Enjoy";private IEnjoyManager service;public EnjoyManager(IEnjoyManager service) {this.service = service;}public void sendMessage(String msg) {try {service.sendMessage(msg);} catch (RemoteException e) {e.printStackTrace();}}
}

framework/base/Android.mk:

packages_to_document := \android \javax/microedition/khronos \org/apache/http/conn \org/apache/http/params \com/enjoy/service

4、修改Context

在frameworks/base/core/java/android/content/Context.java中加入常量:

public static final String ENJOY_SERVICE="enjoy";

5、注册系统服务

在frameworks/base/services/java/com/android/server/SystemServer.java中 注册系统服务

import com.enjoy.service.EnjoyManagerService;
private void startOtherServices(){//......ServiceManager.addService(Context.ENJOY_SERVICE,new EnjoyManagerService());//......
}

6、注册应用系统服务获取器

在frameworks/base/core/java/android/app/SystemServiceRegistry.java注册服务获取器:

import com.enjoy.service.IEnjoyManager;
import com.enjoy.service.EnjoyManager;
static{registerService(Context.ENJOY_SERVICE, EnjoyManager.class,new CachedServiceFetcher<EnjoyManager>() {@Overridepublic EnjoyManager createService(ContextImpl ctx) throws ServiceNotFoundException  {// 获取服务IBinder b = ServiceManager.getServiceOrThrow(Context.ENJOY_SERVICE);IEnjoyManager service = IEnjoyManager.Stub.asInterface(b);return new EnjoyManager(service);}});
}

7、配置SELinux权限

system/sepolicy/private/service_contexts

activity                                  u:object_r:activity_service:s0					   
enjoy                                     u:object_r:enjoy_service:s0

system/sepolicy/public/service.te:

type activity_service, app_api_service, ephemeral_app_api_service, system_server_service, service_manager_type;
type enjoy_service, app_api_service, ephemeral_app_api_service, system_server_service, service_manager_type;

system/sepolicy/private/untrusted_app_all.te :

allow untrusted_app enjoy_service:service_manager find;

*8、配置白名单

如果以当前案例的方式新增自定义系统服务,因为SystemServiceRegistry 中需要使用到com.enjoy下的类,为了让其获取此包下类的引用,需要配置:build/core/tasks/check_boot_jars/package_whitelist.txt ,加入:com\.enjoy\..* 。否则会因为无法获取类引用而编译报错!

dalvik\..*
libcore\..*
android\..*
com\.android\..*
com\.enjoy\..*  

若新增的服务像AMS等原有系统服务的IActivityManager.aidl与ActivityManager一样放在android.app包下即可不用进行此步处理!

9、编译并刷机

#编译
make update-api
make –j4 
#刷机
adb reboot bootloader
reboot flashall -w

10、使用自定义服务

10.1 利用双亲委托机制

在需要使用自定义服务的app中编写EnjoyManager(包名与framework中一致):

package com.enjoy.service;import android.os.RemoteException;
import android.util.Log;public class EnjoyManager {public void sendMessage(String msg) {}
}

此时由于类加载的双亲委托机制,app在运行时实际使用的是framework中的EnjoyManager。app中的EnjoyManager仅仅只是为了编译成功编写的空壳。

10.2 修改SDK

修改app使用的sdk,可以通过make sdk 将SDK完成编译出来。也可以直接在out/target/common/obj/JAVA_LIBRARIES/framework_intermediates中找到EnjoyManager类将其加入原生SDK中的android.jar

SystemService

系统服务需要通过ServiceManager.addService("xx", new XXManagerService);将自己(Binder Stub)注册进入SM才能够让其他进程利用Binder与之通信。而自定义系统服务如果需要根据系统启动的不同阶段进行不同的处理则需要注册生命周期回调。以AMS为例:

/frameworks/base/services/java/com/android/server/SystemService中启动AMS:

private void startBootstrapServices() {//...// Activity manager runs the show.traceBeginAndSlog("StartActivityManager");mActivityManagerService = mSystemServiceManager.startService(ActivityManagerService.Lifecycle.class).getService();mActivityManagerService.setSystemServiceManager(mSystemServiceManager);mActivityManagerService.setInstaller(installer);traceEnd(); //...mActivityManagerService.setSystemProcess();//...
}

AMS中的setSystemProcess方法的实现为:

public void setSystemProcess() {//...ServiceManager.addService(Context.ACTIVITY_SERVICE, this, /* allowIsolated= */ true,DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO);//...
}

setSystemProcess中会完成向SM注册AMS的实现。而在setSystemProcess之前有一段代码:

 mActivityManagerService = mSystemServiceManager.startService(ActivityManagerService.Lifecycle.class).getService();

则为注册生命周期监听,ActivityManagerService.Lifecycle就相当于生命周期的回调接口对象,它继承自:

/frameworks/base/services/core/java/com/android/server/SystemService。这个SystemService中主要需要实现两个方法:

  • onStart() :mSystemServiceManager.startService第一时间回调该函数。

  • onBootPhase(int phase) : 系统启动的各个阶段会回调该函数

    • SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY:这是一个依赖项,只有DisplayManagerService中进行了对应处理;
    • SystemService.PHASE_LOCK_SETTINGS_READY:经过这个引导阶段后,服务才可以接收到wakelock相关设置数据;
    • SystemService.PHASE_SYSTEM_SERVICES_READY:经过这个引导阶段 后,服务才可以安全地使用核心系统服务
    • SystemService.PHASE_ACTIVITY_MANAGER_READY:经过这个引导阶 段后,服务可以发送广播
    • SystemService.PHASE_THIRD_PARTY_APPS_CAN_START:经过这个引导阶段后,服务可以启动第三方应用,第三方应用也可以通过Binder来调用服务。
    • SystemService.PHASE_BOOT_COMPLETED:经过这个引导阶段后,说明服务启动完成,这时用户就可以和设备进行交互。

比如AMS中的Lifecycle:

public static final class Lifecycle extends SystemService {@Overridepublic void onBootPhase(int phase) {mService.mBootPhase = phase;if (phase == PHASE_SYSTEM_SERVICES_READY) {mService.mBatteryStatsService.systemServicesReady();mService.mServices.systemServicesReady();} else if (phase == PHASE_ACTIVITY_MANAGER_READY) {// 准备广播处理mService.startBroadcastObservers();} else if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) {mService.mPackageWatchdog.onPackagesReady();}}
}

在AMS中会处理PHASE_ACTIVITY_MANAGER_READY ,经过这个阶段后,也就是需要在下一个阶段PHASE_THIRD_PARTY_APPS_CAN_START才可以发送广播。

同步问题

在修改了SDK之后,可能出现同步错误:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

此时我们需要去修改AGP插件中的一个类:MockableJarGenerator

在我的工程当中当前使用的AGP版本为:7.2.1,从C:\Users\Administrator\.gradle\caches\modules-2\files-2.1\com.android.tools.build\builder\7.2.1 目录下找到builder-7.2.1-sources.jar 并将其解压,找到com.android.builder.testing 中的MockableJarGenerator。

将此类放入Android Studio工程app模块的单元测试中,并在app的gradle中加入:

dependencies {   testImplementation 'org.ow2.asm:asm:7.1'testImplementation 'org.ow2.asm:asm-commons:7.1'//    testImplementation 'com.google.guava:guava:23.6-jre'testImplementation group:'com.google.guava', name:'guava', version:'23.6-jre'
}

操作步骤为:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

最后将C:\Users\Administrator\.gradle\caches\modules-2\files-2.1\com.android.tools.build\builder\7.2.1builder-7.2.1.jarMockableJarGenerator.class替换成刚刚编译的class文件。

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

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

相关文章

Brian Kernighan 算法应用

Brian Kernighan算法&#xff0c;也被称为布莱恩柯林汉算法&#xff0c;是一种用于统计二进制中位数为1的个数的高效算法。该算法通过不断清除二进制数中最右侧的1来计算1的个数&#xff0c;直到二进制数变为0为止。 201. 数字范围按位与 461. 汉明距离 # 461. 汉明距离 clas…

Python教程:拆分多级目录的方法

前言 大家早好、午好、晚好吖 ❤ ~欢迎光临本文章 如果有什么疑惑/资料需要的可以点击文章末尾名片领取源码 实现多级目录差分&#xff0c;举例说明如下&#xff1a; 假设现有的目录结构如下&#xff1a;1、2、2.1、2.2、2.3、2.4、3、4、5、6、6.1、6.1.1、6.1.2、6.1.3、6…

WinSCP下载安装并实现远程SSH本地服务器上传文件

文章目录 1. 简介2. 软件下载安装&#xff1a;3. SSH链接服务器4. WinSCP使用公网TCP地址链接本地服务器5. WinSCP使用固定公网TCP地址访问服务器 1. 简介 ​ Winscp是一个支持SSH(Secure SHell)的可视化SCP(Secure Copy)文件传输软件&#xff0c;它的主要功能是在本地与远程计…

【Unity学习笔记】第十一 · 动画基础(Animation、状态机、root motion、bake into pose、blendTree、大量案例)

转载引用请注明出处&#xff1a;&#x1f517;https://blog.csdn.net/weixin_44013533/article/details/132081959 作者&#xff1a;CSDN|Ringleader| 如果本文对你有帮助&#xff0c;不妨点赞收藏关注一下&#xff0c;你的鼓励是我前进最大的动力&#xff01;ヾ(≧▽≦*)o 主…

#Uniapp:微信开发者工具运行与打包---打包H5---打包app

微信开发者工具运行与打包 manifest.json 添加上微信小程序AppID ** 如果点击打不开从微信开发者工具先到处本地C:\Users\fjgk-28\Desktop\huanrun\uni-demo\uni-shop\unpackage\dist\dev\mp-weixin 打开 添加上AppID试试** 微信开发者工具上传代码需要 "permission&quo…

Redis——list以及他的应用场景

介绍 &#xff1a;list 即是 链表。链表是一种非常常见的数据结构&#xff0c;特点是易于数据元素的插入和删除并且且可以灵活调整链表长度&#xff0c;但是链表的随机访问困难。许多高级编程语言都内置了链表的实现比如 Java 中的 LinkedList&#xff0c;但是 C 语言并没有实现…

文件防止泄密的措施,公司如何防止电脑泄密(防止信息泄露的6大秘籍)

在当今信息时代&#xff0c;数据安全和信息保密对于企业来说至关重要。然而&#xff0c;泄密事件时有发生&#xff0c;给企业带来巨大的损失和风险。 某泄密事件&#xff1a; 某大型企业发生了一起严重的电脑泄密事件&#xff0c;导致大量客户资料和内部战略规划被泄露。 经过…

网工每日一练(1月25日)

【说明】 某仓储企业网络拓扑结构如图1-1所示&#xff0c;该企业占地500亩。有五层办公楼1栋&#xff0c;大型仓库10栋。每栋仓库内、外部配置视频监控16台&#xff0c;共计安装视频监控160台&#xff0c;SwitchA、服务器、防火墙、管理机、RouterA等设备部署在企业办公楼一层的…

【C++入门到精通】智能指针 shared_ptr循环引用 | weak_ptr 简介及C++模拟实现 [ C++入门 ]

阅读导航 引言一、std::shared_ptr的循环引用1. 概念2. 示例分析 二、std::weak_ptr1. 简介2. weak_ptr模板类提供的成员方法3. 使用示例&#xff08;1&#xff09;weak_ptr指针的创建&#xff08;2&#xff09;完整示例&#xff08;解决上面循环引用问题&#xff09; 4. C模拟…

如何使用Flutter构建高质量的用户界面

Flutter 是一种比较流行的移动应用开发框架&#xff0c;可以让开发者使用一个代码库构建高质量的 iOS 和 Android 应用。Flutter 以其快速、美观、高度可定制等优点吸引了开发社区的广泛关注。但如何使用 Flutter 构建高质量的用户界面呢&#xff1f;下面分为以下几个部分简单的…

centos更换国内yum下载源

centos更换国内yum下载源 1.前提&#xff0c;可以ping通百度 先下载wget工具&#xff0c;可能有点慢 yum install -y wget2.备份原来的下载源 sudo mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup3.更换源 3.1更换阿里源 # 下载阿里云的…

JNI中获取当前时间戳

在JNI中获取当前时间戳&#xff0c;使用java.util.Date类的getTime()方法。以下是在JNI中获取当前时间戳的示例代码&#xff1a; 首先&#xff0c;在Java代码中定义一个获取当前时间戳的方法&#xff1a; public class MyUtils {public static native long getCurrentTimesta…

Matlab图像处理——谷物颗粒计数

针对目前谷物人工计数和光电计数方法存在的不足 , 提出了一种基于 Matlab 图像识别和处理技术的谷物计数方法 , 并用实例验证了其可靠性。该方法减轻了操作者劳动强度 , 弥补了人视觉的不足之处 , 提高了效率及准确率 , 为今后进一步研究奠定了必要的理论与实践基础 , 对完善“…

HarmonyOS鸿蒙应用开发 (二、应用程序包结构理解及Ability的跳转,与Android的对比)

在进行应用开发前&#xff0c;对程序的目录及包结构的理解是有必要的。如果之前有过android开发经验的&#xff0c;会发现OpenHarmony的应用开发也很简单&#xff0c;有很多概念是相似的。下面对比android分析总结下鸿蒙的应用程序包结构&#xff0c;以及鸿蒙对比android的诸多…

armv8 - GIC-V2 中断控制器

GIC起源 上一节中&#xff0c;粗略讲了hylicos上用的armv7上的一个通用中断控制器&#xff0c;其只支持60个中断源。但现代SoC上&#xff0c;中断系统正变得越来越复杂&#xff0c;旧的中断控制器已经无法胜任这些系统&#xff0c;主要体现在以下几点上&#xff1a; 中断源越…

android 自定义软键盘的显示和隐藏

记一下,以后不用找在InputMethodService中有这两个方法可以看到软键盘显示状态 //软键盘隐藏 override fun onWindowHidden() {super.onWindowHidden() } //软键盘显示 override fun onWindowShown() {super.onWindowShown() } 在activity中可以通过这种方法看到软键盘显示状…

《WebKit 技术内幕》学习之六(1): CSS解释器和样式布局

《WebKit 技术内幕》之六&#xff08;1&#xff09;&#xff1a;CSS解释器和样式布局 CSS解释器和规则匹配处于DOM树建立之后&#xff0c;RenderObject树之前&#xff0c;CSS解释器解释后的结果会保存起来&#xff0c;然后RenderObject树基于该结果来进行规范匹配和布局计算。当…

【力扣 21】合并两个有序链表 C++题解(链表+双指针)

将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1&#xff1a; 输入&#xff1a;l1 [1,2,4], l2 [1,3,4] 输出&#xff1a;[1,1,2,3,4,4] 示例 2&#xff1a; 输入&#xff1a;l1 [], l2 [] 输出&#xff1a;[]…

小程序发劵插件sendCoupon的使用

发劵插件官方文档 我目前的需求是&#xff0c;商家自定义满减劵、优惠劵&#xff0c;点击添加按钮可以添加到自己的卡包。 一开始后台了我发劵插件send-coupon文档&#xff0c;我想要用插件&#xff0c;又占空间&#xff0c;感觉又麻烦&#xff0c;不是有个wx.addCard嘛。非常…

求连续值遍历步数 OD(C++)

将从1开始的连续整数随机打乱,存放到数组 numbers中,请计算从1开始递增访问完所有元素,总共需要移动的步数。 输入 2<= numbers,length <= 100, 1 <= numbers[i]<= numbers.length 输出 一个整数,表示需要移动的步数 样例1 输入:[4,3,6,1,5,2] 输出…