Android Fingerprint中的IPC(Binder)

Android中的指纹模块虽然相对来说不是那么复杂,但是它也是麻雀虽小五脏俱全。
本文将通过Fingerprint模块来分析Android中的Binder机制。
在指纹的整个框架中,有3个地方用到了IPC机制(包括获取指纹服务的一个)。
FingerprintManager-------FingerprintService
FingerprintService--------JNI------HAL

中间文件
Android O

out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/core/java/android/hardware/fingerprint/

Android P
还没有找到。可能已经打包到相关的jar包中,中间文件看不到。

在Android系统中,系统服务运行在一个专门的进程中,这个进程有个名字叫systemserver。该进程在系统启动的时候,就被加载和启动。
Binder机制:系统中有一个专门来管理系统服务的类,叫做ServiceManager,负责注册和管理所有的系统服务。当某个应用程序想要使用系统服务时,需要通过服务的代理来调用服务。由于客户应用程序是运行在自己的进程中,由于与systemserver进程是彼此独立的,因此代理需要通过进程间通讯将请求发送到目标systemserver进程中去,由该进程来响应服务,然后将处理的结果返回给这个用户应用程序。
NOTE:service 可以与组件通过IPC机制进行交互(Binder)

FingerprintManager类中的所有功能都依赖于一个名叫mService的字段来实现。这个字段的类型就是IFingerprintService,它就是我们所说的代理(client端只有通过服务的代理才能够申请到指纹的服务,该服务在systemserver中)。在FingerprintManager中是通过IFingerprintService这个代理来获得FingerprintService这个系统服务的。
代理就是aidl编译出来的类,是IPC的重要体现。
FingerprintManager.java

复制代码

  /**
   * @hide  文档注释
   */ 
  public FingerprintManager(Context context, IFingerprintService service) { 
        mContext = context; 
        mService = service; 
        if (mService == null) { 
          Slog.v(TAG, "FingerprintManagerService was null"); 
        } 
        mHandler = new MyHandler(context); 
   } //既然在构造函数中初始化这个字段,那我们找到FingerprintManager被new的地方也即是该构造函数被调用的地方: 
 //frameworks/base/core/java/android/app/SystemServiceRegistry.java 
 registerService(Context.FINGERPRINT_SERVICE, FingerprintManager.class, 
   new CachedServiceFetcher<FingerprintManager>()
    { 
     @Override 
     public FingerprintManager createService(ContextImpl ctx) throws ServiceNotFoundException 
     { 
        final IBinder binder; 
     if (ctx.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.O) 
     { 
        binder = ServiceManager.getServiceOrThrow(Context.FINGERPRINT_SERVICE); 
      }
      else { 
          binder = ServiceManager.getService(Context.FINGERPRINT_SERVICE); 
      } 
      IFingerprintService service = IFingerprintService.Stub.asInterface(binder); 
     return new FingerprintManager(ctx.getOuterContext(), service); 
     }
    }
   ); 

在这里我们看到 ServiceManager这个类,这个类是专门来管理系统服务的,通过它我们可以获得特定服务的实现类对象:
IBinder binder = ServiceManager.getService(Context.FINGERPRINT_SERVICE); 
接着将其转换成服务的代理: IFingerprintService service = IfingerprintService.Stub.asInterface(binder);
存放在FingerprintManager中: new FingerprintManager(ctx.getOuterContext(), service); 
至此完成了客户端FingerprintManager到服务端 FINGERPRINT_SERVICE 的连接。 

这里的 FINGERPRINT_SERVICE与FingerprintService之间又有什么关联吗? 

public class FingerprintService extends SystemService implements IHwBinder.DeathRecipient {
// FingerprintService是系统服务中的一员,
//SystemService: import com.android.server.SystemService; 
   frameworks/base/services/core/java/com/android/server/SystemService.java
  /** 
   * Called when the dependencies listed in the @Service class-annotation are available 
   * and after the chosen start phase. 
   * When this method returns, the service should be published. 
   */
   public abstract void onStart(); 
    

    //frameworks/base/services/core/java/com/android/server/fingerprint/FingerprintService.java
    /**
     * A service to manage multiple clients that want to access the fingerprint HAL API.
     * The service is responsible for maintaining a list of clients and dispatching all
     * fingerprint -related events.
     *
     * @hide
     */
    public class FingerprintService extends SystemService implements IHwBinder.DeathRecipient {
     ......

复制代码

接着看到FingerprintService下的onStart方法

复制代码

 
    @Override
    public void onStart() {
        publishBinderService(Context.FINGERPRINT_SERVICE, new FingerprintServiceWrapper());
        SystemServerInitThreadPool.get().submit(this::getFingerprintDaemon, TAG + ".onStart");
        listenForUserSwitches();
    }
     ......

     /frameworks/base/services/java/com/android/server/SystemServer.java
    /**
     * Starts a miscellaneous grab bag of stuff that has yet to be refactored
     * and organized.
     */
    private void startOtherServices() {
      …..
             if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) {
                    traceBeginAndSlog("StartFingerprintSensor");
                    mSystemServiceManager.startService(FingerprintService.class);
                    traceEnd();
                }
     …...
FingerprintService在 SystemServer中创建并初始化,当检测到手机支持指纹功能的时候,就会启动这个服务
frameworks/base/services/core/java/com/android/server/SystemServiceManager.java  : mSystemServiceManager

复制代码

 FingerprintService在初始化后会建立和HAL层的通信,即连接到BiometricsFingerprint,拿到用于通信的IBiometricsFingerprint对象(binder) 

本质上来说,除去安全相关的策略外,指纹的功能是依赖硬件实现的,FingerprintService也只是充当了framework java层与native层的消息传递者罢了,所以指纹的识别,录入和监听都是向BiometricsFingerprint(fingerprintd)发送命令和获取相应的结果。

既然FingerprintService已经注册并且启动成功,那么接下来如何去使用指纹服务呢(如何去拿到服务中提供的API)?
指纹服务的代理IFingerprintService 既然已经通过参数传到FingerprintManager中,当然是通过FingerprintManager去调用相关的API。

那么在app层我们是如何获得FingerprintManager的(方法?),并分析?

复制代码

方法:
if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) 
{ 
  mFpm = (FingerprintManager) context.getSystemService(Context.FINGERPRINT_SERVICE); //经典方法  
} 
or 
context.getSystemService( FingerprintManager.class) 
分析: 
 // FingerprintService.java
    @Override
    public void onStart() {
        publishBinderService(Context.FINGERPRINT_SERVICE, new FingerprintServiceWrapper());
        IFingerprintDaemon daemon = getFingerprintDaemon();
        if (DEBUG) Slog.v(TAG, "Fingerprint HAL id: " + mHalDeviceId);
        listenForUserSwitches();
    }

  ServiceManager
 /frameworks/base/core/java/android/os/ServiceManager.java 
    /**
     * Returns a reference to a service with the given name.
     *
     * @param name the name of the service to get
     * @return a reference to the service, or <code>null</code> if the service doesn't exist
     */
    public static IBinder getService(String name) {
        try {
            IBinder service = sCache.get(name);
            if (service != null) {
                return service;
            } else {
                return getIServiceManager().getService(name);
            }
        } catch (RemoteException e) {
            Log.e(TAG, "error in getService", e);
        }
        return null;
    }

    /**
     * Place a new @a service called @a name into the service
     * manager.
     *
     * @param name the name of the new service
     * @param service the service object
     */
    public static void addService(String name, IBinder service) {
        try {
            getIServiceManager().addService(name, service, false);
        } catch (RemoteException e) {
            Log.e(TAG, "error in addService", e);
        }
    }

    /**
     * Place a new @a service called @a name into the service
     * manager.
     *
     * @param name the name of the new service
     * @param service the service object
     * @param allowIsolated set to true to allow isolated sandboxed processes
     * to access this service
     */
    public static void addService(String name, IBinder service, boolean allowIsolated) {
        try {
            getIServiceManager().addService(name, service, allowIsolated);
        } catch (RemoteException e) {
            Log.e(TAG, "error in addService", e);
        }
    }

    //Android O 
    /frameworks/base/core/java/android/app/SystemServiceRegistry.java
    registerService(Context.FINGERPRINT_SERVICE, FingerprintManager.class,
                new CachedServiceFetcher<FingerprintManager>() {
            @Override
            public FingerprintManager createService(ContextImpl ctx) {
                IBinder binder = ServiceManager.getService(Context.FINGERPRINT_SERVICE);
                IFingerprintService service = IFingerprintService.Stub.asInterface(binder);
                return new FingerprintManager(ctx.getOuterContext(), service);
            }});

    /packages/apps/Settings/src/com/android/settings/Utils.java
    public static FingerprintManager getFingerprintManagerOrNull(Context context) {
        if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) {
            return context.getSystemService(FingerprintManager.class);
        } else {
            return null;
        }
    }

  @Override
  public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);

            Activity activity = getActivity();
            //拿到FingerprintManager的对象,接着使用当中的API
            mFingerprintManager = Utils.getFingerprintManagerOrNull(activity);

复制代码

NOTE:FingerprintService与FingerprintManager之所以要使用IPC并不是放置位置上的距离,而是由于它们彼此处在独立的进程中。  

相关类简述

1、com.android.server.SystemServer

本身由zygote进程运行,用来启动各种各样的系统服务(SystemService)

2、com.android.server.SystemService

运行在系统进程中的service,每个SystemService都是有生命周期的,所有的生命周期函数都是运行在SystemServer的主线程当中。

  • 每个SystemService都有一个参数为Context的构造函数,用来初始化SystemService;
  •  调用onstart()使得SystemService处于运行状态,在这种状态下,该SystemService可以通过publishBinderService(String, IBinder) 方法来向外提供服务(binder interface),
  •  在启动阶段onBootPhase(int)会被不停的调用直到运行到PHASE_BOOT_COMPLETED阶段(启动阶段的最后阶段),在启动的每一阶段都可以完成一些特殊的任务。

3、 com.android.server.SystemServiceManager

负责管理SystemService的创建、启动以及其他生命周期函数

4、android.app.ActivityManager

用来和系统中所有运行的Activity进行交互,运行在用户进程中;
IActivityManager是一个系统服务,对于上层应用,IActivityManager不希望把所有的接口都暴露出来,因而使用ActivityManager作为中介来访问IActivityManager提供的功能。ActivityManager是通过ActivityManagerNative.getDefault()来获取到IActivityManager这个接口的。因为ActivityManager是运行在用户进程的,因而getDefault()获取的是ActivityManagerProxy.

参考博客: 

https://www.jianshu.com/p/abab3b44c6b0

ActivityManagerService简要分析

https://www.jianshu.com/p/6c625e4323a1

Android7.0指纹服务FingerprintService介绍

发布了31 篇原创文章 · 获赞 6 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/u012824529/article/details/103744352