blob: c0fb3b63a7457a0144cb527ef4f1089227b1db6b [file] [log] [blame]
<html devsite>
<head>
<title>Example Interaction Sequences</title>
<meta name="project_path" value="/_project.yaml" />
<meta name="book_path" value="/_book.yaml" />
</head>
{% include "_versions.html" %}
<body>
<!--
Copyright 2018 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<p>
In the following automotive audio examples, the vehicle head unit runs
Android {{ androidPVersionNumber }} and includes a radio application and a
navigation application. In addition, the vehicle tuner is externally routed
and plays over the speakers. In real-world use cases, it may be advantageous
to handle the tuner as an input to Android and have the Radio app read from
the tuner and write to an <code>AudioTrack</code> object.
</p>
<h2 id="user-starts-radio">User starts radio</h2>
<p>
In this interaction sequence, no media is playing in the vehicle when the user
presses <strong>Play</strong> for a preset frequency in the radio application.
The radio application must gain focus for the tuner to play sound over the
speakers.
</p>
<p><img src="/devices/automotive/images/audio_auto_focus_radio.png"></p>
<figcaption><strong>Figure 1.</strong> Radio gains focus and tuner play over
speakers</figcaption>
<ol>
<li>Radio: "Tune to FM 96.5."</li>
<li>Radio: Request focus GAIN.</li>
<li>AudioManager: GAIN granted.</li>
<li>Radio: <code>createAudioPatch()</code></li>
<li>Radio: "Play tuner output."</li>
<li>Externally-routed tuner: Mixer enables Tuner audio route to amplifier.
</li>
</ol>
<h2 id="radio-ducks-nav-prompt">Radio ducks navigation prompt</h2>
<p>
In this interaction sequence, the radio is playing when the navigation
application generates a navigation prompt for a next turn announcement. The
navigation application must obtain transient focus from the
<code>AudioManager</code> to play the navigation prompt.
</p>
<p><img src="/devices/automotive/images/audio_auto_radio_ducks.png"></p>
<figcaption><strong>Figure 2.</strong> Radio playback ducks navigation
prompt</figcaption>
<ol>
<li value="5">Radio: "Play tuner output."</li>
<li>Externally-routed tuner: Mixer enables Tuner audio route to amplifier.
</li>
<li>Navigation: Request focus GAIN TRANSIENT from <code>AudioManager</code>.
</li>
<li>AudioManager: GAIN TRANSIENT to Navigation.</li>
<li>Navigation: Open stream, send packets.
<ol>
<li>Navigation: Context GUIDANCE routed on bus1.</li>
<li>Mixer: Ducks Tuner to play bus1 GUIDANCE on Speakers.</li>
</ol>
</li>
<li>Navigation: Announcement over, close stream.</li>
<li>Navigation: Abandon focus.</li>
</ol>
<p>
The <code>AudioManager</code> recognizes the radio playback can duck and would
normally apply a ducking factor to the music stream without notifying the
radio application. However, the framework ducking is bypassed by overlaying
<code>framework/base/core/res/res/values/config.xml</code> and setting
<code>config_applyInternalDucking</code> to <code>false</code>, so the
external tuner continues to provide sound and the radio application remains
unaware of any changes. The mixer (below the HAL) is responsible for combining
the two inputs and can choose to duck radio playback or move radio playback to
the rear speakers.
</p>
<p>
When the navigation prompt is complete, the navigation application releases
focus and radio playback resumes.
</p>
<h2 id="user-launches-audio-book">User launches audio book application</h2>
<p>
In this interaction sequence, the user launches an audio book application,
causing radio playback to stop (pressing play in a streaming music app would
be a similar trigger).
</p>
<p><img src="/devices/automotive/images/audio_auto_focus_book.png"></p>
<figcaption><strong>Figure 3.</strong> Audio book takes focus from radio
playback</figcaption>
<ol>
<li value="12">Audio Book: Request GAIN context MEDIA from
<code>AudioManager</code>.</li>
<li>Radio loses focus:
<ol>
<li>AudioManager: LOSS.</li>
<li>Radio: <code>releaseAudioPatch()</code></li>
</ol>
</li>
<li>Audio Book gains focus:
<ol>
<li>GAIN granted, Context MEDIA routed on bus0</li>
<li>Open stream, send MEDIA packets.</li>
</ol>
</li>
</ol>
<p>
The request for focus by the audio book application is not transient, and so
the previous focus holder (the radio application), receives a permanent focus
loss, to which the radio application responds by tearing down the patch to the
tuner. The mixer stops listening to the tuner and starts processing the audio
delivered via the Audio HAL (it may also optionally perform a cross fade as
part of the radio-to-audiobook transition).
</p>
<h2 id="nav-prompt-takes-focus">Navigation prompt takes focus</h2>
<p>
In this interaction sequence, the audio book is playing when the navigation
application generates a navigation prompt.
</p>
<p><img src="/devices/automotive/images/audio_auto_focus_nav.png"></p>
<figcaption><strong>Figure 4.</strong> Navigation prompt takes focus from audio
book playback</figcaption>
<ol>
<li value="15">Audio Book: Streaming MEDIA packets, focus no-concurrent.</li>
<li>Navigation: Request GAIN TRANSIENT.</li>
<li>AudioManager: LOSS TRANSIENT.</li>
<li>Audio Book: Stops.</li>
<li>Audio Manager: GAIN TRANSIENT granted.</li>
<li>Navigation: Open stream, send packets.
<ol>
<li>Navigation: Context GUIDANCE routed on bus1.</li>
<li>Mixer: Plays bus1 (GUIDANCE).</li>
</ol>
</li>
<li>Navigation: Announcement over, close stream.</li>
<li>Navigation: Abandon focus.</li>
<li>Audio Book: GAIN.</li>
<li>Audio Book: Restarts.</li>
</ol>
<p>
Because the original audio book application <code>AudioFocusRequest</code>
(sent when starting the <code>AudioTrack</code>) included the
<code>AUDIOFOCUS_FLAG_PAUSES_ON_DUCKABLE_LOSS</code> flag, the
<code>AudioManager</code> determines it cannot handle ducking for the audio
book app. Instead, <code>AudioManager</code> sends an
<code>AUDIOFOCUS_LOSS_TRANSIENT</code> message to the audio book app, which is
expected to respond by suspending its playback.
</p>
<p>
The navigation application can now play the navigation prompt without
interruption. When the navigation prompt is complete, the audio book regains
focus and resumes playback.
</p>
</body>
</html>