کتابخانه Jetpack WindowManager به توسعهدهندگان برنامهها این امکان را میدهد که از فرمفکتورهای جدید دستگاه و محیطهای چندپنجرهای پشتیبانی کنند.
افزونههای WindowManager (افزونهها) یک ماژول پلتفرم اندروید اختیاری است که طیف وسیعی از ویژگیهای Jetpack WindowManager را فعال میکند. این ماژول در AOSP در frameworks/base/libs/WindowManager/Jetpack پیادهسازی شده و روی دستگاههایی که از ویژگیهای WindowManager پشتیبانی میکنند، عرضه میشود.
توزیع ماژول افزونهها
افزونهها در یک کتابخانه .jar کامپایل میشوند و در صورت فعال بودن افزونهها در فایل ساخت دستگاه، در پارتیشن system_ext دستگاه قرار میگیرند.
برای فعال کردن افزونهها روی یک دستگاه، موارد زیر را به فایل ساخت دستگاه محصول اضافه کنید:
$(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 ماژول Extensions فعلی است که به صورت فعال در حال توسعه است. ماژول androidx.window.sidecar یک ماژول قدیمی است که برای سازگاری با نسخههای اولیه Jetpack WindowManager گنجانده شده است، اما sidecar دیگر به طور فعال پشتیبانی نمیشود.
شکل زیر منطق تعیین استفاده از androidx.window.extensions یا androidx.window.sidecar را نشان میدهد.

androidx.window.extensions یا androidx.window.sidecar .ماژولهای افزونه
افزونهها ویژگیهای پنجرهای را برای دستگاههای تاشو با صفحه نمایش بزرگ و دستگاههایی که از پنجرهای شدن در نمایشگرهای خارجی پشتیبانی میکنند، فراهم میکنند. این ویژگیها عبارتند از:
پیادهسازیهای OEM از Extensionها میتوانند کامپوننتهای null یا کامپوننتهایی با پیادهسازیهای پیشفرض یا stub متدها در رابط WindowExtensions ارائه دهند، در صورتی که سختافزار دستگاه از ویژگیهای مربوطه پشتیبانی نکند، مگر اینکه این ویژگی به طور خاص در سند تعریف سازگاری (CDD) 7.1.1.1 درخواست شده باشد.
افزونهها و APIهای جتپک
ماژول WindowManager Extensions علاوه بر APIهای عمومی پلتفرم، سطح API مخصوص به خود را نیز ارائه میدهد. ماژول Extensions به صورت عمومی در یک کتابخانه Jetpack به نام androidx.window.extensions توسعه داده شده است، به طوری که Jetpack WindowManager ( androidx.window ) میتواند در زمان کامپایل به آن متصل شود. سطح API Extensions معمولاً APIهای سطح پایینتری را ارائه میدهد.
APIهایی که Extensions ارائه میدهند، فقط برای استفاده توسط کتابخانه Jetpack WindowManager در نظر گرفته شدهاند. APIهای Extensions قرار نیست مستقیماً توسط توسعهدهندگان برنامه فراخوانی شوند. کتابخانه Extensions نباید به عنوان یک وابستگی برای یک برنامه در فایل Gradle build اضافه شود تا عملکرد صحیح آن تضمین شود. از کامپایل کردن مستقیم کتابخانه Extensions در یک برنامه خودداری کنید. در عوض، برای جلوگیری از بارگذاری ترکیبی از کلاسهای Extensions از پیش کامپایل شده و ارائه شده در زمان اجرا، به بارگذاری در زمان اجرا تکیه کنید.
Jetpack WindowManager ( androidx.window ) قرار است به عنوان یک وابستگی به برنامه اضافه شود و APIهای عمومی مورد نیاز توسعهدهندگان، از جمله APIهای مربوط به ویژگیهای WindowManager Extensions را فراهم میکند. کتابخانه WindowManager به طور خودکار Extensions را در فرآیند برنامه بارگذاری میکند و APIهای Extensions سطح پایینتر را در انتزاعهای سطح بالاتر و رابطهای متمرکزتر قرار میدهد. APIهای WindowManager Jetpack از استانداردهای توسعه برنامههای مدرن اندروید پیروی میکنند و قرار است با ادغام خوب با پایگاههای کدی که از سایر کتابخانههای AndroidX استفاده میکنند، قابلیت همکاری مناسبی را فراهم کنند.
نسخهها و بهروزرسانیهای افزونهها
ماژول افزونهها (Extensions) میتواند همراه با بهروزرسانیهای سالانه یا فصلی پلتفرم اندروید بهروزرسانی شود. بهروزرسانیهای فصلی امکان افزایش سطح API افزونهها (Extensions API) را بین بهروزرسانیهای API پلتفرم اندروید فراهم میکند و امکان تکرار سریعتر را فراهم میکند و به تولیدکنندگان اصلی تجهیزات (OEM) فرصتی میدهد تا دسترسی رسمی API به ویژگیهای جدید را نزدیک به زمان عرضه سختافزار اضافه کنند.
جدول زیر نسخههای API مربوط androidx.window.extensions را برای نسخههای مختلف اندروید فهرست میکند.
| نسخه پلتفرم اندروید | سطح API افزونههای WindowManager | نسخه API مربوط به androidx.window.extensions |
|---|---|---|
| اندروید ۱۵ | ۶ | ۱.۵.۰ (به زودی) |
| اندروید ۱۴ QPR3 | ۵ | ۱.۴.۰ (به زودی) |
| اندروید ۱۴ QPR1 | ۴ | ۱.۳.۰ |
| اندروید ۱۴ | ۳ | ۱.۲.۰ |
| اندروید ۱۳ QPR3 | ۲ | ۱.۱.۰ |
| اندروید ۱۳ | ۱ | ۱.۰.۰ |
| اندروید ۱۲L | ۱ | ۱.۰.۰ |
سطح API افزونهها (ستون وسط) هر بار که چیزی به سطح API پایدار موجود (ستون سمت راست) اضافه میشود، افزایش مییابد.
سازگاری رو به عقب و رو به جلو
Jetpack WindowManager پیچیدگیهای مربوط به بهروزرسانیهای مکرر سطح API، تکامل سریع API و سازگاری با نسخههای قبلی را مدیریت میکند. هنگامی که کد کتابخانه در فرآیند برنامه اجرا میشود، کتابخانه سطح API افزونههای اعلامشده را بررسی میکند و دسترسی به ویژگیها را مطابق با سطح اعلامشده فراهم میکند.
برای محافظت از برنامه در برابر خرابی در زمان اجرا، WindowManager همچنین یک بررسی بازتاب جاوا در زمان اجرا از APIهای افزونههای موجود مطابق با سطح API افزونههای اعلامشده انجام میدهد. در صورت عدم تطابق، WindowManager میتواند استفاده از افزونهها را (به طور جزئی یا کامل) غیرفعال کند و ویژگیهای مربوطه را به عنوان غیرقابل دسترس برای برنامه گزارش دهد.
افزونههای WindowManager به عنوان یک ماژول system_ext پیادهسازی میشوند که از APIهای خصوصی پلتفرم برای فراخوانی هسته WindowManager، DeviceStateManager و سایر سرویسهای سیستم در پیادهسازی ویژگیهای افزونهها استفاده میکند.
سازگاری ممکن است با نسخههای پیشانتشار افزونهها، قبل از انتشار فصلی یا سالانهی پلتفرم اندروید مربوطه که نسخهها با آن نهایی میشوند، حفظ نشود. تاریخچهی کامل APIهای افزونهها را میتوان در فایلهای متنی API مربوط به شاخهی انتشار window:extensions:extensions یافت.
نسخههای جدیدتر Extensions باید به منظور حفظ سازگاری رو به جلو، به کار با نسخههای قدیمیتر WindowManager کامپایل شده در برنامهها ادامه دهند. برای اطمینان از این امر، هر نسخه جدید Extensions API فقط APIهای جدید را اضافه میکند و APIهای قدیمیتر را حذف نمیکند. در نتیجه، برنامههایی که نسخههای قدیمیتر WindowManager دارند، میتوانند به استفاده از Extensions APIهای قدیمیتری که برنامهها با آنها کامپایل شدهاند، ادامه دهند.
تأیید CTS تضمین میکند که برای هر نسخه اعلامشده از APIهای افزونهها در دستگاه، تمام APIهای آن و نسخههای قبلی موجود و کاربردی هستند.
عملکرد
ماژول Extensions به طور پیشفرض از اندروید ۱۴ (سطح API ۳۴) در لودرهای کلاس سیستم non‑bootclasspath ذخیره میشود، بنابراین هیچ تأثیر عملکردی به دلیل بارگذاری ماژول در حافظه در هنگام راهاندازی برنامه وجود ندارد. استفاده از ویژگیهای ماژولهای جداگانه ممکن است هنگام انجام فراخوانیهای IPC اضافی بین کلاینت و سرور، تأثیر کمی بر ویژگیهای عملکرد برنامهها داشته باشد.
ماژولها
تعبیه فعالیت
کامپوننت تعبیه فعالیت، برنامهها را قادر میسازد تا رابط کاربری خود را برای دستگاههای صفحه نمایش بزرگ و نمایشگرهای خارجی بهینه کنند. تعبیه فعالیت، امکان نمایش دو فعالیت در کنار هم را در یک طرح چند قسمتی فراهم میکند و توسعه تطبیقی برنامه را برای برنامههای قدیمی تسهیل میکند.
کامپوننت تعبیه فعالیت باید در تمام دستگاههایی که نمایشگر داخلی آنها برابر یا بزرگتر از sw600dp است، در دسترس باشد. تعبیه فعالیت همچنین باید در دستگاههایی که از اتصالات نمایشگر خارجی پشتیبانی میکنند، فعال باشد، زیرا ممکن است هنگام اتصال نمایشگرهای خارجی در زمان اجرا، برنامه در اندازه بزرگتری نمایش داده شود.
پیکربندی دستگاه
هیچ پیکربندی خاصی برای دستگاه لازم نیست، جز فعال کردن ماژول افزونهها، همانطور که در بخش توزیع ماژول افزونهها توضیح داده شده است. فعال کردن افزونهها در تمام دستگاههایی که از حالت چند پنجرهای پشتیبانی میکنند، منطقی است. نسخههای آینده اندروید احتمالاً افزونهها را در پیکربندیهای رایج دستگاههای دستی و صفحه نمایش بزرگ الزامی میکنند.
اطلاعات طرح پنجره
مؤلفه اطلاعات طرحبندی پنجره، موقعیت و وضعیت لولا را در یک دستگاه تاشو، هنگامی که لولا از پنجره یک برنامه عبور میکند، مشخص میکند. اطلاعات طرحبندی پنجره، برنامهها را قادر میسازد تا به طرحبندیهای بهینه در حالت رومیزی روی دستگاههای تاشو پاسخ دهند و آنها را نمایش دهند. برای جزئیات استفاده، به بخش «برنامه خود را از حالت تاشو آگاه کنید» مراجعه کنید.
دستگاههای اندرویدی تاشو که شامل لولایی هستند که نواحی جداگانه یا پیوسته پنل نمایشگر را به هم متصل میکند، باید اطلاعات مربوط به لولا را از طریق WindowLayoutComponent در دسترس برنامهها قرار دهند.
موقعیت و مرزهای لولا باید نسبت به پنجره برنامه که توسط Context ارسال شده به API شناسایی میشود، گزارش شوند. اگر مرزهای پنجره برنامه با مرزهای لولا تلاقی نداشته باشند، DisplayFeature لولا نباید گزارش شود. همچنین گزارش نکردن ویژگیهای نمایش در مواردی که موقعیت آنها به طور قابل اعتمادی گزارش نشود، مانند زمانی که یک پنجره برنامه میتواند آزادانه توسط کاربر در حالت چند پنجرهای یا حالت جعبه حروف سازگاری حرکت کند، قابل قبول است.
برای ویژگیهای تاشو ، بهروزرسانیهای وضعیت باید زمانی گزارش شوند که موقعیت لولا بین حالتهای پایدار تغییر کند. بهطور پیشفرض در حالت نمایش مسطح، API باید FoldingFeature.State.FLAT را گزارش کند. اگر سختافزار دستگاه بتواند در حالت پایدار در حالت نیمه تا شده باقی بماند، API باید FoldingFeature.State.HALF_OPENED را گزارش کند. هیچ حالت بستهای در API وجود ندارد، زیرا در چنین حالتی پنجره برنامه یا قابل مشاهده نیست یا از مرزهای لولا عبور نمیکند.
پیکربندی دستگاه
برای پشتیبانی از پیادهسازی ویژگی تاشو، تولیدکنندگان تجهیزات اصلی (OEM) باید موارد زیر را انجام دهند:
وضعیت دستگاه را در
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در device overlay).قالب مورد انتظار برای رشته به صورت زیر است:
<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: در اندروید ۱۴، مقداری که میتواند برای حالتهای شبیهسازیشده استفاده شود که در آن حالت لولا با استفاده از حالت پایه، همانطور که در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>-
مساحت پنجره
مؤلفهی ناحیهی پنجره مجموعهای از ویژگیها را فراهم میکند که به برنامهها امکان دسترسی به نمایشگرها و نواحی نمایش اضافی در برخی از دستگاههای تاشو و چند نمایشگره را میدهد.
حالت نمایش پشتی به یک برنامه امکان میدهد تا پیشنمایش رابط کاربری دوربین را روی نمایشگر جلویی یک دستگاه تاشو نشان دهد تا امکان استفاده از دوربین اصلی دستگاه برای سلفی و ویدیو فراهم شود. دستگاههایی که نمایشگر رویی سازگار با اندروید (مطابق با تعریف CDD اندروید از نظر ویژگیهایی مانند اندازه، تراکم و امکانات ناوبری موجود) دارند که با دوربینهای عقب دستگاه همتراز است، باید دسترسی به حالت نمایش پشتی را فراهم کنند.
در اندروید ۱۴، حالت نمایش دوگانه به برنامههایی که روی نمایشگر داخلی یک دستگاه تاشو اجرا میشوند، امکان میدهد محتوای اضافی را روی نمایشگر جلویی که رو به سایر کاربران است، نمایش دهند؛ برای مثال، نمایشگر جلویی میتواند پیشنمایش دوربین را به شخصی که از او عکس یا فیلم گرفته میشود، نشان دهد.
پیکربندی دستگاه
برای پشتیبانی از پیادهسازی ویژگی تاشو، تولیدکنندگان تجهیزات اصلی (OEM) باید موارد زیر را انجام دهند:
وضعیت دستگاه را در
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اضافه کنید تا برای برنامهها در دسترس باشد.
- وضعیتهای مربوطه را در
در اندروید ۱۴، برای دستگاههایی که از حالت نمایش دوگانه (همزمان) پشتیبانی میکنند:
- مقدار
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 استفاده میکنند، برای آزمایش پیادهسازیها در اختیار تولیدکنندگان اصلی تجهیزات (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 از خط فرمان، موارد زیر را انجام دهید:
- دستگاهی را وصل کنید که گزینههای توسعهدهنده و اشکالزدایی USB آن فعال باشد.
- به کامپیوتر اجازه دهید دستگاه را اشکالزدایی کند.
- یک پوسته (shell) در دایرکتوری ریشه مخزن androidx باز کنید.
- دایرکتوری را به
framework/supportتغییر دهید. - دستور زیر را اجرا کنید:
./gradlew window:window:connectedAndroidTest. - نتایج را تحلیل کنید.
برای اجرای تستها از اندروید استودیو، موارد زیر را انجام دهید:
- اندروید استودیو را باز کنید.
- دستگاهی را وصل کنید که گزینههای توسعهدهنده و اشکالزدایی USB آن فعال باشد.
- به کامپیوتر اجازه دهید دستگاه را اشکالزدایی کند.
- به یک تست در کتابخانه پنجره ماژول پنجره بروید.
- یک کلاس آزمایشی باز کنید و با استفاده از فلشهای سبز رنگ در سمت راست ویرایشگر، آن را اجرا کنید.
از طرف دیگر، میتوانید در اندروید استودیو پیکربندی ایجاد کنید تا یک متد تست، یک کلاس تست یا تمام تستهای یک ماژول را اجرا کنید.
نتایج را میتوان به صورت دستی با نگاه کردن به خروجی پوسته تجزیه و تحلیل کرد. اگر دستگاه فرضیات خاصی را برآورده نکند، برخی از آزمایشها رد میشوند. نتایج در یک مکان استاندارد ذخیره میشوند و تحلیلگران میتوانند اسکریپتی برای خودکارسازی تجزیه و تحلیل نتایج بنویسند.