在平常android应用开发中,多数只是调framwork中的API进行application layer的coding,而在系统开发中可能会自己添加系统服务;
系统服务如任何添加,服务如何调native code,以及service如何被manager调用...这里我给出一个结果验证的demo。
1、实现编写native code,framwork/base/services/jni/com_android_server_VirtualInputService.cpp;
以下是会使用到的native 函数,以及register_android_server_VirtualInputService;具体实现就不在详讲了。
static JNINativeMethod method_table[] = {
{"native_open", "()I",(void *)android_server_VirtualInputService_open},
{"native_close", "()Z", (void *)android_server_VirtualInputService_close},
{"native_sendir", "(II)Z", (void *)android_server_VirtualInputService_sendir},
};
+int register_android_server_VirtualInputService(JNIEnv *env)
+{
+ jclass clazz = env->FindClass("com/android/server/VirtualInputService");
+ if (clazz == NULL) {
+ ALOGE("Can't find com/android/server/VirtualInputService");
+ return -1;
+ }
+
+ return jniRegisterNativeMethods(env, "com/android/server/VirtualInputService",
+ method_table, NELEM(method_table));
+}
+};
2、base/services/jni/onload.cpp中添加register_android_server_VirtualInputService
int register_android_server_SerialService(JNIEnv* env);
+int register_android_server_VirtualInputService(JNIEnv* env);
int register_android_server_UsbDeviceManager(JNIEnv* env);
register_android_server_SerialService(env);
+ register_android_server_VirtualInputService(env);
register_android_server_InputApplicationHandle(env);
3、mk中添加com_android_server_VirtualInputService,使其被编译到
+++ base/services/jni/Android.mk (working copy)
@@ -16,6 +16,7 @@
com_android_server_VibratorService.cpp \
com_android_server_location_GpsLocationProvider.cpp \
com_android_server_connectivity_Vpn.cpp \
+ com_android_server_VirtualInputService.cpp \
onload.cpp
4、service添加: base/services/java/com/android/server/VirtualInputService.java
其必须继承IVirtualInputManager.Stub使其能被远程调用;
声明native方法:private native static int native_open();
private native static boolean native_close();
private native static boolean native_sendir(int keycode, int type);
+package com.android.server;
+
+import android.content.Context;
+import android.hardware.input.IVirtualInputManager;
+import android.util.Log;
+
+import java.io.File;
+import java.util.ArrayList;
+
+public class VirtualInputService extends IVirtualInputManager.Stub {
+ private static final String TAG = "VirtualInputManager";
+
+ private final Context mContext;
+ private int mVirtualInputFd = -1;
+
+ public VirtualInputService(Context context) {
+ mContext = context;
+ if(mVirtualInputFd == -1){
+ mVirtualInputFd = native_open();
+ Log.d(TAG, "mVirtualInputFd:"+mVirtualInputFd);
+ }else
+ Log.d(TAG, "mVirtualInputFd1:"+mVirtualInputFd);
+
+ }
+
+ public boolean SendIR(int keycode){
+ if(mVirtualInputFd > 0)
+ {
+ Log.d(TAG, "Service SendIR:"+keycode);
+ return native_sendir(keycode,0);
+ }
+ else
+ return false;
+ }
+
+ private native static int native_open();
+ private native static boolean native_close();
+ private native static boolean native_sendir(int keycode, int type);
+
+}
5、base/services/java/com/android/server/SystemServer.java中添加新service
SerialService serial = null;
+ VirtualInputService VirtualInput = null;
TwilightService twilight = null;
try {
+ Slog.i(TAG, "VirtualInput Service");
+ VirtualInput = new VirtualInputService(context);
+ ServiceManager.addService(Context.VIRTUALINPUT_SERVICE, VirtualInput);
+ } catch (Throwable e) {
+ Slog.e(TAG, "Failure starting VirtualInputService", e);
+ }
+
+ try {
Slog.i(TAG, "Twilight Service");
twilight = new TwilightService(context);
} catch (Throwable e) {
6、添加aidl接口:base/core/java/android/hardware/input/IVirtualInputManager.aidl
+package android.hardware.input;
+
+
+/** @hide */
+interface IVirtualInputManager
+{
+ boolean SendIR(int keycode);
+}
7、实现IVirtualInputManager.java;base/core/java/android/hardware/input/VirtualInputManager.java
+package android.hardware.input;
+
+import android.app.PendingIntent;
+import android.content.Context;
+import android.os.Bundle;
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
+import android.os.SystemProperties;
+import android.util.Log;
+
+import java.io.IOException;
+import java.util.HashMap;
+
+/**
+ * @hide
+ */
+public class VirtualInputManager {
+ private static final String TAG = "VirtualInputManager";
+
+ private final Context mContext;
+ private final IVirtualInputManager mService;
+
+ /**
+ * {@hide}
+ */
+ public VirtualInputManager(Context context, IVirtualInputManager service) {
+ mContext = context;
+ mService = service;
+ Log.d(TAG,"VirtualInputManager");
+ }
+
+ public boolean SendIR(int keycode) throws android.os.RemoteException{
+ Log.d(TAG,"keycode:"+keycode);
+ return mService.SendIR(keycode);
+ }
+}
8.framwork/base/Android.mk
core/java/android/hardware/input/IInputManager.aidl \
+ core/java/android/hardware/input/IVirtualInputManager.aidl \
core/java/android/hardware/input/IInputDevicesChangedListener.aidl \
9、base/core/java/android/content/Context.java 中添加系统获取服务的标示
+ public static final String VIRTUALINPUT_SERVICE = "virtualinput";
10、base/core/java/android/app/ContextImpl.java
+ registerService(VIRTUALINPUT_SERVICE, new ServiceFetcher() {
+ public Object createService(ContextImpl ctx) {
+ IBinder b = ServiceManager.getService(VIRTUALINPUT_SERVICE);
+ return new VirtualInputManager(ctx, IVirtualInputManager.Stub.asInterface(b));
+ }});
+
以上就是添加一个完整的service的步骤了...