准备工作
在正式开始之前,需要知道下面两点以及满足下面条件:
前提条件
Android原生代码,可以通过make全编通过,编译完成之后,可以通过emulator命令启动out目录下生成的image文件,需要注意在执行emulator命令之前,需要执行source build/envsetup.sh构建环境,以及lunch选择产品
1.定义ISelfManager.aidl文件
系统里面很多的aidl文件定义在/frameworks/base/core/Java/android/os下,所以我们需要做的就是参考其他的aidl,照样子写一个简单的ISelfManager.aidl
/frameworks/basecore/java/android/os/ISelfManager.aidl
package android.os;
interface ISelfManager {
int selfAddNumber(int numberFirst, int numberSecond);
String selfAddString(String originalStr);
}
2.更新Android.mk文件
在frameworks/base/Android.mk文件的LOCAL_SRC_FILES中系统添加了很多aidl文件,我们需要添加自己定义的ISelfManager.aidl文件
LOCAL_SRC_FILES += \
core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl \
core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl \
.....
core/java/android/os/ISelfManager.aidl \
然后使用mmm frameworks/base,此时会自动根据aidl文件生成对应的stub接口,其实这里没有生成也没有关系,我们可以自己将该文件添加到Android studio中,让ADT自动生成也可以,这里主要是方便后面编写实现类,没有太多的实际意义。
3.添加远端实现SelfManagerService.java
这里,我们没有特殊的需求就放在frameworks/base/services/core/java/com/android/server里
SelfManagerService.java
package com.android.server;
import android.util.Log;
import android.os.ISelfManager;
/**
* @hide
*/
public class SelfManagerService extends ISelfManager.Stub {
/**
* @hide
*/
public int read() {
int result = tngpio_read();
Slog.e("zhy", "read=" + result);
return result;
}
/**
* @hide
*/
public void write(char c) {
Log.e("zhy", "write:" + c);
tngpio_write(c);
}
private static native int tngpio_read();
private static native void tngpio_write(char c);
}
4.创建对应的SelfManager
/frameworks/base/core/java/android/app/SelfManager.java
package android.app;
import android.util.Log;
import android.os.ISelfManager;
import android.content.Context;
import android.os.RemoteException;
public class SelfManager {
private static String TAG = "SelfManager";
ISelfManager mSelfManager;
public SelfManager(Context ctx,ISelfManager selfManager) {
mSelfManager = selfManager;
}
public int read() throws RemoteException {
return mSelfManager.read();
}
public void write(char c) throws RemoteException {
mSelfManager.write(c);
}
}
5.管理和注册SelfManagerService
在开始之前,已经分析系统Service的注册流程,需要分别在SystemServer.java和SystemServiceRegistry.java中修改
- 在SystemServer.java中将SelfManagerService添加到ServiceManager中管理,这里我添加到了startOtherServices方法中
private void startOtherServices() {
....
ServiceManager.addService("selfservice", new SelfManagerService());
....
}
- 在SystemServiceRegistry.java中注册我们的SelfManagerService服务
import android.os.ISelfManager;
static {
....
registerService("selfservice", SelfManager.class,
new CachedServiceFetcher() {
@Override
public SelfManager createService(ContextImpl ctx) {
IBinder b = ServiceManager.getService("selfservice");
ISelfManager service = ISelfManager.Stub.asInterface(b);
return new SelfManager(ctx,service);
}});
....
}
这里的”selfservice”,一般来说需要在Context.java中声明,然后在这里引用。
6.更新service.te文件
service.te主要用来定义我们自己服务的类型,在/system/sepolicy/service.te目录下,不同厂商的定制可能导致该路径不同在该文件中已经定义了很多service类型,只需要照着画就行了。
type wifi_service, app_api_service, system_server_service, service_manager_type;
// 参照 wifi_service的定义添加自己的定义就行了
type selfservice, system_api_service, system_server_service, service_manager_type;
更新/system/sepolicy/service_contexts文件
selfservice u:object_r:system_server_service:s0
-
现在万事已经具备了.全编就可以了,需要注意, 在全编之前,需要更新当前系统的API
执行make update-api -j4,完成之后会生成自己添加的服务的API/frameworks/base/api/current.txt
完成之后,执行make命令全编就可以了,public class SelfManager { ctor public SelfManager(android.content.Context, android.os.ISelfManager); method public int selfAddNumber(int, int) throws android.os.RemoteException; method public java.lang.String
7.创建并且实现com_android_server_SelfManagerService.cpp
为什么需要它?因为我们的hal代码并没有提供jni的接口(这里提供了一种新的方法来提供native方法,之前是自动产生头文件然后来实现的)。
frameworks/base/services/core/jni/com_android_server_SelfManagerService.cpp
/* * Copyright (C) 2009 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define LOG_TAG "SelfManagerService" #include "jni.h" #include "JNIHelp.h" #include "android_runtime/AndroidRuntime.h" #include#include #include #include #include "JNIHelp.h" #include "jni.h" #include #include #include #include #include #include #include #include #include #include #include #include #include //方法在驱动中生成的节点 #define DEV_NAME "/dev/memdev" namespace android { static jint com_android_server_SelfManagerService_tngpio_read (JNIEnv* env, jobject clazz) { jint fd; fd = open(DEV_NAME, O_RDWR); //open 是jni提供的函数 char buffer[1] = {1}; jint result = read(fd, buffer, 1); return result; } static void com_android_server_SelfManagerService_tngpio_write (JNIEnv* env, jobject clazz, char c) { jint fd; char buffer[1] = {c}; fd = open(DEV_NAME, O_RDWR); write(fd, buffer, 1); close(fd); } /*Java本地接口方法表*/ static JNINativeMethod method_table[] = { { "tngpio_read", "()I", (void*)com_android_server_SelfManagerService_tngpio_read }, { "tngpio_write", "(C)V", (void*)com_android_server_SelfManagerService_tngpio_write } }; /*注册Java本地接口方法*/ int register_android_server_SelfManagerService(JNIEnv *env) { return jniRegisterNativeMethods(env, "com/android/server/SelfManagerService", method_table, NELEM(method_table)); } };
8.注册native接口
在frameworks/base/services/core/jni/onload.cpp中添加(两个地方)
int register_android_server_SelfManagerService(JNIEnv* env);
register_android_server_SelfManagerService(env);
9.修改Android.mk
在frameworks/base/services/core/jni/Android.mk中加入自己写的
com_android_server_SelfManagerService.cpp:
$(LOCAL_REL_DIR)/com_android_server_SelfManagerService.cpp \
10.mmm frameworks/base/services/编译.
进行到这里,所有的步骤就完成了,我们可以通过
SelfManager selfManager = (SelfManager) getContext().getSystemService("selfservice");
selfManager.read(); selfManager.write('c');
来调用驱动的读和写的方法。
几个需要注意的地方
1:新建接口ISelfManager.aidl文件后,一定要将这个文件添加到framework/base/ 目录下的Android.mk文件中
2:修改SelfManagerService.java这个文件后,最后执行下make update-api -j4,生成新的jar包
参考博客:http://blog.csdn.net/mockingbirds/article/details/54382072
http://blog.csdn.net/hedaogelaoshu/article/details/45247337
http://blog.csdn.net/richu123/article/details/51025477