NotificationPlayer: fix race conditions
This patch fixes two race conditions that affect the Looper used
to signal the completion of a notification to abandon audio focus
as well as the wakelock used between issuing a playback
command and its actual start. Annotations are added to clarify
which objects are used to synchronize which methods and variables.
Looper for notification playback completion:
Before a notification starts playing, audio focus is requested,
which causes the ducking of media apps. When the notification
completes, audio focus is abandoned. If a new notification is
to be played while one is playing, the current player is
stopped and the Looper on which we expect the MediaPlayer
completion callback is .quit(). But there is a race condition
between the quitting of the current Looper whenever a sound
is started (in startSound()) and when quit when playback
is stopped (command STOP), and when created in
CreationAndCompletionThread.run(). If the Looper is quit
when another notification starts to play, the completion
callback cannot be received, and audio focus will not be
abandoned.
The fix consists in synchronizing all access to mLooper
on mCompletionHandlingLock.
Wakelock:
Initializing and acquiring the wakelock, and releasing it
are done in different threads (client thread vs CmdThread).
There was no memory barrier between the initialization
and release. The fix consists in making all wakelock
operations synchronized on mCmdQueue.
Test: issue multiple notifications that interrupt eachother, verify focus is abandonned (in logs, check "abandonAudioFocus()")
Bug: 65866087
Bug: 64531811
Change-Id: Ie8f4091eaa96bd0bcb732e27423f6e31e76da98e
1 file changed