正式进入NFCService.java,开始NFC framework探索, jiu~~~~
接上篇文章内容,进入NfcService后,就开始启动各种Services,Hold on,一大波代码马上到来:
{
mUserId = ActivityManager.getCurrentUser();
mContext = nfcApplication;
//@paul: Tag相关; extend INfcTag;最终调用到NativeNfcTag
mNfcTagService = new TagService();
//@paul: 上层APP 调用 NFC 功能时, 中间变量adapter;extend INfcAdaptor;最终调用到NfcAdaptor
mNfcAdapter = new NfcAdapterService();
Log.i(TAG, "Starting NFC service");
sService = this;
//@paul: NFC与屏幕解锁的关系,含OFF / ON_LOCK / ON_UNLOCK
mScreenStateHelper = new ScreenStateHelper(mContext);
mContentResolver = mContext.getContentResolver();
//@paul: 底层Driver 相关的JNI 接口
mDeviceHost = new NativeNfcManager(mContext, this);
//@paul: 还不懂
mNfcUnlockManager = NfcUnlockManager.getInstance();
//@paul: 和handover 相关接口;主要是bluetooth, 实际上wifi 也是可以实现的
mHandoverManager = new HandoverManager(mContext);
boolean isNfcProvisioningEnabled = false;
try {
isNfcProvisioningEnabled = mContext.getResources().getBoolean(
R.bool.enable_nfc_provisioning);
} catch (NotFoundException e) {
}
//@paul: 设备是否在setup wizard阶段支持接收NFC 数据
if (isNfcProvisioningEnabled) {
mInProvisionMode = Settings.Secure.getInt(mContentResolver,
Settings.Global.DEVICE_PROVISIONED, 0) == 0;
} else {
mInProvisionMode = false;
}
//@paul: 收到NFC 消息处理流程, 最终调用到dispatchTag()
mNfcDispatcher = new NfcDispatcher(mContext, mHandoverManager, mInProvisionMode);
//@paul: 基于LLCP 连接的服务,含NdefPushService/SnepService/P2pEventManager
//@paul: 此类会定义doPut/doGet, 后续还会提到
mP2pLinkManager = new P2pLinkManager(mContext, mHandoverManager,
mDeviceHost.getDefaultLlcpMiu(), mDeviceHost.getDefaultLlcpRwSize());
//@paul: 获取shared_pref 信息,一般存储位置在/data/data/<包名>/shared_prefs
mPrefs = mContext.getSharedPreferences(PREF, Context.MODE_PRIVATE);
mPrefsEditor = mPrefs.edit();
//@paul: 和security相关,主要是读取解析/etc/nfcee_access.xml文件
mNfceeAccessControl = new NfceeAccessControl(mContext);
mState = NfcAdapter.STATE_OFF;
//@paul: 依prefs 文件定义,检查NdefPush 是否enable
mIsNdefPushEnabled = mPrefs.getBoolean(PREF_NDEF_PUSH_ON, NDEF_PUSH_ON_DEFAULT);
setBeamShareActivityState(mIsNdefPushEnabled);
mIsDebugBuild = "userdebug".equals(Build.TYPE) || "eng".equals(Build.TYPE);
//@paul: 电源管理模块,主要是屏幕状态与NFC 是否响应有关系
mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
//@paul: 获取WakeLock
// 步骤:1.获取powermanager 实例
// 2.生成实例: new WakeLock
// 3.通过acquire() 获取锁
mRoutingWakeLock = mPowerManager.newWakeLock(
PowerManager.PARTIAL_WAKE_LOCK, "NfcService:mRoutingWakeLock");
//@paul: 屏幕锁
mKeyguard = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
mScreenState = mScreenStateHelper.checkScreenState();
//@Paul: 将NFC 加入到系统service中
ServiceManager.addService(SERVICE_NAME, mNfcAdapter);
// Intents for all users
//@paul: 注册屏幕亮/灭,用户激活和切换
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
filter.addAction(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_USER_PRESENT);
filter.addAction(Intent.ACTION_USER_SWITCHED);
registerForAirplaneMode(filter);
mContext.registerReceiverAsUser(mReceiver, UserHandle.ALL, filter, null, null);
IntentFilter ownerFilter = new IntentFilter(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
ownerFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
mContext.registerReceiver(mOwnerReceiver, ownerFilter);
//@paul: 关注程序安装和卸载
ownerFilter = new IntentFilter();
ownerFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
ownerFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
ownerFilter.addDataScheme("package");
mContext.registerReceiver(mOwnerReceiver, ownerFilter);
updatePackageCache();
PackageManager pm = mContext.getPackageManager();
//@paul: 判断系统是否支持卡模拟
mIsHceCapable = pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION);
if (mIsHceCapable) {
mCardEmulationManager = new CardEmulationManager(mContext);
}
mForegroundUtils = ForegroundUtils.getInstance();
//@paul: 开始执行NFC , 参数TASK_BOOT
new EnableDisableTask().execute(TASK_BOOT); // do blocking boot tasks
}
看完这么多的代码,是不是还不确定各个部分的意义。没有关系,继续挖。
1. TagService
此部分实现的接口都在INfcTag.aidl中定义,接口如下:
{
int close(int nativeHandle);
int connect(int nativeHandle, int technology);
int reconnect(int nativeHandle);
int[] getTechList(int nativeHandle);
boolean isNdef(int nativeHandle);
boolean isPresent(int nativeHandle);
TransceiveResult transceive(int nativeHandle, in byte[] data, boolean raw);
NdefMessage ndefRead(int nativeHandle);
int ndefWrite(int nativeHandle, in NdefMessage msg);
int ndefMakeReadOnly(int nativeHandle);
boolean ndefIsWritable(int nativeHandle);
int formatNdef(int nativeHandle, in byte[] key);
Tag rediscover(int nativehandle);
int setTimeout(int technology, int timeout);
int getTimeout(int technology);
void resetTimeouts();
boolean canMakeReadOnly(int ndefType);
int getMaxTransceiveLength(int technology);
boolean getExtendedLengthApdusSupported();
}
以其中connect()函数为例,解释一下此部分的流程和逻辑,其余的函数基本上可以参考connect()函数:
@Override
public int connect(int nativeHandle, int technology) throws RemoteException {
//@paul: 检查manifest中是否有nfc操作权限
NfcPermissions.enforceUserPermissions(mContext);
TagEndpoint tag = null;
//@paul: 判断NFC是否启动,在执行enableInternal()时,条件为真
if (!isNfcEnabled()) {
return ErrorCodes.ERROR_NOT_INITIALIZED;
}
/* find the tag in the hmap */
tag = (TagEndpoint) findObject(nativeHandle);
if (tag == null) {
return ErrorCodes.ERROR_DISCONNECT;
}
//@pau