Android 7.0 ได้ปรับโครงสร้าง Radio Interface Layer (RIL) ใหม่โดยใช้ฟีเจอร์ต่างๆ เพื่อปรับปรุงฟังก์ชันการทำงานของ RIL คุณต้องทำการเปลี่ยนแปลงโค้ดของพาร์ทเนอร์เพื่อใช้ฟีเจอร์เหล่านี้ ซึ่งเป็นตัวเลือกแต่เราขอแนะนำให้ใช้ การเปลี่ยนแปลงการปรับโครงสร้างใหม่เข้ากันได้กับเวอร์ชันก่อนหน้า ดังนั้นการใช้งานฟีเจอร์ที่ปรับโครงสร้างใหม่ก่อนหน้านี้จะยังคงทำงานได้
การปรับโครงสร้าง RIL ใหม่มีการปรับปรุงดังนี้
- รหัสข้อผิดพลาด RIL เปิดใช้รหัสข้อผิดพลาดที่เฉพาะเจาะจงนอกเหนือจากรหัส
GENERIC_FAILUREที่มีอยู่ ซึ่งจะช่วยในการแก้ปัญหาข้อผิดพลาดโดยให้ข้อมูลที่เฉพาะเจาะจงมากขึ้นเกี่ยวกับสาเหตุของข้อผิดพลาด - การกำหนดเวอร์ชัน RIL ให้ข้อมูลเวอร์ชันที่แม่นยำและกำหนดค่าได้ง่ายขึ้น
- การสื่อสาร RIL โดยใช้ Wakelock ปรับปรุงประสิทธิภาพแบตเตอรี่ของอุปกรณ์
คุณสามารถใช้การปรับปรุงข้างต้นทั้งหมดหรือบางส่วนก็ได้ ดูรายละเอียดเพิ่มเติมได้ที่ความคิดเห็นในโค้ดเกี่ยวกับการกำหนดเวอร์ชัน RIL ใน
https://android.googlesource.com/platform/hardware/ril/+/android17-release/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 ยังเพิ่มรหัสข้อผิดพลาดเพิ่มเติมสำหรับ Enum 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 จะปล่อย Wakelock ซึ่งอาจทำให้โปรเซสเซอร์ของแอปเปลี่ยนจากสถานะไม่ได้ใช้งานเป็นสถานะระงับ เมื่อโค้ดของผู้ให้บริการแสดงการตอบกลับ RIL Java (โปรเซสเซอร์ของแอป) จะรับ Wakelock อีกครั้ง ประมวลผลการตอบกลับ แล้วกลับสู่สถานะไม่ได้ใช้งาน การเปลี่ยนจากสถานะไม่ได้ใช้งานเป็นสถานะระงับแล้วกลับสู่สถานะไม่ได้ใช้งานเช่นนี้อาจใช้พลังงานมาก
หากเวลาตอบกลับไม่นานพอ การเก็บ Wakelock ไว้และอยู่ในสถานะไม่มีการใช้งานตลอดเวลาที่ใช้ในการตอบกลับอาจประหยัดพลังงานมากกว่าการเข้าสู่สถานะระงับโดยการปล่อย Wakelock และปลุกระบบเมื่อมีการตอบกลับ ผู้ให้บริการควรใช้การวัดพลังงานที่เฉพาะเจาะจงของแพลตฟอร์มเพื่อกำหนดค่าเกณฑ์ของเวลา T เมื่อพลังงานที่ใช้ในการอยู่ในสถานะไม่มีการใช้งานตลอดเวลา T มากกว่าพลังงานที่ใช้ในการเปลี่ยนจากสถานะไม่มีการใช้งานเป็นสถานะระงับแล้วกลับสู่สถานะไม่มีการใช้งานในเวลา T เดียวกัน เมื่อทราบเวลา T แล้ว คำสั่ง RIL ที่ใช้เวลามากกว่าเวลา T จะจัดอยู่ในหมวดหมู่คำสั่งอะซิงโครนัส และคำสั่งที่เหลือ จะจัดอยู่ในหมวดหมู่คำสั่งซิงโครนัส
สถานการณ์การสื่อสาร RIL
แผนภาพต่อไปนี้แสดงสถานการณ์การสื่อสาร RIL ทั่วไปและแสดงวิธีแก้ปัญหาในการแก้ไขโค้ดเพื่อจัดการคำขอ RIL ที่ร้องขอและไม่ได้ร้องขอ
หมายเหตุ: โปรดดูรายละเอียดการใช้งานฟังก์ชันที่ใช้ในแผนภาพต่อไปนี้ที่เมธอด acquireWakeLock(), decrementWakeLock() และ clearWakeLock() ใน ril.cpp
สถานการณ์: คำขอ RIL และการตอบกลับแบบอะซิงโครนัสที่ร้องขอ
ในสถานการณ์นี้ หากคาดว่าการตอบกลับแบบอะซิงโครนัสที่ร้องขอ RIL จะใช้เวลาพอสมควร (เช่น การตอบกลับ RIL_REQUEST_GET_AVAILABLE_NETWORKS) ระบบจะเก็บ Wakelock ไว้เป็นเวลานานในฝั่งโปรเซสเซอร์ของแอป ปัญหาเกี่ยวกับโมเด็มอาจทำให้ต้องรอนานด้วย

วิธีแก้ปัญหาที่ 1: โมเด็มเก็บ Wakelock ไว้สำหรับคำขอ RIL และการตอบกลับแบบอะซิงโครนัส

- ระบบส่งคำขอ RIL และโมเด็มรับ Wakelock เพื่อประมวลผลคำขอนั้น
- โมเด็มส่งการรับทราบซึ่งทำให้ฝั่ง Java ลดตัวนับ Wakelock และปล่อย Wakelock เมื่อค่าตัวนับเป็น 0
หมายเหตุ: ระยะหมดเวลา Wakelock สำหรับลำดับคำขอ-การรับทราบจะสั้นกว่าระยะหมดเวลาที่ใช้ในปัจจุบัน เนื่องจากควรได้รับการรับทราบค่อนข้างเร็ว
- หลังจากประมวลผลคำขอแล้ว โมเด็มจะส่งการขัดจังหวะไปยังโค้ดของผู้ให้บริการซึ่งรับ Wakelock และส่งการตอบกลับไปยัง ril.cpp ซึ่งจะรับ Wakelock และส่งการตอบกลับไปยังฝั่ง Java
- เมื่อการตอบกลับไปถึงฝั่ง Java ระบบจะรับ Wakelock และส่งการตอบกลับไปยังผู้เรียกใช้
- หลังจากที่โมดูลทั้งหมดประมวลผลการตอบกลับแล้ว ระบบจะส่งการรับทราบ (ผ่านซ็อกเก็ต) กลับไปยัง
ril.cppซึ่งจะปล่อย Wakelock ที่รับในขั้นตอนที่ 3
วิธีแก้ปัญหาที่ 2: โมเด็มไม่เก็บ Wakelock ไว้และการตอบกลับรวดเร็ว (คำขอและการตอบกลับ RIL แบบซิงโครนัส) ลักษณะการทำงานแบบซิงโครนัสเทียบกับแบบอะซิงโครนัสจะฮาร์ดโค้ดไว้สำหรับคำสั่ง RIL ที่เฉพาะเจาะจงและตัดสินใจตามการเรียกใช้แต่ละครั้ง

- ระบบส่งคำขอ RIL โดยเรียกใช้
acquireWakeLock()ในฝั่ง Java - โค้ดของผู้ให้บริการไม่จำเป็นต้องรับ Wakelock และสามารถประมวลผลคำขอและตอบกลับได้อย่างรวดเร็ว
- เมื่อฝั่ง Java ได้รับการตอบกลับ ระบบจะเรียกใช้
decrementWakeLock()ซึ่งจะลดตัวนับ Wakelock และปล่อย Wakelock หากค่าตัวนับเป็น 0
สถานการณ์: การตอบกลับ RIL ที่ไม่ได้ร้องขอ
ในสถานการณ์นี้ การตอบกลับ RIL ที่ไม่พึงประสงค์จะมีแฟล็กประเภท Wakelock ในการตอบกลับซึ่งระบุว่าต้องรับ Wakelock สำหรับการตอบกลับของผู้ให้บริการหรือไม่ หากตั้งค่าแฟล็กไว้ ระบบจะตั้งค่า Wakelock ที่กำหนดเวลาไว้และส่งการตอบกลับผ่านซ็อกเก็ตไปยังฝั่ง Java เมื่อหมดเวลา ระบบจะปล่อย Wakelock Wakelock ที่กำหนดเวลาไว้อาจนานหรือสั้นเกินไปสำหรับการตอบกลับ RIL ที่ไม่พึงประสงค์ต่างๆ

วิธีแก้ปัญหา: ระบบจะส่งการรับทราบจากโค้ด Java ไปยังฝั่งเนทีฟ (ril.cpp) แทนที่จะเก็บ Wakelock ที่กำหนดเวลาไว้ในฝั่งเนทีฟขณะส่งการตอบกลับที่ไม่ได้ร้องขอ

ตรวจสอบ Wakelock ที่ออกแบบใหม่
ตรวจสอบว่าระบบระบุการเรียกใช้ RIL เป็นแบบซิงโครนัสหรืออะซิงโครนัส เนื่องจากการใช้พลังงานแบตเตอรี่อาจขึ้นอยู่กับฮาร์ดแวร์/แพลตฟอร์ม ผู้ให้บริการควรทำการทดสอบภายในเพื่อดูว่าการใช้ความหมายใหม่ของ Wakelock สำหรับการเรียกใช้แบบอะซิงโครนัสจะช่วยประหยัดพลังงานแบตเตอรี่ได้หรือไม่