پشتیبانی از دکوراسیون سیستم

به‌روزرسانی‌های انجام‌شده در این قسمت‌های خاص نمایش، در این صفحه ارائه می‌شوند.

تزئینات سیستم

اندروید ۱۰ پشتیبانی از پیکربندی نمایشگرهای ثانویه برای نمایش برخی از تزئینات سیستم، مانند تصویر زمینه، نوار ناوبری و لانچر را اضافه می‌کند. به طور پیش‌فرض، نمایشگر اصلی تمام تزئینات سیستم را نشان می‌دهد و نمایشگرهای ثانویه مواردی را که به صورت اختیاری فعال هستند، نشان می‌دهند. می‌توانید پشتیبانی از ویرایشگر روش ورودی (IME) را جدا از سایر تزئینات سیستم تنظیم کنید.

برای افزودن پشتیبانی از تزئینات سیستم در یک نمایشگر خاص یا ارائه یک مقدار پیش‌فرض در /data/system/display_settings.xml ، DisplayWindowSettings#setShouldShowSystemDecorsLocked استفاده کنید. برای مثال، به تنظیمات پنجره نمایش مراجعه کنید.

پیاده‌سازی

DisplayWindowSettings#setShouldShowSystemDecorsLocked همچنین برای آزمایش در WindowManager#setShouldShowSystemDecors قرار دارد. فعال کردن این متد با هدف فعال کردن دکورهای سیستم، پنجره‌های دکوری که قبلاً وجود نداشتند را اضافه نمی‌کند، یا اگر قبلاً وجود داشتند، آنها را حذف نمی‌کند. در بیشتر موارد، تغییر پشتیبانی از دکوراسیون سیستم تنها پس از راه‌اندازی مجدد دستگاه به طور کامل اعمال می‌شود.

بررسی پشتیبانی از تزئینات سیستم در کد پایه WindowManager معمولاً از طریق DisplayContent#supportsSystemDecorations انجام می‌شود، در حالی که بررسی سرویس‌های خارجی (مانند System UI برای بررسی اینکه آیا نوار ناوبری باید نمایش داده شود یا خیر) WindowManager#shouldShowSystemDecors استفاده می‌کند. برای درک آنچه توسط این تنظیم کنترل می‌شود، نقاط فراخوانی این متدها را بررسی کنید.

پنجره‌های دکور رابط کاربری سیستم

اندروید ۱۰ پشتیبانی از پنجره دکور سیستم را برای نوار ناوبری اضافه می‌کند، تنها به این دلیل که نوار ناوبری برای پیمایش بین فعالیت‌ها و برنامه‌ها ضروری است. به طور پیش‌فرض، نوار ناوبری گزینه‌های «بازگشت» و «خانه» را نشان می‌دهد. نوار ناوبری تنها در صورتی گنجانده می‌شود که نمایشگر هدف از تزئینات سیستم پشتیبانی کند (به DisplayWindowSettings مراجعه کنید).

نوار وضعیت یک پنجره سیستمی پیچیده‌تر است، زیرا شامل پنل اعلان‌ها، تنظیمات سریع و قفل صفحه نیز می‌شود. در اندروید ۱۰، نوار وضعیت در نمایشگرهای ثانویه پشتیبانی نمی‌شود. بنابراین، اعلان‌ها، تنظیمات و یک محافظ صفحه کلید کامل فقط در نمایشگر اصلی در دسترس هستند.

پنجره سیستمی « مرور کلی» یا «اخیر» در صفحه نمایش‌های ثانویه پشتیبانی نمی‌شود. در اندروید ۱۰، AOSP فقط «اخیر»ها را در صفحه نمایش پیش‌فرض نمایش می‌دهد و شامل فعالیت‌های همه صفحه نمایش‌ها است. وقتی از «اخیر» اجرا می‌شود، فعالیتی که در صفحه نمایش ثانویه بوده است، به طور پیش‌فرض در آن صفحه نمایش به جلو آورده می‌شود. این رویکرد برخی مشکلات شناخته شده دارد، مانند عدم به‌روزرسانی فوری هنگام نمایش برنامه‌ها در صفحه نمایش‌های دیگر.

پیاده‌سازی

برای پیاده‌سازی ویژگی‌های اضافی رابط کاربری سیستم، تولیدکنندگان دستگاه باید از یک جزء رابط کاربری سیستم واحد استفاده کنند که به اضافه یا حذف نمایشگرها گوش می‌دهد و محتوای مناسب را ارائه می‌دهد.

یک جزء رابط کاربری سیستم که از چند نمایشگر (MD) پشتیبانی می‌کند، باید موارد زیر را مدیریت کند:

  • مقداردهی اولیه چندین نمایشگر در هنگام راه‌اندازی
  • نمایش در زمان اجرا اضافه شد
  • نمایش در زمان اجرا حذف شد

وقتی رابط کاربری سیستم، اضافه شدن یک نمایشگر را قبل از WindowManager تشخیص می‌دهد، یک وضعیت رقابتی ایجاد می‌کند. می‌توانید با پیاده‌سازی یک فراخوانی سفارشی از WindowManager به رابط کاربری سیستم، هنگام اضافه شدن یک نمایشگر، به جای اشتراک در رویدادهای DisplayManager.DisplayListener ، از این امر جلوگیری کنید. برای پیاده‌سازی مرجع، برای پشتیبانی از نوار ناوبری به CommandQueue.Callbacks#onDisplayAddSystemDecorations و برای تصاویر پس‌زمینه به WallpaperManagerInternal#onDisplayAddSystemDecorations مراجعه کنید.

علاوه بر این، اندروید ۱۰ این به‌روزرسانی‌ها را ارائه می‌دهد:

  • کلاس NavigationBarController تمام عملکردهای مربوط به نوارهای ناوبری را کنترل می‌کند.
  • برای مشاهده‌ی یک نوار ناوبری سفارشی، به CarStatusBar مراجعه کنید.
  • TYPE_NAVIGATION_BAR دیگر محدود به یک نمونه واحد نیست و می‌تواند در هر نمایشگر استفاده شود.
  • IWindowManager#hasNavigationBar به‌روزرسانی شده است تا پارامتر displayId را فقط برای رابط کاربری سیستم در بر بگیرد.

پرتابگر

در اندروید ۱۰، هر نمایشگر که برای پشتیبانی از تزئینات سیستم پیکربندی شده است، به طور پیش‌فرض یک پشته خانگی اختصاصی برای فعالیت‌های لانچر با نوع WindowConfiguration#ACTIVITY_TYPE_HOME دارد. هر نمایشگر از یک نمونه جداگانه از فعالیت لانچر استفاده می‌کند:

شکل ۱. مثال لانچر چند نمایشگره برای پلتفرم/توسعه/نمونه‌ها/چندنمایشگره.

اکثر لانچرهای موجود از چندین نمونه پشتیبانی نمی‌کنند و برای اندازه‌های بزرگ صفحه نمایش بهینه نشده‌اند. همچنین، اغلب انتظار می‌رود نوع متفاوتی از تجربه در نمایشگرهای ثانویه/خارجی ارائه شود. برای ارائه یک فعالیت اختصاصی برای صفحه نمایش‌های ثانویه، اندروید ۱۰ دسته SECONDARY_HOME را در فیلترهای intent معرفی کرد. نمونه‌هایی از این فعالیت در تمام نمایشگرهایی که از تزئینات سیستم پشتیبانی می‌کنند، استفاده می‌شود، یکی در هر نمایشگر.

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

این فعالیت باید یک حالت راه‌اندازی داشته باشد که از چندین نمونه جلوگیری نکند و انتظار می‌رود با اندازه‌های مختلف صفحه نمایش سازگار شود. حالت راه‌اندازی نمی‌تواند singleInstance یا singleTask باشد.

پیاده‌سازی

در اندروید ۱۰، RootActivityContainer#startHomeOnDisplay به طور خودکار کامپوننت و intent مورد نظر را بسته به نمایشگری که صفحه اصلی در آن اجرا می‌شود، انتخاب می‌کند. RootActivityContainer#resolveSecondaryHomeActivity شامل منطقی است که کامپوننت activity لانچر را بسته به لانچر انتخاب شده فعلی جستجو می‌کند و در صورت نیاز می‌تواند از پیش‌فرض سیستم استفاده کند (به ActivityTaskManagerService#getSecondaryHomeIntent مراجعه کنید).

محدودیت‌های امنیتی

علاوه بر محدودیت‌هایی که برای فعالیت‌ها در نمایشگرهای ثانویه اعمال می‌شود، برای جلوگیری از احتمال ایجاد یک نمایشگر مجازی با تزئینات سیستم فعال و خواندن اطلاعات حساس کاربر از سطح توسط یک برنامه مخرب، لانچر فقط در نمایشگرهای مجازی متعلق به سیستم ظاهر می‌شود. لانچر محتوا را در نمایشگرهای مجازی غیر سیستمی نمایش نمی‌دهد.

تصاویر پس زمینه

در اندروید ۱۰ و بالاتر، تصاویر پس زمینه در نمایشگرهای ثانویه پشتیبانی می‌شوند:

شکل ۲. تصویر زمینه زنده روی نمایشگرهای داخلی (بالا) و خارجی (پایین).

توسعه‌دهندگان می‌توانند با ارائه android:supportsMultipleDisplays="true" در تعریف XML WallpaperInfo پشتیبانی از ویژگی تصویر زمینه را اعلام کنند. همچنین انتظار می‌رود توسعه‌دهندگان تصویر زمینه، فایل‌های موجود در تصویر زمینه را با استفاده از زمینه نمایش در WallpaperService.Engine#getDisplayContext بارگذاری کنند.

این فریم‌ورک برای هر نمایشگر یک نمونه WallpaperService.Engine ایجاد می‌کند، بنابراین هر موتور سطح و زمینه نمایشگر مخصوص به خود را دارد. توسعه‌دهنده باید مطمئن شود که هر موتور می‌تواند به طور مستقل، با نرخ فریم‌های مختلف و با رعایت VSync، ترسیم کند.

تصاویر پس زمینه را برای صفحه نمایش های جداگانه انتخاب کنید

اندروید ۱۰ پشتیبانی مستقیم پلتفرم را برای انتخاب تصاویر پس زمینه برای صفحه نمایش‌های جداگانه ارائه نمی‌دهد. برای دستیابی به این هدف، به یک شناسه نمایشگر پایدار نیاز است تا تنظیمات تصویر زمینه را برای هر صفحه نمایش حفظ کند. Display#getDisplayId پویا است، بنابراین هیچ تضمینی وجود ندارد که یک صفحه نمایش فیزیکی پس از راه‌اندازی مجدد، شناسه یکسانی داشته باشد.

با این حال، اندروید ۱۰ DisplayInfo.mAddress اضافه کرده است که شامل شناسه‌های پایداری برای نمایشگرهای فیزیکی است و می‌تواند برای پیاده‌سازی کامل در آینده مورد استفاده قرار گیرد. متأسفانه، برای پیاده‌سازی منطق برای اندروید ۱۰ خیلی دیر شده است. راه‌حل پیشنهادی:

  1. برای تنظیم تصاویر پس زمینه از کلاس WallpaperManager استفاده کنید.

    WallpaperManager از یک شیء Context به دست می‌آید و هر شیء Context اطلاعاتی در مورد نمایش مربوطه دارد ( Context#getDisplay/getDisplayId ). بنابراین، می‌توانید displayId از یک نمونه WallpaperManager بدون اضافه کردن متدهای جدید به دست آورید.

  2. در سمت فریم‌ورک، از displayId به دست آمده از یک شیء Context استفاده کنید و آن را به یک شناسه استاتیک (مانند پورت یک نمایشگر فیزیکی) نگاشت کنید. از شناسه استاتیک برای حفظ تصویر زمینه انتخاب شده استفاده کنید.

این راهکار از پیاده‌سازی‌های موجود برای انتخاب‌کننده‌های تصویر زمینه استفاده می‌کند. اگر روی یک نمایشگر خاص باز شده باشد و از زمینه مناسب استفاده کند، هنگام فراخوانی برای تنظیم تصویر زمینه، سیستم می‌تواند به‌طور خودکار نمایشگر را شناسایی کند.

اگر نیاز به تنظیم تصویر زمینه برای نمایشگری غیر از نمایشگر فعلی دارید، یک شیء Context جدید برای نمایشگر هدف ( Context#createDisplayContext ) ایجاد کنید و نمونه WallpaperManager را از آن نمایشگر دریافت کنید.

محدودیت‌های امنیتی

سیستم، تصاویر پس‌زمینه‌ای را که متعلق به خودش نیست، روی نمایشگرهای مجازی نمایش نمی‌دهد. این به دلیل یک نگرانی امنیتی است که یک برنامه مخرب می‌تواند یک نمایشگر مجازی با پشتیبانی فعال از تزئینات سیستم ایجاد کند و اطلاعات حساس کاربر را از روی سطح (مانند یک عکس شخصی) بخواند.

پیاده‌سازی

در اندروید ۱۰، رابط‌های IWallpaperConnection#attachEngine و IWallpaperService#attach پارامتر displayId را برای ایجاد اتصالات به ازای هر نمایشگر می‌پذیرند. WallpaperManagerService.DisplayConnector یک موتور تصویر زمینه و اتصال به ازای هر نمایشگر را کپسوله‌سازی می‌کند. در WindowManager، کنترلرهای تصویر زمینه برای هر شیء DisplayContent در زمان ساخت ایجاد می‌شوند، به جای اینکه برای همه نمایشگرها یک WallpaperController واحد ایجاد شود.

برخی از پیاده‌سازی‌های متد عمومی WallpaperManager (مانند WallpaperManager#getDesiredMinimumWidth ) به‌روزرسانی شدند تا اطلاعات مربوط به نمایشگرهای مربوطه را محاسبه و ارائه دهند. WallpaperInfo#supportsMultipleDisplays و یک ویژگی منبع مربوطه اضافه شدند، به طوری که توسعه‌دهندگان برنامه می‌توانند گزارش دهند که کدام تصاویر پس زمینه برای چندین صفحه نمایش آماده هستند.

اگر سرویس تصویر زمینه نمایش داده شده در نمایشگر پیش‌فرض از چندین نمایشگر پشتیبانی نکند، سیستم تصویر زمینه پیش‌فرض را در نمایشگرهای ثانویه نمایش می‌دهد:

شکل ۳. منطق جایگزین تصویر زمینه برای نمایشگرهای ثانویه.

فعال کردن پشتیبانی از تصویر زمینه زنده

در اندروید ۱۰ و بالاتر (API 29)، توسعه‌دهندگان می‌توانند از ویژگی android:supportsMultipleDisplays برای نشان دادن اینکه آیا تصویر زمینه آنها می‌تواند در نمایشگرهای مختلف نمایش داده شود یا خیر، استفاده کنند. در محیط‌های پنجره‌ای دسکتاپ، که چندوظیفگی فشرده است، رندر کردن تصاویر پس زمینه زنده در نمایشگرهای خارجی می‌تواند به طور قابل توجهی بر GPU و حافظه سربار تأثیر بگذارد.

برای حفظ منابع سیستم، سیستم به طور پیش‌فرض تصاویر پس‌زمینه زنده را روی نمایشگرهای متصل رندر نمی‌کند. وقتی یک تصویر پس‌زمینه زنده توسط پیکربندی سیستم یا مانیفست برنامه محدود شده باشد، سیستم یک تصویر پس‌زمینه ثابت جایگزین رندر می‌کند.

تولیدکنندگان تجهیزات اصلی (OEM) می‌توانند این تجربه را با فعال کردن پشتیبانی از تصویر زمینه زنده برای سخت‌افزارهای رده بالا یا سفارشی‌سازی تصویر زمینه ثابت برای ظاهری مطابق با برند، تنظیم کنند.

اگر سخت‌افزار شما می‌تواند چندین نمونه تصویر زمینه زنده را رندر کند، پیکربندی زیر را لغو کنید:

مسیر منابع فریم‌ورک‌ها/پایه/هسته/res/res/values/config.xml
نام پیکربندی config_isLiveWallpaperSupportedInDesktopExperience

تصویر زمینه جایگزین را سفارشی کنید

اگر تصاویر پس زمینه زنده توسط ارائه دهنده غیرفعال یا پشتیبانی نشوند، سیستم از یک جزء پیش فرض استفاده می‌کند. می‌توانید این را به ارائه دهنده تصویر پس زمینه ثابت خود ارجاع دهید:

مسیر منابع فریم‌ورک‌ها/پایه/هسته/res/res/values/config.xml
نام پیکربندی fallback_wallpaper_component

پشتیبانی از تصویر زمینه را پیاده سازی کنید

برای اعمال این تغییرات، از یک پوشه‌ی منبع زمان ساخت در پوشه‌ی مخصوص دستگاه خود استفاده کنید که معمولاً در device/<vendor>/<product>/overlay/frameworks/base/core/res/res/values/ قرار دارد.