[转载]NFC源码分析之初始化流程

时间:2024-03-18 20:33:59

https://blog.csdn.net/zy00000000001/article/details/78863699

Nfc的app代码位于:
    android/package/apps/Nfc/... 编译生成Nfc的apk和libnfc_nci_jni.so
Nfc的协议栈和Hal相关的代码位于:
    system/nfc/... (原生的应该是位于/external/libnfc-nci)编译生成libnfc-nci.so
    在Nfc的app的AndroidManifest中查看application的节点,会有 "persisent = true"的属性,所以 这个app会在
Android systemserver启动的时候启动当前NfcApplication这个类,然后调用它的onCreate(), 此处就不讨论这个
流程,需要注意的是在Android N以后有一个FBE(DirectBootMode)模式,就是首次开机用户不解 锁此时的设计
要求是不启动Nfc的。在NfcApplication的onCreate当中会去实例化NfcService,开启Nfc的初始化.
相关代码:
1
AndroidManifest.xml
2
    <application android:name=".NfcApplication"
3
                android:icon="@drawable/icon"
4
                android:label="@string/app_name"
5
                android:theme="@android:style/Theme.Material.Light"
6
                android:persistent="true"
7
                android:hardwareAccelerated="false"
8
                android:backupAgent="com.android.nfc.NfcBackupAgent"
9
                android:killAfterRestore="false"
10
                android:usesCleartextTraffic="false"
11
                android:supportsRtl="true"
12
    >
NfcApplication.java
1
    public void onCreate() {
          
2
        super.onCreate();
3

4
        boolean isMainProcess = false;
5
        ......
6
        ActivityManager am = (ActivityManager)this.getSystemService(ACTIVITY_SERVICE);
7
        List processes = am.getRunningAppProcesses();
8
        Iterator i = processes.iterator();
9
        while (i.hasNext()) {
          
10
            RunningAppProcessInfo appInfo = (RunningAppProcessInfo)(i.next());
11
            if (appInfo.pid == Process.myPid()) {
          
12
                isMainProcess =  (NFC_PROCESS.equals(appInfo.processName));
13
                break;
14
            }
15
        }
16
        if (UserHandle.myUserId() == 0 && isMainProcess) {
          
17
            mNfcService = new NfcService(this);
18
            ThreadedRenderer.enableForegroundTrimming();
19
        }
20
    }
整体时序图:
[转载]NFC源码分析之初始化流程
基本的类图关系:
[转载]NFC源码分析之初始化流程
整体架构分析:
    1)、开发第三方的使用Nfc功能应用
      使用framework层的api,路径:android.nfc.*和android.nfc.tech.*
      此时运行的进程是当前应用所在的进程。
    2)、系统Nfc中的包含NfcService等重要的类,很多功能的真正的实现在这个层面
      第三方的应用调用framework的api的接口,最终是通过binder调用到这里的实现
      如:
          NfcAdapterService extends INfcAdapter.Stub
          TagService extends INfcTag.Stub
      注意:这一步还包含了nci和nxp两个中JNI层的接口实现,根据配置的mk决定用那个,
      公司用的是nci的,通过Nfc app内部通过JNI调用到libnfc-nci.so当中.
      此时运行的进程是com.android.nfc(就是系统的nfc所在进程)所在的进程和第三
      方应用是处于不同进程的。
    3)、system/nfc的code,是nci芯片的HAL层和协议栈的实现,如NCI的代码实现,
        发送命令和接收event等功能。
        运行在自己的进程中,nxp的类似如下:[email protected]
    4)、最下层就是Nfc Driver了。通过HAL调用到这一层用来和Nfc chip交互.
        暂不清楚。
关于运行的进程的名字:
1
[email protected]:~$ adb shell ps -A | grep nfc
2
nfc      897    1  22164  3016 binder_thread_read 70db203f18 S [email protected]
3
nfc      2785  735 2283348  68876 SyS_epoll_wait 7d0f471e28 S com.android.nfc
4
u0_a114  7005  735 2249568  39120 SyS_epoll_wait 7d0f471e28 S com.sonymobile.nfcextension  
1、NfcService的主要实现
1
import com.android.nfc.DeviceHost.DeviceHostListener;
2
public class NfcService implements DeviceHostListener { }.
      实现了一个DeviceHostListener,DeviceHostListener是DeviceHost内部的一个接口。 DeviceHost里面定义
了,几乎NFC(上层功能)需要的全部interface和API,不同的厂家依据DeviceHost提 供的interface,实现对应的
内容,接口是统一规范这样来适配framework层的api。
    所以此处有必要分析DeviceHost的主要功能,列出自己关心的几个,NativeNfcManager实现了 DeviceHost的
具体功能,里面有很多接口的定义和NFC功能调用的api。
1
public interface DeviceHost {
           
2
    //NfcService实现了它的具体功能,里面基本上都是描述的整体nfc的状态的接口.
3
    public interface DeviceHostListener {
           
4
        //当检测到远端的tag的时候的回调,TagEndpoint:来表示远端的tag
5
        public void onRemoteEndpointDiscovered(TagEndpoint tag);
6
        ......
7
        //当卡模拟的Aid被选中的时候
8
        public void onCardEmulationAidSelected(byte[] aid,byte[] data, int evtSrc);
9
        //通知se相关的事件
10
        public void onConnectivityEvent(int evtSrc);
11
        //当P2P链接成功的时候
12
        public void onLlcpLinkActivated(NfcDepEndpoint device);
13
        ......
14
        //作为reader检测到remoteFiled(就是远端的card)的时候
15
        public void onRemoteFieldActivated();
16
        ......
17
    }
18
    //NativeNfcTag类实现了它的具体功能,用来实现Nfc Tag的一些功能。
19
    public interface TagEndpoint {
           
20
        //Tag建立起了连接
21
        boolean connect(int technology);
22
        ......
23
        //读取Tag中所用到的tech
24
        int[] getTechList();
25
        ......
26
        //读取Tag中的ndef消息
27
        byte[] readNdef();
28
        //向Tag中写入Ndef消息
29
        boolean writeNdef(byte[] data);
30
        ......
31
    }
32
    //Tag断开链接的回调
33
    public interface TagDisconnectedCallback {
           
34
        void onTagDisconnected(long handle);
35
    }
36
    ......
37
    //NativeP2pDevice类实现它的具体功能,P2P的Initiator发起端的功能实现。
38
    //自己没有跟这里的看起来即可以表示发起端,又可以表示接收端。
39
    public interface NfcDepEndpoint {
           
40
        /**
41
        * Peer-to-Peer Target
42
        */
43
        public static final short MODE_P2P_TARGET = 0x00;
44
        /**
45
        * Peer-to-Peer Initiator
46
        */
47
        public static final short MODE_P2P_INITIATOR = 0x01;
48
        ......
49
        public byte[] receive();
50
        public boolean send(byte[] data);
51
        public boolean connect();
52
        public boolean disconnect();
53
        ......
54
    }
55
    //NativeLlcpSocket类实现它的具体功能,
56
    //代表了一个llcp链接中的客户端的通信部分.
57
    //那么问题来了P2P的这个连接中谁是客户端?发起方?接收方?还是说并不是P2P才用这个?
58
    //比如read/write模式。这样就比较好定义客户端和服务端了。?这块不太清楚
59
    public interface LlcpSocket {
           
60
        ......
61
        public void connectToService(String serviceName) throws IOException;
62
        public void close() throws IOException;
63
        public void send(byte[] data) throws IOException;
64
        public int receive(byte[] recvBuff) throws IOException;
65
        public int getRemoteMiu();
66
        ......
67
        public int getLocalSap();
68
        ......
69
    }
70
    //NativeLlcpServiceSocket类实现它的具体功能,表示一个llcp链接中的服务端的通信部分.
71
    public interface LlcpServerSocket {
           
72
        //监听客户端的链接
73
        public LlcpSocket accept() throws IOException, LlcpException;
74
        //关闭服务
75
        public void close() throws IOException;
76
    }
77
    //NativeLlcpConnectionlessSocket类实现它的具体功能,代表在无连接通信中使用的LLCP对象?不太清楚.
78
    public interface LlcpConnectionlessSocket {
           
79
        public int getLinkMiu();
80
        public int getSap();
81
        public void send(int sap, byte[] data) throws IOException;
82
        public LlcpPacket receive() throws IOException;
83
        public void close() throws IOException;
84
    }
85
    //以上的接口在内部实现的时候如它们的名字所示,Native...,他们内部基本都有native方法去进一步的
86
    //通过JNI调用到native层实现的地方。
87
    
88
    //下面都是管理NFC功能的api,位于NativeNfcManager当中.
89
    public void checkFirmware();
90
    ......
91
    public boolean initialize();
92
    public String getName();
93
    public void enableDiscovery(NfcDiscoveryParameters params, boolean restart);
94
    public void doSetScreenState(int mScreenState);
95
    ......
96
    public void disableDiscovery();
97
    ......
98
    public LlcpConnectionlessSocket createLlcpConnectionlessSocket(int nSap, String sn)
99
            throws LlcpException;
100
    public LlcpServerSocket createLlcpServerSocket(int nSap, String sn, int miu,
101
            int rw, int linearBufferLength) throws LlcpException;
102
    public LlcpSocket createLlcpSocket(int sap, int miu, int rw,
103
            int linearBufferLength) throws LlcpException;
104
    ......
105
}
         介绍完DeviceHost以及它内部的接口的实现,回到NfcServie这个类中看它的构造方法初始化了很多重要的
类如:TagService、 NfcAdapterService、NativeNfcManager、NfcDispatcher等,下面只是留了一些关心的部
分。 构造如下:
1
public NfcService(Application nfcApplication) {
          
2
    ......
3
    //Nfc Tag相关的一些操作.最终调用到的就是DeviceHost里面的interface的
4
    //实现NativeNfcTag此处就是final class TagService extends INfcTag.Stub {...}
5
    //然后在内部的方法中去调用DeviceHost.TagEndpoint,也就是调用到了NativeNfcTag.
6
    //下面的很多service都是这种实现方式,这样framework层api通过binder调用到native层实现的地方
7
    mNfcTagService = new TagService();
8
    
9
    //BluetoothAdapter类似,用于供外部调用NFC功能。个人理解adapter适配,也就是说其实是一个转接口
10
    //它只是提供统一规范,然后在它的内部会再去调用如NativeNfcManager里面真正的native的方法去和NFC打交道
11
    //这样做还有一个好处就是可以一定程度封装代码。结构清晰,代码隐蔽.
12
    //实现方式类似上面的TagService
13
    mNfcAdapter = new NfcAdapterService();
14
    //下面省略了一些NxpNfcAdapterService的初始化,暂时不清楚这些类的功能,可能是HiNXP扩展用.
15
    ......
16
    //卡模拟的service,现在直接被注释掉了,可能不用了,直接用对应的manager管理
17
    //mCardEmulationService = new CardEmulationService();
18

19
    //sService是NfcService
20
    sService = this;
21

22
    //NFC与屏幕锁定状态相关的类,用来方便屏幕状态的管理
23
    mScreenStateHelper = new ScreenStateHelper(mContext);
24
    
25
    //NativeNfcManager里面基本上都是native的方法,用于进一步调用到native层和NFC进行通信.
26
    //private DeviceHost mDeviceHost;可以看到NativeNfcManager就是DeviceHost
27
    mDeviceHost = new NativeNfcManager(mContext, this);
28

29
    //在进行一些handover等的时候,NFC对屏幕解锁的一些逻辑(某些状态下)。
30
    mNfcUnlockManager = NfcUnlockManager.getInstance();
31
    
32
    //使用别的技术如蓝牙进行handover的时候的帮助类,目前为止只有对蓝牙的实现,可以通过此类
33
    //把蓝牙地址、名字等信息封装成对应的标准NDEF Message进行传输.
34
    mHandoverDataParser = new HandoverDataParser();
35

36
    ......//此处省略了在Nfc在setup wizard阶段接受数据的处理
37

38
    //分发Nfc的不同的EVENT然后根据Android的policy区启动对应的activity处理相应的事件。
39
    mNfcDispatcher = new NfcDispatcher(mContext, mHandoverDataParser, mInProvisionMode);
40
    
41
    //基于LLCP连接的服务,含NdefPushService/SnepService/P2pEventManager
42
    //就是处理NFC进行P2P的时候的一些逻辑
43
    mP2pLinkManager = new P2pLinkManager(mContext, mHandoverDataParser,
44
            mDeviceHost.getDefaultLlcpMiu(), mDeviceHost.getDefaultLlcpRwSize());
45

46
    //电源管理模块,主要是处理屏幕状态与NFC是否响应的联系
47
    mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
48

49
    ......
50
    //注册屏幕亮/灭,用户**和切换 
51
    IntentFilter filter = new IntentFilter(NativeNfcManager.INTERNAL_TARGET_DESELECTED_ACTION);
52
    filter.addAction(Intent.ACTION_SCREEN_OFF);
53
    filter.addAction(Intent.ACTION_SCREEN_ON);
54
    filter.addAction(Intent.ACTION_USER_PRESENT);
55
    filter.addAction(Intent.ACTION_USER_SWITCHED);
56
    mContext.registerReceiverAsUser(mReceiver, UserHandle.ALL, filter, null, null);
57
    filter = new IntentFilter(Intent.ACTION_SHUTDOWN);
58
    mContext.registerReceiver(mOwnerReceiver, filter);
59
    IntentFilter ownerFilter = new IntentFilter(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
60
    ownerFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
61
    mContext.registerReceiver(mOwnerReceiver, ownerFilter);
62
    //关注程序安装和卸载  
63
    ownerFilter = new IntentFilter();
64
    ownerFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
65
    ownerFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);