Merge "Improve the performance when loading image wallpaper colors"
diff --git a/Android.bp b/Android.bp
index 1ee7405..6288940 100644
--- a/Android.bp
+++ b/Android.bp
@@ -69,7 +69,6 @@
         "core/java/android/app/ITaskStackListener.aidl",
         "core/java/android/app/IBackupAgent.aidl",
         "core/java/android/app/IEphemeralResolver.aidl",
-        "core/java/android/app/IInputForwarder.aidl",
         "core/java/android/app/IInstantAppResolver.aidl",
         "core/java/android/app/IInstrumentationWatcher.aidl",
         "core/java/android/app/INotificationManager.aidl",
diff --git a/api/TEST_MAPPING b/api/TEST_MAPPING
index 8a676e9..2cdf54b 100644
--- a/api/TEST_MAPPING
+++ b/api/TEST_MAPPING
@@ -2,6 +2,9 @@
   "presubmit": [
     {
       "name": "CtsCurrentApiSignatureTestCases"
+    },
+    {
+      "name": "GtsUnofficialApisUsageTestCases"
     }
   ]
 }
diff --git a/api/current.txt b/api/current.txt
index 1c60efa..7f1e7f5 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -38609,13 +38609,13 @@
 
   public static final class MediaStore.Images.Media implements android.provider.MediaStore.Images.ImageColumns {
     ctor public MediaStore.Images.Media();
-    method public static android.graphics.Bitmap getBitmap(android.content.ContentResolver, android.net.Uri) throws java.io.FileNotFoundException, java.io.IOException;
+    method @Deprecated public static android.graphics.Bitmap getBitmap(android.content.ContentResolver, android.net.Uri) throws java.io.FileNotFoundException, java.io.IOException;
     method public static android.net.Uri getContentUri(String);
-    method public static String insertImage(android.content.ContentResolver, String, String, String) throws java.io.FileNotFoundException;
-    method public static String insertImage(android.content.ContentResolver, android.graphics.Bitmap, String, String);
-    method public static android.database.Cursor query(android.content.ContentResolver, android.net.Uri, String[]);
-    method public static android.database.Cursor query(android.content.ContentResolver, android.net.Uri, String[], String, String);
-    method public static android.database.Cursor query(android.content.ContentResolver, android.net.Uri, String[], String, String[], String);
+    method @Deprecated public static String insertImage(android.content.ContentResolver, String, String, String) throws java.io.FileNotFoundException;
+    method @Deprecated public static String insertImage(android.content.ContentResolver, android.graphics.Bitmap, String, String);
+    method @Deprecated public static android.database.Cursor query(android.content.ContentResolver, android.net.Uri, String[]);
+    method @Deprecated public static android.database.Cursor query(android.content.ContentResolver, android.net.Uri, String[], String, String);
+    method @Deprecated public static android.database.Cursor query(android.content.ContentResolver, android.net.Uri, String[], String, String[], String);
     field public static final String CONTENT_TYPE = "vnd.android.cursor.dir/image";
     field public static final String DEFAULT_SORT_ORDER = "bucket_display_name";
     field public static final android.net.Uri EXTERNAL_CONTENT_URI;
@@ -38684,7 +38684,7 @@
 
   public static final class MediaStore.Video {
     ctor public MediaStore.Video();
-    method public static android.database.Cursor query(android.content.ContentResolver, android.net.Uri, String[]);
+    method @Deprecated public static android.database.Cursor query(android.content.ContentResolver, android.net.Uri, String[]);
     field public static final String DEFAULT_SORT_ORDER = "_display_name";
   }
 
diff --git a/config/hiddenapi-greylist.txt b/config/hiddenapi-greylist.txt
index dc2ed4c..a836e8e 100644
--- a/config/hiddenapi-greylist.txt
+++ b/config/hiddenapi-greylist.txt
@@ -170,7 +170,6 @@
 Landroid/app/IAssistDataReceiver$Stub;-><init>()V
 Landroid/app/IAssistDataReceiver;->onHandleAssistData(Landroid/os/Bundle;)V
 Landroid/app/IAssistDataReceiver;->onHandleAssistScreenshot(Landroid/graphics/Bitmap;)V
-Landroid/app/IInputForwarder;->forwardEvent(Landroid/view/InputEvent;)Z
 Landroid/app/IInstrumentationWatcher$Stub;-><init>()V
 Landroid/app/IInstrumentationWatcher;->instrumentationStatus(Landroid/content/ComponentName;ILandroid/os/Bundle;)V
 Landroid/app/INotificationManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
diff --git a/core/java/android/annotation/CurrentTimeMillisLong.java b/core/java/android/annotation/CurrentTimeMillisLong.java
index 9846cce..355bb5a 100644
--- a/core/java/android/annotation/CurrentTimeMillisLong.java
+++ b/core/java/android/annotation/CurrentTimeMillisLong.java
@@ -25,12 +25,12 @@
 import java.lang.annotation.Target;
 
 /**
- * @memberDoc Value is a non-negative timestamp in the
- *            {@link System#currentTimeMillis()} time base.
- * @paramDoc Value is a non-negative timestamp in the
- *           {@link System#currentTimeMillis()} time base.
- * @returnDoc Value is a non-negative timestamp in the
- *            {@link System#currentTimeMillis()} time base.
+ * @memberDoc Value is a non-negative timestamp measured as the number of
+ *            milliseconds since 1970-01-01T00:00:00Z.
+ * @paramDoc Value is a non-negative timestamp measured as the number of
+ *            milliseconds since 1970-01-01T00:00:00Z.
+ * @returnDoc Value is a non-negative timestamp measured as the number of
+ *            milliseconds since 1970-01-01T00:00:00Z.
  * @hide
  */
 @Retention(SOURCE)
diff --git a/core/java/android/annotation/CurrentTimeSecondsLong.java b/core/java/android/annotation/CurrentTimeSecondsLong.java
new file mode 100644
index 0000000..2b4ffd7
--- /dev/null
+++ b/core/java/android/annotation/CurrentTimeSecondsLong.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2019 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.annotation;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * @memberDoc Value is a non-negative timestamp measured as the number of
+ *            seconds since 1970-01-01T00:00:00Z.
+ * @paramDoc Value is a non-negative timestamp measured as the number of
+ *            seconds since 1970-01-01T00:00:00Z.
+ * @returnDoc Value is a non-negative timestamp measured as the number of
+ *            seconds since 1970-01-01T00:00:00Z.
+ * @hide
+ */
+@Retention(SOURCE)
+@Target({METHOD, PARAMETER, FIELD})
+public @interface CurrentTimeSecondsLong {
+}
diff --git a/core/java/android/annotation/Px.java b/core/java/android/annotation/Px.java
index ad99fdb..cec7f80 100644
--- a/core/java/android/annotation/Px.java
+++ b/core/java/android/annotation/Px.java
@@ -29,6 +29,7 @@
  * Denotes that a numeric parameter, field or method return value is expected
  * to represent a pixel dimension.
  *
+ * @memberDoc This units of this value are pixels.
  * @paramDoc This units of this value are pixels.
  * @returnDoc This units of this value are pixels.
  * {@hide}
diff --git a/core/java/android/app/IInputForwarder.aidl b/core/java/android/app/IInputForwarder.aidl
deleted file mode 100644
index d6be63e..0000000
--- a/core/java/android/app/IInputForwarder.aidl
+++ /dev/null
@@ -1,29 +0,0 @@
-/**
- * Copyright (c) 2017, 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.app;
-
-import android.view.InputEvent;
-
-/**
- * Forwards input events into owned activity container, used in {@link android.app.ActivityView}.
- * To forward input to other apps {@link android.Manifest.permission.INJECT_EVENTS} permission is
- * required.
- * @hide
- */
-interface IInputForwarder {
-    boolean forwardEvent(in InputEvent event);
-}
\ No newline at end of file
diff --git a/core/java/android/hardware/input/IInputManager.aidl b/core/java/android/hardware/input/IInputManager.aidl
index 97868fa..64448fd9 100644
--- a/core/java/android/hardware/input/IInputManager.aidl
+++ b/core/java/android/hardware/input/IInputManager.aidl
@@ -16,7 +16,6 @@
 
 package android.hardware.input;
 
-import android.app.IInputForwarder;
 import android.hardware.input.InputDeviceIdentifier;
 import android.hardware.input.KeyboardLayout;
 import android.hardware.input.IInputDevicesChangedListener;
@@ -82,7 +81,4 @@
     void setCustomPointerIcon(in PointerIcon icon);
 
     void requestPointerCapture(IBinder windowToken, boolean enabled);
-
-    /** Create input forwarder to deliver touch events to owned display. */
-    IInputForwarder createInputForwarder(int displayId);
 }
diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java
index bfb7c58..fec5c34 100644
--- a/core/java/android/hardware/input/InputManager.java
+++ b/core/java/android/hardware/input/InputManager.java
@@ -21,7 +21,6 @@
 import android.annotation.SdkConstant.SdkConstantType;
 import android.annotation.SystemService;
 import android.annotation.UnsupportedAppUsage;
-import android.app.IInputForwarder;
 import android.content.Context;
 import android.media.AudioAttributes;
 import android.os.Binder;
@@ -934,26 +933,6 @@
         }
     }
 
-
-    /**
-     * Create an {@link IInputForwarder} targeted to provided display.
-     * {@link android.Manifest.permission.INJECT_EVENTS} permission is required to call this method.
-     *
-     * @param displayId Id of the target display where input events should be forwarded.
-     *                  Display must exist and must be owned by the caller.
-     * @return The forwarder instance.
-     *
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public IInputForwarder createInputForwarder(int displayId) {
-        try {
-            return mIm.createInputForwarder(displayId);
-        } catch (RemoteException ex) {
-            throw ex.rethrowFromSystemServer();
-        }
-    }
-
     private void populateInputDevicesLocked() {
         if (mInputDevicesChangedListener == null) {
             final InputDevicesChangedListener listener = new InputDevicesChangedListener();
diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java
index 3feccf5..0aed981 100644
--- a/core/java/android/os/Environment.java
+++ b/core/java/android/os/Environment.java
@@ -388,7 +388,7 @@
 
     /** {@hide} */
     public static File getDataStagingDirectory(String volumeUuid) {
-        return new File(getDataDirectory(volumeUuid), "staging");
+        return new File(getDataDirectory(volumeUuid), "pkg_staging");
     }
 
     /** {@hide} */
diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java
index 1b10bef..643307e 100644
--- a/core/java/android/provider/MediaStore.java
+++ b/core/java/android/provider/MediaStore.java
@@ -17,6 +17,8 @@
 package android.provider;
 
 import android.annotation.BytesLong;
+import android.annotation.CurrentTimeMillisLong;
+import android.annotation.CurrentTimeSecondsLong;
 import android.annotation.DurationMillisLong;
 import android.annotation.IntRange;
 import android.annotation.NonNull;
@@ -40,7 +42,9 @@
 import android.database.DatabaseUtils;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
+import android.graphics.ImageDecoder;
 import android.graphics.Point;
+import android.graphics.PostProcessor;
 import android.media.ExifInterface;
 import android.net.Uri;
 import android.os.Bundle;
@@ -78,8 +82,15 @@
 import java.util.regex.Pattern;
 
 /**
- * The Media provider contains meta data for all available media on both internal
- * and external storage devices.
+ * The contract between the media provider and applications. Contains
+ * definitions for the supported URIs and columns.
+ * <p>
+ * The media provider provides an indexed collection of common media types, such
+ * as {@link Audio}, {@link Video}, and {@link Images}, from any attached
+ * storage devices. Each collection is organized based on the primary MIME type
+ * of the underlying content; for example, {@code image/*} content is indexed
+ * under {@link Images}. The {@link Files} collection provides a broad view
+ * across all collections, and does not filter by MIME type.
  */
 public final class MediaStore {
     private final static String TAG = "MediaStore";
@@ -847,11 +858,11 @@
     }
 
     /**
-     * Common fields for most MediaProvider tables
+     * Common media metadata columns.
      */
     public interface MediaColumns extends BaseColumns {
         /**
-         * Path to the file on disk.
+         * Path to the media item on disk.
          * <p>
          * Note that apps may not have filesystem permissions to directly access
          * this path. Instead of trying to open this path directly, apps should
@@ -871,7 +882,7 @@
         public static final String DATA = "_data";
 
         /**
-         * Hash of the file on disk.
+         * Hash of the media item on disk.
          * <p>
          * Contains a 20-byte binary blob which is the SHA-1 hash of the file as
          * persisted on disk. For performance reasons, the hash may not be
@@ -890,35 +901,35 @@
         public static final String HASH = "_hash";
 
         /**
-         * The size of the file in bytes
+         * The size of the media item.
          */
+        @BytesLong
         @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
         public static final String SIZE = "_size";
 
         /**
-         * The display name of the file
+         * The display name of the media item.
          */
         @Column(Cursor.FIELD_TYPE_STRING)
         public static final String DISPLAY_NAME = "_display_name";
 
         /**
-         * The title of the content
+         * The title of the media item.
          */
         @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
         public static final String TITLE = "title";
 
         /**
-         * The time the file was added to the media provider
-         * Units are seconds since 1970.
+         * The time the media item was first added.
          */
+        @CurrentTimeSecondsLong
         @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
         public static final String DATE_ADDED = "date_added";
 
         /**
-         * The time the file was last modified
-         * Units are seconds since 1970.
-         * NOTE: This is for internal use by the media scanner.  Do not modify this field.
+         * The time the media item was last modified.
          */
+        @CurrentTimeSecondsLong
         @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
         public static final String DATE_MODIFIED = "date_modified";
 
@@ -986,23 +997,25 @@
         public static final String IS_TRASHED = "is_trashed";
 
         /**
-         * The time the file should be considered expired. Units are seconds
-         * since 1970. Typically only meaningful in the context of
-         * {@link #IS_PENDING} or {@link #IS_TRASHED}.
+         * The time the media item should be considered expired. Typically only
+         * meaningful in the context of {@link #IS_PENDING} or
+         * {@link #IS_TRASHED}.
+         *
          * @removed
          */
         @Deprecated
+        @CurrentTimeSecondsLong
         @Column(Cursor.FIELD_TYPE_INTEGER)
         public static final String DATE_EXPIRES = "date_expires";
 
         /**
-         * The width of the image/video in pixels.
+         * The width of the media item, in pixels.
          */
         @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
         public static final String WIDTH = "width";
 
         /**
-         * The height of the image/video in pixels.
+         * The height of the media item, in pixels.
          */
         @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
         public static final String HEIGHT = "height";
@@ -1151,8 +1164,7 @@
         }
 
         /**
-         * Fields for master table for all media files.
-         * Table also contains MediaColumns._ID, DATA, SIZE and DATE_MODIFIED.
+         * File metadata columns.
          */
         public interface FileColumns extends MediaColumns {
             /**
@@ -1179,15 +1191,26 @@
             public static final String PARENT = "parent";
 
             /**
-             * The MIME type of the file
-             * <P>Type: TEXT</P>
+             * The MIME type of the media item.
+             * <p>
+             * This is typically defined based on the file extension of the media
+             * item. However, it may be the value of the {@code format} attribute
+             * defined by the <em>Dublin Core Media Initiative</em> standard,
+             * extracted from any XMP metadata contained within this media item.
+             * <p class="note">
+             * Note: the {@code format} attribute may be ignored if the top-level
+             * MIME type disagrees with the file extension. For example, it's
+             * reasonable for an {@code image/jpeg} file to declare a {@code format}
+             * of {@code image/vnd.google.panorama360+jpg}, but declaring a
+             * {@code format} of {@code audio/ogg} would be ignored.
+             * <p>
+             * This is a read-only column that is automatically computed.
              */
             @Column(Cursor.FIELD_TYPE_STRING)
             public static final String MIME_TYPE = "mime_type";
 
             /**
-             * The title of the content
-             * <P>Type: TEXT</P>
+             * The title of the media item.
              */
             @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
             public static final String TITLE = "title";
@@ -1245,10 +1268,12 @@
         public static final Point MICRO_SIZE = new Point(96, 96);
     }
 
-    /** Column fields for downloaded files used in {@link Downloads} table */
+    /**
+     * Download metadata columns.
+     */
     public interface DownloadColumns extends MediaColumns {
         /**
-         * Uri indicating where the file has been downloaded from.
+         * Uri indicating where the item has been downloaded from.
          */
         @Column(Cursor.FIELD_TYPE_STRING)
         String DOWNLOAD_URI = "download_uri";
@@ -1422,9 +1447,12 @@
     }
 
     /**
-     * Contains meta data for all available images.
+     * Collection of all media with MIME type of {@code image/*}.
      */
     public static final class Images {
+        /**
+         * Image metadata columns.
+         */
         public interface ImageColumns extends MediaColumns {
             /**
              * The description of the image
@@ -1473,9 +1501,9 @@
             public static final String LONGITUDE = "longitude";
 
             /**
-             * The date & time that the image was taken in units
-             * of milliseconds since jan 1, 1970.
+             * The time the media item was taken.
              */
+            @CurrentTimeMillisLong
             @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
             public static final String DATE_TAKEN = "datetaken";
 
@@ -1531,16 +1559,34 @@
         }
 
         public static final class Media implements ImageColumns {
+            /**
+             * @deprecated all queries should be performed through
+             *             {@link ContentResolver} directly, which offers modern
+             *             features like {@link CancellationSignal}.
+             */
+            @Deprecated
             public static final Cursor query(ContentResolver cr, Uri uri, String[] projection) {
                 return cr.query(uri, projection, null, null, DEFAULT_SORT_ORDER);
             }
 
+            /**
+             * @deprecated all queries should be performed through
+             *             {@link ContentResolver} directly, which offers modern
+             *             features like {@link CancellationSignal}.
+             */
+            @Deprecated
             public static final Cursor query(ContentResolver cr, Uri uri, String[] projection,
                     String where, String orderBy) {
                 return cr.query(uri, projection, where,
                                              null, orderBy == null ? DEFAULT_SORT_ORDER : orderBy);
             }
 
+            /**
+             * @deprecated all queries should be performed through
+             *             {@link ContentResolver} directly, which offers modern
+             *             features like {@link CancellationSignal}.
+             */
+            @Deprecated
             public static final Cursor query(ContentResolver cr, Uri uri, String[] projection,
                     String selection, String [] selectionArgs, String orderBy) {
                 return cr.query(uri, projection, selection,
@@ -1552,9 +1598,12 @@
              *
              * @param cr The content resolver to use
              * @param url The url of the image
-             * @throws FileNotFoundException
-             * @throws IOException
+             * @deprecated loading of images should be performed through
+             *             {@link ImageDecoder#createSource(ContentResolver, Uri)},
+             *             which offers modern features like
+             *             {@link PostProcessor}.
              */
+            @Deprecated
             public static final Bitmap getBitmap(ContentResolver cr, Uri url)
                     throws FileNotFoundException, IOException {
                 InputStream input = cr.openInputStream(url);
@@ -1571,8 +1620,11 @@
              * @param name The name of the image
              * @param description The description of the image
              * @return The URL to the newly created image
-             * @throws FileNotFoundException
+             * @deprecated inserting of images should be performed through
+             *             {@link MediaStore#createPending(Context, PendingParams)},
+             *             which offers richer control over lifecycle.
              */
+            @Deprecated
             public static final String insertImage(ContentResolver cr, String imagePath,
                     String name, String description) throws FileNotFoundException {
                 // Check if file exists with a FileInputStream
@@ -1599,7 +1651,11 @@
              * @param description The description of the image
              * @return The URL to the newly created image, or <code>null</code> if the image failed to be stored
              *              for any reason.
+             * @deprecated inserting of images should be performed through
+             *             {@link MediaStore#createPending(Context, PendingParams)},
+             *             which offers richer control over lifecycle.
              */
+            @Deprecated
             public static final String insertImage(ContentResolver cr, Bitmap source,
                                                    String title, String description) {
                 ContentValues values = new ContentValues();
@@ -1694,15 +1750,33 @@
          */
         @Deprecated
         public static class Thumbnails implements BaseColumns {
+            /**
+             * @deprecated all queries should be performed through
+             *             {@link ContentResolver} directly, which offers modern
+             *             features like {@link CancellationSignal}.
+             */
+            @Deprecated
             public static final Cursor query(ContentResolver cr, Uri uri, String[] projection) {
                 return cr.query(uri, projection, null, null, DEFAULT_SORT_ORDER);
             }
 
+            /**
+             * @deprecated all queries should be performed through
+             *             {@link ContentResolver} directly, which offers modern
+             *             features like {@link CancellationSignal}.
+             */
+            @Deprecated
             public static final Cursor queryMiniThumbnails(ContentResolver cr, Uri uri, int kind,
                     String[] projection) {
                 return cr.query(uri, projection, "kind = " + kind, null, DEFAULT_SORT_ORDER);
             }
 
+            /**
+             * @deprecated all queries should be performed through
+             *             {@link ContentResolver} directly, which offers modern
+             *             features like {@link CancellationSignal}.
+             */
+            @Deprecated
             public static final Cursor queryMiniThumbnail(ContentResolver cr, long origId, int kind,
                     String[] projection) {
                 return cr.query(EXTERNAL_CONTENT_URI, projection,
@@ -1885,11 +1959,11 @@
     }
 
     /**
-     * Container for all audio content.
+     * Collection of all media with MIME type of {@code audio/*}.
      */
     public static final class Audio {
         /**
-         * Columns for audio file that show up in multiple tables.
+         * Audio metadata columns.
          */
         public interface AudioColumns extends MediaColumns {
 
@@ -1901,15 +1975,17 @@
             public static final String TITLE_KEY = "title_key";
 
             /**
-             * The duration of the audio file, in ms
+             * The duration of the audio item.
              */
+            @DurationMillisLong
             @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
             public static final String DURATION = "duration";
 
             /**
-             * The position, in ms, playback was at when playback for this file
-             * was last stopped.
+             * The position within the audio item at which playback should be
+             * resumed.
              */
+            @DurationMillisLong
             @Column(Cursor.FIELD_TYPE_INTEGER)
             public static final String BOOKMARK = "bookmark";
 
@@ -2187,7 +2263,7 @@
         }
 
         /**
-         * Columns representing an audio genre
+         * Audio genre metadata columns.
          */
         public interface GenresColumns {
             /**
@@ -2290,7 +2366,7 @@
         }
 
         /**
-         * Columns representing a playlist
+         * Audio playlist metadata columns.
          */
         public interface PlaylistsColumns {
             /**
@@ -2321,17 +2397,16 @@
             public static final String DATA = "_data";
 
             /**
-             * The time the file was added to the media provider
-             * Units are seconds since 1970.
+             * The time the media item was first added.
              */
+            @CurrentTimeSecondsLong
             @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
             public static final String DATE_ADDED = "date_added";
 
             /**
-             * The time the file was last modified
-             * Units are seconds since 1970.
-             * NOTE: This is for internal use by the media scanner.  Do not modify this field.
+             * The time the media item was last modified.
              */
+            @CurrentTimeSecondsLong
             @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
             public static final String DATE_MODIFIED = "date_modified";
         }
@@ -2450,7 +2525,7 @@
         }
 
         /**
-         * Columns representing an artist
+         * Audio artist metadata columns.
          */
         public interface ArtistColumns {
             /**
@@ -2537,7 +2612,7 @@
         }
 
         /**
-         * Columns representing an album
+         * Audio album metadata columns.
          */
         public interface AlbumColumns {
 
@@ -2707,6 +2782,9 @@
         }
     }
 
+    /**
+     * Collection of all media with MIME type of {@code video/*}.
+     */
     public static final class Video {
 
         /**
@@ -2714,15 +2792,25 @@
          */
         public static final String DEFAULT_SORT_ORDER = MediaColumns.DISPLAY_NAME;
 
+        /**
+         * @deprecated all queries should be performed through
+         *             {@link ContentResolver} directly, which offers modern
+         *             features like {@link CancellationSignal}.
+         */
+        @Deprecated
         public static final Cursor query(ContentResolver cr, Uri uri, String[] projection) {
             return cr.query(uri, projection, null, null, DEFAULT_SORT_ORDER);
         }
 
+        /**
+         * Video metadata columns.
+         */
         public interface VideoColumns extends MediaColumns {
 
             /**
-             * The duration of the video file, in ms
+             * The duration of the video item.
              */
+            @DurationMillisLong
             @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
             public static final String DURATION = "duration";
 
@@ -2799,9 +2887,9 @@
             public static final String LONGITUDE = "longitude";
 
             /**
-             * The date & time that the video was taken in units
-             * of milliseconds since jan 1, 1970.
+             * The time the media item was taken.
              */
+            @CurrentTimeMillisLong
             @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
             public static final String DATE_TAKEN = "datetaken";
 
@@ -2849,11 +2937,10 @@
             public static final String GROUP_ID = "group_id";
 
             /**
-             * The bookmark for the video. Time in ms. Represents the location in the video that the
-             * video should start playing at the next time it is opened. If the value is null or
-             * out of the range 0..DURATION-1 then the video should start playing from the
-             * beginning.
+             * The position within the video item at which playback should be
+             * resumed.
              */
+            @DurationMillisLong
             @Column(Cursor.FIELD_TYPE_INTEGER)
             public static final String BOOKMARK = "bookmark";
 
diff --git a/core/java/com/android/internal/policy/DividerSnapAlgorithm.java b/core/java/com/android/internal/policy/DividerSnapAlgorithm.java
index a8ad810..c46f867 100644
--- a/core/java/com/android/internal/policy/DividerSnapAlgorithm.java
+++ b/core/java/com/android/internal/policy/DividerSnapAlgorithm.java
@@ -137,6 +137,7 @@
         mDismissStartTarget = mTargets.get(0);
         mDismissEndTarget = mTargets.get(mTargets.size() - 1);
         mMiddleTarget = mTargets.get(mTargets.size() / 2);
+        mMiddleTarget.isMiddleTarget = true;
     }
 
     /**
@@ -438,6 +439,8 @@
 
         public final int flag;
 
+        public boolean isMiddleTarget;
+
         /**
          * Multiplier used to calculate distance to snap position. The lower this value, the harder
          * it's to snap on this target
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index d69d416..c45900c 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -667,6 +667,11 @@
     char methodTraceFileSizeBuf[sizeof("-Xmethod-trace-file-size:") + PROPERTY_VALUE_MAX];
     std::string fingerprintBuf;
     char jdwpProviderBuf[sizeof("-XjdwpProvider:") - 1 + PROPERTY_VALUE_MAX];
+    char bootImageBuf[sizeof("-Ximage:") - 1 + PROPERTY_VALUE_MAX];
+
+    if (parseRuntimeOption("dalvik.vm.boot-image", bootImageBuf, "-Ximage:")) {
+        ALOGI("Boot image: '%s'\n", bootImageBuf);
+    }
 
     bool checkJni = false;
     property_get("dalvik.vm.checkjni", propBuf, "");
diff --git a/core/tests/coretests/src/android/net/UriTest.java b/core/tests/coretests/src/android/net/UriTest.java
index a33de7b..a71000b 100644
--- a/core/tests/coretests/src/android/net/UriTest.java
+++ b/core/tests/coretests/src/android/net/UriTest.java
@@ -182,8 +182,7 @@
 
         uri = Uri.parse("http://bob%40lee%3ajr@local%68ost:4%32");
         assertEquals("bob@lee:jr", uri.getUserInfo());
-        assertEquals("localhost", uri.getHost());
-        assertEquals(42, uri.getPort());
+        assertEquals("localhost:42", uri.getHost());
 
         uri = Uri.parse("http://localhost");
         assertEquals("localhost", uri.getHost());
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
index 7a7d1f6..bb34a87 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
@@ -461,6 +461,9 @@
         if (mSnapAlgorithm == null) {
             mSnapAlgorithm = new DividerSnapAlgorithm(getContext().getResources(), mDisplayWidth,
                     mDisplayHeight, mDividerSize, isHorizontalDivision(), mStableInsets, mDockSide);
+            if (mSnapTargetBeforeMinimized != null && mSnapTargetBeforeMinimized.isMiddleTarget) {
+                mSnapTargetBeforeMinimized = mSnapAlgorithm.getMiddleTarget();
+            }
         }
         if (mMinimizedSnapAlgorithm == null) {
             mMinimizedSnapAlgorithm = new DividerSnapAlgorithm(getContext().getResources(),
diff --git a/services/core/java/com/android/server/input/InputForwarder.java b/services/core/java/com/android/server/input/InputForwarder.java
deleted file mode 100644
index 00af839..0000000
--- a/services/core/java/com/android/server/input/InputForwarder.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2017 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 com.android.server.input;
-
-import android.app.IInputForwarder;
-import android.hardware.input.InputManagerInternal;
-import android.view.InputEvent;
-
-import com.android.server.LocalServices;
-
-import static android.hardware.input.InputManager.INJECT_INPUT_EVENT_MODE_ASYNC;
-
-/**
- * Basic implementation of {@link IInputForwarder}.
- */
-class InputForwarder extends IInputForwarder.Stub {
-
-    private final InputManagerInternal mInputManagerInternal;
-    private final int mDisplayId;
-
-    InputForwarder(int displayId) {
-        mDisplayId = displayId;
-        mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
-    }
-
-    @Override
-    public boolean forwardEvent(InputEvent event) {
-        event.setDisplayId(mDisplayId);
-        return mInputManagerInternal.injectInputEvent(event, INJECT_INPUT_EVENT_MODE_ASYNC);
-    }
-}
\ No newline at end of file
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index 28393a2..87c7441 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -17,7 +17,6 @@
 package com.android.server.input;
 
 import android.annotation.NonNull;
-import android.app.IInputForwarder;
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
@@ -1685,29 +1684,6 @@
         nativeMonitor(mPtr);
     }
 
-    // Binder call
-    @Override
-    public IInputForwarder createInputForwarder(int displayId) throws RemoteException {
-        if (!checkCallingPermission(android.Manifest.permission.INJECT_EVENTS,
-                "createInputForwarder()")) {
-            throw new SecurityException("Requires INJECT_EVENTS permission");
-        }
-        final DisplayManager displayManager = mContext.getSystemService(DisplayManager.class);
-        final Display display = displayManager.getDisplay(displayId);
-        if (display == null) {
-            throw new IllegalArgumentException(
-                    "Can't create input forwarder for non-existent displayId: " + displayId);
-        }
-        final int callingUid = Binder.getCallingUid();
-        final int displayOwnerUid = display.getOwnerUid();
-        if (callingUid != displayOwnerUid) {
-            throw new SecurityException(
-                    "Only owner of the display can forward input events to it.");
-        }
-
-        return new InputForwarder(displayId);
-    }
-
     // Native callback.
     private void notifyConfigurationChanged(long whenNanos) {
         mWindowManagerCallbacks.notifyConfigurationChanged();
diff --git a/services/core/java/com/android/server/pm/ApexManager.java b/services/core/java/com/android/server/pm/ApexManager.java
index e12d1dc..8051abb 100644
--- a/services/core/java/com/android/server/pm/ApexManager.java
+++ b/services/core/java/com/android/server/pm/ApexManager.java
@@ -27,6 +27,7 @@
 import android.content.pm.PackageParser.PackageParserException;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.os.ServiceManager.ServiceNotFoundException;
 import android.util.Slog;
 
 import com.android.internal.util.IndentingPrintWriter;
@@ -50,8 +51,12 @@
     private final Map<String, PackageInfo> mActivePackagesCache;
 
     ApexManager() {
-        mApexService = IApexService.Stub.asInterface(
-            ServiceManager.getService("apexservice"));
+        try {
+            mApexService = IApexService.Stub.asInterface(
+                ServiceManager.getServiceOrThrow("apexservice"));
+        } catch (ServiceNotFoundException e) {
+            throw new IllegalStateException("Required service apexservice not available");
+        }
         mActivePackagesCache = populateActivePackagesCache();
     }
 
@@ -151,7 +156,7 @@
     }
 
     /**
-     * Mark a staged session previously submitted using {@cde submitStagedSession} as ready to be
+     * Mark a staged session previously submitted using {@code submitStagedSession} as ready to be
      * applied at next reboot.
      *
      * @param sessionId the identifier of the {@link PackageInstallerSession} being marked as ready.
@@ -227,8 +232,6 @@
                     ipw.println("State: STAGED");
                 } else if (si.isActivated) {
                     ipw.println("State: ACTIVATED");
-                } else if (si.isActivationPendingRetry) {
-                    ipw.println("State: ACTIVATION PENDING RETRY");
                 } else if (si.isActivationFailed) {
                     ipw.println("State: ACTIVATION FAILED");
                 }
diff --git a/services/core/java/com/android/server/pm/OWNERS b/services/core/java/com/android/server/pm/OWNERS
index 640b155..8ce2568 100644
--- a/services/core/java/com/android/server/pm/OWNERS
+++ b/services/core/java/com/android/server/pm/OWNERS
@@ -9,6 +9,10 @@
 toddke@android.com
 toddke@google.com
 
+# apex support
+per-file ApexManager.java = dariofreni@google.com, narayan@google.com, toddke@android.com, toddke@google.com
+per-file StagingManager.java = dariofreni@google.com, narayan@google.com, toddke@android.com, toddke@google.com
+
 # dex
 per-file AbstractStatsBase.java = agampe@google.com
 per-file AbstractStatsBase.java = calin@google.com
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index f56b984..8df5a71 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -1181,11 +1181,9 @@
             @NonNull int[] updatedUserIds) {
         AppOpsManager appOpsManager = mContext.getSystemService(AppOpsManager.class);
 
-        if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
-            return updatedUserIds;
-        }
-
         String pkgName = pkg.packageName;
+        boolean supportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
+                >= Build.VERSION_CODES.M;
 
         int[] users = UserManagerService.getInstance().getUserIds();
         int numUsers = users.length;
@@ -1210,15 +1208,17 @@
                             if ((flags & (FLAG_PERMISSION_GRANTED_BY_DEFAULT
                                     | FLAG_PERMISSION_POLICY_FIXED | FLAG_PERMISSION_SYSTEM_FIXED))
                                     == 0) {
-                                int revokeResult = ps.revokeRuntimePermission(bp, userId);
-                                if (revokeResult
-                                        != PERMISSION_OPERATION_FAILURE) {
-
-                                    if (DEBUG_PERMISSIONS) {
-                                        Slog.i(TAG, "Revoking runtime permission " + permission
-                                                + " for " + pkgName
-                                                + " as it is now requested");
+                                if (supportsRuntimePermissions) {
+                                    int revokeResult = ps.revokeRuntimePermission(bp, userId);
+                                    if (revokeResult != PERMISSION_OPERATION_FAILURE) {
+                                        if (DEBUG_PERMISSIONS) {
+                                            Slog.i(TAG, "Revoking runtime permission "
+                                                    + permission + " for " + pkgName
+                                                    + " as it is now requested");
+                                        }
                                     }
+                                } else {
+                                    setAppOpMode(permission, pkg, userId, MODE_IGNORED);
                                 }
 
                                 List<String> fgPerms = mBackgroundPermissions.get(permission);
diff --git a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
index ceaf829..05d3c17 100644
--- a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
+++ b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
@@ -16,6 +16,7 @@
 
 package com.android.server.rollback;
 
+import android.annotation.NonNull;
 import android.app.AppOpsManager;
 import android.content.BroadcastReceiver;
 import android.content.Context;
@@ -842,6 +843,7 @@
             String packageName = newPackage.packageName;
             for (PackageRollbackInfo info : rd.packages) {
                 if (info.getPackageName().equals(packageName)) {
+                    info.getInstalledUsers().addAll(IntArray.wrap(installedUsers));
                     AppDataRollbackHelper.SnapshotAppDataResult rs =
                             mAppDataRollbackHelper.snapshotAppData(packageName, installedUsers);
                     info.getPendingBackups().addAll(rs.pendingBackups);
@@ -874,7 +876,7 @@
      * the child sessions, not the parent session.
      */
     private boolean enableRollbackForSession(PackageInstaller.SessionInfo session,
-            int[] installedUsers, boolean snapshotUserData) {
+            @NonNull int[] installedUsers, boolean snapshotUserData) {
         // TODO: Don't attempt to enable rollback for split installs.
         final int installFlags = session.installFlags;
         if ((installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) == 0) {
@@ -1016,7 +1018,7 @@
             }
 
             if (!session.isMultiPackage()) {
-                if (!enableRollbackForSession(session, null, false)) {
+                if (!enableRollbackForSession(session, new int[0], false)) {
                     Log.e(TAG, "Unable to enable rollback for session: " + sessionId);
                     result.offer(false);
                     return;
@@ -1030,7 +1032,7 @@
                         result.offer(false);
                         return;
                     }
-                    if (!enableRollbackForSession(childSession, null, false)) {
+                    if (!enableRollbackForSession(childSession, new int[0], false)) {
                         Log.e(TAG, "Unable to enable rollback for session: " + sessionId);
                         result.offer(false);
                         return;
diff --git a/services/core/java/com/android/server/rollback/TEST_MAPPING b/services/core/java/com/android/server/rollback/TEST_MAPPING
index c1d95ac..6be93a0 100644
--- a/services/core/java/com/android/server/rollback/TEST_MAPPING
+++ b/services/core/java/com/android/server/rollback/TEST_MAPPING
@@ -2,6 +2,9 @@
   "presubmit": [
     {
       "name": "RollbackTest"
+    },
+    {
+      "name": "StagedRollbackTest"
     }
   ]
 }
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index f33c518..087de69 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -87,8 +87,6 @@
 import static android.os.Build.VERSION_CODES.O;
 import static android.os.Process.SYSTEM_UID;
 import static android.view.Display.INVALID_DISPLAY;
-import static android.view.WindowManagerPolicyConstants.NAV_BAR_LEFT;
-import static android.view.WindowManagerPolicyConstants.NAV_BAR_RIGHT;
 
 import static com.android.server.am.ActivityRecordProto.CONFIGURATION_CONTAINER;
 import static com.android.server.am.ActivityRecordProto.FRONT_OF_TASK;
@@ -2828,28 +2826,6 @@
             outAppBounds.setEmpty();
         }
 
-        // TODO(b/112288258): Remove below calculation because the position information in bounds
-        // will be replaced by the offset of surface.
-        final Rect appBounds = parentConfig.windowConfiguration.getAppBounds();
-        if (appBounds != null) {
-            final Rect outBounds = inOutConfig.windowConfiguration.getBounds();
-            final int activityWidth = outBounds.width();
-            final int navBarPosition = mAtmService.mWindowManager.getNavBarPosition(getDisplayId());
-            if (navBarPosition == NAV_BAR_LEFT) {
-                // Position the activity frame on the opposite side of the nav bar.
-                outBounds.left = appBounds.right - activityWidth;
-                outBounds.right = appBounds.right;
-            } else if (navBarPosition == NAV_BAR_RIGHT) {
-                // Position the activity frame on the opposite side of the nav bar.
-                outBounds.left = 0;
-                outBounds.right = activityWidth + appBounds.left;
-            } else if (appBounds.width() > activityWidth) {
-                // Horizontally center the frame.
-                outBounds.left = appBounds.left + (appBounds.width() - activityWidth) / 2;
-                outBounds.right = outBounds.left + activityWidth;
-            }
-        }
-
         task.computeConfigResourceOverrides(inOutConfig, parentConfig, insideParentBounds);
     }
 
diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
index 0a3c2fb..c685b05 100644
--- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
@@ -2332,6 +2332,20 @@
             if (!task.canBeLaunchedOnDisplay(actualDisplayId)) {
                 throw new IllegalStateException("Task resolved to incompatible display");
             }
+
+            final ActivityDisplay preferredDisplay =
+                    mRootActivityContainer.getActivityDisplay(preferredDisplayId);
+
+            final boolean singleTaskInstance = preferredDisplay != null
+                    && preferredDisplay.isSingleTaskInstance();
+
+            if (singleTaskInstance) {
+                // Suppress the warning toast if the preferredDisplay was set to singleTask.
+                // The singleTaskInstance displays will only contain one task and any attempt to
+                // launch new task will re-route to the default display.
+                return;
+            }
+
             if (preferredDisplayId != actualDisplayId) {
                 Slog.w(TAG, "Failed to put " + task + " on display " + preferredDisplayId);
                 // Display a warning toast that we failed to put a task on a secondary display.
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 3430987..21a557e 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -2164,9 +2164,6 @@
                 // A modal window uses the whole compatibility bounds.
                 flags |= FLAG_NOT_TOUCH_MODAL;
                 mTmpRect.set(mAppToken.getResolvedOverrideBounds());
-                // TODO(b/112288258): Remove the forced offset when the override bounds always
-                // starts from zero (See {@link ActivityRecord#resolveOverrideConfiguration}).
-                mTmpRect.offsetTo(0, 0);
             } else {
                 // Non-modal uses the application based frame.
                 mTmpRect.set(mWindowFrames.mCompatFrame);
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 9523202..9767efd 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -5181,7 +5181,7 @@
         Preconditions.checkNotNull(who, "ComponentName is null");
         final int userHandle = mInjector.userHandleGetCallingUserId();
         synchronized (getLockObject()) {
-            ActiveAdmin ap = getActiveAdminForCallerLocked(
+            final ActiveAdmin ap = getActiveAdminForCallerLocked(
                     who, DeviceAdminInfo.USES_POLICY_FORCE_LOCK, parent);
             if (ap.maximumTimeToUnlock != timeMs) {
                 ap.maximumTimeToUnlock = timeMs;
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index 8c36905..a1db3e8 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -27,9 +27,6 @@
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
-import static com.android.server.policy.WindowManagerPolicy.NAV_BAR_BOTTOM;
-import static com.android.server.policy.WindowManagerPolicy.NAV_BAR_LEFT;
-import static com.android.server.policy.WindowManagerPolicy.NAV_BAR_RIGHT;
 import static com.android.server.wm.ActivityStack.ActivityState.INITIALIZING;
 import static com.android.server.wm.ActivityStack.ActivityState.PAUSING;
 import static com.android.server.wm.ActivityStack.ActivityState.RESUMED;
@@ -158,35 +155,6 @@
         assertTrue(mActivity.isState(STOPPED));
     }
 
-    @Test
-    public void testPositionLimitedAspectRatioNavBarBottom() {
-        verifyPositionWithLimitedAspectRatio(NAV_BAR_BOTTOM, new Rect(0, 0, 1000, 2000), 1.5f,
-                new Rect(0, 0, 1000, 1500));
-    }
-
-    @Test
-    public void testPositionLimitedAspectRatioNavBarLeft() {
-        verifyPositionWithLimitedAspectRatio(NAV_BAR_LEFT, new Rect(0, 0, 2000, 1000), 1.5f,
-                new Rect(500, 0, 2000, 1000));
-    }
-
-    @Test
-    public void testPositionLimitedAspectRatioNavBarRight() {
-        verifyPositionWithLimitedAspectRatio(NAV_BAR_RIGHT, new Rect(0, 0, 2000, 1000), 1.5f,
-                new Rect(0, 0, 1500, 1000));
-    }
-
-    private void verifyPositionWithLimitedAspectRatio(int navBarPosition, Rect taskBounds,
-            float aspectRatio, Rect expectedActivityBounds) {
-        // Verify with nav bar on the right.
-        when(mService.mWindowManager.getNavBarPosition(mActivity.getDisplayId()))
-                .thenReturn(navBarPosition);
-        mTask.getConfiguration().windowConfiguration.setAppBounds(taskBounds);
-        mActivity.info.maxAspectRatio = aspectRatio;
-        ensureActivityConfiguration();
-        assertEquals(expectedActivityBounds, mActivity.getBounds());
-    }
-
     private void ensureActivityConfiguration() {
         mActivity.ensureActivityConfiguration(0 /* globalChanges */, false /* preserveWindow */);
     }
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
index 3eb9085..b0e20b8 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
@@ -35,6 +35,7 @@
 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
 import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
 
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.never;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.reset;
@@ -54,7 +55,6 @@
 import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doNothing;
 
 import android.graphics.Insets;
 import android.graphics.Matrix;
@@ -87,6 +87,7 @@
  */
 @SmallTest
 @Presubmit
+@FlakyTest(bugId = 124127512)
 public class WindowStateTests extends WindowTestsBase {
     private static int sPreviousNewInsetsMode;
 
@@ -389,6 +390,7 @@
     }
 
     @Test
+    @FlakyTest(bugId = 74078662)
     public void testLayoutSeqResetOnReparent() {
         final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
         app.mLayoutSeq = 1;
@@ -445,6 +447,7 @@
     }
 
     @Test
+    @FlakyTest(bugId = 74078662)
     public void testDisplayCutoutIsCalculatedRelativeToFrame() {
         final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
         WindowFrames wf = app.getWindowFrames();
diff --git a/tests/DexLoggerIntegrationTests/src/com/android/server/pm/dex/DexLoggerIntegrationTests.java b/tests/DexLoggerIntegrationTests/src/com/android/server/pm/dex/DexLoggerIntegrationTests.java
index 1cf960a..99d1f5ff4 100644
--- a/tests/DexLoggerIntegrationTests/src/com/android/server/pm/dex/DexLoggerIntegrationTests.java
+++ b/tests/DexLoggerIntegrationTests/src/com/android/server/pm/dex/DexLoggerIntegrationTests.java
@@ -65,6 +65,8 @@
 @RunWith(JUnit4.class)
 public final class DexLoggerIntegrationTests {
 
+    private static final String SHA_256 = "SHA-256";
+
     // Event log tag used for SNET related events
     private static final int SNET_TAG = 0x534e4554;
 
@@ -76,6 +78,13 @@
     private static final int IDLE_LOGGING_JOB_ID = 2030028;
     private static final int AUDIT_WATCHING_JOB_ID = 203142925;
 
+    // For tests that rely on parsing audit logs, how often to retry. (There are many reasons why
+    // we might not see the audit logs, including throttling and delays in log generation, so to
+    // avoid flakiness we run these tests multiple times, allowing progressively longer between
+    // code loading and checking the logs on each try.)
+    private static final int AUDIT_LOG_RETRIES = 10;
+    private static final int RETRY_DELAY_MS = 2_000;
+
     private static Context sContext;
     private static int sMyUid;
 
@@ -144,78 +153,65 @@
 
     @Test
     public void testGeneratesEvents_nativeLibrary() throws Exception {
-        File privateCopyFile = privateFile("copied.so");
-        String expectedNameHash =
-                "996223BAD4B4FE75C57A3DEC61DB9C0B38E0A7AD479FC95F33494F4BC55A0F0E";
-        String expectedContentHash =
-                copyAndHashResource(libraryPath("DexLoggerNativeTestLibrary.so"), privateCopyFile);
+        new TestNativeCodeWithRetries() {
+            @Override
+            protected void loadNativeCode(int tryNumber) throws Exception {
+                // We need to use a different file name for each retry, because once a file is
+                // loaded, re-loading it has no effect.
+                String privateCopyName = "copied" + tryNumber + ".so";
+                File privateCopyFile = privateFile(privateCopyName);
+                mExpectedNameHash = hashOf(privateCopyName);
+                mExpectedContentHash = copyAndHashResource(
+                        libraryPath("DexLoggerNativeTestLibrary.so"), privateCopyFile);
 
-        System.load(privateCopyFile.toString());
-
-        // Run the job to scan generated audit log entries
-        runDynamicCodeLoggingJob(AUDIT_WATCHING_JOB_ID);
-
-        // And then make sure we log events about it
-        long previousEventNanos = mostRecentEventTimeNanos();
-        runDynamicCodeLoggingJob(IDLE_LOGGING_JOB_ID);
-
-        assertDclLoggedSince(previousEventNanos, DCL_NATIVE_SUBTAG,
-                expectedNameHash, expectedContentHash);
+                System.load(privateCopyFile.toString());
+            }
+        }.runTest();
     }
 
     @Test
     public void testGeneratesEvents_nativeLibrary_escapedName() throws Exception {
-        // A file name with a space will be escaped in the audit log; verify we un-escape it
-        // correctly.
-        File privateCopyFile = privateFile("second copy.so");
-        String expectedNameHash =
-                "8C39990C560B4F36F83E208E279F678746FE23A790E4C50F92686584EA2041CA";
-        String expectedContentHash =
-                copyAndHashResource(libraryPath("DexLoggerNativeTestLibrary.so"), privateCopyFile);
+        new TestNativeCodeWithRetries() {
+            @Override
+            protected void loadNativeCode(int tryNumber) throws Exception {
+                // A file name with a space will be escaped in the audit log; verify we un-escape it
+                // correctly.
+                String privateCopyName = "second copy " + tryNumber + ".so";
+                File privateCopyFile = privateFile(privateCopyName);
+                mExpectedNameHash = hashOf(privateCopyName);
+                mExpectedContentHash = copyAndHashResource(
+                        libraryPath("DexLoggerNativeTestLibrary.so"), privateCopyFile);
 
-        System.load(privateCopyFile.toString());
-
-        // Run the job to scan generated audit log entries
-        runDynamicCodeLoggingJob(AUDIT_WATCHING_JOB_ID);
-
-        // And then make sure we log events about it
-        long previousEventNanos = mostRecentEventTimeNanos();
-        runDynamicCodeLoggingJob(IDLE_LOGGING_JOB_ID);
-
-        assertDclLoggedSince(previousEventNanos, DCL_NATIVE_SUBTAG,
-                expectedNameHash, expectedContentHash);
+                System.load(privateCopyFile.toString());
+            }
+        }.runTest();
     }
 
     @Test
     public void testGeneratesEvents_nativeExecutable() throws Exception {
-        File privateCopyFile = privateFile("test_executable");
-        String expectedNameHash =
-                "3FBEC3F925A132D18F347F11AE9A5BB8DE1238828F8B4E064AA86EB68BD46DCF";
-        String expectedContentHash =
-                copyAndHashResource("/DexLoggerNativeExecutable", privateCopyFile);
-        assertThat(privateCopyFile.setExecutable(true)).isTrue();
+        new TestNativeCodeWithRetries() {
+            @Override
+            protected void loadNativeCode(int tryNumber) throws Exception {
+                String privateCopyName = "test_executable" + tryNumber;
+                File privateCopyFile = privateFile(privateCopyName);
+                mExpectedNameHash = hashOf(privateCopyName);
+                mExpectedContentHash = copyAndHashResource(
+                        "/DexLoggerNativeExecutable", privateCopyFile);
+                assertThat(privateCopyFile.setExecutable(true)).isTrue();
 
-        Process process = Runtime.getRuntime().exec(privateCopyFile.toString());
-        int exitCode = process.waitFor();
-        assertThat(exitCode).isEqualTo(0);
-
-        // Run the job to scan generated audit log entries
-        runDynamicCodeLoggingJob(AUDIT_WATCHING_JOB_ID);
-
-        // And then make sure we log events about it
-        long previousEventNanos = mostRecentEventTimeNanos();
-        runDynamicCodeLoggingJob(IDLE_LOGGING_JOB_ID);
-
-        assertDclLoggedSince(previousEventNanos, DCL_NATIVE_SUBTAG,
-                expectedNameHash, expectedContentHash);
+                Process process = Runtime.getRuntime().exec(privateCopyFile.toString());
+                int exitCode = process.waitFor();
+                assertThat(exitCode).isEqualTo(0);
+            }
+        }.runTest();
     }
 
     @Test
     public void testGeneratesEvents_spoofed_validFile() throws Exception {
         File privateCopyFile = privateFile("spoofed");
 
-        String expectedContentHash =
-                copyAndHashResource("/DexLoggerNativeExecutable", privateCopyFile);
+        String expectedContentHash = copyAndHashResource(
+                "/DexLoggerNativeExecutable", privateCopyFile);
 
         EventLog.writeEvent(EventLog.getTagCode("auditd"),
                 "type=1400 avc: granted { execute_no_trans } "
@@ -304,6 +300,40 @@
         assertNoDclLoggedSince(previousEventNanos, DCL_NATIVE_SUBTAG, expectedNameHash);
     }
 
+    // Abstract out the logic for running a native code loading test multiple times if needed and
+    // leaving time for audit messages to reach the log.
+    private abstract class TestNativeCodeWithRetries {
+        String mExpectedContentHash;
+        String mExpectedNameHash;
+
+        abstract void loadNativeCode(int tryNumber) throws Exception;
+
+        final void runTest() throws Exception {
+            List<String> messages = null;
+
+            for (int i = 0; i < AUDIT_LOG_RETRIES; i++) {
+                loadNativeCode(i);
+
+                SystemClock.sleep(i * RETRY_DELAY_MS);
+
+                // Run the job to scan generated audit log entries
+                runDynamicCodeLoggingJob(AUDIT_WATCHING_JOB_ID);
+
+                // And then make sure we log events about it
+                long previousEventNanos = mostRecentEventTimeNanos();
+                runDynamicCodeLoggingJob(IDLE_LOGGING_JOB_ID);
+
+                messages = findMatchingEvents(
+                        previousEventNanos, DCL_NATIVE_SUBTAG, mExpectedNameHash);
+                if (!messages.isEmpty()) {
+                    break;
+                }
+            }
+
+            assertHasDclLog(messages, mExpectedContentHash);
+        }
+    }
+
     private static File privateFile(String name) {
         return new File(sContext.getDir("dcl", Context.MODE_PRIVATE), name);
     }
@@ -315,7 +345,7 @@
     }
 
     private static String copyAndHashResource(String resourcePath, File copyTo) throws Exception {
-        MessageDigest hasher = MessageDigest.getInstance("SHA-256");
+        MessageDigest hasher = MessageDigest.getInstance(SHA_256);
 
         // Copy the jar from our Java resources to a private data directory
         Class<?> thisClass = DexLoggerIntegrationTests.class;
@@ -334,6 +364,16 @@
 
         // Compute the SHA-256 of the file content so we can check that it is the same as the value
         // we see logged.
+        return toHexString(hasher);
+    }
+
+    private String hashOf(String input) throws Exception {
+        MessageDigest hasher = MessageDigest.getInstance(SHA_256);
+        hasher.update(input.getBytes());
+        return toHexString(hasher);
+    }
+
+    private static String toHexString(MessageDigest hasher) {
         Formatter formatter = new Formatter();
         for (byte b : hasher.digest()) {
             formatter.format("%02X", b);
@@ -388,6 +428,10 @@
         List<String> messages =
                 findMatchingEvents(previousEventNanos, expectedSubTag, expectedNameHash);
 
+        assertHasDclLog(messages, expectedContentHash);
+    }
+
+    private static void assertHasDclLog(List<String> messages, String expectedContentHash) {
         assertWithMessage("Expected exactly one matching log entry").that(messages).hasSize(1);
         assertThat(messages.get(0)).endsWith(expectedContentHash);
     }
diff --git a/tests/RollbackTest/TEST_MAPPING b/tests/RollbackTest/TEST_MAPPING
index c1d95ac..6be93a0 100644
--- a/tests/RollbackTest/TEST_MAPPING
+++ b/tests/RollbackTest/TEST_MAPPING
@@ -2,6 +2,9 @@
   "presubmit": [
     {
       "name": "RollbackTest"
+    },
+    {
+      "name": "StagedRollbackTest"
     }
   ]
 }