Merge "Suppress tests in ListManagedCursorTest."
diff --git a/api/current.txt b/api/current.txt
index f5e2cda..05d9604 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -12303,6 +12303,7 @@
     method public int getIntrinsicWidth();
     method public int getLayoutDirection();
     method public final int getLevel();
+    method public final float getLevelFloat();
     method public int getMinimumHeight();
     method public int getMinimumWidth();
     method public abstract int getOpacity();
@@ -12322,6 +12323,7 @@
     method protected void onBoundsChange(android.graphics.Rect);
     method public boolean onLayoutDirectionChanged(int);
     method protected boolean onLevelChange(int);
+    method protected boolean onLevelChange(float);
     method protected boolean onStateChange(int[]);
     method public static int resolveOpacity(int, int);
     method public void scheduleSelf(java.lang.Runnable, long);
@@ -12339,12 +12341,15 @@
     method public void setHotspotBounds(int, int, int, int);
     method public final boolean setLayoutDirection(int);
     method public final boolean setLevel(int);
+    method public final boolean setLevel(float);
     method public boolean setState(int[]);
     method public void setTint(int);
     method public void setTintList(android.content.res.ColorStateList);
     method public void setTintMode(android.graphics.PorterDuff.Mode);
     method public boolean setVisible(boolean, boolean);
     method public void unscheduleSelf(java.lang.Runnable);
+    field public static final int MAX_LEVEL = 10000; // 0x2710
+    field public static final float MAX_LEVEL_FLOAT = 10000.0f;
   }
 
   public static abstract interface Drawable.Callback {
diff --git a/api/system-current.txt b/api/system-current.txt
index ec8f952..de0b7ed 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -12640,6 +12640,7 @@
     method public int getIntrinsicWidth();
     method public int getLayoutDirection();
     method public final int getLevel();
+    method public final float getLevelFloat();
     method public int getMinimumHeight();
     method public int getMinimumWidth();
     method public abstract int getOpacity();
@@ -12659,6 +12660,7 @@
     method protected void onBoundsChange(android.graphics.Rect);
     method public boolean onLayoutDirectionChanged(int);
     method protected boolean onLevelChange(int);
+    method protected boolean onLevelChange(float);
     method protected boolean onStateChange(int[]);
     method public static int resolveOpacity(int, int);
     method public void scheduleSelf(java.lang.Runnable, long);
@@ -12676,12 +12678,15 @@
     method public void setHotspotBounds(int, int, int, int);
     method public final boolean setLayoutDirection(int);
     method public final boolean setLevel(int);
+    method public final boolean setLevel(float);
     method public boolean setState(int[]);
     method public void setTint(int);
     method public void setTintList(android.content.res.ColorStateList);
     method public void setTintMode(android.graphics.PorterDuff.Mode);
     method public boolean setVisible(boolean, boolean);
     method public void unscheduleSelf(java.lang.Runnable);
+    field public static final int MAX_LEVEL = 10000; // 0x2710
+    field public static final float MAX_LEVEL_FLOAT = 10000.0f;
   }
 
   public static abstract interface Drawable.Callback {
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 5970c3f..bcf9b2c 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -484,6 +484,7 @@
         public boolean secure;
         public long appVsyncOffsetNanos;
         public long presentationDeadlineNanos;
+        public int colorTransform;
 
         public PhysicalDisplayInfo() {
         }
@@ -507,7 +508,8 @@
                     && yDpi == other.yDpi
                     && secure == other.secure
                     && appVsyncOffsetNanos == other.appVsyncOffsetNanos
-                    && presentationDeadlineNanos == other.presentationDeadlineNanos;
+                    && presentationDeadlineNanos == other.presentationDeadlineNanos
+                    && colorTransform == other.colorTransform;
         }
 
         @Override
@@ -525,6 +527,7 @@
             secure = other.secure;
             appVsyncOffsetNanos = other.appVsyncOffsetNanos;
             presentationDeadlineNanos = other.presentationDeadlineNanos;
+            colorTransform = other.colorTransform;
         }
 
         // For debugging purposes
@@ -533,7 +536,8 @@
             return "PhysicalDisplayInfo{" + width + " x " + height + ", " + refreshRate + " fps, "
                     + "density " + density + ", " + xDpi + " x " + yDpi + " dpi, secure " + secure
                     + ", appVsyncOffset " + appVsyncOffsetNanos
-                    + ", bufferDeadline " + presentationDeadlineNanos + "}";
+                    + ", bufferDeadline " + presentationDeadlineNanos
+                    + ", colorTransform " + colorTransform + "}";
         }
     }
 
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 959d249..af73097 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -179,19 +179,15 @@
 
     static void preload() {
         Log.d(TAG, "begin preload");
-        try {
-            Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadClasses");
-            preloadClasses();
-        } finally {
-            Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
-        }
-        try {
-            Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadResources");
-            preloadResources();
-        } finally {
-            Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
-        }
+        Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadClasses");
+        preloadClasses();
+        Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
+        Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadResources");
+        preloadResources();
+        Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
+        Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadOpenGL");
         preloadOpenGL();
+        Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
         preloadSharedLibraries();
         preloadTextResources();
         // Ask the WebViewFactory to do any initialization that must run in the zygote process,
@@ -275,8 +271,8 @@
                     continue;
                 }
 
+                Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadClass " + line);
                 try {
-                    Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadClass " + line);
                     if (false) {
                         Log.v(TAG, "Preloading " + line + "...");
                     }
@@ -300,9 +296,8 @@
                         throw (RuntimeException) t;
                     }
                     throw new RuntimeException(t);
-                } finally {
-                    Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
                 }
+                Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
             }
 
             Log.i(TAG, "...preloaded " + count + " classes in "
@@ -579,57 +574,49 @@
 
     public static void main(String argv[]) {
         try {
+            Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "ZygoteInit");
+            RuntimeInit.enableDdms();
+            // Start profiling the zygote initialization.
+            SamplingProfilerIntegration.start();
+
             boolean startSystemServer = false;
             String socketName = "zygote";
             String abiList = null;
-            try {
-                Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "ZygoteInit");
-                RuntimeInit.enableDdms();
-                // Start profiling the zygote initialization.
-                SamplingProfilerIntegration.start();
-
-                for (int i = 1; i < argv.length; i++) {
-                    if ("start-system-server".equals(argv[i])) {
-                        startSystemServer = true;
-                    } else if (argv[i].startsWith(ABI_LIST_ARG)) {
-                        abiList = argv[i].substring(ABI_LIST_ARG.length());
-                    } else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
-                        socketName = argv[i].substring(SOCKET_NAME_ARG.length());
-                    } else {
-                        throw new RuntimeException("Unknown command line argument: " + argv[i]);
-                    }
+            for (int i = 1; i < argv.length; i++) {
+                if ("start-system-server".equals(argv[i])) {
+                    startSystemServer = true;
+                } else if (argv[i].startsWith(ABI_LIST_ARG)) {
+                    abiList = argv[i].substring(ABI_LIST_ARG.length());
+                } else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
+                    socketName = argv[i].substring(SOCKET_NAME_ARG.length());
+                } else {
+                    throw new RuntimeException("Unknown command line argument: " + argv[i]);
                 }
-
-                if (abiList == null) {
-                    throw new RuntimeException("No ABI list supplied.");
-                }
-
-                registerZygoteSocket(socketName);
-                try {
-                    Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "ZygotePreload");
-                    EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
-                            SystemClock.uptimeMillis());
-                    preload();
-                    EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
-                            SystemClock.uptimeMillis());
-                } finally {
-                    Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
-                }
-
-                // Finish profiling the zygote initialization.
-                SamplingProfilerIntegration.writeZygoteSnapshot();
-
-                // Do an initial gc to clean up after startup
-                try {
-                    Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PostZygoteInitGC");
-                    gcAndFinalize();
-                } finally {
-                    Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
-                }
-            } finally {
-                Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
             }
 
+            if (abiList == null) {
+                throw new RuntimeException("No ABI list supplied.");
+            }
+
+            registerZygoteSocket(socketName);
+            Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "ZygotePreload");
+            EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
+                SystemClock.uptimeMillis());
+            preload();
+            EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
+                SystemClock.uptimeMillis());
+            Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
+
+            // Finish profiling the zygote initialization.
+            SamplingProfilerIntegration.writeZygoteSnapshot();
+
+            // Do an initial gc to clean up after startup
+            Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PostZygoteInitGC");
+            gcAndFinalize();
+            Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
+
+            Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
+
             // Disable tracing so that forked processes do not inherit stale tracing tags from
             // Zygote.
             Trace.setTracingEnabled(false);
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 54be410..d1acb59 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -57,6 +57,7 @@
     jfieldID secure;
     jfieldID appVsyncOffsetNanos;
     jfieldID presentationDeadlineNanos;
+    jfieldID colorTransform;
 } gPhysicalDisplayInfoClassInfo;
 
 static struct {
@@ -394,6 +395,8 @@
                 info.appVsyncOffset);
         env->SetLongField(infoObj, gPhysicalDisplayInfoClassInfo.presentationDeadlineNanos,
                 info.presentationDeadline);
+        env->SetIntField(infoObj, gPhysicalDisplayInfoClassInfo.colorTransform,
+                info.colorTransform);
         env->SetObjectArrayElement(configArray, static_cast<jsize>(c), infoObj);
         env->DeleteLocalRef(infoObj);
     }
@@ -656,6 +659,8 @@
             clazz, "appVsyncOffsetNanos", "J");
     gPhysicalDisplayInfoClassInfo.presentationDeadlineNanos = GetFieldIDOrDie(env,
             clazz, "presentationDeadlineNanos", "J");
+    gPhysicalDisplayInfoClassInfo.colorTransform = GetFieldIDOrDie(env, clazz,
+            "colorTransform", "I");
 
     jclass rectClazz = FindClassOrDie(env, "android/graphics/Rect");
     gRectClassInfo.bottom = GetFieldIDOrDie(env, rectClazz, "bottom", "I");
diff --git a/core/tests/coretests/src/android/animation/AutoCancelTest.java b/core/tests/coretests/src/android/animation/AutoCancelTest.java
index b1f88db..5810818 100644
--- a/core/tests/coretests/src/android/animation/AutoCancelTest.java
+++ b/core/tests/coretests/src/android/animation/AutoCancelTest.java
@@ -18,10 +18,12 @@
 import android.os.Handler;
 import android.test.ActivityInstrumentationTestCase2;
 import android.test.suitebuilder.annotation.SmallTest;
+import android.test.suitebuilder.annotation.Suppress;
 
 import java.util.HashMap;
 import java.util.concurrent.TimeUnit;
 
+@Suppress  // Failing
 public class AutoCancelTest extends ActivityInstrumentationTestCase2<BasicAnimatorActivity> {
 
     boolean mAnimX1Canceled = false;
diff --git a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
index 1857345..abb51db 100644
--- a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
@@ -217,7 +217,7 @@
     }
 
     @Override
-    protected boolean onLevelChange(int level) {
+    protected boolean onLevelChange(float level) {
         return mAnimatedVectorState.mVectorDrawable.setLevel(level);
     }
 
diff --git a/graphics/java/android/graphics/drawable/ClipDrawable.java b/graphics/java/android/graphics/drawable/ClipDrawable.java
index 31fccd0..3b92507 100644
--- a/graphics/java/android/graphics/drawable/ClipDrawable.java
+++ b/graphics/java/android/graphics/drawable/ClipDrawable.java
@@ -52,8 +52,6 @@
     public static final int HORIZONTAL = 1;
     public static final int VERTICAL = 2;
 
-    private static final int MAX_LEVEL = 10000;
-
     private final Rect mTmpRect = new Rect();
 
     private ClipState mState;
@@ -143,7 +141,7 @@
     }
 
     @Override
-    protected boolean onLevelChange(int level) {
+    protected boolean onLevelChange(float level) {
         super.onLevelChange(level);
         invalidateSelf();
         return true;
@@ -153,12 +151,12 @@
     public int getOpacity() {
         final Drawable dr = getDrawable();
         final int opacity = dr.getOpacity();
-        if (opacity == PixelFormat.TRANSPARENT || dr.getLevel() == 0) {
+        if (opacity == PixelFormat.TRANSPARENT || dr.getLevelFloat() == 0) {
             return PixelFormat.TRANSPARENT;
         }
 
-        final int level = getLevel();
-        if (level >= MAX_LEVEL) {
+        final float level = getLevelFloat();
+        if (level >= MAX_LEVEL_FLOAT) {
             return dr.getOpacity();
         }
 
@@ -169,24 +167,24 @@
     @Override
     public void draw(Canvas canvas) {
         final Drawable dr = getDrawable();
-        if (dr.getLevel() == 0) {
+        if (dr.getLevelFloat() == 0) {
             return;
         }
 
         final Rect r = mTmpRect;
         final Rect bounds = getBounds();
-        final int level = getLevel();
+        final float level = getLevelFloat();
 
         int w = bounds.width();
-        final int iw = 0; //mState.mDrawable.getIntrinsicWidth();
+        final int iw = 0;
         if ((mState.mOrientation & HORIZONTAL) != 0) {
-            w -= (w - iw) * (MAX_LEVEL - level) / MAX_LEVEL;
+            w -= Math.round((w - iw) * (MAX_LEVEL_FLOAT - level) / MAX_LEVEL_FLOAT);
         }
 
         int h = bounds.height();
-        final int ih = 0; //mState.mDrawable.getIntrinsicHeight();
+        final int ih = 0;
         if ((mState.mOrientation & VERTICAL) != 0) {
-            h -= (h - ih) * (MAX_LEVEL - level) / MAX_LEVEL;
+            h -= Math.round((h - ih) * (MAX_LEVEL_FLOAT - level) / MAX_LEVEL_FLOAT);
         }
 
         final int layoutDirection = getLayoutDirection();
diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java
index b95c183..fb77155 100644
--- a/graphics/java/android/graphics/drawable/Drawable.java
+++ b/graphics/java/android/graphics/drawable/Drawable.java
@@ -41,6 +41,7 @@
 import android.os.Trace;
 import android.util.AttributeSet;
 import android.util.DisplayMetrics;
+import android.util.FloatProperty;
 import android.util.StateSet;
 import android.util.TypedValue;
 import android.util.Xml;
@@ -126,12 +127,19 @@
  * document.</p></div>
  */
 public abstract class Drawable {
+
     private static final Rect ZERO_BOUNDS_RECT = new Rect();
 
     static final PorterDuff.Mode DEFAULT_TINT_MODE = PorterDuff.Mode.SRC_IN;
 
+    /** The standard maximum value for calls to {@link #setLevel(int)}. */
+    public static final int MAX_LEVEL = 10000;
+
+    /** The standard maximum value for calls to {@link #setLevel(float)}. */
+    public static final float MAX_LEVEL_FLOAT = 10000.0f;
+
     private int[] mStateSet = StateSet.WILD_CARD;
-    private int mLevel = 0;
+    private float mLevel = 0.0f;
     private int mChangingConfigurations = 0;
     private Rect mBounds = ZERO_BOUNDS_RECT;  // lazily becomes a new Rect()
     private WeakReference<Callback> mCallback = null;
@@ -711,22 +719,63 @@
     }
 
     /**
-     * Specify the level for the drawable.  This allows a drawable to vary its
-     * imagery based on a continuous controller, for example to show progress
-     * or volume level.
+     * Sets the level for the drawable as an integer value where typically the
+     * minimum level is 0 and the maximum is 10000 {@link #MAX_LEVEL}; however,
+     * the range may vary based on the Drawable implementation and is not
+     * clamped.
+     * <p>
+     * This allows a drawable to vary its imagery based on a continuous
+     * controller. For example, it may be used to show progress or volume
+     * level.
+     * <p>
+     * Use #setLevelFloat(float) to set the level as a high-precision
+     * floating-point value.
      *
-     * <p>If the new level you are supplying causes the appearance of the
-     * Drawable to change, then it is responsible for calling
-     * {@link #invalidateSelf} in order to have itself redrawn, <em>and</em>
-     * true will be returned from this function.
-     *
-     * @param level The new level, from 0 (minimum) to 10000 (maximum).
-     *
-     * @return Returns true if this change in level has caused the appearance
-     * of the Drawable to change (hence requiring an invalidate), otherwise
-     * returns false.
+     * @param level the new level, typically between 0 and 10000
+     * @return {@code true} if this change in level has caused the appearance
+     *         of the drawable to change and will require a subsequent call to
+     *         invalidate, {@code false} otherwise
+     * @see #getLevel()
+     * @see #setLevel(float)
+     * @see #onLevelChange(int)
      */
     public final boolean setLevel(int level) {
+        return setLevel((float) level);
+    }
+
+    /**
+     * Returns the current level as a rounded integer value.
+     * <p>
+     * Use #getLevelFloat() to return the level as a high-precision
+     * floating-point value.
+     *
+     * @return the current level, typically between 0 and 10000
+     * @see #setLevel(int)
+     * @see #getLevelFloat()
+     */
+    public final int getLevel() {
+        return Math.round(mLevel);
+    }
+
+    /**
+     * Sets the level for the drawable as a floating-point value where
+     * typically the minimum level is 0.0 and the maximum is 10000.0
+     * {@link #MAX_LEVEL_FLOAT}; however, the range may vary based on the
+     * Drawable implementation and is not clamped.
+     * <p>
+     * This allows a drawable to vary its imagery based on a continuous
+     * controller. For example, it may be used to show progress or volume
+     * level.
+     *
+     * @param level the new level, typically between 0.0 and 10000.0
+     *              ({@link #MAX_LEVEL_FLOAT})
+     * @return {@code true} if this change in level has caused the appearance
+     *         of the drawable to change and will require a subsequent call to
+     *         invalidate, {@code false} otherwise
+     * @see #getLevelFloat()
+     * @see #onLevelChange(float)
+     */
+    public final boolean setLevel(float level) {
         if (mLevel != level) {
             mLevel = level;
             return onLevelChange(level);
@@ -735,11 +784,13 @@
     }
 
     /**
-     * Retrieve the current level.
+     * Returns the current level as a floating-point value.
      *
-     * @return int Current level, from 0 (minimum) to 10000 (maximum).
+     * @return the current level, typically between 0.0 and 10000.0
+     *         ({@link #MAX_LEVEL_FLOAT})
+     * @see #setLevel(float)
      */
-    public final int getLevel() {
+    public final float getLevelFloat() {
         return mLevel;
     }
 
@@ -894,14 +945,47 @@
      * last state.
      */
     protected boolean onStateChange(int[] state) { return false; }
-    /** Override this in your subclass to change appearance if you vary based
-     *  on level.
-     * @return Returns true if the level change has caused the appearance of
-     * the Drawable to change (that is, it needs to be drawn), else false
-     * if it looks the same and there is no need to redraw it since its
-     * last level.
+
+    /**
+     * Called when the drawable level changes.
+     * <p>
+     * Override this in your subclass to change appearance if you vary based on
+     * level and do not need floating-point accuracy. To handle changes with
+     * higher accuracy, override {@link #onLevelChange(float)} instead.
+     * <p>
+     * <strong>Note:</strong> Do not override both this method and
+     * {@link #onLevelChange(float)}. Only override one method.
+     *
+     * @param level the level as an integer value, typically between 0
+     *              (minimum) and 10000 ({@link #MAX_LEVEL})
+     * @return {@code true} if the level change has caused the appearance of
+     *         the drawable to change such that it needs to be redrawn, or
+     *         {@code false} if there is no need to redraw
      */
     protected boolean onLevelChange(int level) { return false; }
+
+    /**
+     * Called when the drawable level changes.
+     * <p>
+     * Override this in your subclass to change appearance if you vary based on
+     * level and need floating-point accuracy.
+     * <p>
+     * <strong>Note:</strong> Do not override both this method and
+     * {@link #onLevelChange(int)}. Only override one method. If your app
+     * targets SDK <= 23 ({@link android.os.Build.VERSION_CODES#M M}), you
+     * will need to override {@link #onLevelChange(int)} to receive callbacks
+     * on devices running Android M and below.
+     *
+     * @param level the level as a floating-point value, typically between 0.0
+     *              and 10000.0 ({@link #MAX_LEVEL_FLOAT})
+     * @return {@code true} if the level change has caused the appearance of
+     *         the drawable to change such that it needs to be redrawn, or
+     *         {@code false} if there is no need to redraw
+     */
+    protected boolean onLevelChange(float level) {
+        return onLevelChange(Math.round(level));
+    }
+
     /**
      * Override this in your subclass to change appearance if you vary based on
      * the bounds.
@@ -1328,6 +1412,23 @@
     }
 
     /**
+     * Animatable property for Drawable level.
+     *
+     * @hide Until Drawable animations have been cleaned up.
+     */
+    public static final FloatProperty<Drawable> LEVEL = new FloatProperty<Drawable>("levelFloat") {
+        @Override
+        public Float get(Drawable object) {
+            return object.getLevelFloat();
+        }
+
+        @Override
+        public void setValue(Drawable object, float value) {
+            object.setLevel(value);
+        }
+    };
+
+    /**
      * Obtains styled attributes from the theme, if available, or unstyled
      * resources if the theme is null.
      */
diff --git a/graphics/java/android/graphics/drawable/DrawableContainer.java b/graphics/java/android/graphics/drawable/DrawableContainer.java
index 1915dd7..0210ddb 100644
--- a/graphics/java/android/graphics/drawable/DrawableContainer.java
+++ b/graphics/java/android/graphics/drawable/DrawableContainer.java
@@ -322,7 +322,7 @@
     }
 
     @Override
-    protected boolean onLevelChange(int level) {
+    protected boolean onLevelChange(float level) {
         if (mLastDrawable != null) {
             return mLastDrawable.setLevel(level);
         }
@@ -510,7 +510,7 @@
         d.setVisible(isVisible(), true);
         d.setDither(mDrawableContainerState.mDither);
         d.setState(getState());
-        d.setLevel(getLevel());
+        d.setLevel(getLevelFloat());
         d.setBounds(getBounds());
         d.setLayoutDirection(getLayoutDirection());
         d.setAutoMirrored(mDrawableContainerState.mAutoMirrored);
diff --git a/graphics/java/android/graphics/drawable/DrawableWrapper.java b/graphics/java/android/graphics/drawable/DrawableWrapper.java
index 9185e1a..57b4db2 100644
--- a/graphics/java/android/graphics/drawable/DrawableWrapper.java
+++ b/graphics/java/android/graphics/drawable/DrawableWrapper.java
@@ -92,7 +92,7 @@
             // Only call setters for data that's stored in the base Drawable.
             dr.setVisible(isVisible(), true);
             dr.setState(getState());
-            dr.setLevel(getLevel());
+            dr.setLevel(getLevelFloat());
             dr.setBounds(getBounds());
             dr.setLayoutDirection(getLayoutDirection());
 
@@ -286,7 +286,7 @@
     }
 
     @Override
-    protected boolean onLevelChange(int level) {
+    protected boolean onLevelChange(float level) {
         return mDrawable != null && mDrawable.setLevel(level);
     }
 
diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java
index d7fd8a5..15295a0 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -530,8 +530,8 @@
      *                 {@code false} otherwise
      *
      * @see #mutate()
-     * @see #setLevel(int)
-     * @see #getLevel()
+     * @see #setLevel(float)
+     * @see #getLevelFloat()
      * @see #isUseLevel()
      */
     public void setUseLevel(boolean useLevel) {
@@ -764,7 +764,7 @@
         if (mRingPath != null && (!st.mUseLevelForShape || !mPathIsDirty)) return mRingPath;
         mPathIsDirty = false;
 
-        float sweep = st.mUseLevelForShape ? (360.0f * getLevel() / 10000.0f) : 360f;
+        float sweep = st.mUseLevelForShape ? (360.0f * getLevelFloat() / MAX_LEVEL_FLOAT) : 360f;
 
         RectF bounds = new RectF(mRect);
 
@@ -990,7 +990,7 @@
     }
 
     @Override
-    protected boolean onLevelChange(int level) {
+    protected boolean onLevelChange(float level) {
         super.onLevelChange(level);
         mGradientIsDirty = true;
         mPathIsDirty = true;
@@ -1026,7 +1026,7 @@
                 final float x0, x1, y0, y1;
 
                 if (st.mGradient == LINEAR_GRADIENT) {
-                    final float level = st.mUseLevel ? getLevel() / 10000.0f : 1.0f;
+                    final float level = st.mUseLevel ? getLevelFloat() / MAX_LEVEL_FLOAT : 1.0f;
                     switch (st.mOrientation) {
                     case TOP_BOTTOM:
                         x0 = r.left;            y0 = r.top;
@@ -1080,7 +1080,7 @@
                     }
 
                     if (st.mUseLevel) {
-                        radius *= getLevel() / 10000.0f;
+                        radius *= getLevelFloat() / MAX_LEVEL_FLOAT;
                     }
 
                     mGradientRadius = radius;
@@ -1115,7 +1115,7 @@
                             tempPositions = st.mTempPositions = new float[length + 1];
                         }
 
-                        final float level = getLevel() / 10000.0f;
+                        final float level = getLevelFloat() / MAX_LEVEL_FLOAT;
                         for (int i = 0; i < length; i++) {
                             tempPositions[i] = i * fraction * level;
                         }
diff --git a/graphics/java/android/graphics/drawable/LayerDrawable.java b/graphics/java/android/graphics/drawable/LayerDrawable.java
index 1a0ba6f..c9e38b9 100644
--- a/graphics/java/android/graphics/drawable/LayerDrawable.java
+++ b/graphics/java/android/graphics/drawable/LayerDrawable.java
@@ -1400,7 +1400,7 @@
     }
 
     @Override
-    protected boolean onLevelChange(int level) {
+    protected boolean onLevelChange(float level) {
         boolean changed = false;
 
         final ChildDrawable[] array = mLayerState.mChildren;
@@ -1733,7 +1733,7 @@
                 clone.setCallback(owner);
                 clone.setLayoutDirection(dr.getLayoutDirection());
                 clone.setBounds(dr.getBounds());
-                clone.setLevel(dr.getLevel());
+                clone.setLevel(dr.getLevelFloat());
             } else {
                 clone = null;
             }
diff --git a/graphics/java/android/graphics/drawable/LevelListDrawable.java b/graphics/java/android/graphics/drawable/LevelListDrawable.java
index b01c643..09d8b6f 100644
--- a/graphics/java/android/graphics/drawable/LevelListDrawable.java
+++ b/graphics/java/android/graphics/drawable/LevelListDrawable.java
@@ -69,15 +69,16 @@
         if (drawable != null) {
             mLevelListState.addLevel(low, high, drawable);
             // in case the new state matches our current state...
-            onLevelChange(getLevel());
+            onLevelChange(getLevelFloat());
         }
     }
 
     // overrides from Drawable
 
     @Override
-    protected boolean onLevelChange(int level) {
-        int idx = mLevelListState.indexOfLevel(level);
+    protected boolean onLevelChange(float level) {
+        final int nearestLevel = Math.round(level);
+        final int idx = mLevelListState.indexOfLevel(nearestLevel);
         if (selectDrawable(idx)) {
             return true;
         }
@@ -141,7 +142,7 @@
             mLevelListState.addLevel(low, high, dr);
         }
 
-        onLevelChange(getLevel());
+        onLevelChange(getLevelFloat());
     }
 
     @Override
@@ -240,7 +241,7 @@
     private LevelListDrawable(LevelListState state, Resources res) {
         final LevelListState as = new LevelListState(state, this, res);
         setConstantState(as);
-        onLevelChange(getLevel());
+        onLevelChange(getLevelFloat());
     }
 }
 
diff --git a/graphics/java/android/graphics/drawable/RotateDrawable.java b/graphics/java/android/graphics/drawable/RotateDrawable.java
index 036a078..71c9977 100644
--- a/graphics/java/android/graphics/drawable/RotateDrawable.java
+++ b/graphics/java/android/graphics/drawable/RotateDrawable.java
@@ -303,10 +303,10 @@
     }
 
     @Override
-    protected boolean onLevelChange(int level) {
+    protected boolean onLevelChange(float level) {
         super.onLevelChange(level);
 
-        final float value = level / (float) MAX_LEVEL;
+        final float value = level / (float) MAX_LEVEL_FLOAT;
         final float degrees = MathUtils.lerp(mState.mFromDegrees, mState.mToDegrees, value);
         mState.mCurrentDegrees = degrees;
 
diff --git a/graphics/java/android/graphics/drawable/ScaleDrawable.java b/graphics/java/android/graphics/drawable/ScaleDrawable.java
index 0acbeda..38c6b80 100644
--- a/graphics/java/android/graphics/drawable/ScaleDrawable.java
+++ b/graphics/java/android/graphics/drawable/ScaleDrawable.java
@@ -50,8 +50,6 @@
  * @attr ref android.R.styleable#ScaleDrawable_drawable
  */
 public class ScaleDrawable extends DrawableWrapper {
-    private static final int MAX_LEVEL = 10000;
-
     private final Rect mTmpRect = new Rect();
 
     private ScaleState mState;
@@ -170,7 +168,7 @@
     @Override
     public void draw(Canvas canvas) {
         final Drawable d = getDrawable();
-        if (d != null && d.getLevel() != 0) {
+        if (d != null && d.getLevelFloat() != 0) {
             d.draw(canvas);
         }
     }
@@ -178,12 +176,12 @@
     @Override
     public int getOpacity() {
         final Drawable d = getDrawable();
-        if (d.getLevel() == 0) {
+        if (d.getLevelFloat() == 0) {
             return PixelFormat.TRANSPARENT;
         }
 
         final int opacity = d.getOpacity();
-        if (opacity == PixelFormat.OPAQUE && d.getLevel() < MAX_LEVEL) {
+        if (opacity == PixelFormat.OPAQUE && d.getLevelFloat() < MAX_LEVEL_FLOAT) {
             return PixelFormat.TRANSLUCENT;
         }
 
@@ -191,7 +189,7 @@
     }
 
     @Override
-    protected boolean onLevelChange(int level) {
+    protected boolean onLevelChange(float level) {
         super.onLevelChange(level);
         onBoundsChange(getBounds());
         invalidateSelf();
@@ -203,18 +201,20 @@
         final Drawable d = getDrawable();
         final Rect r = mTmpRect;
         final boolean min = mState.mUseIntrinsicSizeAsMin;
-        final int level = getLevel();
+        final float level = getLevelFloat();
 
         int w = bounds.width();
         if (mState.mScaleWidth > 0) {
             final int iw = min ? d.getIntrinsicWidth() : 0;
-            w -= (int) ((w - iw) * (MAX_LEVEL - level) * mState.mScaleWidth / MAX_LEVEL);
+            w -= (int) ((w - iw) * (MAX_LEVEL_FLOAT - level)
+                    * mState.mScaleWidth / MAX_LEVEL_FLOAT);
         }
 
         int h = bounds.height();
         if (mState.mScaleHeight > 0) {
             final int ih = min ? d.getIntrinsicHeight() : 0;
-            h -= (int) ((h - ih) * (MAX_LEVEL - level) * mState.mScaleHeight / MAX_LEVEL);
+            h -= (int) ((h - ih) * (MAX_LEVEL_FLOAT - level)
+                    * mState.mScaleHeight / MAX_LEVEL_FLOAT);
         }
 
         final int layoutDirection = getLayoutDirection();
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
index b0429ef..e4b1ed8 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
@@ -539,10 +539,10 @@
          * Otherwise, allow the connect on UUID change.
          */
         if (!mProfiles.isEmpty()
-                && ((mConnectAttempted + timeout) > SystemClock.elapsedRealtime()
-                || (mConnectAttempted == 0))) {
+                && ((mConnectAttempted + timeout) > SystemClock.elapsedRealtime())) {
             connectWithoutResettingTimer(false);
         }
+
         dispatchAttributesChanged();
     }
 
diff --git a/telephony/java/android/telephony/RadioAccessFamily.java b/telephony/java/android/telephony/RadioAccessFamily.java
index 0c5c557..2bfaf1b 100644
--- a/telephony/java/android/telephony/RadioAccessFamily.java
+++ b/telephony/java/android/telephony/RadioAccessFamily.java
@@ -185,6 +185,36 @@
             case RILConstants.NETWORK_MODE_GLOBAL:
                 raf = GSM | WCDMA | CDMA | EVDO;
                 break;
+            case RILConstants.NETWORK_MODE_TDSCDMA_ONLY:
+                raf = RAF_TD_SCDMA;
+                break;
+            case RILConstants.NETWORK_MODE_TDSCDMA_WCDMA:
+                raf = RAF_TD_SCDMA | WCDMA;
+                break;
+            case RILConstants.NETWORK_MODE_LTE_TDSCDMA:
+                raf = RAF_LTE | RAF_TD_SCDMA;
+                break;
+            case RILConstants.NETWORK_MODE_TDSCDMA_GSM:
+                raf = RAF_TD_SCDMA | GSM;
+                break;
+            case RILConstants.NETWORK_MODE_LTE_TDSCDMA_GSM:
+                raf = RAF_LTE | RAF_TD_SCDMA | GSM;
+                break;
+            case RILConstants.NETWORK_MODE_TDSCDMA_GSM_WCDMA:
+                raf = RAF_TD_SCDMA | GSM | WCDMA;
+                break;
+            case RILConstants.NETWORK_MODE_LTE_TDSCDMA_WCDMA:
+                raf = RAF_LTE | RAF_TD_SCDMA | WCDMA;
+                break;
+            case RILConstants.NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA:
+                raf = RAF_LTE | RAF_TD_SCDMA | GSM | WCDMA;
+                break;
+            case RILConstants.NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
+                raf = RAF_TD_SCDMA | CDMA | EVDO | GSM | WCDMA;
+                break;
+            case RILConstants.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
+                raf = RAF_LTE | RAF_TD_SCDMA | CDMA | EVDO | GSM | WCDMA;
+                break;
             default:
                 raf = RAF_UNKNOWN;
                 break;
@@ -248,6 +278,36 @@
             case (GSM | WCDMA | CDMA | EVDO):
                 type = RILConstants.NETWORK_MODE_GLOBAL;
                 break;
+            case RAF_TD_SCDMA:
+                type = RILConstants.NETWORK_MODE_TDSCDMA_ONLY;
+                break;
+            case (RAF_TD_SCDMA | WCDMA):
+                type = RILConstants.NETWORK_MODE_TDSCDMA_WCDMA;
+                break;
+            case (RAF_LTE | RAF_TD_SCDMA):
+                type = RILConstants.NETWORK_MODE_LTE_TDSCDMA;
+                break;
+            case (RAF_TD_SCDMA | GSM):
+                type = RILConstants.NETWORK_MODE_TDSCDMA_GSM;
+                break;
+            case (RAF_LTE | RAF_TD_SCDMA | GSM):
+                type = RILConstants.NETWORK_MODE_LTE_TDSCDMA_GSM;
+                break;
+            case (RAF_TD_SCDMA | GSM | WCDMA):
+                type = RILConstants.NETWORK_MODE_TDSCDMA_GSM_WCDMA;
+                break;
+            case (RAF_LTE | RAF_TD_SCDMA | WCDMA):
+                type = RILConstants.NETWORK_MODE_LTE_TDSCDMA_WCDMA;
+                break;
+            case (RAF_LTE | RAF_TD_SCDMA | GSM | WCDMA):
+                type = RILConstants.NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA;
+                break;
+            case (RAF_TD_SCDMA | CDMA | EVDO | GSM | WCDMA):
+                type = RILConstants.NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA;
+                break;
+            case (RAF_LTE | RAF_TD_SCDMA | RAF_LTE | CDMA | EVDO | GSM | WCDMA):
+                type = RILConstants.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA;
+                break;
             default:
                 type = RILConstants.PREFERRED_NETWORK_MODE ;
                 break;
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index 80515cf..1337487 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -731,6 +731,9 @@
             case RIL_RADIO_TECHNOLOGY_IWLAN:
                 rtString = "IWLAN";
                 break;
+            case RIL_RADIO_TECHNOLOGY_TD_SCDMA:
+                rtString = "TD-SCDMA";
+                break;
             default:
                 rtString = "Unexpected";
                 Rlog.w(LOG_TAG, "Unexpected radioTechnology=" + rt);
@@ -1068,6 +1071,8 @@
             return TelephonyManager.NETWORK_TYPE_HSPAP;
         case ServiceState.RIL_RADIO_TECHNOLOGY_GSM:
             return TelephonyManager.NETWORK_TYPE_GSM;
+        case ServiceState.RIL_RADIO_TECHNOLOGY_TD_SCDMA:
+            return TelephonyManager.NETWORK_TYPE_TD_SCDMA;
         case ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN:
             return TelephonyManager.NETWORK_TYPE_IWLAN;
         default:
diff --git a/telephony/java/android/telephony/SignalStrength.java b/telephony/java/android/telephony/SignalStrength.java
index f02d109..f535e5d 100644
--- a/telephony/java/android/telephony/SignalStrength.java
+++ b/telephony/java/android/telephony/SignalStrength.java
@@ -68,6 +68,7 @@
     private int mLteRsrq;
     private int mLteRssnr;
     private int mLteCqi;
+    private int mTdScdmaRscp;
 
     private boolean isGsm; // This value is set by the ServiceStateTracker onSignalStrengthResult
 
@@ -107,6 +108,7 @@
         mLteRsrq = INVALID;
         mLteRssnr = INVALID;
         mLteCqi = INVALID;
+        mTdScdmaRscp = INVALID;
         isGsm = true;
     }
 
@@ -131,6 +133,7 @@
         mLteRsrq = INVALID;
         mLteRssnr = INVALID;
         mLteCqi = INVALID;
+        mTdScdmaRscp = INVALID;
         isGsm = gsmFlag;
     }
 
@@ -143,6 +146,22 @@
             int cdmaDbm, int cdmaEcio,
             int evdoDbm, int evdoEcio, int evdoSnr,
             int lteSignalStrength, int lteRsrp, int lteRsrq, int lteRssnr, int lteCqi,
+            int tdScdmaRscp, boolean gsmFlag) {
+        initialize(gsmSignalStrength, gsmBitErrorRate, cdmaDbm, cdmaEcio,
+                evdoDbm, evdoEcio, evdoSnr, lteSignalStrength, lteRsrp,
+                lteRsrq, lteRssnr, lteCqi, gsmFlag);
+        mTdScdmaRscp = tdScdmaRscp;
+    }
+
+    /**
+     * Constructor
+     *
+     * @hide
+     */
+    public SignalStrength(int gsmSignalStrength, int gsmBitErrorRate,
+            int cdmaDbm, int cdmaEcio,
+            int evdoDbm, int evdoEcio, int evdoSnr,
+            int lteSignalStrength, int lteRsrp, int lteRsrq, int lteRssnr, int lteCqi,
             boolean gsmFlag) {
         initialize(gsmSignalStrength, gsmBitErrorRate, cdmaDbm, cdmaEcio,
                 evdoDbm, evdoEcio, evdoSnr, lteSignalStrength, lteRsrp,
@@ -233,6 +252,7 @@
         mLteRsrq = lteRsrq;
         mLteRssnr = lteRssnr;
         mLteCqi = lteCqi;
+        mTdScdmaRscp = INVALID;
         isGsm = gsm;
         if (DBG) log("initialize: " + toString());
     }
@@ -253,6 +273,7 @@
         mLteRsrq = s.mLteRsrq;
         mLteRssnr = s.mLteRssnr;
         mLteCqi = s.mLteCqi;
+        mTdScdmaRscp = s.mTdScdmaRscp;
         isGsm = s.isGsm;
     }
 
@@ -276,6 +297,7 @@
         mLteRsrq = in.readInt();
         mLteRssnr = in.readInt();
         mLteCqi = in.readInt();
+        mTdScdmaRscp = in.readInt();
         isGsm = (in.readInt() != 0);
     }
 
@@ -302,7 +324,7 @@
         ss.mLteRsrq = in.readInt();
         ss.mLteRssnr = in.readInt();
         ss.mLteCqi = in.readInt();
-
+        ss.mTdScdmaRscp = in.readInt();
         return ss;
     }
 
@@ -322,6 +344,7 @@
         out.writeInt(mLteRsrq);
         out.writeInt(mLteRssnr);
         out.writeInt(mLteCqi);
+        out.writeInt(mTdScdmaRscp);
         out.writeInt(isGsm ? 1 : 0);
     }
 
@@ -377,6 +400,9 @@
         mLteRsrq = ((mLteRsrq >= 3) && (mLteRsrq <= 20)) ? -mLteRsrq : SignalStrength.INVALID;
         mLteRssnr = ((mLteRssnr >= -200) && (mLteRssnr <= 300)) ? mLteRssnr
                 : SignalStrength.INVALID;
+
+        mTdScdmaRscp = ((mTdScdmaRscp >= 25) && (mTdScdmaRscp <= 120))
+                ? -mTdScdmaRscp : SignalStrength.INVALID;
         // Cqi no change
         if (DBG) log("Signal after validate=" + this);
     }
@@ -477,12 +503,15 @@
      *     while 4 represents a very strong signal strength.
      */
     public int getLevel() {
-        int level;
+        int level = 0;
 
         if (isGsm) {
             level = getLteLevel();
             if (level == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
-                level = getGsmLevel();
+                level = getTdScdmaLevel();
+                if (level == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
+                    level = getGsmLevel();
+                }
             }
         } else {
             int cdmaLevel = getCdmaLevel();
@@ -508,10 +537,14 @@
      * @hide
      */
     public int getAsuLevel() {
-        int asuLevel;
+        int asuLevel = 0;
         if (isGsm) {
             if (getLteLevel() == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
-                asuLevel = getGsmAsuLevel();
+                if (getTdScdmaLevel() == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
+                    asuLevel = getGsmAsuLevel();
+                } else {
+                    asuLevel = getTdScdmaAsuLevel();
+                }
             } else {
                 asuLevel = getLteAsuLevel();
             }
@@ -539,12 +572,16 @@
      * @hide
      */
     public int getDbm() {
-        int dBm;
+        int dBm = INVALID;
 
         if(isGsm()) {
             dBm = getLteDbm();
             if (dBm == INVALID) {
-                dBm = getGsmDbm();
+                if (getTdScdmaLevel() == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
+                    dBm = getGsmDbm();
+                } else {
+                    dBm = getTdScdmaDbm();
+                }
             }
         } else {
             int cdmaDbm = getCdmaDbm();
@@ -849,6 +886,54 @@
     }
 
     /**
+     * @return get TD_SCDMA dbm
+     *
+     * @hide
+     */
+    public int getTdScdmaDbm() {
+        return this.mTdScdmaRscp;
+    }
+
+    /**
+     * Get TD-SCDMA as level 0..4
+     * Range : 25 to 120
+     * INT_MAX: 0x7FFFFFFF denotes invalid value
+     * Reference: 3GPP TS 25.123, section 9.1.1.1
+     *
+     * @hide
+     */
+    public int getTdScdmaLevel() {
+        final int tdScdmaDbm = getTdScdmaDbm();
+        int level;
+
+        if ((tdScdmaDbm > -25) || (tdScdmaDbm == SignalStrength.INVALID))
+                level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+        else if (tdScdmaDbm >= -49) level = SIGNAL_STRENGTH_GREAT;
+        else if (tdScdmaDbm >= -73) level = SIGNAL_STRENGTH_GOOD;
+        else if (tdScdmaDbm >= -97) level = SIGNAL_STRENGTH_MODERATE;
+        else if (tdScdmaDbm >= -120) level = SIGNAL_STRENGTH_POOR;
+        else level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+
+        if (DBG) log("getTdScdmaLevel = " + level);
+        return level;
+     }
+
+    /**
+     * Get the TD-SCDMA signal level as an asu value.
+     *
+     * @hide
+     */
+    public int getTdScdmaAsuLevel() {
+        final int tdScdmaDbm = getTdScdmaDbm();
+        int tdScdmaAsuLevel;
+
+        if (tdScdmaDbm == INVALID) tdScdmaAsuLevel = 255;
+        else tdScdmaAsuLevel = tdScdmaDbm + 120;
+        if (DBG) log("TD-SCDMA Asu level: " + tdScdmaAsuLevel);
+        return tdScdmaAsuLevel;
+    }
+
+   /**
      * @return hash code
      */
     @Override
@@ -860,7 +945,7 @@
                 + (mEvdoDbm * primeNum) + (mEvdoEcio * primeNum) + (mEvdoSnr * primeNum)
                 + (mLteSignalStrength * primeNum) + (mLteRsrp * primeNum)
                 + (mLteRsrq * primeNum) + (mLteRssnr * primeNum) + (mLteCqi * primeNum)
-                + (isGsm ? 1 : 0));
+                + (mTdScdmaRscp * primeNum) + (isGsm ? 1 : 0));
     }
 
     /**
@@ -892,6 +977,7 @@
                 && mLteRsrq == s.mLteRsrq
                 && mLteRssnr == s.mLteRssnr
                 && mLteCqi == s.mLteCqi
+                && mTdScdmaRscp == s.mTdScdmaRscp
                 && isGsm == s.isGsm);
     }
 
@@ -913,6 +999,7 @@
                 + " " + mLteRsrq
                 + " " + mLteRssnr
                 + " " + mLteCqi
+                + " " + mTdScdmaRscp
                 + " " + (isGsm ? "gsm|lte" : "cdma"));
     }
 
@@ -935,6 +1022,7 @@
         mLteRsrq = m.getInt("LteRsrq");
         mLteRssnr = m.getInt("LteRssnr");
         mLteCqi = m.getInt("LteCqi");
+        mTdScdmaRscp = m.getInt("TdScdma");
         isGsm = m.getBoolean("isGsm");
     }
 
@@ -957,6 +1045,7 @@
         m.putInt("LteRsrq", mLteRsrq);
         m.putInt("LteRssnr", mLteRssnr);
         m.putInt("LteCqi", mLteCqi);
+        m.putInt("TdScdma", mTdScdmaRscp);
         m.putBoolean("isGsm", Boolean.valueOf(isGsm));
     }
 
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index e104b38..f6e4bed 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -1099,11 +1099,21 @@
         case RILConstants.NETWORK_MODE_LTE_GSM_WCDMA:
         case RILConstants.NETWORK_MODE_LTE_WCDMA:
         case RILConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA:
+        case RILConstants.NETWORK_MODE_TDSCDMA_ONLY:
+        case RILConstants.NETWORK_MODE_TDSCDMA_WCDMA:
+        case RILConstants.NETWORK_MODE_LTE_TDSCDMA:
+        case RILConstants.NETWORK_MODE_TDSCDMA_GSM:
+        case RILConstants.NETWORK_MODE_LTE_TDSCDMA_GSM:
+        case RILConstants.NETWORK_MODE_TDSCDMA_GSM_WCDMA:
+        case RILConstants.NETWORK_MODE_LTE_TDSCDMA_WCDMA:
+        case RILConstants.NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA:
+        case RILConstants.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
             return PhoneConstants.PHONE_TYPE_GSM;
 
         // Use CDMA Phone for the global mode including CDMA
         case RILConstants.NETWORK_MODE_GLOBAL:
         case RILConstants.NETWORK_MODE_LTE_CDMA_EVDO:
+        case RILConstants.NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
             return PhoneConstants.PHONE_TYPE_CDMA;
 
         case RILConstants.NETWORK_MODE_LTE_ONLY:
diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java
index 8d48c86..7088be8 100644
--- a/telephony/java/com/android/internal/telephony/RILConstants.java
+++ b/telephony/java/com/android/internal/telephony/RILConstants.java
@@ -96,6 +96,16 @@
     int NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA = 10; /* LTE, CDMA, EvDo, GSM/WCDMA */
     int NETWORK_MODE_LTE_ONLY       = 11; /* LTE Only mode. */
     int NETWORK_MODE_LTE_WCDMA      = 12; /* LTE/WCDMA */
+    int NETWORK_MODE_TDSCDMA_ONLY            = 13; /* TD-SCDMA only */
+    int NETWORK_MODE_TDSCDMA_WCDMA           = 14; /* TD-SCDMA and WCDMA */
+    int NETWORK_MODE_LTE_TDSCDMA             = 15; /* TD-SCDMA and LTE */
+    int NETWORK_MODE_TDSCDMA_GSM             = 16; /* TD-SCDMA and GSM */
+    int NETWORK_MODE_LTE_TDSCDMA_GSM         = 17; /* TD-SCDMA,GSM and LTE */
+    int NETWORK_MODE_TDSCDMA_GSM_WCDMA       = 18; /* TD-SCDMA, GSM/WCDMA */
+    int NETWORK_MODE_LTE_TDSCDMA_WCDMA       = 19; /* TD-SCDMA, WCDMA and LTE */
+    int NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA   = 20; /* TD-SCDMA, GSM/WCDMA and LTE */
+    int NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA  = 21; /*TD-SCDMA,EvDo,CDMA,GSM/WCDMA*/
+    int NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA = 22; /* TD-SCDMA/LTE/GSM/WCDMA, CDMA, and EvDo */
     int PREFERRED_NETWORK_MODE      = SystemProperties.getInt("ro.telephony.default_network",
             NETWORK_MODE_WCDMA_PREF);