[NFC]NFC启动流程2

本文深入探讨NFCService的启动过程,涉及TagService、NativeNfcTag、ScreenStateHelper、NativeNfcManager等关键组件的工作原理,阐述了NFC在Android系统中的框架结构和交互方式,为理解NFC功能的实现提供了详细解析。
摘要由CSDN通过智能技术生成

正式进入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
  • 0
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值