Audio Effects: added methods to effects java classes to store and load current effect settings in
a single call.

Addional changes:
- Fixed simulator build
- Use effect interface UUIDs from OpenSL ES includes when available
- Added cleanspec rules to remove now obsolete test effect libraries
- Fixed bug in AudioEffect JNI setParameter function.

Change-Id: Ic25ddb135e2cec5a68c181d727321f5ac7a1ab6b
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 26d8a1b..1efe77c 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -54,7 +54,19 @@
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/android.policy*)
 $(call add-clean-step, rm -rf $(TARGET_OUT_JAVA_LIBRARIES)/android.policy.jar)
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates)
-
+$(call add-clean-step, rm -f $(PRODUCT_OUT)/obj/lib/libequalizer.so)
+$(call add-clean-step, rm -f $(PRODUCT_OUT)/obj/lib/libequalizertest.so)
+$(call add-clean-step, rm -f $(PRODUCT_OUT)/obj/lib/libreverb.so)
+$(call add-clean-step, rm -f $(PRODUCT_OUT)/obj/lib/libreverbtest.so)
+$(call add-clean-step, rm -f $(PRODUCT_OUT)/symbols/system/lib/libequalizer.so)
+$(call add-clean-step, rm -f $(PRODUCT_OUT)/symbols/system/lib/libequalizertest.so)
+$(call add-clean-step, rm -f $(PRODUCT_OUT)/symbols/system/lib/libreverb.so)
+$(call add-clean-step, rm -f $(PRODUCT_OUT)/symbols/system/lib/libreverbtest.so)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libequalizer_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libequalizertest_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libreverb_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libreverbtest_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/soundfx/)
 
 # ************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
diff --git a/include/media/EffectBassBoostApi.h b/include/media/EffectBassBoostApi.h
index b24a5f4..75f8d78 100644
--- a/include/media/EffectBassBoostApi.h
+++ b/include/media/EffectBassBoostApi.h
@@ -23,9 +23,10 @@
 extern "C" {
 #endif
 
-// TODO: include OpenSLES_IID.h instead
+#ifndef OPENSL_ES_H_
 static const effect_uuid_t SL_IID_BASSBOOST_ = { 0x0634f220, 0xddd4, 0x11db, 0xa0fc, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } };
 const effect_uuid_t * const SL_IID_BASSBOOST = &SL_IID_BASSBOOST_;
+#endif //OPENSL_ES_H_
 
 /* enumerated parameter settings for BassBoost effect */
 typedef enum
diff --git a/include/media/EffectEnvironmentalReverbApi.h b/include/media/EffectEnvironmentalReverbApi.h
index d490f71..2233e3f 100644
--- a/include/media/EffectEnvironmentalReverbApi.h
+++ b/include/media/EffectEnvironmentalReverbApi.h
@@ -23,9 +23,10 @@
 extern "C" {
 #endif
 
-// TODO: include OpenSLES_IID.h instead
+#ifndef OPENSL_ES_H_
 static const effect_uuid_t SL_IID_ENVIRONMENTALREVERB_ = { 0xc2e5d5f0, 0x94bd, 0x4763, 0x9cac, { 0x4e, 0x23, 0x4d, 0x6, 0x83, 0x9e } };
 const effect_uuid_t * const SL_IID_ENVIRONMENTALREVERB = &SL_IID_ENVIRONMENTALREVERB_;
+#endif //OPENSL_ES_H_
 
 /* enumerated parameter settings for environmental reverb effect */
 typedef enum
@@ -45,20 +46,19 @@
     REVERB_PARAM_BYPASS
 } t_env_reverb_params;
 
-//t_reverb_properties is equal to SLEnvironmentalReverbSettings defined in OpenSL ES specification.
-typedef struct s_reverb_properties {
+//t_reverb_settings is equal to SLEnvironmentalReverbSettings defined in OpenSL ES specification.
+typedef struct s_reverb_settings {
     int16_t roomLevel;
     int16_t roomHFLevel;
     int32_t decayTime;
     int16_t decayHFRatio;
     int16_t reflectionsLevel;
     int32_t reflectionsDelay;
-    int32_t reverbDelay;
     int16_t reverbLevel;
+    int32_t reverbDelay;
     int16_t diffusion;
     int16_t density;
-    int16_t padding;
-} t_reverb_properties;
+} __attribute__((packed)) t_reverb_settings;
 
 
 #if __cplusplus
diff --git a/include/media/EffectEqualizerApi.h b/include/media/EffectEqualizerApi.h
index cb05b32..0492ea0 100644
--- a/include/media/EffectEqualizerApi.h
+++ b/include/media/EffectEqualizerApi.h
@@ -19,8 +19,10 @@
 
 #include <media/EffectApi.h>
 
-// for the definition of SL_IID_EQUALIZER
-#include "OpenSLES.h"
+#ifndef OPENSL_ES_H_
+static const effect_uuid_t SL_IID_EQUALIZER_ = { 0x0bed4300, 0xddd6, 0x11db, 0x8f34, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } };
+const effect_uuid_t * const SL_IID_EQUALIZER = &SL_IID_EQUALIZER_;
+#endif //OPENSL_ES_H_
 
 #if __cplusplus
 extern "C" {
@@ -37,9 +39,16 @@
     EQ_PARAM_GET_BAND,              // Gets the band that has the most effect on the given frequency.
     EQ_PARAM_CUR_PRESET,            // Gets/Sets the current preset.
     EQ_PARAM_GET_NUM_OF_PRESETS,    // Gets the total number of presets the equalizer supports.
-    EQ_PARAM_GET_PRESET_NAME        // Gets the preset name based on the index.
+    EQ_PARAM_GET_PRESET_NAME,       // Gets the preset name based on the index.
+    EQ_PARAM_PROPERTIES             // Gets/Sets all parameters at a time.
 } t_equalizer_params;
 
+//t_equalizer_settings groups all current equalizer setting for backup and restore.
+typedef struct s_equalizer_settings {
+    uint16_t curPreset;
+    uint16_t numBands;
+    uint16_t bandLevels[];
+} t_equalizer_settings;
 
 #if __cplusplus
 }  // extern "C"
diff --git a/include/media/EffectPresetReverbApi.h b/include/media/EffectPresetReverbApi.h
index 34ffffe..53205bb 100644
--- a/include/media/EffectPresetReverbApi.h
+++ b/include/media/EffectPresetReverbApi.h
@@ -23,10 +23,10 @@
 extern "C" {
 #endif
 
-// TODO: include OpenSLES_IID.h instead
-
+#ifndef OPENSL_ES_H_
 static const effect_uuid_t SL_IID_PRESETREVERB_ = { 0x47382d60, 0xddd8, 0x11db, 0xbf3a, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } };
 const effect_uuid_t * const SL_IID_PRESETREVERB = &SL_IID_PRESETREVERB_;
+#endif //OPENSL_ES_H_
 
 /* enumerated parameter settings for preset reverb effect */
 typedef enum
diff --git a/include/media/EffectVirtualizerApi.h b/include/media/EffectVirtualizerApi.h
index 601c384..c3d5131 100644
--- a/include/media/EffectVirtualizerApi.h
+++ b/include/media/EffectVirtualizerApi.h
@@ -23,9 +23,10 @@
 extern "C" {
 #endif
 
-// TODO: include OpenSLES_IID.h instead
+#ifndef OPENSL_ES_H_
 static const effect_uuid_t SL_IID_VIRTUALIZER_ = { 0x37cc2c00, 0xdddd, 0x11db, 0x8577, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } };
 const effect_uuid_t * const SL_IID_VIRTUALIZER = &SL_IID_VIRTUALIZER_;
+#endif //OPENSL_ES_H_
 
 /* enumerated parameter settings for virtualizer effect */
 typedef enum
diff --git a/include/media/EffectVisualizerApi.h b/include/media/EffectVisualizerApi.h
index 1155db8..bef1a4f 100644
--- a/include/media/EffectVisualizerApi.h
+++ b/include/media/EffectVisualizerApi.h
@@ -23,10 +23,11 @@
 extern "C" {
 #endif
 
-//TODO replace by openSL ES include when available
+#ifndef OPENSL_ES_H_
 static const effect_uuid_t SL_IID_VISUALIZATION_ =
     { 0xe46b26a0, 0xdddd, 0x11db, 0x8afd, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } };
 const effect_uuid_t * const SL_IID_VISUALIZATION = &SL_IID_VISUALIZATION_;
+#endif //OPENSL_ES_H_
 
 #define VISUALIZER_CAPTURE_SIZE_MAX 1024  // maximum capture size in samples
 #define VISUALIZER_CAPTURE_SIZE_MIN 128   // minimum capture size in samples
diff --git a/media/java/android/media/BassBoost.java b/media/java/android/media/BassBoost.java
index ef4ce05..75c2c88 100644
--- a/media/java/android/media/BassBoost.java
+++ b/media/java/android/media/BassBoost.java
@@ -19,17 +19,19 @@
 import android.app.Activity;
 import android.content.Context;
 import android.content.Intent;
+import android.media.AudioEffect;
 import android.os.Bundle;
 import android.util.Log;
+
 import java.nio.ByteOrder;
 import java.nio.ByteBuffer;
 import java.nio.CharBuffer;
+import java.util.StringTokenizer;
 
-import android.media.AudioEffect;
 
 /**
  * Bass boost is an audio effect to boost or amplify low frequencies of the sound. It is comparable
- * to an simple equalizer but limited to one band amplification in the low frequency range.
+ * to a simple equalizer but limited to one band amplification in the low frequency range.
  * <p>An application creates a BassBoost object to instantiate and control a bass boost engine
  * in the audio framework.
  * <p>The methods, parameter types and units exposed by the BassBoost implementation are directly
@@ -210,4 +212,82 @@
             }
         }
     }
+
+    /**
+     * The Settings class regroups all bass boost parameters. It is used in
+     * conjuntion with getProperties() and setProperties() methods to backup and restore
+     * all parameters in a single call.
+     */
+    public static class Settings {
+        public short strength;
+
+        public Settings() {
+        }
+
+        /**
+         * Settings class constructor from a key=value; pairs formatted string. The string is
+         * typically returned by Settings.toString() method.
+         * @throws IllegalArgumentException if the string is not correctly formatted.
+         */
+        public Settings(String settings) {
+            StringTokenizer st = new StringTokenizer(settings, "=;");
+            int tokens = st.countTokens();
+            if (st.countTokens() != 3) {
+                throw new IllegalArgumentException("settings: " + settings);
+            }
+            String key = st.nextToken();
+            if (!key.equals("BassBoost")) {
+                throw new IllegalArgumentException(
+                        "invalid settings for BassBoost: " + key);
+            }
+            try {
+                key = st.nextToken();
+                if (!key.equals("strength")) {
+                    throw new IllegalArgumentException("invalid key name: " + key);
+                }
+                strength = Short.parseShort(st.nextToken());
+             } catch (NumberFormatException nfe) {
+                throw new IllegalArgumentException("invalid value for key: " + key);
+            }
+        }
+
+        @Override
+        public String toString() {
+            String str = new String (
+                    "BassBoost"+
+                    ";strength="+Short.toString(strength)
+                    );
+            return str;
+        }
+    };
+
+
+    /**
+     * Gets the bass boost properties. This method is useful when a snapshot of current
+     * bass boost settings must be saved by the application.
+     * @return a BassBoost.Settings object containing all current parameters values
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public BassBoost.Settings getProperties()
+    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        Settings settings = new Settings();
+        short[] value = new short[1];
+        checkStatus(getParameter(PARAM_STRENGTH, value));
+        settings.strength = value[0];
+        return settings;
+    }
+
+    /**
+     * Sets the bass boost properties. This method is useful when bass boost settings have to
+     * be applied from a previous backup.
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public void setProperties(BassBoost.Settings settings)
+    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        checkStatus(setParameter(PARAM_STRENGTH, settings.strength));
+    }
 }
diff --git a/media/java/android/media/EnvironmentalReverb.java b/media/java/android/media/EnvironmentalReverb.java
index 88230fc..3cc8452 100644
--- a/media/java/android/media/EnvironmentalReverb.java
+++ b/media/java/android/media/EnvironmentalReverb.java
@@ -19,12 +19,13 @@
 import android.app.Activity;
 import android.content.Context;
 import android.content.Intent;
+import android.media.AudioEffect;
 import android.os.Bundle;
 import android.util.Log;
+
 import java.nio.ByteOrder;
 import java.nio.ByteBuffer;
-
-import android.media.AudioEffect;
+import java.util.StringTokenizer;
 
 /**
  * A sound generated within a room travels in many directions. The listener first hears the
@@ -107,6 +108,9 @@
      */
     public static final int PARAM_DENSITY = 9;
 
+    // used by setProperties()/getProperties
+    private static final int PARAM_PROPERTIES = 10;
+
     /**
      * Registered listener for parameter changes
      */
@@ -142,7 +146,6 @@
     public EnvironmentalReverb(int priority, int audioSession)
     throws IllegalArgumentException, UnsupportedOperationException, RuntimeException {
         super(EFFECT_TYPE_ENV_REVERB, EFFECT_TYPE_NULL, priority, audioSession);
-        Log.e(TAG, "contructor");
     }
 
     /**
@@ -501,4 +504,169 @@
             }
         }
     }
+
+    /**
+     * The Settings class regroups all environmental reverb parameters. It is used in
+     * conjuntion with getProperties() and setProperties() methods to backup and restore
+     * all parameters in a single call.
+     */
+    public static class Settings {
+        public short roomLevel;
+        public short roomHFLevel;
+        public int decayTime;
+        public short decayHFRatio;
+        public short reflectionsLevel;
+        public int reflectionsDelay;
+        public short reverbLevel;
+        public int reverbDelay;
+        public short diffusion;
+        public short density;
+
+        public Settings() {
+        }
+
+        /**
+         * Settings class constructor from a key=value; pairs formatted string. The string is
+         * typically returned by Settings.toString() method.
+         * @throws IllegalArgumentException if the string is not correctly formatted.
+         */
+        public Settings(String settings) {
+            StringTokenizer st = new StringTokenizer(settings, "=;");
+            int tokens = st.countTokens();
+            if (st.countTokens() != 21) {
+                throw new IllegalArgumentException("settings: " + settings);
+            }
+            String key = st.nextToken();
+            if (!key.equals("EnvironmentalReverb")) {
+                throw new IllegalArgumentException(
+                        "invalid settings for EnvironmentalReverb: " + key);
+            }
+
+            try {
+                key = st.nextToken();
+                if (!key.equals("roomLevel")) {
+                    throw new IllegalArgumentException("invalid key name: " + key);
+                }
+                roomLevel = Short.parseShort(st.nextToken());
+                key = st.nextToken();
+                if (!key.equals("roomHFLevel")) {
+                    throw new IllegalArgumentException("invalid key name: " + key);
+                }
+                roomHFLevel = Short.parseShort(st.nextToken());
+                key = st.nextToken();
+                if (!key.equals("decayTime")) {
+                    throw new IllegalArgumentException("invalid key name: " + key);
+                }
+                decayTime = Integer.parseInt(st.nextToken());
+                key = st.nextToken();
+                if (!key.equals("decayHFRatio")) {
+                    throw new IllegalArgumentException("invalid key name: " + key);
+                }
+                decayHFRatio = Short.parseShort(st.nextToken());
+                key = st.nextToken();
+                if (!key.equals("reflectionsLevel")) {
+                    throw new IllegalArgumentException("invalid key name: " + key);
+                }
+                reflectionsLevel = Short.parseShort(st.nextToken());
+                key = st.nextToken();
+                if (!key.equals("reflectionsDelay")) {
+                    throw new IllegalArgumentException("invalid key name: " + key);
+                }
+                reflectionsDelay = Integer.parseInt(st.nextToken());
+                key = st.nextToken();
+                if (!key.equals("reverbLevel")) {
+                    throw new IllegalArgumentException("invalid key name: " + key);
+                }
+                reverbLevel = Short.parseShort(st.nextToken());
+                key = st.nextToken();
+                if (!key.equals("reverbDelay")) {
+                    throw new IllegalArgumentException("invalid key name: " + key);
+                }
+                reverbDelay = Integer.parseInt(st.nextToken());
+                key = st.nextToken();
+                if (!key.equals("diffusion")) {
+                    throw new IllegalArgumentException("invalid key name: " + key);
+                }
+                diffusion = Short.parseShort(st.nextToken());
+                key = st.nextToken();
+                if (!key.equals("density")) {
+                    throw new IllegalArgumentException("invalid key name: " + key);
+                }
+                density = Short.parseShort(st.nextToken());
+             } catch (NumberFormatException nfe) {
+                throw new IllegalArgumentException("invalid value for key: " + key);
+            }
+        }
+
+        @Override
+        public String toString() {
+            return new String (
+                    "EnvironmentalReverb"+
+                    ";roomLevel="+Short.toString(roomLevel)+
+                    ";roomHFLevel="+Short.toString(roomHFLevel)+
+                    ";decayTime="+Integer.toString(decayTime)+
+                    ";decayHFRatio="+Short.toString(decayHFRatio)+
+                    ";reflectionsLevel="+Short.toString(reflectionsLevel)+
+                    ";reflectionsDelay="+Integer.toString(reflectionsDelay)+
+                    ";reverbLevel="+Short.toString(reverbLevel)+
+                    ";reverbDelay="+Integer.toString(reverbDelay)+
+                    ";diffusion="+Short.toString(diffusion)+
+                    ";density="+Short.toString(density)
+                    );
+        }
+    };
+
+    // Keep this in sync with sizeof(s_reverb_settings) defined in
+    // frameworks/base/include/media/EffectEnvironmentalReverbApi.h
+    static private int PROPERTY_SIZE = 26;
+
+    /**
+     * Gets the environmental reverb properties. This method is useful when a snapshot of current
+     * reverb settings must be saved by the application.
+     * @return an EnvironmentalReverb.Settings object containing all current parameters values
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public EnvironmentalReverb.Settings getProperties()
+    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        byte[] param = new byte[PROPERTY_SIZE];
+        checkStatus(getParameter(PARAM_PROPERTIES, param));
+        Settings settings = new Settings();
+        settings.roomLevel = byteArrayToShort(param, 0);
+        settings.roomHFLevel = byteArrayToShort(param, 2);
+        settings.decayTime = byteArrayToInt(param, 4);
+        settings.decayHFRatio = byteArrayToShort(param, 8);
+        settings.reflectionsLevel = byteArrayToShort(param, 10);
+        settings.reflectionsDelay = byteArrayToInt(param, 12);
+        settings.reverbLevel = byteArrayToShort(param, 16);
+        settings.reverbDelay = byteArrayToInt(param, 18);
+        settings.diffusion = byteArrayToShort(param, 22);
+        settings.density = byteArrayToShort(param, 24);
+        return settings;
+    }
+
+    /**
+     * Sets the environmental reverb properties. This method is useful when reverb settings have to
+     * be applied from a previous backup.
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public void setProperties(EnvironmentalReverb.Settings settings)
+    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+
+        byte[] param = concatArrays(shortToByteArray(settings.roomLevel),
+                                    shortToByteArray(settings.roomHFLevel),
+                                    intToByteArray(settings.decayTime),
+                                    shortToByteArray(settings.decayHFRatio),
+                                    shortToByteArray(settings.reflectionsLevel),
+                                    intToByteArray(settings.reflectionsDelay),
+                                    shortToByteArray(settings.reverbLevel),
+                                    intToByteArray(settings.reverbDelay),
+                                    shortToByteArray(settings.diffusion),
+                                    shortToByteArray(settings.density));
+
+        checkStatus(setParameter(PARAM_PROPERTIES, param));
+    }
 }
diff --git a/media/java/android/media/Equalizer.java b/media/java/android/media/Equalizer.java
index 082f694..21c37bb 100644
--- a/media/java/android/media/Equalizer.java
+++ b/media/java/android/media/Equalizer.java
@@ -19,13 +19,15 @@
 import android.app.Activity;
 import android.content.Context;
 import android.content.Intent;
+import android.media.AudioEffect;
 import android.os.Bundle;
 import android.util.Log;
+
 import java.nio.ByteOrder;
 import java.nio.ByteBuffer;
 import java.nio.CharBuffer;
+import java.util.StringTokenizer;
 
-import android.media.AudioEffect;
 
 /**
  * An Equalizer is used to alter the frequency response of a particular music source or of the main
@@ -87,12 +89,19 @@
      * Request preset name. Parameter ID for OnParameterChangeListener
      */
     public static final int PARAM_GET_PRESET_NAME = 8;
+    // used by setProperties()/getProperties
+    private static final int PARAM_PROPERTIES = 9;
     /**
      * maximum size for perset name
      */
     public static final int PARAM_STRING_SIZE_MAX = 32;
 
     /**
+     * Number of bands implemented by Equalizer engine
+     */
+    private short mNumBands = 0;
+
+    /**
      * Number of presets implemented by Equalizer engine
      */
     private int mNumPresets;
@@ -136,6 +145,8 @@
            UnsupportedOperationException, RuntimeException {
         super(EFFECT_TYPE_EQUALIZER, EFFECT_TYPE_NULL, priority, audioSession);
 
+        getNumberOfBands();
+
         mNumPresets = (int)getNumberOfPresets();
 
         if (mNumPresets != 0) {
@@ -150,7 +161,6 @@
                 while (value[length] != 0) length++;
                 try {
                     mPresetNames[i] = new String(value, 0, length, "ISO-8859-1");
-                    Log.e(TAG, "preset #: "+i+" name: "+mPresetNames[i]+" length: "+length);
                 } catch (java.io.UnsupportedEncodingException e) {
                     Log.e(TAG, "preset name decode error");
                 }
@@ -167,11 +177,15 @@
      */
     public short getNumberOfBands()
     throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        if (mNumBands != 0) {
+            return mNumBands;
+        }
         int[] param = new int[1];
         param[0] = PARAM_NUM_BANDS;
         short[] value = new short[1];
         checkStatus(getParameter(param, value));
-        return value[0];
+        mNumBands = value[0];
+        return mNumBands;
     }
 
     /**
@@ -440,4 +454,120 @@
         }
     }
 
+    /**
+     * The Settings class regroups all equalizer parameters. It is used in
+     * conjuntion with getProperties() and setProperties() methods to backup and restore
+     * all parameters in a single call.
+     */
+    public static class Settings {
+        public short curPreset;
+        public short numBands = 0;
+        public short[] bandLevels = null;
+
+        public Settings() {
+        }
+
+        /**
+         * Settings class constructor from a key=value; pairs formatted string. The string is
+         * typically returned by Settings.toString() method.
+         * @throws IllegalArgumentException if the string is not correctly formatted.
+         */
+        public Settings(String settings) {
+            StringTokenizer st = new StringTokenizer(settings, "=;");
+            int tokens = st.countTokens();
+            if (st.countTokens() < 5) {
+                throw new IllegalArgumentException("settings: " + settings);
+            }
+            String key = st.nextToken();
+            if (!key.equals("Equalizer")) {
+                throw new IllegalArgumentException(
+                        "invalid settings for Equalizer: " + key);
+            }
+            try {
+                key = st.nextToken();
+                if (!key.equals("curPreset")) {
+                    throw new IllegalArgumentException("invalid key name: " + key);
+                }
+                curPreset = Short.parseShort(st.nextToken());
+                key = st.nextToken();
+                if (!key.equals("numBands")) {
+                    throw new IllegalArgumentException("invalid key name: " + key);
+                }
+                numBands = Short.parseShort(st.nextToken());
+                if (st.countTokens() != numBands*2) {
+                    throw new IllegalArgumentException("settings: " + settings);
+                }
+                bandLevels = new short[numBands];
+                for (int i = 0; i < numBands; i++) {
+                    key = st.nextToken();
+                    if (!key.equals("band"+(i+1)+"Level")) {
+                        throw new IllegalArgumentException("invalid key name: " + key);
+                    }
+                    bandLevels[i] = Short.parseShort(st.nextToken());
+                }
+             } catch (NumberFormatException nfe) {
+                throw new IllegalArgumentException("invalid value for key: " + key);
+            }
+        }
+
+        @Override
+        public String toString() {
+
+            String str = new String (
+                    "Equalizer"+
+                    ";curPreset="+Short.toString(curPreset)+
+                    ";numBands="+Short.toString(numBands)
+                    );
+            for (int i = 0; i < numBands; i++) {
+                str = str.concat(";band"+(i+1)+"Level="+Short.toString(bandLevels[i]));
+            }
+            return str;
+        }
+    };
+
+
+    /**
+     * Gets the equalizer properties. This method is useful when a snapshot of current
+     * equalizer settings must be saved by the application.
+     * @return an Equalizer.Settings object containing all current parameters values
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public Equalizer.Settings getProperties()
+    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        byte[] param = new byte[4 + mNumBands * 2];
+        checkStatus(getParameter(PARAM_PROPERTIES, param));
+        Settings settings = new Settings();
+        settings.curPreset = byteArrayToShort(param, 0);
+        settings.numBands = byteArrayToShort(param, 2);
+        settings.bandLevels = new short[mNumBands];
+        for (int i = 0; i < mNumBands; i++) {
+            settings.bandLevels[i] = byteArrayToShort(param, 4 + 2*i);
+        }
+        return settings;
+    }
+
+    /**
+     * Sets the equalizer properties. This method is useful when equalizer settings have to
+     * be applied from a previous backup.
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public void setProperties(Equalizer.Settings settings)
+    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        if (settings.numBands != settings.bandLevels.length ||
+            settings.numBands != mNumBands) {
+            throw new IllegalArgumentException("settings invalid band count: " +settings.numBands);
+        }
+
+        byte[] param = concatArrays(shortToByteArray(settings.curPreset),
+                                    shortToByteArray(mNumBands));
+        for (int i = 0; i < mNumBands; i++) {
+            param = concatArrays(param,
+                                 shortToByteArray(settings.bandLevels[i]));
+        }
+        checkStatus(setParameter(PARAM_PROPERTIES, param));
+    }
 }
diff --git a/media/java/android/media/PresetReverb.java b/media/java/android/media/PresetReverb.java
index 83a01a4..c7d7037 100644
--- a/media/java/android/media/PresetReverb.java
+++ b/media/java/android/media/PresetReverb.java
@@ -19,12 +19,14 @@
 import android.app.Activity;
 import android.content.Context;
 import android.content.Intent;
+import android.media.AudioEffect;
 import android.os.Bundle;
 import android.util.Log;
+
 import java.nio.ByteOrder;
 import java.nio.ByteBuffer;
+import java.util.StringTokenizer;
 
-import android.media.AudioEffect;
 
 /**
  * A sound generated within a room travels in many directions. The listener first hears the
@@ -116,7 +118,6 @@
     public PresetReverb(int priority, int audioSession)
     throws IllegalArgumentException, UnsupportedOperationException, RuntimeException {
         super(EFFECT_TYPE_PRESET_REVERB, EFFECT_TYPE_NULL, priority, audioSession);
-        Log.e(TAG, "contructor");
     }
 
     /**
@@ -144,10 +145,8 @@
      */
     public short getPreset()
     throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
-        int[] param = new int[1];
-        param[0] = PARAM_PRESET;
         short[] value = new short[1];
-        checkStatus(getParameter(param, value));
+        checkStatus(getParameter(PARAM_PRESET, value));
         return value[0];
     }
 
@@ -216,4 +215,82 @@
             }
         }
     }
+
+    /**
+     * The Settings class regroups all preset reverb parameters. It is used in
+     * conjuntion with getProperties() and setProperties() methods to backup and restore
+     * all parameters in a single call.
+     */
+    public static class Settings {
+        public short preset;
+
+        public Settings() {
+        }
+
+        /**
+         * Settings class constructor from a key=value; pairs formatted string. The string is
+         * typically returned by Settings.toString() method.
+         * @throws IllegalArgumentException if the string is not correctly formatted.
+         */
+        public Settings(String settings) {
+            StringTokenizer st = new StringTokenizer(settings, "=;");
+            int tokens = st.countTokens();
+            if (st.countTokens() != 3) {
+                throw new IllegalArgumentException("settings: " + settings);
+            }
+            String key = st.nextToken();
+            if (!key.equals("PresetReverb")) {
+                throw new IllegalArgumentException(
+                        "invalid settings for PresetReverb: " + key);
+            }
+            try {
+                key = st.nextToken();
+                if (!key.equals("preset")) {
+                    throw new IllegalArgumentException("invalid key name: " + key);
+                }
+                preset = Short.parseShort(st.nextToken());
+             } catch (NumberFormatException nfe) {
+                throw new IllegalArgumentException("invalid value for key: " + key);
+            }
+        }
+
+        @Override
+        public String toString() {
+            String str = new String (
+                    "PresetReverb"+
+                    ";preset="+Short.toString(preset)
+                    );
+            return str;
+        }
+    };
+
+
+    /**
+     * Gets the preset reverb properties. This method is useful when a snapshot of current
+     * preset reverb settings must be saved by the application.
+     * @return a PresetReverb.Settings object containing all current parameters values
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public PresetReverb.Settings getProperties()
+    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        Settings settings = new Settings();
+        short[] value = new short[1];
+        checkStatus(getParameter(PARAM_PRESET, value));
+        settings.preset = value[0];
+        return settings;
+    }
+
+    /**
+     * Sets the preset reverb properties. This method is useful when preset reverb settings have to
+     * be applied from a previous backup.
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public void setProperties(PresetReverb.Settings settings)
+    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        checkStatus(setParameter(PARAM_PRESET, settings.preset));
+    }
 }
diff --git a/media/java/android/media/Virtualizer.java b/media/java/android/media/Virtualizer.java
index 9f71297..2c8909e 100644
--- a/media/java/android/media/Virtualizer.java
+++ b/media/java/android/media/Virtualizer.java
@@ -19,13 +19,15 @@
 import android.app.Activity;
 import android.content.Context;
 import android.content.Intent;
+import android.media.AudioEffect;
 import android.os.Bundle;
 import android.util.Log;
+
 import java.nio.ByteOrder;
 import java.nio.ByteBuffer;
 import java.nio.CharBuffer;
+import java.util.StringTokenizer;
 
-import android.media.AudioEffect;
 
 /**
  * An audio virtualizer is a general name for an effect to spatialize audio channels. The exact
@@ -211,4 +213,82 @@
             }
         }
     }
+
+    /**
+     * The Settings class regroups all virtualizer parameters. It is used in
+     * conjuntion with getProperties() and setProperties() methods to backup and restore
+     * all parameters in a single call.
+     */
+    public static class Settings {
+        public short strength;
+
+        public Settings() {
+        }
+
+        /**
+         * Settings class constructor from a key=value; pairs formatted string. The string is
+         * typically returned by Settings.toString() method.
+         * @throws IllegalArgumentException if the string is not correctly formatted.
+         */
+        public Settings(String settings) {
+            StringTokenizer st = new StringTokenizer(settings, "=;");
+            int tokens = st.countTokens();
+            if (st.countTokens() != 3) {
+                throw new IllegalArgumentException("settings: " + settings);
+            }
+            String key = st.nextToken();
+            if (!key.equals("Virtualizer")) {
+                throw new IllegalArgumentException(
+                        "invalid settings for Virtualizer: " + key);
+            }
+            try {
+                key = st.nextToken();
+                if (!key.equals("strength")) {
+                    throw new IllegalArgumentException("invalid key name: " + key);
+                }
+                strength = Short.parseShort(st.nextToken());
+             } catch (NumberFormatException nfe) {
+                throw new IllegalArgumentException("invalid value for key: " + key);
+            }
+        }
+
+        @Override
+        public String toString() {
+            String str = new String (
+                    "Virtualizer"+
+                    ";strength="+Short.toString(strength)
+                    );
+            return str;
+        }
+    };
+
+
+    /**
+     * Gets the virtualizer properties. This method is useful when a snapshot of current
+     * virtualizer settings must be saved by the application.
+     * @return a Virtualizer.Settings object containing all current parameters values
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public Virtualizer.Settings getProperties()
+    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        Settings settings = new Settings();
+        short[] value = new short[1];
+        checkStatus(getParameter(PARAM_STRENGTH, value));
+        settings.strength = value[0];
+        return settings;
+    }
+
+    /**
+     * Sets the virtualizer properties. This method is useful when virtualizer settings have to
+     * be applied from a previous backup.
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public void setProperties(Virtualizer.Settings settings)
+    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        checkStatus(setParameter(PARAM_STRENGTH, settings.strength));
+    }
 }
diff --git a/media/jni/audioeffect/android_media_AudioEffect.cpp b/media/jni/audioeffect/android_media_AudioEffect.cpp
index beb3dfc..e3b9e36 100644
--- a/media/jni/audioeffect/android_media_AudioEffect.cpp
+++ b/media/jni/audioeffect/android_media_AudioEffect.cpp
@@ -549,7 +549,7 @@
     p = (effect_param_t *) malloc(sizeof(effect_param_t) + voffset + vsize);
     memcpy(p->data, lpParam, psize);
     p->psize = psize;
-    memcpy(p->data + voffset, lpValue, psize);
+    memcpy(p->data + voffset, lpValue, vsize);
     p->vsize = vsize;
 
     lStatus = lpAudioEffect->setParameter(p);
diff --git a/media/libeffects/lvm/wrapper/Android.mk b/media/libeffects/lvm/wrapper/Android.mk
index 4ebc443..7855dcd 100644
--- a/media/libeffects/lvm/wrapper/Android.mk
+++ b/media/libeffects/lvm/wrapper/Android.mk
@@ -1,30 +1,36 @@
-LOCAL_PATH:= $(call my-dir)

-

-# music bundle wrapper

-LOCAL_PATH:= $(call my-dir)

-include $(CLEAR_VARS)

-

-LOCAL_ARM_MODE := arm

-

-LOCAL_SRC_FILES:= \

-	Bundle/EffectBundle.cpp

-

-LOCAL_MODULE:= libbundlewrapper

-

-LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/soundfx

-

-LOCAL_PRELINK_MODULE := false

-

-LOCAL_STATIC_LIBRARIES += libmusicbundle

-

-LOCAL_SHARED_LIBRARIES := \

-     libcutils \

-     libdl

-

-LOCAL_C_INCLUDES += \

-	$(LOCAL_PATH)/Bundle \

-	$(LOCAL_PATH)/../lib/Common/lib/ \

-	$(LOCAL_PATH)/../lib/Bundle/lib/

-

-

-include $(BUILD_SHARED_LIBRARY)

+LOCAL_PATH:= $(call my-dir)
+
+# music bundle wrapper
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_ARM_MODE := arm
+
+LOCAL_SRC_FILES:= \
+	Bundle/EffectBundle.cpp
+
+LOCAL_MODULE:= libbundlewrapper
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/soundfx
+
+LOCAL_PRELINK_MODULE := false
+
+LOCAL_STATIC_LIBRARIES += libmusicbundle
+
+LOCAL_SHARED_LIBRARIES := \
+     libcutils \
+
+ifeq ($(TARGET_SIMULATOR),true)
+LOCAL_LDLIBS += -ldl
+else
+LOCAL_SHARED_LIBRARIES += libdl
+endif
+
+
+LOCAL_C_INCLUDES += \
+	$(LOCAL_PATH)/Bundle \
+	$(LOCAL_PATH)/../lib/Common/lib/ \
+	$(LOCAL_PATH)/../lib/Bundle/lib/
+
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
index 5e91974..4440447 100644
--- a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
+++ b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
@@ -1625,7 +1625,7 @@
     //LOGV("\tBassBoost_getParameter start");
 
     switch (param){
-        case BASSBOOST_PARAM_STRENGTH_SUP:
+        case BASSBOOST_PARAM_STRENGTH_SUPPORTED:
         case BASSBOOST_PARAM_STRENGTH:
             if (*pValueSize != sizeof(int16_t)){
                 LOGV("\tLVM_ERROR : BassBoost_getParameter() invalid pValueSize2 %d", *pValueSize);
@@ -1640,10 +1640,10 @@
     }
 
     switch (param){
-        case BASSBOOST_PARAM_STRENGTH_SUP:
+        case BASSBOOST_PARAM_STRENGTH_SUPPORTED:
             *(uint32_t *)pValue = 1;
 
-            //LOGV("\tBassBoost_getParameter() BASSBOOST_PARAM_STRENGTH_SUP Value is %d",
+            //LOGV("\tBassBoost_getParameter() BASSBOOST_PARAM_STRENGTH_SUPPORTED Value is %d",
             //        *(uint32_t *)pValue);
             break;
 
@@ -1735,7 +1735,7 @@
     //LOGV("\tVirtualizer_getParameter start");
 
     switch (param){
-        case VIRTUALIZER_PARAM_STRENGTH_SUP:
+        case VIRTUALIZER_PARAM_STRENGTH_SUPPORTED:
         case VIRTUALIZER_PARAM_STRENGTH:
             if (*pValueSize != sizeof(int16_t)){
                 LOGV("\tLVM_ERROR : Virtualizer_getParameter() invalid pValueSize2 %d",*pValueSize);
@@ -1750,10 +1750,10 @@
     }
 
     switch (param){
-        case VIRTUALIZER_PARAM_STRENGTH_SUP:
+        case VIRTUALIZER_PARAM_STRENGTH_SUPPORTED:
             *(uint32_t *)pValue = 1;
 
-            //LOGV("\tVirtualizer_getParameter() VIRTUALIZER_PARAM_STRENGTH_SUP Value is %d",
+            //LOGV("\tVirtualizer_getParameter() VIRTUALIZER_PARAM_STRENGTH_SUPPORTED Value is %d",
             //        *(uint32_t *)pValue);
             break;
 
@@ -1876,6 +1876,14 @@
     case EQ_PARAM_GET_PRESET_NAME:
         break;
 
+    case EQ_PARAM_PROPERTIES:
+        if (*pValueSize < (2 + FIVEBAND_NUMBANDS) * sizeof(uint16_t)) {
+            LOGV("\tLVM_ERROR : Equalizer_getParameter() invalid pValueSize 1  %d", *pValueSize);
+            return -EINVAL;
+        }
+        *pValueSize = (2 + FIVEBAND_NUMBANDS) * sizeof(uint16_t);
+        break;
+
     default:
         LOGV("\tLVM_ERROR : Equalizer_getParameter unknown param %d", param);
         return -EINVAL;
@@ -1959,6 +1967,16 @@
         //      param2, gEqualizerPresets[param2].name, *pValueSize);
         break;
 
+    case EQ_PARAM_PROPERTIES: {
+        uint16_t *p = (uint16_t *)pValue;
+        LOGV("\tEqualizer_getParameter() EQ_PARAM_PROPERTIES");
+        p[0] = EqualizerGetPreset(pContext);
+        p[1] = FIVEBAND_NUMBANDS;
+        for (int i = 0; i < FIVEBAND_NUMBANDS; i++) {
+            p[2 + i] = EqualizerGetBandLevel(pContext, i);
+        }
+    } break;
+
     default:
         LOGV("\tLVM_ERROR : Equalizer_getParameter() invalid param %d", param);
         status = -EINVAL;
diff --git a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.h b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.h
index 029f843..d009bf9 100644
--- a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.h
+++ b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.h
@@ -17,7 +17,9 @@
 #ifndef ANDROID_EFFECTBUNDLE_H_
 #define ANDROID_EFFECTBUNDLE_H_
 
-#include <media/EffectApi.h>
+#include <media/EffectEqualizerApi.h>
+#include <media/EffectBassBoostApi.h>
+#include <media/EffectVirtualizerApi.h>
 #include <LVM.h>
 
 #if __cplusplus
@@ -29,22 +31,11 @@
 #define MAX_CALL_SIZE           256
 //#define LVM_PCM
 
-//TODO: this should be included from each effect API include
-static const effect_uuid_t SL_IID_BASSBOOST_ = { 0x0634f220, 0xddd4, 0x11db, 0xa0fc,
-                                               { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } };
-const effect_uuid_t * const SL_IID_BASSBOOST = &SL_IID_BASSBOOST_;
-
-static const effect_uuid_t SL_IID_EQUALIZER_ = { 0x0bed4300, 0xddd6, 0x11db, 0x8f34,
-                                               { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } };
-const effect_uuid_t * const SL_IID_EQUALIZER = &SL_IID_EQUALIZER_;
-
-static const effect_uuid_t SL_IID_VIRTUALIZER_ = { 0x37cc2c00, 0xdddd, 0x11db, 0x8577,
-                                                 { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } };
-const effect_uuid_t * const SL_IID_VIRTUALIZER = &SL_IID_VIRTUALIZER_;
-
+#ifndef OPENSL_ES_H_
 static const effect_uuid_t SL_IID_VOLUME_ = { 0x09e8ede0, 0xddde, 0x11db, 0xb4f6,
                                             { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } };
 const effect_uuid_t * const SL_IID_VOLUME = &SL_IID_VOLUME_;
+#endif //OPENSL_ES_H_
 
 typedef enum
 {
@@ -112,34 +103,6 @@
     BundledEffectContext            *pBundledContext;
 };
 
-//TODO: this should be included from each effect API include
-/* enumerated parameter settings for BassBoost effect */
-typedef enum
-{
-    BASSBOOST_PARAM_STRENGTH_SUP,        // type SLboolean  = typedef SLuint32
-    BASSBOOST_PARAM_STRENGTH             // type SLpermille = typedef SLuint16
-} t_bassboost_params;
-
-/* enumerated parameter settings for Virtualizer effect */
-typedef enum
-{
-    VIRTUALIZER_PARAM_STRENGTH_SUP,        // type SLboolean  = typedef SLuint32
-    VIRTUALIZER_PARAM_STRENGTH             // type SLpermille = typedef SLuint16
-} t_virtualizer_params;
-
-/* enumerated parameter settings for Equalizer effect */
-typedef enum
-{
-    EQ_PARAM_NUM_BANDS,           // Gets the number of frequency bands that the equalizer supports.
-    EQ_PARAM_LEVEL_RANGE,         // Returns the minimum and maximum band levels supported.
-    EQ_PARAM_BAND_LEVEL,          // Gets/Sets the gain set for the given equalizer band.
-    EQ_PARAM_CENTER_FREQ,         // Gets the center frequency of the given band.
-    EQ_PARAM_BAND_FREQ_RANGE,     // Gets the frequency range of the given frequency band.
-    EQ_PARAM_GET_BAND,            // Gets the band that has the most effect on the given frequency.
-    EQ_PARAM_CUR_PRESET,          // Gets/Sets the current preset.
-    EQ_PARAM_GET_NUM_OF_PRESETS,  // Gets the total number of presets the equalizer supports.
-    EQ_PARAM_GET_PRESET_NAME      // Gets the preset name based on the index.
-} t_equalizer_params;
 
 /* enumerated parameter settings for Volume effect */
 typedef enum
diff --git a/media/libeffects/testlibs/EffectReverb.c b/media/libeffects/testlibs/EffectReverb.c
index 2ce7558..3f9069f 100644
--- a/media/libeffects/testlibs/EffectReverb.c
+++ b/media/libeffects/testlibs/EffectReverb.c
@@ -688,7 +688,7 @@
         void *pValue) {
     int32_t *pValue32;
     int16_t *pValue16;
-    t_reverb_properties *pProperties;
+    t_reverb_settings *pProperties;
     int32_t i;
     int32_t temp;
     int32_t temp2;
@@ -727,7 +727,7 @@
             break;
 
         case REVERB_PARAM_PROPERTIES:
-            size = sizeof(t_reverb_properties);
+            size = sizeof(t_reverb_settings);
             break;
 
         default:
@@ -740,7 +740,7 @@
 
         pValue32 = (int32_t *) pValue;
         pValue16 = (int16_t *) pValue;
-        pProperties = (t_reverb_properties *) pValue;
+        pProperties = (t_reverb_settings *) pValue;
 
         switch (param) {
         case REVERB_PARAM_BYPASS:
@@ -971,7 +971,7 @@
         void *pValue) {
     int32_t value32;
     int16_t value16;
-    t_reverb_properties *pProperties;
+    t_reverb_settings *pProperties;
     int32_t i;
     int32_t temp;
     int32_t temp2;
@@ -1019,7 +1019,7 @@
             break;
 
         case REVERB_PARAM_PROPERTIES:
-            paramSize = sizeof(t_reverb_properties);
+            paramSize = sizeof(t_reverb_settings);
             break;
 
         default:
@@ -1035,7 +1035,7 @@
         } else if (paramSize == sizeof(int32_t)) {
             value32 = *(int32_t *) pValue;
         } else {
-            pProperties = (t_reverb_properties *) pValue;
+            pProperties = (t_reverb_settings *) pValue;
         }
 
         pPreset = &pReverb->m_sPreset.m_sPreset[pReverb->m_nNextRoom];
diff --git a/media/libeffects/visualizer/Android.mk b/media/libeffects/visualizer/Android.mk
index 82cd925..48b45ff 100644
--- a/media/libeffects/visualizer/Android.mk
+++ b/media/libeffects/visualizer/Android.mk
@@ -15,7 +15,7 @@
 LOCAL_MODULE:= libvisualizer
 
 ifeq ($(TARGET_OS)-$(TARGET_SIMULATOR),linux-true)
-LOCAL_LDLIBS += -ldlS
+LOCAL_LDLIBS += -ldl
 endif
 
 ifneq ($(TARGET_SIMULATOR),true)