Merge "[SB Refactor] Define a new status bar wifi view that can be swapped in/out with the old view. Define a skeleton ViewBinder for the new view." into tm-qpr-dev
diff --git a/packages/SystemUI/res/layout/new_status_bar_wifi_group.xml b/packages/SystemUI/res/layout/new_status_bar_wifi_group.xml
new file mode 100644
index 0000000..753ba2f
--- /dev/null
+++ b/packages/SystemUI/res/layout/new_status_bar_wifi_group.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2022, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<com.android.systemui.statusbar.pipeline.wifi.ui.view.ModernStatusBarWifiView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/wifi_combo"
+    android:layout_width="wrap_content"
+    android:layout_height="match_parent"
+    android:gravity="center_vertical" >
+
+    <include layout="@layout/status_bar_wifi_group_inner" />
+
+</com.android.systemui.statusbar.pipeline.wifi.ui.view.ModernStatusBarWifiView>
diff --git a/packages/SystemUI/res/layout/status_bar_wifi_group.xml b/packages/SystemUI/res/layout/status_bar_wifi_group.xml
index 35cce25..6cb6993b 100644
--- a/packages/SystemUI/res/layout/status_bar_wifi_group.xml
+++ b/packages/SystemUI/res/layout/status_bar_wifi_group.xml
@@ -18,70 +18,11 @@
 -->
 <com.android.systemui.statusbar.StatusBarWifiView
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:systemui="http://schemas.android.com/apk/res-auto"
     android:id="@+id/wifi_combo"
     android:layout_width="wrap_content"
     android:layout_height="match_parent"
     android:gravity="center_vertical" >
 
-    <com.android.keyguard.AlphaOptimizedLinearLayout
-        android:id="@+id/wifi_group"
-        android:layout_width="wrap_content"
-        android:layout_height="match_parent"
-        android:gravity="center_vertical"
-        android:layout_marginStart="2.5dp"
-    >
-        <FrameLayout
-                android:id="@+id/inout_container"
-                android:layout_height="17dp"
-                android:layout_width="wrap_content"
-                android:gravity="center_vertical" >
-            <ImageView
-                android:id="@+id/wifi_in"
-                android:layout_height="wrap_content"
-                android:layout_width="wrap_content"
-                android:src="@drawable/ic_activity_down"
-                android:visibility="gone"
-                android:paddingEnd="2dp"
-            />
-            <ImageView
-                android:id="@+id/wifi_out"
-                android:layout_height="wrap_content"
-                android:layout_width="wrap_content"
-                android:src="@drawable/ic_activity_up"
-                android:paddingEnd="2dp"
-                android:visibility="gone"
-            />
-        </FrameLayout>
-        <FrameLayout
-            android:id="@+id/wifi_combo"
-            android:layout_height="wrap_content"
-            android:layout_width="wrap_content"
-            android:gravity="center_vertical" >
-            <com.android.systemui.statusbar.AlphaOptimizedImageView
-                android:id="@+id/wifi_signal"
-                android:layout_height="@dimen/status_bar_wifi_signal_size"
-                android:layout_width="@dimen/status_bar_wifi_signal_size" />
-        </FrameLayout>
+    <include layout="@layout/status_bar_wifi_group_inner" />
 
-        <View
-            android:id="@+id/wifi_signal_spacer"
-            android:layout_width="@dimen/status_bar_wifi_signal_spacer_width"
-            android:layout_height="4dp"
-            android:visibility="gone" />
-
-        <!-- Looks like CarStatusBar uses this... -->
-        <ViewStub
-            android:id="@+id/connected_device_signals_stub"
-            android:layout="@layout/connected_device_signal"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content" />
-
-        <View
-            android:id="@+id/wifi_airplane_spacer"
-            android:layout_width="@dimen/status_bar_airplane_spacer_width"
-            android:layout_height="4dp"
-            android:visibility="gone"
-        />
-    </com.android.keyguard.AlphaOptimizedLinearLayout>
-</com.android.systemui.statusbar.StatusBarWifiView>
+</com.android.systemui.statusbar.StatusBarWifiView>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/status_bar_wifi_group_inner.xml b/packages/SystemUI/res/layout/status_bar_wifi_group_inner.xml
new file mode 100644
index 0000000..0ea0653
--- /dev/null
+++ b/packages/SystemUI/res/layout/status_bar_wifi_group_inner.xml
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2022, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <com.android.keyguard.AlphaOptimizedLinearLayout
+        android:id="@+id/wifi_group"
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent"
+        android:gravity="center_vertical"
+        android:layout_marginStart="2.5dp"
+    >
+        <FrameLayout
+                android:id="@+id/inout_container"
+                android:layout_height="17dp"
+                android:layout_width="wrap_content"
+                android:gravity="center_vertical" >
+            <ImageView
+                android:id="@+id/wifi_in"
+                android:layout_height="wrap_content"
+                android:layout_width="wrap_content"
+                android:src="@drawable/ic_activity_down"
+                android:visibility="gone"
+                android:paddingEnd="2dp"
+            />
+            <ImageView
+                android:id="@+id/wifi_out"
+                android:layout_height="wrap_content"
+                android:layout_width="wrap_content"
+                android:src="@drawable/ic_activity_up"
+                android:paddingEnd="2dp"
+                android:visibility="gone"
+            />
+        </FrameLayout>
+        <FrameLayout
+            android:id="@+id/wifi_combo"
+            android:layout_height="wrap_content"
+            android:layout_width="wrap_content"
+            android:gravity="center_vertical" >
+            <com.android.systemui.statusbar.AlphaOptimizedImageView
+                android:id="@+id/wifi_signal"
+                android:layout_height="@dimen/status_bar_wifi_signal_size"
+                android:layout_width="@dimen/status_bar_wifi_signal_size" />
+        </FrameLayout>
+
+        <View
+            android:id="@+id/wifi_signal_spacer"
+            android:layout_width="@dimen/status_bar_wifi_signal_spacer_width"
+            android:layout_height="4dp"
+            android:visibility="gone" />
+
+        <!-- Looks like CarStatusBar uses this... -->
+        <ViewStub
+            android:id="@+id/connected_device_signals_stub"
+            android:layout="@layout/connected_device_signal"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content" />
+
+        <View
+            android:id="@+id/wifi_airplane_spacer"
+            android:layout_width="@dimen/status_bar_airplane_spacer_width"
+            android:layout_height="4dp"
+            android:visibility="gone"
+        />
+    </com.android.keyguard.AlphaOptimizedLinearLayout>
+</merge>
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.java b/packages/SystemUI/src/com/android/systemui/flags/Flags.java
index d87ed57..f868263 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.java
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.java
@@ -155,7 +155,11 @@
     public static final ReleasedFlag STATUS_BAR_LETTERBOX_APPEARANCE =
             new ReleasedFlag(603, false);
 
-    public static final UnreleasedFlag NEW_STATUS_BAR_PIPELINE = new UnreleasedFlag(604, true);
+    public static final UnreleasedFlag NEW_STATUS_BAR_PIPELINE_BACKEND =
+            new UnreleasedFlag(604, true);
+
+    public static final UnreleasedFlag NEW_STATUS_BAR_PIPELINE_FRONTEND =
+            new UnreleasedFlag(605, true);
 
     /***************************************/
     // 700 - dialer/calls
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java
index eeb1010..2a6cf66 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java
@@ -80,7 +80,8 @@
             FeatureFlags featureFlags,
             VariableDateViewController.Factory variableDateViewControllerFactory,
             BatteryMeterViewController batteryMeterViewController,
-            StatusBarContentInsetsProvider statusBarContentInsetsProvider) {
+            StatusBarContentInsetsProvider statusBarContentInsetsProvider,
+            StatusBarIconController.TintedIconManager.Factory tintedIconManagerFactory) {
         super(view);
         mPrivacyIconsController = headerPrivacyIconsController;
         mStatusBarIconController = statusBarIconController;
@@ -103,7 +104,7 @@
                 mView.requireViewById(R.id.date_clock)
         );
 
-        mIconManager = new StatusBarIconController.TintedIconManager(mIconContainer, featureFlags);
+        mIconManager = tintedIconManagerFactory.create(mIconContainer);
         mDemoModeReceiver = new ClockDemoModeReceiver(mClockView);
         mColorExtractor = colorExtractor;
         mOnColorsChangedListener = (extractor, which) -> {
diff --git a/packages/SystemUI/src/com/android/systemui/shade/LargeScreenShadeHeaderController.kt b/packages/SystemUI/src/com/android/systemui/shade/LargeScreenShadeHeaderController.kt
index 0f9ac36..fab70fc 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/LargeScreenShadeHeaderController.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/LargeScreenShadeHeaderController.kt
@@ -77,6 +77,7 @@
 class LargeScreenShadeHeaderController @Inject constructor(
     @Named(LARGE_SCREEN_SHADE_HEADER) private val header: View,
     private val statusBarIconController: StatusBarIconController,
+    private val tintedIconManagerFactory: StatusBarIconController.TintedIconManager.Factory,
     private val privacyIconsController: HeaderPrivacyIconsController,
     private val insetsProvider: StatusBarContentInsetsProvider,
     private val configurationController: ConfigurationController,
@@ -259,7 +260,7 @@
         batteryMeterViewController.ignoreTunerUpdates()
         batteryIcon.setPercentShowMode(BatteryMeterView.MODE_ESTIMATE)
 
-        iconManager = StatusBarIconController.TintedIconManager(iconContainer, featureFlags)
+        iconManager = tintedIconManagerFactory.create(iconContainer)
         iconManager.setTint(
             Utils.getColorAttrDefaultColor(header.context, android.R.attr.textColorPrimary)
         )
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBarWifiView.kt b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBarWifiView.kt
new file mode 100644
index 0000000..4d53064
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBarWifiView.kt
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.statusbar
+
+import android.content.Context
+import android.util.AttributeSet
+import android.widget.FrameLayout
+
+/**
+ * A temporary base class that's shared between our old status bar wifi view implementation
+ * ([StatusBarWifiView]) and our new status bar wifi view implementation
+ * ([ModernStatusBarWifiView]).
+ *
+ * Once our refactor is over, we should be able to delete this go-between class and the old view
+ * class.
+ */
+abstract class BaseStatusBarWifiView @JvmOverloads constructor(
+    context: Context,
+    attrs: AttributeSet? = null,
+    defStyleAttrs: Int = 0,
+) : FrameLayout(context, attrs, defStyleAttrs), StatusIconDisplayable
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarWifiView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarWifiView.java
index a6986d7..5aee62e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarWifiView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarWifiView.java
@@ -28,7 +28,6 @@
 import android.view.Gravity;
 import android.view.LayoutInflater;
 import android.view.View;
-import android.widget.FrameLayout;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
 
@@ -41,8 +40,7 @@
 /**
  * Start small: StatusBarWifiView will be able to layout from a WifiIconState
  */
-public class StatusBarWifiView extends FrameLayout implements DarkReceiver,
-        StatusIconDisplayable {
+public class StatusBarWifiView extends BaseStatusBarWifiView implements DarkReceiver {
     private static final String TAG = "StatusBarWifiView";
 
     /// Used to show etc dots
@@ -80,11 +78,6 @@
         super(context, attrs, defStyleAttr);
     }
 
-    public StatusBarWifiView(Context context, AttributeSet attrs, int defStyleAttr,
-            int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-    }
-
     public void setSlot(String slot) {
         mSlot = slot;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/WifiIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/WifiIcons.java
index 3c449ad..7097568 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/WifiIcons.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/WifiIcons.java
@@ -23,7 +23,7 @@
 /** */
 public class WifiIcons {
 
-    static final int[] WIFI_FULL_ICONS = {
+    public static final int[] WIFI_FULL_ICONS = {
             com.android.internal.R.drawable.ic_wifi_signal_0,
             com.android.internal.R.drawable.ic_wifi_signal_1,
             com.android.internal.R.drawable.ic_wifi_signal_2,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java
index fc8e7d5..deb6150 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java
@@ -225,6 +225,7 @@
 
     public void addDemoWifiView(WifiIconState state) {
         Log.d(TAG, "addDemoWifiView: ");
+        // TODO(b/238425913): Migrate this view to {@code ModernStatusBarWifiView}.
         StatusBarWifiView view = StatusBarWifiView.fromContext(mContext, state.slot);
 
         int viewIndex = getChildCount();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
index 30b640b..ed186ab 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
@@ -40,6 +40,7 @@
 import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.plugins.DarkIconDispatcher;
 import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver;
+import com.android.systemui.statusbar.BaseStatusBarWifiView;
 import com.android.systemui.statusbar.StatusBarIconView;
 import com.android.systemui.statusbar.StatusBarMobileView;
 import com.android.systemui.statusbar.StatusBarWifiView;
@@ -47,12 +48,16 @@
 import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.CallIndicatorIconState;
 import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.MobileIconState;
 import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.WifiIconState;
+import com.android.systemui.statusbar.pipeline.StatusBarPipelineFlags;
+import com.android.systemui.statusbar.pipeline.wifi.ui.view.ModernStatusBarWifiView;
+import com.android.systemui.statusbar.pipeline.wifi.ui.viewmodel.WifiViewModel;
 import com.android.systemui.util.Assert;
 
 import java.util.ArrayList;
 import java.util.List;
 
 import javax.inject.Inject;
+import javax.inject.Provider;
 
 public interface StatusBarIconController {
 
@@ -128,8 +133,12 @@
         private final DarkIconDispatcher mDarkIconDispatcher;
         private int mIconHPadding;
 
-        public DarkIconManager(LinearLayout linearLayout, FeatureFlags featureFlags) {
-            super(linearLayout, featureFlags);
+        public DarkIconManager(
+                LinearLayout linearLayout,
+                FeatureFlags featureFlags,
+                StatusBarPipelineFlags statusBarPipelineFlags,
+                Provider<WifiViewModel> wifiViewModelProvider) {
+            super(linearLayout, featureFlags, statusBarPipelineFlags, wifiViewModelProvider);
             mIconHPadding = mContext.getResources().getDimensionPixelSize(
                     R.dimen.status_bar_icon_padding);
             mDarkIconDispatcher = Dependency.get(DarkIconDispatcher.class);
@@ -183,14 +192,40 @@
             mDarkIconDispatcher.removeDarkReceiver(mDemoStatusIcons);
             super.exitDemoMode();
         }
+
+        @SysUISingleton
+        public static class Factory {
+            private final FeatureFlags mFeatureFlags;
+            private final StatusBarPipelineFlags mStatusBarPipelineFlags;
+            private final Provider<WifiViewModel> mWifiViewModelProvider;
+
+            @Inject
+            public Factory(
+                    FeatureFlags featureFlags,
+                    StatusBarPipelineFlags statusBarPipelineFlags,
+                    Provider<WifiViewModel> wifiViewModelProvider) {
+                mFeatureFlags = featureFlags;
+                mStatusBarPipelineFlags = statusBarPipelineFlags;
+                mWifiViewModelProvider = wifiViewModelProvider;
+            }
+
+            public DarkIconManager create(LinearLayout group) {
+                return new DarkIconManager(
+                        group, mFeatureFlags, mStatusBarPipelineFlags, mWifiViewModelProvider);
+            }
+        }
     }
 
     /** */
     class TintedIconManager extends IconManager {
         private int mColor;
 
-        public TintedIconManager(ViewGroup group, FeatureFlags featureFlags) {
-            super(group, featureFlags);
+        public TintedIconManager(
+                ViewGroup group,
+                FeatureFlags featureFlags,
+                StatusBarPipelineFlags statusBarPipelineFlags,
+                Provider<WifiViewModel> wifiViewModelProvider) {
+            super(group, featureFlags, statusBarPipelineFlags, wifiViewModelProvider);
         }
 
         @Override
@@ -223,14 +258,22 @@
         @SysUISingleton
         public static class Factory {
             private final FeatureFlags mFeatureFlags;
+            private final StatusBarPipelineFlags mStatusBarPipelineFlags;
+            private final Provider<WifiViewModel> mWifiViewModelProvider;
 
             @Inject
-            public Factory(FeatureFlags featureFlags) {
+            public Factory(
+                    FeatureFlags featureFlags,
+                    StatusBarPipelineFlags statusBarPipelineFlags,
+                    Provider<WifiViewModel> wifiViewModelProvider) {
                 mFeatureFlags = featureFlags;
+                mStatusBarPipelineFlags = statusBarPipelineFlags;
+                mWifiViewModelProvider = wifiViewModelProvider;
             }
 
             public TintedIconManager create(ViewGroup group) {
-                return new TintedIconManager(group, mFeatureFlags);
+                return new TintedIconManager(
+                        group, mFeatureFlags, mStatusBarPipelineFlags, mWifiViewModelProvider);
             }
         }
     }
@@ -239,8 +282,10 @@
      * Turns info from StatusBarIconController into ImageViews in a ViewGroup.
      */
     class IconManager implements DemoModeCommandReceiver {
-        private final FeatureFlags mFeatureFlags;
         protected final ViewGroup mGroup;
+        private final FeatureFlags mFeatureFlags;
+        private final StatusBarPipelineFlags mStatusBarPipelineFlags;
+        private final Provider<WifiViewModel> mWifiViewModelProvider;
         protected final Context mContext;
         protected final int mIconSize;
         // Whether or not these icons show up in dumpsys
@@ -254,9 +299,15 @@
 
         protected ArrayList<String> mBlockList = new ArrayList<>();
 
-        public IconManager(ViewGroup group, FeatureFlags featureFlags) {
-            mFeatureFlags = featureFlags;
+        public IconManager(
+                ViewGroup group,
+                FeatureFlags featureFlags,
+                StatusBarPipelineFlags statusBarPipelineFlags,
+                Provider<WifiViewModel> wifiViewModelProvider) {
             mGroup = group;
+            mFeatureFlags = featureFlags;
+            mStatusBarPipelineFlags = statusBarPipelineFlags;
+            mWifiViewModelProvider = wifiViewModelProvider;
             mContext = group.getContext();
             mIconSize = mContext.getResources().getDimensionPixelSize(
                     com.android.internal.R.dimen.status_bar_icon_size);
@@ -308,7 +359,7 @@
                     return addIcon(index, slot, blocked, holder.getIcon());
 
                 case TYPE_WIFI:
-                    return addSignalIcon(index, slot, holder.getWifiState());
+                    return addWifiIcon(index, slot, holder.getWifiState());
 
                 case TYPE_MOBILE:
                     return addMobileIcon(index, slot, holder.getMobileState());
@@ -327,9 +378,17 @@
         }
 
         @VisibleForTesting
-        protected StatusBarWifiView addSignalIcon(int index, String slot, WifiIconState state) {
-            StatusBarWifiView view = onCreateStatusBarWifiView(slot);
-            view.applyWifiState(state);
+        protected StatusIconDisplayable addWifiIcon(int index, String slot, WifiIconState state) {
+            final BaseStatusBarWifiView view;
+            if (mStatusBarPipelineFlags.isNewPipelineFrontendEnabled()) {
+                view = onCreateModernStatusBarWifiView(slot);
+                // When [ModernStatusBarWifiView] is created, it will automatically apply the
+                // correct view state so we don't need to call applyWifiState.
+            } else {
+                StatusBarWifiView wifiView = onCreateStatusBarWifiView(slot);
+                wifiView.applyWifiState(state);
+                view = wifiView;
+            }
             mGroup.addView(view, index, onCreateLayoutParams());
 
             if (mIsInDemoMode) {
@@ -359,6 +418,11 @@
             return view;
         }
 
+        private ModernStatusBarWifiView onCreateModernStatusBarWifiView(String slot) {
+            return ModernStatusBarWifiView.constructAndBind(
+                    mContext, slot, mWifiViewModelProvider.get());
+        }
+
         private StatusBarMobileView onCreateStatusBarMobileView(String slot) {
             StatusBarMobileView view = StatusBarMobileView.fromContext(mContext, slot);
             return view;
@@ -415,9 +479,8 @@
                     onSetIcon(viewIndex, holder.getIcon());
                     return;
                 case TYPE_WIFI:
-                    onSetSignalIcon(viewIndex, holder.getWifiState());
+                    onSetWifiIcon(viewIndex, holder.getWifiState());
                     return;
-
                 case TYPE_MOBILE:
                     onSetMobileIcon(viewIndex, holder.getMobileState());
                 default:
@@ -425,10 +488,16 @@
             }
         }
 
-        public void onSetSignalIcon(int viewIndex, WifiIconState state) {
-            StatusBarWifiView wifiView = (StatusBarWifiView) mGroup.getChildAt(viewIndex);
-            if (wifiView != null) {
-                wifiView.applyWifiState(state);
+        public void onSetWifiIcon(int viewIndex, WifiIconState state) {
+            View view = mGroup.getChildAt(viewIndex);
+            if (view instanceof StatusBarWifiView) {
+                ((StatusBarWifiView) view).applyWifiState(state);
+            } else if (view instanceof ModernStatusBarWifiView) {
+                // ModernStatusBarWifiView will automatically apply state based on its callbacks, so
+                // we don't need to call applyWifiState.
+            } else {
+                throw new IllegalStateException("View at " + viewIndex + " must be of type "
+                        + "StatusBarWifiView or ModernStatusBarWifiView");
             }
 
             if (mIsInDemoMode) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java
index c4e7a8a..627cfb7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java
@@ -287,6 +287,7 @@
             PanelExpansionStateManager panelExpansionStateManager,
             FeatureFlags featureFlags,
             StatusBarIconController statusBarIconController,
+            StatusBarIconController.DarkIconManager.Factory darkIconManagerFactory,
             StatusBarHideIconsForBouncerManager statusBarHideIconsForBouncerManager,
             KeyguardStateController keyguardStateController,
             NotificationPanelViewController notificationPanelViewController,
@@ -308,6 +309,7 @@
                 panelExpansionStateManager,
                 featureFlags,
                 statusBarIconController,
+                darkIconManagerFactory,
                 statusBarHideIconsForBouncerManager,
                 keyguardStateController,
                 notificationPanelViewController,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java
index 29b4d5b..84bb82b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java
@@ -130,6 +130,7 @@
     private final StatusBarIconController mStatusBarIconController;
     private final CarrierConfigTracker mCarrierConfigTracker;
     private final StatusBarHideIconsForBouncerManager mStatusBarHideIconsForBouncerManager;
+    private final StatusBarIconController.DarkIconManager.Factory mDarkIconManagerFactory;
     private final SecureSettings mSecureSettings;
     private final Executor mMainExecutor;
     private final DumpManager mDumpManager;
@@ -185,6 +186,7 @@
             PanelExpansionStateManager panelExpansionStateManager,
             FeatureFlags featureFlags,
             StatusBarIconController statusBarIconController,
+            StatusBarIconController.DarkIconManager.Factory darkIconManagerFactory,
             StatusBarHideIconsForBouncerManager statusBarHideIconsForBouncerManager,
             KeyguardStateController keyguardStateController,
             NotificationPanelViewController notificationPanelViewController,
@@ -207,6 +209,7 @@
         mFeatureFlags = featureFlags;
         mStatusBarIconController = statusBarIconController;
         mStatusBarHideIconsForBouncerManager = statusBarHideIconsForBouncerManager;
+        mDarkIconManagerFactory = darkIconManagerFactory;
         mKeyguardStateController = keyguardStateController;
         mNotificationPanelViewController = notificationPanelViewController;
         mNetworkController = networkController;
@@ -247,7 +250,7 @@
             mStatusBar.restoreHierarchyState(
                     savedInstanceState.getSparseParcelableArray(EXTRA_PANEL_STATE));
         }
-        mDarkIconManager = new DarkIconManager(view.findViewById(R.id.statusIcons), mFeatureFlags);
+        mDarkIconManager = mDarkIconManagerFactory.create(view.findViewById(R.id.statusIcons));
         mDarkIconManager.setShouldLog(true);
         updateBlockedIcons();
         mStatusBarIconController.addIconGroup(mDarkIconManager);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/ConnectivityInfoProcessor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/ConnectivityInfoProcessor.kt
index 0b01816..fe84674 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/ConnectivityInfoProcessor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/ConnectivityInfoProcessor.kt
@@ -43,7 +43,7 @@
         private val wifiViewModelProvider: Provider<WifiViewModel>,
 ) : CoreStartable(context) {
     override fun start() {
-        if (!statusBarPipelineFlags.isNewPipelineEnabled()) {
+        if (!statusBarPipelineFlags.isNewPipelineBackendEnabled()) {
             return
         }
         // TODO(b/238425913): The view binder should do this instead. For now, do it here so we can
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/StatusBarPipelineFlags.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/StatusBarPipelineFlags.kt
index 589cdb8..9b8b643 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/StatusBarPipelineFlags.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/StatusBarPipelineFlags.kt
@@ -25,13 +25,28 @@
 @SysUISingleton
 class StatusBarPipelineFlags @Inject constructor(private val featureFlags: FeatureFlags) {
     /**
-     * Returns true if we should run the new pipeline.
+     * Returns true if we should run the new pipeline backend.
      *
-     * TODO(b/238425913): We may want to split this out into:
-     *   (1) isNewPipelineLoggingEnabled(), where the new pipeline runs and logs its decisions but
-     *       doesn't change the UI at all.
-     *   (2) isNewPipelineEnabled(), where the new pipeline runs and does change the UI (and the old
-     *       pipeline doesn't change the UI).
+     * The new pipeline backend hooks up to all our external callbacks, logs those callback inputs,
+     * and logs the output state.
      */
-    fun isNewPipelineEnabled(): Boolean = featureFlags.isEnabled(Flags.NEW_STATUS_BAR_PIPELINE)
+    fun isNewPipelineBackendEnabled(): Boolean =
+        featureFlags.isEnabled(Flags.NEW_STATUS_BAR_PIPELINE_BACKEND)
+
+    /**
+     * Returns true if we should run the new pipeline frontend *and* backend.
+     *
+     * The new pipeline frontend will use the outputted state from the new backend and will make the
+     * correct changes to the UI.
+     */
+    fun isNewPipelineFrontendEnabled(): Boolean =
+        isNewPipelineBackendEnabled() &&
+            featureFlags.isEnabled(Flags.NEW_STATUS_BAR_PIPELINE_FRONTEND)
+
+    /**
+     * Returns true if we should apply some coloring to icons that were rendered with the new
+     * pipeline to help with debugging.
+     */
+    // For now, just always apply the debug coloring if we've enabled frontend rendering.
+    fun useNewPipelineDebugColoring(): Boolean = isNewPipelineFrontendEnabled()
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/binder/WifiViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/binder/WifiViewBinder.kt
new file mode 100644
index 0000000..b06aaf4
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/binder/WifiViewBinder.kt
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.pipeline.wifi.ui.binder
+
+import android.content.res.ColorStateList
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageView
+import androidx.core.view.isVisible
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.repeatOnLifecycle
+import com.android.systemui.R
+import com.android.systemui.lifecycle.repeatWhenAttached
+import com.android.systemui.statusbar.connectivity.WifiIcons.WIFI_FULL_ICONS
+import com.android.systemui.statusbar.pipeline.wifi.ui.viewmodel.WifiViewModel
+import kotlinx.coroutines.InternalCoroutinesApi
+import kotlinx.coroutines.flow.collect
+import kotlinx.coroutines.launch
+
+/**
+ * Binds a wifi icon in the status bar to its view-model.
+ *
+ * To use this properly, users should maintain a one-to-one relationship between the [View] and the
+ * view-binding, binding each view only once. It is okay and expected for the same instance of the
+ * view-model to be reused for multiple view/view-binder bindings.
+ */
+@OptIn(InternalCoroutinesApi::class)
+object WifiViewBinder {
+    /** Binds the view to the view-model, continuing to update the former based on the latter. */
+    @JvmStatic
+    fun bind(
+        view: ViewGroup,
+        viewModel: WifiViewModel,
+    ) {
+        val iconView = view.requireViewById<ImageView>(R.id.wifi_signal)
+
+        view.isVisible = true
+        iconView.isVisible = true
+        iconView.setImageDrawable(view.context.getDrawable(WIFI_FULL_ICONS[2]))
+
+        view.repeatWhenAttached {
+            repeatOnLifecycle(Lifecycle.State.STARTED) {
+                launch {
+                    viewModel.tint.collect { tint ->
+                        iconView.imageTintList = ColorStateList.valueOf(tint)
+                    }
+                }
+            }
+        }
+
+        // TODO(b/238425913): Hook up to [viewModel] to render actual changes to the wifi icon.
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiView.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiView.kt
new file mode 100644
index 0000000..c14a897
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiView.kt
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.pipeline.wifi.ui.view
+
+import android.content.Context
+import android.graphics.Rect
+import android.util.AttributeSet
+import android.view.LayoutInflater
+import com.android.systemui.R
+import com.android.systemui.statusbar.BaseStatusBarWifiView
+import com.android.systemui.statusbar.StatusBarIconView.STATE_ICON
+import com.android.systemui.statusbar.pipeline.wifi.ui.binder.WifiViewBinder
+import com.android.systemui.statusbar.pipeline.wifi.ui.viewmodel.WifiViewModel
+
+/**
+ * A new and more modern implementation of [com.android.systemui.statusbar.StatusBarWifiView] that
+ * is updated by [WifiViewBinder].
+ */
+class ModernStatusBarWifiView(
+    context: Context,
+    attrs: AttributeSet?
+) : BaseStatusBarWifiView(context, attrs) {
+
+    private lateinit var slot: String
+
+    override fun onDarkChanged(areas: ArrayList<Rect>?, darkIntensity: Float, tint: Int) {
+        // TODO(b/238425913)
+    }
+
+    override fun getSlot() = slot
+
+    override fun setStaticDrawableColor(color: Int) {
+        // TODO(b/238425913)
+    }
+
+    override fun setDecorColor(color: Int) {
+        // TODO(b/238425913)
+    }
+
+    override fun setVisibleState(state: Int, animate: Boolean) {
+        // TODO(b/238425913)
+    }
+
+    override fun getVisibleState(): Int {
+        // TODO(b/238425913)
+        return STATE_ICON
+    }
+
+    override fun isIconVisible(): Boolean {
+        // TODO(b/238425913)
+        return true
+    }
+
+    /** Set the slot name for this view. */
+    private fun setSlot(slotName: String) {
+        this.slot = slotName
+    }
+
+    companion object {
+        /**
+         * Inflates a new instance of [ModernStatusBarWifiView], binds it to [viewModel], and
+         * returns it.
+         */
+        @JvmStatic
+        fun constructAndBind(
+            context: Context,
+            slot: String,
+            viewModel: WifiViewModel,
+        ): ModernStatusBarWifiView {
+            return (
+                LayoutInflater.from(context).inflate(R.layout.new_status_bar_wifi_group, null)
+                    as ModernStatusBarWifiView
+                ).also {
+                    it.setSlot(slot)
+                    WifiViewBinder.bind(it, viewModel)
+                }
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModel.kt
index b990eb7..7a26260 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModel.kt
@@ -16,12 +16,15 @@
 
 package com.android.systemui.statusbar.pipeline.wifi.ui.viewmodel
 
+import android.graphics.Color
+import com.android.systemui.statusbar.pipeline.StatusBarPipelineFlags
 import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
 import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger.Companion.logOutputChange
 import com.android.systemui.statusbar.pipeline.wifi.domain.interactor.WifiInteractor
 import com.android.systemui.statusbar.pipeline.wifi.shared.WifiConstants
 import javax.inject.Inject
 import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.emptyFlow
 import kotlinx.coroutines.flow.flowOf
 
 /**
@@ -30,9 +33,10 @@
  * TODO(b/238425913): Hook this up to the real status bar wifi view using a view binder.
  */
 class WifiViewModel @Inject constructor(
-        private val constants: WifiConstants,
-        private val logger: ConnectivityPipelineLogger,
-        private val interactor: WifiInteractor,
+    statusBarPipelineFlags: StatusBarPipelineFlags,
+    private val constants: WifiConstants,
+    private val logger: ConnectivityPipelineLogger,
+    private val interactor: WifiInteractor,
 ) {
     val isActivityInVisible: Flow<Boolean>
         get() =
@@ -42,4 +46,11 @@
                 interactor.hasActivityIn
             }
                 .logOutputChange(logger, "activityInVisible")
+
+    /** The tint that should be applied to the icon. */
+    val tint: Flow<Int> = if (!statusBarPipelineFlags.useNewPipelineDebugColoring()) {
+        emptyFlow()
+    } else {
+        flowOf(Color.CYAN)
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QuickStatusBarHeaderControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/QuickStatusBarHeaderControllerTest.kt
index be14cc5..cb4f08e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QuickStatusBarHeaderControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QuickStatusBarHeaderControllerTest.kt
@@ -93,6 +93,10 @@
     private lateinit var featureFlags: FeatureFlags
     @Mock
     private lateinit var insetsProvider: StatusBarContentInsetsProvider
+    @Mock
+    private lateinit var iconManagerFactory: StatusBarIconController.TintedIconManager.Factory
+    @Mock
+    private lateinit var iconManager: StatusBarIconController.TintedIconManager
 
     private val qsExpansionPathInterpolator = QSExpansionPathInterpolator()
 
@@ -106,6 +110,7 @@
         `when`(qsCarrierGroupControllerBuilder.build()).thenReturn(qsCarrierGroupController)
         `when`(variableDateViewControllerFactory.create(any()))
                 .thenReturn(variableDateViewController)
+        `when`(iconManagerFactory.create(any())).thenReturn(iconManager)
         `when`(view.resources).thenReturn(mContext.resources)
         `when`(view.isAttachedToWindow).thenReturn(true)
         `when`(view.context).thenReturn(context)
@@ -122,7 +127,8 @@
                 featureFlags,
                 variableDateViewControllerFactory,
                 batteryMeterViewController,
-                insetsProvider
+                insetsProvider,
+                iconManagerFactory,
         )
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerCombinedTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerCombinedTest.kt
index ed1a13b..20c6d9a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerCombinedTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerCombinedTest.kt
@@ -91,6 +91,10 @@
     @Mock
     private lateinit var statusBarIconController: StatusBarIconController
     @Mock
+    private lateinit var iconManagerFactory: StatusBarIconController.TintedIconManager.Factory
+    @Mock
+    private lateinit var iconManager: StatusBarIconController.TintedIconManager
+    @Mock
     private lateinit var qsCarrierGroupController: QSCarrierGroupController
     @Mock
     private lateinit var qsCarrierGroupControllerBuilder: QSCarrierGroupController.Builder
@@ -169,6 +173,8 @@
         }
         whenever(view.visibility).thenAnswer { _ -> viewVisibility }
 
+        whenever(iconManagerFactory.create(any())).thenReturn(iconManager)
+
         whenever(featureFlags.isEnabled(Flags.COMBINED_QS_HEADERS)).thenReturn(true)
         whenever(featureFlags.isEnabled(Flags.NEW_HEADER)).thenReturn(true)
 
@@ -178,6 +184,7 @@
         controller = LargeScreenShadeHeaderController(
             view,
             statusBarIconController,
+            iconManagerFactory,
             privacyIconsController,
             insetsProvider,
             configurationController,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerTest.kt
index 02b26db..eeb61bc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerTest.kt
@@ -43,6 +43,8 @@
     @Mock private lateinit var view: View
     @Mock private lateinit var statusIcons: StatusIconContainer
     @Mock private lateinit var statusBarIconController: StatusBarIconController
+    @Mock private lateinit var iconManagerFactory: StatusBarIconController.TintedIconManager.Factory
+    @Mock private lateinit var iconManager: StatusBarIconController.TintedIconManager
     @Mock private lateinit var qsCarrierGroupController: QSCarrierGroupController
     @Mock private lateinit var qsCarrierGroupControllerBuilder: QSCarrierGroupController.Builder
     @Mock private lateinit var featureFlags: FeatureFlags
@@ -91,10 +93,12 @@
         whenever(view.visibility).thenAnswer { _ -> viewVisibility }
         whenever(variableDateViewControllerFactory.create(any()))
             .thenReturn(variableDateViewController)
+        whenever(iconManagerFactory.create(any())).thenReturn(iconManager)
         whenever(featureFlags.isEnabled(Flags.COMBINED_QS_HEADERS)).thenReturn(false)
         mLargeScreenShadeHeaderController = LargeScreenShadeHeaderController(
                 view,
                 statusBarIconController,
+                iconManagerFactory,
                 privacyIconsController,
                 insetsProvider,
                 configurationController,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java
index 11e502f..6cf1a12 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java
@@ -47,7 +47,6 @@
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.battery.BatteryMeterViewController;
-import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.shade.NotificationPanelViewController;
 import com.android.systemui.statusbar.SysuiStatusBarStateController;
@@ -89,7 +88,9 @@
     @Mock
     private StatusBarIconController mStatusBarIconController;
     @Mock
-    private FeatureFlags mFeatureFlags;
+    private StatusBarIconController.TintedIconManager.Factory mIconManagerFactory;
+    @Mock
+    private StatusBarIconController.TintedIconManager mIconManager;
     @Mock
     private BatteryMeterViewController mBatteryMeterViewController;
     @Mock
@@ -129,6 +130,8 @@
 
         MockitoAnnotations.initMocks(this);
 
+        when(mIconManagerFactory.create(any())).thenReturn(mIconManager);
+
         allowTestableLooperAsMainThread();
         TestableLooper.get(this).runWithLooper(() -> {
             mKeyguardStatusBarView =
@@ -148,7 +151,7 @@
                 mBatteryController,
                 mUserInfoController,
                 mStatusBarIconController,
-                new StatusBarIconController.TintedIconManager.Factory(mFeatureFlags),
+                mIconManagerFactory,
                 mBatteryMeterViewController,
                 mNotificationPanelViewStateProvider,
                 mKeyguardStateController,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarIconControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarIconControllerTest.java
index 0f1c40b..a6b7e51 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarIconControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarIconControllerTest.java
@@ -40,12 +40,16 @@
 import com.android.systemui.statusbar.phone.StatusBarIconController.IconManager;
 import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.MobileIconState;
 import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.WifiIconState;
+import com.android.systemui.statusbar.pipeline.StatusBarPipelineFlags;
+import com.android.systemui.statusbar.pipeline.wifi.ui.viewmodel.WifiViewModel;
 import com.android.systemui.utils.leaks.LeakCheckedTest;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import javax.inject.Provider;
+
 @RunWith(AndroidTestingRunner.class)
 @RunWithLooper
 @SmallTest
@@ -67,7 +71,11 @@
     @Test
     public void testSetCalledOnAdd_DarkIconManager() {
         LinearLayout layout = new LinearLayout(mContext);
-        TestDarkIconManager manager = new TestDarkIconManager(layout, mock(FeatureFlags.class));
+        TestDarkIconManager manager = new TestDarkIconManager(
+                layout,
+                mock(FeatureFlags.class),
+                mock(StatusBarPipelineFlags.class),
+                () -> mock(WifiViewModel.class));
         testCallOnAdd_forManager(manager);
     }
 
@@ -104,8 +112,12 @@
     private static class TestDarkIconManager extends DarkIconManager
             implements TestableIconManager {
 
-        TestDarkIconManager(LinearLayout group, FeatureFlags featureFlags) {
-            super(group, featureFlags);
+        TestDarkIconManager(
+                LinearLayout group,
+                FeatureFlags featureFlags,
+                StatusBarPipelineFlags statusBarPipelineFlags,
+                Provider<WifiViewModel> wifiViewModelProvider) {
+            super(group, featureFlags, statusBarPipelineFlags, wifiViewModelProvider);
         }
 
         @Override
@@ -123,7 +135,7 @@
         }
 
         @Override
-        protected StatusBarWifiView addSignalIcon(int index, String slot, WifiIconState state) {
+        protected StatusBarWifiView addWifiIcon(int index, String slot, WifiIconState state) {
             StatusBarWifiView mock = mock(StatusBarWifiView.class);
             mGroup.addView(mock, index);
             return mock;
@@ -140,7 +152,10 @@
 
     private static class TestIconManager extends IconManager implements TestableIconManager {
         TestIconManager(ViewGroup group) {
-            super(group, mock(FeatureFlags.class));
+            super(group,
+                    mock(FeatureFlags.class),
+                    mock(StatusBarPipelineFlags.class),
+                    () -> mock(WifiViewModel.class));
         }
 
         @Override
@@ -158,7 +173,7 @@
         }
 
         @Override
-        protected StatusBarWifiView addSignalIcon(int index, String slot, WifiIconState state) {
+        protected StatusBarWifiView addWifiIcon(int index, String slot, WifiIconState state) {
             StatusBarWifiView mock = mock(StatusBarWifiView.class);
             mGroup.addView(mock, index);
             return mock;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java
index 52a573f..20bf50e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java
@@ -113,6 +113,10 @@
     @Mock
     private NotificationPanelViewController mNotificationPanelViewController;
     @Mock
+    private StatusBarIconController.DarkIconManager.Factory mIconManagerFactory;
+    @Mock
+    private StatusBarIconController.DarkIconManager mIconManager;
+    @Mock
     private StatusBarHideIconsForBouncerManager mStatusBarHideIconsForBouncerManager;
     @Mock
     private DumpManager mDumpManager;
@@ -463,6 +467,7 @@
         mOperatorNameViewControllerFactory = mock(OperatorNameViewController.Factory.class);
         when(mOperatorNameViewControllerFactory.create(any()))
                 .thenReturn(mOperatorNameViewController);
+        when(mIconManagerFactory.create(any())).thenReturn(mIconManager);
         mSecureSettings = mock(SecureSettings.class);
 
         setUpNotificationIconAreaController();
@@ -475,6 +480,7 @@
                 new PanelExpansionStateManager(),
                 mock(FeatureFlags.class),
                 mStatusBarIconController,
+                mIconManagerFactory,
                 mStatusBarHideIconsForBouncerManager,
                 mKeyguardStateController,
                 mNotificationPanelViewController,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiViewTest.kt
new file mode 100644
index 0000000..3c200a5
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiViewTest.kt
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.pipeline.wifi.ui.view
+
+import android.testing.TestableLooper.RunWithLooper
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.lifecycle.InstantTaskExecutorRule
+import com.android.systemui.util.Assert
+import com.android.systemui.util.mockito.mock
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@SmallTest
+@RunWith(JUnit4::class)
+@RunWithLooper
+class ModernStatusBarWifiViewTest : SysuiTestCase() {
+
+    @JvmField @Rule
+    val instantTaskExecutor = InstantTaskExecutorRule()
+
+    @Before
+    fun setUp() {
+        Assert.setTestThread(Thread.currentThread())
+    }
+
+    @Test
+    fun constructAndBind_hasCorrectSlot() {
+        val view = ModernStatusBarWifiView.constructAndBind(
+            context, "slotName", mock()
+        )
+
+        assertThat(view.slot).isEqualTo("slotName")
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt
index fae4b105..c790734 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt
@@ -18,6 +18,7 @@
 
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.statusbar.pipeline.StatusBarPipelineFlags
 import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
 import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiActivityModel
 import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel
@@ -43,6 +44,7 @@
 
     private lateinit var underTest: WifiViewModel
 
+    @Mock private lateinit var statusBarPipelineFlags: StatusBarPipelineFlags
     @Mock private lateinit var logger: ConnectivityPipelineLogger
     @Mock private lateinit var constants: WifiConstants
     private lateinit var repository: FakeWifiRepository
@@ -55,9 +57,10 @@
         interactor = WifiInteractor(repository)
 
         underTest = WifiViewModel(
-                constants,
-                logger,
-                interactor
+            statusBarPipelineFlags,
+            constants,
+            logger,
+            interactor
         )
 
         // Set up with a valid SSID