Android Framework 仿 WindowManager 添加系统服务

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/yichen97/article/details/90486487

引言

该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(转)

猜你喜欢

转载自blog.csdn.net/yichen97/article/details/90486487