Merge "Read -Xjittransitionweight from system properties." into nyc-dev
diff --git a/api/current.txt b/api/current.txt
index f267789..4dfbe63 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -40380,9 +40380,7 @@
   }
 
   public final class LocaleList implements android.os.Parcelable {
-    ctor public LocaleList();
-    ctor public LocaleList(java.util.Locale);
-    ctor public LocaleList(java.util.Locale[]);
+    ctor public LocaleList(java.util.Locale...);
     method public int describeContents();
     method public static android.util.LocaleList forLanguageTags(java.lang.String);
     method public java.util.Locale get(int);
@@ -40935,6 +40933,7 @@
     method public void getCurrentSizeRange(android.graphics.Point, android.graphics.Point);
     method public int getDisplayId();
     method public int getFlags();
+    method public android.view.Display.HdrCapabilities getHdrCapabilities();
     method public deprecated int getHeight();
     method public void getMetrics(android.util.DisplayMetrics);
     method public android.view.Display.Mode getMode();
@@ -40967,6 +40966,21 @@
     field public static final int STATE_UNKNOWN = 0; // 0x0
   }
 
+  public static final class Display.HdrCapabilities implements android.os.Parcelable {
+    ctor public Display.HdrCapabilities(int[], float, float, float);
+    method public int describeContents();
+    method public float getDesiredMaxAverageLuminance();
+    method public float getDesiredMaxLuminance();
+    method public float getDesiredMinLuminance();
+    method public int[] getSupportedHdrTypes();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.view.Display.HdrCapabilities> CREATOR;
+    field public static final int HDR_TYPE_DOLBY_VISION = 1; // 0x1
+    field public static final int HDR_TYPE_HDR10 = 2; // 0x2
+    field public static final int HDR_TYPE_HLG = 3; // 0x3
+    field public static final float INVALID_LUMINANCE = -1.0f;
+  }
+
   public static final class Display.Mode implements android.os.Parcelable {
     method public int describeContents();
     method public int getModeId();
@@ -42049,6 +42063,21 @@
     field public static final int ORIENTATION_UNKNOWN = -1; // 0xffffffff
   }
 
+  public final class PixelCopy {
+    method public static void request(android.view.SurfaceView, android.graphics.Bitmap, android.view.PixelCopy.OnPixelCopyFinishedListener, android.os.Handler);
+    method public static void request(android.view.Surface, android.graphics.Bitmap, android.view.PixelCopy.OnPixelCopyFinishedListener, android.os.Handler);
+    field public static final int ERROR_DESTINATION_INVALID = 5; // 0x5
+    field public static final int ERROR_SOURCE_INVALID = 4; // 0x4
+    field public static final int ERROR_SOURCE_NO_DATA = 3; // 0x3
+    field public static final int ERROR_TIMEOUT = 2; // 0x2
+    field public static final int ERROR_UNKNOWN = 1; // 0x1
+    field public static final int SUCCESS = 0; // 0x0
+  }
+
+  public static abstract interface PixelCopy.OnPixelCopyFinishedListener {
+    method public abstract void onPixelCopyFinished(int);
+  }
+
   public final class PointerIcon implements android.os.Parcelable {
     method public static android.view.PointerIcon createCustomIcon(android.graphics.Bitmap, float, float);
     method public int describeContents();
diff --git a/api/system-current.txt b/api/system-current.txt
index f9d8d34..a8afd96 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -43370,9 +43370,7 @@
   }
 
   public final class LocaleList implements android.os.Parcelable {
-    ctor public LocaleList();
-    ctor public LocaleList(java.util.Locale);
-    ctor public LocaleList(java.util.Locale[]);
+    ctor public LocaleList(java.util.Locale...);
     method public int describeContents();
     method public static android.util.LocaleList forLanguageTags(java.lang.String);
     method public java.util.Locale get(int);
@@ -43925,6 +43923,7 @@
     method public void getCurrentSizeRange(android.graphics.Point, android.graphics.Point);
     method public int getDisplayId();
     method public int getFlags();
+    method public android.view.Display.HdrCapabilities getHdrCapabilities();
     method public deprecated int getHeight();
     method public void getMetrics(android.util.DisplayMetrics);
     method public android.view.Display.Mode getMode();
@@ -43957,6 +43956,21 @@
     field public static final int STATE_UNKNOWN = 0; // 0x0
   }
 
+  public static final class Display.HdrCapabilities implements android.os.Parcelable {
+    ctor public Display.HdrCapabilities(int[], float, float, float);
+    method public int describeContents();
+    method public float getDesiredMaxAverageLuminance();
+    method public float getDesiredMaxLuminance();
+    method public float getDesiredMinLuminance();
+    method public int[] getSupportedHdrTypes();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.view.Display.HdrCapabilities> CREATOR;
+    field public static final int HDR_TYPE_DOLBY_VISION = 1; // 0x1
+    field public static final int HDR_TYPE_HDR10 = 2; // 0x2
+    field public static final int HDR_TYPE_HLG = 3; // 0x3
+    field public static final float INVALID_LUMINANCE = -1.0f;
+  }
+
   public static final class Display.Mode implements android.os.Parcelable {
     method public int describeContents();
     method public int getModeId();
@@ -45039,6 +45053,21 @@
     field public static final int ORIENTATION_UNKNOWN = -1; // 0xffffffff
   }
 
+  public final class PixelCopy {
+    method public static void request(android.view.SurfaceView, android.graphics.Bitmap, android.view.PixelCopy.OnPixelCopyFinishedListener, android.os.Handler);
+    method public static void request(android.view.Surface, android.graphics.Bitmap, android.view.PixelCopy.OnPixelCopyFinishedListener, android.os.Handler);
+    field public static final int ERROR_DESTINATION_INVALID = 5; // 0x5
+    field public static final int ERROR_SOURCE_INVALID = 4; // 0x4
+    field public static final int ERROR_SOURCE_NO_DATA = 3; // 0x3
+    field public static final int ERROR_TIMEOUT = 2; // 0x2
+    field public static final int ERROR_UNKNOWN = 1; // 0x1
+    field public static final int SUCCESS = 0; // 0x0
+  }
+
+  public static abstract interface PixelCopy.OnPixelCopyFinishedListener {
+    method public abstract void onPixelCopyFinished(int);
+  }
+
   public final class PointerIcon implements android.os.Parcelable {
     method public static android.view.PointerIcon createCustomIcon(android.graphics.Bitmap, float, float);
     method public int describeContents();
diff --git a/api/test-current.txt b/api/test-current.txt
index 25e58e2..a0ca0f4 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -40458,9 +40458,7 @@
   }
 
   public final class LocaleList implements android.os.Parcelable {
-    ctor public LocaleList();
-    ctor public LocaleList(java.util.Locale);
-    ctor public LocaleList(java.util.Locale[]);
+    ctor public LocaleList(java.util.Locale...);
     method public int describeContents();
     method public static android.util.LocaleList forLanguageTags(java.lang.String);
     method public java.util.Locale get(int);
@@ -41013,6 +41011,7 @@
     method public void getCurrentSizeRange(android.graphics.Point, android.graphics.Point);
     method public int getDisplayId();
     method public int getFlags();
+    method public android.view.Display.HdrCapabilities getHdrCapabilities();
     method public deprecated int getHeight();
     method public void getMetrics(android.util.DisplayMetrics);
     method public android.view.Display.Mode getMode();
@@ -41045,6 +41044,21 @@
     field public static final int STATE_UNKNOWN = 0; // 0x0
   }
 
+  public static final class Display.HdrCapabilities implements android.os.Parcelable {
+    ctor public Display.HdrCapabilities(int[], float, float, float);
+    method public int describeContents();
+    method public float getDesiredMaxAverageLuminance();
+    method public float getDesiredMaxLuminance();
+    method public float getDesiredMinLuminance();
+    method public int[] getSupportedHdrTypes();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.view.Display.HdrCapabilities> CREATOR;
+    field public static final int HDR_TYPE_DOLBY_VISION = 1; // 0x1
+    field public static final int HDR_TYPE_HDR10 = 2; // 0x2
+    field public static final int HDR_TYPE_HLG = 3; // 0x3
+    field public static final float INVALID_LUMINANCE = -1.0f;
+  }
+
   public static final class Display.Mode implements android.os.Parcelable {
     method public int describeContents();
     method public int getModeId();
@@ -42127,6 +42141,21 @@
     field public static final int ORIENTATION_UNKNOWN = -1; // 0xffffffff
   }
 
+  public final class PixelCopy {
+    method public static void request(android.view.SurfaceView, android.graphics.Bitmap, android.view.PixelCopy.OnPixelCopyFinishedListener, android.os.Handler);
+    method public static void request(android.view.Surface, android.graphics.Bitmap, android.view.PixelCopy.OnPixelCopyFinishedListener, android.os.Handler);
+    field public static final int ERROR_DESTINATION_INVALID = 5; // 0x5
+    field public static final int ERROR_SOURCE_INVALID = 4; // 0x4
+    field public static final int ERROR_SOURCE_NO_DATA = 3; // 0x3
+    field public static final int ERROR_TIMEOUT = 2; // 0x2
+    field public static final int ERROR_UNKNOWN = 1; // 0x1
+    field public static final int SUCCESS = 0; // 0x0
+  }
+
+  public static abstract interface PixelCopy.OnPixelCopyFinishedListener {
+    method public abstract void onPixelCopyFinished(int);
+  }
+
   public final class PointerIcon implements android.os.Parcelable {
     method public static android.view.PointerIcon createCustomIcon(android.graphics.Bitmap, float, float);
     method public int describeContents();
diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java
index 3e25edb..6911b01 100644
--- a/core/java/android/service/notification/ZenModeConfig.java
+++ b/core/java/android/service/notification/ZenModeConfig.java
@@ -40,6 +40,7 @@
 
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Calendar;
 import java.util.GregorianCalendar;
 import java.util.Locale;
@@ -878,6 +879,19 @@
             rt.nextAlarm = nextAlarm;
             return rt;
         }
+
+        @Override
+        public String toString() {
+            return "ScheduleInfo{" +
+                    "days=" + Arrays.toString(days) +
+                    ", startHour=" + startHour +
+                    ", startMinute=" + startMinute +
+                    ", endHour=" + endHour +
+                    ", endMinute=" + endMinute +
+                    ", exitAtAlarm=" + exitAtAlarm +
+                    ", nextAlarm=" + nextAlarm +
+                    '}';
+        }
     }
 
     // ==== Built-in system condition: event ====
diff --git a/core/java/android/util/LocaleList.java b/core/java/android/util/LocaleList.java
index fa3921c..b153e92 100644
--- a/core/java/android/util/LocaleList.java
+++ b/core/java/android/util/LocaleList.java
@@ -32,8 +32,8 @@
 import java.util.Locale;
 
 /**
- * LocaleList is an immutable list of Locales, typically used to keep an
- * ordered user preferences for locales.
+ * LocaleList is an immutable list of Locales, typically used to keep an ordered list of user
+ * preferences for locales.
  */
 public final class LocaleList implements Parcelable {
     private final Locale[] mList;
@@ -46,19 +46,42 @@
     private static final Locale[] sEmptyList = new Locale[0];
     private static final LocaleList sEmptyLocaleList = new LocaleList();
 
-    public Locale get(int location) {
-        return (0 <= location && location < mList.length) ? mList[location] : null;
+    /**
+     * Retrieves the {@link Locale} at the specified index.
+     *
+     * @param index The position to retrieve.
+     * @return The {@link Locale} in the given index.
+     */
+    public Locale get(int index) {
+        return (0 <= index && index < mList.length) ? mList[index] : null;
     }
 
+    /**
+     * Returns whether the {@link LocaleList} contains no {@link Locale} items.
+     *
+     * @return {@code true} if this {@link LocaleList} has no {@link Locale} items, {@code false}
+     *     otherwise.
+     */
     public boolean isEmpty() {
         return mList.length == 0;
     }
 
+    /**
+     * Returns the number of {@link Locale} items in this {@link LocaleList}.
+     */
     @IntRange(from=0)
     public int size() {
         return mList.length;
     }
 
+    /**
+     * Searches this {@link LocaleList} for the specified {@link Locale} and returns the index of
+     * the first occurrence.
+     *
+     * @param locale The {@link Locale} to search for.
+     * @return The index of the first occurrence of the {@link Locale} or {@code -1} if the item
+     *     wasn't found.
+     */
     @IntRange(from=-1)
     public int indexOf(Locale locale) {
         for (int i = 0; i < mList.length; i++) {
@@ -118,6 +141,9 @@
         dest.writeString(mStringRepresentation);
     }
 
+    /**
+     * Retrieves a String representation of the language tags in this list.
+     */
     @NonNull
     public String toLanguageTags() {
         return mStringRepresentation;
@@ -126,6 +152,8 @@
     /**
      * It is almost always better to call {@link #getEmptyLocaleList()} instead which returns
      * a pre-constructed empty locale list.
+     *
+     * @hide
      */
     public LocaleList() {
         mList = sEmptyList;
@@ -133,25 +161,15 @@
     }
 
     /**
+     * Creates a new {@link LocaleList}.
+     *
+     * <p>For empty lists of {@link Locale} items it is better to use {@link #getEmptyLocaleList()},
+     * which returns a pre-constructed empty list.</p>
+     *
      * @throws NullPointerException if any of the input locales is <code>null</code>.
      * @throws IllegalArgumentException if any of the input locales repeat.
      */
-    public LocaleList(@Nullable Locale locale) {
-        if (locale == null) {
-            mList = sEmptyList;
-            mStringRepresentation = "";
-        } else {
-            mList = new Locale[1];
-            mList[0] = (Locale) locale.clone();
-            mStringRepresentation = locale.toLanguageTag();
-        }
-    }
-
-    /**
-     * @throws NullPointerException if any of the input locales is <code>null</code>.
-     * @throws IllegalArgumentException if any of the input locales repeat.
-     */
-    public LocaleList(@Nullable Locale[] list) {
+    public LocaleList(@Nullable Locale... list) {
         if (list == null || list.length == 0) {
             mList = sEmptyList;
             mStringRepresentation = "";
@@ -242,11 +260,20 @@
         }
     };
 
+    /**
+     * Retrieve an empty instance of {@link LocaleList}.
+     */
     @NonNull
     public static LocaleList getEmptyLocaleList() {
         return sEmptyLocaleList;
     }
 
+    /**
+     * Generates a new LocaleList with the given language tags.
+     *
+     * @param list The language tags to be included as a single {@link String} separated by commas.
+     * @return A new instance with the {@link Locale} items identified by the given tags.
+     */
     @NonNull
     public static LocaleList forLanguageTags(@Nullable String list) {
         if (list == null || list.equals("")) {
@@ -374,7 +401,8 @@
      * Returns the first match in the locale list given an unordered array of supported locales
      * in BCP 47 format.
      *
-     * If the locale list is empty, null would be returned.
+     * @return The first {@link Locale} from this list that appears in the given array, or
+     *     {@code null} if the {@link LocaleList} is empty.
      */
     @Nullable
     public Locale getFirstMatch(String[] supportedLocales) {
@@ -445,9 +473,9 @@
      * preferred locales, having concluded that the primary preference is not supported but a
      * secondary preference is.
      *
-     * Note that the default LocaleList would change if Locale.setDefault() is called. This method
-     * takes that into account by always checking the output of Locale.getDefault() and
-     * recalculating the default LocaleList if needed.
+     * <p>Note that the default LocaleList would change if Locale.setDefault() is called. This
+     * method takes that into account by always checking the output of Locale.getDefault() and
+     * recalculating the default LocaleList if needed.</p>
      */
     @NonNull @Size(min=1)
     public static LocaleList getDefault() {
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index 22d5ed8..48eee05 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -719,10 +719,12 @@
 
     /**
      * Returns the display's HDR capabilities.
-     * @hide
      */
     public HdrCapabilities getHdrCapabilities() {
-        return new HdrCapabilities();
+        synchronized (this) {
+            updateDisplayInfoLocked();
+            return mDisplayInfo.hdrCapabilities;
+        }
     }
 
     /**
@@ -1127,7 +1129,6 @@
      * For example, what HDR types it supports and details about the desired luminance data.
      * <p>You can get an instance for a given {@link Display} object with
      * {@link Display#getHdrCapabilities getHdrCapabilities()}.
-     * @hide
      */
     public static final class HdrCapabilities implements Parcelable {
         /**
@@ -1147,6 +1148,7 @@
          */
         public static final int HDR_TYPE_HLG = 3;
 
+        /** @hide */
         @IntDef({
             HDR_TYPE_DOLBY_VISION,
             HDR_TYPE_HDR10,
@@ -1160,9 +1162,20 @@
         private float mMaxAverageLuminance = INVALID_LUMINANCE;
         private float mMinLuminance = INVALID_LUMINANCE;
 
+        /**
+         * @hide
+         */
         public HdrCapabilities() {
         }
 
+        public HdrCapabilities(int[] supportedHdrTypes, float maxLuminance,
+                float maxAverageLuminance, float minLuminance) {
+            mSupportedHdrTypes = supportedHdrTypes;
+            mMaxLuminance = maxLuminance;
+            mMaxAverageLuminance = maxAverageLuminance;
+            mMinLuminance = minLuminance;
+        }
+
         /**
          * Gets the supported HDR types of this display.
          * Returns empty array if HDR is not supported by the display.
@@ -1205,6 +1218,9 @@
             readFromParcel(source);
         }
 
+        /**
+         * @hide
+         */
         public void readFromParcel(Parcel source) {
             int types = source.readInt();
             mSupportedHdrTypes = new int[types];
diff --git a/core/java/android/view/DisplayInfo.java b/core/java/android/view/DisplayInfo.java
index ee76274..27fe687c 100644
--- a/core/java/android/view/DisplayInfo.java
+++ b/core/java/android/view/DisplayInfo.java
@@ -178,6 +178,9 @@
     /** The list of supported color transforms */
     public Display.ColorTransform[] supportedColorTransforms = Display.ColorTransform.EMPTY_ARRAY;
 
+    /** The display's HDR capabilities */
+    public Display.HdrCapabilities hdrCapabilities;
+
     /**
      * The logical display density which is the basis for density-independent
      * pixels.
@@ -290,6 +293,7 @@
                 && defaultModeId == other.defaultModeId
                 && colorTransformId == other.colorTransformId
                 && defaultColorTransformId == other.defaultColorTransformId
+                && Objects.equal(hdrCapabilities, other.hdrCapabilities)
                 && logicalDensityDpi == other.logicalDensityDpi
                 && physicalXDpi == other.physicalXDpi
                 && physicalYDpi == other.physicalYDpi
@@ -332,6 +336,7 @@
         defaultColorTransformId = other.defaultColorTransformId;
         supportedColorTransforms = Arrays.copyOf(
                 other.supportedColorTransforms, other.supportedColorTransforms.length);
+        hdrCapabilities = other.hdrCapabilities;
         logicalDensityDpi = other.logicalDensityDpi;
         physicalXDpi = other.physicalXDpi;
         physicalYDpi = other.physicalYDpi;
@@ -375,6 +380,7 @@
         for (int i = 0; i < nColorTransforms; i++) {
             supportedColorTransforms[i] = Display.ColorTransform.CREATOR.createFromParcel(source);
         }
+        hdrCapabilities = Display.HdrCapabilities.CREATOR.createFromParcel(source);
         logicalDensityDpi = source.readInt();
         physicalXDpi = source.readFloat();
         physicalYDpi = source.readFloat();
@@ -418,6 +424,7 @@
         for (int i = 0; i < supportedColorTransforms.length; i++) {
             supportedColorTransforms[i].writeToParcel(dest, flags);
         }
+        hdrCapabilities.writeToParcel(dest, flags);
         dest.writeInt(logicalDensityDpi);
         dest.writeFloat(physicalXDpi);
         dest.writeFloat(physicalYDpi);
@@ -614,6 +621,8 @@
         sb.append(defaultColorTransformId);
         sb.append(", supportedColorTransforms ");
         sb.append(Arrays.toString(supportedColorTransforms));
+        sb.append(", hdrCapabilities ");
+        sb.append(hdrCapabilities);
         sb.append(", rotation ");
         sb.append(rotation);
         sb.append(", density ");
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index dc9014b..7b01267 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -88,6 +88,7 @@
     private static native void nativeSetOverrideScalingMode(long nativeObject,
             int scalingMode);
     private static native IBinder nativeGetHandle(long nativeObject);
+    private static native Display.HdrCapabilities nativeGetHdrCapabilities(IBinder displayToken);
 
 
     private final CloseGuard mCloseGuard = CloseGuard.get();
@@ -656,6 +657,13 @@
         nativeSetDisplaySize(displayToken, width, height);
     }
 
+    public static Display.HdrCapabilities getHdrCapabilities(IBinder displayToken) {
+        if (displayToken == null) {
+            throw new IllegalArgumentException("displayToken must not be null");
+        }
+        return nativeGetHdrCapabilities(displayToken);
+    }
+
     public static IBinder createDisplay(String name, boolean secure) {
         if (name == null) {
             throw new IllegalArgumentException("name must not be null");
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index 34110df..9c6e6b7 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -909,7 +909,7 @@
         nSerializeDisplayListTree(mNativeProxy);
     }
 
-    public static boolean copySurfaceInto(Surface surface, Bitmap bitmap) {
+    public static int copySurfaceInto(Surface surface, Bitmap bitmap) {
         return nCopySurfaceInto(surface, bitmap);
     }
 
@@ -1051,5 +1051,5 @@
     private static native long nAddFrameMetricsObserver(long nativeProxy, FrameMetricsObserver observer);
     private static native void nRemoveFrameMetricsObserver(long nativeProxy, long nativeObserver);
 
-    private static native boolean nCopySurfaceInto(Surface surface, Bitmap bitmap);
+    private static native int nCopySurfaceInto(Surface surface, Bitmap bitmap);
 }
diff --git a/core/java/android/widget/EditText.java b/core/java/android/widget/EditText.java
index ad35550..24d8618 100644
--- a/core/java/android/widget/EditText.java
+++ b/core/java/android/widget/EditText.java
@@ -149,26 +149,4 @@
             info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SET_TEXT);
         }
     }
-
-    /** @hide */
-    @Override
-    public boolean performAccessibilityActionInternal(int action, Bundle arguments) {
-        switch (action) {
-            case AccessibilityNodeInfo.ACTION_SET_TEXT: {
-                if (!isEnabled()) {
-                    return false;
-                }
-                CharSequence text = (arguments != null) ? arguments.getCharSequence(
-                        AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE) : null;
-                setText(text);
-                if (text != null && text.length() > 0) {
-                    setSelection(text.length());
-                }
-                return true;
-            }
-            default: {
-                return super.performAccessibilityActionInternal(action, arguments);
-            }
-        }
-    }
 }
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 3216fba..26697f9 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -9203,8 +9203,11 @@
                 CharSequence text = (arguments != null) ? arguments.getCharSequence(
                         AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE) : null;
                 setText(text);
-                if (text != null && text.length() > 0) {
-                    Selection.setSelection((Spannable) mText, text.length());
+                if (mText != null) {
+                    int updatedTextLength = mText.length();
+                    if (updatedTextLength > 0) {
+                        Selection.setSelection((Spannable) mText, updatedTextLength);
+                    }
                 }
             } return true;
             default: {
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 0590134..864a0bf 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -33,6 +33,7 @@
 #include <memory>
 #include <stdio.h>
 #include <ui/DisplayInfo.h>
+#include <ui/HdrCapabilities.h>
 #include <ui/FrameStats.h>
 #include <ui/Rect.h>
 #include <ui/Region.h>
@@ -83,6 +84,11 @@
     jmethodID init;
 } gWindowAnimationFrameStatsClassInfo;
 
+static struct {
+    jclass clazz;
+    jmethodID ctor;
+} gHdrCapabilitiesClassInfo;
+
 // ----------------------------------------------------------------------------
 
 static jlong nativeCreate(JNIEnv* env, jclass clazz, jobject sessionObj,
@@ -610,6 +616,22 @@
     return javaObjectForIBinder(env, ctrl->getHandle());
 }
 
+static jobject nativeGetHdrCapabilities(JNIEnv* env, jclass clazz, jobject tokenObject) {
+    sp<IBinder> token(ibinderForJavaObject(env, tokenObject));
+    if (token == NULL) return NULL;
+
+    HdrCapabilities capabilities;
+    SurfaceComposerClient::getHdrCapabilities(token, &capabilities);
+
+    const auto& types = capabilities.getSupportedHdrTypes();
+    auto typesArray = env->NewIntArray(types.size());
+    env->SetIntArrayRegion(typesArray, 0, types.size(), types.data());
+
+    return env->NewObject(gHdrCapabilitiesClassInfo.clazz, gHdrCapabilitiesClassInfo.ctor,
+            typesArray, capabilities.getDesiredMaxLuminance(),
+            capabilities.getDesiredMaxAverageLuminance(), capabilities.getDesiredMinLuminance());
+}
+
 // ----------------------------------------------------------------------------
 
 static const JNINativeMethod sSurfaceControlMethods[] = {
@@ -671,6 +693,8 @@
             (void*)nativeGetActiveConfig },
     {"nativeSetActiveConfig", "(Landroid/os/IBinder;I)Z",
             (void*)nativeSetActiveConfig },
+    {"nativeGetHdrCapabilities", "(Landroid/os/IBinder;)Landroid/view/Display$HdrCapabilities;",
+            (void*)nativeGetHdrCapabilities },
     {"nativeClearContentFrameStats", "(J)Z",
             (void*)nativeClearContentFrameStats },
     {"nativeGetContentFrameStats", "(JLandroid/view/WindowContentFrameStats;)Z",
@@ -733,6 +757,11 @@
             animFrameStatsClazz, "init", "(J[J)V");
     gWindowAnimationFrameStatsClassInfo.UNDEFINED_TIME_NANO = undefined_time_nano;
 
+    jclass hdrCapabilitiesClazz = FindClassOrDie(env, "android/view/Display$HdrCapabilities");
+    gHdrCapabilitiesClassInfo.clazz = MakeGlobalRefOrDie(env, hdrCapabilitiesClazz);
+    gHdrCapabilitiesClassInfo.ctor = GetMethodIDOrDie(env, hdrCapabilitiesClazz, "<init>",
+            "([IFFF)V");
+
     return err;
 }
 
diff --git a/core/jni/android_view_ThreadedRenderer.cpp b/core/jni/android_view_ThreadedRenderer.cpp
index 68c818e..650a0fc 100644
--- a/core/jni/android_view_ThreadedRenderer.cpp
+++ b/core/jni/android_view_ThreadedRenderer.cpp
@@ -669,7 +669,7 @@
     proxy->setContentDrawBounds(left, top, right, bottom);
 }
 
-static jboolean android_view_ThreadedRenderer_copySurfaceInto(JNIEnv* env,
+static jint android_view_ThreadedRenderer_copySurfaceInto(JNIEnv* env,
         jobject clazz, jobject jsurface, jobject jbitmap) {
     SkBitmap bitmap;
     GraphicsJNI::getSkBitmap(env, jbitmap, &bitmap);
@@ -783,7 +783,7 @@
     { "nRemoveFrameMetricsObserver",
             "(JJ)V",
             (void*)android_view_ThreadedRenderer_removeFrameMetricsObserver },
-    { "nCopySurfaceInto", "(Landroid/view/Surface;Landroid/graphics/Bitmap;)Z",
+    { "nCopySurfaceInto", "(Landroid/view/Surface;Landroid/graphics/Bitmap;)I",
                 (void*)android_view_ThreadedRenderer_copySurfaceInto },
 };
 
diff --git a/graphics/java/android/graphics/PixelCopy.java b/graphics/java/android/graphics/PixelCopy.java
deleted file mode 100644
index c599126..0000000
--- a/graphics/java/android/graphics/PixelCopy.java
+++ /dev/null
@@ -1,104 +0,0 @@
-package android.graphics;
-
-import android.annotation.NonNull;
-import android.os.Handler;
-import android.view.Surface;
-import android.view.SurfaceView;
-import android.view.ThreadedRenderer;
-
-/**
- * Provides a mechanisms to issue pixel copy requests to allow for copy
- * operations from {@link Surface} to {@link Bitmap}
- *
- * @hide
- */
-public final class PixelCopy {
-    /**
-     * Contains the result of a pixel copy request
-     */
-    public static final class Response {
-        /**
-         * Indicates whether or not the copy request completed successfully.
-         * If this is true, then {@link #bitmap} contains the result of the copy.
-         * If this is false, {@link #bitmap} is unmodified from the originally
-         * passed destination.
-         *
-         * For example a request might fail if the source is protected content
-         * so copies are not allowed. Similarly if the source has nothing to
-         * copy from, because either no frames have been produced yet or because
-         * it has already been destroyed, then this will be false.
-         */
-        public boolean success;
-
-        /**
-         * The output bitmap. This is always the same object that was passed
-         * to request() as the 'dest' bitmap. If {@link #success} is true this
-         * contains a copy of the pixels of the source object. If {@link #success}
-         * is false then this is unmodified.
-         */
-        @NonNull
-        public Bitmap bitmap;
-    }
-
-    public interface OnPixelCopyFinished {
-        /**
-         * Callback for when a pixel copy request has completed. This will be called
-         * regardless of whether the copy succeeded or failed.
-         *
-         * @param response Contains the result of the copy request which includes
-         * whether or not the copy was successful.
-         */
-        void onPixelCopyFinished(PixelCopy.Response response);
-    }
-
-    /**
-     * Requests for the display content of a {@link SurfaceView} to be copied
-     * into a provided {@link Bitmap}.
-     *
-     * The contents of the source will be scaled to fit exactly inside the bitmap.
-     * The pixel format of the source buffer will be converted, as part of the copy,
-     * to fit the the bitmap's {@link Bitmap.Config}. The most recently queued buffer
-     * in the SurfaceView's Surface will be used as the source of the copy.
-     *
-     * @param source The source from which to copy
-     * @param dest The destination of the copy. The source will be scaled to
-     * match the width, height, and format of this bitmap.
-     * @param listener Callback for when the pixel copy request completes
-     * @param listenerThread The callback will be invoked on this Handler when
-     * the copy is finished.
-     */
-    public static void request(@NonNull SurfaceView source, @NonNull Bitmap dest,
-            @NonNull OnPixelCopyFinished listener, @NonNull Handler listenerThread) {
-        request(source.getHolder().getSurface(), dest, listener, listenerThread);
-    }
-
-    /**
-     * Requests a copy of the pixels from a {@link Surface} to be copied into
-     * a provided {@link Bitmap}.
-     *
-     * The contents of the source will be scaled to fit exactly inside the bitmap.
-     * The pixel format of the source buffer will be converted, as part of the copy,
-     * to fit the the bitmap's {@link Bitmap.Config}. The most recently queued buffer
-     * in the Surface will be used as the source of the copy.
-     *
-     * @param source The source from which to copy
-     * @param dest The destination of the copy. The source will be scaled to
-     * match the width, height, and format of this bitmap.
-     * @param listener Callback for when the pixel copy request completes
-     * @param listenerThread The callback will be invoked on this Handler when
-     * the copy is finished.
-     */
-    public static void request(@NonNull Surface source, @NonNull Bitmap dest,
-            @NonNull OnPixelCopyFinished listener, @NonNull Handler listenerThread) {
-        // TODO: Make this actually async and fast and cool and stuff
-        final PixelCopy.Response response = new PixelCopy.Response();
-        response.success = ThreadedRenderer.copySurfaceInto(source, dest);
-        response.bitmap = dest;
-        listenerThread.post(new Runnable() {
-            @Override
-            public void run() {
-                listener.onPixelCopyFinished(response);
-            }
-        });
-    }
-}
diff --git a/graphics/java/android/view/PixelCopy.java b/graphics/java/android/view/PixelCopy.java
new file mode 100644
index 0000000..95c930c
--- /dev/null
+++ b/graphics/java/android/view/PixelCopy.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2016 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.view;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.graphics.Bitmap;
+import android.os.Handler;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Provides a mechanisms to issue pixel copy requests to allow for copy
+ * operations from {@link Surface} to {@link Bitmap}
+ */
+public final class PixelCopy {
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({SUCCESS, ERROR_UNKNOWN, ERROR_TIMEOUT, ERROR_SOURCE_NO_DATA,
+        ERROR_SOURCE_INVALID, ERROR_DESTINATION_INVALID})
+    public @interface CopyResultStatus {}
+
+    /** The pixel copy request succeeded */
+    public static final int SUCCESS = 0;
+
+    /** The pixel copy request failed with an unknown error. */
+    public static final int ERROR_UNKNOWN = 1;
+
+    /**
+     * A timeout occurred while trying to acquire a buffer from the source to
+     * copy from.
+     */
+    public static final int ERROR_TIMEOUT = 2;
+
+    /**
+     * The source has nothing to copy from. When the source is a {@link Surface}
+     * this means that no buffers have been queued yet. Wait for the source
+     * to produce a frame and try again.
+     */
+    public static final int ERROR_SOURCE_NO_DATA = 3;
+
+    /**
+     * It is not possible to copy from the source. This can happen if the source
+     * is hardware-protected or destroyed.
+     */
+    public static final int ERROR_SOURCE_INVALID = 4;
+
+    /**
+     * The destination isn't a valid copy target. If the destination is a bitmap
+     * this can occur if the bitmap is too large for the hardware to copy to.
+     * It can also occur if the destination has been destroyed.
+     */
+    public static final int ERROR_DESTINATION_INVALID = 5;
+
+    /**
+     * Listener for observing the completion of a PixelCopy request.
+     */
+    public interface OnPixelCopyFinishedListener {
+        /**
+         * Callback for when a pixel copy request has completed. This will be called
+         * regardless of whether the copy succeeded or failed.
+         *
+         * @param copyResult Contains the resulting status of the copy request.
+         * This will either be {@link PixelCopy#SUCCESS} or one of the
+         * <code>PixelCopy.ERROR_*</code> values.
+         */
+        void onPixelCopyFinished(@CopyResultStatus int copyResult);
+    }
+
+    /**
+     * Requests for the display content of a {@link SurfaceView} to be copied
+     * into a provided {@link Bitmap}.
+     *
+     * The contents of the source will be scaled to fit exactly inside the bitmap.
+     * The pixel format of the source buffer will be converted, as part of the copy,
+     * to fit the the bitmap's {@link Bitmap.Config}. The most recently queued buffer
+     * in the SurfaceView's Surface will be used as the source of the copy.
+     *
+     * @param source The source from which to copy
+     * @param dest The destination of the copy. The source will be scaled to
+     * match the width, height, and format of this bitmap.
+     * @param listener Callback for when the pixel copy request completes
+     * @param listenerThread The callback will be invoked on this Handler when
+     * the copy is finished.
+     */
+    public static void request(@NonNull SurfaceView source, @NonNull Bitmap dest,
+            @NonNull OnPixelCopyFinishedListener listener, @NonNull Handler listenerThread) {
+        request(source.getHolder().getSurface(), dest, listener, listenerThread);
+    }
+
+    /**
+     * Requests a copy of the pixels from a {@link Surface} to be copied into
+     * a provided {@link Bitmap}.
+     *
+     * The contents of the source will be scaled to fit exactly inside the bitmap.
+     * The pixel format of the source buffer will be converted, as part of the copy,
+     * to fit the the bitmap's {@link Bitmap.Config}. The most recently queued buffer
+     * in the Surface will be used as the source of the copy.
+     *
+     * @param source The source from which to copy
+     * @param dest The destination of the copy. The source will be scaled to
+     * match the width, height, and format of this bitmap.
+     * @param listener Callback for when the pixel copy request completes
+     * @param listenerThread The callback will be invoked on this Handler when
+     * the copy is finished.
+     */
+    public static void request(@NonNull Surface source, @NonNull Bitmap dest,
+            @NonNull OnPixelCopyFinishedListener listener, @NonNull Handler listenerThread) {
+        validateBitmapDest(dest);
+        // TODO: Make this actually async and fast and cool and stuff
+        int result = ThreadedRenderer.copySurfaceInto(source, dest);
+        listenerThread.post(new Runnable() {
+            @Override
+            public void run() {
+                listener.onPixelCopyFinished(result);
+            }
+        });
+    }
+
+    private static void validateBitmapDest(Bitmap bitmap) {
+        // TODO: Pre-check max texture dimens if we can
+        if (bitmap == null) {
+            throw new IllegalArgumentException("Bitmap cannot be null");
+        }
+        if (bitmap.isRecycled()) {
+            throw new IllegalArgumentException("Bitmap is recycled");
+        }
+        if (!bitmap.isMutable()) {
+            throw new IllegalArgumentException("Bitmap is immutable");
+        }
+    }
+
+    private PixelCopy() {}
+}
diff --git a/libs/hwui/Readback.cpp b/libs/hwui/Readback.cpp
index 4a32589..49596e1 100644
--- a/libs/hwui/Readback.cpp
+++ b/libs/hwui/Readback.cpp
@@ -30,7 +30,7 @@
 namespace android {
 namespace uirenderer {
 
-bool Readback::copySurfaceInto(renderthread::RenderThread& renderThread,
+CopyResult Readback::copySurfaceInto(renderthread::RenderThread& renderThread,
         Surface& surface, SkBitmap* bitmap) {
     // TODO: Clean this up and unify it with LayerRenderer::copyLayer,
     // of which most of this is copied from.
@@ -44,12 +44,12 @@
                 || destHeight > caches.maxTextureSize) {
         ALOGW("Can't copy surface into bitmap, %dx%d exceeds max texture size %d",
                 destWidth, destHeight, caches.maxTextureSize);
-        return false;
+        return CopyResult::DestinationInvalid;
     }
     GLuint fbo = renderState.createFramebuffer();
     if (!fbo) {
         ALOGW("Could not obtain an FBO");
-        return false;
+        return CopyResult::UnknownError;
     }
 
     SkAutoLockPixels alp(*bitmap);
@@ -104,16 +104,20 @@
     status_t err = surface.getLastQueuedBuffer(&sourceBuffer, &sourceFence);
     if (err != NO_ERROR) {
         ALOGW("Failed to get last queued buffer, error = %d", err);
-        return false;
+        return CopyResult::UnknownError;
     }
     if (!sourceBuffer.get()) {
         ALOGW("Surface doesn't have any previously queued frames, nothing to readback from");
-        return false;
+        return CopyResult::SourceEmpty;
+    }
+    if (sourceBuffer->getUsage() & GRALLOC_USAGE_PROTECTED) {
+        ALOGW("Surface is protected, unable to copy from it");
+        return CopyResult::SourceInvalid;
     }
     err = sourceFence->wait(500 /* ms */);
     if (err != NO_ERROR) {
         ALOGE("Timeout (500ms) exceeded waiting for buffer fence, abandoning readback attempt");
-        return false;
+        return CopyResult::Timeout;
     }
 
     // TODO: Can't use Image helper since it forces GL_TEXTURE_2D usage via
@@ -130,7 +134,7 @@
 
     if (sourceImage == EGL_NO_IMAGE_KHR) {
         ALOGW("Error creating image (%#x)", eglGetError());
-        return false;
+        return CopyResult::UnknownError;
     }
     GLuint sourceTexId;
     // Create a 2D texture to sample from the EGLImage
@@ -141,7 +145,7 @@
     GLenum status = GL_NO_ERROR;
     while ((status = glGetError()) != GL_NO_ERROR) {
         ALOGW("Error creating image (%#x)", status);
-        return false;
+        return CopyResult::UnknownError;
     }
 
     Texture sourceTexture(caches);
@@ -178,7 +182,7 @@
 
     GL_CHECKPOINT(MODERATE);
 
-    return true;
+    return CopyResult::Success;
 }
 
 } // namespace uirenderer
diff --git a/libs/hwui/Readback.h b/libs/hwui/Readback.h
index ea03c82..a112c42 100644
--- a/libs/hwui/Readback.h
+++ b/libs/hwui/Readback.h
@@ -24,9 +24,19 @@
 namespace android {
 namespace uirenderer {
 
+// Keep in sync with PixelCopy.java codes
+enum class CopyResult {
+    Success = 0,
+    UnknownError = 1,
+    Timeout = 2,
+    SourceEmpty = 3,
+    SourceInvalid = 4,
+    DestinationInvalid = 5,
+};
+
 class Readback {
 public:
-    static bool copySurfaceInto(renderthread::RenderThread& renderThread,
+    static CopyResult copySurfaceInto(renderthread::RenderThread& renderThread,
             Surface& surface, SkBitmap* bitmap);
 };
 
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index 5e37856e..54af282 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -623,12 +623,13 @@
             *args->surface, args->bitmap);
 }
 
-bool RenderProxy::copySurfaceInto(sp<Surface>& surface, SkBitmap* bitmap) {
+int RenderProxy::copySurfaceInto(sp<Surface>& surface, SkBitmap* bitmap) {
     SETUP_TASK(copySurfaceInto);
     args->bitmap = bitmap;
     args->surface = surface.get();
     args->thread = &RenderThread::getInstance();
-    return (bool) staticPostAndWait(task);
+    return static_cast<int>(
+            reinterpret_cast<intptr_t>( staticPostAndWait(task) ));
 }
 
 void RenderProxy::post(RenderTask* task) {
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index c39319d..898b314 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -127,7 +127,7 @@
     ANDROID_API void removeFrameMetricsObserver(FrameMetricsObserver* observer);
     ANDROID_API long getDroppedFrameReportCount();
 
-    ANDROID_API static bool copySurfaceInto(sp<Surface>& surface, SkBitmap* bitmap);
+    ANDROID_API static int copySurfaceInto(sp<Surface>& surface, SkBitmap* bitmap);
 
 private:
     RenderThread& mRenderThread;
diff --git a/services/core/java/com/android/server/display/DisplayDeviceInfo.java b/services/core/java/com/android/server/display/DisplayDeviceInfo.java
index 55ba302..5ce66fa 100644
--- a/services/core/java/com/android/server/display/DisplayDeviceInfo.java
+++ b/services/core/java/com/android/server/display/DisplayDeviceInfo.java
@@ -165,6 +165,11 @@
     public Display.ColorTransform[] supportedColorTransforms = Display.ColorTransform.EMPTY_ARRAY;
 
     /**
+     * The HDR capabilities this display claims to support.
+     */
+    public Display.HdrCapabilities hdrCapabilities;
+
+    /**
      * The nominal apparent density of the display in DPI used for layout calculations.
      * This density is sensitive to the viewing distance.  A big TV and a tablet may have
      * the same apparent density even though the pixels on the TV are much bigger than
@@ -288,6 +293,7 @@
                 || colorTransformId != other.colorTransformId
                 || defaultColorTransformId != other.defaultColorTransformId
                 || !Arrays.equals(supportedColorTransforms, other.supportedColorTransforms)
+                || !Objects.equal(hdrCapabilities, other.hdrCapabilities)
                 || densityDpi != other.densityDpi
                 || xDpi != other.xDpi
                 || yDpi != other.yDpi
@@ -321,6 +327,7 @@
         colorTransformId = other.colorTransformId;
         defaultColorTransformId = other.defaultColorTransformId;
         supportedColorTransforms = other.supportedColorTransforms;
+        hdrCapabilities = other.hdrCapabilities;
         densityDpi = other.densityDpi;
         xDpi = other.xDpi;
         yDpi = other.yDpi;
@@ -349,6 +356,7 @@
         sb.append(", colorTransformId ").append(colorTransformId);
         sb.append(", defaultColorTransformId ").append(defaultColorTransformId);
         sb.append(", supportedColorTransforms ").append(Arrays.toString(supportedColorTransforms));
+        sb.append(", HdrCapabilities ").append(hdrCapabilities);
         sb.append(", density ").append(densityDpi);
         sb.append(", ").append(xDpi).append(" x ").append(yDpi).append(" dpi");
         sb.append(", appVsyncOff ").append(appVsyncOffsetNanos);
diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
index 715d2d8..7b16ea6 100644
--- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
@@ -158,6 +158,7 @@
         private int mDefaultColorTransformId;
         private int mActiveColorTransformId;
         private boolean mActiveColorTransformInvalid;
+        private Display.HdrCapabilities mHdrCapabilities;
 
         private  SurfaceControl.PhysicalDisplayInfo mDisplayInfos[];
 
@@ -172,6 +173,7 @@
             } else {
                 mBacklight = null;
             }
+            mHdrCapabilities = SurfaceControl.getHdrCapabilities(displayToken);
         }
 
         public boolean updatePhysicalDisplayInfoLocked(
@@ -368,6 +370,7 @@
                 for (int i = 0; i < mSupportedColorTransforms.size(); i++) {
                     mInfo.supportedColorTransforms[i] = mSupportedColorTransforms.valueAt(i);
                 }
+                mInfo.hdrCapabilities = mHdrCapabilities;
                 mInfo.appVsyncOffsetNanos = phys.appVsyncOffsetNanos;
                 mInfo.presentationDeadlineNanos = phys.presentationDeadlineNanos;
                 mInfo.state = mState;
diff --git a/services/core/java/com/android/server/display/LogicalDisplay.java b/services/core/java/com/android/server/display/LogicalDisplay.java
index 6dae397..973f04c 100644
--- a/services/core/java/com/android/server/display/LogicalDisplay.java
+++ b/services/core/java/com/android/server/display/LogicalDisplay.java
@@ -241,6 +241,7 @@
             mBaseDisplayInfo.supportedColorTransforms = Arrays.copyOf(
                     deviceInfo.supportedColorTransforms,
                     deviceInfo.supportedColorTransforms.length);
+            mBaseDisplayInfo.hdrCapabilities = deviceInfo.hdrCapabilities;
             mBaseDisplayInfo.logicalDensityDpi = deviceInfo.densityDpi;
             mBaseDisplayInfo.physicalXDpi = deviceInfo.xDpi;
             mBaseDisplayInfo.physicalYDpi = deviceInfo.yDpi;
diff --git a/services/core/java/com/android/server/notification/ScheduleCalendar.java b/services/core/java/com/android/server/notification/ScheduleCalendar.java
index 4c57c1d..9267d82 100644
--- a/services/core/java/com/android/server/notification/ScheduleCalendar.java
+++ b/services/core/java/com/android/server/notification/ScheduleCalendar.java
@@ -31,7 +31,7 @@
 
     @Override
     public String toString() {
-        return "ScheduleCalendar[mDays=" + mDays + "]";
+        return "ScheduleCalendar[mDays=" + mDays + ", mSchedule=" + mSchedule + "]";
     }
 
     public void setSchedule(ScheduleInfo schedule) {
diff --git a/services/core/java/com/android/server/notification/ScheduleConditionProvider.java b/services/core/java/com/android/server/notification/ScheduleConditionProvider.java
index 8d0ad96..15a63ec 100644
--- a/services/core/java/com/android/server/notification/ScheduleConditionProvider.java
+++ b/services/core/java/com/android/server/notification/ScheduleConditionProvider.java
@@ -86,6 +86,8 @@
             pw.print("        ");
             pw.print(meetsSchedule(mSubscriptions.get(conditionId), now) ? "* " : "  ");
             pw.println(conditionId);
+            pw.print("            ");
+            pw.println(mSubscriptions.get(conditionId).toString());
         }
         dumpUpcomingTime(pw, "mNextAlarmTime", mNextAlarmTime, now);
     }
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/GetBitmapSurfaceViewActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/GetBitmapSurfaceViewActivity.java
index d3cd7db..f658b7c 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/GetBitmapSurfaceViewActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/GetBitmapSurfaceViewActivity.java
@@ -18,13 +18,11 @@
 
 import android.app.Activity;
 import android.graphics.Bitmap;
-import android.graphics.PixelCopy;
-import android.graphics.PixelCopy.OnPixelCopyFinished;
-import android.graphics.PixelCopy.Response;
 import android.hardware.Camera;
 import android.os.Bundle;
 import android.os.Environment;
 import android.view.Gravity;
+import android.view.PixelCopy;
 import android.view.SurfaceHolder;
 import android.view.SurfaceView;
 import android.view.View;
@@ -32,7 +30,6 @@
 import android.widget.FrameLayout;
 import android.widget.Toast;
 
-import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
 
@@ -52,12 +49,25 @@
         Button button = new Button(this);
         button.setText("Copy bitmap to /sdcard/surfaceview.png");
         button.setOnClickListener((View v) -> {
-            Bitmap b = Bitmap.createBitmap(
-                            mSurfaceView.getWidth(),
-                            mSurfaceView.getHeight(),
-                            Bitmap.Config.ARGB_8888);
+            final Bitmap b = Bitmap.createBitmap(
+                    mSurfaceView.getWidth(), mSurfaceView.getHeight(),
+                    Bitmap.Config.ARGB_8888);
             PixelCopy.request(mSurfaceView, b,
-                    mOnCopyFinished, mSurfaceView.getHandler());
+                    (int result) -> {
+                        if (result != PixelCopy.SUCCESS) {
+                            Toast.makeText(GetBitmapSurfaceViewActivity.this,
+                                    "Failed to copy", Toast.LENGTH_SHORT).show();
+                            return;
+                        }
+                        try {
+                            try (FileOutputStream out = new FileOutputStream(
+                                    Environment.getExternalStorageDirectory() + "/surfaceview.png");) {
+                                b.compress(Bitmap.CompressFormat.PNG, 100, out);
+                            }
+                        } catch (Exception e) {
+                            // Ignore
+                        }
+                    }, mSurfaceView.getHandler());
         });
 
         content.addView(mSurfaceView, new FrameLayout.LayoutParams(500, 400, Gravity.CENTER));
@@ -67,25 +77,6 @@
         setContentView(content);
     }
 
-    private final OnPixelCopyFinished mOnCopyFinished = new OnPixelCopyFinished() {
-        @Override
-        public void onPixelCopyFinished(Response response) {
-            if (!response.success) {
-                Toast.makeText(GetBitmapSurfaceViewActivity.this,
-                        "Failed to copy", Toast.LENGTH_SHORT).show();
-                return;
-            }
-            try {
-                try (FileOutputStream out = new FileOutputStream(
-                        Environment.getExternalStorageDirectory() + "/surfaceview.png");) {
-                    response.bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
-                }
-            } catch (Exception e) {
-                // Ignore
-            }
-        }
-    };
-
     @Override
     public void surfaceCreated(SurfaceHolder holder) {
         mCamera = Camera.open();
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/HardwareCanvasSurfaceViewActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/HardwareCanvasSurfaceViewActivity.java
index 5c30fab..086a8f0 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/HardwareCanvasSurfaceViewActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/HardwareCanvasSurfaceViewActivity.java
@@ -20,12 +20,10 @@
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.Paint;
-import android.graphics.PixelCopy;
-import android.graphics.PixelCopy.OnPixelCopyFinished;
-import android.graphics.PixelCopy.Response;
 import android.graphics.PorterDuff;
 import android.os.Bundle;
 import android.os.Environment;
+import android.view.PixelCopy;
 import android.view.Surface;
 import android.view.SurfaceHolder;
 import android.view.SurfaceHolder.Callback;
@@ -36,9 +34,7 @@
 import android.widget.LinearLayout;
 import android.widget.Toast;
 
-import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
-import java.io.IOException;
 
 public class HardwareCanvasSurfaceViewActivity extends Activity implements Callback {
     private SurfaceView mSurfaceView;
@@ -56,12 +52,25 @@
         Button button = new Button(this);
         button.setText("Copy bitmap to /sdcard/surfaceview.png");
         button.setOnClickListener((View v) -> {
-            Bitmap b = Bitmap.createBitmap(
-                            mSurfaceView.getWidth(),
-                            mSurfaceView.getHeight(),
-                            Bitmap.Config.ARGB_8888);
+            final Bitmap b = Bitmap.createBitmap(
+                    mSurfaceView.getWidth(), mSurfaceView.getHeight(),
+                    Bitmap.Config.ARGB_8888);
             PixelCopy.request(mSurfaceView, b,
-                    mOnCopyFinished, mSurfaceView.getHandler());
+                    (int result) -> {
+                        if (result != PixelCopy.SUCCESS) {
+                            Toast.makeText(HardwareCanvasSurfaceViewActivity.this,
+                                    "Failed to copy", Toast.LENGTH_SHORT).show();
+                            return;
+                        }
+                        try {
+                            try (FileOutputStream out = new FileOutputStream(
+                                    Environment.getExternalStorageDirectory() + "/surfaceview.png");) {
+                                b.compress(Bitmap.CompressFormat.PNG, 100, out);
+                            }
+                        } catch (Exception e) {
+                            // Ignore
+                        }
+                    }, mSurfaceView.getHandler());
         });
 
         LinearLayout layout = new LinearLayout(this);
@@ -77,25 +86,6 @@
         setContentView(content);
     }
 
-    private final OnPixelCopyFinished mOnCopyFinished = new OnPixelCopyFinished() {
-        @Override
-        public void onPixelCopyFinished(Response response) {
-            if (!response.success) {
-                Toast.makeText(HardwareCanvasSurfaceViewActivity.this,
-                        "Failed to copy", Toast.LENGTH_SHORT).show();
-                return;
-            }
-            try {
-                try (FileOutputStream out = new FileOutputStream(
-                        Environment.getExternalStorageDirectory() + "/surfaceview.png");) {
-                    response.bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
-                }
-            } catch (Exception e) {
-                // Ignore
-            }
-        }
-    };
-
     @Override
     public void surfaceCreated(SurfaceHolder holder) {
         mThread = new RenderingThread(holder.getSurface());