在平常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的步驟了...