תמיכה בקישוטי המערכת

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

קישוטי המערכת

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

שימוש בפורמט DisplayWindowSettings#setShouldShowSystemDecorsLocked() כדי להוסיף תמיכה בקישוטי מערכת במסך ספציפי או ערך ברירת מחדל ב-/data/system/display_settings.xml. לדוגמה, ראו הגדרות של חלון תצוגה.

הטמעה

DisplayWindowSettings#setShouldShowSystemDecorsLocked() נחשף גם ב- WindowManager#setShouldShowSystemDecors() לבדיקה. הפעלה של השיטה הזו מתוך כוונה להפעיל עיצובים של המערכת לא מוסיפה חלונות עיצוב חסרות בעבר, או להסיר אותן אם הן היו קיימות בעבר. במרבית במקרים רבים, השינוי בתמיכה בקישוטי המערכת נכנס לתוקף במלואו רק לאחר להפעיל מחדש את המכשיר.

בדיקות אם יש תמיכה בקישוטי המערכת בבסיס הקוד של windowManager בדרך כלל דרך DisplayContent#supportsSystemDecorations() חיפוש שירותים חיצוניים (למשל, ממשק המשתמש של המערכת כדי לבדוק אם סרגל הניווט) צריך להציג) יש להשתמש ב-WindowManager#shouldShowSystemDecors(). כדי להבין מה נשלט על ידי ההגדרה הזו, כדאי לבדוק את נקודות השיחה של את השיטות האלה.

חלונות עיצוב לממשק המשתמש של המערכת

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

שורת הסטטוס היא חלון מערכת מורכב יותר, כי מכיל גם את 'אזור ההתראות', 'הגדרות מהירות' ו'מסך נעילה'. ב-Android 10, שורת הסטטוס לא נתמכת במסכים משניים. לכן, התראות, הגדרות ושומר מקשים מלא זמינים רק המסך הראשי.

חלון המערכת סקירה כללית/אחרונים לא נתמך במכשיר המשני מסכים. ב-Android 10, AOSP מציג את האפשרות 'אחרונים' רק בתצוגת ברירת המחדל ומכיל פעילויות מכל המסכים. בהפעלה מ: פעילות מהזמן האחרון, פעילות שהייתה במסך משני מועברת לחזית המכשיר שמוצגות כברירת מחדל. בגישה הזאת יש כמה בעיות ידועות, כגון מתבצע עדכון מיידי כשאפליקציות מופיעות במסכים אחרים.

הטמעה

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

רכיב בממשק המשתמש של המערכת שתומך בתצוגה מרובת מסכים (MD) צריך לטפל במקרים הבאים:

  • אתחול מספר מסכים בזמן ההפעלה
  • המסך נוסף בזמן הריצה
  • המסך הוסר בזמן הריצה

כשממשק המשתמש של המערכת מזהה הוספה של תצוגה לפני windowManager, הוא יוצר מרוץ תהליכים. אפשר למנוע זאת על ידי הטמעת קריאה חוזרת בהתאמה אישית: windowManager לממשק המשתמש של המערכת כשנוסף מסך במקום להירשם למינוי אירועי DisplayManager.DisplayListener. לצורך הטמעה של קובצי עזר, תמיכה בסרגל הניווט מופיעה בCommandQueue.Callbacks#onDisplayReady ו-WallpaperManagerInternal#onDisplayReady לטפטים.

בנוסף, ב-Android 10 קיימים העדכונים הבאים:

  • המחלקה NavigationBarController שולטת בכל הפונקציונליות ספציפיים לסרגלי הניווט.
  • בכתובת CarStatusBar אפשר להציג סרגל ניווט מותאם אישית.
  • הסרטון TYPE_NAVIGATION_BAR כבר לא מוגבל לצפייה בודדת וניתן להשתמש בו בכל תצוגה.
  • IWindowManager#hasNavigationBar() עודכן וכולל את פרמטר displayId לממשק המשתמש של המערכת בלבד.

מרכז האפליקציות

ב-Android 10, כל מסך שהוגדר לתמיכה לקישוטי המערכת יש מקבץ בית ייעודי לפעילויות של מרכז האפליקציות מסוג WindowConfiguration#ACTIVITY_TYPE_HOME, כברירת מחדל. כל תצוגה משתמש במופע נפרד של פעילות במרכז האפליקציות.

איור 1. דוגמה למרכז האפליקציות לתצוגה מרובת מסכים עבור platform/development/samples/MultiDisplay

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

<activity>
    ...
    <intent-filter>
        <category android:name="android.intent.category.SECONDARY_HOME" />
        ...
    </intent-filter>
</activity>

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

הטמעה

ב-Android 10, RootActivityContainer#startHomeOnDisplay() בוחר אוטומטית את הרכיב והכוונה הרצויים בהתאם למסך שבו מופעל מסך הבית. RootActivityContainer#resolveSecondaryHomeActivity() מכיל את הלוגיקה לחיפוש רכיב הפעילות של מרכז האפליקציות, בהתאם במרכז האפליקציות הנבחר ויכול להשתמש בברירת המחדל של המערכת, במקרה הצורך (ראו ActivityTaskManagerService#getSecondaryHomeIntent()).

הגבלות אבטחה

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

טפטים

ב-Android מגרסה 10 ואילך), יש תמיכה בטפטים במסכים משניים:

איור 2. טפט דינמי במסך פנימי (למעלה) וחיצוני מסכים (מתחת)

מפתחים יכולים להצהיר על תמיכה בתכונה 'טפט' על ידי הוספת android:supportsMultipleDisplays="true" ב- הגדרת XML WallpaperInfo. מפתחי טפטים הם גם צפויה לטעון נכסים באמצעות הקשר התצוגה WallpaperService.Engine#getDisplayContext()

תוכנת ה-framework יוצרת מכונה אחת מסוג WallpaperService.Engine כך שלכל מנוע יש משטח והקשר תצוגה משלו. צריך לוודא שכל מנוע יכול לשרטט בנפרד, קצבי פריימים שונים, בהתאם ל-VSYNC.

בחירת טפטים למסכים ספציפיים

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

אבל ב-Android 10 נוספו DisplayInfo.mAddress, שכולל מזהים קבועים של מסכים פיזיים ואפשר להשתמש בו את ההטמעה שלו בעתיד. לצערי מאוחר מדי ליישם את הלוגיקה ל-Android 10. הפתרון המוצע:

  1. משתמשים ב-API WallpaperManager כדי להגדיר את הטפטים.
  2. הערך WallpaperManager מתקבל מ-Context וכל אובייקט Context מכיל מידע על מסך (Context#getDisplay()/getDisplayId()). לכן, אפשר משיגים displayId ממכונה של WallpaperManager בלי להוסיף שיטות חדשות.
  3. בצד של ה-framework, משתמשים בפונקציה displayId שהתקבל אובייקט Context וממפים אותו למזהה סטטי (כמו יציאה של תצוגה פיזית). משתמשים במזהה הסטטי כדי לשמור את הטפט שנבחר.

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

אם יש צורך להגדיר טפט עבור תצוגה שאינה הנוכחית תצוגה, ואז ליצור אובייקט Context חדש לתצוגת היעד (Context#createDisplayContext) ולקבל את מופע WallpaperManager מהתצוגה הזו.

הגבלות אבטחה

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

הטמעה

ב-Android 10, IWallpaperConnection#attachEngine() ו-IWallpaperService#attach() מקבלים את displayId ליצירת חיבורים לכל תצוגה. WallpaperManagerService.DisplayConnector כולל נתון לכל תצוגה מנוע הטפט והחיבור. ב-WindowManager, בקרי הטפטים שנוצר לכל אובייקט DisplayContent בבנייה במקום WallpaperController יחיד לכל המסכים.

חלק מההטמעות הציבוריות של WallpaperManager (כמו WallpaperManager#getDesiredMinimumWidth()) עודכנו לצורך חישוב ולספק מידע על המסכים התואמים. WallpaperInfo#supportsMultipleDisplays() ותווית תואמת נוסף מאפיין של משאב, כדי שמפתחי האפליקציות יוכלו לדווח הטפטים מוכנים להצגה במספר מסכים.

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

איור 3. לוגיקה חלופית של טפטים למסכים משניים