在机器开机过程中,可以抓取到以下的正常logcat信息:
//setp1
I/NfcService( 3809): Starting NFC service
D/NFCJNI ( 3809): NFC Service : loading JNI
I/RegisteredComponentCache( 3809): ComponentInfo: ResolveInfo{41344108
com.android.apps.tag.TagViewer p=0 o=0 m=0x108000}, techs: android.nfc.tech.Ndef,
W/NfceeAccess( 3809): could not find /etc/nfcee_access.xml, no NFCEE access allowed
I/NfceeAccess( 3809): read 0 signature(s) for NFCEE access
D/NfcService( 3809): checking on firmware download
下面是硬件不支持NFC的异常logcat信息:
I/NfcService( 3485): Starting NFC service
D/NFCJNI ( 3485): NFC Service : loading JNI
W/NfceeAccess( 3485): could not find /etc/nfcee_access.xml, no NFCEE access allowed
I/NfceeAccess( 3485): read 0 signature(s) for NFCEE access
D/NfcService( 3485): checking on firmware download
D/NfcService( 3485): NFC is on. Doing normal stuff
I/NfcService( 3485): Enabling NFC
D/NFCJNI ( 3485): Start Initialization
E/NFCJNI ( 3485): hw_get_module() failed.
D/NFCJNI ( 3485): Terminating client thread...
W/NfcService( 3485): Error enabling NFC
来看正常logcat信息setp1,NfcService 是application,它的onCreate()方法:
@Override
public void onCreate() {
super.onCreate();
mNfcTagService = new TagService();
mNfcAdapter = new NfcAdapterService();
mExtrasService = new NfcAdapterExtrasService();
Log.i(TAG, "Starting NFC service");
//setp2:NFC Service : loading JNI
mDeviceHost = new NativeNfcManager(this, this);
HandoverManager handoverManager = new HandoverManager(mContext);
//NfcDispatcher主要负责tag消息处理,并派发Intent消息,启动Activity。
mNfcDispatcher = new NfcDispatcher(this, handoverManager);
mP2pLinkManager = new P2pLinkManager(mContext, handoverManager);
mSecureElement = new NativeNfcSecureElement(mContext);
//setp3:could not find /etc/nfcee_access.xml, no NFCEE access allowed
mNfceeAccessControl = new NfceeAccessControl(this);
//把mNfcAdapter 作为Service 添加到系统服务中,ServiceManager.getService("nfc")可以获取到binder
ServiceManager.addService(SERVICE_NAME, mNfcAdapter);
updatePackageCache();
//setp4:checking on firmware download
new EnableDisableTask().execute(TASK_BOOT); // do blocking boot tasks
}
Setp2:NFC Service loading JNI,这一部分是在NativeNfcManager.java中处理的
//加载jni编译生成的nfc_jni.so.通过NativeNfcManager调用jni部分
static {
System.loadLibrary("nfc_jni");
}
//NativeNfcManager 构造方法
public NativeNfcManager(Context context, DeviceHostListener listener) {
mListener = listener;
//setp2-1:com_android_nfc_NativeNfcManager.cpp的native方法
//com_android_nfc_NfcManager_init_native_struc(JNIEnv *e, jobject o)
initializeNativeStructure();
mContext = context;
}
Setp2-1:com_android_nfc_NfcManager_init_native_struc(),初始化nfc_jni_native_data结构体
static jboolean com_android_nfc_NfcManager_init_native_struc(JNIEnv *e, jobject o)
{
/* Initialize native structure */
// 涉及到nfc_jni_native_date结构体的定义在com_android_nfc.h
nat = (nfc_jni_native_data*)malloc(sizeof(struct nfc_jni_native_data));
if(nat == NULL)
{
ALOGD("malloc of nfc_jni_native_data failed");
return FALSE;
}
memset(nat, 0, sizeof(*nat));
/* Initialize native cached references */
//通过jni 调用java 层的方法
cached_NfcManager_notifyNdefMessageListeners = e->GetMethodID(cls,
"notifyNdefMessageListeners","(Lcom/android/nfc/nxp/NativeNfcTag;)V");
cached_NfcManager_notifyTransactionListeners = e->GetMethodID(cls,
"notifyTransactionListeners", "([B)V");
cached_NfcManager_notifyLlcpLinkActivation = e->GetMethodID(cls,
"notifyLlcpLinkActivation","(Lcom/android/nfc/nxp/NativeP2pDevice;)V");
cached_NfcManager_notifyLlcpLinkDeactivated = e->GetMethodID(cls,
"notifyLlcpLinkDeactivated","(Lcom/android/nfc/nxp/NativeP2pDevice;)V");
cached_NfcManager_notifyTargetDeselected = e->GetMethodID(cls,
"notifyTargetDeselected","()V");
//nfc_jni_cache_object 原型在com_android_nfc.cpp中,有什么作用,做什么动作暂时没有搞清楚?
if(nfc_jni_cache_object(e,"com/android/nfc/nxp/NativeNfcTag",&(nat->cached_NfcTag)) == -1)
{
ALOGD("Native Structure initialization failed");
return FALSE;
}
if(nfc_jni_cache_object(e,"com/android/nfc/nxp/NativeP2pDevice",&(nat->cached_P2pDevice)) == -1)
{
ALOGD("Native Structure initialization failed");
return FALSE;
}
TRACE("****** Init Native Structure OK ******");
return TRUE;
}
Setp3:解析/etc/nfcee_access.xml,NfceeAccessControl.java主要用来解析nfcee_access,xml并做一些证书和安全方面的check。nfcee_access.xml的文件内容:
我的理解nfcee_access.xml是用来控制一些Apps对NFC的访问的,可能用于手机钱包,手机支付等安全性要求高的应用中。不知道对不对,欢迎探讨。
tatic{
registerService(NFC_SERVICE, new ServiceFetcher() {
public Object createService(ContextImpl ctx) {
return new NfcManager(ctx);
}});
}
在NfcManager的构造函数中,调用了NfcAdapter.getNfcAdapter(context),创建NFC Adapter。
public static synchronized NfcAdapter getNfcAdapter(Context context) {
……
sService = getServiceInterface();//获取NFC服务接口
……
try {
sTagService = sService.getNfcTagInterface();//获取NFC tag服务接口
} catch (RemoteException e) {
}
……
NfcAdapter adapter = sNfcAdapters.get(context);
if (adapter == null) {
adapter = new NfcAdapter(context);
sNfcAdapters.put(context, adapter);
}
return adapter;
}
private static INfcAdapter getServiceInterface() {//获取NFC服务接口
IBinder b = ServiceManager.getService("nfc");
if (b == null) {
return null;
}
return INfcAdapter.Stub.asInterface(b);
}
我们看看getServiceInterface()方法,调用ServiceManager.addService()将NfcAdapterService的实例添加到系统的服务列表中,这里我们调用ServiceManager.getService(“nfc”)获取到了服务端的NfcAdapterService对象的实例。
以上部分转自:
NFC framework introduce(一)