בגרסה 7.0 של Android בוצעה רה-פירמנטציה של שכבת ממשק הרדיו (RIL) באמצעות קבוצה של תכונות כדי לשפר את הפונקציונליות של RIL. כדי להטמיע את התכונות האלה, נדרשים שינויים בקוד של השותף. השינוי הזה הוא אופציונלי, אבל מומלץ לבצע אותו. השינויים במסגרת ה-Refactoring תואמים לאחור, כך שההטמעות הקודמות של התכונות שעברו Refactoring ימשיכו לפעול.
שיפורי ה-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 ואילך, יצרני ציוד מקורי יכולים להחזיר ערך ייחודי של קוד שגיאה שמשויך לכל שגיאה שונה שמסווגת כרגע בתור GENERIC_FAILURE
. יצרני ציוד מקורי שלא רוצים לחשוף באופן ציבורי את קודי השגיאות בהתאמה אישית שלהם יכולים להחזיר שגיאות כקבוצה נפרדת של מספרים שלמים (כמו 1 עד x) שממופים כ-OEM_ERROR_1
עד OEM_ERROR_X
. הספקים צריכים לוודא שכל קוד שגיאה מוצפן כזה ממופות לסיבת שגיאה ייחודית בקוד. שימוש בקודי שגיאה ספציפיים יכול לזרז את ניפוי הבאגים ב-RIL בכל פעם שה-OEM מחזיר שגיאות כלליות, כי לרוב נדרש הרבה זמן כדי לזהות את הסיבה המדויקת של קוד השגיאה GENERIC_FAILURE
(ולפעמים אי אפשר לזהות אותה).
בנוסף, ril.h
מוסיף קודי שגיאה נוספים למאפייני המנייה 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
נעשה שימוש ב-wakelocks מתוזמנים בתקשורת RIL באופן לא מדויק, שמשפיע לרעה על ביצועי הסוללה. ב-Android 7.x ואילך, אפשר לשפר את הביצועים על ידי סיווג בקשות RIL ועדכון הקוד כדי לטפל ב-wakelocks באופן שונה לסוגים שונים של בקשות.
סיווג בקשות RIL
בקשות RIL יכולות להיות מרצון או לא מרצון. ספקים צריכים לסווג בקשות שהתקבלו מלקוחות לפי אחת מהקטגוריות הבאות:
- סינכרוני. בקשות שלא נדרשת להן תשובה מיידית. לדוגמה,
RIL_REQUEST_GET_SIM_STATUS
. - אסינכרוני. בקשות שצריך זמן רב כדי להשיב עליהן. לדוגמה,
RIL_REQUEST_QUERY_AVAILABLE_NETWORKS
.
שליחת בקשות RIL מרצון באופן אסינכרוני עשויה להימשך זמן רב. אחרי קבלת אישור מקוד הספק, RIL Java משחרר את ה-wakelock, וזה עלול לגרום למעבד האפליקציה לעבור ממצב חוסר פעילות למצב השהיה. כשהתגובה זמינה מקוד הספק, RIL Java (מעבד האפליקציות) מקבל מחדש את ה-wakelock, מעבד את התגובה ואז חוזר למצב המתנה. מעבר כזה מסטטוס 'לא פעיל' לסטטוס 'השהיה' וחזרה לסטטוס 'לא פעיל' יכול לצרוך הרבה חשמל.
אם זמן התגובה לא ארוך מספיק, כדאי להחזיק את ה-wakelock ולהישאר במצב חוסר פעילות במשך כל הזמן שנדרש לתגובה. כך אפשר לחסוך באנרגיה יותר מאשר לעבור למצב השהיה על ידי שחרור ה-wakelock והתעוררות כשהתגובה מגיעה. ספקים צריכים להשתמש במדידות צריכת אנרגיה ספציפיות לפלטפורמה כדי לקבוע את ערך הסף של הזמן T, כאשר צריכת האנרגיה במצב מנוחה במשך כל הזמן T גבוהה מצריכת האנרגיה במעבר ממצב מנוחה למצב השהיה וממנוחה שוב למצב מנוחה באותו זמן T. כשהזמן T ידוע, אפשר לסווג פקודות RIL שנמשכות יותר מ-T כפקודות אסינכרניות, ואת שאר הפקודות כפקודות סינכרוניות.
תרחישים של תקשורת RIL
בתרשים הבא מוצגים תרחישים נפוצים של תקשורת 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) יהיה קצר יותר ממשך הזמן של זמן הקצאת הזמן לתפוגה שבו נעשה שימוש כרגע, כי האישור אמור להתקבל במהירות יחסית.
- אחרי עיבוד הבקשה, המודם שולח הפסקה לקוד של הספק שמקבל את ה-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 המתוזמן ארוך מדי או קצר מדי לתשובות לא מתוזמנות שונות של RIL.
הפתרון: הודעה על אישור נשלחת מקוד Java לצד המקורי (ril.cpp
) במקום להחזיק את wakelock המתוזמן בצד המקורי בזמן שליחת תשובה לא מבקשת.
אימות של נעילות מצב פעילות (wakelocks) בעיצוב מחדש
מוודאים שהקריאות ל-RIL מזוהות כסינכרוניות או כאסינכררוניות. מכיוון שצריכת החשמל של הסוללה עשויה להיות תלויה בחומרה או בפלטפורמה, הספקים צריכים לבצע בדיקות פנימיות כדי לבדוק אם השימוש בסמינטיקה החדשה של wakelock לשיחות אסינכררוניות מוביל לחיסכון בצריכת החשמל של הסוללה.