Merge change 21660 into eclair

* changes:
  Optimized Galaxy
diff --git a/api/current.xml b/api/current.xml
index 8fab662..461fc38 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -27037,7 +27037,7 @@
  abstract="false"
  native="false"
  synchronized="false"
- static="false"
+ static="true"
  final="false"
  deprecated="not deprecated"
  visibility="public"
@@ -27349,7 +27349,7 @@
  abstract="false"
  native="false"
  synchronized="false"
- static="false"
+ static="true"
  final="false"
  deprecated="not deprecated"
  visibility="public"
@@ -35797,6 +35797,17 @@
  visibility="public"
 >
 </field>
+<field name="isUserFacing"
+ type="boolean"
+ transient="false"
+ volatile="false"
+ value="true"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 </class>
 <interface name="SyncStatusObserver"
  abstract="true"
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index 94b6162..bf1a442 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -1015,7 +1015,7 @@
      * Check if this account/provider is syncable.
      * @return >0 if it is syncable, 0 if not, and <0 if the state isn't known yet.
      */
-    public int getIsSyncable(Account account, String authority) {
+    public static int getIsSyncable(Account account, String authority) {
         try {
             return getContentService().getIsSyncable(account, authority);
         } catch (RemoteException e) {
@@ -1027,7 +1027,7 @@
      * Set whether this account/provider is syncable.
      * @param syncable >0 denotes syncable, 0 means not syncable, <0 means unknown
      */
-    public void setIsSyncable(Account account, String authority, int syncable) {
+    public static void setIsSyncable(Account account, String authority, int syncable) {
         try {
             getContentService().setIsSyncable(account, authority, syncable);
         } catch (RemoteException e) {
diff --git a/core/java/android/content/SyncAdapterType.java b/core/java/android/content/SyncAdapterType.java
index 5a96003..d3f8230 100644
--- a/core/java/android/content/SyncAdapterType.java
+++ b/core/java/android/content/SyncAdapterType.java
@@ -27,6 +27,7 @@
 public class SyncAdapterType implements Parcelable {
     public final String authority;
     public final String accountType;
+    public final boolean isUserFacing = true; // TODO: implement logic to set this
 
     public SyncAdapterType(String authority, String accountType) {
         if (TextUtils.isEmpty(authority)) {
diff --git a/core/java/android/net/MobileDataStateTracker.java b/core/java/android/net/MobileDataStateTracker.java
index 6b00900..da1115d 100644
--- a/core/java/android/net/MobileDataStateTracker.java
+++ b/core/java/android/net/MobileDataStateTracker.java
@@ -49,7 +49,6 @@
 
     private String mApnType;
     private boolean mEnabled;
-    private boolean mTeardownRequested;
 
     /**
      * Create a new MobileDataStateTracker
@@ -66,7 +65,6 @@
                 TelephonyManager.getDefault().getNetworkTypeName());
         mApnType = apnType;
         mPhoneService = null;
-        mTeardownRequested = false;
         if(netType == ConnectivityManager.TYPE_MOBILE) {
             mEnabled = true;
         } else {
@@ -81,7 +79,9 @@
                 "net.eth0.dns3",
                 "net.eth0.dns4",
                 "net.gprs.dns1",
-                "net.gprs.dns2"};
+                "net.gprs.dns2",
+                "net.ppp0.dns1",
+                "net.ppp0.dns2"};
 
     }
 
@@ -160,9 +160,9 @@
 
                     switch (state) {
                     case DISCONNECTED:
-                        if(mTeardownRequested) {
+                        if(isTeardownRequested()) {
                             mEnabled = false;
-                            mTeardownRequested = false;
+                            setTeardownRequested(false);
                         }
 
                         setDetailedState(DetailedState.DISCONNECTED, reason, apnName);
@@ -277,7 +277,7 @@
      */
     @Override
     public boolean teardown() {
-        mTeardownRequested = true;
+        setTeardownRequested(true);
         return (setEnableApn(mApnType, false) != Phone.APN_REQUEST_FAILED);
     }
 
@@ -286,7 +286,7 @@
      */
     public boolean reconnect() {
         mEnabled = true;
-        mTeardownRequested = false;
+        setTeardownRequested(false);
         mEnabled = (setEnableApn(mApnType, true) !=
                 Phone.APN_REQUEST_FAILED);
         return mEnabled;
diff --git a/core/java/android/text/BoringLayout.java b/core/java/android/text/BoringLayout.java
index 843754b..944f735 100644
--- a/core/java/android/text/BoringLayout.java
+++ b/core/java/android/text/BoringLayout.java
@@ -19,6 +19,7 @@
 import android.graphics.Canvas;
 import android.graphics.Paint;
 import android.graphics.Path;
+import android.text.style.ParagraphStyle;
 import android.util.FloatMath;
 
 /**
@@ -262,6 +263,14 @@
 
         TextUtils.recycle(temp);
 
+        if (boring && text instanceof Spanned) {
+            Spanned sp = (Spanned) text;
+            Object[] styles = sp.getSpans(0, text.length(), ParagraphStyle.class);
+            if (styles.length > 0) {
+                boring = false;
+            }
+        }
+
         if (boring) {
             Metrics fm = metrics;
             if (fm == null) {
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 7468aef..f49aab1 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -4689,19 +4689,20 @@
         mZoomCenterY = mLastTouchY;
         mInZoomOverview = !mInZoomOverview;
         mCallbackProxy.uiOnChangeViewingMode(mInZoomOverview);
-        if (mInZoomOverview) {
-            if (getSettings().getBuiltInZoomControls()) {
-                if (mZoomButtonsController.isVisible()) {
-                    mZoomButtonsController.setVisible(false);
-                }
-            } else {
-                if (mZoomControlRunnable != null) {
-                    mPrivateHandler.removeCallbacks(mZoomControlRunnable);
-                }
-                if (mZoomControls != null) {
-                    mZoomControls.hide();
-                }
+        // remove the zoom control after double tap
+        if (getSettings().getBuiltInZoomControls()) {
+            if (mZoomButtonsController.isVisible()) {
+                mZoomButtonsController.setVisible(false);
             }
+        } else {
+            if (mZoomControlRunnable != null) {
+                mPrivateHandler.removeCallbacks(mZoomControlRunnable);
+            }
+            if (mZoomControls != null) {
+                mZoomControls.hide();
+            }
+        }
+        if (mInZoomOverview) {
             zoomWithPreview((float) getViewWidth() / mZoomOverviewWidth);
         } else {
             // mLastTouchX and mLastTouchY are the point in the current viewport
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index 02a137d..993b7cb 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -1428,7 +1428,8 @@
                 throw new IllegalStateException("The content of the adapter has changed but "
                         + "ListView did not receive a notification. Make sure the content of "
                         + "your adapter is not modified from a background thread, but only "
-                        + "from the UI thread.");
+                        + "from the UI thread. [in ListView(" + getId() + ", " + getClass() 
+                        + ") with Adapter(" + mAdapter.getClass() + ")]");
             }
 
             setSelectedPositionInt(mNextSelectedPosition);
diff --git a/docs/html/guide/developing/tools/aidl.jd b/docs/html/guide/developing/tools/aidl.jd
index f370a80..abfa8b1 100644
--- a/docs/html/guide/developing/tools/aidl.jd
+++ b/docs/html/guide/developing/tools/aidl.jd
@@ -194,7 +194,6 @@
 <li>Make your class implement the {@link android.os.Parcelable} interface.</li>
 <li>Implement the method <code>public void writeToParcel(Parcel out)</code> that takes the
 current state of the object and writes it to a parcel.</li>
-<li>Implement the method <code>public void readFromParcel(Parcel in)</code> that reads the
 value in a parcel into your object.</li>
 <li>Add a static field called <code>CREATOR</code> to your class which is an object implementing
 the {@link android.os.Parcelable.Creator Parcelable.Creator} interface.</li>
diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java
index 33748ae..21b5e39 100644
--- a/graphics/java/android/graphics/drawable/Drawable.java
+++ b/graphics/java/android/graphics/drawable/Drawable.java
@@ -654,7 +654,7 @@
      * Create a drawable from an inputstream
      */
     public static Drawable createFromStream(InputStream is, String srcName) {
-        return createFromResourceStream(null, null, is, srcName);
+        return createFromResourceStream(null, null, is, srcName, null);
     }
 
     /**
@@ -663,7 +663,7 @@
      */
     public static Drawable createFromResourceStream(Resources res, TypedValue value,
             InputStream is, String srcName) {
-        return createFromResourceStream(res, value, is, srcName);
+        return createFromResourceStream(res, value, is, srcName, null);
     }
 
     /**
diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp
index 4d6f252..ff997e7 100644
--- a/graphics/jni/android_renderscript_RenderScript.cpp
+++ b/graphics/jni/android_renderscript_RenderScript.cpp
@@ -74,7 +74,7 @@
 
     jint len = _env->GetArrayLength(str);
     jbyte * cptr = (jbyte *) _env->GetPrimitiveArrayCritical(str, 0);
-    rsAssignName((void *)obj, (const char *)cptr, len);
+    rsAssignName(con, (void *)obj, (const char *)cptr, len);
     _env->ReleasePrimitiveArrayCritical(str, cptr, JNI_ABORT);
 }
 
@@ -87,7 +87,7 @@
 
     jint len = _env->GetArrayLength(str);
     jbyte * cptr = (jbyte *) _env->GetPrimitiveArrayCritical(str, 0);
-    jint ret = (jint)rsFileOpen((const char *)cptr, len);
+    jint ret = (jint)rsFileOpen(con, (const char *)cptr, len);
     _env->ReleasePrimitiveArrayCritical(str, cptr, JNI_ABORT);
     return ret;
 }
@@ -141,7 +141,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nElementBegin, con(%p)", con);
-    rsElementBegin();
+    rsElementBegin(con);
 }
 
 static void
@@ -149,7 +149,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nElementAddPredefined, con(%p), predef(%i)", con, predef);
-    rsElementAddPredefined((RsElementPredefined)predef);
+    rsElementAddPredefined(con, (RsElementPredefined)predef);
 }
 
 static void
@@ -161,7 +161,7 @@
         n = _env->GetStringUTFChars(name, NULL);
     }
     LOG_API("nElementAdd, con(%p), kind(%i), type(%i), norm(%i), bits(%i)", con, kind, type, norm, bits);
-    rsElementAdd((RsDataKind)kind, (RsDataType)type, norm != 0, (size_t)bits, n);
+    rsElementAdd(con, (RsDataKind)kind, (RsDataType)type, norm != 0, (size_t)bits, n);
     if (n) {
         _env->ReleaseStringUTFChars(name, n);
     }
@@ -172,7 +172,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nElementCreate, con(%p)", con);
-    return (jint)rsElementCreate();
+    return (jint)rsElementCreate(con);
 }
 
 static jint
@@ -180,7 +180,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nElementGetPredefined, con(%p) predef(%i)", con, predef);
-    return (jint)rsElementGetPredefined((RsElementPredefined)predef);
+    return (jint)rsElementGetPredefined(con, (RsElementPredefined)predef);
 }
 
 static void
@@ -188,7 +188,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nElementDestroy, con(%p) e(%p)", con, (RsElement)e);
-    rsElementDestroy((RsElement)e);
+    rsElementDestroy(con, (RsElement)e);
 }
 
 // -----------------------------------
@@ -198,7 +198,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nTypeBegin, con(%p) e(%p)", con, (RsElement)eID);
-    rsTypeBegin((RsElement)eID);
+    rsTypeBegin(con, (RsElement)eID);
 }
 
 static void
@@ -206,7 +206,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nTypeAdd, con(%p) dim(%i), val(%i)", con, dim, val);
-    rsTypeAdd((RsDimension)dim, val);
+    rsTypeAdd(con, (RsDimension)dim, val);
 }
 
 static jint
@@ -214,7 +214,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nTypeCreate, con(%p)", con);
-    return (jint)rsTypeCreate();
+    return (jint)rsTypeCreate(con);
 }
 
 static void
@@ -222,7 +222,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nTypeDestroy, con(%p), t(%p)", con, (RsType)eID);
-    rsTypeDestroy((RsType)eID);
+    rsTypeDestroy(con, (RsType)eID);
 }
 
 static void * SF_LoadInt(JNIEnv *_env, jobject _obj, jfieldID _field, void *buffer)
@@ -317,7 +317,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nAllocationCreateTyped, con(%p), e(%p)", con, (RsElement)e);
-    return (jint) rsAllocationCreateTyped((RsElement)e);
+    return (jint) rsAllocationCreateTyped(con, (RsElement)e);
 }
 
 static jint
@@ -325,7 +325,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nAllocationCreatePredefSized, con(%p), predef(%i), count(%i)", con, predef, count);
-    return (jint) rsAllocationCreatePredefSized((RsElementPredefined)predef, count);
+    return (jint) rsAllocationCreatePredefSized(con, (RsElementPredefined)predef, count);
 }
 
 static jint
@@ -333,7 +333,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nAllocationCreateSized, con(%p), e(%p), count(%i)", con, (RsElement)e, count);
-    return (jint) rsAllocationCreateSized((RsElement)e, count);
+    return (jint) rsAllocationCreateSized(con, (RsElement)e, count);
 }
 
 static void
@@ -341,7 +341,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nAllocationUploadToTexture, con(%p), a(%p), mip(%i)", con, (RsAllocation)a, mip);
-    rsAllocationUploadToTexture((RsAllocation)a, mip);
+    rsAllocationUploadToTexture(con, (RsAllocation)a, mip);
 }
 
 static RsElementPredefined SkBitmapToPredefined(SkBitmap::Config cfg)
@@ -380,7 +380,7 @@
         const int w = bitmap.width();
         const int h = bitmap.height();
         const void* ptr = bitmap.getPixels();
-        jint id = (jint)rsAllocationCreateFromBitmap(w, h, (RsElementPredefined)dstFmt, e, genMips, ptr);
+        jint id = (jint)rsAllocationCreateFromBitmap(con, w, h, (RsElementPredefined)dstFmt, e, genMips, ptr);
         bitmap.unlockPixels();
         return id;
     }
@@ -403,7 +403,7 @@
         const int w = bitmap.width();
         const int h = bitmap.height();
         const void* ptr = bitmap.getPixels();
-        jint id = (jint)rsAllocationCreateFromBitmapBoxed(w, h, (RsElementPredefined)dstFmt, e, genMips, ptr);
+        jint id = (jint)rsAllocationCreateFromBitmapBoxed(con, w, h, (RsElementPredefined)dstFmt, e, genMips, ptr);
         bitmap.unlockPixels();
         return id;
     }
@@ -416,7 +416,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nAllocationDestroy, con(%p), a(%p)", con, (RsAllocation)a);
-    rsAllocationDestroy((RsAllocation)a);
+    rsAllocationDestroy(con, (RsAllocation)a);
 }
 
 static void
@@ -426,7 +426,7 @@
     jint len = _env->GetArrayLength(data);
     LOG_API("nAllocationData_i, con(%p), alloc(%p), len(%i)", con, (RsAllocation)alloc, len);
     jint *ptr = _env->GetIntArrayElements(data, NULL);
-    rsAllocationData((RsAllocation)alloc, ptr);
+    rsAllocationData(con, (RsAllocation)alloc, ptr);
     _env->ReleaseIntArrayElements(data, ptr, JNI_ABORT);
 }
 
@@ -437,7 +437,7 @@
     jint len = _env->GetArrayLength(data);
     LOG_API("nAllocationData_i, con(%p), alloc(%p), len(%i)", con, (RsAllocation)alloc, len);
     jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
-    rsAllocationData((RsAllocation)alloc, ptr);
+    rsAllocationData(con, (RsAllocation)alloc, ptr);
     _env->ReleaseFloatArrayElements(data, ptr, JNI_ABORT);
 }
 
@@ -448,7 +448,7 @@
     jint len = _env->GetArrayLength(data);
     LOG_API("nAllocation1DSubData_i, con(%p), adapter(%p), offset(%i), count(%i), len(%i)", con, (RsAllocation)alloc, offset, count, len);
     jint *ptr = _env->GetIntArrayElements(data, NULL);
-    rsAllocation1DSubData((RsAllocation)alloc, offset, count, ptr);
+    rsAllocation1DSubData(con, (RsAllocation)alloc, offset, count, ptr);
     _env->ReleaseIntArrayElements(data, ptr, JNI_ABORT);
 }
 
@@ -459,7 +459,7 @@
     jint len = _env->GetArrayLength(data);
     LOG_API("nAllocation1DSubData_f, con(%p), adapter(%p), offset(%i), count(%i), len(%i)", con, (RsAllocation)alloc, offset, count, len);
     jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
-    rsAllocation1DSubData((RsAllocation)alloc, offset, count, ptr);
+    rsAllocation1DSubData(con, (RsAllocation)alloc, offset, count, ptr);
     _env->ReleaseFloatArrayElements(data, ptr, JNI_ABORT);
 }
 
@@ -470,7 +470,7 @@
     jint len = _env->GetArrayLength(data);
     LOG_API("nAllocation2DSubData_i, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i)", con, (RsAllocation)alloc, xoff, yoff, w, h, len);
     jint *ptr = _env->GetIntArrayElements(data, NULL);
-    rsAllocation2DSubData((RsAllocation)alloc, xoff, yoff, w, h, ptr);
+    rsAllocation2DSubData(con, (RsAllocation)alloc, xoff, yoff, w, h, ptr);
     _env->ReleaseIntArrayElements(data, ptr, JNI_ABORT);
 }
 
@@ -481,7 +481,7 @@
     jint len = _env->GetArrayLength(data);
     LOG_API("nAllocation2DSubData_i, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i)", con, (RsAllocation)alloc, xoff, yoff, w, h, len);
     jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
-    rsAllocation2DSubData((RsAllocation)alloc, xoff, yoff, w, h, ptr);
+    rsAllocation2DSubData(con, (RsAllocation)alloc, xoff, yoff, w, h, ptr);
     _env->ReleaseFloatArrayElements(data, ptr, JNI_ABORT);
 }
 
@@ -492,7 +492,7 @@
     jint len = _env->GetArrayLength(data);
     LOG_API("nAllocationRead_i, con(%p), alloc(%p), len(%i)", con, (RsAllocation)alloc, len);
     jint *ptr = _env->GetIntArrayElements(data, NULL);
-    rsAllocationRead((RsAllocation)alloc, ptr);
+    rsAllocationRead(con, (RsAllocation)alloc, ptr);
     _env->ReleaseIntArrayElements(data, ptr, JNI_COMMIT);
 }
 
@@ -503,7 +503,7 @@
     jint len = _env->GetArrayLength(data);
     LOG_API("nAllocationRead_f, con(%p), alloc(%p), len(%i)", con, (RsAllocation)alloc, len);
     jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
-    rsAllocationRead((RsAllocation)alloc, ptr);
+    rsAllocationRead(con, (RsAllocation)alloc, ptr);
     _env->ReleaseFloatArrayElements(data, ptr, JNI_COMMIT);
 }
 
@@ -523,7 +523,7 @@
         const TypeFieldCache *tfc = &tc->fields[ct];
         buf = tfc->ptr(_env, _o, tfc->field, buf);
     }
-    rsAllocationData((RsAllocation)alloc, bufAlloc);
+    rsAllocationData(con, (RsAllocation)alloc, bufAlloc);
     const uint32_t * tmp = (const uint32_t *)bufAlloc;
     free(bufAlloc);
 }
@@ -535,7 +535,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nTriangleMeshDestroy, con(%p), tm(%p)", con, (RsAllocation)tm);
-    rsTriangleMeshDestroy((RsTriangleMesh)tm);
+    rsTriangleMeshDestroy(con, (RsTriangleMesh)tm);
 }
 
 static void
@@ -543,7 +543,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nTriangleMeshBegin, con(%p), vertex(%p), index(%p)", con, (RsElement)v, (RsElement)i);
-    rsTriangleMeshBegin((RsElement)v, (RsElement)i);
+    rsTriangleMeshBegin(con, (RsElement)v, (RsElement)i);
 }
 
 static void
@@ -552,7 +552,7 @@
     float v[] = {x, y};
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nTriangleMeshAddVertex_XY, con(%p), x(%f), y(%f)", con, x, y);
-    rsTriangleMeshAddVertex(v);
+    rsTriangleMeshAddVertex(con, v);
 }
 
 static void
@@ -561,7 +561,7 @@
     float v[] = {x, y, z};
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nTriangleMeshAddVertex_XYZ, con(%p), x(%f), y(%f), z(%f)", con, x, y, z);
-    rsTriangleMeshAddVertex(v);
+    rsTriangleMeshAddVertex(con, v);
 }
 
 static void
@@ -570,7 +570,7 @@
     float v[] = {s, t, x, y};
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nTriangleMeshAddVertex_XY_ST, con(%p), x(%f), y(%f), s(%f), t(%f)", con, x, y, s, t);
-    rsTriangleMeshAddVertex(v);
+    rsTriangleMeshAddVertex(con, v);
 }
 
 static void
@@ -579,7 +579,7 @@
     float v[] = {s, t, x, y, z};
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nTriangleMeshAddVertex_XYZ_ST, con(%p), x(%f), y(%f), z(%f), s(%f), t(%f)", con, x, y, z, s, t);
-    rsTriangleMeshAddVertex(v);
+    rsTriangleMeshAddVertex(con, v);
 }
 
 static void
@@ -588,7 +588,7 @@
     float v[] = {nx, ny, nz, s, t, x, y, z};
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nTriangleMeshAddVertex_XYZ_ST, con(%p), x(%f), y(%f), z(%f), s(%f), t(%f)", con, x, y, z, s, t);
-    rsTriangleMeshAddVertex(v);
+    rsTriangleMeshAddVertex(con, v);
 }
 
 static void
@@ -596,7 +596,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nTriangleMeshAddTriangle, con(%p), i1(%i), i2(%i), i3(%i)", con, i1, i2, i3);
-    rsTriangleMeshAddTriangle(i1, i2, i3);
+    rsTriangleMeshAddTriangle(con, i1, i2, i3);
 }
 
 static jint
@@ -604,7 +604,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nTriangleMeshCreate, con(%p)", con);
-    return (jint) rsTriangleMeshCreate();
+    return (jint) rsTriangleMeshCreate(con);
 }
 
 // -----------------------------------
@@ -614,7 +614,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nAdapter1DDestroy, con(%p), adapter(%p)", con, (RsAdapter1D)adapter);
-    rsAdapter1DDestroy((RsAdapter1D)adapter);
+    rsAdapter1DDestroy(con, (RsAdapter1D)adapter);
 }
 
 static void
@@ -622,7 +622,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nAdapter1DBindAllocation, con(%p), adapter(%p), alloc(%p)", con, (RsAdapter1D)adapter, (RsAllocation)alloc);
-    rsAdapter1DBindAllocation((RsAdapter1D)adapter, (RsAllocation)alloc);
+    rsAdapter1DBindAllocation(con, (RsAdapter1D)adapter, (RsAllocation)alloc);
 }
 
 static void
@@ -630,7 +630,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nAdapter1DSetConstraint, con(%p), adapter(%p), dim(%i), value(%i)", con, (RsAdapter1D)adapter, dim, value);
-    rsAdapter1DSetConstraint((RsAdapter1D)adapter, (RsDimension)dim, value);
+    rsAdapter1DSetConstraint(con, (RsAdapter1D)adapter, (RsDimension)dim, value);
 }
 
 static void
@@ -640,7 +640,7 @@
     jint len = _env->GetArrayLength(data);
     LOG_API("nAdapter1DData_i, con(%p), adapter(%p), len(%i)", con, (RsAdapter1D)adapter, len);
     jint *ptr = _env->GetIntArrayElements(data, NULL);
-    rsAdapter1DData((RsAdapter1D)adapter, ptr);
+    rsAdapter1DData(con, (RsAdapter1D)adapter, ptr);
     _env->ReleaseIntArrayElements(data, ptr, 0/*JNI_ABORT*/);
 }
 
@@ -651,7 +651,7 @@
     jint len = _env->GetArrayLength(data);
     LOG_API("nAdapter1DSubData_i, con(%p), adapter(%p), offset(%i), count(%i), len(%i)", con, (RsAdapter1D)adapter, offset, count, len);
     jint *ptr = _env->GetIntArrayElements(data, NULL);
-    rsAdapter1DSubData((RsAdapter1D)adapter, offset, count, ptr);
+    rsAdapter1DSubData(con, (RsAdapter1D)adapter, offset, count, ptr);
     _env->ReleaseIntArrayElements(data, ptr, 0/*JNI_ABORT*/);
 }
 
@@ -662,7 +662,7 @@
     jint len = _env->GetArrayLength(data);
     LOG_API("nAdapter1DData_f, con(%p), adapter(%p), len(%i)", con, (RsAdapter1D)adapter, len);
     jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
-    rsAdapter1DData((RsAdapter1D)adapter, ptr);
+    rsAdapter1DData(con, (RsAdapter1D)adapter, ptr);
     _env->ReleaseFloatArrayElements(data, ptr, 0/*JNI_ABORT*/);
 }
 
@@ -673,7 +673,7 @@
     jint len = _env->GetArrayLength(data);
     LOG_API("nAdapter1DSubData_f, con(%p), adapter(%p), offset(%i), count(%i), len(%i)", con, (RsAdapter1D)adapter, offset, count, len);
     jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
-    rsAdapter1DSubData((RsAdapter1D)adapter, offset, count, ptr);
+    rsAdapter1DSubData(con, (RsAdapter1D)adapter, offset, count, ptr);
     _env->ReleaseFloatArrayElements(data, ptr, 0/*JNI_ABORT*/);
 }
 
@@ -682,7 +682,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nAdapter1DCreate, con(%p)", con);
-    return (jint)rsAdapter1DCreate();
+    return (jint)rsAdapter1DCreate(con);
 }
 
 // -----------------------------------
@@ -692,7 +692,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nAdapter2DDestroy, con(%p), adapter(%p)", con, (RsAdapter2D)adapter);
-    rsAdapter2DDestroy((RsAdapter2D)adapter);
+    rsAdapter2DDestroy(con, (RsAdapter2D)adapter);
 }
 
 static void
@@ -700,7 +700,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nAdapter2DBindAllocation, con(%p), adapter(%p), alloc(%p)", con, (RsAdapter2D)adapter, (RsAllocation)alloc);
-    rsAdapter2DBindAllocation((RsAdapter2D)adapter, (RsAllocation)alloc);
+    rsAdapter2DBindAllocation(con, (RsAdapter2D)adapter, (RsAllocation)alloc);
 }
 
 static void
@@ -708,7 +708,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nAdapter2DSetConstraint, con(%p), adapter(%p), dim(%i), value(%i)", con, (RsAdapter2D)adapter, dim, value);
-    rsAdapter2DSetConstraint((RsAdapter2D)adapter, (RsDimension)dim, value);
+    rsAdapter2DSetConstraint(con, (RsAdapter2D)adapter, (RsDimension)dim, value);
 }
 
 static void
@@ -718,7 +718,7 @@
     jint len = _env->GetArrayLength(data);
     LOG_API("nAdapter2DData_i, con(%p), adapter(%p), len(%i)", con, (RsAdapter2D)adapter, len);
     jint *ptr = _env->GetIntArrayElements(data, NULL);
-    rsAdapter2DData((RsAdapter2D)adapter, ptr);
+    rsAdapter2DData(con, (RsAdapter2D)adapter, ptr);
     _env->ReleaseIntArrayElements(data, ptr, 0/*JNI_ABORT*/);
 }
 
@@ -729,7 +729,7 @@
     jint len = _env->GetArrayLength(data);
     LOG_API("nAdapter2DData_f, con(%p), adapter(%p), len(%i)", con, (RsAdapter2D)adapter, len);
     jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
-    rsAdapter2DData((RsAdapter2D)adapter, ptr);
+    rsAdapter2DData(con, (RsAdapter2D)adapter, ptr);
     _env->ReleaseFloatArrayElements(data, ptr, 0/*JNI_ABORT*/);
 }
 
@@ -741,7 +741,7 @@
     LOG_API("nAdapter2DSubData_i, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i)",
             con, (RsAdapter2D)adapter, xoff, yoff, w, h, len);
     jint *ptr = _env->GetIntArrayElements(data, NULL);
-    rsAdapter2DSubData((RsAdapter2D)adapter, xoff, yoff, w, h, ptr);
+    rsAdapter2DSubData(con, (RsAdapter2D)adapter, xoff, yoff, w, h, ptr);
     _env->ReleaseIntArrayElements(data, ptr, 0/*JNI_ABORT*/);
 }
 
@@ -753,7 +753,7 @@
     LOG_API("nAdapter2DSubData_f, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i)",
             con, (RsAdapter2D)adapter, xoff, yoff, w, h, len);
     jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
-    rsAdapter2DSubData((RsAdapter1D)adapter, xoff, yoff, w, h, ptr);
+    rsAdapter2DSubData(con, (RsAdapter1D)adapter, xoff, yoff, w, h, ptr);
     _env->ReleaseFloatArrayElements(data, ptr, 0/*JNI_ABORT*/);
 }
 
@@ -762,7 +762,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nAdapter2DCreate, con(%p)", con);
-    return (jint)rsAdapter2DCreate();
+    return (jint)rsAdapter2DCreate(con);
 }
 
 // -----------------------------------
@@ -772,7 +772,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nScriptDestroy, con(%p), script(%p)", con, (RsScript)script);
-    rsScriptDestroy((RsScript)script);
+    rsScriptDestroy(con, (RsScript)script);
 }
 
 static void
@@ -780,7 +780,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nScriptBindAllocation, con(%p), script(%p), alloc(%p), slot(%i)", con, (RsScript)script, (RsAllocation)alloc, slot);
-    rsScriptBindAllocation((RsScript)script, (RsAllocation)alloc, slot);
+    rsScriptBindAllocation(con, (RsScript)script, (RsAllocation)alloc, slot);
 }
 
 static void
@@ -788,7 +788,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nScriptSetClearColor, con(%p), s(%p), r(%f), g(%f), b(%f), a(%f)", con, script, r, g, b, a);
-    rsScriptSetClearColor((RsScript)script, r, g, b, a);
+    rsScriptSetClearColor(con, (RsScript)script, r, g, b, a);
 }
 
 static void
@@ -796,7 +796,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nScriptCSetClearDepth, con(%p), s(%p), depth(%f)", con, script, d);
-    rsScriptSetClearDepth((RsScript)script, d);
+    rsScriptSetClearDepth(con, (RsScript)script, d);
 }
 
 static void
@@ -804,7 +804,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nScriptCSetClearStencil, con(%p), s(%p), stencil(%i)", con, script, stencil);
-    rsScriptSetClearStencil((RsScript)script, stencil);
+    rsScriptSetClearStencil(con, (RsScript)script, stencil);
 }
 
 static void
@@ -817,7 +817,7 @@
     jbyte* timeZone_ptr;
     timeZone_ptr = (jbyte *) _env->GetPrimitiveArrayCritical(timeZone, (jboolean *)0);
 
-    rsScriptSetTimeZone((RsScript)script, (const char *)timeZone_ptr, length);
+    rsScriptSetTimeZone(con, (RsScript)script, (const char *)timeZone_ptr, length);
 
     if (timeZone_ptr) {
         _env->ReleasePrimitiveArrayCritical(timeZone, timeZone_ptr, 0);
@@ -833,7 +833,7 @@
     if (_str) {
         n = _env->GetStringUTFChars(_str, NULL);
     }
-    rsScriptSetType((RsType)type, slot, writable, n);
+    rsScriptSetType(con, (RsType)type, slot, writable, n);
     if (n) {
         _env->ReleaseStringUTFChars(_str, n);
     }
@@ -844,7 +844,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nScriptCSetRoot, con(%p), isRoot(%i)", con, isRoot);
-    rsScriptSetRoot(isRoot);
+    rsScriptSetRoot(con, isRoot);
 }
 
 // -----------------------------------
@@ -854,7 +854,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nScriptCBegin, con(%p)", con);
-    rsScriptCBegin();
+    rsScriptCBegin(con);
 }
 
 static void
@@ -892,7 +892,7 @@
         _env->GetPrimitiveArrayCritical(scriptRef, (jboolean *)0);
     script_ptr = script_base + offset;
 
-    rsScriptCSetText((const char *)script_ptr, length);
+    rsScriptCSetText(con, (const char *)script_ptr, length);
 
 exit:
     if (script_base) {
@@ -906,7 +906,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nScriptCCreate, con(%p)", con);
-    return (jint)rsScriptCCreate();
+    return (jint)rsScriptCCreate(con);
 }
 
 static void
@@ -915,7 +915,7 @@
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     const char* n = _env->GetStringUTFChars(name, NULL);
     LOG_API("nScriptCAddDefineI32, con(%p) name(%s) value(%d)", con, n, value);
-    rsScriptCSetDefineI32(n, value);
+    rsScriptCSetDefineI32(con, n, value);
     _env->ReleaseStringUTFChars(name, n);
 }
 
@@ -925,7 +925,7 @@
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     const char* n = _env->GetStringUTFChars(name, NULL);
     LOG_API("nScriptCAddDefineF, con(%p) name(%s) value(%f)", con, n, value);
-    rsScriptCSetDefineF(n, value);
+    rsScriptCSetDefineF(con, n, value);
     _env->ReleaseStringUTFChars(name, n);
 }
 
@@ -936,7 +936,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nProgramFragmentStoreBegin, con(%p), in(%p), out(%p)", con, (RsElement)in, (RsElement)out);
-    rsProgramFragmentStoreBegin((RsElement)in, (RsElement)out);
+    rsProgramFragmentStoreBegin(con, (RsElement)in, (RsElement)out);
 }
 
 static void
@@ -944,7 +944,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nProgramFragmentStoreDepthFunc, con(%p), func(%i)", con, func);
-    rsProgramFragmentStoreDepthFunc((RsDepthFunc)func);
+    rsProgramFragmentStoreDepthFunc(con, (RsDepthFunc)func);
 }
 
 static void
@@ -952,7 +952,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nProgramFragmentStoreDepthMask, con(%p), enable(%i)", con, enable);
-    rsProgramFragmentStoreDepthMask(enable);
+    rsProgramFragmentStoreDepthMask(con, enable);
 }
 
 static void
@@ -960,7 +960,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nProgramFragmentStoreColorMask, con(%p), r(%i), g(%i), b(%i), a(%i)", con, r, g, b, a);
-    rsProgramFragmentStoreColorMask(r, g, b, a);
+    rsProgramFragmentStoreColorMask(con, r, g, b, a);
 }
 
 static void
@@ -968,7 +968,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nProgramFragmentStoreBlendFunc, con(%p), src(%i), dst(%i)", con, src, dst);
-    rsProgramFragmentStoreBlendFunc((RsBlendSrcFunc)src, (RsBlendDstFunc)dst);
+    rsProgramFragmentStoreBlendFunc(con, (RsBlendSrcFunc)src, (RsBlendDstFunc)dst);
 }
 
 static void
@@ -976,7 +976,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nProgramFragmentStoreDither, con(%p), enable(%i)", con, enable);
-    rsProgramFragmentStoreDither(enable);
+    rsProgramFragmentStoreDither(con, enable);
 }
 
 static jint
@@ -985,7 +985,7 @@
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nProgramFragmentStoreCreate, con(%p)", con);
 
-    return (jint)rsProgramFragmentStoreCreate();
+    return (jint)rsProgramFragmentStoreCreate(con);
 }
 
 static void
@@ -993,7 +993,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nProgramFragmentStoreDestroy, con(%p), pgm(%i)", con, pgm);
-    rsProgramFragmentStoreDestroy((RsProgramFragmentStore)pgm);
+    rsProgramFragmentStoreDestroy(con, (RsProgramFragmentStore)pgm);
 }
 
 // ---------------------------------------------------------------------------
@@ -1003,7 +1003,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nProgramFragmentBegin, con(%p), in(%p), out(%p)", con, (RsElement)in, (RsElement)out);
-    rsProgramFragmentBegin((RsElement)in, (RsElement)out);
+    rsProgramFragmentBegin(con, (RsElement)in, (RsElement)out);
 }
 
 static void
@@ -1011,7 +1011,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nProgramFragmentBindTexture, con(%p), vpf(%p), slot(%i), a(%p)", con, (RsProgramFragment)vpf, slot, (RsAllocation)a);
-    rsProgramFragmentBindTexture((RsProgramFragment)vpf, slot, (RsAllocation)a);
+    rsProgramFragmentBindTexture(con, (RsProgramFragment)vpf, slot, (RsAllocation)a);
 }
 
 static void
@@ -1019,7 +1019,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nProgramFragmentBindSampler, con(%p), vpf(%p), slot(%i), a(%p)", con, (RsProgramFragment)vpf, slot, (RsSampler)a);
-    rsProgramFragmentBindSampler((RsProgramFragment)vpf, slot, (RsSampler)a);
+    rsProgramFragmentBindSampler(con, (RsProgramFragment)vpf, slot, (RsSampler)a);
 }
 
 static void
@@ -1027,7 +1027,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nProgramFragmentSetType, con(%p), slot(%i), vt(%p)", con, slot, (RsType)vt);
-    rsProgramFragmentSetType(slot, (RsType)vt);
+    rsProgramFragmentSetType(con, slot, (RsType)vt);
 }
 
 static void
@@ -1035,7 +1035,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nProgramFragmentSetEnvMode, con(%p), slot(%i), vt(%i)", con, slot, env);
-    rsProgramFragmentSetEnvMode(slot, (RsTexEnvMode)env);
+    rsProgramFragmentSetEnvMode(con, slot, (RsTexEnvMode)env);
 }
 
 static void
@@ -1043,7 +1043,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nProgramFragmentSetTexEnable, con(%p), slot(%i), enable(%i)", con, slot, enable);
-    rsProgramFragmentSetTexEnable(slot, enable);
+    rsProgramFragmentSetTexEnable(con, slot, enable);
 }
 
 static jint
@@ -1051,7 +1051,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nProgramFragmentCreate, con(%p)", con);
-    return (jint)rsProgramFragmentCreate();
+    return (jint)rsProgramFragmentCreate(con);
 }
 
 static void
@@ -1059,7 +1059,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nProgramFragmentDestroy, con(%p), pgm(%i)", con, pgm);
-    rsProgramFragmentDestroy((RsProgramFragment)pgm);
+    rsProgramFragmentDestroy(con, (RsProgramFragment)pgm);
 }
 
 // ---------------------------------------------------------------------------
@@ -1069,7 +1069,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nProgramVertexBegin, con(%p), in(%p), out(%p)", con, (RsElement)in, (RsElement)out);
-    rsProgramVertexBegin((RsElement)in, (RsElement)out);
+    rsProgramVertexBegin(con, (RsElement)in, (RsElement)out);
 }
 
 static void
@@ -1077,7 +1077,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nProgramVertexBindAllocation, con(%p), vpf(%p), slot(%i), a(%p)", con, (RsProgramVertex)vpv, slot, (RsAllocation)a);
-    rsProgramVertexBindAllocation((RsProgramFragment)vpv, (RsAllocation)a);
+    rsProgramVertexBindAllocation(con, (RsProgramFragment)vpv, (RsAllocation)a);
 }
 
 static void
@@ -1085,7 +1085,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nProgramVertexSetTextureMatrixEnable, con(%p), enable(%i)", con, enable);
-    rsProgramVertexSetTextureMatrixEnable(enable);
+    rsProgramVertexSetTextureMatrixEnable(con, enable);
 }
 
 static void
@@ -1093,7 +1093,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nProgramVertexAddLight, con(%p), light(%p)", con, (RsLight)light);
-    rsProgramVertexAddLight((RsLight)light);
+    rsProgramVertexAddLight(con, (RsLight)light);
 }
 
 static jint
@@ -1101,7 +1101,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nProgramVertexCreate, con(%p)", con);
-    return (jint)rsProgramVertexCreate();
+    return (jint)rsProgramVertexCreate(con);
 }
 
 static void
@@ -1109,7 +1109,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nProgramFragmentDestroy, con(%p), pgm(%i)", con, pgm);
-    rsProgramFragmentDestroy((RsProgramFragment)pgm);
+    rsProgramFragmentDestroy(con, (RsProgramFragment)pgm);
 }
 
 
@@ -1122,7 +1122,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nContextBindRootScript, con(%p), script(%p)", con, (RsScript)script);
-    rsContextBindRootScript((RsScript)script);
+    rsContextBindRootScript(con, (RsScript)script);
 }
 
 static void
@@ -1130,7 +1130,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nContextBindProgramFragmentStore, con(%p), pfs(%p)", con, (RsProgramFragmentStore)pfs);
-    rsContextBindProgramFragmentStore((RsProgramFragmentStore)pfs);
+    rsContextBindProgramFragmentStore(con, (RsProgramFragmentStore)pfs);
 }
 
 static void
@@ -1138,7 +1138,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nContextBindProgramFragment, con(%p), pf(%p)", con, (RsProgramFragment)pf);
-    rsContextBindProgramFragment((RsProgramFragment)pf);
+    rsContextBindProgramFragment(con, (RsProgramFragment)pf);
 }
 
 static void
@@ -1146,7 +1146,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nContextBindProgramVertex, con(%p), pf(%p)", con, (RsProgramVertex)pf);
-    rsContextBindProgramVertex((RsProgramVertex)pf);
+    rsContextBindProgramVertex(con, (RsProgramVertex)pf);
 }
 
 static void
@@ -1155,7 +1155,7 @@
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     const char* n = _env->GetStringUTFChars(name, NULL);
     LOG_API("nScriptCAddDefineI32, con(%p) name(%s) value(%d)", con, n, value);
-    rsContextSetDefineI32(n, value);
+    rsContextSetDefineI32(con, n, value);
     _env->ReleaseStringUTFChars(name, n);
 }
 
@@ -1165,7 +1165,7 @@
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     const char* n = _env->GetStringUTFChars(name, NULL);
     LOG_API("nScriptCAddDefineF, con(%p) name(%s) value(%f)", con, n, value);
-    rsContextSetDefineF(n, value);
+    rsContextSetDefineF(con, n, value);
     _env->ReleaseStringUTFChars(name, n);
 }
 
@@ -1177,7 +1177,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nSamplerDestroy, con(%p), sampler(%p)", con, (RsSampler)s);
-    rsSamplerDestroy((RsSampler)s);
+    rsSamplerDestroy(con, (RsSampler)s);
 }
 
 static void
@@ -1185,7 +1185,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nSamplerBegin, con(%p)", con);
-    rsSamplerBegin();
+    rsSamplerBegin(con);
 }
 
 static void
@@ -1193,7 +1193,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nSamplerSet, con(%p), param(%i), value(%i)", con, p, v);
-    rsSamplerSet((RsSamplerParam)p, (RsSamplerValue)v);
+    rsSamplerSet(con, (RsSamplerParam)p, (RsSamplerValue)v);
 }
 
 static jint
@@ -1201,7 +1201,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nSamplerCreate, con(%p)", con);
-    return (jint)rsSamplerCreate();
+    return (jint)rsSamplerCreate(con);
 }
 
 // ---------------------------------------------------------------------------
@@ -1211,7 +1211,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nLightBegin, con(%p)", con);
-    rsLightBegin();
+    rsLightBegin(con);
 }
 
 static void
@@ -1219,7 +1219,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nLightSetIsMono, con(%p), isMono(%i)", con, isMono);
-    rsLightSetMonochromatic(isMono);
+    rsLightSetMonochromatic(con, isMono);
 }
 
 static void
@@ -1227,7 +1227,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nLightSetIsLocal, con(%p), isLocal(%i)", con, isLocal);
-    rsLightSetLocal(isLocal);
+    rsLightSetLocal(con, isLocal);
 }
 
 static jint
@@ -1235,7 +1235,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nLightCreate, con(%p)", con);
-    return (jint)rsLightCreate();
+    return (jint)rsLightCreate(con);
 }
 
 static void
@@ -1243,7 +1243,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nLightDestroy, con(%p), light(%p)", con, (RsLight)light);
-    rsLightDestroy((RsLight)light);
+    rsLightDestroy(con, (RsLight)light);
 }
 
 static void
@@ -1251,7 +1251,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nLightSetColor, con(%p), light(%p), r(%f), g(%f), b(%f)", con, (RsLight)light, r, g, b);
-    rsLightSetColor((RsLight)light, r, g, b);
+    rsLightSetColor(con, (RsLight)light, r, g, b);
 }
 
 static void
@@ -1259,7 +1259,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nLightSetPosition, con(%p), light(%p), x(%f), y(%f), z(%f)", con, (RsLight)light, x, y, z);
-    rsLightSetPosition((RsLight)light, x, y, z);
+    rsLightSetPosition(con, (RsLight)light, x, y, z);
 }
 
 // ---------------------------------------------------------------------------
@@ -1269,7 +1269,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nSimpleMeshDestroy, con(%p), SimpleMesh(%p)", con, (RsSimpleMesh)s);
-    rsSimpleMeshDestroy((RsSimpleMesh)s);
+    rsSimpleMeshDestroy(con, (RsSimpleMesh)s);
 }
 
 static jint
@@ -1280,7 +1280,7 @@
     LOG_API("nSimpleMeshCreate, con(%p), batchID(%i), indexID(%i), vtxIDs.len(%i), primID(%i)",
             con, batchID, indexID, len, primID);
     jint *ptr = _env->GetIntArrayElements(vtxIDs, NULL);
-    int id = (int)rsSimpleMeshCreate((void *)batchID, (void *)indexID, (void **)ptr, len, primID);
+    int id = (int)rsSimpleMeshCreate(con, (void *)batchID, (void *)indexID, (void **)ptr, len, primID);
     _env->ReleaseIntArrayElements(vtxIDs, ptr, 0/*JNI_ABORT*/);
     return id;
 }
@@ -1290,7 +1290,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nSimpleMeshBindVertex, con(%p), SimpleMesh(%p), Alloc(%p), slot(%i)", con, (RsSimpleMesh)s, (RsAllocation)alloc, slot);
-    rsSimpleMeshBindVertex((RsSimpleMesh)s, (RsAllocation)alloc, slot);
+    rsSimpleMeshBindVertex(con, (RsSimpleMesh)s, (RsAllocation)alloc, slot);
 }
 
 static void
@@ -1298,7 +1298,7 @@
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
     LOG_API("nSimpleMeshBindIndex, con(%p), SimpleMesh(%p), Alloc(%p)", con, (RsSimpleMesh)s, (RsAllocation)alloc);
-    rsSimpleMeshBindIndex((RsSimpleMesh)s, (RsAllocation)alloc);
+    rsSimpleMeshBindIndex(con, (RsSimpleMesh)s, (RsAllocation)alloc);
 }
 
 // ---------------------------------------------------------------------------
diff --git a/include/binder/Parcel.h b/include/binder/Parcel.h
index 58c2d9a..ba6c711 100644
--- a/include/binder/Parcel.h
+++ b/include/binder/Parcel.h
@@ -74,6 +74,7 @@
     status_t            writeInt64(int64_t val);
     status_t            writeFloat(float val);
     status_t            writeDouble(double val);
+    status_t            writeIntPtr(intptr_t val);
     status_t            writeCString(const char* str);
     status_t            writeString8(const String8& str);
     status_t            writeString16(const String16& str);
@@ -109,6 +110,8 @@
     status_t            readFloat(float *pArg) const;
     double              readDouble() const;
     status_t            readDouble(double *pArg) const;
+    intptr_t            readIntPtr() const;
+    status_t            readIntPtr(intptr_t *pArg) const;
 
     const char*         readCString() const;
     String8             readString8() const;
@@ -163,6 +166,14 @@
     void                initState();
     void                scanForFds() const;
                         
+    template<class T>
+    status_t            readAligned(T *pArg) const;
+
+    template<class T>   T readAligned() const;
+
+    template<class T>
+    status_t            writeAligned(T val);
+
     status_t            mError;
     uint8_t*            mData;
     size_t              mDataSize;
diff --git a/include/utils/Debug.h b/include/utils/Debug.h
index 21d04bd..d9ed32d 100644
--- a/include/utils/Debug.h
+++ b/include/utils/Debug.h
@@ -29,6 +29,8 @@
 #define COMPILE_TIME_ASSERT(_exp) \
     template class CompileTimeAssert< (_exp) >;
 #endif
+#define COMPILE_TIME_ASSERT_FUNCTION_SCOPE(_exp) \
+    CompileTimeAssert<( _exp )>();
 
 // ---------------------------------------------------------------------------
 
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 785a3c5..e397bce 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -562,54 +562,27 @@
 
 status_t Parcel::writeInt32(int32_t val)
 {
-    if ((mDataPos+sizeof(val)) <= mDataCapacity) {
-restart_write:
-        *reinterpret_cast<int32_t*>(mData+mDataPos) = val;
-        return finishWrite(sizeof(val));
-    }
-
-    status_t err = growData(sizeof(val));
-    if (err == NO_ERROR) goto restart_write;
-    return err;
+    return writeAligned(val);
 }
 
 status_t Parcel::writeInt64(int64_t val)
 {
-    if ((mDataPos+sizeof(val)) <= mDataCapacity) {
-restart_write:
-        *reinterpret_cast<int64_t*>(mData+mDataPos) = val;
-        return finishWrite(sizeof(val));
-    }
-
-    status_t err = growData(sizeof(val));
-    if (err == NO_ERROR) goto restart_write;
-    return err;
+    return writeAligned(val);
 }
 
 status_t Parcel::writeFloat(float val)
 {
-    if ((mDataPos+sizeof(val)) <= mDataCapacity) {
-restart_write:
-        *reinterpret_cast<float*>(mData+mDataPos) = val;
-        return finishWrite(sizeof(val));
-    }
-
-    status_t err = growData(sizeof(val));
-    if (err == NO_ERROR) goto restart_write;
-    return err;
+    return writeAligned(val);
 }
 
 status_t Parcel::writeDouble(double val)
 {
-    if ((mDataPos+sizeof(val)) <= mDataCapacity) {
-restart_write:
-        *reinterpret_cast<double*>(mData+mDataPos) = val;
-        return finishWrite(sizeof(val));
-    }
+    return writeAligned(val);
+}
 
-    status_t err = growData(sizeof(val));
-    if (err == NO_ERROR) goto restart_write;
-    return err;
+status_t Parcel::writeIntPtr(intptr_t val)
+{
+    return writeAligned(val);
 }
 
 status_t Parcel::writeCString(const char* str)
@@ -768,103 +741,98 @@
     return NULL;
 }
 
-status_t Parcel::readInt32(int32_t *pArg) const
-{
-    if ((mDataPos+sizeof(int32_t)) <= mDataSize) {
+template<class T>
+status_t Parcel::readAligned(T *pArg) const {
+    COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE(sizeof(T)) == sizeof(T));
+
+    if ((mDataPos+sizeof(T)) <= mDataSize) {
         const void* data = mData+mDataPos;
-        mDataPos += sizeof(int32_t);
-        *pArg =  *reinterpret_cast<const int32_t*>(data);
+        mDataPos += sizeof(T);
+        *pArg =  *reinterpret_cast<const T*>(data);
         return NO_ERROR;
     } else {
         return NOT_ENOUGH_DATA;
     }
 }
 
+template<class T>
+T Parcel::readAligned() const {
+    T result;
+    if (readAligned(&result) != NO_ERROR) {
+        result = 0;
+    }
+
+    return result;
+}
+
+template<class T>
+status_t Parcel::writeAligned(T val) {
+    COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE(sizeof(T)) == sizeof(T));
+
+    if ((mDataPos+sizeof(val)) <= mDataCapacity) {
+restart_write:
+        *reinterpret_cast<T*>(mData+mDataPos) = val;
+        return finishWrite(sizeof(val));
+    }
+
+    status_t err = growData(sizeof(val));
+    if (err == NO_ERROR) goto restart_write;
+    return err;
+}
+
+status_t Parcel::readInt32(int32_t *pArg) const
+{
+    return readAligned(pArg);
+}
+
 int32_t Parcel::readInt32() const
 {
-    if ((mDataPos+sizeof(int32_t)) <= mDataSize) {
-        const void* data = mData+mDataPos;
-        mDataPos += sizeof(int32_t);
-        LOGV("readInt32 Setting data pos of %p to %d\n", this, mDataPos);
-        return *reinterpret_cast<const int32_t*>(data);
-    }
-    return 0;
+    return readAligned<int32_t>();
 }
 
 
 status_t Parcel::readInt64(int64_t *pArg) const
 {
-    if ((mDataPos+sizeof(int64_t)) <= mDataSize) {
-        const void* data = mData+mDataPos;
-        mDataPos += sizeof(int64_t);
-        *pArg = *reinterpret_cast<const int64_t*>(data);
-        LOGV("readInt64 Setting data pos of %p to %d\n", this, mDataPos);
-        return NO_ERROR;
-    } else {
-        return NOT_ENOUGH_DATA;
-    }
+    return readAligned(pArg);
 }
 
 
 int64_t Parcel::readInt64() const
 {
-    if ((mDataPos+sizeof(int64_t)) <= mDataSize) {
-        const void* data = mData+mDataPos;
-        mDataPos += sizeof(int64_t);
-        LOGV("readInt64 Setting data pos of %p to %d\n", this, mDataPos);
-        return *reinterpret_cast<const int64_t*>(data);
-    }
-    return 0;
+    return readAligned<int64_t>();
 }
 
 status_t Parcel::readFloat(float *pArg) const
 {
-    if ((mDataPos+sizeof(float)) <= mDataSize) {
-        const void* data = mData+mDataPos;
-        mDataPos += sizeof(float);
-        LOGV("readFloat Setting data pos of %p to %d\n", this, mDataPos);
-        *pArg = *reinterpret_cast<const float*>(data);
-        return NO_ERROR;
-    } else {
-        return NOT_ENOUGH_DATA;
-    }
+    return readAligned(pArg);
 }
 
 
 float Parcel::readFloat() const
 {
-    if ((mDataPos+sizeof(float)) <= mDataSize) {
-        const void* data = mData+mDataPos;
-        mDataPos += sizeof(float);
-        LOGV("readFloat Setting data pos of %p to %d\n", this, mDataPos);
-        return *reinterpret_cast<const float*>(data);
-    }
-    return 0;
+    return readAligned<float>();
 }
 
 status_t Parcel::readDouble(double *pArg) const
 {
-    if ((mDataPos+sizeof(double)) <= mDataSize) {
-        const void* data = mData+mDataPos;
-        mDataPos += sizeof(double);
-        LOGV("readDouble Setting data pos of %p to %d\n", this, mDataPos);
-        *pArg = *reinterpret_cast<const double*>(data);
-        return NO_ERROR;
-    } else {
-        return NOT_ENOUGH_DATA;
-    }
+    return readAligned(pArg);
 }
 
 
 double Parcel::readDouble() const
 {
-    if ((mDataPos+sizeof(double)) <= mDataSize) {
-        const void* data = mData+mDataPos;
-        mDataPos += sizeof(double);
-        LOGV("readDouble Setting data pos of %p to %d\n", this, mDataPos);
-        return *reinterpret_cast<const double*>(data);
-    }
-    return 0;
+    return readAligned<double>();
+}
+
+status_t Parcel::readIntPtr(intptr_t *pArg) const
+{
+    return readAligned(pArg);
+}
+
+
+intptr_t Parcel::readIntPtr() const
+{
+    return readAligned<intptr_t>();
 }
 
 
diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp
index 2860452..52389ea 100644
--- a/libs/rs/rsContext.cpp
+++ b/libs/rs/rsContext.cpp
@@ -84,11 +84,6 @@
 
 bool Context::runRootScript()
 {
-#if RS_LOG_TIMES
-    struct timespec beginTime;
-    clock_gettime(CLOCK_MONOTONIC, &beginTime);
-#endif
-
     rsAssert(mRootScript->mEnviroment.mIsRoot);
 
     //glColor4f(1,1,1,1);
@@ -116,9 +111,10 @@
     struct timespec endTime;
     clock_gettime(CLOCK_MONOTONIC, &endTime);
 
-    int t1 = ((unsigned long)startTime.tv_nsec - (unsigned long)beginTime.tv_nsec) / 1000 / 1000;
-    int t2 = ((unsigned long)endTime.tv_nsec - (unsigned long)startTime.tv_nsec) / 1000 / 1000;
-    LOGE("times  %i,  %i", t1, t2);
+    uint64_t t1 = endTime.tv_nsec + ((uint64_t)endTime.tv_sec * 1000 * 1000 * 1000);
+    uint64_t t2 = startTime.tv_nsec + ((uint64_t)startTime.tv_sec * 1000 * 1000 * 1000);
+    int t3 = (int)((t1 - t2) / 1000 / 1000);
+    LOGE("times  %i", t3);
 #endif
 
     return ret;
@@ -143,7 +139,6 @@
 {
      Context *rsc = static_cast<Context *>(vrsc);
 
-     gIO = new ThreadIO();
      rsc->initEGL();
 
      ScriptTLSStruct *tlsStruct = new ScriptTLSStruct;
@@ -168,7 +163,7 @@
      rsc->mRunning = true;
      bool mDraw = true;
      while (!rsc->mExit) {
-         mDraw |= gIO->playCoreCommands(rsc, !mDraw);
+         mDraw |= rsc->mIO.playCoreCommands(rsc, !mDraw);
          mDraw &= (rsc->mRootScript.get() != NULL);
 
          if (mDraw) {
diff --git a/libs/rs/rsContext.h b/libs/rs/rsContext.h
index 60a526b..3d17298 100644
--- a/libs/rs/rsContext.h
+++ b/libs/rs/rsContext.h
@@ -21,6 +21,7 @@
 
 #include <ui/Surface.h>
 
+#include "rsThreadIO.h"
 #include "rsType.h"
 #include "rsMatrix.h"
 #include "rsAllocation.h"
@@ -115,6 +116,9 @@
     uint32_t getWidth() const {return mWidth;}
     uint32_t getHeight() const {return mHeight;}
 
+
+    ThreadIO mIO;
+
 protected:
     Device *mDev;
 
diff --git a/libs/rs/rsThreadIO.cpp b/libs/rs/rsThreadIO.cpp
index 89df59d..20b0a94 100644
--- a/libs/rs/rsThreadIO.cpp
+++ b/libs/rs/rsThreadIO.cpp
@@ -21,8 +21,6 @@
 using namespace android;
 using namespace android::renderscript;
 
-ThreadIO *android::renderscript::gIO = NULL;
-
 ThreadIO::ThreadIO()
 {
     mToCore.init(16 * 1024);
diff --git a/libs/rs/rsThreadIO.h b/libs/rs/rsThreadIO.h
index 72746c5..4aab1b4 100644
--- a/libs/rs/rsThreadIO.h
+++ b/libs/rs/rsThreadIO.h
@@ -43,9 +43,6 @@
 
 };
 
-extern ThreadIO *gIO;
-
-
 
 }
 }
diff --git a/libs/rs/rsg_generator.c b/libs/rs/rsg_generator.c
index 7cf6bb6..e3f816f 100644
--- a/libs/rs/rsg_generator.c
+++ b/libs/rs/rsg_generator.c
@@ -103,8 +103,10 @@
     fprintf(f, " %s%s (", prefix, api->name);
     if (addContext) {
         fprintf(f, "Context *");
+    } else {
+        fprintf(f, "RsContext rsc");
     }
-    printArgList(f, api, addContext);
+    printArgList(f, api, 1);
     fprintf(f, ")");
 }
 
@@ -147,7 +149,7 @@
 
         printFuncDecl(f, api, "rs", 0);
         fprintf(f, "\n{\n");
-        fprintf(f, "    ThreadIO *io = gIO;\n");
+        fprintf(f, "    ThreadIO *io = &((Context *)rsc)->mIO;\n");
         //fprintf(f, "    LOGE(\"add command %s\\n\");\n", api->name);
         fprintf(f, "    RS_CMD_%s *cmd = static_cast<RS_CMD_%s *>(io->mToCore.reserve(sizeof(RS_CMD_%s)));\n", api->name, api->name, api->name);
         fprintf(f, "    uint32_t size = sizeof(RS_CMD_%s);\n", api->name);
@@ -200,7 +202,7 @@
         fprintf(f, "    const RS_CMD_%s *cmd = static_cast<const RS_CMD_%s *>(vp);\n", api->name, api->name);
         fprintf(f, "    ");
         if (api->ret.typeName[0]) {
-            fprintf(f, "gIO->mToCoreRet = (intptr_t)");
+            fprintf(f, "con->mIO.mToCoreRet = (intptr_t)");
         }
         fprintf(f, "rsi_%s(con", api->name);
         for(ct2=0; ct2 < api->paramCount; ct2++) {
diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp
index ec3241c..10bebd0 100644
--- a/media/libmedia/IOMX.cpp
+++ b/media/libmedia/IOMX.cpp
@@ -45,16 +45,6 @@
             displayWidth, displayHeight);
 }
 
-static void *readVoidStar(const Parcel *parcel) {
-    // FIX if sizeof(void *) != sizeof(int32)
-    return (void *)parcel->readInt32();
-}
-
-static void writeVoidStar(void *x, Parcel *parcel) {
-    // FIX if sizeof(void *) != sizeof(int32)
-    parcel->writeInt32((int32_t)x);
-}
-
 class BpOMX : public BpInterface<IOMX> {
 public:
     BpOMX(const sp<IBinder> &impl)
@@ -86,7 +76,7 @@
 
         status_t err = reply.readInt32();
         if (err == OK) {
-            *node = readVoidStar(&reply);
+            *node = (void*)reply.readIntPtr();
         } else {
             *node = 0;
         }
@@ -97,7 +87,7 @@
     virtual status_t free_node(node_id node) {
         Parcel data, reply;
         data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
-        writeVoidStar(node, &data);
+        data.writeIntPtr((intptr_t)node);
         remote()->transact(FREE_NODE, data, &reply);
 
         return reply.readInt32();
@@ -107,7 +97,7 @@
             node_id node, OMX_COMMANDTYPE cmd, OMX_S32 param) {
         Parcel data, reply;
         data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
-        writeVoidStar(node, &data);
+        data.writeIntPtr((intptr_t)node);
         data.writeInt32(cmd);
         data.writeInt32(param);
         remote()->transact(SEND_COMMAND, data, &reply);
@@ -120,7 +110,7 @@
             void *params, size_t size) {
         Parcel data, reply;
         data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
-        writeVoidStar(node, &data);
+        data.writeIntPtr((intptr_t)node);
         data.writeInt32(index);
         data.writeInt32(size);
         data.write(params, size);
@@ -141,7 +131,7 @@
             const void *params, size_t size) {
         Parcel data, reply;
         data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
-        writeVoidStar(node, &data);
+        data.writeIntPtr((intptr_t)node);
         data.writeInt32(index);
         data.writeInt32(size);
         data.write(params, size);
@@ -155,7 +145,7 @@
             void *params, size_t size) {
         Parcel data, reply;
         data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
-        writeVoidStar(node, &data);
+        data.writeIntPtr((intptr_t)node);
         data.writeInt32(index);
         data.writeInt32(size);
         data.write(params, size);
@@ -176,7 +166,7 @@
             const void *params, size_t size) {
         Parcel data, reply;
         data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
-        writeVoidStar(node, &data);
+        data.writeIntPtr((intptr_t)node);
         data.writeInt32(index);
         data.writeInt32(size);
         data.write(params, size);
@@ -190,7 +180,7 @@
             buffer_id *buffer) {
         Parcel data, reply;
         data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
-        writeVoidStar(node, &data);
+        data.writeIntPtr((intptr_t)node);
         data.writeInt32(port_index);
         data.writeStrongBinder(params->asBinder());
         remote()->transact(USE_BUFFER, data, &reply);
@@ -202,7 +192,7 @@
             return err;
         }
 
-        *buffer = readVoidStar(&reply);
+        *buffer = (void*)reply.readIntPtr();
 
         return err;
     }
@@ -212,7 +202,7 @@
             buffer_id *buffer) {
         Parcel data, reply;
         data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
-        writeVoidStar(node, &data);
+        data.writeIntPtr((intptr_t)node);
         data.writeInt32(port_index);
         data.writeInt32(size);
         remote()->transact(ALLOC_BUFFER, data, &reply);
@@ -224,7 +214,7 @@
             return err;
         }
 
-        *buffer = readVoidStar(&reply);
+        *buffer = (void*)reply.readIntPtr();
 
         return err;
     }
@@ -234,7 +224,7 @@
             buffer_id *buffer) {
         Parcel data, reply;
         data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
-        writeVoidStar(node, &data);
+        data.writeIntPtr((intptr_t)node);
         data.writeInt32(port_index);
         data.writeStrongBinder(params->asBinder());
         remote()->transact(ALLOC_BUFFER_WITH_BACKUP, data, &reply);
@@ -246,7 +236,7 @@
             return err;
         }
 
-        *buffer = readVoidStar(&reply);
+        *buffer = (void*)reply.readIntPtr();
 
         return err;
     }
@@ -255,9 +245,9 @@
             node_id node, OMX_U32 port_index, buffer_id buffer) {
         Parcel data, reply;
         data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
-        writeVoidStar(node, &data);
+        data.writeIntPtr((intptr_t)node);
         data.writeInt32(port_index);
-        writeVoidStar(buffer, &data);
+        data.writeIntPtr((intptr_t)buffer);
         remote()->transact(FREE_BUFFER, data, &reply);
 
         return reply.readInt32();
@@ -267,7 +257,7 @@
             node_id node, const sp<IOMXObserver> &observer) {
         Parcel data, reply;
         data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
-        writeVoidStar(node, &data);
+        data.writeIntPtr((intptr_t)node);
         data.writeStrongBinder(observer->asBinder());
         remote()->transact(OBSERVE_NODE, data, &reply);
 
@@ -277,8 +267,8 @@
     virtual void fill_buffer(node_id node, buffer_id buffer) {
         Parcel data, reply;
         data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
-        writeVoidStar(node, &data);
-        writeVoidStar(buffer, &data);
+        data.writeIntPtr((intptr_t)node);
+        data.writeIntPtr((intptr_t)buffer);
         remote()->transact(FILL_BUFFER, data, &reply, IBinder::FLAG_ONEWAY);
     }
 
@@ -289,8 +279,8 @@
             OMX_U32 flags, OMX_TICKS timestamp) {
         Parcel data, reply;
         data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
-        writeVoidStar(node, &data);
-        writeVoidStar(buffer, &data);
+        data.writeIntPtr((intptr_t)node);
+        data.writeIntPtr((intptr_t)buffer);
         data.writeInt32(range_offset);
         data.writeInt32(range_length);
         data.writeInt32(flags);
@@ -304,7 +294,7 @@
             OMX_INDEXTYPE *index) {
         Parcel data, reply;
         data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
-        writeVoidStar(node, &data);
+        data.writeIntPtr((intptr_t)node);
         data.writeCString(parameter_name);
 
         remote()->transact(GET_EXTENSION_INDEX, data, &reply);
@@ -379,7 +369,7 @@
             status_t err = allocate_node(data.readCString(), &node);
             reply->writeInt32(err);
             if (err == OK) {
-                writeVoidStar(node, reply);
+                reply->writeIntPtr((intptr_t)node);
             }
                 
             return NO_ERROR;
@@ -389,7 +379,7 @@
         {
             CHECK_INTERFACE(IOMX, data, reply);
 
-            node_id node = readVoidStar(&data);
+            node_id node = (void*)data.readIntPtr();
 
             reply->writeInt32(free_node(node));
                 
@@ -400,7 +390,7 @@
         {
             CHECK_INTERFACE(IOMX, data, reply);
 
-            node_id node = readVoidStar(&data);
+            node_id node = (void*)data.readIntPtr();
 
             OMX_COMMANDTYPE cmd =
                 static_cast<OMX_COMMANDTYPE>(data.readInt32());
@@ -415,7 +405,7 @@
         {
             CHECK_INTERFACE(IOMX, data, reply);
 
-            node_id node = readVoidStar(&data);
+            node_id node = (void*)data.readIntPtr();
             OMX_INDEXTYPE index = static_cast<OMX_INDEXTYPE>(data.readInt32());
 
             size_t size = data.readInt32();
@@ -442,7 +432,7 @@
         {
             CHECK_INTERFACE(IOMX, data, reply);
 
-            node_id node = readVoidStar(&data);
+            node_id node = (void*)data.readIntPtr();
             OMX_INDEXTYPE index = static_cast<OMX_INDEXTYPE>(data.readInt32());
 
             size_t size = data.readInt32();
@@ -457,7 +447,7 @@
         {
             CHECK_INTERFACE(IOMX, data, reply);
 
-            node_id node = readVoidStar(&data);
+            node_id node = (void*)data.readIntPtr();
             OMX_INDEXTYPE index = static_cast<OMX_INDEXTYPE>(data.readInt32());
 
             size_t size = data.readInt32();
@@ -484,7 +474,7 @@
         {
             CHECK_INTERFACE(IOMX, data, reply);
 
-            node_id node = readVoidStar(&data);
+            node_id node = (void*)data.readIntPtr();
             OMX_INDEXTYPE index = static_cast<OMX_INDEXTYPE>(data.readInt32());
 
             size_t size = data.readInt32();
@@ -499,7 +489,7 @@
         {
             CHECK_INTERFACE(IOMX, data, reply);
 
-            node_id node = readVoidStar(&data);
+            node_id node = (void*)data.readIntPtr();
             OMX_U32 port_index = data.readInt32();
             sp<IMemory> params =
                 interface_cast<IMemory>(data.readStrongBinder());
@@ -509,7 +499,7 @@
             reply->writeInt32(err);
 
             if (err == OK) {
-                writeVoidStar(buffer, reply);
+                reply->writeIntPtr((intptr_t)buffer);
             }
 
             return NO_ERROR;
@@ -519,7 +509,7 @@
         {
             CHECK_INTERFACE(IOMX, data, reply);
 
-            node_id node = readVoidStar(&data);
+            node_id node = (void*)data.readIntPtr();
             OMX_U32 port_index = data.readInt32();
             size_t size = data.readInt32();
 
@@ -528,7 +518,7 @@
             reply->writeInt32(err);
 
             if (err == OK) {
-                writeVoidStar(buffer, reply);
+                reply->writeIntPtr((intptr_t)buffer);
             }
 
             return NO_ERROR;
@@ -538,7 +528,7 @@
         {
             CHECK_INTERFACE(IOMX, data, reply);
 
-            node_id node = readVoidStar(&data);
+            node_id node = (void*)data.readIntPtr();
             OMX_U32 port_index = data.readInt32();
             sp<IMemory> params =
                 interface_cast<IMemory>(data.readStrongBinder());
@@ -550,7 +540,7 @@
             reply->writeInt32(err);
 
             if (err == OK) {
-                writeVoidStar(buffer, reply);
+                reply->writeIntPtr((intptr_t)buffer);
             }
 
             return NO_ERROR;
@@ -560,9 +550,9 @@
         {
             CHECK_INTERFACE(IOMX, data, reply);
 
-            node_id node = readVoidStar(&data);
+            node_id node = (void*)data.readIntPtr();
             OMX_U32 port_index = data.readInt32();
-            buffer_id buffer = readVoidStar(&data);
+            buffer_id buffer = (void*)data.readIntPtr();
             reply->writeInt32(free_buffer(node, port_index, buffer));
 
             return NO_ERROR;
@@ -572,7 +562,7 @@
         {
             CHECK_INTERFACE(IOMX, data, reply);
 
-            node_id node = readVoidStar(&data);
+            node_id node = (void*)data.readIntPtr();
             sp<IOMXObserver> observer =
                 interface_cast<IOMXObserver>(data.readStrongBinder());
             reply->writeInt32(observe_node(node, observer));
@@ -584,8 +574,8 @@
         {
             CHECK_INTERFACE(IOMX, data, reply);
 
-            node_id node = readVoidStar(&data);
-            buffer_id buffer = readVoidStar(&data);
+            node_id node = (void*)data.readIntPtr();
+            buffer_id buffer = (void*)data.readIntPtr();
             fill_buffer(node, buffer);
 
             return NO_ERROR;
@@ -595,8 +585,8 @@
         {
             CHECK_INTERFACE(IOMX, data, reply);
 
-            node_id node = readVoidStar(&data);
-            buffer_id buffer = readVoidStar(&data);
+            node_id node = (void*)data.readIntPtr();
+            buffer_id buffer = (void*)data.readIntPtr();
             OMX_U32 range_offset = data.readInt32();
             OMX_U32 range_length = data.readInt32();
             OMX_U32 flags = data.readInt32();
@@ -613,7 +603,7 @@
         {
             CHECK_INTERFACE(IOMX, data, reply);
 
-            node_id node = readVoidStar(&data);
+            node_id node = (void*)data.readIntPtr();
             const char *parameter_name = data.readCString();
             
             OMX_INDEXTYPE index;
@@ -711,7 +701,7 @@
     virtual void render(IOMX::buffer_id buffer) {
         Parcel data, reply;
         data.writeInterfaceToken(IOMXRenderer::getInterfaceDescriptor());
-        writeVoidStar(buffer, &data);
+        data.writeIntPtr((intptr_t)buffer);
 
         // NOTE: Do NOT make this a ONE_WAY call, it must be synchronous
         // so that the caller knows when to recycle the buffer.
@@ -728,7 +718,7 @@
         {
             CHECK_INTERFACE(IOMXRenderer, data, reply);
 
-            IOMX::buffer_id buffer = readVoidStar(&data);
+            IOMX::buffer_id buffer = (void*)data.readIntPtr();
 
             render(buffer);
 
diff --git a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
index fa0ffcd..29e89b5 100644
--- a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
@@ -24,14 +24,18 @@
 import android.os.RemoteException;
 import android.provider.Settings;
 import android.provider.Settings.SettingNotFoundException;
+import android.text.TextUtils;
 import android.util.Log;
 
+import java.util.ArrayList;
+
 /**
  * {@hide}
  *
  */
 public abstract class DataConnectionTracker extends Handler {
-    private static final boolean DBG = true;
+    protected static final boolean DBG = true;
+    protected final String LOG_TAG = "DataConnectionTracker";
 
     /**
      * IDLE: ready to start data connection setup, default state
@@ -98,6 +102,20 @@
 
     //***** Constants
 
+    protected static final int APN_INVALID_ID = -1;
+    protected static final int APN_DEFAULT_ID = 0;
+    protected static final int APN_MMS_ID = 1;
+    protected static final int APN_SUPL_ID = 2;
+    protected static final int APN_DUN_ID = 3;
+    protected static final int APN_HIPRI_ID = 4;
+    protected static final int APN_NUM_TYPES = 5;
+
+    protected boolean[] dataEnabled = new boolean[APN_NUM_TYPES];
+    protected int enabledCount = 0;
+
+    /* Currently requested APN type */
+    protected String mRequestedApnType = Phone.APN_TYPE_DEFAULT;
+
     /** Retry configuration: A doubling of retry times from 5secs to 30minutes */
     protected static final String DEFAULT_DATA_RETRY_CONFIG = "default_randomization=2000,"
         + "5000,10000,20000,40000,80000:5000,160000:5000,"
@@ -167,6 +185,8 @@
         this.phone = phone;
     }
 
+    public abstract void dispose();
+
     public Activity getActivity() {
         return activity;
     }
@@ -301,24 +321,18 @@
      * @return {@code false} if data connectivity has been explicitly disabled,
      * {@code true} otherwise.
      */
-    public abstract boolean getDataEnabled();
+    public boolean getDataEnabled() {
+        return dataEnabled[APN_DEFAULT_ID];
+    }
 
     /**
      * Report on whether data connectivity is enabled
      * @return {@code false} if data connectivity has been explicitly disabled,
      * {@code true} otherwise.
      */
-    public abstract boolean getAnyDataEnabled();
-
-    /**
-     * Prevent mobile data connections from being established,
-     * or once again allow mobile data connections. If the state
-     * toggles, then either tear down or set up data, as
-     * appropriate to match the new state.
-     * @param enable indicates whether to enable ({@code true}) or disable ({@code false}) data
-     * @return {@code true} if the operation succeeded
-     */
-    public abstract boolean setDataEnabled(boolean enable);
+    public boolean getAnyDataEnabled() {
+        return (enabledCount != 0);
+    }
 
     protected abstract void startNetStatPoll();
 
@@ -327,4 +341,162 @@
     protected abstract void restartRadio();
 
     protected abstract void log(String s);
+
+    protected int apnTypeToId(String type) {
+        if (TextUtils.equals(type, Phone.APN_TYPE_DEFAULT)) {
+            return APN_DEFAULT_ID;
+        } else if (TextUtils.equals(type, Phone.APN_TYPE_MMS)) {
+            return APN_MMS_ID;
+        } else if (TextUtils.equals(type, Phone.APN_TYPE_SUPL)) {
+            return APN_SUPL_ID;
+        } else if (TextUtils.equals(type, Phone.APN_TYPE_DUN)) {
+            return APN_DUN_ID;
+        } else if (TextUtils.equals(type, Phone.APN_TYPE_HIPRI)) {
+            return APN_HIPRI_ID;
+        } else {
+            return APN_INVALID_ID;
+        }
+    }
+
+    protected abstract boolean isApnTypeActive(String type);
+
+    protected abstract boolean isApnTypeAvailable(String type);
+
+    protected abstract String[] getActiveApnTypes();
+
+    protected abstract String getActiveApnString();
+
+    public abstract ArrayList<DataConnection> getAllDataConnections();
+
+    protected abstract String getInterfaceName(String apnType);
+
+    protected abstract String getIpAddress(String apnType);
+
+    protected abstract String getGateway(String apnType);
+
+    protected abstract String[] getDnsServers(String apnType);
+
+    protected abstract void setState(State s);
+
+    protected boolean isEnabled(int id) {
+        if (id != APN_INVALID_ID) {
+            return dataEnabled[id];
+        }
+        return false;
+    }
+
+    /**
+     * Ensure that we are connected to an APN of the specified type.
+     * @param type the APN type (currently the only valid values
+     * are {@link Phone#APN_TYPE_MMS} and {@link Phone#APN_TYPE_SUPL})
+     * @return the result of the operation. Success is indicated by
+     * a return value of either {@code Phone.APN_ALREADY_ACTIVE} or
+     * {@code Phone.APN_REQUEST_STARTED}. In the latter case, a broadcast
+     * will be sent by the ConnectivityManager when a connection to
+     * the APN has been established.
+     */
+    public int enableApnType(String type) {
+        int id = apnTypeToId(type);
+        if (id == APN_INVALID_ID) {
+            return Phone.APN_REQUEST_FAILED;
+        }
+
+        // If already active, return
+        if(DBG) Log.d(LOG_TAG, "enableApnType("+type+"), isApnTypeActive = "
+                + isApnTypeActive(type) + " and state = " + state);
+
+        if (isApnTypeActive(type)) {
+            if (state == State.INITING) return Phone.APN_REQUEST_STARTED;
+            else if (state == State.CONNECTED) return Phone.APN_ALREADY_ACTIVE;
+        }
+
+        if (!isApnTypeAvailable(type)) {
+            return Phone.APN_TYPE_NOT_AVAILABLE;
+        }
+
+        setEnabled(id, true);
+        mRequestedApnType = type;
+        sendMessage(obtainMessage(EVENT_ENABLE_NEW_APN));
+        return Phone.APN_REQUEST_STARTED;
+    }
+
+    /**
+     * The APN of the specified type is no longer needed. Ensure that if
+     * use of the default APN has not been explicitly disabled, we are connected
+     * to the default APN.
+     * @param type the APN type. The only valid values are currently
+     * {@link Phone#APN_TYPE_MMS} and {@link Phone#APN_TYPE_SUPL}.
+     * @return
+     */
+    public int disableApnType(String type) {
+        if (DBG) Log.d(LOG_TAG, "disableApnType("+type+")");
+        int id = apnTypeToId(type);
+        if (id == APN_INVALID_ID) {
+            return Phone.APN_REQUEST_FAILED;
+        }
+        if (isEnabled(id)) {
+            setEnabled(id, false);
+            if (isApnTypeActive(Phone.APN_TYPE_DEFAULT)) {
+                mRequestedApnType = Phone.APN_TYPE_DEFAULT;
+                if (dataEnabled[APN_DEFAULT_ID]) {
+                    return Phone.APN_ALREADY_ACTIVE;
+                } else {
+                    return Phone.APN_REQUEST_STARTED;
+                }
+            } else {
+                return Phone.APN_REQUEST_STARTED;
+            }
+        } else {
+            return Phone.APN_REQUEST_FAILED;
+        }
+    }
+
+    protected synchronized void setEnabled(int id, boolean enable) {
+        if (DBG) Log.d(LOG_TAG, "setEnabled(" + id + ", " + enable + ')');
+        if (dataEnabled[id] != enable) {
+            dataEnabled[id] = enable;
+
+            if (enable) {
+                enabledCount++;
+            } else {
+                enabledCount--;
+            }
+
+            if (enabledCount == 0) {
+                setPrivateDataEnabled(false);
+            } else if (enabledCount == 1) {
+                setPrivateDataEnabled(true);
+            }
+        }
+    }
+
+    /**
+     * Prevent mobile data connections from being established,
+     * or once again allow mobile data connections. If the state
+     * toggles, then either tear down or set up data, as
+     * appropriate to match the new state.
+     * <p>This operation only affects the default APN, and if the same APN is
+     * currently being used for MMS traffic, the teardown will not happen
+     * even when {@code enable} is {@code false}.</p>
+     * @param enable indicates whether to enable ({@code true}) or disable ({@code false}) data
+     * @return {@code true} if the operation succeeded
+     */
+    public boolean setDataEnabled(boolean enable) {
+        if (DBG) Log.d(LOG_TAG, "setDataEnabled("+enable+")");
+        setEnabled(APN_DEFAULT_ID, enable);
+        return true;
+    }
+
+    private void setPrivateDataEnabled(boolean enable) {
+        if (DBG) Log.d(LOG_TAG, "setPrivateDataEnabled("+enable+")");
+        if (enable) {
+            sendMessage(obtainMessage(EVENT_TRY_SETUP_DATA));
+        } else {
+            Message msg = obtainMessage(EVENT_CLEAN_UP_CONNECTION);
+            msg.arg1 = 1; // tearDown is true
+            msg.obj = Phone.REASON_DATA_DISABLED;
+            sendMessage(msg);
+        }
+    }
+
 }
diff --git a/telephony/java/com/android/internal/telephony/PhoneBase.java b/telephony/java/com/android/internal/telephony/PhoneBase.java
index b279527..6f4aef9 100644
--- a/telephony/java/com/android/internal/telephony/PhoneBase.java
+++ b/telephony/java/com/android/internal/telephony/PhoneBase.java
@@ -109,6 +109,7 @@
     public CommandsInterface mCM;
     protected IccFileHandler mIccFileHandler;
     boolean mDnsCheckDisabled = false;
+    public DataConnectionTracker mDataConnection;
 
     /**
      * Set a system property, unless we're in unit test mode
@@ -824,4 +825,71 @@
         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
          Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone.");
      }
+
+    public String getInterfaceName(String apnType) {
+        return mDataConnection.getInterfaceName(apnType);
+    }
+
+    public String getIpAddress(String apnType) {
+        return mDataConnection.getIpAddress(apnType);
+    }
+
+    public boolean isDataConnectivityEnabled() {
+        return mDataConnection.getDataEnabled();
+    }
+
+    public String getGateway(String apnType) {
+        return mDataConnection.getGateway(apnType);
+    }
+
+    public String[] getDnsServers(String apnType) {
+        return mDataConnection.getDnsServers(apnType);
+    }
+
+    public String[] getActiveApnTypes() {
+        return mDataConnection.getActiveApnTypes();
+    }
+
+    public String getActiveApn() {
+        return mDataConnection.getActiveApnString();
+    }
+
+    public int enableApnType(String type) {
+        return mDataConnection.enableApnType(type);
+    }
+
+    public int disableApnType(String type) {
+        return mDataConnection.disableApnType(type);
+    }
+
+    /**
+     * simulateDataConnection
+     *
+     * simulates various data connection states. This messes with
+     * DataConnectionTracker's internal states, but doesn't actually change
+     * the underlying radio connection states.
+     *
+     * @param state Phone.DataState enum.
+     */
+    public void simulateDataConnection(Phone.DataState state) {
+        DataConnectionTracker.State dcState;
+
+        switch (state) {
+            case CONNECTED:
+                dcState = DataConnectionTracker.State.CONNECTED;
+                break;
+            case SUSPENDED:
+                dcState = DataConnectionTracker.State.CONNECTED;
+                break;
+            case DISCONNECTED:
+                dcState = DataConnectionTracker.State.FAILED;
+                break;
+            default:
+                dcState = DataConnectionTracker.State.CONNECTING;
+                break;
+        }
+
+        mDataConnection.setState(dcState);
+        notifyDataConnection(null);
+    }
 }
diff --git a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
index 522fa1d..f0c0ea2 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
@@ -95,7 +95,6 @@
     CdmaCallTracker mCT;
     CdmaSMSDispatcher mSMS;
     CdmaServiceStateTracker mSST;
-    CdmaDataConnectionTracker mDataConnection;
     RuimFileHandler mRuimFileHandler;
     RuimRecords mRuimRecords;
     RuimCard mRuimCard;
@@ -369,42 +368,11 @@
         return mCT.backgroundCall;
     }
 
-    public String getGateway(String apnType) {
-        return mDataConnection.getGateway();
-    }
-
     public boolean handleInCallMmiCommands(String dialString) {
         Log.e(LOG_TAG, "method handleInCallMmiCommands is NOT supported in CDMA!");
         return false;
     }
 
-    public int enableApnType(String type) {
-        // This request is mainly used to enable MMS APN
-        // In CDMA there is no need to enable/disable a different APN for MMS
-        Log.d(LOG_TAG, "Request to enableApnType("+type+")");
-        if (TextUtils.equals(type, Phone.APN_TYPE_MMS)) {
-            return Phone.APN_ALREADY_ACTIVE;
-        } else {
-            return Phone.APN_REQUEST_FAILED;
-        }
-    }
-
-    public int disableApnType(String type) {
-        // This request is mainly used to disable MMS APN
-        // In CDMA there is no need to enable/disable a different APN for MMS
-        Log.d(LOG_TAG, "Request to disableApnType("+type+")");
-        if (TextUtils.equals(type, Phone.APN_TYPE_MMS)) {
-            return Phone.APN_REQUEST_STARTED;
-        } else {
-            return Phone.APN_REQUEST_FAILED;
-        }
-    }
-
-    public String getActiveApn() {
-        Log.d(LOG_TAG, "Request to getActiveApn()");
-        return null;
-    }
-
     public void
     setNetworkSelectionModeAutomatic(Message response) {
         Log.e(LOG_TAG, "method setNetworkSelectionModeAutomatic is NOT supported in CDMA!");
@@ -481,10 +449,6 @@
         return false;
     }
 
-    public String getInterfaceName(String apnType) {
-        return mDataConnection.getInterfaceName();
-    }
-
     public CellLocation getCellLocation() {
         return mSST.cellLoc;
     }
@@ -512,10 +476,6 @@
         return false;
     }
 
-    public boolean isDataConnectivityEnabled() {
-        return mDataConnection.getDataEnabled();
-    }
-
     public boolean isDataConnectivityPossible() {
         boolean noData = mDataConnection.getDataEnabled() &&
                 getDataConnectionState() == DataState.DISCONNECTED;
@@ -528,10 +488,6 @@
         Log.e(LOG_TAG, "setLine1Number: not possible in CDMA");
     }
 
-    public String[] getDnsServers(String apnType) {
-        return mDataConnection.getDnsServers();
-    }
-
     public IccCard getIccCard() {
         return mRuimCard;
     }
@@ -584,10 +540,6 @@
         mCT.unregisterForCallWaiting(h);
     }
 
-    public String getIpAddress(String apnType) {
-        return mDataConnection.getIpAddress();
-    }
-
     public void
     getNeighboringCids(Message response) {
         /*
@@ -701,14 +653,6 @@
         Log.e(LOG_TAG, "getAvailableNetworks: not possible in CDMA");
     }
 
-    public String[] getActiveApnTypes() {
-        String[] result;
-        Log.d(LOG_TAG, "Request to getActiveApn()");
-        result = new String[1];
-        result[0] = Phone.APN_TYPE_DEFAULT;
-        return result;
-    }
-
     public void setOutgoingCallerIdDisplay(int commandInterfaceCLIRMode, Message onComplete) {
         Log.e(LOG_TAG, "setOutgoingCallerIdDisplay: not possible in CDMA");
     }
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
index 8bae483..d02d33e 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
@@ -57,8 +57,7 @@
  * {@hide}
  */
 public final class CdmaDataConnectionTracker extends DataConnectionTracker {
-    private static final String LOG_TAG = "CDMA";
-    private static final boolean DBG = true;
+    protected final String LOG_TAG = "CDMA";
 
     private CDMAPhone mCdmaPhone;
 
@@ -77,12 +76,6 @@
     /** Currently active CdmaDataConnection */
     private CdmaDataConnection mActiveDataConnection;
 
-    /** Defined cdma connection profiles */
-    private static final int EXTERNAL_NETWORK_DEFAULT_ID = 0;
-    private static final int EXTERNAL_NETWORK_NUM_TYPES  = 1;
-
-    private boolean[] dataEnabled = new boolean[EXTERNAL_NETWORK_NUM_TYPES];
-
     /**
      * Pool size of CdmaDataConnection objects.
      */
@@ -101,6 +94,11 @@
      private static final int DATA_CONNECTION_ACTIVE_PH_LINK_DOWN = 1;
      private static final int DATA_CONNECTION_ACTIVE_PH_LINK_UP = 2;
 
+    private static final String[] mSupportedApnTypes = {
+            Phone.APN_TYPE_DEFAULT,
+            Phone.APN_TYPE_MMS,
+            Phone.APN_TYPE_HIPRI };
+
     // Possibly promoate to base class, the only difference is
     // the INTENT_RECONNECT_ALARM action is a different string.
     // Do consider technology changes if it is promoted.
@@ -182,9 +180,12 @@
         // and 2) whether the RIL will setup the baseband to auto-PS attach.
         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(phone.getContext());
 
-        dataEnabled[EXTERNAL_NETWORK_DEFAULT_ID] =
+        dataEnabled[APN_DEFAULT_ID] =
                 !sp.getBoolean(CDMAPhone.DATA_DISABLED_ON_BOOT_KEY, false);
-        noAutoAttach = !dataEnabled[EXTERNAL_NETWORK_DEFAULT_ID];
+        if (dataEnabled[APN_DEFAULT_ID]) {
+            enabledCount++;
+        }
+        noAutoAttach = !dataEnabled[APN_DEFAULT_ID];
 
         if (!mRetryMgr.configure(SystemProperties.get("ro.cdma.data_retry_config"))) {
             if (!mRetryMgr.configure(DEFAULT_DATA_RETRY_CONFIG)) {
@@ -219,7 +220,7 @@
         if(DBG) Log.d(LOG_TAG, "CdmaDataConnectionTracker finalized");
     }
 
-    void setState(State s) {
+    protected void setState(State s) {
         if (DBG) log ("setState: " + s);
         if (state != s) {
             if (s == State.INITING) { // request Data connection context
@@ -236,39 +237,33 @@
         state = s;
     }
 
-    public int enableApnType(String type) {
-        // This request is mainly used to enable MMS APN
-        // In CDMA there is no need to enable/disable a different APN for MMS
-        Log.d(LOG_TAG, "Request to enableApnType("+type+")");
-        if (TextUtils.equals(type, Phone.APN_TYPE_MMS)) {
-            return Phone.APN_ALREADY_ACTIVE;
-        } else if (TextUtils.equals(type, Phone.APN_TYPE_SUPL)) {
-            Log.w(LOG_TAG, "Phone.APN_TYPE_SUPL not enabled for CDMA");
-            return Phone.APN_REQUEST_FAILED;
-        } else {
-            return Phone.APN_REQUEST_FAILED;
+    @Override
+    protected boolean isApnTypeActive(String type) {
+        return (isApnTypeAvailable(type) &&
+                mCdmaPhone.mSST.getCurrentCdmaDataConnectionState() ==
+                ServiceState.STATE_IN_SERVICE);
+    }
+
+    @Override
+    protected boolean isApnTypeAvailable(String type) {
+        for (String s : mSupportedApnTypes) {
+            if (TextUtils.equals(type, s)) {
+                return true;
+            }
         }
+        return false;
     }
 
-    public int disableApnType(String type) {
-        // This request is mainly used to disable MMS APN
-        // In CDMA there is no need to enable/disable a different APN for MMS
-        Log.d(LOG_TAG, "Request to disableApnType("+type+")");
-        if (TextUtils.equals(type, Phone.APN_TYPE_MMS)) {
-            return Phone.APN_REQUEST_STARTED;
-        } else {
-            return Phone.APN_REQUEST_FAILED;
+    protected String[] getActiveApnTypes() {
+        if (mCdmaPhone.mSST.getCurrentCdmaDataConnectionState() ==
+                ServiceState.STATE_IN_SERVICE) {
+            return mSupportedApnTypes.clone();
         }
+        return new String[0];
     }
 
-    private boolean isEnabled(int cdmaDataProfile) {
-        return dataEnabled[cdmaDataProfile];
-    }
-
-    private void setEnabled(int cdmaDataProfile, boolean enable) {
-        Log.d(LOG_TAG, "setEnabled("  + cdmaDataProfile + ", " + enable + ')');
-        dataEnabled[cdmaDataProfile] = enable;
-        Log.d(LOG_TAG, "dataEnabled[DEFAULT_PROFILE]=" + dataEnabled[EXTERNAL_NETWORK_DEFAULT_ID]);
+    protected String getActiveApnString() {
+        return null;
     }
 
     /**
@@ -294,54 +289,6 @@
         return true;
     }
 
-    /**
-     * Prevent mobile data connections from being established,
-     * or once again allow mobile data connections. If the state
-     * toggles, then either tear down or set up data, as
-     * appropriate to match the new state.
-     * <p>This operation only affects the default connection
-     * @param enable indicates whether to enable ({@code true}) or disable ({@code false}) data
-     * @return {@code true} if the operation succeeded
-     */
-    public boolean setDataEnabled(boolean enable) {
-
-        boolean isEnabled = isEnabled(EXTERNAL_NETWORK_DEFAULT_ID);
-
-        Log.d(LOG_TAG, "setDataEnabled("+enable+") isEnabled=" + isEnabled);
-        if (!isEnabled && enable) {
-            setEnabled(EXTERNAL_NETWORK_DEFAULT_ID, true);
-            sendMessage(obtainMessage(EVENT_TRY_SETUP_DATA));
-        } else if (!enable) {
-            setEnabled(EXTERNAL_NETWORK_DEFAULT_ID, false);
-            Message msg = obtainMessage(EVENT_CLEAN_UP_CONNECTION);
-            msg.arg1 = 1; // tearDown is true
-            msg.obj = Phone.REASON_DATA_DISABLED;
-            sendMessage(msg);
-        }
-        return true;
-    }
-
-    /**
-     * Report the current state of data connectivity (enabled or disabled)
-     * @return {@code false} if data connectivity has been explicitly disabled,
-     * {@code true} otherwise.
-     */
-    public boolean getDataEnabled() {
-        return dataEnabled[EXTERNAL_NETWORK_DEFAULT_ID];
-    }
-
-    /**
-     * Report on whether data connectivity is enabled
-     * @return {@code false} if data connectivity has been explicitly disabled,
-     * {@code true} otherwise.
-     */
-    public boolean getAnyDataEnabled() {
-        for (int i=0; i < EXTERNAL_NETWORK_NUM_TYPES; i++) {
-            if (isEnabled(i)) return true;
-        }
-        return false;
-    }
-
     private boolean isDataAllowed() {
         boolean roaming = phone.getServiceState().getRoaming();
         return getAnyDataEnabled() && (!roaming || getDataOnRoamingEnabled());
@@ -921,28 +868,28 @@
         }
     }
 
-    String getInterfaceName() {
+    protected String getInterfaceName(String apnType) {
         if (mActiveDataConnection != null) {
             return mActiveDataConnection.getInterface();
         }
         return null;
     }
 
-    protected String getIpAddress() {
+    protected String getIpAddress(String apnType) {
         if (mActiveDataConnection != null) {
             return mActiveDataConnection.getIpAddress();
         }
         return null;
     }
 
-    String getGateway() {
+    protected String getGateway(String apnType) {
         if (mActiveDataConnection != null) {
             return mActiveDataConnection.getGatewayAddress();
         }
         return null;
     }
 
-    protected String[] getDnsServers() {
+    protected String[] getDnsServers(String apnType) {
         if (mActiveDataConnection != null) {
             return mActiveDataConnection.getDnsServers();
         }
diff --git a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
index 94d4344..bb04a43 100755
--- a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
@@ -102,7 +102,6 @@
     GsmCallTracker mCT;
     GsmServiceStateTracker mSST;
     GsmSMSDispatcher mSMS;
-    GsmDataConnectionTracker mDataConnection;
     SIMRecords mSIMRecords;
     SimCard mSimCard;
     StkService mStkService;
@@ -280,14 +279,6 @@
         return "GSM";
     }
 
-    public String[] getActiveApnTypes() {
-        return mDataConnection.getActiveApnTypes();
-    }
-
-    public String getActiveApn() {
-        return mDataConnection.getActiveApnString();
-    }
-
     public SignalStrength getSignalStrength() {
         return mSST.mSignalStrength;
     }
@@ -1145,38 +1136,10 @@
         return mDataConnection.setDataEnabled(true);
     }
 
-    public int enableApnType(String type) {
-        return mDataConnection.enableApnType(type);
-    }
-
-    public int disableApnType(String type) {
-        return mDataConnection.disableApnType(type);
-    }
-
     public boolean disableDataConnectivity() {
         return mDataConnection.setDataEnabled(false);
     }
 
-    public String getInterfaceName(String apnType) {
-        return mDataConnection.getInterfaceName(apnType);
-    }
-
-    public String getIpAddress(String apnType) {
-        return mDataConnection.getIpAddress(apnType);
-    }
-
-    public String getGateway(String apnType) {
-        return mDataConnection.getGateway(apnType);
-    }
-
-    public String[] getDnsServers(String apnType) {
-        return mDataConnection.getDnsServers(apnType);
-    }
-
-    public boolean isDataConnectivityEnabled() {
-        return mDataConnection.getDataEnabled();
-    }
-
     /**
      * The only circumstances under which we report that data connectivity is not
      * possible are
@@ -1543,36 +1506,6 @@
             }
         }
     }
-    /**
-     * simulateDataConnection
-     *
-     * simulates various data connection states. This messes with
-     * DataConnectionTracker's internal states, but doesn't actually change
-     * the underlying radio connection states.
-     *
-     * @param state Phone.DataState enum.
-     */
-    public void simulateDataConnection(Phone.DataState state) {
-        DataConnectionTracker.State dcState;
-
-        switch (state) {
-            case CONNECTED:
-                dcState = DataConnectionTracker.State.CONNECTED;
-                break;
-            case SUSPENDED:
-                dcState = DataConnectionTracker.State.CONNECTED;
-                break;
-            case DISCONNECTED:
-                dcState = DataConnectionTracker.State.FAILED;
-                break;
-            default:
-                dcState = DataConnectionTracker.State.CONNECTING;
-                break;
-        }
-
-        mDataConnection.setState(dcState);
-        notifyDataConnection(null);
-    }
 
     /**
      * Retrieves the PhoneSubInfo of the GSMPhone
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
index 34d3039..b9688f3 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
@@ -63,8 +63,7 @@
  * {@hide}
  */
 public final class GsmDataConnectionTracker extends DataConnectionTracker {
-    private static final String LOG_TAG = "GSM";
-    private static final boolean DBG = true;
+    protected final String LOG_TAG = "GSM";
 
     private GSMPhone mGsmPhone;
     /**
@@ -119,31 +118,17 @@
 
     private ApnSetting preferredApn = null;
 
+    /* Currently active APN */
+    protected ApnSetting mActiveApn;
+
     /**
      * pdpList holds all the PDP connection, i.e. IP Link in GPRS
      */
     private ArrayList<DataConnection> pdpList;
 
-    /** Currently requested APN type */
-    private String mRequestedApnType = Phone.APN_TYPE_DEFAULT;
-
-    /** Currently active APN */
-    private ApnSetting mActiveApn;
-
     /** Currently active PdpConnection */
     private PdpConnection mActivePdp;
 
-    private static int APN_INVALID_ID = -1;
-    private static int APN_DEFAULT_ID = 0;
-    private static int APN_MMS_ID = 1;
-    private static int APN_SUPL_ID = 2;
-    private static int APN_DUN_ID = 3;
-    private static int APN_HIPRI_ID = 4;
-    private static int APN_NUM_TYPES = 5;
-
-    private boolean[] dataEnabled = new boolean[APN_NUM_TYPES];
-    private int enabledCount = 0;
-
     /** Is packet service restricted by network */
     private boolean mIsPsRestricted = false;
 
@@ -293,7 +278,7 @@
         if(DBG) Log.d(LOG_TAG, "GsmDataConnectionTracker finalized");
     }
 
-    void setState(State s) {
+    protected void setState(State s) {
         if (DBG) log ("setState: " + s);
         if (state != s) {
             if (s == State.INITING) { // request PDP context
@@ -317,7 +302,7 @@
         }
     }
 
-    String[] getActiveApnTypes() {
+    public String[] getActiveApnTypes() {
         String[] result;
         if (mActiveApn != null) {
             result = mActiveApn.types;
@@ -336,87 +321,6 @@
         return result;
     }
 
-    protected int apnTypeToId(String type) {
-        if (TextUtils.equals(type, Phone.APN_TYPE_DEFAULT)) {
-            return APN_DEFAULT_ID;
-        } else if (TextUtils.equals(type, Phone.APN_TYPE_MMS)) {
-            return APN_MMS_ID;
-        } else if (TextUtils.equals(type, Phone.APN_TYPE_SUPL)) {
-            return APN_SUPL_ID;
-        } else if (TextUtils.equals(type, Phone.APN_TYPE_DUN)) {
-            return APN_DUN_ID;
-        } else if (TextUtils.equals(type, Phone.APN_TYPE_HIPRI)) {
-            return APN_HIPRI_ID;
-        } else {
-            return APN_INVALID_ID;
-        }
-    }
-
-    /**
-     * Ensure that we are connected to an APN of the specified type.
-     * @param type the APN type (currently the only valid values
-     * are {@link Phone#APN_TYPE_MMS} and {@link Phone#APN_TYPE_SUPL})
-     * @return the result of the operation. Success is indicated by
-     * a return value of either {@code Phone.APN_ALREADY_ACTIVE} or
-     * {@code Phone.APN_REQUEST_STARTED}. In the latter case, a broadcast
-     * will be sent by the ConnectivityManager when a connection to
-     * the APN has been established.
-     */
-    protected int enableApnType(String type) {
-        int id = apnTypeToId(type);
-        if (id == APN_INVALID_ID) {
-            return Phone.APN_REQUEST_FAILED;
-        }
-
-        // If already active, return
-        if(DBG) Log.d(LOG_TAG, "enableApnType("+type+"), isApnTypeActive = "
-                + isApnTypeActive(type) + " and state = " + state);
-        if (isApnTypeActive(type)) {
-            if (state == State.INITING) return Phone.APN_REQUEST_STARTED;
-            else if (state == State.CONNECTED) return Phone.APN_ALREADY_ACTIVE;
-        }
-
-        if (!isApnTypeAvailable(type)) {
-            return Phone.APN_TYPE_NOT_AVAILABLE;
-        }
-
-        setEnabled(id, true);
-        mRequestedApnType = type;
-        sendMessage(obtainMessage(EVENT_ENABLE_NEW_APN));
-        return Phone.APN_REQUEST_STARTED;
-    }
-
-    /**
-     * The APN of the specified type is no longer needed. Ensure that if
-     * use of the default APN has not been explicitly disabled, we are connected
-     * to the default APN.
-     * @param type the APN type. The only valid values are currently
-     * {@link Phone#APN_TYPE_MMS} and {@link Phone#APN_TYPE_SUPL}.
-     * @return
-     */
-    protected int disableApnType(String type) {
-        if (DBG) Log.d(LOG_TAG, "disableApnType("+type+")");
-        int id = apnTypeToId(type);
-        if (id == APN_INVALID_ID) {
-            return Phone.APN_REQUEST_FAILED;
-        }
-        if (isEnabled(id)) {
-            setEnabled(id, false);
-            if (isApnTypeActive(Phone.APN_TYPE_DEFAULT)) {
-                mRequestedApnType = Phone.APN_TYPE_DEFAULT;
-                if (dataEnabled[APN_DEFAULT_ID]) {
-                    return Phone.APN_ALREADY_ACTIVE;
-                } else {
-                    return Phone.APN_REQUEST_STARTED;
-                }
-            } else {
-                return Phone.APN_REQUEST_STARTED;
-            }
-        } else {
-            return Phone.APN_REQUEST_FAILED;
-        }
-    }
-
     /**
      * The data connection is expected to be setup while device
      *  1. has sim card
@@ -427,7 +331,7 @@
      * @return false while no data connection if all above requirements are met.
      */
     public boolean isDataConnectionAsDesired() {
-        boolean roaming = phone.getServiceState().getRoaming();
+        boolean roaming = getDataRoaming();
 
         if (mGsmPhone.mSIMRecords.getRecordsLoaded() &&
                 mGsmPhone.mSST.getCurrentGprsState() == ServiceState.STATE_IN_SERVICE &&
@@ -439,12 +343,18 @@
         return true;
     }
 
-    private boolean isApnTypeActive(String type) {
-        // TODO: to support simultaneous, mActiveApn can be a List instead.
+    private boolean getDataRoaming() {
+        return mGsmPhone.mSST.getDataRoaming();
+    }
+
+    @Override
+    protected boolean isApnTypeActive(String type) {
+        // TODO: support simultaneous with List instead
         return mActiveApn != null && mActiveApn.canHandleType(type);
     }
 
-    private boolean isApnTypeAvailable(String type) {
+    @Override
+    protected boolean isApnTypeAvailable(String type) {
         if (allApns != null) {
             for (ApnSetting apn : allApns) {
                 if (apn.canHandleType(type)) {
@@ -455,80 +365,6 @@
         return false;
     }
 
-    private boolean isEnabled(int id) {
-        if (id != APN_INVALID_ID) {
-            return dataEnabled[id];
-        }
-        return false;
-    }
-
-    private void setEnabled(int id, boolean enable) {
-        if (DBG) Log.d(LOG_TAG, "setEnabled(" + id + ", " + enable + ')');
-        if (dataEnabled[id] != enable) {
-            dataEnabled[id] = enable;
-
-            if (enable) {
-                enabledCount++;
-            } else {
-                enabledCount--;
-            }
-
-            if (enabledCount == 0) {
-                setPrivateDataEnabled(false);
-            } else if (enabledCount == 1) {
-                setPrivateDataEnabled(true);
-            }
-        }
-    }
-
-    /**
-     * Prevent mobile data connections from being established,
-     * or once again allow mobile data connections. If the state
-     * toggles, then either tear down or set up data, as
-     * appropriate to match the new state.
-     * <p>This operation only affects the default APN, and if the same APN is
-     * currently being used for MMS traffic, the teardown will not happen
-     * even when {@code enable} is {@code false}.</p>
-     * @param enable indicates whether to enable ({@code true}) or disable ({@code false}) data
-     * @return {@code true} if the operation succeeded
-     */
-    public boolean setDataEnabled(boolean enable) {
-        if (DBG) Log.d(LOG_TAG, "setDataEnabled("+enable+")");
-        setEnabled(APN_DEFAULT_ID, enable);
-        return true;
-    }
-
-    private void setPrivateDataEnabled(boolean enable) {
-        if (DBG) Log.d(LOG_TAG, "setPrivateDataEnabled("+enable+")");
-        if (enable) {
-            sendMessage(obtainMessage(EVENT_TRY_SETUP_DATA));
-        } else {
-            Message msg = obtainMessage(EVENT_CLEAN_UP_CONNECTION);
-            msg.arg1 = 1; // tearDown is true
-            msg.obj = Phone.REASON_DATA_DISABLED;
-            sendMessage(msg);
-        }
-    }
-
-    /**
-     * Report the current state of data connectivity (enabled or disabled) for
-     * the default APN.
-     * @return {@code false} if data connectivity has been explicitly disabled,
-     * {@code true} otherwise.
-     */
-    public boolean getDataEnabled() {
-        return dataEnabled[APN_DEFAULT_ID];
-    }
-
-    /**
-     * Report on whether data connectivity is enabled for any APN.
-     * @return {@code false} if data connectivity has been explicitly disabled,
-     * {@code true} otherwise.
-     */
-    public boolean getAnyDataEnabled() {
-        return (enabledCount != 0);
-    }
-
     /**
      * Formerly this method was ArrayList<PdpConnection> getAllPdps()
      */
@@ -538,7 +374,7 @@
     }
 
     private boolean isDataAllowed() {
-        boolean roaming = phone.getServiceState().getRoaming();
+        boolean roaming = getDataRoaming();
         return getAnyDataEnabled() && (!roaming || getDataOnRoamingEnabled());
     }
 
@@ -585,7 +421,7 @@
         }
 
         int gprsState = mGsmPhone.mSST.getCurrentGprsState();
-        boolean roaming = phone.getServiceState().getRoaming();
+        boolean roaming = getDataRoaming();
         boolean desiredPowerState = mGsmPhone.mSST.getDesiredPowerState();
 
         if ((state == State.IDLE || state == State.SCANNING)
@@ -744,7 +580,7 @@
         return true;
     }
 
-    String getInterfaceName(String apnType) {
+    protected String getInterfaceName(String apnType) {
         if (mActivePdp != null
                 && (apnType == null || mActiveApn.canHandleType(apnType))) {
             return mActivePdp.getInterface();
@@ -760,7 +596,7 @@
         return null;
     }
 
-    String getGateway(String apnType) {
+    public String getGateway(String apnType) {
         if (mActivePdp != null
                 && (apnType == null || mActiveApn.canHandleType(apnType))) {
             return mActivePdp.getGatewayAddress();
@@ -1242,16 +1078,38 @@
         trySetupData(reason);
     }
 
+    /**
+     * Check the data roaming consistency since this can be triggered by
+     * voice roaming flag of ServiceState in setDataOnRoamingEnabled()
+     *
+     * TODO make this triggered by data roaming state only
+     */
+    @Override
     protected void onRoamingOff() {
-        trySetupData(Phone.REASON_ROAMING_OFF);
+        if (!getDataRoaming()) { //data roaming is off
+            trySetupData(Phone.REASON_ROAMING_OFF);
+        } else { // Inconsistent! data roaming is on
+            sendMessage(obtainMessage(EVENT_ROAMING_ON));
+        }
     }
 
+    /**
+     * Check the data roaming consistency since this can be triggered by
+     * voice roaming flag of ServiceState in setDataOnRoamingEnabled()
+     *
+     * TODO make this triggered by data roaming state only
+     */
+    @Override
     protected void onRoamingOn() {
-        if (getDataOnRoamingEnabled()) {
-            trySetupData(Phone.REASON_ROAMING_ON);
-        } else {
-            if (DBG) log("Tear down data connection on roaming.");
-            cleanUpConnection(true, Phone.REASON_ROAMING_ON);
+        if (getDataRoaming()) { // data roaming is on
+            if (getDataOnRoamingEnabled()) {
+                trySetupData(Phone.REASON_ROAMING_ON);
+            } else {
+                if (DBG) log("Tear down data connection on roaming.");
+                cleanUpConnection(true, Phone.REASON_ROAMING_ON);
+            }
+        } else { // Inconsistent! data roaming is off
+            sendMessage(obtainMessage(EVENT_ROAMING_OFF));
         }
     }
 
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
index 4178115..0c040e6 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
@@ -88,6 +88,9 @@
     private int newNetworkType = 0;
     /* gsm roaming status solely based on TS 27.007 7.2 CREG */
     private boolean mGsmRoaming = false;
+    /* data roaming status solely based on TS 27.007 10.1.19 CGREG */
+    private boolean mDataRoaming = false;
+    private boolean newDataRoaming = false;
 
     private RegistrantList gprsAttachedRegistrants = new RegistrantList();
     private RegistrantList gprsDetachedRegistrants = new RegistrantList();
@@ -311,6 +314,10 @@
         psRestrictDisabledRegistrants.remove(h);
     }
 
+    /*protected*/ boolean getDataRoaming() {
+        return mDataRoaming;
+    }
+
     //***** Called from GSMPhone
     public void
     getLacAndCid(Message onComplete) {
@@ -668,6 +675,7 @@
                         }
                     }
                     newGPRSState = regCodeToServiceState(regState);
+                    newDataRoaming = regCodeIsRoaming(regState);
                     newNetworkType = type;
                 break;
 
@@ -695,6 +703,11 @@
 
         if (pollingContext[0] == 0) {
             newSS.setRoaming(isRoamingBetweenOperators(mGsmRoaming, newSS));
+            // when both roaming indicators are true but not roaming between
+            // operators, roaming should set to false.
+            if (newDataRoaming && mGsmRoaming && !newSS.getRoaming()) {
+                newDataRoaming = false;
+            }
             pollStateDone();
         }
 
@@ -724,6 +737,7 @@
                 newCellLoc.setStateInvalid();
                 setSignalStrengthDefaultValues();
                 mGotCountryCode = false;
+                newDataRoaming = false;
 
                 pollStateDone();
             break;
@@ -733,6 +747,7 @@
                 newCellLoc.setStateInvalid();
                 setSignalStrengthDefaultValues();
                 mGotCountryCode = false;
+                newDataRoaming = false;
 
                 pollStateDone();
             break;
@@ -747,6 +762,8 @@
                 newCellLoc.setStateInvalid();
                 setSignalStrengthDefaultValues();
                 mGotCountryCode = false;
+                newDataRoaming = false;
+                mDataRoaming = false;
 
                 //NOTE: pollStateDone() is not needed in this case
                 break;
@@ -831,9 +848,9 @@
 
         boolean hasChanged = !newSS.equals(ss);
 
-        boolean hasRoamingOn = !ss.getRoaming() && newSS.getRoaming();
+        boolean hasRoamingOn = !mDataRoaming && newDataRoaming;
 
-        boolean hasRoamingOff = ss.getRoaming() && !newSS.getRoaming();
+        boolean hasRoamingOff = mDataRoaming && !newDataRoaming;
 
         boolean hasLocationChanged = !newCellLoc.equals(cellLoc);
 
@@ -850,6 +867,7 @@
 
         gprsState = newGPRSState;
         networkType = newNetworkType;
+        mDataRoaming = newDataRoaming;
 
         newSS.setStateOutOfService(); // clean slate for next time
 
diff --git a/tests/backup/backup_stress_test.sh b/tests/backup/backup_stress_test.sh
new file mode 100755
index 0000000..8155507
--- /dev/null
+++ b/tests/backup/backup_stress_test.sh
@@ -0,0 +1,64 @@
+#!/bin/bash
+
+# Copyright (C) 2009 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.
+
+iterations=150
+failures=0
+i=0
+LOGDIR="$HOME/backup_tests"
+LOGFILE="$LOGDIR/backup_stress.`date +%s`.log"
+export BUGREPORT_DIR="$LOGDIR/bugreports"
+
+# make sure that we have a place to put logs and bugreports
+mkdir -p $LOGDIR $BUGREPORT_DIR
+
+echo "logfile is $LOGFILE"
+
+(while (sleep 10); do
+    failed=0
+    
+    echo
+    echo "Iteration $i at `date`"
+    echo
+
+    ./test_backup.sh "$@" 2>&1
+
+    sleep 10
+    echo "Restore at `date`"
+    echo
+
+    ./test_restore.sh "$@" 2>&1 || failed=1
+    
+    if [ "$failed" -ne 0 ]; then
+        failures=$(($failures+1))
+        # Long and verbose so it sticks out
+        echo "FAILED iteration $i of $iterations; $failures failures so far"
+        echo "FAILED iteration $i of $iterations; $failures failures so far" > /dev/stderr
+    else
+        printf "Iteration %d:\tPASS; remaining: %d\n" $i $(($iterations - $i - 1))
+        printf "Iteration %d:\tPASS; remaining: %d\n" $i $(($iterations - $i - 1)) > /dev/stderr
+    fi
+
+    echo "End $i at `date`"
+    
+    i=$(($i+1))
+    if [ $i -eq $iterations ]; then
+        echo "DONE: $iterations iterations with $failures failures."
+        echo "DONE: $iterations iterations with $failures failures." > /dev/stderr
+        [ "$failures" -eq 0 ] && exit 0
+        exit 1
+    fi
+done) > "$LOGFILE"
+
diff --git a/tests/backup/test_restore.sh b/tests/backup/test_restore.sh
index 4506c16..46b46e4 100755
--- a/tests/backup/test_restore.sh
+++ b/tests/backup/test_restore.sh
@@ -18,7 +18,7 @@
 #export DRY_RUN="echo"
 source test_backup_common.sh
 
-BUGREPORT_DIR="$HOME/backup/bugreports"
+[ -z "$BUGREPORT_DIR" ] && BUGREPORT_DIR="$HOME/backup/bugreports"
 
 function check_file
 {
@@ -107,3 +107,5 @@
 echo "Last 3 timestamps in 3.txt:"
 a shell cat /data/data/com.android.backuptest/files/3.txt | tail -n 3
 
+exit $need_bug
+