Android 7.0 ปรับโครงสร้าง Radio Interface Layer (RIL) โดยใช้ชุดฟีเจอร์เพื่อปรับปรุงฟังก์ชันการทำงานของ RIL พาร์ทเนอร์ต้องเปลี่ยนแปลงโค้ดเพื่อใช้ฟีเจอร์เหล่านี้ ซึ่งไม่บังคับแต่แนะนําให้ใช้ การเปลี่ยนแปลงการแยกส่วนโค้ดจะใช้งานย้อนหลังได้ ดังนั้นการใช้งานฟีเจอร์ที่แยกส่วนโค้ดก่อนหน้านี้จะยังคงใช้งานได้ต่อไป
การแยกส่วน RIL มีการปรับปรุงต่อไปนี้
- รหัสข้อผิดพลาด RIL เปิดใช้รหัสข้อผิดพลาดที่เฉพาะเจาะจงนอกเหนือจากรหัส
GENERIC_FAILURE
ที่มีอยู่ ซึ่งช่วยในการแก้ปัญหาข้อผิดพลาดโดยให้ข้อมูลที่เฉพาะเจาะจงมากขึ้นเกี่ยวกับสาเหตุของข้อผิดพลาด - การกำหนดเวอร์ชัน RIL กำหนดค่าข้อมูลเวอร์ชันได้ง่ายขึ้นและแม่นยำมากขึ้น
- การสื่อสาร RIL โดยใช้ Wakelock ปรับปรุงประสิทธิภาพแบตเตอรี่ของอุปกรณ์
คุณสามารถใช้การปรับปรุงข้างต้นอย่างใดอย่างหนึ่งหรือทั้งหมดก็ได้ ดูรายละเอียดเพิ่มเติมได้ที่ความคิดเห็นโค้ดเกี่ยวกับการกำหนดเวอร์ชัน RIL ใน https://android.googlesource.com/platform/hardware/ril/+/main/include/telephony/ril.h
ใช้รหัสข้อผิดพลาด 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
ผู้ให้บริการควรตรวจสอบว่ารหัสข้อผิดพลาดที่มีการมาสก์แต่ละรายการที่แสดงผลนั้นแมปกับเหตุผลของข้อผิดพลาดที่ไม่ซ้ำกันในโค้ด การใช้รหัสข้อผิดพลาดที่เฉพาะเจาะจงจะช่วยเร่งการแก้ไขข้อบกพร่อง RIL ได้ทุกครั้งที่มีการแสดงข้อผิดพลาดทั่วไปจาก OEM เนื่องจากบางครั้งอาจใช้เวลานานเกินไปในการระบุสาเหตุที่แน่ชัดของรหัสข้อผิดพลาด GENERIC_FAILURE
(และบางครั้งก็ไม่สามารถระบุได้)
นอกจากนี้ ril.h
ยังเพิ่มรหัสข้อผิดพลาดอื่นๆ สําหรับ enums RIL_LastCallFailCause
และ RIL_DataCallFailCause
เพื่อให้โค้ดของผู้ให้บริการหลีกเลี่ยงการแสดงผลข้อผิดพลาดทั่วไป เช่น CALL_FAIL_ERROR_UNSPECIFIED
และ PDP_FAIL_ERROR_UNSPECIFIED
ตรวจสอบรหัสข้อผิดพลาด RIL ที่ปรับปรุงแล้ว
หลังจากเพิ่มรหัสข้อผิดพลาดใหม่เพื่อแทนที่รหัส GENERIC_FAILURE
แล้ว ให้ตรวจสอบว่ารหัสข้อผิดพลาดใหม่แสดงขึ้นจากการเรียก RIL แทน GENERIC_FAILURE
ใช้การกำหนดเวอร์ชัน RIL ที่ปรับปรุงแล้ว
เวอร์ชัน RIL ใน Android เวอร์ชันเก่ามีปัญหา เนื่องจากเวอร์ชันนั้นไม่แม่นยำ กลไกการรายงานเวอร์ชัน RIL ไม่ชัดเจน (ทำให้ผู้ให้บริการบางรายรายงานเวอร์ชันที่ไม่ถูกต้อง) และวิธีแก้ปัญหาในการประมาณเวอร์ชันมีแนวโน้มที่จะไม่ถูกต้อง
ใน Android 7.x ขึ้นไป ril.h
จะบันทึกค่าเวอร์ชัน RIL ทั้งหมด อธิบายเวอร์ชัน RIL ที่เกี่ยวข้อง และแสดงรายการการเปลี่ยนแปลงทั้งหมดของเวอร์ชันนั้น เมื่อทำการเปลี่ยนแปลงที่เกี่ยวข้องกับเวอร์ชัน RIL เวนเดอร์ต้องอัปเดตเวอร์ชันในโค้ดและส่งเวอร์ชันนั้นใน RIL_REGISTER
ตรวจสอบการกำหนดเวอร์ชัน RIL ที่ปรับปรุงแล้ว
ตรวจสอบว่าระบบแสดงผลเวอร์ชัน RIL ที่สอดคล้องกับรหัส RIL ของคุณในระหว่าง RIL_REGISTER
(แทนที่จะเป็น RIL_VERSION
ที่ระบุไว้ใน ril.h
)
ใช้การสื่อสาร RIL โดยใช้ Wakelock
ระบบใช้ Wakelock แบบตั้งเวลาในการสื่อสาร RIL ในลักษณะที่ไม่แม่นยำ ซึ่งส่งผลเสียต่อประสิทธิภาพของแบตเตอรี่ ใน Android 7.x ขึ้นไป คุณสามารถปรับปรุงประสิทธิภาพได้โดยการจัดประเภทคำขอ RIL และการอัปเดตโค้ดเพื่อจัดการ Wakelock ที่แตกต่างกันสำหรับคำขอประเภทต่างๆ
จัดประเภทคำขอ RIL
คำขอ RIL อาจเป็นคำขอที่ขอหรือไม่ได้ขอก็ได้ ผู้ให้บริการควรจัดประเภทคำขอที่ขอเข้ามาใหม่เป็นประเภทใดประเภทหนึ่งต่อไปนี้
- แบบเรียลไทม์ คำขอที่ใช้เวลาไม่นานในการตอบกลับ เช่น
RIL_REQUEST_GET_SIM_STATUS
- แบบไม่เรียลไทม์ คำขอที่ใช้เวลาในการตอบกลับนาน เช่น
RIL_REQUEST_QUERY_AVAILABLE_NETWORKS
คำขอ RIL ที่ส่งมาแบบอะซิงโครนัสอาจใช้เวลานาน หลังจากได้รับ ACK จากโค้ดของผู้ให้บริการแล้ว RIL Java จะปล่อยการล็อกการปลุก ซึ่งอาจทำให้โปรเซสเซอร์แอปเปลี่ยนจากสถานะ "ไม่มีการใช้งาน" เป็น "หยุดชั่วคราว" เมื่อได้รับคําตอบจากโค้ดของผู้ให้บริการ RIL Java (ตัวประมวลผลแอป) จะรับการล็อกการปลุกอีกครั้ง ประมวลผลคําตอบ แล้วกลับไปอยู่ในสถานะรอ การเปลี่ยนจากการทำงานแบบไม่มีการใช้งานเป็นการหยุดชั่วคราวและกลับไปทำงานแบบไม่มีการใช้งานอาจใช้พลังงานมาก
หากเวลาในการตอบสนองไม่นานพอ การล็อกให้ตื่นค้างไว้และอยู่ในสถานะ "ไม่มีการใช้งาน" ตลอดระยะเวลาที่ใช้ในการตอบสนองอาจประหยัดพลังงานได้มากกว่าการเข้าสู่สถานะ "หยุดชั่วคราว" โดยการปล่อยการล็อกให้ตื่นค้างไว้และตื่นขึ้นเมื่อได้รับคำตอบ ผู้ให้บริการควรใช้การวัดพลังงานเฉพาะแพลตฟอร์มเพื่อกำหนดค่าเกณฑ์ของเวลา T เมื่อพลังงานที่ใช้ไปจากการอยู่ในโหมดสแตนด์บายตลอดทั้งเวลา T มากกว่าพลังงานที่ใช้ไปจากการเปลี่ยนจากโหมดสแตนด์บายเป็นโหมดระงับและกลับไปยังโหมดสแตนด์บายในเวลาเดียวกัน T เมื่อทราบเวลา T แล้ว คำสั่ง RIL ที่ใช้เวลานานกว่าเวลา T จะจัดประเภทเป็นแบบอะซิงโครนัส และจัดประเภทคำสั่งที่เหลือเป็นแบบซิงโครนัส
สถานการณ์การสื่อสาร RIL
แผนภาพต่อไปนี้แสดงสถานการณ์การสื่อสาร RIL ที่พบบ่อยและแสดงวิธีแก้ไขโค้ดเพื่อจัดการคำขอที่ RIL ขอและไม่ขอ
หมายเหตุ: ดูรายละเอียดการใช้งานฟังก์ชันที่ใช้ในแผนภาพต่อไปนี้ได้ที่เมธอด acquireWakeLock()
, decrementWakeLock()
และ clearWakeLock(
ใน ril.cpp
สถานการณ์: คำขอ RIL และการตอบกลับแบบไม่พร้อมกันที่ขอ
ในกรณีนี้ หากคาดว่าการตอบกลับที่ RIL ขอจะใช้เวลานาน (เช่น การตอบกลับRIL_REQUEST_GET_AVAILABLE_NETWORKS
) ระบบจะล็อกให้อุปกรณ์ตื่นเป็นเวลานานในฝั่งตัวประมวลผลของแอป ปัญหาเกี่ยวกับโมเด็มอาจส่งผลให้คุณต้องรอนาน
วิธีแก้ปัญหาที่ 1: โมเด็มจะล็อกให้ตื่นอยู่เพื่อรับคำขอ RIL และการตอบกลับแบบไม่พร้อมกัน
- ระบบจะส่งคำขอ RIL และโมเด็มจะรับการล็อกการปลุกเพื่อประมวลผลคำขอนั้น
- โมเด็มส่งการตอบกลับที่ทำให้ฝั่ง Java ลดลง
ตัวนับการตื่นล็อกและปล่อยเมื่อค่าตัวนับเป็น 0
หมายเหตุ: ระยะเวลาการหมดเวลาของ Wakelock สําหรับลําดับคําขอ-การตอบกลับจะสั้นกว่าระยะเวลาการหมดเวลาที่ใช้งานอยู่ในปัจจุบัน เนื่องจากควรจะได้รับการตอบกลับอย่างรวดเร็ว
- หลังจากประมวลผลคําขอแล้ว โมเด็มจะส่งการขัดจังหวะไปยังโค้ดของผู้ให้บริการที่รับ Wakelock และส่งการตอบกลับไปยัง ril.cpp ซึ่งจะรับ Wakelock และส่งการตอบกลับไปยังฝั่ง Java
- เมื่อการตอบกลับมาถึงฝั่ง Java ระบบจะรับ Wakelock และส่งการตอบกลับกลับไปยังผู้เรียกใช้
- หลังจากโมดูลทั้งหมดประมวลผลการตอบกลับแล้ว ระบบจะส่งการตอบกลับ (ผ่านซ็อกเก็ต) กลับไปยัง
ril.cpp
ซึ่งจะปล่อยการล็อกที่ตื่นอยู่ซึ่งได้มาจากขั้นตอนที่ 3
วิธีแก้ปัญหาที่ 2: โมเด็มไม่ได้ล็อกการตื่นไว้และการตอบกลับรวดเร็ว (คำขอและคำตอบ RIL แบบซิงค์) ลักษณะการทำงานแบบซิงค์กับแบบแอซิงค์จะกำหนดไว้ล่วงหน้าสำหรับคําสั่ง RIL ที่เฉพาะเจาะจงและตัดสินใจในแต่ละการเรียก
- ระบบจะส่งคําขอ RIL โดยการเรียกใช้
acquireWakeLock()
ฝั่ง Java - โค้ดของผู้ให้บริการไม่จำเป็นต้องใช้ Wakelock และสามารถประมวลผลคำขอและตอบกลับได้อย่างรวดเร็ว
- เมื่อฝั่ง Java ได้รับคำตอบ ระบบจะเรียกใช้
decrementWakeLock()
ซึ่งจะลดตัวนับการตื่นอยู่ และปล่อยการตื่นอยู่หากค่าตัวนับเป็น 0
สถานการณ์: การตอบกลับที่ไม่พึงประสงค์ของ RIL
ในกรณีนี้ การตอบกลับที่ไม่พึงประสงค์ของ RIL จะมี Flag ประเภท Wakelock ในการบ่งชี้ว่าจำเป็นต้องใช้ Wakelock สำหรับการตอบกลับของผู้ให้บริการหรือไม่ หากตั้งค่า Flag ระบบจะตั้งค่า Wakelock แบบกำหนดเวลาและส่งการตอบกลับผ่านซ็อกเก็ตไปยังฝั่ง Java เมื่อตัวจับเวลาหมดอายุ ระบบจะยกเลิกการล็อกการปลุก การล็อกที่ทำงานตามเวลาอาจนานหรือสั้นเกินไปสำหรับการตอบกลับที่ไม่พึงประสงค์ของ RIL
วิธีแก้ไข: ระบบจะส่งการตอบกลับจากโค้ด Java ไปยังฝั่งเนทีฟ (ril.cpp
) แทนการล็อกให้ตื่นตามเวลาในฝั่งเนทีฟขณะส่งการตอบกลับที่ไม่พึงประสงค์
ตรวจสอบ Wakelock ที่ออกแบบใหม่
ยืนยันว่าการเรียก RIL ได้รับการระบุว่าเป็นแบบเรียลไทม์หรือไม่เรียลไทม์ เนื่องจากปริมาณการใช้พลังงานแบตเตอรี่อาจขึ้นอยู่กับฮาร์ดแวร์/แพลตฟอร์ม ผู้ให้บริการจึงควรทำการทดสอบภายในเพื่อดูว่าการใช้เซมาติกส์ Wakelock ใหม่สำหรับการเรียกแบบไม่พร้อมกันช่วยประหยัดพลังงานแบตเตอรี่ได้หรือไม่