מדריך אינטגרציה ליצרני OEM

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

VHAL

בקר סיבובי תומך בפעולות הבאות:

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

ראה hardware/interfaces/automotive/vehicle/2.0/types.hal לתיעוד על מאפייני המערכת וה- int32Values ​​המתאימים.

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

דְחִיפָה

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

  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 ​​הבאים כדי לשלוח אירוע לאנדרואיד:

  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 ​​הבאים כדי לשלוח אירוע לאנדרואיד:

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

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

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

כפתור חזרה

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

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

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

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

כפתור בית

טפל בלחצן הבית כפי שהיית עושה בלחצן 'הקודם' אבל עם KEYCODE_HOME במקום KEYCODE_BACK .

כפתורים אחרים

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

בניית תצורה

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

PRODUCT_PACKAGES += CarRotaryController

ייתכן שתרצה לכלול את החבילות הבאות בבניית באגים:

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

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

התאמה אישית

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

  • car-ui-library ממוקמת packages/apps/Car/libs/car-ui-lib
  • RotaryService ממוקם packages/apps/Car/RotaryController
  • Core ממוקם frameworks/base/core

דחף היסטוריה

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

התמקד במטמון ההיסטוריה

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

  • 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_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 )
ה-OEM יכול לעקוף שני משאבים שלמים ב- RotaryService כדי לציין אם יש תאוצה, כגון האצת עכבר, לסיבוב:

  • rotation_acceleration_3x_ms : מרווח זמן (במילישניות) המשמש כדי להחליט אם Google צריכה להאיץ את סיבוב הבקר לצורך מעצור של סיבוב. אם המרווח בין עצירה זו למעצור הסיבוב הקודם קטן מערך זה, הוא יטופל כאל שלושה עצירות סיבוב. הגדר את זה ל-2147483647 כדי להשבית תאוצה של 3×.
  • 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),

הדגשת פוקוס

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

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

מסגרת אנדרואיד מספקת הדגשת מיקוד ברירת מחדל באמצעות התכונה 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 .

התמקד במשאבי הדגשה בספריית רכב-UI

ה-OEM יכול לעקוף כמה משאבים של ספריית משתמש-UI לרכב כדי לשלוט כיצד ייראה הדגשת המיקוד בתצוגות עם הדגשת מיקוד לא מלבנית (כגון עגולה או בצורת גלולה) ובאפליקציות המשתמשות בערכת נושא שאינה נובעת מ- 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
  • ( אנדרואיד 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, אך ניתן להפעיל אותה על ידי דריסת משאבי ספריית רכב-UI:

  • car_ui_enable_focus_area_foreground_highlight : צייר הדגשה על גבי FocusArea והצאצאים שלו. ב-AOSP, הציור הזה הוא קו מתאר סביב ה- FocusArea . יצרני OEM יכולים לעקוף את ה- 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 מבוסס המגע. לדוגמה, אם יצרן הציוד המקורי משתמש ב-IME שסופק עם Android Automotive, עליהם לציין com.google.android.apps.automotive.inputmethod/.InputMethodService .

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

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

דחיפות מחוץ למסך

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

  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 dimen ב- packages/apps/Car/Notification/res/values/dimens.xml
  • ( אנדרואיד 12 )
    excluded_application_overlay_window_titles : מערך של כותרות של חלונות שלא אמורים להיחשב לחלונות שכבת-על. זה צריך לכלול כותרות של חלונות אפליקציה המייצגים TaskViews או TaskDisplayAreas . כברירת מחדל, רשימה זו מכילה רק "מפות".

אתה יכול לכסות את המשאב הבא RotaryService :

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