ByteScope

dumpsys sensorservice

唯讀

手機上的每一個感測器,含廠商、type、取樣率與批次能力,以及一段近期讀數的緩衝。

指令
adb shell dumpsys sensorservice
指令
系統服務(dumpsys)
風險
唯讀

語法

dumpsys sensorservice

範例

  • dumpsys sensorservice

    感測器表,以及每個感測器的近期讀數。

  • getevent -lp

    輸入這一側的另一半:原始的 evdev 裝置,含觸控面板。

輸出怎麼讀

輸出範例

Sensor List:
0x00000001) LSM6DSO Accelerometer | STMicro | ver: 1 | type: android.sensor.accelerometer(1) | perm: n/a | flags: 0x00000000
	continuous | minRate=12.50Hz | maxRate=416.00Hz | FIFO (max,reserved) = (3000, 600) events | non-wakeUp
Accelerometer: last 50 events
	 1 (ts=12345.678901234, wall=13:37:01.234) 0.12, 9.81, 0.03,

每個感測器是一個十六進位 handle、一個右括號,然後是用 `|` 分隔的欄位,接著是一行以 tab 縮排的取樣率與批次資訊。再往下的近期事件緩衝是用感測器的「名稱」而不是 handle 來索引的,而且由新到舊排列。欄位順序在不同版本與不同廠牌之間都不穩定,所以要靠標籤來讀。

輸出欄位

欄位意義
0x…)感測器 handle。這是每個版本都一定會印的那個 token。
type: android.sensor.x(N)平台的 type 字串與它的數值。
minRate / maxRate單位是赫茲——而且命名和直覺相反:minRate 是從最大延遲算出來的,maxRate 是從最小延遲算出來的。
FIFO (max,reserved)以事件數表示的批次容量。沒有批次能力時會改印 `no batching`。
wakeUp / non-wakeUp這個感測器能不能把手機從休眠喚醒。
ts=boot time 時鐘的秒數,經過一次休眠後在緩衝裡可能不是單調遞增的。
[value masked]呼叫方沒有那個感測器需要的權限;讀數是被遮住而不是不存在。

需要什麼權限

`SensorService` 是原生的,所以它的檢查不是常見的 Java 那套:`SensorService::dump` 向 `PermissionCache::checkCallingPermission` 要 `android.permission.DUMP`,那個權限 Shell 套件有,失敗時它會在清單該在的位置補上一行拒絕。看感測器表不需要 root。它上面還有第二道比較安靜的關卡,而那才是會讓你困惑的那一道。在同一個函式裡,`privileged` 是用 `getCallingUid() == 0` 算出來的——只有 root,沒有別人。`adb shell` 跑起來是 uid 2000,所以它永遠不是 privileged,於是每一個 `getRequiredPermission()` 非空的感測器,它的近期事件緩衝都會被切成遮蔽格式。沒有東西被拒絕,也不會印任何警告:時間戳照樣在,而數值該在的位置寫的是 `[value masked]`。那不是讀不到的讀數、不是睡著的感測器、也不是壞掉的驅動程式,而且重跑不會有任何改變。這是這一頁上唯一 `adb root` 會改變的東西,而正式版上 `adb root` 會被拒絕,所以在零售機上被遮住的感測器就是一直被遮著。感測器表本身——handle、廠商、取樣率、批次能力——永遠不會被遮,這也是 Android Sensor Tester 能用一個普通 shell 就把清單建起來的原因。

失敗訊息對照

訊息意義
Permission Denial: can't dump SensorService from pid=4821, uid=10231這是原生程式碼,所以它**沒有** Java 那些 dump 的重複 `from from`,也不會指名缺了哪個權限——請把它當成自己的一組字串來比對。它被接在結果緩衝後面,所以會從標準輸出出現、而且是取代感測器清單,這也是為什麼它乍看之下像一台沒有感測器的手機。
No Sensors on the device服務手上一個感測器都沒有時印的,緊接著一行 `devInitCheck : <n>` 帶著感測器裝置自己的初始化狀態。那裡是負值代表某個硬體層根本沒起來,回的是一個 errno——這和一份真的沒有任何感測器的模擬器映像是完全不同的問題,而且從這份輸出裡只能靠它把兩者分開。
Can't find service: sensorservice在服務被接觸到之前,就由 `dumpsys` 這支程式印到標準錯誤:service manager 裡沒有 `sensorservice` 這一項。開機期間很正常。因為它走標準錯誤,一次沒帶 `2>&1` 的收集會得到一份空清單,而且裡面沒有任何地方解釋原因。
*** SERVICE 'sensorservice' DUMP TIMEOUT (10000ms) EXPIRED ***十秒是 `dumpsys` 的預設,而這份 dump 在走過每個感測器與每個近期事件緩衝時,會持有服務的連線鎖。活下來的是輸出的開頭——感測器表;失去的是尾巴,也就是近期事件。被截斷的 dump 仍然是一份可用的清冊,但不是一份可用的讀數樣本。

版本與廠商注意事項

  • 文字版輸出已經很多個版本都不印最大量程、解析度與耗電了。平台 API 與 proto 格式裡有,所以會顯示它們的版本是廠商改過的。
  • 兩個同名的感測器會讓近期事件緩衝的對應變得有歧義,而錯誤的對應會把讀數畫到別的感測器上。
  • 這是這一家族裡最不穩定的一份輸出:它的文字由好幾個不同元件各自組出來,中間沒有共用的結構定義。

這個我們有 UI

Android Sensor Tester 會透過 USB 執行這個指令並解析回應——只要 Chromium 系瀏覽器,不必安裝 SDK,也不會上傳任何東西。

開啟 Android Sensor Tester

相關指令

和 dumpsys sensorservice 會在同一次作業裡出現的指令。

指令做什麼
getevent直接從核心串流原始輸入事件,或列出每個輸入裝置能回報什麼。
dumpsys thermalservice手機是不是正在因為溫度而降速,以及硬體層回報的每一個溫區,單位是攝氏。
wm size回報顯示器的解析度,或覆寫它,讓手機假裝自己是另一塊螢幕。

其他系統服務(dumpsys)指令

指令做什麼
dumpsys battery電池服務目前的狀態:電量、充電狀態、健康度、電壓與溫度。
dumpsys diskstats每個分割區的剩餘空間、一次磁碟寫入延遲的實測,以及一份快取起來的各 app 空間用量。
dumpsys meminfo哪些行程最吃記憶體,量的是 PSS(按比例分攤的用量)。
dumpsys package套件管理員知道的一切:版本、路徑、flags、安裝來源,以及每個使用者的狀態。
dumpsys activity activities現在哪個 app 在前景,以及它背後的 task 與 stack 結構。
dumpsys dropbox平台用來存放當機、ANR 與 tombstone 的環形緩衝——這是不用 root 讀 ANR 追蹤的方法。

這些行為是在撰寫 Web ADB 工具背後的解析程式時,對照 AOSP、toybox 與核心原始碼查證的。真的會因 Android 版本或廠牌而異的地方,這一頁會直接說明,而不是給你一個在半數手機上都是錯的數字。

常見問題

adb shell 指令要怎麼執行?

在手機上打開開發者選項與 USB 除錯、接上線,然後從裝了 platform-tools 的機器執行 adb shell <指令>——或者只執行 adb shell 取得互動提示字元,再直接打指令、不用前綴。如果指令會輸出二進位資料(例如截圖),請改用 adb exec-out 而不是 adb shell:單純的 shell 服務會配一個終端機,而它會改寫換行位元組並毀掉資料。

adb shell 指令需要 root 嗎?

這份參考裡的都不用。它們以 shell 使用者身分執行,可以針對自己的 Android 使用者管理套件、讀取大多數 dumpsys 服務、寫入設定提供者、注入輸入,以及讀取共用儲存空間。需要 root 的是這份參考刻意避開的事:讀取其他 app 的私有資料(除了對可除錯版本使用 run-as)、寫入系統分割區,或直接讀 /data/anr。

為什麼在我的手機上輸出看起來不一樣?

不是 Android 版本就是廠商。有些旗標與欄位是從特定版本才有的,那些都在各指令頁註明了。其餘是廠商改動,而受影響最深的是 dumpsys:一份 dump 是除錯輸出,它的文字就是那個服務的作者最後印了什麼,而廠商既會改它也會把改動往回移植。請用名稱而不是位置來讀欄位,並把沒見過的格式當成差異而不是失敗。

可以用瀏覽器而不是終端機來跑嗎?

很多指令可以——本站的 Web ADB 工具從 Chromium 系桌面瀏覽器透過 WebUSB 和手機對話,不必安裝 SDK,也不會上傳任何東西。每一頁在有對應工具時都會連過去。有兩個限制值得知道:同一時間只有一個程式能持有 ADB 介面,所以桌面的 adb server 要先停掉;而 adb forward 與 adb reverse 在瀏覽器裡完全無法運作。

比較想按而不是打字?Web ADB Toolkit 會從瀏覽器透過 USB 執行這類指令。或者瀏覽全部指令。