Merge "AudioManager: add previous AudioPort list" into mnc-dev
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 19900d0..56f0400 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -3402,7 +3402,17 @@
      * @hide
      */
     public static int listAudioPorts(ArrayList<AudioPort> ports) {
-        return updateAudioPortCache(ports, null);
+        return updateAudioPortCache(ports, null, null);
+    }
+
+    /**
+     * Returns a list of descriptors for all audio ports managed by the audio framework as
+     * it was before the last update calback.
+     * @param ports An AudioPort ArrayList where the list will be returned.
+     * @hide
+     */
+    public static int listPreviousAudioPorts(ArrayList<AudioPort> ports) {
+        return updateAudioPortCache(null, null, ports);
     }
 
     /**
@@ -3411,20 +3421,45 @@
      * @hide
      */
     public static int listAudioDevicePorts(ArrayList<AudioDevicePort> devices) {
+        if (devices == null) {
+            return ERROR_BAD_VALUE;
+        }
         ArrayList<AudioPort> ports = new ArrayList<AudioPort>();
-        int status = updateAudioPortCache(ports, null);
+        int status = updateAudioPortCache(ports, null, null);
         if (status == SUCCESS) {
-            devices.clear();
-            for (int i = 0; i < ports.size(); i++) {
-                if (ports.get(i) instanceof AudioDevicePort) {
-                    devices.add((AudioDevicePort)ports.get(i));
-                }
-            }
+            filterDevicePorts(ports, devices);
         }
         return status;
     }
 
     /**
+     * Specialized version of listPreviousAudioPorts() listing only audio devices (AudioDevicePort)
+     * @see listPreviousAudioPorts(ArrayList<AudioPort>)
+     * @hide
+     */
+    public static int listPreviousAudioDevicePorts(ArrayList<AudioDevicePort> devices) {
+        if (devices == null) {
+            return ERROR_BAD_VALUE;
+        }
+        ArrayList<AudioPort> ports = new ArrayList<AudioPort>();
+        int status = updateAudioPortCache(null, null, ports);
+        if (status == SUCCESS) {
+            filterDevicePorts(ports, devices);
+        }
+        return status;
+    }
+
+    private static void filterDevicePorts(ArrayList<AudioPort> ports,
+                                          ArrayList<AudioDevicePort> devices) {
+        devices.clear();
+        for (int i = 0; i < ports.size(); i++) {
+            if (ports.get(i) instanceof AudioDevicePort) {
+                devices.add((AudioDevicePort)ports.get(i));
+            }
+        }
+    }
+
+    /**
      * Create a connection between two or more devices. The framework will reject the request if
      * device types are not compatible or the implementation does not support the requested
      * configuration.
@@ -3474,7 +3509,7 @@
      * @hide
      */
     public static int listAudioPatches(ArrayList<AudioPatch> patches) {
-        return updateAudioPortCache(null, patches);
+        return updateAudioPortCache(null, patches, null);
     }
 
     /**
@@ -3540,6 +3575,7 @@
     static final int AUDIOPORT_GENERATION_INIT = 0;
     static Integer sAudioPortGeneration = new Integer(AUDIOPORT_GENERATION_INIT);
     static ArrayList<AudioPort> sAudioPortsCached = new ArrayList<AudioPort>();
+    static ArrayList<AudioPort> sPreviousAudioPortsCached = new ArrayList<AudioPort>();
     static ArrayList<AudioPatch> sAudioPatchesCached = new ArrayList<AudioPatch>();
 
     static int resetAudioPortGeneration() {
@@ -3551,7 +3587,8 @@
         return generation;
     }
 
-    static int updateAudioPortCache(ArrayList<AudioPort> ports, ArrayList<AudioPatch> patches) {
+    static int updateAudioPortCache(ArrayList<AudioPort> ports, ArrayList<AudioPatch> patches,
+                                    ArrayList<AudioPort> previousPorts) {
         synchronized (sAudioPortGeneration) {
 
             if (sAudioPortGeneration == AUDIOPORT_GENERATION_INIT) {
@@ -3610,6 +3647,7 @@
                     }
                 }
 
+                sPreviousAudioPortsCached = sAudioPortsCached;
                 sAudioPortsCached = newPorts;
                 sAudioPatchesCached = newPatches;
                 sAudioPortGeneration = portGeneration[0];
@@ -3622,6 +3660,10 @@
                 patches.clear();
                 patches.addAll(sAudioPatchesCached);
             }
+            if (previousPorts != null) {
+                previousPorts.clear();
+                previousPorts.addAll(sPreviousAudioPortsCached);
+            }
         }
         return SUCCESS;
     }
diff --git a/media/java/android/media/AudioPortEventHandler.java b/media/java/android/media/AudioPortEventHandler.java
index c49e8c2..c152245 100644
--- a/media/java/android/media/AudioPortEventHandler.java
+++ b/media/java/android/media/AudioPortEventHandler.java
@@ -84,7 +84,7 @@
                         ArrayList<AudioPort> ports = new ArrayList<AudioPort>();
                         ArrayList<AudioPatch> patches = new ArrayList<AudioPatch>();
                         if (msg.what != AUDIOPORT_EVENT_SERVICE_DIED) {
-                            int status = AudioManager.updateAudioPortCache(ports, patches);
+                            int status = AudioManager.updateAudioPortCache(ports, patches, null);
                             if (status != AudioManager.SUCCESS) {
                                 return;
                             }