Fix deadlock in AudioService

Locks related to audio focus and remote control should always be
 taken in the following order:
 1/ audio focus lock
 2/ remote control stack
 3/ current remote control client generation

Change-Id: If8be11bfef92849957e692b2bd52adbd67a2ef0b
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index a876291..fe57e8a 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -3072,7 +3072,7 @@
     /**
      * Update the remote control displays with the new "focused" client generation
      */
-    private void setNewRcClientOnDisplays_syncRcStack(int newClientGeneration,
+    private void setNewRcClientOnDisplays_syncAfRcsCurrc(int newClientGeneration,
             ComponentName newClientEventReceiver, boolean clearing) {
         // NOTE: Only one IRemoteControlDisplay supported in this implementation
         if (mRcDisplay != null) {
@@ -3091,7 +3091,7 @@
     /**
      * Update the remote control clients with the new "focused" client generation
      */
-    private void setNewRcClientGenerationOnClients_syncRcStack(int newClientGeneration) {
+    private void setNewRcClientGenerationOnClients_syncAfRcsCurrc(int newClientGeneration) {
         Iterator<RemoteControlStackEntry> stackIterator = mRCStack.iterator();
         while(stackIterator.hasNext()) {
             RemoteControlStackEntry se = stackIterator.next();
@@ -3115,15 +3115,13 @@
      * @param clearing true if the new client generation value maps to a remote control update
      *    where the display should be cleared.
      */
-    private void setNewRcClient(int newClientGeneration, ComponentName newClientEventReceiver,
-            boolean clearing) {
-        synchronized(mRCStack) {
-            // send the new valid client generation ID to all displays
-            setNewRcClientOnDisplays_syncRcStack(newClientGeneration, newClientEventReceiver,
-                    clearing);
-            // send the new valid client generation ID to all clients
-            setNewRcClientGenerationOnClients_syncRcStack(newClientGeneration);
-        }
+    private void setNewRcClient_syncAfRcsCurrc(int newClientGeneration,
+            ComponentName newClientEventReceiver, boolean clearing) {
+        // send the new valid client generation ID to all displays
+        setNewRcClientOnDisplays_syncAfRcsCurrc(newClientGeneration, newClientEventReceiver,
+                clearing);
+        // send the new valid client generation ID to all clients
+        setNewRcClientGenerationOnClients_syncAfRcsCurrc(newClientGeneration);
     }
 
     /**
@@ -3133,11 +3131,13 @@
         // TODO remove log before release
         Log.i(TAG, "Clear remote control display");
 
-        synchronized(mCurrentRcLock) {
-            mCurrentRcClientGen++;
-
-            // synchronously update the displays and clients with the new client generation
-            setNewRcClient(mCurrentRcClientGen, null /*event receiver*/, true /*clearing*/);
+        synchronized(mRCStack) {
+            synchronized(mCurrentRcLock) {
+                mCurrentRcClientGen++;
+                // synchronously update the displays and clients with the new client generation
+                setNewRcClient_syncAfRcsCurrc(mCurrentRcClientGen,
+                        null /*event receiver*/, true /*clearing*/);
+            }
         }
     }
 
@@ -3145,30 +3145,32 @@
      * Called when processing MSG_RCDISPLAY_UPDATE event
      */
     private void onRcDisplayUpdate(RemoteControlStackEntry rcse, int flags /* USED ?*/) {
-        synchronized(mCurrentRcLock) {
-            if ((mCurrentRcClient != null) && (mCurrentRcClient.equals(rcse.mRcClient))) {
-                // TODO remove log before release
-                Log.i(TAG, "Display/update remote control ");
+        synchronized(mRCStack) {
+            synchronized(mCurrentRcLock) {
+                if ((mCurrentRcClient != null) && (mCurrentRcClient.equals(rcse.mRcClient))) {
+                    // TODO remove log before release
+                    Log.i(TAG, "Display/update remote control ");
 
-                mCurrentRcClientGen++;
+                    mCurrentRcClientGen++;
+                    // synchronously update the displays and clients with
+                    //      the new client generation
+                    setNewRcClient_syncAfRcsCurrc(mCurrentRcClientGen,
+                            rcse.mReceiverComponent /*event receiver*/,
+                            false /*clearing*/);
 
-                // synchronously update the displays and clients with the new client generation
-                setNewRcClient(mCurrentRcClientGen,
-                        rcse.mReceiverComponent /*event receiver*/,
-                        false /*clearing*/);
-
-                // ask the current client that it needs to send info
-                try {
-                    mCurrentRcClient.onInformationRequested(mCurrentRcClientGen,
-                            flags, mArtworkExpectedWidth, mArtworkExpectedHeight);
-                } catch (RemoteException e) {
-                    Log.e(TAG, "Current valid remote client is dead: "+e);
-                    mCurrentRcClient = null;
+                    // ask the current client that it needs to send info
+                    try {
+                        mCurrentRcClient.onInformationRequested(mCurrentRcClientGen,
+                                flags, mArtworkExpectedWidth, mArtworkExpectedHeight);
+                    } catch (RemoteException e) {
+                        Log.e(TAG, "Current valid remote client is dead: "+e);
+                        mCurrentRcClient = null;
+                    }
+                } else {
+                    // the remote control display owner has changed between the
+                    // the message to update the display was sent, and the time it
+                    // gets to be processed (now)
                 }
-            } else {
-                // the remote control display owner has changed between the
-                // the message to update the display was sent, and the time it
-                // gets to be processed (now)
             }
         }
     }