Merge "Import translations. DO NOT MERGE"
diff --git a/api/current.txt b/api/current.txt
index 7ebabe4..42b1e18 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -11637,6 +11637,12 @@
     field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_AVAILABLE_TEST_PATTERN_MODES;
     field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_BASE_GAIN_FACTOR;
     field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_BLACK_LEVEL_PATTERN;
+    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_CALIBRATION_TRANSFORM1;
+    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_CALIBRATION_TRANSFORM2;
+    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_COLOR_TRANSFORM1;
+    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_COLOR_TRANSFORM2;
+    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_FORWARD_MATRIX1;
+    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_FORWARD_MATRIX2;
     field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_INFO_ACTIVE_ARRAY_SIZE;
     field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_INFO_COLOR_FILTER_ARRANGEMENT;
     field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_INFO_EXPOSURE_TIME_RANGE;
@@ -11648,6 +11654,8 @@
     field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_MAX_ANALOG_SENSITIVITY;
     field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_ORIENTATION;
     field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_PROFILE_HUE_SAT_MAP_DIMENSIONS;
+    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_REFERENCE_ILLUMINANT1;
+    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_REFERENCE_ILLUMINANT2;
     field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES;
     field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES;
     field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_INFO_MAX_FACE_COUNT;
@@ -11841,25 +11849,25 @@
     field public static final int SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_GRBG = 1; // 0x1
     field public static final int SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_RGB = 4; // 0x4
     field public static final int SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_RGGB = 0; // 0x0
-    field public static final int SENSOR_REFERENCE_ILLUMINANT_CLOUDY_WEATHER = 10; // 0xa
-    field public static final int SENSOR_REFERENCE_ILLUMINANT_COOL_WHITE_FLUORESCENT = 14; // 0xe
-    field public static final int SENSOR_REFERENCE_ILLUMINANT_D50 = 23; // 0x17
-    field public static final int SENSOR_REFERENCE_ILLUMINANT_D55 = 20; // 0x14
-    field public static final int SENSOR_REFERENCE_ILLUMINANT_D65 = 21; // 0x15
-    field public static final int SENSOR_REFERENCE_ILLUMINANT_D75 = 22; // 0x16
-    field public static final int SENSOR_REFERENCE_ILLUMINANT_DAYLIGHT = 1; // 0x1
-    field public static final int SENSOR_REFERENCE_ILLUMINANT_DAYLIGHT_FLUORESCENT = 12; // 0xc
-    field public static final int SENSOR_REFERENCE_ILLUMINANT_DAY_WHITE_FLUORESCENT = 13; // 0xd
-    field public static final int SENSOR_REFERENCE_ILLUMINANT_FINE_WEATHER = 9; // 0x9
-    field public static final int SENSOR_REFERENCE_ILLUMINANT_FLASH = 4; // 0x4
-    field public static final int SENSOR_REFERENCE_ILLUMINANT_FLUORESCENT = 2; // 0x2
-    field public static final int SENSOR_REFERENCE_ILLUMINANT_ISO_STUDIO_TUNGSTEN = 24; // 0x18
-    field public static final int SENSOR_REFERENCE_ILLUMINANT_SHADE = 11; // 0xb
-    field public static final int SENSOR_REFERENCE_ILLUMINANT_STANDARD_A = 17; // 0x11
-    field public static final int SENSOR_REFERENCE_ILLUMINANT_STANDARD_B = 18; // 0x12
-    field public static final int SENSOR_REFERENCE_ILLUMINANT_STANDARD_C = 19; // 0x13
-    field public static final int SENSOR_REFERENCE_ILLUMINANT_TUNGSTEN = 3; // 0x3
-    field public static final int SENSOR_REFERENCE_ILLUMINANT_WHITE_FLUORESCENT = 15; // 0xf
+    field public static final int SENSOR_REFERENCE_ILLUMINANT1_CLOUDY_WEATHER = 10; // 0xa
+    field public static final int SENSOR_REFERENCE_ILLUMINANT1_COOL_WHITE_FLUORESCENT = 14; // 0xe
+    field public static final int SENSOR_REFERENCE_ILLUMINANT1_D50 = 23; // 0x17
+    field public static final int SENSOR_REFERENCE_ILLUMINANT1_D55 = 20; // 0x14
+    field public static final int SENSOR_REFERENCE_ILLUMINANT1_D65 = 21; // 0x15
+    field public static final int SENSOR_REFERENCE_ILLUMINANT1_D75 = 22; // 0x16
+    field public static final int SENSOR_REFERENCE_ILLUMINANT1_DAYLIGHT = 1; // 0x1
+    field public static final int SENSOR_REFERENCE_ILLUMINANT1_DAYLIGHT_FLUORESCENT = 12; // 0xc
+    field public static final int SENSOR_REFERENCE_ILLUMINANT1_DAY_WHITE_FLUORESCENT = 13; // 0xd
+    field public static final int SENSOR_REFERENCE_ILLUMINANT1_FINE_WEATHER = 9; // 0x9
+    field public static final int SENSOR_REFERENCE_ILLUMINANT1_FLASH = 4; // 0x4
+    field public static final int SENSOR_REFERENCE_ILLUMINANT1_FLUORESCENT = 2; // 0x2
+    field public static final int SENSOR_REFERENCE_ILLUMINANT1_ISO_STUDIO_TUNGSTEN = 24; // 0x18
+    field public static final int SENSOR_REFERENCE_ILLUMINANT1_SHADE = 11; // 0xb
+    field public static final int SENSOR_REFERENCE_ILLUMINANT1_STANDARD_A = 17; // 0x11
+    field public static final int SENSOR_REFERENCE_ILLUMINANT1_STANDARD_B = 18; // 0x12
+    field public static final int SENSOR_REFERENCE_ILLUMINANT1_STANDARD_C = 19; // 0x13
+    field public static final int SENSOR_REFERENCE_ILLUMINANT1_TUNGSTEN = 3; // 0x3
+    field public static final int SENSOR_REFERENCE_ILLUMINANT1_WHITE_FLUORESCENT = 15; // 0xf
     field public static final int SENSOR_TEST_PATTERN_MODE_COLOR_BARS = 2; // 0x2
     field public static final int SENSOR_TEST_PATTERN_MODE_COLOR_BARS_FADE_TO_GRAY = 3; // 0x3
     field public static final int SENSOR_TEST_PATTERN_MODE_CUSTOM1 = 256; // 0x100
@@ -12009,16 +12017,12 @@
     field public static final android.hardware.camera2.CameraMetadata.Key REQUEST_FRAME_COUNT;
     field public static final android.hardware.camera2.CameraMetadata.Key REQUEST_PIPELINE_DEPTH;
     field public static final android.hardware.camera2.CameraMetadata.Key SCALER_CROP_REGION;
-    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_CALIBRATION_TRANSFORM;
-    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_COLOR_TRANSFORM;
     field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_EXPOSURE_TIME;
-    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_FORWARD_MATRIX;
     field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_FRAME_DURATION;
     field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_GREEN_SPLIT;
     field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_NEUTRAL_COLOR_POINT;
     field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_PROFILE_HUE_SAT_MAP;
     field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_PROFILE_TONE_CURVE;
-    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_REFERENCE_ILLUMINANT;
     field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_SENSITIVITY;
     field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_TEMPERATURE;
     field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_TEST_PATTERN_MODE;
@@ -19102,6 +19106,7 @@
     field public static final int JELLY_BEAN_MR1 = 17; // 0x11
     field public static final int JELLY_BEAN_MR2 = 18; // 0x12
     field public static final int KITKAT = 19; // 0x13
+    field public static final int KITKAT_WATCH = 10000; // 0x2710
     field public static final int L = 10000; // 0x2710
   }
 
@@ -25202,6 +25207,18 @@
     field public static final android.os.Parcelable.Creator CREATOR;
   }
 
+  public class DataConnectionRealTimeInfo implements android.os.Parcelable {
+    method public int describeContents();
+    method public int getDcPowerState();
+    method public long getTime();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator CREATOR;
+    field public static int DC_POWER_STATE_HIGH;
+    field public static int DC_POWER_STATE_LOW;
+    field public static int DC_POWER_STATE_MEDIUM;
+    field public static int DC_POWER_STATE_UNKNOWN;
+  }
+
   public class NeighboringCellInfo implements android.os.Parcelable {
     ctor public deprecated NeighboringCellInfo();
     ctor public deprecated NeighboringCellInfo(int, int);
@@ -30946,6 +30963,7 @@
     method public boolean hasInsets();
     method public boolean hasSystemWindowInsets();
     method public boolean hasWindowDecorInsets();
+    method public boolean isRound();
   }
 
   public abstract interface WindowManager implements android.view.ViewManager {
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 9f1b56e..44c74d8 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -2029,7 +2029,7 @@
             data.enforceInterface(IActivityManager.descriptor);
             IBinder parentActivityToken = data.readStrongBinder();
             IActivityContainerCallback callback =
-                    (IActivityContainerCallback) data.readStrongBinder();
+                    IActivityContainerCallback.Stub.asInterface(data.readStrongBinder());
             IActivityContainer activityContainer =
                     createActivityContainer(parentActivityToken, callback);
             reply.writeNoException();
@@ -4744,7 +4744,7 @@
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
         data.writeStrongBinder(parentActivityToken);
-        data.writeStrongBinder((IBinder)callback);
+        data.writeStrongBinder(callback == null ? null : callback.asBinder());
         mRemote.transact(CREATE_ACTIVITY_CONTAINER_TRANSACTION, data, reply, 0);
         reply.readException();
         final int result = reply.readInt();
diff --git a/core/java/android/app/ActivityView.java b/core/java/android/app/ActivityView.java
index 113f123..51cb12a 100644
--- a/core/java/android/app/ActivityView.java
+++ b/core/java/android/app/ActivityView.java
@@ -92,8 +92,8 @@
         super.onAttachedToWindow();
         try {
             final IBinder token = mActivity.getActivityToken();
-            mActivityContainer =
-                    ActivityManagerNative.getDefault().createActivityContainer(token, null);
+            mActivityContainer = ActivityManagerNative.getDefault().createActivityContainer(token,
+                      new ActivityContainerCallback());
         } catch (RemoteException e) {
             throw new IllegalStateException("ActivityView: Unable to create ActivityContainer. "
                     + e);
@@ -282,4 +282,14 @@
         }
 
     }
+
+    private class ActivityContainerCallback extends IActivityContainerCallback.Stub {
+        @Override
+        public void setVisible(IBinder container, boolean visible) {
+            if (DEBUG) Log.v(TAG, "setVisible(): container=" + container + " visible=" + visible);
+            if (visible) {
+            } else {
+            }
+        }
+    }
 }
diff --git a/core/java/android/app/IActivityContainerCallback.aidl b/core/java/android/app/IActivityContainerCallback.aidl
index 55c2001..7f6d2c3 100644
--- a/core/java/android/app/IActivityContainerCallback.aidl
+++ b/core/java/android/app/IActivityContainerCallback.aidl
@@ -20,5 +20,5 @@
 
 /** @hide */
 interface IActivityContainerCallback {
-    oneway void onLastActivityRemoved(IBinder container);
+    oneway void setVisible(IBinder container, boolean visible);
 }
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index 9852776..528e119 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -1030,6 +1030,195 @@
             new Key<Integer>("android.sensor.info.whiteLevel", int.class);
 
     /**
+     * <p>The standard reference illuminant used as the scene light source when
+     * calculating the {@link CameraCharacteristics#SENSOR_COLOR_TRANSFORM1 android.sensor.colorTransform1},
+     * {@link CameraCharacteristics#SENSOR_CALIBRATION_TRANSFORM1 android.sensor.calibrationTransform1}, and
+     * {@link CameraCharacteristics#SENSOR_FORWARD_MATRIX1 android.sensor.forwardMatrix1} matrices.</p>
+     * <p>The values in this tag correspond to the values defined for the
+     * EXIF LightSource tag. These illuminants are standard light sources
+     * that are often used calibrating camera devices.</p>
+     * <p>If this tag is present, then {@link CameraCharacteristics#SENSOR_COLOR_TRANSFORM1 android.sensor.colorTransform1},
+     * {@link CameraCharacteristics#SENSOR_CALIBRATION_TRANSFORM1 android.sensor.calibrationTransform1}, and
+     * {@link CameraCharacteristics#SENSOR_FORWARD_MATRIX1 android.sensor.forwardMatrix1} will also be present.</p>
+     * <p>Some devices may choose to provide a second set of calibration
+     * information for improved quality, including
+     * {@link CameraCharacteristics#SENSOR_REFERENCE_ILLUMINANT2 android.sensor.referenceIlluminant2} and its corresponding matrices.</p>
+     *
+     * @see CameraCharacteristics#SENSOR_CALIBRATION_TRANSFORM1
+     * @see CameraCharacteristics#SENSOR_COLOR_TRANSFORM1
+     * @see CameraCharacteristics#SENSOR_FORWARD_MATRIX1
+     * @see CameraCharacteristics#SENSOR_REFERENCE_ILLUMINANT2
+     * @see #SENSOR_REFERENCE_ILLUMINANT1_DAYLIGHT
+     * @see #SENSOR_REFERENCE_ILLUMINANT1_FLUORESCENT
+     * @see #SENSOR_REFERENCE_ILLUMINANT1_TUNGSTEN
+     * @see #SENSOR_REFERENCE_ILLUMINANT1_FLASH
+     * @see #SENSOR_REFERENCE_ILLUMINANT1_FINE_WEATHER
+     * @see #SENSOR_REFERENCE_ILLUMINANT1_CLOUDY_WEATHER
+     * @see #SENSOR_REFERENCE_ILLUMINANT1_SHADE
+     * @see #SENSOR_REFERENCE_ILLUMINANT1_DAYLIGHT_FLUORESCENT
+     * @see #SENSOR_REFERENCE_ILLUMINANT1_DAY_WHITE_FLUORESCENT
+     * @see #SENSOR_REFERENCE_ILLUMINANT1_COOL_WHITE_FLUORESCENT
+     * @see #SENSOR_REFERENCE_ILLUMINANT1_WHITE_FLUORESCENT
+     * @see #SENSOR_REFERENCE_ILLUMINANT1_STANDARD_A
+     * @see #SENSOR_REFERENCE_ILLUMINANT1_STANDARD_B
+     * @see #SENSOR_REFERENCE_ILLUMINANT1_STANDARD_C
+     * @see #SENSOR_REFERENCE_ILLUMINANT1_D55
+     * @see #SENSOR_REFERENCE_ILLUMINANT1_D65
+     * @see #SENSOR_REFERENCE_ILLUMINANT1_D75
+     * @see #SENSOR_REFERENCE_ILLUMINANT1_D50
+     * @see #SENSOR_REFERENCE_ILLUMINANT1_ISO_STUDIO_TUNGSTEN
+     */
+    public static final Key<Integer> SENSOR_REFERENCE_ILLUMINANT1 =
+            new Key<Integer>("android.sensor.referenceIlluminant1", int.class);
+
+    /**
+     * <p>The standard reference illuminant used as the scene light source when
+     * calculating the {@link CameraCharacteristics#SENSOR_COLOR_TRANSFORM2 android.sensor.colorTransform2},
+     * {@link CameraCharacteristics#SENSOR_CALIBRATION_TRANSFORM2 android.sensor.calibrationTransform2}, and
+     * {@link CameraCharacteristics#SENSOR_FORWARD_MATRIX2 android.sensor.forwardMatrix2} matrices.</p>
+     * <p>See {@link CameraCharacteristics#SENSOR_REFERENCE_ILLUMINANT1 android.sensor.referenceIlluminant1} for more details.
+     * Valid values for this are the same as those given for the first
+     * reference illuminant.</p>
+     * <p>If this tag is present, then {@link CameraCharacteristics#SENSOR_COLOR_TRANSFORM2 android.sensor.colorTransform2},
+     * {@link CameraCharacteristics#SENSOR_CALIBRATION_TRANSFORM2 android.sensor.calibrationTransform2}, and
+     * {@link CameraCharacteristics#SENSOR_FORWARD_MATRIX2 android.sensor.forwardMatrix2} will also be present.</p>
+     *
+     * @see CameraCharacteristics#SENSOR_CALIBRATION_TRANSFORM2
+     * @see CameraCharacteristics#SENSOR_COLOR_TRANSFORM2
+     * @see CameraCharacteristics#SENSOR_FORWARD_MATRIX2
+     * @see CameraCharacteristics#SENSOR_REFERENCE_ILLUMINANT1
+     */
+    public static final Key<Byte> SENSOR_REFERENCE_ILLUMINANT2 =
+            new Key<Byte>("android.sensor.referenceIlluminant2", byte.class);
+
+    /**
+     * <p>A per-device calibration transform matrix that maps from the
+     * reference sensor colorspace to the actual device sensor colorspace.</p>
+     * <p>This matrix is used to correct for per-device variations in the
+     * sensor colorspace, and is used for processing raw buffer data.</p>
+     * <p>The matrix is expressed as a 3x3 matrix in row-major-order, and
+     * contains a per-device calibration transform that maps colors
+     * from reference sensor color space (i.e. the "golden module"
+     * colorspace) into this camera device's native sensor color
+     * space under the first reference illuminant
+     * ({@link CameraCharacteristics#SENSOR_REFERENCE_ILLUMINANT1 android.sensor.referenceIlluminant1}).</p>
+     * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
+     *
+     * @see CameraCharacteristics#SENSOR_REFERENCE_ILLUMINANT1
+     */
+    public static final Key<Rational[]> SENSOR_CALIBRATION_TRANSFORM1 =
+            new Key<Rational[]>("android.sensor.calibrationTransform1", Rational[].class);
+
+    /**
+     * <p>A per-device calibration transform matrix that maps from the
+     * reference sensor colorspace to the actual device sensor colorspace
+     * (this is the colorspace of the raw buffer data).</p>
+     * <p>This matrix is used to correct for per-device variations in the
+     * sensor colorspace, and is used for processing raw buffer data.</p>
+     * <p>The matrix is expressed as a 3x3 matrix in row-major-order, and
+     * contains a per-device calibration transform that maps colors
+     * from reference sensor color space (i.e. the "golden module"
+     * colorspace) into this camera device's native sensor color
+     * space under the second reference illuminant
+     * ({@link CameraCharacteristics#SENSOR_REFERENCE_ILLUMINANT2 android.sensor.referenceIlluminant2}).</p>
+     * <p>This matrix will only be present if the second reference
+     * illuminant is present.</p>
+     * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
+     *
+     * @see CameraCharacteristics#SENSOR_REFERENCE_ILLUMINANT2
+     */
+    public static final Key<Rational[]> SENSOR_CALIBRATION_TRANSFORM2 =
+            new Key<Rational[]>("android.sensor.calibrationTransform2", Rational[].class);
+
+    /**
+     * <p>A matrix that transforms color values from CIE XYZ color space to
+     * reference sensor color space.</p>
+     * <p>This matrix is used to convert from the standard CIE XYZ color
+     * space to the reference sensor colorspace, and is used when processing
+     * raw buffer data.</p>
+     * <p>The matrix is expressed as a 3x3 matrix in row-major-order, and
+     * contains a color transform matrix that maps colors from the CIE
+     * XYZ color space to the reference sensor color space (i.e. the
+     * "golden module" colorspace) under the first reference illuminant
+     * ({@link CameraCharacteristics#SENSOR_REFERENCE_ILLUMINANT1 android.sensor.referenceIlluminant1}).</p>
+     * <p>The white points chosen in both the reference sensor color space
+     * and the CIE XYZ colorspace when calculating this transform will
+     * match the standard white point for the first reference illuminant
+     * (i.e. no chromatic adaptation will be applied by this transform).</p>
+     * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
+     *
+     * @see CameraCharacteristics#SENSOR_REFERENCE_ILLUMINANT1
+     */
+    public static final Key<Rational[]> SENSOR_COLOR_TRANSFORM1 =
+            new Key<Rational[]>("android.sensor.colorTransform1", Rational[].class);
+
+    /**
+     * <p>A matrix that transforms color values from CIE XYZ color space to
+     * reference sensor color space.</p>
+     * <p>This matrix is used to convert from the standard CIE XYZ color
+     * space to the reference sensor colorspace, and is used when processing
+     * raw buffer data.</p>
+     * <p>The matrix is expressed as a 3x3 matrix in row-major-order, and
+     * contains a color transform matrix that maps colors from the CIE
+     * XYZ color space to the reference sensor color space (i.e. the
+     * "golden module" colorspace) under the second reference illuminant
+     * ({@link CameraCharacteristics#SENSOR_REFERENCE_ILLUMINANT2 android.sensor.referenceIlluminant2}).</p>
+     * <p>The white points chosen in both the reference sensor color space
+     * and the CIE XYZ colorspace when calculating this transform will
+     * match the standard white point for the second reference illuminant
+     * (i.e. no chromatic adaptation will be applied by this transform).</p>
+     * <p>This matrix will only be present if the second reference
+     * illuminant is present.</p>
+     * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
+     *
+     * @see CameraCharacteristics#SENSOR_REFERENCE_ILLUMINANT2
+     */
+    public static final Key<Rational[]> SENSOR_COLOR_TRANSFORM2 =
+            new Key<Rational[]>("android.sensor.colorTransform2", Rational[].class);
+
+    /**
+     * <p>A matrix that transforms white balanced camera colors from the reference
+     * sensor colorspace to the CIE XYZ colorspace with a D50 whitepoint.</p>
+     * <p>This matrix is used to convert to the standard CIE XYZ colorspace, and
+     * is used when processing raw buffer data.</p>
+     * <p>This matrix is expressed as a 3x3 matrix in row-major-order, and contains
+     * a color transform matrix that maps white balanced colors from the
+     * reference sensor color space to the CIE XYZ color space with a D50 white
+     * point.</p>
+     * <p>Under the first reference illuminant ({@link CameraCharacteristics#SENSOR_REFERENCE_ILLUMINANT1 android.sensor.referenceIlluminant1})
+     * this matrix is chosen so that the standard white point for this reference
+     * illuminant in the reference sensor colorspace is mapped to D50 in the
+     * CIE XYZ colorspace.</p>
+     * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
+     *
+     * @see CameraCharacteristics#SENSOR_REFERENCE_ILLUMINANT1
+     */
+    public static final Key<Rational[]> SENSOR_FORWARD_MATRIX1 =
+            new Key<Rational[]>("android.sensor.forwardMatrix1", Rational[].class);
+
+    /**
+     * <p>A matrix that transforms white balanced camera colors from the reference
+     * sensor colorspace to the CIE XYZ colorspace with a D50 whitepoint.</p>
+     * <p>This matrix is used to convert to the standard CIE XYZ colorspace, and
+     * is used when processing raw buffer data.</p>
+     * <p>This matrix is expressed as a 3x3 matrix in row-major-order, and contains
+     * a color transform matrix that maps white balanced colors from the
+     * reference sensor color space to the CIE XYZ color space with a D50 white
+     * point.</p>
+     * <p>Under the second reference illuminant ({@link CameraCharacteristics#SENSOR_REFERENCE_ILLUMINANT2 android.sensor.referenceIlluminant2})
+     * this matrix is chosen so that the standard white point for this reference
+     * illuminant in the reference sensor colorspace is mapped to D50 in the
+     * CIE XYZ colorspace.</p>
+     * <p>This matrix will only be present if the second reference
+     * illuminant is present.</p>
+     * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
+     *
+     * @see CameraCharacteristics#SENSOR_REFERENCE_ILLUMINANT2
+     */
+    public static final Key<Rational[]> SENSOR_FORWARD_MATRIX2 =
+            new Key<Rational[]>("android.sensor.forwardMatrix2", Rational[].class);
+
+    /**
      * <p>Gain factor from electrons to raw units when
      * ISO=100</p>
      * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index 9b1bc53..ba8db3a 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -457,6 +457,110 @@
     public static final int SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_RGB = 4;
 
     //
+    // Enumeration values for CameraCharacteristics#SENSOR_REFERENCE_ILLUMINANT1
+    //
+
+    /**
+     * @see CameraCharacteristics#SENSOR_REFERENCE_ILLUMINANT1
+     */
+    public static final int SENSOR_REFERENCE_ILLUMINANT1_DAYLIGHT = 1;
+
+    /**
+     * @see CameraCharacteristics#SENSOR_REFERENCE_ILLUMINANT1
+     */
+    public static final int SENSOR_REFERENCE_ILLUMINANT1_FLUORESCENT = 2;
+
+    /**
+     * <p>Incandescent light</p>
+     * @see CameraCharacteristics#SENSOR_REFERENCE_ILLUMINANT1
+     */
+    public static final int SENSOR_REFERENCE_ILLUMINANT1_TUNGSTEN = 3;
+
+    /**
+     * @see CameraCharacteristics#SENSOR_REFERENCE_ILLUMINANT1
+     */
+    public static final int SENSOR_REFERENCE_ILLUMINANT1_FLASH = 4;
+
+    /**
+     * @see CameraCharacteristics#SENSOR_REFERENCE_ILLUMINANT1
+     */
+    public static final int SENSOR_REFERENCE_ILLUMINANT1_FINE_WEATHER = 9;
+
+    /**
+     * @see CameraCharacteristics#SENSOR_REFERENCE_ILLUMINANT1
+     */
+    public static final int SENSOR_REFERENCE_ILLUMINANT1_CLOUDY_WEATHER = 10;
+
+    /**
+     * @see CameraCharacteristics#SENSOR_REFERENCE_ILLUMINANT1
+     */
+    public static final int SENSOR_REFERENCE_ILLUMINANT1_SHADE = 11;
+
+    /**
+     * <p>D 5700 - 7100K</p>
+     * @see CameraCharacteristics#SENSOR_REFERENCE_ILLUMINANT1
+     */
+    public static final int SENSOR_REFERENCE_ILLUMINANT1_DAYLIGHT_FLUORESCENT = 12;
+
+    /**
+     * <p>N 4600 - 5400K</p>
+     * @see CameraCharacteristics#SENSOR_REFERENCE_ILLUMINANT1
+     */
+    public static final int SENSOR_REFERENCE_ILLUMINANT1_DAY_WHITE_FLUORESCENT = 13;
+
+    /**
+     * <p>W 3900 - 4500K</p>
+     * @see CameraCharacteristics#SENSOR_REFERENCE_ILLUMINANT1
+     */
+    public static final int SENSOR_REFERENCE_ILLUMINANT1_COOL_WHITE_FLUORESCENT = 14;
+
+    /**
+     * <p>WW 3200 - 3700K</p>
+     * @see CameraCharacteristics#SENSOR_REFERENCE_ILLUMINANT1
+     */
+    public static final int SENSOR_REFERENCE_ILLUMINANT1_WHITE_FLUORESCENT = 15;
+
+    /**
+     * @see CameraCharacteristics#SENSOR_REFERENCE_ILLUMINANT1
+     */
+    public static final int SENSOR_REFERENCE_ILLUMINANT1_STANDARD_A = 17;
+
+    /**
+     * @see CameraCharacteristics#SENSOR_REFERENCE_ILLUMINANT1
+     */
+    public static final int SENSOR_REFERENCE_ILLUMINANT1_STANDARD_B = 18;
+
+    /**
+     * @see CameraCharacteristics#SENSOR_REFERENCE_ILLUMINANT1
+     */
+    public static final int SENSOR_REFERENCE_ILLUMINANT1_STANDARD_C = 19;
+
+    /**
+     * @see CameraCharacteristics#SENSOR_REFERENCE_ILLUMINANT1
+     */
+    public static final int SENSOR_REFERENCE_ILLUMINANT1_D55 = 20;
+
+    /**
+     * @see CameraCharacteristics#SENSOR_REFERENCE_ILLUMINANT1
+     */
+    public static final int SENSOR_REFERENCE_ILLUMINANT1_D65 = 21;
+
+    /**
+     * @see CameraCharacteristics#SENSOR_REFERENCE_ILLUMINANT1
+     */
+    public static final int SENSOR_REFERENCE_ILLUMINANT1_D75 = 22;
+
+    /**
+     * @see CameraCharacteristics#SENSOR_REFERENCE_ILLUMINANT1
+     */
+    public static final int SENSOR_REFERENCE_ILLUMINANT1_D50 = 23;
+
+    /**
+     * @see CameraCharacteristics#SENSOR_REFERENCE_ILLUMINANT1
+     */
+    public static final int SENSOR_REFERENCE_ILLUMINANT1_ISO_STUDIO_TUNGSTEN = 24;
+
+    //
     // Enumeration values for CameraCharacteristics#LED_AVAILABLE_LEDS
     //
 
@@ -1731,110 +1835,6 @@
     public static final int LENS_STATE_MOVING = 1;
 
     //
-    // Enumeration values for CaptureResult#SENSOR_REFERENCE_ILLUMINANT
-    //
-
-    /**
-     * @see CaptureResult#SENSOR_REFERENCE_ILLUMINANT
-     */
-    public static final int SENSOR_REFERENCE_ILLUMINANT_DAYLIGHT = 1;
-
-    /**
-     * @see CaptureResult#SENSOR_REFERENCE_ILLUMINANT
-     */
-    public static final int SENSOR_REFERENCE_ILLUMINANT_FLUORESCENT = 2;
-
-    /**
-     * <p>Incandescent light</p>
-     * @see CaptureResult#SENSOR_REFERENCE_ILLUMINANT
-     */
-    public static final int SENSOR_REFERENCE_ILLUMINANT_TUNGSTEN = 3;
-
-    /**
-     * @see CaptureResult#SENSOR_REFERENCE_ILLUMINANT
-     */
-    public static final int SENSOR_REFERENCE_ILLUMINANT_FLASH = 4;
-
-    /**
-     * @see CaptureResult#SENSOR_REFERENCE_ILLUMINANT
-     */
-    public static final int SENSOR_REFERENCE_ILLUMINANT_FINE_WEATHER = 9;
-
-    /**
-     * @see CaptureResult#SENSOR_REFERENCE_ILLUMINANT
-     */
-    public static final int SENSOR_REFERENCE_ILLUMINANT_CLOUDY_WEATHER = 10;
-
-    /**
-     * @see CaptureResult#SENSOR_REFERENCE_ILLUMINANT
-     */
-    public static final int SENSOR_REFERENCE_ILLUMINANT_SHADE = 11;
-
-    /**
-     * <p>D 5700 - 7100K</p>
-     * @see CaptureResult#SENSOR_REFERENCE_ILLUMINANT
-     */
-    public static final int SENSOR_REFERENCE_ILLUMINANT_DAYLIGHT_FLUORESCENT = 12;
-
-    /**
-     * <p>N 4600 - 5400K</p>
-     * @see CaptureResult#SENSOR_REFERENCE_ILLUMINANT
-     */
-    public static final int SENSOR_REFERENCE_ILLUMINANT_DAY_WHITE_FLUORESCENT = 13;
-
-    /**
-     * <p>W 3900 - 4500K</p>
-     * @see CaptureResult#SENSOR_REFERENCE_ILLUMINANT
-     */
-    public static final int SENSOR_REFERENCE_ILLUMINANT_COOL_WHITE_FLUORESCENT = 14;
-
-    /**
-     * <p>WW 3200 - 3700K</p>
-     * @see CaptureResult#SENSOR_REFERENCE_ILLUMINANT
-     */
-    public static final int SENSOR_REFERENCE_ILLUMINANT_WHITE_FLUORESCENT = 15;
-
-    /**
-     * @see CaptureResult#SENSOR_REFERENCE_ILLUMINANT
-     */
-    public static final int SENSOR_REFERENCE_ILLUMINANT_STANDARD_A = 17;
-
-    /**
-     * @see CaptureResult#SENSOR_REFERENCE_ILLUMINANT
-     */
-    public static final int SENSOR_REFERENCE_ILLUMINANT_STANDARD_B = 18;
-
-    /**
-     * @see CaptureResult#SENSOR_REFERENCE_ILLUMINANT
-     */
-    public static final int SENSOR_REFERENCE_ILLUMINANT_STANDARD_C = 19;
-
-    /**
-     * @see CaptureResult#SENSOR_REFERENCE_ILLUMINANT
-     */
-    public static final int SENSOR_REFERENCE_ILLUMINANT_D55 = 20;
-
-    /**
-     * @see CaptureResult#SENSOR_REFERENCE_ILLUMINANT
-     */
-    public static final int SENSOR_REFERENCE_ILLUMINANT_D65 = 21;
-
-    /**
-     * @see CaptureResult#SENSOR_REFERENCE_ILLUMINANT
-     */
-    public static final int SENSOR_REFERENCE_ILLUMINANT_D75 = 22;
-
-    /**
-     * @see CaptureResult#SENSOR_REFERENCE_ILLUMINANT
-     */
-    public static final int SENSOR_REFERENCE_ILLUMINANT_D50 = 23;
-
-    /**
-     * @see CaptureResult#SENSOR_REFERENCE_ILLUMINANT
-     */
-    public static final int SENSOR_REFERENCE_ILLUMINANT_ISO_STUDIO_TUNGSTEN = 24;
-
-    //
     // Enumeration values for CaptureResult#STATISTICS_SCENE_FLICKER
     //
 
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index b3bce3b..70d3c63 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -1607,77 +1607,14 @@
             new Key<Float>("android.sensor.temperature", float.class);
 
     /**
-     * <p>A reference illumination source roughly matching the current scene
-     * illumination, which is used to describe the sensor color space
-     * transformations.</p>
-     * <p>The values in this tag correspond to the values defined for the
-     * EXIF LightSource tag. These illuminants are standard light sources
-     * that are often used for calibrating camera devices.</p>
-     * @see #SENSOR_REFERENCE_ILLUMINANT_DAYLIGHT
-     * @see #SENSOR_REFERENCE_ILLUMINANT_FLUORESCENT
-     * @see #SENSOR_REFERENCE_ILLUMINANT_TUNGSTEN
-     * @see #SENSOR_REFERENCE_ILLUMINANT_FLASH
-     * @see #SENSOR_REFERENCE_ILLUMINANT_FINE_WEATHER
-     * @see #SENSOR_REFERENCE_ILLUMINANT_CLOUDY_WEATHER
-     * @see #SENSOR_REFERENCE_ILLUMINANT_SHADE
-     * @see #SENSOR_REFERENCE_ILLUMINANT_DAYLIGHT_FLUORESCENT
-     * @see #SENSOR_REFERENCE_ILLUMINANT_DAY_WHITE_FLUORESCENT
-     * @see #SENSOR_REFERENCE_ILLUMINANT_COOL_WHITE_FLUORESCENT
-     * @see #SENSOR_REFERENCE_ILLUMINANT_WHITE_FLUORESCENT
-     * @see #SENSOR_REFERENCE_ILLUMINANT_STANDARD_A
-     * @see #SENSOR_REFERENCE_ILLUMINANT_STANDARD_B
-     * @see #SENSOR_REFERENCE_ILLUMINANT_STANDARD_C
-     * @see #SENSOR_REFERENCE_ILLUMINANT_D55
-     * @see #SENSOR_REFERENCE_ILLUMINANT_D65
-     * @see #SENSOR_REFERENCE_ILLUMINANT_D75
-     * @see #SENSOR_REFERENCE_ILLUMINANT_D50
-     * @see #SENSOR_REFERENCE_ILLUMINANT_ISO_STUDIO_TUNGSTEN
-     */
-    public static final Key<Integer> SENSOR_REFERENCE_ILLUMINANT =
-            new Key<Integer>("android.sensor.referenceIlluminant", int.class);
-
-    /**
-     * <p>A per-device calibration transform matrix to be applied after the
-     * color space transform when rendering the raw image buffer.</p>
-     * <p>This matrix is expressed as a 3x3 matrix in row-major-order, and
-     * contains a per-device calibration transform that maps colors
-     * from reference camera color space (i.e. the "golden module"
-     * colorspace) into this camera device's linear native sensor color
-     * space for the current scene illumination and white balance choice.</p>
-     * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
-     */
-    public static final Key<Rational[]> SENSOR_CALIBRATION_TRANSFORM =
-            new Key<Rational[]>("android.sensor.calibrationTransform", Rational[].class);
-
-    /**
-     * <p>A matrix that transforms color values from CIE XYZ color space to
-     * reference camera color space when rendering the raw image buffer.</p>
-     * <p>This matrix is expressed as a 3x3 matrix in row-major-order, and
-     * contains a color transform matrix that maps colors from the CIE
-     * XYZ color space to the reference camera raw color space (i.e. the
-     * "golden module" colorspace) for the current scene illumination and
-     * white balance choice.</p>
-     * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
-     */
-    public static final Key<Rational[]> SENSOR_COLOR_TRANSFORM =
-            new Key<Rational[]>("android.sensor.colorTransform", Rational[].class);
-
-    /**
-     * <p>A matrix that transforms white balanced camera colors to the CIE XYZ
-     * colorspace with a D50 whitepoint.</p>
-     * <p>This matrix is expressed as a 3x3 matrix in row-major-order, and contains
-     * a color transform matrix that maps a unit vector in the linear native
-     * sensor color space to the D50 whitepoint in CIE XYZ color space.</p>
-     * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
-     */
-    public static final Key<Rational[]> SENSOR_FORWARD_MATRIX =
-            new Key<Rational[]>("android.sensor.forwardMatrix", Rational[].class);
-
-    /**
-     * <p>The estimated white balance at the time of capture.</p>
-     * <p>The estimated white balance encoded as the RGB values of the
-     * perfectly neutral color point in the linear native sensor color space.
-     * The order of the values is R, G, B; where R is in the lowest index.</p>
+     * <p>The estimated camera neutral color in the native sensor colorspace at
+     * the time of capture.</p>
+     * <p>This value gives the neutral color point encoded as an RGB value in the
+     * native sensor color space.  The neutral color point indicates the
+     * currently estimated white point of the scene illumination.  It can be
+     * used to interpolate between the provided color transforms when
+     * processing raw sensor data.</p>
+     * <p>The order of the values is R, G, B; where R is in the lowest index.</p>
      * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
      */
     public static final Key<Rational[]> SENSOR_NEUTRAL_COLOR_POINT =
diff --git a/core/java/android/net/NetworkScorerApplication.java b/core/java/android/net/NetworkScorerApplication.java
new file mode 100644
index 0000000..b137ad3
--- /dev/null
+++ b/core/java/android/net/NetworkScorerApplication.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.net;
+
+import android.Manifest.permission;
+import android.app.AppOpsManager;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.provider.Settings;
+import android.provider.Settings.Global;
+import android.text.TextUtils;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * Internal class for managing the primary network scorer application.
+ *
+ * @hide
+ */
+public final class NetworkScorerApplication {
+
+    private static final Intent SCORE_INTENT =
+            new Intent(NetworkScoreManager.ACTION_SCORE_NETWORKS);
+
+    /** This class cannot be instantiated. */
+    private NetworkScorerApplication() {}
+
+    /**
+     * Returns the list of available scorer app package names.
+     *
+     * <p>A network scorer is any application which:
+     * <ul>
+     * <li>Declares the {@link android.Manifest.permission#SCORE_NETWORKS} permission.
+     * <li>Includes a receiver for {@link NetworkScoreManager#ACTION_SCORE_NETWORKS} guarded by the
+     *     {@link android.Manifest.permission#BROADCAST_SCORE_NETWORKS} permission.
+     * </ul>
+     *
+     * @return the list of scorers, or the empty list if there are no valid scorers.
+     */
+    public static Collection<String> getAllValidScorers(Context context) {
+        List<String> scorers = new ArrayList<>();
+
+        PackageManager pm = context.getPackageManager();
+        List<ResolveInfo> receivers = pm.queryBroadcastReceivers(SCORE_INTENT, 0 /* flags */);
+        for (ResolveInfo receiver : receivers) {
+            // This field is a misnomer, see android.content.pm.ResolveInfo#activityInfo
+            final ActivityInfo receiverInfo = receiver.activityInfo;
+            if (receiverInfo == null) {
+                // Should never happen with queryBroadcastReceivers, but invalid nonetheless.
+                continue;
+            }
+            if (!permission.BROADCAST_SCORE_NETWORKS.equals(receiverInfo.permission)) {
+                // Receiver doesn't require the BROADCAST_SCORE_NETWORKS permission, which means
+                // anyone could trigger network scoring and flood the framework with score requests.
+                continue;
+            }
+            if (pm.checkPermission(permission.SCORE_NETWORKS, receiverInfo.packageName) !=
+                    PackageManager.PERMISSION_GRANTED) {
+                // Application doesn't hold the SCORE_NETWORKS permission, so the user never
+                // approved it as a network scorer.
+                continue;
+            }
+            scorers.add(receiverInfo.packageName);
+        }
+
+        return scorers;
+    }
+
+    /**
+     * Get the application package name to use for scoring networks.
+     *
+     * @return the scorer package or null if scoring is disabled (including if no scorer was ever
+     *     selected) or if the previously-set scorer is no longer a valid scorer app (e.g. because
+     *     it was disabled or uninstalled).
+     */
+    public static String getActiveScorer(Context context) {
+        String scorerPackage = Settings.Global.getString(context.getContentResolver(),
+                Global.NETWORK_SCORER_APP);
+        Collection<String> applications = getAllValidScorers(context);
+        if (isPackageValidScorer(applications, scorerPackage)) {
+            return scorerPackage;
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Set the specified package as the default scorer application.
+     *
+     * <p>The caller must have permission to write to {@link Settings.Global}.
+     *
+     * @param context the context of the calling application
+     * @param packageName the packageName of the new scorer to use. If null, scoring will be
+     *     disabled. Otherwise, the scorer will only be set if it is a valid scorer application.
+     */
+    public static void setActiveScorer(Context context, String packageName) {
+        String oldPackageName = Settings.Global.getString(context.getContentResolver(),
+                Settings.Global.NETWORK_SCORER_APP);
+        if (TextUtils.equals(oldPackageName, packageName)) {
+            // No change.
+            return;
+        }
+
+        if (packageName == null) {
+            Settings.Global.putString(context.getContentResolver(), Global.NETWORK_SCORER_APP,
+                    null);
+        } else {
+            // We only make the change if the new package is valid.
+            Collection<String> applications = getAllValidScorers(context);
+            if (isPackageValidScorer(applications, packageName)) {
+                Settings.Global.putString(context.getContentResolver(),
+                        Settings.Global.NETWORK_SCORER_APP, packageName);
+            }
+        }
+    }
+
+    /** Determine whether the application with the given UID is the enabled scorer. */
+    public static boolean isCallerDefaultScorer(Context context, int callingUid) {
+        String defaultApp = getActiveScorer(context);
+        if (defaultApp == null) {
+            return false;
+        }
+        AppOpsManager appOpsMgr = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
+        try {
+            appOpsMgr.checkPackage(callingUid, defaultApp);
+            return true;
+        } catch (SecurityException e) {
+            return false;
+        }
+    }
+
+    /** Returns true if the given package is a valid scorer. */
+    private static boolean isPackageValidScorer(Collection<String> scorerPackageNames,
+            String packageName) {
+        return packageName != null && scorerPackageNames.contains(packageName);
+    }
+}
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 7f1a2e4..63e15a9 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -476,6 +476,11 @@
         public static final int KITKAT = 19;
 
         /**
+         * Android 4.5: KitKat for watches, snacks on the run.
+         */
+        public static final int KITKAT_WATCH = CUR_DEVELOPMENT; // STOPSHIP: update API level
+
+        /**
          * L!
          *
          * <p>Applications targeting this or a later release will get these
diff --git a/core/java/android/preference/PreferenceFragment.java b/core/java/android/preference/PreferenceFragment.java
index 11d8878..325b2e6 100644
--- a/core/java/android/preference/PreferenceFragment.java
+++ b/core/java/android/preference/PreferenceFragment.java
@@ -337,6 +337,26 @@
         return mList;
     }
 
+    /** @hide */
+    public boolean hasListView() {
+        if (mList != null) {
+            return true;
+        }
+        View root = getView();
+        if (root == null) {
+            return false;
+        }
+        View rawListView = root.findViewById(android.R.id.list);
+        if (!(rawListView instanceof ListView)) {
+            return false;
+        }
+        mList = (ListView)rawListView;
+        if (mList == null) {
+            return false;
+        }
+        return true;
+    }
+
     private void ensureList() {
         if (mList != null) {
             return;
diff --git a/core/java/android/preference/PreferenceGroupAdapter.java b/core/java/android/preference/PreferenceGroupAdapter.java
index c2e1f51..9b41ff0 100644
--- a/core/java/android/preference/PreferenceGroupAdapter.java
+++ b/core/java/android/preference/PreferenceGroupAdapter.java
@@ -20,6 +20,8 @@
 import java.util.Collections;
 import java.util.List;
 
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
 import android.os.Handler;
 import android.preference.Preference.OnPreferenceChangeInternalListener;
 import android.view.View;
@@ -91,7 +93,8 @@
         }
     };
 
-    private int mActivatedPosition = -1;
+    private int mHighlightedPosition = -1;
+    private Drawable mHighlightedDrawable;
 
     private static class PreferenceLayout implements Comparable<PreferenceLayout> {
         private int resId;
@@ -212,8 +215,18 @@
         return this.getItem(position).getId();
     }
 
-    public void setActivated(int position) {
-        mActivatedPosition = position;
+    /**
+     * @hide
+     */
+    public void setHighlighted(int position) {
+        mHighlightedPosition = position;
+    }
+
+    /**
+     * @hide
+     */
+    public void setHighlightedDrawable(Drawable drawable) {
+        mHighlightedDrawable = drawable;
     }
 
     public View getView(int position, View convertView, ViewGroup parent) {
@@ -227,7 +240,9 @@
             convertView = null;
         }
         View result = preference.getView(convertView, parent);
-        result.setActivated(position == mActivatedPosition);
+        if (position == mHighlightedPosition && mHighlightedDrawable != null) {
+            result.setBackgroundDrawable(mHighlightedDrawable);
+        }
         return result;
     }
 
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 7062933..1e202ca 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -5097,6 +5097,13 @@
        public static final String NETWORK_PREFERENCE = "network_preference";
 
        /**
+        * Which package name to use for network scoring. If null, or if the package is not a valid
+        * scorer app, external network scores will neither be requested nor accepted.
+        * @hide
+        */
+       public static final String NETWORK_SCORER_APP = "network_scorer_app";
+
+       /**
         * If the NITZ_UPDATE_DIFF time is exceeded then an automatic adjustment
         * to SystemClock will be allowed even if NITZ_UPDATE_SPACING has not been
         * exceeded.
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index c274fc4..f0d8a61 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -378,17 +378,6 @@
 
     private static native void nDrawLayer(long renderer, long layer, float x, float y);
 
-    void interrupt() {
-        nInterrupt(mRenderer);
-    }
-    
-    void resume() {
-        nResume(mRenderer);
-    }
-
-    private static native void nInterrupt(long renderer);
-    private static native void nResume(long renderer);
-
     ///////////////////////////////////////////////////////////////////////////
     // Support
     ///////////////////////////////////////////////////////////////////////////
diff --git a/core/java/android/view/GLRenderer.java b/core/java/android/view/GLRenderer.java
index eba4f7f..d8d11f7 100644
--- a/core/java/android/view/GLRenderer.java
+++ b/core/java/android/view/GLRenderer.java
@@ -1177,7 +1177,7 @@
                     callbacks.onHardwarePreDraw(canvas);
 
                     if (displayList != null) {
-                        status |= drawDisplayList(attachInfo, canvas, displayList, status);
+                        status |= drawDisplayList(canvas, displayList, status);
                     } else {
                         // Shouldn't reach here
                         view.draw(canvas);
@@ -1308,8 +1308,8 @@
         return status;
     }
 
-    private int drawDisplayList(View.AttachInfo attachInfo, HardwareCanvas canvas,
-            RenderNode displayList, int status) {
+    private int drawDisplayList(HardwareCanvas canvas, RenderNode displayList,
+            int status) {
 
         long drawDisplayListStartTime = 0;
         if (mProfileEnabled) {
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index 1429837..60d7c78 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -194,6 +194,8 @@
 
         updateRootDisplayList(view, callbacks);
 
+        attachInfo.mIgnoreDirtyState = false;
+
         if (dirty == null) {
             dirty = NULL_RECT;
         }
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index ef22def..eec4354 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -1171,6 +1171,11 @@
         m.preTranslate(-attachInfo.mWindowLeft, -attachInfo.mWindowTop);
     }
 
+    void dispatchApplyInsets(View host) {
+        mFitSystemWindowsInsets.set(mAttachInfo.mContentInsets);
+        host.dispatchApplyWindowInsets(new WindowInsets(mFitSystemWindowsInsets));
+    }
+
     private void performTraversals() {
         // cache mView since it is used so much below...
         final View host = mView;
@@ -1257,8 +1262,7 @@
             }
             host.dispatchAttachedToWindow(attachInfo, 0);
             attachInfo.mTreeObserver.dispatchOnWindowAttachedChange(true);
-            mFitSystemWindowsInsets.set(mAttachInfo.mContentInsets);
-            host.fitSystemWindows(mFitSystemWindowsInsets);
+            dispatchApplyInsets(host);
             //Log.i(TAG, "Screen on initialized: " + attachInfo.mKeepScreenOn);
 
         } else {
@@ -1383,9 +1387,8 @@
 
         if (mFitSystemWindowsRequested) {
             mFitSystemWindowsRequested = false;
-            mFitSystemWindowsInsets.set(mAttachInfo.mContentInsets);
             mLastOverscanRequested = mAttachInfo.mOverscanRequested;
-            host.fitSystemWindows(mFitSystemWindowsInsets);
+            dispatchApplyInsets(host);
             if (mLayoutRequested) {
                 // Short-circuit catching a new layout request here, so
                 // we don't need to go through two layout passes when things
@@ -1559,8 +1562,7 @@
                     mLastSystemUiVisibility = mAttachInfo.mSystemUiVisibility;
                     mLastOverscanRequested = mAttachInfo.mOverscanRequested;
                     mFitSystemWindowsRequested = false;
-                    mFitSystemWindowsInsets.set(mAttachInfo.mContentInsets);
-                    host.fitSystemWindows(mFitSystemWindowsInsets);
+                    dispatchApplyInsets(host);
                 }
                 if (visibleInsetsChanged) {
                     mAttachInfo.mVisibleInsets.set(mPendingVisibleInsets);
diff --git a/core/java/android/view/WindowInsets.java b/core/java/android/view/WindowInsets.java
index cdfcb43..f8cc793 100644
--- a/core/java/android/view/WindowInsets.java
+++ b/core/java/android/view/WindowInsets.java
@@ -33,6 +33,7 @@
     private Rect mSystemWindowInsets;
     private Rect mWindowDecorInsets;
     private Rect mTempRect;
+    private boolean mIsRound;
 
     private static final Rect EMPTY_RECT = new Rect(0, 0, 0, 0);
 
@@ -46,8 +47,14 @@
 
     /** @hide */
     public WindowInsets(Rect systemWindowInsets, Rect windowDecorInsets) {
+        this(systemWindowInsets, windowDecorInsets, false);
+    }
+
+    /** @hide */
+    public WindowInsets(Rect systemWindowInsets, Rect windowDecorInsets, boolean isRound) {
         mSystemWindowInsets = systemWindowInsets;
         mWindowDecorInsets = windowDecorInsets;
+        mIsRound = isRound;
     }
 
     /**
@@ -58,12 +65,12 @@
     public WindowInsets(WindowInsets src) {
         mSystemWindowInsets = src.mSystemWindowInsets;
         mWindowDecorInsets = src.mWindowDecorInsets;
+        mIsRound = src.mIsRound;
     }
 
     /** @hide */
     public WindowInsets(Rect systemWindowInsets) {
-        mSystemWindowInsets = systemWindowInsets;
-        mWindowDecorInsets = EMPTY_RECT;
+        this(systemWindowInsets, EMPTY_RECT);
     }
 
     /**
@@ -220,6 +227,20 @@
         return hasSystemWindowInsets() || hasWindowDecorInsets();
     }
 
+    /**
+     * Returns true if the associated window has a round shape.
+     *
+     * <p>A round window's left, top, right and bottom edges reach all the way to the
+     * associated edges of the window but the corners may not be visible. Views responding
+     * to round insets should take care to not lay out critical elements within the corners
+     * where they may not be accessible.</p>
+     *
+     * @return True if the window is round
+     */
+    public boolean isRound() {
+        return mIsRound;
+    }
+
     public WindowInsets cloneWithSystemWindowInsetsConsumed() {
         final WindowInsets result = new WindowInsets(this);
         result.mSystemWindowInsets = new Rect(0, 0, 0, 0);
@@ -273,6 +294,6 @@
     @Override
     public String toString() {
         return "WindowInsets{systemWindowInsets=" + mSystemWindowInsets + " windowDecorInsets=" +
-                mWindowDecorInsets + "}";
+                mWindowDecorInsets + (isRound() ? "round}" : "}");
     }
 }
diff --git a/core/jni/android_database_CursorWindow.cpp b/core/jni/android_database_CursorWindow.cpp
index 67f3879..af6cc72 100644
--- a/core/jni/android_database_CursorWindow.cpp
+++ b/core/jni/android_database_CursorWindow.cpp
@@ -17,6 +17,7 @@
 #undef LOG_TAG
 #define LOG_TAG "CursorWindow"
 
+#include <inttypes.h>
 #include <jni.h>
 #include <JNIHelp.h>
 #include <android_runtime/AndroidRuntime.h>
@@ -225,7 +226,7 @@
     } else if (type == CursorWindow::FIELD_TYPE_INTEGER) {
         int64_t value = window->getFieldSlotValueLong(fieldSlot);
         char buf[32];
-        snprintf(buf, sizeof(buf), "%lld", value);
+        snprintf(buf, sizeof(buf), "%" PRId64, value);
         return env->NewStringUTF(buf);
     } else if (type == CursorWindow::FIELD_TYPE_FLOAT) {
         double value = window->getFieldSlotValueDouble(fieldSlot);
@@ -314,7 +315,7 @@
     } else if (type == CursorWindow::FIELD_TYPE_INTEGER) {
         int64_t value = window->getFieldSlotValueLong(fieldSlot);
         char buf[32];
-        snprintf(buf, sizeof(buf), "%lld", value);
+        snprintf(buf, sizeof(buf), "%" PRId64, value);
         fillCharArrayBufferUTF(env, bufferObj, buf, strlen(buf));
     } else if (type == CursorWindow::FIELD_TYPE_FLOAT) {
         double value = window->getFieldSlotValueDouble(fieldSlot);
diff --git a/core/jni/android_net_TrafficStats.cpp b/core/jni/android_net_TrafficStats.cpp
index f904b62..031637f 100644
--- a/core/jni/android_net_TrafficStats.cpp
+++ b/core/jni/android_net_TrafficStats.cpp
@@ -19,6 +19,7 @@
 #include <dirent.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <inttypes.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 
@@ -85,9 +86,9 @@
     uint64_t rxBytes, rxPackets, txBytes, txPackets, tcpRxPackets, tcpTxPackets;
 
     while (fgets(buffer, sizeof(buffer), fp) != NULL) {
-        int matched = sscanf(buffer, "%31s %llu %llu %llu %llu "
-                "%*u %llu %*u %*u %*u %*u "
-                "%*u %llu %*u %*u %*u %*u", cur_iface, &rxBytes,
+        int matched = sscanf(buffer, "%31s %" SCNu64 " %" SCNu64 " %" SCNu64
+                " %" SCNu64 " " "%*u %" SCNu64 " %*u %*u %*u %*u "
+                "%*u %" SCNu64 " %*u %*u %*u %*u", cur_iface, &rxBytes,
                 &rxPackets, &txBytes, &txPackets, &tcpRxPackets, &tcpTxPackets);
         if (matched >= 5) {
             if (matched == 7) {
@@ -129,9 +130,11 @@
     uint64_t tag, rxBytes, rxPackets, txBytes, txPackets;
 
     while (fgets(buffer, sizeof(buffer), fp) != NULL) {
-        if (sscanf(buffer, "%d %31s 0x%llx %u %u %llu %llu %llu %llu", &idx,
-                iface, &tag, &cur_uid, &set, &rxBytes, &rxPackets, &txBytes,
-                &txPackets) == 9) {
+        if (sscanf(buffer,
+                "%" SCNu32 " %31s 0x%" SCNx64 " %u %u %" SCNu64 " %" SCNu64
+                " %" SCNu64 " %" SCNu64 "",
+                &idx, iface, &tag, &cur_uid, &set, &rxBytes, &rxPackets,
+                &txBytes, &txPackets) == 9) {
             if (uid == cur_uid && tag == 0L) {
                 stats->rxBytes += rxBytes;
                 stats->rxPackets += rxPackets;
diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp
index d4873d6..86207f0 100644
--- a/core/jni/android_os_Debug.cpp
+++ b/core/jni/android_os_Debug.cpp
@@ -24,6 +24,7 @@
 
 #include <cutils/log.h>
 #include <fcntl.h>
+#include <inttypes.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -824,9 +825,9 @@
                 break;
             } else {
 #ifdef __LP64__
-                fprintf(fp, " %016x", backtrace[bt]);
+                fprintf(fp, " %016" PRIxPTR, backtrace[bt]);
 #else
-                fprintf(fp, " %08x", backtrace[bt]);
+                fprintf(fp, " %08" PRIxPTR, backtrace[bt]);
 #endif
             }
         }
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index e72aff9..8549004 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -893,18 +893,6 @@
 // Layers
 // ----------------------------------------------------------------------------
 
-static void android_view_GLES20Canvas_interrupt(JNIEnv* env, jobject clazz,
-        jlong rendererPtr) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
-    renderer->interrupt();
-}
-
-static void android_view_GLES20Canvas_resume(JNIEnv* env, jobject clazz,
-        jlong rendererPtr) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
-    renderer->resume();
-}
-
 static void android_view_GLES20Canvas_drawLayer(JNIEnv* env, jobject clazz,
         jlong rendererPtr, jlong layerPtr, jfloat x, jfloat y) {
     OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
@@ -1093,9 +1081,6 @@
 
     { "nCreateDisplayListRenderer", "()J",     (void*) android_view_GLES20Canvas_createDisplayListRenderer },
 
-    { "nInterrupt",              "(J)V",       (void*) android_view_GLES20Canvas_interrupt },
-    { "nResume",                 "(J)V",       (void*) android_view_GLES20Canvas_resume },
-
     { "nDrawLayer",              "(JJFF)V",    (void*) android_view_GLES20Canvas_drawLayer },
     { "nCopyLayer",              "(JJ)Z",      (void*) android_view_GLES20Canvas_copyLayer },
     { "nClearLayerUpdates",      "(J)V",       (void*) android_view_GLES20Canvas_clearLayerUpdates },
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index d5e78a5..f549290 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1340,10 +1340,10 @@
          Example: com.google.android.myapp/.resolver.MyResolverActivity  -->
     <string name="config_customResolverActivity"></string>
 
-    <!-- Name of the activity that prompts the user to reject, accept, or whitelist
+    <!-- Name of the activity or service that prompts the user to reject, accept, or whitelist
          an adb host's public key, when an unwhitelisted host connects to the local adbd.
          Can be customized for other product types -->
-    <string name="config_customAdbPublicKeyActivity"
+    <string name="config_customAdbPublicKeyConfirmationComponent"
             >com.android.systemui/com.android.systemui.usb.UsbDebuggingActivity</string>
 
     <!-- Apps that are authorized to access shared accounts, overridden by product overlays -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index ac708b8..563272b 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1623,7 +1623,7 @@
   <java-symbol type="string" name="enable_explore_by_touch_warning_message" />
   <java-symbol type="bool" name="config_powerDecoupleAutoSuspendModeFromDisplay" />
   <java-symbol type="bool" name="config_powerDecoupleInteractiveModeFromDisplay" />
-  <java-symbol type="string" name="config_customAdbPublicKeyActivity" />
+  <java-symbol type="string" name="config_customAdbPublicKeyConfirmationComponent" />
 
   <java-symbol type="layout" name="resolver_list" />
   <java-symbol type="id" name="resolver_list" />
diff --git a/core/tests/coretests/Android.mk b/core/tests/coretests/Android.mk
index 73a53cb..6bdeaf0 100644
--- a/core/tests/coretests/Android.mk
+++ b/core/tests/coretests/Android.mk
@@ -23,7 +23,7 @@
 
 LOCAL_DX_FLAGS := --core-library
 LOCAL_AAPT_FLAGS = -0 dat -0 gld
-LOCAL_STATIC_JAVA_LIBRARIES := core-tests-support android-common frameworks-core-util-lib mockwebserver guava littlemock
+LOCAL_STATIC_JAVA_LIBRARIES := core-tests-support android-common frameworks-core-util-lib mockwebserver guava littlemock mockito-target
 LOCAL_JAVA_LIBRARIES := android.test.runner conscrypt telephony-common
 LOCAL_PACKAGE_NAME := FrameworksCoreTests
 
diff --git a/core/tests/coretests/src/android/net/NetworkScorerApplicationTest.java b/core/tests/coretests/src/android/net/NetworkScorerApplicationTest.java
new file mode 100644
index 0000000..6d5ede8
--- /dev/null
+++ b/core/tests/coretests/src/android/net/NetworkScorerApplicationTest.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.net;
+
+import android.Manifest.permission;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.test.InstrumentationTestCase;
+
+import com.google.android.collect.Lists;
+
+import org.mockito.ArgumentMatcher;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+
+import java.util.Iterator;
+
+public class NetworkScorerApplicationTest extends InstrumentationTestCase {
+    @Mock private Context mMockContext;
+    @Mock private PackageManager mMockPm;
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+
+        // Configuration needed to make mockito/dexcache work.
+        System.setProperty("dexmaker.dexcache",
+                getInstrumentation().getTargetContext().getCacheDir().getPath());
+        ClassLoader newClassLoader = getInstrumentation().getClass().getClassLoader();
+        Thread.currentThread().setContextClassLoader(newClassLoader);
+
+        MockitoAnnotations.initMocks(this);
+        Mockito.when(mMockContext.getPackageManager()).thenReturn(mMockPm);
+    }
+
+    public void testGetAllValidScorers() throws Exception {
+        // Package 1 - Valid scorer.
+        ResolveInfo package1 = buildResolveInfo("package1", true, true);
+
+        // Package 2 - Receiver does not have BROADCAST_SCORE_NETWORKS permission.
+        ResolveInfo package2 = buildResolveInfo("package2", false, true);
+
+        // Package 3 - App does not have SCORE_NETWORKS permission.
+        ResolveInfo package3 = buildResolveInfo("package3", true, false);
+
+        setScorers(package1, package2, package3);
+
+        Iterator<String> result =
+                NetworkScorerApplication.getAllValidScorers(mMockContext).iterator();
+
+        assertTrue(result.hasNext());
+        assertEquals("package1", result.next());
+
+        assertFalse(result.hasNext());
+    }
+
+    private void setScorers(ResolveInfo... scorers) {
+        Mockito.when(mMockPm.queryBroadcastReceivers(
+                Mockito.argThat(new ArgumentMatcher<Intent>() {
+                    @Override
+                    public boolean matches(Object object) {
+                        Intent intent = (Intent) object;
+                        return NetworkScoreManager.ACTION_SCORE_NETWORKS.equals(intent.getAction());
+                    }
+                }), Mockito.eq(0)))
+                .thenReturn(Lists.newArrayList(scorers));
+    }
+
+    private ResolveInfo buildResolveInfo(String packageName,
+            boolean hasReceiverPermission, boolean hasScorePermission) throws Exception {
+        Mockito.when(mMockPm.checkPermission(permission.SCORE_NETWORKS, packageName))
+                .thenReturn(hasScorePermission ?
+                        PackageManager.PERMISSION_GRANTED : PackageManager.PERMISSION_DENIED);
+
+        ResolveInfo resolveInfo = new ResolveInfo();
+        resolveInfo.activityInfo = new ActivityInfo();
+        resolveInfo.activityInfo.packageName = packageName;
+        if (hasReceiverPermission) {
+            resolveInfo.activityInfo.permission = permission.BROADCAST_SCORE_NETWORKS;
+        }
+        return resolveInfo;
+    }
+}
diff --git a/graphics/java/android/graphics/drawable/VectorDrawable.java b/graphics/java/android/graphics/drawable/VectorDrawable.java
index 8fe06b5..736b143 100644
--- a/graphics/java/android/graphics/drawable/VectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/VectorDrawable.java
@@ -49,24 +49,24 @@
 import java.util.HashSet;
 
 /**
- * This lets you create a drawable based on an XML vector graphic
- * It can be defined in an XML file with the <code>&lt;vector></code> element.
+ * This lets you create a drawable based on an XML vector graphic It can be
+ * defined in an XML file with the <code>&lt;vector></code> element.
  * <p/>
  * The vector drawable has 6 elements:
  * <p/>
  * <dl>
  * <dt><code>&lt;vector></code></dt>
  * <dd>The attribute <code>android:trigger</code> defines a state change that
- * will drive the animation </dd>
+ * will drive the animation</dd>
  * <dd>The attribute <code>android:versionCode</code> defines the version of
- * VectorDrawable </dd>
+ * VectorDrawable</dd>
  * <dt><code>&lt;size></code></dt>
  * <dd>Used to defined the intrinsic Width Height size of the drawable using
- * <code>android:width</code> and <code>android:height</code> </dd>
+ * <code>android:width</code> and <code>android:height</code></dd>
  * <dt><code>&lt;viewport></code></dt>
  * <dd>Used to defined the size of the virtual canvas the paths are drawn on.
- * The size is defined using the attributes <code>android:viewportHeight
- * </code> <code>android:viewportWidth</code></dd>
+ * The size is defined using the attributes <code>android:viewportHeight</code>
+ * <code>android:viewportWidth</code></dd>
  * <dt><code>&lt;group></code></dt>
  * <dd>Defines a "key frame" in the animation if there is only one group the
  * drawable is static 2D image that has no animation.</dd>
@@ -80,7 +80,8 @@
  * <dt><code>android:fill</code>
  * <dd>Defines the color to fill the path (none if not present).</dd></dt>
  * <dt><code>android:stroke</code>
- * <dd>Defines the color to draw the path outline (none if not present).</dd></dt>
+ * <dd>Defines the color to draw the path outline (none if not present).</dd>
+ * </dt>
  * <dt><code>android:strokeWidth</code>
  * <dd>The width a path stroke</dd></dt>
  * <dt><code>android:strokeOpacity</code>
@@ -98,7 +99,8 @@
  * <dt><code>android:trimPathEnd</code>
  * <dd>The fraction of the path to trim from the end from 0 to 1</dd></dt>
  * <dt><code>android:trimPathOffset</code>
- * <dd>Shift trim region (allows showed region to include the start and end) from 0 to 1</dd></dt>
+ * <dd>Shift trim region (allows showed region to include the start and end)
+ * from 0 to 1</dd></dt>
  * <dt><code>android:clipToPath</code>
  * <dd>Path will set the clip path</dd></dt>
  * <dt><code>android:strokeLineCap</code>
@@ -135,19 +137,20 @@
  * <dt><code>android:sequence</code>
  * <dd>Configures this animation sequence between the named paths.</dd></dt>
  * <dt><code>android:limitTo</code>
- * <dd>Limits an animation to only interpolate the selected variable
- * unlimited, path, rotation, trimPathStart, trimPathEnd, trimPathOffset</dd></dt>
+ * <dd>Limits an animation to only interpolate the selected variable unlimited,
+ * path, rotation, trimPathStart, trimPathEnd, trimPathOffset</dd></dt>
  * <dt><code>android:repeatCount</code>
  * <dd>Number of times to loop this aspect of the animation</dd></dt>
  * <dt><code>android:durations</code>
- * <dd>The duration of each step in the animation in milliseconds
- * Must contain the number of named paths - 1</dd></dt>
+ * <dd>The duration of each step in the animation in milliseconds Must contain
+ * the number of named paths - 1</dd></dt>
  * <dt><code>android:startDelay</code>
  * <dd></dd></dt>
  * <dt><code>android:repeatStyle</code>
- *  <dd>when repeating how does it repeat back and forth or a to b: forward, inAndOut</dd></dt>
+ * <dd>when repeating how does it repeat back and forth or a to b: forward,
+ * inAndOut</dd></dt>
  * <dt><code>android:animate</code>
- *  <dd>linear, accelerate, decelerate, easing</dd></dt>
+ * <dd>linear, accelerate, decelerate, easing</dd></dt>
  * </dl>
  * </dd>
  */
@@ -193,8 +196,10 @@
         }
 
         long duration = mVectorState.mVAnimatedPath.getTotalAnimationDuration();
-        if (duration == -1) { // if it set to infinite set to 1 hour
-            duration = DEFAULT_INFINITE_DURATION; // TODO define correct approach for infinite
+        if (duration == -1) {
+            // If duration is infinite, set to 1 hour.
+            // TODO: Define correct approach for infinite.
+            duration = DEFAULT_INFINITE_DURATION;
             mVectorState.mBasicAnimator.setFloatValues(0, duration / 1000);
             mVectorState.mBasicAnimator.setInterpolator(new LinearInterpolator());
         }
@@ -219,7 +224,7 @@
     }
 
     /**
-     * Stops the animation.
+     * Stops the animation and moves to the end state.
      */
     public void stop() {
         mVectorState.mBasicAnimator.end();
@@ -255,11 +260,11 @@
 
     /**
      * Defines what this animation should do when it reaches the end. This
-     * setting is applied only when the repeat count is either greater than
-     * 0 or {@link ValueAnimator#INFINITE}.
+     * setting is applied only when the repeat count is either greater than 0 or
+     * {@link ValueAnimator#INFINITE}.
      *
-     * @param mode the animation mode, either {@link ValueAnimator#RESTART}
-     *        or {@link ValueAnimator#REVERSE}
+     * @param mode the animation mode, either {@link ValueAnimator#RESTART} or
+     *            {@link ValueAnimator#REVERSE}
      */
     public void setRepeatMode(int mode) {
         mVectorState.mBasicAnimator.setRepeatMode(mode);
@@ -304,16 +309,16 @@
         return true;
     }
 
-    private void animateForward(){
+    private void animateForward() {
         if (!mVectorState.mBasicAnimator.isStarted()) {
-            mVectorState.mBasicAnimator.setFloatValues(0,1);
+            mVectorState.mBasicAnimator.setFloatValues(0, 1);
             start();
         }
     }
 
-    private void animateBackward(){
+    private void animateBackward() {
         if (!mVectorState.mBasicAnimator.isStarted()) {
-            mVectorState.mBasicAnimator.setFloatValues(.99f,0);
+            mVectorState.mBasicAnimator.setFloatValues(.99f, 0);
             start();
         }
     }
@@ -347,8 +352,8 @@
     }
 
     /**
-     * Sets padding for this shape, defined by a Rect object. Define the padding in the Rect object
-     * as: left, top, right, bottom.
+     * Sets padding for this shape, defined by a Rect object. Define the padding
+     * in the Rect object as: left, top, right, bottom.
      */
     public void setPadding(Rect padding) {
         setPadding(padding.left, padding.top, padding.right, padding.bottom);
@@ -472,13 +477,14 @@
                     currentGroup = new VGroup();
                     animatedPath.mGroupList.add(currentGroup);
                     noGroupTag = false;
-                }  else if (SHAPE_VECTOR.equals(tagName)) {
+                } else if (SHAPE_VECTOR.equals(tagName)) {
                     final TypedArray a = res.obtainAttributes(attrs, R.styleable.VectorDrawable);
                     animatedPath.setTrigger(a.getInteger(R.styleable.VectorDrawable_trigger, 0));
 
                     // Parsing the version information.
                     // Right now, we only support version "1".
-                    // If the xml didn't specify the version number, the default version is "1".
+                    // If the xml didn't specify the version number, the default
+                    // version is "1".
                     final int versionCode = a.getInt(R.styleable.VectorDrawable_versionCode, 1);
                     if (versionCode != 1) {
                         throw new IllegalArgumentException(
@@ -499,22 +505,22 @@
                 tag.append(SHAPE_SIZE);
             }
 
-            if  (noViewportTag){
-                if (tag.length()>0) {
+            if (noViewportTag) {
+                if (tag.length() > 0) {
                     tag.append(" & ");
                 }
                 tag.append(SHAPE_SIZE);
             }
 
-            if  (noGroupTag){
-                if (tag.length()>0) {
+            if (noGroupTag) {
+                if (tag.length() > 0) {
                     tag.append(" & ");
                 }
                 tag.append(SHAPE_GROUP);
             }
 
-            if  (noPathTag){
-                if (tag.length()>0) {
+            if (noPathTag) {
+                if (tag.length() > 0) {
                     tag.append(" or ");
                 }
                 tag.append(SHAPE_PATH);
@@ -533,7 +539,8 @@
 
         long duration = mVectorState.mVAnimatedPath.getTotalAnimationDuration();
         if (duration == -1) { // if it set to infinite set to 1 hour
-            duration = DEFAULT_INFINITE_DURATION; // TODO define correct approach for infinite
+            duration = DEFAULT_INFINITE_DURATION; // TODO define correct
+                                                  // approach for infinite
             mVectorState.mBasicAnimator.setFloatValues(0, duration / 1000);
             mVectorState.mBasicAnimator.setInterpolator(new LinearInterpolator());
         }
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 16baf77..4ed73c3 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -445,6 +445,10 @@
     DrawGlInfo dummyInfo;
     memset(&dummyInfo, 0, sizeof(DrawGlInfo));
     (*functor)(mode, &dummyInfo);
+
+    if (mCanvas) {
+        mCanvas->resume();
+    }
 }
 
 bool CanvasContext::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap) {
diff --git a/media/java/android/media/WebVttRenderer.java b/media/java/android/media/WebVttRenderer.java
index 58d3520..1c9730f 100644
--- a/media/java/android/media/WebVttRenderer.java
+++ b/media/java/android/media/WebVttRenderer.java
@@ -558,7 +558,11 @@
     }
 }
 
-/** @hide */
+/**
+ *  Supporting July 10 2013 draft version
+ *
+ *  @hide
+ */
 class WebVttParser {
     private static final String TAG = "WebVttParser";
     private Phase mPhase;
@@ -726,15 +730,15 @@
                                 "has invalid value", e.getMessage(), value);
                     }
                 } else if (name.equals("lines")) {
-                    try {
-                        int lines = Integer.parseInt(value);
-                        if (lines >= 0) {
-                            region.mLines = lines;
-                        } else {
-                            log_warning("region setting", name, "is negative", value);
+                    if (value.matches(".*[^0-9].*")) {
+                        log_warning("lines", name, "contains an invalid character", value);
+                    } else {
+                        try {
+                            region.mLines = Integer.parseInt(value);
+                            assert(region.mLines >= 0); // lines contains only digits
+                        } catch (NumberFormatException e) {
+                            log_warning("region setting", name, "is not numeric", value);
                         }
-                    } catch (NumberFormatException e) {
-                        log_warning("region setting", name, "is not numeric", value);
                     }
                 } else if (name.equals("regionanchor") ||
                            name.equals("viewportanchor")) {
@@ -872,26 +876,23 @@
                     }
                 } else if (name.equals("line")) {
                     try {
-                        int linePosition;
                         /* TRICKY: we know that there are no spaces in value */
                         assert(value.indexOf(' ') < 0);
                         if (value.endsWith("%")) {
-                            linePosition = Integer.parseInt(
-                                    value.substring(0, value.length() - 1));
-                            if (linePosition < 0 || linePosition > 100) {
-                                log_warning("cue setting", name, "is out of range", value);
-                                continue;
-                            }
                             mCue.mSnapToLines = false;
-                            mCue.mLinePosition = linePosition;
+                            mCue.mLinePosition = parseIntPercentage(value);
+                        } else if (value.matches(".*[^0-9].*")) {
+                            log_warning("cue setting", name,
+                                    "contains an invalid character", value);
                         } else {
                             mCue.mSnapToLines = true;
                             mCue.mLinePosition = Integer.parseInt(value);
                         }
                     } catch (NumberFormatException e) {
                         log_warning("cue setting", name,
-                               "is not numeric or percentage", value);
+                                "is not numeric or percentage", value);
                     }
+                    // TODO: add support for optional alignment value [,start|middle|end]
                 } else if (name.equals("position")) {
                     try {
                         mCue.mTextPosition = parseIntPercentage(value);
diff --git a/media/jni/android_media_MediaRecorder.cpp b/media/jni/android_media_MediaRecorder.cpp
index fd69cad..1685a44 100644
--- a/media/jni/android_media_MediaRecorder.cpp
+++ b/media/jni/android_media_MediaRecorder.cpp
@@ -14,6 +14,13 @@
  * limitations under the License.
  */
 
+#include <assert.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <limits.h>
+#include <stdio.h>
+#include <unistd.h>
+
 //#define LOG_NDEBUG 0
 #define LOG_TAG "MediaRecorderJNI"
 #include <utils/Log.h>
@@ -22,11 +29,6 @@
 #include <camera/ICameraService.h>
 #include <camera/Camera.h>
 #include <media/mediarecorder.h>
-#include <stdio.h>
-#include <assert.h>
-#include <limits.h>
-#include <unistd.h>
-#include <fcntl.h>
 #include <utils/threads.h>
 
 #include "jni.h"
@@ -303,7 +305,7 @@
     sp<MediaRecorder> mr = getMediaRecorder(env, thiz);
 
     char params[64];
-    sprintf(params, "max-filesize=%lld", max_filesize_bytes);
+    sprintf(params, "max-filesize=%" PRId64, max_filesize_bytes);
 
     process_media_recorder_call(env, mr->setParameters(String8(params)), "java/lang/RuntimeException", "setMaxFileSize failed.");
 }
diff --git a/media/jni/mediaeditor/VideoEditorMain.cpp b/media/jni/mediaeditor/VideoEditorMain.cpp
index c0f6a95..0894d74 100644
--- a/media/jni/mediaeditor/VideoEditorMain.cpp
+++ b/media/jni/mediaeditor/VideoEditorMain.cpp
@@ -16,6 +16,7 @@
 #define LOG_NDEBUG 1
 #define LOG_TAG "VideoEditorMain"
 #include <dlfcn.h>
+#include <inttypes.h>
 #include <stdio.h>
 #include <unistd.h>
 #include <utils/Log.h>
@@ -3371,7 +3372,7 @@
     err = M4OSA_fileReadOpen (&inputFileHandle, pInputFileURL, M4OSA_kFileRead);
     if (inputFileHandle == M4OSA_NULL) {
         VIDEOEDIT_LOG_ERROR(ANDROID_LOG_INFO, "VIDEO_EDITOR",
-            "M4MA_generateAudioGraphFile: Cannot open input file 0x%lx", err);
+            "M4MA_generateAudioGraphFile: Cannot open input file 0x%" PRIx32, err);
         return err;
     }
 
@@ -3405,7 +3406,7 @@
         bufferIn.m_bufferSize = samplesCountInBytes*sizeof(M4OSA_UInt16);
     } else {
         VIDEOEDIT_LOG_ERROR(ANDROID_LOG_INFO, "VIDEO_EDITOR",
-            "M4MA_generateAudioGraphFile: Malloc failed for bufferIn.m_dataAddress 0x%lx",
+            "M4MA_generateAudioGraphFile: Malloc failed for bufferIn.m_dataAddress 0x%" PRIx32,
             M4ERR_ALLOC);
         return M4ERR_ALLOC;
     }
@@ -3445,7 +3446,7 @@
         if (err != M4NO_ERROR) {
             // if out value of bytes-read is 0, break
             if ( numBytesToRead == 0) {
-                VIDEOEDIT_LOG_ERROR(ANDROID_LOG_INFO, "VIDEO_EDITOR", "numBytesToRead 0x%lx",
+                VIDEOEDIT_LOG_ERROR(ANDROID_LOG_INFO, "VIDEO_EDITOR", "numBytesToRead 0x%" PRIx32,
                 numBytesToRead);
                 break; /* stop if file is empty or EOF */
             }
@@ -3497,7 +3498,7 @@
 
     } while (numBytesToRead != 0);
 
-    VIDEOEDIT_LOG_ERROR(ANDROID_LOG_INFO, "VIDEO_EDITOR", "loop 0x%lx", volumeValuesCount);
+    VIDEOEDIT_LOG_ERROR(ANDROID_LOG_INFO, "VIDEO_EDITOR", "loop 0x%" PRIx32, volumeValuesCount);
 
     /* if some error occured in fwrite */
     if (numBytesToRead != 0) {
diff --git a/packages/BackupRestoreConfirmation/res/values-sk/strings.xml b/packages/BackupRestoreConfirmation/res/values-sk/strings.xml
index 21e21b5..12f562b 100644
--- a/packages/BackupRestoreConfirmation/res/values-sk/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-sk/strings.xml
@@ -24,7 +24,7 @@
     <string name="restore_confirm_text" msgid="7499866728030461776">"Z pripojeného počítača bolo vyžiadané úplné obnovenie všetkých údajov. Chcete túto akciu povoliť?\n\nAk ste toto obnovenie nevyžiadali vy, túto operáciu nepovoľujte. Táto akcia nahradí všetky údaje v zariadení."</string>
     <string name="allow_restore_button_label" msgid="3081286752277127827">"Obnoviť údaje"</string>
     <string name="deny_restore_button_label" msgid="1724367334453104378">"Neobnoviť"</string>
-    <string name="current_password_text" msgid="8268189555578298067">"Zadajte svoje aktuálne heslo pre zálohu nižšie:"</string>
+    <string name="current_password_text" msgid="8268189555578298067">"Zadajte svoje aktuálne heslo záloh nižšie:"</string>
     <string name="device_encryption_restore_text" msgid="1570864916855208992">"Zadajte svoje heslo na šifrovanie zariadenia nižšie."</string>
     <string name="device_encryption_backup_text" msgid="5866590762672844664">"Zadajte svoje heslo na šifrovanie zariadenia nižšie. Bude tiež použité na šifrovanie archívu zálohy."</string>
     <string name="backup_enc_password_text" msgid="4981585714795233099">"Zadajte heslo, ktoré sa použije pri šifrovaní údajov úplnej zálohy. Ak pole ponecháte prázdne, použije sa vaše aktuálne heslo zálohy:"</string>
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java
index 7cfd684..f85e29f 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java
@@ -22,10 +22,8 @@
 import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
 import com.android.keyguard.KeyguardUpdateMonitor.DisplayClientState;
 
-import android.app.Activity;
 import android.app.ActivityManager;
 import android.app.ActivityOptions;
-import android.app.SearchManager;
 import android.app.admin.DevicePolicyManager;
 import android.appwidget.AppWidgetHost;
 import android.appwidget.AppWidgetHostView;
@@ -36,7 +34,6 @@
 import android.content.Intent;
 import android.content.IntentSender;
 import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.pm.UserInfo;
 import android.content.res.Resources;
 import android.graphics.Rect;
 import android.media.RemoteControlClient;
@@ -44,7 +41,6 @@
 import android.os.Looper;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.os.SystemClock;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.Settings;
@@ -55,9 +51,7 @@
 import android.view.View;
 import android.widget.RemoteViews.OnClickHandler;
 
-import java.io.File;
 import java.lang.ref.WeakReference;
-import java.util.List;
 
 public class KeyguardHostView extends KeyguardViewBase {
     private static final String TAG = "KeyguardHostView";
@@ -595,16 +589,16 @@
     };
 
     @Override
-    public void onScreenTurnedOn() {
-        super.onScreenTurnedOn();
+    public void onResume() {
+        super.onResume();
         if (mViewStateManager != null) {
             mViewStateManager.showUsabilityHints();
         }
     }
 
     @Override
-    public void onScreenTurnedOff() {
-        super.onScreenTurnedOff();
+    public void onPause() {
+        super.onPause();
         // We use mAppWidgetToShow to show a particular widget after you add it-- once the screen
         // turns off we reset that behavior
         clearAppWidgetToShow();
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityModel.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityModel.java
index da6482a..2d492db 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityModel.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityModel.java
@@ -28,7 +28,7 @@
      * The different types of security available for {@link Mode#UnlockScreen}.
      * @see com.android.internal.policy.impl.LockPatternKeyguardView#getUnlockMode()
      */
-    enum SecurityMode {
+    public enum SecurityMode {
         Invalid, // NULL state
         None, // No security enabled
         Pattern, // Unlock by drawing a pattern.
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardViewBase.java b/packages/Keyguard/src/com/android/keyguard/KeyguardViewBase.java
index bc0f364..d8e5b8a 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardViewBase.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardViewBase.java
@@ -217,9 +217,9 @@
     }
 
     /**
-     * Called when the screen turned off.
+     * Called when the Keyguard is not actively shown anymore on the screen.
      */
-    public void onScreenTurnedOff() {
+    public void onPause() {
         if (DEBUG) Log.d(TAG, String.format("screen off, instance %s at %s",
                 Integer.toHexString(hashCode()), SystemClock.uptimeMillis()));
         // Once the screen turns off, we no longer consider this to be first boot and we want the
@@ -231,9 +231,9 @@
     }
 
     /**
-     * Called when the screen turned on.
+     * Called when the Keyguard is actively shown on the screen.
      */
-    public void onScreenTurnedOn() {
+    public void onResume() {
         if (DEBUG) Log.d(TAG, "screen on, instance " + Integer.toHexString(hashCode()));
         mSecurityContainer.showPrimarySecurityScreen(false);
         mSecurityContainer.onResume(KeyguardSecurityView.SCREEN_ON);
@@ -476,6 +476,10 @@
         mSecurityContainer.setLockPatternUtils(utils);
     }
 
+    public SecurityMode getSecurityMode() {
+        return mSecurityContainer.getSecurityMode();
+    }
+
     protected abstract void onUserSwitching(boolean switching);
 
     protected abstract void onCreateOptions(Bundle options);
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_notify_open_normal.png b/packages/SystemUI/res/drawable-hdpi/ic_notify_open_normal.png
index 092b561..3c0dc4e 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_notify_open_normal.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_notify_open_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_notify_quicksettings_normal.png b/packages/SystemUI/res/drawable-hdpi/ic_notify_quicksettings_normal.png
index 064860d..3b1944d 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_notify_quicksettings_normal.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_notify_quicksettings_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_notify_open_normal.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_notify_open_normal.png
deleted file mode 100644
index 13f6b7f..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_notify_open_normal.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_notify_quicksettings_normal.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_notify_quicksettings_normal.png
deleted file mode 100644
index ecdb240..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_notify_quicksettings_normal.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_notify_open_normal.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_notify_open_normal.png
deleted file mode 100644
index c98911c..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_notify_open_normal.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_notify_quicksettings_normal.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_notify_quicksettings_normal.png
deleted file mode 100644
index bb99022..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_notify_quicksettings_normal.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_notify_open_normal.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_notify_open_normal.png
deleted file mode 100644
index d9d8b13..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_notify_open_normal.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_notify_quicksettings_normal.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_notify_quicksettings_normal.png
deleted file mode 100644
index 09e0a3c..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_notify_quicksettings_normal.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_notify_open_normal.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_notify_open_normal.png
deleted file mode 100644
index c0855b5..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_notify_open_normal.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_notify_quicksettings_normal.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_notify_quicksettings_normal.png
deleted file mode 100644
index e3fb992..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_notify_quicksettings_normal.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_notify_open_normal.png b/packages/SystemUI/res/drawable-mdpi/ic_notify_open_normal.png
index ae5d263..8010ce7 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_notify_open_normal.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_notify_open_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_notify_quicksettings_normal.png b/packages/SystemUI/res/drawable-mdpi/ic_notify_quicksettings_normal.png
index 32fbed4..807f607 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_notify_quicksettings_normal.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_notify_quicksettings_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_notify_open_normal.png b/packages/SystemUI/res/drawable-xhdpi/ic_notify_open_normal.png
index 990f8bb..6d46fdd 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_notify_open_normal.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_notify_open_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_notify_quicksettings_normal.png b/packages/SystemUI/res/drawable-xhdpi/ic_notify_quicksettings_normal.png
index 96eaafe..e562bc2 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_notify_quicksettings_normal.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_notify_quicksettings_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_notify_open_normal.png b/packages/SystemUI/res/drawable-xxhdpi/ic_notify_open_normal.png
index 60579f9..7742207 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_notify_open_normal.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_notify_open_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_notify_quicksettings_normal.png b/packages/SystemUI/res/drawable-xxhdpi/ic_notify_quicksettings_normal.png
index abb9b18..a2e8fe1 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_notify_quicksettings_normal.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_notify_quicksettings_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/layout/flip_settings.xml b/packages/SystemUI/res/layout/flip_settings.xml
index 1b8898c5..28d9625 100644
--- a/packages/SystemUI/res/layout/flip_settings.xml
+++ b/packages/SystemUI/res/layout/flip_settings.xml
@@ -14,18 +14,12 @@
      limitations under the License.
 -->
 
-<com.android.systemui.statusbar.phone.QuickSettingsScrollView
+<com.android.systemui.statusbar.phone.QuickSettingsContainerView
     xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/quick_settings_container"
+    android:padding="@dimen/notification_side_padding"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:layout_marginBottom="@dimen/close_handle_underlap"
-    android:overScrollMode="ifContentScrolls"
-    >
-    <com.android.systemui.statusbar.phone.QuickSettingsContainerView
-        android:id="@+id/quick_settings_container"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:animateLayoutChanges="true"
-        android:columnCount="@integer/quick_settings_num_columns"
-        />
-</com.android.systemui.statusbar.phone.QuickSettingsScrollView>
\ No newline at end of file
+    android:background="#5f000000"
+    android:animateLayoutChanges="true"
+    android:columnCount="@integer/quick_settings_num_columns" />
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml
index 8f4417e..8a3f090 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded.xml
@@ -41,7 +41,7 @@
         android:layout_width="50dp"
         android:layout_height="50dp"
         android:layout_gravity="right|top"
-        android:layout_marginTop="@*android:dimen/status_bar_height"
+        android:layout_marginTop="@dimen/status_bar_height"
         android:visibility="gone" />
 
     <LinearLayout
diff --git a/packages/SystemUI/res/layout/super_status_bar.xml b/packages/SystemUI/res/layout/super_status_bar.xml
index 9176d24..2b01a06 100644
--- a/packages/SystemUI/res/layout/super_status_bar.xml
+++ b/packages/SystemUI/res/layout/super_status_bar.xml
@@ -27,14 +27,14 @@
 
     <include layout="@layout/status_bar"
         android:layout_width="match_parent"
-        android:layout_height="@*android:dimen/status_bar_height" />
+        android:layout_height="@dimen/status_bar_height" />
 
     <com.android.systemui.statusbar.phone.PanelHolder
         android:id="@+id/panel_holder"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:layout_marginTop="@dimen/panel_holder_padding_top"
-        android:layout_marginBottom="@*android:dimen/navigation_bar_height">
+        android:layout_marginBottom="@dimen/navigation_bar_height">
         <include layout="@layout/status_bar_expanded"
             android:layout_width="@dimen/notification_panel_width"
             android:layout_height="wrap_content"
diff --git a/packages/SystemUI/res/values-land/config.xml b/packages/SystemUI/res/values-land/config.xml
index 6476d88..7223773 100644
--- a/packages/SystemUI/res/values-land/config.xml
+++ b/packages/SystemUI/res/values-land/config.xml
@@ -27,6 +27,9 @@
     <!-- The number of columns in the QuickSettings -->
     <integer name="quick_settings_num_columns">6</integer>
 
+    <!-- The maximum number of rows in the QuickSettings -->
+    <integer name="quick_settings_max_rows">2</integer>
+
     <!-- The number of columns that the top level tiles span in the QuickSettings -->
     <integer name="quick_settings_user_time_settings_tile_span">2</integer>
 </resources>
diff --git a/packages/SystemUI/res/values-sw600dp/config.xml b/packages/SystemUI/res/values-sw600dp/config.xml
index 440ead6..c6bc44d 100644
--- a/packages/SystemUI/res/values-sw600dp/config.xml
+++ b/packages/SystemUI/res/values-sw600dp/config.xml
@@ -26,6 +26,9 @@
     <!-- The number of columns in the QuickSettings -->
     <integer name="quick_settings_num_columns">3</integer>
 
+    <!-- The maximum number of rows in the QuickSettings -->
+    <integer name="quick_settings_max_rows">4</integer>
+
     <!-- The number of columns that the top level tiles span in the QuickSettings -->
     <integer name="quick_settings_user_time_settings_tile_span">1</integer>
 
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 73e3e05..f908a1e 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -81,6 +81,12 @@
     <!-- The number of columns in the QuickSettings -->
     <integer name="quick_settings_num_columns">3</integer>
 
+    <!-- The maximum number of rows in the QuickSettings -->
+    <integer name="quick_settings_max_rows">4</integer>
+
+    <!-- The maximum number of rows in the QuickSettings when on the keyguard -->
+    <integer name="quick_settings_max_rows_keyguard">3</integer>
+
     <!-- The number of columns that the top level tiles span in the QuickSettings -->
     <integer name="quick_settings_user_time_settings_tile_span">1</integer>
 
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index e7959ab..9aacf42 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -269,4 +269,7 @@
 
     <!-- Camera affordance drag distance -->
     <dimen name="camera_drag_distance">100dp</dimen>
+
+    <dimen name="quick_settings_tmp_scrim_stroke_width">8dp</dimen>
+    <dimen name="quick_settings_tmp_scrim_text_size">30dp</dimen>
 </resources>
diff --git a/packages/SystemUI/res/values/internal.xml b/packages/SystemUI/res/values/internal.xml
new file mode 100644
index 0000000..ddaab942
--- /dev/null
+++ b/packages/SystemUI/res/values/internal.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+    <dimen name="status_bar_height">@*android:dimen/status_bar_height</dimen>
+    <dimen name="navigation_bar_height">@*android:dimen/navigation_bar_height</dimen>
+    <drawable name="notification_quantum_bg">@*android:drawable/notification_quantum_bg</drawable>
+</resources>
+
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index bb39d36..cbfc266 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -1285,6 +1285,9 @@
                     flags |= StatusBarManager.DISABLE_SEARCH;
                 }
             }
+            if (isShowingAndNotOccluded()) {
+                flags |= StatusBarManager.DISABLE_HOME;
+            }
 
             if (DEBUG) {
                 Log.d(TAG, "adjustStatusBarLocked: mShowing=" + mShowing + " mOccluded=" + mOccluded
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
index 7cbde36..f2054a2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
@@ -17,20 +17,18 @@
 package com.android.systemui.statusbar.phone;
 
 import android.content.Context;
-import android.os.RemoteException;
-import android.util.Slog;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 
-import com.android.internal.policy.IKeyguardShowCallback;
 import com.android.internal.widget.LockPatternUtils;
-import com.android.keyguard.KeyguardHostView;
 import com.android.keyguard.KeyguardViewBase;
 import com.android.keyguard.R;
 import com.android.keyguard.ViewMediatorCallback;
 import com.android.systemui.keyguard.KeyguardViewMediator;
 
+import static com.android.keyguard.KeyguardSecurityModel.*;
+
 /**
  * A class which manages the bouncer on the lockscreen.
  */
@@ -66,6 +64,7 @@
         if (!mKeyguardView.dismiss()) {
             mRoot.setVisibility(View.VISIBLE);
             mKeyguardView.requestFocus();
+            mKeyguardView.onResume();
         }
     }
 
@@ -84,14 +83,8 @@
     }
 
     public void onScreenTurnedOff() {
-        if (mKeyguardView != null) {
-            mKeyguardView.onScreenTurnedOff();
-        }
-    }
-
-    public void onScreenTurnedOn() {
-        if (mKeyguardView != null) {
-            mKeyguardView.onScreenTurnedOn();
+        if (mKeyguardView != null && mRoot.getVisibility() == View.VISIBLE) {
+            mKeyguardView.onPause();
         }
     }
 
@@ -136,4 +129,31 @@
     public boolean onBackPressed() {
         return mKeyguardView != null && mKeyguardView.handleBackKey();
     }
+
+    /**
+     * @return True if and only if the current security method should be shown before showing
+     *         the notifications on Keyguard, like SIM PIN/PUK.
+     */
+    public boolean needsFullscreenBouncer() {
+        if (mKeyguardView != null) {
+            SecurityMode mode = mKeyguardView.getSecurityMode();
+            return mode == SecurityMode.SimPin
+                    || mode == SecurityMode.SimPuk;
+        }
+        return false;
+    }
+
+    public boolean onMenuPressed() {
+        ensureView();
+        if (mKeyguardView.handleMenuKey()) {
+
+            // We need to show it in case it is secure. If not, it will get dismissed in any case.
+            mRoot.setVisibility(View.VISIBLE);
+            mKeyguardView.requestFocus();
+            mKeyguardView.onResume();
+            return true;
+        } else {
+            return false;
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index db26a42..7ca672d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -205,6 +205,15 @@
                         mContext.startActivityAsUser(
                                 new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE),
                                 UserHandle.CURRENT);
+                        cameraButtonView.animate().x(-cameraButtonView.getWidth())
+                                .setInterpolator(new AccelerateInterpolator(2f)).withEndAction(
+                                new Runnable() {
+                                    @Override
+                                    public void run() {
+                                        cameraButtonView.setTranslationX(0);
+                                    }
+                                });
+                        mSkipCancelAnimation = true;
                     }
                     if (realX < mStartX - mScaledTouchSlop) {
                         mTouchSlopReached = true;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 6f93bed..45ac50b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -30,11 +30,14 @@
     public static final boolean DEBUG_GESTURES = true;
 
     PhoneStatusBar mStatusBar;
+    private View mHeader;
+    private View mKeyguardStatusView;
+
     private NotificationStackScrollLayout mNotificationStackScroller;
     private int[] mTempLocation = new int[2];
     private int[] mTempChildLocation = new int[2];
     private View mNotificationParent;
-
+    private boolean mTrackingSettings;
 
     public NotificationPanelView(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -59,6 +62,8 @@
     protected void onFinishInflate() {
         super.onFinishInflate();
 
+        mHeader = findViewById(R.id.header);
+        mKeyguardStatusView = findViewById(R.id.keyguard_status_view);
         mNotificationStackScroller = (NotificationStackScrollLayout)
                 findViewById(R.id.notification_stack_scroller);
         mNotificationParent = findViewById(R.id.notification_container_parent);
@@ -99,9 +104,38 @@
     }
 
     @Override
+    public boolean onInterceptTouchEvent(MotionEvent event) {
+        // intercept for quick settings
+        if (event.getAction() == MotionEvent.ACTION_DOWN) {
+            final View target = mStatusBar.isOnKeyguard() ?  mKeyguardStatusView : mHeader;
+            final boolean inTarget = PhoneStatusBar.inBounds(target, event, true);
+            if (inTarget && !isInSettings()) {
+                mTrackingSettings = true;
+                return true;
+            }
+            if (!inTarget && isInSettings()) {
+                mTrackingSettings = true;
+                return true;
+            }
+        }
+        return super.onInterceptTouchEvent(event);
+    }
+
+    @Override
     public boolean onTouchEvent(MotionEvent event) {
         // TODO: Handle doublefinger swipe to notifications again. Look at history for a reference
         // implementation.
+        if (mTrackingSettings) {
+            mStatusBar.onSettingsEvent(event);
+            if (event.getAction() == MotionEvent.ACTION_UP
+                    || event.getAction() == MotionEvent.ACTION_CANCEL) {
+                mTrackingSettings = false;
+            }
+            return true;
+        }
+        if (isInSettings()) {
+            return true;
+        }
         return super.onTouchEvent(event);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index e89544c..d577070 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -73,6 +73,7 @@
 import android.view.MotionEvent;
 import android.view.VelocityTracker;
 import android.view.View;
+import android.view.ViewConfiguration;
 import android.view.ViewGroup;
 import android.view.ViewGroup.LayoutParams;
 import android.view.ViewPropertyAnimator;
@@ -97,11 +98,9 @@
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.GestureRecorder;
 import com.android.systemui.statusbar.InterceptedNotifications;
-import com.android.systemui.statusbar.LatestItemView;
 import com.android.systemui.statusbar.NotificationData;
 import com.android.systemui.statusbar.NotificationData.Entry;
 import com.android.systemui.statusbar.NotificationOverflowContainer;
-import com.android.systemui.statusbar.NotificationOverflowIconsView;
 import com.android.systemui.statusbar.SignalClusterView;
 import com.android.systemui.statusbar.StatusBarIconView;
 import com.android.systemui.statusbar.policy.BatteryController;
@@ -233,8 +232,7 @@
     int mKeyguardMaxNotificationCount;
     View mDateTimeView;
     View mClearButton;
-    ImageView mSettingsButton, mNotificationButton;
-    View mKeyguardSettingsFlipButton;
+    FlipperButton mHeaderFlipper, mKeyguardFlipper;
 
     // carrier/wifi label
     private TextView mCarrierLabel;
@@ -314,9 +312,9 @@
             if (MULTIUSER_DEBUG) Log.d(TAG, String.format("User setup changed: " +
                     "selfChange=%s userSetup=%s mUserSetup=%s",
                     selfChange, userSetup, mUserSetup));
-            if (mSettingsButton != null && mHasFlipSettings) {
-                mSettingsButton.setVisibility(userSetup ? View.VISIBLE : View.INVISIBLE);
-            }
+            mHeaderFlipper.userSetup(userSetup);
+            mKeyguardFlipper.userSetup(userSetup);
+
             if (mSettingsPanel != null) {
                 mSettingsPanel.setEnabled(userSetup);
             }
@@ -371,6 +369,11 @@
 
     private Runnable mOnFlipRunnable;
     private InterceptedNotifications mIntercepted;
+    private VelocityTracker mSettingsTracker;
+    private float mSettingsDownY;
+    private boolean mSettingsCancelled;
+    private boolean mSettingsClosing;
+    private int mNotificationPadding;
 
     private final OnChildLocationsChangedListener mOnChildLocationsChangedListener =
             new OnChildLocationsChangedListener() {
@@ -631,35 +634,10 @@
             mDateTimeView.setEnabled(true);
         }
 
-        mSettingsButton = (ImageView) mStatusBarWindow.findViewById(R.id.settings_button);
-        if (mSettingsButton != null) {
-            mSettingsButton.setOnClickListener(mSettingsButtonListener);
-            if (mHasSettingsPanel) {
-                if (mStatusBarView.hasFullWidthNotifications()) {
-                    // the settings panel is hiding behind this button
-                    mSettingsButton.setImageResource(R.drawable.ic_notify_quicksettings);
-                    mSettingsButton.setVisibility(View.VISIBLE);
-                } else {
-                    // there is a settings panel, but it's on the other side of the (large) screen
-                    final View buttonHolder = mStatusBarWindow.findViewById(
-                            R.id.settings_button_holder);
-                    if (buttonHolder != null) {
-                        buttonHolder.setVisibility(View.GONE);
-                    }
-                }
-            } else {
-                // no settings panel, go straight to settings
-                mSettingsButton.setVisibility(View.VISIBLE);
-                mSettingsButton.setImageResource(R.drawable.ic_notify_settings);
-            }
-        }
-        if (mHasFlipSettings) {
-            mNotificationButton = (ImageView) mStatusBarWindow.findViewById(
-                    R.id.notification_button);
-            if (mNotificationButton != null) {
-                mNotificationButton.setOnClickListener(mNotificationButtonListener);
-            }
-        }
+        mHeaderFlipper = new FlipperButton(mNotificationPanelHeader
+                .findViewById(R.id.settings_button_holder));
+        ViewStub flipStub = (ViewStub) mStatusBarWindow.findViewById(R.id.keyguard_flip_stub);
+        mKeyguardFlipper = new FlipperButton(flipStub.inflate());
 
         if (!mNotificationPanelIsFullScreenWidth) {
             mNotificationPanel.setSystemUiVisibility(
@@ -735,6 +713,8 @@
         }
 
         // Quick Settings (where available, some restrictions apply)
+        mNotificationPadding = mContext.getResources()
+                .getDimensionPixelSize(R.dimen.notification_side_padding);
         if (mHasSettingsPanel) {
             // first, figure out where quick settings should be inflated
             final View settings_stub;
@@ -803,6 +783,87 @@
         return mStatusBarView;
     }
 
+    public boolean onSettingsEvent(MotionEvent event) {
+        if (mSettingsTracker != null) {
+            mSettingsTracker.addMovement(event);
+        }
+
+        if (event.getAction() == MotionEvent.ACTION_DOWN) {
+            mSettingsTracker = VelocityTracker.obtain();
+            mSettingsDownY = event.getY();
+            mSettingsCancelled = false;
+            mSettingsClosing = mFlipSettingsView.getVisibility() == View.VISIBLE;
+            mFlipSettingsView.setVisibility(View.VISIBLE);
+            mStackScroller.setVisibility(View.VISIBLE);
+            positionSettings(0);
+            if (!mSettingsClosing) {
+                mFlipSettingsView.setTranslationY(-mNotificationPanel.getMeasuredHeight());
+            }
+            dispatchSettingsEvent(event);
+        } else if (mSettingsTracker != null && (event.getAction() == MotionEvent.ACTION_UP
+                || event.getAction() == MotionEvent.ACTION_CANCEL)) {
+            final float dy = event.getY() - mSettingsDownY;
+            final FlipperButton flipper = mOnKeyguard ? mKeyguardFlipper : mHeaderFlipper;
+            final boolean inButton = flipper.inHolderBounds(event);
+            final int slop = ViewConfiguration.get(mContext).getScaledTouchSlop();
+            final boolean qsTap = mSettingsClosing &&  Math.abs(dy) < slop;
+            if (!qsTap && !inButton) {
+                mSettingsTracker.computeCurrentVelocity(1000);
+                final float vy = mSettingsTracker.getYVelocity();
+                if (dy <= slop || vy <= 0) {
+                    flipToNotifications();
+                } else {
+                    flipToSettings();
+                }
+            }
+            mSettingsTracker.recycle();
+            mSettingsTracker = null;
+            dispatchSettingsEvent(event);
+        } else if (mSettingsTracker != null && event.getAction() == MotionEvent.ACTION_MOVE) {
+            final float dy = event.getY() - mSettingsDownY;
+            positionSettings(dy);
+            if (mSettingsClosing) {
+                final boolean qsTap =
+                        Math.abs(dy) < ViewConfiguration.get(mContext).getScaledTouchSlop();
+                if (!mSettingsCancelled && !qsTap) {
+                    MotionEvent cancelEvent = MotionEvent.obtainNoHistory(event);
+                    cancelEvent.setAction(MotionEvent.ACTION_CANCEL);
+                    dispatchSettingsEvent(cancelEvent);
+                    mSettingsCancelled = true;
+                }
+            } else {
+                dispatchSettingsEvent(event);
+            }
+        }
+        return true;
+    }
+
+    private void dispatchSettingsEvent(MotionEvent event) {
+        final View target = mSettingsClosing ? mFlipSettingsView : mNotificationPanelHeader;
+        final int[] targetLoc = new int[2];
+        target.getLocationInWindow(targetLoc);
+        final int[] panelLoc = new int[2];
+        mNotificationPanel.getLocationInWindow(panelLoc);
+        final int dx = targetLoc[0] - panelLoc[0];
+        final int dy = targetLoc[1] - panelLoc[1];
+        event.offsetLocation(-dx, -dy);
+        target.dispatchTouchEvent(event);
+    }
+
+    private void positionSettings(float dy) {
+        final int h = mFlipSettingsView.getMeasuredHeight();
+        final int ph = mNotificationPanel.getMeasuredHeight();
+        if (mSettingsClosing) {
+            dy = Math.min(Math.max(-ph, dy), 0);
+            mFlipSettingsView.setTranslationY(dy);
+            mStackScroller.setTranslationY(ph + dy);
+        } else {
+            dy = Math.min(Math.max(0, dy), ph);
+            mFlipSettingsView.setTranslationY(-h + dy - mNotificationPadding * 2);
+            mStackScroller.setTranslationY(dy);
+        }
+    }
+
     private void startKeyguard() {
         KeyguardViewMediator keyguardViewMediator = getComponent(KeyguardViewMediator.class);
         mStatusBarKeyguardViewManager = keyguardViewMediator.registerStatusBar(this,
@@ -1163,17 +1224,8 @@
             ((ImageView)mClearButton).setImageResource(R.drawable.ic_notify_clear);
         }
 
-        if (mSettingsButton != null) {
-            // Force asset reloading
-            mSettingsButton.setImageDrawable(null);
-            mSettingsButton.setImageResource(R.drawable.ic_notify_quicksettings);
-        }
-
-        if (mNotificationButton != null) {
-            // Force asset reloading
-            mNotificationButton.setImageDrawable(null);
-            mNotificationButton.setImageResource(R.drawable.ic_notifications);
-        }
+        mHeaderFlipper.refreshLayout();
+        mKeyguardFlipper.refreshLayout();
 
         refreshAllStatusBarIcons();
     }
@@ -1228,9 +1280,8 @@
             }
         }
 
-        if (mSettingsButton != null) {
-            mSettingsButton.setEnabled(isDeviceProvisioned());
-        }
+        mHeaderFlipper.provisionCheck(provisioned);
+        mKeyguardFlipper.provisionCheck(provisioned);
     }
 
     @Override
@@ -1647,6 +1698,9 @@
 
             mStatusBarWindow.cancelExpandHelper();
             mStatusBarView.collapseAllPanels(true);
+            if (isFlippedToSettings()) {
+                flipToNotifications();
+            }
         }
     }
 
@@ -1694,8 +1748,7 @@
     final int FLIP_DURATION_IN = 225;
     final int FLIP_DURATION = (FLIP_DURATION_IN + FLIP_DURATION_OUT);
 
-    Animator mScrollViewAnim, mFlipSettingsViewAnim, mNotificationButtonAnim,
-        mSettingsButtonAnim, mClearButtonAnim;
+    Animator mScrollViewAnim, mFlipSettingsViewAnim, mClearButtonAnim;
 
     @Override
     public void animateExpandNotificationsPanel() {
@@ -1715,33 +1768,29 @@
     public void flipToNotifications() {
         if (mFlipSettingsViewAnim != null) mFlipSettingsViewAnim.cancel();
         if (mScrollViewAnim != null) mScrollViewAnim.cancel();
-        if (mSettingsButtonAnim != null) mSettingsButtonAnim.cancel();
-        if (mNotificationButtonAnim != null) mNotificationButtonAnim.cancel();
+        mHeaderFlipper.cancel();
+        mKeyguardFlipper.cancel();
         if (mClearButtonAnim != null) mClearButtonAnim.cancel();
 
         mStackScroller.setVisibility(View.VISIBLE);
+        final int h = mNotificationPanel.getMeasuredHeight();
+        final float settingsY = mSettingsTracker != null ? mFlipSettingsView.getTranslationY() : 0;
+        final float scrollerY = mSettingsTracker != null ? mStackScroller.getTranslationY() : h;
         mScrollViewAnim = start(
-            startDelay(FLIP_DURATION_OUT,
+            startDelay(0,
                 interpolator(mDecelerateInterpolator,
-                    ObjectAnimator.ofFloat(mStackScroller, View.SCALE_X, 0f, 1f)
-                        .setDuration(FLIP_DURATION_IN)
+                    ObjectAnimator.ofFloat(mStackScroller, View.TRANSLATION_Y, scrollerY, 0)
+                        .setDuration(FLIP_DURATION)
                     )));
         mFlipSettingsViewAnim = start(
             setVisibilityWhenDone(
-                interpolator(mAccelerateInterpolator,
-                        ObjectAnimator.ofFloat(mFlipSettingsView, View.SCALE_X, 1f, 0f)
+                interpolator(mDecelerateInterpolator,
+                        ObjectAnimator.ofFloat(mFlipSettingsView, View.TRANSLATION_Y, settingsY, -h)
                         )
-                    .setDuration(FLIP_DURATION_OUT),
-                mFlipSettingsView, View.INVISIBLE));
-        mNotificationButtonAnim = start(
-            setVisibilityWhenDone(
-                ObjectAnimator.ofFloat(mNotificationButton, View.ALPHA, 0f)
                     .setDuration(FLIP_DURATION),
-                mNotificationButton, View.INVISIBLE));
-        mSettingsButton.setVisibility(View.VISIBLE);
-        mSettingsButtonAnim = start(
-            ObjectAnimator.ofFloat(mSettingsButton, View.ALPHA, 1f)
-                .setDuration(FLIP_DURATION));
+                mFlipSettingsView, View.INVISIBLE));
+        mHeaderFlipper.flipToNotifications();
+        mKeyguardFlipper.flipToNotifications();
         mClearButton.setVisibility(View.VISIBLE);
         mClearButton.setAlpha(0f);
         setAreThereNotifications(); // this will show/hide the button as necessary
@@ -1767,7 +1816,8 @@
 
         if (mHasFlipSettings) {
             mNotificationPanel.expand();
-            if (mFlipSettingsView.getVisibility() != View.VISIBLE) {
+            if (mFlipSettingsView.getVisibility() != View.VISIBLE
+                    || mFlipSettingsView.getTranslationY() < 0) {
                 flipToSettings();
             }
         } else if (mSettingsPanel != null) {
@@ -1777,23 +1827,6 @@
         if (false) postStartTracing();
     }
 
-    public void switchToSettings() {
-        // Settings are not available in setup
-        if (!mUserSetup) return;
-
-        mFlipSettingsView.setScaleX(1f);
-        mFlipSettingsView.setVisibility(View.VISIBLE);
-        mSettingsButton.setVisibility(View.GONE);
-        mStackScroller.setVisibility(View.GONE);
-        mStackScroller.setScaleX(0f);
-        mNotificationButton.setVisibility(View.VISIBLE);
-        mNotificationButton.setAlpha(1f);
-        mClearButton.setVisibility(View.GONE);
-        if (mOnFlipRunnable != null) {
-            mOnFlipRunnable.run();
-        }
-    }
-
     public boolean isFlippedToSettings() {
         if (mFlipSettingsView != null) {
             return mFlipSettingsView.getVisibility() == View.VISIBLE;
@@ -1807,34 +1840,29 @@
 
         if (mFlipSettingsViewAnim != null) mFlipSettingsViewAnim.cancel();
         if (mScrollViewAnim != null) mScrollViewAnim.cancel();
-        if (mSettingsButtonAnim != null) mSettingsButtonAnim.cancel();
-        if (mNotificationButtonAnim != null) mNotificationButtonAnim.cancel();
+        mHeaderFlipper.cancel();
+        mKeyguardFlipper.cancel();
         if (mClearButtonAnim != null) mClearButtonAnim.cancel();
 
         mFlipSettingsView.setVisibility(View.VISIBLE);
-        mFlipSettingsView.setScaleX(0f);
+        final int h = mNotificationPanel.getMeasuredHeight();
+        final float settingsY = mSettingsTracker != null ? mFlipSettingsView.getTranslationY() : -h;
+        final float scrollerY = mSettingsTracker != null ? mStackScroller.getTranslationY() : 0;
         mFlipSettingsViewAnim = start(
-            startDelay(FLIP_DURATION_OUT,
-                interpolator(mDecelerateInterpolator,
-                    ObjectAnimator.ofFloat(mFlipSettingsView, View.SCALE_X, 0f, 1f)
-                        .setDuration(FLIP_DURATION_IN)
-                    )));
+                startDelay(0,
+                    interpolator(mDecelerateInterpolator,
+                        ObjectAnimator.ofFloat(mFlipSettingsView, View.TRANSLATION_Y, settingsY, 0f)
+                            .setDuration(FLIP_DURATION)
+                        )));
         mScrollViewAnim = start(
             setVisibilityWhenDone(
-                interpolator(mAccelerateInterpolator,
-                        ObjectAnimator.ofFloat(mStackScroller, View.SCALE_X, 1f, 0f)
+                interpolator(mDecelerateInterpolator,
+                        ObjectAnimator.ofFloat(mStackScroller, View.TRANSLATION_Y, scrollerY, h)
                         )
-                    .setDuration(FLIP_DURATION_OUT),
-                    mStackScroller, View.INVISIBLE));
-        mSettingsButtonAnim = start(
-            setVisibilityWhenDone(
-                ObjectAnimator.ofFloat(mSettingsButton, View.ALPHA, 0f)
                     .setDuration(FLIP_DURATION),
                     mStackScroller, View.INVISIBLE));
-        mNotificationButton.setVisibility(View.VISIBLE);
-        mNotificationButtonAnim = start(
-            ObjectAnimator.ofFloat(mNotificationButton, View.ALPHA, 1f)
-                .setDuration(FLIP_DURATION));
+        mHeaderFlipper.flipToSettings();
+        mKeyguardFlipper.flipToSettings();
         mClearButtonAnim = start(
             setVisibilityWhenDone(
                 ObjectAnimator.ofFloat(mClearButton, View.ALPHA, 0f)
@@ -1883,18 +1911,16 @@
             // reset things to their proper state
             if (mFlipSettingsViewAnim != null) mFlipSettingsViewAnim.cancel();
             if (mScrollViewAnim != null) mScrollViewAnim.cancel();
-            if (mSettingsButtonAnim != null) mSettingsButtonAnim.cancel();
-            if (mNotificationButtonAnim != null) mNotificationButtonAnim.cancel();
             if (mClearButtonAnim != null) mClearButtonAnim.cancel();
 
-            mStackScroller.setScaleX(1f);
             mStackScroller.setVisibility(View.VISIBLE);
-            mSettingsButton.setAlpha(1f);
-            mSettingsButton.setVisibility(View.VISIBLE);
             mNotificationPanel.setVisibility(View.GONE);
             mFlipSettingsView.setVisibility(View.GONE);
-            mNotificationButton.setVisibility(View.GONE);
+
             setAreThereNotifications(); // show the clear button
+
+            mHeaderFlipper.reset();
+            mKeyguardFlipper.reset();
         }
 
         mExpandedVisible = false;
@@ -2945,28 +2971,23 @@
         if (isFlippedToSettings()) {
             flipToNotifications();
         }
-        mStatusBarWindow.setSystemUiVisibility(View.STATUS_BAR_DISABLE_HOME);
         mKeyguardStatusView.setVisibility(View.VISIBLE);
         mNotificationPanelHeader.setVisibility(View.GONE);
-        if (mKeyguardSettingsFlipButton == null) {
-            ViewStub flipStub = (ViewStub) mStatusBarWindow.findViewById(R.id.keyguard_flip_stub);
-            mKeyguardSettingsFlipButton = flipStub.inflate();
-            installSettingsButton(mKeyguardSettingsFlipButton);
-        }
-        mKeyguardSettingsFlipButton.setVisibility(View.VISIBLE);
-        mKeyguardSettingsFlipButton.findViewById(R.id.settings_button).setVisibility(View.VISIBLE);
-        mKeyguardSettingsFlipButton.findViewById(R.id.notification_button)
-                .setVisibility(View.INVISIBLE);
+
+        mKeyguardFlipper.setVisibility(View.VISIBLE);
+        mSettingsContainer.setKeyguardShowing(true);
         updateRowStates();
     }
 
     public void hideKeyguard() {
         mOnKeyguard = false;
-        mStatusBarWindow.setSystemUiVisibility(0);
         mKeyguardStatusView.setVisibility(View.GONE);
         mNotificationPanelHeader.setVisibility(View.VISIBLE);
-        mKeyguardSettingsFlipButton.setVisibility(View.GONE);
+
+        mKeyguardFlipper.setVisibility(View.GONE);
+        mSettingsContainer.setKeyguardShowing(false);
         updateRowStates();
+        instantCollapseNotificationPanel();
     }
 
     public void userActivity() {
@@ -2975,6 +2996,10 @@
         }
     }
 
+    public boolean onMenuPressed() {
+        return mOnKeyguard && mStatusBarKeyguardViewManager.onMenuPressed();
+    }
+
     public boolean onBackPressed() {
         if (mOnKeyguard) {
             return mStatusBarKeyguardViewManager.onBackPressed();
@@ -2995,6 +3020,10 @@
         mNotificationPanel.setExpandedFraction(1);
     }
 
+    private void instantCollapseNotificationPanel() {
+        mNotificationPanel.setExpandedFraction(0);
+    }
+
     @Override
     public void onActivated(View view) {
         userActivity();
@@ -3021,39 +3050,112 @@
         }
     }
 
-    private void installSettingsButton(View parent) {
-        final ImageView settingsButton =
-                (ImageView) mStatusBarWindow.findViewById(R.id.settings_button);
-        final ImageView notificationButton =
-                (ImageView) mStatusBarWindow.findViewById(R.id.notification_button);
-        if (settingsButton != null) {
-            settingsButton.setOnClickListener(new View.OnClickListener() {
-                @Override
-                public void onClick(View v) {
-                    animateExpandSettingsPanel();
-                    v.setVisibility(View.INVISIBLE);
-                    notificationButton.setVisibility(View.VISIBLE);
+    public static boolean inBounds(View view, MotionEvent event, boolean orAbove) {
+        final int[] location = new int[2];
+        view.getLocationInWindow(location);
+        final int rx = (int) event.getRawX();
+        final int ry = (int) event.getRawY();
+        return rx >= location[0] && rx <= location[0] + view.getMeasuredWidth()
+                && (orAbove || ry >= location[1]) && ry <= location[1] + view.getMeasuredHeight();
+    }
+
+    private final class FlipperButton {
+        private final View mHolder;
+
+        private ImageView mSettingsButton, mNotificationButton;
+        private Animator mSettingsButtonAnim, mNotificationButtonAnim;
+
+        public FlipperButton(View holder) {
+            mHolder = holder;
+            mSettingsButton = (ImageView) holder.findViewById(R.id.settings_button);
+            if (mSettingsButton != null) {
+                mSettingsButton.setOnClickListener(mSettingsButtonListener);
+                if (mHasSettingsPanel) {
+                    // the settings panel is hiding behind this button
+                    mSettingsButton.setImageResource(R.drawable.ic_notify_quicksettings);
+                    mSettingsButton.setVisibility(View.VISIBLE);
+                } else {
+                    // no settings panel, go straight to settings
+                    mSettingsButton.setVisibility(View.VISIBLE);
+                    mSettingsButton.setImageResource(R.drawable.ic_notify_settings);
                 }
-            });
-            settingsButton.setVisibility(View.VISIBLE);
-            if (mHasSettingsPanel) {
-                // the settings panel is hiding behind this button
-                settingsButton.setImageResource(R.drawable.ic_notify_quicksettings);
-            } else {
-                // no settings panel, go straight to settings
-                settingsButton.setImageResource(R.drawable.ic_notify_settings);
+            }
+            if (mHasFlipSettings) {
+                mNotificationButton = (ImageView) holder.findViewById(R.id.notification_button);
+                if (mNotificationButton != null) {
+                    mNotificationButton.setOnClickListener(mNotificationButtonListener);
+                }
             }
         }
-        if (notificationButton != null) {
-            notificationButton.setVisibility(View.INVISIBLE);
-            notificationButton.setOnClickListener(new View.OnClickListener() {
-                @Override
-                public void onClick(View v) {
-                    flipToNotifications();
-                    v.setVisibility(View.INVISIBLE);
-                    settingsButton.setVisibility(View.VISIBLE);
-                }
-            });
+
+        public boolean inHolderBounds(MotionEvent event) {
+            return inBounds(mHolder, event, false);
+        }
+
+        public void provisionCheck(boolean provisioned) {
+            if (mSettingsButton != null) {
+                mSettingsButton.setEnabled(provisioned);
+            }
+        }
+
+        public void userSetup(boolean userSetup) {
+            if (mSettingsButton != null && mHasFlipSettings) {
+                mSettingsButton.setVisibility(userSetup ? View.VISIBLE : View.INVISIBLE);
+            }
+        }
+
+        public void reset() {
+            cancel();
+            mSettingsButton.setVisibility(View.VISIBLE);
+            mNotificationButton.setVisibility(View.GONE);
+        }
+
+        public void refreshLayout() {
+            if (mSettingsButton != null) {
+                // Force asset reloading
+                mSettingsButton.setImageDrawable(null);
+                mSettingsButton.setImageResource(R.drawable.ic_notify_quicksettings);
+            }
+
+            if (mNotificationButton != null) {
+                // Force asset reloading
+                mNotificationButton.setImageDrawable(null);
+                mNotificationButton.setImageResource(R.drawable.ic_notifications);
+            }
+        }
+
+        public void flipToSettings() {
+            mSettingsButtonAnim = start(
+                setVisibilityWhenDone(
+                    ObjectAnimator.ofFloat(mSettingsButton, View.ALPHA, 0f)
+                        .setDuration(FLIP_DURATION),
+                    mStackScroller, View.INVISIBLE));
+            mNotificationButton.setVisibility(View.VISIBLE);
+            mNotificationButtonAnim = start(
+                ObjectAnimator.ofFloat(mNotificationButton, View.ALPHA, 1f)
+                    .setDuration(FLIP_DURATION));
+        }
+
+        public void flipToNotifications() {
+            mNotificationButtonAnim = start(
+                setVisibilityWhenDone(
+                    ObjectAnimator.ofFloat(mNotificationButton, View.ALPHA, 0f)
+                        .setDuration(FLIP_DURATION),
+                    mNotificationButton, View.INVISIBLE));
+
+            mSettingsButton.setVisibility(View.VISIBLE);
+            mSettingsButtonAnim = start(
+                ObjectAnimator.ofFloat(mSettingsButton, View.ALPHA, 1f)
+                    .setDuration(FLIP_DURATION));
+        }
+
+        public void cancel() {
+            if (mSettingsButtonAnim != null) mSettingsButtonAnim.cancel();
+            if (mNotificationButtonAnim != null) mNotificationButtonAnim.cancel();
+        }
+
+        public void setVisibility(int vis) {
+            mHolder.setVisibility(vis);
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsContainerView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsContainerView.java
index 17ee017..02e9c0d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsContainerView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsContainerView.java
@@ -19,7 +19,13 @@
 import android.animation.LayoutTransition;
 import android.content.Context;
 import android.content.res.Resources;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.Rect;
+import android.graphics.Typeface;
 import android.util.AttributeSet;
+import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.FrameLayout;
@@ -31,30 +37,58 @@
  */
 class QuickSettingsContainerView extends FrameLayout {
 
+    private static boolean sShowScrim = true;
+
+    private final Context mContext;
+
     // The number of columns in the QuickSettings grid
     private int mNumColumns;
 
+    private boolean mKeyguardShowing;
+    private int mMaxRows;
+    private int mMaxRowsOnKeyguard;
+
     // The gap between tiles in the QuickSettings grid
     private float mCellGap;
 
+    private ScrimView mScrim;
+
     public QuickSettingsContainerView(Context context, AttributeSet attrs) {
         super(context, attrs);
-
+        mContext = context;
         updateResources();
     }
 
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
-
+        mScrim = new ScrimView(mContext);
+        addView(mScrim);
+        mScrim.setAlpha(sShowScrim ? 1 : 0);
         // TODO: Setup the layout transitions
         LayoutTransition transitions = getLayoutTransition();
     }
 
+    @Override
+    public boolean onTouchEvent(MotionEvent event) {
+        if (mScrim.getAlpha() == 1) {
+            mScrim.animate().alpha(0).setDuration(1000).start();
+            sShowScrim = false;
+        }
+        return super.onTouchEvent(event);
+    }
+
     void updateResources() {
         Resources r = getContext().getResources();
         mCellGap = r.getDimension(R.dimen.quick_settings_cell_gap);
         mNumColumns = r.getInteger(R.integer.quick_settings_num_columns);
+        mMaxRows = r.getInteger(R.integer.quick_settings_max_rows);
+        mMaxRowsOnKeyguard = r.getInteger(R.integer.quick_settings_max_rows_keyguard);
+        requestLayout();
+    }
+
+    void setKeyguardShowing(boolean showing) {
+        mKeyguardShowing = showing;
         requestLayout();
     }
 
@@ -71,10 +105,18 @@
         final int N = getChildCount();
         int cellHeight = 0;
         int cursor = 0;
+        int maxRows = mKeyguardShowing ? mMaxRowsOnKeyguard : mMaxRows;
+
         for (int i = 0; i < N; ++i) {
+            if (getChildAt(i).equals(mScrim)) {
+                continue;
+            }
             // Update the child's width
             QuickSettingsTileView v = (QuickSettingsTileView) getChildAt(i);
             if (v.getVisibility() != View.GONE) {
+                int row = (int) (cursor / mNumColumns);
+                if (row >= maxRows) continue;
+
                 ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) v.getLayoutParams();
                 int colSpan = v.getColumnSpan();
                 lp.width = (int) ((colSpan * cellWidth) + (colSpan - 1) * mCellGap);
@@ -102,6 +144,7 @@
 
     @Override
     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+        mScrim.bringToFront();
         final int N = getChildCount();
         final boolean isLayoutRtl = isLayoutRtl();
         final int width = getWidth();
@@ -109,8 +152,18 @@
         int x = getPaddingStart();
         int y = getPaddingTop();
         int cursor = 0;
+        int maxRows = mKeyguardShowing ? mMaxRowsOnKeyguard : mMaxRows;
 
         for (int i = 0; i < N; ++i) {
+            if (getChildAt(i).equals(mScrim)) {
+                int w = right - left - getPaddingLeft() - getPaddingRight();
+                int h = bottom - top - getPaddingTop() - getPaddingBottom();
+                mScrim.measure(
+                        MeasureSpec.makeMeasureSpec(w, MeasureSpec.EXACTLY),
+                        MeasureSpec.makeMeasureSpec(h, MeasureSpec.EXACTLY));
+                mScrim.layout(getPaddingLeft(), getPaddingTop(), right, bottom);
+                continue;
+            }
             QuickSettingsTileView child = (QuickSettingsTileView) getChildAt(i);
             ViewGroup.LayoutParams lp = child.getLayoutParams();
             if (child.getVisibility() != GONE) {
@@ -121,6 +174,7 @@
                 final int childHeight = lp.height;
 
                 int row = (int) (cursor / mNumColumns);
+                if (row >= maxRows) continue;
 
                 // Push the item to the next row if it can't fit on this one
                 if ((col + colSpan) > mNumColumns) {
@@ -150,4 +204,87 @@
             }
         }
     }
+
+    private static final class ScrimView extends View {
+        private static final int COLOR = 0xaf4285f4;
+
+        private final Paint mLinePaint;
+        private final int mStrokeWidth;
+        private final Rect mTmp = new Rect();
+        private final Paint mTextPaint;
+        private final int mTextSize;
+
+        public ScrimView(Context context) {
+            super(context);
+            setFocusable(false);
+            final Resources res = context.getResources();
+            mStrokeWidth = res.getDimensionPixelSize(R.dimen.quick_settings_tmp_scrim_stroke_width);
+            mTextSize = res.getDimensionPixelSize(R.dimen.quick_settings_tmp_scrim_text_size);
+
+            mLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+            mLinePaint.setColor(COLOR);
+            mLinePaint.setStrokeWidth(mStrokeWidth);
+            mLinePaint.setStrokeJoin(Paint.Join.ROUND);
+            mLinePaint.setStrokeCap(Paint.Cap.ROUND);
+            mLinePaint.setStyle(Paint.Style.STROKE);
+
+            mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+            mTextPaint.setColor(COLOR);
+            mTextPaint.setTextSize(mTextSize);
+            mTextPaint.setTypeface(Typeface.create("sans-serif-condensed", Typeface.BOLD));
+        }
+
+        @Override
+        protected void onDraw(Canvas canvas) {
+            final int w = getMeasuredWidth();
+            final int h = getMeasuredHeight();
+            final int f = mStrokeWidth * 3 / 4;
+
+            canvas.drawPath(line(f, h / 2, w - f, h / 2), mLinePaint);
+            canvas.drawPath(line(w / 2, f, w / 2, h - f), mLinePaint);
+
+            final int s = mStrokeWidth;
+            mTextPaint.setTextAlign(Paint.Align.RIGHT);
+            canvas.drawText("FUTURE", w / 2 - s, h / 2 - s, mTextPaint);
+            mTextPaint.setTextAlign(Paint.Align.LEFT);
+            canvas.drawText("SITE OF", w / 2 + s, h / 2 - s , mTextPaint);
+            mTextPaint.setTextAlign(Paint.Align.RIGHT);
+            drawUnder(canvas, "QUANTUM", w / 2 - s, h / 2 + s);
+            mTextPaint.setTextAlign(Paint.Align.LEFT);
+            drawUnder(canvas, "SETTINGS", w / 2 + s, h / 2 + s);
+        }
+
+        private void drawUnder(Canvas c, String text, float x, float y) {
+            if (mTmp.isEmpty()) {
+                mTextPaint.getTextBounds(text, 0, text.length(), mTmp);
+            }
+            c.drawText(text, x, y + mTmp.height() * .85f, mTextPaint);
+        }
+
+        private Path line(float x1, float y1, float x2, float y2) {
+            final int a = mStrokeWidth * 2;
+            final Path p = new Path();
+            p.moveTo(x1, y1);
+            p.lineTo(x2, y2);
+            if (y1 == y2) {
+                p.moveTo(x1 + a, y1 + a);
+                p.lineTo(x1, y1);
+                p.lineTo(x1 + a, y1 - a);
+
+                p.moveTo(x2 - a, y2 - a);
+                p.lineTo(x2, y2);
+                p.lineTo(x2 - a, y2 + a);
+            }
+            if (x1 == x2) {
+                p.moveTo(x1 - a, y1 + a);
+                p.lineTo(x1, y1);
+                p.lineTo(x1 + a, y1 + a);
+
+                p.moveTo(x2 - a, y2 - a);
+                p.lineTo(x2, y2);
+                p.lineTo(x2 + a, y2 - a);
+            }
+            return p;
+        }
+    }
 }
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index b8592c3..460f122 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -56,6 +56,7 @@
     private boolean mScreenOn = false;
     private KeyguardBouncer mBouncer;
     private boolean mShowing;
+    private boolean mOccluded = false;
 
     public StatusBarKeyguardViewManager(Context context, ViewMediatorCallback callback,
             LockPatternUtils lockPatternUtils) {
@@ -80,22 +81,39 @@
     public void show(Bundle options) {
         mShowing = true;
         mStatusBarWindowManager.setKeyguardShowing(true);
-        mPhoneStatusBar.showKeyguard();
-        mBouncer.prepare();
+        showBouncerOrKeyguard();
         updateBackButtonState();
     }
 
+    /**
+     * Shows the notification keyguard or the bouncer depending on
+     * {@link KeyguardBouncer#needsFullscreenBouncer()}.
+     */
+    private void showBouncerOrKeyguard() {
+        if (mBouncer.needsFullscreenBouncer()) {
+
+            // The keyguard might be showing (already). So we need to hide it.
+            mPhoneStatusBar.hideKeyguard();
+            mBouncer.show();
+        } else {
+            mPhoneStatusBar.showKeyguard();
+            mBouncer.hide();
+            mBouncer.prepare();
+        }
+    }
+
     public void showBouncer() {
-        mBouncer.show();
-        updateBackButtonState();
+        if (!mOccluded) {
+            mBouncer.show();
+            updateBackButtonState();
+        }
     }
 
     /**
      * Reset the state of the view.
      */
     public void reset() {
-        mBouncer.reset();
-        mPhoneStatusBar.showKeyguard();
+        showBouncerOrKeyguard();
         updateBackButtonState();
     }
 
@@ -106,7 +124,6 @@
 
     public void onScreenTurnedOn(final IKeyguardShowCallback callback) {
         mScreenOn = true;
-        mBouncer.onScreenTurnedOn();
         if (callback != null) {
             callbackAfterDraw(callback);
         }
@@ -138,6 +155,13 @@
     }
 
     public void setOccluded(boolean occluded) {
+        mOccluded = occluded;
+        if (occluded) {
+            mPhoneStatusBar.hideKeyguard();
+            mBouncer.hide();
+        } else {
+            showBouncerOrKeyguard();
+        }
         mStatusBarWindowManager.setKeyguardOccluded(occluded);
     }
 
@@ -185,10 +209,15 @@
 
     private void updateBackButtonState() {
         int vis = mContainer.getSystemUiVisibility();
-        if (mBouncer.isShowing()) {
+        boolean bouncerDismissable = mBouncer.isShowing() && !mBouncer.needsFullscreenBouncer();
+        if (bouncerDismissable || !mShowing) {
             mContainer.setSystemUiVisibility(vis & ~View.STATUS_BAR_DISABLE_BACK);
         } else {
             mContainer.setSystemUiVisibility(vis | View.STATUS_BAR_DISABLE_BACK);
         }
     }
+
+    public boolean onMenuPressed() {
+        return mBouncer.onMenuPressed();
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
index 6153cde..716e326 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
@@ -128,6 +128,10 @@
         }
     }
 
+    private void applyFitsSystemWindows(State state) {
+        mStatusBarView.setFitsSystemWindows(!state.isKeyguardShowingAndNotOccluded());
+    }
+
     private void applyUserActivityTimeout(State state) {
         if (state.isKeyguardShowingAndNotOccluded()) {
             mLp.userActivityTimeout = state.keyguardUserActivityTimeout;
@@ -151,6 +155,7 @@
         applyHeight(state);
         applyUserActivityTimeout(state);
         applyInputFeatures(state);
+        applyFitsSystemWindows(state);
         mWindowManager.updateViewLayout(mStatusBarView, mLp);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
index dd89f47..1d675bd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
@@ -77,11 +77,15 @@
     public boolean dispatchKeyEvent(KeyEvent event) {
         boolean down = event.getAction() == KeyEvent.ACTION_DOWN;
         switch (event.getKeyCode()) {
-        case KeyEvent.KEYCODE_BACK:
-            if (!down) {
-                mService.onBackPressed();
-            }
-            return true;
+            case KeyEvent.KEYCODE_BACK:
+                if (!down) {
+                    mService.onBackPressed();
+                }
+                return true;
+            case KeyEvent.KEYCODE_MENU:
+                if (!down) {
+                    return mService.onMenuPressed();
+                }
         }
         return super.dispatchKeyEvent(event);
     }
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 77f5182..037a744 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -32,6 +32,7 @@
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.telephony.CellLocation;
+import android.telephony.DataConnectionRealTimeInfo;
 import android.telephony.PhoneStateListener;
 import android.telephony.ServiceState;
 import android.telephony.SignalStrength;
@@ -129,6 +130,8 @@
 
     private List<CellInfo> mCellInfo = null;
 
+    private DataConnectionRealTimeInfo mDcRtInfo = new DataConnectionRealTimeInfo();
+
     private int mRingingCallState = PreciseCallState.PRECISE_CALL_STATE_IDLE;
 
     private int mForegroundCallState = PreciseCallState.PRECISE_CALL_STATE_IDLE;
@@ -324,6 +327,13 @@
                             remove(r.binder);
                         }
                     }
+                    if ((events & PhoneStateListener.LISTEN_DATA_CONNECTION_REAL_TIME_INFO) != 0) {
+                        try {
+                            r.callback.onDataConnectionRealTimeInfoChanged(mDcRtInfo);
+                        } catch (RemoteException ex) {
+                            remove(r.binder);
+                        }
+                    }
                     if ((events & PhoneStateListener.LISTEN_PRECISE_CALL_STATE) != 0) {
                         try {
                             r.callback.onPreciseCallStateChanged(mPreciseCallState);
@@ -451,6 +461,31 @@
         }
     }
 
+    public void notifyDataConnectionRealTimeInfo(DataConnectionRealTimeInfo dcRtInfo) {
+        if (!checkNotifyPermission("notifyDataConnectionRealTimeInfo()")) {
+            return;
+        }
+
+        synchronized (mRecords) {
+            mDcRtInfo = dcRtInfo;
+            for (Record r : mRecords) {
+                if (validateEventsAndUserLocked(r,
+                        PhoneStateListener.LISTEN_DATA_CONNECTION_REAL_TIME_INFO)) {
+                    try {
+                        if (DBG_LOC) {
+                            Slog.d(TAG, "notifyDataConnectionRealTimeInfo: mDcRtInfo="
+                                    + mDcRtInfo + " r=" + r);
+                        }
+                        r.callback.onDataConnectionRealTimeInfoChanged(mDcRtInfo);
+                    } catch (RemoteException ex) {
+                        mRemoveList.add(r.binder);
+                    }
+                }
+            }
+            handleRemoveListLocked();
+        }
+    }
+
     public void notifyMessageWaitingChanged(boolean mwi) {
         if (!checkNotifyPermission("notifyMessageWaitingChanged()")) {
             return;
@@ -754,6 +789,7 @@
             pw.println("  mDataConnectionLinkCapabilities=" + mDataConnectionLinkCapabilities);
             pw.println("  mCellLocation=" + mCellLocation);
             pw.println("  mCellInfo=" + mCellInfo);
+            pw.println("  mDcRtInfo=" + mDcRtInfo);
             pw.println("registrations: count=" + recordCount);
             for (Record r : mRecords) {
                 pw.println("  " + r.pkgForDebug + " 0x" + Integer.toHexString(r.events));
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index b894724..8dd4317 100755
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -1063,6 +1063,16 @@
         return mStackSupervisor.isFrontStack(this);
     }
 
+    private void setVisibile(ActivityRecord r, boolean visible) {
+        r.visible = visible;
+        mWindowManager.setAppVisibility(r.appToken, visible);
+        final ArrayList<ActivityStack> containers = r.mChildContainers;
+        for (int containerNdx = containers.size() - 1; containerNdx >= 0; --containerNdx) {
+            ActivityContainer container = containers.get(containerNdx).mActivityContainer;
+            container.setVisible(visible);
+        }
+    }
+
     /**
      * Version of ensureActivitiesVisible that can easily be called anywhere.
      */
@@ -1141,8 +1151,7 @@
                             if (!r.visible) {
                                 if (DEBUG_VISBILITY) Slog.v(
                                         TAG, "Starting and making visible: " + r);
-                                r.visible = true;
-                                mWindowManager.setAppVisibility(r.appToken, true);
+                                setVisibile(r, true);
                             }
                             if (r != starting) {
                                 mStackSupervisor.startSpecificActivityLocked(r, false, false);
@@ -1168,7 +1177,7 @@
                                 if (mTranslucentActivityWaiting != null) {
                                     mUndrawnActivitiesBelowTopTranslucent.add(r);
                                 }
-                                mWindowManager.setAppVisibility(r.appToken, true);
+                                setVisibile(r, true);
                                 r.sleeping = false;
                                 r.app.pendingUiClean = true;
                                 r.app.thread.scheduleWindowVisibility(r.appToken, true);
@@ -1204,9 +1213,8 @@
                     // sure they no longer are keeping the screen frozen.
                     if (r.visible) {
                         if (DEBUG_VISBILITY) Slog.v(TAG, "Making invisible: " + r);
-                        r.visible = false;
                         try {
-                            mWindowManager.setAppVisibility(r.appToken, false);
+                            setVisibile(r, false);
                             switch (r.state) {
                                 case STOPPING:
                                 case STOPPED:
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 47b4d0a..63f9d09 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -127,6 +127,7 @@
     static final int HANDLE_DISPLAY_ADDED = FIRST_SUPERVISOR_STACK_MSG + 5;
     static final int HANDLE_DISPLAY_CHANGED = FIRST_SUPERVISOR_STACK_MSG + 6;
     static final int HANDLE_DISPLAY_REMOVED = FIRST_SUPERVISOR_STACK_MSG + 7;
+    static final int CONTAINER_CALLBACK_VISIBILITY = FIRST_SUPERVISOR_STACK_MSG + 8;
 
     private final static String VIRTUAL_DISPLAY_BASE_NAME = "ActivityViewVirtualDisplay";
 
@@ -3015,6 +3016,14 @@
                 case HANDLE_DISPLAY_REMOVED: {
                     handleDisplayRemovedLocked(msg.arg1);
                 } break;
+                case CONTAINER_CALLBACK_VISIBILITY: {
+                    final ActivityContainer container = (ActivityContainer) msg.obj;
+                    try {
+                        // We only send this message if mCallback is non-null.
+                        container.mCallback.setVisible(container.asBinder(), msg.arg1 == 1);
+                    } catch (RemoteException e) {
+                    }
+                }
             }
         }
     }
@@ -3026,6 +3035,8 @@
         final ActivityRecord mParentActivity;
         final String mIdString;
 
+        boolean mVisible = true;
+
         /** Display this ActivityStack is currently on. Null if not attached to a Display. */
         ActivityDisplay mActivityDisplay;
 
@@ -3173,6 +3184,16 @@
             }
         }
 
+        void setVisible(boolean visible) {
+            if (mVisible != visible) {
+                mVisible = visible;
+                if (mCallback != null) {
+                    mHandler.obtainMessage(CONTAINER_CALLBACK_VISIBILITY, visible ? 1 : 0,
+                            0 /* unused */, this).sendToTarget();
+                }
+            }
+        }
+
         @Override
         public String toString() {
             return mIdString + (mActivityDisplay == null ? "N" : "A");
diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java
index 16ed7fe..75e5857 100644
--- a/services/core/java/com/android/server/tv/TvInputManagerService.java
+++ b/services/core/java/com/android/server/tv/TvInputManagerService.java
@@ -197,8 +197,8 @@
         UserState userState = getUserStateLocked(userId);
         ServiceState serviceState = userState.serviceStateMap.get(name);
         if (serviceState == null) {
-            throw new IllegalStateException("Service state not found for " + name + " (userId=" +
-                    userId + ")");
+            throw new IllegalStateException("Service state not found for " + name + " (userId="
+                    + userId + ")");
         }
         return serviceState;
     }
@@ -233,8 +233,8 @@
         if (serviceState == null) {
             return;
         }
-        boolean isStateEmpty = serviceState.clients.size() == 0
-                && serviceState.sessionStateMap.size() == 0;
+        boolean isStateEmpty = serviceState.clients.isEmpty()
+                && serviceState.sessionTokens.isEmpty();
         if (serviceState.service == null && !isStateEmpty && userId == mCurrentUserId) {
             // This means that the service is not yet connected but its state indicates that we
             // have pending requests. Then, connect the service.
@@ -263,7 +263,9 @@
     }
 
     private void createSessionInternalLocked(ITvInputService service, final IBinder sessionToken,
-            final SessionState sessionState, final int userId) {
+            final int userId) {
+        final SessionState sessionState =
+                getUserStateLocked(userId).sessionStateMap.get(sessionToken);
         if (DEBUG) {
             Log.d(TAG, "createSessionInternalLocked(name=" + sessionState.name.getClassName()
                     + ")");
@@ -319,10 +321,10 @@
         UserState userState = getUserStateLocked(userId);
         SessionState sessionState = userState.sessionStateMap.remove(sessionToken);
 
-        // Also remove the session state from the session state map of the current service.
+        // Also remove the session token from the session token list of the current service.
         ServiceState serviceState = userState.serviceStateMap.get(sessionState.name);
         if (serviceState != null) {
-            serviceState.sessionStateMap.remove(sessionToken);
+            serviceState.sessionTokens.remove(sessionToken);
         }
         updateServiceConnectionLocked(sessionState.name, userId);
     }
@@ -465,11 +467,11 @@
                         serviceState = new ServiceState(name, resolvedUserId);
                         userState.serviceStateMap.put(name, serviceState);
                     }
-                    serviceState.sessionStateMap.put(sessionToken, sessionState);
+                    serviceState.sessionTokens.add(sessionToken);
 
                     if (serviceState.service != null) {
                         createSessionInternalLocked(serviceState.service, sessionToken,
-                                sessionState, resolvedUserId);
+                                resolvedUserId);
                     } else {
                         updateServiceConnectionLocked(name, resolvedUserId);
                     }
@@ -580,8 +582,7 @@
 
     private final class ServiceState {
         private final List<IBinder> clients = new ArrayList<IBinder>();
-        private final ArrayMap<IBinder, SessionState> sessionStateMap = new ArrayMap<IBinder,
-                SessionState>();
+        private final List<IBinder> sessionTokens = new ArrayList<IBinder>();
         private final ServiceConnection connection;
 
         private ITvInputService service;
@@ -637,10 +638,8 @@
                 }
 
                 // And create sessions, if any.
-                for (Map.Entry<IBinder, SessionState> entry : serviceState.sessionStateMap
-                        .entrySet()) {
-                    createSessionInternalLocked(serviceState.service, entry.getKey(),
-                            entry.getValue(), mUserId);
+                for (IBinder sessionToken : serviceState.sessionTokens) {
+                    createSessionInternalLocked(serviceState.service, sessionToken, mUserId);
                 }
             }
         }
diff --git a/services/usb/java/com/android/server/usb/UsbDebuggingManager.java b/services/usb/java/com/android/server/usb/UsbDebuggingManager.java
index f73d425..0946c5a 100644
--- a/services/usb/java/com/android/server/usb/UsbDebuggingManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDebuggingManager.java
@@ -20,6 +20,8 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
 import android.content.res.Resources;
 import android.net.LocalSocket;
 import android.net.LocalSocketAddress;
@@ -210,7 +212,7 @@
                 case MESSAGE_ADB_CONFIRM: {
                     String key = (String)msg.obj;
                     mFingerprints = getFingerprints(key);
-                    showConfirmationDialog(key, mFingerprints);
+                    startConfirmation(key, mFingerprints);
                     break;
                 }
 
@@ -245,22 +247,60 @@
         return sb.toString();
     }
 
-    private void showConfirmationDialog(String key, String fingerprints) {
-        Intent intent = new Intent();
+    private void startConfirmation(String key, String fingerprints) {
+        String nameString = Resources.getSystem().getString(
+                com.android.internal.R.string.config_customAdbPublicKeyConfirmationComponent);
+        ComponentName componentName = ComponentName.unflattenFromString(nameString);
+        if (startConfirmationActivity(componentName, key, fingerprints)
+                || startConfirmationService(componentName, key, fingerprints)) {
+            return;
+        }
+        Slog.e(TAG, "unable to start customAdbPublicKeyConfirmationComponent "
+                + nameString + " as an Activity or a Service");
+    }
 
-        ComponentName componentName = ComponentName.unflattenFromString(
-                Resources.getSystem().getString(
-                        com.android.internal.R.string.config_customAdbPublicKeyActivity));
-        intent.setClassName(componentName.getPackageName(),
-                componentName.getClassName());
+    /**
+     * @returns true if the componentName led to an Activity that was started.
+     */
+    private boolean startConfirmationActivity(ComponentName componentName, String key,
+            String fingerprints) {
+        PackageManager packageManager = mContext.getPackageManager();
+        Intent intent = createConfirmationIntent(componentName, key, fingerprints);
         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        if (packageManager.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY) != null) {
+            try {
+                mContext.startActivity(intent);
+                return true;
+            } catch (ActivityNotFoundException e) {
+                Slog.e(TAG, "unable to start adb whitelist activity: " + componentName, e);
+            }
+        }
+        return false;
+    }
+
+    /**
+     * @returns true if the componentName led to a Service that was started.
+     */
+    private boolean startConfirmationService(ComponentName componentName, String key,
+            String fingerprints) {
+        Intent intent = createConfirmationIntent(componentName, key, fingerprints);
+        try {
+            if (mContext.startService(intent) != null) {
+                return true;
+            }
+        } catch (SecurityException e) {
+            Slog.e(TAG, "unable to start adb whitelist service: " + componentName, e);
+        }
+        return false;
+    }
+
+    private Intent createConfirmationIntent(ComponentName componentName, String key,
+            String fingerprints) {
+        Intent intent = new Intent();
+        intent.setClassName(componentName.getPackageName(), componentName.getClassName());
         intent.putExtra("key", key);
         intent.putExtra("fingerprints", fingerprints);
-        try {
-            mContext.startActivity(intent);
-        } catch (ActivityNotFoundException e) {
-            Slog.e(TAG, "unable to start UsbDebuggingActivity");
-        }
+        return intent;
     }
 
     private File getUserKeyFile() {
diff --git a/telephony/java/android/telephony/DataConnectionRealTimeInfo.aidl b/telephony/java/android/telephony/DataConnectionRealTimeInfo.aidl
new file mode 100644
index 0000000..70fbb11
--- /dev/null
+++ b/telephony/java/android/telephony/DataConnectionRealTimeInfo.aidl
@@ -0,0 +1,20 @@
+/*
+**
+** Copyright 2007, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package android.telephony;
+
+parcelable DataConnectionRealTimeInfo;
diff --git a/telephony/java/android/telephony/DataConnectionRealTimeInfo.java b/telephony/java/android/telephony/DataConnectionRealTimeInfo.java
new file mode 100644
index 0000000..4a9ae39
--- /dev/null
+++ b/telephony/java/android/telephony/DataConnectionRealTimeInfo.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Data connection real time information
+ *
+ * TODO: How to handle multiple subscriptions?
+ */
+public class DataConnectionRealTimeInfo implements Parcelable {
+    private long mTime;             // Time the info was collected since boot in nanos;
+
+    public static int DC_POWER_STATE_LOW       = 1;
+    public static int DC_POWER_STATE_MEDIUM    = 2;
+    public static int DC_POWER_STATE_HIGH      = 3;
+    public static int DC_POWER_STATE_UNKNOWN   = Integer.MAX_VALUE;
+
+    private int mDcPowerState;      // DC_POWER_STATE_[LOW | MEDIUM | HIGH | UNKNOWN]
+
+    /**
+     * Constructor
+     *
+     * @hide
+     */
+    public DataConnectionRealTimeInfo(long time, int dcPowerState) {
+        mTime = time;
+        mDcPowerState = dcPowerState;
+    }
+
+    /**
+     * Constructor
+     *
+     * @hide
+     */
+    public DataConnectionRealTimeInfo() {
+        mTime = Long.MAX_VALUE;
+        mDcPowerState = DC_POWER_STATE_UNKNOWN;
+    }
+
+    /**
+     * Construct a PreciseCallState object from the given parcel.
+     */
+    private DataConnectionRealTimeInfo(Parcel in) {
+        mTime = in.readLong();
+        mDcPowerState = in.readInt();
+    }
+
+    /**
+     * @return time the information was collected or Long.MAX_VALUE if unknown
+     */
+    public long getTime() {
+        return mTime;
+    }
+
+    /**
+     * @return DC_POWER_STATE_[LOW | MEDIUM | HIGH | UNKNOWN]
+     */
+    public int getDcPowerState() {
+        return mDcPowerState;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeLong(mTime);
+        out.writeInt(mDcPowerState);
+    }
+
+    public static final Parcelable.Creator<DataConnectionRealTimeInfo> CREATOR
+            = new Parcelable.Creator<DataConnectionRealTimeInfo>() {
+
+        @Override
+        public DataConnectionRealTimeInfo createFromParcel(Parcel in) {
+            return new DataConnectionRealTimeInfo(in);
+        }
+
+        @Override
+        public DataConnectionRealTimeInfo[] newArray(int size) {
+            return new DataConnectionRealTimeInfo[size];
+        }
+    };
+
+    @Override
+    public int hashCode() {
+        final long prime = 17;
+        long result = 1;
+        result = (prime * result) + mTime;
+        result += (prime * result) + mDcPowerState;
+        return (int)result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        DataConnectionRealTimeInfo other = (DataConnectionRealTimeInfo) obj;
+        return (mTime == other.mTime)
+                && (mDcPowerState == other.mDcPowerState);
+    }
+
+    @Override
+    public String toString() {
+        StringBuffer sb = new StringBuffer();
+
+        sb.append("mTime=").append(mTime);
+        sb.append(" mDcPowerState=").append(mDcPowerState);
+
+        return sb.toString();
+    }
+}
diff --git a/telephony/java/android/telephony/PhoneStateListener.java b/telephony/java/android/telephony/PhoneStateListener.java
index bb3f132..7c5c648 100644
--- a/telephony/java/android/telephony/PhoneStateListener.java
+++ b/telephony/java/android/telephony/PhoneStateListener.java
@@ -188,6 +188,17 @@
      */
     public static final int LISTEN_PRECISE_DATA_CONNECTION_STATE            = 0x00001000;
 
+    /**
+     * Listen for real time info for all data connections (cellular)).
+     * {@more}
+     * Requires Permission: {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE
+     * READ_PRECISE_PHONE_STATE}
+     *
+     * @see #onDataConnectionRealTimeInfoChanged(DataConnectionRealTimeInfo)
+     * @hide
+     */
+    public static final int LISTEN_DATA_CONNECTION_REAL_TIME_INFO           = 0x00002000;
+
     public PhoneStateListener() {
     }
 
@@ -335,6 +346,16 @@
     }
 
     /**
+     * Callback invoked when data connection state changes with precise information.
+     *
+     * @hide
+     */
+    public void onDataConnectionRealTimeInfoChanged(
+            DataConnectionRealTimeInfo dcRtInfo) {
+        // default implementation empty
+    }
+
+    /**
      * The callback methods need to be called on the handler thread where
      * this object was created.  If the binder did that for us it'd be nice.
      */
@@ -396,6 +417,12 @@
             Message.obtain(mHandler, LISTEN_PRECISE_DATA_CONNECTION_STATE, 0, 0,
                     dataConnectionState).sendToTarget();
         }
+
+        public void onDataConnectionRealTimeInfoChanged(
+                DataConnectionRealTimeInfo dcRtInfo) {
+            Message.obtain(mHandler, LISTEN_DATA_CONNECTION_REAL_TIME_INFO, 0, 0,
+                    dcRtInfo).sendToTarget();
+        }
     };
 
     Handler mHandler = new Handler() {
@@ -441,6 +468,11 @@
                     break;
                 case LISTEN_PRECISE_DATA_CONNECTION_STATE:
                     PhoneStateListener.this.onPreciseDataConnectionStateChanged((PreciseDataConnectionState)msg.obj);
+                    break;
+                case LISTEN_DATA_CONNECTION_REAL_TIME_INFO:
+                    PhoneStateListener.this.onDataConnectionRealTimeInfoChanged(
+                            (DataConnectionRealTimeInfo)msg.obj);
+                    break;
             }
         }
     };
diff --git a/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl b/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl
index f228d4e..3f36645 100644
--- a/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl
+++ b/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl
@@ -20,6 +20,7 @@
 import android.telephony.ServiceState;
 import android.telephony.SignalStrength;
 import android.telephony.CellInfo;
+import android.telephony.DataConnectionRealTimeInfo;
 import android.telephony.PreciseCallState;
 import android.telephony.PreciseDataConnectionState;
 
@@ -39,5 +40,6 @@
     void onCellInfoChanged(in List<CellInfo> cellInfo);
     void onPreciseCallStateChanged(in PreciseCallState callState);
     void onPreciseDataConnectionStateChanged(in PreciseDataConnectionState dataConnectionState);
+    void onDataConnectionRealTimeInfoChanged(in DataConnectionRealTimeInfo dcRtInfo);
 }
 
diff --git a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
index 546ce17..8ea9b0d 100644
--- a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
@@ -20,9 +20,10 @@
 import android.net.LinkProperties;
 import android.net.LinkCapabilities;
 import android.os.Bundle;
+import android.telephony.CellInfo;
+import android.telephony.DataConnectionRealTimeInfo;
 import android.telephony.ServiceState;
 import android.telephony.SignalStrength;
-import android.telephony.CellInfo;
 import com.android.internal.telephony.IPhoneStateListener;
 
 interface ITelephonyRegistry {
@@ -46,4 +47,5 @@
     void notifyDisconnectCause(int disconnectCause, int preciseDisconnectCause);
     void notifyPreciseDataConnectionFailed(String reason, String apnType, String apn,
             String failCause);
+    void notifyDataConnectionRealTimeInfo(in DataConnectionRealTimeInfo dcRtInfo);
 }