Do not call directly into AudioSystem in setBluetoothScoOn() but
send a message to the AudioService handler instead. As the
procedure to switch audio path to BT SCO can last some time we should
not block the caller which can run in the UI thread.
Change-Id: I6ac4b5a934d69781db3aebe5d0e8137b52a0ada4
Use a death handler when audio focus changes are caused by audio
mode changes.
The bug comes from the fact that audio focus clients that use the
audio mode for automatic focus handling didn't register a death
handler, which was set to null. When such a client died, this
handler was compared against the one to remove from the
audio focus stack, which resulted in an NPE.
The fix consists in registering a valid IBinder object in the
audio focus stack, even for clients whose focus requests originate
from a change in audio mode, as implemented in the
handleFocusForCalls() method.
Change-Id: Id9e1d3d10afcd99969285f6d60fc4d7dde1e4a10
Release all sco audio clients when the intent indicating
STATE_AUDIO_DISCONNECTED state is received.
Also clear mScoClients array when clients are released.
Change-Id: I63ec9d70fe72a102e09a4a473a367fb2e550b171
The problem is that the AudioService is not notified of the death of
IAudioFlinger binder interface because no methods was called on AudioFlinger
from system_server since the device booted. Therefore, AudioSystem did not created any
IAudioFlinger interface in the system_server process.
The root cause was always present but more likely to happen on a tablet than on a phone
as for instance no beeps are played when volume is adjusted.
The fix consists in having AudioSystem explicitly call a method on AudioFlinger when a
callback is installed to make sure that an IAudioFlinger binder interface is created
regardless of any other activity in the client process.
Change-Id: I9df34a36825af0b25cd0246dd02edbd712263f41
Commit 25101b0b in AudioSystem for issue 3395734 broke the mechanism
in AudioService to poll and detect the restarting of media server
process after a crash.
The fix consists in changing the method used to poll AudioSystem and
trigger a callback indicating success when media server is responding
(the method must be on IAudioFlinger and not IAudioService to trigger the callback).
Change-Id: I843c0194de9cbf82c779cabbf2f3cbf8064603c8
- Make sure that STREAM_MUSIC is affected by ringer mode on non voice capable
devices whatever the saved settings say.
- Added a hidden method to AudioManager for VolumePanel to override
the stream selection logic while the panel is showing.
Change-Id: Ib2ff2a7af63decb4e29c45700c41e5058f79d877
Modified default volume control logic in AudioService:
1 IN_CALL volume if in video/audio chat
2 NOTIFICATION if notification is playing or was playing less than 5s ago.
3 MUSIC
Modified silent mode:
- now also affect MUSIC stream type
- entering silent mode when VOL- hard key is pressed once while selected
stream volume is already at 0 (except for VOICE_CALL stream).
- exiting silent mode when pressing VOL+ hard key while in silent mode
Play sound FX (audible selections, keyboard clicks) at a fixed volume.
Modified audio framework:
- isStreamActive() method now implemented in AudioPolicyManagerBase (previously AudioFlinger)
- iStreamActive() now specifies a time window during which the stream is considered
active after it actually stopped.
Change-Id: I7e5a0724099450b9fc90825224180ac97322785f
When the user is in a phone or VoIP call, the volume keys should
control the STREAM_VOICE_CALL volume. Before MODE_IN_COMMUNICATION
was introduced to cover VoIP use cases, having an active VoIP call
was determined by checking whether there was any track used the
output stream STREAM_VOICE_CALL, which can give false positives.
This CL checks instead against the audio mode to see if
MODE_IN_COMMUNICATION is selected to determine if a VoIP call
is in progress.
This implies that applications that play on STREAM_VOICE_CALL
shouldn't rely on that fact alone to expect the volume keys
to control the STREAM_VOICE_CALL volume, and should instead,
rely on the official mechanism for that:
android.app.Activity.setVolumeControlStream(int)
Change-Id: Ia487951ea1684477aa3d522c9031fad484d8a40d
The problem is that SoundPool never calls the onLoadComplete() callback
when load() method fails because the file cannot be opened.
AudioService loadSoundEffects() was blocked waiting for a callback
that never came.
In this particular case, this happened on a specific build where sound
effects assets were not included.
The fix consists in waiting for the callback only if at least one sample is
accepted by SoundPool load().
Also moved the initial loading of sound effect samples from the boot completed
broadcast receiver to the audio service message handler to avoid waiting in the
main system server thread.
Change-Id: I902e5988f8b644a81d8e585c52eed1df4ca0ec05
The problem can occur if a sample is started at the same time as the last AudioTrack callback
for a playing sample is called. At this time, allocateChannel() can be called concurrently with moveToFront()
which can cause an entry in mChannels being used by moveToFront() to be erased temporarily by allocateChannel().
The fix consists in making sure that the SoundPool mutex is held whenever play(), stop() or done() are called.
In addition, other potential weaknesses have been removed by making sure that the channel mutex is held while
starting, stopping and processing the AudioTrack call back.
To that purpose, a mechanism similar to the channel restart method is implemented to avoid stopping channels
from the AudioTrack call back but do it from the restart thread instead.
The sound effects SounPool management in AudioService has also been improved to make sure that the samples have
been loaded when a playback request is received and also to immediately release the SoundPool when the effects are
unloaded without waiting for the GC to occur.
The SoundPool.java class was modified to allow the use of a looper attached to the thread in which the sample
loaded listener is running and not to the thread in which the SoundPool is created.
The maximum number of samples that can be loaded in a SoundPool lifetime as been increased from 255 to 65535.
Change-Id: I368a3bdfda4239f807f857c3e97b70f6b31b0af3
HDMI device should have a higher priority than analog dock audio but a lower priority
than wired headsets.
Also modified AudioService so that HDMI is mapped to DEVICE_OUT_AUX_DIGITAL device and not
DEVICE_OUT_DGTL_DOCK_HEADSET as before to enable discrimination between SPDIF going to
digital dock and SPIDF going to HDMI.
Change-Id: I887d0c73479784dd2edaf41ce1a7d8d0bdcbb4bd
Before the introduction of the MODE_IN_COMMUNICATION audio mode,
"calls" were only made through telephony and the PhoneStateListener
was used to request and abandon audio focus as calls where started
and ended. VoIP applications do not cause phone state events to
be broadcast, and set the audio mode to MODE_IN_COMMUNICATION
directly. This change monitors mode changes to automatically
grab and abandon audio focus.
Change-Id: Ie9a4193e35ba8447764fac66a988959a93c4909f
AudioService now uses SCO virtual calls instead of voice recognition to
implement startBluetoothSco() method.
Also make sure that a virtual call is not started when SCO audio is active
due to in call audio or voice recognition.
Change-Id: I93ed119afbc57250a4433201156714e35f70fea4
The audio mode MODE_IN_CALL signals the system the device a phone
call is currently underway. There was no way for audio video
chat or VoIP applications to signal a call is underway, but not
using the telephony resources. This change introduces a new mode
to address this. Changes in other parts of the system (java
and native) are required to take this new mode into account.
The generic AudioPolicyManager is updated to not use its phone
state variable directly, but to use two new convenience methods,
isInCall() and isStateInCall(int) instead.
Change-Id: Id744cd26520ea1d1a4795eabe6a1f0c58789af76
Why is it needed: SCO audio connections can fail.
Currently no indication is given to clients which are waiting
for SCO connections. This was working fine before because
SCO connections where blocking calls, which was wrong in itself.
Change-Id: Ic449b2db8506a7a5ae6be6c68715f1a7343f9e40
app is the phone is ringing, even in silent mode.
Use the PhoneStateListener to know whether the phone is ringing,
as the mode is not MODE_RINGTONE when ringing in silent mode.
Change-Id: Iede350cecde0b663d50f9b4a57f9a9ef08066c0d
Problem:
When the bluetooth device is removed, the AudioService clears all active SCO connections
and unlinks from the client application's binder interface death.
The problem is that the unlinking is done even if no more connections are active for a given client,
which throws a runtime exception that is not catched causing the system server to crash.
The fix consists in calling unlinkToDeath() in ScoClient.clearCount() only if the number of
active SCO connections for this client is not 0. The NoSuchElementException exception is also
catched when calling unlinkToDeath()
Change-Id: I29a28fcce1a579217cea271956a55778e05d3e37
Use setParameters() API to indicate to audio HAL that we are restarting the media server after a crash.
The use made by audio HAL implementation of this indication is platform specific.
Change-Id: I085b174fa1474575da0e4d295921079b6b68efb8
When the user selects a "Silent" notification sound, the Uri encoded
path is an empty string. Setting this Uri as the data source of the
MediaPlayer used to play notifications caused the completion listener
to not be called, which with the AudioFocus logic causes the Music
app to pause and never resume. The NotificationPlayer modifications
cause the MediaPlayer for the notification to only request audio
focus when the data source is not empty.
The audio focus code in AudioService is defensively synchronized
against a unique lock, and the exception observed in bug 2670395
is explicitely caught in case another edge case wasn't caught by
this fix.
The AudioFocus handling in AudioManager is modified so only the
requestAudioFocus and abandonAudioFocus methods are meant to be
used, as registerAudioFocusListener and unregisterAudioFocusListener
provided no additional functionality over the request/abandon
methods. abandonAudioFocus() also removes the listener from the
map in AudioManager since after abandonning focus, the listener
would no longer be called.
Change-Id: I3b553ee8a8163c25e01117d7e5479dd5fdfa7c6b
connected to A2DP media profile
When the phone is docked and using the dock A2DP, and the user
connects another A2DP device, make the dock unavailable immediately
before connecting the new A2DP device.
Change-Id: I82d53836fb509ee4ea7cdb68f467dfb946c634f8
Phone calls and rings are treated as a new client, with a dedicated
client ID that identifies it in the audio focus stack. When it is
present in the stack, others clients cannot request audio focus
(request is denied).
Because the phone state is now mostly handled like a new client,
there is no need monitor mode changes and to keep track of
undispatched focus changes, as those will delayed focus gains
will now automatically happen at the end of the call when the
phone client is removed from the focus stack.
Change-Id: I11ff73b015ab93f07040755fd8ee75c8d675e025
The problem occurs if the device is powered down in silent mode. When the device restarts,
AudioService reads current ringer mode from saved settings but does not call setRingerModeInt()
to perform actions required when ringer mode changes.
The volumes of streams affected by ringer mode are actually at 0 because they are also read from settings
but their mute state is not applied correclty. When we later exit from silent mode, the streams
other than STREAM_RING that are affected by ringer mode are not restored as they are not considered
muted. This applies to STREAM_SYSTEM but also to STREAM_NOTIFICATION if its volume is controlled independently
from STREAM_RING.
The fix consists in calling setRingerModeInt() when AudioService starts.
Change-Id: Ica75b9874938dda1bc1b634c3e97db4a650d295c
There was a regression introduced by change 4c637b9e34
fixing issue 2578813. As the A2DP device disconnection is notified to the audio policy manager
after a delay, there is a period during which the A2DP device is actually not connected but the
A2DP output is considered present by audio framework. If a playback is started during this period,
The A2DP output requests the activation of the A2DP sink which in turn triggers a reconnection
of the A2DP sink.
The fix consists in suspending the A2DP output immediately when receiving the A2DP disconnection
intent so that any activity on A2DP output is ignored until the output is actually closed by the
audio policy manager.
Change-Id: I16eaace45e12bfc970f50836b46a73b756b493f0
This is a regression introduced by change 5b4e654d0c for issue 2472495.
When AudioService changes audio mode, setMode() reapplies current volume for the default active stream
which in this case is STREAM_RING.
Because the new implementation of silent mode actually mutes the ringer stream,
setStreamVolumeInt() now applies the volume change received while in silent mode
to the last audible value and we end up clearing the last audible volume for ringer.
The fix consists in not modifying last audible value when the new value is 0.
Also removed obsolete code in setStreamVolumeInt() since new implementation of setRingerModeInt()
in change 5b4e654d0c.
Change-Id: I746f3bc1af39a602ce12d130ce592007b2d0ebb6
The problem happens only if volume down key is pressed while
already in silent or vibrate mode. In this case, AudioService accepts
changing the last audible index for ringer volume from 1 to 0.
When volume up is pressed, current ringer volume value is restored from 0
instead of 1.
The fix consists in keeping last audible index at 1 once in silent of vibrate
mode even is volume down key is pressed.
Change-Id: Id08edd12ce985c22233124545eba2c3e4b8cdc8e
Moved broadcast of ACTION_AUDIO_BECOMING_NOISY from BluetoothA2dpService
to AudioService.
Broadcast ACTION_AUDIO_BECOMING_NOISY when disconnecting an A2DP
device.
Disconnect from A2DP docks with a delay to handle transient
disconnections.
Cancel delayed A2DP disconnections when connecting to a dock as this
can be a reconnection after a transient disconnection.
Change-Id: I1ee9e99f3ffa20727af38a4c4c8711942894a696
Unlike the other audio focus and media button stack handling
methods, abandonAudioFocus() and unregisterAudioFocusClient() were
not synchronized around their focus stack. This CL corrects this.
Change-Id: I5ada574e4e163fa95da9dad2fefe610b48303320
The problem is that AudioService.adjustStreamVolume() only handles the ringer mode change when the
STREAM_RING volume changes from 1 to 0 or 0 to 1. If another stream is soloed, the STREAM_RING stream
volume is forced to 0 and then never transits from 0 to 0 when volume down key is pressed.
The fix consists in considering the saved value instead of current value when ajusting or setting
the volume of a muted stream: only the saved value is adjusted too, leaving the stream muted but updating
the value that will be restored when it will be unmuted.
Also changed implementation of stream volume control by setRingerModeInt() to use stream mute feature
instead of direct volume control.
Change-Id: Id85d76450b36d61a0fe8195eb4bffe63ffbd427c
- if a focus owner abandons audio focus during a call, the next
focus owner in the stack was never notified
- if a focus owner requests the focus while alread owning it, and
the type of focus request changes, the previous focus owner was
not notified that the type of focus loss had changed.
Change-Id: Iee6c6e17bcdd3c225a4b600f40ba434294870f17
Added public methods to AudioManager API so that unbundled applications can use bluetooth
SCO audio when the phone is not incall.
Without this change, the only way to activate and use bluetooth SCO is via the BluetoothHeadset API
which is not public yet.
Change-Id: Ia1680f219ea1d0943092d475d5be7d6638983ebb
events among multiple applications competing for the remote control
focus.
AudioManager defines a new API for applications to use in order to
register their BroadcastReceiver for the media button as the one
to receive the corresponding intent, but all applications at the
same time (in an ordered broadcast).
AudioService handles a stack of remote control focus owners. It
traps ACTION_MEDIA_BUTTON intents and sends a new intent to the
remote control focus owner.
Change-Id: I3c109221ecfb160cbb1ec0e40a71b241aad73812
Part 1 of the fix: when the user doesn't elect to use the car dock
for music and media, the APM was not aware of the device being
docked.
This is fixed by dissociating the notification for the APM of
the docking to the dock from the sink state change of the A2DP
device.
Also missing was forcing the volumes to be reevaluated whenever
the device is docked or undocked, as volumes for docks may
differ, even when the same output device is being used.
Change-Id: If5314e27821a71adbd6df6fdf887c45208241d96
The problem is that even if silent mode is active, changing the alarm volume will change current
alarm stream volume. This is true for other stream types affected by ringer mode (ring, notification...) but
the UI design is such that it is not possible to change these volumes while in silent mode.
The fix consists in modifying AudioService.setStreamVolumeInt() so that when a stream is affected by ringer mode
and we are in silent mode, only the saved volume value is modified, current value remaining to unchanged (0).
In earlier versions of Android, "vibrate mode" (in which
only alarms and media produce sound, but notifications may
operate the vibe motor) was only accessible by adjusting the
ringer volume (via the device's volume rocker) down until
the "vibrate" icon appeared (between the lowest ring volume
and silent mode).
Many users prefer that "silent mode" always allow vibration.
Others prefer Android's historical behavior, in which silent
mode stops the vibes as well.
To accommodate these two distinct usage patterns, we now
allow the user to decide whether vibration is allowed in
"silent mode", a user interface abstraction that now spans
both AudioManager.RINGER_MODE_VIBRATE and
AudioManager.RINGER_MODE_SILENT.
To minimize API impact (and therefore maximize backward
compatibility), RINGER_MODE_VIBRATE and RINGER_MODE_SILENT
remain unchanged. What has changed is what happens when the
user activates silent mode, either via Settings,
GlobalActions (longpress on power), volume rocker, or the
keyguard tab. In essence, there is now only one "silent"
position in these controls, and whether RINGER_MODE_VIBRATE
or RINGER_MODE_SILENT is actually set on the AudioService is
determined by a new one-off setting
(System.VIBRATE_IN_SILENT). This new setting isn't meant to
be a long-term API, however: in the future we hope to
replace and extend this design with a much more
sophisticated set of systemwide feedback profiles. ETA TBD.
Related changes:
* I09ad7d69 (GlobalActions and keyguard)
* I22ba7bcf (Settings app)
Bug: 2457183
Change-Id: I14cf91b0910261ffdfd1bf302423f41ec747d057
AudioService now sends intent AudioManager.VOLUME_CHANGED_ACTION when the volume is changed
on any stream type (previously the intent was sent only for STREAM_BLUETOOTH_SCO stream).
A new extra for previous volume value is added to the intent.
Modified AudioService.getActiveStreamType() so that STREAM_VOICE_CALL is selected when a track using this stream
type is playing.
Chanded isMusicActive() for a more generic isStreamActive(stream) method in AudioSystem, IAudioFlinger and AudioFlinger.
This change fixes a problem occuring when an application (for instance a VoIP application)
changes the audio mode to MODE_IN_CALL and crashes. In this case, the audio routing policy
remains as if we were in call until the audio mode is changed back to MODE_NORMAL, for instance when a new call
made or received and terminated.
The fix consists in registering a death receipient to the binder that made the setMode() request and resetting the audio
mode in case of client process crash.