亚欧色一区w666天堂,色情一区二区三区免费看,少妇特黄A片一区二区三区,亚洲人成网站999久久久综合,国产av熟女一区二区三区

  • 發布文章
  • 消息中心
點贊
收藏
評論
分享
原創

最簡單的Binder調用

2023-05-29 02:06:49
176
0

Android提供簡單的binder服務測試命令service(代碼), 比如說要打開或者關閉畫面更新閃爍,可以發送指令:

# 打開
adb shell service call SurfaceFlinger 1002 i32 1

#關閉
adb shell service call SurfaceFlinger 1002 i32 0

其中,SurfaceFlinger是服務名稱,1002是需要調用的函數id, i32 1 表示寫一個32-bit integer為1的參數。

一,CPP的最簡單調用

下面是提取了service.cpp的代碼寫的最簡短的畫面更新閃爍調用:

#define LOG_TAG "simplest_call"

#include <utils/Log.h>
#include <binder/TextOutput.h>
#include <binder/IInterface.h>
#include <binder/IBinder.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>

using namespace android;

int main() {
    sp<IServiceManager> sm = defaultServiceManager();
    sp<IBinder> service = sm->checkService(String16("SurfaceFlinger"));
    String16 ifName("android.ui.ISurfaceComposer");
    if (service != nullptr && ifName.size() > 0) {
        Parcel data, reply;
        // the interface name is first
        data.writeInterfaceToken(ifName);
        data.writeInt32(1);
        service->transact(1002, data, &reply);
        aout << "Result: " << reply << endl;
    }
}

上面代碼實現的就是adb shell service call SurfaceFlinger 1002 i32 1命令的功能,通過IServiceManager獲取SurfaceFlinger服務,然后通過IServiceManager調用對應函數,其中Binder InterfaceToken "android.ui.ISurfaceComposer"也可以通過以下函數獲取:

static String16 get_interface_name(sp<IBinder> service)
{
    if (service != nullptr) {
        Parcel data, reply;
        status_t err = service->transact(IBinder::INTERFACE_TRANSACTION, data, &reply);
        if (err == NO_ERROR) {
            return reply.readString16();
        }
    }
    return String16();
}
String16 ifName = get_interface_name(service);

二,JAVA的最簡單調用

java的調用方式和cpp的基本一致,只是java的ServiceManager和cpp中的IServiceManager的最終調用并不一樣,java最終還是需要在native cpp中去操作binder內核,但使用的是libbinder.so中的方法。

package simplestcall;

import android.os.Bundle;
import android.os.IBinder;
import android.os.Parcel;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.Log;

public class Main {
    private static final String TAG = "SimplestCall";

    public static void main(String[] args) {
        IBinder service = ServiceManager.getService("SurfaceFlinger");
        final Parcel data = Parcel.obtain();
        final Parcel reply = Parcel.obtain();
        data.writeInterfaceToken("android.ui.ISurfaceComposer");
        data.writeInt(1);
        try {
            service.transact(1002, data, reply, 0 /* flags */);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        System.out.println(reply.toString());
        reply.recycle();
        data.recycle();
    }
}

三,更直接的方式

上面的Demo都用到了系統提供的ServiceManager, ServerManager本身也是一個binder服務,是否有方法可以直接獲取呢,在Android 11之前,AOSP在測試類bctest.c(代碼)上提供了svcmgr_lookup方法,通過binder_call方法直接操作binder節點獲取包括ServerManager在內的所有系統服務。

uint32_t svcmgr_lookup(struct binder_state *bs, uint32_t target, const char *name)
{
    uint32_t handle;
    unsigned iodata[512/4];
    struct binder_io msg, reply;

    bio_init(&msg, iodata, sizeof(iodata), 4);
    bio_put_uint32(&msg, 0);  // strict mode header
    bio_put_string16_x(&msg, SVC_MGR_NAME);
    bio_put_string16_x(&msg, name);

    if (binder_call(bs, &msg, &reply, target, SVC_MGR_CHECK_SERVICE))
        return 0;

    handle = bio_get_ref(&reply);

    if (handle)
        binder_acquire(bs, handle);

    binder_done(bs, &msg, &reply);

    return handle;
}

在此基礎上,我們就可以增加一個直接調用SurfaceFlinger服務獲取的方法, 實現前面demo中一樣的功能。

void simple_call_sf(struct binder_state *bs)
{
    uint32_t handle;
    unsigned iodata[512/4];
    struct binder_io msg, reply;

    bio_init(&msg, iodata, sizeof(iodata), 4);
    bio_put_uint32(&msg, 0);  // strict mode header

    bio_put_string16_x(&msg, "android.ui.ISurfaceComposer");
    bio_put_uint32(&msg, 1);
    handle = svcmgr_lookup(bs, BINDER_SERVICE_MANAGER, "SurfaceFlinger");
    if (binder_call(bs, &msg, &reply, handle, 1002 /*SHOW_UPDATES*/))
        return ;

    binder_done(bs, &msg, &reply);
}

參考資料

Gityuan-徹底理解Android Binder通信架構

0條評論
0 / 1000
h****n
13文章數
0粉絲數
h****n
13 文章 | 0 粉絲
原創

最簡單的Binder調用

2023-05-29 02:06:49
176
0

Android提供簡單的binder服務測試命令service(代碼), 比如說要打開或者關閉畫面更新閃爍,可以發送指令:

# 打開
adb shell service call SurfaceFlinger 1002 i32 1

#關閉
adb shell service call SurfaceFlinger 1002 i32 0

其中,SurfaceFlinger是服務名稱,1002是需要調用的函數id, i32 1 表示寫一個32-bit integer為1的參數。

一,CPP的最簡單調用

下面是提取了service.cpp的代碼寫的最簡短的畫面更新閃爍調用:

#define LOG_TAG "simplest_call"

#include <utils/Log.h>
#include <binder/TextOutput.h>
#include <binder/IInterface.h>
#include <binder/IBinder.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>

using namespace android;

int main() {
    sp<IServiceManager> sm = defaultServiceManager();
    sp<IBinder> service = sm->checkService(String16("SurfaceFlinger"));
    String16 ifName("android.ui.ISurfaceComposer");
    if (service != nullptr && ifName.size() > 0) {
        Parcel data, reply;
        // the interface name is first
        data.writeInterfaceToken(ifName);
        data.writeInt32(1);
        service->transact(1002, data, &reply);
        aout << "Result: " << reply << endl;
    }
}

上面代碼實現的就是adb shell service call SurfaceFlinger 1002 i32 1命令的功能,通過IServiceManager獲取SurfaceFlinger服務,然后通過IServiceManager調用對應函數,其中Binder InterfaceToken "android.ui.ISurfaceComposer"也可以通過以下函數獲取:

static String16 get_interface_name(sp<IBinder> service)
{
    if (service != nullptr) {
        Parcel data, reply;
        status_t err = service->transact(IBinder::INTERFACE_TRANSACTION, data, &reply);
        if (err == NO_ERROR) {
            return reply.readString16();
        }
    }
    return String16();
}
String16 ifName = get_interface_name(service);

二,JAVA的最簡單調用

java的調用方式和cpp的基本一致,只是java的ServiceManager和cpp中的IServiceManager的最終調用并不一樣,java最終還是需要在native cpp中去操作binder內核,但使用的是libbinder.so中的方法。

package simplestcall;

import android.os.Bundle;
import android.os.IBinder;
import android.os.Parcel;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.Log;

public class Main {
    private static final String TAG = "SimplestCall";

    public static void main(String[] args) {
        IBinder service = ServiceManager.getService("SurfaceFlinger");
        final Parcel data = Parcel.obtain();
        final Parcel reply = Parcel.obtain();
        data.writeInterfaceToken("android.ui.ISurfaceComposer");
        data.writeInt(1);
        try {
            service.transact(1002, data, reply, 0 /* flags */);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        System.out.println(reply.toString());
        reply.recycle();
        data.recycle();
    }
}

三,更直接的方式

上面的Demo都用到了系統提供的ServiceManager, ServerManager本身也是一個binder服務,是否有方法可以直接獲取呢,在Android 11之前,AOSP在測試類bctest.c(代碼)上提供了svcmgr_lookup方法,通過binder_call方法直接操作binder節點獲取包括ServerManager在內的所有系統服務。

uint32_t svcmgr_lookup(struct binder_state *bs, uint32_t target, const char *name)
{
    uint32_t handle;
    unsigned iodata[512/4];
    struct binder_io msg, reply;

    bio_init(&msg, iodata, sizeof(iodata), 4);
    bio_put_uint32(&msg, 0);  // strict mode header
    bio_put_string16_x(&msg, SVC_MGR_NAME);
    bio_put_string16_x(&msg, name);

    if (binder_call(bs, &msg, &reply, target, SVC_MGR_CHECK_SERVICE))
        return 0;

    handle = bio_get_ref(&reply);

    if (handle)
        binder_acquire(bs, handle);

    binder_done(bs, &msg, &reply);

    return handle;
}

在此基礎上,我們就可以增加一個直接調用SurfaceFlinger服務獲取的方法, 實現前面demo中一樣的功能。

void simple_call_sf(struct binder_state *bs)
{
    uint32_t handle;
    unsigned iodata[512/4];
    struct binder_io msg, reply;

    bio_init(&msg, iodata, sizeof(iodata), 4);
    bio_put_uint32(&msg, 0);  // strict mode header

    bio_put_string16_x(&msg, "android.ui.ISurfaceComposer");
    bio_put_uint32(&msg, 1);
    handle = svcmgr_lookup(bs, BINDER_SERVICE_MANAGER, "SurfaceFlinger");
    if (binder_call(bs, &msg, &reply, handle, 1002 /*SHOW_UPDATES*/))
        return ;

    binder_done(bs, &msg, &reply);
}

參考資料

Gityuan-徹底理解Android Binder通信架構

文章來自個人專欄
文章 | 訂閱
0條評論
0 / 1000
請輸入你的評論
0
0