vold小記

  • 根據 /system/etc/vold.fstab 去monitor可移除裝置。dev_mount label 掛載點 auto或第n個partition /sys下的路徑,要扣掉/sys
  • NetlinkManager以netlink和kernel建立溝通管道以取得裝置insert/remove事件並做處置(NetlinkHandler)。
  • NetlinkHandler內實際上是呼叫VolumeManager做進一步處理
  • VolumeManager
    1. 管理的是Volume,DirectVolume是其子類別,這裡用了template pattern
    2. 負責mount/umount/share/unshare/format以及secure container
  • 以CommandListener去listen以接收指令,也就是跟上層溝通的管道。(CommandListener, VoldCommand, Process, ResponseCode)。
  • Volume/DirectVolume::mountVol 看來是個適合填 android usb gadget 所需資訊的地方。因為
    1. 有檢查狀態
    2. 可知道是哪一個partition或disk
    3. 可得知insert/remove狀態
  • 需要/dev/device-mapper,所以kernel要把此部份打勾。這邊的設定還蠻多的:
    CONFIG_MD=y
    CONFIG_BLK_DEV_DM=y
    CONFIG_DM_DEBUG=y
    CONFIG_DM_CRYPT=y
    CONFIG_DM_UEVENT=y
    CONFIG_CRYPTO_AEAD=y
    CONFIG_CRYPTO_AUTHENC=y
    CONFIG_CRYPTO_CBC=y
    CONFIG_CRYPTO_PCBC=y
    CONFIG_CRYPTO_HMAC=y
    CONFIG_CRYPTO_MD5=y
    CONFIG_CRYPTO_DES=y
    CONFIG_CRYPTO_TWOFISH=y
    CONFIG_CRYPTO_TWOFISH_COMMON=y

參考資料:

Airplane mode

在追bug時,去Trace的結果,後來發現如果Phone的RIL層有問題的話,會造成看起來沒有進Airplane mode但實際上卻已經進去的奇怪現象 。Android裡,選Airplane mode以後會發生的事情:

  1. AirplaneModeEnabler送broadcast message出來。有3個人會收到:1.wifi 2.bluetooth 3.Phone。wifi 跟 bluetooth 裡收到訊息以後的處理都很簡單,Phone 裡主要是呼叫 phone.setRadioPower() 這行 (Packages/apps/Phone/src/com/android/phone/PhoneApp.java)。
  2. 這時候會呼叫 GSMPhone/CDMAPhone 的 setRadioPower,GSMPhone/CDMAPhone 都繼承自 ServiceStateTracker,所以是呼叫 ServiceStateTracker.setRadioPower。
  3. ServiceStateTracker.setRadioPower 會呼叫 setPowerStateToDesired (CdmaServiceStateTracker/GsmServiceStateTracker),實際上又是呼叫 cm.setRadioPower
  4. cm 的型別是 CommandsInterface,只有 RIL 有實作此 interface (frameworks/base/telephony/java/com/android/internal/telephony/RIL.java)。自此,訊息往下丟到 RIL daemon,參照 reference-ril 裡的 setRadioState,之後處理完會回傳 RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED。
  5. RIL.java 的 processUnsolicited() 會處理,這邊會呼叫 setRadioStateFromRILInt(),setRadioStateFromRILInt()裏面又再呼叫 setRadioState (frameworks/base/telephony/java/com/android/internal/telephony/BaseCommands.java),這裡會去 notify,所以根據 mRadioStateChangedRestrants 找 registerForRadioStateChanged()
  6. 找 registerForRadioStateChanged 的結果,可以看到 GsmServiceStateTracker/CdmaServiceStateTracker 有去呼叫。再看 ServiceStateTracker 裡的 handler 去處理 EVENT_RADIO_STATE_CHANGED 的部份:setPowerStateToDesired() => pollState() => pollStateDone(),pollStateDone() 裏面就可以看到有用 phone.notifyServiceStateChanged(),notifyServiceStateChange 又是呼叫父類別的 notifyServiceStateChangedP()。
  7. notifyServiceStateChangedP() 呼叫 mNotifier.notifyServiceState。mNotifier 則是 DefaultPhoneNotifier,再看 DefaultPhoneNotifier,裏面就有 registry.notifyServiceState() (TelephonyRegistry.java),這會再呼叫 broadcastServiceStateChanged()。從這裡的 TelephonyIntents.ACTION_SERVICE_STATE_CHANGED 去找,可以發現只有 PhoneStateIntentReceiver 有收這個 broadcast message。
  8. PhoneStateIntentReceiver 會再去 sendMessage。AirplaneModeEnabler 裡就有使用 PhoneStateIntentReceiver,並註冊了自己的 handler,所以 AirplaneModeEnabler 最後就會收到,並且改變項目的狀態。

這段過程幾乎都是以非同步的方式在傳遞,並不是平鋪直敘的,所以我看了好幾次才確定是這麼一回事…沒邊寫邊記的話,恐怕會多繞好幾天…

電影流水帳(2010/11/12~2010/12/31)

今年只看了 61.5 部片,很遺憾,沒達成百片的目標,”The Experiment”看到一半,就沒看了,明年要找時間來看完。

  • Akeelah and the Bee(IMDB, Wikipedia)。英文老師在課堂上放映的,主要是讓我們去學要怎麼背單字。裏面介紹很多背法,像是用節奏、玩cross word、語源、發音…等等,很值得參考。一個黑人的小女孩,因為死去的父親的關係,對於背單字相當的有興趣,在某次意外裡,被抓去參加學校拼字比賽,因此被發掘。後來就跟學校方面達成協議,繼續參加地區性的比賽。比賽跟練習的過程裡,他認識了志同道合的朋友,建立的自信心,也跟到了好老師,學到很多東西,後來幫老師解除了心裡的結。家裡的問題,差點讓她沒辦法繼續下去,在媽媽看到她的表現之後,化解了母女間的隔閡。最後當然是有了圓滿的結局,跟原本是對手的朋友一起得到了冠軍。

竹取js

雖然官方的網頁上是日文,我看不太懂,不過好在他提供的範例很容易了解,看來是不難用。
如果想要用 gtk+webkit+竹取js 來顯示直書,問題大概就會出在翻頁上了。用Space/Shift+Space 或 PgUp/PgDown 都可以翻頁,但如果想改變某些按鍵的行為,如 h/l 、Left/Right、Up/Down 來做翻頁的話,可能就要再找資料來看了。
想用這來改寫pymbook看看。

fcrackzip

正愁不知道怎麼破解密碼,就丟 ubuntu brute zip password extract 這些字到 google 去找,想不到立馬就找到Ubuntu Geek上的這篇:Howto Crack Zip Files Password,用 apt-get 就可以裝好。
使用也很簡單 fcrackzip your_file.zip 就行了。要縮小範圍的話,可以參考 -h 的說明,指定參數來縮小範圍、加快解密的速度。

Lettering.js

剛好看到,就連上去 Lettering.js 看了一下,不覺得有什麼特別的。
看了原始碼,就只有看到呼叫 $(“.your_class”).lettering(); 而已,實在是很簡單,但是網頁上的效果卻又不是圖檔或是flash。再更仔細看網頁的 css 之後,發現有 .char1, .char2….或是 .word1, .word2…等的定義。啊~看來這就是關鍵了,只要你的 css 裡有定義這些 class,再呼叫 .lettering() 之後,lettering 就會幫你把這些 class 套用到 jquery selector 選取的字或詞(參數帶 ‘word’)上。
真的是挺方便的 jquery plugin。

pdftotext win32

幫朋友試的,轉 pdf 為文字檔。本來是要用 pdfbox 跟 iTextSharp 的,無奈 pdfbox 編譯不出 .net 的 dll,而 iTextSharp 的 model 又太複雜。

Linux 下的 pdftotext 正巧是可以轉的,所以首要就先找 win32 版本的。pdftotext 由兩個套件提供,一個是 xpdf,另一個是 poppler,目前 ubuntu 預設是使用 poppler。但是 popper 卻沒有善心人事編譯出 win32 的版本,只有 xpdf 有 (gnuwin32提供)。

所以就先下載來安裝,裝完以後,就有 pdftotext 指令可用,但是轉換時,卻轉不出中文。參考 pdftotext 的使用說明,發現有 -enc 選項可用,但指定以後,卻會出現

Error: Couldn't find unicodeMap file for the 'cp950' encoding
Error: Couldn't get text encoding

看來是少了檔案。
xpdf 官方網頁上有提供 xpdf-chinese-traditional.tar.gz,印象中,linux 下使用時,通常也是要再額外安裝才可以看到中文。那麼,就下載來使用吧。下載以後,把檔案解開放到 C:\Program Files\GnuWin32\share\xpdf\chinese-traditional 下,然後修改 C:\Program Files\GnuWin32\etc\xpdfrc ,加上這幾行:

#----- begin Chinese Traditional support package (2004-jul-27)
cidToUnicode	Adobe-CNS1	c:\progra~1\gnuwin32\share\xpdf\chinese-traditional\Adobe-CNS1.cidToUnicode
unicodeMap	Big5		c:\progra~1\gnuwin32\share\xpdf\chinese-traditional\Big5.unicodeMap
unicodeMap	Big5ascii	c:\progra~1\gnuwin32\share\xpdf\chinese-traditional\Big5ascii.unicodeMap
cMapDir		Adobe-CNS1	c:\progra~1\gnuwin32\share\xpdf\chinese-traditional\CMap
toUnicodeDir			c:\progra~1\gnuwin32\share\xpdf\chinese-traditional\CMap
#----- end Chinese Traditional support package

這樣設定就完成了。
使用的時候就可以用 “c:\Program Files\GnuWin32\bin\pdftotext.exe” -cfg c:\progra~1\gnuwin32\e
tc\xpdfrc -enc Big5 your_file.pdf your_file.txt 來進行轉換了。

註:我是 xpdf 的 setup 檔來安裝,所以會裝到 c:\program files\gnuwin32 下,若你是用.zip檔,那麼路徑請自行調整。

Android Build Number

Settings > About Phone > Build number 跟 TARGET_BUILD_VARIANT 有關係。
如果 TARGET_BUILD_VARIANT 為空,那麼,顯示出來的會是一串長長的字串,由很多東西所組成。
如果 TARGET_BUILD_VARIANT 的值是 user,那麼,顯示出來的字串會依 DISPLAY_BUILD_NUMBER (true/false)來決定是只有 BUILD_ID 或 BUILD_ID + BUILD_NUMBER。(參考 build/core/Makefile)
那麼要怎麼自訂 BUILD_ID 或 BUILD_NUMBER 呢?照理說,應該是要在 buildspec.mk 裡定義,但是在 build/core/config.mk 裡,include buildspec.mk 之後,又 include 了 envsetup.mk 跟 BoardConfig.mk,envsetup.mk 裡有 include version_defaults.mk,這裡有 include build_id.mk 會把之前定義的 BUILD_ID 跟 BUILD_NUMBER 都覆蓋掉。所以比較適合的地方是 device 下的 BoardConfig.mk,只是這樣有個小缺點,就是 make 時,顯示出來的資訊是 build_id.mk 裡定義的。
以上,都是參考 build 下的檔案。