Merge "Teach AssetAtlas about more drawables" into lmp-mr1-dev
diff --git a/core/java/android/hardware/camera2/legacy/GLThreadManager.java b/core/java/android/hardware/camera2/legacy/GLThreadManager.java
index 64c532b..b160d2a 100644
--- a/core/java/android/hardware/camera2/legacy/GLThreadManager.java
+++ b/core/java/android/hardware/camera2/legacy/GLThreadManager.java
@@ -22,6 +22,8 @@
 import android.os.Handler;
 import android.os.Message;
 import android.util.Log;
+import android.util.Pair;
+import android.util.Size;
 import android.view.Surface;
 
 import java.util.Collection;
@@ -57,11 +59,11 @@
      */
     private static class ConfigureHolder {
         public final ConditionVariable condition;
-        public final Collection<Surface> surfaces;
+        public final Collection<Pair<Surface, Size>> surfaces;
         public final CaptureCollector collector;
 
-        public ConfigureHolder(ConditionVariable condition, Collection<Surface> surfaces,
-                               CaptureCollector collector) {
+        public ConfigureHolder(ConditionVariable condition, Collection<Pair<Surface,
+                Size>> surfaces, CaptureCollector collector) {
             this.condition = condition;
             this.surfaces = surfaces;
             this.collector = collector;
@@ -202,10 +204,12 @@
      * Configure the GL renderer for the given set of output surfaces, and block until
      * this configuration has been applied.
      *
-     * @param surfaces a collection of {@link android.view.Surface}s to configure.
+     * @param surfaces a collection of pairs of {@link android.view.Surface}s and their
+     *                 corresponding sizes to configure.
      * @param collector a {@link CaptureCollector} to retrieve requests from.
      */
-    public void setConfigurationAndWait(Collection<Surface> surfaces, CaptureCollector collector) {
+    public void setConfigurationAndWait(Collection<Pair<Surface, Size>> surfaces,
+                                        CaptureCollector collector) {
         checkNotNull(collector, "collector must not be null");
         Handler handler = mGLHandlerThread.getHandler();
 
diff --git a/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java b/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java
index 3a976ba..3043d13 100644
--- a/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java
+++ b/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java
@@ -24,7 +24,6 @@
 import android.hardware.camera2.impl.CameraDeviceImpl;
 import android.hardware.camera2.impl.CaptureResultExtras;
 import android.hardware.camera2.ICameraDeviceCallbacks;
-import android.hardware.camera2.params.StreamConfiguration;
 import android.hardware.camera2.params.StreamConfigurationMap;
 import android.hardware.camera2.utils.ArrayUtils;
 import android.hardware.camera2.utils.CameraBinderDecorator;
@@ -36,6 +35,7 @@
 import android.os.HandlerThread;
 import android.os.RemoteException;
 import android.util.Log;
+import android.util.Pair;
 import android.util.Size;
 import android.view.Surface;
 
@@ -78,6 +78,15 @@
     private final Handler mResultHandler;
     private static final int ILLEGAL_VALUE = -1;
 
+    // Keep up to date with values in hardware/libhardware/include/hardware/gralloc.h
+    private static final int GRALLOC_USAGE_RENDERSCRIPT = 0x00100000;
+    private static final int GRALLOC_USAGE_SW_READ_OFTEN = 0x00000003;
+    private static final int GRALLOC_USAGE_HW_TEXTURE = 0x00000100;
+    private static final int GRALLOC_USAGE_HW_COMPOSER = 0x00000800;
+    private static final int GRALLOC_USAGE_HW_VIDEO_ENCODER = 0x00010000;
+
+    private static final int MAX_DIMEN_FOR_ROUNDING = 1080; // maximum allowed width for rounding
+
     private CaptureResultExtras getExtrasFromRequest(RequestHolder holder) {
         if (holder == null) {
             return new CaptureResultExtras(ILLEGAL_VALUE, ILLEGAL_VALUE, ILLEGAL_VALUE,
@@ -276,6 +285,7 @@
      *          on success.
      */
     public int configureOutputs(List<Surface> outputs) {
+        List<Pair<Surface, Size>> sizedSurfaces = new ArrayList<>();
         if (outputs != null) {
             for (Surface output : outputs) {
                 if (output == null) {
@@ -289,16 +299,25 @@
                 try {
                     Size s = getSurfaceSize(output);
                     int surfaceType = detectSurfaceType(output);
-                    Size[] sizes = streamConfigurations.getOutputSizes(surfaceType);
+                    int usageFlags = detectSurfaceUsageFlags(output);
 
+                    // Keep up to date with allowed consumer types in
+                    // frameworks/av/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+                    int disallowedFlags = GRALLOC_USAGE_HW_VIDEO_ENCODER | GRALLOC_USAGE_RENDERSCRIPT;
+                    int allowedFlags = GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_SW_READ_OFTEN |
+                            GRALLOC_USAGE_HW_COMPOSER;
+                    boolean flexibleConsumer = ((usageFlags & disallowedFlags) == 0 &&
+                            (usageFlags & allowedFlags) != 0);
+
+                    Size[] sizes = streamConfigurations.getOutputSizes(surfaceType);
                     if (sizes == null) {
                         // WAR: Override default format to IMPLEMENTATION_DEFINED for b/9487482
                         if ((surfaceType >= LegacyMetadataMapper.HAL_PIXEL_FORMAT_RGBA_8888 &&
                             surfaceType <= LegacyMetadataMapper.HAL_PIXEL_FORMAT_BGRA_8888)) {
 
-                            // YUV_420_888 is always present in LEGACY for all IMPLEMENTATION_DEFINED
-                            // output sizes, and is publicly visible in the API (i.e.
-                            // {@code #getOutputSizes} works here).
+                            // YUV_420_888 is always present in LEGACY for all
+                            // IMPLEMENTATION_DEFINED output sizes, and is publicly visible in the
+                            // API (i.e. {@code #getOutputSizes} works here).
                             sizes = streamConfigurations.getOutputSizes(ImageFormat.YUV_420_888);
                         } else if (surfaceType == LegacyMetadataMapper.HAL_PIXEL_FORMAT_BLOB) {
                             sizes = streamConfigurations.getOutputSizes(ImageFormat.JPEG);
@@ -306,12 +325,18 @@
                     }
 
                     if (!ArrayUtils.contains(sizes, s)) {
-                        String reason = (sizes == null) ? "format is invalid." :
-                                ("size not in valid set: " + Arrays.toString(sizes));
-                        Log.e(TAG, String.format("Surface with size (w=%d, h=%d) and format 0x%x is"
-                                + " not valid, %s", s.getWidth(), s.getHeight(), surfaceType,
-                                reason));
-                        return BAD_VALUE;
+                        if (flexibleConsumer && (s = findClosestSize(s, sizes)) != null) {
+                            sizedSurfaces.add(new Pair<>(output, s));
+                        } else {
+                            String reason = (sizes == null) ? "format is invalid." :
+                                    ("size not in valid set: " + Arrays.toString(sizes));
+                            Log.e(TAG, String.format("Surface with size (w=%d, h=%d) and format " +
+                                    "0x%x is not valid, %s", s.getWidth(), s.getHeight(),
+                                    surfaceType, reason));
+                            return BAD_VALUE;
+                        }
+                    } else {
+                        sizedSurfaces.add(new Pair<>(output, s));
                     }
                 } catch (BufferQueueAbandonedException e) {
                     Log.e(TAG, "Surface bufferqueue is abandoned, cannot configure as output: ", e);
@@ -323,7 +348,7 @@
 
         boolean success = false;
         if (mDeviceState.setConfiguring()) {
-            mRequestThreadManager.configure(outputs);
+            mRequestThreadManager.configure(sizedSurfaces);
             success = mDeviceState.setIdle();
         }
 
@@ -473,6 +498,31 @@
         }
     }
 
+    static long findEuclidDistSquare(Size a, Size b) {
+        long d0 = a.getWidth() - b.getWidth();
+        long d1 = a.getHeight() - b.getHeight();
+        return d0 * d0 + d1 * d1;
+    }
+
+    // Keep up to date with rounding behavior in
+    // frameworks/av/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+    static Size findClosestSize(Size size, Size[] supportedSizes) {
+        if (size == null || supportedSizes == null) {
+            return null;
+        }
+        Size bestSize = null;
+        for (Size s : supportedSizes) {
+            if (s.equals(size)) {
+                return size;
+            } else if (s.getWidth() <= MAX_DIMEN_FOR_ROUNDING && (bestSize == null ||
+                    LegacyCameraDevice.findEuclidDistSquare(size, s) <
+                    LegacyCameraDevice.findEuclidDistSquare(bestSize, s))) {
+                bestSize = s;
+            }
+        }
+        return bestSize;
+    }
+
     /**
      * Query the surface for its currently configured default buffer size.
      * @param surface a non-{@code null} {@code Surface}
@@ -490,6 +540,11 @@
         return new Size(dimens[0], dimens[1]);
     }
 
+    static int detectSurfaceUsageFlags(Surface surface) {
+        checkNotNull(surface);
+        return nativeDetectSurfaceUsageFlags(surface);
+    }
+
     static int detectSurfaceType(Surface surface) throws BufferQueueAbandonedException {
         checkNotNull(surface);
         return LegacyExceptionUtils.throwOnError(nativeDetectSurfaceType(surface));
@@ -608,5 +663,7 @@
 
     private static native int nativeSetNextTimestamp(Surface surface, long timestamp);
 
+    private static native int nativeDetectSurfaceUsageFlags(Surface surface);
+
     static native int nativeGetJpegFooterSize();
 }
diff --git a/core/java/android/hardware/camera2/legacy/RequestThreadManager.java b/core/java/android/hardware/camera2/legacy/RequestThreadManager.java
index 35deb71..6535a4e 100644
--- a/core/java/android/hardware/camera2/legacy/RequestThreadManager.java
+++ b/core/java/android/hardware/camera2/legacy/RequestThreadManager.java
@@ -41,6 +41,7 @@
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.Iterator;
 import java.util.List;
 import java.util.concurrent.TimeUnit;
 
@@ -116,9 +117,10 @@
      */
     private static class ConfigureHolder {
         public final ConditionVariable condition;
-        public final Collection<Surface> surfaces;
+        public final Collection<Pair<Surface, Size>> surfaces;
 
-        public ConfigureHolder(ConditionVariable condition, Collection<Surface> surfaces) {
+        public ConfigureHolder(ConditionVariable condition, Collection<Pair<Surface,
+                Size>> surfaces) {
             this.condition = condition;
             this.surfaces = surfaces;
         }
@@ -317,7 +319,7 @@
         startPreview();
     }
 
-    private void configureOutputs(Collection<Surface> outputs) {
+    private void configureOutputs(Collection<Pair<Surface, Size>> outputs) {
         if (DEBUG) {
             String outputsStr = outputs == null ? "null" : (outputs.size() + " surfaces");
             Log.d(TAG, "configureOutputs with " + outputsStr);
@@ -346,10 +348,15 @@
         mJpegSurfaceIds.clear();
         mPreviewTexture = null;
 
+        List<Size> previewOutputSizes = new ArrayList<>();
+        List<Size> callbackOutputSizes = new ArrayList<>();
+
         int facing = mCharacteristics.get(CameraCharacteristics.LENS_FACING);
         int orientation = mCharacteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
         if (outputs != null) {
-            for (Surface s : outputs) {
+            for (Pair<Surface, Size> outPair : outputs) {
+                Surface s = outPair.first;
+                Size outSize = outPair.second;
                 try {
                     int format = LegacyCameraDevice.detectSurfaceType(s);
                     LegacyCameraDevice.setSurfaceOrientation(s, facing, orientation);
@@ -362,9 +369,11 @@
                             }
                             mJpegSurfaceIds.add(LegacyCameraDevice.getSurfaceId(s));
                             mCallbackOutputs.add(s);
+                            callbackOutputSizes.add(outSize);
                             break;
                         default:
                             mPreviewOutputs.add(s);
+                            previewOutputSizes.add(outSize);
                             break;
                     }
                 } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) {
@@ -391,18 +400,9 @@
         mParams.setPreviewFpsRange(bestRange[Camera.Parameters.PREVIEW_FPS_MIN_INDEX],
                 bestRange[Camera.Parameters.PREVIEW_FPS_MAX_INDEX]);
 
-        if (mPreviewOutputs.size() > 0) {
-            List<Size> outputSizes = new ArrayList<>(outputs.size());
-            for (Surface s : mPreviewOutputs) {
-                try {
-                    Size size = LegacyCameraDevice.getSurfaceSize(s);
-                    outputSizes.add(size);
-                } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) {
-                    Log.w(TAG, "Surface abandoned, skipping...", e);
-                }
-            }
+        if (previewOutputSizes.size() > 0) {
 
-            Size largestOutput = SizeAreaComparator.findLargestByArea(outputSizes);
+            Size largestOutput = SizeAreaComparator.findLargestByArea(previewOutputSizes);
 
             // Find largest jpeg dimension - assume to have the same aspect ratio as sensor.
             Size largestJpegDimen = ParameterUtils.getLargestSupportedJpegSizeByArea(mParams);
@@ -439,7 +439,8 @@
             }
         }
 
-        Size smallestSupportedJpegSize = calculatePictureSize(mCallbackOutputs, mParams);
+        Size smallestSupportedJpegSize = calculatePictureSize(mCallbackOutputs,
+                callbackOutputSizes, mParams);
         if (smallestSupportedJpegSize != null) {
             /*
              * Set takePicture size to the smallest supported JPEG size large enough
@@ -457,7 +458,12 @@
             mGLThreadManager.start();
         }
         mGLThreadManager.waitUntilStarted();
-        mGLThreadManager.setConfigurationAndWait(mPreviewOutputs, mCaptureCollector);
+        List<Pair<Surface, Size>> previews = new ArrayList<>();
+        Iterator<Size> previewSizeIter = previewOutputSizes.iterator();
+        for (Surface p : mPreviewOutputs) {
+            previews.add(new Pair<>(p, previewSizeIter.next()));
+        }
+        mGLThreadManager.setConfigurationAndWait(previews, mCaptureCollector);
         mGLThreadManager.allowNewFrames();
         mPreviewTexture = mGLThreadManager.getCurrentSurfaceTexture();
         if (mPreviewTexture != null) {
@@ -499,26 +505,25 @@
      *          {@code null} if the {@code callbackOutputs} did not have any {@code JPEG}
      *          surfaces.
      */
-    private Size calculatePictureSize(
-            Collection<Surface> callbackOutputs, Camera.Parameters params) {
+    private Size calculatePictureSize( List<Surface> callbackOutputs,
+                                       List<Size> callbackSizes, Camera.Parameters params) {
         /*
          * Find the largest JPEG size (if any), from the configured outputs:
          * - the api1 picture size should be set to the smallest legal size that's at least as large
          *   as the largest configured JPEG size
          */
-        List<Size> configuredJpegSizes = new ArrayList<Size>();
+        if (callbackOutputs.size() != callbackSizes.size()) {
+            throw new IllegalStateException("Input collections must be same length");
+        }
+        List<Size> configuredJpegSizes = new ArrayList<>();
+        Iterator<Size> sizeIterator = callbackSizes.iterator();
         for (Surface callbackSurface : callbackOutputs) {
-            try {
-
+            Size jpegSize = sizeIterator.next();
                 if (!LegacyCameraDevice.containsSurfaceId(callbackSurface, mJpegSurfaceIds)) {
                     continue; // Ignore non-JPEG callback formats
                 }
 
-                Size jpegSize = LegacyCameraDevice.getSurfaceSize(callbackSurface);
                 configuredJpegSizes.add(jpegSize);
-            } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) {
-                Log.w(TAG, "Surface abandoned, skipping...", e);
-            }
         }
         if (!configuredJpegSizes.isEmpty()) {
             /*
@@ -994,7 +999,7 @@
      *
      * @param outputs a {@link java.util.Collection} of outputs to configure.
      */
-    public void configure(Collection<Surface> outputs) {
+    public void configure(Collection<Pair<Surface, Size>> outputs) {
         Handler handler = mRequestThread.waitAndGetHandler();
         final ConditionVariable condition = new ConditionVariable(/*closed*/false);
         ConfigureHolder holder = new ConfigureHolder(condition, outputs);
diff --git a/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java b/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java
index c0d1d5e..4853b81 100644
--- a/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java
+++ b/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java
@@ -397,16 +397,9 @@
                 EGL14.EGL_NONE
         };
         for (EGLSurfaceHolder holder : surfaces) {
-            try {
-                Size size = LegacyCameraDevice.getSurfaceSize(holder.surface);
-                holder.width = size.getWidth();
-                holder.height = size.getHeight();
-                holder.eglSurface = EGL14.eglCreateWindowSurface(mEGLDisplay, mConfigs,
-                        holder.surface, surfaceAttribs, /*offset*/ 0);
-                checkEglError("eglCreateWindowSurface");
-            } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) {
-                Log.w(TAG, "Surface abandoned, skipping...", e);
-            }
+            holder.eglSurface = EGL14.eglCreateWindowSurface(mEGLDisplay, mConfigs,
+                    holder.surface, surfaceAttribs, /*offset*/ 0);
+            checkEglError("eglCreateWindowSurface");
         }
     }
 
@@ -417,24 +410,17 @@
 
         int maxLength = 0;
         for (EGLSurfaceHolder holder : surfaces) {
-            try {
-                Size size = LegacyCameraDevice.getSurfaceSize(holder.surface);
-                int length = size.getWidth() * size.getHeight();
-                // Find max surface size, ensure PBuffer can hold this many pixels
-                maxLength = (length > maxLength) ? length : maxLength;
-                int[] surfaceAttribs = {
-                        EGL14.EGL_WIDTH, size.getWidth(),
-                        EGL14.EGL_HEIGHT, size.getHeight(),
-                        EGL14.EGL_NONE
-                };
-                holder.width = size.getWidth();
-                holder.height = size.getHeight();
-                holder.eglSurface =
-                        EGL14.eglCreatePbufferSurface(mEGLDisplay, mConfigs, surfaceAttribs, 0);
-                checkEglError("eglCreatePbufferSurface");
-            } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) {
-                Log.w(TAG, "Surface abandoned, skipping...", e);
-            }
+            int length = holder.width * holder.height;
+            // Find max surface size, ensure PBuffer can hold this many pixels
+            maxLength = (length > maxLength) ? length : maxLength;
+            int[] surfaceAttribs = {
+                    EGL14.EGL_WIDTH, holder.width,
+                    EGL14.EGL_HEIGHT, holder.height,
+                    EGL14.EGL_NONE
+            };
+            holder.eglSurface =
+                    EGL14.eglCreatePbufferSurface(mEGLDisplay, mConfigs, surfaceAttribs, 0);
+            checkEglError("eglCreatePbufferSurface");
         }
         mPBufferPixels = ByteBuffer.allocateDirect(maxLength * PBUFFER_PIXEL_BYTES)
                 .order(ByteOrder.nativeOrder());
@@ -569,7 +555,7 @@
      *
      * @param surfaces a {@link Collection} of surfaces.
      */
-    public void configureSurfaces(Collection<Surface> surfaces) {
+    public void configureSurfaces(Collection<Pair<Surface, Size>> surfaces) {
         releaseEGLContext();
 
         if (surfaces == null || surfaces.size() == 0) {
@@ -577,18 +563,20 @@
             return;
         }
 
-        for (Surface s : surfaces) {
+        for (Pair<Surface, Size> p : surfaces) {
+            Surface s = p.first;
+            Size surfaceSize = p.second;
             // If pixel conversions aren't handled by egl, use a pbuffer
             try {
+                EGLSurfaceHolder holder = new EGLSurfaceHolder();
+                holder.surface = s;
+                holder.width = surfaceSize.getWidth();
+                holder.height = surfaceSize.getHeight();
                 if (LegacyCameraDevice.needsConversion(s)) {
                     // Always override to YV12 output for YUV surface formats.
                     LegacyCameraDevice.setSurfaceFormat(s, ImageFormat.YV12);
-                    EGLSurfaceHolder holder = new EGLSurfaceHolder();
-                    holder.surface = s;
                     mConversionSurfaces.add(holder);
                 } else {
-                    EGLSurfaceHolder holder = new EGLSurfaceHolder();
-                    holder.surface = s;
                     mSurfaces.add(holder);
                 }
             } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) {
@@ -672,10 +660,11 @@
         List<Long> targetSurfaceIds = LegacyCameraDevice.getSurfaceIds(targetSurfaces);
         for (EGLSurfaceHolder holder : mSurfaces) {
             if (LegacyCameraDevice.containsSurfaceId(holder.surface, targetSurfaceIds)) {
-                makeCurrent(holder.eglSurface);
-                try {
+                try{
                     LegacyCameraDevice.setSurfaceDimens(holder.surface, holder.width,
                             holder.height);
+                    makeCurrent(holder.eglSurface);
+
                     LegacyCameraDevice.setNextTimestamp(holder.surface, captureHolder.second);
                     drawFrame(mSurfaceTexture, holder.width, holder.height);
                     swapBuffers(holder.eglSurface);
@@ -695,10 +684,11 @@
 
                 try {
                     int format = LegacyCameraDevice.detectSurfaceType(holder.surface);
+                    LegacyCameraDevice.setSurfaceDimens(holder.surface, holder.width,
+                            holder.height);
                     LegacyCameraDevice.setNextTimestamp(holder.surface, captureHolder.second);
                     LegacyCameraDevice.produceFrame(holder.surface, mPBufferPixels.array(),
                             holder.width, holder.height, format);
-                    swapBuffers(holder.eglSurface);
                 } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) {
                     Log.w(TAG, "Surface abandoned, dropping frame. ", e);
                 }
diff --git a/core/java/android/net/LocalServerSocket.java b/core/java/android/net/LocalServerSocket.java
index a36203b..9464222 100644
--- a/core/java/android/net/LocalServerSocket.java
+++ b/core/java/android/net/LocalServerSocket.java
@@ -20,12 +20,8 @@
 import java.io.FileDescriptor;
 
 /**
- * non-standard class for creating inbound UNIX-domain socket
- * on the Android platform, this is created in the Linux non-filesystem
- * namespace.
- *
- * On simulator platforms, this may be created in a temporary directory on
- * the filesystem
+ * Non-standard class for creating an inbound UNIX-domain socket
+ * in the Linux abstract namespace.
  */
 public class LocalServerSocket {
     private final LocalSocketImpl impl;
@@ -35,7 +31,7 @@
     private static final int LISTEN_BACKLOG = 50;
 
     /**
-     * Crewates a new server socket listening at specified name.
+     * Creates a new server socket listening at specified name.
      * On the Android platform, the name is created in the Linux
      * abstract namespace (instead of on the filesystem).
      * 
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index 67f632f..9496b53 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -691,8 +691,8 @@
                     if (DEBUG) Log.v(TAG, "New surface: " + mSurfaceHolder.mSurface
                             + ", frame=" + mWinFrame);
                     
-                    int w = mWinFrame.width() + mOverscanInsets.left + mOverscanInsets.right;
-                    int h = mWinFrame.height() + mOverscanInsets.top + mOverscanInsets.bottom;
+                    int w = mWinFrame.width();
+                    int h = mWinFrame.height();
 
                     if (!fixedSize) {
                         final Rect padding = mIWallpaperEngine.mDisplayPadding;
diff --git a/core/java/android/view/RenderNodeAnimator.java b/core/java/android/view/RenderNodeAnimator.java
index 7feca30..7b35a3b 100644
--- a/core/java/android/view/RenderNodeAnimator.java
+++ b/core/java/android/view/RenderNodeAnimator.java
@@ -148,6 +148,10 @@
         if (mState != STATE_PREPARE) {
             throw new IllegalStateException("Animator has already started, cannot change it now!");
         }
+        if (mNativePtr == null) {
+            throw new IllegalStateException("Animator's target has been destroyed "
+                    + "(trying to modify an animation after activity destroy?)");
+        }
     }
 
     static boolean isNativeInterpolator(TimeInterpolator interpolator) {
@@ -180,7 +184,10 @@
         mState = STATE_DELAYED;
         applyInterpolator();
 
-        if (mStartDelay <= 0 || !mUiThreadHandlesDelay) {
+        if (mNativePtr == null) {
+            // It's dead, immediately cancel
+            cancel();
+        } else if (mStartDelay <= 0 || !mUiThreadHandlesDelay) {
             nSetStartDelay(mNativePtr.get(), mStartDelay);
             doStart();
         } else {
@@ -208,7 +215,9 @@
 
     private void moveToRunningState() {
         mState = STATE_RUNNING;
-        nStart(mNativePtr.get(), this);
+        if (mNativePtr != null) {
+            nStart(mNativePtr.get());
+        }
         notifyStartListeners();
     }
 
@@ -227,7 +236,6 @@
                 getHelper().removeDelayedAnimation(this);
                 moveToRunningState();
             }
-            nEnd(mNativePtr.get());
 
             final ArrayList<AnimatorListener> listeners = cloneListeners();
             final int numListeners = listeners == null ? 0 : listeners.size();
@@ -235,10 +243,7 @@
                 listeners.get(i).onAnimationCancel(this);
             }
 
-            if (mViewTarget != null) {
-                // Kick off a frame to flush the state change
-                mViewTarget.invalidateViewProperty(true, false);
-            }
+            end();
         }
     }
 
@@ -249,10 +254,15 @@
                 getHelper().removeDelayedAnimation(this);
                 doStart();
             }
-            nEnd(mNativePtr.get());
-            if (mViewTarget != null) {
-                // Kick off a frame to flush the state change
-                mViewTarget.invalidateViewProperty(true, false);
+            if (mNativePtr != null) {
+                nEnd(mNativePtr.get());
+                if (mViewTarget != null) {
+                    // Kick off a frame to flush the state change
+                    mViewTarget.invalidateViewProperty(true, false);
+                }
+            } else {
+                // It's already dead, jump to onFinish
+                onFinished();
             }
         }
     }
@@ -281,9 +291,11 @@
     }
 
     private void setTarget(RenderNode node) {
+        checkMutable();
         if (mTarget != null) {
             throw new IllegalStateException("Target already set!");
         }
+        nSetListener(mNativePtr.get(), this);
         mTarget = node;
         mTarget.addAnimator(this);
     }
@@ -346,6 +358,12 @@
     }
 
     protected void onFinished() {
+        if (mState == STATE_PREPARE) {
+            // Unlikely but possible, the native side has been destroyed
+            // before we have started.
+            releaseNativePtr();
+            return;
+        }
         if (mState == STATE_DELAYED) {
             getHelper().removeDelayedAnimation(this);
             notifyStartListeners();
@@ -361,8 +379,14 @@
         // Release the native object, as it has a global reference to us. This
         // breaks the cyclic reference chain, and allows this object to be
         // GC'd
-        mNativePtr.release();
-        mNativePtr = null;
+        releaseNativePtr();
+    }
+
+    private void releaseNativePtr() {
+        if (mNativePtr != null) {
+            mNativePtr.release();
+            mNativePtr = null;
+        }
     }
 
     @SuppressWarnings("unchecked")
@@ -484,7 +508,8 @@
     private static native void nSetStartDelay(long nativePtr, long startDelay);
     private static native void nSetInterpolator(long animPtr, long interpolatorPtr);
     private static native void nSetAllowRunningAsync(long animPtr, boolean mayRunAsync);
+    private static native void nSetListener(long animPtr, RenderNodeAnimator listener);
 
-    private static native void nStart(long animPtr, RenderNodeAnimator finishListener);
+    private static native void nStart(long animPtr);
     private static native void nEnd(long animPtr);
 }
diff --git a/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp b/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp
index 8440a0e..b44c829 100644
--- a/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp
+++ b/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp
@@ -470,6 +470,26 @@
     return NO_ERROR;
 }
 
+static jint LegacyCameraDevice_nativeDetectSurfaceUsageFlags(JNIEnv* env, jobject thiz,
+          jobject surface) {
+    ALOGV("nativeDetectSurfaceUsageFlags");
+
+    sp<ANativeWindow> anw;
+    if ((anw = getNativeWindow(env, surface)) == NULL) {
+        jniThrowException(env, "Ljava/lang/UnsupportedOperationException;",
+            "Could not retrieve native window from surface.");
+        return BAD_VALUE;
+    }
+    int32_t usage = 0;
+    status_t err = anw->query(anw.get(), NATIVE_WINDOW_CONSUMER_USAGE_BITS, &usage);
+    if(err != NO_ERROR) {
+        jniThrowException(env, "Ljava/lang/UnsupportedOperationException;",
+            "Error while querying surface usage bits");
+        return err;
+    }
+    return usage;
+}
+
 static jint LegacyCameraDevice_nativeDetectTextureDimens(JNIEnv* env, jobject thiz,
         jobject surfaceTexture, jintArray dimens) {
     ALOGV("nativeDetectTextureDimens");
@@ -713,6 +733,9 @@
     { "nativeGetJpegFooterSize",
     "()I",
     (void *)LegacyCameraDevice_nativeGetJpegFooterSize },
+    { "nativeDetectSurfaceUsageFlags",
+    "(Landroid/view/Surface;)I",
+    (void *)LegacyCameraDevice_nativeDetectSurfaceUsageFlags },
 };
 
 // Get all the required offsets in java class and register native functions
diff --git a/core/jni/android_view_RenderNodeAnimator.cpp b/core/jni/android_view_RenderNodeAnimator.cpp
index 311882d..eb56639 100644
--- a/core/jni/android_view_RenderNodeAnimator.cpp
+++ b/core/jni/android_view_RenderNodeAnimator.cpp
@@ -177,9 +177,13 @@
     animator->setAllowRunningAsync(mayRunAsync);
 }
 
-static void start(JNIEnv* env, jobject clazz, jlong animatorPtr, jobject finishListener) {
+static void setListener(JNIEnv* env, jobject clazz, jlong animatorPtr, jobject finishListener) {
     BaseRenderNodeAnimator* animator = reinterpret_cast<BaseRenderNodeAnimator*>(animatorPtr);
     animator->setListener(new AnimationListenerBridge(env, finishListener));
+}
+
+static void start(JNIEnv* env, jobject clazz, jlong animatorPtr) {
+    BaseRenderNodeAnimator* animator = reinterpret_cast<BaseRenderNodeAnimator*>(animatorPtr);
     animator->start();
 }
 
@@ -208,7 +212,8 @@
     { "nSetStartDelay", "(JJ)V", (void*) setStartDelay },
     { "nSetInterpolator", "(JJ)V", (void*) setInterpolator },
     { "nSetAllowRunningAsync", "(JZ)V", (void*) setAllowRunningAsync },
-    { "nStart", "(JLandroid/view/RenderNodeAnimator;)V", (void*) start },
+    { "nSetListener", "(JLandroid/view/RenderNodeAnimator;)V", (void*) setListener},
+    { "nStart", "(J)V", (void*) start},
     { "nEnd", "(J)V", (void*) end },
 #endif
 };
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index d0c612d..6769c85 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1830,6 +1830,9 @@
          provisioning, availability etc -->
     <bool name="config_carrier_volte_available">false</bool>
 
+    <!-- Flag specifying whether VoLTE availability is based on provisioning -->
+    <bool name="config_carrier_volte_provisioned">false</bool>
+
     <!-- Flag specifying whether VT is available on device -->
     <bool name="config_device_vt_available">false</bool>
 
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 9845096..4f2ed22 100755
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2079,6 +2079,7 @@
   <java-symbol type="bool" name="imsServiceAllowTurnOff" />
   <java-symbol type="bool" name="config_device_volte_available" />
   <java-symbol type="bool" name="config_carrier_volte_available" />
+  <java-symbol type="bool" name="config_carrier_volte_provisioned" />
   <java-symbol type="bool" name="config_device_vt_available" />
   <java-symbol type="bool" name="config_carrier_vt_available" />
   <java-symbol type="bool" name="useImsAlwaysForEmergencyCall" />
diff --git a/docs/html/design/material/index.jd b/docs/html/design/material/index.jd
index db18a83..4d9a1a7 100644
--- a/docs/html/design/material/index.jd
+++ b/docs/html/design/material/index.jd
@@ -5,6 +5,40 @@
 
 @jd:body
 
+<!-- developer docs box -->
+<a class="notice-developers right" href="{@docRoot}training/material/index.html">
+  <div>
+    <h3>Developer Docs</h3>
+    <p>Creating Apps with Material Design</p>
+  </div>
+</a>
+
+<!-- video box -->
+<a class="notice-developers-video" href="https://www.youtube.com/watch?v=p4gmvHyuZzw">
+<div>
+    <h3>Video</h3>
+    <p>Introduction to Material Design</p>
+</div>
+</a>
+
+<!-- video box -->
+<a class="notice-developers-video" href="https://www.youtube.com/watch?v=YaG_ljfzeUw">
+<div>
+    <h3>Video</h3>
+    <p>Paper and Ink: The Materials that Matter</p>
+</div>
+</a>
+
+<!-- video box -->
+<a class="notice-developers-video" href="https://www.youtube.com/watch?v=XOcCOBe8PTc">
+<div>
+    <h3>Video</h3>
+    <p>Material Design in the Google I/O App</p>
+</div>
+</a>
+
+
+
 <p itemprop="description">Material design is a comprehensive guide for visual, motion, and
 interaction design across platforms and devices. Android now includes support for
 material design apps. To use material design in your Android apps, follow the guidelines defined
diff --git a/docs/html/images/tools/projectview01.png b/docs/html/images/tools/projectview01.png
index 90589fb..2deb752 100644
--- a/docs/html/images/tools/projectview01.png
+++ b/docs/html/images/tools/projectview01.png
Binary files differ
diff --git a/docs/html/images/tools/studio-cloudmodule.png b/docs/html/images/tools/studio-cloudmodule.png
index b7c4fb7..cffa2d5 100644
--- a/docs/html/images/tools/studio-cloudmodule.png
+++ b/docs/html/images/tools/studio-cloudmodule.png
Binary files differ
diff --git a/docs/html/images/tools/studio-helloworld-design.png b/docs/html/images/tools/studio-helloworld-design.png
index ff90c6b..a355e7a 100644
--- a/docs/html/images/tools/studio-helloworld-design.png
+++ b/docs/html/images/tools/studio-helloworld-design.png
Binary files differ
diff --git a/docs/html/images/tools/studio-helloworld-text.png b/docs/html/images/tools/studio-helloworld-text.png
index 5dde675..28e39fe 100644
--- a/docs/html/images/tools/studio-helloworld-text.png
+++ b/docs/html/images/tools/studio-helloworld-text.png
Binary files differ
diff --git a/docs/html/images/tools/studio-projectview_scripts.png b/docs/html/images/tools/studio-projectview_scripts.png
index 3e7b9cd..a0565c5 100644
--- a/docs/html/images/tools/studio-projectview_scripts.png
+++ b/docs/html/images/tools/studio-projectview_scripts.png
Binary files differ
diff --git a/docs/html/images/tools/studio-samples-githubaccess.png b/docs/html/images/tools/studio-samples-githubaccess.png
index 991bf69..3980361 100644
--- a/docs/html/images/tools/studio-samples-githubaccess.png
+++ b/docs/html/images/tools/studio-samples-githubaccess.png
Binary files differ
diff --git a/docs/html/images/tools/studio-setup-wizard.png b/docs/html/images/tools/studio-setup-wizard.png
index f84660a..ccd92d3 100644
--- a/docs/html/images/tools/studio-setup-wizard.png
+++ b/docs/html/images/tools/studio-setup-wizard.png
Binary files differ
diff --git a/docs/html/images/tools/studio-tvwearsupport.png b/docs/html/images/tools/studio-tvwearsupport.png
index 02bf484..88343a6 100644
--- a/docs/html/images/tools/studio-tvwearsupport.png
+++ b/docs/html/images/tools/studio-tvwearsupport.png
Binary files differ
diff --git a/docs/html/sdk/index.jd b/docs/html/sdk/index.jd
index 7b40f00..dc7a6ca 100644
--- a/docs/html/sdk/index.jd
+++ b/docs/html/sdk/index.jd
@@ -429,8 +429,9 @@
 </div>
 
 
-<p>If you've been using Eclipse with ADT, be aware that the ADT plugin is no longer in active
-development, so you should migrate to Android Studio as soon as possible. For help moving projects,
+<p>If you have been using Eclipse with ADT, be aware that Android Studio is now the official IDE
+for Android, so you should migrate to Android Studio to receive all the
+latest IDE updates. For help moving projects,
 see <a href="{@docRoot}sdk/installing/migrate.html">Migrating to Android
 Studio</a>.</p>
 
diff --git a/docs/html/sdk/installing/index.jd b/docs/html/sdk/installing/index.jd
index 744ce15..14d274f 100644
--- a/docs/html/sdk/installing/index.jd
+++ b/docs/html/sdk/installing/index.jd
@@ -28,9 +28,8 @@
 <!-- ################    STUDIO    ##################### -->
 <div id="studio" heading="Installing Android Studio" style="display:none">
 
-<p>Android Studio provides the tools you need to start developing apps, including
-the Android Studio IDE (powered by IntelliJ) and guides you to install
-the Android SDK tools to streamline your Android app development.</p>
+<p>Android Studio provides everything you need to start developing apps for Android, including
+the Android Studio IDE and the Android SDK tools.</p>
 
 <p>If you didn't download Android Studio, go <a href="{@docRoot}sdk/index.html"
 ><b>download Android Studio now</b></a>, or switch to the
@@ -39,7 +38,8 @@
 
 
 <p>Before you set up Android Studio, be sure you have installed
-JDK 6 or greater (the JRE alone is not sufficient). To check if you
+JDK 6 or higher (the JRE alone is not sufficient)&mdash;JDK 7 is required when
+developing for Android 5.0 and higher. To check if you
 have JDK installed (and which version), open a terminal and type <code>javac -version</code>.
 If the JDK is not available or the version is lower than 6,
 <a href="http://www.oracle.com/technetwork/java/javase/downloads/index.html" class="external-link"
@@ -57,7 +57,7 @@
 <p><b>To set up Android Studio on Windows:</b></p>
   <ol>
     <li>Launch the <code>.exe</code> file you just downloaded.</li>
-    <li>Follow the setup wizard to install Android Studio and the SDK Tools.
+    <li>Follow the setup wizard to install Android Studio and any necessary SDK tools.
 
     <p>On some Windows systems, the launcher script does not find where Java is installed.
       If you encounter this problem,
@@ -88,7 +88,7 @@
   <ol>
     <li>Launch the {@code .dmg} file you just downloaded.</li>
     <li>Drag and drop Android Studio into the Applications folder.
-    <li>Open Android Studio and follow the instructions to set up the SDK.
+    <li>Open Android Studio and follow the setup wizard to install any necessary SDK tools.
       <p>
       Depending on your security settings, when you attempt to open Android Studio, you might
       see a warning that says the package is damaged and should be moved to the trash. If this
@@ -118,7 +118,7 @@
       <p>You may want to add {@code android-studio/bin/} to your PATH environmental
       variable so that you can start Android Studio from any directory.</p>
     </li>
-    <li>Follow the links to install the SDK tools outside of the Android Studio directories.</li>
+    <li>Follow the setup wizard to install any necessary SDK tools.</li>
   </ol>
 
 </div><!-- end linux -->
@@ -226,8 +226,7 @@
       <li><a href="https://help.ubuntu.com/community/Java">https://help.ubuntu.com/community/JavaInstallation</a></li>
     </ul>
   </li>
-  <li>Here are the steps to install Java and Eclipse, prior to installing
-  the Android SDK and ADT Plugin.
+  <li>Here are the steps to install Java:
     <ol>
       <li><p>If you are running a 64-bit distribution on your development
       machine, you need to install additional packages first. For Ubuntu 13.10 (Saucy Salamander)
@@ -241,13 +240,6 @@
       <pre class="no-pretty-print">apt-get install ia32-libs</pre>
       </li>
       <li>Next, install Java: <pre class="no-pretty-print">apt-get install sun-java6-jdk</pre></li>
-      <li>The Ubuntu package manager does not currently offer an Eclipse 3.7
-      version for download, so we recommend that you download Eclipse from
-      eclipse.org (<a
-      href="http://www.eclipse.org/downloads/">http://www.eclipse.org/downloads/</a>).
-      A Java or RCP version of Eclipse is recommended.</li>
-      <li>Follow the steps given in previous sections to install the SDK
-      and the ADT plugin. </li>
     </ol>
   </li>
 </ul>
@@ -272,47 +264,6 @@
 
 
 
-<!-- ###################    ADT BUNDLE     ####################### -->
-<div id="adt" heading="Installing the Eclipse ADT Bundle" style="display:none">
-
-
-<p>The Eclipse ADT Bundle provides everything you need to start developing apps, including
-the Android SDK tools and a version of the Eclipse IDE with built-in ADT
-(Android Developer Tools) to streamline your Android app development.</p>
-
-<p>If you didn't download the Eclipse ADT bundle, go <a href="{@docRoot}tools/eclipse/index.html"
-><b>download the Eclipse ADT bundle now</b></a>, or switch to the
-<a href="{@docRoot}sdk/installing/index.html?pkg=studio">Android Studio
-install</a> or <a href="{@docRoot}sdk/installing/index.html?pkg=tools">stand-alone SDK Tools
-install</a> instructions</i>.</p>
-
-<div class="procedure-box">
-<p><b>To set up the ADT Bundle:</b></p>
-<ol>
-<li>Unpack the ZIP file
-(named {@code adt-bundle-&lt;os_platform>.zip}) and save it to an appropriate location,
-such as a "Development" directory in your home directory.</li>
-<li>Open the {@code adt-bundle-&lt;os_platform>/eclipse/} directory and launch
-<strong>Eclipse</strong>.</li>
-</ol>
-
-<p class="caution"><strong>Caution:</strong> Do not move any of the files or directories
-from the {@code adt-bundle-&lt;os_platform>} directory. If you move the {@code eclipse/}
-or {@code sdk/} directory, ADT will not be able to locate the SDK and you'll
-need to manually update the ADT preferences.</p>
-</div>
-
-<p>Eclipse with ADT is now ready and loaded with the Android developer tools, but there are still
-a couple packages you should add to make your Android SDK complete.</p>
-
-<p class="paging-links">
-<a href="{@docRoot}sdk/installing/adding-packages.html" class="next-page-link">
-Continue: Adding SDK Packages</a></p>
-
-
-</div>
-<!-- ################    END ADT BUNDLE    ##################### -->
-
 
 
 
@@ -368,10 +319,6 @@
   // Show the SDK Tools (other IDE) instructions
   $("h1").text($("#tools").attr('heading'));
   $("#tools").show();
-} else if (package == "adt") {
-  // Show the ADT instructions
-  $("h1").text($("#adt").attr('heading'));
-  $("#adt").show();
 } else if (package == "studio") {
   // Show the Android Studio instructions
   $("h1").text($("#studio").attr('heading'));
diff --git a/docs/html/sdk/installing/installing-adt.jd b/docs/html/sdk/installing/installing-adt.jd
index c8200aa..0114848 100644
--- a/docs/html/sdk/installing/installing-adt.jd
+++ b/docs/html/sdk/installing/installing-adt.jd
@@ -15,12 +15,18 @@
 UI, debug your app, and export signed (or unsigned) app packages (APKs) for distribution.
 </p>
 
-<p class="note"><strong>Note:</strong> You should install the ADT plugin
-only if you already have an Eclipse installation that you want to continue using. If you do not
-have Eclipse installed, you should instead <b><a href="{@docRoot}sdk/index.html">install
-the complete Android SDK</a></b>, which includes the latest IDE for Android developers.</p>
+<p class="note"><strong>Note:</strong>
+If you have been using Eclipse with ADT, be aware that <a
+href="{@docRoot}tools/studio/index.html">Android Studio</a> is now the official IDE
+for Android, so you should migrate to Android Studio to receive all the
+latest IDE updates. For help moving projects,
+see <a href="/sdk/installing/migrate.html">Migrating to Android
+Studio</a>.</p>
 
-<p>Your existing Eclipse installation must meet these requirements:</p>
+
+<p>You should install the ADT plugin
+only if you already have an Eclipse installation that you want to continue using.
+Your existing Eclipse installation must meet these requirements:</p>
     <ul>
       <li><a href="http://eclipse.org/mobile/">Eclipse</a> 3.7.2 (Indigo) or greater
 <p class="note"><strong>Note:</strong> Eclipse 3.6 (Helios) is no longer
diff --git a/docs/html/sdk/installing/migrate.jd b/docs/html/sdk/installing/migrate.jd
index 06b9e3f..3c04cb4 100644
--- a/docs/html/sdk/installing/migrate.jd
+++ b/docs/html/sdk/installing/migrate.jd
@@ -6,7 +6,8 @@
 <div id="qv">
 <h2>See also</h2>
 <ul>
-  <li><a href="http://confluence.jetbrains.com/display/IntelliJIDEA/FAQ+on+Migrating+to+IntelliJ+IDEA">IntelliJ FAQ on migrating to IntelliJ IDEA</a></li>
+  <li><a href="http://confluence.jetbrains.com/display/IntelliJIDEA/FAQ+on+Migrating+to+IntelliJ+IDEA"
+  class="external-link">IntelliJ FAQ on migrating to IntelliJ IDEA</a></li>
  <li><a href="http://confluence.jetbrains.com/display/IntelliJIDEA/Working+in+Eclipse+Compatibility+Mode" class="external-link"
  >Eclipse Compatibility Mode</a></li>
  <li><a href="http://confluence.jetbrains.com/display/IntelliJIDEA/FAQ+on+Migrating+to+IntelliJ+IDEA" class="external-link"
@@ -15,25 +16,12 @@
 </div>
 </div>
 
-<p>If you're currently using Eclipse with ADT, we recommend you migrate to
-<a href="{@docRoot}tools/studio/index.html">Android Studio</a> as soon as possible, because
-the ADT plugin for Eclipse is no longer in active development.</p>
 
+<p>If you have been using <a href="{@docRoot}tools/help/adt.html">Eclipse with ADT</a>, be aware
+that <a href="{@docRoot}tools/studio/index.html">Android Studio</a> is now the official IDE for
+Android, so you should migrate to Android Studio to receive all the latest IDE updates.</p>
 
-<p>To migrate existing Android projects from Eclipse,
-you should export your projects from Eclipse in order to generate
-Gradle build files:</p>
-
-<ol>
-  <li>In Eclipse, select <strong>File &gt; Export</strong>.</li>
-  <li>Select <strong>Generate Gradle build files</strong> inside the Android folder, then click
-  <strong>Next</strong>.</li>
-  <li>Click <strong>Browse</strong> to find your project to export.</li>
-  <li>Select your project from the list, click <strong>OK</strong>, then <strong>Finish</strong>.</li>
-</ol>
-
-
-<p>You can then import the project into Android Studio:</p>
+<p>To migrate existing Android projects, simply import them using Android Studio:</p>
 
 <ol>
   <li>In Android Studio, close any projects currently open. You should see the
@@ -45,11 +33,10 @@
   <strong>OK</strong>. (You do not need to specify the Gradle home.)</li>
 </ol>
 
-<p>It's possible to import an existing Android project to Android Studio even if you
-don't generate a Gradle build file from Eclipse&mdash;Android Studio will successfully build and
-run projects using an existing Ant build file. However, in order to take advantage of build
-variants and other advanced features in the future,
-you should generate a Gradle build file using
-the ADT plugin or write your own Gradle build file for use with Android Studio.</p>
+<p>Android Studio properly updates the project structure and creates the appropriate
+Gradle build file.</p>
 
-<p><a href="{@docRoot}tools/studio/index.html">Learn more about Android Studio</a>.</p>
+<p>For more help getting started with Android Studio and the IntelliJ user experience,
+<a href="{@docRoot}tools/studio/index.html">learn more about Android Studio</a> and
+read <a href="http://confluence.jetbrains.com/display/IntelliJIDEA/FAQ+on+Migrating+to+IntelliJ+IDEA"
+  class="external-link">FAQ on Migrating to IntelliJ IDEA</a>.</p>
diff --git a/docs/html/sdk/installing/studio-build.jd b/docs/html/sdk/installing/studio-build.jd
index c80368f..4fe9071 100644
--- a/docs/html/sdk/installing/studio-build.jd
+++ b/docs/html/sdk/installing/studio-build.jd
@@ -13,7 +13,7 @@
    <li><a href="{@docRoot}sdk/installing/studio.html">
    Getting Started with Android Studio</a></li>
    <li><a href="{@docRoot}tools/studio/index.html">Android Studio Basics</a></li>
-   <li><a href="{@docRoot}tools/eclipse/migrate-adt.html">Migrating from Eclipse</a></li>
+   <li><a href="{@docRoot}sdk/installing/migrate.html">Migrating from Eclipse</a></li>
 </div>
 </div>
 
diff --git a/docs/html/tools/eclipse/index.jd b/docs/html/tools/eclipse/index.jd
deleted file mode 100644
index c8a998b..0000000
--- a/docs/html/tools/eclipse/index.jd
+++ /dev/null
@@ -1,37 +0,0 @@
-page.title=Eclipse ADT
-@jd:body
-
-
-<div id="qv-wrapper">
-<div id="qv">
-  <h2>See also</h2>
-  <ol>
-    <li><a href="{@docRoot}tools/sdk/index.html">Downloading Android Studio</a></li>
-    <li><a href="{@docRoot}tools/studio/index.html">Android Studio</a></li>
-    <li><a href="{@docRoot}tools/eclipse/migrate-adt.html">Migrating to Android Studio</a></li>
-  </ol>
-</div>
-</div>
-
-
-<p>The Android Developer Tools (ADT) plugin for Eclipse provides a professional-grade development
-environment for building Android apps. It's a full Java IDE with advanced features to help you build,
-test, debug, and package your Android apps. </p>
-
-<p>Android developers are encouraged to <a href="{@docRoot}tools/eclipse/migrate-adt.html">migrate
-to Android Studio</a> as the Eclipse ADT is no longer in active development.
-</p>
-
-<p>The Android Studio build system replaces the Apache Ant build software used with Eclipse ADT
-with an Android plugin for <em>Gradle</em>. <a href="http://www.gradle.org/">Gradle</a> is an
-advanced build toolkit that manages dependencies and allows you to define custom build logic. Android
-Studio also adds support for Maven-based build dependencies, build variants, advanced code
-completion and refactoring. For more details about Android Studio, see the
-<a href="{@docRoot}tools/studio/index.html">Android Studio</a> guide.
-
-<p>If you still wish to get started with the ADT plugin,
-<a href="{@docRoot}tools/eclipse/installing-adt.html">download and install the Eclipse ADT plugin.</a>
-</p>
-
-</div>
-</div>
diff --git a/docs/html/tools/help/adt.jd b/docs/html/tools/help/adt.jd
index 1bb3015..0130524 100644
--- a/docs/html/tools/help/adt.jd
+++ b/docs/html/tools/help/adt.jd
@@ -24,63 +24,30 @@
         </li>
 
         <li><a href="#refactoring">Layout Factoring Support</a></li>
-        <li><a href="#Updating">Updating the ADT Plugin</h2>
+        <li><a href="#Updating">Updating the ADT Plugin</a></li>
 
       </ol>
-
-      <h2>Related videos</h2>
-
-      <ol>
-        <li><a href="{@docRoot}videos/index.html#v=Oq05KqjXTvs">Android Developer Tools
-            Google I/O Session</a>
-        </li>
-      </ol>
-
-      <h2>See also</h2>
-
-      <ol>
-        <li><a href="http://tools.android.com/recent">Android Tools change blog</a></li>
-      </ol>
     </div>
   </div>
 
   <p>ADT (Android Developer Tools) is a plugin for Eclipse that provides a suite of
   tools that are integrated with the Eclipse IDE. It offers you access to many features that help
-  you develop Android applications quickly. ADT
+  you develop Android applications. ADT
   provides GUI access to many of the command line SDK tools as well as a UI design tool for rapid
   prototyping, designing, and building of your application's user interface.</p>
 
-  <p>Because ADT is a plugin for Eclipse, you get the functionality of a well-established IDE,
-  along with Android-specific features that are bundled with ADT. The following
-  describes important features of Eclipse and ADT:</p>
+<p class="note"><strong>Note:</strong>
+If you have been using Eclipse with ADT, be aware that <a
+href="{@docRoot}tools/studio/index.html">Android Studio</a> is now the official IDE
+for Android, so you should migrate to Android Studio to receive all the
+latest IDE updates. For help moving projects,
+see <a href="/sdk/installing/migrate.html">Migrating to Android
+Studio</a>.</p>
 
-  <dl>
-    <dt><strong>Integrated Android project creation, building, packaging, installation, and
-    debugging</strong></dt>
+<p>If you still wish to use the ADT plugin for Eclipse, see
+<a href="{@docRoot}sdk/installing/installing-adt.html">Installing Eclipse Plugin.</a>
+</p>
 
-    <dd>ADT integrates many development workflow tasks into Eclipse, making it easy for you to
-    rapidly develop and test your Android applications.</dd>
-
-    <dt><strong>SDK Tools integration</strong></dt>
-
-    <dd>Many of the <a href="#tools">SDK tools</a> are integrated into Eclipse's menus,
-    perspectives, or as a part of background processes ran by ADT.</dd>
-
-    <dt><strong>Java programming language and XML editors</strong></dt>
-
-    <dd>The Java programming language editor contains common IDE features such as compile time
-    syntax checking, auto-completion, and integrated documentation for the Android framework APIs.
-    ADT also provides custom XML editors that let you
-    edit Android-specific XML files in a form-based UI. A graphical layout editor lets you design
-    user interfaces with a drag and drop interface.</dd>
-
-    <dt><strong>Integrated documentation for Android framework APIs</strong></dt>
-    <dd>You can access documentation by hovering over classes, methods, or variables.</dd>
-  </dl>
-
-  <p>You can find the most up-to-date and more detailed information about changes and new features
-on the <a  href="http://tools.android.com/recent">Recent Changes</a> page at the Android  Tools
-Project site.</p>
 
   <h2 id="tools">SDK Tools Integration</h2>
 
@@ -568,5 +535,6 @@
 
 
 <p>If you encounter problems during the update, remove the existing ADT plugin from Eclipse, then
-perform a fresh installation, using the instructions for <a href="#installing">Installing the ADT
+perform a fresh installation, using the instructions for <a
+href="{@docRoot}sdk/installing/installing-adt.html">Installing the ADT
 Plugin</a>.</p>
diff --git a/docs/html/tools/revisions/build-tools.jd b/docs/html/tools/revisions/build-tools.jd
index 4afdf13..593770a 100644
--- a/docs/html/tools/revisions/build-tools.jd
+++ b/docs/html/tools/revisions/build-tools.jd
@@ -1,4 +1,5 @@
-page.title=Build Tools
+page.title=SDK Build Tools Release Notes
+
 @jd:body
 
 <div id="qv-wrapper">
diff --git a/docs/html/tools/revisions/platforms.jd b/docs/html/tools/revisions/platforms.jd
index ef8575a..75b3cef 100644
--- a/docs/html/tools/revisions/platforms.jd
+++ b/docs/html/tools/revisions/platforms.jd
@@ -1,4 +1,5 @@
-page.title=Platforms
+page.title=SDK Platforms Release Notes
+
 @jd:body
 
 <div id="qv-wrapper">
@@ -20,10 +21,16 @@
 
 
 
-<p>This document provides information about Android platform releases. In order to compile your
-application against a particular platform release, you must download and install the SDK Platform
-for that release. If you want to test your application on an emulator, you must also download at
-least one system image for that platform release.</p>
+<p>This document provides release information about the SDK Platform packages required
+for app development. If you want details about the features and APIs added in each Android
+version, instead read the highlights in the <a href="{@docRoot}about/index.html">About</a>
+section.</p>
+
+<p>In order to compile your application against a particular version of Android, you must use the
+<a href="{@docRoot}tools/help/sdk-manager.html">SDK Manager</a> to download and install the SDK
+Platform for that release. If you want to test your application on an emulator, you must also
+download at least one System Image for that Android version.</p>
+
 
 <p>Each platform release includes system images that support a specific processor architecture,
 such as ARM EABI, Intel x86 or MIPS. Platform releases also include a system image that contains
@@ -44,7 +51,7 @@
 <p class="caution"><strong>Important:</strong> To download the most recent Android
 system components from the Android SDK Manager, you must first update the SDK Tools to the
 most recent release and restart the SDK Manager. If you do not, the latest Android system
-components will not be available for download.</p>
+packages may not be available for download.</p>
 
 
 <h2 id="5.0">Android 5.0</h2>
@@ -58,6 +65,8 @@
   <div class="toggle-content-toggleme">
 
     <p>Initial release for Android 5.0 (API level 21).</p>
+    <p>Also see the
+    <a href="{@docRoot}about/versions/android-5.0.html">Android 5.0 APIs overview</a>.</p>
     <p>Dependencies:</p>
     <ul>
       <li>Android SDK Platform-tools r21 or higher is required.</li>
@@ -82,7 +91,7 @@
 
 <div class="toggle-content open">
   <p><a href="#" onclick="return toggleContent(this)">
-    <img src="{@docRoot}assets/images/triangle-open.png"
+    <img src="{@docRoot}assets/images/triangle-closed.png"
 class="toggle-content-img" alt="" />Revision 2</a> <em>(October 2014)</em>
   </p>
 
@@ -135,6 +144,8 @@
   <div class="toggle-content-toggleme">
 
     <p>Maintenance release. The system version is 4.4.2.</p>
+    <p>Also see the
+    <a href="{@docRoot}about/versions/android-4.4.html">Android 4.4 APIs overview</a>.</p>
     <dl>
       <dt>Dependencies:</dt>
       <dd>Android SDK Platform-tools r19 or higher is required.</dd>
@@ -153,6 +164,8 @@
   <div class="toggle-content-toggleme">
 
     <p>Initial release. The system version is 4.4.</p>
+    <p>Also see the
+    <a href="{@docRoot}about/versions/android-4.4.html">Android 4.4 APIs overview</a>.</p>
     <dl>
       <dt>Dependencies:</dt>
       <dd>Android SDK Platform-tools r19 or higher is required.</dd>
diff --git a/docs/html/tools/revisions/studio.jd b/docs/html/tools/revisions/studio.jd
index 523929d..422beaa 100644
--- a/docs/html/tools/revisions/studio.jd
+++ b/docs/html/tools/revisions/studio.jd
@@ -1,4 +1,4 @@
-page.title=Android Studio Revisions
+page.title=Android Studio Release Notes
 
 @jd:body
 
@@ -26,7 +26,7 @@
 <li>A version of the Android system image for the emulator</li>
 </ul>
 
-<p>For an introduction to Android Studio, make sure to read the
+<p>For an introduction to Android Studio, read the
 <a href="{@docRoot}tools/studio/index.html">Android Studio</a> guide.</p>
 
 <p>Periodic updates are pushed to Android Studio without requiring you to update from here. To
diff --git a/docs/html/tools/sdk/eclipse-adt.jd b/docs/html/tools/sdk/eclipse-adt.jd
index deafed5..c3a4dea 100644
--- a/docs/html/tools/sdk/eclipse-adt.jd
+++ b/docs/html/tools/sdk/eclipse-adt.jd
@@ -1,4 +1,4 @@
-page.title=ADT Plugin
+page.title=ADT Plugin Release Notes
 
 @jd:body
 
@@ -15,29 +15,25 @@
 </div>
 
 <p>Android Development Tools (ADT) is a plugin for the Eclipse IDE
-that is designed to give you a powerful, integrated environment in which
-to build Android applications.</p>
-
-<p>ADT extends the capabilities of Eclipse to let you quickly set up new Android
+that extends the capabilities of Eclipse to let you quickly set up new Android
 projects, create an application UI, add packages based on the Android
 Framework API, debug your applications using the Android SDK tools, and even
 export signed (or unsigned) {@code .apk} files in order to distribute your application.</p>
 
-<p>Developing in Eclipse with ADT is highly recommended and is the fastest way
-to get started. With the guided project setup it provides, as well as tools
-integration, custom XML editors, and debug output pane, ADT gives you an
-incredible boost in developing Android applications. </p>
+<p class="note"><strong>Note:</strong>
+If you have been using Eclipse with ADT, be aware that <a
+href="{@docRoot}tools/studio/index.html">Android Studio</a> is now the official IDE
+for Android, so you should migrate to Android Studio to receive all the
+latest IDE updates. For help moving projects,
+see <a href="/sdk/installing/migrate.html">Migrating to Android
+Studio</a>.</p>
 
-<p>This document provides step-by-step instructions on how to download the ADT
-plugin and install it into your Eclipse development environment. Note that
+<p>Note that
 before you can install or use ADT, you must have compatible versions of both the
 Eclipse IDE and the Android SDK installed. For details, make sure to read <a
 href="{@docRoot}sdk/installing/installing-adt.html">Installing the Eclipse
 Plugin</a>. </p>
 
-<p>If you are already using ADT, this document also provides instructions on
-how to update ADT to the latest version or how to uninstall it, if necessary.
-</p>
 
 <p>For information about the features provided by the ADT plugin, such as code
 editor features, SDK tool integration, and the graphical layout editor (for drag-and-drop layout
diff --git a/docs/html/tools/sdk/tools-notes.jd b/docs/html/tools/sdk/tools-notes.jd
index 6b3a0a9..80edb4f 100644
--- a/docs/html/tools/sdk/tools-notes.jd
+++ b/docs/html/tools/sdk/tools-notes.jd
@@ -1,19 +1,15 @@
-page.title=SDK Tools
+page.title=SDK Tools Release Notes
 excludeFromSuggestions=true
 @jd:body
 
 <p>SDK Tools is a downloadable component for the Android SDK. It includes the
-complete set of development and debugging tools for the Android SDK.</p>
-
-<p>If you are new to the Android SDK, the <a
-href="{@docRoot}sdk/index.html">SDK starter package</a> installs the
-latest revision of the SDK Tools in the <code>&lt;sdk&gt;/tools</code> directory.</p>
+complete set of development and debugging tools for the Android SDK. It is included
+with <a href="{@docRoot}tools/studio/index.html">Android Studio</a>.</p>
 
 <p>If you are already using the SDK and you want to update to the latest version
-of the SDK Tools, use the <em>Android SDK Manager</em> to get the
-update, rather than downloading a new SDK starter package. For more information
-about how to update, see <a
-href="{@docRoot}tools/help/sdk-manager.html">SDK Manager</a>.</p>
+of the SDK Tools, use the <a
+href="{@docRoot}tools/help/sdk-manager.html">SDK Manager</a> to get the
+update.</p>
 
 
 <h2 id="notes">Revisions</h2>
diff --git a/docs/html/tools/studio/index.jd b/docs/html/tools/studio/index.jd
index 1b9dd18..20c41e0 100644
--- a/docs/html/tools/studio/index.jd
+++ b/docs/html/tools/studio/index.jd
@@ -44,7 +44,7 @@
   <li>And much more</li>
 </ul>
 
-<p><b><a href="{@docRoot}tools/sdk/index.html">Download Android Studio now</a></b>. </p>
+<p><b><a href="{@docRoot}sdk/index.html">Download Android Studio now</a></b>. </p>
 
 <p>If you're new to Android Studio or the IntelliJ IDEA interface, this
 page provides an introduction to some key Android
@@ -102,9 +102,8 @@
 
 
 <h3>New Project and Directory Structure</h3>
-<p>When you use the <em>Project</em> view of a new project in Android Studio or
-(<a href="{@docRoot}tools/eclipse/migrate-adt.html"> a project migrated from Eclipse</a>), you
-should notice that the project structure appears different than you may be used to. Each
+<p>When you use the <em>Project</em> view of a new project in Android Studio, you
+should notice that the project structure appears different than you may be used to in Eclipse. Each
 instance of Android Studio contains a project with one or more application modules. Each
 application module folder contains the complete source sets for that module, including
 {@code src/main} and {@code src/androidTest} directories, resources, build
diff --git a/docs/html/tools/tools_toc.cs b/docs/html/tools/tools_toc.cs
index a8c588a..cb6a1de 100644
--- a/docs/html/tools/tools_toc.cs
+++ b/docs/html/tools/tools_toc.cs
@@ -159,13 +159,6 @@
 class="en">Tools Help</span></a></div>
     <ul>
       <li><a href="<?cs var:toroot ?>tools/help/adb.html">adb</a></li>
-      <li class="nav-section">
-        <div class="nav-section-header"><a href="<?cs var:toroot ?>tools/help/adt.html">ADT</a></div>
-        <ul>
-          <li><a href="<?cs var:toroot ?>sdk/installing/installing-adt.html">
-              <span class="en">Installing the Eclipse Plugin</span></a></li>
-        </ul>
-      </li>
       <li><a href="<?cs var:toroot ?>tools/help/android.html">android</a></li>
       <li><a href="<?cs var:toroot ?>tools/help/avd-manager.html">AVD Manager</a></li>
       <li><a href="<?cs var:toroot ?>tools/help/bmgr.html">bmgr</a>
@@ -262,10 +255,10 @@
         <span class="en">SDK Tools</span>
       </a></li>
       <li><a href="<?cs var:toroot ?>tools/revisions/build-tools.html">
-        <span class="en">Build Tools</span>
+        <span class="en">SDK Build Tools</span>
       </a></li>
       <li><a href="<?cs var:toroot ?>tools/revisions/platforms.html">
-        <span class="en">Platforms</span></a></li>
+        <span class="en">SDK Platforms</span></a></li>
       <li><a href="<?cs var:toroot ?>tools/sdk/eclipse-adt.html">
         <span class="en">ADT Plugin</span></a></li>
     </ul>
@@ -293,11 +286,13 @@
 
   <li class="nav-section">
     <div class="nav-section-header">
-    <a href="<?cs var:toroot ?>tools/eclipse/index.html">
+    <a href="<?cs var:toroot ?>tools/help/adt.html">
       <span class="en">Eclipse with ADT</span></a>
     </div>
     <ul>
     <li><a href="<?cs var:toroot ?>sdk/installing/migrate.html">Migrating to Android Studio</a></li>
+    <li><a href="<?cs var:toroot ?>sdk/installing/installing-adt.html">
+        <span class="en">Installing the Eclipse Plugin</span></a></li>
     <li><a href="<?cs var:toroot ?>tools/projects/projects-eclipse.html">Managing Projects</a></li>
     <li><a href="<?cs var:toroot ?>tools/building/building-eclipse.html">Building and Running</a></li>
     <li><a href="<?cs var:toroot ?>tools/building/building-cmdline-ant.html">Building with Ant</a></li>
diff --git a/libs/hwui/ResourceCache.cpp b/libs/hwui/ResourceCache.cpp
index 717ce9a..31bd637 100644
--- a/libs/hwui/ResourceCache.cpp
+++ b/libs/hwui/ResourceCache.cpp
@@ -68,8 +68,6 @@
 }
 
 void ResourceCache::incrementRefcount(const SkBitmap* bitmapResource) {
-    bitmapResource->pixelRef()->globalRef();
-    SkSafeRef(bitmapResource->getColorTable());
     incrementRefcount((void*) bitmapResource, kBitmap);
 }
 
@@ -92,8 +90,6 @@
 }
 
 void ResourceCache::incrementRefcountLocked(const SkBitmap* bitmapResource) {
-    bitmapResource->pixelRef()->globalRef();
-    SkSafeRef(bitmapResource->getColorTable());
     incrementRefcountLocked((void*) bitmapResource, kBitmap);
 }
 
@@ -111,8 +107,6 @@
 }
 
 void ResourceCache::decrementRefcount(const SkBitmap* bitmapResource) {
-    bitmapResource->pixelRef()->globalUnref();
-    SkSafeUnref(bitmapResource->getColorTable());
     decrementRefcount((void*) bitmapResource);
 }
 
@@ -138,8 +132,6 @@
 }
 
 void ResourceCache::decrementRefcountLocked(const SkBitmap* bitmapResource) {
-    bitmapResource->pixelRef()->globalUnref();
-    SkSafeUnref(bitmapResource->getColorTable());
     decrementRefcountLocked((void*) bitmapResource);
 }
 
diff --git a/media/java/android/media/ImageReader.java b/media/java/android/media/ImageReader.java
index 400c082..8d6a588 100644
--- a/media/java/android/media/ImageReader.java
+++ b/media/java/android/media/ImageReader.java
@@ -578,7 +578,11 @@
         @Override
         public int getWidth() {
             if (mIsImageValid) {
-                return ImageReader.this.mWidth;
+                if (mWidth == -1) {
+                    mWidth = (getFormat() == ImageFormat.JPEG) ? ImageReader.this.getWidth() :
+                            nativeGetWidth();
+                }
+                return mWidth;
             } else {
                 throw new IllegalStateException("Image is already released");
             }
@@ -587,7 +591,11 @@
         @Override
         public int getHeight() {
             if (mIsImageValid) {
-                return ImageReader.this.mHeight;
+                if (mHeight == -1) {
+                    mHeight = (getFormat() == ImageFormat.JPEG) ? ImageReader.this.getHeight() :
+                            nativeGetHeight();
+                }
+                return mHeight;
             } else {
                 throw new IllegalStateException("Image is already released");
             }
@@ -721,9 +729,13 @@
 
         private SurfacePlane[] mPlanes;
         private boolean mIsImageValid;
+        private int mHeight = -1;
+        private int mWidth = -1;
 
         private synchronized native ByteBuffer nativeImageGetBuffer(int idx, int readerFormat);
         private synchronized native SurfacePlane nativeCreatePlane(int idx, int readerFormat);
+        private synchronized native int nativeGetWidth();
+        private synchronized native int nativeGetHeight();
     }
 
     private synchronized native void nativeInit(Object weakSelf, int w, int h,
diff --git a/media/jni/android_media_ImageReader.cpp b/media/jni/android_media_ImageReader.cpp
index 7830c80..3f4736d 100644
--- a/media/jni/android_media_ImageReader.cpp
+++ b/media/jni/android_media_ImageReader.cpp
@@ -615,6 +615,24 @@
     return rowStride;
 }
 
+static int Image_getBufferWidth(CpuConsumer::LockedBuffer* buffer) {
+    if (buffer == NULL) return -1;
+
+    if (!buffer->crop.isEmpty()) {
+        return buffer->crop.getWidth();
+    }
+    return buffer->width;
+}
+
+static int Image_getBufferHeight(CpuConsumer::LockedBuffer* buffer) {
+    if (buffer == NULL) return -1;
+
+    if (!buffer->crop.isEmpty()) {
+        return buffer->crop.getHeight();
+    }
+    return buffer->height;
+}
+
 // ----------------------------------------------------------------------------
 
 static void ImageReader_classInit(JNIEnv* env, jclass clazz)
@@ -795,33 +813,16 @@
     }
 
     // Check if the producer buffer configurations match what ImageReader configured.
-    // We want to fail for the very first image because this case is too bad.
-    int outputWidth = buffer->width;
-    int outputHeight = buffer->height;
-
-    // Correct width/height when crop is set.
-    if (!buffer->crop.isEmpty()) {
-        outputWidth = buffer->crop.getWidth();
-        outputHeight = buffer->crop.getHeight();
-    }
+    int outputWidth = Image_getBufferWidth(buffer);
+    int outputHeight = Image_getBufferHeight(buffer);
 
     int imgReaderFmt = ctx->getBufferFormat();
     int imageReaderWidth = ctx->getBufferWidth();
     int imageReaderHeight = ctx->getBufferHeight();
     if ((buffer->format != HAL_PIXEL_FORMAT_BLOB) && (imgReaderFmt != HAL_PIXEL_FORMAT_BLOB) &&
-            (imageReaderWidth != outputWidth || imageReaderHeight > outputHeight)) {
-        /**
-         * For video decoder, the buffer height is actually the vertical stride,
-         * which is always >= actual image height. For future, decoder need provide
-         * right crop rectangle to CpuConsumer to indicate the actual image height,
-         * see bug 9563986. After this bug is fixed, we can enforce the height equal
-         * check. Right now, only make sure buffer height is no less than ImageReader
-         * height.
-         */
-        jniThrowExceptionFmt(env, "java/lang/IllegalStateException",
-                "Producer buffer size: %dx%d, doesn't match ImageReader configured size: %dx%d",
-                outputWidth, outputHeight, imageReaderWidth, imageReaderHeight);
-        return -1;
+            (imageReaderWidth != outputWidth || imageReaderHeight != outputHeight)) {
+        ALOGV("%s: Producer buffer size: %dx%d, doesn't match ImageReader configured size: %dx%d",
+                __FUNCTION__, outputWidth, outputHeight, imageReaderWidth, imageReaderHeight);
     }
 
     int bufFmt = buffer->format;
@@ -934,6 +935,19 @@
     return byteBuffer;
 }
 
+static jint Image_getWidth(JNIEnv* env, jobject thiz)
+{
+    CpuConsumer::LockedBuffer* buffer = Image_getLockedBuffer(env, thiz);
+    return Image_getBufferWidth(buffer);
+}
+
+static jint Image_getHeight(JNIEnv* env, jobject thiz)
+{
+    CpuConsumer::LockedBuffer* buffer = Image_getLockedBuffer(env, thiz);
+    return Image_getBufferHeight(buffer);
+}
+
+
 } // extern "C"
 
 // ----------------------------------------------------------------------------
@@ -943,14 +957,16 @@
     {"nativeInit",             "(Ljava/lang/Object;IIII)V",  (void*)ImageReader_init },
     {"nativeClose",            "()V",                        (void*)ImageReader_close },
     {"nativeReleaseImage",     "(Landroid/media/Image;)V",   (void*)ImageReader_imageRelease },
-    {"nativeImageSetup",       "(Landroid/media/Image;)I",    (void*)ImageReader_imageSetup },
+    {"nativeImageSetup",       "(Landroid/media/Image;)I",   (void*)ImageReader_imageSetup },
     {"nativeGetSurface",       "()Landroid/view/Surface;",   (void*)ImageReader_getSurface },
 };
 
 static JNINativeMethod gImageMethods[] = {
     {"nativeImageGetBuffer",   "(II)Ljava/nio/ByteBuffer;",   (void*)Image_getByteBuffer },
     {"nativeCreatePlane",      "(II)Landroid/media/ImageReader$SurfaceImage$SurfacePlane;",
-                                                             (void*)Image_createSurfacePlane },
+                                                              (void*)Image_createSurfacePlane },
+    {"nativeGetWidth",         "()I",                         (void*)Image_getWidth },
+    {"nativeGetHeight",        "()I",                         (void*)Image_getHeight },
 };
 
 int register_android_media_ImageReader(JNIEnv *env) {
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPinBasedInputView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPinBasedInputView.java
index bca0305..7c56e84 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardPinBasedInputView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPinBasedInputView.java
@@ -17,7 +17,11 @@
 package com.android.keyguard;
 
 import android.content.Context;
+import android.database.ContentObserver;
 import android.graphics.Rect;
+import android.os.Handler;
+import android.os.UserHandle;
+import android.provider.Settings;
 import android.util.AttributeSet;
 import android.view.KeyEvent;
 import android.view.View;
@@ -28,19 +32,39 @@
 public abstract class KeyguardPinBasedInputView extends KeyguardAbsKeyInputView
         implements View.OnKeyListener {
 
+    private final android.database.ContentObserver mSpeakPasswordObserver
+            = new ContentObserver(new Handler()) {
+        @Override
+        public void onChange(boolean selfChange) {
+            super.onChange(selfChange);
+            // Ensure that it's not called too early
+            if (mButton0 != null) {
+                mButton0.updateContentDescription();
+                mButton1.updateContentDescription();
+                mButton2.updateContentDescription();
+                mButton3.updateContentDescription();
+                mButton4.updateContentDescription();
+                mButton5.updateContentDescription();
+                mButton6.updateContentDescription();
+                mButton7.updateContentDescription();
+                mButton8.updateContentDescription();
+                mButton9.updateContentDescription();
+            }
+        }
+    };
     protected PasswordTextView mPasswordEntry;
     private View mOkButton;
     private View mDeleteButton;
-    private View mButton0;
-    private View mButton1;
-    private View mButton2;
-    private View mButton3;
-    private View mButton4;
-    private View mButton5;
-    private View mButton6;
-    private View mButton7;
-    private View mButton8;
-    private View mButton9;
+    private NumPadKey mButton0;
+    private NumPadKey mButton1;
+    private NumPadKey mButton2;
+    private NumPadKey mButton3;
+    private NumPadKey mButton4;
+    private NumPadKey mButton5;
+    private NumPadKey mButton6;
+    private NumPadKey mButton7;
+    private NumPadKey mButton8;
+    private NumPadKey mButton9;
 
     public KeyguardPinBasedInputView(Context context) {
         this(context, null);
@@ -48,6 +72,9 @@
 
     public KeyguardPinBasedInputView(Context context, AttributeSet attrs) {
         super(context, attrs);
+        context.getContentResolver().registerContentObserver(
+                Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD), true,
+                mSpeakPasswordObserver, UserHandle.USER_ALL);
     }
 
     @Override
@@ -188,16 +215,16 @@
             }
         });
 
-        mButton0 = findViewById(R.id.key0);
-        mButton1 = findViewById(R.id.key1);
-        mButton2 = findViewById(R.id.key2);
-        mButton3 = findViewById(R.id.key3);
-        mButton4 = findViewById(R.id.key4);
-        mButton5 = findViewById(R.id.key5);
-        mButton6 = findViewById(R.id.key6);
-        mButton7 = findViewById(R.id.key7);
-        mButton8 = findViewById(R.id.key8);
-        mButton9 = findViewById(R.id.key9);
+        mButton0 = (NumPadKey) findViewById(R.id.key0);
+        mButton1 = (NumPadKey) findViewById(R.id.key1);
+        mButton2 = (NumPadKey) findViewById(R.id.key2);
+        mButton3 = (NumPadKey) findViewById(R.id.key3);
+        mButton4 = (NumPadKey) findViewById(R.id.key4);
+        mButton5 = (NumPadKey) findViewById(R.id.key5);
+        mButton6 = (NumPadKey) findViewById(R.id.key6);
+        mButton7 = (NumPadKey) findViewById(R.id.key7);
+        mButton8 = (NumPadKey) findViewById(R.id.key8);
+        mButton9 = (NumPadKey) findViewById(R.id.key9);
 
         mPasswordEntry.requestFocus();
         super.onFinishInflate();
diff --git a/packages/Keyguard/src/com/android/keyguard/NumPadKey.java b/packages/Keyguard/src/com/android/keyguard/NumPadKey.java
index d539856..70a4108 100644
--- a/packages/Keyguard/src/com/android/keyguard/NumPadKey.java
+++ b/packages/Keyguard/src/com/android/keyguard/NumPadKey.java
@@ -22,6 +22,8 @@
 import android.os.Debug;
 import android.os.PowerManager;
 import android.os.SystemClock;
+import android.os.UserHandle;
+import android.provider.Settings;
 import android.util.AttributeSet;
 import android.view.HapticFeedbackConstants;
 import android.view.KeyEvent;
@@ -118,7 +120,17 @@
         }
 
         setBackground(mContext.getDrawable(R.drawable.ripple_drawable));
-        setContentDescription(mDigitText.getText().toString() + mKlondikeText.getText().toString());
+        updateContentDescription();
+    }
+
+    public void updateContentDescription() {
+        if (shouldSpeakPasswordsForAccessibility()) {
+            setContentDescription(
+                    mDigitText.getText().toString() + mKlondikeText.getText().toString());
+        } else {
+            setContentDescription(getContext().getString(
+                    com.android.internal.R.string.keyboard_password_character_no_headset));
+        }
     }
 
     @Override
@@ -152,6 +164,15 @@
         mKlondikeText.layout(left, top, left + mKlondikeText.getMeasuredWidth(), bottom);
     }
 
+    /**
+     * @return true if the user has explicitly allowed accessibility services
+     * to speak passwords.
+     */
+    private boolean shouldSpeakPasswordsForAccessibility() {
+        return (Settings.Secure.getIntForUser(mContext.getContentResolver(),
+                Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD, 0, UserHandle.USER_CURRENT) == 1);
+    }
+
     @Override
     public boolean hasOverlappingRendering() {
         return false;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index e7a0432..3397a38 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -483,6 +483,10 @@
                 cachedControllers.get(key).unregisterListener();
             }
         }
+        // There may be new MobileSignalControllers around, make sure they get the current
+        // inet condition and airplane mode.
+        pushConnectivityToSignals();
+        updateAirplaneMode(true /* force */);
     }
 
     private boolean hasCorrectMobileControllers(List<SubscriptionInfo> allSubscriptions) {
@@ -577,6 +581,13 @@
         mBluetoothTethered = mConnectedTransports.get(TRANSPORT_BLUETOOTH);
         mEthernetConnected = mConnectedTransports.get(TRANSPORT_ETHERNET);
 
+        pushConnectivityToSignals();
+    }
+
+    /**
+     * Pushes the current connectivity state to all SignalControllers.
+     */
+    private void pushConnectivityToSignals() {
         // We want to update all the icons, all at once, for any condition change
         for (MobileSignalController mobileSignalController : mMobileSignalControllers.values()) {
             mobileSignalController.setInetCondition(
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index ba89f23..021a6e4 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -617,8 +617,8 @@
 
         mOverscanInsets.set(Math.max(mOverscanFrame.left - mFrame.left, 0),
                 Math.max(mOverscanFrame.top - mFrame.top, 0),
-                Math.min(mFrame.right - mOverscanFrame.right, 0),
-                Math.min(mFrame.bottom - mOverscanFrame.bottom, 0));
+                Math.max(mFrame.right - mOverscanFrame.right, 0),
+                Math.max(mFrame.bottom - mOverscanFrame.bottom, 0));
 
         mContentInsets.set(mContentFrame.left - mFrame.left,
                 mContentFrame.top - mFrame.top,
diff --git a/telephony/java/com/android/ims/internal/IImsConfig.aidl b/telephony/java/com/android/ims/internal/IImsConfig.aidl
index c5ccf5f..c17637c 100644
--- a/telephony/java/com/android/ims/internal/IImsConfig.aidl
+++ b/telephony/java/com/android/ims/internal/IImsConfig.aidl
@@ -49,22 +49,22 @@
  */
 interface IImsConfig {
     /**
-     * Gets the value for ims service/capabilities parameters from the master
+     * Gets the value for ims service/capabilities parameters from the provisioned
      * value storage. Synchronous blocking call.
      *
      * @param item, as defined in com.android.ims.ImsConfig#ConfigConstants.
      * @return value in Integer format.
      */
-    int getMasterValue(int item);
+    int getProvisionedValue(int item);
 
     /**
-     * Gets the value for ims service/capabilities parameters from the master
+     * Gets the value for ims service/capabilities parameters from the provisioned
      * value storage. Synchronous blocking call.
      *
      * @param item, as defined in com.android.ims.ImsConfig#ConfigConstants.
      * @return value in String format.
      */
-    String getMasterStringValue(int item);
+    String getProvisionedStringValue(int item);
 
     /**
      * Sets the value for IMS service/capabilities parameters by the operator device
@@ -112,4 +112,12 @@
      * @return void
      */
     oneway void setFeatureValue(int feature, int network, int value, ImsConfigListener listener);
+
+    /**
+     * Gets the value for IMS volte provisioned.
+     * This should be the same as the operator provisioned value if applies.
+     *
+     * @return void
+     */
+    boolean getVolteProvisioned();
 }
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/RevealActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/RevealActivity.java
index 256a1d4..1216fc4 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/RevealActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/RevealActivity.java
@@ -17,12 +17,14 @@
 package com.android.test.hwui;
 
 import android.animation.Animator;
+import android.animation.Animator.AnimatorListener;
 import android.animation.AnimatorSet;
 import android.app.Activity;
 import android.content.Context;
 import android.graphics.Canvas;
 import android.graphics.Color;
 import android.os.Bundle;
+import android.util.Log;
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.view.ViewAnimationUtils;
@@ -37,6 +39,29 @@
     private boolean mShouldBlock;
     private int mIteration = 0;
 
+    private AnimatorListener mListener = new AnimatorListener() {
+
+        @Override
+        public void onAnimationStart(Animator animation) {
+            Log.d("Reveal", "onAnimatorStart " + animation);
+        }
+
+        @Override
+        public void onAnimationRepeat(Animator animation) {
+            Log.d("Reveal", "onAnimationRepeat " + animation);
+        }
+
+        @Override
+        public void onAnimationEnd(Animator animation) {
+            Log.d("Reveal", "onAnimationEnd " + animation);
+        }
+
+        @Override
+        public void onAnimationCancel(Animator animation) {
+            Log.d("Reveal", "onAnimationCancel " + animation);
+        }
+    };
+
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -59,6 +84,8 @@
         Animator animator = ViewAnimationUtils.createCircularReveal(view,
                 view.getWidth() / 2, view.getHeight() / 2,
                 0, Math.max(view.getWidth(), view.getHeight()));
+        Log.d("Reveal", "Calling start...");
+        animator.addListener(mListener);
         if (mIteration < 2) {
             animator.setDuration(DURATION);
             animator.start();
@@ -66,6 +93,7 @@
             AnimatorSet set = new AnimatorSet();
             set.playTogether(animator);
             set.setDuration(DURATION);
+            set.addListener(mListener);
             set.start();
         }