Görüntülü reklamlara özgü bu alanlarda yapılan güncellemeler aşağıda verilmiştir:
- Etkinlikleri ve ekranları yeniden boyutlandırma
- Görüntü boyutları ve en boy oranları
- Görüntülü reklam politikaları
- Görüntüleme aralığı ayarları
- Statik görüntülü reklam tanımlayıcıları
- İkiden fazla ekran kullanma
- Ekran başına odaklanma
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 etkinliğin yapılandırması, uygulamadan veya görsel olmayan başka bir bileşenden farklı olabilir. Sık karşılaşılan bir hata, uygulama bağlamından görüntüleme metriklerini okumaktı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ırmayı işleyemeyebilir ve kilitlenebilir, bozuk bir kullanıcı arayüzü gösterebilir veya örnek durumunu kaydetmeden yeniden başlatıldığı için durumunu kaybedebilir.
- Bir uygulama, mutlak giriş koordinatlarını (pencere konumuna göre olanlar yerine) kullanmaya çalışabilir. Bu durum, çoklu pencerede girişin bozulmasına neden olabilir.
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 boyutlandırılamayan bir etkinliği çağırmaya çalışırsa platform bölünmüş ekran modundan çıkar ve boyutlandırılamayan etkinliği tam ekran modunda başlatır.
Uyumluluk modu uygulanmadığı sürece, manifest dosyasında bu özelliği açıkça false
olarak ayarlayan uygulamalar ç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ı dolduracak şekilde yeniden boyutlandırılır.
Varsayılan uygulamada aşağıdaki politika geçerlidir:
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.
android:screenOrientation
uygulamasıyla sabit yöndür- Uygulama, API düzeyini hedefleyerek varsayılan maksimum veya minimum en-boy oranına sahiptir ya da en-boy oranını açıkça beyan eder
Bu resimde, belirtilen en boy oranına sahip, boyutlandırılamayan bir etkinlik gösterilmektedir. Cihaz katlandığında pencere, uygun sinemaskop kullanılarak en boy oranı korunurken alana sığacak şekilde küçültülür. 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çtığınızda 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ı tamamen 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 üstte hizalanır ve yatay olarak ortalanacaktır. Etkinlik sınırları AppWindowToken#calculateCompatBoundsTransformation()
tarafından hesaplanmaktadı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.
Ş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
- Aşırı tarama değerleri
- Kullanıcı rotasyonu ve rotasyon modu
- Zorunlu boyut, yoğunluk ve ölçekleme modu
- İçerik kaldırma modu (görüntü 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ılı bilgi için DisplayWindowSettings.AtomicFileStorage
ve DisplayWindowSettings#writeSettings()
başlıklı makaleleri inceleyin. 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 silinmesi durumunda dosyayı geri yüklemek 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 gösterimler 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ılar için Statik görüntüleme tanımlayıcıları başlıklı makaleyi inceleyin.
Ayarlar, geçmiş nedenlerden dolayı /data
dizininde kalıcıdır. 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 sayıcı artırılarak söz konusu ekran için Display#mDisplayId
veya DisplayInfo#displayId
oluşturuldu. Sistem aynı ekranı ekleyip kaldırdıysa farklı bir kimlik oluşturulur.
Bir cihazın açılışta kullanılabilecek birden fazla ekranı varsa zamanlamaya bağlı olarak ekranlara farklı tanımlayıcılar atanabiliyordu. 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, DisplayInfo#uniqueId
değerini sabit bir tanımlayıcı eklemek ve yerel, ağ ve sanal ekranlar arasında ayrım yapmak için değiştirir.
Gösterim türü | Biçim |
---|---|
Yerel | local:<stable-id> |
Ağ | network:<mac-address> |
Sanal | virtual:<package-name-and-name> |
DisplayInfo.address
, uniqueId
güncellemelerine ek olarak, yeniden başlatmalarda kararlı olan DisplayAddress
ekran tanımlayıcısını da içerir. Android 10'da DisplayAddress
fiziksel 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
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ı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 desteklenmiyorsa veya hata oluşursa SurfaceFlinger, yukarıda açıklandığı gibi DisplayInfo#address
değerinin null olduğu ve DisplayInfo#uniqueId
değerinin sabit kodlandığı eski MD moduna geçer.
Bu özelliğin desteklendiğini doğrulamak için şunları ç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 için Statik görüntülü reklam tanımlayıcıları başlıklı makaleyi inceleyin.
Çerçeve, SurfaceControl#getPhysicalDisplayIds
'den veya bir DisplayEventReceiver
hotspot etkinliğinden 64 bit görüntü kimliğini aldıktan sonra SurfaceControl#getPhysicalDisplayToken
üzerinden fiziksel bir ekran için IBinder
jetonunu arayabilir.
Android 10 (ve önceki sürümler) cihazlarda birincil dahili ekran TYPE_INTERNAL
şeklindedir 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 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ümlerde kaldırılmıştır.
- Android 11'de, başlatma sırasında bildirilen ilk ekran birincil ekrandır. Bağlantı türü (dahili veya harici) önemli değildir. 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
veyaDisplay.TYPE_EXTERNAL
(eski adlarıyla sırasıylaDisplay.TYPE_BUILT_IN
veDisplay.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. Burada 0 dahili ekran, 1 harici ekran, [2, INT32_MAX]
HWC sanal ekranları ve -1 geçersiz ekranı veya HWC olmayan 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
özelliğini destekliyor ve ekran tanımlama verileri sağlıyorsa SurfaceFlinger, EDID yapısını ayrıştırır ve fiziksel ekranlar ile 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, yalnızca birden fazla kullanıcı aynı anda aynı cihazla etkileşime giren ve farklı giriş yöntemleri veya cihazlar (ör. Android Automotive) 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 bilgiler giren kullanıcıyı (ör. bir bankacılık uygulamasına giriş yapan veya hassas bilgiler içeren metin giren kullanıcı) düşünün. Kötü amaçlı bir uygulama, bir etkinliği yürütmek için kullanabileceğiniz sanal bir ekran dışı görüntü ve ayrıca bir metin giriş alanı oluşturabilir. Hem meşru hem de kötü amaçlı etkinlikler odaklanır ve her ikisi de etkin giriş göstergesi (yanıp sönen imleç) gösterir.
Ancak, klavyeden (donanım veya yazılım) gelen girişler yalnızca en üstteki etkinliğe (en son başlatılan uygulama) girildiğinden, kötü amaçlı bir uygulama gizli bir sanal ekran oluşturarak birincil cihaz ekranında yazılım klavyesi kullanıldığında bile kullanıcı 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şlemdeki iki pencerenin odaklandığı nadir durumlarda sistem, yalnızca Z sırasındaki daha yüksek 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 üstte odaklanan yığının tanımlanması gereken durumlarda benzer bir yaklaşım benimser. İlk uygun yığın aranırken yığınlar yukarıdan aşağıya doğru taranır.
InputDispatcher
artık birden çok odaklanmış pencereye
(ekran başına bir adet) sahip olabilir. Bir giriş etkinliği görüntülemeye özgüyse ilgili ekranda odaklanılan 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()
hükümlerini inceleyin. Odaklanmış uygulamalar da NativeInputManager::setFocusedApplication()
aracılığıyla InputManagerService'te 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ı.