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.xml2
<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的(在android.mk 文件中,通过LOCAL_SRC_FILES += $(call all-java-files-under, nci) 来加载nci 的目录,所以,我们公司用的也是NCI目录)。通过Nfc app内部通过JNI调用到libnfc-nci.so当中.
此时运行的进程是com.android.nfc(就是系统的nfc所在进程)所在的进程和第三
方应用是处于不同进程的。
3)、system/nfc的code,是nci芯片的HAL层和协议栈的实现,如NCI的代码实现,
发送命令和接收event等功能。
运行在自己的进程中,nxp的类似如下:vendor.nxp.nxpnfc@1.0-service
4)、最下层就是Nfc Driver了。通过HAL调用到这一层用来和Nfc chip交互.
暂不清楚。
关于运行的进程的名字:
1
xp022430@cnbjlx24729:~$ adb shell ps -A | grep nfc2
nfc 897 1 22164 3016 binder_thread_read 70db203f18 S vendor.nxp.nxpnfc@1.0-service3
nfc 2785 735 2283348 68876 SyS_epoll_wait 7d0f471e28 S com.android.nfc4
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
3
public interface DeviceHostListener {4
5
public void onRemoteEndpointDiscovered(TagEndpoint tag);6
......7
8
public void onCardEmulationAidSelected(byte[] aid,byte[] data, int evtSrc);9
10
public void onConnectivityEvent(int evtSrc);11
12
public void onLlcpLinkActivated(NfcDepEndpoint device);13
......14
15
public void onRemoteFieldActivated();16
......17
}18
19
public interface TagEndpoint {20
21
boolean connect(int technology);22
......23
24
int[] getTechList();25
......26
27
byte[] readNdef();28
29
boolean writeNdef(byte[] data);30
......31
}32
33
public interface TagDisconnectedCallback {34
void onTagDisconnected(long handle);35
}36
......37
38
39
public interface NfcDepEndpoint {40
41
42
43
public static final short MODE_P2P_TARGET = 0x00;44
45
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
56
57
58
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
71
public interface LlcpServerSocket {72
73
public LlcpSocket accept() throws IOException, LlcpException;74
75
public void close() throws IOException;76
}77
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
86
87
88
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
4
5
6
7
mNfcTagService = new TagService();8
9
10
11
12
13
mNfcAdapter = new NfcAdapterService();14
15
......16
17
18
19
20
sService = this;21
22
23
mScreenStateHelper = new ScreenStateHelper(mContext);24
25
26
27
mDeviceHost = new NativeNfcManager(mContext, this);28
29
30
mNfcUnlockManager = NfcUnlockManager.getInstance();31
32
33
34
mHandoverDataParser = new HandoverDataParser();35
36
......37
38
39
mNfcDispatcher = new NfcDispatcher(mContext, mHandoverDataParser, mInProvisionMode);40
41
42
43
mP2pLinkManager = new P2pLinkManager(mContext, mHandoverDataParser,44
mDeviceHost.getDefaultLlcpMiu(), mDeviceHost.getDefaultLlcpRwSize());45
46
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);66
ownerFilter.addDataScheme("package");67
mContext.registerReceiver(mOwnerReceiver, ownerFilter);68
......69
70
71
IntentFilter enableNfc = new IntentFilter();72
enableNfc.addAction(NxpConstants.ACTION_GSMA_ENABLE_NFC);73
mContext.registerReceiverAsUser(mEnableNfc, UserHandle.ALL, enableNfc, null, null);74
75
IntentFilter lsFilter = new IntentFilter(NfcAdapter.ACTION_ADAPTER_STATE_CHANGED);76
77
mContext.registerReceiverAsUser(mAlaReceiver, UserHandle.ALL, lsFilter, null, null);78
......79
80
81
ServiceManager.addService(SERVICE_NAME, mNfcAdapter);82
83
84
mCameraManager = (CameraManager)mContext.getSystemService(Context.CAMERA_SERVICE);85
86
......87
88
new EnableDisableTask().execute(TASK_BOOT);89
}2、NfcService中的构造解析。2.1、TagService
它是NfcService的一个内部类,,framework层的接口api通过binder可以调用到它内部,它最终是操
作NativeNfcTag.其中的方法基本都是一个模式获取到TagEndpoint,然后去调用它的方法,TagEndpoint这个接口就是NativeNfcTag实现的.下面以connect为例子简单过一下流程.1
final class TagService extends INfcTag.Stub{2
@Override3
public int connect(int nativeHandle, int technology) throws RemoteException {4
5
NfcPermissions.enforceUserPermissions(mContext);6
7
TagEndpoint tag = null;8
9
if (!isNfcEnabled()) {10
return ErrorCodes.ERROR_NOT_INITIALIZED;11
}12
13
14
15
tag = (TagEndpoint) findObject(nativeHandle);16
......17
18
if (!tag.isPresent()) {19
return ErrorCodes.ERROR_DISCONNECT;20
}21
22
23
24
25
26
27
28
if (tag.connect(technology)) {29
return ErrorCodes.SUCCESS;30
} 31
......32
}33
@Override34
public int reconnect(int nativeHandle) throws RemoteException {35
......36
tag.reconnect())37
......38
}39
@Override40
public int[] getTechList(int nativeHandle) throws RemoteException {41
......42
tag.getTechList();43
......44
}45
@Override46
public boolean isPresent(int nativeHandle) throws RemoteException {47
......48
return tag.isPresent();49
}50
@Override51
public boolean isNdef(int nativeHandle) throws RemoteException {52
......53
return tag.checkNdef(ndefInfo);54
}55
@Override56
public TransceiveResult transceive(int nativeHandle, byte[] data, boolean raw)57
throws RemoteException {58
......59
60
tag = (TagEndpoint) findObject(nativeHandle);61
if (tag != null) {62
63
if (data.length > getMaxTransceiveLength(tag.getConnectedTechnology())) {64
return new TransceiveResult(TransceiveResult.RESULT_EXCEEDED_LENGTH, null);65
}66
int[] targetLost = new int[1];67
response = tag.transceive(data, raw, targetLost);68
int result;69
if (response != null) {70
result = TransceiveResult.RESULT_SUCCESS;71
} else if (targetLost[0] == 1) {72
result = TransceiveResult.RESULT_TAGLOST;73
} else {74
result = TransceiveResult.RESULT_FAILURE;75
}76
return new TransceiveResult(result, response);77
}78
return null;79
}80
@Override81
public NdefMessage ndefRead(int nativeHandle) throws RemoteException {82
......83
return new NdefMessage(buf);84
......85
}86
@Override87
public int ndefWrite(int nativeHandle, NdefMessage msg) throws RemoteException {88
......89
tag.writeNdef(msg.toByteArray())90
......91
}92
......93
@Override94
public int formatNdef(int nativeHandle, byte[] key) throws RemoteException {95
......96
tag.formatNdef(key)97
......98
}99
......100
} 走到NativeNfcTag当中的
1
public class NativeNfcTag implements TagEndpoint {2
3
private native int doConnect(int handle);4
5
......6
public synchronized boolean connect(int technology) {7
return connectWithStatus(technology) == 0;8
}9
10
public synchronized int connectWithStatus(int technology) {11
......12
int status = -1;13
for (int i = 0; i < mTechList.length; i++) {14
15
if (mTechList[i] == technology) {16
17
if (mConnectedHandle != mTechHandles[i]) {18
19
if (mConnectedHandle == -1) {20
21
status = doConnect(i);22
} else {23
24
status = reconnectWithStatus(i