跳转至

aosp原生Service快捷扩展接口

背景

想在 aosp 原生 Service 提供新的功能给 APP 使用,但又不想改动 aidl 文件以及 manager 文件。 也就是说想尽量少改代码的方式实现新功能。基于这样的大前提下可以通过 onTransact() 接口去实现。 对 binder 了解的都知道,每个 binder 对象里的 Stub 会有一个 onTransact() 接口用来 ipc 的;并且区分每个接口是通过 transact code 来区分。

我们以 WindowManagerService 为例。

Service

在 WindowManagerService 中:

public boolean onTransact(int code, Parcel data, Parcel reply, int flags)  
        throws RemoteException {  
    try {  
        if (code == 100001) {
            Log.d(TAG, "onTransact(solo-debug) called with: code = [" + code + "], data = [" + data + "], reply = [" + reply + "], flags = [" + flags + "]");  
            return true;  
        }  

        return super.onTransact(code, data, reply, flags);  
    } catch (RuntimeException e) {  
        // The window manager only throws security exceptions, so let's  
        // log all others.        if (!(e instanceof SecurityException)) {  
            ProtoLog.wtf(WM_ERROR, "Window Manager Crash %s", e);  
        }  
        throw e;  
    }  
}

APP

Parcel data = Parcel.obtain();  
Parcel reply = Parcel.obtain();  
try {  
    IBinder binder = ServiceManager.getService(Context.WINDOW_SERVICE);  
    if (binder != null) {  
        data.writeInterfaceToken("android.view.IWindowManager");  
        data.writeInt(11);  
        data.writeInt(22);  
        data.writeString("test");  
        binder.transact(100001, data, reply, 0);  
    }  
} catch (Exception e) {  
    Log.e(TAG, "solo-debug transact failed = "+ e);  
} finally {  
    data.recycle();  
    reply.recycle();  
}

执行后输出的log如下,说明这个方案是可行的。

11-29 08:27:07.139  2414  4145 D WindowManager: onTransact(solo-debug) called with: code = [100001], data = [android.os.Parcel@cc9491b], reply = [android.os.Parcel@bdc8ab8], flags = [0]                            

这个方案在 SurfaceFlinger 中经常用到。

评论