Merge "Fixing issue with old thumbnails on first launch of app. (Bug 18718114)" into lmp-mr1-dev
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 6b4db10..bcd8fb4 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -44,7 +44,10 @@
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.hardware.display.DisplayManagerGlobal;
+import android.net.ConnectivityManager;
 import android.net.IConnectivityManager;
+import android.net.LinkProperties;
+import android.net.Network;
 import android.net.Proxy;
 import android.net.ProxyInfo;
 import android.net.Uri;
@@ -839,7 +842,13 @@
         }
 
         public void setHttpProxy(String host, String port, String exclList, Uri pacFileUrl) {
-            Proxy.setHttpProxySystemProperty(host, port, exclList, pacFileUrl);
+            final Network network = ConnectivityManager.getProcessDefaultNetwork();
+            if (network != null) {
+                Proxy.setHttpProxySystemProperty(
+                        ConnectivityManager.from(getSystemContext()).getDefaultProxy());
+            } else {
+                Proxy.setHttpProxySystemProperty(host, port, exclList, pacFileUrl);
+            }
         }
 
         public void processInBackground() {
@@ -4430,7 +4439,7 @@
             // crash if we can't get it.
             IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
             try {
-                ProxyInfo proxyInfo = service.getProxy();
+                final ProxyInfo proxyInfo = service.getDefaultProxy();
                 Proxy.setHttpProxySystemProperty(proxyInfo);
             } catch (RemoteException e) {}
         }
diff --git a/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java b/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java
index 4853b81..a0a0716 100644
--- a/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java
+++ b/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java
@@ -58,6 +58,11 @@
     private static final int GLES_VERSION = 2;
     private static final int PBUFFER_PIXEL_BYTES = 4;
 
+    private static final int FLIP_TYPE_NONE = 0;
+    private static final int FLIP_TYPE_HORIZONTAL = 1;
+    private static final int FLIP_TYPE_VERTICAL = 2;
+    private static final int FLIP_TYPE_BOTH = FLIP_TYPE_HORIZONTAL | FLIP_TYPE_VERTICAL;
+
     private EGLDisplay mEGLDisplay = EGL14.EGL_NO_DISPLAY;
     private EGLContext mEGLContext = EGL14.EGL_NO_CONTEXT;
     private EGLConfig mConfigs;
@@ -82,8 +87,8 @@
     private static final int TRIANGLE_VERTICES_DATA_POS_OFFSET = 0;
     private static final int TRIANGLE_VERTICES_DATA_UV_OFFSET = 3;
 
-    // Sampling is mirrored across the vertical axis to undo horizontal flip from the front camera
-    private static final float[] sFrontCameraTriangleVertices = {
+    // Sampling is mirrored across the horizontal axis
+    private static final float[] sHorizontalFlipTriangleVertices = {
             // X, Y, Z, U, V
             -1.0f, -1.0f, 0, 1.f, 0.f,
             1.0f, -1.0f, 0, 0.f, 0.f,
@@ -91,8 +96,26 @@
             1.0f,  1.0f, 0, 0.f, 1.f,
     };
 
+    // Sampling is mirrored across the vertical axis
+    private static final float[] sVerticalFlipTriangleVertices = {
+            // X, Y, Z, U, V
+            -1.0f, -1.0f, 0, 0.f, 1.f,
+            1.0f, -1.0f, 0, 1.f, 1.f,
+            -1.0f,  1.0f, 0, 0.f, 0.f,
+            1.0f,  1.0f, 0, 1.f, 0.f,
+    };
+
+    // Sampling is mirrored across the both axes
+    private static final float[] sBothFlipTriangleVertices = {
+            // X, Y, Z, U, V
+            -1.0f, -1.0f, 0, 1.f, 1.f,
+            1.0f, -1.0f, 0, 0.f, 1.f,
+            -1.0f,  1.0f, 0, 1.f, 0.f,
+            1.0f,  1.0f, 0, 0.f, 0.f,
+    };
+
     // Sampling is 1:1 for a straight copy for the back camera
-    private static final float[] sBackCameraTriangleVertices = {
+    private static final float[] sRegularTriangleVertices = {
             // X, Y, Z, U, V
             -1.0f, -1.0f, 0, 0.f, 0.f,
             1.0f, -1.0f, 0, 1.f, 0.f,
@@ -100,7 +123,11 @@
             1.0f,  1.0f, 0, 1.f, 1.f,
     };
 
-    private FloatBuffer mTriangleVertices;
+    private FloatBuffer mRegularTriangleVertices;
+    private FloatBuffer mHorizontalFlipTriangleVertices;
+    private FloatBuffer mVerticalFlipTriangleVertices;
+    private FloatBuffer mBothFlipTriangleVertices;
+    private final int mFacing;
 
     /**
      * As used in this file, this vertex shader maps a unit square to the view, and
@@ -148,15 +175,27 @@
     private static final String LEGACY_PERF_PROPERTY = "persist.camera.legacy_perf";
 
     public SurfaceTextureRenderer(int facing) {
-        if (facing == CameraCharacteristics.LENS_FACING_BACK) {
-            mTriangleVertices = ByteBuffer.allocateDirect(sBackCameraTriangleVertices.length *
-                    FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer();
-            mTriangleVertices.put(sBackCameraTriangleVertices).position(0);
-        } else {
-            mTriangleVertices = ByteBuffer.allocateDirect(sFrontCameraTriangleVertices.length *
-                    FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer();
-            mTriangleVertices.put(sFrontCameraTriangleVertices).position(0);
-        }
+        mFacing = facing;
+
+        mRegularTriangleVertices = ByteBuffer.allocateDirect(sRegularTriangleVertices.length *
+                FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer();
+        mRegularTriangleVertices.put(sRegularTriangleVertices).position(0);
+
+        mHorizontalFlipTriangleVertices = ByteBuffer.allocateDirect(
+                sHorizontalFlipTriangleVertices.length * FLOAT_SIZE_BYTES).
+                order(ByteOrder.nativeOrder()).asFloatBuffer();
+        mHorizontalFlipTriangleVertices.put(sHorizontalFlipTriangleVertices).position(0);
+
+        mVerticalFlipTriangleVertices = ByteBuffer.allocateDirect(
+                sVerticalFlipTriangleVertices.length * FLOAT_SIZE_BYTES).
+                order(ByteOrder.nativeOrder()).asFloatBuffer();
+        mVerticalFlipTriangleVertices.put(sVerticalFlipTriangleVertices).position(0);
+
+        mBothFlipTriangleVertices = ByteBuffer.allocateDirect(
+                sBothFlipTriangleVertices.length * FLOAT_SIZE_BYTES).
+                order(ByteOrder.nativeOrder()).asFloatBuffer();
+        mBothFlipTriangleVertices.put(sBothFlipTriangleVertices).position(0);
+
         Matrix.setIdentityM(mSTMatrix, 0);
     }
 
@@ -209,7 +248,7 @@
         return program;
     }
 
-    private void drawFrame(SurfaceTexture st, int width, int height) {
+    private void drawFrame(SurfaceTexture st, int width, int height, int flipType) {
         checkGlError("onDrawFrame start");
         st.getTransformMatrix(mSTMatrix);
 
@@ -266,16 +305,32 @@
         GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
         GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, mTextureID);
 
-        mTriangleVertices.position(TRIANGLE_VERTICES_DATA_POS_OFFSET);
+        FloatBuffer triangleVertices;
+        switch(flipType) {
+            case FLIP_TYPE_HORIZONTAL:
+                triangleVertices = mHorizontalFlipTriangleVertices;
+                break;
+            case FLIP_TYPE_VERTICAL:
+                triangleVertices = mVerticalFlipTriangleVertices;
+                break;
+            case FLIP_TYPE_BOTH:
+                triangleVertices = mBothFlipTriangleVertices;
+                break;
+            default:
+                triangleVertices = mRegularTriangleVertices;
+                break;
+        }
+
+        triangleVertices.position(TRIANGLE_VERTICES_DATA_POS_OFFSET);
         GLES20.glVertexAttribPointer(maPositionHandle, VERTEX_POS_SIZE, GLES20.GL_FLOAT,
-                /*normalized*/ false, TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices);
+                /*normalized*/ false, TRIANGLE_VERTICES_DATA_STRIDE_BYTES, triangleVertices);
         checkGlError("glVertexAttribPointer maPosition");
         GLES20.glEnableVertexAttribArray(maPositionHandle);
         checkGlError("glEnableVertexAttribArray maPositionHandle");
 
-        mTriangleVertices.position(TRIANGLE_VERTICES_DATA_UV_OFFSET);
+        triangleVertices.position(TRIANGLE_VERTICES_DATA_UV_OFFSET);
         GLES20.glVertexAttribPointer(maTextureHandle, VERTEX_UV_SIZE, GLES20.GL_FLOAT,
-                /*normalized*/ false, TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices);
+                /*normalized*/ false, TRIANGLE_VERTICES_DATA_STRIDE_BYTES, triangleVertices);
         checkGlError("glVertexAttribPointer maTextureHandle");
         GLES20.glEnableVertexAttribArray(maTextureHandle);
         checkGlError("glEnableVertexAttribArray maTextureHandle");
@@ -666,7 +721,9 @@
                     makeCurrent(holder.eglSurface);
 
                     LegacyCameraDevice.setNextTimestamp(holder.surface, captureHolder.second);
-                    drawFrame(mSurfaceTexture, holder.width, holder.height);
+                    drawFrame(mSurfaceTexture, holder.width, holder.height,
+                            (mFacing == CameraCharacteristics.LENS_FACING_FRONT) ?
+                                    FLIP_TYPE_HORIZONTAL : FLIP_TYPE_NONE);
                     swapBuffers(holder.eglSurface);
                 } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) {
                     Log.w(TAG, "Surface abandoned, dropping frame. ", e);
@@ -676,7 +733,10 @@
         for (EGLSurfaceHolder holder : mConversionSurfaces) {
             if (LegacyCameraDevice.containsSurfaceId(holder.surface, targetSurfaceIds)) {
                 makeCurrent(holder.eglSurface);
-                drawFrame(mSurfaceTexture, holder.width, holder.height);
+                // glReadPixels reads from the bottom of the buffer, so add an extra vertical flip
+                drawFrame(mSurfaceTexture, holder.width, holder.height,
+                        (mFacing == CameraCharacteristics.LENS_FACING_FRONT) ?
+                                FLIP_TYPE_BOTH : FLIP_TYPE_VERTICAL);
                 mPBufferPixels.clear();
                 GLES20.glReadPixels(/*x*/ 0, /*y*/ 0, holder.width, holder.height,
                         GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, mPBufferPixels);
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 7d5db85..17ee494 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -441,6 +441,13 @@
     public static final int NETID_UNSET = 0;
 
     private final IConnectivityManager mService;
+    /**
+     * A kludge to facilitate static access where a Context pointer isn't available, like in the
+     * case of the static set/getProcessDefaultNetwork methods and from the Network class.
+     * TODO: Remove this after deprecating the static methods in favor of non-static methods or
+     * methods that take a Context argument.
+     */
+    private static ConnectivityManager sInstance;
 
     private INetworkManagementService mNMService;
 
@@ -1392,6 +1399,7 @@
      */
     public ConnectivityManager(IConnectivityManager service) {
         mService = checkNotNull(service, "missing IConnectivityManager");
+        sInstance = this;
     }
 
     /** {@hide} */
@@ -1414,6 +1422,18 @@
     }
 
     /**
+     * @deprecated - use getSystemService. This is a kludge to support static access in certain
+     *               situations where a Context pointer is unavailable.
+     * @hide
+     */
+    public static ConnectivityManager getInstance() {
+        if (sInstance == null) {
+            throw new IllegalStateException("No ConnectivityManager yet constructed");
+        }
+        return sInstance;
+    }
+
+    /**
      * Get the set of tetherable, available interfaces.  This list is limited by
      * device configuration and current interface existence.
      *
@@ -1744,20 +1764,26 @@
     }
 
     /**
-     * Get the HTTP proxy settings for the current default network.  Note that
-     * if a global proxy is set, it will override any per-network setting.
+     * Get the current default HTTP proxy settings.  If a global proxy is set it will be returned,
+     * otherwise if this process is bound to a {@link Network} using
+     * {@link #setProcessDefaultNetwork} then that {@code Network}'s proxy is returned, otherwise
+     * the default network's proxy is returned.
      *
      * @return the {@link ProxyInfo} for the current HTTP proxy, or {@code null} if no
      *        HTTP proxy is active.
-     *
-     * <p>This method requires the call to hold the permission
-     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
-     * {@hide}
-     * @deprecated Deprecated in favor of {@link #getLinkProperties}
+     * @hide
      */
-    public ProxyInfo getProxy() {
+    public ProxyInfo getDefaultProxy() {
+        final Network network = getProcessDefaultNetwork();
+        if (network != null) {
+            final ProxyInfo globalProxy = getGlobalProxy();
+            if (globalProxy != null) return globalProxy;
+            final LinkProperties lp = getLinkProperties(network);
+            if (lp != null) return lp.getHttpProxy();
+            return null;
+        }
         try {
-            return mService.getProxy();
+            return mService.getDefaultProxy();
         } catch (RemoteException e) {
             return null;
         }
@@ -2470,6 +2496,9 @@
             return true;
         }
         if (NetworkUtils.bindProcessToNetwork(netId)) {
+            // Set HTTP proxy system properties to match network.
+            // TODO: Deprecate this static method and replace it with a non-static version.
+            Proxy.setHttpProxySystemProperty(getInstance().getDefaultProxy());
             // Must flush DNS cache as new network may have different DNS resolutions.
             InetAddress.clearDnsCache();
             // Must flush socket pool as idle sockets will be bound to previous network and may
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index d9921a6..46af112 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -100,7 +100,7 @@
 
     void setGlobalProxy(in ProxyInfo p);
 
-    ProxyInfo getProxy();
+    ProxyInfo getDefaultProxy();
 
     void setDataDependency(int networkType, boolean met);
 
diff --git a/core/java/android/net/Network.java b/core/java/android/net/Network.java
index 4fa0593..5c12696 100644
--- a/core/java/android/net/Network.java
+++ b/core/java/android/net/Network.java
@@ -27,6 +27,7 @@
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.net.MalformedURLException;
+import java.net.ProxySelector;
 import java.net.Socket;
 import java.net.SocketAddress;
 import java.net.SocketException;
@@ -244,16 +245,46 @@
      * @see java.net.URL#openConnection()
      */
     public URLConnection openConnection(URL url) throws IOException {
+        final ConnectivityManager cm = ConnectivityManager.getInstance();
+        // TODO: Should this be optimized to avoid fetching the global proxy for every request?
+        ProxyInfo proxyInfo = cm.getGlobalProxy();
+        if (proxyInfo == null) {
+            // TODO: Should this be optimized to avoid fetching LinkProperties for every request?
+            final LinkProperties lp = cm.getLinkProperties(this);
+            if (lp != null) proxyInfo = lp.getHttpProxy();
+        }
+        java.net.Proxy proxy = null;
+        if (proxyInfo != null) {
+            proxy = proxyInfo.makeProxy();
+        } else {
+            proxy = java.net.Proxy.NO_PROXY;
+        }
+        return openConnection(url, proxy);
+    }
+
+    /**
+     * Opens the specified {@link URL} on this {@code Network}, such that all traffic will be sent
+     * on this Network. The URL protocol must be {@code HTTP} or {@code HTTPS}.
+     *
+     * @param proxy the proxy through which the connection will be established.
+     * @return a {@code URLConnection} to the resource referred to by this URL.
+     * @throws MalformedURLException if the URL protocol is not HTTP or HTTPS.
+     * @throws IllegalArgumentException if the argument proxy is null.
+     * @throws IOException if an error occurs while opening the connection.
+     * @see java.net.URL#openConnection()
+     * @hide
+     */
+    public URLConnection openConnection(URL url, java.net.Proxy proxy) throws IOException {
+        if (proxy == null) throw new IllegalArgumentException("proxy is null");
         maybeInitHttpClient();
         String protocol = url.getProtocol();
         OkHttpClient client;
         // TODO: HttpHandler creates OkHttpClients that share the default ResponseCache.
         // Could this cause unexpected behavior?
-        // TODO: Should the network's proxy be specified?
         if (protocol.equals("http")) {
-            client = HttpHandler.createHttpOkHttpClient(null /* proxy */);
+            client = HttpHandler.createHttpOkHttpClient(proxy);
         } else if (protocol.equals("https")) {
-            client = HttpsHandler.createHttpsOkHttpClient(null /* proxy */);
+            client = HttpsHandler.createHttpsOkHttpClient(proxy);
         } else {
             // OkHttpClient only supports HTTP and HTTPS and returns a null URLStreamHandler if
             // passed another protocol.
diff --git a/core/java/android/net/NetworkFactory.java b/core/java/android/net/NetworkFactory.java
index 6ddd8b3..9b80e74 100644
--- a/core/java/android/net/NetworkFactory.java
+++ b/core/java/android/net/NetworkFactory.java
@@ -274,4 +274,12 @@
     protected void log(String s) {
         Log.d(LOG_TAG, s);
     }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder("{").append(LOG_TAG).append(" - ScoreFilter=").
+                append(mScore).append(", Filter=").append(mCapabilityFilter).append(", requests=").
+                append(mNetworkRequests.size()).append("}");
+        return sb.toString();
+    }
 }
diff --git a/core/java/android/net/ProxyInfo.java b/core/java/android/net/ProxyInfo.java
index 7694420..a3cad77 100644
--- a/core/java/android/net/ProxyInfo.java
+++ b/core/java/android/net/ProxyInfo.java
@@ -260,7 +260,8 @@
         if (!Uri.EMPTY.equals(mPacFileUrl)) {
             sb.append("PAC Script: ");
             sb.append(mPacFileUrl);
-        } else if (mHost != null) {
+        }
+        if (mHost != null) {
             sb.append("[");
             sb.append(mHost);
             sb.append("] ");
diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java
index a9deaf3..b8178b4 100644
--- a/core/java/android/os/Debug.java
+++ b/core/java/android/os/Debug.java
@@ -296,7 +296,7 @@
                 case 1: return "Stack";
                 case 2: return "Cursor";
                 case 3: return "Ashmem";
-                case 4: return "Gfx driver";
+                case 4: return "Gfx dev";
                 case 5: return "Other dev";
                 case 6: return ".so mmap";
                 case 7: return ".jar mmap";
@@ -306,9 +306,9 @@
                 case 11: return ".oat mmap";
                 case 12: return ".art mmap";
                 case 13: return "Other mmap";
-                case 14: return "Graphics";
-                case 15: return "GL";
-                case 16: return "Memtrack";
+                case 14: return "EGL mtrack";
+                case 15: return "GL mtrack";
+                case 16: return "Other mtrack";
                 case 17: return ".Heap";
                 case 18: return ".LOS";
                 case 19: return ".LinearAlloc";
diff --git a/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp b/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp
index b44c829..b27add8 100644
--- a/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp
+++ b/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp
@@ -49,36 +49,35 @@
 #define ALIGN(x, mask) ( ((x) + (mask) - 1) & ~((mask) - 1) )
 
 /**
- * Convert from RGB 888 to Y'CbCr using the conversion specified in ITU-R BT.601 for
- * digital RGB with K_b = 0.114, and K_r = 0.299.
+ * Convert from RGB 888 to Y'CbCr using the conversion specified in JFIF v1.02
  */
 static void rgbToYuv420(uint8_t* rgbBuf, size_t width, size_t height, uint8_t* yPlane,
         uint8_t* uPlane, uint8_t* vPlane, size_t chromaStep, size_t yStride, size_t chromaStride) {
     uint8_t R, G, B;
     size_t index = 0;
-
-    size_t cStrideDiff = chromaStride - width;
-
     for (size_t j = 0; j < height; j++) {
+        uint8_t* u = uPlane;
+        uint8_t* v = vPlane;
+        uint8_t* y = yPlane;
+        bool jEven = (j & 1) == 0;
         for (size_t i = 0; i < width; i++) {
             R = rgbBuf[index++];
             G = rgbBuf[index++];
             B = rgbBuf[index++];
-            *(yPlane + i) = ((66 * R + 129 * G +  25 * B + 128) >> 8) +  16;
-
-            if (j % 2 == 0 && i % 2 == 0){
-                *uPlane = (( -38 * R -  74 * G + 112 * B + 128) >> 8) + 128;
-                *vPlane = (( 112 * R -  94 * G -  18 * B + 128) >> 8) + 128;
-                uPlane += chromaStep;
-                vPlane += chromaStep;
+            *y++ = (77 * R + 150 * G +  29 * B) >> 8;
+            if (jEven && (i & 1) == 0) {
+                *v = (( -43 * R - 85 * G + 128 * B) >> 8) + 128;
+                *u = (( 128 * R - 107 * G - 21 * B) >> 8) + 128;
+                u += chromaStep;
+                v += chromaStep;
             }
             // Skip alpha
             index++;
         }
         yPlane += yStride;
-        if (j % 2 == 0) {
-            uPlane += cStrideDiff;
-            vPlane += cStrideDiff;
+        if (jEven) {
+            uPlane += chromaStride;
+            vPlane += chromaStride;
         }
     }
 }
@@ -87,8 +86,10 @@
     size_t cStep = ycbcr->chroma_step;
     size_t cStride = ycbcr->cstride;
     size_t yStride = ycbcr->ystride;
+    ALOGV("%s: yStride is: %zu, cStride is: %zu, cStep is: %zu", __FUNCTION__, yStride, cStride,
+            cStep);
     rgbToYuv420(rgbBuf, width, height, reinterpret_cast<uint8_t*>(ycbcr->y),
-            reinterpret_cast<uint8_t*>(ycbcr->cb), reinterpret_cast<uint8_t*>(ycbcr->cr),
+            reinterpret_cast<uint8_t*>(ycbcr->cr), reinterpret_cast<uint8_t*>(ycbcr->cb),
             cStep, yStride, cStride);
 }
 
@@ -231,6 +232,7 @@
 
     size_t totalSizeBytes = tmpSize;
 
+    ALOGV("%s: Pixel format chosen: %x", __FUNCTION__, pixelFmt);
     switch(pixelFmt) {
         case HAL_PIXEL_FORMAT_YCrCb_420_SP: {
             if (bufferLength < totalSizeBytes) {
@@ -276,6 +278,7 @@
             }
 
             uint32_t stride = buf->getStride();
+            ALOGV("%s: stride is: %" PRIu32, __FUNCTION__, stride);
             LOG_ALWAYS_FATAL_IF(stride % 16, "Stride is not 16 pixel aligned %d", stride);
 
             uint32_t cStride = ALIGN(stride / 2, 16);
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 6769c85..48e512d 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -425,6 +425,9 @@
     <!-- Integer indicating minimum blacklisting delay of a wofo configuration due to connectin or auth errors -->
     <integer translatable="false" name="config_wifi_framework_network_black_list_min_time_milli">120000</integer>
 
+    <!-- Integer indicating RSSI boost given to current network -->
+    <integer translatable="false" name="config_wifi_framework_current_network_boost">25</integer>
+
     <!-- Boolean indicating associated scan are allowed -->
     <bool translatable="false" name="config_wifi_framework_enable_associated_autojoin_scan">true</bool>
 
@@ -1972,7 +1975,9 @@
     <!-- An array of CDMA roaming indicators which means international roaming -->
     <integer-array translatable="false" name="config_cdma_international_roaming_indicators" />
 
-
     <!-- set the system language as value of EF LI/EF PL -->
     <bool name="config_use_sim_language_file">true</bool>
+
+    <!-- Use ERI text for network name on CDMA LTE -->
+    <bool name="config_LTE_eri_for_network_name">true</bool>
 </resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 4f2ed22..2dcf5bd 100755
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -338,6 +338,7 @@
   <java-symbol type="integer" name="config_wifi_framework_max_connection_errors_to_blacklist" />
   <java-symbol type="integer" name="config_wifi_framework_max_auth_errors_to_blacklist" />
   <java-symbol type="integer" name="config_wifi_framework_network_black_list_min_time_milli" />
+  <java-symbol type="integer" name="config_wifi_framework_current_network_boost" />
   <java-symbol type="integer" name="config_bluetooth_max_advertisers" />
   <java-symbol type="integer" name="config_bluetooth_max_scan_filters" />
   <java-symbol type="integer" name="config_cursorWindowSize" />
@@ -2146,4 +2147,5 @@
   <java-symbol type="string" name="kg_text_message_separator" />
 
   <java-symbol type="bool" name="config_use_sim_language_file" />
+  <java-symbol type="bool" name="config_LTE_eri_for_network_name" />
 </resources>
diff --git a/docs/html/about/versions/android-5.0-changes.jd b/docs/html/about/versions/android-5.0-changes.jd
index f12e83c..f54cde4 100644
--- a/docs/html/about/versions/android-5.0-changes.jd
+++ b/docs/html/about/versions/android-5.0-changes.jd
@@ -1,4 +1,4 @@
-page.title=Android 5.0 Changes
+page.title=Android 5.0 Behavior Changes
 excludeFromSuggestions=true
 sdk.platform.version=5.0
 sdk.platform.apiLevel=21
@@ -20,6 +20,7 @@
   <li><a href="#Power"><a href="#BehaviorWebView">WebView</a></a></li>
   <li><a href="#custom_permissions">Custom Permissions</a></li>
   <li><a href="#ssl">TLS/SSL Configuration</a></li>
+  <li><a href="#managed_profiles">Support for Managed Profiles</a></li>
 </ol>
 
 <h2>API Differences</h2>
@@ -40,9 +41,8 @@
 </div>
 
 <p>API Level: {@sdkPlatformApiLevel}</p>
-<p>Along with new features and capabilities, Android 5.0 includes a variety of changes
-API changes,
-behavior changes, system enhancements, and bug fixes. This document highlights
+<p>Along with new features and capabilities, Android 5.0 includes a variety of
+system changes and API behavior changes. This document highlights
 some of the key changes that you should be understand and account for in your apps.</p>
 
 <p>If you have previously published an app for Android, be aware that your app
@@ -522,4 +522,64 @@
   communicate with the server. The factory should be designed to create
   SSLSocket instances with only those protocols enabled which are correctly
   supported by the server.
-</p>
\ No newline at end of file
+</p>
+
+<h2 id="managed_profiles">Support for Managed Profiles</h2>
+
+<p>
+  Device administrators can add a <em>managed profile</em> to a device. This
+  profile is owned by the administrator, giving the administrator control
+  over the managed profile while leaving the user's personal profile, and its
+  storage space, under the user's control.
+  This change can affect the behavior of your existing app in
+  the following ways.</p>
+
+<h3 id="mg_profile_intents">Handling intents</h3>
+
+<p>Device administrators can restrict access to system applications from the
+managed profile. In this case, if an app fires an intent from the managed
+profile that would ordinarily be handled by that application, and there is no
+suitable handler for the intent on the managed profile,
+the intent causes an exception. For example, the
+device administrator can restrict apps on the managed profile from accessing
+the system's camera application. If your app is running on the managed profile
+and calls {@link
+android.app.Activity#startActivityForResult startActivityForResult()} for {@link
+android.provider.MediaStore#ACTION_IMAGE_CAPTURE
+MediaStore.ACTION_IMAGE_CAPTURE}, and there is no app on the managed profile
+that can handle the intent, this results in an {@link
+android.content.ActivityNotFoundException}.</p>
+
+<p>You can prevent this by checking
+that there is at least one handler for any intent
+before firing it. To check for a valid handler, call {@link
+android.content.Intent#resolveActivity Intent.resolveActivity()}. You can see
+an example of this being done in <a
+href="{@docRoot}training/camera/photobasics.html#TaskCaptureIntent">Take Photos
+Simply: Take a Photo with the Camera App</a>.</p>
+
+<h3 id="mp_profile_file_sharing">Sharing files across profiles</h3>
+
+<p>Each profile has its own file storage. Since a file URI refers to a specific
+location in the file storage, this means that a file URI that is valid on one
+profile is not valid on the other one. This is not ordinarily a problem for an
+app, which usually just accesses the files it creates. However, if an app
+attaches a file to an intent, it is not safe to attach a file URI, since in some
+circumstances, the intent might be handled on the other profile.
+For example, a device administrator might specify that image capture events
+should be handled by the camera app on the personal profile. If the intent is
+fired by an app on the managed profile, the camera needs to be able to write the
+image to a location where the managed profile's apps can read it.</p>
+
+<p>To be safe, when
+you need to attach a file to an intent that might cross from one profile to the
+other, you should create and use a <em>content URI</em> for the file. For more
+information about sharing files with content URIs, see <a
+href="{@docRoot}training/secure-file-sharing/index.html">Sharing Files</a>.
+For example, the device administrator might whitelist {@link
+android.provider.MediaStore#ACTION_IMAGE_CAPTURE ACTION_IMAGE_CAPTURE} to be
+handled by the camera in the personal profile. The firing intent's {@link
+android.provider.MediaStore#EXTRA_OUTPUT EXTRA_OUTPUT} should contain a content
+URI specifying where the photo should be stored. The camera app can write the
+image to the location specified by that URI, and the app that fired the intent
+would be able to read that file, even if the app is on the other profile. </p>
diff --git a/docs/html/design/wear/index.jd b/docs/html/design/wear/index.jd
index 104e154..c75723f 100644
--- a/docs/html/design/wear/index.jd
+++ b/docs/html/design/wear/index.jd
@@ -2,7 +2,6 @@
 @jd:body
 
 
-
 <p>Designing apps for wearable devices powered by Android Wear
 is substantially different than designing for phones or
 tablets: different strengths and weaknesses, different use cases, different ergonomics.
diff --git a/docs/html/design/wear/watchfaces.jd b/docs/html/design/wear/watchfaces.jd
index ef700ee..1a4b1f9 100644
--- a/docs/html/design/wear/watchfaces.jd
+++ b/docs/html/design/wear/watchfaces.jd
@@ -4,10 +4,10 @@
 
 <!-- developer docs box -->
 <a class="notice-developers right" href="{@docRoot}training/wearables/watch-faces/index.html"
-   style="clear:left;margin-bottom:70px">
+   style="clear:left;margin-bottom:90px">
   <div>
     <h3>Developer Docs</h3>
-    <p>Creating Custom Watch Faces</p>
+    <p>Creating Watch Faces</p>
   </div>
 </a>
 
@@ -158,8 +158,8 @@
   burn-in effect. When these screens are in ambient mode, the system shifts the contents of
   the screen periodically by a few pixels to avoid pixel burn-in. Do not use large blocks of
   pixels in your ambient mode designs and keep 95% of the pixels black. Replace solid shapes in
-  your regular ambient mode designs with outlined shapes in burn-protected ambient mode. Replace
-  also filled images with pixel patterns. For analog watch face designs, hollow out the center
+  your regular ambient mode designs with outlined shapes in burn-protected ambient mode. Also
+  replace filled images with pixel patterns. For analog watch face designs, hollow out the center
   where the hands meet to avoid pixel burn-in in this mode.</p>
 </div>
 <div class="layout-content-col span-4">
diff --git a/docs/html/jd_collections.js b/docs/html/jd_collections.js
index 1b7cfc9..ab5a655 100644
--- a/docs/html/jd_collections.js
+++ b/docs/html/jd_collections.js
@@ -4,7 +4,7 @@
     "resources": [
       "training/building-wearables.html",
       "training/material/index.html",
-      "sdk/installing/studio.html"
+      "sdk/index.html"
     ]
   },
   "index/primary/zhcn": {
diff --git a/docs/html/sdk/index.jd b/docs/html/sdk/index.jd
index 986862b..e56f3f5 100644
--- a/docs/html/sdk/index.jd
+++ b/docs/html/sdk/index.jd
@@ -15,8 +15,8 @@
 studio.mac_bundle_checksum=0d9e0e230ece9f2e696b1b076c36ee1e73edcf3c
 
 studio.win_bundle_exe_download=android-studio-bundle-135.1629389.exe
-studio.win_bundle_exe_bytes=852499624
-studio.win_bundle_exe_checksum=0c8a3b45385a698b43a47757fdd6a83ca837abd2
+studio.win_bundle_exe_bytes=868337656
+studio.win_bundle_exe_checksum=1931dbaeadb52f5e0a8ba6e2ae60d9df20b2076b
 
 studio.win_notools_exe_download=android-studio-ide-135.1629389.exe
 studio.win_notools_exe_bytes=262099808
diff --git a/docs/html/tools/revisions/platforms.jd b/docs/html/tools/revisions/platforms.jd
index 75b3cef..a73be5e 100644
--- a/docs/html/tools/revisions/platforms.jd
+++ b/docs/html/tools/revisions/platforms.jd
@@ -59,6 +59,22 @@
 <div class="toggle-content opened">
   <p><a href="#" onclick="return toggleContent(this)">
     <img src="{@docRoot}assets/images/triangle-opened.png"
+class="toggle-content-img" alt="" />Revision 2</a> <em>(December 2014)</em>
+  </p>
+
+  <div class="toggle-content-toggleme">
+
+    <p>Updated layouts in the Support Library and fixed various issues.</p>
+    <p>Dependencies:</p>
+    <ul>
+      <li>Android SDK Platform-tools r21 or higher is required.</li>
+      <li>Android SDK Tools 23.0.5 or higher is required.</li>
+    </ul>
+  </div>
+
+<div class="toggle-content closed">
+  <p><a href="#" onclick="return toggleContent(this)">
+    <img src="{@docRoot}assets/images/triangle-closed.png"
 class="toggle-content-img" alt="" />Revision 1</a> <em>(October 2014)</em>
   </p>
 
diff --git a/docs/html/tools/sdk/tools-notes.jd b/docs/html/tools/sdk/tools-notes.jd
index 80edb4f..ed48887 100644
--- a/docs/html/tools/sdk/tools-notes.jd
+++ b/docs/html/tools/sdk/tools-notes.jd
@@ -25,6 +25,33 @@
 <div class="toggle-content opened">
   <p><a href="#" onclick="return toggleContent(this)">
     <img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-content-img"
+      alt=""/>SDK Tools, Revision 24.0.1</a> <em>(December 2014)</em>
+  </p>
+
+  <div class="toggle-content-toggleme">
+
+    <dl>
+    <dt>Dependencies:</dt>
+
+    <dd>
+      <ul>
+        <li>Android SDK Platform-tools revision 19 or later.</li>
+      </ul>
+    </dd>
+
+    <dt>General Notes:</dt>
+    <dd>
+      <ul>
+        <li>Fixed Java detection issue on 32-bit Windows systems.</li>
+      </ul>
+    </dd>
+  </div>
+</div>
+
+
+<div class="toggle-content closed">
+  <p><a href="#" onclick="return toggleContent(this)">
+    <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-content-img"
       alt=""/>SDK Tools, Revision 24.0.0</a> <em>(December 2014)</em>
   </p>
 
@@ -49,6 +76,7 @@
 </div>
 
 
+
 <div class="toggle-content closed">
   <p><a href="#" onclick="return toggleContent(this)">
     <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-content-img"
diff --git a/docs/html/tools/studio/index.jd b/docs/html/tools/studio/index.jd
index 258fedb..7480f57 100644
--- a/docs/html/tools/studio/index.jd
+++ b/docs/html/tools/studio/index.jd
@@ -235,8 +235,8 @@
 
 <p>The AVD Manager comes with emulators for Nexus 6 and Nexus 9 devices and also supports
 creating custom Android device skins based on specific emulator properties and assigning those
-skins to hardware profiles. Android Studio installs the the Intel x86 Emulator Accelerator (HAXM)
-and creates a default emulator for quick app prototyping.</p>
+skins to hardware profiles. Android Studio installs the Intel&#174; x86 Hardware Accelerated Execution
+Manager (HAXM) emulator accelerator and creates a default emulator for quick app prototyping.</p>
 
 <p>For more information, see <a href="{@docRoot}tools/devices/managing-avds.html">Managing AVDs</a>.</p>
 
@@ -334,7 +334,7 @@
 <p>An updated installation and setup wizards walk you through a step-by-step installation
 and setup process as the wizard checks for system requirements, such as the Java Development
 Kit (JDK) and available RAM, and then prompts for optional installation options, such as the
-Intel &#174; HAXM accelerator.</p>
+Intel&#174; HAXM emulator accelerator.</p>
 
 <p>An updated setup wizard walks you through the setup processes as
 the wizard updates your system image and emulation requirements, such GPU, and then creates
@@ -386,7 +386,7 @@
 
 
 
-<h2 id="other">Other Highlights/h2>
+<h2 id="other">Other Highlights</h2>
 
 <h3> Translation Editor</h3>
 <p>Multi-language support is enhanced with the Translation Editor plugin so you can easily add
@@ -414,5 +414,5 @@
 <p>Clicking <strong>Import Samples</strong> from the <strong>File</strong> menu or Welcome page
 provides seamless access to Google code samples on GitHub.</p>
     <p><img src="{@docRoot}images/tools/studio-samples-githubaccess.png" /></p>
-    <p class="img-caption"><strong>Figure 12.</strong> Code Sample Access/p>
+    <p class="img-caption"><strong>Figure 12.</strong> Code Sample Access</p>
 
diff --git a/docs/html/training/basics/actionbar/adding-buttons.jd b/docs/html/training/basics/actionbar/adding-buttons.jd
index 26c9d0e..40d0bd1 100644
--- a/docs/html/training/basics/actionbar/adding-buttons.jd
+++ b/docs/html/training/basics/actionbar/adding-buttons.jd
@@ -1,4 +1,6 @@
 page.title=Adding Action Buttons
+page.tags=actionbar
+helpoutsWidget=true
 
 trainingnavtop=true
 
diff --git a/docs/html/training/basics/actionbar/index.jd b/docs/html/training/basics/actionbar/index.jd
index 0303043..6a8eaff 100644
--- a/docs/html/training/basics/actionbar/index.jd
+++ b/docs/html/training/basics/actionbar/index.jd
@@ -1,5 +1,6 @@
 page.title=Adding the Action Bar
 page.tags=actionbar
+helpoutsWidget=true
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/basics/actionbar/overlaying.jd b/docs/html/training/basics/actionbar/overlaying.jd
index 800cd44..634534e 100644
--- a/docs/html/training/basics/actionbar/overlaying.jd
+++ b/docs/html/training/basics/actionbar/overlaying.jd
@@ -1,4 +1,6 @@
 page.title=Overlaying the Action Bar
+page.tags=actionbar
+helpoutsWidget=true
 
 trainingnavtop=true
 
diff --git a/docs/html/training/basics/actionbar/setting-up.jd b/docs/html/training/basics/actionbar/setting-up.jd
index 158ce92..bccbd04 100644
--- a/docs/html/training/basics/actionbar/setting-up.jd
+++ b/docs/html/training/basics/actionbar/setting-up.jd
@@ -1,4 +1,6 @@
 page.title=Setting Up the Action Bar
+page.tags=actionbar
+helpoutsWidget=true
 
 trainingnavtop=true
 
diff --git a/docs/html/training/basics/actionbar/styling.jd b/docs/html/training/basics/actionbar/styling.jd
index 4128a97..7c63952 100644
--- a/docs/html/training/basics/actionbar/styling.jd
+++ b/docs/html/training/basics/actionbar/styling.jd
@@ -1,4 +1,6 @@
 page.title=Styling the Action Bar
+page.tags=actionbar
+helpoutsWidget=true
 
 trainingnavtop=true
 
diff --git a/docs/html/training/basics/data-storage/databases.jd b/docs/html/training/basics/data-storage/databases.jd
index 6ea2140..4a91d0d 100644
--- a/docs/html/training/basics/data-storage/databases.jd
+++ b/docs/html/training/basics/data-storage/databases.jd
@@ -1,8 +1,8 @@
 page.title=Saving Data in SQL Databases
+page.tags=data storage
+helpoutsWidget=true
 
 trainingnavtop=true
-previous.title=Saving Data in Files
-previous.link=files.html
 
 @jd:body
 
diff --git a/docs/html/training/basics/data-storage/files.jd b/docs/html/training/basics/data-storage/files.jd
index 52bea4c..49a9169 100644
--- a/docs/html/training/basics/data-storage/files.jd
+++ b/docs/html/training/basics/data-storage/files.jd
@@ -1,4 +1,6 @@
 page.title=Saving Files
+page.tags=data storage
+helpoutsWidget=true
 
 trainingnavtop=true
 
diff --git a/docs/html/training/basics/data-storage/index.jd b/docs/html/training/basics/data-storage/index.jd
index fc0c8b5..aa223f6 100644
--- a/docs/html/training/basics/data-storage/index.jd
+++ b/docs/html/training/basics/data-storage/index.jd
@@ -1,5 +1,6 @@
 page.title=Saving Data
 page.tags=data storage,files,sql,database,preferences
+helpoutsWidget=true
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/basics/data-storage/shared-preferences.jd b/docs/html/training/basics/data-storage/shared-preferences.jd
index a6717c4..debb17d 100644
--- a/docs/html/training/basics/data-storage/shared-preferences.jd
+++ b/docs/html/training/basics/data-storage/shared-preferences.jd
@@ -1,4 +1,6 @@
 page.title=Saving Key-Value Sets
+page.tags=data storage
+helpoutsWidget=true
 
 trainingnavtop=true
 
diff --git a/docs/html/training/notify-user/build-notification.jd b/docs/html/training/notify-user/build-notification.jd
index 80f2cd5..d24a496 100644
--- a/docs/html/training/notify-user/build-notification.jd
+++ b/docs/html/training/notify-user/build-notification.jd
@@ -1,10 +1,8 @@
 page.title=Building a Notification
-parent.title=Notifying the User
-parent.link=index.html
+page.tags=notifications
+helpoutsWidget=true
 
 trainingnavtop=true
-next.title=Preserving Navigation when Starting an Activity
-next.link=navigation.html
 
 @jd:body
 
diff --git a/docs/html/training/notify-user/display-progress.jd b/docs/html/training/notify-user/display-progress.jd
index c00576c..3439571 100644
--- a/docs/html/training/notify-user/display-progress.jd
+++ b/docs/html/training/notify-user/display-progress.jd
@@ -1,10 +1,8 @@
 page.title=Displaying Progress in a Notification
-parent.title=Notifying the User
-parent.link=index.html
+page.tags=notifications
+helpoutsWidget=true
 
 trainingnavtop=true
-previous.title=Using Expanded Notification Styles
-previous.link=expanded.html
 
 @jd:body
 
diff --git a/docs/html/training/notify-user/expanded.jd b/docs/html/training/notify-user/expanded.jd
index a3cc6ad..b657426 100644
--- a/docs/html/training/notify-user/expanded.jd
+++ b/docs/html/training/notify-user/expanded.jd
@@ -1,10 +1,8 @@
 page.title=Using Big View Styles
-Styles parent.title=Notifying the User
-parent.link=index.html
+page.tags=notifications
+helpoutsWidget=true
 
 trainingnavtop=true
-next.title=Displaying Progress in a Notification
-next.link=display-progress.html
 
 @jd:body
 
diff --git a/docs/html/training/notify-user/index.jd b/docs/html/training/notify-user/index.jd
index f7d0f87..616e767 100644
--- a/docs/html/training/notify-user/index.jd
+++ b/docs/html/training/notify-user/index.jd
@@ -1,5 +1,6 @@
 page.title=Notifying the User
 page.tags=notifications
+helpoutsWidget=true
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/notify-user/managing.jd b/docs/html/training/notify-user/managing.jd
index 4782734..fc12cfb 100644
--- a/docs/html/training/notify-user/managing.jd
+++ b/docs/html/training/notify-user/managing.jd
@@ -1,10 +1,8 @@
 page.title=Updating Notifications
-parent.title=Notifying the User
-parent.link=index.html
+page.tags=notifications
+helpoutsWidget=true
 
 trainingnavtop=true
-next.title=Creating Expanded Notifications
-next.link=expanded.html
 
 @jd:body
 
diff --git a/docs/html/training/notify-user/navigation.jd b/docs/html/training/notify-user/navigation.jd
index fc95013..b7051ab 100644
--- a/docs/html/training/notify-user/navigation.jd
+++ b/docs/html/training/notify-user/navigation.jd
@@ -1,10 +1,8 @@
 page.title=Preserving Navigation when Starting an Activity
-parent.title=Notifying the User
-parent.link=index.html
+page.tags=notifications
+helpoutsWidget=true
 
 trainingnavtop=true
-next.title=Updating Notifications
-next.link=managing.html
 
 @jd:body
 
diff --git a/docs/html/training/training_toc.cs b/docs/html/training/training_toc.cs
index f883e25..f3b2693 100644
--- a/docs/html/training/training_toc.cs
+++ b/docs/html/training/training_toc.cs
@@ -838,8 +838,8 @@
       <li class="nav-section">
         <div class="nav-section-header">
           <a href="<?cs var:toroot ?>training/wearables/watch-faces/index.html"
-             description="How to create custom watch faces for wearables."
-            >Creating Custom Watch Faces</a>
+             description="How to create watch faces for wearables."
+            >Creating Watch Faces</a>
         </div>
         <ul>
           <li>
diff --git a/docs/html/training/tv/discovery/in-app-search.jd b/docs/html/training/tv/discovery/in-app-search.jd
index 28c7a35..fb7c097 100644
--- a/docs/html/training/tv/discovery/in-app-search.jd
+++ b/docs/html/training/tv/discovery/in-app-search.jd
@@ -1,5 +1,6 @@
 page.title=Searching within TV Apps
-page.tags="leanback"
+page.tags=tv, leanback
+helpoutsWidget=true
 
 trainingnavtop=true
 
diff --git a/docs/html/training/tv/discovery/index.jd b/docs/html/training/tv/discovery/index.jd
index 5849149..f22ca67 100644
--- a/docs/html/training/tv/discovery/index.jd
+++ b/docs/html/training/tv/discovery/index.jd
@@ -1,5 +1,6 @@
 page.title=Helping Users Find Your Content on TV
-page.tags="tv", "leanback"
+page.tags=tv, leanback
+helpoutsWidget=true
 
 startpage=true
 
diff --git a/docs/html/training/tv/discovery/recommendations.jd b/docs/html/training/tv/discovery/recommendations.jd
index a6eb152..0f6d256 100644
--- a/docs/html/training/tv/discovery/recommendations.jd
+++ b/docs/html/training/tv/discovery/recommendations.jd
@@ -1,5 +1,6 @@
 page.title=Recommending TV Content
-page.tags="recommendation","recommend"
+page.tags=tv, recommendations
+helpoutsWidget=true
 
 trainingnavtop=true
 
diff --git a/docs/html/training/tv/games/index.jd b/docs/html/training/tv/games/index.jd
index 5276d7f..371e9e9 100644
--- a/docs/html/training/tv/games/index.jd
+++ b/docs/html/training/tv/games/index.jd
@@ -1,5 +1,6 @@
 page.title=Building TV Games
-page.tags="tv", "games", "controller"
+page.tags=tv, games, controller
+helpoutsWidget=true
 page.image=images/games/game-controller-buttons_2x_crop.png
 page.metaDescription=How to bring your games to Android TV, including recommendations and examples.
 page.article=true
diff --git a/docs/html/training/tv/playback/browse.jd b/docs/html/training/tv/playback/browse.jd
index 9b25166..9c81597 100644
--- a/docs/html/training/tv/playback/browse.jd
+++ b/docs/html/training/tv/playback/browse.jd
@@ -1,5 +1,6 @@
 page.title=Creating a Catalog Browser
-page.tags="browsefragment","presenter","backgroundmanager"
+page.tags=tv, browsefragment, presenter, backgroundmanager
+helpoutsWidget=true
 
 trainingnavtop=true
 
diff --git a/docs/html/training/tv/playback/details.jd b/docs/html/training/tv/playback/details.jd
index 6391a49..bd6d67a 100644
--- a/docs/html/training/tv/playback/details.jd
+++ b/docs/html/training/tv/playback/details.jd
@@ -1,5 +1,6 @@
 page.title=Building a Details View
-page.tags="detailsfragment"
+page.tags=tv, detailsfragment
+helpoutsWidget=true
 
 trainingnavtop=true
 
diff --git a/docs/html/training/tv/playback/index.jd b/docs/html/training/tv/playback/index.jd
index 09c3f24..31c7524 100644
--- a/docs/html/training/tv/playback/index.jd
+++ b/docs/html/training/tv/playback/index.jd
@@ -1,5 +1,6 @@
 page.title=Building TV Playback Apps
-page.tags="tv","leanback"
+page.tags=tv, leanback
+helpoutsWidget=true
 
 startpage=true
 
diff --git a/docs/html/training/tv/playback/now-playing.jd b/docs/html/training/tv/playback/now-playing.jd
index b64beb0..e158697 100644
--- a/docs/html/training/tv/playback/now-playing.jd
+++ b/docs/html/training/tv/playback/now-playing.jd
@@ -1,5 +1,6 @@
 page.title=Displaying a Now Playing Card
-page.tags="nowplaying","mediasession"
+page.tags=tv, mediasession
+helpoutsWidget=true
 
 trainingnavtop=true
 
diff --git a/docs/html/training/tv/start/hardware.jd b/docs/html/training/tv/start/hardware.jd
index fc52602..b25a0dd 100644
--- a/docs/html/training/tv/start/hardware.jd
+++ b/docs/html/training/tv/start/hardware.jd
@@ -1,5 +1,6 @@
 page.title=Handling TV Hardware
-page.tags="unsupported"
+page.tags=tv
+helpoutsWidget=true
 trainingnavtop=true
 
 @jd:body
diff --git a/docs/html/training/tv/start/index.jd b/docs/html/training/tv/start/index.jd
index fb478a8..54ff2d9 100644
--- a/docs/html/training/tv/start/index.jd
+++ b/docs/html/training/tv/start/index.jd
@@ -1,5 +1,6 @@
 page.title=Building TV Apps
-page.tags="tv", "leanback"
+page.tags=tv, leanback
+helpoutsWidget=true
 startpage=true
 
 @jd:body
diff --git a/docs/html/training/tv/start/layouts.jd b/docs/html/training/tv/start/layouts.jd
index d2abe1d..a390702 100644
--- a/docs/html/training/tv/start/layouts.jd
+++ b/docs/html/training/tv/start/layouts.jd
@@ -1,4 +1,7 @@
 page.title=Building Layouts for TV
+page.tags=tv
+helpoutsWidget=true
+
 trainingnavtop=true
 
 @jd:body
diff --git a/docs/html/training/tv/start/navigation.jd b/docs/html/training/tv/start/navigation.jd
index 1c9faca..a94e3ae 100644
--- a/docs/html/training/tv/start/navigation.jd
+++ b/docs/html/training/tv/start/navigation.jd
@@ -1,5 +1,6 @@
 page.title=Creating TV Navigation
-page.tags="focus","selection","d-pad"
+page.tags=tv, d-pad, focus
+helpoutsWidget=true
 trainingnavtop=true
 
 @jd:body
diff --git a/docs/html/training/tv/start/start.jd b/docs/html/training/tv/start/start.jd
index aab1a39..e3b92c6 100644
--- a/docs/html/training/tv/start/start.jd
+++ b/docs/html/training/tv/start/start.jd
@@ -1,5 +1,6 @@
 page.title=Get Started with TV Apps
-page.tags="leanback","recyclerview","launcher"
+page.tags=tv, leanback, recyclerview
+helpoutsWidget=true
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/tv/tif/index.jd b/docs/html/training/tv/tif/index.jd
index cde8ba7..9c10850 100644
--- a/docs/html/training/tv/tif/index.jd
+++ b/docs/html/training/tv/tif/index.jd
@@ -1,5 +1,6 @@
 page.title=Building Live TV Apps
-page.tags="tv", "tif"
+page.tags=tv, tif
+helpoutsWidget=true
 page.article=true
 
 @jd:body
diff --git a/docs/html/training/wearables/apps/bt-debugging.jd b/docs/html/training/wearables/apps/bt-debugging.jd
index 7569e7e..beded9e 100644
--- a/docs/html/training/wearables/apps/bt-debugging.jd
+++ b/docs/html/training/wearables/apps/bt-debugging.jd
@@ -1,4 +1,6 @@
 page.title=Debugging over Bluetooth
+page.tags=wear
+helpoutsWidget=true
 
 @jd:body
 
diff --git a/docs/html/training/wearables/apps/creating.jd b/docs/html/training/wearables/apps/creating.jd
index 683dd31..c12ffa7 100644
--- a/docs/html/training/wearables/apps/creating.jd
+++ b/docs/html/training/wearables/apps/creating.jd
@@ -1,4 +1,6 @@
 page.title=Creating and Running a Wearable App
+page.tags=wear
+helpoutsWidget=true
 
 @jd:body
 
diff --git a/docs/html/training/wearables/apps/index.jd b/docs/html/training/wearables/apps/index.jd
index 4bdd6bf..812f893 100644
--- a/docs/html/training/wearables/apps/index.jd
+++ b/docs/html/training/wearables/apps/index.jd
@@ -1,5 +1,6 @@
 page.title=Creating Wearable Apps
-page.tags="wear","wearable","app"
+page.tags=wear
+helpoutsWidget=true
 page.image=wear/images/01_create.png
 
 @jd:body
diff --git a/docs/html/training/wearables/apps/layouts.jd b/docs/html/training/wearables/apps/layouts.jd
index 4eeb281..69e57ca 100644
--- a/docs/html/training/wearables/apps/layouts.jd
+++ b/docs/html/training/wearables/apps/layouts.jd
@@ -1,4 +1,6 @@
 page.title=Creating Custom Layouts
+page.tags=wear
+helpoutsWidget=true
 
 @jd:body
 
diff --git a/docs/html/training/wearables/apps/packaging.jd b/docs/html/training/wearables/apps/packaging.jd
index 180f730..9c42978 100644
--- a/docs/html/training/wearables/apps/packaging.jd
+++ b/docs/html/training/wearables/apps/packaging.jd
@@ -1,4 +1,6 @@
 page.title=Packaging Wearable Apps
+page.tags=wear
+helpoutsWidget=true
 
 @jd:body
 
diff --git a/docs/html/training/wearables/apps/voice.jd b/docs/html/training/wearables/apps/voice.jd
index 4aa8031..6d49319 100644
--- a/docs/html/training/wearables/apps/voice.jd
+++ b/docs/html/training/wearables/apps/voice.jd
@@ -1,4 +1,7 @@
 page.title=Adding Voice Capabilities
+page.tags=wear
+helpoutsWidget=true
+
 @jd:body
 
 <div id="tb-wrapper">
diff --git a/docs/html/training/wearables/notifications/creating.jd b/docs/html/training/wearables/notifications/creating.jd
index 57ac36e..542664b 100644
--- a/docs/html/training/wearables/notifications/creating.jd
+++ b/docs/html/training/wearables/notifications/creating.jd
@@ -1,4 +1,6 @@
-page.title=Creating a Notification
+page.title=Creating a Notification for Wearables
+page.tags=notifications
+helpoutsWidget=true
 
 @jd:body
 
diff --git a/docs/html/training/wearables/notifications/index.jd b/docs/html/training/wearables/notifications/index.jd
index 2833dfa..6be945c 100644
--- a/docs/html/training/wearables/notifications/index.jd
+++ b/docs/html/training/wearables/notifications/index.jd
@@ -1,6 +1,8 @@
 page.title=Adding Wearable Features to Notifications
-page.tags="wear","notifications","wearables"
+page.tags=notifications, wear
 page.image=wear/images/01_notifications.png
+helpoutsWidget=true
+
 @jd:body
 
 <div id="tb-wrapper">
diff --git a/docs/html/training/wearables/notifications/pages.jd b/docs/html/training/wearables/notifications/pages.jd
index 6315037..41a3d7e 100644
--- a/docs/html/training/wearables/notifications/pages.jd
+++ b/docs/html/training/wearables/notifications/pages.jd
@@ -1,4 +1,6 @@
 page.title=Adding Pages to a Notification
+page.tags=notifications
+helpoutsWidget=true
 
 @jd:body
 
diff --git a/docs/html/training/wearables/notifications/stacks.jd b/docs/html/training/wearables/notifications/stacks.jd
index 9e70e1b..8056fc8 100644
--- a/docs/html/training/wearables/notifications/stacks.jd
+++ b/docs/html/training/wearables/notifications/stacks.jd
@@ -1,4 +1,6 @@
 page.title=Stacking Notifications
+page.tags=notifications
+helpoutsWidget=true
 
 @jd:body
 
diff --git a/docs/html/training/wearables/notifications/voice-input.jd b/docs/html/training/wearables/notifications/voice-input.jd
index 5a49343..73936f9 100644
--- a/docs/html/training/wearables/notifications/voice-input.jd
+++ b/docs/html/training/wearables/notifications/voice-input.jd
@@ -1,4 +1,6 @@
 page.title=Receiving Voice Input in a Notification
+page.tags=notifications
+helpoutsWidget=true
 
 @jd:body
 
diff --git a/docs/html/training/wearables/watch-faces/designing.jd b/docs/html/training/wearables/watch-faces/designing.jd
index b7fcfd4..1033fed 100644
--- a/docs/html/training/wearables/watch-faces/designing.jd
+++ b/docs/html/training/wearables/watch-faces/designing.jd
@@ -16,6 +16,14 @@
 </div>
 </div>
 
+<!-- design guide box -->
+<a class="notice-designers wide" href="{@docRoot}design/wear/watchfaces.html">
+  <div>
+    <h3>Design Guide</h3>
+    <p>Watch Faces</p>
+  </div>
+</a>
+
 <p>Similar to the process of designing a traditional watch face, creating one for
 Android Wear is an exercise in visualizing time clearly. Android Wear devices
 provide advanced capabilities for watch faces that you can leverage in your designs, such as
diff --git a/docs/html/training/wearables/watch-faces/index.jd b/docs/html/training/wearables/watch-faces/index.jd
index c510fb2..c7affd1 100644
--- a/docs/html/training/wearables/watch-faces/index.jd
+++ b/docs/html/training/wearables/watch-faces/index.jd
@@ -1,4 +1,4 @@
-page.title=Creating Custom Watch Faces
+page.title=Creating Watch Faces
 
 @jd:body
 
@@ -13,6 +13,14 @@
 </div>
 </div>
 
+<!-- design guide box -->
+<a class="notice-designers wide" href="{@docRoot}design/wear/watchfaces.html">
+  <div>
+    <h3>Design Guide</h3>
+    <p>Watch Faces</p>
+  </div>
+</a>
+
 <p>Watch faces in Android Wear leverage a dynamic digital canvas to tell time using colors,
 animations, and relevant contextual information. The <a
 href="https://play.google.com/store/apps/details?id=com.google.android.wearable.app">Android
diff --git a/docs/html/training/wearables/watch-faces/service.jd b/docs/html/training/wearables/watch-faces/service.jd
index 0cb628c..87ebefa 100644
--- a/docs/html/training/wearables/watch-faces/service.jd
+++ b/docs/html/training/wearables/watch-faces/service.jd
@@ -75,7 +75,7 @@
 dependencies {
     ...
     wearApp project(':wear')
-    compile 'com.google.android.gms:play-services:6.1.+'
+    compile 'com.google.android.gms:play-services:6.5.+'
 }
 </pre>
 
@@ -90,7 +90,7 @@
 dependencies {
     ...
     compile 'com.google.android.support:wearable:1.1.+'
-    compile 'com.google.android.gms:play-services-wearable:6.1.+'
+    compile 'com.google.android.gms:play-services-wearable:6.5.+'
 }
 </pre>
 
@@ -183,7 +183,7 @@
         }
 
         &#64;Override
-        public void onDraw(Canvas canvas) {
+        public void onDraw(Canvas canvas, Rect bounds) {
             /* draw your watch face */
         }
 
diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java
index 94c7026..cb42397 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -1795,5 +1795,7 @@
                 mStrokePaint.setPathEffect(e);
             }
         }
+
+        mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode);
     }
 }
diff --git a/libs/hwui/AssetAtlas.cpp b/libs/hwui/AssetAtlas.cpp
index e5a93bd..c6de535 100644
--- a/libs/hwui/AssetAtlas.cpp
+++ b/libs/hwui/AssetAtlas.cpp
@@ -36,39 +36,37 @@
     ATRACE_NAME("AssetAtlas::init");
 
     mImage = new Image(buffer);
-
     if (mImage->getTexture()) {
-        Caches& caches = Caches::getInstance();
-
-        mTexture = new Texture(caches);
-        mTexture->id = mImage->getTexture();
-        mTexture->width = buffer->getWidth();
-        mTexture->height = buffer->getHeight();
-
-        createEntries(caches, map, count);
+        if (!mTexture) {
+            Caches& caches = Caches::getInstance();
+            mTexture = new Texture(caches);
+            mTexture->width = buffer->getWidth();
+            mTexture->height = buffer->getHeight();
+            createEntries(caches, map, count);
+        }
     } else {
         ALOGW("Could not create atlas image");
-
         delete mImage;
         mImage = NULL;
-        mTexture = NULL;
     }
 
-    mGenerationId++;
+    updateTextureId();
 }
 
 void AssetAtlas::terminate() {
     if (mImage) {
         delete mImage;
         mImage = NULL;
+        updateTextureId();
+    }
+}
 
-        delete mTexture;
-        mTexture = NULL;
 
-        for (size_t i = 0; i < mEntries.size(); i++) {
-            delete mEntries.valueAt(i);
-        }
-        mEntries.clear();
+void AssetAtlas::updateTextureId() {
+    mTexture->id = mImage ? mImage->getTexture() : 0;
+    for (size_t i = 0; i < mEntries.size(); i++) {
+        AssetAtlas::Entry* entry = mEntries.valueAt(i);
+        entry->texture->id = mTexture->id;
     }
 }
 
@@ -133,7 +131,6 @@
                 y / height, (y + bitmap->height()) / height);
 
         Texture* texture = new DelegateTexture(caches, mTexture);
-        texture->id = mTexture->id;
         texture->blend = !bitmap->isOpaque();
         texture->width = bitmap->width();
         texture->height = bitmap->height();
diff --git a/libs/hwui/AssetAtlas.h b/libs/hwui/AssetAtlas.h
index 2ec556e..fffd740 100644
--- a/libs/hwui/AssetAtlas.h
+++ b/libs/hwui/AssetAtlas.h
@@ -106,7 +106,7 @@
         friend class AssetAtlas;
     };
 
-    AssetAtlas(): mTexture(NULL), mImage(NULL), mGenerationId(0),
+    AssetAtlas(): mTexture(NULL), mImage(NULL),
             mBlendKey(true), mOpaqueKey(false) { }
     ~AssetAtlas() { terminate(); }
 
@@ -130,7 +130,7 @@
      * After calling this method, the width, height
      * and texture are set to 0.
      */
-    ANDROID_API void terminate();
+    void terminate();
 
     /**
      * Returns the width of this atlas in pixels.
@@ -168,21 +168,13 @@
      */
     Texture* getEntryTexture(const SkBitmap* bitmap) const;
 
-    /**
-     * Returns the current generation id of the atlas.
-     */
-    uint32_t getGenerationId() const {
-        return mGenerationId;
-    }
-
 private:
     void createEntries(Caches& caches, int64_t* map, int count);
+    void updateTextureId();
 
     Texture* mTexture;
     Image* mImage;
 
-    uint32_t mGenerationId;
-
     const bool mBlendKey;
     const bool mOpaqueKey;
 
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp
index 6453206..4bbe6ed 100644
--- a/libs/hwui/Caches.cpp
+++ b/libs/hwui/Caches.cpp
@@ -237,8 +237,6 @@
     programCache.clear();
     currentProgram = NULL;
 
-    assetAtlas.terminate();
-
     patchCache.clear();
 
     clearGarbage();
diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h
index e338686..2e179af 100644
--- a/libs/hwui/Caches.h
+++ b/libs/hwui/Caches.h
@@ -348,8 +348,6 @@
     Dither dither;
     Stencil stencil;
 
-    AssetAtlas assetAtlas;
-
     bool gpuPixelBuffersEnabled;
 
     // Debug methods
diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h
index 96e76d0..8a5e21d 100644
--- a/libs/hwui/DisplayListOp.h
+++ b/libs/hwui/DisplayListOp.h
@@ -32,6 +32,7 @@
 #include "AssetAtlas.h"
 #include "DeferredDisplayList.h"
 #include "DisplayListRenderer.h"
+#include "RenderState.h"
 #include "UvMapper.h"
 #include "utils/LinearAllocator.h"
 
@@ -647,24 +648,17 @@
     DrawBitmapOp(const SkBitmap* bitmap, const SkPaint* paint)
             : DrawBoundedOp(0, 0, bitmap->width(), bitmap->height(), paint)
             , mBitmap(bitmap)
-            , mAtlas(Caches::getInstance().assetAtlas) {
-        mEntry = mAtlas.getEntry(bitmap);
-        if (mEntry) {
-            mEntryGenerationId = mAtlas.getGenerationId();
-            mUvMapper = mEntry->uvMapper;
-        }
+            , mEntryValid(false), mEntry(NULL) {
     }
 
     virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
         return renderer.drawBitmap(mBitmap, getPaint(renderer));
     }
 
-    AssetAtlas::Entry* getAtlasEntry() {
-        // The atlas entry is stale, let's get a new one
-        if (mEntry && mEntryGenerationId != mAtlas.getGenerationId()) {
-            mEntryGenerationId = mAtlas.getGenerationId();
-            mEntry = mAtlas.getEntry(mBitmap);
-            mUvMapper = mEntry->uvMapper;
+    AssetAtlas::Entry* getAtlasEntry(OpenGLRenderer& renderer) {
+        if (!mEntryValid) {
+            mEntryValid = true;
+            mEntry = renderer.renderState().assetAtlas().getEntry(mBitmap);
         }
         return mEntry;
     }
@@ -700,7 +694,7 @@
             pureTranslate &= state.mMatrix.isPureTranslate();
 
             Rect texCoords(0, 0, 1, 1);
-            ((DrawBitmapOp*) ops[i].op)->mUvMapper.map(texCoords);
+            ((DrawBitmapOp*) ops[i].op)->uvMap(renderer, texCoords);
 
             SET_TEXTURE(vertex, opBounds, bounds, texCoords, left, top);
             SET_TEXTURE(vertex, opBounds, bounds, texCoords, right, top);
@@ -729,7 +723,7 @@
     virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
             const DeferredDisplayState& state) {
         deferInfo.batchId = DeferredDisplayList::kOpBatch_Bitmap;
-        deferInfo.mergeId = getAtlasEntry() ?
+        deferInfo.mergeId = getAtlasEntry(renderer) ?
                 (mergeid_t) mEntry->getMergeId() : (mergeid_t) mBitmap;
 
         // Don't merge non-simply transformed or neg scale ops, SET_TEXTURE doesn't handle rotation
@@ -742,13 +736,17 @@
                 (mBitmap->colorType() != kAlpha_8_SkColorType);
     }
 
+    void uvMap(OpenGLRenderer& renderer, Rect& texCoords) {
+        if (getAtlasEntry(renderer)) {
+            mEntry->uvMapper.map(texCoords);
+        }
+    }
+
     const SkBitmap* bitmap() { return mBitmap; }
 protected:
     const SkBitmap* mBitmap;
-    const AssetAtlas& mAtlas;
-    uint32_t mEntryGenerationId;
+    bool mEntryValid;
     AssetAtlas::Entry* mEntry;
-    UvMapper mUvMapper;
 };
 
 class DrawBitmapRectOp : public DrawBoundedOp {
@@ -841,18 +839,13 @@
             float left, float top, float right, float bottom, const SkPaint* paint)
             : DrawBoundedOp(left, top, right, bottom, paint),
             mBitmap(bitmap), mPatch(patch), mGenerationId(0), mMesh(NULL),
-            mAtlas(Caches::getInstance().assetAtlas) {
-        mEntry = mAtlas.getEntry(bitmap);
-        if (mEntry) {
-            mEntryGenerationId = mAtlas.getGenerationId();
-        }
+            mEntryValid(false), mEntry(NULL) {
     };
 
-    AssetAtlas::Entry* getAtlasEntry() {
-        // The atlas entry is stale, let's get a new one
-        if (mEntry && mEntryGenerationId != mAtlas.getGenerationId()) {
-            mEntryGenerationId = mAtlas.getGenerationId();
-            mEntry = mAtlas.getEntry(mBitmap);
+    AssetAtlas::Entry* getAtlasEntry(OpenGLRenderer& renderer) {
+        if (!mEntryValid) {
+            mEntryValid = true;
+            mEntry = renderer.renderState().assetAtlas().getEntry(mBitmap);
         }
         return mEntry;
     }
@@ -860,7 +853,7 @@
     const Patch* getMesh(OpenGLRenderer& renderer) {
         if (!mMesh || renderer.getCaches().patchCache.getGenerationId() != mGenerationId) {
             PatchCache& cache = renderer.getCaches().patchCache;
-            mMesh = cache.get(getAtlasEntry(), mBitmap->width(), mBitmap->height(),
+            mMesh = cache.get(getAtlasEntry(renderer), mBitmap->width(), mBitmap->height(),
                     mLocalBounds.getWidth(), mLocalBounds.getHeight(), mPatch);
             mGenerationId = cache.getGenerationId();
         }
@@ -942,14 +935,14 @@
             indexCount += opMesh->indexCount;
         }
 
-        return renderer.drawPatches(mBitmap, getAtlasEntry(),
+        return renderer.drawPatches(mBitmap, getAtlasEntry(renderer),
                 &vertices[0], indexCount, getPaint(renderer));
     }
 
     virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
         // We're not calling the public variant of drawPatch() here
         // This method won't perform the quickReject() since we've already done it at this point
-        return renderer.drawPatch(mBitmap, getMesh(renderer), getAtlasEntry(),
+        return renderer.drawPatch(mBitmap, getMesh(renderer), getAtlasEntry(renderer),
                 mLocalBounds.left, mLocalBounds.top, mLocalBounds.right, mLocalBounds.bottom,
                 getPaint(renderer));
     }
@@ -964,7 +957,7 @@
     virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
             const DeferredDisplayState& state) {
         deferInfo.batchId = DeferredDisplayList::kOpBatch_Patch;
-        deferInfo.mergeId = getAtlasEntry() ? (mergeid_t) mEntry->getMergeId() : (mergeid_t) mBitmap;
+        deferInfo.mergeId = getAtlasEntry(renderer) ? (mergeid_t) mEntry->getMergeId() : (mergeid_t) mBitmap;
         deferInfo.mergeable = state.mMatrix.isPureTranslate() &&
                 OpenGLRenderer::getXfermodeDirect(mPaint) == SkXfermode::kSrcOver_Mode;
         deferInfo.opaqueOverBounds = isOpaqueOverBounds(state) && mBitmap->isOpaque();
@@ -977,8 +970,7 @@
     uint32_t mGenerationId;
     const Patch* mMesh;
 
-    const AssetAtlas& mAtlas;
-    uint32_t mEntryGenerationId;
+    bool mEntryValid;
     AssetAtlas::Entry* mEntry;
 };
 
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 96257e4..7285496 100755
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -2054,7 +2054,7 @@
     }
 
     mCaches.activeTexture(0);
-    Texture* texture = mCaches.assetAtlas.getEntryTexture(bitmap);
+    Texture* texture = mRenderState.assetAtlas().getEntryTexture(bitmap);
     const UvMapper& mapper(getMapper(texture));
 
     for (int32_t y = 0; y < meshHeight; y++) {
@@ -2237,7 +2237,7 @@
         return DrawGlInfo::kStatusDone;
     }
 
-    AssetAtlas::Entry* entry = mCaches.assetAtlas.getEntry(bitmap);
+    AssetAtlas::Entry* entry = mRenderState.assetAtlas().getEntry(bitmap);
     const Patch* mesh = mCaches.patchCache.get(entry, bitmap->width(), bitmap->height(),
             right - left, bottom - top, patch);
 
@@ -3033,7 +3033,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 Texture* OpenGLRenderer::getTexture(const SkBitmap* bitmap) {
-    Texture* texture = mCaches.assetAtlas.getEntryTexture(bitmap);
+    Texture* texture = mRenderState.assetAtlas().getEntryTexture(bitmap);
     if (!texture) {
         return mCaches.textureCache.get(bitmap);
     }
diff --git a/libs/hwui/RenderState.cpp b/libs/hwui/RenderState.cpp
index a8cf26f..d1f5f4e 100644
--- a/libs/hwui/RenderState.cpp
+++ b/libs/hwui/RenderState.cpp
@@ -38,6 +38,7 @@
     mCaches = &Caches::getInstance();
     mCaches->init();
     mCaches->setRenderState(this);
+    mCaches->textureCache.setAssetAtlas(&mAssetAtlas);
 }
 
 void RenderState::onGLContextDestroyed() {
@@ -72,6 +73,7 @@
         LOG_ALWAYS_FATAL("%d layers have survived gl context destruction", size);
     }
 */
+    mAssetAtlas.terminate();
 }
 
 void RenderState::setViewport(GLsizei width, GLsizei height) {
diff --git a/libs/hwui/RenderState.h b/libs/hwui/RenderState.h
index afeef95..1ecfb1c 100644
--- a/libs/hwui/RenderState.h
+++ b/libs/hwui/RenderState.h
@@ -23,6 +23,7 @@
 
 #include <private/hwui/DrawGlInfo.h>
 
+#include "AssetAtlas.h"
 #include "Caches.h"
 #include "utils/Macros.h"
 
@@ -73,6 +74,8 @@
     // more thinking...
     void postDecStrong(VirtualLightRefBase* object);
 
+    AssetAtlas& assetAtlas() { return mAssetAtlas; }
+
 private:
     friend class renderthread::RenderThread;
     friend class Caches;
@@ -86,6 +89,7 @@
 
     renderthread::RenderThread& mRenderThread;
     Caches* mCaches;
+    AssetAtlas mAssetAtlas;
     std::set<const Layer*> mActiveLayers;
     std::set<renderthread::CanvasContext*> mRegisteredContexts;
 
diff --git a/libs/hwui/TextureCache.cpp b/libs/hwui/TextureCache.cpp
index 5bad2fc..63454d8 100644
--- a/libs/hwui/TextureCache.cpp
+++ b/libs/hwui/TextureCache.cpp
@@ -24,6 +24,7 @@
 
 #include <utils/Mutex.h>
 
+#include "AssetAtlas.h"
 #include "Caches.h"
 #include "TextureCache.h"
 #include "Properties.h"
@@ -39,7 +40,7 @@
 TextureCache::TextureCache():
         mCache(LruCache<uint32_t, Texture*>::kUnlimitedCapacity),
         mSize(0), mMaxSize(MB(DEFAULT_TEXTURE_CACHE_SIZE)),
-        mFlushRate(DEFAULT_TEXTURE_CACHE_FLUSH_RATE) {
+        mFlushRate(DEFAULT_TEXTURE_CACHE_FLUSH_RATE), mAssetAtlas(0) {
     char property[PROPERTY_VALUE_MAX];
     if (property_get(PROPERTY_TEXTURE_CACHE_SIZE, property, NULL) > 0) {
         INIT_LOGD("  Setting texture cache size to %sMB", property);
@@ -62,7 +63,7 @@
 
 TextureCache::TextureCache(uint32_t maxByteSize):
         mCache(LruCache<uint32_t, Texture*>::kUnlimitedCapacity),
-        mSize(0), mMaxSize(maxByteSize) {
+        mSize(0), mMaxSize(maxByteSize), mAssetAtlas(0) {
     init();
 }
 
@@ -124,6 +125,10 @@
 // Caching
 ///////////////////////////////////////////////////////////////////////////////
 
+void TextureCache::setAssetAtlas(AssetAtlas* assetAtlas) {
+    mAssetAtlas = assetAtlas;
+}
+
 void TextureCache::resetMarkInUse() {
     LruCache<uint32_t, Texture*>::Iterator iter(mCache);
     while (iter.next()) {
@@ -143,6 +148,13 @@
 // Returns a prepared Texture* that either is already in the cache or can fit
 // in the cache (and is thus added to the cache)
 Texture* TextureCache::getCachedTexture(const SkBitmap* bitmap) {
+    if (CC_LIKELY(mAssetAtlas)) {
+        AssetAtlas::Entry* entry = mAssetAtlas->getEntry(bitmap);
+        if (CC_UNLIKELY(entry)) {
+            return entry->texture;
+        }
+    }
+
     Texture* texture = mCache.get(bitmap->pixelRef()->getStableID());
 
     if (!texture) {
diff --git a/libs/hwui/TextureCache.h b/libs/hwui/TextureCache.h
index 3e94d1f..cf8d134 100644
--- a/libs/hwui/TextureCache.h
+++ b/libs/hwui/TextureCache.h
@@ -44,6 +44,8 @@
 // Classes
 ///////////////////////////////////////////////////////////////////////////////
 
+class AssetAtlas;
+
 /**
  * A simple LRU texture cache. The cache has a maximum size expressed in bytes.
  * Any texture added to the cache causing the cache to grow beyond the maximum
@@ -123,6 +125,8 @@
      */
     void setFlushRate(float flushRate);
 
+    void setAssetAtlas(AssetAtlas* assetAtlas);
+
 private:
 
     bool canMakeTextureFromBitmap(const SkBitmap* bitmap);
@@ -155,6 +159,8 @@
 
     Vector<uint32_t> mGarbage;
     mutable Mutex mLock;
+
+    AssetAtlas* mAssetAtlas;
 }; // class TextureCache
 
 }; // namespace uirenderer
diff --git a/libs/hwui/renderthread/EglManager.cpp b/libs/hwui/renderthread/EglManager.cpp
index 378cf61..8fb1b10 100644
--- a/libs/hwui/renderthread/EglManager.cpp
+++ b/libs/hwui/renderthread/EglManager.cpp
@@ -175,7 +175,8 @@
 
 void EglManager::initAtlas() {
     if (mAtlasBuffer.get()) {
-        Caches::getInstance().assetAtlas.init(mAtlasBuffer, mAtlasMap, mAtlasMapSize);
+        mRenderThread.renderState().assetAtlas().init(mAtlasBuffer,
+                mAtlasMap, mAtlasMapSize);
     }
 }
 
diff --git a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
index 1c7b033..7253579 100644
--- a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
+++ b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
@@ -23,12 +23,10 @@
 import android.graphics.Bitmap;
 import android.net.ConnectivityManager;
 import android.net.ConnectivityManager.NetworkCallback;
-import android.net.LinkProperties;
 import android.net.Network;
 import android.net.NetworkCapabilities;
 import android.net.NetworkRequest;
 import android.net.Proxy;
-import android.net.ProxyInfo;
 import android.net.Uri;
 import android.os.Bundle;
 import android.provider.Settings;
@@ -96,26 +94,10 @@
             done(CAPTIVE_PORTAL_APP_RETURN_WANTED_AS_IS);
         }
 
+        final ConnectivityManager cm = ConnectivityManager.from(this);
         final Network network = new Network(mNetId);
-        ConnectivityManager.setProcessDefaultNetwork(network);
-
-        // Set HTTP proxy system properties to those of the selected Network.
-        final LinkProperties lp = ConnectivityManager.from(this).getLinkProperties(network);
-        if (lp != null) {
-            final ProxyInfo proxyInfo = lp.getHttpProxy();
-            String host = "";
-            String port = "";
-            String exclList = "";
-            Uri pacFileUrl = Uri.EMPTY;
-            if (proxyInfo != null) {
-                host = proxyInfo.getHost();
-                port = Integer.toString(proxyInfo.getPort());
-                exclList = proxyInfo.getExclusionListAsString();
-                pacFileUrl = proxyInfo.getPacFileUrl();
-            }
-            Proxy.setHttpProxySystemProperty(host, port, exclList, pacFileUrl);
-            Log.v(TAG, "Set proxy system properties to " + proxyInfo);
-        }
+        // Also initializes proxy system properties.
+        cm.setProcessDefaultNetwork(network);
 
         // Proxy system properties must be initialized before setContentView is called because
         // setContentView initializes the WebView logic which in turn reads the system properties.
@@ -124,8 +106,7 @@
         getActionBar().setDisplayShowHomeEnabled(false);
 
         // Exit app if Network disappears.
-        final NetworkCapabilities networkCapabilities =
-                ConnectivityManager.from(this).getNetworkCapabilities(network);
+        final NetworkCapabilities networkCapabilities = cm.getNetworkCapabilities(network);
         if (networkCapabilities == null) {
             finish();
             return;
@@ -140,7 +121,7 @@
         for (int transportType : networkCapabilities.getTransportTypes()) {
             builder.addTransportType(transportType);
         }
-        ConnectivityManager.from(this).registerNetworkCallback(builder.build(), mNetworkCallback);
+        cm.registerNetworkCallback(builder.build(), mNetworkCallback);
 
         final WebView myWebView = (WebView) findViewById(R.id.webview);
         myWebView.clearCache(true);
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java
index 3212eec..0dfe1dc 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java
@@ -370,6 +370,7 @@
             final Runnable finishListener) {
         if (appearing) {
             animatedCell.scale = 0.0f;
+            animatedCell.alpha = 1.0f;
         }
         animatedCell.translateY = appearing ? translationY : 0;
         ValueAnimator animator = ValueAnimator.ofFloat(animatedCell.translateY,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
index 7b60307..465a141 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
@@ -25,8 +25,6 @@
 import android.graphics.BitmapShader;
 import android.graphics.Canvas;
 import android.graphics.Color;
-import android.graphics.ColorMatrix;
-import android.graphics.ColorMatrixColorFilter;
 import android.graphics.Paint;
 import android.graphics.PorterDuff;
 import android.graphics.PorterDuffColorFilter;
@@ -43,7 +41,6 @@
 import android.view.animation.PathInterpolator;
 
 import com.android.systemui.R;
-import com.android.systemui.statusbar.phone.NotificationPanelView;
 
 /**
  * Base class for both {@link ExpandableNotificationRow} and {@link NotificationOverflowContainer}
@@ -355,11 +352,14 @@
             if (mActivated) {
                 mBackgroundDimmed.setVisibility(View.VISIBLE);
                 mBackgroundNormal.setVisibility(View.VISIBLE);
-            } else {
+            } else if (mDimmed) {
                 mBackgroundDimmed.setVisibility(View.VISIBLE);
                 mBackgroundNormal.setVisibility(View.INVISIBLE);
+            } else {
+                mBackgroundDimmed.setVisibility(View.INVISIBLE);
+                mBackgroundNormal.setVisibility(View.VISIBLE);
             }
-            fadeDarkToDimmed(delay);
+            fadeInFromDark(delay);
         } else {
             updateBackground();
         }
@@ -401,15 +401,16 @@
     }
 
     /**
-     * Fades the dimmed background when exiting dark mode.
+     * Fades in the background when exiting dark mode.
      */
-    private void fadeDarkToDimmed(long delay) {
-        mBackgroundDimmed.setAlpha(0f);
-        mBackgroundDimmed.setPivotX(mBackgroundDimmed.getWidth() / 2f);
-        mBackgroundDimmed.setPivotY(getActualHeight() / 2f);
-        mBackgroundDimmed.setScaleX(DARK_EXIT_SCALE_START);
-        mBackgroundDimmed.setScaleY(DARK_EXIT_SCALE_START);
-        mBackgroundDimmed.animate()
+    private void fadeInFromDark(long delay) {
+        final View background = mDimmed ? mBackgroundDimmed : mBackgroundNormal;
+        background.setAlpha(0f);
+        background.setPivotX(mBackgroundDimmed.getWidth() / 2f);
+        background.setPivotY(getActualHeight() / 2f);
+        background.setScaleX(DARK_EXIT_SCALE_START);
+        background.setScaleY(DARK_EXIT_SCALE_START);
+        background.animate()
                 .alpha(1f)
                 .scaleX(1f)
                 .scaleY(1f)
@@ -420,9 +421,9 @@
                     @Override
                     public void onAnimationCancel(Animator animation) {
                         // Jump state if we are cancelled
-                        mBackgroundDimmed.setScaleX(1f);
-                        mBackgroundDimmed.setScaleY(1f);
-                        mBackgroundDimmed.setAlpha(1f);
+                        background.setScaleX(1f);
+                        background.setScaleY(1f);
+                        background.setAlpha(1f);
                     }
                 })
                 .start();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java
index 076cfe2..229c558 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java
@@ -289,9 +289,11 @@
                         .getDevicesMatchingConnectionStates(connectionType);
                 for (int k = 0; k < devices.size(); k++) {
                     DeviceInfo info = mDeviceInfo.get(devices.get(k));
-                    info.connectionState = CONNECTION_STATES[i];
-                    if (CONNECTION_STATES[i] == BluetoothProfile.STATE_CONNECTED) {
-                        info.connectedProfiles.put(profile, true);
+                    if (info != null) {
+                        info.connectionState = CONNECTION_STATES[i];
+                        if (CONNECTION_STATES[i] == BluetoothProfile.STATE_CONNECTED) {
+                            info.connectedProfiles.put(profile, true);
+                        }
                     }
                 }
             }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index 2a393bf..6dcbed6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -2280,8 +2280,7 @@
                 updateContentHeight();
                 notifyHeightChangeListener(mDismissView);
             } else {
-                mEmptyShadeView.setWillBeGone(true);
-                mEmptyShadeView.performVisibilityAnimation(false, new Runnable() {
+                Runnable onFinishedRunnable = new Runnable() {
                     @Override
                     public void run() {
                         mEmptyShadeView.setVisibility(GONE);
@@ -2289,7 +2288,14 @@
                         updateContentHeight();
                         notifyHeightChangeListener(mDismissView);
                     }
-                });
+                };
+                if (mAnimationsEnabled) {
+                    mEmptyShadeView.setWillBeGone(true);
+                    mEmptyShadeView.performVisibilityAnimation(false, onFinishedRunnable);
+                } else {
+                    mEmptyShadeView.setInvisible();
+                    onFinishedRunnable.run();
+                }
             }
         }
     }
@@ -2318,7 +2324,7 @@
                         notifyHeightChangeListener(mDismissView);
                     }
                 };
-                if (mDismissView.isButtonVisible() && mIsExpanded) {
+                if (mDismissView.isButtonVisible() && mIsExpanded && mAnimationsEnabled) {
                     mDismissView.setWillBeGone(true);
                     mDismissView.performVisibilityAnimation(false, dimissHideFinishRunnable);
                 } else {
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index e11fa93..499cff3 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -2585,7 +2585,7 @@
         }
     }
 
-    public ProxyInfo getProxy() {
+    public ProxyInfo getDefaultProxy() {
         // this information is already available as a world read/writable jvm property
         // so this API change wouldn't have a benifit.  It also breaks the passing
         // of proxy info to all the JVMs.
@@ -2597,6 +2597,34 @@
         }
     }
 
+    // Convert empty ProxyInfo's to null as null-checks are used to determine if proxies are present
+    // (e.g. if mGlobalProxy==null fall back to network-specific proxy, if network-specific
+    // proxy is null then there is no proxy in place).
+    private ProxyInfo canonicalizeProxyInfo(ProxyInfo proxy) {
+        if (proxy != null && TextUtils.isEmpty(proxy.getHost())
+                && (proxy.getPacFileUrl() == null || Uri.EMPTY.equals(proxy.getPacFileUrl()))) {
+            proxy = null;
+        }
+        return proxy;
+    }
+
+    // ProxyInfo equality function with a couple modifications over ProxyInfo.equals() to make it
+    // better for determining if a new proxy broadcast is necessary:
+    // 1. Canonicalize empty ProxyInfos to null so an empty proxy compares equal to null so as to
+    //    avoid unnecessary broadcasts.
+    // 2. Make sure all parts of the ProxyInfo's compare true, including the host when a PAC URL
+    //    is in place.  This is important so legacy PAC resolver (see com.android.proxyhandler)
+    //    changes aren't missed.  The legacy PAC resolver pretends to be a simple HTTP proxy but
+    //    actually uses the PAC to resolve; this results in ProxyInfo's with PAC URL, host and port
+    //    all set.
+    private boolean proxyInfoEqual(ProxyInfo a, ProxyInfo b) {
+        a = canonicalizeProxyInfo(a);
+        b = canonicalizeProxyInfo(b);
+        // ProxyInfo.equals() doesn't check hosts when PAC URLs are present, but we need to check
+        // hosts even when PAC URLs are present to account for the legacy PAC resolver.
+        return Objects.equals(a, b) && (a == null || Objects.equals(a.getHost(), b.getHost()));
+    }
+
     public void setGlobalProxy(ProxyInfo proxyProperties) {
         enforceConnectivityInternalPermission();
 
@@ -2714,6 +2742,20 @@
         }
     }
 
+    // If the proxy has changed from oldLp to newLp, resend proxy broadcast with default proxy.
+    // This method gets called when any network changes proxy, but the broadcast only ever contains
+    // the default proxy (even if it hasn't changed).
+    // TODO: Deprecate the broadcast extras as they aren't necessarily applicable in a multi-network
+    // world where an app might be bound to a non-default network.
+    private void updateProxy(LinkProperties newLp, LinkProperties oldLp, NetworkAgentInfo nai) {
+        ProxyInfo newProxyInfo = newLp == null ? null : newLp.getHttpProxy();
+        ProxyInfo oldProxyInfo = oldLp == null ? null : oldLp.getHttpProxy();
+
+        if (!proxyInfoEqual(newProxyInfo, oldProxyInfo)) {
+            sendProxyBroadcast(getDefaultProxy());
+        }
+    }
+
     private void handleDeprecatedGlobalHttpProxy() {
         String proxy = Settings.Global.getString(mContext.getContentResolver(),
                 Settings.Global.HTTP_PROXY);
@@ -3627,7 +3669,11 @@
         updateDnses(newLp, oldLp, netId, flushDns, useDefaultDns);
 
         updateClat(newLp, oldLp, networkAgent);
-        if (isDefaultNetwork(networkAgent)) handleApplyDefaultProxy(newLp.getHttpProxy());
+        if (isDefaultNetwork(networkAgent)) {
+            handleApplyDefaultProxy(newLp.getHttpProxy());
+        } else {
+            updateProxy(newLp, oldLp, networkAgent);
+        }
         // TODO - move this check to cover the whole function
         if (!Objects.equals(newLp, oldLp)) {
             notifyIfacesChanged();
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 844980b..c0fc890 100755
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -4657,9 +4657,11 @@
             stats.noteProcessDiedLocked(app.info.uid, pid);
         }
 
-        Process.killProcessQuiet(pid);
-        Process.killProcessGroup(app.info.uid, pid);
-        app.killed = true;
+        if (!app.killed) {
+            Process.killProcessQuiet(pid);
+            Process.killProcessGroup(app.info.uid, pid);
+            app.killed = true;
+        }
 
         // Clean up already done if the process has been re-started.
         if (app.pid == pid && app.thread != null &&
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index 31d5cd7..0f9a59b 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -347,7 +347,10 @@
                 break;
             case AudioManager.RINGER_MODE_VIBRATE:
             case AudioManager.RINGER_MODE_NORMAL:
-                if (mZenMode != Global.ZEN_MODE_OFF) {
+                if (isChange && ringerModeOld == AudioManager.RINGER_MODE_SILENT
+                        && mZenMode == Global.ZEN_MODE_NO_INTERRUPTIONS) {
+                    newZen = Global.ZEN_MODE_OFF;
+                } else if (mZenMode != Global.ZEN_MODE_OFF) {
                     ringerModeExternalOut = AudioManager.RINGER_MODE_SILENT;
                 }
                 break;
diff --git a/telephony/java/com/android/ims/ImsCallProfile.java b/telephony/java/com/android/ims/ImsCallProfile.java
index 9de938a..8740e19 100644
--- a/telephony/java/com/android/ims/ImsCallProfile.java
+++ b/telephony/java/com/android/ims/ImsCallProfile.java
@@ -269,6 +269,7 @@
     public String toString() {
         return "{ serviceType=" + mServiceType +
                 ", callType=" + mCallType +
+                ", restrictCause=" + mRestrictCause +
                 ", callExtras=" + mCallExtras.toString() +
                 ", mediaProfile=" + mMediaProfile.toString() + " }";
     }