前面介紹過NFC相關的Spec後,從本章節開始,將進入Android AOSP NFC Frameworks部分的學習。
代碼主要的路徑存放在:
Android5.0\packages\apps\Nfc 包含以下目錄:
Assets:含start.png
etc:nfcee_access實例
nci:nci規範中的接口和驅動
nxp:nxp芯片對應的接口和驅動
res:app用到的圖片,字串資源等
src:主要代碼流程
tests:Google提供的部分測試程序
Android5.0\packages\apps\Settings\src\com\android\settings\nfc是Setting中關於NFC的代碼。
NFC Application的啓動不同於Wi-Fi及Wi-Fi P2P等service。
NFC Application對應的AndroidManifest.xml文件中含有關鍵信息如下:
<applicationandroid:name=".NfcApplication" android:icon="@drawable/icon" android:label="@string/app_name" android:theme="@android:style/Theme.Material.Light" android:persistent="true" android:backupAgent="com.android.nfc.NfcBackupAgent" android:killAfterRestore="false" >
此處就涉及到android application啓動的機制。此處不詳細的分析,列舉對應的代碼,方便大家學習:
Android5.0\frameworks\base\services\core\java\com\android\server\am\ActivityManagerService.java
public void systemReady(final RunnablegoingCallback) { .... if (mFactoryTest !=FactoryTest.FACTORY_TEST_LOW_LEVEL) { try { List apps =AppGlobals.getPackageManager(). getPersistentApplications(STOCK_PM_FLAGS); if (apps != null) { int N = apps.size(); int i; for (i=0; i<N; i++){ ApplicationInfoinfo =(ApplicationInfo)apps.get(i); if (info != null && !info.packageName.equals("android")) { addAppLocked(info, false, null /* ABI override */); } } } } catch (RemoteException ex) { // pm is in same process,this will never happen. } } ... }
繼續分析addAppLocked()
final ProcessRecordaddAppLocked(ApplicationInfo info, boolean isolated, String abiOverride) { ... if (app.thread == null &&mPersistentStartingProcesses.indexOf(app) < 0) { mPersistentStartingProcesses.add(app); startProcessLocked(app, "addedapplication", app.processName, abiOverride, null /* entryPoint */, null /*entryPointArgs */); } ... }
最終會call到NfcApplication.java中的NfcApplication()構造函數,其中的onCreate()會被調用到。
@Override public void onCreate() { super.onCreate(); boolean isMainProcess = false; // We start a service in a separateprocess to do // handover transfer. We don't want toinstantiate an NfcService // object in those cases, hence checkthe name of the process // to determine whether we're the mainNFC service, or the // handover process ActivityManager am =(ActivityManager)this.getSystemService(ACTIVITY_SERVICE); List processes =am.getRunningAppProcesses(); Iterator i = processes.iterator(); while (i.hasNext()) { //檢查當前運行的App名字是否爲"com.android.nfc",如果名字相同,則表示當前啓動的程序是主程序 RunningAppProcessInfo appInfo =(RunningAppProcessInfo)(i.next()); if (appInfo.pid == Process.myPid()){ isMainProcess = (NFC_PROCESS.equals(appInfo.processName)); break; } } if (UserHandle.myUserId() == 0&& isMainProcess) {</span> //啓動NfcService mNfcService = new NfcService(this); HardwareRenderer.enableForegroundTrimming(); } }
當調用了new NfcService()之後,後面會依次創建各個Service。
在進行後續分析前,簡單的列舉一下NFC的類圖,方便後續的理解:
上層APP主要透過調用android.nfc.tech及android.nfc的接口來實現期望的功能;而android.nfc.tech和android.nfc透過AIDL的方式調用到NfcService中的接口。Framework中NfcService透過JNI與底層NFC Driver進行溝通,實現發送命令和接收event功能。
在進入NFCService.java前,需要對整個系統的架構有個初步的瞭解。
DeviceHost.java定義了目前幾乎NFC需要的全部interface和API。不同的廠家依據DeviceHost.java提供的interface,實現對應的內容,就可以和上層app進行溝通了。