Galaxy Note 也升級 Android 4.0 了

某天早上打開 Kies 的視窗時, 赫然發現 Note 已經有新的韌體可以升級了. 點進去一看, 果然是Android 4.0. 我一時手癢, 就叫 Kies 幫我安裝. 結果這個安裝時間大概有 50 分鐘左右, 又不能拔線, 害我上班差點遲到.

新的手機長相和原來差不多, 倒是把我原來排好的 widget 全部改為預設值, 等於我先前白忙了一場. 完整的升級 “開箱文" 請參考這一篇: 三星Galaxy Note終於可以升上Android 4.0版了,趕快來升級吧!

升了 4.0 之後, 當然我最關心的是多了什麼好東西?最大的發現有兩個:

首先就是 “臉部解鎖" 不太好用. 在燈光充足的狀況下, 辨識率還算 OK, 畢竟我一天之內也不會變太多. 不過到了光線暗的地方就不行了, 一句 “找不到臉孔" 或是 “抱歉!不認識你.",  就得 key in PIN 或是畫綠色矩陣上的圖形解鎖.

為了增加辨識率, Android 的設定 → 安全性裡面有一個改善臉部辨識的選項, 每重新訓練一次, 就要再輸入一次 PIN, 其實真是有點煩. 難道就不能來個 “訓練 10 連拍", 讓我有機會把表情做足, 或每付眼鏡都換一次嗎?這裡還有很多改進空間, 目前只能算是噱頭.

第二個重點就是: 設定 / 儲存空間 / 裝置記憶體 / 總空間變成 1.97GB 了. 我記得它的規格就是 1GB, 以前看也是 1GB, 升級後竟然變成 2GB 了. 而這 2GB 已經用掉了 1.5GB, 也就是我還是只剩下 516 MB 可以用. 所以我猜這是 bug 吧!

Android Thread Safe / Lock Free / Atomic 小註解

Atomic (原子) 通常是指一個指令不會被打斷, 例如一道組合語言的指令, 在沒有執行完之前, 就是 ISR (interrupt service routine) 也無法干擾其結果. 同樣的概念如果放到 function 上, 就很難說這個 function 從來都沒有打斷過了. 我們頂多說這個 function 的結果是如預期的.

怎麼樣保證如預期呢?在 Android 當中的 atomic.c 採用暴力的方法進行, 例如要做一個 write.

void android_atomic_write(int32_t value, volatile int32_t* addr) 顧名思義想把 value 寫到這個 addr,  而它裡面的內容就是:

{

int32_t oldValue;

do {

oldValue = *addr;

} while (android_atomic_cmpxchg(oldValue, value, addr);

只要 OldValue 沒有 value, 這個 loop 就不善罷干休. 所以一定可以寫成功. 只要成功了, 就準備離開. 大家可以發現, 如果此時別的 thread 也來寫同樣的位置, 那就出事了. 

為了避免後者的狀況發生, 我們最好不允許這個在有效期間之內又被改掉. 解決之道是 lock 此一變數, 直到 unlock 之前, 都不讓別人改寫. 不過 Android 的 atomic 是 lock-free 的, 所以不需要用 lock. 相對地, 它讓其他的 thread 不會影響到當前的 thread, 也就是確保 thread safe.

怎麼做到 lock free, thread safe 呢, 簡單地說就是避免使用全域變數 (global variable), 只用區域變數 (local variable 或 auto variable). 此時每個 thread 都只針對自己的記憶體空間操作, 就不會影響到別人了.

此外, 我們可以指定哪些變數必須是 automic 的, 例如宣告成:AtomicBoolean, AutomicInteger, AutomicLong, AutomicIntegerFieldUpdate<T> …等等就有保護作用. 這些描述在 java.util.concurrent,automic.

當然, Android 還是有 lock, class 是 java.util.concurrent.locks.

[ref]

1. Android SDK

2. Lock-free atomic operations in Android

3. Thread-Safe的理解與分析

Android 執行應用程式的方式

Android 執行應用程式的方式大概有三種, 直接從 Native Service Binder 呼叫 HAL Library, 或是透過 Native Service / Daemon 來呼叫. 如果只用一張圖表示, 它長成下面這樣.

其中 Native Serice Binder 若直接呼叫 HAL Library, 相當於 Application 用 Binder IPC 呼叫 Run-time Service.

Application Framework 和 Library 這兩層包括的東西, 還是直接看標準版的 Android System Architecture 圖最容易了解, 再次貼在後面.

Android Function Call:

Android System Architecture:

[note]

1. IPC = Inter-Process Communication.

2. JNI = Java Native Interface

Quadrant Benchmark 小註解

 Quadrant  是 Aurora 公司推出的軟體, 功能是測量 Android 系統的效能. 相較於 Windows 有官方的性能評分工具, 但是分數的間距很小; Quadrant 比較像是 3D Mark 那樣, 能夠給出比較拉得開的分數. 除了總分, 也可以對 CPU, Memory, IO, 2D 和 3D 做出評價 (Advanced 以上的版本).

假如不用 Quadrant, 有沒有其它的代替方案呢? 有, 前三名還包括 Linpack 和 Neocore. 據說 CF-Bench 也可以測多核心 Android 系統的效能, 差別在於它不測 GPU.

只要用 Google 圖片去 search quadrant, 就可以看到很多 “第一名" 自拍. 我看到最厲害的是 3278 分. 客官啊, 這個 bench mark 的 bench mark 是 1 千多分, 破 3000 分是怎麼來的呢? 原來是有人破解了 Qudrant 的計分標準. 它的罩門在於 IO 速度這一項.

這位 Cyanogen 老兄發現, 只要把 Qadrant 測試用的目錄, 設在用 memory 模擬的 file system 下面, 就可以靠著 IO 方面的優勢, 獲得不可思議的高分. 引用 WIKI 的說明, 下面原文中提到的 tmpfs, 就是用 mount -t tmpfs -o size=1G, nr_inodes=10k, mode=0700 tmpfs /space 之類的指令, 把 1GB 的記憶體, 指定給 space 這個目錄夾使用. Quadrant 拿這個資料夾去測 IO, 當然就不察而給予過度高估的評價.

In Cyanogen’s tweet, he says he was able to exploit the flaw to get obscenely high Quadrant benchmark scores by mounting “a tmpfs over quadrant’s data directory.” A tmpfs, or temporary file storage system, can artificially inflate a device’s I/O score and provide unreal benchmark improvements.

這篇文章的原作者提到, 既然 Qadrant 有 bug, 所以參考意義不大. 不過我想到如果各家廠商要 PK Qadrant 的時候, 說不定也可以用這個技巧來欺騙對手…哈!

[ref] http://briefmobile.com/cyanogen-demonstrates-quadrants-flaws

Android Market 的運作機制

當我們從 Android Market 買一個 Application 的時候, Market 的 client 就會去問 server, 這個 application 對於這個 user 的狀態是什麼? 此外, 這個狀態不只是付費了沒有? 而是包括了詳盡的特殊條件 (custom constraints), 比方說只是試用一段時間、只能裝在特殊的平台…等等的 policy.

當 application 在 check status 的時候, 會產生一對 RSA key 來做加解密. Public key 會存在 myApp.apk 裡面, private key 用來與 server 溝通. 當 Application 想要知道它的license status, 它可以 call License Verification Library (LVL) 裡面帶有 callback function 的 library checker method.

Market client 負責與 market server 溝通, 它會收集 Google Account username, 手機的 (International Mobile Subscriber Identity), 和其他資訊送給 server 確認. Server 檢查過 user 資料, 並且檢查過購買紀錄之後, 就以 call back function 把 license 的狀態傳回給 client.

在 Java 的理想下, 一隻 AP 可以 write once, run everywhere. 不過前提依然是要能夠賺錢. 不收錢的軟體, Android Market 就不需要動用 license 檢查的機制的, 但對於收費軟體,  Android Market 讓花功夫寫軟體的人, 可以保障他的權利, 只要這個軟體是透過 Android market 所發佈的. 為了追蹤合法性, Android market client 必須要先在 host 上面跑 Android 1.5  以後的版本.

為了要確認 license 的狀態, Android 必須要上網, 或者是記住 (cache) 上次上網的狀態.

[ref] http://developer.android.com/guide/publishing/licensing.html