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
}
整体时序图:
基本的类图关系:
整体架构分析:
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);