מדריך שילוב ליצרני ציוד מקורי

הדף הזה מתאר איך לעבד חוגה לקלט הנתונים ב-VHAL ולהגדיר את גרסת ה-build כדי לכלול את שירות החוגה ואיך להתאים אישית את חוויית החוגה בכל האפליקציות. למידע על אפליקציות OEM (יצרן ציוד מקורי) שהותקנו מראש, כמו מרכז אפליקציות שסופק על ידי ה-OEM: ספריית ממשק המשתמש של הרכב (car-ui-library)

VHAL

שלט חוגה יש תמיכה בפעולות הבאות:

  • הסטה למעלה, למטה, שמאלה וימינה.
  • צריך לסובב את הראש בכיוון השעון או נגד כיוון השעון.
  • לוחצים על הלחצן 'מרכז'.
  • לוחצים על לחצן 'הקודם'.
  • לוחצים על לחצן דף הבית.
  • לוחצים על לחצנים אחרים, למשל 'טלפון' ו'מדיה'.

בכתובת hardware/interfaces/automotive/vehicle/2.0/types.hal יש מסמכים בנושא את מאפייני המערכת ואת int32Values התואמים.

ה-VHAL צריך לטפל בפעולות הבאות:

נדנוד

כשהמשתמש דוחף את החוגה ימינה, ה-VHAL צריך להשתמש נכס HW_KEY_INPUT עם int32Values הבא כדי לשלוח אירוע ל-Android:

  1. ACTION_DOWN
  2. KEYCODE_SYSTEM_NAVIGATION_RIGHT
  3. תצוגה ביעד.

כשהמשתמש משחרר את החוגה לבקר, ה-VHAL צריך להשתמש באותו מאפיין וגם קוד מפתח עם ACTION_UP. בנדנודים בכיוונים אחרים צריך להשתמש ברכיב את קודי המפתח התואמים.

אין קודי מפתח באלכסון, אבל VHAL יכול לשלב בין פורמט אופקי ואנכי האירוע יפיק אלכסון אם החומרה תומכת באלכסון. לדוגמה, נדנוד ובצד שמאל אמור להתקבל:

  • HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_LEFT ACTION_DOWN
  • HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_UP ACTION_DOWN

בכל אחד מהסדרים הבאים (ולאחר מכן) שחרור של החוגה צריכה לייצר:

  • HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_LEFT ACTION_UP
  • HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_UP ACTION_UP

המשתמש יכול לדחוף את הבקר החוגה לכיוון אנכי לפני שחרורו. לדוגמה, התרחיש הבא:

כיוון מאונך
איור 1. כיוון אנכי

הפעולה הזו אמורה ליצור את רצף האירועים הבא:

  1. HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_LEFT ACTION_DOWN
  2. HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_UP ACTION_DOWN
  3. HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_LEFT ACTION_UP
  4. HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_UP ACTION_UP

אין ליצור אירועים חוזרים בזמן ההפעלה של החוגה בכיוון אחד.

סיבוב

כשהמשתמש מסובב את הבקר החוגה בכיוון השעון בסמן אחד (לחיצה), סימן ה-VHAL צריך להשתמש במאפיין HW_ROTARY_INPUT עם ה-int32Values הבא כדי לשלוח אירוע ל-Android:

  1. ROTARY_INPUT_TYPE_SYSTEM_NAVIGATION
  2. ערך אחד (1) של ערך.
  3. תצוגה ביעד.

צריך להגדיר את חותמת הזמן של האירוע לזמן שחלף בננו-שניות.

סיבוב אחד (1) של ערך נגד כיוון השעון אמור ליצור את אותו אירוע, אבל עם 1- למספר המעצרים.

אם מספר קצוות של סיבוב באותו כיוון מתרחשים ברצף מהיר, VHAL צריך לשלב את הנתונים לאירוע אחד כדי לא להעמיס על המערכת יותר מדי אירועים. במקרה הזה, חותמת הזמן של האירוע צריכה להיות התאריך שבו התרחש הערך הראשון של הסבב. הערך int32Values צריך לכלול את מספר הננו-שניות בין גורמים עוקבים עוקבים של סיבוב.

לדוגמה, הרצף הבא של הסיבובים:

  • בשעה t0, המשתמש סובב סיבוב אחד נגד כיוון השעון.
  • בשעה t0 + 5 ns, המשתמש סובב סיבוב אחד נגד כיוון השעון.
  • בשעה t0 + 8 ns, המשתמש סובב סיבוב אחד נגד כיוון השעון.

צריך ליצור את האירוע הבא:

  • נכס: HW_ROTARY_INPUT
  • חותמת זמן: t0
  • int32Values:
    1. ROTARY_INPUT_TYPE_SYSTEM_NAVIGATION
    2. 3- (שלושה מכשירים נגד כיוון השעון).
    3. תצוגה ביעד.
    4. 5 ns בין הערך הראשון לשני.
    5. 3 ns בין פתח שני לשלישי.

הלחצן המרכזי

כשהמשתמש לוחץ על הלחצן המרכזי, VHAL צריך להשתמש ב-HW_KEY_INPUT נכס עם int32Values הבא כדי לשלוח אירוע ל-Android:

  1. ACTION_DOWN
  2. KEYCODE_DPAD_CENTER
  3. תצוגה ביעד.

כשהמשתמש משחרר את השלט הרחוק של החוגה, ב-VHAL צריך להשתמש באותו מאפיין וקוד מפתח באמצעות ACTION_UP.

אין ליצור אירועים חוזרים כאשר לוחצים לחיצה ארוכה על הלחצן 'מרכז'.

לחצן 'הקודם'

כשהמשתמש לוחץ על הלחצן 'הקודם', ה-VHAL צריך להשתמש ב-HW_KEY_INPUT נכס עם int32Values הבא כדי לשלוח אירוע ל-Android:

  1. ACTION_DOWN
  2. KEYCODE_BACK
  3. תצוגה ביעד.

כשהמשתמש משחרר את השלט הרחוק של החוגה, ב-VHAL צריך להשתמש באותו מאפיין וקוד מפתח באמצעות ACTION_UP.

אין ליצור אירועים חוזרים בזמן לחיצה ארוכה על הלחצן 'מרכז'.

לחצן 'דף הבית'

יש להשתמש בלחצן דף הבית כמו בלחצן 'הקודם', אך במקום זאת ב-KEYCODE_HOME מתוך KEYCODE_BACK.

לחצנים אחרים

אם השלט רחוק החוגה כולל לחצנים נוספים, VHAL יכול לטפל בהם מבחינת ה-OEM, הם לא נחשבים לחלק מהחוגה. בדרך כלל מקשי הקיצור האלה פועלים כמו לחצני 'הקודם' ו'דף הבית', אבל קודי מקשים שונים. לדוגמה, KEYCODE_CALL או KEYCODE_MUSIC.

הגדרת build

שירות נגישות בשם RotaryService מספק את הניווט החוגה. כדי לכלול את השירות הזה בתמונת המערכת של המכשיר, צריך להוסיף את השורה הבאה אל makefile:

PRODUCT_PACKAGES += CarRotaryController

כדאי גם לכלול את החבילות הבאות בגרסאות build של ניפוי באגים:

  • RotaryPlayground אפליקציית עזר לחוגה (למידע נוסף: RotaryPlayground).
  • RotaryIME הדגמה של שיטת בידינג סיבובית (עיינו בעורכי שיטות קלט).
  • CarRotaryImeRRO שכבת-העל של RotaryIME.

שירות החוגה מופעל באופן אוטומטי כשהמכשיר מבצע אתחול וכשמשתמש מתבצעת העברה. כך ניתן להבטיח שהמשתמש יוכל להשתמש בבקר החוגה במהלך ההגדרה.

אם משתמשים באותו build לרכבים עם או בלי שלט חוגה, מוסיפים את CarRotaryController כמו שמוצג למעלה כדי שהקוד הנדרש ייכלל ב-build. כדי למנוע את הפעלת החוגה במכוניות עם חוגה, צריך ליצור RRO סטטי לשכבת-על של משאב המחרוזת rotaryService packages/services/Car/service עם מחרוזת ריקה. אתם תשתמשו באותו build, אבל יש להם הגדרות אישיות נפרדות של המוצר, למכשירים עם חוגה ולמכשירים שאינם מסתובבים. רק האפשרות השנייה כולל את שכבת-העל.

התאמה אישית

יצרני ציוד מקורי יכולים להתאים אישית את הלוגיקה של מציאת המיקוד, את הרגעים הבולטים ופריטים נוספים באמצעות שכבות-על של משאבים במיקומים הבאים:

  • הספרייה car-ui-Library נמצאת ב-packages/apps/Car/libs/car-ui-lib
  • המיקום של RotaryService הוא packages/apps/Car/RotaryController
  • המיקום של Core הוא frameworks/base/core

הסטת ההיסטוריה

ה-OEM יכול להגדיר אם כל אחד משני סוגים של היסטוריית נדנודים יופעל או לא. אם כן, את המדיניות לגבי גודל מטמון ותוקף. כדי לעשות את זה, מחליפים ספריות שונות של מכוניות במשאבי אנוש.

מיקוד במטמון של ההיסטוריה

(Android 11 QPR3, Android 11 Car, Android 12)
המטמון לכל FocusArea מאחסן את התצוגה שמוקדה לאחרונה FocusArea כדי שניתן יהיה להתמקד כשנדונים חזרה אל FocusArea. ניתן להגדיר את המטמון הזה על ידי יצירת שכבת-על של המשאבים הבאים ב-car-ui-library:

  • car_ui_focus_history_cache_type:
    1. המטמון מושבת.
    2. תוקף המטמון יפוג לאחר זמן מה (ראו בהמשך).
    3. המטמון לא יפוג אף פעם.
  • car_ui_focus_history_expiration_period_ms: כמה אלפיות השנייה לפני התוקף של המטמון יפוג אם סוג המטמון מוגדר לשניים (2) (ראו למעלה).

מטמון ההיסטוריה של FocusArea

(Android 11 QPR3, Android 11 Car, Android 12)
במטמון הזה נשמרים היסטוריה של נדנודים, כך שנדנודים בכיוון ההפוך החזרת המיקוד לאותו FocusArea. אפשר להגדיר את המטמון על ידי הוספת שכבת-על המשאבים הבאים ב-car-ui-library:

  • car_ui_focus_area_history_cache_type:
    1. המטמון מושבת.
    2. התוקף של המטמון פג לאחר זמן מה (ראו בהמשך).
    3. המטמון לא פג אף פעם.
  • car_ui_focus_area_history_expiration_period_ms: כמה אלפיות השנייה לפני התוקף של המטמון יפוג אם סוג המטמון מוגדר ל-2 (ראו למעלה).
  • car_ui_clear_focus_area_history_when_rotating: האם לבטל את המטמון כשהמשתמש מסובב את השלט רחוק.

סיבוב

(Android 11 QPR3, Android 11 Car, Android 12)
יצרן הציוד המקורי יכול לבטל שני משאבים של מספרים שלמים ב-RotaryService כדי לציין אם יש תאוצה, כמו האצת עכבר, עבור סיבוב:

  • rotation_acceleration_3x_ms: מרווח הזמן (באלפיות השנייה) שמשמש להחלטה האם Google צריכה להאיץ את הרוטציה של הבקר כדי לבטל את הסיבוב. אם המרווח בין ערך הסף הזה לבין ערך הסיבוב הקודם קטן מהערך הזה. המערכת תתייחס אליו כאל שלושה גורמים של סיבוב. כדי להשבית את 3× צריך להגדיר זאת ל- 2147483647 האצה.
  • rotation_acceleration_2x_ms: דומה ל-rotation_acceleration_3x_ms. משמש לתאוצה של פי 2. יש להגדיר את הערך 2147483647 כדי להשבית האצה של 2×.

ההאצה פועלת בצורה הטובה ביותר כשיש חותמות זמן נפרדות לכל ערך של זיהוי סבב, חובה מאת VHAL. אם הם לא זמינים, RotaryService מניח שהגורמים הסיבוב מחולק באופן שווה.

/**
     * Property to feed H/W rotary events to android
     *
     * int32Values[0] : RotaryInputType identifying which rotary knob rotated
     * int32Values[1] : number of detents (clicks), positive for clockwise,
     *                  negative for counterclockwise
     * int32Values[2] : target display defined in VehicleDisplay. Events not
     *                  tied to specific display must be sent to
     *                  VehicleDisplay#MAIN.
     * int32values[3 .. 3 + abs(number of detents) - 2]:
     *                  nanosecond deltas between pairs of consecutive detents,
     *                  if the number of detents is > 1 or < -1
     *
     * VehiclePropValue.timestamp: when the rotation occurred. If the number of
     *                             detents is > 1 or < -1, this is when the
     *                             first detent of rotation occurred.
     *
     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
     * @data_enum RotaryInputType
     * @access VehiclePropertyAccess:READ
     */
    HW_ROTARY_INPUT = (
        0x0A20
        | VehiclePropertyGroup:SYSTEM
        | VehiclePropertyType:INT32_VEC
        | VehicleArea:GLOBAL),

התמקדות בהדגשה

יצרן הציוד המקורי יכול לבטל את הדגשת ברירת המחדל של המיקוד במסגרת Android כמה מוקדים מדגישים משאבים ב-car-ui-library.

הדגשת ברירת מחדל של המיקוד

אפליקציית Android מספקת כברירת מחדל הדגשה של המיקוד באמצעות המאפיין selectableItemBackground בTheme.DeviceDefault, המאפיין מתייחס ל-item_background.xml ב-Core. ה-OEM יכול ליצור שכבת-על item_background.xml כדי לשנות את אפשרות ההדגשה של הדגשת המיקוד שמוגדרת כברירת מחדל.

פריט הגרפיקה הזה צריך להיות בדרך כלל מסוג StateListDrawable, שמתאים את הרקע על סמך שילובים שונים של מדינות, כולל android:state_focused ו-android:state_pressed. כשהמשתמש משתמש בבקר החוגה כדי התמקדות בתצוגה, ב-android:state_focused יהיה true, אבל android:state_pressed יהיה false. אם המשתמש לוחץ לחצן המרכז בבקר החוגה, גם android:state_focused וגם הערך android:state_pressed יהיה true בזמן שהמשתמש לוחץ לחיצה ארוכה על הלחצן. כשהמשתמש משחרר את הלחצן, רק android:state_focused יישאר true.

בכתובת car-ui-library נעשה שימוש בעיצוב שנגזר מ-Theme.DeviceDefault. כתוצאה מכך, שכבת-העל הזו משפיעה על אפליקציות שמשתמשות בספרייה הזו ועל אפליקציות שמשתמשות בכל עיצוב שנגזר Theme.DeviceDefault הפעולה הזו לא תשפיע על אפליקציות שמתבססות על עיצוב לא קשור, כמו Theme.Material.

מיקוד המשאבים של הפריטים המודגשים בספרייה ברכב

יצרן הציוד המקורי יכול לשנות כמה משאבים ששמורים בספרייה של המכונית כדי לשלוט באופן שבו הדגשת המיקוד מסתכל על תצוגות עם הדגשה לא מלבנית (למשל, עגולה או בצורת גלולה) אפליקציות שהעיצוב שלהן לא נגזר מ-Theme.DeviceDefault. האלה את המשאבים צריך להציג בשכבת-על כך שההדגשה של ההתמקדות תהיה עקבית הדגשת ברירת מחדל להדגשת המיקוד.

(Android 11 QPR3, Android 11 Car, Android 12)
המשאבים הבאים משמשים כדי לציין מתי התצוגה מתמקדת אך לא נלחץ:

  • car_ui_rotary_focus_fill_color: צבע מילוי.
  • car_ui_rotary_focus_stroke_color: צבע המתאר.
  • car_ui_rotary_focus_stroke_width: עובי המתאר.

(Android 11 QPR3, Android 11 Car, Android 12)
המשאבים הבאים משמשים כדי לציין מתי מתמקדים בתצוגה וגם לוחצים עליה:

  • car_ui_rotary_focus_pressed_fill_color: צבע מילוי.
  • car_ui_rotary_focus_pressed_stroke_color: צבע המתאר.
  • car_ui_rotary_focus_pressed_stroke_width: עובי המתאר.

לפעמים הלחצן מקבל צבע רקע אחיד כדי למשוך אותו לתשומת לב המשתמש, כמו בדוגמה שמוצגת. לכן, יכול להיות שיהיה קשה לראות את המוקד המודגש.

לחצן עם רקע אחיד
איור 2. לחצן עם רקע אחיד

במצב כזה, המפתח יכול לציין הדגשה מותאמת אישית באמצעות צבעים משניים:
  • (Android 11 QPR3, Android 11 Car, Android 12)
    car_ui_rotary_focus_fill_secondary_color
    car_ui_rotary_focus_stroke_secondary_color
  • (Android 12)
    car_ui_rotary_focus_pressed_fill_secondary_color
    car_ui_rotary_focus_pressed_stroke_secondary_color

כל אחד מהצבעים יכול להיות שקוף, וכל אחד מהמאפיינים יכול להיות אפס אם, לדוגמה רציתי רק מילוי או קו מתאר.

הדגשה ב-FocusArea

(Android 11 QPR3, Android 11 Car, Android 12)
ל-FocusArea יש אפשרות לצייר שני סוגים של הדגשה כשאחד מהצאצאים שלו הוא ממוקד. אם תרצו, אפשר להשתמש בשתיהן יחד. התכונה הזו מושבתת כברירת מחדל ב- AOSP, אבל אפשר להפעיל אותו על ידי שינוי המשאבים של ספריית הרכב:

  • car_ui_enable_focus_area_foreground_highlight: שרטוט הדגשה מעל FocusArea וצאצאים שלו. ב-AOSP, פריט הגרפיקה הזה הוא קו מתאר בסביבות FocusArea. יצרני ציוד מקורי יכולים לבטל את פריט car_ui_focus_area_foreground_highlight שניתן להזזה.
  • car_ui_enable_focus_area_background_highlight: שרטוט הדגשה מעל FocusArea אבל מאחורי הצאצאים שלו. ב-AOSP, הפריט הזה שניתן להזזה הוא מילוי מלא. יצרני ציוד מקורי יכולים לבטל את הפריט הגרפי car_ui_focus_area_background_highlight.

עורכי שיטות קלט

עורכי שיטות קלט (IME) הם שיטות קלט. לדוגמה, מקלדת שמופיעה במסך.

(Android 11 QPR3, Android 11 Car, Android 12)
ה-OEM (יצרן הציוד המקורי) צריך ליצור שכבת-על של משאב המחרוזת default_touch_input_method ב-RotaryService כדי לציין את ComponentName של IME מבוסס-מגע. לדוגמה, אם ה-OEM (יצרן הציוד המקורי) משתמש ב-IME שסופק עם Android Automotive, הם צריכים לציין com.google.android.apps.automotive.inputmethod/.InputMethodService

(Android 11 QPR3, Android 11 Car, Android 12)
אם יצרן הציוד המקורי יצר IME במיוחד לחוגה, עליו לציין ComponentName במשאב rotary_input_method. אם מקור המידע הזה תופיע כשכבת-על, ייעשה שימוש ב-IME שצוין בכל פעם שהמשתמש יוצר אינטראקציה עם היחידה הראשית באמצעות הנדנוד, הסיבוב והלחצן המרכזי של השלט רחוק החוגה. כשמשתמש נוגע המסך, ייעשה שימוש ב-IME הקודם. לחצן 'הקודם' (ולחצנים אחרים בחוגה בקר) אין השפעה על בחירת IME. אם המשאב הזה לא משמש כשכבת-על, לא ניתן להחליף IME מתרחשת. קרטון הקרינה לא תומך בחוגה כך שהמשתמש לא יכול להזין טקסט דרך החוגה אם ה-OEM לא סיפק IME סיבובי.

RotaryIME הוא גרסת IME של סיבובי הדגמה. אומנם ברמה הבסיסית, מספיק מומלץ לנסות את החלפת ה-IME האוטומטית שמתוארת למעלה. קוד המקור של RotaryIME אפשר למצוא את packages/apps/Car/tests/RotaryIME/.

נדנודים שלא מופיעים במסך

כברירת מחדל, כשהמשתמש מנסה להזיז את קצה המסך לא קורה דבר. ה-OEM (יצרן הציוד המקורי) יכול להגדיר מה צריך להתרחש בכל אחד מארבעת הכיוונים על ידי ציון שילוב של:

  1. פעולה גלובלית שהוגדרה על ידי AccessibilityService. לדוגמה, GLOBAL_ACTION_BACK
  2. קוד מפתח, כמו KEYCODE_BACK.
  3. כוונה להפעיל פעילות שמיוצגת ככתובת URL.

(Android 11 QPR3, Android 11 Car, Android 12)
הם מצוין על ידי שכבת-על של משאבי המערך הבאים במקטע RotaryService:

  • off_screen_nudge_global_actions: מערך של פעולות גלובליות שצריך לבצע כאשר המשתמש נדנדת למעלה, למטה, שמאלה או ימינה מקצה המסך. לא בוצעה פעולה גלובלית אם הרכיב הרלוונטי של המערך הוא -1.
  • off_screen_nudge_key_codes: מערך של קודים מרכזיים של אירועים מסוג קליק שניתן להחדיר כאשר המשתמש נדחף לקצה המסך, למטה, שמאלה או ימינה. אין אירועים מזינים אם הרכיב הרלוונטי של המערך הוא 0 (KEYCODE_UNKNOWN).
  • off_screen_nudge_intents: מערך של כוונות להפעלת פעילות כאשר המשתמש נדנדת למעלה, למטה, שמאלה או ימינה מקצה המסך. אין פעילות מופעלת אם הרכיב הרלוונטי של המערך ריק.

הגדרות אחרות

צריך להוסיף שכבת-על למשאבים הבאים ב-RotaryService:

  • (Android 11 QPR3, Android 11 Car, Android 12)
    config_showHeadsUpNotificationOnBottom: ערך בוליאני שמייצג אם התראות 'שימו לב' צריכות להופיע בתחתית המסך ולא בחלק העליון. חובה הם בעלי ערך זהה לזה של config_showHeadsUpNotificationOnBottom משאב בוליאני ב- frameworks/base/packages/CarSystemUI/res/values/config.xml
  • (Android 11 QPR3, Android 11 Car, Android 12)
    notification_headsup_card_margin_horizontal: שוליים שמאליים וימינה עבור חלון התראות 'שימו לב'. הערך הזה חייב להיות זהה לערך של משאב אחד (notification_headsup_card_margin_horizontal) של צמצם ב- packages/apps/Car/Notification/res/values/dimens.xml
  • (Android 12)
    excluded_application_overlay_window_titles: מערך של כותרות של חלונות שלא נחשבים לחלונות של שכבות-על. צריך לכלול שמות מחלונות של אפליקציות שמייצגים TaskViews או TaskDisplayAreas. כברירת מחדל, רשימה זו מכילה רק 'מפות'.

אפשר להוסיף שכבת-על למשאב RotaryService הבא:

  • (Android 11 QPR3, Android 11 Car, Android 12)
    long_press_ms: ערך של מספר שלם שמייצג את מספר אלפיות השנייה כדי להפעיל לחיצה ארוכה, צריך ללחוץ לחיצה ארוכה על הלחצן המרכזי. אפס מציין את המערכת צריך להשתמש במצב ברירת המחדל של הזמן הקצוב לתפוגה בלחיצה ארוכה. זהו ערך ברירת המחדל.