Merge "Input devices configure on per-display basis (2/2)"
diff --git a/api/current.txt b/api/current.txt
index afd09ad..6a2c842 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5811,6 +5811,7 @@
     method public final void setInterruptionFilter(int);
     method public void setNotificationDelegate(@NonNull String);
     method public void setNotificationPolicy(@NonNull android.app.NotificationManager.Policy);
+    method public boolean shouldHideSilentStatusBarIcons();
     method public boolean updateAutomaticZenRule(String, android.app.AutomaticZenRule);
     field public static final String ACTION_APP_BLOCK_STATE_CHANGED = "android.app.action.APP_BLOCK_STATE_CHANGED";
     field public static final String ACTION_AUTOMATIC_ZEN_RULE = "android.app.action.AUTOMATIC_ZEN_RULE";
@@ -36527,7 +36528,7 @@
     field public static final String ACCOUNT_TYPE_LOCAL = "LOCAL";
     field public static final String ACTION_EVENT_REMINDER = "android.intent.action.EVENT_REMINDER";
     field public static final String ACTION_HANDLE_CUSTOM_EVENT = "android.provider.calendar.action.HANDLE_CUSTOM_EVENT";
-    field public static final String ACTION_VIEW_WORK_CALENDAR_EVENT = "android.provider.calendar.action.VIEW_WORK_CALENDAR_EVENT";
+    field public static final String ACTION_VIEW_MANAGED_PROFILE_CALENDAR_EVENT = "android.provider.calendar.action.VIEW_MANAGED_PROFILE_CALENDAR_EVENT";
     field public static final String AUTHORITY = "com.android.calendar";
     field public static final String CALLER_IS_SYNCADAPTER = "caller_is_syncadapter";
     field public static final android.net.Uri CONTENT_URI;
@@ -41555,6 +41556,7 @@
     method public void onNotificationRemoved(android.service.notification.StatusBarNotification);
     method public void onNotificationRemoved(android.service.notification.StatusBarNotification, android.service.notification.NotificationListenerService.RankingMap);
     method public void onNotificationRemoved(android.service.notification.StatusBarNotification, android.service.notification.NotificationListenerService.RankingMap, int);
+    method public void onStatusBarIconsBehaviorChanged(boolean);
     method public final void requestInterruptionFilter(int);
     method public final void requestListenerHints(int);
     method public static void requestRebind(android.content.ComponentName);
@@ -52887,6 +52889,9 @@
 
   public final class UserDataRemovalRequest implements android.os.Parcelable {
     method public int describeContents();
+    method @NonNull public String getPackageName();
+    method @NonNull public java.util.List<android.view.contentcapture.UserDataRemovalRequest.UriRequest> getUriRequests();
+    method public boolean isForEverything();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.view.contentcapture.UserDataRemovalRequest> CREATOR;
   }
@@ -52898,6 +52903,11 @@
     method @NonNull public android.view.contentcapture.UserDataRemovalRequest.Builder forEverything();
   }
 
+  public final class UserDataRemovalRequest.UriRequest {
+    method @NonNull public android.net.Uri getUri();
+    method @NonNull public boolean isRecursive();
+  }
+
 }
 
 package android.view.inputmethod {
@@ -58117,13 +58127,13 @@
     ctor public ByteArrayOutputStream(int);
     method public void reset();
     method public int size();
-    method public byte[] toByteArray();
+    method @NonNull public byte[] toByteArray();
     method @NonNull public String toString(@NonNull String) throws java.io.UnsupportedEncodingException;
     method @Deprecated @NonNull public String toString(int);
     method public void write(int);
-    method public void write(byte[], int, int);
+    method public void write(@NonNull byte[], int, int);
     method public void writeTo(@NonNull java.io.OutputStream) throws java.io.IOException;
-    field protected byte[] buf;
+    field @NonNull protected byte[] buf;
     field protected int count;
   }
 
@@ -58294,12 +58304,12 @@
     method public boolean isHidden();
     method public long lastModified();
     method public long length();
-    method public String[] list();
-    method public String[] list(@Nullable java.io.FilenameFilter);
-    method public java.io.File[] listFiles();
-    method public java.io.File[] listFiles(@Nullable java.io.FilenameFilter);
-    method public java.io.File[] listFiles(@Nullable java.io.FileFilter);
-    method public static java.io.File[] listRoots();
+    method @Nullable public String[] list();
+    method @Nullable public String[] list(@Nullable java.io.FilenameFilter);
+    method @Nullable public java.io.File[] listFiles();
+    method @Nullable public java.io.File[] listFiles(@Nullable java.io.FilenameFilter);
+    method @Nullable public java.io.File[] listFiles(@Nullable java.io.FileFilter);
+    method @NonNull public static java.io.File[] listRoots();
     method public boolean mkdir();
     method public boolean mkdirs();
     method public boolean renameTo(@NonNull java.io.File);
@@ -58788,8 +58798,8 @@
     method protected void clearError();
     method public void close();
     method public void flush();
-    method @NonNull public java.io.PrintWriter format(@NonNull String, java.lang.Object...);
-    method @NonNull public java.io.PrintWriter format(@Nullable java.util.Locale, @NonNull String, java.lang.Object...);
+    method @NonNull public java.io.PrintWriter format(@NonNull String, @NonNull java.lang.Object...);
+    method @NonNull public java.io.PrintWriter format(@Nullable java.util.Locale, @NonNull String, @NonNull java.lang.Object...);
     method public void print(boolean);
     method public void print(char);
     method public void print(int);
@@ -58799,8 +58809,8 @@
     method public void print(char[]);
     method public void print(@Nullable String);
     method public void print(@Nullable Object);
-    method @NonNull public java.io.PrintWriter printf(@NonNull String, java.lang.Object...);
-    method @NonNull public java.io.PrintWriter printf(@Nullable java.util.Locale, @NonNull String, java.lang.Object...);
+    method @NonNull public java.io.PrintWriter printf(@NonNull String, @NonNull java.lang.Object...);
+    method @NonNull public java.io.PrintWriter printf(@Nullable java.util.Locale, @NonNull String, @NonNull java.lang.Object...);
     method public void println();
     method public void println(boolean);
     method public void println(char);
@@ -59626,45 +59636,45 @@
     method @NonNull public static Class<?> forName(@NonNull String) throws java.lang.ClassNotFoundException;
     method @NonNull public static Class<?> forName(@NonNull String, boolean, @Nullable ClassLoader) throws java.lang.ClassNotFoundException;
     method @Nullable public <A extends java.lang.annotation.Annotation> A getAnnotation(@NonNull Class<A>);
-    method public java.lang.annotation.Annotation[] getAnnotations();
+    method @NonNull public java.lang.annotation.Annotation[] getAnnotations();
     method @NonNull public <A extends java.lang.annotation.Annotation> A[] getAnnotationsByType(@NonNull Class<A>);
     method @Nullable public String getCanonicalName();
     method @Nullable public ClassLoader getClassLoader();
-    method public Class<?>[] getClasses();
+    method @NonNull public Class<?>[] getClasses();
     method @Nullable public Class<?> getComponentType();
-    method @NonNull public java.lang.reflect.Constructor<T> getConstructor(Class<?>...) throws java.lang.NoSuchMethodException, java.lang.SecurityException;
-    method public java.lang.reflect.Constructor<?>[] getConstructors() throws java.lang.SecurityException;
+    method @NonNull public java.lang.reflect.Constructor<T> getConstructor(@Nullable Class<?>...) throws java.lang.NoSuchMethodException, java.lang.SecurityException;
+    method @NonNull public java.lang.reflect.Constructor<?>[] getConstructors() throws java.lang.SecurityException;
     method @Nullable public <A extends java.lang.annotation.Annotation> A getDeclaredAnnotation(@NonNull Class<A>);
-    method public java.lang.annotation.Annotation[] getDeclaredAnnotations();
-    method public Class<?>[] getDeclaredClasses();
-    method @NonNull public java.lang.reflect.Constructor<T> getDeclaredConstructor(Class<?>...) throws java.lang.NoSuchMethodException, java.lang.SecurityException;
-    method public java.lang.reflect.Constructor<?>[] getDeclaredConstructors() throws java.lang.SecurityException;
+    method @NonNull public java.lang.annotation.Annotation[] getDeclaredAnnotations();
+    method @NonNull public Class<?>[] getDeclaredClasses();
+    method @NonNull public java.lang.reflect.Constructor<T> getDeclaredConstructor(@Nullable Class<?>...) throws java.lang.NoSuchMethodException, java.lang.SecurityException;
+    method @NonNull public java.lang.reflect.Constructor<?>[] getDeclaredConstructors() throws java.lang.SecurityException;
     method @NonNull public java.lang.reflect.Field getDeclaredField(@NonNull String) throws java.lang.NoSuchFieldException;
-    method public java.lang.reflect.Field[] getDeclaredFields();
-    method @NonNull public java.lang.reflect.Method getDeclaredMethod(@NonNull String, Class<?>...) throws java.lang.NoSuchMethodException, java.lang.SecurityException;
-    method public java.lang.reflect.Method[] getDeclaredMethods() throws java.lang.SecurityException;
+    method @NonNull public java.lang.reflect.Field[] getDeclaredFields();
+    method @NonNull public java.lang.reflect.Method getDeclaredMethod(@NonNull String, @Nullable Class<?>...) throws java.lang.NoSuchMethodException, java.lang.SecurityException;
+    method @NonNull public java.lang.reflect.Method[] getDeclaredMethods() throws java.lang.SecurityException;
     method @Nullable public Class<?> getDeclaringClass();
     method @Nullable public Class<?> getEnclosingClass();
     method @Nullable public java.lang.reflect.Constructor<?> getEnclosingConstructor();
     method @Nullable public java.lang.reflect.Method getEnclosingMethod();
-    method public T[] getEnumConstants();
+    method @Nullable public T[] getEnumConstants();
     method @NonNull public java.lang.reflect.Field getField(@NonNull String) throws java.lang.NoSuchFieldException;
-    method public java.lang.reflect.Field[] getFields() throws java.lang.SecurityException;
-    method public java.lang.reflect.Type[] getGenericInterfaces();
+    method @NonNull public java.lang.reflect.Field[] getFields() throws java.lang.SecurityException;
+    method @NonNull public java.lang.reflect.Type[] getGenericInterfaces();
     method @Nullable public java.lang.reflect.Type getGenericSuperclass();
-    method public Class<?>[] getInterfaces();
-    method @NonNull public java.lang.reflect.Method getMethod(@NonNull String, Class<?>...) throws java.lang.NoSuchMethodException, java.lang.SecurityException;
-    method public java.lang.reflect.Method[] getMethods() throws java.lang.SecurityException;
+    method @NonNull public Class<?>[] getInterfaces();
+    method @NonNull public java.lang.reflect.Method getMethod(@NonNull String, @Nullable Class<?>...) throws java.lang.NoSuchMethodException, java.lang.SecurityException;
+    method @NonNull public java.lang.reflect.Method[] getMethods() throws java.lang.SecurityException;
     method public int getModifiers();
     method @NonNull public String getName();
     method @Nullable public Package getPackage();
     method @Nullable public java.security.ProtectionDomain getProtectionDomain();
     method @Nullable public java.net.URL getResource(@NonNull String);
     method @Nullable public java.io.InputStream getResourceAsStream(@NonNull String);
-    method public Object[] getSigners();
+    method @Nullable public Object[] getSigners();
     method @NonNull public String getSimpleName();
     method @Nullable public Class<? super T> getSuperclass();
-    method public java.lang.reflect.TypeVariable<java.lang.Class<T>>[] getTypeParameters();
+    method @NonNull public java.lang.reflect.TypeVariable<java.lang.Class<T>>[] getTypeParameters();
     method public boolean isAnnotation();
     method public boolean isAnonymousClass();
     method public boolean isArray();
@@ -60551,8 +60561,8 @@
     method @NonNull public static String copyValueOf(char[]);
     method public boolean endsWith(@NonNull String);
     method public boolean equalsIgnoreCase(@Nullable String);
-    method @NonNull public static String format(@NonNull String, java.lang.Object...);
-    method @NonNull public static String format(@NonNull java.util.Locale, @NonNull String, java.lang.Object...);
+    method @NonNull public static String format(@NonNull String, @NonNull java.lang.Object...);
+    method @NonNull public static String format(@NonNull java.util.Locale, @NonNull String, @NonNull java.lang.Object...);
     method @Deprecated public void getBytes(int, int, byte[], int);
     method public byte[] getBytes(@NonNull String) throws java.io.UnsupportedEncodingException;
     method public byte[] getBytes(@NonNull java.nio.charset.Charset);
@@ -60564,7 +60574,7 @@
     method public int indexOf(@NonNull String, int);
     method @NonNull public String intern();
     method public boolean isEmpty();
-    method @NonNull public static String join(@NonNull CharSequence, java.lang.CharSequence...);
+    method @NonNull public static String join(@NonNull CharSequence, @Nullable java.lang.CharSequence...);
     method @NonNull public static String join(@NonNull CharSequence, @NonNull Iterable<? extends java.lang.CharSequence>);
     method public int lastIndexOf(int);
     method public int lastIndexOf(int, int);
@@ -60579,8 +60589,8 @@
     method @NonNull public String replace(@NonNull CharSequence, @NonNull CharSequence);
     method @NonNull public String replaceAll(@NonNull String, @NonNull String);
     method @NonNull public String replaceFirst(@NonNull String, @NonNull String);
-    method public String[] split(@NonNull String, int);
-    method public String[] split(@NonNull String);
+    method @NonNull public String[] split(@NonNull String, int);
+    method @NonNull public String[] split(@NonNull String);
     method public boolean startsWith(@NonNull String, int);
     method public boolean startsWith(@NonNull String);
     method @NonNull public CharSequence subSequence(int, int);
@@ -60781,7 +60791,7 @@
     method public long getId();
     method @NonNull public final String getName();
     method public final int getPriority();
-    method public StackTraceElement[] getStackTrace();
+    method @NonNull public StackTraceElement[] getStackTrace();
     method @NonNull public java.lang.Thread.State getState();
     method @Nullable public final ThreadGroup getThreadGroup();
     method @Nullable public java.lang.Thread.UncaughtExceptionHandler getUncaughtExceptionHandler();
@@ -60879,13 +60889,13 @@
     method @Nullable public Throwable getCause();
     method @Nullable public String getLocalizedMessage();
     method @Nullable public String getMessage();
-    method public StackTraceElement[] getStackTrace();
-    method public final Throwable[] getSuppressed();
+    method @NonNull public StackTraceElement[] getStackTrace();
+    method @NonNull public final Throwable[] getSuppressed();
     method @NonNull public Throwable initCause(@Nullable Throwable);
     method public void printStackTrace();
     method public void printStackTrace(@NonNull java.io.PrintStream);
     method public void printStackTrace(@NonNull java.io.PrintWriter);
-    method public void setStackTrace(StackTraceElement[]);
+    method public void setStackTrace(@NonNull StackTraceElement[]);
   }
 
   public class TypeNotPresentException extends java.lang.RuntimeException {
@@ -61208,8 +61218,8 @@
   public class AccessibleObject implements java.lang.reflect.AnnotatedElement {
     ctor protected AccessibleObject();
     method @Nullable public <T extends java.lang.annotation.Annotation> T getAnnotation(@NonNull Class<T>);
-    method public java.lang.annotation.Annotation[] getAnnotations();
-    method public java.lang.annotation.Annotation[] getDeclaredAnnotations();
+    method @NonNull public java.lang.annotation.Annotation[] getAnnotations();
+    method @NonNull public java.lang.annotation.Annotation[] getDeclaredAnnotations();
     method public boolean isAccessible();
     method public static void setAccessible(java.lang.reflect.AccessibleObject[], boolean) throws java.lang.SecurityException;
     method public void setAccessible(boolean) throws java.lang.SecurityException;
@@ -61217,10 +61227,10 @@
 
   public interface AnnotatedElement {
     method @Nullable public <T extends java.lang.annotation.Annotation> T getAnnotation(@NonNull Class<T>);
-    method public java.lang.annotation.Annotation[] getAnnotations();
+    method @NonNull public java.lang.annotation.Annotation[] getAnnotations();
     method public default <T extends java.lang.annotation.Annotation> T[] getAnnotationsByType(@NonNull Class<T>);
     method @Nullable public default <T extends java.lang.annotation.Annotation> T getDeclaredAnnotation(@NonNull Class<T>);
-    method public java.lang.annotation.Annotation[] getDeclaredAnnotations();
+    method @NonNull public java.lang.annotation.Annotation[] getDeclaredAnnotations();
     method public default <T extends java.lang.annotation.Annotation> T[] getDeclaredAnnotationsByType(@NonNull Class<T>);
     method public default boolean isAnnotationPresent(@NonNull Class<? extends java.lang.annotation.Annotation>);
   }
@@ -61255,20 +61265,20 @@
     method public int getModifiers();
     method @NonNull public String getName();
     method public java.lang.annotation.Annotation[][] getParameterAnnotations();
-    method public Class<?>[] getParameterTypes();
+    method @NonNull public Class<?>[] getParameterTypes();
     method public java.lang.reflect.TypeVariable<java.lang.reflect.Constructor<T>>[] getTypeParameters();
     method @NonNull public T newInstance(java.lang.Object...) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException, java.lang.InstantiationException, java.lang.reflect.InvocationTargetException;
     method @NonNull public String toGenericString();
   }
 
   public abstract class Executable extends java.lang.reflect.AccessibleObject implements java.lang.reflect.GenericDeclaration java.lang.reflect.Member {
-    method public abstract Class<?>[] getExceptionTypes();
-    method public java.lang.reflect.Type[] getGenericExceptionTypes();
-    method public java.lang.reflect.Type[] getGenericParameterTypes();
-    method public abstract java.lang.annotation.Annotation[][] getParameterAnnotations();
+    method @NonNull public abstract Class<?>[] getExceptionTypes();
+    method @NonNull public java.lang.reflect.Type[] getGenericExceptionTypes();
+    method @NonNull public java.lang.reflect.Type[] getGenericParameterTypes();
+    method @NonNull public abstract java.lang.annotation.Annotation[][] getParameterAnnotations();
     method public int getParameterCount();
-    method public abstract Class<?>[] getParameterTypes();
-    method public java.lang.reflect.Parameter[] getParameters();
+    method @NonNull public abstract Class<?>[] getParameterTypes();
+    method @NonNull public java.lang.reflect.Parameter[] getParameters();
     method public final boolean isAnnotationPresent(@NonNull Class<? extends java.lang.annotation.Annotation>);
     method public boolean isSynthetic();
     method public boolean isVarArgs();
@@ -61357,7 +61367,7 @@
     method @NonNull public Class<?>[] getParameterTypes();
     method @NonNull public Class<?> getReturnType();
     method @NonNull public java.lang.reflect.TypeVariable<java.lang.reflect.Method>[] getTypeParameters();
-    method @Nullable public Object invoke(@Nullable Object, java.lang.Object...) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException, java.lang.reflect.InvocationTargetException;
+    method @Nullable public Object invoke(@Nullable Object, @Nullable java.lang.Object...) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException, java.lang.reflect.InvocationTargetException;
     method public boolean isBridge();
     method public boolean isDefault();
     method @NonNull public String toGenericString();
@@ -61400,8 +61410,8 @@
 
   public final class Parameter implements java.lang.reflect.AnnotatedElement {
     method @Nullable public <T extends java.lang.annotation.Annotation> T getAnnotation(@NonNull Class<T>);
-    method public java.lang.annotation.Annotation[] getAnnotations();
-    method public java.lang.annotation.Annotation[] getDeclaredAnnotations();
+    method @NonNull public java.lang.annotation.Annotation[] getAnnotations();
+    method @NonNull public java.lang.annotation.Annotation[] getDeclaredAnnotations();
     method @NonNull public java.lang.reflect.Executable getDeclaringExecutable();
     method public int getModifiers();
     method @NonNull public String getName();
@@ -61414,7 +61424,7 @@
   }
 
   public interface ParameterizedType extends java.lang.reflect.Type {
-    method public java.lang.reflect.Type[] getActualTypeArguments();
+    method @NonNull public java.lang.reflect.Type[] getActualTypeArguments();
     method @Nullable public java.lang.reflect.Type getOwnerType();
     method @NonNull public java.lang.reflect.Type getRawType();
   }
@@ -61422,9 +61432,9 @@
   public class Proxy implements java.io.Serializable {
     ctor protected Proxy(@NonNull java.lang.reflect.InvocationHandler);
     method @NonNull public static java.lang.reflect.InvocationHandler getInvocationHandler(@NonNull Object) throws java.lang.IllegalArgumentException;
-    method @NonNull public static Class<?> getProxyClass(@Nullable ClassLoader, Class<?>...) throws java.lang.IllegalArgumentException;
+    method @NonNull public static Class<?> getProxyClass(@Nullable ClassLoader, @NonNull Class<?>...) throws java.lang.IllegalArgumentException;
     method public static boolean isProxyClass(@NonNull Class<?>);
-    method @NonNull public static Object newProxyInstance(@Nullable ClassLoader, Class<?>[], @NonNull java.lang.reflect.InvocationHandler) throws java.lang.IllegalArgumentException;
+    method @NonNull public static Object newProxyInstance(@Nullable ClassLoader, @NonNull Class<?>[], @NonNull java.lang.reflect.InvocationHandler) throws java.lang.IllegalArgumentException;
     field protected java.lang.reflect.InvocationHandler h;
   }
 
@@ -61438,7 +61448,7 @@
   }
 
   public interface TypeVariable<D extends java.lang.reflect.GenericDeclaration> extends java.lang.reflect.Type {
-    method public java.lang.reflect.Type[] getBounds();
+    method @NonNull public java.lang.reflect.Type[] getBounds();
     method @NonNull public D getGenericDeclaration();
     method @NonNull public String getName();
   }
@@ -61450,8 +61460,8 @@
   }
 
   public interface WildcardType extends java.lang.reflect.Type {
-    method public java.lang.reflect.Type[] getLowerBounds();
-    method public java.lang.reflect.Type[] getUpperBounds();
+    method @NonNull public java.lang.reflect.Type[] getLowerBounds();
+    method @NonNull public java.lang.reflect.Type[] getUpperBounds();
   }
 
 }
@@ -62495,7 +62505,7 @@
   public abstract class ByteBuffer extends java.nio.Buffer implements java.lang.Comparable<java.nio.ByteBuffer> {
     method @NonNull public static java.nio.ByteBuffer allocate(int);
     method @NonNull public static java.nio.ByteBuffer allocateDirect(int);
-    method public final byte[] array();
+    method @NonNull public final byte[] array();
     method public final int arrayOffset();
     method @NonNull public abstract java.nio.CharBuffer asCharBuffer();
     method @NonNull public abstract java.nio.DoubleBuffer asDoubleBuffer();
@@ -62509,8 +62519,8 @@
     method @NonNull public abstract java.nio.ByteBuffer duplicate();
     method public abstract byte get();
     method public abstract byte get(int);
-    method @NonNull public java.nio.ByteBuffer get(byte[], int, int);
-    method @NonNull public java.nio.ByteBuffer get(byte[]);
+    method @NonNull public java.nio.ByteBuffer get(@NonNull byte[], int, int);
+    method @NonNull public java.nio.ByteBuffer get(@NonNull byte[]);
     method public abstract char getChar();
     method public abstract char getChar(int);
     method public abstract double getDouble();
@@ -62529,8 +62539,8 @@
     method @NonNull public abstract java.nio.ByteBuffer put(byte);
     method @NonNull public abstract java.nio.ByteBuffer put(int, byte);
     method @NonNull public java.nio.ByteBuffer put(@NonNull java.nio.ByteBuffer);
-    method @NonNull public java.nio.ByteBuffer put(byte[], int, int);
-    method @NonNull public final java.nio.ByteBuffer put(byte[]);
+    method @NonNull public java.nio.ByteBuffer put(@NonNull byte[], int, int);
+    method @NonNull public final java.nio.ByteBuffer put(@NonNull byte[]);
     method @NonNull public abstract java.nio.ByteBuffer putChar(char);
     method @NonNull public abstract java.nio.ByteBuffer putChar(int, char);
     method @NonNull public abstract java.nio.ByteBuffer putDouble(double);
@@ -62544,8 +62554,8 @@
     method @NonNull public abstract java.nio.ByteBuffer putShort(short);
     method @NonNull public abstract java.nio.ByteBuffer putShort(int, short);
     method @NonNull public abstract java.nio.ByteBuffer slice();
-    method @NonNull public static java.nio.ByteBuffer wrap(byte[], int, int);
-    method @NonNull public static java.nio.ByteBuffer wrap(byte[]);
+    method @NonNull public static java.nio.ByteBuffer wrap(@NonNull byte[], int, int);
+    method @NonNull public static java.nio.ByteBuffer wrap(@NonNull byte[]);
   }
 
   public final class ByteOrder {
@@ -64378,20 +64388,20 @@
 
   public abstract class MessageDigest extends java.security.MessageDigestSpi {
     ctor protected MessageDigest(@NonNull String);
-    method public byte[] digest();
-    method public int digest(byte[], int, int) throws java.security.DigestException;
-    method public byte[] digest(byte[]);
+    method @NonNull public byte[] digest();
+    method public int digest(@NonNull byte[], int, int) throws java.security.DigestException;
+    method @NonNull public byte[] digest(@NonNull byte[]);
     method @NonNull public final String getAlgorithm();
     method public final int getDigestLength();
     method @NonNull public static java.security.MessageDigest getInstance(@NonNull String) throws java.security.NoSuchAlgorithmException;
     method @NonNull public static java.security.MessageDigest getInstance(@NonNull String, @NonNull String) throws java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException;
     method @NonNull public static java.security.MessageDigest getInstance(@NonNull String, @NonNull java.security.Provider) throws java.security.NoSuchAlgorithmException;
     method @NonNull public final java.security.Provider getProvider();
-    method public static boolean isEqual(byte[], byte[]);
+    method public static boolean isEqual(@Nullable byte[], @Nullable byte[]);
     method public void reset();
     method public void update(byte);
-    method public void update(byte[], int, int);
-    method public void update(byte[]);
+    method public void update(@NonNull byte[], int, int);
+    method public void update(@NonNull byte[]);
     method public final void update(@NonNull java.nio.ByteBuffer);
   }
 
@@ -66998,7 +67008,7 @@
     method @NonNull public final StringBuffer format(@NonNull Object, @NonNull StringBuffer, @NonNull java.text.FieldPosition);
     method @NonNull public abstract StringBuffer format(@NonNull java.util.Date, @NonNull StringBuffer, @NonNull java.text.FieldPosition);
     method @NonNull public final String format(@NonNull java.util.Date);
-    method public static java.util.Locale[] getAvailableLocales();
+    method @NonNull public static java.util.Locale[] getAvailableLocales();
     method @NonNull public java.util.Calendar getCalendar();
     method @NonNull public static final java.text.DateFormat getDateInstance();
     method @NonNull public static final java.text.DateFormat getDateInstance(int);
@@ -67238,7 +67248,7 @@
     method @NonNull public final String format(long);
     method @NonNull public abstract StringBuffer format(double, @NonNull StringBuffer, @NonNull java.text.FieldPosition);
     method @NonNull public abstract StringBuffer format(long, @NonNull StringBuffer, @NonNull java.text.FieldPosition);
-    method public static java.util.Locale[] getAvailableLocales();
+    method @NonNull public static java.util.Locale[] getAvailableLocales();
     method @Nullable public java.util.Currency getCurrency();
     method @NonNull public static final java.text.NumberFormat getCurrencyInstance();
     method @NonNull public static java.text.NumberFormat getCurrencyInstance(@NonNull java.util.Locale);
@@ -68892,8 +68902,8 @@
     method public boolean remove(@Nullable Object);
     method public boolean removeAll(@NonNull java.util.Collection<?>);
     method public boolean retainAll(@NonNull java.util.Collection<?>);
-    method public Object[] toArray();
-    method public <T> T[] toArray(T[]);
+    method @NonNull public Object[] toArray();
+    method @NonNull public <T> T[] toArray(@NonNull T[]);
   }
 
   public abstract class AbstractList<E> extends java.util.AbstractCollection<E> implements java.util.List<E> {
@@ -69002,161 +69012,161 @@
   }
 
   public class Arrays {
-    method @NonNull @java.lang.SafeVarargs public static <T> java.util.List<T> asList(T...);
-    method public static int binarySearch(long[], long);
-    method public static int binarySearch(long[], int, int, long);
-    method public static int binarySearch(int[], int);
-    method public static int binarySearch(int[], int, int, int);
-    method public static int binarySearch(short[], short);
-    method public static int binarySearch(short[], int, int, short);
-    method public static int binarySearch(char[], char);
-    method public static int binarySearch(char[], int, int, char);
-    method public static int binarySearch(byte[], byte);
-    method public static int binarySearch(byte[], int, int, byte);
-    method public static int binarySearch(double[], double);
-    method public static int binarySearch(double[], int, int, double);
-    method public static int binarySearch(float[], float);
-    method public static int binarySearch(float[], int, int, float);
-    method public static int binarySearch(Object[], @NonNull Object);
-    method public static int binarySearch(Object[], int, int, @NonNull Object);
-    method public static <T> int binarySearch(T[], T, @Nullable java.util.Comparator<? super T>);
-    method public static <T> int binarySearch(T[], int, int, T, @Nullable java.util.Comparator<? super T>);
-    method public static <T> T[] copyOf(T[], int);
-    method public static <T, U> T[] copyOf(U[], int, @NonNull Class<? extends T[]>);
-    method public static byte[] copyOf(byte[], int);
-    method public static short[] copyOf(short[], int);
-    method public static int[] copyOf(int[], int);
-    method public static long[] copyOf(long[], int);
-    method public static char[] copyOf(char[], int);
-    method public static float[] copyOf(float[], int);
-    method public static double[] copyOf(double[], int);
-    method public static boolean[] copyOf(boolean[], int);
-    method public static <T> T[] copyOfRange(T[], int, int);
-    method public static <T, U> T[] copyOfRange(U[], int, int, @NonNull Class<? extends T[]>);
-    method public static byte[] copyOfRange(byte[], int, int);
-    method public static short[] copyOfRange(short[], int, int);
-    method public static int[] copyOfRange(int[], int, int);
-    method public static long[] copyOfRange(long[], int, int);
-    method public static char[] copyOfRange(char[], int, int);
-    method public static float[] copyOfRange(float[], int, int);
-    method public static double[] copyOfRange(double[], int, int);
-    method public static boolean[] copyOfRange(boolean[], int, int);
-    method public static boolean deepEquals(Object[], Object[]);
-    method public static int deepHashCode(Object[]);
-    method @NonNull public static String deepToString(Object[]);
-    method public static boolean equals(long[], long[]);
-    method public static boolean equals(int[], int[]);
-    method public static boolean equals(short[], short[]);
-    method public static boolean equals(char[], char[]);
-    method public static boolean equals(byte[], byte[]);
-    method public static boolean equals(boolean[], boolean[]);
-    method public static boolean equals(double[], double[]);
-    method public static boolean equals(float[], float[]);
-    method public static boolean equals(Object[], Object[]);
-    method public static void fill(long[], long);
-    method public static void fill(long[], int, int, long);
-    method public static void fill(int[], int);
-    method public static void fill(int[], int, int, int);
-    method public static void fill(short[], short);
-    method public static void fill(short[], int, int, short);
-    method public static void fill(char[], char);
-    method public static void fill(char[], int, int, char);
-    method public static void fill(byte[], byte);
-    method public static void fill(byte[], int, int, byte);
-    method public static void fill(boolean[], boolean);
-    method public static void fill(boolean[], int, int, boolean);
-    method public static void fill(double[], double);
-    method public static void fill(double[], int, int, double);
-    method public static void fill(float[], float);
-    method public static void fill(float[], int, int, float);
-    method public static void fill(Object[], @Nullable Object);
-    method public static void fill(Object[], int, int, @Nullable Object);
-    method public static int hashCode(long[]);
-    method public static int hashCode(int[]);
-    method public static int hashCode(short[]);
-    method public static int hashCode(char[]);
-    method public static int hashCode(byte[]);
-    method public static int hashCode(boolean[]);
-    method public static int hashCode(float[]);
-    method public static int hashCode(double[]);
-    method public static int hashCode(Object[]);
-    method public static <T> void parallelPrefix(T[], @NonNull java.util.function.BinaryOperator<T>);
-    method public static <T> void parallelPrefix(T[], int, int, @NonNull java.util.function.BinaryOperator<T>);
-    method public static void parallelPrefix(long[], @NonNull java.util.function.LongBinaryOperator);
-    method public static void parallelPrefix(long[], int, int, @NonNull java.util.function.LongBinaryOperator);
-    method public static void parallelPrefix(double[], @NonNull java.util.function.DoubleBinaryOperator);
-    method public static void parallelPrefix(double[], int, int, @NonNull java.util.function.DoubleBinaryOperator);
-    method public static void parallelPrefix(int[], @NonNull java.util.function.IntBinaryOperator);
-    method public static void parallelPrefix(int[], int, int, @NonNull java.util.function.IntBinaryOperator);
-    method public static <T> void parallelSetAll(T[], @NonNull java.util.function.IntFunction<? extends T>);
-    method public static void parallelSetAll(int[], @NonNull java.util.function.IntUnaryOperator);
-    method public static void parallelSetAll(long[], @NonNull java.util.function.IntToLongFunction);
-    method public static void parallelSetAll(double[], @NonNull java.util.function.IntToDoubleFunction);
-    method public static void parallelSort(byte[]);
-    method public static void parallelSort(byte[], int, int);
-    method public static void parallelSort(char[]);
-    method public static void parallelSort(char[], int, int);
-    method public static void parallelSort(short[]);
-    method public static void parallelSort(short[], int, int);
-    method public static void parallelSort(int[]);
-    method public static void parallelSort(int[], int, int);
-    method public static void parallelSort(long[]);
-    method public static void parallelSort(long[], int, int);
-    method public static void parallelSort(float[]);
-    method public static void parallelSort(float[], int, int);
-    method public static void parallelSort(double[]);
-    method public static void parallelSort(double[], int, int);
-    method public static <T extends java.lang.Comparable<? super T>> void parallelSort(T[]);
-    method public static <T extends java.lang.Comparable<? super T>> void parallelSort(T[], int, int);
-    method public static <T> void parallelSort(T[], @Nullable java.util.Comparator<? super T>);
-    method public static <T> void parallelSort(T[], int, int, @Nullable java.util.Comparator<? super T>);
-    method public static <T> void setAll(T[], @NonNull java.util.function.IntFunction<? extends T>);
-    method public static void setAll(int[], @NonNull java.util.function.IntUnaryOperator);
-    method public static void setAll(long[], @NonNull java.util.function.IntToLongFunction);
-    method public static void setAll(double[], @NonNull java.util.function.IntToDoubleFunction);
-    method public static void sort(int[]);
-    method public static void sort(int[], int, int);
-    method public static void sort(long[]);
-    method public static void sort(long[], int, int);
-    method public static void sort(short[]);
-    method public static void sort(short[], int, int);
-    method public static void sort(char[]);
-    method public static void sort(char[], int, int);
-    method public static void sort(byte[]);
-    method public static void sort(byte[], int, int);
-    method public static void sort(float[]);
-    method public static void sort(float[], int, int);
-    method public static void sort(double[]);
-    method public static void sort(double[], int, int);
-    method public static void sort(Object[]);
-    method public static void sort(Object[], int, int);
-    method public static <T> void sort(T[], @Nullable java.util.Comparator<? super T>);
-    method public static <T> void sort(T[], int, int, @Nullable java.util.Comparator<? super T>);
-    method @NonNull public static <T> java.util.Spliterator<T> spliterator(T[]);
-    method @NonNull public static <T> java.util.Spliterator<T> spliterator(T[], int, int);
-    method @NonNull public static java.util.Spliterator.OfInt spliterator(int[]);
-    method @NonNull public static java.util.Spliterator.OfInt spliterator(int[], int, int);
-    method @NonNull public static java.util.Spliterator.OfLong spliterator(long[]);
-    method @NonNull public static java.util.Spliterator.OfLong spliterator(long[], int, int);
-    method @NonNull public static java.util.Spliterator.OfDouble spliterator(double[]);
-    method @NonNull public static java.util.Spliterator.OfDouble spliterator(double[], int, int);
-    method @NonNull public static <T> java.util.stream.Stream<T> stream(T[]);
-    method @NonNull public static <T> java.util.stream.Stream<T> stream(T[], int, int);
-    method @NonNull public static java.util.stream.IntStream stream(int[]);
-    method @NonNull public static java.util.stream.IntStream stream(int[], int, int);
-    method @NonNull public static java.util.stream.LongStream stream(long[]);
-    method @NonNull public static java.util.stream.LongStream stream(long[], int, int);
-    method @NonNull public static java.util.stream.DoubleStream stream(double[]);
-    method @NonNull public static java.util.stream.DoubleStream stream(double[], int, int);
-    method @NonNull public static String toString(long[]);
-    method @NonNull public static String toString(int[]);
-    method @NonNull public static String toString(short[]);
-    method @NonNull public static String toString(char[]);
-    method @NonNull public static String toString(byte[]);
-    method @NonNull public static String toString(boolean[]);
-    method @NonNull public static String toString(float[]);
-    method @NonNull public static String toString(double[]);
-    method @NonNull public static String toString(Object[]);
+    method @NonNull @java.lang.SafeVarargs public static <T> java.util.List<T> asList(@NonNull T...);
+    method public static int binarySearch(@NonNull long[], long);
+    method public static int binarySearch(@NonNull long[], int, int, long);
+    method public static int binarySearch(@NonNull int[], int);
+    method public static int binarySearch(@NonNull int[], int, int, int);
+    method public static int binarySearch(@NonNull short[], short);
+    method public static int binarySearch(@NonNull short[], int, int, short);
+    method public static int binarySearch(@NonNull char[], char);
+    method public static int binarySearch(@NonNull char[], int, int, char);
+    method public static int binarySearch(@NonNull byte[], byte);
+    method public static int binarySearch(@NonNull byte[], int, int, byte);
+    method public static int binarySearch(@NonNull double[], double);
+    method public static int binarySearch(@NonNull double[], int, int, double);
+    method public static int binarySearch(@NonNull float[], float);
+    method public static int binarySearch(@NonNull float[], int, int, float);
+    method public static int binarySearch(@NonNull Object[], @NonNull Object);
+    method public static int binarySearch(@NonNull Object[], int, int, @NonNull Object);
+    method public static <T> int binarySearch(@NonNull T[], T, @Nullable java.util.Comparator<? super T>);
+    method public static <T> int binarySearch(@NonNull T[], int, int, T, @Nullable java.util.Comparator<? super T>);
+    method @NonNull public static <T> T[] copyOf(@NonNull T[], int);
+    method @NonNull public static <T, U> T[] copyOf(@NonNull U[], int, @NonNull Class<? extends T[]>);
+    method @NonNull public static byte[] copyOf(@NonNull byte[], int);
+    method @NonNull public static short[] copyOf(@NonNull short[], int);
+    method @NonNull public static int[] copyOf(@NonNull int[], int);
+    method @NonNull public static long[] copyOf(@NonNull long[], int);
+    method @NonNull public static char[] copyOf(@NonNull char[], int);
+    method @NonNull public static float[] copyOf(@NonNull float[], int);
+    method @NonNull public static double[] copyOf(@NonNull double[], int);
+    method @NonNull public static boolean[] copyOf(@NonNull boolean[], int);
+    method @NonNull public static <T> T[] copyOfRange(@NonNull T[], int, int);
+    method @NonNull public static <T, U> T[] copyOfRange(@NonNull U[], int, int, @NonNull Class<? extends T[]>);
+    method @NonNull public static byte[] copyOfRange(@NonNull byte[], int, int);
+    method @NonNull public static short[] copyOfRange(@NonNull short[], int, int);
+    method @NonNull public static int[] copyOfRange(@NonNull int[], int, int);
+    method @NonNull public static long[] copyOfRange(@NonNull long[], int, int);
+    method @NonNull public static char[] copyOfRange(@NonNull char[], int, int);
+    method @NonNull public static float[] copyOfRange(@NonNull float[], int, int);
+    method @NonNull public static double[] copyOfRange(@NonNull double[], int, int);
+    method @NonNull public static boolean[] copyOfRange(@NonNull boolean[], int, int);
+    method public static boolean deepEquals(@Nullable Object[], @Nullable Object[]);
+    method public static int deepHashCode(@Nullable Object[]);
+    method @NonNull public static String deepToString(@Nullable Object[]);
+    method public static boolean equals(@Nullable long[], @Nullable long[]);
+    method public static boolean equals(@Nullable int[], @Nullable int[]);
+    method public static boolean equals(@Nullable short[], @Nullable short[]);
+    method public static boolean equals(@Nullable char[], @Nullable char[]);
+    method public static boolean equals(@Nullable byte[], @Nullable byte[]);
+    method public static boolean equals(@Nullable boolean[], @Nullable boolean[]);
+    method public static boolean equals(@Nullable double[], @Nullable double[]);
+    method public static boolean equals(@Nullable float[], @Nullable float[]);
+    method public static boolean equals(@Nullable Object[], @Nullable Object[]);
+    method public static void fill(@NonNull long[], long);
+    method public static void fill(@NonNull long[], int, int, long);
+    method public static void fill(@NonNull int[], int);
+    method public static void fill(@NonNull int[], int, int, int);
+    method public static void fill(@NonNull short[], short);
+    method public static void fill(@NonNull short[], int, int, short);
+    method public static void fill(@NonNull char[], char);
+    method public static void fill(@NonNull char[], int, int, char);
+    method public static void fill(@NonNull byte[], byte);
+    method public static void fill(@NonNull byte[], int, int, byte);
+    method public static void fill(@NonNull boolean[], boolean);
+    method public static void fill(@NonNull boolean[], int, int, boolean);
+    method public static void fill(@NonNull double[], double);
+    method public static void fill(@NonNull double[], int, int, double);
+    method public static void fill(@NonNull float[], float);
+    method public static void fill(@NonNull float[], int, int, float);
+    method public static void fill(@NonNull Object[], @Nullable Object);
+    method public static void fill(@NonNull Object[], int, int, @Nullable Object);
+    method public static int hashCode(@Nullable long[]);
+    method public static int hashCode(@Nullable int[]);
+    method public static int hashCode(@Nullable short[]);
+    method public static int hashCode(@Nullable char[]);
+    method public static int hashCode(@Nullable byte[]);
+    method public static int hashCode(@Nullable boolean[]);
+    method public static int hashCode(@Nullable float[]);
+    method public static int hashCode(@Nullable double[]);
+    method public static int hashCode(@Nullable Object[]);
+    method public static <T> void parallelPrefix(@NonNull T[], @NonNull java.util.function.BinaryOperator<T>);
+    method public static <T> void parallelPrefix(@NonNull T[], int, int, @NonNull java.util.function.BinaryOperator<T>);
+    method public static void parallelPrefix(@NonNull long[], @NonNull java.util.function.LongBinaryOperator);
+    method public static void parallelPrefix(@NonNull long[], int, int, @NonNull java.util.function.LongBinaryOperator);
+    method public static void parallelPrefix(@NonNull double[], @NonNull java.util.function.DoubleBinaryOperator);
+    method public static void parallelPrefix(@NonNull double[], int, int, @NonNull java.util.function.DoubleBinaryOperator);
+    method public static void parallelPrefix(@NonNull int[], @NonNull java.util.function.IntBinaryOperator);
+    method public static void parallelPrefix(@NonNull int[], int, int, @NonNull java.util.function.IntBinaryOperator);
+    method public static <T> void parallelSetAll(@NonNull T[], @NonNull java.util.function.IntFunction<? extends T>);
+    method public static void parallelSetAll(@NonNull int[], @NonNull java.util.function.IntUnaryOperator);
+    method public static void parallelSetAll(@NonNull long[], @NonNull java.util.function.IntToLongFunction);
+    method public static void parallelSetAll(@NonNull double[], @NonNull java.util.function.IntToDoubleFunction);
+    method public static void parallelSort(@NonNull byte[]);
+    method public static void parallelSort(@NonNull byte[], int, int);
+    method public static void parallelSort(@NonNull char[]);
+    method public static void parallelSort(@NonNull char[], int, int);
+    method public static void parallelSort(@NonNull short[]);
+    method public static void parallelSort(@NonNull short[], int, int);
+    method public static void parallelSort(@NonNull int[]);
+    method public static void parallelSort(@NonNull int[], int, int);
+    method public static void parallelSort(@NonNull long[]);
+    method public static void parallelSort(@NonNull long[], int, int);
+    method public static void parallelSort(@NonNull float[]);
+    method public static void parallelSort(@NonNull float[], int, int);
+    method public static void parallelSort(@NonNull double[]);
+    method public static void parallelSort(@NonNull double[], int, int);
+    method public static <T extends java.lang.Comparable<? super T>> void parallelSort(@NonNull T[]);
+    method public static <T extends java.lang.Comparable<? super T>> void parallelSort(@NonNull T[], int, int);
+    method public static <T> void parallelSort(@NonNull T[], @Nullable java.util.Comparator<? super T>);
+    method public static <T> void parallelSort(@NonNull T[], int, int, @Nullable java.util.Comparator<? super T>);
+    method public static <T> void setAll(@NonNull T[], @NonNull java.util.function.IntFunction<? extends T>);
+    method public static void setAll(@NonNull int[], @NonNull java.util.function.IntUnaryOperator);
+    method public static void setAll(@NonNull long[], @NonNull java.util.function.IntToLongFunction);
+    method public static void setAll(@NonNull double[], @NonNull java.util.function.IntToDoubleFunction);
+    method public static void sort(@NonNull int[]);
+    method public static void sort(@NonNull int[], int, int);
+    method public static void sort(@NonNull long[]);
+    method public static void sort(@NonNull long[], int, int);
+    method public static void sort(@NonNull short[]);
+    method public static void sort(@NonNull short[], int, int);
+    method public static void sort(@NonNull char[]);
+    method public static void sort(@NonNull char[], int, int);
+    method public static void sort(@NonNull byte[]);
+    method public static void sort(@NonNull byte[], int, int);
+    method public static void sort(@NonNull float[]);
+    method public static void sort(@NonNull float[], int, int);
+    method public static void sort(@NonNull double[]);
+    method public static void sort(@NonNull double[], int, int);
+    method public static void sort(@NonNull Object[]);
+    method public static void sort(@NonNull Object[], int, int);
+    method public static <T> void sort(@NonNull T[], @Nullable java.util.Comparator<? super T>);
+    method public static <T> void sort(@NonNull T[], int, int, @Nullable java.util.Comparator<? super T>);
+    method @NonNull public static <T> java.util.Spliterator<T> spliterator(@NonNull T[]);
+    method @NonNull public static <T> java.util.Spliterator<T> spliterator(@NonNull T[], int, int);
+    method @NonNull public static java.util.Spliterator.OfInt spliterator(@NonNull int[]);
+    method @NonNull public static java.util.Spliterator.OfInt spliterator(@NonNull int[], int, int);
+    method @NonNull public static java.util.Spliterator.OfLong spliterator(@NonNull long[]);
+    method @NonNull public static java.util.Spliterator.OfLong spliterator(@NonNull long[], int, int);
+    method @NonNull public static java.util.Spliterator.OfDouble spliterator(@NonNull double[]);
+    method @NonNull public static java.util.Spliterator.OfDouble spliterator(@NonNull double[], int, int);
+    method @NonNull public static <T> java.util.stream.Stream<T> stream(@NonNull T[]);
+    method @NonNull public static <T> java.util.stream.Stream<T> stream(@NonNull T[], int, int);
+    method @NonNull public static java.util.stream.IntStream stream(@NonNull int[]);
+    method @NonNull public static java.util.stream.IntStream stream(@NonNull int[], int, int);
+    method @NonNull public static java.util.stream.LongStream stream(@NonNull long[]);
+    method @NonNull public static java.util.stream.LongStream stream(@NonNull long[], int, int);
+    method @NonNull public static java.util.stream.DoubleStream stream(@NonNull double[]);
+    method @NonNull public static java.util.stream.DoubleStream stream(@NonNull double[], int, int);
+    method @NonNull public static String toString(@Nullable long[]);
+    method @NonNull public static String toString(@Nullable int[]);
+    method @NonNull public static String toString(@Nullable short[]);
+    method @NonNull public static String toString(@Nullable char[]);
+    method @NonNull public static String toString(@Nullable byte[]);
+    method @NonNull public static String toString(@Nullable boolean[]);
+    method @NonNull public static String toString(@Nullable float[]);
+    method @NonNull public static String toString(@Nullable double[]);
+    method @NonNull public static String toString(@Nullable Object[]);
   }
 
   public class Base64 {
@@ -69240,7 +69250,7 @@
     method public int getActualMaximum(int);
     method public int getActualMinimum(int);
     method @NonNull public static java.util.Set<java.lang.String> getAvailableCalendarTypes();
-    method public static java.util.Locale[] getAvailableLocales();
+    method @NonNull public static java.util.Locale[] getAvailableLocales();
     method @NonNull public String getCalendarType();
     method @Nullable public String getDisplayName(int, int, @NonNull java.util.Locale);
     method @Nullable public java.util.Map<java.lang.String,java.lang.Integer> getDisplayNames(int, int, @NonNull java.util.Locale);
@@ -69328,8 +69338,8 @@
     field public static final int YEAR = 1; // 0x1
     field public static final int ZONE_OFFSET = 15; // 0xf
     field protected boolean areFieldsSet;
-    field protected int[] fields;
-    field protected boolean[] isSet;
+    field @NonNull protected int[] fields;
+    field @NonNull protected boolean[] isSet;
     field protected boolean isTimeSet;
     field protected long time;
   }
@@ -69340,7 +69350,7 @@
     method @NonNull public java.util.Calendar.Builder set(int, int);
     method @NonNull public java.util.Calendar.Builder setCalendarType(@NonNull String);
     method @NonNull public java.util.Calendar.Builder setDate(int, int, int);
-    method @NonNull public java.util.Calendar.Builder setFields(int...);
+    method @NonNull public java.util.Calendar.Builder setFields(@NonNull int...);
     method @NonNull public java.util.Calendar.Builder setInstant(long);
     method @NonNull public java.util.Calendar.Builder setInstant(@NonNull java.util.Date);
     method @NonNull public java.util.Calendar.Builder setLenient(boolean);
@@ -69370,12 +69380,12 @@
     method public int size();
     method @NonNull public default java.util.Spliterator<E> spliterator();
     method @NonNull public default java.util.stream.Stream<E> stream();
-    method public Object[] toArray();
-    method public <T> T[] toArray(T[]);
+    method @NonNull public Object[] toArray();
+    method @NonNull public <T> T[] toArray(@NonNull T[]);
   }
 
   public class Collections {
-    method @java.lang.SafeVarargs public static <T> boolean addAll(@NonNull java.util.Collection<? super T>, T...);
+    method @java.lang.SafeVarargs public static <T> boolean addAll(@NonNull java.util.Collection<? super T>, @NonNull T...);
     method @NonNull public static <T> java.util.Queue<T> asLifoQueue(@NonNull java.util.Deque<T>);
     method public static <T> int binarySearch(@NonNull java.util.List<? extends java.lang.Comparable<? super T>>, @NonNull T);
     method public static <T> int binarySearch(@NonNull java.util.List<? extends T>, T, @Nullable java.util.Comparator<? super T>);
@@ -69893,7 +69903,7 @@
     method @NonNull public static java.util.List<java.lang.String> filterTags(@NonNull java.util.List<java.util.Locale.LanguageRange>, @NonNull java.util.Collection<java.lang.String>, @NonNull java.util.Locale.FilteringMode);
     method @NonNull public static java.util.List<java.lang.String> filterTags(@NonNull java.util.List<java.util.Locale.LanguageRange>, @NonNull java.util.Collection<java.lang.String>);
     method @NonNull public static java.util.Locale forLanguageTag(@NonNull String);
-    method public static java.util.Locale[] getAvailableLocales();
+    method @NonNull public static java.util.Locale[] getAvailableLocales();
     method @NonNull public String getCountry();
     method @NonNull public static java.util.Locale getDefault();
     method @NonNull public static java.util.Locale getDefault(@NonNull java.util.Locale.Category);
@@ -69911,8 +69921,8 @@
     method @NonNull public java.util.Set<java.lang.Character> getExtensionKeys();
     method @NonNull public String getISO3Country() throws java.util.MissingResourceException;
     method @NonNull public String getISO3Language() throws java.util.MissingResourceException;
-    method public static String[] getISOCountries();
-    method public static String[] getISOLanguages();
+    method @NonNull public static String[] getISOCountries();
+    method @NonNull public static String[] getISOLanguages();
     method @NonNull public String getLanguage();
     method @NonNull public String getScript();
     method @NonNull public java.util.Set<java.lang.String> getUnicodeLocaleAttributes();
@@ -70106,7 +70116,7 @@
     method public static <T> int compare(T, T, @NonNull java.util.Comparator<? super T>);
     method public static boolean deepEquals(@Nullable Object, @Nullable Object);
     method public static boolean equals(@Nullable Object, @Nullable Object);
-    method public static int hash(java.lang.Object...);
+    method public static int hash(@Nullable java.lang.Object...);
     method public static int hashCode(@Nullable Object);
     method public static boolean isNull(@Nullable Object);
     method public static boolean nonNull(@Nullable Object);
@@ -70771,7 +70781,7 @@
     method public void addElement(E);
     method public int capacity();
     method @NonNull public Object clone();
-    method public void copyInto(Object[]);
+    method public void copyInto(@NonNull Object[]);
     method public E elementAt(int);
     method @NonNull public java.util.Enumeration<E> elements();
     method public void ensureCapacity(int);
@@ -70791,7 +70801,7 @@
     method public void trimToSize();
     field protected int capacityIncrement;
     field protected int elementCount;
-    field protected Object[] elementData;
+    field @NonNull protected Object[] elementData;
   }
 
   public class WeakHashMap<K, V> extends java.util.AbstractMap<K,V> implements java.util.Map<K,V> {
@@ -71182,7 +71192,7 @@
   public class CopyOnWriteArrayList<E> implements java.lang.Cloneable java.util.List<E> java.util.RandomAccess java.io.Serializable {
     ctor public CopyOnWriteArrayList();
     ctor public CopyOnWriteArrayList(@NonNull java.util.Collection<? extends E>);
-    ctor public CopyOnWriteArrayList(E[]);
+    ctor public CopyOnWriteArrayList(@NonNull E[]);
     method public boolean add(E);
     method public void add(int, E);
     method public boolean addAll(@NonNull java.util.Collection<? extends E>);
@@ -71210,8 +71220,8 @@
     method public E set(int, E);
     method public int size();
     method @NonNull public java.util.List<E> subList(int, int);
-    method public Object[] toArray();
-    method public <T> T[] toArray(T[]);
+    method @NonNull public Object[] toArray();
+    method @NonNull public <T> T[] toArray(@NonNull T[]);
   }
 
   public class CopyOnWriteArraySet<E> extends java.util.AbstractSet<E> implements java.io.Serializable {
@@ -72963,7 +72973,7 @@
     method public void config(@NonNull java.util.function.Supplier<java.lang.String>);
     method public void entering(@Nullable String, @Nullable String);
     method public void entering(@Nullable String, @Nullable String, @Nullable Object);
-    method public void entering(@Nullable String, @Nullable String, Object[]);
+    method public void entering(@Nullable String, @Nullable String, @Nullable Object[]);
     method public void exiting(@Nullable String, @Nullable String);
     method public void exiting(@Nullable String, @Nullable String, @Nullable Object);
     method public void fine(@Nullable String);
@@ -72976,7 +72986,7 @@
     method @NonNull public static java.util.logging.Logger getAnonymousLogger(@Nullable String);
     method @Nullable public java.util.logging.Filter getFilter();
     method @NonNull public static final java.util.logging.Logger getGlobal();
-    method public java.util.logging.Handler[] getHandlers();
+    method @NonNull public java.util.logging.Handler[] getHandlers();
     method @Nullable public java.util.logging.Level getLevel();
     method @NonNull public static java.util.logging.Logger getLogger(@NonNull String);
     method @NonNull public static java.util.logging.Logger getLogger(@NonNull String, @Nullable String);
@@ -72992,7 +73002,7 @@
     method public void log(@NonNull java.util.logging.Level, @Nullable String);
     method public void log(@NonNull java.util.logging.Level, @NonNull java.util.function.Supplier<java.lang.String>);
     method public void log(@NonNull java.util.logging.Level, @Nullable String, @Nullable Object);
-    method public void log(@NonNull java.util.logging.Level, @Nullable String, Object[]);
+    method public void log(@NonNull java.util.logging.Level, @Nullable String, @Nullable Object[]);
     method public void log(@NonNull java.util.logging.Level, @Nullable String, @Nullable Throwable);
     method public void log(@NonNull java.util.logging.Level, @Nullable Throwable, @NonNull java.util.function.Supplier<java.lang.String>);
     method public void logp(@NonNull java.util.logging.Level, @Nullable String, @Nullable String, @Nullable String);
@@ -73003,8 +73013,8 @@
     method public void logp(@NonNull java.util.logging.Level, @Nullable String, @Nullable String, @Nullable Throwable, @NonNull java.util.function.Supplier<java.lang.String>);
     method @Deprecated public void logrb(@NonNull java.util.logging.Level, @Nullable String, @Nullable String, @Nullable String, @Nullable String);
     method @Deprecated public void logrb(@NonNull java.util.logging.Level, @Nullable String, @Nullable String, @Nullable String, @Nullable String, @Nullable Object);
-    method @Deprecated public void logrb(@NonNull java.util.logging.Level, @Nullable String, @Nullable String, @Nullable String, @Nullable String, Object[]);
-    method public void logrb(@NonNull java.util.logging.Level, @Nullable String, @Nullable String, @Nullable java.util.ResourceBundle, @Nullable String, java.lang.Object...);
+    method @Deprecated public void logrb(@NonNull java.util.logging.Level, @Nullable String, @Nullable String, @Nullable String, @Nullable String, @Nullable Object[]);
+    method public void logrb(@NonNull java.util.logging.Level, @Nullable String, @Nullable String, @Nullable java.util.ResourceBundle, @Nullable String, @Nullable java.lang.Object...);
     method @Deprecated public void logrb(@NonNull java.util.logging.Level, @Nullable String, @Nullable String, @Nullable String, @Nullable String, @Nullable Throwable);
     method public void logrb(@NonNull java.util.logging.Level, @Nullable String, @Nullable String, @Nullable java.util.ResourceBundle, @Nullable String, @Nullable Throwable);
     method public void removeHandler(@Nullable java.util.logging.Handler) throws java.lang.SecurityException;
@@ -73266,8 +73276,8 @@
     method public static boolean matches(@NonNull String, @NonNull CharSequence);
     method @NonNull public String pattern();
     method @NonNull public static String quote(@NonNull String);
-    method public String[] split(@NonNull CharSequence, int);
-    method public String[] split(@NonNull CharSequence);
+    method @NonNull public String[] split(@NonNull CharSequence, int);
+    method @NonNull public String[] split(@NonNull CharSequence);
     method @NonNull public java.util.stream.Stream<java.lang.String> splitAsStream(@NonNull CharSequence);
     field public static final int CANON_EQ = 128; // 0x80
     field public static final int CASE_INSENSITIVE = 2; // 0x2
diff --git a/api/system-current.txt b/api/system-current.txt
index e7c7b57..19b3f0e 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -1718,9 +1718,9 @@
   public final class RollbackInfo implements android.os.Parcelable {
     method public int describeContents();
     method public java.util.List<android.content.pm.VersionedPackage> getCausePackages();
+    method public int getCommittedSessionId();
     method public java.util.List<android.content.rollback.PackageRollbackInfo> getPackages();
     method public int getRollbackId();
-    method public int getSessionId();
     method public boolean isStaged();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.content.rollback.RollbackInfo> CREATOR;
@@ -9404,17 +9404,6 @@
     method public void setContentCaptureFeatureEnabled(boolean);
   }
 
-  public final class UserDataRemovalRequest implements android.os.Parcelable {
-    method @NonNull public String getPackageName();
-    method @NonNull public java.util.List<android.view.contentcapture.UserDataRemovalRequest.UriRequest> getUriRequests();
-    method public boolean isForEverything();
-  }
-
-  public final class UserDataRemovalRequest.UriRequest {
-    method @NonNull public android.net.Uri getUri();
-    method @NonNull public boolean isRecursive();
-  }
-
   public final class ViewNode extends android.app.assist.AssistStructure.ViewNode {
     method @Nullable public android.view.autofill.AutofillId getParentAutofillId();
   }
diff --git a/cmds/statsd/src/external/StatsCompanionServicePuller.cpp b/cmds/statsd/src/external/StatsCompanionServicePuller.cpp
index 4e4b8f3..f37d2be 100644
--- a/cmds/statsd/src/external/StatsCompanionServicePuller.cpp
+++ b/cmds/statsd/src/external/StatsCompanionServicePuller.cpp
@@ -55,6 +55,10 @@
         Status status = statsCompanionServiceCopy->pullData(mTagId, &returned_value);
         if (!status.isOk()) {
             ALOGW("StatsCompanionServicePuller::pull failed for %d", mTagId);
+            StatsdStats::getInstance().noteStatsCompanionPullFailed(mTagId);
+            if (status.exceptionCode() == Status::Exception::EX_TRANSACTION_FAILED) {
+                StatsdStats::getInstance().noteStatsCompanionPullBinderTransactionFailed(mTagId);
+            }
             return false;
         }
         data->clear();
diff --git a/cmds/statsd/src/external/StatsPullerManager.cpp b/cmds/statsd/src/external/StatsPullerManager.cpp
index ba7bcc4..a6ba2ca 100644
--- a/cmds/statsd/src/external/StatsPullerManager.cpp
+++ b/cmds/statsd/src/external/StatsPullerManager.cpp
@@ -231,6 +231,9 @@
     if (kAllPullAtomInfo.find(tagId) != kAllPullAtomInfo.end()) {
         bool ret = kAllPullAtomInfo.find(tagId)->second.puller->Pull(data);
         VLOG("pulled %d items", (int)data->size());
+        if (!ret) {
+            StatsdStats::getInstance().notePullFailed(tagId);
+        }
         return ret;
     } else {
         VLOG("Unknown tagId %d", tagId);
diff --git a/cmds/statsd/src/guardrail/StatsdStats.cpp b/cmds/statsd/src/guardrail/StatsdStats.cpp
index f4d0144..37ccad5 100644
--- a/cmds/statsd/src/guardrail/StatsdStats.cpp
+++ b/cmds/statsd/src/guardrail/StatsdStats.cpp
@@ -403,6 +403,60 @@
     mSystemServerRestartSec.push_back(timeSec);
 }
 
+void StatsdStats::notePullFailed(int atomId) {
+    lock_guard<std::mutex> lock(mLock);
+    mPulledAtomStats[atomId].pullFailed++;
+}
+
+void StatsdStats::noteStatsCompanionPullFailed(int atomId) {
+    lock_guard<std::mutex> lock(mLock);
+    mPulledAtomStats[atomId].statsCompanionPullFailed++;
+}
+
+void StatsdStats::noteStatsCompanionPullBinderTransactionFailed(int atomId) {
+    lock_guard<std::mutex> lock(mLock);
+    mPulledAtomStats[atomId].statsCompanionPullBinderTransactionFailed++;
+}
+
+void StatsdStats::noteEmptyData(int atomId) {
+    lock_guard<std::mutex> lock(mLock);
+    mPulledAtomStats[atomId].emptyData++;
+}
+
+void StatsdStats::noteHardDimensionLimitReached(int metricId) {
+    lock_guard<std::mutex> lock(mLock);
+    getAtomMetricStats(metricId).hardDimensionLimitReached++;
+}
+
+void StatsdStats::noteLateLogEventSkipped(int metricId) {
+    lock_guard<std::mutex> lock(mLock);
+    getAtomMetricStats(metricId).lateLogEventSkipped++;
+}
+
+void StatsdStats::noteSkippedForwardBuckets(int metricId) {
+    lock_guard<std::mutex> lock(mLock);
+    getAtomMetricStats(metricId).skippedForwardBuckets++;
+}
+
+void StatsdStats::noteBadValueType(int metricId) {
+    lock_guard<std::mutex> lock(mLock);
+    getAtomMetricStats(metricId).badValueType++;
+}
+
+void StatsdStats::noteConditionChangeInNextBucket(int metricId) {
+    lock_guard<std::mutex> lock(mLock);
+    getAtomMetricStats(metricId).conditionChangeInNextBucket++;
+}
+
+StatsdStats::AtomMetricStats& StatsdStats::getAtomMetricStats(int metricId) {
+    auto atomMetricStatsIter = mAtomMetricStats.find(metricId);
+    if (atomMetricStatsIter != mAtomMetricStats.end()) {
+        return atomMetricStatsIter->second;
+    }
+    auto emplaceResult = mAtomMetricStats.emplace(metricId, AtomMetricStats());
+    return emplaceResult.first->second;
+}
+
 void StatsdStats::reset() {
     lock_guard<std::mutex> lock(mLock);
     resetInternalLocked();
@@ -442,6 +496,7 @@
         pullStats.second.pullTimeout = 0;
         pullStats.second.pullExceedMaxDelay = 0;
     }
+    mAtomMetricStats.clear();
 }
 
 string buildTimeString(int64_t timeSec) {
@@ -713,6 +768,10 @@
         android::os::statsd::writePullerStatsToStream(pair, &proto);
     }
 
+    for (const auto& pair : mAtomMetricStats) {
+        android::os::statsd::writeAtomMetricStatsToStream(pair, &proto);
+    }
+
     if (mAnomalyAlarmRegisteredStats > 0) {
         uint64_t token = proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_ANOMALY_ALARM_STATS);
         proto.write(FIELD_TYPE_INT32 | FIELD_ID_ANOMALY_ALARMS_REGISTERED,
diff --git a/cmds/statsd/src/guardrail/StatsdStats.h b/cmds/statsd/src/guardrail/StatsdStats.h
index dc647f8..01e9ca1 100644
--- a/cmds/statsd/src/guardrail/StatsdStats.h
+++ b/cmds/statsd/src/guardrail/StatsdStats.h
@@ -318,6 +318,53 @@
     void noteLogLost(int32_t wallClockTimeSec, int32_t count, int lastError);
 
     /**
+     * Records that the pull of an atom has failed
+     */
+    void notePullFailed(int atomId);
+
+    /**
+     * Records that the pull of StatsCompanionService atom has failed
+     */
+    void noteStatsCompanionPullFailed(int atomId);
+
+    /**
+     * Records that the pull of a StatsCompanionService atom has failed due to a failed binder
+     * transaction. This can happen when StatsCompanionService returns too
+     * much data (the max Binder parcel size is 1MB)
+     */
+    void noteStatsCompanionPullBinderTransactionFailed(int atomId);
+
+    /**
+     * A pull with no data occurred
+     */
+    void noteEmptyData(int atomId);
+
+    /**
+     * Hard limit was reached in the cardinality of an atom
+     */
+    void noteHardDimensionLimitReached(int atomId);
+
+    /**
+     * A log event was too late, arrived in the wrong bucket and was skipped
+     */
+    void noteLateLogEventSkipped(int atomId);
+
+    /**
+     * Buckets were skipped as time elapsed without any data for them
+     */
+    void noteSkippedForwardBuckets(int atomId);
+
+    /**
+     * An unsupported value type was received
+     */
+    void noteBadValueType(int atomId);
+
+    /**
+     * A condition change was too late, arrived in the wrong bucket and was skipped
+     */
+    void noteConditionChangeInNextBucket(int atomId);
+
+    /**
      * Reset the historical stats. Including all stats in icebox, and the tracked stats about
      * metrics, matchers, and atoms. The active configs will be kept and StatsdStats will continue
      * to collect stats after reset() has been called.
@@ -349,8 +396,20 @@
         long dataError = 0;
         long pullTimeout = 0;
         long pullExceedMaxDelay = 0;
+        long pullFailed = 0;
+        long statsCompanionPullFailed = 0;
+        long statsCompanionPullBinderTransactionFailed = 0;
+        long emptyData = 0;
     } PulledAtomStats;
 
+    typedef struct {
+        long hardDimensionLimitReached = 0;
+        long lateLogEventSkipped = 0;
+        long skippedForwardBuckets = 0;
+        long badValueType = 0;
+        long conditionChangeInNextBucket = 0;
+    } AtomMetricStats;
+
 private:
     StatsdStats();
 
@@ -378,6 +437,9 @@
     // Maps PullAtomId to its stats. The size is capped by the puller atom counts.
     std::map<int, PulledAtomStats> mPulledAtomStats;
 
+    // Maps metric ID to its stats. The size is capped by the number of metrics.
+    std::map<int, AtomMetricStats> mAtomMetricStats;
+
     struct LogLossStats {
         LogLossStats(int32_t sec, int32_t count, int32_t error)
             : mWallClockSec(sec), mCount(count), mLastError(error) {
@@ -414,6 +476,12 @@
 
     void addToIceBoxLocked(std::shared_ptr<ConfigStats>& stats);
 
+    /**
+     * Get a reference to AtomMetricStats for a metric. If none exists, create it. The reference
+     * will live as long as `this`.
+     */
+    StatsdStats::AtomMetricStats& getAtomMetricStats(int metricId);
+
     FRIEND_TEST(StatsdStatsTest, TestValidConfigAdd);
     FRIEND_TEST(StatsdStatsTest, TestInvalidConfigAdd);
     FRIEND_TEST(StatsdStatsTest, TestConfigRemove);
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.cpp b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
index 5645461..6aa8e84 100644
--- a/cmds/statsd/src/metrics/ValueMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
@@ -322,6 +322,7 @@
     if (eventTimeNs < mCurrentBucketStartTimeNs) {
         VLOG("Skip event due to late arrival: %lld vs %lld", (long long)eventTimeNs,
              (long long)mCurrentBucketStartTimeNs);
+        StatsdStats::getInstance().noteConditionChangeInNextBucket(mMetricId);
         return;
     }
 
@@ -359,6 +360,12 @@
     }
     StatsdStats::getInstance().notePullDelay(mPullTagId, pullDelayNs);
 
+    if (timestampNs < mCurrentBucketStartTimeNs) {
+        // The data will be skipped in onMatchedLogEventInternalLocked, but we don't want to report
+        // for every event, just the pull
+        StatsdStats::getInstance().noteLateLogEventSkipped(mMetricId);
+    }
+
     for (const auto& data : allData) {
         // make a copy before doing and changes
         LogEvent localCopy = data->makeCopy();
@@ -380,6 +387,7 @@
     if (mCondition) {
         if (allData.size() == 0) {
             VLOG("Data pulled is empty");
+            StatsdStats::getInstance().noteEmptyData(mPullTagId);
             return;
         }
         // For scheduled pulled data, the effective event time is snap to the nearest
@@ -394,6 +402,7 @@
         if (bucketEndTime < mCurrentBucketStartTimeNs) {
             VLOG("Skip bucket end pull due to late arrival: %lld vs %lld", (long long)bucketEndTime,
                  (long long)mCurrentBucketStartTimeNs);
+            StatsdStats::getInstance().noteLateLogEventSkipped(mMetricId);
             return;
         }
         for (const auto& data : allData) {
@@ -442,6 +451,7 @@
         if (newTupleCount > mDimensionHardLimit) {
             ALOGE("ValueMetric %lld dropping data for dimension key %s", (long long)mMetricId,
                   newKey.toString().c_str());
+            StatsdStats::getInstance().noteHardDimensionLimitReached(mMetricId);
             return true;
         }
     }
@@ -539,6 +549,7 @@
         Value value;
         if (!getDoubleOrLong(event, matcher, value)) {
             VLOG("Failed to get value %d from event %s", i, event.ToString().c_str());
+            StatsdStats::getInstance().noteBadValueType(mMetricId);
             return;
         }
         interval.seenNewData = true;
@@ -656,6 +667,7 @@
 
     if (numBucketsForward > 1) {
         VLOG("Skipping forward %lld buckets", (long long)numBucketsForward);
+        StatsdStats::getInstance().noteSkippedForwardBuckets(mMetricId);
         // take base again in future good bucket.
         resetBase();
     }
diff --git a/cmds/statsd/src/stats_log.proto b/cmds/statsd/src/stats_log.proto
index e8de875..cca09ac 100644
--- a/cmds/statsd/src/stats_log.proto
+++ b/cmds/statsd/src/stats_log.proto
@@ -403,9 +403,23 @@
         optional int64 data_error = 9;
         optional int64 pull_timeout = 10;
         optional int64 pull_exceed_max_delay = 11;
+        optional int64 pull_failed = 12;
+        optional int64 stats_companion_pull_failed = 13;
+        optional int64 stats_companion_pull_binder_transaction_failed = 14;
+        optional int64 empty_data = 15;
     }
     repeated PulledAtomStats pulled_atom_stats = 10;
 
+    message AtomMetricStats {
+      optional int64 metric_id = 1;
+      optional int64 hard_dimension_limit_reached = 2;
+      optional int64 late_log_event_skipped = 3;
+      optional int64 skipped_forward_buckets = 4;
+      optional int64 bad_value_type = 5;
+      optional int64 condition_change_in_next_bucket = 6;
+    }
+    repeated AtomMetricStats atom_metric_stats = 17;
+
     message LoggerErrorStats {
         optional int32 logger_disconnection_sec = 1;
         optional int32 error_code = 2;
diff --git a/cmds/statsd/src/stats_log_util.cpp b/cmds/statsd/src/stats_log_util.cpp
index 7de0bb3..9c9985e 100644
--- a/cmds/statsd/src/stats_log_util.cpp
+++ b/cmds/statsd/src/stats_log_util.cpp
@@ -66,6 +66,18 @@
 const int FIELD_ID_DATA_ERROR = 9;
 const int FIELD_ID_PULL_TIMEOUT = 10;
 const int FIELD_ID_PULL_EXCEED_MAX_DELAY = 11;
+const int FIELD_ID_PULL_FAILED = 12;
+const int FIELD_ID_STATS_COMPANION_FAILED = 13;
+const int FIELD_ID_STATS_COMPANION_BINDER_TRANSACTION_FAILED = 14;
+const int FIELD_ID_EMPTY_DATA = 15;
+// for AtomMetricStats proto
+const int FIELD_ID_ATOM_METRIC_STATS = 17;
+const int FIELD_ID_METRIC_ID = 1;
+const int FIELD_ID_HARD_DIMENSION_LIMIT_REACHED = 2;
+const int FIELD_ID_LATE_LOG_EVENT_SKIPPED = 3;
+const int FIELD_ID_SKIPPED_FORWARD_BUCKETS = 4;
+const int FIELD_ID_BAD_VALUE_TYPE = 5;
+const int FIELD_ID_CONDITION_CHANGE_IN_NEXT_BUCKET = 6;
 
 namespace {
 
@@ -456,6 +468,32 @@
                        (long long)pair.second.pullTimeout);
     protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_PULL_EXCEED_MAX_DELAY,
                        (long long)pair.second.pullExceedMaxDelay);
+    protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_PULL_FAILED,
+                       (long long)pair.second.pullFailed);
+    protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_STATS_COMPANION_FAILED,
+                       (long long)pair.second.statsCompanionPullFailed);
+    protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_STATS_COMPANION_BINDER_TRANSACTION_FAILED,
+                       (long long)pair.second.statsCompanionPullBinderTransactionFailed);
+    protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_EMPTY_DATA,
+                       (long long)pair.second.emptyData);
+    protoOutput->end(token);
+}
+
+void writeAtomMetricStatsToStream(const std::pair<int, StatsdStats::AtomMetricStats> &pair,
+                                  util::ProtoOutputStream *protoOutput) {
+    uint64_t token = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_ID_ATOM_METRIC_STATS |
+                                        FIELD_COUNT_REPEATED);
+    protoOutput->write(FIELD_TYPE_INT32 | FIELD_ID_METRIC_ID, (int32_t)pair.first);
+    protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_HARD_DIMENSION_LIMIT_REACHED,
+                       (long long)pair.second.hardDimensionLimitReached);
+    protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_LATE_LOG_EVENT_SKIPPED,
+                       (long long)pair.second.lateLogEventSkipped);
+    protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_SKIPPED_FORWARD_BUCKETS,
+                       (long long)pair.second.skippedForwardBuckets);
+    protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_BAD_VALUE_TYPE,
+                       (long long)pair.second.badValueType);
+    protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_CONDITION_CHANGE_IN_NEXT_BUCKET,
+                       (long long)pair.second.conditionChangeInNextBucket);
     protoOutput->end(token);
 }
 
diff --git a/cmds/statsd/src/stats_log_util.h b/cmds/statsd/src/stats_log_util.h
index 61f31eb..dcea0e6 100644
--- a/cmds/statsd/src/stats_log_util.h
+++ b/cmds/statsd/src/stats_log_util.h
@@ -73,6 +73,10 @@
 void writePullerStatsToStream(const std::pair<int, StatsdStats::PulledAtomStats>& pair,
                               util::ProtoOutputStream* protoOutput);
 
+// Helper function to write AtomMetricStats to ProtoOutputStream
+void writeAtomMetricStatsToStream(const std::pair<int, StatsdStats::AtomMetricStats> &pair,
+                                  util::ProtoOutputStream *protoOutput);
+
 template<class T>
 bool parseProtoOutputStream(util::ProtoOutputStream& protoOutput, T* message) {
     std::string pbBytes;
diff --git a/config/hiddenapi-greylist.txt b/config/hiddenapi-greylist.txt
index 8e7a58b..a748959 100644
--- a/config/hiddenapi-greylist.txt
+++ b/config/hiddenapi-greylist.txt
@@ -1942,7 +1942,6 @@
 Lcom/android/internal/R$id;->titleDivider:I
 Lcom/android/internal/R$id;->titleDividerTop:I
 Lcom/android/internal/R$id;->title_container:I
-Lcom/android/internal/R$id;->title_icon:I
 Lcom/android/internal/R$id;->title_template:I
 Lcom/android/internal/R$id;->topPanel:I
 Lcom/android/internal/R$id;->up:I
diff --git a/core/java/android/app/ActivityView.java b/core/java/android/app/ActivityView.java
index ce5d8a5..eae7d6b 100644
--- a/core/java/android/app/ActivityView.java
+++ b/core/java/android/app/ActivityView.java
@@ -28,15 +28,12 @@
 import android.content.Intent;
 import android.hardware.display.DisplayManager;
 import android.hardware.display.VirtualDisplay;
-import android.hardware.input.InputManager;
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.util.AttributeSet;
 import android.util.DisplayMetrics;
 import android.util.Log;
 import android.view.IWindowManager;
-import android.view.InputDevice;
-import android.view.MotionEvent;
 import android.view.SurfaceControl;
 import android.view.SurfaceHolder;
 import android.view.SurfaceSession;
@@ -51,9 +48,7 @@
 import java.util.List;
 
 /**
- * Activity container that allows launching activities into itself and does input forwarding.
- * <p>Creation of this view is only allowed to callers who have
- * {@link android.Manifest.permission#INJECT_EVENTS} permission.
+ * Activity container that allows launching activities into itself.
  * <p>Activity launching into this container is restricted by the same rules that apply to launching
  * on VirtualDisplays.
  * @hide
@@ -76,9 +71,8 @@
     private StateCallback mActivityViewCallback;
 
     private IActivityTaskManager mActivityTaskManager;
-    private IInputForwarder mInputForwarder;
-    // Temp container to store view coordinates on screen.
-    private final int[] mLocationOnScreen = new int[2];
+    // Temp container to store view coordinates in window.
+    private final int[] mLocationInWindow = new int[2];
 
     private TaskStackListener mTaskStackListener;
 
@@ -280,7 +274,7 @@
     }
 
     /**
-     * Triggers an update of {@link ActivityView}'s location on screen to properly set touch exclude
+     * Triggers an update of {@link ActivityView}'s location in window to properly set touch exclude
      * regions and avoid focus switches by touches on this view.
      */
     public void onLocationChanged() {
@@ -295,45 +289,14 @@
     /** Send current location and size to the WM to set tap exclude region for this view. */
     private void updateLocation() {
         try {
-            getLocationOnScreen(mLocationOnScreen);
+            getLocationInWindow(mLocationInWindow);
             WindowManagerGlobal.getWindowSession().updateTapExcludeRegion(getWindow(), hashCode(),
-                    mLocationOnScreen[0], mLocationOnScreen[1], getWidth(), getHeight());
+                    mLocationInWindow[0], mLocationInWindow[1], getWidth(), getHeight());
         } catch (RemoteException e) {
             e.rethrowAsRuntimeException();
         }
     }
 
-    @Override
-    public boolean onTouchEvent(MotionEvent event) {
-        return injectInputEvent(event) || super.onTouchEvent(event);
-    }
-
-    @Override
-    public boolean onGenericMotionEvent(MotionEvent event) {
-        if (event.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) {
-            if (injectInputEvent(event)) {
-                return true;
-            }
-        }
-        return super.onGenericMotionEvent(event);
-    }
-
-    private boolean injectInputEvent(MotionEvent event) {
-        if (mInputForwarder != null) {
-            try {
-                // The touch event that the ActivityView gets is in View space, but the event needs
-                // to get forwarded in screen space. This offsets the touch event by the location
-                // the ActivityView is on screen and sends it to the input forwarder.
-                getLocationOnScreen(mLocationOnScreen);
-                event.offsetLocation(mLocationOnScreen[0], mLocationOnScreen[1]);
-                return mInputForwarder.forwardEvent(event);
-            } catch (RemoteException e) {
-                e.rethrowAsRuntimeException();
-            }
-        }
-        return false;
-    }
-
     private class SurfaceCallback implements SurfaceHolder.Callback {
         @Override
         public void surfaceCreated(SurfaceHolder surfaceHolder) {
@@ -416,7 +379,6 @@
         }
 
         mTmpTransaction.show(mRootSurfaceControl).apply();
-        mInputForwarder = InputManager.getInstance().createInputForwarder(displayId);
         mTaskStackListener = new TaskStackListenerImpl();
         try {
             mActivityTaskManager.registerTaskStackListener(mTaskStackListener);
@@ -432,9 +394,6 @@
 
         mSurfaceView.getHolder().removeCallback(mSurfaceCallback);
 
-        if (mInputForwarder != null) {
-            mInputForwarder = null;
-        }
         cleanTapExcludeRegion();
 
         if (mTaskStackListener != null) {
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index 8953940..ec78428 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -65,6 +65,9 @@
     boolean areNotificationsEnabled(String pkg);
     int getPackageImportance(String pkg);
 
+    boolean shouldHideSilentStatusIcons(String callingPkg);
+    void setHideSilentStatusIcons(boolean hide);
+
     void setBubblesAllowed(String pkg, int uid, boolean allowed);
     boolean areBubblesAllowed(String pkg);
     boolean areBubblesAllowedForPackage(String pkg, int uid);
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index 621f134..587b591 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -20,6 +20,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SdkConstant;
+import android.annotation.SystemApi;
 import android.annotation.SystemService;
 import android.annotation.TestApi;
 import android.annotation.UnsupportedAppUsage;
@@ -353,7 +354,8 @@
     public static final int IMPORTANCE_MIN = 1;
 
     /**
-     * Low notification importance: shows everywhere, but is not intrusive.
+     * Low notification importance: Shows in the shade, and potentially in the status bar
+     * (see {@link #shouldHideSilentStatusBarIcons()}), but is not audibly intrusive.
      */
     public static final int IMPORTANCE_LOW = 2;
 
@@ -1162,6 +1164,22 @@
         }
     }
 
+    /**
+     * Returns whether the user wants silent notifications (see {@link #IMPORTANCE_LOW} to appear
+     * in the status bar.
+     *
+     * <p>Only available for {@link #isNotificationListenerAccessGranted(ComponentName) notification
+     * listeners}.
+     */
+    public boolean shouldHideSilentStatusBarIcons() {
+        INotificationManager service = getService();
+        try {
+            return service.shouldHideSilentStatusIcons(mContext.getOpPackageName());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
     /** @hide */
     public boolean isNotificationPolicyAccessGrantedForPackage(String pkg) {
         INotificationManager service = getService();
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 65ea635..a3021f3 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -971,7 +971,8 @@
      *
      * @param target The Intent that the user will be selecting an activity
      * to perform.
-     * @param title Optional title that will be displayed in the chooser.
+     * @param title Optional title that will be displayed in the chooser,
+     * only when the target action is not ACTION_SEND or ACTION_SEND_MULTIPLE.
      * @return Return a new Intent object that you can hand to
      * {@link Context#startActivity(Intent) Context.startActivity()} and
      * related methods.
@@ -998,7 +999,8 @@
      *
      * @param target The Intent that the user will be selecting an activity
      * to perform.
-     * @param title Optional title that will be displayed in the chooser.
+     * @param title Optional title that will be displayed in the chooser,
+     * only when the target action is not ACTION_SEND or ACTION_SEND_MULTIPLE.
      * @param sender Optional IntentSender to be called when a choice is made.
      * @return Return a new Intent object that you can hand to
      * {@link Context#startActivity(Intent) Context.startActivity()} and
diff --git a/core/java/android/content/rollback/PackageRollbackInfo.java b/core/java/android/content/rollback/PackageRollbackInfo.java
index 4644a83..d4ed35a 100644
--- a/core/java/android/content/rollback/PackageRollbackInfo.java
+++ b/core/java/android/content/rollback/PackageRollbackInfo.java
@@ -16,10 +16,14 @@
 
 package android.content.rollback;
 
+import android.annotation.NonNull;
 import android.annotation.SystemApi;
 import android.content.pm.VersionedPackage;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.util.IntArray;
+
+import java.util.ArrayList;
 
 /**
  * Information about a rollback available for a particular package.
@@ -33,6 +37,38 @@
     private final VersionedPackage mVersionRolledBackTo;
 
     /**
+     * Encapsulates information required to restore a snapshot of an app's userdata.
+     *
+     * @hide
+     */
+    public static class RestoreInfo {
+        public final int userId;
+        public final int appId;
+        public final String seInfo;
+
+        public RestoreInfo(int userId, int appId, String seInfo) {
+            this.userId = userId;
+            this.appId = appId;
+            this.seInfo = seInfo;
+        }
+    }
+
+    /*
+     * The list of users for which we need to backup userdata for this package. Backups of
+     * credential encrypted data are listed as pending if the user hasn't unlocked their device
+     * with credentials yet.
+     */
+    // NOTE: Not a part of the Parcelable representation of this object.
+    private final IntArray mPendingBackups;
+
+    /**
+     * The list of users for which we need to restore userdata for this package. This field is
+     * non-null only after a rollback for this package has been committed.
+     */
+    // NOTE: Not a part of the Parcelable representation of this object.
+    private final ArrayList<RestoreInfo> mPendingRestores;
+
+    /**
      * Returns the name of the package to roll back from.
      */
     public String getPackageName() {
@@ -54,15 +90,46 @@
     }
 
     /** @hide */
+    public IntArray getPendingBackups() {
+        return mPendingBackups;
+    }
+
+    /** @hide */
+    public ArrayList<RestoreInfo> getPendingRestores() {
+        return mPendingRestores;
+    }
+
+    /** @hide */
+    public RestoreInfo getRestoreInfo(int userId) {
+        for (RestoreInfo ri : mPendingRestores) {
+            if (ri.userId == userId) {
+                return ri;
+            }
+        }
+
+        return null;
+    }
+
+    /** @hide */
+    public void removeRestoreInfo(RestoreInfo ri) {
+        mPendingRestores.remove(ri);
+    }
+
+    /** @hide */
     public PackageRollbackInfo(VersionedPackage packageRolledBackFrom,
-            VersionedPackage packageRolledBackTo) {
+            VersionedPackage packageRolledBackTo,
+            @NonNull IntArray pendingBackups, @NonNull ArrayList<RestoreInfo> pendingRestores) {
         this.mVersionRolledBackFrom = packageRolledBackFrom;
         this.mVersionRolledBackTo = packageRolledBackTo;
+        this.mPendingBackups = pendingBackups;
+        this.mPendingRestores = pendingRestores;
     }
 
     private PackageRollbackInfo(Parcel in) {
         this.mVersionRolledBackFrom = VersionedPackage.CREATOR.createFromParcel(in);
         this.mVersionRolledBackTo = VersionedPackage.CREATOR.createFromParcel(in);
+        this.mPendingRestores = null;
+        this.mPendingBackups = null;
     }
 
     @Override
diff --git a/core/java/android/content/rollback/RollbackInfo.java b/core/java/android/content/rollback/RollbackInfo.java
index 1111b43..3fd2476 100644
--- a/core/java/android/content/rollback/RollbackInfo.java
+++ b/core/java/android/content/rollback/RollbackInfo.java
@@ -83,7 +83,7 @@
      * Returns the session ID for the committed rollback for staged rollbacks.
      * Only applicable for rollbacks that have been committed.
      */
-    public int getSessionId() {
+    public int getCommittedSessionId() {
         // TODO: Support rollback of staged installs.
         return PackageInstaller.SessionInfo.INVALID_ID;
     }
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 3bae12e..ef8ca9e 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -2918,11 +2918,11 @@
         }
     }
 
-    /** {@hide} */
+    /** {@hide} - returns the factory serial number */
     @UnsupportedAppUsage
-    public void registerNetworkFactory(Messenger messenger, String name) {
+    public int registerNetworkFactory(Messenger messenger, String name) {
         try {
-            mService.registerNetworkFactory(messenger, name);
+            return mService.registerNetworkFactory(messenger, name);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -2938,6 +2938,10 @@
         }
     }
 
+    // TODO : remove this method. It is a stopgap measure to help sheperding a number
+    // of dependent changes that would conflict throughout the automerger graph. Having this
+    // temporarily helps with the process of going through with all these dependent changes across
+    // the entire tree.
     /**
      * @hide
      * Register a NetworkAgent with ConnectivityService.
@@ -2945,8 +2949,20 @@
      */
     public int registerNetworkAgent(Messenger messenger, NetworkInfo ni, LinkProperties lp,
             NetworkCapabilities nc, int score, NetworkMisc misc) {
+        return registerNetworkAgent(messenger, ni, lp, nc, score, misc,
+                NetworkFactory.SerialNumber.NONE);
+    }
+
+    /**
+     * @hide
+     * Register a NetworkAgent with ConnectivityService.
+     * @return NetID corresponding to NetworkAgent.
+     */
+    public int registerNetworkAgent(Messenger messenger, NetworkInfo ni, LinkProperties lp,
+            NetworkCapabilities nc, int score, NetworkMisc misc, int factorySerialNumber) {
         try {
-            return mService.registerNetworkAgent(messenger, ni, lp, nc, score, misc);
+            return mService.registerNetworkAgent(messenger, ni, lp, nc, score, misc,
+                    factorySerialNumber);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index fd7360f..f88adc2 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -139,14 +139,14 @@
 
     void setAirplaneMode(boolean enable);
 
-    void registerNetworkFactory(in Messenger messenger, in String name);
+    int registerNetworkFactory(in Messenger messenger, in String name);
 
     boolean requestBandwidthUpdate(in Network network);
 
     void unregisterNetworkFactory(in Messenger messenger);
 
     int registerNetworkAgent(in Messenger messenger, in NetworkInfo ni, in LinkProperties lp,
-            in NetworkCapabilities nc, int score, in NetworkMisc misc);
+            in NetworkCapabilities nc, int score, in NetworkMisc misc, in int factorySerialNumber);
 
     NetworkRequest requestNetwork(in NetworkCapabilities networkCapabilities,
             in Messenger messenger, int timeoutSec, in IBinder binder, int legacy);
diff --git a/core/java/android/net/NetworkAgent.java b/core/java/android/net/NetworkAgent.java
index 99bfc14..204c25f 100644
--- a/core/java/android/net/NetworkAgent.java
+++ b/core/java/android/net/NetworkAgent.java
@@ -58,6 +58,7 @@
     private static final long BW_REFRESH_MIN_WIN_MS = 500;
     private boolean mPollLceScheduled = false;
     private AtomicBoolean mPollLcePending = new AtomicBoolean(false);
+    public final int mFactorySerialNumber;
 
     private static final int BASE = Protocol.BASE_NETWORK_AGENT;
 
@@ -193,16 +194,31 @@
      */
     public static final int CMD_PREVENT_AUTOMATIC_RECONNECT = BASE + 15;
 
+    // TODO : remove these two constructors. They are a stopgap measure to help sheperding a number
+    // of dependent changes that would conflict throughout the automerger graph. Having these
+    // temporarily helps with the process of going through with all these dependent changes across
+    // the entire tree.
     public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni,
             NetworkCapabilities nc, LinkProperties lp, int score) {
-        this(looper, context, logTag, ni, nc, lp, score, null);
+        this(looper, context, logTag, ni, nc, lp, score, null, NetworkFactory.SerialNumber.NONE);
+    }
+    public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni,
+            NetworkCapabilities nc, LinkProperties lp, int score, NetworkMisc misc) {
+        this(looper, context, logTag, ni, nc, lp, score, misc, NetworkFactory.SerialNumber.NONE);
     }
 
     public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni,
-            NetworkCapabilities nc, LinkProperties lp, int score, NetworkMisc misc) {
+            NetworkCapabilities nc, LinkProperties lp, int score, int factorySerialNumber) {
+        this(looper, context, logTag, ni, nc, lp, score, null, factorySerialNumber);
+    }
+
+    public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni,
+            NetworkCapabilities nc, LinkProperties lp, int score, NetworkMisc misc,
+            int factorySerialNumber) {
         super(looper);
         LOG_TAG = logTag;
         mContext = context;
+        mFactorySerialNumber = factorySerialNumber;
         if (ni == null || nc == null || lp == null) {
             throw new IllegalArgumentException();
         }
@@ -211,7 +227,8 @@
         ConnectivityManager cm = (ConnectivityManager)mContext.getSystemService(
                 Context.CONNECTIVITY_SERVICE);
         netId = cm.registerNetworkAgent(new Messenger(this), new NetworkInfo(ni),
-                new LinkProperties(lp), new NetworkCapabilities(nc), score, misc);
+                new LinkProperties(lp), new NetworkCapabilities(nc), score, misc,
+                factorySerialNumber);
     }
 
     @Override
diff --git a/core/java/android/net/NetworkFactory.java b/core/java/android/net/NetworkFactory.java
index 181cab4..0dfe7a4 100644
--- a/core/java/android/net/NetworkFactory.java
+++ b/core/java/android/net/NetworkFactory.java
@@ -32,6 +32,7 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
+import java.util.concurrent.atomic.AtomicInteger;
 
 /**
  * A NetworkFactory is an entity that creates NetworkAgent objects.
@@ -49,6 +50,20 @@
  * @hide
  **/
 public class NetworkFactory extends Handler {
+    /** @hide */
+    public static class SerialNumber {
+        // Guard used by no network factory.
+        public static final int NONE = -1;
+        // A hardcoded serial number for NetworkAgents representing VPNs. These agents are
+        // not created by any factory, so they use this constant for clarity instead of NONE.
+        public static final int VPN = -2;
+        private static final AtomicInteger sNetworkFactorySerialNumber = new AtomicInteger(1);
+        /** Returns a unique serial number for a factory. */
+        public static final int nextSerialNumber() {
+            return sNetworkFactorySerialNumber.getAndIncrement();
+        }
+    }
+
     private static final boolean DBG = true;
     private static final boolean VDBG = false;
 
@@ -64,7 +79,7 @@
      * disregard any that it will never be able to service, for example
      * those requiring a different bearer.
      * msg.obj = NetworkRequest
-     * msg.arg1 = score - the score of the any network currently satisfying this
+     * msg.arg1 = score - the score of the network currently satisfying this
      *            request.  If this bearer knows in advance it cannot
      *            exceed this score it should not try to connect, holding the request
      *            for the future.
@@ -74,6 +89,8 @@
      *            with the same NetworkRequest but an updated score.
      *            Also, network conditions may change for this bearer
      *            allowing for a better score in the future.
+     * msg.arg2 = the serial number of the factory currently responsible for the
+     *            NetworkAgent handling this request, or SerialNumber.NONE if none.
      */
     public static final int CMD_REQUEST_NETWORK = BASE;
 
@@ -107,6 +124,7 @@
 
     private int mRefCount = 0;
     private Messenger mMessenger = null;
+    private int mSerialNumber;
 
     @UnsupportedAppUsage
     public NetworkFactory(Looper looper, Context context, String logTag,
@@ -121,7 +139,8 @@
         if (DBG) log("Registering NetworkFactory");
         if (mMessenger == null) {
             mMessenger = new Messenger(this);
-            ConnectivityManager.from(mContext).registerNetworkFactory(mMessenger, LOG_TAG);
+            mSerialNumber = ConnectivityManager.from(mContext).registerNetworkFactory(mMessenger,
+                    LOG_TAG);
         }
     }
 
@@ -137,7 +156,7 @@
     public void handleMessage(Message msg) {
         switch (msg.what) {
             case CMD_REQUEST_NETWORK: {
-                handleAddRequest((NetworkRequest)msg.obj, msg.arg1);
+                handleAddRequest((NetworkRequest) msg.obj, msg.arg1, msg.arg2);
                 break;
             }
             case CMD_CANCEL_REQUEST: {
@@ -159,11 +178,13 @@
         public final NetworkRequest request;
         public int score;
         public boolean requested; // do we have a request outstanding, limited by score
+        public int factorySerialNumber;
 
-        public NetworkRequestInfo(NetworkRequest request, int score) {
+        NetworkRequestInfo(NetworkRequest request, int score, int factorySerialNumber) {
             this.request = request;
             this.score = score;
             this.requested = false;
+            this.factorySerialNumber = factorySerialNumber;
         }
 
         @Override
@@ -172,16 +193,51 @@
         }
     }
 
+    /**
+     * Add a NetworkRequest that the bearer may want to attempt to satisfy.
+     * @see #CMD_REQUEST_NETWORK
+     *
+     * @param request the request to handle.
+     * @param score the score of the NetworkAgent currently satisfying this request.
+     * @param servingFactorySerialNumber the serial number of the NetworkFactory that
+     *         created the NetworkAgent currently satisfying this request.
+     */
+    // TODO : remove this method. It is a stopgap measure to help sheperding a number
+    // of dependent changes that would conflict throughout the automerger graph. Having this
+    // temporarily helps with the process of going through with all these dependent changes across
+    // the entire tree.
     @VisibleForTesting
     protected void handleAddRequest(NetworkRequest request, int score) {
+        handleAddRequest(request, score, SerialNumber.NONE);
+    }
+
+    /**
+     * Add a NetworkRequest that the bearer may want to attempt to satisfy.
+     * @see #CMD_REQUEST_NETWORK
+     *
+     * @param request the request to handle.
+     * @param score the score of the NetworkAgent currently satisfying this request.
+     * @param servingFactorySerialNumber the serial number of the NetworkFactory that
+     *         created the NetworkAgent currently satisfying this request.
+     */
+    @VisibleForTesting
+    protected void handleAddRequest(NetworkRequest request, int score,
+            int servingFactorySerialNumber) {
         NetworkRequestInfo n = mNetworkRequests.get(request.requestId);
         if (n == null) {
-            if (DBG) log("got request " + request + " with score " + score);
-            n = new NetworkRequestInfo(request, score);
+            if (DBG) {
+                log("got request " + request + " with score " + score
+                        + " and serial " + servingFactorySerialNumber);
+            }
+            n = new NetworkRequestInfo(request, score, servingFactorySerialNumber);
             mNetworkRequests.put(n.request.requestId, n);
         } else {
-            if (VDBG) log("new score " + score + " for exisiting request " + request);
+            if (VDBG) {
+                log("new score " + score + " for exisiting request " + request
+                        + " with serial " + servingFactorySerialNumber);
+            }
             n.score = score;
+            n.factorySerialNumber = servingFactorySerialNumber;
         }
         if (VDBG) log("  my score=" + mScore + ", my filter=" + mCapabilityFilter);
 
@@ -231,16 +287,19 @@
     }
 
     private void evalRequest(NetworkRequestInfo n) {
-        if (VDBG) log("evalRequest");
-        if (n.requested == false && n.score < mScore &&
-                n.request.networkCapabilities.satisfiedByNetworkCapabilities(
-                mCapabilityFilter) && acceptRequest(n.request, n.score)) {
+        if (VDBG) {
+            log("evalRequest");
+            log(" n.requests = " + n.requested);
+            log(" n.score = " + n.score);
+            log(" mScore = " + mScore);
+            log(" n.factorySerialNumber = " + n.factorySerialNumber);
+            log(" mSerialNumber = " + mSerialNumber);
+        }
+        if (shouldNeedNetworkFor(n)) {
             if (VDBG) log("  needNetworkFor");
             needNetworkFor(n.request, n.score);
             n.requested = true;
-        } else if (n.requested == true &&
-                (n.score > mScore || n.request.networkCapabilities.satisfiedByNetworkCapabilities(
-                mCapabilityFilter) == false || acceptRequest(n.request, n.score) == false)) {
+        } else if (shouldReleaseNetworkFor(n)) {
             if (VDBG) log("  releaseNetworkFor");
             releaseNetworkFor(n.request);
             n.requested = false;
@@ -249,10 +308,39 @@
         }
     }
 
+    private boolean shouldNeedNetworkFor(NetworkRequestInfo n) {
+        // If this request is already tracked, it doesn't qualify for need
+        return !n.requested
+            // If the score of this request is higher or equal to that of this factory and some
+            // other factory is responsible for it, then this factory should not track the request
+            // because it has no hope of satisfying it.
+            && (n.score < mScore || n.factorySerialNumber == mSerialNumber)
+            // If this factory can't satisfy the capability needs of this request, then it
+            // should not be tracked.
+            && n.request.networkCapabilities.satisfiedByNetworkCapabilities(mCapabilityFilter)
+            // Finally if the concrete implementation of the factory rejects the request, then
+            // don't track it.
+            && acceptRequest(n.request, n.score);
+    }
+
+    private boolean shouldReleaseNetworkFor(NetworkRequestInfo n) {
+        // Don't release a request that's not tracked.
+        return n.requested
+            // The request should be released if it can't be satisfied by this factory. That
+            // means either of the following conditions are met :
+            // - Its score is too high to be satisfied by this factory and it's not already
+            //   assigned to the factory
+            // - This factory can't satisfy the capability needs of the request
+            // - The concrete implementation of the factory rejects the request
+            && ((n.score > mScore && n.factorySerialNumber != mSerialNumber)
+                    || !n.request.networkCapabilities.satisfiedByNetworkCapabilities(
+                            mCapabilityFilter)
+                    || !acceptRequest(n.request, n.score));
+    }
+
     private void evalRequests() {
         for (int i = 0; i < mNetworkRequests.size(); i++) {
             NetworkRequestInfo n = mNetworkRequests.valueAt(i);
-
             evalRequest(n);
         }
     }
@@ -280,16 +368,6 @@
         if (--mRefCount == 0) stopNetwork();
     }
 
-
-    public void addNetworkRequest(NetworkRequest networkRequest, int score) {
-        sendMessage(obtainMessage(CMD_REQUEST_NETWORK,
-                new NetworkRequestInfo(networkRequest, score)));
-    }
-
-    public void removeNetworkRequest(NetworkRequest networkRequest) {
-        sendMessage(obtainMessage(CMD_CANCEL_REQUEST, networkRequest));
-    }
-
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
     public void setScoreFilter(int score) {
         sendMessage(obtainMessage(CMD_SET_SCORE, score, 0));
@@ -304,6 +382,10 @@
         return mNetworkRequests.size();
     }
 
+    public int getSerialNumber() {
+        return mSerialNumber;
+    }
+
     protected void log(String s) {
         Log.d(LOG_TAG, s);
     }
@@ -321,10 +403,11 @@
 
     @Override
     public String toString() {
-        StringBuilder sb = new StringBuilder("{").append(LOG_TAG).append(" - ScoreFilter=").
-                append(mScore).append(", Filter=").append(mCapabilityFilter).append(", requests=").
-                append(mNetworkRequests.size()).append(", refCount=").append(mRefCount).
-                append("}");
+        StringBuilder sb = new StringBuilder("{").append(LOG_TAG).append(" - mSerialNumber=")
+                .append(mSerialNumber).append(", ScoreFilter=")
+                .append(mScore).append(", Filter=").append(mCapabilityFilter).append(", requests=")
+                .append(mNetworkRequests.size()).append(", refCount=").append(mRefCount)
+                .append("}");
         return sb.toString();
     }
 }
diff --git a/core/java/android/provider/CalendarContract.java b/core/java/android/provider/CalendarContract.java
index 8a52f1f..3e5bd4b 100644
--- a/core/java/android/provider/CalendarContract.java
+++ b/core/java/android/provider/CalendarContract.java
@@ -138,8 +138,8 @@
      * Action used to help apps show calendar events in the managed profile.
      */
     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
-    public static final String ACTION_VIEW_WORK_CALENDAR_EVENT =
-            "android.provider.calendar.action.VIEW_WORK_CALENDAR_EVENT";
+    public static final String ACTION_VIEW_MANAGED_PROFILE_CALENDAR_EVENT =
+            "android.provider.calendar.action.VIEW_MANAGED_PROFILE_CALENDAR_EVENT";
 
     /**
      * Intent Extras key: {@link EventsColumns#CUSTOM_APP_URI} for the event in
@@ -166,7 +166,7 @@
     public static final String EXTRA_EVENT_ALL_DAY = "allDay";
 
     /**
-     * Intent Extras key: The id of an event.
+     * Intent Extras key: An extra of type {@code long} holding the id of an event.
      */
     public static final String EXTRA_EVENT_ID = "id";
 
@@ -218,7 +218,7 @@
      * When this API is called, the system will attempt to start an activity
      * in the managed profile with an intent targeting the same caller package.
      * The intent will have its action set to
-     * {@link CalendarContract#ACTION_VIEW_WORK_CALENDAR_EVENT} and contain extras
+     * {@link CalendarContract#ACTION_VIEW_MANAGED_PROFILE_CALENDAR_EVENT} and contain extras
      * corresponding to the API's arguments. A calendar app intending to support
      * cross-profile events viewing should handle this intent, parse the arguments
      * and show the appropriate UI.
@@ -226,10 +226,10 @@
      * @param context the context.
      * @param eventId the id of the event to be viewed. Will be put into {@link #EXTRA_EVENT_ID}
      *                field of the intent.
-     * @param start the start time of the event. Will be put into {@link #EXTRA_EVENT_BEGIN_TIME}
-     *              field of the intent.
-     * @param end the end time of the event. Will be put into {@link #EXTRA_EVENT_END_TIME} field
-     *            of the intent.
+     * @param startMs the start time of the event in milliseconds since epoch.
+     *                Will be put into {@link #EXTRA_EVENT_BEGIN_TIME} field of the intent.
+     * @param endMs the end time of the event in milliseconds since epoch.
+     *              Will be put into {@link #EXTRA_EVENT_END_TIME} field of the intent.
      * @param allDay if the event is an all-day event. Will be put into
      *               {@link #EXTRA_EVENT_ALL_DAY} field of the intent.
      * @param flags flags to be set on the intent via {@link Intent#setFlags}
@@ -241,12 +241,12 @@
      * @see #EXTRA_EVENT_ALL_DAY
      */
     public static boolean startViewCalendarEventInManagedProfile(@NonNull Context context,
-            long eventId, long start, long end, boolean allDay, int flags) {
+            long eventId, long startMs, long endMs, boolean allDay, int flags) {
         Preconditions.checkNotNull(context, "Context is null");
         final DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService(
                 Context.DEVICE_POLICY_SERVICE);
-        return dpm.startViewCalendarEventInManagedProfile(eventId, start,
-                end, allDay, flags);
+        return dpm.startViewCalendarEventInManagedProfile(eventId, startMs,
+                endMs, allDay, flags);
     }
 
     /**
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 794c2f1..5151e29 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -10521,8 +10521,10 @@
         /**
          * Setting to enable connected MAC randomization in Wi-Fi; disabled by default, and
          * setting to 1 will enable it. In the future, additional values may be supported.
+         * @deprecated MAC randomization is now a per-network setting
          * @hide
          */
+        @Deprecated
         public static final String WIFI_CONNECTED_MAC_RANDOMIZATION_ENABLED =
                 "wifi_connected_mac_randomization_enabled";
 
diff --git a/core/java/android/service/notification/INotificationListener.aidl b/core/java/android/service/notification/INotificationListener.aidl
index 1ddc099e..22104b5 100644
--- a/core/java/android/service/notification/INotificationListener.aidl
+++ b/core/java/android/service/notification/INotificationListener.aidl
@@ -33,6 +33,7 @@
     void onListenerConnected(in NotificationRankingUpdate update);
     void onNotificationPosted(in IStatusBarNotificationHolder notificationHolder,
             in NotificationRankingUpdate update);
+    void onStatusBarIconsBehaviorChanged(boolean hideSilentStatusIcons);
     // stats only for assistant
     void onNotificationRemoved(in IStatusBarNotificationHolder notificationHolder,
             in NotificationRankingUpdate update, in NotificationStats stats, int reason);
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java
index c734b63..d4e8879 100644
--- a/core/java/android/service/notification/NotificationListenerService.java
+++ b/core/java/android/service/notification/NotificationListenerService.java
@@ -469,6 +469,17 @@
     }
 
     /**
+     * Implement this method to be notified when the behavior of silent notifications in the status
+     * bar changes. See {@link NotificationManager#shouldHideSilentStatusBarIcons()}.
+     *
+     * @param hideSilentStatusIcons whether or not status bar icons should be hidden for silent
+     *                              notifications
+     */
+    public void onStatusBarIconsBehaviorChanged(boolean hideSilentStatusIcons) {
+        // optional
+    }
+
+    /**
      * Implement this method to learn about notification channel modifications.
      *
      * <p>The caller must have {@link CompanionDeviceManager#getAssociations() an associated
@@ -1411,6 +1422,12 @@
             mHandler.obtainMessage(
                     MyHandler.MSG_ON_NOTIFICATION_CHANNEL_GROUP_MODIFIED, args).sendToTarget();
         }
+
+        @Override
+        public void onStatusBarIconsBehaviorChanged(boolean hideSilentStatusIcons) {
+            mHandler.obtainMessage(MyHandler.MSG_ON_STATUS_BAR_ICON_BEHAVIOR_CHANGED,
+                    hideSilentStatusIcons).sendToTarget();
+        }
     }
 
     /**
@@ -2142,6 +2159,7 @@
         public static final int MSG_ON_INTERRUPTION_FILTER_CHANGED = 6;
         public static final int MSG_ON_NOTIFICATION_CHANNEL_MODIFIED = 7;
         public static final int MSG_ON_NOTIFICATION_CHANNEL_GROUP_MODIFIED = 8;
+        public static final int MSG_ON_STATUS_BAR_ICON_BEHAVIOR_CHANGED = 9;
 
         public MyHandler(Looper looper) {
             super(looper, null, false);
@@ -2207,6 +2225,10 @@
                     int modificationType = (int) args.arg4;
                     onNotificationChannelGroupModified(pkgName, user, group, modificationType);
                 } break;
+
+                case MSG_ON_STATUS_BAR_ICON_BEHAVIOR_CHANGED: {
+                    onStatusBarIconsBehaviorChanged((Boolean) msg.obj);
+                } break;
             }
         }
     }
diff --git a/core/java/android/view/AccessibilityInteractionController.java b/core/java/android/view/AccessibilityInteractionController.java
index eb41e07..59e562f 100644
--- a/core/java/android/view/AccessibilityInteractionController.java
+++ b/core/java/android/view/AccessibilityInteractionController.java
@@ -41,12 +41,14 @@
 import android.view.accessibility.AccessibilityInteractionClient;
 import android.view.accessibility.AccessibilityManager;
 import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
 import android.view.accessibility.AccessibilityNodeProvider;
 import android.view.accessibility.AccessibilityRequestPreparer;
 import android.view.accessibility.IAccessibilityInteractionConnectionCallback;
 
 import com.android.internal.R;
 import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.os.SomeArgs;
 
 import java.util.ArrayList;
@@ -64,8 +66,11 @@
  * called from the interaction connection ViewAncestor gives the system to
  * talk to it and a corresponding *UiThread method that is executed on the
  * UI thread.
+ *
+ * @hide
  */
-final class AccessibilityInteractionController {
+@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+public final class AccessibilityInteractionController {
 
     private static final String LOG_TAG = "AccessibilityInteractionController";
 
@@ -85,7 +90,7 @@
 
     private final Object mLock = new Object();
 
-    private final Handler mHandler;
+    private final PrivateHandler mHandler;
 
     private final ViewRootImpl mViewRootImpl;
 
@@ -131,11 +136,19 @@
             // thread in this process, set the message as a static reference so
             // after this call completes the same thread but in the interrogating
             // client can handle the message to generate the result.
-            if (interrogatingPid == mMyProcessId && interrogatingTid == mMyLooperThreadId) {
+            if (interrogatingPid == mMyProcessId && interrogatingTid == mMyLooperThreadId
+                    && mHandler.hasAccessibilityCallback(message)) {
                 AccessibilityInteractionClient.getInstanceForThread(
                         interrogatingTid).setSameThreadMessage(message);
             } else {
-                mHandler.sendMessage(message);
+                // For messages without callback of interrogating client, just handle the
+                // message immediately if this is UI thread.
+                if (!mHandler.hasAccessibilityCallback(message)
+                        && Thread.currentThread().getId() == mMyLooperThreadId) {
+                    mHandler.handleMessage(message);
+                } else {
+                    mHandler.sendMessage(message);
+                }
             }
         }
     }
@@ -731,6 +744,52 @@
         }
     }
 
+    /**
+     * Finds the accessibility focused node in the root, and clears the accessibility focus.
+     */
+    public void clearAccessibilityFocusClientThread() {
+        final Message message = mHandler.obtainMessage();
+        message.what = PrivateHandler.MSG_CLEAR_ACCESSIBILITY_FOCUS;
+
+        // Don't care about pid and tid because there's no interrogating client for this message.
+        scheduleMessage(message, 0, 0, CONSIDER_REQUEST_PREPARERS);
+    }
+
+    private void clearAccessibilityFocusUiThread() {
+        if (mViewRootImpl.mView == null || mViewRootImpl.mAttachInfo == null) {
+            return;
+        }
+        try {
+            mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags =
+                    AccessibilityNodeInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;
+            final View root = mViewRootImpl.mView;
+            if (root != null && isShown(root)) {
+                final View host = mViewRootImpl.mAccessibilityFocusedHost;
+                // If there is no accessibility focus host or it is not a descendant
+                // of the root from which to start the search, then the search failed.
+                if (host == null || !ViewRootImpl.isViewDescendantOf(host, root)) {
+                    return;
+                }
+                final AccessibilityNodeProvider provider = host.getAccessibilityNodeProvider();
+                final AccessibilityNodeInfo focusNode =
+                        mViewRootImpl.mAccessibilityFocusedVirtualView;
+                if (provider != null && focusNode != null) {
+                    final int virtualNodeId = AccessibilityNodeInfo.getVirtualDescendantId(
+                            focusNode.getSourceNodeId());
+                    provider.performAction(virtualNodeId,
+                            AccessibilityAction.ACTION_CLEAR_ACCESSIBILITY_FOCUS.getId(),
+                            null);
+                } else {
+                    host.performAccessibilityAction(
+                            AccessibilityAction.ACTION_CLEAR_ACCESSIBILITY_FOCUS.getId(),
+                            null);
+                }
+            }
+        } finally {
+            mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = 0;
+        }
+    }
+
     private View findViewByAccessibilityId(int accessibilityId) {
         View root = mViewRootImpl.mView;
         if (root == null) {
@@ -1294,6 +1353,12 @@
         private static final int MSG_APP_PREPARATION_FINISHED = 8;
         private static final int MSG_APP_PREPARATION_TIMEOUT = 9;
 
+        // Uses FIRST_NO_ACCESSIBILITY_CALLBACK_MSG for messages that don't need to call back
+        // results to interrogating client.
+        private static final int FIRST_NO_ACCESSIBILITY_CALLBACK_MSG = 100;
+        private static final int MSG_CLEAR_ACCESSIBILITY_FOCUS =
+                FIRST_NO_ACCESSIBILITY_CALLBACK_MSG + 1;
+
         public PrivateHandler(Looper looper) {
             super(looper);
         }
@@ -1320,6 +1385,8 @@
                     return "MSG_APP_PREPARATION_FINISHED";
                 case MSG_APP_PREPARATION_TIMEOUT:
                     return "MSG_APP_PREPARATION_TIMEOUT";
+                case MSG_CLEAR_ACCESSIBILITY_FOCUS:
+                    return "MSG_CLEAR_ACCESSIBILITY_FOCUS";
                 default:
                     throw new IllegalArgumentException("Unknown message type: " + type);
             }
@@ -1356,10 +1423,17 @@
                 case MSG_APP_PREPARATION_TIMEOUT: {
                     requestPreparerTimeoutUiThread();
                 } break;
+                case MSG_CLEAR_ACCESSIBILITY_FOCUS: {
+                    clearAccessibilityFocusUiThread();
+                } break;
                 default:
                     throw new IllegalArgumentException("Unknown message type: " + type);
             }
         }
+
+        boolean hasAccessibilityCallback(Message message) {
+            return message.what < FIRST_NO_ACCESSIBILITY_CALLBACK_MSG ? true : false;
+        }
     }
 
     private final class AddNodeInfosForViewId implements Predicate<View> {
diff --git a/core/java/android/view/InputWindowHandle.java b/core/java/android/view/InputWindowHandle.java
index 92e0009..ec79eea 100644
--- a/core/java/android/view/InputWindowHandle.java
+++ b/core/java/android/view/InputWindowHandle.java
@@ -16,10 +16,10 @@
 
 package android.view;
 
+import static android.view.Display.INVALID_DISPLAY;
+
 import android.graphics.Region;
 import android.os.IBinder;
-import android.view.IWindow;
-import android.view.InputChannel;
 
 /**
  * Functions as a handle for a window that can receive input.
@@ -94,6 +94,10 @@
     // Display this input is on.
     public int displayId;
 
+    // If this value is set to a valid display ID, it indicates this window is a portal which
+    // transports the touch of this window to the display indicated by portalToDisplayId.
+    public int portalToDisplayId = INVALID_DISPLAY;
+
     private native void nativeDispose();
 
     public InputWindowHandle(InputApplicationHandle inputApplicationHandle,
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index f47eb10..9213f32 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -8718,6 +8718,15 @@
                 }
             }
         }
+
+        @Override
+        public void clearAccessibilityFocus() {
+            ViewRootImpl viewRootImpl = mViewRootImpl.get();
+            if (viewRootImpl != null && viewRootImpl.mView != null) {
+                viewRootImpl.getAccessibilityInteractionController()
+                        .clearAccessibilityFocusClientThread();
+            }
+        }
     }
 
     private class SendWindowContentChangedAccessibilityEvent implements Runnable {
diff --git a/core/java/android/view/accessibility/IAccessibilityInteractionConnection.aidl b/core/java/android/view/accessibility/IAccessibilityInteractionConnection.aidl
index 4c0fdfd..947ff05 100644
--- a/core/java/android/view/accessibility/IAccessibilityInteractionConnection.aidl
+++ b/core/java/android/view/accessibility/IAccessibilityInteractionConnection.aidl
@@ -55,4 +55,6 @@
     void performAccessibilityAction(long accessibilityNodeId, int action, in Bundle arguments,
         int interactionId, IAccessibilityInteractionConnectionCallback callback, int flags,
         int interrogatingPid, long interrogatingTid);
+
+    void clearAccessibilityFocus();
 }
diff --git a/core/java/android/view/contentcapture/UserDataRemovalRequest.java b/core/java/android/view/contentcapture/UserDataRemovalRequest.java
index 8ee63ef..8fedcd5 100644
--- a/core/java/android/view/contentcapture/UserDataRemovalRequest.java
+++ b/core/java/android/view/contentcapture/UserDataRemovalRequest.java
@@ -16,7 +16,6 @@
 package android.view.contentcapture;
 
 import android.annotation.NonNull;
-import android.annotation.SystemApi;
 import android.app.ActivityThread;
 import android.net.Uri;
 import android.os.Parcel;
@@ -67,9 +66,7 @@
 
     /**
      * Gets the name of the app that's making the request.
-     * @hide
      */
-    @SystemApi
     @NonNull
     public String getPackageName() {
         return mPackageName;
@@ -77,20 +74,14 @@
 
     /**
      * Checks if app is requesting to remove all user data associated with its package.
-     *
-     * @hide
      */
-    @SystemApi
     public boolean isForEverything() {
         return mForEverything;
     }
 
     /**
      * Gets the list of {@code Uri}s the apps is requesting to remove.
-     *
-     * @hide
      */
-    @SystemApi
     @NonNull
     public List<UriRequest> getUriRequests() {
         return mUriRequests;
@@ -203,9 +194,7 @@
 
     /**
      * Representation of a request to remove data associated with an {@link Uri}.
-     * @hide
      */
-    @SystemApi
     public final class UriRequest {
         private final @NonNull Uri mUri;
         private final boolean mRecursive;
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 299801a..46f42f7 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -24,6 +24,7 @@
 import android.app.prediction.AppTarget;
 import android.app.prediction.AppTargetEvent;
 import android.app.prediction.AppTargetId;
+import android.content.ClipData;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -41,9 +42,13 @@
 import android.content.pm.ShortcutInfo;
 import android.content.pm.ShortcutManager;
 import android.database.DataSetObserver;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
 import android.graphics.Color;
+import android.graphics.Path;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.Icon;
+import android.net.Uri;
 import android.os.AsyncTask;
 import android.os.Bundle;
 import android.os.Environment;
@@ -62,7 +67,9 @@
 import android.service.chooser.IChooserTargetResult;
 import android.service.chooser.IChooserTargetService;
 import android.text.TextUtils;
+import android.util.AttributeSet;
 import android.util.Log;
+import android.util.Size;
 import android.util.Slog;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -73,9 +80,11 @@
 import android.view.ViewGroup.LayoutParams;
 import android.widget.AbsListView;
 import android.widget.BaseAdapter;
+import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.ListView;
 import android.widget.Space;
+import android.widget.TextView;
 
 import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
@@ -85,6 +94,7 @@
 import com.google.android.collect.Lists;
 
 import java.io.File;
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
@@ -262,16 +272,31 @@
         }
 
         mReplacementExtras = intent.getBundleExtra(Intent.EXTRA_REPLACEMENT_EXTRAS);
-        CharSequence title = intent.getCharSequenceExtra(Intent.EXTRA_TITLE);
+
+        // Do not allow the title to be changed when sharing content
+        CharSequence title = null;
+        if (target != null) {
+            String targetAction = target.getAction();
+            if (!(Intent.ACTION_SEND.equals(targetAction) || Intent.ACTION_SEND_MULTIPLE.equals(
+                    targetAction))) {
+                title = intent.getCharSequenceExtra(Intent.EXTRA_TITLE);
+            } else {
+                Log.w(TAG, "Ignoring intent's EXTRA_TITLE, deprecated in P. You may wish to set a"
+                        + " preview title by using EXTRA_TITLE property of the wrapped"
+                        + " EXTRA_INTENT.");
+            }
+        }
+
         int defaultTitleRes = 0;
         if (title == null) {
             defaultTitleRes = com.android.internal.R.string.chooseActivity;
         }
+
         Parcelable[] pa = intent.getParcelableArrayExtra(Intent.EXTRA_INITIAL_INTENTS);
         Intent[] initialIntents = null;
         if (pa != null) {
             initialIntents = new Intent[pa.length];
-            for (int i=0; i<pa.length; i++) {
+            for (int i = 0; i < pa.length; i++) {
                 if (!(pa[i] instanceof Intent)) {
                     Log.w(TAG, "Initial intent #" + i + " not an Intent: " + pa[i]);
                     finish();
@@ -364,6 +389,68 @@
         }
     }
 
+    /**
+     * Override method to add content preview area, specific to the chooser activity.
+     */
+    @Override
+    public void setHeader() {
+        super.setHeader();
+
+        Intent targetIntent = getTargetIntent();
+        if (targetIntent == null) {
+            return;
+        }
+
+        ViewGroup contentPreviewLayout = findViewById(R.id.content_preview);
+        String action = targetIntent.getAction();
+        if (!(Intent.ACTION_SEND.equals(action) || Intent.ACTION_SEND_MULTIPLE.equals(action))) {
+            contentPreviewLayout.setVisibility(View.GONE);
+            return;
+        }
+
+        showDefaultContentPreview(contentPreviewLayout, targetIntent);
+    }
+
+    private void showDefaultContentPreview(final ViewGroup parentLayout,
+            final Intent targetIntent) {
+        CharSequence sharingText = targetIntent.getCharSequenceExtra(Intent.EXTRA_TEXT);
+        TextView previewTextView = findViewById(R.id.content_preview_text);
+        if (sharingText == null) {
+            previewTextView.setVisibility(View.GONE);
+        } else {
+            previewTextView.setText(sharingText);
+        }
+
+        String previewTitle = targetIntent.getStringExtra(Intent.EXTRA_TITLE);
+        TextView previewTitleView = findViewById(R.id.content_preview_title);
+        if (previewTitle == null) {
+            previewTitleView.setVisibility(View.GONE);
+        } else {
+            previewTitleView.setText(previewTitle);
+        }
+
+        ClipData previewData = targetIntent.getClipData();
+        Uri previewThumbnail = null;
+        if (previewData != null) {
+            if (previewData.getItemCount() > 0) {
+                ClipData.Item previewDataItem = previewData.getItemAt(0);
+                previewThumbnail = previewDataItem.getUri();
+            }
+        }
+
+        ImageView previewThumbnailView = findViewById(R.id.content_preview_thumbnail);
+        if (previewThumbnail == null) {
+            previewThumbnailView.setVisibility(View.GONE);
+        } else {
+            Bitmap bmp = loadThumbnail(previewThumbnail, new Size(200, 200));
+            if (bmp == null) {
+                previewThumbnailView.setVisibility(View.GONE);
+            } else {
+                previewThumbnailView.setImageBitmap(bmp);
+            }
+        }
+    }
+
     static SharedPreferences getPinnedSharedPrefs(Context context) {
         // The code below is because in the android:ui process, no one can hear you scream.
         // The package info in the context isn't initialized in the way it is for normal apps,
@@ -630,15 +717,19 @@
                 }
             }
             if (targetsToQuery >= QUERY_TARGET_SERVICE_LIMIT) {
-                if (DEBUG) Log.d(TAG, "queryTargets hit query target limit "
-                        + QUERY_TARGET_SERVICE_LIMIT);
+                if (DEBUG) {
+                    Log.d(TAG, "queryTargets hit query target limit "
+                            + QUERY_TARGET_SERVICE_LIMIT);
+                }
                 break;
             }
         }
 
         if (!mServiceConnections.isEmpty()) {
-            if (DEBUG) Log.d(TAG, "queryTargets setting watchdog timer for "
-                    + WATCHDOG_TIMEOUT_MILLIS + "ms");
+            if (DEBUG) {
+                Log.d(TAG, "queryTargets setting watchdog timer for "
+                        + WATCHDOG_TIMEOUT_MILLIS + "ms");
+            }
             mChooserHandler.sendEmptyMessageDelayed(CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT,
                     WATCHDOG_TIMEOUT_MILLIS);
         } else {
@@ -969,6 +1060,20 @@
                 mLaunchedFromUid);
     }
 
+    @VisibleForTesting
+    protected Bitmap loadThumbnail(Uri uri, Size size) {
+        if (uri == null || size == null) {
+            return null;
+        }
+
+        try {
+            return getContentResolver().loadThumbnail(uri, size, null);
+        } catch (IOException | NullPointerException ex) {
+            Log.w(TAG, "Error loading preview thumbnail for uri: " + uri.toString(), ex);
+        }
+        return null;
+    }
+
     final class ChooserTargetInfo implements TargetInfo {
         private final DisplayResolveInfo mSourceInfo;
         private final ResolveInfo mBackupResolveInfo;
@@ -1247,7 +1352,7 @@
                     UserManager userManager =
                             (UserManager) getSystemService(Context.USER_SERVICE);
                     if (ii instanceof LabeledIntent) {
-                        LabeledIntent li = (LabeledIntent)ii;
+                        LabeledIntent li = (LabeledIntent) ii;
                         ri.resolvePackageName = li.getSourcePackage();
                         ri.labelRes = li.getLabelResource();
                         ri.nonLocalizedLabel = li.getNonLocalizedLabel();
@@ -1391,8 +1496,10 @@
         }
 
         public void addServiceResults(DisplayResolveInfo origTarget, List<ChooserTarget> targets) {
-            if (DEBUG) Log.d(TAG, "addServiceResults " + origTarget + ", " + targets.size()
-                    + " targets");
+            if (DEBUG) {
+                Log.d(TAG, "addServiceResults " + origTarget + ", " + targets.size()
+                        + " targets");
+            }
 
             if (mTargetsNeedPruning && targets.size() > 0) {
                 // First proper update since we got an onListRebuilt() with (transient) 0 items.
@@ -1492,8 +1599,9 @@
         public int getCount() {
             return (int) (
                     getCallerTargetRowCount()
-                    + getServiceTargetRowCount()
-                    + Math.ceil((float) mChooserListAdapter.getStandardTargetCount() / mColumnCount)
+                            + getServiceTargetRowCount()
+                            + Math.ceil(
+                            (float) mChooserListAdapter.getStandardTargetCount() / mColumnCount)
             );
         }
 
@@ -1860,7 +1968,7 @@
 
             final int chooserTargetRows = mChooserRowAdapter.getServiceTargetRowCount();
             int offset = 0;
-            for (int i = 0; i < chooserTargetRows; i++)  {
+            for (int i = 0; i < chooserTargetRows; i++) {
                 final int pos = mChooserRowAdapter.getCallerTargetRowCount() + i;
                 final int vt = mChooserRowAdapter.getItemViewType(pos);
                 if (vt != mCachedViewType) {
@@ -1882,4 +1990,65 @@
             mResolverDrawerLayout.setCollapsibleHeightReserved(offset);
         }
     }
+
+
+    /**
+     * Used internally to round image corners while obeying view padding.
+     */
+    public static class RoundedRectImageView extends ImageView {
+        private int mRadius = 0;
+        private Path mPath = new Path();
+
+        public RoundedRectImageView(Context context) {
+            super(context);
+        }
+
+        public RoundedRectImageView(Context context, AttributeSet attrs) {
+            this(context, attrs, 0);
+        }
+
+        public RoundedRectImageView(Context context, AttributeSet attrs, int defStyleAttr) {
+            this(context, attrs, defStyleAttr, 0);
+        }
+
+        public RoundedRectImageView(Context context, AttributeSet attrs, int defStyleAttr,
+                int defStyleRes) {
+            super(context, attrs, defStyleAttr, defStyleRes);
+            mRadius = context.getResources().getDimensionPixelSize(R.dimen.chooser_corner_radius);
+        }
+
+        private void updatePath(int width, int height) {
+            mPath.reset();
+
+            int imageWidth = width - getPaddingLeft() - getPaddingRight();
+            int imageHeight = height - getPaddingTop() - getPaddingBottom();
+            mPath.addRoundRect(getPaddingLeft(), getPaddingTop(), imageWidth, imageHeight, mRadius,
+                    mRadius, Path.Direction.CW);
+        }
+
+        /**
+          * Sets the corner radius on all corners
+          *
+          * param radius 0 for no radius, &gt; 0 for a visible corner radius
+          */
+        public void setRadius(int radius) {
+            mRadius = radius;
+            updatePath(getWidth(), getHeight());
+        }
+
+        @Override
+        protected void onSizeChanged(int width, int height, int oldWidth, int oldHeight) {
+            super.onSizeChanged(width, height, oldWidth, oldHeight);
+            updatePath(width, height);
+        }
+
+        @Override
+        protected void onDraw(Canvas canvas) {
+            if (mRadius != 0) {
+                canvas.clipPath(mPath);
+            }
+
+            super.onDraw(canvas);
+        }
+    }
 }
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index a50c736..0919911 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -1044,7 +1044,10 @@
         }
     }
 
-    public void setTitleAndIcon() {
+    /**
+     * Configure the area above the app selection list (title, content preview, etc).
+     */
+    public void setHeader() {
         if (mAdapter.getCount() == 0 && mAdapter.mPlaceholderCount == 0) {
             final TextView titleView = findViewById(R.id.title);
             if (titleView != null) {
@@ -1062,23 +1065,6 @@
                 titleView.setText(title);
             }
             setTitle(title);
-
-            // Try to initialize the title icon if we have a view for it and a title to match
-            final ImageView titleIcon = findViewById(R.id.title_icon);
-            if (titleIcon != null) {
-                ApplicationInfo ai = null;
-                try {
-                    if (!TextUtils.isEmpty(mReferrerPackage)) {
-                        ai = mPm.getApplicationInfo(mReferrerPackage, 0);
-                    }
-                } catch (NameNotFoundException e) {
-                    Log.e(TAG, "Could not find referrer package " + mReferrerPackage);
-                }
-
-                if (ai != null) {
-                    titleIcon.setImageDrawable(ai.loadIcon(mPm));
-                }
-            }
         }
 
         final ImageView iconView = findViewById(R.id.icon);
@@ -1692,7 +1678,7 @@
                 mPostListReadyRunnable = new Runnable() {
                     @Override
                     public void run() {
-                        setTitleAndIcon();
+                        setHeader();
                         resetButtonBar();
                         onListRebuilt();
                         mPostListReadyRunnable = null;
diff --git a/core/java/com/android/internal/os/AppZygoteInit.java b/core/java/com/android/internal/os/AppZygoteInit.java
index afe6dad..6ba584d 100644
--- a/core/java/com/android/internal/os/AppZygoteInit.java
+++ b/core/java/com/android/internal/os/AppZygoteInit.java
@@ -73,6 +73,9 @@
             Log.i(TAG, "Beginning application preload for " + appInfo.packageName);
             LoadedApk loadedApk = new LoadedApk(null, appInfo, null, null, false, true, false);
             ClassLoader loader = loadedApk.getClassLoader();
+
+            Zygote.allowAppFilesAcrossFork(appInfo);
+
             Class<?> cl;
             Method m;
             try {
diff --git a/core/java/com/android/internal/os/WebViewZygoteInit.java b/core/java/com/android/internal/os/WebViewZygoteInit.java
index c8d30b2..9ed7384 100644
--- a/core/java/com/android/internal/os/WebViewZygoteInit.java
+++ b/core/java/com/android/internal/os/WebViewZygoteInit.java
@@ -78,18 +78,7 @@
             ClassLoader loader = loadedApk.getClassLoader();
             doPreload(loader, WebViewFactory.getWebViewLibrary(appInfo));
 
-            // Add the APK to the Zygote's list of allowed files for children.
-            Zygote.nativeAllowFileAcrossFork(appInfo.sourceDir);
-            if (appInfo.splitSourceDirs != null) {
-                for (String path : appInfo.splitSourceDirs) {
-                    Zygote.nativeAllowFileAcrossFork(path);
-                }
-            }
-            if (appInfo.sharedLibraryFiles != null) {
-                for (String path : appInfo.sharedLibraryFiles) {
-                    Zygote.nativeAllowFileAcrossFork(path);
-                }
-            }
+            Zygote.allowAppFilesAcrossFork(appInfo);
 
             Log.i(TAG, "Application preload done");
         }
diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java
index bc7cf87..474d4d7 100644
--- a/core/java/com/android/internal/os/Zygote.java
+++ b/core/java/com/android/internal/os/Zygote.java
@@ -20,6 +20,7 @@
 
 import static com.android.internal.os.ZygoteConnectionConstants.MAX_ZYGOTE_ARGC;
 
+import android.content.pm.ApplicationInfo;
 import android.net.Credentials;
 import android.net.LocalServerSocket;
 import android.net.LocalSocket;
@@ -370,6 +371,27 @@
     protected static native void nativeAllowFileAcrossFork(String path);
 
     /**
+     * Lets children of the zygote inherit open file descriptors that belong to the
+     * ApplicationInfo that is passed in.
+     *
+     * @param appInfo ApplicationInfo of the application
+     */
+    protected static void allowAppFilesAcrossFork(ApplicationInfo appInfo) {
+        Zygote.nativeAllowFileAcrossFork(appInfo.sourceDir);
+        if (appInfo.splitSourceDirs != null) {
+            for (String path : appInfo.splitSourceDirs) {
+                Zygote.nativeAllowFileAcrossFork(path);
+            }
+        }
+        // As well as its shared libs
+        if (appInfo.sharedLibraryFiles != null) {
+            for (String path : appInfo.sharedLibraryFiles) {
+                Zygote.nativeAllowFileAcrossFork(path);
+            }
+        }
+    }
+
+    /**
      * Installs a seccomp filter that limits setresuid()/setresgid() to the passed-in range
      * @param uidGidMin The smallest allowed uid/gid
      * @param uidGidMax The largest allowed uid/gid
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index 9afd5d0..51a3b48 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -301,6 +301,7 @@
         "libhwui",
         "libdl",
         "libstatslog",
+        "server_configurable_flags",
     ],
 
     generated_sources: ["android_util_StatsLog.cpp"],
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index c90071a..49598bb 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -31,6 +31,7 @@
 #include <binder/Parcel.h>
 #include <utils/threads.h>
 #include <cutils/properties.h>
+#include <server_configurable_flags/get_flags.h>
 
 #include <SkGraphics.h>
 
@@ -774,7 +775,17 @@
       addOption("-XX:LowMemoryMode");
     }
 
-    parseRuntimeOption("dalvik.vm.gctype", gctypeOptsBuf, "-Xgc:");
+    std::string gc_type_override =
+            server_configurable_flags::GetServerConfigurableFlag("runtime_native", "gctype", "");
+    std::string gc_type_override_temp;
+    if (gc_type_override.empty()) {
+        parseRuntimeOption("dalvik.vm.gctype", gctypeOptsBuf, "-Xgc:");
+    } else {
+        // Copy the string so it doesn't go out of scope since addOption does not make a copy.
+        gc_type_override_temp = "-Xgc:" + gc_type_override;
+        addOption(gc_type_override_temp.c_str());
+    }
+
     parseRuntimeOption("dalvik.vm.backgroundgctype", backgroundgcOptsBuf, "-XX:BackgroundGC=");
 
     /*
diff --git a/core/jni/android_hardware_input_InputWindowHandle.cpp b/core/jni/android_hardware_input_InputWindowHandle.cpp
index c0e45b1..67a7441 100644
--- a/core/jni/android_hardware_input_InputWindowHandle.cpp
+++ b/core/jni/android_hardware_input_InputWindowHandle.cpp
@@ -55,6 +55,7 @@
     jfieldID ownerUid;
     jfieldID inputFeatures;
     jfieldID displayId;
+    jfieldID portalToDisplayId;
 } gInputWindowHandleClassInfo;
 
 static Mutex gHandleMutex;
@@ -154,6 +155,8 @@
             gInputWindowHandleClassInfo.inputFeatures);
     mInfo.displayId = env->GetIntField(obj,
             gInputWindowHandleClassInfo.displayId);
+    mInfo.portalToDisplayId = env->GetIntField(obj,
+            gInputWindowHandleClassInfo.portalToDisplayId);
 
     jobject inputApplicationHandleObj = env->GetObjectField(obj,
             gInputWindowHandleClassInfo.inputApplicationHandle);
@@ -307,6 +310,9 @@
 
     GET_FIELD_ID(gInputWindowHandleClassInfo.displayId, clazz,
             "displayId", "I");
+
+    GET_FIELD_ID(gInputWindowHandleClassInfo.portalToDisplayId, clazz,
+            "portalToDisplayId", "I");
     return 0;
 }
 
diff --git a/core/proto/android/providers/settings/global.proto b/core/proto/android/providers/settings/global.proto
index e0eaf14..712994b 100644
--- a/core/proto/android/providers/settings/global.proto
+++ b/core/proto/android/providers/settings/global.proto
@@ -999,7 +999,7 @@
         optional SettingProto watchdog_poor_network_test_enabled = 22 [ (android.privacy).dest = DEST_AUTOMATIC ];
         optional SettingProto suspend_optimizations_enabled = 23 [ (android.privacy).dest = DEST_AUTOMATIC ];
         optional SettingProto verbose_logging_enabled = 24 [ (android.privacy).dest = DEST_AUTOMATIC ];
-        optional SettingProto connected_mac_randomization_enabled = 25 [ (android.privacy).dest = DEST_AUTOMATIC ];
+        reserved 25; // connected_mac_randomization_enabled
         optional SettingProto max_dhcp_retry_count = 26 [ (android.privacy).dest = DEST_AUTOMATIC ];
         optional SettingProto mobile_data_transition_wakelock_timeout_ms = 27 [ (android.privacy).dest = DEST_AUTOMATIC ];
         // Controls whether WiFi configurations created by a Device Owner app should
diff --git a/core/res/res/layout/chooser_grid.xml b/core/res/res/layout/chooser_grid.xml
index ded2b35..c42f43a 100644
--- a/core/res/res/layout/chooser_grid.xml
+++ b/core/res/res/layout/chooser_grid.xml
@@ -29,8 +29,6 @@
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_alwaysShow="true"
-            android:elevation="8dp"
-            android:paddingStart="16dp"
             android:background="?attr/colorBackgroundFloating" >
         <TextView android:id="@+id/profile_button"
                   android:layout_width="wrap_content"
@@ -46,25 +44,66 @@
                   android:layout_alignParentTop="true"
                   android:layout_alignParentRight="true"
                   android:singleLine="true"/>
-        <ImageView android:id="@+id/title_icon"
-                   android:layout_width="24dp"
-                   android:layout_height="24dp"
-                   android:layout_marginEnd="16dp"
-                   android:visibility="gone"
-                   android:scaleType="fitCenter"
-                   android:layout_below="@id/profile_button"
-                   android:layout_alignParentLeft="true"/>
+
         <TextView android:id="@+id/title"
                   android:layout_height="wrap_content"
                   android:layout_width="wrap_content"
                   android:textAppearance="?attr/textAppearanceMedium"
-                  android:textSize="14sp"
-                  android:gravity="start|center_vertical"
+                  android:textSize="20sp"
+                  android:gravity="center"
                   android:paddingEnd="?attr/dialogPreferredPadding"
                   android:paddingTop="12dp"
-                  android:paddingBottom="12dp"
+                  android:paddingBottom="6dp"
                   android:layout_below="@id/profile_button"
-                  android:layout_toRightOf="@id/title_icon"/>
+                  android:layout_centerHorizontal="true"/>
+    </RelativeLayout>
+
+    <RelativeLayout 
+        android:id="@+id/content_preview"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:background="?attr/colorBackgroundFloating">
+      
+      <view class="com.android.internal.app.ChooserActivity$RoundedRectImageView"
+            android:id="@+id/content_preview_thumbnail"
+            android:layout_alignParentTop="true"
+            android:layout_width="100dp"
+            android:layout_height="wrap_content"
+            android:layout_alignParentStart="true"
+            android:gravity="center"
+            android:adjustViewBounds="true"
+            android:maxWidth="90dp"
+            android:maxHeight="90dp"
+            android:scaleType="fitCenter"
+            android:padding="5dp"/>
+
+      <TextView
+          android:id="@+id/content_preview_title"
+          android:layout_alignParentTop="true"
+          android:layout_toEndOf="@id/content_preview_thumbnail"
+          android:layout_width="match_parent"
+          android:layout_height="wrap_content"
+          android:gravity="start|top"
+          android:textAppearance="?attr/textAppearanceMedium"
+          android:maxLines="2"
+          android:ellipsize="end"
+          android:paddingStart="15dp"
+          android:paddingEnd="15dp"
+          android:paddingTop="10dp" />
+
+      <TextView
+          android:id="@+id/content_preview_text"
+          android:layout_width="match_parent"
+          android:layout_height="wrap_content"
+          android:layout_below="@id/content_preview_title"
+          android:layout_toEndOf="@id/content_preview_thumbnail"
+          android:gravity="start|top"
+          android:maxLines="2"
+          android:ellipsize="end"
+          android:paddingStart="15dp"
+          android:paddingEnd="15dp"
+          android:paddingTop="10dp"
+          android:paddingBottom="5dp"/>
     </RelativeLayout>
 
     <ListView
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index c870683..ef3834c 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -714,4 +714,7 @@
     <dimen name="harmful_app_message_padding_bottom">24dp</dimen>
     <!-- Line spacing modifier for the message field of the harmful app dialog -->
     <item name="harmful_app_message_line_spacing_modifier" type="dimen">1.22</item>
+
+    <!-- chooser corner radius -->
+    <dimen name="chooser_corner_radius">4dp</dimen>
 </resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index a761baf..6adb4a7 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -3082,7 +3082,7 @@
     <!-- Label for a link to a intent resolver dialog when selecting an editor application -->
     <string name="whichEditApplicationLabel">Edit</string>
     <!-- Title of intent resolver dialog when selecting a sharing application to run. -->
-    <string name="whichSendApplication">Share with</string>
+    <string name="whichSendApplication">Share</string>
     <!-- Title of intent resolver dialog when selecting a sharing application to run
          and a previously used application is known. -->
     <string name="whichSendApplicationNamed">Share with %1$s</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index ca8e226..54a3243 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -50,6 +50,10 @@
   <java-symbol type="id" name="characterPicker" />
   <java-symbol type="id" name="clearDefaultHint" />
   <java-symbol type="id" name="contentPanel" />
+  <java-symbol type="id" name="content_preview" />
+  <java-symbol type="id" name="content_preview_thumbnail" />
+  <java-symbol type="id" name="content_preview_text" />
+  <java-symbol type="id" name="content_preview_title" />
   <java-symbol type="id" name="current_scene" />
   <java-symbol type="id" name="scene_layoutid_cache" />
   <java-symbol type="id" name="customPanel" />
@@ -2703,9 +2707,9 @@
   <java-symbol type="layout" name="date_picker_month_item_material" />
   <java-symbol type="id" name="month_view" />
   <java-symbol type="integer" name="config_zen_repeat_callers_threshold" />
+  <java-symbol type="dimen" name="chooser_corner_radius" />
   <java-symbol type="layout" name="chooser_grid" />
   <java-symbol type="layout" name="resolve_grid_item" />
-  <java-symbol type="id" name="title_icon" />
   <java-symbol type="id" name="day_picker_view_pager" />
   <java-symbol type="layout" name="day_picker_content_material" />
   <java-symbol type="drawable" name="scroll_indicator_material" />
diff --git a/core/tests/coretests/Android.mk b/core/tests/coretests/Android.mk
index 9d04e63..6a81050 100644
--- a/core/tests/coretests/Android.mk
+++ b/core/tests/coretests/Android.mk
@@ -37,7 +37,9 @@
     mockwebserver \
     guava \
     androidx.test.runner \
+    androidx.test.ext.junit \
     androidx.test.rules \
+    androidx.test.espresso.core \
     mockito-target-minus-junit4 \
     espresso-core \
     ub-uiautomator \
diff --git a/core/tests/coretests/AndroidManifest.xml b/core/tests/coretests/AndroidManifest.xml
index 86818c6..268bb81 100644
--- a/core/tests/coretests/AndroidManifest.xml
+++ b/core/tests/coretests/AndroidManifest.xml
@@ -62,6 +62,7 @@
     <uses-permission android:name="android.permission.READ_LOGS"/>
     <uses-permission android:name="android.permission.READ_PHONE_STATE" />
     <uses-permission android:name="android.permission.READ_SMS"/>
+    <uses-permission android:name="android.permission.START_ACTIVITIES_FROM_BACKGROUND"/>
     <uses-permission android:name="android.permission.UPDATE_DEVICE_STATS" />
     <uses-permission android:name="android.permission.USE_CREDENTIALS" />
     <uses-permission android:name="android.permission.WAKE_LOCK" />
@@ -1144,6 +1145,14 @@
             </intent-filter>
         </activity>
 
+        <activity android:name="android.view.accessibility.AccessibilityTestActivity"
+                  android:label="AccessibilityTestActivity" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+            </intent-filter>
+        </activity>
+
         <!-- Activity-level metadata -->
         <meta-data android:name="com.android.frameworks.coretests.isApp" android:value="true" />
         <meta-data android:name="com.android.frameworks.coretests.string" android:value="foo" />
diff --git a/core/tests/coretests/res/layout/accessibility_test.xml b/core/tests/coretests/res/layout/accessibility_test.xml
new file mode 100644
index 0000000..1bdd21b
--- /dev/null
+++ b/core/tests/coretests/res/layout/accessibility_test.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2018 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.
+  -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <Button android:id="@+id/appNameBtn"
+        android:text="@string/app_name"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginRight="60dp"
+        android:bufferType="normal">
+    </Button>
+</LinearLayout>
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index 0b5bde7..e32b412 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -509,7 +509,6 @@
                     Settings.Global.WIFI_ALWAYS_REQUESTED,
                     Settings.Global.WIFI_BADGING_THRESHOLDS,
                     Settings.Global.WIFI_BOUNCE_DELAY_OVERRIDE_MS,
-                    Settings.Global.WIFI_CONNECTED_MAC_RANDOMIZATION_ENABLED,
                     Settings.Global.WIFI_COUNTRY_CODE,
                     Settings.Global.WIFI_DATA_STALL_MIN_TX_BAD,
                     Settings.Global.WIFI_DATA_STALL_MIN_TX_SUCCESS_WITHOUT_RX,
diff --git a/core/tests/coretests/src/android/view/AccessibilityInteractionControllerTest.java b/core/tests/coretests/src/android/view/AccessibilityInteractionControllerTest.java
new file mode 100644
index 0000000..d0719cb
--- /dev/null
+++ b/core/tests/coretests/src/android/view/AccessibilityInteractionControllerTest.java
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
+import android.accessibilityservice.AccessibilityServiceInfo;
+import android.app.Activity;
+import android.app.Instrumentation;
+import android.app.Service;
+import android.app.UiAutomation;
+import android.graphics.Rect;
+import android.os.SystemClock;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.rule.ActivityTestRule;
+import android.support.test.runner.AndroidJUnit4;
+import android.text.TextUtils;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityManager;
+import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityTestActivity;
+import android.view.accessibility.AccessibilityWindowInfo;
+
+import com.android.compatibility.common.util.TestUtils;
+import com.android.frameworks.coretests.R;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.List;
+import java.util.concurrent.TimeoutException;
+
+@RunWith(AndroidJUnit4.class)
+public class AccessibilityInteractionControllerTest {
+    static final long TIMEOUT_DEFAULT = 10000; // 10 seconds
+
+    private static Instrumentation sInstrumentation;
+    private static UiAutomation sUiAutomation;
+
+    @Rule
+    public ActivityTestRule<AccessibilityTestActivity> mActivityRule = new ActivityTestRule<>(
+            AccessibilityTestActivity.class, false, false);
+
+    private AccessibilityInteractionController mAccessibilityInteractionController;
+    private ViewRootImpl mViewRootImpl;
+    private View mButton;
+
+    @BeforeClass
+    public static void oneTimeSetup() {
+        sInstrumentation = InstrumentationRegistry.getInstrumentation();
+        sUiAutomation = sInstrumentation.getUiAutomation();
+    }
+
+    @AfterClass
+    public static void postTestTearDown() {
+        sUiAutomation.destroy();
+    }
+
+    @Before
+    public void setUp() throws Throwable {
+        launchActivity();
+        enableTouchExploration(true);
+        mActivityRule.runOnUiThread(() -> {
+            mViewRootImpl = mActivityRule.getActivity().getWindow().getDecorView()
+                    .getViewRootImpl();
+            mButton = mActivityRule.getActivity().findViewById(R.id.appNameBtn);
+        });
+        mAccessibilityInteractionController =
+                mViewRootImpl.getAccessibilityInteractionController();
+    }
+
+    @After
+    public void tearDown() {
+        enableTouchExploration(false);
+    }
+
+    @Test
+    public void clearAccessibilityFocus_shouldClearFocus() throws Exception {
+        performAccessibilityFocus("com.android.frameworks.coretests:id/appNameBtn");
+        assertTrue("Button should have a11y focus",
+                mButton.isAccessibilityFocused());
+        mAccessibilityInteractionController.clearAccessibilityFocusClientThread();
+        sInstrumentation.waitForIdleSync();
+        assertFalse("Button should not have a11y focus",
+                mButton.isAccessibilityFocused());
+    }
+
+    @Test
+    public void clearAccessibilityFocus_uiThread_shouldClearFocus() throws Exception {
+        performAccessibilityFocus("com.android.frameworks.coretests:id/appNameBtn");
+        assertTrue("Button should have a11y focus",
+                mButton.isAccessibilityFocused());
+        sInstrumentation.runOnMainSync(() -> {
+            mAccessibilityInteractionController.clearAccessibilityFocusClientThread();
+        });
+        assertFalse("Button should not have a11y focus",
+                mButton.isAccessibilityFocused());
+    }
+
+    private void launchActivity() {
+        final Object waitObject = new Object();
+        final int[] location = new int[2];
+        final StringBuilder activityPackage = new StringBuilder();
+        final Rect bounds = new Rect();
+        final StringBuilder activityTitle = new StringBuilder();
+        try {
+            final long executionStartTimeMillis = SystemClock.uptimeMillis();
+            sUiAutomation.setOnAccessibilityEventListener((event) -> {
+                if (event.getEventTime() < executionStartTimeMillis) {
+                    return;
+                }
+                synchronized (waitObject) {
+                    waitObject.notifyAll();
+                }
+            });
+            enableRetrieveAccessibilityWindows();
+
+            final Activity activity = mActivityRule.launchActivity(null);
+            sInstrumentation.runOnMainSync(() -> {
+                activity.getWindow().getDecorView().getLocationOnScreen(location);
+                activityPackage.append(activity.getPackageName());
+                activityTitle.append(activity.getTitle());
+            });
+            sInstrumentation.waitForIdleSync();
+
+            TestUtils.waitOn(waitObject, () -> {
+                final AccessibilityWindowInfo window = findWindowByTitle(activityTitle);
+                if (window == null) return false;
+                window.getBoundsInScreen(bounds);
+                activity.getWindow().getDecorView().getLocationOnScreen(location);
+                if (bounds.isEmpty()) {
+                    return false;
+                }
+                return (!bounds.isEmpty())
+                        && (bounds.left == location[0]) && (bounds.top == location[1]);
+            }, TIMEOUT_DEFAULT, "Launch Activity");
+        } finally {
+            sUiAutomation.setOnAccessibilityEventListener(null);
+        }
+    }
+
+    private void enableRetrieveAccessibilityWindows() {
+        AccessibilityServiceInfo info = sUiAutomation.getServiceInfo();
+        info.flags |= AccessibilityServiceInfo.FLAG_RETRIEVE_INTERACTIVE_WINDOWS;
+        sUiAutomation.setServiceInfo(info);
+    }
+
+    private void enableTouchExploration(boolean enabled) {
+        final Object waitObject = new Object();
+        final AccessibilityManager accessibilityManager =
+                (AccessibilityManager) sInstrumentation.getContext().getSystemService(
+                        Service.ACCESSIBILITY_SERVICE);
+        final AccessibilityManager.TouchExplorationStateChangeListener listener = status -> {
+            synchronized (waitObject) {
+                waitObject.notifyAll();
+            }
+        };
+        try {
+            accessibilityManager.addTouchExplorationStateChangeListener(listener);
+            final AccessibilityServiceInfo info = sUiAutomation.getServiceInfo();
+            if (enabled) {
+                info.flags |= AccessibilityServiceInfo.FLAG_REQUEST_TOUCH_EXPLORATION_MODE;
+            } else {
+                info.flags &= ~AccessibilityServiceInfo.FLAG_REQUEST_TOUCH_EXPLORATION_MODE;
+            }
+            sUiAutomation.setServiceInfo(info);
+            TestUtils.waitOn(waitObject,
+                    () -> accessibilityManager.isTouchExplorationEnabled() == enabled,
+                    TIMEOUT_DEFAULT,
+                    (enabled ? "Enable" : "Disable") + "touch exploration");
+        } finally {
+            accessibilityManager.removeTouchExplorationStateChangeListener(listener);
+        }
+    }
+
+    private void performAccessibilityFocus(String viewId) throws TimeoutException {
+        final AccessibilityNodeInfo node = sUiAutomation.getRootInActiveWindow()
+                .findAccessibilityNodeInfosByViewId(viewId).get(0);
+        // Perform an action and wait for an event
+        sUiAutomation.executeAndWaitForEvent(
+                () -> node.performAction(AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS),
+                event -> event.getEventType() == AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED,
+                TIMEOUT_DEFAULT);
+        node.refresh();
+    }
+
+    private AccessibilityWindowInfo findWindowByTitle(CharSequence title) {
+        final List<AccessibilityWindowInfo> windows = sUiAutomation.getWindows();
+        AccessibilityWindowInfo returnValue = null;
+        for (int i = 0; i < windows.size(); i++) {
+            final AccessibilityWindowInfo window = windows.get(i);
+            if (TextUtils.equals(title, window.getTitle())) {
+                returnValue = window;
+            } else {
+                window.recycle();
+            }
+        }
+        return returnValue;
+    }
+}
diff --git a/core/tests/coretests/src/android/view/accessibility/AccessibilityTestActivity.java b/core/tests/coretests/src/android/view/accessibility/AccessibilityTestActivity.java
new file mode 100644
index 0000000..a17fa73
--- /dev/null
+++ b/core/tests/coretests/src/android/view/accessibility/AccessibilityTestActivity.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view.accessibility;
+
+import android.app.Activity;
+import android.app.KeyguardManager;
+import android.content.Context;
+import android.os.Bundle;
+
+import com.android.frameworks.coretests.R;
+
+/**
+ * An activity for accessibility test.
+ */
+public class AccessibilityTestActivity extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        turnOnScreen();
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.accessibility_test);
+    }
+
+    private void turnOnScreen() {
+        setTurnScreenOn(true);
+        setShowWhenLocked(true);
+        KeyguardManager keyguardManager = (KeyguardManager) getSystemService(
+                Context.KEYGUARD_SERVICE);
+        keyguardManager.requestDismissKeyguard(this, null);
+    }
+}
diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
index aaa624e..21fcae7 100644
--- a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
+++ b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
@@ -16,12 +16,12 @@
 
 package com.android.internal.app;
 
-import static android.support.test.espresso.Espresso.onView;
-import static android.support.test.espresso.action.ViewActions.click;
-import static android.support.test.espresso.assertion.ViewAssertions.matches;
-import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static android.support.test.espresso.matcher.ViewMatchers.withId;
-import static android.support.test.espresso.matcher.ViewMatchers.withText;
+import static androidx.test.espresso.Espresso.onView;
+import static androidx.test.espresso.action.ViewActions.click;
+import static androidx.test.espresso.assertion.ViewAssertions.matches;
+import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
+import static androidx.test.espresso.matcher.ViewMatchers.withId;
+import static androidx.test.espresso.matcher.ViewMatchers.withText;
 
 import static com.android.internal.app.ChooserWrapperActivity.sOverrides;
 
@@ -33,12 +33,18 @@
 import static org.mockito.Mockito.when;
 
 import android.app.usage.UsageStatsManager;
+import android.content.ClipData;
 import android.content.Intent;
 import android.content.pm.ResolveInfo;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.net.Uri;
 
-import androidx.test.InstrumentationRegistry;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.platform.app.InstrumentationRegistry;
 import androidx.test.rule.ActivityTestRule;
-import androidx.test.runner.AndroidJUnit4;
 
 import com.android.internal.R;
 import com.android.internal.app.ResolverActivity.ResolvedComponentInfo;
@@ -69,7 +75,21 @@
 
     @Test
     public void customTitle() throws InterruptedException {
-        Intent sendIntent = createSendImageIntent();
+        Intent viewIntent = createViewTextIntent();
+        List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
+
+        when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
+                Mockito.anyBoolean(),
+                Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
+        mActivityRule.launchActivity(Intent.createChooser(viewIntent, "chooser test"));
+
+        waitForIdle();
+        onView(withId(R.id.title)).check(matches(withText("chooser test")));
+    }
+
+    @Test
+    public void customTitleIgnoredForSendIntents() throws InterruptedException {
+        Intent sendIntent = createSendTextIntent();
         List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
 
         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
@@ -77,12 +97,12 @@
                 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
         mActivityRule.launchActivity(Intent.createChooser(sendIntent, "chooser test"));
         waitForIdle();
-        onView(withId(R.id.title)).check(matches(withText("chooser test")));
+        onView(withId(R.id.title)).check(matches(withText(R.string.whichSendApplication)));
     }
 
     @Test
     public void emptyTitle() throws InterruptedException {
-        Intent sendIntent = createSendImageIntent();
+        Intent sendIntent = createSendTextIntent();
         List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
 
         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
@@ -95,8 +115,72 @@
     }
 
     @Test
+    public void emptyPreviewTitleAndThumbnail() throws InterruptedException {
+        Intent sendIntent = createSendTextIntentWithPreview(null, null);
+        List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
+
+        when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
+                Mockito.anyBoolean(),
+                Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
+        mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
+        waitForIdle();
+        onView(withId(R.id.content_preview_title)).check(matches(not(isDisplayed())));
+        onView(withId(R.id.content_preview_thumbnail)).check(matches(not(isDisplayed())));
+    }
+
+    @Test
+    public void visiblePreviewTitleWithoutThumbnail() throws InterruptedException {
+        String previewTitle = "My Content Preview Title";
+        Intent sendIntent = createSendTextIntentWithPreview(previewTitle, null);
+        List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
+
+        when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
+                Mockito.anyBoolean(),
+                Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
+        mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
+        waitForIdle();
+        onView(withId(R.id.content_preview_title)).check(matches(isDisplayed()));
+        onView(withId(R.id.content_preview_title)).check(matches(withText(previewTitle)));
+        onView(withId(R.id.content_preview_thumbnail)).check(matches(not(isDisplayed())));
+    }
+
+    @Test
+    public void visiblePreviewTitleWithInvalidThumbnail() throws InterruptedException {
+        String previewTitle = "My Content Preview Title";
+        Intent sendIntent = createSendTextIntentWithPreview(previewTitle,
+                Uri.parse("tel:(+49)12345789"));
+        List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
+
+        when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
+                Mockito.anyBoolean(),
+                Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
+        mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
+        waitForIdle();
+        onView(withId(R.id.content_preview_title)).check(matches(isDisplayed()));
+        onView(withId(R.id.content_preview_thumbnail)).check(matches(not(isDisplayed())));
+    }
+
+    @Test
+    public void visiblePreviewTitleAndThumbnail() throws InterruptedException {
+        String previewTitle = "My Content Preview Title";
+        Intent sendIntent = createSendTextIntentWithPreview(previewTitle,
+                Uri.parse("android.resource://com.android.frameworks.coretests/"
+                        + com.android.frameworks.coretests.R.drawable.test320x240));
+        sOverrides.previewThumbnail = createBitmap();
+        List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
+
+        when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
+                Mockito.anyBoolean(),
+                Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
+        mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
+        waitForIdle();
+        onView(withId(R.id.content_preview_title)).check(matches(isDisplayed()));
+        onView(withId(R.id.content_preview_thumbnail)).check(matches(isDisplayed()));
+    }
+
+    @Test
     public void twoOptionsAndUserSelectsOne() throws InterruptedException {
-        Intent sendIntent = createSendImageIntent();
+        Intent sendIntent = createSendTextIntent();
         List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
 
         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
@@ -125,7 +209,7 @@
 
     @Test
     public void updateChooserCountsAndModelAfterUserSelection() throws InterruptedException {
-        Intent sendIntent = createSendImageIntent();
+        Intent sendIntent = createSendTextIntent();
         List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
 
         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
@@ -158,7 +242,7 @@
         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
                 Mockito.anyBoolean(),
                 Mockito.isA(List.class))).thenReturn(null);
-        Intent sendIntent = createSendImageIntent();
+        Intent sendIntent = createSendTextIntent();
         final ChooserWrapperActivity activity = mActivityRule
                 .launchActivity(Intent.createChooser(sendIntent, null));
         waitForIdle();
@@ -186,7 +270,7 @@
                 Mockito.anyBoolean(),
                 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
 
-        Intent sendIntent = createSendImageIntent();
+        Intent sendIntent = createSendTextIntent();
         final ChooserWrapperActivity activity = mActivityRule
                 .launchActivity(Intent.createChooser(sendIntent, null));
         waitForIdle();
@@ -197,7 +281,7 @@
 
     @Test
     public void hasOtherProfileOneOption() throws Exception {
-        Intent sendIntent = createSendImageIntent();
+        Intent sendIntent = createSendTextIntent();
         List<ResolvedComponentInfo> resolvedComponentInfos =
                 createResolvedComponentsForTestWithOtherProfile(2);
         ResolveInfo toChoose = resolvedComponentInfos.get(1).getResolveInfoAt(0);
@@ -234,7 +318,7 @@
 
     @Test
     public void hasOtherProfileTwoOptionsAndUserSelectsOne() throws Exception {
-        Intent sendIntent = createSendImageIntent();
+        Intent sendIntent = createSendTextIntent();
         List<ResolvedComponentInfo> resolvedComponentInfos =
                 createResolvedComponentsForTestWithOtherProfile(3);
         ResolveInfo toChoose = resolvedComponentInfos.get(1).getResolveInfoAt(0);
@@ -273,7 +357,7 @@
 
     @Test
     public void hasLastChosenActivityAndOtherProfile() throws Exception {
-        Intent sendIntent = createSendImageIntent();
+        Intent sendIntent = createSendTextIntent();
         List<ResolvedComponentInfo> resolvedComponentInfos =
                 createResolvedComponentsForTestWithOtherProfile(3);
         ResolveInfo toChoose = resolvedComponentInfos.get(1).getResolveInfoAt(0);
@@ -308,14 +392,33 @@
         assertThat(chosen[0], is(toChoose));
     }
 
-    private Intent createSendImageIntent() {
+    private Intent createSendTextIntent() {
         Intent sendIntent = new Intent();
         sendIntent.setAction(Intent.ACTION_SEND);
         sendIntent.putExtra(Intent.EXTRA_TEXT, "testing intent sending");
-        sendIntent.setType("image/jpeg");
         return sendIntent;
     }
 
+    private Intent createSendTextIntentWithPreview(String title, Uri imageThumbnail) {
+        Intent sendIntent = new Intent();
+        sendIntent.setAction(Intent.ACTION_SEND);
+        sendIntent.putExtra(Intent.EXTRA_TEXT, "testing intent sending");
+        sendIntent.putExtra(Intent.EXTRA_TITLE, title);
+        if (imageThumbnail != null) {
+            ClipData.Item clipItem = new ClipData.Item(imageThumbnail);
+            sendIntent.setClipData(new ClipData("Clip Label", new String[]{"image/png"}, clipItem));
+        }
+
+        return sendIntent;
+    }
+
+    private Intent createViewTextIntent() {
+        Intent viewIntent = new Intent();
+        viewIntent.setAction(Intent.ACTION_VIEW);
+        viewIntent.putExtra(Intent.EXTRA_TEXT, "testing intent viewing");
+        return viewIntent;
+    }
+
     private List<ResolvedComponentInfo> createResolvedComponentsForTest(int numberOfResults) {
         List<ResolvedComponentInfo> infoList = new ArrayList<>(numberOfResults);
         for (int i = 0; i < numberOfResults; i++) {
@@ -340,4 +443,24 @@
     private void waitForIdle() {
         InstrumentationRegistry.getInstrumentation().waitForIdleSync();
     }
-}
\ No newline at end of file
+
+    private Bitmap createBitmap() {
+        int width = 200;
+        int height = 200;
+        Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+        Canvas canvas = new Canvas(bitmap);
+
+        Paint paint = new Paint();
+        paint.setColor(Color.RED);
+        paint.setStyle(Paint.Style.FILL);
+        canvas.drawPaint(paint);
+
+        paint.setColor(Color.WHITE);
+        paint.setAntiAlias(true);
+        paint.setTextSize(14.f);
+        paint.setTextAlign(Paint.Align.CENTER);
+        canvas.drawText("Hi!", (width / 2.f), (height / 2.f), paint);
+
+        return bitmap;
+    }
+}
diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java b/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java
index 60529f6..637d2ea 100644
--- a/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java
+++ b/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java
@@ -21,6 +21,9 @@
 import android.app.usage.UsageStatsManager;
 import android.content.Context;
 import android.content.pm.PackageManager;
+import android.graphics.Bitmap;
+import android.net.Uri;
+import android.util.Size;
 
 import java.util.function.Function;
 
@@ -74,6 +77,14 @@
         return super.getPackageManager();
     }
 
+    @Override
+    protected Bitmap loadThumbnail(Uri uri, Size size) {
+        if (sOverrides.previewThumbnail != null) {
+            return sOverrides.previewThumbnail;
+        }
+        return super.loadThumbnail(uri, size);
+    }
+
     /**
      * We cannot directly mock the activity created since instrumentation creates it.
      * <p>
@@ -85,11 +96,13 @@
         public Function<TargetInfo, Boolean> onSafelyStartCallback;
         public ResolverListController resolverListController;
         public Boolean isVoiceInteraction;
+        public Bitmap previewThumbnail;
 
         public void reset() {
             onSafelyStartCallback = null;
             isVoiceInteraction = null;
             createPackageManager = null;
+            previewThumbnail = null;
             resolverListController = mock(ResolverListController.class);
         }
     }
diff --git a/media/Android.bp b/media/Android.bp
index 3181a29..e7d5faf 100644
--- a/media/Android.bp
+++ b/media/Android.bp
@@ -66,7 +66,9 @@
 filegroup {
     name: "media1-srcs",
     srcs: [
+        "apex/java/android/media/MediaDescription.java",
         "apex/java/android/media/MediaParceledListSlice.java",
+        "apex/java/android/media/Rating.java",
         "apex/java/android/media/VolumeProvider.java",
         "apex/java/android/media/browse/MediaBrowser.java",
         "apex/java/android/media/browse/MediaBrowserUtils.java",
diff --git a/media/java/android/media/MediaDescription.aidl b/media/apex/java/android/media/MediaDescription.aidl
similarity index 100%
rename from media/java/android/media/MediaDescription.aidl
rename to media/apex/java/android/media/MediaDescription.aidl
diff --git a/media/java/android/media/MediaDescription.java b/media/apex/java/android/media/MediaDescription.java
similarity index 93%
rename from media/java/android/media/MediaDescription.java
rename to media/apex/java/android/media/MediaDescription.java
index 31079e5..39eeb3e 100644
--- a/media/java/android/media/MediaDescription.java
+++ b/media/apex/java/android/media/MediaDescription.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright 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.media;
 
 import android.annotation.Nullable;
@@ -226,7 +242,7 @@
             return false;
         }
 
-        if (!(o instanceof MediaDescription)){
+        if (!(o instanceof MediaDescription)) {
             return false;
         }
 
@@ -375,6 +391,11 @@
             return this;
         }
 
+        /**
+         * Build {@link MediaDescription}.
+         *
+         * @return a new media description.
+         */
         public MediaDescription build() {
             return new MediaDescription(mMediaId, mTitle, mSubtitle, mDescription, mIcon, mIconUri,
                     mExtras, mMediaUri);
diff --git a/media/java/android/media/Rating.aidl b/media/apex/java/android/media/Rating.aidl
similarity index 100%
rename from media/java/android/media/Rating.aidl
rename to media/apex/java/android/media/Rating.aidl
diff --git a/media/java/android/media/Rating.java b/media/apex/java/android/media/Rating.java
similarity index 93%
rename from media/java/android/media/Rating.java
rename to media/apex/java/android/media/Rating.java
index 04d5364f..ffe7e48 100644
--- a/media/java/android/media/Rating.java
+++ b/media/apex/java/android/media/Rating.java
@@ -33,7 +33,7 @@
  * through one of the factory methods.
  */
 public final class Rating implements Parcelable {
-    private final static String TAG = "Rating";
+    private static final String TAG = "Rating";
 
     /**
      * @hide
@@ -55,40 +55,40 @@
      * type, but can be used by other classes to indicate they do not support
      * Rating.
      */
-    public final static int RATING_NONE = 0;
+    public static final int RATING_NONE = 0;
 
     /**
      * A rating style with a single degree of rating, "heart" vs "no heart". Can be used to
      * indicate the content referred to is a favorite (or not).
      */
-    public final static int RATING_HEART = 1;
+    public static final int RATING_HEART = 1;
 
     /**
      * A rating style for "thumb up" vs "thumb down".
      */
-    public final static int RATING_THUMB_UP_DOWN = 2;
+    public static final int RATING_THUMB_UP_DOWN = 2;
 
     /**
      * A rating style with 0 to 3 stars.
      */
-    public final static int RATING_3_STARS = 3;
+    public static final int RATING_3_STARS = 3;
 
     /**
      * A rating style with 0 to 4 stars.
      */
-    public final static int RATING_4_STARS = 4;
+    public static final int RATING_4_STARS = 4;
 
     /**
      * A rating style with 0 to 5 stars.
      */
-    public final static int RATING_5_STARS = 5;
+    public static final int RATING_5_STARS = 5;
 
     /**
      * A rating style expressed as a percentage.
      */
-    public final static int RATING_PERCENTAGE = 6;
+    public static final int RATING_PERCENTAGE = 6;
 
-    private final static float RATING_NOT_RATED = -1.0f;
+    private static final float RATING_NOT_RATED = -1.0f;
 
     private final int mRatingStyle;
 
@@ -116,8 +116,7 @@
         dest.writeFloat(mRatingValue);
     }
 
-    public static final Parcelable.Creator<Rating> CREATOR
-            = new Parcelable.Creator<Rating>() {
+    public static final Parcelable.Creator<Rating> CREATOR = new Parcelable.Creator<Rating>() {
         /**
          * Rebuilds a Rating previously stored with writeToParcel().
          * @param p    Parcel object to read the Rating from
@@ -205,7 +204,7 @@
                 break;
             default:
                 Log.e(TAG, "Invalid rating style (" + starRatingStyle + ") for a star rating");
-                        return null;
+                return null;
         }
         if ((starRating < 0.0f) || (starRating > maxRating)) {
             Log.e(TAG, "Trying to set out of range star-based rating");
@@ -281,16 +280,16 @@
      *    not star-based, or if it is unrated.
      */
     public float getStarRating() {
+        float ratingValue = -1.0f;
         switch (mRatingStyle) {
             case RATING_3_STARS:
             case RATING_4_STARS:
             case RATING_5_STARS:
                 if (isRated()) {
-                    return mRatingValue;
+                    ratingValue = mRatingValue;
                 }
-            default:
-                return -1.0f;
         }
+        return ratingValue;
     }
 
     /**
diff --git a/packages/ExtServices/AndroidManifest.xml b/packages/ExtServices/AndroidManifest.xml
index 010a810..7fb51b9 100644
--- a/packages/ExtServices/AndroidManifest.xml
+++ b/packages/ExtServices/AndroidManifest.xml
@@ -22,6 +22,7 @@
     coreApp="true">
 
     <uses-permission android:name="android.permission.PROVIDE_RESOLVER_RANKER_SERVICE" />
+    <uses-permission android:name="android.permission.READ_DEVICE_CONFIG" />
 
     <application android:label="@string/app_name"
         android:defaultToDeviceProtectedStorage="true"
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index f523481..ec70f8c 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -618,8 +618,6 @@
     <string name="wifi_display_certification">Wireless display certification</string>
     <!-- Setting Checkbox title whether to enable WiFi Verbose Logging. [CHAR LIMIT=40] -->
     <string name="wifi_verbose_logging">Enable Wi\u2011Fi Verbose Logging</string>
-    <!-- Setting Checkbox title whether to enable connected MAC randomization -->
-    <string name="wifi_connected_mac_randomization">Connected MAC Randomization</string>
     <!-- Setting Checkbox title whether to always keep mobile data active. [CHAR LIMIT=80] -->
     <string name="mobile_data_always_on">Mobile data always active</string>
     <!-- Setting Checkbox title whether to enable hardware acceleration for tethering. [CHAR LIMIT=80] -->
@@ -675,8 +673,6 @@
     <string name="wifi_display_certification_summary">Show options for wireless display certification</string>
     <!-- Setting Checkbox summary whether to enable Wifi verbose Logging [CHAR LIMIT=80] -->
     <string name="wifi_verbose_logging_summary">Increase Wi\u2011Fi logging level, show per SSID RSSI in Wi\u2011Fi Picker</string>
-    <!-- Setting Checkbox title whether to enable connected MAC randomization -->
-    <string name="wifi_connected_mac_randomization_summary">Randomize MAC address when connecting to Wi\u2011Fi networks</string>
     <!-- Label indicating network has been manually marked as metered -->
     <string name="wifi_metered_label">Metered</string>
     <!-- Label indicating network has been manually marked as unmetered -->
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index 3877c90..6ca8261 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -1511,9 +1511,6 @@
                 Settings.Global.WIFI_VERBOSE_LOGGING_ENABLED,
                 GlobalSettingsProto.Wifi.VERBOSE_LOGGING_ENABLED);
         dumpSetting(s, p,
-                Settings.Global.WIFI_CONNECTED_MAC_RANDOMIZATION_ENABLED,
-                GlobalSettingsProto.Wifi.CONNECTED_MAC_RANDOMIZATION_ENABLED);
-        dumpSetting(s, p,
                 Settings.Global.WIFI_MAX_DHCP_RETRY_COUNT,
                 GlobalSettingsProto.Wifi.MAX_DHCP_RETRY_COUNT);
         dumpSetting(s, p,
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
index f66a57b..9b3d7ed 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
@@ -137,8 +137,10 @@
     }
 
     public NotificationIconAreaController createNotificationIconAreaController(Context context,
-            StatusBar statusBar, StatusBarStateController statusBarStateController) {
-        return new NotificationIconAreaController(context, statusBar, statusBarStateController);
+            StatusBar statusBar, StatusBarStateController statusBarStateController,
+            NotificationListener listener) {
+        return new NotificationIconAreaController(context, statusBar, statusBarStateController,
+                listener);
     }
 
     public KeyguardIndicationController createKeyguardIndicationController(Context context,
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipAccessibilityInteractionConnection.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipAccessibilityInteractionConnection.java
index 968bd28..60dceef 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipAccessibilityInteractionConnection.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipAccessibilityInteractionConnection.java
@@ -165,6 +165,11 @@
         }
     }
 
+    @Override
+    public void clearAccessibilityFocus() {
+        // We should not be here.
+    }
+
     public static AccessibilityNodeInfo obtainRootAccessibilityNodeInfo() {
         AccessibilityNodeInfo info = AccessibilityNodeInfo.obtain();
         info.setSourceNodeId(AccessibilityNodeInfo.ROOT_NODE_ID,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java
index f3a46ce..0583843 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java
@@ -20,6 +20,8 @@
 import static com.android.systemui.statusbar.phone.StatusBar.DEBUG;
 import static com.android.systemui.statusbar.phone.StatusBar.ENABLE_CHILD_NOTIFICATIONS;
 
+import android.annotation.SuppressLint;
+import android.app.NotificationManager;
 import android.content.ComponentName;
 import android.content.Context;
 import android.os.RemoteException;
@@ -32,10 +34,13 @@
 import com.android.systemui.statusbar.phone.NotificationGroupManager;
 import com.android.systemui.statusbar.phone.NotificationListenerWithPlugins;
 
+import java.util.ArrayList;
+
 /**
  * This class handles listening to notification updates and passing them along to
  * NotificationPresenter to be displayed to the user.
  */
+@SuppressLint("OverrideAbstract")
 public class NotificationListener extends NotificationListenerWithPlugins {
     private static final String TAG = "NotificationListener";
 
@@ -47,6 +52,7 @@
     private final NotificationGroupManager mGroupManager =
             Dependency.get(NotificationGroupManager.class);
 
+    private final ArrayList<NotificationSettingsListener> mSettingsListeners = new ArrayList<>();
     private final Context mContext;
 
     protected NotificationPresenter mPresenter;
@@ -55,6 +61,10 @@
         mContext = context;
     }
 
+    public void addNotificationSettingsListener(NotificationSettingsListener listener) {
+        mSettingsListeners.add(listener);
+    }
+
     @Override
     public void onListenerConnected() {
         if (DEBUG) Log.d(TAG, "onListenerConnected");
@@ -70,6 +80,8 @@
                 mEntryManager.addNotification(sbn, currentRanking);
             }
         });
+        NotificationManager noMan = mContext.getSystemService(NotificationManager.class);
+        onStatusBarIconsBehaviorChanged(noMan.shouldHideSilentStatusBarIcons());
     }
 
     @Override
@@ -133,6 +145,13 @@
         }
     }
 
+    @Override
+    public void onStatusBarIconsBehaviorChanged(boolean hideSilentStatusIcons) {
+        for (NotificationSettingsListener listener : mSettingsListeners) {
+            listener.onStatusBarIconsBehaviorChanged(hideSilentStatusIcons);
+        }
+    }
+
     public void setUpWithPresenter(NotificationPresenter presenter) {
         mPresenter = presenter;
 
@@ -144,4 +163,10 @@
             Log.e(TAG, "Unable to register notification listener", e);
         }
     }
+
+    public interface NotificationSettingsListener {
+
+        default void onStatusBarIconsBehaviorChanged(boolean hideSilentStatusIcons) { }
+
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
index e86996a..9e99fe9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
@@ -11,9 +11,7 @@
 import android.view.ViewGroup;
 import android.widget.FrameLayout;
 
-import androidx.annotation.NonNull;
-import androidx.collection.ArrayMap;
-
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.statusbar.StatusBarIcon;
 import com.android.internal.util.ContrastColorUtil;
 import com.android.internal.widget.ViewClippingUtil;
@@ -21,6 +19,7 @@
 import com.android.systemui.R;
 import com.android.systemui.plugins.DarkIconDispatcher;
 import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver;
+import com.android.systemui.statusbar.NotificationListener;
 import com.android.systemui.statusbar.NotificationShelf;
 import com.android.systemui.statusbar.StatusBarIconView;
 import com.android.systemui.statusbar.StatusBarStateController;
@@ -28,11 +27,13 @@
 import com.android.systemui.statusbar.notification.NotificationUtils;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
-import com.android.systemui.tuner.TunerService;
 
 import java.util.ArrayList;
 import java.util.function.Function;
 
+import androidx.annotation.NonNull;
+import androidx.collection.ArrayMap;
+
 /**
  * A controller for the space in the status bar to the left of the system icons. This area is
  * normally reserved for notifications.
@@ -46,18 +47,19 @@
     private final NotificationEntryManager mEntryManager;
     private final Runnable mUpdateStatusBarIcons = this::updateStatusBarIcons;
     private final StatusBarStateController mStatusBarStateController;
-    private final TunerService.Tunable mTunable = new TunerService.Tunable() {
-        @Override
-        public void onTuningChanged(String key, String newValue) {
-            if (key.equals(LOW_PRIORITY)) {
-                mShowLowPriority = "1".equals(newValue)
-                        || !NotificationUtils.useNewInterruptionModel(mContext);
-                if (mNotificationScrollLayout != null) {
-                    updateStatusBarIcons();
+    @VisibleForTesting
+    final NotificationListener.NotificationSettingsListener mSettingsListener =
+            new NotificationListener.NotificationSettingsListener() {
+                @Override
+                public void onStatusBarIconsBehaviorChanged(boolean hideSilentStatusIcons) {
+                    if (NotificationUtils.useNewInterruptionModel(mContext)) {
+                        mShowLowPriority = !hideSilentStatusIcons;
+                        if (mNotificationScrollLayout != null) {
+                            updateStatusBarIcons();
+                        }
+                    }
                 }
-            }
-        }
-    };
+            };
 
     private int mIconSize;
     private int mIconHPadding;
@@ -71,7 +73,7 @@
     private ViewGroup mNotificationScrollLayout;
     private Context mContext;
     private boolean mFullyDark;
-    private boolean mShowLowPriority;
+    private boolean mShowLowPriority = true;
 
     /**
      * Ratio representing being awake or in ambient mode, where 1 is dark and 0 awake.
@@ -90,15 +92,15 @@
             view -> view instanceof StatusBarWindowView;
 
     public NotificationIconAreaController(Context context, StatusBar statusBar,
-            StatusBarStateController statusBarStateController) {
+            StatusBarStateController statusBarStateController,
+            NotificationListener notificationListener) {
         mStatusBar = statusBar;
         mContrastColorUtil = ContrastColorUtil.getInstance(context);
         mContext = context;
         mEntryManager = Dependency.get(NotificationEntryManager.class);
         mStatusBarStateController = statusBarStateController;
         mStatusBarStateController.addCallback(this);
-
-        Dependency.get(TunerService.class).addTunable(mTunable, LOW_PRIORITY);
+        notificationListener.addNotificationSettingsListener(mSettingsListener);
 
         initializeNotificationAreaViews(context);
     }
@@ -243,6 +245,11 @@
                 true /* hideRepliedMessages */);
     }
 
+    @VisibleForTesting
+    boolean shouldShouldLowPriorityIcons() {
+        return mShowLowPriority;
+    }
+
     /**
      * Updates the notification icons for a host layout. This will ensure that the notification
      * host layout will have the same icons like the ones in here.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 1470d0f..ceadd1e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -801,7 +801,8 @@
         mNotificationLogger.setUpWithContainer(notifListContainer);
 
         mNotificationIconAreaController = SystemUIFactory.getInstance()
-                .createNotificationIconAreaController(context, this, mStatusBarStateController);
+                .createNotificationIconAreaController(
+                        context, this, mStatusBarStateController, mNotificationListener);
         inflateShelf();
         mNotificationIconAreaController.setupShelf(mNotificationShelf);
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationListenerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationListenerTest.java
index c880172..bcf5964 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationListenerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationListenerTest.java
@@ -17,10 +17,12 @@
 package com.android.systemui.statusbar;
 
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.app.Notification;
+import android.app.NotificationManager;
 import android.os.Handler;
 import android.os.UserHandle;
 import android.service.notification.NotificationListenerService;
@@ -55,6 +57,7 @@
     // Dependency mocks:
     @Mock private NotificationEntryManager mEntryManager;
     @Mock private NotificationRemoteInputManager mRemoteInputManager;
+    @Mock private NotificationManager mNotificationManager;
 
     private NotificationListener mListener;
     private StatusBarNotification mSbn;
@@ -67,6 +70,7 @@
                 mRemoteInputManager);
         mDependency.injectTestDependency(Dependency.MAIN_HANDLER,
                 new Handler(TestableLooper.get(this).getLooper()));
+        mContext.addMockSystemService(NotificationManager.class, mNotificationManager);
 
         when(mEntryManager.getNotificationData()).thenReturn(mNotificationData);
 
@@ -106,4 +110,28 @@
         // RankingMap may be modified by plugins.
         verify(mEntryManager).updateNotificationRanking(any());
     }
+
+    @Test
+    public void testOnConnectReadStatusBarSetting() {
+        NotificationListener.NotificationSettingsListener settingsListener =
+                mock(NotificationListener.NotificationSettingsListener.class);
+        mListener.addNotificationSettingsListener(settingsListener);
+
+        when(mNotificationManager.shouldHideSilentStatusBarIcons()).thenReturn(true);
+
+        mListener.onListenerConnected();
+
+        verify(settingsListener).onStatusBarIconsBehaviorChanged(true);
+    }
+
+    @Test
+    public void testOnStatusBarIconsBehaviorChanged() {
+        NotificationListener.NotificationSettingsListener settingsListener =
+                mock(NotificationListener.NotificationSettingsListener.class);
+        mListener.addNotificationSettingsListener(settingsListener);
+
+        mListener.onStatusBarIconsBehaviorChanged(true);
+
+        verify(settingsListener).onStatusBarIconsBehaviorChanged(true);
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconAreaControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconAreaControllerTest.java
new file mode 100644
index 0000000..13145b8
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconAreaControllerTest.java
@@ -0,0 +1,92 @@
+/*
+ * 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 com.android.systemui.statusbar.phone;
+
+import static android.provider.Settings.Secure.NOTIFICATION_NEW_INTERRUPTION_MODEL;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.content.Context;
+import android.provider.Settings;
+import android.support.test.filters.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.statusbar.CommandQueue;
+import com.android.systemui.statusbar.NotificationListener;
+import com.android.systemui.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.phone.LightBarTransitionsController.DarkIntensityApplier;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+public class NotificationIconAreaControllerTest extends SysuiTestCase {
+
+    @Mock
+    private NotificationListener mListener;
+    @Mock
+    StatusBar mStatusBar;
+    @Mock
+    StatusBarStateController mStatusBarStateController;
+    private NotificationIconAreaController mController;
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+
+        mController = new NotificationIconAreaController(mContext, mStatusBar,
+                mStatusBarStateController, mListener);
+    }
+
+    @Test
+    public void testNotificationIcons_featureOff() {
+        Settings.Secure.putInt(
+                mContext.getContentResolver(), NOTIFICATION_NEW_INTERRUPTION_MODEL, 0);
+        assertTrue(mController.shouldShouldLowPriorityIcons());
+    }
+
+    @Test
+    public void testNotificationIcons_featureOn_settingHideIcons() {
+        Settings.Secure.putInt(
+                mContext.getContentResolver(), NOTIFICATION_NEW_INTERRUPTION_MODEL, 1);
+        mController.mSettingsListener.onStatusBarIconsBehaviorChanged(true);
+
+        assertFalse(mController.shouldShouldLowPriorityIcons());
+    }
+
+    @Test
+    public void testNotificationIcons_featureOn_settingShowIcons() {
+        Settings.Secure.putInt(
+                mContext.getContentResolver(), NOTIFICATION_NEW_INTERRUPTION_MODEL, 1);
+        mController.mSettingsListener.onStatusBarIconsBehaviorChanged(false);
+
+        assertTrue(mController.shouldShouldLowPriorityIcons());
+    }
+}
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index f88d521..47cd917 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -3024,9 +3024,19 @@
         }
 
         public void clearAccessibilityFocusNotLocked(int windowId) {
-            AccessibilityNodeInfo focus = getAccessibilityFocusNotLocked(windowId);
-            if (focus != null) {
-                focus.performAction(AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS);
+            RemoteAccessibilityConnection connection;
+            synchronized (mLock) {
+                connection = getConnectionLocked(windowId);
+                if (connection == null) {
+                    return;
+                }
+            }
+            try {
+                connection.getRemote().clearAccessibilityFocus();
+            } catch (RemoteException re) {
+                if (DEBUG) {
+                    Slog.e(LOG_TAG, "Error calling clearAccessibilityFocus()");
+                }
             }
         }
 
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index c8e5d2b..de7c8cc 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -79,6 +79,7 @@
 import android.net.NetworkAgent;
 import android.net.NetworkCapabilities;
 import android.net.NetworkConfig;
+import android.net.NetworkFactory;
 import android.net.NetworkInfo;
 import android.net.NetworkInfo.DetailedState;
 import android.net.NetworkMisc;
@@ -2773,8 +2774,17 @@
                 for (NetworkRequestInfo nri : mNetworkRequests.values()) {
                     if (nri.request.isListen()) continue;
                     NetworkAgentInfo nai = getNetworkForRequest(nri.request.requestId);
-                    ac.sendMessage(android.net.NetworkFactory.CMD_REQUEST_NETWORK,
-                            (nai != null ? nai.getCurrentScore() : 0), 0, nri.request);
+                    final int score;
+                    final int serial;
+                    if (nai != null) {
+                        score = nai.getCurrentScore();
+                        serial = nai.factorySerialNumber;
+                    } else {
+                        score = 0;
+                        serial = NetworkFactory.SerialNumber.NONE;
+                    }
+                    ac.sendMessage(android.net.NetworkFactory.CMD_REQUEST_NETWORK, score, serial,
+                            nri.request);
                 }
             } else {
                 loge("Error connecting NetworkFactory");
@@ -2871,7 +2881,7 @@
             NetworkAgentInfo currentNetwork = getNetworkForRequest(request.requestId);
             if (currentNetwork != null && currentNetwork.network.netId == nai.network.netId) {
                 clearNetworkForRequest(request.requestId);
-                sendUpdatedScoreToFactories(request, 0);
+                sendUpdatedScoreToFactories(request, null);
             }
         }
         nai.clearLingerState();
@@ -2947,7 +2957,7 @@
         }
         rematchAllNetworksAndRequests(null, 0);
         if (nri.request.isRequest() && getNetworkForRequest(nri.request.requestId) == null) {
-            sendUpdatedScoreToFactories(nri.request, 0);
+            sendUpdatedScoreToFactories(nri.request, null);
         }
     }
 
@@ -4532,11 +4542,14 @@
         public final String name;
         public final Messenger messenger;
         public final AsyncChannel asyncChannel;
+        public final int factorySerialNumber;
 
-        public NetworkFactoryInfo(String name, Messenger messenger, AsyncChannel asyncChannel) {
+        NetworkFactoryInfo(String name, Messenger messenger, AsyncChannel asyncChannel,
+                int factorySerialNumber) {
             this.name = name;
             this.messenger = messenger;
             this.asyncChannel = asyncChannel;
+            this.factorySerialNumber = factorySerialNumber;
         }
     }
 
@@ -4897,10 +4910,12 @@
     }
 
     @Override
-    public void registerNetworkFactory(Messenger messenger, String name) {
+    public int registerNetworkFactory(Messenger messenger, String name) {
         enforceConnectivityInternalPermission();
-        NetworkFactoryInfo nfi = new NetworkFactoryInfo(name, messenger, new AsyncChannel());
+        NetworkFactoryInfo nfi = new NetworkFactoryInfo(name, messenger, new AsyncChannel(),
+                NetworkFactory.SerialNumber.nextSerialNumber());
         mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_FACTORY, nfi));
+        return nfi.factorySerialNumber;
     }
 
     private void handleRegisterNetworkFactory(NetworkFactoryInfo nfi) {
@@ -4992,9 +5007,35 @@
         return nri.request.requestId == mDefaultRequest.requestId;
     }
 
+    // TODO : remove this method. It's a stopgap measure to help sheperding a number of dependent
+    // changes that would conflict throughout the automerger graph. Having this method temporarily
+    // helps with the process of going through with all these dependent changes across the entire
+    // tree.
     public int registerNetworkAgent(Messenger messenger, NetworkInfo networkInfo,
             LinkProperties linkProperties, NetworkCapabilities networkCapabilities,
             int currentScore, NetworkMisc networkMisc) {
+        return registerNetworkAgent(messenger, networkInfo, linkProperties, networkCapabilities,
+                currentScore, networkMisc, NetworkFactory.SerialNumber.NONE);
+    }
+
+    /**
+     * Register a new agent with ConnectivityService to handle a network.
+     *
+     * @param messenger a messenger for ConnectivityService to contact the agent asynchronously.
+     * @param networkInfo the initial info associated with this network. It can be updated later :
+     *         see {@link #updateNetworkInfo}.
+     * @param linkProperties the initial link properties of this network. They can be updated
+     *         later : see {@link #updateLinkProperties}.
+     * @param networkCapabilities the initial capabilites of this network. They can be updated
+     *         later : see {@link #updateNetworkCapabilities}.
+     * @param currentScore the initial score of the network. See
+     *         {@link NetworkAgentInfo#getCurrentScore}.
+     * @param networkMisc metadata about the network. This is never updated.
+     * @param factorySerialNumber the serial number of the factory owning this NetworkAgent.
+     */
+    public int registerNetworkAgent(Messenger messenger, NetworkInfo networkInfo,
+            LinkProperties linkProperties, NetworkCapabilities networkCapabilities,
+            int currentScore, NetworkMisc networkMisc, int factorySerialNumber) {
         enforceConnectivityInternalPermission();
 
         LinkProperties lp = new LinkProperties(linkProperties);
@@ -5004,7 +5045,8 @@
         final NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities);
         final NetworkAgentInfo nai = new NetworkAgentInfo(messenger, new AsyncChannel(),
                 new Network(reserveNetId()), new NetworkInfo(networkInfo), lp, nc, currentScore,
-                mContext, mTrackerHandler, new NetworkMisc(networkMisc), this, mNetd, mNMS);
+                mContext, mTrackerHandler, new NetworkMisc(networkMisc), this, mNetd, mNMS,
+                factorySerialNumber);
         // Make sure the network capabilities reflect what the agent info says.
         nai.networkCapabilities = mixInCapabilities(nai, nc);
         final String extraInfo = networkInfo.getExtraInfo();
@@ -5420,17 +5462,23 @@
             NetworkRequest nr = nai.requestAt(i);
             // Don't send listening requests to factories. b/17393458
             if (nr.isListen()) continue;
-            sendUpdatedScoreToFactories(nr, nai.getCurrentScore());
+            sendUpdatedScoreToFactories(nr, nai);
         }
     }
 
-    private void sendUpdatedScoreToFactories(NetworkRequest networkRequest, int score) {
+    private void sendUpdatedScoreToFactories(NetworkRequest networkRequest, NetworkAgentInfo nai) {
+        int score = 0;
+        int serial = 0;
+        if (nai != null) {
+            score = nai.getCurrentScore();
+            serial = nai.factorySerialNumber;
+        }
         if (VDBG || DDBG){
             log("sending new Min Network Score(" + score + "): " + networkRequest.toString());
         }
         for (NetworkFactoryInfo nfi : mNetworkFactoryInfos.values()) {
-            nfi.asyncChannel.sendMessage(android.net.NetworkFactory.CMD_REQUEST_NETWORK, score, 0,
-                    networkRequest);
+            nfi.asyncChannel.sendMessage(android.net.NetworkFactory.CMD_REQUEST_NETWORK, score,
+                    serial, networkRequest);
         }
     }
 
@@ -5706,7 +5754,7 @@
                     // TODO - this could get expensive if we have a lot of requests for this
                     // network.  Think about if there is a way to reduce this.  Push
                     // netid->request mapping to each factory?
-                    sendUpdatedScoreToFactories(nri.request, score);
+                    sendUpdatedScoreToFactories(nri.request, newNetwork);
                     if (isDefaultRequest(nri)) {
                         isNewDefault = true;
                         oldDefaultNetwork = currentNetwork;
@@ -5730,7 +5778,7 @@
                 newNetwork.removeRequest(nri.request.requestId);
                 if (currentNetwork == newNetwork) {
                     clearNetworkForRequest(nri.request.requestId);
-                    sendUpdatedScoreToFactories(nri.request, 0);
+                    sendUpdatedScoreToFactories(nri.request, null);
                 } else {
                     Slog.wtf(TAG, "BUG: Removing request " + nri.request.requestId + " from " +
                             newNetwork.name() +
diff --git a/services/core/java/com/android/server/PackageWatchdog.java b/services/core/java/com/android/server/PackageWatchdog.java
index 84577f1..4507193 100644
--- a/services/core/java/com/android/server/PackageWatchdog.java
+++ b/services/core/java/com/android/server/PackageWatchdog.java
@@ -21,6 +21,7 @@
 import android.annotation.IntDef;
 import android.annotation.Nullable;
 import android.content.Context;
+import android.content.pm.VersionedPackage;
 import android.os.Environment;
 import android.os.Handler;
 import android.os.Looper;
@@ -230,7 +231,6 @@
         return null;
     }
 
-    // TODO(zezeozue:) Accept current versionCodes of failing packages?
     /**
      * Called when a process fails either due to a crash or ANR.
      *
@@ -239,15 +239,16 @@
      *
      * <p>This method could be called frequently if there is a severe problem on the device.
      */
-    public void onPackageFailure(String[] packages) {
+    public void onPackageFailure(List<VersionedPackage> packages) {
         mWorkerHandler.post(() -> {
             synchronized (mLock) {
                 if (mAllObservers.isEmpty()) {
                     return;
                 }
 
-                for (int pIndex = 0; pIndex < packages.length; pIndex++) {
-                    String packageToReport = packages[pIndex];
+                for (int pIndex = 0; pIndex < packages.size(); pIndex++) {
+                    String packageToReport = packages.get(pIndex).getPackageName();
+                    long packageVersionCode = packages.get(pIndex).getVersionCode();
                     // Observer that will receive failure for packageToReport
                     PackageHealthObserver currentObserverToNotify = null;
                     int currentObserverImpact = Integer.MAX_VALUE;
@@ -258,7 +259,8 @@
                         PackageHealthObserver registeredObserver = observer.mRegisteredObserver;
                         if (registeredObserver != null
                                 && observer.onPackageFailure(packageToReport)) {
-                            int impact = registeredObserver.onHealthCheckFailed(packageToReport);
+                            int impact = registeredObserver.onHealthCheckFailed(packageToReport,
+                                    packageVersionCode);
                             if (impact != PackageHealthObserverImpact.USER_IMPACT_NONE
                                     && impact < currentObserverImpact) {
                                 currentObserverToNotify = registeredObserver;
@@ -269,7 +271,7 @@
 
                     // Execute action with least user impact
                     if (currentObserverToNotify != null) {
-                        currentObserverToNotify.execute(packageToReport);
+                        currentObserverToNotify.execute(packageToReport, packageVersionCode);
                     }
                 }
             }
@@ -313,14 +315,14 @@
          * @return any one of {@link PackageHealthObserverImpact} to express the impact
          * to the user on {@link #execute}
          */
-        @PackageHealthObserverImpact int onHealthCheckFailed(String packageName);
+        @PackageHealthObserverImpact int onHealthCheckFailed(String packageName, long versionCdoe);
 
         /**
          * Executes mitigation for {@link #onHealthCheckFailed}.
          *
          * @return {@code true} if action was executed successfully, {@code false} otherwise
          */
-        boolean execute(String packageName);
+        boolean execute(String packageName, long versionCode);
 
         // TODO(zezeozue): Ensure uniqueness?
         /**
diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java
index a634b57..f153ab9 100644
--- a/services/core/java/com/android/server/am/AppErrors.java
+++ b/services/core/java/com/android/server/am/AppErrors.java
@@ -34,6 +34,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.ApplicationInfo;
+import android.content.pm.VersionedPackage;
 import android.net.Uri;
 import android.os.Binder;
 import android.os.Message;
@@ -60,6 +61,7 @@
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.Collections;
+import java.util.List;
 
 /**
  * Controls error conditions in applications.
@@ -411,7 +413,7 @@
             } else {
                 // If a non-persistent app is stuck in crash loop, we want to inform
                 // the package watchdog, maybe an update or experiment can be rolled back.
-                mPackageWatchdog.onPackageFailure(r.getPackageList());
+                mPackageWatchdog.onPackageFailure(r.getPackageListWithVersionCode());
             }
         }
 
@@ -830,7 +832,7 @@
 
     void handleShowAnrUi(Message msg) {
         Dialog dialogToShow = null;
-        String[] packageList = null;
+        List<VersionedPackage> packageList = null;
         synchronized (mService) {
             AppNotRespondingDialog.Data data = (AppNotRespondingDialog.Data) msg.obj;
             final ProcessRecord proc = data.proc;
@@ -839,7 +841,7 @@
                 return;
             }
             if (!proc.isPersistent()) {
-                packageList = proc.getPackageList();
+                packageList = proc.getPackageListWithVersionCode();
             }
             if (proc.anrDialog != null) {
                 Slog.e(TAG, "App already has anr dialog: " + proc);
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index 580d688..7ae77d5 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -32,6 +32,7 @@
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.ServiceInfo;
+import android.content.pm.VersionedPackage;
 import android.content.res.CompatibilityInfo;
 import android.os.Binder;
 import android.os.Debug;
@@ -66,6 +67,7 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.List;
 
 /**
  * Full information about a particular process that
@@ -974,6 +976,18 @@
         return list;
     }
 
+    public List<VersionedPackage> getPackageListWithVersionCode() {
+        int size = pkgList.size();
+        if (size == 0) {
+            return null;
+        }
+        List<VersionedPackage> list = new ArrayList<>();
+        for (int i = 0; i < pkgList.size(); i++) {
+            list.add(new VersionedPackage(pkgList.keyAt(i), pkgList.valueAt(i).appVersion));
+        }
+        return list;
+    }
+
     WindowProcessController getWindowProcessController() {
         return mWindowProcessController;
     }
diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
index d0cff25..cd4ce2d 100644
--- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
@@ -235,6 +235,8 @@
     public final Messenger messenger;
     public final AsyncChannel asyncChannel;
 
+    public final int factorySerialNumber;
+
     // Used by ConnectivityService to keep track of 464xlat.
     public Nat464Xlat clatd;
 
@@ -252,7 +254,7 @@
     public NetworkAgentInfo(Messenger messenger, AsyncChannel ac, Network net, NetworkInfo info,
             LinkProperties lp, NetworkCapabilities nc, int score, Context context, Handler handler,
             NetworkMisc misc, ConnectivityService connService, INetd netd,
-            INetworkManagementService nms) {
+            INetworkManagementService nms, int factorySerialNumber) {
         this.messenger = messenger;
         asyncChannel = ac;
         network = net;
@@ -266,6 +268,7 @@
         mContext = context;
         mHandler = handler;
         networkMisc = misc;
+        this.factorySerialNumber = factorySerialNumber;
     }
 
     /**
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index 2508844..7e95f10 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -54,6 +54,7 @@
 import android.net.Network;
 import android.net.NetworkAgent;
 import android.net.NetworkCapabilities;
+import android.net.NetworkFactory;
 import android.net.NetworkInfo;
 import android.net.NetworkInfo.DetailedState;
 import android.net.NetworkMisc;
@@ -942,7 +943,8 @@
         try {
             mNetworkAgent = new NetworkAgent(mLooper, mContext, NETWORKTYPE /* logtag */,
                     mNetworkInfo, mNetworkCapabilities, lp,
-                    ConnectivityConstants.VPN_DEFAULT_SCORE, networkMisc) {
+                    ConnectivityConstants.VPN_DEFAULT_SCORE, networkMisc,
+                    NetworkFactory.SerialNumber.VPN) {
                             @Override
                             public void unwanted() {
                                 // We are user controlled, not driven by NetworkRequest.
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 467b192..e68bcda 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -2366,6 +2366,28 @@
         }
 
         @Override
+        public boolean shouldHideSilentStatusIcons(String callingPkg) {
+            checkCallerIsSameApp(callingPkg);
+
+            if (isCallerSystemOrPhone()
+                    || mListeners.isListenerPackage(callingPkg)) {
+                return mPreferencesHelper.shouldHideSilentStatusIcons();
+            } else {
+                throw new SecurityException("Only available for notification listeners");
+            }
+        }
+
+        @Override
+        public void setHideSilentStatusIcons(boolean hide) {
+            checkCallerIsSystem();
+
+            mPreferencesHelper.setHideSilentStatusIcons(hide);
+            handleSavePolicyFile();
+
+            mListeners.onStatusBarIconsBehaviorChanged(hide);
+        }
+
+        @Override
         public int getPackageImportance(String pkg) {
             checkCallerIsSystemOrSameApp(pkg);
             return mPreferencesHelper.getImportance(pkg, Binder.getCallingUid());
@@ -7324,6 +7346,20 @@
             return mLightTrimListeners.contains(info) ? TRIM_LIGHT : TRIM_FULL;
         }
 
+        public void onStatusBarIconsBehaviorChanged(boolean hideSilentStatusIcons) {
+            for (final ManagedServiceInfo info : getServices()) {
+                mHandler.post(() -> {
+                    final INotificationListener listener = (INotificationListener) info.service;
+                     try {
+                        listener.onStatusBarIconsBehaviorChanged(hideSilentStatusIcons);
+                    } catch (RemoteException ex) {
+                        Log.e(TAG, "unable to notify listener "
+                                + "(hideSilentStatusIcons): " + listener, ex);
+                    }
+                });
+            }
+        }
+
         /**
          * asynchronously notify all listeners about a new notification
          *
diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java
index 3f0043c..6ed4f5c 100644
--- a/services/core/java/com/android/server/notification/PreferencesHelper.java
+++ b/services/core/java/com/android/server/notification/PreferencesHelper.java
@@ -76,6 +76,7 @@
     private static final String TAG_CHANNEL = "channel";
     private static final String TAG_GROUP = "channelGroup";
     private static final String TAG_DELEGATE = "delegate";
+    private static final String TAG_STATUS_ICONS = "status_icons";
 
     private static final String ATT_VERSION = "version";
     private static final String ATT_NAME = "name";
@@ -89,10 +90,13 @@
     private static final String ATT_APP_USER_LOCKED_FIELDS = "app_user_locked_fields";
     private static final String ATT_ENABLED = "enabled";
     private static final String ATT_USER_ALLOWED = "allowed";
+    private static final String ATT_HIDE_SILENT = "hide_silent";
 
     private static final int DEFAULT_PRIORITY = Notification.PRIORITY_DEFAULT;
     private static final int DEFAULT_VISIBILITY = NotificationManager.VISIBILITY_NO_OVERRIDE;
     private static final int DEFAULT_IMPORTANCE = NotificationManager.IMPORTANCE_UNSPECIFIED;
+    @VisibleForTesting
+    static final boolean DEFAULT_HIDE_SILENT_STATUS_BAR_ICONS = false;
     private static final boolean DEFAULT_SHOW_BADGE = true;
     private static final boolean DEFAULT_ALLOW_BUBBLE = true;
     private static final boolean DEFAULT_OEM_LOCKED_IMPORTANCE  = false;
@@ -124,6 +128,7 @@
 
     private SparseBooleanArray mBadgingEnabled;
     private boolean mAreChannelsBypassingDnd;
+    private boolean mHideSilentStatusBarIcons;
 
     public PreferencesHelper(Context context, PackageManager pm, RankingHandler rankingHandler,
             ZenModeHelper zenHelper) {
@@ -143,9 +148,8 @@
         String tag = parser.getName();
         if (!TAG_RANKING.equals(tag)) return;
         synchronized (mPackagePreferences) {
-            // Clobber groups and channels with the xml, but don't delete other data that wasn't present
-
-            // at the time of serialization.
+            // Clobber groups and channels with the xml, but don't delete other data that wasn't
+            // present at the time of serialization.
             mRestoredWithoutUids.clear();
             while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) {
                 tag = parser.getName();
@@ -153,7 +157,10 @@
                     return;
                 }
                 if (type == XmlPullParser.START_TAG) {
-                    if (TAG_PACKAGE.equals(tag)) {
+                    if (TAG_STATUS_ICONS.equals(tag)) {
+                        mHideSilentStatusBarIcons = XmlUtils.readBooleanAttribute(
+                                parser, ATT_HIDE_SILENT, DEFAULT_HIDE_SILENT_STATUS_BAR_ICONS);
+                    } else if (TAG_PACKAGE.equals(tag)) {
                         int uid = XmlUtils.readIntAttribute(parser, ATT_UID, UNKNOWN_UID);
                         String name = parser.getAttributeValue(null, ATT_NAME);
                         if (!TextUtils.isEmpty(name)) {
@@ -375,6 +382,11 @@
     public void writeXml(XmlSerializer out, boolean forBackup) throws IOException {
         out.startTag(null, TAG_RANKING);
         out.attribute(null, ATT_VERSION, Integer.toString(XML_VERSION));
+        if (mHideSilentStatusBarIcons != DEFAULT_HIDE_SILENT_STATUS_BAR_ICONS) {
+            out.startTag(null, TAG_STATUS_ICONS);
+            out.attribute(null, ATT_HIDE_SILENT, String.valueOf(mHideSilentStatusBarIcons));
+            out.endTag(null, TAG_STATUS_ICONS);
+        }
 
         synchronized (mPackagePreferences) {
             final int N = mPackagePreferences.size();
@@ -781,6 +793,14 @@
         }
     }
 
+    public boolean shouldHideSilentStatusIcons() {
+        return mHideSilentStatusBarIcons;
+    }
+
+    public void setHideSilentStatusIcons(boolean hide) {
+        mHideSilentStatusBarIcons = hide;
+    }
+
     public void lockChannelsForOEM(String[] appOrChannelList) {
         if (appOrChannelList == null) {
             return;
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index 6f1eeeb..dc18dfc 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -61,6 +61,10 @@
 import android.content.pm.dex.ISnapshotRuntimeProfileCallback;
 import android.content.res.AssetManager;
 import android.content.res.Resources;
+import android.content.rollback.IRollbackManager;
+import android.content.rollback.PackageRollbackInfo;
+import android.content.rollback.RollbackInfo;
+import android.content.rollback.RollbackManager;
 import android.net.Uri;
 import android.os.Binder;
 import android.os.Build;
@@ -263,6 +267,8 @@
                     return getStagedSessions();
                 case "uninstall-system-updates":
                     return uninstallSystemUpdates();
+                case "rollback-app":
+                    return runRollbackApp();
                 default: {
                     String nextArg = getNextArg();
                     if (nextArg == null) {
@@ -348,6 +354,55 @@
         return 1;
     }
 
+    private int runRollbackApp() {
+        final PrintWriter pw = getOutPrintWriter();
+
+        final String packageName = getNextArgRequired();
+        if (packageName == null) {
+            pw.println("Error: package name not specified");
+            return 1;
+        }
+
+        final LocalIntentReceiver receiver = new LocalIntentReceiver();
+        try {
+            IRollbackManager rm = IRollbackManager.Stub.asInterface(
+                    ServiceManager.getService(Context.ROLLBACK_SERVICE));
+
+            RollbackInfo rollback = null;
+            for (RollbackInfo r : (List<RollbackInfo>) rm.getAvailableRollbacks().getList()) {
+                for (PackageRollbackInfo info : r.getPackages()) {
+                    if (packageName.equals(info.getPackageName())) {
+                        rollback = r;
+                        break;
+                    }
+                }
+            }
+
+            if (rollback == null) {
+                pw.println("No available rollbacks for: " + packageName);
+                return 1;
+            }
+
+            rm.commitRollback(rollback.getRollbackId(),
+                    ParceledListSlice.<VersionedPackage>emptyList(),
+                    "com.android.shell", receiver.getIntentSender());
+        } catch (RemoteException re) {
+            // Cannot happen.
+        }
+
+        final Intent result = receiver.getResult();
+        final int status = result.getIntExtra(RollbackManager.EXTRA_STATUS,
+                RollbackManager.STATUS_FAILURE);
+        if (status == RollbackManager.STATUS_SUCCESS) {
+            pw.println("Success");
+            return 0;
+        } else {
+            pw.println("Failure ["
+                    + result.getStringExtra(RollbackManager.EXTRA_STATUS_MESSAGE) + "]");
+            return 1;
+        }
+    }
+
     private void setParamsSize(InstallParams params, String inPath) {
         if (params.sessionParams.sizeBytes == -1 && !STDIN_PATH.equals(inPath)) {
             final ParcelFileDescriptor fd = openFileForSystem(inPath, "r");
diff --git a/services/core/java/com/android/server/rollback/AppDataRollbackHelper.java b/services/core/java/com/android/server/rollback/AppDataRollbackHelper.java
new file mode 100644
index 0000000..8dd0760
--- /dev/null
+++ b/services/core/java/com/android/server/rollback/AppDataRollbackHelper.java
@@ -0,0 +1,236 @@
+/*
+ * 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 com.android.server.rollback;
+
+import android.content.rollback.PackageRollbackInfo;
+import android.content.rollback.PackageRollbackInfo.RestoreInfo;
+import android.content.rollback.RollbackInfo;
+import android.os.storage.StorageManager;
+import android.util.IntArray;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.pm.Installer;
+import com.android.server.pm.Installer.InstallerException;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Encapsulates the logic for initiating userdata snapshots and rollbacks via installd.
+ */
+@VisibleForTesting
+// TODO(narayan): Reason about the failure scenarios that involve one or more IPCs to installd
+// failing. We need to decide what course of action to take if calls to snapshotAppData or
+// restoreAppDataSnapshot fail.
+public class AppDataRollbackHelper {
+    private static final String TAG = "RollbackManager";
+
+    private final Installer mInstaller;
+
+    public AppDataRollbackHelper(Installer installer) {
+        mInstaller = installer;
+    }
+
+    /**
+     * Creates an app data snapshot for a specified {@code packageName} for {@code installedUsers},
+     * a specified set of users for whom the package is installed.
+     *
+     * @return a list of users for which the snapshot is pending, usually because data for one or
+     *         more users is still credential locked.
+     */
+    public IntArray snapshotAppData(String packageName, int[] installedUsers) {
+        final IntArray pendingBackups = new IntArray();
+        for (int user : installedUsers) {
+            final int storageFlags;
+            if (isUserCredentialLocked(user)) {
+                // We've encountered a user that hasn't unlocked on a FBE device, so we can't copy
+                // across app user data until the user unlocks their device.
+                Log.v(TAG, "User: " + user + " isn't unlocked, skipping CE userdata backup.");
+                storageFlags = Installer.FLAG_STORAGE_DE;
+                pendingBackups.add(user);
+            } else {
+                storageFlags = Installer.FLAG_STORAGE_CE | Installer.FLAG_STORAGE_DE;
+            }
+
+            try {
+                mInstaller.snapshotAppData(packageName, user, storageFlags);
+            } catch (InstallerException ie) {
+                Log.e(TAG, "Unable to create app data snapshot for: " + packageName
+                        + ", userId: " + user, ie);
+            }
+        }
+
+        return pendingBackups;
+    }
+
+    /**
+     * Restores an app data snapshot for a specified package ({@code packageName},
+     * {@code rollbackData}) for a specified {@code userId}.
+     *
+     * @return {@code true} iff. a change to the {@code rollbackData} has been made. Changes to
+     *         {@code rollbackData} are restricted to the removal or addition of {@code userId} to
+     *         the list of pending backups or restores.
+     */
+    public boolean restoreAppData(String packageName, RollbackData rollbackData,
+            int userId, int appId, long ceDataInode, String seInfo) {
+        if (rollbackData == null) {
+            return false;
+        }
+
+        if (!rollbackData.inProgress) {
+            Log.e(TAG, "Request to restore userData for: " + packageName
+                    + ", but no rollback in progress.");
+            return false;
+        }
+
+        PackageRollbackInfo packageInfo = RollbackManagerServiceImpl.getPackageRollbackInfo(
+                rollbackData, packageName);
+        int storageFlags = Installer.FLAG_STORAGE_DE;
+
+        final IntArray pendingBackups = packageInfo.getPendingBackups();
+        final List<RestoreInfo> pendingRestores = packageInfo.getPendingRestores();
+        boolean changedRollbackData = false;
+
+        // If we still have a userdata backup pending for this user, it implies that the user
+        // hasn't unlocked their device between the point of backup and the point of restore,
+        // so the data cannot have changed. We simply skip restoring CE data in this case.
+        if (pendingBackups != null && pendingBackups.indexOf(userId) != -1) {
+            pendingBackups.remove(pendingBackups.indexOf(userId));
+            changedRollbackData = true;
+        } else {
+            // There's no pending CE backup for this user, which means that we successfully
+            // managed to backup data for the user, which means we seek to restore it
+            if (isUserCredentialLocked(userId)) {
+                // We've encountered a user that hasn't unlocked on a FBE device, so we can't
+                // copy across app user data until the user unlocks their device.
+                pendingRestores.add(new RestoreInfo(userId, appId, seInfo));
+                changedRollbackData = true;
+            } else {
+                // This user has unlocked, we can proceed to restore both CE and DE data.
+                storageFlags = storageFlags | Installer.FLAG_STORAGE_CE;
+            }
+        }
+
+        try {
+            mInstaller.restoreAppDataSnapshot(packageName, appId, ceDataInode,
+                    seInfo, userId, storageFlags);
+        } catch (InstallerException ie) {
+            Log.e(TAG, "Unable to restore app data snapshot: " + packageName, ie);
+        }
+
+        return changedRollbackData;
+    }
+
+    /**
+     * Computes the list of pending backups and restores for {@code userId} given lists of
+     * available and recent rollbacks. Packages pending backup for the given user are added
+     * to {@code pendingBackups} and packages pending restore are added to {@code pendingRestores}
+     * along with their corresponding {@code RestoreInfo}.
+     *
+     * @return the list of {@code RollbackData} that have been modified during this computation.
+     */
+    public List<RollbackData> computePendingBackupsAndRestores(int userId,
+            ArrayList<String> pendingBackupPackages, Map<String, RestoreInfo> pendingRestores,
+            List<RollbackData> availableRollbacks, List<RollbackInfo> recentRollbacks) {
+        List<RollbackData> rd = new ArrayList<>();
+        // First check with the list of available rollbacks to see whether there are any
+        // pending backup operations that we've not managed to execute.
+        for (RollbackData data : availableRollbacks) {
+            for (PackageRollbackInfo info : data.packages) {
+                final IntArray pendingBackupUsers = info.getPendingBackups();
+                if (pendingBackupUsers != null) {
+                    final int idx = pendingBackupUsers.indexOf(userId);
+                    if (idx != -1) {
+                        pendingBackupPackages.add(info.getPackageName());
+                        pendingBackupUsers.remove(idx);
+                        if (rd.indexOf(data) == -1) {
+                            rd.add(data);
+                        }
+                    }
+                }
+            }
+        }
+
+        // Then check with the list of recently executed rollbacks to see whether there are
+        // any rollback operations
+        for (RollbackInfo data : recentRollbacks) {
+            for (PackageRollbackInfo info : data.getPackages()) {
+                final RestoreInfo ri = info.getRestoreInfo(userId);
+                if (ri != null) {
+                    if (pendingBackupPackages.contains(info.getPackageName())) {
+                        // This implies that the user hasn't unlocked their device between
+                        // the request to backup data for this user and the request to restore
+                        // it, so we do nothing here.
+                        pendingBackupPackages.remove(info.getPackageName());
+                    } else {
+                        pendingRestores.put(info.getPackageName(), ri);
+                    }
+
+                    info.removeRestoreInfo(ri);
+                }
+            }
+        }
+
+        return rd;
+    }
+
+    /**
+     * Commits the list of pending backups and restores for a given {@code userId}.
+     */
+    public void commitPendingBackupAndRestoreForUser(int userId,
+            ArrayList<String> pendingBackups, Map<String, RestoreInfo> pendingRestores) {
+        if (!pendingBackups.isEmpty()) {
+            for (String packageName : pendingBackups) {
+                try {
+                    mInstaller.snapshotAppData(packageName, userId, Installer.FLAG_STORAGE_CE);
+                } catch (InstallerException ie) {
+                    Log.e(TAG, "Unable to create app data snapshot for: " + packageName, ie);
+                }
+            }
+        }
+
+        // TODO(narayan): Should we perform the restore before the backup for packages that have
+        // both backups and restores pending ? We could get into this case if we have a pending
+        // restore from a rollback + a snapshot request from a new restore.
+        if (!pendingRestores.isEmpty()) {
+            for (String packageName : pendingRestores.keySet()) {
+                try {
+                    final RestoreInfo ri = pendingRestores.get(packageName);
+
+                    // TODO(narayan): Verify that the user of "0" for ceDataInode is accurate
+                    // here. We know that the user has unlocked (and that their CE data is
+                    // available) so we shouldn't need to resort to the fallback path.
+                    mInstaller.restoreAppDataSnapshot(packageName, ri.appId,
+                            0 /* ceDataInode */, ri.seInfo, userId, Installer.FLAG_STORAGE_CE);
+                } catch (InstallerException ie) {
+                    Log.e(TAG, "Unable to restore app data snapshot for: " + packageName, ie);
+                }
+            }
+        }
+    }
+
+    /**
+     * @return {@code true} iff. {@code userId} is locked on an FBE device.
+     */
+    @VisibleForTesting
+    public boolean isUserCredentialLocked(int userId) {
+        return StorageManager.isFileEncryptedNativeOrEmulated()
+                && !StorageManager.isUserKeyUnlocked(userId);
+    }
+}
diff --git a/services/core/java/com/android/server/rollback/RollbackManagerService.java b/services/core/java/com/android/server/rollback/RollbackManagerService.java
index 4b5e764..ba6cddd 100644
--- a/services/core/java/com/android/server/rollback/RollbackManagerService.java
+++ b/services/core/java/com/android/server/rollback/RollbackManagerService.java
@@ -39,4 +39,9 @@
         mService = new RollbackManagerServiceImpl(getContext());
         publishBinderService(Context.ROLLBACK_SERVICE, mService);
     }
+
+    @Override
+    public void onUnlockUser(int user) {
+        mService.onUnlockUser(user);
+    }
 }
diff --git a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
index 289618e..5eb137b 100644
--- a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
+++ b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
@@ -31,6 +31,7 @@
 import android.content.pm.VersionedPackage;
 import android.content.rollback.IRollbackManager;
 import android.content.rollback.PackageRollbackInfo;
+import android.content.rollback.PackageRollbackInfo.RestoreInfo;
 import android.content.rollback.RollbackInfo;
 import android.content.rollback.RollbackManager;
 import android.os.Binder;
@@ -39,14 +40,13 @@
 import android.os.HandlerThread;
 import android.os.ParcelFileDescriptor;
 import android.os.Process;
-import android.os.storage.StorageManager;
+import android.util.IntArray;
 import android.util.Log;
 import android.util.SparseBooleanArray;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.server.LocalServices;
 import com.android.server.pm.Installer;
-import com.android.server.pm.Installer.InstallerException;
 import com.android.server.pm.PackageManagerServiceUtils;
 
 import java.io.File;
@@ -111,6 +111,7 @@
     private final HandlerThread mHandlerThread;
     private final Installer mInstaller;
     private final RollbackPackageHealthObserver mPackageHealthObserver;
+    private final AppDataRollbackHelper mUserdataHelper;
 
     RollbackManagerServiceImpl(Context context) {
         mContext = context;
@@ -124,6 +125,7 @@
         mRollbackStore = new RollbackStore(new File(Environment.getDataDirectory(), "rollback"));
 
         mPackageHealthObserver = new RollbackPackageHealthObserver(mContext);
+        mUserdataHelper = new AppDataRollbackHelper(mInstaller);
 
         // Kick off loading of the rollback data from strorage in a background
         // thread.
@@ -424,6 +426,35 @@
         }
     }
 
+    void onUnlockUser(int userId) {
+        getHandler().post(() -> {
+            final ArrayList<String> pendingBackupPackages = new ArrayList<>();
+            final Map<String, RestoreInfo> pendingRestorePackages = new HashMap<>();
+            final List<RollbackData> changed;
+            synchronized (mLock) {
+                ensureRollbackDataLoadedLocked();
+                changed = mUserdataHelper.computePendingBackupsAndRestores(userId,
+                        pendingBackupPackages, pendingRestorePackages, mAvailableRollbacks,
+                        mRecentlyExecutedRollbacks);
+            }
+
+            mUserdataHelper.commitPendingBackupAndRestoreForUser(userId,
+                    pendingBackupPackages, pendingRestorePackages);
+
+            for (RollbackData rd : changed) {
+                try {
+                    mRollbackStore.saveAvailableRollback(rd);
+                } catch (IOException ioe) {
+                    Log.e(TAG, "Unable to save rollback info for : " + rd.rollbackId, ioe);
+                }
+            }
+
+            synchronized (mLock) {
+                mRollbackStore.saveRecentlyExecutedRollbacks(mRecentlyExecutedRollbacks);
+            }
+        });
+    }
+
     /**
      * Load rollback data from storage if it has not already been loaded.
      * After calling this funciton, mAvailableRollbacks and
@@ -533,6 +564,20 @@
         // that are necessary to keep track of.
         synchronized (mLock) {
             ensureRollbackDataLoadedLocked();
+
+            // This should never happen because we can't have any pending backups left after
+            // a rollback has been executed. See AppDataRollbackHelper#restoreAppData where we
+            // clear all pending backups at the point of restore because they're guaranteed to be
+            // no-ops.
+            //
+            // We may, however, have one or more pending restores left to handle.
+            for (PackageRollbackInfo target : rollback.getPackages()) {
+                if (target.getPendingBackups().size() > 0) {
+                    Log.e(TAG, "No backups allowed to be pending for: " + target);
+                    target.getPendingBackups().clear();
+                }
+            }
+
             mRecentlyExecutedRollbacks.add(rollback);
             mRollbackStore.saveRecentlyExecutedRollbacks(mRecentlyExecutedRollbacks);
         }
@@ -701,27 +746,12 @@
         VersionedPackage installedVersion = new VersionedPackage(packageName,
                 installedPackage.getLongVersionCode());
 
-        for (int user : installedUsers) {
-            final int storageFlags;
-            if (StorageManager.isFileEncryptedNativeOrEmulated()
-                    && !StorageManager.isUserKeyUnlocked(user)) {
-                // We've encountered a user that hasn't unlocked on a FBE device, so we can't copy
-                // across app user data until the user unlocks their device.
-                Log.e(TAG, "User: " + user + " isn't unlocked, skipping CE userdata backup.");
-                storageFlags = Installer.FLAG_STORAGE_DE;
-            } else {
-                storageFlags = Installer.FLAG_STORAGE_CE | Installer.FLAG_STORAGE_DE;
-            }
 
-            try {
-                mInstaller.snapshotAppData(packageName, user, storageFlags);
-            } catch (InstallerException ie) {
-                Log.e(TAG, "Unable to create app data snapshot for: " + packageName, ie);
-            }
-        }
+        final IntArray pendingBackups = mUserdataHelper.snapshotAppData(packageName,
+                installedUsers);
 
-        PackageRollbackInfo info = new PackageRollbackInfo(newVersion, installedVersion);
-
+        PackageRollbackInfo info = new PackageRollbackInfo(newVersion, installedVersion,
+                pendingBackups, new ArrayList<>());
         RollbackData data;
         try {
             synchronized (mLock) {
@@ -760,40 +790,24 @@
         }
 
         getHandler().post(() -> {
-            PackageManagerInternal pmi = LocalServices.getService(PackageManagerInternal.class);
             final RollbackData rollbackData = getRollbackForPackage(packageName);
-            if (rollbackData == null) {
-                pmi.finishPackageInstall(token, false);
-                return;
-            }
-
-            if (!rollbackData.inProgress) {
-                Log.e(TAG, "Request to restore userData for: " + packageName
-                        + ", but no rollback in progress.");
-                pmi.finishPackageInstall(token, false);
-                return;
-            }
-
-            final int storageFlags;
-            if (StorageManager.isFileEncryptedNativeOrEmulated()
-                    && !StorageManager.isUserKeyUnlocked(userId)) {
-                // We've encountered a user that hasn't unlocked on a FBE device, so we can't copy
-                // across app user data until the user unlocks their device.
-                Log.e(TAG, "User: " + userId + " isn't unlocked, skipping CE userdata restore.");
-
-                storageFlags = Installer.FLAG_STORAGE_DE;
-            } else {
-                storageFlags = Installer.FLAG_STORAGE_CE | Installer.FLAG_STORAGE_DE;
-            }
-
-            try {
-                mInstaller.restoreAppDataSnapshot(packageName, appId, ceDataInode,
-                        seInfo, userId, storageFlags);
-            } catch (InstallerException ie) {
-                Log.e(TAG, "Unable to restore app data snapshot: " + packageName, ie);
-            }
-
+            final boolean changedRollbackData = mUserdataHelper.restoreAppData(packageName,
+                    rollbackData, userId, appId, ceDataInode, seInfo);
+            final PackageManagerInternal pmi = LocalServices.getService(
+                    PackageManagerInternal.class);
             pmi.finishPackageInstall(token, false);
+
+            // We've updated metadata about this rollback, so save it to flash.
+            if (changedRollbackData) {
+                try {
+                    mRollbackStore.saveAvailableRollback(rollbackData);
+                } catch (IOException ioe) {
+                    // TODO(narayan): What is the right thing to do here ? This isn't a fatal error,
+                    // since it will only result in us trying to restore data again, which will be
+                    // a no-op if there's no data available.
+                    Log.e(TAG, "Unable to save available rollback: " + packageName, ioe);
+                }
+            }
         });
     }
 
@@ -900,10 +914,8 @@
             ensureRollbackDataLoadedLocked();
             for (int i = 0; i < mAvailableRollbacks.size(); ++i) {
                 RollbackData data = mAvailableRollbacks.get(i);
-                for (PackageRollbackInfo info : data.packages) {
-                    if (info.getPackageName().equals(packageName)) {
-                        return data;
-                    }
+                if (getPackageRollbackInfo(data, packageName) != null) {
+                    return data;
                 }
             }
         }
@@ -926,6 +938,22 @@
                 }
             }
         }
+
+        return null;
+    }
+
+    /**
+     * Returns the {@code PackageRollbackInfo} associated with {@code packageName} from
+     * a specified {@code RollbackData}.
+     */
+    static PackageRollbackInfo getPackageRollbackInfo(RollbackData data,
+            String packageName) {
+        for (PackageRollbackInfo info : data.packages) {
+            if (info.getPackageName().equals(packageName)) {
+                return info;
+            }
+        }
+
         return null;
     }
 
diff --git a/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java b/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java
index 2880103..f50e776 100644
--- a/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java
+++ b/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java
@@ -54,8 +54,8 @@
     }
 
     @Override
-    public int onHealthCheckFailed(String packageName) {
-        RollbackInfo rollback = getAvailableRollback(packageName);
+    public int onHealthCheckFailed(String packageName, long versionCode) {
+        RollbackInfo rollback = getAvailableRollback(packageName, versionCode);
         if (rollback == null) {
             // Don't handle the notification, no rollbacks available for the package
             return PackageHealthObserverImpact.USER_IMPACT_NONE;
@@ -65,8 +65,8 @@
     }
 
     @Override
-    public boolean execute(String packageName) {
-        RollbackInfo rollback = getAvailableRollback(packageName);
+    public boolean execute(String packageName, long versionCode) {
+        RollbackInfo rollback = getAvailableRollback(packageName, versionCode);
         if (rollback == null) {
             // Expected a rollback to be available, what happened?
             return false;
@@ -110,11 +110,12 @@
         PackageWatchdog.getInstance(mContext).startObservingHealth(this, packages, durationMs);
     }
 
-    private RollbackInfo getAvailableRollback(String packageName) {
+    private RollbackInfo getAvailableRollback(String packageName, long versionCode) {
         for (RollbackInfo rollback : mRollbackManager.getAvailableRollbacks()) {
             for (PackageRollbackInfo packageRollback : rollback.getPackages()) {
-                if (packageName.equals(packageRollback.getPackageName())) {
-                    // TODO(zezeozue): Only rollback if rollback version == failed package version
+                if (packageName.equals(packageRollback.getPackageName())
+                        && packageRollback.getVersionRolledBackFrom().getVersionCode()
+                        == versionCode) {
                     return rollback;
                 }
             }
diff --git a/services/core/java/com/android/server/rollback/RollbackStore.java b/services/core/java/com/android/server/rollback/RollbackStore.java
index 98ebb09..c70f47d 100644
--- a/services/core/java/com/android/server/rollback/RollbackStore.java
+++ b/services/core/java/com/android/server/rollback/RollbackStore.java
@@ -16,9 +16,12 @@
 
 package com.android.server.rollback;
 
+import android.annotation.NonNull;
 import android.content.pm.VersionedPackage;
 import android.content.rollback.PackageRollbackInfo;
+import android.content.rollback.PackageRollbackInfo.RestoreInfo;
 import android.content.rollback.RollbackInfo;
+import android.util.IntArray;
 import android.util.Log;
 
 import libcore.io.IoUtils;
@@ -99,6 +102,64 @@
     }
 
     /**
+     * Converts an {@code JSONArray} of integers to an {@code IntArray}.
+     */
+    private static @NonNull IntArray convertToIntArray(@NonNull JSONArray jsonArray)
+            throws JSONException {
+        if (jsonArray.length() == 0) {
+            return new IntArray();
+        }
+
+        final int[] ret = new int[jsonArray.length()];
+        for (int i = 0; i < ret.length; ++i) {
+            ret[i] = jsonArray.getInt(i);
+        }
+
+        return IntArray.wrap(ret);
+    }
+
+    /**
+     * Converts an {@code IntArray} into an {@code JSONArray} of integers.
+     */
+    private static @NonNull JSONArray convertToJsonArray(@NonNull IntArray intArray) {
+        JSONArray jsonArray = new JSONArray();
+        for (int i = 0; i < intArray.size(); ++i) {
+            jsonArray.put(intArray.get(i));
+        }
+
+        return jsonArray;
+    }
+
+    private static @NonNull JSONArray convertToJsonArray(@NonNull List<RestoreInfo> list)
+            throws JSONException {
+        JSONArray jsonArray = new JSONArray();
+        for (RestoreInfo ri : list) {
+            JSONObject jo = new JSONObject();
+            jo.put("userId", ri.userId);
+            jo.put("appId", ri.appId);
+            jo.put("seInfo", ri.seInfo);
+            jsonArray.put(jo);
+        }
+
+        return jsonArray;
+    }
+
+    private static @NonNull ArrayList<RestoreInfo> convertToRestoreInfoArray(
+            @NonNull JSONArray array) throws JSONException {
+        ArrayList<RestoreInfo> restoreInfos = new ArrayList<>();
+
+        for (int i = 0; i < array.length(); ++i) {
+            JSONObject jo = array.getJSONObject(i);
+            restoreInfos.add(new RestoreInfo(
+                    jo.getInt("userId"),
+                    jo.getInt("appId"),
+                    jo.getString("seInfo")));
+        }
+
+        return restoreInfos;
+    }
+
+    /**
      * Reads the list of recently executed rollbacks from persistent storage.
      */
     List<RollbackInfo> loadRecentlyExecutedRollbacks() {
@@ -239,6 +300,12 @@
         JSONObject json = new JSONObject();
         json.put("versionRolledBackFrom", toJson(info.getVersionRolledBackFrom()));
         json.put("versionRolledBackTo", toJson(info.getVersionRolledBackTo()));
+
+        IntArray pendingBackups = info.getPendingBackups();
+        List<RestoreInfo> pendingRestores = info.getPendingRestores();
+        json.put("pendingBackups", convertToJsonArray(pendingBackups));
+        json.put("pendingRestores", convertToJsonArray(pendingRestores));
+
         return json;
     }
 
@@ -247,7 +314,14 @@
                 json.getJSONObject("versionRolledBackFrom"));
         VersionedPackage versionRolledBackTo = versionedPackageFromJson(
                 json.getJSONObject("versionRolledBackTo"));
-        return new PackageRollbackInfo(versionRolledBackFrom, versionRolledBackTo);
+
+        final IntArray pendingBackups = convertToIntArray(
+                json.getJSONArray("pendingBackups"));
+        final ArrayList<RestoreInfo> pendingRestores = convertToRestoreInfoArray(
+                json.getJSONArray("pendingRestores"));
+
+        return new PackageRollbackInfo(versionRolledBackFrom, versionRolledBackTo,
+                pendingBackups, pendingRestores);
     }
 
     private JSONArray versionedPackagesToJson(List<VersionedPackage> packages)
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index a83ffe8..080f965 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -29,6 +29,7 @@
 import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.Display.FLAG_PRIVATE;
+import static android.view.Display.INVALID_DISPLAY;
 import static android.view.InsetsState.TYPE_IME;
 import static android.view.Surface.ROTATION_0;
 import static android.view.Surface.ROTATION_180;
@@ -43,6 +44,7 @@
 import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
 import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
 import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
+import static android.view.WindowManager.LayoutParams.FLAG_SPLIT_TOUCH;
 import static android.view.WindowManager.LayoutParams.NEEDS_MENU_SET_TRUE;
 import static android.view.WindowManager.LayoutParams.NEEDS_MENU_UNSET;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
@@ -140,9 +142,11 @@
 import android.graphics.Region;
 import android.graphics.Region.Op;
 import android.hardware.display.DisplayManagerInternal;
+import android.os.Binder;
 import android.os.Debug;
 import android.os.Handler;
 import android.os.IBinder;
+import android.os.Process;
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.os.Trace;
@@ -157,6 +161,7 @@
 import android.view.Gravity;
 import android.view.InputChannel;
 import android.view.InputDevice;
+import android.view.InputWindowHandle;
 import android.view.InsetsState.InternalInsetType;
 import android.view.MagnificationSpec;
 import android.view.RemoteAnimationDefinition;
@@ -515,6 +520,9 @@
 
     private final InsetsStateController mInsetsStateController;
 
+    private SurfaceControl mParentSurfaceControl;
+    private InputWindowHandle mPortalWindowHandle;
+
     // Last systemUiVisibility we received from status bar.
     private int mLastStatusBarVisibility = 0;
     // Last systemUiVisibility we dispatched to windows.
@@ -2417,10 +2425,7 @@
             win.getTouchableRegion(mTmpRegion);
             mTouchExcludeRegion.op(mTmpRegion, Region.Op.UNION);
         }
-        for (int i = mTapExcludeProvidingWindows.size() - 1; i >= 0; i--) {
-            final WindowState win = mTapExcludeProvidingWindows.valueAt(i);
-            win.amendTapExcludeRegion(mTouchExcludeRegion);
-        }
+        amendWindowTapExcludeRegion(mTouchExcludeRegion);
         // TODO(multi-display): Support docked stacks on secondary displays.
         if (mDisplayId == DEFAULT_DISPLAY && getSplitScreenPrimaryStack() != null) {
             mDividerControllerLocked.getTouchRegion(mTmpRect);
@@ -2432,6 +2437,18 @@
         }
     }
 
+    /**
+     * Union the region with all the tap exclude region provided by windows on this display.
+     *
+     * @param inOutRegion The region to be amended.
+     */
+    void amendWindowTapExcludeRegion(Region inOutRegion) {
+        for (int i = mTapExcludeProvidingWindows.size() - 1; i >= 0; i--) {
+            final WindowState win = mTapExcludeProvidingWindows.valueAt(i);
+            win.amendTapExcludeRegion(inOutRegion);
+        }
+    }
+
     @Override
     void switchUser() {
         super.switchUser();
@@ -3593,6 +3610,13 @@
     private void updateBounds() {
         calculateBounds(mDisplayInfo, mTmpBounds);
         setBounds(mTmpBounds);
+        if (mPortalWindowHandle != null && mParentSurfaceControl != null) {
+            mPortalWindowHandle.touchableRegion.getBounds(mTmpRect);
+            if (!mTmpBounds.equals(mTmpRect)) {
+                mPortalWindowHandle.touchableRegion.set(mTmpBounds);
+                mPendingTransaction.setInputWindowInfo(mParentSurfaceControl, mPortalWindowHandle);
+            }
+        }
     }
 
     // Determines the current display bounds based on the current state
@@ -4837,15 +4861,43 @@
                 || mWmService.mForceDesktopModeOnExternalDisplays;
     }
 
-     /**
+    /**
      * Re-parent the DisplayContent's top surfaces, {@link #mWindowingLayer} and
      * {@link #mOverlayLayer} to the specified surfaceControl.
      *
-     * @param surfaceControlHandle The new SurfaceControl, where the DisplayContent's
-     *                             surfaces will be re-parented to.
+     * @param sc The new SurfaceControl, where the DisplayContent's surfaces will be re-parented to.
      */
     void reparentDisplayContent(SurfaceControl sc) {
-        mPendingTransaction.reparent(mWindowingLayer, sc)
-                .reparent(mOverlayLayer, sc);
+        mParentSurfaceControl = sc;
+        if (mPortalWindowHandle == null) {
+            mPortalWindowHandle = createPortalWindowHandle(sc.toString());
+        }
+        mPendingTransaction.setInputWindowInfo(sc, mPortalWindowHandle)
+                .reparent(mWindowingLayer, sc).reparent(mOverlayLayer, sc);
+    }
+
+    /**
+     * Create a portal window handle for input. This window transports any touch to the display
+     * indicated by {@link InputWindowHandle#portalToDisplayId} if the touch hits this window.
+     *
+     * @param name The name of the portal window handle.
+     * @return the new portal window handle.
+     */
+    private InputWindowHandle createPortalWindowHandle(String name) {
+        // Let surface flinger to set the display ID of this input window handle because we don't
+        // know which display the parent surface control is on.
+        final InputWindowHandle portalWindowHandle = new InputWindowHandle(
+                null /* inputApplicationHandle */, null /* clientWindow */, INVALID_DISPLAY);
+        portalWindowHandle.name = name;
+        portalWindowHandle.token = new Binder();
+        portalWindowHandle.layoutParamsFlags =
+                FLAG_SPLIT_TOUCH | FLAG_NOT_FOCUSABLE | FLAG_NOT_TOUCH_MODAL;
+        getBounds(mTmpBounds);
+        portalWindowHandle.touchableRegion.set(mTmpBounds);
+        portalWindowHandle.scaleFactor = 1f;
+        portalWindowHandle.ownerPid = Process.myPid();
+        portalWindowHandle.ownerUid = Process.myUid();
+        portalWindowHandle.portalToDisplayId = mDisplayId;
+        return portalWindowHandle;
     }
 }
diff --git a/services/core/java/com/android/server/wm/TapExcludeRegionHolder.java b/services/core/java/com/android/server/wm/TapExcludeRegionHolder.java
index cbc936f..0a4ab67 100644
--- a/services/core/java/com/android/server/wm/TapExcludeRegionHolder.java
+++ b/services/core/java/com/android/server/wm/TapExcludeRegionHolder.java
@@ -49,7 +49,9 @@
     void amendRegion(Region region, Rect boundingRegion) {
         for (int i = mTapExcludeRects.size() - 1; i>= 0 ; --i) {
             final Rect rect = mTapExcludeRects.valueAt(i);
-            rect.intersect(boundingRegion);
+            if (boundingRegion != null) {
+                rect.intersect(boundingRegion);
+            }
             region.union(rect);
         }
     }
diff --git a/services/core/java/com/android/server/wm/TaskTapPointerEventListener.java b/services/core/java/com/android/server/wm/TaskTapPointerEventListener.java
index 2e5df45..dd94af6 100644
--- a/services/core/java/com/android/server/wm/TaskTapPointerEventListener.java
+++ b/services/core/java/com/android/server/wm/TaskTapPointerEventListener.java
@@ -70,6 +70,18 @@
                     // method target window will lose the focus.
                     return;
                 }
+                final Region windowTapExcludeRegion = Region.obtain();
+                mDisplayContent.amendWindowTapExcludeRegion(windowTapExcludeRegion);
+                if (windowTapExcludeRegion.contains(x, y)) {
+                    windowTapExcludeRegion.recycle();
+                    // The user is tapping on the window tap exclude region. We don't move this
+                    // display to top. A window tap exclude region, for example, may be set by an
+                    // ActivityView, and the region would match the bounds of both the ActivityView
+                    // and the virtual display in it. In this case, we would take the tap that is on
+                    // the embedded virtual display instead of this display.
+                    return;
+                }
+                windowTapExcludeRegion.recycle();
                 WindowContainer parent = mDisplayContent.getParent();
                 if (parent != null && parent.getTopChild() != mDisplayContent) {
                     parent.positionChildAt(WindowContainer.POSITION_TOP, mDisplayContent,
@@ -81,9 +93,6 @@
 
     @Override
     public void onPointerEvent(MotionEvent motionEvent) {
-        if (motionEvent.getDisplayId() != getDisplayId()) {
-            return;
-        }
         switch (motionEvent.getActionMasked()) {
             case MotionEvent.ACTION_DOWN: {
                 final int x = (int) motionEvent.getX();
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 752c24e..975e62a 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -6532,8 +6532,13 @@
 
     /**
      * Update a tap exclude region with a rectangular area in the window identified by the provided
-     * id. Touches on this region will not switch focus to this window. Passing an empty rect will
-     * remove the area from the exclude region of this window.
+     * id. Touches down on this region will not:
+     * <ol>
+     * <li>Switch focus to this window.</li>
+     * <li>Move the display of this window to top.</li>
+     * <li>Send the touch events to this window.</li>
+     * </ol>
+     * Passing an empty rect will remove the area from the exclude region of this window.
      */
     void updateTapExcludeRegion(IWindow client, int regionId, int left, int top, int width,
             int height) {
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 4f12010..62e7200 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -536,7 +536,7 @@
     private final Point mSurfacePosition = new Point();
 
     /**
-     * A region inside of this window to be excluded from touch-related focus switches.
+     * A region inside of this window to be excluded from touch.
      */
     private TapExcludeRegionHolder mTapExcludeRegionHolder;
 
@@ -2168,6 +2168,24 @@
             }
             region.set(mTmpRect);
             cropRegionToStackBoundsIfNeeded(region);
+            subtractTouchExcludeRegionIfNeeded(region);
+        } else if (modal && mTapExcludeRegionHolder != null) {
+            final Region touchExcludeRegion = Region.obtain();
+            amendTapExcludeRegion(touchExcludeRegion);
+            if (!touchExcludeRegion.isEmpty()) {
+                // Remove touch modal because there are some areas that cannot be touched.
+                flags |= FLAG_NOT_TOUCH_MODAL;
+                // Give it a large touchable region at first because it was touch modal. The window
+                // might be moved on the display, so the touchable region should be large enough to
+                // ensure it covers the whole display, no matter where it is moved.
+                getDisplayContent().getBounds(mTmpRect);
+                final int dw = mTmpRect.width();
+                final int dh = mTmpRect.height();
+                region.set(-dw, -dh, dw + dw, dh + dh);
+                // Subtract the area that cannot be touched.
+                region.op(touchExcludeRegion, Region.Op.DIFFERENCE);
+            }
+            touchExcludeRegion.recycle();
         } else {
             // Not modal or full screen modal
             getTouchableRegion(region);
@@ -2837,6 +2855,7 @@
             }
         }
         cropRegionToStackBoundsIfNeeded(outRegion);
+        subtractTouchExcludeRegionIfNeeded(outRegion);
     }
 
     private void cropRegionToStackBoundsIfNeeded(Region region) {
@@ -2855,6 +2874,22 @@
     }
 
     /**
+     * If this window has areas that cannot be touched, we subtract those areas from its touchable
+     * region.
+     */
+    private void subtractTouchExcludeRegionIfNeeded(Region touchableRegion) {
+        if (mTapExcludeRegionHolder == null) {
+            return;
+        }
+        final Region touchExcludeRegion = Region.obtain();
+        amendTapExcludeRegion(touchExcludeRegion);
+        if (!touchExcludeRegion.isEmpty()) {
+            touchableRegion.op(touchExcludeRegion, Region.Op.DIFFERENCE);
+        }
+        touchExcludeRegion.recycle();
+    }
+
+    /**
      * Report a focus change.  Must be called with no locks held, and consistently
      * from the same serialized thread (such as dispatched from a handler).
      */
@@ -4728,11 +4763,25 @@
         mTapExcludeRegionHolder.updateRegion(regionId, left, top, width, height);
         // Trigger touch exclude region update on current display.
         currentDisplay.updateTouchExcludeRegion();
+        // Trigger touchable region update for this window.
+        currentDisplay.getInputMonitor().updateInputWindowsLw(true /* force */);
     }
 
-    /** Union the region with current tap exclude region that this window provides. */
+    /**
+     * Union the region with current tap exclude region that this window provides.
+     *
+     * @param region The region to be amended. It is on the screen coordinates.
+     */
     void amendTapExcludeRegion(Region region) {
-        mTapExcludeRegionHolder.amendRegion(region, getBounds());
+        final Region tempRegion = Region.obtain();
+        mTmpRect.set(mWindowFrames.mFrame);
+        mTmpRect.offsetTo(0, 0);
+        mTapExcludeRegionHolder.amendRegion(tempRegion, mTmpRect);
+        // The region held by the holder is on the window coordinates. We need to translate it to
+        // the screen coordinates.
+        tempRegion.translate(mWindowFrames.mFrame.left, mWindowFrames.mFrame.top);
+        region.op(tempRegion, Region.Op.UNION);
+        tempRegion.recycle();
     }
 
     @Override
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 51bdbb3..8f223b2 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -74,20 +74,14 @@
 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
 import static android.provider.Settings.Global.PRIVATE_DNS_MODE;
 import static android.provider.Settings.Global.PRIVATE_DNS_SPECIFIER;
-
 import static android.provider.Telephony.Carriers.DPC_URI;
 import static android.provider.Telephony.Carriers.ENFORCE_KEY;
 import static android.provider.Telephony.Carriers.ENFORCE_MANAGED_URI;
 
-import static com.android.internal.logging.nano.MetricsProto.MetricsEvent
-        .PROVISIONING_ENTRY_POINT_ADB;
-import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker
-        .STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW;
-
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.PROVISIONING_ENTRY_POINT_ADB;
+import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW;
 import static com.android.server.devicepolicy.TransferOwnershipMetadataManager.ADMIN_TYPE_DEVICE_OWNER;
 import static com.android.server.devicepolicy.TransferOwnershipMetadataManager.ADMIN_TYPE_PROFILE_OWNER;
-
-
 import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
 
 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
@@ -240,11 +234,11 @@
 import com.android.internal.util.FunctionalUtils.ThrowingRunnable;
 import com.android.internal.util.JournaledFile;
 import com.android.internal.util.Preconditions;
+import com.android.internal.util.StatLogger;
 import com.android.internal.util.XmlUtils;
 import com.android.internal.widget.LockPatternUtils;
 import com.android.server.LocalServices;
 import com.android.server.LockGuard;
-import com.android.internal.util.StatLogger;
 import com.android.server.SystemServerInitThreadPool;
 import com.android.server.SystemService;
 import com.android.server.devicepolicy.DevicePolicyManagerService.ActiveAdmin.TrustAgentInfo;
@@ -14207,7 +14201,8 @@
                         + "calendar APIs", packageName));
                 return false;
             }
-            final Intent intent = new Intent(CalendarContract.ACTION_VIEW_WORK_CALENDAR_EVENT);
+            final Intent intent = new Intent(
+                    CalendarContract.ACTION_VIEW_MANAGED_PROFILE_CALENDAR_EVENT);
             intent.setPackage(packageName);
             intent.putExtra(CalendarContract.EXTRA_EVENT_ID, eventId);
             intent.putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, start);
diff --git a/services/tests/servicestests/src/com/android/server/rollback/AppDataRollbackHelperTest.java b/services/tests/servicestests/src/com/android/server/rollback/AppDataRollbackHelperTest.java
new file mode 100644
index 0000000..33cbf7a
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/rollback/AppDataRollbackHelperTest.java
@@ -0,0 +1,176 @@
+/*
+ * 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 com.android.server.rollback;
+
+import static org.junit.Assert.*;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verifyZeroInteractions;
+
+import android.content.pm.VersionedPackage;
+import android.content.rollback.PackageRollbackInfo;
+import android.content.rollback.PackageRollbackInfo.RestoreInfo;
+import android.util.IntArray;
+
+import com.android.server.pm.Installer;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.mockito.InOrder;
+import org.mockito.Mockito;
+
+import java.io.File;
+import java.util.ArrayList;
+
+@RunWith(JUnit4.class)
+public class AppDataRollbackHelperTest {
+
+    @Test
+    public void testSnapshotAppData() throws Exception {
+        Installer installer = mock(Installer.class);
+        AppDataRollbackHelper helper = spy(new AppDataRollbackHelper(installer));
+
+        // All users are unlocked so we should snapshot data for them.
+        doReturn(true).when(helper).isUserCredentialLocked(eq(10));
+        doReturn(true).when(helper).isUserCredentialLocked(eq(11));
+        IntArray pending = helper.snapshotAppData("com.foo.bar", new int[]{10, 11});
+        assertEquals(2, pending.size());
+        assertEquals(10, pending.get(0));
+        assertEquals(11, pending.get(1));
+
+        InOrder inOrder = Mockito.inOrder(installer);
+        inOrder.verify(installer).snapshotAppData(
+                eq("com.foo.bar"), eq(10), eq(Installer.FLAG_STORAGE_DE));
+        inOrder.verify(installer).snapshotAppData(
+                eq("com.foo.bar"), eq(11), eq(Installer.FLAG_STORAGE_DE));
+        inOrder.verifyNoMoreInteractions();
+
+        // One of the users is unlocked but the other isn't
+        doReturn(false).when(helper).isUserCredentialLocked(eq(10));
+        doReturn(true).when(helper).isUserCredentialLocked(eq(11));
+
+        pending = helper.snapshotAppData("com.foo.bar", new int[]{10, 11});
+        assertEquals(1, pending.size());
+        assertEquals(11, pending.get(0));
+
+        inOrder = Mockito.inOrder(installer);
+        inOrder.verify(installer).snapshotAppData(
+                eq("com.foo.bar"), eq(10),
+                eq(Installer.FLAG_STORAGE_CE | Installer.FLAG_STORAGE_DE));
+        inOrder.verify(installer).snapshotAppData(
+                eq("com.foo.bar"), eq(11), eq(Installer.FLAG_STORAGE_DE));
+        inOrder.verifyNoMoreInteractions();
+    }
+
+    private static RollbackData createInProgressRollbackData(String packageName) {
+        RollbackData data = new RollbackData(1, new File("/does/not/exist"));
+        data.packages.add(new PackageRollbackInfo(
+                new VersionedPackage(packageName, 1), new VersionedPackage(packageName, 1),
+                new IntArray(), new ArrayList<>()));
+        data.inProgress = true;
+
+        return data;
+    }
+
+    @Test
+    public void testRestoreAppDataSnapshot_noRollbackData() throws Exception {
+        Installer installer = mock(Installer.class);
+        AppDataRollbackHelper helper = spy(new AppDataRollbackHelper(installer));
+
+        assertFalse(helper.restoreAppData("com.foo", null, 0, 0, 0, "seinfo"));
+        verifyZeroInteractions(installer);
+    }
+
+    @Test
+    public void testRestoreAppDataSnapshot_noRollbackInProgress() throws Exception {
+        Installer installer = mock(Installer.class);
+        AppDataRollbackHelper helper = spy(new AppDataRollbackHelper(installer));
+
+        RollbackData rd = createInProgressRollbackData("com.foo");
+        // Override the in progress flag.
+        rd.inProgress = false;
+        assertFalse(helper.restoreAppData("com.foo", rd, 0, 0, 0, "seinfo"));
+        verifyZeroInteractions(installer);
+    }
+
+    @Test
+    public void testRestoreAppDataSnapshot_pendingBackupForUser() throws Exception {
+        Installer installer = mock(Installer.class);
+        AppDataRollbackHelper helper = spy(new AppDataRollbackHelper(installer));
+
+        RollbackData rd = createInProgressRollbackData("com.foo");
+        IntArray pendingBackups = rd.packages.get(0).getPendingBackups();
+        pendingBackups.add(10);
+        pendingBackups.add(11);
+
+        assertTrue(helper.restoreAppData("com.foo", rd, 10 /* userId */, 1, 2, "seinfo"));
+
+        // Should only require FLAG_STORAGE_DE here because we have a pending backup that we
+        // didn't manage to execute.
+        InOrder inOrder = Mockito.inOrder(installer);
+        inOrder.verify(installer).restoreAppDataSnapshot(
+                eq("com.foo"), eq(1), eq(2L), eq("seinfo"), eq(10), eq(Installer.FLAG_STORAGE_DE));
+        inOrder.verifyNoMoreInteractions();
+
+        assertEquals(1, pendingBackups.size());
+        assertEquals(11, pendingBackups.get(0));
+    }
+
+    @Test
+    public void testRestoreAppDataSnapshot_availableBackupForLockedUser() throws Exception {
+        Installer installer = mock(Installer.class);
+        AppDataRollbackHelper helper = spy(new AppDataRollbackHelper(installer));
+        doReturn(true).when(helper).isUserCredentialLocked(eq(10));
+
+        RollbackData rd = createInProgressRollbackData("com.foo");
+
+        assertTrue(helper.restoreAppData("com.foo", rd, 10 /* userId */, 1, 2, "seinfo"));
+
+        InOrder inOrder = Mockito.inOrder(installer);
+        inOrder.verify(installer).restoreAppDataSnapshot(
+                eq("com.foo"), eq(1), eq(2L), eq("seinfo"), eq(10), eq(Installer.FLAG_STORAGE_DE));
+        inOrder.verifyNoMoreInteractions();
+
+        ArrayList<RestoreInfo> pendingRestores = rd.packages.get(0).getPendingRestores();
+        assertEquals(1, pendingRestores.size());
+        assertEquals(10, pendingRestores.get(0).userId);
+        assertEquals(1, pendingRestores.get(0).appId);
+        assertEquals("seinfo", pendingRestores.get(0).seInfo);
+    }
+
+    @Test
+    public void testRestoreAppDataSnapshot_availableBackupForUnockedUser() throws Exception {
+        Installer installer = mock(Installer.class);
+        AppDataRollbackHelper helper = spy(new AppDataRollbackHelper(installer));
+        doReturn(false).when(helper).isUserCredentialLocked(eq(10));
+
+        RollbackData rd = createInProgressRollbackData("com.foo");
+        assertFalse(helper.restoreAppData("com.foo", rd, 10 /* userId */, 1, 2, "seinfo"));
+
+        InOrder inOrder = Mockito.inOrder(installer);
+        inOrder.verify(installer).restoreAppDataSnapshot(
+                eq("com.foo"), eq(1), eq(2L), eq("seinfo"), eq(10),
+                eq(Installer.FLAG_STORAGE_DE | Installer.FLAG_STORAGE_CE));
+        inOrder.verifyNoMoreInteractions();
+
+        ArrayList<RestoreInfo> pendingRestores = rd.packages.get(0).getPendingRestores();
+        assertEquals(0, pendingRestores.size());
+    }
+}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
index bde9dde..47ec390 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
@@ -2006,6 +2006,28 @@
     }
 
     @Test
+    public void testXml_statusBarIcons_default() throws Exception {
+        ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false);
+        mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper);
+        loadStreamXml(baos, false);
+
+        assertEquals(PreferencesHelper.DEFAULT_HIDE_SILENT_STATUS_BAR_ICONS,
+                mHelper.shouldHideSilentStatusIcons());
+    }
+
+    @Test
+    public void testXml_statusBarIcons() throws Exception {
+        mHelper.setHideSilentStatusIcons(!PreferencesHelper.DEFAULT_HIDE_SILENT_STATUS_BAR_ICONS);
+
+        ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false);
+        mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper);
+        loadStreamXml(baos, false);
+
+        assertEquals(!PreferencesHelper.DEFAULT_HIDE_SILENT_STATUS_BAR_ICONS,
+                mHelper.shouldHideSilentStatusIcons());
+    }
+
+    @Test
     public void testSetNotificationDelegate() {
         mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
         assertEquals("other", mHelper.getNotificationDelegate(PKG_O, UID_O));
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index 4475630..3317876 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -540,7 +540,7 @@
      *
      * @hide
      */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
+    @UnsupportedAppUsage
     public int getDataRegState() {
         return mDataRegState;
     }
diff --git a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
index 86af642..c1c598d 100644
--- a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
+++ b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
@@ -22,6 +22,7 @@
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
+import android.content.pm.VersionedPackage;
 import android.os.test.TestLooper;
 import android.support.test.InstrumentationRegistry;
 
@@ -47,6 +48,7 @@
     private static final String APP_B = "com.package.b";
     private static final String APP_C = "com.package.c";
     private static final String APP_D = "com.package.d";
+    private static final long VERSION_CODE = 1L;
     private static final String OBSERVER_NAME_1 = "observer1";
     private static final String OBSERVER_NAME_2 = "observer2";
     private static final String OBSERVER_NAME_3 = "observer3";
@@ -193,7 +195,7 @@
 
         // Then fail APP_A below the threshold
         for (int i = 0; i < TRIGGER_FAILURE_COUNT - 1; i++) {
-            watchdog.onPackageFailure(new String[]{APP_A});
+            watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)));
         }
 
         // Run handler so package failures are dispatched to observers
@@ -209,12 +211,10 @@
      * the failed packages.
      */
     @Test
-    public void testPackageFailureNotifyNone() throws Exception {
+    public void testPackageFailureDifferentPackageNotifyNone() throws Exception {
         PackageWatchdog watchdog = createWatchdog();
-        TestObserver observer1 = new TestObserver(OBSERVER_NAME_1,
-                PackageHealthObserverImpact.USER_IMPACT_HIGH);
-        TestObserver observer2 = new TestObserver(OBSERVER_NAME_2,
-                PackageHealthObserverImpact.USER_IMPACT_HIGH);
+        TestObserver observer1 = new TestObserver(OBSERVER_NAME_1);
+        TestObserver observer2 = new TestObserver(OBSERVER_NAME_2);
 
 
         watchdog.startObservingHealth(observer2, Arrays.asList(APP_A), SHORT_DURATION);
@@ -222,7 +222,7 @@
 
         // Then fail APP_C (not observed) above the threshold
         for (int i = 0; i < TRIGGER_FAILURE_COUNT; i++) {
-            watchdog.onPackageFailure(new String[]{APP_C});
+            watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_C, VERSION_CODE)));
         }
 
         // Run handler so package failures are dispatched to observers
@@ -234,6 +234,40 @@
     }
 
     /**
+     * Test package failure and does not notify any observer because the failed package version
+     * does not match the available rollback-from-version.
+     */
+    @Test
+    public void testPackageFailureDifferentVersionNotifyNone() throws Exception {
+        PackageWatchdog watchdog = createWatchdog();
+        long differentVersionCode = 2L;
+        TestObserver observer = new TestObserver(OBSERVER_NAME_1) {
+                public int onHealthCheckFailed(String packageName, long versionCode) {
+                    if (versionCode == VERSION_CODE) {
+                        // Only rollback for specific versionCode
+                        return PackageHealthObserverImpact.USER_IMPACT_MEDIUM;
+                    }
+                    return PackageHealthObserverImpact.USER_IMPACT_NONE;
+                }
+            };
+
+        watchdog.startObservingHealth(observer, Arrays.asList(APP_A), SHORT_DURATION);
+
+        // Then fail APP_A (different version) above the threshold
+        for (int i = 0; i < TRIGGER_FAILURE_COUNT; i++) {
+            watchdog.onPackageFailure(Arrays.asList(
+                            new VersionedPackage(APP_A, differentVersionCode)));
+        }
+
+        // Run handler so package failures are dispatched to observers
+        mTestLooper.dispatchAll();
+
+        // Verify that observers are not notified
+        assertEquals(0, observer.mFailedPackages.size());
+    }
+
+
+    /**
      * Test package failure and notifies only least impact observers.
      */
     @Test
@@ -260,7 +294,10 @@
 
         // Then fail all apps above the threshold
         for (int i = 0; i < TRIGGER_FAILURE_COUNT; i++) {
-            watchdog.onPackageFailure(new String[]{APP_A, APP_B, APP_C, APP_D});
+            watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE),
+                    new VersionedPackage(APP_B, VERSION_CODE),
+                    new VersionedPackage(APP_C, VERSION_CODE),
+                    new VersionedPackage(APP_D, VERSION_CODE)));
         }
 
         // Run handler so package failures are dispatched to observers
@@ -297,7 +334,7 @@
      * <ul>
      */
     @Test
-    public void testPackageFailureNotifyLeastSuccessively() throws Exception {
+    public void testPackageFailureNotifyLeastImpactSuccessively() throws Exception {
         PackageWatchdog watchdog = createWatchdog();
         TestObserver observerFirst = new TestObserver(OBSERVER_NAME_1,
                 PackageHealthObserverImpact.USER_IMPACT_LOW);
@@ -310,7 +347,7 @@
 
         // Then fail APP_A above the threshold
         for (int i = 0; i < TRIGGER_FAILURE_COUNT; i++) {
-            watchdog.onPackageFailure(new String[]{APP_A});
+            watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)));
         }
         // Run handler so package failures are dispatched to observers
         mTestLooper.dispatchAll();
@@ -327,7 +364,7 @@
 
         // Then fail APP_A again above the threshold
         for (int i = 0; i < TRIGGER_FAILURE_COUNT; i++) {
-            watchdog.onPackageFailure(new String[]{APP_A});
+            watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)));
         }
         // Run handler so package failures are dispatched to observers
         mTestLooper.dispatchAll();
@@ -344,7 +381,7 @@
 
         // Then fail APP_A again above the threshold
         for (int i = 0; i < TRIGGER_FAILURE_COUNT; i++) {
-            watchdog.onPackageFailure(new String[]{APP_A});
+            watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)));
         }
         // Run handler so package failures are dispatched to observers
         mTestLooper.dispatchAll();
@@ -361,7 +398,7 @@
 
         // Then fail APP_A again above the threshold
         for (int i = 0; i < TRIGGER_FAILURE_COUNT; i++) {
-            watchdog.onPackageFailure(new String[]{APP_A});
+            watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)));
         }
         // Run handler so package failures are dispatched to observers
         mTestLooper.dispatchAll();
@@ -388,7 +425,7 @@
 
         // Then fail APP_A above the threshold
         for (int i = 0; i < TRIGGER_FAILURE_COUNT; i++) {
-            watchdog.onPackageFailure(new String[]{APP_A});
+            watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)));
         }
 
         // Run handler so package failures are dispatched to observers
@@ -420,11 +457,11 @@
             mImpact = impact;
         }
 
-        public int onHealthCheckFailed(String packageName) {
+        public int onHealthCheckFailed(String packageName, long versionCode) {
             return mImpact;
         }
 
-        public boolean execute(String packageName) {
+        public boolean execute(String packageName, long versionCode) {
             mFailedPackages.add(packageName);
             return true;
         }
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 036c5dc..3127d74 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -495,7 +495,7 @@
 
             mNetworkAgent = new NetworkAgent(mHandlerThread.getLooper(), mServiceContext,
                     "Mock-" + typeName, mNetworkInfo, mNetworkCapabilities,
-                    linkProperties, mScore, new NetworkMisc()) {
+                    linkProperties, mScore, new NetworkMisc(), NetworkFactory.SerialNumber.NONE) {
                 @Override
                 public void unwanted() { mDisconnected.open(); }
 
@@ -725,7 +725,7 @@
     /**
      * A NetworkFactory that allows tests to wait until any in-flight NetworkRequest add or remove
      * operations have been processed. Before ConnectivityService can add or remove any requests,
-     * the factory must be told to expect those operations by calling expectAddRequests or
+     * the factory must be told to expect those operations by calling expectAddRequestsWithScores or
      * expectRemoveRequests.
      */
     private static class MockNetworkFactory extends NetworkFactory {
@@ -734,19 +734,22 @@
         private final AtomicBoolean mNetworkStarted = new AtomicBoolean(false);
 
         // Used to expect that requests be removed or added on a separate thread, without sleeping.
-        // Callers can call either expectAddRequests() or expectRemoveRequests() exactly once, then
-        // cause some other thread to add or remove requests, then call waitForRequests(). We can
-        // either expect requests to be added or removed, but not both, because CountDownLatch can
-        // only count in one direction.
-        private CountDownLatch mExpectations;
+        // Callers can call either expectAddRequestsWithScores() or expectRemoveRequests() exactly
+        // once, then cause some other thread to add or remove requests, then call
+        // waitForRequests().
+        // It is not possible to wait for both add and remove requests. When adding, the queue
+        // contains the expected score. When removing, the value is unused, all matters is the
+        // number of objects in the queue.
+        private final LinkedBlockingQueue<Integer> mExpectations;
 
         // Whether we are currently expecting requests to be added or removed. Valid only if
-        // mExpectations is non-null.
+        // mExpectations is non-empty.
         private boolean mExpectingAdditions;
 
         public MockNetworkFactory(Looper looper, Context context, String logTag,
                 NetworkCapabilities filter) {
             super(looper, context, logTag, filter);
+            mExpectations = new LinkedBlockingQueue<>();
         }
 
         public int getMyRequestCount() {
@@ -778,69 +781,82 @@
         }
 
         @Override
-        protected void handleAddRequest(NetworkRequest request, int score) {
-            // If we're expecting anything, we must be expecting additions.
-            if (mExpectations != null && !mExpectingAdditions) {
-                fail("Can't add requests while expecting requests to be removed");
-            }
+        protected void handleAddRequest(NetworkRequest request, int score,
+                int factorySerialNumber) {
+            synchronized (mExpectations) {
+                final Integer expectedScore = mExpectations.poll(); // null if the queue is empty
 
-            // Add the request.
-            super.handleAddRequest(request, score);
+                assertNotNull("Added more requests than expected (" + request + " score : "
+                        + score + ")", expectedScore);
+                // If we're expecting anything, we must be expecting additions.
+                if (!mExpectingAdditions) {
+                    fail("Can't add requests while expecting requests to be removed");
+                }
+                if (expectedScore != score) {
+                    fail("Expected score was " + expectedScore + " but actual was " + score
+                            + " in added request");
+                }
 
-            // Reduce the number of request additions we're waiting for.
-            if (mExpectingAdditions) {
-                assertTrue("Added more requests than expected", mExpectations.getCount() > 0);
-                mExpectations.countDown();
+                // Add the request.
+                super.handleAddRequest(request, score, factorySerialNumber);
+                mExpectations.notify();
             }
         }
 
         @Override
         protected void handleRemoveRequest(NetworkRequest request) {
-            // If we're expecting anything, we must be expecting removals.
-            if (mExpectations != null && mExpectingAdditions) {
-                fail("Can't remove requests while expecting requests to be added");
-            }
+            synchronized (mExpectations) {
+                final Integer expectedScore = mExpectations.poll(); // null if the queue is empty
 
-            // Remove the request.
-            super.handleRemoveRequest(request);
+                assertTrue("Removed more requests than expected", expectedScore != null);
+                // If we're expecting anything, we must be expecting removals.
+                if (mExpectingAdditions) {
+                    fail("Can't remove requests while expecting requests to be added");
+                }
 
-            // Reduce the number of request removals we're waiting for.
-            if (!mExpectingAdditions) {
-                assertTrue("Removed more requests than expected", mExpectations.getCount() > 0);
-                mExpectations.countDown();
+                // Remove the request.
+                super.handleRemoveRequest(request);
+                mExpectations.notify();
             }
         }
 
         private void assertNoExpectations() {
-            if (mExpectations != null) {
-                fail("Can't add expectation, " + mExpectations.getCount() + " already pending");
+            if (mExpectations.size() != 0) {
+                fail("Can't add expectation, " + mExpectations.size() + " already pending");
             }
         }
 
-        // Expects that count requests will be added.
-        public void expectAddRequests(final int count) {
+        // Expects that requests with the specified scores will be added.
+        public void expectAddRequestsWithScores(final int... scores) {
             assertNoExpectations();
             mExpectingAdditions = true;
-            mExpectations = new CountDownLatch(count);
+            for (int score : scores) {
+                mExpectations.add(score);
+            }
         }
 
         // Expects that count requests will be removed.
         public void expectRemoveRequests(final int count) {
             assertNoExpectations();
             mExpectingAdditions = false;
-            mExpectations = new CountDownLatch(count);
+            for (int i = 0; i < count; ++i) {
+                mExpectations.add(0); // For removals the score is ignored so any value will do.
+            }
         }
 
         // Waits for the expected request additions or removals to happen within a timeout.
         public void waitForRequests() throws InterruptedException {
-            assertNotNull("Nothing to wait for", mExpectations);
-            mExpectations.await(TIMEOUT_MS, TimeUnit.MILLISECONDS);
-            final long count = mExpectations.getCount();
+            final long deadline = SystemClock.elapsedRealtime() + TIMEOUT_MS;
+            synchronized (mExpectations) {
+                while (mExpectations.size() > 0 && SystemClock.elapsedRealtime() < deadline) {
+                    mExpectations.wait(deadline - SystemClock.elapsedRealtime());
+                }
+            }
+            final long count = mExpectations.size();
             final String msg = count + " requests still not " +
                     (mExpectingAdditions ? "added" : "removed") +
                     " after " + TIMEOUT_MS + " ms";
             assertEquals(msg, 0, count);
-            mExpectations = null;
         }
 
         public void waitForNetworkRequests(final int count) throws InterruptedException {
@@ -2271,6 +2287,12 @@
         callback.expectCallback(CallbackState.LOST, mEthernetNetworkAgent);
     }
 
+    private int[] makeIntArray(final int size, final int value) {
+        final int[] array = new int[size];
+        Arrays.fill(array, value);
+        return array;
+    }
+
     private void tryNetworkFactoryRequests(int capability) throws Exception {
         // Verify NOT_RESTRICTED is set appropriately
         final NetworkCapabilities nc = new NetworkRequest.Builder().addCapability(capability)
@@ -2292,7 +2314,7 @@
                 mServiceContext, "testFactory", filter);
         testFactory.setScoreFilter(40);
         ConditionVariable cv = testFactory.getNetworkStartedCV();
-        testFactory.expectAddRequests(1);
+        testFactory.expectAddRequestsWithScores(0);
         testFactory.register();
         testFactory.waitForNetworkRequests(1);
         int expectedRequestCount = 1;
@@ -2303,7 +2325,7 @@
             assertFalse(testFactory.getMyStartRequested());
             NetworkRequest request = new NetworkRequest.Builder().addCapability(capability).build();
             networkCallback = new NetworkCallback();
-            testFactory.expectAddRequests(1);
+            testFactory.expectAddRequestsWithScores(0);  // New request
             mCm.requestNetwork(request, networkCallback);
             expectedRequestCount++;
             testFactory.waitForNetworkRequests(expectedRequestCount);
@@ -2323,7 +2345,7 @@
         // When testAgent connects, ConnectivityService will re-send us all current requests with
         // the new score. There are expectedRequestCount such requests, and we must wait for all of
         // them.
-        testFactory.expectAddRequests(expectedRequestCount);
+        testFactory.expectAddRequestsWithScores(makeIntArray(expectedRequestCount, 50));
         testAgent.connect(false);
         testAgent.addCapability(capability);
         waitFor(cv);
@@ -2331,7 +2353,7 @@
         assertFalse(testFactory.getMyStartRequested());
 
         // Bring in a bunch of requests.
-        testFactory.expectAddRequests(10);
+        testFactory.expectAddRequestsWithScores(makeIntArray(10, 50));
         assertEquals(expectedRequestCount, testFactory.getMyRequestCount());
         ConnectivityManager.NetworkCallback[] networkCallbacks =
                 new ConnectivityManager.NetworkCallback[10];
@@ -2354,8 +2376,11 @@
 
         // Drop the higher scored network.
         cv = testFactory.getNetworkStartedCV();
+        // With the default network disconnecting, the requests are sent with score 0 to factories.
+        testFactory.expectAddRequestsWithScores(makeIntArray(expectedRequestCount, 0));
         testAgent.disconnect();
         waitFor(cv);
+        testFactory.waitForNetworkRequests(expectedRequestCount);
         assertEquals(expectedRequestCount, testFactory.getMyRequestCount());
         assertTrue(testFactory.getMyStartRequested());
 
@@ -3177,22 +3202,23 @@
         testFactory.setScoreFilter(40);
 
         // Register the factory and expect it to start looking for a network.
-        testFactory.expectAddRequests(1);
+        testFactory.expectAddRequestsWithScores(0);  // Score 0 as the request is not served yet.
         testFactory.register();
         testFactory.waitForNetworkRequests(1);
         assertTrue(testFactory.getMyStartRequested());
 
         // Bring up wifi. The factory stops looking for a network.
         mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
-        testFactory.expectAddRequests(2);  // Because the default request changes score twice.
+        // Score 60 - 40 penalty for not validated yet, then 60 when it validates
+        testFactory.expectAddRequestsWithScores(20, 60);
         mWiFiNetworkAgent.connect(true);
-        testFactory.waitForNetworkRequests(1);
+        testFactory.waitForRequests();
         assertFalse(testFactory.getMyStartRequested());
 
         ContentResolver cr = mServiceContext.getContentResolver();
 
         // Turn on mobile data always on. The factory starts looking again.
-        testFactory.expectAddRequests(1);
+        testFactory.expectAddRequestsWithScores(0);  // Always on requests comes up with score 0
         setAlwaysOnNetworks(true);
         testFactory.waitForNetworkRequests(2);
         assertTrue(testFactory.getMyStartRequested());
@@ -3200,7 +3226,7 @@
         // Bring up cell data and check that the factory stops looking.
         assertLength(1, mCm.getAllNetworks());
         mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
-        testFactory.expectAddRequests(2);  // Because the cell request changes score twice.
+        testFactory.expectAddRequestsWithScores(10, 50);  // Unvalidated, then validated
         mCellNetworkAgent.connect(true);
         cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
         testFactory.waitForNetworkRequests(2);
diff --git a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
index 9578ded..e877a8f 100644
--- a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
+++ b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
@@ -35,6 +35,7 @@
 import android.net.INetd;
 import android.net.Network;
 import android.net.NetworkCapabilities;
+import android.net.NetworkFactory;
 import android.net.NetworkInfo;
 import android.net.NetworkMisc;
 import android.net.NetworkStack;
@@ -356,7 +357,8 @@
         caps.addCapability(0);
         caps.addTransportType(transport);
         NetworkAgentInfo nai = new NetworkAgentInfo(null, null, new Network(netId), info, null,
-                caps, 50, mCtx, null, mMisc, mConnService, mNetd, mNMS);
+                caps, 50, mCtx, null, mMisc, mConnService, mNetd, mNMS,
+                NetworkFactory.SerialNumber.NONE);
         nai.everValidated = true;
         return nai;
     }