Merge "Fix a bug where the fast scroll track would be positioned incorrectly."
diff --git a/core/java/android/preference/PreferenceActivity.java b/core/java/android/preference/PreferenceActivity.java
index 6172ce9..d9039ab 100644
--- a/core/java/android/preference/PreferenceActivity.java
+++ b/core/java/android/preference/PreferenceActivity.java
@@ -990,6 +990,9 @@
      */
     public void showBreadCrumbs(CharSequence title, CharSequence shortTitle) {
         if (mFragmentBreadCrumbs == null) {
+            View crumbs = findViewById(android.R.id.title);
+            // For screens with a different kind of title, don't create breadcrumbs.
+            if (!(crumbs instanceof FragmentBreadCrumbs)) return;
             mFragmentBreadCrumbs = (FragmentBreadCrumbs) findViewById(android.R.id.title);
             if (mFragmentBreadCrumbs == null) {
                 mFragmentBreadCrumbs = new FragmentBreadCrumbs(this);
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index b6dd59d..d6e5974 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -319,6 +319,8 @@
     private int mLastDownPositionX, mLastDownPositionY;
     private Callback mCustomSelectionActionModeCallback;
 
+    private final int mSquaredTouchSlopDistance;
+
     /*
      * Kick-start the font cache for the zygote process (to pay the cost of
      * initializing freetype for our default font only once).
@@ -1009,6 +1011,10 @@
         setLongClickable(longClickable);
 
         prepareCursorControllers();
+
+        final ViewConfiguration viewConfiguration = ViewConfiguration.get(context);
+        final int touchSlop = viewConfiguration.getScaledTouchSlop();
+        mSquaredTouchSlopDistance = touchSlop * touchSlop;
     }
 
     private void setTypefaceByIndex(int typefaceIndex, int styleIndex) {
@@ -8402,15 +8408,24 @@
         private float mTouchOffsetY;
         private int mLastParentX;
         private int mLastParentY;
+        private float mDownPositionX, mDownPositionY;
         private int mContainerPositionX, mContainerPositionY;
         private long mTouchTimer;
-        private boolean mHasPastePopupWindow = false;
+        private boolean mIsInsertionHandle = false;
         private PastePopupMenu mPastePopupWindow;
+        private LongPressCallback mLongPressCallback;
 
         public static final int LEFT = 0;
         public static final int CENTER = 1;
         public static final int RIGHT = 2;
 
+        class LongPressCallback implements Runnable {
+            public void run() {
+                mController.hide();
+                startSelectionActionMode();
+            }
+        }
+
         public HandleView(CursorController controller, int pos) {
             super(TextView.this.mContext);
             mController = controller;
@@ -8457,7 +8472,7 @@
                 mDrawable = mSelectHandleCenter;
                 handleWidth = mDrawable.getIntrinsicWidth();
                 mHotspotX = handleWidth / 2;
-                mHasPastePopupWindow = true;
+                mIsInsertionHandle = true;
                 break;
             }
             }
@@ -8616,20 +8631,25 @@
         public boolean onTouchEvent(MotionEvent ev) {
             switch (ev.getActionMasked()) {
             case MotionEvent.ACTION_DOWN: {
-                final float rawX = ev.getRawX();
-                final float rawY = ev.getRawY();
-                mTouchToWindowOffsetX = rawX - mPositionX;
-                mTouchToWindowOffsetY = rawY - mPositionY;
+                mDownPositionX = ev.getRawX();
+                mDownPositionY = ev.getRawY();
+                mTouchToWindowOffsetX = mDownPositionX - mPositionX;
+                mTouchToWindowOffsetY = mDownPositionY - mPositionY;
                 final int[] coords = mTempCoords;
                 TextView.this.getLocationInWindow(coords);
                 mLastParentX = coords[0];
                 mLastParentY = coords[1];
                 mIsDragging = true;
-                if (mHasPastePopupWindow) {
+                if (mIsInsertionHandle) {
                     mTouchTimer = SystemClock.uptimeMillis();
+                    if (mLongPressCallback == null) {
+                        mLongPressCallback = new LongPressCallback();
+                    }
+                    postDelayed(mLongPressCallback, ViewConfiguration.getLongPressTimeout());
                 }
                 break;
             }
+
             case MotionEvent.ACTION_MOVE: {
                 final float rawX = ev.getRawX();
                 final float rawY = ev.getRawY();
@@ -8638,35 +8658,37 @@
 
                 mController.updatePosition(this, Math.round(newPosX), Math.round(newPosY));
 
+                if (mIsInsertionHandle) {
+                    final float dx = rawX - mDownPositionX;
+                    final float dy = rawY - mDownPositionY;
+                    final float distanceSquared = dx * dx + dy * dy;
+                    if (distanceSquared >= mSquaredTouchSlopDistance) {
+                        removeCallbacks(mLongPressCallback);
+                    }
+                }
                 break;
             }
+
             case MotionEvent.ACTION_UP:
-                if (mHasPastePopupWindow) {
+                if (mIsInsertionHandle) {
+                    removeCallbacks(mLongPressCallback);
                     long delay = SystemClock.uptimeMillis() - mTouchTimer;
                     if (delay < ViewConfiguration.getTapTimeout()) {
-                        final float touchOffsetX = ev.getRawX() - mPositionX;
-                        final float touchOffsetY = ev.getRawY() - mPositionY;
-                        final float dx = touchOffsetX - mTouchToWindowOffsetX;
-                        final float dy = touchOffsetY - mTouchToWindowOffsetY;
-                        final float distanceSquared = dx * dx + dy * dy;
-                        final ViewConfiguration viewConfiguration = ViewConfiguration.get(getContext());
-                        final int doubleTapSlop = viewConfiguration.getScaledDoubleTapSlop();
-                        final int slopSquared = doubleTapSlop * doubleTapSlop;
-                        if (distanceSquared < slopSquared) {
-                            if (mPastePopupWindow != null && mPastePopupWindow.isShowing()) {
-                                // Tapping on the handle dismisses the displayed paste view,
-                                mPastePopupWindow.hide();
-                            } else {
-                                ((InsertionPointCursorController) mController).show(0);
-                            }
+                        if (mPastePopupWindow != null && mPastePopupWindow.isShowing()) {
+                            // Tapping on the handle dismisses the displayed paste view,
+                            mPastePopupWindow.hide();
+                        } else {
+                            ((InsertionPointCursorController) mController).show(0);
                         }
-                    } else {
-                        mController.show();
                     }
                 }
                 mIsDragging = false;
                 break;
+
             case MotionEvent.ACTION_CANCEL:
+                if (mIsInsertionHandle) {
+                    removeCallbacks(mLongPressCallback);
+                }
                 mIsDragging = false;
             }
             return true;
@@ -8696,7 +8718,7 @@
         }
 
         void showPastePopupWindow() {
-            if (mHasPastePopupWindow) {
+            if (mIsInsertionHandle) {
                 if (mPastePopupWindow == null) {
                     // Lazy initialisation: create when actually shown only.
                     mPastePopupWindow = new PastePopupMenu();
@@ -8924,10 +8946,7 @@
                             final int deltaX = x - mPreviousTapPositionX;
                             final int deltaY = y - mPreviousTapPositionY;
                             final int distanceSquared = deltaX * deltaX + deltaY * deltaY;
-                            final int doubleTapSlop =
-                                ViewConfiguration.get(getContext()).getScaledDoubleTapSlop();
-                            final int slopSquared = doubleTapSlop * doubleTapSlop;
-                            if (distanceSquared < slopSquared) {
+                            if (distanceSquared < mSquaredTouchSlopDistance) {
                                 startSelectionActionMode();
                                 mDiscardNextActionUp = true;
                             }
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiApStress.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiApStress.java
index 21ab0e6..2ac7265 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiApStress.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiApStress.java
@@ -43,7 +43,7 @@
     private final static String TAG = "WifiApStress";
     private static String NETWORK_ID = "AndroidAPTest";
     private static String PASSWD = "androidwifi";
-    private final static String OUTPUT_FILE = "WifiApStressOutput.txt";
+    private final static String OUTPUT_FILE = "WifiStressTestOutput.txt";
     private ConnectivityManagerTestActivity mAct;
     private int iterations;
     private PowerManager.WakeLock mWakelock = null;
@@ -75,8 +75,7 @@
         // write the total number of iterations into output file
         mOutputWriter = new BufferedWriter(new FileWriter(new File(
                 Environment.getExternalStorageDirectory(), OUTPUT_FILE)));
-        mOutputWriter.write(String.format("iteration %d out of %d"
-                + "\n", mLastIteration, iterations));
+        mOutputWriter.write(String.format("iteration %d out of %d\n", mLastIteration, iterations));
         mOutputWriter.flush();
         mOutputWriter.close();
         super.tearDown();
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
index 0756a72..7914417 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
@@ -169,15 +169,18 @@
     public void testWifiScanning() {
         int scanTimeSum = 0;
         int i;
-        int averageScanTime = 0;
         int ssidAppearInScanResultsCount = 0; // count times of given ssid appear in scan results.
         for (i = 0; i < mScanIterations; i++) {
             log("testWifiScanning: iteration: " + i);
-            writeOutput(String.format("scan iteration %d out of %d",
+            int averageScanTime = 0;
+            if (i > 0) {
+                averageScanTime = scanTimeSum/i;
+            }
+            writeOutput(String.format("iteration %d out of %d",
                     i, mScanIterations));
             writeOutput(String.format("average scanning time is %d", averageScanTime));
             writeOutput(String.format("ssid appear %d out of %d scan iterations",
-                    ssidAppearInScanResultsCount, mScanIterations));
+                    ssidAppearInScanResultsCount, i));
             long startTime = System.currentTimeMillis();
             mAct.scanResultAvailable = false;
             assertTrue("start scan failed", mAct.mWifiManager.startScanActive());
@@ -196,8 +199,6 @@
                     if (mAct.scanResultAvailable) {
                         long scanTime = (System.currentTimeMillis() - startTime);
                         scanTimeSum += scanTime;
-                        averageScanTime = scanTimeSum/mScanIterations;
-                        log("average scanning time: " + averageScanTime);
                         break;
                     }
                 }
@@ -224,9 +225,9 @@
             }
         }
         if (i == mScanIterations) {
-            writeOutput(String.format("scan iteration %d out of %d",
+            writeOutput(String.format("iteration %d out of %d",
                     i, mScanIterations));
-            writeOutput(String.format("average scanning time is %d", averageScanTime));
+            writeOutput(String.format("average scanning time is %d", scanTimeSum/mScanIterations));
             writeOutput(String.format("ssid appear %d out of %d scan iterations",
                     ssidAppearInScanResultsCount, mScanIterations));
         }
@@ -269,7 +270,7 @@
             // 1. Put device into sleep
             // 2. Wait for the device to sleep for sometime, very 3G is connected
             // 3. Wake up the device
-            writeOutput(String.format("reconnection after sleep iteration %d out of %d",
+            writeOutput(String.format("iteration %d out of %d",
                     i, mReconnectIterations));
             log("iteration: " + i);
             turnScreenOff();
@@ -294,7 +295,7 @@
                     ConnectivityManagerTestActivity.LONG_TIMEOUT));
         }
         if (i == mReconnectIterations) {
-            writeOutput(String.format("reconnection after sleep iteration %d out of %d",
+            writeOutput(String.format("iteration %d out of %d",
                     i, mReconnectIterations));
         }
     }
diff --git a/graphics/java/android/renderscript/Allocation.java b/graphics/java/android/renderscript/Allocation.java
index 97d513a..b937721 100644
--- a/graphics/java/android/renderscript/Allocation.java
+++ b/graphics/java/android/renderscript/Allocation.java
@@ -55,13 +55,13 @@
         }
     }
 
-    public enum MipmapGenerationControl {
+    public enum MipmapControl {
         MIPMAP_NONE(0),
         MIPMAP_FULL(1),
         MIPMAP_ON_SYNC_TO_TEXTURE(2);
 
         int mID;
-        MipmapGenerationControl(int id) {
+        MipmapControl(int id) {
             mID = id;
         }
     }
@@ -131,6 +131,14 @@
         subData1D(0, mType.getCount(), i);
     }
 
+    private void validateBitmap(Bitmap b) {
+        mRS.validate();
+        if(mType.getX() != b.getWidth() ||
+           mType.getY() != b.getHeight()) {
+            throw new RSIllegalArgumentException("Cannot update allocation from bitmap, sizes mismatch");
+        }
+    }
+
     public void copyFrom(int[] d) {
         mRS.validate();
         subData1D(0, mType.getCount(), d);
@@ -147,18 +155,17 @@
         mRS.validate();
         subData1D(0, mType.getCount(), d);
     }
-
     public void copyFrom(Bitmap b) {
-
-        mRS.validate();
-        if(mType.getX() != b.getWidth() ||
-           mType.getY() != b.getHeight()) {
-            throw new RSIllegalArgumentException("Cannot update allocation from bitmap, sizes mismatch");
-        }
-
-        mRS.nAllocationUpdateFromBitmap(getID(), b);
+        validateBitmap(b);
+        mRS.nAllocationCopyFromBitmap(getID(), b);
     }
 
+    public void copyTo(Bitmap b) {
+        validateBitmap(b);
+        mRS.nAllocationCopyToBitmap(getID(), b);
+    }
+
+
     public void subData(int xoff, FieldPacker fp) {
         int eSize = mType.mElement.getSizeBytes();
         final byte[] data = fp.getData();
@@ -423,17 +430,17 @@
     }
 
     static private Type typeFromBitmap(RenderScript rs, Bitmap b,
-                                       MipmapGenerationControl mip) {
+                                       MipmapControl mip) {
         Element e = elementFromBitmap(rs, b);
         Type.Builder tb = new Type.Builder(rs, e);
         tb.setX(b.getWidth());
         tb.setY(b.getHeight());
-        tb.setMipmaps(mip == MipmapGenerationControl.MIPMAP_FULL);
+        tb.setMipmaps(mip == MipmapControl.MIPMAP_FULL);
         return tb.create();
     }
 
     static public Allocation createFromBitmap(RenderScript rs, Bitmap b,
-                                              MipmapGenerationControl mips,
+                                              MipmapControl mips,
                                               int usage) {
         rs.validate();
         Type t = typeFromBitmap(rs, b, mips);
@@ -447,15 +454,15 @@
 
     static public Allocation createFromBitmap(RenderScript rs, Bitmap b,
                                               Element dstFmt, boolean genMips) {
-        MipmapGenerationControl mc = MipmapGenerationControl.MIPMAP_NONE;
+        MipmapControl mc = MipmapControl.MIPMAP_NONE;
         if (genMips) {
-            mc = MipmapGenerationControl.MIPMAP_ON_SYNC_TO_TEXTURE;
+            mc = MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE;
         }
         return createFromBitmap(rs, b, mc, USAGE_ALL);
     }
 
     static public Allocation createCubemapFromBitmap(RenderScript rs, Bitmap b,
-                                                     MipmapGenerationControl mips,
+                                                     MipmapControl mips,
                                                      CubemapLayout layout,
                                                      int usage) {
         rs.validate();
@@ -482,7 +489,7 @@
         tb.setX(width);
         tb.setY(width);
         tb.setFaces(true);
-        tb.setMipmaps(mips == MipmapGenerationControl.MIPMAP_FULL);
+        tb.setMipmaps(mips == MipmapControl.MIPMAP_FULL);
         Type t = tb.create();
 
         int id = rs.nAllocationCubeCreateFromBitmap(t.getID(), mips.mID, b, usage);
@@ -496,33 +503,17 @@
                                                      Element dstFmt,
                                                      boolean genMips,
                                                      CubemapLayout layout) {
-        MipmapGenerationControl mc = MipmapGenerationControl.MIPMAP_NONE;
+        MipmapControl mc = MipmapControl.MIPMAP_NONE;
         if (genMips) {
-            mc = MipmapGenerationControl.MIPMAP_ON_SYNC_TO_TEXTURE;
+            mc = MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE;
         }
         return createCubemapFromBitmap(rs, b, mc, layout, USAGE_ALL);
     }
 
-
-    static public Allocation createBitmapRef(RenderScript rs, Bitmap b) {
-
-        rs.validate();
-        Type t = typeFromBitmap(rs, b, MipmapGenerationControl.MIPMAP_NONE);
-
-        int id = rs.nAllocationCreateBitmapRef(t.getID(), b);
-        if(id == 0) {
-            throw new RSRuntimeException("Load failed.");
-        }
-
-        Allocation a = new Allocation(id, rs, t, USAGE_SCRIPT);
-        a.mBitmap = b;
-        return a;
-    }
-
     static public Allocation createFromBitmapResource(RenderScript rs,
                                                       Resources res,
                                                       int id,
-                                                      MipmapGenerationControl mips,
+                                                      MipmapControl mips,
                                                       int usage) {
 
         rs.validate();
@@ -537,9 +528,9 @@
                                                       int id,
                                                       Element dstFmt,
                                                       boolean genMips) {
-        MipmapGenerationControl mc = MipmapGenerationControl.MIPMAP_NONE;
+        MipmapControl mc = MipmapControl.MIPMAP_NONE;
         if (genMips) {
-            mc = MipmapGenerationControl.MIPMAP_ON_SYNC_TO_TEXTURE;
+            mc = MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE;
         }
         return createFromBitmapResource(rs, res, id, mc, USAGE_ALL);
     }
diff --git a/graphics/java/android/renderscript/Element.java b/graphics/java/android/renderscript/Element.java
index 7e89a56..7616316 100644
--- a/graphics/java/android/renderscript/Element.java
+++ b/graphics/java/android/renderscript/Element.java
@@ -654,17 +654,5 @@
             return new Element(id, mRS, ein, sin, asin);
         }
     }
-
-    static void initPredefined(RenderScript rs) {
-        int a8 = rs.nElementCreate(DataType.UNSIGNED_8.mID,
-                                   DataKind.PIXEL_A.mID, true, 1);
-        int rgba4444 = rs.nElementCreate(DataType.UNSIGNED_4_4_4_4.mID,
-                                         DataKind.PIXEL_RGBA.mID, true, 4);
-        int rgba8888 = rs.nElementCreate(DataType.UNSIGNED_8.mID,
-                                         DataKind.PIXEL_RGBA.mID, true, 4);
-        int rgb565 = rs.nElementCreate(DataType.UNSIGNED_5_6_5.mID,
-                                       DataKind.PIXEL_RGB.mID, true, 3);
-        rs.nInitElements(a8, rgba4444, rgba8888, rgb565);
-    }
 }
 
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index e3a9a67..3fa9965 100644
--- a/graphics/java/android/renderscript/RenderScript.java
+++ b/graphics/java/android/renderscript/RenderScript.java
@@ -65,7 +65,6 @@
     }
 
     // Non-threadsafe functions.
-    native void nInitElements(int a8, int rgba4444, int rgba8888, int rgb565);
     native int  nDeviceCreate();
     native void nDeviceDestroy(int dev);
     native void nDeviceSetConfig(int dev, int param, int value);
@@ -213,13 +212,19 @@
         return rsnAllocationCreateFromAssetStream(mContext, mips, assetStream, usage);
     }
 
+    native void  rsnAllocationCopyToBitmap(int con, int alloc, Bitmap bmp);
+    synchronized void nAllocationCopyToBitmap(int alloc, Bitmap bmp) {
+        rsnAllocationCopyToBitmap(mContext, alloc, bmp);
+    }
+
+
     native void rsnAllocationSyncAll(int con, int alloc, int src);
     synchronized void nAllocationSyncAll(int alloc, int src) {
         rsnAllocationSyncAll(mContext, alloc, src);
     }
-    native void  rsnAllocationUpdateFromBitmap(int con, int alloc, Bitmap bmp);
-    synchronized void nAllocationUpdateFromBitmap(int alloc, Bitmap bmp) {
-        rsnAllocationUpdateFromBitmap(mContext, alloc, bmp);
+    native void  rsnAllocationCopyFromBitmap(int con, int alloc, Bitmap bmp);
+    synchronized void nAllocationCopyFromBitmap(int alloc, Bitmap bmp) {
+        rsnAllocationCopyFromBitmap(mContext, alloc, bmp);
     }
 
     native void rsnAllocationUploadToTexture(int con, int alloc, boolean genMips, int baseMioLevel);
@@ -787,7 +792,6 @@
         rs.mContext = rs.nContextCreate(rs.mDev, 0);
         rs.mMessageThread = new MessageThread(rs);
         rs.mMessageThread.start();
-        Element.initPredefined(rs);
         return rs;
     }
 
diff --git a/graphics/java/android/renderscript/RenderScriptGL.java b/graphics/java/android/renderscript/RenderScriptGL.java
index 4a1c40a..0886db4 100644
--- a/graphics/java/android/renderscript/RenderScriptGL.java
+++ b/graphics/java/android/renderscript/RenderScriptGL.java
@@ -190,7 +190,6 @@
         }
         mMessageThread = new MessageThread(this);
         mMessageThread.start();
-        Element.initPredefined(this);
     }
 
     /**
diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp
index 65acf93..8344842 100644
--- a/graphics/jni/android_renderscript_RenderScript.cpp
+++ b/graphics/jni/android_renderscript_RenderScript.cpp
@@ -59,11 +59,6 @@
 static jfieldID gNativeBitmapID = 0;
 static jfieldID gTypeNativeCache = 0;
 
-static RsElement g_A_8 = NULL;
-static RsElement g_RGBA_4444 = NULL;
-static RsElement g_RGBA_8888 = NULL;
-static RsElement g_RGB_565 = NULL;
-
 static void _nInit(JNIEnv *_env, jclass _this)
 {
     gContextId             = _env->GetFieldID(_this, "mContext", "I");
@@ -72,14 +67,6 @@
     gNativeBitmapID = _env->GetFieldID(bitmapClass, "mNativeBitmap", "I");
 }
 
-static void nInitElements(JNIEnv *_env, jobject _this, jint a8, jint rgba4444, jint rgba8888, jint rgb565)
-{
-    g_A_8 = reinterpret_cast<RsElement>(a8);
-    g_RGBA_4444 = reinterpret_cast<RsElement>(rgba4444);
-    g_RGBA_8888 = reinterpret_cast<RsElement>(rgba8888);
-    g_RGB_565 = reinterpret_cast<RsElement>(rgb565);
-}
-
 // ---------------------------------------------------------------------------
 
 static void
@@ -415,26 +402,6 @@
     rsAllocationSyncAll(con, (RsAllocation)a, (RsAllocationUsageType)bits);
 }
 
-static RsElement SkBitmapToPredefined(SkBitmap::Config cfg)
-{
-    switch (cfg) {
-    case SkBitmap::kA8_Config:
-        return g_A_8;
-    case SkBitmap::kARGB_4444_Config:
-        return g_RGBA_4444;
-    case SkBitmap::kARGB_8888_Config:
-        return g_RGBA_8888;
-    case SkBitmap::kRGB_565_Config:
-        return g_RGB_565;
-
-    default:
-        break;
-    }
-    // If we don't have a conversion mark it as a user type.
-    LOGE("Unsupported bitmap type");
-    return NULL;
-}
-
 static int
 nAllocationCreateFromBitmap(JNIEnv *_env, jobject _this, RsContext con, jint type, jint mip, jobject jbitmap, jint usage)
 {
@@ -464,20 +431,29 @@
 }
 
 static void
-nAllocationUpdateFromBitmap(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jobject jbitmap)
+nAllocationCopyFromBitmap(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jobject jbitmap)
 {
     SkBitmap const * nativeBitmap =
             (SkBitmap const *)_env->GetIntField(jbitmap, gNativeBitmapID);
     const SkBitmap& bitmap(*nativeBitmap);
-    SkBitmap::Config config = bitmap.getConfig();
 
-    RsElement e = SkBitmapToPredefined(config);
-    if (e) {
-        bitmap.lockPixels();
-        const void* ptr = bitmap.getPixels();
-        rsAllocationUpdateFromBitmap(con, (RsAllocation)alloc, e, ptr);
-        bitmap.unlockPixels();
-    }
+    bitmap.lockPixels();
+    const void* ptr = bitmap.getPixels();
+    rsAllocationCopyFromBitmap(con, (RsAllocation)alloc, ptr, bitmap.getSize());
+    bitmap.unlockPixels();
+}
+
+static void
+nAllocationCopyToBitmap(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jobject jbitmap)
+{
+    SkBitmap const * nativeBitmap =
+            (SkBitmap const *)_env->GetIntField(jbitmap, gNativeBitmapID);
+    const SkBitmap& bitmap(*nativeBitmap);
+
+    bitmap.lockPixels();
+    void* ptr = bitmap.getPixels();
+    rsAllocationCopyToBitmap(con, (RsAllocation)alloc, ptr, bitmap.getSize());
+    bitmap.unlockPixels();
 }
 
 static void ReleaseBitmapCallback(void *bmp)
@@ -486,44 +462,6 @@
     nativeBitmap->unlockPixels();
 }
 
-static int
-nAllocationCreateBitmapRef(JNIEnv *_env, jobject _this, RsContext con, jint type, jobject jbitmap)
-{
-    SkBitmap * nativeBitmap =
-            (SkBitmap *)_env->GetIntField(jbitmap, gNativeBitmapID);
-
-
-    nativeBitmap->lockPixels();
-    void* ptr = nativeBitmap->getPixels();
-    jint id = (jint)rsAllocationCreateBitmapRef(con, (RsType)type, ptr, nativeBitmap, ReleaseBitmapCallback);
-    return id;
-}
-
-static int
-nAllocationCreateFromAssetStream(JNIEnv *_env, jobject _this, RsContext con, jint dstFmt, jboolean genMips, jint native_asset, jint usage)
-{
-    /*
-    Asset* asset = reinterpret_cast<Asset*>(native_asset);
-    SkBitmap bitmap;
-    SkImageDecoder::DecodeMemory(asset->getBuffer(false), asset->getLength(),
-            &bitmap, SkBitmap::kNo_Config, SkImageDecoder::kDecodePixels_Mode);
-
-    SkBitmap::Config config = bitmap.getConfig();
-
-    RsElement e = SkBitmapToPredefined(config);
-
-    if (e) {
-        bitmap.lockPixels();
-        const int w = bitmap.width();
-        const int h = bitmap.height();
-        const void* ptr = bitmap.getPixels();
-        jint id = (jint)rsaAllocationCreateFromBitmap(con, w, h, (RsElement)dstFmt, e, genMips, ptr, usage);
-        bitmap.unlockPixels();
-        return id;
-    }
-    */
-    return 0;
-}
 
 static void
 nAllocationSubData1D_i(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint offset, jint count, jintArray data, int sizeBytes)
@@ -1266,7 +1204,6 @@
 
 static JNINativeMethod methods[] = {
 {"_nInit",                         "()V",                                     (void*)_nInit },
-{"nInitElements",                  "(IIII)V",                                 (void*)nInitElements },
 
 {"nDeviceCreate",                  "()I",                                     (void*)nDeviceCreate },
 {"nDeviceDestroy",                 "(I)V",                                    (void*)nDeviceDestroy },
@@ -1311,10 +1248,10 @@
 {"rsnAllocationCreateTyped",         "(III)I",                                (void*)nAllocationCreateTyped },
 {"rsnAllocationCreateFromBitmap",    "(IIILandroid/graphics/Bitmap;I)I",      (void*)nAllocationCreateFromBitmap },
 {"rsnAllocationCubeCreateFromBitmap","(IIILandroid/graphics/Bitmap;I)I",      (void*)nAllocationCubeCreateFromBitmap },
-{"rsnAllocationCreateBitmapRef",     "(IILandroid/graphics/Bitmap;)I",        (void*)nAllocationCreateBitmapRef },
-{"rsnAllocationCreateFromAssetStream","(IIII)I",                              (void*)nAllocationCreateFromAssetStream },
 
-{"rsnAllocationUpdateFromBitmap",    "(IILandroid/graphics/Bitmap;)V",        (void*)nAllocationUpdateFromBitmap },
+{"rsnAllocationCopyFromBitmap",      "(IILandroid/graphics/Bitmap;)V",        (void*)nAllocationCopyFromBitmap },
+{"rsnAllocationCopyToBitmap",        "(IILandroid/graphics/Bitmap;)V",        (void*)nAllocationCopyToBitmap },
+
 {"rsnAllocationUploadToTexture",     "(IIZI)V",                               (void*)nAllocationUploadToTexture },
 {"rsnAllocationUploadToBufferObject","(II)V",                                 (void*)nAllocationUploadToBufferObject },
 {"rsnAllocationSyncAll",             "(III)V",                                (void*)nAllocationSyncAll },
diff --git a/include/surfaceflinger/ISurfaceComposer.h b/include/surfaceflinger/ISurfaceComposer.h
index 382cbda..693fbfb 100644
--- a/include/surfaceflinger/ISurfaceComposer.h
+++ b/include/surfaceflinger/ISurfaceComposer.h
@@ -121,7 +121,8 @@
     virtual status_t captureScreen(DisplayID dpy,
             sp<IMemoryHeap>* heap,
             uint32_t* width, uint32_t* height, PixelFormat* format,
-            uint32_t reqWidth, uint32_t reqHeight) = 0;
+            uint32_t reqWidth, uint32_t reqHeight,
+            uint32_t minLayerZ, uint32_t maxLayerZ) = 0;
 
     virtual status_t turnElectronBeamOff(int32_t mode) = 0;
     virtual status_t turnElectronBeamOn(int32_t mode) = 0;
diff --git a/include/surfaceflinger/SurfaceComposerClient.h b/include/surfaceflinger/SurfaceComposerClient.h
index a80832d..25b2ebf 100644
--- a/include/surfaceflinger/SurfaceComposerClient.h
+++ b/include/surfaceflinger/SurfaceComposerClient.h
@@ -183,6 +183,8 @@
     // frees the previous screenshot and capture a new one
     status_t update();
     status_t update(uint32_t reqWidth, uint32_t reqHeight);
+    status_t update(uint32_t reqWidth, uint32_t reqHeight,
+            uint32_t minLayerZ, uint32_t maxLayerZ);
 
     // release memory occupied by the screenshot
     void release();
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 8bfc8d4..17b9e83 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -385,11 +385,7 @@
 
     if (bounds.isEmpty() || bounds.getWidth() > mCaches.maxTextureSize ||
             bounds.getHeight() > mCaches.maxTextureSize) {
-        if (fboLayer) {
-            snapshot->invisible = true;
-        } else {
-            snapshot->empty = true;
-        }
+        snapshot->empty = fboLayer;
     } else {
         snapshot->invisible = snapshot->invisible || (alpha <= ALPHA_THRESHOLD && fboLayer);
     }
diff --git a/libs/rs/java/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java b/libs/rs/java/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java
index e935fa9..09654ab 100644
--- a/libs/rs/java/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java
+++ b/libs/rs/java/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java
@@ -283,7 +283,7 @@
             long t = java.lang.System.currentTimeMillis();
             if (true) {
                 mScript.invoke_filter();
-                mRS.finish();
+                mOutPixelsAllocation.copyTo(mBitmapOut);
             } else {
                 javaFilter();
                 mDisplayView.invalidate();
@@ -352,7 +352,7 @@
     public void surfaceCreated(SurfaceHolder holder) {
         createScript();
         mScript.invoke_filter();
-        mRS.finish();
+        mOutPixelsAllocation.copyTo(mBitmapOut);
     }
 
     public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
@@ -365,8 +365,12 @@
         mRS = RenderScript.create();
         mRS.setMessageHandler(new FilterCallback());
 
-        mInPixelsAllocation = Allocation.createBitmapRef(mRS, mBitmapIn);
-        mOutPixelsAllocation = Allocation.createBitmapRef(mRS, mBitmapOut);
+        mInPixelsAllocation = Allocation.createFromBitmap(mRS, mBitmapIn,
+                                                          Allocation.MipmapControl.MIPMAP_NONE,
+                                                          Allocation.USAGE_SCRIPT);
+        mOutPixelsAllocation = Allocation.createFromBitmap(mRS, mBitmapOut,
+                                                           Allocation.MipmapControl.MIPMAP_NONE,
+                                                           Allocation.USAGE_SCRIPT);
 
         Type.Builder tb = new Type.Builder(mRS, Element.F32_4(mRS));
         tb.setX(mBitmapIn.getWidth());
@@ -419,7 +423,7 @@
         long t = java.lang.System.currentTimeMillis();
 
         mScript.invoke_filter();
-        mRS.finish();
+        mOutPixelsAllocation.copyTo(mBitmapOut);
 
         t = java.lang.System.currentTimeMillis() - t;
         android.util.Log.v("Img", "Renderscript frame time core ms " + t);
@@ -432,6 +436,6 @@
         mScript.set_radius(mRadius);
 
         mScript.invoke_filter();
-        mRS.finish();
+        mOutPixelsAllocation.copyTo(mBitmapOut);
     }
 }
diff --git a/libs/rs/java/tests/src/com/android/rs/test/RSTestCore.java b/libs/rs/java/tests/src/com/android/rs/test/RSTestCore.java
index 11b0fcd..c1f652f 100644
--- a/libs/rs/java/tests/src/com/android/rs/test/RSTestCore.java
+++ b/libs/rs/java/tests/src/com/android/rs/test/RSTestCore.java
@@ -64,7 +64,6 @@
         unitTests.add(new UT_primitives(this, mRes));
         unitTests.add(new UT_rsdebug(this, mRes));
         unitTests.add(new UT_rstypes(this, mRes));
-        unitTests.add(new UT_vector_array(this, mRes));
         unitTests.add(new UT_fp_mad(this, mRes));
         /*
         unitTests.add(new UnitTest(null, "<Pass>", 1));
diff --git a/libs/rs/java/tests/src/com/android/rs/test/UT_vector_array.java b/libs/rs/java/tests/src/com/android/rs/test/UT_vector_array.java
deleted file mode 100644
index 6798781..0000000
--- a/libs/rs/java/tests/src/com/android/rs/test/UT_vector_array.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.rs.test;
-
-import android.content.res.Resources;
-import android.renderscript.*;
-
-public class UT_vector_array extends UnitTest {
-    private Resources mRes;
-
-    protected UT_vector_array(RSTestCore rstc, Resources res) {
-        super(rstc, "Vector Array");
-        mRes = res;
-    }
-
-    public void run() {
-        RenderScript pRS = RenderScript.create();
-        ScriptC_vector_array s = new ScriptC_vector_array(pRS, mRes, R.raw.vector_array);
-        pRS.setMessageHandler(mRsMessage);
-        s.invoke_vector_array_test();
-        pRS.finish();
-        waitForMessage();
-        pRS.destroy();
-    }
-}
-
diff --git a/libs/rs/java/tests/src/com/android/rs/test/vector_array.rs b/libs/rs/java/tests/src/com/android/rs/test/vector_array.rs
deleted file mode 100644
index 49e38c1..0000000
--- a/libs/rs/java/tests/src/com/android/rs/test/vector_array.rs
+++ /dev/null
@@ -1,49 +0,0 @@
-// 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.
-
-#include "shared.rsh"
-
-typedef struct float3Struct{
-    float3 arr[2];
-} float3Struct;
-
-float3Struct f;
-
-bool size_test() {
-    bool failed = false;
-    int expectedSize = 2 * 3 * (int) sizeof(float);
-    int actualSize = (int) sizeof(f);
-
-    rsDebug("Size of struct { float3 arr[2]; } (expected):", expectedSize);
-    rsDebug("Size of struct { float3 arr[2]; } (actual)  :", actualSize);
-
-    if (expectedSize != actualSize) {
-        failed = true;
-    }
-
-    return failed;
-}
-
-void vector_array_test() {
-    bool failed = false;
-    failed |= size_test();
-
-    if (failed) {
-        rsSendToClientBlocking(RS_MSG_TEST_FAILED);
-    }
-    else {
-        rsSendToClientBlocking(RS_MSG_TEST_PASSED);
-    }
-}
-
diff --git a/libs/rs/rs.spec b/libs/rs/rs.spec
index 97ecca0..14094c4 100644
--- a/libs/rs/rs.spec
+++ b/libs/rs/rs.spec
@@ -77,10 +77,16 @@
 	ret RsElement
 	}
 
-AllocationUpdateFromBitmap {
+AllocationCopyFromBitmap {
 	param RsAllocation alloc
-	param RsElement srcFmt
 	param const void * data
+	param size_t dataLen
+	}
+
+AllocationCopyToBitmap {
+	param RsAllocation alloc
+	param void * data
+	param size_t dataLen
 	}
 
 AllocationCreateBitmapRef {
diff --git a/libs/rs/rsAllocation.cpp b/libs/rs/rsAllocation.cpp
index f42be0e..10a5caf 100644
--- a/libs/rs/rsAllocation.cpp
+++ b/libs/rs/rsAllocation.cpp
@@ -763,30 +763,42 @@
     return alloc;
 }
 
-void rsi_AllocationUpdateFromBitmap(Context *rsc, RsAllocation va,
-                                    RsElement _src, const void *data) {
+void rsi_AllocationCopyFromBitmap(Context *rsc, RsAllocation va, const void *data, size_t dataLen) {
     Allocation *texAlloc = static_cast<Allocation *>(va);
-    const Element *src = static_cast<const Element *>(_src);
-    const Element *dst = texAlloc->getType()->getElement();
-    uint32_t w = texAlloc->getType()->getDimX();
-    uint32_t h = texAlloc->getType()->getDimY();
-    bool genMips = texAlloc->getType()->getDimLOD();
+    const Type * t = texAlloc->getType();
 
-    ElementConverter_t cvt = pickConverter(dst, src);
-    if (cvt) {
-        cvt(texAlloc->getPtr(), data, w * h);
-        if (genMips) {
-            Adapter2D adapt(rsc, texAlloc);
-            Adapter2D adapt2(rsc, texAlloc);
-            for (uint32_t lod=0; lod < (texAlloc->getType()->getLODCount() -1); lod++) {
-                adapt.setLOD(lod);
-                adapt2.setLOD(lod + 1);
-                mip(adapt2, adapt);
-            }
-        }
-    } else {
-        rsc->setError(RS_ERROR_BAD_VALUE, "Unsupported bitmap format");
+    uint32_t w = t->getDimX();
+    uint32_t h = t->getDimY();
+    bool genMips = t->getDimLOD();
+    size_t s = w * h * t->getElementSizeBytes();
+    if (s != dataLen) {
+        rsc->setError(RS_ERROR_BAD_VALUE, "Bitmap size didn't match allocation size");
+        return;
     }
+
+    memcpy(texAlloc->getPtr(), data, s);
+    if (genMips) {
+        Adapter2D adapt(rsc, texAlloc);
+        Adapter2D adapt2(rsc, texAlloc);
+        for (uint32_t lod=0; lod < (texAlloc->getType()->getLODCount() -1); lod++) {
+            adapt.setLOD(lod);
+            adapt2.setLOD(lod + 1);
+            mip(adapt2, adapt);
+        }
+    }
+}
+
+void rsi_AllocationCopyToBitmap(Context *rsc, RsAllocation va, void *data, size_t dataLen) {
+    Allocation *texAlloc = static_cast<Allocation *>(va);
+    const Type * t = texAlloc->getType();
+
+    size_t s = t->getDimX() * t->getDimY() * t->getElementSizeBytes();
+    if (s != dataLen) {
+        rsc->setError(RS_ERROR_BAD_VALUE, "Bitmap size didn't match allocation size");
+        return;
+    }
+
+    memcpy(data, texAlloc->getPtr(), s);
 }
 
 void rsi_AllocationData(Context *rsc, RsAllocation va, const void *data, uint32_t sizeBytes) {
diff --git a/libs/surfaceflinger_client/ISurfaceComposer.cpp b/libs/surfaceflinger_client/ISurfaceComposer.cpp
index 969ee79..b8a7a79 100644
--- a/libs/surfaceflinger_client/ISurfaceComposer.cpp
+++ b/libs/surfaceflinger_client/ISurfaceComposer.cpp
@@ -127,13 +127,16 @@
     virtual status_t captureScreen(DisplayID dpy,
             sp<IMemoryHeap>* heap,
             uint32_t* width, uint32_t* height, PixelFormat* format,
-            uint32_t reqWidth, uint32_t reqHeight)
+            uint32_t reqWidth, uint32_t reqHeight,
+            uint32_t minLayerZ, uint32_t maxLayerZ)
     {
         Parcel data, reply;
         data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         data.writeInt32(dpy);
         data.writeInt32(reqWidth);
         data.writeInt32(reqHeight);
+        data.writeInt32(minLayerZ);
+        data.writeInt32(maxLayerZ);
         remote()->transact(BnSurfaceComposer::CAPTURE_SCREEN, data, &reply);
         *heap = interface_cast<IMemoryHeap>(reply.readStrongBinder());
         *width = reply.readInt32();
@@ -231,11 +234,13 @@
             DisplayID dpy = data.readInt32();
             uint32_t reqWidth = data.readInt32();
             uint32_t reqHeight = data.readInt32();
+            uint32_t minLayerZ = data.readInt32();
+            uint32_t maxLayerZ = data.readInt32();
             sp<IMemoryHeap> heap;
             uint32_t w, h;
             PixelFormat f;
             status_t res = captureScreen(dpy, &heap, &w, &h, &f,
-                    reqWidth, reqHeight);
+                    reqWidth, reqHeight, minLayerZ, maxLayerZ);
             reply->writeStrongBinder(heap->asBinder());
             reply->writeInt32(w);
             reply->writeInt32(h);
diff --git a/libs/surfaceflinger_client/SurfaceComposerClient.cpp b/libs/surfaceflinger_client/SurfaceComposerClient.cpp
index f270461..d336724 100644
--- a/libs/surfaceflinger_client/SurfaceComposerClient.cpp
+++ b/libs/surfaceflinger_client/SurfaceComposerClient.cpp
@@ -555,7 +555,8 @@
     if (s == NULL) return NO_INIT;
     mHeap = 0;
     return s->captureScreen(0, &mHeap,
-            &mWidth, &mHeight, &mFormat, 0, 0);
+            &mWidth, &mHeight, &mFormat, 0, 0,
+            0, -1UL);
 }
 
 status_t ScreenshotClient::update(uint32_t reqWidth, uint32_t reqHeight) {
@@ -563,7 +564,18 @@
     if (s == NULL) return NO_INIT;
     mHeap = 0;
     return s->captureScreen(0, &mHeap,
-            &mWidth, &mHeight, &mFormat, reqWidth, reqHeight);
+            &mWidth, &mHeight, &mFormat, reqWidth, reqHeight,
+            0, -1UL);
+}
+
+status_t ScreenshotClient::update(uint32_t reqWidth, uint32_t reqHeight,
+        uint32_t minLayerZ, uint32_t maxLayerZ) {
+    sp<ISurfaceComposer> s(ComposerService::getComposerService());
+    if (s == NULL) return NO_INIT;
+    mHeap = 0;
+    return s->captureScreen(0, &mHeap,
+            &mWidth, &mHeight, &mFormat, reqWidth, reqHeight,
+            minLayerZ, maxLayerZ);
 }
 
 void ScreenshotClient::release() {
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 7980dfa..61d08aa 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2078,7 +2078,8 @@
 status_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy,
         sp<IMemoryHeap>* heap,
         uint32_t* w, uint32_t* h, PixelFormat* f,
-        uint32_t sw, uint32_t sh)
+        uint32_t sw, uint32_t sh,
+        uint32_t minLayerZ, uint32_t maxLayerZ)
 {
     status_t result = PERMISSION_DENIED;
 
@@ -2132,7 +2133,10 @@
         const size_t count = layers.size();
         for (size_t i=0 ; i<count ; ++i) {
             const sp<LayerBase>& layer(layers[i]);
-            layer->drawForSreenShot();
+            const uint32_t z = layer->drawingState().z;
+            if (z >= minLayerZ && z <= maxLayerZ) {
+                layer->drawForSreenShot();
+            }
         }
 
         // XXX: this is needed on tegra
@@ -2185,7 +2189,8 @@
 status_t SurfaceFlinger::captureScreen(DisplayID dpy,
         sp<IMemoryHeap>* heap,
         uint32_t* width, uint32_t* height, PixelFormat* format,
-        uint32_t sw, uint32_t sh)
+        uint32_t sw, uint32_t sh,
+        uint32_t minLayerZ, uint32_t maxLayerZ)
 {
     // only one display supported for now
     if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
@@ -2203,13 +2208,18 @@
         PixelFormat* f;
         uint32_t sw;
         uint32_t sh;
+        uint32_t minLayerZ;
+        uint32_t maxLayerZ;
         status_t result;
     public:
         MessageCaptureScreen(SurfaceFlinger* flinger, DisplayID dpy,
                 sp<IMemoryHeap>* heap, uint32_t* w, uint32_t* h, PixelFormat* f,
-                uint32_t sw, uint32_t sh)
+                uint32_t sw, uint32_t sh,
+                uint32_t minLayerZ, uint32_t maxLayerZ)
             : flinger(flinger), dpy(dpy),
-              heap(heap), w(w), h(h), f(f), sw(sw), sh(sh), result(PERMISSION_DENIED)
+              heap(heap), w(w), h(h), f(f), sw(sw), sh(sh),
+              minLayerZ(minLayerZ), maxLayerZ(maxLayerZ),
+              result(PERMISSION_DENIED)
         {
         }
         status_t getResult() const {
@@ -2223,14 +2233,14 @@
                 return true;
 
             result = flinger->captureScreenImplLocked(dpy,
-                    heap, w, h, f, sw, sh);
+                    heap, w, h, f, sw, sh, minLayerZ, maxLayerZ);
 
             return true;
         }
     };
 
     sp<MessageBase> msg = new MessageCaptureScreen(this,
-            dpy, heap, width, height, format, sw, sh);
+            dpy, heap, width, height, format, sw, sh, minLayerZ, maxLayerZ);
     status_t res = postMessageSync(msg);
     if (res == NO_ERROR) {
         res = static_cast<MessageCaptureScreen*>( msg.get() )->getResult();
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index c0e5acd..ca7d27d 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -192,13 +192,13 @@
     virtual status_t                    unfreezeDisplay(DisplayID dpy, uint32_t flags);
     virtual int                         setOrientation(DisplayID dpy, int orientation, uint32_t flags);
     virtual void                        signal() const;
-    virtual status_t                    captureScreen(DisplayID dpy,
-                                                      sp<IMemoryHeap>* heap,
-                                                      uint32_t* width,
-                                                      uint32_t* height,
-                                                      PixelFormat* format,
-                                                      uint32_t reqWidth,
-                                                      uint32_t reqHeight);
+
+    virtual status_t captureScreen(DisplayID dpy,
+            sp<IMemoryHeap>* heap,
+            uint32_t* width, uint32_t* height,
+            PixelFormat* format, uint32_t reqWidth, uint32_t reqHeight,
+            uint32_t minLayerZ, uint32_t maxLayerZ);
+
     virtual status_t                    turnElectronBeamOff(int32_t mode);
     virtual status_t                    turnElectronBeamOn(int32_t mode);
 
@@ -313,7 +313,8 @@
             status_t captureScreenImplLocked(DisplayID dpy,
                     sp<IMemoryHeap>* heap,
                     uint32_t* width, uint32_t* height, PixelFormat* format,
-                    uint32_t reqWidth = 0, uint32_t reqHeight = 0);
+                    uint32_t reqWidth, uint32_t reqHeight,
+                    uint32_t minLayerZ, uint32_t maxLayerZ);
 
             status_t turnElectronBeamOffImplLocked(int32_t mode);
             status_t turnElectronBeamOnImplLocked(int32_t mode);
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 38f57c9..4424e5b 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -954,4 +954,20 @@
         return mContext.getResources().getBoolean(
                 com.android.internal.R.bool.config_voice_capable);
     }
+
+    /**
+     * @return true if the current device supports sms service.
+     * <p>
+     * If true, this means that the device supports both sending and
+     * receiving sms via the telephony network.
+     * <p>
+     * Note: Voicemail waiting sms, cell broadcasting sms, and MMS are
+     *       disabled when device doesn't support sms.
+     *
+     * @hide pending API review
+     */
+    public boolean isSmsCapable() {
+        return mContext.getResources().getBoolean(
+                com.android.internal.R.bool.config_sms_capable);
+    }
 }
diff --git a/telephony/java/com/android/internal/telephony/SMSDispatcher.java b/telephony/java/com/android/internal/telephony/SMSDispatcher.java
index ec49a19..e7cfe75 100644
--- a/telephony/java/com/android/internal/telephony/SMSDispatcher.java
+++ b/telephony/java/com/android/internal/telephony/SMSDispatcher.java
@@ -156,6 +156,9 @@
     protected boolean mStorageAvailable = true;
     protected boolean mReportMemoryStatusPending = false;
 
+    /* Flag indicating whether the current device allows sms service */
+    protected boolean mSmsCapable = true;
+
     protected static int getNextConcatenatedRef() {
         sConcatenatedRef += 1;
         return sConcatenatedRef;
@@ -249,6 +252,9 @@
         filter.addAction(Intent.ACTION_DEVICE_STORAGE_FULL);
         filter.addAction(Intent.ACTION_DEVICE_STORAGE_NOT_FULL);
         mContext.registerReceiver(mResultReceiver, filter);
+
+        mSmsCapable = mContext.getResources().getBoolean(
+                com.android.internal.R.bool.config_sms_capable);
     }
 
     public void dispose() {
@@ -682,6 +688,7 @@
      *  <code>RESULT_ERROR_GENERIC_FAILURE</code><br>
      *  <code>RESULT_ERROR_RADIO_OFF</code><br>
      *  <code>RESULT_ERROR_NULL_PDU</code><br>
+     *  <code>RESULT_ERROR_NO_SERVICE</code><br>.
      *  For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include
      *  the extra "errorCode" containing a radio technology specific value,
      *  generally only useful for troubleshooting.<br>
@@ -709,6 +716,7 @@
      *  <code>RESULT_ERROR_GENERIC_FAILURE</code><br>
      *  <code>RESULT_ERROR_RADIO_OFF</code><br>
      *  <code>RESULT_ERROR_NULL_PDU</code><br>
+     *  <code>RESULT_ERROR_NO_SERVICE</code><br>.
      *  For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include
      *  the extra "errorCode" containing a radio technology specific value,
      *  generally only useful for troubleshooting.<br>
@@ -737,7 +745,8 @@
      *   or one of these errors:
      *   <code>RESULT_ERROR_GENERIC_FAILURE</code>
      *   <code>RESULT_ERROR_RADIO_OFF</code>
-     *   <code>RESULT_ERROR_NULL_PDU</code>.
+     *   <code>RESULT_ERROR_NULL_PDU</code>
+     *   <code>RESULT_ERROR_NO_SERVICE</code>.
      *  The per-application based SMS control checks sentIntent. If sentIntent
      *  is NULL the caller will be checked against all unknown applications,
      *  which cause smaller number of SMS to be sent in checking period.
@@ -763,7 +772,8 @@
      *  or one of these errors:
      *  <code>RESULT_ERROR_GENERIC_FAILURE</code>
      *  <code>RESULT_ERROR_RADIO_OFF</code>
-     *  <code>RESULT_ERROR_NULL_PDU</code>.
+     *  <code>RESULT_ERROR_NULL_PDU</code>
+     *  <code>RESULT_ERROR_NO_SERVICE</code>.
      *  The per-application based SMS control checks sentIntent. If sentIntent
      *  is NULL the caller will be checked against all unknown applications,
      *  which cause smaller number of SMS to be sent in checking period.
@@ -773,6 +783,16 @@
      */
     protected void sendRawPdu(byte[] smsc, byte[] pdu, PendingIntent sentIntent,
             PendingIntent deliveryIntent) {
+        if (!mSmsCapable) {
+            if (sentIntent != null) {
+                try {
+                    sentIntent.send(RESULT_ERROR_NO_SERVICE);
+                } catch (CanceledException ex) {}
+            }
+            Log.d(TAG, "Device does not support sms service.");
+            return;
+        }
+
         if (pdu == null) {
             if (sentIntent != null) {
                 try {
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
index 53555d8..01234b0 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
@@ -107,6 +107,13 @@
             return Activity.RESULT_OK;
         }
 
+        if (!mSmsCapable) {
+            // Device doesn't support SMS service,
+            Log.d(TAG, "Received short message on device which doesn't support "
+                    + "SMS service. Ignored.");
+            return Intents.RESULT_SMS_HANDLED;
+        }
+
         // See if we have a network duplicate SMS.
         SmsMessage sms = (SmsMessage) smsb;
         mLastDispatchedSmsFingerprint = sms.getIncomingSmsFingerprint();
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java b/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java
index 70f8f86..497c552 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java
@@ -110,6 +110,13 @@
             return Intents.RESULT_SMS_HANDLED;
         }
 
+        if (!mSmsCapable) {
+            // Device doesn't support SMS service,
+            Log.d(TAG, "Received short message on device which doesn't support "
+                    + "SMS service. Ignored.");
+            return Intents.RESULT_SMS_HANDLED;
+        }
+
         // Special case the message waiting indicator messages
         if (sms.isMWISetMessage()) {
             mGsmPhone.updateMessageWaitingIndicator(true);