Merge "RTP: Fix non-zero DC in EchoSuppressor caused while aggregating samples." into gingerbread
diff --git a/api/current.xml b/api/current.xml
index d99d3ca..d36fe69 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -96518,32 +96518,6 @@
 <parameter name="callbackImmediately" type="boolean">
 </parameter>
 </method>
-<method name="setRingbackToneEnabled"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="enabled" type="boolean">
-</parameter>
-</method>
-<method name="setRingtoneEnabled"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="enabled" type="boolean">
-</parameter>
-</method>
 <method name="setSpeakerMode"
  return="void"
  abstract="false"
@@ -97242,25 +97216,6 @@
 <exception name="SipException" type="android.net.sip.SipException">
 </exception>
 </method>
-<method name="takeAudioCall"
- return="android.net.sip.SipAudioCall"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="incomingCallIntent" type="android.content.Intent">
-</parameter>
-<parameter name="listener" type="android.net.sip.SipAudioCall.Listener">
-</parameter>
-<parameter name="ringtoneEnabled" type="boolean">
-</parameter>
-<exception name="SipException" type="android.net.sip.SipException">
-</exception>
-</method>
 <method name="unregister"
  return="void"
  abstract="false"
@@ -100481,7 +100436,7 @@
  visibility="public"
 >
 </method>
-<method name="isTagDiscoveryEnabled"
+<method name="isEnabled"
  return="boolean"
  abstract="false"
  native="false"
diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c
index 822f62d..0723f67 100644
--- a/cmds/dumpstate/dumpstate.c
+++ b/cmds/dumpstate/dumpstate.c
@@ -216,19 +216,21 @@
         fclose(cmdline);
     }
 
-    /* switch to non-root user and group */
-    gid_t groups[] = { AID_LOG, AID_SDCARD_RW, AID_MOUNT };
-    if (setgroups(sizeof(groups)/sizeof(groups[0]), groups) != 0) {
-        LOGE("Unable to setgroups, aborting: %s\n", strerror(errno));
-        return -1;
-    }
-    if (setgid(AID_SHELL) != 0) {
-        LOGE("Unable to setgid, aborting: %s\n", strerror(errno));
-        return -1;
-    }
-    if (setuid(AID_SHELL) != 0) {
-        LOGE("Unable to setuid, aborting: %s\n", strerror(errno));
-        return -1;
+    if (getuid() == 0) {
+        /* switch to non-root user and group */
+        gid_t groups[] = { AID_LOG, AID_SDCARD_RW, AID_MOUNT };
+        if (setgroups(sizeof(groups)/sizeof(groups[0]), groups) != 0) {
+            LOGE("Unable to setgroups, aborting: %s\n", strerror(errno));
+            return -1;
+        }
+        if (setgid(AID_SHELL) != 0) {
+            LOGE("Unable to setgid, aborting: %s\n", strerror(errno));
+            return -1;
+        }
+        if (setuid(AID_SHELL) != 0) {
+            LOGE("Unable to setuid, aborting: %s\n", strerror(errno));
+            return -1;
+        }
     }
 
     char path[PATH_MAX], tmp_path[PATH_MAX];
diff --git a/core/java/android/app/NativeActivity.java b/core/java/android/app/NativeActivity.java
index d7a0412..c98128c 100644
--- a/core/java/android/app/NativeActivity.java
+++ b/core/java/android/app/NativeActivity.java
@@ -162,15 +162,10 @@
         
         String path = null;
         
-        if ((ai.applicationInfo.flags&ApplicationInfo.FLAG_HAS_CODE) == 0) {
-            // If the application does not have (Java) code, then no ClassLoader
-            // has been set up for it.  We will need to do our own search for
-            // the native code.
-            File libraryFile = new File(ai.applicationInfo.nativeLibraryDir,
-                    System.mapLibraryName(libname));
-            if (libraryFile.exists()) {
-                path = libraryFile.getPath();
-            }
+        File libraryFile = new File(ai.applicationInfo.nativeLibraryDir,
+                System.mapLibraryName(libname));
+        if (libraryFile.exists()) {
+            path = libraryFile.getPath();
         }
         
         if (path == null) {
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 175d6db5..665b606 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -252,9 +252,6 @@
     public static final int FLAG_RESTORE_ANY_VERSION = 1<<17;
 
     /**
-     * Value for {@link #flags}: Set to true if the application has been
-     * installed using the forward lock option.
-     *
      * Value for {@link #flags}: Set to true if the application is
      * currently installed on external/removable/unprotected storage.  Such
      * applications may not be available if their storage is not currently
diff --git a/core/java/android/hardware/SensorEvent.java b/core/java/android/hardware/SensorEvent.java
index 2c5c909..98bf632 100644
--- a/core/java/android/hardware/SensorEvent.java
+++ b/core/java/android/hardware/SensorEvent.java
@@ -177,12 +177,12 @@
      *  <h4>{@link android.hardware.Sensor#TYPE_ROTATION_VECTOR Sensor.TYPE_ROTATION_VECTOR}:</h4>
      *  The rotation vector represents the orientation of the device as a combination of an angle
      *  and an axis, in which the device has rotated through an angle theta around an axis
-     *  <x, y, z>. The three elements of the rotation vector are
-     *  <x*sin(theta/2), y*sin(theta/2), z*sin(theta/2)>, such that the magnitude of the rotation
+     *  &lt;x, y, z>. The three elements of the rotation vector are
+     *  &lt;x*sin(theta/2), y*sin(theta/2), z*sin(theta/2)>, such that the magnitude of the rotation
      *  vector is equal to sin(theta/2), and the direction of the rotation vector is equal to the
      *  direction of the axis of rotation. The three elements of the rotation vector are equal to
      *  the last three components of a unit quaternion
-     *  <cos(theta/2), x*sin(theta/2), y*sin(theta/2), z*sin(theta/2)>.  Elements of the rotation
+     *  &lt;cos(theta/2), x*sin(theta/2), y*sin(theta/2), z*sin(theta/2)>.  Elements of the rotation
      *  vector are unitless.  The x,y, and z axis are defined in the same way as the acceleration
      *  sensor.
      *
diff --git a/core/java/android/nfc/INfcTag.aidl b/core/java/android/nfc/INfcTag.aidl
index 2171434..13b97d6 100644
--- a/core/java/android/nfc/INfcTag.aidl
+++ b/core/java/android/nfc/INfcTag.aidl
@@ -28,6 +28,7 @@
     String getType(int nativeHandle);
     byte[] getUid(int nativeHandle);
     boolean isNdef(int nativeHandle);
+    boolean isPresent(int nativeHandle);
     byte[] transceive(int nativeHandle, in byte[] data);
 
     int getLastError(int nativeHandle);
diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java
index bc3c6d9..6884abb 100644
--- a/core/java/android/nfc/NfcAdapter.java
+++ b/core/java/android/nfc/NfcAdapter.java
@@ -227,14 +227,17 @@
     }
 
     /**
-     * Return true if this NFC Adapter is enabled to discover new tags.
+     * Return true if this NFC Adapter has any features enabled.
      * <p>
      * If this method returns false, then applications should request the user
      * turn on NFC tag discovery in Settings.
+     * <p>
+     * If this method returns false, the NFC hardware is guaranteed not to
+     * perform or respond to any NFC communication.
      *
      * @return true if this NFC Adapter is enabled to discover new tags
      */
-    public boolean isTagDiscoveryEnabled() {
+    public boolean isEnabled() {
         try {
             return mService.isEnabled();
         } catch (RemoteException e) {
@@ -244,12 +247,14 @@
     }
 
     /**
+     * Enable NFC hardware.
+     * <p>
      * NOTE: may block for ~second or more.  Poor API.  Avoid
      * calling from the UI thread.
      *
      * @hide
      */
-    public boolean enableTagDiscovery() {
+    public boolean enable() {
         try {
             return mService.enable();
         } catch (RemoteException e) {
@@ -259,12 +264,16 @@
     }
 
     /**
+     * Disable NFC hardware.
+     * No NFC features will work after this call, and the hardware
+     * will not perform or respond to any NFC communication.
+     * <p>
      * NOTE: may block for ~second or more.  Poor API.  Avoid
      * calling from the UI thread.
      *
      * @hide
      */
-    public boolean disableTagDiscovery() {
+    public boolean disable() {
         try {
             return mService.disable();
         } catch (RemoteException e) {
diff --git a/core/java/android/nfc/RawTagConnection.java b/core/java/android/nfc/RawTagConnection.java
index 265eb1b..1261db1 100644
--- a/core/java/android/nfc/RawTagConnection.java
+++ b/core/java/android/nfc/RawTagConnection.java
@@ -95,10 +95,16 @@
      * returns true.
      */
     public boolean isConnected() {
-        // TODO(nxp): update mIsConnected when tag goes out of range -
-        //            but do not do an active prescence check in
-        //            isConnected()
-        return mIsConnected;
+        if (!mIsConnected) {
+            return false;
+        }
+
+        try {
+            return mTagService.isPresent(mTag.mNativeHandle);
+        } catch (RemoteException e) {
+            Log.e(TAG, "NFC service died", e);
+            return false;
+        }
     }
 
     /**
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 90cd840..5aa22fb 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -1640,86 +1640,6 @@
         public static final String NOTIFICATION_LIGHT_PULSE = "notification_light_pulse";
 
         /**
-         * Whether nfc is enabled/disabled
-         * 0=disabled. 1=enabled.
-         * @hide
-         */
-        public static final String NFC_ON = "nfc_on";
-
-        /**
-         * Whether nfc secure element is enabled/disabled
-         * 0=disabled. 1=enabled.
-         * @hide
-         */
-        public static final String NFC_SECURE_ELEMENT_ON = "nfc_secure_element_on";
-
-        /**
-         * Whether nfc secure element is enabled/disabled
-         * 0=disabled. 1=enabled.
-         * @hide
-         */
-        public static final String NFC_SECURE_ELEMENT_ID = "nfc_secure_element_id";
-
-        /**
-         * LLCP LTO value
-         * @hide
-         */
-        public static final String NFC_LLCP_LTO = "nfc_llcp_lto";
-
-        /**
-         * LLCP MIU value
-         * @hide
-         */
-        public static final String NFC_LLCP_MIU = "nfc_llcp_miu";
-
-        /**
-         * LLCP WKS value
-         * @hide
-         */
-        public static final String NFC_LLCP_WKS = "nfc_llcp_wks";
-
-        /**
-         * LLCP OPT value
-         * @hide
-         */
-        public static final String NFC_LLCP_OPT = "nfc_llcp_opt";
-
-        /**
-         * NFC Discovery Reader A
-         * 0=disabled. 1=enabled.
-         * @hide
-         */
-        public static final String NFC_DISCOVERY_A = "nfc_discovery_a";
-
-        /**
-         * NFC Discovery Reader B
-         * 0=disabled. 1=enabled.
-         * @hide
-         */
-        public static final String NFC_DISCOVERY_B = "nfc_discovery_b";
-
-        /**
-         * NFC Discovery Reader Felica
-         * 0=disabled. 1=enabled.
-         * @hide
-         */
-        public static final String NFC_DISCOVERY_F = "nfc_discovery_felica";
-
-        /**
-         * NFC Discovery Reader 15693
-         * 0=disabled. 1=enabled.
-         * @hide
-         */
-        public static final String NFC_DISCOVERY_15693 = "nfc_discovery_15693";
-
-        /**
-         * NFC Discovery NFCIP
-         * 0=disabled. 1=enabled.
-         * @hide
-         */
-        public static final String NFC_DISCOVERY_NFCIP = "nfc_discovery_nfcip";
-
-        /**
          * Show pointer location on screen?
          * 0 = no
          * 1 = yes
@@ -1885,18 +1805,6 @@
             NOTIFICATION_LIGHT_PULSE,
             SIP_CALL_OPTIONS,
             SIP_RECEIVE_CALLS,
-            NFC_ON,
-            NFC_SECURE_ELEMENT_ON,
-            NFC_SECURE_ELEMENT_ID,
-            NFC_LLCP_LTO,
-            NFC_LLCP_MIU,
-            NFC_LLCP_WKS,
-            NFC_LLCP_OPT,
-            NFC_DISCOVERY_A,
-            NFC_DISCOVERY_B,
-            NFC_DISCOVERY_F,
-            NFC_DISCOVERY_15693,
-            NFC_DISCOVERY_NFCIP,
         };
 
         // Settings moved to Settings.Secure
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 36acb85..bc6d6d2 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -3985,8 +3985,8 @@
                 // we have gone through a significant charge (from a very low
                 // level to a now very high level).
                 if (oldStatus == BatteryManager.BATTERY_STATUS_FULL
-                        || level >= 100
-                        || (mDischargeCurrentLevel < 20 && level > 90)) {
+                        || level >= 95
+                        || (mDischargeCurrentLevel < 30 && level >= 90)) {
                     doWrite = true;
                     resetAllStatsLocked();
                     mDischargeStartLevel = level;
diff --git a/core/res/res/drawable-hdpi/ic_media_play.png b/core/res/res/drawable-hdpi/ic_media_play.png
index e4110bd..a7cdd41 100644
--- a/core/res/res/drawable-hdpi/ic_media_play.png
+++ b/core/res/res/drawable-hdpi/ic_media_play.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_play.png b/core/res/res/drawable-mdpi/ic_media_play.png
index 96593a4..41cd65f 100644
--- a/core/res/res/drawable-mdpi/ic_media_play.png
+++ b/core/res/res/drawable-mdpi/ic_media_play.png
Binary files differ
diff --git a/include/media/stagefright/MPEG4Writer.h b/include/media/stagefright/MPEG4Writer.h
index cff38b2..bb469e5 100644
--- a/include/media/stagefright/MPEG4Writer.h
+++ b/include/media/stagefright/MPEG4Writer.h
@@ -152,6 +152,7 @@
     bool exceedsFileSizeLimit();
     bool use32BitFileOffset() const;
     bool exceedsFileDurationLimit();
+    bool isFileStreamable() const;
     void trackProgressStatus(const Track* track, int64_t timeUs, status_t err = OK);
 
     MPEG4Writer(const MPEG4Writer &);
diff --git a/libs/rs/Android.mk b/libs/rs/Android.mk
index 98464a0..6f2cd07 100644
--- a/libs/rs/Android.mk
+++ b/libs/rs/Android.mk
@@ -102,6 +102,9 @@
 	rsType.cpp \
 	rsVertexArray.cpp
 
+ifeq ($(TARGET_BOARD_PLATFORM), s5pc110)
+	LOCAL_CFLAGS += -DHAS_CONTEXT_PRIORITY
+endif
 
 LOCAL_SHARED_LIBRARIES += libcutils libutils libEGL libGLESv1_CM libGLESv2 libui libacc
 LOCAL_LDLIBS := -lpthread -ldl
diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp
index 596f533..92c6619 100644
--- a/libs/rs/rsContext.cpp
+++ b/libs/rs/rsContext.cpp
@@ -26,6 +26,7 @@
 
 #include <cutils/properties.h>
 
+#include <EGL/eglext.h>
 #include <GLES/gl.h>
 #include <GLES/glext.h>
 #include <GLES2/gl2.h>
@@ -58,7 +59,18 @@
     mEGL.mNumConfigs = -1;
     EGLint configAttribs[128];
     EGLint *configAttribsPtr = configAttribs;
-    EGLint context_attribs2[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
+    EGLint context_attribs2[] = { EGL_CONTEXT_CLIENT_VERSION, 2,
+            EGL_NONE, GL_NONE, EGL_NONE };
+
+#ifdef HAS_CONTEXT_PRIORITY
+#ifdef EGL_IMG_context_priority
+#warning "using EGL_IMG_context_priority"
+    if (mThreadPriority > 0) {
+        context_attribs2[2] = EGL_CONTEXT_PRIORITY_LEVEL_IMG;
+        context_attribs2[3] = EGL_CONTEXT_PRIORITY_LOW_IMG;
+    }
+#endif
+#endif
 
     memset(configAttribs, 0, sizeof(configAttribs));
 
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index e53b0a0..90b104a 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -309,11 +309,10 @@
     //
     // Statistical analysis shows that metadata usually accounts
     // for a small portion of the total file size, usually < 0.6%.
-    // Currently, lets set to 0.4% for now.
 
-    // The default MIN_MOOV_BOX_SIZE is set to 0.4% x 1MB,
+    // The default MIN_MOOV_BOX_SIZE is set to 0.6% x 1MB / 2,
     // where 1MB is the common file size limit for MMS application.
-    // The default MAX _MOOV_BOX_SIZE value is based on about 4
+    // The default MAX _MOOV_BOX_SIZE value is based on about 3
     // minute video recording with a bit rate about 3 Mbps, because
     // statistics also show that most of the video captured are going
     // to be less than 3 minutes.
@@ -321,20 +320,33 @@
     // If the estimation is wrong, we will pay the price of wasting
     // some reserved space. This should not happen so often statistically.
     static const int32_t factor = mUse32BitOffset? 1: 2;
-    static const int64_t MIN_MOOV_BOX_SIZE = 4 * 1024;  // 4 KB
+    static const int64_t MIN_MOOV_BOX_SIZE = 3 * 1024;  // 3 KB
     static const int64_t MAX_MOOV_BOX_SIZE = (180 * 3000000 * 6LL / 8000);
     int64_t size = MIN_MOOV_BOX_SIZE;
 
+    // Max file size limit is set
     if (mMaxFileSizeLimitBytes != 0 && mIsFileSizeLimitExplicitlyRequested) {
-        size = mMaxFileSizeLimitBytes * 4 / 1000;
-    } else if (mMaxFileDurationLimitUs != 0) {
-        if (bitRate <= 0) {
-            // We could not estimate the file size since bitRate is not set.
-            size = MIN_MOOV_BOX_SIZE;
-        } else {
-            size = ((mMaxFileDurationLimitUs * bitRate * 4) / 1000 / 8000000);
+        size = mMaxFileSizeLimitBytes * 6 / 1000;
+    }
+
+    // Max file duration limit is set
+    if (mMaxFileDurationLimitUs != 0) {
+        if (bitRate > 0) {
+            int64_t size2 =
+                ((mMaxFileDurationLimitUs * bitRate * 6) / 1000 / 8000000);
+            if (mMaxFileSizeLimitBytes != 0 && mIsFileSizeLimitExplicitlyRequested) {
+                // When both file size and duration limits are set,
+                // we use the smaller limit of the two.
+                if (size > size2) {
+                    size = size2;
+                }
+            } else {
+                // Only max file duration limit is set
+                size = size2;
+            }
         }
     }
+
     if (size < MIN_MOOV_BOX_SIZE) {
         size = MIN_MOOV_BOX_SIZE;
     }
@@ -787,6 +799,10 @@
     write(data, 1, size, mFile);
 }
 
+bool MPEG4Writer::isFileStreamable() const {
+    return mStreamableFile;
+}
+
 bool MPEG4Writer::exceedsFileSizeLimit() {
     // No limit
     if (mMaxFileSizeLimitBytes == 0) {
@@ -799,7 +815,7 @@
         nTotalBytesEstimate += (*it)->getEstimatedTrackSizeBytes();
     }
 
-    return (nTotalBytesEstimate  + 1024 >= mMaxFileSizeLimitBytes);
+    return (nTotalBytesEstimate >= mMaxFileSizeLimitBytes);
 }
 
 bool MPEG4Writer::exceedsFileDurationLimit() {
@@ -887,12 +903,16 @@
 
     int64_t stszBoxSizeBytes = mSamplesHaveSameSize? 4: (mNumSamples * 4);
 
-    mEstimatedTrackSizeBytes = mMdatSizeBytes +             // media data size
-                               mNumStscTableEntries * 12 +  // stsc box size
-                               mNumStssTableEntries * 4 +   // stss box size
-                               mNumSttsTableEntries * 8 +   // stts box size
-                               stcoBoxSizeBytes +           // stco box size
-                               stszBoxSizeBytes;            // stsz box size
+    mEstimatedTrackSizeBytes = mMdatSizeBytes;  // media data size
+    if (!mOwner->isFileStreamable()) {
+        // Reserved free space is not large enough to hold
+        // all meta data and thus wasted.
+        mEstimatedTrackSizeBytes += mNumStscTableEntries * 12 +  // stsc box size
+                                    mNumStssTableEntries * 4 +   // stss box size
+                                    mNumSttsTableEntries * 8 +   // stts box size
+                                    stcoBoxSizeBytes +           // stco box size
+                                    stszBoxSizeBytes;            // stsz box size
+    }
 }
 
 void MPEG4Writer::Track::addOneStscTableEntry(
diff --git a/opengl/libagl/egl.cpp b/opengl/libagl/egl.cpp
index 3fb322a..1ea8d06 100644
--- a/opengl/libagl/egl.cpp
+++ b/opengl/libagl/egl.cpp
@@ -947,6 +947,7 @@
         { EGL_RED_SIZE,         5 },
         { EGL_DEPTH_SIZE,       0 },
         { EGL_CONFIG_ID,        0 },
+        { EGL_NATIVE_VISUAL_ID, GGL_PIXEL_FORMAT_RGB_565 },
         { EGL_SURFACE_TYPE,     EGL_WINDOW_BIT|EGL_PBUFFER_BIT|EGL_PIXMAP_BIT },
 };
 
@@ -958,6 +959,7 @@
         { EGL_RED_SIZE,         5 },
         { EGL_DEPTH_SIZE,      16 },
         { EGL_CONFIG_ID,        1 },
+        { EGL_NATIVE_VISUAL_ID, GGL_PIXEL_FORMAT_RGB_565 },
         { EGL_SURFACE_TYPE,     EGL_WINDOW_BIT|EGL_PBUFFER_BIT|EGL_PIXMAP_BIT },
 };
 
@@ -970,6 +972,7 @@
         { EGL_RED_SIZE,         8 },
         { EGL_DEPTH_SIZE,       0 },
         { EGL_CONFIG_ID,        6 },
+        { EGL_NATIVE_VISUAL_ID, GGL_PIXEL_FORMAT_RGBX_8888 },
         { EGL_SURFACE_TYPE,     EGL_WINDOW_BIT|EGL_PBUFFER_BIT|EGL_PIXMAP_BIT },
 };
 
@@ -981,6 +984,7 @@
         { EGL_RED_SIZE,         8 },
         { EGL_DEPTH_SIZE,      16 },
         { EGL_CONFIG_ID,        7 },
+        { EGL_NATIVE_VISUAL_ID, GGL_PIXEL_FORMAT_RGBX_8888 },
         { EGL_SURFACE_TYPE,     EGL_WINDOW_BIT|EGL_PBUFFER_BIT|EGL_PIXMAP_BIT },
 };
 
@@ -992,6 +996,7 @@
         { EGL_GREEN_SIZE,       8 },
         { EGL_RED_SIZE,         8 },
         { EGL_DEPTH_SIZE,       0 },
+        { EGL_NATIVE_VISUAL_ID, GGL_PIXEL_FORMAT_RGBA_8888 },
         { EGL_CONFIG_ID,        2 },
         { EGL_SURFACE_TYPE,     EGL_WINDOW_BIT|EGL_PBUFFER_BIT|EGL_PIXMAP_BIT },
 };
@@ -1004,6 +1009,7 @@
         { EGL_RED_SIZE,         8 },
         { EGL_DEPTH_SIZE,      16 },
         { EGL_CONFIG_ID,        3 },
+        { EGL_NATIVE_VISUAL_ID, GGL_PIXEL_FORMAT_RGBA_8888 },
         { EGL_SURFACE_TYPE,     EGL_WINDOW_BIT|EGL_PBUFFER_BIT|EGL_PIXMAP_BIT },
 };
 
@@ -1016,6 +1022,7 @@
         { EGL_RED_SIZE,         0 },
         { EGL_DEPTH_SIZE,       0 },
         { EGL_CONFIG_ID,        4 },
+        { EGL_NATIVE_VISUAL_ID, GGL_PIXEL_FORMAT_A_8 },
         { EGL_SURFACE_TYPE,     EGL_WINDOW_BIT|EGL_PBUFFER_BIT|EGL_PIXMAP_BIT },
 };
 
@@ -1026,6 +1033,7 @@
         { EGL_GREEN_SIZE,       0 },
         { EGL_RED_SIZE,         0 },
         { EGL_DEPTH_SIZE,      16 },
+        { EGL_NATIVE_VISUAL_ID, GGL_PIXEL_FORMAT_A_8 },
         { EGL_CONFIG_ID,        5 },
         { EGL_SURFACE_TYPE,     EGL_WINDOW_BIT|EGL_PBUFFER_BIT|EGL_PIXMAP_BIT },
 };
diff --git a/opengl/tests/configdump/Android.mk b/opengl/tests/configdump/Android.mk
new file mode 100644
index 0000000..3f7c915
--- /dev/null
+++ b/opengl/tests/configdump/Android.mk
@@ -0,0 +1,16 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	configdump.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+	libcutils \
+    libEGL \
+    libGLESv1_CM
+
+LOCAL_MODULE:= test-opengl-configdump
+
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_EXECUTABLE)
diff --git a/opengl/tests/configdump/configdump.cpp b/opengl/tests/configdump/configdump.cpp
new file mode 100644
index 0000000..69b9eb6
--- /dev/null
+++ b/opengl/tests/configdump/configdump.cpp
@@ -0,0 +1,89 @@
+/*
+** Copyright 2010, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <EGL/egl.h>
+
+#define ATTRIBUTE(_attr) { _attr, #_attr }
+
+struct Attribute {
+    EGLint attribute;
+    char const* name;
+};
+
+Attribute attributes[] = {
+        ATTRIBUTE( EGL_BUFFER_SIZE ),
+        ATTRIBUTE( EGL_ALPHA_SIZE ),
+        ATTRIBUTE( EGL_BLUE_SIZE ),
+        ATTRIBUTE( EGL_GREEN_SIZE ),
+        ATTRIBUTE( EGL_RED_SIZE ),
+        ATTRIBUTE( EGL_DEPTH_SIZE ),
+        ATTRIBUTE( EGL_STENCIL_SIZE ),
+        ATTRIBUTE( EGL_CONFIG_CAVEAT ),
+        ATTRIBUTE( EGL_CONFIG_ID ),
+        ATTRIBUTE( EGL_LEVEL ),
+        ATTRIBUTE( EGL_MAX_PBUFFER_HEIGHT ),
+        ATTRIBUTE( EGL_MAX_PBUFFER_WIDTH ),
+        ATTRIBUTE( EGL_MAX_PBUFFER_PIXELS ),
+        ATTRIBUTE( EGL_NATIVE_RENDERABLE ),
+        ATTRIBUTE( EGL_NATIVE_VISUAL_ID ),
+        ATTRIBUTE( EGL_NATIVE_VISUAL_TYPE ),
+        ATTRIBUTE( EGL_SAMPLES ),
+        ATTRIBUTE( EGL_SAMPLE_BUFFERS ),
+        ATTRIBUTE( EGL_SURFACE_TYPE ),
+        ATTRIBUTE( EGL_TRANSPARENT_TYPE ),
+        ATTRIBUTE( EGL_TRANSPARENT_BLUE_VALUE ),
+        ATTRIBUTE( EGL_TRANSPARENT_GREEN_VALUE ),
+        ATTRIBUTE( EGL_TRANSPARENT_RED_VALUE ),
+        ATTRIBUTE( EGL_BIND_TO_TEXTURE_RGB ),
+        ATTRIBUTE( EGL_BIND_TO_TEXTURE_RGBA ),
+        ATTRIBUTE( EGL_MIN_SWAP_INTERVAL ),
+        ATTRIBUTE( EGL_MAX_SWAP_INTERVAL ),
+        ATTRIBUTE( EGL_LUMINANCE_SIZE ),
+        ATTRIBUTE( EGL_ALPHA_MASK_SIZE ),
+        ATTRIBUTE( EGL_COLOR_BUFFER_TYPE ),
+        ATTRIBUTE( EGL_RENDERABLE_TYPE ),
+        ATTRIBUTE( EGL_MATCH_NATIVE_PIXMAP ),
+        ATTRIBUTE( EGL_CONFORMANT ),
+};
+
+
+int main(int argc, char** argv)
+{
+    EGLConfig* configs;
+    EGLint n;
+
+    EGLDisplay dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+    eglInitialize(dpy, 0, 0);
+    eglGetConfigs(dpy, NULL, 0, &n);
+    configs = new EGLConfig[n];
+    eglGetConfigs(dpy, configs, n, &n);
+
+    for (EGLint i=0 ; i<n ; i++) {
+        printf("EGLConfig[%d]\n", i);
+        for (int attr = 0 ; attr<sizeof(attributes)/sizeof(Attribute) ; attr++) {
+            EGLint value;
+            eglGetConfigAttrib(dpy, configs[i], attributes[attr].attribute, &value);
+            printf("\t%-32s: %10d (0x%08x)\n", attributes[attr].name, value, value);
+        }
+    }
+
+    delete [] configs;
+    eglTerminate(dpy);
+    return 0;
+}
diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java
index 8cf8f6a..85bb3aa 100644
--- a/services/java/com/android/server/MountService.java
+++ b/services/java/com/android/server/MountService.java
@@ -1155,7 +1155,7 @@
 
     private void setUmsEnabling(boolean enable) {
         synchronized (mListeners) {
-            mUmsEnabling = true;
+            mUmsEnabling = enable;
         }
     }
 
diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk
index a14bfb5..e2f8a74 100644
--- a/services/surfaceflinger/Android.mk
+++ b/services/surfaceflinger/Android.mk
@@ -23,6 +23,10 @@
 ifeq ($(TARGET_BOARD_PLATFORM), omap3)
 	LOCAL_CFLAGS += -DNO_RGBX_8888
 endif
+ifeq ($(TARGET_BOARD_PLATFORM), s5pc110)
+	LOCAL_CFLAGS += -DHAS_CONTEXT_PRIORITY
+endif
+
 
 # need "-lrt" on Linux simulator to pick up clock_gettime
 ifeq ($(TARGET_SIMULATOR),true)
diff --git a/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp
index 0515110..28a512e 100644
--- a/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp
+++ b/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp
@@ -199,8 +199,18 @@
      * Create our OpenGL ES context
      */
     
-    context = eglCreateContext(display, config, NULL, NULL);
-    
+
+    EGLint contextAttributes[] = {
+#ifdef EGL_IMG_context_priority
+#ifdef HAS_CONTEXT_PRIORITY
+#warning "using EGL_IMG_context_priority"
+        EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG,
+#endif
+#endif
+        EGL_NONE, EGL_NONE
+    };
+    context = eglCreateContext(display, config, NULL, contextAttributes);
+
     mDisplay = display;
     mConfig  = config;
     mSurface = surface;
diff --git a/telephony/java/com/android/internal/telephony/CallManager.java b/telephony/java/com/android/internal/telephony/CallManager.java
index 3f0ec0a..ab7b601 100644
--- a/telephony/java/com/android/internal/telephony/CallManager.java
+++ b/telephony/java/com/android/internal/telephony/CallManager.java
@@ -1626,7 +1626,15 @@
     }
 
 
-
+    private boolean hasMoreThanOneRingingCall() {
+        int count = 0;
+        for (Call call : mRingingCalls) {
+            if (call.getState().isRinging()) {
+                if (++count > 1) return true;
+            }
+        }
+        return false;
+    }
 
     private Handler mHandler = new Handler() {
 
@@ -1644,7 +1652,17 @@
                     break;
                 case EVENT_NEW_RINGING_CONNECTION:
                     if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_NEW_RINGING_CONNECTION)");
-                    mNewRingingConnectionRegistrants.notifyRegistrants((AsyncResult) msg.obj);
+                    if (getActiveFgCallState().isDialing() || hasMoreThanOneRingingCall()) {
+                        Connection c = (Connection) ((AsyncResult) msg.obj).result;
+                        try {
+                            Log.d(LOG_TAG, "silently drop incoming call: " + c.getCall());
+                            c.getCall().hangup();
+                        } catch (CallStateException e) {
+                            Log.w(LOG_TAG, "new ringing connection", e);
+                        }
+                    } else {
+                        mNewRingingConnectionRegistrants.notifyRegistrants((AsyncResult) msg.obj);
+                    }
                     break;
                 case EVENT_UNKNOWN_CONNECTION:
                     if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_UNKNOWN_CONNECTION)");
diff --git a/telephony/java/com/android/internal/telephony/CallerInfo.java b/telephony/java/com/android/internal/telephony/CallerInfo.java
index 1e9b930..f7506c6 100644
--- a/telephony/java/com/android/internal/telephony/CallerInfo.java
+++ b/telephony/java/com/android/internal/telephony/CallerInfo.java
@@ -260,6 +260,7 @@
         Uri contactUri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number));
 
         CallerInfo info = getCallerInfo(context, contactUri);
+        info = doSecondaryLookupIfNecessary(context, number, info);
 
         // if no query results were returned with a viable number,
         // fill in the original number value we used to query with.
@@ -271,6 +272,30 @@
     }
 
     /**
+     * Performs another lookup if previous lookup fails and it's a SIP call
+     * and the peer's username is all numeric. Look up the username as it
+     * could be a PSTN number in the contact database.
+     *
+     * @param context the query context
+     * @param number the original phone number, could be a SIP URI
+     * @param previousResult the result of previous lookup
+     * @return previousResult if it's not the case
+     */
+    static CallerInfo doSecondaryLookupIfNecessary(Context context,
+            String number, CallerInfo previousResult) {
+        if (!previousResult.contactExists
+                && PhoneNumberUtils.isUriNumber(number)) {
+            String username = number.substring(0, number.indexOf('@'));
+            if (PhoneNumberUtils.isGlobalPhoneNumber(username)) {
+                previousResult = getCallerInfo(context,
+                        Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI,
+                                Uri.encode(username)));
+            }
+        }
+        return previousResult;
+    }
+
+    /**
      * getCallerId: a convenience method to get the caller id for a given
      * number.
      *
@@ -402,6 +427,7 @@
                 .append("\nisCachedPhotoCurrent: " + isCachedPhotoCurrent)
                 .append("\nemergency: " + mIsEmergency)
                 .append("\nvoicemail " + mIsVoiceMail)
+                .append("\ncontactExists " + contactExists)
                 .toString();
     }
 }
diff --git a/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java b/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java
index 9561c6e..79bb832 100644
--- a/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java
+++ b/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java
@@ -230,6 +230,14 @@
                     mCallerInfo = CallerInfo.getCallerInfo(mQueryContext, mQueryUri, cursor);
                     if (DBG) Log.d(LOG_TAG, "==> Got mCallerInfo: " + mCallerInfo);
 
+                    CallerInfo newCallerInfo = CallerInfo.doSecondaryLookupIfNecessary(
+                            mQueryContext, cw.number, mCallerInfo);
+                    if (newCallerInfo != mCallerInfo) {
+                        mCallerInfo = newCallerInfo;
+                        if (DBG) Log.d(LOG_TAG, "#####async contact look up with numeric username"
+                                + mCallerInfo);
+                    }
+
                     // Use the number entered by the user for display.
                     if (!TextUtils.isEmpty(cw.number)) {
                         mCallerInfo.phoneNumber = PhoneNumberUtils.formatNumber(cw.number);
diff --git a/telephony/java/com/android/internal/telephony/sip/SipConnectionBase.java b/telephony/java/com/android/internal/telephony/sip/SipConnectionBase.java
index d546a08..154a334 100644
--- a/telephony/java/com/android/internal/telephony/sip/SipConnectionBase.java
+++ b/telephony/java/com/android/internal/telephony/sip/SipConnectionBase.java
@@ -49,7 +49,7 @@
      * calculating deltas.
      */
     private long connectTimeReal;
-    private long duration;
+    private long duration = -1L;
     private long holdingStartTime;  // The time when the Connection last transitioned
                             // into HOLDING
 
@@ -74,7 +74,7 @@
                 }
                 break;
             case DISCONNECTED:
-                duration = SystemClock.elapsedRealtime() - connectTimeReal;
+                duration = getDurationMillis();
                 disconnectTime = System.currentTimeMillis();
                 break;
             case HOLDING:
@@ -102,7 +102,7 @@
     public long getDurationMillis() {
         if (connectTimeReal == 0) {
             return 0;
-        } else if (duration == 0) {
+        } else if (duration < 0) {
             return SystemClock.elapsedRealtime() - connectTimeReal;
         } else {
             return duration;
diff --git a/telephony/java/com/android/internal/telephony/sip/SipPhone.java b/telephony/java/com/android/internal/telephony/sip/SipPhone.java
index b9a2e60..b154c91 100755
--- a/telephony/java/com/android/internal/telephony/sip/SipPhone.java
+++ b/telephony/java/com/android/internal/telephony/sip/SipPhone.java
@@ -481,7 +481,12 @@
 
         void merge(SipCall that) throws CallStateException {
             AudioGroup audioGroup = getAudioGroup();
-            for (Connection c : that.connections) {
+
+            // copy to an array to avoid concurrent modification as connections
+            // in that.connections will be removed in add(SipConnection).
+            Connection[] cc = that.connections.toArray(
+                    new Connection[that.connections.size()]);
+            for (Connection c : cc) {
                 SipConnection conn = (SipConnection) c;
                 add(conn);
                 if (conn.getState() == Call.State.HOLDING) {
@@ -714,7 +719,6 @@
             setState(Call.State.DIALING);
             mSipAudioCall = mSipManager.makeAudioCall(mProfile, mPeer, null,
                     TIMEOUT_MAKE_CALL);
-            mSipAudioCall.setRingbackToneEnabled(false);
             mSipAudioCall.setListener(mAdapter);
         }
 
@@ -799,7 +803,9 @@
         @Override
         public void separate() throws CallStateException {
             synchronized (SipPhone.class) {
-                SipCall call = (SipCall) SipPhone.this.getBackgroundCall();
+                SipCall call = (getPhone() == SipPhone.this)
+                        ? (SipCall) SipPhone.this.getBackgroundCall()
+                        : (SipCall) SipPhone.this.getForegroundCall();
                 if (call.getState() != Call.State.IDLE) {
                     throw new CallStateException(
                             "cannot put conn back to a call in non-idle state: "
@@ -809,10 +815,20 @@
                         + mPeer.getUriString() + " from " + mOwner + " back to "
                         + call);
 
+                // separate the AudioGroup and connection from the original call
+                Phone originalPhone = getPhone();
                 AudioGroup audioGroup = call.getAudioGroup(); // may be null
                 call.add(this);
                 mSipAudioCall.setAudioGroup(audioGroup);
-                call.hold();
+
+                // put the original call to bg; and the separated call becomes
+                // fg if it was in bg
+                originalPhone.switchHoldingAndActive();
+
+                // start audio and notify the phone app of the state change
+                call = (SipCall) SipPhone.this.getForegroundCall();
+                mSipAudioCall.startAudio();
+                call.onConnectionStateChanged(this);
             }
         }
 
diff --git a/voip/java/android/net/sip/SipAudioCall.java b/voip/java/android/net/sip/SipAudioCall.java
index f55bade..6a4014f 100644
--- a/voip/java/android/net/sip/SipAudioCall.java
+++ b/voip/java/android/net/sip/SipAudioCall.java
@@ -18,10 +18,6 @@
 
 import android.content.Context;
 import android.media.AudioManager;
-import android.media.Ringtone;
-import android.media.RingtoneManager;
-import android.media.ToneGenerator;
-import android.net.Uri;
 import android.net.rtp.AudioCodec;
 import android.net.rtp.AudioGroup;
 import android.net.rtp.AudioStream;
@@ -30,8 +26,6 @@
 import android.net.wifi.WifiManager;
 import android.os.Message;
 import android.os.RemoteException;
-import android.os.Vibrator;
-import android.provider.Settings;
 import android.util.Log;
 
 import java.io.IOException;
@@ -47,6 +41,16 @@
  * facilitates instantiating a {@code SipAudioCall} object for making/receiving
  * calls. See {@link SipManager#makeAudioCall} and
  * {@link SipManager#takeAudioCall}.
+ *
+ * <p>Requires permissions to use this class:
+ *   {@link android.Manifest.permission#INTERNET} and
+ *   {@link android.Manifest.permission#USE_SIP}.
+ * <br/>Requires permissions to {@link #startAudio}:
+ *   {@link android.Manifest.permission#RECORD_AUDIO},
+ *   {@link android.Manifest.permission#ACCESS_WIFI_STATE} and
+ *   {@link android.Manifest.permission#WAKE_LOCK}.
+ * <br/>Requires permissions to {@link #setSpeakerMode}:
+ *   {@link android.Manifest.permission#MODIFY_AUDIO_SETTINGS}.
  */
 public class SipAudioCall {
     private static final String TAG = SipAudioCall.class.getSimpleName();
@@ -175,11 +179,6 @@
     private boolean mMuted = false;
     private boolean mHold = false;
 
-    private boolean mRingbackToneEnabled = true;
-    private boolean mRingtoneEnabled = true;
-    private Ringtone mRingtone;
-    private ToneGenerator mRingbackTone;
-
     private SipProfile mPendingCallRequest;
     private WifiManager mWm;
     private WifiManager.WifiLock mWifiHighPerfLock;
@@ -285,8 +284,6 @@
 
     private synchronized void close(boolean closeRtp) {
         if (closeRtp) stopCall(RELEASE_SOCKET);
-        stopRingbackTone();
-        stopRinging();
 
         mInCall = false;
         mHold = false;
@@ -366,7 +363,6 @@
             @Override
             public void onRingingBack(SipSession session) {
                 Log.d(TAG, "sip call ringing back: " + session);
-                if (!mInCall) startRingbackTone();
                 Listener listener = mListener;
                 if (listener != null) {
                     try {
@@ -403,8 +399,6 @@
             @Override
             public void onCallEstablished(SipSession session,
                     String sessionDescription) {
-                stopRingbackTone();
-                stopRinging();
                 mPeerSd = sessionDescription;
                 Log.v(TAG, "onCallEstablished()" + mPeerSd);
 
@@ -533,10 +527,6 @@
             Log.v(TAG, "attachCall()" + mPeerSd);
             try {
                 session.setListener(createListener());
-
-                if (getState() == SipSession.State.INCOMING_CALL) {
-                    startRinging();
-                }
             } catch (Throwable e) {
                 Log.e(TAG, "attachCall()", e);
                 throwSipException(e);
@@ -580,7 +570,6 @@
      */
     public void endCall() throws SipException {
         synchronized (this) {
-            stopRinging();
             stopCall(RELEASE_SOCKET);
             mInCall = false;
 
@@ -625,7 +614,6 @@
      */
     public void answerCall(int timeout) throws SipException {
         synchronized (this) {
-            stopRinging();
             try {
                 mAudioStream = new AudioStream(InetAddress.getByName(
                         getLocalIp()));
@@ -796,7 +784,11 @@
         }
     }
 
-    /** Puts the device to speaker mode. */
+    /**
+     * Puts the device to speaker mode.
+     * <p>Requires permission:
+     *   {@link android.Manifest.permission#MODIFY_AUDIO_SETTINGS}.
+     */
     public void setSpeakerMode(boolean speakerMode) {
         synchronized (this) {
             ((AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE))
@@ -896,6 +888,10 @@
     /**
      * Starts the audio for the established call. This method should be called
      * after {@link Listener#onCallEstablished} is called.
+     * <p>Requires permission:
+     *   {@link android.Manifest.permission#RECORD_AUDIO},
+     *   {@link android.Manifest.permission#ACCESS_WIFI_STATE} and
+     *   {@link android.Manifest.permission#WAKE_LOCK}.
      */
     public void startAudio() {
         try {
@@ -1024,69 +1020,6 @@
         return mSipSession.getLocalIp();
     }
 
-
-    /**
-     * Enables/disables the ring-back tone.
-     *
-     * @param enabled true to enable; false to disable
-     */
-    public void setRingbackToneEnabled(boolean enabled) {
-        synchronized (this) {
-            mRingbackToneEnabled = enabled;
-        }
-    }
-
-    /**
-     * Enables/disables the ring tone.
-     *
-     * @param enabled true to enable; false to disable
-     */
-    public void setRingtoneEnabled(boolean enabled) {
-        synchronized (this) {
-            mRingtoneEnabled = enabled;
-        }
-    }
-
-    private void startRingbackTone() {
-        if (!mRingbackToneEnabled) return;
-        if (mRingbackTone == null) {
-            // The volume relative to other sounds in the stream
-            int toneVolume = 80;
-            mRingbackTone = new ToneGenerator(
-                    AudioManager.STREAM_VOICE_CALL, toneVolume);
-        }
-        mRingbackTone.startTone(ToneGenerator.TONE_CDMA_LOW_PBX_L);
-    }
-
-    private void stopRingbackTone() {
-        if (mRingbackTone != null) {
-            mRingbackTone.stopTone();
-            mRingbackTone.release();
-            mRingbackTone = null;
-        }
-    }
-
-    private void startRinging() {
-        if (!mRingtoneEnabled) return;
-        ((Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE))
-                .vibrate(new long[] {0, 1000, 1000}, 1);
-        AudioManager am = (AudioManager)
-                mContext.getSystemService(Context.AUDIO_SERVICE);
-        if (am.getStreamVolume(AudioManager.STREAM_RING) > 0) {
-            String ringtoneUri =
-                    Settings.System.DEFAULT_RINGTONE_URI.toString();
-            mRingtone = RingtoneManager.getRingtone(mContext,
-                    Uri.parse(ringtoneUri));
-            mRingtone.play();
-        }
-    }
-
-    private void stopRinging() {
-        ((Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE))
-                .cancel();
-        if (mRingtone != null) mRingtone.stop();
-    }
-
     private void throwSipException(Throwable throwable) throws SipException {
         if (throwable instanceof SipException) {
             throw (SipException) throwable;
diff --git a/voip/java/android/net/sip/SipManager.java b/voip/java/android/net/sip/SipManager.java
index 2f03e34..38d2b0c 100644
--- a/voip/java/android/net/sip/SipManager.java
+++ b/voip/java/android/net/sip/SipManager.java
@@ -50,6 +50,9 @@
  * </ul>
  * {@code SipManager} can only be instantiated if SIP API is supported by the
  * device. (See {@link #isApiSupported}).
+ * <p>Requires permissions to use this class:
+ *   {@link android.Manifest.permission#INTERNET} and
+ *   {@link android.Manifest.permission#USE_SIP}.
  */
 public class SipManager {
     /**
@@ -351,17 +354,6 @@
     }
 
     /**
-     * The method calls {@code takeAudioCall(incomingCallIntent,
-     * listener, true}.
-     *
-     * @see #takeAudioCall(Intent, SipAudioCall.Listener, boolean)
-     */
-    public SipAudioCall takeAudioCall(Intent incomingCallIntent,
-            SipAudioCall.Listener listener) throws SipException {
-        return takeAudioCall(incomingCallIntent, listener, true);
-    }
-
-    /**
      * Creates a {@link SipAudioCall} to take an incoming call. Before the call
      * is returned, the listener will receive a
      * {@link SipAudioCall.Listener#onRinging}
@@ -374,8 +366,7 @@
      * @throws SipException if calling the SIP service results in an error
      */
     public SipAudioCall takeAudioCall(Intent incomingCallIntent,
-            SipAudioCall.Listener listener, boolean ringtoneEnabled)
-            throws SipException {
+            SipAudioCall.Listener listener) throws SipException {
         if (incomingCallIntent == null) return null;
 
         String callId = getCallId(incomingCallIntent);
@@ -394,7 +385,6 @@
             if (session == null) return null;
             SipAudioCall call = new SipAudioCall(
                     mContext, session.getLocalProfile());
-            call.setRingtoneEnabled(ringtoneEnabled);
             call.attachCall(new SipSession(session), offerSd);
             call.setListener(listener);
             return call;