Dukungan dekorasi sistem

Pembaruan yang dilakukan pada area khusus tampilan ini diberikan di bawah:

Dekorasi sistem

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

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

Implementasi

DisplayWindowSettings#setShouldShowSystemDecorsLocked() juga ditampilkan di WindowManager#setShouldShowSystemDecors() untuk pengujian. Memicu metode ini dengan intent untuk mengaktifkan dekorasi sistem tidak akan menambahkan jendela dekorasi yang sebelumnya tidak ada, atau menghapusnya jika sebelumnya ada. Dalam sebagian besar kasus, perubahan dukungan dekorasi sistem hanya akan diterapkan sepenuhnya setelah perangkat dimulai ulang.

Pemeriksaan dukungan dekorasi sistem di codebase WindowManager biasanya melalui DisplayContent#supportsSystemDecorations(), sedangkan pemeriksaan untuk layanan eksternal (seperti UI Sistem untuk memeriksa apakah menu navigasi harus ditampilkan) menggunakan WindowManager#shouldShowSystemDecors(). Untuk memahami apa yang dikontrol oleh setelan ini, pelajari 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 bernavigasi di antara aktivitas dan aplikasi. Secara default, menu navigasi menampilkan akses Kembali dan Beranda. Ini hanya disertakan jika tampilan target mendukung dekorasi sistem (lihat DisplayWindowSettings).

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

Jendela sistem Ringkasan/Terbaru tidak didukung di layar sekunder. Di Android 10, AOSP hanya menampilkan Terbaru di layar default dan berisi aktivitas dari semua layar. Saat diluncurkan dari Terbaru, aktivitas yang berada di layar sekunder akan ditampilkan di depan layar tersebut, secara default. Pendekatan ini memiliki beberapa masalah umum, seperti tidak langsung diupdate saat aplikasi muncul di layar lain.

Implementasi

Untuk menerapkan fitur UI Sistem tambahan, produsen perangkat harus menggunakan satu komponen UI Sistem yang memproses penambahan/penghapusan tampilan dan menampilkan konten yang sesuai.

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

  • Inisialisasi beberapa layar saat memulai
  • Layar ditambahkan saat runtime
  • Layar dihapus saat runtime

Saat UI Sistem mendeteksi penambahan layar sebelum WindowManager, UI Sistem akan membuat kondisi race. Hal ini dapat dihindari dengan menerapkan callback kustom dari WindowManager ke UI Sistem saat layar ditambahkan, bukan berlangganan peristiwa DisplayManager.DisplayListener. 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 menu navigasi.
  • Untuk melihat menu navigasi yang disesuaikan, lihat CarStatusBar.
  • TYPE_NAVIGATION_BAR tidak lagi dibatasi untuk satu instance dan dapat digunakan per tampilan.
  • IWindowManager#hasNavigationBar() diperbarui untuk menyertakan parameter displayId hanya untuk UI Sistem.

Peluncur

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

Gambar 1. Contoh peluncur multi-layar 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 kali diharapkan di layar sekunder/eksternal. Untuk menyediakan aktivitas khusus bagi layar sekunder, Android 10 memperkenalkan kategori SECONDARY_HOME dalam filter intent. Instance aktivitas ini digunakan pada semua layar yang mendukung dekorasi sistem, satu instance untuk setiap layar.

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

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

Implementasi

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

Pembatasan keamanan

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

Wallpaper

Di Android 10 (dan yang lebih baru), wallpaper didukung di layar sekunder:

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

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

Framework membuat satu instance WallpaperService.Engine per tampilan, sehingga setiap mesin memiliki platform dan konteks tampilannya sendiri. Developer harus memastikan bahwa setiap mesin dapat menggambar secara independen, dengan kecepatan frame yang berbeda, dengan mempertimbangkan VSYNC.

Memilih wallpaper untuk setiap layar

Android 10 tidak menyediakan dukungan platform langsung untuk memilih wallpaper untuk setiap layar. Untuk melakukannya, diperlukan ID tampilan yang stabil untuk mempertahankan setelan wallpaper per tampilan. Display#getDisplayId() bersifat dinamis, jadi tidak ada jaminan bahwa tampilan fisik akan memiliki ID yang sama setelah reboot.

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

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

Solusi ini menggunakan implementasi yang ada untuk pemilih wallpaper. Jika dibuka di layar tertentu dan menggunakan konteks yang tepat, saat memanggil untuk menyetel wallpaper, sistem dapat otomatis mengidentifikasi layar.

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

Pembatasan keamanan

Sistem tidak akan menampilkan wallpaper di layar virtual yang bukan miliknya. Hal ini disebabkan oleh masalah keamanan bahwa aplikasi berbahaya dapat membuat tampilan virtual dengan dukungan dekorasi sistem yang diaktifkan dan membaca informasi sensitif pengguna dari platform (seperti foto pribadi).

Implementasi

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

Beberapa implementasi metode WallpaperManager publik (seperti WallpaperManager#getDesiredMinimumWidth()) telah diperbarui untuk menghitung dan memberikan informasi untuk tampilan yang sesuai. WallpaperInfo#supportsMultipleDisplays() dan atribut resource yang sesuai telah ditambahkan, sehingga developer aplikasi dapat melaporkan wallpaper mana yang siap untuk beberapa layar.

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

Gambar 3. Logika penggantian wallpaper untuk layar sekunder