国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Android 13添加自定義native服務(wù)

這篇具有很好參考價(jià)值的文章主要介紹了Android 13添加自定義native服務(wù)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

歡迎加入我的知識(shí)星球Android系統(tǒng)開發(fā)指南

歡迎關(guān)注微信公眾號(hào) 無限無羨
歡迎關(guān)注知乎賬號(hào) 無限無羨

native服務(wù)添加

native服務(wù)就是用c++寫的系統(tǒng)服務(wù),通過init進(jìn)程啟動(dòng),可以實(shí)現(xiàn)binder接口供client調(diào)用。
下面我們以實(shí)現(xiàn)一個(gè)beanserver的后臺(tái)服務(wù)為例:

  1. 首先需要寫一個(gè)rc文件
// 文件路徑根據(jù)自己需求放置
// vendor/zzh/native-service/bean-server/beanserver.rc
service beanserver /system/bin/beanserver
    class main
  1. 寫服務(wù)的main函數(shù)
// vendor/zzh/native-service/bean-server/main_beanserver.cpp
#define LOG_TAG "beanserver"
//#define LOG_NDEBUG 0

#include <hidl/HidlTransportSupport.h>
using namespace android;


int main(int argc __unused, char** argv __unused)
{
    ALOGD(" beamserver start......");
    return 0;
}

這個(gè)服務(wù)我們啟動(dòng)后只是打印了一行日志就退出了,具體可以根據(jù)自己的需求加入自己開機(jī)處理的業(yè)務(wù)。

  1. 編寫Android.bp
cc_binary {
	// 最終會(huì)生成到/system/bin/beanserver
    name: "beanserver",

    srcs: ["main_beanserver.cpp"],

    header_libs: [
    ],

    shared_libs: [
        "liblog",
        "libutils",
        "libui",
        "libgui",
        "libbinder",
        "libhidlbase",
    ],
    compile_multilib: "first",
    cflags: [
        "-Wall",
        "-Wextra",
        "-Werror",
        "-Wno-unused-parameter",
    ],
	// 最終會(huì)生成到/system/etc/init/beanserver.rc
	// init進(jìn)程啟動(dòng)時(shí)會(huì)解析/system/etc/init/目錄下的rc文件
    init_rc: ["beanserver.rc"],

    vintf_fragments: [
    ],
}

beanserver.rc在經(jīng)過編譯后會(huì)生成到/system/etc/init/beanserver.rc,然后init進(jìn)程啟動(dòng)的時(shí)候就會(huì)解析該文件啟動(dòng)進(jìn)程。

native空間的的服務(wù)在哪里定義,Android系統(tǒng)開發(fā),android,java,開發(fā)語言

init進(jìn)程解析/system/etc/init/的代碼

// system/core/init/init.cpp
// 可以看到init會(huì)解析多個(gè)目錄下的rc文件
static void LoadBootScripts(ActionManager& action_manager, ServiceList& service_list) {
    Parser parser = CreateParser(action_manager, service_list);

    std::string bootscript = GetProperty("ro.boot.init_rc", "");
    if (bootscript.empty()) {
        parser.ParseConfig("/system/etc/init/hw/init.rc");
        if (!parser.ParseConfig("/system/etc/init")) {
            late_import_paths.emplace_back("/system/etc/init");
        }
        // late_import is available only in Q and earlier release. As we don't
        // have system_ext in those versions, skip late_import for system_ext.
        parser.ParseConfig("/system_ext/etc/init");
        if (!parser.ParseConfig("/vendor/etc/init")) {
            late_import_paths.emplace_back("/vendor/etc/init");
        }
        if (!parser.ParseConfig("/odm/etc/init")) {
            late_import_paths.emplace_back("/odm/etc/init");
        }
        if (!parser.ParseConfig("/product/etc/init")) {
            late_import_paths.emplace_back("/product/etc/init");
        }
    } else {
        parser.ParseConfig(bootscript);
    }
}
  1. 加到編譯鏡像環(huán)境
// device/generic/car/emulator/aosp_car_emulator.mk
// 找到自己項(xiàng)目的mk文件加入
PRODUCT_PACKAGES += beanserver

這樣才會(huì)將beanserver編譯到鏡像中。

  1. 編譯鏡像驗(yàn)證
    編譯完啟動(dòng)時(shí)看到有如下報(bào)錯(cuò)日志:
03-29 07:13:38.364     0     0 I init    : Parsing file /system/etc/init/beanserver.rc...
03-29 07:13:41.706     0     0 E init    : Could not start service 'beanserver' as part of class 'core': File /system/bin/beanserver(labeled "u:object_r:system_file:s0") has incorrect label or no domain transition from u:r:init:s0 to another SELinux domain defined. Have you configured your service correctly? https://source.android.com/security/selinux/device-policy#label_new_services_and_address_denials. Note: this error shows up even in permissive mode in order to make auditing denials possible.

提示缺少selinux權(quán)限配置,我們可以在Google官網(wǎng)看到label_new_services_and_address_denials

下面我們配置一下selinux權(quán)限

selinux權(quán)限配置

  1. 編寫自定義服務(wù)的te文件
// 我這里將新加的selinux配置放在了自己創(chuàng)建目錄中
// 注意文件的首尾保留一行空行
// vendor/zzh/sepolicy/vendor/beanserver.te

# beanserver
type beanserver, domain, coredomain;
type beanserver_exec, exec_type, file_type, system_file_type;

init_daemon_domain(beanserver)

  1. 編寫file_contexts文件
// vendor/zzh/sepolicy/vendor/file_contexts
// 注意文件的首尾保留一行空行

/system/bin/beanserver   u:object_r:beanserver_exec:s0

添加到sepolicy編譯規(guī)則

// device/generic/car/emulator/aosp_car_emulator.mk
BOARD_VENDOR_SEPOLICY_DIRS += vendor/zzh/sepolicy/vendor
  1. 編譯后啟動(dòng)模擬器
    這個(gè)時(shí)候能看到服務(wù)啟動(dòng)了,但是發(fā)現(xiàn)beanserver一直在重啟,日志如下:
    native空間的的服務(wù)在哪里定義,Android系統(tǒng)開發(fā),android,java,開發(fā)語言
    經(jīng)過排查發(fā)生這個(gè)現(xiàn)象的原因有兩個(gè):
    (1)我們的進(jìn)程啟動(dòng)后只是打印了一行日志就return 0退出了,通過查看init的代碼發(fā)現(xiàn),init進(jìn)程會(huì)通過signal 9去kill掉退出的進(jìn)程,這里總感覺有點(diǎn)矛盾,可能時(shí)init擔(dān)心進(jìn)程自己退出的不徹底,所以來個(gè)signal 9? init 里的代碼如下:
// system/core/init/sigchld_handler.cpp
static pid_t ReapOneProcess() {
    siginfo_t siginfo = {};
    // This returns a zombie pid or informs us that there are no zombies left to be reaped.
    // It does NOT reap the pid; that is done below.
    if (TEMP_FAILURE_RETRY(waitid(P_ALL, 0, &siginfo, WEXITED | WNOHANG | WNOWAIT)) != 0) {
        PLOG(ERROR) << "waitid failed";
        return 0;
    }

    auto pid = siginfo.si_pid;
    if (pid == 0) return 0;

    // At this point we know we have a zombie pid, so we use this scopeguard to reap the pid
    // whenever the function returns from this point forward.
    // We do NOT want to reap the zombie earlier as in Service::Reap(), we kill(-pid, ...) and we
    // want the pid to remain valid throughout that (and potentially future) usages.
    auto reaper = make_scope_guard([pid] { TEMP_FAILURE_RETRY(waitpid(pid, nullptr, WNOHANG)); });

    std::string name;
    std::string wait_string;
    Service* service = nullptr;

    if (SubcontextChildReap(pid)) {
        name = "Subcontext";
    } else {
        service = ServiceList::GetInstance().FindService(pid, &Service::pid);

        if (service) {
            name = StringPrintf("Service '%s' (pid %d)", service->name().c_str(), pid);
            if (service->flags() & SVC_EXEC) {
                auto exec_duration = boot_clock::now() - service->time_started();
                auto exec_duration_ms =
                    std::chrono::duration_cast<std::chrono::milliseconds>(exec_duration).count();
                wait_string = StringPrintf(" waiting took %f seconds", exec_duration_ms / 1000.0f);
            } else if (service->flags() & SVC_ONESHOT) {
                auto exec_duration = boot_clock::now() - service->time_started();
                auto exec_duration_ms =
                        std::chrono::duration_cast<std::chrono::milliseconds>(exec_duration)
                                .count();
                wait_string = StringPrintf(" oneshot service took %f seconds in background",
                                           exec_duration_ms / 1000.0f);
            }
        } else {
            name = StringPrintf("Untracked pid %d", pid);
        }
    }

	// beanserver退出后,si_code為CLD_EXITED
    if (siginfo.si_code == CLD_EXITED) {
        LOG(INFO) << name << " exited with status " << siginfo.si_status << wait_string;
    } else {
        LOG(INFO) << name << " received signal " << siginfo.si_status << wait_string;
    }

    if (!service) {
        LOG(INFO) << name << " did not have an associated service entry and will not be reaped";
        return pid;
    }

	// 這里將siginfo傳入Reap函數(shù)
    service->Reap(siginfo);

    if (service->flags() & SVC_TEMPORARY) {
        ServiceList::GetInstance().RemoveService(*service);
    }

    return pid;
}

void Service::Reap(const siginfo_t& siginfo) {
	// 如果沒有oneshot屬性或者設(shè)置了restart的屬性,則會(huì)調(diào)用SIGKILL殺掉進(jìn)程
	// 這里的oneshot和restart指的是rc文件里面的配置,我們的rc文件只聲明了class main
	// 如果沒有聲明oneshot屬性,則服務(wù)被殺后會(huì)重新啟動(dòng),如果配置了oneshot則只會(huì)啟動(dòng)一次
    if (!(flags_ & SVC_ONESHOT) || (flags_ & SVC_RESTART)) {
        KillProcessGroup(SIGKILL, false);
    } else {
        // Legacy behavior from ~2007 until Android R: this else branch did not exist and we did not
        // kill the process group in this case.
        if (SelinuxGetVendorAndroidVersion() >= __ANDROID_API_R__) {
            // The new behavior in Android R is to kill these process groups in all cases.  The
            // 'true' parameter instructions KillProcessGroup() to report a warning message where it
            // detects a difference in behavior has occurred.
            KillProcessGroup(SIGKILL, true);
        }
    }
    ...
}

為了保證服務(wù)不退出,我們先在main函數(shù)里加個(gè)死循環(huán)看下效果

int main(int argc __unused, char** argv __unused)
{
    ALOGD(" beamserver start......");

    while (true) {
        sleep(3);
        ALOGD("beanserver_thread...........");
    }

    return 0;
}

編譯后啟動(dòng)模擬器看下啟動(dòng)日志:

native空間的的服務(wù)在哪里定義,Android系統(tǒng)開發(fā),android,java,開發(fā)語言

可以看到目前服務(wù)已經(jīng)正常了,這個(gè)服務(wù)將一直在后臺(tái)運(yùn)行。
如果我們只想開機(jī)后執(zhí)行一些操作后退出,那也可以,我們修改下看看效果。
修改beanserver.rc文件:

service beanserver /system/bin/beanserver
    class main
    oneshot //只啟動(dòng)一次

修改main_beanserver.cpp文件:

#define LOG_TAG "beanserver"
//#define LOG_NDEBUG 0

#include <hidl/HidlTransportSupport.h>
using namespace android;


void quickSort(int arr[], int left, int right) {
    int i = left, j = right;
    int tmp;
    int pivot = arr[(left + right) / 2];

    /* partition */
    while (i <= j) {
        while (arr[i] < pivot)
            i++;
        while (arr[j] > pivot)
            j--;
        if (i <= j) {
            tmp = arr[i];
            arr[i] = arr[j];
            arr[j] = tmp;
            i++;
            j--;
        }
    };

    /* recursion */
    if (left < j)
        quickSort(arr, left, j);
    if (i < right)
        quickSort(arr, i, right);
}

int main(int argc __unused, char** argv __unused)
{
    ALOGD(" beamserver start...");

    int data[] = {9, 21, 3, 66, 100, 8, 36};
    quickSort(data, 0, 7);
    for (int i = 0; i < 7; i++) {
        ALOGD("data[%d]=%d", i, data[i]);
    }

    return 0;
}

將一組數(shù)據(jù)用快速排序進(jìn)行排序后輸出,然后服務(wù)退出,通過日志可以看到,服務(wù)退出后init發(fā)送了signal 9,到此服務(wù)進(jìn)程退出。

native空間的的服務(wù)在哪里定義,Android系統(tǒng)開發(fā),android,java,開發(fā)語言

通過binder訪問服務(wù)

先看下文件目錄:

如果想要被別的進(jìn)程調(diào)用,就需要實(shí)現(xiàn)binder接口,這樣才算是一個(gè)完整的系統(tǒng)服務(wù)。

  1. 定義aidl接口
// vendor/zzh/native-service/bean-server/libbeanservice/aidl/com/zzh/IBeanService.aidl
package com.zzh;

interface IBeanService {
    void sayHello();
}
  1. 加入Android.bp中進(jìn)行編譯
// vendor/zzh/native-service/bean-server/libbeanservice/Android.bp
cc_library_shared {
    name: "libbeanservice_aidl",

    aidl: {
        export_aidl_headers: true,
        local_include_dirs: ["aidl"],
        include_dirs: [
        ],
    },

    srcs: [
        ":beanservice_aidl",
    ],

    shared_libs: [
        "libbase",
        "libcutils",
        "libutils",
        "liblog",
        "libbinder",
        "libgui",
    ],


    cflags: [
        "-Werror",
        "-Wall",
        "-Wextra",
    ],
}

filegroup {
    name: "beanservice_aidl",
    srcs: [
        "aidl/com/zzh/IBeanService.aidl",
    ],
    path: "aidl",
}

make libbeanservice_aidl 后可以看到out下生成的文件:
IBeanService.cpp
IBeanService.h
BpBeanService.h
BnBeanService.h

native空間的的服務(wù)在哪里定義,Android系統(tǒng)開發(fā),android,java,開發(fā)語言

  1. 實(shí)現(xiàn)服務(wù),繼承BnBeanService
    BeanService.h
// vendor/zzh/native-service/bean-server/libbeanservice/BeanService.h

#ifndef BEANSERVICE_H
#define BEANSERVICE_H

#include <com/zzh/BnBeanService.h>
#include <binder/BinderService.h>

namespace android {

class BeanService:
    public BinderService<BeanService>,
    public virtual ::com::zzh::BnBeanService,
    public virtual IBinder::DeathRecipient
{
public:
    // Implementation of BinderService<T>
    static char const* getServiceName() { return "bean.like"; }

    // IBinder::DeathRecipient implementation
    virtual void        binderDied(const wp<IBinder> &who);
    
    BeanService();
    ~BeanService();
    virtual binder::Status  sayHello();
};

}

#endif

這里BeanService繼承了BinderService,必須重寫getServiceName函數(shù)用來返回服務(wù)的名稱,后續(xù)注冊(cè)服務(wù)時(shí)會(huì)用到這個(gè)名字。

BeanService.cpp

// vendor/zzh/native-service/bean-server/libbeanservice/BeanService.cpp
#define LOG_TAG "BeanService"
//#define LOG_NDEBUG 0

#include "BeanService.h"
#include <iostream>

namespace android {

using binder::Status;

BeanService::BeanService() {

}

BeanService::~BeanService() {

}

/*virtual*/void BeanService::binderDied(const wp<IBinder> &who) {
    ALOGE("%s: Java client's binder died, removing it from the list of active clients, who=%p",
            __FUNCTION__, &who);
}

Status BeanService::sayHello() {
    ALOGD(" BeanService::sayHello ");
    return Status::ok();
}

}

Android.bp

// vendor/zzh/native-service/bean-server/libbeanservice/Android.bp
cc_library_shared {
    name: "libbeanservice",

    srcs: [
        "BeanService.cpp",
    ],

    header_libs: [
    ],

    shared_libs: [
        "libbeanservice_aidl",
        "libbase",
        "libui",
        "liblog",
        "libutils",
        "libbinder",
        "libcutils",
    ],

    static_libs: [
    ],

    include_dirs: [
    ],

    export_shared_lib_headers: [
        "libbinder",
        "libbeanservice_aidl",
    ],

    export_include_dirs: ["."],

    cflags: [
        "-Wall",
        "-Wextra",
        "-Werror",
        "-Wno-ignored-qualifiers",
    ],

}

cc_library_shared {
    name: "libbeanservice_aidl",

    aidl: {
        export_aidl_headers: true,
        local_include_dirs: ["aidl"],
        include_dirs: [
        ],
    },

    srcs: [
        ":beanservice_aidl",
    ],

    shared_libs: [
        "libbase",
        "libcutils",
        "libutils",
        "liblog",
        "libbinder",
        "libgui",
    ],


    cflags: [
        "-Werror",
        "-Wall",
        "-Wextra",
    ],
}

filegroup {
    name: "beanservice_aidl",
    srcs: [
        "aidl/com/zzh/IBeanService.aidl",
    ],
    path: "aidl",
}
  1. 注冊(cè)服務(wù)
// vendor/zzh/native-service/bean-server/main_beanserver.cpp
#define LOG_TAG "beanserver"
//#define LOG_NDEBUG 0

#include "BeanService.h"
#include <hidl/HidlTransportSupport.h>
using namespace android;


int main(int argc __unused, char** argv __unused)
{
    ALOGD(" beamserver start...");
    signal(SIGPIPE, SIG_IGN);

    // Set 5 threads for HIDL calls. Now cameraserver will serve HIDL calls in
    // addition to consuming them from the Camera HAL as well.
    hardware::configureRpcThreadpool(5, /*willjoin*/ false);

    sp<ProcessState> proc(ProcessState::self());
    sp<IServiceManager> sm = defaultServiceManager();
    ALOGI("ServiceManager: %p", sm.get());
    BeanService::instantiate();
    ALOGI("ServiceManager: %p done instantiate", sm.get());
    ProcessState::self()->startThreadPool();
    IPCThreadState::self()->joinThreadPool();
}

BeanService::instantiate()這個(gè)函數(shù)會(huì)調(diào)用父類BinderService的方法,最終會(huì)調(diào)用publish方法進(jìn)行服務(wù)注冊(cè)。

template<typename SERVICE>
class BinderService
{
public:
	// 進(jìn)行服務(wù)注冊(cè)的方法,被instantiate()調(diào)用
    static status_t publish(bool allowIsolated = false,
                            int dumpFlags = IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT) {
        sp<IServiceManager> sm(defaultServiceManager());
        // 這里進(jìn)行服務(wù)注冊(cè),SERVICE::getServiceName()這個(gè)就是BeanService重寫的方法,返回"bean.like"
        return sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated,
                              dumpFlags);
    }

    static void publishAndJoinThreadPool(
            bool allowIsolated = false,
            int dumpFlags = IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT) {
        publish(allowIsolated, dumpFlags);
        joinThreadPool();
    }

	// 調(diào)用publish()方法
    static void instantiate() { publish(); }

    static status_t shutdown() { return NO_ERROR; }
   ...
}
  1. 編譯后啟動(dòng)模擬器,看日志:

native空間的的服務(wù)在哪里定義,Android系統(tǒng)開發(fā),android,java,開發(fā)語言

接下來根據(jù)提示配置selinux權(quán)限
adb pull /sys/fs/selinux/policy
adb logcat -b events -d | audit2allow -p policy
輸出信息如下:

#============= beanserver ==============
allow beanserver servicemanager:binder call;

#============= hal_audio_caremu ==============
allow hal_audio_caremu audioserver:fifo_file write;
allow hal_audio_caremu default_prop:file read;

#============= init ==============
allow init vendor_toolbox_exec:file execute_no_trans;

我們將規(guī)則加入beanserver.te即可:
selinux一般情況下并不能一次加完,每次都是添加了log中所報(bào)的權(quán)限后,再次運(yùn)行時(shí)又會(huì)有新的權(quán)限錯(cuò)誤,我們按照上面的方法逐一添加即可,最終的te文件如下:

// vendor/zzh/sepolicy/vendor/beanserver.te

# beanserver
type beanserver, domain, coredomain;
type beanserver_exec, exec_type, file_type, system_file_type;

init_daemon_domain(beanserver)

allow beanserver servicemanager:binder { call transfer };
allow beanserver beanserver_service:service_manager add;

除了上述修改外,還需要做如下修改:

// vendor/zzh/sepolicy/public/service.te
type beanserver_service,       service_manager_type;
// vendor/zzh/sepolicy/private/service_contexts
bean.like                             u:object_r:beanserver_service:s0
// device/generic/car/emulator/aosp_car_emulator.mk
SYSTEM_EXT_PUBLIC_SEPOLICY_DIRS += vendor/zzh/sepolicy/public
SYSTEM_EXT_PRIVATE_SEPOLICY_DIRS += vendor/zzh/sepolicy/private

簡單解釋一下,我們需要為定義的服務(wù)定義一個(gè)標(biāo)簽,ServiceManager執(zhí)行addService操作時(shí)會(huì)進(jìn)行檢查,如果不定義標(biāo)簽的話會(huì)使用默認(rèn)的default_android_service,但Selinux是不允許以這個(gè)標(biāo)簽add service的。

// system/sepolicy/public/domain.te
# Do not allow service_manager add for default service labels.
# Instead domains should use a more specific type such as
# system_app_service rather than the generic type.
# New service_types are defined in {,hw,vnd}service.te and new mappings
# from service name to service_type are defined in {,hw,vnd}service_contexts.
neverallow * default_android_service:service_manager *;
neverallow * default_android_vndservice:service_manager *;
neverallow * default_android_hwservice:hwservice_manager *;

再次編譯啟動(dòng)模擬器:

native空間的的服務(wù)在哪里定義,Android系統(tǒng)開發(fā),android,java,開發(fā)語言
native空間的的服務(wù)在哪里定義,Android系統(tǒng)開發(fā),android,java,開發(fā)語言

到此,我們的服務(wù)已經(jīng)成功的添加到ServiceManager中。

  1. Client通過binder訪問服務(wù)

我們寫一個(gè)demo進(jìn)行訪問服務(wù)
測(cè)試文件:

// vendor/zzh/native-service/bean-server/client/BeanServer_client_test.cpp
#define LOG_TAG "beanclient"
//#define LOG_NDEBUG 0
#include <com/zzh/IBeanService.h>
#include <binder/IServiceManager.h>

using namespace android;
using com::zzh::IBeanService;


int main(int argc __unused, char** argv __unused) {

    ALOGD(" beanclient start...");  
    // 先獲取IServiceManager
    sp<IServiceManager> sm = defaultServiceManager(); 
    sp<IBinder> binder;
    do {
    	// 通過服務(wù)名稱拿到代理對(duì)象
        binder = sm->getService(String16("bean.like"));
        if (binder != 0) {
            break;
        }
        usleep(500000); // 0.5s
    } while (true);
	// 轉(zhuǎn)換成IBeanService
    sp<IBeanService>   beanService = interface_cast<IBeanService>(binder);
    // 通過代理調(diào)用服務(wù)端函數(shù)
    beanService->sayHello();
    
    return 0;
}

Android.bp

// vendor/zzh/native-service/bean-server/client/Android.bp
cc_binary {
    name: "beanserver_client",

    srcs: ["BeanServer_client_test.cpp"],

    cflags: [
        "-Wall",
        "-Wextra",
        "-Werror",
        "-Wno-unused-parameter",
    ],

    compile_multilib: "first",

    shared_libs: [
        "libbeanservice_aidl",
        "libbase",
        "libcutils",
        "libutils",
        "liblog",
        "libbinder",
        "libgui",
    ],

    include_dirs: ["."],
}

編譯到系統(tǒng)目錄

// device/generic/car/emulator/aosp_car_emulator.mk
PRODUCT_PACKAGES += beanserver_client

也可以不加上面的編譯選項(xiàng),直接make beanserver_client,然后將生成的產(chǎn)物adb push到系統(tǒng)目錄也可以。

啟動(dòng)模擬器,在終端執(zhí)行beanserver_client,查看日志:

native空間的的服務(wù)在哪里定義,Android系統(tǒng)開發(fā),android,java,開發(fā)語言

可以看出是不允許shell訪問beanserver服務(wù),這里在實(shí)際業(yè)務(wù)中要對(duì)client端配置selinux,由于我們這里是測(cè)試,就不贅述了。直接setenforce 0進(jìn)行測(cè)試

su
setenforce  0

然后再重新執(zhí)行beanservere_client

native空間的的服務(wù)在哪里定義,Android系統(tǒng)開發(fā),android,java,開發(fā)語言

調(diào)用成功!

為了方便大家清晰的理解代碼結(jié)果,下面列出了本例中的代碼目錄:

zzh@ubuntu:~/work/android/aosp/android-13.0.0_r35/vendor/zzh$ tree
.
├── native-service
│   └── bean-server
│       ├── Android.bp
│       ├── beanserver.rc
│       ├── client
│       │   ├── Android.bp
│       │   └── BeanServer_client_test.cpp
│       ├── libbeanservice
│       │   ├── aidl
│       │   │   └── com
│       │   │       └── zzh
│       │   │           └── IBeanService.aidl
│       │   ├── Android.bp
│       │   ├── BeanService.cpp
│       │   └── BeanService.h
│       └── main_beanserver.cpp
└── sepolicy
    ├── private
    │   └── service_contexts
    ├── public
    │   └── service.te
    └── vendor
        ├── beanserver.te
        └── file_contexts

11 directories, 13 files

上述文件我已經(jīng)整理好,大家想要的話可以關(guān)注我的微信公眾號(hào)無限無羨,回復(fù)"nt" 即可獲取,獲取后只需修改部分名稱,添加編譯選項(xiàng)到自己項(xiàng)目的配置文件即可。文章來源地址http://www.zghlxwxcb.cn/news/detail-652118.html

到了這里,關(guān)于Android 13添加自定義native服務(wù)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Android 14.0 添加自定義服務(wù),并生成jar給第三方app調(diào)用

    在14.0系統(tǒng)ROM產(chǎn)品定制化開發(fā)中,由于需要新增加自定義的功能,所以要增加自定義服務(wù),而app上層通過調(diào)用自定義服務(wù),來調(diào)用相應(yīng)的功能,所以系統(tǒng)需要先生成jar,然后生成jar 給上層app調(diào)用,接下來就來分析實(shí)現(xiàn)的步驟,然后來實(shí)現(xiàn)相關(guān)的功能 從而來實(shí)現(xiàn)所需要的功能 在

    2024年04月10日
    瀏覽(105)
  • WebService 客戶端增加Header頭、并且指定命名空間、添加攔截器(日志攔截器,自定義攔截器)、soap:Envelope 添加命名空間

    1.增加Header頭 生成XML結(jié)果如下 2.添加攔截器 3.soap:Envelope 添加命名空間 生成XML結(jié)果如下

    2024年02月10日
    瀏覽(28)
  • Android13系統(tǒng)導(dǎo)航欄添加隱藏導(dǎo)航欄功能按鈕

    Android13系統(tǒng)導(dǎo)航欄添加隱藏導(dǎo)航欄功能按鈕

    最近有個(gè)項(xiàng)目,客戶要求在底部導(dǎo)航欄中添加一個(gè)可以隱藏整個(gè)導(dǎo)航欄的功能按鈕,效果如下圖: 具體方法如下: 1. 在frameworks/base做如下修改: 2. 上面修改中有一行代碼android:src=\\\"@drawable/ic_sysbar_hide\\\"引用了一個(gè)ic_sysbar_hide.xml文件,該文件內(nèi)容如下:其實(shí)就是那個(gè)隱藏按鈕的

    2024年04月23日
    瀏覽(99)
  • android 13.0 添加系統(tǒng)字體并且設(shè)置為默認(rèn)字體

    在13.0系統(tǒng)定制化開發(fā)中,在產(chǎn)品定制中,有產(chǎn)品需求對(duì)于系統(tǒng)字體風(fēng)格不太滿意,所以想要更換系統(tǒng)的默認(rèn)字體,對(duì)于系統(tǒng)字體的修改也是常有的功能,而系統(tǒng)默認(rèn)也支持增加字體,所以就來添加楷體字體為系統(tǒng)字體,并替換為系統(tǒng)默認(rèn)字體, 接下來就來分析下替換默認(rèn)字

    2024年02月22日
    瀏覽(130)
  • android 13.0 SystemUI狀態(tài)欄下拉快捷添加截圖快捷開關(guān)

    在13.0的系統(tǒng)產(chǎn)品rom定制化開發(fā)中,對(duì)SystemUI的定制需求也是挺多的,在下拉狀態(tài)欄中 添加截圖快捷開關(guān),也是常有的開發(fā)功能,下面就以添加 截圖功能為例功能的實(shí)現(xiàn) 在Systemui的下拉狀態(tài)欄的相關(guān)源碼中,在快捷設(shè)置區(qū)域QSPanel及點(diǎn)擊事件流程 分析 SystemUI下拉之后的那些快捷

    2024年02月03日
    瀏覽(25)
  • Android 13(targetSdkVersion:33)必需添加com.google.android.gms.permission.AD_ID

    Android 13(targetSdkVersion:33)必需添加com.google.android.gms.permission.AD_ID

    關(guān)于這個(gè)問題個(gè)人覺得Google真有點(diǎn)變態(tài)。 大概的意思是:你要適配Android 13,必須將targetSdkVersion升至33,這都很正常;你必須添加com.google.android.gms.permission.AD_ID的權(quán)限獲取,OK,雖然不知道我的APP沒有廣告為何一定要我加這個(gè),你要加就加唄?。。〉儜B(tài)的是在提交新版本審核

    2024年02月11日
    瀏覽(21)
  • 【Android13開發(fā)WIFI添加頻段設(shè)置項(xiàng)(2.4G/5G/automatic)更改筆記】

    【Android13開發(fā)WIFI添加頻段設(shè)置項(xiàng)(2.4G/5G/automatic)更改筆記】

    提示:這里簡述項(xiàng)目相關(guān)背景: Android13中客戶需求添加WIFI頻段選項(xiàng): 2.4G only,只顯示鏈接2.4G的AP。 5G only,只能顯示和鏈接5G的AP。 Automatic:自動(dòng)顯示,即全部正常顯示。 提示:這里描述項(xiàng)目中遇到的問題: 作為初學(xué)者的我,剛開始接到這個(gè)bug,還是比較懵的,多虧了CSDN的前輩

    2024年02月05日
    瀏覽(21)
  • 【論文閱讀】Vision Mamba:雙向狀態(tài)空間模型的的高效視覺表示學(xué)習(xí)

    【論文閱讀】Vision Mamba:雙向狀態(tài)空間模型的的高效視覺表示學(xué)習(xí)

    論文地址: Vision Mamba 在這篇文章,我們展示對(duì)于視覺表示學(xué)習(xí),不再依賴自注意力,提出一個(gè)新的泛用的視覺backbone基于雙向Mamba塊,通過位置嵌入來標(biāo)示圖片序列,通過雙向狀態(tài)空間模型壓縮視覺表示。結(jié)果表示,Vim有能力解決在高分辨率圖片上應(yīng)用tranformer類型所導(dǎo)致計(jì)算

    2024年03月21日
    瀏覽(28)
  • 【Android Framework系列】第13章 SVG矢量圖形自定義組件(繪制中國地圖)

    【Android Framework系列】第13章 SVG矢量圖形自定義組件(繪制中國地圖)

    本章節(jié)我們來了解下什么是 SVG 矢量圖形,怎么通過 SVG 實(shí)現(xiàn)圖形的繪制,通過 SVG 實(shí)現(xiàn)不規(guī)則的自定義控件,項(xiàng)目實(shí)現(xiàn)一個(gè)中國地圖,實(shí)現(xiàn)每個(gè)省都能夠點(diǎn)擊,項(xiàng)目地址在文末請(qǐng)自取。 SVG 指可伸縮矢量圖形 (Scalable Vector Graphics) SVG 用來定義用于網(wǎng)絡(luò)的基于矢量的圖形 SVG 使用

    2024年02月10日
    瀏覽(25)
  • Android10.0 hal層添加自定義hal模塊功能實(shí)現(xiàn)

    在10.0的系統(tǒng)rom定制化開發(fā)中,在 對(duì)hal模塊進(jìn)行開發(fā)時(shí),需要通過添加自定義的hal模塊來實(shí)現(xiàn)某些 功能時(shí),就需要添加hal模塊的相關(guān)功能,接下來就來實(shí)現(xiàn)一個(gè)案例來供參考 HAL是硬件抽象層,它向下屏蔽了硬件的實(shí)現(xiàn)細(xì)節(jié),向上提供了抽象接口, HAL是底層硬件和上層框架直

    2024年02月15日
    瀏覽(24)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包