Android 7.1.1 源码framework中加入自定义服务,亲测成功运行

准备工作

开始之前需准备以下工具:
 

Android 7.1.1源码

Linux系统(Ubuntu or others)

JDK_1.8.0_191 (openjdk亦可)

 

Android源码可从google官网下载,当然国内因为墙的原因,可以购买VPN或其他方式获取。笔者推荐使用清华镜像下载,不用翻墙,且速度较快。因代码较大,可能需要长达10个小时的时间才能下载完成。笔者下载了一晚上,搞定。建议不要直接下载aosp.zip的压缩包文件,解压容易出错。导致源码编译不过。

 

PS: 因Android7.1.1源码很大,大概有30多个G。编译之后生成的文件更大,建议留足空间。笔者Home目录有200G硬盘。

 

1. 推荐一篇文章,可以下载Android源码:

https://blog.csdn.net/sk569437/article/details/52046917

 

2. 编译Android原生代码,具体方法这里不详述,不了解的可以参考我的另一篇文章。

Ubuntu16.04 LTS 编译Android6.0.1源码

 

 

3. Android原生代码通过make全编通过,编译完成之后,可以通过emulator命令启动out目录下生成的image文件,需要注意在执行emulator命令之前,需要执行如下命令构建环境

source build/envsetup.sh

执行结果如下:

 

如下命令选择产品:

lunch

笔者编译源码时使用的是第五个aosp_x86-eng(编译64位占用硬盘空间太大),因此这里选择编译时选择的产品,结果如下:

 

 

 

 

Android调用系统服务WindowManager方法:

 

android开发中调用系统服务,使用Context的getSystemService(String service_name)函数获取。了解安卓的知道具体实现函数在ContextImpl.java中。调用方法如下:

WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);

 

 

系统服务注册流程:

跟踪代码进入上面的context.getSystemService的调用代码,最终到ContextImpl中,如下: 

 

@Override
public Object getSystemService(String name) {
    return SystemServiceRegistry.getSystemService(this, name);
}
 

从上面可以知道系统服务的注册流程,实际上ContextImpl也是通过SystemServiceRegistry.getSystemService()来获取具体的服务,这些系统服务都是在SystemServiceRegistry.javastatic静态代码块中进行注册的。

可以按照系统服务注册使用的方式,加入我们自定义的测试服务----- SelfService

 

 

 

 

定义 ISelfManager.aidl 文件

系统里面很多的aidl文件定义在android_7.1.1/frameworks/base/core/java/android/os下,所以我们需要做的就是参考其他的aidl,照样子写一个简单的ISelfManager.aidl

在android_7.1.1/frameworks/base/core/java/android/os/目录下建立ISelfManager.aidl文件。代码如下:

package android.os; 
interface ISelfManager { 
    int selfAddNumber(int numberFirst, int numberSecond); 
    String selfAddString(String originalStr); 
}

 

 

 

 

编译 ISelfManager.aidl 文件

 

android_7.1.1/frameworks/base/Android.mk文件的LOCAL_SRC_FILES中添加自定义ISelfManager.aidl文件,可以看到这里有很多aidl文件。

LOCAL_SRC_FILES += \
        core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl \
        ...

	core/java/android/os/ISelfManager.aidl \

        ...

然后使用命令mmm frameworks/base,此时会自动根据aidl文件生成对应的stub接口

mmm frameworks/base

 

 

 

 

添加远端实现代码 SelfManagerService.java

这里,我们没有特殊的需求就放在android_7.1.1/frameworks/base/services/core/java/com/android/server里。当然也可以在这个目录下新建一个文件加放入我们的服务。为方便,我们直接在当前目录新建SelfManagerService.java文件。代码如下:

 

package com.android.server;
import android.util.Log;
import android.os.ISelfManager;

public class SelfManagerService extends ISelfManager.Stub {
    private static final String TAG = "SelfManagerService";


    public int selfAddNumber(int numberFirst, int numberSecond) {
        Log.d(TAG,"I WILL CALCULATE IT numberFirst is:"+numberFirst+"  numberSecond is :"+numberSecond);
    return numberFirst + numberSecond;
    }

    public String selfAddString(String originalStr) {
    Log.d(TAG,"I will add a string to originalStr previous....");
        return "previous lalala "+originalStr;
    }
}

 

 

 

 

创建对应的SelfManager.java,  即客户端代理类

android_7.1.1/frameworks/base/core/java/android/app/目录下创建SelfManager.java,代码如下:

package android.app;
import android.util.Log;
import android.os.ISelfManager;
import android.content.Context;
import android.os.RemoteException;

public class SelfManager {
    private static String TAG = "SelfManager";

    ISelfManager mSelfManager;

    public SelfManager(Context ctx,ISelfManager selfManager) {
        mSelfManager = selfManager;
    }

    public int selfAddNumber(int numberFirst, int numberSecond) throws RemoteException {
        Log.d(TAG,"SelfManager  selfAddNumber ......... ");
        return mSelfManager.selfAddNumber(numberFirst,numberSecond);
    }

    public String selfAddString(String originalStr) throws RemoteException {
    Log.d(TAG,"SelfManager  selfAddString .........");
        return mSelfManager.selfAddString(originalStr);
    }
}

 

定义SELF_SERVICE服务名

 

在Context文件中,添加我们自定义的SelfService服务的名字 ---- self  ,  代码如下:

public static final String SELF_SERVICE = "self";

 

 

 

系统服务(SystemServer.java)中添加自定义服务SelfManagerService

 

我们知道wifi_service, location_service, window_service都必须添加到SystemServer中。SystemServer.java文件在以下目录。

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

 

SystemServer中添加自定义的SelfManagerService服务,服务名字用前面在Context中定义的SELF_SERVICE代替,代码如下:

private void startOtherServices() {
    ....

    ServiceManager.addService(Context.SELF_SERVICE, new SelfManagerService());
    ....
}

 

 

 

 

SystemServiceRegistry.java中注册服务

 

在以下文件android_7.1.1/frameworks/base/core/java/android/app/SystemServiceRegistry.java中静态注册自定义SelfManagerService服务。代码如下:

Log.e("SelfManager", "----------------- before register selfManager service-------");
registerService(Context.SELF_SERVICE, SelfManager.class,
           new CachedServiceFetcher<SelfManager>() {
                @Override
                public SelfManager createService(ContextImpl ctx) {
                    IBinder b = ServiceManager.getService(Context.SELF_SERVICE);
                    ISelfManager service = ISelfManager.Stub.asInterface(b);
		    Log.e("SelfManager", "%%%%%%%%%%% SelfManager NEW %%%%%%%%%%%%%%");
                        return new SelfManager(ctx,service);
                    }});

Log.e("SelfManager", "++++++++++++++++++++ end register selfManager service-------");

 

 

 

 

更新sepolicy配置

 

 

需要更新sepolicy的配置,否则即使编译通过也是不会生效的。

不同版本不同厂商sepolicy文件位置不同,android7.1.1源码的位置在android_7.1.1/system/sepolicy/目录下面。

 

 

 

更新service.te文件

 

更新android_7.1.1/system/sepolicy/service.te文件,在里面找写代码,如下:

 

type self_service, system_api_service, system_server_service, service_manager_type;

 

 

注意这里写的self_service。 当前目录下另外一个文件service_contexts中添加的代码必须用这个字符串,代码如下:

self                                      u:object_r:self_service:s0

 

PS:前面写的self就是Context.java重定义的服务名SELF_SERVICE的内容。后面的self_service是前面service.te文件中定义的那个名字。

 

 

更新API

需要更新当前系统的API,执行如下命令:

make update-api -j4

 

 

完成之后会生成自己添加的服务的API。可以在android_7.1.1/frameworks/base/api/current.txt里面查看,有如下代码说明更新成功:

  public class SelfManager {
    ctor public SelfManager(android.content.Context, android.os.ISelfManager);
    method public int selfAddNumber(int, int) throws android.os.RemoteException;
    method public java.lang.String selfAddString(java.lang.String) throws android.os.RemoteException;
  }

 

 

编译代码

执行如下命令编译代码,更新system.img文件。

make -j8

 

 

 

验证SelfManagerService服务是否添加成功

 

在android studio IDE中新建一个工程TestSelfService。 获取SelfService服务,调用其函数,看是否正常。

由于用到的SelfManager类在android sdk中不存在,为了正常编译打包,可自定义一个module,新建一个SelfManager文件,内容如下:

package android.app;


public class SelfManager {
    public int selfAddNumber(int numberFirst, int numberSecond){
        return 0;
    }

    public String selfAddString(String originalStr){
        return null;
    }

}

 

不用写具体的函数实现,只要写空函数就行。打包成SelfManager-release.jar包,供工程使用。

打包时使用providedcompileOnly 只参与编译,不参与打包命令。打包成apk文件。测试代码如下:

package com.ts.sk.testselfservice;

import android.app.SelfManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "SelfService";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        findViewById(R.id.tv_tip).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                testSelfService();
            }
        });
    }

    private void testSelfService() {
        try {
            SelfManager sm = (SelfManager) getSystemService("self");
            if(sm == null) {
                Log.e(TAG, "self manager service is null....");
                return;
            }
            Log.d(TAG, "self manager before called....");

            int ret = sm.selfAddNumber(3, 4);
            Log.d(TAG, "self manager add num is:" + ret);

            String ret2 = sm.selfAddString("hello self service");
            Log.d(TAG, "self manager add String is:" + ret2);

        }catch (Exception e){
            Log.e(TAG, "self manager invoke method get exception, msg:" + e.getMessage());
        }
    }
}

 

使用compileOnly命令参与编译,不参与打包APK,配置如下:

 

 

PS: 使用getSystemService(String name)函数获取selfManager服务时,使用self字符串,因为andrid SDK中没有定义SELF_SERVICE

 

运行

有条件的可以将生成的system.img烧写到手机中。没有工程手机,也可以直接运行生成的模拟器。

 

在终端中输入如下命令,运行模拟器:

//这里是以源码自带的内核启动模拟器
emulator&

//若想以自定义的内核启动模拟器,用以下命令,-kernel 后面跟自己编译出来的内核文件全路径
emulator -kernel ./kernel/android-goldfish-3.10/arch/x86/boot/bzImage &

 

 

安装测试APK

 

使用adb命令将打包的测试apk文件安装到模拟器上。运行。

adb install -r TestSelfService.apk

安装之后如下:

 

 

查看自定义服务是否注册成功

 

通过adb shell service list命令可以列出当前设备中所有已注册的服务。命令如下:

adb shell service list

执行结果如下:

 

从上面可以看到我们自定义服务 self 已经注册成功。

 

 

 

运行测试APK

 

运行TestSelfService,并用adb shell logcat 查看日志,如下:

 

 

验证

 

查看日志发现报NullPointerException错误。仔细查看log,发现里面有如下错误代码:

12-07 10:32:13.795  2100  2100 E SelfManager: %%%%%%%%%%%%% SelfManager NEW %%%%%%%%%%%%%%%%
12-07 10:32:13.795  2100  2100 D SelfManager: SelfManager constructor called begin*********************
12-07 10:32:13.795  2100  2100 D SelfManager: SelfManager constructor called end**********************
12-07 10:32:13.795  2100  2100 D SelfManager: SelfManager fuzhi is null...error...........
12-07 10:32:13.795  2100  2100 D SelfManager: SelfManager  selfAddNumber ......... 
12-07 10:32:13.795  2100  2100 E SelfService: self manager invoke method get exception, msg:Attempt to invoke interface method 'int android.os.ISelfManager.selfAddNumber(int, int)' on a null object reference

 

 

根据log查看代码发现selfservice服务已经加入到systemserver中。且获取SelfManager服务时正常的。但执行的时候报错了。

仔细查看详细日志,发现里面存在以下与 self 有关的log,如下:

SELinux : avc:  denied  { find } for service=self

 

 

说明是SELinux权限问题。跟代码无关。接下来需要打开权限,或者关闭SELinux。使用adb shell 命令查看和设置SELinux模式。执行如下命令:

adb shell getenforce    // 获取SELinux的模式(enforcing, permissive)

 结果如下:

 

可以看到SELinuxEnforcing模式。用以下命令切换模式:

setenforce 1    // 设置SELinux 成为enforcing模式
setenforce 0    // 设置SELinux 成为permissive模式 

结果如下:

 

 

经过验证,设置成permissive模式后, 可以运行正常了。结果如下:

 

 

OK,到此为止,在Android 7.1.1中添加自定义系统服务SelfService就完成了。

 

 

以上测试代码及APK(apk在工程app/release目录下面)我放到github上,有需求的可以自己下载,地址如下:

https://github.com/sk569437/TestSelfService.git

 

 

 

参考:

        https://blog.csdn.net/mockingbirds/article/details/54382072

 

 

  • 8
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值