Merge "Remove ZigZagClassifer from lock-icon longpress falsing algo" into sc-qpr1-dev
diff --git a/packages/SystemUI/res/layout/internet_connectivity_dialog.xml b/packages/SystemUI/res/layout/internet_connectivity_dialog.xml
index 5b58fe8..b841419 100644
--- a/packages/SystemUI/res/layout/internet_connectivity_dialog.xml
+++ b/packages/SystemUI/res/layout/internet_connectivity_dialog.xml
@@ -30,7 +30,7 @@
         style="@style/Widget.SliceView.Panel"
         android:gravity="center_vertical|center_horizontal"
         android:layout_marginTop="24dp"
-        android:layout_marginBottom="16dp"
+        android:layout_marginBottom="@dimen/internet_dialog_network_layout_margin"
         android:orientation="vertical">
 
         <TextView
@@ -57,7 +57,7 @@
     <LinearLayout
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:layout_marginBottom="16dp"
+        android:layout_marginBottom="@dimen/internet_dialog_network_layout_margin"
         android:orientation="vertical">
 
         <View
@@ -101,8 +101,8 @@
                     android:background="?android:attr/selectableItemBackground"
                     android:layout_gravity="center_vertical|start"
                     android:orientation="horizontal"
-                    android:layout_marginEnd="@dimen/settingslib_switchbar_margin"
-                    android:layout_marginStart="@dimen/settingslib_switchbar_margin"
+                    android:layout_marginEnd="@dimen/internet_dialog_network_layout_margin"
+                    android:layout_marginStart="@dimen/internet_dialog_network_layout_margin"
                     android:paddingStart="22dp"
                     android:paddingEnd="22dp">
 
@@ -130,24 +130,24 @@
                         <TextView
                             android:id="@+id/mobile_title"
                             android:textDirection="locale"
-                            android:layout_marginStart="16dp"
+                            android:layout_marginStart="@dimen/internet_dialog_network_layout_margin"
+                            android:layout_marginEnd="7dp"
                             android:layout_width="wrap_content"
                             android:layout_height="wrap_content"
                             android:layout_gravity="center_vertical|start"
                             android:ellipsize="end"
-                            android:maxLines="1"
                             android:textColor="?android:attr/textColorPrimary"
                             android:textSize="16sp"
                             android:fontFamily="google-sans"/>
                         <TextView
                             android:id="@+id/mobile_summary"
                             android:textDirection="locale"
-                            android:layout_marginStart="16dp"
+                            android:layout_marginStart="@dimen/internet_dialog_network_layout_margin"
+                            android:layout_marginEnd="34dp"
                             android:layout_width="wrap_content"
                             android:layout_height="wrap_content"
                             android:layout_gravity="center_vertical|start"
                             android:ellipsize="end"
-                            android:maxLines="1"
                             android:textColor="?android:attr/textColorTertiary"
                             android:textSize="14sp"
                             android:fontFamily="google-sans"/>
@@ -179,8 +179,8 @@
                     android:background="?android:attr/selectableItemBackground"
                     android:gravity="center"
                     android:orientation="horizontal"
-                    android:layout_marginEnd="@dimen/settingslib_switchbar_margin"
-                    android:layout_marginStart="@dimen/settingslib_switchbar_margin"
+                    android:layout_marginEnd="@dimen/internet_dialog_network_layout_margin"
+                    android:layout_marginStart="@dimen/internet_dialog_network_layout_margin"
                     android:paddingStart="22dp"
                     android:paddingEnd="22dp">
 
@@ -191,6 +191,7 @@
                         android:layout_width="wrap_content"
                         android:layout_height="match_parent">
                         <TextView
+                            android:id="@+id/wifi_toggle_title"
                             android:text="@string/turn_on_wifi"
                             android:textDirection="locale"
                             android:layout_width="wrap_content"
@@ -229,10 +230,10 @@
                     android:visibility="gone"
                     android:background="?android:attr/selectableItemBackground"
                     android:orientation="horizontal"
-                    android:layout_marginEnd="@dimen/settingslib_switchbar_margin"
-                    android:layout_marginStart="@dimen/settingslib_switchbar_margin"
-                    android:paddingStart="22dp"
-                    android:paddingEnd="22dp">
+                    android:layout_marginStart="@dimen/internet_dialog_network_layout_margin"
+                    android:layout_marginEnd="@dimen/internet_dialog_network_layout_margin"
+                    android:paddingStart="20dp"
+                    android:paddingEnd="24dp">
 
                     <FrameLayout
                         android:layout_width="24dp"
@@ -247,12 +248,13 @@
                     </FrameLayout>
 
                     <LinearLayout
-                        android:layout_weight="3"
                         android:id="@+id/wifi_connected_list"
                         android:orientation="vertical"
                         android:clickable="false"
                         android:layout_width="wrap_content"
                         android:layout_height="72dp"
+                        android:layout_marginEnd="30dp"
+                        android:layout_weight="1"
                         android:gravity="start|center_vertical">
                         <TextView
                             android:id="@+id/wifi_connected_title"
@@ -260,9 +262,8 @@
                             android:layout_width="wrap_content"
                             android:layout_height="wrap_content"
                             android:layout_gravity="center_vertical|start"
-                            android:layout_marginStart="16dp"
+                            android:layout_marginStart="@dimen/internet_dialog_network_layout_margin"
                             android:ellipsize="end"
-                            android:maxLines="1"
                             android:textColor="?android:attr/textColorPrimary"
                             android:textSize="14sp"
                             android:fontFamily="google-sans"/>
@@ -272,9 +273,8 @@
                             android:layout_width="wrap_content"
                             android:layout_height="wrap_content"
                             android:layout_gravity="center_vertical|start"
-                            android:layout_marginStart="16dp"
+                            android:layout_marginStart="@dimen/internet_dialog_network_layout_margin"
                             android:ellipsize="end"
-                            android:maxLines="1"
                             android:textColor="?android:attr/textColorTertiary"
                             android:textSize="14sp"
                             android:fontFamily="google-sans"/>
@@ -283,14 +283,14 @@
                     <FrameLayout
                         android:layout_width="24dp"
                         android:layout_height="match_parent"
-                        android:layout_marginEnd="5dp"
                         android:clickable="false"
+                        android:layout_gravity="end|center_vertical"
                         android:gravity="center">
                         <ImageView
                             android:id="@+id/wifi_settings_icon"
                             android:src="@drawable/ic_settings_24dp"
                             android:layout_width="24dp"
-                            android:layout_gravity="center"
+                            android:layout_gravity="end|center_vertical"
                             android:layout_height="wrap_content"/>
                     </FrameLayout>
 
@@ -323,7 +323,7 @@
                     android:layout_height="24dp"
                     android:clickable="false"
                     android:layout_gravity="center_vertical|start"
-                    android:layout_marginStart="16dp">
+                    android:layout_marginStart="@dimen/internet_dialog_network_layout_margin">
                     <ImageView
                         android:id="@+id/arrow_forward"
                         android:src="@drawable/ic_arrow_forward"
@@ -337,7 +337,7 @@
                     android:clickable="false"
                     android:layout_width="match_parent"
                     android:layout_height="match_parent"
-                    android:layout_marginStart="16dp">
+                    android:layout_marginStart="@dimen/internet_dialog_network_layout_margin">
                     <TextView
                         android:text="@string/see_all_networks"
                         android:textDirection="locale"
diff --git a/packages/SystemUI/res/layout/internet_list_item.xml b/packages/SystemUI/res/layout/internet_list_item.xml
index 19b1ef9..b52933d 100644
--- a/packages/SystemUI/res/layout/internet_list_item.xml
+++ b/packages/SystemUI/res/layout/internet_list_item.xml
@@ -31,15 +31,14 @@
         android:focusable="true"
         android:background="?android:attr/selectableItemBackground"
         android:orientation="horizontal"
-        android:paddingStart="22dp"
-        android:paddingEnd="22dp">
-
+        android:paddingStart="20dp"
+        android:paddingEnd="40dp">
         <FrameLayout
             android:layout_width="24dp"
             android:layout_height="24dp"
             android:clickable="false"
             android:layout_gravity="center_vertical|start"
-            android:layout_marginStart="16dp">
+            android:layout_marginStart="@dimen/internet_dialog_network_layout_margin">
             <ImageView
                 android:id="@+id/wifi_icon"
                 android:layout_width="wrap_content"
@@ -48,52 +47,47 @@
         </FrameLayout>
 
         <LinearLayout
-            android:layout_weight="3"
             android:id="@+id/wifi_network_layout"
             android:orientation="vertical"
             android:clickable="false"
             android:layout_width="wrap_content"
-            android:layout_height="72dp">
+            android:layout_height="72dp"
+            android:layout_weight="1"
+            android:gravity="start|center_vertical"
+            android:layout_marginStart="@dimen/internet_dialog_network_layout_margin">
             <TextView
                 android:id="@+id/wifi_title"
                 android:textDirection="locale"
-                android:layout_weight="1"
                 android:layout_width="wrap_content"
-                android:layout_height="0dp"
-                android:layout_gravity="center_vertical|start"
+                android:layout_height="20dp"
                 android:gravity="start|center_vertical"
-                android:layout_marginStart="16dp"
                 android:ellipsize="end"
-                android:maxLines="1"
                 android:textColor="?android:attr/textColorPrimary"
                 android:textSize="14sp"
-                android:fontFamily="google-sans"/>
+                android:fontFamily="google-sans"
+                android:layout_marginEnd="18dp"/>
             <TextView
                 android:id="@+id/wifi_summary"
                 android:textDirection="locale"
-                android:layout_weight="1"
                 android:layout_width="wrap_content"
-                android:layout_height="0dp"
-                android:layout_gravity="center_vertical|start"
+                android:layout_height="20dp"
                 android:gravity="start|center_vertical"
-                android:layout_marginStart="16dp"
                 android:ellipsize="end"
-                android:maxLines="1"
                 android:textColor="?android:attr/textColorSecondary"
                 android:textSize="14sp"
-                android:fontFamily="google-sans"/>
+                android:fontFamily="google-sans"
+                android:layout_marginEnd="18dp"/>
         </LinearLayout>
 
         <FrameLayout
             android:layout_width="24dp"
             android:layout_height="match_parent"
-            android:layout_marginEnd="@dimen/settingslib_switchbar_padding_right"
             android:clickable="false"
-            android:gravity="center">
+            android:layout_gravity="end|center_vertical">
             <ImageView
                 android:id="@+id/wifi_locked_icon"
+                android:layout_gravity="end|center_vertical"
                 android:layout_width="wrap_content"
-                android:layout_gravity="center"
                 android:layout_height="wrap_content"/>
         </FrameLayout>
 
diff --git a/packages/SystemUI/res/values-sw600dp/dimens.xml b/packages/SystemUI/res/values-sw600dp/dimens.xml
index da80b85..0a34dfd 100644
--- a/packages/SystemUI/res/values-sw600dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp/dimens.xml
@@ -95,4 +95,7 @@
     <dimen name="controls_top_margin">24dp</dimen>
 
     <dimen name="global_actions_grid_item_layout_height">80dp</dimen>
+
+    <!-- Internet panel related dimensions -->
+    <dimen name="internet_dialog_list_max_width">624dp</dimen>
 </resources>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 2554548..ac7ad5d 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -1594,15 +1594,16 @@
     <!-- Internet panel related dimensions -->
     <dimen name="internet_dialog_list_margin">12dp</dimen>
     <dimen name="internet_dialog_list_max_height">646dp</dimen>
-    <dimen name="internet_dialog_list_max_width">412dp</dimen>
+    <dimen name="internet_dialog_list_max_width">@dimen/match_parent</dimen>
 
     <!-- Signal icon in internet dialog -->
     <dimen name="signal_strength_icon_size">24dp</dimen>
 
     <!-- Internet dialog related dimensions -->
     <dimen name="internet_dialog_corner_radius">24dp</dimen>
-
-    <!-- Size of internet dialog -->
+    <!-- End margin of network layout -->
+    <dimen name="internet_dialog_network_layout_margin">16dp</dimen>
+    <!-- Size of switch bar in internet dialog -->
     <dimen name="settingslib_switchbar_margin">16dp</dimen>
     <!-- Minimum width of switch -->
     <dimen name="settingslib_min_switch_width">52dp</dimen>
diff --git a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
index a68f796..c8f8404 100644
--- a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
@@ -20,6 +20,8 @@
 import android.graphics.Bitmap;
 import android.graphics.Rect;
 import android.graphics.RectF;
+import android.hardware.display.DisplayManager;
+import android.hardware.display.DisplayManager.DisplayListener;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.SystemClock;
@@ -29,7 +31,6 @@
 import android.util.Log;
 import android.util.MathUtils;
 import android.util.Size;
-import android.view.DisplayInfo;
 import android.view.SurfaceHolder;
 import android.view.WindowManager;
 
@@ -90,7 +91,7 @@
         mMiniBitmap = null;
     }
 
-    class GLEngine extends Engine {
+    class GLEngine extends Engine implements DisplayListener {
         // Surface is rejected if size below a threshold on some devices (ie. 8px on elfin)
         // set min to 64 px (CTS covers this), please refer to ag/4867989 for detail.
         @VisibleForTesting
@@ -102,15 +103,15 @@
         private EglHelper mEglHelper;
         private final Runnable mFinishRenderingTask = this::finishRendering;
         private boolean mNeedRedraw;
-        private int mWidth = 1;
-        private int mHeight = 1;
+
+        private boolean mDisplaySizeValid = false;
+        private int mDisplayWidth = 1;
+        private int mDisplayHeight = 1;
+
         private int mImgWidth = 1;
         private int mImgHeight = 1;
-        private float mPageWidth = 1.f;
-        private float mPageOffset = 1.f;
 
-        GLEngine() {
-        }
+        GLEngine() { }
 
         @VisibleForTesting
         GLEngine(Handler handler) {
@@ -124,13 +125,23 @@
             mRenderer = getRendererInstance();
             setFixedSizeAllowed(true);
             updateSurfaceSize();
-            Rect window = getDisplayContext()
-                    .getSystemService(WindowManager.class)
-                    .getCurrentWindowMetrics()
-                    .getBounds();
-            mHeight = window.height();
-            mWidth = window.width();
+
             mRenderer.setOnBitmapChanged(this::updateMiniBitmap);
+            getDisplayContext().getSystemService(DisplayManager.class)
+                    .registerDisplayListener(this, mWorker.getThreadHandler());
+        }
+
+        @Override
+        public void onDisplayAdded(int displayId) { }
+
+        @Override
+        public void onDisplayRemoved(int displayId) { }
+
+        @Override
+        public void onDisplayChanged(int displayId) {
+            if (displayId == getDisplayContext().getDisplayId()) {
+                mDisplaySizeValid = false;
+            }
         }
 
         EglHelper getEglHelperInstance() {
@@ -154,26 +165,10 @@
             if (pages == mPages) return;
             mPages = pages;
             if (mMiniBitmap == null || mMiniBitmap.isRecycled()) return;
-            updateShift();
             mWorker.getThreadHandler().post(() ->
                     computeAndNotifyLocalColors(new ArrayList<>(mColorAreas), mMiniBitmap));
         }
 
-        private void updateShift() {
-            if (mImgHeight == 0) {
-                mPageOffset = 0;
-                mPageWidth = 1;
-                return;
-            }
-            // calculate shift
-            DisplayInfo displayInfo = new DisplayInfo();
-            getDisplayContext().getDisplay().getDisplayInfo(displayInfo);
-            int screenWidth = displayInfo.getNaturalWidth();
-            float imgWidth = Math.min(mImgWidth > 0 ? screenWidth / (float) mImgWidth : 1.f, 1.f);
-            mPageWidth = imgWidth;
-            mPageOffset = (1 - imgWidth) / (float) (mPages - 1);
-        }
-
         private void updateMiniBitmap(Bitmap b) {
             if (b == null) return;
             int size = Math.min(b.getWidth(), b.getHeight());
@@ -204,6 +199,8 @@
 
         @Override
         public void onDestroy() {
+            getDisplayContext().getSystemService(DisplayManager.class)
+                    .unregisterDisplayListener(this);
             mMiniBitmap = null;
             mWorker.getThreadHandler().post(() -> {
                 mRenderer.finish();
@@ -268,6 +265,16 @@
          * (1-Wr)].
          */
         private RectF pageToImgRect(RectF area) {
+            if (!mDisplaySizeValid) {
+                Rect window = getDisplayContext()
+                        .getSystemService(WindowManager.class)
+                        .getCurrentWindowMetrics()
+                        .getBounds();
+                mDisplayWidth = window.width();
+                mDisplayHeight = window.height();
+                mDisplaySizeValid = true;
+            }
+
             // Width of a page for the caller of this API.
             float virtualPageWidth = 1f / (float) mPages;
             float leftPosOnPage = (area.left % virtualPageWidth) / virtualPageWidth;
@@ -275,12 +282,24 @@
             int currentPage = (int) Math.floor(area.centerX() / virtualPageWidth);
 
             RectF imgArea = new RectF();
+
+            if (mImgWidth == 0 || mImgHeight == 0 || mDisplayWidth <= 0 || mDisplayHeight <= 0) {
+                return imgArea;
+            }
+
             imgArea.bottom = area.bottom;
             imgArea.top = area.top;
+
+            float imageScale = Math.min(((float) mImgHeight) / mDisplayHeight, 1);
+            float mappedScreenWidth = mDisplayWidth * imageScale;
+            float pageWidth = Math.min(1.0f,
+                    mImgWidth > 0 ? mappedScreenWidth / (float) mImgWidth : 1.f);
+            float pageOffset = (1 - pageWidth) / (float) (mPages - 1);
+
             imgArea.left = MathUtils.constrain(
-                    leftPosOnPage * mPageWidth + currentPage * mPageOffset, 0, 1);
+                    leftPosOnPage * pageWidth + currentPage * pageOffset, 0, 1);
             imgArea.right = MathUtils.constrain(
-                    rightPosOnPage * mPageWidth + currentPage * mPageOffset, 0, 1);
+                    rightPosOnPage * pageWidth + currentPage * pageOffset, 0, 1);
             if (imgArea.left > imgArea.right) {
                 // take full page
                 imgArea.left = 0;
@@ -293,7 +312,6 @@
         private List<WallpaperColors> getLocalWallpaperColors(@NonNull List<RectF> areas,
                 Bitmap b) {
             List<WallpaperColors> colors = new ArrayList<>(areas.size());
-            updateShift();
             for (int i = 0; i < areas.size(); i++) {
                 RectF area = pageToImgRect(areas.get(i));
                 if (area == null || !LOCAL_COLOR_BOUNDS.contains(area)) {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
index b8c15d8..f22483a 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
@@ -163,7 +163,8 @@
     public static final AudioAttributes VIBRATION_SONIFICATION_ATTRIBUTES =
             new AudioAttributes.Builder()
                     .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
-                    .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
+                    // vibration will bypass battery saver mode:
+                    .setUsage(AudioAttributes.USAGE_ASSISTANCE_ACCESSIBILITY)
                     .build();
 
     public static final VibrationEffect EFFECT_CLICK =
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java
index 2e771d6..b1cd03c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java
@@ -116,6 +116,9 @@
                     : icon.getInvisibleDrawable(mContext) : null;
             int padding = icon != null ? icon.getPadding() : 0;
             if (d != null) {
+                if (d.getConstantState() != null) {
+                    d = d.getConstantState().newDrawable();
+                }
                 d.setAutoMirrored(false);
                 d.setLayoutDirection(getLayoutDirection());
             }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTile.java
index d0a4b62..cc9e748 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTile.java
@@ -122,8 +122,9 @@
 
     @Override
     protected void handleClick(@Nullable View view) {
-        boolean canConfigMobileData = mAccessPointController.canConfigMobileData();
-        mHandler.post(() -> mInternetDialogFactory.create(true, canConfigMobileData));
+        mHandler.post(() -> mInternetDialogFactory.create(true,
+                mAccessPointController.canConfigMobileData(),
+                mAccessPointController.canConfigWifi()));
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetAdapter.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetAdapter.java
index 91c81bc5..4e897d9 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetAdapter.java
@@ -24,7 +24,6 @@
 import android.graphics.drawable.Drawable;
 import android.text.Html;
 import android.text.TextUtils;
-import android.util.Log;
 import android.view.Gravity;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -34,6 +33,7 @@
 import android.widget.TextView;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 import androidx.recyclerview.widget.RecyclerView;
 
 import com.android.settingslib.Utils;
@@ -43,7 +43,6 @@
 
 import java.util.List;
 import java.util.concurrent.atomic.AtomicReference;
-import java.util.stream.Collectors;
 
 /**
  * Adapter for showing Wi-Fi networks.
@@ -54,9 +53,10 @@
     private static final String ACTION_WIFI_DIALOG = "com.android.settings.WIFI_DIALOG";
     private static final String EXTRA_CHOSEN_WIFI_ENTRY_KEY = "key_chosen_wifientry_key";
     private static final String EXTRA_CONNECT_FOR_CALLER = "connect_for_caller";
-    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
     private final InternetDialogController mInternetDialogController;
+    private List<WifiEntry> mWifiEntries;
+    private int mWifiEntriesCount;
 
     protected View mHolderView;
     protected Context mContext;
@@ -76,54 +76,31 @@
 
     @Override
     public void onBindViewHolder(@NonNull InternetViewHolder viewHolder, int position) {
-        List<WifiEntry> wifiList = getWifiEntryList();
-        if (wifiList != null && wifiList.size() != 0) {
-            int count = getItemCount();
-            if (wifiList.size() > count) {
-                wifiList = getWifiEntryList().subList(0, count - 1);
-            }
-
-            if (position < wifiList.size()) {
-                viewHolder.onBind(wifiList.get(position));
-            }
-        } else if (DEBUG) {
-            Log.d(TAG, "onBindViewHolder, Wi-Fi entry list = null");
+        if (mWifiEntries == null || position >= mWifiEntriesCount) {
+            return;
         }
-    }
-
-    private List<WifiEntry> getWifiEntryList() {
-        if (mInternetDialogController.getWifiEntryList() == null) {
-            return null;
-        }
-
-        return mInternetDialogController.getWifiEntryList().stream()
-                .filter(wifiEntry -> (!wifiEntry.isDefaultNetwork()
-                        || !wifiEntry.hasInternetAccess()))
-                .limit(getItemCount())
-                .collect(Collectors.toList());
+        viewHolder.onBind(mWifiEntries.get(position));
     }
 
     /**
-     * The total number of networks (mobile network and entries of Wi-Fi) should be four in
-     * {@link InternetDialog}.
+     * Updates the Wi-Fi networks.
      *
-     * Airplane mode is ON (mobile network is gone):
-     *   Return four Wi-Fi's entries if no internet Wi-Fi.
-     *   Return three Wi-Fi's entries if one internet Wi-Fi.
-     * Airplane mode is OFF (mobile network is visible):
-     *   Return three Wi-Fi's entries if no internet Wi-Fi.
-     *   Return two Wi-Fi's entries if one internet Wi-Fi.
+     * @param wifiEntries the updated Wi-Fi entries.
+     * @param wifiEntriesCount the total number of Wi-Fi entries.
+     */
+    public void setWifiEntries(@Nullable List<WifiEntry> wifiEntries, int wifiEntriesCount) {
+        mWifiEntries = wifiEntries;
+        mWifiEntriesCount = wifiEntriesCount;
+    }
+
+    /**
+     * Gets the total number of Wi-Fi networks.
      *
-     * @return The total number of networks.
+     * @return The total number of Wi-Fi entries.
      */
     @Override
     public int getItemCount() {
-        final boolean hasInternetWifi = mInternetDialogController.getInternetWifiEntry() != null;
-        if (mInternetDialogController.isAirplaneModeEnabled()) {
-            return hasInternetWifi ? 3 : 4;
-        } else {
-            return hasInternetWifi ? 2 : 3;
-        }
+        return mWifiEntriesCount;
     }
 
     /**
@@ -198,18 +175,18 @@
             mWifiNetworkLayout.setVisibility(View.VISIBLE);
             mWifiTitleText.setText(title);
             if (TextUtils.isEmpty(summary)) {
-                mWifiTitleText.setGravity(Gravity.CENTER);
                 mWifiSummaryText.setVisibility(View.GONE);
                 return;
             } else {
-                mWifiTitleText.setGravity(Gravity.BOTTOM);
-                mWifiSummaryText.setGravity(Gravity.TOP);
                 mWifiSummaryText.setVisibility(View.VISIBLE);
             }
             mWifiSummaryText.setText(summary);
         }
 
         Drawable getWifiDrawable(@NonNull WifiEntry wifiEntry) throws Throwable {
+            if (wifiEntry.getLevel() == WifiEntry.WIFI_LEVEL_UNREACHABLE) {
+                return null;
+            }
             final Drawable drawable = mWifiIconInjector.getIcon(wifiEntry.shouldShowXLevelIcon(),
                     wifiEntry.getLevel());
             if (drawable == null) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialog.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialog.java
index e1e0ba7..4d0cbd1 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialog.java
@@ -21,13 +21,11 @@
 
 import android.app.AlertDialog;
 import android.content.Context;
-import android.content.Intent;
 import android.graphics.Color;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
 import android.net.Network;
 import android.net.NetworkCapabilities;
-import android.net.wifi.ScanResult;
 import android.net.wifi.WifiManager;
 import android.os.Bundle;
 import android.os.Handler;
@@ -51,11 +49,12 @@
 import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.ProgressBar;
-import android.widget.Space;
 import android.widget.Switch;
 import android.widget.TextView;
 
+import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
+import androidx.annotation.WorkerThread;
 import androidx.recyclerview.widget.LinearLayoutManager;
 import androidx.recyclerview.widget.RecyclerView;
 
@@ -92,7 +91,7 @@
     @VisibleForTesting
     protected View mDialogView;
     @VisibleForTesting
-    protected WifiEntry mConnectedWifiEntry;
+    protected boolean mCanConfigWifi;
 
     private InternetDialogFactory mInternetDialogFactory;
     private SubscriptionManager mSubscriptionManager;
@@ -105,12 +104,14 @@
     private TextView mInternetDialogSubTitle;
     private View mDivider;
     private ProgressBar mProgressBar;
+    private LinearLayout mInternetDialogLayout;
     private LinearLayout mInternetListLayout;
     private LinearLayout mConnectedWifListLayout;
     private LinearLayout mConnectedWifList;
     private LinearLayout mMobileNetworkLayout;
     private LinearLayout mMobileNetworkList;
     private LinearLayout mTurnWifiOnLayout;
+    private TextView mWifiToggleTitleText;
     private LinearLayout mSeeAllLayout;
     private RecyclerView mWifiRecyclerView;
     private ImageView mConnectedWifiIcon;
@@ -125,10 +126,14 @@
     private Button mDoneButton;
     private Drawable mBackgroundOn;
     private int mListMaxHeight;
-    private int mListMaxWidth;
+    private int mLayoutWidth;
     private int mDefaultDataSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
     private boolean mCanConfigMobileData;
 
+    // Wi-Fi entries
+    protected WifiEntry mConnectedWifiEntry;
+    protected int mWifiEntriesCount;
+
     // Wi-Fi scanning progress bar
     protected boolean mIsProgressBarVisible;
     protected boolean mIsSearchingHidden;
@@ -142,16 +147,17 @@
 
     private final ViewTreeObserver.OnGlobalLayoutListener mInternetListLayoutListener = () -> {
         // Set max height for list
-        if (mInternetListLayout.getHeight() > mListMaxHeight) {
-            ViewGroup.LayoutParams params = mInternetListLayout.getLayoutParams();
+        if (mInternetDialogLayout.getHeight() > mListMaxHeight) {
+            ViewGroup.LayoutParams params = mInternetDialogLayout.getLayoutParams();
             params.height = mListMaxHeight;
-            mInternetListLayout.setLayoutParams(params);
+            mInternetDialogLayout.setLayoutParams(params);
         }
     };
 
     public InternetDialog(Context context, InternetDialogFactory internetDialogFactory,
             InternetDialogController internetDialogController, boolean canConfigMobileData,
-            boolean aboveStatusBar, UiEventLogger uiEventLogger, @Main Handler handler) {
+            boolean canConfigWifi, boolean aboveStatusBar, UiEventLogger uiEventLogger,
+            @Main Handler handler) {
         super(context, R.style.Theme_SystemUI_Dialog_Internet);
         if (DEBUG) {
             Log.d(TAG, "Init InternetDialog");
@@ -165,6 +171,7 @@
         mTelephonyManager = mInternetDialogController.getTelephonyManager();
         mWifiManager = mInternetDialogController.getWifiManager();
         mCanConfigMobileData = canConfigMobileData;
+        mCanConfigWifi = canConfigWifi;
 
         mLayoutManager = new LinearLayoutManager(mContext) {
             @Override
@@ -174,7 +181,7 @@
         };
         mListMaxHeight = context.getResources().getDimensionPixelSize(
                 R.dimen.internet_dialog_list_max_height);
-        mListMaxWidth = context.getResources().getDimensionPixelSize(
+        mLayoutWidth = context.getResources().getDimensionPixelSize(
                 R.dimen.internet_dialog_list_max_width);
         mUiEventLogger = uiEventLogger;
         mAdapter = new InternetAdapter(mInternetDialogController);
@@ -202,11 +209,14 @@
         layoutParams.setFitInsetsIgnoringVisibility(true);
         window.setAttributes(layoutParams);
         window.setContentView(mDialogView);
-        window.setLayout(mListMaxWidth, ViewGroup.LayoutParams.WRAP_CONTENT);
+        //Only fix the width for large screen or tablet.
+        window.setLayout(mContext.getResources().getDimensionPixelSize(
+                R.dimen.internet_dialog_list_max_width), ViewGroup.LayoutParams.WRAP_CONTENT);
         window.setWindowAnimations(R.style.Animation_InternetDialog);
         window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
         window.addFlags(FLAG_LAYOUT_NO_LIMITS);
 
+        mInternetDialogLayout = mDialogView.requireViewById(R.id.internet_connectivity_dialog);
         mInternetDialogTitle = mDialogView.requireViewById(R.id.internet_dialog_title);
         mInternetDialogSubTitle = mDialogView.requireViewById(R.id.internet_dialog_subtitle);
         mDivider = mDialogView.requireViewById(R.id.divider);
@@ -215,6 +225,7 @@
         mMobileNetworkLayout = mDialogView.requireViewById(R.id.mobile_network_layout);
         mMobileNetworkList = mDialogView.requireViewById(R.id.mobile_network_list);
         mTurnWifiOnLayout = mDialogView.requireViewById(R.id.turn_on_wifi_layout);
+        mWifiToggleTitleText = mDialogView.requireViewById(R.id.wifi_toggle_title);
         mConnectedWifListLayout = mDialogView.requireViewById(R.id.wifi_connected_layout);
         mConnectedWifList = mDialogView.requireViewById(R.id.wifi_connected_list);
         mConnectedWifiIcon = mDialogView.requireViewById(R.id.wifi_connected_icon);
@@ -230,7 +241,7 @@
         mMobileDataToggle = mDialogView.requireViewById(R.id.mobile_toggle);
         mWiFiToggle = mDialogView.requireViewById(R.id.wifi_toggle);
         mBackgroundOn = mContext.getDrawable(R.drawable.settingslib_switch_bar_bg_on);
-        mInternetListLayout.getViewTreeObserver().addOnGlobalLayoutListener(
+        mInternetDialogLayout.getViewTreeObserver().addOnGlobalLayoutListener(
                 mInternetListLayoutListener);
         mInternetDialogTitle.setText(getDialogTitleText());
         mInternetDialogTitle.setGravity(Gravity.START | Gravity.CENTER_VERTICAL);
@@ -247,7 +258,19 @@
         if (DEBUG) {
             Log.d(TAG, "onStart");
         }
-        mInternetDialogController.onStart(this);
+        mInternetDialogController.onStart(this, mCanConfigWifi);
+        if (!mCanConfigWifi) {
+            hideWifiViews();
+        }
+    }
+
+    @VisibleForTesting
+    void hideWifiViews() {
+        setProgressBarVisible(false);
+        mTurnWifiOnLayout.setVisibility(View.GONE);
+        mConnectedWifListLayout.setVisibility(View.GONE);
+        mWifiRecyclerView.setVisibility(View.GONE);
+        mSeeAllLayout.setVisibility(View.GONE);
     }
 
     @Override
@@ -286,23 +309,22 @@
         } else {
             mInternetDialogSubTitle.setText(getSubtitleText());
         }
-        showProgressBar();
         setMobileDataLayout(mInternetDialogController.activeNetworkIsCellular());
 
+        if (!mCanConfigWifi) {
+            return;
+        }
+
+        showProgressBar();
         final boolean isDeviceLocked = mInternetDialogController.isDeviceLocked();
         final boolean isWifiEnabled = mWifiManager.isWifiEnabled();
         updateWifiToggle(isWifiEnabled, isDeviceLocked);
         updateConnectedWifi(isWifiEnabled, isDeviceLocked);
 
-        List<WifiEntry> wifiEntryList = mInternetDialogController.getWifiEntryList();
-        final int wifiListVisibility =
-                (isDeviceLocked || wifiEntryList == null || wifiEntryList.size() <= 0)
-                        ? View.GONE : View.VISIBLE;
-        mWifiRecyclerView.setVisibility(wifiListVisibility);
-        if (wifiListVisibility == View.VISIBLE) {
-            mAdapter.notifyDataSetChanged();
-        }
-        mSeeAllLayout.setVisibility(wifiListVisibility);
+        final int visibility = (isDeviceLocked || !isWifiEnabled || mWifiEntriesCount <= 0)
+                ? View.GONE : View.VISIBLE;
+        mWifiRecyclerView.setVisibility(visibility);
+        mSeeAllLayout.setVisibility(visibility);
     }
 
     private void setOnClickListener() {
@@ -368,6 +390,12 @@
 
     private void updateWifiToggle(boolean isWifiEnabled, boolean isDeviceLocked) {
         mWiFiToggle.setChecked(isWifiEnabled);
+        if (isDeviceLocked && mInternetDialogController.isNightMode()) {
+            int titleColor = mConnectedWifiEntry != null ? mContext.getColor(
+                    R.color.connected_network_primary_color) : Utils.getColorAttrDefaultColor(
+                    mContext, android.R.attr.textColorPrimary);
+            mWifiToggleTitleText.setTextColor(titleColor);
+        }
         mTurnWifiOnLayout.setBackground(
                 (isDeviceLocked && mConnectedWifiEntry != null) ? mBackgroundOn : null);
     }
@@ -379,8 +407,8 @@
             return;
         }
         mConnectedWifListLayout.setVisibility(View.VISIBLE);
-        mConnectedWifiTitleText.setText(mInternetDialogController.getInternetWifiTitle());
-        mConnectedWifiSummaryText.setText(mInternetDialogController.getInternetWifiSummary());
+        mConnectedWifiTitleText.setText(mConnectedWifiEntry.getTitle());
+        mConnectedWifiSummaryText.setText(mConnectedWifiEntry.getSummary(false));
         mConnectedWifiIcon.setImageDrawable(
                 mInternetDialogController.getInternetWifiDrawable(mConnectedWifiEntry));
         if (mInternetDialogController.isNightMode()) {
@@ -430,8 +458,7 @@
             return;
         }
         setProgressBarVisible(true);
-        List<ScanResult> wifiScanResults = mWifiManager.getScanResults();
-        if (wifiScanResults != null && wifiScanResults.size() > 0) {
+        if (mConnectedWifiEntry != null || mWifiEntriesCount > 0) {
             mHandler.postDelayed(mHideProgressBarRunnable, PROGRESS_DELAY_MS);
         } else if (!mIsSearchingHidden) {
             mHandler.postDelayed(mHideSearchingRunnable, PROGRESS_DELAY_MS);
@@ -516,8 +543,8 @@
     }
 
     @Override
+    @WorkerThread
     public void onDataConnectionStateChanged(int state, int networkType) {
-        mAdapter.notifyDataSetChanged();
         mHandler.post(() -> updateDialog());
     }
 
@@ -532,10 +559,16 @@
     }
 
     @Override
-    public void onAccessPointsChanged(List<WifiEntry> wifiEntryList, WifiEntry connectedEntry) {
+    @WorkerThread
+    public void onAccessPointsChanged(@Nullable List<WifiEntry> wifiEntries,
+            @Nullable WifiEntry connectedEntry) {
         mConnectedWifiEntry = connectedEntry;
-        mAdapter.notifyDataSetChanged();
-        mHandler.post(() -> updateDialog());
+        mWifiEntriesCount = wifiEntries == null ? 0 : wifiEntries.size();
+        mAdapter.setWifiEntries(wifiEntries, mWifiEntriesCount);
+        mHandler.post(() -> {
+            mAdapter.notifyDataSetChanged();
+            updateDialog();
+        });
     }
 
     @Override
@@ -548,24 +581,6 @@
         }
     }
 
-    @Override
-    public void onWifiStateReceived(Context context, Intent intent) {
-        if (intent == null) {
-            return;
-        }
-
-        String action = intent.getAction();
-        if (action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {
-            mInternetDialogController.scanWifiAccessPoints();
-            showProgressBar();
-            return;
-        }
-
-        if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
-            mHandler.post(() -> updateDialog());
-        }
-    }
-
     public enum InternetDialogEvent implements UiEventLogger.UiEventEnum {
         @UiEvent(doc = "The Internet dialog became visible on the screen.")
         INTERNET_DIALOG_SHOW(843);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java
index ed32730..dfe78de8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java
@@ -32,7 +32,6 @@
 import android.net.Network;
 import android.net.NetworkCapabilities;
 import android.net.NetworkRequest;
-import android.net.wifi.ScanResult;
 import android.net.wifi.WifiManager;
 import android.os.Handler;
 import android.provider.Settings;
@@ -53,6 +52,7 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
+import androidx.annotation.WorkerThread;
 
 import com.android.internal.logging.UiEventLogger;
 import com.android.keyguard.KeyguardUpdateMonitor;
@@ -108,6 +108,8 @@
             R.string.all_network_unavailable;
     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
+    static final int MAX_WIFI_ENTRY_COUNT = 4;
+
     private WifiManager mWifiManager;
     private Context mContext;
     private SubscriptionManager mSubscriptionManager;
@@ -122,7 +124,8 @@
     private AccessPointController mAccessPointController;
     private IntentFilter mConnectionStateFilter;
     private InternetDialogCallback mCallback;
-    private List<WifiEntry> mWifiEntry;
+    private WifiEntry mConnectedEntry;
+    private int mWifiEntriesCount;
     private UiEventLogger mUiEventLogger;
     private BroadcastDispatcher mBroadcastDispatcher;
     private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
@@ -132,16 +135,15 @@
     @VisibleForTesting
     protected ActivityStarter mActivityStarter;
     @VisibleForTesting
-    protected WifiEntry mConnectedEntry;
-    @VisibleForTesting
     protected SubscriptionManager.OnSubscriptionsChangedListener mOnSubscriptionsChangedListener;
     @VisibleForTesting
     protected InternetTelephonyCallback mInternetTelephonyCallback;
     @VisibleForTesting
     protected WifiUtils.InternetIconInjector mWifiIconInjector;
-
     @VisibleForTesting
-    KeyguardStateController mKeyguardStateController;
+    protected boolean mCanConfigWifi;
+    @VisibleForTesting
+    protected KeyguardStateController mKeyguardStateController;
 
     private final KeyguardUpdateMonitorCallback mKeyguardUpdateCallback =
             new KeyguardUpdateMonitorCallback() {
@@ -183,8 +185,6 @@
         mKeyguardUpdateMonitor = keyguardUpdateMonitor;
         mKeyguardStateController = keyguardStateController;
         mConnectionStateFilter = new IntentFilter();
-        mConnectionStateFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
-        mConnectionStateFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
         mConnectionStateFilter.addAction(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED);
         mUiEventLogger = uiEventLogger;
         mActivityStarter = starter;
@@ -193,7 +193,7 @@
         mWifiIconInjector = new WifiUtils.InternetIconInjector(mContext);
     }
 
-    void onStart(@NonNull InternetDialogCallback callback) {
+    void onStart(@NonNull InternetDialogCallback callback, boolean canConfigWifi) {
         if (DEBUG) {
             Log.d(TAG, "onStart");
         }
@@ -217,6 +217,7 @@
         mConnectivityManager.registerNetworkCallback(new NetworkRequest.Builder()
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
                 .build(), new DataConnectivityListener(), mHandler);
+        mCanConfigWifi = canConfigWifi;
         scanWifiAccessPoints();
     }
 
@@ -270,7 +271,7 @@
             return null;
         }
 
-        if (!mWifiManager.isWifiEnabled()) {
+        if (mCanConfigWifi && !mWifiManager.isWifiEnabled()) {
             // When the airplane mode is off and Wi-Fi is disabled.
             //   Sub-Title: Wi-Fi is off
             if (DEBUG) {
@@ -288,12 +289,11 @@
             return mContext.getText(SUBTITLE_TEXT_UNLOCK_TO_VIEW_NETWORKS);
         }
 
-        final List<ScanResult> wifiList = mWifiManager.getScanResults();
-        if (wifiList != null && wifiList.size() != 0) {
-            return mContext.getText(SUBTITLE_TEXT_TAP_A_NETWORK_TO_CONNECT);
+        if (mConnectedEntry != null || mWifiEntriesCount > 0) {
+            return mCanConfigWifi ? mContext.getText(SUBTITLE_TEXT_TAP_A_NETWORK_TO_CONNECT) : null;
         }
 
-        if (isProgressBarVisible) {
+        if (mCanConfigWifi && isProgressBarVisible) {
             // When the Wi-Fi scan result callback is received
             //   Sub-Title: Searching for networks...
             return mContext.getText(SUBTITLE_TEXT_SEARCHING_FOR_NETWORKS);
@@ -317,7 +317,7 @@
             return mContext.getText(SUBTITLE_TEXT_ALL_CARRIER_NETWORK_UNAVAILABLE);
         }
 
-        if (!isMobileDataEnabled()) {
+        if (mCanConfigWifi && !isMobileDataEnabled()) {
             if (DEBUG) {
                 Log.d(TAG, "Mobile data off");
             }
@@ -331,7 +331,10 @@
             return mContext.getText(SUBTITLE_TEXT_ALL_CARRIER_NETWORK_UNAVAILABLE);
         }
 
-        return mContext.getText(SUBTITLE_TEXT_NON_CARRIER_NETWORK_UNAVAILABLE);
+        if (mCanConfigWifi) {
+            return mContext.getText(SUBTITLE_TEXT_NON_CARRIER_NETWORK_UNAVAILABLE);
+        }
+        return null;
     }
 
     Drawable getInternetWifiDrawable(@NonNull WifiEntry wifiEntry) {
@@ -549,26 +552,6 @@
         return summary;
     }
 
-    String getInternetWifiTitle() {
-        if (getInternetWifiEntry() == null) {
-            if (DEBUG) {
-                Log.d(TAG, "connected entry is null");
-            }
-            return "";
-        }
-        return getInternetWifiEntry().getTitle();
-    }
-
-    String getInternetWifiSummary() {
-        if (getInternetWifiEntry() == null) {
-            if (DEBUG) {
-                Log.d(TAG, "connected entry is null");
-            }
-            return "";
-        }
-        return getInternetWifiEntry().getSummary(false);
-    }
-
     void launchNetworkSetting() {
         mCallback.dismissDialog();
         mActivityStarter.postStartActivityDismissingKeyguard(getSettingsIntent(), 0);
@@ -590,18 +573,6 @@
         }
     }
 
-    List<WifiEntry> getWifiEntryList() {
-        return mWifiEntry;
-    }
-
-    WifiEntry getInternetWifiEntry() {
-        if (mConnectedEntry == null || !mConnectedEntry.isDefaultNetwork()
-                || !mConnectedEntry.hasInternetAccess()) {
-            return null;
-        }
-        return mConnectedEntry;
-    }
-
     WifiManager getWifiManager() {
         return mWifiManager;
     }
@@ -779,20 +750,33 @@
         }
     }
 
-    void scanWifiAccessPoints() {
-        mAccessPointController.scanForAccessPoints();
+    private void scanWifiAccessPoints() {
+        if (mCanConfigWifi) {
+            mAccessPointController.scanForAccessPoints();
+        }
     }
 
     @Override
+    @WorkerThread
     public void onAccessPointsChanged(List<WifiEntry> accessPoints) {
-        if (accessPoints == null) {
+        if (!mCanConfigWifi) {
+            return;
+        }
+
+        if (accessPoints == null || accessPoints.size() == 0) {
+            mConnectedEntry = null;
+            mWifiEntriesCount = 0;
+            if (mCallback != null) {
+                mCallback.onAccessPointsChanged(null /* wifiEntries */, null /* connectedEntry */);
+            }
             return;
         }
 
         boolean hasConnectedWifi = false;
-        mWifiEntry = accessPoints;
-        for (WifiEntry wifiEntry : accessPoints) {
-            if (wifiEntry.getConnectedState() == WifiEntry.CONNECTED_STATE_CONNECTED) {
+        final int accessPointSize = accessPoints.size();
+        for (int i = 0; i < accessPointSize; i++) {
+            WifiEntry wifiEntry = accessPoints.get(i);
+            if (wifiEntry.isDefaultNetwork() && wifiEntry.hasInternetAccess()) {
                 mConnectedEntry = wifiEntry;
                 hasConnectedWifi = true;
                 break;
@@ -802,7 +786,23 @@
             mConnectedEntry = null;
         }
 
-        mCallback.onAccessPointsChanged(mWifiEntry, getInternetWifiEntry());
+        int count = MAX_WIFI_ENTRY_COUNT;
+        if (hasCarrier()) {
+            count -= 1;
+        }
+        if (hasConnectedWifi) {
+            count -= 1;
+        }
+        final List<WifiEntry> wifiEntries = accessPoints.stream()
+                .filter(wifiEntry -> (!wifiEntry.isDefaultNetwork()
+                        || !wifiEntry.hasInternetAccess()))
+                .limit(count)
+                .collect(Collectors.toList());
+        mWifiEntriesCount = wifiEntries == null ? 0 : wifiEntries.size();
+
+        if (mCallback != null) {
+            mCallback.onAccessPointsChanged(wifiEntries, mConnectedEntry);
+        }
     }
 
     @Override
@@ -855,8 +855,17 @@
 
     private class DataConnectivityListener extends ConnectivityManager.NetworkCallback {
         @Override
+        @WorkerThread
         public void onCapabilitiesChanged(@NonNull Network network,
                 @NonNull NetworkCapabilities networkCapabilities) {
+            if (mCanConfigWifi) {
+                for (int transport : networkCapabilities.getTransportTypes()) {
+                    if (transport == NetworkCapabilities.TRANSPORT_WIFI) {
+                        scanWifiAccessPoints();
+                        break;
+                    }
+                }
+            }
             final Network activeNetwork = mConnectivityManager.getActiveNetwork();
             if (activeNetwork != null && activeNetwork.equals(network)) {
                 // update UI
@@ -869,11 +878,6 @@
         @Override
         public void onReceive(Context context, Intent intent) {
             final String action = intent.getAction();
-            if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)
-                    || action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {
-                mCallback.onWifiStateReceived(context, intent);
-            }
-
             if (action.equals(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED)) {
                 if (DEBUG) {
                     Log.d(TAG, "ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED");
@@ -929,8 +933,7 @@
 
         void dismissDialog();
 
-        void onAccessPointsChanged(List<WifiEntry> wifiEntryList, WifiEntry connectedEntry);
-
-        void onWifiStateReceived(Context context, Intent intent);
+        void onAccessPointsChanged(@Nullable List<WifiEntry> wifiEntries,
+                @Nullable WifiEntry connectedEntry);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogFactory.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogFactory.kt
index e82e89ef1..11c6980 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogFactory.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogFactory.kt
@@ -31,17 +31,17 @@
  */
 @SysUISingleton
 class InternetDialogFactory @Inject constructor(
-        @Main private val handler: Handler,
-        private val internetDialogController: InternetDialogController,
-        private val context: Context,
-        private val uiEventLogger: UiEventLogger
+    @Main private val handler: Handler,
+    private val internetDialogController: InternetDialogController,
+    private val context: Context,
+    private val uiEventLogger: UiEventLogger
 ) {
     companion object {
         var internetDialog: InternetDialog? = null
     }
 
     /** Creates a [InternetDialog]. */
-    fun create(aboveStatusBar: Boolean, canConfigMobileData: Boolean) {
+    fun create(aboveStatusBar: Boolean, canConfigMobileData: Boolean, canConfigWifi: Boolean) {
         if (internetDialog != null) {
             if (DEBUG) {
                 Log.d(TAG, "InternetDialog is showing, do not create it twice.")
@@ -49,7 +49,7 @@
             return
         } else {
             internetDialog = InternetDialog(context, this, internetDialogController,
-                    canConfigMobileData, aboveStatusBar, uiEventLogger, handler)
+                    canConfigMobileData, canConfigWifi, aboveStatusBar, uiEventLogger, handler)
             internetDialog?.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 8bb545b..af0d413 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -801,8 +801,8 @@
                 mReceiverHandler.post(this::handleConfigurationChanged);
                 break;
             case Settings.Panel.ACTION_INTERNET_CONNECTIVITY:
-                boolean canConfigMobileData = mAccessPoints.canConfigMobileData();
-                mMainHandler.post(() -> mInternetDialogFactory.create(true, canConfigMobileData));
+                mMainHandler.post(() -> mInternetDialogFactory.create(true,
+                        mAccessPoints.canConfigMobileData(), mAccessPoints.canConfigWifi()));
                 break;
             default:
                 int subId = intent.getIntExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
index f64d517..cff2aed 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
@@ -16,6 +16,8 @@
 
 package com.android.systemui.biometrics;
 
+import static android.media.AudioAttributes.USAGE_ASSISTANCE_ACCESSIBILITY;
+
 import static junit.framework.Assert.assertEquals;
 
 import static org.mockito.ArgumentMatchers.any;
@@ -563,5 +565,10 @@
                 eq(mUdfpsController.EFFECT_CLICK),
                 eq("udfps-onStart"),
                 eq(UdfpsController.VIBRATION_SONIFICATION_ATTRIBUTES));
+
+        // THEN make sure vibration attributes has so that it always will play the haptic,
+        // even in battery saver mode
+        assertEquals(USAGE_ASSISTANCE_ACCESSIBILITY,
+                UdfpsController.VIBRATION_SONIFICATION_ATTRIBUTES.getUsage());
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSIconViewImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSIconViewImplTest.java
index 63ebe92..23e5168 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSIconViewImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSIconViewImplTest.java
@@ -18,6 +18,7 @@
 import static org.junit.Assert.assertFalse;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.argThat;
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
@@ -74,6 +75,24 @@
     }
 
     @Test
+    public void testMutateIconDrawable() {
+        SlashImageView iv = mock(SlashImageView.class);
+        Drawable originalDrawable = mock(Drawable.class);
+        Drawable otherDrawable = mock(Drawable.class);
+        State s = new State();
+        s.icon = mock(Icon.class);
+        when(s.icon.getInvisibleDrawable(eq(mContext))).thenReturn(originalDrawable);
+        when(s.icon.getDrawable(eq(mContext))).thenReturn(originalDrawable);
+        when(iv.isShown()).thenReturn(true);
+        when(originalDrawable.getConstantState()).thenReturn(fakeConstantState(otherDrawable));
+
+
+        mIconView.updateIcon(iv, s, /* allowAnimations= */true);
+
+        verify(iv).setState(any(), eq(otherDrawable));
+    }
+
+    @Test
     public void testNoFirstFade() {
         ImageView iv = mock(ImageView.class);
         State s = new State();
@@ -104,4 +123,18 @@
     public void testIconNotSet_toString() {
         assertFalse(mIconView.toString().contains("lastIcon"));
     }
+
+    private static Drawable.ConstantState fakeConstantState(Drawable otherDrawable) {
+        return new Drawable.ConstantState() {
+            @Override
+            public Drawable newDrawable() {
+                return otherDrawable;
+            }
+
+            @Override
+            public int getChangingConfigurations() {
+                return 1;
+            }
+        };
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetAdapterTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetAdapterTest.java
index 2b9082d..fa5f70c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetAdapterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetAdapterTest.java
@@ -2,8 +2,11 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -24,6 +27,7 @@
 import org.mockito.MockitoAnnotations;
 
 import java.util.Arrays;
+import java.util.List;
 
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
@@ -35,6 +39,8 @@
     @Mock
     private WifiEntry mInternetWifiEntry;
     @Mock
+    private List<WifiEntry> mWifiEntries;
+    @Mock
     private WifiEntry mWifiEntry;
     @Mock
     private InternetDialogController mInternetDialogController;
@@ -56,43 +62,17 @@
 
         mInternetAdapter = new InternetAdapter(mInternetDialogController);
         mViewHolder = mInternetAdapter.onCreateViewHolder(new LinearLayout(mContext), 0);
-        when(mInternetDialogController.getInternetWifiEntry()).thenReturn(mInternetWifiEntry);
-        when(mInternetDialogController.getWifiEntryList()).thenReturn(Arrays.asList(mWifiEntry));
+        mInternetAdapter.setWifiEntries(Arrays.asList(mWifiEntry), 1 /* wifiEntriesCount */);
         mViewHolder.mWifiIconInjector = mWifiIconInjector;
     }
 
     @Test
-    public void getItemCount_withApmOnWifiOnNoInternetWifi_returnFour() {
-        // The preconditions WiFi ON is already in setUp()
-        when(mInternetDialogController.getInternetWifiEntry()).thenReturn(null);
-        when(mInternetDialogController.isAirplaneModeEnabled()).thenReturn(true);
+    public void getItemCount_returnWifiEntriesCount() {
+        for (int i = 0; i < InternetDialogController.MAX_WIFI_ENTRY_COUNT; i++) {
+            mInternetAdapter.setWifiEntries(mWifiEntries, i /* wifiEntriesCount */);
 
-        assertThat(mInternetAdapter.getItemCount()).isEqualTo(4);
-    }
-
-    @Test
-    public void getItemCount_withApmOnWifiOnHasInternetWifi_returnThree() {
-        // The preconditions WiFi ON and Internet WiFi are already in setUp()
-        when(mInternetDialogController.isAirplaneModeEnabled()).thenReturn(true);
-
-        assertThat(mInternetAdapter.getItemCount()).isEqualTo(3);
-    }
-
-    @Test
-    public void getItemCount_withApmOffWifiOnNoInternetWifi_returnThree() {
-        // The preconditions WiFi ON is already in setUp()
-        when(mInternetDialogController.getInternetWifiEntry()).thenReturn(null);
-        when(mInternetDialogController.isAirplaneModeEnabled()).thenReturn(false);
-
-        assertThat(mInternetAdapter.getItemCount()).isEqualTo(3);
-    }
-
-    @Test
-    public void getItemCount_withApmOffWifiOnHasInternetWifi_returnTwo() {
-        // The preconditions WiFi ON and Internet WiFi are already in setUp()
-        when(mInternetDialogController.isAirplaneModeEnabled()).thenReturn(false);
-
-        assertThat(mInternetAdapter.getItemCount()).isEqualTo(2);
+            assertThat(mInternetAdapter.getItemCount()).isEqualTo(i);
+        }
     }
 
     @Test
@@ -118,7 +98,17 @@
     }
 
     @Test
-    public void onBindViewHolder_bindDefaultWifiNetwork_getIconWithInternet() {
+    public void onBindViewHolder_wifiLevelUnreachable_shouldNotGetWifiIcon() {
+        reset(mWifiIconInjector);
+        when(mWifiEntry.getLevel()).thenReturn(WifiEntry.WIFI_LEVEL_UNREACHABLE);
+
+        mInternetAdapter.onBindViewHolder(mViewHolder, 0);
+
+        verify(mWifiIconInjector, never()).getIcon(anyBoolean(), anyInt());
+    }
+
+    @Test
+    public void onBindViewHolder_shouldNotShowXLevelIcon_getIconWithInternet() {
         when(mWifiEntry.shouldShowXLevelIcon()).thenReturn(false);
 
         mInternetAdapter.onBindViewHolder(mViewHolder, 0);
@@ -127,7 +117,7 @@
     }
 
     @Test
-    public void onBindViewHolder_bindNoDefaultWifiNetwork_getIconWithNoInternet() {
+    public void onBindViewHolder_shouldShowXLevelIcon_getIconWithNoInternet() {
         when(mWifiEntry.shouldShowXLevelIcon()).thenReturn(true);
 
         mInternetAdapter.onBindViewHolder(mViewHolder, 0);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogControllerTest.java
index 830fe5a..cacc409 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogControllerTest.java
@@ -10,6 +10,7 @@
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -17,7 +18,6 @@
 import android.content.Intent;
 import android.graphics.drawable.Drawable;
 import android.net.ConnectivityManager;
-import android.net.wifi.ScanResult;
 import android.net.wifi.WifiManager;
 import android.os.Handler;
 import android.telephony.ServiceState;
@@ -84,14 +84,26 @@
     @Mock
     private WifiEntry mConnectedEntry;
     @Mock
+    private WifiEntry mWifiEntry1;
+    @Mock
+    private WifiEntry mWifiEntry2;
+    @Mock
+    private WifiEntry mWifiEntry3;
+    @Mock
+    private WifiEntry mWifiEntry4;
+    @Mock
     private ServiceState mServiceState;
     @Mock
     private BroadcastDispatcher mBroadcastDispatcher;
     @Mock
     private WifiUtils.InternetIconInjector mWifiIconInjector;
+    @Mock
+    InternetDialogController.InternetDialogCallback mInternetDialogCallback;
 
     private MockInternetDialogController mInternetDialogController;
     private FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock());
+    private List<WifiEntry> mAccessPoints = new ArrayList<>();
+    private List<WifiEntry> mWifiEntries = new ArrayList<>();
 
     @Before
     public void setUp() {
@@ -100,6 +112,13 @@
         when(mKeyguardStateController.isUnlocked()).thenReturn(true);
         when(mConnectedEntry.isDefaultNetwork()).thenReturn(true);
         when(mConnectedEntry.hasInternetAccess()).thenReturn(true);
+        when(mWifiEntry1.getConnectedState()).thenReturn(WifiEntry.CONNECTED_STATE_DISCONNECTED);
+        when(mWifiEntry2.getConnectedState()).thenReturn(WifiEntry.CONNECTED_STATE_DISCONNECTED);
+        when(mWifiEntry3.getConnectedState()).thenReturn(WifiEntry.CONNECTED_STATE_DISCONNECTED);
+        when(mWifiEntry4.getConnectedState()).thenReturn(WifiEntry.CONNECTED_STATE_DISCONNECTED);
+        mAccessPoints.add(mConnectedEntry);
+        mAccessPoints.add(mWifiEntry1);
+        when(mSubscriptionManager.getActiveSubscriptionIdList()).thenReturn(new int[]{SUB_ID});
 
         mInternetDialogController = new MockInternetDialogController(mContext,
                 mock(UiEventLogger.class), mock(ActivityStarter.class), mAccessPointController,
@@ -108,10 +127,9 @@
                 mock(KeyguardUpdateMonitor.class), mGlobalSettings, mKeyguardStateController);
         mSubscriptionManager.addOnSubscriptionsChangedListener(mExecutor,
                 mInternetDialogController.mOnSubscriptionsChangedListener);
-        mInternetDialogController.onStart(
-                mock(InternetDialogController.InternetDialogCallback.class));
+        mInternetDialogController.onStart(mInternetDialogCallback, true);
+        mInternetDialogController.onAccessPointsChanged(mAccessPoints);
         mInternetDialogController.mActivityStarter = mActivityStarter;
-        mInternetDialogController.mConnectedEntry = mConnectedEntry;
         mInternetDialogController.mWifiIconInjector = mWifiIconInjector;
     }
 
@@ -143,32 +161,46 @@
         mInternetDialogController.setAirplaneModeEnabled(false);
         when(mWifiManager.isWifiEnabled()).thenReturn(false);
 
-        assertTrue(TextUtils.equals(mInternetDialogController.getSubtitleText(false),
-                getResourcesString("wifi_is_off")));
+        assertThat(mInternetDialogController.getSubtitleText(false))
+                .isEqualTo(getResourcesString("wifi_is_off"));
+
+        // if the Wi-Fi disallow config, then don't return Wi-Fi related string.
+        mInternetDialogController.mCanConfigWifi = false;
+
+        assertThat(mInternetDialogController.getSubtitleText(false))
+                .isNotEqualTo(getResourcesString("wifi_is_off"));
     }
 
     @Test
     public void getSubtitleText_withNoWifiEntry_returnSearchWifi() {
         mInternetDialogController.setAirplaneModeEnabled(false);
         when(mWifiManager.isWifiEnabled()).thenReturn(true);
-        List<ScanResult> wifiScanResults = mock(ArrayList.class);
-        doReturn(0).when(wifiScanResults).size();
-        when(mWifiManager.getScanResults()).thenReturn(wifiScanResults);
+        mInternetDialogController.onAccessPointsChanged(null /* accessPoints */);
 
-        assertTrue(TextUtils.equals(mInternetDialogController.getSubtitleText(true),
-                getResourcesString("wifi_empty_list_wifi_on")));
+        assertThat(mInternetDialogController.getSubtitleText(true))
+                .isEqualTo(getResourcesString("wifi_empty_list_wifi_on"));
+
+        // if the Wi-Fi disallow config, then don't return Wi-Fi related string.
+        mInternetDialogController.mCanConfigWifi = false;
+
+        assertThat(mInternetDialogController.getSubtitleText(true))
+                .isNotEqualTo(getResourcesString("wifi_empty_list_wifi_on"));
     }
 
     @Test
     public void getSubtitleText_withWifiEntry_returnTapToConnect() {
+        // The preconditions WiFi Entries is already in setUp()
         mInternetDialogController.setAirplaneModeEnabled(false);
         when(mWifiManager.isWifiEnabled()).thenReturn(true);
-        List<ScanResult> wifiScanResults = mock(ArrayList.class);
-        doReturn(1).when(wifiScanResults).size();
-        when(mWifiManager.getScanResults()).thenReturn(wifiScanResults);
 
-        assertTrue(TextUtils.equals(mInternetDialogController.getSubtitleText(false),
-                getResourcesString("tap_a_network_to_connect")));
+        assertThat(mInternetDialogController.getSubtitleText(false))
+                .isEqualTo(getResourcesString("tap_a_network_to_connect"));
+
+        // if the Wi-Fi disallow config, then don't return Wi-Fi related string.
+        mInternetDialogController.mCanConfigWifi = false;
+
+        assertThat(mInternetDialogController.getSubtitleText(false))
+                .isNotEqualTo(getResourcesString("tap_a_network_to_connect"));
     }
 
     @Test
@@ -185,11 +217,7 @@
     public void getSubtitleText_withNoService_returnNoNetworksAvailable() {
         mInternetDialogController.setAirplaneModeEnabled(false);
         when(mWifiManager.isWifiEnabled()).thenReturn(true);
-        List<ScanResult> wifiScanResults = new ArrayList<>();
-        doReturn(wifiScanResults).when(mWifiManager).getScanResults();
-        when(mWifiManager.getScanResults()).thenReturn(wifiScanResults);
-        when(mSubscriptionManager.getActiveSubscriptionIdList())
-                .thenReturn(new int[] {SUB_ID});
+        mInternetDialogController.onAccessPointsChanged(null /* accessPoints */);
 
         doReturn(ServiceState.STATE_OUT_OF_SERVICE).when(mServiceState).getState();
         doReturn(mServiceState).when(mTelephonyManager).getServiceState();
@@ -203,83 +231,26 @@
     public void getSubtitleText_withMobileDataDisabled_returnNoOtherAvailable() {
         mInternetDialogController.setAirplaneModeEnabled(false);
         when(mWifiManager.isWifiEnabled()).thenReturn(true);
-        List<ScanResult> wifiScanResults = new ArrayList<>();
-        doReturn(wifiScanResults).when(mWifiManager).getScanResults();
-        when(mWifiManager.getScanResults()).thenReturn(wifiScanResults);
-        when(mSubscriptionManager.getActiveSubscriptionIdList())
-                .thenReturn(new int[] {SUB_ID});
+        mInternetDialogController.onAccessPointsChanged(null /* accessPoints */);
 
         doReturn(ServiceState.STATE_IN_SERVICE).when(mServiceState).getState();
         doReturn(mServiceState).when(mTelephonyManager).getServiceState();
 
         when(mTelephonyManager.isDataEnabled()).thenReturn(false);
 
-        assertTrue(TextUtils.equals(mInternetDialogController.getSubtitleText(false),
-                getResourcesString("non_carrier_network_unavailable")));
-    }
+        assertThat(mInternetDialogController.getSubtitleText(false))
+                .isEqualTo(getResourcesString("non_carrier_network_unavailable"));
 
-    @Test
-    public void getInternetWifiEntry_connectedEntryIsNull_returnNull() {
-        mInternetDialogController.mConnectedEntry = null;
+        // if the Wi-Fi disallow config, then don't return Wi-Fi related string.
+        mInternetDialogController.mCanConfigWifi = false;
 
-        assertThat(mInternetDialogController.getInternetWifiEntry()).isNull();
-    }
-
-    @Test
-    public void getInternetWifiEntry_connectedWifiIsNotDefaultNetwork_returnNull() {
-        when(mConnectedEntry.isDefaultNetwork()).thenReturn(false);
-
-        assertThat(mInternetDialogController.getInternetWifiEntry()).isNull();
-    }
-
-    @Test
-    public void getInternetWifiEntry_connectedWifiHasNotInternetAccess_returnNull() {
-        when(mConnectedEntry.hasInternetAccess()).thenReturn(false);
-
-        assertThat(mInternetDialogController.getInternetWifiEntry()).isNull();
-    }
-
-    @Test
-    public void getInternetWifiEntry_connectedEntryIsInternetWifi_returnConnectedEntry() {
-        // The preconditions have been set in setUp().
-        //   - The connected Wi-Fi entry have both default network and internet access conditions.
-
-        assertThat(mInternetDialogController.getInternetWifiEntry()).isEqualTo(mConnectedEntry);
-    }
-
-    @Test
-    public void getInternetWifiTitle_withNoConnectedWifiEntry_returnEmpty() {
-        mInternetDialogController.mConnectedEntry = null;
-
-        assertThat(mInternetDialogController.getInternetWifiTitle()).isEmpty();
-    }
-
-    @Test
-    public void getInternetWifiTitle_withInternetWifi_returnTitle() {
-        // The preconditions have been set in setUp().
-        //   - The connected Wi-Fi entry have both default network and internet access conditions.
-        when(mConnectedEntry.getTitle()).thenReturn(CONNECTED_TITLE);
-
-        assertThat(mInternetDialogController.getInternetWifiTitle()).isEqualTo(CONNECTED_TITLE);
-    }
-
-    @Test
-    public void getInternetWifiSummary_withNoConnectedWifiEntry_returnEmpty() {
-        mInternetDialogController.mConnectedEntry = null;
-
-        assertThat(mInternetDialogController.getInternetWifiSummary()).isEmpty();
-    }
-
-    @Test
-    public void getInternetWifiSummary_withInternetWifi_returnSummary() {
-        when(mConnectedEntry.getSummary(false)).thenReturn(CONNECTED_SUMMARY);
-
-        assertThat(mInternetDialogController.getInternetWifiSummary()).isEqualTo(CONNECTED_SUMMARY);
+        assertThat(mInternetDialogController.getSubtitleText(false))
+                .isNotEqualTo(getResourcesString("non_carrier_network_unavailable"));
     }
 
     @Test
     public void getWifiDetailsSettingsIntent_withNoConnectedEntry_returnNull() {
-        mInternetDialogController.mConnectedEntry = null;
+        mInternetDialogController.onAccessPointsChanged(null /* accessPoints */);
 
         assertThat(mInternetDialogController.getWifiDetailsSettingsIntent()).isNull();
     }
@@ -311,7 +282,7 @@
 
     @Test
     public void launchWifiNetworkDetailsSetting_withNoConnectedEntry_doNothing() {
-        mInternetDialogController.mConnectedEntry = null;
+        mInternetDialogController.onAccessPointsChanged(null /* accessPoints */);
 
         mInternetDialogController.launchWifiNetworkDetailsSetting();
 
@@ -342,6 +313,143 @@
         assertThat(mInternetDialogController.isDeviceLocked()).isTrue();
     }
 
+    @Test
+    public void onAccessPointsChanged_canNotConfigWifi_doNothing() {
+        reset(mInternetDialogCallback);
+        mInternetDialogController.mCanConfigWifi = false;
+
+        mInternetDialogController.onAccessPointsChanged(null /* accessPoints */);
+
+        verify(mInternetDialogCallback, never()).onAccessPointsChanged(any(), any());
+    }
+
+    @Test
+    public void onAccessPointsChanged_nullAccessPoints_callbackBothNull() {
+        reset(mInternetDialogCallback);
+
+        mInternetDialogController.onAccessPointsChanged(null /* accessPoints */);
+
+        verify(mInternetDialogCallback)
+                .onAccessPointsChanged(null /* wifiEntries */, null /* connectedEntry */);
+    }
+
+    @Test
+    public void onAccessPointsChanged_oneConnectedEntry_callbackConnectedEntryOnly() {
+        reset(mInternetDialogCallback);
+        mInternetDialogController.setAirplaneModeEnabled(true);
+        mAccessPoints.clear();
+        mAccessPoints.add(mConnectedEntry);
+
+        mInternetDialogController.onAccessPointsChanged(mAccessPoints);
+
+        mWifiEntries.clear();
+        verify(mInternetDialogCallback).onAccessPointsChanged(mWifiEntries, mConnectedEntry);
+    }
+
+    @Test
+    public void onAccessPointsChanged_noConnectedEntryAndOneOther_callbackWifiEntriesOnly() {
+        reset(mInternetDialogCallback);
+        mInternetDialogController.setAirplaneModeEnabled(true);
+        mAccessPoints.clear();
+        mAccessPoints.add(mWifiEntry1);
+
+        mInternetDialogController.onAccessPointsChanged(mAccessPoints);
+
+        mWifiEntries.clear();
+        mWifiEntries.add(mWifiEntry1);
+        verify(mInternetDialogCallback)
+                .onAccessPointsChanged(mWifiEntries, null /* connectedEntry */);
+    }
+
+    @Test
+    public void onAccessPointsChanged_oneConnectedEntryAndOneOther_callbackCorrectly() {
+        reset(mInternetDialogCallback);
+        mInternetDialogController.setAirplaneModeEnabled(true);
+        mAccessPoints.clear();
+        mAccessPoints.add(mConnectedEntry);
+        mAccessPoints.add(mWifiEntry1);
+
+        mInternetDialogController.onAccessPointsChanged(mAccessPoints);
+
+        mWifiEntries.clear();
+        mWifiEntries.add(mWifiEntry1);
+        verify(mInternetDialogCallback).onAccessPointsChanged(mWifiEntries, mConnectedEntry);
+    }
+
+    @Test
+    public void onAccessPointsChanged_oneConnectedEntryAndTwoOthers_callbackCorrectly() {
+        reset(mInternetDialogCallback);
+        mInternetDialogController.setAirplaneModeEnabled(true);
+        mAccessPoints.clear();
+        mAccessPoints.add(mConnectedEntry);
+        mAccessPoints.add(mWifiEntry1);
+        mAccessPoints.add(mWifiEntry2);
+
+        mInternetDialogController.onAccessPointsChanged(mAccessPoints);
+
+        mWifiEntries.clear();
+        mWifiEntries.add(mWifiEntry1);
+        mWifiEntries.add(mWifiEntry2);
+        verify(mInternetDialogCallback).onAccessPointsChanged(mWifiEntries, mConnectedEntry);
+    }
+
+    @Test
+    public void onAccessPointsChanged_oneConnectedEntryAndThreeOthers_callbackCutMore() {
+        reset(mInternetDialogCallback);
+        mInternetDialogController.setAirplaneModeEnabled(true);
+        mAccessPoints.clear();
+        mAccessPoints.add(mConnectedEntry);
+        mAccessPoints.add(mWifiEntry1);
+        mAccessPoints.add(mWifiEntry2);
+        mAccessPoints.add(mWifiEntry3);
+
+        mInternetDialogController.onAccessPointsChanged(mAccessPoints);
+
+        mWifiEntries.clear();
+        mWifiEntries.add(mWifiEntry1);
+        mWifiEntries.add(mWifiEntry2);
+        mWifiEntries.add(mWifiEntry3);
+        verify(mInternetDialogCallback).onAccessPointsChanged(mWifiEntries, mConnectedEntry);
+
+        // Turn off airplane mode to has carrier network, then Wi-Fi entries will cut last one.
+        reset(mInternetDialogCallback);
+        mInternetDialogController.setAirplaneModeEnabled(false);
+
+        mInternetDialogController.onAccessPointsChanged(mAccessPoints);
+
+        mWifiEntries.remove(mWifiEntry3);
+        verify(mInternetDialogCallback).onAccessPointsChanged(mWifiEntries, mConnectedEntry);
+    }
+
+    @Test
+    public void onAccessPointsChanged_oneConnectedEntryAndFourOthers_callbackCutMore() {
+        reset(mInternetDialogCallback);
+        mInternetDialogController.setAirplaneModeEnabled(true);
+        mAccessPoints.clear();
+        mAccessPoints.add(mConnectedEntry);
+        mAccessPoints.add(mWifiEntry1);
+        mAccessPoints.add(mWifiEntry2);
+        mAccessPoints.add(mWifiEntry3);
+        mAccessPoints.add(mWifiEntry4);
+
+        mInternetDialogController.onAccessPointsChanged(mAccessPoints);
+
+        mWifiEntries.clear();
+        mWifiEntries.add(mWifiEntry1);
+        mWifiEntries.add(mWifiEntry2);
+        mWifiEntries.add(mWifiEntry3);
+        verify(mInternetDialogCallback).onAccessPointsChanged(mWifiEntries, mConnectedEntry);
+
+        // Turn off airplane mode to has carrier network, then Wi-Fi entries will cut last one.
+        reset(mInternetDialogCallback);
+        mInternetDialogController.setAirplaneModeEnabled(false);
+
+        mInternetDialogController.onAccessPointsChanged(mAccessPoints);
+
+        mWifiEntries.remove(mWifiEntry3);
+        verify(mInternetDialogCallback).onAccessPointsChanged(mWifiEntries, mConnectedEntry);
+    }
+
     private String getResourcesString(String name) {
         return mContext.getResources().getString(getResourcesId(name));
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogTest.java
index 5a018f4..fa9c053 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogTest.java
@@ -12,7 +12,6 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-import android.net.wifi.ScanResult;
 import android.net.wifi.WifiManager;
 import android.os.Handler;
 import android.telephony.TelephonyManager;
@@ -20,7 +19,6 @@
 import android.testing.TestableLooper;
 import android.view.View;
 import android.widget.LinearLayout;
-import android.widget.TextView;
 
 import androidx.recyclerview.widget.RecyclerView;
 import androidx.test.filters.SmallTest;
@@ -39,8 +37,6 @@
 import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 
-import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.List;
 
 @SmallTest
@@ -62,13 +58,16 @@
     @Mock
     private WifiEntry mInternetWifiEntry;
     @Mock
-    private WifiEntry mWifiEntry;
+    private List<WifiEntry> mWifiEntries;
     @Mock
     private InternetAdapter mInternetAdapter;
     @Mock
     private InternetDialogController mInternetDialogController;
 
     private InternetDialog mInternetDialog;
+    private View mDialogView;
+    private View mSubTitle;
+    private LinearLayout mMobileDataToggle;
     private LinearLayout mWifiToggle;
     private LinearLayout mConnectedWifi;
     private RecyclerView mWifiList;
@@ -83,26 +82,26 @@
         when(mInternetWifiEntry.getSummary(false)).thenReturn(WIFI_SUMMARY);
         when(mInternetWifiEntry.isDefaultNetwork()).thenReturn(true);
         when(mInternetWifiEntry.hasInternetAccess()).thenReturn(true);
-        when(mWifiEntry.getTitle()).thenReturn(WIFI_TITLE);
-        when(mWifiEntry.getSummary(false)).thenReturn(WIFI_SUMMARY);
+        when(mWifiEntries.size()).thenReturn(1);
 
         when(mInternetDialogController.getMobileNetworkTitle()).thenReturn(MOBILE_NETWORK_TITLE);
         when(mInternetDialogController.getMobileNetworkSummary())
                 .thenReturn(MOBILE_NETWORK_SUMMARY);
         when(mInternetDialogController.getWifiManager()).thenReturn(mWifiManager);
-        when(mInternetDialogController.getInternetWifiEntry()).thenReturn(mInternetWifiEntry);
-        when(mInternetDialogController.getWifiEntryList()).thenReturn(Arrays.asList(mWifiEntry));
 
         mInternetDialog = new InternetDialog(mContext, mock(InternetDialogFactory.class),
-                mInternetDialogController, true, true, mock(UiEventLogger.class), mHandler);
+                mInternetDialogController, true, true, true, mock(UiEventLogger.class), mHandler);
         mInternetDialog.mAdapter = mInternetAdapter;
-        mInternetDialog.mConnectedWifiEntry = mInternetWifiEntry;
+        mInternetDialog.onAccessPointsChanged(mWifiEntries, mInternetWifiEntry);
         mInternetDialog.show();
 
-        mWifiToggle = mInternetDialog.mDialogView.requireViewById(R.id.turn_on_wifi_layout);
-        mConnectedWifi = mInternetDialog.mDialogView.requireViewById(R.id.wifi_connected_layout);
-        mWifiList = mInternetDialog.mDialogView.requireViewById(R.id.wifi_list_layout);
-        mSeeAll = mInternetDialog.mDialogView.requireViewById(R.id.see_all_layout);
+        mDialogView = mInternetDialog.mDialogView;
+        mSubTitle = mDialogView.requireViewById(R.id.internet_dialog_subtitle);
+        mMobileDataToggle = mDialogView.requireViewById(R.id.mobile_network_layout);
+        mWifiToggle = mDialogView.requireViewById(R.id.turn_on_wifi_layout);
+        mConnectedWifi = mDialogView.requireViewById(R.id.wifi_connected_layout);
+        mWifiList = mDialogView.requireViewById(R.id.wifi_list_layout);
+        mSeeAll = mDialogView.requireViewById(R.id.see_all_layout);
     }
 
     @After
@@ -111,33 +110,41 @@
     }
 
     @Test
+    public void hideWifiViews_WifiViewsGone() {
+        mInternetDialog.hideWifiViews();
+
+        assertThat(mInternetDialog.mIsProgressBarVisible).isFalse();
+        assertThat(mWifiToggle.getVisibility()).isEqualTo(View.GONE);
+        assertThat(mConnectedWifi.getVisibility()).isEqualTo(View.GONE);
+        assertThat(mWifiList.getVisibility()).isEqualTo(View.GONE);
+        assertThat(mSeeAll.getVisibility()).isEqualTo(View.GONE);
+    }
+
+    @Test
     public void updateDialog_withApmOn_internetDialogSubTitleGone() {
         when(mInternetDialogController.isAirplaneModeEnabled()).thenReturn(true);
-        mInternetDialog.updateDialog();
-        final TextView view = mInternetDialog.mDialogView.requireViewById(
-                R.id.internet_dialog_subtitle);
 
-        assertThat(view.getVisibility()).isEqualTo(View.GONE);
+        mInternetDialog.updateDialog();
+
+        assertThat(mSubTitle.getVisibility()).isEqualTo(View.GONE);
     }
 
     @Test
     public void updateDialog_withApmOff_internetDialogSubTitleVisible() {
         when(mInternetDialogController.isAirplaneModeEnabled()).thenReturn(false);
-        mInternetDialog.updateDialog();
-        final TextView view = mInternetDialog.mDialogView.requireViewById(
-                R.id.internet_dialog_subtitle);
 
-        assertThat(view.getVisibility()).isEqualTo(View.VISIBLE);
+        mInternetDialog.updateDialog();
+
+        assertThat(mSubTitle.getVisibility()).isEqualTo(View.VISIBLE);
     }
 
     @Test
     public void updateDialog_withApmOn_mobileDataLayoutGone() {
         when(mInternetDialogController.isAirplaneModeEnabled()).thenReturn(true);
-        mInternetDialog.updateDialog();
-        final LinearLayout linearLayout = mInternetDialog.mDialogView.requireViewById(
-                R.id.mobile_network_layout);
 
-        assertThat(linearLayout.getVisibility()).isEqualTo(View.GONE);
+        mInternetDialog.updateDialog();
+
+        assertThat(mMobileDataToggle.getVisibility()).isEqualTo(View.GONE);
     }
 
     @Test
@@ -152,7 +159,8 @@
 
     @Test
     public void updateDialog_wifiOnAndNoConnectedWifi_hideConnectedWifi() {
-        mInternetDialog.mConnectedWifiEntry = null;
+        // The precondition WiFi ON is already in setUp()
+        mInternetDialog.onAccessPointsChanged(mWifiEntries, null /* connectedEntry*/);
         doReturn(false).when(mInternetDialogController).activeNetworkIsCellular();
 
         mInternetDialog.updateDialog();
@@ -162,7 +170,8 @@
 
     @Test
     public void updateDialog_wifiOnAndNoWifiList_hideWifiListAndSeeAll() {
-        when(mInternetDialogController.getWifiEntryList()).thenReturn(null);
+        // The precondition WiFi ON is already in setUp()
+        mInternetDialog.onAccessPointsChanged(null /* wifiEntries */, mInternetWifiEntry);
 
         mInternetDialog.updateDialog();
 
@@ -245,9 +254,6 @@
     public void showProgressBar_wifiEnabledWithWifiEntry_showProgressBarThenHide() {
         Mockito.reset(mHandler);
         when(mWifiManager.isWifiEnabled()).thenReturn(true);
-        List<ScanResult> wifiScanResults = mock(ArrayList.class);
-        when(wifiScanResults.size()).thenReturn(1);
-        when(mWifiManager.getScanResults()).thenReturn(wifiScanResults);
 
         mInternetDialog.showProgressBar();
 
@@ -264,12 +270,10 @@
     }
 
     @Test
-    public void showProgressBar_wifiEnabledWithoutWifiScanResults_showProgressBarThenHideSearch() {
+    public void showProgressBar_wifiEnabledWithoutWifiEntries_showProgressBarThenHideSearch() {
         Mockito.reset(mHandler);
         when(mWifiManager.isWifiEnabled()).thenReturn(true);
-        List<ScanResult> wifiScanResults = mock(ArrayList.class);
-        when(wifiScanResults.size()).thenReturn(0);
-        when(mWifiManager.getScanResults()).thenReturn(wifiScanResults);
+        mInternetDialog.onAccessPointsChanged(null /* wifiEntries */, null /* connectedEntry*/);
 
         mInternetDialog.showProgressBar();
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
index b248fef..f3420be 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
@@ -744,13 +744,6 @@
         finishAnimationsImmediately();
         mScrimController.transitionTo(ScrimState.UNLOCKED);
 
-        // Immediately tinted black after the transition starts
-        assertScrimTinted(Map.of(
-                mScrimInFront, true,
-                mScrimBehind, true,
-                mScrimForBubble, true
-        ));
-
         finishAnimationsImmediately();
 
         // All scrims should be transparent at the end of fade transition.
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 207baf5..1ca037e 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -8756,10 +8756,22 @@
 
     void snoozeNotificationInt(String key, long duration, String snoozeCriterionId,
             ManagedServiceInfo listener) {
-        String listenerName = listener == null ? null : listener.component.toShortString();
+        if (listener == null) {
+            return;
+        }
+        String listenerName = listener.component.toShortString();
         if ((duration <= 0 && snoozeCriterionId == null) || key == null) {
             return;
         }
+        synchronized (mNotificationLock) {
+            final NotificationRecord r = findInCurrentAndSnoozedNotificationByKeyLocked(key);
+            if (r == null) {
+                return;
+            }
+            if (!listener.enabledAndUserMatches(r.getSbn().getNormalizedUserId())){
+                return;
+            }
+        }
 
         if (DBG) {
             Slog.d(TAG, String.format("snooze event(%s, %d, %s, %s)", key, duration,
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index 7bbf3e6..f660af0 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -516,7 +516,7 @@
 
         when(mAssistants.isAdjustmentAllowed(anyString())).thenReturn(true);
 
-        mWorkerHandler = mService.new WorkerHandler(mTestableLooper.getLooper());
+        mWorkerHandler = spy(mService.new WorkerHandler(mTestableLooper.getLooper()));
         mService.init(mWorkerHandler, mRankingHandler, mPackageManager, mPackageManagerClient,
                 mockLightsManager, mListeners, mAssistants, mConditionProviders, mCompanionMgr,
                 mSnoozeHelper, mUsageStats, mPolicyFile, mActivityManager, mGroupHelper, mAm, mAtm,
@@ -2703,6 +2703,42 @@
     }
 
     @Test
+    public void testCrossUserSnooze() {
+        NotificationRecord r = generateNotificationRecord(mTestNotificationChannel, 10);
+        mService.addNotification(r);
+        NotificationRecord r2 = generateNotificationRecord(mTestNotificationChannel, 0);
+        mService.addNotification(r2);
+
+        mListener = mock(ManagedServices.ManagedServiceInfo.class);
+        mListener.component = new ComponentName(PKG, PKG);
+        when(mListener.enabledAndUserMatches(anyInt())).thenReturn(false);
+        when(mListeners.checkServiceTokenLocked(any())).thenReturn(mListener);
+
+        mService.snoozeNotificationInt(r.getKey(), 1000, null, mListener);
+
+        verify(mWorkerHandler, never()).post(
+                any(NotificationManagerService.SnoozeNotificationRunnable.class));
+    }
+
+    @Test
+    public void testSameUserSnooze() {
+        NotificationRecord r = generateNotificationRecord(mTestNotificationChannel, 10);
+        mService.addNotification(r);
+        NotificationRecord r2 = generateNotificationRecord(mTestNotificationChannel, 0);
+        mService.addNotification(r2);
+
+        mListener = mock(ManagedServices.ManagedServiceInfo.class);
+        mListener.component = new ComponentName(PKG, PKG);
+        when(mListener.enabledAndUserMatches(anyInt())).thenReturn(true);
+        when(mListeners.checkServiceTokenLocked(any())).thenReturn(mListener);
+
+        mService.snoozeNotificationInt(r2.getKey(), 1000, null, mListener);
+
+        verify(mWorkerHandler).post(
+                any(NotificationManagerService.SnoozeNotificationRunnable.class));
+    }
+
+    @Test
     public void testSnoozeRunnable_reSnoozeASingleSnoozedNotification() throws Exception {
         final NotificationRecord notification = generateNotificationRecord(
                 mTestNotificationChannel, 1, null, true);
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index 759afd7..f2f1645 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -775,6 +775,21 @@
             "android.telecom.extra.REMOTE_PHONE_ACCOUNT_HANDLE";
 
     /**
+     * The Telecom call ID of the conference an existing connection should be added to.  This is
+     * required when {@link com.android.services.telephony.TelephonyConnectionService} adds a
+     * {@link Conference} to Telecom using the
+     * {@link ConnectionService#addExistingConnection(PhoneAccountHandle, Connection, Conference)}
+     * API.  That API specifies a parent conference associated with the new existing connection
+     * being added, and there is no equivalent as part of the {@link RemoteConnectionService} API.
+     * This extra key is used to stack the ID of the conference to which the existing connection
+     * will be added so that Telecom can link it up correctly when the {@link RemoteConference}
+     * is added to Telecom by the connection manager.
+     * @hide
+     */
+    public static final String EXTRA_ADD_TO_CONFERENCE_ID =
+            "android.telecom.extra.ADD_TO_CONFERENCE_ID";
+
+    /**
      * Extra key set from a {@link ConnectionService} when using the remote connection APIs
      * (e.g. {@link RemoteConnectionService#createRemoteConnection(PhoneAccountHandle,
      * ConnectionRequest, boolean)}) to create a remote connection.  Provides the receiving
diff --git a/telecomm/java/android/telecom/RemoteConnectionService.java b/telecomm/java/android/telecom/RemoteConnectionService.java
index bf6a6ef7..efe35d2 100644
--- a/telecomm/java/android/telecom/RemoteConnectionService.java
+++ b/telecomm/java/android/telecom/RemoteConnectionService.java
@@ -239,13 +239,9 @@
                     conference.addConnection(c);
                 }
             }
-            if (conference.getConnections().size() == 0) {
-                // A conference was created, but none of its connections are ones that have been
-                // created by, and therefore being tracked by, this remote connection service. It
-                // is of no interest to us.
-                Log.d(this, "addConferenceCall - skipping");
-                return;
-            }
+            // We used to skip adding empty conferences; however in the world of IMS conference
+            // calls we need to add them to the remote connection service because they will always
+            // start with no participants.
 
             conference.setState(parcel.getState());
             conference.setConnectionCapabilities(parcel.getConnectionCapabilities());
@@ -379,6 +375,8 @@
         @Override
         public void addExistingConnection(String callId, ParcelableConnection connection,
                 Session.Info sessionInfo) {
+            Log.i(RemoteConnectionService.this, "addExistingConnection: callId=%s, conn=%s", callId,
+                    connection);
             String callingPackage = mOurConnectionServiceImpl.getApplicationContext().
                     getOpPackageName();
             int callingTargetSdkVersion = mOurConnectionServiceImpl.getApplicationInfo()
@@ -390,6 +388,20 @@
             Bundle newExtras = new Bundle();
             newExtras.putParcelable(Connection.EXTRA_REMOTE_PHONE_ACCOUNT_HANDLE,
                     connection.getPhoneAccount());
+            if (connection.getParentCallId() != null) {
+                RemoteConference parentConf = mConferenceById.get(connection.getParentCallId());
+                // If there is a parent being set, we need to stash the conference ID here.
+                // Telephony can add an existing connection while specifying a parent conference.
+                // There is no equivalent version of that operation as part of the remote connection
+                // API, so we will stash the pre-defined parent's ID in the extras.  When the
+                // connectionmanager copies over the extras from the remote connection to the
+                // actual one, it'll get passed to Telecom so that it can make the association.
+                if (parentConf != null) {
+                    newExtras.putString(Connection.EXTRA_ADD_TO_CONFERENCE_ID, parentConf.getId());
+                    Log.i(this, "addExistingConnection: stash parent of %s as %s",
+                            connection.getParentCallId(), parentConf.getId());
+                }
+            }
             remoteConnection.putExtras(newExtras);
             mConnectionById.put(callId, remoteConnection);
             remoteConnection.registerCallback(new RemoteConnection.Callback() {