FrameWork从纵向来看主要就是添加Service并且利用JNI调用HAL层C/C++的代码来实现提供API给APP操作硬件的目的
本文就是描述在Android5.1如何实现添加自己的System Service来实现跟HAL进行Socket通信
一:首先先描述如何注册自己的SystemService并且实现自己的AIDL,我们这部分要实现的目标是在APP通过调用 (InfraredManager)context.getSystemService(Context.XXX) 提供API,实现InfraredManager步骤如下
1:将Binder的"客户端"部分实现在\frameworks\base\core\java\com\android\infrared\InfraredManager.java 同时创建 \frameworks\base\core\java\com\yuekong\infrared\InfraredReceptionManager.aidl
AIDL就是Binder调用的接口
package com.android.infrared;
import com.android.infrared.IOnInfraredReceivedListener;
import java.lang.String;
/**
* Binder interface that clients running in application context
* can use to interface with remote service
*/
interface InfraredReceptionManager {
void sendStartLearnMsg();
void sendLearnMsg();
void sendStopLearnMsg();
void sendInfo(in String info);
void addInfraredReceivedListener(in IOnInfraredReceivedListener listener);
void removeInfraredReceivedListener(in IOnInfraredReceivedListener listener);
}
2:binder接口创建好后,实现"服务端"的service 在\frameworks\base\services\core\java\com\yuekong\infrared\InfraredManagerService
package com.android.infrared;
import android.content.Context;
import android.widget.Toast;
import android.os.IBinder;
import com.android.server.SystemService;
import com.android.infrared.IOnInfraredReceivedListener;
import android.os.RemoteCallbackList;
import android.os.Binder;
import com.android.infrared.InfraredSocketClient.OnReceivedInfraredListener;
import android.os.RemoteException;
public class InfraredManagerService extends SystemService implements OnReceivedInfraredListener {
private static final String TAG = "InfraredManagerService";
private final Context mContext;
private InfraredSocketClient mClient = null;
private RemoteCallbackList<IOnInfraredReceivedListener> mListenersList = new RemoteCallbackList<IOnInfraredReceivedListener>();
public InfraredManagerService(Context context){
super(context);
mContext = context;
publishBinderService(context.INFRARED_SERVICE, mService);
}
/**
* Implementation of AIDL service interface
*/
private final IBinder mService = new InfraredReceptionManager.Stub() {
@Override
public void sendStartLearnMsg() {
getSocketInstance().sendSocket(CommandConstant.Command_Learn_Start);
}
@Override
public void sendLearnMsg() {
getSocketInstance().sendSocket(CommandConstant.Command_Learn_Key);
}
@Override
public void sendStopLearnMsg() {
getSocketInstance().sendSocket(CommandConstant.Command_Learn_Stop);
}
@Override
public void sendInfo(String info) {
getSocketInstance().sendSocket(info);
Xlog.w(TAG, "stop learn mode");
}
@Override
public void addInfraredReceivedListener(IOnInfraredReceivedListener listener){
if(listener == null){
return;
}
synchronized(mListenersList){
mListenersList.register(listener, Binder.getCallingUserHandle());
}
}
@Override
public void removeInfraredReceivedListener(IOnInfraredReceivedListener listener){
if(listener == null){
return;
}
synchronized(mListenersList){
mListenersList.unregister(listener);
}
}
};
/**
* Called when service is started by the main system service
*/
@Override
public void onStart() {
Xlog.d(TAG, "Service start");
getSocketInstance().startConnection();
getSocketInstance().setInfraredReceivedListener(InfraredManagerService.this);
}
@Override
public void onReceivedInfraredInfo(int mode,boolean success, int[] info){
final int size = mListenersList.beginBroadcast();
for (int i = 0; i < size; i++) {
IOnInfraredReceivedListener listener = mListenersList.getBroadcastItem(i);
try {
Xlog.d(TAG, "binder listener call back" + listener.toString());
listener.onInfraredReceived(mode,success, info);
} catch (RemoteException re) {
Xlog.d(TAG, "Callback failed ");
}
}
mListenersList.finishBroadcast();
}
private InfraredSocketClient getSocketInstance(){
if(mClient == null){
mClient = new InfraredSocketClient();
}
return mClient;
}
}
3:我们在调用SystemService的时候都会用context.getSystemService实现调用,然后我们实现自己的Manager给App调用
package com.android.infrared;
import com.android.infrared.InfraredReceptionManager;
import android.content.Context;
import android.os.RemoteException;
import java.util.ArrayList;
import java.util.List;
public class InfraredManager{
private static final String TAG = "InfraredManager";
private final Context mContext;
private final InfraredReceptionManager mService;
private List<InfraredReceiverListener> mCallBackList = new ArrayList<InfraredReceiverListener>();
private IOnInfraredReceivedListener.Stub mInfraredReceivedListener;
public InfraredManager(Context context,InfraredReceptionManager service ){
this.mContext = context;
this.mService = service;
}
public void sendStartLearnMsg() {
try{
if(mService != null){
mService.sendStartLearnMsg();
}
} catch (RemoteException ex){
}
}
public void sendLearnMsg(){
try{
if(mService != null){
mService.sendLearnMsg();
}
} catch (RemoteException ex){
}
}
public void sendStopLearnMsg() {
try{
if(mService != null){
mService.sendStopLearnMsg();
}
} catch (RemoteException ex){
}
}
public void sendInfo(String info){
try{
mService.sendInfo(info);
} catch (RemoteException ex){
}
}
public void registerListerner(InfraredReceiverListener listener){
synchronized(this){
if(mCallBackList != null && listener != null && !callBackContain(mCallBackList,listener)){
mCallBackList.add(listener);
boolean addedFirstCallback = (mCallBackList.size() == 1);
if(addedFirstCallback){
try {
mService.addInfraredReceivedListener(getInstance());
} catch (RemoteException re) {
}
}
}
}
}
private boolean callBackContain( List<InfraredReceiverListener> callBackList,InfraredReceiverListener listener){
if( callBackList.size() == 0 ){
return false;
}
for(int i = 0 ; i < callBackList.size(); i++ ){
Xlog.d(TAG, "register listener has this : " +listener.toString());
if(callBackList.get(i) == listener ){
return true;
}
}
return false;
}
public void unregisterListener(InfraredReceiverListener listener) {
if(listener == null){
return;
}
synchronized (this) {
final int size = mCallBackList.size();
for (int i = 0; i < size; ++i) {
if (mCallBackList.get(i) == listener) {
Xlog.d(TAG, "unregister listener :" +listener.toString());
mCallBackList.remove(i);
Xlog.d(TAG, "after unregieter size :" + mCallBackList.size());
return;
}
}
if(mCallBackList.size() == 0 && mInfraredReceivedListener != null){
try{
mService.removeInfraredReceivedListener(mInfraredReceivedListener);
}catch(RemoteException re){
}
Xlog.d(TAG, "unregister binder listener :" +mInfraredReceivedListener.toString());
mInfraredReceivedListener = null;
}
}
}
public static abstract class InfraredReceiverListener{
abstract public void onInfraredReceived(int mode,boolean isSuccess,int[] info);
}
private IOnInfraredReceivedListener.Stub getInstance(){
if(mInfraredReceivedListener == null){
mInfraredReceivedListener = new IOnInfraredReceivedListener.Stub() {
@Override
public void onInfraredReceived(int mode,boolean isSuccess,int[] info){
synchronized (InfraredManager.this) {
for (UCONInfraredReceiverListener listener : mCallBackList) {
Xlog.d(TAG, "start call back listener " + listener.toString());
listener.onInfraredReceived(mode,isSuccess,info);
}
}
}
};
}
Xlog.d(TAG, "create binder listener name is " + mInfraredReceivedListener.toString());
return mInfraredReceivedListener;
}
}
4:这边Binder的客户端和服务端实现结束,还要在系统的ServiceManager注册自己的SystemService 在 frameworks/base/core/java/android/app/ContextImpl.java
//add by zhongqi.shao on 2016-08-05 start
registerService(INFRARED_SERVICE, new ServiceFetcher() {
public Object createService(ContextImpl ctx) {
IBinder b = ServiceManager.getService(INFRARED_SERVICE);
InfraredReceptionManager uconInfraredService =
InfraredReceptionManager.Stub.asInterface(b);
if (InfraredService != null) {
return new InfraredManager(ctx,InfraredService);
} else {
// not supported
return null;
}
}
});
//add by zhongqi.shao on 2016-08-05 end
</pre><pre code_snippet_id="1978267" snippet_file_name="blog_20161110_6_4875789" name="code" class="java">这一步就可以实现在framework添加自己的SystemService