为Android添加核心服务101

3/14/2018
Ref:https://wenku.baidu.com/view/5846922a647d27284b7351d5.html

起点:

  • Android 6.0源代码。
  • 不做任何改动时,可以顺利编译通过。
  • 编译得到的img文件,可以顺利地刷写到安卓中,测试正常。

第一步:服务实现

此步将新建native service并编译为so库

在源码目录中,新建一个目录frameworks/base/addservice/libaddservice,编写了3个文件,分别如下:

  • AddService.h
  • AddService.cpp
  • Android.mk

文件1:AddService.h

四点:

  1. 实例化 instantiate
  2. 构造函数AddService
  3. 析构函数~AddService
  4. onTransact
//AddService.h
#ifndef ANDROID_GUILH_ADD_SERVICE_H
#define ANDROID_GUILH_ADD_SERVICE_H

#include 
#include 
#include 
#include 

namespace android {
        class AddService:public BBinder {
                mutable Mutex mLock;
                int32_t mNextConnId;
                public:
                static int instantiate();
                AddService();
                virtual ~AddService();
                virtual status_t onTransact(uint32_t, const Parcel&, Parcel*, uint32_t);
        };
}; //namespace
#endif

文件2:AddService.cpp

把这四点具体实现:

  1. 实例化 instantiate
  2. 构造函数AddService
  3. 析构函数~AddService
  4. onTransact
//AddService.cpp
#include "AddService.h"
#include 
#include 

namespace android {

        static struct sigaction oldact;
        static pthread_key_t sigbuskey;

        int AddService::instantiate(){
                ALOGE("AddService instantiate");
                int r=defaultServiceManager()->addService(String16("guilh.add"), new AddService());
//上面这一行是把AddSerice这个服务添加到Binder Driver中,服务取名为   guilh.add
                ALOGE("AddService r = %d\n", r);
                return r;

        }

        AddService::AddService() { //构造函数
                ALOGV("AddService created");
                mNextConnId =1 ;
                pthread_key_create(&sigbuskey, NULL);
        }

        AddService::~AddService() { //析构函数
                pthread_key_delete(sigbuskey);
                ALOGV("AddService destroyed");
        }

//下面这个onTransact是服务具体的本地实现,功能实现都应该放在这里面,通过传入执行代码(code)的不同来执行不同的操作,上层映射为不同的API
        status_t AddService::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
                switch(code) {//根据code的不同执行不同的操作
                        case 0: {
                                pid_t pid=data.readInt32();
                                int num = data.readInt32();
                                num = num + 1000;
                                reply-> writeInt32(num);
                                return NO_ERROR;
                        }
                        break;
                        default:
                        return BBinder::onTransact(code, data, reply, flags);
                }
        }
}; //namespace

文件3:Android.mk

目的:指定源cpp文件;列出共享库;指定输出的so库文件名为libAdd.so

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
AddService.cpp

LOCAL_C_INCLUDES := \
$(JNI_H_INCLUDE)

LOCAL_SHARED_LIBRARIES := \
        libcutils \
        libutils \
        libbinder \
        libandroid_runtime

LOCAL_PRELINK_MODULE := false

LOCAL_MODULE := libAdd

include $(BUILD_SHARED_LIBRARY) #这一行表示编译为动态库

编译

先要退回Android源码根目录,执行以下命令来设置好编译环境。

source build/envsetup.sh
lunch 15 //(对应15. full_espresso8890-eng, 按需更改)

然后回到刚才的目录,并执行mm:

cd frameworks/base/addservice/libaddservice
mm
mm -B //如果已经编译过,可以用此命令覆盖旧的文件
mma -B -j50 //编译当前文件夹,以及所有依赖(50为线程个数,按需更改)

编译成功。生成的so文件位于:

out/target/product/espresso8890/system/lib/libAdd.so

第二步:服务进程实现

目的:把服务添加到Binder闭合循环进程(Binder Driver)中

在源码中新建一个目录:

frameworks/base/addservice/addserver

编写2个文件:

  • addserver.cpp
  • Android.mk

文件1:addserver.cpp

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include "../libaddservice/AddService.h"
//#include 

using namespace android;

int main(int argc, char** argv) {
        printf("ServiceManager Started!!!\n");
        sp proc(ProcessState::self());
        sp sm= defaultServiceManager();
        ALOGI("ServiceManager: %p", sm.get());
        printf("ServiceManager: %p\n", sm.get());
        AddService::instantiate();
        printf("instatiated! \n");

        ProcessState::self()->startThreadPool();
        //下面这一行是把服务添加到Binder闭合循环进程中
        IPCThreadState::self()->joinThreadPool();
}

以上为底层服务的标准操作。

文件2:Android.mk

  • 指定cpp文件
  • 指定要使用的共享库
  • 定义生成的程序的名称:addserver (倒数第2行)
  • 编译为可执行文件
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_LDLIBS := -L$(SYSROOT)/lib -llog

LOCAL_SRC_FILES := \
addserver.cpp

LOCAL_SHARED_LIBRARIES := \
libAdd \
libutils \
libbinder

LOCAL_MODULE := addserver

include $(BUILD_EXECUTABLE)

编译

在当前目录中执行:

mm

编译成功,得到的可执行文件addserver位于:

out/target/product/espresso8890/system/bin/addserver

第三步:真机测试

把以上得到的so库可执行文件手工复制到安卓设备上进行测试。

  1. 使用adb push命令,把so库文件拷贝到/system/lib64中(如果是32位so文件则放在/system/lib中)
  2. 使用adb push命令,把可执行文件addserver拷贝到/system/bin
  3. 然后手动执行此命令。
    3.1 如果执行命令时,使用的是cd /system/bin然后./addserver,在用top检查时,会看到./addserver这个进程。
    3.2 如果执行命令时,使用的是/system/bin/addserver,在用top检查时,会看到/system/bin/addserver这个进程。

>>>>>>>>>>>>>>>> 以下为可选步骤 <<<<<<<<<<<<<<<<

第四步:修改init.rc文件让服务开机启动

在源码的android/system/core/rootdir/目录下,修改init.rc文件,让addserver这个程序可以在开机时自动启动。

service addservice /system/bin/addserver
        class core
        group root system

第五步:安卓全编译

回到源码根目录,执行make -j50进行全编译。编译成功后的镜像文件位于out/target/product/espresso8890/boot.img

...
Installed file list: out/target/product/espresso8890/installed-files.txt
Target system fs image: out/target/product/espresso8890/obj/PACKAGING/systemimage_intermediates/system.img
Running:  mkuserimg.sh -s out/target/product/espresso8890/system out/target/product/espresso8890/obj/PACKAGING/systemimage_intermediates/system.img ext4 system 2097152000 -D out/target/product/espresso8890/system -L system out/target/product/espresso8890/root/file_contexts
make_ext4fs -s -T -1 -S out/target/product/espresso8890/root/file_contexts -L system -l 2097152000 -a system out/target/product/espresso8890/obj/PACKAGING/systemimage_intermediates/system.img out/target/product/espresso8890/system out/target/product/espresso8890/system
Creating filesystem with parameters:
    Size: 2097152000
    Block size: 4096
    Blocks per group: 32768
    Inodes per group: 8000
    Inode size: 256
    Journal blocks: 8000
    Label: system
    Blocks: 512000
    Block groups: 16
    Reserved block group size: 127
Created filesystem with 1873/128000 inodes and 173299/512000 blocks
Install system fs image: out/target/product/espresso8890/system.img
out/target/product/espresso8890/system.img+out/target/product/espresso8890/obj/PACKAGING/recovery_patch_intermediates/recovery_from_boot.p maxsize=2141061120 blocksize=4224 total=677120414 reserve=21626880

#### make completed successfully (02:36 (mm:ss)) ####

第六步:验证

  • 将安卓开发板启动到fastboot模式
  • fastboot flash boot boot.img命令,将boot.img这个镜像写入到安卓开发板。
  • 刷写成功后,重启开发板。
  • Android正常启动
  • 启动完成后,通过adb shell进入开发板,执行top |grep addserver命令。
  • 此时应该能看到一个/system/bin/addserver的进程!
130|root@espresso8890:/ # top | grep addserver                                  
 3820  4   0% S     2  56084K  19944K  fg root     /system/bin/addserver

你可能感兴趣的:(为Android添加核心服务101)