Android5.1 FrameWork添加自己的SystemService提供API给APP

论坛 期权论坛 脚本     
匿名网站用户   2020-12-21 03:38   26   0

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




分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:1136255
帖子:227251
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP