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进程中去,由该进程来响应服务,然后将处理的结果返回给这个用户应用程序。
NOTEservice 可以与组件通过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介绍

转载于:https://www.cnblogs.com/chsigu/p/10635183.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值