1.添加jni接口
a.在目录frameworks/base/services/core/jni/添加文件com_android_server_LedService.cpp
b.修改文件frameworks/base/services/core/jni/onload.cpp
@@ -42,6 +42,7 @@ int register_android_server_tv_TvInputHal(JNIEnv* env);
int register_android_server_PersistentDataBlockService(JNIEnv* env);
int register_android_server_fingerprint_FingerprintService(JNIEnv* env);
int register_android_server_Watchdog(JNIEnv* env);
+int register_android_server_LedService(JNIEnv* env); //注意添加的位置,不然会导致改service注册不成功,报No implementation found for native的错误
};
using namespace android;
@@ -79,6 +80,7 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved)
register_android_server_PersistentDataBlockService(env);
register_android_server_fingerprint_FingerprintService(env);
register_android_server_Watchdog(env);
+ register_android_server_LedService(env); //注意添加的位置,不然会导致改service注册不成功,报No implementation found for native的错误
return JNI_VERSION_1_4;
}
c.修改mk文件frameworks/base/services/core/jni/Android.mk
@@ -25,6 +25,7 @@ LOCAL_SRC_FILES += \
$(LOCAL_REL_DIR)/com_android_server_UsbHostManager.cpp \
$(LOCAL_REL_DIR)/com_android_server_VibratorService.cpp \
$(LOCAL_REL_DIR)/com_android_server_PersistentDataBlockService.cpp \
+ $(LOCAL_REL_DIR)/com_android_server_LedService.cpp \
$(LOCAL_REL_DIR)/onload.cpp
2.添加AIDL接口
a.新建目录frameworks/base/core/java/android/led
b.新建文件frameworks/base/core/java/android/led/LedManager.java
frameworks/base/core/java/android/led/ILedManager.aidl
LedManager.java初步实现LedManager.aidl的接口,然后service层则负责中进一步实现AIDL的接口
c.修改mk文件frameworks/base/Android.mk
@@ -267,6 +267,7 @@ LOCAL_SRC_FILES += \
core/java/android/speech/IRecognitionService.aidl \
core/java/android/speech/tts/ITextToSpeechCallback.aidl \
core/java/android/speech/tts/ITextToSpeechService.aidl \
+ core/java/android/led/ILedManager.aidl \
core/java/codeaurora/ultrasound/IDigitalPenDimensionsCallback.aidl \
core/java/com/android/internal/app/IAppOpsCallback.aidl \
core/java/com/android/internal/app/IAppOpsService.aidl \
3.添加service服务(后台运行,进一步实现AIDL的接口并调用jni接口)
a.添加文件frameworks/base/services/core/java/com/android/server/LedService.java
@@ -0,0 +1,43 @@
+package com.android.server;
+
+ import android.os.RemoteException;
+ import android.content.Context;
+ import android.util.Log;
+ import android.led.ILedManager;
+
+ public class LedService extends ILedManager.Stub {
+ private static final String TAG = "LedService";
+ private Context mContext;
+
+ public LedService(Context context) {
+ // mContext = context;
+ super();
+ Log.e(TAG,"in LedService");
+ }
+
+ public void led_on()
+ {
+
+ JNI_Open();
+
+ }
+ public void led_off()
+ {
+ JNI_Close();
+ }
+ public void led_ctl(int lable,int cmd)
+ {
+ JNI_LedCtl(lable,cmd);
+ }
+
+
+ public native int JNI_Open();
+ public native int JNI_Close();
+ public native int JNI_LedCtl(int lable,int cmd);
+}
4.修改Context(主要设置标签,让应用层可以通过context获取系统服务)
a.修改文件frameworks/base/core/java/android/content/Context.java
public abstract class Context {
+ //add by fa
+ public static final String LED_SERVICE = "led";
+ //end by fa
/**
* File creation mode: the defa
b.修改文件frameworks/base/core/java/android/app/ContextImpl.java
+import android.led.LedManager; //add by fa
+import android.led.ILedManager; //add by fa
import com.android.internal.annotations.GuardedBy;
import com.android.internal.app.IAppOpsService;
@@ -588,6 +590,13 @@ class ContextImpl extends Context {
IBinder b = ServiceManager.getService(SERIAL_SERVICE);
return new SerialManager(ctx, ISerialManager.Stub.asInterface(b));
}});
+ //add by fa
+ registerService(LED_SERVICE, new ServiceFetcher() {
+ public Object createService(ContextImpl ctx) {
+ IBinder b = ServiceManager.getService(LED_SERVICE);
+ return new LedManager(ctx, ILedManager.Stub.asInterface(b));
+ }});
+ //end by fa
(这文件主要是用来注册service,这里添加位置有个小技巧,就是一般添加到串口服务的后面,可以全局搜Serial,然后在其后添加)
5.最后一步,把自己添加的server添加到systemserver进程中,这样开机就可以跑起来了
修改文件frameworks/base/services/java/com/android/server/SystemServer.java
@@ -862,6 +862,23 @@ public final class SystemServer {
}
}
+//add by fa
+ LedService leds = null;
+ try {
+ Slog.i(TAG, "Leds Service 1");
+ // Radio port support
+ leds = new LedService(context);
+ Slog.i(TAG, "Leds Service 2");
+
+ ServiceManager.addService(Context.LED_SERVICE, leds);
+ Slog.i(TAG, "Leds Service 3");
+ } catch (Throwable e) {
+ Slog.e(TAG, "Failure starting LedService", e);
+ }
+
+//end by fa
(这里添加有个小技巧,全局搜SERIAL,一般添加在其后面就可以了)
6.framework层已经添加好了,但是还有个问题,就是android5.0引入了selinux机制,所以导致jni层无法打开/dev目录下的设备节点,SystemServe中的ServiceManager.addService无法添加服务,所以还要给这些添加权限
a.修改文件external/sepolicy/file_contexts
@@ -119,6 +119,9 @@
/dev/zero u:object_r:zero_device:s0
/dev/__kmsg__ u:object_r:klog_device:s0
/dev/__properties__ u:object_r:properties_device:s0
+#add by fa
+/dev/leds u:object_r:led_device:s0
+#end by fa
b.修改文件external/sepolicy/device.te
@@ -15,6 +15,7 @@ type console_device, dev_type;
type cpuctl_device, dev_type;
type fscklogs, dev_type;
type full_device, dev_type;
+type led_device,dev_type; # by fa
c.修改文件external/sepolicy/system_server.te
@@ -372,6 +372,10 @@ allow system_server pstorefs:file r_file_perms;
allow system_server system_server_service:service_manager add;
+#add by fa
+allow system_server led_device:chr_file rw_file_perms; \\rw_file_perms表示可读写
+#end by fa
+
allow system_server keystore:keystore_key {
test
get
d.修改文件external/sepolicy/service_contexts
wifiscanner u:object_r:system_server_service:s0
wifi u:object_r:system_server_service:s0
window u:object_r:system_server_service:s0
+led u:object_r:system_server_service:s0
(这里led的值由Context类中的public static final String LED_SERVICE = "led"这个定义决定)
* u:object_r:default_android_service:s0