Android framework自定义系统服务

主要分享在Android9.0上添加自定义服务的过程,和遇到的SELinux权限的问题,这篇帖子将紧接着上一篇Android系统源码编译,接下来还是以Android9.0,手机设备Piexl一代为例,来讲述framework自定义系统服务。

一、环境准备

(1) Ubuntu16.04(270G+16核+32GRAM)
(2) VMware15
(3) Android Studio (可以在这里创建一个工程,把类写好后拷贝到Android系统源码下)
(4) Sublim Text 3 (这个工具用于修改Android源代码,装好ctags插件实现函数之间的跳转)

二、概述

自定义系统服务首先要创建aidl文件、aidl的stub实现类以及服务的Manager类,总共涉及到三个文件(这里我会进行一个拓展,如何在系统服务中添加一个回调,那么现在总共涉及到四个文件)首先我们先定义文件的名称:
(1)IHelloService.aidl
(2)HelloService.java
(3)HelloServiceManager.java
(4)IHelloCallback.aidl (回调接口,主要用于做一些监听事件,在某些场景下很有用,比如说监听某些函数的调用或者返回一些有用的数据)

/frameworks/base/core/java/android/os/IHelloCallback.aidl

package android.os;

// Declare any non-default types here with import statements
interface IHelloCallback{

  void callback(String str);
  
}

/frameworks/base/core/java/android/os/IHelloService.aidl

package android.os;

import android.os.IHelloCallback;

// Declare any non-default types here with import statements
interface IHelloService{

  void registerCallBack(IHelloCallback callBack);
 
  void registerCallBack(IHelloCallback callBack);

  void invokeHello(String str);
  
}

/frameworks/base/core/java/com/android/server/HelloService.java

package com.android.server;

import android.os.IHelloCallback;
import android.os.IHelloService;
import android.os.RemoteCallbackList;
import android.os.RemoteException;

public class HelloService extends IHelloService.Stub {
  private RemoteCallbackList<IHelloCallback> sCallbackList = new RemoteCallbackList();
  
  @Override
  void registerCallBack(IHelloCallback callback) throws RemoteException{
	 if(callback != null) {
	  	  sCallbackList.register(callback);
	  }
  }
 
 @Override
  void registerCallBack(IHelloCallback callback) throws RemoteException{
	if(callback != null) {
	  	 sCallbackList.unregister(callback);
	 }
  }

  @Override
  void invokeHello(String str) throws RemoteException{
     /*
     	注意这里有一个坑,就是RemoteCallbackList的beginBroadcast方法
     	和finishBroadcast方法必须要配套使用否则会抛出异常;
     	解决方案可以进行加锁,或者使用单个线程来控制调用
     */
  	 int len = sRemoteCallbackList.beginBroadcast();
     for (int i=0;i<len;i++) {
        try {
             IHelloCallback callback= sRemoteCallbackList.getBroadcastItem(i);
             callback.callback(str);
        }catch (Exception e) {
             e.printStackTrace();
        }
     }
     sRemoteCallbackList.finishBroadcast();
  }
}

/frameworks/base/core/java/com/android/server/HelloServiceManager.java

package com.android.server;

import android.content.Context;
import android.os.IHelloCallback;
import android.os.IHelloService;
import android.os.RemoteException;

public class HelloServiceManager {
    private Context context;
    private IHelloService helloService;

    public HelloServiceManager(Context context, IHelloService helloService) {
        this.context = context;
        this.helloService = helloService;
    }

    public void registerCallBack (IHelloCallback callback) throws RemoteException {
        helloService.registerCallBack(callback);
    }

    public void unRegisterCallBack(IHelloCallback callback) throws RemoteException {
        helloService.unRegisterCallBack(callback);
    }

    public void invokeApi(String str) {
        try {
            helloService.invokeHello(str);
        }catch (Exception e) {
            e.printStackTrace();
        }
    }
}

三、注册系统服务

(1)在/frameworks/base/core/java/android/content/Context.java文件中添加属性

public static final String HELLO_SERVICE = "hello";
.....
.....
.....
@StringDef(suffix = { "_SERVICE" }, value = {
	....
	....
	HELLO_SERVICE,  //在这里添加系统服务的静态字段
	....
	....
})

(2)在/frameworks/base/services/java/com/android/server/SystemServer.java文件中的startOtherServices方法中添加系统服务

try{
	//.................

	traceBeginAndSlog("HelloService");
	HelloService helloService = new HelloService();
	ServiceManager.addService(Context.HELLO_SERVICE, helloService);
	traceEnd();
}catch(Exception e){
 	 //................
 	 //................
}

(3)在/frameworks/base/core/java/android/app/SystemServiceRegistry.java文件中的static静态代码块中注册系统服务

static {
	//.....................
	registerService(Context.HELLO_SERVICE, HelloServiceManager.class,
                new CachedServiceFetcher<HelloServiceManager>() {
                    @Override
                    public HelloServiceManager createService(ContextImpl ctx)
                            throws ServiceNotFoundException {

                        IHelloService service = IHelloService.Stub.asInterface(
                                ServiceManager.getServiceOrThrow(Context.HELLO_SERVICE));
                        return new HelloServiceManager(ctx.getOuterContext(), service);
                    }});
}

三、注册aidl文件

编辑\aosp\frameworks\base\Android.dp文件,添加以下内容

"core/java/android/os/IHelloService.aidl",
"core/java/android/os/IHelloCallback.aidl",

四、添加SELinux权限

这里涉及的文件比较多,按照步骤一步一步添加就可以了
(1)编辑
a. system/sepolicy/private/service_contexts文件
b. system/sepolicy/prebuilts/api/28.0/private/service_contexts文件
c. system/sepolicy/prebuilts/api/27.0/private/service_contexts文件
d. system/sepolicy/prebuilts/api/26.0/private/service_contexts文件
添加内容如下(注意这文件内容要一致,要不然编译通不过):

hello                             u:object_r:hello_service:s0

(2)编辑
a. system/sepolicy/public/service.te文件
b. system/sepolicy/prebuilts/api/28.0/public/service.te文件
c. system/sepolicy/prebuilts/api/27.0/public/service.te文件
d. system/sepolicy/prebuilts/api/26.0/public/service.te文件
添加内容如下(注意这文件内容要一致,要不然编译通不过):

type hello_service, system_api_service, system_server_service, service_manager_type;

(3)编辑
a. system/sepolicy/private/compat/26.0/26.0.cil文件,
b. system/sepolicy/prebuilts/api/28.0/private/compat/26.0/26.0.cil文件
c. system/sepolicy/prebuilts/api/27.0/private/compat/26.0/26.0.cil文件

(typeattributeset hello_service_26_0 (hello_service))

(4)编辑
a. system/sepolicy/private/compat/27.0/27.0.cil文件
b. system/sepolicy/prebuilts/api/28.0/private/compat/27.0/27.0.cil文件

(typeattributeset hello_service_27_0 (hello_service))

(5)编辑 system/sepolicy/prebuilts/api/26.0/nonplat_sepolicy.cil文件

(typeattribute hello_service_26_0)
(roletype object_r hello_service_26_0)

(6)编辑system/sepolicy/prebuilts/api/27.0/nonplat_sepolicy.cil文件

(typeattribute hello_service_27_0)
(roletype object_r hello_service_27_0)

(7)编辑
a. system/sepolicy/private/untrusted_app文件
b. system/sepolicy/prebuilts/api/28.0/private/untrusted_app文件
c. system/sepolicy/prebuilts/api/27.0/private/untrusted_app文件
d.system/sepolicy/prebuilts/api/26.0/private/untrusted_app文件

allow untrusted_app hello_service:service_manager find;

(8)编辑
a. system/sepolicy/private/untrusted_app_25文件
b. system/sepolicy/prebuilts/api/28.0/private/untrusted_app_25文件
c. system/sepolicy/prebuilts/api/27.0/private/untrusted_app_25文件
d.system/sepolicy/prebuilts/api/26.0/private/untrusted_app_25文件

allow untrusted_app_25 hello_service:service_manager find;

(9)编辑
a. system/sepolicy/private/untrusted_app_27文件
b. system/sepolicy/prebuilts/api/28.0/private/untrusted_app_27文件
c. system/sepolicy/prebuilts/api/27.0/private/untrusted_app_27文件
d.system/sepolicy/prebuilts/api/26.0/private/untrusted_app_27文件

allow untrusted_app_27 hello_service:service_manager find;

(10)编辑
a. system/sepolicy/private/untrusted_app_all文件
b. system/sepolicy/prebuilts/api/28.0/private/untrusted_app_all文件
c. system/sepolicy/prebuilts/api/27.0/private/untrusted_app_all文件
d.system/sepolicy/prebuilts/api/26.0/private/untrusted_app_all文件

allow untrusted_app_all hello_service:service_manager find;

(11)编辑
a. system/sepolicy/private/untrusted_v2_app文件
b. system/sepolicy/prebuilts/api/28.0/private/untrusted_v2_app文件
c. system/sepolicy/prebuilts/api/27.0/private/untrusted_v2_app文件
d.system/sepolicy/prebuilts/api/26.0/private/untrusted_v2_app文件

allow untrusted_v2_app hello_service:service_manager find;

添加完之后,使用make update-api更新

五、编译

在aosp根目录下使用以下命令进行编译

(1)source build/envsetup.sh
(2)lunch
(3)make -j32

六、调用自定义服务

在这里可以利用java的双亲委派机制,在自己的工程中引入这些自定义服务相关联的类,这样就可以直接使用这些类了,不需要用到反射

HelloServiceManager helloServiceManager = (HelloServiceManager) getSystemService(Context.HELLO_SERVICE);
helloServiceManager.registerCallBack(new IHelloCallback(){
	public void callback(String str){
		Log.e("asjhan","接收到的内容:"+str);
	}
});
helloServiceManager.invokeApi("hello world");

七、编译报错

编译报错最多的就是SELinux方面的东西,这里举几个常见的报错例子
(1)find权限

SELinux: avc:  denied  { find } for service=hello pid=5620 uid=10073 scontext=u:r:untrusted_app:s0:c73,c256,c512,c768 tcontext=u:object_r:hello_service:s0 tclass=service_manager permissive=0

解决方式

allow untrusted_app hello_service:service_manager find

基本的参考公式,模板:allow scontext tcontext:tclass permission;

scontext=u:r:untrusted_app                  什么文件
tcontext=u:object_r:hello_service           什么服务
tclass=service_manager                      什么类型
denied  { find }                            什么权限

(2)api更新

frameworks/base/api/system-current.txt:25036: error 8: Removed public class 

解决方式

make update-api

如果修改了Android原有API的 ,需要update frameworks/base/api/current.txt。否则编译被中断并出现编译错误提示


asjhan for Android reverse

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android framework底层开发课件是一门深入了解Android操作系统底层架构和实现原理的课程。在这门课程中,学生将学习如何通过开发Android framework层的组件和功能来增强和扩展Android平台的能力。 在Android系统中,框架层是连接应用程序和底层系统组件的关键。它提供了一系列的API和服务,使应用程序能够访问底层资源和功能,例如网络通信、传感器、数据库等。同时,它也负责处理应用程序之间的交互和管理系统级别的任务。 在课程中,学生将学习如何使用Java和Kotlin编程语言来开发Android framework层的代码。他们将学习使用Android SDK工具和开发环境,如Android Studio,来创建、调试和测试自己的应用程序和组件。 课程的内容将包括以下主题: 1. Android系统架构:学生将了解Android操作系统的整体架构和各个组件的作用,包括应用层、框架层和底层硬件驱动。 2. 框架层API和服务:学生将学习Android框架层提供的各种API和服务,如Activity、BroadcastReceiver、ContentProvider、Service等,并学习如何使用它们来构建应用程序。 3. 系统级别的任务管理:学生将学习如何管理应用程序的生命周期,并探索Android系统如何管理任务和进程,以及如何优化内存和性能。 4. 自定义组件和功能:学生将学习如何扩展Android框架层的能力,通过开发自定义组件和功能,如自定义View、自定义动画、添加新的系统服务等。 5. 其他相关技术:课程还将涉及其他相关技术,如Android的安全性和权限管理、多线程编程、性能优化等。 通过学习Android framework底层开发课件,学生将对Android系统的内部工作原理有更深入的理解,并能够开发出更具创造力和功能的Android应用程序。这将使他们在Android开发领域有更广阔的发展机会和竞争优势。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值