Android 7.0 使用一組功能重構了無線電介面層 (RIL),藉此提升 RIL 功能。如要導入這些功能,合作夥伴必須變更程式碼。這些功能為選用功能,但我們建議導入。重構變更可回溯相容,因此重構功能先前的實作項目仍可繼續運作。
RIL 重構包含下列改善項目:
- RIL 錯誤代碼。除了現有的 
GENERIC_FAILURE代碼,還可啟用特定錯誤代碼。這有助於排解錯誤,因為可提供錯誤原因的更具體資訊。 - RIL 版本管理。提供更準確且更容易設定的版本資訊。
 - 使用喚醒鎖進行 RIL 通訊。提升裝置電池效能。
 
您可以導入上述任何或所有改善措施。詳情請參閱 https://android.googlesource.com/platform/hardware/ril/+/android16-release/include/telephony/ril.h 中 RIL 版本控管的程式碼註解。
實作強化型 RIL 錯誤代碼
幾乎所有 RIL 要求呼叫都可以在發生錯誤時傳回 GENERIC_FAILURE 錯誤代碼。這是 OEM 傳回的所有要求回應都有的問題,如果 RIL 呼叫因不同原因傳回相同的 GENERIC_FAILURE 錯誤代碼,就可能難以從錯誤報告中偵錯。供應商可能需要相當長的時間,才能找出程式碼中可能傳回 GENERIC_FAILURE 代碼的部分。
在 Android 7.x 以上版本中,原始設備製造商 (OEM) 可以傳回與目前歸類為 GENERIC_FAILURE 的每個不同錯誤相關聯的專屬錯誤代碼值。如果 OEM 不想公開自訂錯誤代碼,可以將錯誤傳回為一組不同的整數 (例如 1 到 x),並對應為 OEM_ERROR_1 到 OEM_ERROR_X。供應商應確保傳回的每個這類遮蓋錯誤代碼,都會對應至程式碼中的專屬錯誤原因。如果 OEM 傳回一般錯誤,使用特定錯誤代碼可加快 RIL 偵錯速度,因為找出 GENERIC_FAILURE 錯誤代碼的確切原因往往需要很長時間 (有時甚至不可能)。
此外,ril.h 會為列舉 RIL_LastCallFailCause 和 RIL_DataCallFailCause 新增更多錯誤代碼,因此供應商程式碼可以避免傳回一般錯誤,例如 CALL_FAIL_ERROR_UNSPECIFIED 和 PDP_FAIL_ERROR_UNSPECIFIED。
驗證增強型 RIL 錯誤代碼
新增錯誤代碼來取代 GENERIC_FAILURE 代碼後,請確認 RIL 呼叫傳回的是新錯誤代碼,而非 GENERIC_FAILURE。
導入強化 RIL 版本控管機制
舊版 Android 的 RIL 版本控管有問題:版本本身不精確、回報 RIL 版本的機制不明確 (導致部分供應商回報錯誤版本),以及用於估算版本的解決方法容易出錯。
在 Android 7.x 以上版本中,ril.h 會記錄所有 RIL 版本值、說明對應的 RIL 版本,並列出該版本的所有變更。進行與 RIL 版本相應的變更時,供應商必須更新程式碼中的版本,並在 RIL_REGISTER 中傳回該版本。
驗證強化 RIL 版本管理
確認 RIL_REGISTER 期間傳回的 RIL 版本對應至 RIL 程式碼 (而非 ril.h 中定義的 RIL_VERSION)。
使用喚醒鎖實作 RIL 通訊
RIL 通訊會以不精確的方式使用計時喚醒鎖定,進而對電池效能造成負面影響。在 Android 7.x 以上版本中,您可以分類 RIL 要求並更新程式碼,針對不同要求類型以不同方式處理喚醒鎖定,藉此提升效能。
分類 RIL 要求
RIL 要求可分為主動要求和非主動要求。供應商應進一步將徵求的要求分類為下列其中一種:
- 同步。要求回覆時間不會太長。例如 
RIL_REQUEST_GET_SIM_STATUS。 - 非同步。需要相當長的時間才能回應的要求。例如:
RIL_REQUEST_QUERY_AVAILABLE_NETWORKS。 
非同步主動式 RIL 要求可能需要相當長的時間。收到供應商程式碼的 ACK 後,RIL Java 會釋出喚醒鎖定,這可能會導致應用程式處理器從閒置狀態進入暫停狀態。當供應商程式碼提供回應時,RIL Java (應用程式處理器) 會重新取得喚醒鎖定,處理回應,然後返回閒置狀態。這類從閒置到暫停再到閒置的動作可能會消耗大量電力。
如果回應時間不夠長,與其釋放喚醒鎖定並在收到回應時喚醒,不如保留喚醒鎖定並在整個回應時間內保持閒置狀態,這樣更省電。供應商應使用平台專屬的電量測量結果,判斷時間 T 的閾值。當閒置時間 T 消耗的電量,大於從閒置狀態轉換為暫停狀態,再轉換回閒置狀態所消耗的電量時,即為閾值。T如果知道時間 T,則耗時超過 T 的 RIL 指令可歸類為非同步,其餘指令則歸類為同步。
RIL 通訊情境
下圖說明常見的 RIL 通訊情境,並提供修改程式碼的解決方案,以處理 RIL 主動和非主動要求。
注意:如要瞭解下列圖表中使用的函式實作詳細資料,請參閱 ril.cpp 中的 acquireWakeLock()、decrementWakeLock() 和 clearWakeLock( 方法。
情境:RIL 要求和主動式非同步回應
在這種情況下,如果 RIL 徵求的回應預計需要相當長的時間 (即對 RIL_REQUEST_GET_AVAILABLE_NETWORKS 的回應),應用程式處理器端會長時間持有喚醒鎖定。數據機問題也可能導致等待時間過長。

解決方案 1:數據機保留 RIL 要求和非同步回應的喚醒鎖定。

- 系統會傳送 RIL 要求,而數據機則會取得喚醒鎖定,以處理該要求。
 - 數據機傳送確認訊息,導致 Java 端遞減喚醒鎖計數器,並在計數器值為 0 時釋放喚醒鎖。
注意:要求確認序列的喚醒鎖定逾時時間會比目前使用的逾時時間短,因為系統應會相當快速地收到確認。
 - 處理要求後,數據機就會將中斷訊號傳送給取得喚醒鎖的供應商程式碼,並將回應傳送給 ril.cpp,而 ril.cpp 會取得喚醒鎖,並將回應傳送給 Java 端。
 - 回應傳回 Java 端時,系統會取得喚醒鎖定,並將回應傳回給呼叫者。
 - 所有模組處理完回應後,系統會透過插座將確認訊息傳回 
ril.cpp,然後釋放步驟 3 中取得的喚醒鎖定。 
解決方案 2:數據機不會保留喚醒鎖定,且回應速度很快 (同步 RIL 要求和回應)。特定 RIL 指令的同步與非同步行為已硬式編碼,且會根據每次呼叫決定。

- 在 Java 端呼叫 
acquireWakeLock(),即可傳送 RIL 要求。 - 供應商程式碼不需要取得喚醒鎖定,即可處理要求並快速回應。
 - Java 端收到回應時,系統會呼叫 
decrementWakeLock(),減少喚醒鎖計數器,並在計數器值為 0 時釋放喚醒鎖。 
情境:RIL 未經要求的響應
在這種情況下,RIL 未經要求的響應會在其中包含喚醒鎖定類型標記,指出是否需要為供應商響應取得喚醒鎖定。如果設定了旗標,系統會設定計時喚醒鎖定,並透過通訊端將回應傳送至 Java 端。計時器到期時,系統會釋放喚醒鎖。對於不同的 RIL 未經要求回應,定時喚醒鎖可能過長或過短。

解決方法:從 Java 程式碼傳送確認訊息至原生端 (ril.cpp),而非在傳送未經要求的訊息時,於原生端保留計時喚醒鎖定。

驗證重新設計的喚醒鎖
確認 RIL 呼叫是否識別為同步或非同步。由於耗電量可能取決於硬體/平台,供應商應進行一些內部測試,瞭解使用非同步呼叫的新喚醒鎖語意是否能節省電力。