Ses Odağı

Bir uygulama, mantıksal bir akış başlatmadan önce mantıksal akışında kullanılanla aynı ses özelliklerini kullanarak ses odağını istemelidir. Bu tür bir odaklanma isteği göndermek önerilir ancak sistem tarafından zorunlu kılınmaz. Bazı uygulamalar, belirli davranışlara ulaşmak için isteği göndermeyi açıkça atlayabilir (ör. telefon görüşmesi sırasında ses çalmak için).

Bu nedenle, odağı birincil ses kontrol mekanizması olarak değil, oynatmayı dolaylı olarak kontrol etme ve çakışmayı önleme yöntemi olarak değerlendirmeniz gerekir. Araç, ses alt sisteminin çalışması için odağı kullanmamalıdır.

Odak etkileşimleri

AAOS'un ihtiyaçlarını desteklemek için ses odak isteklerinin işlenmesi, isteğin CarAudioContext ile mevcut odak sahiplerinin CarAudioContext arasındaki önceden tanımlanmış etkileşimlere dayanır. Üç tür etkileşim vardır: münhasır, reddetme ve eşzamanlı.

Özel etkileşim

Özel etkileşimlerde aynı anda yalnızca bir uygulamanın odakta olmasına izin verilir. Bu nedenle, gelen odak isteğine odaklanma izni verilirken mevcut odak sahibi odağını kaybeder. Buna örnek olarak, mevcut bir uygulamada müzik çalarken kullanıcının yeni bir müzik uygulaması başlatması verilebilir. Her ikisi de medya oynattığından, aynı anda yalnızca bir uygulamanın odağa alınmasına izin verilir. Sonuç olarak, yeni başlatılan uygulamanın odak isteği AUDIOFOCUS_REQUEST_GRANTED ile döndürülür ve şu anda müzik çalan uygulama, yapılan istek türüne karşılık gelen bir kayıp durumu içeren bir odak değişikliği etkinliği alır. Bu, Android'de en sık görülen etkileşim modelidir.

Etkileşimi reddetme

Reddetme etkileşimlerinde gelen istek her zaman reddedilir. Bir arama devam ederken müzik çalmaya çalışmak, reddedilen etkileşime örnek gösterilebilir. Bu durumda, arama cihazı şu anda bir arama için ses odağını elinde tutuyorsa ve ikinci bir uygulama müzik çalmak için odak isterse müzik uygulaması, isteğiyle birlikte AUDIOFOCUS_REQUEST_FAILED değerini alır. Odak isteği reddedildiği için mevcut odak tutucusuna herhangi bir türde odak kaybı gönderilmez.

Eşzamanlı etkileşim

AAOS'a özgü en önemli özelliklerden biri eşzamanlı etkileşimlerdir. Bu sayede, araçta ses odağına sahip olmak isteyen uygulamalar diğer uygulamalarla aynı anda odağa sahip olabilir. Eşzamanlı etkileşimin gerçekleşmesi için aşağıdaki koşulların karşılanması gerekir. Aşağıdakiler:

Bu ölçütler karşılanırsa odaklanma isteği AUDIOFOCUS_REQUEST_GRANTED ile döndürülür ve mevcut odaklanma tutucusunda odaklanmada herhangi bir değişiklik olmaz. Ancak, mevcut odak sahibi, gizleme etkinlikleri almayı veya gizlendiğinde duraklatmayı seçerse mevcut odak sahibi, özel etkileşimde olduğu gibi odağı kaybeder.

Eşzamanlı akışları yönetme

Eşzamanlı etkileşimin birçok yararlı uygulaması olsa da OEM'lerin, çıkış cihazları arasında donanım düzeyinde karıştırma ve ses azaltma işlemlerini yapması gerekir. Bu nedenle, CarAudioContext'lerin yalnızca eşzamanlı olarak oynayamadıkları CarAudioContext'lerle aynı çıkış cihazına yönlendirilmesi önemle tavsiye edilir. Eşzamanlı yayınlar için ayrı çıkış cihazları olması, HAL'in yayınları karıştırmadan önce yayınlardan birini susturmasına veya fiziksel yayınları araçtaki farklı hoparlörlere yönlendirmesine olanak tanır. Mantıksal akışlar Android'de karıştırılırsa kazançları değiştirilmez ve aynı fiziksel akış kapsamında yayınlanır.

Örneğin, gezinme ve medya aynı anda yayınlanırken medya akışının kazancı geçici olarak azaltılabilir (ses kısılabilir) böylece gezinme talimatları daha net duyulabilir. Alternatif olarak, navigasyon akışı sürücü tarafı hoparlörlere yönlendirilebilir. Bu durumda, medya kabinin geri kalanında çalmaya devam eder.

Etkileşim matrisi

Aşağıdaki tabloda, CarAudioService tarafından tanımlanan etkileşim matrisi gösterilmektedir. Satırlar, mevcut odak tutucunun CarAudioContext değerini, sütunlar ise gelen isteğin değerini temsil eder.

Bir müzik medya uygulamasının şu anda odaklandığını ve bir navigasyon uygulamasının odak isteğinde bulunduğunu varsayalım. Matriste, eşzamanlı etkileşimler ile ilgili diğer ölçütlerin karşılandığı varsayılarak iki etkileşimin eşzamanlı olarak oynatılabileceği gösterilir.

Eşzamanlı etkileşimler nedeniyle birden fazla odak tutucunun olması mümkündür. Bu durumda, gelen bir odaklanma isteği, ne tür bir etkileşimin uygulanacağına karar verilmeden önce mevcut odaklanma sahiplerinin her biri ile karşılaştırılır. Bu durumda en muhafazakar etkileşim kazanır (reddet, ardından özel ve son olarak eşzamanlı).

Aşağıdaki tabloda, gelen bir odak isteği için CarAudioContext (sütunlar) ile mevcut odak tutucuların bağlamı (satırlar) arasındaki odak etkileşimleri sağlanmaktadır. Her hücre, iki bağlam için beklenen etkileşim türünü temsil eder.

Ses odağı etkileşimleri

Şekil 1. Ses odağı etkileşimleri

Android 11'de, kullanıcıların gezinme ve telefon görüşmeleri arasındaki etkileşim davranışını değiştirmelerine olanak tanıyan yeni bir kullanıcı ayarı kullanıma sunuldu. Ayarlandığında android.car.KEY_AUDIO_FOCUS_NAVIGATION_REJECTED_DURING_CALL, gelen NAVIGATION odak istekleriyle mevcut CALL odak tutucular arasındaki etkileşimi eşzamanlı yerine reddet olarak değiştirir. Bu nedenle, bir kullanıcının aramasını navigasyon talimatlarının bölmesini istemiyorsa bu ayarı etkinleştirebilir. Bu değer kullanıcı için kalıcı olur ve sonraki odaklanma isteklerinin yeni ayar değerine uyması için dinamik olarak ayarlanabilir.

Ertelenebilen ses odağı

Android 11'de AAOS, geciktirilebilir ses odağını isteme desteği ekledi. Bu sayede, geçici olmayan odak isteklerinin, mevcut odak sahipleriyle etkileşimi normalde reddedilmelerine neden olduğunda geciktirilmesi sağlanır. Odaktaki bir değişiklik, gecikmeli isteğin odak alabileceği bir duruma yol açtığında istek kabul edilir.

Gecikmeli ses odak istekleriyle ilgili kurallar

  • Yalnızca geçici olmayan istekler: Daha önce de belirtildiği gibi, gecikmeli istek yalnızca geçici olmayan kaynaklar için gönderilebilir. Bu, geçici bir sesin alakalı olmaktan çok sonra çalınmasını önlemek içindir.
  • Tek seferde yalnızca bir istek ertelenebilir: Ertelenebilen bir istek, ertelenmiş bir istek varken yapılırsa orijinal ertelenmiş istek bir AUDIOFOCUS_LOSS değişiklik etkinliği alır ve yeni istek AUDIOFOCUS_REQUEST_DELAYED eşzamanlı yanıtı alır.
  • Geciktirilebilir isteklerin bir OnAudioFocusChangeListener değeri olmalıdır. Bir istek ertelendikten sonra, istek sonunda kabul edildiğinde (AUDIOFOCUS_GAIN) veya daha sonra reddedildiğinde (AUDIOFOCUS_LOSS) istek sahibini bilgilendirmek için dinleyici kullanılır.

Ertelenebilen odaklanmayı isteme

Ertelenebilecek bir istek oluşturmak için AudioFocusRequest.Builder#setAcceptsDelayedFocusGain:

mMediaWithDelayedFocusListener = new MediaWithDelayedFocusListener();

mDelayedFocusRequest = new AudioFocusRequest
     .Builder(AudioManager.AUDIOFOCUS_GAIN)
     .setAudioAttributes(mMusicAudioAttrib)
     .setOnAudioFocusChangeListener(mMediaWithDelayedFocusListener)
     .setForceDucking(false)
     .setWillPauseWhenDucked(false)
     .setAcceptsDelayedFocusGain(true)
     .build();

Ardından, isteği gönderirken AUDIOFOCUS_REQUEST_DELAYED yanıtını ele alın:

int delayedFocusRequestResults = mAudioManager.requestAudioFocus(mDelayedFocusRequest);
if (delayedFocusRequestResults == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
// start audio playback
return;
}
if (delayedFocusRequestResults == AudioManager.AUDIOFOCUS_REQUEST_DELAYED) {
     // audio playback delayed to audio focus listener
     return;
}

İstek gecikirse odak dinleyicisi, odaktaki değişiklikleri yönetmekten sorumludur:

private final class MediaWithDelayedFocusListener implements
OnAudioFocusChangeListener {
       @Override
       public void onAudioFocusChange(int focusChange) {
           synchronized (mLock) {
               switch (focusChange) {
                   case AudioManager.AUDIOFOCUS_GAIN:
                        // Start focus playback
                   case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
                        // Pause media transiently
                   case AudioManager.AUDIOFOCUS_LOSS:
                        // Stop media

Çoklu bölgeli odak yönetimi

Birden fazla ses bölgesi olan araçlarda ses odak noktası her bölge için ayrı ayrı yönetilir. Bu nedenle, bir bölgeye gönderilen istek, diğer bölgelerde neyin odaklandığını dikkate almaz ve diğer bölgelerdeki odak tutucuların odağını kaybetmesine neden olmaz. Bu sayede ana kabinin odak noktası, arka koltuk eğlence sisteminden ayrı olarak yönetilebilir. Böylece, bir bölgedeki odak değişiklikleri nedeniyle başka bir bölgedeki ses oynatmanın kesintiye uğraması önlenebilir.

Tüm uygulamalarda odak yönetimi CarAudioService tarafından otomatik olarak yönetilir. Odak isteği ses bölgesi, ilişkili UserId veya UID'a göre belirlenir. Ayrıntılar için Ses Yönlendirme başlıklı makaleyi inceleyin.

Eşzamanlı olarak birden fazla bölgeden ses isteme

Bir uygulama birden fazla bölgede aynı anda ses çalmak istiyorsa pakete AUDIOFOCUS_EXTRA_REQUEST_ZONE_ID ekleyerek her bölge için odaklanmayı istemelidir:

// Create attribute with bundle and AUDIOFOCUS_EXTRA_REQUEST_ZONE_ID
Bundle bundle = new Bundle();
bundle.putInt(CarAudioManager.AUDIOFOCUS_EXTRA_REQUEST_ZONE_ID,
               zoneId);

AudioAttributes attributesWithZone = new AudioAttributes.Builder()
     .setUsage(AudioAttributes.USAGE_MEDIA)
     .addBundle(bundle)
     .build();

// Create focus request using built attributesWithZone

Bu paket parametresi, istek sahibinin otomatik ses bölgesi eşlemelerini geçersiz kılarak belirtilen bölge kimliğini kullanmasına olanak tanır. Bu nedenle, bir uygulama farklı ses bölgeleri için ayrı istek gönderebilir.

HAL Ses Odağı

Android 11'den itibaren HAL, harici akışlar adına odaklanma isteğinde bulunabilir. İsteğe bağlı olsa da bu API'lerin, Android ekosisteminde daha iyi katılımcılar olmak ve daha sorunsuz bir kullanıcı deneyimi sunmak için harici sesleri etkinleştirmesi önemle tavsiye edilir.

Hangi seslerin öncelikli olacağı konusunda nihai kararı HAL'ın verdiğini unutmayın. Bu nedenle, acil durum ve güvenlik açısından kritik sesler, HAL'e ses odağının verilip verilmediğinden bağımsız olarak çalınmalı ve HAL ses odağını kaybederse bile uygun şekilde çalınmaya devam etmelidir. Aynı durum, yönetmelikler uyarınca gerekli olan tüm sesler için de geçerlidir.

Aynı şekilde HAL, acil durum veya güvenlik açısından kritik seslerin net bir şekilde duyulmasını sağlamak için Android akışlarını gerektiğinde proaktif olarak sessize almalıdır.

AudioControl@2.0

AudioControl HAL'ın 2.0 sürümünde birkaç yeni API kullanıma sunulmuştur:

API Amaç
IAudioControl#registerFocusListener AudioControl HAL ile bir IFocusListener örneği kaydeder. Bu dinleyici, HAL'in ses odağını istemesini ve bırakmasını sağlar. HAl'ın, dinleyicinin kaydını iptal etmek için Android tarafından kullanılacak bir ICloseHandle örneği sağlaması beklenir.
IAudioControl#onAudioFocusChange HAL tarafından IFocusListener üzerinden yapılan odaklanma isteklerinde durum değişikliklerini HAL'e bildirir. İlk odaklanma isteklerine verilen yanıtlar da buna dahildir.
IFocusListener#requestAudioFocus Belirli bir kullanım, bölge kimliği ve odak kazancı türü için HAL adına odaklanma isteğinde bulunur.
IFocusListener#abandonAudioFocus Belirtilen kullanım ve bölge kimliği için mevcut HAL odaklanma isteklerini terk eder.

HAL'de aynı anda birden fazla odak isteği olabilir ancak kullanım ve bölge kimliği eşleştirme başına bir istekle sınırlıdır. Android, HAL'ın bir istek yapıldıktan sonra hemen ses çalmaya başladığını ve odak kaybolana kadar bunu yapmaya devam ettiğini varsayar.

Android'in bir odaklanma isteği işlenirken HAL'i geciktirmemesi için registerFocusListener dışındaki tüm bu istekler oneway olur. HAL, güvenlik açısından kritik sesleri oynatmadan önce odaklanmayı beklememelidir. HAL'in IAudioControl#onAudioFocusChange üzerinden ses odak noktasındaki değişiklikleri dinlemesi ve bunlara yanıt vermesi isteğe bağlıdır ancak uygun olduğunda önerilir.