Merge "Added tests for audio effects in MediaFrameworkTest" into gingerbread
diff --git a/api/current.xml b/api/current.xml
index 197e2cd..841aa21 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -85290,7 +85290,7 @@
  type="int"
  transient="false"
  volatile="false"
- value="1"
+ value="0"
  static="true"
  final="true"
  deprecated="not deprecated"
@@ -85301,7 +85301,7 @@
  type="int"
  transient="false"
  volatile="false"
- value="0"
+ value="1"
  static="true"
  final="true"
  deprecated="not deprecated"
diff --git a/media/java/android/media/AudioEffect.java b/media/java/android/media/AudioEffect.java
index aed29c3..35038fa 100644
--- a/media/java/android/media/AudioEffect.java
+++ b/media/java/android/media/AudioEffect.java
@@ -101,15 +101,15 @@
     public static final int STATE_INITIALIZED = 1;
 
     // to keep in sync with
-    // frameworks/base/media/jni/audioeffect/android_media_AudioEffect.cpp
-    /**
-     * Event id for engine state change notification.
-     */
-    public static final int NATIVE_EVENT_ENABLED_STATUS = 0;
+    // frameworks/base/include/media/AudioEffect.h
     /**
      * Event id for engine control ownership change notification.
      */
-    public static final int NATIVE_EVENT_CONTROL_STATUS = 1;
+    public static final int NATIVE_EVENT_CONTROL_STATUS = 0;
+    /**
+     * Event id for engine state change notification.
+     */
+    public static final int NATIVE_EVENT_ENABLED_STATUS = 1;
     /**
      * Event id for engine parameter change notification.
      */
@@ -795,7 +795,7 @@
     // Interface definitions
     // --------------------
     /**
-     * The OnParameterChangeListener interface defines a method called by the AudioEffect
+     * The OnEnableStatusChangeListener interface defines a method called by the AudioEffect
      * when a the enabled state of the effect engine was changed by the controlling application.
      */
     public interface OnEnableStatusChangeListener {
@@ -922,7 +922,6 @@
         if (effect == null) {
             return;
         }
-
         if (effect.mNativeEventHandler != null) {
             Message m = effect.mNativeEventHandler.obtainMessage(what, arg1,
                     arg2, obj);
diff --git a/media/libmedia/AudioEffect.cpp b/media/libmedia/AudioEffect.cpp
index 3cdf48a..0f3e245 100644
--- a/media/libmedia/AudioEffect.cpp
+++ b/media/libmedia/AudioEffect.cpp
@@ -218,7 +218,7 @@
            return mIEffect->disable();
         }
     }
-    return INVALID_OPERATION;
+    return NO_ERROR;
 }
 
 status_t AudioEffect::command(uint32_t cmdCode,
@@ -231,7 +231,22 @@
         return INVALID_OPERATION;
     }
 
-    return mIEffect->command(cmdCode, cmdSize, cmdData, replySize, replyData);
+    status_t status = mIEffect->command(cmdCode, cmdSize, cmdData, replySize, replyData);
+    if (status != NO_ERROR) {
+        return status;
+    }
+    status = *(status_t *)replyData;
+    if (status != NO_ERROR) {
+        return status;
+    }
+
+    if (cmdCode == EFFECT_CMD_ENABLE) {
+        android_atomic_or(1, &mEnabled);
+    }
+    if (cmdCode == EFFECT_CMD_DISABLE) {
+        android_atomic_and(~1, &mEnabled);
+    }
+    return status;
 }
 
 
@@ -347,7 +362,11 @@
 {
     LOGV("enableStatusChanged %p enabled %d mCbf %p", this, enabled, mCbf);
     if (mStatus == ALREADY_EXISTS) {
-        mEnabled = enabled;
+        if (enabled) {
+            android_atomic_or(1, &mEnabled);
+        } else {
+            android_atomic_and(~1, &mEnabled);
+        }
         if (mCbf) {
             mCbf(EVENT_ENABLE_STATUS_CHANGED, mUserData, &enabled);
         }
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 252b42a..1c7faa4 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -1696,7 +1696,10 @@
     // Delegate master volume control to effect in output mix effect chain if needed
     sp<EffectChain> chain = getEffectChain_l(AudioSystem::SESSION_OUTPUT_MIX);
     if (chain != 0) {
-        uint32_t v = (uint32_t)(masterVolume * (1 << 24));
+        uint32_t v = 0;
+        if (!masterMute) {
+            v = (uint32_t)(masterVolume * (1 << 24));
+        }
         chain->setVolume_l(&v, &v);
         masterVolume = (float)((v + (1 << 23)) >> 24);
         chain.clear();
@@ -1750,7 +1753,7 @@
 
             // compute volume for this track
             int16_t left, right, aux;
-            if (track->isMuted() || masterMute || track->isPausing() ||
+            if (track->isMuted() || track->isPausing() ||
                 mStreamTypes[track->type()].mute) {
                 left = right = aux = 0;
                 if (track->isPausing()) {
@@ -5351,7 +5354,7 @@
         return;
     }
 
-    if (mState == ACTIVE || mState == STOPPING || mState == STOPPED) {
+    if (mState == ACTIVE || mState == STOPPING || mState == STOPPED || mState == RESTART) {
         // do 32 bit to 16 bit conversion for auxiliary effect input buffer
         if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
             AudioMixer::ditherAndClamp(mConfig.inputCfg.buffer.s32,
@@ -6032,8 +6035,8 @@
 AudioFlinger::EffectChain::EffectChain(const wp<ThreadBase>& wThread,
                                         int sessionId)
     : mThread(wThread), mSessionId(sessionId), mActiveTrackCnt(0), mOwnInBuffer(false),
-            mVolumeCtrlIdx(-1), mLeftVolume(0), mRightVolume(0),
-            mNewLeftVolume(0), mNewRightVolume(0)
+            mVolumeCtrlIdx(-1), mLeftVolume(UINT_MAX), mRightVolume(UINT_MAX),
+            mNewLeftVolume(UINT_MAX), mNewRightVolume(UINT_MAX)
 {
     mStrategy = AudioSystem::getStrategyForStream(AudioSystem::MUSIC);
 }
diff --git a/telephony/java/com/android/internal/telephony/CallManager.java b/telephony/java/com/android/internal/telephony/CallManager.java
index d77f778..b57f358 100644
--- a/telephony/java/com/android/internal/telephony/CallManager.java
+++ b/telephony/java/com/android/internal/telephony/CallManager.java
@@ -24,6 +24,7 @@
 import android.telephony.PhoneStateListener;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 
 /**
@@ -163,6 +164,14 @@
     }
 
     /**
+     * Returns all the registered phone objects.
+     * @return all the registered phone objects.
+     */
+    public List<Phone> getAllPhones() {
+        return Collections.unmodifiableList(mPhones);
+    }
+
+    /**
      * Get current coarse-grained voice call state.
      * If the Call Manager has an active call and call waiting occurs,
      * then the phone state is RINGING not OFFHOOK
diff --git a/telephony/java/com/android/internal/telephony/PhoneFactory.java b/telephony/java/com/android/internal/telephony/PhoneFactory.java
index 803b736..2e391cb 100644
--- a/telephony/java/com/android/internal/telephony/PhoneFactory.java
+++ b/telephony/java/com/android/internal/telephony/PhoneFactory.java
@@ -24,6 +24,8 @@
 
 import com.android.internal.telephony.cdma.CDMAPhone;
 import com.android.internal.telephony.gsm.GSMPhone;
+import com.android.internal.telephony.sip.SipPhone;
+import com.android.internal.telephony.sip.SipPhoneFactory;
 
 /**
  * {@hide}
@@ -175,4 +177,13 @@
             return phone;
         }
     }
+
+    /**
+     * Makes a {@link SipPhone} object.
+     * @param sipUri the local SIP URI the phone runs on
+     * @return the {@code SipPhone} object or null if the SIP URI is not valid
+     */
+    public static SipPhone makeSipPhone(String sipUri) {
+        return SipPhoneFactory.makePhone(sipUri, sContext, sPhoneNotifier);
+    }
 }
diff --git a/telephony/java/com/android/internal/telephony/sip/SipPhoneFactory.java b/telephony/java/com/android/internal/telephony/sip/SipPhoneFactory.java
index c9e9762..a1bdd2f 100644
--- a/telephony/java/com/android/internal/telephony/sip/SipPhoneFactory.java
+++ b/telephony/java/com/android/internal/telephony/sip/SipPhoneFactory.java
@@ -16,7 +16,6 @@
 
 package com.android.internal.telephony.sip;
 
-import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneNotifier;
 
 import android.content.Context;
@@ -26,42 +25,25 @@
 import java.text.ParseException;
 
 /**
- * @hide
+ * {@hide}
  */
 public class SipPhoneFactory {
-    private static PhoneNotifier sPhoneNotifier = makeDefaultPhoneNotifier();
-    private static Context sContext;
-
-    public static void makeDefaultPhones(Context context) {
-        makeDefaultPhone(context);
-    }
-
-    public static void makeDefaultPhone(Context context) {
-        sContext = context;
-        SipPhoneProxy.getInstance().setPhone(
-                makePhone("sip:anonymous@localhost"));
-    }
-
-    public static Phone getDefaultPhone() {
-       return SipPhoneProxy.getInstance();
-    }
-
-    public static SipPhone makePhone(String sipProfileUri) {
+    /**
+     * Makes a {@link SipPhone} object.
+     * @param sipUri the local SIP URI the phone runs on
+     * @param context {@code Context} needed to create a Phone object
+     * @param phoneNotifier {@code PhoneNotifier} needed to create a Phone
+     *      object
+     * @return the {@code SipPhone} object or null if the SIP URI is not valid
+     */
+    public static SipPhone makePhone(String sipUri, Context context,
+            PhoneNotifier phoneNotifier) {
         try {
-            SipProfile profile = new SipProfile.Builder(sipProfileUri).build();
-            return new SipPhone(sContext, sPhoneNotifier, profile);
+            SipProfile profile = new SipProfile.Builder(sipUri).build();
+            return new SipPhone(context, phoneNotifier, profile);
         } catch (ParseException e) {
-            Log.v("SipPhoneProxy", "setPhone", e);
+            Log.w("SipPhoneProxy", "setPhone", e);
             return null;
         }
     }
-
-    private static PhoneNotifier makeDefaultPhoneNotifier() {
-        try {
-            return new com.android.internal.telephony.SipPhoneNotifier();
-        } catch (Error e) {
-            Log.e("SipPhoneProxy", "makeDefaultPhoneNotifier", e);
-            throw e;
-        }
-    }
 }