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