Android Framework 仿 WindowManager 添加系统服务

    xiaoxiao2022-07-13  150

    引言

    该demo为基于Android P(9.0)。

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

     

    1. IWindowManager.aidl

    位置:/frameworks/base/core/java/android/os/IWindowManager.aidl

    package android.os; interface IWindowManager{ String selfAddString(String originalStr); }

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

     

    2. Android.bp

    位置:/frameworks/base/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

    位置:/frameworks/base/services/core/java/com/android/server/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

    位置:/frameworks/base/core/java/android/app/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

    位置:/frameworks/base/core/java/android/content/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

    位置:/frameworks/base/services/java/com/android/server/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

    位置:/frameworks/base/core/java/android/app/SystemServiceRegistry.java

    import android.os.IWindowManager; static { ... registerService(Context.WINDOW_MANAGER_SERVICE,WindowManager.class,new CachedServiceFetcher<WindowManager>(){ @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

    位置:/system/sepolicy/public/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打印出来 ,如果是字符串拼接的,这说明服务的路子已经通了,在方法里自己需要的内容就行了。

     

    参考文献

    Android framework层添加三方应用接口,及添加系统Service(转)

    最新回复(0)