Hacking Firefox OS Emulator for RIL

《Mo語》:「不學 Emulator 無以 test;不寫 test 無以 land!

之前我們介紹過 Firefox OS Emulator,也聊過如何使用 Marionette 來為 Firefox OS 寫測試項;今天我們來研究一下如何為模擬器新增功能來協助開發 RIL (Radio Interface Layer) 相關的測試項。Firefox OS 基於 Gonk,利用 Gonk 所提供的功能以完成對 Web Apps 的服務,RIL 更是作為手機最重要的一項。Firefox OS RIL 利用 gecko/dom/system/gonk/ril_worker.js 與 Gonk 上的 rilproxy/rild 溝通,rild 在模擬器 target 的環境下則利用 qemud 向 host 端下命令。修改模擬器讓我們得以不需要硬體也能測試,甚至電信商沒有佈建的功能也照測不誤!是故:

《Mo語》:「寫 code 務 test,test 立則 awesome!

以下介紹兩種常用的作法。其一,以 Bug 785988 為例,示範新增一組模擬器命令;其二,以 Bug 788191 為例,示範新增一個模擬器的 SIM 卡檔案。

首先,在 Bug 785988 當中,電信網路所播送的服務商長短名可能是空字串而造成一些誤判。在現實生活中,我們很難能夠就這類的問題加以複製並測試,好在 Firefox OS 有模擬器,真的好放心!我們希望能為模擬器加上一個功能,讓我們能隨心所欲地變更服務商資訊,讓我們得以更廣泛地測試相關或潛在的問題。Marionette 內建的 runEmulatorCmd API[1] 在於模擬器上的進入點位於 external/qemu/android/console.c,如同 commit dba99ea 所示,在 main_commands 之下新增一個群組,並為它加入一些子命令:

static int do_operator_set( ControlClient client, char* args ) { ... }

static const CommandDefRec  operator_commands[] = { ... };

static const CommandDefRec   main_commands[] = {   ... { "operator", "manage telephony operator info", "allows you to modify/retrieve telephony operator info\r\n", NULL, NULL, operator_commands }, ... };

每一個 command handler 應該要解析 args 所示的命令內容,也都可以透過 ControlClient 來向 console 回報訊息。android_modem 是目前單一 SIM 卡架構下的 Modem 物件指標,對 Emulator Modem 的控制都應該透過它。

之後在 external/qemu/telephony/android_modem.c 實作功能:

void amodem_set_operator_name( AModem  modem, ANameIndex  index, const char*  buffer, int  buffer_size ) { ... }

別忘了在變更設定後,可能需要通知 Firefox OS 目前的連線狀態已變更:

// Notify device through amodem_unsol(...) amodem_set_voice_registration(android_modem, amodem_get_voice_registration(android_modem));

最後可以在測試項裡頭使用這個熱騰騰的命令來對所作的修改作全面的測試。

sendEmulatorCommand("operator set " + which + " " + longName + "," + shortName);

---

接著,第二實作講到 Bug 788191,我們需要提供額外的、SIM 卡上的資訊給 Web App,讓它們能對一些必要的狀況作處置。我們需要回傳一個名為 Service Provoider Name 的檔案內容,在 Firefox OS 上,這段支援也當然是實作在 ril_woker.js 這個檔案裡。同樣地,測試的功夫不能少。有詩為證:

《Mo詩》:「test 之罄矣,維 committer 之恥!

在模擬器裡頭主管 SIM 卡檔案功能在 external/qemu/telephony/sim_card.c,最後的函式 asimcard_io 內含所有支援的檔案。在 Firefox OS RIL 的開發過程中,各方標準文件將一直是最佳枕邊讀物,明確地註明出處章節對於後繼的開發者有著妙不可言的功效。

// Service Provider Name(6F46): //   Display Condition: 0x1, display network name in HPLMN; display SPN if not in HPLMN. //   Service Provider Name: "Android" // @see 3GPP TS 31.102 section 4.2.12 EFspn (Service Provider Name) // @see 3GPP TS 51.011 section 9.4.4 Referencing Management { "+CRSM=192,28486,0,0,15", "+CRSM: 144,0,000000116f4604000aa0aa01020000" }, { "+CRSM=176,28486,0,0,17", "+CRSM: 144,0,01416e64726f6964ffffffffffffffffff" },

打完收工。

Hacking Firefox OS Emulator for RIL