Dukungan dekorasi sistem

Pembaruan yang dilakukan pada area khusus tampilan tersebut tercantum di bawah ini:

Dekorasi sistem

Android 10 menambahkan dukungan untuk mengonfigurasi komponen sekunder layar untuk menunjukkan dekorasi sistem tertentu, seperti wallpaper, menu navigasi, dan peluncur. Secara default, layar utama menampilkan semua dekorasi sistem, dan tampilan sekunder akan menampilkan keduanya secara opsional. Dukungan untuk Editor Metode Input (IME) dapat diatur terpisah dari dekorasi sistem lainnya.

Gunakan DisplayWindowSettings#setShouldShowSystemDecorsLocked() untuk menambahkan dukungan bagi dekorasi sistem pada tampilan tertentu atau menyediakan nilai default di /data/system/display_settings.xml. Contohnya, lihat Setelan jendela tampilan.

Implementasi

DisplayWindowSettings#setShouldShowSystemDecorsLocked() juga diekspos di WindowManager#setShouldShowSystemDecors() untuk pengujian. Memicu metode ini dengan maksud untuk mengaktifkan dekorasi sistem tidak menambahkan jendela dekorasi yang sebelumnya tidak ada, atau menghapusnya jika ada. Dalam sebagian besar ini, perubahan dukungan dekorasi sistem berdampak penuh hanya setelah memulai ulang perangkat.

Memeriksa dukungan dekorasi sistem di code base WindowManager biasanya melewati DisplayContent#supportsSystemDecorations() saat memeriksa layanan eksternal (seperti UI Sistem untuk memeriksa apakah menu navigasi harus ditampilkan) gunakan WindowManager#shouldShowSystemDecors(). Untuk memahami apa yang dikontrol oleh setelan ini, jelajahi titik panggilan metode ini.

Jendela dekorasi UI sistem

Android 10 menambahkan dukungan jendela dekorasi sistem untuk menu navigasi saja, karena menu navigasi sangat penting untuk berpindah antara aktivitas dan aplikasi. Secara {i>default<i}, {i>navigation bar<i} menampilkan Kemampuan untuk Kembali dan Rumah. Ini disertakan hanya jika layar target mendukung dekorasi sistem (lihat DisplayWindowSettings).

Status bar adalah jendela sistem yang lebih rumit, karena juga berisi Shade Notifikasi, Setelan Cepat, dan Layar Kunci. Di Android 10, status bar tidak didukung pada tampilan sekunder. Oleh karena itu, notifikasi, pengaturan, dan keyguard penuh hanya tersedia di layar utama.

Jendela sistem Ringkasan/Terbaru tidak didukung di sekunder layar. Di Android 10, AOSP hanya menampilkan Recents pada tampilan default dan berisi aktivitas dari semua tampilan. Saat diluncurkan dari Terbaru, aktivitas yang sebelumnya ada di tampilan sekunder dibawa ke depan di yang ditampilkan, secara {i>default<i}. Pendekatan ini memiliki beberapa masalah umum, seperti tidak memperbarui segera ketika aplikasi muncul di layar yang lain.

Implementasi

Untuk mengimplementasikan fitur UI Sistem tambahan, produsen perangkat harus menggunakan komponen UI Sistem tunggal yang memproses penambahan/penghapusan layar dan menyajikan konten yang sesuai.

Komponen UI Sistem yang mendukung Multi-Tampilan (MD) harus menangani kasus berikut:

  • Beberapa inisialisasi tampilan saat startup
  • Tampilan ditambahkan saat runtime
  • Tampilan dihapus saat runtime

Saat UI Sistem mendeteksi penambahan layar sebelum WindowManager, UI akan membuat kondisi race. Hal ini dapat dihindari dengan menerapkan callback khusus dari WindowManager ke UI Sistem saat layar ditambahkan, bukan berlangganan Peristiwa.DisplayListener DisplayManager. Untuk implementasi referensi, lihat CommandQueue.Callbacks#onDisplayReady untuk dukungan menu navigasi dan WallpaperManagerInternal#onDisplayReady untuk wallpaper.

Selain itu, Android 10 menyediakan update berikut:

  • Class NavigationBarController mengontrol semua fungsi khusus untuk bilah navigasi.
  • Untuk melihat menu navigasi yang disesuaikan, lihat CarStatusBar.
  • TYPE_NAVIGATION_BAR tidak lagi dibatasi untuk satu dan dapat digunakan per tampilan.
  • IWindowManager#hasNavigationBar() diupdate untuk menyertakan Parameter displayId hanya untuk UI Sistem.

Peluncur

Di Android 10, setiap tampilan yang dikonfigurasi untuk mendukung dekorasi sistem memiliki stack rumah khusus untuk aktivitas peluncur dengan jenis WindowConfiguration#ACTIVITY_TYPE_HOME, secara default. Setiap tampilan menggunakan instance aktivitas peluncur terpisah.

Gambar 1. Contoh peluncur multi-tampilan untuk platform/development/samples/MultiDisplay

Sebagian besar peluncur yang ada tidak mendukung beberapa instance dan tidak dioptimalkan untuk ukuran layar besar. Selain itu, jenis pengalaman yang berbeda sering diharapkan pada tampilan sekunder/eksternal. Untuk menyediakan aktivitas khusus bagi layar, Android 10 memperkenalkan kategori SECONDARY_HOME dalam intent filter. Instance aktivitas ini digunakan pada semua layar yang mendukung sistem dekorasi, satu per layar.

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

Aktivitas harus memiliki mode peluncuran yang tidak mencegah beberapa dan diharapkan dapat beradaptasi dengan berbagai ukuran layar. Mode peluncuran tidak boleh singleInstance atau singleTask.

Implementasi

Di Android 10, RootActivityContainer#startHomeOnDisplay() secara otomatis memilih komponen dan intent yang diinginkan bergantung pada tampilan di mana layar beranda diluncurkan. RootActivityContainer#resolveSecondaryHomeActivity() berisi logika untuk mencari komponen aktivitas peluncur bergantung pada peluncur yang dipilih dan dapat menggunakan default sistem, jika diperlukan (lihat ActivityTaskManagerService#getSecondaryHomeIntent()).

Pembatasan keamanan

Selain batasan yang berlaku untuk aktivitas pada tampilan sekunder, untuk menghindari kemungkinan aplikasi berbahaya membuat tampilan virtual dengan mengaktifkan Dekorasi sistem dan membaca informasi sensitif dari pengguna, peluncur hanya akan muncul pada tampilan virtual yang dimiliki oleh sistem. Peluncur tidak menampilkan konten di virtual non-sistem.

Wallpaper

Di Android 10 (dan yang lebih tinggi), wallpaper didukung pada tampilan sekunder:

Gambar 2. Wallpaper animasi di internal (di atas) dan eksternal menampilkan (di bawah)

Developer dapat menyatakan dukungan untuk fitur wallpaper dengan memberikan android:supportsMultipleDisplays="true" dalam Definisi XML WallpaperInfo. Developer wallpaper juga diharapkan memuat aset menggunakan konteks tampilan di WallpaperService.Engine#getDisplayContext().

Framework ini membuat satu instance WallpaperService.Engine per tampilan, sehingga setiap mesin memiliki platform dan konteks tampilannya sendiri. Tujuan developer perlu memastikan bahwa setiap mesin dapat menggambar secara independen, dengan kecepatan frame yang berbeda, dengan mematuhi VSYNC.

Memilih wallpaper untuk setiap layar

Android 10 tidak menyediakan dukungan platform langsung untuk memilih wallpaper untuk layar individual. Untuk melakukannya, ID tampilan yang stabil adalah diperlukan untuk mempertahankan setelan wallpaper per tampilan. Display#getDisplayId() bersifat dinamis. Oleh karena itu, tidak ada jaminan bahwa tampilan fisik akan memiliki ID yang sama setelah {i>reboot<i}.

Namun, Android 10 menambahkan DisplayInfo.mAddress, yang berisi ID stabil untuk tampilan fisik dan dapat digunakan untuk implementasi di masa mendatang. Sayangnya, sudah terlambat untuk menerapkan logika untuk Android 10. Solusi yang disarankan:

  1. Gunakan API WallpaperManager untuk menyetel wallpaper.
  2. WallpaperManager diperoleh dari Context dan setiap objek Context memiliki informasi tentang tampilan (Context#getDisplay()/getDisplayId()). Oleh karena itu, Anda dapat mendapatkan displayId dari instance WallpaperManager tanpa menambahkan metode baru.
  3. Di sisi framework, gunakan displayId yang diperoleh dari Context, lalu petakan ke ID statis (seperti port tampilan fisik). Gunakan ID statis untuk mempertahankan wallpaper yang dipilih.

Solusi ini menggunakan implementasi yang ada untuk pemilih wallpaper. Jika ya dibuka pada tampilan tertentu dan menggunakan konteks yang tepat, maka ketika untuk menyetel wallpaper, sistem bisa otomatis mengidentifikasi tampilan.

Jika perlu menyetel wallpaper untuk tampilan selain layar saat ini tampilan, lalu buat objek Context baru untuk tampilan target (Context#createDisplayContext) dan dapatkan WallpaperManager dari tampilan tersebut.

Pembatasan keamanan

Sistem tidak akan menampilkan wallpaper pada tampilan virtual yang bukan miliknya. Hal ini karena permasalahan keamanan bahwa aplikasi berbahaya dapat membuat menampilkan dukungan dekorasi sistem yang diaktifkan dan membaca informasi dari permukaannya (seperti foto pribadi).

Implementasi

Di Android 10, IWallpaperConnection#attachEngine() dan antarmuka IWallpaperService#attach() menerima displayId untuk membuat koneksi per-tampilan. WallpaperManagerService.DisplayConnector merangkum per-tampilan mesin wallpaper dan koneksi. Di WindowManager, pengontrol wallpaper dibuat untuk setiap objek DisplayContent pada saat pembuatan, bukan satu WallpaperController untuk semua tampilan.

Beberapa implementasi metode WallpaperManager publik (seperti WallpaperManager#getDesiredMinimumWidth()) diperbarui untuk menghitung dan menyediakan informasi untuk tampilan yang sesuai. WallpaperInfo#supportsMultipleDisplays() dan atribut ditambahkan, sehingga pengembang aplikasi dapat melaporkan wallpaper siap digunakan di beberapa layar.

Jika layanan wallpaper yang ditampilkan pada tampilan default tidak mendukung beberapa tampilan, sistem akan menampilkan wallpaper default di layar sekunder layar.

Gambar 3. Logika penggantian wallpaper untuk tampilan sekunder