Merge "Implement API council feedback for dismissKeyguard" into oc-dev
diff --git a/api/current.txt b/api/current.txt
index 77efc59..ed83772 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -3682,7 +3682,6 @@
     method public void onLowMemory();
     method public boolean onMenuItemSelected(int, android.view.MenuItem);
     method public boolean onMenuOpened(int, android.view.Menu);
-    method public void onMovedToDisplay(int, android.content.res.Configuration);
     method public void onMultiWindowModeChanged(boolean, android.content.res.Configuration);
     method public deprecated void onMultiWindowModeChanged(boolean);
     method public boolean onNavigateUp();
@@ -3944,7 +3943,7 @@
     field public static final int IMPORTANCE_FOREGROUND_SERVICE = 125; // 0x7d
     field public static final int IMPORTANCE_GONE = 1000; // 0x3e8
     field public static final int IMPORTANCE_PERCEPTIBLE = 230; // 0xe6
-    field public static final deprecated int IMPORTANCE_PERCEPTIBLE_DEPRECATED = 130; // 0x82
+    field public static final int IMPORTANCE_PERCEPTIBLE_PRE_26 = 130; // 0x82
     field public static final int IMPORTANCE_SERVICE = 300; // 0x12c
     field public static final int IMPORTANCE_TOP_SLEEPING = 150; // 0x96
     field public static final int IMPORTANCE_VISIBLE = 200; // 0xc8
@@ -4031,6 +4030,7 @@
     method public static android.app.ActivityOptions makeTaskLaunchBehind();
     method public static android.app.ActivityOptions makeThumbnailScaleUpAnimation(android.view.View, android.graphics.Bitmap, int, int);
     method public void requestUsageTimeReport(android.app.PendingIntent);
+    method public android.app.ActivityOptions setAppVerificationBundle(android.os.Bundle);
     method public android.app.ActivityOptions setLaunchBounds(android.graphics.Rect);
     method public android.app.ActivityOptions setLaunchDisplayId(int);
     method public android.os.Bundle toBundle();
@@ -4854,7 +4854,6 @@
     method public abstract android.app.FragmentTransaction remove(android.app.Fragment);
     method public abstract android.app.FragmentTransaction replace(int, android.app.Fragment);
     method public abstract android.app.FragmentTransaction replace(int, android.app.Fragment, java.lang.String);
-    method public abstract android.app.FragmentTransaction setAllowOptimization(boolean);
     method public abstract android.app.FragmentTransaction setBreadCrumbShortTitle(int);
     method public abstract android.app.FragmentTransaction setBreadCrumbShortTitle(java.lang.CharSequence);
     method public abstract android.app.FragmentTransaction setBreadCrumbTitle(int);
@@ -4862,6 +4861,7 @@
     method public abstract android.app.FragmentTransaction setCustomAnimations(int, int);
     method public abstract android.app.FragmentTransaction setCustomAnimations(int, int, int, int);
     method public abstract android.app.FragmentTransaction setPrimaryNavigationFragment(android.app.Fragment);
+    method public abstract android.app.FragmentTransaction setReorderingAllowed(boolean);
     method public abstract android.app.FragmentTransaction setTransition(int);
     method public abstract android.app.FragmentTransaction setTransitionStyle(int);
     method public abstract android.app.FragmentTransaction show(android.app.Fragment);
@@ -4955,7 +4955,7 @@
     method public final android.app.Activity getLastActivity();
     method public final android.app.Instrumentation.ActivityResult getResult();
     method public final boolean isBlocking();
-    method public android.app.Instrumentation.ActivityResult onMatchIntent(android.content.Intent);
+    method public android.app.Instrumentation.ActivityResult onStartActivity(android.content.Intent);
     method public final android.app.Activity waitForActivity();
     method public final android.app.Activity waitForActivityWithTimeout(long);
   }
@@ -6206,7 +6206,7 @@
 package android.app.admin {
 
   public final class ConnectEvent extends android.app.admin.NetworkEvent implements android.os.Parcelable {
-    method public java.lang.String getIpAddress();
+    method public java.net.InetAddress getInetAddress();
     method public int getPort();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.app.admin.ConnectEvent> CREATOR;
@@ -6549,8 +6549,8 @@
 
   public final class DnsEvent extends android.app.admin.NetworkEvent implements android.os.Parcelable {
     method public java.lang.String getHostname();
-    method public java.lang.String[] getIpAddresses();
-    method public int getIpAddressesCount();
+    method public java.net.InetAddress[] getInetAddresses();
+    method public int getTotalResolvedAddressCount();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.app.admin.DnsEvent> CREATOR;
   }
@@ -45610,7 +45610,6 @@
     method public boolean onKeyUp(int, android.view.KeyEvent);
     method protected void onLayout(boolean, int, int, int, int);
     method protected void onMeasure(int, int);
-    method public void onMovedToDisplay(int, android.content.res.Configuration);
     method protected void onOverScrolled(int, int, boolean, boolean);
     method public void onPointerCaptureChange(boolean);
     method public void onPopulateAccessibilityEvent(android.view.accessibility.AccessibilityEvent);
@@ -48938,7 +48937,6 @@
     method public int getRendererRequestedPriority();
     method public deprecated float getScale();
     method public android.webkit.WebSettings getSettings();
-    method public android.view.textclassifier.TextClassifier getTextClassifier();
     method public java.lang.String getTitle();
     method public java.lang.String getUrl();
     method public android.webkit.WebChromeClient getWebChromeClient();
@@ -48955,6 +48953,7 @@
     method public deprecated void onChildViewAdded(android.view.View, android.view.View);
     method public deprecated void onChildViewRemoved(android.view.View, android.view.View);
     method public deprecated void onGlobalFocusChanged(android.view.View, android.view.View);
+    method public void onMovedToDisplay(int, android.content.res.Configuration);
     method public void onPause();
     method public void onResume();
     method public deprecated boolean overlayHorizontalScrollbar();
@@ -48985,7 +48984,6 @@
     method public void setNetworkAvailable(boolean);
     method public deprecated void setPictureListener(android.webkit.WebView.PictureListener);
     method public void setRendererPriorityPolicy(int, boolean);
-    method public void setTextClassifier(android.view.textclassifier.TextClassifier);
     method public deprecated void setVerticalScrollbarOverlay(boolean);
     method public void setWebChromeClient(android.webkit.WebChromeClient);
     method public static void setWebContentsDebuggingEnabled(boolean);
@@ -52130,15 +52128,15 @@
     ctor public DexClassLoader(java.lang.String, java.lang.String, java.lang.String, java.lang.ClassLoader);
   }
 
-  public final class DexFile {
-    ctor public DexFile(java.io.File) throws java.io.IOException;
-    ctor public DexFile(java.lang.String) throws java.io.IOException;
+  public final deprecated class DexFile {
+    ctor public deprecated DexFile(java.io.File) throws java.io.IOException;
+    ctor public deprecated DexFile(java.lang.String) throws java.io.IOException;
     method public void close() throws java.io.IOException;
     method public java.util.Enumeration<java.lang.String> entries();
     method public java.lang.String getName();
     method public static boolean isDexOptNeeded(java.lang.String) throws java.io.FileNotFoundException, java.io.IOException;
     method public java.lang.Class loadClass(java.lang.String, java.lang.ClassLoader);
-    method public static dalvik.system.DexFile loadDex(java.lang.String, java.lang.String, int) throws java.io.IOException;
+    method public static deprecated dalvik.system.DexFile loadDex(java.lang.String, java.lang.String, int) throws java.io.IOException;
   }
 
   public final class InMemoryDexClassLoader extends dalvik.system.BaseDexClassLoader {
diff --git a/api/system-current.txt b/api/system-current.txt
index 066e393..5ddb641 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -3815,7 +3815,6 @@
     method public void onLowMemory();
     method public boolean onMenuItemSelected(int, android.view.MenuItem);
     method public boolean onMenuOpened(int, android.view.Menu);
-    method public void onMovedToDisplay(int, android.content.res.Configuration);
     method public void onMultiWindowModeChanged(boolean, android.content.res.Configuration);
     method public deprecated void onMultiWindowModeChanged(boolean);
     method public boolean onNavigateUp();
@@ -4093,7 +4092,7 @@
     field public static final int IMPORTANCE_FOREGROUND_SERVICE = 125; // 0x7d
     field public static final int IMPORTANCE_GONE = 1000; // 0x3e8
     field public static final int IMPORTANCE_PERCEPTIBLE = 230; // 0xe6
-    field public static final deprecated int IMPORTANCE_PERCEPTIBLE_DEPRECATED = 130; // 0x82
+    field public static final int IMPORTANCE_PERCEPTIBLE_PRE_26 = 130; // 0x82
     field public static final int IMPORTANCE_SERVICE = 300; // 0x12c
     field public static final int IMPORTANCE_TOP_SLEEPING = 150; // 0x96
     field public static final int IMPORTANCE_VISIBLE = 200; // 0xc8
@@ -4180,6 +4179,7 @@
     method public static android.app.ActivityOptions makeTaskLaunchBehind();
     method public static android.app.ActivityOptions makeThumbnailScaleUpAnimation(android.view.View, android.graphics.Bitmap, int, int);
     method public void requestUsageTimeReport(android.app.PendingIntent);
+    method public android.app.ActivityOptions setAppVerificationBundle(android.os.Bundle);
     method public android.app.ActivityOptions setLaunchBounds(android.graphics.Rect);
     method public android.app.ActivityOptions setLaunchDisplayId(int);
     method public android.os.Bundle toBundle();
@@ -5022,7 +5022,6 @@
     method public abstract android.app.FragmentTransaction remove(android.app.Fragment);
     method public abstract android.app.FragmentTransaction replace(int, android.app.Fragment);
     method public abstract android.app.FragmentTransaction replace(int, android.app.Fragment, java.lang.String);
-    method public abstract android.app.FragmentTransaction setAllowOptimization(boolean);
     method public abstract android.app.FragmentTransaction setBreadCrumbShortTitle(int);
     method public abstract android.app.FragmentTransaction setBreadCrumbShortTitle(java.lang.CharSequence);
     method public abstract android.app.FragmentTransaction setBreadCrumbTitle(int);
@@ -5030,6 +5029,7 @@
     method public abstract android.app.FragmentTransaction setCustomAnimations(int, int);
     method public abstract android.app.FragmentTransaction setCustomAnimations(int, int, int, int);
     method public abstract android.app.FragmentTransaction setPrimaryNavigationFragment(android.app.Fragment);
+    method public abstract android.app.FragmentTransaction setReorderingAllowed(boolean);
     method public abstract android.app.FragmentTransaction setTransition(int);
     method public abstract android.app.FragmentTransaction setTransitionStyle(int);
     method public abstract android.app.FragmentTransaction show(android.app.Fragment);
@@ -5135,7 +5135,7 @@
     method public final android.app.Activity getLastActivity();
     method public final android.app.Instrumentation.ActivityResult getResult();
     method public final boolean isBlocking();
-    method public android.app.Instrumentation.ActivityResult onMatchIntent(android.content.Intent);
+    method public android.app.Instrumentation.ActivityResult onStartActivity(android.content.Intent);
     method public final android.app.Activity waitForActivity();
     method public final android.app.Activity waitForActivityWithTimeout(long);
   }
@@ -6420,7 +6420,7 @@
 package android.app.admin {
 
   public final class ConnectEvent extends android.app.admin.NetworkEvent implements android.os.Parcelable {
-    method public java.lang.String getIpAddress();
+    method public java.net.InetAddress getInetAddress();
     method public int getPort();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.app.admin.ConnectEvent> CREATOR;
@@ -6797,8 +6797,8 @@
 
   public final class DnsEvent extends android.app.admin.NetworkEvent implements android.os.Parcelable {
     method public java.lang.String getHostname();
-    method public java.lang.String[] getIpAddresses();
-    method public int getIpAddressesCount();
+    method public java.net.InetAddress[] getInetAddresses();
+    method public int getTotalResolvedAddressCount();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.app.admin.DnsEvent> CREATOR;
   }
@@ -49194,7 +49194,6 @@
     method public boolean onKeyUp(int, android.view.KeyEvent);
     method protected void onLayout(boolean, int, int, int, int);
     method protected void onMeasure(int, int);
-    method public void onMovedToDisplay(int, android.content.res.Configuration);
     method protected void onOverScrolled(int, int, boolean, boolean);
     method public void onPointerCaptureChange(boolean);
     method public void onPopulateAccessibilityEvent(android.view.accessibility.AccessibilityEvent);
@@ -52618,7 +52617,6 @@
     method public int getRendererRequestedPriority();
     method public deprecated float getScale();
     method public android.webkit.WebSettings getSettings();
-    method public android.view.textclassifier.TextClassifier getTextClassifier();
     method public java.lang.String getTitle();
     method public java.lang.String getUrl();
     method public android.webkit.WebChromeClient getWebChromeClient();
@@ -52636,6 +52634,7 @@
     method public deprecated void onChildViewAdded(android.view.View, android.view.View);
     method public deprecated void onChildViewRemoved(android.view.View, android.view.View);
     method public deprecated void onGlobalFocusChanged(android.view.View, android.view.View);
+    method public void onMovedToDisplay(int, android.content.res.Configuration);
     method public void onPause();
     method public void onResume();
     method public deprecated boolean overlayHorizontalScrollbar();
@@ -52666,7 +52665,6 @@
     method public void setNetworkAvailable(boolean);
     method public deprecated void setPictureListener(android.webkit.WebView.PictureListener);
     method public void setRendererPriorityPolicy(int, boolean);
-    method public void setTextClassifier(android.view.textclassifier.TextClassifier);
     method public deprecated void setVerticalScrollbarOverlay(boolean);
     method public void setWebChromeClient(android.webkit.WebChromeClient);
     method public static void setWebContentsDebuggingEnabled(boolean);
@@ -56082,15 +56080,15 @@
     ctor public DexClassLoader(java.lang.String, java.lang.String, java.lang.String, java.lang.ClassLoader);
   }
 
-  public final class DexFile {
-    ctor public DexFile(java.io.File) throws java.io.IOException;
-    ctor public DexFile(java.lang.String) throws java.io.IOException;
+  public final deprecated class DexFile {
+    ctor public deprecated DexFile(java.io.File) throws java.io.IOException;
+    ctor public deprecated DexFile(java.lang.String) throws java.io.IOException;
     method public void close() throws java.io.IOException;
     method public java.util.Enumeration<java.lang.String> entries();
     method public java.lang.String getName();
     method public static boolean isDexOptNeeded(java.lang.String) throws java.io.FileNotFoundException, java.io.IOException;
     method public java.lang.Class loadClass(java.lang.String, java.lang.ClassLoader);
-    method public static dalvik.system.DexFile loadDex(java.lang.String, java.lang.String, int) throws java.io.IOException;
+    method public static deprecated dalvik.system.DexFile loadDex(java.lang.String, java.lang.String, int) throws java.io.IOException;
   }
 
   public final class InMemoryDexClassLoader extends dalvik.system.BaseDexClassLoader {
diff --git a/api/test-current.txt b/api/test-current.txt
index 38c65f2..9439e38 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -3684,7 +3684,6 @@
     method public void onLowMemory();
     method public boolean onMenuItemSelected(int, android.view.MenuItem);
     method public boolean onMenuOpened(int, android.view.Menu);
-    method public void onMovedToDisplay(int, android.content.res.Configuration);
     method public void onMultiWindowModeChanged(boolean, android.content.res.Configuration);
     method public deprecated void onMultiWindowModeChanged(boolean);
     method public boolean onNavigateUp();
@@ -3954,7 +3953,7 @@
     field public static final int IMPORTANCE_FOREGROUND_SERVICE = 125; // 0x7d
     field public static final int IMPORTANCE_GONE = 1000; // 0x3e8
     field public static final int IMPORTANCE_PERCEPTIBLE = 230; // 0xe6
-    field public static final deprecated int IMPORTANCE_PERCEPTIBLE_DEPRECATED = 130; // 0x82
+    field public static final int IMPORTANCE_PERCEPTIBLE_PRE_26 = 130; // 0x82
     field public static final int IMPORTANCE_SERVICE = 300; // 0x12c
     field public static final int IMPORTANCE_TOP_SLEEPING = 150; // 0x96
     field public static final int IMPORTANCE_VISIBLE = 200; // 0xc8
@@ -4041,6 +4040,7 @@
     method public static android.app.ActivityOptions makeTaskLaunchBehind();
     method public static android.app.ActivityOptions makeThumbnailScaleUpAnimation(android.view.View, android.graphics.Bitmap, int, int);
     method public void requestUsageTimeReport(android.app.PendingIntent);
+    method public android.app.ActivityOptions setAppVerificationBundle(android.os.Bundle);
     method public android.app.ActivityOptions setLaunchBounds(android.graphics.Rect);
     method public android.app.ActivityOptions setLaunchDisplayId(int);
     method public void setLaunchStackId(int);
@@ -4867,7 +4867,6 @@
     method public abstract android.app.FragmentTransaction remove(android.app.Fragment);
     method public abstract android.app.FragmentTransaction replace(int, android.app.Fragment);
     method public abstract android.app.FragmentTransaction replace(int, android.app.Fragment, java.lang.String);
-    method public abstract android.app.FragmentTransaction setAllowOptimization(boolean);
     method public abstract android.app.FragmentTransaction setBreadCrumbShortTitle(int);
     method public abstract android.app.FragmentTransaction setBreadCrumbShortTitle(java.lang.CharSequence);
     method public abstract android.app.FragmentTransaction setBreadCrumbTitle(int);
@@ -4875,6 +4874,7 @@
     method public abstract android.app.FragmentTransaction setCustomAnimations(int, int);
     method public abstract android.app.FragmentTransaction setCustomAnimations(int, int, int, int);
     method public abstract android.app.FragmentTransaction setPrimaryNavigationFragment(android.app.Fragment);
+    method public abstract android.app.FragmentTransaction setReorderingAllowed(boolean);
     method public abstract android.app.FragmentTransaction setTransition(int);
     method public abstract android.app.FragmentTransaction setTransitionStyle(int);
     method public abstract android.app.FragmentTransaction show(android.app.Fragment);
@@ -4968,7 +4968,7 @@
     method public final android.app.Activity getLastActivity();
     method public final android.app.Instrumentation.ActivityResult getResult();
     method public final boolean isBlocking();
-    method public android.app.Instrumentation.ActivityResult onMatchIntent(android.content.Intent);
+    method public android.app.Instrumentation.ActivityResult onStartActivity(android.content.Intent);
     method public final android.app.Activity waitForActivity();
     method public final android.app.Activity waitForActivityWithTimeout(long);
   }
@@ -6226,7 +6226,7 @@
 package android.app.admin {
 
   public final class ConnectEvent extends android.app.admin.NetworkEvent implements android.os.Parcelable {
-    method public java.lang.String getIpAddress();
+    method public java.net.InetAddress getInetAddress();
     method public int getPort();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.app.admin.ConnectEvent> CREATOR;
@@ -6579,8 +6579,8 @@
 
   public final class DnsEvent extends android.app.admin.NetworkEvent implements android.os.Parcelable {
     method public java.lang.String getHostname();
-    method public java.lang.String[] getIpAddresses();
-    method public int getIpAddressesCount();
+    method public java.net.InetAddress[] getInetAddresses();
+    method public int getTotalResolvedAddressCount();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.app.admin.DnsEvent> CREATOR;
   }
@@ -45978,7 +45978,6 @@
     method public boolean onKeyUp(int, android.view.KeyEvent);
     method protected void onLayout(boolean, int, int, int, int);
     method protected void onMeasure(int, int);
-    method public void onMovedToDisplay(int, android.content.res.Configuration);
     method protected void onOverScrolled(int, int, boolean, boolean);
     method public void onPointerCaptureChange(boolean);
     method public void onPopulateAccessibilityEvent(android.view.accessibility.AccessibilityEvent);
@@ -49317,7 +49316,6 @@
     method public int getRendererRequestedPriority();
     method public deprecated float getScale();
     method public android.webkit.WebSettings getSettings();
-    method public android.view.textclassifier.TextClassifier getTextClassifier();
     method public java.lang.String getTitle();
     method public java.lang.String getUrl();
     method public android.webkit.WebChromeClient getWebChromeClient();
@@ -49334,6 +49332,7 @@
     method public deprecated void onChildViewAdded(android.view.View, android.view.View);
     method public deprecated void onChildViewRemoved(android.view.View, android.view.View);
     method public deprecated void onGlobalFocusChanged(android.view.View, android.view.View);
+    method public void onMovedToDisplay(int, android.content.res.Configuration);
     method public void onPause();
     method public void onResume();
     method public deprecated boolean overlayHorizontalScrollbar();
@@ -49364,7 +49363,6 @@
     method public void setNetworkAvailable(boolean);
     method public deprecated void setPictureListener(android.webkit.WebView.PictureListener);
     method public void setRendererPriorityPolicy(int, boolean);
-    method public void setTextClassifier(android.view.textclassifier.TextClassifier);
     method public deprecated void setVerticalScrollbarOverlay(boolean);
     method public void setWebChromeClient(android.webkit.WebChromeClient);
     method public static void setWebContentsDebuggingEnabled(boolean);
@@ -52524,15 +52522,15 @@
     ctor public DexClassLoader(java.lang.String, java.lang.String, java.lang.String, java.lang.ClassLoader);
   }
 
-  public final class DexFile {
-    ctor public DexFile(java.io.File) throws java.io.IOException;
-    ctor public DexFile(java.lang.String) throws java.io.IOException;
+  public final deprecated class DexFile {
+    ctor public deprecated DexFile(java.io.File) throws java.io.IOException;
+    ctor public deprecated DexFile(java.lang.String) throws java.io.IOException;
     method public void close() throws java.io.IOException;
     method public java.util.Enumeration<java.lang.String> entries();
     method public java.lang.String getName();
     method public static boolean isDexOptNeeded(java.lang.String) throws java.io.FileNotFoundException, java.io.IOException;
     method public java.lang.Class loadClass(java.lang.String, java.lang.ClassLoader);
-    method public static dalvik.system.DexFile loadDex(java.lang.String, java.lang.String, int) throws java.io.IOException;
+    method public static deprecated dalvik.system.DexFile loadDex(java.lang.String, java.lang.String, int) throws java.io.IOException;
   }
 
   public final class InMemoryDexClassLoader extends dalvik.system.BaseDexClassLoader {
diff --git a/core/java/android/animation/AnimatorSet.java b/core/java/android/animation/AnimatorSet.java
index cdeca13..ca4b4d5 100644
--- a/core/java/android/animation/AnimatorSet.java
+++ b/core/java/android/animation/AnimatorSet.java
@@ -930,12 +930,14 @@
     }
 
     /**
-     * Gets the current position of the animation in time, which is equal to the current
-     * time minus the time that the animation started. An animation that is not yet started will
-     * return a value of zero, unless the animation has has its play time set via
-     * {@link #setCurrentPlayTime(long)}, in which case it will return the time that was set.
+     * Returns the milliseconds elapsed since the start of the animation.
      *
-     * @return The current position in time of the animation.
+     * <p>For ongoing animations, this method returns the current progress of the animation in
+     * terms of play time. For an animation that has not yet been started: if the animation has been
+     * seeked to a certain time via {@link #setCurrentPlayTime(long)}, the seeked play time will
+     * be returned; otherwise, this method will return 0.
+     *
+     * @return the current position in time of the animation in milliseconds
      */
     public long getCurrentPlayTime() {
         if (mSeekState.isActive()) {
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index e621c01..ab4f33d 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -2172,6 +2172,7 @@
      *
      * @see #onConfigurationChanged(Configuration)
      * @see View#onMovedToDisplay(int, Configuration)
+     * @hide
      */
     public void onMovedToDisplay(int displayId, Configuration config) {
     }
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 6e7b750..2230472 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -3143,10 +3143,15 @@
          * before {@link Build.VERSION_CODES#O}.  Since the {@link Build.VERSION_CODES#O} SDK,
          * the value of {@link #IMPORTANCE_PERCEPTIBLE} has been fixed.
          *
-         * @deprecated Use {@link #IMPORTANCE_PERCEPTIBLE} instead.
+         * <p>The system will return this value instead of {@link #IMPORTANCE_PERCEPTIBLE}
+         * on Android versions below {@link Build.VERSION_CODES#O}.
+         *
+         * <p>On Android version {@link Build.VERSION_CODES#O} and later, this value will still be
+         * returned for apps with the target API level below {@link Build.VERSION_CODES#O}.
+         * For apps targeting version {@link Build.VERSION_CODES#O} and later,
+         * the correct value {@link #IMPORTANCE_PERCEPTIBLE} will be returned.
          */
-        @Deprecated
-        public static final int IMPORTANCE_PERCEPTIBLE_DEPRECATED = 130;
+        public static final int IMPORTANCE_PERCEPTIBLE_PRE_26 = 130;
 
         /**
          * Constant for {@link #importance}: This process is not something the user
@@ -3160,11 +3165,17 @@
          * before {@link Build.VERSION_CODES#O}.  Since the {@link Build.VERSION_CODES#O} SDK,
          * the value of {@link #IMPORTANCE_CANT_SAVE_STATE} has been fixed.
          *
-         * @deprecated Use {@link #IMPORTANCE_CANT_SAVE_STATE} instead.
+         * <p>The system will return this value instead of {@link #IMPORTANCE_CANT_SAVE_STATE}
+         * on Android versions below {@link Build.VERSION_CODES#O}.
+         *
+         * <p>On Android version {@link Build.VERSION_CODES#O} after, this value will still be
+         * returned for apps with the target API level below {@link Build.VERSION_CODES#O}.
+         * For apps targeting version {@link Build.VERSION_CODES#O} and later,
+         * the correct value {@link #IMPORTANCE_CANT_SAVE_STATE} will be returned.
+         *
          * @hide
          */
-        @Deprecated
-        public static final int IMPORTANCE_CANT_SAVE_STATE_DEPRECATED = 170;
+        public static final int IMPORTANCE_CANT_SAVE_STATE_PRE_26 = 170;
 
         /**
          * Constant for {@link #importance}: This process is running an
@@ -3244,15 +3255,25 @@
          */
         public static @Importance int procStateToImportanceForClient(int procState,
                 Context clientContext) {
+            return procStateToImportanceForTargetSdk(procState,
+                    clientContext.getApplicationInfo().targetSdkVersion);
+        }
+
+        /**
+         * See {@link #procStateToImportanceForClient}.
+         * @hide
+         */
+        public static @Importance int procStateToImportanceForTargetSdk(int procState,
+                int targetSdkVersion) {
             final int importance = procStateToImportance(procState);
 
             // For pre O apps, convert to the old, wrong values.
-            if (clientContext.getApplicationInfo().targetSdkVersion < VERSION_CODES.O) {
+            if (targetSdkVersion < VERSION_CODES.O) {
                 switch (importance) {
                     case IMPORTANCE_PERCEPTIBLE:
-                        return IMPORTANCE_PERCEPTIBLE_DEPRECATED;
+                        return IMPORTANCE_PERCEPTIBLE_PRE_26;
                     case IMPORTANCE_CANT_SAVE_STATE:
-                        return IMPORTANCE_CANT_SAVE_STATE_DEPRECATED;
+                        return IMPORTANCE_CANT_SAVE_STATE_PRE_26;
                 }
             }
             return importance;
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java
index 63e8cc6..3eec596 100644
--- a/core/java/android/app/ActivityOptions.java
+++ b/core/java/android/app/ActivityOptions.java
@@ -211,6 +211,9 @@
     private static final String KEY_USAGE_TIME_REPORT = "android:activity.usageTimeReport";
     private static final String KEY_ROTATION_ANIMATION_HINT = "android:activity.rotationAnimationHint";
 
+    private static final String KEY_INSTANT_APP_VERIFICATION_BUNDLE
+            = "android:instantapps.installerbundle";
+
     /** @hide */
     public static final int ANIM_NONE = 0;
     /** @hide */
@@ -264,6 +267,7 @@
     private boolean mTaskOverlayCanResume;
     private AppTransitionAnimationSpec mAnimSpecs[];
     private int mRotationAnimationHint = -1;
+    private Bundle mAppVerificationBundle;
 
     /**
      * Create an ActivityOptions specifying a custom animation to run when
@@ -886,6 +890,7 @@
                     opts.getBinder(KEY_ANIMATION_FINISHED_LISTENER));
         }
         mRotationAnimationHint = opts.getInt(KEY_ROTATION_ANIMATION_HINT);
+        mAppVerificationBundle = opts.getBundle(KEY_INSTANT_APP_VERIFICATION_BUNDLE);
     }
 
     /**
@@ -1275,6 +1280,9 @@
             b.putBinder(KEY_ANIMATION_FINISHED_LISTENER, mAnimationFinishedListener.asBinder());
         }
         b.putInt(KEY_ROTATION_ANIMATION_HINT, mRotationAnimationHint);
+        if (mAppVerificationBundle != null) {
+            b.putBundle(KEY_INSTANT_APP_VERIFICATION_BUNDLE, mAppVerificationBundle);
+        }
 
         return b;
     }
@@ -1342,6 +1350,30 @@
         mRotationAnimationHint = hint;
     }
 
+    /**
+     * Pop the extra verification bundle for the installer.
+     * This removes the bundle from the ActivityOptions to make sure the installer bundle
+     * is only available once.
+     * @hide
+     */
+    public Bundle popAppVerificationBundle() {
+        Bundle out = mAppVerificationBundle;
+        mAppVerificationBundle = null;
+        return out;
+    }
+
+    /**
+     * Set the {@link Bundle} that is provided to the app installer for additional verification
+     * if the call to {@link Context#startActivity} results in an app being installed.
+     *
+     * This Bundle is not provided to any other app besides the installer.
+     */
+    public ActivityOptions setAppVerificationBundle(Bundle bundle) {
+        mAppVerificationBundle = bundle;
+        return this;
+
+    }
+
     /** @hide */
     @Override
     public String toString() {
diff --git a/core/java/android/app/BackStackRecord.java b/core/java/android/app/BackStackRecord.java
index cf274b4..65c5b4f 100644
--- a/core/java/android/app/BackStackRecord.java
+++ b/core/java/android/app/BackStackRecord.java
@@ -16,8 +16,6 @@
 
 package android.app;
 
-import android.content.Context;
-import android.content.pm.ApplicationInfo;
 import android.os.Build;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -45,7 +43,7 @@
     final CharSequence mBreadCrumbShortTitleText;
     final ArrayList<String> mSharedElementSourceNames;
     final ArrayList<String> mSharedElementTargetNames;
-    final boolean mAllowOptimization;
+    final boolean mReorderingAllowed;
 
     public BackStackState(FragmentManagerImpl fm, BackStackRecord bse) {
         final int numOps = bse.mOps.size();
@@ -75,7 +73,7 @@
         mBreadCrumbShortTitleText = bse.mBreadCrumbShortTitleText;
         mSharedElementSourceNames = bse.mSharedElementSourceNames;
         mSharedElementTargetNames = bse.mSharedElementTargetNames;
-        mAllowOptimization = bse.mAllowOptimization;
+        mReorderingAllowed = bse.mReorderingAllowed;
     }
 
     public BackStackState(Parcel in) {
@@ -90,7 +88,7 @@
         mBreadCrumbShortTitleText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
         mSharedElementSourceNames = in.createStringArrayList();
         mSharedElementTargetNames = in.createStringArrayList();
-        mAllowOptimization = in.readInt() != 0;
+        mReorderingAllowed = in.readInt() != 0;
     }
 
     public BackStackRecord instantiate(FragmentManagerImpl fm) {
@@ -133,7 +131,7 @@
         bse.mBreadCrumbShortTitleText = mBreadCrumbShortTitleText;
         bse.mSharedElementSourceNames = mSharedElementSourceNames;
         bse.mSharedElementTargetNames = mSharedElementTargetNames;
-        bse.mAllowOptimization = mAllowOptimization;
+        bse.mReorderingAllowed = mReorderingAllowed;
         bse.bumpBackStackNesting(1);
         return bse;
     }
@@ -154,7 +152,7 @@
         TextUtils.writeToParcel(mBreadCrumbShortTitleText, dest, 0);
         dest.writeStringList(mSharedElementSourceNames);
         dest.writeStringList(mSharedElementTargetNames);
-        dest.writeInt(mAllowOptimization ? 1 : 0);
+        dest.writeInt(mReorderingAllowed ? 1 : 0);
     }
 
     public static final Parcelable.Creator<BackStackState> CREATOR
@@ -218,7 +216,7 @@
     String mName;
     boolean mCommitted;
     int mIndex = -1;
-    boolean mAllowOptimization;
+    boolean mReorderingAllowed;
 
     ArrayList<Runnable> mCommitRunnables;
 
@@ -370,7 +368,7 @@
 
     public BackStackRecord(FragmentManagerImpl manager) {
         mManager = manager;
-        mAllowOptimization = mManager.getTargetSdk() > Build.VERSION_CODES.N_MR1;
+        mReorderingAllowed = mManager.getTargetSdk() > Build.VERSION_CODES.N_MR1;
     }
 
     public int getId() {
@@ -665,8 +663,8 @@
     }
 
     @Override
-    public FragmentTransaction setAllowOptimization(boolean allowOptimization) {
-        mAllowOptimization = allowOptimization;
+    public FragmentTransaction setReorderingAllowed(boolean reorderingAllowed) {
+        mReorderingAllowed = reorderingAllowed;
         return this;
     }
 
@@ -800,11 +798,11 @@
                 default:
                     throw new IllegalArgumentException("Unknown cmd: " + op.cmd);
             }
-            if (!mAllowOptimization && op.cmd != OP_ADD && f != null) {
+            if (!mReorderingAllowed && op.cmd != OP_ADD && f != null) {
                 mManager.moveFragmentToExpectedState(f);
             }
         }
-        if (!mAllowOptimization) {
+        if (!mReorderingAllowed) {
             // Added fragments are added at the end to comply with prior behavior.
             mManager.moveToState(mManager.mCurState, true);
         }
@@ -859,11 +857,11 @@
                 default:
                     throw new IllegalArgumentException("Unknown cmd: " + op.cmd);
             }
-            if (!mAllowOptimization && op.cmd != OP_REMOVE && f != null) {
+            if (!mReorderingAllowed && op.cmd != OP_REMOVE && f != null) {
                 mManager.moveFragmentToExpectedState(f);
             }
         }
-        if (!mAllowOptimization && moveToState) {
+        if (!mReorderingAllowed && moveToState) {
             mManager.moveToState(mManager.mCurState, true);
         }
     }
diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java
index 759efdb..c2fd007 100644
--- a/core/java/android/app/Fragment.java
+++ b/core/java/android/app/Fragment.java
@@ -2417,7 +2417,7 @@
      * enabled.
      *
      * @see Activity#postponeEnterTransition()
-     * @see FragmentTransaction#setAllowOptimization(boolean)
+     * @see FragmentTransaction#setReorderingAllowed(boolean)
      */
     public void postponeEnterTransition() {
         ensureAnimationInfo().mEnterTransitionPostponed = true;
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index 9e8809a..fdd1b7e 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -54,7 +54,6 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
 import java.util.concurrent.CopyOnWriteArrayList;
@@ -682,7 +681,7 @@
     String mNoTransactionsBecause;
     boolean mHavePendingDeferredStart;
 
-    // Temporary vars for optimizing execution of BackStackRecords:
+    // Temporary vars for removing redundant operations in BackStackRecords:
     ArrayList<BackStackRecord> mTmpRecords;
     ArrayList<Boolean> mTmpIsPop;
     ArrayList<Fragment> mTmpAddedFragments;
@@ -853,7 +852,7 @@
         if (executePop) {
             mExecutingActions = true;
             try {
-                optimizeAndExecuteOps(mTmpRecords, mTmpIsPop);
+                removeRedundantOperationsAndExecute(mTmpRecords, mTmpIsPop);
             } finally {
                 cleanupExec();
             }
@@ -2002,7 +2001,7 @@
         if (action.generateOps(mTmpRecords, mTmpIsPop)) {
             mExecutingActions = true;
             try {
-                optimizeAndExecuteOps(mTmpRecords, mTmpIsPop);
+                removeRedundantOperationsAndExecute(mTmpRecords, mTmpIsPop);
             } finally {
                 cleanupExec();
             }
@@ -2032,7 +2031,7 @@
         while (generateOpsForPendingActions(mTmpRecords, mTmpIsPop)) {
             mExecutingActions = true;
             try {
-                optimizeAndExecuteOps(mTmpRecords, mTmpIsPop);
+                removeRedundantOperationsAndExecute(mTmpRecords, mTmpIsPop);
             } finally {
                 cleanupExec();
             }
@@ -2080,19 +2079,20 @@
     }
 
     /**
-     * Optimizes BackStackRecord operations. This method merges operations of proximate records
-     * that allow optimization. See {@link FragmentTransaction#setAllowOptimization(boolean)}.
+     * Remove redundant BackStackRecord operations and executes them. This method merges operations
+     * of proximate records that allow reordering. See
+     * {@link FragmentTransaction#setReorderingAllowed(boolean)}.
      * <p>
      * For example, a transaction that adds to the back stack and then another that pops that
-     * back stack record will be optimized.
+     * back stack record will be optimized to remove the unnecessary operation.
      * <p>
      * Likewise, two transactions committed that are executed at the same time will be optimized
-     * as well as two pop operations executed together.
+     * to remove the redundant operations as well as two pop operations executed together.
      *
      * @param records The records pending execution
      * @param isRecordPop The direction that these records are being run.
      */
-    private void optimizeAndExecuteOps(ArrayList<BackStackRecord> records,
+    private void removeRedundantOperationsAndExecute(ArrayList<BackStackRecord> records,
             ArrayList<Boolean> isRecordPop) {
         if (records == null || records.isEmpty()) {
             return;
@@ -2108,24 +2108,25 @@
         final int numRecords = records.size();
         int startIndex = 0;
         for (int recordNum = 0; recordNum < numRecords; recordNum++) {
-            final boolean canOptimize = records.get(recordNum).mAllowOptimization;
-            if (!canOptimize) {
+            final boolean canReorder = records.get(recordNum).mReorderingAllowed;
+            if (!canReorder) {
                 // execute all previous transactions
                 if (startIndex != recordNum) {
                     executeOpsTogether(records, isRecordPop, startIndex, recordNum);
                 }
-                // execute all unoptimized pop operations together or one add operation
-                int optimizeEnd = recordNum + 1;
+                // execute all pop operations that don't allow reordering together or
+                // one add operation
+                int reorderingEnd = recordNum + 1;
                 if (isRecordPop.get(recordNum)) {
-                    while (optimizeEnd < numRecords
-                            && isRecordPop.get(optimizeEnd)
-                            && !records.get(optimizeEnd).mAllowOptimization) {
-                        optimizeEnd++;
+                    while (reorderingEnd < numRecords
+                            && isRecordPop.get(reorderingEnd)
+                            && !records.get(reorderingEnd).mReorderingAllowed) {
+                        reorderingEnd++;
                     }
                 }
-                executeOpsTogether(records, isRecordPop, recordNum, optimizeEnd);
-                startIndex = optimizeEnd;
-                recordNum = optimizeEnd - 1;
+                executeOpsTogether(records, isRecordPop, recordNum, reorderingEnd);
+                startIndex = reorderingEnd;
+                recordNum = reorderingEnd - 1;
             }
         }
         if (startIndex != numRecords) {
@@ -2134,16 +2135,16 @@
     }
 
     /**
-     * Optimizes a subset of a list of BackStackRecords, all of which either allow optimization or
-     * do not allow optimization.
-     * @param records A list of BackStackRecords that are to be optimized
+     * Executes a subset of a list of BackStackRecords, all of which either allow reordering or
+     * do not allow ordering.
+     * @param records A list of BackStackRecords that are to be executed together
      * @param isRecordPop The direction that these records are being run.
-     * @param startIndex The index of the first record in <code>records</code> to be optimized
-     * @param endIndex One more than the final record index in <code>records</code> to optimize.
+     * @param startIndex The index of the first record in <code>records</code> to be executed
+     * @param endIndex One more than the final record index in <code>records</code> to executed.
      */
     private void executeOpsTogether(ArrayList<BackStackRecord> records,
             ArrayList<Boolean> isRecordPop, int startIndex, int endIndex) {
-        final boolean allowOptimization = records.get(startIndex).mAllowOptimization;
+        final boolean allowReordering = records.get(startIndex).mReorderingAllowed;
         boolean addToBackStack = false;
         if (mTmpAddedFragments == null) {
             mTmpAddedFragments = new ArrayList<>();
@@ -2166,14 +2167,14 @@
         }
         mTmpAddedFragments.clear();
 
-        if (!allowOptimization) {
+        if (!allowReordering) {
             FragmentTransition.startTransitions(this, records, isRecordPop, startIndex, endIndex,
                     false);
         }
         executeOps(records, isRecordPop, startIndex, endIndex);
 
         int postponeIndex = endIndex;
-        if (allowOptimization) {
+        if (allowReordering) {
             ArraySet<Fragment> addedFragments = new ArraySet<>();
             addAddedFragments(addedFragments);
             postponeIndex = postponePostponableTransactions(records, isRecordPop,
@@ -2181,7 +2182,7 @@
             makeRemovedFragmentsInvisible(addedFragments);
         }
 
-        if (postponeIndex != startIndex && allowOptimization) {
+        if (postponeIndex != startIndex && allowReordering) {
             // need to run something now
             FragmentTransition.startTransitions(this, records, isRecordPop, startIndex,
                     postponeIndex, true);
diff --git a/core/java/android/app/FragmentTransaction.java b/core/java/android/app/FragmentTransaction.java
index c938aa6..a0e5a4e 100644
--- a/core/java/android/app/FragmentTransaction.java
+++ b/core/java/android/app/FragmentTransaction.java
@@ -6,6 +6,7 @@
 import android.annotation.Nullable;
 import android.annotation.StringRes;
 import android.annotation.StyleRes;
+import android.os.Bundle;
 import android.view.View;
 
 import java.lang.annotation.Retention;
@@ -279,33 +280,37 @@
 
     /**
      * Sets whether or not to allow optimizing operations within and across
-     * transactions. Optimizing fragment transaction's operations can eliminate
+     * transactions. This will remove redundant operations, eliminating
      * operations that cancel. For example, if two transactions are executed
      * together, one that adds a fragment A and the next replaces it with fragment B,
      * the operations will cancel and only fragment B will be added. That means that
      * fragment A may not go through the creation/destruction lifecycle.
      * <p>
-     * The side effect of optimization is that fragments may have state changes
+     * The side effect of removing redundant operations is that fragments may have state changes
      * out of the expected order. For example, one transaction adds fragment A,
-     * a second adds fragment B, then a third removes fragment A. Without optimization,
-     * fragment B could expect that while it is being created, fragment A will also
+     * a second adds fragment B, then a third removes fragment A. Without removing the redundant
+     * operations, fragment B could expect that while it is being created, fragment A will also
      * exist because fragment A will be removed after fragment B was added.
-     * With optimization, fragment B cannot expect fragment A to exist when
+     * With removing redundant operations, fragment B cannot expect fragment A to exist when
      * it has been created because fragment A's add/remove will be optimized out.
      * <p>
+     * It can also reorder the state changes of Fragments to allow for better Transitions.
+     * Added Fragments may have {@link Fragment#onCreate(Bundle)} called before replaced
+     * Fragments have {@link Fragment#onDestroy()} called.
+     * <p>
      * The default is {@code false} for applications targeting version
      * versions prior to O and {@code true} for applications targeting O and
      * later.
      *
-     * @param allowOptimization {@code true} to enable optimizing operations
-     *                          or {@code false} to disable optimizing
+     * @param reorderingAllowed {@code true} to enable optimizing out redundant operations
+     *                          or {@code false} to disable optimizing out redundant
      *                          operations on this transaction.
      */
-    public abstract FragmentTransaction setAllowOptimization(boolean allowOptimization);
+    public abstract FragmentTransaction setReorderingAllowed(boolean reorderingAllowed);
 
     /**
      * Add a Runnable to this transaction that will be run after this transaction has
-     * been committed. If fragment transactions are {@link #setAllowOptimization(boolean) optimized}
+     * been committed. If fragment transactions are {@link #setReorderingAllowed(boolean) optimized}
      * this may be after other subsequent fragment operations have also taken place, or operations
      * in this transaction may have been optimized out due to the presence of a subsequent
      * fragment transaction in the batch.
diff --git a/core/java/android/app/FragmentTransition.java b/core/java/android/app/FragmentTransition.java
index b4c6dce..ceb828b 100644
--- a/core/java/android/app/FragmentTransition.java
+++ b/core/java/android/app/FragmentTransition.java
@@ -34,9 +34,10 @@
 import java.util.Map;
 
 /**
- * Contains the Fragment Transition functionality for both optimized and unoptimized
- * Fragment Transactions. With optimized fragment transactions, all Views have been
- * added to the View hierarchy prior to calling startTransitions. With
+ * Contains the Fragment Transition functionality for both ordered and reordered
+ * Fragment Transactions. With reordered fragment transactions, all Views have been
+ * added to the View hierarchy prior to calling startTransitions. With ordered
+ * fragment transactions, Views will be removed and added after calling startTransitions.
  */
 class FragmentTransition {
     /**
@@ -65,9 +66,9 @@
      * {@link Fragment#getSharedElementReturnTransition()} and the entering
      * {@link Fragment#getReenterTransition()} will be run.
      * <p>
-     * With optimized Fragment Transitions, all Views have been added to the
+     * With reordered Fragment Transitions, all Views have been added to the
      * View hierarchy prior to calling this method. The incoming Fragment's Views
-     * will be INVISIBLE. With unoptimized Fragment Transitions, this method
+     * will be INVISIBLE. With ordered Fragment Transitions, this method
      * is called before any change has been made to the hierarchy. That means
      * that the added Fragments have not created their Views yet and the hierarchy
      * is unknown.
@@ -79,13 +80,13 @@
      *                   part of this transition.
      * @param endIndex One past the last index into records and isRecordPop to execute
      *                 as part of this transition.
-     * @param isOptimized true if this is an optimized transaction, meaning that the
+     * @param isReordered true if this is a reordered transaction, meaning that the
      *                    Views of incoming fragments have been added. false if the
      *                    transaction has yet to be run and Views haven't been created.
      */
     static void startTransitions(FragmentManagerImpl fragmentManager,
             ArrayList<BackStackRecord> records, ArrayList<Boolean> isRecordPop,
-            int startIndex, int endIndex, boolean isOptimized) {
+            int startIndex, int endIndex, boolean isReordered) {
         if (fragmentManager.mCurState < Fragment.CREATED) {
             return;
         }
@@ -95,9 +96,9 @@
             final BackStackRecord record = records.get(i);
             final boolean isPop = isRecordPop.get(i);
             if (isPop) {
-                calculatePopFragments(record, transitioningFragments, isOptimized);
+                calculatePopFragments(record, transitioningFragments, isReordered);
             } else {
-                calculateFragments(record, transitioningFragments, isOptimized);
+                calculateFragments(record, transitioningFragments, isReordered);
             }
         }
 
@@ -111,11 +112,11 @@
 
                 FragmentContainerTransition containerTransition = transitioningFragments.valueAt(i);
 
-                if (isOptimized) {
-                    configureTransitionsOptimized(fragmentManager, containerId,
+                if (isReordered) {
+                    configureTransitionsReordered(fragmentManager, containerId,
                             containerTransition, nonExistentView, nameOverrides);
                 } else {
-                    configureTransitionsUnoptimized(fragmentManager, containerId,
+                    configureTransitionsOrdered(fragmentManager, containerId,
                             containerTransition, nonExistentView, nameOverrides);
                 }
             }
@@ -175,7 +176,7 @@
 
     /**
      * Configures a transition for a single fragment container for which the transaction was
-     * optimized. That means that all Fragment Views have been added and incoming fragment
+     * reordered. That means that all Fragment Views have been added and incoming fragment
      * Views are marked invisible.
      *
      * @param fragmentManager The executing FragmentManagerImpl
@@ -188,7 +189,7 @@
      *                      the final fragment's Views as given in
      *                      {@link FragmentTransaction#addSharedElement(View, String)}.
      */
-    private static void configureTransitionsOptimized(FragmentManagerImpl fragmentManager,
+    private static void configureTransitionsReordered(FragmentManagerImpl fragmentManager,
             int containerId, FragmentContainerTransition fragments,
             View nonExistentView, ArrayMap<String, String> nameOverrides) {
         ViewGroup sceneRoot = null;
@@ -208,7 +209,7 @@
         Transition enterTransition = getEnterTransition(inFragment, inIsPop);
         Transition exitTransition = getExitTransition(outFragment, outIsPop);
 
-        TransitionSet sharedElementTransition = configureSharedElementsOptimized(sceneRoot,
+        TransitionSet sharedElementTransition = configureSharedElementsReordered(sceneRoot,
                 nonExistentView, nameOverrides, fragments, sharedElementsOut, sharedElementsIn,
                 enterTransition, exitTransition);
 
@@ -247,7 +248,7 @@
 
     /**
      * Configures a transition for a single fragment container for which the transaction was
-     * not optimized. That means that the transaction has not been executed yet, so incoming
+     * ordered. That means that the transaction has not been executed yet, so incoming
      * Views are not yet known.
      *
      * @param fragmentManager The executing FragmentManagerImpl
@@ -260,7 +261,7 @@
      *                      the final fragment's Views as given in
      *                      {@link FragmentTransaction#addSharedElement(View, String)}.
      */
-    private static void configureTransitionsUnoptimized(FragmentManagerImpl fragmentManager,
+    private static void configureTransitionsOrdered(FragmentManagerImpl fragmentManager,
             int containerId, FragmentContainerTransition fragments,
             View nonExistentView, ArrayMap<String, String> nameOverrides) {
         ViewGroup sceneRoot = null;
@@ -281,7 +282,7 @@
         ArrayList<View> sharedElementsOut = new ArrayList<>();
         ArrayList<View> sharedElementsIn = new ArrayList<>();
 
-        TransitionSet sharedElementTransition = configureSharedElementsUnoptimized(sceneRoot,
+        TransitionSet sharedElementTransition = configureSharedElementsOrdered(sceneRoot,
                 nonExistentView, nameOverrides, fragments, sharedElementsOut, sharedElementsIn,
                 enterTransition, exitTransition);
 
@@ -345,7 +346,7 @@
     }
 
     /**
-     * This method is used for fragment transitions for unoptimized transactions to change the
+     * This method is used for fragment transitions for ordered transactions to change the
      * enter and exit transition targets after the call to
      * {@link TransitionManager#beginDelayedTransition(ViewGroup, Transition)}. The exit transition
      * must ensure that it does not target any Views and the enter transition must start targeting
@@ -448,7 +449,7 @@
     }
 
     /**
-     * Configures the shared elements of an optimized fragment transaction's transition.
+     * Configures the shared elements of an reordered fragment transaction's transition.
      * This retrieves the shared elements of the outgoing and incoming fragments, maps the
      * views, and sets up the epicenter on the transitions.
      * <p>
@@ -474,7 +475,7 @@
      *                       epicenter
      * @return The shared element transition or null if no shared elements exist
      */
-    private static TransitionSet configureSharedElementsOptimized(final ViewGroup sceneRoot,
+    private static TransitionSet configureSharedElementsReordered(final ViewGroup sceneRoot,
             final View nonExistentView, ArrayMap<String, String> nameOverrides,
             final FragmentContainerTransition fragments,
             final ArrayList<View> sharedElementsOut,
@@ -576,7 +577,7 @@
     }
 
     /**
-     * Configures the shared elements of an unoptimized fragment transaction's transition.
+     * Configures the shared elements of an ordered fragment transaction's transition.
      * This retrieves the shared elements of the incoming fragments, and schedules capturing
      * the incoming fragment's shared elements. It also maps the views, and sets up the epicenter
      * on the transitions.
@@ -603,7 +604,7 @@
      *                       epicenter
      * @return The shared element transition or null if no shared elements exist
      */
-    private static TransitionSet configureSharedElementsUnoptimized(final ViewGroup sceneRoot,
+    private static TransitionSet configureSharedElementsOrdered(final ViewGroup sceneRoot,
             final View nonExistentView, ArrayMap<String, String> nameOverrides,
             final FragmentContainerTransition fragments,
             final ArrayList<View> sharedElementsOut,
@@ -1195,11 +1196,11 @@
      */
     public static void calculateFragments(BackStackRecord transaction,
             SparseArray<FragmentContainerTransition> transitioningFragments,
-            boolean isOptimized) {
+            boolean isReordered) {
         final int numOps = transaction.mOps.size();
         for (int opNum = 0; opNum < numOps; opNum++) {
             final BackStackRecord.Op op = transaction.mOps.get(opNum);
-            addToFirstInLastOut(transaction, op, transitioningFragments, false, isOptimized);
+            addToFirstInLastOut(transaction, op, transitioningFragments, false, isReordered);
         }
     }
 
@@ -1212,14 +1213,14 @@
      *                               this method.
      */
     public static void calculatePopFragments(BackStackRecord transaction,
-            SparseArray<FragmentContainerTransition> transitioningFragments, boolean isOptimized) {
+            SparseArray<FragmentContainerTransition> transitioningFragments, boolean isReordered) {
         if (!transaction.mManager.mContainer.onHasView()) {
             return; // nothing to see, so no transitions
         }
         final int numOps = transaction.mOps.size();
         for (int opNum = numOps - 1; opNum >= 0; opNum--) {
             final BackStackRecord.Op op = transaction.mOps.get(opNum);
-            addToFirstInLastOut(transaction, op, transitioningFragments, true, isOptimized);
+            addToFirstInLastOut(transaction, op, transitioningFragments, true, isReordered);
         }
     }
 
@@ -1232,14 +1233,14 @@
      * @param transitioningFragments A structure holding the first in and last out fragments
      *                               for each fragment container.
      * @param isPop Is the operation a pop?
-     * @param isOptimizedTransaction True if the operations have been partially executed and the
+     * @param isReorderedTransaction True if the operations have been partially executed and the
      *                               added fragments have Views in the hierarchy or false if the
      *                               operations haven't been executed yet.
      */
     @SuppressWarnings("ReferenceEquality")
     private static void addToFirstInLastOut(BackStackRecord transaction, BackStackRecord.Op op,
             SparseArray<FragmentContainerTransition> transitioningFragments, boolean isPop,
-            boolean isOptimizedTransaction) {
+            boolean isReorderedTransaction) {
         final Fragment fragment = op.fragment;
         if (fragment == null) {
             return; // no fragment, no transition
@@ -1255,7 +1256,7 @@
         boolean wasAdded = false;
         switch (command) {
             case BackStackRecord.OP_SHOW:
-                if (isOptimizedTransaction) {
+                if (isReorderedTransaction) {
                     setLastIn = fragment.mHiddenChanged && !fragment.mHidden &&
                             fragment.mAdded;
                 } else {
@@ -1265,7 +1266,7 @@
                 break;
             case BackStackRecord.OP_ADD:
             case BackStackRecord.OP_ATTACH:
-                if (isOptimizedTransaction) {
+                if (isReorderedTransaction) {
                     setLastIn = fragment.mIsNewlyAdded;
                 } else {
                     setLastIn = !fragment.mAdded && !fragment.mHidden;
@@ -1273,7 +1274,7 @@
                 wasAdded = true;
                 break;
             case BackStackRecord.OP_HIDE:
-                if (isOptimizedTransaction) {
+                if (isReorderedTransaction) {
                     setFirstOut = fragment.mHiddenChanged && fragment.mAdded &&
                             fragment.mHidden;
                 } else {
@@ -1283,7 +1284,7 @@
                 break;
             case BackStackRecord.OP_REMOVE:
             case BackStackRecord.OP_DETACH:
-                if (isOptimizedTransaction) {
+                if (isReorderedTransaction) {
                     setFirstOut = !fragment.mAdded && fragment.mView != null
                             && fragment.mView.getVisibility() == View.VISIBLE
                             && fragment.mView.getTransitionAlpha() > 0;
@@ -1301,7 +1302,7 @@
             containerTransition.lastInIsPop = isPop;
             containerTransition.lastInTransaction = transaction;
         }
-        if (!isOptimizedTransaction && wasAdded) {
+        if (!isReorderedTransaction && wasAdded) {
             if (containerTransition != null && containerTransition.firstOut == fragment) {
                 containerTransition.firstOut = null;
             }
@@ -1313,7 +1314,7 @@
             FragmentManagerImpl manager = transaction.mManager;
             if (fragment.mState < Fragment.CREATED && manager.mCurState >= Fragment.CREATED &&
                     manager.mHost.getContext().getApplicationInfo().targetSdkVersion >=
-                            Build.VERSION_CODES.N && !transaction.mAllowOptimization) {
+                            Build.VERSION_CODES.N && !transaction.mReorderingAllowed) {
                 manager.makeActive(fragment);
                 manager.moveToState(fragment, Fragment.CREATED, 0, 0, false);
             }
@@ -1326,7 +1327,7 @@
             containerTransition.firstOutTransaction = transaction;
         }
 
-        if (!isOptimizedTransaction && wasRemoved &&
+        if (!isReorderedTransaction && wasRemoved &&
                 (containerTransition != null && containerTransition.lastIn == fragment)) {
             containerTransition.lastIn = null;
         }
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
index 9377d35..69ed439 100644
--- a/core/java/android/app/Instrumentation.java
+++ b/core/java/android/app/Instrumentation.java
@@ -543,10 +543,10 @@
          * Create a new ActivityMonitor that can be used for intercepting any activity to be
          * started.
          *
-         * <p> When an activity is started, {@link #onMatchIntent(Intent)} will be called on
+         * <p> When an activity is started, {@link #onStartActivity(Intent)} will be called on
          * instances created using this constructor to see if it is a hit.
          *
-         * @see #onMatchIntent(Intent)
+         * @see #onStartActivity(Intent)
          */
         public ActivityMonitor() {
             mWhich = null;
@@ -558,7 +558,7 @@
 
         /**
          * @return true if this monitor is used for intercepting any started activity by calling
-         *         into {@link #onMatchIntent(Intent)}, false if this monitor is only used
+         *         into {@link #onStartActivity(Intent)}, false if this monitor is only used
          *         for specific intents corresponding to the intent filter or activity class
          *         passed in the constructor.
          */
@@ -665,7 +665,7 @@
          * @param intent The intent used for starting the activity.
          * @return The {@link ActivityResult} that needs to be used in case of a match.
          */
-        public ActivityResult onMatchIntent(Intent intent) {
+        public ActivityResult onStartActivity(Intent intent) {
             return null;
         }
 
@@ -1589,7 +1589,7 @@
                     final ActivityMonitor am = mActivityMonitors.get(i);
                     ActivityResult result = null;
                     if (am.ignoreMatchingSpecificIntents()) {
-                        result = am.onMatchIntent(intent);
+                        result = am.onStartActivity(intent);
                     }
                     if (result != null) {
                         am.mHits++;
@@ -1652,7 +1652,7 @@
                     final ActivityMonitor am = mActivityMonitors.get(i);
                     ActivityResult result = null;
                     if (am.ignoreMatchingSpecificIntents()) {
-                        result = am.onMatchIntent(intents[0]);
+                        result = am.onStartActivity(intents[0]);
                     }
                     if (result != null) {
                         am.mHits++;
@@ -1722,7 +1722,7 @@
                     final ActivityMonitor am = mActivityMonitors.get(i);
                     ActivityResult result = null;
                     if (am.ignoreMatchingSpecificIntents()) {
-                        result = am.onMatchIntent(intent);
+                        result = am.onStartActivity(intent);
                     }
                     if (result != null) {
                         am.mHits++;
@@ -1789,7 +1789,7 @@
                     final ActivityMonitor am = mActivityMonitors.get(i);
                     ActivityResult result = null;
                     if (am.ignoreMatchingSpecificIntents()) {
-                        result = am.onMatchIntent(intent);
+                        result = am.onStartActivity(intent);
                     }
                     if (result != null) {
                         am.mHits++;
@@ -1835,7 +1835,7 @@
                     final ActivityMonitor am = mActivityMonitors.get(i);
                     ActivityResult result = null;
                     if (am.ignoreMatchingSpecificIntents()) {
-                        result = am.onMatchIntent(intent);
+                        result = am.onStartActivity(intent);
                     }
                     if (result != null) {
                         am.mHits++;
@@ -1880,7 +1880,7 @@
                     final ActivityMonitor am = mActivityMonitors.get(i);
                     ActivityResult result = null;
                     if (am.ignoreMatchingSpecificIntents()) {
-                        result = am.onMatchIntent(intent);
+                        result = am.onStartActivity(intent);
                     }
                     if (result != null) {
                         am.mHits++;
diff --git a/core/java/android/app/admin/ConnectEvent.java b/core/java/android/app/admin/ConnectEvent.java
index 5111443..423ee52 100644
--- a/core/java/android/app/admin/ConnectEvent.java
+++ b/core/java/android/app/admin/ConnectEvent.java
@@ -19,6 +19,9 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
 /**
  * A class that represents a connect library call event.
  */
@@ -44,8 +47,14 @@
         this.timestamp = in.readLong();
     }
 
-    public String getIpAddress() {
-        return ipAddress;
+    public InetAddress getInetAddress() {
+        try {
+            // ipAddress is already an address, not a host name, no DNS resolution will happen.
+            return InetAddress.getByName(ipAddress);
+        } catch (UnknownHostException e) {
+            // Should never happen as we aren't passing a host name.
+            return InetAddress.getLoopbackAddress();
+        }
     }
 
     public int getPort() {
diff --git a/core/java/android/app/admin/DnsEvent.java b/core/java/android/app/admin/DnsEvent.java
index a3a3f58..87f86b5 100644
--- a/core/java/android/app/admin/DnsEvent.java
+++ b/core/java/android/app/admin/DnsEvent.java
@@ -19,6 +19,9 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
 /**
  * A class that represents a DNS lookup event.
  */
@@ -59,15 +62,27 @@
     }
 
     /** Returns (possibly a subset of) the IP addresses returned. */
-    public String[] getIpAddresses() {
-        return ipAddresses;
+    public InetAddress[] getInetAddresses() {
+        final int length = ipAddresses != null ? ipAddresses.length : 0;
+        final InetAddress[] inetAddresses = new InetAddress[length];
+        for (int i = 0; i < length; i++) {
+            try {
+                // ipAddress is already an address, not a host name, no DNS resolution will happen.
+                inetAddresses[i] = InetAddress.getByName(ipAddresses[i]);
+            } catch (UnknownHostException e) {
+                // Should never happen as we aren't passing a host name.
+                inetAddresses[i] = InetAddress.getLoopbackAddress();
+            }
+        }
+        return inetAddresses;
     }
 
     /**
      * Returns the number of IP addresses returned from the DNS lookup event. May be different from
-     * the length of ipAddresses if there were too many addresses to log.
+     * the length of the array returned by {@link #getInetAddresses()} if there were too many
+     * addresses to log.
      */
-    public int getIpAddressesCount() {
+    public int getTotalResolvedAddressCount() {
         return ipAddressesCount;
     }
 
diff --git a/core/java/android/app/assist/AssistStructure.java b/core/java/android/app/assist/AssistStructure.java
index d6b89a1..03ef24a9 100644
--- a/core/java/android/app/assist/AssistStructure.java
+++ b/core/java/android/app/assist/AssistStructure.java
@@ -2023,8 +2023,9 @@
 
     /**
      * Returns whether the activity associated with this AssistStructure was the home activity
-     * at the time the assist data was acquired.
+     * (Launcher) at the time the assist data was acquired.
      * @return Whether the activity was the home activity.
+     * @see android.content.Intent#CATEGORY_HOME
      */
     public boolean isHomeActivity() {
         return mIsHomeActivity;
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 5f7947f..737ccf26 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -4422,6 +4422,21 @@
     public static final String EXTRA_VERSION_CODE = "android.intent.extra.VERSION_CODE";
 
     /**
+     * The app that triggered the ephemeral installation.
+     * @hide
+     */
+    public static final String EXTRA_CALLING_PACKAGE
+            = "android.intent.extra.CALLING_PACKAGE";
+
+    /**
+     * Optional calling app provided bundle containing additional launch information the
+     * installer may use.
+     * @hide
+     */
+    public static final String EXTRA_VERIFICATION_BUNDLE
+            = "android.intent.extra.VERIFICATION_BUNDLE";
+
+    /**
      * A Bundle forming a mapping of potential target package names to different extras Bundles
      * to add to the default intent extras in {@link #EXTRA_INTENT} when used with
      * {@link #ACTION_CHOOSER}. Each key should be a package name. The package need not
diff --git a/core/java/android/content/pm/InstantAppRequest.java b/core/java/android/content/pm/InstantAppRequest.java
index b45169d..27d2828 100644
--- a/core/java/android/content/pm/InstantAppRequest.java
+++ b/core/java/android/content/pm/InstantAppRequest.java
@@ -17,6 +17,7 @@
 package android.content.pm;
 
 import android.content.Intent;
+import android.os.Bundle;
 
 /**
  * Information needed to make an instant application resolution request.
@@ -33,13 +34,18 @@
     public final String callingPackage;
     /** ID of the user requesting the instant application */
     public final int userId;
+    /**
+     * Optional extra bundle provided by the source application to the installer for additional
+     * verification. */
+    public final Bundle verificationBundle;
 
     public InstantAppRequest(AuxiliaryResolveInfo responseObj, Intent origIntent,
-            String resolvedType, String callingPackage, int userId) {
+            String resolvedType, String callingPackage, int userId, Bundle verificationBundle) {
         this.responseObj = responseObj;
         this.origIntent = origIntent;
         this.resolvedType = resolvedType;
         this.callingPackage = callingPackage;
         this.userId = userId;
+        this.verificationBundle = verificationBundle;
     }
-}
\ No newline at end of file
+}
diff --git a/core/java/android/content/pm/PackageManagerInternal.java b/core/java/android/content/pm/PackageManagerInternal.java
index 7bfde75..426f3cf 100644
--- a/core/java/android/content/pm/PackageManagerInternal.java
+++ b/core/java/android/content/pm/PackageManagerInternal.java
@@ -19,6 +19,7 @@
 import android.content.ComponentName;
 import android.content.Intent;
 import android.content.pm.PackageManager.NameNotFoundException;
+import android.os.Bundle;
 import android.util.SparseArray;
 
 import java.util.List;
@@ -215,11 +216,13 @@
      * @param origIntent The original intent that triggered ephemeral resolution
      * @param resolvedType The resolved type of the intent
      * @param callingPackage The name of the package requesting the ephemeral application
+     * @param verificationBundle Optional bundle to pass to the installer for additional
+     * verification
      * @param userId The ID of the user that triggered ephemeral resolution
      */
     public abstract void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
             Intent origIntent, String resolvedType, String callingPackage,
-            int userId);
+            Bundle verificationBundle, int userId);
 
     /**
      * Grants access to the package metadata for an ephemeral application.
@@ -333,4 +336,9 @@
      * @param isolatedUid isolated uid that is no longer being used.
      */
     public abstract void removeIsolatedUid(int isolatedUid);
+
+    /**
+     * Return the taget SDK version for the app with the given UID.
+     */
+    public abstract int getUidTargetSdkVersion(int uid);
 }
diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java
index a044804..f0adcd6 100644
--- a/core/java/android/content/res/AssetManager.java
+++ b/core/java/android/content/res/AssetManager.java
@@ -788,8 +788,8 @@
     /**
      * Retrieve the resource identifier for the given resource name.
      */
-    /*package*/ native final int getResourceIdentifier(String type,
-                                                       String name,
+    /*package*/ native final int getResourceIdentifier(String name,
+                                                       String defType,
                                                        String defPackage);
 
     /*package*/ native final String getResourceName(int resid);
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 695efdd..a18381b 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -16577,6 +16577,7 @@
      * @param config Configuration of the resources on new display after move.
      *
      * @see #onConfigurationChanged(Configuration)
+     * @hide
      */
     public void onMovedToDisplay(int displayId, Configuration config) {
     }
diff --git a/core/java/android/view/textclassifier/SmartSelection.java b/core/java/android/view/textclassifier/SmartSelection.java
index f0f39b6..f0e83d1 100644
--- a/core/java/android/view/textclassifier/SmartSelection.java
+++ b/core/java/android/view/textclassifier/SmartSelection.java
@@ -75,6 +75,20 @@
         nativeClose(mCtx);
     }
 
+    /**
+     * Returns the language of the model.
+     */
+    public static String getLanguage(int fd) {
+        return nativeGetLanguage(fd);
+    }
+
+    /**
+     * Returns the version of the model.
+     */
+    public static int getVersion(int fd) {
+        return nativeGetVersion(fd);
+    }
+
     private static native long nativeNew(int fd);
 
     private static native int[] nativeSuggest(
@@ -85,6 +99,10 @@
 
     private static native void nativeClose(long context);
 
+    private static native String nativeGetLanguage(int fd);
+
+    private static native int nativeGetVersion(int fd);
+
     /** Classification result for classifyText method. */
     static final class ClassificationResult {
         final String mCollection;
diff --git a/core/java/android/view/textclassifier/TextClassifierImpl.java b/core/java/android/view/textclassifier/TextClassifierImpl.java
index 246fab3..9c4fc3c 100644
--- a/core/java/android/view/textclassifier/TextClassifierImpl.java
+++ b/core/java/android/view/textclassifier/TextClassifierImpl.java
@@ -44,6 +44,7 @@
 
 import java.io.File;
 import java.io.FileNotFoundException;
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
@@ -71,6 +72,8 @@
     private static final String LOG_TAG = "TextClassifierImpl";
     private static final String MODEL_DIR = "/etc/textclassifier/";
     private static final String MODEL_FILE_REGEX = "textclassifier\\.smartselection\\.(.*)\\.model";
+    private static final String UPDATED_MODEL_FILE_PATH =
+            "/data/misc/textclassifier/textclassifier.smartselection.model";
 
     private final Context mContext;
 
@@ -175,15 +178,12 @@
         synchronized (mSmartSelectionLock) {
             localeList = localeList == null ? LocaleList.getEmptyLocaleList() : localeList;
             final Locale locale = findBestSupportedLocaleLocked(localeList);
+            if (locale == null) {
+                throw new FileNotFoundException("No file for null locale");
+            }
             if (mSmartSelection == null || !Objects.equals(mLocale, locale)) {
                 destroySmartSelectionIfExistsLocked();
-                mSmartSelection = new SmartSelection(
-                        ParcelFileDescriptor.open(
-                                // findBestSupportedLocaleLocked should have initialized
-                                // mModelFilePaths
-                                new File(mModelFilePaths.get(locale)),
-                                ParcelFileDescriptor.MODE_READ_ONLY)
-                                .getFd());
+                mSmartSelection = new SmartSelection(getFdLocked(locale));
                 mLocale = locale;
             }
             return mSmartSelection;
@@ -191,6 +191,68 @@
     }
 
     @GuardedBy("mSmartSelectionLock") // Do not call outside this lock.
+    private int getFdLocked(Locale locale) throws FileNotFoundException {
+        ParcelFileDescriptor updateFd;
+        try {
+            updateFd = ParcelFileDescriptor.open(
+                    new File(UPDATED_MODEL_FILE_PATH), ParcelFileDescriptor.MODE_READ_ONLY);
+        } catch (FileNotFoundException e) {
+            updateFd = null;
+        }
+        ParcelFileDescriptor factoryFd;
+        try {
+            final String factoryModelFilePath = getFactoryModelFilePathsLocked().get(locale);
+            if (factoryModelFilePath != null) {
+                factoryFd = ParcelFileDescriptor.open(
+                        new File(factoryModelFilePath), ParcelFileDescriptor.MODE_READ_ONLY);
+            } else {
+                factoryFd = null;
+            }
+        } catch (FileNotFoundException e) {
+            factoryFd = null;
+        }
+
+        if (updateFd == null) {
+            if (factoryFd != null) {
+                return factoryFd.getFd();
+            } else {
+                throw new FileNotFoundException(
+                        String.format("No model file found for %s", locale));
+            }
+        }
+
+        final int updateFdInt = updateFd.getFd();
+        final boolean localeMatches = Objects.equals(
+                locale.getLanguage().trim().toLowerCase(),
+                SmartSelection.getLanguage(updateFdInt).trim().toLowerCase());
+        if (factoryFd == null) {
+            if (localeMatches) {
+                return updateFdInt;
+            } else {
+                closeAndLogError(updateFd);
+                throw new FileNotFoundException(
+                        String.format("No model file found for %s", locale));
+            }
+        }
+
+        if (!localeMatches) {
+            closeAndLogError(updateFd);
+            return factoryFd.getFd();
+        }
+
+        final int updateVersion = SmartSelection.getVersion(updateFdInt);
+        final int factoryFdInt = factoryFd.getFd();
+        final int factoryVersion = SmartSelection.getVersion(factoryFdInt);
+        if (updateVersion > factoryVersion) {
+            closeAndLogError(factoryFd);
+            return updateFdInt;
+        } else {
+            closeAndLogError(updateFd);
+            return factoryFdInt;
+        }
+    }
+
+    @GuardedBy("mSmartSelectionLock") // Do not call outside this lock.
     private void destroySmartSelectionIfExistsLocked() {
         if (mSmartSelection != null) {
             mSmartSelection.close();
@@ -206,11 +268,18 @@
                 ? LocaleList.getDefault().toLanguageTags()
                 : localeList.toLanguageTags() + "," + LocaleList.getDefault().toLanguageTags();
         final List<Locale.LanguageRange> languageRangeList = Locale.LanguageRange.parse(languages);
-        return Locale.lookup(languageRangeList, loadModelFilePathsLocked().keySet());
+
+        final List<Locale> supportedLocales =
+                new ArrayList<>(getFactoryModelFilePathsLocked().keySet());
+        final Locale updatedModelLocale = getUpdatedModelLocale();
+        if (updatedModelLocale != null) {
+            supportedLocales.add(updatedModelLocale);
+        }
+        return Locale.lookup(languageRangeList, supportedLocales);
     }
 
     @GuardedBy("mSmartSelectionLock") // Do not call outside this lock.
-    private Map<Locale, String> loadModelFilePathsLocked() {
+    private Map<Locale, String> getFactoryModelFilePathsLocked() {
         if (mModelFilePaths == null) {
             final Map<Locale, String> modelFilePaths = new HashMap<>();
             final File modelsDir = new File(MODEL_DIR);
@@ -233,6 +302,20 @@
         return mModelFilePaths;
     }
 
+    @Nullable
+    private Locale getUpdatedModelLocale() {
+        try {
+            final ParcelFileDescriptor updateFd = ParcelFileDescriptor.open(
+                    new File(UPDATED_MODEL_FILE_PATH), ParcelFileDescriptor.MODE_READ_ONLY);
+            final Locale locale = Locale.forLanguageTag(
+                    SmartSelection.getLanguage(updateFd.getFd()));
+            closeAndLogError(updateFd);
+            return locale;
+        } catch (FileNotFoundException e) {
+            return null;
+        }
+    }
+
     private TextClassificationResult createClassificationResult(
             SmartSelection.ClassificationResult[] classifications, CharSequence text) {
         final TextClassificationResult.Builder builder = new TextClassificationResult.Builder()
@@ -319,6 +402,17 @@
     }
 
     /**
+     * Closes the ParcelFileDescriptor and logs any errors that occur.
+     */
+    private static void closeAndLogError(ParcelFileDescriptor fd) {
+        try {
+            fd.close();
+        } catch (IOException e) {
+            Log.e(LOG_TAG, "Error closing file.", e);
+        }
+    }
+
+    /**
      * @throws IllegalArgumentException if text is null; startIndex is negative;
      *      endIndex is greater than text.length() or is not greater than startIndex
      */
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 6213a63..8a441fc8 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -2255,6 +2255,7 @@
 
     /**
      * Sets the {@link TextClassifier} for this WebView.
+     * @hide
      */
     public void setTextClassifier(@Nullable TextClassifier textClassifier) {
         mProvider.setTextClassifier(textClassifier);
@@ -2263,6 +2264,7 @@
     /**
      * Returns the {@link TextClassifier} used by this WebView.
      * If no TextClassifier has been set, this WebView uses the default set by the system.
+     * @hide
      */
     @NonNull
     public TextClassifier getTextClassifier() {
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 406386aa..99b9bd2bfb 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -56,6 +56,7 @@
 import android.graphics.Typeface;
 import android.graphics.drawable.Drawable;
 import android.graphics.fonts.FontVariationAxis;
+import android.graphics.fonts.FontVariationAxis.InvalidFormatException;
 import android.icu.text.DecimalFormatSymbols;
 import android.os.AsyncTask;
 import android.os.Build.VERSION_CODES;
@@ -3886,26 +3887,43 @@
      * are invalid. If a specified axis name is not defined in the font, the settings will be
      * ignored.
      *
+     * <p>
+     * Examples,
+     * <ul>
+     * <li>Set font width to 150.
      * <pre>
-     *   textView.setFontVariationSettings("'wdth' 1.0");
-     *   textView.setFontVariationSettings("'AX  ' 1.8, 'FB  ' 2.0");
+     * <code>
+     *   TextView textView = (TextView) findViewById(R.id.textView);
+     *   textView.setFontVariationSettings("'wdth' 150");
+     * </code>
      * </pre>
+     * </li>
+     *
+     * <li>Set the font slant to 20 degrees and ask for italic style.
+     * <pre>
+     * <code>
+     *   TextView textView = (TextView) findViewById(R.id.textView);
+     *   textView.setFontVariationSettings("'slnt' 20, 'ital' 1");
+     * </code>
+     * </pre>
+     * </p>
+     * </li>
+     * </ul>
      *
      * @param fontVariationSettings font variation settings. You can pass null or empty string as
      *                              no variation settings.
-     *
      * @return true if the given settings is effective to at least one font file underlying this
      *         TextView. This function also returns true for empty settings string. Otherwise
      *         returns false.
      *
-     * @throws FontVariationAxis.InvalidFormatException
-     *         If given string is not a valid font variation settings format.
+     * @throws InvalidFormatException If given string is not a valid font variation settings
+     *                                format.
      *
      * @see #getFontVariationSettings()
-     * @see Paint#getFontVariationSettings() Paint.getFontVariationSettings()
+     * @see FontVariationAxis
      */
     public boolean setFontVariationSettings(@Nullable String fontVariationSettings)
-            throws FontVariationAxis.InvalidFormatException {
+            throws InvalidFormatException {
         final String existingSettings = mTextPaint.getFontVariationSettings();
         if (fontVariationSettings == existingSettings
                 || (fontVariationSettings != null
diff --git a/core/java/com/android/internal/content/PackageMonitor.java b/core/java/com/android/internal/content/PackageMonitor.java
index c6b6a7fb..d2e9789 100644
--- a/core/java/com/android/internal/content/PackageMonitor.java
+++ b/core/java/com/android/internal/content/PackageMonitor.java
@@ -65,6 +65,7 @@
     int mChangeType;
     int mChangeUserId = UserHandle.USER_NULL;
     boolean mSomePackagesChanged;
+    String[] mModifiedComponents;
 
     String[] mTempArray = new String[1];
 
@@ -269,6 +270,18 @@
         }
         return false;
     }
+
+    public boolean isComponentModified(String className) {
+        if (className == null || mModifiedComponents == null) {
+            return false;
+        }
+        for (int i = mModifiedComponents.length - 1; i >= 0; i--) {
+            if (className.equals(mModifiedComponents[i])) {
+                return true;
+            }
+        }
+        return false;
+    }
     
     public void onSomePackagesChanged() {
     }
@@ -301,6 +314,7 @@
         
         mDisappearingPackages = mAppearingPackages = null;
         mSomePackagesChanged = false;
+        mModifiedComponents = null;
         
         String action = intent.getAction();
         if (Intent.ACTION_PACKAGE_ADDED.equals(action)) {
@@ -358,13 +372,13 @@
         } else if (Intent.ACTION_PACKAGE_CHANGED.equals(action)) {
             String pkg = getPackageName(intent);
             int uid = intent.getIntExtra(Intent.EXTRA_UID, 0);
-            String[] components = intent.getStringArrayExtra(
+            mModifiedComponents = intent.getStringArrayExtra(
                     Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST);
             if (pkg != null) {
                 mModifiedPackages = mTempArray;
                 mTempArray[0] = pkg;
                 mChangeType = PACKAGE_PERMANENT_CHANGE;
-                if (onPackageChanged(pkg, uid, components)) {
+                if (onPackageChanged(pkg, uid, mModifiedComponents)) {
                     mSomePackagesChanged = true;
                 }
                 onPackageModified(pkg);
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index ad4afae..ba24eec 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -37,8 +37,7 @@
 
 /** Tests that ensure appropriate settings are backed up. */
 @RunWith(AndroidJUnit4.class)
-// TODO(b/37684646): Can re-enable pre-submit once test is fixed.
-//@Presubmit
+@Presubmit
 @SmallTest
 public class SettingsBackupTest {
 
diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java
index 828729a..81bd6ad 100644
--- a/graphics/java/android/graphics/Paint.java
+++ b/graphics/java/android/graphics/Paint.java
@@ -21,6 +21,7 @@
 import android.annotation.Size;
 import android.graphics.FontListParser;
 import android.graphics.fonts.FontVariationAxis;
+import android.graphics.fonts.FontVariationAxis.InvalidFormatException;
 import android.os.LocaleList;
 import android.text.FontConfig;
 import android.text.GraphicsOperations;
@@ -1539,25 +1540,49 @@
     }
 
     /**
-     * Set font variation settings.
+     * Sets TrueType or OpenType font variation settings. The settings string is constructed from
+     * multiple pairs of axis tag and style values. The axis tag must contain four ASCII characters
+     * and must be wrapped with single quotes (U+0027) or double quotes (U+0022). Axis strings that
+     * are longer or shorter than four characters, or contain characters outside of U+0020..U+007E
+     * are invalid. If a specified axis name is not defined in the font, the settings will be
+     * ignored.
      *
-     * This function does nothing if none of the settings is applicable to underlying font files.
+     * Examples,
+     * <ul>
+     * <li>Set font width to 150.
+     * <pre>
+     * <code>
+     *   Paint paint = new Paint();
+     *   paint.setFontVariationSettings("'wdth' 150");
+     * </code>
+     * </pre>
+     * </li>
      *
-     * @param settings font variation settings, e.g. "'wdth' 300, 'wght' 1.8"
+     * <li>Set the font slant to 20 degrees and ask for italic style.
+     * <pre>
+     * <code>
+     *   Paint paint = new Paint();
+     *   paint.setFontVariationSettings("'slnt' 20, 'ital' 1");
+     * </code>
+     * </pre>
+     * </li>
+     * </ul>
      *
-     * @see #getFontVariationSettings()
+     * @param fontVariationSettings font variation settings. You can pass null or empty string as
+     *                              no variation settings.
      *
-     * @param settings the font variation settings. You can pass null or empty string as no
-     *                 variation settings.
      * @return true if the given settings is effective to at least one font file underlying this
      *         typeface. This function also returns true for empty settings string. Otherwise
      *         returns false
-     * @throws FontVariationAxis.InvalidFormatException
-     *         If given string is not a valid font variation settings format.
+     *
+     * @throws InvalidFormatException If given string is not a valid font variation settings format.
+     *
+     * @see #getFontVariationSettings()
+     * @see FontVariationAxis
      */
-    public boolean setFontVariationSettings(String settings)
-            throws FontVariationAxis.InvalidFormatException {
-        settings = TextUtils.nullIfEmpty(settings);
+    public boolean setFontVariationSettings(String fontVariationSettings)
+            throws InvalidFormatException {
+        final String settings = TextUtils.nullIfEmpty(fontVariationSettings);
         if (settings == mFontVariationSettings
                 || (settings != null && settings.equals(mFontVariationSettings))) {
             return true;
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java
index 49fc2ea..32e6389 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java
@@ -35,8 +35,8 @@
 import android.os.UserManager;
 import android.provider.Settings;
 import android.support.annotation.VisibleForTesting;
-import android.text.Spanned;
 import android.text.SpannableStringBuilder;
+import android.text.Spanned;
 import android.text.style.ForegroundColorSpan;
 import android.text.style.ImageSpan;
 import android.view.MenuItem;
@@ -75,41 +75,52 @@
      */
     public static EnforcedAdmin checkIfRestrictionEnforced(Context context,
             String userRestriction, int userId) {
-        DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService(
+        final DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService(
                 Context.DEVICE_POLICY_SERVICE);
         if (dpm == null) {
             return null;
         }
-        UserManager um = UserManager.get(context);
-        int restrictionSource = um.getUserRestrictionSource(userRestriction,
-                UserHandle.of(userId));
 
-        // If the restriction is not enforced or enforced only by system then return null
-        if (restrictionSource == UserManager.RESTRICTION_NOT_SET
-                || restrictionSource == UserManager.RESTRICTION_SOURCE_SYSTEM) {
+        final UserManager um = UserManager.get(context);
+        final List<UserManager.EnforcingUser> enforcingUsers =
+                um.getUserRestrictionSources(userRestriction, UserHandle.of(userId));
+
+        if (enforcingUsers.isEmpty()) {
+            // Restriction is not enforced.
             return null;
+        } else if (enforcingUsers.size() > 1) {
+            return EnforcedAdmin.MULTIPLE_ENFORCED_ADMIN;
         }
 
-        final boolean enforcedByProfileOwner =
-                (restrictionSource & UserManager.RESTRICTION_SOURCE_PROFILE_OWNER) != 0;
-        final boolean enforcedByDeviceOwner =
-                (restrictionSource & UserManager.RESTRICTION_SOURCE_DEVICE_OWNER) != 0;
-        if (enforcedByProfileOwner) {
-            return getProfileOwner(context, userId);
-        } else if (enforcedByDeviceOwner) {
+        final int restrictionSource = enforcingUsers.get(0).getUserRestrictionSource();
+        final int adminUserId = enforcingUsers.get(0).getUserHandle().getIdentifier();
+
+        if (restrictionSource == UserManager.RESTRICTION_SOURCE_PROFILE_OWNER) {
+            // Check if it is a profile owner of the user under consideration.
+            if (adminUserId == userId) {
+                return getProfileOwner(context, adminUserId);
+            } else {
+                // Check if it is a profile owner of a managed profile of the current user.
+                // Otherwise it is in a separate user and we return a default EnforcedAdmin.
+                final UserInfo parentUser = um.getProfileParent(adminUserId);
+                return (parentUser != null && parentUser.id == userId)
+                        ? getProfileOwner(context, adminUserId)
+                        : EnforcedAdmin.MULTIPLE_ENFORCED_ADMIN;
+            }
+        } else if (restrictionSource == UserManager.RESTRICTION_SOURCE_DEVICE_OWNER) {
             // When the restriction is enforced by device owner, return the device owner admin only
             // if the admin is for the {@param userId} otherwise return a default EnforcedAdmin.
-            final EnforcedAdmin deviceOwner = getDeviceOwner(context);
-            return deviceOwner.userId == userId
-                    ? deviceOwner
-                    : EnforcedAdmin.MULTIPLE_ENFORCED_ADMIN;
+            return adminUserId == userId
+                    ? getDeviceOwner(context) : EnforcedAdmin.MULTIPLE_ENFORCED_ADMIN;
         }
+
+        // If the restriction is enforced by system then return null.
         return null;
     }
 
     public static boolean hasBaseUserRestriction(Context context,
             String userRestriction, int userId) {
-        UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
+        final UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
         return um.hasBaseUserRestriction(userRestriction, UserHandle.of(userId));
     }
 
@@ -424,7 +435,6 @@
         if (dpm == null) {
             return null;
         }
-        LockPatternUtils lockPatternUtils = new LockPatternUtils(context);
         EnforcedAdmin enforcedAdmin = null;
         final int userId = UserHandle.myUserId();
         final UserManager um = UserManager.get(context);
diff --git a/packages/SystemUI/res-keyguard/values/strings.xml b/packages/SystemUI/res-keyguard/values/strings.xml
index 2f52227..1efa3a8 100644
--- a/packages/SystemUI/res-keyguard/values/strings.xml
+++ b/packages/SystemUI/res-keyguard/values/strings.xml
@@ -102,6 +102,9 @@
     <string name="keyguard_widget_12_hours_format" translatable="false">h\uee01mm</string>
     <!-- Time format strings for fall-back clock widget -->
     <string name="keyguard_widget_24_hours_format" translatable="false">kk\uee01mm</string>
+    <!-- The character used in keyguard_widget_12_hours_format and keyguard_widget_24_hours_format
+         to represent a ":". -->
+    <string name="keyguard_fancy_colon" translatable="false">\uee01</string>
 
     <!-- Accessibility description of the PIN password view. [CHAR_LIMIT=none] -->
     <string name="keyguard_accessibility_pin_area">PIN area</string>
diff --git a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_1x.xml b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_1x.xml
index be9a7e2..d7463a4 100644
--- a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_1x.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_1x.xml
@@ -14,10 +14,10 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="17dp"
-    android:height="17dp"
-    android:viewportWidth="12.0"
-    android:viewportHeight="12.0">
+        android:width="8.5dp"
+        android:height="17dp"
+        android:viewportWidth="12.0"
+        android:viewportHeight="24.0">
     <path
         android:fillColor="#FFFFFFFF"
         android:pathData="M3.500000,11.000000L1.800000,11.000000L1.800000,4.400000L0.200000,5.100000L0.200000,3.700000l3.100000,-1.300000l0.200000,0.000000L3.500000,11.000000z"/>
diff --git a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_3g.xml b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_3g.xml
index fd7a658..6309b6d 100644
--- a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_3g.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_3g.xml
@@ -14,10 +14,10 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="17dp"
+        android:width="9.208dp"
         android:height="17dp"
         android:viewportWidth="13.0"
-        android:viewportHeight="13.0">
+        android:viewportHeight="24.0">
     <path
         android:fillColor="#FFFFFFFF"
         android:pathData="M2.000000,6.000000l0.800000,0.000000c0.300000,0.000000 0.500000,-0.100000 0.700000,-0.300000s0.200000,-0.500000 0.200000,-0.900000c0.000000,-0.300000 -0.100000,-0.600000 -0.200000,-0.800000S3.200000,3.700000 2.900000,3.700000C2.700000,3.700000 2.500000,3.800000 2.300000,4.000000S2.100000,4.400000 2.100000,4.700000L0.500000,4.700000C0.500000,4.000000 0.700000,3.400000 1.100000,3.000000s1.000000,-0.600000 1.700000,-0.600000c0.800000,0.000000 1.400000,0.200000 1.900000,0.600000s0.700000,1.000000 0.700000,1.800000c0.000000,0.400000 -0.100000,0.700000 -0.300000,1.100000S4.600000,6.500000 4.300000,6.600000C4.700000,6.800000 5.000000,7.100000 5.200000,7.400000s0.300000,0.700000 0.300000,1.200000c0.000000,0.800000 -0.200000,1.400000 -0.700000,1.800000s-1.100000,0.700000 -1.900000,0.700000c-0.700000,0.000000 -1.300000,-0.200000 -1.800000,-0.600000s-0.700000,-1.000000 -0.700000,-1.800000L2.000000,8.700000C2.000000,9.000000 2.100000,9.300000 2.300000,9.500000s0.400000,0.300000 0.600000,0.300000c0.300000,0.000000 0.500000,-0.100000 0.700000,-0.300000S3.900000,9.000000 3.900000,8.600000c0.000000,-0.500000 -0.100000,-0.800000 -0.300000,-1.000000S3.200000,7.300000 2.800000,7.300000L2.000000,7.300000L2.000000,6.000000z"/>
diff --git a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_4g.xml b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_4g.xml
index 02c4ab6..4067ae5 100644
--- a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_4g.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_4g.xml
@@ -14,10 +14,10 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="17dp"
+        android:width="8.5dp"
         android:height="17dp"
         android:viewportWidth="12.0"
-        android:viewportHeight="12.0">
+        android:viewportHeight="24.0">
     <path
         android:fillColor="#FFFFFFFF"
         android:pathData="M4.600000,7.800000l0.700000,0.000000l0.000000,1.300000L4.600000,9.100000L4.600000,11.000000L3.000000,11.000000L3.000000,9.200000L0.100000,9.200000L0.000000,8.100000L3.000000,2.500000l1.700000,0.000000L4.700000,7.800000zM1.600000,7.800000L3.000000,7.800000l0.000000,-3.000000L2.900000,5.000000L1.600000,7.800000z"/>
diff --git a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_4g_plus.xml b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_4g_plus.xml
index daf4061..3cdd3e1 100644
--- a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_4g_plus.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_4g_plus.xml
@@ -14,10 +14,10 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="25.5dp"
+        android:width="17.0dp"
         android:height="17.0dp"
-        android:viewportWidth="18.0"
-        android:viewportHeight="12.0">
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
     <path
         android:fillColor="#FFFFFFFF"
         android:pathData="M4.6,7.8l0.7,0.0l0.0,1.3L4.6,9.1L4.6,11.0L3.0,11.0L3.0,9.2L0.1,9.2L0.0,8.2l3.0,-5.7l1.7,0.0L4.6,7.8L4.6,7.8zM1.7,7.8L3.0,7.8l0.0,-3.0L2.9,5.0L1.7,7.8z"/>
diff --git a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_e.xml b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_e.xml
index cd0cc65..acaa9b1 100644
--- a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_e.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_e.xml
@@ -14,10 +14,10 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="7.083dp"
+        android:width="3.541dp"
         android:height="17dp"
         android:viewportWidth="5.0"
-        android:viewportHeight="12.0">
+        android:viewportHeight="24.0">
     <path
         android:fillColor="#FFFFFFFF"
         android:pathData="M4.400000,7.300000L1.700000,7.300000l0.000000,2.400000l3.300000,0.000000L5.000000,11.000000L0.000000,11.000000L0.000000,2.500000l4.900000,0.000000l0.000000,1.300000L1.700000,3.800000l0.000000,2.100000l2.800000,0.000000L4.500000,7.300000z"/>
diff --git a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_g.xml b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_g.xml
index 92ed49c..7985237 100644
--- a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_g.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_g.xml
@@ -14,10 +14,10 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="9.154dp"
+        android:width="4.958dp"
         android:height="17dp"
         android:viewportWidth="7.0"
-        android:viewportHeight="13">
+        android:viewportHeight="24.0">
     <path
         android:fillColor="#FFFFFFFF"
         android:pathData="M6.500000,9.900000c-0.200000,0.400000 -0.600000,0.700000 -1.000000,0.900000s-1.000000,0.400000 -1.800000,0.400000c-0.900000,0.000000 -1.700000,-0.300000 -2.200000,-0.800000S0.700000,9.000000 0.700000,7.900000L0.700000,5.600000c0.000000,-1.100000 0.300000,-1.900000 0.800000,-2.400000s1.200000,-0.800000 2.100000,-0.800000c1.000000,0.000000 1.700000,0.200000 2.100000,0.700000s0.700000,1.200000 0.700000,2.100000L4.700000,5.200000c0.000000,-0.500000 -0.100000,-0.900000 -0.200000,-1.100000S4.000000,3.700000 3.600000,3.700000c-0.400000,0.000000 -0.700000,0.200000 -0.900000,0.500000S2.300000,5.000000 2.300000,5.600000l0.000000,2.300000c0.000000,0.700000 0.100000,1.100000 0.300000,1.400000s0.600000,0.500000 1.000000,0.500000c0.300000,0.000000 0.600000,0.000000 0.700000,-0.100000s0.300000,-0.200000 0.400000,-0.300000L4.700000,7.800000L3.500000,7.800000L3.500000,6.600000l2.900000,0.000000L6.400000,9.900000z"/>
diff --git a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_h.xml b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_h.xml
index ca61b6f..fda8761 100644
--- a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_h.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_h.xml
@@ -14,10 +14,10 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="9.5dp"
+        android:width="4.25dp"
         android:height="17dp"
         android:viewportWidth="6.0"
-        android:viewportHeight="12.0">
+        android:viewportHeight="24.0">
     <path
         android:fillColor="#FFFFFFFF"
         android:pathData="M6.000000,11.000000L4.400000,11.000000L4.400000,7.500000L1.700000,7.500000L1.700000,11.000000L0.000000,11.000000L0.000000,2.500000l1.700000,0.000000l0.000000,3.700000l2.700000,0.000000L4.400000,2.500000L6.000000,2.500000L6.000000,11.000000z"/>
diff --git a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_lte.xml b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_lte.xml
index add96b4..c08ff20 100644
--- a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_lte.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_lte.xml
@@ -14,10 +14,10 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="18.417dp"
+        android:width="9.208dp"
         android:height="17dp"
-        android:viewportWidth="13"
-        android:viewportHeight="12.0">
+        android:viewportWidth="13.0"
+        android:viewportHeight="24.0">
     <path
         android:fillColor="#FFFFFFFF"
         android:pathData="M2.000000,9.700000l2.000000,0.000000L4.000000,11.000000L0.300000,11.000000L0.300000,2.500000L2.000000,2.500000L2.000000,9.700000z"/>
diff --git a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_lte_plus.xml b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_lte_plus.xml
index 8811d2f..db18fad 100644
--- a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_lte_plus.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_lte_plus.xml
@@ -14,10 +14,10 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="25.0dp"
+        android:width="17.0dp"
         android:height="17.0dp"
-        android:viewportWidth="18.0"
-        android:viewportHeight="12.0">
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
     <path
         android:fillColor="#FFFFFFFF"
         android:pathData="M2.0,9.7l2.0,0.0L4.0,11.0L0.4,11.0L0.4,2.5L2.0,2.5L2.0,9.7z"/>
diff --git a/packages/SystemUI/res/drawable/stat_sys_roaming.xml b/packages/SystemUI/res/drawable/stat_sys_roaming.xml
index 363e231..4baa472 100644
--- a/packages/SystemUI/res/drawable/stat_sys_roaming.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_roaming.xml
@@ -14,10 +14,10 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="4.25dp"
+        android:width="8.5dp"
         android:height="17dp"
         android:viewportWidth="6.0"
-        android:viewportHeight="24.0">
+        android:viewportHeight="12.0">
     <path
         android:fillColor="#FFFFFFFF"
         android:pathData="M2.800000,7.900000l-1.000000,0.000000L1.800000,11.000000L0.200000,11.000000L0.200000,2.500000l2.700000,0.000000c0.900000,0.000000 1.500000,0.200000 2.000000,0.700000s0.700000,1.100000 0.700000,1.900000c0.000000,0.600000 -0.100000,1.100000 -0.300000,1.500000S4.800000,7.200000 4.400000,7.400000l1.500000,3.500000L5.900000,11.000000L4.100000,11.000000L2.800000,7.900000zM1.800000,6.500000l1.100000,0.000000c0.400000,0.000000 0.600000,-0.100000 0.800000,-0.400000S4.000000,5.600000 4.000000,5.200000c0.000000,-0.400000 -0.100000,-0.800000 -0.300000,-1.000000S3.300000,3.800000 2.900000,3.800000L1.800000,3.800000L1.800000,6.500000z"/>
diff --git a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_disconnected.xml b/packages/SystemUI/res/drawable/stat_sys_wifi_signal_disconnected.xml
deleted file mode 100644
index 8e626e9..0000000
--- a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_disconnected.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<!--
-    Copyright (C) 2016 The Android Open Source Project
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="18.41dp"
-        android:height="17dp"
-        android:viewportWidth="26.0"
-        android:viewportHeight="24.0">
-    <path
-        android:fillColor="?attr/backgroundColor"
-        android:pathData="M21.0,8.5
-        c0.85,0.0 1.6,0.23 2.3,0.62l2.24,-2.79
-        C25.1,5.96 20.26,2.0 13.0,2.0
-        S0.9,5.9 0.42,6.32
-        l12.57,15.6 4.21,-5.17
-        c-0.76,-0.87 -1.22,-2.0 -1.22,-3.25
-        c0.0,-2.76 2.24,-5.0 5.0,-5.0z"/>
-    <path
-        android:fillColor="?attr/backgroundColor"
-        android:pathData="M21.0,10.0
-        c-1.93,0.0 -3.5,1.57 -3.5,3.5l1.75,0.0
-        c0.0,-0.9 0.78,-1.75 1.75,-1.75s1.7,0.78 1.75,1.75
-        c0.0,0.48 -0.2,0.92 -0.51,1.24l-1.09,1.1
-        c-0.6,0.63 -1.02,1.51 -1.02,2.47l0.0,0.44l1.75,0.0
-        c0.0,-1.3 0.39,-1.84 1.03,-2.47l0.78,-0.8
-        c0.5,-0.5 0.82,-1.2 0.82,-1.97
-        C24.5,11.57 22.93,10.0 21.0,10.0z
-        m-0.95,11.95l1.9,0.0l0.0,-1.9l-1.9,0.0l0.0,1.9z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_null.xml b/packages/SystemUI/res/drawable/stat_sys_wifi_signal_null.xml
index c1856fa..5169de4 100644
--- a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_null.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_wifi_signal_null.xml
@@ -20,8 +20,5 @@
         android:viewportHeight="24.0">
     <path
         android:fillColor="?attr/backgroundColor"
-        android:pathData="M17.500000,16.500000L5.800000,3.400000c0.000000,0.000000 0.000000,0.000000 0.000000,0.000000l-2.700000,-3.000000L1.600000,1.800000l2.200000,2.500000c-2.000000,1.000000 -3.200000,2.000000 -3.400000,2.200000L13.000000,22.000000l0.000000,0.000000l0.000000,0.000000l0.000000,0.000000l0.000000,0.000000l3.200000,-3.900000l2.400000,2.700000l1.500000,-1.400000L17.500000,16.500000L17.500000,16.500000z"/>
-    <path
-        android:fillColor="?attr/backgroundColor"
-        android:pathData="M25.600000,6.500000C25.100000,6.100000 20.299999,2.100000 13.000000,2.100000c-1.900000,0.000000 -3.600000,0.300000 -5.200000,0.700000L18.700001,15.000000L25.600000,6.500000z"/>
+        android:pathData="M13.000000,2.000000C7.700000,2.000000 3.700000,3.900000 0.400000,6.400000L13.000000,22.000000L25.600000,6.500000C22.299999,4.000000 18.299999,2.000000 13.000000,2.000000zM13.000000,18.600000L3.300000,7.000000l0.000000,0.000000l0.000000,0.000000C6.000000,5.300000 8.700000,4.000000 13.000000,4.000000s7.000000,1.400000 9.700000,3.000000l0.000000,0.000000l0.000000,0.000000L13.000000,18.600000z"/>
 </vector>
diff --git a/packages/SystemUI/res/layout/mobile_signal_group.xml b/packages/SystemUI/res/layout/mobile_signal_group.xml
index 6d4365c..33effba 100644
--- a/packages/SystemUI/res/layout/mobile_signal_group.xml
+++ b/packages/SystemUI/res/layout/mobile_signal_group.xml
@@ -63,21 +63,20 @@
             systemui:hasOverlappingRendering="false"
             />
         <ImageView
-            android:id="@+id/mobile_roaming"
+            android:id="@+id/mobile_type"
             android:layout_height="wrap_content"
             android:layout_width="wrap_content"
-            android:src="@drawable/stat_sys_roaming"
-            android:contentDescription="@string/accessibility_data_connection_roaming"
-            android:visibility="gone"
             />
         <ImageView
-            android:id="@+id/mobile_type"
+            android:id="@+id/mobile_roaming"
             android:layout_width="wrap_content"
             android:layout_height="17dp"
-            android:paddingStart="19dp"
+            android:paddingStart="22dp"
             android:paddingTop="1.5dp"
             android:paddingBottom="3dp"
             android:scaleType="fitCenter"
+            android:src="@drawable/stat_sys_roaming"
+            android:contentDescription="@string/accessibility_data_connection_roaming"
             android:visibility="gone" />
     </FrameLayout>
 </LinearLayout>
diff --git a/packages/SystemUI/res/layout/signal_cluster_view.xml b/packages/SystemUI/res/layout/signal_cluster_view.xml
index 5df50cd..9a97d60 100644
--- a/packages/SystemUI/res/layout/signal_cluster_view.xml
+++ b/packages/SystemUI/res/layout/signal_cluster_view.xml
@@ -53,54 +53,9 @@
             android:alpha="0.0"
             />
     </FrameLayout>
-    <ViewStub
-        android:id="@+id/connected_device_signals_stub"
-        android:layout="@layout/connected_device_signal"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content" />
-    <LinearLayout
-        android:id="@+id/mobile_signal_group"
-        android:layout_height="wrap_content"
-        android:layout_width="wrap_content"
-        >
-    </LinearLayout>
-    <View
-        android:id="@+id/wifi_signal_spacer"
-        android:layout_width="@dimen/status_bar_wifi_signal_spacer_width"
-        android:layout_height="4dp"
-        android:visibility="gone"
-        />
-    <FrameLayout
-        android:id="@+id/no_sims_combo"
-        android:layout_height="wrap_content"
-        android:layout_width="wrap_content"
-        android:contentDescription="@string/accessibility_no_sims">
-        <com.android.systemui.statusbar.AlphaOptimizedImageView
-            android:theme="@style/DualToneLightTheme"
-            android:id="@+id/no_sims"
-            android:layout_height="wrap_content"
-            android:layout_width="wrap_content"
-            android:src="@drawable/stat_sys_no_sims"
-            />
-        <com.android.systemui.statusbar.AlphaOptimizedImageView
-            android:theme="@style/DualToneDarkTheme"
-            android:id="@+id/no_sims_dark"
-            android:layout_height="wrap_content"
-            android:layout_width="wrap_content"
-            android:src="@drawable/stat_sys_no_sims"
-            android:alpha="0.0"
-            />
-    </FrameLayout>
-    <View
-        android:id="@+id/wifi_airplane_spacer"
-        android:layout_width="@dimen/status_bar_airplane_spacer_width"
-        android:layout_height="4dp"
-        android:visibility="gone"
-        />
     <FrameLayout
         android:layout_height="17dp"
-        android:layout_width="wrap_content"
-        android:paddingStart="2dp">
+        android:layout_width="wrap_content">
         <ImageView
             android:id="@+id/wifi_in"
             android:layout_height="wrap_content"
@@ -142,6 +97,50 @@
             android:layout_width="wrap_content"
             />
     </FrameLayout>
+    <View
+        android:id="@+id/wifi_signal_spacer"
+        android:layout_width="@dimen/status_bar_wifi_signal_spacer_width"
+        android:layout_height="4dp"
+        android:visibility="gone"
+        />
+    <ViewStub
+        android:id="@+id/connected_device_signals_stub"
+        android:layout="@layout/connected_device_signal"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content" />
+    <LinearLayout
+        android:id="@+id/mobile_signal_group"
+        android:layout_height="wrap_content"
+        android:layout_width="wrap_content"
+        >
+    </LinearLayout>
+    <FrameLayout
+        android:id="@+id/no_sims_combo"
+        android:layout_height="wrap_content"
+        android:layout_width="wrap_content"
+        android:contentDescription="@string/accessibility_no_sims">
+        <com.android.systemui.statusbar.AlphaOptimizedImageView
+            android:theme="@style/DualToneLightTheme"
+            android:id="@+id/no_sims"
+            android:layout_height="wrap_content"
+            android:layout_width="wrap_content"
+            android:src="@drawable/stat_sys_no_sims"
+            />
+        <com.android.systemui.statusbar.AlphaOptimizedImageView
+            android:theme="@style/DualToneDarkTheme"
+            android:id="@+id/no_sims_dark"
+            android:layout_height="wrap_content"
+            android:layout_width="wrap_content"
+            android:src="@drawable/stat_sys_no_sims"
+            android:alpha="0.0"
+            />
+    </FrameLayout>
+    <View
+        android:id="@+id/wifi_airplane_spacer"
+        android:layout_width="@dimen/status_bar_airplane_spacer_width"
+        android:layout_height="4dp"
+        android:visibility="gone"
+        />
     <ImageView
         android:id="@+id/airplane"
         android:layout_height="wrap_content"
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockAccessibilityDelegate.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockAccessibilityDelegate.java
new file mode 100644
index 0000000..80509a6
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockAccessibilityDelegate.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.keyguard;
+
+import android.content.Context;
+import android.text.TextUtils;
+import android.view.View;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityNodeInfo;
+import android.widget.TextView;
+
+/**
+ * Replaces fancy colons with regular colons. Only works on TextViews.
+ */
+class KeyguardClockAccessibilityDelegate extends View.AccessibilityDelegate {
+    private final String mFancyColon;
+
+    public KeyguardClockAccessibilityDelegate(Context context) {
+        mFancyColon = context.getString(R.string.keyguard_fancy_colon);
+    }
+
+    @Override
+    public void onInitializeAccessibilityEvent(View host, AccessibilityEvent event) {
+        super.onInitializeAccessibilityEvent(host, event);
+        CharSequence text = event.getContentDescription();
+        if (!TextUtils.isEmpty(text)) {
+            event.setContentDescription(replaceFancyColon(text));
+        }
+    }
+
+    @Override
+    public void onPopulateAccessibilityEvent(View host, AccessibilityEvent event) {
+        CharSequence text = ((TextView) host).getText();
+        if (!TextUtils.isEmpty(text)) {
+            event.getText().add(replaceFancyColon(text));
+        }
+    }
+
+    @Override
+    public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
+        super.onInitializeAccessibilityNodeInfo(host, info);
+        if (!TextUtils.isEmpty(info.getText())) {
+            info.setText(replaceFancyColon(info.getText()));
+        }
+        if (!TextUtils.isEmpty(info.getContentDescription())) {
+            info.setContentDescription(replaceFancyColon(info.getContentDescription()));
+        }
+    }
+
+    private CharSequence replaceFancyColon(CharSequence text) {
+        return text.toString().replace(mFancyColon, ":");
+    }
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
index 162faa5..d4d69ff 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
@@ -38,7 +38,6 @@
 import com.android.internal.widget.LockPatternUtils;
 import com.android.systemui.ChargingView;
 
-import java.util.Arrays;
 import java.util.Locale;
 
 public class KeyguardStatusView extends GridLayout {
@@ -121,6 +120,7 @@
         mClockView = findViewById(R.id.clock_view);
         mDateView.setShowCurrentUserTime(true);
         mClockView.setShowCurrentUserTime(true);
+        mClockView.setAccessibilityDelegate(new KeyguardClockAccessibilityDelegate(mContext));
         mOwnerInfo = findViewById(R.id.owner_info);
         mBatteryDoze = findViewById(R.id.battery_doze);
         mVisibleInDoze = new View[]{mBatteryDoze, mClockView};
diff --git a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
index 8c4159a..9c03ea6 100644
--- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
@@ -51,7 +51,7 @@
     public static final int X = 0;
     public static final int Y = 1;
 
-    private float SWIPE_ESCAPE_VELOCITY = 100f; // dp/sec
+    private float SWIPE_ESCAPE_VELOCITY = 500f; // dp/sec
     private int DEFAULT_ESCAPE_ANIMATION_DURATION = 200; // ms
     private int MAX_ESCAPE_ANIMATION_DURATION = 400; // ms
     private int MAX_DISMISS_VELOCITY = 4000; // dp/sec
@@ -59,6 +59,9 @@
 
     static final float SWIPE_PROGRESS_FADE_END = 0.5f; // fraction of thumbnail width
                                               // beyond which swipe progress->0
+    public static final float SWIPED_FAR_ENOUGH_SIZE_FRACTION = 0.6f;
+    static final float MAX_SCROLL_SIZE_FRACTION = 0.3f;
+
     private float mMinSwipeProgress = 0f;
     private float mMaxSwipeProgress = 1f;
 
@@ -363,9 +366,8 @@
         // if the language is rtl we prefer swiping to the left
         boolean animateLeftForRtl = velocity == 0 && (getTranslation(animView) == 0 || isDismissAll)
                 && isLayoutRtl;
-        boolean animateLeft = velocity < 0
-                || (velocity == 0 && getTranslation(animView) < 0 && !isDismissAll);
-
+        boolean animateLeft = (Math.abs(velocity) > getEscapeVelocity() && velocity < 0) ||
+                (getTranslation(animView) < 0 && !isDismissAll);
         if (animateLeft || animateLeftForRtl || animateUpForMenu) {
             newPos = -getSize(animView);
         } else {
@@ -584,7 +586,7 @@
                     // maxScrollDistance
                     if (CONSTRAIN_SWIPE && !mCallback.canChildBeDismissed(mCurrView)) {
                         float size = getSize(mCurrView);
-                        float maxScrollDistance = 0.25f * size;
+                        float maxScrollDistance = MAX_SCROLL_SIZE_FRACTION * size;
                         if (absDelta >= size) {
                             delta = delta > 0 ? maxScrollDistance : -maxScrollDistance;
                         } else {
@@ -646,7 +648,8 @@
 
     protected boolean swipedFarEnough() {
         float translation = getTranslation(mCurrView);
-        return DISMISS_IF_SWIPED_FAR_ENOUGH && Math.abs(translation) > 0.4 * getSize(mCurrView);
+        return DISMISS_IF_SWIPED_FAR_ENOUGH
+                && Math.abs(translation) > SWIPED_FAR_ENOUGH_SIZE_FRACTION * getSize(mCurrView);
     }
 
     public boolean isDismissGesture(MotionEvent ev) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
index e457d72..7518527a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
@@ -77,9 +77,6 @@
 
         BatteryMeterView battery = findViewById(R.id.battery);
         battery.setForceShowPercent(true);
-        // Don't show the Wi-Fi indicator here, because it is shown just below in the tile.
-        SignalClusterView signalCluster = findViewById(R.id.signal_cluster);
-        signalCluster.setForceBlockWifi();
 
         mActivityStarter = Dependency.get(ActivityStarter.class);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
index d74e3ac..92ff17a1 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
@@ -128,7 +128,7 @@
         state.value = mDataController.isMobileDataSupported()
                 && mDataController.isMobileDataEnabled();
         state.icon = ResourceIcon.get(R.drawable.ic_data_unavailable);
-        state.state = cb.airplaneModeEnabled || !cb.enabled || cb.noSim ? Tile.STATE_UNAVAILABLE
+        state.state = cb.airplaneModeEnabled || !cb.enabled ? Tile.STATE_UNAVAILABLE
                 : state.value ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
         if (state.state == Tile.STATE_ACTIVE) {
             state.icon = ResourceIcon.get(R.drawable.ic_data_on);
@@ -161,27 +161,44 @@
 
     private static final class CallbackInfo {
         boolean enabled;
+        boolean wifiEnabled;
         boolean airplaneModeEnabled;
+        String signalContentDescription;
+        int dataTypeIconId;
+        String dataContentDescription;
         boolean activityIn;
         boolean activityOut;
+        String enabledDesc;
         boolean noSim;
+        boolean isDataTypeIconWide;
         boolean roaming;
     }
 
     private final class CellSignalCallback implements SignalCallback {
         private final CallbackInfo mInfo = new CallbackInfo();
+        @Override
+        public void setWifiIndicators(boolean enabled, IconState statusIcon, IconState qsIcon,
+                boolean activityIn, boolean activityOut, String description, boolean isTransient) {
+            mInfo.wifiEnabled = enabled;
+            refreshState(mInfo);
+        }
 
         @Override
-        public void setMobileDataIndicators(IconState statusIcon, int statusType,
-                boolean activityIn, boolean activityOut, String typeContentDescription,
-                int subId, boolean roaming, boolean isEmergency) {
-            if (statusIcon == null) {
+        public void setMobileDataIndicators(IconState statusIcon, IconState qsIcon, int statusType,
+                int qsType, boolean activityIn, boolean activityOut, String typeContentDescription,
+                String description, boolean isWide, int subId, boolean roaming) {
+            if (qsIcon == null) {
                 // Not data sim, don't display.
                 return;
             }
-            mInfo.enabled = statusIcon.visible;
+            mInfo.enabled = qsIcon.visible;
+            mInfo.signalContentDescription = qsIcon.contentDescription;
+            mInfo.dataTypeIconId = qsType;
+            mInfo.dataContentDescription = typeContentDescription;
             mInfo.activityIn = activityIn;
             mInfo.activityOut = activityOut;
+            mInfo.enabledDesc = description;
+            mInfo.isDataTypeIconWide = qsType != 0 && isWide;
             mInfo.roaming = roaming;
             refreshState(mInfo);
         }
@@ -189,6 +206,15 @@
         @Override
         public void setNoSims(boolean show) {
             mInfo.noSim = show;
+            if (mInfo.noSim) {
+                // Make sure signal gets cleared out when no sims.
+                mInfo.dataTypeIconId = 0;
+                // Show a No SIMs description to avoid emergency calls message.
+                mInfo.enabled = true;
+                mInfo.enabledDesc = mContext.getString(
+                        R.string.keyguard_missing_sim_message_short);
+                mInfo.signalContentDescription = mInfo.enabledDesc;
+            }
             refreshState(mInfo);
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java
index 7563fd1..4305bdef 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java
@@ -16,13 +16,13 @@
 
 package com.android.systemui.statusbar;
 
+import static com.android.systemui.SwipeHelper.SWIPED_FAR_ENOUGH_SIZE_FRACTION;
+
 import java.util.ArrayList;
 
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
-import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin.MenuItem;
-import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin.OnMenuEventListener;
 import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper;
 import com.android.systemui.statusbar.NotificationGuts.GutsContent;
 import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
@@ -46,10 +46,21 @@
 
 public class NotificationMenuRow implements NotificationMenuRowPlugin, View.OnClickListener {
 
+    private static final boolean DEBUG = false;
+    private static final String TAG = "swipe";
+
     private static final int ICON_ALPHA_ANIM_DURATION = 200;
     private static final long SHOW_MENU_DELAY = 60;
     private static final long SWIPE_MENU_TIMING = 200;
 
+    // Notification must be swiped at least this fraction of a single menu item to show menu
+    private static final float SWIPED_FAR_ENOUGH_MENU_FRACTION = 0.25f;
+    private static final float SWIPED_FAR_ENOUGH_MENU_UNCLEARABLE_FRACTION = 0.15f;
+
+    // When the menu is displayed, the notification must be swiped within this fraction of a single
+    // menu item to snap back to menu (else it will cover the menu or it'll be dismissed)
+    private static final float SWIPED_BACK_ENOUGH_TO_COVER_FRACTION = 0.2f;
+
     private ExpandableNotificationRow mParent;
 
     private Context mContext;
@@ -78,6 +89,7 @@
     private int mIconPadding;
 
     private float mAlpha = 0f;
+    private float mPrevX;
 
     private CheckForDrag mCheckForDrag;
     private Handler mHandler;
@@ -203,14 +215,14 @@
                 }
                 mHandler.removeCallbacks(mCheckForDrag);
                 mCheckForDrag = null;
+                mPrevX = ev.getRawX();
                 break;
 
             case MotionEvent.ACTION_MOVE:
                 mSnapping = false;
-                // If the menu is visible and the movement is towards it it's not a location change.
-                boolean locationChange = isTowardsMenu(mTranslation)
-                        ? false : isMenuLocationChange();
-                if (locationChange) {
+                float diffX = ev.getRawX() - mPrevX;
+                mPrevX = ev.getRawX();
+                if (!isTowardsMenu(diffX) && isMenuLocationChange()) {
                     // Don't consider it "snapped" if location has changed.
                     mMenuSnappedTo = false;
 
@@ -262,36 +274,53 @@
         final double timeForGesture = ev.getEventTime() - ev.getDownTime();
         final boolean showMenuForSlowOnGoing = !mParent.canViewBeDismissed()
                 && timeForGesture >= SWIPE_MENU_TIMING;
+        final float menuSnapTarget = mOnLeft ? getSpaceForMenu() : -getSpaceForMenu();
 
-        final float targetLeft = mOnLeft ? getSpaceForMenu() : -getSpaceForMenu();
-        if (mMenuSnappedTo && isMenuVisible()) {
-            if (mMenuSnappedOnLeft == mOnLeft) {
-                boolean coveringMenu = Math.abs(mTranslation) <= getSpaceForMenu() * 0.6f;
-                if (gestureTowardsMenu || coveringMenu) {
-                    // Gesture is towards or covering the menu or a dismiss
-                    snapBack(animView, 0);
-                } else if (mSwipeHelper.isDismissGesture(ev)) {
-                    dismiss(animView, velocity);
-                } else {
-                    // Didn't move enough to dismiss or cover, snap to the menu
-                    showMenu(animView, targetLeft, velocity);
-                }
-            } else if ((!gestureFastEnough && swipedEnoughToShowMenu())
-                    || (gestureTowardsMenu && !gestureFarEnough)) {
-                // The menu has been snapped to previously, however, the menu is now on the
-                // other side. If gesture is towards menu and not too far snap to the menu.
-                showMenu(animView, targetLeft, velocity);
-            } else if (mSwipeHelper.isDismissGesture(ev)) {
+        if (DEBUG) {
+            Log.d(TAG, "mTranslation= " + mTranslation
+                    + " mAlpha= " + mAlpha
+                    + " velocity= " + velocity
+                    + " mMenuSnappedTo= " + mMenuSnappedTo
+                    + " mMenuSnappedOnLeft= " + mMenuSnappedOnLeft
+                    + " mOnLeft= " + mOnLeft
+                    + " minDismissVel= " + mSwipeHelper.getMinDismissVelocity()
+                    + " isDismissGesture= " + mSwipeHelper.isDismissGesture(ev)
+                    + " gestureTowardsMenu= " + gestureTowardsMenu
+                    + " gestureFastEnough= " + gestureFastEnough
+                    + " gestureFarEnough= " + gestureFarEnough);
+        }
+
+        if (mMenuSnappedTo && isMenuVisible() && mMenuSnappedOnLeft == mOnLeft) {
+            // Menu was snapped to previously and we're on the same side, figure out if
+            // we should stick to the menu, snap back into place, or dismiss
+            final float maximumSwipeDistance = mHorizSpaceForIcon
+                    * SWIPED_BACK_ENOUGH_TO_COVER_FRACTION;
+            final float targetLeft = getSpaceForMenu() - maximumSwipeDistance;
+            final float targetRight = mParent.getWidth() * SWIPED_FAR_ENOUGH_SIZE_FRACTION;
+            boolean withinSnapMenuThreshold = mOnLeft
+                    ? mTranslation > targetLeft && mTranslation < targetRight
+                    : mTranslation < -targetLeft && mTranslation > -targetRight;
+            boolean shouldSnapTo = mOnLeft ? mTranslation < targetLeft : mTranslation > -targetLeft;
+            if (DEBUG) {
+                Log.d(TAG, "   withinSnapMenuThreshold= " + withinSnapMenuThreshold
+                        + "   shouldSnapTo= " + shouldSnapTo
+                        + "   targetLeft= " + targetLeft
+                        + "   targetRight= " + targetRight);
+            }
+            if (withinSnapMenuThreshold && !mSwipeHelper.isDismissGesture(ev)) {
+                // Haven't moved enough to unsnap from the menu
+                showMenu(animView, menuSnapTarget, velocity);
+            } else if (mSwipeHelper.isDismissGesture(ev) && !shouldSnapTo) {
+                // Only dismiss if we're not moving towards the menu
                 dismiss(animView, velocity);
             } else {
                 snapBack(animView, velocity);
             }
-        } else if (((!gestureFastEnough || showMenuForSlowOnGoing)
-                && swipedEnoughToShowMenu())
-                || gestureTowardsMenu) {
+        } else if ((swipedEnoughToShowMenu() && (!gestureFastEnough || showMenuForSlowOnGoing))
+                || (gestureTowardsMenu && !mSwipeHelper.isDismissGesture(ev))) {
             // Menu has not been snapped to previously and this is menu revealing gesture
-            showMenu(animView, targetLeft, velocity);
-        } else if (mSwipeHelper.isDismissGesture(ev)) {
+            showMenu(animView, menuSnapTarget, velocity);
+        } else if (mSwipeHelper.isDismissGesture(ev) && !gestureTowardsMenu) {
             dismiss(animView, velocity);
         } else {
             snapBack(animView, velocity);
@@ -326,14 +355,18 @@
         mSwipeHelper.dismiss(animView, velocity);
     }
 
+    /**
+     * @return whether the notification has been translated enough to show the menu and not enough
+     *         to be dismissed.
+     */
     private boolean swipedEnoughToShowMenu() {
-        // If the notification can't be dismissed then how far it can move is
-        // restricted -- reduce the distance it needs to move in this case.
-        final float multiplier = mParent.canViewBeDismissed() ? 0.4f : 0.2f;
-        final float snapBackThreshold = getSpaceForMenu() * multiplier;
-        return !mSwipeHelper.swipedFarEnough(0, 0) && isMenuVisible() && (mOnLeft
-                ? mTranslation > snapBackThreshold
-                : mTranslation < -snapBackThreshold);
+        final float multiplier = mParent.canViewBeDismissed()
+                ? SWIPED_FAR_ENOUGH_MENU_FRACTION
+                : SWIPED_FAR_ENOUGH_MENU_UNCLEARABLE_FRACTION;
+        final float minimumSwipeDistance = mHorizSpaceForIcon * multiplier;
+        return !mSwipeHelper.swipedFarEnough(0, 0) && isMenuVisible()
+                && (mOnLeft ? mTranslation > minimumSwipeDistance
+                        : mTranslation < -minimumSwipeDistance);
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
index b01d9cc..dc254f9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
@@ -24,6 +24,8 @@
 import android.content.res.TypedArray;
 import android.graphics.Color;
 import android.graphics.Rect;
+import android.graphics.drawable.Animatable;
+import android.graphics.drawable.AnimatedVectorDrawable;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.LayerDrawable;
 import android.telephony.SubscriptionInfo;
@@ -118,7 +120,6 @@
     private boolean mBlockWifi;
     private boolean mBlockEthernet;
     private boolean mActivityEnabled;
-    private boolean mForceBlockWifi;
 
     public SignalClusterView(Context context) {
         this(context, null);
@@ -150,16 +151,6 @@
         updateActivityEnabled();
     }
 
-    public void setForceBlockWifi() {
-        mForceBlockWifi = true;
-        mBlockWifi = true;
-        if (isAttachedToWindow()) {
-            // Re-register to get new callbacks.
-            mNetworkController.removeCallback(this);
-            mNetworkController.addCallback(this);
-        }
-    }
-
     @Override
     public void onTuningChanged(String key, String newValue) {
         if (!StatusBarIconController.ICON_BLACKLIST.equals(key)) {
@@ -176,7 +167,7 @@
             mBlockAirplane = blockAirplane;
             mBlockMobile = blockMobile;
             mBlockEthernet = blockEthernet;
-            mBlockWifi = blockWifi || mForceBlockWifi;
+            mBlockWifi = blockWifi;
             // Re-register to get new callbacks.
             mNetworkController.removeCallback(this);
             mNetworkController.addCallback(this);
@@ -297,9 +288,9 @@
     }
 
     @Override
-    public void setMobileDataIndicators(IconState statusIcon, int statusType,
-            boolean activityIn, boolean activityOut, String typeContentDescription,
-            int subId, boolean roaming, boolean isEmergency) {
+    public void setMobileDataIndicators(IconState statusIcon, IconState qsIcon, int statusType,
+            int qsType, boolean activityIn, boolean activityOut, String typeContentDescription,
+            String description, boolean isWide, int subId, boolean roaming) {
         PhoneState state = getState(subId);
         if (state == null) {
             return;
@@ -309,6 +300,7 @@
         state.mMobileTypeId = statusType;
         state.mMobileDescription = statusIcon.contentDescription;
         state.mMobileTypeDescription = typeContentDescription;
+        state.mIsMobileTypeIconWide = statusType != 0 && isWide;
         state.mRoaming = roaming;
         state.mActivityIn = activityIn && mActivityEnabled;
         state.mActivityOut = activityOut && mActivityEnabled;
@@ -533,7 +525,7 @@
             mWifiAirplaneSpacer.setVisibility(View.GONE);
         }
 
-        if (((anyMobileVisible && firstMobileTypeId == 0) || mNoSimsVisible) && mWifiVisible) {
+        if (((anyMobileVisible && firstMobileTypeId != 0) || mNoSimsVisible) && mWifiVisible) {
             mWifiSignalSpacer.setVisibility(View.VISIBLE);
         } else {
             mWifiSignalSpacer.setVisibility(View.GONE);
@@ -644,6 +636,7 @@
         private int mMobileStrengthId = 0, mMobileTypeId = 0;
         private int mLastMobileStrengthId = -1;
         private int mLastMobileTypeId = -1;
+        private boolean mIsMobileTypeIconWide;
         private String mMobileDescription, mMobileTypeDescription;
 
         private ViewGroup mMobileGroup;
@@ -699,8 +692,12 @@
             // When this isn't next to wifi, give it some extra padding between the signals.
             mMobileGroup.setPaddingRelative(isSecondaryIcon ? mSecondaryTelephonyPadding : 0,
                     0, 0, 0);
-            mMobile.setPaddingRelative(mMobileDataIconStartPadding, 0, 0, 0);
-            mMobileDark.setPaddingRelative(mMobileDataIconStartPadding, 0, 0, 0);
+            mMobile.setPaddingRelative(
+                    mIsMobileTypeIconWide ? mWideTypeIconStartPadding : mMobileDataIconStartPadding,
+                    0, 0, 0);
+            mMobileDark.setPaddingRelative(
+                    mIsMobileTypeIconWide ? mWideTypeIconStartPadding : mMobileDataIconStartPadding,
+                    0, 0, 0);
 
             if (DEBUG) Log.d(TAG, String.format("mobile: %s sig=%d typ=%d",
                         (mMobileVisible ? "VISIBLE" : "GONE"), mMobileStrengthId, mMobileTypeId));
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SignalDrawable.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SignalDrawable.java
index 6361eb6..a9eb20b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SignalDrawable.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SignalDrawable.java
@@ -57,12 +57,12 @@
     private static final int LEVEL_MASK = 0xff;
     private static final int NUM_LEVEL_SHIFT = 8;
     private static final int NUM_LEVEL_MASK = 0xff << NUM_LEVEL_SHIFT;
-    public static final int STATE_SHIFT = 16;
-    public static final int STATE_MASK = 0xff << STATE_SHIFT;
-    public static final int STATE_NONE = 0;
-    public static final int STATE_EMPTY = 1;
-    public static final int STATE_CUT = 2;
-    public static final int STATE_CARRIER_CHANGE = 3;
+    private static final int STATE_SHIFT = 16;
+    private static final int STATE_MASK = 0xff << STATE_SHIFT;
+    private static final int STATE_NONE = 0;
+    private static final int STATE_EMPTY = 1;
+    private static final int STATE_CUT = 2;
+    private static final int STATE_CARRIER_CHANGE = 3;
 
     private static final long DOT_DELAY = 1000;
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CallbackHandler.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CallbackHandler.java
index e98dc98..a456786 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CallbackHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CallbackHandler.java
@@ -110,24 +110,30 @@
     public void setWifiIndicators(final boolean enabled, final IconState statusIcon,
             final IconState qsIcon, final boolean activityIn, final boolean activityOut,
             final String description, boolean isTransient) {
-        post(() -> {
-            for (SignalCallback callback : mSignalCallbacks) {
-                callback.setWifiIndicators(enabled, statusIcon, qsIcon, activityIn, activityOut,
-                        description, isTransient);
+        post(new Runnable() {
+            @Override
+            public void run() {
+                for (SignalCallback callback : mSignalCallbacks) {
+                    callback.setWifiIndicators(enabled, statusIcon, qsIcon, activityIn, activityOut,
+                            description, isTransient);
+                }
             }
         });
     }
 
     @Override
-    public void setMobileDataIndicators(final IconState statusIcon,
-            final int statusType, final boolean activityIn,
+    public void setMobileDataIndicators(final IconState statusIcon, final IconState qsIcon,
+            final int statusType, final int qsType,final boolean activityIn,
             final boolean activityOut, final String typeContentDescription,
-            final int subId, boolean roaming, boolean isEmergency) {
-        post(() -> {
-            for (SignalCallback signalCluster : mSignalCallbacks) {
-                signalCluster.setMobileDataIndicators(statusIcon, statusType,
-                        activityIn, activityOut, typeContentDescription,
-                        subId, roaming, isEmergency);
+            final String description, final boolean isWide, final int subId, boolean roaming) {
+        post(new Runnable() {
+            @Override
+            public void run() {
+                for (SignalCallback signalCluster : mSignalCallbacks) {
+                    signalCluster.setMobileDataIndicators(statusIcon, qsIcon, statusType, qsType,
+                            activityIn, activityOut, typeContentDescription, description, isWide,
+                            subId, roaming);
+                }
             }
         });
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
index 4421a6a..67b5596 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
@@ -244,8 +244,7 @@
             return SignalDrawable.getCarrierChangeState(getNumLevels());
         } else if (mCurrentState.connected) {
             return SignalDrawable.getState(mCurrentState.level, getNumLevels(),
-                    mCurrentState.inetCondition == 0 ||
-                            (mCurrentState.dataDisabled && mCurrentState.userSetup));
+                    mCurrentState.inetCondition == 0);
         } else if (mCurrentState.enabled) {
             return SignalDrawable.getEmptyState(getNumLevels());
         } else {
@@ -264,14 +263,24 @@
 
         String contentDescription = getStringIfExists(getContentDescription());
         String dataContentDescription = getStringIfExists(icons.mDataContentDescription);
-        final boolean dataDisabled = mCurrentState.dataDisabled
+        final boolean dataDisabled = mCurrentState.iconGroup == TelephonyIcons.DATA_DISABLED
                 && mCurrentState.userSetup;
 
         // Show icon in QS when we are connected or data is disabled.
-        boolean showDataIcon = mCurrentState.dataConnected;
+        boolean showDataIcon = mCurrentState.dataConnected || dataDisabled;
         IconState statusIcon = new IconState(mCurrentState.enabled && !mCurrentState.airplaneMode,
                 getCurrentIconId(), contentDescription);
 
+        int qsTypeIcon = 0;
+        IconState qsIcon = null;
+        String description = null;
+        // Only send data sim callbacks to QS.
+        if (mCurrentState.dataSim) {
+            qsTypeIcon = showDataIcon ? icons.mQsDataType : 0;
+            qsIcon = new IconState(mCurrentState.enabled
+                    && !mCurrentState.isEmergency, getQsCurrentIconId(), contentDescription);
+            description = mCurrentState.isEmergency ? null : mCurrentState.networkName;
+        }
         boolean activityIn = mCurrentState.dataConnected
                 && !mCurrentState.carrierNetworkChangeMode
                 && mCurrentState.activityIn;
@@ -280,10 +289,9 @@
                 && mCurrentState.activityOut;
         showDataIcon &= mCurrentState.isDefault || dataDisabled;
         int typeIcon = showDataIcon ? icons.mDataType : 0;
-        callback.setMobileDataIndicators(statusIcon, typeIcon,
-                activityIn, activityOut, dataContentDescription,
-                mSubscriptionInfo.getSubscriptionId(), mCurrentState.roaming,
-                mCurrentState.isEmergency);
+        callback.setMobileDataIndicators(statusIcon, qsIcon, typeIcon, qsTypeIcon,
+                activityIn, activityOut, dataContentDescription, description, icons.mIsWide,
+                mSubscriptionInfo.getSubscriptionId(), mCurrentState.roaming);
     }
 
     @Override
@@ -430,14 +438,14 @@
         } else {
             mCurrentState.iconGroup = mDefaultIcons;
         }
-        mCurrentState.dataDisabled = isDataDisabled();
         mCurrentState.dataConnected = mCurrentState.connected
-                && mDataState == TelephonyManager.DATA_CONNECTED
-                && !mCurrentState.dataDisabled;
+                && mDataState == TelephonyManager.DATA_CONNECTED;
 
         mCurrentState.roaming = isRoaming();
         if (isCarrierNetworkChangeActive()) {
             mCurrentState.iconGroup = TelephonyIcons.CARRIER_NETWORK_CHANGE;
+        } else if (isDataDisabled()) {
+            mCurrentState.iconGroup = TelephonyIcons.DATA_DISABLED;
         }
         if (isEmergencyOnly() != mCurrentState.isEmergency) {
             mCurrentState.isEmergency = isEmergencyOnly();
@@ -569,7 +577,6 @@
         boolean isDefault;
         boolean userSetup;
         boolean roaming;
-        boolean dataDisabled;
 
         @Override
         public void copyFrom(State s) {
@@ -585,7 +592,6 @@
             carrierNetworkChangeMode = state.carrierNetworkChangeMode;
             userSetup = state.userSetup;
             roaming = state.roaming;
-            dataDisabled = state.dataDisabled;
         }
 
         @Override
@@ -603,7 +609,6 @@
             builder.append("carrierNetworkChangeMode=").append(carrierNetworkChangeMode)
                     .append(',');
             builder.append("userSetup=").append(userSetup);
-            builder.append("dataDisabled=").append(dataDisabled);
         }
 
         @Override
@@ -618,7 +623,6 @@
                     && ((MobileState) o).carrierNetworkChangeMode == carrierNetworkChangeMode
                     && ((MobileState) o).userSetup == userSetup
                     && ((MobileState) o).isDefault == isDefault
-                    && ((MobileState) o).dataDisabled == dataDisabled
                     && ((MobileState) o).roaming == roaming;
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
index ab4a8f2..c02ce0e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
@@ -48,9 +48,9 @@
         default void setWifiIndicators(boolean enabled, IconState statusIcon, IconState qsIcon,
                 boolean activityIn, boolean activityOut, String description, boolean isTransient) {}
 
-        default void setMobileDataIndicators(IconState statusIcon, int statusType,
-                boolean activityIn, boolean activityOut, String typeContentDescription,
-                int subId, boolean roaming, boolean isEmergency) {}
+        default void setMobileDataIndicators(IconState statusIcon, IconState qsIcon, int statusType,
+                int qsType, boolean activityIn, boolean activityOut, String typeContentDescription,
+                String description, boolean isWide, int subId, boolean roaming) {}
         default void setSubs(List<SubscriptionInfo> subs) {}
         default void setNoSims(boolean show) {}
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index 60f4ab8..c21f444 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -867,6 +867,7 @@
                             datatype.equals("h") ? TelephonyIcons.H :
                             datatype.equals("lte") ? TelephonyIcons.LTE :
                             datatype.equals("lte+") ? TelephonyIcons.LTE_PLUS :
+                            datatype.equals("dis") ? TelephonyIcons.DATA_DISABLED :
                             TelephonyIcons.UNKNOWN;
                 }
                 if (args.containsKey("roam")) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java
index ec7e557..aaa0568 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java
@@ -44,6 +44,10 @@
     static final int ICON_4G_PLUS = R.drawable.stat_sys_data_fully_connected_4g_plus;
     static final int ICON_1X = R.drawable.stat_sys_data_fully_connected_1x;
 
+    static final int ICON_DATA_DISABLED = R.drawable.stat_sys_data_disabled;
+
+    static final int QS_ICON_DATA_DISABLED = R.drawable.ic_qs_data_disabled;
+
     static final MobileIconGroup CARRIER_NETWORK_CHANGE = new MobileIconGroup(
             "CARRIER_NETWORK_CHANGE",
             null,
@@ -217,5 +221,20 @@
             true,
             TelephonyIcons.QS_DATA_LTE_PLUS
             );
+
+    static final MobileIconGroup DATA_DISABLED = new MobileIconGroup(
+            "DataDisabled",
+            null,
+            null,
+            AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH,
+            0, 0,
+            0,
+            0,
+            AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[0],
+            R.string.accessibility_cell_data_off,
+            TelephonyIcons.ICON_DATA_DISABLED,
+            false,
+            TelephonyIcons.QS_ICON_DATA_DISABLED
+            );
 }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiIcons.java
index dfc3591..374408d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiIcons.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiIcons.java
@@ -47,7 +47,6 @@
 
     static final int QS_WIFI_NO_NETWORK = R.drawable.ic_qs_wifi_no_network;
     static final int WIFI_NO_NETWORK = R.drawable.stat_sys_wifi_signal_null;
-    static final int WIFI_DISCONNECTED = R.drawable.stat_sys_wifi_signal_disconnected;
 
     static final int WIFI_LEVEL_COUNT = WIFI_SIGNAL_STRENGTH[0].length;
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java
index a773acf..2104cb1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java
@@ -80,7 +80,7 @@
                 AccessibilityContentDescriptions.WIFI_CONNECTION_STRENGTH,
                 WifiIcons.WIFI_NO_NETWORK,
                 WifiIcons.QS_WIFI_NO_NETWORK,
-                WifiIcons.WIFI_DISCONNECTED,
+                WifiIcons.WIFI_NO_NETWORK,
                 WifiIcons.QS_WIFI_NO_NETWORK,
                 AccessibilityContentDescriptions.WIFI_NO_CONNECTION
                 );
@@ -133,7 +133,8 @@
     @Override
     public void notifyListeners(SignalCallback callback) {
         // only show wifi in the cluster if connected or if wifi-only
-        boolean wifiVisible = true;
+        boolean wifiVisible = mCurrentState.enabled
+                && (mCurrentState.connected || !mHasMobileData);
         String wifiDesc = wifiVisible ? mCurrentState.ssid : null;
         boolean ssidPresent = wifiVisible && mCurrentState.ssid != null;
         String contentDescription = getStringIfExists(getContentDescription());
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockAccessibilityDelegateTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockAccessibilityDelegateTest.java
new file mode 100644
index 0000000..1c9f813
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockAccessibilityDelegateTest.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.keyguard;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.content.Context;
+import android.support.test.InstrumentationRegistry;
+import android.text.TextUtils;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityNodeInfo;
+import android.widget.TextView;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.List;
+
+public class KeyguardClockAccessibilityDelegateTest {
+
+    private Context mContext;
+    private TextView mView;
+
+    @Before
+    public void setUp() throws Exception {
+        mContext = InstrumentationRegistry.getContext();
+        mView = new TextView(mContext);
+        mView.setText(R.string.keyguard_widget_12_hours_format);
+        mView.setContentDescription(mContext.getString(R.string.keyguard_widget_12_hours_format));
+        mView.setAccessibilityDelegate(new KeyguardClockAccessibilityDelegate(mContext));
+    }
+
+    @Test
+    public void onInitializeAccessibilityEvent_producesNonEmptyAsciiContentDesc() throws Exception {
+        AccessibilityEvent ev = AccessibilityEvent.obtain();
+        mView.onInitializeAccessibilityEvent(ev);
+
+        assertFalse(TextUtils.isEmpty(ev.getContentDescription()));
+        assertTrue(isAscii(ev.getContentDescription()));
+    }
+
+    @Test
+    public void onPopulateAccessibilityEvent_producesNonEmptyAsciiText() throws Exception {
+        AccessibilityEvent ev = AccessibilityEvent.obtain();
+        mView.onPopulateAccessibilityEvent(ev);
+
+        assertFalse(isEmpty(ev.getText()));
+        assertTrue(isAscii(ev.getText()));
+    }
+
+    @Test
+    public void onInitializeAccessibilityNodeInfo_producesNonEmptyAsciiText() throws Exception {
+        AccessibilityNodeInfo info = AccessibilityNodeInfo.obtain();
+        // Usually done in View.onInitializeAccessibilityNodeInfoInternal, but only when attached.
+        info.setContentDescription(mView.getContentDescription());
+        mView.onInitializeAccessibilityNodeInfo(info);
+
+        assertFalse(TextUtils.isEmpty(info.getText()));
+        assertTrue(isAscii(info.getText()));
+
+        assertFalse(TextUtils.isEmpty(info.getContentDescription()));
+        assertTrue(isAscii(info.getContentDescription()));
+    }
+
+    private boolean isAscii(CharSequence text) {
+        return text.chars().allMatch((i) -> i < 128);
+    }
+
+    private boolean isAscii(List<CharSequence> texts) {
+        return texts.stream().allMatch(this::isAscii);
+    }
+
+    private boolean isEmpty(List<CharSequence> texts) {
+        return texts.stream().allMatch(TextUtils::isEmpty);
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeConfigurationTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeConfigurationTest.java
index 048936b..bbe324d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeConfigurationTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeConfigurationTest.java
@@ -47,9 +47,8 @@
             return;
         }
 
-        mContext.getSettingsProvider().acquireOverridesBuilder()
-                .addSetting("secure", Settings.Secure.DOZE_ALWAYS_ON, null)
-                .build();
+        Settings.Secure.putString(mContext.getContentResolver(), Settings.Secure.DOZE_ALWAYS_ON,
+                null);
 
         assertFalse(mDozeConfig.alwaysOnEnabled(UserHandle.USER_CURRENT));
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CallbackHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CallbackHandlerTest.java
index f6c75a8..3ed1681 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CallbackHandlerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CallbackHandlerTest.java
@@ -114,26 +114,33 @@
         boolean wide = true;
         int subId = 5;
         boolean roaming = true;
-        boolean isEmergency = true;
-        mHandler.setMobileDataIndicators(status, type, in, out, typeDescription,
-                subId, roaming, isEmergency);
+        mHandler.setMobileDataIndicators(status, qs, type, qsType, in, out, typeDescription,
+                description, wide, subId, roaming);
         waitForCallbacks();
 
         ArgumentCaptor<IconState> statusArg = ArgumentCaptor.forClass(IconState.class);
+        ArgumentCaptor<IconState> qsArg = ArgumentCaptor.forClass(IconState.class);
         ArgumentCaptor<Integer> typeIconArg = ArgumentCaptor.forClass(Integer.class);
+        ArgumentCaptor<Integer> qsTypeIconArg = ArgumentCaptor.forClass(Integer.class);
         ArgumentCaptor<Boolean> inArg = ArgumentCaptor.forClass(Boolean.class);
         ArgumentCaptor<Boolean> outArg = ArgumentCaptor.forClass(Boolean.class);
         ArgumentCaptor<String> typeContentArg = ArgumentCaptor.forClass(String.class);
+        ArgumentCaptor<String> descArg = ArgumentCaptor.forClass(String.class);
+        ArgumentCaptor<Boolean> wideArg = ArgumentCaptor.forClass(Boolean.class);
         ArgumentCaptor<Integer> subIdArg = ArgumentCaptor.forClass(Integer.class);
         Mockito.verify(mSignalCallback).setMobileDataIndicators(statusArg.capture(),
-                typeIconArg.capture(), inArg.capture(),
-                outArg.capture(), typeContentArg.capture(),
-                subIdArg.capture(), eq(roaming), eq(isEmergency));
+                qsArg.capture(), typeIconArg.capture(), qsTypeIconArg.capture(), inArg.capture(),
+                outArg.capture(), typeContentArg.capture(), descArg.capture(), wideArg.capture(),
+                subIdArg.capture(), eq(roaming));
         assertEquals(status, statusArg.getValue());
+        assertEquals(qs, qsArg.getValue());
         assertEquals(type, (int) typeIconArg.getValue());
+        assertEquals(qsType, (int) qsTypeIconArg.getValue());
         assertEquals(in, (boolean) inArg.getValue());
         assertEquals(out, (boolean) outArg.getValue());
         assertEquals(typeDescription, typeContentArg.getValue());
+        assertEquals(description, descArg.getValue());
+        assertEquals(wide, (boolean) wideArg.getValue());
         assertEquals(subId, (int) subIdArg.getValue());
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
index b39171e..505e1d8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
@@ -29,7 +29,6 @@
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.util.Log;
-
 import com.android.internal.telephony.cdma.EriInfo;
 import com.android.settingslib.net.DataUsageController;
 import com.android.systemui.statusbar.phone.SignalDrawable;
@@ -46,6 +45,8 @@
 import org.junit.runner.Description;
 import org.mockito.ArgumentCaptor;
 import org.mockito.Mockito;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
 
 import java.io.PrintWriter;
 import java.io.StringWriter;
@@ -69,7 +70,7 @@
     protected static final int DEFAULT_SIGNAL_STRENGTH = DEFAULT_LEVEL;
     protected static final int DEFAULT_QS_SIGNAL_STRENGTH = DEFAULT_LEVEL;
     protected static final int DEFAULT_ICON = TelephonyIcons.ICON_3G;
-    protected static final int DEFAULT_QS_ICON = DEFAULT_ICON;
+    protected static final int DEFAULT_QS_ICON = TelephonyIcons.QS_DATA_3G;
 
     protected NetworkControllerImpl mNetworkController;
     protected MobileSignalController mMobileSignalController;
@@ -116,7 +117,7 @@
 
         when(mMockCm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)).thenReturn(true);
         when(mMockCm.getDefaultNetworkCapabilitiesForUser(0)).thenReturn(
-                new NetworkCapabilities[]{mNetCapabilities});
+                new NetworkCapabilities[] { mNetCapabilities });
 
         mSignalStrength = mock(SignalStrength.class);
         mServiceState = mock(ServiceState.class);
@@ -174,17 +175,17 @@
     }
 
     protected NetworkControllerImpl setUpNoMobileData() {
-        when(mMockCm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)).thenReturn(false);
-        NetworkControllerImpl networkControllerNoMobile
-                = new NetworkControllerImpl(mContext, mMockCm, mMockNetworkScoreManager, mMockTm,
-                mMockWm, mMockSm, mConfig, mContext.getMainLooper(), mCallbackHandler,
-                mock(AccessPointControllerImpl.class),
-                mock(DataUsageController.class), mMockSubDefaults,
-                mock(DeviceProvisionedController.class));
+      when(mMockCm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)).thenReturn(false);
+      NetworkControllerImpl networkControllerNoMobile
+              = new NetworkControllerImpl(mContext, mMockCm, mMockNetworkScoreManager, mMockTm,
+                        mMockWm, mMockSm, mConfig, mContext.getMainLooper(), mCallbackHandler,
+                        mock(AccessPointControllerImpl.class),
+                        mock(DataUsageController.class), mMockSubDefaults,
+                        mock(DeviceProvisionedController.class));
 
-        setupNetworkController();
+      setupNetworkController();
 
-        return networkControllerNoMobile;
+      return networkControllerNoMobile;
 
     }
 
@@ -307,10 +308,11 @@
         ArgumentCaptor<Boolean> dataOutArg = ArgumentCaptor.forClass(Boolean.class);
 
         Mockito.verify(mCallbackHandler, Mockito.atLeastOnce()).setMobileDataIndicators(
-                iconArg.capture(),
-                typeIconArg.capture(),
-                dataInArg.capture(), dataOutArg.capture(),
-                anyString(), anyInt(), anyBoolean(), anyBoolean());
+                    any(),
+                    iconArg.capture(),
+                    anyInt(),
+                    typeIconArg.capture(), dataInArg.capture(), dataOutArg.capture(),
+                    anyString(), anyString(), anyBoolean(), anyInt(), anyBoolean());
         IconState iconState = iconArg.getValue();
         int state = SignalDrawable.getState(icon, SignalStrength.NUM_SIGNAL_STRENGTH_BINS,
                 false);
@@ -333,16 +335,17 @@
     }
 
     protected void verifyLastMobileDataIndicators(boolean visible, int icon, int typeIcon,
-            boolean roaming, boolean inet) {
+        boolean roaming, boolean inet) {
         ArgumentCaptor<IconState> iconArg = ArgumentCaptor.forClass(IconState.class);
         ArgumentCaptor<Integer> typeIconArg = ArgumentCaptor.forClass(Integer.class);
 
         // TODO: Verify all fields.
         Mockito.verify(mCallbackHandler, Mockito.atLeastOnce()).setMobileDataIndicators(
                 iconArg.capture(),
+                any(),
                 typeIconArg.capture(),
-                anyBoolean(), anyBoolean(), anyString(),
-                anyInt(), eq(roaming), anyBoolean());
+                anyInt(), anyBoolean(), anyBoolean(), anyString(), anyString(), anyBoolean(),
+                anyInt(), eq(roaming));
         IconState iconState = iconArg.getValue();
 
         int state = icon == -1 ? 0
@@ -353,18 +356,22 @@
     }
 
     protected void verifyLastMobileDataIndicators(boolean visible, int icon, int typeIcon,
-            boolean qsVisible, boolean dataIn, boolean dataOut) {
+            boolean qsVisible, int qsIcon, int qsTypeIcon, boolean dataIn, boolean dataOut) {
         ArgumentCaptor<IconState> iconArg = ArgumentCaptor.forClass(IconState.class);
         ArgumentCaptor<Integer> typeIconArg = ArgumentCaptor.forClass(Integer.class);
+        ArgumentCaptor<IconState> qsIconArg = ArgumentCaptor.forClass(IconState.class);
+        ArgumentCaptor<Integer> qsTypeIconArg = ArgumentCaptor.forClass(Integer.class);
         ArgumentCaptor<Boolean> dataInArg = ArgumentCaptor.forClass(Boolean.class);
         ArgumentCaptor<Boolean> dataOutArg = ArgumentCaptor.forClass(Boolean.class);
 
         Mockito.verify(mCallbackHandler, Mockito.atLeastOnce()).setMobileDataIndicators(
                 iconArg.capture(),
+                qsIconArg.capture(),
                 typeIconArg.capture(),
+                qsTypeIconArg.capture(),
                 dataInArg.capture(),
                 dataOutArg.capture(),
-                anyString(), anyInt(), anyBoolean(), anyBoolean());
+                anyString(), anyString(), anyBoolean(), anyInt(), anyBoolean());
 
         IconState iconState = iconArg.getValue();
 
@@ -374,15 +381,17 @@
         assertEquals("Signal icon in status bar", state, iconState.icon);
         assertEquals("Visibility in status bar", visible, iconState.visible);
 
+        iconState = qsIconArg.getValue();
         assertEquals("Visibility in quick settings", qsVisible, iconState.visible);
         assertEquals("Signal icon in quick settings", state, iconState.icon);
+        assertEquals("Data icon in quick settings", qsTypeIcon, (int) qsTypeIconArg.getValue());
         assertEquals("Data direction in in quick settings", dataIn,
                 (boolean) dataInArg.getValue());
         assertEquals("Data direction out in quick settings", dataOut,
                 (boolean) dataOutArg.getValue());
     }
 
-    protected void assertNetworkNameEquals(String expected) {
-        assertEquals("Network name", expected, mMobileSignalController.getState().networkName);
-    }
+   protected void assertNetworkNameEquals(String expected) {
+       assertEquals("Network name", expected, mMobileSignalController.getState().networkName);
+   }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
index 6470c11..dfe00f9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
@@ -1,9 +1,5 @@
 package com.android.systemui.statusbar.policy;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.Matchers.anyInt;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
@@ -15,14 +11,10 @@
 import android.test.suitebuilder.annotation.SmallTest;
 
 import com.android.settingslib.net.DataUsageController;
-import com.android.systemui.statusbar.phone.SignalDrawable;
-import com.android.systemui.statusbar.policy.NetworkController.IconState;
 
 import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mockito;
 
 @SmallTest
 @RunWith(AndroidJUnit4.class)
@@ -124,11 +116,8 @@
         updateDataConnectionState(TelephonyManager.DATA_DISCONNECTED, 0);
         setConnectivity(NetworkCapabilities.TRANSPORT_CELLULAR, false, false);
 
-        ArgumentCaptor<IconState> iconArg = ArgumentCaptor.forClass(IconState.class);
-        Mockito.verify(mCallbackHandler, Mockito.atLeastOnce()).setMobileDataIndicators(
-                iconArg.capture(), anyInt(), anyBoolean(), anyBoolean(), any(), anyInt(),
-                anyBoolean(), anyBoolean());
-        assertEquals(SignalDrawable.STATE_CUT, SignalDrawable.getState(iconArg.getValue().icon));
+        verifyDataIndicators(TelephonyIcons.ICON_DATA_DISABLED,
+                TelephonyIcons.QS_ICON_DATA_DISABLED);
     }
 
     @Test
@@ -140,14 +129,9 @@
         setConnectivity(NetworkCapabilities.TRANSPORT_CELLULAR, false, false);
         when(mMockProvisionController.isUserSetup(anyInt())).thenReturn(false);
         mUserCallback.onUserSetupChanged();
-        waitForIdleSync();
 
         // Don't show the X until the device is setup.
-        ArgumentCaptor<IconState> iconArg = ArgumentCaptor.forClass(IconState.class);
-        Mockito.verify(mCallbackHandler, Mockito.atLeastOnce()).setMobileDataIndicators(
-                iconArg.capture(), anyInt(), anyBoolean(), anyBoolean(), any(), anyInt(),
-                anyBoolean(), anyBoolean());
-        assertNotEquals(SignalDrawable.STATE_CUT, SignalDrawable.getState(iconArg.getValue().icon));
+        verifyDataIndicators(0, 0);
     }
 
     @Test
@@ -197,12 +181,12 @@
         updateDataActivity(direction);
 
         verifyLastMobileDataIndicators(true, DEFAULT_SIGNAL_STRENGTH, DEFAULT_ICON, true,
-                in, out);
+                DEFAULT_QS_SIGNAL_STRENGTH, DEFAULT_QS_ICON, in, out);
     }
 
     private void verifyDataIndicators(int dataIcon, int qsDataIcon) {
         verifyLastMobileDataIndicators(true, DEFAULT_SIGNAL_STRENGTH, dataIcon,
-                true, false,
+                true, DEFAULT_QS_SIGNAL_STRENGTH, qsDataIcon, false,
                 false);
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
index e542c37..1627925 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
@@ -214,7 +214,7 @@
 
             verifyLastQsMobileDataIndicators(true,
                     testStrength,
-                    TelephonyIcons.ICON_1X, false, false);
+                    TelephonyIcons.QS_DATA_1X, false, false);
         }
     }
 
@@ -434,7 +434,7 @@
 
       verifyLastQsMobileDataIndicators(true /* visible */,
               DEFAULT_LEVEL /* icon */,
-              DEFAULT_ICON /* typeIcon */,
+              DEFAULT_QS_ICON /* typeIcon */,
               false /* dataIn */,
               true /* dataOut */);
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java
index edfa326..dbaa2c5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java
@@ -18,7 +18,6 @@
 
 import com.android.settingslib.Utils;
 import com.android.systemui.statusbar.policy.NetworkController.IconState;
-import android.testing.TestableSettings.SettingOverrider;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -62,7 +61,7 @@
     public void testWifiIcon() {
         String testSsid = "Test SSID";
         setWifiEnabled(true);
-        verifyLastWifiIcon(true, WifiIcons.WIFI_DISCONNECTED);
+        verifyLastWifiIcon(false, WifiIcons.WIFI_NO_NETWORK);
 
         setWifiState(true, testSsid);
         verifyLastWifiIcon(true, WifiIcons.WIFI_SIGNAL_STRENGTH[0][0]);
@@ -92,11 +91,10 @@
                         attr);
 
         // Must set the Settings value before instantiating the NetworkControllerImpl due to bugs in
-        // TestableSettings.
-        SettingOverrider settingsOverrider =
-                mContext.getSettingsProvider().acquireOverridesBuilder()
-                        .addSetting("global", Settings.Global.NETWORK_SCORING_UI_ENABLED, "1")
-                        .build();
+        // TestableSettingsProvider.
+        Settings.Global.putString(mContext.getContentResolver(),
+                Settings.Global.NETWORK_SCORING_UI_ENABLED,
+                "1");
         super.setUp(); // re-instantiate NetworkControllImpl now that setting has been updated
         setupNetworkScoreManager();
 
@@ -131,8 +129,6 @@
         assertEquals("SD Badge is set",
                 Utils.getWifiBadgeResource(NetworkBadging.BADGING_SD),
                 iconState.iconOverlay);
-
-        settingsOverrider.release();
     }
 
     private void setupNetworkScoreManager() {
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index fc70b2b..dc082e1 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -3923,6 +3923,31 @@
     // OS: O
     ACTION_TEXT_SELECTION_MENU_ITEM_ASSIST = 937;
 
+    // OPEN: Settings > Security > Managed Device Info > Apps installed
+    // CATEGORY: SETTINGS
+    // OS: O
+    ENTERPRISE_PRIVACY_INSTALLED_APPS = 938;
+
+    // OPEN: Settings > Security > Managed Device Info > nnn permissions
+    // CATEGORY: SETTINGS
+    // OS: O
+    ENTERPRISE_PRIVACY_PERMISSIONS = 939;
+
+    // OPEN: Settings > Security > Managed Device Info > Default apps
+    // CATEGORY: SETTINGS
+    // OS: O
+    ENTERPRISE_PRIVACY_DEFAULT_APPS = 940;
+
+    // OPEN: Settings > Notifications > An app > A channel > Importance
+    // CATEGORY: SETTINGS
+    // OS: O
+    NOTIFICATION_CHANNEL_IMPORTANCE = 941;
+
+    // OPEN: Settings > Notifications > An app > A channel > On the lock screen
+    // CATEGORY: SETTINGS
+    // OS: O
+    NOTIFICATION_CHANNEL_LOCK_SCREEN_VIS = 942;
+
     // ---- End O Constants, all O constants go above this line ----
 
     // Add new aosp constants above this line.
diff --git a/services/core/java/com/android/server/SyntheticPasswordManager.java b/services/core/java/com/android/server/SyntheticPasswordManager.java
index d23584f..6ec74e1 100644
--- a/services/core/java/com/android/server/SyntheticPasswordManager.java
+++ b/services/core/java/com/android/server/SyntheticPasswordManager.java
@@ -82,7 +82,7 @@
     // 256-bit synthetic password
     private static final byte SYNTHETIC_PASSWORD_LENGTH = 256 / 8;
 
-    private static final int PASSWORD_SCRYPT_N = 13;
+    private static final int PASSWORD_SCRYPT_N = 11;
     private static final int PASSWORD_SCRYPT_R = 3;
     private static final int PASSWORD_SCRYPT_P = 1;
     private static final int PASSWORD_SALT_LENGTH = 16;
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 8d1435b..e9989d6 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -14644,8 +14644,10 @@
     }
 
     static int procStateToImportance(int procState, int memAdj,
-            ActivityManager.RunningAppProcessInfo currApp) {
-        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
+            ActivityManager.RunningAppProcessInfo currApp,
+            int clientTargetSdk) {
+        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk(
+                procState, clientTargetSdk);
         if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
             currApp.lru = memAdj;
         } else {
@@ -14655,7 +14657,8 @@
     }
 
     private void fillInProcMemInfo(ProcessRecord app,
-            ActivityManager.RunningAppProcessInfo outInfo) {
+            ActivityManager.RunningAppProcessInfo outInfo,
+            int clientTargetSdk) {
         outInfo.pid = app.pid;
         outInfo.uid = app.info.uid;
         if (mHeavyWeightProcess == app) {
@@ -14670,7 +14673,7 @@
         outInfo.lastTrimLevel = app.trimMemoryLevel;
         int adj = app.curAdj;
         int procState = app.curProcState;
-        outInfo.importance = procStateToImportance(procState, adj, outInfo);
+        outInfo.importance = procStateToImportance(procState, adj, outInfo, clientTargetSdk);
         outInfo.importanceReasonCode = app.adjTypeCode;
         outInfo.processState = app.curProcState;
     }
@@ -14680,6 +14683,7 @@
         enforceNotIsolatedCaller("getRunningAppProcesses");
 
         final int callingUid = Binder.getCallingUid();
+        final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
 
         // Lazy instantiation of list
         List<ActivityManager.RunningAppProcessInfo> runList = null;
@@ -14702,7 +14706,7 @@
                     ActivityManager.RunningAppProcessInfo currApp =
                         new ActivityManager.RunningAppProcessInfo(app.processName,
                                 app.pid, app.getPackageList());
-                    fillInProcMemInfo(app, currApp);
+                    fillInProcMemInfo(app, currApp, clientTargetSdk);
                     if (app.adjSource instanceof ProcessRecord) {
                         currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
                         currApp.importanceReasonImportance =
@@ -14758,12 +14762,16 @@
     @Override
     public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
         enforceNotIsolatedCaller("getMyMemoryState");
+
+        final int callingUid = Binder.getCallingUid();
+        final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
+
         synchronized (this) {
             ProcessRecord proc;
             synchronized (mPidsSelfLocked) {
                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
             }
-            fillInProcMemInfo(proc, outInfo);
+            fillInProcMemInfo(proc, outInfo, clientTargetSdk);
         }
     }
 
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 728a3b9..82e2a3d 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -3301,13 +3301,21 @@
 
         final ActivityRecord next = topRunningActivityLocked();
         final String myReason = reason + " adjustFocus";
+
         if (next != r) {
             if (next != null && StackId.keepFocusInStackIfPossible(mStackId) && isFocusable()) {
                 // For freeform, docked, and pinned stacks we always keep the focus within the
                 // stack as long as there is a running activity.
                 return;
             } else {
+                // Task is not guaranteed to be non-null. For example, destroying the
+                // {@link ActivityRecord} will disassociate the task from the activity.
                 final TaskRecord task = r.getTask();
+
+                if (task == null) {
+                    throw new IllegalStateException("activity no longer associated with task:" + r);
+                }
+
                 final boolean isAssistantOrOverAssistant = task.getStack().isAssistantStack() ||
                         task.isOverAssistantStack();
                 if (r.frontOfTask && isATopFinishingTask(task)
@@ -3373,8 +3381,8 @@
                     if (DEBUG_STATES) Slog.d(TAG_STATES, "no-history finish of " + r);
                     if (requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
                             "stop-no-history", false)) {
-                        // Activity was finished, no need to continue trying to schedule stop.
-                        adjustFocusedActivityStackLocked(r, "stopActivityFinished");
+                        // If {@link requestFinishActivityLocked} returns {@code true},
+                        // {@link adjustFocusedActivityStackLocked} would have been already called.
                         r.resumeKeyDispatchingLocked();
                         return;
                     }
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index bff3ce3..dfeff52 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -110,7 +110,6 @@
 import android.app.ActivityOptions;
 import android.app.AppOpsManager;
 import android.app.IActivityContainerCallback;
-import android.app.ITaskStackListener;
 import android.app.ProfilerInfo;
 import android.app.ResultInfo;
 import android.app.StatusBarManager;
@@ -157,7 +156,6 @@
 import android.provider.Settings;
 import android.provider.Settings.SettingNotFoundException;
 import android.service.voice.IVoiceInteractionSession;
-import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.EventLog;
@@ -1129,7 +1127,7 @@
         mActivitiesWaitingForVisibleActivity.remove(r);
 
         for (int i = mWaitingForActivityVisible.size() - 1; i >= 0; --i) {
-            if (mWaitingForActivityVisible.get(i).matches(r)) {
+            if (mWaitingForActivityVisible.get(i).matches(r.realActivity)) {
                 mWaitingForActivityVisible.remove(i);
             }
         }
@@ -1143,7 +1141,7 @@
         boolean changed = false;
         for (int i = mWaitingForActivityVisible.size() - 1; i >= 0; --i) {
             final WaitInfo w = mWaitingForActivityVisible.get(i);
-            if (w.matches(r)) {
+            if (w.matches(r.realActivity)) {
                 final WaitResult result = w.getResult();
                 changed = true;
                 result.timeout = false;
@@ -3944,10 +3942,11 @@
     }
 
     private StackInfo getStackInfoLocked(ActivityStack stack) {
-        final ActivityDisplay display = mActivityDisplays.get(DEFAULT_DISPLAY);
+        final int displayId = stack.mDisplayId;
+        final ActivityDisplay display = mActivityDisplays.get(displayId);
         StackInfo info = new StackInfo();
         stack.getWindowContainerBounds(info.bounds);
-        info.displayId = DEFAULT_DISPLAY;
+        info.displayId = displayId;
         info.stackId = stack.mStackId;
         info.userId = stack.mCurrentUser;
         info.visible = stack.shouldBeVisible(null) == STACK_VISIBLE;
@@ -5140,10 +5139,8 @@
             this.mResult = result;
         }
 
-        public boolean matches(ActivityRecord record) {
-            return mTargetComponent == null ||
-                    (TextUtils.equals(mTargetComponent.getPackageName(), record.info.packageName)
-                            && TextUtils.equals(mTargetComponent.getClassName(), record.info.name));
+        public boolean matches(ComponentName targetComponent) {
+            return mTargetComponent == null || mTargetComponent.equals(targetComponent);
         }
 
         public WaitResult getResult() {
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index 1f4b21b1..ca842d55 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -245,6 +245,9 @@
             ActivityRecord[] outActivity, ActivityStackSupervisor.ActivityContainer container,
             TaskRecord inTask) {
         int err = ActivityManager.START_SUCCESS;
+        // Pull the optional Ephemeral Installer-only bundle out of the options early.
+        final Bundle verificationBundle
+                = options != null ? options.popAppVerificationBundle() : null;
 
         ProcessRecord callerApp = null;
         if (caller != null) {
@@ -466,7 +469,7 @@
         // app [on install success].
         if (rInfo != null && rInfo.auxiliaryInfo != null) {
             intent = createLaunchIntent(rInfo.auxiliaryInfo, ephemeralIntent,
-                    callingPackage, resolvedType, userId);
+                    callingPackage, verificationBundle, resolvedType, userId);
             resolvedType = null;
             callingUid = realCallingUid;
             callingPid = realCallingPid;
@@ -522,14 +525,16 @@
      * Creates a launch intent for the given auxiliary resolution data.
      */
     private @NonNull Intent createLaunchIntent(@NonNull AuxiliaryResolveInfo auxiliaryResponse,
-            Intent originalIntent, String callingPackage, String resolvedType, int userId) {
+            Intent originalIntent, String callingPackage, Bundle verificationBundle,
+            String resolvedType, int userId) {
         if (auxiliaryResponse.needsPhaseTwo) {
             // request phase two resolution
             mService.getPackageManagerInternalLocked().requestInstantAppResolutionPhaseTwo(
-                    auxiliaryResponse, originalIntent, resolvedType, callingPackage, userId);
+                    auxiliaryResponse, originalIntent, resolvedType, callingPackage,
+                    verificationBundle, userId);
         }
         return InstantAppResolver.buildEphemeralInstallerIntent(originalIntent,
-            callingPackage, resolvedType, userId, auxiliaryResponse.packageName,
+            callingPackage, verificationBundle, resolvedType, userId, auxiliaryResponse.packageName,
             auxiliaryResponse.splitName, auxiliaryResponse.versionCode,
             auxiliaryResponse.token, auxiliaryResponse.needsPhaseTwo);
     }
diff --git a/services/core/java/com/android/server/pm/InstantAppResolver.java b/services/core/java/com/android/server/pm/InstantAppResolver.java
index b56db04..624d8c9 100644
--- a/services/core/java/com/android/server/pm/InstantAppResolver.java
+++ b/services/core/java/com/android/server/pm/InstantAppResolver.java
@@ -41,6 +41,7 @@
 import android.metrics.LogMaker;
 import android.os.Binder;
 import android.os.Build;
+import android.os.Bundle;
 import android.os.Handler;
 import android.os.RemoteException;
 import android.util.Log;
@@ -147,6 +148,7 @@
                 final Intent installerIntent = buildEphemeralInstallerIntent(
                         requestObj.origIntent,
                         requestObj.callingPackage,
+                        requestObj.verificationBundle,
                         requestObj.resolvedType,
                         requestObj.userId,
                         packageName,
@@ -172,6 +174,7 @@
      */
     public static Intent buildEphemeralInstallerIntent(@NonNull Intent origIntent,
             @NonNull String callingPackage,
+            @Nullable Bundle verificationBundle,
             @NonNull String resolvedType,
             int userId,
             @NonNull String instantAppPackageName,
@@ -234,6 +237,10 @@
             intent.putExtra(Intent.EXTRA_PACKAGE_NAME, instantAppPackageName);
             intent.putExtra(Intent.EXTRA_SPLIT_NAME, instantAppSplitName);
             intent.putExtra(Intent.EXTRA_VERSION_CODE, versionCode);
+            intent.putExtra(Intent.EXTRA_CALLING_PACKAGE, callingPackage);
+            if (verificationBundle != null) {
+                intent.putExtra(Intent.EXTRA_VERIFICATION_BUNDLE, verificationBundle);
+            }
         }
 
         return intent;
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 7bbb1fe..f8e4014 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -5820,10 +5820,10 @@
 
     private void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
             Intent origIntent, String resolvedType, String callingPackage,
-            int userId) {
+            Bundle verificationBundle, int userId) {
         final Message msg = mHandler.obtainMessage(INSTANT_APP_RESOLUTION_PHASE_TWO,
                 new InstantAppRequest(responseObj, origIntent, resolvedType,
-                        callingPackage, userId));
+                        callingPackage, userId, verificationBundle));
         mHandler.sendMessage(msg);
     }
 
@@ -6372,7 +6372,7 @@
             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveEphemeral");
             final InstantAppRequest requestObject = new InstantAppRequest(
                     null /*responseObj*/, intent /*origIntent*/, resolvedType,
-                    null /*callingPackage*/, userId);
+                    null /*callingPackage*/, userId, null /*verificationBundle*/);
             final AuxiliaryResolveInfo auxiliaryResponse =
                     InstantAppResolver.doInstantAppResolutionPhaseOne(
                             mContext, mInstantAppResolverConnection, requestObject);
@@ -23423,9 +23423,11 @@
 
         @Override
         public void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
-                Intent origIntent, String resolvedType, String callingPackage, int userId) {
+                Intent origIntent, String resolvedType, String callingPackage,
+                Bundle verificationBundle, int userId) {
             PackageManagerService.this.requestInstantAppResolutionPhaseTwo(
-                    responseObj, origIntent, resolvedType, callingPackage, userId);
+                    responseObj, origIntent, resolvedType, callingPackage, verificationBundle,
+                    userId);
         }
 
         @Override
@@ -23570,6 +23572,13 @@
                 mIsolatedOwners.delete(isolatedUid);
             }
         }
+
+        @Override
+        public int getUidTargetSdkVersion(int uid) {
+            synchronized (mPackages) {
+                return getUidTargetSdkVersionLockedLPr(uid);
+            }
+        }
     }
 
     @Override
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java
index 58166b6..c87eaed 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java
@@ -22,6 +22,7 @@
 import static org.junit.Assert.assertTrue;
 
 import android.content.ComponentName;
+import android.content.pm.ActivityInfo;
 import android.platform.test.annotations.Presubmit;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
@@ -84,4 +85,16 @@
         // Make sure the resumed activity is untouched.
         assertEquals(testStack.mResumedActivity, activityRecord);
     }
+
+    @Test
+    public void testStopActivityWhenActivityDestroyed() throws Exception {
+        final ActivityManagerService service = createActivityManagerService();
+        final TaskRecord task = createTask(service, testActivityComponent, TEST_STACK_ID);
+        final ActivityRecord activityRecord = createActivity(service, testActivityComponent, task);
+        activityRecord.info.flags |= ActivityInfo.FLAG_NO_HISTORY;
+        final ActivityStack testStack = service.mStackSupervisor.getStack(TEST_STACK_ID);
+        service.mStackSupervisor.setFocusStackUnchecked("testStopActivityWithDestroy", testStack);
+
+        testStack.stopActivityLocked(activityRecord);
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java b/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java
index 0827084..3fc2c12 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java
@@ -161,6 +161,11 @@
         void moveHomeStackToFront(String reason) {
         }
 
+        @Override
+        boolean moveHomeStackTaskToTop(String reason) {
+            return true;
+        }
+
         // Invoked during {@link ActivityStack} creation.
         @Override
         void updateUIDsPresentOnDisplay() {
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/NetworkEventTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/NetworkEventTest.java
index 315d37c..caa26e1 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/NetworkEventTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/NetworkEventTest.java
@@ -35,7 +35,7 @@
         p.setDataPosition(0);
         ConnectEvent unparceledEvent = p.readParcelable(NetworkEventTest.class.getClassLoader());
         p.recycle();
-        assertEquals(event.getIpAddress(), unparceledEvent.getIpAddress());
+        assertEquals(event.getInetAddress(), unparceledEvent.getInetAddress());
         assertEquals(event.getPort(), unparceledEvent.getPort());
         assertEquals(event.getPackageName(), unparceledEvent.getPackageName());
         assertEquals(event.getTimestamp(), unparceledEvent.getTimestamp());
@@ -53,9 +53,9 @@
         DnsEvent unparceledEvent = p.readParcelable(NetworkEventTest.class.getClassLoader());
         p.recycle();
         assertEquals(event.getHostname(), unparceledEvent.getHostname());
-        assertEquals(event.getIpAddresses()[0], unparceledEvent.getIpAddresses()[0]);
-        assertEquals(event.getIpAddresses()[1], unparceledEvent.getIpAddresses()[1]);
-        assertEquals(event.getIpAddressesCount(), unparceledEvent.getIpAddressesCount());
+        assertEquals(event.getInetAddresses()[0], unparceledEvent.getInetAddresses()[0]);
+        assertEquals(event.getInetAddresses()[1], unparceledEvent.getInetAddresses()[1]);
+        assertEquals(event.getTotalResolvedAddressCount(), unparceledEvent.getTotalResolvedAddressCount());
         assertEquals(event.getPackageName(), unparceledEvent.getPackageName());
         assertEquals(event.getTimestamp(), unparceledEvent.getTimestamp());
     }
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index 6c4ced4..4ffacfd 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -1203,6 +1203,50 @@
             }
 
             @Override
+            public void onPackageModified(String pkgName) {
+                // If the package modified is not in the current user, then don't bother making
+                // any changes as we are going to do any initialization needed when we switch users.
+                if (mCurUser != getChangingUserId()) {
+                    return;
+                }
+                // Package getting updated will be handled by {@link #onSomePackagesChanged}.
+                if (isPackageAppearing(pkgName) != PACKAGE_UNCHANGED) {
+                    return;
+                }
+                final ComponentName curInteractor = getCurInteractor(mCurUser);
+                if (curInteractor == null) {
+                    final VoiceInteractionServiceInfo availInteractorInfo
+                            = findAvailInteractor(mCurUser, pkgName);
+                    if (availInteractorInfo != null) {
+                        final ComponentName availInteractor = new ComponentName(
+                                availInteractorInfo.getServiceInfo().packageName,
+                                availInteractorInfo.getServiceInfo().name);
+                        setCurInteractor(availInteractor, mCurUser);
+                        if (getCurRecognizer(mCurUser) == null &&
+                                availInteractorInfo.getRecognitionService() != null) {
+                            setCurRecognizer(new ComponentName(
+                                    availInteractorInfo.getServiceInfo().packageName,
+                                    availInteractorInfo.getRecognitionService()), mCurUser);
+                        }
+                    }
+                } else {
+                    if (didSomePackagesChange()) {
+                        // Package is changed
+                        if (curInteractor != null && pkgName.equals(
+                                curInteractor.getPackageName())) {
+                            switchImplementationIfNeeded(true);
+                        }
+                    } else {
+                        // Only some components are changed
+                        if (curInteractor != null
+                                && isComponentModified(curInteractor.getClassName())) {
+                            switchImplementationIfNeeded(true);
+                        }
+                    }
+                }
+            }
+
+            @Override
             public void onSomePackagesChanged() {
                 int userHandle = getChangingUserId();
                 if (DEBUG) Slog.d(TAG, "onSomePackagesChanged user=" + userHandle);
diff --git a/tests/testables/src/android/testing/TestableContext.java b/tests/testables/src/android/testing/TestableContext.java
index cb5d4cb..630a287 100644
--- a/tests/testables/src/android/testing/TestableContext.java
+++ b/tests/testables/src/android/testing/TestableContext.java
@@ -43,7 +43,7 @@
  * <ul>
  * <li>System services can be mocked out with {@link #addMockSystemService}</li>
  * <li>Service binding can be mocked out with {@link #addMockService}</li>
- * <li>Settings support {@link TestableSettings}</li>
+ * <li>Settings support {@link TestableSettingsProvider}</li>
  * <li>Has support for {@link LeakCheck} for services and receivers</li>
  * </ul>
  *
@@ -59,7 +59,7 @@
 public class TestableContext extends ContextWrapper implements TestRule {
 
     private final TestableContentResolver mTestableContentResolver;
-    private final TestableSettings mSettingsProvider;
+    private final TestableSettingsProvider mSettingsProvider;
 
     private ArrayMap<String, Object> mMockSystemServices;
     private ArrayMap<ComponentName, IBinder> mMockServices;
@@ -79,9 +79,8 @@
         mTestableContentResolver = new TestableContentResolver(base);
         ContentProviderClient settings = base.getContentResolver()
                 .acquireContentProviderClient(Settings.AUTHORITY);
-        mSettingsProvider = TestableSettings.getFakeSettingsProvider(settings,
-                mTestableContentResolver);
-        mTestableContentResolver.addProvider(Settings.AUTHORITY, mSettingsProvider.getProvider());
+        mSettingsProvider = TestableSettingsProvider.getFakeSettingsProvider(settings);
+        mTestableContentResolver.addProvider(Settings.AUTHORITY, mSettingsProvider);
         mReceiver = check != null ? check.getTracker("receiver") : null;
         mService = check != null ? check.getTracker("service") : null;
         mComponent = check != null ? check.getTracker("component") : null;
@@ -129,7 +128,7 @@
         return super.getSystemService(name);
     }
 
-    public TestableSettings getSettingsProvider() {
+    TestableSettingsProvider getSettingsProvider() {
         return mSettingsProvider;
     }
 
@@ -236,12 +235,12 @@
         return new TestWatcher() {
             @Override
             protected void succeeded(Description description) {
-                mSettingsProvider.clearOverrides();
+                mSettingsProvider.clearValuesAndCheck(TestableContext.this);
             }
 
             @Override
             protected void failed(Throwable e, Description description) {
-                mSettingsProvider.clearOverrides();
+                mSettingsProvider.clearValuesAndCheck(TestableContext.this);
             }
         }.apply(base, description);
     }
diff --git a/tests/testables/src/android/testing/TestableSettings.java b/tests/testables/src/android/testing/TestableSettings.java
deleted file mode 100644
index d19f1ef..0000000
--- a/tests/testables/src/android/testing/TestableSettings.java
+++ /dev/null
@@ -1,318 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package android.testing;
-
-import android.content.ContentProvider;
-import android.content.ContentProviderClient;
-import android.content.ContentResolver;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.provider.Settings;
-import android.support.annotation.VisibleForTesting;
-import android.test.mock.MockContentProvider;
-import android.testing.TestableSettings.SettingOverrider.Builder;
-import android.util.ArrayMap;
-import android.util.ArraySet;
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Allows calls to android.provider.Settings to be tested easier.  A SettingOverride
- * can be acquired and a set of specific settings can be set to a value (and not changed
- * in the system when set), so that they can be tested without breaking the test device.
- * <p>
- * To use, in the before method acquire the override add all settings that will affect if
- * your test passes or not.
- *
- * <pre class="prettyprint">
- * {@literal
- * mSettingOverride = mTestableContext.getSettingsProvider().acquireOverridesBuilder()
- * .addSetting("secure", Secure.USER_SETUP_COMPLETE, "0")
- * .build();
- * }
- * </pre>
- *
- * Then in the after free up the settings.
- *
- * <pre class="prettyprint">
- * {@literal
- * mSettingOverride.release();
- * }
- * </pre>
- */
-public class TestableSettings {
-
-    private static final String TAG = "TestableSettings";
-    private static final boolean DEBUG = false;
-
-    // Number of times to try to acquire a setting if in use.
-    private static final int MAX_TRIES = 10;
-    // Time to wait for each setting.  WAIT_TIMEOUT * MAX_TRIES will be the maximum wait time
-    // for a setting.
-    private static final long WAIT_TIMEOUT = 1000;
-
-    private static TestableSettingsProvider sInstance;
-
-    private final TestableSettingsProvider mProvider;
-
-    private TestableSettings(TestableSettingsProvider provider) {
-        mProvider = provider;
-    }
-
-    public Builder acquireOverridesBuilder() {
-        return new Builder(this);
-    }
-
-    public void clearOverrides() {
-        List<SettingOverrider> overrides = mProvider.mOwners.remove(this);
-        if (overrides != null) {
-            overrides.forEach(override -> override.ensureReleased());
-        }
-    }
-
-    private void acquireSettings(SettingOverrider overridder, Set<String> keys)
-            throws AcquireTimeoutException {
-        mProvider.acquireSettings(overridder, keys, this);
-    }
-
-    ContentProvider getProvider() {
-        return mProvider;
-    }
-
-    @VisibleForTesting
-    Object getLock() {
-        return mProvider.mOverrideMap;
-    }
-
-    public static class SettingOverrider {
-        private final Set<String> mValidKeys;
-        private final Map<String, String> mValueMap = new ArrayMap<>();
-        private final TestableSettings mSettings;
-        private boolean mReleased;
-        public Throwable mObtain;
-
-        private SettingOverrider(Set<String> keys, TestableSettings provider) {
-            mValidKeys = new ArraySet<>(keys);
-            mSettings = provider;
-        }
-
-        private void ensureReleased() {
-            if (!mReleased) {
-                release();
-            }
-        }
-
-        public void release() {
-            mSettings.mProvider.releaseSettings(mValidKeys);
-            mReleased = true;
-        }
-
-        private void putDirect(String key, String value) {
-            mValueMap.put(key, value);
-        }
-
-        public void put(String table, String key, String value) {
-            if (!mValidKeys.contains(key(table, key))) {
-                throw new IllegalArgumentException("Key " + table + " " + key
-                        + " not acquired for this overrider");
-            }
-            mValueMap.put(key(table, key), value);
-        }
-
-        public void remove(String table, String key) {
-            if (!mValidKeys.contains(key(table, key))) {
-                throw new IllegalArgumentException("Key " + table + " " + key
-                        + " not acquired for this overrider");
-            }
-            mValueMap.remove(key(table, key));
-        }
-
-        public String get(String table, String key) {
-            if (!mValidKeys.contains(key(table, key))) {
-                throw new IllegalArgumentException("Key " + table + " " + key
-                        + " not acquired for this overrider");
-            }
-            Log.d(TAG, "Get " + table + " " + key + " " + mValueMap.get(key(table, key)));
-            return mValueMap.get(key(table, key));
-        }
-
-        public static class Builder {
-            private final TestableSettings mProvider;
-            private Set<String> mKeys = new ArraySet<>();
-            private Map<String, String> mValues = new ArrayMap<>();
-
-            private Builder(TestableSettings provider) {
-                mProvider = provider;
-            }
-
-            public Builder addSetting(String table, String key) {
-                mKeys.add(key(table, key));
-                return this;
-            }
-
-            public Builder addSetting(String table, String key, String value) {
-                addSetting(table, key);
-                mValues.put(key(table, key), value);
-                return this;
-            }
-
-            public SettingOverrider build() throws AcquireTimeoutException {
-                SettingOverrider overrider = new SettingOverrider(mKeys, mProvider);
-                mProvider.acquireSettings(overrider, mKeys);
-                mValues.forEach((key, value) -> overrider.putDirect(key, value));
-                return overrider;
-            }
-        }
-    }
-
-    private static class TestableSettingsProvider extends MockContentProvider {
-
-        private final Map<String, SettingOverrider> mOverrideMap = new ArrayMap<>();
-        private final Map<Object, List<SettingOverrider>> mOwners = new ArrayMap<>();
-
-        private final ContentProviderClient mSettings;
-        private final ContentResolver mResolver;
-
-        public TestableSettingsProvider(ContentProviderClient settings, ContentResolver resolver) {
-            mSettings = settings;
-            mResolver = resolver;
-        }
-
-        private void releaseSettings(Set<String> keys) {
-            synchronized (mOverrideMap) {
-                for (String key : keys) {
-                    if (DEBUG) Log.d(TAG, "Releasing " + key);
-                    mOverrideMap.remove(key);
-                }
-                if (DEBUG) Log.d(TAG, "Notifying");
-                mOverrideMap.notify();
-            }
-        }
-
-        private boolean checkKeysLocked(Set<String> keys, boolean shouldThrow)
-                throws AcquireTimeoutException {
-            for (String key : keys) {
-                if (mOverrideMap.containsKey(key)) {
-                    if (shouldThrow) {
-                        if (DEBUG) Log.e(TAG, "Lock obtained at",
-                                mOverrideMap.get(key).mObtain);
-                        throw new AcquireTimeoutException("Could not acquire " + key,
-                                mOverrideMap.get(key).mObtain);
-                    }
-                    return false;
-                }
-            }
-            return true;
-        }
-
-        private void acquireSettings(SettingOverrider overridder, Set<String> keys,
-                Object owner) throws AcquireTimeoutException {
-            synchronized (mOwners) {
-                List<SettingOverrider> list = mOwners.get(owner);
-                if (list == null) {
-                    list = new ArrayList<>();
-                    mOwners.put(owner, list);
-                }
-                list.add(overridder);
-            }
-            synchronized (mOverrideMap) {
-                for (int i = 0; i < MAX_TRIES; i++) {
-                    if (checkKeysLocked(keys, false)) break;
-                    try {
-                        if (DEBUG) Log.d(TAG, "Waiting for contention to finish");
-                        mOverrideMap.wait(WAIT_TIMEOUT);
-                    } catch (InterruptedException e) {
-                    }
-                }
-                overridder.mObtain = new Throwable();
-                checkKeysLocked(keys, true);
-                for (String key : keys) {
-                    if (DEBUG) Log.d(TAG, "Acquiring " + key);
-                    mOverrideMap.put(key, overridder);
-                }
-            }
-        }
-
-        public Bundle call(String method, String arg, Bundle extras) {
-            // Methods are "GET_system", "GET_global", "PUT_secure", etc.
-            final String[] commands = method.split("_", 2);
-            final String op = commands[0];
-            final String table = commands[1];
-
-            synchronized (mOverrideMap) {
-                SettingOverrider overrider = mOverrideMap.get(key(table, arg));
-                if (overrider == null) {
-                    // Fall through to real settings.
-                    try {
-                        if (DEBUG) Log.d(TAG, "Falling through to real settings " + method);
-                        // TODO: Add our own version of caching to handle this.
-                        Bundle call = mSettings.call(method, arg, extras);
-                        call.remove(Settings.CALL_METHOD_TRACK_GENERATION_KEY);
-                        return call;
-                    } catch (RemoteException e) {
-                        throw new RuntimeException(e);
-                    }
-                }
-                String value;
-                Bundle out = new Bundle();
-                switch (op) {
-                    case "GET":
-                        value = overrider.get(table, arg);
-                        if (value != null) {
-                            out.putString(Settings.NameValueTable.VALUE, value);
-                        }
-                        break;
-                    case "PUT":
-                        value = extras.getString(Settings.NameValueTable.VALUE, null);
-                        if (value != null) {
-                            overrider.put(table, arg, value);
-                        } else {
-                            overrider.remove(table, arg);
-                        }
-                        break;
-                    default:
-                        throw new UnsupportedOperationException("Unknown command " + method);
-                }
-                return out;
-            }
-        }
-    }
-
-    public static class AcquireTimeoutException extends Exception {
-        public AcquireTimeoutException(String str, Throwable cause) {
-            super(str, cause);
-        }
-    }
-
-    private static String key(String table, String key) {
-        return table + "_" + key;
-    }
-
-    /**
-     * Since the settings provider is cached inside android.provider.Settings, this must
-     * be gotten statically to ensure there is only one instance referenced.
-     */
-    public static TestableSettings getFakeSettingsProvider(ContentProviderClient settings,
-            ContentResolver resolver) {
-        if (sInstance == null) {
-            sInstance = new TestableSettingsProvider(settings, resolver);
-        }
-        return new TestableSettings(sInstance);
-    }
-}
diff --git a/tests/testables/src/android/testing/TestableSettingsProvider.java b/tests/testables/src/android/testing/TestableSettingsProvider.java
new file mode 100644
index 0000000..13056cf
--- /dev/null
+++ b/tests/testables/src/android/testing/TestableSettingsProvider.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package android.testing;
+
+import android.content.ContentProviderClient;
+import android.content.Context;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.provider.Settings;
+import android.test.mock.MockContentProvider;
+import android.util.Log;
+
+import java.util.HashMap;
+
+import static org.junit.Assert.*;
+
+/**
+ * Allows calls to android.provider.Settings to be tested easier.
+ *
+ * This provides a simple copy-on-write implementation of settings that gets cleared
+ * at the end of each test.
+ */
+public class TestableSettingsProvider extends MockContentProvider {
+
+    private static final String TAG = "TestableSettingsProvider";
+    private static final boolean DEBUG = false;
+    private static final String MY_UNIQUE_KEY = "Key_" + TestableSettingsProvider.class.getName();
+    private static TestableSettingsProvider sInstance;
+
+    private final ContentProviderClient mSettings;
+
+    private final HashMap<String, String> mValues = new HashMap<>();
+
+    private TestableSettingsProvider(ContentProviderClient settings) {
+        mSettings = settings;
+    }
+
+    void clearValuesAndCheck(Context context) {
+        mValues.put(key("global", MY_UNIQUE_KEY), MY_UNIQUE_KEY);
+        mValues.put(key("secure", MY_UNIQUE_KEY), MY_UNIQUE_KEY);
+        mValues.put(key("system", MY_UNIQUE_KEY), MY_UNIQUE_KEY);
+
+        // Verify that if any test is using TestableContext, they all have the correct settings
+        // provider.
+        assertEquals("Incorrect settings provider, test using incorrect Context?", MY_UNIQUE_KEY,
+                Settings.Global.getString(context.getContentResolver(), MY_UNIQUE_KEY));
+        assertEquals("Incorrect settings provider, test using incorrect Context?", MY_UNIQUE_KEY,
+                Settings.Secure.getString(context.getContentResolver(), MY_UNIQUE_KEY));
+        assertEquals("Incorrect settings provider, test using incorrect Context?", MY_UNIQUE_KEY,
+                Settings.System.getString(context.getContentResolver(), MY_UNIQUE_KEY));
+
+        mValues.clear();
+    }
+
+    public Bundle call(String method, String arg, Bundle extras) {
+        // Methods are "GET_system", "GET_global", "PUT_secure", etc.
+        final String[] commands = method.split("_", 2);
+        final String op = commands[0];
+        final String table = commands[1];
+
+            String k = key(table, arg);
+            String value;
+            Bundle out = new Bundle();
+            switch (op) {
+                case "GET":
+                    if (mValues.containsKey(k)) {
+                        value = mValues.get(k);
+                        if (value != null) {
+                            out.putString(Settings.NameValueTable.VALUE, value);
+                        }
+                    } else {
+                        // Fall through to real settings.
+                        try {
+                            if (DEBUG) Log.d(TAG, "Falling through to real settings " + method);
+                            // TODO: Add our own version of caching to handle this.
+                            Bundle call = mSettings.call(method, arg, extras);
+                            call.remove(Settings.CALL_METHOD_TRACK_GENERATION_KEY);
+                            return call;
+                        } catch (RemoteException e) {
+                            throw new RuntimeException(e);
+                        }
+                    }
+                    break;
+                case "PUT":
+                    value = extras.getString(Settings.NameValueTable.VALUE, null);
+                    mValues.put(k, value);
+                    break;
+                default:
+                    throw new UnsupportedOperationException("Unknown command " + method);
+            }
+            return out;
+    }
+
+    private static String key(String table, String key) {
+        return table + "_" + key;
+    }
+
+    /**
+     * Since the settings provider is cached inside android.provider.Settings, this must
+     * be gotten statically to ensure there is only one instance referenced.
+     */
+    static TestableSettingsProvider getFakeSettingsProvider(ContentProviderClient settings) {
+        if (sInstance == null) {
+            sInstance = new TestableSettingsProvider(settings);
+        }
+        return sInstance;
+    }
+}
diff --git a/tests/testables/tests/src/android/testing/TestableSettingsProviderTest.java b/tests/testables/tests/src/android/testing/TestableSettingsProviderTest.java
new file mode 100644
index 0000000..1f71867
--- /dev/null
+++ b/tests/testables/tests/src/android/testing/TestableSettingsProviderTest.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package android.testing;
+
+import android.content.ContentResolver;
+import android.provider.Settings;
+import android.provider.Settings.Global;
+import android.provider.Settings.Secure;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.*;
+
+@RunWith(AndroidJUnit4.class)
+public class TestableSettingsProviderTest {
+
+    public static final String NONEXISTENT_SETTING = "nonexistent_setting";
+    private static final String TAG = "TestableSettingsProviderTest";
+    private ContentResolver mContentResolver;
+    @Rule
+    public final TestableContext mContext =
+            new TestableContext(InstrumentationRegistry.getContext());
+
+    @Before
+    public void setup() {
+        mContentResolver = mContext.getContentResolver();
+        Settings.Secure.putString(mContentResolver, NONEXISTENT_SETTING, null);
+        Settings.Global.putString(mContentResolver, NONEXISTENT_SETTING, "initial value");
+        Settings.Global.putString(mContentResolver, Global.DEVICE_PROVISIONED, null);
+    }
+
+    @Test
+    public void testInitialValueSecure() {
+        String value = Secure.getString(mContentResolver, NONEXISTENT_SETTING);
+        assertNull(value);
+    }
+
+    @Test
+    public void testInitialValueGlobal() {
+        String value = Global.getString(mContentResolver, NONEXISTENT_SETTING);
+        assertEquals("initial value", value);
+    }
+
+    @Test
+    public void testSeparateTables() {
+        Secure.putString(mContentResolver, NONEXISTENT_SETTING, "something");
+        Global.putString(mContentResolver, NONEXISTENT_SETTING, "else");
+        assertEquals("something", Secure.getString(mContentResolver, NONEXISTENT_SETTING));
+        assertEquals("else", Global.getString(mContentResolver, NONEXISTENT_SETTING));
+    }
+
+    @Test
+    public void testPassThrough() {
+        // Grab the value of a setting that is not overridden.
+        assertTrue(Secure.getInt(mContentResolver, Secure.USER_SETUP_COMPLETE, 0) != 0);
+    }
+
+    @Test
+    public void testOverrideExisting() {
+        // Grab the value of a setting that is overridden and will be different than the actual
+        // value.
+        assertNull(Global.getString(mContentResolver, Global.DEVICE_PROVISIONED));
+    }
+
+    @Test
+    public void testRelease() {
+        // Verify different value.
+        assertNull(Global.getString(mContentResolver, Global.DEVICE_PROVISIONED));
+        mContext.getSettingsProvider().clearValuesAndCheck(mContext);
+        // Verify actual value after release.
+        assertEquals("1", Global.getString(mContentResolver, Global.DEVICE_PROVISIONED));
+    }
+}
diff --git a/tests/testables/tests/src/android/testing/TestableSettingsTest.java b/tests/testables/tests/src/android/testing/TestableSettingsTest.java
deleted file mode 100644
index 1b01542..0000000
--- a/tests/testables/tests/src/android/testing/TestableSettingsTest.java
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package android.testing;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-import android.content.ContentResolver;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.provider.Settings;
-import android.provider.Settings.Global;
-import android.provider.Settings.Secure;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
-import android.testing.TestableSettings.AcquireTimeoutException;
-import android.testing.TestableSettings.SettingOverrider;
-import android.util.Log;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(AndroidJUnit4.class)
-public class TestableSettingsTest {
-
-    public static final String NONEXISTENT_SETTING = "nonexistent_setting";
-    private static final String TAG = "TestableSettingsTest";
-    private SettingOverrider mOverrider;
-    private ContentResolver mContentResolver;
-    @Rule
-    public final TestableContext mContext =
-            new TestableContext(InstrumentationRegistry.getContext());
-
-    @Before
-    public void setup() throws AcquireTimeoutException {
-        mOverrider = mContext.getSettingsProvider().acquireOverridesBuilder()
-                .addSetting("secure", NONEXISTENT_SETTING)
-                .addSetting("global", NONEXISTENT_SETTING, "initial value")
-                .addSetting("global", Global.DEVICE_PROVISIONED)
-                .build();
-        mContentResolver = mContext.getContentResolver();
-    }
-
-    @Test
-    public void testInitialValueSecure() {
-        String value = Secure.getString(mContentResolver, NONEXISTENT_SETTING);
-        assertNull(value);
-    }
-
-    @Test
-    public void testInitialValueGlobal() {
-        String value = Global.getString(mContentResolver, NONEXISTENT_SETTING);
-        assertEquals("initial value", value);
-    }
-
-    @Test
-    public void testSeparateTables() {
-        Secure.putString(mContentResolver, NONEXISTENT_SETTING, "something");
-        Global.putString(mContentResolver, NONEXISTENT_SETTING, "else");
-        assertEquals("something", Secure.getString(mContentResolver, NONEXISTENT_SETTING));
-        assertEquals("something", mOverrider.get("secure", NONEXISTENT_SETTING));
-        assertEquals("else", Global.getString(mContentResolver, NONEXISTENT_SETTING));
-        assertEquals("else", mOverrider.get("global", NONEXISTENT_SETTING));
-    }
-
-    @Test
-    public void testPassThrough() {
-        // Grab the value of a setting that is not overridden.
-        assertTrue(Secure.getInt(mContentResolver, Secure.USER_SETUP_COMPLETE, 0) != 0);
-    }
-
-    @Test
-    public void testOverrideExisting() {
-        // Grab the value of a setting that is overridden and will be different than the actual
-        // value.
-        assertNull(Global.getString(mContentResolver, Global.DEVICE_PROVISIONED));
-    }
-
-    @Test
-    public void testRelease() {
-        // Verify different value.
-        assertNull(Global.getString(mContentResolver, Global.DEVICE_PROVISIONED));
-        mOverrider.release();
-        mOverrider = null;
-        // Verify actual value after release.
-        assertEquals("1", Global.getString(mContentResolver, Global.DEVICE_PROVISIONED));
-    }
-
-    @Test
-    public void testAutoRelease() throws Exception {
-        mOverrider.release();
-        mOverrider = null;
-        mContext.getSettingsProvider().acquireOverridesBuilder()
-                .addSetting("global", Global.DEVICE_PROVISIONED)
-                .build();
-    }
-
-    @Test
-    public void testContention() throws AcquireTimeoutException, InterruptedException {
-        SettingOverrider[] overriders = new SettingOverrider[2];
-        Object lock = new Object();
-        String secure = "secure";
-        String key = "something shared";
-        String[] result = new String[1];
-        overriders[0] = mContext.getSettingsProvider().acquireOverridesBuilder()
-                .addSetting(secure, key, "Some craziness")
-                .build();
-        synchronized (lock) {
-            HandlerThread t = runOnHandler(() -> {
-                try {
-                    // Grab the lock that will be used for the settings ownership to ensure
-                    // we have some contention going on.
-                    synchronized (mContext.getSettingsProvider().getLock()) {
-                        synchronized (lock) {
-                            // Let the other thread know to release the settings, but it won't
-                            // be able to until this thread waits in the build() method.
-                            lock.notify();
-                        }
-                        overriders[1] = mContext.getSettingsProvider()
-                                .acquireOverridesBuilder()
-                                .addSetting(secure, key, "default value")
-                                .build();
-                        // Ensure that the default is the one we set, and not left over from
-                        // the other setting override.
-                        result[0] = Settings.Secure.getString(mContentResolver, key);
-                        synchronized (lock) {
-                            // Let the main thread know we are done.
-                            lock.notify();
-                        }
-                    }
-                } catch (AcquireTimeoutException e) {
-                    Log.e(TAG, "Couldn't acquire setting", e);
-                }
-            });
-            // Wait for the thread to hold the acquire lock, then release the settings.
-            lock.wait();
-            overriders[0].release();
-            // Wait for the thread to be done getting the value.
-            lock.wait();
-            // Quit and cleanup.
-            t.quitSafely();
-            assertNotNull(overriders[1]);
-            overriders[1].release();
-        }
-        // Verify the value was the expected one from the thread's SettingOverride.
-        assertEquals("default value", result[0]);
-    }
-
-    private HandlerThread runOnHandler(Runnable r) {
-        HandlerThread t = new HandlerThread("Test Thread");
-        t.start();
-        new Handler(t.getLooper()).post(r);
-        return t;
-    }
-}
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index 7defa7c..e31a74b 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -228,9 +228,9 @@
      */
     public int networkId;
 
+    // Fixme We need remove this field to use only Quality network selection status only
     /**
      * The current status of this network configuration entry.
-     * Fixme We need remove this field to use only Quality network selection status only
      * @see Status
      */
     public int status;
@@ -238,8 +238,8 @@
     /**
      * The network's SSID. Can either be an ASCII string,
      * which must be enclosed in double quotation marks
-     * (e.g., {@code "MyNetwork"}, or a string of
-     * hex digits,which are not enclosed in quotes
+     * (e.g., {@code "MyNetwork"}), or a string of
+     * hex digits, which are not enclosed in quotes
      * (e.g., {@code 01a243f405}).
      */
     public String SSID;
@@ -290,9 +290,10 @@
      * string otherwise.
      */
     public String preSharedKey;
+
     /**
      * Up to four WEP keys. Either an ASCII string enclosed in double
-     * quotation marks (e.g., {@code "abcdef"} or a string
+     * quotation marks (e.g., {@code "abcdef"}) or a string
      * of hex digits (e.g., {@code 0102030405}).
      * <p/>
      * When the value of one of these keys is read, the actual key is