diff --git a/Android.mk b/Android.mk
index f45f977..d684cd3 100644
--- a/Android.mk
+++ b/Android.mk
@@ -78,8 +78,9 @@
 	core/java/android/app/IThumbnailReceiver.aidl \
 	core/java/android/app/IThumbnailRetriever.aidl \
 	core/java/android/app/ITransientNotification.aidl \
+	core/java/android/app/IUiAutomationConnection.aidl \
 	core/java/android/app/IUiModeManager.aidl \
-    core/java/android/app/IUserSwitchObserver.aidl \
+	core/java/android/app/IUserSwitchObserver.aidl \
 	core/java/android/app/IWallpaperManager.aidl \
 	core/java/android/app/IWallpaperManagerCallback.aidl \
 	core/java/android/app/admin/IDevicePolicyManager.aidl \
@@ -219,10 +220,7 @@
 	telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl \
 	telephony/java/com/android/internal/telephony/IWapPushManager.aidl \
 	wifi/java/android/net/wifi/IWifiManager.aidl \
-	wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl \
-	voip/java/android/net/sip/ISipSession.aidl \
-	voip/java/android/net/sip/ISipSessionListener.aidl \
-	voip/java/android/net/sip/ISipService.aidl
+	wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl
 #
 
 
@@ -353,6 +351,8 @@
 	../../external/apache-http/src/org/apache/http \
 	../opt/telephony/src/java/android/telephony \
 	../opt/telephony/src/java/android/telephony/gsm \
+	../opt/net/voip/src/java/android/net/rtp \
+	../opt/net/voip/src/java/android/net/sip
 
 # These are relative to frameworks/base
 dirs_to_check_apis := \
@@ -405,6 +405,7 @@
 			framework \
 			mms-common \
 			telephony-common \
+			voip-common \
 
 framework_docs_LOCAL_MODULE_CLASS := JAVA_LIBRARIES
 framework_docs_LOCAL_DROIDDOC_HTML_DIR := docs/html
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 06f7c54..2c7d16f 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -149,6 +149,11 @@
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/view/IDisplayMagnificationController.P)
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/view/IDisplayMagnificationMediator.java)
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/view/IDisplayMagnificationMediator.P)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/voip)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/librtp_jni_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/librtp_jni.so)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/lib/librtp_jni.so)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/symbols/system/lib/librtp_jni.so)
 
 # ************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
diff --git a/api/current.txt b/api/current.txt
index fc60f94..fab07f6 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -2104,6 +2104,7 @@
     field public static final int FEEDBACK_SPOKEN = 1; // 0x1
     field public static final int FEEDBACK_VISUAL = 8; // 0x8
     field public static final int FLAG_INCLUDE_NOT_IMPORTANT_VIEWS = 2; // 0x2
+    field public static final int FLAG_REPORT_VIEW_IDS = 8; // 0x8
     field public static final int FLAG_REQUEST_TOUCH_EXPLORATION_MODE = 4; // 0x4
     field public int eventTypes;
     field public int feedbackType;
@@ -3587,6 +3588,7 @@
     method public android.content.ComponentName getComponentName();
     method public android.content.Context getContext();
     method public android.content.Context getTargetContext();
+    method public android.app.UiAutomation getUiAutomation();
     method public boolean invokeContextMenuAction(android.app.Activity, int, int);
     method public boolean invokeMenuActionSync(android.app.Activity, int, int);
     method public boolean isProfiling();
@@ -4144,6 +4146,26 @@
     method public abstract void onTimeSet(android.widget.TimePicker, int, int);
   }
 
+  public final class UiAutomation {
+    method public android.view.accessibility.AccessibilityEvent executeAndWaitForEvent(java.lang.Runnable, com.android.internal.util.Predicate<android.view.accessibility.AccessibilityEvent>, long) throws java.util.concurrent.TimeoutException;
+    method public android.view.accessibility.AccessibilityNodeInfo getRootInActiveWindow();
+    method public boolean injectInputEvent(android.view.InputEvent, boolean);
+    method public void setOnAccessibilityEventListener(android.app.UiAutomation.OnAccessibilityEventListener);
+    method public boolean setRotation(int);
+    method public android.graphics.Bitmap takeScreenshot();
+    method public void waitForIdle(long, long) throws java.util.concurrent.TimeoutException;
+    field public static final int ROTATION_FREEZE_0 = 0; // 0x0
+    field public static final int ROTATION_FREEZE_180 = 2; // 0x2
+    field public static final int ROTATION_FREEZE_270 = 3; // 0x3
+    field public static final int ROTATION_FREEZE_90 = 1; // 0x1
+    field public static final int ROTATION_FREEZE_CURRENT = -1; // 0xffffffff
+    field public static final int ROTATION_UNFREEZE = -2; // 0xfffffffe
+  }
+
+  public static abstract interface UiAutomation.OnAccessibilityEventListener {
+    method public abstract void onAccessibilityEvent(android.view.accessibility.AccessibilityEvent);
+  }
+
   public class UiModeManager {
     method public void disableCarMode(int);
     method public void enableCarMode(int);
@@ -21308,6 +21330,7 @@
     ctor public InstrumentationTestRunner();
     method public junit.framework.TestSuite getAllTests();
     method protected android.test.AndroidTestRunner getAndroidTestRunner();
+    method public android.os.Bundle getArguments();
     method public java.lang.ClassLoader getLoader();
     method public junit.framework.TestSuite getTestSuite();
     field public static final java.lang.String REPORT_KEY_NAME_CLASS = "class";
@@ -26254,6 +26277,7 @@
     method public void addChild(android.view.View, int);
     method public int describeContents();
     method public java.util.List<android.view.accessibility.AccessibilityNodeInfo> findAccessibilityNodeInfosByText(java.lang.String);
+    method public java.util.List<android.view.accessibility.AccessibilityNodeInfo> findAccessibilityNodeInfosByViewId(java.lang.String);
     method public android.view.accessibility.AccessibilityNodeInfo findFocus(int);
     method public android.view.accessibility.AccessibilityNodeInfo focusSearch(int);
     method public int getActions();
@@ -26269,6 +26293,7 @@
     method public java.lang.CharSequence getPackageName();
     method public android.view.accessibility.AccessibilityNodeInfo getParent();
     method public java.lang.CharSequence getText();
+    method public java.lang.CharSequence getViewId();
     method public int getWindowId();
     method public boolean isAccessibilityFocused();
     method public boolean isCheckable();
@@ -26316,6 +26341,7 @@
     method public void setSource(android.view.View);
     method public void setSource(android.view.View, int);
     method public void setText(java.lang.CharSequence);
+    method public void setViewId(java.lang.CharSequence);
     method public void setVisibleToUser(boolean);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final int ACTION_ACCESSIBILITY_FOCUS = 64; // 0x40
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java
index add7a23..b5574cf 100644
--- a/cmds/am/src/com/android/commands/am/Am.java
+++ b/cmds/am/src/com/android/commands/am/Am.java
@@ -24,6 +24,7 @@
 import android.app.IActivityManager;
 import android.app.IInstrumentationWatcher;
 import android.app.Instrumentation;
+import android.app.UiAutomationConnection;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.IIntentReceiver;
@@ -661,10 +662,13 @@
         if (cn == null) throw new IllegalArgumentException("Bad component name: " + cnArg);
 
         InstrumentationWatcher watcher = null;
+        UiAutomationConnection connection = null;
         if (wait) {
             watcher = new InstrumentationWatcher();
             watcher.setRawOutput(rawMode);
+            connection = new UiAutomationConnection();
         }
+
         float[] oldAnims = null;
         if (no_window_animation) {
             oldAnims = wm.getAnimationScales();
@@ -672,7 +676,7 @@
             wm.setAnimationScale(1, 0.0f);
         }
 
-        if (!mAm.startInstrumentation(cn, profileFile, 0, args, watcher, userId)) {
+        if (!mAm.startInstrumentation(cn, profileFile, 0, args, watcher, connection, userId)) {
             throw new AndroidException("INSTRUMENTATION_FAILED: " + cn.flattenToString());
         }
 
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index 7efe189..8dddbc1 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -339,7 +339,10 @@
 
     private static final String LOG_TAG = "AccessibilityService";
 
-    interface Callbacks {
+    /**
+     * @hide
+     */
+    public interface Callbacks {
         public void onAccessibilityEvent(AccessibilityEvent event);
         public void onInterrupt();
         public void onServiceConnected();
@@ -538,8 +541,10 @@
     /**
      * Implements the internal {@link IAccessibilityServiceClient} interface to convert
      * incoming calls to it back to calls on an {@link AccessibilityService}.
+     *
+     * @hide
      */
-    static class IAccessibilityServiceClientWrapper extends IAccessibilityServiceClient.Stub
+    public static class IAccessibilityServiceClientWrapper extends IAccessibilityServiceClient.Stub
             implements HandlerCaller.Callback {
 
         static final int NO_ID = -1;
@@ -610,6 +615,7 @@
                         mCallback.onServiceConnected();
                     } else {
                         AccessibilityInteractionClient.getInstance().removeConnection(connectionId);
+                        AccessibilityInteractionClient.getInstance().clearCache();
                         mCallback.onSetConnectionId(AccessibilityInteractionClient.NO_ID);
                     }
                     return;
diff --git a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
index 75a4f83..2006bc7 100644
--- a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
+++ b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
@@ -33,6 +33,7 @@
 import android.util.Xml;
 import android.view.View;
 import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityNodeInfo;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
@@ -152,6 +153,15 @@
     public static final int FLAG_REQUEST_TOUCH_EXPLORATION_MODE= 0x0000004;
 
     /**
+     * This flag requests that the {@link AccessibilityNodeInfo}s obtained
+     * by an {@link AccessibilityService} contain the id of the source view.
+     * The source view id will be a fully qualified resource name of the
+     * form "package:id/name", for example "foo.bar:id/my_list", and it is
+     * useful for UI test automation. This flag is not set by default.
+     */
+    public static final int FLAG_REPORT_VIEW_IDS = 0x00000008;
+
+    /**
      * The event types an {@link AccessibilityService} is interested in.
      * <p>
      *   <strong>Can be dynamically set at runtime.</strong>
diff --git a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
index f33f503..7a29f35 100644
--- a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
+++ b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
@@ -85,15 +85,15 @@
      *     where to start the search. Use
      *     {@link android.view.accessibility.AccessibilityNodeInfo#ROOT_NODE_ID}
      *     to start from the root.
-     * @param id The id of the node.
+     * @param viewId The fully qualified resource name of the view id to find.
      * @param interactionId The id of the interaction for matching with the callback result.
      * @param callback Callback which to receive the result.
      * @param threadId The id of the calling thread.
      * @return Whether the call succeeded.
      */
-    boolean findAccessibilityNodeInfoByViewId(int accessibilityWindowId, long accessibilityNodeId,
-        int viewId, int interactionId, IAccessibilityInteractionConnectionCallback callback,
-        long threadId);
+    boolean findAccessibilityNodeInfosByViewId(int accessibilityWindowId,
+        long accessibilityNodeId, String viewId, int interactionId,
+        IAccessibilityInteractionConnectionCallback callback, long threadId);
 
     /**
      * Finds the {@link android.view.accessibility.AccessibilityNodeInfo} that has the specified
diff --git a/core/java/android/accessibilityservice/UiTestAutomationBridge.java b/core/java/android/accessibilityservice/UiTestAutomationBridge.java
deleted file mode 100644
index 6837386..0000000
--- a/core/java/android/accessibilityservice/UiTestAutomationBridge.java
+++ /dev/null
@@ -1,496 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-package android.accessibilityservice;
-
-import android.accessibilityservice.AccessibilityService.Callbacks;
-import android.accessibilityservice.AccessibilityService.IAccessibilityServiceClientWrapper;
-import android.content.Context;
-import android.os.Bundle;
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.os.SystemClock;
-import android.util.Log;
-import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityInteractionClient;
-import android.view.accessibility.AccessibilityNodeInfo;
-import android.view.accessibility.IAccessibilityManager;
-
-import com.android.internal.util.Predicate;
-
-import java.util.List;
-import java.util.concurrent.TimeoutException;
-
-/**
- * This class represents a bridge that can be used for UI test
- * automation. It is responsible for connecting to the system,
- * keeping track of the last accessibility event, and exposing
- * window content querying APIs. This class is designed to be
- * used from both an Android application and a Java program
- * run from the shell.
- *
- * @hide
- */
-public class UiTestAutomationBridge {
-
-    private static final String LOG_TAG = UiTestAutomationBridge.class.getSimpleName();
-
-    private static final int TIMEOUT_REGISTER_SERVICE = 5000;
-
-    public static final int ACTIVE_WINDOW_ID = AccessibilityNodeInfo.ACTIVE_WINDOW_ID;
-
-    public static final long ROOT_NODE_ID = AccessibilityNodeInfo.ROOT_NODE_ID;
-
-    public static final int UNDEFINED = -1;
-
-    private static final int FIND_ACCESSIBILITY_NODE_INFO_PREFETCH_FLAGS =
-        AccessibilityNodeInfo.FLAG_PREFETCH_PREDECESSORS
-        | AccessibilityNodeInfo.FLAG_PREFETCH_SIBLINGS
-        | AccessibilityNodeInfo.FLAG_PREFETCH_DESCENDANTS;
-
-    private final Object mLock = new Object();
-
-    private volatile int mConnectionId = AccessibilityInteractionClient.NO_ID;
-
-    private IAccessibilityServiceClientWrapper mListener;
-
-    private AccessibilityEvent mLastEvent;
-
-    private volatile boolean mWaitingForEventDelivery;
-
-    private volatile boolean mUnprocessedEventAvailable;
-
-    private HandlerThread mHandlerThread;
-
-    /**
-     * Gets the last received {@link AccessibilityEvent}.
-     *
-     * @return The event.
-     */
-    public AccessibilityEvent getLastAccessibilityEvent() {
-        return mLastEvent;
-    }
-
-    /**
-     * Callback for receiving an {@link AccessibilityEvent}.
-     *
-     * <strong>Note:</strong> This method is <strong>NOT</strong>
-     * executed on the application main thread. The client are
-     * responsible for proper synchronization.
-     *
-     * @param event The received event.
-     */
-    public void onAccessibilityEvent(AccessibilityEvent event) {
-        /* hook - do nothing */
-    }
-
-    /**
-     * Callback for requests to stop feedback.
-     *
-     * <strong>Note:</strong> This method is <strong>NOT</strong>
-     * executed on the application main thread. The client are
-     * responsible for proper synchronization.
-     */
-    public void onInterrupt() {
-        /* hook - do nothing */
-    }
-
-    /**
-     * Connects this service.
-     *
-     * @throws IllegalStateException If already connected.
-     */
-    public void connect() {
-        if (isConnected()) {
-            throw new IllegalStateException("Already connected.");
-        }
-
-        // Serialize binder calls to a handler on a dedicated thread
-        // different from the main since we expose APIs that block
-        // the main thread waiting for a result the deliver of which
-        // on the main thread will prevent that thread from waking up.
-        // The serialization is needed also to ensure that events are
-        // examined in delivery order. Otherwise, a fair locking
-        // is needed for making sure the binder calls are interleaved
-        // with check for the expected event and also to make sure the
-        // binder threads are allowed to proceed in the received order.
-        mHandlerThread = new HandlerThread("UiTestAutomationBridge");
-        mHandlerThread.setDaemon(true);
-        mHandlerThread.start();
-        Looper looper = mHandlerThread.getLooper();
-
-        mListener = new IAccessibilityServiceClientWrapper(null, looper, new Callbacks() {
-            @Override
-            public void onServiceConnected() {
-                /* do nothing */
-            }
-
-            @Override
-            public void onInterrupt() {
-                UiTestAutomationBridge.this.onInterrupt();
-            }
-
-            @Override
-            public void onAccessibilityEvent(AccessibilityEvent event) {
-                synchronized (mLock) {
-                    while (true) {
-                        mLastEvent = AccessibilityEvent.obtain(event);
-                        if (!mWaitingForEventDelivery) {
-                            mLock.notifyAll();
-                            break;
-                        }
-                        if (!mUnprocessedEventAvailable) {
-                            mUnprocessedEventAvailable = true;
-                            mLock.notifyAll();
-                            break;
-                        }
-                        try {
-                            mLock.wait();
-                        } catch (InterruptedException ie) {
-                            /* ignore */
-                        }
-                    }
-                }
-                UiTestAutomationBridge.this.onAccessibilityEvent(event);
-            }
-
-            @Override
-            public void onSetConnectionId(int connectionId) {
-                synchronized (mLock) {
-                    mConnectionId = connectionId;
-                    mLock.notifyAll();
-                }
-            }
-
-            @Override
-            public boolean onGesture(int gestureId) {
-                return false;
-            }
-        });
-
-        final IAccessibilityManager manager = IAccessibilityManager.Stub.asInterface(
-                ServiceManager.getService(Context.ACCESSIBILITY_SERVICE));
-
-        final AccessibilityServiceInfo info = new AccessibilityServiceInfo();
-        info.eventTypes = AccessibilityEvent.TYPES_ALL_MASK;
-        info.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC;
-        info.flags |= AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;
-
-        try {
-            manager.registerUiTestAutomationService(mListener, info);
-        } catch (RemoteException re) {
-            throw new IllegalStateException("Cound not register UiAutomationService.", re);
-        }
-
-        synchronized (mLock) {
-            final long startTimeMillis = SystemClock.uptimeMillis();
-            while (true) {
-                if (isConnected()) {
-                    return;
-                }
-                final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
-                final long remainingTimeMillis = TIMEOUT_REGISTER_SERVICE - elapsedTimeMillis;
-                if (remainingTimeMillis <= 0) {
-                    throw new IllegalStateException("Cound not register UiAutomationService.");
-                }
-                try {
-                    mLock.wait(remainingTimeMillis);
-                } catch (InterruptedException ie) {
-                    /* ignore */
-                }
-            }
-        }
-    }
-
-    /**
-     * Disconnects this service.
-     *
-     * @throws IllegalStateException If already disconnected.
-     */
-    public void disconnect() {
-        if (!isConnected()) {
-            throw new IllegalStateException("Already disconnected.");
-        }
-
-        mHandlerThread.quit();
-
-        IAccessibilityManager manager = IAccessibilityManager.Stub.asInterface(
-              ServiceManager.getService(Context.ACCESSIBILITY_SERVICE));
-
-        try {
-            manager.unregisterUiTestAutomationService(mListener);
-        } catch (RemoteException re) {
-            Log.e(LOG_TAG, "Error while unregistering UiTestAutomationService", re);
-        }
-    }
-
-    /**
-     * Gets whether this service is connected.
-     *
-     * @return True if connected.
-     */
-    public boolean isConnected() {
-        return (mConnectionId != AccessibilityInteractionClient.NO_ID);
-    }
-
-    /**
-     * Executes a command and waits for a specific accessibility event type up
-     * to a given timeout.
-     *
-     * @param command The command to execute before starting to wait for the event.
-     * @param predicate Predicate for recognizing the awaited event.
-     * @param timeoutMillis The max wait time in milliseconds.
-     */
-    public AccessibilityEvent executeCommandAndWaitForAccessibilityEvent(Runnable command,
-            Predicate<AccessibilityEvent> predicate, long timeoutMillis)
-            throws TimeoutException, Exception {
-        // TODO: This is broken - remove from here when finalizing this as public APIs.
-        synchronized (mLock) {
-            // Prepare to wait for an event.
-            mWaitingForEventDelivery = true;
-            mUnprocessedEventAvailable = false;
-            if (mLastEvent != null) {
-                mLastEvent.recycle();
-                mLastEvent = null;
-            }
-            // Execute the command.
-            command.run();
-            // Wait for the event.
-            final long startTimeMillis = SystemClock.uptimeMillis();
-            while (true) {
-                // If the expected event is received, that's it.
-                if ((mUnprocessedEventAvailable && predicate.apply(mLastEvent))) {
-                    mWaitingForEventDelivery = false;
-                    mUnprocessedEventAvailable = false;
-                    mLock.notifyAll();
-                    return mLastEvent;
-                }
-                // Ask for another event.
-                mWaitingForEventDelivery = true;
-                mUnprocessedEventAvailable = false;
-                mLock.notifyAll();
-                // Check if timed out and if not wait.
-                final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
-                final long remainingTimeMillis = timeoutMillis - elapsedTimeMillis;
-                if (remainingTimeMillis <= 0) {
-                    mWaitingForEventDelivery = false;
-                    mUnprocessedEventAvailable = false;
-                    mLock.notifyAll();
-                    throw new TimeoutException("Expacted event not received within: "
-                            + timeoutMillis + " ms.");
-                }
-                try {
-                    mLock.wait(remainingTimeMillis);
-                } catch (InterruptedException ie) {
-                    /* ignore */
-                }
-            }
-        }
-    }
-
-    /**
-     * Waits for the accessibility event stream to become idle, which is not to
-     * have received a new accessibility event within <code>idleTimeout</code>,
-     * and do so within a maximal global timeout as specified by
-     * <code>globalTimeout</code>.
-     *
-     * @param idleTimeout The timeout between two event to consider the device idle.
-     * @param globalTimeout The maximal global timeout in which to wait for idle.
-     */
-    public void waitForIdle(long idleTimeout, long globalTimeout) {
-        final long startTimeMillis = SystemClock.uptimeMillis();
-        long lastEventTime = (mLastEvent != null)
-                ? mLastEvent.getEventTime() : SystemClock.uptimeMillis();
-        synchronized (mLock) {
-            while (true) {
-                final long currentTimeMillis = SystemClock.uptimeMillis();
-                final long sinceLastEventTimeMillis = currentTimeMillis - lastEventTime;
-                if (sinceLastEventTimeMillis > idleTimeout) {
-                    return;
-                }
-                if (mLastEvent != null) {
-                    lastEventTime = mLastEvent.getEventTime();
-                }
-                final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
-                final long remainingTimeMillis = globalTimeout - elapsedTimeMillis;
-                if (remainingTimeMillis <= 0) {
-                    return;
-                }
-                try {
-                     mLock.wait(idleTimeout);
-                } catch (InterruptedException e) {
-                     /* ignore */
-                }
-            }
-        }
-    }
-
-    /**
-     * Finds an {@link AccessibilityNodeInfo} by accessibility id in the active
-     * window. The search is performed from the root node.
-     *
-     * @param accessibilityNodeId A unique view id or virtual descendant id for
-     *     which to search.
-     * @return The current window scale, where zero means a failure.
-     */
-    public AccessibilityNodeInfo findAccessibilityNodeInfoByAccessibilityIdInActiveWindow(
-            long accessibilityNodeId) {
-        return findAccessibilityNodeInfoByAccessibilityId(ACTIVE_WINDOW_ID, accessibilityNodeId);
-    }
-
-    /**
-     * Finds an {@link AccessibilityNodeInfo} by accessibility id.
-     *
-     * @param accessibilityWindowId A unique window id. Use {@link #ACTIVE_WINDOW_ID} to query
-     *     the currently active window.
-     * @param accessibilityNodeId A unique view id or virtual descendant id for
-     *     which to search.
-     * @return The current window scale, where zero means a failure.
-     */
-    public AccessibilityNodeInfo findAccessibilityNodeInfoByAccessibilityId(
-            int accessibilityWindowId, long accessibilityNodeId) {
-        // Cache the id to avoid locking
-        final int connectionId = mConnectionId;
-        ensureValidConnection(connectionId);
-        return AccessibilityInteractionClient.getInstance()
-                .findAccessibilityNodeInfoByAccessibilityId(mConnectionId,
-                        accessibilityWindowId, accessibilityNodeId,
-                        FIND_ACCESSIBILITY_NODE_INFO_PREFETCH_FLAGS);
-    }
-
-    /**
-     * Finds an {@link AccessibilityNodeInfo} by View id in the active
-     * window. The search is performed from the root node.
-     *
-     * @param viewId The id of a View.
-     * @return The current window scale, where zero means a failure.
-     */
-    public AccessibilityNodeInfo findAccessibilityNodeInfoByViewIdInActiveWindow(int viewId) {
-        return findAccessibilityNodeInfoByViewId(ACTIVE_WINDOW_ID, ROOT_NODE_ID, viewId);
-    }
-
-    /**
-     * Finds an {@link AccessibilityNodeInfo} by View id. The search is performed in
-     * the window whose id is specified and starts from the node whose accessibility
-     * id is specified.
-     *
-     * @param accessibilityWindowId A unique window id. Use
-     *     {@link  #ACTIVE_WINDOW_ID} to query the currently active window.
-     * @param accessibilityNodeId A unique view id or virtual descendant id from
-     *     where to start the search. Use {@link  #ROOT_NODE_ID} to start from the root.
-     * @param viewId The id of a View.
-     * @return The current window scale, where zero means a failure.
-     */
-    public AccessibilityNodeInfo findAccessibilityNodeInfoByViewId(int accessibilityWindowId,
-            long accessibilityNodeId, int viewId) {
-        // Cache the id to avoid locking
-        final int connectionId = mConnectionId;
-        ensureValidConnection(connectionId);
-        return AccessibilityInteractionClient.getInstance()
-                .findAccessibilityNodeInfoByViewId(connectionId, accessibilityWindowId,
-                        accessibilityNodeId, viewId);
-    }
-
-    /**
-     * Finds {@link AccessibilityNodeInfo}s by View text in the active
-     * window. The search is performed from the root node.
-     *
-     * @param text The searched text.
-     * @return The current window scale, where zero means a failure.
-     */
-    public List<AccessibilityNodeInfo> findAccessibilityNodeInfosByTextInActiveWindow(String text) {
-        return findAccessibilityNodeInfosByText(ACTIVE_WINDOW_ID, ROOT_NODE_ID, text);
-    }
-
-    /**
-     * Finds {@link AccessibilityNodeInfo}s by View text. The match is case
-     * insensitive containment. The search is performed in the window whose
-     * id is specified and starts from the node whose accessibility id is
-     * specified.
-     *
-     * @param accessibilityWindowId A unique window id. Use
-     *     {@link #ACTIVE_WINDOW_ID} to query the currently active window.
-     * @param accessibilityNodeId A unique view id or virtual descendant id from
-     *     where to start the search. Use {@link #ROOT_NODE_ID} to start from the root.
-     * @param text The searched text.
-     * @return The current window scale, where zero means a failure.
-     */
-    public List<AccessibilityNodeInfo> findAccessibilityNodeInfosByText(int accessibilityWindowId,
-            long accessibilityNodeId, String text) {
-        // Cache the id to avoid locking
-        final int connectionId = mConnectionId;
-        ensureValidConnection(connectionId);
-        return AccessibilityInteractionClient.getInstance()
-                .findAccessibilityNodeInfosByText(connectionId, accessibilityWindowId,
-                        accessibilityNodeId, text);
-    }
-
-    /**
-     * Performs an accessibility action on an {@link AccessibilityNodeInfo}
-     * in the active window.
-     *
-     * @param accessibilityNodeId A unique node id (accessibility and virtual descendant id).
-     * @param action The action to perform.
-     * @param arguments Optional action arguments.
-     * @return Whether the action was performed.
-     */
-    public boolean performAccessibilityActionInActiveWindow(long accessibilityNodeId, int action,
-            Bundle arguments) {
-        return performAccessibilityAction(ACTIVE_WINDOW_ID, accessibilityNodeId, action, arguments);
-    }
-
-    /**
-     * Performs an accessibility action on an {@link AccessibilityNodeInfo}.
-     *
-     * @param accessibilityWindowId A unique window id. Use
-     *     {@link #ACTIVE_WINDOW_ID} to query the currently active window.
-     * @param accessibilityNodeId A unique node id (accessibility and virtual descendant id).
-     * @param action The action to perform.
-     * @param arguments Optional action arguments.
-     * @return Whether the action was performed.
-     */
-    public boolean performAccessibilityAction(int accessibilityWindowId, long accessibilityNodeId,
-            int action, Bundle arguments) {
-        // Cache the id to avoid locking
-        final int connectionId = mConnectionId;
-        ensureValidConnection(connectionId);
-        return AccessibilityInteractionClient.getInstance().performAccessibilityAction(connectionId,
-                accessibilityWindowId, accessibilityNodeId, action, arguments);
-    }
-
-    /**
-     * Gets the root {@link AccessibilityNodeInfo} in the active window.
-     *
-     * @return The root info.
-     */
-    public AccessibilityNodeInfo getRootAccessibilityNodeInfoInActiveWindow() {
-        // Cache the id to avoid locking
-        final int connectionId = mConnectionId;
-        ensureValidConnection(connectionId);
-        return AccessibilityInteractionClient.getInstance()
-                .findAccessibilityNodeInfoByAccessibilityId(connectionId, ACTIVE_WINDOW_ID,
-                        ROOT_NODE_ID, AccessibilityNodeInfo.FLAG_PREFETCH_DESCENDANTS);
-    }
-
-    private void ensureValidConnection(int connectionId) {
-        if (connectionId == UNDEFINED) {
-            throw new IllegalStateException("UiAutomationService not connected."
-                    + " Did you call #register()?");
-        }
-    }
-}
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index bc27a57d..d8e2239 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -39,7 +39,6 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.StrictMode;
-import android.os.UserHandle;
 import android.text.TextUtils;
 import android.util.Log;
 import android.util.Singleton;
@@ -836,8 +835,10 @@
             Bundle arguments = data.readBundle();
             IBinder b = data.readStrongBinder();
             IInstrumentationWatcher w = IInstrumentationWatcher.Stub.asInterface(b);
+            b = data.readStrongBinder();
+            IUiAutomationConnection c = IUiAutomationConnection.Stub.asInterface(b);
             int userId = data.readInt();
-            boolean res = startInstrumentation(className, profileFile, fl, arguments, w, userId);
+            boolean res = startInstrumentation(className, profileFile, fl, arguments, w, c, userId);
             reply.writeNoException();
             reply.writeInt(res ? 1 : 0);
             return true;
@@ -2874,8 +2875,8 @@
     }
 
     public boolean startInstrumentation(ComponentName className, String profileFile,
-            int flags, Bundle arguments, IInstrumentationWatcher watcher, int userId)
-            throws RemoteException {
+            int flags, Bundle arguments, IInstrumentationWatcher watcher,
+            IUiAutomationConnection connection, int userId) throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
@@ -2884,6 +2885,7 @@
         data.writeInt(flags);
         data.writeBundle(arguments);
         data.writeStrongBinder(watcher != null ? watcher.asBinder() : null);
+        data.writeStrongBinder(connection != null ? connection.asBinder() : null);
         data.writeInt(userId);
         mRemote.transact(START_INSTRUMENTATION_TRANSACTION, data, reply, 0);
         reply.readException();
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 570fb80..bb73cf4 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -43,7 +43,6 @@
 import android.database.sqlite.SQLiteDebug.DbStats;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
-import android.hardware.display.DisplayManager;
 import android.hardware.display.DisplayManagerGlobal;
 import android.net.IConnectivityManager;
 import android.net.Proxy;
@@ -102,7 +101,6 @@
 import java.io.PrintWriter;
 import java.lang.ref.WeakReference;
 import java.net.InetAddress;
-import java.security.Security;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
@@ -420,6 +418,7 @@
         ComponentName instrumentationName;
         Bundle instrumentationArgs;
         IInstrumentationWatcher instrumentationWatcher;
+        IUiAutomationConnection instrumentationUiAutomationConnection;
         int debugMode;
         boolean enableOpenGlTrace;
         boolean restrictedBackupMode;
@@ -730,9 +729,10 @@
                 ComponentName instrumentationName, String profileFile,
                 ParcelFileDescriptor profileFd, boolean autoStopProfiler,
                 Bundle instrumentationArgs, IInstrumentationWatcher instrumentationWatcher,
-                int debugMode, boolean enableOpenGlTrace, boolean isRestrictedBackupMode,
-                boolean persistent, Configuration config, CompatibilityInfo compatInfo,
-                Map<String, IBinder> services, Bundle coreSettings) {
+                IUiAutomationConnection instrumentationUiConnection, int debugMode,
+                boolean enableOpenGlTrace, boolean isRestrictedBackupMode, boolean persistent,
+                Configuration config, CompatibilityInfo compatInfo, Map<String, IBinder> services,
+                Bundle coreSettings) {
 
             if (services != null) {
                 // Setup the service cache in the ServiceManager
@@ -748,6 +748,7 @@
             data.instrumentationName = instrumentationName;
             data.instrumentationArgs = instrumentationArgs;
             data.instrumentationWatcher = instrumentationWatcher;
+            data.instrumentationUiAutomationConnection = instrumentationUiConnection;
             data.debugMode = debugMode;
             data.enableOpenGlTrace = enableOpenGlTrace;
             data.restrictedBackupMode = isRestrictedBackupMode;
@@ -4375,7 +4376,8 @@
             }
 
             mInstrumentation.init(this, instrContext, appContext,
-                    new ComponentName(ii.packageName, ii.name), data.instrumentationWatcher);
+                   new ComponentName(ii.packageName, ii.name), data.instrumentationWatcher,
+                   data.instrumentationUiAutomationConnection);
 
             if (mProfiler.profileFile != null && !ii.handleProfiling
                     && mProfiler.profileFd == null) {
diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java
index f0e367c..b1c58f2 100644
--- a/core/java/android/app/ApplicationThreadNative.java
+++ b/core/java/android/app/ApplicationThreadNative.java
@@ -267,6 +267,9 @@
             Bundle testArgs = data.readBundle();
             IBinder binder = data.readStrongBinder();
             IInstrumentationWatcher testWatcher = IInstrumentationWatcher.Stub.asInterface(binder);
+            binder = data.readStrongBinder();
+            IUiAutomationConnection uiAutomationConnection =
+                    IUiAutomationConnection.Stub.asInterface(binder);
             int testMode = data.readInt();
             boolean openGlTrace = data.readInt() != 0;
             boolean restrictedBackupMode = (data.readInt() != 0);
@@ -277,8 +280,9 @@
             Bundle coreSettings = data.readBundle();
             bindApplication(packageName, info,
                             providers, testName, profileName, profileFd, autoStopProfiler,
-                            testArgs, testWatcher, testMode, openGlTrace, restrictedBackupMode,
-                            persistent, config, compatInfo, services, coreSettings);
+                            testArgs, testWatcher, uiAutomationConnection, testMode,
+                            openGlTrace, restrictedBackupMode, persistent, config, compatInfo,
+                            services, coreSettings);
             return true;
         }
 
@@ -874,10 +878,11 @@
     public final void bindApplication(String packageName, ApplicationInfo info,
             List<ProviderInfo> providers, ComponentName testName, String profileName,
             ParcelFileDescriptor profileFd, boolean autoStopProfiler, Bundle testArgs,
-            IInstrumentationWatcher testWatcher, int debugMode, boolean openGlTrace,
-            boolean restrictedBackupMode, boolean persistent,
-            Configuration config, CompatibilityInfo compatInfo,
-            Map<String, IBinder> services, Bundle coreSettings) throws RemoteException {
+            IInstrumentationWatcher testWatcher,
+            IUiAutomationConnection uiAutomationConnection, int debugMode,
+            boolean openGlTrace, boolean restrictedBackupMode, boolean persistent,
+            Configuration config, CompatibilityInfo compatInfo, Map<String, IBinder> services,
+            Bundle coreSettings) throws RemoteException {
         Parcel data = Parcel.obtain();
         data.writeInterfaceToken(IApplicationThread.descriptor);
         data.writeString(packageName);
@@ -899,6 +904,7 @@
         data.writeInt(autoStopProfiler ? 1 : 0);
         data.writeBundle(testArgs);
         data.writeStrongInterface(testWatcher);
+        data.writeStrongInterface(uiAutomationConnection);
         data.writeInt(debugMode);
         data.writeInt(openGlTrace ? 1 : 0);
         data.writeInt(restrictedBackupMode ? 1 : 0);
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index fd4389e..e03d3fd 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -1475,7 +1475,7 @@
                 arguments.setAllowFds(false);
             }
             return ActivityManagerNative.getDefault().startInstrumentation(
-                    className, profileFile, 0, arguments, null, getUserId());
+                    className, profileFile, 0, arguments, null, null, getUserId());
         } catch (RemoteException e) {
             // System has crashed, nothing we can do.
         }
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index baac07f..5a493294 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -158,8 +158,8 @@
     public void killApplicationProcess(String processName, int uid) throws RemoteException;
     
     public boolean startInstrumentation(ComponentName className, String profileFile,
-            int flags, Bundle arguments, IInstrumentationWatcher watcher, int userId)
-            throws RemoteException;
+            int flags, Bundle arguments, IInstrumentationWatcher watcher,
+            IUiAutomationConnection connection, int userId) throws RemoteException;
     public void finishInstrumentation(IApplicationThread target,
             int resultCode, Bundle results) throws RemoteException;
 
diff --git a/core/java/android/app/IApplicationThread.java b/core/java/android/app/IApplicationThread.java
index 8516694..3189b31a 100644
--- a/core/java/android/app/IApplicationThread.java
+++ b/core/java/android/app/IApplicationThread.java
@@ -90,7 +90,8 @@
     void bindApplication(String packageName, ApplicationInfo info, List<ProviderInfo> providers,
             ComponentName testName, String profileName, ParcelFileDescriptor profileFd,
             boolean autoStopProfiler, Bundle testArguments, IInstrumentationWatcher testWatcher,
-            int debugMode, boolean openGlTrace, boolean restrictedBackupMode, boolean persistent,
+            IUiAutomationConnection uiAutomationConnection, int debugMode,
+            boolean openGlTrace, boolean restrictedBackupMode, boolean persistent,
             Configuration config, CompatibilityInfo compatInfo, Map<String, IBinder> services,
             Bundle coreSettings) throws RemoteException;
     void scheduleExit() throws RemoteException;
diff --git a/core/java/android/app/IUiAutomationConnection.aidl b/core/java/android/app/IUiAutomationConnection.aidl
new file mode 100644
index 0000000..09bf829
--- /dev/null
+++ b/core/java/android/app/IUiAutomationConnection.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+
+package android.app;
+
+import android.accessibilityservice.IAccessibilityServiceClient;
+import android.graphics.Bitmap;
+import android.view.InputEvent;
+import android.os.ParcelFileDescriptor;
+
+/**
+ * This interface contains privileged operations a shell program can perform
+ * on behalf of an instrumentation that it runs. These operations require
+ * special permissions which the shell user has but the instrumentation does
+ * not. Running privileged operations by the shell user on behalf of an
+ * instrumentation is needed for running UiTestCases. 
+ *
+ * {@hide}
+ */
+interface IUiAutomationConnection {
+    void connect(IAccessibilityServiceClient client);
+    void disconnect();
+    boolean injectInputEvent(in InputEvent event, boolean sync);
+    boolean setRotation(int rotation);
+    Bitmap takeScreenshot(int width, int height);
+    void shutdown();
+}
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
index 39186c6..a2eeddd 100644
--- a/core/java/android/app/Instrumentation.java
+++ b/core/java/android/app/Instrumentation.java
@@ -49,7 +49,6 @@
 import java.util.ArrayList;
 import java.util.List;
 
-
 /**
  * Base class for implementing application instrumentation code.  When running
  * with instrumentation turned on, this class will be instantiated for you
@@ -59,6 +58,7 @@
  * &lt;instrumentation&gt; tag.
  */
 public class Instrumentation {
+
     /**
      * If included in the status or final bundle sent to an IInstrumentationWatcher, this key 
      * identifies the class that is writing the report.  This can be used to provide more structured
@@ -73,7 +73,7 @@
      * instrumentation can also be launched, and results collected, by an automated system.
      */
     public static final String REPORT_KEY_STREAMRESULT = "stream";
-    
+
     private static final String TAG = "Instrumentation";
     
     private final Object mSync = new Object();
@@ -86,9 +86,11 @@
     private List<ActivityWaiter> mWaitingActivities;
     private List<ActivityMonitor> mActivityMonitors;
     private IInstrumentationWatcher mWatcher;
+    private IUiAutomationConnection mUiAutomationConnection;
     private boolean mAutomaticPerformanceSnapshots = false;
     private PerformanceCollector mPerformanceCollector;
     private Bundle mPerfMetrics = new Bundle();
+    private UiAutomation mUiAutomation;
 
     public Instrumentation() {
     }
@@ -1598,13 +1600,14 @@
 
     /*package*/ final void init(ActivityThread thread,
             Context instrContext, Context appContext, ComponentName component, 
-            IInstrumentationWatcher watcher) {
+            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection) {
         mThread = thread;
         mMessageQueue = mThread.getLooper().myQueue();
         mInstrContext = instrContext;
         mAppContext = appContext;
         mComponent = component;
         mWatcher = watcher;
+        mUiAutomationConnection = uiAutomationConnection;
     }
 
     /*package*/ static void checkStartActivityResult(int res, Object intent) {
@@ -1644,12 +1647,42 @@
         }
     }
 
+    /**
+     * Gets the {@link UiAutomation} instance.
+     * <p>
+     * <strong>Note:</strong> The APIs exposed via the returned {@link UiAutomation}
+     * work across application boundaries while the APIs exposed by the instrumentation
+     * do not. For example, {@link Instrumentation#sendPointerSync(MotionEvent)} will
+     * not allow you to inject the event in an app different from the instrumentation
+     * target, while {@link UiAutomation#injectInputEvent(android.view.InputEvent, boolean)}
+     * will work regardless of the current application.
+     * </p>
+     * <p>
+     * A typical test case should be using either the {@link UiAutomation} or
+     * {@link Instrumentation} APIs. Using both APIs at the same time is not
+     * a mistake by itself but a client has to be aware of the APIs limitations.
+     * </p>
+     * @return The UI automation instance.
+     *
+     * @see UiAutomation
+     */
+    public UiAutomation getUiAutomation() {
+        if (mUiAutomationConnection != null) {
+            if (mUiAutomation == null) {
+                mUiAutomation = new UiAutomation(getTargetContext().getMainLooper(),
+                        mUiAutomationConnection);
+                mUiAutomation.connect();
+            }
+            return mUiAutomation;
+        }
+        return null;
+    }
+
     private final class InstrumentationThread extends Thread {
         public InstrumentationThread(String name) {
             super(name);
         }
         public void run() {
-            IActivityManager am = ActivityManagerNative.getDefault();
             try {
                 Process.setThreadPriority(Process.THREAD_PRIORITY_URGENT_DISPLAY);
             } catch (RuntimeException e) {
@@ -1660,9 +1693,13 @@
                 startPerformanceSnapshot();
             }
             onStart();
+            if (mUiAutomation != null) {
+                mUiAutomation.disconnect();
+                mUiAutomation = null;
+            }
         }
     }
-    
+
     private static final class EmptyRunnable implements Runnable {
         public void run() {
         }
diff --git a/core/java/android/app/UiAutomation.java b/core/java/android/app/UiAutomation.java
new file mode 100644
index 0000000..e611f6d
--- /dev/null
+++ b/core/java/android/app/UiAutomation.java
@@ -0,0 +1,597 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+
+package android.app;
+
+import android.accessibilityservice.AccessibilityService.Callbacks;
+import android.accessibilityservice.AccessibilityService.IAccessibilityServiceClientWrapper;
+import android.accessibilityservice.IAccessibilityServiceClient;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Point;
+import android.hardware.display.DisplayManagerGlobal;
+import android.os.Looper;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.util.Log;
+import android.view.Display;
+import android.view.InputEvent;
+import android.view.Surface;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityInteractionClient;
+import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.IAccessibilityInteractionConnection;
+
+import com.android.internal.util.Predicate;
+
+import java.util.ArrayList;
+import java.util.concurrent.TimeoutException;
+
+/**
+ * Class for interacting with the device's UI by simulation user actions and
+ * introspection of the screen content. It relies on the platform accessibility
+ * APIs to introspect the screen and to perform some actions on the remote view
+ * tree. It also allows injecting of arbitrary raw input events simulating user
+ * interaction with keyboards and touch devices.
+ * <p>
+ * The APIs exposed by this class are low-level to maximize flexibility when
+ * developing UI test automation tools and libraries. Generally, a UiAutomation
+ * client should be using a higher-level library or implement high-level functions.
+ * For example, performing a tap on the screen requires construction and injecting
+ * of a touch down and up events which have to be delivered to the system by a
+ * call to {@link #injectInputEvent(InputEvent, boolean)}.
+ * </p>
+ * <p>
+ * The APIs exposed by this class operate across applications enabling a client
+ * to write tests that cover use cases spanning over multiple applications. For
+ * example, going to the settings application to change a setting and then
+ * interacting with another application whose behavior depends on that setting.
+ * </p>
+ */
+public final class UiAutomation {
+
+    private static final String LOG_TAG = UiAutomation.class.getSimpleName();
+
+    private static final boolean DEBUG = false;
+
+    private static final int CONNECTION_ID_UNDEFINED = -1;
+
+    private static final long CONNECT_TIMEOUT_MILLIS = 5000;
+
+    /** Rotation constant: Unfreeze rotation (rotating the device changes its rotation state). */
+    public static final int ROTATION_UNFREEZE = -2;
+
+    /** Rotation constant: Freeze rotation to its current state. */
+    public static final int ROTATION_FREEZE_CURRENT = -1;
+
+    /** Rotation constant: Freeze rotation to 0 degrees (natural orientation) */
+    public static final int ROTATION_FREEZE_0 = Surface.ROTATION_0;
+
+    /** Rotation constant: Freeze rotation to 90 degrees . */
+    public static final int ROTATION_FREEZE_90 = Surface.ROTATION_90;
+
+    /** Rotation constant: Freeze rotation to 180 degrees . */
+    public static final int ROTATION_FREEZE_180 = Surface.ROTATION_180;
+
+    /** Rotation constant: Freeze rotation to 270 degrees . */
+    public static final int ROTATION_FREEZE_270 = Surface.ROTATION_270;
+
+    private final Object mLock = new Object();
+
+    private final ArrayList<AccessibilityEvent> mEventQueue = new ArrayList<AccessibilityEvent>();
+
+    private final IAccessibilityServiceClient mClient;
+
+    private final IUiAutomationConnection mUiAutomationConnection;
+
+    private int mConnectionId = CONNECTION_ID_UNDEFINED;
+
+    private OnAccessibilityEventListener mOnAccessibilityEventListener;
+
+    private boolean mWaitingForEventDelivery;
+
+    private long mLastEventTimeMillis;
+
+    private boolean mIsConnecting;
+
+    /**
+     * Listener for observing the {@link AccessibilityEvent} stream.
+     */
+    public static interface OnAccessibilityEventListener {
+
+        /**
+         * Callback for receiving an {@link AccessibilityEvent}.
+         * <p>
+         * <strong>Note:</strong> This method is <strong>NOT</strong> executed
+         * on the main test thread. The client is responsible for proper
+         * synchronization.
+         * </p>
+         * <p>
+         * <strong>Note:</strong> It is responsibility of the client
+         * to recycle the received events to minimize object creation.
+         * </p>
+         *
+         * @param event The received event.
+         */
+        public void onAccessibilityEvent(AccessibilityEvent event);
+    }
+
+    /**
+     * Creates a new instance that will handle callbacks from the accessibility
+     * layer on the thread of the provided looper and perform requests for privileged
+     * operations on the provided connection.
+     *
+     * @param looper The looper on which to execute accessibility callbacks.
+     * @param connection The connection for performing privileged operations.
+     *
+     * @hide
+     */
+    public UiAutomation(Looper looper, IUiAutomationConnection connection) {
+        if (looper == null) {
+            throw new IllegalArgumentException("Looper cannot be null!");
+        }
+        if (connection == null) {
+            throw new IllegalArgumentException("Connection cannot be null!");
+        }
+        mUiAutomationConnection = connection;
+        mClient = new IAccessibilityServiceClientImpl(looper);
+    }
+
+    /**
+     * Connects this UiAutomation to the accessibility introspection APIs.
+     *
+     * @hide
+     */
+    public void connect() {
+        synchronized (mLock) {
+            throwIfConnectedLocked();
+            if (mIsConnecting) {
+                return;
+            }
+            mIsConnecting = true;
+        }
+
+        try {
+            // Calling out without a lock held.
+            mUiAutomationConnection.connect(mClient);
+        } catch (RemoteException re) {
+            throw new RuntimeException("Error while connecting UiAutomation", re);
+        }
+
+        synchronized (mLock) {
+            final long startTimeMillis = SystemClock.uptimeMillis();
+            try {
+                while (true) {
+                    if (isConnectedLocked()) {
+                        break;
+                    }
+                    final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
+                    final long remainingTimeMillis = CONNECT_TIMEOUT_MILLIS - elapsedTimeMillis;
+                    if (remainingTimeMillis <= 0) {
+                        throw new RuntimeException("Error while connecting UiAutomation");
+                    }
+                    try {
+                        mLock.wait(remainingTimeMillis);
+                    } catch (InterruptedException ie) {
+                        /* ignore */
+                    }
+                }
+            } finally {
+                mIsConnecting = false;
+            }
+        }
+    }
+
+    /**
+     * Disconnects this UiAutomation from the accessibility introspection APIs.
+     *
+     * @hide
+     */
+    public void disconnect() {
+        synchronized (mLock) {
+            if (mIsConnecting) {
+                throw new IllegalStateException(
+                        "Cannot call disconnect() while connecting!");
+            }
+            throwIfNotConnectedLocked();
+            mConnectionId = CONNECTION_ID_UNDEFINED;
+        }
+        try {
+            // Calling out without a lock held.
+            mUiAutomationConnection.disconnect();
+        } catch (RemoteException re) {
+            throw new RuntimeException("Error while disconnecting UiAutomation", re);
+        }
+    }
+
+    /**
+     * The id of the {@link IAccessibilityInteractionConnection} for querying
+     * the screen content. This is here for legacy purposes since some tools use
+     * hidden APIs to introspect the screen.
+     *
+     * @hide
+     */
+    public int getConnectionId() {
+        synchronized (mLock) {
+            throwIfNotConnectedLocked();
+            return mConnectionId;
+        }
+    }
+
+    /**
+     * Sets a callback for observing the stream of {@link AccessibilityEvent}s.
+     *
+     * @param listener The callback.
+     */
+    public void setOnAccessibilityEventListener(OnAccessibilityEventListener listener) {
+        synchronized (mLock) {
+            mOnAccessibilityEventListener = listener;
+        }
+    }
+
+    /**
+     * Gets the root {@link AccessibilityNodeInfo} in the active window.
+     *
+     * @return The root info.
+     */
+    public AccessibilityNodeInfo getRootInActiveWindow() {
+        final int connectionId;
+        synchronized (mLock) {
+            throwIfNotConnectedLocked();
+            connectionId = mConnectionId;
+        }
+        // Calling out without a lock held.
+        return AccessibilityInteractionClient.getInstance()
+                .getRootInActiveWindow(connectionId);
+    }
+
+    /**
+     * A method for injecting an arbitrary input event.
+     * <p>
+     * <strong>Note:</strong> It is caller's responsibility to recycle the event.
+     * </p>
+     * @param event The event to inject.
+     * @param sync Whether to inject the event synchronously.
+     * @return Whether event injection succeeded.
+     */
+    public boolean injectInputEvent(InputEvent event, boolean sync) {
+        synchronized (mLock) {
+            throwIfNotConnectedLocked();
+        }
+        try {
+            if (DEBUG) {
+                Log.i(LOG_TAG, "Injecting: " + event + " sync: " + sync);
+            }
+            // Calling out without a lock held.
+            return mUiAutomationConnection.injectInputEvent(event, sync);
+        } catch (RemoteException re) {
+            Log.e(LOG_TAG, "Error while injecting input event!", re);
+        }
+        return false;
+    }
+
+    /**
+     * Sets the device rotation. A client can freeze the rotation in
+     * desired state or freeze the rotation to its current state or
+     * unfreeze the rotation (rotating the device changes its rotation
+     * state).
+     *
+     * @param rotation The desired rotation.
+     * @return Whether the rotation was set successfully.
+     *
+     * @see #ROTATION_FREEZE_0
+     * @see #ROTATION_FREEZE_90
+     * @see #ROTATION_FREEZE_180
+     * @see #ROTATION_FREEZE_270
+     * @see #ROTATION_FREEZE_CURRENT
+     * @see #ROTATION_UNFREEZE
+     */
+    public boolean setRotation(int rotation) {
+        synchronized (mLock) {
+            throwIfNotConnectedLocked();
+        }
+        switch (rotation) {
+            case ROTATION_FREEZE_0:
+            case ROTATION_FREEZE_90:
+            case ROTATION_FREEZE_180:
+            case ROTATION_FREEZE_270:
+            case ROTATION_UNFREEZE:
+            case ROTATION_FREEZE_CURRENT: {
+                try {
+                    // Calling out without a lock held.
+                    mUiAutomationConnection.setRotation(rotation);
+                    return true;
+                } catch (RemoteException re) {
+                    Log.e(LOG_TAG, "Error while setting rotation!", re);
+                }
+            } return false;
+            default: {
+                throw new IllegalArgumentException("Invalid rotation.");
+            }
+        }
+    }
+
+    /**
+     * Executes a command and waits for a specific accessibility event up to a
+     * given wait timeout. To detect a sequence of events one can implement a
+     * filter that keeps track of seen events of the expected sequence and
+     * returns true after the last event of that sequence is received.
+     * <p>
+     * <strong>Note:</strong> It is caller's responsibility to recycle the returned event.
+     * </p>
+     * @param command The command to execute.
+     * @param filter Filter that recognizes the expected event.
+     * @param timeoutMillis The wait timeout in milliseconds.
+     *
+     * @throws TimeoutException If the expected event is not received within the timeout.
+     */
+    public AccessibilityEvent executeAndWaitForEvent(Runnable command,
+            Predicate<AccessibilityEvent> filter, long timeoutMillis) throws TimeoutException {
+        synchronized (mLock) {
+            throwIfNotConnectedLocked();
+
+            mEventQueue.clear();
+            // Prepare to wait for an event.
+            mWaitingForEventDelivery = true;
+
+            // We will ignore events from previous interactions.
+            final long executionStartTimeMillis = SystemClock.uptimeMillis();
+
+            // Execute the command.
+            command.run();
+            try {
+                // Wait for the event.
+                final long startTimeMillis = SystemClock.uptimeMillis();
+                while (true) {
+                    // Drain the event queue
+                    while (!mEventQueue.isEmpty()) {
+                        AccessibilityEvent event = mEventQueue.remove(0);
+                        // Ignore events from previous interactions.
+                        if (event.getEventTime() <= executionStartTimeMillis) {
+                            continue;
+                        }
+                        if (filter.apply(event)) {
+                            return event;
+                        }
+                        event.recycle();
+                    }
+                    // Check if timed out and if not wait.
+                    final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
+                    final long remainingTimeMillis = timeoutMillis - elapsedTimeMillis;
+                    if (remainingTimeMillis <= 0) {
+                        throw new TimeoutException("Expected event not received within: "
+                                + timeoutMillis + " ms.");
+                    }
+                    try {
+                        mLock.wait(remainingTimeMillis);
+                    } catch (InterruptedException ie) {
+                        /* ignore */
+                    }
+                }
+            } finally {
+                mWaitingForEventDelivery = false;
+                mEventQueue.clear();
+                mLock.notifyAll();
+            }
+        }
+    }
+
+    /**
+     * Waits for the accessibility event stream to become idle, which is not to
+     * have received an accessibility event within <code>idleTimeoutMillis</code>.
+     * The total time spent to wait for an idle accessibility event stream is bounded
+     * by the <code>globalTimeoutMillis</code>.
+     *
+     * @param idleTimeoutMillis The timeout in milliseconds between two events
+     *            to consider the device idle.
+     * @param globalTimeoutMillis The maximal global timeout in milliseconds in
+     *            which to wait for an idle state.
+     *
+     * @throws TimeoutException If no idle state was detected within
+     *            <code>globalTimeoutMillis.</code>
+     */
+    public void waitForIdle(long idleTimeoutMillis, long globalTimeoutMillis)
+            throws TimeoutException {
+        synchronized (mLock) {
+            throwIfNotConnectedLocked();
+
+            final long startTimeMillis = SystemClock.uptimeMillis();
+            if (mLastEventTimeMillis <= 0) {
+                mLastEventTimeMillis = startTimeMillis;
+            }
+
+            while (true) {
+                final long currentTimeMillis = SystemClock.uptimeMillis();
+                // Did we get idle state within the global timeout?
+                final long elapsedGlobalTimeMillis = currentTimeMillis - startTimeMillis;
+                final long remainingGlobalTimeMillis =
+                        globalTimeoutMillis - elapsedGlobalTimeMillis;
+                if (remainingGlobalTimeMillis <= 0) {
+                    throw new TimeoutException("No idle state with idle timeout: "
+                            + idleTimeoutMillis + " within global timeout: "
+                            + globalTimeoutMillis);
+                }
+                // Did we get an idle state within the idle timeout?
+                final long elapsedIdleTimeMillis = currentTimeMillis - mLastEventTimeMillis;
+                final long remainingIdleTimeMillis = idleTimeoutMillis - elapsedIdleTimeMillis;
+                if (remainingIdleTimeMillis <= 0) {
+                    return;
+                }
+                try {
+                     mLock.wait(remainingIdleTimeMillis);
+                } catch (InterruptedException ie) {
+                     /* ignore */
+                }
+            }
+        }
+    }
+
+    /**
+     * Takes a screenshot.
+     *
+     * @return The screenshot bitmap on success, null otherwise.
+     */
+    public Bitmap takeScreenshot() {
+        synchronized (mLock) {
+            throwIfNotConnectedLocked();
+        }
+        Display display = DisplayManagerGlobal.getInstance()
+                .getRealDisplay(Display.DEFAULT_DISPLAY);
+        Point displaySize = new Point();
+        display.getRealSize(displaySize);
+        final int displayWidth = displaySize.x;
+        final int displayHeight = displaySize.y;
+
+        final float screenshotWidth;
+        final float screenshotHeight;
+
+        final int rotation = display.getRotation();
+        switch (rotation) {
+            case ROTATION_FREEZE_0: {
+                screenshotWidth = displayWidth;
+                screenshotHeight = displayHeight;
+            } break;
+            case ROTATION_FREEZE_90: {
+                screenshotWidth = displayHeight;
+                screenshotHeight = displayWidth;
+            } break;
+            case ROTATION_FREEZE_180: {
+                screenshotWidth = displayWidth;
+                screenshotHeight = displayHeight;
+            } break;
+            case ROTATION_FREEZE_270: {
+                screenshotWidth = displayHeight;
+                screenshotHeight = displayWidth;
+            } break;
+            default: {
+                throw new IllegalArgumentException("Invalid rotation: "
+                        + rotation);
+            }
+        }
+
+        // Take the screenshot
+        Bitmap screenShot = null;
+        try {
+            // Calling out without a lock held.
+            screenShot = mUiAutomationConnection.takeScreenshot((int) screenshotWidth,
+                    (int) screenshotHeight);
+            if (screenShot == null) {
+                return null;
+            }
+        } catch (RemoteException re) {
+            Log.e(LOG_TAG, "Error while taking screnshot!", re);
+            return null;
+        }
+
+        // Rotate the screenshot to the current orientation
+        if (rotation != ROTATION_FREEZE_0) {
+            Bitmap unrotatedScreenShot = Bitmap.createBitmap(displayWidth, displayHeight,
+                    Bitmap.Config.ARGB_8888);
+            Canvas canvas = new Canvas(unrotatedScreenShot);
+            canvas.translate(unrotatedScreenShot.getWidth() / 2,
+                    unrotatedScreenShot.getHeight() / 2);
+            canvas.rotate(getDegreesForRotation(rotation));
+            canvas.translate(- screenshotWidth / 2, - screenshotHeight / 2);
+            canvas.drawBitmap(screenShot, 0, 0, null);
+            canvas.setBitmap(null);
+            screenShot = unrotatedScreenShot;
+        }
+
+        // Optimization
+        screenShot.setHasAlpha(false);
+
+        return screenShot;
+    }
+
+    private static float getDegreesForRotation(int value) {
+        switch (value) {
+            case Surface.ROTATION_90: {
+                return 360f - 90f;
+            }
+            case Surface.ROTATION_180: {
+                return 360f - 180f;
+            }
+            case Surface.ROTATION_270: {
+                return 360f - 270f;
+            } default: {
+                return 0;
+            }
+        }
+    }
+
+    private boolean isConnectedLocked() {
+        return mConnectionId != CONNECTION_ID_UNDEFINED;
+    }
+
+    private void throwIfConnectedLocked() {
+        if (mConnectionId != CONNECTION_ID_UNDEFINED) {
+            throw new IllegalStateException("UiAutomation not connected!");
+        }
+    }
+
+    private void throwIfNotConnectedLocked() {
+        if (!isConnectedLocked()) {
+            throw new IllegalStateException("UiAutomation not connected!");
+        }
+    }
+
+    private class IAccessibilityServiceClientImpl extends IAccessibilityServiceClientWrapper {
+
+        public IAccessibilityServiceClientImpl(Looper looper) {
+            super(null, looper, new Callbacks() {
+                @Override
+                public void onSetConnectionId(int connectionId) {
+                    synchronized (mLock) {
+                        mConnectionId = connectionId;
+                        mLock.notifyAll();
+                    }
+                }
+
+                @Override
+                public void onServiceConnected() {
+                    /* do nothing */
+                }
+
+                @Override
+                public void onInterrupt() {
+                    /* do nothing */
+                }
+
+                @Override
+                public boolean onGesture(int gestureId) {
+                    /* do nothing */
+                    return false;
+                }
+
+                @Override
+                public void onAccessibilityEvent(AccessibilityEvent event) {
+                    synchronized (mLock) {
+                        mLastEventTimeMillis = event.getEventTime();
+                        if (mWaitingForEventDelivery) {
+                            mEventQueue.add(AccessibilityEvent.obtain(event));
+                        }
+                        mLock.notifyAll();
+                    }
+                    // Calling out only without a lock held.
+                    final OnAccessibilityEventListener listener = mOnAccessibilityEventListener;
+                    if (listener != null) {
+                        listener.onAccessibilityEvent(AccessibilityEvent.obtain(event));
+                    }
+                }
+            });
+        }
+    }
+}
diff --git a/core/java/android/app/UiAutomationConnection.java b/core/java/android/app/UiAutomationConnection.java
new file mode 100644
index 0000000..9b5857f
--- /dev/null
+++ b/core/java/android/app/UiAutomationConnection.java
@@ -0,0 +1,239 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+
+package android.app;
+
+import android.accessibilityservice.AccessibilityServiceInfo;
+import android.accessibilityservice.IAccessibilityServiceClient;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.hardware.input.InputManager;
+import android.os.Binder;
+import android.os.Process;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.view.IWindowManager;
+import android.view.InputEvent;
+import android.view.Surface;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.IAccessibilityManager;
+
+/**
+ * This is a remote object that is passed from the shell to an instrumentation
+ * for enabling access to privileged operations which the shell can do and the
+ * instrumentation cannot. These privileged operations are needed for implementing
+ * a {@link UiAutomation} that enables across application testing by simulating
+ * user actions and performing screen introspection.
+ *
+ * @hide
+ */
+public final class UiAutomationConnection extends IUiAutomationConnection.Stub {
+
+    private static final int INITIAL_FROZEN_ROTATION_UNSPECIFIED = -1;
+
+    private final IWindowManager mWindowManager = IWindowManager.Stub.asInterface(
+            ServiceManager.getService(Service.WINDOW_SERVICE));
+
+    private final Object mLock = new Object();
+
+    private int mInitialFrozenRotation = INITIAL_FROZEN_ROTATION_UNSPECIFIED;
+
+    private IAccessibilityServiceClient mClient;
+
+    private boolean mIsShutdown;
+
+    private int mOwningUid;
+
+    public void connect(IAccessibilityServiceClient client) {
+        if (client == null) {
+            throw new IllegalArgumentException("Client cannot be null!");
+        }
+        synchronized (mLock) {
+            throwIfShutdownLocked();
+            if (isConnectedLocked()) {
+                throw new IllegalStateException("Already connected.");
+            }
+            mOwningUid = Binder.getCallingUid();
+            registerUiTestAutomationServiceLocked(client);
+            storeRotationStateLocked();
+        }
+    }
+
+    @Override
+    public void disconnect() {
+        synchronized (mLock) {
+            throwIfCalledByNotTrustedUidLocked();
+            throwIfShutdownLocked();
+            if (!isConnectedLocked()) {
+                throw new IllegalStateException("Already disconnected.");
+            }
+            mOwningUid = -1;
+            unregisterUiTestAutomationServiceLocked();
+            restoreRotationStateLocked();
+        }
+    }
+
+    @Override
+    public boolean injectInputEvent(InputEvent event, boolean sync) {
+        synchronized (mLock) {
+            throwIfCalledByNotTrustedUidLocked();
+            throwIfShutdownLocked();
+            throwIfNotConnectedLocked();
+        }
+        final int mode = (sync) ? InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH
+                : InputManager.INJECT_INPUT_EVENT_MODE_ASYNC;
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            return InputManager.getInstance().injectInputEvent(event, mode);
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    @Override
+    public boolean setRotation(int rotation) {
+        synchronized (mLock) {
+            throwIfCalledByNotTrustedUidLocked();
+            throwIfShutdownLocked();
+            throwIfNotConnectedLocked();
+        }
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            if (rotation == UiAutomation.ROTATION_UNFREEZE) {
+                mWindowManager.thawRotation();
+            } else {
+                mWindowManager.freezeRotation(rotation);
+            }
+            return true;
+        } catch (RemoteException re) {
+            /* ignore */
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+        return false;
+    }
+
+    @Override
+    public Bitmap takeScreenshot(int width, int height) {
+        synchronized (mLock) {
+            throwIfCalledByNotTrustedUidLocked();
+            throwIfShutdownLocked();
+            throwIfNotConnectedLocked();
+        }
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            return Surface.screenshot(width, height);
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    @Override
+    public void shutdown() {
+        synchronized (mLock) {
+            throwIfCalledByNotTrustedUidLocked();
+            throwIfShutdownLocked();
+            mIsShutdown = true;
+            if (isConnectedLocked()) {
+                disconnect();
+            }
+        }
+    }
+
+    private void registerUiTestAutomationServiceLocked(IAccessibilityServiceClient client) {
+        IAccessibilityManager manager = IAccessibilityManager.Stub.asInterface(
+                ServiceManager.getService(Context.ACCESSIBILITY_SERVICE));
+        AccessibilityServiceInfo info = new AccessibilityServiceInfo();
+        info.eventTypes = AccessibilityEvent.TYPES_ALL_MASK;
+        info.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC;
+        info.flags |= AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS
+                | AccessibilityServiceInfo.FLAG_REPORT_VIEW_IDS;
+        try {
+            // Calling out with a lock held is fine since if the system
+            // process is gone the client calling in will be killed.
+            manager.registerUiTestAutomationService(client, info);
+            mClient = client;
+        } catch (RemoteException re) {
+            throw new IllegalStateException("Error while registering UiTestAutomationService.", re);
+        }
+    }
+
+    private void unregisterUiTestAutomationServiceLocked() {
+        IAccessibilityManager manager = IAccessibilityManager.Stub.asInterface(
+              ServiceManager.getService(Context.ACCESSIBILITY_SERVICE));
+        try {
+            // Calling out with a lock held is fine since if the system
+            // process is gone the client calling in will be killed.
+            manager.unregisterUiTestAutomationService(mClient);
+            mClient = null;
+        } catch (RemoteException re) {
+            throw new IllegalStateException("Error while unregistering UiTestAutomationService",
+                    re);
+        }
+    }
+
+    private void storeRotationStateLocked() {
+        try {
+            if (mWindowManager.isRotationFrozen()) {
+                // Calling out with a lock held is fine since if the system
+                // process is gone the client calling in will be killed.
+                mInitialFrozenRotation = mWindowManager.getRotation();
+            }
+        } catch (RemoteException re) {
+            /* ignore */
+        }
+    }
+
+    private void restoreRotationStateLocked() {
+        try {
+            if (mInitialFrozenRotation != INITIAL_FROZEN_ROTATION_UNSPECIFIED) {
+                // Calling out with a lock held is fine since if the system
+                // process is gone the client calling in will be killed.
+                mWindowManager.freezeRotation(mInitialFrozenRotation);
+            } else {
+                // Calling out with a lock held is fine since if the system
+                // process is gone the client calling in will be killed.
+                mWindowManager.thawRotation();
+            }
+        } catch (RemoteException re) {
+            /* ignore */
+        }
+    }
+
+    private boolean isConnectedLocked() {
+        return mClient != null;
+    }
+
+    private void throwIfShutdownLocked() {
+        if (mIsShutdown) {
+            throw new IllegalStateException("Connection shutdown!");
+        }
+    }
+
+    private void throwIfNotConnectedLocked() {
+        if (!isConnectedLocked()) {
+            throw new IllegalStateException("Not connected!");
+        }
+    }
+
+    private void throwIfCalledByNotTrustedUidLocked() {
+        final int callingUid = Binder.getCallingUid();
+        if (callingUid != mOwningUid && mOwningUid != Process.SYSTEM_UID
+                && callingUid != 0 /*root*/) {
+            throw new SecurityException("Calling from not trusted UID!");
+        }
+    }
+}
diff --git a/core/java/android/os/MessageQueue.java b/core/java/android/os/MessageQueue.java
index 5ad60ec..222578a 100644
--- a/core/java/android/os/MessageQueue.java
+++ b/core/java/android/os/MessageQueue.java
@@ -48,10 +48,10 @@
     // Barriers are indicated by messages with a null target whose arg1 field carries the token.
     private int mNextBarrierToken;
 
-    private native void nativeInit();
-    private native void nativeDestroy();
-    private native void nativePollOnce(int ptr, int timeoutMillis);
-    private native void nativeWake(int ptr);
+    private native static int nativeInit();
+    private native static void nativeDestroy(int ptr);
+    private native static void nativePollOnce(int ptr, int timeoutMillis);
+    private native static void nativeWake(int ptr);
 
     /**
      * Callback interface for discovering when a thread is going to block
@@ -102,18 +102,25 @@
 
     MessageQueue(boolean quitAllowed) {
         mQuitAllowed = quitAllowed;
-        nativeInit();
+        mPtr = nativeInit();
     }
 
     @Override
     protected void finalize() throws Throwable {
         try {
-            nativeDestroy();
+            dispose();
         } finally {
             super.finalize();
         }
     }
 
+    private void dispose() {
+        if (mPtr != 0) {
+            nativeDestroy(mPtr);
+            mPtr = 0;
+        }
+    }
+
     final Message next() {
         int pendingIdleHandlerCount = -1; // -1 only during first iteration
         int nextPollTimeoutMillis = 0;
@@ -126,6 +133,7 @@
 
             synchronized (this) {
                 if (mQuiting) {
+                    dispose();
                     return null;
                 }
 
diff --git a/core/java/android/view/AccessibilityInteractionController.java b/core/java/android/view/AccessibilityInteractionController.java
index ba82d79..81c25d8 100644
--- a/core/java/android/view/AccessibilityInteractionController.java
+++ b/core/java/android/view/AccessibilityInteractionController.java
@@ -16,8 +16,8 @@
 
 package android.view;
 
-import static android.view.accessibility.AccessibilityNodeInfo.INCLUDE_NOT_IMPORTANT_VIEWS;
-
+import android.app.ActivityThread;
+import android.content.Context;
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.os.Bundle;
@@ -34,6 +34,7 @@
 import android.view.accessibility.IAccessibilityInteractionConnectionCallback;
 
 import com.android.internal.os.SomeArgs;
+import com.android.internal.util.Predicate;
 
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -49,7 +50,7 @@
  */
 final class AccessibilityInteractionController {
 
-    private ArrayList<AccessibilityNodeInfo> mTempAccessibilityNodeInfoList =
+    private final ArrayList<AccessibilityNodeInfo> mTempAccessibilityNodeInfoList =
         new ArrayList<AccessibilityNodeInfo>();
 
     private final Handler mHandler;
@@ -69,6 +70,8 @@
     private final Rect mTempRect1 = new Rect();
     private final Rect mTempRect2 = new Rect();
 
+    private AddNodeInfosForViewId mAddNodeInfosForViewId;
+
     public AccessibilityInteractionController(ViewRootImpl viewRootImpl) {
         Looper looper =  viewRootImpl.mHandler.getLooper();
         mMyLooperThreadId = looper.getThread().getId();
@@ -135,8 +138,7 @@
             if (mViewRootImpl.mView == null || mViewRootImpl.mAttachInfo == null) {
                 return;
             }
-            mViewRootImpl.mAttachInfo.mIncludeNotImportantViews =
-                (flags & INCLUDE_NOT_IMPORTANT_VIEWS) != 0;
+            mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = flags;
             View root = null;
             if (accessibilityViewId == AccessibilityNodeInfo.UNDEFINED) {
                 root = mViewRootImpl.mView;
@@ -148,7 +150,7 @@
             }
         } finally {
             try {
-                mViewRootImpl.mAttachInfo.mIncludeNotImportantViews = false;
+                mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = 0;
                 applyAppScaleAndMagnificationSpecIfNeeded(infos, spec);
                 if (spec != null) {
                     spec.recycle();
@@ -161,19 +163,19 @@
         }
     }
 
-    public void findAccessibilityNodeInfoByViewIdClientThread(long accessibilityNodeId,
-            int viewId, int interactionId, IAccessibilityInteractionConnectionCallback callback,
+    public void findAccessibilityNodeInfosByViewIdClientThread(long accessibilityNodeId,
+            String viewId, int interactionId, IAccessibilityInteractionConnectionCallback callback,
             int flags, int interrogatingPid, long interrogatingTid, MagnificationSpec spec) {
         Message message = mHandler.obtainMessage();
-        message.what = PrivateHandler.MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_VIEW_ID;
+        message.what = PrivateHandler.MSG_FIND_ACCESSIBLITY_NODE_INFOS_BY_VIEW_ID;
         message.arg1 = flags;
         message.arg2 = AccessibilityNodeInfo.getAccessibilityViewId(accessibilityNodeId);
 
         SomeArgs args = SomeArgs.obtain();
-        args.argi1 = viewId;
-        args.argi2 = interactionId;
+        args.argi1 = interactionId;
         args.arg1 = callback;
         args.arg2 = spec;
+        args.arg3 = viewId;
 
         message.obj = args;
 
@@ -189,26 +191,26 @@
         }
     }
 
-    private void findAccessibilityNodeInfoByViewIdUiThread(Message message) {
+    private void findAccessibilityNodeInfosByViewIdUiThread(Message message) {
         final int flags = message.arg1;
         final int accessibilityViewId = message.arg2;
 
         SomeArgs args = (SomeArgs) message.obj;
-        final int viewId = args.argi1;
-        final int interactionId = args.argi2;
+        final int interactionId = args.argi1;
         final IAccessibilityInteractionConnectionCallback callback =
             (IAccessibilityInteractionConnectionCallback) args.arg1;
         final MagnificationSpec spec = (MagnificationSpec) args.arg2;
+        final String viewId = (String) args.arg3;
 
         args.recycle();
 
-        AccessibilityNodeInfo info = null;
+        final List<AccessibilityNodeInfo> infos = mTempAccessibilityNodeInfoList;
+        infos.clear();
         try {
             if (mViewRootImpl.mView == null || mViewRootImpl.mAttachInfo == null) {
                 return;
             }
-            mViewRootImpl.mAttachInfo.mIncludeNotImportantViews =
-                (flags & INCLUDE_NOT_IMPORTANT_VIEWS) != 0;
+            mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = flags;
             View root = null;
             if (accessibilityViewId != AccessibilityNodeInfo.UNDEFINED) {
                 root = findViewByAccessibilityId(accessibilityViewId);
@@ -216,19 +218,31 @@
                 root = mViewRootImpl.mView;
             }
             if (root != null) {
-                View target = root.findViewById(viewId);
-                if (target != null && isShown(target)) {
-                    info = target.createAccessibilityNodeInfo();
+                int resolvedViewId = root.getContext().getResources().getIdentifier(
+                        viewId, "id", root.getContext().getPackageName());
+                if (resolvedViewId <= 0) {
+                    resolvedViewId = ((Context) ActivityThread.currentActivityThread()
+                            .getSystemContext()).getResources()
+                            .getIdentifier(viewId, "id", "android");
                 }
+                if (resolvedViewId <= 0) {
+                    return;
+                }
+                if (mAddNodeInfosForViewId == null) {
+                    mAddNodeInfosForViewId = new AddNodeInfosForViewId();
+                }
+                mAddNodeInfosForViewId.init(resolvedViewId, infos);
+                root.findViewByPredicate(mAddNodeInfosForViewId);
+                mAddNodeInfosForViewId.reset();
             }
         } finally {
             try {
-                mViewRootImpl.mAttachInfo.mIncludeNotImportantViews = false;
-                applyAppScaleAndMagnificationSpecIfNeeded(info, spec);
+                mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = 0;
+                applyAppScaleAndMagnificationSpecIfNeeded(infos, spec);
                 if (spec != null) {
                     spec.recycle();
                 }
-                callback.setFindAccessibilityNodeInfoResult(info, interactionId);
+                callback.setFindAccessibilityNodeInfosResult(infos, interactionId);
             } catch (RemoteException re) {
                 /* ignore - the other side will time out */
             }
@@ -281,8 +295,7 @@
             if (mViewRootImpl.mView == null || mViewRootImpl.mAttachInfo == null) {
                 return;
             }
-            mViewRootImpl.mAttachInfo.mIncludeNotImportantViews =
-                (flags & INCLUDE_NOT_IMPORTANT_VIEWS) != 0;
+            mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = flags;
             View root = null;
             if (accessibilityViewId != AccessibilityNodeInfo.UNDEFINED) {
                 root = findViewByAccessibilityId(accessibilityViewId);
@@ -325,7 +338,7 @@
             }
         } finally {
             try {
-                mViewRootImpl.mAttachInfo.mIncludeNotImportantViews = false;
+                mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = 0;
                 applyAppScaleAndMagnificationSpecIfNeeded(infos, spec);
                 if (spec != null) {
                     spec.recycle();
@@ -384,8 +397,7 @@
             if (mViewRootImpl.mView == null || mViewRootImpl.mAttachInfo == null) {
                 return;
             }
-            mViewRootImpl.mAttachInfo.mIncludeNotImportantViews =
-                (flags & INCLUDE_NOT_IMPORTANT_VIEWS) != 0;
+            mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = flags;
             View root = null;
             if (accessibilityViewId != AccessibilityNodeInfo.UNDEFINED) {
                 root = findViewByAccessibilityId(accessibilityViewId);
@@ -426,7 +438,7 @@
             }
         } finally {
             try {
-                mViewRootImpl.mAttachInfo.mIncludeNotImportantViews = false;
+                mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = 0;
                 applyAppScaleAndMagnificationSpecIfNeeded(focused, spec);
                 if (spec != null) {
                     spec.recycle();
@@ -484,8 +496,7 @@
             if (mViewRootImpl.mView == null || mViewRootImpl.mAttachInfo == null) {
                 return;
             }
-            mViewRootImpl.mAttachInfo.mIncludeNotImportantViews =
-                (flags & INCLUDE_NOT_IMPORTANT_VIEWS) != 0;
+            mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = flags;
             View root = null;
             if (accessibilityViewId != AccessibilityNodeInfo.UNDEFINED) {
                 root = findViewByAccessibilityId(accessibilityViewId);
@@ -500,7 +511,7 @@
             }
         } finally {
             try {
-                mViewRootImpl.mAttachInfo.mIncludeNotImportantViews = false;
+                mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = 0;
                 applyAppScaleAndMagnificationSpecIfNeeded(next, spec);
                 if (spec != null) {
                     spec.recycle();
@@ -561,8 +572,7 @@
             if (mViewRootImpl.mView == null || mViewRootImpl.mAttachInfo == null) {
                 return;
             }
-            mViewRootImpl.mAttachInfo.mIncludeNotImportantViews =
-                (flags & INCLUDE_NOT_IMPORTANT_VIEWS) != 0;
+            mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = flags;
             View target = null;
             if (accessibilityViewId != AccessibilityNodeInfo.UNDEFINED) {
                 target = findViewByAccessibilityId(accessibilityViewId);
@@ -580,7 +590,7 @@
             }
         } finally {
             try {
-                mViewRootImpl.mAttachInfo.mIncludeNotImportantViews = false;
+                mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = 0;
                 callback.setPerformAccessibilityActionResult(succeeded, interactionId);
             } catch (RemoteException re) {
                 /* ignore - the other side will time out */
@@ -690,20 +700,20 @@
 
         private final ArrayList<View> mTempViewList = new ArrayList<View>();
 
-        public void prefetchAccessibilityNodeInfos(View view, int virtualViewId, int prefetchFlags,
+        public void prefetchAccessibilityNodeInfos(View view, int virtualViewId, int fetchFlags,
                 List<AccessibilityNodeInfo> outInfos) {
             AccessibilityNodeProvider provider = view.getAccessibilityNodeProvider();
             if (provider == null) {
                 AccessibilityNodeInfo root = view.createAccessibilityNodeInfo();
                 if (root != null) {
                     outInfos.add(root);
-                    if ((prefetchFlags & AccessibilityNodeInfo.FLAG_PREFETCH_PREDECESSORS) != 0) {
+                    if ((fetchFlags & AccessibilityNodeInfo.FLAG_PREFETCH_PREDECESSORS) != 0) {
                         prefetchPredecessorsOfRealNode(view, outInfos);
                     }
-                    if ((prefetchFlags & AccessibilityNodeInfo.FLAG_PREFETCH_SIBLINGS) != 0) {
+                    if ((fetchFlags & AccessibilityNodeInfo.FLAG_PREFETCH_SIBLINGS) != 0) {
                         prefetchSiblingsOfRealNode(view, outInfos);
                     }
-                    if ((prefetchFlags & AccessibilityNodeInfo.FLAG_PREFETCH_DESCENDANTS) != 0) {
+                    if ((fetchFlags & AccessibilityNodeInfo.FLAG_PREFETCH_DESCENDANTS) != 0) {
                         prefetchDescendantsOfRealNode(view, outInfos);
                     }
                 }
@@ -711,13 +721,13 @@
                 AccessibilityNodeInfo root = provider.createAccessibilityNodeInfo(virtualViewId);
                 if (root != null) {
                     outInfos.add(root);
-                    if ((prefetchFlags & AccessibilityNodeInfo.FLAG_PREFETCH_PREDECESSORS) != 0) {
+                    if ((fetchFlags & AccessibilityNodeInfo.FLAG_PREFETCH_PREDECESSORS) != 0) {
                         prefetchPredecessorsOfVirtualNode(root, view, provider, outInfos);
                     }
-                    if ((prefetchFlags & AccessibilityNodeInfo.FLAG_PREFETCH_SIBLINGS) != 0) {
+                    if ((fetchFlags & AccessibilityNodeInfo.FLAG_PREFETCH_SIBLINGS) != 0) {
                         prefetchSiblingsOfVirtualNode(root, view, provider, outInfos);
                     }
-                    if ((prefetchFlags & AccessibilityNodeInfo.FLAG_PREFETCH_DESCENDANTS) != 0) {
+                    if ((fetchFlags & AccessibilityNodeInfo.FLAG_PREFETCH_DESCENDANTS) != 0) {
                         prefetchDescendantsOfVirtualNode(root, provider, outInfos);
                     }
                 }
@@ -920,7 +930,7 @@
     private class PrivateHandler extends Handler {
         private final static int MSG_PERFORM_ACCESSIBILITY_ACTION = 1;
         private final static int MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_ACCESSIBILITY_ID = 2;
-        private final static int MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_VIEW_ID = 3;
+        private final static int MSG_FIND_ACCESSIBLITY_NODE_INFOS_BY_VIEW_ID = 3;
         private final static int MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_TEXT = 4;
         private final static int MSG_FIND_FOCUS = 5;
         private final static int MSG_FOCUS_SEARCH = 6;
@@ -937,8 +947,8 @@
                     return "MSG_PERFORM_ACCESSIBILITY_ACTION";
                 case MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_ACCESSIBILITY_ID:
                     return "MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_ACCESSIBILITY_ID";
-                case MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_VIEW_ID:
-                    return "MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_VIEW_ID";
+                case MSG_FIND_ACCESSIBLITY_NODE_INFOS_BY_VIEW_ID:
+                    return "MSG_FIND_ACCESSIBLITY_NODE_INFOS_BY_VIEW_ID";
                 case MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_TEXT:
                     return "MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_TEXT";
                 case MSG_FIND_FOCUS:
@@ -960,8 +970,8 @@
                 case MSG_PERFORM_ACCESSIBILITY_ACTION: {
                     perfromAccessibilityActionUiThread(message);
                 } break;
-                case MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_VIEW_ID: {
-                    findAccessibilityNodeInfoByViewIdUiThread(message);
+                case MSG_FIND_ACCESSIBLITY_NODE_INFOS_BY_VIEW_ID: {
+                    findAccessibilityNodeInfosByViewIdUiThread(message);
                 } break;
                 case MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_TEXT: {
                     findAccessibilityNodeInfosByTextUiThread(message);
@@ -977,4 +987,27 @@
             }
         }
     }
+
+    private final class AddNodeInfosForViewId implements Predicate<View> {
+        private int mViewId = View.NO_ID;
+        private List<AccessibilityNodeInfo> mInfos;
+
+        public void init(int viewId, List<AccessibilityNodeInfo> infos) {
+            mViewId = viewId;
+            mInfos = infos;
+        }
+
+        public void reset() {
+            mViewId = View.NO_ID;
+            mInfos = null;
+        }
+
+        @Override
+        public boolean apply(View view) {
+            if (view.getId() == mViewId && isShown(view)) {
+                mInfos.add(view.createAccessibilityNodeInfo());
+            }
+            return false;
+        }
+    }
 }
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 1ee2bb3..a9ad97f 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -190,6 +190,13 @@
     void thawRotation();
 
     /**
+     * Gets whether the rotation is frozen. 
+     *
+     * @return Whether the rotation is frozen.
+     */
+    boolean isRotationFrozen();
+
+    /**
      * Create a screenshot of the applications currently displayed.
      */
     Bitmap screenshotApplications(IBinder appToken, int displayId, int maxWidth, int maxHeight);
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index a4e4f37..b9babdc 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -16,6 +16,7 @@
 
 package android.view;
 
+import android.app.ActivityThread;
 import android.content.ClipData;
 import android.content.Context;
 import android.content.res.Configuration;
@@ -5007,6 +5008,25 @@
             if (label != null) {
                 info.setLabeledBy(label);
             }
+
+            if ((mAttachInfo.mAccessibilityFetchFlags
+                    & AccessibilityNodeInfo.FLAG_REPORT_VIEW_IDS) != 0) {
+                String viewId = null;
+                try {
+                    viewId = getResources().getResourceName(mID);
+                } catch (Resources.NotFoundException nfe) {
+                    /* ignore */
+                }
+                if (viewId == null) {
+                    try {
+                        viewId = ((Context) ActivityThread.currentActivityThread()
+                                .getSystemContext()).getResources().getResourceName(mID);
+                    } catch (Resources.NotFoundException nfe) {
+                        /* ignore */
+                    }
+                }
+                info.setViewId(viewId);
+            }
         }
 
         if (mLabelForId != View.NO_ID) {
@@ -6838,7 +6858,9 @@
      */
     public boolean includeForAccessibility() {
         if (mAttachInfo != null) {
-            return mAttachInfo.mIncludeNotImportantViews || isImportantForAccessibility();
+            return (mAttachInfo.mAccessibilityFetchFlags
+                    & AccessibilityNodeInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS) != 0
+                    || isImportantForAccessibility();
         }
         return false;
     }
@@ -18004,10 +18026,12 @@
         int mAccessibilityWindowId = View.NO_ID;
 
         /**
-         * Whether to ingore not exposed for accessibility Views when
-         * reporting the view tree to accessibility services.
+         * Flags related to accessibility processing.
+         *
+         * @see AccessibilityNodeInfo#FLAG_INCLUDE_NOT_IMPORTANT_VIEWS
+         * @see AccessibilityNodeInfo#FLAG_REPORT_VIEW_IDS
          */
-        boolean mIncludeNotImportantViews;
+        int mAccessibilityFetchFlags;
 
         /**
          * The drawable for highlighting accessibility focus.
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 9f075c4..ba9eb89 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -5482,15 +5482,16 @@
         }
 
         @Override
-        public void findAccessibilityNodeInfoByViewId(long accessibilityNodeId, int viewId,
-                int interactionId, IAccessibilityInteractionConnectionCallback callback, int flags,
+        public void findAccessibilityNodeInfosByViewId(long accessibilityNodeId,
+                String viewId, int interactionId,
+                IAccessibilityInteractionConnectionCallback callback, int flags,
                 int interrogatingPid, long interrogatingTid, MagnificationSpec spec) {
             ViewRootImpl viewRootImpl = mViewRootImpl.get();
             if (viewRootImpl != null && viewRootImpl.mView != null) {
                 viewRootImpl.getAccessibilityInteractionController()
-                    .findAccessibilityNodeInfoByViewIdClientThread(accessibilityNodeId, viewId,
-                            interactionId, callback, flags, interrogatingPid, interrogatingTid,
-                            spec);
+                    .findAccessibilityNodeInfosByViewIdClientThread(accessibilityNodeId,
+                            viewId, interactionId, callback, flags, interrogatingPid,
+                            interrogatingTid, spec);
             } else {
                 // We cannot make the call and notify the caller so it does not wait.
                 try {
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index 9377cfa..02be4db 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -1035,6 +1035,16 @@
     public void keepScreenOnStoppedLw();
 
     /**
+     * Gets the current user rotation mode. 
+     *
+     * @return The rotation mode.
+     *
+     * @see WindowManagerPolicy#USER_ROTATION_LOCKED
+     * @see WindowManagerPolicy#USER_ROTATION_FREE 
+     */
+    public int getUserRotationMode();
+
+    /**
      * Inform the policy that the user has chosen a preferred orientation ("rotation lock"). 
      *
      * @param mode One of {@link WindowManagerPolicy#USER_ROTATION_LOCKED} or
diff --git a/core/java/android/view/accessibility/AccessibilityInteractionClient.java b/core/java/android/view/accessibility/AccessibilityInteractionClient.java
index 67df684..84d7e72 100644
--- a/core/java/android/view/accessibility/AccessibilityInteractionClient.java
+++ b/core/java/android/view/accessibility/AccessibilityInteractionClient.java
@@ -230,23 +230,25 @@
      *     where to start the search. Use
      *     {@link android.view.accessibility.AccessibilityNodeInfo#ROOT_NODE_ID}
      *     to start from the root.
-     * @param viewId The id of the view.
-     * @return An {@link AccessibilityNodeInfo} if found, null otherwise.
+     * @param viewId The fully qualified resource name of the view id to find.
+     * @return An list of {@link AccessibilityNodeInfo} if found, empty list otherwise.
      */
-    public AccessibilityNodeInfo findAccessibilityNodeInfoByViewId(int connectionId,
-            int accessibilityWindowId, long accessibilityNodeId, int viewId) {
+    public List<AccessibilityNodeInfo> findAccessibilityNodeInfosByViewId(int connectionId,
+            int accessibilityWindowId, long accessibilityNodeId, String viewId) {
         try {
             IAccessibilityServiceConnection connection = getConnection(connectionId);
             if (connection != null) {
                 final int interactionId = mInteractionIdCounter.getAndIncrement();
-                final boolean success =connection.findAccessibilityNodeInfoByViewId(
+                final boolean success = connection.findAccessibilityNodeInfosByViewId(
                         accessibilityWindowId, accessibilityNodeId, viewId, interactionId, this,
                         Thread.currentThread().getId());
                 if (success) {
-                    AccessibilityNodeInfo info = getFindAccessibilityNodeInfoResultAndClear(
+                    List<AccessibilityNodeInfo> infos = getFindAccessibilityNodeInfosResultAndClear(
                             interactionId);
-                    finalizeAndCacheAccessibilityNodeInfo(info, connectionId);
-                    return info;
+                    if (infos != null) {
+                        finalizeAndCacheAccessibilityNodeInfos(infos, connectionId);
+                        return infos;
+                    }
                 }
             } else {
                 if (DEBUG) {
@@ -259,7 +261,7 @@
                         + " findAccessibilityNodeInfoByViewIdInActiveWindow", re);
             }
         }
-        return null;
+        return Collections.emptyList();
     }
 
     /**
@@ -291,8 +293,10 @@
                 if (success) {
                     List<AccessibilityNodeInfo> infos = getFindAccessibilityNodeInfosResultAndClear(
                             interactionId);
-                    finalizeAndCacheAccessibilityNodeInfos(infos, connectionId);
-                    return infos;
+                    if (infos != null) {
+                        finalizeAndCacheAccessibilityNodeInfos(infos, connectionId);
+                        return infos;
+                    }
                 }
             } else {
                 if (DEBUG) {
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index 6c03280..6d0a237 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -16,6 +16,7 @@
 
 package android.view.accessibility;
 
+import android.accessibilityservice.AccessibilityServiceInfo;
 import android.graphics.Rect;
 import android.os.Bundle;
 import android.os.Parcel;
@@ -78,7 +79,10 @@
     public static final int FLAG_PREFETCH_DESCENDANTS = 0x00000004;
 
     /** @hide */
-    public static final int INCLUDE_NOT_IMPORTANT_VIEWS = 0x00000008;
+    public static final int FLAG_INCLUDE_NOT_IMPORTANT_VIEWS = 0x00000008;
+
+    /** @hide */
+    public static final int FLAG_REPORT_VIEW_IDS = 0x00000010;
 
     // Actions.
 
@@ -375,6 +379,7 @@
     private CharSequence mClassName;
     private CharSequence mText;
     private CharSequence mContentDescription;
+    private CharSequence mViewId;
 
     private final SparseLongArray mChildNodeIds = new SparseLongArray();
     private int mActions;
@@ -729,6 +734,37 @@
     }
 
     /**
+     * Finds {@link AccessibilityNodeInfo}s by the fully qualified view id's resource
+     * name where a fully qualified id is of the from "package:id/id_resource_name".
+     * For example, if the target application's package is "foo.bar" and the id
+     * resource name is "baz", the fully qualified resource id is "foo.bar:id/baz".
+     *
+     * <p>
+     *   <strong>Note:</strong> It is a client responsibility to recycle the
+     *     received info by calling {@link AccessibilityNodeInfo#recycle()}
+     *     to avoid creating of multiple instances.
+     * </p>
+     * <p>
+     *   <strong>Note:</strong> The primary usage of this API is for UI test automation
+     *   and in order to report the fully qualified view id if an {@link AccessibilityNodeInfo}
+     *   the client has to set the {@link AccessibilityServiceInfo#FLAG_REPORT_VIEW_IDS}
+     *   flag when configuring his {@link android.accessibilityservice.AccessibilityService}.
+     * </p>
+     *
+     * @param viewId The fully qualified resource name of the view id to find.
+     * @return A list of node info.
+     */
+    public List<AccessibilityNodeInfo> findAccessibilityNodeInfosByViewId(String viewId) {
+        enforceSealed();
+        if (!canPerformRequestOverConnection(mSourceNodeId)) {
+            return Collections.emptyList();
+        }
+        AccessibilityInteractionClient client = AccessibilityInteractionClient.getInstance();
+        return client.findAccessibilityNodeInfosByViewId(mConnectionId, mWindowId, mSourceNodeId,
+                viewId);
+    }
+
+    /**
      * Gets the parent.
      * <p>
      *   <strong>Note:</strong> It is a client responsibility to recycle the
@@ -1373,6 +1409,38 @@
     }
 
     /**
+     * Sets the fully qualified resource name of the source view's id.
+     *
+     * <p>
+     *   <strong>Note:</strong> Cannot be called from an
+     *   {@link android.accessibilityservice.AccessibilityService}.
+     *   This class is made immutable before being delivered to an AccessibilityService.
+     * </p>
+     *
+     * @param viewId The id resource name.
+     */
+    public void setViewId(CharSequence viewId) {
+        enforceNotSealed();
+        mViewId = viewId;
+    }
+
+    /**
+     * Gets the fully qualified resource name of the source view's id.
+     *
+     * <p>
+     *   <strong>Note:</strong> The primary usage of this API is for UI test automation
+     *   and in order to report the source view id of an {@link AccessibilityNodeInfo} the
+     *   client has to set the {@link AccessibilityServiceInfo#FLAG_REPORT_VIEW_IDS}
+     *   flag when configuring his {@link android.accessibilityservice.AccessibilityService}.
+     * </p>
+
+     * @return The id resource name.
+     */
+    public CharSequence getViewId() {
+        return mViewId;
+    }
+
+    /**
      * Gets the value of a boolean property.
      *
      * @param property The property.
@@ -1614,6 +1682,7 @@
         parcel.writeCharSequence(mClassName);
         parcel.writeCharSequence(mText);
         parcel.writeCharSequence(mContentDescription);
+        parcel.writeCharSequence(mViewId);
 
         // Since instances of this class are fetched via synchronous i.e. blocking
         // calls in IPCs we always recycle as soon as the instance is marshaled.
@@ -1639,6 +1708,7 @@
         mClassName = other.mClassName;
         mText = other.mText;
         mContentDescription = other.mContentDescription;
+        mViewId = other.mViewId;
         mActions= other.mActions;
         mBooleanProperties = other.mBooleanProperties;
         mMovementGranularities = other.mMovementGranularities;
@@ -1689,6 +1759,7 @@
         mClassName = parcel.readCharSequence();
         mText = parcel.readCharSequence();
         mContentDescription = parcel.readCharSequence();
+        mViewId = parcel.readCharSequence();
     }
 
     /**
@@ -1711,6 +1782,7 @@
         mClassName = null;
         mText = null;
         mContentDescription = null;
+        mViewId = null;
         mActions = 0;
     }
 
@@ -1855,6 +1927,7 @@
         builder.append("; className: ").append(mClassName);
         builder.append("; text: ").append(mText);
         builder.append("; contentDescription: ").append(mContentDescription);
+        builder.append("; viewId: ").append(mViewId);
 
         builder.append("; checkable: ").append(isCheckable());
         builder.append("; checked: ").append(isChecked());
diff --git a/core/java/android/view/accessibility/IAccessibilityInteractionConnection.aidl b/core/java/android/view/accessibility/IAccessibilityInteractionConnection.aidl
index c313b07..8d15472 100644
--- a/core/java/android/view/accessibility/IAccessibilityInteractionConnection.aidl
+++ b/core/java/android/view/accessibility/IAccessibilityInteractionConnection.aidl
@@ -33,9 +33,9 @@
         IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid,
         long interrogatingTid, in MagnificationSpec spec);
 
-    void findAccessibilityNodeInfoByViewId(long accessibilityNodeId, int viewId, int interactionId,
-        IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid,
-        long interrogatingTid, in MagnificationSpec spec);
+    void findAccessibilityNodeInfosByViewId(long accessibilityNodeId, String viewId,
+        int interactionId, IAccessibilityInteractionConnectionCallback callback, int flags,
+        int interrogatingPid, long interrogatingTid, in MagnificationSpec spec);
 
     void findAccessibilityNodeInfosByText(long accessibilityNodeId, String text, int interactionId,
         IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid,
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 57bf0d3..396fd68 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -1374,9 +1374,11 @@
         if (isEnabled()) {
             if (getFirstVisiblePosition() > 0) {
                 info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD);
+                info.setScrollable(true);
             }
             if (getLastVisiblePosition() < getCount() - 1) {
                 info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
+                info.setScrollable(true);
             }
         }
     }
diff --git a/core/jni/android_os_MessageQueue.cpp b/core/jni/android_os_MessageQueue.cpp
index a4dcac6..7540645 100644
--- a/core/jni/android_os_MessageQueue.cpp
+++ b/core/jni/android_os_MessageQueue.cpp
@@ -109,55 +109,34 @@
 
 // ----------------------------------------------------------------------------
 
-static NativeMessageQueue* android_os_MessageQueue_getNativeMessageQueue(JNIEnv* env,
-        jobject messageQueueObj) {
+sp<MessageQueue> android_os_MessageQueue_getMessageQueue(JNIEnv* env, jobject messageQueueObj) {
     jint intPtr = env->GetIntField(messageQueueObj, gMessageQueueClassInfo.mPtr);
     return reinterpret_cast<NativeMessageQueue*>(intPtr);
 }
 
-static void android_os_MessageQueue_setNativeMessageQueue(JNIEnv* env, jobject messageQueueObj,
-        NativeMessageQueue* nativeMessageQueue) {
-    env->SetIntField(messageQueueObj, gMessageQueueClassInfo.mPtr,
-             reinterpret_cast<jint>(nativeMessageQueue));
-}
-
-sp<MessageQueue> android_os_MessageQueue_getMessageQueue(JNIEnv* env, jobject messageQueueObj) {
-    NativeMessageQueue* nativeMessageQueue =
-            android_os_MessageQueue_getNativeMessageQueue(env, messageQueueObj);
-    return nativeMessageQueue;
-}
-
-static void android_os_MessageQueue_nativeInit(JNIEnv* env, jobject obj) {
+static jint android_os_MessageQueue_nativeInit(JNIEnv* env, jclass clazz) {
     NativeMessageQueue* nativeMessageQueue = new NativeMessageQueue();
     if (!nativeMessageQueue) {
         jniThrowRuntimeException(env, "Unable to allocate native queue");
-        return;
+        return 0;
     }
 
     nativeMessageQueue->incStrong(env);
-    android_os_MessageQueue_setNativeMessageQueue(env, obj, nativeMessageQueue);
+    return reinterpret_cast<jint>(nativeMessageQueue);
 }
 
-static void android_os_MessageQueue_nativeDestroy(JNIEnv* env, jobject obj) {
-    NativeMessageQueue* nativeMessageQueue =
-            android_os_MessageQueue_getNativeMessageQueue(env, obj);
-    if (nativeMessageQueue) {
-        android_os_MessageQueue_setNativeMessageQueue(env, obj, NULL);
-        nativeMessageQueue->decStrong(env);
-    }
+static void android_os_MessageQueue_nativeDestroy(JNIEnv* env, jclass clazz, jint ptr) {
+    NativeMessageQueue* nativeMessageQueue = reinterpret_cast<NativeMessageQueue*>(ptr);
+    nativeMessageQueue->decStrong(env);
 }
 
-static void throwQueueNotInitialized(JNIEnv* env) {
-    jniThrowException(env, "java/lang/IllegalStateException", "Message queue not initialized");
-}
-
-static void android_os_MessageQueue_nativePollOnce(JNIEnv* env, jobject obj,
+static void android_os_MessageQueue_nativePollOnce(JNIEnv* env, jclass clazz,
         jint ptr, jint timeoutMillis) {
     NativeMessageQueue* nativeMessageQueue = reinterpret_cast<NativeMessageQueue*>(ptr);
     nativeMessageQueue->pollOnce(env, timeoutMillis);
 }
 
-static void android_os_MessageQueue_nativeWake(JNIEnv* env, jobject obj, jint ptr) {
+static void android_os_MessageQueue_nativeWake(JNIEnv* env, jclass clazz, jint ptr) {
     NativeMessageQueue* nativeMessageQueue = reinterpret_cast<NativeMessageQueue*>(ptr);
     return nativeMessageQueue->wake();
 }
@@ -166,8 +145,8 @@
 
 static JNINativeMethod gMessageQueueMethods[] = {
     /* name, signature, funcPtr */
-    { "nativeInit", "()V", (void*)android_os_MessageQueue_nativeInit },
-    { "nativeDestroy", "()V", (void*)android_os_MessageQueue_nativeDestroy },
+    { "nativeInit", "()I", (void*)android_os_MessageQueue_nativeInit },
+    { "nativeDestroy", "(I)V", (void*)android_os_MessageQueue_nativeDestroy },
     { "nativePollOnce", "(II)V", (void*)android_os_MessageQueue_nativePollOnce },
     { "nativeWake", "(I)V", (void*)android_os_MessageQueue_nativeWake }
 };
diff --git a/core/tests/coretests/AndroidManifest.xml b/core/tests/coretests/AndroidManifest.xml
index 41f8536..f8b26bc 100644
--- a/core/tests/coretests/AndroidManifest.xml
+++ b/core/tests/coretests/AndroidManifest.xml
@@ -1241,13 +1241,6 @@
             </intent-filter>
         </activity>
 
-        <activity android:name="android.accessibilityservice.InterrogationActivity">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
-            </intent-filter>
-        </activity>
-
         <activity android:name="android.animation.BasicAnimatorActivity">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
diff --git a/core/tests/coretests/src/android/accessibilityservice/InterrogationActivity.java b/core/tests/coretests/src/android/accessibilityservice/InterrogationActivity.java
deleted file mode 100644
index a9f144b..0000000
--- a/core/tests/coretests/src/android/accessibilityservice/InterrogationActivity.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/**
- * Copyright (C) 2011 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.
- */
-
-package android.accessibilityservice;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.view.View;
-
-import com.android.frameworks.coretests.R;
-
-/**
- * Activity for testing the accessibility APIs for "interrogation" of
- * the screen content. These APIs allow exploring the screen and
- * requesting an action to be performed on a given view from an
- * AccessiiblityService.
- */
-public class InterrogationActivity extends Activity {
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.interrogation_activity);
-
-        findViewById(R.id.button5).setOnClickListener(new View.OnClickListener() {
-            public void onClick(View v) {
-                /* do nothing */
-            }
-        });
-        findViewById(R.id.button5).setOnLongClickListener(new View.OnLongClickListener() {
-            public boolean onLongClick(View v) {
-                return true;
-            }
-        });
-    }
-}
diff --git a/core/tests/coretests/src/android/accessibilityservice/InterrogationActivityTest.java b/core/tests/coretests/src/android/accessibilityservice/InterrogationActivityTest.java
deleted file mode 100644
index 3dc140b..0000000
--- a/core/tests/coretests/src/android/accessibilityservice/InterrogationActivityTest.java
+++ /dev/null
@@ -1,472 +0,0 @@
-/**
- * Copyright (C) 2011 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.
- */
-
-package android.accessibilityservice;
-
-import static android.view.accessibility.AccessibilityNodeInfo.ACTION_FOCUS;
-import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLEAR_FOCUS;
-import static android.view.accessibility.AccessibilityNodeInfo.ACTION_SELECT;
-import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLEAR_SELECTION;
-
-import android.graphics.Rect;
-import android.os.SystemClock;
-import android.test.ActivityInstrumentationTestCase2;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.util.Log;
-import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityNodeInfo;
-
-import com.android.frameworks.coretests.R;
-import com.android.internal.util.Predicate;
-
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Queue;
-
-/**
- * Activity for testing the accessibility APIs for "interrogation" of
- * the screen content. These APIs allow exploring the screen and
- * requesting an action to be performed on a given view from an
- * AccessiiblityService.
- */
-public class InterrogationActivityTest
-        extends ActivityInstrumentationTestCase2<InterrogationActivity> {
-    private static final boolean DEBUG = false;
-
-    private static String LOG_TAG = "InterrogationActivityTest";
-
-    // Timeout for the accessibility state of an Activity to be fully initialized.
-    private static final int TIMEOUT_PROPAGATE_ACCESSIBILITY_EVENT_MILLIS = 5000;
-
-    // Timeout for which non getting accessibility events considers the app idle.
-    private static final long IDLE_EVENT_TIME_DELTA_MILLIS = 200;
-
-    // Timeout in which to wait for idle device.
-    private static final long GLOBAL_IDLE_DETECTION_TIMEOUT_MILLIS = 1000;
-
-    // Handle to a connection to the AccessibilityManagerService
-    private UiTestAutomationBridge mUiTestAutomationBridge;
-
-    public InterrogationActivityTest() {
-        super(InterrogationActivity.class);
-    }
-
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-        mUiTestAutomationBridge = new UiTestAutomationBridge();
-        mUiTestAutomationBridge.connect();
-        mUiTestAutomationBridge.waitForIdle(IDLE_EVENT_TIME_DELTA_MILLIS,
-                GLOBAL_IDLE_DETECTION_TIMEOUT_MILLIS);
-        mUiTestAutomationBridge.executeCommandAndWaitForAccessibilityEvent(new Runnable() {
-                // wait for the first accessibility event
-                @Override
-                public void run() {
-                    // bring up the activity
-                    getActivity();
-                }
-            },
-            new Predicate<AccessibilityEvent>() {
-                @Override
-                public boolean apply(AccessibilityEvent event) {
-                    return (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED
-                            && event.getPackageName().equals(getActivity().getPackageName()));
-                }
-            },
-            TIMEOUT_PROPAGATE_ACCESSIBILITY_EVENT_MILLIS);
-    }
-
-    @Override
-    public void tearDown() throws Exception {
-        mUiTestAutomationBridge.disconnect();
-        super.tearDown();
-    }
-
-    @LargeTest
-    public void testFindAccessibilityNodeInfoByViewId() throws Exception {
-        final long startTimeMillis = SystemClock.uptimeMillis();
-        try {
-            AccessibilityNodeInfo button = mUiTestAutomationBridge
-                .findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5);
-            assertNotNull(button);
-            assertEquals(0, button.getChildCount());
-
-            // bounds
-            Rect bounds = new Rect();
-            button.getBoundsInParent(bounds);
-            assertEquals(0, bounds.left);
-            assertEquals(0, bounds.top);
-            assertEquals(160, bounds.right);
-            assertEquals(100, bounds.bottom);
-
-            // char sequence attributes
-            assertEquals("com.android.frameworks.coretests", button.getPackageName());
-            assertEquals("android.widget.Button", button.getClassName());
-            assertEquals("Button5", button.getText());
-            assertNull(button.getContentDescription());
-
-            // boolean attributes
-            assertTrue(button.isFocusable());
-            assertTrue(button.isClickable());
-            assertTrue(button.isEnabled());
-            assertFalse(button.isFocused());
-            assertTrue(button.isClickable());
-            assertFalse(button.isPassword());
-            assertFalse(button.isSelected());
-            assertFalse(button.isCheckable());
-            assertFalse(button.isChecked());
-
-            // actions
-            assertEquals(ACTION_FOCUS | ACTION_SELECT | ACTION_CLEAR_SELECTION,
-                button.getActions());
-        } finally {
-            if (DEBUG) {
-                final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
-                Log.i(LOG_TAG, "testFindAccessibilityNodeInfoByViewId: "
-                        + elapsedTimeMillis + "ms");
-            }
-        }
-    }
-
-    @LargeTest
-    public void testFindAccessibilityNodeInfoByViewText() throws Exception {
-        final long startTimeMillis = SystemClock.uptimeMillis();
-        try {
-            // find a view by text
-            List<AccessibilityNodeInfo> buttons = mUiTestAutomationBridge
-                .findAccessibilityNodeInfosByTextInActiveWindow("butto");
-            assertEquals(9, buttons.size());
-        } finally {
-            if (DEBUG) {
-                final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
-                Log.i(LOG_TAG, "testFindAccessibilityNodeInfoByViewText: "
-                        + elapsedTimeMillis + "ms");
-            }
-        }
-    }
-
-    @LargeTest
-    public void testFindAccessibilityNodeInfoByViewTextContentDescription() throws Exception {
-        final long startTimeMillis = SystemClock.uptimeMillis();
-        try {
-            // find a view by text
-            List<AccessibilityNodeInfo> buttons = mUiTestAutomationBridge
-                .findAccessibilityNodeInfosByTextInActiveWindow("contentDescription");
-            assertEquals(1, buttons.size());
-        } finally {
-            if (DEBUG) {
-                final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
-                Log.i(LOG_TAG, "testFindAccessibilityNodeInfoByViewTextContentDescription: "
-                        + elapsedTimeMillis + "ms");
-            }
-        }
-    }
-
-    @LargeTest
-    public void testTraverseAllViews() throws Exception {
-        final long startTimeMillis = SystemClock.uptimeMillis();
-        try {
-            // make list of expected nodes
-            List<String> classNameAndTextList = new ArrayList<String>();
-            classNameAndTextList.add("android.widget.LinearLayout");
-            classNameAndTextList.add("android.widget.LinearLayout");
-            classNameAndTextList.add("android.widget.LinearLayout");
-            classNameAndTextList.add("android.widget.LinearLayout");
-            classNameAndTextList.add("android.widget.ButtonButton1");
-            classNameAndTextList.add("android.widget.ButtonButton2");
-            classNameAndTextList.add("android.widget.ButtonButton3");
-            classNameAndTextList.add("android.widget.ButtonButton4");
-            classNameAndTextList.add("android.widget.ButtonButton5");
-            classNameAndTextList.add("android.widget.ButtonButton6");
-            classNameAndTextList.add("android.widget.ButtonButton7");
-            classNameAndTextList.add("android.widget.ButtonButton8");
-            classNameAndTextList.add("android.widget.ButtonButton9");
-
-            AccessibilityNodeInfo root = mUiTestAutomationBridge
-                .findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.root);
-            assertNotNull("We must find the existing root.", root);
-
-            Queue<AccessibilityNodeInfo> fringe = new LinkedList<AccessibilityNodeInfo>();
-            fringe.add(root);
-
-            // do a BFS traversal and check nodes
-            while (!fringe.isEmpty()) {
-                AccessibilityNodeInfo current = fringe.poll();
-
-                CharSequence className = current.getClassName();
-                CharSequence text = current.getText();
-                String receivedClassNameAndText = className.toString()
-                   + ((text != null) ? text.toString() : "");
-                String expectedClassNameAndText = classNameAndTextList.remove(0);
-
-                assertEquals("Did not get the expected node info",
-                        expectedClassNameAndText, receivedClassNameAndText);
-
-                final int childCount = current.getChildCount();
-                for (int i = 0; i < childCount; i++) {
-                    AccessibilityNodeInfo child = current.getChild(i);
-                    fringe.add(child);
-                }
-            }
-        } finally {
-            if (DEBUG) {
-                final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
-                Log.i(LOG_TAG, "testTraverseAllViews: " + elapsedTimeMillis + "ms");
-            }
-        }
-    }
-
-    @LargeTest
-    public void testPerformAccessibilityActionFocus() throws Exception {
-        final long startTimeMillis = SystemClock.uptimeMillis();
-        try {
-            // find a view and make sure it is not focused
-            AccessibilityNodeInfo button = mUiTestAutomationBridge
-                .findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5);
-            assertFalse(button.isFocused());
-
-            // focus the view
-            assertTrue(button.performAction(ACTION_FOCUS));
-
-            // find the view again and make sure it is focused
-            button = mUiTestAutomationBridge
-                    .findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5);
-            assertTrue(button.isFocused());
-        } finally {
-            if (DEBUG) {
-                final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
-                Log.i(LOG_TAG, "testPerformAccessibilityActionFocus: " + elapsedTimeMillis + "ms");
-            }
-        }
-    }
-
-    @LargeTest
-    public void testPerformAccessibilityActionClearFocus() throws Exception {
-        final long startTimeMillis = SystemClock.uptimeMillis();
-        try {
-            // find a view and make sure it is not focused
-            AccessibilityNodeInfo button = mUiTestAutomationBridge
-                .findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5);
-            assertFalse(button.isFocused());
-
-            // focus the view
-            assertTrue(button.performAction(ACTION_FOCUS));
-
-            // find the view again and make sure it is focused
-            button = mUiTestAutomationBridge
-                .findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5);
-            assertTrue(button.isFocused());
-
-            // unfocus the view
-            assertTrue(button.performAction(ACTION_CLEAR_FOCUS));
-
-            // find the view again and make sure it is not focused
-            button = mUiTestAutomationBridge
-                .findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5);
-            assertFalse(button.isFocused());
-        } finally {
-            if (DEBUG) {
-                final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
-                Log.i(LOG_TAG, "testPerformAccessibilityActionClearFocus: "
-                        + elapsedTimeMillis + "ms");
-            }
-        }
-    }
-
-    @LargeTest
-    public void testPerformAccessibilityActionSelect() throws Exception {
-        final long startTimeMillis = SystemClock.uptimeMillis();
-        try {
-            // find a view and make sure it is not selected
-            AccessibilityNodeInfo button = mUiTestAutomationBridge
-                .findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5);
-            assertFalse(button.isSelected());
-
-            // select the view
-            assertTrue(button.performAction(ACTION_SELECT));
-
-            // find the view again and make sure it is selected
-            button = mUiTestAutomationBridge
-                .findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5);
-            assertTrue(button.isSelected());
-        } finally {
-            if (DEBUG) {
-                final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
-                Log.i(LOG_TAG, "testPerformAccessibilityActionSelect: " + elapsedTimeMillis + "ms");
-            }
-        }
-    }
-
-    @LargeTest
-    public void testPerformAccessibilityActionClearSelection() throws Exception {
-        final long startTimeMillis = SystemClock.uptimeMillis();
-        try {
-            // find a view and make sure it is not selected
-            AccessibilityNodeInfo button = mUiTestAutomationBridge
-                .findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5);
-            assertFalse(button.isSelected());
-
-            // select the view
-            assertTrue(button.performAction(ACTION_SELECT));
-
-            // find the view again and make sure it is selected
-            button = mUiTestAutomationBridge
-                .findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5);
-            assertTrue(button.isSelected());
-
-            // unselect the view
-            assertTrue(button.performAction(ACTION_CLEAR_SELECTION));
-
-            // find the view again and make sure it is not selected
-            button = mUiTestAutomationBridge
-                .findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5);
-            assertFalse(button.isSelected());
-        } finally {
-            if (DEBUG) {
-                final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
-                Log.i(LOG_TAG, "testPerformAccessibilityActionClearSelection: "
-                        + elapsedTimeMillis + "ms");
-            }
-        }
-    }
-
-    @LargeTest
-    public void testAccessibilityEventGetSource() throws Exception {
-        final long startTimeMillis = SystemClock.uptimeMillis();
-        try {
-            // find a view and make sure it is not focused
-            final AccessibilityNodeInfo button = mUiTestAutomationBridge
-                .findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5);
-            assertFalse(button.isFocused());
-
-            AccessibilityEvent event = mUiTestAutomationBridge
-                    .executeCommandAndWaitForAccessibilityEvent(new Runnable() {
-                @Override
-                public void run() {
-                    // focus the view
-                    assertTrue(button.performAction(ACTION_FOCUS));
-                }
-            },
-            new Predicate<AccessibilityEvent>() {
-                @Override
-                public boolean apply(AccessibilityEvent event) {
-                    return (event.getEventType() == AccessibilityEvent.TYPE_VIEW_FOCUSED
-                            && event.getPackageName().equals(getActivity().getPackageName())
-                            && event.getText().get(0).equals(button.getText()));
-                }
-            },
-            TIMEOUT_PROPAGATE_ACCESSIBILITY_EVENT_MILLIS);
-
-            // check the last event
-            assertNotNull(event);
-
-            // check that last event source
-            AccessibilityNodeInfo source = event.getSource();
-            assertNotNull(source);
-
-            // bounds
-            Rect buttonBounds = new Rect();
-            button.getBoundsInParent(buttonBounds);
-            Rect sourceBounds = new Rect();
-            source.getBoundsInParent(sourceBounds);
-
-            assertEquals(buttonBounds.left, sourceBounds.left);
-            assertEquals(buttonBounds.right, sourceBounds.right);
-            assertEquals(buttonBounds.top, sourceBounds.top);
-            assertEquals(buttonBounds.bottom, sourceBounds.bottom);
-
-            // char sequence attributes
-            assertEquals(button.getPackageName(), source.getPackageName());
-            assertEquals(button.getClassName(), source.getClassName());
-            assertEquals(button.getText(), source.getText());
-            assertSame(button.getContentDescription(), source.getContentDescription());
-
-            // boolean attributes
-            assertSame(button.isFocusable(), source.isFocusable());
-            assertSame(button.isClickable(), source.isClickable());
-            assertSame(button.isEnabled(), source.isEnabled());
-            assertNotSame(button.isFocused(), source.isFocused());
-            assertSame(button.isLongClickable(), source.isLongClickable());
-            assertSame(button.isPassword(), source.isPassword());
-            assertSame(button.isSelected(), source.isSelected());
-            assertSame(button.isCheckable(), source.isCheckable());
-            assertSame(button.isChecked(), source.isChecked());
-        } finally {
-            if (DEBUG) {
-                final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
-                Log.i(LOG_TAG, "testAccessibilityEventGetSource: " + elapsedTimeMillis + "ms");
-            }
-        }
-    }
-
-    @LargeTest
-    public void testObjectContract() throws Exception {
-        final long startTimeMillis = SystemClock.uptimeMillis();
-        try {
-            // find a view and make sure it is not focused
-            AccessibilityNodeInfo button = mUiTestAutomationBridge
-                .findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5);
-            assertNotNull(button);
-            AccessibilityNodeInfo parent = button.getParent();
-            final int childCount = parent.getChildCount();
-            for (int i = 0; i < childCount; i++) {
-                AccessibilityNodeInfo child = parent.getChild(i);
-                assertNotNull(child);
-                if (child.equals(button)) {
-                    assertEquals("Equal objects must have same hasCode.", button.hashCode(),
-                            child.hashCode());
-                    return;
-                }
-            }
-            fail("Parent's children do not have the info whose parent is the parent.");
-        } finally {
-            if (DEBUG) {
-                final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
-                Log.i(LOG_TAG, "testObjectContract: " + elapsedTimeMillis + "ms");
-            }
-        }
-    }
-
-    @LargeTest
-    public void testGetRootAccessibilityNodeInfoInActiveWindow() throws Exception {
-        final long startTimeMillis = SystemClock.uptimeMillis();
-        try {
-            // get the root via the designated API
-            AccessibilityNodeInfo fetched = mUiTestAutomationBridge
-                    .getRootAccessibilityNodeInfoInActiveWindow();
-            assertNotNull(fetched);
-
-            // get the root via traversal
-            AccessibilityNodeInfo expected = mUiTestAutomationBridge
-                    .findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.root);
-            while (true) {
-                AccessibilityNodeInfo parent = expected.getParent();
-                if (parent == null) {
-                    break;
-                }
-                expected = parent;
-            }
-            assertNotNull(expected);
-
-            assertEquals("The node with id \"root\" should be the root.", expected, fetched);
-        } finally {
-            if (DEBUG) {
-                final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
-                Log.i(LOG_TAG, "testGetRootAccessibilityNodeInfoInActiveWindow: "
-                        + elapsedTimeMillis + "ms");
-            }
-        }
-    }
-}
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 0d409d5..d1fb2b0 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -4141,6 +4141,11 @@
         return rotation == mPortraitRotation || rotation == mUpsideDownRotation;
     }
 
+    public int getUserRotationMode() {
+        return Settings.System.getIntForUser(mContext.getContentResolver(),
+                Settings.System.USER_ROTATION, WindowManagerPolicy.USER_ROTATION_FREE,
+                UserHandle.USER_CURRENT);
+    }
 
     // User rotation: to be used when all else fails in assigning an orientation to the device
     public void setUserRotationMode(int mode, int rot) {
diff --git a/services/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
index 0725df0..b7c3450 100644
--- a/services/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -17,7 +17,6 @@
 package com.android.server.accessibility;
 
 import static android.accessibilityservice.AccessibilityServiceInfo.DEFAULT;
-import static android.accessibilityservice.AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;
 
 import android.Manifest;
 import android.accessibilityservice.AccessibilityService;
@@ -518,6 +517,10 @@
         ComponentName componentName = new ComponentName("foo.bar",
                 "AutomationAccessibilityService");
         synchronized (mLock) {
+            if (mUiAutomationService != null) {
+                throw new IllegalStateException("UiAutomationService " + serviceClient
+                        + "already registered!");
+            }
             // If an automation services is connected to the system all services are stopped
             // so the automation one is the only one running. Settings are not changed so when
             // the automation service goes away the state is restored from the settings.
@@ -556,7 +559,8 @@
         synchronized (mLock) {
             UserState userState = getCurrentUserStateLocked();
             // Stash the old state so we can restore it when the keyguard is gone.
-            mTempStateChangeForCurrentUserMemento.initialize(mCurrentUserId, getCurrentUserStateLocked());
+            mTempStateChangeForCurrentUserMemento.initialize(mCurrentUserId,
+                    getCurrentUserStateLocked());
             // Set the temporary state.
             userState.mIsAccessibilityEnabled = true;
             userState.mIsTouchExplorationEnabled= touchExplorationEnabled;
@@ -579,6 +583,9 @@
                     && serviceClient != null && mUiAutomationService.mServiceInterface
                             .asBinder() == serviceClient.asBinder()) {
                 mUiAutomationService.binderDied();
+            } else {
+                throw new IllegalStateException("UiAutomationService " + serviceClient
+                        + " not registered!");
             }
         }
     }
@@ -935,7 +942,8 @@
         }
 
         if (!event.isImportantForAccessibility()
-                && !service.mIncludeNotImportantViews) {
+                && (service.mFetchFlags
+                        & AccessibilityNodeInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS) == 0) {
             return false;
         }
 
@@ -1486,7 +1494,7 @@
 
         boolean mRequestTouchExplorationMode;
 
-        boolean mIncludeNotImportantViews;
+        int mFetchFlags;
 
         long mNotificationTimeout;
 
@@ -1565,10 +1573,15 @@
 
             if (mIsAutomation || info.getResolveInfo().serviceInfo.applicationInfo.targetSdkVersion
                     >= Build.VERSION_CODES.JELLY_BEAN) {
-                mIncludeNotImportantViews =
-                    (info.flags & FLAG_INCLUDE_NOT_IMPORTANT_VIEWS) != 0;
+                mFetchFlags |= (info.flags
+                        & AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS) != 0 ?
+                                AccessibilityNodeInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS : 0;
             }
 
+            mFetchFlags |= (info.flags
+                    & AccessibilityServiceInfo.FLAG_REPORT_VIEW_IDS) != 0 ?
+                            AccessibilityNodeInfo.FLAG_REPORT_VIEW_IDS : 0;
+
             mRequestTouchExplorationMode = (info.flags
                     & AccessibilityServiceInfo.FLAG_REQUEST_TOUCH_EXPLORATION_MODE) != 0;
 
@@ -1664,8 +1677,8 @@
         }
 
         @Override
-        public boolean findAccessibilityNodeInfoByViewId(int accessibilityWindowId,
-                long accessibilityNodeId, int viewId, int interactionId,
+        public boolean findAccessibilityNodeInfosByViewId(int accessibilityWindowId,
+                long accessibilityNodeId, String viewIdResName, int interactionId,
                 IAccessibilityInteractionConnectionCallback callback, long interrogatingTid)
                 throws RemoteException {
             final int resolvedWindowId;
@@ -1689,14 +1702,13 @@
                     }
                 }
             }
-            final int flags = (mIncludeNotImportantViews) ?
-                    AccessibilityNodeInfo.INCLUDE_NOT_IMPORTANT_VIEWS : 0;
             final int interrogatingPid = Binder.getCallingPid();
             final long identityToken = Binder.clearCallingIdentity();
             MagnificationSpec spec = getCompatibleMagnificationSpec(resolvedWindowId);
             try {
-                connection.findAccessibilityNodeInfoByViewId(accessibilityNodeId, viewId,
-                        interactionId, callback, flags, interrogatingPid, interrogatingTid, spec);
+                connection.findAccessibilityNodeInfosByViewId(accessibilityNodeId,
+                        viewIdResName, interactionId, callback, mFetchFlags, interrogatingPid,
+                        interrogatingTid, spec);
                 return true;
             } catch (RemoteException re) {
                 if (DEBUG) {
@@ -1735,14 +1747,13 @@
                     }
                 }
             }
-            final int flags = (mIncludeNotImportantViews) ?
-                    AccessibilityNodeInfo.INCLUDE_NOT_IMPORTANT_VIEWS : 0;
             final int interrogatingPid = Binder.getCallingPid();
             final long identityToken = Binder.clearCallingIdentity();
             MagnificationSpec spec = getCompatibleMagnificationSpec(resolvedWindowId);
             try {
                 connection.findAccessibilityNodeInfosByText(accessibilityNodeId, text,
-                        interactionId, callback, flags, interrogatingPid, interrogatingTid, spec);
+                        interactionId, callback, mFetchFlags, interrogatingPid, interrogatingTid,
+                        spec);
                 return true;
             } catch (RemoteException re) {
                 if (DEBUG) {
@@ -1781,15 +1792,13 @@
                     }
                 }
             }
-            final int allFlags = flags | ((mIncludeNotImportantViews) ?
-                    AccessibilityNodeInfo.INCLUDE_NOT_IMPORTANT_VIEWS : 0);
             final int interrogatingPid = Binder.getCallingPid();
             final long identityToken = Binder.clearCallingIdentity();
             MagnificationSpec spec = getCompatibleMagnificationSpec(resolvedWindowId);
             try {
                 connection.findAccessibilityNodeInfoByAccessibilityId(accessibilityNodeId,
-                        interactionId, callback, allFlags, interrogatingPid, interrogatingTid,
-                        spec);
+                        interactionId, callback, mFetchFlags | flags, interrogatingPid,
+                        interrogatingTid, spec);
                 return true;
             } catch (RemoteException re) {
                 if (DEBUG) {
@@ -1828,14 +1837,12 @@
                     }
                 }
             }
-            final int flags = (mIncludeNotImportantViews) ?
-                    AccessibilityNodeInfo.INCLUDE_NOT_IMPORTANT_VIEWS : 0;
             final int interrogatingPid = Binder.getCallingPid();
             final long identityToken = Binder.clearCallingIdentity();
             MagnificationSpec spec = getCompatibleMagnificationSpec(resolvedWindowId);
             try {
                 connection.findFocus(accessibilityNodeId, focusType, interactionId, callback,
-                        flags, interrogatingPid, interrogatingTid, spec);
+                        mFetchFlags, interrogatingPid, interrogatingTid, spec);
                 return true;
             } catch (RemoteException re) {
                 if (DEBUG) {
@@ -1874,14 +1881,12 @@
                     }
                 }
             }
-            final int flags = (mIncludeNotImportantViews) ?
-                    AccessibilityNodeInfo.INCLUDE_NOT_IMPORTANT_VIEWS : 0;
             final int interrogatingPid = Binder.getCallingPid();
             final long identityToken = Binder.clearCallingIdentity();
             MagnificationSpec spec = getCompatibleMagnificationSpec(resolvedWindowId);
             try {
                 connection.focusSearch(accessibilityNodeId, direction, interactionId, callback,
-                        flags, interrogatingPid, interrogatingTid, spec);
+                        mFetchFlags, interrogatingPid, interrogatingTid, spec);
                 return true;
             } catch (RemoteException re) {
                 if (DEBUG) {
@@ -1920,13 +1925,11 @@
                     }
                 }
             }
-            final int flags = (mIncludeNotImportantViews) ?
-                    AccessibilityNodeInfo.INCLUDE_NOT_IMPORTANT_VIEWS : 0;
             final int interrogatingPid = Binder.getCallingPid();
             final long identityToken = Binder.clearCallingIdentity();
             try {
                 connection.performAccessibilityAction(accessibilityNodeId, action, arguments,
-                        interactionId, callback, flags, interrogatingPid, interrogatingTid);
+                        interactionId, callback, mFetchFlags, interrogatingPid, interrogatingTid);
             } catch (RemoteException re) {
                 if (DEBUG) {
                     Slog.e(LOG_TAG, "Error calling performAccessibilityAction()");
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index e0046ad..ca60a93 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -51,6 +51,7 @@
 import android.app.IServiceConnection;
 import android.app.IStopUserCallback;
 import android.app.IThumbnailReceiver;
+import android.app.IUiAutomationConnection;
 import android.app.IUserSwitchObserver;
 import android.app.Instrumentation;
 import android.app.Notification;
@@ -162,7 +163,7 @@
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicLong;
 
-public final class ActivityManagerService extends ActivityManagerNative
+public final class ActivityManagerService  extends ActivityManagerNative
         implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
     private static final String USER_DATA_DIR = "/data/user/";
     static final String TAG = "ActivityManager";
@@ -4283,8 +4284,9 @@
             }
             thread.bindApplication(processName, appInfo, providers,
                     app.instrumentationClass, profileFile, profileFd, profileAutoStop,
-                    app.instrumentationArguments, app.instrumentationWatcher, testMode,
-                    enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent,
+                    app.instrumentationArguments, app.instrumentationWatcher,
+                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
+                    isRestrictedBackupMode || !normalMode, app.persistent,
                     new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
                     mCoreSettingsObserver.getCoreSettingsLocked());
             updateLruProcessLocked(app, false);
@@ -12228,7 +12230,8 @@
 
     public boolean startInstrumentation(ComponentName className,
             String profileFile, int flags, Bundle arguments,
-            IInstrumentationWatcher watcher, int userId) {
+            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
+            int userId) {
         enforceNotIsolatedCaller("startInstrumentation");
         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
                 userId, false, true, "startInstrumentation", null);
@@ -12282,6 +12285,7 @@
             app.instrumentationProfileFile = profileFile;
             app.instrumentationArguments = arguments;
             app.instrumentationWatcher = watcher;
+            app.instrumentationUiAutomationConnection = uiAutomationConnection;
             app.instrumentationResultClass = className;
             Binder.restoreCallingIdentity(origId);
         }
@@ -12324,7 +12328,15 @@
             } catch (RemoteException e) {
             }
         }
+        if (app.instrumentationUiAutomationConnection != null) {
+            try {
+                app.instrumentationUiAutomationConnection.shutdown();
+            } catch (RemoteException re) {
+                /* ignore */
+            }
+        }
         app.instrumentationWatcher = null;
+        app.instrumentationUiAutomationConnection = null;
         app.instrumentationClass = null;
         app.instrumentationInfo = null;
         app.instrumentationProfileFile = null;
diff --git a/services/java/com/android/server/am/ProcessRecord.java b/services/java/com/android/server/am/ProcessRecord.java
index 7fbab04..a32af2f 100644
--- a/services/java/com/android/server/am/ProcessRecord.java
+++ b/services/java/com/android/server/am/ProcessRecord.java
@@ -22,6 +22,7 @@
 import android.app.Dialog;
 import android.app.IApplicationThread;
 import android.app.IInstrumentationWatcher;
+import android.app.IUiAutomationConnection;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
@@ -95,6 +96,7 @@
     ApplicationInfo instrumentationInfo; // the application being instrumented
     String instrumentationProfileFile; // where to save profiling
     IInstrumentationWatcher instrumentationWatcher; // who is waiting
+    IUiAutomationConnection instrumentationUiAutomationConnection; // Connection to use the UI introspection APIs.
     Bundle instrumentationArguments;// as given to us
     ComponentName instrumentationResultClass;// copy of instrumentationClass
     boolean usingWrapper;       // Set to true when process was launched with a wrapper attached
diff --git a/services/java/com/android/server/usb/UsbDeviceManager.java b/services/java/com/android/server/usb/UsbDeviceManager.java
index c7c2c62..8fa6de5 100644
--- a/services/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/java/com/android/server/usb/UsbDeviceManager.java
@@ -169,7 +169,9 @@
             startAccessoryMode();
         }
 
-        if ("1".equals(SystemProperties.get("ro.adb.secure"))) {
+        boolean secureAdbEnabled = SystemProperties.getBoolean("ro.adb.secure", false);
+        boolean dataEncrypted = "1".equals(SystemProperties.get("vold.decrypt"));
+        if (secureAdbEnabled && !dataEncrypted) {
             mDebuggingManager = new UsbDebuggingManager(context);
         }
     }
diff --git a/services/java/com/android/server/wm/DisplayMagnifier.java b/services/java/com/android/server/wm/DisplayMagnifier.java
index d3c01f0..6e876f6 100644
--- a/services/java/com/android/server/wm/DisplayMagnifier.java
+++ b/services/java/com/android/server/wm/DisplayMagnifier.java
@@ -228,6 +228,10 @@
         return spec;
     }
 
+    public void destroyLocked() {
+        mMagnifedViewport.destroyWindow();
+    }
+
     /** NOTE: This has to be called within a surface transaction. */
     public void drawMagnifiedRegionBorderIfNeededLocked() {
         mMagnifedViewport.drawWindowIfNeededLocked();
@@ -258,7 +262,7 @@
         private final int mBorderWidth;
         private final int mHalfBorderWidth;
 
-        private ViewportWindow mWindow;
+        private final ViewportWindow mWindow;
 
         private boolean mFullRedrawNeeded;
 
@@ -459,6 +463,10 @@
             mWindow.drawIfNeeded();
         }
 
+        public void destroyWindow() {
+            mWindow.releaseSurface();
+        }
+
         private final class ViewportWindow {
             private static final String SURFACE_TITLE = "Magnification Overlay";
 
@@ -640,6 +648,10 @@
                     }
                 }
             }
+
+            public void releaseSurface() {
+                mSurface.release();
+            }
         }
     }
 
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index ff2dc0f..1e5cd54 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -3039,7 +3039,10 @@
                 mDisplayMagnifier = new DisplayMagnifier(this, callbacks);
             } else {
                 if (callbacks == null) {
-                    mDisplayMagnifier = null;
+                    if (mDisplayMagnifier != null) {
+                        mDisplayMagnifier.destroyLocked();
+                        mDisplayMagnifier = null;
+                    }
                 } else {
                     throw new IllegalStateException("Magnification callbacks already set!");
                 }
@@ -5598,6 +5601,11 @@
     }
 
     @Override
+    public boolean isRotationFrozen() {
+        return mPolicy.getUserRotationMode() == WindowManagerPolicy.USER_ROTATION_LOCKED;
+    }
+
+    @Override
     public int watchRotation(IRotationWatcher watcher) {
         final IBinder watcherBinder = watcher.asBinder();
         IBinder.DeathRecipient dr = new IBinder.DeathRecipient() {
diff --git a/services/jni/com_android_server_input_InputManagerService.cpp b/services/jni/com_android_server_input_InputManagerService.cpp
index a97becf..57803e3 100644
--- a/services/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/jni/com_android_server_input_InputManagerService.cpp
@@ -975,6 +975,11 @@
 static jint nativeInit(JNIEnv* env, jclass clazz,
         jobject serviceObj, jobject contextObj, jobject messageQueueObj) {
     sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);
+    if (messageQueue == NULL) {
+        jniThrowRuntimeException(env, "MessageQueue is not initialized.");
+        return 0;
+    }
+
     NativeInputManager* im = new NativeInputManager(contextObj, serviceObj,
             messageQueue->getLooper());
     im->incStrong(serviceObj);
diff --git a/test-runner/src/android/test/AndroidTestRunner.java b/test-runner/src/android/test/AndroidTestRunner.java
index 30876d0..aa7c677 100644
--- a/test-runner/src/android/test/AndroidTestRunner.java
+++ b/test-runner/src/android/test/AndroidTestRunner.java
@@ -21,6 +21,7 @@
 import android.os.PerformanceCollector.PerformanceResultsWriter;
 
 import com.google.android.collect.Lists;
+
 import junit.framework.Test;
 import junit.framework.TestCase;
 import junit.framework.TestListener;
diff --git a/test-runner/src/android/test/InstrumentationTestRunner.java b/test-runner/src/android/test/InstrumentationTestRunner.java
index 8e30875..91d04da 100644
--- a/test-runner/src/android/test/InstrumentationTestRunner.java
+++ b/test-runner/src/android/test/InstrumentationTestRunner.java
@@ -390,12 +390,11 @@
     }
 
     /**
-     * Get the Bundle object that contains the arguments
+     * Get the arguments passed to this instrumentation.
      *
      * @return the Bundle object
-     * @hide
      */
-    public Bundle getBundle(){
+    public Bundle getArguments() {
         return mArguments;
     }
 
diff --git a/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java b/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java
index e2cb65d..6b9f4c3 100644
--- a/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java
+++ b/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java
@@ -60,7 +60,7 @@
     public void testMeasureStartUpTime() throws RemoteException {
         InstrumentationTestRunner instrumentation =
                 (InstrumentationTestRunner)getInstrumentation();
-        Bundle args = instrumentation.getBundle();
+        Bundle args = instrumentation.getArguments();
         mAm = ActivityManagerNative.getDefault();
 
         createMappings();
diff --git a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
index f012bcb..9f116fc 100644
--- a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
+++ b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
@@ -487,4 +487,10 @@
         // TODO Auto-generated method stub
         return null;
     }
+
+    @Override
+    public boolean isRotationFrozen() throws RemoteException {
+        // TODO Auto-generated method stub
+        return false;
+    }
 }
diff --git a/voip/java/android/net/rtp/AudioCodec.java b/voip/java/android/net/rtp/AudioCodec.java
deleted file mode 100644
index 85255c8..0000000
--- a/voip/java/android/net/rtp/AudioCodec.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-package android.net.rtp;
-
-import java.util.Arrays;
-
-/**
- * This class defines a collection of audio codecs to be used with
- * {@link AudioStream}s. Their parameters are designed to be exchanged using
- * Session Description Protocol (SDP). Most of the values listed here can be
- * found in RFC 3551, while others are described in separated standards.
- *
- * <p>Few simple configurations are defined as public static instances for the
- * convenience of direct uses. More complicated ones could be obtained using
- * {@link #getCodec(int, String, String)}. For example, one can use the
- * following snippet to create a mode-1-only AMR codec.</p>
- * <pre>
- * AudioCodec codec = AudioCodec.getCodec(100, "AMR/8000", "mode-set=1");
- * </pre>
- *
- * @see AudioStream
- */
-public class AudioCodec {
-    /**
-     * The RTP payload type of the encoding.
-     */
-    public final int type;
-
-    /**
-     * The encoding parameters to be used in the corresponding SDP attribute.
-     */
-    public final String rtpmap;
-
-    /**
-     * The format parameters to be used in the corresponding SDP attribute.
-     */
-    public final String fmtp;
-
-    /**
-     * G.711 u-law audio codec.
-     */
-    public static final AudioCodec PCMU = new AudioCodec(0, "PCMU/8000", null);
-
-    /**
-     * G.711 a-law audio codec.
-     */
-    public static final AudioCodec PCMA = new AudioCodec(8, "PCMA/8000", null);
-
-    /**
-     * GSM Full-Rate audio codec, also known as GSM-FR, GSM 06.10, GSM, or
-     * simply FR.
-     */
-    public static final AudioCodec GSM = new AudioCodec(3, "GSM/8000", null);
-
-    /**
-     * GSM Enhanced Full-Rate audio codec, also known as GSM-EFR, GSM 06.60, or
-     * simply EFR.
-     */
-    public static final AudioCodec GSM_EFR = new AudioCodec(96, "GSM-EFR/8000", null);
-
-    /**
-     * Adaptive Multi-Rate narrowband audio codec, also known as AMR or AMR-NB.
-     * Currently CRC, robust sorting, and interleaving are not supported. See
-     * more details about these features in RFC 4867.
-     */
-    public static final AudioCodec AMR = new AudioCodec(97, "AMR/8000", null);
-
-    private static final AudioCodec[] sCodecs = {GSM_EFR, AMR, GSM, PCMU, PCMA};
-
-    private AudioCodec(int type, String rtpmap, String fmtp) {
-        this.type = type;
-        this.rtpmap = rtpmap;
-        this.fmtp = fmtp;
-    }
-
-    /**
-     * Returns system supported audio codecs.
-     */
-    public static AudioCodec[] getCodecs() {
-        return Arrays.copyOf(sCodecs, sCodecs.length);
-    }
-
-    /**
-     * Creates an AudioCodec according to the given configuration.
-     *
-     * @param type The payload type of the encoding defined in RTP/AVP.
-     * @param rtpmap The encoding parameters specified in the corresponding SDP
-     *     attribute, or null if it is not available.
-     * @param fmtp The format parameters specified in the corresponding SDP
-     *     attribute, or null if it is not available.
-     * @return The configured AudioCodec or {@code null} if it is not supported.
-     */
-    public static AudioCodec getCodec(int type, String rtpmap, String fmtp) {
-        if (type < 0 || type > 127) {
-            return null;
-        }
-
-        AudioCodec hint = null;
-        if (rtpmap != null) {
-            String clue = rtpmap.trim().toUpperCase();
-            for (AudioCodec codec : sCodecs) {
-                if (clue.startsWith(codec.rtpmap)) {
-                    String channels = clue.substring(codec.rtpmap.length());
-                    if (channels.length() == 0 || channels.equals("/1")) {
-                        hint = codec;
-                    }
-                    break;
-                }
-            }
-        } else if (type < 96) {
-            for (AudioCodec codec : sCodecs) {
-                if (type == codec.type) {
-                    hint = codec;
-                    rtpmap = codec.rtpmap;
-                    break;
-                }
-            }
-        }
-
-        if (hint == null) {
-            return null;
-        }
-        if (hint == AMR && fmtp != null) {
-            String clue = fmtp.toLowerCase();
-            if (clue.contains("crc=1") || clue.contains("robust-sorting=1") ||
-                    clue.contains("interleaving=")) {
-                return null;
-            }
-        }
-        return new AudioCodec(type, rtpmap, fmtp);
-    }
-}
diff --git a/voip/java/android/net/rtp/AudioGroup.java b/voip/java/android/net/rtp/AudioGroup.java
deleted file mode 100644
index 8faeb88..0000000
--- a/voip/java/android/net/rtp/AudioGroup.java
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-package android.net.rtp;
-
-import android.media.AudioManager;
-
-import java.util.HashMap;
-import java.util.Locale;
-import java.util.Map;
-
-/**
- * An AudioGroup is an audio hub for the speaker, the microphone, and
- * {@link AudioStream}s. Each of these components can be logically turned on
- * or off by calling {@link #setMode(int)} or {@link RtpStream#setMode(int)}.
- * The AudioGroup will go through these components and process them one by one
- * within its execution loop. The loop consists of four steps. First, for each
- * AudioStream not in {@link RtpStream#MODE_SEND_ONLY}, decodes its incoming
- * packets and stores in its buffer. Then, if the microphone is enabled,
- * processes the recorded audio and stores in its buffer. Third, if the speaker
- * is enabled, mixes all AudioStream buffers and plays back. Finally, for each
- * AudioStream not in {@link RtpStream#MODE_RECEIVE_ONLY}, mixes all other
- * buffers and sends back the encoded packets. An AudioGroup does nothing if
- * there is no AudioStream in it.
- *
- * <p>Few things must be noticed before using these classes. The performance is
- * highly related to the system load and the network bandwidth. Usually a
- * simpler {@link AudioCodec} costs fewer CPU cycles but requires more network
- * bandwidth, and vise versa. Using two AudioStreams at the same time doubles
- * not only the load but also the bandwidth. The condition varies from one
- * device to another, and developers should choose the right combination in
- * order to get the best result.</p>
- *
- * <p>It is sometimes useful to keep multiple AudioGroups at the same time. For
- * example, a Voice over IP (VoIP) application might want to put a conference
- * call on hold in order to make a new call but still allow people in the
- * conference call talking to each other. This can be done easily using two
- * AudioGroups, but there are some limitations. Since the speaker and the
- * microphone are globally shared resources, only one AudioGroup at a time is
- * allowed to run in a mode other than {@link #MODE_ON_HOLD}. The others will
- * be unable to acquire these resources and fail silently.</p>
- *
- * <p class="note">Using this class requires
- * {@link android.Manifest.permission#RECORD_AUDIO} permission. Developers
- * should set the audio mode to {@link AudioManager#MODE_IN_COMMUNICATION}
- * using {@link AudioManager#setMode(int)} and change it back when none of
- * the AudioGroups is in use.</p>
- *
- * @see AudioStream
- */
-public class AudioGroup {
-    /**
-     * This mode is similar to {@link #MODE_NORMAL} except the speaker and
-     * the microphone are both disabled.
-     */
-    public static final int MODE_ON_HOLD = 0;
-
-    /**
-     * This mode is similar to {@link #MODE_NORMAL} except the microphone is
-     * disabled.
-     */
-    public static final int MODE_MUTED = 1;
-
-    /**
-     * This mode indicates that the speaker, the microphone, and all
-     * {@link AudioStream}s in the group are enabled. First, the packets
-     * received from the streams are decoded and mixed with the audio recorded
-     * from the microphone. Then, the results are played back to the speaker,
-     * encoded and sent back to each stream.
-     */
-    public static final int MODE_NORMAL = 2;
-
-    /**
-     * This mode is similar to {@link #MODE_NORMAL} except the echo suppression
-     * is enabled. It should be only used when the speaker phone is on.
-     */
-    public static final int MODE_ECHO_SUPPRESSION = 3;
-
-    private static final int MODE_LAST = 3;
-
-    private final Map<AudioStream, Integer> mStreams;
-    private int mMode = MODE_ON_HOLD;
-
-    private int mNative;
-    static {
-        System.loadLibrary("rtp_jni");
-    }
-
-    /**
-     * Creates an empty AudioGroup.
-     */
-    public AudioGroup() {
-        mStreams = new HashMap<AudioStream, Integer>();
-    }
-
-    /**
-     * Returns the {@link AudioStream}s in this group.
-     */
-    public AudioStream[] getStreams() {
-        synchronized (this) {
-            return mStreams.keySet().toArray(new AudioStream[mStreams.size()]);
-        }
-    }
-
-    /**
-     * Returns the current mode.
-     */
-    public int getMode() {
-        return mMode;
-    }
-
-    /**
-     * Changes the current mode. It must be one of {@link #MODE_ON_HOLD},
-     * {@link #MODE_MUTED}, {@link #MODE_NORMAL}, and
-     * {@link #MODE_ECHO_SUPPRESSION}.
-     *
-     * @param mode The mode to change to.
-     * @throws IllegalArgumentException if the mode is invalid.
-     */
-    public void setMode(int mode) {
-        if (mode < 0 || mode > MODE_LAST) {
-            throw new IllegalArgumentException("Invalid mode");
-        }
-        synchronized (this) {
-            nativeSetMode(mode);
-            mMode = mode;
-        }
-    }
-
-    private native void nativeSetMode(int mode);
-
-    // Package-private method used by AudioStream.join().
-    synchronized void add(AudioStream stream) {
-        if (!mStreams.containsKey(stream)) {
-            try {
-                AudioCodec codec = stream.getCodec();
-                String codecSpec = String.format(Locale.US, "%d %s %s", codec.type,
-                        codec.rtpmap, codec.fmtp);
-                int id = nativeAdd(stream.getMode(), stream.getSocket(),
-                        stream.getRemoteAddress().getHostAddress(),
-                        stream.getRemotePort(), codecSpec, stream.getDtmfType());
-                mStreams.put(stream, id);
-            } catch (NullPointerException e) {
-                throw new IllegalStateException(e);
-            }
-        }
-    }
-
-    private native int nativeAdd(int mode, int socket, String remoteAddress,
-            int remotePort, String codecSpec, int dtmfType);
-
-    // Package-private method used by AudioStream.join().
-    synchronized void remove(AudioStream stream) {
-        Integer id = mStreams.remove(stream);
-        if (id != null) {
-            nativeRemove(id);
-        }
-    }
-
-    private native void nativeRemove(int id);
-
-    /**
-     * Sends a DTMF digit to every {@link AudioStream} in this group. Currently
-     * only event {@code 0} to {@code 15} are supported.
-     *
-     * @throws IllegalArgumentException if the event is invalid.
-     */
-    public void sendDtmf(int event) {
-        if (event < 0 || event > 15) {
-            throw new IllegalArgumentException("Invalid event");
-        }
-        synchronized (this) {
-            nativeSendDtmf(event);
-        }
-    }
-
-    private native void nativeSendDtmf(int event);
-
-    /**
-     * Removes every {@link AudioStream} in this group.
-     */
-    public void clear() {
-        for (AudioStream stream : getStreams()) {
-            stream.join(null);
-        }
-    }
-
-    @Override
-    protected void finalize() throws Throwable {
-        nativeRemove(0);
-        super.finalize();
-    }
-}
diff --git a/voip/java/android/net/rtp/AudioStream.java b/voip/java/android/net/rtp/AudioStream.java
deleted file mode 100644
index 5cd1abc..0000000
--- a/voip/java/android/net/rtp/AudioStream.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-package android.net.rtp;
-
-import java.net.InetAddress;
-import java.net.SocketException;
-
-/**
- * An AudioStream is a {@link RtpStream} which carrys audio payloads over
- * Real-time Transport Protocol (RTP). Two different classes are developed in
- * order to support various usages such as audio conferencing. An AudioStream
- * represents a remote endpoint which consists of a network mapping and a
- * configured {@link AudioCodec}. On the other side, An {@link AudioGroup}
- * represents a local endpoint which mixes all the AudioStreams and optionally
- * interacts with the speaker and the microphone at the same time. The simplest
- * usage includes one for each endpoints. For other combinations, developers
- * should be aware of the limitations described in {@link AudioGroup}.
- *
- * <p>An AudioStream becomes busy when it joins an AudioGroup. In this case most
- * of the setter methods are disabled. This is designed to ease the task of
- * managing native resources. One can always make an AudioStream leave its
- * AudioGroup by calling {@link #join(AudioGroup)} with {@code null} and put it
- * back after the modification is done.</p>
- *
- * <p class="note">Using this class requires
- * {@link android.Manifest.permission#INTERNET} permission.</p>
- *
- * @see RtpStream
- * @see AudioGroup
- */
-public class AudioStream extends RtpStream {
-    private AudioCodec mCodec;
-    private int mDtmfType = -1;
-    private AudioGroup mGroup;
-
-    /**
-     * Creates an AudioStream on the given local address. Note that the local
-     * port is assigned automatically to conform with RFC 3550.
-     *
-     * @param address The network address of the local host to bind to.
-     * @throws SocketException if the address cannot be bound or a problem
-     *     occurs during binding.
-     */
-    public AudioStream(InetAddress address) throws SocketException {
-        super(address);
-    }
-
-    /**
-     * Returns {@code true} if the stream has already joined an
-     * {@link AudioGroup}.
-     */
-    @Override
-    public final boolean isBusy() {
-        return mGroup != null;
-    }
-
-    /**
-     * Returns the joined {@link AudioGroup}.
-     */
-    public AudioGroup getGroup() {
-        return mGroup;
-    }
-
-    /**
-     * Joins an {@link AudioGroup}. Each stream can join only one group at a
-     * time. The group can be changed by passing a different one or removed
-     * by calling this method with {@code null}.
-     *
-     * @param group The AudioGroup to join or {@code null} to leave.
-     * @throws IllegalStateException if the stream is not properly configured.
-     * @see AudioGroup
-     */
-    public void join(AudioGroup group) {
-        synchronized (this) {
-            if (mGroup == group) {
-                return;
-            }
-            if (mGroup != null) {
-                mGroup.remove(this);
-                mGroup = null;
-            }
-            if (group != null) {
-                group.add(this);
-                mGroup = group;
-            }
-        }
-    }
-
-    /**
-     * Returns the {@link AudioCodec}, or {@code null} if it is not set.
-     *
-     * @see #setCodec(AudioCodec)
-     */
-    public AudioCodec getCodec() {
-        return mCodec;
-    }
-
-    /**
-     * Sets the {@link AudioCodec}.
-     *
-     * @param codec The AudioCodec to be used.
-     * @throws IllegalArgumentException if its type is used by DTMF.
-     * @throws IllegalStateException if the stream is busy.
-     */
-    public void setCodec(AudioCodec codec) {
-        if (isBusy()) {
-            throw new IllegalStateException("Busy");
-        }
-        if (codec.type == mDtmfType) {
-            throw new IllegalArgumentException("The type is used by DTMF");
-        }
-        mCodec = codec;
-    }
-
-    /**
-     * Returns the RTP payload type for dual-tone multi-frequency (DTMF) digits,
-     * or {@code -1} if it is not enabled.
-     *
-     * @see #setDtmfType(int)
-     */
-    public int getDtmfType() {
-        return mDtmfType;
-    }
-
-    /**
-     * Sets the RTP payload type for dual-tone multi-frequency (DTMF) digits.
-     * The primary usage is to send digits to the remote gateway to perform
-     * certain tasks, such as second-stage dialing. According to RFC 2833, the
-     * RTP payload type for DTMF is assigned dynamically, so it must be in the
-     * range of 96 and 127. One can use {@code -1} to disable DTMF and free up
-     * the previous assigned type. This method cannot be called when the stream
-     * already joined an {@link AudioGroup}.
-     *
-     * @param type The RTP payload type to be used or {@code -1} to disable it.
-     * @throws IllegalArgumentException if the type is invalid or used by codec.
-     * @throws IllegalStateException if the stream is busy.
-     * @see AudioGroup#sendDtmf(int)
-     */
-    public void setDtmfType(int type) {
-        if (isBusy()) {
-            throw new IllegalStateException("Busy");
-        }
-        if (type != -1) {
-            if (type < 96 || type > 127) {
-                throw new IllegalArgumentException("Invalid type");
-            }
-            if (mCodec != null && type == mCodec.type) {
-                throw new IllegalArgumentException("The type is used by codec");
-            }
-        }
-        mDtmfType = type;
-    }
-}
diff --git a/voip/java/android/net/rtp/RtpStream.java b/voip/java/android/net/rtp/RtpStream.java
deleted file mode 100644
index b9d75cd..0000000
--- a/voip/java/android/net/rtp/RtpStream.java
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-package android.net.rtp;
-
-import java.net.InetAddress;
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.net.SocketException;
-
-/**
- * RtpStream represents the base class of streams which send and receive network
- * packets with media payloads over Real-time Transport Protocol (RTP).
- *
- * <p class="note">Using this class requires
- * {@link android.Manifest.permission#INTERNET} permission.</p>
- */
-public class RtpStream {
-    /**
-     * This mode indicates that the stream sends and receives packets at the
-     * same time. This is the initial mode for new streams.
-     */
-    public static final int MODE_NORMAL = 0;
-
-    /**
-     * This mode indicates that the stream only sends packets.
-     */
-    public static final int MODE_SEND_ONLY = 1;
-
-    /**
-     * This mode indicates that the stream only receives packets.
-     */
-    public static final int MODE_RECEIVE_ONLY = 2;
-
-    private static final int MODE_LAST = 2;
-
-    private final InetAddress mLocalAddress;
-    private final int mLocalPort;
-
-    private InetAddress mRemoteAddress;
-    private int mRemotePort = -1;
-    private int mMode = MODE_NORMAL;
-
-    private int mSocket = -1;
-    static {
-        System.loadLibrary("rtp_jni");
-    }
-
-    /**
-     * Creates a RtpStream on the given local address. Note that the local
-     * port is assigned automatically to conform with RFC 3550.
-     *
-     * @param address The network address of the local host to bind to.
-     * @throws SocketException if the address cannot be bound or a problem
-     *     occurs during binding.
-     */
-    RtpStream(InetAddress address) throws SocketException {
-        mLocalPort = create(address.getHostAddress());
-        mLocalAddress = address;
-    }
-
-    private native int create(String address) throws SocketException;
-
-    /**
-     * Returns the network address of the local host.
-     */
-    public InetAddress getLocalAddress() {
-        return mLocalAddress;
-    }
-
-    /**
-     * Returns the network port of the local host.
-     */
-    public int getLocalPort() {
-        return mLocalPort;
-    }
-
-    /**
-     * Returns the network address of the remote host or {@code null} if the
-     * stream is not associated.
-     */
-    public InetAddress getRemoteAddress() {
-        return mRemoteAddress;
-    }
-
-    /**
-     * Returns the network port of the remote host or {@code -1} if the stream
-     * is not associated.
-     */
-    public int getRemotePort() {
-        return mRemotePort;
-    }
-
-    /**
-     * Returns {@code true} if the stream is busy. In this case most of the
-     * setter methods are disabled. This method is intended to be overridden
-     * by subclasses.
-     */
-    public boolean isBusy() {
-        return false;
-    }
-
-    /**
-     * Returns the current mode.
-     */
-    public int getMode() {
-        return mMode;
-    }
-
-    /**
-     * Changes the current mode. It must be one of {@link #MODE_NORMAL},
-     * {@link #MODE_SEND_ONLY}, and {@link #MODE_RECEIVE_ONLY}.
-     *
-     * @param mode The mode to change to.
-     * @throws IllegalArgumentException if the mode is invalid.
-     * @throws IllegalStateException if the stream is busy.
-     * @see #isBusy()
-     */
-    public void setMode(int mode) {
-        if (isBusy()) {
-            throw new IllegalStateException("Busy");
-        }
-        if (mode < 0 || mode > MODE_LAST) {
-            throw new IllegalArgumentException("Invalid mode");
-        }
-        mMode = mode;
-    }
-
-    /**
-     * Associates with a remote host. This defines the destination of the
-     * outgoing packets.
-     *
-     * @param address The network address of the remote host.
-     * @param port The network port of the remote host.
-     * @throws IllegalArgumentException if the address is not supported or the
-     *     port is invalid.
-     * @throws IllegalStateException if the stream is busy.
-     * @see #isBusy()
-     */
-    public void associate(InetAddress address, int port) {
-        if (isBusy()) {
-            throw new IllegalStateException("Busy");
-        }
-        if (!(address instanceof Inet4Address && mLocalAddress instanceof Inet4Address) &&
-                !(address instanceof Inet6Address && mLocalAddress instanceof Inet6Address)) {
-            throw new IllegalArgumentException("Unsupported address");
-        }
-        if (port < 0 || port > 65535) {
-            throw new IllegalArgumentException("Invalid port");
-        }
-        mRemoteAddress = address;
-        mRemotePort = port;
-    }
-
-    int getSocket() {
-        return mSocket;
-    }
-
-    /**
-     * Releases allocated resources. The stream becomes inoperable after calling
-     * this method.
-     *
-     * @throws IllegalStateException if the stream is busy.
-     * @see #isBusy()
-     */
-    public void release() {
-        synchronized (this) {
-            if (isBusy()) {
-                throw new IllegalStateException("Busy");
-            }
-            close();
-        }
-    }
-
-    private native void close();
-
-    @Override
-    protected void finalize() throws Throwable {
-        close();
-        super.finalize();
-    }
-}
diff --git a/voip/java/android/net/rtp/package.html b/voip/java/android/net/rtp/package.html
deleted file mode 100644
index 4506b09..0000000
--- a/voip/java/android/net/rtp/package.html
+++ /dev/null
@@ -1,28 +0,0 @@
-<html>
-<body>
-<p>Provides APIs for RTP (Real-time Transport Protocol), allowing applications to manage on-demand
-or interactive data streaming. In particular, apps that provide VOIP, push-to-talk, conferencing,
-and audio streaming can use these APIs to initiate sessions and transmit or receive data streams
-over any available network.</p>
-
-<p>To support audio conferencing and similar usages, you need to instantiate two classes as
-endpoints for the stream:</p>
-
-<ul>
-<li>{@link android.net.rtp.AudioStream} specifies a remote endpoint and consists of network mapping
-and a configured {@link android.net.rtp.AudioCodec}.</li>
-
-<li>{@link android.net.rtp.AudioGroup} represents the local endpoint for one or more {@link
-android.net.rtp.AudioStream}s. The {@link android.net.rtp.AudioGroup} mixes all the {@link
-android.net.rtp.AudioStream}s and optionally interacts with the device speaker and the microphone at
-the same time.</li>
-</ul>
-
-<p>The simplest usage involves a single remote endpoint and local endpoint. For more complex usages,
-refer to the limitations described for {@link android.net.rtp.AudioGroup}.</p>
-
-<p class="note"><strong>Note:</strong> To use the RTP APIs, you must request the {@link
-android.Manifest.permission#INTERNET} and {@link
-android.Manifest.permission#RECORD_AUDIO} permissions in your manifest file.</p>
-</body>
-</html>
\ No newline at end of file
diff --git a/voip/java/android/net/sip/ISipService.aidl b/voip/java/android/net/sip/ISipService.aidl
deleted file mode 100644
index 3250bf9..0000000
--- a/voip/java/android/net/sip/ISipService.aidl
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-package android.net.sip;
-
-import android.app.PendingIntent;
-import android.net.sip.ISipSession;
-import android.net.sip.ISipSessionListener;
-import android.net.sip.SipProfile;
-
-/**
- * {@hide}
- */
-interface ISipService {
-    void open(in SipProfile localProfile);
-    void open3(in SipProfile localProfile,
-            in PendingIntent incomingCallPendingIntent,
-            in ISipSessionListener listener);
-    void close(in String localProfileUri);
-    boolean isOpened(String localProfileUri);
-    boolean isRegistered(String localProfileUri);
-    void setRegistrationListener(String localProfileUri,
-            ISipSessionListener listener);
-
-    ISipSession createSession(in SipProfile localProfile,
-            in ISipSessionListener listener);
-    ISipSession getPendingSession(String callId);
-
-    SipProfile[] getListOfProfiles();
-}
diff --git a/voip/java/android/net/sip/ISipSession.aidl b/voip/java/android/net/sip/ISipSession.aidl
deleted file mode 100644
index 2d515db..0000000
--- a/voip/java/android/net/sip/ISipSession.aidl
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-package android.net.sip;
-
-import android.net.sip.ISipSessionListener;
-import android.net.sip.SipProfile;
-
-/**
- * A SIP session that is associated with a SIP dialog or a transaction that is
- * not within a dialog.
- * @hide
- */
-interface ISipSession {
-    /**
-     * Gets the IP address of the local host on which this SIP session runs.
-     *
-     * @return the IP address of the local host
-     */
-    String getLocalIp();
-
-    /**
-     * Gets the SIP profile that this session is associated with.
-     *
-     * @return the SIP profile that this session is associated with
-     */
-    SipProfile getLocalProfile();
-
-    /**
-     * Gets the SIP profile that this session is connected to. Only available
-     * when the session is associated with a SIP dialog.
-     *
-     * @return the SIP profile that this session is connected to
-     */
-    SipProfile getPeerProfile();
-
-    /**
-     * Gets the session state. The value returned must be one of the states in
-     * {@link SipSessionState}.
-     *
-     * @return the session state
-     */
-    int getState();
-
-    /**
-     * Checks if the session is in a call.
-     *
-     * @return true if the session is in a call
-     */
-    boolean isInCall();
-
-    /**
-     * Gets the call ID of the session.
-     *
-     * @return the call ID
-     */
-    String getCallId();
-
-
-    /**
-     * Sets the listener to listen to the session events. A {@link ISipSession}
-     * can only hold one listener at a time. Subsequent calls to this method
-     * override the previous listener.
-     *
-     * @param listener to listen to the session events of this object
-     */
-    void setListener(in ISipSessionListener listener);
-
-
-    /**
-     * Performs registration to the server specified by the associated local
-     * profile. The session listener is called back upon success or failure of
-     * registration. The method is only valid to call when the session state is
-     * in {@link SipSessionState#READY_TO_CALL}.
-     *
-     * @param duration duration in second before the registration expires
-     * @see ISipSessionListener
-     */
-    void register(int duration);
-
-    /**
-     * Performs unregistration to the server specified by the associated local
-     * profile. Unregistration is technically the same as registration with zero
-     * expiration duration. The session listener is called back upon success or
-     * failure of unregistration. The method is only valid to call when the
-     * session state is in {@link SipSessionState#READY_TO_CALL}.
-     *
-     * @see ISipSessionListener
-     */
-    void unregister();
-
-    /**
-     * Initiates a call to the specified profile. The session listener is called
-     * back upon defined session events. The method is only valid to call when
-     * the session state is in {@link SipSessionState#READY_TO_CALL}.
-     *
-     * @param callee the SIP profile to make the call to
-     * @param sessionDescription the session description of this call
-     * @param timeout the session will be timed out if the call is not
-     *        established within {@code timeout} seconds
-     * @see ISipSessionListener
-     */
-    void makeCall(in SipProfile callee, String sessionDescription, int timeout);
-
-    /**
-     * Answers an incoming call with the specified session description. The
-     * method is only valid to call when the session state is in
-     * {@link SipSessionState#INCOMING_CALL}.
-     *
-     * @param sessionDescription the session description to answer this call
-     * @param timeout the session will be timed out if the call is not
-     *        established within {@code timeout} seconds
-     */
-    void answerCall(String sessionDescription, int timeout);
-
-    /**
-     * Ends an established call, terminates an outgoing call or rejects an
-     * incoming call. The method is only valid to call when the session state is
-     * in {@link SipSessionState#IN_CALL},
-     * {@link SipSessionState#INCOMING_CALL},
-     * {@link SipSessionState#OUTGOING_CALL} or
-     * {@link SipSessionState#OUTGOING_CALL_RING_BACK}.
-     */
-    void endCall();
-
-    /**
-     * Changes the session description during a call. The method is only valid
-     * to call when the session state is in {@link SipSessionState#IN_CALL}.
-     *
-     * @param sessionDescription the new session description
-     * @param timeout the session will be timed out if the call is not
-     *        established within {@code timeout} seconds
-     */
-    void changeCall(String sessionDescription, int timeout);
-}
diff --git a/voip/java/android/net/sip/ISipSessionListener.aidl b/voip/java/android/net/sip/ISipSessionListener.aidl
deleted file mode 100644
index 690700c..0000000
--- a/voip/java/android/net/sip/ISipSessionListener.aidl
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-package android.net.sip;
-
-import android.net.sip.ISipSession;
-import android.net.sip.SipProfile;
-
-/**
- * Listener class to listen to SIP session events.
- * @hide
- */
-interface ISipSessionListener {
-    /**
-     * Called when an INVITE request is sent to initiate a new call.
-     *
-     * @param session the session object that carries out the transaction
-     */
-    void onCalling(in ISipSession session);
-
-    /**
-     * Called when an INVITE request is received.
-     *
-     * @param session the session object that carries out the transaction
-     * @param caller the SIP profile of the caller
-     * @param sessionDescription the caller's session description
-     */
-    void onRinging(in ISipSession session, in SipProfile caller,
-            String sessionDescription);
-
-    /**
-     * Called when a RINGING response is received for the INVITE request sent
-     *
-     * @param session the session object that carries out the transaction
-     */
-    void onRingingBack(in ISipSession session);
-
-    /**
-     * Called when the session is established.
-     *
-     * @param session the session object that is associated with the dialog
-     * @param sessionDescription the peer's session description
-     */
-    void onCallEstablished(in ISipSession session,
-            String sessionDescription);
-
-    /**
-     * Called when the session is terminated.
-     *
-     * @param session the session object that is associated with the dialog
-     */
-    void onCallEnded(in ISipSession session);
-
-    /**
-     * Called when the peer is busy during session initialization.
-     *
-     * @param session the session object that carries out the transaction
-     */
-    void onCallBusy(in ISipSession session);
-
-    /**
-     * Called when the call is being transferred to a new one.
-     *
-     * @param newSession the new session that the call will be transferred to
-     * @param sessionDescription the new peer's session description
-     */
-    void onCallTransferring(in ISipSession newSession, String sessionDescription);
-
-    /**
-     * Called when an error occurs during session initialization and
-     * termination.
-     *
-     * @param session the session object that carries out the transaction
-     * @param errorCode error code defined in {@link SipErrorCode}
-     * @param errorMessage error message
-     */
-    void onError(in ISipSession session, int errorCode, String errorMessage);
-
-    /**
-     * Called when an error occurs during session modification negotiation.
-     *
-     * @param session the session object that carries out the transaction
-     * @param errorCode error code defined in {@link SipErrorCode}
-     * @param errorMessage error message
-     */
-    void onCallChangeFailed(in ISipSession session, int errorCode,
-            String errorMessage);
-
-    /**
-     * Called when a registration request is sent.
-     *
-     * @param session the session object that carries out the transaction
-     */
-    void onRegistering(in ISipSession session);
-
-    /**
-     * Called when registration is successfully done.
-     *
-     * @param session the session object that carries out the transaction
-     * @param duration duration in second before the registration expires
-     */
-    void onRegistrationDone(in ISipSession session, int duration);
-
-    /**
-     * Called when the registration fails.
-     *
-     * @param session the session object that carries out the transaction
-     * @param errorCode error code defined in {@link SipErrorCode}
-     * @param errorMessage error message
-     */
-    void onRegistrationFailed(in ISipSession session, int errorCode,
-            String errorMessage);
-
-    /**
-     * Called when the registration gets timed out.
-     *
-     * @param session the session object that carries out the transaction
-     */
-    void onRegistrationTimeout(in ISipSession session);
-}
diff --git a/voip/java/android/net/sip/SimpleSessionDescription.java b/voip/java/android/net/sip/SimpleSessionDescription.java
deleted file mode 100644
index 9fcd21d..0000000
--- a/voip/java/android/net/sip/SimpleSessionDescription.java
+++ /dev/null
@@ -1,613 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-package android.net.sip;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Locale;
-
-/**
- * An object used to manipulate messages of Session Description Protocol (SDP).
- * It is mainly designed for the uses of Session Initiation Protocol (SIP).
- * Therefore, it only handles connection addresses ("c="), bandwidth limits,
- * ("b="), encryption keys ("k="), and attribute fields ("a="). Currently this
- * implementation does not support multicast sessions.
- *
- * <p>Here is an example code to create a session description.</p>
- * <pre>
- * SimpleSessionDescription description = new SimpleSessionDescription(
- *     System.currentTimeMillis(), "1.2.3.4");
- * Media media = description.newMedia("audio", 56789, 1, "RTP/AVP");
- * media.setRtpPayload(0, "PCMU/8000", null);
- * media.setRtpPayload(8, "PCMA/8000", null);
- * media.setRtpPayload(127, "telephone-event/8000", "0-15");
- * media.setAttribute("sendrecv", "");
- * </pre>
- * <p>Invoking <code>description.encode()</code> will produce a result like the
- * one below.</p>
- * <pre>
- * v=0
- * o=- 1284970442706 1284970442709 IN IP4 1.2.3.4
- * s=-
- * c=IN IP4 1.2.3.4
- * t=0 0
- * m=audio 56789 RTP/AVP 0 8 127
- * a=rtpmap:0 PCMU/8000
- * a=rtpmap:8 PCMA/8000
- * a=rtpmap:127 telephone-event/8000
- * a=fmtp:127 0-15
- * a=sendrecv
- * </pre>
- * @hide
- */
-public class SimpleSessionDescription {
-    private final Fields mFields = new Fields("voscbtka");
-    private final ArrayList<Media> mMedia = new ArrayList<Media>();
-
-    /**
-     * Creates a minimal session description from the given session ID and
-     * unicast address. The address is used in the origin field ("o=") and the
-     * connection field ("c="). See {@link SimpleSessionDescription} for an
-     * example of its usage.
-     */
-    public SimpleSessionDescription(long sessionId, String address) {
-        address = (address.indexOf(':') < 0 ? "IN IP4 " : "IN IP6 ") + address;
-        mFields.parse("v=0");
-        mFields.parse(String.format(Locale.US, "o=- %d %d %s", sessionId,
-                System.currentTimeMillis(), address));
-        mFields.parse("s=-");
-        mFields.parse("t=0 0");
-        mFields.parse("c=" + address);
-    }
-
-    /**
-     * Creates a session description from the given message.
-     *
-     * @throws IllegalArgumentException if message is invalid.
-     */
-    public SimpleSessionDescription(String message) {
-        String[] lines = message.trim().replaceAll(" +", " ").split("[\r\n]+");
-        Fields fields = mFields;
-
-        for (String line : lines) {
-            try {
-                if (line.charAt(1) != '=') {
-                    throw new IllegalArgumentException();
-                }
-                if (line.charAt(0) == 'm') {
-                    String[] parts = line.substring(2).split(" ", 4);
-                    String[] ports = parts[1].split("/", 2);
-                    Media media = newMedia(parts[0], Integer.parseInt(ports[0]),
-                            (ports.length < 2) ? 1 : Integer.parseInt(ports[1]),
-                            parts[2]);
-                    for (String format : parts[3].split(" ")) {
-                        media.setFormat(format, null);
-                    }
-                    fields = media;
-                } else {
-                    fields.parse(line);
-                }
-            } catch (Exception e) {
-                throw new IllegalArgumentException("Invalid SDP: " + line);
-            }
-        }
-    }
-
-    /**
-     * Creates a new media description in this session description.
-     *
-     * @param type The media type, e.g. {@code "audio"}.
-     * @param port The first transport port used by this media.
-     * @param portCount The number of contiguous ports used by this media.
-     * @param protocol The transport protocol, e.g. {@code "RTP/AVP"}.
-     */
-    public Media newMedia(String type, int port, int portCount,
-            String protocol) {
-        Media media = new Media(type, port, portCount, protocol);
-        mMedia.add(media);
-        return media;
-    }
-
-    /**
-     * Returns all the media descriptions in this session description.
-     */
-    public Media[] getMedia() {
-        return mMedia.toArray(new Media[mMedia.size()]);
-    }
-
-    /**
-     * Encodes the session description and all its media descriptions in a
-     * string. Note that the result might be incomplete if a required field
-     * has never been added before.
-     */
-    public String encode() {
-        StringBuilder buffer = new StringBuilder();
-        mFields.write(buffer);
-        for (Media media : mMedia) {
-            media.write(buffer);
-        }
-        return buffer.toString();
-    }
-
-    /**
-     * Returns the connection address or {@code null} if it is not present.
-     */
-    public String getAddress() {
-        return mFields.getAddress();
-    }
-
-    /**
-     * Sets the connection address. The field will be removed if the address
-     * is {@code null}.
-     */
-    public void setAddress(String address) {
-        mFields.setAddress(address);
-    }
-
-    /**
-     * Returns the encryption method or {@code null} if it is not present.
-     */
-    public String getEncryptionMethod() {
-        return mFields.getEncryptionMethod();
-    }
-
-    /**
-     * Returns the encryption key or {@code null} if it is not present.
-     */
-    public String getEncryptionKey() {
-        return mFields.getEncryptionKey();
-    }
-
-    /**
-     * Sets the encryption method and the encryption key. The field will be
-     * removed if the method is {@code null}.
-     */
-    public void setEncryption(String method, String key) {
-        mFields.setEncryption(method, key);
-    }
-
-    /**
-     * Returns the types of the bandwidth limits.
-     */
-    public String[] getBandwidthTypes() {
-        return mFields.getBandwidthTypes();
-    }
-
-    /**
-     * Returns the bandwidth limit of the given type or {@code -1} if it is not
-     * present.
-     */
-    public int getBandwidth(String type) {
-        return mFields.getBandwidth(type);
-    }
-
-    /**
-     * Sets the bandwith limit for the given type. The field will be removed if
-     * the value is negative.
-     */
-    public void setBandwidth(String type, int value) {
-        mFields.setBandwidth(type, value);
-    }
-
-    /**
-     * Returns the names of all the attributes.
-     */
-    public String[] getAttributeNames() {
-        return mFields.getAttributeNames();
-    }
-
-    /**
-     * Returns the attribute of the given name or {@code null} if it is not
-     * present.
-     */
-    public String getAttribute(String name) {
-        return mFields.getAttribute(name);
-    }
-
-    /**
-     * Sets the attribute for the given name. The field will be removed if
-     * the value is {@code null}. To set a binary attribute, use an empty
-     * string as the value.
-     */
-    public void setAttribute(String name, String value) {
-        mFields.setAttribute(name, value);
-    }
-
-    /**
-     * This class represents a media description of a session description. It
-     * can only be created by {@link SimpleSessionDescription#newMedia}. Since
-     * the syntax is more restricted for RTP based protocols, two sets of access
-     * methods are implemented. See {@link SimpleSessionDescription} for an
-     * example of its usage.
-     */
-    public static class Media extends Fields {
-        private final String mType;
-        private final int mPort;
-        private final int mPortCount;
-        private final String mProtocol;
-        private ArrayList<String> mFormats = new ArrayList<String>();
-
-        private Media(String type, int port, int portCount, String protocol) {
-            super("icbka");
-            mType = type;
-            mPort = port;
-            mPortCount = portCount;
-            mProtocol = protocol;
-        }
-
-        /**
-         * Returns the media type.
-         */
-        public String getType() {
-            return mType;
-        }
-
-        /**
-         * Returns the first transport port used by this media.
-         */
-        public int getPort() {
-            return mPort;
-        }
-
-        /**
-         * Returns the number of contiguous ports used by this media.
-         */
-        public int getPortCount() {
-            return mPortCount;
-        }
-
-        /**
-         * Returns the transport protocol.
-         */
-        public String getProtocol() {
-            return mProtocol;
-        }
-
-        /**
-         * Returns the media formats.
-         */
-        public String[] getFormats() {
-            return mFormats.toArray(new String[mFormats.size()]);
-        }
-
-        /**
-         * Returns the {@code fmtp} attribute of the given format or
-         * {@code null} if it is not present.
-         */
-        public String getFmtp(String format) {
-            return super.get("a=fmtp:" + format, ' ');
-        }
-
-        /**
-         * Sets a format and its {@code fmtp} attribute. If the attribute is
-         * {@code null}, the corresponding field will be removed.
-         */
-        public void setFormat(String format, String fmtp) {
-            mFormats.remove(format);
-            mFormats.add(format);
-            super.set("a=rtpmap:" + format, ' ', null);
-            super.set("a=fmtp:" + format, ' ', fmtp);
-        }
-
-        /**
-         * Removes a format and its {@code fmtp} attribute.
-         */
-        public void removeFormat(String format) {
-            mFormats.remove(format);
-            super.set("a=rtpmap:" + format, ' ', null);
-            super.set("a=fmtp:" + format, ' ', null);
-        }
-
-        /**
-         * Returns the RTP payload types.
-         */
-        public int[] getRtpPayloadTypes() {
-            int[] types = new int[mFormats.size()];
-            int length = 0;
-            for (String format : mFormats) {
-                try {
-                    types[length] = Integer.parseInt(format);
-                    ++length;
-                } catch (NumberFormatException e) { }
-            }
-            return Arrays.copyOf(types, length);
-        }
-
-        /**
-         * Returns the {@code rtpmap} attribute of the given RTP payload type
-         * or {@code null} if it is not present.
-         */
-        public String getRtpmap(int type) {
-            return super.get("a=rtpmap:" + type, ' ');
-        }
-
-        /**
-         * Returns the {@code fmtp} attribute of the given RTP payload type or
-         * {@code null} if it is not present.
-         */
-        public String getFmtp(int type) {
-            return super.get("a=fmtp:" + type, ' ');
-        }
-
-        /**
-         * Sets a RTP payload type and its {@code rtpmap} and {@code fmtp}
-         * attributes. If any of the attributes is {@code null}, the
-         * corresponding field will be removed. See
-         * {@link SimpleSessionDescription} for an example of its usage.
-         */
-        public void setRtpPayload(int type, String rtpmap, String fmtp) {
-            String format = String.valueOf(type);
-            mFormats.remove(format);
-            mFormats.add(format);
-            super.set("a=rtpmap:" + format, ' ', rtpmap);
-            super.set("a=fmtp:" + format, ' ', fmtp);
-        }
-
-        /**
-         * Removes a RTP payload and its {@code rtpmap} and {@code fmtp}
-         * attributes.
-         */
-        public void removeRtpPayload(int type) {
-            removeFormat(String.valueOf(type));
-        }
-
-        private void write(StringBuilder buffer) {
-            buffer.append("m=").append(mType).append(' ').append(mPort);
-            if (mPortCount != 1) {
-                buffer.append('/').append(mPortCount);
-            }
-            buffer.append(' ').append(mProtocol);
-            for (String format : mFormats) {
-                buffer.append(' ').append(format);
-            }
-            buffer.append("\r\n");
-            super.write(buffer);
-        }
-    }
-
-    /**
-     * This class acts as a set of fields, and the size of the set is expected
-     * to be small. Therefore, it uses a simple list instead of maps. Each field
-     * has three parts: a key, a delimiter, and a value. Delimiters are special
-     * because they are not included in binary attributes. As a result, the
-     * private methods, which are the building blocks of this class, all take
-     * the delimiter as an argument.
-     */
-    private static class Fields {
-        private final String mOrder;
-        private final ArrayList<String> mLines = new ArrayList<String>();
-
-        Fields(String order) {
-            mOrder = order;
-        }
-
-        /**
-         * Returns the connection address or {@code null} if it is not present.
-         */
-        public String getAddress() {
-            String address = get("c", '=');
-            if (address == null) {
-                return null;
-            }
-            String[] parts = address.split(" ");
-            if (parts.length != 3) {
-                return null;
-            }
-            int slash = parts[2].indexOf('/');
-            return (slash < 0) ? parts[2] : parts[2].substring(0, slash);
-        }
-
-        /**
-         * Sets the connection address. The field will be removed if the address
-         * is {@code null}.
-         */
-        public void setAddress(String address) {
-            if (address != null) {
-                address = (address.indexOf(':') < 0 ? "IN IP4 " : "IN IP6 ") +
-                        address;
-            }
-            set("c", '=', address);
-        }
-
-        /**
-         * Returns the encryption method or {@code null} if it is not present.
-         */
-        public String getEncryptionMethod() {
-            String encryption = get("k", '=');
-            if (encryption == null) {
-                return null;
-            }
-            int colon = encryption.indexOf(':');
-            return (colon == -1) ? encryption : encryption.substring(0, colon);
-        }
-
-        /**
-         * Returns the encryption key or {@code null} if it is not present.
-         */
-        public String getEncryptionKey() {
-            String encryption = get("k", '=');
-            if (encryption == null) {
-                return null;
-            }
-            int colon = encryption.indexOf(':');
-            return (colon == -1) ? null : encryption.substring(0, colon + 1);
-        }
-
-        /**
-         * Sets the encryption method and the encryption key. The field will be
-         * removed if the method is {@code null}.
-         */
-        public void setEncryption(String method, String key) {
-            set("k", '=', (method == null || key == null) ?
-                    method : method + ':' + key);
-        }
-
-        /**
-         * Returns the types of the bandwidth limits.
-         */
-        public String[] getBandwidthTypes() {
-            return cut("b=", ':');
-        }
-
-        /**
-         * Returns the bandwidth limit of the given type or {@code -1} if it is
-         * not present.
-         */
-        public int getBandwidth(String type) {
-            String value = get("b=" + type, ':');
-            if (value != null) {
-                try {
-                    return Integer.parseInt(value);
-                } catch (NumberFormatException e) { }
-                setBandwidth(type, -1);
-            }
-            return -1;
-        }
-
-        /**
-         * Sets the bandwith limit for the given type. The field will be removed
-         * if the value is negative.
-         */
-        public void setBandwidth(String type, int value) {
-            set("b=" + type, ':', (value < 0) ? null : String.valueOf(value));
-        }
-
-        /**
-         * Returns the names of all the attributes.
-         */
-        public String[] getAttributeNames() {
-            return cut("a=", ':');
-        }
-
-        /**
-         * Returns the attribute of the given name or {@code null} if it is not
-         * present.
-         */
-        public String getAttribute(String name) {
-            return get("a=" + name, ':');
-        }
-
-        /**
-         * Sets the attribute for the given name. The field will be removed if
-         * the value is {@code null}. To set a binary attribute, use an empty
-         * string as the value.
-         */
-        public void setAttribute(String name, String value) {
-            set("a=" + name, ':', value);
-        }
-
-        private void write(StringBuilder buffer) {
-            for (int i = 0; i < mOrder.length(); ++i) {
-                char type = mOrder.charAt(i);
-                for (String line : mLines) {
-                    if (line.charAt(0) == type) {
-                        buffer.append(line).append("\r\n");
-                    }
-                }
-            }
-        }
-
-        /**
-         * Invokes {@link #set} after splitting the line into three parts.
-         */
-        private void parse(String line) {
-            char type = line.charAt(0);
-            if (mOrder.indexOf(type) == -1) {
-                return;
-            }
-            char delimiter = '=';
-            if (line.startsWith("a=rtpmap:") || line.startsWith("a=fmtp:")) {
-                delimiter = ' ';
-            } else if (type == 'b' || type == 'a') {
-                delimiter = ':';
-            }
-            int i = line.indexOf(delimiter);
-            if (i == -1) {
-                set(line, delimiter, "");
-            } else {
-                set(line.substring(0, i), delimiter, line.substring(i + 1));
-            }
-        }
-
-        /**
-         * Finds the key with the given prefix and returns its suffix.
-         */
-        private String[] cut(String prefix, char delimiter) {
-            String[] names = new String[mLines.size()];
-            int length = 0;
-            for (String line : mLines) {
-                if (line.startsWith(prefix)) {
-                    int i = line.indexOf(delimiter);
-                    if (i == -1) {
-                        i = line.length();
-                    }
-                    names[length] = line.substring(prefix.length(), i);
-                    ++length;
-                }
-            }
-            return Arrays.copyOf(names, length);
-        }
-
-        /**
-         * Returns the index of the key.
-         */
-        private int find(String key, char delimiter) {
-            int length = key.length();
-            for (int i = mLines.size() - 1; i >= 0; --i) {
-                String line = mLines.get(i);
-                if (line.startsWith(key) && (line.length() == length ||
-                        line.charAt(length) == delimiter)) {
-                    return i;
-                }
-            }
-            return -1;
-        }
-
-        /**
-         * Sets the key with the value or removes the key if the value is
-         * {@code null}.
-         */
-        private void set(String key, char delimiter, String value) {
-            int index = find(key, delimiter);
-            if (value != null) {
-                if (value.length() != 0) {
-                    key = key + delimiter + value;
-                }
-                if (index == -1) {
-                    mLines.add(key);
-                } else {
-                    mLines.set(index, key);
-                }
-            } else if (index != -1) {
-                mLines.remove(index);
-            }
-        }
-
-        /**
-         * Returns the value of the key.
-         */
-        private String get(String key, char delimiter) {
-            int index = find(key, delimiter);
-            if (index == -1) {
-                return null;
-            }
-            String line = mLines.get(index);
-            int length = key.length();
-            return (line.length() == length) ? "" : line.substring(length + 1);
-        }
-    }
-}
diff --git a/voip/java/android/net/sip/SipAudioCall.java b/voip/java/android/net/sip/SipAudioCall.java
deleted file mode 100644
index ea943e9..0000000
--- a/voip/java/android/net/sip/SipAudioCall.java
+++ /dev/null
@@ -1,1143 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-package android.net.sip;
-
-import android.content.Context;
-import android.media.AudioManager;
-import android.net.rtp.AudioCodec;
-import android.net.rtp.AudioGroup;
-import android.net.rtp.AudioStream;
-import android.net.rtp.RtpStream;
-import android.net.sip.SimpleSessionDescription.Media;
-import android.net.wifi.WifiManager;
-import android.os.Message;
-import android.telephony.Rlog;
-import android.text.TextUtils;
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-
-/**
- * Handles an Internet audio call over SIP. You can instantiate this class with {@link SipManager},
- * using {@link SipManager#makeAudioCall makeAudioCall()} and  {@link SipManager#takeAudioCall
- * takeAudioCall()}.
- *
- * <p class="note"><strong>Note:</strong> Using this class require the
- *   {@link android.Manifest.permission#INTERNET} and
- *   {@link android.Manifest.permission#USE_SIP} permissions. In addition, {@link
- *   #startAudio} requires the
- *   {@link android.Manifest.permission#RECORD_AUDIO},
- *   {@link android.Manifest.permission#ACCESS_WIFI_STATE}, and
- *   {@link android.Manifest.permission#WAKE_LOCK} permissions; and {@link #setSpeakerMode
- *   setSpeakerMode()} requires the
- *   {@link android.Manifest.permission#MODIFY_AUDIO_SETTINGS} permission.</p>
- *
- * <div class="special reference">
- * <h3>Developer Guides</h3>
- * <p>For more information about using SIP, read the
- * <a href="{@docRoot}guide/topics/network/sip.html">Session Initiation Protocol</a>
- * developer guide.</p>
- * </div>
- */
-public class SipAudioCall {
-    private static final String LOG_TAG = SipAudioCall.class.getSimpleName();
-    private static final boolean DBG = true;
-    private static final boolean RELEASE_SOCKET = true;
-    private static final boolean DONT_RELEASE_SOCKET = false;
-    private static final int SESSION_TIMEOUT = 5; // in seconds
-    private static final int TRANSFER_TIMEOUT = 15; // in seconds
-
-    /** Listener for events relating to a SIP call, such as when a call is being
-     * recieved ("on ringing") or a call is outgoing ("on calling").
-     * <p>Many of these events are also received by {@link SipSession.Listener}.</p>
-     */
-    public static class Listener {
-        /**
-         * Called when the call object is ready to make another call.
-         * The default implementation calls {@link #onChanged}.
-         *
-         * @param call the call object that is ready to make another call
-         */
-        public void onReadyToCall(SipAudioCall call) {
-            onChanged(call);
-        }
-
-        /**
-         * Called when a request is sent out to initiate a new call.
-         * The default implementation calls {@link #onChanged}.
-         *
-         * @param call the call object that carries out the audio call
-         */
-        public void onCalling(SipAudioCall call) {
-            onChanged(call);
-        }
-
-        /**
-         * Called when a new call comes in.
-         * The default implementation calls {@link #onChanged}.
-         *
-         * @param call the call object that carries out the audio call
-         * @param caller the SIP profile of the caller
-         */
-        public void onRinging(SipAudioCall call, SipProfile caller) {
-            onChanged(call);
-        }
-
-        /**
-         * Called when a RINGING response is received for the INVITE request
-         * sent. The default implementation calls {@link #onChanged}.
-         *
-         * @param call the call object that carries out the audio call
-         */
-        public void onRingingBack(SipAudioCall call) {
-            onChanged(call);
-        }
-
-        /**
-         * Called when the session is established.
-         * The default implementation calls {@link #onChanged}.
-         *
-         * @param call the call object that carries out the audio call
-         */
-        public void onCallEstablished(SipAudioCall call) {
-            onChanged(call);
-        }
-
-        /**
-         * Called when the session is terminated.
-         * The default implementation calls {@link #onChanged}.
-         *
-         * @param call the call object that carries out the audio call
-         */
-        public void onCallEnded(SipAudioCall call) {
-            onChanged(call);
-        }
-
-        /**
-         * Called when the peer is busy during session initialization.
-         * The default implementation calls {@link #onChanged}.
-         *
-         * @param call the call object that carries out the audio call
-         */
-        public void onCallBusy(SipAudioCall call) {
-            onChanged(call);
-        }
-
-        /**
-         * Called when the call is on hold.
-         * The default implementation calls {@link #onChanged}.
-         *
-         * @param call the call object that carries out the audio call
-         */
-        public void onCallHeld(SipAudioCall call) {
-            onChanged(call);
-        }
-
-        /**
-         * Called when an error occurs. The default implementation is no op.
-         *
-         * @param call the call object that carries out the audio call
-         * @param errorCode error code of this error
-         * @param errorMessage error message
-         * @see SipErrorCode
-         */
-        public void onError(SipAudioCall call, int errorCode,
-                String errorMessage) {
-            // no-op
-        }
-
-        /**
-         * Called when an event occurs and the corresponding callback is not
-         * overridden. The default implementation is no op. Error events are
-         * not re-directed to this callback and are handled in {@link #onError}.
-         */
-        public void onChanged(SipAudioCall call) {
-            // no-op
-        }
-    }
-
-    private Context mContext;
-    private SipProfile mLocalProfile;
-    private SipAudioCall.Listener mListener;
-    private SipSession mSipSession;
-    private SipSession mTransferringSession;
-
-    private long mSessionId = System.currentTimeMillis();
-    private String mPeerSd;
-
-    private AudioStream mAudioStream;
-    private AudioGroup mAudioGroup;
-
-    private boolean mInCall = false;
-    private boolean mMuted = false;
-    private boolean mHold = false;
-
-    private WifiManager mWm;
-    private WifiManager.WifiLock mWifiHighPerfLock;
-
-    private int mErrorCode = SipErrorCode.NO_ERROR;
-    private String mErrorMessage;
-
-    /**
-     * Creates a call object with the local SIP profile.
-     * @param context the context for accessing system services such as
-     *        ringtone, audio, WIFI etc
-     */
-    public SipAudioCall(Context context, SipProfile localProfile) {
-        mContext = context;
-        mLocalProfile = localProfile;
-        mWm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
-    }
-
-    /**
-     * Sets the listener to listen to the audio call events. The method calls
-     * {@link #setListener setListener(listener, false)}.
-     *
-     * @param listener to listen to the audio call events of this object
-     * @see #setListener(Listener, boolean)
-     */
-    public void setListener(SipAudioCall.Listener listener) {
-        setListener(listener, false);
-    }
-
-    /**
-     * Sets the listener to listen to the audio call events. A
-     * {@link SipAudioCall} can only hold one listener at a time. Subsequent
-     * calls to this method override the previous listener.
-     *
-     * @param listener to listen to the audio call events of this object
-     * @param callbackImmediately set to true if the caller wants to be called
-     *      back immediately on the current state
-     */
-    public void setListener(SipAudioCall.Listener listener,
-            boolean callbackImmediately) {
-        mListener = listener;
-        try {
-            if ((listener == null) || !callbackImmediately) {
-                // do nothing
-            } else if (mErrorCode != SipErrorCode.NO_ERROR) {
-                listener.onError(this, mErrorCode, mErrorMessage);
-            } else if (mInCall) {
-                if (mHold) {
-                    listener.onCallHeld(this);
-                } else {
-                    listener.onCallEstablished(this);
-                }
-            } else {
-                int state = getState();
-                switch (state) {
-                    case SipSession.State.READY_TO_CALL:
-                        listener.onReadyToCall(this);
-                        break;
-                    case SipSession.State.INCOMING_CALL:
-                        listener.onRinging(this, getPeerProfile());
-                        break;
-                    case SipSession.State.OUTGOING_CALL:
-                        listener.onCalling(this);
-                        break;
-                    case SipSession.State.OUTGOING_CALL_RING_BACK:
-                        listener.onRingingBack(this);
-                        break;
-                }
-            }
-        } catch (Throwable t) {
-            loge("setListener()", t);
-        }
-    }
-
-    /**
-     * Checks if the call is established.
-     *
-     * @return true if the call is established
-     */
-    public boolean isInCall() {
-        synchronized (this) {
-            return mInCall;
-        }
-    }
-
-    /**
-     * Checks if the call is on hold.
-     *
-     * @return true if the call is on hold
-     */
-    public boolean isOnHold() {
-        synchronized (this) {
-            return mHold;
-        }
-    }
-
-    /**
-     * Closes this object. This object is not usable after being closed.
-     */
-    public void close() {
-        close(true);
-    }
-
-    private synchronized void close(boolean closeRtp) {
-        if (closeRtp) stopCall(RELEASE_SOCKET);
-
-        mInCall = false;
-        mHold = false;
-        mSessionId = System.currentTimeMillis();
-        mErrorCode = SipErrorCode.NO_ERROR;
-        mErrorMessage = null;
-
-        if (mSipSession != null) {
-            mSipSession.setListener(null);
-            mSipSession = null;
-        }
-    }
-
-    /**
-     * Gets the local SIP profile.
-     *
-     * @return the local SIP profile
-     */
-    public SipProfile getLocalProfile() {
-        synchronized (this) {
-            return mLocalProfile;
-        }
-    }
-
-    /**
-     * Gets the peer's SIP profile.
-     *
-     * @return the peer's SIP profile
-     */
-    public SipProfile getPeerProfile() {
-        synchronized (this) {
-            return (mSipSession == null) ? null : mSipSession.getPeerProfile();
-        }
-    }
-
-    /**
-     * Gets the state of the {@link SipSession} that carries this call.
-     * The value returned must be one of the states in {@link SipSession.State}.
-     *
-     * @return the session state
-     */
-    public int getState() {
-        synchronized (this) {
-            if (mSipSession == null) return SipSession.State.READY_TO_CALL;
-            return mSipSession.getState();
-        }
-    }
-
-
-    /**
-     * Gets the {@link SipSession} that carries this call.
-     *
-     * @return the session object that carries this call
-     * @hide
-     */
-    public SipSession getSipSession() {
-        synchronized (this) {
-            return mSipSession;
-        }
-    }
-
-    private synchronized void transferToNewSession() {
-        if (mTransferringSession == null) return;
-        SipSession origin = mSipSession;
-        mSipSession = mTransferringSession;
-        mTransferringSession = null;
-
-        // stop the replaced call.
-        if (mAudioStream != null) {
-            mAudioStream.join(null);
-        } else {
-            try {
-                mAudioStream = new AudioStream(InetAddress.getByName(
-                        getLocalIp()));
-            } catch (Throwable t) {
-                loge("transferToNewSession():", t);
-            }
-        }
-        if (origin != null) origin.endCall();
-        startAudio();
-    }
-
-    private SipSession.Listener createListener() {
-        return new SipSession.Listener() {
-            @Override
-            public void onCalling(SipSession session) {
-                if (DBG) log("onCalling: session=" + session);
-                Listener listener = mListener;
-                if (listener != null) {
-                    try {
-                        listener.onCalling(SipAudioCall.this);
-                    } catch (Throwable t) {
-                        loge("onCalling():", t);
-                    }
-                }
-            }
-
-            @Override
-            public void onRingingBack(SipSession session) {
-                if (DBG) log("onRingingBackk: " + session);
-                Listener listener = mListener;
-                if (listener != null) {
-                    try {
-                        listener.onRingingBack(SipAudioCall.this);
-                    } catch (Throwable t) {
-                        loge("onRingingBack():", t);
-                    }
-                }
-            }
-
-            @Override
-            public void onRinging(SipSession session,
-                    SipProfile peerProfile, String sessionDescription) {
-                // this callback is triggered only for reinvite.
-                synchronized (SipAudioCall.this) {
-                    if ((mSipSession == null) || !mInCall
-                            || !session.getCallId().equals(
-                                    mSipSession.getCallId())) {
-                        // should not happen
-                        session.endCall();
-                        return;
-                    }
-
-                    // session changing request
-                    try {
-                        String answer = createAnswer(sessionDescription).encode();
-                        mSipSession.answerCall(answer, SESSION_TIMEOUT);
-                    } catch (Throwable e) {
-                        loge("onRinging():", e);
-                        session.endCall();
-                    }
-                }
-            }
-
-            @Override
-            public void onCallEstablished(SipSession session,
-                    String sessionDescription) {
-                mPeerSd = sessionDescription;
-                if (DBG) log("onCallEstablished(): " + mPeerSd);
-
-                // TODO: how to notify the UI that the remote party is changed
-                if ((mTransferringSession != null)
-                        && (session == mTransferringSession)) {
-                    transferToNewSession();
-                    return;
-                }
-
-                Listener listener = mListener;
-                if (listener != null) {
-                    try {
-                        if (mHold) {
-                            listener.onCallHeld(SipAudioCall.this);
-                        } else {
-                            listener.onCallEstablished(SipAudioCall.this);
-                        }
-                    } catch (Throwable t) {
-                        loge("onCallEstablished(): ", t);
-                    }
-                }
-            }
-
-            @Override
-            public void onCallEnded(SipSession session) {
-                if (DBG) log("onCallEnded: " + session + " mSipSession:" + mSipSession);
-                // reset the trasnferring session if it is the one.
-                if (session == mTransferringSession) {
-                    mTransferringSession = null;
-                    return;
-                }
-                // or ignore the event if the original session is being
-                // transferred to the new one.
-                if ((mTransferringSession != null) ||
-                    (session != mSipSession)) return;
-
-                Listener listener = mListener;
-                if (listener != null) {
-                    try {
-                        listener.onCallEnded(SipAudioCall.this);
-                    } catch (Throwable t) {
-                        loge("onCallEnded(): ", t);
-                    }
-                }
-                close();
-            }
-
-            @Override
-            public void onCallBusy(SipSession session) {
-                if (DBG) log("onCallBusy: " + session);
-                Listener listener = mListener;
-                if (listener != null) {
-                    try {
-                        listener.onCallBusy(SipAudioCall.this);
-                    } catch (Throwable t) {
-                        loge("onCallBusy(): ", t);
-                    }
-                }
-                close(false);
-            }
-
-            @Override
-            public void onCallChangeFailed(SipSession session, int errorCode,
-                    String message) {
-                if (DBG) log("onCallChangedFailed: " + message);
-                mErrorCode = errorCode;
-                mErrorMessage = message;
-                Listener listener = mListener;
-                if (listener != null) {
-                    try {
-                        listener.onError(SipAudioCall.this, mErrorCode,
-                                message);
-                    } catch (Throwable t) {
-                        loge("onCallBusy():", t);
-                    }
-                }
-            }
-
-            @Override
-            public void onError(SipSession session, int errorCode,
-                    String message) {
-                SipAudioCall.this.onError(errorCode, message);
-            }
-
-            @Override
-            public void onRegistering(SipSession session) {
-                // irrelevant
-            }
-
-            @Override
-            public void onRegistrationTimeout(SipSession session) {
-                // irrelevant
-            }
-
-            @Override
-            public void onRegistrationFailed(SipSession session, int errorCode,
-                    String message) {
-                // irrelevant
-            }
-
-            @Override
-            public void onRegistrationDone(SipSession session, int duration) {
-                // irrelevant
-            }
-
-            @Override
-            public void onCallTransferring(SipSession newSession,
-                    String sessionDescription) {
-                if (DBG) log("onCallTransferring: mSipSession="
-                        + mSipSession + " newSession=" + newSession);
-                mTransferringSession = newSession;
-                try {
-                    if (sessionDescription == null) {
-                        newSession.makeCall(newSession.getPeerProfile(),
-                                createOffer().encode(), TRANSFER_TIMEOUT);
-                    } else {
-                        String answer = createAnswer(sessionDescription).encode();
-                        newSession.answerCall(answer, SESSION_TIMEOUT);
-                    }
-                } catch (Throwable e) {
-                    loge("onCallTransferring()", e);
-                    newSession.endCall();
-                }
-            }
-        };
-    }
-
-    private void onError(int errorCode, String message) {
-        if (DBG) log("onError: "
-                + SipErrorCode.toString(errorCode) + ": " + message);
-        mErrorCode = errorCode;
-        mErrorMessage = message;
-        Listener listener = mListener;
-        if (listener != null) {
-            try {
-                listener.onError(this, errorCode, message);
-            } catch (Throwable t) {
-                loge("onError():", t);
-            }
-        }
-        synchronized (this) {
-            if ((errorCode == SipErrorCode.DATA_CONNECTION_LOST)
-                    || !isInCall()) {
-                close(true);
-            }
-        }
-    }
-
-    /**
-     * Attaches an incoming call to this call object.
-     *
-     * @param session the session that receives the incoming call
-     * @param sessionDescription the session description of the incoming call
-     * @throws SipException if the SIP service fails to attach this object to
-     *        the session or VOIP API is not supported by the device
-     * @see SipManager#isVoipSupported
-     */
-    public void attachCall(SipSession session, String sessionDescription)
-            throws SipException {
-        if (!SipManager.isVoipSupported(mContext)) {
-            throw new SipException("VOIP API is not supported");
-        }
-
-        synchronized (this) {
-            mSipSession = session;
-            mPeerSd = sessionDescription;
-            if (DBG) log("attachCall(): " + mPeerSd);
-            try {
-                session.setListener(createListener());
-            } catch (Throwable e) {
-                loge("attachCall()", e);
-                throwSipException(e);
-            }
-        }
-    }
-
-    /**
-     * Initiates an audio call to the specified profile. The attempt will be
-     * timed out if the call is not established within {@code timeout} seconds
-     * and {@link Listener#onError onError(SipAudioCall, SipErrorCode.TIME_OUT, String)}
-     * will be called.
-     *
-     * @param peerProfile the SIP profile to make the call to
-     * @param sipSession the {@link SipSession} for carrying out the call
-     * @param timeout the timeout value in seconds. Default value (defined by
-     *        SIP protocol) is used if {@code timeout} is zero or negative.
-     * @see Listener#onError
-     * @throws SipException if the SIP service fails to create a session for the
-     *        call or VOIP API is not supported by the device
-     * @see SipManager#isVoipSupported
-     */
-    public void makeCall(SipProfile peerProfile, SipSession sipSession,
-            int timeout) throws SipException {
-        if (DBG) log("makeCall: " + peerProfile + " session=" + sipSession + " timeout=" + timeout);
-        if (!SipManager.isVoipSupported(mContext)) {
-            throw new SipException("VOIP API is not supported");
-        }
-
-        synchronized (this) {
-            mSipSession = sipSession;
-            try {
-                mAudioStream = new AudioStream(InetAddress.getByName(
-                        getLocalIp()));
-                sipSession.setListener(createListener());
-                sipSession.makeCall(peerProfile, createOffer().encode(),
-                        timeout);
-            } catch (IOException e) {
-                loge("makeCall:", e);
-                throw new SipException("makeCall()", e);
-            }
-        }
-    }
-
-    /**
-     * Ends a call.
-     * @throws SipException if the SIP service fails to end the call
-     */
-    public void endCall() throws SipException {
-        if (DBG) log("endCall: mSipSession" + mSipSession);
-        synchronized (this) {
-            stopCall(RELEASE_SOCKET);
-            mInCall = false;
-
-            // perform the above local ops first and then network op
-            if (mSipSession != null) mSipSession.endCall();
-        }
-    }
-
-    /**
-     * Puts a call on hold.  When succeeds, {@link Listener#onCallHeld} is
-     * called. The attempt will be timed out if the call is not established
-     * within {@code timeout} seconds and
-     * {@link Listener#onError onError(SipAudioCall, SipErrorCode.TIME_OUT, String)}
-     * will be called.
-     *
-     * @param timeout the timeout value in seconds. Default value (defined by
-     *        SIP protocol) is used if {@code timeout} is zero or negative.
-     * @see Listener#onError
-     * @throws SipException if the SIP service fails to hold the call
-     */
-    public void holdCall(int timeout) throws SipException {
-        if (DBG) log("holdCall: mSipSession" + mSipSession + " timeout=" + timeout);
-        synchronized (this) {
-            if (mHold) return;
-            if (mSipSession == null) {
-                loge("holdCall:");
-                throw new SipException("Not in a call to hold call");
-            }
-            mSipSession.changeCall(createHoldOffer().encode(), timeout);
-            mHold = true;
-            setAudioGroupMode();
-        }
-    }
-
-    /**
-     * Answers a call. The attempt will be timed out if the call is not
-     * established within {@code timeout} seconds and
-     * {@link Listener#onError onError(SipAudioCall, SipErrorCode.TIME_OUT, String)}
-     * will be called.
-     *
-     * @param timeout the timeout value in seconds. Default value (defined by
-     *        SIP protocol) is used if {@code timeout} is zero or negative.
-     * @see Listener#onError
-     * @throws SipException if the SIP service fails to answer the call
-     */
-    public void answerCall(int timeout) throws SipException {
-        if (DBG) log("answerCall: mSipSession" + mSipSession + " timeout=" + timeout);
-        synchronized (this) {
-            if (mSipSession == null) {
-                throw new SipException("No call to answer");
-            }
-            try {
-                mAudioStream = new AudioStream(InetAddress.getByName(
-                        getLocalIp()));
-                mSipSession.answerCall(createAnswer(mPeerSd).encode(), timeout);
-            } catch (IOException e) {
-                loge("answerCall:", e);
-                throw new SipException("answerCall()", e);
-            }
-        }
-    }
-
-    /**
-     * Continues a call that's on hold. When succeeds,
-     * {@link Listener#onCallEstablished} is called. The attempt will be timed
-     * out if the call is not established within {@code timeout} seconds and
-     * {@link Listener#onError onError(SipAudioCall, SipErrorCode.TIME_OUT, String)}
-     * will be called.
-     *
-     * @param timeout the timeout value in seconds. Default value (defined by
-     *        SIP protocol) is used if {@code timeout} is zero or negative.
-     * @see Listener#onError
-     * @throws SipException if the SIP service fails to unhold the call
-     */
-    public void continueCall(int timeout) throws SipException {
-        if (DBG) log("continueCall: mSipSession" + mSipSession + " timeout=" + timeout);
-        synchronized (this) {
-            if (!mHold) return;
-            mSipSession.changeCall(createContinueOffer().encode(), timeout);
-            mHold = false;
-            setAudioGroupMode();
-        }
-    }
-
-    private SimpleSessionDescription createOffer() {
-        SimpleSessionDescription offer =
-                new SimpleSessionDescription(mSessionId, getLocalIp());
-        AudioCodec[] codecs = AudioCodec.getCodecs();
-        Media media = offer.newMedia(
-                "audio", mAudioStream.getLocalPort(), 1, "RTP/AVP");
-        for (AudioCodec codec : AudioCodec.getCodecs()) {
-            media.setRtpPayload(codec.type, codec.rtpmap, codec.fmtp);
-        }
-        media.setRtpPayload(127, "telephone-event/8000", "0-15");
-        if (DBG) log("createOffer: offer=" + offer);
-        return offer;
-    }
-
-    private SimpleSessionDescription createAnswer(String offerSd) {
-        if (TextUtils.isEmpty(offerSd)) return createOffer();
-        SimpleSessionDescription offer =
-                new SimpleSessionDescription(offerSd);
-        SimpleSessionDescription answer =
-                new SimpleSessionDescription(mSessionId, getLocalIp());
-        AudioCodec codec = null;
-        for (Media media : offer.getMedia()) {
-            if ((codec == null) && (media.getPort() > 0)
-                    && "audio".equals(media.getType())
-                    && "RTP/AVP".equals(media.getProtocol())) {
-                // Find the first audio codec we supported.
-                for (int type : media.getRtpPayloadTypes()) {
-                    codec = AudioCodec.getCodec(type, media.getRtpmap(type),
-                            media.getFmtp(type));
-                    if (codec != null) {
-                        break;
-                    }
-                }
-                if (codec != null) {
-                    Media reply = answer.newMedia(
-                            "audio", mAudioStream.getLocalPort(), 1, "RTP/AVP");
-                    reply.setRtpPayload(codec.type, codec.rtpmap, codec.fmtp);
-
-                    // Check if DTMF is supported in the same media.
-                    for (int type : media.getRtpPayloadTypes()) {
-                        String rtpmap = media.getRtpmap(type);
-                        if ((type != codec.type) && (rtpmap != null)
-                                && rtpmap.startsWith("telephone-event")) {
-                            reply.setRtpPayload(
-                                    type, rtpmap, media.getFmtp(type));
-                        }
-                    }
-
-                    // Handle recvonly and sendonly.
-                    if (media.getAttribute("recvonly") != null) {
-                        answer.setAttribute("sendonly", "");
-                    } else if(media.getAttribute("sendonly") != null) {
-                        answer.setAttribute("recvonly", "");
-                    } else if(offer.getAttribute("recvonly") != null) {
-                        answer.setAttribute("sendonly", "");
-                    } else if(offer.getAttribute("sendonly") != null) {
-                        answer.setAttribute("recvonly", "");
-                    }
-                    continue;
-                }
-            }
-            // Reject the media.
-            Media reply = answer.newMedia(
-                    media.getType(), 0, 1, media.getProtocol());
-            for (String format : media.getFormats()) {
-                reply.setFormat(format, null);
-            }
-        }
-        if (codec == null) {
-            loge("createAnswer: no suitable codes");
-            throw new IllegalStateException("Reject SDP: no suitable codecs");
-        }
-        if (DBG) log("createAnswer: answer=" + answer);
-        return answer;
-    }
-
-    private SimpleSessionDescription createHoldOffer() {
-        SimpleSessionDescription offer = createContinueOffer();
-        offer.setAttribute("sendonly", "");
-        if (DBG) log("createHoldOffer: offer=" + offer);
-        return offer;
-    }
-
-    private SimpleSessionDescription createContinueOffer() {
-        if (DBG) log("createContinueOffer");
-        SimpleSessionDescription offer =
-                new SimpleSessionDescription(mSessionId, getLocalIp());
-        Media media = offer.newMedia(
-                "audio", mAudioStream.getLocalPort(), 1, "RTP/AVP");
-        AudioCodec codec = mAudioStream.getCodec();
-        media.setRtpPayload(codec.type, codec.rtpmap, codec.fmtp);
-        int dtmfType = mAudioStream.getDtmfType();
-        if (dtmfType != -1) {
-            media.setRtpPayload(dtmfType, "telephone-event/8000", "0-15");
-        }
-        return offer;
-    }
-
-    private void grabWifiHighPerfLock() {
-        if (mWifiHighPerfLock == null) {
-            if (DBG) log("grabWifiHighPerfLock:");
-            mWifiHighPerfLock = ((WifiManager)
-                    mContext.getSystemService(Context.WIFI_SERVICE))
-                    .createWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF, LOG_TAG);
-            mWifiHighPerfLock.acquire();
-        }
-    }
-
-    private void releaseWifiHighPerfLock() {
-        if (mWifiHighPerfLock != null) {
-            if (DBG) log("releaseWifiHighPerfLock:");
-            mWifiHighPerfLock.release();
-            mWifiHighPerfLock = null;
-        }
-    }
-
-    private boolean isWifiOn() {
-        return (mWm.getConnectionInfo().getBSSID() == null) ? false : true;
-    }
-
-    /** Toggles mute. */
-    public void toggleMute() {
-        synchronized (this) {
-            mMuted = !mMuted;
-            setAudioGroupMode();
-        }
-    }
-
-    /**
-     * Checks if the call is muted.
-     *
-     * @return true if the call is muted
-     */
-    public boolean isMuted() {
-        synchronized (this) {
-            return mMuted;
-        }
-    }
-
-    /**
-     * Puts the device to speaker mode.
-     * <p class="note"><strong>Note:</strong> Requires the
-     *   {@link android.Manifest.permission#MODIFY_AUDIO_SETTINGS} permission.</p>
-     *
-     * @param speakerMode set true to enable speaker mode; false to disable
-     */
-    public void setSpeakerMode(boolean speakerMode) {
-        synchronized (this) {
-            ((AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE))
-                    .setSpeakerphoneOn(speakerMode);
-            setAudioGroupMode();
-        }
-    }
-
-    private boolean isSpeakerOn() {
-        return ((AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE))
-                .isSpeakerphoneOn();
-    }
-
-    /**
-     * Sends a DTMF code. According to <a href="http://tools.ietf.org/html/rfc2833">RFC 2883</a>,
-     * event 0--9 maps to decimal
-     * value 0--9, '*' to 10, '#' to 11, event 'A'--'D' to 12--15, and event
-     * flash to 16. Currently, event flash is not supported.
-     *
-     * @param code the DTMF code to send. Value 0 to 15 (inclusive) are valid
-     *        inputs.
-     */
-    public void sendDtmf(int code) {
-        sendDtmf(code, null);
-    }
-
-    /**
-     * Sends a DTMF code. According to <a href="http://tools.ietf.org/html/rfc2833">RFC 2883</a>,
-     * event 0--9 maps to decimal
-     * value 0--9, '*' to 10, '#' to 11, event 'A'--'D' to 12--15, and event
-     * flash to 16. Currently, event flash is not supported.
-     *
-     * @param code the DTMF code to send. Value 0 to 15 (inclusive) are valid
-     *        inputs.
-     * @param result the result message to send when done
-     */
-    public void sendDtmf(int code, Message result) {
-        synchronized (this) {
-            AudioGroup audioGroup = getAudioGroup();
-            if ((audioGroup != null) && (mSipSession != null)
-                    && (SipSession.State.IN_CALL == getState())) {
-                if (DBG) log("sendDtmf: code=" + code + " result=" + result);
-                audioGroup.sendDtmf(code);
-            }
-            if (result != null) result.sendToTarget();
-        }
-    }
-
-    /**
-     * Gets the {@link AudioStream} object used in this call. The object
-     * represents the RTP stream that carries the audio data to and from the
-     * peer. The object may not be created before the call is established. And
-     * it is undefined after the call ends or the {@link #close} method is
-     * called.
-     *
-     * @return the {@link AudioStream} object or null if the RTP stream has not
-     *      yet been set up
-     * @hide
-     */
-    public AudioStream getAudioStream() {
-        synchronized (this) {
-            return mAudioStream;
-        }
-    }
-
-    /**
-     * Gets the {@link AudioGroup} object which the {@link AudioStream} object
-     * joins. The group object may not exist before the call is established.
-     * Also, the {@code AudioStream} may change its group during a call (e.g.,
-     * after the call is held/un-held). Finally, the {@code AudioGroup} object
-     * returned by this method is undefined after the call ends or the
-     * {@link #close} method is called. If a group object is set by
-     * {@link #setAudioGroup(AudioGroup)}, then this method returns that object.
-     *
-     * @return the {@link AudioGroup} object or null if the RTP stream has not
-     *      yet been set up
-     * @see #getAudioStream
-     * @hide
-     */
-    public AudioGroup getAudioGroup() {
-        synchronized (this) {
-            if (mAudioGroup != null) return mAudioGroup;
-            return ((mAudioStream == null) ? null : mAudioStream.getGroup());
-        }
-    }
-
-    /**
-     * Sets the {@link AudioGroup} object which the {@link AudioStream} object
-     * joins. If {@code audioGroup} is null, then the {@code AudioGroup} object
-     * will be dynamically created when needed. Note that the mode of the
-     * {@code AudioGroup} is not changed according to the audio settings (i.e.,
-     * hold, mute, speaker phone) of this object. This is mainly used to merge
-     * multiple {@code SipAudioCall} objects to form a conference call. The
-     * settings of the first object (that merges others) override others'.
-     *
-     * @see #getAudioStream
-     * @hide
-     */
-    public void setAudioGroup(AudioGroup group) {
-        synchronized (this) {
-            if (DBG) log("setAudioGroup: group=" + group);
-            if ((mAudioStream != null) && (mAudioStream.getGroup() != null)) {
-                mAudioStream.join(group);
-            }
-            mAudioGroup = group;
-        }
-    }
-
-    /**
-     * Starts the audio for the established call. This method should be called
-     * after {@link Listener#onCallEstablished} is called.
-     * <p class="note"><strong>Note:</strong> Requires the
-     *   {@link android.Manifest.permission#RECORD_AUDIO},
-     *   {@link android.Manifest.permission#ACCESS_WIFI_STATE} and
-     *   {@link android.Manifest.permission#WAKE_LOCK} permissions.</p>
-     */
-    public void startAudio() {
-        try {
-            startAudioInternal();
-        } catch (UnknownHostException e) {
-            onError(SipErrorCode.PEER_NOT_REACHABLE, e.getMessage());
-        } catch (Throwable e) {
-            onError(SipErrorCode.CLIENT_ERROR, e.getMessage());
-        }
-    }
-
-    private synchronized void startAudioInternal() throws UnknownHostException {
-        if (DBG) loge("startAudioInternal: mPeerSd=" + mPeerSd);
-        if (mPeerSd == null) {
-            throw new IllegalStateException("mPeerSd = null");
-        }
-
-        stopCall(DONT_RELEASE_SOCKET);
-        mInCall = true;
-
-        // Run exact the same logic in createAnswer() to setup mAudioStream.
-        SimpleSessionDescription offer =
-                new SimpleSessionDescription(mPeerSd);
-        AudioStream stream = mAudioStream;
-        AudioCodec codec = null;
-        for (Media media : offer.getMedia()) {
-            if ((codec == null) && (media.getPort() > 0)
-                    && "audio".equals(media.getType())
-                    && "RTP/AVP".equals(media.getProtocol())) {
-                // Find the first audio codec we supported.
-                for (int type : media.getRtpPayloadTypes()) {
-                    codec = AudioCodec.getCodec(
-                            type, media.getRtpmap(type), media.getFmtp(type));
-                    if (codec != null) {
-                        break;
-                    }
-                }
-
-                if (codec != null) {
-                    // Associate with the remote host.
-                    String address = media.getAddress();
-                    if (address == null) {
-                        address = offer.getAddress();
-                    }
-                    stream.associate(InetAddress.getByName(address),
-                            media.getPort());
-
-                    stream.setDtmfType(-1);
-                    stream.setCodec(codec);
-                    // Check if DTMF is supported in the same media.
-                    for (int type : media.getRtpPayloadTypes()) {
-                        String rtpmap = media.getRtpmap(type);
-                        if ((type != codec.type) && (rtpmap != null)
-                                && rtpmap.startsWith("telephone-event")) {
-                            stream.setDtmfType(type);
-                        }
-                    }
-
-                    // Handle recvonly and sendonly.
-                    if (mHold) {
-                        stream.setMode(RtpStream.MODE_NORMAL);
-                    } else if (media.getAttribute("recvonly") != null) {
-                        stream.setMode(RtpStream.MODE_SEND_ONLY);
-                    } else if(media.getAttribute("sendonly") != null) {
-                        stream.setMode(RtpStream.MODE_RECEIVE_ONLY);
-                    } else if(offer.getAttribute("recvonly") != null) {
-                        stream.setMode(RtpStream.MODE_SEND_ONLY);
-                    } else if(offer.getAttribute("sendonly") != null) {
-                        stream.setMode(RtpStream.MODE_RECEIVE_ONLY);
-                    } else {
-                        stream.setMode(RtpStream.MODE_NORMAL);
-                    }
-                    break;
-                }
-            }
-        }
-        if (codec == null) {
-            throw new IllegalStateException("Reject SDP: no suitable codecs");
-        }
-
-        if (isWifiOn()) grabWifiHighPerfLock();
-
-        // AudioGroup logic:
-        AudioGroup audioGroup = getAudioGroup();
-        if (mHold) {
-            // don't create an AudioGroup here; doing so will fail if
-            // there's another AudioGroup out there that's active
-        } else {
-            if (audioGroup == null) audioGroup = new AudioGroup();
-            stream.join(audioGroup);
-        }
-        setAudioGroupMode();
-    }
-
-    // set audio group mode based on current audio configuration
-    private void setAudioGroupMode() {
-        AudioGroup audioGroup = getAudioGroup();
-        if (DBG) log("setAudioGroupMode: audioGroup=" + audioGroup);
-        if (audioGroup != null) {
-            if (mHold) {
-                audioGroup.setMode(AudioGroup.MODE_ON_HOLD);
-            } else if (mMuted) {
-                audioGroup.setMode(AudioGroup.MODE_MUTED);
-            } else if (isSpeakerOn()) {
-                audioGroup.setMode(AudioGroup.MODE_ECHO_SUPPRESSION);
-            } else {
-                audioGroup.setMode(AudioGroup.MODE_NORMAL);
-            }
-        }
-    }
-
-    private void stopCall(boolean releaseSocket) {
-        if (DBG) log("stopCall: releaseSocket=" + releaseSocket);
-        releaseWifiHighPerfLock();
-        if (mAudioStream != null) {
-            mAudioStream.join(null);
-
-            if (releaseSocket) {
-                mAudioStream.release();
-                mAudioStream = null;
-            }
-        }
-    }
-
-    private String getLocalIp() {
-        return mSipSession.getLocalIp();
-    }
-
-    private void throwSipException(Throwable throwable) throws SipException {
-        if (throwable instanceof SipException) {
-            throw (SipException) throwable;
-        } else {
-            throw new SipException("", throwable);
-        }
-    }
-
-    private void log(String s) {
-        Rlog.d(LOG_TAG, s);
-    }
-
-    private void loge(String s) {
-        Rlog.e(LOG_TAG, s);
-    }
-
-    private void loge(String s, Throwable t) {
-        Rlog.e(LOG_TAG, s, t);
-    }
-}
diff --git a/voip/java/android/net/sip/SipErrorCode.java b/voip/java/android/net/sip/SipErrorCode.java
deleted file mode 100644
index 509728f..0000000
--- a/voip/java/android/net/sip/SipErrorCode.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-package android.net.sip;
-
-/**
- * Defines error codes returned during SIP actions. For example, during
- * {@link SipRegistrationListener#onRegistrationFailed onRegistrationFailed()},
- * {@link SipSession.Listener#onError onError()},
- * {@link SipSession.Listener#onCallChangeFailed onCallChangeFailed()} and
- * {@link SipSession.Listener#onRegistrationFailed onRegistrationFailed()}.
- */
-public class SipErrorCode {
-    /** Not an error. */
-    public static final int NO_ERROR = 0;
-
-    /** When some socket error occurs. */
-    public static final int SOCKET_ERROR = -1;
-
-    /** When server responds with an error. */
-    public static final int SERVER_ERROR = -2;
-
-    /** When transaction is terminated unexpectedly. */
-    public static final int TRANSACTION_TERMINTED = -3;
-
-    /** When some error occurs on the device, possibly due to a bug. */
-    public static final int CLIENT_ERROR = -4;
-
-    /** When the transaction gets timed out. */
-    public static final int TIME_OUT = -5;
-
-    /** When the remote URI is not valid. */
-    public static final int INVALID_REMOTE_URI = -6;
-
-    /** When the peer is not reachable. */
-    public static final int PEER_NOT_REACHABLE = -7;
-
-    /** When invalid credentials are provided. */
-    public static final int INVALID_CREDENTIALS = -8;
-
-    /** The client is in a transaction and cannot initiate a new one. */
-    public static final int IN_PROGRESS = -9;
-
-    /** When data connection is lost. */
-    public static final int DATA_CONNECTION_LOST = -10;
-
-    /** Cross-domain authentication required. */
-    public static final int CROSS_DOMAIN_AUTHENTICATION = -11;
-
-    /** When the server is not reachable. */
-    public static final int SERVER_UNREACHABLE = -12;
-
-    public static String toString(int errorCode) {
-        switch (errorCode) {
-            case NO_ERROR:
-                return "NO_ERROR";
-            case SOCKET_ERROR:
-                return "SOCKET_ERROR";
-            case SERVER_ERROR:
-                return "SERVER_ERROR";
-            case TRANSACTION_TERMINTED:
-                return "TRANSACTION_TERMINTED";
-            case CLIENT_ERROR:
-                return "CLIENT_ERROR";
-            case TIME_OUT:
-                return "TIME_OUT";
-            case INVALID_REMOTE_URI:
-                return "INVALID_REMOTE_URI";
-            case PEER_NOT_REACHABLE:
-                return "PEER_NOT_REACHABLE";
-            case INVALID_CREDENTIALS:
-                return "INVALID_CREDENTIALS";
-            case IN_PROGRESS:
-                return "IN_PROGRESS";
-            case DATA_CONNECTION_LOST:
-                return "DATA_CONNECTION_LOST";
-            case CROSS_DOMAIN_AUTHENTICATION:
-                return "CROSS_DOMAIN_AUTHENTICATION";
-            case SERVER_UNREACHABLE:
-                return "SERVER_UNREACHABLE";
-            default:
-                return "UNKNOWN";
-        }
-    }
-
-    private SipErrorCode() {
-    }
-}
diff --git a/voip/java/android/net/sip/SipException.java b/voip/java/android/net/sip/SipException.java
deleted file mode 100644
index 0339395..0000000
--- a/voip/java/android/net/sip/SipException.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-package android.net.sip;
-
-/**
- * Indicates a general SIP-related exception.
- */
-public class SipException extends Exception {
-    public SipException() {
-    }
-
-    public SipException(String message) {
-        super(message);
-    }
-
-    public SipException(String message, Throwable cause) {
-        // we want to eliminate the dependency on javax.sip.SipException
-        super(message, ((cause instanceof javax.sip.SipException)
-                && (cause.getCause() != null))
-                ? cause.getCause()
-                : cause);
-    }
-}
diff --git a/voip/java/android/net/sip/SipManager.java b/voip/java/android/net/sip/SipManager.java
deleted file mode 100644
index a94232a..0000000
--- a/voip/java/android/net/sip/SipManager.java
+++ /dev/null
@@ -1,622 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-package android.net.sip;
-
-import android.app.PendingIntent;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.telephony.Rlog;
-
-import java.text.ParseException;
-
-/**
- * Provides APIs for SIP tasks, such as initiating SIP connections, and provides access to related
- * SIP services. This class is the starting point for any SIP actions. You can acquire an instance
- * of it with {@link #newInstance newInstance()}.</p>
- * <p>The APIs in this class allows you to:</p>
- * <ul>
- * <li>Create a {@link SipSession} to get ready for making calls or listen for incoming calls. See
- * {@link #createSipSession createSipSession()} and {@link #getSessionFor getSessionFor()}.</li>
- * <li>Initiate and receive generic SIP calls or audio-only SIP calls. Generic SIP calls may
- * be video, audio, or other, and are initiated with {@link #open open()}. Audio-only SIP calls
- * should be handled with a {@link SipAudioCall}, which you can acquire with {@link
- * #makeAudioCall makeAudioCall()} and {@link #takeAudioCall takeAudioCall()}.</li>
- * <li>Register and unregister with a SIP service provider, with
- *      {@link #register register()} and {@link #unregister unregister()}.</li>
- * <li>Verify session connectivity, with {@link #isOpened isOpened()} and
- *      {@link #isRegistered isRegistered()}.</li>
- * </ul>
- * <p class="note"><strong>Note:</strong> Not all Android-powered devices support VOIP calls using
- * SIP. You should always call {@link android.net.sip.SipManager#isVoipSupported
- * isVoipSupported()} to verify that the device supports VOIP calling and {@link
- * android.net.sip.SipManager#isApiSupported isApiSupported()} to verify that the device supports
- * the SIP APIs. Your application must also request the {@link
- * android.Manifest.permission#INTERNET} and {@link android.Manifest.permission#USE_SIP}
- * permissions.</p>
- *
- * <div class="special reference">
- * <h3>Developer Guides</h3>
- * <p>For more information about using SIP, read the
- * <a href="{@docRoot}guide/topics/network/sip.html">Session Initiation Protocol</a>
- * developer guide.</p>
- * </div>
- */
-public class SipManager {
-    /**
-     * The result code to be sent back with the incoming call
-     * {@link PendingIntent}.
-     * @see #open(SipProfile, PendingIntent, SipRegistrationListener)
-     */
-    public static final int INCOMING_CALL_RESULT_CODE = 101;
-
-    /**
-     * Key to retrieve the call ID from an incoming call intent.
-     * @see #open(SipProfile, PendingIntent, SipRegistrationListener)
-     */
-    public static final String EXTRA_CALL_ID = "android:sipCallID";
-
-    /**
-     * Key to retrieve the offered session description from an incoming call
-     * intent.
-     * @see #open(SipProfile, PendingIntent, SipRegistrationListener)
-     */
-    public static final String EXTRA_OFFER_SD = "android:sipOfferSD";
-
-    /**
-     * Action to broadcast when SipService is up.
-     * Internal use only.
-     * @hide
-     */
-    public static final String ACTION_SIP_SERVICE_UP =
-            "android.net.sip.SIP_SERVICE_UP";
-    /**
-     * Action string for the incoming call intent for the Phone app.
-     * Internal use only.
-     * @hide
-     */
-    public static final String ACTION_SIP_INCOMING_CALL =
-            "com.android.phone.SIP_INCOMING_CALL";
-    /**
-     * Action string for the add-phone intent.
-     * Internal use only.
-     * @hide
-     */
-    public static final String ACTION_SIP_ADD_PHONE =
-            "com.android.phone.SIP_ADD_PHONE";
-    /**
-     * Action string for the remove-phone intent.
-     * Internal use only.
-     * @hide
-     */
-    public static final String ACTION_SIP_REMOVE_PHONE =
-            "com.android.phone.SIP_REMOVE_PHONE";
-    /**
-     * Part of the ACTION_SIP_ADD_PHONE and ACTION_SIP_REMOVE_PHONE intents.
-     * Internal use only.
-     * @hide
-     */
-    public static final String EXTRA_LOCAL_URI = "android:localSipUri";
-
-    private static final String TAG = "SipManager";
-
-    private ISipService mSipService;
-    private Context mContext;
-
-    /**
-     * Creates a manager instance. Returns null if SIP API is not supported.
-     *
-     * @param context application context for creating the manager object
-     * @return the manager instance or null if SIP API is not supported
-     */
-    public static SipManager newInstance(Context context) {
-        return (isApiSupported(context) ? new SipManager(context) : null);
-    }
-
-    /**
-     * Returns true if the SIP API is supported by the system.
-     */
-    public static boolean isApiSupported(Context context) {
-        return context.getPackageManager().hasSystemFeature(
-                PackageManager.FEATURE_SIP);
-    }
-
-    /**
-     * Returns true if the system supports SIP-based VOIP API.
-     */
-    public static boolean isVoipSupported(Context context) {
-        return context.getPackageManager().hasSystemFeature(
-                PackageManager.FEATURE_SIP_VOIP) && isApiSupported(context);
-    }
-
-    /**
-     * Returns true if SIP is only available on WIFI.
-     */
-    public static boolean isSipWifiOnly(Context context) {
-        return context.getResources().getBoolean(
-                com.android.internal.R.bool.config_sip_wifi_only);
-    }
-
-    private SipManager(Context context) {
-        mContext = context;
-        createSipService();
-    }
-
-    private void createSipService() {
-        IBinder b = ServiceManager.getService(Context.SIP_SERVICE);
-        mSipService = ISipService.Stub.asInterface(b);
-    }
-
-    /**
-     * Opens the profile for making generic SIP calls. The caller may make subsequent calls
-     * through {@link #makeAudioCall}. If one also wants to receive calls on the
-     * profile, use
-     * {@link #open(SipProfile, PendingIntent, SipRegistrationListener)}
-     * instead.
-     *
-     * @param localProfile the SIP profile to make calls from
-     * @throws SipException if the profile contains incorrect settings or
-     *      calling the SIP service results in an error
-     */
-    public void open(SipProfile localProfile) throws SipException {
-        try {
-            mSipService.open(localProfile);
-        } catch (RemoteException e) {
-            throw new SipException("open()", e);
-        }
-    }
-
-    /**
-     * Opens the profile for making calls and/or receiving generic SIP calls. The caller may
-     * make subsequent calls through {@link #makeAudioCall}. If the
-     * auto-registration option is enabled in the profile, the SIP service
-     * will register the profile to the corresponding SIP provider periodically
-     * in order to receive calls from the provider. When the SIP service
-     * receives a new call, it will send out an intent with the provided action
-     * string. The intent contains a call ID extra and an offer session
-     * description string extra. Use {@link #getCallId} and
-     * {@link #getOfferSessionDescription} to retrieve those extras.
-     *
-     * @param localProfile the SIP profile to receive incoming calls for
-     * @param incomingCallPendingIntent When an incoming call is received, the
-     *      SIP service will call
-     *      {@link PendingIntent#send(Context, int, Intent)} to send back the
-     *      intent to the caller with {@link #INCOMING_CALL_RESULT_CODE} as the
-     *      result code and the intent to fill in the call ID and session
-     *      description information. It cannot be null.
-     * @param listener to listen to registration events; can be null
-     * @see #getCallId
-     * @see #getOfferSessionDescription
-     * @see #takeAudioCall
-     * @throws NullPointerException if {@code incomingCallPendingIntent} is null
-     * @throws SipException if the profile contains incorrect settings or
-     *      calling the SIP service results in an error
-     * @see #isIncomingCallIntent
-     * @see #getCallId
-     * @see #getOfferSessionDescription
-     */
-    public void open(SipProfile localProfile,
-            PendingIntent incomingCallPendingIntent,
-            SipRegistrationListener listener) throws SipException {
-        if (incomingCallPendingIntent == null) {
-            throw new NullPointerException(
-                    "incomingCallPendingIntent cannot be null");
-        }
-        try {
-            mSipService.open3(localProfile, incomingCallPendingIntent,
-                    createRelay(listener, localProfile.getUriString()));
-        } catch (RemoteException e) {
-            throw new SipException("open()", e);
-        }
-    }
-
-    /**
-     * Sets the listener to listen to registration events. No effect if the
-     * profile has not been opened to receive calls (see
-     * {@link #open(SipProfile, PendingIntent, SipRegistrationListener)}).
-     *
-     * @param localProfileUri the URI of the profile
-     * @param listener to listen to registration events; can be null
-     * @throws SipException if calling the SIP service results in an error
-     */
-    public void setRegistrationListener(String localProfileUri,
-            SipRegistrationListener listener) throws SipException {
-        try {
-            mSipService.setRegistrationListener(
-                    localProfileUri, createRelay(listener, localProfileUri));
-        } catch (RemoteException e) {
-            throw new SipException("setRegistrationListener()", e);
-        }
-    }
-
-    /**
-     * Closes the specified profile to not make/receive calls. All the resources
-     * that were allocated to the profile are also released.
-     *
-     * @param localProfileUri the URI of the profile to close
-     * @throws SipException if calling the SIP service results in an error
-     */
-    public void close(String localProfileUri) throws SipException {
-        try {
-            mSipService.close(localProfileUri);
-        } catch (RemoteException e) {
-            throw new SipException("close()", e);
-        }
-    }
-
-    /**
-     * Checks if the specified profile is opened in the SIP service for
-     * making and/or receiving calls.
-     *
-     * @param localProfileUri the URI of the profile in question
-     * @return true if the profile is enabled to receive calls
-     * @throws SipException if calling the SIP service results in an error
-     */
-    public boolean isOpened(String localProfileUri) throws SipException {
-        try {
-            return mSipService.isOpened(localProfileUri);
-        } catch (RemoteException e) {
-            throw new SipException("isOpened()", e);
-        }
-    }
-
-    /**
-     * Checks if the SIP service has successfully registered the profile to the
-     * SIP provider (specified in the profile) for receiving calls. Returning
-     * true from this method also implies the profile is opened
-     * ({@link #isOpened}).
-     *
-     * @param localProfileUri the URI of the profile in question
-     * @return true if the profile is registered to the SIP provider; false if
-     *        the profile has not been opened in the SIP service or the SIP
-     *        service has not yet successfully registered the profile to the SIP
-     *        provider
-     * @throws SipException if calling the SIP service results in an error
-     */
-    public boolean isRegistered(String localProfileUri) throws SipException {
-        try {
-            return mSipService.isRegistered(localProfileUri);
-        } catch (RemoteException e) {
-            throw new SipException("isRegistered()", e);
-        }
-    }
-
-    /**
-     * Creates a {@link SipAudioCall} to make a call. The attempt will be timed
-     * out if the call is not established within {@code timeout} seconds and
-     * {@link SipAudioCall.Listener#onError onError(SipAudioCall, SipErrorCode.TIME_OUT, String)}
-     * will be called.
-     *
-     * @param localProfile the SIP profile to make the call from
-     * @param peerProfile the SIP profile to make the call to
-     * @param listener to listen to the call events from {@link SipAudioCall};
-     *      can be null
-     * @param timeout the timeout value in seconds. Default value (defined by
-     *        SIP protocol) is used if {@code timeout} is zero or negative.
-     * @return a {@link SipAudioCall} object
-     * @throws SipException if calling the SIP service results in an error or
-     *      VOIP API is not supported by the device
-     * @see SipAudioCall.Listener#onError
-     * @see #isVoipSupported
-     */
-    public SipAudioCall makeAudioCall(SipProfile localProfile,
-            SipProfile peerProfile, SipAudioCall.Listener listener, int timeout)
-            throws SipException {
-        if (!isVoipSupported(mContext)) {
-            throw new SipException("VOIP API is not supported");
-        }
-        SipAudioCall call = new SipAudioCall(mContext, localProfile);
-        call.setListener(listener);
-        SipSession s = createSipSession(localProfile, null);
-        call.makeCall(peerProfile, s, timeout);
-        return call;
-    }
-
-    /**
-     * Creates a {@link SipAudioCall} to make an audio call. The attempt will be
-     * timed out if the call is not established within {@code timeout} seconds
-     * and
-     * {@link SipAudioCall.Listener#onError onError(SipAudioCall, SipErrorCode.TIME_OUT, String)}
-     * will be called.
-     *
-     * @param localProfileUri URI of the SIP profile to make the call from
-     * @param peerProfileUri URI of the SIP profile to make the call to
-     * @param listener to listen to the call events from {@link SipAudioCall};
-     *      can be null
-     * @param timeout the timeout value in seconds. Default value (defined by
-     *        SIP protocol) is used if {@code timeout} is zero or negative.
-     * @return a {@link SipAudioCall} object
-     * @throws SipException if calling the SIP service results in an error or
-     *      VOIP API is not supported by the device
-     * @see SipAudioCall.Listener#onError
-     * @see #isVoipSupported
-     */
-    public SipAudioCall makeAudioCall(String localProfileUri,
-            String peerProfileUri, SipAudioCall.Listener listener, int timeout)
-            throws SipException {
-        if (!isVoipSupported(mContext)) {
-            throw new SipException("VOIP API is not supported");
-        }
-        try {
-            return makeAudioCall(
-                    new SipProfile.Builder(localProfileUri).build(),
-                    new SipProfile.Builder(peerProfileUri).build(), listener,
-                    timeout);
-        } catch (ParseException e) {
-            throw new SipException("build SipProfile", e);
-        }
-    }
-
-    /**
-     * Creates a {@link SipAudioCall} to take an incoming call. Before the call
-     * is returned, the listener will receive a
-     * {@link SipAudioCall.Listener#onRinging}
-     * callback.
-     *
-     * @param incomingCallIntent the incoming call broadcast intent
-     * @param listener to listen to the call events from {@link SipAudioCall};
-     *      can be null
-     * @return a {@link SipAudioCall} object
-     * @throws SipException if calling the SIP service results in an error
-     */
-    public SipAudioCall takeAudioCall(Intent incomingCallIntent,
-            SipAudioCall.Listener listener) throws SipException {
-        if (incomingCallIntent == null) {
-            throw new SipException("Cannot retrieve session with null intent");
-        }
-
-        String callId = getCallId(incomingCallIntent);
-        if (callId == null) {
-            throw new SipException("Call ID missing in incoming call intent");
-        }
-
-        String offerSd = getOfferSessionDescription(incomingCallIntent);
-        if (offerSd == null) {
-            throw new SipException("Session description missing in incoming "
-                    + "call intent");
-        }
-
-        try {
-            ISipSession session = mSipService.getPendingSession(callId);
-            if (session == null) {
-                throw new SipException("No pending session for the call");
-            }
-            SipAudioCall call = new SipAudioCall(
-                    mContext, session.getLocalProfile());
-            call.attachCall(new SipSession(session), offerSd);
-            call.setListener(listener);
-            return call;
-        } catch (Throwable t) {
-            throw new SipException("takeAudioCall()", t);
-        }
-    }
-
-    /**
-     * Checks if the intent is an incoming call broadcast intent.
-     *
-     * @param intent the intent in question
-     * @return true if the intent is an incoming call broadcast intent
-     */
-    public static boolean isIncomingCallIntent(Intent intent) {
-        if (intent == null) return false;
-        String callId = getCallId(intent);
-        String offerSd = getOfferSessionDescription(intent);
-        return ((callId != null) && (offerSd != null));
-    }
-
-    /**
-     * Gets the call ID from the specified incoming call broadcast intent.
-     *
-     * @param incomingCallIntent the incoming call broadcast intent
-     * @return the call ID or null if the intent does not contain it
-     */
-    public static String getCallId(Intent incomingCallIntent) {
-        return incomingCallIntent.getStringExtra(EXTRA_CALL_ID);
-    }
-
-    /**
-     * Gets the offer session description from the specified incoming call
-     * broadcast intent.
-     *
-     * @param incomingCallIntent the incoming call broadcast intent
-     * @return the offer session description or null if the intent does not
-     *      have it
-     */
-    public static String getOfferSessionDescription(Intent incomingCallIntent) {
-        return incomingCallIntent.getStringExtra(EXTRA_OFFER_SD);
-    }
-
-    /**
-     * Creates an incoming call broadcast intent.
-     *
-     * @param callId the call ID of the incoming call
-     * @param sessionDescription the session description of the incoming call
-     * @return the incoming call intent
-     * @hide
-     */
-    public static Intent createIncomingCallBroadcast(String callId,
-            String sessionDescription) {
-        Intent intent = new Intent();
-        intent.putExtra(EXTRA_CALL_ID, callId);
-        intent.putExtra(EXTRA_OFFER_SD, sessionDescription);
-        return intent;
-    }
-
-    /**
-     * Manually registers the profile to the corresponding SIP provider for
-     * receiving calls.
-     * {@link #open(SipProfile, PendingIntent, SipRegistrationListener)} is
-     * still needed to be called at least once in order for the SIP service to
-     * notify the caller with the {@link android.app.PendingIntent} when an incoming call is
-     * received.
-     *
-     * @param localProfile the SIP profile to register with
-     * @param expiryTime registration expiration time (in seconds)
-     * @param listener to listen to the registration events
-     * @throws SipException if calling the SIP service results in an error
-     */
-    public void register(SipProfile localProfile, int expiryTime,
-            SipRegistrationListener listener) throws SipException {
-        try {
-            ISipSession session = mSipService.createSession(localProfile,
-                    createRelay(listener, localProfile.getUriString()));
-            if (session == null) {
-                throw new SipException(
-                        "SipService.createSession() returns null");
-            }
-            session.register(expiryTime);
-        } catch (RemoteException e) {
-            throw new SipException("register()", e);
-        }
-    }
-
-    /**
-     * Manually unregisters the profile from the corresponding SIP provider for
-     * stop receiving further calls. This may interference with the auto
-     * registration process in the SIP service if the auto-registration option
-     * in the profile is enabled.
-     *
-     * @param localProfile the SIP profile to register with
-     * @param listener to listen to the registration events
-     * @throws SipException if calling the SIP service results in an error
-     */
-    public void unregister(SipProfile localProfile,
-            SipRegistrationListener listener) throws SipException {
-        try {
-            ISipSession session = mSipService.createSession(localProfile,
-                    createRelay(listener, localProfile.getUriString()));
-            if (session == null) {
-                throw new SipException(
-                        "SipService.createSession() returns null");
-            }
-            session.unregister();
-        } catch (RemoteException e) {
-            throw new SipException("unregister()", e);
-        }
-    }
-
-    /**
-     * Gets the {@link SipSession} that handles the incoming call. For audio
-     * calls, consider to use {@link SipAudioCall} to handle the incoming call.
-     * See {@link #takeAudioCall}. Note that the method may be called only once
-     * for the same intent. For subsequent calls on the same intent, the method
-     * returns null.
-     *
-     * @param incomingCallIntent the incoming call broadcast intent
-     * @return the session object that handles the incoming call
-     */
-    public SipSession getSessionFor(Intent incomingCallIntent)
-            throws SipException {
-        try {
-            String callId = getCallId(incomingCallIntent);
-            ISipSession s = mSipService.getPendingSession(callId);
-            return ((s == null) ? null : new SipSession(s));
-        } catch (RemoteException e) {
-            throw new SipException("getSessionFor()", e);
-        }
-    }
-
-    private static ISipSessionListener createRelay(
-            SipRegistrationListener listener, String uri) {
-        return ((listener == null) ? null : new ListenerRelay(listener, uri));
-    }
-
-    /**
-     * Creates a {@link SipSession} with the specified profile. Use other
-     * methods, if applicable, instead of interacting with {@link SipSession}
-     * directly.
-     *
-     * @param localProfile the SIP profile the session is associated with
-     * @param listener to listen to SIP session events
-     */
-    public SipSession createSipSession(SipProfile localProfile,
-            SipSession.Listener listener) throws SipException {
-        try {
-            ISipSession s = mSipService.createSession(localProfile, null);
-            if (s == null) {
-                throw new SipException(
-                        "Failed to create SipSession; network unavailable?");
-            }
-            return new SipSession(s, listener);
-        } catch (RemoteException e) {
-            throw new SipException("createSipSession()", e);
-        }
-    }
-
-    /**
-     * Gets the list of profiles hosted by the SIP service. The user information
-     * (username, password and display name) are crossed out.
-     * @hide
-     */
-    public SipProfile[] getListOfProfiles() {
-        try {
-            return mSipService.getListOfProfiles();
-        } catch (RemoteException e) {
-            return new SipProfile[0];
-        }
-    }
-
-    private static class ListenerRelay extends SipSessionAdapter {
-        private SipRegistrationListener mListener;
-        private String mUri;
-
-        // listener must not be null
-        public ListenerRelay(SipRegistrationListener listener, String uri) {
-            mListener = listener;
-            mUri = uri;
-        }
-
-        private String getUri(ISipSession session) {
-            try {
-                return ((session == null)
-                        ? mUri
-                        : session.getLocalProfile().getUriString());
-            } catch (Throwable e) {
-                // SipService died? SIP stack died?
-                Rlog.e(TAG, "getUri(): ", e);
-                return null;
-            }
-        }
-
-        @Override
-        public void onRegistering(ISipSession session) {
-            mListener.onRegistering(getUri(session));
-        }
-
-        @Override
-        public void onRegistrationDone(ISipSession session, int duration) {
-            long expiryTime = duration;
-            if (duration > 0) expiryTime += System.currentTimeMillis();
-            mListener.onRegistrationDone(getUri(session), expiryTime);
-        }
-
-        @Override
-        public void onRegistrationFailed(ISipSession session, int errorCode,
-                String message) {
-            mListener.onRegistrationFailed(getUri(session), errorCode, message);
-        }
-
-        @Override
-        public void onRegistrationTimeout(ISipSession session) {
-            mListener.onRegistrationFailed(getUri(session),
-                    SipErrorCode.TIME_OUT, "registration timed out");
-        }
-    }
-}
diff --git a/voip/java/android/net/sip/SipProfile.aidl b/voip/java/android/net/sip/SipProfile.aidl
deleted file mode 100644
index 3b6f68f..0000000
--- a/voip/java/android/net/sip/SipProfile.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-package android.net.sip;
-
-parcelable SipProfile;
diff --git a/voip/java/android/net/sip/SipProfile.java b/voip/java/android/net/sip/SipProfile.java
deleted file mode 100644
index 0ef754c..0000000
--- a/voip/java/android/net/sip/SipProfile.java
+++ /dev/null
@@ -1,502 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-package android.net.sip;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.text.TextUtils;
-
-import java.io.ObjectStreamException;
-import java.io.Serializable;
-import java.text.ParseException;
-import javax.sip.InvalidArgumentException;
-import javax.sip.ListeningPoint;
-import javax.sip.PeerUnavailableException;
-import javax.sip.SipFactory;
-import javax.sip.address.Address;
-import javax.sip.address.AddressFactory;
-import javax.sip.address.SipURI;
-import javax.sip.address.URI;
-
-/**
- * Defines a SIP profile, including a SIP account, domain and server information.
- * <p>You can create a {@link SipProfile} using {@link
- * SipProfile.Builder}. You can also retrieve one from a {@link SipSession}, using {@link
- * SipSession#getLocalProfile} and {@link SipSession#getPeerProfile}.</p>
- *
- * <div class="special reference">
- * <h3>Developer Guides</h3>
- * <p>For more information about using SIP, read the
- * <a href="{@docRoot}guide/topics/network/sip.html">Session Initiation Protocol</a>
- * developer guide.</p>
- * </div>
- */
-public class SipProfile implements Parcelable, Serializable, Cloneable {
-    private static final long serialVersionUID = 1L;
-    private static final int DEFAULT_PORT = 5060;
-    private static final String TCP = "TCP";
-    private static final String UDP = "UDP";
-    private Address mAddress;
-    private String mProxyAddress;
-    private String mPassword;
-    private String mDomain;
-    private String mProtocol = UDP;
-    private String mProfileName;
-    private String mAuthUserName;
-    private int mPort = DEFAULT_PORT;
-    private boolean mSendKeepAlive = false;
-    private boolean mAutoRegistration = true;
-    private transient int mCallingUid = 0;
-
-    public static final Parcelable.Creator<SipProfile> CREATOR =
-            new Parcelable.Creator<SipProfile>() {
-                public SipProfile createFromParcel(Parcel in) {
-                    return new SipProfile(in);
-                }
-
-                public SipProfile[] newArray(int size) {
-                    return new SipProfile[size];
-                }
-            };
-
-    /**
-     * Helper class for creating a {@link SipProfile}.
-     */
-    public static class Builder {
-        private AddressFactory mAddressFactory;
-        private SipProfile mProfile = new SipProfile();
-        private SipURI mUri;
-        private String mDisplayName;
-        private String mProxyAddress;
-
-        {
-            try {
-                mAddressFactory =
-                        SipFactory.getInstance().createAddressFactory();
-            } catch (PeerUnavailableException e) {
-                throw new RuntimeException(e);
-            }
-        }
-
-        /**
-         * Creates a builder based on the given profile.
-         */
-        public Builder(SipProfile profile) {
-            if (profile == null) throw new NullPointerException();
-            try {
-                mProfile = (SipProfile) profile.clone();
-            } catch (CloneNotSupportedException e) {
-                throw new RuntimeException("should not occur", e);
-            }
-            mProfile.mAddress = null;
-            mUri = profile.getUri();
-            mUri.setUserPassword(profile.getPassword());
-            mDisplayName = profile.getDisplayName();
-            mProxyAddress = profile.getProxyAddress();
-            mProfile.mPort = profile.getPort();
-        }
-
-        /**
-         * Constructor.
-         *
-         * @param uriString the URI string as "sip:<user_name>@<domain>"
-         * @throws ParseException if the string is not a valid URI
-         */
-        public Builder(String uriString) throws ParseException {
-            if (uriString == null) {
-                throw new NullPointerException("uriString cannot be null");
-            }
-            URI uri = mAddressFactory.createURI(fix(uriString));
-            if (uri instanceof SipURI) {
-                mUri = (SipURI) uri;
-            } else {
-                throw new ParseException(uriString + " is not a SIP URI", 0);
-            }
-            mProfile.mDomain = mUri.getHost();
-        }
-
-        /**
-         * Constructor.
-         *
-         * @param username username of the SIP account
-         * @param serverDomain the SIP server domain; if the network address
-         *      is different from the domain, use {@link #setOutboundProxy} to
-         *      set server address
-         * @throws ParseException if the parameters are not valid
-         */
-        public Builder(String username, String serverDomain)
-                throws ParseException {
-            if ((username == null) || (serverDomain == null)) {
-                throw new NullPointerException(
-                        "username and serverDomain cannot be null");
-            }
-            mUri = mAddressFactory.createSipURI(username, serverDomain);
-            mProfile.mDomain = serverDomain;
-        }
-
-        private String fix(String uriString) {
-            return (uriString.trim().toLowerCase().startsWith("sip:")
-                    ? uriString
-                    : "sip:" + uriString);
-        }
-
-        /**
-         * Sets the username used for authentication.
-         *
-         * @param name authentication username of the profile
-         * @return this builder object
-         */
-        public Builder setAuthUserName(String name) {
-            mProfile.mAuthUserName = name;
-            return this;
-        }
-
-        /**
-         * Sets the name of the profile. This name is given by user.
-         *
-         * @param name name of the profile
-         * @return this builder object
-         */
-        public Builder setProfileName(String name) {
-            mProfile.mProfileName = name;
-            return this;
-        }
-
-        /**
-         * Sets the password of the SIP account
-         *
-         * @param password password of the SIP account
-         * @return this builder object
-         */
-        public Builder setPassword(String password) {
-            mUri.setUserPassword(password);
-            return this;
-        }
-
-        /**
-         * Sets the port number of the server. By default, it is 5060.
-         *
-         * @param port port number of the server
-         * @return this builder object
-         * @throws IllegalArgumentException if the port number is out of range
-         */
-        public Builder setPort(int port) throws IllegalArgumentException {
-            if ((port > 65535) || (port < 1000)) {
-                throw new IllegalArgumentException("incorrect port arugment: " + port);
-            }
-            mProfile.mPort = port;
-            return this;
-        }
-
-        /**
-         * Sets the protocol used to connect to the SIP server. Currently,
-         * only "UDP" and "TCP" are supported.
-         *
-         * @param protocol the protocol string
-         * @return this builder object
-         * @throws IllegalArgumentException if the protocol is not recognized
-         */
-        public Builder setProtocol(String protocol)
-                throws IllegalArgumentException {
-            if (protocol == null) {
-                throw new NullPointerException("protocol cannot be null");
-            }
-            protocol = protocol.toUpperCase();
-            if (!protocol.equals(UDP) && !protocol.equals(TCP)) {
-                throw new IllegalArgumentException(
-                        "unsupported protocol: " + protocol);
-            }
-            mProfile.mProtocol = protocol;
-            return this;
-        }
-
-        /**
-         * Sets the outbound proxy of the SIP server.
-         *
-         * @param outboundProxy the network address of the outbound proxy
-         * @return this builder object
-         */
-        public Builder setOutboundProxy(String outboundProxy) {
-            mProxyAddress = outboundProxy;
-            return this;
-        }
-
-        /**
-         * Sets the display name of the user.
-         *
-         * @param displayName display name of the user
-         * @return this builder object
-         */
-        public Builder setDisplayName(String displayName) {
-            mDisplayName = displayName;
-            return this;
-        }
-
-        /**
-         * Sets the send keep-alive flag.
-         *
-         * @param flag true if sending keep-alive message is required,
-         *      false otherwise
-         * @return this builder object
-         */
-        public Builder setSendKeepAlive(boolean flag) {
-            mProfile.mSendKeepAlive = flag;
-            return this;
-        }
-
-
-        /**
-         * Sets the auto. registration flag.
-         *
-         * @param flag true if the profile will be registered automatically,
-         *      false otherwise
-         * @return this builder object
-         */
-        public Builder setAutoRegistration(boolean flag) {
-            mProfile.mAutoRegistration = flag;
-            return this;
-        }
-
-        /**
-         * Builds and returns the SIP profile object.
-         *
-         * @return the profile object created
-         */
-        public SipProfile build() {
-            // remove password from URI
-            mProfile.mPassword = mUri.getUserPassword();
-            mUri.setUserPassword(null);
-            try {
-                if (!TextUtils.isEmpty(mProxyAddress)) {
-                    SipURI uri = (SipURI)
-                            mAddressFactory.createURI(fix(mProxyAddress));
-                    mProfile.mProxyAddress = uri.getHost();
-                } else {
-                    if (!mProfile.mProtocol.equals(UDP)) {
-                        mUri.setTransportParam(mProfile.mProtocol);
-                    }
-                    if (mProfile.mPort != DEFAULT_PORT) {
-                        mUri.setPort(mProfile.mPort);
-                    }
-                }
-                mProfile.mAddress = mAddressFactory.createAddress(
-                        mDisplayName, mUri);
-            } catch (InvalidArgumentException e) {
-                throw new RuntimeException(e);
-            } catch (ParseException e) {
-                // must not occur
-                throw new RuntimeException(e);
-            }
-            return mProfile;
-        }
-    }
-
-    private SipProfile() {
-    }
-
-    private SipProfile(Parcel in) {
-        mAddress = (Address) in.readSerializable();
-        mProxyAddress = in.readString();
-        mPassword = in.readString();
-        mDomain = in.readString();
-        mProtocol = in.readString();
-        mProfileName = in.readString();
-        mSendKeepAlive = (in.readInt() == 0) ? false : true;
-        mAutoRegistration = (in.readInt() == 0) ? false : true;
-        mCallingUid = in.readInt();
-        mPort = in.readInt();
-        mAuthUserName = in.readString();
-    }
-
-    @Override
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeSerializable(mAddress);
-        out.writeString(mProxyAddress);
-        out.writeString(mPassword);
-        out.writeString(mDomain);
-        out.writeString(mProtocol);
-        out.writeString(mProfileName);
-        out.writeInt(mSendKeepAlive ? 1 : 0);
-        out.writeInt(mAutoRegistration ? 1 : 0);
-        out.writeInt(mCallingUid);
-        out.writeInt(mPort);
-        out.writeString(mAuthUserName);
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    /**
-     * Gets the SIP URI of this profile.
-     *
-     * @return the SIP URI of this profile
-     * @hide
-     */
-    public SipURI getUri() {
-        return (SipURI) mAddress.getURI();
-    }
-
-    /**
-     * Gets the SIP URI string of this profile.
-     *
-     * @return the SIP URI string of this profile
-     */
-    public String getUriString() {
-        // We need to return the sip uri domain instead of
-        // the SIP URI with transport, port information if
-        // the outbound proxy address exists.
-        if (!TextUtils.isEmpty(mProxyAddress)) {
-            return "sip:" + getUserName() + "@" + mDomain;
-        }
-        return getUri().toString();
-    }
-
-    /**
-     * Gets the SIP address of this profile.
-     *
-     * @return the SIP address of this profile
-     * @hide
-     */
-    public Address getSipAddress() {
-        return mAddress;
-    }
-
-    /**
-     * Gets the display name of the user.
-     *
-     * @return the display name of the user
-     */
-    public String getDisplayName() {
-        return mAddress.getDisplayName();
-    }
-
-    /**
-     * Gets the username.
-     *
-     * @return the username
-     */
-    public String getUserName() {
-        return getUri().getUser();
-    }
-
-    /**
-     * Gets the username for authentication. If it is null, then the username
-     * is used in authentication instead.
-     *
-     * @return the authentication username
-     * @see #getUserName
-     */
-    public String getAuthUserName() {
-        return mAuthUserName;
-    }
-
-    /**
-     * Gets the password.
-     *
-     * @return the password
-     */
-    public String getPassword() {
-        return mPassword;
-    }
-
-    /**
-     * Gets the SIP domain.
-     *
-     * @return the SIP domain
-     */
-    public String getSipDomain() {
-        return mDomain;
-    }
-
-    /**
-     * Gets the port number of the SIP server.
-     *
-     * @return the port number of the SIP server
-     */
-    public int getPort() {
-        return mPort;
-    }
-
-    /**
-     * Gets the protocol used to connect to the server.
-     *
-     * @return the protocol
-     */
-    public String getProtocol() {
-        return mProtocol;
-    }
-
-    /**
-     * Gets the network address of the server outbound proxy.
-     *
-     * @return the network address of the server outbound proxy
-     */
-    public String getProxyAddress() {
-        return mProxyAddress;
-    }
-
-    /**
-     * Gets the (user-defined) name of the profile.
-     *
-     * @return name of the profile
-     */
-    public String getProfileName() {
-        return mProfileName;
-    }
-
-    /**
-     * Gets the flag of 'Sending keep-alive'.
-     *
-     * @return the flag of sending SIP keep-alive messages.
-     */
-    public boolean getSendKeepAlive() {
-        return mSendKeepAlive;
-    }
-
-    /**
-     * Gets the flag of 'Auto Registration'.
-     *
-     * @return the flag of registering the profile automatically.
-     */
-    public boolean getAutoRegistration() {
-        return mAutoRegistration;
-    }
-
-    /**
-     * Sets the calling process's Uid in the sip service.
-     * @hide
-     */
-    public void setCallingUid(int uid) {
-        mCallingUid = uid;
-    }
-
-    /**
-     * Gets the calling process's Uid in the sip settings.
-     * @hide
-     */
-    public int getCallingUid() {
-        return mCallingUid;
-    }
-
-    private Object readResolve() throws ObjectStreamException {
-        // For compatibility.
-        if (mPort == 0) mPort = DEFAULT_PORT;
-        return this;
-    }
-}
diff --git a/voip/java/android/net/sip/SipRegistrationListener.java b/voip/java/android/net/sip/SipRegistrationListener.java
deleted file mode 100644
index 9968cc7..0000000
--- a/voip/java/android/net/sip/SipRegistrationListener.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-package android.net.sip;
-
-/**
- * Listener for SIP registration events.
- */
-public interface SipRegistrationListener {
-    /**
-     * Called when a registration request is sent.
-     *
-     * @param localProfileUri the URI string of the SIP profile to register with
-     */
-    void onRegistering(String localProfileUri);
-
-    /**
-     * Called when the registration succeeded.
-     *
-     * @param localProfileUri the URI string of the SIP profile to register with
-     * @param expiryTime duration in seconds before the registration expires
-     */
-    void onRegistrationDone(String localProfileUri, long expiryTime);
-
-    /**
-     * Called when the registration failed.
-     *
-     * @param localProfileUri the URI string of the SIP profile to register with
-     * @param errorCode error code of this error
-     * @param errorMessage error message
-     * @see SipErrorCode
-     */
-    void onRegistrationFailed(String localProfileUri, int errorCode,
-            String errorMessage);
-}
diff --git a/voip/java/android/net/sip/SipSession.java b/voip/java/android/net/sip/SipSession.java
deleted file mode 100644
index edbc66f..0000000
--- a/voip/java/android/net/sip/SipSession.java
+++ /dev/null
@@ -1,574 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-package android.net.sip;
-
-import android.os.RemoteException;
-import android.telephony.Rlog;
-
-/**
- * Represents a SIP session that is associated with a SIP dialog or a standalone
- * transaction not within a dialog.
- * <p>You can get a {@link SipSession} from {@link SipManager} with {@link
- * SipManager#createSipSession createSipSession()} (when initiating calls) or {@link
- * SipManager#getSessionFor getSessionFor()} (when receiving calls).</p>
- */
-public final class SipSession {
-    private static final String TAG = "SipSession";
-
-    /**
-     * Defines SIP session states, such as "registering", "outgoing call", and "in call".
-     */
-    public static class State {
-        /** When session is ready to initiate a call or transaction. */
-        public static final int READY_TO_CALL = 0;
-
-        /** When the registration request is sent out. */
-        public static final int REGISTERING = 1;
-
-        /** When the unregistration request is sent out. */
-        public static final int DEREGISTERING = 2;
-
-        /** When an INVITE request is received. */
-        public static final int INCOMING_CALL = 3;
-
-        /** When an OK response is sent for the INVITE request received. */
-        public static final int INCOMING_CALL_ANSWERING = 4;
-
-        /** When an INVITE request is sent. */
-        public static final int OUTGOING_CALL = 5;
-
-        /** When a RINGING response is received for the INVITE request sent. */
-        public static final int OUTGOING_CALL_RING_BACK = 6;
-
-        /** When a CANCEL request is sent for the INVITE request sent. */
-        public static final int OUTGOING_CALL_CANCELING = 7;
-
-        /** When a call is established. */
-        public static final int IN_CALL = 8;
-
-        /** When an OPTIONS request is sent. */
-        public static final int PINGING = 9;
-
-        /** When ending a call. @hide */
-        public static final int ENDING_CALL = 10;
-
-        /** Not defined. */
-        public static final int NOT_DEFINED = 101;
-
-        /**
-         * Converts the state to string.
-         */
-        public static String toString(int state) {
-            switch (state) {
-                case READY_TO_CALL:
-                    return "READY_TO_CALL";
-                case REGISTERING:
-                    return "REGISTERING";
-                case DEREGISTERING:
-                    return "DEREGISTERING";
-                case INCOMING_CALL:
-                    return "INCOMING_CALL";
-                case INCOMING_CALL_ANSWERING:
-                    return "INCOMING_CALL_ANSWERING";
-                case OUTGOING_CALL:
-                    return "OUTGOING_CALL";
-                case OUTGOING_CALL_RING_BACK:
-                    return "OUTGOING_CALL_RING_BACK";
-                case OUTGOING_CALL_CANCELING:
-                    return "OUTGOING_CALL_CANCELING";
-                case IN_CALL:
-                    return "IN_CALL";
-                case PINGING:
-                    return "PINGING";
-                default:
-                    return "NOT_DEFINED";
-            }
-        }
-
-        private State() {
-        }
-    }
-
-    /**
-     * Listener for events relating to a SIP session, such as when a session is being registered
-     * ("on registering") or a call is outgoing ("on calling").
-     * <p>Many of these events are also received by {@link SipAudioCall.Listener}.</p>
-     */
-    public static class Listener {
-        /**
-         * Called when an INVITE request is sent to initiate a new call.
-         *
-         * @param session the session object that carries out the transaction
-         */
-        public void onCalling(SipSession session) {
-        }
-
-        /**
-         * Called when an INVITE request is received.
-         *
-         * @param session the session object that carries out the transaction
-         * @param caller the SIP profile of the caller
-         * @param sessionDescription the caller's session description
-         */
-        public void onRinging(SipSession session, SipProfile caller,
-                String sessionDescription) {
-        }
-
-        /**
-         * Called when a RINGING response is received for the INVITE request sent
-         *
-         * @param session the session object that carries out the transaction
-         */
-        public void onRingingBack(SipSession session) {
-        }
-
-        /**
-         * Called when the session is established.
-         *
-         * @param session the session object that is associated with the dialog
-         * @param sessionDescription the peer's session description
-         */
-        public void onCallEstablished(SipSession session,
-                String sessionDescription) {
-        }
-
-        /**
-         * Called when the session is terminated.
-         *
-         * @param session the session object that is associated with the dialog
-         */
-        public void onCallEnded(SipSession session) {
-        }
-
-        /**
-         * Called when the peer is busy during session initialization.
-         *
-         * @param session the session object that carries out the transaction
-         */
-        public void onCallBusy(SipSession session) {
-        }
-
-        /**
-         * Called when the call is being transferred to a new one.
-         *
-         * @hide
-         * @param newSession the new session that the call will be transferred to
-         * @param sessionDescription the new peer's session description
-         */
-        public void onCallTransferring(SipSession newSession,
-                String sessionDescription) {
-        }
-
-        /**
-         * Called when an error occurs during session initialization and
-         * termination.
-         *
-         * @param session the session object that carries out the transaction
-         * @param errorCode error code defined in {@link SipErrorCode}
-         * @param errorMessage error message
-         */
-        public void onError(SipSession session, int errorCode,
-                String errorMessage) {
-        }
-
-        /**
-         * Called when an error occurs during session modification negotiation.
-         *
-         * @param session the session object that carries out the transaction
-         * @param errorCode error code defined in {@link SipErrorCode}
-         * @param errorMessage error message
-         */
-        public void onCallChangeFailed(SipSession session, int errorCode,
-                String errorMessage) {
-        }
-
-        /**
-         * Called when a registration request is sent.
-         *
-         * @param session the session object that carries out the transaction
-         */
-        public void onRegistering(SipSession session) {
-        }
-
-        /**
-         * Called when registration is successfully done.
-         *
-         * @param session the session object that carries out the transaction
-         * @param duration duration in second before the registration expires
-         */
-        public void onRegistrationDone(SipSession session, int duration) {
-        }
-
-        /**
-         * Called when the registration fails.
-         *
-         * @param session the session object that carries out the transaction
-         * @param errorCode error code defined in {@link SipErrorCode}
-         * @param errorMessage error message
-         */
-        public void onRegistrationFailed(SipSession session, int errorCode,
-                String errorMessage) {
-        }
-
-        /**
-         * Called when the registration gets timed out.
-         *
-         * @param session the session object that carries out the transaction
-         */
-        public void onRegistrationTimeout(SipSession session) {
-        }
-    }
-
-    private final ISipSession mSession;
-    private Listener mListener;
-
-    SipSession(ISipSession realSession) {
-        mSession = realSession;
-        if (realSession != null) {
-            try {
-                realSession.setListener(createListener());
-            } catch (RemoteException e) {
-                loge("SipSession.setListener:", e);
-            }
-        }
-    }
-
-    SipSession(ISipSession realSession, Listener listener) {
-        this(realSession);
-        setListener(listener);
-    }
-
-    /**
-     * Gets the IP address of the local host on which this SIP session runs.
-     *
-     * @return the IP address of the local host
-     */
-    public String getLocalIp() {
-        try {
-            return mSession.getLocalIp();
-        } catch (RemoteException e) {
-            loge("getLocalIp:", e);
-            return "127.0.0.1";
-        }
-    }
-
-    /**
-     * Gets the SIP profile that this session is associated with.
-     *
-     * @return the SIP profile that this session is associated with
-     */
-    public SipProfile getLocalProfile() {
-        try {
-            return mSession.getLocalProfile();
-        } catch (RemoteException e) {
-            loge("getLocalProfile:", e);
-            return null;
-        }
-    }
-
-    /**
-     * Gets the SIP profile that this session is connected to. Only available
-     * when the session is associated with a SIP dialog.
-     *
-     * @return the SIP profile that this session is connected to
-     */
-    public SipProfile getPeerProfile() {
-        try {
-            return mSession.getPeerProfile();
-        } catch (RemoteException e) {
-            loge("getPeerProfile:", e);
-            return null;
-        }
-    }
-
-    /**
-     * Gets the session state. The value returned must be one of the states in
-     * {@link State}.
-     *
-     * @return the session state
-     */
-    public int getState() {
-        try {
-            return mSession.getState();
-        } catch (RemoteException e) {
-            loge("getState:", e);
-            return State.NOT_DEFINED;
-        }
-    }
-
-    /**
-     * Checks if the session is in a call.
-     *
-     * @return true if the session is in a call
-     */
-    public boolean isInCall() {
-        try {
-            return mSession.isInCall();
-        } catch (RemoteException e) {
-            loge("isInCall:", e);
-            return false;
-        }
-    }
-
-    /**
-     * Gets the call ID of the session.
-     *
-     * @return the call ID
-     */
-    public String getCallId() {
-        try {
-            return mSession.getCallId();
-        } catch (RemoteException e) {
-            loge("getCallId:", e);
-            return null;
-        }
-    }
-
-
-    /**
-     * Sets the listener to listen to the session events. A {@code SipSession}
-     * can only hold one listener at a time. Subsequent calls to this method
-     * override the previous listener.
-     *
-     * @param listener to listen to the session events of this object
-     */
-    public void setListener(Listener listener) {
-        mListener = listener;
-    }
-
-
-    /**
-     * Performs registration to the server specified by the associated local
-     * profile. The session listener is called back upon success or failure of
-     * registration. The method is only valid to call when the session state is
-     * in {@link State#READY_TO_CALL}.
-     *
-     * @param duration duration in second before the registration expires
-     * @see Listener
-     */
-    public void register(int duration) {
-        try {
-            mSession.register(duration);
-        } catch (RemoteException e) {
-            loge("register:", e);
-        }
-    }
-
-    /**
-     * Performs unregistration to the server specified by the associated local
-     * profile. Unregistration is technically the same as registration with zero
-     * expiration duration. The session listener is called back upon success or
-     * failure of unregistration. The method is only valid to call when the
-     * session state is in {@link State#READY_TO_CALL}.
-     *
-     * @see Listener
-     */
-    public void unregister() {
-        try {
-            mSession.unregister();
-        } catch (RemoteException e) {
-            loge("unregister:", e);
-        }
-    }
-
-    /**
-     * Initiates a call to the specified profile. The session listener is called
-     * back upon defined session events. The method is only valid to call when
-     * the session state is in {@link State#READY_TO_CALL}.
-     *
-     * @param callee the SIP profile to make the call to
-     * @param sessionDescription the session description of this call
-     * @param timeout the session will be timed out if the call is not
-     *        established within {@code timeout} seconds. Default value (defined
-     *        by SIP protocol) is used if {@code timeout} is zero or negative.
-     * @see Listener
-     */
-    public void makeCall(SipProfile callee, String sessionDescription,
-            int timeout) {
-        try {
-            mSession.makeCall(callee, sessionDescription, timeout);
-        } catch (RemoteException e) {
-            loge("makeCall:", e);
-        }
-    }
-
-    /**
-     * Answers an incoming call with the specified session description. The
-     * method is only valid to call when the session state is in
-     * {@link State#INCOMING_CALL}.
-     *
-     * @param sessionDescription the session description to answer this call
-     * @param timeout the session will be timed out if the call is not
-     *        established within {@code timeout} seconds. Default value (defined
-     *        by SIP protocol) is used if {@code timeout} is zero or negative.
-     */
-    public void answerCall(String sessionDescription, int timeout) {
-        try {
-            mSession.answerCall(sessionDescription, timeout);
-        } catch (RemoteException e) {
-            loge("answerCall:", e);
-        }
-    }
-
-    /**
-     * Ends an established call, terminates an outgoing call or rejects an
-     * incoming call. The method is only valid to call when the session state is
-     * in {@link State#IN_CALL},
-     * {@link State#INCOMING_CALL},
-     * {@link State#OUTGOING_CALL} or
-     * {@link State#OUTGOING_CALL_RING_BACK}.
-     */
-    public void endCall() {
-        try {
-            mSession.endCall();
-        } catch (RemoteException e) {
-            loge("endCall:", e);
-        }
-    }
-
-    /**
-     * Changes the session description during a call. The method is only valid
-     * to call when the session state is in {@link State#IN_CALL}.
-     *
-     * @param sessionDescription the new session description
-     * @param timeout the session will be timed out if the call is not
-     *        established within {@code timeout} seconds. Default value (defined
-     *        by SIP protocol) is used if {@code timeout} is zero or negative.
-     */
-    public void changeCall(String sessionDescription, int timeout) {
-        try {
-            mSession.changeCall(sessionDescription, timeout);
-        } catch (RemoteException e) {
-            loge("changeCall:", e);
-        }
-    }
-
-    ISipSession getRealSession() {
-        return mSession;
-    }
-
-    private ISipSessionListener createListener() {
-        return new ISipSessionListener.Stub() {
-            @Override
-            public void onCalling(ISipSession session) {
-                if (mListener != null) {
-                    mListener.onCalling(SipSession.this);
-                }
-            }
-
-            @Override
-            public void onRinging(ISipSession session, SipProfile caller,
-                    String sessionDescription) {
-                if (mListener != null) {
-                    mListener.onRinging(SipSession.this, caller,
-                            sessionDescription);
-                }
-            }
-
-            @Override
-            public void onRingingBack(ISipSession session) {
-                if (mListener != null) {
-                    mListener.onRingingBack(SipSession.this);
-                }
-            }
-
-            @Override
-            public void onCallEstablished(ISipSession session,
-                    String sessionDescription) {
-                if (mListener != null) {
-                    mListener.onCallEstablished(SipSession.this,
-                            sessionDescription);
-                }
-            }
-
-            @Override
-            public void onCallEnded(ISipSession session) {
-                if (mListener != null) {
-                    mListener.onCallEnded(SipSession.this);
-                }
-            }
-
-            @Override
-            public void onCallBusy(ISipSession session) {
-                if (mListener != null) {
-                    mListener.onCallBusy(SipSession.this);
-                }
-            }
-
-            @Override
-            public void onCallTransferring(ISipSession session,
-                    String sessionDescription) {
-                if (mListener != null) {
-                    mListener.onCallTransferring(
-                            new SipSession(session, SipSession.this.mListener),
-                            sessionDescription);
-
-                }
-            }
-
-            @Override
-            public void onCallChangeFailed(ISipSession session, int errorCode,
-                    String message) {
-                if (mListener != null) {
-                    mListener.onCallChangeFailed(SipSession.this, errorCode,
-                            message);
-                }
-            }
-
-            @Override
-            public void onError(ISipSession session, int errorCode, String message) {
-                if (mListener != null) {
-                    mListener.onError(SipSession.this, errorCode, message);
-                }
-            }
-
-            @Override
-            public void onRegistering(ISipSession session) {
-                if (mListener != null) {
-                    mListener.onRegistering(SipSession.this);
-                }
-            }
-
-            @Override
-            public void onRegistrationDone(ISipSession session, int duration) {
-                if (mListener != null) {
-                    mListener.onRegistrationDone(SipSession.this, duration);
-                }
-            }
-
-            @Override
-            public void onRegistrationFailed(ISipSession session, int errorCode,
-                    String message) {
-                if (mListener != null) {
-                    mListener.onRegistrationFailed(SipSession.this, errorCode,
-                            message);
-                }
-            }
-
-            @Override
-            public void onRegistrationTimeout(ISipSession session) {
-                if (mListener != null) {
-                    mListener.onRegistrationTimeout(SipSession.this);
-                }
-            }
-        };
-    }
-
-    private void loge(String s, Throwable t) {
-        Rlog.e(TAG, s, t);
-    }
-}
diff --git a/voip/java/android/net/sip/SipSessionAdapter.java b/voip/java/android/net/sip/SipSessionAdapter.java
deleted file mode 100644
index f538983..0000000
--- a/voip/java/android/net/sip/SipSessionAdapter.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-package android.net.sip;
-
-/**
- * Adapter class for {@link ISipSessionListener}. Default implementation of all
- * callback methods is no-op.
- * @hide
- */
-public class SipSessionAdapter extends ISipSessionListener.Stub {
-    public void onCalling(ISipSession session) {
-    }
-
-    public void onRinging(ISipSession session, SipProfile caller,
-            String sessionDescription) {
-    }
-
-    public void onRingingBack(ISipSession session) {
-    }
-
-    public void onCallEstablished(ISipSession session,
-            String sessionDescription) {
-    }
-
-    public void onCallEnded(ISipSession session) {
-    }
-
-    public void onCallBusy(ISipSession session) {
-    }
-
-    public void onCallTransferring(ISipSession session,
-            String sessionDescription) {
-    }
-
-    public void onCallChangeFailed(ISipSession session, int errorCode,
-            String message) {
-    }
-
-    public void onError(ISipSession session, int errorCode, String message) {
-    }
-
-    public void onRegistering(ISipSession session) {
-    }
-
-    public void onRegistrationDone(ISipSession session, int duration) {
-    }
-
-    public void onRegistrationFailed(ISipSession session, int errorCode,
-            String message) {
-    }
-
-    public void onRegistrationTimeout(ISipSession session) {
-    }
-}
diff --git a/voip/java/android/net/sip/package.html b/voip/java/android/net/sip/package.html
deleted file mode 100644
index 3c4cc23..0000000
--- a/voip/java/android/net/sip/package.html
+++ /dev/null
@@ -1,45 +0,0 @@
-<HTML>
-<BODY>
-<p>Provides access to Session Initiation Protocol (SIP) functionality, such as
-making and answering VOIP calls using SIP.</p>
-
-<p>For more information, see the
-<a href="{@docRoot}guide/topics/connectivity/sip.html">Session Initiation Protocol</a>
-developer guide.</p>
-{@more}
-
-<p>To get started, you need to get an instance of the {@link android.net.sip.SipManager} by
-calling {@link android.net.sip.SipManager#newInstance newInstance()}.</p>
-
-<p>With the {@link android.net.sip.SipManager}, you can initiate SIP audio calls with {@link
-android.net.sip.SipManager#makeAudioCall makeAudioCall()} and {@link
-android.net.sip.SipManager#takeAudioCall takeAudioCall()}. Both methods require
-a {@link android.net.sip.SipAudioCall.Listener} that receives callbacks when the state of the
-call changes, such as when the call is ringing, established, or ended.</p>
-
-<p>Both {@link android.net.sip.SipManager#makeAudioCall makeAudioCall()} also requires two
-{@link android.net.sip.SipProfile} objects, representing the local device and the peer
-device. You can create a {@link android.net.sip.SipProfile} using the {@link
-android.net.sip.SipProfile.Builder} subclass.</p>
-
-<p>Once you have a {@link android.net.sip.SipAudioCall}, you can perform SIP audio call actions with
-the instance, such as make a call, answer a call, mute a call, turn on speaker mode, send DTMF
-tones, and more.</p>
-
-<p>If you want to create generic SIP connections (such as for video calls or other), you can
-create a SIP connection from the {@link android.net.sip.SipManager}, using {@link
-android.net.sip.SipManager#open open()}. If you only want to create audio SIP calls, though, you
-should use the {@link android.net.sip.SipAudioCall} class, as described above.</p>
-
-<p class="note"><strong>Note:</strong>
-Not all Android-powered devices support VOIP functionality with SIP. Before performing any SIP
-activity, you should call {@link android.net.sip.SipManager#isVoipSupported isVoipSupported()}
-to verify that the device supports VOIP calling and {@link
-android.net.sip.SipManager#isApiSupported isApiSupported()} to verify that the device supports the
-SIP APIs.
-Your application must also request the {@link android.Manifest.permission#INTERNET} and {@link
-android.Manifest.permission#USE_SIP} permissions in order to use the SIP APIs.
-</p>
-
-</BODY>
-</HTML>
\ No newline at end of file
diff --git a/voip/java/com/android/server/sip/SipHelper.java b/voip/java/com/android/server/sip/SipHelper.java
deleted file mode 100644
index c708be8..0000000
--- a/voip/java/com/android/server/sip/SipHelper.java
+++ /dev/null
@@ -1,537 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-package com.android.server.sip;
-
-import gov.nist.javax.sip.SipStackExt;
-import gov.nist.javax.sip.clientauthutils.AccountManager;
-import gov.nist.javax.sip.clientauthutils.AuthenticationHelper;
-import gov.nist.javax.sip.header.extensions.ReferencesHeader;
-import gov.nist.javax.sip.header.extensions.ReferredByHeader;
-import gov.nist.javax.sip.header.extensions.ReplacesHeader;
-
-import android.net.sip.SipProfile;
-import android.telephony.Rlog;
-
-import java.text.ParseException;
-import java.util.ArrayList;
-import java.util.EventObject;
-import java.util.List;
-import java.util.regex.Pattern;
-
-import javax.sip.ClientTransaction;
-import javax.sip.Dialog;
-import javax.sip.DialogTerminatedEvent;
-import javax.sip.InvalidArgumentException;
-import javax.sip.ListeningPoint;
-import javax.sip.PeerUnavailableException;
-import javax.sip.RequestEvent;
-import javax.sip.ResponseEvent;
-import javax.sip.ServerTransaction;
-import javax.sip.SipException;
-import javax.sip.SipFactory;
-import javax.sip.SipProvider;
-import javax.sip.SipStack;
-import javax.sip.Transaction;
-import javax.sip.TransactionTerminatedEvent;
-import javax.sip.TransactionState;
-import javax.sip.address.Address;
-import javax.sip.address.AddressFactory;
-import javax.sip.address.SipURI;
-import javax.sip.header.CSeqHeader;
-import javax.sip.header.CallIdHeader;
-import javax.sip.header.ContactHeader;
-import javax.sip.header.FromHeader;
-import javax.sip.header.Header;
-import javax.sip.header.HeaderFactory;
-import javax.sip.header.MaxForwardsHeader;
-import javax.sip.header.ToHeader;
-import javax.sip.header.ViaHeader;
-import javax.sip.message.Message;
-import javax.sip.message.MessageFactory;
-import javax.sip.message.Request;
-import javax.sip.message.Response;
-
-/**
- * Helper class for holding SIP stack related classes and for various low-level
- * SIP tasks like sending messages.
- */
-class SipHelper {
-    private static final String TAG = SipHelper.class.getSimpleName();
-    private static final boolean DBG = false;
-    private static final boolean DBG_PING = false;
-
-    private SipStack mSipStack;
-    private SipProvider mSipProvider;
-    private AddressFactory mAddressFactory;
-    private HeaderFactory mHeaderFactory;
-    private MessageFactory mMessageFactory;
-
-    public SipHelper(SipStack sipStack, SipProvider sipProvider)
-            throws PeerUnavailableException {
-        mSipStack = sipStack;
-        mSipProvider = sipProvider;
-
-        SipFactory sipFactory = SipFactory.getInstance();
-        mAddressFactory = sipFactory.createAddressFactory();
-        mHeaderFactory = sipFactory.createHeaderFactory();
-        mMessageFactory = sipFactory.createMessageFactory();
-    }
-
-    private FromHeader createFromHeader(SipProfile profile, String tag)
-            throws ParseException {
-        return mHeaderFactory.createFromHeader(profile.getSipAddress(), tag);
-    }
-
-    private ToHeader createToHeader(SipProfile profile) throws ParseException {
-        return createToHeader(profile, null);
-    }
-
-    private ToHeader createToHeader(SipProfile profile, String tag)
-            throws ParseException {
-        return mHeaderFactory.createToHeader(profile.getSipAddress(), tag);
-    }
-
-    private CallIdHeader createCallIdHeader() {
-        return mSipProvider.getNewCallId();
-    }
-
-    private CSeqHeader createCSeqHeader(String method)
-            throws ParseException, InvalidArgumentException {
-        long sequence = (long) (Math.random() * 10000);
-        return mHeaderFactory.createCSeqHeader(sequence, method);
-    }
-
-    private MaxForwardsHeader createMaxForwardsHeader()
-            throws InvalidArgumentException {
-        return mHeaderFactory.createMaxForwardsHeader(70);
-    }
-
-    private MaxForwardsHeader createMaxForwardsHeader(int max)
-            throws InvalidArgumentException {
-        return mHeaderFactory.createMaxForwardsHeader(max);
-    }
-
-    private ListeningPoint getListeningPoint() throws SipException {
-        ListeningPoint lp = mSipProvider.getListeningPoint(ListeningPoint.UDP);
-        if (lp == null) lp = mSipProvider.getListeningPoint(ListeningPoint.TCP);
-        if (lp == null) {
-            ListeningPoint[] lps = mSipProvider.getListeningPoints();
-            if ((lps != null) && (lps.length > 0)) lp = lps[0];
-        }
-        if (lp == null) {
-            throw new SipException("no listening point is available");
-        }
-        return lp;
-    }
-
-    private List<ViaHeader> createViaHeaders()
-            throws ParseException, SipException {
-        List<ViaHeader> viaHeaders = new ArrayList<ViaHeader>(1);
-        ListeningPoint lp = getListeningPoint();
-        ViaHeader viaHeader = mHeaderFactory.createViaHeader(lp.getIPAddress(),
-                lp.getPort(), lp.getTransport(), null);
-        viaHeader.setRPort();
-        viaHeaders.add(viaHeader);
-        return viaHeaders;
-    }
-
-    private ContactHeader createContactHeader(SipProfile profile)
-            throws ParseException, SipException {
-        return createContactHeader(profile, null, 0);
-    }
-
-    private ContactHeader createContactHeader(SipProfile profile,
-            String ip, int port) throws ParseException,
-            SipException {
-        SipURI contactURI = (ip == null)
-                ? createSipUri(profile.getUserName(), profile.getProtocol(),
-                        getListeningPoint())
-                : createSipUri(profile.getUserName(), profile.getProtocol(),
-                        ip, port);
-
-        Address contactAddress = mAddressFactory.createAddress(contactURI);
-        contactAddress.setDisplayName(profile.getDisplayName());
-
-        return mHeaderFactory.createContactHeader(contactAddress);
-    }
-
-    private ContactHeader createWildcardContactHeader() {
-        ContactHeader contactHeader  = mHeaderFactory.createContactHeader();
-        contactHeader.setWildCard();
-        return contactHeader;
-    }
-
-    private SipURI createSipUri(String username, String transport,
-            ListeningPoint lp) throws ParseException {
-        return createSipUri(username, transport, lp.getIPAddress(), lp.getPort());
-    }
-
-    private SipURI createSipUri(String username, String transport,
-            String ip, int port) throws ParseException {
-        SipURI uri = mAddressFactory.createSipURI(username, ip);
-        try {
-            uri.setPort(port);
-            uri.setTransportParam(transport);
-        } catch (InvalidArgumentException e) {
-            throw new RuntimeException(e);
-        }
-        return uri;
-    }
-
-    public ClientTransaction sendOptions(SipProfile caller, SipProfile callee,
-            String tag) throws SipException {
-        try {
-            Request request = (caller == callee)
-                    ? createRequest(Request.OPTIONS, caller, tag)
-                    : createRequest(Request.OPTIONS, caller, callee, tag);
-
-            ClientTransaction clientTransaction =
-                    mSipProvider.getNewClientTransaction(request);
-            clientTransaction.sendRequest();
-            return clientTransaction;
-        } catch (Exception e) {
-            throw new SipException("sendOptions()", e);
-        }
-    }
-
-    public ClientTransaction sendRegister(SipProfile userProfile, String tag,
-            int expiry) throws SipException {
-        try {
-            Request request = createRequest(Request.REGISTER, userProfile, tag);
-            if (expiry == 0) {
-                // remove all previous registrations by wildcard
-                // rfc3261#section-10.2.2
-                request.addHeader(createWildcardContactHeader());
-            } else {
-                request.addHeader(createContactHeader(userProfile));
-            }
-            request.addHeader(mHeaderFactory.createExpiresHeader(expiry));
-
-            ClientTransaction clientTransaction =
-                    mSipProvider.getNewClientTransaction(request);
-            clientTransaction.sendRequest();
-            return clientTransaction;
-        } catch (ParseException e) {
-            throw new SipException("sendRegister()", e);
-        }
-    }
-
-    private Request createRequest(String requestType, SipProfile userProfile,
-            String tag) throws ParseException, SipException {
-        FromHeader fromHeader = createFromHeader(userProfile, tag);
-        ToHeader toHeader = createToHeader(userProfile);
-
-        String replaceStr = Pattern.quote(userProfile.getUserName() + "@");
-        SipURI requestURI = mAddressFactory.createSipURI(
-                userProfile.getUriString().replaceFirst(replaceStr, ""));
-
-        List<ViaHeader> viaHeaders = createViaHeaders();
-        CallIdHeader callIdHeader = createCallIdHeader();
-        CSeqHeader cSeqHeader = createCSeqHeader(requestType);
-        MaxForwardsHeader maxForwards = createMaxForwardsHeader();
-        Request request = mMessageFactory.createRequest(requestURI,
-                requestType, callIdHeader, cSeqHeader, fromHeader,
-                toHeader, viaHeaders, maxForwards);
-        Header userAgentHeader = mHeaderFactory.createHeader("User-Agent",
-                "SIPAUA/0.1.001");
-        request.addHeader(userAgentHeader);
-        return request;
-    }
-
-    public ClientTransaction handleChallenge(ResponseEvent responseEvent,
-            AccountManager accountManager) throws SipException {
-        AuthenticationHelper authenticationHelper =
-                ((SipStackExt) mSipStack).getAuthenticationHelper(
-                        accountManager, mHeaderFactory);
-        ClientTransaction tid = responseEvent.getClientTransaction();
-        ClientTransaction ct = authenticationHelper.handleChallenge(
-                responseEvent.getResponse(), tid, mSipProvider, 5);
-        if (DBG) log("send request with challenge response: "
-                + ct.getRequest());
-        ct.sendRequest();
-        return ct;
-    }
-
-    private Request createRequest(String requestType, SipProfile caller,
-            SipProfile callee, String tag) throws ParseException, SipException {
-        FromHeader fromHeader = createFromHeader(caller, tag);
-        ToHeader toHeader = createToHeader(callee);
-        SipURI requestURI = callee.getUri();
-        List<ViaHeader> viaHeaders = createViaHeaders();
-        CallIdHeader callIdHeader = createCallIdHeader();
-        CSeqHeader cSeqHeader = createCSeqHeader(requestType);
-        MaxForwardsHeader maxForwards = createMaxForwardsHeader();
-
-        Request request = mMessageFactory.createRequest(requestURI,
-                requestType, callIdHeader, cSeqHeader, fromHeader,
-                toHeader, viaHeaders, maxForwards);
-
-        request.addHeader(createContactHeader(caller));
-        return request;
-    }
-
-    public ClientTransaction sendInvite(SipProfile caller, SipProfile callee,
-            String sessionDescription, String tag, ReferredByHeader referredBy,
-            String replaces) throws SipException {
-        try {
-            Request request = createRequest(Request.INVITE, caller, callee, tag);
-            if (referredBy != null) request.addHeader(referredBy);
-            if (replaces != null) {
-                request.addHeader(mHeaderFactory.createHeader(
-                        ReplacesHeader.NAME, replaces));
-            }
-            request.setContent(sessionDescription,
-                    mHeaderFactory.createContentTypeHeader(
-                            "application", "sdp"));
-            ClientTransaction clientTransaction =
-                    mSipProvider.getNewClientTransaction(request);
-            if (DBG) log("send INVITE: " + request);
-            clientTransaction.sendRequest();
-            return clientTransaction;
-        } catch (ParseException e) {
-            throw new SipException("sendInvite()", e);
-        }
-    }
-
-    public ClientTransaction sendReinvite(Dialog dialog,
-            String sessionDescription) throws SipException {
-        try {
-            Request request = dialog.createRequest(Request.INVITE);
-            request.setContent(sessionDescription,
-                    mHeaderFactory.createContentTypeHeader(
-                            "application", "sdp"));
-
-            // Adding rport argument in the request could fix some SIP servers
-            // in resolving the initiator's NAT port mapping for relaying the
-            // response message from the other end.
-
-            ViaHeader viaHeader = (ViaHeader) request.getHeader(ViaHeader.NAME);
-            if (viaHeader != null) viaHeader.setRPort();
-
-            ClientTransaction clientTransaction =
-                    mSipProvider.getNewClientTransaction(request);
-            if (DBG) log("send RE-INVITE: " + request);
-            dialog.sendRequest(clientTransaction);
-            return clientTransaction;
-        } catch (ParseException e) {
-            throw new SipException("sendReinvite()", e);
-        }
-    }
-
-    public ServerTransaction getServerTransaction(RequestEvent event)
-            throws SipException {
-        ServerTransaction transaction = event.getServerTransaction();
-        if (transaction == null) {
-            Request request = event.getRequest();
-            return mSipProvider.getNewServerTransaction(request);
-        } else {
-            return transaction;
-        }
-    }
-
-    /**
-     * @param event the INVITE request event
-     */
-    public ServerTransaction sendRinging(RequestEvent event, String tag)
-            throws SipException {
-        try {
-            Request request = event.getRequest();
-            ServerTransaction transaction = getServerTransaction(event);
-
-            Response response = mMessageFactory.createResponse(Response.RINGING,
-                    request);
-
-            ToHeader toHeader = (ToHeader) response.getHeader(ToHeader.NAME);
-            toHeader.setTag(tag);
-            response.addHeader(toHeader);
-            if (DBG) log("send RINGING: " + response);
-            transaction.sendResponse(response);
-            return transaction;
-        } catch (ParseException e) {
-            throw new SipException("sendRinging()", e);
-        }
-    }
-
-    /**
-     * @param event the INVITE request event
-     */
-    public ServerTransaction sendInviteOk(RequestEvent event,
-            SipProfile localProfile, String sessionDescription,
-            ServerTransaction inviteTransaction, String externalIp,
-            int externalPort) throws SipException {
-        try {
-            Request request = event.getRequest();
-            Response response = mMessageFactory.createResponse(Response.OK,
-                    request);
-            response.addHeader(createContactHeader(localProfile, externalIp,
-                    externalPort));
-            response.setContent(sessionDescription,
-                    mHeaderFactory.createContentTypeHeader(
-                            "application", "sdp"));
-
-            if (inviteTransaction == null) {
-                inviteTransaction = getServerTransaction(event);
-            }
-
-            if (inviteTransaction.getState() != TransactionState.COMPLETED) {
-                if (DBG) log("send OK: " + response);
-                inviteTransaction.sendResponse(response);
-            }
-
-            return inviteTransaction;
-        } catch (ParseException e) {
-            throw new SipException("sendInviteOk()", e);
-        }
-    }
-
-    public void sendInviteBusyHere(RequestEvent event,
-            ServerTransaction inviteTransaction) throws SipException {
-        try {
-            Request request = event.getRequest();
-            Response response = mMessageFactory.createResponse(
-                    Response.BUSY_HERE, request);
-
-            if (inviteTransaction == null) {
-                inviteTransaction = getServerTransaction(event);
-            }
-
-            if (inviteTransaction.getState() != TransactionState.COMPLETED) {
-                if (DBG) log("send BUSY HERE: " + response);
-                inviteTransaction.sendResponse(response);
-            }
-        } catch (ParseException e) {
-            throw new SipException("sendInviteBusyHere()", e);
-        }
-    }
-
-    /**
-     * @param event the INVITE ACK request event
-     */
-    public void sendInviteAck(ResponseEvent event, Dialog dialog)
-            throws SipException {
-        Response response = event.getResponse();
-        long cseq = ((CSeqHeader) response.getHeader(CSeqHeader.NAME))
-                .getSeqNumber();
-        Request ack = dialog.createAck(cseq);
-        if (DBG) log("send ACK: " + ack);
-        dialog.sendAck(ack);
-    }
-
-    public void sendBye(Dialog dialog) throws SipException {
-        Request byeRequest = dialog.createRequest(Request.BYE);
-        if (DBG) log("send BYE: " + byeRequest);
-        dialog.sendRequest(mSipProvider.getNewClientTransaction(byeRequest));
-    }
-
-    public void sendCancel(ClientTransaction inviteTransaction)
-            throws SipException {
-        Request cancelRequest = inviteTransaction.createCancel();
-        if (DBG) log("send CANCEL: " + cancelRequest);
-        mSipProvider.getNewClientTransaction(cancelRequest).sendRequest();
-    }
-
-    public void sendResponse(RequestEvent event, int responseCode)
-            throws SipException {
-        try {
-            Request request = event.getRequest();
-            Response response = mMessageFactory.createResponse(
-                    responseCode, request);
-            if (DBG && (!Request.OPTIONS.equals(request.getMethod())
-                    || DBG_PING)) {
-                log("send response: " + response);
-            }
-            getServerTransaction(event).sendResponse(response);
-        } catch (ParseException e) {
-            throw new SipException("sendResponse()", e);
-        }
-    }
-
-    public void sendReferNotify(Dialog dialog, String content)
-            throws SipException {
-        try {
-            Request request = dialog.createRequest(Request.NOTIFY);
-            request.addHeader(mHeaderFactory.createSubscriptionStateHeader(
-                    "active;expires=60"));
-            // set content here
-            request.setContent(content,
-                    mHeaderFactory.createContentTypeHeader(
-                            "message", "sipfrag"));
-            request.addHeader(mHeaderFactory.createEventHeader(
-                    ReferencesHeader.REFER));
-            if (DBG) log("send NOTIFY: " + request);
-            dialog.sendRequest(mSipProvider.getNewClientTransaction(request));
-        } catch (ParseException e) {
-            throw new SipException("sendReferNotify()", e);
-        }
-    }
-
-    public void sendInviteRequestTerminated(Request inviteRequest,
-            ServerTransaction inviteTransaction) throws SipException {
-        try {
-            Response response = mMessageFactory.createResponse(
-                    Response.REQUEST_TERMINATED, inviteRequest);
-            if (DBG) log("send response: " + response);
-            inviteTransaction.sendResponse(response);
-        } catch (ParseException e) {
-            throw new SipException("sendInviteRequestTerminated()", e);
-        }
-    }
-
-    public static String getCallId(EventObject event) {
-        if (event == null) return null;
-        if (event instanceof RequestEvent) {
-            return getCallId(((RequestEvent) event).getRequest());
-        } else if (event instanceof ResponseEvent) {
-            return getCallId(((ResponseEvent) event).getResponse());
-        } else if (event instanceof DialogTerminatedEvent) {
-            Dialog dialog = ((DialogTerminatedEvent) event).getDialog();
-            return getCallId(((DialogTerminatedEvent) event).getDialog());
-        } else if (event instanceof TransactionTerminatedEvent) {
-            TransactionTerminatedEvent e = (TransactionTerminatedEvent) event;
-            return getCallId(e.isServerTransaction()
-                    ? e.getServerTransaction()
-                    : e.getClientTransaction());
-        } else {
-            Object source = event.getSource();
-            if (source instanceof Transaction) {
-                return getCallId(((Transaction) source));
-            } else if (source instanceof Dialog) {
-                return getCallId((Dialog) source);
-            }
-        }
-        return "";
-    }
-
-    public static String getCallId(Transaction transaction) {
-        return ((transaction != null) ? getCallId(transaction.getRequest())
-                                      : "");
-    }
-
-    private static String getCallId(Message message) {
-        CallIdHeader callIdHeader =
-                (CallIdHeader) message.getHeader(CallIdHeader.NAME);
-        return callIdHeader.getCallId();
-    }
-
-    private static String getCallId(Dialog dialog) {
-        return dialog.getCallId().getCallId();
-    }
-
-    private void log(String s) {
-        Rlog.d(TAG, s);
-    }
-}
diff --git a/voip/java/com/android/server/sip/SipService.java b/voip/java/com/android/server/sip/SipService.java
deleted file mode 100644
index 80fe68c..0000000
--- a/voip/java/com/android/server/sip/SipService.java
+++ /dev/null
@@ -1,1262 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-package com.android.server.sip;
-
-import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.net.ConnectivityManager;
-import android.net.NetworkInfo;
-import android.net.sip.ISipService;
-import android.net.sip.ISipSession;
-import android.net.sip.ISipSessionListener;
-import android.net.sip.SipErrorCode;
-import android.net.sip.SipManager;
-import android.net.sip.SipProfile;
-import android.net.sip.SipSession;
-import android.net.sip.SipSessionAdapter;
-import android.net.wifi.WifiManager;
-import android.os.Binder;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.os.Message;
-import android.os.PowerManager;
-import android.os.Process;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.os.SystemClock;
-import android.telephony.Rlog;
-
-import java.io.IOException;
-import java.net.DatagramSocket;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.Executor;
-import javax.sip.SipException;
-
-/**
- * @hide
- */
-public final class SipService extends ISipService.Stub {
-    static final String TAG = "SipService";
-    static final boolean DBG = true;
-    private static final int EXPIRY_TIME = 3600;
-    private static final int SHORT_EXPIRY_TIME = 10;
-    private static final int MIN_EXPIRY_TIME = 60;
-    private static final int DEFAULT_KEEPALIVE_INTERVAL = 10; // in seconds
-    private static final int DEFAULT_MAX_KEEPALIVE_INTERVAL = 120; // in seconds
-
-    private Context mContext;
-    private String mLocalIp;
-    private int mNetworkType = -1;
-    private SipWakeupTimer mTimer;
-    private WifiManager.WifiLock mWifiLock;
-    private boolean mSipOnWifiOnly;
-
-    private SipKeepAliveProcessCallback mSipKeepAliveProcessCallback;
-
-    private MyExecutor mExecutor = new MyExecutor();
-
-    // SipProfile URI --> group
-    private Map<String, SipSessionGroupExt> mSipGroups =
-            new HashMap<String, SipSessionGroupExt>();
-
-    // session ID --> session
-    private Map<String, ISipSession> mPendingSessions =
-            new HashMap<String, ISipSession>();
-
-    private ConnectivityReceiver mConnectivityReceiver;
-    private SipWakeLock mMyWakeLock;
-    private int mKeepAliveInterval;
-    private int mLastGoodKeepAliveInterval = DEFAULT_KEEPALIVE_INTERVAL;
-
-    /**
-     * Starts the SIP service. Do nothing if the SIP API is not supported on the
-     * device.
-     */
-    public static void start(Context context) {
-        if (SipManager.isApiSupported(context)) {
-            ServiceManager.addService("sip", new SipService(context));
-            context.sendBroadcast(new Intent(SipManager.ACTION_SIP_SERVICE_UP));
-            if (DBG) slog("start:");
-        }
-    }
-
-    private SipService(Context context) {
-        if (DBG) log("SipService: started!");
-        mContext = context;
-        mConnectivityReceiver = new ConnectivityReceiver();
-
-        mWifiLock = ((WifiManager)
-                context.getSystemService(Context.WIFI_SERVICE))
-                .createWifiLock(WifiManager.WIFI_MODE_FULL, TAG);
-        mWifiLock.setReferenceCounted(false);
-        mSipOnWifiOnly = SipManager.isSipWifiOnly(context);
-
-        mMyWakeLock = new SipWakeLock((PowerManager)
-                context.getSystemService(Context.POWER_SERVICE));
-
-        mTimer = new SipWakeupTimer(context, mExecutor);
-    }
-
-    @Override
-    public synchronized SipProfile[] getListOfProfiles() {
-        mContext.enforceCallingOrSelfPermission(
-                android.Manifest.permission.USE_SIP, null);
-        boolean isCallerRadio = isCallerRadio();
-        ArrayList<SipProfile> profiles = new ArrayList<SipProfile>();
-        for (SipSessionGroupExt group : mSipGroups.values()) {
-            if (isCallerRadio || isCallerCreator(group)) {
-                profiles.add(group.getLocalProfile());
-            }
-        }
-        return profiles.toArray(new SipProfile[profiles.size()]);
-    }
-
-    @Override
-    public synchronized void open(SipProfile localProfile) {
-        mContext.enforceCallingOrSelfPermission(
-                android.Manifest.permission.USE_SIP, null);
-        localProfile.setCallingUid(Binder.getCallingUid());
-        try {
-            createGroup(localProfile);
-        } catch (SipException e) {
-            loge("openToMakeCalls()", e);
-            // TODO: how to send the exception back
-        }
-    }
-
-    @Override
-    public synchronized void open3(SipProfile localProfile,
-            PendingIntent incomingCallPendingIntent,
-            ISipSessionListener listener) {
-        mContext.enforceCallingOrSelfPermission(
-                android.Manifest.permission.USE_SIP, null);
-        localProfile.setCallingUid(Binder.getCallingUid());
-        if (incomingCallPendingIntent == null) {
-            if (DBG) log("open3: incomingCallPendingIntent cannot be null; "
-                    + "the profile is not opened");
-            return;
-        }
-        if (DBG) log("open3: " + localProfile.getUriString() + ": "
-                + incomingCallPendingIntent + ": " + listener);
-        try {
-            SipSessionGroupExt group = createGroup(localProfile,
-                    incomingCallPendingIntent, listener);
-            if (localProfile.getAutoRegistration()) {
-                group.openToReceiveCalls();
-                updateWakeLocks();
-            }
-        } catch (SipException e) {
-            loge("open3:", e);
-            // TODO: how to send the exception back
-        }
-    }
-
-    private boolean isCallerCreator(SipSessionGroupExt group) {
-        SipProfile profile = group.getLocalProfile();
-        return (profile.getCallingUid() == Binder.getCallingUid());
-    }
-
-    private boolean isCallerCreatorOrRadio(SipSessionGroupExt group) {
-        return (isCallerRadio() || isCallerCreator(group));
-    }
-
-    private boolean isCallerRadio() {
-        return (Binder.getCallingUid() == Process.PHONE_UID);
-    }
-
-    @Override
-    public synchronized void close(String localProfileUri) {
-        mContext.enforceCallingOrSelfPermission(
-                android.Manifest.permission.USE_SIP, null);
-        SipSessionGroupExt group = mSipGroups.get(localProfileUri);
-        if (group == null) return;
-        if (!isCallerCreatorOrRadio(group)) {
-            if (DBG) log("only creator or radio can close this profile");
-            return;
-        }
-
-        group = mSipGroups.remove(localProfileUri);
-        notifyProfileRemoved(group.getLocalProfile());
-        group.close();
-
-        updateWakeLocks();
-    }
-
-    @Override
-    public synchronized boolean isOpened(String localProfileUri) {
-        mContext.enforceCallingOrSelfPermission(
-                android.Manifest.permission.USE_SIP, null);
-        SipSessionGroupExt group = mSipGroups.get(localProfileUri);
-        if (group == null) return false;
-        if (isCallerCreatorOrRadio(group)) {
-            return true;
-        } else {
-            if (DBG) log("only creator or radio can query on the profile");
-            return false;
-        }
-    }
-
-    @Override
-    public synchronized boolean isRegistered(String localProfileUri) {
-        mContext.enforceCallingOrSelfPermission(
-                android.Manifest.permission.USE_SIP, null);
-        SipSessionGroupExt group = mSipGroups.get(localProfileUri);
-        if (group == null) return false;
-        if (isCallerCreatorOrRadio(group)) {
-            return group.isRegistered();
-        } else {
-            if (DBG) log("only creator or radio can query on the profile");
-            return false;
-        }
-    }
-
-    @Override
-    public synchronized void setRegistrationListener(String localProfileUri,
-            ISipSessionListener listener) {
-        mContext.enforceCallingOrSelfPermission(
-                android.Manifest.permission.USE_SIP, null);
-        SipSessionGroupExt group = mSipGroups.get(localProfileUri);
-        if (group == null) return;
-        if (isCallerCreator(group)) {
-            group.setListener(listener);
-        } else {
-            if (DBG) log("only creator can set listener on the profile");
-        }
-    }
-
-    @Override
-    public synchronized ISipSession createSession(SipProfile localProfile,
-            ISipSessionListener listener) {
-        if (DBG) log("createSession: profile" + localProfile);
-        mContext.enforceCallingOrSelfPermission(
-                android.Manifest.permission.USE_SIP, null);
-        localProfile.setCallingUid(Binder.getCallingUid());
-        if (mNetworkType == -1) {
-            if (DBG) log("createSession: mNetworkType==-1 ret=null");
-            return null;
-        }
-        try {
-            SipSessionGroupExt group = createGroup(localProfile);
-            return group.createSession(listener);
-        } catch (SipException e) {
-            if (DBG) loge("createSession;", e);
-            return null;
-        }
-    }
-
-    @Override
-    public synchronized ISipSession getPendingSession(String callId) {
-        mContext.enforceCallingOrSelfPermission(
-                android.Manifest.permission.USE_SIP, null);
-        if (callId == null) return null;
-        return mPendingSessions.get(callId);
-    }
-
-    private String determineLocalIp() {
-        try {
-            DatagramSocket s = new DatagramSocket();
-            s.connect(InetAddress.getByName("192.168.1.1"), 80);
-            return s.getLocalAddress().getHostAddress();
-        } catch (IOException e) {
-            if (DBG) loge("determineLocalIp()", e);
-            // dont do anything; there should be a connectivity change going
-            return null;
-        }
-    }
-
-    private SipSessionGroupExt createGroup(SipProfile localProfile)
-            throws SipException {
-        String key = localProfile.getUriString();
-        SipSessionGroupExt group = mSipGroups.get(key);
-        if (group == null) {
-            group = new SipSessionGroupExt(localProfile, null, null);
-            mSipGroups.put(key, group);
-            notifyProfileAdded(localProfile);
-        } else if (!isCallerCreator(group)) {
-            throw new SipException("only creator can access the profile");
-        }
-        return group;
-    }
-
-    private SipSessionGroupExt createGroup(SipProfile localProfile,
-            PendingIntent incomingCallPendingIntent,
-            ISipSessionListener listener) throws SipException {
-        String key = localProfile.getUriString();
-        SipSessionGroupExt group = mSipGroups.get(key);
-        if (group != null) {
-            if (!isCallerCreator(group)) {
-                throw new SipException("only creator can access the profile");
-            }
-            group.setIncomingCallPendingIntent(incomingCallPendingIntent);
-            group.setListener(listener);
-        } else {
-            group = new SipSessionGroupExt(localProfile,
-                    incomingCallPendingIntent, listener);
-            mSipGroups.put(key, group);
-            notifyProfileAdded(localProfile);
-        }
-        return group;
-    }
-
-    private void notifyProfileAdded(SipProfile localProfile) {
-        if (DBG) log("notify: profile added: " + localProfile);
-        Intent intent = new Intent(SipManager.ACTION_SIP_ADD_PHONE);
-        intent.putExtra(SipManager.EXTRA_LOCAL_URI, localProfile.getUriString());
-        mContext.sendBroadcast(intent);
-        if (mSipGroups.size() == 1) {
-            registerReceivers();
-        }
-    }
-
-    private void notifyProfileRemoved(SipProfile localProfile) {
-        if (DBG) log("notify: profile removed: " + localProfile);
-        Intent intent = new Intent(SipManager.ACTION_SIP_REMOVE_PHONE);
-        intent.putExtra(SipManager.EXTRA_LOCAL_URI, localProfile.getUriString());
-        mContext.sendBroadcast(intent);
-        if (mSipGroups.size() == 0) {
-            unregisterReceivers();
-        }
-    }
-
-    private void stopPortMappingMeasurement() {
-        if (mSipKeepAliveProcessCallback != null) {
-            mSipKeepAliveProcessCallback.stop();
-            mSipKeepAliveProcessCallback = null;
-        }
-    }
-
-    private void startPortMappingLifetimeMeasurement(
-            SipProfile localProfile) {
-        startPortMappingLifetimeMeasurement(localProfile,
-                DEFAULT_MAX_KEEPALIVE_INTERVAL);
-    }
-
-    private void startPortMappingLifetimeMeasurement(
-            SipProfile localProfile, int maxInterval) {
-        if ((mSipKeepAliveProcessCallback == null)
-                && (mKeepAliveInterval == -1)
-                && isBehindNAT(mLocalIp)) {
-            if (DBG) log("startPortMappingLifetimeMeasurement: profile="
-                    + localProfile.getUriString());
-
-            int minInterval = mLastGoodKeepAliveInterval;
-            if (minInterval >= maxInterval) {
-                // If mLastGoodKeepAliveInterval also does not work, reset it
-                // to the default min
-                minInterval = mLastGoodKeepAliveInterval
-                        = DEFAULT_KEEPALIVE_INTERVAL;
-                log("  reset min interval to " + minInterval);
-            }
-            mSipKeepAliveProcessCallback = new SipKeepAliveProcessCallback(
-                    localProfile, minInterval, maxInterval);
-            mSipKeepAliveProcessCallback.start();
-        }
-    }
-
-    private void restartPortMappingLifetimeMeasurement(
-            SipProfile localProfile, int maxInterval) {
-        stopPortMappingMeasurement();
-        mKeepAliveInterval = -1;
-        startPortMappingLifetimeMeasurement(localProfile, maxInterval);
-    }
-
-    private synchronized void addPendingSession(ISipSession session) {
-        try {
-            cleanUpPendingSessions();
-            mPendingSessions.put(session.getCallId(), session);
-            if (DBG) log("#pending sess=" + mPendingSessions.size());
-        } catch (RemoteException e) {
-            // should not happen with a local call
-            loge("addPendingSession()", e);
-        }
-    }
-
-    private void cleanUpPendingSessions() throws RemoteException {
-        Map.Entry<String, ISipSession>[] entries =
-                mPendingSessions.entrySet().toArray(
-                new Map.Entry[mPendingSessions.size()]);
-        for (Map.Entry<String, ISipSession> entry : entries) {
-            if (entry.getValue().getState() != SipSession.State.INCOMING_CALL) {
-                mPendingSessions.remove(entry.getKey());
-            }
-        }
-    }
-
-    private synchronized boolean callingSelf(SipSessionGroupExt ringingGroup,
-            SipSessionGroup.SipSessionImpl ringingSession) {
-        String callId = ringingSession.getCallId();
-        for (SipSessionGroupExt group : mSipGroups.values()) {
-            if ((group != ringingGroup) && group.containsSession(callId)) {
-                if (DBG) log("call self: "
-                        + ringingSession.getLocalProfile().getUriString()
-                        + " -> " + group.getLocalProfile().getUriString());
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private synchronized void onKeepAliveIntervalChanged() {
-        for (SipSessionGroupExt group : mSipGroups.values()) {
-            group.onKeepAliveIntervalChanged();
-        }
-    }
-
-    private int getKeepAliveInterval() {
-        return (mKeepAliveInterval < 0)
-                ? mLastGoodKeepAliveInterval
-                : mKeepAliveInterval;
-    }
-
-    private boolean isBehindNAT(String address) {
-        try {
-            // TODO: How is isBehindNAT used and why these constanst address:
-            //       10.x.x.x | 192.168.x.x | 172.16.x.x .. 172.19.x.x
-            byte[] d = InetAddress.getByName(address).getAddress();
-            if ((d[0] == 10) ||
-                    (((0x000000FF & d[0]) == 172) &&
-                    ((0x000000F0 & d[1]) == 16)) ||
-                    (((0x000000FF & d[0]) == 192) &&
-                    ((0x000000FF & d[1]) == 168))) {
-                return true;
-            }
-        } catch (UnknownHostException e) {
-            loge("isBehindAT()" + address, e);
-        }
-        return false;
-    }
-
-    private class SipSessionGroupExt extends SipSessionAdapter {
-        private static final String SSGE_TAG = "SipSessionGroupExt";
-        private static final boolean SSGE_DBG = true;
-        private SipSessionGroup mSipGroup;
-        private PendingIntent mIncomingCallPendingIntent;
-        private boolean mOpenedToReceiveCalls;
-
-        private SipAutoReg mAutoRegistration =
-                new SipAutoReg();
-
-        public SipSessionGroupExt(SipProfile localProfile,
-                PendingIntent incomingCallPendingIntent,
-                ISipSessionListener listener) throws SipException {
-            if (SSGE_DBG) log("SipSessionGroupExt: profile=" + localProfile);
-            mSipGroup = new SipSessionGroup(duplicate(localProfile),
-                    localProfile.getPassword(), mTimer, mMyWakeLock);
-            mIncomingCallPendingIntent = incomingCallPendingIntent;
-            mAutoRegistration.setListener(listener);
-        }
-
-        public SipProfile getLocalProfile() {
-            return mSipGroup.getLocalProfile();
-        }
-
-        public boolean containsSession(String callId) {
-            return mSipGroup.containsSession(callId);
-        }
-
-        public void onKeepAliveIntervalChanged() {
-            mAutoRegistration.onKeepAliveIntervalChanged();
-        }
-
-        // TODO: remove this method once SipWakeupTimer can better handle variety
-        // of timeout values
-        void setWakeupTimer(SipWakeupTimer timer) {
-            mSipGroup.setWakeupTimer(timer);
-        }
-
-        private SipProfile duplicate(SipProfile p) {
-            try {
-                return new SipProfile.Builder(p).setPassword("*").build();
-            } catch (Exception e) {
-                loge("duplicate()", e);
-                throw new RuntimeException("duplicate profile", e);
-            }
-        }
-
-        public void setListener(ISipSessionListener listener) {
-            mAutoRegistration.setListener(listener);
-        }
-
-        public void setIncomingCallPendingIntent(PendingIntent pIntent) {
-            mIncomingCallPendingIntent = pIntent;
-        }
-
-        public void openToReceiveCalls() throws SipException {
-            mOpenedToReceiveCalls = true;
-            if (mNetworkType != -1) {
-                mSipGroup.openToReceiveCalls(this);
-                mAutoRegistration.start(mSipGroup);
-            }
-            if (SSGE_DBG) log("openToReceiveCalls: " + getUri() + ": "
-                    + mIncomingCallPendingIntent);
-        }
-
-        public void onConnectivityChanged(boolean connected)
-                throws SipException {
-            if (SSGE_DBG) {
-                log("onConnectivityChanged: connected=" + connected + " uri="
-                    + getUri() + ": " + mIncomingCallPendingIntent);
-            }
-            mSipGroup.onConnectivityChanged();
-            if (connected) {
-                mSipGroup.reset();
-                if (mOpenedToReceiveCalls) openToReceiveCalls();
-            } else {
-                mSipGroup.close();
-                mAutoRegistration.stop();
-            }
-        }
-
-        public void close() {
-            mOpenedToReceiveCalls = false;
-            mSipGroup.close();
-            mAutoRegistration.stop();
-            if (SSGE_DBG) log("close: " + getUri() + ": " + mIncomingCallPendingIntent);
-        }
-
-        public ISipSession createSession(ISipSessionListener listener) {
-            if (SSGE_DBG) log("createSession");
-            return mSipGroup.createSession(listener);
-        }
-
-        @Override
-        public void onRinging(ISipSession s, SipProfile caller,
-                String sessionDescription) {
-            SipSessionGroup.SipSessionImpl session =
-                    (SipSessionGroup.SipSessionImpl) s;
-            synchronized (SipService.this) {
-                try {
-                    if (!isRegistered() || callingSelf(this, session)) {
-                        if (SSGE_DBG) log("onRinging: end notReg or self");
-                        session.endCall();
-                        return;
-                    }
-
-                    // send out incoming call broadcast
-                    addPendingSession(session);
-                    Intent intent = SipManager.createIncomingCallBroadcast(
-                            session.getCallId(), sessionDescription);
-                    if (SSGE_DBG) log("onRinging: uri=" + getUri() + ": "
-                            + caller.getUri() + ": " + session.getCallId()
-                            + " " + mIncomingCallPendingIntent);
-                    mIncomingCallPendingIntent.send(mContext,
-                            SipManager.INCOMING_CALL_RESULT_CODE, intent);
-                } catch (PendingIntent.CanceledException e) {
-                    loge("onRinging: pendingIntent is canceled, drop incoming call", e);
-                    session.endCall();
-                }
-            }
-        }
-
-        @Override
-        public void onError(ISipSession session, int errorCode,
-                String message) {
-            if (SSGE_DBG) log("onError: errorCode=" + errorCode + " desc="
-                    + SipErrorCode.toString(errorCode) + ": " + message);
-        }
-
-        public boolean isOpenedToReceiveCalls() {
-            return mOpenedToReceiveCalls;
-        }
-
-        public boolean isRegistered() {
-            return mAutoRegistration.isRegistered();
-        }
-
-        private String getUri() {
-            return mSipGroup.getLocalProfileUri();
-        }
-
-        private void log(String s) {
-            Rlog.d(SSGE_TAG, s);
-        }
-
-        private void loge(String s, Throwable t) {
-            Rlog.e(SSGE_TAG, s, t);
-        }
-
-    }
-
-    private class SipKeepAliveProcessCallback implements Runnable,
-            SipSessionGroup.KeepAliveProcessCallback {
-        private static final String SKAI_TAG = "SipKeepAliveProcessCallback";
-        private static final boolean SKAI_DBG = true;
-        private static final int MIN_INTERVAL = 5; // in seconds
-        private static final int PASS_THRESHOLD = 10;
-        private static final int NAT_MEASUREMENT_RETRY_INTERVAL = 120; // in seconds
-        private SipProfile mLocalProfile;
-        private SipSessionGroupExt mGroup;
-        private SipSessionGroup.SipSessionImpl mSession;
-        private int mMinInterval;
-        private int mMaxInterval;
-        private int mInterval;
-        private int mPassCount;
-
-        public SipKeepAliveProcessCallback(SipProfile localProfile,
-                int minInterval, int maxInterval) {
-            mMaxInterval = maxInterval;
-            mMinInterval = minInterval;
-            mLocalProfile = localProfile;
-        }
-
-        public void start() {
-            synchronized (SipService.this) {
-                if (mSession != null) {
-                    return;
-                }
-
-                mInterval = (mMaxInterval + mMinInterval) / 2;
-                mPassCount = 0;
-
-                // Don't start measurement if the interval is too small
-                if (mInterval < DEFAULT_KEEPALIVE_INTERVAL || checkTermination()) {
-                    if (SKAI_DBG) log("start: measurement aborted; interval=[" +
-                            mMinInterval + "," + mMaxInterval + "]");
-                    return;
-                }
-
-                try {
-                    if (SKAI_DBG) log("start: interval=" + mInterval);
-
-                    mGroup = new SipSessionGroupExt(mLocalProfile, null, null);
-                    // TODO: remove this line once SipWakeupTimer can better handle
-                    // variety of timeout values
-                    mGroup.setWakeupTimer(new SipWakeupTimer(mContext, mExecutor));
-
-                    mSession = (SipSessionGroup.SipSessionImpl)
-                            mGroup.createSession(null);
-                    mSession.startKeepAliveProcess(mInterval, this);
-                } catch (Throwable t) {
-                    onError(SipErrorCode.CLIENT_ERROR, t.toString());
-                }
-            }
-        }
-
-        public void stop() {
-            synchronized (SipService.this) {
-                if (mSession != null) {
-                    mSession.stopKeepAliveProcess();
-                    mSession = null;
-                }
-                if (mGroup != null) {
-                    mGroup.close();
-                    mGroup = null;
-                }
-                mTimer.cancel(this);
-                if (SKAI_DBG) log("stop");
-            }
-        }
-
-        private void restart() {
-            synchronized (SipService.this) {
-                // Return immediately if the measurement process is stopped
-                if (mSession == null) return;
-
-                if (SKAI_DBG) log("restart: interval=" + mInterval);
-                try {
-                    mSession.stopKeepAliveProcess();
-                    mPassCount = 0;
-                    mSession.startKeepAliveProcess(mInterval, this);
-                } catch (SipException e) {
-                    loge("restart", e);
-                }
-            }
-        }
-
-        private boolean checkTermination() {
-            return ((mMaxInterval - mMinInterval) < MIN_INTERVAL);
-        }
-
-        // SipSessionGroup.KeepAliveProcessCallback
-        @Override
-        public void onResponse(boolean portChanged) {
-            synchronized (SipService.this) {
-                if (!portChanged) {
-                    if (++mPassCount != PASS_THRESHOLD) return;
-                    // update the interval, since the current interval is good to
-                    // keep the port mapping.
-                    if (mKeepAliveInterval > 0) {
-                        mLastGoodKeepAliveInterval = mKeepAliveInterval;
-                    }
-                    mKeepAliveInterval = mMinInterval = mInterval;
-                    if (SKAI_DBG) {
-                        log("onResponse: portChanged=" + portChanged + " mKeepAliveInterval="
-                                + mKeepAliveInterval);
-                    }
-                    onKeepAliveIntervalChanged();
-                } else {
-                    // Since the rport is changed, shorten the interval.
-                    mMaxInterval = mInterval;
-                }
-                if (checkTermination()) {
-                    // update mKeepAliveInterval and stop measurement.
-                    stop();
-                    // If all the measurements failed, we still set it to
-                    // mMinInterval; If mMinInterval still doesn't work, a new
-                    // measurement with min interval=DEFAULT_KEEPALIVE_INTERVAL
-                    // will be conducted.
-                    mKeepAliveInterval = mMinInterval;
-                    if (SKAI_DBG) {
-                        log("onResponse: checkTermination mKeepAliveInterval="
-                                + mKeepAliveInterval);
-                    }
-                } else {
-                    // calculate the new interval and continue.
-                    mInterval = (mMaxInterval + mMinInterval) / 2;
-                    if (SKAI_DBG) {
-                        log("onResponse: mKeepAliveInterval=" + mKeepAliveInterval
-                                + ", new mInterval=" + mInterval);
-                    }
-                    restart();
-                }
-            }
-        }
-
-        // SipSessionGroup.KeepAliveProcessCallback
-        @Override
-        public void onError(int errorCode, String description) {
-            if (SKAI_DBG) loge("onError: errorCode=" + errorCode + " desc=" + description);
-            restartLater();
-        }
-
-        // timeout handler
-        @Override
-        public void run() {
-            mTimer.cancel(this);
-            restart();
-        }
-
-        private void restartLater() {
-            synchronized (SipService.this) {
-                int interval = NAT_MEASUREMENT_RETRY_INTERVAL;
-                mTimer.cancel(this);
-                mTimer.set(interval * 1000, this);
-            }
-        }
-
-        private void log(String s) {
-            Rlog.d(SKAI_TAG, s);
-        }
-
-        private void loge(String s) {
-            Rlog.d(SKAI_TAG, s);
-        }
-
-        private void loge(String s, Throwable t) {
-            Rlog.d(SKAI_TAG, s, t);
-        }
-    }
-
-    private class SipAutoReg extends SipSessionAdapter
-            implements Runnable, SipSessionGroup.KeepAliveProcessCallback {
-        private String SAR_TAG;
-        private static final boolean SAR_DBG = true;
-        private static final int MIN_KEEPALIVE_SUCCESS_COUNT = 10;
-
-        private SipSessionGroup.SipSessionImpl mSession;
-        private SipSessionGroup.SipSessionImpl mKeepAliveSession;
-        private SipSessionListenerProxy mProxy = new SipSessionListenerProxy();
-        private int mBackoff = 1;
-        private boolean mRegistered;
-        private long mExpiryTime;
-        private int mErrorCode;
-        private String mErrorMessage;
-        private boolean mRunning = false;
-
-        private int mKeepAliveSuccessCount = 0;
-
-        public void start(SipSessionGroup group) {
-            if (!mRunning) {
-                mRunning = true;
-                mBackoff = 1;
-                mSession = (SipSessionGroup.SipSessionImpl)
-                        group.createSession(this);
-                // return right away if no active network connection.
-                if (mSession == null) return;
-
-                // start unregistration to clear up old registration at server
-                // TODO: when rfc5626 is deployed, use reg-id and sip.instance
-                // in registration to avoid adding duplicate entries to server
-                mMyWakeLock.acquire(mSession);
-                mSession.unregister();
-                SAR_TAG = "SipAutoReg:" + mSession.getLocalProfile().getUriString();
-                if (SAR_DBG) log("start: group=" + group);
-            }
-        }
-
-        private void startKeepAliveProcess(int interval) {
-            if (SAR_DBG) log("startKeepAliveProcess: interval=" + interval);
-            if (mKeepAliveSession == null) {
-                mKeepAliveSession = mSession.duplicate();
-            } else {
-                mKeepAliveSession.stopKeepAliveProcess();
-            }
-            try {
-                mKeepAliveSession.startKeepAliveProcess(interval, this);
-            } catch (SipException e) {
-                loge("startKeepAliveProcess: interval=" + interval, e);
-            }
-        }
-
-        private void stopKeepAliveProcess() {
-            if (mKeepAliveSession != null) {
-                mKeepAliveSession.stopKeepAliveProcess();
-                mKeepAliveSession = null;
-            }
-            mKeepAliveSuccessCount = 0;
-        }
-
-        // SipSessionGroup.KeepAliveProcessCallback
-        @Override
-        public void onResponse(boolean portChanged) {
-            synchronized (SipService.this) {
-                if (portChanged) {
-                    int interval = getKeepAliveInterval();
-                    if (mKeepAliveSuccessCount < MIN_KEEPALIVE_SUCCESS_COUNT) {
-                        if (SAR_DBG) {
-                            log("onResponse: keepalive doesn't work with interval "
-                                    + interval + ", past success count="
-                                    + mKeepAliveSuccessCount);
-                        }
-                        if (interval > DEFAULT_KEEPALIVE_INTERVAL) {
-                            restartPortMappingLifetimeMeasurement(
-                                    mSession.getLocalProfile(), interval);
-                            mKeepAliveSuccessCount = 0;
-                        }
-                    } else {
-                        if (SAR_DBG) {
-                            log("keep keepalive going with interval "
-                                    + interval + ", past success count="
-                                    + mKeepAliveSuccessCount);
-                        }
-                        mKeepAliveSuccessCount /= 2;
-                    }
-                } else {
-                    // Start keep-alive interval measurement on the first
-                    // successfully kept-alive SipSessionGroup
-                    startPortMappingLifetimeMeasurement(
-                            mSession.getLocalProfile());
-                    mKeepAliveSuccessCount++;
-                }
-
-                if (!mRunning || !portChanged) return;
-
-                // The keep alive process is stopped when port is changed;
-                // Nullify the session so that the process can be restarted
-                // again when the re-registration is done
-                mKeepAliveSession = null;
-
-                // Acquire wake lock for the registration process. The
-                // lock will be released when registration is complete.
-                mMyWakeLock.acquire(mSession);
-                mSession.register(EXPIRY_TIME);
-            }
-        }
-
-        // SipSessionGroup.KeepAliveProcessCallback
-        @Override
-        public void onError(int errorCode, String description) {
-            if (SAR_DBG) {
-                loge("onError: errorCode=" + errorCode + " desc=" + description);
-            }
-            onResponse(true); // re-register immediately
-        }
-
-        public void stop() {
-            if (!mRunning) return;
-            mRunning = false;
-            mMyWakeLock.release(mSession);
-            if (mSession != null) {
-                mSession.setListener(null);
-                if (mNetworkType != -1 && mRegistered) mSession.unregister();
-            }
-
-            mTimer.cancel(this);
-            stopKeepAliveProcess();
-
-            mRegistered = false;
-            setListener(mProxy.getListener());
-        }
-
-        public void onKeepAliveIntervalChanged() {
-            if (mKeepAliveSession != null) {
-                int newInterval = getKeepAliveInterval();
-                if (SAR_DBG) {
-                    log("onKeepAliveIntervalChanged: interval=" + newInterval);
-                }
-                mKeepAliveSuccessCount = 0;
-                startKeepAliveProcess(newInterval);
-            }
-        }
-
-        public void setListener(ISipSessionListener listener) {
-            synchronized (SipService.this) {
-                mProxy.setListener(listener);
-
-                try {
-                    int state = (mSession == null)
-                            ? SipSession.State.READY_TO_CALL
-                            : mSession.getState();
-                    if ((state == SipSession.State.REGISTERING)
-                            || (state == SipSession.State.DEREGISTERING)) {
-                        mProxy.onRegistering(mSession);
-                    } else if (mRegistered) {
-                        int duration = (int)
-                                (mExpiryTime - SystemClock.elapsedRealtime());
-                        mProxy.onRegistrationDone(mSession, duration);
-                    } else if (mErrorCode != SipErrorCode.NO_ERROR) {
-                        if (mErrorCode == SipErrorCode.TIME_OUT) {
-                            mProxy.onRegistrationTimeout(mSession);
-                        } else {
-                            mProxy.onRegistrationFailed(mSession, mErrorCode,
-                                    mErrorMessage);
-                        }
-                    } else if (mNetworkType == -1) {
-                        mProxy.onRegistrationFailed(mSession,
-                                SipErrorCode.DATA_CONNECTION_LOST,
-                                "no data connection");
-                    } else if (!mRunning) {
-                        mProxy.onRegistrationFailed(mSession,
-                                SipErrorCode.CLIENT_ERROR,
-                                "registration not running");
-                    } else {
-                        mProxy.onRegistrationFailed(mSession,
-                                SipErrorCode.IN_PROGRESS,
-                                String.valueOf(state));
-                    }
-                } catch (Throwable t) {
-                    loge("setListener: ", t);
-                }
-            }
-        }
-
-        public boolean isRegistered() {
-            return mRegistered;
-        }
-
-        // timeout handler: re-register
-        @Override
-        public void run() {
-            synchronized (SipService.this) {
-                if (!mRunning) return;
-
-                mErrorCode = SipErrorCode.NO_ERROR;
-                mErrorMessage = null;
-                if (SAR_DBG) log("run: registering");
-                if (mNetworkType != -1) {
-                    mMyWakeLock.acquire(mSession);
-                    mSession.register(EXPIRY_TIME);
-                }
-            }
-        }
-
-        private void restart(int duration) {
-            if (SAR_DBG) log("restart: duration=" + duration + "s later.");
-            mTimer.cancel(this);
-            mTimer.set(duration * 1000, this);
-        }
-
-        private int backoffDuration() {
-            int duration = SHORT_EXPIRY_TIME * mBackoff;
-            if (duration > 3600) {
-                duration = 3600;
-            } else {
-                mBackoff *= 2;
-            }
-            return duration;
-        }
-
-        @Override
-        public void onRegistering(ISipSession session) {
-            if (SAR_DBG) log("onRegistering: " + session);
-            synchronized (SipService.this) {
-                if (notCurrentSession(session)) return;
-
-                mRegistered = false;
-                mProxy.onRegistering(session);
-            }
-        }
-
-        private boolean notCurrentSession(ISipSession session) {
-            if (session != mSession) {
-                ((SipSessionGroup.SipSessionImpl) session).setListener(null);
-                mMyWakeLock.release(session);
-                return true;
-            }
-            return !mRunning;
-        }
-
-        @Override
-        public void onRegistrationDone(ISipSession session, int duration) {
-            if (SAR_DBG) log("onRegistrationDone: " + session);
-            synchronized (SipService.this) {
-                if (notCurrentSession(session)) return;
-
-                mProxy.onRegistrationDone(session, duration);
-
-                if (duration > 0) {
-                    mExpiryTime = SystemClock.elapsedRealtime()
-                            + (duration * 1000);
-
-                    if (!mRegistered) {
-                        mRegistered = true;
-                        // allow some overlap to avoid call drop during renew
-                        duration -= MIN_EXPIRY_TIME;
-                        if (duration < MIN_EXPIRY_TIME) {
-                            duration = MIN_EXPIRY_TIME;
-                        }
-                        restart(duration);
-
-                        SipProfile localProfile = mSession.getLocalProfile();
-                        if ((mKeepAliveSession == null) && (isBehindNAT(mLocalIp)
-                                || localProfile.getSendKeepAlive())) {
-                            startKeepAliveProcess(getKeepAliveInterval());
-                        }
-                    }
-                    mMyWakeLock.release(session);
-                } else {
-                    mRegistered = false;
-                    mExpiryTime = -1L;
-                    if (SAR_DBG) log("Refresh registration immediately");
-                    run();
-                }
-            }
-        }
-
-        @Override
-        public void onRegistrationFailed(ISipSession session, int errorCode,
-                String message) {
-            if (SAR_DBG) log("onRegistrationFailed: " + session + ": "
-                    + SipErrorCode.toString(errorCode) + ": " + message);
-            synchronized (SipService.this) {
-                if (notCurrentSession(session)) return;
-
-                switch (errorCode) {
-                    case SipErrorCode.INVALID_CREDENTIALS:
-                    case SipErrorCode.SERVER_UNREACHABLE:
-                        if (SAR_DBG) log("   pause auto-registration");
-                        stop();
-                        break;
-                    default:
-                        restartLater();
-                }
-
-                mErrorCode = errorCode;
-                mErrorMessage = message;
-                mProxy.onRegistrationFailed(session, errorCode, message);
-                mMyWakeLock.release(session);
-            }
-        }
-
-        @Override
-        public void onRegistrationTimeout(ISipSession session) {
-            if (SAR_DBG) log("onRegistrationTimeout: " + session);
-            synchronized (SipService.this) {
-                if (notCurrentSession(session)) return;
-
-                mErrorCode = SipErrorCode.TIME_OUT;
-                mProxy.onRegistrationTimeout(session);
-                restartLater();
-                mMyWakeLock.release(session);
-            }
-        }
-
-        private void restartLater() {
-            if (SAR_DBG) loge("restartLater");
-            mRegistered = false;
-            restart(backoffDuration());
-        }
-
-        private void log(String s) {
-            Rlog.d(SAR_TAG, s);
-        }
-
-        private void loge(String s) {
-            Rlog.e(SAR_TAG, s);
-        }
-
-        private void loge(String s, Throwable e) {
-            Rlog.e(SAR_TAG, s, e);
-        }
-    }
-
-    private class ConnectivityReceiver extends BroadcastReceiver {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            Bundle bundle = intent.getExtras();
-            if (bundle != null) {
-                final NetworkInfo info = (NetworkInfo)
-                        bundle.get(ConnectivityManager.EXTRA_NETWORK_INFO);
-
-                // Run the handler in MyExecutor to be protected by wake lock
-                mExecutor.execute(new Runnable() {
-                    @Override
-                    public void run() {
-                        onConnectivityChanged(info);
-                    }
-                });
-            }
-        }
-    }
-
-    private void registerReceivers() {
-        mContext.registerReceiver(mConnectivityReceiver,
-                new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
-        if (DBG) log("registerReceivers:");
-    }
-
-    private void unregisterReceivers() {
-        mContext.unregisterReceiver(mConnectivityReceiver);
-        if (DBG) log("unregisterReceivers:");
-
-        // Reset variables maintained by ConnectivityReceiver.
-        mWifiLock.release();
-        mNetworkType = -1;
-    }
-
-    private void updateWakeLocks() {
-        for (SipSessionGroupExt group : mSipGroups.values()) {
-            if (group.isOpenedToReceiveCalls()) {
-                // Also grab the WifiLock when we are disconnected, so the
-                // system will keep trying to reconnect. It will be released
-                // when the system eventually connects to something else.
-                if (mNetworkType == ConnectivityManager.TYPE_WIFI || mNetworkType == -1) {
-                    mWifiLock.acquire();
-                } else {
-                    mWifiLock.release();
-                }
-                return;
-            }
-        }
-        mWifiLock.release();
-        mMyWakeLock.reset(); // in case there's a leak
-    }
-
-    private synchronized void onConnectivityChanged(NetworkInfo info) {
-        // We only care about the default network, and getActiveNetworkInfo()
-        // is the only way to distinguish them. However, as broadcasts are
-        // delivered asynchronously, we might miss DISCONNECTED events from
-        // getActiveNetworkInfo(), which is critical to our SIP stack. To
-        // solve this, if it is a DISCONNECTED event to our current network,
-        // respect it. Otherwise get a new one from getActiveNetworkInfo().
-        if (info == null || info.isConnected() || info.getType() != mNetworkType) {
-            ConnectivityManager cm = (ConnectivityManager)
-                    mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
-            info = cm.getActiveNetworkInfo();
-        }
-
-        // Some devices limit SIP on Wi-Fi. In this case, if we are not on
-        // Wi-Fi, treat it as a DISCONNECTED event.
-        int networkType = (info != null && info.isConnected()) ? info.getType() : -1;
-        if (mSipOnWifiOnly && networkType != ConnectivityManager.TYPE_WIFI) {
-            networkType = -1;
-        }
-
-        // Ignore the event if the current active network is not changed.
-        if (mNetworkType == networkType) {
-            // TODO: Maybe we need to send seq/generation number
-            return;
-        }
-        if (DBG) {
-            log("onConnectivityChanged: " + mNetworkType +
-                    " -> " + networkType);
-        }
-
-        try {
-            if (mNetworkType != -1) {
-                mLocalIp = null;
-                stopPortMappingMeasurement();
-                for (SipSessionGroupExt group : mSipGroups.values()) {
-                    group.onConnectivityChanged(false);
-                }
-            }
-            mNetworkType = networkType;
-
-            if (mNetworkType != -1) {
-                mLocalIp = determineLocalIp();
-                mKeepAliveInterval = -1;
-                mLastGoodKeepAliveInterval = DEFAULT_KEEPALIVE_INTERVAL;
-                for (SipSessionGroupExt group : mSipGroups.values()) {
-                    group.onConnectivityChanged(true);
-                }
-            }
-            updateWakeLocks();
-        } catch (SipException e) {
-            loge("onConnectivityChanged()", e);
-        }
-    }
-
-    private static Looper createLooper() {
-        HandlerThread thread = new HandlerThread("SipService.Executor");
-        thread.start();
-        return thread.getLooper();
-    }
-
-    // Executes immediate tasks in a single thread.
-    // Hold/release wake lock for running tasks
-    private class MyExecutor extends Handler implements Executor {
-        MyExecutor() {
-            super(createLooper());
-        }
-
-        @Override
-        public void execute(Runnable task) {
-            mMyWakeLock.acquire(task);
-            Message.obtain(this, 0/* don't care */, task).sendToTarget();
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            if (msg.obj instanceof Runnable) {
-                executeInternal((Runnable) msg.obj);
-            } else {
-                if (DBG) log("handleMessage: not Runnable ignore msg=" + msg);
-            }
-        }
-
-        private void executeInternal(Runnable task) {
-            try {
-                task.run();
-            } catch (Throwable t) {
-                loge("run task: " + task, t);
-            } finally {
-                mMyWakeLock.release(task);
-            }
-        }
-    }
-
-    private void log(String s) {
-        Rlog.d(TAG, s);
-    }
-
-    private static void slog(String s) {
-        Rlog.d(TAG, s);
-    }
-
-    private void loge(String s, Throwable e) {
-        Rlog.e(TAG, s, e);
-    }
-}
diff --git a/voip/java/com/android/server/sip/SipSessionGroup.java b/voip/java/com/android/server/sip/SipSessionGroup.java
deleted file mode 100644
index e820f35..0000000
--- a/voip/java/com/android/server/sip/SipSessionGroup.java
+++ /dev/null
@@ -1,1863 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-package com.android.server.sip;
-
-import gov.nist.javax.sip.clientauthutils.AccountManager;
-import gov.nist.javax.sip.clientauthutils.UserCredentials;
-import gov.nist.javax.sip.header.ProxyAuthenticate;
-import gov.nist.javax.sip.header.ReferTo;
-import gov.nist.javax.sip.header.SIPHeaderNames;
-import gov.nist.javax.sip.header.StatusLine;
-import gov.nist.javax.sip.header.WWWAuthenticate;
-import gov.nist.javax.sip.header.extensions.ReferredByHeader;
-import gov.nist.javax.sip.header.extensions.ReplacesHeader;
-import gov.nist.javax.sip.message.SIPMessage;
-import gov.nist.javax.sip.message.SIPResponse;
-
-import android.net.sip.ISipSession;
-import android.net.sip.ISipSessionListener;
-import android.net.sip.SipErrorCode;
-import android.net.sip.SipProfile;
-import android.net.sip.SipSession;
-import android.net.sip.SipSessionAdapter;
-import android.text.TextUtils;
-import android.telephony.Rlog;
-
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.net.DatagramSocket;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.text.ParseException;
-import java.util.EventObject;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Properties;
-
-import javax.sip.ClientTransaction;
-import javax.sip.Dialog;
-import javax.sip.DialogTerminatedEvent;
-import javax.sip.IOExceptionEvent;
-import javax.sip.ObjectInUseException;
-import javax.sip.RequestEvent;
-import javax.sip.ResponseEvent;
-import javax.sip.ServerTransaction;
-import javax.sip.SipException;
-import javax.sip.SipFactory;
-import javax.sip.SipListener;
-import javax.sip.SipProvider;
-import javax.sip.SipStack;
-import javax.sip.TimeoutEvent;
-import javax.sip.Transaction;
-import javax.sip.TransactionTerminatedEvent;
-import javax.sip.address.Address;
-import javax.sip.address.SipURI;
-import javax.sip.header.CSeqHeader;
-import javax.sip.header.ContactHeader;
-import javax.sip.header.ExpiresHeader;
-import javax.sip.header.FromHeader;
-import javax.sip.header.HeaderAddress;
-import javax.sip.header.MinExpiresHeader;
-import javax.sip.header.ReferToHeader;
-import javax.sip.header.ViaHeader;
-import javax.sip.message.Message;
-import javax.sip.message.Request;
-import javax.sip.message.Response;
-
-
-/**
- * Manages {@link ISipSession}'s for a SIP account.
- */
-class SipSessionGroup implements SipListener {
-    private static final String TAG = "SipSession";
-    private static final boolean DBG = false;
-    private static final boolean DBG_PING = false;
-    private static final String ANONYMOUS = "anonymous";
-    // Limit the size of thread pool to 1 for the order issue when the phone is
-    // waken up from sleep and there are many packets to be processed in the SIP
-    // stack. Note: The default thread pool size in NIST SIP stack is -1 which is
-    // unlimited.
-    private static final String THREAD_POOL_SIZE = "1";
-    private static final int EXPIRY_TIME = 3600; // in seconds
-    private static final int CANCEL_CALL_TIMER = 3; // in seconds
-    private static final int END_CALL_TIMER = 3; // in seconds
-    private static final int KEEPALIVE_TIMEOUT = 5; // in seconds
-    private static final int INCALL_KEEPALIVE_INTERVAL = 10; // in seconds
-    private static final long WAKE_LOCK_HOLDING_TIME = 500; // in milliseconds
-
-    private static final EventObject DEREGISTER = new EventObject("Deregister");
-    private static final EventObject END_CALL = new EventObject("End call");
-
-    private final SipProfile mLocalProfile;
-    private final String mPassword;
-
-    private SipStack mSipStack;
-    private SipHelper mSipHelper;
-
-    // session that processes INVITE requests
-    private SipSessionImpl mCallReceiverSession;
-    private String mLocalIp;
-
-    private SipWakeupTimer mWakeupTimer;
-    private SipWakeLock mWakeLock;
-
-    // call-id-to-SipSession map
-    private Map<String, SipSessionImpl> mSessionMap =
-            new HashMap<String, SipSessionImpl>();
-
-    // external address observed from any response
-    private String mExternalIp;
-    private int mExternalPort;
-
-    /**
-     * @param profile the local profile with password crossed out
-     * @param password the password of the profile
-     * @throws SipException if cannot assign requested address
-     */
-    public SipSessionGroup(SipProfile profile, String password,
-            SipWakeupTimer timer, SipWakeLock wakeLock) throws SipException {
-        mLocalProfile = profile;
-        mPassword = password;
-        mWakeupTimer = timer;
-        mWakeLock = wakeLock;
-        reset();
-    }
-
-    // TODO: remove this method once SipWakeupTimer can better handle variety
-    // of timeout values
-    void setWakeupTimer(SipWakeupTimer timer) {
-        mWakeupTimer = timer;
-    }
-
-    synchronized void reset() throws SipException {
-        Properties properties = new Properties();
-
-        String protocol = mLocalProfile.getProtocol();
-        int port = mLocalProfile.getPort();
-        String server = mLocalProfile.getProxyAddress();
-
-        if (!TextUtils.isEmpty(server)) {
-            properties.setProperty("javax.sip.OUTBOUND_PROXY",
-                    server + ':' + port + '/' + protocol);
-        } else {
-            server = mLocalProfile.getSipDomain();
-        }
-        if (server.startsWith("[") && server.endsWith("]")) {
-            server = server.substring(1, server.length() - 1);
-        }
-
-        String local = null;
-        try {
-            for (InetAddress remote : InetAddress.getAllByName(server)) {
-                DatagramSocket socket = new DatagramSocket();
-                socket.connect(remote, port);
-                if (socket.isConnected()) {
-                    local = socket.getLocalAddress().getHostAddress();
-                    port = socket.getLocalPort();
-                    socket.close();
-                    break;
-                }
-                socket.close();
-            }
-        } catch (Exception e) {
-            // ignore.
-        }
-        if (local == null) {
-            // We are unable to reach the server. Just bail out.
-            return;
-        }
-
-        close();
-        mLocalIp = local;
-
-        properties.setProperty("javax.sip.STACK_NAME", getStackName());
-        properties.setProperty(
-                "gov.nist.javax.sip.THREAD_POOL_SIZE", THREAD_POOL_SIZE);
-        mSipStack = SipFactory.getInstance().createSipStack(properties);
-        try {
-            SipProvider provider = mSipStack.createSipProvider(
-                    mSipStack.createListeningPoint(local, port, protocol));
-            provider.addSipListener(this);
-            mSipHelper = new SipHelper(mSipStack, provider);
-        } catch (SipException e) {
-            throw e;
-        } catch (Exception e) {
-            throw new SipException("failed to initialize SIP stack", e);
-        }
-
-        if (DBG) log("reset: start stack for " + mLocalProfile.getUriString());
-        mSipStack.start();
-    }
-
-    synchronized void onConnectivityChanged() {
-        SipSessionImpl[] ss = mSessionMap.values().toArray(
-                    new SipSessionImpl[mSessionMap.size()]);
-        // Iterate on the copied array instead of directly on mSessionMap to
-        // avoid ConcurrentModificationException being thrown when
-        // SipSessionImpl removes itself from mSessionMap in onError() in the
-        // following loop.
-        for (SipSessionImpl s : ss) {
-            s.onError(SipErrorCode.DATA_CONNECTION_LOST,
-                    "data connection lost");
-        }
-    }
-
-    synchronized void resetExternalAddress() {
-        if (DBG) {
-            log("resetExternalAddress: " + mSipStack);
-        }
-        mExternalIp = null;
-        mExternalPort = 0;
-    }
-
-    public SipProfile getLocalProfile() {
-        return mLocalProfile;
-    }
-
-    public String getLocalProfileUri() {
-        return mLocalProfile.getUriString();
-    }
-
-    private String getStackName() {
-        return "stack" + System.currentTimeMillis();
-    }
-
-    public synchronized void close() {
-        if (DBG) log("close: " + mLocalProfile.getUriString());
-        onConnectivityChanged();
-        mSessionMap.clear();
-        closeToNotReceiveCalls();
-        if (mSipStack != null) {
-            mSipStack.stop();
-            mSipStack = null;
-            mSipHelper = null;
-        }
-        resetExternalAddress();
-    }
-
-    public synchronized boolean isClosed() {
-        return (mSipStack == null);
-    }
-
-    // For internal use, require listener not to block in callbacks.
-    public synchronized void openToReceiveCalls(ISipSessionListener listener) {
-        if (mCallReceiverSession == null) {
-            mCallReceiverSession = new SipSessionCallReceiverImpl(listener);
-        } else {
-            mCallReceiverSession.setListener(listener);
-        }
-    }
-
-    public synchronized void closeToNotReceiveCalls() {
-        mCallReceiverSession = null;
-    }
-
-    public ISipSession createSession(ISipSessionListener listener) {
-        return (isClosed() ? null : new SipSessionImpl(listener));
-    }
-
-    synchronized boolean containsSession(String callId) {
-        return mSessionMap.containsKey(callId);
-    }
-
-    private synchronized SipSessionImpl getSipSession(EventObject event) {
-        String key = SipHelper.getCallId(event);
-        SipSessionImpl session = mSessionMap.get(key);
-        if ((session != null) && isLoggable(session)) {
-            if (DBG) log("getSipSession: event=" + key);
-            if (DBG) log("getSipSession: active sessions:");
-            for (String k : mSessionMap.keySet()) {
-                if (DBG) log("getSipSession: ..." + k + ": " + mSessionMap.get(k));
-            }
-        }
-        return ((session != null) ? session : mCallReceiverSession);
-    }
-
-    private synchronized void addSipSession(SipSessionImpl newSession) {
-        removeSipSession(newSession);
-        String key = newSession.getCallId();
-        mSessionMap.put(key, newSession);
-        if (isLoggable(newSession)) {
-            if (DBG) log("addSipSession: key='" + key + "'");
-            for (String k : mSessionMap.keySet()) {
-                if (DBG) log("addSipSession:  " + k + ": " + mSessionMap.get(k));
-            }
-        }
-    }
-
-    private synchronized void removeSipSession(SipSessionImpl session) {
-        if (session == mCallReceiverSession) return;
-        String key = session.getCallId();
-        SipSessionImpl s = mSessionMap.remove(key);
-        // sanity check
-        if ((s != null) && (s != session)) {
-            if (DBG) log("removeSession: " + session + " is not associated with key '"
-                    + key + "'");
-            mSessionMap.put(key, s);
-            for (Map.Entry<String, SipSessionImpl> entry
-                    : mSessionMap.entrySet()) {
-                if (entry.getValue() == s) {
-                    key = entry.getKey();
-                    mSessionMap.remove(key);
-                }
-            }
-        }
-
-        if ((s != null) && isLoggable(s)) {
-            if (DBG) log("removeSession: " + session + " @key '" + key + "'");
-            for (String k : mSessionMap.keySet()) {
-                if (DBG) log("removeSession:  " + k + ": " + mSessionMap.get(k));
-            }
-        }
-    }
-
-    @Override
-    public void processRequest(final RequestEvent event) {
-        if (isRequestEvent(Request.INVITE, event)) {
-            if (DBG) log("processRequest: mWakeLock.acquire got INVITE, thread:"
-                    + Thread.currentThread());
-            // Acquire a wake lock and keep it for WAKE_LOCK_HOLDING_TIME;
-            // should be large enough to bring up the app.
-            mWakeLock.acquire(WAKE_LOCK_HOLDING_TIME);
-        }
-        process(event);
-    }
-
-    @Override
-    public void processResponse(ResponseEvent event) {
-        process(event);
-    }
-
-    @Override
-    public void processIOException(IOExceptionEvent event) {
-        process(event);
-    }
-
-    @Override
-    public void processTimeout(TimeoutEvent event) {
-        process(event);
-    }
-
-    @Override
-    public void processTransactionTerminated(TransactionTerminatedEvent event) {
-        process(event);
-    }
-
-    @Override
-    public void processDialogTerminated(DialogTerminatedEvent event) {
-        process(event);
-    }
-
-    private synchronized void process(EventObject event) {
-        SipSessionImpl session = getSipSession(event);
-        try {
-            boolean isLoggable = isLoggable(session, event);
-            boolean processed = (session != null) && session.process(event);
-            if (isLoggable && processed) {
-                log("process: event new state after: "
-                        + SipSession.State.toString(session.mState));
-            }
-        } catch (Throwable e) {
-            loge("process: error event=" + event, getRootCause(e));
-            session.onError(e);
-        }
-    }
-
-    private String extractContent(Message message) {
-        // Currently we do not support secure MIME bodies.
-        byte[] bytes = message.getRawContent();
-        if (bytes != null) {
-            try {
-                if (message instanceof SIPMessage) {
-                    return ((SIPMessage) message).getMessageContent();
-                } else {
-                    return new String(bytes, "UTF-8");
-                }
-            } catch (UnsupportedEncodingException e) {
-            }
-        }
-        return null;
-    }
-
-    private void extractExternalAddress(ResponseEvent evt) {
-        Response response = evt.getResponse();
-        ViaHeader viaHeader = (ViaHeader)(response.getHeader(
-                SIPHeaderNames.VIA));
-        if (viaHeader == null) return;
-        int rport = viaHeader.getRPort();
-        String externalIp = viaHeader.getReceived();
-        if ((rport > 0) && (externalIp != null)) {
-            mExternalIp = externalIp;
-            mExternalPort = rport;
-            if (DBG) {
-                log("extractExternalAddress: external addr " + externalIp + ":" + rport
-                        + " on " + mSipStack);
-            }
-        }
-    }
-
-    private Throwable getRootCause(Throwable exception) {
-        Throwable cause = exception.getCause();
-        while (cause != null) {
-            exception = cause;
-            cause = exception.getCause();
-        }
-        return exception;
-    }
-
-    private SipSessionImpl createNewSession(RequestEvent event,
-            ISipSessionListener listener, ServerTransaction transaction,
-            int newState) throws SipException {
-        SipSessionImpl newSession = new SipSessionImpl(listener);
-        newSession.mServerTransaction = transaction;
-        newSession.mState = newState;
-        newSession.mDialog = newSession.mServerTransaction.getDialog();
-        newSession.mInviteReceived = event;
-        newSession.mPeerProfile = createPeerProfile((HeaderAddress)
-                event.getRequest().getHeader(FromHeader.NAME));
-        newSession.mPeerSessionDescription =
-                extractContent(event.getRequest());
-        return newSession;
-    }
-
-    private class SipSessionCallReceiverImpl extends SipSessionImpl {
-        private static final String SSCRI_TAG = "SipSessionCallReceiverImpl";
-        private static final boolean SSCRI_DBG = true;
-
-        public SipSessionCallReceiverImpl(ISipSessionListener listener) {
-            super(listener);
-        }
-
-        private int processInviteWithReplaces(RequestEvent event,
-                ReplacesHeader replaces) {
-            String callId = replaces.getCallId();
-            SipSessionImpl session = mSessionMap.get(callId);
-            if (session == null) {
-                return Response.CALL_OR_TRANSACTION_DOES_NOT_EXIST;
-            }
-
-            Dialog dialog = session.mDialog;
-            if (dialog == null) return Response.DECLINE;
-
-            if (!dialog.getLocalTag().equals(replaces.getToTag()) ||
-                    !dialog.getRemoteTag().equals(replaces.getFromTag())) {
-                // No match is found, returns 481.
-                return Response.CALL_OR_TRANSACTION_DOES_NOT_EXIST;
-            }
-
-            ReferredByHeader referredBy = (ReferredByHeader) event.getRequest()
-                    .getHeader(ReferredByHeader.NAME);
-            if ((referredBy == null) ||
-                    !dialog.getRemoteParty().equals(referredBy.getAddress())) {
-                return Response.CALL_OR_TRANSACTION_DOES_NOT_EXIST;
-            }
-            return Response.OK;
-        }
-
-        private void processNewInviteRequest(RequestEvent event)
-                throws SipException {
-            ReplacesHeader replaces = (ReplacesHeader) event.getRequest()
-                    .getHeader(ReplacesHeader.NAME);
-            SipSessionImpl newSession = null;
-            if (replaces != null) {
-                int response = processInviteWithReplaces(event, replaces);
-                if (SSCRI_DBG) {
-                    log("processNewInviteRequest: " + replaces
-                            + " response=" + response);
-                }
-                if (response == Response.OK) {
-                    SipSessionImpl replacedSession =
-                            mSessionMap.get(replaces.getCallId());
-                    // got INVITE w/ replaces request.
-                    newSession = createNewSession(event,
-                            replacedSession.mProxy.getListener(),
-                            mSipHelper.getServerTransaction(event),
-                            SipSession.State.INCOMING_CALL);
-                    newSession.mProxy.onCallTransferring(newSession,
-                            newSession.mPeerSessionDescription);
-                } else {
-                    mSipHelper.sendResponse(event, response);
-                }
-            } else {
-                // New Incoming call.
-                newSession = createNewSession(event, mProxy,
-                        mSipHelper.sendRinging(event, generateTag()),
-                        SipSession.State.INCOMING_CALL);
-                mProxy.onRinging(newSession, newSession.mPeerProfile,
-                        newSession.mPeerSessionDescription);
-            }
-            if (newSession != null) addSipSession(newSession);
-        }
-
-        @Override
-        public boolean process(EventObject evt) throws SipException {
-            if (isLoggable(this, evt)) log("process: " + this + ": "
-                    + SipSession.State.toString(mState) + ": processing "
-                    + logEvt(evt));
-            if (isRequestEvent(Request.INVITE, evt)) {
-                processNewInviteRequest((RequestEvent) evt);
-                return true;
-            } else if (isRequestEvent(Request.OPTIONS, evt)) {
-                mSipHelper.sendResponse((RequestEvent) evt, Response.OK);
-                return true;
-            } else {
-                return false;
-            }
-        }
-
-        private void log(String s) {
-            Rlog.d(SSCRI_TAG, s);
-        }
-    }
-
-    static interface KeepAliveProcessCallback {
-        /** Invoked when the response of keeping alive comes back. */
-        void onResponse(boolean portChanged);
-        void onError(int errorCode, String description);
-    }
-
-    class SipSessionImpl extends ISipSession.Stub {
-        private static final String SSI_TAG = "SipSessionImpl";
-        private static final boolean SSI_DBG = true;
-
-        SipProfile mPeerProfile;
-        SipSessionListenerProxy mProxy = new SipSessionListenerProxy();
-        int mState = SipSession.State.READY_TO_CALL;
-        RequestEvent mInviteReceived;
-        Dialog mDialog;
-        ServerTransaction mServerTransaction;
-        ClientTransaction mClientTransaction;
-        String mPeerSessionDescription;
-        boolean mInCall;
-        SessionTimer mSessionTimer;
-        int mAuthenticationRetryCount;
-
-        private SipKeepAlive mSipKeepAlive;
-
-        private SipSessionImpl mSipSessionImpl;
-
-        // the following three members are used for handling refer request.
-        SipSessionImpl mReferSession;
-        ReferredByHeader mReferredBy;
-        String mReplaces;
-
-        // lightweight timer
-        class SessionTimer {
-            private boolean mRunning = true;
-
-            void start(final int timeout) {
-                new Thread(new Runnable() {
-                    @Override
-                    public void run() {
-                        sleep(timeout);
-                        if (mRunning) timeout();
-                    }
-                }, "SipSessionTimerThread").start();
-            }
-
-            synchronized void cancel() {
-                mRunning = false;
-                this.notify();
-            }
-
-            private void timeout() {
-                synchronized (SipSessionGroup.this) {
-                    onError(SipErrorCode.TIME_OUT, "Session timed out!");
-                }
-            }
-
-            private synchronized void sleep(int timeout) {
-                try {
-                    this.wait(timeout * 1000);
-                } catch (InterruptedException e) {
-                    loge("session timer interrupted!", e);
-                }
-            }
-        }
-
-        public SipSessionImpl(ISipSessionListener listener) {
-            setListener(listener);
-        }
-
-        SipSessionImpl duplicate() {
-            return new SipSessionImpl(mProxy.getListener());
-        }
-
-        private void reset() {
-            mInCall = false;
-            removeSipSession(this);
-            mPeerProfile = null;
-            mState = SipSession.State.READY_TO_CALL;
-            mInviteReceived = null;
-            mPeerSessionDescription = null;
-            mAuthenticationRetryCount = 0;
-            mReferSession = null;
-            mReferredBy = null;
-            mReplaces = null;
-
-            if (mDialog != null) mDialog.delete();
-            mDialog = null;
-
-            try {
-                if (mServerTransaction != null) mServerTransaction.terminate();
-            } catch (ObjectInUseException e) {
-                // ignored
-            }
-            mServerTransaction = null;
-
-            try {
-                if (mClientTransaction != null) mClientTransaction.terminate();
-            } catch (ObjectInUseException e) {
-                // ignored
-            }
-            mClientTransaction = null;
-
-            cancelSessionTimer();
-
-            if (mSipSessionImpl != null) {
-                mSipSessionImpl.stopKeepAliveProcess();
-                mSipSessionImpl = null;
-            }
-        }
-
-        @Override
-        public boolean isInCall() {
-            return mInCall;
-        }
-
-        @Override
-        public String getLocalIp() {
-            return mLocalIp;
-        }
-
-        @Override
-        public SipProfile getLocalProfile() {
-            return mLocalProfile;
-        }
-
-        @Override
-        public SipProfile getPeerProfile() {
-            return mPeerProfile;
-        }
-
-        @Override
-        public String getCallId() {
-            return SipHelper.getCallId(getTransaction());
-        }
-
-        private Transaction getTransaction() {
-            if (mClientTransaction != null) return mClientTransaction;
-            if (mServerTransaction != null) return mServerTransaction;
-            return null;
-        }
-
-        @Override
-        public int getState() {
-            return mState;
-        }
-
-        @Override
-        public void setListener(ISipSessionListener listener) {
-            mProxy.setListener((listener instanceof SipSessionListenerProxy)
-                    ? ((SipSessionListenerProxy) listener).getListener()
-                    : listener);
-        }
-
-        // process the command in a new thread
-        private void doCommandAsync(final EventObject command) {
-            new Thread(new Runnable() {
-                    @Override
-                    public void run() {
-                        try {
-                            processCommand(command);
-                        } catch (Throwable e) {
-                            loge("command error: " + command + ": "
-                                    + mLocalProfile.getUriString(),
-                                    getRootCause(e));
-                            onError(e);
-                        }
-                    }
-            }, "SipSessionAsyncCmdThread").start();
-        }
-
-        @Override
-        public void makeCall(SipProfile peerProfile, String sessionDescription,
-                int timeout) {
-            doCommandAsync(new MakeCallCommand(peerProfile, sessionDescription,
-                    timeout));
-        }
-
-        @Override
-        public void answerCall(String sessionDescription, int timeout) {
-            synchronized (SipSessionGroup.this) {
-                if (mPeerProfile == null) return;
-                doCommandAsync(new MakeCallCommand(mPeerProfile,
-                        sessionDescription, timeout));
-            }
-        }
-
-        @Override
-        public void endCall() {
-            doCommandAsync(END_CALL);
-        }
-
-        @Override
-        public void changeCall(String sessionDescription, int timeout) {
-            synchronized (SipSessionGroup.this) {
-                if (mPeerProfile == null) return;
-                doCommandAsync(new MakeCallCommand(mPeerProfile,
-                        sessionDescription, timeout));
-            }
-        }
-
-        @Override
-        public void register(int duration) {
-            doCommandAsync(new RegisterCommand(duration));
-        }
-
-        @Override
-        public void unregister() {
-            doCommandAsync(DEREGISTER);
-        }
-
-        private void processCommand(EventObject command) throws SipException {
-            if (isLoggable(command)) log("process cmd: " + command);
-            if (!process(command)) {
-                onError(SipErrorCode.IN_PROGRESS,
-                        "cannot initiate a new transaction to execute: "
-                        + command);
-            }
-        }
-
-        protected String generateTag() {
-            // 32-bit randomness
-            return String.valueOf((long) (Math.random() * 0x100000000L));
-        }
-
-        @Override
-        public String toString() {
-            try {
-                String s = super.toString();
-                return s.substring(s.indexOf("@")) + ":"
-                        + SipSession.State.toString(mState);
-            } catch (Throwable e) {
-                return super.toString();
-            }
-        }
-
-        public boolean process(EventObject evt) throws SipException {
-            if (isLoggable(this, evt)) log(" ~~~~~   " + this + ": "
-                    + SipSession.State.toString(mState) + ": processing "
-                    + logEvt(evt));
-            synchronized (SipSessionGroup.this) {
-                if (isClosed()) return false;
-
-                if (mSipKeepAlive != null) {
-                    // event consumed by keepalive process
-                    if (mSipKeepAlive.process(evt)) return true;
-                }
-
-                Dialog dialog = null;
-                if (evt instanceof RequestEvent) {
-                    dialog = ((RequestEvent) evt).getDialog();
-                } else if (evt instanceof ResponseEvent) {
-                    dialog = ((ResponseEvent) evt).getDialog();
-                    extractExternalAddress((ResponseEvent) evt);
-                }
-                if (dialog != null) mDialog = dialog;
-
-                boolean processed;
-
-                switch (mState) {
-                case SipSession.State.REGISTERING:
-                case SipSession.State.DEREGISTERING:
-                    processed = registeringToReady(evt);
-                    break;
-                case SipSession.State.READY_TO_CALL:
-                    processed = readyForCall(evt);
-                    break;
-                case SipSession.State.INCOMING_CALL:
-                    processed = incomingCall(evt);
-                    break;
-                case SipSession.State.INCOMING_CALL_ANSWERING:
-                    processed = incomingCallToInCall(evt);
-                    break;
-                case SipSession.State.OUTGOING_CALL:
-                case SipSession.State.OUTGOING_CALL_RING_BACK:
-                    processed = outgoingCall(evt);
-                    break;
-                case SipSession.State.OUTGOING_CALL_CANCELING:
-                    processed = outgoingCallToReady(evt);
-                    break;
-                case SipSession.State.IN_CALL:
-                    processed = inCall(evt);
-                    break;
-                case SipSession.State.ENDING_CALL:
-                    processed = endingCall(evt);
-                    break;
-                default:
-                    processed = false;
-                }
-                return (processed || processExceptions(evt));
-            }
-        }
-
-        private boolean processExceptions(EventObject evt) throws SipException {
-            if (isRequestEvent(Request.BYE, evt)) {
-                // terminate the call whenever a BYE is received
-                mSipHelper.sendResponse((RequestEvent) evt, Response.OK);
-                endCallNormally();
-                return true;
-            } else if (isRequestEvent(Request.CANCEL, evt)) {
-                mSipHelper.sendResponse((RequestEvent) evt,
-                        Response.CALL_OR_TRANSACTION_DOES_NOT_EXIST);
-                return true;
-            } else if (evt instanceof TransactionTerminatedEvent) {
-                if (isCurrentTransaction((TransactionTerminatedEvent) evt)) {
-                    if (evt instanceof TimeoutEvent) {
-                        processTimeout((TimeoutEvent) evt);
-                    } else {
-                        processTransactionTerminated(
-                                (TransactionTerminatedEvent) evt);
-                    }
-                    return true;
-                }
-            } else if (isRequestEvent(Request.OPTIONS, evt)) {
-                mSipHelper.sendResponse((RequestEvent) evt, Response.OK);
-                return true;
-            } else if (evt instanceof DialogTerminatedEvent) {
-                processDialogTerminated((DialogTerminatedEvent) evt);
-                return true;
-            }
-            return false;
-        }
-
-        private void processDialogTerminated(DialogTerminatedEvent event) {
-            if (mDialog == event.getDialog()) {
-                onError(new SipException("dialog terminated"));
-            } else {
-                if (SSI_DBG) log("not the current dialog; current=" + mDialog
-                        + ", terminated=" + event.getDialog());
-            }
-        }
-
-        private boolean isCurrentTransaction(TransactionTerminatedEvent event) {
-            Transaction current = event.isServerTransaction()
-                    ? mServerTransaction
-                    : mClientTransaction;
-            Transaction target = event.isServerTransaction()
-                    ? event.getServerTransaction()
-                    : event.getClientTransaction();
-
-            if ((current != target) && (mState != SipSession.State.PINGING)) {
-                if (SSI_DBG) log("not the current transaction; current="
-                        + toString(current) + ", target=" + toString(target));
-                return false;
-            } else if (current != null) {
-                if (SSI_DBG) log("transaction terminated: " + toString(current));
-                return true;
-            } else {
-                // no transaction; shouldn't be here; ignored
-                return true;
-            }
-        }
-
-        private String toString(Transaction transaction) {
-            if (transaction == null) return "null";
-            Request request = transaction.getRequest();
-            Dialog dialog = transaction.getDialog();
-            CSeqHeader cseq = (CSeqHeader) request.getHeader(CSeqHeader.NAME);
-            return String.format("req=%s,%s,s=%s,ds=%s,", request.getMethod(),
-                    cseq.getSeqNumber(), transaction.getState(),
-                    ((dialog == null) ? "-" : dialog.getState()));
-        }
-
-        private void processTransactionTerminated(
-                TransactionTerminatedEvent event) {
-            switch (mState) {
-                case SipSession.State.IN_CALL:
-                case SipSession.State.READY_TO_CALL:
-                    if (SSI_DBG) log("Transaction terminated; do nothing");
-                    break;
-                default:
-                    if (SSI_DBG) log("Transaction terminated early: " + this);
-                    onError(SipErrorCode.TRANSACTION_TERMINTED,
-                            "transaction terminated");
-            }
-        }
-
-        private void processTimeout(TimeoutEvent event) {
-            if (SSI_DBG) log("processing Timeout...");
-            switch (mState) {
-                case SipSession.State.REGISTERING:
-                case SipSession.State.DEREGISTERING:
-                    reset();
-                    mProxy.onRegistrationTimeout(this);
-                    break;
-                case SipSession.State.INCOMING_CALL:
-                case SipSession.State.INCOMING_CALL_ANSWERING:
-                case SipSession.State.OUTGOING_CALL:
-                case SipSession.State.OUTGOING_CALL_CANCELING:
-                    onError(SipErrorCode.TIME_OUT, event.toString());
-                    break;
-
-                default:
-                    if (SSI_DBG) log("   do nothing");
-                    break;
-            }
-        }
-
-        private int getExpiryTime(Response response) {
-            int time = -1;
-            ContactHeader contact = (ContactHeader) response.getHeader(ContactHeader.NAME);
-            if (contact != null) {
-                time = contact.getExpires();
-            }
-            ExpiresHeader expires = (ExpiresHeader) response.getHeader(ExpiresHeader.NAME);
-            if (expires != null && (time < 0 || time > expires.getExpires())) {
-                time = expires.getExpires();
-            }
-            if (time <= 0) {
-                time = EXPIRY_TIME;
-            }
-            expires = (ExpiresHeader) response.getHeader(MinExpiresHeader.NAME);
-            if (expires != null && time < expires.getExpires()) {
-                time = expires.getExpires();
-            }
-            if (SSI_DBG) {
-                log("Expiry time = " + time);
-            }
-            return time;
-        }
-
-        private boolean registeringToReady(EventObject evt)
-                throws SipException {
-            if (expectResponse(Request.REGISTER, evt)) {
-                ResponseEvent event = (ResponseEvent) evt;
-                Response response = event.getResponse();
-
-                int statusCode = response.getStatusCode();
-                switch (statusCode) {
-                case Response.OK:
-                    int state = mState;
-                    onRegistrationDone((state == SipSession.State.REGISTERING)
-                            ? getExpiryTime(((ResponseEvent) evt).getResponse())
-                            : -1);
-                    return true;
-                case Response.UNAUTHORIZED:
-                case Response.PROXY_AUTHENTICATION_REQUIRED:
-                    handleAuthentication(event);
-                    return true;
-                default:
-                    if (statusCode >= 500) {
-                        onRegistrationFailed(response);
-                        return true;
-                    }
-                }
-            }
-            return false;
-        }
-
-        private boolean handleAuthentication(ResponseEvent event)
-                throws SipException {
-            Response response = event.getResponse();
-            String nonce = getNonceFromResponse(response);
-            if (nonce == null) {
-                onError(SipErrorCode.SERVER_ERROR,
-                        "server does not provide challenge");
-                return false;
-            } else if (mAuthenticationRetryCount < 2) {
-                mClientTransaction = mSipHelper.handleChallenge(
-                        event, getAccountManager());
-                mDialog = mClientTransaction.getDialog();
-                mAuthenticationRetryCount++;
-                if (isLoggable(this, event)) {
-                    if (SSI_DBG) log("   authentication retry count="
-                            + mAuthenticationRetryCount);
-                }
-                return true;
-            } else {
-                if (crossDomainAuthenticationRequired(response)) {
-                    onError(SipErrorCode.CROSS_DOMAIN_AUTHENTICATION,
-                            getRealmFromResponse(response));
-                } else {
-                    onError(SipErrorCode.INVALID_CREDENTIALS,
-                            "incorrect username or password");
-                }
-                return false;
-            }
-        }
-
-        private boolean crossDomainAuthenticationRequired(Response response) {
-            String realm = getRealmFromResponse(response);
-            if (realm == null) realm = "";
-            return !mLocalProfile.getSipDomain().trim().equals(realm.trim());
-        }
-
-        private AccountManager getAccountManager() {
-            return new AccountManager() {
-                @Override
-                public UserCredentials getCredentials(ClientTransaction
-                        challengedTransaction, String realm) {
-                    return new UserCredentials() {
-                        @Override
-                        public String getUserName() {
-                            String username = mLocalProfile.getAuthUserName();
-                            return (!TextUtils.isEmpty(username) ? username :
-                                    mLocalProfile.getUserName());
-                        }
-
-                        @Override
-                        public String getPassword() {
-                            return mPassword;
-                        }
-
-                        @Override
-                        public String getSipDomain() {
-                            return mLocalProfile.getSipDomain();
-                        }
-                    };
-                }
-            };
-        }
-
-        private String getRealmFromResponse(Response response) {
-            WWWAuthenticate wwwAuth = (WWWAuthenticate)response.getHeader(
-                    SIPHeaderNames.WWW_AUTHENTICATE);
-            if (wwwAuth != null) return wwwAuth.getRealm();
-            ProxyAuthenticate proxyAuth = (ProxyAuthenticate)response.getHeader(
-                    SIPHeaderNames.PROXY_AUTHENTICATE);
-            return (proxyAuth == null) ? null : proxyAuth.getRealm();
-        }
-
-        private String getNonceFromResponse(Response response) {
-            WWWAuthenticate wwwAuth = (WWWAuthenticate)response.getHeader(
-                    SIPHeaderNames.WWW_AUTHENTICATE);
-            if (wwwAuth != null) return wwwAuth.getNonce();
-            ProxyAuthenticate proxyAuth = (ProxyAuthenticate)response.getHeader(
-                    SIPHeaderNames.PROXY_AUTHENTICATE);
-            return (proxyAuth == null) ? null : proxyAuth.getNonce();
-        }
-
-        private String getResponseString(int statusCode) {
-            StatusLine statusLine = new StatusLine();
-            statusLine.setStatusCode(statusCode);
-            statusLine.setReasonPhrase(SIPResponse.getReasonPhrase(statusCode));
-            return statusLine.encode();
-        }
-
-        private boolean readyForCall(EventObject evt) throws SipException {
-            // expect MakeCallCommand, RegisterCommand, DEREGISTER
-            if (evt instanceof MakeCallCommand) {
-                mState = SipSession.State.OUTGOING_CALL;
-                MakeCallCommand cmd = (MakeCallCommand) evt;
-                mPeerProfile = cmd.getPeerProfile();
-                if (mReferSession != null) {
-                    mSipHelper.sendReferNotify(mReferSession.mDialog,
-                            getResponseString(Response.TRYING));
-                }
-                mClientTransaction = mSipHelper.sendInvite(
-                        mLocalProfile, mPeerProfile, cmd.getSessionDescription(),
-                        generateTag(), mReferredBy, mReplaces);
-                mDialog = mClientTransaction.getDialog();
-                addSipSession(this);
-                startSessionTimer(cmd.getTimeout());
-                mProxy.onCalling(this);
-                return true;
-            } else if (evt instanceof RegisterCommand) {
-                mState = SipSession.State.REGISTERING;
-                int duration = ((RegisterCommand) evt).getDuration();
-                mClientTransaction = mSipHelper.sendRegister(mLocalProfile,
-                        generateTag(), duration);
-                mDialog = mClientTransaction.getDialog();
-                addSipSession(this);
-                mProxy.onRegistering(this);
-                return true;
-            } else if (DEREGISTER == evt) {
-                mState = SipSession.State.DEREGISTERING;
-                mClientTransaction = mSipHelper.sendRegister(mLocalProfile,
-                        generateTag(), 0);
-                mDialog = mClientTransaction.getDialog();
-                addSipSession(this);
-                mProxy.onRegistering(this);
-                return true;
-            }
-            return false;
-        }
-
-        private boolean incomingCall(EventObject evt) throws SipException {
-            // expect MakeCallCommand(answering) , END_CALL cmd , Cancel
-            if (evt instanceof MakeCallCommand) {
-                // answer call
-                mState = SipSession.State.INCOMING_CALL_ANSWERING;
-                mServerTransaction = mSipHelper.sendInviteOk(mInviteReceived,
-                        mLocalProfile,
-                        ((MakeCallCommand) evt).getSessionDescription(),
-                        mServerTransaction,
-                        mExternalIp, mExternalPort);
-                startSessionTimer(((MakeCallCommand) evt).getTimeout());
-                return true;
-            } else if (END_CALL == evt) {
-                mSipHelper.sendInviteBusyHere(mInviteReceived,
-                        mServerTransaction);
-                endCallNormally();
-                return true;
-            } else if (isRequestEvent(Request.CANCEL, evt)) {
-                RequestEvent event = (RequestEvent) evt;
-                mSipHelper.sendResponse(event, Response.OK);
-                mSipHelper.sendInviteRequestTerminated(
-                        mInviteReceived.getRequest(), mServerTransaction);
-                endCallNormally();
-                return true;
-            }
-            return false;
-        }
-
-        private boolean incomingCallToInCall(EventObject evt) {
-            // expect ACK, CANCEL request
-            if (isRequestEvent(Request.ACK, evt)) {
-                String sdp = extractContent(((RequestEvent) evt).getRequest());
-                if (sdp != null) mPeerSessionDescription = sdp;
-                if (mPeerSessionDescription == null) {
-                    onError(SipErrorCode.CLIENT_ERROR, "peer sdp is empty");
-                } else {
-                    establishCall(false);
-                }
-                return true;
-            } else if (isRequestEvent(Request.CANCEL, evt)) {
-                // http://tools.ietf.org/html/rfc3261#section-9.2
-                // Final response has been sent; do nothing here.
-                return true;
-            }
-            return false;
-        }
-
-        private boolean outgoingCall(EventObject evt) throws SipException {
-            if (expectResponse(Request.INVITE, evt)) {
-                ResponseEvent event = (ResponseEvent) evt;
-                Response response = event.getResponse();
-
-                int statusCode = response.getStatusCode();
-                switch (statusCode) {
-                case Response.RINGING:
-                case Response.CALL_IS_BEING_FORWARDED:
-                case Response.QUEUED:
-                case Response.SESSION_PROGRESS:
-                    // feedback any provisional responses (except TRYING) as
-                    // ring back for better UX
-                    if (mState == SipSession.State.OUTGOING_CALL) {
-                        mState = SipSession.State.OUTGOING_CALL_RING_BACK;
-                        cancelSessionTimer();
-                        mProxy.onRingingBack(this);
-                    }
-                    return true;
-                case Response.OK:
-                    if (mReferSession != null) {
-                        mSipHelper.sendReferNotify(mReferSession.mDialog,
-                                getResponseString(Response.OK));
-                        // since we don't need to remember the session anymore.
-                        mReferSession = null;
-                    }
-                    mSipHelper.sendInviteAck(event, mDialog);
-                    mPeerSessionDescription = extractContent(response);
-                    establishCall(true);
-                    return true;
-                case Response.UNAUTHORIZED:
-                case Response.PROXY_AUTHENTICATION_REQUIRED:
-                    if (handleAuthentication(event)) {
-                        addSipSession(this);
-                    }
-                    return true;
-                case Response.REQUEST_PENDING:
-                    // TODO: rfc3261#section-14.1; re-schedule invite
-                    return true;
-                default:
-                    if (mReferSession != null) {
-                        mSipHelper.sendReferNotify(mReferSession.mDialog,
-                                getResponseString(Response.SERVICE_UNAVAILABLE));
-                    }
-                    if (statusCode >= 400) {
-                        // error: an ack is sent automatically by the stack
-                        onError(response);
-                        return true;
-                    } else if (statusCode >= 300) {
-                        // TODO: handle 3xx (redirect)
-                    } else {
-                        return true;
-                    }
-                }
-                return false;
-            } else if (END_CALL == evt) {
-                // RFC says that UA should not send out cancel when no
-                // response comes back yet. We are cheating for not checking
-                // response.
-                mState = SipSession.State.OUTGOING_CALL_CANCELING;
-                mSipHelper.sendCancel(mClientTransaction);
-                startSessionTimer(CANCEL_CALL_TIMER);
-                return true;
-            } else if (isRequestEvent(Request.INVITE, evt)) {
-                // Call self? Send BUSY HERE so server may redirect the call to
-                // voice mailbox.
-                RequestEvent event = (RequestEvent) evt;
-                mSipHelper.sendInviteBusyHere(event,
-                        event.getServerTransaction());
-                return true;
-            }
-            return false;
-        }
-
-        private boolean outgoingCallToReady(EventObject evt)
-                throws SipException {
-            if (evt instanceof ResponseEvent) {
-                ResponseEvent event = (ResponseEvent) evt;
-                Response response = event.getResponse();
-                int statusCode = response.getStatusCode();
-                if (expectResponse(Request.CANCEL, evt)) {
-                    if (statusCode == Response.OK) {
-                        // do nothing; wait for REQUEST_TERMINATED
-                        return true;
-                    }
-                } else if (expectResponse(Request.INVITE, evt)) {
-                    switch (statusCode) {
-                        case Response.OK:
-                            outgoingCall(evt); // abort Cancel
-                            return true;
-                        case Response.REQUEST_TERMINATED:
-                            endCallNormally();
-                            return true;
-                    }
-                } else {
-                    return false;
-                }
-
-                if (statusCode >= 400) {
-                    onError(response);
-                    return true;
-                }
-            } else if (evt instanceof TransactionTerminatedEvent) {
-                // rfc3261#section-14.1:
-                // if re-invite gets timed out, terminate the dialog; but
-                // re-invite is not reliable, just let it go and pretend
-                // nothing happened.
-                onError(new SipException("timed out"));
-            }
-            return false;
-        }
-
-        private boolean processReferRequest(RequestEvent event)
-                throws SipException {
-            try {
-                ReferToHeader referto = (ReferToHeader) event.getRequest()
-                        .getHeader(ReferTo.NAME);
-                Address address = referto.getAddress();
-                SipURI uri = (SipURI) address.getURI();
-                String replacesHeader = uri.getHeader(ReplacesHeader.NAME);
-                String username = uri.getUser();
-                if (username == null) {
-                    mSipHelper.sendResponse(event, Response.BAD_REQUEST);
-                    return false;
-                }
-                // send notify accepted
-                mSipHelper.sendResponse(event, Response.ACCEPTED);
-                SipSessionImpl newSession = createNewSession(event,
-                        this.mProxy.getListener(),
-                        mSipHelper.getServerTransaction(event),
-                        SipSession.State.READY_TO_CALL);
-                newSession.mReferSession = this;
-                newSession.mReferredBy = (ReferredByHeader) event.getRequest()
-                        .getHeader(ReferredByHeader.NAME);
-                newSession.mReplaces = replacesHeader;
-                newSession.mPeerProfile = createPeerProfile(referto);
-                newSession.mProxy.onCallTransferring(newSession,
-                        null);
-                return true;
-            } catch (IllegalArgumentException e) {
-                throw new SipException("createPeerProfile()", e);
-            }
-        }
-
-        private boolean inCall(EventObject evt) throws SipException {
-            // expect END_CALL cmd, BYE request, hold call (MakeCallCommand)
-            // OK retransmission is handled in SipStack
-            if (END_CALL == evt) {
-                // rfc3261#section-15.1.1
-                mState = SipSession.State.ENDING_CALL;
-                mSipHelper.sendBye(mDialog);
-                mProxy.onCallEnded(this);
-                startSessionTimer(END_CALL_TIMER);
-                return true;
-            } else if (isRequestEvent(Request.INVITE, evt)) {
-                // got Re-INVITE
-                mState = SipSession.State.INCOMING_CALL;
-                RequestEvent event = mInviteReceived = (RequestEvent) evt;
-                mPeerSessionDescription = extractContent(event.getRequest());
-                mServerTransaction = null;
-                mProxy.onRinging(this, mPeerProfile, mPeerSessionDescription);
-                return true;
-            } else if (isRequestEvent(Request.BYE, evt)) {
-                mSipHelper.sendResponse((RequestEvent) evt, Response.OK);
-                endCallNormally();
-                return true;
-            } else if (isRequestEvent(Request.REFER, evt)) {
-                return processReferRequest((RequestEvent) evt);
-            } else if (evt instanceof MakeCallCommand) {
-                // to change call
-                mState = SipSession.State.OUTGOING_CALL;
-                mClientTransaction = mSipHelper.sendReinvite(mDialog,
-                        ((MakeCallCommand) evt).getSessionDescription());
-                startSessionTimer(((MakeCallCommand) evt).getTimeout());
-                return true;
-            } else if (evt instanceof ResponseEvent) {
-                if (expectResponse(Request.NOTIFY, evt)) return true;
-            }
-            return false;
-        }
-
-        private boolean endingCall(EventObject evt) throws SipException {
-            if (expectResponse(Request.BYE, evt)) {
-                ResponseEvent event = (ResponseEvent) evt;
-                Response response = event.getResponse();
-
-                int statusCode = response.getStatusCode();
-                switch (statusCode) {
-                    case Response.UNAUTHORIZED:
-                    case Response.PROXY_AUTHENTICATION_REQUIRED:
-                        if (handleAuthentication(event)) {
-                            return true;
-                        } else {
-                            // can't authenticate; pass through to end session
-                        }
-                }
-                cancelSessionTimer();
-                reset();
-                return true;
-            }
-            return false;
-        }
-
-        // timeout in seconds
-        private void startSessionTimer(int timeout) {
-            if (timeout > 0) {
-                mSessionTimer = new SessionTimer();
-                mSessionTimer.start(timeout);
-            }
-        }
-
-        private void cancelSessionTimer() {
-            if (mSessionTimer != null) {
-                mSessionTimer.cancel();
-                mSessionTimer = null;
-            }
-        }
-
-        private String createErrorMessage(Response response) {
-            return String.format("%s (%d)", response.getReasonPhrase(),
-                    response.getStatusCode());
-        }
-
-        private void enableKeepAlive() {
-            if (mSipSessionImpl != null) {
-                mSipSessionImpl.stopKeepAliveProcess();
-            } else {
-                mSipSessionImpl = duplicate();
-            }
-            try {
-                mSipSessionImpl.startKeepAliveProcess(
-                        INCALL_KEEPALIVE_INTERVAL, mPeerProfile, null);
-            } catch (SipException e) {
-                loge("keepalive cannot be enabled; ignored", e);
-                mSipSessionImpl.stopKeepAliveProcess();
-            }
-        }
-
-        private void establishCall(boolean enableKeepAlive) {
-            mState = SipSession.State.IN_CALL;
-            cancelSessionTimer();
-            if (!mInCall && enableKeepAlive) enableKeepAlive();
-            mInCall = true;
-            mProxy.onCallEstablished(this, mPeerSessionDescription);
-        }
-
-        private void endCallNormally() {
-            reset();
-            mProxy.onCallEnded(this);
-        }
-
-        private void endCallOnError(int errorCode, String message) {
-            reset();
-            mProxy.onError(this, errorCode, message);
-        }
-
-        private void endCallOnBusy() {
-            reset();
-            mProxy.onCallBusy(this);
-        }
-
-        private void onError(int errorCode, String message) {
-            cancelSessionTimer();
-            switch (mState) {
-                case SipSession.State.REGISTERING:
-                case SipSession.State.DEREGISTERING:
-                    onRegistrationFailed(errorCode, message);
-                    break;
-                default:
-                    endCallOnError(errorCode, message);
-            }
-        }
-
-
-        private void onError(Throwable exception) {
-            exception = getRootCause(exception);
-            onError(getErrorCode(exception), exception.toString());
-        }
-
-        private void onError(Response response) {
-            int statusCode = response.getStatusCode();
-            if (!mInCall && (statusCode == Response.BUSY_HERE)) {
-                endCallOnBusy();
-            } else {
-                onError(getErrorCode(statusCode), createErrorMessage(response));
-            }
-        }
-
-        private int getErrorCode(int responseStatusCode) {
-            switch (responseStatusCode) {
-                case Response.TEMPORARILY_UNAVAILABLE:
-                case Response.FORBIDDEN:
-                case Response.GONE:
-                case Response.NOT_FOUND:
-                case Response.NOT_ACCEPTABLE:
-                case Response.NOT_ACCEPTABLE_HERE:
-                    return SipErrorCode.PEER_NOT_REACHABLE;
-
-                case Response.REQUEST_URI_TOO_LONG:
-                case Response.ADDRESS_INCOMPLETE:
-                case Response.AMBIGUOUS:
-                    return SipErrorCode.INVALID_REMOTE_URI;
-
-                case Response.REQUEST_TIMEOUT:
-                    return SipErrorCode.TIME_OUT;
-
-                default:
-                    if (responseStatusCode < 500) {
-                        return SipErrorCode.CLIENT_ERROR;
-                    } else {
-                        return SipErrorCode.SERVER_ERROR;
-                    }
-            }
-        }
-
-        private int getErrorCode(Throwable exception) {
-            String message = exception.getMessage();
-            if (exception instanceof UnknownHostException) {
-                return SipErrorCode.SERVER_UNREACHABLE;
-            } else if (exception instanceof IOException) {
-                return SipErrorCode.SOCKET_ERROR;
-            } else {
-                return SipErrorCode.CLIENT_ERROR;
-            }
-        }
-
-        private void onRegistrationDone(int duration) {
-            reset();
-            mProxy.onRegistrationDone(this, duration);
-        }
-
-        private void onRegistrationFailed(int errorCode, String message) {
-            reset();
-            mProxy.onRegistrationFailed(this, errorCode, message);
-        }
-
-        private void onRegistrationFailed(Response response) {
-            int statusCode = response.getStatusCode();
-            onRegistrationFailed(getErrorCode(statusCode),
-                    createErrorMessage(response));
-        }
-
-        // Notes: SipSessionListener will be replaced by the keepalive process
-        // @param interval in seconds
-        public void startKeepAliveProcess(int interval,
-                KeepAliveProcessCallback callback) throws SipException {
-            synchronized (SipSessionGroup.this) {
-                startKeepAliveProcess(interval, mLocalProfile, callback);
-            }
-        }
-
-        // Notes: SipSessionListener will be replaced by the keepalive process
-        // @param interval in seconds
-        public void startKeepAliveProcess(int interval, SipProfile peerProfile,
-                KeepAliveProcessCallback callback) throws SipException {
-            synchronized (SipSessionGroup.this) {
-                if (mSipKeepAlive != null) {
-                    throw new SipException("Cannot create more than one "
-                            + "keepalive process in a SipSession");
-                }
-                mPeerProfile = peerProfile;
-                mSipKeepAlive = new SipKeepAlive();
-                mProxy.setListener(mSipKeepAlive);
-                mSipKeepAlive.start(interval, callback);
-            }
-        }
-
-        public void stopKeepAliveProcess() {
-            synchronized (SipSessionGroup.this) {
-                if (mSipKeepAlive != null) {
-                    mSipKeepAlive.stop();
-                    mSipKeepAlive = null;
-                }
-            }
-        }
-
-        class SipKeepAlive extends SipSessionAdapter implements Runnable {
-            private static final String SKA_TAG = "SipKeepAlive";
-            private static final boolean SKA_DBG = true;
-
-            private boolean mRunning = false;
-            private KeepAliveProcessCallback mCallback;
-
-            private boolean mPortChanged = false;
-            private int mRPort = 0;
-            private int mInterval; // just for debugging
-
-            // @param interval in seconds
-            void start(int interval, KeepAliveProcessCallback callback) {
-                if (mRunning) return;
-                mRunning = true;
-                mInterval = interval;
-                mCallback = new KeepAliveProcessCallbackProxy(callback);
-                mWakeupTimer.set(interval * 1000, this);
-                if (SKA_DBG) {
-                    log("start keepalive:"
-                            + mLocalProfile.getUriString());
-                }
-
-                // No need to run the first time in a separate thread for now
-                run();
-            }
-
-            // return true if the event is consumed
-            boolean process(EventObject evt) {
-                if (mRunning && (mState == SipSession.State.PINGING)) {
-                    if (evt instanceof ResponseEvent) {
-                        if (parseOptionsResult(evt)) {
-                            if (mPortChanged) {
-                                resetExternalAddress();
-                                stop();
-                            } else {
-                                cancelSessionTimer();
-                                removeSipSession(SipSessionImpl.this);
-                            }
-                            mCallback.onResponse(mPortChanged);
-                            return true;
-                        }
-                    }
-                }
-                return false;
-            }
-
-            // SipSessionAdapter
-            // To react to the session timeout event and network error.
-            @Override
-            public void onError(ISipSession session, int errorCode, String message) {
-                stop();
-                mCallback.onError(errorCode, message);
-            }
-
-            // SipWakeupTimer timeout handler
-            // To send out keepalive message.
-            @Override
-            public void run() {
-                synchronized (SipSessionGroup.this) {
-                    if (!mRunning) return;
-
-                    if (DBG_PING) {
-                        String peerUri = (mPeerProfile == null)
-                                ? "null"
-                                : mPeerProfile.getUriString();
-                        log("keepalive: " + mLocalProfile.getUriString()
-                                + " --> " + peerUri + ", interval=" + mInterval);
-                    }
-                    try {
-                        sendKeepAlive();
-                    } catch (Throwable t) {
-                        if (SKA_DBG) {
-                            loge("keepalive error: "
-                                    + mLocalProfile.getUriString(), getRootCause(t));
-                        }
-                        // It's possible that the keepalive process is being stopped
-                        // during session.sendKeepAlive() so need to check mRunning
-                        // again here.
-                        if (mRunning) SipSessionImpl.this.onError(t);
-                    }
-                }
-            }
-
-            void stop() {
-                synchronized (SipSessionGroup.this) {
-                    if (SKA_DBG) {
-                        log("stop keepalive:" + mLocalProfile.getUriString()
-                                + ",RPort=" + mRPort);
-                    }
-                    mRunning = false;
-                    mWakeupTimer.cancel(this);
-                    reset();
-                }
-            }
-
-            private void sendKeepAlive() throws SipException {
-                synchronized (SipSessionGroup.this) {
-                    mState = SipSession.State.PINGING;
-                    mClientTransaction = mSipHelper.sendOptions(
-                            mLocalProfile, mPeerProfile, generateTag());
-                    mDialog = mClientTransaction.getDialog();
-                    addSipSession(SipSessionImpl.this);
-
-                    startSessionTimer(KEEPALIVE_TIMEOUT);
-                    // when timed out, onError() will be called with SipErrorCode.TIME_OUT
-                }
-            }
-
-            private boolean parseOptionsResult(EventObject evt) {
-                if (expectResponse(Request.OPTIONS, evt)) {
-                    ResponseEvent event = (ResponseEvent) evt;
-                    int rPort = getRPortFromResponse(event.getResponse());
-                    if (rPort != -1) {
-                        if (mRPort == 0) mRPort = rPort;
-                        if (mRPort != rPort) {
-                            mPortChanged = true;
-                            if (SKA_DBG) log(String.format(
-                                    "rport is changed: %d <> %d", mRPort, rPort));
-                            mRPort = rPort;
-                        } else {
-                            if (SKA_DBG) log("rport is the same: " + rPort);
-                        }
-                    } else {
-                        if (SKA_DBG) log("peer did not respond rport");
-                    }
-                    return true;
-                }
-                return false;
-            }
-
-            private int getRPortFromResponse(Response response) {
-                ViaHeader viaHeader = (ViaHeader)(response.getHeader(
-                        SIPHeaderNames.VIA));
-                return (viaHeader == null) ? -1 : viaHeader.getRPort();
-            }
-
-            private void log(String s) {
-                Rlog.d(SKA_TAG, s);
-            }
-        }
-
-        private void log(String s) {
-            Rlog.d(SSI_TAG, s);
-        }
-    }
-
-    /**
-     * @return true if the event is a request event matching the specified
-     *      method; false otherwise
-     */
-    private static boolean isRequestEvent(String method, EventObject event) {
-        try {
-            if (event instanceof RequestEvent) {
-                RequestEvent requestEvent = (RequestEvent) event;
-                return method.equals(requestEvent.getRequest().getMethod());
-            }
-        } catch (Throwable e) {
-        }
-        return false;
-    }
-
-    private static String getCseqMethod(Message message) {
-        return ((CSeqHeader) message.getHeader(CSeqHeader.NAME)).getMethod();
-    }
-
-    /**
-     * @return true if the event is a response event and the CSeqHeader method
-     * match the given arguments; false otherwise
-     */
-    private static boolean expectResponse(
-            String expectedMethod, EventObject evt) {
-        if (evt instanceof ResponseEvent) {
-            ResponseEvent event = (ResponseEvent) evt;
-            Response response = event.getResponse();
-            return expectedMethod.equalsIgnoreCase(getCseqMethod(response));
-        }
-        return false;
-    }
-
-    private static SipProfile createPeerProfile(HeaderAddress header)
-            throws SipException {
-        try {
-            Address address = header.getAddress();
-            SipURI uri = (SipURI) address.getURI();
-            String username = uri.getUser();
-            if (username == null) username = ANONYMOUS;
-            int port = uri.getPort();
-            SipProfile.Builder builder =
-                    new SipProfile.Builder(username, uri.getHost())
-                    .setDisplayName(address.getDisplayName());
-            if (port > 0) builder.setPort(port);
-            return builder.build();
-        } catch (IllegalArgumentException e) {
-            throw new SipException("createPeerProfile()", e);
-        } catch (ParseException e) {
-            throw new SipException("createPeerProfile()", e);
-        }
-    }
-
-    private static boolean isLoggable(SipSessionImpl s) {
-        if (s != null) {
-            switch (s.mState) {
-                case SipSession.State.PINGING:
-                    return DBG_PING;
-            }
-        }
-        return DBG;
-    }
-
-    private static boolean isLoggable(EventObject evt) {
-        return isLoggable(null, evt);
-    }
-
-    private static boolean isLoggable(SipSessionImpl s, EventObject evt) {
-        if (!isLoggable(s)) return false;
-        if (evt == null) return false;
-
-        if (evt instanceof ResponseEvent) {
-            Response response = ((ResponseEvent) evt).getResponse();
-            if (Request.OPTIONS.equals(response.getHeader(CSeqHeader.NAME))) {
-                return DBG_PING;
-            }
-            return DBG;
-        } else if (evt instanceof RequestEvent) {
-            if (isRequestEvent(Request.OPTIONS, evt)) {
-                return DBG_PING;
-            }
-            return DBG;
-        }
-        return false;
-    }
-
-    private static String logEvt(EventObject evt) {
-        if (evt instanceof RequestEvent) {
-            return ((RequestEvent) evt).getRequest().toString();
-        } else if (evt instanceof ResponseEvent) {
-            return ((ResponseEvent) evt).getResponse().toString();
-        } else {
-            return evt.toString();
-        }
-    }
-
-    private class RegisterCommand extends EventObject {
-        private int mDuration;
-
-        public RegisterCommand(int duration) {
-            super(SipSessionGroup.this);
-            mDuration = duration;
-        }
-
-        public int getDuration() {
-            return mDuration;
-        }
-    }
-
-    private class MakeCallCommand extends EventObject {
-        private String mSessionDescription;
-        private int mTimeout; // in seconds
-
-        public MakeCallCommand(SipProfile peerProfile,
-                String sessionDescription, int timeout) {
-            super(peerProfile);
-            mSessionDescription = sessionDescription;
-            mTimeout = timeout;
-        }
-
-        public SipProfile getPeerProfile() {
-            return (SipProfile) getSource();
-        }
-
-        public String getSessionDescription() {
-            return mSessionDescription;
-        }
-
-        public int getTimeout() {
-            return mTimeout;
-        }
-    }
-
-    /** Class to help safely run KeepAliveProcessCallback in a different thread. */
-    static class KeepAliveProcessCallbackProxy implements KeepAliveProcessCallback {
-        private static final String KAPCP_TAG = "KeepAliveProcessCallbackProxy";
-        private KeepAliveProcessCallback mCallback;
-
-        KeepAliveProcessCallbackProxy(KeepAliveProcessCallback callback) {
-            mCallback = callback;
-        }
-
-        private void proxy(Runnable runnable) {
-            // One thread for each calling back.
-            // Note: Guarantee ordering if the issue becomes important. Currently,
-            // the chance of handling two callback events at a time is none.
-            new Thread(runnable, "SIP-KeepAliveProcessCallbackThread").start();
-        }
-
-        @Override
-        public void onResponse(final boolean portChanged) {
-            if (mCallback == null) return;
-            proxy(new Runnable() {
-                @Override
-                public void run() {
-                    try {
-                        mCallback.onResponse(portChanged);
-                    } catch (Throwable t) {
-                        loge("onResponse", t);
-                    }
-                }
-            });
-        }
-
-        @Override
-        public void onError(final int errorCode, final String description) {
-            if (mCallback == null) return;
-            proxy(new Runnable() {
-                @Override
-                public void run() {
-                    try {
-                        mCallback.onError(errorCode, description);
-                    } catch (Throwable t) {
-                        loge("onError", t);
-                    }
-                }
-            });
-        }
-
-        private void loge(String s, Throwable t) {
-            Rlog.e(KAPCP_TAG, s, t);
-        }
-    }
-
-    private void log(String s) {
-        Rlog.d(TAG, s);
-    }
-
-    private void loge(String s, Throwable t) {
-        Rlog.e(TAG, s, t);
-    }
-}
diff --git a/voip/java/com/android/server/sip/SipSessionListenerProxy.java b/voip/java/com/android/server/sip/SipSessionListenerProxy.java
deleted file mode 100644
index 7a4ae8d..0000000
--- a/voip/java/com/android/server/sip/SipSessionListenerProxy.java
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-package com.android.server.sip;
-
-import android.net.sip.ISipSession;
-import android.net.sip.ISipSessionListener;
-import android.net.sip.SipProfile;
-import android.os.DeadObjectException;
-import android.telephony.Rlog;
-
-/** Class to help safely run a callback in a different thread. */
-class SipSessionListenerProxy extends ISipSessionListener.Stub {
-    private static final String TAG = "SipSessionListnerProxy";
-
-    private ISipSessionListener mListener;
-
-    public void setListener(ISipSessionListener listener) {
-        mListener = listener;
-    }
-
-    public ISipSessionListener getListener() {
-        return mListener;
-    }
-
-    private void proxy(Runnable runnable) {
-        // One thread for each calling back.
-        // Note: Guarantee ordering if the issue becomes important. Currently,
-        // the chance of handling two callback events at a time is none.
-        new Thread(runnable, "SipSessionCallbackThread").start();
-    }
-
-    @Override
-    public void onCalling(final ISipSession session) {
-        if (mListener == null) return;
-        proxy(new Runnable() {
-            @Override
-            public void run() {
-                try {
-                    mListener.onCalling(session);
-                } catch (Throwable t) {
-                    handle(t, "onCalling()");
-                }
-            }
-        });
-    }
-
-    @Override
-    public void onRinging(final ISipSession session, final SipProfile caller,
-            final String sessionDescription) {
-        if (mListener == null) return;
-        proxy(new Runnable() {
-            @Override
-            public void run() {
-                try {
-                    mListener.onRinging(session, caller, sessionDescription);
-                } catch (Throwable t) {
-                    handle(t, "onRinging()");
-                }
-            }
-        });
-    }
-
-    @Override
-    public void onRingingBack(final ISipSession session) {
-        if (mListener == null) return;
-        proxy(new Runnable() {
-            @Override
-            public void run() {
-                try {
-                    mListener.onRingingBack(session);
-                } catch (Throwable t) {
-                    handle(t, "onRingingBack()");
-                }
-            }
-        });
-    }
-
-    @Override
-    public void onCallEstablished(final ISipSession session,
-            final String sessionDescription) {
-        if (mListener == null) return;
-        proxy(new Runnable() {
-            @Override
-            public void run() {
-                try {
-                    mListener.onCallEstablished(session, sessionDescription);
-                } catch (Throwable t) {
-                    handle(t, "onCallEstablished()");
-                }
-            }
-        });
-    }
-
-    @Override
-    public void onCallEnded(final ISipSession session) {
-        if (mListener == null) return;
-        proxy(new Runnable() {
-            @Override
-            public void run() {
-                try {
-                    mListener.onCallEnded(session);
-                } catch (Throwable t) {
-                    handle(t, "onCallEnded()");
-                }
-            }
-        });
-    }
-
-    @Override
-    public void onCallTransferring(final ISipSession newSession,
-            final String sessionDescription) {
-        if (mListener == null) return;
-        proxy(new Runnable() {
-            @Override
-            public void run() {
-                try {
-                    mListener.onCallTransferring(newSession, sessionDescription);
-                } catch (Throwable t) {
-                    handle(t, "onCallTransferring()");
-                }
-            }
-        });
-    }
-
-    @Override
-    public void onCallBusy(final ISipSession session) {
-        if (mListener == null) return;
-        proxy(new Runnable() {
-            @Override
-            public void run() {
-                try {
-                    mListener.onCallBusy(session);
-                } catch (Throwable t) {
-                    handle(t, "onCallBusy()");
-                }
-            }
-        });
-    }
-
-    @Override
-    public void onCallChangeFailed(final ISipSession session,
-            final int errorCode, final String message) {
-        if (mListener == null) return;
-        proxy(new Runnable() {
-            @Override
-            public void run() {
-                try {
-                    mListener.onCallChangeFailed(session, errorCode, message);
-                } catch (Throwable t) {
-                    handle(t, "onCallChangeFailed()");
-                }
-            }
-        });
-    }
-
-    @Override
-    public void onError(final ISipSession session, final int errorCode,
-            final String message) {
-        if (mListener == null) return;
-        proxy(new Runnable() {
-            @Override
-            public void run() {
-                try {
-                    mListener.onError(session, errorCode, message);
-                } catch (Throwable t) {
-                    handle(t, "onError()");
-                }
-            }
-        });
-    }
-
-    @Override
-    public void onRegistering(final ISipSession session) {
-        if (mListener == null) return;
-        proxy(new Runnable() {
-            @Override
-            public void run() {
-                try {
-                    mListener.onRegistering(session);
-                } catch (Throwable t) {
-                    handle(t, "onRegistering()");
-                }
-            }
-        });
-    }
-
-    @Override
-    public void onRegistrationDone(final ISipSession session,
-            final int duration) {
-        if (mListener == null) return;
-        proxy(new Runnable() {
-            @Override
-            public void run() {
-                try {
-                    mListener.onRegistrationDone(session, duration);
-                } catch (Throwable t) {
-                    handle(t, "onRegistrationDone()");
-                }
-            }
-        });
-    }
-
-    @Override
-    public void onRegistrationFailed(final ISipSession session,
-            final int errorCode, final String message) {
-        if (mListener == null) return;
-        proxy(new Runnable() {
-            @Override
-            public void run() {
-                try {
-                    mListener.onRegistrationFailed(session, errorCode, message);
-                } catch (Throwable t) {
-                    handle(t, "onRegistrationFailed()");
-                }
-            }
-        });
-    }
-
-    @Override
-    public void onRegistrationTimeout(final ISipSession session) {
-        if (mListener == null) return;
-        proxy(new Runnable() {
-            @Override
-            public void run() {
-                try {
-                    mListener.onRegistrationTimeout(session);
-                } catch (Throwable t) {
-                    handle(t, "onRegistrationTimeout()");
-                }
-            }
-        });
-    }
-
-    private void handle(Throwable t, String message) {
-        if (t instanceof DeadObjectException) {
-            mListener = null;
-            // This creates race but it's harmless. Just don't log the error
-            // when it happens.
-        } else if (mListener != null) {
-            loge(message, t);
-        }
-    }
-
-    private void log(String s) {
-        Rlog.d(TAG, s);
-    }
-
-    private void loge(String s, Throwable t) {
-        Rlog.e(TAG, s, t);
-    }
-}
diff --git a/voip/java/com/android/server/sip/SipWakeLock.java b/voip/java/com/android/server/sip/SipWakeLock.java
deleted file mode 100644
index b3fbb56..0000000
--- a/voip/java/com/android/server/sip/SipWakeLock.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-package com.android.server.sip;
-
-import android.os.PowerManager;
-import android.telephony.Rlog;
-
-import java.util.HashSet;
-
-class SipWakeLock {
-    private static final String TAG = "SipWakeLock";
-    private static final boolean DBG = false;
-    private PowerManager mPowerManager;
-    private PowerManager.WakeLock mWakeLock;
-    private PowerManager.WakeLock mTimerWakeLock;
-    private HashSet<Object> mHolders = new HashSet<Object>();
-
-    SipWakeLock(PowerManager powerManager) {
-        mPowerManager = powerManager;
-    }
-
-    synchronized void reset() {
-        if (DBG) log("reset count=" + mHolders.size());
-        mHolders.clear();
-        release(null);
-    }
-
-    synchronized void acquire(long timeout) {
-        if (mTimerWakeLock == null) {
-            mTimerWakeLock = mPowerManager.newWakeLock(
-                    PowerManager.PARTIAL_WAKE_LOCK, "SipWakeLock.timer");
-            mTimerWakeLock.setReferenceCounted(true);
-        }
-        mTimerWakeLock.acquire(timeout);
-    }
-
-    synchronized void acquire(Object holder) {
-        mHolders.add(holder);
-        if (mWakeLock == null) {
-            mWakeLock = mPowerManager.newWakeLock(
-                    PowerManager.PARTIAL_WAKE_LOCK, "SipWakeLock");
-        }
-        if (!mWakeLock.isHeld()) mWakeLock.acquire();
-        if (DBG) log("acquire count=" + mHolders.size());
-    }
-
-    synchronized void release(Object holder) {
-        mHolders.remove(holder);
-        if ((mWakeLock != null) && mHolders.isEmpty()
-                && mWakeLock.isHeld()) {
-            mWakeLock.release();
-        }
-        if (DBG) log("release count=" + mHolders.size());
-    }
-
-    private void log(String s) {
-        Rlog.d(TAG, s);
-    }
-}
diff --git a/voip/java/com/android/server/sip/SipWakeupTimer.java b/voip/java/com/android/server/sip/SipWakeupTimer.java
deleted file mode 100644
index 3ba43312..0000000
--- a/voip/java/com/android/server/sip/SipWakeupTimer.java
+++ /dev/null
@@ -1,336 +0,0 @@
-/*
- * Copyright (C) 2011, 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.
- */
-
-package com.android.server.sip;
-
-import android.app.AlarmManager;
-import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.SystemClock;
-import android.telephony.Rlog;
-
-import java.util.Comparator;
-import java.util.Iterator;
-import java.util.TreeSet;
-import java.util.concurrent.Executor;
-
-/**
- * Timer that can schedule events to occur even when the device is in sleep.
- */
-class SipWakeupTimer extends BroadcastReceiver {
-    private static final String TAG = "SipWakeupTimer";
-    private static final boolean DBG = SipService.DBG && true; // STOPSHIP if true
-    private static final String TRIGGER_TIME = "TriggerTime";
-
-    private Context mContext;
-    private AlarmManager mAlarmManager;
-
-    // runnable --> time to execute in SystemClock
-    private TreeSet<MyEvent> mEventQueue =
-            new TreeSet<MyEvent>(new MyEventComparator());
-
-    private PendingIntent mPendingIntent;
-
-    private Executor mExecutor;
-
-    public SipWakeupTimer(Context context, Executor executor) {
-        mContext = context;
-        mAlarmManager = (AlarmManager)
-                context.getSystemService(Context.ALARM_SERVICE);
-
-        IntentFilter filter = new IntentFilter(getAction());
-        context.registerReceiver(this, filter);
-        mExecutor = executor;
-    }
-
-    /**
-     * Stops the timer. No event can be scheduled after this method is called.
-     */
-    public synchronized void stop() {
-        mContext.unregisterReceiver(this);
-        if (mPendingIntent != null) {
-            mAlarmManager.cancel(mPendingIntent);
-            mPendingIntent = null;
-        }
-        mEventQueue.clear();
-        mEventQueue = null;
-    }
-
-    private boolean stopped() {
-        if (mEventQueue == null) {
-            if (DBG) log("Timer stopped");
-            return true;
-        } else {
-            return false;
-        }
-    }
-
-    private void cancelAlarm() {
-        mAlarmManager.cancel(mPendingIntent);
-        mPendingIntent = null;
-    }
-
-    private void recalculatePeriods() {
-        if (mEventQueue.isEmpty()) return;
-
-        MyEvent firstEvent = mEventQueue.first();
-        int minPeriod = firstEvent.mMaxPeriod;
-        long minTriggerTime = firstEvent.mTriggerTime;
-        for (MyEvent e : mEventQueue) {
-            e.mPeriod = e.mMaxPeriod / minPeriod * minPeriod;
-            int interval = (int) (e.mLastTriggerTime + e.mMaxPeriod
-                    - minTriggerTime);
-            interval = interval / minPeriod * minPeriod;
-            e.mTriggerTime = minTriggerTime + interval;
-        }
-        TreeSet<MyEvent> newQueue = new TreeSet<MyEvent>(
-                mEventQueue.comparator());
-        newQueue.addAll(mEventQueue);
-        mEventQueue.clear();
-        mEventQueue = newQueue;
-        if (DBG) {
-            log("queue re-calculated");
-            printQueue();
-        }
-    }
-
-    // Determines the period and the trigger time of the new event and insert it
-    // to the queue.
-    private void insertEvent(MyEvent event) {
-        long now = SystemClock.elapsedRealtime();
-        if (mEventQueue.isEmpty()) {
-            event.mTriggerTime = now + event.mPeriod;
-            mEventQueue.add(event);
-            return;
-        }
-        MyEvent firstEvent = mEventQueue.first();
-        int minPeriod = firstEvent.mPeriod;
-        if (minPeriod <= event.mMaxPeriod) {
-            event.mPeriod = event.mMaxPeriod / minPeriod * minPeriod;
-            int interval = event.mMaxPeriod;
-            interval -= (int) (firstEvent.mTriggerTime - now);
-            interval = interval / minPeriod * minPeriod;
-            event.mTriggerTime = firstEvent.mTriggerTime + interval;
-            mEventQueue.add(event);
-        } else {
-            long triggerTime = now + event.mPeriod;
-            if (firstEvent.mTriggerTime < triggerTime) {
-                event.mTriggerTime = firstEvent.mTriggerTime;
-                event.mLastTriggerTime -= event.mPeriod;
-            } else {
-                event.mTriggerTime = triggerTime;
-            }
-            mEventQueue.add(event);
-            recalculatePeriods();
-        }
-    }
-
-    /**
-     * Sets a periodic timer.
-     *
-     * @param period the timer period; in milli-second
-     * @param callback is called back when the timer goes off; the same callback
-     *      can be specified in multiple timer events
-     */
-    public synchronized void set(int period, Runnable callback) {
-        if (stopped()) return;
-
-        long now = SystemClock.elapsedRealtime();
-        MyEvent event = new MyEvent(period, callback, now);
-        insertEvent(event);
-
-        if (mEventQueue.first() == event) {
-            if (mEventQueue.size() > 1) cancelAlarm();
-            scheduleNext();
-        }
-
-        long triggerTime = event.mTriggerTime;
-        if (DBG) {
-            log("set: add event " + event + " scheduled on "
-                    + showTime(triggerTime) + " at " + showTime(now)
-                    + ", #events=" + mEventQueue.size());
-            printQueue();
-        }
-    }
-
-    /**
-     * Cancels all the timer events with the specified callback.
-     *
-     * @param callback the callback
-     */
-    public synchronized void cancel(Runnable callback) {
-        if (stopped() || mEventQueue.isEmpty()) return;
-        if (DBG) log("cancel:" + callback);
-
-        MyEvent firstEvent = mEventQueue.first();
-        for (Iterator<MyEvent> iter = mEventQueue.iterator();
-                iter.hasNext();) {
-            MyEvent event = iter.next();
-            if (event.mCallback == callback) {
-                iter.remove();
-                if (DBG) log("    cancel found:" + event);
-            }
-        }
-        if (mEventQueue.isEmpty()) {
-            cancelAlarm();
-        } else if (mEventQueue.first() != firstEvent) {
-            cancelAlarm();
-            firstEvent = mEventQueue.first();
-            firstEvent.mPeriod = firstEvent.mMaxPeriod;
-            firstEvent.mTriggerTime = firstEvent.mLastTriggerTime
-                    + firstEvent.mPeriod;
-            recalculatePeriods();
-            scheduleNext();
-        }
-        if (DBG) {
-            log("cancel: X");
-            printQueue();
-        }
-    }
-
-    private void scheduleNext() {
-        if (stopped() || mEventQueue.isEmpty()) return;
-
-        if (mPendingIntent != null) {
-            throw new RuntimeException("pendingIntent is not null!");
-        }
-
-        MyEvent event = mEventQueue.first();
-        Intent intent = new Intent(getAction());
-        intent.putExtra(TRIGGER_TIME, event.mTriggerTime);
-        PendingIntent pendingIntent = mPendingIntent =
-                PendingIntent.getBroadcast(mContext, 0, intent,
-                        PendingIntent.FLAG_UPDATE_CURRENT);
-        mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
-                event.mTriggerTime, pendingIntent);
-    }
-
-    @Override
-    public synchronized void onReceive(Context context, Intent intent) {
-        // This callback is already protected by AlarmManager's wake lock.
-        String action = intent.getAction();
-        if (getAction().equals(action)
-                && intent.getExtras().containsKey(TRIGGER_TIME)) {
-            mPendingIntent = null;
-            long triggerTime = intent.getLongExtra(TRIGGER_TIME, -1L);
-            execute(triggerTime);
-        } else {
-            log("onReceive: unrecognized intent: " + intent);
-        }
-    }
-
-    private void printQueue() {
-        int count = 0;
-        for (MyEvent event : mEventQueue) {
-            log("     " + event + ": scheduled at "
-                    + showTime(event.mTriggerTime) + ": last at "
-                    + showTime(event.mLastTriggerTime));
-            if (++count >= 5) break;
-        }
-        if (mEventQueue.size() > count) {
-            log("     .....");
-        } else if (count == 0) {
-            log("     <empty>");
-        }
-    }
-
-    private void execute(long triggerTime) {
-        if (DBG) log("time's up, triggerTime = "
-                + showTime(triggerTime) + ": " + mEventQueue.size());
-        if (stopped() || mEventQueue.isEmpty()) return;
-
-        for (MyEvent event : mEventQueue) {
-            if (event.mTriggerTime != triggerTime) continue;
-            if (DBG) log("execute " + event);
-
-            event.mLastTriggerTime = triggerTime;
-            event.mTriggerTime += event.mPeriod;
-
-            // run the callback in the handler thread to prevent deadlock
-            mExecutor.execute(event.mCallback);
-        }
-        if (DBG) {
-            log("after timeout execution");
-            printQueue();
-        }
-        scheduleNext();
-    }
-
-    private String getAction() {
-        return toString();
-    }
-
-    private String showTime(long time) {
-        int ms = (int) (time % 1000);
-        int s = (int) (time / 1000);
-        int m = s / 60;
-        s %= 60;
-        return String.format("%d.%d.%d", m, s, ms);
-    }
-
-    private static class MyEvent {
-        int mPeriod;
-        int mMaxPeriod;
-        long mTriggerTime;
-        long mLastTriggerTime;
-        Runnable mCallback;
-
-        MyEvent(int period, Runnable callback, long now) {
-            mPeriod = mMaxPeriod = period;
-            mCallback = callback;
-            mLastTriggerTime = now;
-        }
-
-        @Override
-        public String toString() {
-            String s = super.toString();
-            s = s.substring(s.indexOf("@"));
-            return s + ":" + (mPeriod / 1000) + ":" + (mMaxPeriod / 1000) + ":"
-                    + toString(mCallback);
-        }
-
-        private String toString(Object o) {
-            String s = o.toString();
-            int index = s.indexOf("$");
-            if (index > 0) s = s.substring(index + 1);
-            return s;
-        }
-    }
-
-    // Sort the events by mMaxPeriod so that the first event can be used to
-    // align events with larger periods
-    private static class MyEventComparator implements Comparator<MyEvent> {
-        @Override
-        public int compare(MyEvent e1, MyEvent e2) {
-            if (e1 == e2) return 0;
-            int diff = e1.mMaxPeriod - e2.mMaxPeriod;
-            if (diff == 0) diff = -1;
-            return diff;
-        }
-
-        @Override
-        public boolean equals(Object that) {
-            return (this == that);
-        }
-    }
-
-    private void log(String s) {
-        Rlog.d(TAG, s);
-    }
-}
diff --git a/voip/jni/rtp/AmrCodec.cpp b/voip/jni/rtp/AmrCodec.cpp
deleted file mode 100644
index e2d820e..0000000
--- a/voip/jni/rtp/AmrCodec.cpp
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * Copyrightm (C) 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 <string.h>
-
-#include "AudioCodec.h"
-
-#include "gsmamr_dec.h"
-#include "gsmamr_enc.h"
-
-namespace {
-
-const int gFrameBits[8] = {95, 103, 118, 134, 148, 159, 204, 244};
-
-//------------------------------------------------------------------------------
-
-// See RFC 4867 for the encoding details.
-
-class AmrCodec : public AudioCodec
-{
-public:
-    AmrCodec() {
-        if (AMREncodeInit(&mEncoder, &mSidSync, false)) {
-            mEncoder = NULL;
-        }
-        if (GSMInitDecode(&mDecoder, (Word8 *)"RTP")) {
-            mDecoder = NULL;
-        }
-    }
-
-    ~AmrCodec() {
-        if (mEncoder) {
-            AMREncodeExit(&mEncoder, &mSidSync);
-        }
-        if (mDecoder) {
-            GSMDecodeFrameExit(&mDecoder);
-        }
-    }
-
-    int set(int sampleRate, const char *fmtp);
-    int encode(void *payload, int16_t *samples);
-    int decode(int16_t *samples, int count, void *payload, int length);
-
-private:
-    void *mEncoder;
-    void *mSidSync;
-    void *mDecoder;
-
-    int mMode;
-    int mModeSet;
-    bool mOctetAligned;
-};
-
-int AmrCodec::set(int sampleRate, const char *fmtp)
-{
-    // These parameters are not supported.
-    if (strcasestr(fmtp, "crc=1") || strcasestr(fmtp, "robust-sorting=1") ||
-        strcasestr(fmtp, "interleaving=")) {
-        return -1;
-    }
-
-    // Handle mode-set and octet-align.
-    const char *modes = strcasestr(fmtp, "mode-set=");
-    if (modes) {
-        mMode = 0;
-        mModeSet = 0;
-        for (char c = *modes; c && c != ' '; c = *++modes) {
-            if (c >= '0' && c <= '7') {
-                int mode = c - '0';
-                if (mode > mMode) {
-                    mMode = mode;
-                }
-                mModeSet |= 1 << mode;
-            }
-        }
-    } else {
-        mMode = 7;
-        mModeSet = 0xFF;
-    }
-    mOctetAligned = (strcasestr(fmtp, "octet-align=1") != NULL);
-
-    // TODO: handle mode-change-*.
-
-    return (sampleRate == 8000 && mEncoder && mDecoder) ? 160 : -1;
-}
-
-int AmrCodec::encode(void *payload, int16_t *samples)
-{
-    unsigned char *bytes = (unsigned char *)payload;
-    Frame_Type_3GPP type;
-
-    int length = AMREncode(mEncoder, mSidSync, (Mode)mMode,
-        samples, bytes + 1, &type, AMR_TX_WMF);
-
-    if (type != mMode || length != (8 + gFrameBits[mMode] + 7) >> 3) {
-        return -1;
-    }
-
-    if (mOctetAligned) {
-        bytes[0] = 0xF0;
-        bytes[1] = (mMode << 3) | 0x04;
-        ++length;
-    } else {
-        // CMR = 15 (4-bit), F = 0 (1-bit), FT = mMode (4-bit), Q = 1 (1-bit).
-        bytes[0] = 0xFF;
-        bytes[1] = 0xC0 | (mMode << 1) | 1;
-
-        // Shift left 6 bits and update the length.
-        bytes[length + 1] = 0;
-        for (int i = 0; i <= length; ++i) {
-            bytes[i] = (bytes[i] << 6) | (bytes[i + 1] >> 2);
-        }
-        length = (10 + gFrameBits[mMode] + 7) >> 3;
-    }
-    return length;
-}
-
-int AmrCodec::decode(int16_t *samples, int count, void *payload, int length)
-{
-    unsigned char *bytes = (unsigned char *)payload;
-    Frame_Type_3GPP type;
-    if (length < 2) {
-        return -1;
-    }
-    int request = bytes[0] >> 4;
-
-    if (mOctetAligned) {
-        if ((bytes[1] & 0xC4) != 0x04) {
-            return -1;
-        }
-        type = (Frame_Type_3GPP)(bytes[1] >> 3);
-        if (length != (16 + gFrameBits[type] + 7) >> 3) {
-            return -1;
-        }
-        length -= 2;
-        bytes += 2;
-    } else {
-        if ((bytes[0] & 0x0C) || !(bytes[1] & 0x40)) {
-            return -1;
-        }
-        type = (Frame_Type_3GPP)((bytes[0] << 1 | bytes[1] >> 7) & 0x07);
-        if (length != (10 + gFrameBits[type] + 7) >> 3) {
-            return -1;
-        }
-
-        // Shift left 2 bits and update the length.
-        --length;
-        for (int i = 1; i < length; ++i) {
-            bytes[i] = (bytes[i] << 2) | (bytes[i + 1] >> 6);
-        }
-        bytes[length] <<= 2;
-        length = (gFrameBits[type] + 7) >> 3;
-        ++bytes;
-    }
-
-    if (AMRDecode(mDecoder, type, bytes, samples, MIME_IETF) != length) {
-        return -1;
-    }
-
-    // Handle CMR
-    if (request < 8 && request != mMode) {
-        for (int i = request; i >= 0; --i) {
-            if (mModeSet & (1 << i)) {
-                mMode = request;
-                break;
-            }
-        }
-    }
-
-    return 160;
-}
-
-//------------------------------------------------------------------------------
-
-// See RFC 3551 for the encoding details.
-
-class GsmEfrCodec : public AudioCodec
-{
-public:
-    GsmEfrCodec() {
-        if (AMREncodeInit(&mEncoder, &mSidSync, false)) {
-            mEncoder = NULL;
-        }
-        if (GSMInitDecode(&mDecoder, (Word8 *)"RTP")) {
-            mDecoder = NULL;
-        }
-    }
-
-    ~GsmEfrCodec() {
-        if (mEncoder) {
-            AMREncodeExit(&mEncoder, &mSidSync);
-        }
-        if (mDecoder) {
-            GSMDecodeFrameExit(&mDecoder);
-        }
-    }
-
-    int set(int sampleRate, const char *fmtp) {
-        return (sampleRate == 8000 && mEncoder && mDecoder) ? 160 : -1;
-    }
-
-    int encode(void *payload, int16_t *samples);
-    int decode(int16_t *samples, int count, void *payload, int length);
-
-private:
-    void *mEncoder;
-    void *mSidSync;
-    void *mDecoder;
-};
-
-int GsmEfrCodec::encode(void *payload, int16_t *samples)
-{
-    unsigned char *bytes = (unsigned char *)payload;
-    Frame_Type_3GPP type;
-
-    int length = AMREncode(mEncoder, mSidSync, MR122,
-        samples, bytes, &type, AMR_TX_WMF);
-
-    if (type == AMR_122 && length == 32) {
-        bytes[0] = 0xC0 | (bytes[1] >> 4);
-        for (int i = 1; i < 31; ++i) {
-            bytes[i] = (bytes[i] << 4) | (bytes[i + 1] >> 4);
-        }
-        return 31;
-    }
-    return -1;
-}
-
-int GsmEfrCodec::decode(int16_t *samples, int count, void *payload, int length)
-{
-    unsigned char *bytes = (unsigned char *)payload;
-    int n = 0;
-    while (n + 160 <= count && length >= 31 && (bytes[0] >> 4) == 0x0C) {
-        for (int i = 0; i < 30; ++i) {
-            bytes[i] = (bytes[i] << 4) | (bytes[i + 1] >> 4);
-        }
-        bytes[30] <<= 4;
-
-        if (AMRDecode(mDecoder, AMR_122, bytes, &samples[n], MIME_IETF) != 31) {
-            break;
-        }
-        n += 160;
-        length -= 31;
-        bytes += 31;
-    }
-    return n;
-}
-
-} // namespace
-
-AudioCodec *newAmrCodec()
-{
-    return new AmrCodec;
-}
-
-AudioCodec *newGsmEfrCodec()
-{
-    return new GsmEfrCodec;
-}
diff --git a/voip/jni/rtp/Android.mk b/voip/jni/rtp/Android.mk
deleted file mode 100644
index b265cdd..0000000
--- a/voip/jni/rtp/Android.mk
+++ /dev/null
@@ -1,59 +0,0 @@
-#
-# Copyright (C) 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.
-#
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := librtp_jni
-
-LOCAL_SRC_FILES := \
-	AudioCodec.cpp \
-	AudioGroup.cpp \
-	EchoSuppressor.cpp \
-	RtpStream.cpp \
-	util.cpp \
-	rtp_jni.cpp
-
-LOCAL_SRC_FILES += \
-	AmrCodec.cpp \
-	G711Codec.cpp \
-	GsmCodec.cpp
-
-LOCAL_SHARED_LIBRARIES := \
-	libnativehelper \
-	libcutils \
-	libutils \
-	libmedia \
-	libstagefright_amrnb_common
-
-LOCAL_STATIC_LIBRARIES := libgsm libstagefright_amrnbdec libstagefright_amrnbenc
-
-LOCAL_C_INCLUDES += \
-	$(JNI_H_INCLUDE) \
-	external/libgsm/inc \
-	frameworks/av/media/libstagefright/codecs/amrnb/common/include \
-	frameworks/av/media/libstagefright/codecs/amrnb/common/ \
-	frameworks/av/media/libstagefright/codecs/amrnb/enc/include \
-	frameworks/av/media/libstagefright/codecs/amrnb/enc/src \
-	frameworks/av/media/libstagefright/codecs/amrnb/dec/include \
-	frameworks/av/media/libstagefright/codecs/amrnb/dec/src \
-	$(call include-path-for, audio-effects)
-
-LOCAL_CFLAGS += -fvisibility=hidden
-
-
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/voip/jni/rtp/AudioCodec.cpp b/voip/jni/rtp/AudioCodec.cpp
deleted file mode 100644
index c75fbc9..0000000
--- a/voip/jni/rtp/AudioCodec.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyrightm (C) 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 <strings.h>
-
-#include "AudioCodec.h"
-
-extern AudioCodec *newAlawCodec();
-extern AudioCodec *newUlawCodec();
-extern AudioCodec *newGsmCodec();
-extern AudioCodec *newAmrCodec();
-extern AudioCodec *newGsmEfrCodec();
-
-struct AudioCodecType {
-    const char *name;
-    AudioCodec *(*create)();
-} gAudioCodecTypes[] = {
-    {"PCMA", newAlawCodec},
-    {"PCMU", newUlawCodec},
-    {"GSM", newGsmCodec},
-    {"AMR", newAmrCodec},
-    {"GSM-EFR", newGsmEfrCodec},
-    {NULL, NULL},
-};
-
-AudioCodec *newAudioCodec(const char *codecName)
-{
-    AudioCodecType *type = gAudioCodecTypes;
-    while (type->name != NULL) {
-        if (strcasecmp(codecName, type->name) == 0) {
-            AudioCodec *codec = type->create();
-            codec->name = type->name;
-            return codec;
-        }
-        ++type;
-    }
-    return NULL;
-}
diff --git a/voip/jni/rtp/AudioCodec.h b/voip/jni/rtp/AudioCodec.h
deleted file mode 100644
index 741730b..0000000
--- a/voip/jni/rtp/AudioCodec.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyrightm (C) 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 <stdint.h>
-
-#ifndef __AUDIO_CODEC_H__
-#define __AUDIO_CODEC_H__
-
-class AudioCodec
-{
-public:
-    const char *name;
-    // Needed by destruction through base class pointers.
-    virtual ~AudioCodec() {}
-    // Returns sampleCount or non-positive value if unsupported.
-    virtual int set(int sampleRate, const char *fmtp) = 0;
-    // Returns the length of payload in bytes.
-    virtual int encode(void *payload, int16_t *samples) = 0;
-    // Returns the number of decoded samples.
-    virtual int decode(int16_t *samples, int count, void *payload, int length) = 0;
-};
-
-AudioCodec *newAudioCodec(const char *codecName);
-
-#endif
diff --git a/voip/jni/rtp/AudioGroup.cpp b/voip/jni/rtp/AudioGroup.cpp
deleted file mode 100644
index 2f0829e..0000000
--- a/voip/jni/rtp/AudioGroup.cpp
+++ /dev/null
@@ -1,1073 +0,0 @@
-/*
- * Copyright (C) 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 <stdio.h>
-#include <stdint.h>
-#include <string.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/epoll.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <time.h>
-#include <arpa/inet.h>
-#include <netinet/in.h>
-
-// #define LOG_NDEBUG 0
-#define LOG_TAG "AudioGroup"
-#include <cutils/atomic.h>
-#include <cutils/properties.h>
-#include <utils/Log.h>
-#include <utils/Errors.h>
-#include <utils/RefBase.h>
-#include <utils/threads.h>
-#include <utils/SystemClock.h>
-#include <media/AudioSystem.h>
-#include <media/AudioRecord.h>
-#include <media/AudioTrack.h>
-#include <media/mediarecorder.h>
-#include <media/AudioEffect.h>
-#include <audio_effects/effect_aec.h>
-#include <system/audio.h>
-
-#include "jni.h"
-#include "JNIHelp.h"
-
-#include "AudioCodec.h"
-#include "EchoSuppressor.h"
-
-extern int parse(JNIEnv *env, jstring jAddress, int port, sockaddr_storage *ss);
-
-namespace {
-
-using namespace android;
-
-int gRandom = -1;
-
-// We use a circular array to implement jitter buffer. The simplest way is doing
-// a modulo operation on the index while accessing the array. However modulo can
-// be expensive on some platforms, such as ARM. Thus we round up the size of the
-// array to the nearest power of 2 and then use bitwise-and instead of modulo.
-// Currently we make it 2048ms long and assume packet interval is 50ms or less.
-// The first 100ms is the place where samples get mixed. The rest is the real
-// jitter buffer. For a stream at 8000Hz it takes 32 kilobytes. These numbers
-// are chosen by experiments and each of them can be adjusted as needed.
-
-// Originally a stream does not send packets when it is receive-only or there is
-// nothing to mix. However, this causes some problems with certain firewalls and
-// proxies. A firewall might remove a port mapping when there is no outgoing
-// packet for a preiod of time, and a proxy might wait for incoming packets from
-// both sides before start forwarding. To solve these problems, we send out a
-// silence packet on the stream for every second. It should be good enough to
-// keep the stream alive with relatively low resources.
-
-// Other notes:
-// + We use elapsedRealtime() to get the time. Since we use 32bit variables
-//   instead of 64bit ones, comparison must be done by subtraction.
-// + Sampling rate must be multiple of 1000Hz, and packet length must be in
-//   milliseconds. No floating points.
-// + If we cannot get enough CPU, we drop samples and simulate packet loss.
-// + Resampling is not done yet, so streams in one group must use the same rate.
-//   For the first release only 8000Hz is supported.
-
-#define BUFFER_SIZE     2048
-#define HISTORY_SIZE    100
-#define MEASURE_BASE    100
-#define MEASURE_PERIOD  5000
-#define DTMF_PERIOD     200
-
-class AudioStream
-{
-public:
-    AudioStream();
-    ~AudioStream();
-    bool set(int mode, int socket, sockaddr_storage *remote,
-        AudioCodec *codec, int sampleRate, int sampleCount,
-        int codecType, int dtmfType);
-
-    void sendDtmf(int event);
-    bool mix(int32_t *output, int head, int tail, int sampleRate);
-    void encode(int tick, AudioStream *chain);
-    void decode(int tick);
-
-private:
-    enum {
-        NORMAL = 0,
-        SEND_ONLY = 1,
-        RECEIVE_ONLY = 2,
-        LAST_MODE = 2,
-    };
-
-    int mMode;
-    int mSocket;
-    sockaddr_storage mRemote;
-    AudioCodec *mCodec;
-    uint32_t mCodecMagic;
-    uint32_t mDtmfMagic;
-    bool mFixRemote;
-
-    int mTick;
-    int mSampleRate;
-    int mSampleCount;
-    int mInterval;
-    int mKeepAlive;
-
-    int16_t *mBuffer;
-    int mBufferMask;
-    int mBufferHead;
-    int mBufferTail;
-    int mLatencyTimer;
-    int mLatencyScore;
-
-    uint16_t mSequence;
-    uint32_t mTimestamp;
-    uint32_t mSsrc;
-
-    int mDtmfEvent;
-    int mDtmfStart;
-
-    AudioStream *mNext;
-
-    friend class AudioGroup;
-};
-
-AudioStream::AudioStream()
-{
-    mSocket = -1;
-    mCodec = NULL;
-    mBuffer = NULL;
-    mNext = NULL;
-}
-
-AudioStream::~AudioStream()
-{
-    close(mSocket);
-    delete mCodec;
-    delete [] mBuffer;
-    ALOGD("stream[%d] is dead", mSocket);
-}
-
-bool AudioStream::set(int mode, int socket, sockaddr_storage *remote,
-    AudioCodec *codec, int sampleRate, int sampleCount,
-    int codecType, int dtmfType)
-{
-    if (mode < 0 || mode > LAST_MODE) {
-        return false;
-    }
-    mMode = mode;
-
-    mCodecMagic = (0x8000 | codecType) << 16;
-    mDtmfMagic = (dtmfType == -1) ? 0 : (0x8000 | dtmfType) << 16;
-
-    mTick = elapsedRealtime();
-    mSampleRate = sampleRate / 1000;
-    mSampleCount = sampleCount;
-    mInterval = mSampleCount / mSampleRate;
-
-    // Allocate jitter buffer.
-    for (mBufferMask = 8; mBufferMask < mSampleRate; mBufferMask <<= 1);
-    mBufferMask *= BUFFER_SIZE;
-    mBuffer = new int16_t[mBufferMask];
-    --mBufferMask;
-    mBufferHead = 0;
-    mBufferTail = 0;
-    mLatencyTimer = 0;
-    mLatencyScore = 0;
-
-    // Initialize random bits.
-    read(gRandom, &mSequence, sizeof(mSequence));
-    read(gRandom, &mTimestamp, sizeof(mTimestamp));
-    read(gRandom, &mSsrc, sizeof(mSsrc));
-
-    mDtmfEvent = -1;
-    mDtmfStart = 0;
-
-    // Only take over these things when succeeded.
-    mSocket = socket;
-    if (codec) {
-        mRemote = *remote;
-        mCodec = codec;
-
-        // Here we should never get an private address, but some buggy proxy
-        // servers do give us one. To solve this, we replace the address when
-        // the first time we successfully decode an incoming packet.
-        mFixRemote = false;
-        if (remote->ss_family == AF_INET) {
-            unsigned char *address =
-                (unsigned char *)&((sockaddr_in *)remote)->sin_addr;
-            if (address[0] == 10 ||
-                (address[0] == 172 && (address[1] >> 4) == 1) ||
-                (address[0] == 192 && address[1] == 168)) {
-                mFixRemote = true;
-            }
-        }
-    }
-
-    ALOGD("stream[%d] is configured as %s %dkHz %dms mode %d", mSocket,
-        (codec ? codec->name : "RAW"), mSampleRate, mInterval, mMode);
-    return true;
-}
-
-void AudioStream::sendDtmf(int event)
-{
-    if (mDtmfMagic != 0) {
-        mDtmfEvent = event << 24;
-        mDtmfStart = mTimestamp + mSampleCount;
-    }
-}
-
-bool AudioStream::mix(int32_t *output, int head, int tail, int sampleRate)
-{
-    if (mMode == SEND_ONLY) {
-        return false;
-    }
-
-    if (head - mBufferHead < 0) {
-        head = mBufferHead;
-    }
-    if (tail - mBufferTail > 0) {
-        tail = mBufferTail;
-    }
-    if (tail - head <= 0) {
-        return false;
-    }
-
-    head *= mSampleRate;
-    tail *= mSampleRate;
-
-    if (sampleRate == mSampleRate) {
-        for (int i = head; i - tail < 0; ++i) {
-            output[i - head] += mBuffer[i & mBufferMask];
-        }
-    } else {
-        // TODO: implement resampling.
-        return false;
-    }
-    return true;
-}
-
-void AudioStream::encode(int tick, AudioStream *chain)
-{
-    if (tick - mTick >= mInterval) {
-        // We just missed the train. Pretend that packets in between are lost.
-        int skipped = (tick - mTick) / mInterval;
-        mTick += skipped * mInterval;
-        mSequence += skipped;
-        mTimestamp += skipped * mSampleCount;
-        ALOGV("stream[%d] skips %d packets", mSocket, skipped);
-    }
-
-    tick = mTick;
-    mTick += mInterval;
-    ++mSequence;
-    mTimestamp += mSampleCount;
-
-    // If there is an ongoing DTMF event, send it now.
-    if (mMode != RECEIVE_ONLY && mDtmfEvent != -1) {
-        int duration = mTimestamp - mDtmfStart;
-        // Make sure duration is reasonable.
-        if (duration >= 0 && duration < mSampleRate * DTMF_PERIOD) {
-            duration += mSampleCount;
-            int32_t buffer[4] = {
-                htonl(mDtmfMagic | mSequence),
-                htonl(mDtmfStart),
-                mSsrc,
-                htonl(mDtmfEvent | duration),
-            };
-            if (duration >= mSampleRate * DTMF_PERIOD) {
-                buffer[3] |= htonl(1 << 23);
-                mDtmfEvent = -1;
-            }
-            sendto(mSocket, buffer, sizeof(buffer), MSG_DONTWAIT,
-                (sockaddr *)&mRemote, sizeof(mRemote));
-            return;
-        }
-        mDtmfEvent = -1;
-    }
-
-    int32_t buffer[mSampleCount + 3];
-    bool data = false;
-    if (mMode != RECEIVE_ONLY) {
-        // Mix all other streams.
-        memset(buffer, 0, sizeof(buffer));
-        while (chain) {
-            if (chain != this) {
-                data |= chain->mix(buffer, tick - mInterval, tick, mSampleRate);
-            }
-            chain = chain->mNext;
-        }
-    }
-
-    int16_t samples[mSampleCount];
-    if (data) {
-        // Saturate into 16 bits.
-        for (int i = 0; i < mSampleCount; ++i) {
-            int32_t sample = buffer[i];
-            if (sample < -32768) {
-                sample = -32768;
-            }
-            if (sample > 32767) {
-                sample = 32767;
-            }
-            samples[i] = sample;
-        }
-    } else {
-        if ((mTick ^ mKeepAlive) >> 10 == 0) {
-            return;
-        }
-        mKeepAlive = mTick;
-        memset(samples, 0, sizeof(samples));
-
-        if (mMode != RECEIVE_ONLY) {
-            ALOGV("stream[%d] no data", mSocket);
-        }
-    }
-
-    if (!mCodec) {
-        // Special case for device stream.
-        send(mSocket, samples, sizeof(samples), MSG_DONTWAIT);
-        return;
-    }
-
-    // Cook the packet and send it out.
-    buffer[0] = htonl(mCodecMagic | mSequence);
-    buffer[1] = htonl(mTimestamp);
-    buffer[2] = mSsrc;
-    int length = mCodec->encode(&buffer[3], samples);
-    if (length <= 0) {
-        ALOGV("stream[%d] encoder error", mSocket);
-        return;
-    }
-    sendto(mSocket, buffer, length + 12, MSG_DONTWAIT, (sockaddr *)&mRemote,
-        sizeof(mRemote));
-}
-
-void AudioStream::decode(int tick)
-{
-    char c;
-    if (mMode == SEND_ONLY) {
-        recv(mSocket, &c, 1, MSG_DONTWAIT);
-        return;
-    }
-
-    // Make sure mBufferHead and mBufferTail are reasonable.
-    if ((unsigned int)(tick + BUFFER_SIZE - mBufferHead) > BUFFER_SIZE * 2) {
-        mBufferHead = tick - HISTORY_SIZE;
-        mBufferTail = mBufferHead;
-    }
-
-    if (tick - mBufferHead > HISTORY_SIZE) {
-        // Throw away outdated samples.
-        mBufferHead = tick - HISTORY_SIZE;
-        if (mBufferTail - mBufferHead < 0) {
-            mBufferTail = mBufferHead;
-        }
-    }
-
-    // Adjust the jitter buffer if the latency keeps larger than the threshold
-    // in the measurement period.
-    int score = mBufferTail - tick - MEASURE_BASE;
-    if (mLatencyScore > score || mLatencyScore <= 0) {
-        mLatencyScore = score;
-        mLatencyTimer = tick;
-    } else if (tick - mLatencyTimer >= MEASURE_PERIOD) {
-        ALOGV("stream[%d] reduces latency of %dms", mSocket, mLatencyScore);
-        mBufferTail -= mLatencyScore;
-        mLatencyScore = -1;
-    }
-
-    int count = (BUFFER_SIZE - (mBufferTail - mBufferHead)) * mSampleRate;
-    if (count < mSampleCount) {
-        // Buffer overflow. Drop the packet.
-        ALOGV("stream[%d] buffer overflow", mSocket);
-        recv(mSocket, &c, 1, MSG_DONTWAIT);
-        return;
-    }
-
-    // Receive the packet and decode it.
-    int16_t samples[count];
-    if (!mCodec) {
-        // Special case for device stream.
-        count = recv(mSocket, samples, sizeof(samples),
-            MSG_TRUNC | MSG_DONTWAIT) >> 1;
-    } else {
-        __attribute__((aligned(4))) uint8_t buffer[2048];
-        sockaddr_storage remote;
-        socklen_t addrlen = sizeof(remote);
-
-        int length = recvfrom(mSocket, buffer, sizeof(buffer),
-            MSG_TRUNC | MSG_DONTWAIT, (sockaddr *)&remote, &addrlen);
-
-        // Do we need to check SSRC, sequence, and timestamp? They are not
-        // reliable but at least they can be used to identify duplicates?
-        if (length < 12 || length > (int)sizeof(buffer) ||
-            (ntohl(*(uint32_t *)buffer) & 0xC07F0000) != mCodecMagic) {
-            ALOGV("stream[%d] malformed packet", mSocket);
-            return;
-        }
-        int offset = 12 + ((buffer[0] & 0x0F) << 2);
-        if ((buffer[0] & 0x10) != 0) {
-            offset += 4 + (ntohs(*(uint16_t *)&buffer[offset + 2]) << 2);
-        }
-        if ((buffer[0] & 0x20) != 0) {
-            length -= buffer[length - 1];
-        }
-        length -= offset;
-        if (length >= 0) {
-            length = mCodec->decode(samples, count, &buffer[offset], length);
-        }
-        if (length > 0 && mFixRemote) {
-            mRemote = remote;
-            mFixRemote = false;
-        }
-        count = length;
-    }
-    if (count <= 0) {
-        ALOGV("stream[%d] decoder error", mSocket);
-        return;
-    }
-
-    if (tick - mBufferTail > 0) {
-        // Buffer underrun. Reset the jitter buffer.
-        ALOGV("stream[%d] buffer underrun", mSocket);
-        if (mBufferTail - mBufferHead <= 0) {
-            mBufferHead = tick + mInterval;
-            mBufferTail = mBufferHead;
-        } else {
-            int tail = (tick + mInterval) * mSampleRate;
-            for (int i = mBufferTail * mSampleRate; i - tail < 0; ++i) {
-                mBuffer[i & mBufferMask] = 0;
-            }
-            mBufferTail = tick + mInterval;
-        }
-    }
-
-    // Append to the jitter buffer.
-    int tail = mBufferTail * mSampleRate;
-    for (int i = 0; i < count; ++i) {
-        mBuffer[tail & mBufferMask] = samples[i];
-        ++tail;
-    }
-    mBufferTail += mInterval;
-}
-
-//------------------------------------------------------------------------------
-
-class AudioGroup
-{
-public:
-    AudioGroup();
-    ~AudioGroup();
-    bool set(int sampleRate, int sampleCount);
-
-    bool setMode(int mode);
-    bool sendDtmf(int event);
-    bool add(AudioStream *stream);
-    bool remove(AudioStream *stream);
-    bool platformHasAec() { return mPlatformHasAec; }
-
-private:
-    enum {
-        ON_HOLD = 0,
-        MUTED = 1,
-        NORMAL = 2,
-        ECHO_SUPPRESSION = 3,
-        LAST_MODE = 3,
-    };
-
-    bool checkPlatformAec();
-
-    AudioStream *mChain;
-    int mEventQueue;
-    volatile int mDtmfEvent;
-
-    int mMode;
-    int mSampleRate;
-    int mSampleCount;
-    int mDeviceSocket;
-    bool mPlatformHasAec;
-
-    class NetworkThread : public Thread
-    {
-    public:
-        NetworkThread(AudioGroup *group) : Thread(false), mGroup(group) {}
-
-        bool start()
-        {
-            if (run("Network", ANDROID_PRIORITY_AUDIO) != NO_ERROR) {
-                ALOGE("cannot start network thread");
-                return false;
-            }
-            return true;
-        }
-
-    private:
-        AudioGroup *mGroup;
-        bool threadLoop();
-    };
-    sp<NetworkThread> mNetworkThread;
-
-    class DeviceThread : public Thread
-    {
-    public:
-        DeviceThread(AudioGroup *group) : Thread(false), mGroup(group) {}
-
-        bool start()
-        {
-            if (run("Device", ANDROID_PRIORITY_AUDIO) != NO_ERROR) {
-                ALOGE("cannot start device thread");
-                return false;
-            }
-            return true;
-        }
-
-    private:
-        AudioGroup *mGroup;
-        bool threadLoop();
-    };
-    sp<DeviceThread> mDeviceThread;
-};
-
-AudioGroup::AudioGroup()
-{
-    mMode = ON_HOLD;
-    mChain = NULL;
-    mEventQueue = -1;
-    mDtmfEvent = -1;
-    mDeviceSocket = -1;
-    mNetworkThread = new NetworkThread(this);
-    mDeviceThread = new DeviceThread(this);
-    mPlatformHasAec = checkPlatformAec();
-}
-
-AudioGroup::~AudioGroup()
-{
-    mNetworkThread->requestExitAndWait();
-    mDeviceThread->requestExitAndWait();
-    close(mEventQueue);
-    close(mDeviceSocket);
-    while (mChain) {
-        AudioStream *next = mChain->mNext;
-        delete mChain;
-        mChain = next;
-    }
-    ALOGD("group[%d] is dead", mDeviceSocket);
-}
-
-bool AudioGroup::set(int sampleRate, int sampleCount)
-{
-    mEventQueue = epoll_create(2);
-    if (mEventQueue == -1) {
-        ALOGE("epoll_create: %s", strerror(errno));
-        return false;
-    }
-
-    mSampleRate = sampleRate;
-    mSampleCount = sampleCount;
-
-    // Create device socket.
-    int pair[2];
-    if (socketpair(AF_UNIX, SOCK_DGRAM, 0, pair)) {
-        ALOGE("socketpair: %s", strerror(errno));
-        return false;
-    }
-    mDeviceSocket = pair[0];
-
-    // Create device stream.
-    mChain = new AudioStream;
-    if (!mChain->set(AudioStream::NORMAL, pair[1], NULL, NULL,
-        sampleRate, sampleCount, -1, -1)) {
-        close(pair[1]);
-        ALOGE("cannot initialize device stream");
-        return false;
-    }
-
-    // Give device socket a reasonable timeout.
-    timeval tv;
-    tv.tv_sec = 0;
-    tv.tv_usec = 1000 * sampleCount / sampleRate * 500;
-    if (setsockopt(pair[0], SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv))) {
-        ALOGE("setsockopt: %s", strerror(errno));
-        return false;
-    }
-
-    // Add device stream into event queue.
-    epoll_event event;
-    event.events = EPOLLIN;
-    event.data.ptr = mChain;
-    if (epoll_ctl(mEventQueue, EPOLL_CTL_ADD, pair[1], &event)) {
-        ALOGE("epoll_ctl: %s", strerror(errno));
-        return false;
-    }
-
-    // Anything else?
-    ALOGD("stream[%d] joins group[%d]", pair[1], pair[0]);
-    return true;
-}
-
-bool AudioGroup::setMode(int mode)
-{
-    if (mode < 0 || mode > LAST_MODE) {
-        return false;
-    }
-    // FIXME: temporary code to overcome echo and mic gain issues on herring and tuna boards.
-    // Must be modified/removed when the root cause of the issue is fixed in the hardware or
-    // driver
-    char value[PROPERTY_VALUE_MAX];
-    property_get("ro.product.board", value, "");
-    if (mode == NORMAL &&
-            (!strcmp(value, "herring") || !strcmp(value, "tuna"))) {
-        mode = ECHO_SUPPRESSION;
-    }
-    if (mMode == mode) {
-        return true;
-    }
-
-    mDeviceThread->requestExitAndWait();
-    ALOGD("group[%d] switches from mode %d to %d", mDeviceSocket, mMode, mode);
-    mMode = mode;
-    return (mode == ON_HOLD) || mDeviceThread->start();
-}
-
-bool AudioGroup::sendDtmf(int event)
-{
-    if (event < 0 || event > 15) {
-        return false;
-    }
-
-    // DTMF is rarely used, so we try to make it as lightweight as possible.
-    // Using volatile might be dodgy, but using a pipe or pthread primitives
-    // or stop-set-restart threads seems too heavy. Will investigate later.
-    timespec ts;
-    ts.tv_sec = 0;
-    ts.tv_nsec = 100000000;
-    for (int i = 0; mDtmfEvent != -1 && i < 20; ++i) {
-        nanosleep(&ts, NULL);
-    }
-    if (mDtmfEvent != -1) {
-        return false;
-    }
-    mDtmfEvent = event;
-    nanosleep(&ts, NULL);
-    return true;
-}
-
-bool AudioGroup::add(AudioStream *stream)
-{
-    mNetworkThread->requestExitAndWait();
-
-    epoll_event event;
-    event.events = EPOLLIN;
-    event.data.ptr = stream;
-    if (epoll_ctl(mEventQueue, EPOLL_CTL_ADD, stream->mSocket, &event)) {
-        ALOGE("epoll_ctl: %s", strerror(errno));
-        return false;
-    }
-
-    stream->mNext = mChain->mNext;
-    mChain->mNext = stream;
-    if (!mNetworkThread->start()) {
-        // Only take over the stream when succeeded.
-        mChain->mNext = stream->mNext;
-        return false;
-    }
-
-    ALOGD("stream[%d] joins group[%d]", stream->mSocket, mDeviceSocket);
-    return true;
-}
-
-bool AudioGroup::remove(AudioStream *stream)
-{
-    mNetworkThread->requestExitAndWait();
-
-    for (AudioStream *chain = mChain; chain->mNext; chain = chain->mNext) {
-        if (chain->mNext == stream) {
-            if (epoll_ctl(mEventQueue, EPOLL_CTL_DEL, stream->mSocket, NULL)) {
-                ALOGE("epoll_ctl: %s", strerror(errno));
-                return false;
-            }
-            chain->mNext = stream->mNext;
-            ALOGD("stream[%d] leaves group[%d]", stream->mSocket, mDeviceSocket);
-            delete stream;
-            break;
-        }
-    }
-
-    // Do not start network thread if there is only one stream.
-    if (!mChain->mNext || !mNetworkThread->start()) {
-        return false;
-    }
-    return true;
-}
-
-bool AudioGroup::NetworkThread::threadLoop()
-{
-    AudioStream *chain = mGroup->mChain;
-    int tick = elapsedRealtime();
-    int deadline = tick + 10;
-    int count = 0;
-
-    for (AudioStream *stream = chain; stream; stream = stream->mNext) {
-        if (tick - stream->mTick >= 0) {
-            stream->encode(tick, chain);
-        }
-        if (deadline - stream->mTick > 0) {
-            deadline = stream->mTick;
-        }
-        ++count;
-    }
-
-    int event = mGroup->mDtmfEvent;
-    if (event != -1) {
-        for (AudioStream *stream = chain; stream; stream = stream->mNext) {
-            stream->sendDtmf(event);
-        }
-        mGroup->mDtmfEvent = -1;
-    }
-
-    deadline -= tick;
-    if (deadline < 1) {
-        deadline = 1;
-    }
-
-    epoll_event events[count];
-    count = epoll_wait(mGroup->mEventQueue, events, count, deadline);
-    if (count == -1) {
-        ALOGE("epoll_wait: %s", strerror(errno));
-        return false;
-    }
-    for (int i = 0; i < count; ++i) {
-        ((AudioStream *)events[i].data.ptr)->decode(tick);
-    }
-
-    return true;
-}
-
-bool AudioGroup::checkPlatformAec()
-{
-    effect_descriptor_t fxDesc;
-    uint32_t numFx;
-
-    if (AudioEffect::queryNumberEffects(&numFx) != NO_ERROR) {
-        return false;
-    }
-    for (uint32_t i = 0; i < numFx; i++) {
-        if (AudioEffect::queryEffect(i, &fxDesc) != NO_ERROR) {
-            continue;
-        }
-        if (memcmp(&fxDesc.type, FX_IID_AEC, sizeof(effect_uuid_t)) == 0) {
-            return true;
-        }
-    }
-    return false;
-}
-
-bool AudioGroup::DeviceThread::threadLoop()
-{
-    int mode = mGroup->mMode;
-    int sampleRate = mGroup->mSampleRate;
-    int sampleCount = mGroup->mSampleCount;
-    int deviceSocket = mGroup->mDeviceSocket;
-
-    // Find out the frame count for AudioTrack and AudioRecord.
-    size_t output = 0;
-    size_t input = 0;
-    if (AudioTrack::getMinFrameCount(&output, AUDIO_STREAM_VOICE_CALL,
-        sampleRate) != NO_ERROR || output <= 0 ||
-        AudioRecord::getMinFrameCount(&input, sampleRate,
-        AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_MONO) != NO_ERROR || input <= 0) {
-        ALOGE("cannot compute frame count");
-        return false;
-    }
-    ALOGD("reported frame count: output %d, input %d", output, input);
-
-    if (output < sampleCount * 2) {
-        output = sampleCount * 2;
-    }
-    if (input < sampleCount * 2) {
-        input = sampleCount * 2;
-    }
-    ALOGD("adjusted frame count: output %d, input %d", output, input);
-
-    // Initialize AudioTrack and AudioRecord.
-    AudioTrack track;
-    AudioRecord record;
-    if (track.set(AUDIO_STREAM_VOICE_CALL, sampleRate, AUDIO_FORMAT_PCM_16_BIT,
-                AUDIO_CHANNEL_OUT_MONO, output) != NO_ERROR ||
-            record.set(AUDIO_SOURCE_VOICE_COMMUNICATION, sampleRate, AUDIO_FORMAT_PCM_16_BIT,
-                AUDIO_CHANNEL_IN_MONO, input) != NO_ERROR) {
-        ALOGE("cannot initialize audio device");
-        return false;
-    }
-    ALOGD("latency: output %d, input %d", track.latency(), record.latency());
-
-    // Give device socket a reasonable buffer size.
-    setsockopt(deviceSocket, SOL_SOCKET, SO_RCVBUF, &output, sizeof(output));
-    setsockopt(deviceSocket, SOL_SOCKET, SO_SNDBUF, &output, sizeof(output));
-
-    // Drain device socket.
-    char c;
-    while (recv(deviceSocket, &c, 1, MSG_DONTWAIT) == 1);
-
-    // check if platform supports echo cancellation and do not active local echo suppression in
-    // this case
-    EchoSuppressor *echo = NULL;
-    AudioEffect *aec = NULL;
-    if (mode == ECHO_SUPPRESSION) {
-        if (mGroup->platformHasAec()) {
-            aec = new AudioEffect(FX_IID_AEC,
-                                    NULL,
-                                    0,
-                                    0,
-                                    0,
-                                    record.getSessionId(),
-                                    record.getInput());
-            status_t status = aec->initCheck();
-            if (status == NO_ERROR || status == ALREADY_EXISTS) {
-                aec->setEnabled(true);
-            } else {
-                delete aec;
-                aec = NULL;
-            }
-        }
-        // Create local echo suppressor if platform AEC cannot be used.
-        if (aec == NULL) {
-             echo = new EchoSuppressor(sampleCount,
-                                       (track.latency() + record.latency()) * sampleRate / 1000);
-        }
-    }
-    // Start AudioRecord before AudioTrack. This prevents AudioTrack from being
-    // disabled due to buffer underrun while waiting for AudioRecord.
-    if (mode != MUTED) {
-        record.start();
-        int16_t one;
-        record.read(&one, sizeof(one));
-    }
-    track.start();
-
-    while (!exitPending()) {
-        int16_t output[sampleCount];
-        if (recv(deviceSocket, output, sizeof(output), 0) <= 0) {
-            memset(output, 0, sizeof(output));
-        }
-
-        int16_t input[sampleCount];
-        int toWrite = sampleCount;
-        int toRead = (mode == MUTED) ? 0 : sampleCount;
-        int chances = 100;
-
-        while (--chances > 0 && (toWrite > 0 || toRead > 0)) {
-            if (toWrite > 0) {
-                AudioTrack::Buffer buffer;
-                buffer.frameCount = toWrite;
-
-                status_t status = track.obtainBuffer(&buffer, 1);
-                if (status == NO_ERROR) {
-                    int offset = sampleCount - toWrite;
-                    memcpy(buffer.i8, &output[offset], buffer.size);
-                    toWrite -= buffer.frameCount;
-                    track.releaseBuffer(&buffer);
-                } else if (status != TIMED_OUT && status != WOULD_BLOCK) {
-                    ALOGE("cannot write to AudioTrack");
-                    goto exit;
-                }
-            }
-
-            if (toRead > 0) {
-                AudioRecord::Buffer buffer;
-                buffer.frameCount = toRead;
-
-                status_t status = record.obtainBuffer(&buffer, 1);
-                if (status == NO_ERROR) {
-                    int offset = sampleCount - toRead;
-                    memcpy(&input[offset], buffer.i8, buffer.size);
-                    toRead -= buffer.frameCount;
-                    record.releaseBuffer(&buffer);
-                } else if (status != TIMED_OUT && status != WOULD_BLOCK) {
-                    ALOGE("cannot read from AudioRecord");
-                    goto exit;
-                }
-            }
-        }
-
-        if (chances <= 0) {
-            ALOGW("device loop timeout");
-            while (recv(deviceSocket, &c, 1, MSG_DONTWAIT) == 1);
-        }
-
-        if (mode != MUTED) {
-            if (echo != NULL) {
-                ALOGV("echo->run()");
-                echo->run(output, input);
-            }
-            send(deviceSocket, input, sizeof(input), MSG_DONTWAIT);
-        }
-    }
-
-exit:
-    delete echo;
-    delete aec;
-    return true;
-}
-
-//------------------------------------------------------------------------------
-
-static jfieldID gNative;
-static jfieldID gMode;
-
-int add(JNIEnv *env, jobject thiz, jint mode,
-    jint socket, jstring jRemoteAddress, jint remotePort,
-    jstring jCodecSpec, jint dtmfType)
-{
-    AudioCodec *codec = NULL;
-    AudioStream *stream = NULL;
-    AudioGroup *group = NULL;
-
-    // Sanity check.
-    sockaddr_storage remote;
-    if (parse(env, jRemoteAddress, remotePort, &remote) < 0) {
-        // Exception already thrown.
-        return 0;
-    }
-    if (!jCodecSpec) {
-        jniThrowNullPointerException(env, "codecSpec");
-        return 0;
-    }
-    const char *codecSpec = env->GetStringUTFChars(jCodecSpec, NULL);
-    if (!codecSpec) {
-        // Exception already thrown.
-        return 0;
-    }
-    socket = dup(socket);
-    if (socket == -1) {
-        jniThrowException(env, "java/lang/IllegalStateException",
-            "cannot get stream socket");
-        return 0;
-    }
-
-    // Create audio codec.
-    int codecType = -1;
-    char codecName[16];
-    int sampleRate = -1;
-    sscanf(codecSpec, "%d %15[^/]%*c%d", &codecType, codecName, &sampleRate);
-    codec = newAudioCodec(codecName);
-    int sampleCount = (codec ? codec->set(sampleRate, codecSpec) : -1);
-    env->ReleaseStringUTFChars(jCodecSpec, codecSpec);
-    if (sampleCount <= 0) {
-        jniThrowException(env, "java/lang/IllegalStateException",
-            "cannot initialize audio codec");
-        goto error;
-    }
-
-    // Create audio stream.
-    stream = new AudioStream;
-    if (!stream->set(mode, socket, &remote, codec, sampleRate, sampleCount,
-        codecType, dtmfType)) {
-        jniThrowException(env, "java/lang/IllegalStateException",
-            "cannot initialize audio stream");
-        goto error;
-    }
-    socket = -1;
-    codec = NULL;
-
-    // Create audio group.
-    group = (AudioGroup *)env->GetIntField(thiz, gNative);
-    if (!group) {
-        int mode = env->GetIntField(thiz, gMode);
-        group = new AudioGroup;
-        if (!group->set(8000, 256) || !group->setMode(mode)) {
-            jniThrowException(env, "java/lang/IllegalStateException",
-                "cannot initialize audio group");
-            goto error;
-        }
-    }
-
-    // Add audio stream into audio group.
-    if (!group->add(stream)) {
-        jniThrowException(env, "java/lang/IllegalStateException",
-            "cannot add audio stream");
-        goto error;
-    }
-
-    // Succeed.
-    env->SetIntField(thiz, gNative, (int)group);
-    return (int)stream;
-
-error:
-    delete group;
-    delete stream;
-    delete codec;
-    close(socket);
-    env->SetIntField(thiz, gNative, 0);
-    return 0;
-}
-
-void remove(JNIEnv *env, jobject thiz, jint stream)
-{
-    AudioGroup *group = (AudioGroup *)env->GetIntField(thiz, gNative);
-    if (group) {
-        if (!stream || !group->remove((AudioStream *)stream)) {
-            delete group;
-            env->SetIntField(thiz, gNative, 0);
-        }
-    }
-}
-
-void setMode(JNIEnv *env, jobject thiz, jint mode)
-{
-    AudioGroup *group = (AudioGroup *)env->GetIntField(thiz, gNative);
-    if (group && !group->setMode(mode)) {
-        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
-    }
-}
-
-void sendDtmf(JNIEnv *env, jobject thiz, jint event)
-{
-    AudioGroup *group = (AudioGroup *)env->GetIntField(thiz, gNative);
-    if (group && !group->sendDtmf(event)) {
-        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
-    }
-}
-
-JNINativeMethod gMethods[] = {
-    {"nativeAdd", "(IILjava/lang/String;ILjava/lang/String;I)I", (void *)add},
-    {"nativeRemove", "(I)V", (void *)remove},
-    {"nativeSetMode", "(I)V", (void *)setMode},
-    {"nativeSendDtmf", "(I)V", (void *)sendDtmf},
-};
-
-} // namespace
-
-int registerAudioGroup(JNIEnv *env)
-{
-    gRandom = open("/dev/urandom", O_RDONLY);
-    if (gRandom == -1) {
-        ALOGE("urandom: %s", strerror(errno));
-        return -1;
-    }
-
-    jclass clazz;
-    if ((clazz = env->FindClass("android/net/rtp/AudioGroup")) == NULL ||
-        (gNative = env->GetFieldID(clazz, "mNative", "I")) == NULL ||
-        (gMode = env->GetFieldID(clazz, "mMode", "I")) == NULL ||
-        env->RegisterNatives(clazz, gMethods, NELEM(gMethods)) < 0) {
-        ALOGE("JNI registration failed");
-        return -1;
-    }
-    return 0;
-}
diff --git a/voip/jni/rtp/EchoSuppressor.cpp b/voip/jni/rtp/EchoSuppressor.cpp
deleted file mode 100644
index e223136..0000000
--- a/voip/jni/rtp/EchoSuppressor.cpp
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * Copyrightm (C) 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 <stdio.h>
-#include <string.h>
-#include <stdint.h>
-#include <string.h>
-#include <math.h>
-
-#define LOG_TAG "Echo"
-#include <utils/Log.h>
-
-#include "EchoSuppressor.h"
-
-// It is very difficult to do echo cancellation at this level due to the lack of
-// the timing information of the samples being played and recorded. Therefore,
-// for the first release only echo suppression is implemented.
-
-// The algorithm is derived from the "previous works" summarized in
-//   A new class of doubletalk detectors based on cross-correlation,
-//   J Benesty, DR Morgan, JH Cho, IEEE Trans. on Speech and Audio Processing.
-// The method proposed in that paper is not used because of its high complexity.
-
-// It is well known that cross-correlation can be computed using convolution,
-// but unfortunately not every mobile processor has a (fast enough) FPU. Thus
-// we use integer arithmetic as much as possible and do lots of bookkeeping.
-// Again, parameters and thresholds are chosen by experiments.
-
-EchoSuppressor::EchoSuppressor(int sampleCount, int tailLength)
-{
-    tailLength += sampleCount * 4;
-
-    int shift = 0;
-    while ((sampleCount >> shift) > 1 && (tailLength >> shift) > 256) {
-        ++shift;
-    }
-
-    mShift = shift + 4;
-    mScale = 1 << shift;
-    mSampleCount = sampleCount;
-    mWindowSize = sampleCount >> shift;
-    mTailLength = tailLength >> shift;
-    mRecordLength = tailLength * 2 / sampleCount;
-    mRecordOffset = 0;
-
-    mXs = new uint16_t[mTailLength + mWindowSize];
-    memset(mXs, 0, sizeof(*mXs) * (mTailLength + mWindowSize));
-    mXSums = new uint32_t[mTailLength];
-    memset(mXSums, 0, sizeof(*mXSums) * mTailLength);
-    mX2Sums = new uint32_t[mTailLength];
-    memset(mX2Sums, 0, sizeof(*mX2Sums) * mTailLength);
-    mXRecords = new uint16_t[mRecordLength * mWindowSize];
-    memset(mXRecords, 0, sizeof(*mXRecords) * mRecordLength * mWindowSize);
-
-    mYSum = 0;
-    mY2Sum = 0;
-    mYRecords = new uint32_t[mRecordLength];
-    memset(mYRecords, 0, sizeof(*mYRecords) * mRecordLength);
-    mY2Records = new uint32_t[mRecordLength];
-    memset(mY2Records, 0, sizeof(*mY2Records) * mRecordLength);
-
-    mXYSums = new uint32_t[mTailLength];
-    memset(mXYSums, 0, sizeof(*mXYSums) * mTailLength);
-    mXYRecords = new uint32_t[mRecordLength * mTailLength];
-    memset(mXYRecords, 0, sizeof(*mXYRecords) * mRecordLength * mTailLength);
-
-    mLastX = 0;
-    mLastY = 0;
-    mWeight = 1.0f / (mRecordLength * mWindowSize);
-}
-
-EchoSuppressor::~EchoSuppressor()
-{
-    delete [] mXs;
-    delete [] mXSums;
-    delete [] mX2Sums;
-    delete [] mXRecords;
-    delete [] mYRecords;
-    delete [] mY2Records;
-    delete [] mXYSums;
-    delete [] mXYRecords;
-}
-
-void EchoSuppressor::run(int16_t *playbacked, int16_t *recorded)
-{
-    // Update Xs.
-    for (int i = mTailLength - 1; i >= 0; --i) {
-        mXs[i + mWindowSize] = mXs[i];
-    }
-    for (int i = mWindowSize - 1, j = 0; i >= 0; --i, j += mScale) {
-        uint32_t sum = 0;
-        for (int k = 0; k < mScale; ++k) {
-            int32_t x = playbacked[j + k] << 15;
-            mLastX += x;
-            sum += ((mLastX >= 0) ? mLastX : -mLastX) >> 15;
-            mLastX -= (mLastX >> 10) + x;
-        }
-        mXs[i] = sum >> mShift;
-    }
-
-    // Update XSums, X2Sums, and XRecords.
-    for (int i = mTailLength - mWindowSize - 1; i >= 0; --i) {
-        mXSums[i + mWindowSize] = mXSums[i];
-        mX2Sums[i + mWindowSize] = mX2Sums[i];
-    }
-    uint16_t *xRecords = &mXRecords[mRecordOffset * mWindowSize];
-    for (int i = mWindowSize - 1; i >= 0; --i) {
-        uint16_t x = mXs[i];
-        mXSums[i] = mXSums[i + 1] + x - xRecords[i];
-        mX2Sums[i] = mX2Sums[i + 1] + x * x - xRecords[i] * xRecords[i];
-        xRecords[i] = x;
-    }
-
-    // Compute Ys.
-    uint16_t ys[mWindowSize];
-    for (int i = mWindowSize - 1, j = 0; i >= 0; --i, j += mScale) {
-        uint32_t sum = 0;
-        for (int k = 0; k < mScale; ++k) {
-            int32_t y = recorded[j + k] << 15;
-            mLastY += y;
-            sum += ((mLastY >= 0) ? mLastY : -mLastY) >> 15;
-            mLastY -= (mLastY >> 10) + y;
-        }
-        ys[i] = sum >> mShift;
-    }
-
-    // Update YSum, Y2Sum, YRecords, and Y2Records.
-    uint32_t ySum = 0;
-    uint32_t y2Sum = 0;
-    for (int i = mWindowSize - 1; i >= 0; --i) {
-        ySum += ys[i];
-        y2Sum += ys[i] * ys[i];
-    }
-    mYSum += ySum - mYRecords[mRecordOffset];
-    mY2Sum += y2Sum - mY2Records[mRecordOffset];
-    mYRecords[mRecordOffset] = ySum;
-    mY2Records[mRecordOffset] = y2Sum;
-
-    // Update XYSums and XYRecords.
-    uint32_t *xyRecords = &mXYRecords[mRecordOffset * mTailLength];
-    for (int i = mTailLength - 1; i >= 0; --i) {
-        uint32_t xySum = 0;
-        for (int j = mWindowSize - 1; j >= 0; --j) {
-            xySum += mXs[i + j] * ys[j];
-        }
-        mXYSums[i] += xySum - xyRecords[i];
-        xyRecords[i] = xySum;
-    }
-
-    // Compute correlations.
-    int latency = 0;
-    float corr2 = 0.0f;
-    float varX = 0.0f;
-    float varY = mY2Sum - mWeight * mYSum * mYSum;
-    for (int i = mTailLength - 1; i >= 0; --i) {
-        float cov = mXYSums[i] - mWeight * mXSums[i] * mYSum;
-        if (cov > 0.0f) {
-            float varXi = mX2Sums[i] - mWeight * mXSums[i] * mXSums[i];
-            float corr2i = cov * cov / (varXi * varY + 1);
-            if (corr2i > corr2) {
-                varX = varXi;
-                corr2 = corr2i;
-                latency = i;
-            }
-        }
-    }
-    //ALOGI("corr^2 %.5f, var %8.0f %8.0f, latency %d", corr2, varX, varY,
-    //        latency * mScale);
-
-    // Do echo suppression.
-    if (corr2 > 0.1f && varX > 10000.0f) {
-        int factor = (corr2 > 1.0f) ? 0 : (1.0f - sqrtf(corr2)) * 4096;
-        for (int i = 0; i < mSampleCount; ++i) {
-            recorded[i] = recorded[i] * factor >> 16;
-        }
-    }
-
-    // Increase RecordOffset.
-    ++mRecordOffset;
-    if (mRecordOffset == mRecordLength) {
-        mRecordOffset = 0;
-    }
-}
diff --git a/voip/jni/rtp/EchoSuppressor.h b/voip/jni/rtp/EchoSuppressor.h
deleted file mode 100644
index 2f3b593..0000000
--- a/voip/jni/rtp/EchoSuppressor.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyrightm (C) 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.
- */
-
-#ifndef __ECHO_SUPPRESSOR_H__
-#define __ECHO_SUPPRESSOR_H__
-
-#include <stdint.h>
-
-class EchoSuppressor
-{
-public:
-    // The sampleCount must be power of 2.
-    EchoSuppressor(int sampleCount, int tailLength);
-    ~EchoSuppressor();
-    void run(int16_t *playbacked, int16_t *recorded);
-
-private:
-    int mShift;
-    int mScale;
-    int mSampleCount;
-    int mWindowSize;
-    int mTailLength;
-    int mRecordLength;
-    int mRecordOffset;
-
-    uint16_t *mXs;
-    uint32_t *mXSums;
-    uint32_t *mX2Sums;
-    uint16_t *mXRecords;
-
-    uint32_t mYSum;
-    uint32_t mY2Sum;
-    uint32_t *mYRecords;
-    uint32_t *mY2Records;
-
-    uint32_t *mXYSums;
-    uint32_t *mXYRecords;
-
-    int32_t mLastX;
-    int32_t mLastY;
-
-    float mWeight;
-};
-
-#endif
diff --git a/voip/jni/rtp/G711Codec.cpp b/voip/jni/rtp/G711Codec.cpp
deleted file mode 100644
index ef54863..0000000
--- a/voip/jni/rtp/G711Codec.cpp
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyrightm (C) 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 "AudioCodec.h"
-
-namespace {
-
-const int8_t gExponents[128] = {
-    0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-};
-
-//------------------------------------------------------------------------------
-
-class UlawCodec : public AudioCodec
-{
-public:
-    int set(int sampleRate, const char *fmtp) {
-        mSampleCount = sampleRate / 50;
-        return mSampleCount;
-    }
-    int encode(void *payload, int16_t *samples);
-    int decode(int16_t *samples, int count, void *payload, int length);
-private:
-    int mSampleCount;
-};
-
-int UlawCodec::encode(void *payload, int16_t *samples)
-{
-    int8_t *ulaws = (int8_t *)payload;
-    for (int i = 0; i < mSampleCount; ++i) {
-        int sample = samples[i];
-        int sign = (sample >> 8) & 0x80;
-        if (sample < 0) {
-            sample = -sample;
-        }
-        sample += 132;
-        if (sample > 32767) {
-            sample = 32767;
-        }
-        int exponent = gExponents[sample >> 8];
-        int mantissa = (sample >> (exponent + 3)) & 0x0F;
-        ulaws[i] = ~(sign | (exponent << 4) | mantissa);
-    }
-    return mSampleCount;
-}
-
-int UlawCodec::decode(int16_t *samples, int count, void *payload, int length)
-{
-    int8_t *ulaws = (int8_t *)payload;
-    if (length > count) {
-        length = count;
-    }
-    for (int i = 0; i < length; ++i) {
-        int ulaw = ~ulaws[i];
-        int exponent = (ulaw >> 4) & 0x07;
-        int mantissa = ulaw & 0x0F;
-        int sample = (((mantissa << 3) + 132) << exponent) - 132;
-        samples[i] = (ulaw < 0 ? -sample : sample);
-    }
-    return length;
-}
-
-//------------------------------------------------------------------------------
-
-class AlawCodec : public AudioCodec
-{
-public:
-    int set(int sampleRate, const char *fmtp) {
-        mSampleCount = sampleRate / 50;
-        return mSampleCount;
-    }
-    int encode(void *payload, int16_t *samples);
-    int decode(int16_t *samples, int count, void *payload, int length);
-private:
-    int mSampleCount;
-};
-
-int AlawCodec::encode(void *payload, int16_t *samples)
-{
-    int8_t *alaws = (int8_t *)payload;
-    for (int i = 0; i < mSampleCount; ++i) {
-        int sample = samples[i];
-        int sign = (sample >> 8) & 0x80;
-        if (sample < 0) {
-            sample = -sample;
-        }
-        if (sample > 32767) {
-            sample = 32767;
-        }
-        int exponent = gExponents[sample >> 8];
-        int mantissa = (sample >> (exponent == 0 ? 4 : exponent + 3)) & 0x0F;
-        alaws[i] = (sign | (exponent << 4) | mantissa) ^ 0xD5;
-    }
-    return mSampleCount;
-}
-
-int AlawCodec::decode(int16_t *samples, int count, void *payload, int length)
-{
-    int8_t *alaws = (int8_t *)payload;
-    if (length > count) {
-        length = count;
-    }
-    for (int i = 0; i < length; ++i) {
-        int alaw = alaws[i] ^ 0x55;
-        int exponent = (alaw >> 4) & 0x07;
-        int mantissa = alaw & 0x0F;
-        int sample = (exponent == 0 ? (mantissa << 4) + 8 :
-            ((mantissa << 3) + 132) << exponent);
-        samples[i] = (alaw < 0 ? sample : -sample);
-    }
-    return length;
-}
-
-} // namespace
-
-AudioCodec *newUlawCodec()
-{
-    return new UlawCodec;
-}
-
-AudioCodec *newAlawCodec()
-{
-    return new AlawCodec;
-}
diff --git a/voip/jni/rtp/GsmCodec.cpp b/voip/jni/rtp/GsmCodec.cpp
deleted file mode 100644
index 61dfdc9..0000000
--- a/voip/jni/rtp/GsmCodec.cpp
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyrightm (C) 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 "AudioCodec.h"
-
-extern "C" {
-#include "gsm.h"
-}
-
-namespace {
-
-class GsmCodec : public AudioCodec
-{
-public:
-    GsmCodec() {
-        mEncode = gsm_create();
-        mDecode = gsm_create();
-    }
-
-    ~GsmCodec() {
-        if (mEncode) {
-            gsm_destroy(mEncode);
-        }
-        if (mDecode) {
-            gsm_destroy(mDecode);
-        }
-    }
-
-    int set(int sampleRate, const char *fmtp) {
-        return (sampleRate == 8000 && mEncode && mDecode) ? 160 : -1;
-    }
-
-    int encode(void *payload, int16_t *samples);
-    int decode(int16_t *samples, int count, void *payload, int length);
-
-private:
-    gsm mEncode;
-    gsm mDecode;
-};
-
-int GsmCodec::encode(void *payload, int16_t *samples)
-{
-    gsm_encode(mEncode, samples, (unsigned char *)payload);
-    return 33;
-}
-
-int GsmCodec::decode(int16_t *samples, int count, void *payload, int length)
-{
-    unsigned char *bytes = (unsigned char *)payload;
-    int n = 0;
-    while (n + 160 <= count && length >= 33 &&
-        gsm_decode(mDecode, bytes, &samples[n]) == 0) {
-        n += 160;
-        length -= 33;
-        bytes += 33;
-    }
-    return n;
-}
-
-} // namespace
-
-AudioCodec *newGsmCodec()
-{
-    return new GsmCodec;
-}
diff --git a/voip/jni/rtp/RtpStream.cpp b/voip/jni/rtp/RtpStream.cpp
deleted file mode 100644
index bfe8e24..0000000
--- a/voip/jni/rtp/RtpStream.cpp
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (C) 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 <stdio.h>
-#include <stdint.h>
-#include <string.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <arpa/inet.h>
-#include <netinet/in.h>
-
-#define LOG_TAG "RtpStream"
-#include <utils/Log.h>
-
-#include "jni.h"
-#include "JNIHelp.h"
-
-extern int parse(JNIEnv *env, jstring jAddress, int port, sockaddr_storage *ss);
-
-namespace {
-
-jfieldID gSocket;
-
-jint create(JNIEnv *env, jobject thiz, jstring jAddress)
-{
-    env->SetIntField(thiz, gSocket, -1);
-
-    sockaddr_storage ss;
-    if (parse(env, jAddress, 0, &ss) < 0) {
-        // Exception already thrown.
-        return -1;
-    }
-
-    int socket = ::socket(ss.ss_family, SOCK_DGRAM, 0);
-    socklen_t len = sizeof(ss);
-    if (socket == -1 || bind(socket, (sockaddr *)&ss, sizeof(ss)) != 0 ||
-        getsockname(socket, (sockaddr *)&ss, &len) != 0) {
-        jniThrowException(env, "java/net/SocketException", strerror(errno));
-        ::close(socket);
-        return -1;
-    }
-
-    uint16_t *p = (ss.ss_family == AF_INET) ?
-        &((sockaddr_in *)&ss)->sin_port : &((sockaddr_in6 *)&ss)->sin6_port;
-    uint16_t port = ntohs(*p);
-    if ((port & 1) == 0) {
-        env->SetIntField(thiz, gSocket, socket);
-        return port;
-    }
-    ::close(socket);
-
-    socket = ::socket(ss.ss_family, SOCK_DGRAM, 0);
-    if (socket != -1) {
-        uint16_t delta = port << 1;
-        ++port;
-
-        for (int i = 0; i < 1000; ++i) {
-            do {
-                port += delta;
-            } while (port < 1024);
-            *p = htons(port);
-
-            if (bind(socket, (sockaddr *)&ss, sizeof(ss)) == 0) {
-                env->SetIntField(thiz, gSocket, socket);
-                return port;
-            }
-        }
-    }
-
-    jniThrowException(env, "java/net/SocketException", strerror(errno));
-    ::close(socket);
-    return -1;
-}
-
-void close(JNIEnv *env, jobject thiz)
-{
-    int socket = env->GetIntField(thiz, gSocket);
-    ::close(socket);
-    env->SetIntField(thiz, gSocket, -1);
-}
-
-JNINativeMethod gMethods[] = {
-    {"create", "(Ljava/lang/String;)I", (void *)create},
-    {"close", "()V", (void *)close},
-};
-
-} // namespace
-
-int registerRtpStream(JNIEnv *env)
-{
-    jclass clazz;
-    if ((clazz = env->FindClass("android/net/rtp/RtpStream")) == NULL ||
-        (gSocket = env->GetFieldID(clazz, "mSocket", "I")) == NULL ||
-        env->RegisterNatives(clazz, gMethods, NELEM(gMethods)) < 0) {
-        ALOGE("JNI registration failed");
-        return -1;
-    }
-    return 0;
-}
diff --git a/voip/jni/rtp/rtp_jni.cpp b/voip/jni/rtp/rtp_jni.cpp
deleted file mode 100644
index 9f4bff9..0000000
--- a/voip/jni/rtp/rtp_jni.cpp
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 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 <stdio.h>
-
-#include "jni.h"
-
-extern int registerRtpStream(JNIEnv *env);
-extern int registerAudioGroup(JNIEnv *env);
-
-__attribute__((visibility("default"))) jint JNI_OnLoad(JavaVM *vm, void *unused)
-{
-    JNIEnv *env = NULL;
-    if (vm->GetEnv((void **)&env, JNI_VERSION_1_4) != JNI_OK ||
-        registerRtpStream(env) < 0 || registerAudioGroup(env) < 0) {
-        return -1;
-    }
-    return JNI_VERSION_1_4;
-}
diff --git a/voip/jni/rtp/util.cpp b/voip/jni/rtp/util.cpp
deleted file mode 100644
index 1d702fc..0000000
--- a/voip/jni/rtp/util.cpp
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 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 <stdio.h>
-#include <string.h>
-#include <arpa/inet.h>
-#include <netinet/in.h>
-
-#include "jni.h"
-#include "JNIHelp.h"
-
-int parse(JNIEnv *env, jstring jAddress, int port, sockaddr_storage *ss)
-{
-    if (!jAddress) {
-        jniThrowNullPointerException(env, "address");
-        return -1;
-    }
-    if (port < 0 || port > 65535) {
-        jniThrowException(env, "java/lang/IllegalArgumentException", "port");
-        return -1;
-    }
-    const char *address = env->GetStringUTFChars(jAddress, NULL);
-    if (!address) {
-        // Exception already thrown.
-        return -1;
-    }
-    memset(ss, 0, sizeof(*ss));
-
-    sockaddr_in *sin = (sockaddr_in *)ss;
-    if (inet_pton(AF_INET, address, &(sin->sin_addr)) > 0) {
-        sin->sin_family = AF_INET;
-        sin->sin_port = htons(port);
-        env->ReleaseStringUTFChars(jAddress, address);
-        return 0;
-    }
-
-    sockaddr_in6 *sin6 = (sockaddr_in6 *)ss;
-    if (inet_pton(AF_INET6, address, &(sin6->sin6_addr)) > 0) {
-        sin6->sin6_family = AF_INET6;
-        sin6->sin6_port = htons(port);
-        env->ReleaseStringUTFChars(jAddress, address);
-        return 0;
-    }
-
-    env->ReleaseStringUTFChars(jAddress, address);
-    jniThrowException(env, "java/lang/IllegalArgumentException", "address");
-    return -1;
-}
