ספריית Jetpack WindowManager מאפשרת למפתחי אפליקציות לתמוך בגורמי צורה חדשים של מכשירים ובסביבות מרובות חלונות.
WindowManager Extensions (תוספים) הוא מודול פלטפורמת Android אופציונלי שמאפשר להשתמש במגוון תכונות של Jetpack WindowManager. המודול מיושם ב-AOSP ב-frameworks/base/libs/WindowManager/Jetpack
ונשלח במכשירים שתומכים בתכונות של WindowManager.
הפצה של מודול התוספים
תוספים עוברים קומפילציה לספרייה .jar
ומוצבים במחיצה system_ext
במכשיר אם התוספים מופעלים בקובץ ה-makefile של המכשיר.
כדי להפעיל תוספים במכשיר, מוסיפים את השורה הבאה לקובץ ה-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. כך הפעולה שלהם דומה לקוד של מסגרת בצד הלקוח, כמו שמוצג באיור הבא:

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

androidx.window.extensions
או אל androidx.window.sidecar
.
מודולים של תוספים
תוספים מספקים תכונות של חלונות למכשירים מתקפלים עם מסכים גדולים ולמכשירים שתומכים בחלונות במסכים חיצוניים. אזורי התכונות כוללים:
הטמעות של Extensions על ידי יצרני ציוד מקורי (OEM) יכולות לספק רכיבים מסוג null או רכיבים עם הטמעות ברירת מחדל או stub של השיטות בממשק WindowExtensions
אם החומרה של המכשיר לא תומכת בתכונות המתאימות, אלא אם התכונה נדרשת באופן ספציפי במסמך הגדרת התאימות (CDD) 7.1.1.1.
תוספים וממשקי API של Jetpack
מודול WindowManager Extensions מספק משטח API משלו בנוסף לממשקי ה-API של הפלטפורמה הציבורית. מודול התוספים מפותח באופן ציבורי בספריית Jetpack androidx.window.extensions
שלא מיועדת למפתחים, כדי ש-Jetpack WindowManager (androidx.window
) יוכל לקשר אליו בזמן ההידור. בדרך כלל, ממשקי ה-API של התוספים מספקים ממשקי API ברמה נמוכה יותר.
ממשקי ה-API שתוספים מספקים מיועדים לשימוש רק בספריית JetpackWindowManager. ממשקי ה-API של התוספים לא מיועדים להפעלה ישירה על ידי מפתחי אפליקציות. כדי להבטיח שהפונקציונליות תפעל בצורה תקינה, אסור להוסיף את ספריית התוספים כתלות לאפליקציה בקובץ ה-build של Gradle. לא כדאי לבצע קומפילציה מראש של ספריית התוספים באפליקציה ישירות. במקום זאת, כדאי להסתמך על טעינה בזמן ריצה כדי למנוע טעינה של שילוב של מחלקות תוספים שעברו קומפילציה מראש ומחלקות תוספים שסופקו בזמן ריצה.
Jetpack WindowManager (androidx.window
) מיועד להוספה כתלות של אפליקציה ומספק את ממשקי ה-API הציבוריים שפונים למפתחים, כולל אלה של תכונות ההרחבות של WindowManager. הספרייה WindowManager טוענת באופן אוטומטי תוספים לתהליך האפליקציה, ועוטפת את ממשקי ה-API של התוספים ברמה נמוכה בהפשטות ברמה גבוהה יותר ובממשקים ממוקדים יותר. ממשקי WindowManager Jetpack API עומדים בתקנים של פיתוח אפליקציות מודרניות ל-Android, ומיועדים לספק יכולת פעולה הדדית נוחה על ידי שילוב טוב עם בסיסי קוד שמשתמשים בספריות אחרות של AndroidX.
גרסאות ועדכונים של תוספים
אפשר לעדכן את מודול התוספים יחד עם עדכונים שנתיים או רבעוניים של פלטפורמת Android. עדכונים רבעוניים מאפשרים להעלות את רמת Extensions API בין עדכוני Android Platform API, וכך לקצר את מחזור הפיתוח ולספק ליצרני ציוד מקורי (OEM) הזדמנות להוסיף גישה רשמית ל-API לתכונות חדשות בסמוך להשקות של חומרה.
בטבלה הבאה מפורטות גרסאות ה-API של androidx.window.extensions
לגרסאות שונות של Android.
גרסת פלטפורמת Android | רמת API של WindowManager Extensions | גרסת ה-API של androidx.window.extensions |
---|---|---|
Android 15 | 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 |
רמת Extensions API (העמודה האמצעית) עולה בכל פעם שמוסיפים משהו לממשק ה-API היציב הקיים (העמודה השמאלית).
תאימות לאחור וקדימה
Jetpack WindowManager מטפל במורכבות של עדכונים תכופים ברמת ה-API, בהתפתחות מהירה של ה-API ובתאימות לגרסאות קודמות. כשקוד הספרייה מופעל בתהליך האפליקציה, הספרייה בודקת את רמת ה-API של התוספים שהוגדרה ומספקת גישה לתכונות בהתאם לרמה שהוגדרה.
כדי להגן על אפליקציה מפני קריסה בזמן הריצה, WindowManager מבצע גם בדיקת השתקפות של Java בזמן הריצה של ממשקי ה-API הזמינים של Extensions בהתאם לרמת ה-API של Extensions שהוגדרה. אם יש אי התאמה, WindowManager יכול להשבית את השימוש בתוספים (באופן חלקי או מלא) ולדווח על התכונות הרלוונטיות כלא זמינות לאפליקציה.
התוספים של WindowManager מיושמים כמודול system_ext
שמשתמש בממשקי API פרטיים של הפלטפורמה כדי לבצע קריאה לליבת WindowManager, DeviceStateManager
ולשירותי מערכת אחרים בהטמעה של תכונות התוספים.
יכול להיות שלא תהיה תאימות לגרסאות של Extensions לפני ההשקה, לפני הגרסה הרבעונית או השנתית התואמת של פלטפורמת Android שבה הגרסאות מסתיימות. היסטוריה מלאה של Extensions APIs זמינה בענף הגרסה window:extensions:extensions
API text files.
גרסאות חדשות יותר של Extensions צריכות להמשיך לפעול עם גרסאות ישנות יותר של WindowManager שקומפלו לאפליקציות, כדי לשמור על תאימות קדימה. כדי להבטיח זאת, כל גרסה חדשה של Extensions API מוסיפה רק ממשקי API חדשים ולא מסירה ממשקי API ישנים יותר. כתוצאה מכך, אפליקציות עם גרסאות ישנות יותר של WindowManager יכולות להמשיך להשתמש בממשקי Extensions API ישנים יותר שהאפליקציות קומפלו איתם.
אימות CTS מבטיח שכל ממשקי ה-API של התוספים לגרסה מסוימת שמוצהרת במכשיר, וגם לגרסאות קודמות, קיימים ופועלים.
ביצועים
מודול התוספים נשמר במטמון בטועני מחלקות מערכת שאינם bootclasspath כברירת מחדל החל מ-Android 14 (רמת API 34), כך שאין השפעה על הביצועים בגלל טעינת המודול לזיכרון בהפעלת האפליקציה. לשימוש בתכונות של מודולים נפרדים עשויה להיות השפעה קלה על מאפייני הביצועים של אפליקציות כשמתבצעות קריאות נוספות ל-IPC בין הלקוח לשרת.
מודולים
הטמעה של פעילות
רכיב הטמעת הפעילות מאפשר לאפליקציות לבצע אופטימיזציה של ממשק המשתמש שלהן למכשירים עם מסך גדול ולמסכים חיצוניים. הטמעת פעילות מאפשרת הצגה של שתי פעילויות זו לצד זו בפריסה מרובת חלוניות, וכך מקלה על פיתוח אפליקציות אדפטיביות לאפליקציות מדור קודם.
רכיב הטמעת הפעילות צריך להיות זמין בכל המכשירים עם מסך מובנה בגודל של sw600dp
ומעלה. צריך להפעיל את הטמעת הפעילות גם במכשירים שתומכים בחיבורים למסכים חיצוניים, כי יכול להיות שהאפליקציה תוצג בגודל גדול יותר כשמסכים חיצוניים מחוברים בזמן הריצה.
תצורת מכשיר
לא נדרשת הגדרה ספציפית של המכשיר, מלבד הפעלת מודול התוספים כמו שמתואר בקטע הפצת מודול התוספים. מומלץ להפעיל את התכונה 'חלונות צמודים' בכל המכשירים שתומכים במצב ריבוי חלונות. בגרסאות עתידיות של Android, סביר להניח שיהיה צורך בתוספים בתצורות נפוצות של מכשירים ניידים ומכשירים עם מסך גדול.
מידע על פריסת החלון
רכיב המידע על פריסת החלונות מזהה את המיקום והמצב של הציר במכשיר מתקפל כשהציר חוצה חלון של אפליקציה. מידע על פריסת החלונות מאפשר לאפליקציות להגיב ולהציג פריסות אופטימליות במצב שולחן במכשירים מתקפלים. פרטים על השימוש זמינים במאמר התאמת האפליקציה למכשירים מתקפלים.
במכשירי Android מתקפלים שכוללים ציר שמחבר בין אזורים נפרדים או רציפים של לוח התצוגה, המידע על הציר צריך להיות זמין לאפליקציות באמצעות WindowLayoutComponent
.
צריך לדווח על המיקום והגבולות של הציר ביחס לחלון האפליקציה שמזוהה על ידי Context
שמועבר ל-API. אם הגבולות של חלון האפליקציה לא חותכים את הגבולות של הציר, אסור לדווח על הציר DisplayFeature
. אפשר גם לא לדווח על תכונות התצוגה אם המיקום שלהן לא יכול להיות מדווח באופן מהימן, למשל אם המשתמש יכול להזיז באופן חופשי את חלון האפליקציה במצב ריבוי חלונות או במצב של התאמה לפורמט מסך רחב.
בתכונות של מכשירים מתקפלים, צריך לדווח על עדכוני המצב כשמיקום הציר משתנה בין המצבים היציבים. כברירת מחדל, במצב תצוגה שטוח, ה-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
- מגדירים את
אימות
יצרני ציוד מקורי (OEM) צריכים לאמת את ההטמעות שלהם כדי לוודא שההתנהגות תהיה צפויה בתרחישים נפוצים. יצרני ציוד מקורי יכולים להשתמש בבדיקות CTS ובבדיקות באמצעות Jetpack WindowManager כדי לבדוק את ההטמעות.
בדיקות CTS
כדי להריץ את בדיקות ה-CTS, אפשר לעיין במאמר בנושא הרצת בדיקות CTS. ב-cts/tests/framework/base/windowmanager/jetpack/
מופיעים בדיקות CTS שקשורות ל-Jetpack WindowManager.
שם מודול הבדיקה הוא CtsWindowManagerJetpackTestCases
.
בדיקות של WindowManager
כדי להוריד את הבדיקות של Jetpack WindowManager, פועלים לפי ההוראות של Android Jetpack.
הבדיקות ממוקמות בספריית החלונות במודול window:window
:
window/window/src/androidTest/
.
כדי להריץ את בדיקות המכשיר עבור מודול window:window
משורת הפקודה, מבצעים את הפעולות הבאות:
- מחברים מכשיר שבו מופעלות האפשרויות למפתחים וניפוי באגים ב-USB.
- מאפשרים למחשב לנפות באגים במכשיר.
- פותחים מעטפת בספריית הבסיס של מאגר androidx.
- שינוי הספרייה ל-
framework/support
. - מריצים את הפקודה הבאה:
./gradlew window:window:connectedAndroidTest
. - מנתחים את התוצאות.
כדי להריץ את הבדיקות מ-Android Studio:
- פותחים את Android Studio.
- מחברים מכשיר שבו מופעלות האפשרויות למפתחים וניפוי באגים ב-USB.
- מאפשרים למחשב לנפות באגים במכשיר.
- עוברים לבדיקה בספריית החלונות של מודול החלונות.
- פותחים כיתת בדיקה ומריצים אותה באמצעות החצים הירוקים בצד שמאל של הכלי לעריכת קוד.
אפשר גם ליצור הגדרה ב-Android Studio כדי להריץ שיטת בדיקה, מחלקת בדיקה או את כל הבדיקות במודול.
אפשר לנתח את התוצאות באופן ידני על ידי עיון בפלט של המעטפת. חלק מהבדיקות מדלגות אם המכשיר לא עומד בהנחות מסוימות. התוצאות נשמרות במיקום סטנדרטי, והאנליסטים יכולים לכתוב סקריפט כדי לבצע ניתוח אוטומטי של התוצאות.