Ekran desteği

Görüntülü reklamlara özgü bu alanlarda yapılan güncellemeler aşağıda verilmiştir:

Etkinlikleri ve ekranları yeniden boyutlandırma

Bir uygulamanın çok pencereli modu veya yeniden boyutlandırmayı destekleyemediğini belirtmek için etkinliklerde resizeableActivity=false özelliği kullanılır. Etkinlikler yeniden boyutlandırıldığında uygulamalarla ilgili sık karşılaşılan sorunlar şunlardır:

  • Bir etkinlik, uygulamadan farklı bir yapılandırmaya veya görsel olmayan başka bir bileşene sahip olabilir. Yaygın olarak yapılan bir hata, görüntülü reklam metriklerinin uygulama bağlamından okunmasıdır. Döndürülen değerler, bir etkinliğin gösterildiği görünür alan metriklerine göre ayarlanmaz.
  • Bir etkinlik, yeniden boyutlandırma ve kilitlenme işlemlerini yerine getiremeyebilir, bozuk bir kullanıcı arayüzü görüntüleyebilir veya örnek durumu kaydedilmeden yeniden başlatma nedeniyle durumu kaybedebilir.
  • Bir uygulama, mutlak giriş koordinatlarını (pencere konumuna göre olanlar yerine) kullanmaya çalışabilir. Bu, çoklu pencerede girişi bozabilir.

Android 7 (ve sonraki sürümler) sürümünde, bir uygulama her zaman tam ekran modunda çalışacak şekilde ayarlanabilir. Bu durumda platform, yeniden boyutlandırılamayan etkinliklerin bölünmüş ekrana gitmesini önler. Kullanıcı bölünmüş ekran modundayken başlatıcıdan yeniden boyutlandırılamayan bir etkinlik ç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 manifestte açıkça false değerine 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 işleme aynı yapılandırma uygulanır.
  • Uygulanan yapılandırma, uygulamayla uyumlu ekranlar için CDD şartlarını karşılar.

Android 10'da platform, yeniden boyutlandırılamayan etkinliklerin bölünmüş ekran moduna girmesini engellemeye devam etmektedir, ancak etkinlik sabit bir yön veya en boy oranı beyan etmişse bunlar geçici olarak ölçeklendirilebilir. Aksi takdirde etkinlik, Android 9 ve önceki sürümlerde olduğu gibi ekranın tamamını kaplayacak şekilde yeniden boyutlandırılır.

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

android:resizeableActivity özelliğinin kullanılmasıyla çok pencereli ile uyumlu olmadığı beyan edilen bir etkinlik, aşağıda açıklanan koşullardan birini karşıladığında ve uygulanan ekran yapılandırması 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.

  • Yön, android:screenOrientation uygulayarak sabitlenmiş olmalıdır.
  • Uygulama, API düzeyini hedefleyerek varsayılan maksimum veya minimum en boy oranına sahip veya en boy oranını açık bir şekilde beyan ediyor

Bu resimde, belirtilen en boy oranına sahip, boyutlandırılamayan bir etkinlik gösterilmektedir. Cihaz katlanırken pencere alana sığacak şekilde küçültülür. Aynı zamanda uygun sinemaskop kullanılarak en boy oranı korunur. Ayrıca, etkinliğin görüntüleme alanı her değiştirildiğinde kullanıcıya etkinliği yeniden başlatma seçeneği sunulur.

Cihaz açıldığında etkinliğin yapılandırması, boyutu ve en boy oranı değişmez ancak etkinliği yeniden başlatma seçeneği gösterilir.

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

Uygulama

Sabit yön veya en boy oranına sahip, boyutu değiştirilemeyen etkinliklere kodda boyut uyumluluk modu (SCM) denir. Koşul, ActivityRecord#shouldUseSizeCompatMode() adresinde tanımlanmıştır. Bir SCM etkinliği başlatıldığında ekranla ilgili yapılandırma (ör. boyut veya yoğunluk), istenen geçersiz kılma yapılandırmasında sabitlenir. Böylece etkinlik artık mevcut ekran yapılandırmasına bağlı olmaz.

SCM etkinliği ekranın tamamını 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 (ör. ekran yeniden boyutlandırılır veya etkinlik başka bir ekrana taşınır) ActivityRecord#inSizeCompatMode() doğru olur ve SizeCompatModeActivityController (Sistem kullanıcı arayüzünde), işlemi yeniden başlat düğmesini göstermek için geri çağırma alır.

Ekran boyutları ve en boy oranları

Android 10, yüksek uzun ve ince ekran oranlarından 1:1 oranlarına kadar yeni en boy oranları için destek sağlar. Uygulamalar, kontrol edebildikleri ekranın ApplicationInfo#maxAspectRatio ve ApplicationInfo#minAspectRatio değerini 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 boyut ve çözünürlüklere sahip ikincil ekranlar bulunabilir (en az 2,5 inç genişlik veya yükseklik, smallestScreenWidth için en az 320 DP) ancak bu ekranlara yalnızca bu küçük ekranları desteklemeyi etkinleştiren etkinlikler yerleştirilebilir.

Uygulamalar, hedef ekran boyutundan daha küçük veya eşit bir minimum desteklenen boyutu bildirerek bu özelliği etkinleştirebilir. Bunu yapmak için AndroidManifest dosyasında android:minHeight ve android:minWidth etkinlik düzeni özelliklerini kullanın.

Görüntülü reklam politikaları

Android 10, belirli görüntülü reklam politikalarını PhoneWindowManager'daki varsayılan WindowManagerPolicy uygulamasından ayırıp görüntü başına sınıflara taşır. Örneğin:

  • Ekran durumu ve rotasyonu
  • Bazı tuşlar ve hareket etkinliği izleme
  • Sistem kullanıcı arayüzü ve dekorasyon pencereleri

Android 9 (ve önceki sürümler) sürümlerinde PhoneWindowManager sınıfı; görüntüleme politikaları, durum ve ayarlar, döndürme, dekorasyon penceresi çerçevesi izleme ve daha fazlasını yönetiyordu. Android 10, bu özelliklerin çoğunu DisplayPolicy sınıfına taşıdı. Dönme izleme özelliği ise DisplayRotation sınıfına taşındı.

Görüntüleme aralığı ayarları

Android 10'da, ekran başına yapılandırılabilir pencere ayarı aşağıdakileri içerecek şekilde genişletildi:

  • Varsayılan görüntüleme pencereleme modu
  • Fazla tarama değerleri
  • Kullanıcı rotasyonu ve rotasyon modu
  • Zorunlu boyut, yoğunluk ve ölçeklendirme modu
  • İçerik kaldırma modu (ekran kaldırıldığında)
  • Sistem süslemeleri ve IME desteği

DisplayWindowSettings sınıfı, bu seçeneklerle ilgili ayarları içerir. Ayarlar her değiştiğinde display_settings.xml bölümündeki /data bölümündeki diske kaydedilir. Ayrıntılar için DisplayWindowSettings.AtomicFileStorage ve DisplayWindowSettings#writeSettings() sayfalarına göz atın. Cihaz üreticileri, cihaz yapılandırmaları için display_settings.xml içinde varsayılan değerler sağlayabilir. Ancak dosya /data içinde depolandığından, silme işlemiyle silinirse dosyanın geri yüklenmesi için ek mantık gerekebilir.

Android 10, ayarları kalıcı hale getirirken varsayılan olarak bir ekranın tanımlayıcı olarak DisplayInfo#uniqueId değerini kullanır. uniqueId tüm ekranlar için doldurulmalıdır. Ayrıca fiziksel ve ağ ekranları için kararlıdır. Tanımlayıcı olarak fiziksel ekranın bağlantı noktasını da kullanabilirsiniz. Bu bağlantı noktası DisplayWindowSettings#mIdentifier içinde ayarlanabilir. Her yazma işleminde tüm ayarlar yazılır. Böylece, depolama alanındaki bir görüntüleme girişi için kullanılan anahtarı güncellemek güvenli olur. Ayrıntılı bilgi için Statik görüntüleme tanımlayıcıları bölümüne bakın.

Ayarlar, geçmiş nedenlerle /data dizininde devam ettirilir. Başlangıçta, ekran döndürme gibi kullanıcı tarafından ayarlanan ayarları korumak için kullanılıyordu.

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

Android 9 (ve önceki sürümler), çerçevedeki ekranlar için sabit tanımlayıcılar sağlamamıştır. Sisteme bir ekran eklendiğinde, statik bir sayaç artırılarak söz konusu ekran için Display#mDisplayId veya DisplayInfo#displayId oluşturuldu. Sistem aynı ekranı ekleyip kaldırdığında farklı bir kimlik ortaya çıkar.

Bir cihazda, önyükleme sırasında birden fazla ekran kullanılabiliyorsa ekranlara zamanlamaya bağlı olarak farklı tanımlayıcılar atanabilir. Android 9 (ve önceki sürümler) DisplayInfo#uniqueId içeriyordu, ancak fiziksel ekranlar yerleşik ve harici ekranı temsil edecek şekilde local:0 veya local:1 olarak tanımlandığından ekranları birbirinden ayırt etmek için yeterli bilgi içermiyordu.

Android 10, kararlı bir tanımlayıcı eklemek ve yerel, ağ ve sanal ekranları birbirinden ayırt etmek için DisplayInfo#uniqueId değiştirir.

Görüntüleme türü Biçim
Yerel
local:<stable-id>
network:<mac-address>
Sanal
virtual:<package-name-and-name>

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

Android 10, bağlantı noktası bilgilerini (Physical#getPort()) almak için de kullanışlı bir yöntem sağlar. Bu yöntem, çerçevede ekranları statik olarak tanımlamak için kullanılabilir. Örneğin, DisplayWindowSettings bölgesinde kullanılmıştı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ın 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.

Bu yöntem, bir HWC ekran kimliği (saydam olabilir ve her zaman kararlı olmayabilir) verildiğinde ekran çıkışı için fiziksel bir konnektörü tanımlayan 8 bitlik bağlantı noktası numarasını (platforma özel) ve ekranın EDID blob'unu döndürür. SurfaceFlinger, çerçeveye sunulan kararlı 64 bit ekran kimliklerini oluşturmak için EDID'den üretici veya model bilgilerini ayıklar. Bu yöntem desteklenmezse veya hata oluşursa SurfaceFlinger eski MD moduna döner. Bu modda DisplayInfo#address, yukarıda açıklandığı gibi null ve DisplayInfo#uniqueId sabit kodlu olur.

Bu özelliğin desteklendiğini doğrulamak için şu komutu ç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 (ve önceki sürümler)'de SurfaceFlinger ve DisplayManagerService, sabit kodlu 0 ve 1 kimliklerine sahip en fazla iki fiziksel ekranın varlığını varsayıyordu.

Android 10'dan itibaren SurfaceFlinger, sabit ekran kimlikleri oluşturmak için donanım derleyici (HWC) API'sinden yararlanarak herhangi bir sayıda fiziksel ekranı yönetebilmektedir. Daha fazla bilgi edinmek için Statik görüntüleme tanımlayıcıları bölümüne bakın.

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

Android 10 (ve önceki sürümler) sürümünde birincil dahili ekran TYPE_INTERNAL, tüm ikincil ekranlar ise bağlantı türünden bağımsız olarak TYPE_EXTERNAL olarak işaretlenir. Bu nedenle, ek dahili ekranlar harici ekran olarak değerlendirilir. Cihaza özgü kod, geçici çözüm olarak HWC biliniyorsa ve bağlantı noktası atama mantığı tahmin edilebilirse DisplayAddress.Physical#getPort hakkında varsayımlarda bulunabilir.

Bu sınırlama Android 11 (ve sonraki sürümler) için 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) alakasız. Bununla birlikte, birincil ekranın bağlantısının kesilemeyeceğini ve pratikte bunun dahili bir ekran olması gerektiğini belirtmektedir. Bazı katlanabilir telefonlarda birden fazla dahili ekran bulunduğunu unutmayın.
  • İkincil ekranlar, bağlantı türlerine bağlı olarak Display.TYPE_INTERNAL veya Display.TYPE_EXTERNAL (eski adlarıyla sırasıyla Display.TYPE_BUILT_IN ve Display.TYPE_HDMI) olarak doğru şekilde sınıflandırılır.

Uygulama

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

Android 10'dan itibaren ekranlara sabit ve kalıcı kimlikler verilir. Bu sayede SurfaceFlinger ve DisplayManagerService ikiden fazla ekranı izleyebilir ve önceden görülen ekranları tanıyabilir. 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, bir seçenek türü kullanılarak ifade edilir. Bu türde, null değeri geçersiz bir ekranı veya HWC olmayan sanal ekranı temsil eder. HWC desteği olmadan SurfaceFlinger, en fazla iki fiziksel ekranla eski davranışa geri döner.

Ekran başına odaklanma

Android 10, aynı anda tek tek ekranları hedefleyen çeşitli giriş kaynaklarını desteklemek için birden fazla odaklanmış pencereyi (en fazla ekran başına bir tane) destekleyecek şekilde yapılandırılabilir. Bu özellik yalnızca birden fazla kullanıcının aynı anda aynı cihazla etkileşime geçtiği ve Android Automotive gibi farklı giriş yöntemlerini 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ılan cihazlar da dahil olmak üzere normal cihazlarda etkinleştirilmemesi önemle tavsiye edilir. Bunun nedeni, kullanıcıların hangi pencerede giriş odağının olduğunu merak etmesine neden olabilecek güvenlik endişesidir.

Bir metin giriş alanına güvenli bilgi giren, bir bankacılık uygulamasına giriş yapan veya hassas bilgiler içeren bir metin giren bir kullanıcıyı düşünün. Kötü amaçlı bir uygulama, bir etkinliği yürütmek için sanal bir ekran dışı ekran oluşturabilir ve bu ekranda metin giriş alanı da olabilir. Meşru ve kötü amaçlı etkinliklere odaklanılır ve her ikisi de etkin bir giriş göstergesi (yanıp sönen imleç) gösterir.

Bununla birlikte, gizli bir sanal ekran oluşturarak klavyeden (donanım veya yazılım) gelen giriş (donanım veya yazılım) girildiğinden, birincil cihazın ekranında yazılım klavyesi kullanılsa bile kötü amaçlı bir uygulama kullanıcının girişini alabilir.

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

Uyumluluk

Sorun: Android 9 ve önceki sürümlerde, sistemde aynı anda en fazla bir pencere odakta olur.

Çözüm: Aynı işlemden iki pencerenin odaklanacağı nadir durumlarda sistem yalnızca Z sırasına göre daha yüksek olan pencereye odaklanır. Bu kısıtlama, Android 10'u hedefleyen uygulamalar için kaldırılır. Bu durumda, aynı anda birden fazla pencereye odaklanmanın desteklenmesi beklenir.

Uygulama

WindowManagerService#mPerDisplayFocusEnabled, bu özelliğin kullanılabilirliğini kontrol eder. ActivityManager'te, değişkende artık global izleme yerine ActivityDisplay#getFocusedStack() kullanılıyor. ActivityDisplay#getFocusedStack() değeri önbelleğe almak yerine odak noktasını Z sırasına göre belirler. Bunun nedeni, etkinliklerin Z sırasını yalnızca bir kaynağın (WindowManager) izlemesi gerekmesidir.

ActivityStackSupervisor#getTopDisplayFocusedStack(), sistemdeki en üst odaklı yığının tanımlanmasının gerektiği durumlar için benzer bir yaklaşım uygular. Yığınlar, yukarıdan aşağıya doğru taranarak ilk uygun yığın aranır.

InputDispatcher artık birden fazla odaklı pencereye (ekran başına bir tane) sahip olabilir. Giriş etkinliği ekrana özgüyse ilgili ekrandaki odaklanmış 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() belgelerini inceleyin. Odaklanılan uygulamalar, Giriş Yöneticisi Hizmeti'nde NativeInputManager::setFocusedApplication() üzerinden ayrı olarak güncellenir.

WindowManager'te odaklanan pencereler de ayrı olarak izlenir. DisplayContent#mCurrentFocus ve DisplayContent#mFocusedApp'e ve ilgili kullanım alanlarına bakın. İlgili odak izleme ve güncelleme yöntemleri WindowManagerService bölümünden DisplayContent klasörüne taşındı.