IPC (Binder) in Android Fingerprint

Although the fingerprint module in Android is relatively uncomplicated, it is also a small sparrow with all its internal organs.
This article will analyze the Binder mechanism in Android through the Fingerprint module.
In the entire framework of fingerprints, there are three places where the IPC mechanism is used (including one for obtaining fingerprint services).
FingerprintManager ------- FingerprintService
FingerprintService -------- JNI ------ HAL

Intermediate file
Android O

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

Android P
has not been found. It may have been packaged into related jar packages, and the intermediate files cannot be seen.

In the Android system, the system service runs in a special process, this process has a name called systemserver. This process is loaded and started when the system starts.
Binder mechanism: There is a special class in the system to manage system services, called ServiceManager, which is responsible for registering and managing all system services. When an application wants to use system services, it needs to call the service through the service's proxy. Since the client application is running in its own process, because it is independent of the systemserver process, the agent needs to send the request to the target systemserver process through interprocess communication, and the process will respond to the service, and then the result of the processing Return to this user application.
NOTE: service can interact with components through the IPC mechanism (Binder)

All functions in the FingerprintManager class rely on a field called mService to achieve. The type of this field is IFingerprintService, which is what we call a proxy (the client side can only apply for the fingerprint service through the service proxy, which is in the systemserver). The FingerprintService system service is obtained through the agent IFingerprintService in the FingerprintManager. 
The agent is a class compiled by aidl, which is an important embodiment of IPC.
FingerprintManager.java

Copy code

  /**
   * @hide documentation comments
   * / 
  public FingerprintManager (Context context, IFingerprintService service) { 
        mContext = context; 
        mService = service; 
        if (mService == null) { 
          Slog.v (TAG, "FingerprintManagerService was null"); 
        } 
        mHandler = new MyHandler (context); 
   } // Since the field is initialized in the constructor, we find the place where the FingerprintManager is new and the place where the constructor is called: 
 //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); 
     } 
    } 
   ); 

Here we see the ServiceManager class, this class is specifically to come Management system services, through which we can obtain the implementation class objects of specific services:
IBinder binder = ServiceManager.getService (Context.FINGERPRINT_SERVICE);
接着将其转换成服务的代理: IFingerprintService service = IfingerprintService.Stub.asInterface(binder);
Stored in FingerprintManager: new FingerprintManager (ctx.getOuterContext (), service); 
At this point, the connection from the client FingerprintManager to the server FINGERPRINT_SERVICE is completed. 

Is there any relationship between FINGERPRINT_SERVICE and FingerprintService here? 

public class FingerprintService extends SystemService implements IHwBinder.DeathRecipient { 
// FingerprintService is a member of the system service,
//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 {
     ......

Copy code

Then see the onStart method under FingerprintService

Copy code

 
    @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 is created and initialized in SystemServer, when it detects that the mobile phone supports fingerprint function, it will start this service 
frameworks / base / services / core / java /com/android/server/SystemServiceManager.java: mSystemServiceManager

Copy code

 After initialization, FingerprintService will establish communication with the HAL layer, that is, connect to BiometricsFingerprint and get the IBiometricsFingerprint object (binder) used for communication. 

Essentially, except for security-related policies, the fingerprint function is implemented by hardware. FingerprintService only acts as a messaging agent for the framework java layer and native layer, so fingerprint identification, entry, and monitoring are all directed to Biometrics Fingerprint ( fingerprintd) Send commands and get corresponding results.

Now that FingerprintService has been registered and started successfully, how to use fingerprint service next (how to get the API provided in the service)? 
Since the fingerprint service agent IFingerprintService has been passed to the FingerprintManager through parameters, of course, the related API is called through the FingerprintManager. So how do we get FingerprintManager (method?) At the app level and analyze it?

Copy code

method:
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();
            // Get the FingerprintManager object, and then use the API 
            mFingerprintManager = Utils.getFingerprintManagerOrNull (activity);

Copy code

NOTE: The reason why FingerprintService and FingerprintManager use IPC is not because of the distance between them, but because they are in separate processes from each other.  

 

Brief description of related classes

1、com.android.server.SystemServer

It is run by the zygote process itself to start various system services (SystemService)

2、com.android.server.SystemService

Service running in the system process, each SystemService has a life cycle, all life cycle functions are running in the main thread of SystemServer.

  • Each SystemService has a constructor whose parameter is Context, used to initialize SystemService;
  •  Call onstart () to make the SystemService in a running state. In this state, the SystemService can  provide services (binder interface) to the outside through the publishBinderService (String, IBinder) method.
  •  During the startup phase, onBootPhase (int) will be called continuously until it reaches the PHASE_BOOT_COMPLETED phase (the last phase of the startup phase), and some special tasks can be completed in each phase of startup.

3、 com.android.server.SystemServiceManager

Responsible for managing the creation, startup and other life cycle functions of SystemService

4、android.app.ActivityManager

Used to interact with all the activities running in the system and run in the user process;
IActivityManager is a system service. For upper-layer applications, IActivityManager does not want to expose all the interfaces, so use ActivityManager as an intermediary to access the functions provided by IActivityManager . ActivityManager gets the interface of IActivityManager through ActivityManagerNative.getDefault (). Because ActivityManager runs in the user process, getDefault () gets ActivityManagerProxy.

 

Reference blog: 

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

ActivityManagerService brief analysis

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

Android7.0 fingerprint service FingerprintService introduction

Published 31 original articles · Likes6 · Visitors 10,000+

Guess you like

Origin blog.csdn.net/u012824529/article/details/103744352