תוספי windowManager

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

תוספי windowManager (תוספים) הוא מודול פלטפורמת Android שאפשר להצטרף אליו, ומאפשר מגוון של תכונות Jetpack windowManager. המודול מוטמע ב-AOSP ב-frameworks/base/libs/WindowManager/Jetpack ונשלח במכשירים שתומכים בתכונות של windowManager.

הפצת מודול של תוספים

אם התוספים מופעלים בקובץ ה-makefile של המכשיר, הם מקובצים לספרייה .jar וממוקמים במחיצה system_ext במכשיר.

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

$(call inherit-product, $(SRC_TARGET_DIR)/product/window_extensions.mk)

הפעולה הזו מפעילה את החבילות androidx.window.extensions ו-androidx.window.sidecar במכשיר ומגדירה את המאפיין persist.wm.extensions.enabled. הכללתם של החבילות האלה בקובץ ה-makefile גם ממקמת הצהרות ב-etc/permissions/, כך שהן יהיו זמינות לתהליכי האפליקציה. בדרך כלל, המודולים נטענים ומופעל כחלק מתהליך האפליקציה בזמן הריצה כשספריית Jetpack WindowManager משתמשת בהם. כך הפעולה שלהם דומה לקוד של מסגרת בצד הלקוח, כפי שמוצג באיור הבא:

איור 1. תוספי windowManager שנטענו לתהליך האפליקציה בדומה לקוד הפלטפורמה.

המודול androidx.window.extensions הוא מודול התוספים הנוכחי שנמצא בפיתוח פעיל. המודול androidx.window.sidecar הוא מודול מדור קודם שכלול בתאימות לגרסאות המוקדמות ביותר של Jetpack windowManager, אבל החלונית הצדדית לא מתוחזקת יותר באופן פעיל.

באיור הבא מוצג הלוגיקה לקביעת השימוש ב-androidx.window.extensions או ב-androidx.window.sidecar.

איור 2. עץ החלטות לגישה אל androidx.window.extensions או אל androidx.window.sidecar.

מודולים של תוספים

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

הטמעות OEM (יצרן ציוד מקורי) של תוספים יכולות לספק רכיבים או רכיבי null עם הטמעות ברירת מחדל או stub של השיטות בממשק WindowExtensions אם חומרת המכשיר לא תומכת בתכונות המקבילות, אלא אם התכונה התבקשה ספציפית במסמך הגדרת התאימות (CDD) 7.1.1.1.

תוספים וממשקי API של Jetpack

המודול 'תוספים של windowManager' מספק פלטפורמת API משלו, בנוסף לממשקי ה-API של הפלטפורמה הציבורית. מודול התוספים מפותח באופן ציבורי בספריית Jetpack‏ androidx.window.extensions שלא מיועדת למפתחים, כדי ש-Jetpack WindowManager‏ (androidx.window) יוכל לקשר אליו בזמן הידור. ממשק Extensions API מספק בדרך כלל ממשקי API ברמה נמוכה יותר.

ממשקי ה-API שהתוספים מספקים מיועדים לשימוש רק בספריית Jetpack Windows Manager. מפתחי האפליקציות לא אמורים לקרוא ישירות לממשקי ה-API של התוספים. אין להוסיף את ספריית התוספים כתלות באפליקציה בקובץ ה-build של Gradle, כדי להבטיח פונקציונליות נכונה. לא מומלץ לבצע הידור מראש של ספריית התוספים לאפליקציה באופן ישיר. במקום זאת, הסתמכו על טעינה בזמן הריצה כדי למנוע טעינה של שילוב של מחלקות של תוספים שעברו הידור מראש וכאלה שסופקו על ידי זמן ריצה.

המטרה של Jetpack windowManager (androidx.window) היא להתווסף כתלות באפליקציה, ולספק את ממשקי ה-API הציבוריים שפונים למפתחים, כולל את ממשקי ה-API המשמשים לתכונות של תוספי windowManager. ספריית WindowManager טוענת באופן אוטומטי את התוספים לתהליך האפליקציה, ומעטפת את ממשקי ה-API של התוספים ברמה נמוכה יותר בממשקים ממוקדים יותר ורמה גבוהה יותר של הפשטה. ממשקי ה-API של WindowManager Jetpack עומדים בתקנים של פיתוח אפליקציות מודרני ל-Android, והם נועדו לספק יכולת פעולה הדדית נוחה על ידי שילוב מוצלח עם בסיסים של קוד שמשתמשים בספריות אחרות של AndroidX.

גרסאות ועדכונים של תוספים

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

בטבלה הבאה מפורטות גרסאות ה-API androidx.window.extensions של גרסאות שונות של Android.

גרסת פלטפורמת Android רמת ה-API של תוספי windowManager גרסת API של androidx.window.extensions
15 Android 6 1.5.0 (בקרוב)
Android 14 QPR3 5 1.4.0 (בקרוב)
Android 14 QPR1 4 1.3.0
Android 14 3 1.2.0
Android 13 QPR3 2 1.1.0
Android 13 1 1.0.0
Android 12L 1 1.0.0

רמת ה-API של התוספים (העמודה המרכזית) גדלת בכל פעם שמתווסף לפלטפורמת ה-API היציבה (העמודה הימנית).

תאימות קדימה ואחורה

Jetpack windowManager מטפל במורכבות של התמודדות עם עדכונים ברמת ה-API בתדירות גבוהה, התפתחות מהירה של ה-API ותאימות לאחור. כשקוד הספרייה מופעל בתהליך הבקשה, הספרייה בודקת את רמת Extensions API שהוגדרה ומספקת גישה לתכונות בהתאם לרמה שהוגדרה.

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

התוספים של WindowManager מיושמים כמודול system_ext שמשתמש בממשקי API פרטיים של פלטפורמה כדי לבצע קריאה ליבה של WindowManager,‏ DeviceStateManager ושירותי מערכת אחרים בהטמעה של תכונות התוספים.

לא ניתן לשמור על התאימות עם גרסאות טרום-השקה של תוספים לפני הפצת הגרסה הרבעונית או השנתית של פלטפורמת Android שבה הגרסאות הסופיות. ההיסטוריה המלאה של ממשקי ה-API של התוספים מופיעה בקובצי הטקסט של ממשק ה-API של window:extensions:extensions בהסתעפות של הגרסה היציבה.

גרסאות חדשות יותר של התוספים חייבות להמשיך לעבוד עם גרסאות ישנות יותר של WindowManager שעברו הידור באפליקציות כדי לשמור על תאימות להעברה. כדי לוודא זאת, בכל גרסה חדשה של Extensions API מתווספים רק ממשקי API חדשים, ולא מוסרים ממשקי API ישנים. כתוצאה מכך, אפליקציות עם גרסאות ישנות יותר של windowManager יכולות להמשיך להשתמש בממשקי ה-API הישנים של תוספים (תוספים) שהאפליקציות יצרו מולם.

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

ביצועים

מודול התוספים נשמר במטמון במטעני הכיתות של המערכת שאינם ב-bootclasspath כברירת מחדל, החל מ-Android 14 (רמת API 34). לכן אין השפעה על הביצועים כתוצאה מהטעינה של המודול לזיכרון בזמן הפעלת האפליקציה. לשימוש בתכונות של מודול בודדות עשויה להיות השפעה קלה על מאפייני הביצועים של אפליקציות, כאשר מבוצעות קריאות IPC נוספות בין הלקוח לשרת.

מודולים

הטמעת פעילויות

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

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

תצורת מכשיר

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

מידע על פריסת החלון

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

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

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

בתכונות מתקפלות, צריך לדווח על עדכוני המצב כשמיקום הציר משתנה בין המצבים היציבים. כברירת מחדל, במצב תצוגה רגילה, ה-API חייב לדווח על הערך FoldingFeature.State.FLAT. אם אפשר להשאיר את חומרת המכשיר במצב מקופל למחצה במצב יציב, ה-API חייב לדווח על FoldingFeature.State.HALF_OPENED. אין מצב סגור ב-API, כי במקרה כזה חלון האפליקציה לא יהיה גלוי או לא יעבור את גבולות הציר.

תצורת מכשיר

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

  • מגדירים את מצבי המכשיר ב-device_state_configuration.xml לשימוש ב-DeviceStateManagerService. למידע נוסף, ראו DeviceStateProviderImpl.java.

    אם הטמעות ברירת המחדל של DeviceStateProvider או של DeviceStatePolicy לא מתאימות למכשיר, אפשר להשתמש בהטמעה מותאמת אישית.

  • מפעילים את מודול התוספים כפי שמתואר בקטע הפצת מודול של תוספים.

  • צריך לציין את המיקום של תכונות התצוגה במשאב המחרוזת com.android.internal.R.string.config_display_features (בדרך כלל ב-frameworks/base/core/res/res/values/config.xml בשכבת-העל של המכשיר).

    הפורמט הנדרש למחרוזת הוא:

    <type>-[<left>,<top>,<right>,<bottom>]

    הערך של type יכול להיות fold או hinge. הערכים של left, top, right ו-bottom הם קואורדינטות של פיקסלים מספרים שלמים במרחב הקואורדינטות של המסך בכיוון הטבעי של התצוגה. מחרוזת ההגדרה יכולה להכיל כמה תכונות תצוגה שמופרדות באמצעות נקודה-פסיק.

    לדוגמה:

    <!-- Jetpack WindowManager display features -->
    <string name="config_display_features" translatable="false">fold-[1000,0,1000,2000]</string>
    
  • מגדירים את המיפוי בין המזהים הפנימיים של מצב המכשיר שמשמשים ב-DeviceStateManager לבין קבועי המצב הציבוריים שנשלחים למפתחים ב-com.android.internal.R.array.config_device_state_postures.

    הפורמט הנדרש לכל רשומה הוא:

    <device_specific_state_identifier>:<Jetpack WindowManager state identifier>

    מזהי המדינה הנתמכים הם:

    • COMMON_STATE_NO_FOLDING_FEATURES = 1: אין במדינה תכונות קיפול לדיווח. לדוגמה, זה יכול להיות המצב הסגור של מכשיר מתקפל טיפוסי, שבו המסך הראשי נמצא בצד הפנימי.
    • COMMON_STATE_HALF_OPENED = 2: תכונת המתקפל פתוחה למחצה.
    • COMMON_STATE_FLAT = 3: תכונת הקיפול שטוחה. לדוגמה, המצב הפתוח של מכשיר אופנתי עם מסך מתקפל פנימה, שבו המסך הראשי נמצא בצד הפנימי.
    • COMMON_STATE_USE_BASE_STATE = 1000: ב-Android 14, ערך שאפשר להשתמש בו למצבים מועתקים שבהם מצב הציר נגזר מהמצב הבסיסי, כפי שמוגדר ב-CommonFoldingFeature.java

    מידע נוסף זמין בכתובת DeviceStateManager.DeviceStateCallback#onBaseStateChanged(int).

    לדוגמה:

    <!-- Map of System DeviceState supplied by DeviceStateManager to WindowManager posture.-->
    <string-array name="config_device_state_postures" translatable="false">
        <item>0:1</item>    <!-- CLOSED       : COMMON_STATE_NO_FOLDING_FEATURES -->
        <item>1:2</item>    <!-- HALF_OPENED  : COMMON_STATE_HALF_OPENED -->
        <item>2:3</item>    <!-- OPENED       : COMMON_STATE_FLAT -->
        <item>3:1</item>    <!-- REAR_DISPLAY : COMMON_STATE_NO_FOLDING_FEATURES -->
        <item>4:1000</item> <!-- CONCURRENT   : COMMON_STATE_USE_BASE_STATE -->
    </string-array>
    

שטח החלונות

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

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

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

תצורת מכשיר

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

  • מגדירים את מצבי המכשיר ב-device_state_configuration.xml לשימוש של DeviceStateManagerService. למידע נוסף, ראו DeviceStateProviderImpl.java.

    אם הטמעת ברירת המחדל של DeviceStateProvider או של DeviceStatePolicy לא מתאימה למכשיר, אפשר להשתמש בהטמעה מותאמת אישית.

  • במכשירים מתקפלים שתומכים במצב פתוח או שטוח, צריך לציין את מזהי המצבים המתאימים ב-com.android.internal.R.array.config_openDeviceStates.

  • במכשירים מתקפלים שתומכים במצבים מקופלים, צריך לציין את מזהי המצבים המתאימים בקטע com.android.internal.R.array.config_foldedDeviceStates.

  • במכשירים מתקפלים פנימה שתומכים במצב מקופל למחצה (הציר פתוח למחצה כמו במחשב נייד), יש לציין את המצבים המתאימים ב-com.android.internal.R.array.config_halfFoldedDeviceStates.

  • במכשירים שתומכים במצב תצוגה אחורית:

    • מציינים את המצבים התואמים ב-com.android.internal.R.array.config_rearDisplayDeviceStates עבור DeviceStateManager.
    • צריך לציין את כתובת התצוגה הפיזית של המסך האחורי בcom.android.internal.R.string.config_rearDisplayPhysicalAddress.
    • צריך לציין את מזהה המצב ב-com.android.internal.R.integer.config_deviceStateRearDisplay שישמש את התוספים.
    • מוסיפים את מזהה המצב ב-com.android.internal.R.array.config_deviceStatesAvailableForAppRequests כדי שהוא יהיה זמין לאפליקציות.
  • ב-Android 14, במכשירים שתומכים במצב תצוגה כפול (בו-זמנית):

    • מגדירים את com.android.internal.R.bool.config_supportsConcurrentInternalDisplays להיות true.
    • צריך לציין את כתובת התצוגה הפיזית של המסך האחורי בcom.android.internal.R.config_deviceStateConcurrentRearDisplay.
    • אם המזהה מיועד להיות זמין לאפליקציות, צריך לציין את מזהה המצב ב-com.android.internal.R.integer.config_deviceStateConcurrentRearDisplay כדי שתוספים יוכלו להשתמש בו.
    • מוסיפים את מזהה המצב ב-com.android.internal.R.array.config_deviceStatesAvailableForAppRequests כדי שהוא יהיה זמין לאפליקציות.

אימות

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

בדיקות CTS

במאמר הרצת בדיקות CTS מוסבר איך מריצים את בדיקות CTS. בדיקות ה-CTS שקשורות ל-Jetpack windowManager מתבצעות ב-cts/tests/framework/base/windowmanager/jetpack/. שם מודול הבדיקה הוא CtsWindowManagerJetpackTestCases.

בדיקות windowManager

כדי להוריד את הבדיקות של Jetpack windowManager, פועלים לפי ההוראות ל-Android Jetpack. הבדיקות נמצאות בספריית החלונות במודול window:window: window/window/src/androidTest/.

כדי להריץ את בדיקות המכשיר של המודול window:window משורת הפקודה, מבצעים את הפעולות הבאות:

  1. מחברים מכשיר שבו האפשרויות למפתחים וניפוי הבאגים ב-USB מופעלים.
  2. מאפשרים למחשב לנפות באגים במכשיר.
  3. פותחים מעטפת בספריית השורש של מאגר androidx.
  4. שינוי הספרייה לתיקייה framework/support.
  5. מריצים את הפקודה הבאה: ./gradlew window:window:connectedAndroidTest.
  6. בודקים את התוצאות.

כדי להריץ את הבדיקות מ-Android Studio:

  1. פותחים את Android Studio.
  2. יש לחבר מכשיר שבו האפשרויות למפתחים וניפוי הבאגים ב-USB מופעלים.
  3. מאפשרים למחשב לנפות באגים במכשיר.
  4. עוברים לבדיקה בספריית החלונות של מודול החלון.
  5. פותחים כיתה לבדיקה ומריצים אותה באמצעות החיצים הירוקים שמשמאל לכלי העריכה.

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

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