android 编写系统服务,Android Framework 仿 WindowManager 添加系统服务

引言

该demo为基于Android P(9.0)。

根据原生WindowManager的调用方式,用AIDL跨进程通讯的方式实现。

?

1. IWindowManager.aidl

package android.os;

interface IWindowManager{

String selfAddString(String originalStr);

}

只是创建一个AIDL文件,然后定义要实现的方法。

?

2. Android.bp

srcs: [

// From build/make/core/pathmap.mk FRAMEWORK_BASE_SUBDIRS

"core/java/**/*.java",

"graphics/java/**/*.java",

"location/java/**/*.java",

"lowpan/java/**/*.java",

"media/java/**/*.java",

"media/mca/effect/java/**/*.java",

"media/mca/filterfw/java/**/*.java",

"media/mca/filterpacks/java/**/*.java",

"drm/java/**/*.java",

"opengl/java/**/*.java",

"sax/java/**/*.java",

"telecomm/java/**/*.java",

"telephony/java/**/*.java",

"wifi/java/**/*.java",

"keystore/java/**/*.java",

"rs/java/**/*.java",

":framework-javastream-protos",

"core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl",

"core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl",

"core/java/android/accounts/IAccountManager.aidl",

...

"core/java/android/os/IWindowManager.aidl"

...

],

我是在这个文件中将刚才的aidl文件添加进去,可以让它编进代码里去,使之生成Stub接口。

?

3. mm编译

更新完Android.bp之后,先在base目录下使用mm命令单编一次。

单编一次,正常情况下会生成一个Stub接口。如果不知到有没有生成所需要的东西,可以继续试着向下走,因为到第四步的时候会使用这个Stub接口,如果报错找不到,那就是没有生成啦。也可以使用一个比较笨的方法,将这个aidl放到编辑器中去编,比如说Android Studio,把编辑出来的东西拷出来就可以了。

?

4. WindowManagerService.java

package com.android.server;

import android.util.Log;

import android.os.IWindowManager;

public class WindowManagerService extends IWindowManager.Stub{

public String selfAddString(String originalStr){

return "suyichen" + originalStr;

}

}

这个类为真正的主体类,我们调用自己目前创建的系统服务所真正实现的地方,该类实现了之前定义的aidl方法。这里我就做一个字符串拼接然后返回该字符串。

?

5. WindowManager.java

package anroid.app;

import android.os.IWindowManager;

import android.os.RemoteException;

import android.content.Content;

public class WindowManager{

IWindowManager mWindowManager;

public WindowManager(Context content,IWindowManager windowManager){

mWindowManager = windowManager;

}

public String selfAddString(String originalStr) throws RemoteException{

return mWindowManager.selfAddString(originalStr);

}

}

这个类主要是用来管理WindowManagerService的,相当于是WindowManagerService对外的接口,这里不做其他操作。

?

6. Context.java

/** @hide */

@StringDef(suffix = { "_SERVICE" }, value = {

POWER_SERVICE,

WINDOW_SERVICE,

...

WINDOW_MANAGER_SERVICE

...

})

...

public static final String WINDOW_MANAGER_SERVICE = "windowmanager";

在上下文中添加一个标志,如果不添加这个,在以后的使用中直接写"windowmanager"也是可以的。

?

7. SystemServer.java

import com.android.server.WindowManagerService;

/**

* Starts a miscellaneous grab bag of stuff that has yet to be refactored

* and organized.

*/

private void startOtherServices() {

...

traceBeginAndSlog("StartWindowManagerService");

try{

ServiceManager.addService(Context.WINDOW_MANAGER_SERVICE,

new WindowManagerService());

}catch(Throwable e){

Slog.e(TAG,"Failure starting WindowManagerService",e);

}

}

将WindowManagerService添加在SystemService中。

?

8. SystemServiceRegistry.java

import android.os.IWindowManager;

static {

...

registerService(Context.WINDOW_MANAGER_SERVICE,WindowManager.class,new CachedServiceFetcher(){

@Override

public WindowManager createService(ContextImpl ctx) throws ServiceNotFoundException{

IBinder b = ServiceManager.getService(Context.WINDOW_MANAGER_SERVICE);

IWindowManager service = IWindowManager.Stub.asInterface(b);

return new WindowManager(ctx,service);

}

});

}

将添加的服务注册。

?

9. service.te

type window_manager_service, service_manager_type;

?

10.?service_contexts

位置一般与service.te在同一个上级目录。但service_contexts和service.te根据方案上的不同,目录是不同的,相MTK方案,这两个文件都存放在 /vendor/ 目录下。

windowmanager u:object_r:window_manager_service:s0

service_contexts和service.te两者都是与SELinux相关,不设置会导致之前的操作不生效。

?

11. make update-api

全部添加完毕后,回到p-base目录下,执行 "make update-api" 命令更新API。

更新完毕后,/frameworks/base/api/current.txt?文件会有改动,如果提patch的话,需要将该文件也提交。

到目前服务已经添加完毕了。

?

12. 验证

在任意一个位置执行代码:

try {

WindowManager windowManager = (WindowManager)getSystemService(Context.WINDOW_MANAGER_SERVICE);

String str = windowManager.selfAddString("suyichen");

}catch (RemoteException e){

Log.e(TAG,"Faile ...",e);

}

将str打印出来 ,如果是字符串拼接的,这说明服务的路子已经通了,在方法里自己需要的内容就行了。

?

参考文献

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值