Android 7.0 ปรับโครงสร้าง Radio Interface Layer (RIL) ใหม่โดยใช้ชุดคุณสมบัติเพื่อปรับปรุงฟังก์ชันการทำงานของ RIL จำเป็นต้องเปลี่ยนแปลงรหัสพันธมิตรเพื่อใช้งานคุณสมบัติเหล่านี้ ซึ่งเป็นทางเลือกแต่ได้รับการสนับสนุน การเปลี่ยนแปลงการปรับโครงสร้างใหม่เข้ากันได้แบบย้อนหลัง ดังนั้นการใช้งานคุณลักษณะที่ปรับโครงสร้างใหม่ก่อนหน้านี้จะยังคงทำงานต่อไป
การปรับโครงสร้าง RIL ใหม่มีการปรับปรุงต่อไปนี้:
- รหัสข้อผิดพลาด RIL เปิดใช้งานรหัสข้อผิดพลาดเฉพาะเพิ่มเติมจากรหัส
GENERIC_FAILURE
ที่มีอยู่ ซึ่งช่วยในการแก้ไขปัญหาข้อผิดพลาดโดยการให้ข้อมูลเฉพาะเจาะจงมากขึ้นเกี่ยวกับสาเหตุของข้อผิดพลาด - การกำหนดเวอร์ชัน RIL ให้ข้อมูลเวอร์ชันที่แม่นยำและง่ายขึ้น
- การสื่อสาร RIL โดยใช้ wakelocks ปรับปรุงประสิทธิภาพแบตเตอรี่ของอุปกรณ์
คุณสามารถใช้การปรับปรุงข้างต้นบางส่วนหรือทั้งหมดได้ สำหรับรายละเอียดเพิ่มเติม โปรดดูความคิดเห็นโค้ดเกี่ยวกับการกำหนดเวอร์ชัน RIL ใน https://android.googlesource.com/platform/hardware/ril/+/main/include/telephony/ril.h
การใช้รหัสข้อผิดพลาด RIL ที่ปรับปรุงแล้ว
การเรียกคำขอ RIL เกือบทั้งหมดสามารถส่งคืนรหัสข้อผิดพลาด GENERIC_FAILURE
เพื่อตอบสนองต่อข้อผิดพลาด นี่เป็นปัญหากับการตอบสนองที่ร้องขอทั้งหมดที่ส่งคืนโดย OEM ซึ่งอาจทำให้ยากต่อการแก้ไขปัญหาจากรายงานข้อบกพร่องหากรหัสข้อผิดพลาด GENERIC_FAILURE
เดียวกันถูกส่งคืนโดยการเรียก RIL ด้วยเหตุผลที่แตกต่างกัน ผู้จำหน่ายอาจต้องใช้เวลาพอสมควรในการระบุว่าส่วนใดของโค้ดที่อาจส่งคืนโค้ด 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 โดยใช้ wakelocks
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 ค้างไว้และอยู่ในสถานะไม่ได้ใช้งานตลอดเวลาที่ใช้ในการตอบสนองจะมีประสิทธิภาพในการใช้พลังงานมากกว่าการเข้าสู่สถานะ Suspend โดยการปล่อย 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 และปล่อยเมื่อค่าตัวนับเป็น 0
หมายเหตุ: ระยะเวลาการหมดเวลา wakelock สำหรับลำดับการร้องขอ-ack จะน้อยกว่าระยะเวลาการหมดเวลาที่ใช้อยู่ในปัจจุบัน เนื่องจากควรได้รับ ack อย่างรวดเร็ว
- หลังจากประมวลผลคำขอแล้ว โมเด็มจะส่งการขัดจังหวะไปยังรหัสผู้จำหน่ายที่รับ 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 ใหม่สำหรับการโทรแบบอะซิงโครนัสจะนำไปสู่การประหยัดพลังงานแบตเตอรี่หรือไม่