Merge "Force-flush state sync on texid change" into lmp-mr1-dev
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/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/widget/RadialTimePickerView.java b/core/java/android/widget/RadialTimePickerView.java
index 75c6184..7b64cf5 100644
--- a/core/java/android/widget/RadialTimePickerView.java
+++ b/core/java/android/widget/RadialTimePickerView.java
@@ -1456,6 +1456,32 @@
 
             final boolean selected = isVirtualViewSelected(type, value);
             node.setSelected(selected);
+
+            final int nextId = getVirtualViewIdAfter(type, value);
+            if (nextId != INVALID_ID) {
+                node.setTraversalBefore(RadialTimePickerView.this, nextId);
+            }
+        }
+
+        private int getVirtualViewIdAfter(int type, int value) {
+            if (type == TYPE_HOUR) {
+                final int nextValue = value + 1;
+                final int max = mIs24HourMode ? 23 : 12;
+                if (nextValue <= max) {
+                    return makeId(type, nextValue);
+                }
+            } else if (type == TYPE_MINUTE) {
+                final int current = getCurrentMinute();
+                final int snapValue = value - (value % MINUTE_INCREMENT);
+                final int nextValue = snapValue + MINUTE_INCREMENT;
+                if (value < current && nextValue > current) {
+                    // The current value is between two snap values.
+                    return makeId(type, current);
+                } else if (nextValue < 60) {
+                    return makeId(type, nextValue);
+                }
+            }
+            return INVALID_ID;
         }
 
         @Override
diff --git a/core/java/android/widget/TimePickerClockDelegate.java b/core/java/android/widget/TimePickerClockDelegate.java
index d61b6fc..8d475a7 100644
--- a/core/java/android/widget/TimePickerClockDelegate.java
+++ b/core/java/android/widget/TimePickerClockDelegate.java
@@ -33,9 +33,11 @@
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.View;
+import android.view.View.AccessibilityDelegate;
 import android.view.ViewGroup;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
 
 import com.android.internal.R;
 
@@ -136,9 +138,13 @@
         // Set up hour/minute labels.
         mHourView = (TextView) mHeaderView.findViewById(R.id.hours);
         mHourView.setOnClickListener(mClickListener);
+        mHourView.setAccessibilityDelegate(
+                new ClickActionDelegate(context, R.string.select_hours));
         mSeparatorView = (TextView) mHeaderView.findViewById(R.id.separator);
         mMinuteView = (TextView) mHeaderView.findViewById(R.id.minutes);
         mMinuteView.setOnClickListener(mClickListener);
+        mMinuteView.setAccessibilityDelegate(
+                new ClickActionDelegate(context, R.string.select_minutes));
 
         final int headerTimeTextAppearance = a.getResourceId(
                 R.styleable.TimePicker_headerTimeTextAppearance, 0);
@@ -206,6 +212,22 @@
         initialize(currentHour, currentMinute, false /* 12h */, HOUR_INDEX);
     }
 
+    private static class ClickActionDelegate extends AccessibilityDelegate {
+        private final AccessibilityAction mClickAction;
+
+        public ClickActionDelegate(Context context, int resId) {
+            mClickAction = new AccessibilityAction(
+                    AccessibilityNodeInfo.ACTION_CLICK, context.getString(resId));
+        }
+
+        @Override
+        public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
+            super.onInitializeAccessibilityNodeInfo(host, info);
+
+            info.addAction(mClickAction);
+        }
+    }
+
     private int computeStableWidth(TextView v, int maxNumber) {
         int maxWidth = 0;
 
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 ecc8d9d..48e512d 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1975,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 d8c5f2c..2dcf5bd 100755
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2147,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..3de5c3c 100644
--- a/docs/html/about/versions/android-5.0-changes.jd
+++ b/docs/html/about/versions/android-5.0-changes.jd
@@ -1,9 +1,10 @@
-page.title=Android 5.0 Changes
+page.title=Android 5.0 Behavior Changes
 excludeFromSuggestions=true
 sdk.platform.version=5.0
 sdk.platform.apiLevel=21
 @jd:body
 
+<!-- video box -->
 
 <div id="qv-wrapper">
 <div id="qv">
@@ -20,8 +21,16 @@
   <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>
 
+<a class="notice-developers-video" href="https://www.youtube.com/watch?v=Uiq2kZ2JHVY">
+<div>
+    <h3>Video</h3>
+    <p>Notifications</p>
+</div>
+</a>
+
 <h2>API Differences</h2>
 <ol>
 <li><a href="{@docRoot}sdk/api_diff/21/changes.html">API level 20 to 21 &raquo;</a> </li>
@@ -40,9 +49,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
@@ -296,8 +304,8 @@
 
 <p>
   Android 5.0 includes a behavior change to ensure
-  that only one app can define a given custom permission, unless signed with the 
-  same key as other apps defining the permission. 
+  that only one app can define a given custom permission, unless signed with the
+  same key as other apps defining the permission.
 </p>
 
 <h3>
@@ -316,7 +324,7 @@
 <p>
   In Android 4.4 and earlier, users were able to install multiple such
   apps on a given device, although the system assigned the protection level
-  specified by the first-installed app. 
+  specified by the first-installed app.
 </p>
 
 <p>
@@ -522,4 +530,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/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/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/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/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index 810e487..787ee62 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -429,9 +429,9 @@
                 clipFlags = 0; // all clipping done by saveLayer
             }
 
-            ATRACE_FORMAT("%s alpha caused %ssaveLayer %ux%u",
+            ATRACE_FORMAT("%s alpha caused %ssaveLayer %dx%d",
                     getName(), clipFlags ? "" : "unclipped ",
-                    layerBounds.getWidth(), layerBounds.getHeight());
+                    (int)layerBounds.getWidth(), (int)layerBounds.getHeight());
 
             SaveLayerOp* op = new (handler.allocator()) SaveLayerOp(
                     layerBounds.left, layerBounds.top, layerBounds.right, layerBounds.bottom,
diff --git a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
index 09a6ccc..3e6611a 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
@@ -111,14 +111,23 @@
         public void run() {
             RecentsConfiguration config = RecentsConfiguration.getInstance();
             if (config.svelteLevel == RecentsConfiguration.SVELTE_NONE) {
+                ActivityManager.RunningTaskInfo runningTaskInfo = getTopMostTask();
+
                 // Load the next task only if we aren't svelte
                 RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
                 RecentsTaskLoadPlan plan = loader.createLoadPlan(mContext);
                 loader.preloadTasks(plan, true /* isTopTaskHome */);
                 RecentsTaskLoadPlan.Options launchOpts = new RecentsTaskLoadPlan.Options();
-                launchOpts.numVisibleTasks = 1;
-                launchOpts.numVisibleTaskThumbnails = 1;
+                // This callback is made when a new activity is launched and the old one is paused
+                // so ignore the current activity and try and preload the thumbnail for the
+                // previous one.
+                if (runningTaskInfo != null) {
+                    launchOpts.runningTaskId = runningTaskInfo.id;
+                }
+                launchOpts.numVisibleTasks = 2;
+                launchOpts.numVisibleTaskThumbnails = 2;
                 launchOpts.onlyLoadForCache = true;
+                launchOpts.onlyLoadPausedActivities = true;
                 loader.loadTasks(mContext, plan, launchOpts);
             }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
index 0011811..0e1c01a 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
@@ -50,6 +50,7 @@
         public boolean loadIcons = true;
         public boolean loadThumbnails = true;
         public boolean onlyLoadForCache = false;
+        public boolean onlyLoadPausedActivities = false;
         public int numVisibleTasks = 0;
         public int numVisibleTaskThumbnails = 0;
     }
@@ -141,6 +142,7 @@
                     activityColor, (i == (taskCount - 1)), mConfig.lockToAppEnabled, icon,
                     iconFilename);
             task.thumbnail = loader.getAndUpdateThumbnail(taskKey, mSystemServicesProxy, false);
+            if (DEBUG) Log.d(TAG, "\tthumbnail: " + taskKey + ", " + task.thumbnail);
             loadedTasks.add(task);
         }
         mStack.setTasks(loadedTasks);
@@ -186,6 +188,11 @@
             boolean isVisibleTask = i >= (taskCount - opts.numVisibleTasks);
             boolean isVisibleThumbnail = i >= (taskCount - opts.numVisibleTaskThumbnails);
 
+            // If requested, skip the running task
+            if (opts.onlyLoadPausedActivities && isRunningTask) {
+                continue;
+            }
+
             if (opts.loadIcons && (isRunningTask || isVisibleTask)) {
                 if (task.activityIcon == null) {
                     if (DEBUG) Log.d(TAG, "\tLoading icon: " + taskKey);
@@ -194,7 +201,7 @@
                 }
             }
             if (opts.loadThumbnails && (isRunningTask || isVisibleThumbnail)) {
-                if (task.thumbnail == null) {
+                if (task.thumbnail == null || isRunningTask) {
                     if (DEBUG) Log.d(TAG, "\tLoading thumbnail: " + taskKey);
                     if (mConfig.svelteLevel <= RecentsConfiguration.SVELTE_LIMIT_CACHE) {
                         task.thumbnail = loader.getAndUpdateThumbnail(taskKey, mSystemServicesProxy,
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/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/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index fe2e0a6..64713d9 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -355,7 +355,8 @@
                         boolean applyExistingExitAnimation = mPostKeyguardExitAnimation != null
                                 && !winAnimator.mKeyguardGoingAwayAnimation
                                 && win.hasDrawnLw()
-                                && win.mAttachedWindow == null;
+                                && win.mAttachedWindow == null
+                                && mForceHiding != KEYGUARD_NOT_SHOWN;
 
                         // If the window is already showing and we don't need to apply an existing
                         // Keyguard exit animation, skip.