Merge "Fix empty program list filter handling." into pi-dev
diff --git a/api/current.txt b/api/current.txt
index 670f6ca..bc71226 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -13658,7 +13658,8 @@
     method public android.graphics.ImageDecoder setOnPartialImageListener(android.graphics.ImageDecoder.OnPartialImageListener);
     method public android.graphics.ImageDecoder setPostProcessor(android.graphics.PostProcessor);
     method public android.graphics.ImageDecoder setRequireUnpremultiplied(boolean);
-    method public android.graphics.ImageDecoder setSampleSize(int);
+    method public android.graphics.ImageDecoder setTargetColorSpace(android.graphics.ColorSpace);
+    method public android.graphics.ImageDecoder setTargetSampleSize(int);
     method public android.graphics.ImageDecoder setTargetSize(int, int);
     field public static final int ALLOCATOR_DEFAULT = 0; // 0x0
     field public static final int ALLOCATOR_HARDWARE = 3; // 0x3
@@ -13675,6 +13676,7 @@
   }
 
   public static class ImageDecoder.ImageInfo {
+    method public android.graphics.ColorSpace getColorSpace();
     method public java.lang.String getMimeType();
     method public android.util.Size getSize();
     method public boolean isAnimated();
@@ -50417,9 +50419,9 @@
     ctor public TextClassification.Options();
     method public int describeContents();
     method public android.os.LocaleList getDefaultLocales();
-    method public java.util.Calendar getReferenceTime();
+    method public java.time.ZonedDateTime getReferenceTime();
     method public android.view.textclassifier.TextClassification.Options setDefaultLocales(android.os.LocaleList);
-    method public android.view.textclassifier.TextClassification.Options setReferenceTime(java.util.Calendar);
+    method public android.view.textclassifier.TextClassification.Options setReferenceTime(java.time.ZonedDateTime);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.view.textclassifier.TextClassification.Options> CREATOR;
   }
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index 5e75359..cfb9d87 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -245,7 +245,7 @@
  * Logs when the ble scan state changes.
  *
  * Logged from:
- *   frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
+ *   packages/apps/Bluetooth/src/com/android/bluetooth/gatt/AppScanStats.java
  */
 // TODO: Consider changing to tracking per-scanner-id (log from AppScanStats).
 message BleScanStateChanged {
diff --git a/core/java/android/view/textclassifier/TextClassification.java b/core/java/android/view/textclassifier/TextClassification.java
index 630007b..b413d48 100644
--- a/core/java/android/view/textclassifier/TextClassification.java
+++ b/core/java/android/view/textclassifier/TextClassification.java
@@ -43,8 +43,8 @@
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.time.ZonedDateTime;
 import java.util.ArrayList;
-import java.util.Calendar;
 import java.util.Collections;
 import java.util.List;
 import java.util.Locale;
@@ -512,7 +512,7 @@
     public static final class Options implements Parcelable {
 
         private @Nullable LocaleList mDefaultLocales;
-        private @Nullable Calendar mReferenceTime;
+        private @Nullable ZonedDateTime mReferenceTime;
 
         public Options() {}
 
@@ -531,7 +531,7 @@
          *      be interpreted. This should usually be the time when the text was originally
          *      composed. If no reference time is set, now is used.
          */
-        public Options setReferenceTime(Calendar referenceTime) {
+        public Options setReferenceTime(ZonedDateTime referenceTime) {
             mReferenceTime = referenceTime;
             return this;
         }
@@ -550,7 +550,7 @@
          *      interpreted.
          */
         @Nullable
-        public Calendar getReferenceTime() {
+        public ZonedDateTime getReferenceTime() {
             return mReferenceTime;
         }
 
@@ -567,7 +567,7 @@
             }
             dest.writeInt(mReferenceTime != null ? 1 : 0);
             if (mReferenceTime != null) {
-                dest.writeSerializable(mReferenceTime);
+                dest.writeString(mReferenceTime.toString());
             }
         }
 
@@ -589,7 +589,7 @@
                 mDefaultLocales = LocaleList.CREATOR.createFromParcel(in);
             }
             if (in.readInt() > 0) {
-                mReferenceTime = (Calendar) in.readSerializable();
+                mReferenceTime = ZonedDateTime.parse(in.readString());
             }
         }
     }
diff --git a/core/java/android/view/textclassifier/TextClassifierImpl.java b/core/java/android/view/textclassifier/TextClassifierImpl.java
index 5ba470a..8d1ed0e 100644
--- a/core/java/android/view/textclassifier/TextClassifierImpl.java
+++ b/core/java/android/view/textclassifier/TextClassifierImpl.java
@@ -16,6 +16,8 @@
 
 package android.view.textclassifier;
 
+import static java.time.temporal.ChronoUnit.MILLIS;
+
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.WorkerThread;
@@ -45,9 +47,10 @@
 import java.io.IOException;
 import java.io.UnsupportedEncodingException;
 import java.net.URLEncoder;
+import java.time.Instant;
+import java.time.ZonedDateTime;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Calendar;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
@@ -119,7 +122,7 @@
                     && rangeLength <= mSettings.getSuggestSelectionMaxRangeLength()) {
                 final LocaleList locales = (options == null) ? null : options.getDefaultLocales();
                 final String localesString = concatenateLocales(locales);
-                final Calendar refTime = Calendar.getInstance();
+                final ZonedDateTime refTime = ZonedDateTime.now();
                 final boolean darkLaunchAllowed = options != null && options.isDarkLaunchAllowed();
                 final TextClassifierImplNative nativeImpl = getNative(locales);
                 final String string = text.toString();
@@ -143,8 +146,8 @@
                             nativeImpl.classifyText(
                                     string, start, end,
                                     new TextClassifierImplNative.ClassificationOptions(
-                                            refTime.getTimeInMillis(),
-                                            refTime.getTimeZone().getID(),
+                                            refTime.toInstant().toEpochMilli(),
+                                            refTime.getZone().getId(),
                                             localesString));
                     final int size = results.length;
                     for (int i = 0; i < size; i++) {
@@ -183,19 +186,20 @@
                 final String string = text.toString();
                 final LocaleList locales = (options == null) ? null : options.getDefaultLocales();
                 final String localesString = concatenateLocales(locales);
-                final Calendar refTime = (options != null && options.getReferenceTime() != null)
-                        ? options.getReferenceTime() : Calendar.getInstance();
+                final ZonedDateTime refTime =
+                        (options != null && options.getReferenceTime() != null)
+                                ? options.getReferenceTime() : ZonedDateTime.now();
 
                 final TextClassifierImplNative.ClassificationResult[] results =
                         getNative(locales)
                                 .classifyText(string, startIndex, endIndex,
                                         new TextClassifierImplNative.ClassificationOptions(
-                                                refTime.getTimeInMillis(),
-                                                refTime.getTimeZone().getID(),
+                                                refTime.toInstant().toEpochMilli(),
+                                                refTime.getZone().getId(),
                                                 localesString));
                 if (results.length > 0) {
                     return createClassificationResult(
-                            results, string, startIndex, endIndex, refTime);
+                            results, string, startIndex, endIndex, refTime.toInstant());
                 }
             }
         } catch (Throwable t) {
@@ -224,7 +228,7 @@
         try {
             final long startTimeMs = System.currentTimeMillis();
             final LocaleList defaultLocales = options != null ? options.getDefaultLocales() : null;
-            final Calendar refTime = Calendar.getInstance();
+            final ZonedDateTime refTime = ZonedDateTime.now();
             final Collection<String> entitiesToIdentify =
                     options != null && options.getEntityConfig() != null
                             ? options.getEntityConfig().resolveEntityListModifications(
@@ -236,8 +240,8 @@
                     nativeImpl.annotate(
                         textString,
                         new TextClassifierImplNative.AnnotationOptions(
-                                refTime.getTimeInMillis(),
-                                refTime.getTimeZone().getID(),
+                                refTime.toInstant().toEpochMilli(),
+                                refTime.getZone().getId(),
                                 concatenateLocales(defaultLocales)));
             for (TextClassifierImplNative.AnnotatedSpan span : annotations) {
                 final TextClassifierImplNative.ClassificationResult[] results =
@@ -416,7 +420,7 @@
 
     private TextClassification createClassificationResult(
             TextClassifierImplNative.ClassificationResult[] classifications,
-            String text, int start, int end, @Nullable Calendar referenceTime) {
+            String text, int start, int end, @Nullable Instant referenceTime) {
         final String classifiedText = text.substring(start, end);
         final TextClassification.Builder builder = new TextClassification.Builder()
                 .setText(classifiedText);
@@ -646,7 +650,7 @@
         @NonNull
         public static List<LabeledIntent> create(
                 Context context,
-                @Nullable Calendar referenceTime,
+                @Nullable Instant referenceTime,
                 TextClassifierImplNative.ClassificationResult classification,
                 String text) {
             final String type = classification.getCollection().trim().toLowerCase(Locale.ENGLISH);
@@ -663,10 +667,9 @@
                 case TextClassifier.TYPE_DATE:
                 case TextClassifier.TYPE_DATE_TIME:
                     if (classification.getDatetimeResult() != null) {
-                        Calendar eventTime = Calendar.getInstance();
-                        eventTime.setTimeInMillis(
+                        final Instant parsedTime = Instant.ofEpochMilli(
                                 classification.getDatetimeResult().getTimeMsUtc());
-                        return createForDatetime(context, type, referenceTime, eventTime);
+                        return createForDatetime(context, type, referenceTime, parsedTime);
                     } else {
                         return new ArrayList<>();
                     }
@@ -758,18 +761,17 @@
 
         @NonNull
         private static List<LabeledIntent> createForDatetime(
-                Context context, String type, @Nullable Calendar referenceTime,
-                Calendar eventTime) {
+                Context context, String type, @Nullable Instant referenceTime,
+                Instant parsedTime) {
             if (referenceTime == null) {
                 // If no reference time was given, use now.
-                referenceTime = Calendar.getInstance();
+                referenceTime = Instant.now();
             }
             List<LabeledIntent> actions = new ArrayList<>();
-            actions.add(createCalendarViewIntent(context, eventTime));
-            final long millisSinceReference =
-                    eventTime.getTimeInMillis() - referenceTime.getTimeInMillis();
-            if (millisSinceReference > MIN_EVENT_FUTURE_MILLIS) {
-                actions.add(createCalendarCreateEventIntent(context, eventTime, type));
+            actions.add(createCalendarViewIntent(context, parsedTime));
+            final long millisUntilEvent = referenceTime.until(parsedTime, MILLIS);
+            if (millisUntilEvent > MIN_EVENT_FUTURE_MILLIS) {
+                actions.add(createCalendarCreateEventIntent(context, parsedTime, type));
             }
             return actions;
         }
@@ -784,10 +786,10 @@
         }
 
         @NonNull
-        private static LabeledIntent createCalendarViewIntent(Context context, Calendar eventTime) {
+        private static LabeledIntent createCalendarViewIntent(Context context, Instant parsedTime) {
             Uri.Builder builder = CalendarContract.CONTENT_URI.buildUpon();
             builder.appendPath("time");
-            ContentUris.appendId(builder, eventTime.getTimeInMillis());
+            ContentUris.appendId(builder, parsedTime.toEpochMilli());
             return new LabeledIntent(
                     context.getString(com.android.internal.R.string.view_calendar),
                     context.getString(com.android.internal.R.string.view_calendar_desc),
@@ -796,7 +798,7 @@
 
         @NonNull
         private static LabeledIntent createCalendarCreateEventIntent(
-                Context context, Calendar eventTime, @EntityType String type) {
+                Context context, Instant parsedTime, @EntityType String type) {
             final boolean isAllDay = TextClassifier.TYPE_DATE.equals(type);
             return new LabeledIntent(
                     context.getString(com.android.internal.R.string.add_calendar_event),
@@ -805,9 +807,9 @@
                             .setData(CalendarContract.Events.CONTENT_URI)
                             .putExtra(CalendarContract.EXTRA_EVENT_ALL_DAY, isAllDay)
                             .putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME,
-                                    eventTime.getTimeInMillis())
+                                    parsedTime.toEpochMilli())
                             .putExtra(CalendarContract.EXTRA_EVENT_END_TIME,
-                                    eventTime.getTimeInMillis() + DEFAULT_EVENT_DURATION));
+                                    parsedTime.toEpochMilli() + DEFAULT_EVENT_DURATION));
         }
     }
 }
diff --git a/core/java/com/android/internal/widget/LockPatternView.java b/core/java/com/android/internal/widget/LockPatternView.java
index 957c784..51dd929 100644
--- a/core/java/com/android/internal/widget/LockPatternView.java
+++ b/core/java/com/android/internal/widget/LockPatternView.java
@@ -1008,9 +1008,6 @@
                 mDrawingProfilingStarted = false;
             }
         }
-        if (mFadePattern) {
-            clearPattern();
-        }
     }
 
     private void cancelLineAnimations() {
diff --git a/core/jni/android/graphics/ImageDecoder.cpp b/core/jni/android/graphics/ImageDecoder.cpp
index 726c450..825b7a0 100644
--- a/core/jni/android/graphics/ImageDecoder.cpp
+++ b/core/jni/android/graphics/ImageDecoder.cpp
@@ -210,7 +210,7 @@
                                           jint desiredWidth, jint desiredHeight, jobject jsubset,
                                           jboolean requireMutable, jint allocator,
                                           jboolean requireUnpremul, jboolean preferRamOverQuality,
-                                          jboolean asAlphaMask) {
+                                          jboolean asAlphaMask, jobject jcolorSpace) {
     auto* decoder = reinterpret_cast<ImageDecoder*>(nativePtr);
     SkAndroidCodec* codec = decoder->mCodec.get();
     const SkISize desiredSize = SkISize::Make(desiredWidth, desiredHeight);
@@ -264,7 +264,8 @@
         // This is currently the only way to know that we should decode to F16.
         colorType = codec->computeOutputColorType(colorType);
     }
-    sk_sp<SkColorSpace> colorSpace = codec->computeOutputColorSpace(colorType);
+    sk_sp<SkColorSpace> colorSpace = GraphicsJNI::getNativeColorSpace(env, jcolorSpace);
+    colorSpace = codec->computeOutputColorSpace(colorType, colorSpace);
     decodeInfo = decodeInfo.makeColorType(colorType).makeColorSpace(colorSpace);
 
     SkBitmap bm;
@@ -507,18 +508,26 @@
     return encodedFormatToString(env, decoder->mCodec->getEncodedFormat());
 }
 
+static jobject ImageDecoder_nGetColorSpace(JNIEnv* env, jobject /*clazz*/, jlong nativePtr) {
+    auto* codec = reinterpret_cast<ImageDecoder*>(nativePtr)->mCodec.get();
+    auto colorType = codec->computeOutputColorType(codec->getInfo().colorType());
+    sk_sp<SkColorSpace> colorSpace = codec->computeOutputColorSpace(colorType);
+    return GraphicsJNI::getColorSpace(env, colorSpace, colorType);
+}
+
 static const JNINativeMethod gImageDecoderMethods[] = {
     { "nCreate",        "(JLandroid/graphics/ImageDecoder$Source;)Landroid/graphics/ImageDecoder;",    (void*) ImageDecoder_nCreateAsset },
     { "nCreate",        "(Ljava/nio/ByteBuffer;IILandroid/graphics/ImageDecoder$Source;)Landroid/graphics/ImageDecoder;", (void*) ImageDecoder_nCreateByteBuffer },
     { "nCreate",        "([BIILandroid/graphics/ImageDecoder$Source;)Landroid/graphics/ImageDecoder;", (void*) ImageDecoder_nCreateByteArray },
     { "nCreate",        "(Ljava/io/InputStream;[BLandroid/graphics/ImageDecoder$Source;)Landroid/graphics/ImageDecoder;", (void*) ImageDecoder_nCreateInputStream },
     { "nCreate",        "(Ljava/io/FileDescriptor;Landroid/graphics/ImageDecoder$Source;)Landroid/graphics/ImageDecoder;", (void*) ImageDecoder_nCreateFd },
-    { "nDecodeBitmap",  "(JLandroid/graphics/ImageDecoder;ZIILandroid/graphics/Rect;ZIZZZ)Landroid/graphics/Bitmap;",
+    { "nDecodeBitmap",  "(JLandroid/graphics/ImageDecoder;ZIILandroid/graphics/Rect;ZIZZZLandroid/graphics/ColorSpace;)Landroid/graphics/Bitmap;",
                                                                  (void*) ImageDecoder_nDecodeBitmap },
     { "nGetSampledSize","(JI)Landroid/util/Size;",               (void*) ImageDecoder_nGetSampledSize },
     { "nGetPadding",    "(JLandroid/graphics/Rect;)V",           (void*) ImageDecoder_nGetPadding },
     { "nClose",         "(J)V",                                  (void*) ImageDecoder_nClose},
     { "nGetMimeType",   "(J)Ljava/lang/String;",                 (void*) ImageDecoder_nGetMimeType },
+    { "nGetColorSpace", "(J)Landroid/graphics/ColorSpace;",      (void*) ImageDecoder_nGetColorSpace },
 };
 
 int register_android_graphics_ImageDecoder(JNIEnv* env) {
diff --git a/core/tests/coretests/src/android/view/textclassifier/TextClassificationTest.java b/core/tests/coretests/src/android/view/textclassifier/TextClassificationTest.java
index afc4bd5..5d58f55 100644
--- a/core/tests/coretests/src/android/view/textclassifier/TextClassificationTest.java
+++ b/core/tests/coretests/src/android/view/textclassifier/TextClassificationTest.java
@@ -37,9 +37,10 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import java.util.Calendar;
+import java.time.Instant;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
 import java.util.Locale;
-import java.util.TimeZone;
 
 @SmallTest
 @RunWith(AndroidJUnit4.class)
@@ -163,8 +164,9 @@
 
     @Test
     public void testParcelOptions() {
-        Calendar referenceTime = Calendar.getInstance(TimeZone.getTimeZone("UTC"), Locale.US);
-        referenceTime.setTimeInMillis(946771200000L);  // 2000-01-02
+        ZonedDateTime referenceTime = ZonedDateTime.ofInstant(
+                Instant.ofEpochMilli(946771200000L),  // 2000-01-02
+                ZoneId.of("UTC"));
 
         TextClassification.Options reference = new TextClassification.Options();
         reference.setDefaultLocales(new LocaleList(Locale.US, Locale.GERMANY));
diff --git a/graphics/java/android/graphics/ImageDecoder.java b/graphics/java/android/graphics/ImageDecoder.java
index 6939907..6051f88 100644
--- a/graphics/java/android/graphics/ImageDecoder.java
+++ b/graphics/java/android/graphics/ImageDecoder.java
@@ -432,6 +432,18 @@
         public boolean isAnimated() {
             return mDecoder.mAnimated;
         }
+
+        /**
+         * If known, the color space the decoded bitmap will have. Note that the
+         * output color space is not guaranteed to be the color space the bitmap
+         * is encoded with. If not known (when the config is
+         * {@link Bitmap.Config#ALPHA_8} for instance), or there is an error,
+         * it is set to null.
+         */
+        @Nullable
+        public ColorSpace getColorSpace() {
+            return mDecoder.getColorSpace();
+        }
     };
 
     /** @removed
@@ -582,16 +594,17 @@
     private final int     mHeight;
     private final boolean mAnimated;
 
-    private int     mDesiredWidth;
-    private int     mDesiredHeight;
-    private int     mAllocator = ALLOCATOR_DEFAULT;
-    private boolean mRequireUnpremultiplied = false;
-    private boolean mMutable = false;
-    private boolean mConserveMemory = false;
-    private boolean mDecodeAsAlphaMask = false;
-    private Rect    mCropRect;
-    private Rect    mOutPaddingRect;
-    private Source  mSource;
+    private int        mDesiredWidth;
+    private int        mDesiredHeight;
+    private int        mAllocator = ALLOCATOR_DEFAULT;
+    private boolean    mRequireUnpremultiplied = false;
+    private boolean    mMutable = false;
+    private boolean    mConserveMemory = false;
+    private boolean    mDecodeAsAlphaMask = false;
+    private ColorSpace mDesiredColorSpace = null;
+    private Rect       mCropRect;
+    private Rect       mOutPaddingRect;
+    private Source     mSource;
 
     private PostProcessor          mPostProcessor;
     private OnPartialImageListener mOnPartialImageListener;
@@ -806,7 +819,8 @@
      *  image, which can be retrieved from the {@link ImageInfo} in
      *  {@link OnHeaderDecodedListener#onHeaderDecoded}.</p>
      *
-     *  <p>Only the last call to this or {@link #setSampleSize} is respected.</p>
+     *  <p>Only the last call to this or {@link #setTargetSampleSize} is
+     *  respected.</p>
      *
      *  @param width must be greater than 0.
      *  @param height must be greater than 0.
@@ -824,11 +838,11 @@
     }
 
     /** @removed
-     * @deprecated Renamed to {@link #setSampleSize}.
+     * @deprecated Renamed to {@link #setTargetSampleSize}.
      */
     @java.lang.Deprecated
     public ImageDecoder setResize(int sampleSize) {
-        return this.setSampleSize(sampleSize);
+        return this.setTargetSampleSize(sampleSize);
     }
 
     private int getTargetDimension(int original, int sampleSize, int computed) {
@@ -877,7 +891,7 @@
      *  @param sampleSize Sampling rate of the encoded image.
      *  @return this object for chaining.
      */
-    public ImageDecoder setSampleSize(int sampleSize) {
+    public ImageDecoder setTargetSampleSize(int sampleSize) {
         Size size = this.getSampledSize(sampleSize);
         int targetWidth = getTargetDimension(mWidth, sampleSize, size.getWidth());
         int targetHeight = getTargetDimension(mHeight, sampleSize, size.getHeight());
@@ -1179,6 +1193,37 @@
         return this.getDecodeAsAlphaMask();
     }
 
+    /**
+     * Specify the desired {@link ColorSpace} for the output.
+     *
+     * <p>If non-null, the decoder will try to decode into this
+     * color space. If it is null, which is the default, or the request cannot
+     * be met, the decoder will pick either the color space embedded in the
+     * image or the color space best suited for the requested image
+     * configuration (for instance {@link ColorSpace.Named#SRGB sRGB} for
+     * the {@link Bitmap.Config#ARGB_8888} configuration).</p>
+     *
+     * <p>{@link Bitmap.Config#RGBA_F16} always uses the
+     * {@link ColorSpace.Named#LINEAR_EXTENDED_SRGB scRGB} color space).
+     * Bitmaps in other configurations without an embedded color space are
+     * assumed to be in the {@link ColorSpace.Named#SRGB sRGB} color space.</p>
+     *
+     * <p class="note">Only {@link ColorSpace.Model#RGB} color spaces are
+     * currently supported. An <code>IllegalArgumentException</code> will
+     * be thrown by the decode methods when setting a non-RGB color space
+     * such as {@link ColorSpace.Named#CIE_LAB Lab}.</p>
+     *
+     * <p class="note">The specified color space's transfer function must be
+     * an {@link ColorSpace.Rgb.TransferParameters ICC parametric curve}. An
+     * <code>IllegalArgumentException</code> will be thrown by the decode methods
+     * if calling {@link ColorSpace.Rgb#getTransferParameters()} on the
+     * specified color space returns null.</p>
+     */
+    public ImageDecoder setTargetColorSpace(ColorSpace colorSpace) {
+        mDesiredColorSpace = colorSpace;
+        return this;
+    }
+
     @Override
     public void close() {
         mCloseGuard.close();
@@ -1217,6 +1262,17 @@
         if (mPostProcessor != null && mRequireUnpremultiplied) {
             throw new IllegalStateException("Cannot draw to unpremultiplied pixels!");
         }
+
+        if (mDesiredColorSpace != null) {
+            if (!(mDesiredColorSpace instanceof ColorSpace.Rgb)) {
+                throw new IllegalArgumentException("The target color space must use the "
+                            + "RGB color model - provided: " + mDesiredColorSpace);
+            }
+            if (((ColorSpace.Rgb) mDesiredColorSpace).getTransferParameters() == null) {
+                throw new IllegalArgumentException("The target color space must use an "
+                            + "ICC parametric transfer function - provided: " + mDesiredColorSpace);
+            }
+        }
     }
 
     private static void checkSubset(int width, int height, Rect r) {
@@ -1235,7 +1291,7 @@
         return nDecodeBitmap(mNativePtr, this, mPostProcessor != null,
                 mDesiredWidth, mDesiredHeight, mCropRect,
                 mMutable, mAllocator, mRequireUnpremultiplied,
-                mConserveMemory, mDecodeAsAlphaMask);
+                mConserveMemory, mDecodeAsAlphaMask, mDesiredColorSpace);
     }
 
     private void callHeaderDecoded(@Nullable OnHeaderDecodedListener listener,
@@ -1425,6 +1481,11 @@
         return nGetMimeType(mNativePtr);
     }
 
+    @Nullable
+    private ColorSpace getColorSpace() {
+        return nGetColorSpace(mNativePtr);
+    }
+
     /**
      *  See {@link #decodeBitmap(Source, OnHeaderDecodedListener)}.
      */
@@ -1474,11 +1535,13 @@
             int width, int height,
             @Nullable Rect cropRect, boolean mutable,
             int allocator, boolean requireUnpremul,
-            boolean conserveMemory, boolean decodeAsAlphaMask)
+            boolean conserveMemory, boolean decodeAsAlphaMask,
+            @Nullable ColorSpace desiredColorSpace)
         throws IOException;
     private static native Size nGetSampledSize(long nativePtr,
                                                int sampleSize);
     private static native void nGetPadding(long nativePtr, @NonNull Rect outRect);
     private static native void nClose(long nativePtr);
     private static native String nGetMimeType(long nativePtr);
+    private static native ColorSpace nGetColorSpace(long nativePtr);
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java
index 4cd23f9..9347674 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java
@@ -50,7 +50,9 @@
                 }
             };
     private final NetworkRequest mNetworkRequest = new NetworkRequest.Builder()
-            .clearCapabilities().addTransportType(NetworkCapabilities.TRANSPORT_WIFI).build();
+            .clearCapabilities()
+            .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
+            .addTransportType(NetworkCapabilities.TRANSPORT_WIFI).build();
     private final ConnectivityManager.NetworkCallback mNetworkCallback = new ConnectivityManager
             .NetworkCallback() {
         @Override
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
index 8f80527..a128b54 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
@@ -213,6 +213,7 @@
 
         mNetworkRequest = new NetworkRequest.Builder()
                 .clearCapabilities()
+                .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
                 .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
                 .build();
 
diff --git a/packages/SystemUI/src/com/android/systemui/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/OverviewProxyService.java
index 816c598..8cff56d 100644
--- a/packages/SystemUI/src/com/android/systemui/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/OverviewProxyService.java
@@ -228,9 +228,14 @@
         mHandler.removeCallbacks(mConnectionRunnable);
         Intent launcherServiceIntent = new Intent(ACTION_QUICKSTEP)
                 .setPackage(mRecentsComponentName.getPackageName());
-        boolean bound = mContext.bindServiceAsUser(launcherServiceIntent,
-                mOverviewServiceConnection, Context.BIND_AUTO_CREATE,
-                UserHandle.of(mDeviceProvisionedController.getCurrentUser()));
+        boolean bound = false;
+        try {
+            bound = mContext.bindServiceAsUser(launcherServiceIntent,
+                    mOverviewServiceConnection, Context.BIND_AUTO_CREATE,
+                    UserHandle.of(mDeviceProvisionedController.getCurrentUser()));
+        } catch (SecurityException e) {
+            Log.e(TAG_OPS, "Unable to bind because of security error", e);
+        }
         if (!bound) {
             // Retry after exponential backoff timeout
             final long timeoutMs = (long) Math.scalb(BACKOFF_MILLIS, mConnectionBackoffAttempts);
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 fcd4e8f..df2b817 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
@@ -334,6 +334,20 @@
         return mKeyguardView != null && mKeyguardView.hasDismissActions();
     }
 
+    public int getTop() {
+        if (mKeyguardView == null) {
+            return 0;
+        }
+
+        int top = mKeyguardView.getTop();
+        // The password view has an extra top padding that should be ignored.
+        if (mKeyguardView.getCurrentSecurityMode() == SecurityMode.Password) {
+            View messageArea = mKeyguardView.findViewById(R.id.keyguard_message_area);
+            top += messageArea.getTop();
+        }
+        return top;
+    }
+
     protected void ensureView() {
         // Removal of the view might be deferred to reduce unlock latency,
         // in this case we need to force the removal, otherwise we'll
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
index 19e8295..3d7067d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
@@ -114,6 +114,11 @@
     private boolean mTracking;
 
     /**
+     * Distance in pixels between the top of the screen and the first view of the bouncer.
+     */
+    private int mBouncerTop;
+
+    /**
      * Refreshes the dimension values.
      */
     public void loadDimens(Resources res) {
@@ -129,7 +134,7 @@
 
     public void setup(int minTopMargin, int maxShadeBottom, int notificationStackHeight,
             float expandedHeight, float maxPanelHeight, int parentHeight, int keyguardStatusHeight,
-            float dark, boolean secure, boolean tracking) {
+            float dark, boolean secure, boolean tracking, int bouncerTop) {
         mMinTopMargin = minTopMargin + mContainerTopPadding;
         mMaxShadeBottom = maxShadeBottom;
         mNotificationStackHeight = notificationStackHeight;
@@ -140,6 +145,7 @@
         mDarkAmount = dark;
         mCurrentlySecure = secure;
         mTracking = tracking;
+        mBouncerTop = bouncerTop;
     }
 
     public void run(Result result) {
@@ -189,8 +195,10 @@
     private int getClockY() {
         // Dark: Align the bottom edge of the clock at about half of the screen:
         final float clockYDark = getMaxClockY() + burnInPreventionOffsetY();
-        float clockYRegular = getExpandedClockPosition();
-        float clockYTarget = mCurrentlySecure ? mMinTopMargin : -mKeyguardStatusHeight;
+        final float clockYRegular = getExpandedClockPosition();
+        final boolean hasEnoughSpace = mMinTopMargin + mKeyguardStatusHeight < mBouncerTop;
+        float clockYTarget = mCurrentlySecure && hasEnoughSpace ?
+                mMinTopMargin : -mKeyguardStatusHeight;
 
         // Move clock up while collapsing the shade
         float shadeExpansion = mExpandedHeight / mMaxPanelHeight;
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 cccda90..27ca0d1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -160,6 +160,7 @@
     protected int mQsMinExpansionHeight;
     protected int mQsMaxExpansionHeight;
     private int mQsPeekHeight;
+    private int mBouncerTop;
     private boolean mStackScrollerOverscrolling;
     private boolean mQsExpansionFromOverscroll;
     private float mLastOverscroll;
@@ -476,7 +477,8 @@
                     mKeyguardStatusView.getHeight(),
                     mDarkAmount,
                     mStatusBar.isKeyguardCurrentlySecure(),
-                    mTracking);
+                    mTracking,
+                    mBouncerTop);
             mClockPositionAlgorithm.run(mClockPositionResult);
             if (animate || mClockAnimator != null) {
                 startClockAnimation(mClockPositionResult.clockX, mClockPositionResult.clockY);
@@ -550,6 +552,11 @@
         return count;
     }
 
+    public void setBouncerTop(int bouncerTop) {
+        mBouncerTop = bouncerTop;
+        positionClockAndNotifications();
+    }
+
     private void startClockAnimation(int x, int y) {
         if (mClockAnimationTargetX == x && mClockAnimationTargetY == y) {
             return;
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 4e782de..6b6ea10 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -135,10 +135,16 @@
         mFingerprintUnlockController = fingerprintUnlockController;
         mBouncer = SystemUIFactory.getInstance().createKeyguardBouncer(mContext,
                 mViewMediatorCallback, mLockPatternUtils, container, dismissCallbackRegistry);
+        mContainer.addOnLayoutChangeListener(this::onContainerLayout);
         mNotificationPanelView = notificationPanelView;
         notificationPanelView.setExpansionListener(this::onPanelExpansionChanged);
     }
 
+    private void onContainerLayout(View v, int left, int top, int right, int bottom,
+            int oldLeft, int oldTop, int oldRight, int oldBottom) {
+        mNotificationPanelView.setBouncerTop(mBouncer.getTop());
+    }
+
     private void onPanelExpansionChanged(float expansion, boolean tracking) {
         // We don't want to translate the bounce when:
         // • Keyguard is occluded, because we're in a FLAG_SHOW_WHEN_LOCKED activity and need to
@@ -156,7 +162,7 @@
             if (expansion == 1) {
                 mBouncer.onFullyHidden();
             } else if (!mBouncer.isShowing() && !mBouncer.isAnimatingAway()) {
-                mBouncer.show(false /* resetSecuritySelection */, false /* notifyFalsing */);
+                mBouncer.show(false /* resetSecuritySelection */, false /* animated */);
             } else if (noLongerTracking) {
                 // Notify that falsing manager should stop its session when user stops touching,
                 // even before the animation ends, to guarantee that we're not recording sensitive
diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java
index 3374b30..c445f73 100644
--- a/services/core/java/com/android/server/location/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/GnssLocationProvider.java
@@ -2576,9 +2576,9 @@
             // register for connectivity change events, this is equivalent to the deprecated way of
             // registering for CONNECTIVITY_ACTION broadcasts
             NetworkRequest.Builder networkRequestBuilder = new NetworkRequest.Builder();
-            networkRequestBuilder.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
-            networkRequestBuilder.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
-            networkRequestBuilder.addTransportType(NetworkCapabilities.TRANSPORT_BLUETOOTH);
+            networkRequestBuilder.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
+            networkRequestBuilder.addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
+            networkRequestBuilder.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN);
             NetworkRequest networkRequest = networkRequestBuilder.build();
             mConnMgr.registerNetworkCallback(networkRequest, mNetworkConnectivityCallback);
 
diff --git a/services/core/java/com/android/server/pm/PackageDexOptimizer.java b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
index 61c6be7..9807342 100644
--- a/services/core/java/com/android/server/pm/PackageDexOptimizer.java
+++ b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
@@ -449,13 +449,15 @@
             pw.increaseIndent();
 
             for (String isa : dexCodeInstructionSets) {
-                String status = null;
                 try {
-                    status = DexFile.getDexFileStatus(path, isa);
+                    String[] status = DexFile.getDexFileOptimizationStatus(path, isa);
+                    String compilationStatus = status[0];
+                    String compilationReason = status[1];
+                    pw.println(isa + ": [status=" + compilationStatus
+                            +"] reason=[" + compilationReason + "]");
                 } catch (IOException ioe) {
-                     status = "[Exception]: " + ioe.getMessage();
+                    pw.println(isa + ": [Exception]: " + ioe.getMessage());
                 }
-                pw.println(isa + ": " + status);
             }
 
             if (useInfo.isUsedByOtherApps(path)) {
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index e08ec556..b0b313b 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -808,7 +808,7 @@
         }
 
         final String[] getStaticOverlayPaths(List<PackageParser.Package> overlayPackages,
-                String targetPath, Object installLock) {
+                String targetPath) {
             if (overlayPackages == null || overlayPackages.isEmpty()) {
                 return null;
             }
@@ -828,20 +828,9 @@
                     //
                     // OverlayManagerService will update each of them with a correct gid from its
                     // target package app id.
-                    if (installLock != null) {
-                        synchronized (installLock) {
-                            mInstaller.idmap(targetPath, overlayPackage.baseCodePath,
-                                    UserHandle.getSharedAppGid(
-                                            UserHandle.getUserGid(UserHandle.USER_SYSTEM)));
-                        }
-                    } else {
-                        // We can call mInstaller without holding mInstallLock because mInstallLock
-                        // is held before running parallel parsing.
-                        // Moreover holding mInstallLock on each parsing thread causes dead-lock.
-                        mInstaller.idmap(targetPath, overlayPackage.baseCodePath,
-                                UserHandle.getSharedAppGid(
-                                        UserHandle.getUserGid(UserHandle.USER_SYSTEM)));
-                    }
+                    mInstaller.idmap(targetPath, overlayPackage.baseCodePath,
+                            UserHandle.getSharedAppGid(
+                                    UserHandle.getUserGid(UserHandle.USER_SYSTEM)));
                     if (overlayPathList == null) {
                         overlayPathList = new ArrayList<String>();
                     }
@@ -856,13 +845,15 @@
 
         String[] getStaticOverlayPaths(String targetPackageName, String targetPath) {
             List<PackageParser.Package> overlayPackages;
-            synchronized (mPackages) {
-                overlayPackages = getStaticOverlayPackages(
-                        mPackages.values(), targetPackageName);
+            synchronized (mInstallLock) {
+                synchronized (mPackages) {
+                    overlayPackages = getStaticOverlayPackages(
+                            mPackages.values(), targetPackageName);
+                }
+                // It is safe to keep overlayPackages without holding mPackages because static overlay
+                // packages can't be uninstalled or disabled.
+                return getStaticOverlayPaths(overlayPackages, targetPath);
             }
-            // It is safe to keep overlayPackages without holding mPackages because static overlay
-            // packages can't be uninstalled or disabled.
-            return getStaticOverlayPaths(overlayPackages, targetPath, mInstallLock);
         }
 
         @Override public final String[] getOverlayApks(String targetPackageName) {
@@ -895,11 +886,13 @@
         synchronized String[] getStaticOverlayPaths(String targetPackageName, String targetPath) {
             // We can trust mOverlayPackages without holding mPackages because package uninstall
             // can't happen while running parallel parsing.
-            // Moreover holding mPackages on each parsing thread causes dead-lock.
+            // And we can call mInstaller inside getStaticOverlayPaths without holding mInstallLock
+            // because mInstallLock is held before running parallel parsing.
+            // Moreover holding mPackages or mInstallLock on each parsing thread causes dead-lock.
             return mOverlayPackages == null ? null :
                     getStaticOverlayPaths(
                             getStaticOverlayPackages(mOverlayPackages, targetPackageName),
-                            targetPath, null);
+                            targetPath);
         }
     }
 
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index c8df087..433285b 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -1317,6 +1317,7 @@
         if (pin) {
             NetworkRequest request = new NetworkRequest.Builder()
                     .clearCapabilities()
+                    .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
                     .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
                     .build();
             NetworkPinner.pin(mContext, request);