Ekran desteği

Bu ekrana özel alanlarda yapılan güncellemeler aşağıda verilmiştir:

Etkinlikleri ve ekranları yeniden boyutlandırın

Bir uygulamanın çoklu pencere modunu veya yeniden boyutlandırmayı desteklemeyebileceğini belirtmek için etkinlikler resizeableActivity=false özelliğini kullanır. Etkinlikler yeniden boyutlandırıldığında uygulamaların karşılaştığı yaygın sorunlar şunlardır:

  • Bir aktivite, uygulamadan veya başka bir görsel olmayan bileşenden farklı bir konfigürasyona sahip olabilir. Yaygın bir hata, ekran metriklerini uygulama bağlamından okumaktır. Döndürülen değerler, bir etkinliğin görüntülendiği görünür alan metriklerine göre ayarlanmayacaktır.
  • Bir etkinlik, örnek durumunu kaydetmeden yeniden boyutlandırma ve çökme işlemlerini gerçekleştiremeyebilir, bozuk bir kullanıcı arayüzü görüntüleyemeyebilir veya yeniden başlatma nedeniyle durumu kaybedemeyebilir.
  • Bir uygulama, çoklu pencerede girişi bozabilecek mutlak giriş koordinatlarını (pencere konumuna göre olanlar yerine) kullanmaya çalışabilir.

Android 7'de (ve üzeri), bir uygulama her zaman tam ekran modunda çalışacak şekilde resizeableActivity=false olarak ayarlanabilir. Bu durumda platform, yeniden boyutlandırılamayan etkinliklerin bölünmüş ekrana geçmesini engeller. Kullanıcı zaten bölünmüş ekran modundayken başlatıcıdan yeniden boyutlandırılamayan bir etkinliği çağırmaya çalışırsa, platform bölünmüş ekran modundan çıkar ve yeniden boyutlandırılamayan etkinliği tam ekran modunda başlatır.

Bu özelliği bildirimde açıkça false olarak ayarlayan uygulamalar, uyumluluk modu uygulanmadığı sürece çoklu pencere modunda başlatılmamalıdır:

  • Tüm etkinlikleri ve etkinlik dışı bileşenleri içeren sürece aynı konfigürasyon uygulanır.
  • Uygulanan yapılandırma, uygulama uyumlu ekranlar için CDD gereksinimlerini karşılar.

Android 10'da platform, yeniden boyutlandırılamayan etkinliklerin bölünmüş ekran moduna geçmesini hâlâ engelliyor ancak etkinlik sabit bir yön veya en boy oranı bildirmişse bunlar geçici olarak ölçeklendirilebilir. Aksi takdirde etkinlik, Android 9 ve önceki sürümlerde olduğu gibi ekranın tamamını dolduracak şekilde yeniden boyutlandırılır.

Varsayılan uygulama aşağıdaki politikayı uygular:

android:resizeableActivity özelliği kullanılarak çoklu pencereyle uyumsuz olduğu bildirilen bir etkinlik ve bu etkinlik aşağıda açıklanan koşullardan birini karşıladığında, uygulanan ekran yapılandırmasının değişmesi gerektiğinde etkinlik ve süreç orijinal yapılandırmayla kaydedilir. ve kullanıcıya, güncellenmiş ekran yapılandırmasını kullanmak üzere uygulama sürecini yeniden başlatma olanağı sağlanır.

  • android:screenOrientation uygulaması aracılığıyla sabit yönlendirme
  • Uygulama, API düzeyini hedefleyerek varsayılan maksimum veya minimum en boy oranına sahiptir veya en boy oranını açıkça beyan eder

Bu şekil, bildirilen en boy oranına sahip, yeniden boyutlandırılamayan bir etkinliği görüntüler. Cihazı katlarken, uygun posta kutusu kullanılarak en boy oranı korunurken pencere alana sığacak şekilde küçültülür. Ayrıca aktiviteye ait görüntüleme alanı her değiştiğinde kullanıcıya aktiviteyi yeniden başlatma seçeneği sunulur.

Cihazı açarken etkinliğin yapılandırması, boyutu ve en boy oranı değişmez ancak etkinliği yeniden başlatma seçeneği görüntülenir.

resizeableActivity ayarlanmadığında (veya true olarak ayarlandığında), uygulama yeniden boyutlandırmayı tamamen destekler.

Uygulama

Sabit yönlendirmeye veya en boy oranına sahip, yeniden boyutlandırılamayan bir etkinliğe kodda boyut uyumluluk modu (SCM) adı verilir. Koşul ActivityRecord#shouldUseSizeCompatMode() içinde tanımlanmıştır. Bir SCM etkinliği başlatıldığında, ekranla ilgili yapılandırma (boyut veya yoğunluk gibi) talep edilen geçersiz kılma yapılandırmasında sabitlenir, böylece etkinlik artık geçerli ekran yapılandırmasına bağlı değildir.

SCM etkinliği ekranın tamamını dolduramazsa yukarıya hizalanır ve yatay olarak ortalanır. Etkinlik sınırları AppWindowToken#calculateCompatBoundsTransformation() tarafından hesaplanır.

Bir SCM etkinliği kapsayıcısından farklı bir ekran yapılandırması kullandığında (örneğin, ekran yeniden boyutlandırıldığında veya etkinlik başka bir ekrana taşındığında), ActivityRecord#inSizeCompatMode() doğrudur ve SizeCompatModeActivityController (Sistem kullanıcı arayüzünde) süreci göstermek için geri aramayı alır yeniden başlat düğmesi.

Ekran boyutları ve en boy oranları

Android 10, yüksek oranlı uzun ve ince ekranlardan 1:1 oranlarına kadar yeni en boy oranları için destek sağlıyor. Uygulamalar, işleyebilecekleri ekranın ApplicationInfo#maxAspectRatio ve ApplicationInfo#minAspectRatio değerlerini tanımlayabilir.

Android 10'daki uygulama oranları

Şekil 1. Android 10'da desteklenen örnek uygulama oranları

Cihaz uygulamalarında, Android 9'un gerektirdiğinden daha küçük ve daha düşük boyutlara ve çözünürlüklere sahip ikincil ekranlar bulunabilir (minimum 2,5 inç genişlik veya yükseklik, en küçük smallestScreenWidth için minimum 320 DP), ancak yalnızca bu küçük ekranları desteklemeyi tercih eden etkinlikler kullanılabilir. oraya yerleştirildi.

Uygulamalar, hedef görüntüleme boyutuna eşit olandan daha küçük bir desteklenen minimum boyut bildirerek bu seçeneği etkinleştirebilir. Bunu yapmak için AndroidManifest'teki android:minHeight ve android:minWidth etkinlik düzeni niteliklerini kullanın.

Politikaları görüntüle

Android 10, belirli görüntüleme politikalarını PhoneWindowManager varsayılan WindowManagerPolicy uygulamasından ayırarak ekran başına sınıflara taşır, örneğin:

  • Görüntü durumu ve döndürme
  • Bazı tuşlar ve hareket olayı takibi
  • Sistem kullanıcı arayüzü ve dekorasyon pencereleri

Android 9'da (ve daha eski sürümlerde), PhoneWindowManager sınıfı görüntüleme politikalarını, durumu ve ayarları, döndürmeyi, dekorasyon penceresi çerçevesi izlemeyi ve daha fazlasını yönetiyordu. Android 10, DisplayRotation taşınan rotasyon izleme dışında bunların çoğunu DisplayPolicy sınıfına taşır.

Pencere ayarlarını görüntüle

Android 10'da, ekrana göre yapılandırılabilir pencereleme ayarı aşağıdakileri içerecek şekilde genişletildi:

  • Varsayılan ekran pencereleme modu
  • Aşırı tarama değerleri
  • Kullanıcı döndürme ve döndürme modu
  • Zorunlu boyut, yoğunluk ve ölçeklendirme modu
  • İçerik kaldırma modu (ekran kaldırıldığında)
  • Sistem dekorasyonları ve IME desteği

DisplayWindowSettings sınıfı bu seçeneklere ilişkin ayarları içerir. Bir ayar her değiştirildiğinde, display_settings.xml dosyasındaki /data bölümünde diske kaydedilmeye devam edilir. Ayrıntılar için bkz. DisplayWindowSettings.AtomicFileStorage ve DisplayWindowSettings#writeSettings() . Cihaz üreticileri, cihaz yapılandırmaları için display_settings.xml dosyasında varsayılan değerleri sağlayabilirler. Ancak dosya /data konumunda saklandığından, silme işlemiyle silinirse dosyayı geri yüklemek için ek mantığa ihtiyaç duyulabilir.

Varsayılan olarak Android 10, ayarları sürdürürken bir ekranın tanımlayıcısı olarak DisplayInfo#uniqueId kullanır. uniqueId tüm ekranlar için doldurulmalıdır. Ayrıca fiziksel ve ağ ekranları için de stabildir. Ayrıca DisplayWindowSettings#mIdentifier içinde ayarlanabilen, tanımlayıcı olarak fiziksel bir ekranın bağlantı noktasını kullanmak da mümkündür. Her yazma işleminde tüm ayarlar yazılır, böylece depolamadaki bir ekran girişi için kullanılan anahtarı güncellemek güvenli olur. Ayrıntılar için bkz. Statik ekran tanımlayıcıları .

Ayarlar, geçmiş nedenlerden dolayı /data dizininde korunur. Başlangıçta, ekran döndürme gibi kullanıcı tarafından belirlenen ayarları sürdürmek için kullanılıyorlardı.

Statik ekran tanımlayıcıları

Android 9 (ve altı), çerçevedeki ekranlar için kararlı tanımlayıcılar sağlamıyordu. Sisteme bir ekran eklendiğinde, statik bir sayaç artırılarak o ekran için Display#mDisplayId veya DisplayInfo#displayId oluşturuldu. Sistem aynı ekranı ekleyip çıkardığında farklı bir kimlik ortaya çıktı.

Bir cihazın önyüklemeden itibaren birden fazla ekranı varsa, zamanlamaya bağlı olarak ekranlara farklı tanımlayıcılar atanabilir. Android 9 (ve önceki sürümleri) DisplayInfo#uniqueId öğesini içerse de, fiziksel ekranlar yerleşik ve harici ekranı temsil etmek üzere local:0 veya local:1 olarak tanımlandığından ekranlar arasında ayrım yapmak için yeterli bilgi içermiyordu.

Android 10, kararlı bir tanımlayıcı eklemek ve yerel, ağ ve sanal ekranlar arasında ayrım yapmak için DisplayInfo#uniqueId değerini değiştirir.

Ekran tipi Biçim
Yerel
local:<stable-id>
network:<mac-address>
Sanal
virtual:<package-name-and-name>

uniqueId güncellemelerine ek olarak DisplayInfo.address , yeniden başlatmalarda kararlı olan bir ekran tanımlayıcısı olan DisplayAddress içerir. Android 10'da DisplayAddress , fiziksel ve ağ ekranlarını destekler. DisplayAddress.Physical sabit bir ekran kimliği içerir ( uniqueId ile aynı) ve DisplayAddress#fromPhysicalDisplayId() ile oluşturulabilir.

Android 10 ayrıca bağlantı noktası bilgilerini almak için kullanışlı bir yöntem de sağlar ( Physical#getPort() ). Bu yöntem, ekranları statik olarak tanımlamak için çerçevede kullanılabilir. Örneğin, DisplayWindowSettings kullanılır). DisplayAddress.Network MAC adresini içerir ve DisplayAddress#fromMacAddress() ile oluşturulabilir.

Bu eklemeler, cihaz üreticilerinin statik çoklu ekran kurulumlarındaki ekranları tanımlamasına ve fiziksel ekranlar için bağlantı noktaları gibi statik ekran tanımlayıcılarını kullanarak farklı sistem ayarlarını ve özelliklerini yapılandırmasına olanak tanır. Bu yöntemler gizlidir ve yalnızca system_server içinde kullanılmak üzere tasarlanmıştır.

Bir HWC ekran kimliği verildiğinde (opak olabilir ve her zaman kararlı olmayabilir), bu yöntem, ekranın EDID blobunun yanı sıra, ekran çıkışı için fiziksel bir konektörü tanımlayan (platforma özel) 8 bitlik bağlantı noktası numarasını döndürür. SurfaceFlinger, çerçeveye sunulan kararlı 64 bit ekran kimliklerini oluşturmak için EDID'den üretici veya model bilgilerini çıkarır. Bu yöntem desteklenmiyorsa veya hata veriyorsa SurfaceFlinger, yukarıda açıklandığı gibi DisplayInfo#address boş olduğu ve DisplayInfo#uniqueId sabit kodlandığı eski MD moduna geri döner.

Bu özelliğin desteklendiğini doğrulamak için şunu çalıştırın:

$ dumpsys SurfaceFlinger --display-id
# Example output.
Display 21691504607621632 (HWC display 0): port=0 pnpId=SHP displayName="LQ123P1JX32"
Display 9834494747159041 (HWC display 2): port=1 pnpId=HWP displayName="HP Z24i"
Display 1886279400700944 (HWC display 1): port=2 pnpId=AUS displayName="ASUS MB16AP"

İkiden fazla ekran kullanma

Android 9'da (ve daha eski sürümlerde), SurfaceFlinger ve DisplayManagerService , 0 ve 1 sabit kodlu kimliklere sahip en fazla iki fiziksel ekranın varlığını varsaydı.

Android 10'dan başlayarak SurfaceFlinger, sabit ekran kimlikleri oluşturmak için bir Donanım Oluşturucu (HWC) API'sinden yararlanabilir ve bu da isteğe bağlı sayıda fiziksel ekranı yönetmesine olanak tanır. Daha fazla bilgi edinmek için bkz. Statik ekran tanımlayıcıları .

Çerçeve, SurfaceControl#getPhysicalDisplayIds veya bir DisplayEventReceiver hotplug olayından 64 bit ekran kimliğini aldıktan sonra SurfaceControl#getPhysicalDisplayToken aracılığıyla fiziksel bir ekran için IBinder belirtecini arayabilir.

Android 10'da (ve daha eski sürümlerde), birincil dahili ekran TYPE_INTERNAL ve bağlantı türünden bağımsız olarak tüm ikincil ekranlar TYPE_EXTERNAL olarak işaretlenir. Bu nedenle, ek dahili ekranlar harici olarak değerlendirilir. Geçici bir çözüm olarak, HWC biliniyorsa ve bağlantı noktası tahsis mantığı öngörülebilirse, cihaza özgü kod DisplayAddress.Physical#getPort hakkında varsayımlarda bulunabilir.

Bu sınırlama Android 11'de (ve üzeri) kaldırılmıştır.

  • Android 11'de önyükleme sırasında bildirilen ilk ekran birincil ekrandır. Bağlantı türü (dahili veya harici) önemli değildir. Ancak birincil ekranın bağlantısının kesilemeyeceği doğrudur ve bunun pratikte dahili bir ekran olması gerektiği sonucu çıkar. Bazı katlanabilir telefonların birden fazla dahili ekrana sahip olduğunu unutmayın.
  • İkincil ekranlar, bağlantı türlerine bağlı olarak Display.TYPE_INTERNAL veya Display.TYPE_EXTERNAL (önceden sırasıyla Display.TYPE_BUILT_IN ve Display.TYPE_HDMI olarak biliniyordu) olarak doğru şekilde kategorize edilir.

Uygulama

Android 9 ve önceki sürümlerde ekranlar 32 bit kimliklerle tanımlanır; burada 0 dahili ekran, 1 harici ekran, [2, INT32_MAX] HWC sanal ekranlardır ve -1 geçersiz bir ekranı veya HWC olmayan bir ekranı temsil eder. sanal ekran.

Android 10'dan itibaren ekranlara sabit ve kalıcı kimlikler veriliyor; bu, SurfaceFlinger ve DisplayManagerService ikiden fazla ekranı izlemesine ve daha önce görülen ekranları tanımasına olanak tanıyor. HWC, IComposerClient.getDisplayIdentificationData destekliyorsa ve ekran tanımlama verileri sağlıyorsa SurfaceFlinger, EDID yapısını ayrıştırır ve fiziksel ve HWC sanal ekranlar için kararlı 64 bit ekran kimlikleri ayırır. Kimlikler, boş değerin geçersiz bir ekranı veya HWC olmayan sanal ekranı temsil ettiği bir seçenek türü kullanılarak ifade edilir. HWC desteği olmadan SurfaceFlinger, en fazla iki fiziksel ekranla eski davranışa geri döner.

Ekran başına odaklama

Aynı anda tek tek ekranları hedefleyen birden fazla giriş kaynağını desteklemek için Android 10, ekran başına en fazla bir tane olmak üzere birden fazla odaklanmış pencereyi destekleyecek şekilde yapılandırılabilir. Bu, yalnızca birden fazla kullanıcının aynı anda aynı cihazla etkileşimde bulunduğu ve Android Automotive gibi farklı giriş yöntemleri veya cihazları kullandığı özel cihaz türleri için tasarlanmıştır.

Bu özelliğin, çoklu ekranlı cihazlar veya masaüstü benzeri deneyimler için kullanılanlar da dahil olmak üzere normal cihazlar için etkinleştirilmemesi önemle tavsiye edilir. Bunun temel nedeni, kullanıcıların hangi pencerenin giriş odağına sahip olduğunu merak etmelerine neden olabilecek bir güvenlik sorunudur.

Kullanıcının bir metin giriş alanına güvenli bilgiler girdiğini, örneğin bir bankacılık uygulamasında oturum açtığını veya hassas bilgiler içeren bir metin girdiğini hayal edin. Kötü amaçlı bir uygulama, bir etkinliğin yürütüleceği, ayrıca metin giriş alanına sahip, sanal bir ekran dışı görüntü oluşturabilir. Yasal ve kötü amaçlı faaliyetlerin odağı vardır ve her ikisi de etkin bir giriş göstergesi (yanıp sönen imleç) görüntüler.

Ancak, klavyeden (donanım veya yazılım) gelen girdi yalnızca en üstteki etkinliğe (en son başlatılan uygulamaya) girildiğinden, kötü amaçlı bir uygulama, gizli bir sanal ekran oluşturarak, yazılım klavyesi kullanılırken bile kullanıcı girdisini ele geçirebilir. birincil cihaz ekranında.

Ekran başına odağı ayarlamak için com.android.internal.R.bool.config_perDisplayFocusEnabled kullanın.

Uyumluluk

Sorun: Android 9 ve önceki sürümlerde, sistemdeki en fazla bir pencere aynı anda odaklanıyor.

Çözüm: Aynı süreçten iki pencerenin odaklanacağı nadir durumlarda, sistem yalnızca Z sırasında daha yüksek olan pencereye odaklanma sağlar. Bu kısıtlama, Android 10'u hedefleyen uygulamalar için kaldırılmıştır; bu noktada, birden fazla pencerenin aynı anda odaklanmasını destekleyebilmeleri beklenir.

Uygulama

WindowManagerService#mPerDisplayFocusEnabled bu özelliğin kullanılabilirliğini kontrol eder. ActivityManager artık bir değişkende global izleme yerine ActivityDisplay#getFocusedStack() kullanılıyor. ActivityDisplay#getFocusedStack() değeri önbelleğe almak yerine Z sırasına göre odağı belirler. Bu, yalnızca tek bir kaynağın, WindowManager'ın, etkinliklerin Z sırasını izlemesine ihtiyaç duyması içindir.

ActivityStackSupervisor#getTopDisplayFocusedStack() sistemdeki en üstteki odaklanmış yığının tanımlanmasının gerekli olduğu durumlar için benzer bir yaklaşım benimser. Yığınlar yukarıdan aşağıya doğru hareket ettirilerek ilk uygun yığın aranır.

InputDispatcher artık birden fazla odaklanmış pencereye sahip olabilir (ekran başına bir tane). Bir giriş olayı ekrana özelse ilgili ekrandaki odaklanılan pencereye gönderilir. Aksi takdirde, kullanıcının en son etkileşimde bulunduğu ekran olan odaklanılmış ekrandaki odaklanılan pencereye gönderilir.

Bkz. InputDispatcher::mFocusedWindowHandlesByDisplay ve InputDispatcher::setFocusedDisplay() . Odaklanmış uygulamalar ayrıca NativeInputManager::setFocusedApplication() aracılığıyla inputManagerService'de ayrı olarak güncellenir.

WindowManager odaklanılan pencereler ayrıca ayrı olarak izlenir. DisplayContent#mCurrentFocus ve DisplayContent#mFocusedApp ve ilgili kullanımlara bakın. İlgili odak izleme ve güncelleme yöntemleri WindowManagerService DisplayContent taşındı.