Ekran Desteği

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

Etkinlikleri ve ekranları yeniden boyutlandırma

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

  • Bir etkinlik, uygulamadan veya görsel olmayan başka bir bileşenden farklı bir yapılandırmaya sahip olabilir. Yaygın bir hata, uygulama bağlamından görüntüleme metriklerini okumaktır. Döndürülen değerler, bir etkinliğin görüntülendiği görünür alan metriklerine ayarlanmaz.
  • Bir etkinlik, yeniden boyutlandırmayı ve kilitlenmeyi işleyemez, bozuk bir kullanıcı arayüzü görüntüleyebilir veya örnek durumunu kaydetmeden yeniden başlatma nedeniyle durumunu kaybedebilir.
  • Bir uygulama, çoklu pencerede girişi bozabilecek mutlak giriş koordinatlarını (pencere konumuna göreli olanlar yerine) kullanmayı deneyebilir.

Android 7'de (ve sonraki sürümlerde), 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 girmesini engeller. Kullanıcı, halihazırda bölünmüş ekran modundayken başlatıcıdan yeniden boyutlandırılamayan bir etkinlik başlatmaya çalışırsa, platform bölünmüş ekran modundan çıkar ve yeniden boyutlandırılamayan etkinliği tam ekran modunda başlatır.

Bildirimde bu özelliği açıkça false olarak ayarlayan uygulamalar, uyumluluk modu uygulanmadıkça çoklu pencere modunda başlatılmamalıdır:

  • Tüm aktiviteleri ve aktivite 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 yine de engeller, ancak etkinlik sabit bir yön veya en boy oranı bildirmişse, bunlar geçici olarak ölçeklenebilir. Değilse, etkinlik, Android 9 ve önceki sürümlerde olduğu gibi tüm ekranı dolduracak şekilde yeniden boyutlandırılır.

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

android:resizeableActivity özniteliği kullanılarak bir etkinliğin çoklu pencere ile uyumsuz olduğu bildirildiğinde 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 için 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, beyan edilmiş bir en boy oranına sahip, yeniden boyutlandırılamayan bir etkinliği gösterir. Aygıtı katlarken, uygun mektup kutusu kullanılarak en-boy oranı korunurken pencere alana sığacak şekilde küçültülür. Ayrıca, aktivite için görüntüleme alanı her değiştirildiğinde kullanıcıya yeniden başlatma seçeneği sunulur.

Aygıtı 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ımlanır. Bir SCM etkinliği başlatıldığında, ekranla ilgili yapılandırma (boyut veya yoğunluk gibi), istenen geçersiz kılma yapılandırmasında sabitlenir, dolayısıyla etkinlik artık mevcut ekran yapılandırmasına bağlı değildir.

SCM etkinliği tüm ekranı dolduramıyorsa, üste 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() true olur ve SizeCompatModeActivityController (Sistem Kullanıcı Arabiriminde) işlemi göstermek için geri aramayı alır yeniden başlat düğmesi.

Ekran boyutları ve en boy oranları

Android 10, uzun ve ince ekranların yüksek oranlarından 1:1 oranlarına kadar yeni en boy oranları için destek sağlar. Uygulamalar, ekranın ele alabilecekleri ApplicationInfo#maxAspectRatio ve ApplicationInfo#minAspectRatio #minAspectRatio değerlerini tanımlayabilir.

Android 10'daki uygulama oranları

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

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

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

Görüntüleme politikaları

Android 10, PhoneWindowManager varsayılan WindowManagerPolicy uygulamasından belirli görüntüleme ilkelerini ayırır ve aşağıdakiler gibi görüntüleme başına sınıflara taşır:

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

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

Ekran penceresi ayarları

Android 10'da, yapılandırılabilir ekran başına pencere 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çekleme modu
  • İçerik kaldırma modu (ekran kaldırıldığında)
  • Sistem süslemeleri ve IME desteği

DisplayWindowSettings sınıfı, bu seçenekler için ayarları içerir. Her ayar değiştirildiğinde, display_settings.xml içindeki /data bölümünde diskte kalmaya devam ederler. Ayrıntılar için bkz. DisplayWindowSettings.AtomicFileStorage ve DisplayWindowSettings#writeSettings() . Cihaz üreticileri, cihaz yapılandırmaları için display_settings.xml varsayılan değerler sağlayabilir. Ancak, dosya /data içinde depolandığından, bir silme ile silinirse dosyayı geri yüklemek için ek mantık gerekebilir.

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

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

Statik görüntü tanımlayıcıları

Android 9 (ve önceki sürümler), çerçevedeki görüntüler için kararlı tanımlayıcılar sağlamadı. Sisteme bir ekran eklendiğinde, statik bir sayaç artırılarak o ekran için Display#mDisplayId veya DisplayInfo#displayId displayId oluşturuldu. Sistem aynı ekranı ekleyip kaldırdıysa, farklı bir kimlik ortaya çıktı.

Bir aygıtı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ümler) DisplayInfo#uniqueId içeriyor olsa da, fiziksel görüntüler yerleşik ve harici ekranı temsil etmek için local:0 veya local:1 olarak tanımlandığından, ekranlar arasında ayrım yapmak için yeterli bilgi içermiyordu.

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

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

DisplayAddress DisplayInfo.address uniqueId Android 10'da DisplayAddress , fiziksel ve ağ görüntülerini 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 uygun bir yöntem sağlar ( Physical#getPort() ). Bu yöntem, çerçeve içinde ekranları statik olarak tanımlamak için kullanılabilir. Örneğin, DisplayWindowSettings içinde 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ı 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ılması amaçlanmıştır.

Bir HWC görüntü kimliği (opak olabilir ve her zaman kararlı olmayabilir) verildiğinde, bu yöntem, ekranın EDID bloğunun yanı sıra görüntü çıkışı için fiziksel bir bağlayıcıyı tanımlayan (platforma özgü) 8 bitlik bağlantı noktası numarasını döndürür. SurfaceFlinger, çerçeveye maruz kalan 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# DisplayInfo#address boş 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 düşük sürümlerde), SurfaceFlinger ve DisplayManagerService , sabit kodlanmış kimlikleri 0 ve 1 olan en fazla iki fiziksel ekranın varlığını varsayıyordu.

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

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

Android 10'da (ve daha düşük sürümlerde), birincil dahili ekran TYPE_INTERNAL ve tüm ikincil ekranlar bağlantı türünden bağımsız olarak TYPE_EXTERNAL olarak işaretlenir. Bu nedenle, ek dahili ekranlar harici olarak kabul edilir. Geçici bir çözüm olarak, HWC biliniyorsa ve bağlantı noktası ayırma mantığı tahmin edilebilirse, cihaza özel kod DisplayAddress.Physical#getPort hakkında varsayımlarda bulunabilir.

Bu sınırlama, Android 11'de (ve sonraki sürümlerde) 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) önemsizdir. Bununla birlikte, birincil ekranın bağlantısının kesilemeyeceği ve pratikte dahili bir ekran olması gerektiği doğru kalır. Bazı katlanabilir telefonların birden fazla dahili ekranı olduğunu unutmayın.
  • İkincil ekranlar, bağlantı türlerine bağlı olarak doğru şekilde Display.TYPE_INTERNAL veya Display.TYPE_EXTERNAL (önceden Display.TYPE_BUILT_IN ve Display.TYPE_HDMI olarak bilinirdi) olarak sınıflandırılır.

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 başlayarak, ekranlara, SurfaceFlinger ve DisplayManagerService ikiden fazla ekranı izlemesine ve daha önce görülen ekranları tanımasına olanak tanıyan sabit ve kalıcı kimlikler verilir. 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 tahsis eder. 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 odak

Aynı anda ayrı ekranları hedefleyen birkaç giriş kaynağını desteklemek için Android 10, ekran başına en fazla bir tane olmak üzere birden çok odaklanmış pencereyi destekleyecek şekilde yapılandırılabilir. Bu, yalnızca birden fazla kullanıcının aynı cihazla aynı anda 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, çok ekranlı cihazlar veya masaüstü benzeri deneyimler için kullanılanlar da dahil olmak üzere normal cihazlarda etkinleştirilmemesi şiddetle önerilir. Bu, öncelikle, kullanıcıların hangi pencerenin girdi odağına sahip olduğunu merak etmelerine neden olabilecek bir güvenlik endişesinden kaynaklanmaktadır.

Bir metin giriş alanına güvenli bilgiler giren, belki bir bankacılık uygulamasında oturum açan veya hassas bilgiler içeren metin giren bir kullanıcıyı hayal edin. Kötü amaçlı bir uygulama, bir metin giriş alanı da dahil olmak üzere, bir etkinliği yürütmek için sanal bir ekran dışı görüntü oluşturabilir. Meşru ve kötü niyetli etkinliklere odaklanılır ve her ikisi de etkin bir giriş göstergesi (yanıp sönen imleç) görüntüler.

Ancak, bir klavyeden (donanım veya yazılım) girdi yalnızca en üstteki etkinliğe (en son başlatılan uygulama) girildiğinden, gizli bir sanal ekran oluşturarak kötü amaçlı bir uygulama, bir yazılım klavyesi kullanırken bile kullanıcı girdisini alabilir. 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ğı ender bir durumda, 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, aynı anda odaklanan birden çok pencereyi desteklemeleri 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 bir kaynak olan WindowManager'ın etkinliklerin Z sırasını izlemesi gerektiği içindir.

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

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

InputDispatcher::mFocusedWindowHandlesByDisplay ve InputDispatcher::setFocusedDisplay() bakın. Odaklanmış uygulamalar ayrıca InputManagerService içinde NativeInputManager::setFocusedApplication() aracılığıyla ayrı olarak güncellenir.

WindowManager odaklanmış 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ı.